From 956dd03e9793e439f4e2a28b5f5fbef3c41c3c3e Mon Sep 17 00:00:00 2001 From: basebuilder_pel7ppc64bebuilder0 Date: Thu, 17 May 2018 21:26:18 +0200 Subject: [PATCH] glibc package update Signed-off-by: basebuilder_pel7ppc64bebuilder0 --- SOURCES/glibc-aa64-commonpagesize-64k.patch | 11 + SOURCES/glibc-aa64-setcontext.patch | 220 + ...glibc-aarch64-add-ptr_mangle-support.patch | 233 + ...h64-fpu-optional-trapping-exceptions.patch | 122 + SOURCES/glibc-aarch64-ifunc.patch | 216 + SOURCES/glibc-aarch64-rh1076760.patch | 20 + SOURCES/glibc-aarch64-syscall-rewrite.patch | 539 + SOURCES/glibc-arm-hardfloat-3.patch | 21 + SOURCES/glibc-cs-path.patch | 6 + .../glibc-fedora-__libc_multiple_libcs.patch | 83 + SOURCES/glibc-fedora-elf-ORIGIN.patch | 98 + .../glibc-fedora-elf-init-hidden_undef.patch | 30 + SOURCES/glibc-fedora-elf-rh737223.patch | 15 + SOURCES/glibc-fedora-gai-canonical.patch | 124 + SOURCES/glibc-fedora-getrlimit-PLT.patch | 35 + ...libc-fedora-i386-tls-direct-seg-refs.patch | 18 + SOURCES/glibc-fedora-include-bits-ldbl.patch | 36 + SOURCES/glibc-fedora-ldd.patch | 38 + SOURCES/glibc-fedora-linux-tcsetattr.patch | 48 + SOURCES/glibc-fedora-localedata-rh61908.patch | 38 + SOURCES/glibc-fedora-localedef.patch | 11 + SOURCES/glibc-fedora-locarchive.patch | 51 + SOURCES/glibc-fedora-manual-dircategory.patch | 20 + SOURCES/glibc-fedora-nis-rh188246.patch | 21 + SOURCES/glibc-fedora-nptl-linklibc.patch | 25 + SOURCES/glibc-fedora-nscd.patch | 12 + SOURCES/glibc-fedora-ppc-unwind.patch | 23 + SOURCES/glibc-fedora-regcomp-sw11561.patch | 155 + SOURCES/glibc-fedora-streams-rh436349.patch | 28 + SOURCES/glibc-fedora-uname-getrlimit.patch | 52 + SOURCES/glibc-fix-test-write-buf-size.patch | 54 + SOURCES/glibc-gmake.patch | 37 + SOURCES/glibc-manual-update.patch | 19408 +++++++ SOURCES/glibc-ol7-strstr-sse4.patch | 744 + SOURCES/glibc-powerpc-ldbl_high.patch | 13 + SOURCES/glibc-ppc64le-01.patch | 83 + SOURCES/glibc-ppc64le-02.patch | 3197 ++ SOURCES/glibc-ppc64le-03.patch | 1617 + SOURCES/glibc-ppc64le-04.patch | 676 + SOURCES/glibc-ppc64le-05.patch | 486 + SOURCES/glibc-ppc64le-06.patch | 652 + SOURCES/glibc-ppc64le-07.patch | 651 + SOURCES/glibc-ppc64le-08.patch | 1235 + SOURCES/glibc-ppc64le-09.patch | 567 + SOURCES/glibc-ppc64le-10.patch | 91 + SOURCES/glibc-ppc64le-11.patch | 113 + SOURCES/glibc-ppc64le-12.patch | 74 + SOURCES/glibc-ppc64le-13.patch | 283 + SOURCES/glibc-ppc64le-14.patch | 120 + SOURCES/glibc-ppc64le-15.patch | 119 + SOURCES/glibc-ppc64le-16.patch | 163 + SOURCES/glibc-ppc64le-17.patch | 312 + SOURCES/glibc-ppc64le-18.patch | 81 + SOURCES/glibc-ppc64le-19.patch | 110 + SOURCES/glibc-ppc64le-20.patch | 41 + SOURCES/glibc-ppc64le-21.patch | 294 + SOURCES/glibc-ppc64le-22.patch | 228 + SOURCES/glibc-ppc64le-23.patch | 102 + SOURCES/glibc-ppc64le-24.patch | 55 + SOURCES/glibc-ppc64le-25.patch | 411 + SOURCES/glibc-ppc64le-26.patch | 379 + SOURCES/glibc-ppc64le-27.patch | 861 + SOURCES/glibc-ppc64le-28.patch | 167 + SOURCES/glibc-ppc64le-29.patch | 642 + SOURCES/glibc-ppc64le-30.patch | 7383 +++ SOURCES/glibc-ppc64le-31.patch | 2943 + SOURCES/glibc-ppc64le-32.patch | 272 + SOURCES/glibc-ppc64le-33.patch | 1255 + SOURCES/glibc-ppc64le-34.patch | 68 + SOURCES/glibc-ppc64le-35.patch | 106 + SOURCES/glibc-ppc64le-36.patch | 105 + SOURCES/glibc-ppc64le-37.patch | 31 + SOURCES/glibc-ppc64le-38.patch | 262 + SOURCES/glibc-ppc64le-39.patch | 508 + SOURCES/glibc-ppc64le-40.patch | 159 + SOURCES/glibc-ppc64le-41.patch | 764 + SOURCES/glibc-ppc64le-42.patch | 404 + SOURCES/glibc-ppc64le-43.patch | 248 + SOURCES/glibc-ppc64le-44.patch | 26 + SOURCES/glibc-ppc64le-45.patch | 33 + SOURCES/glibc-ppc64le-46.patch | 22 + SOURCES/glibc-rh1000923.patch | 32 + SOURCES/glibc-rh1008298.patch | 46 + SOURCES/glibc-rh1020637.patch | 128 + SOURCES/glibc-rh1025612.patch | 50 + SOURCES/glibc-rh1025934.patch | 143 + SOURCES/glibc-rh1027101.patch | 58 + SOURCES/glibc-rh1027348-1.patch | 280 + SOURCES/glibc-rh1027348-2.patch | 229 + SOURCES/glibc-rh1027348-3.patch | 144 + SOURCES/glibc-rh1027348-4.patch | 105 + SOURCES/glibc-rh1027348.patch | 3917 ++ SOURCES/glibc-rh1028652.patch | 96 + SOURCES/glibc-rh1032435.patch | 390 + SOURCES/glibc-rh1039496.patch | 102 + SOURCES/glibc-rh1039970.patch | 135 + SOURCES/glibc-rh1046199.patch | 23 + SOURCES/glibc-rh1047983.patch | 555 + SOURCES/glibc-rh1048036.patch | 29 + SOURCES/glibc-rh1048123.patch | 515 + SOURCES/glibc-rh1063681.patch | 948 + SOURCES/glibc-rh1064063.patch | 70 + SOURCES/glibc-rh1064066.patch | 32 + SOURCES/glibc-rh1064945.patch | 77 + SOURCES/glibc-rh1067755.patch | 123 + SOURCES/glibc-rh1070458.patch | 124 + SOURCES/glibc-rh1070471.patch | 53 + SOURCES/glibc-rh1070806.patch | 118 + SOURCES/glibc-rh1073667.patch | 91 + SOURCES/glibc-rh1074410-2.patch | 258 + SOURCES/glibc-rh1074410.patch | 655 + SOURCES/glibc-rh1077389-p1.patch | 77 + SOURCES/glibc-rh1077389-p2.patch | 52 + SOURCES/glibc-rh1078225.patch | 46 + SOURCES/glibc-rh1080766.patch | 57 + SOURCES/glibc-rh1083644.patch | 63 + SOURCES/glibc-rh1083646.patch | 398 + SOURCES/glibc-rh1083647.patch | 26 + SOURCES/glibc-rh1084089.patch | 65 + SOURCES/glibc-rh1084395.patch | 28895 ++++++++++ SOURCES/glibc-rh1085290.patch | 60 + SOURCES/glibc-rh1085313.patch | 34 + SOURCES/glibc-rh1098042.patch | 28 + SOURCES/glibc-rh1098047.patch | 247 + SOURCES/glibc-rh1103856.patch | 27 + SOURCES/glibc-rh1103874.patch | 152 + SOURCES/glibc-rh1120490-int128.patch | 60 + SOURCES/glibc-rh1120490.patch | 190 + SOURCES/glibc-rh1125306.patch | 20 + SOURCES/glibc-rh1132518-mpx.patch | 386 + SOURCES/glibc-rh1133812-1.patch | 207 + SOURCES/glibc-rh1133812-2.patch | 631 + SOURCES/glibc-rh1133812-3.patch | 474 + SOURCES/glibc-rh1138520.patch | 144 + SOURCES/glibc-rh1140250.patch | 346 + SOURCES/glibc-rh1140272-avx512.patch | 1158 + SOURCES/glibc-rh1140474.patch | 154 + SOURCES/glibc-rh1144133.patch | 55 + SOURCES/glibc-rh1144516.patch | 47 + SOURCES/glibc-rh1150282.patch | 515 + SOURCES/glibc-rh1156331.patch | 202 + SOURCES/glibc-rh1159169.patch | 41 + SOURCES/glibc-rh1161666.patch | 125 + SOURCES/glibc-rh1162847-p1.patch | 104 + SOURCES/glibc-rh1162847-p2.patch | 45 + SOURCES/glibc-rh1162895-1.patch | 23 + SOURCES/glibc-rh1162895-2.patch | 200 + SOURCES/glibc-rh1162895-3.patch | 123 + SOURCES/glibc-rh1165192.patch | 150 + SOURCES/glibc-rh1165212.patch | 336 + SOURCES/glibc-rh1170118-CVE-2014-7817.patch | 163 + SOURCES/glibc-rh1173238.patch | 380 + SOURCES/glibc-rh1173537.patch | 65 + SOURCES/glibc-rh1176906.patch | 22 + SOURCES/glibc-rh1183456.patch | 40 + SOURCES/glibc-rh1183545.patch | 233 + SOURCES/glibc-rh1186491.patch | 32 + SOURCES/glibc-rh1186620.patch | 95 + SOURCES/glibc-rh1188235.patch | 89 + SOURCES/glibc-rh1189278-1.patch | 67 + SOURCES/glibc-rh1189278.patch | 407 + SOURCES/glibc-rh1193797.patch | 803 + SOURCES/glibc-rh1194143.patch | 18 + SOURCES/glibc-rh1195762.patch | 33 + SOURCES/glibc-rh1197730-1.patch | 104 + SOURCES/glibc-rh1197730-2.patch | 46 + SOURCES/glibc-rh1197730-3.patch | 62 + SOURCES/glibc-rh1199525.patch | 20 + SOURCES/glibc-rh1202952.patch | 636 + SOURCES/glibc-rh1207032.patch | 649 + SOURCES/glibc-rh1211100.patch | 522 + SOURCES/glibc-rh1211823.patch | 29005 ++++++++++ SOURCES/glibc-rh1213603.patch | 41 + SOURCES/glibc-rh1216246.patch | 69 + SOURCES/glibc-rh1219891.patch | 117 + SOURCES/glibc-rh1221046.patch | 52 + SOURCES/glibc-rh1227699.patch | 33 + SOURCES/glibc-rh1228114-1.patch | 234 + SOURCES/glibc-rh1228114-2.patch | 1551 + SOURCES/glibc-rh1234449-1.patch | 73 + SOURCES/glibc-rh1234449-2.patch | 940 + SOURCES/glibc-rh1234449-3.patch | 93 + SOURCES/glibc-rh1234449-4.patch | 21 + SOURCES/glibc-rh1234622.patch | 12 + SOURCES/glibc-rh1240351-1.patch | 19 + SOURCES/glibc-rh1240351-10.patch | 253 + SOURCES/glibc-rh1240351-11.patch | 450 + SOURCES/glibc-rh1240351-12.patch | 1374 + SOURCES/glibc-rh1240351-2.patch | 231 + SOURCES/glibc-rh1240351-3.patch | 667 + SOURCES/glibc-rh1240351-4.patch | 741 + SOURCES/glibc-rh1240351-5.patch | 793 + SOURCES/glibc-rh1240351-6.patch | 252 + SOURCES/glibc-rh1240351-7.patch | 78 + SOURCES/glibc-rh1240351-8.patch | 1272 + SOURCES/glibc-rh1240351-9.patch | 730 + SOURCES/glibc-rh1240796.patch | 112 + SOURCES/glibc-rh1248208-2.patch | 36 + SOURCES/glibc-rh1248208.patch | 224 + SOURCES/glibc-rh1249102.patch | 25 + SOURCES/glibc-rh1249114.patch | 376 + SOURCES/glibc-rh1249115.patch | 121 + SOURCES/glibc-rh1255822.patch | 34 + SOURCES/glibc-rh1256317-0.patch | 162 + SOURCES/glibc-rh1256317-1.patch | 46 + SOURCES/glibc-rh1256317-10.patch | 46 + SOURCES/glibc-rh1256317-11.patch | 41 + SOURCES/glibc-rh1256317-12.patch | 25 + SOURCES/glibc-rh1256317-13.patch | 153 + SOURCES/glibc-rh1256317-14.patch | 105 + SOURCES/glibc-rh1256317-15.patch | 220 + SOURCES/glibc-rh1256317-16.patch | 42 + SOURCES/glibc-rh1256317-17.patch | 466 + SOURCES/glibc-rh1256317-18.patch | 51 + SOURCES/glibc-rh1256317-19.patch | 254 + SOURCES/glibc-rh1256317-2.patch | 7228 +++ SOURCES/glibc-rh1256317-20.patch | 54 + SOURCES/glibc-rh1256317-21.patch | 509 + SOURCES/glibc-rh1256317-3.patch | 24 + SOURCES/glibc-rh1256317-4.patch | 1239 + SOURCES/glibc-rh1256317-5.patch | 861 + SOURCES/glibc-rh1256317-6.patch | 914 + SOURCES/glibc-rh1256317-7.patch | 546 + SOURCES/glibc-rh1256317-8.patch | 135 + SOURCES/glibc-rh1256317-9.patch | 74 + SOURCES/glibc-rh1268008-1.patch | 97 + SOURCES/glibc-rh1268008-10.patch | 478 + SOURCES/glibc-rh1268008-11.patch | 961 + SOURCES/glibc-rh1268008-12.patch | 501 + SOURCES/glibc-rh1268008-13.patch | 706 + SOURCES/glibc-rh1268008-14.patch | 1237 + SOURCES/glibc-rh1268008-15.patch | 914 + SOURCES/glibc-rh1268008-16.patch | 1100 + SOURCES/glibc-rh1268008-17.patch | 1256 + SOURCES/glibc-rh1268008-18.patch | 585 + SOURCES/glibc-rh1268008-19.patch | 1313 + SOURCES/glibc-rh1268008-2.patch | 52 + SOURCES/glibc-rh1268008-20.patch | 499 + SOURCES/glibc-rh1268008-21.patch | 663 + SOURCES/glibc-rh1268008-22.patch | 657 + SOURCES/glibc-rh1268008-23.patch | 1235 + SOURCES/glibc-rh1268008-24.patch | 1402 + SOURCES/glibc-rh1268008-25.patch | 1106 + SOURCES/glibc-rh1268008-26.patch | 1183 + SOURCES/glibc-rh1268008-27.patch | 306 + SOURCES/glibc-rh1268008-28.patch | 737 + SOURCES/glibc-rh1268008-29.patch | 322 + SOURCES/glibc-rh1268008-3.patch | 643 + SOURCES/glibc-rh1268008-30.patch | 291 + SOURCES/glibc-rh1268008-4.patch | 206 + SOURCES/glibc-rh1268008-5.patch | 2341 + SOURCES/glibc-rh1268008-6.patch | 76 + SOURCES/glibc-rh1268008-7.patch | 55 + SOURCES/glibc-rh1268008-8.patch | 132 + SOURCES/glibc-rh1268008-9.patch | 49 + SOURCES/glibc-rh1276753-0.patch | 310 + SOURCES/glibc-rh1276753.patch | 654 + SOURCES/glibc-rh1284959-1.patch | 238 + SOURCES/glibc-rh1284959-2.patch | 63 + SOURCES/glibc-rh1284959-3.patch | 52 + SOURCES/glibc-rh1288613.patch | 183 + SOURCES/glibc-rh1292018-0.patch | 55 + SOURCES/glibc-rh1292018-0a.patch | 423 + SOURCES/glibc-rh1292018-0b.patch | 148 + SOURCES/glibc-rh1292018-1.patch | 1522 + SOURCES/glibc-rh1292018-2.patch | 1251 + SOURCES/glibc-rh1292018-3.patch | 1948 + SOURCES/glibc-rh1292018-4.patch | 41 + SOURCES/glibc-rh1292018-5.patch | 26 + SOURCES/glibc-rh1292018-6.patch | 188 + SOURCES/glibc-rh1292018-7.patch | 26 + SOURCES/glibc-rh1293433.patch | 45 + SOURCES/glibc-rh1293916.patch | 201 + SOURCES/glibc-rh1293976-2.patch | 551 + SOURCES/glibc-rh1293976.patch | 140 + SOURCES/glibc-rh1296031-0.patch | 461 + SOURCES/glibc-rh1296031-2.patch | 38 + SOURCES/glibc-rh1296031.patch | 554 + SOURCES/glibc-rh1296297-1.patch | 201 + SOURCES/glibc-rh1296297.patch | 356 + SOURCES/glibc-rh1298349.patch | 239 + SOURCES/glibc-rh1298354.patch | 2805 + SOURCES/glibc-rh1298526-0.patch | 347 + SOURCES/glibc-rh1298526-1.patch | 725 + SOURCES/glibc-rh1298526-2.patch | 25 + SOURCES/glibc-rh1298526-3.patch | 82 + SOURCES/glibc-rh1298526-4.patch | 61 + SOURCES/glibc-rh1298975.patch | 617 + SOURCES/glibc-rh1302086-1.patch | 35 + SOURCES/glibc-rh1302086-10.patch | 205 + SOURCES/glibc-rh1302086-11.patch | 61 + SOURCES/glibc-rh1302086-2.patch | 226 + SOURCES/glibc-rh1302086-3.patch | 72 + SOURCES/glibc-rh1302086-4.patch | 34 + SOURCES/glibc-rh1302086-5.patch | 229 + SOURCES/glibc-rh1302086-6.patch | 81 + SOURCES/glibc-rh1302086-7.patch | 24 + SOURCES/glibc-rh1302086-8.patch | 96 + SOURCES/glibc-rh1302086-9.patch | 68 + SOURCES/glibc-rh1308728.patch | 37 + SOURCES/glibc-rh1310530.patch | 18 + SOURCES/glibc-rh1318877.patch | 62 + SOURCES/glibc-rh1318890.patch | 35 + SOURCES/glibc-rh1320596.patch | 216 + SOURCES/glibc-rh1321993.patch | 32 + SOURCES/glibc-rh1322544.patch | 19 + SOURCES/glibc-rh1324427-1.patch | 891 + SOURCES/glibc-rh1324427-2.patch | 384 + SOURCES/glibc-rh1324427-3.patch | 28 + SOURCES/glibc-rh1324568.patch | 54 + SOURCES/glibc-rh1325138.patch | 19 + SOURCES/glibc-rh1326739.patch | 28 + SOURCES/glibc-rh1330705-1.patch | 64 + SOURCES/glibc-rh1330705-2.patch | 19 + SOURCES/glibc-rh1330705-3.patch | 457 + SOURCES/glibc-rh1330705-4.patch | 462 + SOURCES/glibc-rh1330705-5.patch | 385 + SOURCES/glibc-rh1330705-6.patch | 94 + SOURCES/glibc-rh1331283-1.patch | 34 + SOURCES/glibc-rh1331283-2.patch | 52 + SOURCES/glibc-rh1331283-3.patch | 89 + SOURCES/glibc-rh1331283-4.patch | 61 + SOURCES/glibc-rh1331283.patch | 201 + SOURCES/glibc-rh1335286-0.patch | 78 + SOURCES/glibc-rh1335286.patch | 1449 + SOURCES/glibc-rh1335629.patch | 66 + SOURCES/glibc-rh1335925-1.patch | 71 + SOURCES/glibc-rh1335925-2.patch | 34 + SOURCES/glibc-rh1335925-3.patch | 39 + SOURCES/glibc-rh1335925-4.patch | 142 + SOURCES/glibc-rh1337242.patch | 61 + SOURCES/glibc-rh1338672.patch | 294 + SOURCES/glibc-rh1346397.patch | 84 + SOURCES/glibc-rh1347277.patch | 20 + SOURCES/glibc-rh1348000.patch | 138 + SOURCES/glibc-rh1349962.patch | 63 + SOURCES/glibc-rh1349964.patch | 33 + SOURCES/glibc-rh1350733-1.patch | 244 + SOURCES/glibc-rh1366569.patch | 16 + SOURCES/glibc-rh1370630.patch | 64 + SOURCES/glibc-rh1372305.patch | 124 + SOURCES/glibc-rh1374652.patch | 1212 + SOURCES/glibc-rh1374654.patch | 208 + SOURCES/glibc-rh1374657.patch | 188 + SOURCES/glibc-rh1374658.patch | 124 + SOURCES/glibc-rh1375235-1.patch | 120 + SOURCES/glibc-rh1375235-10.patch | 182 + SOURCES/glibc-rh1375235-2.patch | 127 + SOURCES/glibc-rh1375235-3.patch | 373 + SOURCES/glibc-rh1375235-4.patch | 313 + SOURCES/glibc-rh1375235-5.patch | 387 + SOURCES/glibc-rh1375235-6.patch | 85 + SOURCES/glibc-rh1375235-7.patch | 177 + SOURCES/glibc-rh1375235-8.patch | 179 + SOURCES/glibc-rh1375235-9.patch | 187 + SOURCES/glibc-rh1380680-1.patch | 189 + SOURCES/glibc-rh1380680-10.patch | 48 + SOURCES/glibc-rh1380680-11.patch | 762 + SOURCES/glibc-rh1380680-12.patch | 608 + SOURCES/glibc-rh1380680-13.patch | 5226 ++ SOURCES/glibc-rh1380680-14.patch | 287 + SOURCES/glibc-rh1380680-15.patch | 269 + SOURCES/glibc-rh1380680-16.patch | 182 + SOURCES/glibc-rh1380680-17.patch | 399 + SOURCES/glibc-rh1380680-2.patch | 113 + SOURCES/glibc-rh1380680-3.patch | 524 + SOURCES/glibc-rh1380680-4.patch | 1313 + SOURCES/glibc-rh1380680-5.patch | 150 + SOURCES/glibc-rh1380680-6.patch | 319 + SOURCES/glibc-rh1380680-7.patch | 62 + SOURCES/glibc-rh1380680-8.patch | 139 + SOURCES/glibc-rh1380680-9.patch | 839 + SOURCES/glibc-rh1383951.patch | 71 + SOURCES/glibc-rh1385003.patch | 41 + SOURCES/glibc-rh1385004-1.patch | 710 + SOURCES/glibc-rh1385004-10.patch | 33 + SOURCES/glibc-rh1385004-11.patch | 363 + SOURCES/glibc-rh1385004-12.patch | 420 + SOURCES/glibc-rh1385004-13.patch | 795 + SOURCES/glibc-rh1385004-14.patch | 303 + SOURCES/glibc-rh1385004-15.patch | 632 + SOURCES/glibc-rh1385004-16.patch | 189 + SOURCES/glibc-rh1385004-17.patch | 122 + SOURCES/glibc-rh1385004-18.patch | 803 + SOURCES/glibc-rh1385004-19.patch | 58 + SOURCES/glibc-rh1385004-2.patch | 72 + SOURCES/glibc-rh1385004-20.patch | 452 + SOURCES/glibc-rh1385004-21.patch | 666 + SOURCES/glibc-rh1385004-22.patch | 410 + SOURCES/glibc-rh1385004-23.patch | 513 + SOURCES/glibc-rh1385004-24.patch | 72 + SOURCES/glibc-rh1385004-3.patch | 35 + SOURCES/glibc-rh1385004-4.patch | 112 + SOURCES/glibc-rh1385004-5.patch | 68 + SOURCES/glibc-rh1385004-6.patch | 28 + SOURCES/glibc-rh1385004-7.patch | 51 + SOURCES/glibc-rh1385004-8.patch | 136 + SOURCES/glibc-rh1385004-9.patch | 43 + SOURCES/glibc-rh1387874.patch | 23 + SOURCES/glibc-rh1392540.patch | 15 + SOURCES/glibc-rh1398244.patch | 17 + SOURCES/glibc-rh1398413.patch | 726 + SOURCES/glibc-rh1404435.patch | 37 + SOURCES/glibc-rh1409611.patch | 3262 ++ SOURCES/glibc-rh1413638-1.patch | 16 + SOURCES/glibc-rh1413638-2.patch | 19 + SOURCES/glibc-rh1417205.patch | 46 + SOURCES/glibc-rh1418978-0.patch | 108 + SOURCES/glibc-rh1418978-1.patch | 9655 ++++ SOURCES/glibc-rh1418978-2-1.patch | 18 + SOURCES/glibc-rh1418978-2-2.patch | 18 + SOURCES/glibc-rh1418978-2-3.patch | 20 + SOURCES/glibc-rh1418978-2-4.patch | 18 + SOURCES/glibc-rh1418978-2-5.patch | 56 + SOURCES/glibc-rh1418978-2-6.patch | 24 + SOURCES/glibc-rh1418978-3-1.patch | 126 + SOURCES/glibc-rh1418978-3-2.patch | 41 + SOURCES/glibc-rh1418978-max_align_t.patch | 82 + SOURCES/glibc-rh1418997.patch | 51 + SOURCES/glibc-rh1421155.patch | 2278 + SOURCES/glibc-rh1435615.patch | 26 + SOURCES/glibc-rh1436312.patch | 54 + SOURCES/glibc-rh1439165-syscall-names.patch | 610 + SOURCES/glibc-rh1439165.patch | 348 + SOURCES/glibc-rh1440250.patch | 406 + SOURCES/glibc-rh1443236.patch | 31 + SOURCES/glibc-rh1445644.patch | 78 + SOURCES/glibc-rh1445781-1.patch | 49 + SOURCES/glibc-rh1445781-2.patch | 88 + SOURCES/glibc-rh1447556.patch | 25 + SOURCES/glibc-rh1448822.patch | 19 + SOURCES/glibc-rh1452720-1.patch | 23 + SOURCES/glibc-rh1452720-2.patch | 103 + SOURCES/glibc-rh1452720-3.patch | 196 + SOURCES/glibc-rh1452720-4.patch | 51 + SOURCES/glibc-rh1452721-1.patch | 23 + SOURCES/glibc-rh1452721-2.patch | 103 + SOURCES/glibc-rh1452721-3.patch | 196 + SOURCES/glibc-rh1452721-4.patch | 51 + SOURCES/glibc-rh1457177-1.patch | 158 + SOURCES/glibc-rh1457177-2.patch | 179 + SOURCES/glibc-rh1457177-3.patch | 163 + SOURCES/glibc-rh1457177-4.patch | 180 + SOURCES/glibc-rh1463692-1.patch | 49 + SOURCES/glibc-rh1463692-2.patch | 27 + SOURCES/glibc-rh1468807.patch | 226 + SOURCES/glibc-rh1498566.patch | 70 + SOURCES/glibc-rh1498925-1.patch | 89 + SOURCES/glibc-rh1498925-2.patch | 123 + SOURCES/glibc-rh1500908.patch | 28 + SOURCES/glibc-rh1503854-1.patch | 70 + SOURCES/glibc-rh1503854-2.patch | 49 + SOURCES/glibc-rh1503854-3.patch | 49 + SOURCES/glibc-rh1504809-1.patch | 19 + SOURCES/glibc-rh1504809-2.patch | 26 + SOURCES/glibc-rh1504969.patch | 781 + SOURCES/glibc-rh1523119-compat-symbols.patch | 175 + SOURCES/glibc-rh1527904-1.patch | 135 + SOURCES/glibc-rh1527904-2.patch | 136 + SOURCES/glibc-rh1527904-3.patch | 88 + SOURCES/glibc-rh1527904-4.patch | 58 + SOURCES/glibc-rh1529982.patch | 301 + SOURCES/glibc-rh1534635.patch | 141 + SOURCES/glibc-rh677316-RES_USE_INET6.patch | 461 + SOURCES/glibc-rh677316-alloc_buffer.patch | 1307 + ...c-rh677316-check_mul_overflow_size_t.patch | 37 + SOURCES/glibc-rh677316-dynarray.patch | 2359 + SOURCES/glibc-rh677316-fgets_unlocked.patch | 83 + SOURCES/glibc-rh677316-h_errno.patch | 70 + SOURCES/glibc-rh677316-hesiod.patch | 575 + SOURCES/glibc-rh677316-in6addr_any.patch | 62 + SOURCES/glibc-rh677316-inet_pton-zeros.patch | 116 + SOURCES/glibc-rh677316-inet_pton.patch | 1613 + SOURCES/glibc-rh677316-legacy.patch | 61 + SOURCES/glibc-rh677316-libc-diag.patch | 90 + SOURCES/glibc-rh677316-libc-lock.patch | 12 + .../glibc-rh677316-libc-pointer-arith.patch | 10 + SOURCES/glibc-rh677316-mtrace.patch | 19 + SOURCES/glibc-rh677316-netdb-reentrant.patch | 37 + SOURCES/glibc-rh677316-qsort_r.patch | 115 + SOURCES/glibc-rh677316-res_state.patch | 11 + SOURCES/glibc-rh677316-resolv.patch | 19195 +++++++ SOURCES/glibc-rh677316-scratch_buffer.patch | 591 + SOURCES/glibc-rh697421.patch | 10 + SOURCES/glibc-rh731833-hwcap-2.patch | 108 + SOURCES/glibc-rh731833-hwcap-3.patch | 36 + SOURCES/glibc-rh731833-hwcap-4.patch | 279 + SOURCES/glibc-rh731833-hwcap-5.patch | 192 + SOURCES/glibc-rh731833-hwcap.patch | 408 + SOURCES/glibc-rh731833-libm-2.patch | 1740 + SOURCES/glibc-rh731833-libm-3.patch | 268 + SOURCES/glibc-rh731833-libm-4.patch | 53 + SOURCES/glibc-rh731833-libm-5.patch | 113 + SOURCES/glibc-rh731833-libm-6.patch | 169 + SOURCES/glibc-rh731833-libm-7.patch | 58 + SOURCES/glibc-rh731833-libm.patch | 26 + SOURCES/glibc-rh731833-misc-2.patch | 54 + SOURCES/glibc-rh731833-misc-3.patch | 145 + SOURCES/glibc-rh731833-misc-4.patch | 140 + SOURCES/glibc-rh731833-misc-5.patch | 30 + SOURCES/glibc-rh731833-misc-6.patch | 180 + SOURCES/glibc-rh731833-misc.patch | 210 + SOURCES/glibc-rh731833-rtkaio-2.patch | 11 + SOURCES/glibc-rh731833-rtkaio.patch | 31 + SOURCES/glibc-rh731835-0.patch | 761 + SOURCES/glibc-rh731835-1.patch | 215 + SOURCES/glibc-rh731835-2.patch | 43 + SOURCES/glibc-rh731837-00.patch | 210 + SOURCES/glibc-rh731837-01.patch | 537 + SOURCES/glibc-rh731837-02.patch | 255 + SOURCES/glibc-rh731837-03.patch | 578 + SOURCES/glibc-rh731837-04.patch | 232 + SOURCES/glibc-rh731837-05.patch | 231 + SOURCES/glibc-rh731837-06.patch | 201 + SOURCES/glibc-rh731837-07.patch | 223 + SOURCES/glibc-rh731837-08.patch | 187 + SOURCES/glibc-rh731837-09.patch | 199 + SOURCES/glibc-rh731837-10.patch | 247 + SOURCES/glibc-rh731837-11.patch | 219 + SOURCES/glibc-rh731837-12.patch | 236 + SOURCES/glibc-rh731837-13.patch | 211 + SOURCES/glibc-rh731837-14.patch | 225 + SOURCES/glibc-rh731837-15.patch | 398 + SOURCES/glibc-rh731837-16.patch | 401 + SOURCES/glibc-rh731837-17.patch | 423 + SOURCES/glibc-rh731837-18.patch | 1075 + SOURCES/glibc-rh731837-19.patch | 27 + SOURCES/glibc-rh731837-20.patch | 74 + SOURCES/glibc-rh731837-21.patch | 202 + SOURCES/glibc-rh731837-22.patch | 44 + SOURCES/glibc-rh731837-23.patch | 361 + SOURCES/glibc-rh731837-24.patch | 219 + SOURCES/glibc-rh731837-25.patch | 260 + SOURCES/glibc-rh731837-26.patch | 262 + SOURCES/glibc-rh731837-27.patch | 260 + SOURCES/glibc-rh731837-28.patch | 260 + SOURCES/glibc-rh731837-29.patch | 218 + SOURCES/glibc-rh731837-30.patch | 178 + SOURCES/glibc-rh731837-31.patch | 307 + SOURCES/glibc-rh731837-32.patch | 250 + SOURCES/glibc-rh731837-33.patch | 697 + SOURCES/glibc-rh731837-33A.patch | 44 + SOURCES/glibc-rh731837-34.patch | 335 + SOURCES/glibc-rh731837-35.patch | 308 + SOURCES/glibc-rh731837-36.patch | 382 + SOURCES/glibc-rh739743.patch | 56 + SOURCES/glibc-rh741105.patch | 21 + SOURCES/glibc-rh742038.patch | 607 + SOURCES/glibc-rh757881.patch | 167 + SOURCES/glibc-rh804768-bugfix.patch | 656 + SOURCES/glibc-rh819430.patch | 77 + SOURCES/glibc-rh825061.patch | 13 + SOURCES/glibc-rh827510.patch | 27 + SOURCES/glibc-rh841318.patch | 45241 ++++++++++++++++ SOURCES/glibc-rh841653-0.patch | 761 + SOURCES/glibc-rh841653-1.patch | 102 + SOURCES/glibc-rh841653-10.patch | 56 + SOURCES/glibc-rh841653-11.patch | 26 + SOURCES/glibc-rh841653-12.patch | 100 + SOURCES/glibc-rh841653-13.patch | 103 + SOURCES/glibc-rh841653-14.patch | 172 + SOURCES/glibc-rh841653-15.patch | 48 + SOURCES/glibc-rh841653-16.patch | 204 + SOURCES/glibc-rh841653-17.patch | 82 + SOURCES/glibc-rh841653-2.patch | 122 + SOURCES/glibc-rh841653-3.patch | 541 + SOURCES/glibc-rh841653-4.patch | 29 + SOURCES/glibc-rh841653-5.patch | 45 + SOURCES/glibc-rh841653-6.patch | 306 + SOURCES/glibc-rh841653-7.patch | 18 + SOURCES/glibc-rh841653-8.patch | 18 + SOURCES/glibc-rh841653-9.patch | 26 + SOURCES/glibc-rh841787.patch | 56 + SOURCES/glibc-rh884008.patch | 26 + SOURCES/glibc-rh892777.patch | 60 + SOURCES/glibc-rh905184.patch | 95 + SOURCES/glibc-rh905877.patch | 153 + SOURCES/glibc-rh906468-1.patch | 541 + SOURCES/glibc-rh906468-2.patch | 816 + SOURCES/glibc-rh911307-2.patch | 43 + SOURCES/glibc-rh911307-3.patch | 185 + SOURCES/glibc-rh911307.patch | 60 + SOURCES/glibc-rh950093.patch | 327 + SOURCES/glibc-rh952799.patch | 181 + SOURCES/glibc-rh958652.patch | 69 + SOURCES/glibc-rh959034.patch | 80 + SOURCES/glibc-rh966259.patch | 55 + SOURCES/glibc-rh966633.patch | 95 + SOURCES/glibc-rh970791.patch | 180 + SOURCES/glibc-rh971416-1.patch | 53 + SOURCES/glibc-rh971416-2.patch | 26 + SOURCES/glibc-rh971416-3.patch | 112 + SOURCES/glibc-rh971589.patch | 37 + SOURCES/glibc-rh977110-2.patch | 101 + SOURCES/glibc-rh977110.patch | 76 + SOURCES/glibc-rh977870.patch | 67 + SOURCES/glibc-rh977872.patch | 268 + SOURCES/glibc-rh977874.patch | 148 + SOURCES/glibc-rh977875.patch | 96 + SOURCES/glibc-rh977887-2.patch | 337 + SOURCES/glibc-rh977887.patch | 46 + SOURCES/glibc-rh979363.patch | 157 + SOURCES/glibc-rh980323.patch | 50 + SOURCES/glibc-rh981332.patch | 263 + SOURCES/glibc-rh984828.patch | 239 + SOURCES/glibc-rh988869.patch | 22 + SOURCES/glibc-rh989861.patch | 37 + SOURCES/glibc-rh989862-2.patch | 325 + SOURCES/glibc-rh989862-3.patch | 21 + SOURCES/glibc-rh989862.patch | 790 + SOURCES/glibc-rh990388-2.patch | 279 + SOURCES/glibc-rh990388-3.patch | 56 + SOURCES/glibc-rh990388-4.patch | 64 + SOURCES/glibc-rh990388.patch | 191 + SOURCES/glibc-rh990481-CVE-2013-4788.patch | 428 + SOURCES/glibc-rh996227.patch | 302 + SOURCES/glibc-rtkaio-inc-pthread.patch | 20 + SOURCES/glibc-stap-libm.patch | 80 + SOURCES/verify.md5 | 4 + SPECS/glibc.spec | 748 +- 620 files changed, 343868 insertions(+), 20 deletions(-) create mode 100644 SOURCES/glibc-aa64-commonpagesize-64k.patch create mode 100644 SOURCES/glibc-aa64-setcontext.patch create mode 100644 SOURCES/glibc-aarch64-add-ptr_mangle-support.patch create mode 100644 SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch create mode 100644 SOURCES/glibc-aarch64-ifunc.patch create mode 100644 SOURCES/glibc-aarch64-rh1076760.patch create mode 100644 SOURCES/glibc-aarch64-syscall-rewrite.patch create mode 100644 SOURCES/glibc-arm-hardfloat-3.patch create mode 100644 SOURCES/glibc-cs-path.patch create mode 100644 SOURCES/glibc-fedora-__libc_multiple_libcs.patch create mode 100644 SOURCES/glibc-fedora-elf-ORIGIN.patch create mode 100644 SOURCES/glibc-fedora-elf-init-hidden_undef.patch create mode 100644 SOURCES/glibc-fedora-elf-rh737223.patch create mode 100644 SOURCES/glibc-fedora-gai-canonical.patch create mode 100644 SOURCES/glibc-fedora-getrlimit-PLT.patch create mode 100644 SOURCES/glibc-fedora-i386-tls-direct-seg-refs.patch create mode 100644 SOURCES/glibc-fedora-include-bits-ldbl.patch create mode 100644 SOURCES/glibc-fedora-ldd.patch create mode 100644 SOURCES/glibc-fedora-linux-tcsetattr.patch create mode 100644 SOURCES/glibc-fedora-localedata-rh61908.patch create mode 100644 SOURCES/glibc-fedora-localedef.patch create mode 100644 SOURCES/glibc-fedora-locarchive.patch create mode 100644 SOURCES/glibc-fedora-manual-dircategory.patch create mode 100644 SOURCES/glibc-fedora-nis-rh188246.patch create mode 100644 SOURCES/glibc-fedora-nptl-linklibc.patch create mode 100644 SOURCES/glibc-fedora-nscd.patch create mode 100644 SOURCES/glibc-fedora-ppc-unwind.patch create mode 100644 SOURCES/glibc-fedora-regcomp-sw11561.patch create mode 100644 SOURCES/glibc-fedora-streams-rh436349.patch create mode 100644 SOURCES/glibc-fedora-uname-getrlimit.patch create mode 100644 SOURCES/glibc-fix-test-write-buf-size.patch create mode 100644 SOURCES/glibc-gmake.patch create mode 100644 SOURCES/glibc-manual-update.patch create mode 100755 SOURCES/glibc-ol7-strstr-sse4.patch create mode 100644 SOURCES/glibc-powerpc-ldbl_high.patch create mode 100644 SOURCES/glibc-ppc64le-01.patch create mode 100644 SOURCES/glibc-ppc64le-02.patch create mode 100644 SOURCES/glibc-ppc64le-03.patch create mode 100644 SOURCES/glibc-ppc64le-04.patch create mode 100644 SOURCES/glibc-ppc64le-05.patch create mode 100644 SOURCES/glibc-ppc64le-06.patch create mode 100644 SOURCES/glibc-ppc64le-07.patch create mode 100644 SOURCES/glibc-ppc64le-08.patch create mode 100644 SOURCES/glibc-ppc64le-09.patch create mode 100644 SOURCES/glibc-ppc64le-10.patch create mode 100644 SOURCES/glibc-ppc64le-11.patch create mode 100644 SOURCES/glibc-ppc64le-12.patch create mode 100644 SOURCES/glibc-ppc64le-13.patch create mode 100644 SOURCES/glibc-ppc64le-14.patch create mode 100644 SOURCES/glibc-ppc64le-15.patch create mode 100644 SOURCES/glibc-ppc64le-16.patch create mode 100644 SOURCES/glibc-ppc64le-17.patch create mode 100644 SOURCES/glibc-ppc64le-18.patch create mode 100644 SOURCES/glibc-ppc64le-19.patch create mode 100644 SOURCES/glibc-ppc64le-20.patch create mode 100644 SOURCES/glibc-ppc64le-21.patch create mode 100644 SOURCES/glibc-ppc64le-22.patch create mode 100644 SOURCES/glibc-ppc64le-23.patch create mode 100644 SOURCES/glibc-ppc64le-24.patch create mode 100644 SOURCES/glibc-ppc64le-25.patch create mode 100644 SOURCES/glibc-ppc64le-26.patch create mode 100644 SOURCES/glibc-ppc64le-27.patch create mode 100644 SOURCES/glibc-ppc64le-28.patch create mode 100644 SOURCES/glibc-ppc64le-29.patch create mode 100644 SOURCES/glibc-ppc64le-30.patch create mode 100644 SOURCES/glibc-ppc64le-31.patch create mode 100644 SOURCES/glibc-ppc64le-32.patch create mode 100644 SOURCES/glibc-ppc64le-33.patch create mode 100644 SOURCES/glibc-ppc64le-34.patch create mode 100644 SOURCES/glibc-ppc64le-35.patch create mode 100644 SOURCES/glibc-ppc64le-36.patch create mode 100644 SOURCES/glibc-ppc64le-37.patch create mode 100644 SOURCES/glibc-ppc64le-38.patch create mode 100644 SOURCES/glibc-ppc64le-39.patch create mode 100644 SOURCES/glibc-ppc64le-40.patch create mode 100644 SOURCES/glibc-ppc64le-41.patch create mode 100644 SOURCES/glibc-ppc64le-42.patch create mode 100644 SOURCES/glibc-ppc64le-43.patch create mode 100644 SOURCES/glibc-ppc64le-44.patch create mode 100644 SOURCES/glibc-ppc64le-45.patch create mode 100644 SOURCES/glibc-ppc64le-46.patch create mode 100644 SOURCES/glibc-rh1000923.patch create mode 100644 SOURCES/glibc-rh1008298.patch create mode 100644 SOURCES/glibc-rh1020637.patch create mode 100644 SOURCES/glibc-rh1025612.patch create mode 100644 SOURCES/glibc-rh1025934.patch create mode 100644 SOURCES/glibc-rh1027101.patch create mode 100644 SOURCES/glibc-rh1027348-1.patch create mode 100644 SOURCES/glibc-rh1027348-2.patch create mode 100644 SOURCES/glibc-rh1027348-3.patch create mode 100644 SOURCES/glibc-rh1027348-4.patch create mode 100644 SOURCES/glibc-rh1027348.patch create mode 100644 SOURCES/glibc-rh1028652.patch create mode 100644 SOURCES/glibc-rh1032435.patch create mode 100644 SOURCES/glibc-rh1039496.patch create mode 100644 SOURCES/glibc-rh1039970.patch create mode 100644 SOURCES/glibc-rh1046199.patch create mode 100644 SOURCES/glibc-rh1047983.patch create mode 100644 SOURCES/glibc-rh1048036.patch create mode 100644 SOURCES/glibc-rh1048123.patch create mode 100644 SOURCES/glibc-rh1063681.patch create mode 100644 SOURCES/glibc-rh1064063.patch create mode 100644 SOURCES/glibc-rh1064066.patch create mode 100644 SOURCES/glibc-rh1064945.patch create mode 100644 SOURCES/glibc-rh1067755.patch create mode 100644 SOURCES/glibc-rh1070458.patch create mode 100644 SOURCES/glibc-rh1070471.patch create mode 100644 SOURCES/glibc-rh1070806.patch create mode 100644 SOURCES/glibc-rh1073667.patch create mode 100644 SOURCES/glibc-rh1074410-2.patch create mode 100644 SOURCES/glibc-rh1074410.patch create mode 100644 SOURCES/glibc-rh1077389-p1.patch create mode 100644 SOURCES/glibc-rh1077389-p2.patch create mode 100644 SOURCES/glibc-rh1078225.patch create mode 100644 SOURCES/glibc-rh1080766.patch create mode 100644 SOURCES/glibc-rh1083644.patch create mode 100644 SOURCES/glibc-rh1083646.patch create mode 100644 SOURCES/glibc-rh1083647.patch create mode 100644 SOURCES/glibc-rh1084089.patch create mode 100644 SOURCES/glibc-rh1084395.patch create mode 100644 SOURCES/glibc-rh1085290.patch create mode 100644 SOURCES/glibc-rh1085313.patch create mode 100644 SOURCES/glibc-rh1098042.patch create mode 100644 SOURCES/glibc-rh1098047.patch create mode 100644 SOURCES/glibc-rh1103856.patch create mode 100644 SOURCES/glibc-rh1103874.patch create mode 100644 SOURCES/glibc-rh1120490-int128.patch create mode 100644 SOURCES/glibc-rh1120490.patch create mode 100644 SOURCES/glibc-rh1125306.patch create mode 100644 SOURCES/glibc-rh1132518-mpx.patch create mode 100644 SOURCES/glibc-rh1133812-1.patch create mode 100644 SOURCES/glibc-rh1133812-2.patch create mode 100644 SOURCES/glibc-rh1133812-3.patch create mode 100644 SOURCES/glibc-rh1138520.patch create mode 100644 SOURCES/glibc-rh1140250.patch create mode 100644 SOURCES/glibc-rh1140272-avx512.patch create mode 100644 SOURCES/glibc-rh1140474.patch create mode 100644 SOURCES/glibc-rh1144133.patch create mode 100644 SOURCES/glibc-rh1144516.patch create mode 100644 SOURCES/glibc-rh1150282.patch create mode 100644 SOURCES/glibc-rh1156331.patch create mode 100644 SOURCES/glibc-rh1159169.patch create mode 100644 SOURCES/glibc-rh1161666.patch create mode 100644 SOURCES/glibc-rh1162847-p1.patch create mode 100644 SOURCES/glibc-rh1162847-p2.patch create mode 100644 SOURCES/glibc-rh1162895-1.patch create mode 100644 SOURCES/glibc-rh1162895-2.patch create mode 100644 SOURCES/glibc-rh1162895-3.patch create mode 100644 SOURCES/glibc-rh1165192.patch create mode 100644 SOURCES/glibc-rh1165212.patch create mode 100644 SOURCES/glibc-rh1170118-CVE-2014-7817.patch create mode 100644 SOURCES/glibc-rh1173238.patch create mode 100644 SOURCES/glibc-rh1173537.patch create mode 100644 SOURCES/glibc-rh1176906.patch create mode 100644 SOURCES/glibc-rh1183456.patch create mode 100644 SOURCES/glibc-rh1183545.patch create mode 100644 SOURCES/glibc-rh1186491.patch create mode 100644 SOURCES/glibc-rh1186620.patch create mode 100644 SOURCES/glibc-rh1188235.patch create mode 100644 SOURCES/glibc-rh1189278-1.patch create mode 100644 SOURCES/glibc-rh1189278.patch create mode 100644 SOURCES/glibc-rh1193797.patch create mode 100644 SOURCES/glibc-rh1194143.patch create mode 100644 SOURCES/glibc-rh1195762.patch create mode 100644 SOURCES/glibc-rh1197730-1.patch create mode 100644 SOURCES/glibc-rh1197730-2.patch create mode 100644 SOURCES/glibc-rh1197730-3.patch create mode 100644 SOURCES/glibc-rh1199525.patch create mode 100644 SOURCES/glibc-rh1202952.patch create mode 100644 SOURCES/glibc-rh1207032.patch create mode 100644 SOURCES/glibc-rh1211100.patch create mode 100644 SOURCES/glibc-rh1211823.patch create mode 100644 SOURCES/glibc-rh1213603.patch create mode 100644 SOURCES/glibc-rh1216246.patch create mode 100644 SOURCES/glibc-rh1219891.patch create mode 100644 SOURCES/glibc-rh1221046.patch create mode 100644 SOURCES/glibc-rh1227699.patch create mode 100644 SOURCES/glibc-rh1228114-1.patch create mode 100644 SOURCES/glibc-rh1228114-2.patch create mode 100644 SOURCES/glibc-rh1234449-1.patch create mode 100644 SOURCES/glibc-rh1234449-2.patch create mode 100644 SOURCES/glibc-rh1234449-3.patch create mode 100644 SOURCES/glibc-rh1234449-4.patch create mode 100644 SOURCES/glibc-rh1234622.patch create mode 100644 SOURCES/glibc-rh1240351-1.patch create mode 100644 SOURCES/glibc-rh1240351-10.patch create mode 100644 SOURCES/glibc-rh1240351-11.patch create mode 100644 SOURCES/glibc-rh1240351-12.patch create mode 100644 SOURCES/glibc-rh1240351-2.patch create mode 100644 SOURCES/glibc-rh1240351-3.patch create mode 100644 SOURCES/glibc-rh1240351-4.patch create mode 100644 SOURCES/glibc-rh1240351-5.patch create mode 100644 SOURCES/glibc-rh1240351-6.patch create mode 100644 SOURCES/glibc-rh1240351-7.patch create mode 100644 SOURCES/glibc-rh1240351-8.patch create mode 100644 SOURCES/glibc-rh1240351-9.patch create mode 100644 SOURCES/glibc-rh1240796.patch create mode 100644 SOURCES/glibc-rh1248208-2.patch create mode 100644 SOURCES/glibc-rh1248208.patch create mode 100644 SOURCES/glibc-rh1249102.patch create mode 100644 SOURCES/glibc-rh1249114.patch create mode 100644 SOURCES/glibc-rh1249115.patch create mode 100644 SOURCES/glibc-rh1255822.patch create mode 100644 SOURCES/glibc-rh1256317-0.patch create mode 100644 SOURCES/glibc-rh1256317-1.patch create mode 100644 SOURCES/glibc-rh1256317-10.patch create mode 100644 SOURCES/glibc-rh1256317-11.patch create mode 100644 SOURCES/glibc-rh1256317-12.patch create mode 100644 SOURCES/glibc-rh1256317-13.patch create mode 100644 SOURCES/glibc-rh1256317-14.patch create mode 100644 SOURCES/glibc-rh1256317-15.patch create mode 100644 SOURCES/glibc-rh1256317-16.patch create mode 100644 SOURCES/glibc-rh1256317-17.patch create mode 100644 SOURCES/glibc-rh1256317-18.patch create mode 100644 SOURCES/glibc-rh1256317-19.patch create mode 100644 SOURCES/glibc-rh1256317-2.patch create mode 100644 SOURCES/glibc-rh1256317-20.patch create mode 100644 SOURCES/glibc-rh1256317-21.patch create mode 100644 SOURCES/glibc-rh1256317-3.patch create mode 100644 SOURCES/glibc-rh1256317-4.patch create mode 100644 SOURCES/glibc-rh1256317-5.patch create mode 100644 SOURCES/glibc-rh1256317-6.patch create mode 100644 SOURCES/glibc-rh1256317-7.patch create mode 100644 SOURCES/glibc-rh1256317-8.patch create mode 100644 SOURCES/glibc-rh1256317-9.patch create mode 100644 SOURCES/glibc-rh1268008-1.patch create mode 100644 SOURCES/glibc-rh1268008-10.patch create mode 100644 SOURCES/glibc-rh1268008-11.patch create mode 100644 SOURCES/glibc-rh1268008-12.patch create mode 100644 SOURCES/glibc-rh1268008-13.patch create mode 100644 SOURCES/glibc-rh1268008-14.patch create mode 100644 SOURCES/glibc-rh1268008-15.patch create mode 100644 SOURCES/glibc-rh1268008-16.patch create mode 100644 SOURCES/glibc-rh1268008-17.patch create mode 100644 SOURCES/glibc-rh1268008-18.patch create mode 100644 SOURCES/glibc-rh1268008-19.patch create mode 100644 SOURCES/glibc-rh1268008-2.patch create mode 100644 SOURCES/glibc-rh1268008-20.patch create mode 100644 SOURCES/glibc-rh1268008-21.patch create mode 100644 SOURCES/glibc-rh1268008-22.patch create mode 100644 SOURCES/glibc-rh1268008-23.patch create mode 100644 SOURCES/glibc-rh1268008-24.patch create mode 100644 SOURCES/glibc-rh1268008-25.patch create mode 100644 SOURCES/glibc-rh1268008-26.patch create mode 100644 SOURCES/glibc-rh1268008-27.patch create mode 100644 SOURCES/glibc-rh1268008-28.patch create mode 100644 SOURCES/glibc-rh1268008-29.patch create mode 100644 SOURCES/glibc-rh1268008-3.patch create mode 100644 SOURCES/glibc-rh1268008-30.patch create mode 100644 SOURCES/glibc-rh1268008-4.patch create mode 100644 SOURCES/glibc-rh1268008-5.patch create mode 100644 SOURCES/glibc-rh1268008-6.patch create mode 100644 SOURCES/glibc-rh1268008-7.patch create mode 100644 SOURCES/glibc-rh1268008-8.patch create mode 100644 SOURCES/glibc-rh1268008-9.patch create mode 100644 SOURCES/glibc-rh1276753-0.patch create mode 100644 SOURCES/glibc-rh1276753.patch create mode 100644 SOURCES/glibc-rh1284959-1.patch create mode 100644 SOURCES/glibc-rh1284959-2.patch create mode 100644 SOURCES/glibc-rh1284959-3.patch create mode 100644 SOURCES/glibc-rh1288613.patch create mode 100644 SOURCES/glibc-rh1292018-0.patch create mode 100644 SOURCES/glibc-rh1292018-0a.patch create mode 100644 SOURCES/glibc-rh1292018-0b.patch create mode 100644 SOURCES/glibc-rh1292018-1.patch create mode 100644 SOURCES/glibc-rh1292018-2.patch create mode 100644 SOURCES/glibc-rh1292018-3.patch create mode 100644 SOURCES/glibc-rh1292018-4.patch create mode 100644 SOURCES/glibc-rh1292018-5.patch create mode 100644 SOURCES/glibc-rh1292018-6.patch create mode 100644 SOURCES/glibc-rh1292018-7.patch create mode 100644 SOURCES/glibc-rh1293433.patch create mode 100644 SOURCES/glibc-rh1293916.patch create mode 100644 SOURCES/glibc-rh1293976-2.patch create mode 100644 SOURCES/glibc-rh1293976.patch create mode 100644 SOURCES/glibc-rh1296031-0.patch create mode 100644 SOURCES/glibc-rh1296031-2.patch create mode 100644 SOURCES/glibc-rh1296031.patch create mode 100644 SOURCES/glibc-rh1296297-1.patch create mode 100644 SOURCES/glibc-rh1296297.patch create mode 100644 SOURCES/glibc-rh1298349.patch create mode 100644 SOURCES/glibc-rh1298354.patch create mode 100644 SOURCES/glibc-rh1298526-0.patch create mode 100644 SOURCES/glibc-rh1298526-1.patch create mode 100644 SOURCES/glibc-rh1298526-2.patch create mode 100644 SOURCES/glibc-rh1298526-3.patch create mode 100644 SOURCES/glibc-rh1298526-4.patch create mode 100644 SOURCES/glibc-rh1298975.patch create mode 100644 SOURCES/glibc-rh1302086-1.patch create mode 100644 SOURCES/glibc-rh1302086-10.patch create mode 100644 SOURCES/glibc-rh1302086-11.patch create mode 100644 SOURCES/glibc-rh1302086-2.patch create mode 100644 SOURCES/glibc-rh1302086-3.patch create mode 100644 SOURCES/glibc-rh1302086-4.patch create mode 100644 SOURCES/glibc-rh1302086-5.patch create mode 100644 SOURCES/glibc-rh1302086-6.patch create mode 100644 SOURCES/glibc-rh1302086-7.patch create mode 100644 SOURCES/glibc-rh1302086-8.patch create mode 100644 SOURCES/glibc-rh1302086-9.patch create mode 100644 SOURCES/glibc-rh1308728.patch create mode 100644 SOURCES/glibc-rh1310530.patch create mode 100644 SOURCES/glibc-rh1318877.patch create mode 100644 SOURCES/glibc-rh1318890.patch create mode 100644 SOURCES/glibc-rh1320596.patch create mode 100644 SOURCES/glibc-rh1321993.patch create mode 100644 SOURCES/glibc-rh1322544.patch create mode 100644 SOURCES/glibc-rh1324427-1.patch create mode 100644 SOURCES/glibc-rh1324427-2.patch create mode 100644 SOURCES/glibc-rh1324427-3.patch create mode 100644 SOURCES/glibc-rh1324568.patch create mode 100644 SOURCES/glibc-rh1325138.patch create mode 100644 SOURCES/glibc-rh1326739.patch create mode 100644 SOURCES/glibc-rh1330705-1.patch create mode 100644 SOURCES/glibc-rh1330705-2.patch create mode 100644 SOURCES/glibc-rh1330705-3.patch create mode 100644 SOURCES/glibc-rh1330705-4.patch create mode 100644 SOURCES/glibc-rh1330705-5.patch create mode 100644 SOURCES/glibc-rh1330705-6.patch create mode 100644 SOURCES/glibc-rh1331283-1.patch create mode 100644 SOURCES/glibc-rh1331283-2.patch create mode 100644 SOURCES/glibc-rh1331283-3.patch create mode 100644 SOURCES/glibc-rh1331283-4.patch create mode 100644 SOURCES/glibc-rh1331283.patch create mode 100644 SOURCES/glibc-rh1335286-0.patch create mode 100644 SOURCES/glibc-rh1335286.patch create mode 100644 SOURCES/glibc-rh1335629.patch create mode 100644 SOURCES/glibc-rh1335925-1.patch create mode 100644 SOURCES/glibc-rh1335925-2.patch create mode 100644 SOURCES/glibc-rh1335925-3.patch create mode 100644 SOURCES/glibc-rh1335925-4.patch create mode 100644 SOURCES/glibc-rh1337242.patch create mode 100644 SOURCES/glibc-rh1338672.patch create mode 100644 SOURCES/glibc-rh1346397.patch create mode 100644 SOURCES/glibc-rh1347277.patch create mode 100644 SOURCES/glibc-rh1348000.patch create mode 100644 SOURCES/glibc-rh1349962.patch create mode 100644 SOURCES/glibc-rh1349964.patch create mode 100644 SOURCES/glibc-rh1350733-1.patch create mode 100644 SOURCES/glibc-rh1366569.patch create mode 100644 SOURCES/glibc-rh1370630.patch create mode 100644 SOURCES/glibc-rh1372305.patch create mode 100644 SOURCES/glibc-rh1374652.patch create mode 100644 SOURCES/glibc-rh1374654.patch create mode 100644 SOURCES/glibc-rh1374657.patch create mode 100644 SOURCES/glibc-rh1374658.patch create mode 100644 SOURCES/glibc-rh1375235-1.patch create mode 100644 SOURCES/glibc-rh1375235-10.patch create mode 100644 SOURCES/glibc-rh1375235-2.patch create mode 100644 SOURCES/glibc-rh1375235-3.patch create mode 100644 SOURCES/glibc-rh1375235-4.patch create mode 100644 SOURCES/glibc-rh1375235-5.patch create mode 100644 SOURCES/glibc-rh1375235-6.patch create mode 100644 SOURCES/glibc-rh1375235-7.patch create mode 100644 SOURCES/glibc-rh1375235-8.patch create mode 100644 SOURCES/glibc-rh1375235-9.patch create mode 100644 SOURCES/glibc-rh1380680-1.patch create mode 100644 SOURCES/glibc-rh1380680-10.patch create mode 100644 SOURCES/glibc-rh1380680-11.patch create mode 100644 SOURCES/glibc-rh1380680-12.patch create mode 100644 SOURCES/glibc-rh1380680-13.patch create mode 100644 SOURCES/glibc-rh1380680-14.patch create mode 100644 SOURCES/glibc-rh1380680-15.patch create mode 100644 SOURCES/glibc-rh1380680-16.patch create mode 100644 SOURCES/glibc-rh1380680-17.patch create mode 100644 SOURCES/glibc-rh1380680-2.patch create mode 100644 SOURCES/glibc-rh1380680-3.patch create mode 100644 SOURCES/glibc-rh1380680-4.patch create mode 100644 SOURCES/glibc-rh1380680-5.patch create mode 100644 SOURCES/glibc-rh1380680-6.patch create mode 100644 SOURCES/glibc-rh1380680-7.patch create mode 100644 SOURCES/glibc-rh1380680-8.patch create mode 100644 SOURCES/glibc-rh1380680-9.patch create mode 100644 SOURCES/glibc-rh1383951.patch create mode 100644 SOURCES/glibc-rh1385003.patch create mode 100644 SOURCES/glibc-rh1385004-1.patch create mode 100644 SOURCES/glibc-rh1385004-10.patch create mode 100644 SOURCES/glibc-rh1385004-11.patch create mode 100644 SOURCES/glibc-rh1385004-12.patch create mode 100644 SOURCES/glibc-rh1385004-13.patch create mode 100644 SOURCES/glibc-rh1385004-14.patch create mode 100644 SOURCES/glibc-rh1385004-15.patch create mode 100644 SOURCES/glibc-rh1385004-16.patch create mode 100644 SOURCES/glibc-rh1385004-17.patch create mode 100644 SOURCES/glibc-rh1385004-18.patch create mode 100644 SOURCES/glibc-rh1385004-19.patch create mode 100644 SOURCES/glibc-rh1385004-2.patch create mode 100644 SOURCES/glibc-rh1385004-20.patch create mode 100644 SOURCES/glibc-rh1385004-21.patch create mode 100644 SOURCES/glibc-rh1385004-22.patch create mode 100644 SOURCES/glibc-rh1385004-23.patch create mode 100644 SOURCES/glibc-rh1385004-24.patch create mode 100644 SOURCES/glibc-rh1385004-3.patch create mode 100644 SOURCES/glibc-rh1385004-4.patch create mode 100644 SOURCES/glibc-rh1385004-5.patch create mode 100644 SOURCES/glibc-rh1385004-6.patch create mode 100644 SOURCES/glibc-rh1385004-7.patch create mode 100644 SOURCES/glibc-rh1385004-8.patch create mode 100644 SOURCES/glibc-rh1385004-9.patch create mode 100644 SOURCES/glibc-rh1387874.patch create mode 100644 SOURCES/glibc-rh1392540.patch create mode 100644 SOURCES/glibc-rh1398244.patch create mode 100644 SOURCES/glibc-rh1398413.patch create mode 100644 SOURCES/glibc-rh1404435.patch create mode 100644 SOURCES/glibc-rh1409611.patch create mode 100644 SOURCES/glibc-rh1413638-1.patch create mode 100644 SOURCES/glibc-rh1413638-2.patch create mode 100644 SOURCES/glibc-rh1417205.patch create mode 100644 SOURCES/glibc-rh1418978-0.patch create mode 100644 SOURCES/glibc-rh1418978-1.patch create mode 100644 SOURCES/glibc-rh1418978-2-1.patch create mode 100644 SOURCES/glibc-rh1418978-2-2.patch create mode 100644 SOURCES/glibc-rh1418978-2-3.patch create mode 100644 SOURCES/glibc-rh1418978-2-4.patch create mode 100644 SOURCES/glibc-rh1418978-2-5.patch create mode 100644 SOURCES/glibc-rh1418978-2-6.patch create mode 100644 SOURCES/glibc-rh1418978-3-1.patch create mode 100644 SOURCES/glibc-rh1418978-3-2.patch create mode 100644 SOURCES/glibc-rh1418978-max_align_t.patch create mode 100644 SOURCES/glibc-rh1418997.patch create mode 100644 SOURCES/glibc-rh1421155.patch create mode 100644 SOURCES/glibc-rh1435615.patch create mode 100644 SOURCES/glibc-rh1436312.patch create mode 100644 SOURCES/glibc-rh1439165-syscall-names.patch create mode 100644 SOURCES/glibc-rh1439165.patch create mode 100644 SOURCES/glibc-rh1440250.patch create mode 100644 SOURCES/glibc-rh1443236.patch create mode 100644 SOURCES/glibc-rh1445644.patch create mode 100644 SOURCES/glibc-rh1445781-1.patch create mode 100644 SOURCES/glibc-rh1445781-2.patch create mode 100644 SOURCES/glibc-rh1447556.patch create mode 100644 SOURCES/glibc-rh1448822.patch create mode 100644 SOURCES/glibc-rh1452720-1.patch create mode 100644 SOURCES/glibc-rh1452720-2.patch create mode 100644 SOURCES/glibc-rh1452720-3.patch create mode 100644 SOURCES/glibc-rh1452720-4.patch create mode 100644 SOURCES/glibc-rh1452721-1.patch create mode 100644 SOURCES/glibc-rh1452721-2.patch create mode 100644 SOURCES/glibc-rh1452721-3.patch create mode 100644 SOURCES/glibc-rh1452721-4.patch create mode 100644 SOURCES/glibc-rh1457177-1.patch create mode 100644 SOURCES/glibc-rh1457177-2.patch create mode 100644 SOURCES/glibc-rh1457177-3.patch create mode 100644 SOURCES/glibc-rh1457177-4.patch create mode 100644 SOURCES/glibc-rh1463692-1.patch create mode 100644 SOURCES/glibc-rh1463692-2.patch create mode 100644 SOURCES/glibc-rh1468807.patch create mode 100644 SOURCES/glibc-rh1498566.patch create mode 100644 SOURCES/glibc-rh1498925-1.patch create mode 100644 SOURCES/glibc-rh1498925-2.patch create mode 100644 SOURCES/glibc-rh1500908.patch create mode 100644 SOURCES/glibc-rh1503854-1.patch create mode 100644 SOURCES/glibc-rh1503854-2.patch create mode 100644 SOURCES/glibc-rh1503854-3.patch create mode 100644 SOURCES/glibc-rh1504809-1.patch create mode 100644 SOURCES/glibc-rh1504809-2.patch create mode 100644 SOURCES/glibc-rh1504969.patch create mode 100644 SOURCES/glibc-rh1523119-compat-symbols.patch create mode 100644 SOURCES/glibc-rh1527904-1.patch create mode 100644 SOURCES/glibc-rh1527904-2.patch create mode 100644 SOURCES/glibc-rh1527904-3.patch create mode 100644 SOURCES/glibc-rh1527904-4.patch create mode 100644 SOURCES/glibc-rh1529982.patch create mode 100644 SOURCES/glibc-rh1534635.patch create mode 100644 SOURCES/glibc-rh677316-RES_USE_INET6.patch create mode 100644 SOURCES/glibc-rh677316-alloc_buffer.patch create mode 100644 SOURCES/glibc-rh677316-check_mul_overflow_size_t.patch create mode 100644 SOURCES/glibc-rh677316-dynarray.patch create mode 100644 SOURCES/glibc-rh677316-fgets_unlocked.patch create mode 100644 SOURCES/glibc-rh677316-h_errno.patch create mode 100644 SOURCES/glibc-rh677316-hesiod.patch create mode 100644 SOURCES/glibc-rh677316-in6addr_any.patch create mode 100644 SOURCES/glibc-rh677316-inet_pton-zeros.patch create mode 100644 SOURCES/glibc-rh677316-inet_pton.patch create mode 100644 SOURCES/glibc-rh677316-legacy.patch create mode 100644 SOURCES/glibc-rh677316-libc-diag.patch create mode 100644 SOURCES/glibc-rh677316-libc-lock.patch create mode 100644 SOURCES/glibc-rh677316-libc-pointer-arith.patch create mode 100644 SOURCES/glibc-rh677316-mtrace.patch create mode 100644 SOURCES/glibc-rh677316-netdb-reentrant.patch create mode 100644 SOURCES/glibc-rh677316-qsort_r.patch create mode 100644 SOURCES/glibc-rh677316-res_state.patch create mode 100644 SOURCES/glibc-rh677316-resolv.patch create mode 100644 SOURCES/glibc-rh677316-scratch_buffer.patch create mode 100644 SOURCES/glibc-rh697421.patch create mode 100644 SOURCES/glibc-rh731833-hwcap-2.patch create mode 100644 SOURCES/glibc-rh731833-hwcap-3.patch create mode 100644 SOURCES/glibc-rh731833-hwcap-4.patch create mode 100644 SOURCES/glibc-rh731833-hwcap-5.patch create mode 100644 SOURCES/glibc-rh731833-hwcap.patch create mode 100644 SOURCES/glibc-rh731833-libm-2.patch create mode 100644 SOURCES/glibc-rh731833-libm-3.patch create mode 100644 SOURCES/glibc-rh731833-libm-4.patch create mode 100644 SOURCES/glibc-rh731833-libm-5.patch create mode 100644 SOURCES/glibc-rh731833-libm-6.patch create mode 100644 SOURCES/glibc-rh731833-libm-7.patch create mode 100644 SOURCES/glibc-rh731833-libm.patch create mode 100644 SOURCES/glibc-rh731833-misc-2.patch create mode 100644 SOURCES/glibc-rh731833-misc-3.patch create mode 100644 SOURCES/glibc-rh731833-misc-4.patch create mode 100644 SOURCES/glibc-rh731833-misc-5.patch create mode 100644 SOURCES/glibc-rh731833-misc-6.patch create mode 100644 SOURCES/glibc-rh731833-misc.patch create mode 100644 SOURCES/glibc-rh731833-rtkaio-2.patch create mode 100644 SOURCES/glibc-rh731833-rtkaio.patch create mode 100644 SOURCES/glibc-rh731835-0.patch create mode 100644 SOURCES/glibc-rh731835-1.patch create mode 100644 SOURCES/glibc-rh731835-2.patch create mode 100644 SOURCES/glibc-rh731837-00.patch create mode 100644 SOURCES/glibc-rh731837-01.patch create mode 100644 SOURCES/glibc-rh731837-02.patch create mode 100644 SOURCES/glibc-rh731837-03.patch create mode 100644 SOURCES/glibc-rh731837-04.patch create mode 100644 SOURCES/glibc-rh731837-05.patch create mode 100644 SOURCES/glibc-rh731837-06.patch create mode 100644 SOURCES/glibc-rh731837-07.patch create mode 100644 SOURCES/glibc-rh731837-08.patch create mode 100644 SOURCES/glibc-rh731837-09.patch create mode 100644 SOURCES/glibc-rh731837-10.patch create mode 100644 SOURCES/glibc-rh731837-11.patch create mode 100644 SOURCES/glibc-rh731837-12.patch create mode 100644 SOURCES/glibc-rh731837-13.patch create mode 100644 SOURCES/glibc-rh731837-14.patch create mode 100644 SOURCES/glibc-rh731837-15.patch create mode 100644 SOURCES/glibc-rh731837-16.patch create mode 100644 SOURCES/glibc-rh731837-17.patch create mode 100644 SOURCES/glibc-rh731837-18.patch create mode 100644 SOURCES/glibc-rh731837-19.patch create mode 100644 SOURCES/glibc-rh731837-20.patch create mode 100644 SOURCES/glibc-rh731837-21.patch create mode 100644 SOURCES/glibc-rh731837-22.patch create mode 100644 SOURCES/glibc-rh731837-23.patch create mode 100644 SOURCES/glibc-rh731837-24.patch create mode 100644 SOURCES/glibc-rh731837-25.patch create mode 100644 SOURCES/glibc-rh731837-26.patch create mode 100644 SOURCES/glibc-rh731837-27.patch create mode 100644 SOURCES/glibc-rh731837-28.patch create mode 100644 SOURCES/glibc-rh731837-29.patch create mode 100644 SOURCES/glibc-rh731837-30.patch create mode 100644 SOURCES/glibc-rh731837-31.patch create mode 100644 SOURCES/glibc-rh731837-32.patch create mode 100644 SOURCES/glibc-rh731837-33.patch create mode 100644 SOURCES/glibc-rh731837-33A.patch create mode 100644 SOURCES/glibc-rh731837-34.patch create mode 100644 SOURCES/glibc-rh731837-35.patch create mode 100644 SOURCES/glibc-rh731837-36.patch create mode 100644 SOURCES/glibc-rh739743.patch create mode 100644 SOURCES/glibc-rh741105.patch create mode 100644 SOURCES/glibc-rh742038.patch create mode 100644 SOURCES/glibc-rh757881.patch create mode 100644 SOURCES/glibc-rh804768-bugfix.patch create mode 100644 SOURCES/glibc-rh819430.patch create mode 100644 SOURCES/glibc-rh825061.patch create mode 100644 SOURCES/glibc-rh827510.patch create mode 100644 SOURCES/glibc-rh841318.patch create mode 100644 SOURCES/glibc-rh841653-0.patch create mode 100644 SOURCES/glibc-rh841653-1.patch create mode 100644 SOURCES/glibc-rh841653-10.patch create mode 100644 SOURCES/glibc-rh841653-11.patch create mode 100644 SOURCES/glibc-rh841653-12.patch create mode 100644 SOURCES/glibc-rh841653-13.patch create mode 100644 SOURCES/glibc-rh841653-14.patch create mode 100644 SOURCES/glibc-rh841653-15.patch create mode 100644 SOURCES/glibc-rh841653-16.patch create mode 100644 SOURCES/glibc-rh841653-17.patch create mode 100644 SOURCES/glibc-rh841653-2.patch create mode 100644 SOURCES/glibc-rh841653-3.patch create mode 100644 SOURCES/glibc-rh841653-4.patch create mode 100644 SOURCES/glibc-rh841653-5.patch create mode 100644 SOURCES/glibc-rh841653-6.patch create mode 100644 SOURCES/glibc-rh841653-7.patch create mode 100644 SOURCES/glibc-rh841653-8.patch create mode 100644 SOURCES/glibc-rh841653-9.patch create mode 100644 SOURCES/glibc-rh841787.patch create mode 100644 SOURCES/glibc-rh884008.patch create mode 100644 SOURCES/glibc-rh892777.patch create mode 100644 SOURCES/glibc-rh905184.patch create mode 100644 SOURCES/glibc-rh905877.patch create mode 100644 SOURCES/glibc-rh906468-1.patch create mode 100644 SOURCES/glibc-rh906468-2.patch create mode 100644 SOURCES/glibc-rh911307-2.patch create mode 100644 SOURCES/glibc-rh911307-3.patch create mode 100644 SOURCES/glibc-rh911307.patch create mode 100644 SOURCES/glibc-rh950093.patch create mode 100644 SOURCES/glibc-rh952799.patch create mode 100644 SOURCES/glibc-rh958652.patch create mode 100644 SOURCES/glibc-rh959034.patch create mode 100644 SOURCES/glibc-rh966259.patch create mode 100644 SOURCES/glibc-rh966633.patch create mode 100644 SOURCES/glibc-rh970791.patch create mode 100644 SOURCES/glibc-rh971416-1.patch create mode 100644 SOURCES/glibc-rh971416-2.patch create mode 100644 SOURCES/glibc-rh971416-3.patch create mode 100644 SOURCES/glibc-rh971589.patch create mode 100644 SOURCES/glibc-rh977110-2.patch create mode 100644 SOURCES/glibc-rh977110.patch create mode 100644 SOURCES/glibc-rh977870.patch create mode 100644 SOURCES/glibc-rh977872.patch create mode 100644 SOURCES/glibc-rh977874.patch create mode 100644 SOURCES/glibc-rh977875.patch create mode 100644 SOURCES/glibc-rh977887-2.patch create mode 100644 SOURCES/glibc-rh977887.patch create mode 100644 SOURCES/glibc-rh979363.patch create mode 100644 SOURCES/glibc-rh980323.patch create mode 100644 SOURCES/glibc-rh981332.patch create mode 100644 SOURCES/glibc-rh984828.patch create mode 100644 SOURCES/glibc-rh988869.patch create mode 100644 SOURCES/glibc-rh989861.patch create mode 100644 SOURCES/glibc-rh989862-2.patch create mode 100644 SOURCES/glibc-rh989862-3.patch create mode 100644 SOURCES/glibc-rh989862.patch create mode 100644 SOURCES/glibc-rh990388-2.patch create mode 100644 SOURCES/glibc-rh990388-3.patch create mode 100644 SOURCES/glibc-rh990388-4.patch create mode 100644 SOURCES/glibc-rh990388.patch create mode 100644 SOURCES/glibc-rh990481-CVE-2013-4788.patch create mode 100644 SOURCES/glibc-rh996227.patch create mode 100644 SOURCES/glibc-rtkaio-inc-pthread.patch create mode 100644 SOURCES/glibc-stap-libm.patch create mode 100644 SOURCES/verify.md5 diff --git a/SOURCES/glibc-aa64-commonpagesize-64k.patch b/SOURCES/glibc-aa64-commonpagesize-64k.patch new file mode 100644 index 00000000..657d1cb9 --- /dev/null +++ b/SOURCES/glibc-aa64-commonpagesize-64k.patch @@ -0,0 +1,11 @@ +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/preconfigure 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/preconfigure 2014-05-12 14:29:52.007239252 -0400 +@@ -8,7 +8,7 @@ + case "$machine" in + aarch64*) + # Parameters to allow auto-detection of -z relro. +- libc_commonpagesize=0x1000 ++ libc_commonpagesize=0x10000 + libc_relro_required=yes + ;; + esac diff --git a/SOURCES/glibc-aa64-setcontext.patch b/SOURCES/glibc-aa64-setcontext.patch new file mode 100644 index 00000000..f76849c5 --- /dev/null +++ b/SOURCES/glibc-aa64-setcontext.patch @@ -0,0 +1,220 @@ +Backport + +37d350073888887637aa67dddf988d9c4b226032 \ + aarch64: Re-implement setcontext without rt_sigreturn syscall +03ea4d9b6916857e3c2a021f55d2a853cb837398 \ + [AArch64] Simplify getcontext pstate initialization. +6e445a3d2bdf152ebf57d1c92bfea1828e070743 \ + [AArch64] Ensure getcontext() initializes PSTATE. + + +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S +index aff2e32..70b2e32 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S +@@ -1,6 +1,6 @@ + /* Save current context. + +- Copyright (C) 2009-2012 Free Software Foundation, Inc. ++ Copyright (C) 2009-2014 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + +@@ -53,6 +53,9 @@ ENTRY(__getcontext) + mov x2, sp + str x2, [x0, oSP] + ++ /* Initialize the pstate. */ ++ str xzr, [x0, oPSTATE] ++ + /* Figure out where to place the first context extension + block. */ + add x2, x0, #oEXTENSION +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S +index a98f67f..f45a655 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S +@@ -1,6 +1,6 @@ + /* Set current context. + +- Copyright (C) 2009-2012 Free Software Foundation, Inc. ++ Copyright (C) 2009-2014 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + +@@ -22,68 +22,108 @@ + #include "ucontext_i.h" + #include "ucontext-internal.h" + +-/* int setcontext (const ucontext_t *ucp) */ ++/* int __setcontext (const ucontext_t *ucp) + +- .text +- +-ENTRY(__setcontext) +- +- /* Create a signal frame on the stack: +- +- fp +- lr +- ... +- sp-> rt_sigframe +- */ +- +- stp x29, x30, [sp, -16]! +- cfi_adjust_cfa_offset (16) +- cfi_rel_offset (x29, 0) +- cfi_rel_offset (x30, 8) +- +- mov x29, sp +- cfi_def_cfa_register (x29) +- +- /* Allocate space for the sigcontext. */ +- mov w3, #((RT_SIGFRAME_SIZE + SP_ALIGN_SIZE) & SP_ALIGN_MASK) +- sub sp, sp, x3 ++ Restores the machine context in UCP and thereby resumes execution ++ in that context. + +- /* Compute the base address of the ucontext structure. */ +- add x1, sp, #RT_SIGFRAME_UCONTEXT ++ This implementation is intended to be used for *synchronous* context ++ switches only. Therefore, it does not have to restore anything ++ other than the PRESERVED state. */ + +- /* Only ucontext is required in the frame, *copy* it in. */ +- +-#if UCONTEXT_SIZE % 16 +-#error The implementation of setcontext.S assumes sizeof(ucontext_t) % 16 == 0 +-#endif +- +- mov x2, #UCONTEXT_SIZE / 16 +-0: +- ldp x3, x4, [x0], #16 +- stp x3, x4, [x1], #16 +- sub x2, x2, 1 +- cbnz x2, 0b ++ .text + +- /* rt_sigreturn () -- no arguments, sp points to struct rt_sigframe. */ +- mov x8, SYS_ify (rt_sigreturn) ++ENTRY (__setcontext) ++ /* Save a copy of UCP. */ ++ mov x9, x0 ++ ++ /* Set the signal mask with ++ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */ ++ mov x0, #SIG_SETMASK ++ add x1, x9, #UCONTEXT_SIGMASK ++ mov x2, #0 ++ mov x3, #_NSIG8 ++ mov x8, SYS_ify (rt_sigprocmask) + svc 0 +- +- /* Ooops we failed. Recover the stack */ +- +- mov sp, x29 +- cfi_def_cfa_register (sp) +- +- ldp x29, x30, [sp], 16 +- cfi_adjust_cfa_offset (16) +- cfi_restore (x29) +- cfi_restore (x30) +- b C_SYMBOL_NAME(__syscall_error) +- ++ cbz x0, 1f ++ b C_SYMBOL_NAME (__syscall_error) ++1: ++ /* Restore the general purpose registers. */ ++ mov x0, x9 ++ cfi_def_cfa (x0, 0) ++ cfi_offset (x18, oX0 + 18 * SZREG) ++ cfi_offset (x19, oX0 + 19 * SZREG) ++ cfi_offset (x20, oX0 + 20 * SZREG) ++ cfi_offset (x21, oX0 + 21 * SZREG) ++ cfi_offset (x22, oX0 + 22 * SZREG) ++ cfi_offset (x23, oX0 + 23 * SZREG) ++ cfi_offset (x24, oX0 + 24 * SZREG) ++ cfi_offset (x25, oX0 + 25 * SZREG) ++ cfi_offset (x26, oX0 + 26 * SZREG) ++ cfi_offset (x27, oX0 + 27 * SZREG) ++ cfi_offset (x28, oX0 + 28 * SZREG) ++ cfi_offset (x29, oX0 + 29 * SZREG) ++ cfi_offset (x30, oX0 + 30 * SZREG) ++ ++ cfi_offset ( d8, oV0 + 8 * SZVREG) ++ cfi_offset ( d9, oV0 + 9 * SZVREG) ++ cfi_offset (d10, oV0 + 10 * SZVREG) ++ cfi_offset (d11, oV0 + 11 * SZVREG) ++ cfi_offset (d12, oV0 + 12 * SZVREG) ++ cfi_offset (d13, oV0 + 13 * SZVREG) ++ cfi_offset (d14, oV0 + 14 * SZVREG) ++ cfi_offset (d15, oV0 + 15 * SZVREG) ++ ldp x18, x19, [x0, oX0 + 18 * SZREG] ++ ldp x20, x21, [x0, oX0 + 20 * SZREG] ++ ldp x22, x23, [x0, oX0 + 22 * SZREG] ++ ldp x24, x25, [x0, oX0 + 24 * SZREG] ++ ldp x26, x27, [x0, oX0 + 26 * SZREG] ++ ldp x28, x29, [x0, oX0 + 28 * SZREG] ++ ldr x30, [x0, oX0 + 30 * SZREG] ++ ldr x2, [x0, oSP] ++ mov sp, x2 ++ ++ /* Check for FP SIMD context. We don't support restoring ++ contexts created by the kernel, so this context must have ++ been created by getcontext. Hence we can rely on the ++ first extension block being the FP SIMD context. */ ++ add x2, x0, #oEXTENSION ++ ++ mov w3, #(FPSIMD_MAGIC & 0xffff) ++ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16 ++ ldr w1, [x2, #oHEAD + oMAGIC] ++ cmp w1, w3 ++ b.ne 2f ++ ++ /* Restore the FP SIMD context. */ ++ add x3, x2, #oV0 + 8 * SZVREG ++ ldp d8, d9, [x3], #2 * SZVREG ++ ldp d10, d11, [x3], #2 * SZVREG ++ ldp d12, d13, [x3], #2 * SZVREG ++ ldp d14, d15, [x3], #2 * SZVREG ++ ++ add x3, x2, oFPSR ++ ++ ldr w4, [x3] ++ msr fpsr, x4 ++ ++ ldr w4, [x3, oFPCR - oFPSR] ++ msr fpcr, x4 ++ ++2: ++ ldr x16, [x0, oPC] ++ /* Restore arg registers. */ ++ ldp x2, x3, [x0, oX0 + 2 * SZREG] ++ ldp x4, x5, [x0, oX0 + 4 * SZREG] ++ ldp x6, x7, [x0, oX0 + 6 * SZREG] ++ ldp x0, x1, [x0, oX0 + 0 * SZREG] ++ /* Jump to the new pc value. */ ++ br x16 + PSEUDO_END (__setcontext) + weak_alias (__setcontext, setcontext) + +-ENTRY(__startcontext) ++ENTRY (__startcontext) + mov x0, x19 + cbnz x0, __setcontext +-1: b HIDDEN_JUMPTARGET(_exit) +-END(__startcontext) ++1: b HIDDEN_JUMPTARGET (_exit) ++END (__startcontext) +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym +index 1afff78..ab3930c 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym +@@ -37,6 +37,7 @@ STACK_FLAGS stack (ss_flags) + oX0 mcontext (regs) + oSP mcontext (sp) + oPC mcontext (pc) ++oPSTATE mcontext (pstate) + oEXTENSION mcontext (__reserved) + + #define fpsimd_context(member) offsetof (struct fpsimd_context, member) diff --git a/SOURCES/glibc-aarch64-add-ptr_mangle-support.patch b/SOURCES/glibc-aarch64-add-ptr_mangle-support.patch new file mode 100644 index 00000000..cf3bfdad --- /dev/null +++ b/SOURCES/glibc-aarch64-add-ptr_mangle-support.patch @@ -0,0 +1,233 @@ +commit 9188b6818a3d1a6e6d89bf10fa4aea27a591494c +Author: Venkataramanan Kumar +Date: Wed Jan 1 17:47:14 2014 +0000 + + [AArch64] Pointer mangling support for AArch64. + +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S +index 250f2af..2d38bbf 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/__longjmp.S +@@ -50,8 +50,12 @@ ENTRY (__longjmp) + ldp x23, x24, [x0, #JB_X23<<3] + ldp x25, x26, [x0, #JB_X25<<3] + ldp x27, x28, [x0, #JB_X27<<3] ++#ifdef PTR_DEMANGLE ++ ldp x29, x4, [x0, #JB_X29<<3] ++ PTR_DEMANGLE (x30, x4, x3, x2) ++#else + ldp x29, x30, [x0, #JB_X29<<3] +- ++#endif + ldp d8, d9, [x0, #JB_D8<<3] + ldp d10, d11, [x0, #JB_D10<<3] + ldp d12, d13, [x0, #JB_D12<<3] +@@ -87,8 +91,12 @@ ENTRY (__longjmp) + cfi_same_value(d13) + cfi_same_value(d14) + cfi_same_value(d15) +- +- ldr x5, [x0, #JB_SP<<3] ++#ifdef PTR_DEMANGLE ++ ldr x4, [x0, #JB_SP<<3] ++ PTR_DEMANGLE (x5, x4, x3, x2) ++#else ++ ldr x5, [x0, #JB_SP<<3] ++#endif + mov sp, x5 + cmp x1, #0 + mov x0, #1 +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h +index 84c2ccc..bcf2afa 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-offsets.h +@@ -39,6 +39,22 @@ + #define JB_D14 20 + #define JB_D15 21 + ++#ifndef __ASSEMBLER__ ++#include ++#include ++#include ++ ++static inline uintptr_t __attribute__ ((unused)) ++_jmpbuf_sp (__jmp_buf jmpbuf) ++{ ++ uintptr_t sp = jmpbuf[JB_SP]; ++#ifdef PTR_DEMANGLE ++ PTR_DEMANGLE (sp); ++#endif ++ return sp; ++} ++#endif ++ + /* Helper for generic ____longjmp_chk(). */ + #define JB_FRAME_ADDRESS(buf) \ +- ((void *) (buf[JB_SP])) ++ ((void *) _jmpbuf_sp (buf)) +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h +index 22c6c2b..39a5dc2 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/jmpbuf-unwind.h +@@ -29,16 +29,6 @@ + #define _JMPBUF_CFA_UNWINDS_ADJ(jmpbuf, context, adj) \ + _JMPBUF_UNWINDS_ADJ (jmpbuf, (void *) _Unwind_GetCFA (context), adj) + +-static inline uintptr_t __attribute__ ((unused)) +-_jmpbuf_sp (__jmp_buf jmpbuf) +-{ +- uintptr_t sp = jmpbuf[JB_SP]; +-#ifdef PTR_DEMANGLE +- PTR_DEMANGLE (sp); +-#endif +- return sp; +-} +- + #define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +index cb94e01..5822abd 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +@@ -39,13 +39,25 @@ ENTRY (__sigsetjmp) + stp x23, x24, [x0, #JB_X23<<3] + stp x25, x26, [x0, #JB_X25<<3] + stp x27, x28, [x0, #JB_X27<<3] ++ ++#ifdef PTR_MANGLE ++ PTR_MANGLE (x4, x30, x3, x2) ++ stp x29, x4, [x0, #JB_X29<<3] ++#else + stp x29, x30, [x0, #JB_X29<<3] ++#endif + stp d8, d9, [x0, #JB_D8<<3] + stp d10, d11, [x0, #JB_D10<<3] + stp d12, d13, [x0, #JB_D12<<3] + stp d14, d15, [x0, #JB_D14<<3] ++#ifdef PTR_MANGLE ++ mov x4, sp ++ PTR_MANGLE (x5, x4, x3, x2) ++ str x5, [x0, #JB_SP<<3] ++#else + mov x2, sp + str x2, [x0, #JB_SP<<3] ++#endif + #if defined NOT_IN_libc && defined IS_IN_rtld + /* In ld.so we never save the signal mask */ + mov w0, #0 +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h +index 0dd597a..7169ba7 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/sysdep.h +@@ -78,6 +78,17 @@ + # define L(name) .L##name + #endif + ++/* Load or store to/from a pc-relative EXPR into/from R, using T. */ ++#define LDST_PCREL(OP, R, T, EXPR) \ ++ adrp T, EXPR; \ ++ OP R, [T, #:lo12:EXPR];\ ++ ++/* Load or store to/from a got-relative EXPR into/from R, using T. */ ++#define LDST_GLOBAL(OP, R, T, EXPR) \ ++ adrp T, :got:EXPR; \ ++ ldr T, [T, #:got_lo12:EXPR];\ ++ OP R, [T]; ++ + /* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +index f3f0ada..5ccf1da 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -371,8 +371,44 @@ __local_syscall_error: \ + + #endif /* __ASSEMBLER__ */ + +-/* Pointer mangling is not yet supported for AArch64. */ +-#define PTR_MANGLE(var) (void) (var) +-#define PTR_DEMANGLE(var) (void) (var) ++/* Pointer mangling is supported for AArch64. */ ++#if (defined NOT_IN_libc && defined IS_IN_rtld) || \ ++ (!defined SHARED && (!defined NOT_IN_libc || defined IS_IN_libpthread)) ++# ifdef __ASSEMBLER__ ++# define PTR_MANGLE(dst, src, guard, tmp) \ ++ LDST_PCREL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \ ++ PTR_MANGLE2 (dst, src, guard) ++/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ ++# define PTR_MANGLE2(dst, src, guard)\ ++ eor dst, src, guard ++# define PTR_DEMANGLE(dst, src, guard, tmp)\ ++ PTR_MANGLE (dst, src, guard, tmp) ++# define PTR_DEMANGLE2(dst, src, guard)\ ++ PTR_MANGLE2 (dst, src, guard) ++# else ++extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; ++# define PTR_MANGLE(var) \ ++ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) ++# define PTR_DEMANGLE(var) PTR_MANGLE (var) ++# endif ++#else ++# ifdef __ASSEMBLER__ ++# define PTR_MANGLE(dst, src, guard, tmp) \ ++ LDST_GLOBAL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard)); \ ++ PTR_MANGLE2 (dst, src, guard) ++/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ ++# define PTR_MANGLE2(dst, src, guard)\ ++ eor dst, src, guard ++# define PTR_DEMANGLE(dst, src, guard, tmp)\ ++ PTR_MANGLE (dst, src, guard, tmp) ++# define PTR_DEMANGLE2(dst, src, guard)\ ++ PTR_MANGLE2 (dst, src, guard) ++# else ++extern uintptr_t __pointer_chk_guard attribute_relro; ++# define PTR_MANGLE(var) \ ++ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) ++# define PTR_DEMANGLE(var) PTR_MANGLE (var) ++# endif ++#endif + + #endif /* linux/aarch64/sysdep.h */ +commit 0b1f8e35640f5b3f7af11764ade3ff060211c309 +Author: Carlos O'Donell +Date: Mon Sep 23 01:44:38 2013 -0400 + + BZ #15754: Fix test case for ARM. + + Statically built binaries use __pointer_chk_guard_local, + while dynamically built binaries use __pointer_chk_guard. + Provide the right definition depending on the test case + we are building. + +diff --git glibc-2.17-c758a686/elf/Makefile glibc-2.17-c758a686/elf/Makefile +index cb8da93..27d249b 100644 +--- glibc-2.17-c758a686/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -1019,6 +1019,9 @@ tst-stackguard1-ARGS = --command "$(host-test-program-cmd) --child" + tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" + + tst-ptrguard1-ARGS = --command "$(host-built-program-cmd) --child" ++# When built statically, the pointer guard interface uses ++# __pointer_chk_guard_local. ++CFLAGS-tst-ptrguard1-static.c = -DPTRGUARD_LOCAL + tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child" + + $(objpfx)tst-leaks1: $(libdl) +diff --git glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h +index 4fa3d96..b4a6b23 100644 +--- glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h ++++ glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h +@@ -3,5 +3,10 @@ + extern uintptr_t __stack_chk_guard; + #define STACK_CHK_GUARD __stack_chk_guard + ++#ifdef PTRGUARD_LOCAL + extern uintptr_t __pointer_chk_guard_local; +-#define POINTER_CHK_GUARD __pointer_chk_guard_local ++# define POINTER_CHK_GUARD __pointer_chk_guard_local ++#else ++extern uintptr_t __pointer_chk_guard; ++# define POINTER_CHK_GUARD __pointer_chk_guard ++#endif diff --git a/SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch b/SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch new file mode 100644 index 00000000..e6fdd91f --- /dev/null +++ b/SOURCES/glibc-aarch64-fpu-optional-trapping-exceptions.patch @@ -0,0 +1,122 @@ +commit 302949e2940a9da3f6364a1574619e621b7e1e71 +Author: Marcus Shawcroft +Date: Fri Mar 7 14:05:20 2014 +0000 + + [PATCH] [AArch64] Optional trapping exceptions support. + + Trapping exceptions in AArch64 are optional. The relevant exception + control bits in FPCR are are defined as RES0 hence the absence of + support can be detected by reading back the FPCR and comparing with + the desired value. + +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/fpu/feenablxcpt.c ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/fpu/feenablxcpt.c +@@ -35,5 +35,18 @@ feenableexcept (int excepts) + + _FPU_SETCW (fpcr); + ++ /* Trapping exceptions are optional in AArch64 the relevant enable ++ bits in FPCR are RES0 hence the absence of support can be ++ detected by reading back the FPCR and comparing with the required ++ value. */ ++ if (excepts) ++ { ++ fpu_control_t updated_fpcr; ++ ++ _FPU_GETCW (updated_fpcr); ++ if (((updated_fpcr >> FE_EXCEPT_SHIFT) & excepts) != excepts) ++ return -1; ++ } ++ + return original_excepts; + } +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/fpu/fesetenv.c ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/fpu/fesetenv.c +@@ -24,6 +24,7 @@ fesetenv (const fenv_t *envp) + { + fpu_control_t fpcr; + fpu_fpsr_t fpsr; ++ fpu_control_t updated_fpcr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); +@@ -51,6 +52,15 @@ fesetenv (const fenv_t *envp) + + _FPU_SETCW (fpcr); + ++ /* Trapping exceptions are optional in AArch64 the relevant enable ++ bits in FPCR are RES0 hence the absence of support can be ++ detected by reading back the FPCR and comparing with the required ++ value. */ ++ ++ _FPU_GETCW (updated_fpcr); ++ if ((updated_fpcr & fpcr) != fpcr) ++ return 1; ++ + return 0; + } + +commit 423a7160af7fcffc61aac5e2e36d0b6b5b083214 +Author: Wilco +Date: Thu Apr 17 09:39:27 2014 +0100 + + Add fenv test support for targets which don't have FP traps. + +(removed unnecessary code to limit it to test-fenv.c --kyle) + +--- glibc-2.17-c758a686/math/test-fenv.c ++++ glibc-2.17-c758a686/math/test-fenv.c +@@ -233,14 +234,9 @@ feenv_nomask_test (const char *flag_name, int fe_exc) + #if defined FE_NOMASK_ENV + int status; + pid_t pid; +- fenv_t saved; + +- fegetenv (&saved); +- errno = 0; +- fesetenv (FE_NOMASK_ENV); +- status = errno; +- fesetenv (&saved); +- if (status == ENOSYS) ++ if (1 ++ && fesetenv (FE_NOMASK_ENV) != 0) + { + printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n"); + return; +@@ -349,7 +345,13 @@ feexcp_nomask_test (const char *flag_name, int fe_exc) + int status; + pid_t pid; + +- printf ("Test: after fedisableexcept (%s) processes will abort\n", ++ if (1 && feenableexcept (fe_exc) == -1) ++ { ++ printf ("Test: not testing feenableexcept, it isn't implemented.\n"); ++ return; ++ } ++ ++ printf ("Test: after feenableexcept (%s) processes will abort\n", + flag_name); + printf (" when feraiseexcept (%s) is called.\n", flag_name); + pid = fork (); +@@ -470,7 +472,6 @@ feenable_test (const char *flag_name, int fe_exc) + { + int excepts; + +- + printf ("Tests for feenableexcepts etc. with flag %s\n", flag_name); + + /* First disable all exceptions. */ +@@ -488,8 +489,12 @@ feenable_test (const char *flag_name, int fe_exc) + flag_name, excepts); + ++count_errors; + } +- + excepts = feenableexcept (fe_exc); ++ if (1 && excepts == -1) ++ { ++ printf ("Test: not testing feenableexcept, it isn't implemented.\n"); ++ return; ++ } + if (excepts == -1) + { + printf ("Test: feenableexcept (%s) failed\n", flag_name); diff --git a/SOURCES/glibc-aarch64-ifunc.patch b/SOURCES/glibc-aarch64-ifunc.patch new file mode 100644 index 00000000..62da5556 --- /dev/null +++ b/SOURCES/glibc-aarch64-ifunc.patch @@ -0,0 +1,216 @@ +diff --git glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h +index 8686fd5..2b10581 100644 +--- glibc-2.17-c758a686/elf/elf.h ++++ glibc-2.17-c758a686/elf/elf.h +@@ -2327,6 +2327,117 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_AARCH64_NONE 0 /* No relocation. */ + #define R_AARCH64_ABS64 257 /* Direct 64 bit. */ + #define R_AARCH64_ABS32 258 /* Direct 32 bit. */ ++#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ ++#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ ++#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ ++#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ ++#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ ++#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ ++#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ ++#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ ++#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ ++#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ ++#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ ++#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ ++#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ ++#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ ++#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ ++#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ ++#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ ++#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ ++#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ ++#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ ++#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ ++#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ ++#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ ++#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ ++#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ ++#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ ++#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ ++#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ ++#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ ++#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ ++#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ ++#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ ++#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ ++#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ ++#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ ++#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ ++#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ ++#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ ++#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ ++#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ ++#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ ++#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ ++#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ ++#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ ++#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ ++#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ ++#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ ++#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ ++#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ ++#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ ++#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ ++#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ ++#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ ++#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ ++#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ ++#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ ++#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ ++#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ ++#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ ++#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ ++#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ ++#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ ++#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ ++#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ ++#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ ++#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ ++#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ ++#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ ++#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ ++#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ ++#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ ++#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ ++#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ ++#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ ++#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ ++#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ ++#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ ++#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ ++#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ ++#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ ++#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ ++#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ ++#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ ++#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ ++#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ ++#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ ++#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ ++#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ ++#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ ++#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ ++#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ ++#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ ++#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ ++#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ ++#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ ++#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ ++#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ ++#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ ++#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ ++#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ ++#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ ++#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ ++#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ + #define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ + #define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ + #define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ +@@ -2335,6 +2446,7 @@ typedef Elf32_Addr Elf32_Conflict; + #define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */ + #define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */ + #define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ ++#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ + + /* ARM relocs. */ + +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h +index 32dee0f..9a48dc2 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-irel.h +@@ -1,6 +1,6 @@ + /* Machine-dependent ELF indirect relocation inline functions. + AArch64 version. +- Copyright (C) 2012 Free Software Foundation, Inc. ++ Copyright (C) 2012-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -22,15 +22,31 @@ + + #include + #include ++#include + +-/* AArch64 does not yet implement IFUNC support. However since +- 2011-06-20 provision of a elf_ifunc_invoke has been mandatory. */ ++#define ELF_MACHINE_IRELA 1 + + static inline ElfW(Addr) + __attribute ((always_inline)) + elf_ifunc_invoke (ElfW(Addr) addr) + { +- return ((ElfW(Addr) (*) (void)) (addr)) (); ++ return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap)); ++} ++ ++static inline void ++__attribute ((always_inline)) ++elf_irela (const ElfW(Rela) *reloc) ++{ ++ ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset; ++ const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); ++ ++ if (__glibc_likely (r_type == R_AARCH64_IRELATIVE)) ++ { ++ ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend); ++ *reloc_addr = value; ++ } ++ else ++ __libc_fatal ("unexpected reloc type in static binary"); + } + + #endif +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h +index b1878a7..1db5a5b 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/dl-machine.h +@@ -23,6 +23,7 @@ + + #include + #include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -336,6 +337,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + } + break; + ++ case R_AARCH64_IRELATIVE: ++ value = map->l_addr + reloc->r_addend; ++ value = elf_ifunc_invoke (value); ++ *reloc_addr = value; ++ break; ++ + default: + _dl_reloc_bad_type (map, r_type, 0); + break; +@@ -379,6 +386,13 @@ elf_machine_lazy_rel (struct link_map *map, + td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)]) + + map->l_addr); + } ++ else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE)) ++ { ++ ElfW(Addr) value = map->l_addr + reloc->r_addend; ++ if (__glibc_likely (!skip_ifunc)) ++ value = elf_ifunc_invoke (value); ++ *reloc_addr = value; ++ } + else + _dl_reloc_bad_type (map, r_type, 1); + } diff --git a/SOURCES/glibc-aarch64-rh1076760.patch b/SOURCES/glibc-aarch64-rh1076760.patch new file mode 100644 index 00000000..e8123e39 --- /dev/null +++ b/SOURCES/glibc-aarch64-rh1076760.patch @@ -0,0 +1,20 @@ +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/nptl/tls.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/nptl/tls.h +@@ -63,7 +63,7 @@ typedef struct + # define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + + /* Alignment requirements for the initial TCB. */ +-# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) ++# define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread) + + /* This is the size of the TCB. */ + # define TLS_TCB_SIZE sizeof (tcbhead_t) +@@ -72,7 +72,7 @@ typedef struct + # define TLS_PRE_TCB_SIZE sizeof (struct pthread) + + /* Alignment requirements for the TCB. */ +-# define TLS_TCB_ALIGN __alignof__ (tcbhead_t) ++# define TLS_TCB_ALIGN __alignof__ (struct pthread) + + /* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ diff --git a/SOURCES/glibc-aarch64-syscall-rewrite.patch b/SOURCES/glibc-aarch64-syscall-rewrite.patch new file mode 100644 index 00000000..e0bf93ad --- /dev/null +++ b/SOURCES/glibc-aarch64-syscall-rewrite.patch @@ -0,0 +1,539 @@ +From 9a7cb556eef7cb75b31d0bc05f73c6338dfd8e49 Mon Sep 17 00:00:00 2001 +From: Richard Henderson +Date: Fri, 30 May 2014 13:57:04 -0400 +Subject: [PATCH] aarch64: Backport syscall rewrite + +From commits: +a60339aaff82beadea6f580e587d64052cb5e3b8 Fix handling of nocancel syscall... +3612eb8f25d978e7e4ac536a34098091f737161c Merge rtld_errno offset w/ mem ref +a6b3657be6bc5067aeec98d990f60765361c6557 Merge __local_multiple_threads ofs... +c69abcee726a6f63d9e5e8f0d9dcc79374ee3ef8 Fix DO_CALL block comment +6e6c2d01ebb1ef839675c7151d2a114f53663386 Remove DOARGS/UNDOARGS macros +ca3cfa40c16ef34c74951a07a57cfcbcd58898b1 Tidy syscall error check +af4e8ef9443e258ebeb0ddf3c5c9579f24dfacd5 Tabify sysdep-cancel.h +a8b4f04ad7dff4f39797a7ab7f8babda54266026 Share code in sysdep-cancel.h +645d44abe3ca6253a9d4762f092e4a1b9d294b11 Pass regno parameter to SINGLE_THREAD_P +b5be4597716eff94149f5529c8eb2cd3b4296188 Improve syscall-cancel stack frame +74f31c18593111725478a991b395ae45661985a3 Fix error return from __ioctl +f0712b543eaddeca8fc6d7a8eb6b5b8d24105ce2 Remove PSEUDO_RET + +And a not-yet-committed cleanup to clone.S. +--- + ports/sysdeps/unix/sysv/linux/aarch64/clone.S | 51 +++--- + ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S | 13 +- + .../unix/sysv/linux/aarch64/nptl/localplt.data | 1 - + .../unix/sysv/linux/aarch64/nptl/sysdep-cancel.h | 189 +++++++-------------- + ports/sysdeps/unix/sysv/linux/aarch64/syscall.S | 4 +- + ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h | 84 ++------- + ports/sysdeps/unix/sysv/linux/aarch64/vfork.S | 4 +- + 7 files changed, 108 insertions(+), 238 deletions(-) + +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S +index 8be1464..d5c31f3 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S +@@ -39,46 +39,43 @@ + */ + .text + ENTRY(__clone) ++ /* Save args for the child. */ ++ mov x10, x0 ++ mov x11, x2 ++ mov x12, x3 ++ + /* Sanity check args. */ +- cbz x0, 1f +- cbz x1, 1f +- /* Insert the args onto the new stack. */ +- stp x0, x3, [x1, #-16]! /* Fn, arg. */ ++ mov x0, #-EINVAL ++ cbz x10, .Lsyscall_error ++ cbz x1, .Lsyscall_error + + /* Do the system call. */ ++ /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid. */ + mov x0, x2 /* flags */ +- + /* New sp is already in x1. */ + mov x2, x4 /* ptid */ + mov x3, x5 /* tls */ + mov x4, x6 /* ctid */ + +-#ifdef RESET_PID +- /* We rely on the kernel preserving the argument regsiters across a +- each system call so that we can inspect the flags against after +- the clone call. */ +- mov x5, x0 +-#endif +- + mov x8, #SYS_ify(clone) +- /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid. */ + svc 0x0 +- cfi_endproc + cmp x0, #0 +- beq 2f +- blt C_SYMBOL_NAME(__syscall_error) ++ beq thread_start ++ blt .Lsyscall_error + RET +-1: mov x0, #-EINVAL +- b syscall_error ++PSEUDO_END (__clone) + +-2: ++ .align 4 ++ .type thread_start, %function ++thread_start: + cfi_startproc + cfi_undefined (x30) + mov x29, 0 ++ + #ifdef RESET_PID +- tbnz x5, #CLONE_THREAD_BIT, 3f ++ tbnz x11, #CLONE_THREAD_BIT, 3f + mov x0, #-1 +- tbnz x5, #CLONE_VM_BIT, 2f ++ tbnz x11, #CLONE_VM_BIT, 2f + mov x8, #SYS_ify(getpid) + svc 0x0 + 2: +@@ -86,18 +83,16 @@ ENTRY(__clone) + sub x1, x1, #PTHREAD_SIZEOF + str w0, [x1, #PTHREAD_PID_OFFSET] + str w0, [x1, #PTHREAD_TID_OFFSET] +- + 3: + #endif +- /* Pick the function arg and call address from the stack and +- execute. */ +- ldp x1, x0, [sp], #16 +- blr x1 ++ ++ /* Pick the function arg execute. */ ++ mov x0, x12 ++ blr x10 + + /* We are done, pass the return value through x0. */ + b HIDDEN_JUMPTARGET(_exit) + cfi_endproc +- cfi_startproc +-PSEUDO_END (__clone) ++ .size thread_start, .-thread_start + + weak_alias (__clone, clone) +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S +index f01fb84..be6c026 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/ioctl.S +@@ -20,13 +20,12 @@ + + .text + ENTRY(__ioctl) +- movz x8, #__NR_ioctl +- sxtw x0, w0 +- svc #0x0 +- cmn x0, #0x1, lsl #12 +- b.hi C_SYMBOL_NAME(__syscall_error) ++ mov x8, #__NR_ioctl ++ sxtw x0, w0 ++ svc #0x0 ++ cmn x0, #4095 ++ b.cs .Lsyscall_error + ret +- +- PSEUDO_END (__ioctl) ++PSEUDO_END (__ioctl) + + weak_alias (__ioctl, ioctl) +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data +index 84af95d..dfca9a7 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data +@@ -12,4 +12,3 @@ libm.so: matherr + libm.so: __signbit + libm.so: __signbitf + libm.so: __signbitl +-libpthread.so: __errno_location +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +index e0e5cc0..a3b9284 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +@@ -26,119 +26,60 @@ + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +- .section ".text"; \ +- .type __##syscall_name##_nocancel,%function; \ +- .globl __##syscall_name##_nocancel; \ +- __##syscall_name##_nocancel: \ +- cfi_startproc; \ +- DO_CALL (syscall_name, args); \ +- PSEUDO_RET; \ +- cfi_endproc; \ +- .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ +- ENTRY (name); \ +- SINGLE_THREAD_P; \ +- DOARGS_##args; \ +- bne .Lpseudo_cancel; \ +- DO_CALL (syscall_name, 0); \ +- UNDOARGS_##args; \ +- cmn x0, 4095; \ +- PSEUDO_RET; \ +- .Lpseudo_cancel: \ +- DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \ +- CENABLE; \ +- mov x16, x0; /* put mask in safe place. */ \ +- UNDOCARGS_##args; /* restore syscall args. */ \ +- mov x8, SYS_ify (syscall_name); /* do the call. */ \ +- svc 0; \ +- str x0, [sp, -16]!; /* save syscall return value. */ \ +- cfi_adjust_cfa_offset (16); \ +- mov x0, x16; /* get mask back. */ \ +- CDISABLE; \ +- ldr x0, [sp], 16; \ +- cfi_adjust_cfa_offset (-16); \ +- ldr x30, [sp], 16; \ +- cfi_adjust_cfa_offset (-16); \ +- cfi_restore (x30); \ +- UNDOARGS_##args; \ +- cmn x0, 4095; +- +-# define DOCARGS_0 \ +- str x30, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x30, 0) ++ .section ".text"; \ ++ENTRY (__##syscall_name##_nocancel); \ ++.Lpseudo_nocancel: \ ++ DO_CALL (syscall_name, args); \ ++.Lpseudo_finish: \ ++ cmn x0, 4095; \ ++ b.cs .Lsyscall_error; \ ++ .subsection 2; \ ++ .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ ++ENTRY (name); \ ++ SINGLE_THREAD_P(16); \ ++ cbz w16, .Lpseudo_nocancel; \ ++ /* Setup common stack frame no matter the number of args. \ ++ Also save the first arg, since it's basically free. */ \ ++ stp x30, x0, [sp, -64]!; \ ++ cfi_adjust_cfa_offset (64); \ ++ cfi_rel_offset (x30, 0); \ ++ DOCARGS_##args; /* save syscall args around CENABLE. */ \ ++ CENABLE; \ ++ mov x16, x0; /* save mask around syscall. */ \ ++ UNDOCARGS_##args; /* restore syscall args. */ \ ++ DO_CALL (syscall_name, args); \ ++ str x0, [sp, 8]; /* save result around CDISABLE. */ \ ++ mov x0, x16; /* restore mask for CDISABLE. */ \ ++ CDISABLE; \ ++ /* Break down the stack frame, restoring result at once. */ \ ++ ldp x30, x0, [sp], 64; \ ++ cfi_adjust_cfa_offset (-64); \ ++ cfi_restore (x30); \ ++ b .Lpseudo_finish; \ ++ cfi_endproc; \ ++ .size name, .-name; \ ++ .previous ++ ++# undef PSEUDO_END ++# define PSEUDO_END(name) \ ++ SYSCALL_ERROR_HANDLER; \ ++ cfi_endproc ++ ++# define DOCARGS_0 ++# define DOCARGS_1 ++# define DOCARGS_2 str x1, [sp, 16] ++# define DOCARGS_3 stp x1, x2, [sp, 16] ++# define DOCARGS_4 DOCARGS_3; str x3, [sp, 32] ++# define DOCARGS_5 DOCARGS_3; stp x3, x4, [sp, 32] ++# define DOCARGS_6 DOCARGS_5; str x5, [sp, 48] + + # define UNDOCARGS_0 +- +-# define DOCARGS_1 \ +- DOCARGS_0; \ +- str x0, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x0, 0) +- +-# define UNDOCARGS_1 \ +- ldr x0, [sp], 16; \ +- cfi_restore (x0); \ +- cfi_adjust_cfa_offset (-16); \ +- +-# define DOCARGS_2 \ +- DOCARGS_1; \ +- str x1, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x1, 0) +- +-# define UNDOCARGS_2 \ +- ldr x1, [sp], 16; \ +- cfi_restore (x1); \ +- cfi_adjust_cfa_offset (-16); \ +- UNDOCARGS_1 +- +-# define DOCARGS_3 \ +- DOCARGS_2; \ +- str x2, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x2, 0) +- +-# define UNDOCARGS_3 \ +- ldr x2, [sp], 16; \ +- cfi_restore (x2); \ +- cfi_adjust_cfa_offset (-16); \ +- UNDOCARGS_2 +- +-# define DOCARGS_4 \ +- DOCARGS_3; \ +- str x3, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x3, 0) +- +-# define UNDOCARGS_4 \ +- ldr x3, [sp], 16; \ +- cfi_restore (x3); \ +- cfi_adjust_cfa_offset (-16); \ +- UNDOCARGS_3 +- +-# define DOCARGS_5 \ +- DOCARGS_4; \ +- str x4, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x4, 0) +- +-# define UNDOCARGS_5 \ +- ldr x4, [sp], 16; \ +- cfi_restore (x4); \ +- cfi_adjust_cfa_offset (-16); \ +- UNDOCARGS_4 +- +-# define DOCARGS_6 \ +- DOCARGS_5; \ +- str x5, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x5, 0) +- +-# define UNDOCARGS_6 \ +- ldr x5, [sp], 16; \ +- cfi_restore (x5); \ +- cfi_adjust_cfa_offset (-16); \ +- UNDOCARGS_5 ++# define UNDOCARGS_1 ldr x0, [sp, 8] ++# define UNDOCARGS_2 ldp x0, x1, [sp, 8] ++# define UNDOCARGS_3 UNDOCARGS_1; ldp x1, x2, [sp, 16] ++# define UNDOCARGS_4 UNDOCARGS_2; ldp x2, x3, [sp, 24] ++# define UNDOCARGS_5 UNDOCARGS_3; ldp x3, x4, [sp, 32] ++# define UNDOCARGS_6 UNDOCARGS_4; ldp x4, x5, [sp, 40] + + # ifdef IS_IN_libpthread + # define CENABLE bl __pthread_enable_asynccancel +@@ -160,11 +101,9 @@ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) + # else +-# define SINGLE_THREAD_P \ +- adrp x16, __local_multiple_threads; \ +- add x16, x16, #:lo12:__local_multiple_threads; \ +- ldr x16, [x16]; \ +- cmp x16, 0; ++# define SINGLE_THREAD_P(R) \ ++ adrp x##R, __local_multiple_threads; \ ++ ldr w##R, [x##R, :lo12:__local_multiple_threads] + # endif + # else + /* There is no __local_multiple_threads for librt, so use the TCB. */ +@@ -173,20 +112,10 @@ extern int __local_multiple_threads attribute_hidden; + __builtin_expect (THREAD_GETMEM (THREAD_SELF, \ + header.multiple_threads) == 0, 1) + # else +-# define SINGLE_THREAD_P \ +- stp x0, x30, [sp, -16]!; \ +- cfi_adjust_cfa_offset (16); \ +- cfi_rel_offset (x0, 0); \ +- cfi_rel_offset (x30, 8); \ +- bl __read_tp; \ +- sub x0, x0, PTHREAD_SIZEOF; \ +- ldr x16, [x0, PTHREAD_MULTIPLE_THREADS_OFFSET]; \ +- ldp x0, x30, [sp], 16; \ +- cfi_restore (x0); \ +- cfi_restore (x30); \ +- cfi_adjust_cfa_offset (-16); \ +- cmp x16, 0 +-# define SINGLE_THREAD_P_PIC(x) SINGLE_THREAD_P ++# define SINGLE_THREAD_P(R) \ ++ mrs x##R, tpidr_el0; \ ++ sub x##R, x##R, PTHREAD_SIZEOF; \ ++ ldr w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET] + # endif + # endif + +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S +index 574fdf1..fac6416 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/syscall.S +@@ -37,8 +37,6 @@ ENTRY (syscall) + mov x6, x7 + svc 0x0 + cmn x0, #4095 +- b.cs 1f ++ b.cs .Lsyscall_error + RET +-1: +- b SYSCALL_ERROR + PSEUDO_END (syscall) +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +index 713bf7d..9961c03 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -58,19 +58,8 @@ + .text; \ + ENTRY (name); \ + DO_CALL (syscall_name, args); \ +- cmn x0, #4095; +- +-/* Notice the use of 'RET' instead of 'ret' the assembler is case +- insensitive and eglibc already uses the preprocessor symbol 'ret' +- so we use the upper case 'RET' to force through a ret instruction +- to the assembler */ +-# define PSEUDO_RET \ +- b.cs 1f; \ +- RET; \ +- 1: \ +- b SYSCALL_ERROR +-# undef ret +-# define ret PSEUDO_RET ++ cmn x0, #4095; \ ++ b.cs .Lsyscall_error + + # undef PSEUDO_END + # define PSEUDO_END(name) \ +@@ -83,15 +72,7 @@ + ENTRY (name); \ + DO_CALL (syscall_name, args); + +-/* Notice the use of 'RET' instead of 'ret' the assembler is case +- insensitive and eglibc already uses the preprocessor symbol 'ret' +- so we use the upper case 'RET' to force through a ret instruction +- to the assembler */ +-# define PSEUDO_RET_NOERRNO \ +- RET; +- +-# undef ret_NOERRNO +-# define ret_NOERRNO PSEUDO_RET_NOERRNO ++# define ret_NOERRNO ret + + # undef PSEUDO_END_NOERRNO + # define PSEUDO_END_NOERRNO(name) \ +@@ -109,47 +90,38 @@ + # define PSEUDO_END_ERRVAL(name) \ + END (name) + +-# define ret_ERRVAL PSEUDO_RET_NOERRNO ++# define ret_ERRVAL ret + ++# define SYSCALL_ERROR .Lsyscall_error + # if NOT_IN_libc +-# define SYSCALL_ERROR __local_syscall_error + # if RTLD_PRIVATE_ERRNO + # define SYSCALL_ERROR_HANDLER \ +-__local_syscall_error: \ ++.Lsyscall_error: \ + adrp x1, C_SYMBOL_NAME(rtld_errno); \ +- add x1, x1, #:lo12:C_SYMBOL_NAME(rtld_errno); \ + neg w0, w0; \ +- str w0, [x1]; \ ++ str w0, [x1, :lo12:C_SYMBOL_NAME(rtld_errno)]; \ + mov x0, -1; \ + RET; + # else + + # define SYSCALL_ERROR_HANDLER \ +-__local_syscall_error: \ +- stp x29, x30, [sp, -32]!; \ +- cfi_adjust_cfa_offset (32); \ +- cfi_rel_offset (x29, 0); \ +- cfi_rel_offset (x30, 8); \ +- add x29, sp, 0; \ +- str x19, [sp,16]; \ +- neg x19, x0; \ +- bl C_SYMBOL_NAME(__errno_location); \ +- str x19, [x0]; \ ++.Lsyscall_error: \ ++ adrp x1, :gottprel:errno; \ ++ neg w2, w0; \ ++ ldr x1, [x1, :gottprel_lo12:errno]; \ ++ mrs x3, tpidr_el0; \ + mov x0, -1; \ +- ldr x19, [sp,16]; \ +- ldp x29, x30, [sp], 32; \ +- cfi_adjust_cfa_offset (-32); \ +- cfi_restore (x29); \ +- cfi_restore (x30); \ ++ str w2, [x1, x3]; \ + RET; + # endif + # else +-# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ +-# define SYSCALL_ERROR __syscall_error ++# define SYSCALL_ERROR_HANDLER \ ++.Lsyscall_error: \ ++ b __syscall_error; + # endif + + /* Linux takes system call args in registers: +- syscall number in the SVC instruction ++ syscall number x8 + arg 1 x0 + arg 2 x1 + arg 3 x2 +@@ -177,28 +149,8 @@ __local_syscall_error: \ + + # undef DO_CALL + # define DO_CALL(syscall_name, args) \ +- DOARGS_##args \ + mov x8, SYS_ify (syscall_name); \ +- svc 0; \ +- UNDOARGS_##args +- +-# define DOARGS_0 /* nothing */ +-# define DOARGS_1 /* nothing */ +-# define DOARGS_2 /* nothing */ +-# define DOARGS_3 /* nothing */ +-# define DOARGS_4 /* nothing */ +-# define DOARGS_5 /* nothing */ +-# define DOARGS_6 /* nothing */ +-# define DOARGS_7 /* nothing */ +- +-# define UNDOARGS_0 /* nothing */ +-# define UNDOARGS_1 /* nothing */ +-# define UNDOARGS_2 /* nothing */ +-# define UNDOARGS_3 /* nothing */ +-# define UNDOARGS_4 /* nothing */ +-# define UNDOARGS_5 /* nothing */ +-# define UNDOARGS_6 /* nothing */ +-# define UNDOARGS_7 /* nothing */ ++ svc 0 + + #else /* not __ASSEMBLER__ */ + +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S +index f2dc49b..3fb68b9 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/vfork.S +@@ -38,10 +38,8 @@ ENTRY (__vfork) + RESTORE_PID + #endif + cmn x0, #4095 +- b.cs 1f ++ b.cs .Lsyscall_error + RET +-1: +- b SYSCALL_ERROR + + PSEUDO_END (__vfork) + libc_hidden_def (__vfork) +-- +1.8.3.1 diff --git a/SOURCES/glibc-arm-hardfloat-3.patch b/SOURCES/glibc-arm-hardfloat-3.patch new file mode 100644 index 00000000..5bbe5fc3 --- /dev/null +++ b/SOURCES/glibc-arm-hardfloat-3.patch @@ -0,0 +1,21 @@ +(Not needed anymore.) + +diff -Nru glibc-2.17-c758a686/elf/dl-load.c glibc-2.17-c758a686/elf/dl-load.c +--- glibc-2.17-c758a686/elf/dl-load.c 2012-06-06 13:07:41.727524312 -0600 ++++ glibc-2.17-c758a686/elf/dl-load.c 2012-06-06 13:11:19.308681002 -0600 +@@ -2093,10 +2093,14 @@ _dl_map_object (struct link_map *loader, + soname = ((const char *) D_PTR (l, l_info[DT_STRTAB]) + + l->l_info[DT_SONAME]->d_un.d_val); + if (strcmp (name, soname) != 0) +- continue; ++#ifdef __arm__ ++ if (strcmp (name, "ld-linux.so.3") ++ || strcmp (soname, "ld-linux-armhf.so.3")) ++#endif ++ continue; + + /* We have a match on a new name -- cache it. */ +- add_name_to_object (l, soname); ++ add_name_to_object (l, name); + l->l_soname_added = 1; + } diff --git a/SOURCES/glibc-cs-path.patch b/SOURCES/glibc-cs-path.patch new file mode 100644 index 00000000..c94a49af --- /dev/null +++ b/SOURCES/glibc-cs-path.patch @@ -0,0 +1,6 @@ +diff -pruN glibc-2.17-c758a686/sysdeps/unix/confstr.h glibc-2.17-c758a686/sysdeps/unix/confstr.h +--- glibc-2.17-c758a686/sysdeps/unix/confstr.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/unix/confstr.h 2014-09-05 20:02:55.698275219 +0530 +@@ -1 +1 @@ +-#define CS_PATH "/bin:/usr/bin" ++#define CS_PATH "/usr/bin" diff --git a/SOURCES/glibc-fedora-__libc_multiple_libcs.patch b/SOURCES/glibc-fedora-__libc_multiple_libcs.patch new file mode 100644 index 00000000..2dd43ef5 --- /dev/null +++ b/SOURCES/glibc-fedora-__libc_multiple_libcs.patch @@ -0,0 +1,83 @@ +From 16552c01a66633c9e412984d9d92616bd4e5303c Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Fri, 11 Jun 2010 11:04:11 +0200 +Subject: [PATCH] Properly set __libc_multiple_libcs + +* elf/rtld.c (_dl_starting_up): Always define. +(dl_main): Always set _dl_starting_up. +* elf/dl-support.c (_dl_starting_up): Always define. +* elf/dl-init.c (_dl_init): Always clear _dl_starting_up. + +--- + ChangeLog | 7 +++++++ + elf/dl-init.c | 4 ---- + elf/dl-support.c | 2 -- + elf/rtld.c | 4 ---- + 4 files changed, 7 insertions(+), 10 deletions(-) + +--- glibc-2.17-c758a686/elf/dl-init.c ++++ glibc-2.17-c758a686/elf/dl-init.c +@@ -23,11 +23,9 @@ + /* Type of the initializer. */ + typedef void (*init_t) (int, char **, char **); + +-#ifndef HAVE_INLINED_SYSCALLS + /* Flag, nonzero during startup phase. */ + extern int _dl_starting_up; + extern int _dl_starting_up_internal attribute_hidden; +-#endif + + + static void +@@ -132,9 +130,7 @@ _dl_init (struct link_map *main_map, int argc, char **argv, char **env) + while (i-- > 0) + call_init (main_map->l_initfini[i], argc, argv, env); + +-#ifndef HAVE_INLINED_SYSCALLS + /* Finished starting up. */ + INTUSE(_dl_starting_up) = 0; +-#endif + } + INTDEF (_dl_init) +--- glibc-2.17-c758a686/elf/dl-support.c ++++ glibc-2.17-c758a686/elf/dl-support.c +@@ -81,10 +81,8 @@ unsigned long long _dl_load_adds; + create a fake scope containing nothing. */ + struct r_scope_elem _dl_initial_searchlist; + +-#ifndef HAVE_INLINED_SYSCALLS + /* Nonzero during startup. */ + int _dl_starting_up = 1; +-#endif + + /* Random data provided by the kernel. */ + void *_dl_random; +--- glibc-2.17-c758a686/elf/rtld.c ++++ glibc-2.17-c758a686/elf/rtld.c +@@ -106,7 +106,6 @@ static struct audit_list + struct audit_list *next; + } *audit_list; + +-#ifndef HAVE_INLINED_SYSCALLS + /* Set nonzero during loading and initialization of executable and + libraries, cleared before the executable's entry point runs. This + must not be initialized to nonzero, because the unused dynamic +@@ -116,7 +115,6 @@ static struct audit_list + never be called. */ + int _dl_starting_up = 0; + INTVARDEF(_dl_starting_up) +-#endif + + /* This is the structure which defines all variables global to ld.so + (except those which cannot be added for some reason). */ +@@ -929,10 +927,8 @@ dl_main (const ElfW(Phdr) *phdr, + /* Process the environment variable which control the behaviour. */ + process_envvars (&mode); + +-#ifndef HAVE_INLINED_SYSCALLS + /* Set up a flag which tells we are just starting. */ + INTUSE(_dl_starting_up) = 1; +-#endif + + if (*user_entry == (ElfW(Addr)) ENTRY_POINT) + { diff --git a/SOURCES/glibc-fedora-elf-ORIGIN.patch b/SOURCES/glibc-fedora-elf-ORIGIN.patch new file mode 100644 index 00000000..2002969a --- /dev/null +++ b/SOURCES/glibc-fedora-elf-ORIGIN.patch @@ -0,0 +1,98 @@ +From 207e77fd3f0a94acdf0557608dd4f10ce0e0f22f Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Mon, 9 May 2011 10:55:58 +0200 +Subject: [PATCH] Never leave $ORIGIN unexpanded + +* elf/dl-load.c (is_dst): Remove parameter secure, all callers +changed. Move check for valid use of $ORIGIN ... +(_dl_dst_substitute): ... here. Reset check_for_trusted when a +path element is skipped. + +--- + ChangeLog | 7 +++++++ + elf/dl-load.c | 34 ++++++++++++++++------------------ + 2 files changed, 23 insertions(+), 18 deletions(-) + +diff --git glibc-2.17-c758a686/elf/dl-load.c glibc-2.17-c758a686/elf/dl-load.c +index 18a83d2..6e16a9a 100644 +--- glibc-2.17-c758a686/elf/dl-load.c ++++ glibc-2.17-c758a686/elf/dl-load.c +@@ -249,8 +249,7 @@ is_trusted_path_normalize (const char *path, size_t len) + + + static size_t +-is_dst (const char *start, const char *name, const char *str, +- int is_path, int secure) ++is_dst (const char *start, const char *name, const char *str, int is_path) + { + size_t len; + bool is_curly = false; +@@ -279,12 +278,6 @@ is_dst (const char *start, const char *name, const char *str, + && (!is_path || name[len] != ':')) + return 0; + +- if (__builtin_expect (secure, 0) +- && ((name[len] != '\0' && name[len] != '/' +- && (!is_path || name[len] != ':')) +- || (name != start + 1 && (!is_path || name[-2] != ':')))) +- return 0; +- + return len; + } + +@@ -299,13 +292,10 @@ _dl_dst_count (const char *name, int is_path) + { + size_t len; + +- /* $ORIGIN is not expanded for SUID/GUID programs (except if it +- is $ORIGIN alone) and it must always appear first in path. */ + ++name; +- if ((len = is_dst (start, name, "ORIGIN", is_path, +- INTUSE(__libc_enable_secure))) != 0 +- || (len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0 +- || (len = is_dst (start, name, "LIB", is_path, 0)) != 0) ++ if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0 ++ || (len = is_dst (start, name, "PLATFORM", is_path)) != 0 ++ || (len = is_dst (start, name, "LIB", is_path)) != 0) + ++cnt; + + name = strchr (name + len, '$'); +@@ -338,9 +328,16 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result, + size_t len; + + ++name; +- if ((len = is_dst (start, name, "ORIGIN", is_path, +- INTUSE(__libc_enable_secure))) != 0) ++ if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0) + { ++ /* For SUID/GUID programs $ORIGIN must always appear ++ first in a path element. */ ++ if (__builtin_expect (INTUSE(__libc_enable_secure), 0) ++ && ((name[len] != '\0' && name[len] != '/' ++ && (!is_path || name[len] != ':')) ++ || (name != start + 1 && (!is_path || name[-2] != ':')))) ++ repl = (const char *) -1; ++ else + #ifndef SHARED + if (l == NULL) + repl = _dl_get_origin (); +@@ -351,9 +348,9 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result, + check_for_trusted = (INTUSE(__libc_enable_secure) + && l->l_type == lt_executable); + } +- else if ((len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0) ++ else if ((len = is_dst (start, name, "PLATFORM", is_path)) != 0) + repl = GLRO(dl_platform); +- else if ((len = is_dst (start, name, "LIB", is_path, 0)) != 0) ++ else if ((len = is_dst (start, name, "LIB", is_path)) != 0) + repl = DL_DST_LIB; + + if (repl != NULL && repl != (const char *) -1) +@@ -373,6 +370,7 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result, + element, but keep an empty element at the end. */ + if (wp == result && is_path && *name == ':' && name[1] != '\0') + ++name; ++ check_for_trusted = false; + } + else + /* No DST we recognize. */ diff --git a/SOURCES/glibc-fedora-elf-init-hidden_undef.patch b/SOURCES/glibc-fedora-elf-init-hidden_undef.patch new file mode 100644 index 00000000..30f618ba --- /dev/null +++ b/SOURCES/glibc-fedora-elf-init-hidden_undef.patch @@ -0,0 +1,30 @@ +* Fri May 29 2003 Jakub Jelinek 2.3.2-44 +- make __init_array_start etc. symbols in elf-init.oS hidden undefined + +diff -Nru glibc-2.17-c758a686/csu/elf-init.c glibc-2.17-c758a686/csu/elf-init.c +--- glibc-2.17-c758a686/csu/elf-init.c 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/csu/elf-init.c 2012-06-07 12:15:21.570319597 -0600 +@@ -63,6 +63,23 @@ extern void (*__init_array_end []) (int, + extern void (*__fini_array_start []) (void) attribute_hidden; + extern void (*__fini_array_end []) (void) attribute_hidden; + ++#if defined HAVE_VISIBILITY_ATTRIBUTE \ ++ && (defined SHARED || defined LIBC_NONSHARED) ++# define hidden_undef_2(x) #x ++# define hidden_undef_1(x) hidden_undef_2 (x) ++# define hidden_undef(x) \ ++ __asm (hidden_undef_1 (ASM_GLOBAL_DIRECTIVE) " " #x); \ ++ __asm (".hidden " #x); ++#else ++# define hidden_undef(x) ++#endif ++ ++hidden_undef (__preinit_array_start) ++hidden_undef (__preinit_array_end) ++hidden_undef (__init_array_start) ++hidden_undef (__init_array_end) ++hidden_undef (__fini_array_start) ++hidden_undef (__fini_array_end) + + /* These function symbols are provided for the .init/.fini section entry + points automagically by the linker. */ diff --git a/SOURCES/glibc-fedora-elf-rh737223.patch b/SOURCES/glibc-fedora-elf-rh737223.patch new file mode 100644 index 00000000..860a3d57 --- /dev/null +++ b/SOURCES/glibc-fedora-elf-rh737223.patch @@ -0,0 +1,15 @@ +Binary filesglibc-2.17-c758a686/elf/.rtld.c.rej.swp andglibc-2.17-c758a686/elf/.rtld.c.rej.swp differ +diff -Nru glibc-2.17-c758a686/elf/setup-vdso.h glibc-2.17-c758a686/elf/setup-vdso.h +--- glibc-2.17-c758a686/elf/setup-vdso.h 2012-10-10 21:34:38.000000000 -0600 ++++ glibc-2.17-c758a686/elf/setup-vdso.h 2012-10-11 09:43:14.152958832 -0600 +@@ -93,7 +93,9 @@ setup_vdso (struct link_map *main_map __ + char *copy = malloc (len); + if (copy == NULL) + _dl_fatal_printf ("out of memory\n"); +- l->l_libname->name = l->l_name = memcpy (copy, dsoname, len); ++ l->l_libname->name = memcpy (copy, dsoname, len); ++ if (GLRO(dl_debug_mask)) ++ l->l_name = copy; + } + + /* Add the vDSO to the object list. */ diff --git a/SOURCES/glibc-fedora-gai-canonical.patch b/SOURCES/glibc-fedora-gai-canonical.patch new file mode 100644 index 00000000..419c0036 --- /dev/null +++ b/SOURCES/glibc-fedora-gai-canonical.patch @@ -0,0 +1,124 @@ +Upstream commit, fixing [BZ #15218]: + +commit b957ced8890a4438c8efe2c15e5abf4e327f25cf +Author: Andreas Schwab +Date: Tue Oct 15 10:21:13 2013 +0200 + + Don't use gethostbyaddr to determine canonical name + + +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -565,8 +565,8 @@ gaih_inet (const char *name, const struct gaih_service *service, + + /* If we do not have to look for IPv6 addresses, use + the simple, old functions, which do not support +- IPv6 scope ids. */ +- if (req->ai_family == AF_INET) ++ IPv6 scope ids, nor retrieving the canonical name. */ ++ if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0) + { + /* Allocate additional room for struct host_data. */ + size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*) +@@ -1107,70 +1107,10 @@ gaih_inet (const char *name, const struct gaih_service *service, + /* Only the first entry gets the canonical name. */ + if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0) + { +- char *tmpbuf2 = NULL; +- bool malloc_tmpbuf2 = false; +- + if (canon == NULL) +- { +- struct hostent *h = NULL; +- int herrno; +- struct hostent th; +- /* Add room for struct host_data. */ +- size_t tmpbuf2len = (512 + (MAX_NR_ALIASES+MAX_NR_ADDRS+1) +- * sizeof(char*) + 16 * sizeof(char)); +- +- do +- { +- if (__libc_use_alloca (alloca_used + 2 * tmpbuf2len)) +- tmpbuf2 = extend_alloca_account (tmpbuf2, tmpbuf2len, +- tmpbuf2len * 2, +- alloca_used); +- else +- { +- char *newp = realloc (malloc_tmpbuf2 ? tmpbuf2 : NULL, +- 2 * tmpbuf2len); +- if (newp == NULL) +- { +- if (malloc_tmpbuf2) +- free (tmpbuf2); +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- +- tmpbuf2 = newp; +- tmpbuf2len = 2 * tmpbuf2len; +- malloc_tmpbuf2 = true; +- } +- +- rc = __gethostbyaddr_r (at2->addr, +- ((at2->family == AF_INET6) +- ? sizeof (struct in6_addr) +- : sizeof (struct in_addr)), +- at2->family, &th, tmpbuf2, +- tmpbuf2len, &h, &herrno); +- } +- while (rc == ERANGE && herrno == NETDB_INTERNAL); +- +- if (rc != 0 && herrno == NETDB_INTERNAL) +- { +- if (malloc_tmpbuf2) +- free (tmpbuf2); +- +- __set_h_errno (herrno); +- result = -EAI_SYSTEM; +- goto free_and_return; +- } +- +- if (h != NULL) +- canon = h->h_name; +- else +- { +- assert (orig_name != NULL); +- /* If the canonical name cannot be determined, use +- the passed in string. */ +- canon = orig_name; +- } +- } ++ /* If the canonical name cannot be determined, use ++ the passed in string. */ ++ canon = orig_name; + + #ifdef HAVE_LIBIDN + if (req->ai_flags & AI_CANONIDN) +@@ -1185,9 +1125,6 @@ gaih_inet (const char *name, const struct gaih_service *service, + int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags); + if (rc != IDNA_SUCCESS) + { +- if (malloc_tmpbuf2) +- free (tmpbuf2); +- + if (rc == IDNA_MALLOC_ERROR) + result = -EAI_MEMORY; + else if (rc == IDNA_DLOPEN_ERROR) +@@ -1217,17 +1154,11 @@ gaih_inet (const char *name, const struct gaih_service *service, + canon = strdup (canon); + if (canon == NULL) + { +- if (malloc_tmpbuf2) +- free (tmpbuf2); +- + result = -EAI_MEMORY; + goto free_and_return; + } + } + } +- +- if (malloc_tmpbuf2) +- free (tmpbuf2); + } + + family = at2->family; diff --git a/SOURCES/glibc-fedora-getrlimit-PLT.patch b/SOURCES/glibc-fedora-getrlimit-PLT.patch new file mode 100644 index 00000000..94495ead --- /dev/null +++ b/SOURCES/glibc-fedora-getrlimit-PLT.patch @@ -0,0 +1,35 @@ +Related upstream commit: + +commit c5c2b7c3fd823fc5c4a52506292a90eba60b0c62 +Author: Joseph Myers +Date: Sat Dec 6 23:40:48 2014 +0000 + + Fix pthreads getrlimit, gettimeofday namespace (bug 17682). + +--- glibc-2.17-c758a686/include/sys/resource.h ++++ glibc-2.17-c758a686/include/sys/resource.h +@@ -14,5 +14,6 @@ extern int __getrusage (enum __rusage_who __who, struct rusage *__usage) + + extern int __setrlimit (enum __rlimit_resource __resource, + const struct rlimit *__rlimits); ++libc_hidden_proto (__getrlimit) + #endif + #endif +--- glibc-2.17-c758a686/resource/getrlimit.c ++++ glibc-2.17-c758a686/resource/getrlimit.c +@@ -27,6 +27,7 @@ __getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits) + __set_errno (ENOSYS); + return -1; + } ++libc_hidden_def (__getrlimit) + weak_alias (__getrlimit, getrlimit) + + stub_warning (getrlimit) +--- glibc-2.17-c758a686/sysdeps/mach/hurd/getrlimit.c ++++ glibc-2.17-c758a686/sysdeps/mach/hurd/getrlimit.c +@@ -43,4 +43,5 @@ __getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits) + + return 0; + } ++libc_hidden_def (__getrlimit) + weak_alias (__getrlimit, getrlimit) diff --git a/SOURCES/glibc-fedora-i386-tls-direct-seg-refs.patch b/SOURCES/glibc-fedora-i386-tls-direct-seg-refs.patch new file mode 100644 index 00000000..3f9d89ec --- /dev/null +++ b/SOURCES/glibc-fedora-i386-tls-direct-seg-refs.patch @@ -0,0 +1,18 @@ +diff -Nru glibc-2.17-c758a686/sysdeps/i386/Makefile glibc-2.17-c758a686/sysdeps/i386/Makefile +--- glibc-2.17-c758a686/sysdeps/i386/Makefile 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/i386/Makefile 2012-06-07 12:15:21.826318641 -0600 +@@ -62,6 +64,14 @@ endif + + ifneq (,$(filter -mno-tls-direct-seg-refs,$(CFLAGS))) + defines += -DNO_TLS_DIRECT_SEG_REFS ++else ++# .a libraries are not performance critical and so we ++# build them without direct TLS segment references ++# always. ++CPPFLAGS-.o += -DNO_TLS_DIRECT_SEG_REFS ++CFLAGS-.o += -mno-tls-direct-seg-refs ++CPPFLAGS-.oS += -DNO_TLS_DIRECT_SEG_REFS ++CFLAGS-.oS += -mno-tls-direct-seg-refs + endif + + ifeq ($(subdir),elf) diff --git a/SOURCES/glibc-fedora-include-bits-ldbl.patch b/SOURCES/glibc-fedora-include-bits-ldbl.patch new file mode 100644 index 00000000..0aa3c0fa --- /dev/null +++ b/SOURCES/glibc-fedora-include-bits-ldbl.patch @@ -0,0 +1,36 @@ +Only needed for glibc builds with -mlong-double-64: + + https://sourceware.org/ml/libc-alpha/2017-08/msg01139.html + +This means the patch is no longer needed. + +From 5eb4509a6651d19c7a28c4506d6aa582c9ee095a Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Wed, 1 Feb 2006 09:30:43 +0000 +Subject: [PATCH] 128-bit long double fixes + +* include/bits/stdlib-ldbl.h: New file. +* include/bits/wchar-ldbl.h: New file. + +--- + ChangeLog | 5 +++++ + include/bits/stdlib-ldbl.h | 1 + + include/bits/wchar-ldbl.h | 1 + + 3 files changed, 7 insertions(+), 0 deletions(-) + create mode 100644 include/bits/stdlib-ldbl.h + create mode 100644 include/bits/wchar-ldbl.h + +diff --git glibc-2.17-c758a686/include/bits/stdlib-ldbl.h glibc-2.17-c758a686/include/bits/stdlib-ldbl.h +new file mode 100644 +index 0000000..6250949 +--- /dev/null ++++ glibc-2.17-c758a686/include/bits/stdlib-ldbl.h +@@ -0,0 +1 @@ ++#include +diff --git glibc-2.17-c758a686/include/bits/wchar-ldbl.h glibc-2.17-c758a686/include/bits/wchar-ldbl.h +new file mode 100644 +index 0000000..29baa2f +--- /dev/null ++++ glibc-2.17-c758a686/include/bits/wchar-ldbl.h +@@ -0,0 +1 @@ ++#include diff --git a/SOURCES/glibc-fedora-ldd.patch b/SOURCES/glibc-fedora-ldd.patch new file mode 100644 index 00000000..2f2bd2a3 --- /dev/null +++ b/SOURCES/glibc-fedora-ldd.patch @@ -0,0 +1,38 @@ +Upstream commit: + +commit eedca9772e99c72ab4c3c34e43cc764250aa3e3c (HEAD -> master) +Author: Andreas Schwab +Date: Wed Aug 16 15:59:55 2017 +0200 + + ldd: never run file directly + +--- glibc-2.17-c758a686/elf/ldd.bash.in ++++ glibc-2.17-c758a686/elf/ldd.bash.in +@@ -166,18 +166,6 @@ warning: you do not have execution permission for" "\`$file'" >&2 + fi + done + case $ret in +- 0) +- # If the program exits with exit code 5, it means the process has been +- # invoked with __libc_enable_secure. Fall back to running it through +- # the dynamic linker. +- try_trace "$file" +- rc=$? +- if [ $rc = 5 ]; then +- try_trace "$RTLD" "$file" +- rc=$? +- fi +- [ $rc = 0 ] || result=1 +- ;; + 1) + # This can be a non-ELF binary or no binary at all. + nonelf "$file" || { +@@ -185,7 +173,7 @@ warning: you do not have execution permission for" "\`$file'" >&2 + result=1 + } + ;; +- 2) ++ 0|2) + try_trace "$RTLD" "$file" || result=1 + ;; + *) diff --git a/SOURCES/glibc-fedora-linux-tcsetattr.patch b/SOURCES/glibc-fedora-linux-tcsetattr.patch new file mode 100644 index 00000000..3ce8ff32 --- /dev/null +++ b/SOURCES/glibc-fedora-linux-tcsetattr.patch @@ -0,0 +1,48 @@ +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/tcsetattr.c 2012-06-07 12:15:21.831318623 -0600 +@@ -48,6 +48,7 @@ tcsetattr (fd, optional_actions, termios + { + struct __kernel_termios k_termios; + unsigned long int cmd; ++ int retval; + + switch (optional_actions) + { +@@ -79,6 +80,35 @@ tcsetattr (fd, optional_actions, termios + memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], + __KERNEL_NCCS * sizeof (cc_t)); + +- return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); ++ retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); ++ ++ if (retval == 0 && cmd == TCSETS) ++ { ++ /* The Linux kernel has a bug which silently ignore the invalid ++ c_cflag on pty. We have to check it here. */ ++ int save = errno; ++ retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios); ++ if (retval) ++ { ++ /* We cannot verify if the setting is ok. We don't return ++ an error (?). */ ++ __set_errno (save); ++ retval = 0; ++ } ++ else if ((termios_p->c_cflag & (PARENB | CREAD)) ++ != (k_termios.c_cflag & (PARENB | CREAD)) ++ || ((termios_p->c_cflag & CSIZE) ++ && ((termios_p->c_cflag & CSIZE) ++ != (k_termios.c_cflag & CSIZE)))) ++ { ++ /* It looks like the Linux kernel silently changed the ++ PARENB/CREAD/CSIZE bits in c_cflag. Report it as an ++ error. */ ++ __set_errno (EINVAL); ++ retval = -1; ++ } ++ } ++ ++ return retval; + } + libc_hidden_def (tcsetattr) diff --git a/SOURCES/glibc-fedora-localedata-rh61908.patch b/SOURCES/glibc-fedora-localedata-rh61908.patch new file mode 100644 index 00000000..0cdd09f1 --- /dev/null +++ b/SOURCES/glibc-fedora-localedata-rh61908.patch @@ -0,0 +1,38 @@ +* Tue Mar 26 2002 Jakub Jelinek 2.2.5-28 +- add a couple of .ISO-8859-15 locales (#61908) + +diff -Nru glibc-2.17-c758a686/localedata/SUPPORTED glibc-2.17-c758a686/localedata/SUPPORTED +--- glibc-2.17-c758a686/localedata/SUPPORTED 2012-11-25 12:59:31.000000000 -0700 ++++ glibc-2.17-c758a686/localedata/SUPPORTED 2012-11-26 12:58:43.298223018 -0700 +@@ -89,6 +89,7 @@ cy_GB.UTF-8/UTF-8 \ + cy_GB/ISO-8859-14 \ + da_DK.UTF-8/UTF-8 \ + da_DK/ISO-8859-1 \ ++da_DK.ISO-8859-15/ISO-8859-15 \ + de_AT.UTF-8/UTF-8 \ + de_AT/ISO-8859-1 \ + de_AT@euro/ISO-8859-15 \ +@@ -121,6 +122,7 @@ en_DK.UTF-8/UTF-8 \ + en_DK/ISO-8859-1 \ + en_GB.UTF-8/UTF-8 \ + en_GB/ISO-8859-1 \ ++en_GB.ISO-8859-15/ISO-8859-15 \ + en_HK.UTF-8/UTF-8 \ + en_HK/ISO-8859-1 \ + en_IE.UTF-8/UTF-8 \ +@@ -136,6 +138,7 @@ en_SG.UTF-8/UTF-8 \ + en_SG/ISO-8859-1 \ + en_US.UTF-8/UTF-8 \ + en_US/ISO-8859-1 \ ++en_US.ISO-8859-15/ISO-8859-15 \ + en_ZA.UTF-8/UTF-8 \ + en_ZA/ISO-8859-1 \ + en_ZM/UTF-8 \ +@@ -385,6 +388,7 @@ sv_FI/ISO-8859-1 \ + sv_FI@euro/ISO-8859-15 \ + sv_SE.UTF-8/UTF-8 \ + sv_SE/ISO-8859-1 \ ++sv_SE.ISO-8859-15/ISO-8859-15 \ + sw_KE/UTF-8 \ + sw_TZ/UTF-8 \ + szl_PL/UTF-8 \ diff --git a/SOURCES/glibc-fedora-localedef.patch b/SOURCES/glibc-fedora-localedef.patch new file mode 100644 index 00000000..5cb2bab0 --- /dev/null +++ b/SOURCES/glibc-fedora-localedef.patch @@ -0,0 +1,11 @@ +diff -Nru glibc-2.17-c758a686/localedata/Makefile glibc-2.17-c758a686/localedata/Makefile +--- glibc-2.17-c758a686/localedata/Makefile 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/localedata/Makefile 2012-06-07 12:15:21.776318827 -0600 +@@ -211,6 +211,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-lo + echo -n '...'; \ + input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \ + $(LOCALEDEF) --alias-file=../intl/locale.alias \ ++ --no-archive \ + -i locales/$$input -c -f charmaps/$$charset \ + $(addprefix --prefix=,$(install_root)) $$locale; \ + echo ' done'; \ diff --git a/SOURCES/glibc-fedora-locarchive.patch b/SOURCES/glibc-fedora-locarchive.patch new file mode 100644 index 00000000..fe779d90 --- /dev/null +++ b/SOURCES/glibc-fedora-locarchive.patch @@ -0,0 +1,51 @@ +This is a part of commit glibc-2.3.3-1492-ga891c7b, +needed for fedora/build-locale-archive.c only. + +diff -Nru glibc-2.17-c758a686/ChangeLog.17 glibc-2.17-c758a686/ChangeLog.17 +--- glibc-2.17-c758a686/ChangeLog.17 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/ChangeLog.17 2012-06-07 12:15:21.564319619 -0600 +@@ -11818,6 +11829,10 @@ d2009-10-30 Ulrich Drepper ++ ++ * locale/programs/locarchive.c (add_alias, insert_name): Remove static. ++ + 2007-04-16 Ulrich Drepper + + [BZ #4364] +diff -Nru glibc-2.17-c758a686/locale/programs/locarchive.c glibc-2.17-c758a686/locale/programs/locarchive.c +--- glibc-2.17-c758a686/locale/programs/locarchive.c 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/locale/programs/locarchive.c 2012-06-07 12:15:21.585319540 -0600 +@@ -252,9 +252,9 @@ oldlocrecentcmp (const void *a, const vo + /* forward decls for below */ + static uint32_t add_locale (struct locarhandle *ah, const char *name, + locale_data_t data, bool replace); +-static void add_alias (struct locarhandle *ah, const char *alias, +- bool replace, const char *oldname, +- uint32_t *locrec_offset_p); ++void add_alias (struct locarhandle *ah, const char *alias, ++ bool replace, const char *oldname, ++ uint32_t *locrec_offset_p); + + + static bool +@@ -635,7 +635,7 @@ close_archive (struct locarhandle *ah) + #include "../../intl/explodename.c" + #include "../../intl/l10nflist.c" + +-static struct namehashent * ++struct namehashent * + insert_name (struct locarhandle *ah, + const char *name, size_t name_len, bool replace) + { +@@ -693,7 +693,7 @@ insert_name (struct locarhandle *ah, + return &namehashtab[idx]; + } + +-static void ++void + add_alias (struct locarhandle *ah, const char *alias, bool replace, + const char *oldname, uint32_t *locrec_offset_p) + { diff --git a/SOURCES/glibc-fedora-manual-dircategory.patch b/SOURCES/glibc-fedora-manual-dircategory.patch new file mode 100644 index 00000000..8fc2babc --- /dev/null +++ b/SOURCES/glibc-fedora-manual-dircategory.patch @@ -0,0 +1,20 @@ +From 4820b9175535e13df79ce816106016040014916e Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Fri, 3 Nov 2006 16:31:21 +0000 +Subject: [PATCH] Change @dircategory. + +--- + manual/libc.texinfo | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- glibc-2.17-c758a686/manual/libc.texinfo ++++ glibc-2.17-c758a686/manual/libc.texinfo +@@ -7,7 +7,7 @@ + @include macros.texi + + @comment Tell install-info what to do. +-@dircategory Software libraries ++@dircategory Libraries + @direntry + * Libc: (libc). C library. + @end direntry diff --git a/SOURCES/glibc-fedora-nis-rh188246.patch b/SOURCES/glibc-fedora-nis-rh188246.patch new file mode 100644 index 00000000..f2667747 --- /dev/null +++ b/SOURCES/glibc-fedora-nis-rh188246.patch @@ -0,0 +1,21 @@ +From baba5d9461d4e8a581ac26fe4412ad783ffc73e7 Mon Sep 17 00:00:00 2001 +From: Jakub Jelinek +Date: Mon, 1 May 2006 08:02:53 +0000 +Subject: [PATCH] Enable SETENT_BATCH_READ nis/nss option by default + +* Mon May 1 2006 Jakub Jelinek 2.4.90-4 +- SETENT_BATCH_READ /etc/default/nss option for speeding up + some usages of NIS+ (#188246) + +diff --git glibc-2.17-c758a686/nis/nss glibc-2.17-c758a686/nis/nss +--- glibc-2.17-c758a686/nis/nss ++++ glibc-2.17-c758a686/nis/nss +@@ -25,7 +25,7 @@ + # memory with every getXXent() call. Otherwise each getXXent() call + # might result into a network communication with the server to get + # the next entry. +-#SETENT_BATCH_READ=TRUE ++SETENT_BATCH_READ=TRUE + # + # ADJUNCT_AS_SHADOW + # If set to TRUE, the passwd routines in the NIS NSS module will not diff --git a/SOURCES/glibc-fedora-nptl-linklibc.patch b/SOURCES/glibc-fedora-nptl-linklibc.patch new file mode 100644 index 00000000..e679fa19 --- /dev/null +++ b/SOURCES/glibc-fedora-nptl-linklibc.patch @@ -0,0 +1,25 @@ +diff -Nru glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686/nptl/Makefile +--- glibc-2.17-c758a686/nptl/Makefile 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/nptl/Makefile 2012-06-07 12:15:21.816318678 -0600 +@@ -529,15 +529,19 @@ $(addprefix $(objpfx), \ + $(tests) $(xtests) $(test-srcs))): $(objpfx)libpthread.so \ + $(objpfx)libpthread_nonshared.a + $(objpfx)tst-unload: $(common-objpfx)dlfcn/libdl.so +-# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so, ++# $(objpfx)linklibc.so is used instead of $(common-objpfx)libc.so, + # since otherwise libpthread.so comes before libc.so when linking. + $(addprefix $(objpfx), $(tests-reverse)): \ +- $(objpfx)../libc.so $(objpfx)libpthread.so \ ++ $(objpfx)linklibc.so $(objpfx)libpthread.so \ + $(objpfx)libpthread_nonshared.a + $(objpfx)../libc.so: $(common-objpfx)libc.so ; + $(addprefix $(objpfx),$(tests-static) $(xtests-static)): $(objpfx)libpthread.a + + $(objpfx)tst-atfork2.out: $(objpfx)tst-atfork2mod.so ++ ++$(objpfx)linklibc.so: $(common-objpfx)libc.so ++ ln -s ../libc.so $@ ++generated += libclink.so + else + $(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a + endif diff --git a/SOURCES/glibc-fedora-nscd.patch b/SOURCES/glibc-fedora-nscd.patch new file mode 100644 index 00000000..68294631 --- /dev/null +++ b/SOURCES/glibc-fedora-nscd.patch @@ -0,0 +1,12 @@ +diff -Nru glibc-2.17-c758a686/nscd/nscd.conf glibc-2.17-c758a686/nscd/nscd.conf +--- glibc-2.17-c758a686/nscd/nscd.conf 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/nscd/nscd.conf 2012-06-07 12:15:21.818318670 -0600 +@@ -33,7 +33,7 @@ + # logfile /var/log/nscd.log + # threads 4 + # max-threads 32 +-# server-user nobody ++ server-user nscd + # stat-user somebody + debug-level 0 + # reload-count 5 diff --git a/SOURCES/glibc-fedora-ppc-unwind.patch b/SOURCES/glibc-fedora-ppc-unwind.patch new file mode 100644 index 00000000..df44802b --- /dev/null +++ b/SOURCES/glibc-fedora-ppc-unwind.patch @@ -0,0 +1,23 @@ +(This patch is no longer needed because we currently build all of +glibc with -fno-asynchronous-unwind-tables.) + +glibc-2.3.3-1478-g37582bc + +* Thu Nov 30 2006 Jakub Jelinek 2.5.90-9 +- on ppc64 build __libc_start_main without unwind info, + as it breaks MD_FROB_UPDATE_CONTEXT (#217729, #217775; in the + future that could be fixable just by providing .cfi_undefined r2 + in __libc_start_main instead) + +diff -Nru glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile 2012-06-07 12:15:21.828318633 -0600 +@@ -35,6 +35,8 @@ CFLAGS-rtld-memmove.os = $(no-special-re + CFLAGS-rtld-memchr.os = $(no-special-regs) + CFLAGS-rtld-strnlen.os = $(no-special-regs) + ++CFLAGS-libc-start.c += -fno-asynchronous-unwind-tables ++ + ifeq ($(subdir),csu) + sysdep_routines += hp-timing + elide-routines.os += hp-timing diff --git a/SOURCES/glibc-fedora-regcomp-sw11561.patch b/SOURCES/glibc-fedora-regcomp-sw11561.patch new file mode 100644 index 00000000..44c4d5b5 --- /dev/null +++ b/SOURCES/glibc-fedora-regcomp-sw11561.patch @@ -0,0 +1,155 @@ +Upstream commit: + +commit 7e2f0d2d77e4bc273fe00f99d970605d8e38d4d6 +Author: Andreas Schwab +Date: Mon Feb 4 10:16:33 2013 +0100 + + Fix handling of collating symbols in regexps + +From c1b97d6d896b1f22fdf5d28471ef7859ec840a57 Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Wed, 1 Sep 2010 17:26:15 +0200 +Subject: [PATCH] Fix handling of collating symbols in regexps + +[BZ #11561] +* posix/regcomp.c (parse_bracket_exp): When looking up collating +elements compare against the byte sequence of it, not its name. + +--- + ChangeLog | 4 +++ + posix/regcomp.c | 72 ++++++++++++++++++++---------------------------------- + 2 files changed, 31 insertions(+), 45 deletions(-) + +--- glibc-2.17-c758a686/posix/regcomp.c ++++ glibc-2.17-c758a686/posix/regcomp.c +@@ -2772,40 +2772,29 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + + /* Local function for parse_bracket_exp used in _LIBC environement. + Seek the collating symbol entry correspondings to NAME. +- Return the index of the symbol in the SYMB_TABLE. */ ++ Return the index of the symbol in the SYMB_TABLE, ++ or -1 if not found. */ + + auto inline int32_t + __attribute ((always_inline)) +- seek_collating_symbol_entry (name, name_len) +- const unsigned char *name; +- size_t name_len; ++ seek_collating_symbol_entry (const unsigned char *name, size_t name_len) + { +- int32_t hash = elem_hash ((const char *) name, name_len); +- int32_t elem = hash % table_size; +- if (symb_table[2 * elem] != 0) +- { +- int32_t second = hash % (table_size - 2) + 1; +- +- do +- { +- /* First compare the hashing value. */ +- if (symb_table[2 * elem] == hash +- /* Compare the length of the name. */ +- && name_len == extra[symb_table[2 * elem + 1]] +- /* Compare the name. */ +- && memcmp (name, &extra[symb_table[2 * elem + 1] + 1], +- name_len) == 0) +- { +- /* Yep, this is the entry. */ +- break; +- } ++ int32_t elem; + +- /* Next entry. */ +- elem += second; +- } +- while (symb_table[2 * elem] != 0); +- } +- return elem; ++ for (elem = 0; elem < table_size; elem++) ++ if (symb_table[2 * elem] != 0) ++ { ++ int32_t idx = symb_table[2 * elem + 1]; ++ /* Skip the name of collating element name. */ ++ idx += 1 + extra[idx]; ++ if (/* Compare the length of the name. */ ++ name_len == extra[idx] ++ /* Compare the name. */ ++ && memcmp (name, &extra[idx + 1], name_len) == 0) ++ /* Yep, this is the entry. */ ++ return elem; ++ } ++ return -1; + } + + /* Local function for parse_bracket_exp used in _LIBC environment. +@@ -2814,8 +2803,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + + auto inline unsigned int + __attribute ((always_inline)) +- lookup_collation_sequence_value (br_elem) +- bracket_elem_t *br_elem; ++ lookup_collation_sequence_value (bracket_elem_t *br_elem) + { + if (br_elem->type == SB_CHAR) + { +@@ -2843,7 +2831,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + int32_t elem, idx; + elem = seek_collating_symbol_entry (br_elem->opr.name, + sym_name_len); +- if (symb_table[2 * elem] != 0) ++ if (elem != -1) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; +@@ -2861,7 +2849,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + /* Return the collation sequence value. */ + return *(unsigned int *) (extra + idx); + } +- else if (symb_table[2 * elem] == 0 && sym_name_len == 1) ++ else if (sym_name_len == 1) + { + /* No valid character. Match it as a single byte + character. */ +@@ -2883,11 +2871,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + + auto inline reg_errcode_t + __attribute ((always_inline)) +- build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem) +- re_charset_t *mbcset; +- int *range_alloc; +- bitset_t sbcset; +- bracket_elem_t *start_elem, *end_elem; ++ build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc, ++ bracket_elem_t *start_elem, bracket_elem_t *end_elem) + { + unsigned int ch; + uint32_t start_collseq; +@@ -2966,25 +2951,22 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + + auto inline reg_errcode_t + __attribute ((always_inline)) +- build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name) +- re_charset_t *mbcset; +- int *coll_sym_alloc; +- bitset_t sbcset; +- const unsigned char *name; ++ build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, ++ int *coll_sym_alloc, const unsigned char *name) + { + int32_t elem, idx; + size_t name_len = strlen ((const char *) name); + if (nrules != 0) + { + elem = seek_collating_symbol_entry (name, name_len); +- if (symb_table[2 * elem] != 0) ++ if (elem != -1) + { + /* We found the entry. */ + idx = symb_table[2 * elem + 1]; + /* Skip the name of collating element name. */ + idx += 1 + extra[idx]; + } +- else if (symb_table[2 * elem] == 0 && name_len == 1) ++ else if (name_len == 1) + { + /* No valid character, treat it as a normal + character. */ diff --git a/SOURCES/glibc-fedora-streams-rh436349.patch b/SOURCES/glibc-fedora-streams-rh436349.patch new file mode 100644 index 00000000..597c9708 --- /dev/null +++ b/SOURCES/glibc-fedora-streams-rh436349.patch @@ -0,0 +1,28 @@ +This is part of commit glibc-2.3.3-1564-gd0b6ac6 + +* Fri Mar 14 2008 Jakub Jelinek 2.7.90-11 +- remove , define _XOPEN_STREAMS -1 (#436349) + +diff -Nru glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h 2012-06-07 12:15:21.817318674 -0600 +@@ -188,4 +188,7 @@ + /* Typed memory objects are not available. */ + #define _POSIX_TYPED_MEMORY_OBJECTS -1 + ++/* Streams are not available. */ ++#define _XOPEN_STREAMS -1 ++ + #endif /* bits/posix_opt.h */ +diff -Nru glibc-2.17-c758a686/streams/Makefile glibc-2.17-c758a686/streams/Makefile +--- glibc-2.17-c758a686/streams/Makefile 2012-06-05 07:42:49.000000000 -0600 ++++ glibc-2.17-c758a686/streams/Makefile 2012-06-07 12:15:21.824318649 -0600 +@@ -20,7 +20,7 @@ + # + subdir := streams + +-headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h ++#headers = stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h + routines = isastream getmsg getpmsg putmsg putpmsg fattach fdetach + + include ../Rules diff --git a/SOURCES/glibc-fedora-uname-getrlimit.patch b/SOURCES/glibc-fedora-uname-getrlimit.patch new file mode 100644 index 00000000..c137a121 --- /dev/null +++ b/SOURCES/glibc-fedora-uname-getrlimit.patch @@ -0,0 +1,52 @@ +Related upstream commit: + +commit c5c2b7c3fd823fc5c4a52506292a90eba60b0c62 +Author: Joseph Myers +Date: Sat Dec 6 23:40:48 2014 +0000 + + Fix pthreads getrlimit, gettimeofday namespace (bug 17682). + +The uname call is again present in Fedora because UTS namespaces can +be used nowadays to change the uname result. + +--- glibc-2.17-c758a686/nptl/Version ++++ glibc-2.17-c758a686/nptl/Versions +@@ -30,6 +30,7 @@ libc { + __libc_alloca_cutoff; + # Internal libc interface to libpthread + __libc_dl_error_tsd; ++ __getrlimit; + } + } + +--- glibc-2.17-c758a686/nptl/nptl-init.c ++++ glibc-2.17-c758a686/nptl/nptl-init.c +@@ -414,7 +414,7 @@ __pthread_initialize_minimal_internal (void) + /* Determine the default allowed stack size. This is the size used + in case the user does not specify one. */ + struct rlimit limit; +- if (getrlimit (RLIMIT_STACK, &limit) != 0 ++ if (__getrlimit (RLIMIT_STACK, &limit) != 0 + || limit.rlim_cur == RLIM_INFINITY) + /* The system limit is not usable. Use an architecture-specific + default. */ +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/Versions ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/Versions +@@ -0,0 +1,6 @@ ++libc { ++ GLIBC_PRIVATE { ++ # Internal libc interface to libpthread ++ __uname; ++ } ++} +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/smp.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/smp.h +@@ -36,7 +36,7 @@ is_smp_system (void) + char *cp; + + /* Try reading the number using `sysctl' first. */ +- if (uname (&u.uts) == 0) ++ if (__uname (&u.uts) == 0) + cp = u.uts.version; + else + { diff --git a/SOURCES/glibc-fix-test-write-buf-size.patch b/SOURCES/glibc-fix-test-write-buf-size.patch new file mode 100644 index 00000000..57e796a7 --- /dev/null +++ b/SOURCES/glibc-fix-test-write-buf-size.patch @@ -0,0 +1,54 @@ +# This patch fixes tst-cancel4, tst-cancel5, tst-cancelx4 and tst-cancelx5 +# failures on newer kernels where the write buffers are larger. +# +# commit e7074e4c5edb0acaa979ea08e533736f906a9d68 +# Author: David S. Miller +# Date: Tue Jul 23 02:31:37 2013 -0700 +# +# Increase nptl test case buffer size so we really block on current Linux kernels. +# +# * tst-cancel4.c (WRITE_BUFFER_SIZE): Increase to 16384. +# +# commit 135529b443631f840cc66d0cc395f79c416434d9 +# Author: David S. Miller +# Date: Tue Jul 23 11:31:39 2013 -0700 +# +# Remove Linux kernel version ambiguity in comment added by previous commit. +# +# * tst-cancel4.c (WRITE_BUFFER_SIZE): Adjust comment. +# +diff -urN glibc-2.17-c758a686/nptl/tst-cancel4.c glibc-2.17-c758a686/nptl/tst-cancel4.c +--- glibc-2.17-c758a686/nptl/tst-cancel4.c 2014-07-25 22:07:09.130021164 -0400 ++++ glibc-2.17-c758a686/nptl/tst-cancel4.c 2014-07-25 22:12:07.580022919 -0400 +@@ -83,7 +83,30 @@ + # define IPC_ADDVAL 0 + #endif + +-#define WRITE_BUFFER_SIZE 4096 ++/* The WRITE_BUFFER_SIZE value needs to be choosen such that if we set ++ the socket send buffer size to '1', a write of this size on that ++ socket will block. ++ ++ The Linux kernel imposes a minimum send socket buffer size which ++ has changed over the years. As of Linux 3.10 the value is: ++ ++ 2 * (2048 + SKB_DATA_ALIGN(sizeof(struct sk_buff))) ++ ++ which is attempting to make sure that with standard MTUs, ++ TCP can always queue up at least 2 full sized packets. ++ ++ Furthermore, there is logic in the socket send paths that ++ will allow one more packet (of any size) to be queued up as ++ long as some socket buffer space remains. Blocking only ++ occurs when we try to queue up a new packet and the send ++ buffer space has already been fully consumed. ++ ++ Therefore we must set this value to the largest possible value of ++ the formula above (and since it depends upon the size of "struct ++ sk_buff", it is dependent upon machine word size etc.) plus some ++ slack space. */ ++ ++#define WRITE_BUFFER_SIZE 16384 + + /* Cleanup handling test. */ + static int cl_called; diff --git a/SOURCES/glibc-gmake.patch b/SOURCES/glibc-gmake.patch new file mode 100644 index 00000000..883c1b85 --- /dev/null +++ b/SOURCES/glibc-gmake.patch @@ -0,0 +1,37 @@ +# +# BZ #16037 +# +# Allow building glibc with make version 4.0 or greater. +# This facilitates testing and QE on non-RHEL environments during +# patch development. +# +# commit 28d708c44bc47b56f6551ff285f78edcf61c208a +# Author: Marc-Antoine Perennou +# Date: Thu Oct 31 12:37:50 2013 +1000 +# +# Accept make versions 4.0 and greater +# +diff -urN glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure +--- glibc-2.17-c758a686/configure 2015-01-15 16:32:14.983435268 -0500 ++++ glibc-2.17-c758a686/configure 2015-01-15 16:32:45.396495266 -0500 +@@ -4991,7 +4991,7 @@ + ac_prog_version=`$MAKE --version 2>&1 | sed -n 's/^.*GNU Make[^0-9]*\([0-9][0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; +- 3.79* | 3.[89]*) ++ 3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*) + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + +diff -urN glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in +--- glibc-2.17-c758a686/configure.in 2015-01-15 16:32:14.781441511 -0500 ++++ glibc-2.17-c758a686/configure.in 2015-01-15 16:32:34.970817501 -0500 +@@ -945,7 +945,7 @@ + critic_missing="$critic_missing gcc") + AC_CHECK_PROG_VER(MAKE, gnumake gmake make, --version, + [GNU Make[^0-9]*\([0-9][0-9.]*\)], +- [3.79* | 3.[89]*], critic_missing="$critic_missing make") ++ [3.79* | 3.[89]* | [4-9].* | [1-9][0-9]*], critic_missing="$critic_missing make") + + AC_CHECK_PROG_VER(MSGFMT, gnumsgfmt gmsgfmt msgfmt, --version, + [GNU gettext.* \([0-9]*\.[0-9.]*\)], diff --git a/SOURCES/glibc-manual-update.patch b/SOURCES/glibc-manual-update.patch new file mode 100644 index 00000000..ef9e70f6 --- /dev/null +++ b/SOURCES/glibc-manual-update.patch @@ -0,0 +1,19408 @@ +# +# Synchronize RHEL 7.1 manual with upstream manual. +# +# Include updates that don't impact material differences +# between the upstream master and 2.17-based RHEL implemenation. +# +diff -urN glibc-2.17-c758a686/manual/argp.texi glibc-2.17-c758a686/manual/argp.texi +--- glibc-2.17-c758a686/manual/argp.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/argp.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -36,6 +36,35 @@ + @comment argp.h + @comment GNU + @deftypefun {error_t} argp_parse (const struct argp *@var{argp}, int @var{argc}, char **@var{argv}, unsigned @var{flags}, int *@var{arg_index}, void *@var{input}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtslocale{} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c Optionally alloca()tes standard help options, initializes the parser, ++@c then parses individual args in a loop, and then finalizes. ++@c parser_init ++@c calc_sizes ok ++@c option_is_end ok ++@c malloc @ascuheap @acsmem ++@c parser_convert @mtslocale ++@c convert_options @mtslocale ++@c option_is_end ok ++@c option_is_short ok ++@c isprint, but locale may change within the loop ++@c find_long_option ok ++@c group_parse ++@c group->parser (from argp->parser) ++@c parser_parse_next ++@c getopt_long(_only)_r many issues, same as non_r minus @mtasurace ++@c parser_parse_arg ++@c group_parse dup ++@c parser_parse_opt ++@c group_parse dup ++@c argp_error dup @mtasurace:argpbuf @mtsenv @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c dgettext (bad key error) dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c parser_finalize ++@c group_parse ++@c fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem] ++@c dgettext dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c arg_state_help ++@c free dup @ascuhelp @acsmem + The @code{argp_parse} function parses the arguments in @var{argv}, of + length @var{argc}, using the argp parser @var{argp}. @xref{Argp + Parsers}. Passing a null pointer for @var{argp} is the same as using +@@ -660,6 +689,8 @@ + @comment argp.h + @comment GNU + @deftypefun void argp_usage (const struct argp_state *@var{state}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}} ++@c Just calls argp_state_help with stderr and ARGP_HELP_STD_USAGE. + Outputs the standard usage message for the argp parser referred to by + @var{state} to @code{@var{state}->err_stream} and terminate the program + with @code{exit (argp_err_exit_status)}. @xref{Argp Global Variables}. +@@ -669,6 +700,13 @@ + @comment argp.h + @comment GNU + @deftypefun void argp_error (const struct argp_state *@var{state}, const char *@var{fmt}, @dots{}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}} ++@c Lock stream, vasprintf the formatted message into a buffer, print the ++@c buffer prefixed by the short program name (in libc, ++@c argp_short_program_name is a macro that expands to ++@c program_invocation_short_name), releases the buffer, then call ++@c argp_state_help with stream and ARGP_HELP_STD_ERR, unlocking the ++@c stream at the end. + Prints the printf format string @var{fmt} and following args, preceded + by the program name and @samp{:}, and followed by a @w{@samp{Try @dots{} + --help}} message, and terminates the program with an exit status of +@@ -679,6 +717,12 @@ + @comment argp.h + @comment GNU + @deftypefun void argp_failure (const struct argp_state *@var{state}, int @var{status}, int @var{errnum}, const char *@var{fmt}, @dots{}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}} ++@c Lock stream, write out the short program name, vasprintf the optional ++@c formatted message to a buffer, print the buffer prefixed by colon and ++@c blank, release the buffer, call strerror_r with an automatic buffer, ++@c print it out after colon and blank, put[w]c a line break, unlock the ++@c stream, then exit unless ARGP_NO_EXIT. + Similar to the standard gnu error-reporting function @code{error}, this + prints the program name and @samp{:}, the printf format string + @var{fmt}, and the appropriate following args. If it is non-zero, the +@@ -695,6 +739,142 @@ + @comment argp.h + @comment GNU + @deftypefun void argp_state_help (const struct argp_state *@var{state}, FILE *@var{stream}, unsigned @var{flags}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}} ++@c Just calls _help with the short program name and optionally exit. ++@c The main problems in _help, besides the usual issues with stream I/O ++@c and translation, are the use of a static buffer (uparams, thus ++@c @mtasurace:argpbuf) that makes the whole thing thread-unsafe, reading ++@c from the environment for ARGP_HELP_FMT, accessing the locale object ++@c multiple times. ++ ++@c _help @mtsenv @mtasurace:argpbuf @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c dgettext @ascuintl ++@c flockfile @aculock ++@c funlockfile @aculock ++@c fill_in_uparams @mtsenv @mtasurace:argpbuf @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c argp_failure dup (status = errnum = 0) ++@c atoi dup @mtslocale ++@c argp_hol @ascuheap @acsmem ++@c make_hol @ascuheap @acsmem ++@c hol_add_cluster @ascuheap @acsmem ++@c hol_append @ascuheap @acsmem ++@c hol_set_group ok ++@c hol_find_entry ok ++@c hol_sort @mtslocale @acucorrupt ++@c qsort dup @acucorrupt ++@c hol_entry_qcmp @mtslocale ++@c hol_entry_cmp @mtslocale ++@c group_cmp ok ++@c hol_cluster_cmp ok ++@c group_cmp ok ++@c hol_entry_first_short @mtslocale ++@c hol_entry_short_iterate [@mtslocale] ++@c until_short ok ++@c oshort ok ++@c isprint ok ++@c odoc ok ++@c hol_entry_first_long ok ++@c canon_doc_option @mtslocale ++@c tolower dup ++@c hol_usage @mtslocale @ascuintl @ascuheap @acsmem ++@c hol_entry_short_iterate ok ++@c add_argless_short_opt ok ++@c argp_fmtstream_printf dup ++@c hol_entry_short_iterate @mtslocale @ascuintl @ascuheap @acsmem ++@c usage_argful_short_opt @mtslocale @ascuintl @ascuheap @acsmem ++@c dgettext dup ++@c argp_fmtstream_printf dup ++@c hol_entry_long_iterate @mtslocale @ascuintl @ascuheap @acsmem ++@c usage_long_opt @mtslocale @ascuintl @ascuheap @acsmem ++@c dgettext dup ++@c argp_fmtstream_printf dup ++@c hol_help @mtslocale @mtasurace:argpbuf @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c hol_entry_help @mtslocale @mtasurace:argpbuf @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_set_lmargin dup ++@c argp_fmtstream_wmargin dup ++@c argp_fmtstream_set_wmargin dup ++@c comma @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_putc dup ++@c hol_cluster_is_child ok ++@c argp_fmtstream_wmargin dup ++@c print_header dup ++@c argp_fmtstream_set_wmargin dup ++@c argp_fmtstream_puts dup ++@c indent_to dup ++@c argp_fmtstream_putc dup ++@c arg @mtslocale @ascuheap @acsmem ++@c argp_fmtstream_printf dup ++@c odoc dup ++@c argp_fmtstream_puts dup ++@c argp_fmtstream_printf dup ++@c print_header @mtslocale @mtasurace:argpbuf @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c dgettext dup ++@c filter_doc dup ++@c argp_fmtstream_putc dup ++@c indent_to dup ++@c argp_fmtstream_set_lmargin dup ++@c argp_fmtstream_set_wmargin dup ++@c argp_fmtstream_puts dup ++@c free dup ++@c filter_doc dup ++@c argp_fmtstream_point dup ++@c indent_to @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_point dup ++@c argp_fmtstream_putc dup ++@c dgettext dup ++@c filter_doc dup ++@c argp_fmtstream_putc dup ++@c argp_fmtstream_puts dup ++@c free dup ++@c hol_free @ascuheap @acsmem ++@c free dup ++@c argp_args_levels ok ++@c argp_args_usage @mtslocale @ascuintl @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c dgettext dup ++@c filter_doc ok ++@c argp_input ok ++@c argp->help_filter ++@c space @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_point dup ++@c argp_fmtstream_rmargin @mtslocale @asucorrupt @acucorrupt @aculock ++@c argp_fmtstream_update dup ++@c argp_fmtstream_putc dup ++@c argp_fmtstream_write dup ++@c free dup ++@c argp_doc @mtslocale @ascuheap @ascuintl @asucorrupt @acsmem @acucorrupt @aculock ++@c dgettext @ascuintl ++@c strndup @ascuheap @acsmem ++@c argp_input dup ++@c argp->help_filter ++@c argp_fmtstream_putc @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_ensure dup ++@c argp_fmtstream_write dup ++@c argp_fmtstream_puts dup ++@c argp_fmtstream_point @mtslocale @asucorrupt @acucorrupt @aculock ++@c argp_fmtstream_update dup ++@c argp_fmtstream_lmargin dup ++@c free dup ++@c argp_make_fmtstream @ascuheap @acsmem ++@c argp_fmtstream_free @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_update @mtslocale @asucorrupt @acucorrupt @aculock ++@c put[w]c_unlocked dup ++@c isblank in loop @mtslocale ++@c fxprintf @aculock ++@c fxprintf @aculock ++@c free dup ++@c argp_fmtstream_set_wmargin @mtslocale @asucorrupt @acucorrupt @aculock ++@c argp_fmtstream_update dup ++@c argp_fmtstream_printf @mtslocale @ascuheap @acsmem ++@c argp_fmtstream_ensure dup ++@c vsnprintf dup ++@c argp_fmtstream_set_lmargin @mtslocale @asucorrupt @acucorrupt @aculock ++@c argp_fmtstream_update dup ++@c argp_fmtstream_puts @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_write @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_ensure @mtslocale @ascuheap @asucorrupt @acsmem @acucorrupt @aculock ++@c argp_fmtstream_update dup ++@c fxprintf @aculock ++@c realloc @ascuheap @acsmem + Outputs a help message for the argp parser referred to by @var{state}, + to @var{stream}. The @var{flags} argument determines what sort of help + message is produced. @xref{Argp Help Flags}. +@@ -928,6 +1108,8 @@ + @comment argp.h + @comment GNU + @deftypefun void argp_help (const struct argp *@var{argp}, FILE *@var{stream}, unsigned @var{flags}, char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:argpbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @ascuintl{} @asucorrupt{}}@acunsafe{@acsmem{} @acucorrupt{} @aculock{}}} ++@c Just calls _help. + This outputs a help message for the argp parser @var{argp} to + @var{stream}. The type of messages printed will be determined by + @var{flags}. +diff -urN glibc-2.17-c758a686/manual/arith.texi glibc-2.17-c758a686/manual/arith.texi +--- glibc-2.17-c758a686/manual/arith.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/arith.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -160,6 +160,8 @@ + @comment stdlib.h + @comment ISO + @deftypefun div_t div (int @var{numerator}, int @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Functions in this section are pure, and thus safe. + This function @code{div} computes the quotient and remainder from + the division of @var{numerator} by @var{denominator}, returning the + result in a structure of type @code{div_t}. +@@ -199,6 +201,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun ldiv_t ldiv (long int @var{numerator}, long int @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{ldiv} function is similar to @code{div}, except that the + arguments are of type @code{long int} and the result is returned as a + structure of type @code{ldiv_t}. +@@ -225,6 +228,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun lldiv_t lldiv (long long int @var{numerator}, long long int @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{lldiv} function is like the @code{div} function, but the + arguments are of type @code{long long int} and the result is returned as + a structure of type @code{lldiv_t}. +@@ -256,6 +260,7 @@ + @comment inttypes.h + @comment ISO + @deftypefun imaxdiv_t imaxdiv (intmax_t @var{numerator}, intmax_t @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{imaxdiv} function is like the @code{div} function, but the + arguments are of type @code{intmax_t} and the result is returned as + a structure of type @code{imaxdiv_t}. +@@ -318,6 +323,7 @@ + @comment math.h + @comment ISO + @deftypefn {Macro} int fpclassify (@emph{float-type} @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is a generic macro which works on all floating-point types and + which returns a value of type @code{int}. The possible values are: + +@@ -354,6 +360,7 @@ + @comment math.h + @comment ISO + @deftypefn {Macro} int isfinite (@emph{float-type} @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if @var{x} is finite: not plus or + minus infinity, and not NaN. It is equivalent to + +@@ -368,6 +375,7 @@ + @comment math.h + @comment ISO + @deftypefn {Macro} int isnormal (@emph{float-type} @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if @var{x} is finite and normalized. + It is equivalent to + +@@ -379,6 +387,7 @@ + @comment math.h + @comment ISO + @deftypefn {Macro} int isnan (@emph{float-type} @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if @var{x} is NaN. It is equivalent + to + +@@ -387,6 +396,15 @@ + @end smallexample + @end deftypefn + ++@comment math.h ++@comment GNU ++@deftypefn {Macro} int issignaling (@emph{float-type} @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++This macro returns a nonzero value if @var{x} is a signaling NaN ++(sNaN). It is based on draft TS 18661 and currently enabled as a GNU ++extension. ++@end deftypefn ++ + Another set of floating-point classification functions was provided by + BSD. @Theglibc{} also supports these functions; however, we + recommend that you use the ISO C99 macros in new code. Those are standard +@@ -402,6 +420,7 @@ + @comment math.h + @comment BSD + @deftypefunx int isinfl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function returns @code{-1} if @var{x} represents negative infinity, + @code{1} if @var{x} represents positive infinity, and @code{0} otherwise. + @end deftypefun +@@ -415,6 +434,7 @@ + @comment math.h + @comment BSD + @deftypefunx int isnanl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function returns a nonzero value if @var{x} is a ``not a number'' + value, and zero otherwise. + +@@ -437,6 +457,7 @@ + @comment math.h + @comment BSD + @deftypefunx int finitel (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function returns a nonzero value if @var{x} is finite or a ``not a + number'' value, and zero otherwise. + @end deftypefun +@@ -489,7 +510,8 @@ + is called when certain exceptions occur inside math library functions. + However, the Unix98 standard deprecates this interface. We support it + for historical compatibility, but recommend that you do not use it in +-new programs. ++new programs. When this interface is used, exceptions may not be ++raised. + + @noindent + The exceptions defined in @w{IEEE 754} are: +@@ -705,6 +727,14 @@ + @comment fenv.h + @comment ISO + @deftypefun int feclearexcept (int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{@assposix{}}@acsafe{@acsposix{}}} ++@c The other functions in this section that modify FP status register ++@c mostly do so with non-atomic load-modify-store sequences, but since ++@c the register is thread-specific, this should be fine, and safe for ++@c cancellation. As long as the FP environment is restored before the ++@c signal handler returns control to the interrupted thread (like any ++@c kernel should do), the functions are also safe for use in signal ++@c handlers. + This function clears all of the supported exception flags indicated by + @var{excepts}. + +@@ -715,6 +745,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int feraiseexcept (int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function raises the supported exceptions indicated by + @var{excepts}. If more than one exception bit in @var{excepts} is set + the order in which the exceptions are raised is undefined except that +@@ -730,6 +761,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fetestexcept (int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Test whether the exception flags indicated by the parameter @var{except} + are currently set. If any of them are, a nonzero value is returned + which specifies which exceptions are set. Otherwise the result is zero. +@@ -766,6 +798,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fegetexceptflag (fexcept_t *@var{flagp}, int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function stores in the variable pointed to by @var{flagp} an + implementation-defined value representing the current setting of the + exception flags indicated by @var{excepts}. +@@ -777,6 +810,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fesetexceptflag (const fexcept_t *@var{flagp}, int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function restores the flags for the exceptions indicated by + @var{excepts} to the values stored in the variable pointed to by + @var{flagp}. +@@ -798,7 +832,8 @@ + Many of the math functions are defined only over a subset of the real or + complex numbers. Even if they are mathematically defined, their result + may be larger or smaller than the range representable by their return +-type. These are known as @dfn{domain errors}, @dfn{overflows}, and ++type without loss of accuracy. These are known as @dfn{domain errors}, ++@dfn{overflows}, and + @dfn{underflows}, respectively. Math functions do several things when + one of these errors occurs. In this manual we will refer to the + complete response as @dfn{signalling} a domain error, overflow, or +@@ -808,11 +843,20 @@ + exception and returns NaN. It also sets @var{errno} to @code{EDOM}; + this is for compatibility with old systems that do not support @w{IEEE + 754} exception handling. Likewise, when overflow occurs, math +-functions raise the overflow exception and return @math{@infinity{}} or +-@math{-@infinity{}} as appropriate. They also set @var{errno} to +-@code{ERANGE}. When underflow occurs, the underflow exception is +-raised, and zero (appropriately signed) is returned. @var{errno} may be +-set to @code{ERANGE}, but this is not guaranteed. ++functions raise the overflow exception and, in the default rounding ++mode, return @math{@infinity{}} or @math{-@infinity{}} as appropriate ++(in other rounding modes, the largest finite value of the appropriate ++sign is returned when appropriate for that rounding mode). They also ++set @var{errno} to @code{ERANGE} if returning @math{@infinity{}} or ++@math{-@infinity{}}; @var{errno} may or may not be set to ++@code{ERANGE} when a finite value is returned on overflow. When ++underflow occurs, the underflow exception is raised, and zero ++(appropriately signed) or a subnormal value, as appropriate for the ++mathematical result of the function and the rounding mode, is ++returned. @var{errno} may be set to @code{ERANGE}, but this is not ++guaranteed; it is intended that @theglibc{} should set it when the ++underflow is to an appropriately signed zero, but not necessarily for ++other underflows. + + Some of the math functions are defined mathematically to result in a + complex value over parts of their domains. The most familiar example of +@@ -932,6 +976,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fegetround (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns the currently selected rounding mode, represented by one of the + values of the defined rounding mode macros. + @end deftypefun +@@ -942,6 +987,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fesetround (int @var{round}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Changes the currently selected rounding mode to @var{round}. If + @var{round} does not correspond to one of the supported rounding modes + nothing is changed. @code{fesetround} returns zero if it changed the +@@ -986,6 +1032,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fegetenv (fenv_t *@var{envp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Store the floating-point environment in the variable pointed to by + @var{envp}. + +@@ -996,6 +1043,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int feholdexcept (fenv_t *@var{envp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Store the current floating-point environment in the object pointed to by + @var{envp}. Then clear all exception flags, and set the FPU to trap no + exceptions. Not all FPUs support trapping no exceptions; if +@@ -1034,6 +1082,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int fesetenv (const fenv_t *@var{envp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Set the floating-point environment to that described by @var{envp}. + + The function returns zero in case the operation was successful, a +@@ -1043,6 +1092,7 @@ + @comment fenv.h + @comment ISO + @deftypefun int feupdateenv (const fenv_t *@var{envp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Like @code{fesetenv}, this function sets the floating-point environment + to that described by @var{envp}. However, if any exceptions were + flagged in the status word before @code{feupdateenv} was called, they +@@ -1063,6 +1113,7 @@ + @comment fenv.h + @comment GNU + @deftypefun int feenableexcept (int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This functions enables traps for each of the exceptions as indicated by + the parameter @var{except}. The individual exceptions are described in + @ref{Status bit operations}. Only the specified exceptions are +@@ -1075,6 +1126,7 @@ + @comment fenv.h + @comment GNU + @deftypefun int fedisableexcept (int @var{excepts}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This functions disables traps for each of the exceptions as indicated by + the parameter @var{except}. The individual exceptions are described in + @ref{Status bit operations}. Only the specified exceptions are +@@ -1086,7 +1138,8 @@ + + @comment fenv.h + @comment GNU +-@deftypefun int fegetexcept (int @var{excepts}) ++@deftypefun int fegetexcept (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function returns a bitmask of all currently enabled exceptions. It + returns @code{-1} in case of failure. + @end deftypefun +@@ -1138,6 +1191,7 @@ + @comment inttypes.h + @comment ISO + @deftypefunx intmax_t imaxabs (intmax_t @var{number}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the absolute value of @var{number}. + + Most computers use a two's complement integer representation, in which +@@ -1159,6 +1213,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} fabsl (long double @var{number}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function returns the absolute value of the floating-point number + @var{number}. + @end deftypefun +@@ -1172,6 +1227,7 @@ + @comment complex.h + @comment ISO + @deftypefunx {long double} cabsl (complex long double @var{z}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the absolute value of the complex number @var{z} + (@pxref{Complex Numbers}). The absolute value of a complex number is: + +@@ -1181,7 +1237,7 @@ + + This function should always be used instead of the direct formula + because it takes special care to avoid losing precision. It may also +-take advantage of hardware support for this operation. See @code{hypot} ++take advantage of hardware support for this operation. See @code{hypot} + in @ref{Exponents and Logarithms}. + @end deftypefun + +@@ -1209,12 +1265,13 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} frexpl (long double @var{value}, int *@var{exponent}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are used to split the number @var{value} + into a normalized fraction and an exponent. + + If the argument @var{value} is not zero, the return value is @var{value} +-times a power of two, and is always in the range 1/2 (inclusive) to 1 +-(exclusive). The corresponding exponent is stored in ++times a power of two, and its magnitude is always in the range 1/2 ++(inclusive) to 1 (exclusive). The corresponding exponent is stored in + @code{*@var{exponent}}; the return value multiplied by 2 raised to this + exponent equals the original number @var{value}. + +@@ -1234,6 +1291,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} ldexpl (long double @var{value}, int @var{exponent}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the result of multiplying the floating-point + number @var{value} by 2 raised to the power @var{exponent}. (It can + be used to reassemble floating-point numbers that were taken apart +@@ -1248,51 +1306,55 @@ + + @comment math.h + @comment BSD +-@deftypefun double scalb (double @var{value}, int @var{exponent}) ++@deftypefun double scalb (double @var{value}, double @var{exponent}) + @comment math.h + @comment BSD +-@deftypefunx float scalbf (float @var{value}, int @var{exponent}) ++@deftypefunx float scalbf (float @var{value}, float @var{exponent}) + @comment math.h + @comment BSD +-@deftypefunx {long double} scalbl (long double @var{value}, int @var{exponent}) ++@deftypefunx {long double} scalbl (long double @var{value}, long double @var{exponent}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{scalb} function is the BSD name for @code{ldexp}. + @end deftypefun + + @comment math.h + @comment BSD +-@deftypefun {long long int} scalbn (double @var{x}, int @var{n}) ++@deftypefun double scalbn (double @var{x}, int @var{n}) + @comment math.h + @comment BSD +-@deftypefunx {long long int} scalbnf (float @var{x}, int @var{n}) ++@deftypefunx float scalbnf (float @var{x}, int @var{n}) + @comment math.h + @comment BSD +-@deftypefunx {long long int} scalbnl (long double @var{x}, int @var{n}) ++@deftypefunx {long double} scalbnl (long double @var{x}, int @var{n}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{scalbn} is identical to @code{scalb}, except that the exponent + @var{n} is an @code{int} instead of a floating-point number. + @end deftypefun + + @comment math.h + @comment BSD +-@deftypefun {long long int} scalbln (double @var{x}, long int @var{n}) ++@deftypefun double scalbln (double @var{x}, long int @var{n}) + @comment math.h + @comment BSD +-@deftypefunx {long long int} scalblnf (float @var{x}, long int @var{n}) ++@deftypefunx float scalblnf (float @var{x}, long int @var{n}) + @comment math.h + @comment BSD +-@deftypefunx {long long int} scalblnl (long double @var{x}, long int @var{n}) ++@deftypefunx {long double} scalblnl (long double @var{x}, long int @var{n}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{scalbln} is identical to @code{scalb}, except that the exponent + @var{n} is a @code{long int} instead of a floating-point number. + @end deftypefun + + @comment math.h + @comment BSD +-@deftypefun {long long int} significand (double @var{x}) ++@deftypefun double significand (double @var{x}) + @comment math.h + @comment BSD +-@deftypefunx {long long int} significandf (float @var{x}) ++@deftypefunx float significandf (float @var{x}) + @comment math.h + @comment BSD +-@deftypefunx {long long int} significandl (long double @var{x}) ++@deftypefunx {long double} significandl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{significand} returns the mantissa of @var{x} scaled to the range + @math{[1, 2)}. + It is equivalent to @w{@code{scalb (@var{x}, (double) -ilogb (@var{x}))}}. +@@ -1307,7 +1369,7 @@ + + @pindex math.h + The functions listed here perform operations such as rounding and +-truncation of floating-point values. Some of these functions convert ++truncation of floating-point values. Some of these functions convert + floating point numbers to integer values. They are all declared in + @file{math.h}. + +@@ -1327,6 +1389,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} ceill (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions round @var{x} upwards to the nearest integer, + returning that value as a @code{double}. Thus, @code{ceil (1.5)} + is @code{2.0}. +@@ -1341,6 +1404,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} floorl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions round @var{x} downwards to the nearest + integer, returning that value as a @code{double}. Thus, @code{floor + (1.5)} is @code{1.0} and @code{floor (-1.5)} is @code{-2.0}. +@@ -1355,6 +1419,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} truncl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{trunc} functions round @var{x} towards zero to the nearest + integer (returned in floating-point format). Thus, @code{trunc (1.5)} + is @code{1.0} and @code{trunc (-1.5)} is @code{-1.0}. +@@ -1369,6 +1434,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} rintl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions round @var{x} to an integer value according to the + current rounding mode. @xref{Floating Point Parameters}, for + information about the various rounding modes. The default +@@ -1389,6 +1455,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} nearbyintl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the same value as the @code{rint} functions, but + do not raise the inexact exception if @var{x} is not an integer. + @end deftypefun +@@ -1402,6 +1469,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} roundl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are similar to @code{rint}, but they round halfway + cases away from zero instead of to the nearest integer (or other + current rounding mode). +@@ -1416,6 +1484,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long int} lrintl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are just like @code{rint}, but they return a + @code{long int} instead of a floating-point number. + @end deftypefun +@@ -1429,6 +1498,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long long int} llrintl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are just like @code{rint}, but they return a + @code{long long int} instead of a floating-point number. + @end deftypefun +@@ -1442,6 +1512,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long int} lroundl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are just like @code{round}, but they return a + @code{long int} instead of a floating-point number. + @end deftypefun +@@ -1455,6 +1526,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long long int} llroundl (long double @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are just like @code{round}, but they return a + @code{long long int} instead of a floating-point number. + @end deftypefun +@@ -1469,6 +1541,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} modfl (long double @var{value}, long double *@var{integer-part}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions break the argument @var{value} into an integer part and a + fractional part (between @code{-1} and @code{1}, exclusive). Their sum + equals @var{value}. Each of the parts has the same sign as @var{value}, +@@ -1495,6 +1568,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} fmodl (long double @var{numerator}, long double @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions compute the remainder from the division of + @var{numerator} by @var{denominator}. Specifically, the return value is + @code{@var{numerator} - @w{@var{n} * @var{denominator}}}, where @var{n} +@@ -1517,6 +1591,7 @@ + @comment math.h + @comment BSD + @deftypefunx {long double} dreml (long double @var{numerator}, long double @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are like @code{fmod} except that they round the + internal quotient @var{n} to the nearest integer instead of towards zero + to an integer. For example, @code{drem (6.5, 2.3)} returns @code{-0.4}, +@@ -1540,6 +1615,7 @@ + @comment math.h + @comment BSD + @deftypefunx {long double} remainderl (long double @var{numerator}, long double @var{denominator}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is another name for @code{drem}. + @end deftypefun + +@@ -1561,6 +1637,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} copysignl (long double @var{x}, long double @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return @var{x} but with the sign of @var{y}. They work + even if @var{x} or @var{y} are NaN or zero. Both of these can carry a + sign (although not all implementations support it) and this is one of +@@ -1576,6 +1653,7 @@ + @comment math.h + @comment ISO + @deftypefun int signbit (@emph{float-type} @var{x}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{signbit} is a generic macro which can work on all floating-point + types. It returns a nonzero value if the value of @var{x} has its sign + bit set. +@@ -1594,6 +1672,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} nextafterl (long double @var{x}, long double @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{nextafter} function returns the next representable neighbor of + @var{x} in the direction towards @var{y}. The size of the step between + @var{x} and the result depends on the type of the result. If +@@ -1617,6 +1696,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} nexttowardl (long double @var{x}, long double @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions are identical to the corresponding versions of + @code{nextafter} except that their second argument is a @code{long + double}. +@@ -1632,6 +1712,8 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} nanl (const char *@var{tagp}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c The unsafe-but-ruled-safe locale use comes from strtod. + The @code{nan} function returns a representation of NaN, provided that + NaN is supported by the target platform. + @code{nan ("@var{n-char-sequence}")} is equivalent to +@@ -1666,6 +1748,7 @@ + @comment math.h + @comment ISO + @deftypefn Macro int isgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro determines whether the argument @var{x} is greater than + @var{y}. It is equivalent to @code{(@var{x}) > (@var{y})}, but no + exception is raised if @var{x} or @var{y} are NaN. +@@ -1674,6 +1757,7 @@ + @comment math.h + @comment ISO + @deftypefn Macro int isgreaterequal (@emph{real-floating} @var{x}, @emph{real-floating} @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro determines whether the argument @var{x} is greater than or + equal to @var{y}. It is equivalent to @code{(@var{x}) >= (@var{y})}, but no + exception is raised if @var{x} or @var{y} are NaN. +@@ -1682,6 +1766,7 @@ + @comment math.h + @comment ISO + @deftypefn Macro int isless (@emph{real-floating} @var{x}, @emph{real-floating} @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro determines whether the argument @var{x} is less than @var{y}. + It is equivalent to @code{(@var{x}) < (@var{y})}, but no exception is + raised if @var{x} or @var{y} are NaN. +@@ -1690,6 +1775,7 @@ + @comment math.h + @comment ISO + @deftypefn Macro int islessequal (@emph{real-floating} @var{x}, @emph{real-floating} @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro determines whether the argument @var{x} is less than or equal + to @var{y}. It is equivalent to @code{(@var{x}) <= (@var{y})}, but no + exception is raised if @var{x} or @var{y} are NaN. +@@ -1698,6 +1784,7 @@ + @comment math.h + @comment ISO + @deftypefn Macro int islessgreater (@emph{real-floating} @var{x}, @emph{real-floating} @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro determines whether the argument @var{x} is less or greater + than @var{y}. It is equivalent to @code{(@var{x}) < (@var{y}) || + (@var{x}) > (@var{y})} (although it only evaluates @var{x} and @var{y} +@@ -1710,6 +1797,7 @@ + @comment math.h + @comment ISO + @deftypefn Macro int isunordered (@emph{real-floating} @var{x}, @emph{real-floating} @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro determines whether its arguments are unordered. In other + words, it is true if @var{x} or @var{y} are NaN, and false otherwise. + @end deftypefn +@@ -1743,6 +1831,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} fminl (long double @var{x}, long double @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fmin} function returns the lesser of the two values @var{x} + and @var{y}. It is similar to the expression + @smallexample +@@ -1763,6 +1852,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} fmaxl (long double @var{x}, long double @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fmax} function returns the greater of the two values @var{x} + and @var{y}. + +@@ -1779,6 +1869,7 @@ + @comment math.h + @comment ISO + @deftypefunx {long double} fdiml (long double @var{x}, long double @var{y}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fdim} function returns the positive difference between + @var{x} and @var{y}. The positive difference is @math{@var{x} - + @var{y}} if @var{x} is greater than @var{y}, and @math{0} otherwise. +@@ -1796,6 +1887,7 @@ + @comment ISO + @deftypefunx {long double} fmal (long double @var{x}, long double @var{y}, long double @var{z}) + @cindex butterfly ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fma} function performs floating-point multiply-add. This is + the operation @math{(@var{x} @mul{} @var{y}) + @var{z}}, but the + intermediate result is not rounded to the destination type. This can +@@ -1925,6 +2017,7 @@ + @comment complex.h + @comment ISO + @deftypefunx {long double} creall (complex long double @var{z}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the real part of the complex number @var{z}. + @end deftypefun + +@@ -1937,6 +2030,7 @@ + @comment complex.h + @comment ISO + @deftypefunx {long double} cimagl (complex long double @var{z}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the imaginary part of the complex number @var{z}. + @end deftypefun + +@@ -1949,6 +2043,7 @@ + @comment complex.h + @comment ISO + @deftypefunx {complex long double} conjl (complex long double @var{z}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the conjugate value of the complex number + @var{z}. The conjugate of a complex number has the same real part and a + negated imaginary part. In other words, @samp{conj(a + bi) = a + -bi}. +@@ -1963,6 +2058,7 @@ + @comment complex.h + @comment ISO + @deftypefunx {long double} cargl (complex long double @var{z}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the argument of the complex number @var{z}. + The argument of a complex number is the angle in the complex plane + between the positive real axis and a line passing through zero and the +@@ -1981,8 +2077,9 @@ + @comment complex.h + @comment ISO + @deftypefunx {complex long double} cprojl (complex long double @var{z}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + These functions return the projection of the complex value @var{z} onto +-the Riemann sphere. Values with a infinite imaginary part are projected ++the Riemann sphere. Values with an infinite imaginary part are projected + to positive infinity on the real axis, even if the real part is NaN. If + the real part is infinite, the result is equivalent to + +@@ -2026,6 +2123,15 @@ + @comment stdlib.h + @comment ISO + @deftypefun {long int} strtol (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c strtol uses the thread-local pointer to the locale in effect, and ++@c strtol_l loads the LC_NUMERIC locale data from it early on and once, ++@c but if the locale is the global locale, and another thread calls ++@c setlocale in a way that modifies the pointer to the LC_CTYPE locale ++@c category, the behavior of e.g. IS*, TOUPPER will vary throughout the ++@c execution of the function, because they re-read the locale data from ++@c the given locale pointer. We solved this by documenting setlocale as ++@c MT-Unsafe. + The @code{strtol} (``string-to-long'') function converts the initial + part of @var{string} to a signed integer, which is returned as a value + of type @code{long int}. +@@ -2089,6 +2195,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {long int} wcstol (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstol} function is equivalent to the @code{strtol} function + in nearly all aspects but handles wide character strings. + +@@ -2098,6 +2205,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun {unsigned long int} strtoul (const char *retrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{strtoul} (``string-to-unsigned-long'') function is like + @code{strtol} except it converts to an @code{unsigned long int} value. + The syntax is the same as described above for @code{strtol}. The value +@@ -2116,6 +2224,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {unsigned long int} wcstoul (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstoul} function is equivalent to the @code{strtoul} function + in nearly all aspects but handles wide character strings. + +@@ -2125,6 +2234,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun {long long int} strtoll (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{strtoll} function is like @code{strtol} except that it returns + a @code{long long int} value, and accepts numbers with a correspondingly + larger range. +@@ -2141,6 +2251,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {long long int} wcstoll (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstoll} function is equivalent to the @code{strtoll} function + in nearly all aspects but handles wide character strings. + +@@ -2150,12 +2261,14 @@ + @comment stdlib.h + @comment BSD + @deftypefun {long long int} strtoq (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + @code{strtoq} (``string-to-quad-word'') is the BSD name for @code{strtoll}. + @end deftypefun + + @comment wchar.h + @comment GNU + @deftypefun {long long int} wcstoq (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstoq} function is equivalent to the @code{strtoq} function + in nearly all aspects but handles wide character strings. + +@@ -2165,6 +2278,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun {unsigned long long int} strtoull (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{strtoull} function is related to @code{strtoll} the same way + @code{strtoul} is related to @code{strtol}. + +@@ -2174,6 +2288,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {unsigned long long int} wcstoull (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstoull} function is equivalent to the @code{strtoull} function + in nearly all aspects but handles wide character strings. + +@@ -2183,12 +2298,14 @@ + @comment stdlib.h + @comment BSD + @deftypefun {unsigned long long int} strtouq (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + @code{strtouq} is the BSD name for @code{strtoull}. + @end deftypefun + + @comment wchar.h + @comment GNU + @deftypefun {unsigned long long int} wcstouq (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstouq} function is equivalent to the @code{strtouq} function + in nearly all aspects but handles wide character strings. + +@@ -2198,6 +2315,7 @@ + @comment inttypes.h + @comment ISO + @deftypefun intmax_t strtoimax (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{strtoimax} function is like @code{strtol} except that it returns + a @code{intmax_t} value, and accepts numbers of a corresponding range. + +@@ -2214,6 +2332,7 @@ + @comment wchar.h + @comment ISO + @deftypefun intmax_t wcstoimax (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstoimax} function is equivalent to the @code{strtoimax} function + in nearly all aspects but handles wide character strings. + +@@ -2223,6 +2342,7 @@ + @comment inttypes.h + @comment ISO + @deftypefun uintmax_t strtoumax (const char *restrict @var{string}, char **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{strtoumax} function is related to @code{strtoimax} + the same way that @code{strtoul} is related to @code{strtol}. + +@@ -2233,6 +2353,7 @@ + @comment wchar.h + @comment ISO + @deftypefun uintmax_t wcstoumax (const wchar_t *restrict @var{string}, wchar_t **restrict @var{tailptr}, int @var{base}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstoumax} function is equivalent to the @code{strtoumax} function + in nearly all aspects but handles wide character strings. + +@@ -2242,6 +2363,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun {long int} atol (const char *@var{string}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function is similar to the @code{strtol} function with a @var{base} + argument of @code{10}, except that it need not detect overflow errors. + The @code{atol} function is provided mostly for compatibility with +@@ -2251,6 +2373,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun int atoi (const char *@var{string}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function is like @code{atol}, except that it returns an @code{int}. + The @code{atoi} function is also considered obsolete; use @code{strtol} + instead. +@@ -2259,6 +2382,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun {long long int} atoll (const char *@var{string}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function is similar to @code{atol}, except it returns a @code{long + long int}. + +@@ -2323,6 +2447,35 @@ + @comment stdlib.h + @comment ISO + @deftypefun double strtod (const char *restrict @var{string}, char **restrict @var{tailptr}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Besides the unsafe-but-ruled-safe locale uses, this uses a lot of ++@c mpn, but it's all safe. ++@c ++@c round_and_return ++@c get_rounding_mode ok ++@c mpn_add_1 ok ++@c mpn_rshift ok ++@c MPN_ZERO ok ++@c MPN2FLOAT -> mpn_construct_(float|double|long_double) ok ++@c str_to_mpn ++@c mpn_mul_1 -> umul_ppmm ok ++@c mpn_add_1 ok ++@c mpn_lshift_1 -> mpn_lshift ok ++@c STRTOF_INTERNAL ++@c MPN_VAR ok ++@c SET_MANTISSA ok ++@c STRNCASECMP ok, wide and narrow ++@c round_and_return ok ++@c mpn_mul ok ++@c mpn_addmul_1 ok ++@c ... mpn_sub ++@c mpn_lshift ok ++@c udiv_qrnnd ok ++@c count_leading_zeros ok ++@c add_ssaaaa ok ++@c sub_ddmmss ok ++@c umul_ppmm ok ++@c mpn_submul_1 ok + The @code{strtod} (``string-to-double'') function converts the initial + part of @var{string} to a floating-point number, which is returned as a + value of type @code{double}. +@@ -2408,6 +2561,7 @@ + @comment stdlib.h + @comment ISO + @deftypefunx {long double} strtold (const char *@var{string}, char **@var{tailptr}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + These functions are analogous to @code{strtod}, but return @code{float} + and @code{long double} values respectively. They report errors in the + same way as @code{strtod}. @code{strtof} can be substantially faster +@@ -2427,6 +2581,7 @@ + @comment stdlib.h + @comment ISO + @deftypefunx {long double} wcstold (const wchar_t *@var{string}, wchar_t **@var{tailptr}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + The @code{wcstod}, @code{wcstof}, and @code{wcstol} functions are + equivalent in nearly all aspect to the @code{strtod}, @code{strtof}, and + @code{strtold} functions but it handles wide character string. +@@ -2439,6 +2594,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun double atof (const char *@var{string}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function is similar to the @code{strtod} function, except that it + need not detect overflow and underflow errors. The @code{atof} function + is provided mostly for compatibility with existing code; using +@@ -2447,7 +2603,8 @@ + + @Theglibc{} also provides @samp{_l} versions of these functions, + which take an additional argument, the locale to use in conversion. +-@xref{Parsing of Integers}. ++ ++See also @ref{Parsing of Integers}. + + @node System V Number Conversion + @section Old-fashioned System V number-to-string functions +@@ -2465,9 +2622,10 @@ + @comment stdlib.h + @comment SVID, Unix98 + @deftypefun {char *} ecvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:ecvt}}@asunsafe{}@acsafe{}} + The function @code{ecvt} converts the floating-point number @var{value} + to a string with at most @var{ndigit} decimal digits. The +-returned string contains no decimal point or sign. The first digit of ++returned string contains no decimal point or sign. The first digit of + the string is non-zero (unless @var{value} is actually zero) and the + last digit is rounded to nearest. @code{*@var{decpt}} is set to the + index in the string of the first digit after the decimal point. +@@ -2490,6 +2648,7 @@ + @comment stdlib.h + @comment SVID, Unix98 + @deftypefun {char *} fcvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fcvt}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The function @code{fcvt} is like @code{ecvt}, but @var{ndigit} specifies + the number of digits after the decimal point. If @var{ndigit} is less + than zero, @var{value} is rounded to the @math{@var{ndigit}+1}'th place to the +@@ -2508,6 +2667,9 @@ + @comment stdlib.h + @comment SVID, Unix98 + @deftypefun {char *} gcvt (double @var{value}, int @var{ndigit}, char *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c gcvt calls sprintf, that ultimately calls vfprintf, which malloc()s ++@c args_value if it's too large, but gcvt never exercises this path. + @code{gcvt} is functionally equivalent to @samp{sprintf(buf, "%*g", + ndigit, value}. It is provided only for compatibility's sake. It + returns @var{buf}. +@@ -2522,6 +2684,7 @@ + @comment stdlib.h + @comment GNU + @deftypefun {char *} qecvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:qecvt}}@asunsafe{}@acsafe{}} + This function is equivalent to @code{ecvt} except that it takes a + @code{long double} for the first parameter and that @var{ndigit} is + restricted by the precision of a @code{long double}. +@@ -2530,6 +2693,7 @@ + @comment stdlib.h + @comment GNU + @deftypefun {char *} qfcvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:qfcvt}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function is equivalent to @code{fcvt} except that it + takes a @code{long double} for the first parameter and that @var{ndigit} is + restricted by the precision of a @code{long double}. +@@ -2538,6 +2702,7 @@ + @comment stdlib.h + @comment GNU + @deftypefun {char *} qgcvt (long double @var{value}, int @var{ndigit}, char *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is equivalent to @code{gcvt} except that it takes a + @code{long double} for the first parameter and that @var{ndigit} is + restricted by the precision of a @code{long double}. +@@ -2558,6 +2723,7 @@ + @comment stdlib.h + @comment GNU + @deftypefun int ecvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{ecvt_r} function is the same as @code{ecvt}, except + that it places its result into the user-specified buffer pointed to by + @var{buf}, with length @var{len}. The return value is @code{-1} in +@@ -2569,6 +2735,7 @@ + @comment stdlib.h + @comment SVID, Unix98 + @deftypefun int fcvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fcvt_r} function is the same as @code{fcvt}, except that it + places its result into the user-specified buffer pointed to by + @var{buf}, with length @var{len}. The return value is @code{-1} in +@@ -2580,6 +2747,7 @@ + @comment stdlib.h + @comment GNU + @deftypefun int qecvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{qecvt_r} function is the same as @code{qecvt}, except + that it places its result into the user-specified buffer pointed to by + @var{buf}, with length @var{len}. The return value is @code{-1} in +@@ -2591,6 +2759,7 @@ + @comment stdlib.h + @comment GNU + @deftypefun int qfcvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{qfcvt_r} function is the same as @code{qfcvt}, except + that it places its result into the user-specified buffer pointed to by + @var{buf}, with length @var{len}. The return value is @code{-1} in +diff -urN glibc-2.17-c758a686/manual/charset.texi glibc-2.17-c758a686/manual/charset.texi +--- glibc-2.17-c758a686/manual/charset.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/charset.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -504,6 +504,14 @@ + @comment wchar.h + @comment ISO + @deftypefun int mbsinit (const mbstate_t *@var{ps}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c ps is dereferenced once, unguarded. This would call for @mtsrace:ps, ++@c but since a single word-sized field is (atomically) accessed, any ++@c race here would be harmless. Other functions that take an optional ++@c mbstate_t* argument named ps are marked with @mtasurace:/!ps, ++@c to indicate that the function uses a static buffer if ps is NULL. ++@c These could also have been marked with @mtsrace:ps, but we'll omit ++@c that for brevity, for it's somewhat redundant with the @mtasurace. + The @code{mbsinit} function determines whether the state object pointed + to by @var{ps} is in the initial state. If @var{ps} is a null pointer or + the object is in the initial state the return value is nonzero. Otherwise +@@ -559,6 +567,14 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t btowc (int @var{c}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c Calls btowc_fct or __fct; reads from locale, and from the ++@c get_gconv_fcts result multiple times. get_gconv_fcts calls ++@c __wcsmbs_load_conv to initialize the ctype if it's null. ++@c wcsmbs_load_conv takes a non-recursive wrlock before allocating ++@c memory for the fcts structure, initializing it, and then storing it ++@c in the locale object. The initialization involves dlopening and a ++@c lot more. + The @code{btowc} function (``byte to wide character'') converts a valid + single byte character @var{c} in the initial shift state into the wide + character equivalent using the conversion rules from the currently +@@ -615,6 +631,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int wctob (wint_t @var{c}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{wctob} function (``wide character to byte'') takes as the + parameter a valid wide character. If the multibyte representation for + this character in the initial state is exactly one byte long, the return +@@ -634,6 +651,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t mbrtowc (wchar_t *restrict @var{pwc}, const char *restrict @var{s}, size_t @var{n}, mbstate_t *restrict @var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mbrtowc/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + @cindex stateful + The @code{mbrtowc} function (``multibyte restartable to wide + character'') converts the next multibyte character in the string pointed +@@ -728,6 +746,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t mbrlen (const char *restrict @var{s}, size_t @var{n}, mbstate_t *@var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mbrlen/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{mbrlen} function (``multibyte restartable length'') computes + the number of at most @var{n} bytes starting at @var{s}, which form the + next valid and complete multibyte character. +@@ -786,7 +805,7 @@ + This function simply calls @code{mbrlen} for each multibyte character + in the string and counts the number of function calls. Please note that + we here use @code{MB_LEN_MAX} as the size argument in the @code{mbrlen} +-call. This is acceptable since a) this value is larger then the length of ++call. This is acceptable since a) this value is larger than the length of + the longest multibyte character sequence and b) we know that the string + @var{s} ends with a NUL byte, which cannot be part of any other multibyte + character sequence but the one representing the NUL wide character. +@@ -811,6 +830,50 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t wcrtomb (char *restrict @var{s}, wchar_t @var{wc}, mbstate_t *restrict @var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:wcrtomb/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c wcrtomb uses a static, non-thread-local unguarded state variable when ++@c PS is NULL. When a state is passed in, and it's not used ++@c concurrently in other threads, this function behaves safely as long ++@c as gconv modules don't bring MT safety issues of their own. ++@c Attempting to load gconv modules or to build conversion chains in ++@c signal handlers may encounter gconv databases or caches in a ++@c partially-updated state, and asynchronous cancellation may leave them ++@c in such states, besides leaking the lock that guards them. ++@c get_gconv_fcts ok ++@c wcsmbs_load_conv ok ++@c norm_add_slashes ok ++@c wcsmbs_getfct ok ++@c gconv_find_transform ok ++@c gconv_read_conf (libc_once) ++@c gconv_lookup_cache ok ++@c find_module_idx ok ++@c find_module ok ++@c gconv_find_shlib (ok) ++@c ->init_fct (assumed ok) ++@c gconv_get_builtin_trans ok ++@c gconv_release_step ok ++@c do_lookup_alias ok ++@c find_derivation ok ++@c derivation_lookup ok ++@c increment_counter ok ++@c gconv_find_shlib ok ++@c step->init_fct (assumed ok) ++@c gen_steps ok ++@c gconv_find_shlib ok ++@c dlopen (presumed ok) ++@c dlsym (presumed ok) ++@c step->init_fct (assumed ok) ++@c step->end_fct (assumed ok) ++@c gconv_get_builtin_trans ok ++@c gconv_release_step ok ++@c add_derivation ok ++@c gconv_close_transform ok ++@c gconv_release_step ok ++@c step->end_fct (assumed ok) ++@c gconv_release_shlib ok ++@c dlclose (presumed ok) ++@c gconv_release_cache ok ++@c ->tomb->__fct (assumed ok) + The @code{wcrtomb} function (``wide character restartable to + multibyte'') converts a single wide character into a multibyte string + corresponding to that wide character. +@@ -955,8 +1018,9 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t mbsrtowcs (wchar_t *restrict @var{dst}, const char **restrict @var{src}, size_t @var{len}, mbstate_t *restrict @var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mbsrtowcs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{mbsrtowcs} function (``multibyte string restartable to wide +-character string'') converts an NUL-terminated multibyte character ++character string'') converts a NUL-terminated multibyte character + string at @code{*@var{src}} into an equivalent wide character string, + including the NUL wide character at the end. The conversion is started + using the state information from the object pointed to by @var{ps} or +@@ -1039,6 +1103,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t wcsrtombs (char *restrict @var{dst}, const wchar_t **restrict @var{src}, size_t @var{len}, mbstate_t *restrict @var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:wcsrtombs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{wcsrtombs} function (``wide character string restartable to + multibyte string'') converts the NUL-terminated wide character string at + @code{*@var{src}} into an equivalent multibyte character string and +@@ -1084,6 +1149,7 @@ + @comment wchar.h + @comment GNU + @deftypefun size_t mbsnrtowcs (wchar_t *restrict @var{dst}, const char **restrict @var{src}, size_t @var{nmc}, size_t @var{len}, mbstate_t *restrict @var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mbsnrtowcs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{mbsnrtowcs} function is very similar to the @code{mbsrtowcs} + function. All the parameters are the same except for @var{nmc}, which is + new. The return value is the same as for @code{mbsrtowcs}. +@@ -1136,6 +1202,7 @@ + @comment wchar.h + @comment GNU + @deftypefun size_t wcsnrtombs (char *restrict @var{dst}, const wchar_t **restrict @var{src}, size_t @var{nwc}, size_t @var{len}, mbstate_t *restrict @var{ps}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:wcsnrtombs/!ps}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{wcsnrtombs} function implements the conversion from wide + character strings to multibyte character strings. It is similar to + @code{wcsrtombs} but, just like @code{mbsnrtowcs}, it takes an extra +@@ -1280,6 +1347,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun int mbtowc (wchar_t *restrict @var{result}, const char *restrict @var{string}, size_t @var{size}) ++@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{mbtowc} (``multibyte to wide character'') function when called + with non-null @var{string} converts the first multibyte character + beginning at @var{string} to its corresponding wide character code. It +@@ -1314,6 +1382,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun int wctomb (char *@var{string}, wchar_t @var{wchar}) ++@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{wctomb} (``wide character to multibyte'') function converts + the wide character code @var{wchar} to its corresponding multibyte + character sequence, and stores the result in bytes starting at +@@ -1353,6 +1422,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun int mblen (const char *@var{string}, size_t @var{size}) ++@safety{@prelim{}@mtunsafe{@mtasurace{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{mblen} function with a non-null @var{string} argument returns + the number of bytes that make up the multibyte character beginning at + @var{string}, never examining more than @var{size} bytes. (The idea is +@@ -1391,6 +1461,9 @@ + @comment stdlib.h + @comment ISO + @deftypefun size_t mbstowcs (wchar_t *@var{wstring}, const char *@var{string}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c Odd... Although this was supposed to be non-reentrant, the internal ++@c state is not a static buffer, but an automatic variable. + The @code{mbstowcs} (``multibyte string to wide character string'') + function converts the null-terminated string of multibyte characters + @var{string} to an array of wide character codes, storing not more than +@@ -1431,6 +1504,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun size_t wcstombs (char *@var{string}, const wchar_t *@var{wstring}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} + The @code{wcstombs} (``wide character string to multibyte string'') + function converts the null-terminated wide character array @var{wstring} + into a string containing multibyte characters, storing not more than +@@ -1618,6 +1692,16 @@ + @comment iconv.h + @comment XPG2 + @deftypefun iconv_t iconv_open (const char *@var{tocode}, const char *@var{fromcode}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c Calls malloc if tocode and/or fromcode are too big for alloca. Calls ++@c strip and upstr on both, then gconv_open. strip and upstr call ++@c isalnum_l and toupper_l with the C locale. gconv_open may MT-safely ++@c tokenize toset, replace unspecified codesets with the current locale ++@c (possibly two different accesses), and finally it calls ++@c gconv_find_transform and initializes the gconv_t result with all the ++@c steps in the conversion sequence, running each one's initializer, ++@c destructing and releasing them all if anything fails. ++ + The @code{iconv_open} function has to be used before starting a + conversion. The two parameters this function takes determine the + source and destination character set for the conversion, and if the +@@ -1625,7 +1709,7 @@ + function returns a handle. + + If the wanted conversion is not available, the @code{iconv_open} function +-returns @code{(iconv_t) -1}. In this case the global variable ++returns @code{(iconv_t) -1}. In this case the global variable + @code{errno} can have the following values: + + @table @code +@@ -1682,6 +1766,12 @@ + @comment iconv.h + @comment XPG2 + @deftypefun int iconv_close (iconv_t @var{cd}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Calls gconv_close to destruct and release each of the conversion ++@c steps, release the gconv_t object, then call gconv_close_transform. ++@c Access to the gconv_t object is not guarded, but calling iconv_close ++@c concurrently with any other use is undefined. ++ + The @code{iconv_close} function frees all resources associated with the + handle @var{cd}, which must have been returned by a successful call to + the @code{iconv_open} function. +@@ -1708,6 +1798,10 @@ + @comment iconv.h + @comment XPG2 + @deftypefun size_t iconv (iconv_t @var{cd}, char **@var{inbuf}, size_t *@var{inbytesleft}, char **@var{outbuf}, size_t *@var{outbytesleft}) ++@safety{@prelim{}@mtsafe{@mtsrace{:cd}}@assafe{}@acunsafe{@acucorrupt{}}} ++@c Without guarding access to the iconv_t object pointed to by cd, call ++@c the conversion function to convert inbuf or flush the internal ++@c conversion state. + @cindex stateful + The @code{iconv} function converts the text in the input buffer + according to the rules associated with the descriptor @var{cd} and +@@ -1744,7 +1838,7 @@ + Therefore an @code{iconv} call to reset the state should always be + performed if some protocol requires this for the output text. + +-The conversion stops for one of three reasons. The first is that all ++The conversion stops for one of three reasons. The first is that all + characters from the input buffer are converted. This actually can mean + two things: either all bytes from the input buffer are consumed or + there are some bytes at the end of the buffer that possibly can form a +@@ -2039,7 +2133,7 @@ + + Unfortunately, the answer is: there is no general solution. On some + systems guessing might help. On those systems most character sets can +-convert to and from UTF-8 encoded @w{ISO 10646} or Unicode text. Beside ++convert to and from UTF-8 encoded @w{ISO 10646} or Unicode text. Beside + this only some very system-specific methods can help. Since the + conversion functions come from loadable modules and these modules must + be stored somewhere in the filesystem, one @emph{could} try to find them +@@ -2239,7 +2333,7 @@ + + So far this section has described how modules are located and considered + to be used. What remains to be described is the interface of the modules +-so that one can write new ones. This section describes the interface as ++so that one can write new ones. This section describes the interface as + it is in use in January 1999. The interface will change a bit in the + future but, with luck, only in an upwardly compatible way. + +@@ -2485,7 +2579,7 @@ + same size, the minimum and maximum values are the same. + + @item __stateful +-This element must be initialized to an nonzero value if the source ++This element must be initialized to a nonzero value if the source + character set is stateful. Otherwise it must be zero. + @end table + +@@ -2824,7 +2918,7 @@ + /* @r{Run the conversion loop. @code{status} is set} + @r{appropriately afterwards.} */ + +- /* @r{If this is the last step, leave the loop. There is} ++ /* @r{If this is the last step, leave the loop. There is} + @r{nothing we can do.} */ + if (data->__is_last) + @{ +diff -urN glibc-2.17-c758a686/manual/check-safety.sh glibc-2.17-c758a686/manual/check-safety.sh +--- glibc-2.17-c758a686/manual/check-safety.sh 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/manual/check-safety.sh 2014-09-12 16:10:06.044792719 -0400 +@@ -0,0 +1,119 @@ ++#! /bin/sh ++ ++# Copyright 2014 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++ ++# Check that the @safety notes are self-consistent, i.e., that they're ++# in proper order (mt then as then ac), that remarks appear within ++# corresponding sections (mt within mt, etc), that unsafety always has ++# an explicit reason and when there's a reason for unsafety it's not ++# safe, and that there aren't duplicates remarks. ++ ++ ++success=: ++ ++# If no arguments are given, take all *.texi files in the current directory. ++test $# != 0 || set *.texi ++ ++# Check that all safety remarks have entries for all of MT, AS and AC, ++# in this order, with an optional prelim note before them. ++grep -n '^@safety' "$@" | ++grep -v ':@safety{\(@prelim{}\)\?@mt\(un\)\?safe{.*}'\ ++'@as\(un\)\?safe{.*}@ac\(un\)\?safe{.*}}' && ++success=false ++ ++# Check that @mt-started notes appear within @mtsafe or @mtunsafe, ++# that @as-started notes appear within @assafe or @asunsafe, and that ++# @ac-started notes appear within @acsafe or @acunsafe. Also check ++# that @mt, @as and @ac are followed by an s (for safe) or u (for ++# unsafe), but let @mt have as, ac or asc before [su], and let @as ++# have a c (for cancel) before [su]. Also make sure blanks separate ++# each of the annotations. ++grep -n '^@safety' "$@" | ++grep -v ':@safety{\(@prelim{}\)\?'\ ++'@mt\(un\)\?safe{\(@mt\(asc\?\|ac\)\?[su][^ ]*}\)\?'\ ++'\( @mt\(asc\?\|ac\)\?[su][^ ]*}\)*}'\ ++'@as\(un\)\?safe{\(@asc\?[su][^ ]*}\)\?'\ ++'\( @asc\?[su][^ ]*}\)*}'\ ++'@ac\(un\)\?safe{\(@ac[su][^ ]*}\)\?'\ ++'\( @ac[su][^ ]*}\)*}}' && ++success=false ++ ++# Make sure safety lines marked as @mtsafe do not contain any ++# MT-Unsafe remark; that would be @mtu, but there could be as, ac or ++# asc between mt and u. ++grep -n '^@safety.*@mtsafe' "$@" | ++grep '@mt\(asc\?\|ac\)?u' "$@" && ++success=false ++ ++# Make sure @mtunsafe lines contain at least one @mtu remark (with ++# optional as, ac or asc between mt and u). ++grep -n '^@safety.*@mtunsafe' "$@" | ++grep -v '@mtunsafe{.*@mt\(asc\?\|ac\)\?u' && ++success=false ++ ++# Make sure safety lines marked as @assafe do not contain any AS-Unsafe ++# remark, which could be @asu or @mtasu note (with an optional c ++# between as and u in both cases). ++grep -n '^@safety.*@assafe' "$@" | ++grep '@\(mt\)\?asc\?u' && ++success=false ++ ++# Make sure @asunsafe lines contain at least one @asu remark (which ++# could be @ascu, or @mtasu or even @mtascu). ++grep -n '^@safety.*@asunsafe' "$@" | ++grep -v '@mtasc\?u.*@asunsafe\|@asunsafe{.*@asc\?u' && ++success=false ++ ++# Make sure safety lines marked as @acsafe do not contain any ++# AC-Unsafe remark, which could be @acu, @ascu or even @mtacu or ++# @mtascu. ++grep -n '^@safety.*@acsafe' "$@" | ++grep '@\(mt\)\?as\?cu' && ++success=false ++ ++# Make sure @acunsafe lines contain at least one @acu remark (possibly ++# implied by @ascu, @mtacu or @mtascu). ++grep -n '^@safety.*@acunsafe' "$@" | ++grep -v '@\(mtas\?\|as\)cu.*@acunsafe\|@acunsafe{.*@acu' && ++success=false ++ ++# Make sure there aren't duplicate remarks in the same safety note. ++grep -n '^@safety' "$@" | ++grep '[^:]\(@\(mt\|a[sc]\)[^ {]*{[^ ]*}\).*[^:]\1' && ++success=false ++ ++# Check that comments containing safety remarks do not contain {}s, ++# that all @mt remarks appear before @as remarks, that in turn appear ++# before @ac remarks, all properly blank-separated, and that an ++# optional comment about exclusions is between []s at the end of the ++# line. ++grep -n '^@c \+[^@ ]\+\( dup\)\?'\ ++'\( @\(mt\|a[sc]\)[^ ]*\)*\( \[.*\]\)\?$' "$@" | ++grep -v ':@c *[^@{}]*\( @mt[^ {}]*\)*'\ ++'\( @as[^ {}]*\)*\( @ac[^ {}]*\)*\( \[.*\]\)\?$' && ++success=false ++ ++# Check that comments containing safety remarks do not contain ++# duplicate remarks. ++grep -n '^@c \+[^@ ]\+\( dup\)\?'\ ++'\( @\(mt\|a[sc]\)[^ ]*\)*\( \[.*\]\)\?$' "$@" | ++grep '[^:]\(@\(mt\|a[sc]\)[^ ]*\) \(.*[^:]\)\?\1\($\| \)' && ++success=false ++ ++$success +diff -urN glibc-2.17-c758a686/manual/conf.texi glibc-2.17-c758a686/manual/conf.texi +--- glibc-2.17-c758a686/manual/conf.texi 2014-09-12 16:08:17.965070383 -0400 ++++ glibc-2.17-c758a686/manual/conf.texi 2014-09-12 16:10:06.047792712 -0400 +@@ -114,7 +114,7 @@ + + @comment limits.h + @comment POSIX.1 +-@deftypevr Macro int SSIZE_MAX ++@deftypevr Macro ssize_t SSIZE_MAX + The largest value that can fit in an object of type @code{ssize_t}. + Effectively, this is the limit on the number of bytes that can be read + or written in a single operation. +@@ -288,6 +288,17 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {long int} sysconf (int @var{parameter}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c Some parts of the implementation open /proc and /sys files and dirs ++@c to collect system details, using fd and stream I/O depending on the ++@c case. _SC_TZNAME_MAX calls __tzname_max, that (while holding a lock) ++@c calls tzset_internal, that calls getenv if it's called the first ++@c time; there are free and strdup calls in there too. The returned max ++@c value may change over time for TZNAME_MAX, depending on selected ++@c timezones; NPROCS, NPROCS_CONF, PHYS_PAGES, AVPHYS_PAGES, ++@c NGROUPS_MAX, SIGQUEUE_MAX, depending on variable values read from ++@c /proc at each call, and from rlimit-obtained values CHILD_MAX, ++@c OPEN_MAX, ARG_MAX, SIGQUEUE_MAX. + This function is used to inquire about runtime system parameters. The + @var{parameter} argument should be one of the @samp{_SC_} symbols listed + below. +@@ -1121,7 +1132,7 @@ + have on @emph{any} POSIX system. @xref{File Minimums}. + + @cindex limits, link count of files +-@comment limits.h ++@comment limits.h (optional) + @comment POSIX.1 + @deftypevr Macro int LINK_MAX + The uniform system limit (if any) for the number of names for a given +@@ -1348,6 +1359,11 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {long int} pathconf (const char *@var{filename}, int @var{parameter}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c When __statfs_link_max finds an ext* filesystem, it may read ++@c /proc/mounts or similar as a mntent stream. ++@c __statfs_chown_restricted may read from ++@c /proc/sys/fs/xfs/restrict_chown as a file descriptor. + This function is used to inquire about the limits that apply to + the file named @var{filename}. + +@@ -1375,6 +1391,8 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {long int} fpathconf (int @var{filedes}, int @var{parameter}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c Same caveats as pathconf. + This is just like @code{pathconf} except that an open file descriptor + is used to specify the file for which information is requested, instead + of a file name. +@@ -1624,6 +1642,7 @@ + @comment unistd.h + @comment POSIX.2 + @deftypefun size_t confstr (int @var{parameter}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function reads the value of a string-valued system parameter, + storing the string into @var{len} bytes of memory space starting at + @var{buf}. The @var{parameter} argument should be one of the +diff -urN glibc-2.17-c758a686/manual/crypt.texi glibc-2.17-c758a686/manual/crypt.texi +--- glibc-2.17-c758a686/manual/crypt.texi 2014-09-12 16:08:18.169069859 -0400 ++++ glibc-2.17-c758a686/manual/crypt.texi 2014-09-12 16:10:06.042792724 -0400 +@@ -30,15 +30,15 @@ + and the other based on the Data Encryption Standard (DES) that is + compatible with Unix systems. + +-@cindex AUTH_DES ++@vindex AUTH_DES + @cindex FIPS 140-2 + It also provides support for Secure RPC, and some library functions that +-can be used to perform normal DES encryption. The use of DES when +-using @code{AUTH_DES} in Secure RPC for authentication as provided by +-@theglibc{} is not FIPS 140-2 compliant nor is any other use of DES +-within @theglibc{}. It is recommended that Secure RPC should not be used +-for systems that need to be FIPS 140-2 compliant since all forms of +-supported authentication use normal DES. ++can be used to perform normal DES encryption. The @code{AUTH_DES} ++authentication flavor in Secure RPC, as provided by @theglibc{}, ++uses DES and does not comply with FIPS 140-2 nor does any other use of DES ++within @theglibc{}. It is recommended that Secure RPC should not be used ++for systems that need to comply with FIPS 140-2 since all flavors of ++encrypted authentication use normal DES. + + @menu + * Legal Problems:: This software can get you locked up, or worse. +@@ -99,6 +99,13 @@ + @comment unistd.h + @comment BSD + @deftypefun {char *} getpass (const char *@var{prompt}) ++@safety{@prelim{}@mtunsafe{@mtasuterm{}}@asunsafe{@ascuheap{} @asulock{} @asucorrupt{}}@acunsafe{@acuterm{} @aculock{} @acucorrupt{}}} ++@c This function will attempt to create a stream for terminal I/O, but ++@c will fallback to stdio/stderr. It attempts to change the terminal ++@c mode in a thread-unsafe way, write out the prompt, read the password, ++@c then restore the terminal mode. It has a cleanup to close the stream ++@c in case of (synchronous) cancellation, but not to restore the ++@c terminal mode. + + @code{getpass} outputs @var{prompt}, then reads a string in from the + terminal without echoing it. It tries to connect to the real terminal, +@@ -134,6 +141,13 @@ + @comment crypt.h + @comment BSD, SVID + @deftypefun {char *} crypt (const char *@var{key}, const char *@var{salt}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}} ++@c Besides the obvious problem of returning a pointer into static ++@c storage, the DES initializer takes an internal lock with the usual ++@c set of problems for AS- and AC-Safety. The FIPS mode checker and the ++@c NSS implementations of may leak file descriptors if canceled. The ++@c The MD5, SHA256 and SHA512 implementations will malloc on long keys, ++@c and NSS relies on dlopening, which brings about another can of worms. + + The @code{crypt} function takes a password, @var{key}, as a string, and + a @var{salt} character array which is described below, and returns a +@@ -195,6 +209,9 @@ + @comment crypt.h + @comment GNU + @deftypefun {char *} crypt_r (const char *@var{key}, const char *@var{salt}, {struct crypt_data *} @var{data}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{} @ascuheap{} @ascudlopen{}}@acunsafe{@aculock{} @acsmem{}}} ++@c Compared with crypt, this function fixes the @mtasurace:crypt ++@c problem, but nothing else. + + The @code{crypt_r} function does the same thing as @code{crypt}, but + takes an extra parameter which includes space for its result (among +@@ -241,6 +258,11 @@ + @comment crypt.h + @comment BSD, SVID + @deftypefun void setkey (const char *@var{key}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}} ++@c The static buffer stores the key, making it fundamentally ++@c thread-unsafe. The locking issues are only in the initialization ++@c path; cancelling the initialization will leave the lock held, it ++@c would otherwise repeat the initialization on the next call. + + The @code{setkey} function sets an internal data structure to be an + expanded form of @var{key}. @var{key} is specified as an array of 64 +@@ -252,6 +274,8 @@ + @comment crypt.h + @comment BSD, SVID + @deftypefun void encrypt (char *@var{block}, int @var{edflag}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}} ++@c Same issues as setkey. + + The @code{encrypt} function encrypts @var{block} if + @var{edflag} is 0, otherwise it decrypts @var{block}, using a key +@@ -265,9 +289,11 @@ + @comment crypt.h + @comment GNU + @deftypefun void setkey_r (const char *@var{key}, {struct crypt_data *} @var{data}) ++@c @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}} + @comment crypt.h + @comment GNU + @deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}} + + These are reentrant versions of @code{setkey} and @code{encrypt}. The + only difference is the extra parameter, which stores the expanded +@@ -282,6 +308,7 @@ + @comment rpc/des_crypt.h + @comment SUNRPC + @deftypefun int ecb_crypt (char *@var{key}, char *@var{blocks}, unsigned @var{len}, unsigned @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + The function @code{ecb_crypt} encrypts or decrypts one or more blocks + using DES. Each block is encrypted independently. +@@ -356,6 +383,7 @@ + @comment rpc/des_crypt.h + @comment SUNRPC + @deftypefun int DES_FAILED (int @var{err}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns 1 if @var{err} is a `success' result code from + @code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise. + @end deftypefun +@@ -363,6 +391,7 @@ + @comment rpc/des_crypt.h + @comment SUNRPC + @deftypefun int cbc_crypt (char *@var{key}, char *@var{blocks}, unsigned @var{len}, unsigned @var{mode}, char *@var{ivec}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + The function @code{cbc_crypt} encrypts or decrypts one or more blocks + using DES in Cipher Block Chaining mode. +@@ -389,6 +418,7 @@ + @comment rpc/des_crypt.h + @comment SUNRPC + @deftypefun void des_setparity (char *@var{key}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + The function @code{des_setparity} changes the 64-bit @var{key}, stored + packed in 8-bit bytes, to have odd parity by altering the low bits of +diff -urN glibc-2.17-c758a686/manual/ctype.texi glibc-2.17-c758a686/manual/ctype.texi +--- glibc-2.17-c758a686/manual/ctype.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/ctype.texi 2014-09-12 16:10:06.042792724 -0400 +@@ -66,6 +66,16 @@ + @comment ctype.h + @comment ISO + @deftypefun int islower (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c The is* macros call __ctype_b_loc to get the ctype array from the ++@c current locale, and then index it by c. __ctype_b_loc reads from ++@c thread-local memory the (indirect) pointer to the ctype array, which ++@c may involve one word access to the global locale object, if that's ++@c the active locale for the thread, and the array, being part of the ++@c locale data, is undeletable, so there's no thread-safety issue. We ++@c might want to mark these with @mtslocale to flag to callers that ++@c changing locales might affect them, even if not these simpler ++@c functions. + Returns true if @var{c} is a lower-case letter. The letter need not be + from the Latin alphabet, any alphabet representable is valid. + @end deftypefun +@@ -74,6 +84,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isupper (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is an upper-case letter. The letter need not be + from the Latin alphabet, any alphabet representable is valid. + @end deftypefun +@@ -82,6 +93,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isalpha (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is an alphabetic character (a letter). If + @code{islower} or @code{isupper} is true of a character, then + @code{isalpha} is also true. +@@ -97,6 +109,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isdigit (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a decimal digit (@samp{0} through @samp{9}). + @end deftypefun + +@@ -104,6 +117,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isalnum (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is an alphanumeric character (a letter or + number); in other words, if either @code{isalpha} or @code{isdigit} is + true of a character, then @code{isalnum} is also true. +@@ -113,6 +127,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isxdigit (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a hexadecimal digit. + Hexadecimal digits include the normal decimal digits @samp{0} through + @samp{9} and the letters @samp{A} through @samp{F} and +@@ -123,6 +138,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int ispunct (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a punctuation character. + This means any printing character that is not alphanumeric or a space + character. +@@ -132,6 +148,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isspace (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a @dfn{whitespace} character. In the standard + @code{"C"} locale, @code{isspace} returns true for only the standard + whitespace characters: +@@ -161,6 +178,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isblank (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a blank character; that is, a space or a tab. + This function was originally a GNU extension, but was added in @w{ISO C99}. + @end deftypefun +@@ -169,6 +187,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isgraph (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a graphic character; that is, a character + that has a glyph associated with it. The whitespace characters are not + considered graphic. +@@ -178,6 +197,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int isprint (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a printing character. Printing characters + include all the graphic characters, plus the space (@samp{ }) character. + @end deftypefun +@@ -186,6 +206,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int iscntrl (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a control character (that is, a character that + is not a printing character). + @end deftypefun +@@ -194,6 +215,7 @@ + @comment ctype.h + @comment SVID, BSD + @deftypefun int isascii (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns true if @var{c} is a 7-bit @code{unsigned char} value that fits + into the US/UK ASCII character set. This function is a BSD extension + and is also an SVID extension. +@@ -227,6 +249,10 @@ + @comment ctype.h + @comment ISO + @deftypefun int tolower (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c The to* macros/functions call different functions that use different ++@c arrays than those of__ctype_b_loc, but the access patterns and ++@c thus safety guarantees are the same. + If @var{c} is an upper-case letter, @code{tolower} returns the corresponding + lower-case letter. If @var{c} is not an upper-case letter, + @var{c} is returned unchanged. +@@ -235,6 +261,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int toupper (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @var{c} is a lower-case letter, @code{toupper} returns the corresponding + upper-case letter. Otherwise @var{c} is returned unchanged. + @end deftypefun +@@ -242,6 +269,7 @@ + @comment ctype.h + @comment SVID, BSD + @deftypefun int toascii (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function converts @var{c} to a 7-bit @code{unsigned char} value + that fits into the US/UK ASCII character set, by clearing the high-order + bits. This function is a BSD extension and is also an SVID extension. +@@ -250,6 +278,7 @@ + @comment ctype.h + @comment SVID + @deftypefun int _tolower (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is identical to @code{tolower}, and is provided for compatibility + with the SVID. @xref{SVID}.@refill + @end deftypefun +@@ -257,6 +286,7 @@ + @comment ctype.h + @comment SVID + @deftypefun int _toupper (int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is identical to @code{toupper}, and is provided for compatibility + with the SVID. + @end deftypefun +@@ -303,6 +333,18 @@ + @comment wctype.h + @comment ISO + @deftypefun wctype_t wctype (const char *@var{property}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Although the source code of wctype contains multiple references to ++@c the locale, that could each reference different locale_data objects ++@c should the global locale object change while active, the compiler can ++@c and does combine them all into a single dereference that resolves ++@c once to the LCTYPE locale object used throughout the function, so it ++@c is safe in (optimized) practice, if not in theory, even when the ++@c locale changes. Ideally we'd explicitly save the resolved ++@c locale_data object to make it visibly safe instead of safe only under ++@c compiler optimizations, but given the decision that setlocale is ++@c MT-Unsafe, all this would afford us would be the ability to not mark ++@c this function with @mtslocale. + The @code{wctype} returns a value representing a class of wide + characters which is identified by the string @var{property}. Beside + some standard properties each locale can define its own ones. In case +@@ -331,6 +373,8 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswctype (wint_t @var{wc}, wctype_t @var{desc}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c The compressed lookup table returned by wctype is read-only. + This function returns a nonzero value if @var{wc} is in the character + class specified by @var{desc}. @var{desc} must previously be returned + by a successful call to @code{wctype}. +@@ -350,6 +394,16 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswalnum (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c The implicit wctype call in the isw* functions is actually an ++@c optimized version because the category has a known offset, but the ++@c wctype is equally safe when optimized, unsafe with changing locales ++@c if not optimized (thus @mtslocale). Since it's not a macro, we ++@c always optimize, and the locale can't change in any MT-Safe way, it's ++@c fine. The test whether wc is ASCII to use the non-wide is* ++@c macro/function doesn't bring any other safety issues: the test does ++@c not depend on the locale, and each path after the decision resolves ++@c the locale object only once. + This function returns a nonzero value if @var{wc} is an alphanumeric + character (a letter or number); in other words, if either @code{iswalpha} + or @code{iswdigit} is true of a character, then @code{iswalnum} is also +@@ -370,6 +424,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswalpha (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is an alphabetic character (a letter). If + @code{iswlower} or @code{iswupper} is true of a character, then + @code{iswalpha} is also true. +@@ -394,6 +449,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswcntrl (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a control character (that is, a character that + is not a printing character). + +@@ -412,6 +468,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswdigit (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a digit (e.g., @samp{0} through @samp{9}). + Please note that this function does not only return a nonzero value for + @emph{decimal} digits, but for all kinds of digits. A consequence is +@@ -442,6 +499,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswgraph (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a graphic character; that is, a character + that has a glyph associated with it. The whitespace characters are not + considered graphic. +@@ -461,6 +519,7 @@ + @comment ctype.h + @comment ISO + @deftypefun int iswlower (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a lower-case letter. The letter need not be + from the Latin alphabet, any alphabet representable is valid. + +@@ -479,6 +538,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswprint (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a printing character. Printing characters + include all the graphic characters, plus the space (@samp{ }) character. + +@@ -497,6 +557,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswpunct (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a punctuation character. + This means any printing character that is not alphanumeric or a space + character. +@@ -516,6 +577,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswspace (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a @dfn{whitespace} character. In the standard + @code{"C"} locale, @code{iswspace} returns true for only the standard + whitespace characters: +@@ -555,6 +617,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswupper (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is an upper-case letter. The letter need not be + from the Latin alphabet, any alphabet representable is valid. + +@@ -573,6 +636,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswxdigit (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a hexadecimal digit. + Hexadecimal digits include the normal decimal digits @samp{0} through + @samp{9} and the letters @samp{A} through @samp{F} and +@@ -597,6 +661,7 @@ + @comment wctype.h + @comment ISO + @deftypefun int iswblank (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + Returns true if @var{wc} is a blank character; that is, a space or a tab. + This function was originally a GNU extension, but was added in @w{ISO C99}. + It is declared in @file{wchar.h}. +@@ -691,6 +756,8 @@ + @comment wctype.h + @comment ISO + @deftypefun wctrans_t wctrans (const char *@var{property}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Similar implementation, same caveats as wctype. + The @code{wctrans} function has to be used to find out whether a named + mapping is defined in the current locale selected for the + @code{LC_CTYPE} category. If the returned value is non-zero, you can use +@@ -713,6 +780,8 @@ + @comment wctype.h + @comment ISO + @deftypefun wint_t towctrans (wint_t @var{wc}, wctrans_t @var{desc}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Same caveats as iswctype. + @code{towctrans} maps the input character @var{wc} + according to the rules of the mapping for which @var{desc} is a + descriptor, and returns the value it finds. @var{desc} must be +@@ -730,6 +799,9 @@ + @comment wctype.h + @comment ISO + @deftypefun wint_t towlower (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Same caveats as iswalnum, just using a wctrans rather than a wctype ++@c table. + If @var{wc} is an upper-case letter, @code{towlower} returns the corresponding + lower-case letter. If @var{wc} is not an upper-case letter, + @var{wc} is returned unchanged. +@@ -749,6 +821,7 @@ + @comment wctype.h + @comment ISO + @deftypefun wint_t towupper (wint_t @var{wc}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + If @var{wc} is a lower-case letter, @code{towupper} returns the corresponding + upper-case letter. Otherwise @var{wc} is returned unchanged. + +diff -urN glibc-2.17-c758a686/manual/debug.texi glibc-2.17-c758a686/manual/debug.texi +--- glibc-2.17-c758a686/manual/debug.texi 2014-09-12 16:08:17.824070745 -0400 ++++ glibc-2.17-c758a686/manual/debug.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -1,5 +1,5 @@ + @node Debugging Support +-@c @node Debugging Support, Internal Probes, Cryptographic Functions, Top ++@c @node Debugging Support, POSIX Threads, Cryptographic Functions, Top + @c %MENU% Functions to help debugging applications + @chapter Debugging support + +@@ -36,6 +36,16 @@ + @comment execinfo.h + @comment GNU + @deftypefun int backtrace (void **@var{buffer}, int @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{} @ascuheap{} @ascudlopen{} @ascuplugin{} @asulock{}}@acunsafe{@acuinit{} @acsmem{} @aculock{} @acsfd{}}} ++@c The generic implementation just does pointer chasing within the local ++@c stack, without any guarantees that this will handle signal frames ++@c correctly, so it's AS-Unsafe to begin with. However, most (all?) ++@c arches defer to libgcc_s's _Unwind_* implementation, dlopening ++@c libgcc_s.so to that end except in a static version of libc. ++@c libgcc_s's implementation may in turn defer to libunwind. We can't ++@c assume those implementations are AS- or AC-safe, but even if we ++@c could, our own initialization path isn't, and libgcc's implementation ++@c calls malloc and performs internal locking, so... + The @code{backtrace} function obtains a backtrace for the current + thread, as a list of pointers, and places the information into + @var{buffer}. The argument @var{size} should be the number of +@@ -56,6 +66,17 @@ + @comment execinfo.h + @comment GNU + @deftypefun {char **} backtrace_symbols (void *const *@var{buffer}, int @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @aculock{}}} ++@c Collects info returned by _dl_addr in an auto array, allocates memory ++@c for the whole return buffer with malloc then sprintfs into it storing ++@c pointers to the strings into the array entries in the buffer. ++@c _dl_addr takes the recursive dl_load_lock then calls ++@c _dl_find_dso_for_object and determine_info. ++@c _dl_find_dso_for_object calls _dl-addr_inside_object. ++@c All of them are safe as long as the lock is held. ++@c @asucorrupt? It doesn't look like the dynamic loader's data ++@c structures could be in an inconsistent state that would cause ++@c malfunction here. + The @code{backtrace_symbols} function translates the information + obtained from the @code{backtrace} function into an array of strings. + The argument @var{buffer} should be a pointer to an array of addresses +@@ -88,6 +109,11 @@ + @comment execinfo.h + @comment GNU + @deftypefun void backtrace_symbols_fd (void *const *@var{buffer}, int @var{size}, int @var{fd}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} ++@c Single loop of _dl_addr over addresses, collecting info into an iovec ++@c written out with a writev call per iteration. Addresses and offsets ++@c are converted to hex in auto buffers, so the only potential issue ++@c here is leaking the dl lock in case of cancellation. + The @code{backtrace_symbols_fd} function performs the same translation + as the function @code{backtrace_symbols} function. Instead of returning + the strings to the caller, it writes the strings to the file descriptor +diff -urN glibc-2.17-c758a686/manual/errno.texi glibc-2.17-c758a686/manual/errno.texi +--- glibc-2.17-c758a686/manual/errno.texi 2014-09-12 16:08:17.752070930 -0400 ++++ glibc-2.17-c758a686/manual/errno.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -1293,6 +1293,9 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strerror (int @var{errnum}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:strerror}}@asunsafe{@ascuheap{} @ascuintl{}}@acunsafe{@acsmem{}}} ++@c Calls strerror_r with a static buffer allocated with malloc on the ++@c first use. + The @code{strerror} function maps the error code (@pxref{Checking for + Errors}) specified by the @var{errnum} argument to a descriptive error + message string. The return value is a pointer to this string. +@@ -1310,10 +1313,11 @@ + @comment string.h + @comment GNU + @deftypefun {char *} strerror_r (int @var{errnum}, char *@var{buf}, size_t @var{n}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuintl{}}@acunsafe{}} + The @code{strerror_r} function works like @code{strerror} but instead of + returning the error message in a statically allocated buffer shared by + all threads in the process, it returns a private copy for the +-thread. This might be either some permanent global data or a message ++thread. This might be either some permanent global data or a message + string in the user supplied buffer starting at @var{buf} with the + length of @var{n} bytes. + +@@ -1331,6 +1335,10 @@ + @comment stdio.h + @comment ISO + @deftypefun void perror (const char *@var{message}) ++@safety{@prelim{}@mtsafe{@mtasurace{:stderr}}@asunsafe{@asucorrupt{} @ascuintl{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c Besides strerror_r's and some of fprintf's issues, if stderr is not ++@c oriented yet, create a new stream with a dup of stderr's fd and write ++@c to that instead of stderr, to avoid orienting it. + This function prints an error message to the stream @code{stderr}; + see @ref{Standard Streams}. The orientation of @code{stderr} is not + changed. +@@ -1442,6 +1450,13 @@ + @comment error.h + @comment GNU + @deftypefun void error (int @var{status}, int @var{errnum}, const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @asuheap{} @asuintl{}}@acsafe{}} ++@c Cancellation is disabled throughout the execution. It flushes stdout ++@c and then holds a lock on stderr while printing the program name and ++@c then running error_tail. The non-wide case just runs vfprintf; the ++@c wide case converts the message to an alloca/malloc-allocated buffer ++@c with mbsrtowcs, then prints it with vfwprintf. Afterwards, ++@c print_errno_message calls strerror_r and fxprintf. + The @code{error} function can be used to report general problems during + program execution. The @var{format} argument is a format string just + like those given to the @code{printf} family of functions. The +@@ -1477,6 +1492,15 @@ + @comment error.h + @comment GNU + @deftypefun void error_at_line (int @var{status}, int @var{errnum}, const char *@var{fname}, unsigned int @var{lineno}, const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:error_at_line/error_one_per_line} @mtslocale{}}@asunsafe{@asucorrupt{} @asuheap{} @asuintl{}}@acunsafe{@acucorrupt{/error_one_per_line}}} ++@c The error_one_per_line variable is accessed (without any form of ++@c synchronization, but since it's an int used once, it should be safe ++@c enough) and, if this mode is enabled, static variables used to hold ++@c the last printed file name and line number are accessed and modified ++@c without synchronization; the update is not atomic and it occurs ++@c before disabling cancellation, so it can be interrupted after only ++@c one of the two variables is modified. After that, it's very much ++@c like error. + + The @code{error_at_line} function is very similar to the @code{error} + function. The only difference are the additional parameters @var{fname} +@@ -1508,7 +1532,7 @@ + + @comment error.h + @comment GNU +-@deftypevar {void (*) error_print_progname } (void) ++@deftypevar {void (*error_print_progname)} (void) + If the @code{error_print_progname} variable is defined to a non-zero + value the function pointed to is called by @code{error} or + @code{error_at_line}. It is expected to print the program name or do +@@ -1582,6 +1606,8 @@ + @comment err.h + @comment BSD + @deftypefun void warn (const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Just calls vwarn with the va_list. + The @code{warn} function is roughly equivalent to a call like + @smallexample + error (0, errno, format, @r{the parameters}) +@@ -1594,14 +1620,21 @@ + @comment err.h + @comment BSD + @deftypefun void vwarn (const char *@var{format}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c While holding stderr's recursive lock, it prints the programname, the ++@c given message, and the error string with fw?printf's %m. When the ++@c stream is wide, convert_and_print converts the format string to an ++@c alloca/malloc-created buffer using mbsrtowcs and then calls fwprintf. + The @code{vwarn} function is just like @code{warn} except that the + parameters for the handling of the format string @var{format} are passed +-in as an value of type @code{va_list}. ++in as a value of type @code{va_list}. + @end deftypefun + + @comment err.h + @comment BSD + @deftypefun void warnx (const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Same as warn, but without the strerror translation issues. + The @code{warnx} function is roughly equivalent to a call like + @smallexample + error (0, 0, format, @r{the parameters}) +@@ -1615,14 +1648,18 @@ + @comment err.h + @comment BSD + @deftypefun void vwarnx (const char *@var{format}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Same as vwarn, but without the strerror translation issues. + The @code{vwarnx} function is just like @code{warnx} except that the + parameters for the handling of the format string @var{format} are passed +-in as an value of type @code{va_list}. ++in as a value of type @code{va_list}. + @end deftypefun + + @comment err.h + @comment BSD + @deftypefun void err (int @var{status}, const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Same as warn followed by exit. + The @code{err} function is roughly equivalent to a call like + @smallexample + error (status, errno, format, @r{the parameters}) +@@ -1635,14 +1672,18 @@ + @comment err.h + @comment BSD + @deftypefun void verr (int @var{status}, const char *@var{format}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascuintl{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Same as vwarn followed by exit. + The @code{verr} function is just like @code{err} except that the + parameters for the handling of the format string @var{format} are passed +-in as an value of type @code{va_list}. ++in as a value of type @code{va_list}. + @end deftypefun + + @comment err.h + @comment BSD + @deftypefun void errx (int @var{status}, const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Same as warnx followed by exit. + The @code{errx} function is roughly equivalent to a call like + @smallexample + error (status, 0, format, @r{the parameters}) +@@ -1657,7 +1698,9 @@ + @comment err.h + @comment BSD + @deftypefun void verrx (int @var{status}, const char *@var{format}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c Same as vwarnx followed by exit. + The @code{verrx} function is just like @code{errx} except that the + parameters for the handling of the format string @var{format} are passed +-in as an value of type @code{va_list}. ++in as a value of type @code{va_list}. + @end deftypefun +diff -urN glibc-2.17-c758a686/manual/examples/add.c glibc-2.17-c758a686/manual/examples/add.c +--- glibc-2.17-c758a686/manual/examples/add.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/add.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Example of a Variadic Function +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/argp-ex1.c glibc-2.17-c758a686/manual/examples/argp-ex1.c +--- glibc-2.17-c758a686/manual/examples/argp-ex1.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/argp-ex1.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Argp example #1 -- a minimal program using argp +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/argp-ex2.c glibc-2.17-c758a686/manual/examples/argp-ex2.c +--- glibc-2.17-c758a686/manual/examples/argp-ex2.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/argp-ex2.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Argp example #2 -- a pretty minimal program using argp +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/argp-ex3.c glibc-2.17-c758a686/manual/examples/argp-ex3.c +--- glibc-2.17-c758a686/manual/examples/argp-ex3.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/argp-ex3.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Argp example #3 -- a program with options and arguments using argp +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/argp-ex4.c glibc-2.17-c758a686/manual/examples/argp-ex4.c +--- glibc-2.17-c758a686/manual/examples/argp-ex4.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/argp-ex4.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Argp example #4 -- a program with somewhat more complicated options +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/atexit.c glibc-2.17-c758a686/manual/examples/atexit.c +--- glibc-2.17-c758a686/manual/examples/atexit.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/atexit.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Cleanups on Exit +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/db.c glibc-2.17-c758a686/manual/examples/db.c +--- glibc-2.17-c758a686/manual/examples/db.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/db.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* User and Group Database Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/dir2.c glibc-2.17-c758a686/manual/examples/dir2.c +--- glibc-2.17-c758a686/manual/examples/dir2.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/dir2.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Simple Program to List a Directory, Mark II +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/dir.c glibc-2.17-c758a686/manual/examples/dir.c +--- glibc-2.17-c758a686/manual/examples/dir.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/dir.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Simple Program to List a Directory +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/execinfo.c glibc-2.17-c758a686/manual/examples/execinfo.c +--- glibc-2.17-c758a686/manual/examples/execinfo.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/execinfo.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Obtain a backtrace and print it. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/filecli.c glibc-2.17-c758a686/manual/examples/filecli.c +--- glibc-2.17-c758a686/manual/examples/filecli.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/filecli.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Example of Reading Datagrams +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/filesrv.c glibc-2.17-c758a686/manual/examples/filesrv.c +--- glibc-2.17-c758a686/manual/examples/filesrv.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/filesrv.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Datagram Socket Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/fmtmsgexpl.c glibc-2.17-c758a686/manual/examples/fmtmsgexpl.c +--- glibc-2.17-c758a686/manual/examples/fmtmsgexpl.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/fmtmsgexpl.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* How to use fmtmsg and addseverity. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/genpass.c glibc-2.17-c758a686/manual/examples/genpass.c +--- glibc-2.17-c758a686/manual/examples/genpass.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/genpass.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Encrypting Passwords +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/inetcli.c glibc-2.17-c758a686/manual/examples/inetcli.c +--- glibc-2.17-c758a686/manual/examples/inetcli.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/inetcli.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Byte Stream Socket Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/inetsrv.c glibc-2.17-c758a686/manual/examples/inetsrv.c +--- glibc-2.17-c758a686/manual/examples/inetsrv.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/inetsrv.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Byte Stream Connection Server Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/isockad.c glibc-2.17-c758a686/manual/examples/isockad.c +--- glibc-2.17-c758a686/manual/examples/isockad.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/isockad.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Internet Socket Example using sockaddr_in. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/longopt.c glibc-2.17-c758a686/manual/examples/longopt.c +--- glibc-2.17-c758a686/manual/examples/longopt.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/longopt.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Example of Parsing Long Options with getopt_long. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/memopen.c glibc-2.17-c758a686/manual/examples/memopen.c +--- glibc-2.17-c758a686/manual/examples/memopen.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/memopen.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* String Streams +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/memstrm.c glibc-2.17-c758a686/manual/examples/memstrm.c +--- glibc-2.17-c758a686/manual/examples/memstrm.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/memstrm.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* open_memstream example. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/mkfsock.c glibc-2.17-c758a686/manual/examples/mkfsock.c +--- glibc-2.17-c758a686/manual/examples/mkfsock.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/mkfsock.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Example of Local-Namespace Sockets +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +@@ -45,13 +45,12 @@ + + /* The size of the address is + the offset of the start of the filename, +- plus its length, +- plus one for the terminating null byte. ++ plus its length (not including the terminating null byte). + Alternatively you can just do: + size = SUN_LEN (&name); + */ + size = (offsetof (struct sockaddr_un, sun_path) +- + strlen (name.sun_path) + 1); ++ + strlen (name.sun_path)); + + if (bind (sock, (struct sockaddr *) &name, size) < 0) + { +diff -urN glibc-2.17-c758a686/manual/examples/mkisock.c glibc-2.17-c758a686/manual/examples/mkisock.c +--- glibc-2.17-c758a686/manual/examples/mkisock.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/mkisock.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Internet Socket Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/mygetpass.c glibc-2.17-c758a686/manual/examples/mygetpass.c +--- glibc-2.17-c758a686/manual/examples/mygetpass.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/mygetpass.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Reading Passwords +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/pipe.c glibc-2.17-c758a686/manual/examples/pipe.c +--- glibc-2.17-c758a686/manual/examples/pipe.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/pipe.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Creating a Pipe +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/popen.c glibc-2.17-c758a686/manual/examples/popen.c +--- glibc-2.17-c758a686/manual/examples/popen.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/popen.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Pipe to a Subprocess +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/rprintf.c glibc-2.17-c758a686/manual/examples/rprintf.c +--- glibc-2.17-c758a686/manual/examples/rprintf.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/rprintf.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Printf Extension Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/search.c glibc-2.17-c758a686/manual/examples/search.c +--- glibc-2.17-c758a686/manual/examples/search.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/search.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Searching and Sorting Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/select.c glibc-2.17-c758a686/manual/examples/select.c +--- glibc-2.17-c758a686/manual/examples/select.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/select.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Waiting for Input or Output +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/setjmp.c glibc-2.17-c758a686/manual/examples/setjmp.c +--- glibc-2.17-c758a686/manual/examples/setjmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/setjmp.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Introduction to Non-Local Exits +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/sigh1.c glibc-2.17-c758a686/manual/examples/sigh1.c +--- glibc-2.17-c758a686/manual/examples/sigh1.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/sigh1.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Signal Handlers that Return +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/sigusr.c glibc-2.17-c758a686/manual/examples/sigusr.c +--- glibc-2.17-c758a686/manual/examples/sigusr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/sigusr.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Using kill for Communication +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/stpcpy.c glibc-2.17-c758a686/manual/examples/stpcpy.c +--- glibc-2.17-c758a686/manual/examples/stpcpy.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/stpcpy.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* stpcpy example. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/strdupa.c glibc-2.17-c758a686/manual/examples/strdupa.c +--- glibc-2.17-c758a686/manual/examples/strdupa.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/strdupa.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* strdupa example. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/strftim.c glibc-2.17-c758a686/manual/examples/strftim.c +--- glibc-2.17-c758a686/manual/examples/strftim.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/strftim.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Time Functions Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/strncat.c glibc-2.17-c758a686/manual/examples/strncat.c +--- glibc-2.17-c758a686/manual/examples/strncat.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/strncat.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* strncat example. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/subopt.c glibc-2.17-c758a686/manual/examples/subopt.c +--- glibc-2.17-c758a686/manual/examples/subopt.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/subopt.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Parsing of Suboptions Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/swapcontext.c glibc-2.17-c758a686/manual/examples/swapcontext.c +--- glibc-2.17-c758a686/manual/examples/swapcontext.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/swapcontext.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Complete Context Control +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/termios.c glibc-2.17-c758a686/manual/examples/termios.c +--- glibc-2.17-c758a686/manual/examples/termios.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/termios.c 2014-09-12 16:10:06.046792714 -0400 +@@ -1,5 +1,5 @@ + /* Noncanonical Mode Example +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/testopt.c glibc-2.17-c758a686/manual/examples/testopt.c +--- glibc-2.17-c758a686/manual/examples/testopt.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/testopt.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Example of Parsing Arguments with getopt. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/testpass.c glibc-2.17-c758a686/manual/examples/testpass.c +--- glibc-2.17-c758a686/manual/examples/testpass.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/testpass.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* Verify a password. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/examples/timeval_subtract.c glibc-2.17-c758a686/manual/examples/timeval_subtract.c +--- glibc-2.17-c758a686/manual/examples/timeval_subtract.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/examples/timeval_subtract.c 2014-09-12 16:10:06.047792712 -0400 +@@ -1,5 +1,5 @@ + /* struct timeval subtraction. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License +diff -urN glibc-2.17-c758a686/manual/filesys.texi glibc-2.17-c758a686/manual/filesys.texi +--- glibc-2.17-c758a686/manual/filesys.texi 2014-09-12 16:08:17.966070381 -0400 ++++ glibc-2.17-c758a686/manual/filesys.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -58,6 +58,25 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {char *} getcwd (char *@var{buffer}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c If buffer is NULL, this function calls malloc and realloc, and, in ++@c case of error, free. Linux offers a getcwd syscall that we use on ++@c GNU/Linux systems, but it may fail if the pathname is too long. As a ++@c fallback, and on other systems, the generic implementation opens each ++@c parent directory with opendir, which allocates memory for the ++@c directory stream with malloc. If a fstatat64 syscall is not ++@c available, very deep directory trees may also have to malloc to build ++@c longer sequences of ../../../... than those supported by a global ++@c const read-only string. ++ ++@c linux/__getcwd ++@c posix/__getcwd ++@c malloc/realloc/free if buffer is NULL, or if dir is too deep ++@c lstat64 -> see its own entry ++@c fstatat64 ++@c direct syscall if possible, alloca+snprintf+*stat64 otherwise ++@c openat64_not_cancel_3, close_not_cancel_no_status ++@c __fdopendir, __opendir, __readdir, rewinddir + The @code{getcwd} function returns an absolute file name representing + the current working directory, storing it in the character array + @var{buffer} that you provide. The @var{size} argument is how you tell +@@ -116,6 +135,9 @@ + @comment unistd.h + @comment BSD + @deftypefn {Deprecated Function} {char *} getwd (char *@var{buffer}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @ascuintl{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c Besides the getcwd safety issues, it calls strerror_r on error, which ++@c brings in all of the i18n issues. + This is similar to @code{getcwd}, but has no way to specify the size of + the buffer. @Theglibc{} provides @code{getwd} only + for backwards compatibility with BSD. +@@ -130,6 +152,9 @@ + @comment unistd.h + @comment GNU + @deftypefun {char *} get_current_dir_name (void) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c Besides getcwd, which this function calls as a fallback, it calls ++@c getenv, with the potential thread-safety issues that brings about. + @vindex PWD + This @code{get_current_dir_name} function is basically equivalent to + @w{@code{getcwd (NULL, 0)}}. The only difference is that the value of +@@ -145,6 +170,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int chdir (const char *@var{filename}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is used to set the process's working directory to + @var{filename}. + +@@ -158,6 +184,7 @@ + @comment unistd.h + @comment XPG + @deftypefun int fchdir (int @var{filedes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is used to set the process's working directory to + directory associated with the file descriptor @var{filedes}. + +@@ -294,12 +321,14 @@ + @comment dirent.h + @comment BSD + @deftypefun int IFTODT (mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This returns the @code{d_type} value corresponding to @var{mode}. + @end deftypefun + + @comment dirent.h + @comment BSD + @deftypefun mode_t DTTOIF (int @var{dtype}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This returns the @code{st_mode} value corresponding to @var{dtype}. + @end deftypefun + @end table +@@ -342,6 +371,9 @@ + @comment dirent.h + @comment POSIX.1 + @deftypefun {DIR *} opendir (const char *@var{dirname}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c Besides the safe syscall, we have to allocate the DIR object with ++@c __alloc_dir, that calls malloc. + The @code{opendir} function opens and returns a directory stream for + reading the directory whose file name is @var{dirname}. The stream has + type @code{DIR *}. +@@ -381,6 +413,8 @@ + @comment dirent.h + @comment GNU + @deftypefun {DIR *} fdopendir (int @var{fd}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c The DIR object is allocated with __alloc_dir, that calls malloc. + The @code{fdopendir} function works just like @code{opendir} but + instead of taking a file name and opening a file descriptor for the + directory the caller is required to provide a file descriptor. This +@@ -425,6 +459,7 @@ + @comment dirent.h + @comment GNU + @deftypefun int dirfd (DIR *@var{dirstream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{dirfd} returns the file descriptor associated with + the directory stream @var{dirstream}. This descriptor can be used until + the directory is closed with @code{closedir}. If the directory stream +@@ -443,6 +478,12 @@ + @comment dirent.h + @comment POSIX.1 + @deftypefun {struct dirent *} readdir (DIR *@var{dirstream}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:dirstream}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c This function holds dirstream's non-recursive lock, which brings ++@c about the usual issues with locks and async signals and cancellation, ++@c but the lock taking is not enough to make the returned value safe to ++@c use, since it points to a stream's internal buffer that can be ++@c overwritten by subsequent calls or even released by closedir. + This function reads the next entry from the directory. It normally + returns a pointer to a structure containing information about the + file. This structure is associated with the @var{dirstream} handle +@@ -478,6 +519,7 @@ + @comment dirent.h + @comment GNU + @deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + This function is a version of @code{readdir} which performs internal + locking. Like @code{readdir} it returns the next entry from the + directory. To prevent conflicts between simultaneously running +@@ -549,6 +591,7 @@ + @comment dirent.h + @comment LFS + @deftypefun {struct dirent64 *} readdir64 (DIR *@var{dirstream}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:dirstream}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + The @code{readdir64} function is just like the @code{readdir} function + except that it returns a pointer to a record of type @code{struct + dirent64}. Some of the members of this data type (notably @code{d_ino}) +@@ -560,6 +603,7 @@ + @comment dirent.h + @comment LFS + @deftypefun int readdir64_r (DIR *@var{dirstream}, struct dirent64 *@var{entry}, struct dirent64 **@var{result}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + The @code{readdir64_r} function is equivalent to the @code{readdir_r} + function except that it takes parameters of base type @code{struct + dirent64} instead of @code{struct dirent} in the second and third +@@ -570,6 +614,10 @@ + @comment dirent.h + @comment POSIX.1 + @deftypefun int closedir (DIR *@var{dirstream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{/hurd}}@acunsafe{@acsmem{} @acsfd{} @aculock{/hurd}}} ++@c No synchronization in the posix implementation, only in the hurd ++@c one. This is regarded as safe because it is undefined behavior if ++@c other threads could still be using the dir stream while it's closed. + This function closes the directory stream @var{dirstream}. It returns + @code{0} on success and @code{-1} on failure. + +@@ -609,6 +657,7 @@ + @comment dirent.h + @comment POSIX.1 + @deftypefun void rewinddir (DIR *@var{dirstream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + The @code{rewinddir} function is used to reinitialize the directory + stream @var{dirstream}, so that if you call @code{readdir} it + returns information about the first entry in the directory again. This +@@ -622,6 +671,10 @@ + @comment dirent.h + @comment BSD + @deftypefun {long int} telldir (DIR *@var{dirstream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd} @asulock{/bsd}}@acunsafe{@acsmem{/bsd} @aculock{/bsd}}} ++@c The implementation is safe on most platforms, but on BSD it uses ++@c cookies, buckets and records, and the global array of pointers to ++@c dynamically allocated records is guarded by a non-recursive lock. + The @code{telldir} function returns the file position of the directory + stream @var{dirstream}. You can use this value with @code{seekdir} to + restore the directory stream to that position. +@@ -630,6 +683,10 @@ + @comment dirent.h + @comment BSD + @deftypefun void seekdir (DIR *@var{dirstream}, long int @var{pos}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd} @asulock{/bsd}}@acunsafe{@acsmem{/bsd} @aculock{/bsd}}} ++@c The implementation is safe on most platforms, but on BSD it uses ++@c cookies, buckets and records, and the global array of pointers to ++@c dynamically allocated records is guarded by a non-recursive lock. + The @code{seekdir} function sets the file position of the directory + stream @var{dirstream} to @var{pos}. The value @var{pos} must be the + result of a previous call to @code{telldir} on this particular stream; +@@ -648,7 +705,20 @@ + + @comment dirent.h + @comment BSD/SVID +-@deftypefun int scandir (const char *@var{dir}, struct dirent ***@var{namelist}, int (*@var{selector}) (const struct dirent *), int (*@var{cmp}) (const void *, const void *)) ++@deftypefun int scandir (const char *@var{dir}, struct dirent ***@var{namelist}, int (*@var{selector}) (const struct dirent *), int (*@var{cmp}) (const struct dirent **, const struct dirent **)) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c The scandir function calls __opendirat, __readdir, and __closedir to ++@c go over the named dir; malloc and realloc to allocate the namelist ++@c and copies of each selected dirent, besides the selector, if given, ++@c and qsort and the cmp functions if the latter is given. In spite of ++@c the cleanup handler that releases memory and the file descriptor in ++@c case of synchronous cancellation, an asynchronous cancellation may ++@c still leak memory and a file descriptor. Although readdir is unsafe ++@c in general, the use of an internal dir stream for sequential scanning ++@c of the directory with copying of dirents before subsequent calls ++@c makes the use safe, and the fact that the dir stream is private to ++@c each scandir call does away with the lock issues in readdir and ++@c closedir. + + The @code{scandir} function scans the contents of the directory selected + by @var{dir}. The result in *@var{namelist} is an array of pointers to +@@ -678,7 +748,9 @@ + + @comment dirent.h + @comment BSD/SVID +-@deftypefun int alphasort (const void *@var{a}, const void *@var{b}) ++@deftypefun int alphasort (const struct dirent **@var{a}, const struct dirent **@var{b}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Calls strcoll. + The @code{alphasort} function behaves like the @code{strcoll} function + (@pxref{String/Array Comparison}). The difference is that the arguments + are not string pointers but instead they are of type +@@ -690,7 +762,10 @@ + + @comment dirent.h + @comment GNU +-@deftypefun int versionsort (const void *@var{a}, const void *@var{b}) ++@deftypefun int versionsort (const struct dirent **@var{a}, const struct dirent **@var{b}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Calls strverscmp, which will accesses the locale object multiple ++@c times. + The @code{versionsort} function is like @code{alphasort} except that it + uses the @code{strverscmp} function internally. + @end deftypefun +@@ -702,7 +777,9 @@ + + @comment dirent.h + @comment GNU +-@deftypefun int scandir64 (const char *@var{dir}, struct dirent64 ***@var{namelist}, int (*@var{selector}) (const struct dirent64 *), int (*@var{cmp}) (const void *, const void *)) ++@deftypefun int scandir64 (const char *@var{dir}, struct dirent64 ***@var{namelist}, int (*@var{selector}) (const struct dirent64 *), int (*@var{cmp}) (const struct dirent64 **, const struct dirent64 **)) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c See scandir. + The @code{scandir64} function works like the @code{scandir} function + except that the directory entries it returns are described by elements + of type @w{@code{struct dirent64}}. The function pointed to by +@@ -720,7 +797,9 @@ + + @comment dirent.h + @comment GNU +-@deftypefun int alphasort64 (const void *@var{a}, const void *@var{b}) ++@deftypefun int alphasort64 (const struct dirent64 **@var{a}, const struct dirent **@var{b}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c See alphasort. + The @code{alphasort64} function behaves like the @code{strcoll} function + (@pxref{String/Array Comparison}). The difference is that the arguments + are not string pointers but instead they are of type +@@ -732,7 +811,9 @@ + + @comment dirent.h + @comment GNU +-@deftypefun int versionsort64 (const void *@var{a}, const void *@var{b}) ++@deftypefun int versionsort64 (const struct dirent64 **@var{a}, const struct dirent64 **@var{b}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c See versionsort. + The @code{versionsort64} function is like @code{alphasort64}, excepted that it + uses the @code{strverscmp} function internally. + @end deftypefun +@@ -812,7 +893,7 @@ + file does not exist. The situation for @code{nftw} is different. + + This value is only available if the program is compiled with +-@code{_BSD_SOURCE} or @code{_XOPEN_EXTENDED} defined before including ++@code{_XOPEN_EXTENDED} defined before including + the first header. The original SVID systems do not have symbolic links. + @end vtable + +@@ -913,6 +994,8 @@ + @comment ftw.h + @comment SVID + @deftypefun int ftw (const char *@var{filename}, __ftw_func_t @var{func}, int @var{descriptors}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c see nftw for safety details + The @code{ftw} function calls the callback function given in the + parameter @var{func} for every item which is found in the directory + specified by @var{filename} and all directories below. The function +@@ -963,6 +1046,7 @@ + @comment ftw.h + @comment Unix98 + @deftypefun int ftw64 (const char *@var{filename}, __ftw64_func_t @var{func}, int @var{descriptors}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} + This function is similar to @code{ftw} but it can work on filesystems + with large files. File information is reported using a variable of type + @code{struct stat64} which is passed by reference to the callback +@@ -976,6 +1060,17 @@ + @comment ftw.h + @comment XPG4.2 + @deftypefun int nftw (const char *@var{filename}, __nftw_func_t @var{func}, int @var{descriptors}, int @var{flag}) ++@safety{@prelim{}@mtsafe{@mtasscwd{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{} @acscwd{}}} ++@c ftw_startup calls alloca, malloc, free, xstat/lxstat, tdestroy, and ftw_dir ++@c if FTW_CHDIR, call open, and fchdir, or chdir and getcwd ++@c ftw_dir calls open_dir_stream, readdir64, process_entry, closedir ++@c if FTW_CHDIR, also calls fchdir ++@c open_dir_stream calls malloc, realloc, readdir64, free, closedir, ++@c then openat64_not_cancel_3 and fdopendir or opendir, then dirfd. ++@c process_entry may cal realloc, fxstatat/lxstat/xstat, ftw_dir, and ++@c find_object (tsearch) and add_object (tfind). ++@c Since each invocation of *ftw uses its own private search tree, none ++@c of the search tree concurrency issues apply. + The @code{nftw} function works like the @code{ftw} functions. They call + the callback function @var{func} for all items found in the directory + @var{filename} and below. At most @var{descriptors} file descriptors +@@ -1036,6 +1131,7 @@ + @comment ftw.h + @comment Unix98 + @deftypefun int nftw64 (const char *@var{filename}, __nftw64_func_t @var{func}, int @var{descriptors}, int @var{flag}) ++@safety{@prelim{}@mtsafe{@mtasscwd{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{} @acscwd{}}} + This function is similar to @code{nftw} but it can work on filesystems + with large files. File information is reported using a variable of type + @code{struct stat64} which is passed by reference to the callback +@@ -1079,6 +1175,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int link (const char *@var{oldname}, const char *@var{newname}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{link} function makes a new link to the existing file named by + @var{oldname}, under the new name @var{newname}. + +@@ -1186,6 +1283,7 @@ + @comment unistd.h + @comment BSD + @deftypefun int symlink (const char *@var{oldname}, const char *@var{newname}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{symlink} function makes a symbolic link to @var{oldname} named + @var{newname}. + +@@ -1222,7 +1320,8 @@ + + @comment unistd.h + @comment BSD +-@deftypefun int readlink (const char *@var{filename}, char *@var{buffer}, size_t @var{size}) ++@deftypefun ssize_t readlink (const char *@var{filename}, char *@var{buffer}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{readlink} function gets the value of the symbolic link + @var{filename}. The file name that the link points to is copied into + @var{buffer}. This file name string is @emph{not} null-terminated; +@@ -1282,6 +1381,8 @@ + @comment stdlib.h + @comment GNU + @deftypefun {char *} canonicalize_file_name (const char *@var{name}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c Calls realpath. + + The @code{canonicalize_file_name} function returns the absolute name of + the file named by @var{name} which contains no @code{.}, @code{..} +@@ -1323,6 +1424,8 @@ + @comment stdlib.h + @comment XPG + @deftypefun {char *} realpath (const char *restrict @var{name}, char *restrict @var{resolved}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c Calls malloc, realloc, getcwd, lxstat64, readlink, alloca. + + A call to @code{realpath} where the @var{resolved} parameter is + @code{NULL} behaves exactly like @code{canonicalize_file_name}. The +@@ -1362,6 +1465,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int unlink (const char *@var{filename}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{unlink} function deletes the file name @var{filename}. If + this is a file's sole name, the file itself is also deleted. (Actually, + if any process has the file open when this happens, deletion is +@@ -1404,6 +1508,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int rmdir (const char *@var{filename}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @cindex directories, deleting + @cindex deleting a directory + The @code{rmdir} function deletes a directory. The directory must be +@@ -1431,6 +1536,8 @@ + @comment stdio.h + @comment ISO + @deftypefun int remove (const char *@var{filename}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Calls unlink and rmdir. + This is the @w{ISO C} function to remove a file. It works like + @code{unlink} for files and like @code{rmdir} for directories. + @code{remove} is declared in @file{stdio.h}. +@@ -1446,6 +1553,10 @@ + @comment stdio.h + @comment ISO + @deftypefun int rename (const char *@var{oldname}, const char *@var{newname}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c In the absence of a rename syscall, there's an emulation with link ++@c and unlink, but it's racy, even more so if newname exists and is ++@c unlinked first. + The @code{rename} function renames the file @var{oldname} to + @var{newname}. The file formerly accessible under the name + @var{oldname} is afterwards accessible as @var{newname} instead. (If +@@ -1541,6 +1652,7 @@ + @comment sys/stat.h + @comment POSIX.1 + @deftypefun int mkdir (const char *@var{filename}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{mkdir} function creates a new, empty directory with name + @var{filename}. + +@@ -1882,6 +1994,7 @@ + @comment sys/stat.h + @comment POSIX.1 + @deftypefun int stat (const char *@var{filename}, struct stat *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{stat} function returns information about the attributes of the + file named by @w{@var{filename}} in the structure pointed to by @var{buf}. + +@@ -1908,8 +2021,9 @@ + @comment sys/stat.h + @comment Unix98 + @deftypefun int stat64 (const char *@var{filename}, struct stat64 *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{stat} but it is also able to work on +-files larger then @math{2^31} bytes on 32-bit systems. To be able to do ++files larger than @math{2^31} bytes on 32-bit systems. To be able to do + this the result is stored in a variable of type @code{struct stat64} to + which @var{buf} must point. + +@@ -1921,6 +2035,7 @@ + @comment sys/stat.h + @comment POSIX.1 + @deftypefun int fstat (int @var{filedes}, struct stat *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fstat} function is like @code{stat}, except that it takes an + open file descriptor as an argument instead of a file name. + @xref{Low-Level I/O}. +@@ -1942,6 +2057,7 @@ + @comment sys/stat.h + @comment Unix98 + @deftypefun int fstat64 (int @var{filedes}, struct stat64 *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{fstat} but is able to work on large + files on 32-bit platforms. For large files the file descriptor + @var{filedes} should be obtained by @code{open64} or @code{creat64}. +@@ -1953,9 +2069,16 @@ + replaces the interface for small files on 32-bit machines. + @end deftypefun + ++@c fstatat will call alloca and snprintf if the syscall is not ++@c available. ++@c @safety{@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++ + @comment sys/stat.h + @comment BSD + @deftypefun int lstat (const char *@var{filename}, struct stat *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct system call through lxstat, sometimes with an xstat conv call ++@c afterwards. + The @code{lstat} function is like @code{stat}, except that it does not + follow symbolic links. If @var{filename} is the name of a symbolic + link, @code{lstat} returns information about the link itself; otherwise +@@ -1969,8 +2092,11 @@ + @comment sys/stat.h + @comment Unix98 + @deftypefun int lstat64 (const char *@var{filename}, struct stat64 *@var{buf}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct system call through lxstat64, sometimes with an xstat conv ++@c call afterwards. + This function is similar to @code{lstat} but it is also able to work on +-files larger then @math{2^31} bytes on 32-bit systems. To be able to do ++files larger than @math{2^31} bytes on 32-bit systems. To be able to do + this the result is stored in a variable of type @code{struct stat64} to + which @var{buf} must point. + +@@ -2007,12 +2133,14 @@ + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_ISDIR (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a directory. + @end deftypefn + + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_ISCHR (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a character special file (a + device like a terminal). + @end deftypefn +@@ -2020,6 +2148,7 @@ + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_ISBLK (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a block special file (a device + like a disk). + @end deftypefn +@@ -2027,12 +2156,14 @@ + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_ISREG (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a regular file. + @end deftypefn + + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_ISFIFO (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a FIFO special file, or a + pipe. @xref{Pipes and FIFOs}. + @end deftypefn +@@ -2040,6 +2171,7 @@ + @comment sys/stat.h + @comment GNU + @deftypefn Macro int S_ISLNK (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a symbolic link. + @xref{Symbolic Links}. + @end deftypefn +@@ -2047,6 +2179,7 @@ + @comment sys/stat.h + @comment GNU + @deftypefn Macro int S_ISSOCK (mode_t @var{m}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns non-zero if the file is a socket. @xref{Sockets}. + @end deftypefn + +@@ -2129,6 +2262,7 @@ + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_TYPEISMQ (struct stat *@var{s}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If the system implement POSIX message queues as distinct objects and the + file is a message queue object, this macro returns a non-zero value. + In all other cases the result is zero. +@@ -2137,6 +2271,7 @@ + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_TYPEISSEM (struct stat *@var{s}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If the system implement POSIX semaphores as distinct objects and the + file is a semaphore object, this macro returns a non-zero value. + In all other cases the result is zero. +@@ -2145,8 +2280,9 @@ + @comment sys/stat.h + @comment POSIX + @deftypefn Macro int S_TYPEISSHM (struct stat *@var{s}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If the system implement POSIX shared memory objects as distinct objects +-and the file is an shared memory object, this macro returns a non-zero ++and the file is a shared memory object, this macro returns a non-zero + value. In all other cases the result is zero. + @end deftypefn + +@@ -2189,6 +2325,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int chown (const char *@var{filename}, uid_t @var{owner}, gid_t @var{group}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{chown} function changes the owner of the file @var{filename} to + @var{owner}, and its group owner to @var{group}. + +@@ -2222,7 +2359,8 @@ + + @comment unistd.h + @comment BSD +-@deftypefun int fchown (int @var{filedes}, int @var{owner}, int @var{group}) ++@deftypefun int fchown (int @var{filedes}, uid_t @var{owner}, gid_t @var{group}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is like @code{chown}, except that it changes the owner of the open + file with descriptor @var{filedes}. + +@@ -2502,6 +2641,7 @@ + @comment sys/stat.h + @comment POSIX.1 + @deftypefun mode_t umask (mode_t @var{mask}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{umask} function sets the file creation mask of the current + process to @var{mask}, and returns the previous value of the file + creation mask. +@@ -2527,6 +2667,7 @@ + @comment sys/stat.h + @comment GNU + @deftypefun mode_t getumask (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Return the current value of the file creation mask for the current + process. This function is a GNU extension and is only available on + @gnuhurdsystems{}. +@@ -2535,6 +2676,7 @@ + @comment sys/stat.h + @comment POSIX.1 + @deftypefun int chmod (const char *@var{filename}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{chmod} function sets the access permission bits for the file + named by @var{filename} to @var{mode}. + +@@ -2574,7 +2716,8 @@ + + @comment sys/stat.h + @comment BSD +-@deftypefun int fchmod (int @var{filedes}, int @var{mode}) ++@deftypefun int fchmod (int @var{filedes}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is like @code{chmod}, except that it changes the permissions of the + currently open file given by @var{filedes}. + +@@ -2645,6 +2788,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int access (const char *@var{filename}, int @var{how}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{access} function checks to see whether the file named by + @var{filename} can be accessed in the way specified by the @var{how} + argument. The @var{how} argument either can be the bitwise OR of the +@@ -2746,7 +2890,7 @@ + need to include the header file @file{utime.h} to use this facility. + @pindex utime.h + +-@comment time.h ++@comment utime.h + @comment POSIX.1 + @deftp {Data Type} {struct utimbuf} + The @code{utimbuf} structure is used with the @code{utime} function to +@@ -2762,9 +2906,12 @@ + @end table + @end deftp + +-@comment time.h ++@comment utime.h + @comment POSIX.1 + @deftypefun int utime (const char *@var{filename}, const struct utimbuf *@var{times}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c In the absence of a utime syscall, it non-atomically converts times ++@c to a struct timeval and calls utimes. + This function is used to modify the file times associated with the file + named @var{filename}. + +@@ -2815,7 +2962,11 @@ + + @comment sys/time.h + @comment BSD +-@deftypefun int utimes (const char *@var{filename}, struct timeval @var{tvp}@t{[2]}) ++@deftypefun int utimes (const char *@var{filename}, const struct timeval @var{tvp}@t{[2]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c In the absence of a utimes syscall, it non-atomically converts tvp ++@c to struct timespec array and issues a utimensat syscall, or to ++@c struct utimbuf and calls utime. + This function sets the file access and modification times of the file + @var{filename}. The new file access time is specified by + @code{@var{tvp}[0]}, and the new modification time by +@@ -2829,7 +2980,10 @@ + + @comment sys/time.h + @comment BSD +-@deftypefun int lutimes (const char *@var{filename}, struct timeval @var{tvp}@t{[2]}) ++@deftypefun int lutimes (const char *@var{filename}, const struct timeval @var{tvp}@t{[2]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Since there's no lutimes syscall, it non-atomically converts tvp ++@c to struct timespec array and issues a utimensat syscall. + This function is like @code{utimes}, except that it does not follow + symbolic links. If @var{filename} is the name of a symbolic link, + @code{lutimes} sets the file access and modification times of the +@@ -2845,7 +2999,11 @@ + + @comment sys/time.h + @comment BSD +-@deftypefun int futimes (int @var{fd}, struct timeval @var{tvp}@t{[2]}) ++@deftypefun int futimes (int @var{fd}, const struct timeval @var{tvp}@t{[2]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Since there's no futimes syscall, it non-atomically converts tvp ++@c to struct timespec array and issues a utimensat syscall, falling back ++@c to utimes on a /proc/self/fd symlink. + This function is like @code{utimes}, except that it takes an open file + descriptor as an argument instead of a file name. @xref{Low-Level + I/O}. This function comes from FreeBSD, and is not available on all +@@ -2900,6 +3058,8 @@ + @comment unistd.h + @comment X/Open + @deftypefun int truncate (const char *@var{filename}, off_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c In the absence of a truncate syscall, we use open and ftruncate. + + The @code{truncate} function changes the size of @var{filename} to + @var{length}. If @var{length} is shorter than the previous length, data +@@ -2944,6 +3104,8 @@ + @comment unistd.h + @comment Unix98 + @deftypefun int truncate64 (const char *@var{name}, off64_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c In the absence of a syscall, try truncate if length fits. + This function is similar to the @code{truncate} function. The + difference is that the @var{length} argument is 64 bits wide even on 32 + bits machines, which allows the handling of files with sizes up to +@@ -2957,6 +3119,7 @@ + @comment unistd.h + @comment POSIX + @deftypefun int ftruncate (int @var{fd}, off_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + This is like @code{truncate}, but it works on a file descriptor @var{fd} + for an opened file instead of a file name to identify the object. The +@@ -3021,6 +3184,8 @@ + @comment unistd.h + @comment Unix98 + @deftypefun int ftruncate64 (int @var{id}, off64_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c In the absence of a syscall, try ftruncate if length fits. + This function is similar to the @code{ftruncate} function. The + difference is that the @var{length} argument is 64 bits wide even on 32 + bits machines which allows the handling of files with sizes up to +@@ -3082,7 +3247,11 @@ + + @comment sys/stat.h + @comment BSD +-@deftypefun int mknod (const char *@var{filename}, int @var{mode}, int @var{dev}) ++@deftypefun int mknod (const char *@var{filename}, mode_t @var{mode}, dev_t @var{dev}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Instead of issuing the syscall directly, we go through xmknod. ++@c Although the internal xmknod takes a dev_t*, that could lead to ++@c @mtsrace races, it's passed a pointer to mknod's dev. + The @code{mknod} function makes a special file with name @var{filename}. + The @var{mode} specifies the mode of the file, and may include the various + special file bits, such as @code{S_IFCHR} (for a character special file) +@@ -3134,6 +3303,20 @@ + @comment stdio.h + @comment ISO + @deftypefun {FILE *} tmpfile (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}} ++@c The unsafety issues are those of fdopen, plus @acsfd because of the ++@c open. ++@c __path_search (internal buf, !dir, const pfx, !try_tmpdir) ok ++@c libc_secure_genenv only if try_tmpdir ++@c xstat64, strlen, strcmp, sprintf ++@c __gen_tempname (internal tmpl, __GT_FILE) ok ++@c strlen, memcmp, getpid, open/mkdir/lxstat64 ok ++@c HP_TIMING_NOW if available ok ++@c gettimeofday (!tz) first time, or every time if no HP_TIMING_NOW ok ++@c static value is used and modified without synchronization ok ++@c but the use is as a source of non-cryptographic randomness ++@c with retries in case of collision, so it should be safe ++@c unlink, fdopen + This function creates a temporary binary file for update mode, as if by + calling @code{fopen} with mode @code{"wb+"}. The file is deleted + automatically when it is closed or when the program terminates. (On +@@ -3150,9 +3333,10 @@ + @comment stdio.h + @comment Unix98 + @deftypefun {FILE *} tmpfile64 (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}} + This function is similar to @code{tmpfile}, but the stream it returns a + pointer to was opened using @code{tmpfile64}. Therefore this stream can +-be used for files larger then @math{2^31} bytes on 32-bit machines. ++be used for files larger than @math{2^31} bytes on 32-bit machines. + + Please note that the return type is still @code{FILE *}. There is no + special @code{FILE} type for the LFS interface. +@@ -3165,6 +3349,11 @@ + @comment stdio.h + @comment ISO + @deftypefun {char *} tmpnam (char *@var{result}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:tmpnam/!result}}@asunsafe{}@acsafe{}} ++@c The passed-in buffer should not be modified concurrently with the ++@c call. ++@c __path_search (static or passed-in buf, !dir, !pfx, !try_tmpdir) ok ++@c __gen_tempname (internal tmpl, __GT_NOCREATE) ok + This function constructs and returns a valid file name that does not + refer to any existing file. If the @var{result} argument is a null + pointer, the return value is a pointer to an internal static string, +@@ -3189,6 +3378,7 @@ + @comment stdio.h + @comment GNU + @deftypefun {char *} tmpnam_r (char *@var{result}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is nearly identical to the @code{tmpnam} function, except + that if @var{result} is a null pointer it returns a null pointer. + +@@ -3225,6 +3415,13 @@ + @comment stdio.h + @comment SVID + @deftypefun {char *} tempnam (const char *@var{dir}, const char *@var{prefix}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c There's no way (short of being setuid) to avoid getenv("TMPDIR"), ++@c even with a non-NULL dir. ++@c ++@c __path_search (internal buf, dir, pfx, try_tmpdir) unsafe getenv ++@c __gen_tempname (internal tmpl, __GT_NOCREATE) ok ++@c strdup + This function generates a unique temporary file name. If @var{prefix} + is not a null pointer, up to five characters of this string are used as + a prefix for the file name. The return value is a string newly +@@ -3288,6 +3485,8 @@ + @comment stdlib.h + @comment Unix + @deftypefun {char *} mktemp (char *@var{template}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c __gen_tempname (caller tmpl, __GT_NOCREATE) ok + The @code{mktemp} function generates a unique file name by modifying + @var{template} as described above. If successful, it returns + @var{template} as modified. If @code{mktemp} cannot find a unique file +@@ -3306,6 +3505,8 @@ + @comment stdlib.h + @comment BSD + @deftypefun int mkstemp (char *@var{template}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} ++@c __gen_tempname (caller tmpl, __GT_FILE) ok + The @code{mkstemp} function generates a unique file name just as + @code{mktemp} does, but it also opens the file for you with @code{open} + (@pxref{Opening and Closing Files}). If successful, it modifies +@@ -3328,6 +3529,8 @@ + @comment stdlib.h + @comment BSD + @deftypefun {char *} mkdtemp (char *@var{template}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c __gen_tempname (caller tmpl, __GT_DIR) ok + The @code{mkdtemp} function creates a directory with a unique name. If + it succeeds, it overwrites @var{template} with the name of the + directory, and returns @var{template}. As with @code{mktemp} and +@@ -3349,3 +3552,23 @@ + @xref{Creating Directories}. + + The @code{mkdtemp} function comes from OpenBSD. ++ ++@c FIXME these are undocumented: ++@c faccessat ++@c fchmodat ++@c fchownat ++@c futimesat ++@c fstatat (there's a commented-out safety assessment for this one) ++@c linkat ++@c mkdirat ++@c mkfifoat ++@c name_to_handle_at ++@c openat ++@c open_by_handle_at ++@c readlinkat ++@c renameat ++@c scandirat ++@c symlinkat ++@c unlinkat ++@c utimensat ++@c mknodat +diff -urN glibc-2.17-c758a686/manual/freemanuals.texi glibc-2.17-c758a686/manual/freemanuals.texi +--- glibc-2.17-c758a686/manual/freemanuals.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/freemanuals.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -1,4 +1,7 @@ +-@appendix Free Software Needs Free Documentation ++@c freemanuals.texi - blurb for free documentation. ++@c This file is intended to be included within another document, ++@c hence no sectioning command or @node. ++ + @cindex free documentation + + The biggest deficiency in the free software community today is not in +diff -urN glibc-2.17-c758a686/manual/getopt.texi glibc-2.17-c758a686/manual/getopt.texi +--- glibc-2.17-c758a686/manual/getopt.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/getopt.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -59,7 +59,29 @@ + + @comment unistd.h + @comment POSIX.2 +-@deftypefun int getopt (int @var{argc}, char **@var{argv}, const char *@var{options}) ++@deftypefun int getopt (int @var{argc}, char *const *@var{argv}, const char *@var{options}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c Swapping elements of passed-in argv may be partial in case of ++@c cancellation. Gettext brings about a whole lot of AS and AC safety ++@c issues. The getopt API involves returning values in the ++@c non-thread-specific optarg variable, which adds another thread-safety ++@c issue. Given print_errors, it may output errors to stderr, which may ++@c self-deadlock, leak locks, or encounter (in a signal handler) or ++@c leave (in case of cancellation) stderr in an inconsistent state. ++@c Various implicit, indirect uses of malloc, in uses of memstream and ++@c asprintf for error-printing, bring about the usual malloc issues. ++@c (The explicit use of malloc in a conditional situation in ++@c _getopt_initialize is never exercised in glibc.) ++@c ++@c _getopt_internal ++@c _getopt_internal_r ++@c gettext ++@c _getopt_initialize ++@c getenv ++@c malloc if USE_NONOPTION_FLAGS, never defined in libc ++@c open_memstream ++@c lockfile, unlockfile, __fxprintf -> stderr ++@c asprintf + The @code{getopt} function gets the next option argument from the + argument list specified by the @var{argv} and @var{argc} arguments. + Normally these values come directly from the arguments received by +@@ -225,6 +247,8 @@ + @comment getopt.h + @comment GNU + @deftypefun int getopt_long (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c Same issues as getopt. + Decode options from the vector @var{argv} (whose length is @var{argc}). + The argument @var{shortopts} describes the short options to accept, just as + it does in @code{getopt}. The argument @var{longopts} describes the long +@@ -278,6 +302,8 @@ + @comment getopt.h + @comment GNU + @deftypefun int getopt_long_only (int @var{argc}, char *const *@var{argv}, const char *@var{shortopts}, const struct option *@var{longopts}, int *@var{indexptr}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:getopt} @mtsenv{}}@asunsafe{@ascuheap{} @ascuintl{} @asulock{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c Same issues as getopt. + + The @code{getopt_long_only} function is equivalent to the + @code{getopt_long} function but it allows to specify the user of the +diff -urN glibc-2.17-c758a686/manual/install-plain.texi glibc-2.17-c758a686/manual/install-plain.texi +--- glibc-2.17-c758a686/manual/install-plain.texi 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/manual/install-plain.texi 2014-09-12 16:10:06.046792714 -0400 +@@ -0,0 +1,5 @@ ++@c This is for making the `INSTALL' file for the distribution. ++@c Makeinfo ignores it when processing the file from the include. ++@setfilename INSTALL ++@set plain ++@include install.texi +diff -urN glibc-2.17-c758a686/manual/install.texi glibc-2.17-c758a686/manual/install.texi +--- glibc-2.17-c758a686/manual/install.texi 2014-09-12 16:08:17.783070851 -0400 ++++ glibc-2.17-c758a686/manual/install.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -1,10 +1,10 @@ +-@c This is for making the `INSTALL' file for the distribution. +-@c Makeinfo ignores it when processing the file from the include. +-@setfilename INSTALL + @include macros.texi + @include pkgvers.texi + ++@ifclear plain + @node Installation, Maintenance, Library Summary, Top ++@end ifclear ++ + @c %MENU% How to install the GNU C Library + @appendix Installing @theglibc{} + +@@ -21,6 +21,7 @@ + You will need recent versions of several GNU tools: definitely GCC and + GNU Make, and possibly others. @xref{Tools for Compilation}, below. + ++@ifclear plain + @menu + * Configuring and compiling:: How to compile and test GNU libc. + * Running make install:: How to install it once you've got it +@@ -29,6 +30,7 @@ + * Linux:: Specific advice for GNU/Linux systems. + * Reporting Bugs:: So they'll get fixed. + @end menu ++@end ifclear + + @node Configuring and compiling + @appendixsec Configuring and compiling @theglibc{} +@@ -138,11 +140,6 @@ + Don't build libraries with profiling information. You may want to use + this option if you don't plan to do profiling. + +-@item --disable-versioning +-Don't compile the shared libraries with symbol version information. +-Doing this will make the resulting library incompatible with old +-binaries, so it's not recommended. +- + @item --enable-static-nss + Compile static versions of the NSS (Name Service Switch) libraries. + This is not recommended because it defeats the purpose of NSS; a program +@@ -155,6 +152,14 @@ + prevented though there generally is no reason since it creates + compatibility problems. + ++@item --enable-hardcoded-path-in-tests ++By default, dynamic tests are linked to run with the installed C library. ++This option hardcodes the newly built C library path in dynamic tests ++so that they can be invoked directly. ++ ++@item --enable-lock-elision=yes ++Enable lock elision for pthread mutexes by default. ++ + @pindex pt_chown + @findex grantpt + @item --enable-pt_chown +@@ -180,11 +185,11 @@ + + If you only specify @samp{--host}, @code{configure} will prepare for a + native compile but use what you specify instead of guessing what your +-system is. This is most useful to change the CPU submodel. For example, +-if @code{configure} guesses your machine as @code{i586-pc-linux-gnu} but +-you want to compile a library for 386es, give +-@samp{--host=i386-pc-linux-gnu} or just @samp{--host=i386-linux} and add +-the appropriate compiler flags (@samp{-mcpu=i386} will do the trick) to ++system is. This is most useful to change the CPU submodel. For example, ++if @code{configure} guesses your machine as @code{i686-pc-linux-gnu} but ++you want to compile a library for 586es, give ++@samp{--host=i586-pc-linux-gnu} or just @samp{--host=i586-linux} and add ++the appropriate compiler flags (@samp{-mcpu=i586} will do the trick) to + @var{CFLAGS}. + + If you specify just @samp{--build}, @code{configure} will get confused. +@@ -230,6 +235,12 @@ + system such as @file{/etc/passwd}, @file{/etc/nsswitch.conf} and others. + These files must all contain correct and sensible content. + ++Normally, @code{make check} will run all the tests before reporting ++all problems found and exiting with error status if any problems ++occurred. You can specify @samp{stop-on-test-failure=y} when running ++@code{make check} to make the test run stop and exit with an error ++status immediately when a failure occurs. ++ + To format the @cite{GNU C Library Reference Manual} for printing, type + @w{@code{make dvi}}. You need a working @TeX{} installation to do + this. The distribution builds the on-line formatted version of the +@@ -264,13 +275,15 @@ + In general, when testing @theglibc{}, @samp{test-wrapper} may be set + to the name and arguments of any program to run newly built binaries. + This program must preserve the arguments to the binary being run, its +-working directory, all environment variables set as part of testing +-and the standard input, output and error file descriptors. If ++working directory and the standard input, output and error file ++descriptors. If + @samp{@var{test-wrapper} env} will not work to run a program with + environment variables set, then @samp{test-wrapper-env} must be set to + a program that runs a newly built program with environment variable + assignments in effect, those assignments being specified as +-@samp{@var{var}=@var{value}} before the name of the program to be run. ++@samp{@var{var}=@var{value}} before the name of the program to be ++run. If multiple assignments to the same variable are specified, ++the last assignment specified must take precedence. + + + @node Running make install +@@ -278,7 +291,7 @@ + @cindex installing + + To install the library and its header files, and the Info files of the +-manual, type @code{env LANGUAGE=C LC_ALL=C make install}. This will ++manual, type @code{make install}. This will + build things, if necessary, before installing them; however, you should + still compile everything first. If you are installing @theglibc{} as your + primary C library, we recommend that you shut the system down to +@@ -317,14 +330,11 @@ + well. + + One auxiliary program, @file{/usr/libexec/pt_chown}, is installed setuid +-@code{root}. This program is invoked by the @code{grantpt} function; it +-sets the permissions on a pseudoterminal so it can be used by the +-calling process. This means programs like @code{xterm} and +-@code{screen} do not have to be setuid to get a pty. (There may be +-other reasons why they need privileges.) If you are using a +-Linux kernel with the @code{devptsfs} or @code{devfs} filesystems +-providing pty slaves, you don't need this program; otherwise you do. +-The source for @file{pt_chown} is in @file{login/programs/pt_chown.c}. ++@code{root} if the @samp{--enable-pt_chown} configuration option is used. ++This program is invoked by the @code{grantpt} function; it sets the ++permissions on a pseudoterminal so it can be used by the calling process. ++If you are using a Linux kernel with the @code{devpts} filesystem enabled ++and mounted at @file{/dev/pts}, you don't need this program. + + After installation you might want to configure the timezone and locale + installation of your system. @Theglibc{} comes with a locale +@@ -362,9 +372,9 @@ + bugs or lack features. + + @item +-GCC 4.3 or newer, GCC 4.6 recommended ++GCC 4.4 or newer, GCC 4.6 recommended + +-GCC 4.3 or higher is required; as of this writing, GCC 4.6 is the ++GCC 4.4 or higher is required; as of this writing, GCC 4.6 is the + compiler we advise to use to build @theglibc{}. + + You can use whatever compiler you like to compile programs that use +@@ -388,10 +398,11 @@ + mechanism for the info files is not present or works differently. + + @item +-GNU @code{awk} 3.0, or higher ++GNU @code{awk} 3.1.2, or higher + +-@code{Awk} is used in several places to generate files. +-@code{gawk} 3.0 is known to work. ++@code{awk} is used in several places to generate files. ++Some @code{gawk} extensions are used, including the @code{asorti} ++function, which was introduced in version 3.1.2 of @code{gawk}. + + @item + Perl 5 +@@ -412,7 +423,7 @@ + @end itemize + + @noindent +-If you change any of the @file{configure.in} files you will also need ++If you change any of the @file{configure.ac} files you will also need + + @itemize @bullet + @item +@@ -436,7 +447,7 @@ + @cindex kernel header files + + If you are installing @theglibc{} on @gnulinuxsystems{}, you need to have +-the header files from a 2.6.19.1 or newer kernel around for reference. ++the header files from a 2.6.32 or newer kernel around for reference. + These headers must be installed using @samp{make headers_install}; the + headers present in the kernel source directory are not suitable for + direct use by @theglibc{}. You do not need to use that kernel, just have +diff -urN glibc-2.17-c758a686/manual/intro.texi glibc-2.17-c758a686/manual/intro.texi +--- glibc-2.17-c758a686/manual/intro.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/intro.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -159,6 +159,14 @@ + These include utilities for dealing with regular expressions and other + pattern matching facilities (@pxref{Pattern Matching}). + ++@menu ++* POSIX Safety Concepts:: Safety concepts from POSIX. ++* Unsafe Features:: Features that make functions unsafe. ++* Conditionally Safe Features:: Features that make functions unsafe ++ in the absence of workarounds. ++* Other Safety Remarks:: Additional safety features and remarks. ++@end menu ++ + @comment Roland sez: + @comment The GNU C library as it stands conforms to 1003.2 draft 11, which + @comment specifies: +@@ -172,6 +180,725 @@ + @comment (not yet implemented) + @comment confstr + ++@node POSIX Safety Concepts, Unsafe Features, , POSIX ++@subsubsection POSIX Safety Concepts ++@cindex POSIX Safety Concepts ++ ++This manual documents various safety properties of @glibcadj{} ++functions, in lines that follow their prototypes and look like: ++ ++@sampsafety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++ ++The properties are assessed according to the criteria set forth in the ++POSIX standard for such safety contexts as Thread-, Async-Signal- and ++Async-Cancel- -Safety. Intuitive definitions of these properties, ++attempting to capture the meaning of the standard definitions, follow. ++ ++@itemize @bullet ++ ++@item ++@cindex MT-Safe ++@cindex Thread-Safe ++@code{MT-Safe} or Thread-Safe functions are safe to call in the presence ++of other threads. MT, in MT-Safe, stands for Multi Thread. ++ ++Being MT-Safe does not imply a function is atomic, nor that it uses any ++of the memory synchronization mechanisms POSIX exposes to users. It is ++even possible that calling MT-Safe functions in sequence does not yield ++an MT-Safe combination. For example, having a thread call two MT-Safe ++functions one right after the other does not guarantee behavior ++equivalent to atomic execution of a combination of both functions, since ++concurrent calls in other threads may interfere in a destructive way. ++ ++Whole-program optimizations that could inline functions across library ++interfaces may expose unsafe reordering, and so performing inlining ++across the @glibcadj{} interface is not recommended. The documented ++MT-Safety status is not guaranteed under whole-program optimization. ++However, functions defined in user-visible headers are designed to be ++safe for inlining. ++ ++ ++@item ++@cindex AS-Safe ++@cindex Async-Signal-Safe ++@code{AS-Safe} or Async-Signal-Safe functions are safe to call from ++asynchronous signal handlers. AS, in AS-Safe, stands for Asynchronous ++Signal. ++ ++Many functions that are AS-Safe may set @code{errno}, or modify the ++floating-point environment, because their doing so does not make them ++unsuitable for use in signal handlers. However, programs could ++misbehave should asynchronous signal handlers modify this thread-local ++state, and the signal handling machinery cannot be counted on to ++preserve it. Therefore, signal handlers that call functions that may ++set @code{errno} or modify the floating-point environment @emph{must} ++save their original values, and restore them before returning. ++ ++ ++@item ++@cindex AC-Safe ++@cindex Async-Cancel-Safe ++@code{AC-Safe} or Async-Cancel-Safe functions are safe to call when ++asynchronous cancellation is enabled. AC in AC-Safe stands for ++Asynchronous Cancellation. ++ ++The POSIX standard defines only three functions to be AC-Safe, namely ++@code{pthread_cancel}, @code{pthread_setcancelstate}, and ++@code{pthread_setcanceltype}. At present @theglibc{} provides no ++guarantees beyond these three functions, but does document which ++functions are presently AC-Safe. This documentation is provided for use ++by @theglibc{} developers. ++ ++Just like signal handlers, cancellation cleanup routines must configure ++the floating point environment they require. The routines cannot assume ++a floating point environment, particularly when asynchronous ++cancellation is enabled. If the configuration of the floating point ++environment cannot be performed atomically then it is also possible that ++the environment encountered is internally inconsistent. ++ ++ ++@item ++@cindex MT-Unsafe ++@cindex Thread-Unsafe ++@cindex AS-Unsafe ++@cindex Async-Signal-Unsafe ++@cindex AC-Unsafe ++@cindex Async-Cancel-Unsafe ++@code{MT-Unsafe}, @code{AS-Unsafe}, @code{AC-Unsafe} functions are not ++safe to call within the safety contexts described above. Calling them ++within such contexts invokes undefined behavior. ++ ++Functions not explicitly documented as safe in a safety context should ++be regarded as Unsafe. ++ ++ ++@item ++@cindex Preliminary ++@code{Preliminary} safety properties are documented, indicating these ++properties may @emph{not} be counted on in future releases of ++@theglibc{}. ++ ++Such preliminary properties are the result of an assessment of the ++properties of our current implementation, rather than of what is ++mandated and permitted by current and future standards. ++ ++Although we strive to abide by the standards, in some cases our ++implementation is safe even when the standard does not demand safety, ++and in other cases our implementation does not meet the standard safety ++requirements. The latter are most likely bugs; the former, when marked ++as @code{Preliminary}, should not be counted on: future standards may ++require changes that are not compatible with the additional safety ++properties afforded by the current implementation. ++ ++Furthermore, the POSIX standard does not offer a detailed definition of ++safety. We assume that, by ``safe to call'', POSIX means that, as long ++as the program does not invoke undefined behavior, the ``safe to call'' ++function behaves as specified, and does not cause other functions to ++deviate from their specified behavior. We have chosen to use its loose ++definitions of safety, not because they are the best definitions to use, ++but because choosing them harmonizes this manual with POSIX. ++ ++Please keep in mind that these are preliminary definitions and ++annotations, and certain aspects of the definitions are still under ++discussion and might be subject to clarification or change. ++ ++Over time, we envision evolving the preliminary safety notes into stable ++commitments, as stable as those of our interfaces. As we do, we will ++remove the @code{Preliminary} keyword from safety notes. As long as the ++keyword remains, however, they are not to be regarded as a promise of ++future behavior. ++ ++ ++@end itemize ++ ++Other keywords that appear in safety notes are defined in subsequent ++sections. ++ ++ ++@node Unsafe Features, Conditionally Safe Features, POSIX Safety Concepts, POSIX ++@subsubsection Unsafe Features ++@cindex Unsafe Features ++ ++Functions that are unsafe to call in certain contexts are annotated with ++keywords that document their features that make them unsafe to call. ++AS-Unsafe features in this section indicate the functions are never safe ++to call when asynchronous signals are enabled. AC-Unsafe features ++indicate they are never safe to call when asynchronous cancellation is ++enabled. There are no MT-Unsafe marks in this section. ++ ++@itemize @bullet ++ ++@item @code{lock} ++@cindex lock ++ ++Functions marked with @code{lock} as an AS-Unsafe feature may be ++interrupted by a signal while holding a non-recursive lock. If the ++signal handler calls another such function that takes the same lock, the ++result is a deadlock. ++ ++Functions annotated with @code{lock} as an AC-Unsafe feature may, if ++cancelled asynchronously, fail to release a lock that would have been ++released if their execution had not been interrupted by asynchronous ++thread cancellation. Once a lock is left taken, attempts to take that ++lock will block indefinitely. ++ ++ ++@item @code{corrupt} ++@cindex corrupt ++ ++Functions marked with @code{corrupt} as an AS-Unsafe feature may corrupt ++data structures and misbehave when they interrupt, or are interrupted ++by, another such function. Unlike functions marked with @code{lock}, ++these take recursive locks to avoid MT-Safety problems, but this is not ++enough to stop a signal handler from observing a partially-updated data ++structure. Further corruption may arise from the interrupted function's ++failure to notice updates made by signal handlers. ++ ++Functions marked with @code{corrupt} as an AC-Unsafe feature may leave ++data structures in a corrupt, partially updated state. Subsequent uses ++of the data structure may misbehave. ++ ++@c A special case, probably not worth documenting separately, involves ++@c reallocing, or even freeing pointers. Any case involving free could ++@c be easily turned into an ac-safe leak by resetting the pointer before ++@c releasing it; I don't think we have any case that calls for this sort ++@c of fixing. Fixing the realloc cases would require a new interface: ++@c instead of @code{ptr=realloc(ptr,size)} we'd have to introduce ++@c @code{acsafe_realloc(&ptr,size)} that would modify ptr before ++@c releasing the old memory. The ac-unsafe realloc could be implemented ++@c in terms of an internal interface with this semantics (say ++@c __acsafe_realloc), but since realloc can be overridden, the function ++@c we call to implement realloc should not be this internal interface, ++@c but another internal interface that calls __acsafe_realloc if realloc ++@c was not overridden, and calls the overridden realloc with async ++@c cancel disabled. --lxoliva ++ ++ ++@item @code{heap} ++@cindex heap ++ ++Functions marked with @code{heap} may call heap memory management ++functions from the @code{malloc}/@code{free} family of functions and are ++only as safe as those functions. This note is thus equivalent to: ++ ++@sampsafety{@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++ ++ ++@c Check for cases that should have used plugin instead of or in ++@c addition to this. Then, after rechecking gettext, adjust i18n if ++@c needed. ++@item @code{dlopen} ++@cindex dlopen ++ ++Functions marked with @code{dlopen} use the dynamic loader to load ++shared libraries into the current execution image. This involves ++opening files, mapping them into memory, allocating additional memory, ++resolving symbols, applying relocations and more, all of this while ++holding internal dynamic loader locks. ++ ++The locks are enough for these functions to be AS- and AC-Unsafe, but ++other issues may arise. At present this is a placeholder for all ++potential safety issues raised by @code{dlopen}. ++ ++@c dlopen runs init and fini sections of the module; does this mean ++@c dlopen always implies plugin? ++ ++ ++@item @code{plugin} ++@cindex plugin ++ ++Functions annotated with @code{plugin} may run code from plugins that ++may be external to @theglibc{}. Such plugin functions are assumed to be ++MT-Safe, AS-Unsafe and AC-Unsafe. Examples of such plugins are stack ++@cindex NSS ++unwinding libraries, name service switch (NSS) and character set ++@cindex iconv ++conversion (iconv) back-ends. ++ ++Although the plugins mentioned as examples are all brought in by means ++of dlopen, the @code{plugin} keyword does not imply any direct ++involvement of the dynamic loader or the @code{libdl} interfaces, those ++are covered by @code{dlopen}. For example, if one function loads a ++module and finds the addresses of some of its functions, while another ++just calls those already-resolved functions, the former will be marked ++with @code{dlopen}, whereas the latter will get the @code{plugin}. When ++a single function takes all of these actions, then it gets both marks. ++ ++ ++@item @code{i18n} ++@cindex i18n ++ ++Functions marked with @code{i18n} may call internationalization ++functions of the @code{gettext} family and will be only as safe as those ++functions. This note is thus equivalent to: ++ ++@sampsafety{@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @ascudlopen{}}@acunsafe{@acucorrupt{}}} ++ ++ ++@item @code{timer} ++@cindex timer ++ ++Functions marked with @code{timer} use the @code{alarm} function or ++similar to set a time-out for a system call or a long-running operation. ++In a multi-threaded program, there is a risk that the time-out signal ++will be delivered to a different thread, thus failing to interrupt the ++intended thread. Besides being MT-Unsafe, such functions are always ++AS-Unsafe, because calling them in signal handlers may interfere with ++timers set in the interrupted code, and AC-Unsafe, because there is no ++safe way to guarantee an earlier timer will be reset in case of ++asynchronous cancellation. ++ ++@end itemize ++ ++ ++@node Conditionally Safe Features, Other Safety Remarks, Unsafe Features, POSIX ++@subsubsection Conditionally Safe Features ++@cindex Conditionally Safe Features ++ ++For some features that make functions unsafe to call in certain ++contexts, there are known ways to avoid the safety problem other than ++refraining from calling the function altogether. The keywords that ++follow refer to such features, and each of their definitions indicate ++how the whole program needs to be constrained in order to remove the ++safety problem indicated by the keyword. Only when all the reasons that ++make a function unsafe are observed and addressed, by applying the ++documented constraints, does the function become safe to call in a ++context. ++ ++@itemize @bullet ++ ++@item @code{init} ++@cindex init ++ ++Functions marked with @code{init} as an MT-Unsafe feature perform ++MT-Unsafe initialization when they are first called. ++ ++Calling such a function at least once in single-threaded mode removes ++this specific cause for the function to be regarded as MT-Unsafe. If no ++other cause for that remains, the function can then be safely called ++after other threads are started. ++ ++Functions marked with @code{init} as an AS- or AC-Unsafe feature use the ++internal @code{libc_once} machinery or similar to initialize internal ++data structures. ++ ++If a signal handler interrupts such an initializer, and calls any ++function that also performs @code{libc_once} initialization, it will ++deadlock if the thread library has been loaded. ++ ++Furthermore, if an initializer is partially complete before it is ++canceled or interrupted by a signal whose handler requires the same ++initialization, some or all of the initialization may be performed more ++than once, leaking resources or even resulting in corrupt internal data. ++ ++Applications that need to call functions marked with @code{init} as an ++AS- or AC-Unsafe feature should ensure the initialization is performed ++before configuring signal handlers or enabling cancellation, so that the ++AS- and AC-Safety issues related with @code{libc_once} do not arise. ++ ++@c We may have to extend the annotations to cover conditions in which ++@c initialization may or may not occur, since an initial call in a safe ++@c context is no use if the initialization doesn't take place at that ++@c time: it doesn't remove the risk for later calls. ++ ++ ++@item @code{race} ++@cindex race ++ ++Functions annotated with @code{race} as an MT-Safety issue operate on ++objects in ways that may cause data races or similar forms of ++destructive interference out of concurrent execution. In some cases, ++the objects are passed to the functions by users; in others, they are ++used by the functions to return values to users; in others, they are not ++even exposed to users. ++ ++We consider access to objects passed as (indirect) arguments to ++functions to be data race free. The assurance of data race free objects ++is the caller's responsibility. We will not mark a function as ++MT-Unsafe or AS-Unsafe if it misbehaves when users fail to take the ++measures required by POSIX to avoid data races when dealing with such ++objects. As a general rule, if a function is documented as reading from ++an object passed (by reference) to it, or modifying it, users ought to ++use memory synchronization primitives to avoid data races just as they ++would should they perform the accesses themselves rather than by calling ++the library function. @code{FILE} streams are the exception to the ++general rule, in that POSIX mandates the library to guard against data ++races in many functions that manipulate objects of this specific opaque ++type. We regard this as a convenience provided to users, rather than as ++a general requirement whose expectations should extend to other types. ++ ++In order to remind users that guarding certain arguments is their ++responsibility, we will annotate functions that take objects of certain ++types as arguments. We draw the line for objects passed by users as ++follows: objects whose types are exposed to users, and that users are ++expected to access directly, such as memory buffers, strings, and ++various user-visible @code{struct} types, do @emph{not} give reason for ++functions to be annotated with @code{race}. It would be noisy and ++redundant with the general requirement, and not many would be surprised ++by the library's lack of internal guards when accessing objects that can ++be accessed directly by users. ++ ++As for objects that are opaque or opaque-like, in that they are to be ++manipulated only by passing them to library functions (e.g., ++@code{FILE}, @code{DIR}, @code{obstack}, @code{iconv_t}), there might be ++additional expectations as to internal coordination of access by the ++library. We will annotate, with @code{race} followed by a colon and the ++argument name, functions that take such objects but that do not take ++care of synchronizing access to them by default. For example, ++@code{FILE} stream @code{unlocked} functions will be annotated, but ++those that perform implicit locking on @code{FILE} streams by default ++will not, even though the implicit locking may be disabled on a ++per-stream basis. ++ ++In either case, we will not regard as MT-Unsafe functions that may ++access user-supplied objects in unsafe ways should users fail to ensure ++the accesses are well defined. The notion prevails that users are ++expected to safeguard against data races any user-supplied objects that ++the library accesses on their behalf. ++ ++@c The above describes @mtsrace; @mtasurace is described below. ++ ++This user responsibility does not apply, however, to objects controlled ++by the library itself, such as internal objects and static buffers used ++to return values from certain calls. When the library doesn't guard ++them against concurrent uses, these cases are regarded as MT-Unsafe and ++AS-Unsafe (although the @code{race} mark under AS-Unsafe will be omitted ++as redundant with the one under MT-Unsafe). As in the case of ++user-exposed objects, the mark may be followed by a colon and an ++identifier. The identifier groups all functions that operate on a ++certain unguarded object; users may avoid the MT-Safety issues related ++with unguarded concurrent access to such internal objects by creating a ++non-recursive mutex related with the identifier, and always holding the ++mutex when calling any function marked as racy on that identifier, as ++they would have to should the identifier be an object under user ++control. The non-recursive mutex avoids the MT-Safety issue, but it ++trades one AS-Safety issue for another, so use in asynchronous signals ++remains undefined. ++ ++When the identifier relates to a static buffer used to hold return ++values, the mutex must be held for as long as the buffer remains in use ++by the caller. Many functions that return pointers to static buffers ++offer reentrant variants that store return values in caller-supplied ++buffers instead. In some cases, such as @code{tmpname}, the variant is ++chosen not by calling an alternate entry point, but by passing a ++non-@code{NULL} pointer to the buffer in which the returned values are ++to be stored. These variants are generally preferable in multi-threaded ++programs, although some of them are not MT-Safe because of other ++internal buffers, also documented with @code{race} notes. ++ ++ ++@item @code{const} ++@cindex const ++ ++Functions marked with @code{const} as an MT-Safety issue non-atomically ++modify internal objects that are better regarded as constant, because a ++substantial portion of @theglibc{} accesses them without ++synchronization. Unlike @code{race}, that causes both readers and ++writers of internal objects to be regarded as MT-Unsafe and AS-Unsafe, ++this mark is applied to writers only. Writers remain equally MT- and ++AS-Unsafe to call, but the then-mandatory constness of objects they ++modify enables readers to be regarded as MT-Safe and AS-Safe (as long as ++no other reasons for them to be unsafe remain), since the lack of ++synchronization is not a problem when the objects are effectively ++constant. ++ ++The identifier that follows the @code{const} mark will appear by itself ++as a safety note in readers. Programs that wish to work around this ++safety issue, so as to call writers, may use a non-recursve ++@code{rwlock} associated with the identifier, and guard @emph{all} calls ++to functions marked with @code{const} followed by the identifier with a ++write lock, and @emph{all} calls to functions marked with the identifier ++by itself with a read lock. The non-recursive locking removes the ++MT-Safety problem, but it trades one AS-Safety problem for another, so ++use in asynchronous signals remains undefined. ++ ++@c But what if, instead of marking modifiers with const:id and readers ++@c with just id, we marked writers with race:id and readers with ro:id? ++@c Instead of having to define each instance of “idâ€, we'd have a ++@c general pattern governing all such “idâ€s, wherein race:id would ++@c suggest the need for an exclusive/write lock to make the function ++@c safe, whereas ro:id would indicate “id†is expected to be read-only, ++@c but if any modifiers are called (while holding an exclusive lock), ++@c then ro:id-marked functions ought to be guarded with a read lock for ++@c safe operation. ro:env or ro:locale, for example, seems to convey ++@c more clearly the expectations and the meaning, than just env or ++@c locale. ++ ++ ++@item @code{sig} ++@cindex sig ++ ++Functions marked with @code{sig} as a MT-Safety issue (that implies an ++identical AS-Safety issue, omitted for brevity) may temporarily install ++a signal handler for internal purposes, which may interfere with other ++uses of the signal, identified after a colon. ++ ++This safety problem can be worked around by ensuring that no other uses ++of the signal will take place for the duration of the call. Holding a ++non-recursive mutex while calling all functions that use the same ++temporary signal; blocking that signal before the call and resetting its ++handler afterwards is recommended. ++ ++There is no safe way to guarantee the original signal handler is ++restored in case of asynchronous cancellation, therefore so-marked ++functions are also AC-Unsafe. ++ ++@c fixme: at least deferred cancellation should get it right, and would ++@c obviate the restoring bit below, and the qualifier above. ++ ++Besides the measures recommended to work around the MT- and AS-Safety ++problem, in order to avert the cancellation problem, disabling ++asynchronous cancellation @emph{and} installing a cleanup handler to ++restore the signal to the desired state and to release the mutex are ++recommended. ++ ++ ++@item @code{term} ++@cindex term ++ ++Functions marked with @code{term} as an MT-Safety issue may change the ++terminal settings in the recommended way, namely: call @code{tcgetattr}, ++modify some flags, and then call @code{tcsetattr}; this creates a window ++in which changes made by other threads are lost. Thus, functions marked ++with @code{term} are MT-Unsafe. The same window enables changes made by ++asynchronous signals to be lost. These functions are also AS-Unsafe, ++but the corresponding mark is omitted as redundant. ++ ++It is thus advisable for applications using the terminal to avoid ++concurrent and reentrant interactions with it, by not using it in signal ++handlers or blocking signals that might use it, and holding a lock while ++calling these functions and interacting with the terminal. This lock ++should also be used for mutual exclusion with functions marked with ++@code{@mtasurace{:tcattr(fd)}}, where @var{fd} is a file descriptor for ++the controlling terminal. The caller may use a single mutex for ++simplicity, or use one mutex per terminal, even if referenced by ++different file descriptors. ++ ++Functions marked with @code{term} as an AC-Safety issue are supposed to ++restore terminal settings to their original state, after temporarily ++changing them, but they may fail to do so if cancelled. ++ ++@c fixme: at least deferred cancellation should get it right, and would ++@c obviate the restoring bit below, and the qualifier above. ++ ++Besides the measures recommended to work around the MT- and AS-Safety ++problem, in order to avert the cancellation problem, disabling ++asynchronous cancellation @emph{and} installing a cleanup handler to ++restore the terminal settings to the original state and to release the ++mutex are recommended. ++ ++ ++@end itemize ++ ++ ++@node Other Safety Remarks, , Conditionally Safe Features, POSIX ++@subsubsection Other Safety Remarks ++@cindex Other Safety Remarks ++ ++Additional keywords may be attached to functions, indicating features ++that do not make a function unsafe to call, but that may need to be ++taken into account in certain classes of programs: ++ ++@itemize @bullet ++ ++@item @code{locale} ++@cindex locale ++ ++Functions annotated with @code{locale} as an MT-Safety issue read from ++the locale object without any form of synchronization. Functions ++annotated with @code{locale} called concurrently with locale changes may ++behave in ways that do not correspond to any of the locales active ++during their execution, but an unpredictable mix thereof. ++ ++We do not mark these functions as MT- or AS-Unsafe, however, because ++functions that modify the locale object are marked with ++@code{const:locale} and regarded as unsafe. Being unsafe, the latter ++are not to be called when multiple threads are running or asynchronous ++signals are enabled, and so the locale can be considered effectively ++constant in these contexts, which makes the former safe. ++ ++@c Should the locking strategy suggested under @code{const} be used, ++@c failure to guard locale uses is not as fatal as data races in ++@c general: unguarded uses will @emph{not} follow dangling pointers or ++@c access uninitialized, unmapped or recycled memory. Each access will ++@c read from a consistent locale object that is or was active at some ++@c point during its execution. Without synchronization, however, it ++@c cannot even be assumed that, after a change in locale, earlier ++@c locales will no longer be used, even after the newly-chosen one is ++@c used in the thread. Nevertheless, even though unguarded reads from ++@c the locale will not violate type safety, functions that access the ++@c locale multiple times may invoke all sorts of undefined behavior ++@c because of the unexpected locale changes. ++ ++ ++@item @code{env} ++@cindex env ++ ++Functions marked with @code{env} as an MT-Safety issue access the ++environment with @code{getenv} or similar, without any guards to ensure ++safety in the presence of concurrent modifications. ++ ++We do not mark these functions as MT- or AS-Unsafe, however, because ++functions that modify the environment are all marked with ++@code{const:env} and regarded as unsafe. Being unsafe, the latter are ++not to be called when multiple threads are running or asynchronous ++signals are enabled, and so the environment can be considered ++effectively constant in these contexts, which makes the former safe. ++ ++ ++@item @code{hostid} ++@cindex hostid ++ ++The function marked with @code{hostid} as an MT-Safety issue reads from ++the system-wide data structures that hold the ``host ID'' of the ++machine. These data structures cannot generally be modified atomically. ++Since it is expected that the ``host ID'' will not normally change, the ++function that reads from it (@code{gethostid}) is regarded as safe, ++whereas the function that modifies it (@code{sethostid}) is marked with ++@code{@mtasuconst{:@mtshostid{}}}, indicating it may require special ++care if it is to be called. In this specific case, the special care ++amounts to system-wide (not merely intra-process) coordination. ++ ++ ++@item @code{sigintr} ++@cindex sigintr ++ ++Functions marked with @code{sigintr} as an MT-Safety issue access the ++@code{_sigintr} internal data structure without any guards to ensure ++safety in the presence of concurrent modifications. ++ ++We do not mark these functions as MT- or AS-Unsafe, however, because ++functions that modify the this data structure are all marked with ++@code{const:sigintr} and regarded as unsafe. Being unsafe, the latter ++are not to be called when multiple threads are running or asynchronous ++signals are enabled, and so the data structure can be considered ++effectively constant in these contexts, which makes the former safe. ++ ++ ++@item @code{fd} ++@cindex fd ++ ++Functions annotated with @code{fd} as an AC-Safety issue may leak file ++descriptors if asynchronous thread cancellation interrupts their ++execution. ++ ++Functions that allocate or deallocate file descriptors will generally be ++marked as such. Even if they attempted to protect the file descriptor ++allocation and deallocation with cleanup regions, allocating a new ++descriptor and storing its number where the cleanup region could release ++it cannot be performed as a single atomic operation. Similarly, ++releasing the descriptor and taking it out of the data structure ++normally responsible for releasing it cannot be performed atomically. ++There will always be a window in which the descriptor cannot be released ++because it was not stored in the cleanup handler argument yet, or it was ++already taken out before releasing it. It cannot be taken out after ++release: an open descriptor could mean either that the descriptor still ++has to be closed, or that it already did so but the descriptor was ++reallocated by another thread or signal handler. ++ ++Such leaks could be internally avoided, with some performance penalty, ++by temporarily disabling asynchronous thread cancellation. However, ++since callers of allocation or deallocation functions would have to do ++this themselves, to avoid the same sort of leak in their own layer, it ++makes more sense for the library to assume they are taking care of it ++than to impose a performance penalty that is redundant when the problem ++is solved in upper layers, and insufficient when it is not. ++ ++This remark by itself does not cause a function to be regarded as ++AC-Unsafe. However, cumulative effects of such leaks may pose a ++problem for some programs. If this is the case, suspending asynchronous ++cancellation for the duration of calls to such functions is recommended. ++ ++ ++@item @code{mem} ++@cindex mem ++ ++Functions annotated with @code{mem} as an AC-Safety issue may leak ++memory if asynchronous thread cancellation interrupts their execution. ++ ++The problem is similar to that of file descriptors: there is no atomic ++interface to allocate memory and store its address in the argument to a ++cleanup handler, or to release it and remove its address from that ++argument, without at least temporarily disabling asynchronous ++cancellation, which these functions do not do. ++ ++This remark does not by itself cause a function to be regarded as ++generally AC-Unsafe. However, cumulative effects of such leaks may be ++severe enough for some programs that disabling asynchronous cancellation ++for the duration of calls to such functions may be required. ++ ++ ++@item @code{cwd} ++@cindex cwd ++ ++Functions marked with @code{cwd} as an MT-Safety issue may temporarily ++change the current working directory during their execution, which may ++cause relative pathnames to be resolved in unexpected ways in other ++threads or within asynchronous signal or cancellation handlers. ++ ++This is not enough of a reason to mark so-marked functions as MT- or ++AS-Unsafe, but when this behavior is optional (e.g., @code{nftw} with ++@code{FTW_CHDIR}), avoiding the option may be a good alternative to ++using full pathnames or file descriptor-relative (e.g. @code{openat}) ++system calls. ++ ++ ++@item @code{!posix} ++@cindex !posix ++ ++This remark, as an MT-, AS- or AC-Safety note to a function, indicates ++the safety status of the function is known to differ from the specified ++status in the POSIX standard. For example, POSIX does not require a ++function to be Safe, but our implementation is, or vice-versa. ++ ++For the time being, the absence of this remark does not imply the safety ++properties we documented are identical to those mandated by POSIX for ++the corresponding functions. ++ ++ ++@item @code{:identifier} ++@cindex :identifier ++ ++Annotations may sometimes be followed by identifiers, intended to group ++several functions that e.g. access the data structures in an unsafe way, ++as in @code{race} and @code{const}, or to provide more specific ++information, such as naming a signal in a function marked with ++@code{sig}. It is envisioned that it may be applied to @code{lock} and ++@code{corrupt} as well in the future. ++ ++In most cases, the identifier will name a set of functions, but it may ++name global objects or function arguments, or identifiable properties or ++logical components associated with them, with a notation such as ++e.g. @code{:buf(arg)} to denote a buffer associated with the argument ++@var{arg}, or @code{:tcattr(fd)} to denote the terminal attributes of a ++file descriptor @var{fd}. ++ ++The most common use for identifiers is to provide logical groups of ++functions and arguments that need to be protected by the same ++synchronization primitive in order to ensure safe operation in a given ++context. ++ ++ ++@item @code{/condition} ++@cindex /condition ++ ++Some safety annotations may be conditional, in that they only apply if a ++boolean expression involving arguments, global variables or even the ++underlying kernel evaluates evaluates to true. Such conditions as ++@code{/hurd} or @code{/!linux!bsd} indicate the preceding marker only ++applies when the underlying kernel is the HURD, or when it is neither ++Linux nor a BSD kernel, respectively. @code{/!ps} and ++@code{/one_per_line} indicate the preceding marker only applies when ++argument @var{ps} is NULL, or global variable @var{one_per_line} is ++nonzero. ++ ++When all marks that render a function unsafe are adorned with such ++conditions, and none of the named conditions hold, then the function can ++be regarded as safe. ++ ++ ++@end itemize ++ + + @node Berkeley Unix, SVID, POSIX, Standards and Portability + @subsection Berkeley Unix +@@ -556,19 +1283,59 @@ + Here is an overview of the contents of the remaining chapters of + this manual. + ++@c The chapter overview ordering is: ++@c Error Reporting (2) ++@c Virtual Memory Allocation and Paging (3) ++@c Character Handling (4) ++@c Strings and Array Utilities (5) ++@c Character Set Handling (6) ++@c Locales and Internationalization (7) ++@c Searching and Sorting (9) ++@c Pattern Matching (10) ++@c Input/Output Overview (11) ++@c Input/Output on Streams (12) ++@c Low-level Input/Ooutput (13) ++@c File System Interface (14) ++@c Pipes and FIFOs (15) ++@c Sockets (16) ++@c Low-Level Terminal Interface (17) ++@c Syslog (18) ++@c Mathematics (19) ++@c Aritmetic Functions (20) ++@c Date and Time (21) ++@c Non-Local Exist (23) ++@c Signal Handling (24) ++@c The Basic Program/System Interface (25) ++@c Processes (26) ++@c Job Control (28) ++@c System Databases and Name Service Switch (29) ++@c Users and Groups (30) -- References `User Database' and `Group Database' ++@c System Management (31) ++@c System Configuration Parameters (32) ++@c C Language Facilities in the Library (AA) ++@c Summary of Library Facilities (AB) ++@c Installing (AC) ++@c Library Maintenance (AD) ++ ++@c The following chapters need overview text to be added: ++@c Message Translation (8) ++@c Resource Usage And Limitations (22) ++@c Inter-Process Communication (27) ++@c DES Encryption and Password Handling (33) ++@c Debugging support (34) ++@c POSIX Threads (35) ++@c Internal Probes (36) ++@c Platform-specific facilities (AE) ++@c Contributors to (AF) ++@c Free Software Needs Free Documentation (AG) ++@c GNU Lesser General Public License (AH) ++@c GNU Free Documentation License (AI) ++ + @itemize @bullet + @item + @ref{Error Reporting}, describes how errors detected by the library + are reported. + +-@item +-@ref{Language Features}, contains information about library support for +-standard parts of the C language, including things like the @code{sizeof} +-operator and the symbolic constant @code{NULL}, how to write functions +-accepting variable numbers of arguments, and constants describing the +-ranges and other properties of the numerical types. There is also a simple +-debugging mechanism which allows you to put assertions in your code, and +-have diagnostic messages printed if the tests fail. + + @item + @ref{Memory}, describes @theglibc{}'s facilities for managing and +@@ -588,6 +1355,26 @@ + byte arrays, including operations such as copying and comparison. + + @item ++@ref{Character Set Handling}, contains information about manipulating ++characters and strings using character sets larger than will fit in ++the usual @code{char} data type. ++ ++@item ++@ref{Locales}, describes how selecting a particular country ++or language affects the behavior of the library. For example, the locale ++affects collation sequences for strings and how monetary values are ++formatted. ++ ++@item ++@ref{Searching and Sorting}, contains information about functions ++for searching and sorting arrays. You can use these functions on any ++kind of array by providing an appropriate comparison function. ++ ++@item ++@ref{Pattern Matching}, presents functions for matching regular expressions ++and shell file name patterns, and for expanding words as the shell does. ++ ++@item + @ref{I/O Overview}, gives an overall look at the input and output + facilities in the library, and contains information about basic concepts + such as file names. +@@ -639,30 +1426,10 @@ + numbers from strings. + + @item +-@ref{Searching and Sorting}, contains information about functions +-for searching and sorting arrays. You can use these functions on any +-kind of array by providing an appropriate comparison function. +- +-@item +-@ref{Pattern Matching}, presents functions for matching regular expressions +-and shell file name patterns, and for expanding words as the shell does. +- +-@item + @ref{Date and Time}, describes functions for measuring both calendar time + and CPU time, as well as functions for setting alarms and timers. + + @item +-@ref{Character Set Handling}, contains information about manipulating +-characters and strings using character sets larger than will fit in +-the usual @code{char} data type. +- +-@item +-@ref{Locales}, describes how selecting a particular country +-or language affects the behavior of the library. For example, the locale +-affects collation sequences for strings and how monetary values are +-formatted. +- +-@item + @ref{Non-Local Exits}, contains descriptions of the @code{setjmp} and + @code{longjmp} functions. These functions provide a facility for + @code{goto}-like jumps which can jump from one function to another. +@@ -708,6 +1475,15 @@ + compatibility with POSIX. + + @item ++@ref{Language Features}, contains information about library support for ++standard parts of the C language, including things like the @code{sizeof} ++operator and the symbolic constant @code{NULL}, how to write functions ++accepting variable numbers of arguments, and constants describing the ++ranges and other properties of the numerical types. There is also a simple ++debugging mechanism which allows you to put assertions in your code, and ++have diagnostic messages printed if the tests fail. ++ ++@item + @ref{Library Summary}, gives a summary of all the functions, variables, and + macros in the library, with complete data types and function prototypes, + and says what standard or system each is derived from. +diff -urN glibc-2.17-c758a686/manual/ipc.texi glibc-2.17-c758a686/manual/ipc.texi +--- glibc-2.17-c758a686/manual/ipc.texi 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/manual/ipc.texi 2014-09-12 16:10:06.047792712 -0400 +@@ -0,0 +1,116 @@ ++@node Inter-Process Communication, Job Control, Processes, Top ++@c %MENU% All about inter-process communication ++@chapter Inter-Process Communication ++@cindex ipc ++ ++This chapter describes the @glibcadj{} inter-process communication primitives. ++ ++@menu ++* Semaphores:: Support for creating and managing semaphores ++@end menu ++ ++@node Semaphores ++@section Semaphores ++ ++@Theglibc{} implements the semaphore APIs as defined in POSIX and ++System V. Semaphores can be used by multiple processes to coordinate shared ++resources. The following is a complete list of the semaphore functions provided ++by @theglibc{}. ++ ++@c Need descriptions for all of these functions. ++ ++@subsection System V Semaphores ++@deftypefun int semctl (int @var{semid}, int @var{semnum}, int @var{cmd}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{/linux}}} ++@c syscall(ipc) ok ++@c ++@c AC-unsafe because we need to translate the new kernel ++@c semid_ds buf into the userspace layout. Cancellation ++@c at that point results in an inconsistent userspace ++@c semid_ds. ++@end deftypefun ++ ++@deftypefun int semget (key_t @var{key}, int @var{nsems}, int @var{semflg}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c syscall(ipc) ok ++@end deftypefun ++ ++@deftypefun int semop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c syscall(ipc) ok ++@end deftypefun ++ ++@deftypefun int semtimedop (int @var{semid}, struct sembuf *@var{sops}, size_t @var{nsops}, const struct timespec *@var{timeout}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c syscall(ipc) ok ++@end deftypefun ++ ++@subsection POSIX Semaphores ++ ++@deftypefun int sem_init (sem_t *@var{sem}, int @var{pshared}, unsigned int @var{value}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@c Does not atomically update sem_t therefore AC-unsafe ++@c because it can leave sem_t partially initialized. ++@end deftypefun ++ ++@deftypefun int sem_destroy (sem_t *@var{sem}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Function does nothing and is therefore always safe. ++@end deftypefun ++ ++@deftypefun sem_t *sem_open (const char *@var{name}, int @var{oflag}, ...); ++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acuinit{}}} ++@c pthread_once asuinit ++@c ++@c We are AC-Unsafe becuase we use pthread_once to initialize ++@c a global variable that holds the location of the mounted ++@c shmfs on Linux. ++@end deftypefun ++ ++@deftypefun int sem_close (sem_t *@var{sem}); ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c lll_lock asulock aculock ++@c twalk mtsrace{:root} ++@c ++@c We are AS-unsafe because we take a non-recursive lock. ++@c We are AC-unsafe because several internal data structures ++@c are not updated atomically. ++@end deftypefun ++ ++@deftypefun int sem_unlink (const char *@var{name}); ++@safety{@prelim{}@mtsafe{}@asunsafe{@asuinit{}}@acunsafe{@acucorrupt{}}} ++@c pthread_once asuinit acucorrupt aculock ++@c mempcpy acucorrupt ++@end deftypefun ++ ++@deftypefun int sem_wait (sem_t *@var{sem}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@c atomic_increment (nwaiters) acucorrupt ++@c ++@c Given the use atomic operations this function seems ++@c to be AS-safe. It is AC-unsafe because there is still ++@c a window between atomic_decrement and the pthread_push ++@c of the handler that undoes that operation. A cancellation ++@c at that point would fail to remove the process from the ++@c waiters count. ++@end deftypefun ++ ++@deftypefun int sem_timedwait (sem_t *@var{sem}, const struct timespec *@var{abstime}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} ++@c Same safety issues as sem_wait. ++@end deftypefun ++ ++@deftypefun int sem_trywait (sem_t *@var{sem}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c All atomic operations are safe in all contexts. ++@end deftypefun ++ ++@deftypefun int sem_post (sem_t *@var{sem}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Same safety as sem_trywait. ++@end deftypefun ++ ++@deftypefun int sem_getvalue (sem_t *@var{sem}, int *@var{sval}); ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Atomic write of a value is safe in all contexts. ++@end deftypefun +diff -urN glibc-2.17-c758a686/manual/job.texi glibc-2.17-c758a686/manual/job.texi +--- glibc-2.17-c758a686/manual/job.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/job.texi 2014-09-12 16:10:06.048792709 -0400 +@@ -1,4 +1,4 @@ +-@node Job Control, Name Service Switch, Processes, Top ++@node Job Control, Name Service Switch, Inter-Process Communication, Top + @c %MENU% All about process groups and sessions + @chapter Job Control + +@@ -1039,6 +1039,10 @@ + @comment stdio.h + @comment POSIX.1 + @deftypefun {char *} ctermid (char *@var{string}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This function is a stub by default; the actual implementation, for ++@c posix systems, returns an internal buffer if passed a NULL string, ++@c but the internal buffer is always set to /dev/tty. + The @code{ctermid} function returns a string containing the file name of + the controlling terminal for the current process. If @var{string} is + not a null pointer, it should be an array that can hold at least +@@ -1075,6 +1079,12 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun pid_t setsid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is usually a direct syscall, but if a syscall is not available, ++@c we use a stub, or Hurd- and BSD-specific implementations. The former ++@c uses a mutex and a hurd critical section, and the latter issues a few ++@c syscalls, so both seem safe, the locking on Hurd is safe because of ++@c the critical section. + The @code{setsid} function creates a new session. The calling process + becomes the session leader, and is put in a new process group whose + process group ID is the same as the process ID of that process. There +@@ -1098,6 +1108,8 @@ + @comment unistd.h + @comment SVID + @deftypefun pid_t getsid (pid_t @var{pid}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Stub or direct syscall, except on hurd, where it is equally safe. + + The @code{getsid} function returns the process group ID of the session + leader of the specified process. If a @var{pid} is @code{0}, the +@@ -1118,39 +1130,21 @@ + @end table + @end deftypefun + +-The @code{getpgrp} function has two definitions: one derived from BSD +-Unix, and one from the POSIX.1 standard. The feature test macros you +-have selected (@pxref{Feature Test Macros}) determine which definition +-you get. Specifically, you get the BSD version if you define +-@code{_BSD_SOURCE}; otherwise, you get the POSIX version if you define +-@code{_POSIX_SOURCE} or @code{_GNU_SOURCE}. Programs written for old +-BSD systems will not include @file{unistd.h}, which defines +-@code{getpgrp} specially under @code{_BSD_SOURCE}. You must link such +-programs with the @code{-lbsd-compat} option to get the BSD definition.@refill +-@pindex -lbsd-compat +-@pindex bsd-compat +-@cindex BSD compatibility library +- + @comment unistd.h + @comment POSIX.1 +-@deftypefn {POSIX.1 Function} pid_t getpgrp (void) +-The POSIX.1 definition of @code{getpgrp} returns the process group ID of ++@deftypefun pid_t getpgrp (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++The @code{getpgrp} function returns the process group ID of + the calling process. +-@end deftypefn +- +-@comment unistd.h +-@comment BSD +-@deftypefn {BSD Function} pid_t getpgrp (pid_t @var{pid}) +-The BSD definition of @code{getpgrp} returns the process group ID of the +-process @var{pid}. You can supply a value of @code{0} for the @var{pid} +-argument to get information about the calling process. +-@end deftypefn ++@end deftypefun + + @comment unistd.h +-@comment SVID +-@deftypefn {System V Function} int getpgid (pid_t @var{pid}) ++@comment POSIX.1 ++@deftypefun int getpgid (pid_t @var{pid}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Stub or direct syscall, except on hurd, where it is equally safe. + +-@code{getpgid} is the same as the BSD function @code{getpgrp}. It ++The @code{getpgid} function + returns the process group ID of the process @var{pid}. You can supply a + value of @code{0} for the @var{pid} argument to get information about + the calling process. +@@ -1166,11 +1160,13 @@ + process group ID of the process with ID @var{pid} from the calling + process. + @end table +-@end deftypefn ++@end deftypefun + + @comment unistd.h + @comment POSIX.1 + @deftypefun int setpgid (pid_t @var{pid}, pid_t @var{pgid}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Stub or direct syscall, except on hurd, where it is equally safe. + The @code{setpgid} function puts the process @var{pid} into the process + group @var{pgid}. As a special case, either @var{pid} or @var{pgid} can + be zero to indicate the process ID of the calling process. +@@ -1208,6 +1204,8 @@ + @comment unistd.h + @comment BSD + @deftypefun int setpgrp (pid_t @var{pid}, pid_t @var{pgid}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall or setpgid wrapper. + This is the BSD Unix name for @code{setpgid}. Both functions do exactly + the same thing. + @end deftypefun +@@ -1230,6 +1228,8 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun pid_t tcgetpgrp (int @var{filedes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Stub, or ioctl on BSD and GNU/Linux. + This function returns the process group ID of the foreground process + group associated with the terminal open on descriptor @var{filedes}. + +@@ -1258,6 +1258,8 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int tcsetpgrp (int @var{filedes}, pid_t @var{pgid}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Stub, or ioctl on BSD and GNU/Linux. + This function is used to set a terminal's foreground process group ID. + The argument @var{filedes} is a descriptor which specifies the terminal; + @var{pgid} specifies the process group. The calling process must be a +@@ -1297,6 +1299,8 @@ + @comment termios.h + @comment Unix98 + @deftypefun pid_t tcgetsid (int @var{fildes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Ioctl call, if available, or tcgetpgrp followed by getsid. + This function is used to obtain the process group ID of the session + for which the terminal specified by @var{fildes} is the controlling terminal. + If the call is successful the group ID is returned. Otherwise the +diff -urN glibc-2.17-c758a686/manual/lang.texi glibc-2.17-c758a686/manual/lang.texi +--- glibc-2.17-c758a686/manual/lang.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/lang.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -51,6 +51,8 @@ + @comment assert.h + @comment ISO + @deftypefn Macro void assert (int @var{expression}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c assert_fail_base calls asprintf, and fflushes stderr. + Verify the programmer's belief that @var{expression} is nonzero at + this point in the program. + +@@ -91,6 +93,8 @@ + @comment assert.h + @comment GNU + @deftypefn Macro void assert_perror (int @var{errnum}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c assert_fail_base calls asprintf, and fflushes stderr. + Similar to @code{assert}, but verifies that @var{errnum} is zero. + + If @code{NDEBUG} is not defined, @code{assert_perror} tests the value of +@@ -423,6 +427,8 @@ + @comment stdarg.h + @comment ISO + @deftypefn {Macro} void va_start (va_list @var{ap}, @var{last-required}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is no longer provided by glibc, but rather by the compiler. + This macro initializes the argument pointer variable @var{ap} to point + to the first of the optional arguments of the current function; + @var{last-required} must be the last required argument to the function. +@@ -431,6 +437,11 @@ + @comment stdarg.h + @comment ISO + @deftypefn {Macro} @var{type} va_arg (va_list @var{ap}, @var{type}) ++@safety{@prelim{}@mtsafe{@mtsrace{:ap}}@assafe{}@acunsafe{@acucorrupt{}}} ++@c This is no longer provided by glibc, but rather by the compiler. ++@c Unlike the other va_ macros, that either start/end the lifetime of ++@c the va_list object or don't modify it, this one modifies ap, and it ++@c may leave it in a partially updated state. + The @code{va_arg} macro returns the value of the next optional argument, + and modifies the value of @var{ap} to point to the subsequent argument. + Thus, successive uses of @code{va_arg} return successive optional +@@ -445,6 +456,8 @@ + @comment stdarg.h + @comment ISO + @deftypefn {Macro} void va_end (va_list @var{ap}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is no longer provided by glibc, but rather by the compiler. + This ends the use of @var{ap}. After a @code{va_end} call, further + @code{va_arg} calls with the same @var{ap} may not work. You should invoke + @code{va_end} before returning from the function in which @code{va_start} +@@ -466,6 +479,8 @@ + @comment ISO + @deftypefn {Macro} void va_copy (va_list @var{dest}, va_list @var{src}) + @deftypefnx {Macro} void __va_copy (va_list @var{dest}, va_list @var{src}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is no longer provided by glibc, but rather by the compiler. + The @code{va_copy} macro allows copying of objects of type + @code{va_list} even if this is not an integral type. The argument pointer + in @var{dest} is initialized to point to the same argument as the +@@ -1212,7 +1227,9 @@ + @comment stddef.h + @comment ISO + @deftypefn {Macro} size_t offsetof (@var{type}, @var{member}) +-This expands to a integer constant expression that is the offset of the ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is no longer provided by glibc, but rather by the compiler. ++This expands to an integer constant expression that is the offset of the + structure member named @var{member} in the structure type @var{type}. + For example, @code{offsetof (struct s, elem)} is the offset, in bytes, + of the member @code{elem} in a @code{struct s}. +diff -urN glibc-2.17-c758a686/manual/libc.texinfo glibc-2.17-c758a686/manual/libc.texinfo +--- glibc-2.17-c758a686/manual/libc.texinfo 2014-09-12 16:08:17.677071123 -0400 ++++ glibc-2.17-c758a686/manual/libc.texinfo 2014-09-12 16:10:25.996741462 -0400 +@@ -7,7 +7,7 @@ + @include macros.texi + + @comment Tell install-info what to do. +-@dircategory Libraries ++@dircategory Software libraries + @direntry + * Libc: (libc). C library. + @end direntry +@@ -46,7 +46,7 @@ + @value{VERSION} @value{PKGVERSION}. + @end ifclear + +-Copyright @copyright{} 1993--2012 Free Software Foundation, Inc. ++Copyright @copyright{} 1993--2014 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version +@@ -118,6 +118,7 @@ + @include chapters.texi + + @node Free Manuals, Copying, Contributors, Top ++@appendix Free Software Needs Free Documentation + @include freemanuals.texi + + @node Copying, Documentation License, Free Manuals, Top +diff -urN glibc-2.17-c758a686/manual/libc-texinfo.sh glibc-2.17-c758a686/manual/libc-texinfo.sh +--- glibc-2.17-c758a686/manual/libc-texinfo.sh 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/libc-texinfo.sh 2014-09-12 16:10:06.042792724 -0400 +@@ -91,9 +91,11 @@ + * Variable Index:: Index of variables and variable-like macros. + * File Index:: Index of programs and files. + ++ @detailmenu + --- The Detailed Node Listing --- + EOF + cat ${OUTDIR}lmenu.$$ ++ echo '@end detailmenu' + echo '@end menu'; } >${OUTDIR}top-menu.texi.$$ + mv -f ${OUTDIR}top-menu.texi.$$ ${OUTDIR}top-menu.texi + +diff -urN glibc-2.17-c758a686/manual/libdl.texi glibc-2.17-c758a686/manual/libdl.texi +--- glibc-2.17-c758a686/manual/libdl.texi 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/manual/libdl.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -0,0 +1,10 @@ ++@c FIXME these are undocumented: ++@c dladdr ++@c dladdr1 ++@c dlclose ++@c dlerror ++@c dlinfo ++@c dlmopen ++@c dlopen ++@c dlsym ++@c dlvsym +diff -urN glibc-2.17-c758a686/manual/llio.texi glibc-2.17-c758a686/manual/llio.texi +--- glibc-2.17-c758a686/manual/llio.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/llio.texi 2014-09-12 16:10:06.047792712 -0400 +@@ -78,6 +82,7 @@ + @comment fcntl.h + @comment POSIX.1 + @deftypefun int open (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}]) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + The @code{open} function creates and returns a new file descriptor for + the file named by @var{filename}. Initially, the file position + indicator for the file is at the beginning of the file. The argument +@@ -164,6 +169,7 @@ + @comment fcntl.h + @comment Unix98 + @deftypefun int open64 (const char *@var{filename}, int @var{flags}[, mode_t @var{mode}]) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + This function is similar to @code{open}. It returns a file descriptor + which can be used to access the file named by @var{filename}. The only + difference is that on 32 bit systems the file is opened in the +@@ -178,6 +184,7 @@ + @comment fcntl.h + @comment POSIX.1 + @deftypefn {Obsolete function} int creat (const char *@var{filename}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + This function is obsolete. The call: + + @smallexample +@@ -202,6 +209,7 @@ + @comment fcntl.h + @comment Unix98 + @deftypefn {Obsolete function} int creat64 (const char *@var{filename}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + This function is similar to @code{creat}. It returns a file descriptor + which can be used to access the file named by @var{filename}. The only + the difference is that on 32 bit systems the file is opened in the +@@ -219,6 +227,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int close (int @var{filedes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + The function @code{close} closes the file descriptor @var{filedes}. + Closing a file has the following consequences: + +@@ -300,6 +309,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun ssize_t read (int @var{filedes}, void *@var{buffer}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{read} function reads up to @var{size} bytes from the file + with descriptor @var{filedes}, storing the results in the @var{buffer}. + (This is not necessarily a character string, and no terminating null +@@ -395,6 +405,10 @@ + @comment unistd.h + @comment Unix98 + @deftypefun ssize_t pread (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is usually a safe syscall. The sysdeps/posix fallback emulation ++@c is not MT-Safe because it uses lseek, read and lseek back, but is it ++@c used anywhere? + The @code{pread} function is similar to the @code{read} function. The + first three arguments are identical, and the return values and error + codes also correspond. +@@ -430,6 +444,10 @@ + @comment unistd.h + @comment Unix98 + @deftypefun ssize_t pread64 (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off64_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is usually a safe syscall. The sysdeps/posix fallback emulation ++@c is not MT-Safe because it uses lseek64, read and lseek64 back, but is ++@c it used anywhere? + This function is similar to the @code{pread} function. The difference + is that the @var{offset} parameter is of type @code{off64_t} instead of + @code{off_t} which makes it possible on 32 bit machines to address +@@ -447,6 +465,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun ssize_t write (int @var{filedes}, const void *@var{buffer}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{write} function writes up to @var{size} bytes from + @var{buffer} to the file with descriptor @var{filedes}. The data in + @var{buffer} is not necessarily a character string and a null character is +@@ -557,6 +576,10 @@ + @comment unistd.h + @comment Unix98 + @deftypefun ssize_t pwrite (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is usually a safe syscall. The sysdeps/posix fallback emulation ++@c is not MT-Safe because it uses lseek, write and lseek back, but is it ++@c used anywhere? + The @code{pwrite} function is similar to the @code{write} function. The + first three arguments are identical, and the return values and error codes + also correspond. +@@ -592,6 +615,10 @@ + @comment unistd.h + @comment Unix98 + @deftypefun ssize_t pwrite64 (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off64_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is usually a safe syscall. The sysdeps/posix fallback emulation ++@c is not MT-Safe because it uses lseek64, write and lseek64 back, but ++@c is it used anywhere? + This function is similar to the @code{pwrite} function. The difference + is that the @var{offset} parameter is of type @code{off64_t} instead of + @code{off_t} which makes it possible on 32 bit machines to address +@@ -624,6 +651,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun off_t lseek (int @var{filedes}, off_t @var{offset}, int @var{whence}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{lseek} function is used to change the file position of the + file with descriptor @var{filedes}. + +@@ -713,6 +741,7 @@ + @comment unistd.h + @comment Unix98 + @deftypefun off64_t lseek64 (int @var{filedes}, off64_t @var{offset}, int @var{whence}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to the @code{lseek} function. The difference + is that the @var{offset} parameter is of type @code{off64_t} instead of + @code{off_t} which makes it possible on 32 bit machines to address +@@ -825,6 +854,7 @@ + @comment stdio.h + @comment POSIX.1 + @deftypefun {FILE *} fdopen (int @var{filedes}, const char *@var{opentype}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}} + The @code{fdopen} function returns a new stream for the file descriptor + @var{filedes}. + +@@ -853,6 +883,7 @@ + @comment stdio.h + @comment POSIX.1 + @deftypefun int fileno (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function returns the file descriptor associated with the stream + @var{stream}. If an error is detected (for example, if the @var{stream} + is not valid) or if @var{stream} does not do I/O to a file, +@@ -862,6 +893,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int fileno_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fileno_unlocked} function is equivalent to the @code{fileno} + function except that it does not implicitly lock the stream if the state + is @code{FSETLOCKING_INTERNAL}. +@@ -1055,7 +1087,7 @@ + @comment BSD + @deftp {Data Type} {struct iovec} + +-The @code{iovec} structure describes a buffer. It contains two fields: ++The @code{iovec} structure describes a buffer. It contains two fields: + + @table @code + +@@ -1071,6 +1103,11 @@ + @comment sys/uio.h + @comment BSD + @deftypefun ssize_t readv (int @var{filedes}, const struct iovec *@var{vector}, int @var{count}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c The fallback sysdeps/posix implementation, used even on GNU/Linux ++@c with old kernels that lack a full readv/writev implementation, may ++@c malloc the buffer into which data is read, if the total read size is ++@c too large for alloca. + + The @code{readv} function reads data from @var{filedes} and scatters it + into the buffers described in @var{vector}, which is taken to be +@@ -1089,6 +1126,11 @@ + @comment sys/uio.h + @comment BSD + @deftypefun ssize_t writev (int @var{filedes}, const struct iovec *@var{vector}, int @var{count}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c The fallback sysdeps/posix implementation, used even on GNU/Linux ++@c with old kernels that lack a full readv/writev implementation, may ++@c malloc the buffer from which data is written, if the total write size ++@c is too large for alloca. + + The @code{writev} function gathers data from the buffers described in + @var{vector}, which is taken to be @var{count} structures long, and writes +@@ -1103,8 +1145,8 @@ + + @end deftypefun + +-@c Note - I haven't read this anywhere. I surmised it from my knowledge +-@c of computer science. Thus, there could be subtleties I'm missing. ++@c Note - I haven't read this anywhere. I surmised it from my knowledge ++@c of computer science. Thus, there could be subtleties I'm missing. + + Note that if the buffers are small (under about 1kB), high-level streams + may be easier to use than these functions. However, @code{readv} and +@@ -1149,6 +1191,7 @@ + @comment sys/mman.h + @comment POSIX + @deftypefun {void *} mmap (void *@var{address}, size_t @var{length}, int @var{protect}, int @var{flags}, int @var{filedes}, off_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + The @code{mmap} function creates a new mapping, connected to bytes + (@var{offset}) to (@var{offset} + @var{length} - 1) in the file open on +@@ -1156,8 +1199,8 @@ + is created, which is not removed by closing the file. + + @var{address} gives a preferred starting address for the mapping. +-@code{NULL} expresses no preference. Any previous mapping at that +-address is automatically removed. The address you give may still be ++@code{NULL} expresses no preference. Any previous mapping at that ++address is automatically removed. The address you give may still be + changed, unless you use the @code{MAP_FIXED} flag. + + @vindex PROT_READ +@@ -1221,13 +1264,13 @@ + + @c Linux has some other MAP_ options, which I have not discussed here. + @c MAP_DENYWRITE, MAP_EXECUTABLE and MAP_GROWSDOWN don't seem applicable to +-@c user programs (and I don't understand the last two). MAP_LOCKED does ++@c user programs (and I don't understand the last two). MAP_LOCKED does + @c not appear to be implemented. + + @end vtable + +-@code{mmap} returns the address of the new mapping, or @math{-1} for an +-error. ++@code{mmap} returns the address of the new mapping, or ++@code{MAP_FAILED} for an error. + + Possible errors include: + +@@ -1268,6 +1311,9 @@ + @comment sys/mman.h + @comment LFS + @deftypefun {void *} mmap64 (void *@var{address}, size_t @var{length}, int @var{protect}, int @var{flags}, int @var{filedes}, off64_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c The page_shift auto detection when MMAP2_PAGE_SHIFT is -1 (it never ++@c is) would be thread-unsafe. + The @code{mmap64} function is equivalent to the @code{mmap} function but + the @var{offset} parameter is of type @code{off64_t}. On 32-bit systems + this allows the file associated with the @var{filedes} descriptor to be +@@ -1284,6 +1330,7 @@ + @comment sys/mman.h + @comment POSIX + @deftypefun int munmap (void *@var{addr}, size_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{munmap} removes any memory maps from (@var{addr}) to (@var{addr} + + @var{length}). @var{length} should be the length of the mapping. +@@ -1310,6 +1357,7 @@ + @comment sys/mman.h + @comment POSIX + @deftypefun int msync (void *@var{address}, size_t @var{length}, int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + When using shared mappings, the kernel can write the file at any time + before the mapping is removed. To be certain data has actually been +@@ -1357,17 +1405,18 @@ + @comment sys/mman.h + @comment GNU + @deftypefun {void *} mremap (void *@var{address}, size_t @var{length}, size_t @var{new_length}, int @var{flag}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + This function can be used to change the size of an existing memory + area. @var{address} and @var{length} must cover a region entirely mapped +-in the same @code{mmap} statement. A new mapping with the same ++in the same @code{mmap} statement. A new mapping with the same + characteristics will be returned with the length @var{new_length}. + +-One option is possible, @code{MREMAP_MAYMOVE}. If it is given in ++One option is possible, @code{MREMAP_MAYMOVE}. If it is given in + @var{flags}, the system may remove the existing mapping and create a new + one of the desired length in another location. + +-The address of the resulting mapping is returned, or @math{-1}. Possible ++The address of the resulting mapping is returned, or @math{-1}. Possible + error codes include: + + @table @code +@@ -1405,6 +1454,7 @@ + @comment sys/mman.h + @comment POSIX + @deftypefun int madvise (void *@var{addr}, size_t @var{length}, int @var{advice}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + This function can be used to provide the system with @var{advice} about + the intended usage patterns of the memory region starting at @var{addr} +@@ -1418,11 +1468,11 @@ + The region should receive no further special treatment. + + @item MADV_RANDOM +-The region will be accessed via random page references. The kernel ++The region will be accessed via random page references. The kernel + should page-in the minimal number of pages for each page fault. + + @item MADV_SEQUENTIAL +-The region will be accessed via sequential page references. This ++The region will be accessed via sequential page references. This + may cause the kernel to aggressively read-ahead, expecting further + sequential references after any page fault within this region. + +@@ -1471,6 +1521,58 @@ + @end table + @end deftypefun + ++@comment sys/mman.h ++@comment POSIX ++@deftypefn Function int shm_open (const char *@var{name}, int @var{oflag}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c shm_open @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_once(where_is_shmfs) @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd ++@c where_is_shmfs @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c statfs dup ok ++@c setmntent dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c getmntent_r dup @mtslocale @ascuheap @aculock @acsmem [no @asucorrupt @acucorrupt; exclusive stream] ++@c strcmp dup ok ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c endmntent dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c strlen dup ok ++@c strchr dup ok ++@c mempcpy dup ok ++@c open dup @acsfd ++@c fcntl dup ok ++@c close dup @acsfd ++ ++This function returns a file descriptor that can be used to allocate shared ++memory via mmap. Unrelated processes can use same @var{name} to create or ++open existing shared memory objects. ++ ++A @var{name} argument specifies the shared memory object to be opened. ++In @theglibc{} it must be a string smaller than @code{NAME_MAX} bytes starting ++with an optional slash but containing no other slashes. ++ ++The semantics of @var{oflag} and @var{mode} arguments is same as in @code{open}. ++ ++@code{shm_open} returns the file descriptor on success or @math{-1} on error. ++On failure @code{errno} is set. ++@end deftypefn ++ ++@deftypefn Function int shm_unlink (const char *@var{name}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asuinit{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c shm_unlink @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_once(where_is_shmfs) dup @mtslocale @asuinit @ascuheap @asulock @aculock @acsmem @acsfd ++@c strlen dup ok ++@c strchr dup ok ++@c mempcpy dup ok ++@c unlink dup ok ++ ++This function is inverse of @code{shm_open} and removes the object with ++the given @var{name} previously created by @code{shm_open}. ++ ++@code{shm_unlink} returns @math{0} on success or @math{-1} on error. ++On failure @code{errno} is set. ++@end deftypefn ++ + @node Waiting for I/O + @section Waiting for Input or Output + @cindex waiting for input or output +@@ -1531,6 +1633,7 @@ + @comment sys/types.h + @comment BSD + @deftypefn Macro void FD_ZERO (fd_set *@var{set}) ++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}} + This macro initializes the file descriptor set @var{set} to be the + empty set. + @end deftypefn +@@ -1538,6 +1641,9 @@ + @comment sys/types.h + @comment BSD + @deftypefn Macro void FD_SET (int @var{filedes}, fd_set *@var{set}) ++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}} ++@c Setting a bit isn't necessarily atomic, so there's a potential race ++@c here if set is not used exclusively. + This macro adds @var{filedes} to the file descriptor set @var{set}. + + The @var{filedes} parameter must not have side effects since it is +@@ -1547,6 +1653,9 @@ + @comment sys/types.h + @comment BSD + @deftypefn Macro void FD_CLR (int @var{filedes}, fd_set *@var{set}) ++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}} ++@c Setting a bit isn't necessarily atomic, so there's a potential race ++@c here if set is not used exclusively. + This macro removes @var{filedes} from the file descriptor set @var{set}. + + The @var{filedes} parameter must not have side effects since it is +@@ -1556,6 +1665,7 @@ + @comment sys/types.h + @comment BSD + @deftypefn Macro int FD_ISSET (int @var{filedes}, const fd_set *@var{set}) ++@safety{@prelim{}@mtsafe{@mtsrace{:set}}@assafe{}@acsafe{}} + This macro returns a nonzero value (true) if @var{filedes} is a member + of the file descriptor set @var{set}, and zero (false) otherwise. + +@@ -1568,6 +1678,10 @@ + @comment sys/types.h + @comment BSD + @deftypefun int select (int @var{nfds}, fd_set *@var{read-fds}, fd_set *@var{write-fds}, fd_set *@var{except-fds}, struct timeval *@var{timeout}) ++@safety{@prelim{}@mtsafe{@mtsrace{:read-fds} @mtsrace{:write-fds} @mtsrace{:except-fds}}@assafe{}@acsafe{}} ++@c The select syscall is preferred, but pselect6 may be used instead, ++@c which requires converting timeout to a timespec and back. The ++@c conversions are not atomic. + The @code{select} function blocks the calling process until there is + activity on any of the specified sets of file descriptors, or until the + timeout period has expired. +@@ -1669,15 +1783,14 @@ + + @comment unistd.h + @comment X/Open +-@deftypefun int sync (void) ++@deftypefun void sync (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + A call to this function will not return as long as there is data which + has not been written to the device. All dirty buffers in the kernel will + be written and so an overall consistent system can be achieved (if no + other process in parallel writes data). + + A prototype for @code{sync} can be found in @file{unistd.h}. +- +-The return value is zero to indicate no error. + @end deftypefun + + Programs more often want to ensure that data written to a given file is +@@ -1687,6 +1800,7 @@ + @comment unistd.h + @comment POSIX + @deftypefun int fsync (int @var{fildes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fsync} function can be used to make sure all data associated with + the open file @var{fildes} is written to the device associated with the + descriptor. The function call does not return unless all actions have +@@ -1724,6 +1838,7 @@ + @comment unistd.h + @comment POSIX + @deftypefun int fdatasync (int @var{fildes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + When a call to the @code{fdatasync} function returns, it is ensured + that all of the file data is written to the device. For all pending I/O + operations, the parts guaranteeing data integrity finished. +@@ -1925,6 +2040,158 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int aio_read (struct aiocb *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} ++@c Calls aio_enqueue_request. ++@c aio_enqueue_request @asulock @ascuheap @aculock @acsmem ++@c pthread_self ok ++@c pthread_getschedparam @asulock @aculock ++@c lll_lock (pthread descriptor's lock) @asulock @aculock ++@c sched_getparam ok ++@c sched_getscheduler ok ++@c lll_unlock @aculock ++@c pthread_mutex_lock (aio_requests_mutex) @asulock @aculock ++@c get_elem @ascuheap @acsmem [@asucorrupt @acucorrupt] ++@c realloc @ascuheap @acsmem ++@c calloc @ascuheap @acsmem ++@c aio_create_helper_thread @asulock @ascuheap @aculock @acsmem ++@c pthread_attr_init ok ++@c pthread_attr_setdetachstate ok ++@c pthread_get_minstack ok ++@c pthread_attr_setstacksize ok ++@c sigfillset ok ++@c memset ok ++@c sigdelset ok ++@c SYSCALL rt_sigprocmask ok ++@c pthread_create @asulock @ascuheap @aculock @acsmem ++@c lll_lock (default_pthread_attr_lock) @asulock @aculock ++@c alloca/malloc @ascuheap @acsmem ++@c lll_unlock @aculock ++@c allocate_stack @asulock @ascuheap @aculock @acsmem ++@c getpagesize dup ++@c lll_lock (default_pthread_attr_lock) @asulock @aculock ++@c lll_unlock @aculock ++@c _dl_allocate_tls @ascuheap @acsmem ++@c _dl_allocate_tls_storage @ascuheap @acsmem ++@c memalign @ascuheap @acsmem ++@c memset ok ++@c allocate_dtv dup ++@c free @ascuheap @acsmem ++@c allocate_dtv @ascuheap @acsmem ++@c calloc @ascuheap @acsmem ++@c INSTALL_DTV ok ++@c list_add dup ++@c get_cached_stack ++@c lll_lock (stack_cache_lock) @asulock @aculock ++@c list_for_each ok ++@c list_entry dup ++@c FREE_P dup ++@c stack_list_del dup ++@c stack_list_add dup ++@c lll_unlock @aculock ++@c _dl_allocate_tls_init ok ++@c GET_DTV ok ++@c mmap ok ++@c atomic_increment_val ok ++@c munmap ok ++@c change_stack_perm ok ++@c mprotect ok ++@c mprotect ok ++@c stack_list_del dup ++@c _dl_deallocate_tls dup ++@c munmap ok ++@c THREAD_COPY_STACK_GUARD ok ++@c THREAD_COPY_POINTER_GUARD ok ++@c atomic_exchange_acq ok ++@c lll_futex_wake ok ++@c deallocate_stack @asulock @ascuheap @aculock @acsmem ++@c lll_lock (state_cache_lock) @asulock @aculock ++@c stack_list_del ok ++@c atomic_write_barrier ok ++@c list_del ok ++@c atomic_write_barrier ok ++@c queue_stack @ascuheap @acsmem ++@c stack_list_add ok ++@c atomic_write_barrier ok ++@c list_add ok ++@c atomic_write_barrier ok ++@c free_stacks @ascuheap @acsmem ++@c list_for_each_prev_safe ok ++@c list_entry ok ++@c FREE_P ok ++@c stack_list_del dup ++@c _dl_deallocate_tls dup ++@c munmap ok ++@c _dl_deallocate_tls @ascuheap @acsmem ++@c free @ascuheap @acsmem ++@c lll_unlock @aculock ++@c create_thread @asulock @ascuheap @aculock @acsmem ++@c td_eventword ++@c td_eventmask ++@c do_clone @asulock @ascuheap @aculock @acsmem ++@c PREPARE_CREATE ok ++@c lll_lock (pd->lock) @asulock @aculock ++@c atomic_increment ok ++@c clone ok ++@c atomic_decrement ok ++@c atomic_exchange_acq ok ++@c lll_futex_wake ok ++@c deallocate_stack dup ++@c sched_setaffinity ok ++@c tgkill ok ++@c sched_setscheduler ok ++@c atomic_compare_and_exchange_bool_acq ok ++@c nptl_create_event ok ++@c lll_unlock (pd->lock) @aculock ++@c free @ascuheap @acsmem ++@c pthread_attr_destroy ok (cpuset won't be set, so free isn't called) ++@c add_request_to_runlist ok ++@c pthread_cond_signal ok ++@c aio_free_request ok ++@c pthread_mutex_unlock @aculock ++ ++@c (in the new thread, initiated with clone) ++@c start_thread ok ++@c HP_TIMING_NOW ok ++@c ctype_init @mtslocale ++@c atomic_exchange_acq ok ++@c lll_futex_wake ok ++@c sigemptyset ok ++@c sigaddset ok ++@c setjmp ok ++@c CANCEL_ASYNC -> pthread_enable_asynccancel ok ++@c do_cancel ok ++@c pthread_unwind ok ++@c Unwind_ForcedUnwind or longjmp ok [@ascuheap @acsmem?] ++@c lll_lock @asulock @aculock ++@c lll_unlock @asulock @aculock ++@c CANCEL_RESET -> pthread_disable_asynccancel ok ++@c lll_futex_wait ok ++@c ->start_routine ok ----- ++@c call_tls_dtors @asulock @ascuheap @aculock @acsmem ++@c user-supplied dtor ++@c rtld_lock_lock_recursive (dl_load_lock) @asulock @aculock ++@c rtld_lock_unlock_recursive @aculock ++@c free @ascuheap @acsmem ++@c nptl_deallocate_tsd @ascuheap @acsmem ++@c tsd user-supplied dtors ok ++@c free @ascuheap @acsmem ++@c libc_thread_freeres ++@c libc_thread_subfreeres ok ++@c atomic_decrement_and_test ok ++@c td_eventword ok ++@c td_eventmask ok ++@c atomic_compare_exchange_bool_acq ok ++@c nptl_death_event ok ++@c lll_robust_dead ok ++@c getpagesize ok ++@c madvise ok ++@c free_tcb @asulock @ascuheap @aculock @acsmem ++@c free @ascuheap @acsmem ++@c deallocate_stack @asulock @ascuheap @aculock @acsmem ++@c lll_futex_wait ok ++@c exit_thread_inline ok ++@c syscall(exit) ok ++ + This function initiates an asynchronous read operation. It + immediately returns after the operation was enqueued or when an + error was encountered. +@@ -1989,7 +2256,8 @@ + + @comment aio.h + @comment Unix98 +-@deftypefun int aio_read64 (struct aiocb *@var{aiocbp}) ++@deftypefun int aio_read64 (struct aiocb64 *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + This function is similar to the @code{aio_read} function. The only + difference is that on @w{32 bit} machines, the file descriptor should + be opened in the large file mode. Internally, @code{aio_read64} uses +@@ -2008,13 +2276,14 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int aio_write (struct aiocb *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + This function initiates an asynchronous write operation. The function + call immediately returns after the operation was enqueued or if before + this happens an error was encountered. + + The first @code{aiocbp->aio_nbytes} bytes from the buffer starting at + @code{aiocbp->aio_buf} are written to the file for which +-@code{aiocbp->aio_fildes} is an descriptor, starting at the absolute ++@code{aiocbp->aio_fildes} is a descriptor, starting at the absolute + position @code{aiocbp->aio_offset} in the file. + + If prioritized I/O is supported by the platform, the +@@ -2073,7 +2342,8 @@ + + @comment aio.h + @comment Unix98 +-@deftypefun int aio_write64 (struct aiocb *@var{aiocbp}) ++@deftypefun int aio_write64 (struct aiocb64 *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + This function is similar to the @code{aio_write} function. The only + difference is that on @w{32 bit} machines the file descriptor should + be opened in the large file mode. Internally @code{aio_write64} uses +@@ -2095,6 +2365,12 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int lio_listio (int @var{mode}, struct aiocb *const @var{list}[], int @var{nent}, struct sigevent *@var{sig}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} ++@c Call lio_listio_internal, that takes the aio_requests_mutex lock and ++@c enqueues each request. Then, it waits for notification or prepares ++@c for it before releasing the lock. Even though it performs memory ++@c allocation and locking of its own, it doesn't add any classes of ++@c safety issues that aren't already covered by aio_enqueue_request. + The @code{lio_listio} function can be used to enqueue an arbitrary + number of read and write requests at one time. The requests can all be + meant for the same file, all for different files or every solution in +@@ -2177,7 +2453,8 @@ + + @comment aio.h + @comment Unix98 +-@deftypefun int lio_listio64 (int @var{mode}, struct aiocb *const @var{list}, int @var{nent}, struct sigevent *@var{sig}) ++@deftypefun int lio_listio64 (int @var{mode}, struct aiocb64 *const @var{list}[], int @var{nent}, struct sigevent *@var{sig}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + This function is similar to the @code{lio_listio} function. The only + difference is that on @w{32 bit} machines, the file descriptor should + be opened in the large file mode. Internally, @code{lio_listio64} uses +@@ -2206,6 +2483,7 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int aio_error (const struct aiocb *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function determines the error state of the request described by the + @code{struct aiocb} variable pointed to by @var{aiocbp}. If the + request has not yet terminated the value returned is always +@@ -2227,6 +2505,7 @@ + @comment aio.h + @comment Unix98 + @deftypefun int aio_error64 (const struct aiocb64 *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{aio_error} with the only difference + that the argument is a reference to a variable of type @code{struct + aiocb64}. +@@ -2239,7 +2518,8 @@ + + @comment aio.h + @comment POSIX.1b +-@deftypefun ssize_t aio_return (const struct aiocb *@var{aiocbp}) ++@deftypefun ssize_t aio_return (struct aiocb *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function can be used to retrieve the return status of the operation + carried out by the request described in the variable pointed to by + @var{aiocbp}. As long as the error status of this request as returned +@@ -2262,7 +2542,8 @@ + + @comment aio.h + @comment Unix98 +-@deftypefun int aio_return64 (const struct aiocb64 *@var{aiocbp}) ++@deftypefun ssize_t aio_return64 (struct aiocb64 *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{aio_return} with the only difference + that the argument is a reference to a variable of type @code{struct + aiocb64}. +@@ -2291,6 +2572,9 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int aio_fsync (int @var{op}, struct aiocb *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} ++@c After fcntl to check that the FD is open, it calls ++@c aio_enqueue_request. + Calling this function forces all I/O operations operating queued at the + time of the function call operating on the file descriptor + @code{aiocbp->aio_fildes} into the synchronized I/O completion state +@@ -2322,8 +2606,7 @@ + @item EAGAIN + The request could not be enqueued due to temporary lack of resources. + @item EBADF +-The file descriptor @code{aiocbp->aio_fildes} is not valid or not open +-for writing. ++The file descriptor @code{@var{aiocbp}->aio_fildes} is not valid. + @item EINVAL + The implementation does not support I/O synchronization or the @var{op} + parameter is other than @code{O_DSYNC} and @code{O_SYNC}. +@@ -2339,6 +2622,7 @@ + @comment aio.h + @comment Unix98 + @deftypefun int aio_fsync64 (int @var{op}, struct aiocb64 *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + This function is similar to @code{aio_fsync} with the only difference + that the argument is a reference to a variable of type @code{struct + aiocb64}. +@@ -2365,6 +2649,9 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int aio_suspend (const struct aiocb *const @var{list}[], int @var{nent}, const struct timespec *@var{timeout}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c Take aio_requests_mutex, set up waitlist and requestlist, wait ++@c for completion or timeout, and release the mutex. + When calling this function, the calling thread is suspended until at + least one of the requests pointed to by the @var{nent} elements of the + array @var{list} has completed. If any of the requests has already +@@ -2403,6 +2690,7 @@ + @comment aio.h + @comment Unix98 + @deftypefun int aio_suspend64 (const struct aiocb64 *const @var{list}[], int @var{nent}, const struct timespec *@var{timeout}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + This function is similar to @code{aio_suspend} with the only difference + that the argument is a reference to a variable of type @code{struct + aiocb64}. +@@ -2430,6 +2718,16 @@ + @comment aio.h + @comment POSIX.1b + @deftypefun int aio_cancel (int @var{fildes}, struct aiocb *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} ++@c After fcntl to check the fd is open, hold aio_requests_mutex, call ++@c aio_find_req_fd, aio_remove_request, then aio_notify and ++@c aio_free_request each request before releasing the lock. ++@c aio_notify calls aio_notify_only and free, besides cond signal or ++@c similar. aio_notify_only calls pthread_attr_init, ++@c pthread_attr_setdetachstate, malloc, pthread_create, ++@c notify_func_wrapper, aio_sigqueue, getpid, raise. ++@c notify_func_wraper calls aio_start_notify_thread, free and then the ++@c notifier function. + The @code{aio_cancel} function can be used to cancel one or more + outstanding requests. If the @var{aiocbp} parameter is @code{NULL}, the + function tries to cancel all of the outstanding requests which would process +@@ -2477,6 +2775,7 @@ + @comment aio.h + @comment Unix98 + @deftypefun int aio_cancel64 (int @var{fildes}, struct aiocb64 *@var{aiocbp}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + This function is similar to @code{aio_cancel} with the only difference + that the argument is a reference to a variable of type @code{struct + aiocb64}. +@@ -2532,6 +2831,8 @@ + @comment aio.h + @comment GNU + @deftypefun void aio_init (const struct aioinit *@var{init}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c All changes to global objects are guarded by aio_requests_mutex. + This function must be called before any other AIO function. Calling it + is completely voluntary, as it is only meant to help the AIO + implementation perform better. +@@ -2566,6 +2867,7 @@ + @comment fcntl.h + @comment POSIX.1 + @deftypefun int fcntl (int @var{filedes}, int @var{command}, @dots{}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{fcntl} function performs the operation specified by + @var{command} on the file descriptor @var{filedes}. Some commands + require additional arguments to be supplied. These additional arguments +@@ -2592,7 +2894,7 @@ + Set flags associated with the open file. @xref{File Status Flags}. + + @item F_GETLK +-Get a file lock. @xref{File Locks}. ++Test a file lock. @xref{File Locks}. + + @item F_SETLK + Set or clear a file lock. @xref{File Locks}. +@@ -2648,6 +2962,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int dup (int @var{old}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function copies descriptor @var{old} to the first available + descriptor number (the first number not currently open). It is + equivalent to @code{fcntl (@var{old}, F_DUPFD, 0)}. +@@ -2656,6 +2971,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int dup2 (int @var{old}, int @var{new}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function copies the descriptor @var{old} to descriptor number + @var{new}. + +@@ -2929,19 +3245,19 @@ + But most programs will want to be portable to other POSIX.1 systems and + should use the POSIX.1 names above instead. + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment GNU + @deftypevr Macro int O_READ + Open the file for reading. Same as @code{O_RDONLY}; only defined on GNU. + @end deftypevr + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment GNU + @deftypevr Macro int O_WRITE + Open the file for writing. Same as @code{O_WRONLY}; only defined on GNU. + @end deftypevr + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment GNU + @deftypevr Macro int O_EXEC + Open the file for executing. Only defined on GNU. +@@ -3045,7 +3361,7 @@ + The following three file name translation flags exist only on + @gnuhurdsystems{}. + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment GNU + @deftypevr Macro int O_IGNORE_CTTY + Do not recognize the named file as the controlling terminal, even if it +@@ -3054,7 +3370,7 @@ + @xref{Job Control}. + @end deftypevr + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment GNU + @deftypevr Macro int O_NOLINK + If the named file is a symbolic link, open the link itself instead of +@@ -3063,7 +3379,7 @@ + @cindex symbolic link, opening + @end deftypevr + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment GNU + @deftypevr Macro int O_NOTRANS + If the named file is specially translated, do not invoke the translator. +@@ -3095,7 +3411,7 @@ + The remaining operating modes are BSD extensions. They exist only + on some systems. On other systems, these macros are not defined. + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment BSD + @deftypevr Macro int O_SHLOCK + Acquire a shared lock on the file, as with @code{flock}. +@@ -3106,7 +3422,7 @@ + the lock on the new file first. + @end deftypevr + +-@comment fcntl.h ++@comment fcntl.h (optional) + @comment BSD + @deftypevr Macro int O_EXLOCK + Acquire an exclusive lock on the file, as with @code{flock}. +@@ -3599,7 +4134,7 @@ + @gnusystems{} can handle most input/output operations on many different + devices and objects in terms of a few file primitives - @code{read}, + @code{write} and @code{lseek}. However, most devices also have a few +-peculiar operations which do not fit into this model. Such as: ++peculiar operations which do not fit into this model. Such as: + + @itemize @bullet + +@@ -3634,6 +4169,7 @@ + @comment sys/ioctl.h + @comment BSD + @deftypefun int ioctl (int @var{filedes}, int @var{command}, @dots{}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + The @code{ioctl} function performs the generic I/O operation + @var{command} on @var{filedes}. +@@ -3653,3 +4189,6 @@ + Most IOCTLs are OS-specific and/or only used in special system utilities, + and are thus beyond the scope of this document. For an example of the use + of an IOCTL, see @ref{Out-of-Band Data}. ++ ++@c FIXME this is undocumented: ++@c dup3 +diff -urN glibc-2.17-c758a686/manual/locale.texi glibc-2.17-c758a686/manual/locale.texi +--- glibc-2.17-c758a686/manual/locale.texi 2014-09-12 16:08:18.266069610 -0400 ++++ glibc-2.17-c758a686/manual/locale.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -231,6 +231,136 @@ + @comment locale.h + @comment ISO + @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtslocale{}} @mtsenv{}}@asunsafe{@asuinit{} @asulock{} @ascuheap{} @asucorrupt{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c Uses of the global locale object are unguarded in functions that ++@c ought to be MT-Safe, so we're ruling out the use of this function ++@c once threads are started. It takes a write lock itself, but it may ++@c return a pointer loaded from the global locale object after releasing ++@c the lock, or before taking it. ++@c setlocale @mtasuconst:@mtslocale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock ++@c libc_rwlock_wrlock @asulock @aculock ++@c libc_rwlock_unlock @aculock ++@c getenv LOCPATH @mtsenv ++@c malloc @ascuheap @acsmem ++@c free @ascuheap @acsmem ++@c new_composite_name ok ++@c setdata ok ++@c setname ok ++@c _nl_find_locale @mtsenv @asuinit @ascuheap @asulock @asucorrupt @acucorrupt @acsmem @acsfd @aculock ++@c getenv LC_ALL and LANG @mtsenv ++@c _nl_load_locale_from_archive @ascuheap @acucorrupt @acsmem @acsfd ++@c sysconf _SC_PAGE_SIZE ok ++@c _nl_normalize_codeset @ascuheap @acsmem ++@c isalnum_l ok (C locale) ++@c isdigit_l ok (C locale) ++@c malloc @ascuheap @acsmem ++@c tolower_l ok (C locale) ++@c open_not_cancel_2 @acsfd ++@c fxstat64 ok ++@c close_not_cancel_no_status ok ++@c __mmap64 @acsmem ++@c calculate_head_size ok ++@c __munmap ok ++@c compute_hashval ok ++@c qsort dup @acucorrupt ++@c rangecmp ok ++@c malloc @ascuheap @acsmem ++@c strdup @ascuheap @acsmem ++@c _nl_intern_locale_data @ascuheap @acsmem ++@c malloc @ascuheap @acsmem ++@c free @ascuheap @acsmem ++@c _nl_expand_alias @ascuheap @asulock @acsmem @acsfd @aculock ++@c libc_lock_lock @asulock @aculock ++@c bsearch ok ++@c alias_compare ok ++@c strcasecmp ok ++@c read_alias_file @ascuheap @asulock @acsmem @acsfd @aculock ++@c fopen @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking ok ++@c feof_unlocked ok ++@c fgets_unlocked ok ++@c isspace ok (locale mutex is locked) ++@c extend_alias_table @ascuheap @acsmem ++@c realloc @ascuheap @acsmem ++@c realloc @ascuheap @acsmem ++@c fclose @ascuheap @asulock @acsmem @acsfd @aculock ++@c qsort @ascuheap @acsmem ++@c alias_compare dup ++@c libc_lock_unlock @aculock ++@c _nl_explode_name @ascuheap @acsmem ++@c _nl_find_language ok ++@c _nl_normalize_codeset dup @ascuheap @acsmem ++@c _nl_make_l10nflist @ascuheap @acsmem ++@c malloc @ascuheap @acsmem ++@c free @ascuheap @acsmem ++@c __argz_stringify ok ++@c __argz_count ok ++@c __argz_next ok ++@c _nl_load_locale @ascuheap @acsmem @acsfd ++@c open_not_cancel_2 @acsfd ++@c __fxstat64 ok ++@c close_not_cancel_no_status ok ++@c mmap @acsmem ++@c malloc @ascuheap @acsmem ++@c read_not_cancel ok ++@c free @ascuheap @acsmem ++@c _nl_intern_locale_data dup @ascuheap @acsmem ++@c munmap ok ++@c __gconv_compare_alias @asuinit @ascuheap @asucorrupt @asulock @acsmem@acucorrupt @acsfd @aculock ++@c __gconv_read_conf @asuinit @ascuheap @asucorrupt @asulock @acsmem@acucorrupt @acsfd @aculock ++@c (libc_once-initializes gconv_cache and gconv_path_envvar; they're ++@c never modified afterwards) ++@c __gconv_load_cache @ascuheap @acsmem @acsfd ++@c getenv GCONV_PATH @mtsenv ++@c open_not_cancel @acsfd ++@c __fxstat64 ok ++@c close_not_cancel_no_status ok ++@c mmap @acsmem ++@c malloc @ascuheap @acsmem ++@c __read ok ++@c free @ascuheap @acsmem ++@c munmap ok ++@c __gconv_get_path @asulock @ascuheap @aculock @acsmem @acsfd ++@c getcwd @ascuheap @acsmem @acsfd ++@c libc_lock_lock @asulock @aculock ++@c malloc @ascuheap @acsmem ++@c strtok_r ok ++@c libc_lock_unlock @aculock ++@c read_conf_file @ascuheap @asucorrupt @asulock @acsmem @acucorrupt @acsfd @aculock ++@c fopen @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking ok ++@c feof_unlocked ok ++@c getdelim @ascuheap @asucorrupt @acsmem @acucorrupt ++@c isspace_l ok (C locale) ++@c add_alias ++@c isspace_l ok (C locale) ++@c toupper_l ok (C locale) ++@c add_alias2 dup @ascuheap @acucorrupt @acsmem ++@c add_module @ascuheap @acsmem ++@c isspace_l ok (C locale) ++@c toupper_l ok (C locale) ++@c strtol ok (@mtslocale but we hold the locale lock) ++@c tfind __gconv_alias_db ok ++@c __gconv_alias_compare dup ok ++@c calloc @ascuheap @acsmem ++@c insert_module dup @ascuheap ++@c __tfind ok (because the tree is read only by then) ++@c __gconv_alias_compare dup ok ++@c insert_module @ascuheap ++@c free @ascuheap ++@c add_alias2 @ascuheap @acucorrupt @acsmem ++@c detect_conflict ok, reads __gconv_modules_db ++@c malloc @ascuheap @acsmem ++@c tsearch __gconv_alias_db @ascuheap @acucorrupt @acsmem [exclusive tree, no @mtsrace] ++@c __gconv_alias_compare ok ++@c free @ascuheap ++@c __gconv_compare_alias_cache ok ++@c find_module_idx ok ++@c do_lookup_alias ok ++@c __tfind ok (because the tree is read only by then) ++@c __gconv_alias_compare ok ++@c strndup @ascuheap @acsmem ++@c strcasecmp_l ok (C locale) + The function @code{setlocale} sets the current locale for category + @var{category} to @var{locale}. + +@@ -496,6 +626,10 @@ + @comment locale.h + @comment ISO + @deftypefun {struct lconv *} localeconv (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:localeconv} @mtslocale{}}@asunsafe{}@acsafe{}} ++@c This function reads from multiple components of the locale object, ++@c without synchronization, while writing to the static buffer it uses ++@c as the return value. + The @code{localeconv} function returns a pointer to a structure whose + components contain information about how numeric and monetary values + should be formatted in the current locale. +@@ -762,6 +896,9 @@ + @comment langinfo.h + @comment XOPEN + @deftypefun {char *} nl_langinfo (nl_item @var{item}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c It calls _nl_langinfo_l with the current locale, which returns a ++@c pointer into constant strings defined in locale data structures. + The @code{nl_langinfo} function can be used to access individual + elements of the locale categories. Unlike the @code{localeconv} + function, which returns all the information, @code{nl_langinfo} +@@ -1056,6 +1193,11 @@ + numbers according to these rules. + + @deftypefun ssize_t strfmon (char *@var{s}, size_t @var{maxsize}, const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c It (and strfmon_l) both call vstrfmon_l, which, besides accessing the ++@c locale object passed to it, accesses the active locale through ++@c isdigit (but to_digit assumes ASCII digits only). It may call ++@c __printf_fp (@mtslocale @ascuheap @acsmem) and guess_grouping (safe). + The @code{strfmon} function is similar to the @code{strftime} function + in that it takes a buffer, its size, a format string, + and values to write into the buffer as text in a form specified +@@ -1267,6 +1409,10 @@ + @comment GNU + @comment stdlib.h + @deftypefun int rpmatch (const char *@var{response}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c Calls nl_langinfo with YESEXPR and NOEXPR, triggering @mtslocale but ++@c it's regcomp and regexec that bring in all of the safety issues. ++@c regfree is also called, but it doesn't introduce any further issues. + The function @code{rpmatch} checks the string in @var{response} whether + or not it is a correct yes-or-no answer and if yes, which one. The + check uses the @code{YESEXPR} and @code{NOEXPR} data in the +@@ -1318,5 +1464,5 @@ + free (line); + @end smallexample + +-Note that the loop continues until an read error is detected or until a ++Note that the loop continues until a read error is detected or until a + definitive (positive or negative) answer is read. +diff -urN glibc-2.17-c758a686/manual/macros.texi glibc-2.17-c758a686/manual/macros.texi +--- glibc-2.17-c758a686/manual/macros.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/macros.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -35,16 +35,225 @@ + GNU/Linux and GNU/Hurd systems + @end macro + +-@c Descrption applying to GNU/Hurd systems; that is, systems using the ++@c Description applying to GNU/Hurd systems; that is, systems using the + @c GNU Hurd with the GNU C Library. + @macro gnuhurdsystems + GNU/Hurd systems + @end macro + +-@c Descrption applying to GNU/Linux systems; that is, systems using ++@c Description applying to GNU/Linux systems; that is, systems using + @c the Linux kernel with the GNU C Library. + @macro gnulinuxsystems + GNU/Linux systems + @end macro + ++@c Document the safety functions as preliminary. It does NOT expand its ++@c comments. ++@macro prelim {comments} ++Preliminary: ++ ++@end macro ++@c Document a function as thread safe. ++@macro mtsafe {comments} ++| MT-Safe \comments\ ++ ++@end macro ++@c Document a function as thread unsafe. ++@macro mtunsafe {comments} ++| MT-Unsafe \comments\ ++ ++@end macro ++@c Document a function as safe for use in asynchronous signal handlers. ++@macro assafe {comments} ++| AS-Safe \comments\ ++ ++@end macro ++@c Document a function as unsafe for use in asynchronous signal ++@c handlers. This distinguishes unmarked functions, for which this ++@c property has not been assessed, from those that have been analyzed. ++@macro asunsafe {comments} ++| AS-Unsafe \comments\ ++ ++@end macro ++@c Document a function as safe for use when asynchronous cancellation is ++@c enabled. ++@macro acsafe {comments} ++| AC-Safe \comments\ ++ ++@end macro ++@c Document a function as unsafe for use when asynchronous cancellation ++@c is enabled. This distinguishes unmarked functions, for which this ++@c property has not been assessed, from those that have been analyzed. ++@macro acunsafe {comments} ++| AC-Unsafe \comments\ ++ ++@end macro ++@c Format safety properties without referencing the section of the ++@c definitions. To be used in the definitions of the properties ++@c themselves. ++@macro sampsafety {notes} ++@noindent ++\notes\| ++ ++ ++@end macro ++@c Format the safety properties of a function. ++@macro safety {notes} ++\notes\| @xref{POSIX Safety Concepts}. ++ ++ ++@end macro ++@c Function is MT- and AS-Unsafe due to an internal race. ++@macro mtasurace {comments} ++race\comments\ ++@end macro ++@c Function is AS-Unsafe due to an internal race. ++@macro asurace {comments} ++race\comments\ ++@end macro ++@c Function is MT-Safe, but with potential race on user-supplied object ++@c of opaque type. ++@macro mtsrace {comments} ++race\comments\ ++@end macro ++@c Function is MT- and AS-Unsafe for modifying an object that is decreed ++@c MT-constant due to MT-Unsafe accesses elsewhere. ++@macro mtasuconst {comments} ++const\comments\ ++@end macro ++@c Function accesses the assumed-constant locale object. ++@macro mtslocale {comments} ++locale\comments\ ++@end macro ++@c Function accesses the assumed-constant environment. ++@macro mtsenv {comments} ++env\comments\ ++@end macro ++@c Function accesses the assumed-constant hostid. ++@macro mtshostid {comments} ++hostid\comments\ ++@end macro ++@c Function accesses the assumed-constant _sigintr variable. ++@macro mtssigintr {comments} ++sigintr\comments\ ++@end macro ++@c Function performs MT-Unsafe initialization at the first call. ++@macro mtuinit {comments} ++init\comments\ ++@end macro ++@c Function performs libc_once AS-Unsafe initialization. ++@macro asuinit {comments} ++init\comments\ ++@end macro ++@c Function performs libc_once AC-Unsafe initialization. ++@macro acuinit {comments} ++init\comments\ ++@end macro ++@c Function is AS-Unsafe because it takes a non-recursive mutex that may ++@c already be held by the function interrupted by the signal. ++@macro asulock {comments} ++lock\comments\ ++@end macro ++@c Function is AC-Unsafe because it may fail to release a mutex. ++@macro aculock {comments} ++lock\comments\ ++@end macro ++@c Function is AS-Unsafe because some data structure may be inconsistent ++@c due to an ongoing updated interrupted by a signal. ++@macro asucorrupt {comments} ++corrupt\comments\ ++@end macro ++@c Function is AC-Unsafe because some data structure may be left ++@c inconsistent when cancelled. ++@macro acucorrupt {comments} ++corrupt\comments\ ++@end macro ++@c Function is AS- and AC-Unsafe because of malloc/free. ++@macro ascuheap {comments} ++heap\comments\ ++@end macro ++@c Function is AS-Unsafe because of malloc/free. ++@macro asuheap {comments} ++heap\comments\ ++@end macro ++@c Function is AS- and AC-Unsafe because of dlopen/dlclose. ++@macro ascudlopen {comments} ++dlopen\comments\ ++@end macro ++@c Function is AS- and AC-Unsafe because of unknown plugins. ++@macro ascuplugin {comments} ++plugin\comments\ ++@end macro ++@c Function is AS- and AC-Unsafe because of i18n. ++@macro ascuintl {comments} ++i18n\comments\ ++@end macro ++@c Function is AS--Unsafe because of i18n. ++@macro asuintl {comments} ++i18n\comments\ ++@end macro ++@c Function may leak file descriptors if async-cancelled. ++@macro acsfd {comments} ++fd\comments\ ++@end macro ++@c Function may leak memory if async-cancelled. ++@macro acsmem {comments} ++mem\comments\ ++@end macro ++@c Function is unsafe due to temporary overriding a signal handler. ++@macro mtascusig {comments} ++sig\comments\ ++@end macro ++@c Function is MT- and AS-Unsafe due to temporarily changing attributes ++@c of the controlling terminal. ++@macro mtasuterm {comments} ++term\comments\ ++@end macro ++@c Function is AC-Unsafe for failing to restore attributes of the ++@c controlling terminal. ++@macro acuterm {comments} ++term\comments\ ++@end macro ++@c Function sets timers atomically. ++@macro mtstimer {comments} ++timer\comments\ ++@end macro ++@c Function sets and restores timers. ++@macro mtascutimer {comments} ++timer\comments\ ++@end macro ++@c Function temporarily changes the current working directory. ++@macro mtasscwd {comments} ++cwd\comments\ ++@end macro ++@c Function may fail to restore to the original current working ++@c directory after temporarily changing it. ++@macro acscwd {comments} ++cwd\comments\ ++@end macro ++@c Function is MT-Safe while POSIX says it needn't be MT-Safe. ++@macro mtsposix {comments} ++!posix\comments\ ++@end macro ++@c Function is MT-Unsafe while POSIX says it should be MT-Safe. ++@macro mtuposix {comments} ++!posix\comments\ ++@end macro ++@c Function is AS-Safe while POSIX says it needn't be AS-Safe. ++@macro assposix {comments} ++!posix\comments\ ++@end macro ++@c Function is AS-Unsafe while POSIX says it should be AS-Safe. ++@macro asuposix {comments} ++!posix\comments\ ++@end macro ++@c Function is AC-Safe while POSIX says it needn't be AC-Safe. ++@macro acsposix {comments} ++!posix\comments\ ++@end macro ++@c Function is AC-Unsafe while POSIX says it should be AC-Safe. ++@macro acuposix {comments} ++!posix\comments\ ++@end macro ++ + @end ifclear +diff -urN glibc-2.17-c758a686/manual/maint.texi glibc-2.17-c758a686/manual/maint.texi +--- glibc-2.17-c758a686/manual/maint.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/maint.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -316,7 +316,7 @@ + The top-level @file{configure} script uses the shell @code{.} command to + read the @file{configure} file in each system-dependent directory + chosen, in order. The @file{configure} files are often generated from +-@file{configure.in} files using Autoconf. ++@file{configure.ac} files using Autoconf. + + A system-dependent @file{configure} script will usually add things to + the shell variables @samp{DEFS} and @samp{config_vars}; see the +@@ -329,14 +329,14 @@ + just @w{@samp{--with-@var{package}}} (no argument), then it sets + @w{@samp{with_@var{package}}} to @samp{yes}. + +-@item configure.in ++@item configure.ac + + This file is an Autoconf input fragment to be processed into the file + @file{configure} in this subdirectory. @xref{Introduction,,, + autoconf.info, Autoconf: Generating Automatic Configuration Scripts}, + for a description of Autoconf. You should write either @file{configure} +-or @file{configure.in}, but not both. The first line of +-@file{configure.in} should invoke the @code{m4} macro ++or @file{configure.ac}, but not both. The first line of ++@file{configure.ac} should invoke the @code{m4} macro + @samp{GLIBC_PROVIDES}. This macro does several @code{AC_PROVIDE} calls + for Autoconf macros which are used by the top-level @file{configure} + script; without this, those macros might be invoked again unnecessarily +@@ -424,7 +424,7 @@ + files specific to those machine architectures, but not specific to any + particular operating system. There might be subdirectories for + specializations of those architectures, such as +-@w{@file{sysdeps/m68k/68020}}. Code which is specific to the ++@w{@file{sysdeps/m68k/68020}}. Code which is specific to the + floating-point coprocessor used with a particular machine should go in + @w{@file{sysdeps/@var{machine}/fpu}}. + +diff -urN glibc-2.17-c758a686/manual/Makefile glibc-2.17-c758a686/manual/Makefile +--- glibc-2.17-c758a686/manual/Makefile 2014-09-12 16:08:17.823070748 -0400 ++++ glibc-2.17-c758a686/manual/Makefile 2014-09-12 16:10:06.045792717 -0400 +@@ -1,5 +1,4 @@ +-# Copyright (C) 1992-2012 +-# Free Software Foundation, Inc. ++# Copyright (C) 1992-2014 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -20,14 +19,10 @@ + + subdir := manual + +-# Allow override +-INSTALL_INFO = install-info ++include ../Makeconfig + + .PHONY: dvi pdf info html + +-# Get glibc's configuration info. +-include ../Makeconfig +- + dvi: $(objpfx)libc.dvi + pdf: $(objpfx)libc.pdf + +@@ -42,8 +37,8 @@ + intro errno memory ctype string charset locale \ + message search pattern io stdio llio filesys \ + pipe socket terminal syslog math arith time \ +- resource setjmp signal startup process job nss \ +- users sysinfo conf crypt debug probes) ++ resource setjmp signal startup process ipc job \ ++ nss users sysinfo conf crypt debug threads probes) + add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi)) + appendices = lang.texi header.texi install.texi maint.texi platform.texi \ + contrib.texi +@@ -89,6 +84,7 @@ + $(objpfx)summary.texi: $(objpfx)stamp-summary ; + $(objpfx)stamp-summary: summary.awk $(filter-out $(objpfx)summary.texi, \ + $(texis-path)) ++ -$(SHELL) ./check-safety.sh $(filter-out $(objpfx)%, $(texis-path)) + $(AWK) -f $^ | sort -t' ' -df -k 1,1 | tr '\014' '\012' \ + > $(objpfx)summary-tmp + $(move-if-change) $(objpfx)summary-tmp $(objpfx)summary.texi +@@ -145,8 +141,7 @@ + mv -f $@.new $@ + + $(objpfx)%.info: %.texinfo +- LANGUAGE=C LC_ALL=C $(MAKEINFO) -P $(objpfx) --output=`basename $@` $< +- mv `basename $@`* $(objpfx) ++ LANGUAGE=C LC_ALL=C $(MAKEINFO) -P $(objpfx) --output=$@ $< + + $(objpfx)%.dvi: %.texinfo + cd $(objpfx);$(TEXI2DVI) -I $(shell cd $(mutex) @asulock @aculock ++@c malloc_consolidate dup ok ++@c set_max_fast ok ++@c mutex_unlock dup @aculock ++ + When calling @code{mallopt}, the @var{param} argument specifies the + parameter to be set, and @var{value} the new value to be set. Possible + choices for @var{param}, as defined in @file{malloc.h}, are: + + @table @code +-@item M_TRIM_THRESHOLD +-This is the minimum size (in bytes) of the top-most, releasable chunk +-that will cause @code{sbrk} to be called with a negative argument in +-order to return memory to the system. +-@item M_TOP_PAD +-This parameter determines the amount of extra memory to obtain from the +-system when a call to @code{sbrk} is required. It also specifies the +-number of bytes to retain when shrinking the heap by calling @code{sbrk} +-with a negative argument. This provides the necessary hysteresis in +-heap size such that excessive amounts of system calls can be avoided. ++@comment TODO: @item M_ARENA_MAX ++@comment - Document ARENA_MAX env var. ++@comment TODO: @item M_ARENA_TEST ++@comment - Document ARENA_TEST env var. ++@comment TODO: @item M_CHECK_ACTION ++@item M_MMAP_MAX ++The maximum number of chunks to allocate with @code{mmap}. Setting this ++to zero disables all use of @code{mmap}. + @item M_MMAP_THRESHOLD + All chunks larger than this value are allocated outside the normal + heap, using the @code{mmap} system call. This way it is guaranteed + that the memory for these chunks can be returned to the system on + @code{free}. Note that requests smaller than this threshold might still + be allocated via @code{mmap}. +-@item M_MMAP_MAX +-The maximum number of chunks to allocate with @code{mmap}. Setting this +-to zero disables all use of @code{mmap}. ++@comment TODO: @item M_MXFAST + @item M_PERTURB + If non-zero, memory blocks are filled with values depending on some + low order bits of this parameter when they are allocated (except when +@@ -710,6 +1140,16 @@ + guarantee that the freed block will have any specific values. It only + guarantees that the content the block had before it was freed will be + overwritten. ++@item M_TOP_PAD ++This parameter determines the amount of extra memory to obtain from the ++system when a call to @code{sbrk} is required. It also specifies the ++number of bytes to retain when shrinking the heap by calling @code{sbrk} ++with a negative argument. This provides the necessary hysteresis in ++heap size such that excessive amounts of system calls can be avoided. ++@item M_TRIM_THRESHOLD ++This is the minimum size (in bytes) of the top-most, releasable chunk ++that will cause @code{sbrk} to be called with a negative argument in ++order to return memory to the system. + @end table + + @end deftypefun +@@ -728,6 +1168,17 @@ + @comment mcheck.h + @comment GNU + @deftypefun int mcheck (void (*@var{abortfn}) (enum mcheck_status @var{status})) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@c The hooks must be set up before malloc is first used, which sort of ++@c implies @mtuinit/@asuinit but since the function is a no-op if malloc ++@c was already used, that doesn't pose any safety issues. The actual ++@c problem is with the hooks, designed for single-threaded ++@c fully-synchronous operation: they manage an unguarded linked list of ++@c allocated blocks, and get temporarily overwritten before calling the ++@c allocation functions recursively while holding the old hooks. There ++@c are no guards for thread safety, and inconsistent hooks may be found ++@c within signal handlers or left behind in case of cancellation. ++ + Calling @code{mcheck} tells @code{malloc} to perform occasional + consistency checks. These will catch things such as writing + past the end of a block that was allocated with @code{malloc}. +@@ -770,6 +1221,18 @@ + @end deftypefun + + @deftypefun {enum mcheck_status} mprobe (void *@var{pointer}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mcheck} @mtasuconst{:malloc_hooks}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@c The linked list of headers may be modified concurrently by other ++@c threads, and it may find a partial update if called from a signal ++@c handler. It's mostly read only, so cancelling it might be safe, but ++@c it will modify global state that, if cancellation hits at just the ++@c right spot, may be left behind inconsistent. This path is only taken ++@c if checkhdr finds an inconsistency. If the inconsistency could only ++@c occur because of earlier undefined behavior, that wouldn't be an ++@c additional safety issue problem, but because of the other concurrency ++@c issues in the mcheck hooks, the apparent inconsistency could be the ++@c result of mcheck's own internal data race. So, AC-Unsafe it is. ++ + The @code{mprobe} function lets you explicitly check for inconsistencies + in a particular allocated block. You must have already called + @code{mcheck} at the beginning of the program, to do its occasional +@@ -896,16 +1359,18 @@ + @comment malloc.h + @comment GNU + @defvar __memalign_hook +-The value of this variable is a pointer to function that @code{memalign} +-uses whenever it is called. You should define this function to look +-like @code{memalign}; that is, like: ++The value of this variable is a pointer to function that @code{aligned_alloc}, ++@code{memalign}, @code{posix_memalign} and @code{valloc} use whenever they ++are called. You should define this function to look like @code{aligned_alloc}; ++that is, like: + + @smallexample + void *@var{function} (size_t @var{alignment}, size_t @var{size}, const void *@var{caller}) + @end smallexample + + The value of @var{caller} is the return address found on the stack when +-the @code{memalign} function was called. This value allows you to trace the ++the @code{aligned_alloc}, @code{memalign}, @code{posix_memalign} or ++@code{valloc} functions are called. This value allows you to trace the + memory consumption of the program. + @end defvar + +@@ -1082,6 +1547,24 @@ + @comment malloc.h + @comment SVID + @deftypefun {struct mallinfo} mallinfo (void) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasuconst{:mallopt}}@asunsafe{@asuinit{} @asulock{}}@acunsafe{@acuinit{} @aculock{}}} ++@c Accessing mp_.n_mmaps and mp_.max_mmapped_mem, modified with atomics ++@c but non-atomically elsewhere, may get us inconsistent results. We ++@c mark the statistics as unsafe, rather than the fast-path functions ++@c that collect the possibly inconsistent data. ++ ++@c __libc_mallinfo @mtuinit @mtasuconst:mallopt @asuinit @asulock @aculock ++@c ptmalloc_init (once) dup @mtsenv @asulock @aculock @acsfd @acsmem ++@c mutex_lock dup @asulock @aculock ++@c int_mallinfo @mtasuconst:mallopt [mp_ access on main_arena] ++@c malloc_consolidate dup ok ++@c check_malloc_state dup ok/disabled ++@c chunksize dup ok ++@c fastbin dupo ok ++@c bin_at dup ok ++@c last dup ok ++@c mutex_unlock @aculock ++ + This function returns information about the current dynamic memory usage + in a structure of type @code{struct mallinfo}. + @end deftypefun +@@ -1112,6 +1595,14 @@ + Allocate a block of @var{size} bytes, starting on a page boundary. + @xref{Aligned Memory Blocks}. + ++@item void *aligned_alloc (size_t @var{size}, size_t @var{alignment}) ++Allocate a block of @var{size} bytes, starting on an address that is a ++multiple of @var{alignment}. @xref{Aligned Memory Blocks}. ++ ++@item int posix_memalign (void **@var{memptr}, size_t @var{alignment}, size_t @var{size}) ++Allocate a block of @var{size} bytes, starting on an address that is a ++multiple of @var{alignment}. @xref{Aligned Memory Blocks}. ++ + @item void *memalign (size_t @var{size}, size_t @var{boundary}) + Allocate a block of @var{size} bytes, starting on an address that is a + multiple of @var{boundary}. @xref{Aligned Memory Blocks}. +@@ -1134,7 +1625,8 @@ + A pointer to a function that @code{free} uses whenever it is called. + + @item void (*__memalign_hook) (size_t @var{size}, size_t @var{alignment}, const void *@var{caller}) +-A pointer to a function that @code{memalign} uses whenever it is called. ++A pointer to a function that @code{aligned_alloc}, @code{memalign}, ++@code{posix_memalign} and @code{valloc} use whenever they are called. + + @item struct mallinfo mallinfo (void) + Return information about the current dynamic memory usage. +@@ -1171,6 +1663,20 @@ + @comment mcheck.h + @comment GNU + @deftypefun void mtrace (void) ++@safety{@prelim{}@mtunsafe{@mtsenv{} @mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtuinit{}}@asunsafe{@asuinit{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Like the mcheck hooks, these are not designed with thread safety in ++@c mind, because the hook pointers are temporarily modified without ++@c regard to other threads, signals or cancellation. ++ ++@c mtrace @mtuinit @mtasurace:mtrace @mtsenv @asuinit @ascuheap @asucorrupt @acuinit @acucorrupt @aculock @acsfd @acsmem ++@c __libc_secure_getenv dup @mtsenv ++@c malloc dup @ascuheap @acsmem ++@c fopen dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c fcntl dup ok ++@c setvbuf dup @aculock ++@c fprintf dup (on newly-created stream) @aculock ++@c __cxa_atexit (once) dup @asulock @aculock @acsmem ++@c free dup @ascuheap @acsmem + When the @code{mtrace} function is called it looks for an environment + variable named @code{MALLOC_TRACE}. This variable is supposed to + contain a valid file name. The user must have write access. If the +@@ -1194,6 +1700,11 @@ + @comment mcheck.h + @comment GNU + @deftypefun void muntrace (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mtrace} @mtasuconst{:malloc_hooks} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{} @aculock{} @acsfd{}}} ++ ++@c muntrace @mtasurace:mtrace @mtslocale @asucorrupt @ascuheap @acucorrupt @acsmem @aculock @acsfd ++@c fprintf (fputs) dup @mtslocale @asucorrupt @ascuheap @acsmem @aculock @acucorrupt ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd + The @code{muntrace} function can be called after @code{mtrace} was used + to enable tracing the @code{malloc} calls. If no (successful) call of + @code{mtrace} was made @code{muntrace} does nothing. +@@ -1505,6 +2016,20 @@ + @comment obstack.h + @comment GNU + @deftypefun int obstack_init (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{@acsmem{}}} ++@c obstack_init @mtsrace:obstack-ptr @acsmem ++@c _obstack_begin @acsmem ++@c chunkfun = obstack_chunk_alloc (suggested malloc) ++@c freefun = obstack_chunk_free (suggested free) ++@c *chunkfun @acsmem ++@c obstack_chunk_alloc user-supplied ++@c *obstack_alloc_failed_handler user-supplied ++@c -> print_and_abort (default) ++@c ++@c print_and_abort ++@c _ dup @ascuintl ++@c fxprintf dup @asucorrupt @aculock @acucorrupt ++@c exit @acucorrupt? + Initialize obstack @var{obstack-ptr} for allocation of objects. This + function calls the obstack's @code{obstack_chunk_alloc} function. If + allocation of memory fails, the function pointed to by +@@ -1560,6 +2085,10 @@ + @comment obstack.h + @comment GNU + @deftypefun {void *} obstack_alloc (struct obstack *@var{obstack-ptr}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_alloc @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_blank dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt + This allocates an uninitialized block of @var{size} bytes in an obstack + and returns its address. Here @var{obstack-ptr} specifies which obstack + to allocate the block in; it is the address of the @code{struct obstack} +@@ -1594,6 +2123,10 @@ + @comment obstack.h + @comment GNU + @deftypefun {void *} obstack_copy (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_copy @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_grow dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt + This allocates a block and initializes it by copying @var{size} + bytes of data starting at @var{address}. It calls + @code{obstack_alloc_failed_handler} if allocation of memory by +@@ -1603,6 +2136,10 @@ + @comment obstack.h + @comment GNU + @deftypefun {void *} obstack_copy0 (struct obstack *@var{obstack-ptr}, void *@var{address}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_copy0 @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_grow0 dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_finish dup @mtsrace:obstack-ptr @acucorrupt + Like @code{obstack_copy}, but appends an extra byte containing a null + character. This extra byte is not counted in the argument @var{size}. + @end deftypefun +@@ -1635,6 +2172,10 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_free (struct obstack *@var{obstack-ptr}, void *@var{object}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}} ++@c obstack_free @mtsrace:obstack-ptr @acucorrupt ++@c (obstack_free) @mtsrace:obstack-ptr @acucorrupt ++@c *freefun dup user-supplied + If @var{object} is a null pointer, everything allocated in the obstack + is freed. Otherwise, @var{object} must be the address of an object + allocated in the obstack. Then @var{object} is freed, along with +@@ -1739,6 +2280,13 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_blank (struct obstack *@var{obstack-ptr}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_blank @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c _obstack_newchunk @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c *chunkfun dup @acsmem ++@c *obstack_alloc_failed_handler dup user-supplied ++@c *freefun ++@c obstack_blank_fast dup @mtsrace:obstack-ptr + The most basic function for adding to a growing object is + @code{obstack_blank}, which adds space without initializing it. + @end deftypefun +@@ -1746,6 +2294,10 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_grow (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_grow @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c memcpy ok + To add a block of initialized space, use @code{obstack_grow}, which is + the growing-object analogue of @code{obstack_copy}. It adds @var{size} + bytes of data to the growing object, copying the contents from +@@ -1755,6 +2307,12 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_grow0 (struct obstack *@var{obstack-ptr}, void *@var{data}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_grow0 @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c (no sequence point between storing NUL and incrementing next_free) ++@c (multiple changes to next_free => @acucorrupt) ++@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c memcpy ok + This is the growing-object analogue of @code{obstack_copy0}. It adds + @var{size} bytes copied from @var{data}, followed by an additional null + character. +@@ -1763,6 +2321,10 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_1grow (struct obstack *@var{obstack-ptr}, char @var{c}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_1grow @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_1grow_fast dup @mtsrace:obstack-ptr @acucorrupt @acsmem + To add one character at a time, use the function @code{obstack_1grow}. + It adds a single byte containing @var{c} to the growing object. + @end deftypefun +@@ -1770,6 +2332,10 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_ptr_grow (struct obstack *@var{obstack-ptr}, void *@var{data}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_ptr_grow @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_ptr_grow_fast dup @mtsrace:obstack-ptr + Adding the value of a pointer one can use the function + @code{obstack_ptr_grow}. It adds @code{sizeof (void *)} bytes + containing the value of @var{data}. +@@ -1778,6 +2344,10 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_int_grow (struct obstack *@var{obstack-ptr}, int @var{data}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_int_grow @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c _obstack_newchunk dup @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c obstack_int_grow_fast dup @mtsrace:obstack-ptr + A single value of type @code{int} can be added by using the + @code{obstack_int_grow} function. It adds @code{sizeof (int)} bytes to + the growing object and initializes them with the value of @var{data}. +@@ -1786,6 +2356,8 @@ + @comment obstack.h + @comment GNU + @deftypefun {void *} obstack_finish (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{}}} ++@c obstack_finish @mtsrace:obstack-ptr @acucorrupt + When you are finished growing the object, use the function + @code{obstack_finish} to close it off and return its final address. + +@@ -1805,6 +2377,7 @@ + @comment obstack.h + @comment GNU + @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}} + This function returns the current size of the growing object, in bytes. + Remember to call this function @emph{before} finishing the object. + After it is finished, @code{obstack_object_size} will return zero. +@@ -1848,6 +2421,7 @@ + @comment obstack.h + @comment GNU + @deftypefun int obstack_room (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}} + This returns the number of bytes that can be added safely to the current + growing object (or to an object about to be started) in obstack + @var{obstack} using the fast growth functions. +@@ -1859,6 +2433,9 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_1grow_fast (struct obstack *@var{obstack-ptr}, char @var{c}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c obstack_1grow_fast @mtsrace:obstack-ptr @acucorrupt @acsmem ++@c (no sequence point between copying c and incrementing next_free) + The function @code{obstack_1grow_fast} adds one byte containing the + character @var{c} to the growing object in obstack @var{obstack-ptr}. + @end deftypefun +@@ -1866,6 +2443,8 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_ptr_grow_fast (struct obstack *@var{obstack-ptr}, void *@var{data}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}} ++@c obstack_ptr_grow_fast @mtsrace:obstack-ptr + The function @code{obstack_ptr_grow_fast} adds @code{sizeof (void *)} + bytes containing the value of @var{data} to the growing object in + obstack @var{obstack-ptr}. +@@ -1874,6 +2453,8 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_int_grow_fast (struct obstack *@var{obstack-ptr}, int @var{data}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}} ++@c obstack_int_grow_fast @mtsrace:obstack-ptr + The function @code{obstack_int_grow_fast} adds @code{sizeof (int)} bytes + containing the value of @var{data} to the growing object in obstack + @var{obstack-ptr}. +@@ -1882,6 +2463,8 @@ + @comment obstack.h + @comment GNU + @deftypefun void obstack_blank_fast (struct obstack *@var{obstack-ptr}, int @var{size}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}} ++@c obstack_blank_fast @mtsrace:obstack-ptr + The function @code{obstack_blank_fast} adds @var{size} bytes to the + growing object in obstack @var{obstack-ptr} without initializing them. + @end deftypefun +@@ -1909,7 +2492,7 @@ + int room = obstack_room (obstack); + if (room == 0) + @{ +- /* @r{Not enough room. Add one character slowly,} ++ /* @r{Not enough room. Add one character slowly,} + @r{which may copy to a new chunk and make room.} */ + obstack_1grow (obstack, *ptr++); + len--; +@@ -1940,6 +2523,7 @@ + @comment obstack.h + @comment GNU + @deftypefun {void *} obstack_base (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}} + This function returns the tentative address of the beginning of the + currently growing object in @var{obstack-ptr}. If you finish the object + immediately, it will have that address. If you make it larger first, it +@@ -1953,6 +2537,7 @@ + @comment obstack.h + @comment GNU + @deftypefun {void *} obstack_next_free (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acsafe{}} + This function returns the address of the first free byte in the current + chunk of obstack @var{obstack-ptr}. This is the end of the currently + growing object. If no object is growing, @code{obstack_next_free} +@@ -1962,6 +2547,8 @@ + @comment obstack.h + @comment GNU + @deftypefun int obstack_object_size (struct obstack *@var{obstack-ptr}) ++@c dup ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack-ptr}}@assafe{}@acsafe{}} + This function returns the size in bytes of the currently growing object. + This is equivalent to + +@@ -1986,6 +2573,7 @@ + @comment obstack.h + @comment GNU + @deftypefn Macro int obstack_alignment_mask (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The value is a bit mask; a bit that is 1 indicates that the corresponding + bit in the address of an object should be 0. The mask value should be one + less than a power of 2; the effect is that all object addresses are +@@ -2053,6 +2641,7 @@ + @comment obstack.h + @comment GNU + @deftypefn Macro int obstack_chunk_size (struct obstack *@var{obstack-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This returns the chunk size of the given obstack. + @end deftypefn + +@@ -2172,6 +2761,7 @@ + @comment stdlib.h + @comment GNU, BSD + @deftypefun {void *} alloca (size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The return value of @code{alloca} is the address of a block of @var{size} + bytes of memory, allocated in the stack frame of the calling function. + @end deftypefun +@@ -2354,6 +2944,7 @@ + @comment unistd.h + @comment BSD + @deftypefun int brk (void *@var{addr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{brk} sets the high end of the calling process' data segment to + @var{addr}. +@@ -2396,6 +2987,8 @@ + @comment unistd.h + @comment BSD + @deftypefun void *sbrk (ptrdiff_t @var{delta}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++ + This function is the same as @code{brk} except that you specify the new + end of the data segment as an offset @var{delta} from the current end + and on success the return value is the address of the resulting end of +@@ -2535,6 +3128,7 @@ + @comment sys/mman.h + @comment POSIX.1b + @deftypefun int mlock (const void *@var{addr}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{mlock} locks a range of the calling process' virtual pages. + +@@ -2588,6 +3182,7 @@ + @comment sys/mman.h + @comment POSIX.1b + @deftypefun int munlock (const void *@var{addr}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{munlock} unlocks a range of the calling process' virtual pages. + +@@ -2600,6 +3195,7 @@ + @comment sys/mman.h + @comment POSIX.1b + @deftypefun int mlockall (int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{mlockall} locks all the pages in a process' virtual memory address + space, and/or any that are added to it in the future. This includes the +@@ -2676,6 +3272,7 @@ + @comment sys/mman.h + @comment POSIX.1b + @deftypefun int munlockall (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{munlockall} unlocks every page in the calling process' virtual + address space and turn off @code{MCL_FUTURE} future locking mode. +diff -urN glibc-2.17-c758a686/manual/message.texi glibc-2.17-c758a686/manual/message.texi +--- glibc-2.17-c758a686/manual/message.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/message.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -2,9 +2,9 @@ + @c %MENU% How to make the program speak the user's language + @chapter Message Translation + +-The program's interface with the human should be designed in a way to +-ease the human the task. One of the possibilities is to use messages in +-whatever language the user prefers. ++The program's interface with the user should be designed to ease the user's ++task. One way to ease the user's task is to use messages in whatever ++language the user prefers. + + Printing messages in different languages can be implemented in different + ways. One could add all the different languages in the source code and +@@ -40,7 +40,7 @@ + @end itemize + + The two approaches mainly differ in the implementation of this last +-step. The design decisions made for this influences the whole rest. ++step. Decisions made in the last step influence the rest of the design. + + @menu + * Message catalogs a la X/Open:: The @code{catgets} family of functions. +@@ -86,7 +86,32 @@ + @comment nl_types.h + @comment X/Open + @deftypefun nl_catd catopen (const char *@var{cat_name}, int @var{flag}) +-The @code{catgets} function tries to locate the message data file names ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c catopen @mtsenv @ascuheap @acsmem ++@c strchr ok ++@c setlocale(,NULL) ok ++@c getenv @mtsenv ++@c strlen ok ++@c alloca ok ++@c stpcpy ok ++@c malloc @ascuheap @acsmem ++@c __open_catalog @ascuheap @acsmem ++@c strchr ok ++@c open_not_cancel_2 @acsfd ++@c strlen ok ++@c ENOUGH ok ++@c alloca ok ++@c memcpy ok ++@c fxstat64 ok ++@c __set_errno ok ++@c mmap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c read_not_cancel ok ++@c free dup @ascuheap @acsmem ++@c munmap ok ++@c close_not_cancel_no_status ok ++@c free @ascuheap @acsmem ++The @code{catopen} function tries to locate the message data file names + @var{cat_name} and loads it when found. The return value is of an + opaque type and can be used in calls to the other functions to refer to + this loaded catalog. +@@ -243,6 +268,7 @@ + + + @deftypefun {char *} catgets (nl_catd @var{catalog_desc}, int @var{set}, int @var{message}, const char *@var{string}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{catgets} has to be used to access the massage catalog + previously opened using the @code{catopen} function. The + @var{catalog_desc} parameter must be a value previously returned by +@@ -281,6 +307,11 @@ + Usage}). + + @deftypefun int catclose (nl_catd @var{catalog_desc}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c catclose @ascuheap @acucorrupt @acsmem ++@c __set_errno ok ++@c munmap ok ++@c free @ascuheap @acsmem + The @code{catclose} function can be used to free the resources + associated with a message catalog which previously was opened by a call + to @code{catopen}. If the resources can be successfully freed the +@@ -803,12 +834,14 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} gettext (const char *@var{msgid}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Wrapper for dcgettext. + The @code{gettext} function searches the currently selected message + catalogs for a string which is equal to @var{msgid}. If there is such a + string available it is returned. Otherwise the argument string + @var{msgid} is returned. + +-Please note that all though the return value is @code{char *} the ++Please note that although the return value is @code{char *} the + returned string must not be changed. This broken type results from the + history of the function and does not reflect the way the function should + be used. +@@ -850,6 +883,8 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} dgettext (const char *@var{domainname}, const char *@var{msgid}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Wrapper for dcgettext. + The @code{dgettext} functions acts just like the @code{gettext} + function. It only takes an additional first argument @var{domainname} + which guides the selection of the message catalogs which are searched +@@ -864,6 +899,102 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} dcgettext (const char *@var{domainname}, const char *@var{msgid}, int @var{category}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c dcgettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c dcigettext @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c libc_rwlock_rdlock @asulock @aculock ++@c current_locale_name ok [protected from @mtslocale] ++@c tfind ok ++@c libc_rwlock_unlock ok ++@c plural_lookup ok ++@c plural_eval ok ++@c rawmemchr ok ++@c DETERMINE_SECURE ok, nothing ++@c strcmp ok ++@c strlen ok ++@c getcwd @ascuheap @acsmem @acsfd ++@c strchr ok ++@c stpcpy ok ++@c category_to_name ok ++@c guess_category_value @mtsenv ++@c getenv @mtsenv ++@c current_locale_name dup ok [protected from @mtslocale by dcigettext] ++@c strcmp ok ++@c ENABLE_SECURE ok ++@c _nl_find_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c libc_rwlock_rdlock dup @asulock @aculock ++@c _nl_make_l10nflist dup @ascuheap @acsmem ++@c libc_rwlock_unlock dup ok ++@c _nl_load_domain @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock_recursive @aculock ++@c libc_lock_unlock_recursive @aculock ++@c open->open_not_cancel_2 @acsfd ++@c fstat ok ++@c mmap dup @acsmem ++@c close->close_not_cancel_no_status @acsfd ++@c malloc dup @ascuheap @acsmem ++@c read->read_not_cancel ok ++@c munmap dup @acsmem ++@c W dup ok ++@c strlen dup ok ++@c get_sysdep_segment_value ok ++@c memcpy dup ok ++@c hash_string dup ok ++@c free dup @ascuheap @acsmem ++@c libc_rwlock_init ok ++@c _nl_find_msg dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c libc_rwlock_fini ok ++@c EXTRACT_PLURAL_EXPRESSION @ascuheap @acsmem ++@c strstr dup ok ++@c isspace ok ++@c strtoul ok ++@c PLURAL_PARSE @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c INIT_GERMANIC_PLURAL ok, nothing ++@c the pre-C99 variant is @acucorrupt [protected from @mtuinit by dcigettext] ++@c _nl_expand_alias dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c _nl_explode_name dup @ascuheap @acsmem ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c free dup @asulock @aculock @acsfd @acsmem ++@c _nl_find_msg @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c _nl_load_domain dup @mtsenv @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsfd @acsmem ++@c strlen ok ++@c hash_string ok ++@c W ok ++@c SWAP ok ++@c bswap_32 ok ++@c strcmp ok ++@c get_output_charset @mtsenv @ascuheap @acsmem ++@c getenv dup @mtsenv ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c libc_rwlock_rdlock dup @asulock @aculock ++@c libc_rwlock_unlock dup ok ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c realloc @ascuheap @acsmem ++@c strdup @ascuheap @acsmem ++@c strstr ok ++@c strcspn ok ++@c mempcpy dup ok ++@c norm_add_slashes dup ok ++@c gconv_open @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c [protected from @mtslocale by dcigettext locale lock] ++@c free dup @ascuheap @acsmem ++@c libc_lock_lock @asulock @aculock ++@c calloc @ascuheap @acsmem ++@c gconv dup @acucorrupt [protected from @mtsrace and @asucorrupt by lock] ++@c libc_lock_unlock ok ++@c malloc @ascuheap @acsmem ++@c mempcpy ok ++@c memcpy ok ++@c strcpy ok ++@c libc_rwlock_wrlock @asulock @aculock ++@c tsearch @ascuheap @acucorrupt @acsmem [protected from @mtsrace and @asucorrupt] ++@c transcmp ok ++@c strmp dup ok ++@c free @ascuheap @acsmem + The @code{dcgettext} adds another argument to those which + @code{dgettext} takes. This argument @var{category} specifies the last + piece of information needed to localize the message catalog. I.e., the +@@ -967,7 +1098,7 @@ + second best choice to fall back on the language of the developer and + simply not translate any message. Instead a user might be better able + to read the messages in another language and so the user of the program +-should be able to define an precedence order of languages. ++should be able to define a precedence order of languages. + @end itemize + + We can divide the configuration actions in two parts: the one is +@@ -988,6 +1119,13 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} textdomain (const char *@var{domainname}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} ++@c textdomain @asulock @ascuheap @aculock @acsmem ++@c libc_rwlock_wrlock @asulock @aculock ++@c strcmp ok ++@c strdup @ascuheap @acsmem ++@c free @ascuheap @acsmem ++@c libc_rwlock_unlock ok + The @code{textdomain} function sets the default domain, which is used in + all future @code{gettext} calls, to @var{domainname}. Please note that + @code{dgettext} and @code{dcgettext} calls are not influenced if the +@@ -1019,6 +1157,14 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} bindtextdomain (const char *@var{domainname}, const char *@var{dirname}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c bindtextdomain @ascuheap @acsmem ++@c set_binding_values @ascuheap @acsmem ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c strcmp dup ok ++@c strdup dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem + The @code{bindtextdomain} function can be used to specify the directory + which contains the message catalogs for domain @var{domainname} for the + different languages. To be correct, this is the directory where the +@@ -1114,7 +1260,7 @@ + extended @code{gettext} interface should be used. + + These extra functions are taking instead of the one key string two +-strings and an numerical argument. The idea behind this is that using ++strings and a numerical argument. The idea behind this is that using + the numerical argument and the first string as a key, the implementation + can select using rules specified by the translator the right plural + form. The two string arguments then will be used to provide a return +@@ -1134,6 +1280,8 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} ngettext (const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Wrapper for dcngettext. + The @code{ngettext} function is similar to the @code{gettext} function + as it finds the message catalogs in the same way. But it takes two + extra arguments. The @var{msgid1} parameter must contain the singular +@@ -1157,6 +1305,8 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} dngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Wrapper for dcngettext. + The @code{dngettext} is similar to the @code{dgettext} function in the + way the message catalog is selected. The difference is that it takes + two extra parameter to provide the correct plural form. These two +@@ -1166,6 +1316,8 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} dcngettext (const char *@var{domain}, const char *@var{msgid1}, const char *@var{msgid2}, unsigned long int @var{n}, int @var{category}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Wrapper for dcigettext. + The @code{dcngettext} is similar to the @code{dcgettext} function in the + way the message catalog is selected. The difference is that it takes + two extra parameter to provide the correct plural form. These two +@@ -1422,6 +1574,9 @@ + @comment libintl.h + @comment GNU + @deftypefun {char *} bind_textdomain_codeset (const char *@var{domainname}, const char *@var{codeset}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c bind_textdomain_codeset @ascuheap @acsmem ++@c set_binding_values dup @ascuheap @acsmem + The @code{bind_textdomain_codeset} function can be used to specify the + output character set for message catalogs for domain @var{domainname}. + The @var{codeset} argument must be a valid codeset name which can be used +@@ -1429,7 +1584,7 @@ + + If the @var{codeset} parameter is the null pointer, + @code{bind_textdomain_codeset} returns the currently selected codeset +-for the domain with the name @var{domainname}. It returns @code{NULL} if ++for the domain with the name @var{domainname}. It returns @code{NULL} if + no codeset has yet been selected. + + The @code{bind_textdomain_codeset} function can be used several times. +@@ -1441,7 +1596,8 @@ + allocated internally in the function and must not be changed by the + user. If the system went out of core during the execution of + @code{bind_textdomain_codeset}, the return value is @code{NULL} and the +-global variable @var{errno} is set accordingly. @end deftypefun ++global variable @var{errno} is set accordingly. ++@end deftypefun + + + @node GUI program problems +diff -urN glibc-2.17-c758a686/manual/nss.texi glibc-2.17-c758a686/manual/nss.texi +--- glibc-2.17-c758a686/manual/nss.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/nss.texi 2014-09-12 16:10:25.996741462 -0400 +@@ -10,7 +10,7 @@ + using files (e.g., @file{/etc/passwd}), but other nameservices (like the + Network Information Service (NIS) and the Domain Name Service (DNS)) + became popular, and were hacked into the C library, usually with a fixed +-search order (@pxref{frobnicate, , ,jargon, The Jargon File}). ++search order. + + @Theglibc{} contains a cleaner solution of this problem. It is + designed after a method used by Sun Microsystems in the C library of +diff -urN glibc-2.17-c758a686/manual/pattern.texi glibc-2.17-c758a686/manual/pattern.texi +--- glibc-2.17-c758a686/manual/pattern.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/pattern.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -28,6 +28,38 @@ + @comment fnmatch.h + @comment POSIX.2 + @deftypefun int fnmatch (const char *@var{pattern}, const char *@var{string}, int @var{flags}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c fnmatch @mtsenv @mtslocale @ascuheap @acsmem ++@c strnlen dup ok ++@c mbsrtowcs ++@c memset dup ok ++@c malloc dup @ascuheap @acsmem ++@c mbsinit dup ok ++@c free dup @ascuheap @acsmem ++@c FCT = internal_fnwmatch @mtsenv @mtslocale @ascuheap @acsmem ++@c FOLD @mtslocale ++@c towlower @mtslocale ++@c EXT @mtsenv @mtslocale @ascuheap @acsmem ++@c STRLEN = wcslen dup ok ++@c getenv @mtsenv ++@c malloc dup @ascuheap @acsmem ++@c MEMPCPY = wmempcpy dup ok ++@c FCT dup @mtsenv @mtslocale @ascuheap @acsmem ++@c STRCAT = wcscat dup ok ++@c free dup @ascuheap @acsmem ++@c END @mtsenv ++@c getenv @mtsenv ++@c MEMCHR = wmemchr dup ok ++@c getenv @mtsenv ++@c IS_CHAR_CLASS = is_char_class @mtslocale ++@c wctype @mtslocale ++@c BTOWC ok ++@c ISWCTYPE ok ++@c auto findidx dup ok ++@c elem_hash dup ok ++@c memcmp dup ok ++@c collseq_table_lookup dup ok ++@c NO_LEADING_PERIOD ok + This function tests whether the string @var{string} matches the pattern + @var{pattern}. It returns @code{0} if they do match; otherwise, it + returns the nonzero value @code{FNM_NOMATCH}. The arguments +@@ -36,11 +68,8 @@ + The argument @var{flags} is a combination of flag bits that alter the + details of matching. See below for a list of the defined flags. + +-In @theglibc{}, @code{fnmatch} cannot experience an ``error''---it +-always returns an answer for whether the match succeeds. However, other +-implementations of @code{fnmatch} might sometimes report ``errors''. +-They would do so by returning nonzero values that are not equal to +-@code{FNM_NOMATCH}. ++In @theglibc{}, @code{fnmatch} might sometimes report ``errors'' by ++returning nonzero values that are not equal to @code{FNM_NOMATCH}. + @end deftypefun + + These are the available flags for the @var{flags} argument: +@@ -234,6 +263,12 @@ + (*) (const char *,} @w{struct stat *)}}. + + This is a GNU extension. ++ ++@item gl_flags ++The flags used when @code{glob} was called. In addition, @code{GLOB_MAGCHAR} ++might be set. See @ref{Flags for Globbing} for more details. ++ ++This is a GNU extension. + @end table + @end deftp + +@@ -312,12 +347,75 @@ + (*) (const char *,} @w{struct stat64 *)}}. + + This is a GNU extension. ++ ++@item gl_flags ++The flags used when @code{glob} was called. In addition, @code{GLOB_MAGCHAR} ++might be set. See @ref{Flags for Globbing} for more details. ++ ++This is a GNU extension. + @end table + @end deftp + + @comment glob.h + @comment POSIX.2 + @deftypefun int glob (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob_t *@var{vector-ptr}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c glob @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c strlen dup ok ++@c strchr dup ok ++@c malloc dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c next_brace_sub ok ++@c free dup @ascuheap @acsmem ++@c globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c glob_pattern_p ok ++@c glob_pattern_type dup ok ++@c getenv dup @mtsenv ++@c GET_LOGIN_NAME_MAX ok ++@c getlogin_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c GETPW_R_SIZE_MAX ok ++@c getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c memchr dup ok ++@c *pglob->gl_stat user-supplied ++@c stat64 dup ok ++@c S_ISDIR dup ok ++@c strdup dup @ascuheap @acsmem ++@c glob_pattern_type ok ++@c glob_in_dir @mtsenv @mtslocale @asucorrupt @ascuheap @acucorrupt @acsfd @acsmem ++@c strlen dup ok ++@c glob_pattern_type dup ok ++@c malloc dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c *pglob->gl_stat user-supplied ++@c stat64 dup ok ++@c free dup @ascuheap @acsmem ++@c *pglob->gl_opendir user-supplied ++@c opendir dup @ascuheap @acsmem @acsfd ++@c dirfd dup ok ++@c *pglob->gl_readdir user-supplied ++@c CONVERT_DIRENT_DIRENT64 ok ++@c readdir64 ok [protected by exclusive use of the stream] ++@c REAL_DIR_ENTRY ok ++@c DIRENT_MIGHT_BE_DIR ok ++@c fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem ++@c DIRENT_MIGHT_BE_SYMLINK ok ++@c link_exists_p ok ++@c link_exists2_p ok ++@c strlen dup ok ++@c mempcpy dup ok ++@c *pglob->gl_stat user-supplied ++@c fxstatat64 dup ok ++@c realloc dup @ascuheap @acsmem ++@c pglob->gl_closedir user-supplied ++@c closedir @ascuheap @acsmem @acsfd ++@c prefix_array dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c strcpy dup ok + The function @code{glob} does globbing using the pattern @var{pattern} + in the current directory. It puts the result in a newly allocated + vector, and stores the size and address of this vector into +@@ -389,6 +487,8 @@ + @comment glob.h + @comment GNU + @deftypefun int glob64 (const char *@var{pattern}, int @var{flags}, int (*@var{errfunc}) (const char *@var{filename}, int @var{error-code}), glob64_t *@var{vector-ptr}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Same code as glob, but with glob64_t #defined as glob_t. + The @code{glob64} function was added as part of the Large File Summit + extensions but is not part of the original LFS proposal. The reason for + this is simple: it is not necessary. The necessity for a @code{glob64} +@@ -408,10 +508,12 @@ + @node Flags for Globbing + @subsection Flags for Globbing + +-This section describes the flags that you can specify in the ++This section describes the standard flags that you can specify in the + @var{flags} argument to @code{glob}. Choose the flags you want, + and combine them with the C bitwise OR operator @code{|}. + ++Note that there are @ref{More Flags for Globbing} available as GNU extensions. ++ + @vtable @code + @comment glob.h + @comment POSIX.2 +@@ -481,13 +583,6 @@ + + @comment glob.h + @comment POSIX.2 +-@item GLOB_NOSORT +-Don't sort the file names; return them in no particular order. +-(In practice, the order will depend on the order of the entries in +-the directory.) The only reason @emph{not} to sort is to save time. +- +-@comment glob.h +-@comment POSIX.2 + @item GLOB_NOESCAPE + Don't treat the @samp{\} character specially in patterns. Normally, + @samp{\} quotes the following character, turning off its special meaning +@@ -500,6 +595,13 @@ + @code{glob} does its work by calling the function @code{fnmatch} + repeatedly. It handles the flag @code{GLOB_NOESCAPE} by turning on the + @code{FNM_NOESCAPE} flag in calls to @code{fnmatch}. ++ ++@comment glob.h ++@comment POSIX.2 ++@item GLOB_NOSORT ++Don't sort the file names; return them in no particular order. ++(In practice, the order will depend on the order of the entries in ++the directory.) The only reason @emph{not} to sort is to save time. + @end vtable + + @node More Flags for Globbing +@@ -651,6 +753,9 @@ + @comment glob.h + @comment POSIX.2 + @deftypefun void globfree (glob_t *@var{pglob}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c globfree dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c free dup @ascuheap @acsmem + The @code{globfree} function frees all resources allocated by previous + calls to @code{glob} associated with the object pointed to by + @var{pglob}. This function should be called whenever the currently used +@@ -660,6 +765,7 @@ + @comment glob.h + @comment GNU + @deftypefun void globfree64 (glob64_t *@var{pglob}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} + This function is equivalent to @code{globfree} but it frees records of + type @code{glob64_t} which were allocated by @code{glob64}. + @end deftypefun +@@ -722,6 +828,250 @@ + @comment regex.h + @comment POSIX.2 + @deftypefun int regcomp (regex_t *restrict @var{compiled}, const char *restrict @var{pattern}, int @var{cflags}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c All of the issues have to do with memory allocation and multi-byte ++@c character handling present in the input string, or implied by ranges ++@c or inverted character classes. ++@c (re_)malloc @ascuheap @acsmem ++@c re_compile_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c (re_)realloc @ascuheap @acsmem [no @asucorrupt @acucorrupt for we zero the buffer] ++@c init_dfa @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c (re_)malloc @ascuheap @acsmem ++@c calloc @ascuheap @acsmem ++@c _NL_CURRENT ok ++@c _NL_CURRENT_WORD ok ++@c btowc @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c libc_lock_init ok ++@c re_string_construct @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_construct_common ok ++@c re_string_realloc_buffers @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c build_wcs_upper_buffer @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c isascii ok ++@c mbsinit ok ++@c toupper ok ++@c mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c iswlower @mtslocale ++@c towupper @mtslocale ++@c wcrtomb dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c (re_)malloc dup @ascuheap @acsmem ++@c build_upper_buffer ok (@mtslocale but optimized) ++@c islower ok ++@c toupper ok ++@c build_wcs_buffer @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_translate_buffer ok ++@c parse @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c fetch_token @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c peek_token @mtslocale ++@c re_string_eoi ok ++@c re_string_peek_byte ok ++@c re_string_cur_idx ok ++@c re_string_length ok ++@c re_string_peek_byte_case @mtslocale ++@c re_string_peek_byte dup ok ++@c re_string_is_single_byte_char ok ++@c isascii ok ++@c re_string_peek_byte dup ok ++@c re_string_wchar_at ok ++@c re_string_skip_bytes ok ++@c re_string_skip_bytes dup ok ++@c parse_reg_exp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c parse_branch @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c parse_expression @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c create_token_tree dup @ascuheap @acsmem ++@c re_string_eoi dup ok ++@c re_string_first_byte ok ++@c fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c create_tree dup @ascuheap @acsmem ++@c parse_sub_exp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c parse_reg_exp dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c postorder() @ascuheap @acsmem ++@c free_tree @ascuheap @acsmem ++@c free_token dup @ascuheap @acsmem ++@c create_tree dup @ascuheap @acsmem ++@c parse_bracket_exp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c _NL_CURRENT dup ok ++@c _NL_CURRENT_WORD dup ok ++@c calloc dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c peek_token_bracket ok ++@c re_string_eoi dup ok ++@c re_string_peek_byte dup ok ++@c re_string_first_byte dup ok ++@c re_string_cur_idx dup ok ++@c re_string_length dup ok ++@c re_string_skip_bytes dup ok ++@c bitset_set ok ++@c re_string_skip_bytes ok ++@c parse_bracket_element @mtslocale ++@c re_string_char_size_at ok ++@c re_string_wchar_at dup ok ++@c re_string_skip_bytes dup ok ++@c parse_bracket_symbol @mtslocale ++@c re_string_eoi dup ok ++@c re_string_fetch_byte_case @mtslocale ++@c re_string_fetch_byte ok ++@c re_string_first_byte dup ok ++@c isascii ok ++@c re_string_char_size_at dup ok ++@c re_string_skip_bytes dup ok ++@c re_string_fetch_byte dup ok ++@c re_string_peek_byte dup ok ++@c re_string_skip_bytes dup ok ++@c peek_token_bracket dup ok ++@c auto build_range_exp @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c auto lookup_collation_sequence_value @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c btowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c collseq_table_lookup ok ++@c auto seek_collating_symbol_entry dup ok ++@c (re_)realloc dup @ascuheap @acsmem ++@c collseq_table_lookup dup ok ++@c bitset_set dup ok ++@c (re_)realloc dup @ascuheap @acsmem ++@c build_equiv_class @mtslocale @ascuheap @acsmem ++@c _NL_CURRENT ok ++@c auto findidx ok ++@c bitset_set dup ok ++@c (re_)realloc dup @ascuheap @acsmem ++@c auto build_collating_symbol @ascuheap @acsmem ++@c auto seek_collating_symbol_entry ok ++@c bitset_set dup ok ++@c (re_)realloc dup @ascuheap @acsmem ++@c build_charclass @mtslocale @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c bitset_set dup ok ++@c isalnum ok ++@c iscntrl ok ++@c isspace ok ++@c isalpha ok ++@c isdigit ok ++@c isprint ok ++@c isupper ok ++@c isblank ok ++@c isgraph ok ++@c ispunct ok ++@c isxdigit ok ++@c bitset_not ok ++@c bitset_mask ok ++@c create_token_tree dup @ascuheap @acsmem ++@c create_tree dup @ascuheap @acsmem ++@c free_charset dup @ascuheap @acsmem ++@c init_word_char @mtslocale ++@c isalnum ok ++@c build_charclass_op @mtslocale @ascuheap @acsmem ++@c calloc dup @ascuheap @acsmem ++@c build_charclass dup @mtslocale @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c free_charset dup @ascuheap @acsmem ++@c bitset_set dup ok ++@c bitset_not dup ok ++@c bitset_mask dup ok ++@c create_token_tree dup @ascuheap @acsmem ++@c create_tree dup @ascuheap @acsmem ++@c parse_dup_op @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_cur_idx dup ok ++@c fetch_number @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_set_index ok ++@c postorder() @ascuheap @acsmem ++@c free_tree dup @ascuheap @acsmem ++@c mark_opt_subexp ok ++@c duplicate_tree @ascuheap @acsmem ++@c create_token_tree dup @ascuheap @acsmem ++@c create_tree dup @ascuheap @acsmem ++@c postorder() @ascuheap @acsmem ++@c free_tree dup @ascuheap @acsmem ++@c fetch_token dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c parse_branch dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c create_tree dup @ascuheap @acsmem ++@c create_tree @ascuheap @acsmem ++@c create_token_tree @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c analyze @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c preorder() @ascuheap @acsmem ++@c optimize_subexps ok ++@c calc_next ok ++@c link_nfa_nodes @ascuheap @acsmem ++@c re_node_set_init_1 @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c re_node_set_init_2 @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c postorder() @ascuheap @acsmem ++@c lower_subexps @ascuheap @acsmem ++@c lower_subexp @ascuheap @acsmem ++@c create_tree dup @ascuheap @acsmem ++@c calc_first @ascuheap @acsmem ++@c re_dfa_add_node @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c re_node_set_init_empty ok ++@c calc_eclosure @ascuheap @acsmem ++@c calc_eclosure_iter @ascuheap @acsmem ++@c re_node_set_alloc @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c duplicate_node_closure @ascuheap @acsmem ++@c re_node_set_empty ok ++@c duplicate_node @ascuheap @acsmem ++@c re_dfa_add_node dup @ascuheap @acsmem ++@c re_node_set_insert @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c search_duplicated_node ok ++@c re_node_set_merge @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c re_node_set_free @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c re_node_set_insert dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c calc_inveclosure @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c re_node_set_insert_last @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c optimize_utf8 ok ++@c create_initial_state @ascuheap @acsmem ++@c re_node_set_init_copy @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c re_node_set_contains ok ++@c re_node_set_merge dup @ascuheap @acsmem ++@c re_acquire_state_context @ascuheap @acsmem ++@c calc_state_hash ok ++@c re_node_set_compare ok ++@c create_cd_newstate @ascuheap @acsmem ++@c calloc dup @ascuheap @acsmem ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c free_state @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c NOT_SATISFY_PREV_CONSTRAINT ok ++@c re_node_set_remove_at ok ++@c register_state @ascuheap @acsmem ++@c re_node_set_alloc dup @ascuheap @acsmem ++@c re_node_set_insert_last dup @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c free_workarea_compile @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c re_string_destruct @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c free_dfa_content @ascuheap @acsmem ++@c free_token @ascuheap @acsmem ++@c free_charset @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_compile_fastmap @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_compile_fastmap_iter @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_set_fastmap ok ++@c tolower ok ++@c mbrtowc dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c wcrtomb dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c towlower @mtslocale ++@c _NL_CURRENT ok ++@c (re_)free @ascuheap @acsmem + The function @code{regcomp} ``compiles'' a regular expression into a + data structure that you can use with @code{regexec} to match against a + string. The compiled regular expression format is designed for +@@ -871,6 +1221,247 @@ + @comment regex.h + @comment POSIX.2 + @deftypefun int regexec (const regex_t *restrict @var{compiled}, const char *restrict @var{string}, size_t @var{nmatch}, regmatch_t @var{matchptr}[restrict], int @var{eflags}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c libc_lock_lock @asulock @aculock ++@c re_search_internal @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_allocate @ascuheap @acsmem ++@c re_string_construct_common dup ok ++@c re_string_realloc_buffers dup @ascuheap @acsmem ++@c match_ctx_init @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c re_string_byte_at ok ++@c re_string_first_byte dup ok ++@c check_matching @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_cur_idx dup ok ++@c acquire_init_state_context dup @ascuheap @acsmem ++@c re_string_context_at ok ++@c re_string_byte_at dup ok ++@c bitset_contain ok ++@c re_acquire_state_context dup @ascuheap @acsmem ++@c check_subexp_matching_top @ascuheap @acsmem ++@c match_ctx_add_subtop @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c calloc dup @ascuheap @acsmem ++@c transit_state_bkref @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_cur_idx dup ok ++@c re_string_context_at dup ok ++@c NOT_SATISFY_NEXT_CONSTRAINT ok ++@c get_subexp @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_get_buffer ok ++@c search_cur_bkref_entry ok ++@c clean_state_log_if_needed @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c extend_buffers @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_realloc_buffers dup @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c build_wcs_upper_buffer dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c build_upper_buffer dup ok (@mtslocale but optimized) ++@c build_wcs_buffer dup @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_translate_buffer dup ok ++@c get_subexp_sub @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c check_arrival @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c (re_)realloc dup @ascuheap @acsmem ++@c re_string_context_at dup ok ++@c re_node_set_init_1 dup @ascuheap @acsmem ++@c check_arrival_expand_ecl @ascuheap @acsmem ++@c re_node_set_alloc dup @ascuheap @acsmem ++@c find_subexp_node ok ++@c re_node_set_merge dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c check_arrival_expand_ecl_sub @ascuheap @acsmem ++@c re_node_set_contains dup ok ++@c re_node_set_insert dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c expand_bkref_cache @ascuheap @acsmem ++@c search_cur_bkref_entry dup ok ++@c re_node_set_contains dup ok ++@c re_node_set_init_1 dup @ascuheap @acsmem ++@c check_arrival_expand_ecl dup @ascuheap @acsmem ++@c re_node_set_merge dup @ascuheap @acsmem ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c re_node_set_insert dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_acquire_state @ascuheap @acsmem ++@c calc_state_hash dup ok ++@c re_node_set_compare dup ok ++@c create_ci_newstate @ascuheap @acsmem ++@c calloc dup @ascuheap @acsmem ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c register_state dup @ascuheap @acsmem ++@c free_state dup @ascuheap @acsmem ++@c re_acquire_state_context dup @ascuheap @acsmem ++@c re_node_set_merge dup @ascuheap @acsmem ++@c check_arrival_add_next_nodes @mtslocale @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c check_node_accept_bytes @mtslocale @ascuheap @acsmem ++@c re_string_byte_at dup ok ++@c re_string_char_size_at dup ok ++@c re_string_elem_size_at @mtslocale ++@c _NL_CURRENT_WORD dup ok ++@c _NL_CURRENT dup ok ++@c auto findidx dup ok ++@c _NL_CURRENT_WORD dup ok ++@c _NL_CURRENT dup ok ++@c collseq_table_lookup dup ok ++@c find_collation_sequence_value @mtslocale ++@c _NL_CURRENT_WORD dup ok ++@c _NL_CURRENT dup ok ++@c auto findidx dup ok ++@c wcscoll @mtslocale @ascuheap @acsmem ++@c re_node_set_empty dup ok ++@c re_node_set_merge dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_node_set_insert dup @ascuheap @acsmem ++@c re_acquire_state dup @ascuheap @acsmem ++@c check_node_accept ok ++@c re_string_byte_at dup ok ++@c bitset_contain dup ok ++@c re_string_context_at dup ok ++@c NOT_SATISFY_NEXT_CONSTRAINT dup ok ++@c match_ctx_add_entry @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c clean_state_log_if_needed dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c extend_buffers dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c find_subexp_node dup ok ++@c calloc dup @ascuheap @acsmem ++@c check_arrival dup *** ++@c match_ctx_add_sublast @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c re_acquire_state_context dup @ascuheap @acsmem ++@c re_node_set_init_union @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c re_node_set_free dup @ascuheap @acsmem ++@c check_subexp_matching_top dup @ascuheap @acsmem ++@c check_halt_state_context ok ++@c re_string_context_at dup ok ++@c check_halt_node_context ok ++@c NOT_SATISFY_NEXT_CONSTRAINT dup ok ++@c re_string_eoi dup ok ++@c extend_buffers dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c transit_state @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c transit_state_mb @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_context_at dup ok ++@c NOT_SATISFY_NEXT_CONSTRAINT dup ok ++@c check_node_accept_bytes dup @mtslocale @ascuheap @acsmem ++@c re_string_cur_idx dup ok ++@c clean_state_log_if_needed @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_node_set_init_union dup @ascuheap @acsmem ++@c re_acquire_state_context dup @ascuheap @acsmem ++@c re_string_fetch_byte dup ok ++@c re_string_context_at dup ok ++@c build_trtable @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c group_nodes_into_DFAstates @ascuheap @acsmem ++@c bitset_empty dup ok ++@c bitset_set dup ok ++@c bitset_merge dup ok ++@c bitset_set_all ok ++@c bitset_clear ok ++@c bitset_contain dup ok ++@c bitset_copy ok ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c re_node_set_insert dup @ascuheap @acsmem ++@c re_node_set_init_1 dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_node_set_alloc dup @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c bitset_empty ok ++@c re_node_set_empty dup ok ++@c re_node_set_merge dup @ascuheap @acsmem ++@c re_acquire_state_context dup @ascuheap @acsmem ++@c bitset_merge ok ++@c calloc dup @ascuheap @acsmem ++@c bitset_contain dup ok ++@c merge_state_with_log @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c re_string_cur_idx dup ok ++@c re_node_set_init_union dup @ascuheap @acsmem ++@c re_string_context_at dup ok ++@c re_node_set_free dup @ascuheap @acsmem ++@c check_subexp_matching_top @ascuheap @acsmem ++@c match_ctx_add_subtop dup @ascuheap @acsmem ++@c transit_state_bkref dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c find_recover_state ++@c re_string_cur_idx dup ok ++@c re_string_skip_bytes dup ok ++@c merge_state_with_log dup @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c check_halt_state_context dup ok ++@c prune_impossible_nodes @mtslocale @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c sift_ctx_init ok ++@c re_node_set_init_empty dup ok ++@c sift_states_backward @mtslocale @ascuheap @acsmem ++@c re_node_set_init_1 dup @ascuheap @acsmem ++@c update_cur_sifted_state @mtslocale @ascuheap @acsmem ++@c add_epsilon_src_nodes @ascuheap @acsmem ++@c re_acquire_state dup @ascuheap @acsmem ++@c re_node_set_alloc dup @ascuheap @acsmem ++@c re_node_set_merge dup @ascuheap @acsmem ++@c re_node_set_add_intersect @ascuheap @acsmem ++@c (re_)realloc dup @ascuheap @acsmem ++@c check_subexp_limits @ascuheap @acsmem ++@c sub_epsilon_src_nodes @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c re_node_set_contains dup ok ++@c re_node_set_add_intersect dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_node_set_remove_at dup ok ++@c re_node_set_contains dup ok ++@c re_acquire_state dup @ascuheap @acsmem ++@c sift_states_bkref @mtslocale @ascuheap @acsmem ++@c search_cur_bkref_entry dup ok ++@c check_dst_limits ok ++@c search_cur_bkref_entry dup ok ++@c check_dst_limits_calc_pos ok ++@c check_dst_limits_calc_pos_1 ok ++@c re_node_set_init_copy dup @ascuheap @acsmem ++@c re_node_set_insert dup @ascuheap @acsmem ++@c sift_states_backward dup @mtslocale @ascuheap @acsmem ++@c merge_state_array dup @ascuheap @acsmem ++@c re_node_set_remove ok ++@c re_node_set_contains dup ok ++@c re_node_set_remove_at dup ok ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c re_node_set_empty dup ok ++@c build_sifted_states @mtslocale @ascuheap @acsmem ++@c sift_states_iter_mb @mtslocale @ascuheap @acsmem ++@c check_node_accept_bytes dup @mtslocale @ascuheap @acsmem ++@c check_node_accept dup ok ++@c check_dst_limits dup ok ++@c re_node_set_insert dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c check_halt_state_context dup ok ++@c merge_state_array @ascuheap @acsmem ++@c re_node_set_init_union dup @ascuheap @acsmem ++@c re_acquire_state dup @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c set_regs @ascuheap @acsmem ++@c (re_)malloc dup @ascuheap @acsmem ++@c re_node_set_init_empty dup ok ++@c free_fail_stack_return @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c update_regs ok ++@c re_node_set_free dup @ascuheap @acsmem ++@c pop_fail_stack @ascuheap @acsmem ++@c re_node_set_free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c match_ctx_free @ascuheap @acsmem ++@c match_ctx_clean @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c (re_)free dup @ascuheap @acsmem ++@c re_string_destruct dup @ascuheap @acsmem ++@c libc_lock_unlock @aculock + This function tries to match the compiled regular expression + @code{*@var{compiled}} against @var{string}. + +@@ -1033,6 +1624,9 @@ + @comment regex.h + @comment POSIX.2 + @deftypefun void regfree (regex_t *@var{compiled}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c (re_)free dup @ascuheap @acsmem ++@c free_dfa_content dup @ascuheap @acsmem + Calling @code{regfree} frees all the storage that @code{*@var{compiled}} + points to. This includes various internal fields of the @code{regex_t} + structure that aren't documented in this manual. +@@ -1050,6 +1644,8 @@ + @comment regex.h + @comment POSIX.2 + @deftypefun size_t regerror (int @var{errcode}, const regex_t *restrict @var{compiled}, char *restrict @var{buffer}, size_t @var{length}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c regerror calls gettext, strcmp and mempcpy or memcpy. + This function produces an error message string for the error code + @var{errcode}, and stores the string in @var{length} bytes of memory + starting at @var{buffer}. For the @var{compiled} argument, supply the +@@ -1215,6 +1811,145 @@ + @comment wordexp.h + @comment POSIX.2 + @deftypefun int wordexp (const char *@var{words}, wordexp_t *@var{word-vector-ptr}, int @var{flags}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtasuconst{:@mtsenv{}} @mtsenv{} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuintl{} @ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c wordexp @mtasurace:utent @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem ++@c w_newword ok ++@c wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c calloc dup @ascuheap @acsmem ++@c getenv dup @mtsenv ++@c strcpy dup ok ++@c parse_backslash @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c parse_dollars @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c parse_arith @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c w_newword dup ok ++@c parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem ++@c parse_qtd_backslash dup @ascuheap @acsmem ++@c eval_expr @mtslocale ++@c eval_expr_multidiv @mtslocale ++@c eval_expr_val @mtslocale ++@c isspace dup @mtslocale ++@c eval_expr dup @mtslocale ++@c isspace dup @mtslocale ++@c isspace dup @mtslocale ++@c free dup @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c w_addstr dup @ascuheap @acsmem ++@c itoa_word dup ok ++@c parse_comm @ascuplugin @ascuheap @aculock @acsfd @acsmem ++@c w_newword dup ok ++@c pthread_setcancelstate @ascuplugin @ascuheap @acsmem ++@c (disable cancellation around exec_comm; it may do_cancel the ++@c second time, if async cancel is enabled) ++@c THREAD_ATOMIC_CMPXCHG_VAL dup ok ++@c CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok ++@c do_cancel @ascuplugin @ascuheap @acsmem ++@c THREAD_ATOMIC_BIT_SET dup ok ++@c pthread_unwind @ascuplugin @ascuheap @acsmem ++@c Unwind_ForcedUnwind if available @ascuplugin @ascuheap @acsmem ++@c libc_unwind_longjmp otherwise ++@c cleanups ++@c exec_comm @ascuplugin @ascuheap @aculock @acsfd @acsmem ++@c pipe2 dup ok ++@c pipe dup ok ++@c fork dup @ascuplugin @aculock ++@c close dup @acsfd ++@c on child: exec_comm_child -> exec or abort ++@c waitpid dup ok ++@c read dup ok ++@c w_addmem dup @ascuheap @acsmem ++@c strchr dup ok ++@c w_addword dup @ascuheap @acsmem ++@c w_newword dup ok ++@c w_addchar dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c kill dup ok ++@c free dup @ascuheap @acsmem ++@c parse_param @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c reads from __libc_argc and __libc_argv without guards ++@c w_newword dup ok ++@c isalpha dup @mtslocale^^ ++@c w_addchar dup @ascuheap @acsmem ++@c isalnum dup @mtslocale^^ ++@c isdigit dup @mtslocale^^ ++@c strchr dup ok ++@c itoa_word dup ok ++@c atoi dup @mtslocale ++@c getpid dup ok ++@c w_addstr dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c stpcpy dup ok ++@c w_addword dup @ascuheap @acsmem ++@c strdup dup @ascuheap @acsmem ++@c getenv dup @mtsenv ++@c parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c parse_tilde dup @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c fnmatch dup @mtsenv @mtslocale @ascuheap @acsmem ++@c mempcpy dup ok ++@c _ dup @ascuintl ++@c fxprintf dup @aculock ++@c setenv dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c strspn dup ok ++@c strcspn dup ok ++@c parse_backtick @ascuplugin @ascuheap @aculock @acsfd @acsmem ++@c w_newword dup ok ++@c exec_comm dup @ascuplugin @ascuheap @aculock @acsfd @acsmem ++@c free dup @ascuheap @acsmem ++@c parse_qtd_backslash dup @ascuheap @acsmem ++@c parse_backslash dup @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c parse_dquote @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c parse_backtick dup @ascuplugin @ascuheap @aculock @acsfd @acsmem ++@c parse_qtd_backslash dup @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c w_addword dup @ascuheap @acsmem ++@c strdup dup @ascuheap @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c parse_squote dup @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c parse_tilde @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c strchr dup ok ++@c w_addchar dup @ascuheap @acsmem ++@c getenv dup @mtsenv ++@c w_addstr dup @ascuheap @acsmem ++@c strlen dup ok ++@c w_addmem dup @ascuheap @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c getuid dup ok ++@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c parse_glob @mtasurace:utent @mtasuconst:@mtsenv @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c strchr dup ok ++@c parse_dollars dup @mtasuconst:@mtsenv @mtslocale @mtsenv @ascudlopen @ascuplugin @ascuintl @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c parse_qtd_backslash @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c parse_backslash dup @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c w_addword dup @ascuheap @acsmem ++@c w_newword dup ok ++@c do_parse_glob @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem ++@c glob dup @mtasurace:utent @mtsenv @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem [auto glob_t avoids @asucorrupt @acucorrupt] ++@c w_addstr dup @ascuheap @acsmem ++@c w_addchar dup @ascuheap @acsmem ++@c globfree dup @ascuheap @acsmem [auto glob_t avoids @asucorrupt @acucorrupt] ++@c free dup @ascuheap @acsmem ++@c w_newword dup ok ++@c strdup dup @ascuheap @acsmem ++@c w_addword dup @ascuheap @acsmem ++@c wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c strchr dup ok ++@c w_addchar dup @ascuheap @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem + Perform word expansion on the string @var{words}, putting the result in + a newly allocated vector, and store the size and address of this vector + into @code{*@var{word-vector-ptr}}. The argument @var{flags} is a +@@ -1278,6 +2013,9 @@ + @comment wordexp.h + @comment POSIX.2 + @deftypefun void wordfree (wordexp_t *@var{word-vector-ptr}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c wordfree dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c free dup @ascuheap @acsmem + Free the storage used for the word-strings and vector that + @code{*@var{word-vector-ptr}} points to. This does not free the + structure @code{*@var{word-vector-ptr}} itself---only the other +diff -urN glibc-2.17-c758a686/manual/pipe.texi glibc-2.17-c758a686/manual/pipe.texi +--- glibc-2.17-c758a686/manual/pipe.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/pipe.texi 2014-09-12 16:10:06.048792709 -0400 +@@ -56,6 +56,8 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int pipe (int @var{filedes}@t{[2]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} ++@c On Linux, syscall pipe2. On HURD, call socketpair. + The @code{pipe} function creates a pipe and puts the file descriptors + for the reading and writing ends of the pipe (respectively) into + @code{@var{filedes}[0]} and @code{@var{filedes}[1]}. +@@ -108,6 +110,41 @@ + @comment stdio.h + @comment POSIX.2, SVID, BSD + @deftypefun {FILE *} popen (const char *@var{command}, const char *@var{mode}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c popen @ascuheap @asucorrupt @acucorrupt @aculock @acsfd @acsmem ++@c malloc dup @ascuheap @acsmem ++@c _IO_init ok ++@c _IO_no_init ok ++@c _IO_old_init ok ++@c _IO_lock_init ok ++@c _IO_new_file_init @asucorrupt @acucorrupt @aculock @acsfd ++@c _IO_link_in @asucorrupt @acucorrupt @aculock @acsfd ++@c the linked list is guarded by a recursive lock; ++@c it may get corrupted with async signals and cancellation ++@c _IO_lock_lock dup @aculock ++@c _IO_flockfile dup @aculock ++@c _IO_funlockfile dup @aculock ++@c _IO_lock_unlock dup @aculock ++@c _IO_new_proc_open @asucorrupt @acucorrupt @aculock @acsfd ++@c the linked list is guarded by a recursive lock; ++ @c it may get corrupted with async signals and cancellation ++@c _IO_file_is_open ok ++@c pipe2 dup @acsfd ++@c pipe dup @acsfd ++@c _IO_fork=fork @aculock ++@c _IO_close=close_not_cancel dup @acsfd ++@c fcntl dup ok ++@c _IO_lock_lock @aculock ++@c _IO_lock_unlock @aculock ++@c _IO_mask_flags ok [no @mtasurace:stream, nearly but sufficiently exclusive access] ++@c _IO_un_link @asucorrupt @acucorrupt @aculock @acsfd ++@c the linked list is guarded by a recursive lock; ++@c it may get corrupted with async signals and cancellation ++@c _IO_lock_lock dup @aculock ++@c _IO_flockfile dup @aculock ++@c _IO_funlockfile dup @aculock ++@c _IO_lock_unlock dup @aculock ++@c free dup @ascuheap @acsmem + The @code{popen} function is closely related to the @code{system} + function; see @ref{Running a Command}. It executes the shell command + @var{command} as a subprocess. However, instead of waiting for the +@@ -131,6 +168,77 @@ + @comment stdio.h + @comment POSIX.2, SVID, BSD + @deftypefun int pclose (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @ascuplugin{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c Although the stream cannot be used after the call, even in case of ++@c async cancellation, because the stream must not be used after pclose ++@c is called, other stdio linked lists and their locks may be left in ++@c corrupt states; that's where the corrupt and lock annotations come ++@c from. ++@c ++@c pclose @ascuheap @ascuplugin @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem ++@c _IO_new_fclose @ascuheap @ascuplugin @asucorrupt @asulock @acucorrupt @aculock @acsfd @acsmem ++@c _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd ++@c _IO_acquire_lock dup @aculock ++@c _IO_flockfile dup @aculock ++@c _IO_file_close_it @ascuheap @ascuplugin @asucorrupt @aculock @acucorrupt @acsfd @acsmem ++@c _IO_file_is_open dup ok ++@c _IO_do_flush @asucorrupt @ascuplugin @acucorrupt ++@c _IO_do_write @asucorrupt @acucorrupt ++@c new_do_write @asucorrupt @acucorrupt ++@c _IO_SYSSEEK ok ++@c lseek64 dup ok ++@c _IO_SYSWRITE ok ++@c write_not_cancel dup ok ++@c write dup ok ++@c _IO_adjust_column ok ++@c _IO_setg dup @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_wdo_write @asucorrupt @ascuplugin @acucorrupt ++@c _IO_new_do_write=_IO_do_write dup @asucorrupt @acucorrupt ++@c *cc->__codecvt_do_out @ascuplugin ++@c _IO_wsetg dup @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_unsave_markers @ascuheap @asucorrupt @acucorrupt @acsmem ++@c _IO_have_backup dup ok ++@c _IO_free_backup_area dup @ascuheap @asucorrupt @acucorrupt @acsmem ++@c _IO_SYSCLOSE @aculock @acucorrupt @acsfd ++@c _IO_lock_lock dup @aculock ++@c _IO_close=close_not_cancel dup @acsfd ++@c _IO_lock_unlock dup @aculock ++@c _IO_waitpid=waitpid_not_cancel dup ok ++@c _IO_have_wbackup ok ++@c _IO_free_wbackup_area @ascuheap @asucorrupt @acucorrupt @acsmem ++@c _IO_in_backup dup ok ++@c _IO_switch_to_main_wget_area @asucorrupt @acucorrupt ++@c free dup @ascuheap @acsmem ++@c _IO_wsetb @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_wsetg @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_wsetp @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_setb @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_setg @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_setp @asucorrupt @acucorrupt [no @mtasurace:stream, locked] ++@c _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd ++@c _IO_release_lock dup @aculock ++@c _IO_funlockfile dup @aculock ++@c _IO_FINISH @ascuheap @ascuplugin @asucorrupt @acucorrupt @aculock @acsfd @acsmem ++@c _IO_new_file_finish @ascuheap @ascuplugin @asucorrupt @acucorrupt @aculock @acsfd @acsmem ++@c _IO_file_is_open dup ok ++@c _IO_do_flush dup @ascuplugin @asucorrupt @acucorrupt ++@c _IO_SYSCLOSE dup @aculock @acucorrupt @acsfd ++@c _IO_default_finish @ascuheap @asucorrupt @acucorrupt @aculock @acsfd @acsmem ++@c FREE_BUF @acsmem ++@c munmap dup @acsmem ++@c free dup @ascuheap @acsmem ++@c _IO_un_link dup @asucorrupt @acucorrupt @aculock @acsfd ++@c _IO_lock_fini ok ++@c libc_lock_fini_recursive ok ++@c libc_lock_lock dup @asulock @aculock ++@c gconv_release_step ok ++@c libc_lock_unlock dup @asulock @aculock ++@c _IO_have_backup ok ++@c _IO_free_backup_area @ascuheap @asucorrupt @acucorrupt @acsmem ++@c _IO_in_backup ok ++@c _IO_switch_to_main_get_area @asucorrupt @acucorrupt ++@c free dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem + The @code{pclose} function is used to close a stream created by @code{popen}. + It waits for the child process to terminate and returns its status value, + as for the @code{system} function. +@@ -168,6 +276,8 @@ + @comment sys/stat.h + @comment POSIX.1 + @deftypefun int mkfifo (const char *@var{filename}, mode_t @var{mode}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On generic Posix, calls xmknod. + The @code{mkfifo} function makes a FIFO special file with name + @var{filename}. The @var{mode} argument is used to set the file's + permissions; see @ref{Setting Permissions}. +diff -urN glibc-2.17-c758a686/manual/platform.texi glibc-2.17-c758a686/manual/platform.texi +--- glibc-2.17-c758a686/manual/platform.texi 2014-09-12 16:08:17.865070640 -0400 ++++ glibc-2.17-c758a686/manual/platform.texi 2014-09-12 16:10:06.046792714 -0400 +@@ -15,6 +15,7 @@ + operating system are declared in @file{sys/platform/ppc.h}. + + @deftypefun {uint64_t} __ppc_get_timebase (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Read the current value of the Time Base Register. + + The @dfn{Time Base Register} is a 64-bit register that stores a monotonically +@@ -28,6 +29,17 @@ + @end deftypefun + + @deftypefun {uint64_t} __ppc_get_timebase_freq (void) ++@safety{@prelim{}@mtunsafe{@mtuinit{}}@asunsafe{@asucorrupt{:init}}@acunsafe{@acucorrupt{:init}}} ++@c __ppc_get_timebase_freq=__get_timebase_freq @mtuinit @acsfd ++@c __get_clockfreq @mtuinit @asucorrupt:init @acucorrupt:init @acsfd ++@c the initialization of the static timebase_freq is not exactly ++@c safe, because hp_timing_t cannot be atomically set up. ++@c syscall:get_tbfreq ok ++@c open dup @acsfd ++@c read dup ok ++@c memcpy dup ok ++@c memmem dup ok ++@c close dup @acsfd + Read the current frequency at which the Time Base Register is updated. + + This frequency is not related to the processor clock or the bus clock. +@@ -42,17 +54,20 @@ + Section 3.2}. + + @deftypefun {void} __ppc_yield (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Provide a hint that performance will probably be improved if shared resources + dedicated to the executing processor are released for use by other processors. + @end deftypefun + + @deftypefun {void} __ppc_mdoio (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Provide a hint that performance will probably be improved if shared resources + dedicated to the executing processor are released until all outstanding storage + accesses to caching-inhibited storage have been completed. + @end deftypefun + + @deftypefun {void} __ppc_mdoom (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Provide a hint that performance will probably be improved if shared resources + dedicated to the executing processor are released until all outstanding storage + accesses to cacheable storage for which the data is not in the cache have been +@@ -60,6 +75,7 @@ + @end deftypefun + + @deftypefun {void} __ppc_set_ppr_med (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Set the Program Priority Register to medium value (default). + + The @dfn{Program Priority Register} (PPR) is a 64-bit register that controls +@@ -73,9 +89,11 @@ + @end deftypefun + + @deftypefun {void} __ppc_set_ppr_low (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Set the Program Priority Register to low value. + @end deftypefun + + @deftypefun {void} __ppc_set_ppr_med_low (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Set the Program Priority Register to medium low value. + @end deftypefun +diff -urN glibc-2.17-c758a686/manual/process.texi glibc-2.17-c758a686/manual/process.texi +--- glibc-2.17-c758a686/manual/process.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/process.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -1,4 +1,4 @@ +-@node Processes, Job Control, Program Basics, Top ++@node Processes, Inter-Process Communication, Program Basics, Top + @c %MENU% How to create processes and run other programs + @chapter Processes + +@@ -55,6 +55,43 @@ + @comment ISO + @deftypefun int system (const char *@var{command}) + @pindex sh ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}} ++@c system @ascuplugin @ascuheap @asulock @aculock @acsmem ++@c do_system @ascuplugin @ascuheap @asulock @aculock @acsmem ++@c sigemptyset dup ok ++@c libc_lock_lock @asulock @aculock ++@c ADD_REF ok ++@c sigaction dup ok ++@c SUB_REF ok ++@c libc_lock_unlock @aculock ++@c sigaddset dup ok ++@c sigprocmask dup ok ++@c CLEANUP_HANDLER @ascuplugin @ascuheap @acsmem ++@c libc_cleanup_region_start @ascuplugin @ascuheap @acsmem ++@c pthread_cleanup_push_defer @ascuplugin @ascuheap @acsmem ++@c CANCELLATION_P @ascuplugin @ascuheap @acsmem ++@c CANCEL_ENABLED_AND_CANCELED ok ++@c do_cancel @ascuplugin @ascuheap @acsmem ++@c cancel_handler ok ++@c kill syscall ok ++@c waitpid dup ok ++@c libc_lock_lock ok ++@c sigaction dup ok ++@c libc_lock_unlock ok ++@c FORK ok ++@c clone syscall ok ++@c waitpid dup ok ++@c CLEANUP_RESET ok ++@c libc_cleanup_region_end ok ++@c pthread_cleanup_pop_restore ok ++@c SINGLE_THREAD_P ok ++@c LIBC_CANCEL_ASYNC @ascuplugin @ascuheap @acsmem ++@c libc_enable_asynccancel @ascuplugin @ascuheap @acsmem ++@c CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS dup ok ++@c do_cancel dup @ascuplugin @ascuheap @acsmem ++@c LIBC_CANCEL_RESET ok ++@c libc_disable_asynccancel ok ++@c lll_futex_wait dup ok + This function executes @var{command} as a shell command. In @theglibc{}, + it always uses the default shell @code{sh} to run the command. + In particular, it searches the directories in @code{PATH} to find +@@ -157,12 +194,14 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun pid_t getpid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getpid} function returns the process ID of the current process. + @end deftypefun + + @comment unistd.h + @comment POSIX.1 + @deftypefun pid_t getppid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getppid} function returns the process ID of the parent of the + current process. + @end deftypefun +@@ -177,6 +216,19 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun pid_t fork (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}} ++@c The nptl/.../linux implementation safely collects fork_handlers into ++@c an alloca()ed linked list and increments ref counters; it uses atomic ++@c ops and retries, avoiding locking altogether. It then takes the ++@c IO_list lock, resets the thread-local pid, and runs fork. The parent ++@c restores the thread-local pid, releases the lock, and runs parent ++@c handlers, decrementing the ref count and signaling futex wait if ++@c requested by unregister_atfork. The child bumps the fork generation, ++@c sets the thread-local pid, resets cpu clocks, initializes the robust ++@c mutex list, the stream locks, the IO_list lock, the dynamic loader ++@c lock, runs the child handlers, reseting ref counters to 1, and ++@c initializes the fork lock. These are all safe, unless atfork ++@c handlers themselves are unsafe. + The @code{fork} function creates a new process. + + If the operation is successful, there are then both parent and child +@@ -242,6 +294,9 @@ + @comment unistd.h + @comment BSD + @deftypefun pid_t vfork (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}} ++@c The vfork implementation proper is a safe syscall, but it may fall ++@c back to fork if the vfork syscall is not available. + The @code{vfork} function is similar to @code{fork} but on some systems + it is more efficient; however, there are restrictions you must follow to + use it safely. +@@ -287,6 +342,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int execv (const char *@var{filename}, char *const @var{argv}@t{[]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{execv} function executes the file named by @var{filename} as a + new process image. + +@@ -305,6 +361,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int execl (const char *@var{filename}, const char *@var{arg0}, @dots{}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is similar to @code{execv}, but the @var{argv} strings are + specified individually instead of as an array. A null pointer must be + passed as the last such argument. +@@ -313,6 +370,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int execve (const char *@var{filename}, char *const @var{argv}@t{[]}, char *const @var{env}@t{[]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is similar to @code{execv}, but permits you to specify the environment + for the new program explicitly as the @var{env} argument. This should + be an array of strings in the same format as for the @code{environ} +@@ -322,6 +380,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int execle (const char *@var{filename}, const char *@var{arg0}, @dots{}, char *const @var{env}@t{[]}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is similar to @code{execl}, but permits you to specify the + environment for the new program explicitly. The environment argument is + passed following the null pointer that marks the last @var{argv} +@@ -332,6 +391,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int execvp (const char *@var{filename}, char *const @var{argv}@t{[]}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{execvp} function is similar to @code{execv}, except that it + searches the directories listed in the @code{PATH} environment variable + (@pxref{Standard Environment}) to find the full file name of a +@@ -345,6 +405,7 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int execlp (const char *@var{filename}, const char *@var{arg0}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function is like @code{execl}, except that it performs the same + file name searching as the @code{execvp} function. + @end deftypefun +@@ -462,6 +523,7 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefun pid_t waitpid (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{waitpid} function is used to request status information from a + child process whose process ID is @var{pid}. Normally, the calling + process is suspended until the child process makes status information +@@ -565,6 +627,7 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefun pid_t wait (int *@var{status-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is a simplified version of @code{waitpid}, and is used to wait + until any one child process terminates. The call: + +@@ -591,6 +654,7 @@ + @comment sys/wait.h + @comment BSD + @deftypefun pid_t wait4 (pid_t @var{pid}, int *@var{status-ptr}, int @var{options}, struct rusage *@var{usage}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @var{usage} is a null pointer, @code{wait4} is equivalent to + @code{waitpid (@var{pid}, @var{status-ptr}, @var{options})}. + +@@ -643,6 +707,7 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefn Macro int WIFEXITED (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if the child process terminated + normally with @code{exit} or @code{_exit}. + @end deftypefn +@@ -650,6 +715,7 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefn Macro int WEXITSTATUS (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @code{WIFEXITED} is true of @var{status}, this macro returns the + low-order 8 bits of the exit status value from the child process. + @xref{Exit Status}. +@@ -658,6 +724,7 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefn Macro int WIFSIGNALED (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if the child process terminated + because it received a signal that was not handled. + @xref{Signal Handling}. +@@ -666,6 +733,7 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefn Macro int WTERMSIG (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @code{WIFSIGNALED} is true of @var{status}, this macro returns the + signal number of the signal that terminated the child process. + @end deftypefn +@@ -673,6 +741,7 @@ + @comment sys/wait.h + @comment BSD + @deftypefn Macro int WCOREDUMP (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if the child process terminated + and produced a core dump. + @end deftypefn +@@ -680,12 +749,14 @@ + @comment sys/wait.h + @comment POSIX.1 + @deftypefn Macro int WIFSTOPPED (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro returns a nonzero value if the child process is stopped. + @end deftypefn + + @comment sys/wait.h + @comment POSIX.1 + @deftypefn Macro int WSTOPSIG (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @code{WIFSTOPPED} is true of @var{status}, this macro returns the + signal number of the signal that caused the child process to stop. + @end deftypefn +@@ -739,6 +810,7 @@ + @comment sys/wait.h + @comment BSD + @deftypefun pid_t wait3 (union wait *@var{status-ptr}, int @var{options}, struct rusage *@var{usage}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + If @var{usage} is a null pointer, @code{wait3} is equivalent to + @code{waitpid (-1, @var{status-ptr}, @var{options})}. + +diff -urN glibc-2.17-c758a686/manual/resource.texi glibc-2.17-c758a686/manual/resource.texi +--- glibc-2.17-c758a686/manual/resource.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/resource.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -25,6 +25,8 @@ + @comment sys/resource.h + @comment BSD + @deftypefun int getrusage (int @var{processes}, struct rusage *@var{rusage}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On HURD, this calls task_info 3 times. On UNIX, it's a syscall. + This function reports resource usage totals for processes specified by + @var{processes}, storing the information in @code{*@var{rusage}}. + +@@ -129,9 +131,11 @@ + @code{vtimes} and its @code{vtimes} data structure are declared in + @file{sys/vtimes.h}. + @pindex sys/vtimes.h +-@comment vtimes.h + +-@deftypefun int vtimes (struct vtimes @var{current}, struct vtimes @var{child}) ++@comment sys/vtimes.h ++@deftypefun int vtimes (struct vtimes *@var{current}, struct vtimes *@var{child}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Calls getrusage twice. + + @code{vtimes} reports resource usage totals for a process. + +@@ -223,6 +227,8 @@ + @comment sys/resource.h + @comment BSD + @deftypefun int getrlimit (int @var{resource}, struct rlimit *@var{rlp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on most systems. + Read the current and maximum limits for the resource @var{resource} + and store them in @code{*@var{rlp}}. + +@@ -237,6 +243,8 @@ + @comment sys/resource.h + @comment Unix98 + @deftypefun int getrlimit64 (int @var{resource}, struct rlimit64 *@var{rlp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on most systems, wrapper to getrlimit otherwise. + This function is similar to @code{getrlimit} but its second parameter is + a pointer to a variable of type @code{struct rlimit64}, which allows it + to read values which wouldn't fit in the member of a @code{struct +@@ -250,6 +258,8 @@ + @comment sys/resource.h + @comment BSD + @deftypefun int setrlimit (int @var{resource}, const struct rlimit *@var{rlp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on most systems; lock-taking critical section on HURD. + Store the current and maximum limits for the resource @var{resource} + in @code{*@var{rlp}}. + +@@ -275,6 +285,8 @@ + @comment sys/resource.h + @comment Unix98 + @deftypefun int setrlimit64 (int @var{resource}, const struct rlimit64 *@var{rlp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Wrapper for setrlimit or direct syscall. + This function is similar to @code{setrlimit} but its second parameter is + a pointer to a variable of type @code{struct rlimit64} which allows it + to set values which wouldn't fit in the member of a @code{struct +@@ -419,7 +431,7 @@ + + @comment sys/resource.h + @comment BSD +-@deftypevr Constant int RLIM_INFINITY ++@deftypevr Constant rlim_t RLIM_INFINITY + This constant stands for a value of ``infinity'' when supplied as + the limit value in @code{setrlimit}. + @end deftypevr +@@ -433,7 +445,10 @@ + + @comment ulimit.h + @comment BSD +-@deftypefun int ulimit (int @var{cmd}, @dots{}) ++@deftypefun {long int} ulimit (int @var{cmd}, @dots{}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Wrapper for getrlimit, setrlimit or ++@c sysconf(_SC_OPEN_MAX)->getdtablesize->getrlimit. + + @code{ulimit} gets the current limit or sets the current and maximum + limit for a particular resource for the calling process according to the +@@ -480,6 +495,10 @@ + @comment sys/vlimit.h + @comment BSD + @deftypefun int vlimit (int @var{resource}, int @var{limit}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:setrlimit}}@asunsafe{}@acsafe{}} ++@c It calls getrlimit and modifies the rlim_cur field before calling ++@c setrlimit. There's a window for a concurrent call to setrlimit that ++@c modifies e.g. rlim_max, which will be lost if running as super-user. + + @code{vlimit} sets the current limit for a resource for a process. + +@@ -778,6 +797,8 @@ + @comment sched.h + @comment POSIX + @deftypefun int sched_setscheduler (pid_t @var{pid}, int @var{policy}, const struct sched_param *@var{param}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function sets both the absolute priority and the scheduling policy + for a process. +@@ -848,6 +869,8 @@ + @comment sched.h + @comment POSIX + @deftypefun int sched_getscheduler (pid_t @var{pid}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function returns the scheduling policy assigned to the process with + Process ID (pid) @var{pid}, or the calling process if @var{pid} is zero. +@@ -881,6 +904,8 @@ + @comment sched.h + @comment POSIX + @deftypefun int sched_setparam (pid_t @var{pid}, const struct sched_param *@var{param}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function sets a process' absolute priority. + +@@ -893,7 +918,9 @@ + + @comment sched.h + @comment POSIX +-@deftypefun int sched_getparam (pid_t @var{pid}, const struct sched_param *@var{param}) ++@deftypefun int sched_getparam (pid_t @var{pid}, struct sched_param *@var{param}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function returns a process' absolute priority. + +@@ -922,7 +949,9 @@ + + @comment sched.h + @comment POSIX +-@deftypefun int sched_get_priority_min (int *@var{policy}) ++@deftypefun int sched_get_priority_min (int @var{policy}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function returns the lowest absolute priority value that is + allowable for a process with scheduling policy @var{policy}. +@@ -942,7 +971,9 @@ + + @comment sched.h + @comment POSIX +-@deftypefun int sched_get_priority_max (int *@var{policy}) ++@deftypefun int sched_get_priority_max (int @var{policy}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function returns the highest absolute priority value that is + allowable for a process that with scheduling policy @var{policy}. +@@ -963,6 +994,8 @@ + @comment sched.h + @comment POSIX + @deftypefun int sched_rr_get_interval (pid_t @var{pid}, struct timespec *@var{interval}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + This function returns the length of the quantum (time slice) used with + the Round Robin scheduling policy, if it is used, for the process with +@@ -987,6 +1020,8 @@ + @comment sched.h + @comment POSIX + @deftypefun int sched_yield (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on Linux; alias to swtch on HURD. + + This function voluntarily gives up the process' claim on the CPU. + +@@ -1045,7 +1080,7 @@ + about. + + But just to be clear about the scope of this scheduling: Any time a +-process with a absolute priority of 0 and a process with an absolute ++process with an absolute priority of 0 and a process with an absolute + priority higher than 0 are ready to run at the same time, the one with + absolute priority 0 does not run. If it's already running when the + higher priority ready-to-run process comes into existence, it stops +@@ -1138,6 +1173,8 @@ + @comment sys/resource.h + @comment BSD,POSIX + @deftypefun int getpriority (int @var{class}, int @var{id}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on UNIX. On HURD, calls _hurd_priority_which_map. + Return the nice value of a set of processes; @var{class} and @var{id} + specify which ones (see below). If the processes specified do not all + have the same nice value, this returns the lowest value that any of them +@@ -1165,6 +1202,8 @@ + @comment sys/resource.h + @comment BSD,POSIX + @deftypefun int setpriority (int @var{class}, int @var{id}, int @var{niceval}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on UNIX. On HURD, calls _hurd_priority_which_map. + Set the nice value of a set of processes to @var{niceval}; @var{class} + and @var{id} specify which ones (see below). + +@@ -1222,6 +1261,11 @@ + @comment unistd.h + @comment BSD + @deftypefun int nice (int @var{increment}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:setpriority}}@asunsafe{}@acsafe{}} ++@c Calls getpriority before and after setpriority, using the result of ++@c the first call to compute the argument for setpriority. This creates ++@c a window for a concurrent setpriority (or nice) call to be lost or ++@c exhibit surprising behavior. + Increment the nice value of the calling process by @var{increment}. + The return value is the new nice value on success, and @code{-1} on + failure. In the case of failure, @code{errno} will be set to the +@@ -1319,6 +1363,10 @@ + @comment sched.h + @comment GNU + @deftypefn Macro void CPU_ZERO (cpu_set_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_ZERO ok ++@c __CPU_ZERO_S ok ++@c memset dup ok + This macro initializes the CPU set @var{set} to be the empty set. + + This macro is a GNU extension and is defined in @file{sched.h}. +@@ -1327,6 +1375,11 @@ + @comment sched.h + @comment GNU + @deftypefn Macro void CPU_SET (int @var{cpu}, cpu_set_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_SET ok ++@c __CPU_SET_S ok ++@c __CPUELT ok ++@c __CPUMASK ok + This macro adds @var{cpu} to the CPU set @var{set}. + + The @var{cpu} parameter must not have side effects since it is +@@ -1338,6 +1391,11 @@ + @comment sched.h + @comment GNU + @deftypefn Macro void CPU_CLR (int @var{cpu}, cpu_set_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_CLR ok ++@c __CPU_CLR_S ok ++@c __CPUELT dup ok ++@c __CPUMASK dup ok + This macro removes @var{cpu} from the CPU set @var{set}. + + The @var{cpu} parameter must not have side effects since it is +@@ -1349,6 +1407,11 @@ + @comment sched.h + @comment GNU + @deftypefn Macro int CPU_ISSET (int @var{cpu}, const cpu_set_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c CPU_ISSET ok ++@c __CPU_ISSET_S ok ++@c __CPUELT dup ok ++@c __CPUMASK dup ok + This macro returns a nonzero value (true) if @var{cpu} is a member + of the CPU set @var{set}, and zero (false) otherwise. + +@@ -1365,6 +1428,9 @@ + @comment sched.h + @comment GNU + @deftypefun int sched_getaffinity (pid_t @var{pid}, size_t @var{cpusetsize}, cpu_set_t *@var{cpuset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Wrapped syscall to zero out past the kernel cpu set size; Linux ++@c only. + + This functions stores the CPU affinity mask for the process or thread + with the ID @var{pid} in the @var{cpusetsize} bytes long bitmap +@@ -1393,6 +1459,9 @@ + @comment sched.h + @comment GNU + @deftypefun int sched_setaffinity (pid_t @var{pid}, size_t @var{cpusetsize}, const cpu_set_t *@var{cpuset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Wrapped syscall to detect attempts to set bits past the kernel cpu ++@c set size; Linux only. + + This function installs the @var{cpusetsize} bytes long affinity mask + pointed to by @var{cpuset} for the process or thread with the ID @var{pid}. +@@ -1516,6 +1585,9 @@ + @comment unistd.h + @comment BSD + @deftypefun int getpagesize (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Obtained from the aux vec at program startup time. GNU/Linux/m68k is ++@c the exception, with the possibility of a syscall. + The @code{getpagesize} function returns the page size of the process. + This value is fixed for the runtime of the process but can vary in + different runs of the application. +@@ -1559,6 +1631,8 @@ + @comment sys/sysinfo.h + @comment GNU + @deftypefun {long int} get_phys_pages (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c This fopens a /proc file and scans it for the requested information. + The @code{get_phys_pages} function returns the total number of pages of + physical the system has. To get the amount of memory this number has to + be multiplied by the page size. +@@ -1569,7 +1643,8 @@ + @comment sys/sysinfo.h + @comment GNU + @deftypefun {long int} get_avphys_pages (void) +-The @code{get_phys_pages} function returns the number of available pages of ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++The @code{get_avphys_pages} function returns the number of available pages of + physical the system has. To get the amount of memory this number has to + be multiplied by the page size. + +@@ -1614,6 +1689,9 @@ + @comment sys/sysinfo.h + @comment GNU + @deftypefun int get_nprocs_conf (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c This function reads from from /sys using dir streams (single user, so ++@c no @mtasurace issue), and on some arches, from /proc using streams. + The @code{get_nprocs_conf} function returns the number of processors the + operating system configured. + +@@ -1623,6 +1701,8 @@ + @comment sys/sysinfo.h + @comment GNU + @deftypefun int get_nprocs (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} ++@c This function reads from /proc using file descriptor I/O. + The @code{get_nprocs} function returns the number of available processors. + + This function is a GNU extension. +@@ -1638,8 +1718,12 @@ + @comment stdlib.h + @comment BSD + @deftypefun int getloadavg (double @var{loadavg}[], int @var{nelem}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} ++@c Calls host_info on HURD; on Linux, opens /proc/loadavg, reads from ++@c it, closes it, without cancellation point, and calls strtod_l with ++@c the C locale to convert the strings to doubles. + This function gets the 1, 5 and 15 minute load averages of the +-system. The values are placed in @var{loadavg}. @code{getloadavg} will ++system. The values are placed in @var{loadavg}. @code{getloadavg} will + place at most @var{nelem} elements into the array but never more than + three elements. The return value is the number of elements written to + @var{loadavg}, or -1 on error. +diff -urN glibc-2.17-c758a686/manual/search.texi glibc-2.17-c758a686/manual/search.texi +--- glibc-2.17-c758a686/manual/search.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/search.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -71,7 +71,8 @@ + + @comment search.h + @comment SVID +-@deftypefun {void *} lfind (const void *@var{key}, void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar}) ++@deftypefun {void *} lfind (const void *@var{key}, const void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{lfind} function searches in the array with @code{*@var{nmemb}} + elements of @var{size} bytes pointed to by @var{base} for an element + which matches the one pointed to by @var{key}. The function pointed to +@@ -90,6 +91,21 @@ + @comment search.h + @comment SVID + @deftypefun {void *} lsearch (const void *@var{key}, void *@var{base}, size_t *@var{nmemb}, size_t @var{size}, comparison_fn_t @var{compar}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c A signal handler that interrupted an insertion and performed an ++@c insertion itself would leave the array in a corrupt state (e.g. one ++@c new element initialized twice, with parts of both initializations ++@c prevailing, and another uninitialized element), but this is just a ++@c special case of races on user-controlled objects, that have to be ++@c avoided by users. ++ ++@c In case of cancellation, we know the array won't be left in a corrupt ++@c state; the new element is initialized before the element count is ++@c incremented, and the compiler can't reorder these operations because ++@c it can't know that they don't alias. So, we'll either cancel after ++@c the increment and the initialization are both complete, or the ++@c increment won't have taken place, and so how far the initialization ++@c got doesn't matter. + The @code{lsearch} function is similar to the @code{lfind} function. It + searches the given array for an element and returns it if found. The + difference is that if no matching element is found the @code{lsearch} +@@ -113,6 +129,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun {void *} bsearch (const void *@var{key}, const void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{bsearch} function searches the sorted array @var{array} for an object + that is equivalent to @var{key}. The array contains @var{count} elements, + each of which is of size @var{size} bytes. +@@ -146,6 +163,7 @@ + @comment stdlib.h + @comment ISO + @deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}} + The @var{qsort} function sorts the array @var{array}. The array contains + @var{count} elements, each of which is of size @var{size}. + +@@ -256,6 +274,9 @@ + @comment search.h + @comment SVID + @deftypefun int hcreate (size_t @var{nel}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c hcreate @mtasurace:hsearch @ascuheap @acucorrupt @acsmem ++@c hcreate_r dup @mtsrace:htab @ascuheap @acucorrupt @acsmem + The @code{hcreate} function creates a hashing table which can contain at + least @var{nel} elements. There is no possibility to grow this table so + it is necessary to choose the value for @var{nel} wisely. The method +@@ -270,7 +291,7 @@ + The weakest aspect of this function is that there can be at most one + hashing table used through the whole program. The table is allocated + in local memory out of control of the programmer. As an extension @theglibc{} +-provides an additional set of functions with an reentrant ++provides an additional set of functions with a reentrant + interface which provide a similar interface but which allow to keep + arbitrarily many hashing tables. + +@@ -285,6 +306,9 @@ + @comment search.h + @comment SVID + @deftypefun void hdestroy (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c hdestroy @mtasurace:hsearch @ascuheap @acucorrupt @acsmem ++@c hdestroy_r dup @mtsrace:htab @ascuheap @acucorrupt @acsmem + The @code{hdestroy} function can be used to free all the resources + allocated in a previous call of @code{hcreate}. After a call to this + function it is again possible to call @code{hcreate} and allocate a new +@@ -328,6 +352,9 @@ + @comment search.h + @comment SVID + @deftypefun {ENTRY *} hsearch (ENTRY @var{item}, ACTION @var{action}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hsearch}}@asunsafe{}@acunsafe{@acucorrupt{/action==ENTER}}} ++@c hsearch @mtasurace:hsearch @acucorrupt/action==ENTER ++@c hsearch_r dup @mtsrace:htab @acucorrupt/action==ENTER + To search in a hashing table created using @code{hcreate} the + @code{hsearch} function must be used. This function can perform simple + search for an element (if @var{action} has the @code{FIND}) or it can +@@ -358,6 +385,24 @@ + @comment search.h + @comment GNU + @deftypefun int hcreate_r (size_t @var{nel}, struct hsearch_data *@var{htab}) ++@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c Unlike the lsearch array, the htab is (at least in part) opaque, so ++@c let's make it absolutely clear that ensuring exclusive access is a ++@c caller responsibility. ++ ++@c Cancellation is unlikely to leave the htab in a corrupt state: the ++@c last field to be initialized is the one that tells whether the entire ++@c data structure was initialized, and there's a function call (calloc) ++@c in between that will often ensure all other fields are written before ++@c the table. However, should this call be inlined (say with LTO), this ++@c assumption may not hold. The calloc call doesn't cross our library ++@c interface barrier, so let's consider this could happen and mark this ++@c with @acucorrupt. It's no safety loss, since we already have ++@c @ascuheap anyway... ++ ++@c hcreate_r @mtsrace:htab @ascuheap @acucorrupt @acsmem ++@c isprime ok ++@c calloc dup @ascuheap @acsmem + The @code{hcreate_r} function initializes the object pointed to by + @var{htab} to contain a hashing table with at least @var{nel} elements. + So this function is equivalent to the @code{hcreate} function except +@@ -376,6 +421,16 @@ + @comment search.h + @comment GNU + @deftypefun void hdestroy_r (struct hsearch_data *@var{htab}) ++@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c The table is released while the table pointer still points to it. ++@c Async cancellation is thus unsafe, but it already was because we call ++@c free(). Using the table in a handler while it's being released would ++@c also be dangerous, but calling free() already makes it unsafe, and ++@c the requirement on the caller to ensure exclusive access already ++@c guarantees this doesn't happen, so we don't get @asucorrupt. ++ ++@c hdestroy_r @mtsrace:htab @ascuheap @acucorrupt @acsmem ++@c free dup @ascuheap @acsmem + The @code{hdestroy_r} function frees all resources allocated by the + @code{hcreate_r} function for this very same object @var{htab}. As for + @code{hdestroy} it is the programs responsibility to free the strings +@@ -385,6 +440,13 @@ + @comment search.h + @comment GNU + @deftypefun int hsearch_r (ENTRY @var{item}, ACTION @var{action}, ENTRY **@var{retval}, struct hsearch_data *@var{htab}) ++@safety{@prelim{}@mtsafe{@mtsrace{:htab}}@assafe{}@acunsafe{@acucorrupt{/action==ENTER}}} ++@c Callers have to ensure mutual exclusion; insertion, if cancelled, ++@c leaves the table in a corrupt state. ++ ++@c hsearch_r @mtsrace:htab @acucorrupt/action==ENTER ++@c strlen dup ok ++@c strcmp dup ok + The @code{hsearch_r} function is equivalent to @code{hsearch}. The + meaning of the first two arguments is identical. But instead of + operating on a single global hashing table the function works on the +@@ -401,7 +463,7 @@ + + @table @code + @item ENOMEM +-The table is filled and @code{hsearch_r} was called with an so far ++The table is filled and @code{hsearch_r} was called with a so far + unknown key and @var{action} set to @code{ENTER}. + @item ESRCH + The @var{action} parameter is @code{FIND} and no corresponding element +@@ -436,6 +498,12 @@ + @comment search.h + @comment SVID + @deftypefun {void *} tsearch (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar}) ++@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c The tree is not modified in a thread-safe manner, and rotations may ++@c leave the tree in an inconsistent state that could be observed in an ++@c asynchronous signal handler (except for the caller-synchronization ++@c requirement) or after asynchronous cancellation of the thread ++@c performing the rotation or the insertion. + The @code{tsearch} function searches in the tree pointed to by + @code{*@var{rootp}} for an element matching @var{key}. The function + pointed to by @var{compar} is used to determine whether two elements +@@ -465,6 +533,7 @@ + @comment search.h + @comment SVID + @deftypefun {void *} tfind (const void *@var{key}, void *const *@var{rootp}, comparison_fn_t @var{compar}) ++@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@assafe{}@acsafe{}} + The @code{tfind} function is similar to the @code{tsearch} function. It + locates an element matching the one pointed to by @var{key} and returns + a pointer to this element. But if no matching element is available no +@@ -479,6 +548,7 @@ + @comment search.h + @comment SVID + @deftypefun {void *} tdelete (const void *@var{key}, void **@var{rootp}, comparison_fn_t @var{compar}) ++@safety{@prelim{}@mtsafe{@mtsrace{:rootp}}@asunsafe{@ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} + To remove a specific element matching @var{key} from the tree + @code{tdelete} can be used. It locates the matching element using the + same method as @code{tfind}. The corresponding element is then removed +@@ -492,6 +562,7 @@ + @comment search.h + @comment GNU + @deftypefun void tdestroy (void *@var{vroot}, __free_fn_t @var{freefct}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + If the complete search tree has to be removed one can use + @code{tdestroy}. It frees all resources allocated by the @code{tsearch} + function to generate the tree pointed to by @var{vroot}. +@@ -546,6 +617,7 @@ + @comment search.h + @comment SVID + @deftypefun void twalk (const void *@var{root}, __action_fn_t @var{action}) ++@safety{@prelim{}@mtsafe{@mtsrace{:root}}@assafe{}@acsafe{}} + For each node in the tree with a node pointed to by @var{root}, the + @code{twalk} function calls the function provided by the parameter + @var{action}. For leaf nodes the function is called exactly once with +diff -urN glibc-2.17-c758a686/manual/setjmp.texi glibc-2.17-c758a686/manual/setjmp.texi +--- glibc-2.17-c758a686/manual/setjmp.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/setjmp.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -107,6 +107,10 @@ + @comment setjmp.h + @comment ISO + @deftypefn Macro int setjmp (jmp_buf @var{state}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c _setjmp ok ++@c __sigsetjmp(!savemask) ok ++@c __sigjmp_save(!savemask) ok, does not call sigprocmask + When called normally, @code{setjmp} stores information about the + execution state of the program in @var{state} and returns zero. If + @code{longjmp} is later used to perform a non-local exit to this +@@ -116,6 +120,20 @@ + @comment setjmp.h + @comment ISO + @deftypefun void longjmp (jmp_buf @var{state}, int @var{value}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}} ++@c __libc_siglongjmp @ascuplugin @asucorrupt @asulock/hurd @acucorrupt @aculock/hurd ++@c _longjmp_unwind @ascuplugin @asucorrupt @acucorrupt ++@c __pthread_cleanup_upto @ascuplugin @asucorrupt @acucorrupt ++@c plugins may be unsafe themselves, but even if they weren't, this ++@c function isn't robust WRT async signals and cancellation: ++@c cleanups aren't taken off the stack right away, only after all ++@c cleanups have been run. This means that async-cancelling ++@c longjmp, or interrupting longjmp with an async signal handler ++@c that calls longjmp may run the same cleanups multiple times. ++@c _JMPBUF_UNWINDS_ADJ ok ++@c *cleanup_buf->__routine @ascuplugin ++@c sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd ++@c __longjmp ok + This function restores current execution to the state saved in + @var{state}, and continues execution from the call to @code{setjmp} that + established that return point. Returning from @code{setjmp} by means of +@@ -141,7 +159,7 @@ + statement (such as @samp{if}, @samp{switch}, or @samp{while}). + + @item +-As one operand of a equality or comparison operator that appears as the ++As one operand of an equality or comparison operator that appears as the + test expression of a selection or iteration statement. The other + operand must be an integer constant expression. + +@@ -199,6 +217,11 @@ + @comment setjmp.h + @comment POSIX.1 + @deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c sigsetjmp @asulock/hurd @aculock/hurd ++@c __sigsetjmp(savemask) @asulock/hurd @aculock/hurd ++@c __sigjmp_save(savemask) @asulock/hurd @aculock/hurd ++@c sigprocmask(SIG_BLOCK probe) dup @asulock/hurd @aculock/hurd + This is similar to @code{setjmp}. If @var{savesigs} is nonzero, the set + of blocked signals is saved in @var{state} and will be restored if a + @code{siglongjmp} is later performed with this @var{state}. +@@ -207,6 +230,8 @@ + @comment setjmp.h + @comment POSIX.1 + @deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}} ++@c Alias to longjmp. + This is similar to @code{longjmp} except for the type of its @var{state} + argument. If the @code{sigsetjmp} call that set this @var{state} used a + nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of +@@ -237,7 +262,7 @@ + @comment SVID + @deftp {Data Type} ucontext_t + +-The @code{ucontext_t} type is defined as a structure with as least the ++The @code{ucontext_t} type is defined as a structure with at least the + following elements: + + @table @code +@@ -267,6 +292,10 @@ + @comment ucontext.h + @comment SVID + @deftypefun int getcontext (ucontext_t *@var{ucp}) ++@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}} ++@c Linux-only implementations in assembly, including sigprocmask ++@c syscall. A few cases call the sigprocmask function, but that's safe ++@c too. The ppc case is implemented in terms of a swapcontext syscall. + The @code{getcontext} function initializes the variable pointed to by + @var{ucp} with the context of the calling thread. The context contains + the content of the registers, the signal mask, and the current stack. +@@ -278,25 +307,26 @@ + @end deftypefun + + The @code{getcontext} function is similar to @code{setjmp} but it does +-not provide an indication of whether the function returns for the first +-time or whether the initialized context was used and the execution is +-resumed at just that point. If this is necessary the user has to take +-determine this herself. This must be done carefully since the context +-contains registers which might contain register variables. This is a +-good situation to define variables with @code{volatile}. ++not provide an indication of whether @code{getcontext} is returning for ++the first time or whether an initialized context has just been restored. ++If this is necessary the user has to determine this herself. This must ++be done carefully since the context contains registers which might contain ++register variables. This is a good situation to define variables with ++@code{volatile}. + + Once the context variable is initialized it can be used as is or it can +-be modified. The latter is normally done to implement co-routines or +-similar constructs. The @code{makecontext} function is what has to be +-used to do that. ++be modified using the @code{makecontext} function. The latter is normally ++done when implementing co-routines or similar constructs. + + @comment ucontext.h + @comment SVID + @deftypefun void makecontext (ucontext_t *@var{ucp}, void (*@var{func}) (void), int @var{argc}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}} ++@c Linux-only implementations mostly in assembly, nothing unsafe. + +-The @var{ucp} parameter passed to the @code{makecontext} shall be ++The @var{ucp} parameter passed to @code{makecontext} shall be + initialized by a call to @code{getcontext}. The context will be +-modified to in a way so that if the context is resumed it will start by ++modified in a way such that if the context is resumed it will start by + calling the function @code{func} which gets @var{argc} integer arguments + passed. The integer arguments which are to be passed should follow the + @var{argc} parameter in the call to @code{makecontext}. +@@ -316,7 +346,7 @@ + While allocating the memory for the stack one has to be careful. Most + modern processors keep track of whether a certain memory region is + allowed to contain code which is executed or not. Data segments and +-heap memory is normally not tagged to allow this. The result is that ++heap memory are normally not tagged to allow this. The result is that + programs would fail. Examples for such code include the calling + sequences the GNU C compiler generates for calls to nested functions. + Safe ways to allocate stacks correctly include using memory on the +@@ -332,13 +362,22 @@ + allocated for the stack and the size of the memory region is stored in + @code{ss_size}. There are implements out there which require + @code{ss_sp} to be set to the value the stack pointer will have (which +-can depending on the direction the stack grows be different). This ++can, depending on the direction the stack grows, be different). This + difference makes the @code{makecontext} function hard to use and it + requires detection of the platform at compile time. + + @comment ucontext.h + @comment SVID + @deftypefun int setcontext (const ucontext_t *@var{ucp}) ++@safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@c Linux-only implementations mostly in assembly. Some ports use ++@c sigreturn or swapcontext syscalls; others restore the signal mask ++@c first and then proceed restore other registers in userland, which ++@c leaves a window for cancellation or async signals with misaligned or ++@c otherwise corrupt stack. ??? Switching to a different stack, or even ++@c to an earlier state on the same stack, may conflict with pthread ++@c cleanups. This is not quite MT-Unsafe, it's a different kind of ++@c safety issue. + + The @code{setcontext} function restores the context described by + @var{ucp}. The context is not modified and can be reused as often as +@@ -357,6 +396,9 @@ + terminates normally with an exit status value of @code{EXIT_SUCCESS} + (@pxref{Program Termination}). + ++If the context was created by a call to a signal handler or from any ++other source then the behaviour of @code{setcontext} is unspecified. ++ + Since the context contains information about the stack no two threads + should use the same context at the same time. The result in most cases + would be disastrous. +@@ -372,6 +414,10 @@ + @comment ucontext.h + @comment SVID + @deftypefun int swapcontext (ucontext_t *restrict @var{oucp}, const ucontext_t *restrict @var{ucp}) ++@safety{@prelim{}@mtsafe{@mtsrace{:oucp} @mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@c Linux-only implementations mostly in assembly. Some ports call or ++@c inline getcontext and/or setcontext, adjusting the saved context in ++@c between, so we inherit the potential issues of both. + + The @code{swapcontext} function is similar to @code{setcontext} but + instead of just replacing the current context the latter is first saved +@@ -385,15 +431,15 @@ + If @code{swapcontext} succeeds the function does not return unless the + context @var{oucp} is used without prior modification by + @code{makecontext}. The return value in this case is @code{0}. If the +-function fails it returns @code{-1} and set @var{errno} accordingly. ++function fails it returns @code{-1} and sets @var{errno} accordingly. + @end deftypefun + + @heading Example for SVID Context Handling + + The easiest way to use the context handling functions is as a + replacement for @code{setjmp} and @code{longjmp}. The context contains +-on most platforms more information which might lead to less surprises +-but this also means using these functions is more expensive (beside ++on most platforms more information which may lead to fewer surprises ++but this also means using these functions is more expensive (besides + being less portable). + + @smallexample +@@ -440,11 +486,11 @@ + This an example how the context functions can be used to implement + co-routines or cooperative multi-threading. All that has to be done is + to call every once in a while @code{swapcontext} to continue running a +-different context. It is not allowed to do the context switching from +-the signal handler directly since neither @code{setcontext} nor +-@code{swapcontext} are functions which can be called from a signal +-handler. But setting a variable in the signal handler and checking it +-in the body of the functions which are executed. Since +-@code{swapcontext} is saving the current context it is possible to have +-multiple different scheduling points in the code. Execution will always +-resume where it was left. ++different context. It is not recommended to do the context switching from ++the signal handler directly since leaving the signal handler via ++@code{setcontext} if the signal was delivered during code that was not ++asynchronous signal safe could lead to problems. Setting a variable in ++the signal handler and checking it in the body of the functions which ++are executed is a safer approach. Since @code{swapcontext} is saving the ++current context it is possible to have multiple different scheduling points ++in the code. Execution will always resume where it was left. +diff -urN glibc-2.17-c758a686/manual/signal.texi glibc-2.17-c758a686/manual/signal.texi +--- glibc-2.17-c758a686/manual/signal.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/signal.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -889,6 +889,20 @@ + @comment string.h + @comment GNU + @deftypefun {char *} strsignal (int @var{signum}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:strsignal} @mtslocale{}}@asunsafe{@asuinit{} @ascuintl{} @asucorrupt{} @ascuheap{}}@acunsafe{@acuinit{} @acucorrupt{} @acsmem{}}} ++@c strsignal @mtasurace:strsignal @mtslocale @asuinit @ascuintl @asucorrupt @ascuheap @acucorrupt @acsmem ++@c uses a static buffer if tsd key creation fails ++@c [once] init ++@c libc_key_create ok ++@c pthread_key_create dup ok ++@c getbuffer @asucorrupt @ascuheap @acsmem ++@c libc_getspecific ok ++@c pthread_getspecific dup ok ++@c malloc dup @ascuheap @acsmem ++@c libc_setspecific @asucorrupt @ascuheap @acucorrupt @acsmem ++@c pthread_setspecific dup @asucorrupt @ascuheap @acucorrupt @acsmem ++@c snprintf dup @mtslocale @ascuheap @acsmem ++@c _ @ascuintl + This function returns a pointer to a statically-allocated string + containing a message describing the signal @var{signum}. You + should not modify the contents of this string; and, since it can be +@@ -903,6 +917,12 @@ + @comment signal.h + @comment BSD + @deftypefun void psignal (int @var{signum}, const char *@var{message}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuintl{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}} ++@c psignal @mtslocale @asucorrupt @ascuintl @ascuheap @aculock @acucorrupt @acsmem ++@c _ @ascuintl ++@c fxprintf @asucorrupt @aculock @acucorrupt ++@c asprintf @mtslocale @ascuheap @acsmem ++@c free dup @ascuheap @acsmem + This function prints a message describing the signal @var{signum} to the + standard error output stream @code{stderr}; see @ref{Standard Streams}. + +@@ -972,6 +992,12 @@ + @comment signal.h + @comment ISO + @deftypefun sighandler_t signal (int @var{signum}, sighandler_t @var{action}) ++@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}} ++@c signal ok ++@c sigemptyset dup ok ++@c sigaddset dup ok ++@c sigismember dup ok ++@c sigaction dup ok + The @code{signal} function establishes @var{action} as the action for + the signal @var{signum}. + +@@ -1094,6 +1120,10 @@ + @comment signal.h + @comment GNU + @deftypefun sighandler_t sysv_signal (int @var{signum}, sighandler_t @var{action}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c sysv_signal ok ++@c sigemptyset dup ok ++@c sigaction dup ok + The @code{sysv_signal} implements the behavior of the standard + @code{signal} function as found on SVID systems. The difference to BSD + systems is that the handler is deinstalled after a delivery of a signal. +@@ -1106,6 +1136,8 @@ + @comment signal.h + @comment SVID + @deftypefun sighandler_t ssignal (int @var{signum}, sighandler_t @var{action}) ++@safety{@prelim{}@mtsafe{@mtssigintr{}}@assafe{}@acsafe{}} ++@c Aliases signal and bsd_signal. + The @code{ssignal} function does the same thing as @code{signal}; it is + provided only for compatibility with SVID. + @end deftypefun +@@ -1172,6 +1204,7 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigaction (int @var{signum}, const struct sigaction *restrict @var{action}, struct sigaction *restrict @var{old-action}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @var{action} argument is used to set up a new action for the signal + @var{signum}, while the @var{old-action} argument is used to return + information about the action previously associated with this symbol. +@@ -2168,6 +2194,14 @@ + @comment signal.h + @comment ISO + @deftypefun int raise (int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c raise ok ++@c [posix] ++@c getpid dup ok ++@c kill dup ok ++@c [linux] ++@c syscall(gettid) ok ++@c syscall(tgkill) ok + The @code{raise} function sends the signal @var{signum} to the calling + process. It returns zero if successful and a nonzero value if it fails. + About the only reason for failure would be if the value of @var{signum} +@@ -2177,6 +2211,8 @@ + @comment signal.h + @comment SVID + @deftypefun int gsignal (int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Aliases raise. + The @code{gsignal} function does the same thing as @code{raise}; it is + provided only for compatibility with SVID. + @end deftypefun +@@ -2269,6 +2305,11 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int kill (pid_t @var{pid}, int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c The hurd implementation is not a critical section, so it's not ++@c immediately obvious that, in case of cancellation, it won't leak ++@c ports or the memory allocated by proc_getpgrppids when pid <= 0. ++@c Since none of these make it AC-Unsafe, I'm leaving them out. + The @code{kill} function sends the signal @var{signum} to the process + or process group specified by @var{pid}. Besides the signals listed in + @ref{Standard Signals}, @var{signum} can also have a value of zero to +@@ -2325,6 +2366,8 @@ + @comment signal.h + @comment BSD + @deftypefun int killpg (int @var{pgid}, int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Calls kill with -pgid. + This is similar to @code{kill}, but sends signal @var{signum} to the + process group @var{pgid}. This function is provided for compatibility + with BSD; using @code{kill} to do this is more portable. +@@ -2497,6 +2540,8 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigemptyset (sigset_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Just memsets all of set to zero. + This function initializes the signal set @var{set} to exclude all of the + defined signals. It always returns @code{0}. + @end deftypefun +@@ -2504,6 +2549,7 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigfillset (sigset_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function initializes the signal set @var{set} to include + all of the defined signals. Again, the return value is @code{0}. + @end deftypefun +@@ -2511,6 +2557,7 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigaddset (sigset_t *@var{set}, int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function adds the signal @var{signum} to the signal set @var{set}. + All @code{sigaddset} does is modify @var{set}; it does not block or + unblock any signals. +@@ -2527,6 +2574,7 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigdelset (sigset_t *@var{set}, int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function removes the signal @var{signum} from the signal set + @var{set}. All @code{sigdelset} does is modify @var{set}; it does not + block or unblock any signals. The return value and error conditions are +@@ -2538,6 +2586,7 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigismember (const sigset_t *@var{set}, int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{sigismember} function tests whether the signal @var{signum} is + a member of the signal set @var{set}. It returns @code{1} if the signal + is in the set, @code{0} if not, and @code{-1} if there is an error. +@@ -2566,7 +2615,7 @@ + + Note that you must not use @code{sigprocmask} in multi-threaded processes, + because each thread has its own signal mask and there is no single process +-signal mask. According to POSIX, the behavior of @code{sigprocmask} in a ++signal mask. According to POSIX, the behavior of @code{sigprocmask} in a + multi-threaded process is ``unspecified''. + Instead, use @code{pthread_sigmask}. + @ifset linuxthreads +@@ -2576,6 +2625,10 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigprocmask (int @var{how}, const sigset_t *restrict @var{set}, sigset_t *restrict @var{oldset}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/bsd(SIG_UNBLOCK)}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c This takes the hurd_self_sigstate-returned object's lock on HURD. On ++@c BSD, SIG_UNBLOCK is emulated with two sigblock calls, which ++@c introduces a race window. + The @code{sigprocmask} function is used to examine or change the calling + process's signal mask. The @var{how} argument determines how the signal + mask is changed, and must be one of the following values: +@@ -2759,6 +2812,10 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigpending (sigset_t *@var{set}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c Direct rt_sigpending syscall on most systems. On hurd, calls ++@c hurd_self_sigstate, it copies the sigstate's pending while holding ++@c its lock. + The @code{sigpending} function stores information about pending signals + in @var{set}. If there is a pending signal that is blocked from + delivery, then that signal is a member of the returned set. (You can +@@ -2921,7 +2978,18 @@ + + @comment unistd.h + @comment POSIX.1 +-@deftypefun int pause () ++@deftypefun int pause (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c The signal mask read by sigprocmask may be overridden by another ++@c thread or by a signal handler before we call sigsuspend. Is this a ++@c safety issue? Probably not. ++@c pause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd ++@c [ports/linux/generic] ++@c syscall_pause ok ++@c [posix] ++@c sigemptyset dup ok ++@c sigprocmask(SIG_BLOCK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)] ++@c sigsuspend dup @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd + The @code{pause} function suspends program execution until a signal + arrives whose action is either to execute a handler function, or to + terminate the process. +@@ -3017,6 +3085,18 @@ + @comment signal.h + @comment POSIX.1 + @deftypefun int sigsuspend (const sigset_t *@var{set}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c sigsuspend @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd ++@c [posix] @mtasurace:sigprocmask/!bsd!linux ++@c saving and restoring the procmask is racy ++@c sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)] ++@c pause @asulock/hurd @aculock/hurd ++@c [bsd] ++@c sigismember dup ok ++@c sigmask dup ok ++@c sigpause dup ok [no @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd] ++@c [linux] ++@c do_sigsuspend ok + This function replaces the process's signal mask with @var{set} and then + suspends the process until a signal is delivered whose action is either + to terminate the process or invoke a signal handling function. In other +@@ -3150,6 +3230,9 @@ + @comment signal.h + @comment XPG + @deftypefun int sigaltstack (const stack_t *restrict @var{stack}, stack_t *restrict @var{oldstack}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c Syscall on Linux and BSD; the HURD implementation takes a lock on ++@c the hurd_self_sigstate-returned struct. + The @code{sigaltstack} function specifies an alternate stack for use + during signal handling. When a signal is received by the process and + its action indicates that the signal stack is used, the system arranges +@@ -3195,7 +3278,9 @@ + + @comment signal.h + @comment BSD +-@deftypefun int sigstack (const struct sigstack *@var{stack}, struct sigstack *@var{oldstack}) ++@deftypefun int sigstack (struct sigstack *@var{stack}, struct sigstack *@var{oldstack}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c Lossy and dangerous (no size limit) wrapper for sigaltstack. + The @code{sigstack} function specifies an alternate stack for use during + signal handling. When a signal is received by the process and its + action indicates that the signal stack is used, the system arranges a +@@ -3301,6 +3386,13 @@ + @comment signal.h + @comment BSD + @deftypefun int sigvec (int @var{signum}, const struct sigvec *@var{action}, struct sigvec *@var{old-action}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This is mostly a safe wrapper for sigaction. The exception are ++@c systems that lack SA_RESETHAND, in which a signal handler wrapper is ++@c used that calls sigaction to reset the handler before calling the ++@c user-supplied handler; it's unlikely that this emulation is used ++@c anywhere, for user-supplied flags and mask don't seem to be used ++@c the way one would expect. + This function is the equivalent of @code{sigaction} (@pxref{Advanced Signal + Handling}); it installs the action @var{action} for the signal @var{signum}, + returning information about the previous action in effect for that signal +@@ -3310,6 +3402,14 @@ + @comment signal.h + @comment BSD + @deftypefun int siginterrupt (int @var{signum}, int @var{failflag}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtssigintr{}}}@asunsafe{}@acunsafe{@acucorrupt{}}} ++@c This calls sigaction twice, once to get the current sigaction for the ++@c specified signal, another to apply the flags change. This could ++@c override the effects of a concurrent sigaction call. It also ++@c modifies without any guards the global _sigintr variable, that ++@c bsd_signal reads from, and it may leave _sigintr modified without ++@c overriding the active handler if cancelled between the two ++@c operations. + This function specifies which approach to use when certain primitives + are interrupted by handling signal @var{signum}. If @var{failflag} is + false, signal @var{signum} restarts primitives. If @var{failflag} is +@@ -3323,6 +3423,8 @@ + @comment signal.h + @comment BSD + @deftypefn Macro int sigmask (int @var{signum}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c This just shifts signum. + This macro returns a signal mask that has the bit for signal @var{signum} + set. You can bitwise-OR the results of several calls to @code{sigmask} + together to specify more than one signal. For example, +@@ -3339,6 +3441,11 @@ + @comment signal.h + @comment BSD + @deftypefun int sigblock (int @var{mask}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c On most POSIX systems, this is a wrapper for sigprocmask(SIG_BLOCK). ++@c The exception are BSD systems other than 4.4, where it is a syscall. ++@c sigblock @asulock/hurd @aculock/hurd ++@c sigprocmask(SIG_BLOCK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)] + This function is equivalent to @code{sigprocmask} (@pxref{Process Signal + Mask}) with a @var{how} argument of @code{SIG_BLOCK}: it adds the + signals specified by @var{mask} to the calling process's set of blocked +@@ -3348,6 +3455,11 @@ + @comment signal.h + @comment BSD + @deftypefun int sigsetmask (int @var{mask}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c On most POSIX systems, this is a wrapper for sigprocmask(SIG_SETMASK). ++@c The exception are BSD systems other than 4.4, where it is a syscall. ++@c sigsetmask @asulock/hurd @aculock/hurd ++@c sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)] + This function equivalent to @code{sigprocmask} (@pxref{Process + Signal Mask}) with a @var{how} argument of @code{SIG_SETMASK}: it sets + the calling process's signal mask to @var{mask}. The return value is +@@ -3357,6 +3469,15 @@ + @comment signal.h + @comment BSD + @deftypefun int sigpause (int @var{mask}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:sigprocmask/!bsd!linux}}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} ++@c sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd ++@c [posix] ++@c __sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd ++@c do_sigpause @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd ++@c sigprocmask(0) dup @asulock/hurd @aculock/hurd [no @mtasurace:sigprocmask/bsd(SIG_UNBLOCK)] ++@c sigdelset dup ok ++@c sigset_set_old_mask dup ok ++@c sigsuspend dup @mtasurace:sigprocmask/!bsd!linux @asulock/hurd @aculock/hurd + This function is the equivalent of @code{sigsuspend} (@pxref{Waiting + for a Signal}): it sets the calling process's signal mask to @var{mask}, + and waits for a signal to arrive. On return the previous set of blocked +diff -urN glibc-2.17-c758a686/manual/socket.texi glibc-2.17-c758a686/manual/socket.texi +--- glibc-2.17-c758a686/manual/socket.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/socket.texi 2014-09-12 16:10:06.046792714 -0400 +@@ -394,6 +394,8 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int bind (int @var{socket}, struct sockaddr *@var{addr}, socklen_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, except on Hurd. + The @code{bind} function assigns an address to the socket + @var{socket}. The @var{addr} and @var{length} arguments specify the + address; the detailed format of the address depends on the namespace. +@@ -442,6 +444,9 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int getsockname (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsmem{/hurd}}} ++@c Direct syscall, except on Hurd, where it seems like it might leak ++@c VM if cancelled. + The @code{getsockname} function returns information about the + address of the socket @var{socket} in the locations specified by the + @var{addr} and @var{length-ptr} arguments. Note that the +@@ -501,6 +506,14 @@ + @comment net/if.h + @comment IPv6 basic API + @deftypefun {unsigned int} if_nametoindex (const char *@var{ifname}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c It opens a socket to use ioctl on the fd to get the index. ++@c opensock may call socket and access multiple times until it finds a ++@c socket family that works. The Linux implementation has a potential ++@c concurrency issue WRT last_type and last_family not being updated ++@c atomically, but it is harmless; the generic implementation, OTOH, ++@c takes a lock, which makes all callers AS- and AC-Unsafe. ++@c opensock @asulock @aculock @acsfd + This function yields the interface index corresponding to a particular + name. If no interface exists with the name given, it returns 0. + @end deftypefun +@@ -508,6 +521,9 @@ + @comment net/if.h + @comment IPv6 basic API + @deftypefun {char *} if_indextoname (unsigned int @var{ifindex}, char *@var{ifname}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c It opens a socket with opensock to use ioctl on the fd to get the ++@c name from the index. + This function maps an interface index to its corresponding name. The + returned name is placed in the buffer pointed to by @code{ifname}, which + must be at least @code{IFNAMSIZ} bytes in length. If the index was +@@ -534,6 +550,39 @@ + @comment net/if.h + @comment IPv6 basic API + @deftypefun {struct if_nameindex *} if_nameindex (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{/hurd}}@acunsafe{@aculock{/hurd} @acsfd{} @acsmem{}}} ++@c if_nameindex @ascuheap @asulock/hurd @aculock/hurd @acsfd @acsmem ++@c [linux] ++@c netlink_open @acsfd @acsmem/hurd ++@c socket dup @acsfd ++@c memset dup ok ++@c bind dup ok ++@c netlink_close dup @acsfd ++@c getsockname dup @acsmem/hurd ++@c netlink_request @ascuheap @acsmem ++@c getpagesize dup ok ++@c malloc dup @ascuheap @acsmem ++@c netlink_sendreq ok ++@c memset dup ok ++@c sendto dup ok ++@c recvmsg dup ok ++@c memcpy dup ok ++@c free dup @ascuheap @acsmem ++@c netlink_free_handle @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c netlink_close @acsfd ++@c close dup @acsfd ++@c malloc dup @asuheap @acsmem ++@c strndup @ascuheap @acsmem ++@c if_freenameindex @ascuheap @acsmem ++@c [hurd] ++@c opensock dup @asulock @aculock @acsfd ++@c hurd_socket_server ok ++@c pfinet_siocgifconf ok ++@c malloc @ascuheap @acsmem ++@c strdup @ascuheap @acsmem ++@c ioctl dup ok ++@c free @ascuheap @acsmem + This function returns an array of @code{if_nameindex} structures, one + for every interface that is present. The end of the list is indicated + by a structure with an interface of 0 and a null name pointer. If an +@@ -546,6 +595,9 @@ + @comment net/if.h + @comment IPv6 basic API + @deftypefun void if_freenameindex (struct if_nameindex *@var{ptr}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c if_freenameindex @ascuheap @acsmem ++@c free dup @ascuheap @acsmem + This function frees the structure returned by an earlier call to + @code{if_nameindex}. + @end deftypefun +@@ -660,6 +712,7 @@ + @comment sys/un.h + @comment BSD + @deftypefn {Macro} int SUN_LEN (@emph{struct sockaddr_un *} @var{ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The macro computes the length of socket address in the local namespace. + @end deftypefn + +@@ -689,7 +742,7 @@ + To create a socket in the IPv4 Internet namespace, use the symbolic name + @code{PF_INET} of this namespace as the @var{namespace} argument to + @code{socket} or @code{socketpair}. For IPv6 addresses you need the +-macro @code{PF_INET6}. These macros are defined in @file{sys/socket.h}. ++macro @code{PF_INET6}. These macros are defined in @file{sys/socket.h}. + @pindex sys/socket.h + + @comment sys/socket.h +@@ -726,12 +779,12 @@ + * Internet Address Formats:: How socket addresses are specified in the + Internet namespace. + * Host Addresses:: All about host addresses of Internet host. +-* Protocols Database:: Referring to protocols by name. + * Ports:: Internet port numbers. + * Services Database:: Ports may have symbolic names. + * Byte Order:: Different hosts may use different byte + ordering conventions; you need to + canonicalize host address and port number. ++* Protocols Database:: Referring to protocols by name. + * Inet Example:: Putting it all together. + @end menu + +@@ -1035,6 +1088,13 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun int inet_aton (const char *@var{name}, struct in_addr *@var{addr}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c inet_aton @mtslocale ++@c isdigit dup @mtslocale ++@c strtoul dup @mtslocale ++@c isascii dup @mtslocale ++@c isspace dup @mtslocale ++@c htonl dup ok + This function converts the IPv4 Internet host address @var{name} + from the standard numbers-and-dots notation into binary data and stores + it in the @code{struct in_addr} that @var{addr} points to. +@@ -1044,10 +1104,13 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun {uint32_t} inet_addr (const char *@var{name}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c inet_addr @mtslocale ++@c inet_aton dup @mtslocale + This function converts the IPv4 Internet host address @var{name} from the + standard numbers-and-dots notation into binary data. If the input is + not valid, @code{inet_addr} returns @code{INADDR_NONE}. This is an +-obsolete interface to @code{inet_aton}, described immediately above. It ++obsolete interface to @code{inet_aton}, described immediately above. It + is obsolete because @code{INADDR_NONE} is a valid address + (255.255.255.255), and @code{inet_aton} provides a cleaner way to + indicate error return. +@@ -1056,9 +1119,15 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun {uint32_t} inet_network (const char *@var{name}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c inet_network @mtslocale ++@c isdigit dup @mtslocale ++@c isxdigit dup @mtslocale ++@c tolower dup @mtslocale ++@c isspace dup @mtslocale + This function extracts the network number from the address @var{name}, +-given in the standard numbers-and-dots notation. The returned address is +-in host order. If the input is not valid, @code{inet_network} returns ++given in the standard numbers-and-dots notation. The returned address is ++in host order. If the input is not valid, @code{inet_network} returns + @code{-1}. + + The function works only with traditional IPv4 class A, B and C network +@@ -1069,6 +1138,10 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun {char *} inet_ntoa (struct in_addr @var{addr}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asurace{}}@acsafe{}} ++@c inet_ntoa @mtslocale @asurace ++@c writes to a thread-local static buffer ++@c snprintf @mtslocale [no @ascuheap or @acsmem] + This function converts the IPv4 Internet host address @var{addr} to a + string in the standard numbers-and-dots notation. The return value is + a pointer into a statically-allocated buffer. Subsequent calls will +@@ -1087,6 +1160,9 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun {struct in_addr} inet_makeaddr (uint32_t @var{net}, uint32_t @var{local}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c inet_makeaddr ok ++@c htonl dup ok + This function makes an IPv4 Internet host address by combining the network + number @var{net} with the local-address-within-network number + @var{local}. +@@ -1095,6 +1171,11 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun uint32_t inet_lnaof (struct in_addr @var{addr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c inet_lnaof ok ++@c ntohl dup ok ++@c IN_CLASSA ok ++@c IN_CLASSB ok + This function returns the local-address-within-network part of the + Internet host address @var{addr}. + +@@ -1106,6 +1187,11 @@ + @comment arpa/inet.h + @comment BSD + @deftypefun uint32_t inet_netof (struct in_addr @var{addr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c inet_netof ok ++@c ntohl dup ok ++@c IN_CLASSA ok ++@c IN_CLASSB ok + This function returns the network number part of the Internet host + address @var{addr}. + +@@ -1117,6 +1203,16 @@ + @comment arpa/inet.h + @comment IPv6 basic API + @deftypefun int inet_pton (int @var{af}, const char *@var{cp}, void *@var{buf}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c inet_pton @mtslocale ++@c inet_pton4 ok ++@c memcpy dup ok ++@c inet_pton6 @mtslocale ++@c memset dup ok ++@c tolower dup @mtslocale ++@c strchr dup ok ++@c inet_pton4 dup ok ++@c memcpy dup ok + This function converts an Internet address (either IPv4 or IPv6) from + presentation (textual) to network (binary) format. @var{af} should be + either @code{AF_INET} or @code{AF_INET6}, as appropriate for the type of +@@ -1127,7 +1223,17 @@ + + @comment arpa/inet.h + @comment IPv6 basic API +-@deftypefun {const char *} inet_ntop (int @var{af}, const void *@var{cp}, char *@var{buf}, size_t @var{len}) ++@deftypefun {const char *} inet_ntop (int @var{af}, const void *@var{cp}, char *@var{buf}, socklen_t @var{len}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c inet_ntop @mtslocale ++@c inet_ntop4 @mtslocale ++@c sprintf dup @mtslocale [no @ascuheap or @acsmem] ++@c strcpy dup ok ++@c inet_ntop6 @mtslocale ++@c memset dup ok ++@c inet_ntop4 dup @mtslocale ++@c sprintf dup @mtslocale [no @ascuheap or @acsmem] ++@c strcpy dup ok + This function converts an Internet address (either IPv4 or IPv6) from + network (binary) to presentation (textual) form. @var{af} should be + either @code{AF_INET} or @code{AF_INET6}, as appropriate. @var{cp} is a +@@ -1211,6 +1317,71 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct hostent *} gethostbyname (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c gethostbyname @mtasurace:hostbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c nss_hostname_digits_dots @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_maybe_init(!preinit) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_iclose @acsuheap @acsmem @acsfd ++@c close_not_cancel_no_status dup @acsfd ++@c free dup @acsuheap @acsmem ++@c res_vinit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_randomid ok ++@c getpid dup ok ++@c getenv dup @mtsenv ++@c strncpy dup ok ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking dup ok [no concurrent uses] ++@c fgets_unlocked dup ok [no concurrent uses] ++@c MATCH ok ++@c strncmp dup ok ++@c strpbrk dup ok ++@c strchr dup ok ++@c inet_aton dup @mtslocale ++@c htons dup ++@c inet_pton dup @mtslocale ++@c malloc dup @ascuheap @acsmem ++@c IN6_IS_ADDR_LINKLOCAL ok ++@c htonl dup ok ++@c IN6_IS_ADDR_MC_LINKLOCAL ok ++@c if_nametoindex dup @asulock @aculock @acsfd ++@c strtoul dup @mtslocale ++@c ISSORTMASK ok ++@c strchr dup ok ++@c isascii dup @mtslocale ++@c isspace dup @mtslocale ++@c net_mask ok ++@c ntohl dup ok ++@c IN_CLASSA dup ok ++@c htonl dup ok ++@c IN_CLASSB dup ok ++@c res_setoptions @mtslocale ++@c strncmp dup ok ++@c atoi dup @mtslocale ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c inet_makeaddr dup ok ++@c gethostname dup ok ++@c strcpy dup ok ++@c rawmemchr dup ok ++@c res_ninit @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_vinit dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c isdigit dup @mtslocale ++@c isxdigit dup @mtslocale ++@c strlen dup ok ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c memset dup ok ++@c inet_aton dup @mtslocale ++@c inet_pton dup @mtslocale ++@c strcpy dup ok ++@c memcpy dup ok ++@c strchr dup ok ++@c gethostbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c set_h_errno ok + The @code{gethostbyname} function returns information about the host + named @var{name}. If the lookup fails, it returns a null pointer. + @end deftypefun +@@ -1218,6 +1389,16 @@ + @comment netdb.h + @comment IPv6 Basic API + @deftypefun {struct hostent *} gethostbyname2 (const char *@var{name}, int @var{af}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyname2} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c gethostbyname2 @mtasurace:hostbyname2 @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c gethostbyname2_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c set_h_errno dup ok + The @code{gethostbyname2} function is like @code{gethostbyname}, but + allows the caller to specify the desired address family (e.g.@: + @code{AF_INET} or @code{AF_INET6}) of the result. +@@ -1225,11 +1406,20 @@ + + @comment netdb.h + @comment BSD +-@deftypefun {struct hostent *} gethostbyaddr (const char *@var{addr}, size_t @var{length}, int @var{format}) ++@deftypefun {struct hostent *} gethostbyaddr (const void *@var{addr}, socklen_t @var{length}, int @var{format}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hostbyaddr} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c gethostbyaddr @mtasurace:hostbyaddr @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c gethostbyaddr_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c set_h_errno dup ok + The @code{gethostbyaddr} function returns information about the host + with Internet address @var{addr}. The parameter @var{addr} is not + really a pointer to char - it can be a pointer to an IPv4 or an IPv6 +-address. The @var{length} argument is the size (in bytes) of the address ++address. The @var{length} argument is the size (in bytes) of the address + at @var{addr}. @var{format} specifies the address format; for an IPv4 + Internet address, specify a value of @code{AF_INET}; for an IPv6 + Internet address, use @code{AF_INET6}. +@@ -1282,6 +1472,76 @@ + @comment netdb.h + @comment GNU + @deftypefun int gethostbyname_r (const char *restrict @var{name}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c gethostbyname_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c nscd_gethostbyname_r @mtsenv @ascuheap @acsfd @acsmem ++@c nscd_gethst_r @mtsenv @ascuheap @acsfd @acsmem ++@c getenv dup @mtsenv ++@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem ++@c nscd_cache_search dup ok ++@c memcpy dup ok ++@c nscd_open_socket dup @acsfd ++@c readvall dup ok ++@c readall dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref dup @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_hconf_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called] ++@c res_hconf.c:do_init @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c memset dup ok ++@c getenv dup @mtsenv ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking dup ok [no concurrent uses] ++@c fgets_unlocked dup ok [no concurrent uses] ++@c strchrnul dup ok ++@c res_hconf.c:parse_line @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c skip_ws dup @mtslocale ++@c skip_string dup @mtslocale ++@c strncasecmp dup @mtslocale ++@c strlen dup ok ++@c asprintf dup @mtslocale @ascuheap @acsmem ++@c fxprintf dup @asucorrupt @aculock @acucorrupt ++@c free dup @ascuheap @acsmem ++@c arg_trimdomain_list dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c arg_spoof dup @mtslocale ++@c arg_bool dup @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c isspace dup @mtslocale ++@c fclose dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c arg_spoof @mtslocale ++@c skip_string @mtslocale ++@c isspace dup @mtslocale ++@c strncasecmp dup @mtslocale ++@c arg_bool @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c strncasecmp dup @mtslocale ++@c asprintf dup @mtslocale @ascuheap @acsmem ++@c fxprintf dup @asucorrupt @aculock @acucorrupt ++@c free dup @ascuheap @acsmem ++@c arg_trimdomain_list @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem ++@c skip_string dup @mtslocale ++@c asprintf dup @mtslocale @ascuheap @acsmem ++@c fxprintf dup @asucorrupt @aculock @acucorrupt ++@c free dup @ascuheap @acsmem ++@c strndup dup @ascuheap @acsmem ++@c skip_ws @mtslocale ++@c isspace dup @mtslocale ++@c nss_hosts_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_gethostbyname_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_hconf_reorder_addrs @asulock @ascuheap @aculock @acsmem @acsfd ++@c socket dup @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c ifreq @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c if_nextreq dup ok ++@c ioctl dup ok ++@c realloc dup @ascuheap @acsmem ++@c if_freereq dup @acsmem ++@c libc_lock_unlock dup @aculock ++@c close dup @acsfd + The @code{gethostbyname_r} function returns information about the host + named @var{name}. The caller must pass a pointer to an object of type + @code{struct hostent} in the @var{result_buf} parameter. In addition +@@ -1290,37 +1550,42 @@ + parameters. + + A pointer to the buffer, in which the result is stored, is available in +-@code{*@var{result}} after the function call successfully returned. If +-an error occurs or if no entry is found, the pointer @code{*@var{result}} +-is a null pointer. Success is signalled by a zero return value. If the +-function failed the return value is an error number. In addition to the +-errors defined for @code{gethostbyname} it can also be @code{ERANGE}. +-In this case the call should be repeated with a larger buffer. +-Additional error information is not stored in the global variable +-@code{h_errno} but instead in the object pointed to by @var{h_errnop}. ++@code{*@var{result}} after the function call successfully returned. The ++buffer passed as the @var{buf} parameter can be freed only once the caller ++has finished with the result hostent struct, or has copied it including all ++the other memory that it points to. If an error occurs or if no entry is ++found, the pointer @code{*@var{result}} is a null pointer. Success is ++signalled by a zero return value. If the function failed the return value ++is an error number. In addition to the errors defined for ++@code{gethostbyname} it can also be @code{ERANGE}. In this case the call ++should be repeated with a larger buffer. Additional error information is ++not stored in the global variable @code{h_errno} but instead in the object ++pointed to by @var{h_errnop}. + + Here's a small example: + @smallexample + struct hostent * + gethostname (char *host) + @{ +- struct hostent hostbuf, *hp; ++ struct hostent *hostbuf, *hp; + size_t hstbuflen; + char *tmphstbuf; + int res; + int herr; + ++ hostbuf = malloc (sizeof (struct hostent)); + hstbuflen = 1024; +- /* Allocate buffer, remember to free it to avoid memory leakage. */ + tmphstbuf = malloc (hstbuflen); + +- while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen, ++ while ((res = gethostbyname_r (host, hostbuf, tmphstbuf, hstbuflen, + &hp, &herr)) == ERANGE) + @{ + /* Enlarge the buffer. */ + hstbuflen *= 2; + tmphstbuf = realloc (tmphstbuf, hstbuflen); + @} ++ ++ free (tmphstbuf); + /* Check for errors. */ + if (res || hp == NULL) + return NULL; +@@ -1332,6 +1597,17 @@ + @comment netdb.h + @comment GNU + @deftypefun int gethostbyname2_r (const char *@var{name}, int @var{af}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c gethostbyname2_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c nss_hostname_digits_dots dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c nscd_gethostbyname2_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem ++@c nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called] ++@c nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_gethostbyname2_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_hconf_reorder_addrs dup @asulock @ascuheap @aculock @acsmem @acsfd + The @code{gethostbyname2_r} function is like @code{gethostbyname_r}, but + allows the caller to specify the desired address family (e.g.@: + @code{AF_INET} or @code{AF_INET6}) for the result. +@@ -1339,11 +1615,26 @@ + + @comment netdb.h + @comment GNU +-@deftypefun int gethostbyaddr_r (const char *@var{addr}, size_t @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop}) ++@deftypefun int gethostbyaddr_r (const void *@var{addr}, socklen_t @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c gethostbyaddr_r @mtsenv @mtslocale @ascudlopen @ascuplugin @asucorrupt @ascuheap @asulock @aculock @acucorrupt @acsmem @acsfd ++@c memcmp dup ok ++@c nscd_gethostbyaddr_r @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem ++@c nscd_gethst_r dup @mtsenv @ascuheap @asulock @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c res_hconf_init dup @mtsenv @mtslocale @asucorrupt @ascuheap @aculock @acucorrupt @acsmem [no @asuinit:reshconf @acuinit:reshconf, conditionally called] ++@c nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_gethostbyaddr_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_hconf_reorder_addrs dup @asulock @ascuheap @aculock @acsmem @acsfd ++@c res_hconf_trim_domains @mtslocale ++@c res_hconf_trim_domain @mtslocale ++@c strlen dup ok ++@c strcasecmp dup @mtslocale + The @code{gethostbyaddr_r} function returns information about the host + with Internet address @var{addr}. The parameter @var{addr} is not + really a pointer to char - it can be a pointer to an IPv4 or an IPv6 +-address. The @var{length} argument is the size (in bytes) of the address ++address. The @var{length} argument is the size (in bytes) of the address + at @var{addr}. @var{format} specifies the address format; for an IPv4 + Internet address, specify a value of @code{AF_INET}; for an IPv6 + Internet address, use @code{AF_INET6}. +@@ -1362,6 +1653,18 @@ + @comment netdb.h + @comment BSD + @deftypefun void sethostent (int @var{stayopen}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c sethostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_setent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c set_h_errno dup ok ++@c setup(nss_hosts_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *lookup_fct = nss_hosts_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:hostent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock dup @aculock + This function opens the hosts database to begin scanning it. You can + then call @code{gethostent} to read the entries. + +@@ -1377,6 +1680,27 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct hostent *} gethostent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtasurace{:hostentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c gethostent @mtasurace:hostent @mtasurace:hostentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent(gethostent_r) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c malloc dup @ascuheap @acsmem ++@c *func = gethostent_r dup @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c gethostent_r @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent_r(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c setup(nss_hosts_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:hostent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *sfct.f @mtasurace:hostent @ascuplugin ++@c libc_lock_unlock dup @aculock ++ + This function returns the next entry in the hosts database. It + returns a null pointer if there are no more entries. + @end deftypefun +@@ -1384,6 +1708,15 @@ + @comment netdb.h + @comment BSD + @deftypefun void endhostent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:hostent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endhostent @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c nss_endent(nss_hosts_lookup2) @mtasurace:hostent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:hostent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock @aculock + This function closes the hosts database. + @end deftypefun + +@@ -1483,6 +1816,34 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct servent *} getservbyname (const char *@var{name}, const char *@var{proto}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:servbyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getservbyname =~ getpwuid @mtasurace:servbyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getservbyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getservbyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getservbyname_r @ascuheap @acsfd @acsmem ++@c nscd_getserv_r @ascuheap @acsfd @acsmem ++@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c memcpy dup ok ++@c nscd_cache_search dup ok ++@c nscd_open_socket dup @acsfd ++@c readvall dup ok ++@c readall dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref dup @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c nss_services_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getservbyname_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getservbyname} function returns information about the + service named @var{name} using protocol @var{proto}. If it can't find + such a service, it returns a null pointer. +@@ -1494,6 +1855,21 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct servent *} getservbyport (int @var{port}, const char *@var{proto}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:servbyport} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getservbyport =~ getservbyname @mtasurace:servbyport @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getservbyport_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getservbyport_r =~ getservbyname_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getservbyport_r @ascuheap @acsfd @acsmem ++@c nscd_getserv_r dup @ascuheap @acsfd @acsmem ++@c nss_services_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getservbyport_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getservbyport} function returns information about the + service at port @var{port} using protocol @var{proto}. If it can't + find such a service, it returns a null pointer. +@@ -1507,6 +1883,16 @@ + @comment netdb.h + @comment BSD + @deftypefun void setservent (int @var{stayopen}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c setservent @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_setent(nss_services_lookup2) @mtasurace:servenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_services_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *lookup_fct = nss_services_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:servent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock dup @aculock + This function opens the services database to begin scanning it. + + If the @var{stayopen} argument is nonzero, this sets a flag so that +@@ -1519,6 +1905,25 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct servent *} getservent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtasurace{:serventbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getservent @mtasurace:servent @mtasurace:serventbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent(getservent_r) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c malloc dup @ascuheap @acsmem ++@c *func = getservent_r dup @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getservent_r @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent_r(nss_services_lookup2) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_services_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:servent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *sfct.f @mtasurace:servent @ascuplugin ++@c libc_lock_unlock dup @aculock + This function returns the next entry in the services database. If + there are no more entries, it returns a null pointer. + @end deftypefun +@@ -1526,6 +1931,14 @@ + @comment netdb.h + @comment BSD + @deftypefun void endservent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:servent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endservent @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c nss_endent(nss_services_lookup2) @mtasurace:servent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_services_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:servent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock @aculock + This function closes the services database. + @end deftypefun + +@@ -1571,6 +1984,11 @@ + @comment netinet/in.h + @comment BSD + @deftypefun {uint16_t} htons (uint16_t @var{hostshort}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c htons ok ++@c bswap_16 ok ++@c bswap_constant_16 ok ++ + This function converts the @code{uint16_t} integer @var{hostshort} from + host byte order to network byte order. + @end deftypefun +@@ -1578,6 +1996,8 @@ + @comment netinet/in.h + @comment BSD + @deftypefun {uint16_t} ntohs (uint16_t @var{netshort}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Alias to htons. + This function converts the @code{uint16_t} integer @var{netshort} from + network byte order to host byte order. + @end deftypefun +@@ -1585,6 +2005,9 @@ + @comment netinet/in.h + @comment BSD + @deftypefun {uint32_t} htonl (uint32_t @var{hostlong}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c htonl ok ++@c bswap_32 dup ok + This function converts the @code{uint32_t} integer @var{hostlong} from + host byte order to network byte order. + +@@ -1594,6 +2017,8 @@ + @comment netinet/in.h + @comment BSD + @deftypefun {uint32_t} ntohl (uint32_t @var{netlong}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Alias to htonl. + This function converts the @code{uint32_t} integer @var{netlong} from + network byte order to host byte order. + +@@ -1658,6 +2083,20 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct protoent *} getprotobyname (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:protobyname} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getprotobyname =~ getpwuid @mtasurace:protobyname @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getprotobyname_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getprotobyname_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c no nscd support ++@c nss_protocols_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getprotobyname_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getprotobyname} function returns information about the + network protocol named @var{name}. If there is no such protocol, it + returns a null pointer. +@@ -1666,6 +2105,20 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct protoent *} getprotobynumber (int @var{protocol}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:protobynumber} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getprotobynumber =~ getpwuid @mtasurace:protobynumber @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getprotobynumber_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getprotobynumber_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c no nscd support ++@c nss_protocols_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getprotobynumber_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getprotobynumber} function returns information about the + network protocol with number @var{protocol}. If there is no such + protocol, it returns a null pointer. +@@ -1678,6 +2131,16 @@ + @comment netdb.h + @comment BSD + @deftypefun void setprotoent (int @var{stayopen}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c setprotoent @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_setent(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_protocols_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *lookup_fct = nss_protocols_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:protoent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock dup @aculock + This function opens the protocols database to begin scanning it. + + If the @var{stayopen} argument is nonzero, this sets a flag so that +@@ -1690,6 +2153,25 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct protoent *} getprotoent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtasurace{:protoentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getprotoent @mtasurace:protoent @mtasurace:protoentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent(getprotoent_r) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c malloc dup @ascuheap @acsmem ++@c *func = getprotoent_r dup @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getprotoent_r @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent_r(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_protocols_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:servent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *sfct.f @mtasurace:protoent @ascuplugin ++@c libc_lock_unlock dup @aculock + This function returns the next entry in the protocols database. It + returns a null pointer if there are no more entries. + @end deftypefun +@@ -1697,6 +2179,14 @@ + @comment netdb.h + @comment BSD + @deftypefun void endprotoent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:protoent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endprotoent @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c nss_endent(nss_protocols_lookup2) @mtasurace:protoent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_protocols_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:protoent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock @aculock + This function closes the protocols database. + @end deftypefun + +@@ -1766,6 +2256,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int socket (int @var{namespace}, int @var{style}, int @var{protocol}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + This function creates a socket and specifies communication style + @var{style}, which should be one of the socket styles listed in + @ref{Communication Styles}. The @var{namespace} argument specifies +@@ -1828,6 +2319,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int shutdown (int @var{socket}, int @var{how}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{shutdown} function shuts down the connection of socket + @var{socket}. The argument @var{how} specifies what action to + perform: +@@ -1879,6 +2371,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int socketpair (int @var{namespace}, int @var{style}, int @var{protocol}, int @var{filedes}@t{[2]}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + This function creates a socket pair, returning the file descriptors in + @code{@var{filedes}[0]} and @code{@var{filedes}[1]}. The socket pair + is a full-duplex communications channel, so that both reading and writing +@@ -1972,6 +2465,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int connect (int @var{socket}, struct sockaddr *@var{addr}, socklen_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{connect} function initiates a connection from the socket + with file descriptor @var{socket} to the socket whose address is + specified by the @var{addr} and @var{length} arguments. (This socket +@@ -2071,6 +2565,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int listen (int @var{socket}, int @var{n}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + The @code{listen} function enables the socket @var{socket} to accept + connections, thus making it a server socket. + +@@ -2123,6 +2618,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int accept (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length_ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} + This function is used to accept a connection request on the server + socket @var{socket}. + +@@ -2181,6 +2677,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int getpeername (int @var{socket}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getpeername} function returns the address of the socket that + @var{socket} is connected to; it stores the address in the memory space + specified by @var{addr} and @var{length-ptr}. It stores the length of +@@ -2248,7 +2745,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int send (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}) ++@deftypefun ssize_t send (int @var{socket}, const void *@var{buffer}, size_t @var{size}, int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{send} function is like @code{write}, but with the additional + flags @var{flags}. The possible values of @var{flags} are described + in @ref{Socket Data Options}. +@@ -2315,7 +2813,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int recv (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}) ++@deftypefun ssize_t recv (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{recv} function is like @code{read}, but with the additional + flags @var{flags}. The possible values of @var{flags} are described + in @ref{Socket Data Options}. +@@ -2643,7 +3142,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int sendto (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t @var{length}) ++@deftypefun ssize_t sendto (int @var{socket}, const void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{sendto} function transmits the data in the @var{buffer} + through the socket @var{socket} to the destination address specified + by the @var{addr} and @var{length} arguments. The @var{size} argument +@@ -2678,7 +3178,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int recvfrom (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr}) ++@deftypefun ssize_t recvfrom (int @var{socket}, void *@var{buffer}, size_t @var{size}, int @var{flags}, struct sockaddr *@var{addr}, socklen_t *@var{length-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{recvfrom} function reads one packet from the socket + @var{socket} into the buffer @var{buffer}. The @var{size} argument + specifies the maximum number of bytes to be read. +@@ -2725,7 +3226,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags}) ++@deftypefun ssize_t sendmsg (int @var{socket}, const struct msghdr *@var{message}, int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + This function is defined as a cancellation point in multi-threaded + programs, so one has to be prepared for this and make sure that +@@ -2736,7 +3238,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags}) ++@deftypefun ssize_t recvmsg (int @var{socket}, struct msghdr *@var{message}, int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + This function is defined as a cancellation point in multi-threaded + programs, so one has to be prepared for this and make sure that +@@ -2924,6 +3427,7 @@ + @comment sys/socket.h + @comment BSD + @deftypefun int getsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, socklen_t *@var{optlen-ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getsockopt} function gets information about the value of + option @var{optname} at level @var{level} for socket @var{socket}. + +@@ -2953,7 +3457,8 @@ + + @comment sys/socket.h + @comment BSD +-@deftypefun int setsockopt (int @var{socket}, int @var{level}, int @var{optname}, void *@var{optval}, socklen_t @var{optlen}) ++@deftypefun int setsockopt (int @var{socket}, int @var{level}, int @var{optname}, const void *@var{optval}, socklen_t @var{optlen}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is used to set the socket option @var{optname} at level + @var{level} for socket @var{socket}. The value of the option is passed + in the buffer @var{optval} of size @var{optlen}. +@@ -3150,6 +3655,21 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct netent *} getnetbyname (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netbyname} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getnetbyname =~ getpwuid @mtasurace:netbyname @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getnetbyname_r dup @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getnetbyname_r =~ getpwuid_r @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c no nscd support ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getnetbyname_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getnetbyname} function returns information about the network + named @var{name}. It returns a null pointer if there is no such + network. +@@ -3157,7 +3677,21 @@ + + @comment netdb.h + @comment BSD +-@deftypefun {struct netent *} getnetbyaddr (unsigned long int @var{net}, int @var{type}) ++@deftypefun {struct netent *} getnetbyaddr (uint32_t @var{net}, int @var{type}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netbyaddr} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getnetbyaddr =~ getpwuid @mtasurace:netbyaddr @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getnetbyaddr_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getnetbyaddr_r =~ getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c no nscd support ++@c nss_networks_lookup2 =~ nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getnetbyaddr_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getnetbyaddr} function returns information about the network + of type @var{type} with number @var{net}. You should specify a value of + @code{AF_INET} for the @var{type} argument for Internet networks. +@@ -3173,6 +3707,17 @@ + @comment netdb.h + @comment BSD + @deftypefun void setnetent (int @var{stayopen}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c setnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_setent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c setup(nss_networks_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *lookup_fct = nss_networks_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:netent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock dup @aculock + This function opens and rewinds the networks database. + + If the @var{stayopen} argument is nonzero, this sets a flag so that +@@ -3185,6 +3730,26 @@ + @comment netdb.h + @comment BSD + @deftypefun {struct netent *} getnetent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtasurace{:netentbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getnetent @mtasurace:netent @mtasurace:netentbuf @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent(getnetent_r) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c malloc dup @ascuheap @acsmem ++@c *func = getnetent_r dup @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock ++@c ++@c getnetent_r @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent_r(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:servent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *sfct.f @mtasurace:netent @ascuplugin ++@c libc_lock_unlock dup @aculock + This function returns the next entry in the networks database. It + returns a null pointer if there are no more entries. + @end deftypefun +@@ -3192,5 +3757,14 @@ + @comment netdb.h + @comment BSD + @deftypefun void endnetent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netent} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endnetent @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c nss_endent(nss_networks_lookup2) @mtasurace:netent @mtsenv @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c res_maybe_init(!preinit) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c setup(nss_networks_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:netent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock @aculock + This function closes the networks database. + @end deftypefun +diff -urN glibc-2.17-c758a686/manual/startup.texi glibc-2.17-c758a686/manual/startup.texi +--- glibc-2.17-c758a686/manual/startup.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/startup.texi 2014-09-12 16:10:06.042792724 -0400 +@@ -41,7 +41,7 @@ + * Program Termination:: Telling the system you're done; return status + @end menu + +-@node Program Arguments ++@node Program Arguments, Environment Variables, , Program Basics + @section Program Arguments + @cindex program arguments + @cindex command line arguments +@@ -220,7 +220,12 @@ + available. + + @comment stdlib.h +-@deftypefun int getsubopt (char **@var{optionp}, const char* const *@var{tokens}, char **@var{valuep}) ++@deftypefun int getsubopt (char **@var{optionp}, char *const *@var{tokens}, char **@var{valuep}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c getsubopt ok ++@c strchrnul dup ok ++@c memchr dup ok ++@c strncmp dup ok + + The @var{optionp} parameter must be a pointer to a variable containing + the address of the string to process. When the function returns the +@@ -258,7 +263,7 @@ + @end smallexample + + +-@node Environment Variables ++@node Environment Variables, Auxiliary Vector, Program Arguments, Program Basics + @section Environment Variables + + @cindex environment variable +@@ -322,6 +327,8 @@ + @comment stdlib.h + @comment ISO + @deftypefun {char *} getenv (const char *@var{name}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@assafe{}@acsafe{}} ++@c Unguarded access to __environ. + This function returns a string that is the value of the environment + variable @var{name}. You must not modify this string. In some non-Unix + systems not using @theglibc{}, it might be overwritten by subsequent +@@ -333,6 +340,8 @@ + @comment stdlib.h + @comment GNU + @deftypefun {char *} secure_getenv (const char *@var{name}) ++@safety{@prelim{}@mtsafe{@mtsenv{}}@assafe{}@acsafe{}} ++@c Calls getenv unless secure mode is enabled. + This function is similar to @code{getenv}, but it returns a null + pointer if the environment is untrusted. This happens when the + program file has SUID or SGID bits set. General-purpose libraries +@@ -346,6 +355,13 @@ + @comment stdlib.h + @comment SVID + @deftypefun int putenv (char *@var{string}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c putenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c strchr dup ok ++@c strndup dup @ascuheap @acsmem ++@c add_to_environ dup @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c free dup @ascuheap @acsmem ++@c unsetenv dup @mtasuconst:@mtsenv @asulock @aculock + The @code{putenv} function adds or removes definitions from the environment. + If the @var{string} is of the form @samp{@var{name}=@var{value}}, the + definition is added to the environment. Otherwise, the @var{string} is +@@ -358,20 +374,37 @@ + The difference to the @code{setenv} function is that the exact string + given as the parameter @var{string} is put into the environment. If the + user should change the string after the @code{putenv} call this will +-reflect in automatically in the environment. This also requires that +-@var{string} is no automatic variable which scope is left before the ++reflect automatically in the environment. This also requires that ++@var{string} not be an automatic variable whose scope is left before the + variable is removed from the environment. The same applies of course to + dynamically allocated variables which are freed later. + +-This function is part of the extended Unix interface. Since it was also +-available in old SVID libraries you should define either +-@var{_XOPEN_SOURCE} or @var{_SVID_SOURCE} before including any header. ++This function is part of the extended Unix interface. You should define ++@var{_XOPEN_SOURCE} before including any header. + @end deftypefun + + + @comment stdlib.h + @comment BSD + @deftypefun int setenv (const char *@var{name}, const char *@var{value}, int @var{replace}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c setenv @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c add_to_environ @mtasuconst:@mtsenv @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c strlen dup ok ++@c libc_lock_lock @asulock @aculock ++@c strncmp dup ok ++@c realloc dup @ascuheap @acsmem ++@c libc_lock_unlock @aculock ++@c malloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c mempcpy dup ok ++@c memcpy dup ok ++@c KNOWN_VALUE ok ++@c tfind(strcmp) [no @mtsrace guarded access] ++@c strcmp dup ok ++@c STORE_VALUE @ascuheap @acucorrupt @acsmem ++@c tsearch(strcmp) @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt guarded access makes for mtsafe and @asulock] ++@c strcmp dup ok + The @code{setenv} function can be used to add a new definition to the + environment. The entry with the name @var{name} is replaced by the + value @samp{@var{name}=@var{value}}. Please note that this is also true +@@ -395,6 +428,13 @@ + @comment stdlib.h + @comment BSD + @deftypefun int unsetenv (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c unsetenv @mtasuconst:@mtsenv @asulock @aculock ++@c strchr dup ok ++@c strlen dup ok ++@c libc_lock_lock @asulock @aculock ++@c strncmp dup ok ++@c libc_lock_unlock @aculock + Using this function one can remove an entry completely from the + environment. If the environment contains an entry with the key + @var{name} this whole entry is removed. A call to this function is +@@ -418,6 +458,11 @@ + @comment stdlib.h + @comment GNU + @deftypefun int clearenv (void) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtsenv{}}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}} ++@c clearenv @mtasuconst:@mtsenv @ascuheap @asulock @aculock @acsmem ++@c libc_lock_lock @asulock @aculock ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock @aculock + The @code{clearenv} function removes all entries from the environment. + Using @code{putenv} and @code{setenv} new entries can be added again + later. +@@ -622,10 +667,13 @@ + @subsection Definition of @code{getauxval} + @comment sys/auxv.h + @deftypefun {unsigned long int} getauxval (unsigned long int @var{type}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Reads from hwcap or iterates over constant auxv. + This function is used to inquire about the entries in the auxiliary + vector. The @var{type} argument should be one of the @samp{AT_} symbols + defined in @file{elf.h}. If a matching entry is found, the value is +-returned; if the entry is not found, zero is returned. ++returned; if the entry is not found, zero is returned and @code{errno} is ++set to @code{ENOENT}. + @end deftypefun + + For some platforms, the key @code{AT_HWCAP} is the easiest way to inquire +@@ -677,6 +725,7 @@ + @comment unistd.h + @comment ??? + @deftypefun {long int} syscall (long int @var{sysno}, @dots{}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{syscall} performs a generic system call. + +@@ -782,6 +831,10 @@ + @comment stdlib.h + @comment ISO + @deftypefun void exit (int @var{status}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:exit}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} ++@c Access to the atexit/on_exit list, the libc_atexit hook and tls dtors ++@c is not guarded. Streams must be flushed, and that triggers the usual ++@c AS and AC issues with streams. + The @code{exit} function tells the system that the program is done, which + causes it to terminate the process. + +@@ -898,6 +951,15 @@ + @comment stdlib.h + @comment ISO + @deftypefun int atexit (void (*@var{function}) (void)) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}} ++@c atexit @ascuheap @asulock @aculock @acsmem ++@c cxa_atexit @ascuheap @asulock @aculock @acsmem ++@c __internal_atexit @ascuheap @asulock @aculock @acsmem ++@c __new_exitfn @ascuheap @asulock @aculock @acsmem ++@c __libc_lock_lock @asulock @aculock ++@c calloc dup @ascuheap @acsmem ++@c __libc_lock_unlock @aculock ++@c atomic_write_barrier dup ok + The @code{atexit} function registers the function @var{function} to be + called at normal program termination. The @var{function} is called with + no arguments. +@@ -909,6 +971,10 @@ + @comment stdlib.h + @comment SunOS + @deftypefun int on_exit (void (*@var{function})(int @var{status}, void *@var{arg}), void *@var{arg}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}} ++@c on_exit @ascuheap @asulock @aculock @acsmem ++@c new_exitfn dup @ascuheap @asulock @aculock @acsmem ++@c atomic_write_barrier dup ok + This function is a somewhat more powerful variant of @code{atexit}. It + accepts two arguments, a function @var{function} and an arbitrary + pointer @var{arg}. At normal program termination, the @var{function} is +@@ -940,6 +1006,10 @@ + @comment stdlib.h + @comment ISO + @deftypefun void abort (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} ++@c The implementation takes a recursive lock and attempts to support ++@c calls from signal handlers, but if we're in the middle of flushing or ++@c using streams, we may encounter them in inconsistent states. + The @code{abort} function causes abnormal program termination. This + does not execute cleanup functions registered with @code{atexit} or + @code{on_exit}. +@@ -967,6 +1037,9 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun void _exit (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall (exit_group or exit); calls __task_terminate on hurd, ++@c and abort in the generic posix implementation. + The @code{_exit} function is the primitive for causing a process to + terminate with status @var{status}. Calling this function does not + execute cleanup functions registered with @code{atexit} or +@@ -976,6 +1049,8 @@ + @comment stdlib.h + @comment ISO + @deftypefun void _Exit (int @var{status}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Alias for _exit. + The @code{_Exit} function is the @w{ISO C} equivalent to @code{_exit}. + The @w{ISO C} committee members were not sure whether the definitions of + @code{_exit} and @code{_Exit} were compatible so they have not used the +diff -urN glibc-2.17-c758a686/manual/stdio.texi glibc-2.17-c758a686/manual/stdio.texi +--- glibc-2.17-c758a686/manual/stdio.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/stdio.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -148,6 +148,8 @@ + @comment stdio.h + @comment ISO + @deftypefun {FILE *} fopen (const char *@var{filename}, const char *@var{opentype}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}} ++@c fopen may leak the list lock if cancelled within _IO_link_in. + The @code{fopen} function opens a stream for I/O to the file + @var{filename}, and returns a pointer to the stream. + +@@ -265,9 +267,10 @@ + @comment stdio.h + @comment Unix98 + @deftypefun {FILE *} fopen64 (const char *@var{filename}, const char *@var{opentype}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}} + This function is similar to @code{fopen} but the stream it returns a + pointer for is opened using @code{open64}. Therefore this stream can be +-used even on files larger then @math{2^31} bytes on 32 bit machines. ++used even on files larger than @math{2^31} bytes on 32 bit machines. + + Please note that the return type is still @code{FILE *}. There is no + special @code{FILE} type for the LFS interface. +@@ -294,6 +297,16 @@ + @comment stdio.h + @comment ISO + @deftypefun {FILE *} freopen (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsfd{}}} ++@c Like most I/O operations, this one is guarded by a recursive lock, ++@c released even upon cancellation, but cancellation may leak file ++@c descriptors and leave the stream in an inconsistent state (e.g., ++@c still bound to the closed descriptor). Also, if the stream is ++@c part-way through a significant update (say running freopen) when a ++@c signal handler calls freopen again on the same stream, the result is ++@c likely to be an inconsistent stream, and the possibility of closing ++@c twice file descriptor number that the stream used to use, the second ++@c time when it might have already been reused by another thread. + This function is like a combination of @code{fclose} and @code{fopen}. + It first closes the stream referred to by @var{stream}, ignoring any + errors that are detected in the process. (Because errors are ignored, +@@ -320,6 +333,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun {FILE *} freopen64 (const char *@var{filename}, const char *@var{opentype}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @acsfd{}}} + This function is similar to @code{freopen}. The only difference is that + on 32 bit machine the stream returned is able to read beyond the + @math{2^31} bytes limits imposed by the normal interface. It should be +@@ -341,6 +355,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun int __freadable (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{__freadable} function determines whether the stream + @var{stream} was opened to allow reading. In this case the return value + is nonzero. For write-only streams the function returns zero. +@@ -351,6 +366,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun int __fwritable (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{__fwritable} function determines whether the stream + @var{stream} was opened to allow writing. In this case the return value + is nonzero. For read-only streams the function returns zero. +@@ -364,6 +380,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun int __freading (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{__freading} function determines whether the stream + @var{stream} was last read from or whether it is opened read-only. In + this case the return value is nonzero, otherwise it is zero. +@@ -377,6 +394,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun int __fwriting (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{__fwriting} function determines whether the stream + @var{stream} was last written to or whether it is opened write-only. In + this case the return value is nonzero, otherwise it is zero. +@@ -396,6 +414,21 @@ + @comment stdio.h + @comment ISO + @deftypefun int fclose (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c After fclose, it is undefined behavior to use the stream it points ++@c to. Therefore, one must only call fclose when the stream is ++@c otherwise unused. Concurrent uses started before will complete ++@c successfully because of the lock, which makes it MT-Safe. Calling it ++@c from a signal handler is perfectly safe if the stream is known to be ++@c no longer used, which is a precondition for fclose to be safe in the ++@c first place; since this is no further requirement, fclose is safe for ++@c use in async signals too. After calling fclose, you can no longer ++@c use the stream, not even to fclose it again, so its memory and file ++@c descriptor may leak if fclose is canceled before @c releasing them. ++@c That the stream must be unused and it becomes unused after the call ++@c is what would enable fclose to be AS- and AC-Safe while freopen ++@c isn't. However, because of the possibility of leaving __gconv_lock ++@c taken upon cancellation, AC-Safety is lost. + This function causes @var{stream} to be closed and the connection to + the corresponding file to be broken. Any buffered output is written + and any buffered input is discarded. The @code{fclose} function returns +@@ -418,6 +451,12 @@ + @comment stdio.h + @comment GNU + @deftypefun int fcloseall (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:streams}}@asunsafe{}@acsafe{}} ++@c Like fclose, using any previously-opened streams after fcloseall is ++@c undefined. However, the implementation of fcloseall isn't equivalent ++@c to calling fclose for all streams: it just flushes and unbuffers all ++@c streams, without any locking. It's the flushing without locking that ++@c makes it unsafe. + This function causes all open streams of the process to be closed and + the connection to corresponding files to be broken. All buffered data + is written and any buffered input is discarded. The @code{fcloseall} +@@ -474,6 +513,9 @@ + @comment stdio.h + @comment POSIX + @deftypefun void flockfile (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} ++@c There's no way to tell whether the lock was acquired before or after ++@c cancellation so as to unlock only when appropriate. + The @code{flockfile} function acquires the internal locking object + associated with the stream @var{stream}. This ensures that no other + thread can explicitly through @code{flockfile}/@code{ftrylockfile} or +@@ -485,6 +527,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int ftrylockfile (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} + The @code{ftrylockfile} function tries to acquire the internal locking + object associated with the stream @var{stream} just like + @code{flockfile}. But unlike @code{flockfile} this function does not +@@ -496,8 +539,9 @@ + @comment stdio.h + @comment POSIX + @deftypefun void funlockfile (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} + The @code{funlockfile} function releases the internal locking object of +-the stream @var{stream}. The stream must have been locked before by a ++the stream @var{stream}. The stream must have been locked before by a + call to @code{flockfile} or a successful call of @code{ftrylockfile}. + The implicit locking performed by the stream operations do not count. + The @code{funlockfile} function does not return an error status and the +@@ -621,6 +665,15 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun int __fsetlocking (FILE *@var{stream}, int @var{type}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asulock{}}@acsafe{}} ++@c Changing the implicit-locking status of a stream while it's in use by ++@c another thread may cause a lock to be implicitly acquired and not ++@c released, or vice-versa. This function should probably hold the lock ++@c while changing this setting, to make sure we don't change it while ++@c there are any concurrent uses. Meanwhile, callers should acquire the ++@c lock themselves to be safe, and even concurrent uses with external ++@c locking will be fine, as long as functions that require external ++@c locking are not called without holding locks. + + The @code{__fsetlocking} function can be used to select whether the + stream operations will implicitly acquire the locking object of the +@@ -725,6 +778,10 @@ + @comment wchar.h + @comment ISO + @deftypefun int fwide (FILE *@var{stream}, int @var{mode}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{}}} ++@c Querying is always safe, but changing the stream when it's in use ++@c upthread may be problematic. Like most lock-acquiring functions, ++@c this one may leak the lock if canceled. + + The @code{fwide} function can be used to set and query the state of the + orientation of the stream @var{stream}. If the @var{mode} parameter has +@@ -811,6 +868,16 @@ + @comment stdio.h + @comment ISO + @deftypefun int fputc (int @var{c}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} ++@c If the stream is in use when interrupted by a signal, the recursive ++@c lock won't help ensure the stream is consistent; indeed, if fputc ++@c gets a signal precisely before the post-incremented _IO_write_ptr ++@c value is stored, we may overwrite the interrupted write. Conversely, ++@c depending on compiler optimizations, the incremented _IO_write_ptr ++@c may be stored before the character is stored in the buffer, ++@c corrupting the stream if async cancel hits between the two stores. ++@c There may be other reasons for AS- and AC-unsafety in the overflow ++@c cases. + The @code{fputc} function converts the character @var{c} to type + @code{unsigned char}, and writes it to the stream @var{stream}. + @code{EOF} is returned if a write error occurs; otherwise the +@@ -820,6 +887,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t fputwc (wchar_t @var{wc}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + The @code{fputwc} function writes the wide character @var{wc} to the + stream @var{stream}. @code{WEOF} is returned if a write error occurs; + otherwise the character @var{wc} is returned. +@@ -828,13 +896,18 @@ + @comment stdio.h + @comment POSIX + @deftypefun int fputc_unlocked (int @var{c}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@c The unlocked functions can't possibly satisfy the MT-Safety ++@c requirements on their own, because they require external locking for ++@c safety. + The @code{fputc_unlocked} function is equivalent to the @code{fputc} + function except that it does not implicitly lock the stream. + @end deftypefun + + @comment wchar.h + @comment POSIX +-@deftypefun wint_t fputwc_unlocked (wint_t @var{wc}, FILE *@var{stream}) ++@deftypefun wint_t fputwc_unlocked (wchar_t @var{wc}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fputwc_unlocked} function is equivalent to the @code{fputwc} + function except that it does not implicitly lock the stream. + +@@ -844,6 +917,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int putc (int @var{c}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + This is just like @code{fputc}, except that most systems implement it as + a macro, making it faster. One consequence is that it may evaluate the + @var{stream} argument more than once, which is an exception to the +@@ -854,6 +928,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t putwc (wchar_t @var{wc}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + This is just like @code{fputwc}, except that it can be implement as + a macro, making it faster. One consequence is that it may evaluate the + @var{stream} argument more than once, which is an exception to the +@@ -864,6 +939,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int putc_unlocked (int @var{c}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{putc_unlocked} function is equivalent to the @code{putc} + function except that it does not implicitly lock the stream. + @end deftypefun +@@ -871,6 +947,7 @@ + @comment wchar.h + @comment GNU + @deftypefun wint_t putwc_unlocked (wchar_t @var{wc}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{putwc_unlocked} function is equivalent to the @code{putwc} + function except that it does not implicitly lock the stream. + +@@ -880,6 +957,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int putchar (int @var{c}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + The @code{putchar} function is equivalent to @code{putc} with + @code{stdout} as the value of the @var{stream} argument. + @end deftypefun +@@ -887,6 +965,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t putwchar (wchar_t @var{wc}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + The @code{putwchar} function is equivalent to @code{putwc} with + @code{stdout} as the value of the @var{stream} argument. + @end deftypefun +@@ -894,6 +973,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int putchar_unlocked (int @var{c}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:stdout}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{putchar_unlocked} function is equivalent to the @code{putchar} + function except that it does not implicitly lock the stream. + @end deftypefun +@@ -901,6 +981,7 @@ + @comment wchar.h + @comment GNU + @deftypefun wint_t putwchar_unlocked (wchar_t @var{wc}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:stdout}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{putwchar_unlocked} function is equivalent to the @code{putwchar} + function except that it does not implicitly lock the stream. + +@@ -910,6 +991,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fputs (const char *@var{s}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + The function @code{fputs} writes the string @var{s} to the stream + @var{stream}. The terminating null character is not written. + This function does @emph{not} add a newline character, either. +@@ -933,6 +1015,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int fputws (const wchar_t *@var{ws}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} + The function @code{fputws} writes the wide character string @var{ws} to + the stream @var{stream}. The terminating null character is not written. + This function does @emph{not} add a newline character, either. It +@@ -945,6 +1028,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int fputs_unlocked (const char *@var{s}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fputs_unlocked} function is equivalent to the @code{fputs} + function except that it does not implicitly lock the stream. + +@@ -954,6 +1038,7 @@ + @comment wchar.h + @comment GNU + @deftypefun int fputws_unlocked (const wchar_t *@var{ws}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fputws_unlocked} function is equivalent to the @code{fputws} + function except that it does not implicitly lock the stream. + +@@ -963,6 +1048,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int puts (const char *@var{s}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{puts} function writes the string @var{s} to the stream + @code{stdout} followed by a newline. The terminating null character of + the string is not written. (Note that @code{fputs} does @emph{not} +@@ -982,6 +1068,7 @@ + @comment stdio.h + @comment SVID + @deftypefun int putw (int @var{w}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function writes the word @var{w} (that is, an @code{int}) to + @var{stream}. It is provided for compatibility with SVID, but we + recommend you use @code{fwrite} instead (@pxref{Block Input/Output}). +@@ -1014,6 +1101,11 @@ + @comment stdio.h + @comment ISO + @deftypefun int fgetc (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} ++@c Same caveats as fputc, but instead of losing a write in case of async ++@c signals, we may read the same character more than once, and the ++@c stream may be left in odd states due to cancellation in the underflow ++@c cases. + This function reads the next character as an @code{unsigned char} from + the stream @var{stream} and returns its value, converted to an + @code{int}. If an end-of-file condition or read error occurs, +@@ -1023,6 +1115,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t fgetwc (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function reads the next wide character from the stream @var{stream} + and returns its value. If an end-of-file condition or read error + occurs, @code{WEOF} is returned instead. +@@ -1031,6 +1124,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int fgetc_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fgetc_unlocked} function is equivalent to the @code{fgetc} + function except that it does not implicitly lock the stream. + @end deftypefun +@@ -1038,6 +1132,7 @@ + @comment wchar.h + @comment GNU + @deftypefun wint_t fgetwc_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fgetwc_unlocked} function is equivalent to the @code{fgetwc} + function except that it does not implicitly lock the stream. + +@@ -1047,6 +1142,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int getc (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This is just like @code{fgetc}, except that it is permissible (and + typical) for it to be implemented as a macro that evaluates the + @var{stream} argument more than once. @code{getc} is often highly +@@ -1057,6 +1153,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t getwc (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This is just like @code{fgetwc}, except that it is permissible for it to + be implemented as a macro that evaluates the @var{stream} argument more + than once. @code{getwc} can be highly optimized, so it is usually the +@@ -1066,6 +1163,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int getc_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{getc_unlocked} function is equivalent to the @code{getc} + function except that it does not implicitly lock the stream. + @end deftypefun +@@ -1073,6 +1171,7 @@ + @comment wchar.h + @comment GNU + @deftypefun wint_t getwc_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{getwc_unlocked} function is equivalent to the @code{getwc} + function except that it does not implicitly lock the stream. + +@@ -1082,6 +1181,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int getchar (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{getchar} function is equivalent to @code{getc} with @code{stdin} + as the value of the @var{stream} argument. + @end deftypefun +@@ -1089,6 +1189,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t getwchar (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{getwchar} function is equivalent to @code{getwc} with @code{stdin} + as the value of the @var{stream} argument. + @end deftypefun +@@ -1096,6 +1197,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int getchar_unlocked (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:stdin}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{getchar_unlocked} function is equivalent to the @code{getchar} + function except that it does not implicitly lock the stream. + @end deftypefun +@@ -1103,6 +1205,7 @@ + @comment wchar.h + @comment GNU + @deftypefun wint_t getwchar_unlocked (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:stdin}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{getwchar_unlocked} function is equivalent to the @code{getwchar} + function except that it does not implicitly lock the stream. + +@@ -1145,6 +1248,7 @@ + @comment stdio.h + @comment SVID + @deftypefun int getw (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function reads a word (that is, an @code{int}) from @var{stream}. + It's provided for compatibility with SVID. We recommend you use + @code{fread} instead (@pxref{Block Input/Output}). Unlike @code{getc}, +@@ -1173,6 +1277,12 @@ + @comment stdio.h + @comment GNU + @deftypefun ssize_t getline (char **@var{lineptr}, size_t *@var{n}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}} ++@c Besides the usual possibility of getting an inconsistent stream in a ++@c signal handler or leaving it inconsistent in case of cancellation, ++@c the possibility of leaving a dangling pointer upon cancellation ++@c between reallocing the buffer at *lineptr and updating the pointer ++@c brings about another case of @acucorrupt. + This function reads an entire line from @var{stream}, storing the text + (including the newline and a terminating null character) in a buffer + and storing the buffer address in @code{*@var{lineptr}}. +@@ -1188,7 +1298,8 @@ + + If you set @code{*@var{lineptr}} to a null pointer, and @code{*@var{n}} + to zero, before the call, then @code{getline} allocates the initial +-buffer for you by calling @code{malloc}. ++buffer for you by calling @code{malloc}. This buffer remains allocated ++even if @code{getline} encounters errors and is unable to read any bytes. + + In either case, when @code{getline} returns, @code{*@var{lineptr}} is + a @code{char *} which points to the text of the line. +@@ -1208,6 +1319,8 @@ + @comment stdio.h + @comment GNU + @deftypefun ssize_t getdelim (char **@var{lineptr}, size_t *@var{n}, int @var{delimiter}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{}}} ++@c See the getline @acucorrupt note. + This function is like @code{getline} except that the character which + tells it to stop reading is not necessarily newline. The argument + @var{delimiter} specifies the delimiter character; @code{getdelim} keeps +@@ -1232,6 +1345,7 @@ + @comment stdio.h + @comment ISO + @deftypefun {char *} fgets (char *@var{s}, int @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{fgets} function reads characters from the stream @var{stream} + up to and including a newline character and stores them in the string + @var{s}, adding a null character to mark the end of the string. You +@@ -1255,6 +1369,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} fgetws (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{fgetws} function reads wide characters from the stream + @var{stream} up to and including a newline character and stores them in + the string @var{ws}, adding a null wide character to mark the end of the +@@ -1280,6 +1395,7 @@ + @comment stdio.h + @comment GNU + @deftypefun {char *} fgets_unlocked (char *@var{s}, int @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fgets_unlocked} function is equivalent to the @code{fgets} + function except that it does not implicitly lock the stream. + +@@ -1289,6 +1405,7 @@ + @comment wchar.h + @comment GNU + @deftypefun {wchar_t *} fgetws_unlocked (wchar_t *@var{ws}, int @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fgetws_unlocked} function is equivalent to the @code{fgetws} + function except that it does not implicitly lock the stream. + +@@ -1298,6 +1415,7 @@ + @comment stdio.h + @comment ISO + @deftypefn {Deprecated function} {char *} gets (char *@var{s}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The function @code{gets} reads characters from the stream @code{stdin} + up to the next newline character, and stores them in the string @var{s}. + The newline character is discarded (note that this differs from the +@@ -1388,6 +1506,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int ungetc (int @var{c}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{ungetc} function pushes back the character @var{c} onto the + input stream @var{stream}. So the next input from @var{stream} will + read @var{c} before anything else. +@@ -1425,6 +1544,7 @@ + @comment wchar.h + @comment ISO + @deftypefun wint_t ungetwc (wint_t @var{wc}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{ungetwc} function behaves just like @code{ungetc} just that it + pushes back a wide character. + @end deftypefun +@@ -1483,6 +1603,7 @@ + @comment stdio.h + @comment ISO + @deftypefun size_t fread (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function reads up to @var{count} objects of size @var{size} into + the array @var{data}, from the stream @var{stream}. It returns the + number of objects actually read, which might be less than @var{count} if +@@ -1498,6 +1619,7 @@ + @comment stdio.h + @comment GNU + @deftypefun size_t fread_unlocked (void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fread_unlocked} function is equivalent to the @code{fread} + function except that it does not implicitly lock the stream. + +@@ -1507,6 +1629,7 @@ + @comment stdio.h + @comment ISO + @deftypefun size_t fwrite (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function writes up to @var{count} objects of size @var{size} from + the array @var{data}, to the stream @var{stream}. The return value is + normally @var{count}, if the call succeeds. Any other value indicates +@@ -1516,6 +1639,7 @@ + @comment stdio.h + @comment GNU + @deftypefun size_t fwrite_unlocked (const void *@var{data}, size_t @var{size}, size_t @var{count}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fwrite_unlocked} function is equivalent to the @code{fwrite} + function except that it does not implicitly lock the stream. + +@@ -1670,7 +1794,7 @@ + + @defvr Macro NL_ARGMAX + The value of @code{NL_ARGMAX} is the maximum value allowed for the +-specification of an positional parameter in a @code{printf} call. The ++specification of a positional parameter in a @code{printf} call. The + actual value in effect at runtime can be retrieved by using + @code{sysconf} using the @code{_SC_NL_ARGMAX} parameter @pxref{Sysconf + Definition}. +@@ -2257,6 +2381,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int printf (const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + The @code{printf} function prints the optional arguments under the + control of the template string @var{template} to the stream + @code{stdout}. It returns the number of characters printed, or a +@@ -2266,6 +2391,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int wprintf (const wchar_t *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + The @code{wprintf} function prints the optional arguments under the + control of the wide template string @var{template} to the stream + @code{stdout}. It returns the number of wide characters printed, or a +@@ -2275,6 +2401,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fprintf (FILE *@var{stream}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is just like @code{printf}, except that the output is + written to the stream @var{stream} instead of @code{stdout}. + @end deftypefun +@@ -2282,6 +2409,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int fwprintf (FILE *@var{stream}, const wchar_t *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is just like @code{wprintf}, except that the output is + written to the stream @var{stream} instead of @code{stdout}. + @end deftypefun +@@ -2289,6 +2417,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int sprintf (char *@var{s}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is like @code{printf}, except that the output is stored in the character + array @var{s} instead of written to a stream. A null character is written + to mark the end of the string. +@@ -2313,6 +2442,7 @@ + @comment wchar.h + @comment GNU + @deftypefun int swprintf (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is like @code{wprintf}, except that the output is stored in the + wide character array @var{ws} instead of written to a stream. A null + wide character is written to mark the end of the string. The @var{size} +@@ -2330,13 +2460,14 @@ + parameters. @code{swprintf} in fact corresponds to the @code{snprintf} + function. Since the @code{sprintf} function can be dangerous and should + be avoided the @w{ISO C} committee refused to make the same mistake +-again and decided to not define an function exactly corresponding to ++again and decided to not define a function exactly corresponding to + @code{sprintf}. + @end deftypefun + + @comment stdio.h + @comment GNU + @deftypefun int snprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{snprintf} function is similar to @code{sprintf}, except that + the @var{size} argument specifies the maximum number of characters to + produce. The trailing null character is counted towards this limit, so +@@ -2407,6 +2538,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int asprintf (char **@var{ptr}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function is similar to @code{sprintf}, except that it dynamically + allocates a string (as with @code{malloc}; @pxref{Unconstrained + Allocation}) to hold the output, instead of putting the output in a +@@ -2416,7 +2548,7 @@ + location. + + The return value is the number of characters allocated for the buffer, or +-less than zero if an error occurred. Usually this means that the buffer ++less than zero if an error occurred. Usually this means that the buffer + could not be allocated. + + Here is how to use @code{asprintf} to get the same result as the +@@ -2439,6 +2571,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int obstack_printf (struct obstack *@var{obstack}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} + This function is similar to @code{asprintf}, except that it uses the + obstack @var{obstack} to allocate the space. @xref{Obstacks}. + +@@ -2509,6 +2642,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int vprintf (const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is similar to @code{printf} except that, instead of taking + a variable number of arguments directly, it takes an argument list + pointer @var{ap}. +@@ -2517,6 +2651,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int vwprintf (const wchar_t *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is similar to @code{wprintf} except that, instead of taking + a variable number of arguments directly, it takes an argument list + pointer @var{ap}. +@@ -2525,6 +2660,48 @@ + @comment stdio.h + @comment ISO + @deftypefun int vfprintf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} ++@c Although vfprintf sets up a cleanup region to release the lock on the ++@c output stream, it doesn't use it to release args_value or string in ++@c case of cancellation. This doesn't make it unsafe, but cancelling it ++@c may leak memory. The unguarded use of __printf_function_table is ++@c also of concern for all callers. ++@c _itoa ok ++@c _udiv_qrnnd_preinv ok ++@c group_number ok ++@c _i18n_number_rewrite ++@c __wctrans ok ++@c __towctrans @mtslocale ++@c __wcrtomb ok? dup below ++@c outdigit_value ok ++@c outdigitwc_value ok ++@c outchar ok ++@c outstring ok ++@c PAD ok ++@c __printf_fp @mtslocale @ascuheap @acsmem ++@c __printf_fphex @mtslocale ++@c __readonly_area ++@c [GNU/Linux] fopen, strtoul, free ++@c __strerror_r ok if no translation, check otherwise ++@c __btowc ? gconv-modules ++@c __wcrtomb ok (not using internal state) gconv-modules ++@c ARGCHECK ++@c UNBUFFERED_P (tested before taking the stream lock) ++@c buffered_vfprintf ok ++@c __find_spec(wc|mb) ++@c read_int ++@c __libc_use_alloca ++@c process_arg ++@c process_string_arg ++@c extend_alloca ++@c __parse_one_spec(wc|mb) ++@c *__printf_arginfo_table unguarded ++@c __printf_va_arg_table-> unguarded ++@c *__printf_function_table unguarded ++@c done_add ++@c printf_unknown ++@c outchar ++@c _itoa_word + This is the equivalent of @code{fprintf} with the variable argument list + specified directly as for @code{vprintf}. + @end deftypefun +@@ -2532,6 +2709,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int vfwprintf (FILE *@var{stream}, const wchar_t *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This is the equivalent of @code{fwprintf} with the variable argument list + specified directly as for @code{vwprintf}. + @end deftypefun +@@ -2539,6 +2717,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int vsprintf (char *@var{s}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is the equivalent of @code{sprintf} with the variable argument list + specified directly as for @code{vprintf}. + @end deftypefun +@@ -2546,6 +2725,7 @@ + @comment wchar.h + @comment GNU + @deftypefun int vswprintf (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is the equivalent of @code{swprintf} with the variable argument list + specified directly as for @code{vwprintf}. + @end deftypefun +@@ -2553,6 +2733,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int vsnprintf (char *@var{s}, size_t @var{size}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is the equivalent of @code{snprintf} with the variable argument list + specified directly as for @code{vprintf}. + @end deftypefun +@@ -2560,6 +2741,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int vasprintf (char **@var{ptr}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{vasprintf} function is the equivalent of @code{asprintf} with the + variable argument list specified directly as for @code{vprintf}. + @end deftypefun +@@ -2567,6 +2749,10 @@ + @comment stdio.h + @comment GNU + @deftypefun int obstack_vprintf (struct obstack *@var{obstack}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtsrace{:obstack} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c The obstack is not guarded by mutexes, it might be at an inconsistent ++@c state within a signal handler, and it could be left at an ++@c inconsistent state in case of cancellation. + The @code{obstack_vprintf} function is the equivalent of + @code{obstack_printf} with the variable argument list specified directly + as for @code{vprintf}.@refill +@@ -2639,6 +2825,7 @@ + @comment printf.h + @comment GNU + @deftypefun size_t parse_printf_format (const char *@var{template}, size_t @var{n}, int *@var{argtypes}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function returns information about the number and types of + arguments expected by the @code{printf} template string @var{template}. + The information is stored in the array @var{argtypes}; each element of +@@ -2879,6 +3066,12 @@ + @comment printf.h + @comment GNU + @deftypefun int register_printf_function (int @var{spec}, printf_function @var{handler-function}, printf_arginfo_function @var{arginfo-function}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:printfext}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}} ++@c This function is guarded by the global non-recursive libc lock, but ++@c users of the variables it sets aren't, and those should be MT-Safe, ++@c so we're ruling out the use of this extension with threads. Calling ++@c it from a signal handler may self-deadlock, and cancellation may ++@c leave the lock held, besides leaking allocated memory. + This function defines the conversion specifier character @var{spec}. + Thus, if @var{spec} is @code{'Y'}, it defines the conversion @samp{%Y}. + You can redefine the built-in conversions like @samp{%s}, but flag +@@ -3125,6 +3318,12 @@ + @comment printf.h + @comment GNU + @deftypefun int printf_size (FILE *@var{fp}, const struct printf_info *@var{info}, const void *const *@var{args}) ++@safety{@prelim{}@mtsafe{@mtsrace{:fp} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @acucorrupt{}}} ++@c This is meant to be called by vfprintf, that should hold the lock on ++@c the stream, but if this function is called directly, output will be ++@c racy, besides the uses of the global locale object while other ++@c threads may be changing it and the possbility of leaving the stream ++@c object in an inconsistent state in case of cancellation. + Print a given floating point number as for the format @code{%f} except + that there is a postfix character indicating the divisor for the + number to make this less than 1000. There are two possible divisors: +@@ -3183,6 +3382,7 @@ + @comment printf.h + @comment GNU + @deftypefun int printf_size_info (const struct printf_info *@var{info}, size_t @var{n}, int *@var{argtypes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function will return in @var{argtypes} the information about the + used parameters in the way the @code{vfprintf} implementation expects + it. The format always takes one argument. +@@ -3672,7 +3872,7 @@ + To read in characters that belong to an arbitrary set of your choice, + use the @samp{%[} conversion. You specify the set between the @samp{[} + character and a following @samp{]} character, using the same syntax used +-in regular expressions. As special cases: ++in regular expressions for explicit sets of characters. As special cases: + + @itemize @bullet + @item +@@ -3692,6 +3892,10 @@ + The @samp{%[} conversion does not skip over initial whitespace + characters. + ++Note that the @dfn{character class} syntax available in character sets ++that appear inside regular expressions (such as @samp{[:alpha:]}) is ++@emph{not} available in the @samp{%[} conversion. ++ + Here are some examples of @samp{%[} conversions and what they mean: + + @table @samp +@@ -3799,6 +4003,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int scanf (const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + The @code{scanf} function reads formatted input from the stream + @code{stdin} under the control of the template string @var{template}. + The optional arguments are pointers to the places which receive the +@@ -3813,6 +4018,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int wscanf (const wchar_t *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + The @code{wscanf} function reads formatted input from the stream + @code{stdin} under the control of the template string @var{template}. + The optional arguments are pointers to the places which receive the +@@ -3827,6 +4033,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fscanf (FILE *@var{stream}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is just like @code{scanf}, except that the input is read + from the stream @var{stream} instead of @code{stdin}. + @end deftypefun +@@ -3834,6 +4041,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int fwscanf (FILE *@var{stream}, const wchar_t *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is just like @code{wscanf}, except that the input is read + from the stream @var{stream} instead of @code{stdin}. + @end deftypefun +@@ -3841,6 +4049,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int sscanf (const char *@var{s}, const char *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is like @code{scanf}, except that the characters are taken from the + null-terminated string @var{s} instead of from a stream. Reaching the + end of the string is treated as an end-of-file condition. +@@ -3853,7 +4062,8 @@ + + @comment wchar.h + @comment ISO +-@deftypefun int swscanf (const wchar_t *@var{ws}, const char *@var{template}, @dots{}) ++@deftypefun int swscanf (const wchar_t *@var{ws}, const wchar_t *@var{template}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is like @code{wscanf}, except that the characters are taken from the + null-terminated string @var{ws} instead of from a stream. Reaching the + end of the string is treated as an end-of-file condition. +@@ -3880,6 +4090,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int vscanf (const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is similar to @code{scanf}, but instead of taking + a variable number of arguments directly, it takes an argument list + pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}). +@@ -3888,6 +4099,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int vwscanf (const wchar_t *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This function is similar to @code{wscanf}, but instead of taking + a variable number of arguments directly, it takes an argument list + pointer @var{ap} of type @code{va_list} (@pxref{Variadic Functions}). +@@ -3896,6 +4108,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int vfscanf (FILE *@var{stream}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This is the equivalent of @code{fscanf} with the variable argument list + specified directly as for @code{vscanf}. + @end deftypefun +@@ -3903,6 +4116,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int vfwscanf (FILE *@var{stream}, const wchar_t *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acsmem{} @aculock{} @acucorrupt{}}} + This is the equivalent of @code{fwscanf} with the variable argument list + specified directly as for @code{vwscanf}. + @end deftypefun +@@ -3910,6 +4124,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int vsscanf (const char *@var{s}, const char *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is the equivalent of @code{sscanf} with the variable argument list + specified directly as for @code{vscanf}. + @end deftypefun +@@ -3917,6 +4132,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int vswscanf (const wchar_t *@var{s}, const wchar_t *@var{template}, va_list @var{ap}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This is the equivalent of @code{swscanf} with the variable argument list + specified directly as for @code{vwscanf}. + @end deftypefun +@@ -3966,6 +4182,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int feof (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} + The @code{feof} function returns nonzero if and only if the end-of-file + indicator for the stream @var{stream} is set. + +@@ -3975,6 +4192,9 @@ + @comment stdio.h + @comment GNU + @deftypefun int feof_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c There isn't much of a thread unsafety risk in reading a flag word and ++@c testing a bit in it. + The @code{feof_unlocked} function is equivalent to the @code{feof} + function except that it does not implicitly lock the stream. + +@@ -3986,6 +4206,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int ferror (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} + The @code{ferror} function returns nonzero if and only if the error + indicator for the stream @var{stream} is set, indicating that an error + has occurred on a previous operation on the stream. +@@ -3996,6 +4217,7 @@ + @comment stdio.h + @comment GNU + @deftypefun int ferror_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{ferror_unlocked} function is equivalent to the @code{ferror} + function except that it does not implicitly lock the stream. + +@@ -4023,6 +4245,7 @@ + @comment stdio.h + @comment ISO + @deftypefun void clearerr (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@aculock{}}} + This function clears the end-of-file and error indicators for the + stream @var{stream}. + +@@ -4033,6 +4256,7 @@ + @comment stdio.h + @comment GNU + @deftypefun void clearerr_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@assafe{}@acsafe{}} + The @code{clearerr_unlocked} function is equivalent to the @code{clearerr} + function except that it does not implicitly lock the stream. + +@@ -4146,6 +4370,7 @@ + @comment stdio.h + @comment ISO + @deftypefun {long int} ftell (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function returns the current file position of the stream + @var{stream}. + +@@ -4158,6 +4383,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun off_t ftello (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{ftello} function is similar to @code{ftell}, except that it + returns a value of type @code{off_t}. Systems which support this type + use it to describe all file positions, unlike the POSIX specification +@@ -4181,6 +4407,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun off64_t ftello64 (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function is similar to @code{ftello} with the only difference that + the return value is of type @code{off64_t}. This also requires that the + stream @var{stream} was opened using either @code{fopen64}, +@@ -4196,6 +4423,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{fseek} function is used to change the file position of the + stream @var{stream}. The value of @var{whence} must be one of the + constants @code{SEEK_SET}, @code{SEEK_CUR}, or @code{SEEK_END}, to +@@ -4215,6 +4443,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun int fseeko (FILE *@var{stream}, off_t @var{offset}, int @var{whence}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function is similar to @code{fseek} but it corrects a problem with + @code{fseek} in a system with POSIX types. Using a value of type + @code{long int} for the offset is not compatible with POSIX. +@@ -4238,6 +4467,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun int fseeko64 (FILE *@var{stream}, off64_t @var{offset}, int @var{whence}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function is similar to @code{fseeko} with the only difference that + the @var{offset} parameter is of type @code{off64_t}. This also + requires that the stream @var{stream} was opened using either +@@ -4286,6 +4516,7 @@ + @comment stdio.h + @comment ISO + @deftypefun void rewind (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{rewind} function positions the stream @var{stream} at the + beginning of the file. It is equivalent to calling @code{fseek} or + @code{fseeko} on the @var{stream} with an @var{offset} argument of +@@ -4407,6 +4638,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fgetpos (FILE *@var{stream}, fpos_t *@var{position}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function stores the value of the file position indicator for the + stream @var{stream} in the @code{fpos_t} object pointed to by + @var{position}. If successful, @code{fgetpos} returns zero; otherwise +@@ -4421,6 +4653,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun int fgetpos64 (FILE *@var{stream}, fpos64_t *@var{position}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function is similar to @code{fgetpos} but the file position is + returned in a variable of type @code{fpos64_t} to which @var{position} + points. +@@ -4433,6 +4666,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fsetpos (FILE *@var{stream}, const fpos_t *@var{position}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function sets the file position indicator for the stream @var{stream} + to the position @var{position}, which must have been set by a previous + call to @code{fgetpos} on the same stream. If successful, @code{fsetpos} +@@ -4449,6 +4683,7 @@ + @comment stdio.h + @comment Unix98 + @deftypefun int fsetpos64 (FILE *@var{stream}, const fpos64_t *@var{position}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function is similar to @code{fsetpos} but the file position used + for positioning is provided in a variable of type @code{fpos64_t} to + which @var{position} points. +@@ -4560,6 +4795,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int fflush (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function causes any buffered output on @var{stream} to be delivered + to the file. If @var{stream} is a null pointer, then + @code{fflush} causes buffered output on @emph{all} open output streams +@@ -4572,6 +4808,7 @@ + @comment stdio.h + @comment POSIX + @deftypefun int fflush_unlocked (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{fflush_unlocked} function is equivalent to the @code{fflush} + function except that it does not implicitly lock the stream. + @end deftypefun +@@ -4588,6 +4825,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun void _flushlbf (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + The @code{_flushlbf} function flushes all line buffered streams + currently opened. + +@@ -4609,6 +4847,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun void __fpurge (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} + The @code{__fpurge} function causes the buffer of the stream + @var{stream} to be emptied. If the stream is currently in read mode all + input in the buffer is lost. If the stream is in output mode the +@@ -4633,6 +4872,7 @@ + @comment stdio.h + @comment ISO + @deftypefun int setvbuf (FILE *@var{stream}, char *@var{buf}, int @var{mode}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function is used to specify that the stream @var{stream} should + have the buffering mode @var{mode}, which can be either @code{_IOFBF} + (for full buffering), @code{_IOLBF} (for line buffering), or +@@ -4710,6 +4950,7 @@ + @comment stdio.h + @comment ISO + @deftypefun void setbuf (FILE *@var{stream}, char *@var{buf}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + If @var{buf} is a null pointer, the effect of this function is + equivalent to calling @code{setvbuf} with a @var{mode} argument of + @code{_IONBF}. Otherwise, it is equivalent to calling @code{setvbuf} +@@ -4723,6 +4964,7 @@ + @comment stdio.h + @comment BSD + @deftypefun void setbuffer (FILE *@var{stream}, char *@var{buf}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + If @var{buf} is a null pointer, this function makes @var{stream} unbuffered. + Otherwise, it makes @var{stream} fully buffered using @var{buf} as the + buffer. The @var{size} argument specifies the length of @var{buf}. +@@ -4734,6 +4976,7 @@ + @comment stdio.h + @comment BSD + @deftypefun void setlinebuf (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} + This function makes @var{stream} be line buffered, and allocates the + buffer for you. + +@@ -4748,6 +4991,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun int __flbf (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{__flbf} function will return a nonzero value in case the + stream @var{stream} is line buffered. Otherwise the return value is + zero. +@@ -4761,6 +5005,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun size_t __fbufsize (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acsafe{}} + The @code{__fbufsize} function return the size of the buffer in the + stream @var{stream}. This value can be used to optimize the use of the + stream. +@@ -4771,6 +5016,7 @@ + @comment stdio_ext.h + @comment GNU + @deftypefun size_t __fpending (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtsrace{:stream}}@asunsafe{@asucorrupt{}}@acsafe{}} + The @code{__fpending} + function returns the number of bytes currently in the output buffer. + For wide-oriented stream the measuring unit is wide characters. This +@@ -4818,6 +5064,10 @@ + @comment stdio.h + @comment GNU + @deftypefun {FILE *} fmemopen (void *@var{buf}, size_t @var{size}, const char *@var{opentype}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}} ++@c Unlike open_memstream, fmemopen does (indirectly) call _IO_link_in, ++@c bringing with it additional potential for async trouble with ++@c list_all_lock. + This function opens a stream that allows the access specified by the + @var{opentype} argument, that reads from or writes to the buffer specified + by the argument @var{buf}. This array must be at least @var{size} bytes long. +@@ -4870,6 +5120,7 @@ + @comment stdio.h + @comment GNU + @deftypefun {FILE *} open_memstream (char **@var{ptr}, size_t *@var{sizeloc}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function opens a stream for writing to a buffer. The buffer is + allocated dynamically and grown as necessary, using @code{malloc}. + After you've closed the stream, this buffer is your responsibility to +@@ -4985,6 +5236,7 @@ + @comment stdio.h + @comment GNU + @deftypefun {FILE *} fopencookie (void *@var{cookie}, const char *@var{opentype}, cookie_io_functions_t @var{io-functions}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @aculock{}}} + This function actually creates the stream for communicating with the + @var{cookie} using the functions in the @var{io-functions} argument. + The @var{opentype} argument is interpreted as for @code{fopen}; +@@ -5053,26 +5305,26 @@ + + @comment stdio.h + @comment GNU +-@deftp {Data Type} cookie_read_function ++@deftp {Data Type} cookie_read_function_t + This is the data type that the read function for a custom stream should have. + If you declare the function as shown above, this is the type it will have. + @end deftp + + @comment stdio.h + @comment GNU +-@deftp {Data Type} cookie_write_function ++@deftp {Data Type} cookie_write_function_t + The data type of the write function for a custom stream. + @end deftp + + @comment stdio.h + @comment GNU +-@deftp {Data Type} cookie_seek_function ++@deftp {Data Type} cookie_seek_function_t + The data type of the seek function for a custom stream. + @end deftp + + @comment stdio.h + @comment GNU +-@deftp {Data Type} cookie_close_function ++@deftp {Data Type} cookie_close_function_t + The data type of the close function for a custom stream. + @end deftp + +@@ -5166,6 +5418,7 @@ + @comment fmtmsg.h + @comment XPG + @deftypefun int fmtmsg (long int @var{classification}, const char *@var{label}, int @var{severity}, const char *@var{text}, const char *@var{action}, const char *@var{tag}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acsafe{}} + Display a message described by its parameters on the device(s) specified + in the @var{classification} parameter. The @var{label} parameter + identifies the source of the message. The string should consist of two +@@ -5306,6 +5559,7 @@ + but this is toilsome. + + @deftypefun int addseverity (int @var{severity}, const char *@var{string}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}} + This function allows the introduction of new severity classes which can be + addressed by the @var{severity} parameter of the @code{fmtmsg} function. + The @var{severity} parameter of @code{addseverity} must match the value +diff -urN glibc-2.17-c758a686/manual/string.texi glibc-2.17-c758a686/manual/string.texi +--- glibc-2.17-c758a686/manual/string.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/string.texi 2014-09-12 16:10:06.045792717 -0400 +@@ -200,7 +200,7 @@ + @cindex parameter promotion + Some of the memory and string functions take single characters as + arguments. Since a value of type @code{char} is automatically promoted +-into an value of type @code{int} when used as a parameter, the functions ++into a value of type @code{int} when used as a parameter, the functions + are declared with @code{int} as the type of the parameter in question. + In case of the wide character function the situation is similarly: the + parameter type for a single wide character is @code{wint_t} and not +@@ -219,6 +219,7 @@ + @comment string.h + @comment ISO + @deftypefun size_t strlen (const char *@var{s}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strlen} function returns the length of the null-terminated + string @var{s} in bytes. (In other words, it returns the offset of the + terminating null character within the array.) +@@ -285,6 +286,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t wcslen (const wchar_t *@var{ws}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wcslen} function is the wide character equivalent to + @code{strlen}. The return value is the number of wide characters in the + wide character string pointed to by @var{ws} (this is also the offset of +@@ -300,6 +302,7 @@ + @comment string.h + @comment GNU + @deftypefun size_t strnlen (const char *@var{s}, size_t @var{maxlen}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strnlen} function returns the length of the string @var{s} in + bytes if this length is smaller than @var{maxlen} bytes. Otherwise it + returns @var{maxlen}. Therefore this function is equivalent to +@@ -322,6 +325,7 @@ + @comment wchar.h + @comment GNU + @deftypefun size_t wcsnlen (const wchar_t *@var{ws}, size_t @var{maxlen}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{wcsnlen} is the wide character equivalent to @code{strnlen}. The + @var{maxlen} parameter specifies the maximum number of wide characters. + +@@ -367,6 +371,7 @@ + @comment string.h + @comment ISO + @deftypefun {void *} memcpy (void *restrict @var{to}, const void *restrict @var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{memcpy} function copies @var{size} bytes from the object + beginning at @var{from} into the object beginning at @var{to}. The + behavior of this function is undefined if the two arrays @var{to} and +@@ -388,6 +393,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wmemcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wmemcpy} function copies @var{size} wide characters from the object + beginning at @var{wfrom} into the object beginning at @var{wto}. The + behavior of this function is undefined if the two arrays @var{wto} and +@@ -413,6 +419,7 @@ + @comment string.h + @comment GNU + @deftypefun {void *} mempcpy (void *restrict @var{to}, const void *restrict @var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{mempcpy} function is nearly identical to the @code{memcpy} + function. It copies @var{size} bytes from the object beginning at + @code{from} into the object pointed to by @var{to}. But instead of +@@ -440,6 +447,7 @@ + @comment wchar.h + @comment GNU + @deftypefun {wchar_t *} wmempcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wmempcpy} function is nearly identical to the @code{wmemcpy} + function. It copies @var{size} wide characters from the object + beginning at @code{wfrom} into the object pointed to by @var{wto}. But +@@ -468,6 +476,7 @@ + @comment string.h + @comment ISO + @deftypefun {void *} memmove (void *@var{to}, const void *@var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{memmove} copies the @var{size} bytes at @var{from} into the + @var{size} bytes at @var{to}, even if those two blocks of space + overlap. In the case of overlap, @code{memmove} is careful to copy the +@@ -479,7 +488,8 @@ + + @comment wchar.h + @comment ISO +-@deftypefun {wchar_t *} wmemmove (wchar *@var{wto}, const wchar_t *@var{wfrom}, size_t @var{size}) ++@deftypefun {wchar_t *} wmemmove (wchar_t *@var{wto}, const wchar_t *@var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{wmemmove} copies the @var{size} wide characters at @var{wfrom} + into the @var{size} wide characters at @var{wto}, even if those two + blocks of space overlap. In the case of overlap, @code{memmove} is +@@ -507,6 +517,7 @@ + @comment string.h + @comment SVID + @deftypefun {void *} memccpy (void *restrict @var{to}, const void *restrict @var{from}, int @var{c}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function copies no more than @var{size} bytes from @var{from} to + @var{to}, stopping if a byte matching @var{c} is found. The return + value is a pointer into @var{to} one byte past where @var{c} was copied, +@@ -517,6 +528,7 @@ + @comment string.h + @comment ISO + @deftypefun {void *} memset (void *@var{block}, int @var{c}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function copies the value of @var{c} (converted to an + @code{unsigned char}) into each of the first @var{size} bytes of the + object beginning at @var{block}. It returns the value of @var{block}. +@@ -525,6 +537,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wmemset (wchar_t *@var{block}, wchar_t @var{wc}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function copies the value of @var{wc} into each of the first + @var{size} wide characters of the object beginning at @var{block}. It + returns the value of @var{block}. +@@ -533,6 +546,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strcpy (char *restrict @var{to}, const char *restrict @var{from}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This copies characters from the string @var{from} (up to and including + the terminating null character) into the string @var{to}. Like + @code{memcpy}, this function has undefined results if the strings +@@ -542,6 +556,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcscpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This copies wide characters from the string @var{wfrom} (up to and + including the terminating null wide character) into the string + @var{wto}. Like @code{wmemcpy}, this function has undefined results if +@@ -551,6 +566,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strncpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{strcpy} but always copies exactly + @var{size} characters into @var{to}. + +@@ -576,6 +592,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcsncpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{wcscpy} but always copies exactly + @var{size} wide characters into @var{wto}. + +@@ -602,6 +619,7 @@ + @comment string.h + @comment SVID + @deftypefun {char *} strdup (const char *@var{s}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function copies the null-terminated string @var{s} into a newly + allocated string. The string is allocated using @code{malloc}; see + @ref{Unconstrained Allocation}. If @code{malloc} cannot allocate space +@@ -612,6 +630,7 @@ + @comment wchar.h + @comment GNU + @deftypefun {wchar_t *} wcsdup (const wchar_t *@var{ws}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function copies the null-terminated wide character string @var{ws} + into a newly allocated string. The string is allocated using + @code{malloc}; see @ref{Unconstrained Allocation}. If @code{malloc} +@@ -625,6 +644,7 @@ + @comment string.h + @comment GNU + @deftypefun {char *} strndup (const char *@var{s}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + This function is similar to @code{strdup} but always copies at most + @var{size} characters into the newly allocated string. + +@@ -642,6 +662,7 @@ + @comment string.h + @comment Unknown origin + @deftypefun {char *} stpcpy (char *restrict @var{to}, const char *restrict @var{from}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is like @code{strcpy}, except that it returns a pointer to + the end of the string @var{to} (that is, the address of the terminating + null character @code{to + strlen (from)}) rather than the beginning. +@@ -664,6 +685,7 @@ + @comment wchar.h + @comment GNU + @deftypefun {wchar_t *} wcpcpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is like @code{wcscpy}, except that it returns a pointer to + the end of the string @var{wto} (that is, the address of the terminating + null character @code{wto + strlen (wfrom)}) rather than the beginning. +@@ -679,10 +701,11 @@ + @comment string.h + @comment GNU + @deftypefun {char *} stpncpy (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{stpcpy} but copies always exactly + @var{size} characters into @var{to}. + +-If the length of @var{from} is more then @var{size}, then @code{stpncpy} ++If the length of @var{from} is more than @var{size}, then @code{stpncpy} + copies just the first @var{size} characters and returns a pointer to the + character directly following the one which was copied last. Note that in + this case there is no null terminator written into @var{to}. +@@ -704,10 +727,11 @@ + @comment wchar.h + @comment GNU + @deftypefun {wchar_t *} wcpncpy (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{wcpcpy} but copies always exactly + @var{wsize} characters into @var{wto}. + +-If the length of @var{wfrom} is more then @var{size}, then ++If the length of @var{wfrom} is more than @var{size}, then + @code{wcpncpy} copies just the first @var{size} wide characters and + returns a pointer to the wide character directly following the last + non-null wide character which was copied last. Note that in this case +@@ -731,6 +755,7 @@ + @comment string.h + @comment GNU + @deftypefn {Macro} {char *} strdupa (const char *@var{s}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This macro is similar to @code{strdup} but allocates the new string + using @code{alloca} instead of @code{malloc} (@pxref{Variable Size + Automatic}). This means of course the returned string has the same +@@ -757,6 +782,7 @@ + @comment string.h + @comment GNU + @deftypefn {Macro} {char *} strndupa (const char *@var{s}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is similar to @code{strndup} but like @code{strdupa} it + allocates the new string using @code{alloca} + @pxref{Variable Size Automatic}. The same advantages and limitations +@@ -772,6 +798,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strcat (char *restrict @var{to}, const char *restrict @var{from}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strcat} function is similar to @code{strcpy}, except that the + characters from @var{from} are concatenated or appended to the end of + @var{to}, instead of overwriting it. That is, the first character from +@@ -794,6 +821,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcscat (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wcscat} function is similar to @code{wcscpy}, except that the + characters from @var{wfrom} are concatenated or appended to the end of + @var{wto}, instead of overwriting it. That is, the first character from +@@ -942,6 +970,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strncat (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is like @code{strcat} except that not more than @var{size} + characters from @var{from} are appended to the end of @var{to}. A + single null character is also always appended to @var{to}, so the total +@@ -955,8 +984,8 @@ + char * + strncat (char *to, const char *from, size_t size) + @{ +- to[strlen (to) + size] = '\0'; +- strncpy (to + strlen (to), from, size); ++ memcpy (to + strlen (to), from, strnlen (from, size)); ++ to[strlen (to) + strnlen (from, size)] = '\0'; + return to; + @} + @end group +@@ -968,6 +997,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcsncat (wchar_t *restrict @var{wto}, const wchar_t *restrict @var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is like @code{wcscat} except that not more than @var{size} + characters from @var{from} are appended to the end of @var{to}. A + single null character is also always appended to @var{to}, so the total +@@ -982,8 +1012,8 @@ + wcsncat (wchar_t *restrict wto, const wchar_t *restrict wfrom, + size_t size) + @{ +- wto[wcslen (to) + size] = L'\0'; +- wcsncpy (wto + wcslen (wto), wfrom, size); ++ memcpy (wto + wcslen (wto), wfrom, wcsnlen (wfrom, size) * sizeof (wchar_t)); ++ wto[wcslen (to) + wcsnlen (wfrom, size)] = '\0'; + return wto; + @} + @end group +@@ -1012,6 +1042,7 @@ + @comment string.h + @comment BSD + @deftypefun void bcopy (const void *@var{from}, void *@var{to}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is a partially obsolete alternative for @code{memmove}, derived from + BSD. Note that it is not quite equivalent to @code{memmove}, because the + arguments are not in the same order and there is no return value. +@@ -1020,6 +1051,7 @@ + @comment string.h + @comment BSD + @deftypefun void bzero (void *@var{block}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is a partially obsolete alternative for @code{memset}, derived from + BSD. Note that it is not as general as @code{memset}, because the only + value it can store is zero. +@@ -1055,6 +1087,7 @@ + @comment string.h + @comment ISO + @deftypefun int memcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{memcmp} compares the @var{size} bytes of memory + beginning at @var{a1} against the @var{size} bytes of memory beginning + at @var{a2}. The value returned has the same sign as the difference +@@ -1065,9 +1098,10 @@ + @code{0}. + @end deftypefun + +-@comment wcjar.h ++@comment wchar.h + @comment ISO + @deftypefun int wmemcmp (const wchar_t *@var{a1}, const wchar_t *@var{a2}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{wmemcmp} compares the @var{size} wide characters + beginning at @var{a1} against the @var{size} wide characters beginning + at @var{a2}. The value returned is smaller than or larger than zero +@@ -1120,6 +1154,7 @@ + @comment string.h + @comment ISO + @deftypefun int strcmp (const char *@var{s1}, const char *@var{s2}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strcmp} function compares the string @var{s1} against + @var{s2}, returning a value that has the same sign as the difference + between the first differing pair of characters (interpreted as +@@ -1139,6 +1174,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int wcscmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + The @code{wcscmp} function compares the wide character string @var{ws1} + against @var{ws2}. The value returned is smaller than or larger than zero +@@ -1159,6 +1195,11 @@ + @comment string.h + @comment BSD + @deftypefun int strcasecmp (const char *@var{s1}, const char *@var{s2}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Although this calls tolower multiple times, it's a macro, and ++@c strcasecmp is optimized so that the locale pointer is read only once. ++@c There are some asm implementations too, for which the single-read ++@c from locale TLS pointers also applies. + This function is like @code{strcmp}, except that differences in case are + ignored. How uppercase and lowercase characters are related is + determined by the currently selected locale. In the standard @code{"C"} +@@ -1171,7 +1212,10 @@ + + @comment wchar.h + @comment GNU +-@deftypefun int wcscasecmp (const wchar_t *@var{ws1}, const wchar_T *@var{ws2}) ++@deftypefun int wcscasecmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Since towlower is not a macro, the locale object may be read multiple ++@c times. + This function is like @code{wcscmp}, except that differences in case are + ignored. How uppercase and lowercase characters are related is + determined by the currently selected locale. In the standard @code{"C"} +@@ -1185,6 +1229,7 @@ + @comment string.h + @comment ISO + @deftypefun int strncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is the similar to @code{strcmp}, except that no more than + @var{size} characters are compared. In other words, if the two + strings are the same in their first @var{size} characters, the +@@ -1194,6 +1239,7 @@ + @comment wchar.h + @comment ISO + @deftypefun int wcsncmp (const wchar_t *@var{ws1}, const wchar_t *@var{ws2}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function is the similar to @code{wcscmp}, except that no more than + @var{size} wide characters are compared. In other words, if the two + strings are the same in their first @var{size} wide characters, the +@@ -1203,6 +1249,7 @@ + @comment string.h + @comment BSD + @deftypefun int strncasecmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function is like @code{strncmp}, except that differences in case + are ignored. Like @code{strcasecmp}, it is locale dependent how + uppercase and lowercase characters are related. +@@ -1214,6 +1261,7 @@ + @comment wchar.h + @comment GNU + @deftypefun int wcsncasecmp (const wchar_t *@var{ws1}, const wchar_t *@var{s2}, size_t @var{n}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} + This function is like @code{wcsncmp}, except that differences in case + are ignored. Like @code{wcscasecmp}, it is locale dependent how + uppercase and lowercase characters are related. +@@ -1247,6 +1295,8 @@ + @comment string.h + @comment GNU + @deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c Calls isdigit multiple times, locale may change in between. + The @code{strverscmp} function compares the string @var{s1} against + @var{s2}, considering them as holding indices/version numbers. The + return value follows the same conventions as found in the +@@ -1258,7 +1308,7 @@ + mode, where each sequence of digits is taken as a whole. If we reach the + end of these two parts without noticing a difference, we return to the + standard comparison mode. There are two types of numeric parts: +-"integral" and "fractional" (those begin with a '0'). The types ++"integral" and "fractional" (those begin with a '0'). The types + of the numeric parts affect the way we sort them: + + @itemize @bullet +@@ -1297,6 +1347,7 @@ + @comment string.h + @comment BSD + @deftypefun int bcmp (const void *@var{a1}, const void *@var{a2}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is an obsolete alias for @code{memcmp}, derived from BSD. + @end deftypefun + +@@ -1343,6 +1394,9 @@ + @comment string.h + @comment ISO + @deftypefun int strcoll (const char *@var{s1}, const char *@var{s2}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Calls strcoll_l with the current locale, which dereferences only the ++@c LC_COLLATE data pointer. + The @code{strcoll} function is similar to @code{strcmp} but uses the + collating sequence of the current locale for collation (the + @code{LC_COLLATE} locale). +@@ -1351,6 +1405,8 @@ + @comment wchar.h + @comment ISO + @deftypefun int wcscoll (const wchar_t *@var{ws1}, const wchar_t *@var{ws2}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Same as strcoll, but calling wcscoll_l. + The @code{wcscoll} function is similar to @code{wcscmp} but uses the + collating sequence of the current locale for collation (the + @code{LC_COLLATE} locale). +@@ -1370,7 +1426,7 @@ + compare_elements (const void *v1, const void *v2) + @{ + char * const *p1 = v1; +- char * const *p1 = v2; ++ char * const *p2 = v2; + + return strcoll (*p1, *p2); + @} +@@ -1391,6 +1447,7 @@ + @comment string.h + @comment ISO + @deftypefun size_t strxfrm (char *restrict @var{to}, const char *restrict @var{from}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The function @code{strxfrm} transforms the string @var{from} using the + collation transformation determined by the locale currently selected for + collation, and stores the transformed string in the array @var{to}. Up +@@ -1420,6 +1477,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t wcsxfrm (wchar_t *restrict @var{wto}, const wchar_t *@var{wfrom}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The function @code{wcsxfrm} transforms wide character string @var{wfrom} + using the collation transformation determined by the locale currently + selected for collation, and stores the transformed string in the array +@@ -1514,8 +1572,8 @@ + @} + + /* @r{Sort @code{temp_array} by comparing transformed strings.} */ +- qsort (temp_array, sizeof (struct sorter), +- nstrings, compare_elements); ++ qsort (temp_array, nstrings, ++ sizeof (struct sorter), compare_elements); + + /* @r{Put the elements back in the permanent array} + @r{in their sorted order.} */ +@@ -1579,6 +1637,7 @@ + @comment string.h + @comment ISO + @deftypefun {void *} memchr (const void *@var{block}, int @var{c}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function finds the first occurrence of the byte @var{c} (converted + to an @code{unsigned char}) in the initial @var{size} bytes of the + object beginning at @var{block}. The return value is a pointer to the +@@ -1588,6 +1647,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wmemchr (const wchar_t *@var{block}, wchar_t @var{wc}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function finds the first occurrence of the wide character @var{wc} + in the initial @var{size} wide characters of the object beginning at + @var{block}. The return value is a pointer to the located wide +@@ -1597,6 +1657,7 @@ + @comment string.h + @comment GNU + @deftypefun {void *} rawmemchr (const void *@var{block}, int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Often the @code{memchr} function is used with the knowledge that the + byte @var{c} is available in the memory block specified by the + parameters. But this means that the @var{size} parameter is not really +@@ -1627,6 +1688,7 @@ + @comment string.h + @comment GNU + @deftypefun {void *} memrchr (const void *@var{block}, int @var{c}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{memrchr} is like @code{memchr}, except that it searches + backwards from the end of the block defined by @var{block} and @var{size} + (instead of forwards from the front). +@@ -1637,6 +1699,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strchr (const char *@var{string}, int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strchr} function finds the first occurrence of the character + @var{c} (converted to a @code{char}) in the null-terminated string + beginning at @var{string}. The return value is a pointer to the located +@@ -1663,6 +1726,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcschr (const wchar_t *@var{wstring}, int @var{wc}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wcschr} function finds the first occurrence of the wide + character @var{wc} in the null-terminated wide character string + beginning at @var{wstring}. The return value is a pointer to the +@@ -1678,6 +1742,7 @@ + @comment string.h + @comment GNU + @deftypefun {char *} strchrnul (const char *@var{string}, int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{strchrnul} is the same as @code{strchr} except that if it does + not find the character, it returns a pointer to string's terminating + null character rather than a null pointer. +@@ -1688,6 +1753,7 @@ + @comment wchar.h + @comment GNU + @deftypefun {wchar_t *} wcschrnul (const wchar_t *@var{wstring}, wchar_t @var{wc}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{wcschrnul} is the same as @code{wcschr} except that if it does not + find the wide character, it returns a pointer to wide character string's + terminating null wide character rather than a null pointer. +@@ -1723,6 +1789,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strrchr (const char *@var{string}, int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{strrchr} is like @code{strchr}, except that it searches + backwards from the end of the string @var{string} (instead of forwards + from the front). +@@ -1737,6 +1804,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcsrchr (const wchar_t *@var{wstring}, wchar_t @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The function @code{wcsrchr} is like @code{wcschr}, except that it searches + backwards from the end of the string @var{wstring} (instead of forwards + from the front). +@@ -1745,6 +1813,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strstr (const char *@var{haystack}, const char *@var{needle}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is like @code{strchr}, except that it searches @var{haystack} for a + substring @var{needle} rather than just a single character. It + returns a pointer into the string @var{haystack} that is the first +@@ -1763,6 +1832,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcsstr (const wchar_t *@var{haystack}, const wchar_t *@var{needle}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is like @code{wcschr}, except that it searches @var{haystack} for a + substring @var{needle} rather than just a single wide character. It + returns a pointer into the string @var{haystack} that is the first wide +@@ -1773,7 +1843,8 @@ + @comment wchar.h + @comment XPG + @deftypefun {wchar_t *} wcswcs (const wchar_t *@var{haystack}, const wchar_t *@var{needle}) +-@code{wcswcs} is an deprecated alias for @code{wcsstr}. This is the ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@code{wcswcs} is a deprecated alias for @code{wcsstr}. This is the + name originally used in the X/Open Portability Guide before the + @w{Amendment 1} to @w{ISO C90} was published. + @end deftypefun +@@ -1782,6 +1853,9 @@ + @comment string.h + @comment GNU + @deftypefun {char *} strcasestr (const char *@var{haystack}, const char *@var{needle}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c There may be multiple calls of strncasecmp, each accessing the locale ++@c object independently. + This is like @code{strstr}, except that it ignores case in searching for + the substring. Like @code{strcasecmp}, it is locale dependent how + uppercase and lowercase characters are related. +@@ -1800,6 +1874,7 @@ + @comment string.h + @comment GNU + @deftypefun {void *} memmem (const void *@var{haystack}, size_t @var{haystack-len},@*const void *@var{needle}, size_t @var{needle-len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This is like @code{strstr}, but @var{needle} and @var{haystack} are byte + arrays rather than null-terminated strings. @var{needle-len} is the + length of @var{needle} and @var{haystack-len} is the length of +@@ -1811,6 +1886,7 @@ + @comment string.h + @comment ISO + @deftypefun size_t strspn (const char *@var{string}, const char *@var{skipset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strspn} (``string span'') function returns the length of the + initial substring of @var{string} that consists entirely of characters that + are members of the set specified by the string @var{skipset}. The order +@@ -1831,6 +1907,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t wcsspn (const wchar_t *@var{wstring}, const wchar_t *@var{skipset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wcsspn} (``wide character string span'') function returns the + length of the initial substring of @var{wstring} that consists entirely + of wide characters that are members of the set specified by the string +@@ -1841,6 +1918,7 @@ + @comment string.h + @comment ISO + @deftypefun size_t strcspn (const char *@var{string}, const char *@var{stopset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strcspn} (``string complement span'') function returns the length + of the initial substring of @var{string} that consists entirely of characters + that are @emph{not} members of the set specified by the string @var{stopset}. +@@ -1862,6 +1940,7 @@ + @comment wchar.h + @comment ISO + @deftypefun size_t wcscspn (const wchar_t *@var{wstring}, const wchar_t *@var{stopset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wcscspn} (``wide character string complement span'') function + returns the length of the initial substring of @var{wstring} that + consists entirely of wide characters that are @emph{not} members of the +@@ -1873,6 +1952,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strpbrk (const char *@var{string}, const char *@var{stopset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{strpbrk} (``string pointer break'') function is related to + @code{strcspn}, except that it returns a pointer to the first character + in @var{string} that is a member of the set @var{stopset} instead of the +@@ -1897,6 +1977,7 @@ + @comment wchar.h + @comment ISO + @deftypefun {wchar_t *} wcspbrk (const wchar_t *@var{wstring}, const wchar_t *@var{stopset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{wcspbrk} (``wide character string pointer break'') function is + related to @code{wcscspn}, except that it returns a pointer to the first + wide character in @var{wstring} that is a member of the set +@@ -1910,6 +1991,7 @@ + @comment string.h + @comment BSD + @deftypefun {char *} index (const char *@var{string}, int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{index} is another name for @code{strchr}; they are exactly the same. + New code should always use @code{strchr} since this name is defined in + @w{ISO C} while @code{index} is a BSD invention which never was available +@@ -1919,6 +2001,7 @@ + @comment string.h + @comment BSD + @deftypefun {char *} rindex (const char *@var{string}, int @var{c}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{rindex} is another name for @code{strrchr}; they are exactly the same. + New code should always use @code{strrchr} since this name is defined in + @w{ISO C} while @code{rindex} is a BSD invention which never was available +@@ -1940,6 +2023,7 @@ + @comment string.h + @comment ISO + @deftypefun {char *} strtok (char *restrict @var{newstring}, const char *restrict @var{delimiters}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:strtok}}@asunsafe{}@acsafe{}} + A string can be split into tokens by making a series of calls to the + function @code{strtok}. + +@@ -1978,7 +2062,8 @@ + + @comment wchar.h + @comment ISO +-@deftypefun {wchar_t *} wcstok (wchar_t *@var{newstring}, const char *@var{delimiters}) ++@deftypefun {wchar_t *} wcstok (wchar_t *@var{newstring}, const wchar_t *@var{delimiters}, wchar_t **@var{save_ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + A string can be split into tokens by making a series of calls to the + function @code{wcstok}. + +@@ -1986,11 +2071,8 @@ + the first call only. The @code{wcstok} function uses this to set up + some internal state information. Subsequent calls to get additional + tokens from the same wide character string are indicated by passing a +-null pointer as the @var{newstring} argument. Calling @code{wcstok} +-with another non-null @var{newstring} argument reinitializes the state +-information. It is guaranteed that no other library function ever calls +-@code{wcstok} behind your back (which would mess up this internal state +-information). ++null pointer as the @var{newstring} argument, which causes the pointer ++previously stored in @var{save_ptr} to be used instead. + + The @var{delimiters} argument is a wide character string that specifies + a set of delimiters that may surround the token being extracted. All +@@ -1999,8 +2081,10 @@ + delimiters marks the beginning of the next token. The end of the token + is found by looking for the next wide character that is a member of the + delimiter set. This wide character in the original wide character +-string @var{newstring} is overwritten by a null wide character, and the +-pointer to the beginning of the token in @var{newstring} is returned. ++string @var{newstring} is overwritten by a null wide character, the ++pointer past the overwritten wide character is saved in @var{save_ptr}, ++and the pointer to the beginning of the token in @var{newstring} is ++returned. + + On the next call to @code{wcstok}, the searching begins at the next + wide character beyond the one that marked the end of the previous token. +@@ -2010,11 +2094,6 @@ + If the end of the wide character string @var{newstring} is reached, or + if the remainder of string consists only of delimiter wide characters, + @code{wcstok} returns a null pointer. +- +-Note that ``character'' is here used in the sense of byte. In a string +-using a multibyte character encoding (abstract) character consisting of +-more than one byte are not treated as an entity. Each byte is treated +-separately. The function is not locale-dependent. + @end deftypefun + + @strong{Warning:} Since @code{strtok} and @code{wcstok} alter the string +@@ -2039,7 +2118,7 @@ + structure, then it is error-prone to modify the data structure + temporarily. + +-The functions @code{strtok} and @code{wcstok} are not reentrant. ++The function @code{strtok} is not reentrant, whereas @code{wcstok} is. + @xref{Nonreentrancy}, for a discussion of where and why reentrancy is + important. + +@@ -2075,13 +2154,15 @@ + @comment string.h + @comment POSIX + @deftypefun {char *} strtok_r (char *@var{newstring}, const char *@var{delimiters}, char **@var{save_ptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Just like @code{strtok}, this function splits the string into several + tokens which can be accessed by successive calls to @code{strtok_r}. +-The difference is that the information about the next token is stored in +-the space pointed to by the third argument, @var{save_ptr}, which is a +-pointer to a string pointer. Calling @code{strtok_r} with a null +-pointer for @var{newstring} and leaving @var{save_ptr} between the calls +-unchanged does the job without hindering reentrancy. ++The difference is that, as in @code{wcstok}, the information about the ++next token is stored in the space pointed to by the third argument, ++@var{save_ptr}, which is a pointer to a string pointer. Calling ++@code{strtok_r} with a null pointer for @var{newstring} and leaving ++@var{save_ptr} between the calls unchanged does the job without ++hindering reentrancy. + + This function is defined in POSIX.1 and can be found on many systems + which support multi-threading. +@@ -2090,6 +2171,7 @@ + @comment string.h + @comment BSD + @deftypefun {char *} strsep (char **@var{string_ptr}, const char *@var{delimiter}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function has a similar functionality as @code{strtok_r} with the + @var{newstring} argument replaced by the @var{save_ptr} argument. The + initialization of the moving pointer has to be done by the user. +@@ -2141,6 +2223,7 @@ + @comment string.h + @comment GNU + @deftypefun {char *} basename (const char *@var{filename}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The GNU version of the @code{basename} function returns the last + component of the path in @var{filename}. This function is the preferred + usage, since it does not modify the argument, @var{filename}, and +@@ -2175,8 +2258,9 @@ + + @comment libgen.h + @comment XPG +-@deftypefun {char *} basename (char *@var{path}) +-This is the standard XPG defined @code{basename}. It is similar in ++@deftypefun {char *} basename (const char *@var{path}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++This is the standard XPG defined @code{basename}. It is similar in + spirit to the GNU version, but may modify the @var{path} by removing + trailing '/' characters. If the @var{path} is made up entirely of '/' + characters, then "/" will be returned. Also, if @var{path} is +@@ -2211,6 +2295,7 @@ + @comment libgen.h + @comment XPG + @deftypefun {char *} dirname (char *@var{path}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{dirname} function is the compliment to the XPG version of + @code{basename}. It returns the parent directory of the file specified + by @var{path}. If @var{path} is @code{NULL}, an empty string, or +@@ -2233,6 +2318,8 @@ + @comment string.h + @comment GNU + @deftypefun {char *} strfry (char *@var{string}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Calls initstate_r, time, getpid, strlen, and random_r. + + @code{strfry} creates a pseudorandom anagram of a string, replacing the + input with the anagram in place. For each position in the string, +@@ -2268,6 +2355,7 @@ + @comment string.h + @comment GNU + @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + + @code{memfrob} transforms (frobnicates) each byte of the data structure + at @var{mem}, which is @var{length} bytes long, by bitwise exclusive +@@ -2291,13 +2379,14 @@ + + To store or transfer binary data in environments which only support text + one has to encode the binary data by mapping the input bytes to +-characters in the range allowed for storing or transfering. SVID ++characters in the range allowed for storing or transferring. SVID + systems (and nowadays XPG compliant systems) provide minimal support for + this task. + + @comment stdlib.h + @comment XPG + @deftypefun {char *} l64a (long int @var{n}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:l64a}}@asunsafe{}@acsafe{}} + This function encodes a 32-bit input value using characters from the + basic character set. It returns a pointer to a 7 character buffer which + contains an encoded version of @var{n}. To encode a series of bytes the +@@ -2373,6 +2462,7 @@ + @comment stdlib.h + @comment XPG + @deftypefun {long int} a64l (const char *@var{string}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The parameter @var{string} should contain a string which was produced by + a call to @code{l64a}. The function processes at least 6 characters of + this string, and decodes the characters it finds according to the table +@@ -2459,6 +2549,7 @@ + @comment argz.h + @comment GNU + @deftypefun {error_t} argz_create (char *const @var{argv}[], char **@var{argz}, size_t *@var{argz_len}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{argz_create} function converts the Unix-style argument vector + @var{argv} (a vector of pointers to normal C strings, terminated by + @code{(char *)0}; @pxref{Program Arguments}) into an argz vector with +@@ -2468,6 +2559,7 @@ + @comment argz.h + @comment GNU + @deftypefun {error_t} argz_create_sep (const char *@var{string}, int @var{sep}, char **@var{argz}, size_t *@var{argz_len}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{argz_create_sep} function converts the null-terminated string + @var{string} into an argz vector (returned in @var{argz} and + @var{argz_len}) by splitting it into elements at every occurrence of the +@@ -2477,13 +2569,15 @@ + @comment argz.h + @comment GNU + @deftypefun {size_t} argz_count (const char *@var{argz}, size_t @var{arg_len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + Returns the number of elements in the argz vector @var{argz} and + @var{argz_len}. + @end deftypefun + + @comment argz.h + @comment GNU +-@deftypefun {void} argz_extract (char *@var{argz}, size_t @var{argz_len}, char **@var{argv}) ++@deftypefun {void} argz_extract (const char *@var{argz}, size_t @var{argz_len}, char **@var{argv}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{argz_extract} function converts the argz vector @var{argz} and + @var{argz_len} into a Unix-style argument vector stored in @var{argv}, + by putting pointers to every element in @var{argz} into successive +@@ -2501,6 +2595,7 @@ + @comment argz.h + @comment GNU + @deftypefun {void} argz_stringify (char *@var{argz}, size_t @var{len}, int @var{sep}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{argz_stringify} converts @var{argz} into a normal string with + the elements separated by the character @var{sep}, by replacing each + @code{'\0'} inside @var{argz} (except the last one, which terminates the +@@ -2511,6 +2606,8 @@ + @comment argz.h + @comment GNU + @deftypefun {error_t} argz_add (char **@var{argz}, size_t *@var{argz_len}, const char *@var{str}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Calls strlen and argz_append. + The @code{argz_add} function adds the string @var{str} to the end of the + argz vector @code{*@var{argz}}, and updates @code{*@var{argz}} and + @code{*@var{argz_len}} accordingly. +@@ -2519,6 +2616,7 @@ + @comment argz.h + @comment GNU + @deftypefun {error_t} argz_add_sep (char **@var{argz}, size_t *@var{argz_len}, const char *@var{str}, int @var{delim}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{argz_add_sep} function is similar to @code{argz_add}, but + @var{str} is split into separate elements in the result at occurrences of + the character @var{delim}. This is useful, for instance, for +@@ -2529,6 +2627,7 @@ + @comment argz.h + @comment GNU + @deftypefun {error_t} argz_append (char **@var{argz}, size_t *@var{argz_len}, const char *@var{buf}, size_t @var{buf_len}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{argz_append} function appends @var{buf_len} bytes starting at + @var{buf} to the argz vector @code{*@var{argz}}, reallocating + @code{*@var{argz}} to accommodate it, and adding @var{buf_len} to +@@ -2538,6 +2637,8 @@ + @comment argz.h + @comment GNU + @deftypefun {void} argz_delete (char **@var{argz}, size_t *@var{argz_len}, char *@var{entry}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Calls free if no argument is left. + If @var{entry} points to the beginning of one of the elements in the + argz vector @code{*@var{argz}}, the @code{argz_delete} function will + remove this entry and reallocate @code{*@var{argz}}, modifying +@@ -2549,6 +2650,8 @@ + @comment argz.h + @comment GNU + @deftypefun {error_t} argz_insert (char **@var{argz}, size_t *@var{argz_len}, char *@var{before}, const char *@var{entry}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Calls argz_add or realloc and memmove. + The @code{argz_insert} function inserts the string @var{entry} into the + argz vector @code{*@var{argz}} at a point just before the existing + element pointed to by @var{before}, reallocating @code{*@var{argz}} and +@@ -2561,7 +2664,8 @@ + + @comment argz.h + @comment GNU +-@deftypefun {char *} argz_next (char *@var{argz}, size_t @var{argz_len}, const char *@var{entry}) ++@deftypefun {char *} argz_next (const char *@var{argz}, size_t @var{argz_len}, const char *@var{entry}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{argz_next} function provides a convenient way of iterating + over the elements in the argz vector @var{argz}. It returns a pointer + to the next element in @var{argz} after the element @var{entry}, or +@@ -2595,6 +2699,7 @@ + @comment argz.h + @comment GNU + @deftypefun error_t argz_replace (@w{char **@var{argz}, size_t *@var{argz_len}}, @w{const char *@var{str}, const char *@var{with}}, @w{unsigned *@var{replace_count}}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + Replace any occurrences of the string @var{str} in @var{argz} with + @var{with}, reallocating @var{argz} as necessary. If + @var{replace_count} is non-zero, @code{*@var{replace_count}} will be +@@ -2630,6 +2735,7 @@ + @comment envz.h + @comment GNU + @deftypefun {char *} envz_entry (const char *@var{envz}, size_t @var{envz_len}, const char *@var{name}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{envz_entry} function finds the entry in @var{envz} with the name + @var{name}, and returns a pointer to the whole entry---that is, the argz + element which begins with @var{name} followed by a @code{'='} character. If +@@ -2639,6 +2745,7 @@ + @comment envz.h + @comment GNU + @deftypefun {char *} envz_get (const char *@var{envz}, size_t @var{envz_len}, const char *@var{name}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{envz_get} function finds the entry in @var{envz} with the name + @var{name} (like @code{envz_entry}), and returns a pointer to the value + portion of that entry (following the @code{'='}). If there is no entry with +@@ -2648,6 +2755,9 @@ + @comment envz.h + @comment GNU + @deftypefun {error_t} envz_add (char **@var{envz}, size_t *@var{envz_len}, const char *@var{name}, const char *@var{value}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} ++@c Calls envz_remove, which calls enz_entry and argz_delete, and then ++@c argz_add or equivalent code that reallocs and appends name=value. + The @code{envz_add} function adds an entry to @code{*@var{envz}} + (updating @code{*@var{envz}} and @code{*@var{envz_len}}) with the name + @var{name}, and value @var{value}. If an entry with the same name +@@ -2659,6 +2769,7 @@ + @comment envz.h + @comment GNU + @deftypefun {error_t} envz_merge (char **@var{envz}, size_t *@var{envz_len}, const char *@var{envz2}, size_t @var{envz2_len}, int @var{override}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} + The @code{envz_merge} function adds each entry in @var{envz2} to @var{envz}, + as if with @code{envz_add}, updating @code{*@var{envz}} and + @code{*@var{envz_len}}. If @var{override} is true, then values in @var{envz2} +@@ -2672,6 +2783,10 @@ + @comment envz.h + @comment GNU + @deftypefun {void} envz_strip (char **@var{envz}, size_t *@var{envz_len}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{envz_strip} function removes any null entries from @var{envz}, + updating @code{*@var{envz}} and @code{*@var{envz_len}}. + @end deftypefun ++ ++@c FIXME this are undocumented: ++@c strcasecmp_l @safety{@mtsafe{}@assafe{}@acsafe{}} see strcasecmp +diff -urN glibc-2.17-c758a686/manual/summary.awk glibc-2.17-c758a686/manual/summary.awk +--- glibc-2.17-c758a686/manual/summary.awk 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/summary.awk 2014-09-12 16:10:06.042792724 -0400 +@@ -1,5 +1,5 @@ + # awk script to create summary.texinfo from the library texinfo files. +-# Copyright (C) 1992, 1993, 1997, 2001 Free Software Foundation, Inc. ++# Copyright (C) 1992-2014 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +diff -urN glibc-2.17-c758a686/manual/sysinfo.texi glibc-2.17-c758a686/manual/sysinfo.texi +--- glibc-2.17-c758a686/manual/sysinfo.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/sysinfo.texi 2014-09-12 16:10:06.048792709 -0400 +@@ -91,6 +91,9 @@ + @comment unistd.h + @comment BSD + @deftypefun int gethostname (char *@var{name}, size_t @var{size}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on unix; implemented in terms of uname on posix and of ++@c hurd_get_host_config on hurd. + This function returns the host name of the system on which it is called, + in the array @var{name}. The @var{size} argument specifies the size of + this array, in bytes. Note that this is @emph{not} the DNS hostname. +@@ -121,6 +124,9 @@ + @comment unistd.h + @comment BSD + @deftypefun int sethostname (const char *@var{name}, size_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on unix; implemented in terms of hurd_set_host_config ++@c on hurd. + The @code{sethostname} function sets the host name of the system that + calls it to @var{name}, a string with length @var{length}. Only + privileged processes are permitted to do this. +@@ -145,6 +151,8 @@ + @comment unistd.h + @comment ??? + @deftypefun int getdomainnname (char *@var{name}, size_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Syscalls uname, then strlen and memcpy. + @cindex NIS domain name + @cindex YP domain name + +@@ -159,6 +167,8 @@ + @comment unistd.h + @comment ??? + @deftypefun int setdomainname (const char *@var{name}, size_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall. + @cindex NIS domain name + @cindex YP domain name + +@@ -173,6 +183,10 @@ + @comment unistd.h + @comment BSD + @deftypefun {long int} gethostid (void) ++@safety{@prelim{}@mtsafe{@mtshostid{} @mtsenv{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@aculock{} @acucorrupt{} @acsmem{} @acsfd{}}} ++@c On HURD, calls _hurd_get_host_config and strtol. On Linux, open ++@c HOSTIDFILE, reads an int32_t and closes; if that fails, it calls ++@c gethostname and gethostbyname_r to use the h_addr. + This function returns the ``host ID'' of the machine the program is + running on. By convention, this is usually the primary Internet IP address + of that machine, converted to a @w{@code{long int}}. However, on some +@@ -190,6 +204,7 @@ + @comment unistd.h + @comment BSD + @deftypefun int sethostid (long int @var{id}) ++@safety{@prelim{}@mtunsafe{@mtasuconst{:@mtshostid{}}}@asunsafe{}@acunsafe{@acucorrupt{} @acsfd{}}} + The @code{sethostid} function sets the ``host ID'' of the host machine + to @var{id}. Only privileged processes are permitted to do this. Usually + it happens just once, at system boot time. +@@ -226,7 +241,7 @@ + + As a bonus, @code{uname} also gives some information identifying the + particular system your program is running on. This is the same information +-which you can get with functions targetted to this purpose described in ++which you can get with functions targeted to this purpose described in + @ref{Host Identification}. + + +@@ -296,6 +311,10 @@ + @comment sys/utsname.h + @comment POSIX.1 + @deftypefun int uname (struct utsname *@var{info}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall on unix; the posix fallback is to call gethostname and ++@c then fills in the other fields with constants; on HURD, it calls ++@c proc_uname and then gethostname. + The @code{uname} function fills in the structure pointed to by + @var{info} with information about the operating system and host machine. + A non-negative value indicates that the data was successfully stored. +@@ -471,6 +490,12 @@ + @comment fstab.h + @comment BSD + @deftypefun int setfsent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent}}@asunsafe{@ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c setfsent @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd ++@c fstab_init(1) @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd ++@c malloc dup @ascuheap @acsmem ++@c rewind dup @asucorrupt @acucorrupt [no @aculock] ++@c setmntent dup @ascuheap @asulock @acsmem @acsfd @aculock + This function makes sure that the internal read pointer for the + @file{fstab} file is at the beginning of the file. This is done by + either opening the file or resetting the read pointer. +@@ -486,6 +511,9 @@ + @comment fstab.h + @comment BSD + @deftypefun void endfsent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent}}@asunsafe{@ascuheap{} @asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c endfsent @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd ++@c endmntent dup @ascuheap @asulock @aculock @acsmem @acsfd + This function makes sure that all resources acquired by a prior call to + @code{setfsent} (explicitly or implicitly by calling @code{getfsent}) are + freed. +@@ -494,6 +522,13 @@ + @comment fstab.h + @comment BSD + @deftypefun {struct fstab *} getfsent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c getfsent @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c fstab_init(0) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd ++@c fstab_fetch @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem ++@c getmntent_r dup @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem ++@c fstab_convert @mtasurace:fsent ++@c hasmntopt dup ok + This function returns the next entry of the @file{fstab} file. If this + is the first call to any of the functions handling @file{fstab} since + program start or the last call of @code{endfsent}, the file will be +@@ -508,6 +543,12 @@ + @comment fstab.h + @comment BSD + @deftypefun {struct fstab *} getfsspec (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c getffsspec @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c fstab_init(1) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd ++@c fstab_fetch dup @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem ++@c strcmp dup ok ++@c fstab_convert dup @mtasurace:fsent + This function returns the next entry of the @file{fstab} file which has + a string equal to @var{name} pointed to by the @code{fs_spec} element. + Since there is normally exactly one entry for each special device it +@@ -525,6 +566,12 @@ + @comment fstab.h + @comment BSD + @deftypefun {struct fstab *} getfsfile (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fsent} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c getffsfile @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @asulock @acucorrupt @aculock @acsmem ++@c fstab_init(1) dup @mtasurace:fsent @ascuheap @asucorrupt @asulock @acucorrupt @aculock @acsmem @acsfd ++@c fstab_fetch dup @mtasurace:fsent @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem ++@c strcmp dup ok ++@c fstab_convert dup @mtasurace:fsent + This function returns the next entry of the @file{fstab} file which has + a string equal to @var{name} pointed to by the @code{fs_file} element. + Since there is normally exactly one entry for each mount point it +@@ -640,6 +687,13 @@ + @comment mntent.h + @comment BSD + @deftypefun {FILE *} setmntent (const char *@var{file}, const char *@var{mode}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@acsmem{} @acsfd{} @aculock{}}} ++@c setmntent @ascuheap @asulock @acsmem @acsfd @aculock ++@c strlen dup ok ++@c mempcpy dup ok ++@c memcpy dup ok ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking dup ok [no @mtasurace:stream @asulock: exclusive stream] + The @code{setmntent} function prepares the file named @var{FILE} which + must be in the format of a @file{fstab} and @file{mtab} file for the + upcoming processing through the other functions of the family. The +@@ -655,6 +709,9 @@ + @comment mntent.h + @comment BSD + @deftypefun int endmntent (FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c endmntent @ascuheap @asulock @aculock @acsmem @acsfd ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd + This function takes for the @var{stream} parameter a file handle which + previously was returned from the @code{setmntent} call. + @code{endmntent} closes the stream and frees all resources. +@@ -666,6 +723,12 @@ + @comment mntent.h + @comment BSD + @deftypefun {struct mntent *} getmntent (FILE *@var{stream}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:mntentbuf} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asuinit{}}@acunsafe{@acuinit{} @acucorrupt{} @aculock{} @acsmem{}}} ++@c getmntent @mtasurace:mntentbuf @mtslocale @asucorrupt @ascuheap @asuinit @acuinit @acucorrupt @aculock @acsmem ++@c libc_once @ascuheap @asuinit @acuinit @acsmem ++@c allocate @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c getmntent_r dup @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem + The @code{getmntent} function takes as the parameter a file handle + previously returned by successful call to @code{setmntent}. It returns + a pointer to a static variable of type @code{struct mntent} which is +@@ -691,7 +754,17 @@ + + @comment mntent.h + @comment BSD +-@deftypefun {struct mntent *} getmntent_r (FILE *@var{stream}, struct mentent *@var{result}, char *@var{buffer}, int @var{bufsize}) ++@deftypefun {struct mntent *} getmntent_r (FILE *@var{stream}, struct mntent *@var{result}, char *@var{buffer}, int @var{bufsize}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{}}} ++@c getmntent_r @mtslocale @asucorrupt @ascuheap @acucorrupt @aculock @acsmem ++@c flockfile dup @aculock ++@c fgets_unlocked dup @asucorrupt @acucorrupt [locked, so no @mtsrace:stream] ++@c funlockfile dup @aculock ++@c strchr dup ok ++@c strspn dup ok ++@c strsep dup ok ++@c decode_name ok ++@c sscanf dup @mtslocale @ascuheap @acsmem + The @code{getmntent_r} function is the reentrant variant of + @code{getmntent}. It also returns the next entry from the file and + returns a pointer. The actual variable the values are stored in is not +@@ -717,6 +790,12 @@ + @comment mntent.h + @comment BSD + @deftypefun int addmntent (FILE *@var{stream}, const struct mntent *@var{mnt}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:stream} @mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} ++@c addmntent @mtasurace:stream @mtslocale @asucorrupt @acucorrupt ++@c fseek dup @asucorrupt @acucorrupt [no @aculock] ++@c encode_name ok ++@c fprintf dup @mtslocale @asucorrupt @acucorrupt [no @ascuheap @acsmem, no @aculock] ++@c fflush dup @asucorrupt @acucorrupt [no @aculock] + The @code{addmntent} function allows adding a new entry to the file + previously opened with @code{setmntent}. The new entries are always + appended. I.e., even if the position of the file descriptor is not at +@@ -740,6 +819,11 @@ + @comment mntent.h + @comment BSD + @deftypefun {char *} hasmntopt (const struct mntent *@var{mnt}, const char *@var{opt}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c hasmntopt ok ++@c strlen dup ok ++@c strstr dup ok ++@c strchr dup ok + This function can be used to check whether the string pointed to by the + @code{mnt_opts} element of the variable pointed to by @var{mnt} contains + the option @var{opt}. If this is true a pointer to the beginning of the +@@ -778,6 +862,8 @@ + @comment sys/mount.h + @comment SVID, BSD + @deftypefun {int} mount (const char *@var{special_file}, const char *@var{dir}, const char *@var{fstype}, unsigned long int @var{options}, const void *@var{data}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall. + + @code{mount} mounts or remounts a filesystem. The two operations are + quite different and are merged rather unnaturally into this one function. +@@ -982,6 +1068,8 @@ + @comment sys/mount.h + @comment GNU + @deftypefun {int} umount2 (const char *@var{file}, int @var{flags}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall. + + @code{umount2} unmounts a filesystem. + +@@ -1047,6 +1135,8 @@ + @comment sys/mount.h + @comment SVID, GNU + @deftypefun {int} umount (const char *@var{file}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall or wrapper for umount2. + + @code{umount} does the same thing as @code{umount2} with @var{flags} set + to zeroes. It is more widely available than @code{umount2} but since it +@@ -1062,11 +1152,13 @@ + This section describes the @code{sysctl} function, which gets and sets + a variety of system parameters. + +-The symbols used in this section are declared in the file @file{sysctl.h}. ++The symbols used in this section are declared in the file @file{sys/sysctl.h}. + +-@comment sysctl.h ++@comment sys/sysctl.h + @comment BSD + @deftypefun int sysctl (int *@var{names}, int @var{nlen}, void *@var{oldval}, size_t *@var{oldlenp}, void *@var{newval}, size_t @var{newlen}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct syscall, Linux only. + + @code{sysctl} gets or sets a specified system parameter. There are so + many of these parameters that it is not practical to list them all here, +@@ -1090,7 +1182,7 @@ + a particular parameter, you specify a path through the structure in a + way analogous to specifying the pathname of a file. Each component of + the path is specified by an integer and each of these integers has a +-macro defined for it by @file{sysctl.h}. @var{names} is the path, in ++macro defined for it by @file{sys/sysctl.h}. @var{names} is the path, in + the form of an array of integers. Each component of the path is one + element of the array, in order. @var{nlen} is the number of components + in the path. +diff -urN glibc-2.17-c758a686/manual/syslog.texi glibc-2.17-c758a686/manual/syslog.texi +--- glibc-2.17-c758a686/manual/syslog.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/syslog.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -147,6 +147,17 @@ + @comment syslog.h + @comment BSD + @deftypefun void openlog (const char *@var{ident}, int @var{option}, int @var{facility}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c openlog @asulock @aculock @acsfd ++@c libc_lock_lock @asulock @aculock ++@c openlog_internal @acsfd [always guarded by syslog_lock, so no race] ++@c strncpy dup ok ++@c socket dup @acsfd ++@c fcntl dup ok ++@c connect dup ok ++@c close dup @acsfd ++@c cancel_handler(NULL) @aculock ++@c libc_lock_unlock @aculock + + @code{openlog} opens or reopens a connection to Syslog in preparation + for submitting messages. +@@ -275,7 +286,39 @@ + @c syslog() is implemented as a call to vsyslog(). + @comment syslog.h + @comment BSD +-@deftypefun void syslog (int @var{facility_priority}, char *@var{format}, @dots{}) ++@deftypefun void syslog (int @var{facility_priority}, const char *@var{format}, @dots{}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c syslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c va_start dup ok ++@c vsyslog_chk @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c syslog(INTERNALLOG) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c open_memstream @ascuheap @acsmem ++@c stpcpy dup ok ++@c getpid dup ok ++@c mempcpy dup ok ++@c fsetlocking [no @mtasurace:stream @asulock for exclusive stream] ++@c fprintf @mtslocale @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt on temp memstream] ++@c time dup ok ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c strftime_l(C) dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c ftell dup ok [no @asucorrupt @aculock @acucorrupt on temp memstream] ++@c fputs_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream] ++@c putc_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream] ++@c vfprintf/vfprintf_chk dup @mtslocale @ascuheap @acsmem [no @mtasurace:stream @asucorrupt @acucorrupt on temp memstream] ++@c fclose dup @ascuheap @acsmem [no @asulock @aculock @acsfd on caller-locked memstream] ++@c writev dup ok ++@c libc_lock_lock dup @asulock @aculock ++@c memset dup ok ++@c sigemptyset dup ok ++@c sigaction(SIGPIPE) dup @mtasusig:PIPE @acusig:PIPE ++@c openlog_internal dup @acsfd ++@c send dup ok ++@c closelog_internal dup @acsfd ++@c open dup @acsfd ++@c dprintf dup ok ++@c libc_lock_unlock @asulock @aculock ++@c free dup @acsuheap @acsmem ++@c va_end dup ok + + @code{syslog} submits a message to the Syslog facility. It does this by + writing to the Unix domain socket @code{/dev/log}. +@@ -403,7 +446,10 @@ + + @comment syslog.h + @comment BSD +-@deftypefun void vsyslog (int @var{facility_priority}, char *@var{format}, va_list @var{arglist}) ++@deftypefun void vsyslog (int @var{facility_priority}, const char *@var{format}, va_list @var{arglist}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c vsyslog @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c vsyslog_chk dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd + + This is functionally identical to @code{syslog}, with the BSD style variable + length argument. +@@ -420,6 +466,13 @@ + @comment syslog.h + @comment BSD + @deftypefun void closelog (void) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c closelog @asulock @aculock @acsfd ++@c libc_lock_lock @asulock @aculock ++@c closelog_internal @acsfd [always guarded by syslog_lock, so no race] ++@c close dup@acsfd ++@c cancel_handler(NULL) @aculock ++@c libc_lock_unlock @aculock + + @code{closelog} closes the current Syslog connection, if there is one. + This includes closing the @file{/dev/log} socket, if it is open. +@@ -450,6 +503,10 @@ + @comment syslog.h + @comment BSD + @deftypefun int setlogmask (int @var{mask}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:LogMask}}@asunsafe{}@acsafe{}} ++@c Read and modify are not guarded by syslog_lock, so concurrent changes ++@c or even uses are undefined. This should use an atomic swap instead, ++@c at least for modifications. + + @code{setlogmask} sets a mask (the ``logmask'') that determines which + future @code{syslog} calls shall be ignored. If a program has not +diff -urN glibc-2.17-c758a686/manual/terminal.texi glibc-2.17-c758a686/manual/terminal.texi +--- glibc-2.17-c758a686/manual/terminal.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/terminal.texi 2014-09-12 16:10:06.047792712 -0400 +@@ -44,6 +44,9 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int isatty (int @var{filedes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c isatty ok ++@c tcgetattr dup ok + This function returns @code{1} if @var{filedes} is a file descriptor + associated with an open terminal device, and @math{0} otherwise. + @end deftypefun +@@ -55,6 +58,20 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {char *} ttyname (int @var{filedes}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c ttyname @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd ++@c isatty dup ok ++@c fstat dup ok ++@c memcpy dup ok ++@c getttyname @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd ++@c opendir @ascuheap @acsmem @acsfd ++@c readdir ok [protected by exclusive access] ++@c strcmp dup ok ++@c free dup @asulock @aculock @acsfd @acsmem ++@c malloc dup @asulock @aculock @acsfd @acsmem ++@c closedir @ascuheap @acsmem @acsfd ++@c mempcpy dup ok ++@c stat dup ok + If the file descriptor @var{filedes} is associated with a terminal + device, the @code{ttyname} function returns a pointer to a + statically-allocated, null-terminated string containing the file name of +@@ -65,6 +82,18 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int ttyname_r (int @var{filedes}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{} @acsfd{}}} ++@c ttyname_r @ascuheap @acsmem @acsfd ++@c isatty dup ok ++@c fstat dup ok ++@c memcpy dup ok ++@c getttyname_r @ascuheap @acsmem @acsfd ++@c opendir @ascuheap @acsmem @acsfd ++@c readdir ok [protected by exclusive access] ++@c strcmp dup ok ++@c closedir @ascuheap @acsmem @acsfd ++@c stpncpy dup ok ++@c stat dup ok + The @code{ttyname_r} function is similar to the @code{ttyname} function + except that it places its result into the user-specified buffer starting + at @var{buf} with length @var{len}. +@@ -264,6 +293,9 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int tcgetattr (int @var{filedes}, struct termios *@var{termios-p}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Converting the kernel-returned termios data structure to the userland ++@c format does not ensure atomic or consistent writing. + This function is used to examine the attributes of the terminal + device with file descriptor @var{filedes}. The attributes are returned + in the structure that @var{termios-p} points to. +@@ -284,6 +316,9 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int tcsetattr (int @var{filedes}, int @var{when}, const struct termios *@var{termios-p}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Converting the incoming termios data structure to the kernel format ++@c does not ensure atomic or consistent reading. + This function sets the attributes of the terminal device with file + descriptor @var{filedes}. The new attributes are taken from the + structure that @var{termios-p} points to. +@@ -621,7 +656,7 @@ + of characters, carriage return followed by linefeed. + @end deftypevr + +-@comment termios.h ++@comment termios.h (optional) + @comment BSD + @deftypevr Macro tcflag_t OXTABS + If this bit is set, convert tab characters on output into the appropriate +@@ -630,7 +665,7 @@ + @gnulinuxsystems{} it is available as @code{XTABS}. + @end deftypevr + +-@comment termios.h ++@comment termios.h (optional) + @comment BSD + @deftypevr Macro tcflag_t ONOEOT + If this bit is set, discard @kbd{C-d} characters (code @code{004}) on +@@ -962,7 +997,7 @@ + While this bit is set, all output is discarded. @xref{Other Special}. + @end deftypevr + +-@comment termios.h ++@comment termios.h (optional) + @comment BSD + @deftypevr Macro tcflag_t NOKERNINFO + Setting this bit disables handling of the STATUS character. +@@ -1016,6 +1051,10 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun speed_t cfgetospeed (const struct termios *@var{termios-p}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct access to a single termios field, except on Linux, where ++@c multiple accesses may take place. No worries either way, callers ++@c must ensure mutual exclusion on such non-opaque types. + This function returns the output line speed stored in the structure + @code{*@var{termios-p}}. + @end deftypefun +@@ -1023,6 +1062,7 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun speed_t cfgetispeed (const struct termios *@var{termios-p}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function returns the input line speed stored in the structure + @code{*@var{termios-p}}. + @end deftypefun +@@ -1030,6 +1070,7 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int cfsetospeed (struct termios *@var{termios-p}, speed_t @var{speed}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function stores @var{speed} in @code{*@var{termios-p}} as the output + speed. The normal return value is @math{0}; a value of @math{-1} + indicates an error. If @var{speed} is not a speed, @code{cfsetospeed} +@@ -1039,6 +1080,7 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int cfsetispeed (struct termios *@var{termios-p}, speed_t @var{speed}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + This function stores @var{speed} in @code{*@var{termios-p}} as the input + speed. The normal return value is @math{0}; a value of @math{-1} + indicates an error. If @var{speed} is not a speed, @code{cfsetospeed} +@@ -1048,6 +1090,14 @@ + @comment termios.h + @comment BSD + @deftypefun int cfsetspeed (struct termios *@var{termios-p}, speed_t @var{speed}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c There's no guarantee that the two calls are atomic, but since this is ++@c not an opaque type, callers ought to ensure mutual exclusion to the ++@c termios object. ++ ++@c cfsetspeed ok ++@c cfsetispeed ok ++@c cfsetospeed ok + This function stores @var{speed} in @code{*@var{termios-p}} as both the + input and output speeds. The normal return value is @math{0}; a value + of @math{-1} indicates an error. If @var{speed} is not a speed, +@@ -1625,6 +1675,10 @@ + @comment termios.h + @comment BSD + @deftypefun void cfmakeraw (struct termios *@var{termios-p}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c There's no guarantee the changes are atomic, but since this is not an ++@c opaque type, callers ought to ensure mutual exclusion to the termios ++@c object. + This function provides an easy way to set up @code{*@var{termios-p}} for + what has traditionally been called ``raw mode'' in BSD. This uses + noncanonical input, and turns off most processing to give an unmodified +@@ -1678,6 +1732,8 @@ + @comment sgtty.h + @comment BSD + @deftypefun int gtty (int @var{filedes}, struct sgttyb *@var{attributes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct ioctl, BSD only. + This function gets the attributes of a terminal. + + @code{gtty} sets *@var{attributes} to describe the terminal attributes +@@ -1686,7 +1742,9 @@ + + @comment sgtty.h + @comment BSD +-@deftypefun int stty (int @var{filedes}, struct sgttyb *@var{attributes}) ++@deftypefun int stty (int @var{filedes}, const struct sgttyb *@var{attributes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct ioctl, BSD only. + + This function sets the attributes of a terminal. + +@@ -1710,6 +1768,12 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int tcsendbreak (int @var{filedes}, int @var{duration}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:tcattr(filedes)/bsd}}@asunsafe{}@acunsafe{@acucorrupt{/bsd}}} ++@c On Linux, this calls just one out of two ioctls; on BSD, it's two ++@c ioctls with a select (for the delay only) in between, the first ++@c setting and the latter clearing the break status. The BSD ++@c implementation may leave the break enabled if cancelled, and threads ++@c and signals may cause the break to be interrupted before requested. + This function generates a break condition by transmitting a stream of + zero bits on the terminal associated with the file descriptor + @var{filedes}. The duration of the break is controlled by the +@@ -1738,6 +1802,8 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int tcdrain (int @var{filedes}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct ioctl. + The @code{tcdrain} function waits until all queued + output to the terminal @var{filedes} has been transmitted. + +@@ -1772,6 +1838,8 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int tcflush (int @var{filedes}, int @var{queue}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Direct ioctl. + The @code{tcflush} function is used to clear the input and/or output + queues associated with the terminal file @var{filedes}. The @var{queue} + argument specifies which queue(s) to clear, and can be one of the +@@ -1822,6 +1890,11 @@ + @comment termios.h + @comment POSIX.1 + @deftypefun int tcflow (int @var{filedes}, int @var{action}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:tcattr(filedes)/bsd}}@asunsafe{}@acsafe{}} ++@c Direct ioctl on Linux. On BSD, the TCO* actions are a single ioctl, ++@c whereas the TCI actions first call tcgetattr and then write to the fd ++@c the c_cc character corresponding to the action; there's a window for ++@c another thread to change the xon/xoff characters. + The @code{tcflow} function is used to perform operations relating to + XON/XOFF flow control on the terminal file specified by @var{filedes}. + +@@ -1931,6 +2004,14 @@ + @comment stdlib.h + @comment GNU + @deftypefun int getpt (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{@acsfd{}}} ++@c On BSD, tries to open multiple potential pty names, returning on the ++@c first success. On Linux, try posix_openpt first, then fallback to ++@c the BSD implementation. The posix implementation opens the ptmx ++@c device, checks with statfs that /dev/pts is a devpts or that /dev is ++@c a devfs, and returns the fd; static variables devpts_mounted and ++@c have_no_dev_ptmx are safely initialized so as to avoid repeated ++@c tests. + The @code{getpt} function returns a new file descriptor for the next + available master pseudo-terminal. The normal return value from + @code{getpt} is a non-negative integer file descriptor. In the case of +@@ -1948,6 +2029,32 @@ + @comment stdlib.h + @comment SVID, XPG4.2 + @deftypefun int grantpt (int @var{filedes}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c grantpt @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c unix/grantpt:pts_name @acsuheap @acsmem ++@c ptsname_internal dup ok (but this is Linux-only!) ++@c memchr dup ok ++@c realloc dup @acsuheap @acsmem ++@c malloc dup @acsuheap @acsmem ++@c free dup @acsuheap @acsmem ++@c fcntl dup ok ++@c getuid dup ok ++@c chown dup ok ++@c sysconf(_SC_GETGR_R_SIZE_MAX) ok ++@c getgrnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getgid dup ok ++@c chmod dup ok ++@c fork dup @aculock ++@c [child] ++@c setrlimit ++@c dup2 ++@c CLOSE_ALL_FDS ++@c execle ++@c _exit ++@c waitpid dup ok ++@c WIFEXITED dup ok ++@c WEXITSTATUS dup ok ++@c free dup @ascuheap @acsmem + The @code{grantpt} function changes the ownership and access permission + of the slave pseudo-terminal device corresponding to the master + pseudo-terminal device associated with the file descriptor +@@ -1985,6 +2092,13 @@ + @comment stdlib.h + @comment SVID, XPG4.2 + @deftypefun int unlockpt (int @var{filedes}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd}}@acunsafe{@acsmem{} @acsfd{}}} ++@c unlockpt @ascuheap/bsd @acsmem @acsfd ++@c /bsd ++@c ptsname_r dup @ascuheap @acsmem @acsfd ++@c revoke ok (syscall) ++@c /linux ++@c ioctl dup ok + The @code{unlockpt} function unlocks the slave pseudo-terminal device + corresponding to the master pseudo-terminal device associated with the + file descriptor @var{filedes}. On many systems, the slave can only be +@@ -2008,6 +2122,9 @@ + @comment stdlib.h + @comment SVID, XPG4.2 + @deftypefun {char *} ptsname (int @var{filedes}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:ptsname}}@asunsafe{@ascuheap{/bsd}}@acunsafe{@acsmem{} @acsfd{}}} ++@c ptsname @mtasurace:ptsname @ascuheap/bsd @acsmem @acsfd ++@c ptsname_r dup @ascuheap/bsd @acsmem @acsfd + If the file descriptor @var{filedes} is associated with a + master pseudo-terminal device, the @code{ptsname} function returns a + pointer to a statically-allocated, null-terminated string containing the +@@ -2018,6 +2135,37 @@ + @comment stdlib.h + @comment GNU + @deftypefun int ptsname_r (int @var{filedes}, char *@var{buf}, size_t @var{len}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{/bsd}}@acunsafe{@acsmem{} @acsfd{}}} ++@c ptsname_r @ascuheap/bsd @acsmem @acsfd ++@c /hurd ++@c term_get_peername ok ++@c strlen dup ok ++@c memcpy dup ok ++@c /bsd ++@c isatty dup ok ++@c strlen dup ok ++@c ttyname_r dup @ascuheap @acsmem @acsfd ++@c stat dup ok ++@c /linux ++@c ptsname_internal ok ++@c isatty dup ok ++@c ioctl dup ok ++@c strlen dup ok ++@c itoa_word dup ok ++@c stpcpy dup ok ++@c memcpy dup ok ++@c fxstat64 dup ok ++@c MASTER_P ok ++@c major ok ++@c gnu_dev_major ok ++@c minor ok ++@c gnu_dev_minor ok ++@c minor dup ok ++@c xstat64 dup ok ++@c S_ISCHR dup ok ++@c SLAVE_P ok ++@c major dup ok ++@c minor dup ok + The @code{ptsname_r} function is similar to the @code{ptsname} function + except that it places its result into the user-specified buffer starting + at @var{buf} with length @var{len}. +@@ -2083,6 +2231,22 @@ + @comment pty.h + @comment BSD + @deftypefun int openpty (int *@var{amaster}, int *@var{aslave}, char *@var{name}, const struct termios *@var{termp}, const struct winsize *@var{winp}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c openpty @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getpt @acsfd ++@c grantpt @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c unlockpt dup @ascuheap/bsd @acsmem @acsfd ++@c openpty:pts_name @acsuheap @acsmem @acsfd ++@c ptsname_r dup @ascuheap/bsd @acsmem @acsfd ++@c realloc dup @acsuheap @acsmem ++@c malloc dup @acsuheap @acsmem ++@c free dup @acsuheap @acsmem ++@c open dup @acsfd ++@c free dup @acsuheap @acsmem ++@c tcsetattr dup ok ++@c ioctl dup ok ++@c strcpy dup ok ++@c close dup @acsfd + This function allocates and opens a pseudo-terminal pair, returning the + file descriptor for the master in @var{*amaster}, and the file + descriptor for the slave in @var{*aslave}. If the argument @var{name} +@@ -2114,6 +2278,16 @@ + @comment pty.h + @comment BSD + @deftypefun int forkpty (int *@var{amaster}, char *@var{name}, const struct termios *@var{termp}, const struct winsize *@var{winp}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c forkpty @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c openpty dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c fork dup @aculock ++@c close dup @acsfd ++@c /child ++@c close dup @acsfd ++@c login_tty dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd ++@c _exit dup ok ++@c close dup @acsfd + This function is similar to the @code{openpty} function, but in + addition, forks a new process (@pxref{Creating a Process}) and makes the + newly opened slave pseudo-terminal device the controlling terminal +diff -urN glibc-2.17-c758a686/manual/texinfo.tex glibc-2.17-c758a686/manual/texinfo.tex +--- glibc-2.17-c758a686/manual/texinfo.tex 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/texinfo.tex 2014-09-12 16:10:06.047792712 -0400 +@@ -3,11 +3,11 @@ + % Load plain if necessary, i.e., if running under initex. + \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi + % +-\def\texinfoversion{2012-01-19.16} ++\def\texinfoversion{2014-05-05.10} + % + % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, + % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +-% 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. ++% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. + % + % This texinfo.tex file is free software: you can redistribute it and/or + % modify it under the terms of the GNU General Public License as +@@ -24,13 +24,14 @@ + % + % As a special exception, when this file is read by TeX when processing + % a Texinfo source document, you may use the result without +-% restriction. (This has been our intent since Texinfo was invented.) ++% restriction. This Exception is an additional permission under section 7 ++% of the GNU General Public License, version 3 ("GPLv3"). + % + % Please try the latest version of texinfo.tex before submitting bug + % reports; you can get the latest version from: +-% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or +-% ftp://tug.org/tex/texinfo.tex +-% (and all CTAN mirrors, see http://www.ctan.org). ++% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or ++% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or ++% http://www.gnu.org/software/texinfo/ (the Texinfo home page) + % The texinfo.tex in any given distribution could well be out + % of date, so if that's what you're using, please check. + % +@@ -280,9 +281,9 @@ + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% +- \the\toks0 \the\toks2 +- \noexpand\or \the\toks4 \the\toks6 +- \noexpand\else \the\toks8 ++ \the\toks0 \the\toks2 % 0: top marks (\last...) ++ \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...) ++ \noexpand\else \the\toks8 % 2: color marks + }% + } + % \topmark doesn't work for the very first chapter (after the title +@@ -321,10 +322,13 @@ + % + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). ++ \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars} ++ % + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi +- \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}% ++ \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% ++ % + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi +- \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}% ++ \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% + % + {% + % Have to do this stuff outside the \shipout because we want it to +@@ -594,7 +598,7 @@ + \def\:{\spacefactor=1000 } + + % @* forces a line break. +-\def\*{\hfil\break\hbox{}\ignorespaces} ++\def\*{\unskip\hfil\break\hbox{}\ignorespaces} + + % @/ allows a line break. + \let\/=\allowbreak +@@ -887,7 +891,7 @@ + \def\popthisfilestack{\errthisfilestackempty} + \def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} +- ++% + \def\thisfile{} + + % @center line +@@ -895,36 +899,46 @@ + % + \parseargdef\center{% + \ifhmode +- \let\next\centerH ++ \let\centersub\centerH + \else +- \let\next\centerV ++ \let\centersub\centerV + \fi +- \next{\hfil \ignorespaces#1\unskip \hfil}% ++ \centersub{\hfil \ignorespaces#1\unskip \hfil}% ++ \let\centersub\relax % don't let the definition persist, just in case + } +-\def\centerH#1{% +- {% +- \hfil\break +- \advance\hsize by -\leftskip +- \advance\hsize by -\rightskip +- \line{#1}% +- \break +- }% ++\def\centerH#1{{% ++ \hfil\break ++ \advance\hsize by -\leftskip ++ \advance\hsize by -\rightskip ++ \line{#1}% ++ \break ++}} ++% ++\newcount\centerpenalty ++\def\centerV#1{% ++ % The idea here is the same as in \startdefun, \cartouche, etc.: if ++ % @center is the first thing after a section heading, we need to wipe ++ % out the negative parskip inserted by \sectionheading, but still ++ % prevent a page break here. ++ \centerpenalty = \lastpenalty ++ \ifnum\centerpenalty>10000 \vskip\parskip \fi ++ \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi ++ \line{\kern\leftskip #1\kern\rightskip}% + } +-\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}} + + % @sp n outputs n lines of vertical space +- ++% + \parseargdef\sp{\vskip #1\baselineskip} + + % @comment ...line which is ignored... + % @c is the same as @comment + % @ignore ... @end ignore is another way to write a comment +- ++% + \def\comment{\begingroup \catcode`\^^M=\other% + \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% + \commentxxx} + {\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} +- ++% + \let\c=\comment + + % @paragraphindent NCHARS +@@ -1097,7 +1111,7 @@ + % for display in the outlines, and in other places. Thus, we have to + % double any backslashes. Otherwise, a name like "\node" will be + % interpreted as a newline (\n), followed by o, d, e. Not good. +-% ++% + % See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and + % related messages. The final outcome is that it is up to the TeX user + % to double the backslashes and otherwise make the string valid, so +@@ -1107,7 +1121,7 @@ + % #1 is a control sequence in which to do the replacements, + % which we \xdef. + \def\txiescapepdf#1{% +- \ifx\pdfescapestring\relax ++ \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \else +@@ -1124,10 +1138,12 @@ + + \ifpdf + % +- % Color manipulation macros based on pdfcolor.tex, ++ % Color manipulation macros using ideas from pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead +- % of actual black. ++ % of actual black. The dark red here is dark enough to print on paper as ++ % nearly black, but still distinguishable for online viewing. We use ++ % black by default, though. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % +@@ -1173,8 +1189,8 @@ + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% +- \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% +- \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% ++ \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% ++ \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if +@@ -1212,8 +1228,8 @@ + \else + \immediate\pdfximage + \fi +- \ifdim \wd0 >0pt width \imagewidth \fi +- \ifdim \wd2 >0pt height \imageheight \fi ++ \ifdim \wd0 >0pt width \pdfimagewidth \fi ++ \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else +@@ -1237,10 +1253,9 @@ + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % +- % by default, use a color that is dark enough to print on paper as +- % nearly black, but still distinguishable for online viewing. +- \def\urlcolor{\rgbDarkRed} +- \def\linkcolor{\rgbDarkRed} ++ % by default, use black for everything. ++ \def\urlcolor{\rgbBlack} ++ \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines +@@ -1357,12 +1372,17 @@ + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces +- \ifx\p\space\else\addtokens{\filename}{\PP}% +- \advance\filenamelength by 1 +- \fi ++ \addtokens{\filename}{\PP}% ++ \advance\filenamelength by 1 + \fi + \nextsp} +- \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax} ++ \def\getfilename#1{% ++ \filenamelength=0 ++ % If we don't expand the argument now, \skipspaces will get ++ % snagged on things like "@value{foo}". ++ \edef\temp{#1}% ++ \expandafter\skipspaces\temp|\relax ++ } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else +@@ -1459,9 +1479,6 @@ + \def\ttsl{\setfontstyle{ttsl}} + + +-% Default leading. +-\newdimen\textleading \textleading = 13.2pt +- + % Set the baselineskip to #1, and the lineskip and strut size + % correspondingly. There is no deep meaning behind these magic numbers + % used as factors; they just match (closely enough) what Knuth defined. +@@ -1473,6 +1490,7 @@ + % can get a sort of poor man's double spacing by redefining this. + \def\baselinefactor{1} + % ++\newdimen\textleading + \def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 +@@ -1745,18 +1763,24 @@ + \fi\fi + + +-% Set the font macro #1 to the font named #2, adding on the +-% specified font prefix (normally `cm'). ++% Set the font macro #1 to the font named \fontprefix#2. + % #3 is the font's design size, #4 is a scale factor, #5 is the CMap +-% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass +-% empty to omit). ++% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). ++% Example: ++% #1 = \textrm ++% #2 = \rmshape ++% #3 = 10 ++% #4 = \mainmagstep ++% #5 = OT1 ++% + \def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% + } + % This is what gets called when #5 of \setfont is empty. + \let\cmap\gobble +-% emacs-page end of cmaps ++% ++% (end of cmaps) + + % Use cm as the default font prefix. + % To specify the font prefix, you must define \fontprefix +@@ -1766,7 +1790,7 @@ + \fi + % Support font families that don't use the same naming scheme as CM. + \def\rmshape{r} +-\def\rmbshape{bx} %where the normal face is bold ++\def\rmbshape{bx} % where the normal face is bold + \def\bfshape{b} + \def\bxshape{bx} + \def\ttshape{tt} +@@ -1781,8 +1805,7 @@ + \def\scshape{csc} + \def\scbshape{csc} + +-% Definitions for a main text size of 11pt. This is the default in +-% Texinfo. ++% Definitions for a main text size of 11pt. (The default in Texinfo.) + % + \def\definetextfontsizexi{% + % Text fonts (11.2pt, magstep1). +@@ -1907,7 +1930,7 @@ + \textleading = 13.2pt % line spacing for 11pt CM + \textfonts % reset the current fonts + \rm +-} % end of 11pt text font size definitions ++} % end of 11pt text font size definitions, \definetextfontsizexi + + + % Definitions to make the main text be 10pt Computer Modern, with +@@ -2039,7 +2062,7 @@ + \textleading = 12pt % line spacing for 10pt CM + \textfonts % reset the current fonts + \rm +-} % end of 10pt text font size definitions ++} % end of 10pt text font size definitions, \definetextfontsizex + + + % We provide the user-level command +@@ -2123,7 +2146,7 @@ + \let\tenttsl=\secttsl + \def\curfontsize{sec}% + \def\lsize{subsec}\def\lllsize{reduced}% +- \resetmathfonts \setleading{16pt}} ++ \resetmathfonts \setleading{17pt}} + \def\subsecfonts{% + \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl + \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc +@@ -2254,8 +2277,6 @@ + + \gdef\markupsetcodequoteleft{\let`\codequoteleft} + \gdef\markupsetcodequoteright{\let'\codequoteright} +- +-\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft} + } + + \let\markupsetuplqcode \markupsetcodequoteleft +@@ -2264,6 +2285,9 @@ + \let\markupsetuplqexample \markupsetcodequoteleft + \let\markupsetuprqexample \markupsetcodequoteright + % ++\let\markupsetuplqkbd \markupsetcodequoteleft ++\let\markupsetuprqkbd \markupsetcodequoteright ++% + \let\markupsetuplqsamp \markupsetcodequoteleft + \let\markupsetuprqsamp \markupsetcodequoteright + % +@@ -2273,8 +2297,6 @@ + \let\markupsetuplqverbatim \markupsetcodequoteleft + \let\markupsetuprqverbatim \markupsetcodequoteright + +-\let\markupsetuplqkbd \markupsetnoligaturesquoteleft +- + % Allow an option to not use regular directed right quote/apostrophe + % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). + % The undirected quote is ugly, so don't make it the default, but it +@@ -2359,13 +2381,14 @@ + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% ++ \else\ifx\next\.% ++ \else\ifx\next\comma% + \else\ptexslash +- \fi\fi\fi ++ \fi\fi\fi\fi\fi + \aftersmartic + } + +-% like \smartslanted except unconditionally uses \ttsl, and no ic. +-% @var is set to this for defun arguments. ++% Unconditional use \ttsl, and no ic. @var is set to this for defuns. + \def\ttslanted#1{{\ttsl #1}} + + % @cite is like \smartslanted except unconditionally use \sl. We never want +@@ -2430,34 +2453,12 @@ + % @samp. + \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +-% definition of @key that produces a lozenge. Doesn't adjust to text size. +-%\setfont\keyrm\rmshape{8}{1000}{OT1} +-%\font\keysy=cmsy9 +-%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +-% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +-% \vbox{\hrule\kern-0.4pt +-% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +-% \kern-0.4pt\hrule}% +-% \kern-.06em\raise0.4pt\hbox{\angleright}}}} +- +-% definition of @key with no lozenge. If the current font is already +-% monospace, don't change it; that way, we respect @kbdinputstyle. But +-% if it isn't monospace, then use \tt. +-% +-\def\key#1{{\setupmarkupstyle{key}% +- \nohyphenation +- \ifmonospace\else\tt\fi +- #1}\null} +- +-% ctrl is no longer a Texinfo command. +-\def\ctrl #1{{\tt \rawbackslash \hat}#1} ++% @indicateurl is \samp, that is, with quotes. ++\let\indicateurl=\samp + +-% @file, @option are the same as @samp. +-\let\file=\samp +-\let\option=\samp +- +-% @code is a modification of @t, +-% which makes spaces the same size as normal in the surrounding text. ++% @code (and similar) prints in typewriter, but with spaces the same ++% size as normal in the surrounding text, without hyphenation, etc. ++% This is a subroutine for that. + \def\tclose#1{% + {% + % Change normal interword space to be same as for the current font. +@@ -2480,14 +2481,14 @@ + } + + % We *must* turn on hyphenation at `-' and `_' in @code. ++% (But see \codedashfinish below.) + % Otherwise, it is too hard to avoid overfull hboxes + % in the Emacs manual, the Library manual, etc. +- ++% + % Unfortunately, TeX uses one parameter (\hyphenchar) to control + % both hyphenation at - and hyphenation within words. + % We must therefore turn them both off (\tclose does that) +-% and arrange explicitly to hyphenate at a dash. +-% -- rms. ++% and arrange explicitly to hyphenate at a dash. -- rms. + { + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active +@@ -2501,17 +2502,38 @@ + \let-\codedash + \let_\codeunder + \else +- \let-\realdash ++ \let-\normaldash + \let_\realunder + \fi ++ % Given -foo (with a single dash), we do not want to allow a break ++ % after the hyphen. ++ \global\let\codedashprev=\codedash ++ % + \codex + } ++ % ++ \gdef\codedash{\futurelet\next\codedashfinish} ++ \gdef\codedashfinish{% ++ \normaldash % always output the dash character itself. ++ % ++ % Now, output a discretionary to allow a line break, unless ++ % (a) the next character is a -, or ++ % (b) the preceding character is a -. ++ % E.g., given --posix, we do not want to allow a break after either -. ++ % Given --foo-bar, we do want to allow a break between the - and the b. ++ \ifx\next\codedash \else ++ \ifx\codedashprev\codedash ++ \else \discretionary{}{}{}\fi ++ \fi ++ % we need the space after the = for the case when \next itself is a ++ % space token; it would get swallowed otherwise. As in @code{- a}. ++ \global\let\codedashprev= \next ++ } + } +- ++\def\normaldash{-} ++% + \def\codex #1{\tclose{#1}\endgroup} + +-\def\realdash{-} +-\def\codedash{-\discretionary{}{}{}} + \def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) +@@ -2525,9 +2547,9 @@ + } + + % An additional complication: the above will allow breaks after, e.g., +-% each of the four underscores in __typeof__. This is undesirable in +-% some manuals, especially if they don't have long identifiers in +-% general. @allowcodebreaks provides a way to control this. ++% each of the four underscores in __typeof__. This is bad. ++% @allowcodebreaks provides a document-level way to turn breaking at - ++% and _ on and off. + % + \newif\ifallowcodebreaks \allowcodebreakstrue + +@@ -2546,37 +2568,28 @@ + \fi\fi + } + +-% @uref (abbreviation for `urlref') takes an optional (comma-separated) +-% second argument specifying the text to display and an optional third +-% arg as text to display instead of (rather than in addition to) the url +-% itself. First (mandatory) arg is the url. +-% (This \urefnobreak definition isn't used now, leaving it for a while +-% for comparison.) +-\def\urefnobreak#1{\dourefnobreak #1,,,\finish} +-\def\dourefnobreak#1,#2,#3,#4\finish{\begingroup +- \unsepspaces +- \pdfurl{#1}% +- \setbox0 = \hbox{\ignorespaces #3}% +- \ifdim\wd0 > 0pt +- \unhbox0 % third arg given, show only that +- \else +- \setbox0 = \hbox{\ignorespaces #2}% +- \ifdim\wd0 > 0pt +- \ifpdf +- \unhbox0 % PDF: 2nd arg given, show only it +- \else +- \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url +- \fi +- \else +- \code{#1}% only url given, so show it +- \fi +- \fi +- \endlink +-\endgroup} ++% For @command, @env, @file, @option quotes seem unnecessary, ++% so use \code rather than \samp. ++\let\command=\code ++\let\env=\code ++\let\file=\code ++\let\option=\code + +-% This \urefbreak definition is the active one. ++% @uref (abbreviation for `urlref') aka @url takes an optional ++% (comma-separated) second argument specifying the text to display and ++% an optional third arg as text to display instead of (rather than in ++% addition to) the url itself. First (mandatory) arg is the url. ++ ++% TeX-only option to allow changing PDF output to show only the second ++% arg (if given), and not the url (which is then just the link target). ++\newif\ifurefurlonlylink ++ ++% The main macro is \urefbreak, which allows breaking at expected ++% places within the url. (There used to be another version, which ++% didn't support automatic breaking.) + \def\urefbreak{\begingroup \urefcatcodes \dourefbreak} + \let\uref=\urefbreak ++% + \def\dourefbreak#1{\urefbreakfinish #1,,,\finish} + \def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces +@@ -2585,12 +2598,19 @@ + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else +- \setbox0 = \hbox{\ignorespaces #2}% ++ \setbox0 = \hbox{\ignorespaces #2}% look for second arg + \ifdim\wd0 > 0pt + \ifpdf +- \unhbox0 % PDF: 2nd arg given, show only it ++ \ifurefurlonlylink ++ % PDF plus option to not display url, show just arg ++ \unhbox0 ++ \else ++ % PDF, normally display both arg and url for consistency, ++ % visibility, if the pdf is eventually used to print, etc. ++ \unhbox0\ (\urefcode{#1})% ++ \fi + \else +- \unhbox0\ (\urefcode{#1})% DVI: 2nd arg given, show both it and url ++ \unhbox0\ (\urefcode{#1})% DVI, always show arg and url + \fi + \else + \urefcode{#1}% only url given, so show it +@@ -2630,8 +2650,10 @@ + % we put a little stretch before and after the breakable chars, to help + % line breaking of long url's. The unequal skips make look better in + % cmtt at least, especially for dots. +-\def\urefprestretch{\urefprebreak \hskip0pt plus.13em } +-\def\urefpoststretch{\urefpostbreak \hskip0pt plus.1em } ++\def\urefprestretchamount{.13em} ++\def\urefpoststretchamount{.1em} ++\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} ++\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} + % + \def\urefcodeamp{\urefprestretch \&\urefpoststretch} + \def\urefcodedot{\urefprestretch .\urefpoststretch} +@@ -2692,10 +2714,6 @@ + \let\email=\uref + \fi + +-% @kbd is like @code, except that if the argument is just one @key command, +-% then @kbd has no effect. +-\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} +- + % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), + % `example' (@kbd uses ttsl only inside of @example and friends), + % or `code' (@kbd uses normal tty font always). +@@ -2719,16 +2737,36 @@ + % Default is `distinct'. + \kbdinputstyle distinct + ++% @kbd is like @code, except that if the argument is just one @key command, ++% then @kbd has no effect. ++\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} ++ + \def\xkey{\key} +-\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% +-\ifx\one\xkey\ifx\threex\three \key{#2}% +-\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +-\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi} ++\def\kbdsub#1#2#3\par{% ++ \def\one{#1}\def\three{#3}\def\threex{??}% ++ \ifx\one\xkey\ifx\threex\three \key{#2}% ++ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi ++ \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi ++} + +-% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. +-\let\indicateurl=\code +-\let\env=\code +-\let\command=\code ++% definition of @key that produces a lozenge. Doesn't adjust to text size. ++%\setfont\keyrm\rmshape{8}{1000}{OT1} ++%\font\keysy=cmsy9 ++%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% ++% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% ++% \vbox{\hrule\kern-0.4pt ++% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% ++% \kern-0.4pt\hrule}% ++% \kern-.06em\raise0.4pt\hbox{\angleright}}}} ++ ++% definition of @key with no lozenge. If the current font is already ++% monospace, don't change it; that way, we respect @kbdinputstyle. But ++% if it isn't monospace, then use \tt. ++% ++\def\key#1{{\setupmarkupstyle{key}% ++ \nohyphenation ++ \ifmonospace\else\tt\fi ++ #1}\null} + + % @clicksequence{File @click{} Open ...} + \def\clicksequence#1{\begingroup #1\endgroup} +@@ -2836,6 +2874,9 @@ + } + } + ++% ctrl is no longer a Texinfo command, but leave this definition for fun. ++\def\ctrl #1{{\tt \rawbackslash \hat}#1} ++ + % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. + % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, + % except specified as a normal braced arg, so no newlines to worry about. +@@ -2847,6 +2888,15 @@ + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi + } ++% ++% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if ++% FMTNAME is tex, else ELSE-TEXT. ++\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} ++\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% ++ \def\inlinefmtname{#1}% ++ \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi ++} ++% + % For raw, must switch into @tex before parsing the argument, to avoid + % setting catcodes prematurely. Doing it this way means that, for + % example, @inlineraw{html, foo{bar} gets a parse error instead of being +@@ -2863,6 +2913,23 @@ + \endgroup % close group opened by \tex. + } + ++% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. ++% ++\long\def\inlineifset#1{\doinlineifset #1,\finish} ++\long\def\doinlineifset#1,#2,\finish{% ++ \def\inlinevarname{#1}% ++ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax ++ \else\ignorespaces#2\fi ++} ++ ++% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. ++% ++\long\def\inlineifclear#1{\doinlineifclear #1,\finish} ++\long\def\doinlineifclear#1,#2,\finish{% ++ \def\inlinevarname{#1}% ++ \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi ++} ++ + + \message{glyphs,} + % and logos. +@@ -3126,12 +3193,17 @@ + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% +- \ifx\curfontstyle\bfstylename +- % bold: +- \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize +- \else +- % regular: +- \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize ++ \ifmonospace ++ % typewriter: ++ \font\thisecfont = ectt\ecsize \space at \nominalsize ++ \else ++ \ifx\curfontstyle\bfstylename ++ % bold: ++ \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize ++ \else ++ % regular: ++ \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize ++ \fi + \fi + \thisecfont + } +@@ -3244,6 +3316,20 @@ + \finishedtitlepagetrue + } + ++% Settings used for typesetting titles: no hyphenation, no indentation, ++% don't worry much about spacing, ragged right. This should be used ++% inside a \vbox, and fonts need to be set appropriately first. Because ++% it is always used for titles, nothing else, we call \rmisbold. \par ++% should be specified before the end of the \vbox, since a vbox is a group. ++% ++\def\raggedtitlesettings{% ++ \rmisbold ++ \hyphenpenalty=10000 ++ \parindent=0pt ++ \tolerance=5000 ++ \ptexraggedright ++} ++ + % Macros to be used within @titlepage: + + \let\subtitlerm=\tenrm +@@ -3251,7 +3337,7 @@ + + \parseargdef\title{% + \checkenv\titlepage +- \leftline{\titlefonts\rmisbold #1} ++ \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +@@ -3599,7 +3685,7 @@ + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % +- % Try typesetting the item mark that if the document erroneously says ++ % Try typesetting the item mark so that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if +@@ -3850,18 +3936,22 @@ + + % multitable-only commands. + % +-% @headitem starts a heading row, which we typeset in bold. +-% Assignments have to be global since we are inside the implicit group +-% of an alignment entry. \everycr resets \everytab so we don't have to ++% @headitem starts a heading row, which we typeset in bold. Assignments ++% have to be global since we are inside the implicit group of an ++% alignment entry. \everycr below resets \everytab so we don't have to + % undo it ourselves. + \def\headitemfont{\b}% for people to use in the template row; not changeable + \def\headitem{% + \checkenv\multitable + \crcr ++ \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item + }% + % ++% default for tables with no headings. ++\let\headitemcrhook=\relax ++% + % A \tab used to include \hskip1sp. But then the space in a template + % line is not enough. That is bad. So let's go back to just `&' until + % we again encounter the problem the 1sp was intended to solve. +@@ -3892,15 +3982,15 @@ + % + \everycr = {% + \noalign{% +- \global\everytab={}% ++ \global\everytab={}% Reset from possible headitem. + \global\colcount=0 % Reset the column counter. +- % Check for saved footnotes, etc. ++ % ++ % Check for saved footnotes, etc.: + \checkinserts +- % Keeps underfull box messages off when table breaks over pages. +- %\filbreak +- % Maybe so, but it also creates really weird page breaks when the +- % table breaks over pages. Wouldn't \vfil be better? Wait until the +- % problem manifests itself, so it can be fixed for real --karl. ++ % ++ % Perhaps a \nobreak, then reset: ++ \headitemcrhook ++ \global\let\headitemcrhook=\relax + }% + }% + % +@@ -4139,7 +4229,7 @@ + \def\value{\begingroup\makevalueexpandable\valuexxx} + \def\valuexxx#1{\expandablevalue{#1}\endgroup} + { +- \catcode`\- = \active \catcode`\_ = \active ++ \catcode`\-=\active \catcode`\_=\active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue +@@ -4148,7 +4238,7 @@ + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. +- \let-\realdash \let_\normalunderscore ++ \let-\normaldash \let_\normalunderscore + } + } + +@@ -4160,6 +4250,11 @@ + % it will fail (although perhaps we could fix that with sufficient work + % to do a one-level expansion on the result, instead of complete). + % ++% Unfortunately, this has the consequence that when _ is in the *value* ++% of an @set, it does not print properly in the roman fonts (get the cmr ++% dot accent at position 126 instead). No fix comes to mind, and it's ++% been this way since 2003 or earlier, so just ignore it. ++% + \def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% +@@ -4172,7 +4267,8 @@ + % @ifset VAR ... @end ifset reads the `...' iff VAR has been defined + % with @set. + % +-% To get special treatment of `@end ifset,' call \makeond and the redefine. ++% To get the special treatment we need for `@end ifset,' we call ++% \makecond and then redefine. + % + \makecond{ifset} + \def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +@@ -4188,7 +4284,7 @@ + } + \def\ifsetfail{\doignore{ifset}} + +-% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been ++% @ifclear VAR ... @end executes the `...' iff VAR has never been + % defined with @set, or has been undefined with @clear. + % + % The `\else' inside the `\doifset' parameter is a trick to reuse the +@@ -4199,6 +4295,35 @@ + \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} + \def\ifclearfail{\doignore{ifclear}} + ++% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written ++% without the @) is in fact defined. We can only feasibly check at the ++% TeX level, so something like `mathcode' is going to considered ++% defined even though it is not a Texinfo command. ++% ++\makecond{ifcommanddefined} ++\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} ++% ++\def\doifcmddefined#1#2{{% ++ \makevalueexpandable ++ \let\next=\empty ++ \expandafter\ifx\csname #2\endcsname\relax ++ #1% If not defined, \let\next as above. ++ \fi ++ \expandafter ++ }\next ++} ++\def\ifcmddefinedfail{\doignore{ifcommanddefined}} ++ ++% @ifcommandnotdefined CMD ... handled similar to @ifclear above. ++\makecond{ifcommandnotdefined} ++\def\ifcommandnotdefined{% ++ \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} ++\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} ++ ++% Set the `txicommandconditionals' variable, so documents have a way to ++% test if the @ifcommand...defined conditionals are available. ++\set txicommandconditionals ++ + % @dircategory CATEGORY -- specify a category of the dir file + % which this file should belong to. Ignore this in TeX. + \let\dircategory=\comment +@@ -4307,7 +4432,7 @@ + % complicated, when \tex is in effect and \{ is a \delimiter again. + % We can't use \lbracecmd and \rbracecmd because texindex assumes + % braces and backslashes are used only as delimiters. Perhaps we +- % should define @lbrace and @rbrace commands a la @comma. ++ % should use @lbracechar and @rbracechar? + \def\{{{\tt\char123}}% + \def\}{{\tt\char125}}% + % +@@ -4328,8 +4453,7 @@ + % @end macro + % ... + % @funindex commtest +- % +- % The above is not enough to reproduce the bug, but it gives the flavor. ++ % This is not enough to reproduce the bug, but it gives the flavor. + % + % Sample whatsit resulting: + % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} +@@ -4435,6 +4559,7 @@ + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright ++ \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\minus + \definedummyword\ogonek +@@ -4447,6 +4572,7 @@ + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase ++ \definedummyword\rbracechar + \definedummyword\result + \definedummyword\textdegree + % +@@ -4498,6 +4624,7 @@ + \definedummyword\t + % + % Commands that take arguments. ++ \definedummyword\abbr + \definedummyword\acronym + \definedummyword\anchor + \definedummyword\cite +@@ -4509,7 +4636,9 @@ + \definedummyword\emph + \definedummyword\env + \definedummyword\file ++ \definedummyword\image + \definedummyword\indicateurl ++ \definedummyword\inforef + \definedummyword\kbd + \definedummyword\key + \definedummyword\math +@@ -4525,8 +4654,21 @@ + \definedummyword\verb + \definedummyword\w + \definedummyword\xref ++ % ++ % Consider: ++ % @macro mkind{arg1,arg2} ++ % @cindex \arg2\ ++ % @end macro ++ % @mkind{foo, bar} ++ % The space after the comma will end up in the temporary definition ++ % that we make for arg2 (see \parsemargdef ff.). We want all this to be ++ % expanded for the sake of the index, so we end up just seeing "bar". ++ \let\xeatspaces = \eatspaces + } + ++% For testing: output @{ and @} in index sort strings as \{ and \}. ++\newif\ifusebracesinindexes ++ + % \indexnofonts is used when outputting the strings to sort the index + % by, and when constructing control sequence names. It eliminates all + % control sequences and just writes whatever the best ASCII sort string +@@ -4555,8 +4697,16 @@ + % Unfortunately, texindex is not prepared to handle braces in the + % content at all. So for index sorting, we map @{ and @} to strings + % starting with |, since that ASCII character is between ASCII { and }. +- \def\{{|a}% +- \def\}{|b}% ++ \ifusebracesinindexes ++ \def\lbracechar{\lbracecmd}% ++ \def\rbracechar{\rbracecmd}% ++ \else ++ \def\lbracechar{|a}% ++ \def\rbracechar{|b}% ++ \fi ++ \let\{=\lbracechar ++ \let\}=\rbracechar ++ % + % + % Non-English letters. + \def\AA{AA}% +@@ -4732,10 +4882,9 @@ + % + % ..., ready, GO: + % +-\def\safewhatsit#1{% +-\ifhmode ++\def\safewhatsit#1{\ifhmode + #1% +-\else ++ \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% +@@ -4759,7 +4908,6 @@ + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: +- % + % @deffn deffn-whatever + % @vindex index-whatever + % Description. +@@ -4772,8 +4920,7 @@ + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +-\fi +-} ++\fi} + + % The index entry written in the file actually looks like + % \entry {sortstring}{page}{topic} +@@ -5520,14 +5667,6 @@ + + % Define @majorheading, @heading and @subheading + +-% NOTE on use of \vbox for chapter headings, section headings, and such: +-% 1) We use \vbox rather than the earlier \line to permit +-% overlong headings to fold. +-% 2) \hyphenpenalty is set to 10000 because hyphenation in a +-% heading is obnoxious; this forbids it. +-% 3) Likewise, headings look best if no \parindent is used, and +-% if justification is not attempted. Hence \raggedright. +- + \def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +@@ -5535,10 +5674,8 @@ + + \def\chapheading{\chapbreak \parsearg\chapheadingzzz} + \def\chapheadingzzz#1{% +- {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 +- \parindent=0pt\ptexraggedright +- \rmisbold #1\hfill}}% +- \bigskip \par\penalty 200\relax ++ \vbox{\chapfonts \raggedtitlesettings #1\par}% ++ \nobreak\bigskip \nobreak + \suppressfirstparagraphindent + } + +@@ -5697,8 +5834,7 @@ + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. +- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright +- \hangindent=\wd0 \centerparametersmaybe ++ \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title +@@ -5720,18 +5856,18 @@ + \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} + % + \def\unnchfopen #1{% +-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 +- \parindent=0pt\ptexraggedright +- \rmisbold #1\hfill}}\bigskip \par\nobreak ++ \chapoddpage ++ \vbox{\chapfonts \raggedtitlesettings #1\par}% ++ \nobreak\bigskip\nobreak + } + \def\chfopen #1#2{\chapoddpage {\chapfonts + \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% + \par\penalty 5000 % + } + \def\centerchfopen #1{% +-\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 +- \parindent=0pt +- \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak ++ \chapoddpage ++ \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% ++ \nobreak\bigskip \nobreak + } + \def\CHAPFopen{% + \global\let\chapmacro=\chfopen +@@ -5822,7 +5958,7 @@ + % + % Now the second mark, after the heading break. No break points + % between here and the heading. +- \let\prevsectiondefs=\lastsectiondefs ++ \global\let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. +@@ -5876,14 +6012,15 @@ + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a +- % discardable item.) ++ % discardable item.) However, when a paragraph is not started next ++ % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out ++ % or the negative glue will cause weirdly wrong output, typically ++ % obscuring the section heading with something else. + \vskip-\parskip + % +- % This is purely so the last item on the list is a known \penalty > +- % 10000. This is so \startdefun can avoid allowing breakpoints after +- % section headings. Otherwise, it would insert a valid breakpoint between: +- % @section sec-whatever +- % @deffn def-whatever ++ % This is so the last item on the main vertical list is a known ++ % \penalty > 10000, so \startdefun, etc., can recognize the situation ++ % and do the needful. + \penalty 10001 + } + +@@ -6188,8 +6325,8 @@ + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other +- \catcode`\`=\other +- \catcode`\'=\other ++ \catcode `\`=\other ++ \catcode `\'=\other + \escapechar=`\\ + % + % ' is active in math mode (mathcode"8000). So reset it, and all our +@@ -6213,7 +6350,7 @@ + \let\/=\ptexslash + \let\*=\ptexstar + \let\t=\ptext +- \expandafter \let\csname top\endcsname=\ptextop % outer ++ \expandafter \let\csname top\endcsname=\ptextop % we've made it outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% +@@ -6297,13 +6434,11 @@ + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip +- % Flag to tell @lisp, etc., not to narrow margin. +- \let\nonarrowing = t% + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. +- \ifnum\lastpenalty>10000 \vskip\parskip \fi ++ \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt +@@ -6338,7 +6473,7 @@ + \newdimen\nonfillparindent + \def\nonfillstart{% + \aboveenvbreak +- \hfuzz = 12pt % Don't be fussy ++ \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output +@@ -6465,9 +6600,13 @@ + + + % @raggedright does more-or-less normal line breaking but no right +-% justification. From plain.tex. ++% justification. From plain.tex. Don't stretch around special ++% characters in urls in this environment, since the stretch at the right ++% should be enough. + \envdef\raggedright{% +- \rightskip0pt plus2em \spaceskip.3333em \xspaceskip.5em\relax ++ \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax ++ \def\urefprestretchamount{0pt}% ++ \def\urefpoststretchamount{0pt}% + } + \let\Eraggedright\par + +@@ -6496,16 +6635,9 @@ + \makedispenvdef{quotation}{\quotationstart} + % + \def\quotationstart{% +- {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip +- \parindent=0pt +- % +- % @cartouche defines \nonarrowing to inhibit narrowing at next level down. ++ \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax +- \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing +- \exdentamount = \lispnarrowing +- \else +- \let\nonarrowing = \relax + \fi + \parsearg\quotationlabel + } +@@ -6531,6 +6663,32 @@ + \fi + } + ++% @indentedblock is like @quotation, but indents only on the left and ++% has no optional argument. ++% ++\makedispenvdef{indentedblock}{\indentedblockstart} ++% ++\def\indentedblockstart{% ++ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip ++ \parindent=0pt ++ % ++ % @cartouche defines \nonarrowing to inhibit narrowing at next level down. ++ \ifx\nonarrowing\relax ++ \advance\leftskip by \lispnarrowing ++ \exdentamount = \lispnarrowing ++ \else ++ \let\nonarrowing = \relax ++ \fi ++} ++ ++% Keep a nonzero parskip for the environment, since we're doing normal filling. ++% ++\def\Eindentedblock{% ++ \par ++ {\parskip=0pt \afterenvbreak}% ++} ++\def\Esmallindentedblock{\Eindentedblock} ++ + + % LaTeX-like @verbatim...@end verbatim and @verb{...} + % If we want to allow any as delimiter, +@@ -7009,7 +7167,10 @@ + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we +- % want a way to get ttsl. Let's try @var for that. ++ % want a way to get ttsl. We used to recommend @var for that, so ++ % leave the code in, but it's strange for @var to lead to typewriter. ++ % Nowadays we recommend @code, since the difference between a ttsl hyphen ++ % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 +@@ -7338,7 +7499,7 @@ + + % Parse the optional {params} list. Set up \paramno and \paramlist + % so \defmacro knows what to do. Define \macarg.BLAH for each BLAH +-% in the params list to some hook where the argument si to be expanded. If ++% in the params list to some hook where the argument is to be expanded. If + % there are less than 10 arguments that hook is to be replaced by ##N where N + % is the position in that list, that is to say the macro arguments are to be + % defined `a la TeX in the macro body. +@@ -7793,7 +7954,7 @@ + \fi\fi + } + +- ++% + % @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is + % the node name, #2 the name of the Info cross-reference, #3 the printed + % node name, #4 the name of the Info file, #5 the name of the printed +@@ -7803,16 +7964,21 @@ + \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} + \def\ref#1{\xrefX[#1,,,,,,,]} + % +-\newbox\topbox ++\newbox\toprefbox + \newbox\printedrefnamebox ++\newbox\infofilenamebox + \newbox\printedmanualbox + % + \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % ++ % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % ++ \def\infofilename{\ignorespaces #4}% ++ \setbox\infofilenamebox = \hbox{\infofilename\unskip}% ++ % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % +@@ -7845,12 +8011,20 @@ + \ifpdf + {\indexnofonts + \turnoffactive ++ \makevalueexpandable + % This expands tokens, so do it after making catcode changes, so _ +- % etc. don't get their TeX definitions. ++ % etc. don't get their TeX definitions. This ignores all spaces in ++ % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % ++ % This (wrongly) does not take account of leading or trailing ++ % spaces in #1, which should be ignored. + \edef\pdfxrefdest{#1}% +- \txiescapepdf\pdfxrefdest ++ \ifx\pdfxrefdest\empty ++ \def\pdfxrefdest{Top}% no empty targets ++ \else ++ \txiescapepdf\pdfxrefdest % escape PDF special chars ++ \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% +@@ -7883,7 +8057,7 @@ + \printedrefname + \fi + % +- % if the user also gave the printed manual name (fifth arg), append ++ % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% +@@ -7898,32 +8072,20 @@ + % this is a loss. Therefore, we give the text of the node name + % again, so it is as if TeX is seeing it for the first time. + % +- % Cross-manual reference. Only include the "Section ``foo'' in" if +- % the foo is neither missing or Top. Thus, @xref{,,,foo,The Foo Manual} +- % outputs simply "see The Foo Manual". + \ifdim \wd\printedmanualbox > 0pt +- % What is the 7sp about? The idea is that we also want to omit +- % the Section part if we would be printing "Top", since they are +- % clearly trying to refer to the whole manual. But, this being +- % TeX, we can't easily compare strings while ignoring the possible +- % spaces before and after in the input. By adding the arbitrary +- % 7sp, we make it much less likely that a real node name would +- % happen to have the same width as "Top" (e.g., in a monospaced font). +- % I hope it will never happen in practice. ++ % Cross-manual reference with a printed manual name. + % +- % For the same basic reason, we retypeset the "Top" at every +- % reference, since the current font is indeterminate. ++ \crossmanualxref{\cite{\printedmanual\unskip}}% ++ % ++ \else\ifdim \wd\infofilenamebox > 0pt ++ % Cross-manual reference with only an info filename (arg 4), no ++ % printed manual name (arg 5). This is essentially the same as ++ % the case above; we output the filename, since we have nothing else. + % +- \setbox\topbox = \hbox{Top\kern7sp}% +- \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% +- \ifdim \wd2 > 7sp +- \ifdim \wd2 = \wd\topbox \else +- \putwordSection{} ``\printedrefname'' \putwordin{}\space +- \fi +- \fi +- \cite{\printedmanual}% ++ \crossmanualxref{\code{\infofilename\unskip}}% ++ % + \else +- % Reference in this manual. ++ % Reference within this manual. + % + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand +@@ -7944,11 +8106,37 @@ + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% +- \fi ++ \fi\fi + \fi + \endlink + \endgroup} + ++% Output a cross-manual xref to #1. Used just above (twice). ++% ++% Only include the text "Section ``foo'' in" if the foo is neither ++% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply ++% "see The Foo Manual", the idea being to refer to the whole manual. ++% ++% But, this being TeX, we can't easily compare our node name against the ++% string "Top" while ignoring the possible spaces before and after in ++% the input. By adding the arbitrary 7sp below, we make it much less ++% likely that a real node name would have the same width as "Top" (e.g., ++% in a monospaced font). Hopefully it will never happen in practice. ++% ++% For the same basic reason, we retypeset the "Top" at every ++% reference, since the current font is indeterminate. ++% ++\def\crossmanualxref#1{% ++ \setbox\toprefbox = \hbox{Top\kern7sp}% ++ \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% ++ \ifdim \wd2 > 7sp % nonempty? ++ \ifdim \wd2 = \wd\toprefbox \else % same as Top? ++ \putwordSection{} ``\printedrefname'' \putwordin{}\space ++ \fi ++ \fi ++ #1% ++} ++ + % This macro is called from \xrefX for the `[nodename]' part of xref + % output. It's a separate macro only so it can be changed more easily, + % since square brackets don't work well in some documents. Particularly +@@ -8173,6 +8361,7 @@ + \gdef\footnote{% + \let\indent=\ptexindent + \let\noindent=\ptexnoindent ++ % + \global\advance\footnoteno by \@ne + \edef\thisfootno{$^{\the\footnoteno}$}% + % +@@ -8196,6 +8385,11 @@ + % + \gdef\dofootnote{% + \insert\footins\bgroup ++ % ++ % Nested footnotes are not supported in TeX, that would take a lot ++ % more work. (\startsavinginserts does not suffice.) ++ \let\footnote=\errfootnote ++ % + % We want to typeset this text as a normal paragraph, even if the + % footnote reference occurs in (for example) a display environment. + % So reset some parameters. +@@ -8233,13 +8427,19 @@ + } + }%end \catcode `\@=11 + ++\def\errfootnote{% ++ \errhelp=\EMsimple ++ \errmessage{Nested footnotes not supported in texinfo.tex, ++ even though they work in makeinfo; sorry} ++} ++ + % In case a @footnote appears in a vbox, save the footnote text and create + % the real \insert just after the vbox finished. Otherwise, the insertion + % would be lost. + % Similarly, if a @footnote appears inside an alignment, save the footnote + % text to a box and make the \insert when a row of the table is finished. + % And the same can be done for other insert classes. --kasal, 16nov03. +- ++% + % Replace the \insert primitive by a cheating macro. + % Deeper inside, just make sure that the saved insertions are not spilled + % out prematurely. +@@ -8316,7 +8516,7 @@ + it from ftp://tug.org/tex/epsf.tex.} + % + \def\image#1{% +- \ifx\epsfbox\thisiundefined ++ \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% +@@ -8340,6 +8540,13 @@ + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue ++ \else \ifx\centersub\centerV ++ % for @center @image, we need a vbox so we can have our vertical space ++ \imagevmodetrue ++ \vbox\bgroup % vbox has better behavior than vtop herev ++ \fi\fi ++ % ++ \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space +@@ -8349,9 +8556,13 @@ + \fi + % + % Leave vertical mode so that indentation from an enclosing +- % environment such as @quotation is respected. On the other hand, if +- % it's at the top level, we don't want the normal paragraph indentation. +- \noindent ++ % environment such as @quotation is respected. ++ % However, if we're at the top level, we don't want the ++ % normal paragraph indentation. ++ % On the other hand, if we are in the case of @center @image, we don't ++ % want to start a paragraph, which will create a hsize-width box and ++ % eradicate the centering. ++ \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf +@@ -8363,7 +8574,10 @@ + \epsfbox{#1.eps}% + \fi + % +- \ifimagevmode \medskip \fi % space after the standalone image ++ \ifimagevmode ++ \medskip % space after a standalone image ++ \fi ++ \ifx\centersub\centerV \egroup \fi + \endgroup} + + +@@ -9793,11 +10007,9 @@ + \catcode`\"=\active + \def\activedoublequote{{\tt\char34}} + \let"=\activedoublequote +-\catcode`\~=\active +-\def~{{\tt\char126}} ++\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde + \chardef\hat=`\^ +-\catcode`\^=\active +-\def^{{\tt \hat}} ++\catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat + + \catcode`\_=\active + \def_{\ifusingtt\normalunderscore\_} +@@ -9807,16 +10019,26 @@ + + \catcode`\|=\active + \def|{{\tt\char124}} ++ + \chardef \less=`\< +-\catcode`\<=\active +-\def<{{\tt \less}} ++\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless + \chardef \gtr=`\> +-\catcode`\>=\active +-\def>{{\tt \gtr}} +-\catcode`\+=\active +-\def+{{\tt \char 43}} +-\catcode`\$=\active +-\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix ++\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr ++\catcode`\+=\active \def+{{\tt \char 43}} ++\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix ++ ++% used for headline/footline in the output routine, in case the page ++% breaks in the middle of an @tex block. ++\def\texinfochars{% ++ \let< = \activeless ++ \let> = \activegtr ++ \let~ = \activetilde ++ \let^ = \activehat ++ \markupsetuplqdefault \markupsetuprqdefault ++ \let\b = \strong ++ \let\i = \smartitalic ++ % in principle, all other definitions in \tex have to be undone too. ++} + + % If a .fmt file is being used, characters that might appear in a file + % name cannot be active until we have parsed the command line. +@@ -9866,22 +10088,26 @@ + @gdef@otherbackslash{@let\=@realbackslash} + + % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +-% the literal character `\'. ++% the literal character `\'. Also revert - to its normal character, in ++% case the active - from code has slipped in. + % +-@def@normalturnoffactive{% +- @let"=@normaldoublequote +- @let$=@normaldollar %$ font-lock fix +- @let+=@normalplus +- @let<=@normalless +- @let>=@normalgreater +- @let\=@normalbackslash +- @let^=@normalcaret +- @let_=@normalunderscore +- @let|=@normalverticalbar +- @let~=@normaltilde +- @markupsetuplqdefault +- @markupsetuprqdefault +- @unsepspaces ++{@catcode`- = @active ++ @gdef@normalturnoffactive{% ++ @let-=@normaldash ++ @let"=@normaldoublequote ++ @let$=@normaldollar %$ font-lock fix ++ @let+=@normalplus ++ @let<=@normalless ++ @let>=@normalgreater ++ @let\=@normalbackslash ++ @let^=@normalcaret ++ @let_=@normalunderscore ++ @let|=@normalverticalbar ++ @let~=@normaltilde ++ @markupsetuplqdefault ++ @markupsetuprqdefault ++ @unsepspaces ++ } + } + + % Make _ and + \other characters, temporarily. +diff -urN glibc-2.17-c758a686/manual/threads.texi glibc-2.17-c758a686/manual/threads.texi +--- glibc-2.17-c758a686/manual/threads.texi 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/manual/threads.texi 2014-09-12 16:10:06.042792724 -0400 +@@ -0,0 +1,254 @@ ++@node POSIX Threads ++@c @node POSIX Threads, Internal Probes, Cryptographic Functions, Top ++@chapter POSIX Threads ++@c %MENU% POSIX Threads ++@cindex pthreads ++ ++This chapter describes the @glibcadj{} POSIX Thread implementation. ++ ++@menu ++* Thread-specific Data:: Support for creating and ++ managing thread-specific data ++* Non-POSIX Extensions:: Additional functions to extend ++ POSIX Thread functionality ++@end menu ++ ++@node Thread-specific Data ++@section Thread-specific Data ++ ++The @glibcadj{} implements functions to allow users to create and manage ++data specific to a thread. Such data may be destroyed at thread exit, ++if a destructor is provided. The following functions are defined: ++ ++@comment pthread.h ++@comment POSIX ++@deftypefun int pthread_key_create (pthread_key_t *@var{key}, void (*@var{destructor})(void*)) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c pthread_key_create ok ++@c KEY_UNUSED ok ++@c KEY_USABLE ok ++Create a thread-specific data key for the calling thread, referenced by ++@var{key}. ++ ++Objects declared with the C++11 @code{thread_local} keyword are destroyed ++before thread-specific data, so they should not be used in thread-specific ++data destructors or even as members of the thread-specific data, since the ++latter is passed as an argument to the destructor function. ++@end deftypefun ++ ++@comment pthread.h ++@comment POSIX ++@deftypefun int pthread_key_delete (pthread_key_t @var{key}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c pthread_key_delete ok ++@c This uses atomic compare and exchange to increment the seq number ++@c after testing it's not a KEY_UNUSED seq number. ++@c KEY_UNUSED dup ok ++Destroy the thread-specific data @var{key} in the calling thread. The ++destructor for the thread-specific data is not called during destruction, nor ++is it called during thread exit. ++@end deftypefun ++ ++@comment pthread.h ++@comment POSIX ++@deftypefun void *pthread_getspecific (pthread_key_t @var{key}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c pthread_getspecific ok ++Return the thread-specific data associated with @var{key} in the calling ++thread. ++@end deftypefun ++ ++@comment pthread.h ++@comment POSIX ++@deftypefun int pthread_setspecific (pthread_key_t @var{key}, const void *@var{value}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @ascuheap{}}@acunsafe{@acucorrupt{} @acsmem{}}} ++@c pthread_setspecific @asucorrupt @ascuheap @acucorrupt @acsmem ++@c a level2 block may be allocated by a signal handler after ++@c another call already made a decision to allocate it, thus losing ++@c the allocated value. the seq number is updated before the ++@c value, which might cause an earlier-generation value to seem ++@c current if setspecific is cancelled or interrupted by a signal ++@c KEY_UNUSED ok ++@c calloc dup @ascuheap @acsmem ++Associate the thread-specific @var{value} with @var{key} in the calling thread. ++@end deftypefun ++ ++ ++@node Non-POSIX Extensions ++@section Non-POSIX Extensions ++ ++In addition to implementing the POSIX API for threads, @theglibc{} provides ++additional functions and interfaces to provide functionality not specified in ++the standard. ++ ++@menu ++* Default Thread Attributes:: Setting default attributes for ++ threads in a process. ++@end menu ++ ++@node Default Thread Attributes ++@subsection Setting Process-wide defaults for thread attributes ++ ++@Theglibc{} provides non-standard API functions to set and get the default ++attributes used in the creation of threads in a process. ++ ++@comment pthread.h ++@comment GNU ++@deftypefun int pthread_getattr_default_np (pthread_attr_t *@var{attr}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c Takes lock around read from default_pthread_attr. ++Get the default attribute values and set @var{attr} to match. This ++function returns @math{0} on success and a non-zero error code on ++failure. ++@end deftypefun ++ ++@comment pthread.h ++@comment GNU ++@deftypefun int pthread_setattr_default_np (pthread_attr_t *@var{attr}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{}}} ++@c pthread_setattr_default_np @ascuheap @asulock @aculock @acsmem ++@c check_sched_policy_attr ok ++@c check_sched_priority_attr ok ++@c sched_get_priority_min dup ok ++@c sched_get_priority_max dup ok ++@c check_cpuset_attr ok ++@c determine_cpumask_size ok ++@c check_stacksize_attr ok ++@c lll_lock @asulock @aculock ++@c free dup @ascuheap @acsmem ++@c realloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c lll_unlock @asulock @aculock ++Set the default attribute values to match the values in @var{attr}. The ++function returns @math{0} on success and a non-zero error code on failure. ++The following error codes are defined for this function: ++ ++@table @code ++@item EINVAL ++At least one of the values in @var{attr} does not qualify as valid for the ++attributes or the stack address is set in the attribute. ++@item ENOMEM ++The system does not have sufficient memory. ++@end table ++@end deftypefun ++ ++@c FIXME these are undocumented: ++@c pthread_atfork ++@c pthread_attr_destroy ++@c pthread_attr_getaffinity_np ++@c pthread_attr_getdetachstate ++@c pthread_attr_getguardsize ++@c pthread_attr_getinheritsched ++@c pthread_attr_getschedparam ++@c pthread_attr_getschedpolicy ++@c pthread_attr_getscope ++@c pthread_attr_getstack ++@c pthread_attr_getstackaddr ++@c pthread_attr_getstacksize ++@c pthread_attr_init ++@c pthread_attr_setaffinity_np ++@c pthread_attr_setdetachstate ++@c pthread_attr_setguardsize ++@c pthread_attr_setinheritsched ++@c pthread_attr_setschedparam ++@c pthread_attr_setschedpolicy ++@c pthread_attr_setscope ++@c pthread_attr_setstack ++@c pthread_attr_setstackaddr ++@c pthread_attr_setstacksize ++@c pthread_barrierattr_destroy ++@c pthread_barrierattr_getpshared ++@c pthread_barrierattr_init ++@c pthread_barrierattr_setpshared ++@c pthread_barrier_destroy ++@c pthread_barrier_init ++@c pthread_barrier_wait ++@c pthread_cancel ++@c pthread_cleanup_push ++@c pthread_cleanup_pop ++@c pthread_condattr_destroy ++@c pthread_condattr_getclock ++@c pthread_condattr_getpshared ++@c pthread_condattr_init ++@c pthread_condattr_setclock ++@c pthread_condattr_setpshared ++@c pthread_cond_broadcast ++@c pthread_cond_destroy ++@c pthread_cond_init ++@c pthread_cond_signal ++@c pthread_cond_timedwait ++@c pthread_cond_wait ++@c pthread_create ++@c pthread_detach ++@c pthread_equal ++@c pthread_exit ++@c pthread_getaffinity_np ++@c pthread_getattr_np ++@c pthread_getconcurrency ++@c pthread_getcpuclockid ++@c pthread_getname_np ++@c pthread_getschedparam ++@c pthread_join ++@c pthread_kill ++@c pthread_kill_other_threads_np ++@c pthread_mutexattr_destroy ++@c pthread_mutexattr_getkind_np ++@c pthread_mutexattr_getprioceiling ++@c pthread_mutexattr_getprotocol ++@c pthread_mutexattr_getpshared ++@c pthread_mutexattr_getrobust ++@c pthread_mutexattr_getrobust_np ++@c pthread_mutexattr_gettype ++@c pthread_mutexattr_init ++@c pthread_mutexattr_setkind_np ++@c pthread_mutexattr_setprioceiling ++@c pthread_mutexattr_setprotocol ++@c pthread_mutexattr_setpshared ++@c pthread_mutexattr_setrobust ++@c pthread_mutexattr_setrobust_np ++@c pthread_mutexattr_settype ++@c pthread_mutex_consistent ++@c pthread_mutex_consistent_np ++@c pthread_mutex_destroy ++@c pthread_mutex_getprioceiling ++@c pthread_mutex_init ++@c pthread_mutex_lock ++@c pthread_mutex_setprioceiling ++@c pthread_mutex_timedlock ++@c pthread_mutex_trylock ++@c pthread_mutex_unlock ++@c pthread_once ++@c pthread_rwlockattr_destroy ++@c pthread_rwlockattr_getkind_np ++@c pthread_rwlockattr_getpshared ++@c pthread_rwlockattr_init ++@c pthread_rwlockattr_setkind_np ++@c pthread_rwlockattr_setpshared ++@c pthread_rwlock_destroy ++@c pthread_rwlock_init ++@c pthread_rwlock_rdlock ++@c pthread_rwlock_timedrdlock ++@c pthread_rwlock_timedwrlock ++@c pthread_rwlock_tryrdlock ++@c pthread_rwlock_trywrlock ++@c pthread_rwlock_unlock ++@c pthread_rwlock_wrlock ++@c pthread_self ++@c pthread_setaffinity_np ++@c pthread_setcancelstate ++@c pthread_setcanceltype ++@c pthread_setconcurrency ++@c pthread_setname_np ++@c pthread_setschedparam ++@c pthread_setschedprio ++@c pthread_sigmask ++@c pthread_sigqueue ++@c pthread_spin_destroy ++@c pthread_spin_init ++@c pthread_spin_lock ++@c pthread_spin_trylock ++@c pthread_spin_unlock ++@c pthread_testcancel ++@c pthread_timedjoin_np ++@c pthread_tryjoin_np ++@c pthread_yield +diff -urN glibc-2.17-c758a686/manual/time.texi glibc-2.17-c758a686/manual/time.texi +--- glibc-2.17-c758a686/manual/time.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/time.texi 2014-09-12 16:10:06.044792719 -0400 +@@ -79,6 +79,7 @@ + @comment time.h + @comment ISO + @deftypefun double difftime (time_t @var{time1}, time_t @var{time0}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{difftime} function returns the number of seconds of elapsed + time between calendar time @var{time1} and calendar time @var{time0}, as + a value of type @code{double}. The difference ignores leap seconds +@@ -246,6 +247,12 @@ + @comment time.h + @comment ISO + @deftypefun clock_t clock (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On Hurd, this calls task_info twice and adds user and system time ++@c from both basic and thread time info structs. On generic posix, ++@c calls times and adds utime and stime. On bsd, calls getrusage and ++@c safely converts stime and utime to clock. On linux, calls ++@c clock_gettime. + This function returns the calling process' current CPU time. If the CPU + time is not available or cannot be represented, @code{clock} returns the + value @code{(clock_t)(-1)}. +@@ -310,6 +317,12 @@ + @comment sys/times.h + @comment POSIX.1 + @deftypefun clock_t times (struct tms *@var{buffer}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On HURD, this calls task_info twice, for basic and thread times info, ++@c adding user and system times into tms, and then gettimeofday, to ++@c compute the real time. On BSD, it calls getclktck, getrusage (twice) ++@c and time. On Linux, it's a syscall with special handling to account ++@c for clock_t counts that look like error values. + The @code{times} function stores the processor time information for + the calling process in @var{buffer}. + +@@ -409,6 +422,7 @@ + @comment time.h + @comment ISO + @deftypefun time_t time (time_t *@var{result}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{time} function returns the current calendar time as a value of + type @code{time_t}. If the argument @var{result} is not a null pointer, + the calendar time value is also stored in @code{*@var{result}}. If the +@@ -420,7 +434,9 @@ + @c Linux. + @comment time.h + @comment SVID, XPG +-@deftypefun int stime (time_t *@var{newtime}) ++@deftypefun int stime (const time_t *@var{newtime}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On unix, this is implemented in terms of settimeofday. + @code{stime} sets the system clock, i.e., it tells the system that the + current calendar time is @var{newtime}, where @code{newtime} is + interpreted as described in the above definition of @code{time_t}. +@@ -475,6 +491,12 @@ + @comment sys/time.h + @comment BSD + @deftypefun int gettimeofday (struct timeval *@var{tp}, struct timezone *@var{tzp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On most GNU/Linux systems this is a direct syscall, but the posix/ ++@c implementation (not used on GNU/Linux or GNU/Hurd) relies on time and ++@c localtime_r, saving and restoring tzname in an unsafe manner. ++@c On some GNU/Linux variants, ifunc resolvers are used in shared libc ++@c for vdso resolution. ifunc-vdso-revisit. + The @code{gettimeofday} function returns the current calendar time as + the elapsed time since the epoch in the @code{struct timeval} structure + indicated by @var{tp}. (@pxref{Elapsed Time} for a description of +@@ -498,6 +520,9 @@ + @comment sys/time.h + @comment BSD + @deftypefun int settimeofday (const struct timeval *@var{tp}, const struct timezone *@var{tzp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On HURD, it calls host_set_time with a privileged port. On other ++@c unix systems, it's a syscall. + The @code{settimeofday} function sets the current calendar time in the + system clock according to the arguments. As for @code{gettimeofday}, + the calendar time is represented as the elapsed time since the epoch. +@@ -539,6 +564,10 @@ + @comment sys/time.h + @comment BSD + @deftypefun int adjtime (const struct timeval *@var{delta}, struct timeval *@var{olddelta}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On hurd and mach, call host_adjust_time with a privileged port. On ++@c Linux, it's implemented in terms of adjtimex. On other unixen, it's ++@c a syscall. + This function speeds up or slows down the system clock in order to make + a gradual adjustment. This ensures that the calendar time reported by + the system clock is always monotonically increasing, which might not +@@ -577,6 +606,8 @@ + @comment sys/timex.h + @comment GNU + @deftypefun int adjtimex (struct timex *@var{timex}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c It's a syscall, only available on linux. + + @code{adjtimex} is functionally identical to @code{ntp_adjtime}. + @xref{High Accuracy Clock}. +@@ -674,6 +705,10 @@ + @comment time.h + @comment ISO + @deftypefun {struct tm *} localtime (const time_t *@var{time}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c Calls tz_convert with a static buffer. ++@c localtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + The @code{localtime} function converts the simple time pointed to by + @var{time} to broken-down time representation, expressed relative to the + user's specified time zone. +@@ -687,9 +722,8 @@ + as a broken-down time; typically this is because the year cannot fit into + an @code{int}. + +-Calling @code{localtime} has one other effect: it sets the variable +-@code{tzname} with information about the current time zone. @xref{Time +-Zone Functions}. ++Calling @code{localtime} also sets the current time zone as if ++@code{tzset} were called. @xref{Time Zone Functions}. + @end deftypefun + + Using the @code{localtime} function is a big problem in multi-threaded +@@ -699,6 +733,87 @@ + @comment time.h + @comment POSIX.1c + @deftypefun {struct tm *} localtime_r (const time_t *@var{time}, struct tm *@var{resultp}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c localtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c tz_convert(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c tzset_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c always called with tzset_lock held ++@c sets static is_initialized before initialization; ++@c reads and sets old_tz; sets tz_rules. ++@c some of the issues only apply on the first call. ++@c subsequent calls only trigger these when called by localtime; ++@c otherwise, they're ok. ++@c getenv dup @mtsenv ++@c strcmp dup ok ++@c strdup @ascuheap ++@c tzfile_read @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c memcmp dup ok ++@c strstr dup ok ++@c getenv dup @mtsenv ++@c asprintf dup @mtslocale @ascuheap @acsmem ++@c stat64 dup ok ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fileno dup ok ++@c fstat64 dup ok ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c free dup @ascuheap @acsmem ++@c fsetlocking dup ok [no @mtasurace:stream @asulock, exclusive] ++@c fread_unlocked dup ok [no @mtasurace:stream @asucorrupt @acucorrupt] ++@c memcpy dup ok ++@c decode ok ++@c bswap_32 dup ok ++@c fseek dup ok [no @mtasurace:stream @asucorrupt @acucorrupt] ++@c ftello dup ok [no @mtasurace:stream @asucorrupt @acucorrupt] ++@c malloc dup @ascuheap @acsmem ++@c decode64 ok ++@c bswap_64 dup ok ++@c getc_unlocked ok [no @mtasurace:stream @asucorrupt @acucorrupt] ++@c tzstring dup @ascuheap @acsmem ++@c compute_tzname_max dup ok [guarded by tzset_lock] ++@c memset dup ok ++@c update_vars ok [guarded by tzset_lock] ++@c sets daylight, timezone, tzname and tzname_cur_max; ++@c called only with tzset_lock held, unless tzset_parse_tz ++@c (internal, but not static) gets called by users; given the its ++@c double-underscore-prefixed name, this interface violation could ++@c be regarded as undefined behavior. ++@c strlen ok ++@c tzset_parse_tz @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c sscanf dup @mtslocale @ascuheap @acsmem ++@c isalnum dup @mtsenv ++@c tzstring @ascuheap @acsmem ++@c reads and changes tzstring_list without synchronization, but ++@c only called with tzset_lock held (save for interface violations) ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c strcpy dup ok ++@c isdigit dup @mtslocale ++@c compute_offset ok ++@c tzfile_default @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c sets tzname, timezone, types, zone_names, rule_*off, etc; no guards ++@c strlen dup ok ++@c tzfile_read dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c mempcpy dup ok ++@c compute_tzname_max ok [if guarded by tzset_lock] ++@c iterates over zone_names; no guards ++@c free dup @ascuheap @acsmem ++@c strtoul dup @mtslocale ++@c update_vars dup ok ++@c tzfile_compute(use_localtime) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c sets tzname; no guards. with !use_localtime, as in gmtime, it's ok ++@c tzstring dup @acsuheap @acsmem ++@c tzset_parse_tz dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c offtime dup ok ++@c tz_compute dup ok ++@c strcmp dup ok ++@c offtime ok ++@c isleap dup ok ++@c tz_compute ok ++@c compute_change ok ++@c isleap ok ++@c libc_lock_unlock dup @aculock ++ + The @code{localtime_r} function works just like the @code{localtime} + function. It takes a pointer to a variable containing a simple time + and converts it to the broken-down time format. +@@ -715,6 +830,9 @@ + @comment time.h + @comment ISO + @deftypefun {struct tm *} gmtime (const time_t *@var{time}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c gmtime @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c tz_convert dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + This function is similar to @code{localtime}, except that the broken-down + time is expressed as Coordinated Universal Time (UTC) (formerly called + Greenwich Mean Time (GMT)) rather than relative to a local time zone. +@@ -728,6 +846,15 @@ + @comment time.h + @comment POSIX.1c + @deftypefun {struct tm *} gmtime_r (const time_t *@var{time}, struct tm *@var{resultp}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c You'd think tz_convert could avoid some safety issues with ++@c !use_localtime, but no such luck: tzset_internal will always bring ++@c about all possible AS and AC problems when it's first called. ++@c Calling any of localtime,gmtime_r once would run the initialization ++@c and avoid the heap, mem and fd issues in gmtime* in subsequent calls, ++@c but the unsafe locking would remain. ++@c gmtime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c tz_convert(gmtime_r) dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + This function is similar to @code{localtime_r}, except that it converts + just like @code{gmtime} the given time as Coordinated Universal Time. + +@@ -739,30 +866,58 @@ + @comment time.h + @comment ISO + @deftypefun time_t mktime (struct tm *@var{brokentime}) +-The @code{mktime} function is used to convert a broken-down time structure +-to a simple time representation. It also ``normalizes'' the contents of +-the broken-down time structure, by filling in the day of week and day of +-year based on the other date and time components. ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c mktime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c passes a static localtime_offset to mktime_internal; it is read ++@c once, used as an initial guess, and updated at the end, but not ++@c used except as a guess for subsequent calls, so it should be safe. ++@c Even though a compiler might delay the load and perform it multiple ++@c times (bug 16346), there are at least two unconditional uses of the ++@c auto variable in which the first load is stored, separated by a ++@c call to an external function, and a conditional change of the ++@c variable before the external call, so refraining from allocating a ++@c local variable at the first load would be a very bad optimization. ++@c tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c mktime_internal(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c ydhms_diff ok ++@c ranged_convert(localtime_r) @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c *convert = localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c time_t_avg dup ok ++@c guess_time_tm dup ok ++@c ydhms_diff dup ok ++@c time_t_add_ok ok ++@c time_t_avg ok ++@c isdst_differ ok ++@c time_t_int_add_ok ok ++The @code{mktime} function converts a broken-down time structure to a ++simple time representation. It also normalizes the contents of the ++broken-down time structure, and fills in some components based on the ++values of the others. + + The @code{mktime} function ignores the specified contents of the +-@code{tm_wday} and @code{tm_yday} members of the broken-down time ++@code{tm_wday}, @code{tm_yday}, @code{tm_gmtoff}, and @code{tm_zone} ++members of the broken-down time + structure. It uses the values of the other components to determine the + calendar time; it's permissible for these components to have + unnormalized values outside their normal ranges. The last thing that + @code{mktime} does is adjust the components of the @var{brokentime} +-structure (including the @code{tm_wday} and @code{tm_yday}). ++structure, including the members that were initially ignored. + + If the specified broken-down time cannot be represented as a simple time, + @code{mktime} returns a value of @code{(time_t)(-1)} and does not modify + the contents of @var{brokentime}. + +-Calling @code{mktime} also sets the variable @code{tzname} with +-information about the current time zone. @xref{Time Zone Functions}. ++Calling @code{mktime} also sets the current time zone as if ++@code{tzset} were called; @code{mktime} uses this information instead ++of @var{brokentime}'s initial @code{tm_gmtoff} and @code{tm_zone} ++members. @xref{Time Zone Functions}. + @end deftypefun + + @comment time.h + @comment ??? + @deftypefun time_t timelocal (struct tm *@var{brokentime}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c Alias to mktime. + + @code{timelocal} is functionally identical to @code{mktime}, but more + mnemonically named. Note that it is the inverse of the @code{localtime} +@@ -776,6 +931,19 @@ + @comment time.h + @comment ??? + @deftypefun time_t timegm (struct tm *@var{brokentime}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c timegm @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c gmtime_offset triggers the same caveats as localtime_offset in mktime. ++@c although gmtime_r, as called by mktime, might save some issues, ++@c tzset calls tzset_internal with always, which forces ++@c reinitialization, so all issues may arise. ++@c tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c mktime_internal(gmtime_r) @asulock @aculock ++@c ..gmtime_r @asulock @aculock ++@c ... dup ok ++@c tz_convert(!use_localtime) @asulock @aculock ++@c ... dup @asulock @aculock ++@c tzfile_compute(!use_localtime) ok + + @code{timegm} is functionally identical to @code{mktime} except it + always takes the input values to be Coordinated Universal Time (UTC) +@@ -837,6 +1005,8 @@ + @comment sys/timex.h + @comment GNU + @deftypefun int ntp_gettime (struct ntptimeval *@var{tptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Wrapper for adjtimex. + The @code{ntp_gettime} function sets the structure pointed to by + @var{tptr} to current values. The elements of the structure afterwards + contain the values the timer implementation in the kernel assumes. They +@@ -954,6 +1124,8 @@ + @comment sys/timex.h + @comment GNU + @deftypefun int ntp_adjtime (struct timex *@var{tptr}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Alias to adjtimex syscall. + The @code{ntp_adjtime} function sets the structure specified by + @var{tptr} to current values. + +@@ -1008,6 +1180,13 @@ + @comment time.h + @comment ISO + @deftypefun {char *} asctime (const struct tm *@var{brokentime}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:asctime} @mtslocale{}}@asunsafe{}@acsafe{}} ++@c asctime @mtasurace:asctime @mtslocale ++@c Uses a static buffer. ++@c asctime_internal @mtslocale ++@c snprintf dup @mtslocale [no @acsuheap @acsmem] ++@c ab_day_name @mtslocale ++@c ab_month_name @mtslocale + The @code{asctime} function converts the broken-down time value that + @var{brokentime} points to into a string in a standard format: + +@@ -1031,6 +1210,9 @@ + @comment time.h + @comment POSIX.1c + @deftypefun {char *} asctime_r (const struct tm *@var{brokentime}, char *@var{buffer}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@assafe{}@acsafe{}} ++@c asctime_r @mtslocale ++@c asctime_internal dup @mtslocale + This function is similar to @code{asctime} but instead of placing the + result in a static buffer it writes the string in the buffer pointed to + by the parameter @var{buffer}. This buffer should have room +@@ -1045,6 +1227,10 @@ + @comment time.h + @comment ISO + @deftypefun {char *} ctime (const time_t *@var{time}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:tmbuf} @mtasurace{:asctime} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c ctime @mtasurace:tmbuf @mtasurace:asctime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c localtime dup @mtasurace:tmbuf @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c asctime dup @mtasurace:asctime @mtslocale + The @code{ctime} function is similar to @code{asctime}, except that you + specify the calendar time argument as a @code{time_t} simple time value + rather than in broken-down local time format. It is equivalent to +@@ -1053,13 +1239,17 @@ + asctime (localtime (@var{time})) + @end smallexample + +-@code{ctime} sets the variable @code{tzname}, because @code{localtime} +-does so. @xref{Time Zone Functions}. ++Calling @code{ctime} also sets the current time zone as if ++@code{tzset} were called. @xref{Time Zone Functions}. + @end deftypefun + + @comment time.h + @comment POSIX.1c + @deftypefun {char *} ctime_r (const time_t *@var{time}, char *@var{buffer}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c ctime_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c asctime_r dup @mtslocale + This function is similar to @code{ctime}, but places the result in the + string pointed to by @var{buffer}. It is equivalent to (written using + gcc extensions, @pxref{Statement Exprs,,,gcc,Porting and Using gcc}): +@@ -1077,17 +1267,75 @@ + @comment time.h + @comment ISO + @deftypefun size_t strftime (char *@var{s}, size_t @var{size}, const char *@var{template}, const struct tm *@var{brokentime}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c strftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c strftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c strftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c add ok ++@c memset_zero dup ok ++@c memset_space dup ok ++@c strlen dup ok ++@c mbrlen @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd [no @mtasurace:mbstate/!ps] ++@c mbsinit dup ok ++@c cpy ok ++@c add dup ok ++@c memcpy_lowcase ok ++@c TOLOWER ok ++@c tolower_l ok ++@c memcpy_uppcase ok ++@c TOUPPER ok ++@c toupper_l ok ++@c MEMCPY ok ++@c memcpy dup ok ++@c ISDIGIT ok ++@c STRLEN ok ++@c strlen dup ok ++@c strftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c TOUPPER dup ok ++@c nl_get_era_entry @ascuheap @asulock @acsmem @aculock ++@c nl_init_era_entries @ascuheap @asulock @acsmem @aculock ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c memset dup ok ++@c free dup @ascuheap @acsmem ++@c realloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c strchr dup ok ++@c wcschr dup ok ++@c libc_rwlock_unlock dup @asulock @aculock ++@c ERA_DATE_CMP ok ++@c DO_NUMBER ok ++@c DO_NUMBER_SPACEPAD ok ++@c nl_get_alt_digit @ascuheap @asulock @acsmem @aculock ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c nl_init_alt_digit @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c memset dup ok ++@c strchr dup ok ++@c libc_rwlock_unlock dup @aculock ++@c memset_space ok ++@c memset dup ok ++@c memset_zero ok ++@c memset dup ok ++@c mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c iso_week_days ok ++@c isleap ok ++@c tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c tm_diff ok + This function is similar to the @code{sprintf} function (@pxref{Formatted + Input}), but the conversion specifications that can appear in the format + template @var{template} are specialized for printing components of the date + and time @var{brokentime} according to the locale currently specified for +-time conversion (@pxref{Locales}). ++time conversion (@pxref{Locales}) and the current time zone ++(@pxref{Time Zone Functions}). + + Ordinary characters appearing in the @var{template} are copied to the + output string @var{s}; this can include multibyte character sequences. + Conversion specifiers are introduced by a @samp{%} character, followed + by an optional flag which can be one of the following. These flags +-are all GNU extensions. The first three affect only the output of ++are all GNU extensions. The first three affect only the output of + numbers: + + @table @code +@@ -1392,9 +1640,10 @@ + If @var{s} is a null pointer, @code{strftime} does not actually write + anything, but instead returns the number of characters it would have written. + +-According to POSIX.1 every call to @code{strftime} implies a call to +-@code{tzset}. So the contents of the environment variable @code{TZ} +-is examined before any output is produced. ++Calling @code{strftime} also sets the current time zone as if ++@code{tzset} were called; @code{strftime} uses this information ++instead of @var{brokentime}'s @code{tm_gmtoff} and @code{tm_zone} ++members. @xref{Time Zone Functions}. + + For an example of @code{strftime}, see @ref{Time Functions Example}. + @end deftypefun +@@ -1402,6 +1651,53 @@ + @comment time.h + @comment ISO/Amend1 + @deftypefun size_t wcsftime (wchar_t *@var{s}, size_t @var{size}, const wchar_t *@var{template}, const struct tm *@var{brokentime}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@asucorrupt{} @ascuheap{} @asulock{} @ascudlopen{}}@acunsafe{@acucorrupt{} @aculock{} @acsmem{} @acsfd{}}} ++@c wcsftime @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c wcsftime_l @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c wcsftime_internal @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c add ok ++@c memset_zero dup ok ++@c memset_space dup ok ++@c wcslen dup ok ++@c cpy ok ++@c add dup ok ++@c memcpy_lowcase ok ++@c TOLOWER ok ++@c towlower_l dup ok ++@c memcpy_uppcase ok ++@c TOUPPER ok ++@c towupper_l dup ok ++@c MEMCPY ok ++@c wmemcpy dup ok ++@c widen @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c memset dup ok ++@c mbsrtowcs_l @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd [no @mtasurace:mbstate/!ps] ++@c ISDIGIT ok ++@c STRLEN ok ++@c wcslen dup ok ++@c wcsftime_internal dup @mtsenv @mtslocale @asucorrupt @ascuheap @asulock @ascudlopen @acucorrupt @aculock @acsmem @acsfd ++@c TOUPPER dup ok ++@c nl_get_era_entry dup @ascuheap @asulock @acsmem @aculock ++@c DO_NUMBER ok ++@c DO_NUMBER_SPACEPAD ok ++@c nl_get_walt_digit dup @ascuheap @asulock @acsmem @aculock ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c nl_init_alt_digit dup @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c memset dup ok ++@c wcschr dup ok ++@c libc_rwlock_unlock dup @aculock ++@c memset_space ok ++@c wmemset dup ok ++@c memset_zero ok ++@c wmemset dup ok ++@c mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c iso_week_days ok ++@c isleap ok ++@c tzset dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c gmtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c tm_diff ok + The @code{wcsftime} function is equivalent to the @code{strftime} + function with the difference that it operates on wide character + strings. The buffer where the result is stored, pointed to by @var{s}, +@@ -1452,6 +1748,32 @@ + @comment time.h + @comment XPG4 + @deftypefun {char *} strptime (const char *@var{s}, const char *@var{fmt}, struct tm *@var{tp}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c strptime @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c strptime_internal @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c memset dup ok ++@c ISSPACE ok ++@c isspace_l dup ok ++@c match_char ok ++@c match_string ok ++@c strlen dup ok ++@c strncasecmp_l dup ok ++@c strcmp dup ok ++@c recursive @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c strptime_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c get_number ok ++@c ISSPACE dup ok ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c nl_select_era_entry @ascuheap @asulock @acsmem @aculock ++@c nl_init_era_entries dup @ascuheap @asulock @acsmem @aculock ++@c get_alt_number dup @ascuheap @asulock @acsmem @aculock ++@c nl_parse_alt_digit dup @ascuheap @asulock @acsmem @aculock ++@c libc_rwlock_wrlock dup @asulock @aculock ++@c nl_init_alt_digit dup @ascuheap @acsmem ++@c libc_rwlock_unlock dup @aculock ++@c get_number dup ok ++@c day_of_the_week ok ++@c day_of_the_year ok + The @code{strptime} function parses the input string @var{s} according + to the format string @var{fmt} and stores its results in the + structure @var{tp}. +@@ -1865,6 +2187,9 @@ + @comment time.h + @comment Unix98 + @deftypefun {struct tm *} getdate (const char *@var{string}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:getdate} @mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c getdate @mtasurace:getdate @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c getdate_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + The interface to @code{getdate} is the simplest possible for a function + to parse a string and return the value. @var{string} is the input + string and the result is returned in a statically-allocated variable. +@@ -1976,6 +2301,30 @@ + @comment time.h + @comment GNU + @deftypefun int getdate_r (const char *@var{string}, struct tm *@var{tp}) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c getdate_r @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c getenv dup @mtsenv ++@c stat64 dup ok ++@c access dup ok ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking dup ok [no @mtasurace:stream @asulock, exclusive] ++@c isspace dup @mtslocale ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c memcpy dup ok ++@c getline dup @ascuheap @acsmem [no @asucorrupt @aculock @acucorrupt, exclusive] ++@c strptime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c feof_unlocked dup ok ++@c free dup @ascuheap @acsmem ++@c ferror_unlocked dup dup ok ++@c time dup ok ++@c localtime_r dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c first_wday @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c memset dup ok ++@c mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c check_mday ok ++@c mktime dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd + The @code{getdate_r} function is the reentrant counterpart of + @code{getdate}. It does not use the global variable @code{getdate_err} + to signal an error, but instead returns an error code. The same error +@@ -2037,7 +2386,7 @@ + [@code{+}|@code{-}]@var{hh}[@code{:}@var{mm}[@code{:}@var{ss}]]. This + is positive if the local time zone is west of the Prime Meridian and + negative if it is east. The hour must be between @code{0} and +-@code{23}, and the minute and seconds between @code{0} and @code{59}. ++@code{24}, and the minute and seconds between @code{0} and @code{59}. + + For example, here is how we would specify Eastern Standard Time, but + without any Daylight Saving Time alternative: +@@ -2082,17 +2431,51 @@ + + The @var{time} fields specify when, in the local time currently in + effect, the change to the other time occurs. If omitted, the default is +-@code{02:00:00}. +- +-For example, here is how you would specify the Eastern time zone in the +-United States, including the appropriate Daylight Saving Time and its dates +-of applicability. The normal offset from UTC is 5 hours; since this is ++@code{02:00:00}. The hours part of the time fields can range from ++@minus{}167 through 167; this is an extension to POSIX.1, which allows ++only the range 0 through 24. ++ ++Here are some example @code{TZ} values, including the appropriate ++Daylight Saving Time and its dates of applicability. In North ++American Eastern Standard Time (EST) and Eastern Daylight Time (EDT), ++the normal offset from UTC is 5 hours; since this is + west of the prime meridian, the sign is positive. Summer time begins on +-the first Sunday in April at 2:00am, and ends on the last Sunday in October ++March's second Sunday at 2:00am, and ends on November's first Sunday + at 2:00am. + + @smallexample +-EST+5EDT,M4.1.0/2,M10.5.0/2 ++EST+5EDT,M3.2.0/2,M11.1.0/2 ++@end smallexample ++ ++Israel Standard Time (IST) and Israel Daylight Time (IDT) are 2 hours ++ahead of the prime meridian in winter, springing forward an hour on ++March's fourth Thursday at 26:00 (i.e., 02:00 on the first Friday on or ++after March 23), and falling back on October's last Sunday at 02:00. ++ ++@smallexample ++IST-2IDT,M3.4.4/26,M10.5.0 ++@end smallexample ++ ++Western Argentina Summer Time (WARST) is 3 hours behind the prime ++meridian all year. There is a dummy fall-back transition on December ++31 at 25:00 daylight saving time (i.e., 24:00 standard time, ++equivalent to January 1 at 00:00 standard time), and a simultaneous ++spring-forward transition on January 1 at 00:00 standard time, so ++daylight saving time is in effect all year and the initial @code{WART} ++is a placeholder. ++ ++@smallexample ++WART4WARST,J1/0,J365/25 ++@end smallexample ++ ++Western Greenland Time (WGT) and Western Greenland Summer Time (WGST) ++are 3 hours behind UTC in the winter. Its clocks follow the European ++Union rules of springing forward by one hour on March's last Sunday at ++01:00 UTC (@minus{}02:00 local time) and falling back on October's ++last Sunday at 01:00 UTC (@minus{}01:00 local time). ++ ++@smallexample ++WGT3WGST,M3.5.0/-2,M10.5.0/-1 + @end smallexample + + The schedule of Daylight Saving Time in any particular jurisdiction has +@@ -2177,6 +2560,11 @@ + @comment time.h + @comment POSIX.1 + @deftypefun void tzset (void) ++@safety{@prelim{}@mtsafe{@mtsenv{} @mtslocale{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c tzset @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c tzset_internal dup @mtsenv @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_unlock dup @aculock + The @code{tzset} function initializes the @code{tzname} variable from + the value of the @code{TZ} environment variable. It is not usually + necessary for your program to call this function, because it is called +@@ -2314,7 +2702,16 @@ + + @comment sys/time.h + @comment BSD +-@deftypefun int setitimer (int @var{which}, struct itimerval *@var{new}, struct itimerval *@var{old}) ++@deftypefun int setitimer (int @var{which}, const struct itimerval *@var{new}, struct itimerval *@var{old}) ++@safety{@prelim{}@mtsafe{@mtstimer{}}@assafe{}@acsafe{}} ++@c This function is marked with @mtstimer because the same set of timers ++@c is shared by all threads of a process, so calling it in one thread ++@c may interfere with timers set by another thread. This interference ++@c is not regarded as destructive, because the interface specification ++@c makes this overriding while returning the previous value the expected ++@c behavior, and the kernel will serialize concurrent calls so that the ++@c last one prevails, with each call getting the timer information from ++@c the timer installed by the previous call in that serialization. + The @code{setitimer} function sets the timer specified by @var{which} + according to @var{new}. The @var{which} argument can have a value of + @code{ITIMER_REAL}, @code{ITIMER_VIRTUAL}, or @code{ITIMER_PROF}. +@@ -2335,6 +2732,7 @@ + @comment sys/time.h + @comment BSD + @deftypefun int getitimer (int @var{which}, struct itimerval *@var{old}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getitimer} function stores information about the timer specified + by @var{which} in the structure pointed at by @var{old}. + +@@ -2367,6 +2765,8 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {unsigned int} alarm (unsigned int @var{seconds}) ++@safety{@prelim{}@mtsafe{@mtstimer{}}@assafe{}@acsafe{}} ++@c Wrapper for setitimer. + The @code{alarm} function sets the real-time timer to expire in + @var{seconds} seconds. If you want to cancel any existing alarm, you + can do this by calling @code{alarm} with a @var{seconds} argument of +@@ -2426,6 +2826,10 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {unsigned int} sleep (unsigned int @var{seconds}) ++@safety{@prelim{}@mtunsafe{@mtascusig{:SIGCHLD/linux}}@asunsafe{}@acunsafe{}} ++@c On Mach, it uses ports and calls time. On generic posix, it calls ++@c nanosleep. On Linux, it temporarily blocks SIGCHLD, which is MT- and ++@c AS-Unsafe, and in a way that makes it AC-Unsafe (C-unsafe, even!). + The @code{sleep} function waits for @var{seconds} or until a signal + is delivered, whichever happens first. + +@@ -2470,6 +2874,9 @@ + @comment time.h + @comment POSIX.1 + @deftypefun int nanosleep (const struct timespec *@var{requested_time}, struct timespec *@var{remaining}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c On Linux, it's a syscall. On Mach, it calls gettimeofday and uses ++@c ports. + If resolution to seconds is not enough the @code{nanosleep} function can + be used. As the name suggests the sleep interval can be specified in + nanoseconds. The actual elapsed time of the sleep interval might be +diff -urN glibc-2.17-c758a686/manual/tsort.awk glibc-2.17-c758a686/manual/tsort.awk +--- glibc-2.17-c758a686/manual/tsort.awk 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/tsort.awk 2014-09-12 16:10:06.043792722 -0400 +@@ -1,6 +1,6 @@ + #! /usr/bin/awk -f + # Generate topologically sorted list of manual chapters. +-# (C) Copyright 1998, 1999 Free Software Foundation, Inc. ++# Copyright (C) 1998-2014 Free Software Foundation, Inc. + # Written by Ulrich Drepper , 1998. + + BEGIN { +diff -urN glibc-2.17-c758a686/manual/users.texi glibc-2.17-c758a686/manual/users.texi +--- glibc-2.17-c758a686/manual/users.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/users.texi 2014-09-12 16:10:06.043792722 -0400 +@@ -71,7 +71,7 @@ + @cindex group ID + Users are classified in @dfn{groups}. Each user name belongs to one + @dfn{default group} and may also belong to any number of +-@dfn{supplementary groups}. Users who are members of the same group can ++@dfn{supplementary groups}. Users who are members of the same group can + share resources (such as files) that are not accessible to users who are + not a member of that group. Each group has a @dfn{group name} and + @dfn{group ID}. @xref{Group Database}, for how to find information +@@ -221,30 +221,37 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun uid_t getuid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c Atomic syscall, except on hurd, where it takes a lock within a hurd ++@c critical section. + The @code{getuid} function returns the real user ID of the process. + @end deftypefun + + @comment unistd.h + @comment POSIX.1 + @deftypefun gid_t getgid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getgid} function returns the real group ID of the process. + @end deftypefun + + @comment unistd.h + @comment POSIX.1 + @deftypefun uid_t geteuid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{geteuid} function returns the effective user ID of the process. + @end deftypefun + + @comment unistd.h + @comment POSIX.1 + @deftypefun gid_t getegid (void) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getegid} function returns the effective group ID of the process. + @end deftypefun + + @comment unistd.h + @comment POSIX.1 + @deftypefun int getgroups (int @var{count}, gid_t *@var{groups}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + The @code{getgroups} function is used to inquire about the supplementary + group IDs of the process. Up to @var{count} of these group IDs are + stored in the array @var{groups}; the return value from the function is +@@ -291,6 +298,34 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int seteuid (uid_t @var{neweuid}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c seteuid @asulock @aculock ++@c INLINE_SETXID_SYSCALL @asulock @aculock ++@c This may be just a unix syscall, or the ugliness below used by ++@c nptl to propagate the syscall to all cloned processes used to ++@c implement threads. ++@c nptl_setxid @asulock @aculock ++@c while holding the stack_alloc_lock, mark with SETXID_BITMASK all ++@c threads that are not exiting, signal them until no thread remains ++@c marked, clear the marks and run the syscall, then release the lock. ++@c lll_lock @asulock @aculock ++@c list_for_each ok ++@c list_entry ok ++@c setxid_mark_thread ok ++@c if a thread is initializing, wait for it to be cloned. ++@c mark it with SETXID_BITMASK if it's not exiting ++@c setxid_signal_thread ok ++@c if a thread is marked with SETXID_BITMASK, ++@c send it the SIGSETXID signal ++@c setxid_unmark_thread ok ++@c clear SETXID_BITMASK and release the futex if SETXID_BITMASK is ++@c set. ++@c ok ++@c lll_unlock @aculock ++@c ++@c sighandler_setxid ok ++@c issue the syscall, clear SETXID_BITMASK, release the futex, and ++@c wake up the signaller loop if the counter reached zero. + This function sets the effective user ID of a process to @var{neweuid}, + provided that the process is allowed to change its effective user ID. A + privileged process (effective user ID zero) can change its effective +@@ -318,6 +353,9 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int setuid (uid_t @var{newuid}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c setuid @asulock @aculock ++@c INLINE_SETXID_SYSCALL dup @asulock @aculock + If the calling process is privileged, this function sets both the real + and effective user ID of the process to @var{newuid}. It also deletes + the file user ID of the process, if any. @var{newuid} may be any +@@ -334,6 +372,9 @@ + @comment unistd.h + @comment BSD + @deftypefun int setreuid (uid_t @var{ruid}, uid_t @var{euid}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c setreuid @asulock @aculock ++@c INLINE_SETXID_SYSCALL dup @asulock @aculock + This function sets the real user ID of the process to @var{ruid} and the + effective user ID to @var{euid}. If @var{ruid} is @code{-1}, it means + not to change the real user ID; likewise if @var{euid} is @code{-1}, it +@@ -369,6 +410,9 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int setegid (gid_t @var{newgid}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c setegid @asulock @aculock ++@c INLINE_SETXID_SYSCALL dup @asulock @aculock + This function sets the effective group ID of the process to + @var{newgid}, provided that the process is allowed to change its group + ID. Just as with @code{seteuid}, if the process is privileged it may +@@ -388,6 +432,9 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun int setgid (gid_t @var{newgid}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c setgid @asulock @aculock ++@c INLINE_SETXID_SYSCALL dup @asulock @aculock + This function sets both the real and effective group ID of the process + to @var{newgid}, provided that the process is privileged. It also + deletes the file group ID, if any. +@@ -402,6 +449,9 @@ + @comment unistd.h + @comment BSD + @deftypefun int setregid (gid_t @var{rgid}, gid_t @var{egid}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c setregid @asulock @aculock ++@c INLINE_SETXID_SYSCALL dup @asulock @aculock + This function sets the real group ID of the process to @var{rgid} and + the effective group ID to @var{egid}. If @var{rgid} is @code{-1}, it + means not to change the real group ID; likewise if @var{egid} is +@@ -437,7 +487,10 @@ + + @comment grp.h + @comment BSD +-@deftypefun int setgroups (size_t @var{count}, gid_t *@var{groups}) ++@deftypefun int setgroups (size_t @var{count}, const gid_t *@var{groups}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} ++@c setgroups @asulock @aculock ++@c INLINE_SETXID_SYSCALL dup @asulock @aculock + This function sets the process's supplementary group IDs. It can only + be called from privileged processes. The @var{count} argument specifies + the number of group IDs in the array @var{groups}. +@@ -455,6 +508,36 @@ + @comment grp.h + @comment BSD + @deftypefun int initgroups (const char *@var{user}, gid_t @var{group}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}} ++@c initgroups @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c sysconf(_SC_NGROUPS_MAX) dup @acsfd ++@c MIN dup ok ++@c malloc @ascuheap @acsmem ++@c internal_getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getgrouplist @ascuheap @acsfd @acsmem ++@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem ++@c nscd_cache_search dup ok ++@c nscd_open_socket dup @acsfd ++@c realloc dup @ascuheap @acsmem ++@c readall dup ok ++@c memcpy dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref dup @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c nss_database_lookup dup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c compat_call @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c sysconf(_SC_GETGR_R_SIZE_MAX) ok ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *getgrent_fct @ascuplugin ++@c *setgrent_fct @ascuplugin ++@c *endgrent_fct @ascuplugin ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c *initgroups_dyn_fct @ascuplugin ++@c nss_next_action dup ok ++@c setgroups dup @asulock @aculock ++@c free dup @ascuheap @acsmem + The @code{initgroups} function sets the process's supplementary group + IDs to be the normal default for the user name @var{user}. The group + @var{group} is automatically included. +@@ -476,6 +559,13 @@ + @comment grp.h + @comment BSD + @deftypefun int getgrouplist (const char *@var{user}, gid_t @var{group}, gid_t *@var{groups}, int *@var{ngroups}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @acsmem{} @acsfd{} @aculock{}}} ++@c getgrouplist @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c MAX dup ok ++@c malloc dup @ascuheap @acsmem ++@c internal_getgrouplist dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c memcpy dup ok ++@c free dup @ascuheap @acsmem + The @code{getgrouplist} function scans the group database for all the + groups @var{user} belongs to. Up to *@var{ngroups} group IDs + corresponding to these groups are stored in the array @var{groups}; the +@@ -740,7 +830,7 @@ + Be cautious about using the @code{exec} functions in combination with + changing the effective user ID. Don't let users of your program execute + arbitrary programs under a changed user ID. Executing a shell is +-especially bad news. Less obviously, the @code{execlp} and @code{execvp} ++especially bad news. Less obviously, the @code{execlp} and @code{execvp} + functions are a potential risk (since the program they execute depends + on the user's @code{PATH} environment variable). + +@@ -792,6 +882,41 @@ + @comment unistd.h + @comment POSIX.1 + @deftypefun {char *} getlogin (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:getlogin} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getlogin (linux) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getlogin_r_loginuid dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getlogin_fd0 (unix) @mtasurace:getlogin @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem ++@c uses static buffer name => @mtasurace:getlogin ++@c ttyname_r dup @ascuheap @acsmem @acsfd ++@c strncpy dup ok ++@c setutent dup @mtasurace:utent @asulock @aculock @acsfd ++@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c endutent dup @mtasurace:utent @asulock @aculock ++@c libc_lock_unlock dup ok ++@c strlen dup ok ++@c memcpy dup ok ++@c ++@c getlogin_r (linux) @mtasurace:utent @mtascusig:ALRM @mtascutimer @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getlogin_r_loginuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c open_not_cancel_2 dup @acsfd ++@c read_not_cancel dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c strtoul @mtslocale ++@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @asulock @aculock @acsfd @acsmem ++@c strlen dup ok ++@c memcpy dup ok ++@c free dup @asulock @aculock @acsfd @acsmem ++@c getlogin_r_fd0 (unix) @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd ++@c ttyname_r dup @ascuheap @acsmem @acsfd ++@c strncpy dup ok ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->setutent dup @mtasurace:utent @acsfd ++@c *libc_utmp_jump_table->getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer ++@c *libc_utmp_jump_table->endutent dup @mtasurace:utent @asulock @aculock ++@c libc_lock_unlock dup ok ++@c strlen dup ok ++@c memcpy dup ok + The @code{getlogin} function returns a pointer to a string containing the + name of the user logged in on the controlling terminal of the process, + or a null pointer if this information cannot be determined. The string +@@ -802,6 +927,11 @@ + @comment stdio.h + @comment POSIX.1 + @deftypefun {char *} cuserid (char *@var{string}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c cuserid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c geteuid dup ok ++@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c strncpy dup ok + The @code{cuserid} function returns a pointer to a string containing a + user name associated with the effective ID of the process. If + @var{string} is not a null pointer, it should be an array that can hold +@@ -1013,6 +1143,22 @@ + @comment utmp.h + @comment SVID + @deftypefun void setutent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c Besides the static variables in utmp_file.c, there's the jump_table. ++@c They're both modified while holding a lock, but other threads may ++@c cause the variables to be modified between calling this function and ++@c others that rely on the internal state it sets up. ++ ++@c setutent @mtasurace:utent @asulock @aculock @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->setutent @mtasurace:utent @acsfd ++@c setutent_unknown @mtasurace:utent @acsfd ++@c *libc_utmp_file_functions.setutent = setutent_file @mtasurace:utent @acsfd ++@c open_not_cancel_2 dup @acsfd ++@c fcntl_not_cancel dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c lseek64 dup ok ++@c libc_lock_unlock dup ok + This function opens the user accounting database to begin scanning it. + You can then call @code{getutent}, @code{getutid} or @code{getutline} to + read entries and @code{pututline} to write entries. +@@ -1024,6 +1170,14 @@ + @comment utmp.h + @comment SVID + @deftypefun {struct utmp *} getutent (void) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtasurace{:utentbuf} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c The static buffer that holds results is allocated with malloc at ++@c the first call; the test is not thread-safe, so multiple concurrent ++@c calls could malloc multiple buffers. ++ ++@c getutent @mtuinit @mtasurace:utent @mtasurace:utentbuf @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem ++@c malloc @asulock @aculock @acsfd @acsmem ++@c getutent_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + The @code{getutent} function reads the next entry from the user + accounting database. It returns a pointer to the entry, which is + statically allocated and may be overwritten by subsequent calls to +@@ -1037,12 +1191,27 @@ + @comment utmp.h + @comment SVID + @deftypefun void endutent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c endutent @mtasurace:utent @asulock @aculock @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->endutent @mtasurace:utent @acsfd ++@c endutent_unknown ok ++@c endutent_file @mtasurace:utent @acsfd ++@c close_not_cancel_no_status dup @acsfd ++@c libc_lock_unlock dup ok + This function closes the user accounting database. + @end deftypefun + + @comment utmp.h + @comment SVID + @deftypefun {struct utmp *} getutid (const struct utmp *@var{id}) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} ++@c Same caveats as getutline. ++@c ++@c getutid @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsmem @acsfd ++@c uses a static buffer malloced on the first call ++@c malloc dup @ascuheap @acsmem ++@c getutid_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + This function searches forward from the current point in the database + for an entry that matches @var{id}. If the @code{ut_type} member of the + @var{id} structure is one of @code{RUN_LVL}, @code{BOOT_TIME}, +@@ -1073,6 +1242,14 @@ + @comment utmp.h + @comment SVID + @deftypefun {struct utmp *} getutline (const struct utmp *@var{line}) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c The static buffer that holds results is allocated with malloc at ++@c the first call; the test is not thread-safe, so multiple concurrent ++@c calls could malloc multiple buffers. ++ ++@c getutline @mtuinit @mtasurace:utent @mtascusig:ALRM @mtascutimer @ascuheap @asulock @aculock @acsfd @acsmem ++@c malloc @asulock @aculock @acsfd @acsmem ++@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd + This function searches forward from the current point in the database + until it finds an entry whose @code{ut_type} value is + @code{LOGIN_PROCESS} or @code{USER_PROCESS}, and whose @code{ut_line} +@@ -1095,6 +1272,29 @@ + @comment utmp.h + @comment SVID + @deftypefun {struct utmp *} pututline (const struct utmp *@var{utmp}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->pututline @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c pututline_unknown @mtasurace:utent @acsfd ++@c setutent_unknown dup @mtasurace:utent @acsfd ++@c pututline_file @mtascusig:ALRM @mtascutimer @acsfd ++@c TRANSFORM_UTMP_FILE_NAME ok ++@c strcmp dup ok ++@c acesss dup ok ++@c open_not_cancel_2 dup @acsfd ++@c fcntl_not_cancel dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c llseek dup ok ++@c dup2 dup ok ++@c utmp_equal dup ok ++@c internal_getut_r dup @mtascusig:ALRM @mtascutimer ++@c LOCK_FILE dup @mtascusig:ALRM @mtasctimer ++@c LOCKING_FAILED dup ok ++@c ftruncate64 dup ok ++@c write_not_cancel dup ok ++@c UNLOCK_FILE dup @mtasctimer ++@c libc_lock_unlock dup @aculock + The @code{pututline} function inserts the entry @code{*@var{utmp}} at + the appropriate place in the user accounting database. If it finds that + it is not already at the correct place in the database, it uses +@@ -1125,6 +1325,27 @@ + @comment utmp.h + @comment GNU + @deftypefun int getutent_r (struct utmp *@var{buffer}, struct utmp **@var{result}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->getutent_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c getutent_r_unknown @mtasurace:utent @acsfd ++@c setutent_unknown dup @mtasurace:utent @acsfd ++@c getutent_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer ++@c LOCK_FILE @mtascusig:ALRM @mtascutimer ++@c alarm dup @mtascutimer ++@c sigemptyset dup ok ++@c sigaction dup ok ++@c memset dup ok ++@c fcntl_not_cancel dup ok ++@c LOCKING_FAILED ok ++@c read_not_cancel dup ok ++@c UNLOCK_FILE @mtascutimer ++@c fcntl_not_cancel dup ok ++@c alarm dup @mtascutimer ++@c sigaction dup ok ++@c memcpy dup ok ++@c libc_lock_unlock dup ok + The @code{getutent_r} is equivalent to the @code{getutent} function. It + returns the next entry from the database. But instead of storing the + information in a static buffer it stores it in the buffer pointed to by +@@ -1142,6 +1363,22 @@ + @comment utmp.h + @comment GNU + @deftypefun int getutid_r (const struct utmp *@var{id}, struct utmp *@var{buffer}, struct utmp **@var{result}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->getutid_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c getutid_r_unknown @mtasurace:utent @acsfd ++@c setutent_unknown dup @mtasurace:utent @acsfd ++@c getutid_r_file @mtascusig:ALRM @mtascutimer ++@c internal_getut_r @mtascusig:ALRM @mtascutimer ++@c LOCK_FILE dup @mtascusig:ALRM @mtascutimer ++@c LOCKING_FAILED dup ok ++@c read_not_cancel dup ok ++@c utmp_equal ok ++@c strncmp dup ok ++@c UNLOCK_FILE dup @mtascutimer ++@c memcpy dup ok ++@c libc_lock_unlock dup @aculock + This function retrieves just like @code{getutid} the next entry matching + the information stored in @var{id}. But the result is stored in the + buffer pointed to by the parameter @var{buffer}. +@@ -1157,6 +1394,28 @@ + @comment utmp.h + @comment GNU + @deftypefun int getutline_r (const struct utmp *@var{line}, struct utmp *@var{buffer}, struct utmp **@var{result}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} ++@c getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->getutline_r @mtasurace:utent @mtascusig:ALRM @mtascutimer @acsfd ++@c getutline_r_unknown @mtasurace:utent @acsfd ++@c setutent_unknown dup @mtasurace:utent @acsfd ++@c getutline_r_file @mtasurace:utent @mtascusig:ALRM @mtascutimer ++@c LOCK_FILE @mtascusig:ALRM @mtascutimer ++@c alarm dup @mtascutimer ++@c sigemptyset dup ok ++@c sigaction dup ok ++@c memset dup ok ++@c fcntl_not_cancel dup ok ++@c LOCKING_FAILED ok ++@c read_not_cancel dup ok ++@c strncmp dup ok ++@c UNLOCK_FILE @mtascutimer ++@c fcntl_not_cancel dup ok ++@c alarm dup @mtascutimer ++@c sigaction dup ok ++@c memcpy dup ok ++@c libc_lock_unlock dup ok + This function retrieves just like @code{getutline} the next entry + matching the information stored in @var{line}. But the result is stored + in the buffer pointed to by the parameter @var{buffer}. +@@ -1180,6 +1439,14 @@ + @comment utmp.h + @comment SVID + @deftypefun int utmpname (const char *@var{file}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} ++@c utmpname @mtasurace:utent @asulock @ascuheap @aculock @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c *libc_utmp_jump_table->endutent dup @mtasurace:utent ++@c strcmp dup ok ++@c free dup @ascuheap @acsmem ++@c strdup dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock + The @code{utmpname} function changes the name of the database to be + examined to @var{file}, and closes any previously opened database. By + default @code{getutent}, @code{getutid}, @code{getutline} and +@@ -1208,6 +1475,18 @@ + @comment utmp.h + @comment SVID + @deftypefun void updwtmp (const char *@var{wtmp_file}, const struct utmp *@var{utmp}) ++@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}} ++@c updwtmp @mtascusig:ALRM @mtascutimer @acsfd ++@c TRANSFORM_UTMP_FILE_NAME dup ok ++@c *libc_utmp_file_functions->updwtmp = updwtmp_file @mtascusig:ALRM @mtascutimer @acsfd ++@c open_not_cancel_2 dup @acsfd ++@c LOCK_FILE dup @mtascusig:ALRM @mtascutimer ++@c LOCKING_FAILED dup ok ++@c lseek64 dup ok ++@c ftruncate64 dup ok ++@c write_not_cancel dup ok ++@c UNLOCK_FILE dup @mtascutimer ++@c close_not_cancel_no_status dup @acsfd + The @code{updwtmp} function appends the entry *@var{utmp} to the + database specified by @var{wtmp_file}. For possible values for the + @var{wtmp_file} argument see the @code{utmpname} function. +@@ -1330,6 +1609,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun void setutxent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + This function is similar to @code{setutent}. In @theglibc{} it is + simply an alias for @code{setutent}. + @end deftypefun +@@ -1337,6 +1617,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun {struct utmpx *} getutxent (void) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} + The @code{getutxent} function is similar to @code{getutent}, but returns + a pointer to a @code{struct utmpx} instead of @code{struct utmp}. In + @theglibc{} it simply is an alias for @code{getutent}. +@@ -1345,6 +1626,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun void endutxent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{}}@acunsafe{@aculock{}}} + This function is similar to @code{endutent}. In @theglibc{} it is + simply an alias for @code{endutent}. + @end deftypefun +@@ -1352,6 +1634,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun {struct utmpx *} getutxid (const struct utmpx *@var{id}) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{} @acsfd{}}} + This function is similar to @code{getutid}, but uses @code{struct utmpx} + instead of @code{struct utmp}. In @theglibc{} it is simply an alias + for @code{getutid}. +@@ -1360,6 +1643,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun {struct utmpx *} getutxline (const struct utmpx *@var{line}) ++@safety{@prelim{}@mtunsafe{@mtuinit{} @mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} + This function is similar to @code{getutid}, but uses @code{struct utmpx} + instead of @code{struct utmp}. In @theglibc{} it is simply an alias + for @code{getutline}. +@@ -1368,6 +1652,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun {struct utmpx *} pututxline (const struct utmpx *@var{utmp}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{}}@acunsafe{@aculock{} @acsfd{}}} + The @code{pututxline} function is functionally identical to + @code{pututline}, but uses @code{struct utmpx} instead of @code{struct + utmp}. In @theglibc{}, @code{pututxline} is simply an alias for +@@ -1377,6 +1662,7 @@ + @comment utmpx.h + @comment XPG4.2 + @deftypefun int utmpxname (const char *@var{file}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsmem{}}} + The @code{utmpxname} function is functionally identical to + @code{utmpname}. In @theglibc{}, @code{utmpxname} is simply an + alias for @code{utmpname}. +@@ -1391,6 +1677,7 @@ + @comment utmp.h + @comment GNU + @deftypefun int getutmp (const struct utmpx *@var{utmpx}, struct utmp *@var{utmp}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{getutmp} copies the information, insofar as the structures are + compatible, from @var{utmpx} to @var{utmp}. + @end deftypefun +@@ -1399,6 +1686,7 @@ + @comment utmp.h + @comment GNU + @deftypefun int getutmpx (const struct utmp *@var{utmp}, struct utmpx *@var{utmpx}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} + @code{getutmpx} copies the information, insofar as the structures are + compatible, from @var{utmp} to @var{utmpx}. + @end deftypefun +@@ -1418,6 +1706,17 @@ + @comment utmp.h + @comment BSD + @deftypefun int login_tty (int @var{filedes}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:ttyname}}@asunsafe{@ascuheap{} @asulock{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c If this function is canceled, it may have succeeded in redirecting ++@c only some of the standard streams to the newly opened terminal. ++@c Should there be a safety annotation for this? ++@c login_tty @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd ++@c setsid dup ok ++@c ioctl dup ok ++@c ttyname dup @mtasurace:ttyname @ascuheap @asulock @aculock @acsmem @acsfd ++@c close dup @acsfd ++@c open dup @acsfd ++@c dup2 dup ok + This function makes @var{filedes} the controlling terminal of the + current process, redirects standard input, standard output and + standard error output to this terminal, and closes @var{filedes}. +@@ -1429,6 +1728,24 @@ + @comment utmp.h + @comment BSD + @deftypefun void login (const struct utmp *@var{entry}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acucorrupt{} @acsfd{} @acsmem{}}} ++@c login @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acucorrupt @acsfd @acsmem ++@c getpid dup ok ++@c tty_name @ascuheap @acucorrupt @acsmem @acsfd ++@c ttyname_r dup @ascuheap @acsmem @acsfd ++@c memchr dup ok ++@c realloc dup @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c strncmp dup ok ++@c basename dup ok ++@c strncpy dup ok ++@c utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem ++@c setutent dup @mtasurace:utent @asulock @aculock @acsfd ++@c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c endutent dup @mtasurace:utent @asulock @aculock ++@c free dup @ascuheap @acsmem ++@c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd + The @code{login} functions inserts an entry into the user accounting + database. The @code{ut_line} member is set to the name of the terminal + on standard input. If standard input is not a terminal @code{login} +@@ -1444,6 +1761,17 @@ + @comment utmp.h + @comment BSD + @deftypefun int logout (const char *@var{ut_line}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:utent} @mtascusig{:ALRM} @mtascutimer{}}@asunsafe{@asulock{} @ascuheap{}}@acunsafe{@aculock{} @acsfd{} @acsmem{}}} ++@c logout @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @ascuheap @aculock @acsfd @acsmem ++@c utmpname dup @mtasurace:utent @asulock @ascuheap @aculock @acsmem ++@c setutent dup @mtasurace:utent @asulock @aculock @acsfd ++@c strncpy dup ok ++@c getutline_r dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c bzero dup ok ++@c gettimeofday dup ok ++@c time dup ok ++@c pututline dup @mtasurace:utent @mtascusig:ALRM @mtascutimer @asulock @aculock @acsfd ++@c endutent dup @mtasurace:utent @asulock @aculock + This function modifies the user accounting database to indicate that the + user on @var{ut_line} has logged out. + +@@ -1454,6 +1782,14 @@ + @comment utmp.h + @comment BSD + @deftypefun void logwtmp (const char *@var{ut_line}, const char *@var{ut_name}, const char *@var{ut_host}) ++@safety{@prelim{}@mtunsafe{@mtascusig{:ALRM} @mtascutimer{}}@asunsafe{}@acunsafe{@acsfd{}}} ++@c logwtmp @mtascusig:ALRM @mtascutimer @acsfd ++@c memset dup ok ++@c getpid dup ok ++@c strncpy dup ok ++@c gettimeofday dup ok ++@c time dup ok ++@c updwtmp dup @mtascusig:ALRM @mtascutimer @acsfd + The @code{logwtmp} function appends an entry to the user accounting log + file, for the current time and the information provided in the + @var{ut_line}, @var{ut_name} and @var{ut_host} arguments. +@@ -1535,6 +1871,14 @@ + @comment pwd.h + @comment POSIX.1 + @deftypefun {struct passwd *} getpwuid (uid_t @var{uid}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:pwuid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getpwuid @mtasurace:pwuid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock + This function returns a pointer to a statically-allocated structure + containing information about the user whose user ID is @var{uid}. This + structure may be overwritten on subsequent calls to @code{getpwuid}. +@@ -1546,6 +1890,208 @@ + @comment pwd.h + @comment POSIX.1c + @deftypefun int getpwuid_r (uid_t @var{uid}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getpwuid_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getpwuid_r @ascuheap @acsfd @acsmem ++@c itoa_word dup ok ++@c nscd_getpw_r @ascuheap @acsfd @acsmem ++@c nscd_get_map_ref @ascuheap @acsfd @acsmem ++@c nscd_acquire_maplock ok ++@c nscd_get_mapping @ascuheap @acsfd @acsmem ++@c open_socket dup @acsfd ++@c memset dup ok ++@c wait_on_socket dup ok ++@c recvmsg dup ok ++@c strcmp dup ok ++@c fstat64 dup ok ++@c mmap dup @acsmem ++@c munmap dup @acsmem ++@c malloc dup @ascuheap @acsmem ++@c close dup ok ++@c nscd_unmap dup @ascuheap @acsmem ++@c nscd_cache_search ok ++@c nis_hash ok ++@c memcmp dup ok ++@c nscd_open_socket @acsfd ++@c open_socket @acsfd ++@c socket dup @acsfd ++@c fcntl dup ok ++@c strcpy dup ok ++@c connect dup ok ++@c send dup ok ++@c gettimeofday dup ok ++@c poll dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c wait_on_socket dup ok ++@c read dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c readall ok ++@c read dup ok ++@c wait_on_socket ok ++@c poll dup ok ++@c gettimeofday dup ok ++@c memcpy dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c nscd_unmap @ascuheap @acsmem ++@c munmap dup ok ++@c free dup @ascuheap @acsmem ++@c nss_passwd_lookup2 @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_database_lookup @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock ++@c libc_lock_lock @asulock @aculock ++@c libc_lock_unlock @aculock ++@c nss_parse_file @mtslocale @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking dup ok [no concurrent uses] ++@c malloc dup @asulock @aculock @acsfd @acsmem ++@c fclose dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c getline dup @ascuheap @aculock @acucorrupt @acsmem ++@c strchrnul dup ok ++@c nss_getline @mtslocale @ascuheap @acsmem ++@c isspace @mtslocale^^ ++@c strlen dup ok ++@c malloc dup @asulock @aculock @acsfd @acsmem ++@c memcpy dup ok ++@c nss_parse_service_list dup @mtslocale^, @ascuheap @acsmem ++@c feof_unlocked dup ok ++@c free dup @asulock @aculock @acsfd @acsmem ++@c strcmp dup ok ++@c nss_parse_service_list @mtslocale^, @ascuheap @acsmem ++@c isspace @mtslocale^^ ++@c malloc dup @asulock @aculock @acsfd @acsmem ++@c mempcpy dup ok ++@c strncasecmp dup ok ++@c free dup @asulock @aculock @acsfd @acsmem ++@c malloc dup @asulock @aculock @acsfd @acsmem ++@c nss_lookup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup_function @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c tsearch @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking] ++@c known_compare ok ++@c strcmp dup ok ++@c malloc dup @ascuheap @acsmem ++@c tdelete @ascuheap @acucorrupt @acsmem [no @mtsrace or @asucorrupt due to locking] ++@c free dup @ascuheap @acsmem ++@c nss_load_library @ascudlopen @ascuplugin @ascuheap @asulock @aculock @acsfd @acsmem ++@c nss_new_service @ascuheap @acsmem ++@c strcmp dup ok ++@c malloc dup @ascuheap @acsmem ++@c strlen dup ok ++@c stpcpy dup ok ++@c libc_dlopen @ascudlopen @ascuheap @asulock @aculock @acsfd @acsmem ++@c libc_dlsym dup @asulock @aculock @acsfd @acsmem ++@c *ifct(*nscd_init_cb) @ascuplugin ++@c stpcpy dup ok ++@c libc_dlsym dup @asulock @aculock @acsfd @acsmem ++@c libc_lock_unlock dup ok ++@c nss_next_action ok ++@c *fct.l -> _nss_*_getpwuid_r @ascuplugin ++@c nss_next2 @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_next_action dup ok ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++ ++@c _nss_files_getpwuid_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c internal_setent @ascuheap @asulock @aculock @acsmem @acsfd ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fileno dup ok ++@c fcntl dup ok ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c rewind dup @aculock [stream guarded by non-recursive pwent lock] ++@c internal_getent @mtslocale^ ++@c fgets_unlocked dup ok [stream guarded by non-recursive pwent lock] ++@c isspace dup @mtslocale^^ ++@c _nss_files_parse_pwent = parse_line ok ++@c strpbrk dup ok ++@c internal_endent @ascuheap @asulock @aculock @acsmem @acsfd ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_unlock dup @aculock ++ ++@c _nss_nis_getpwuid_r ... not fully reviewed (assumed) @asuinit @asulock @acucorrupt @aculock ++@c yp_get_default_domain @asulock @aculock ++@c libc_lock_lock dup @asulock @aculock ++@c getdomainname dup ok ++@c strcmp dup ok ++@c libc_lock_unlock dup @aculock ++@c snprintf dup @ascuheap @acsmem ++@c yp_match ++@c do_ypcall_tr(xdr_ypreq_key,xdr_ypresp_val) ++@c do_ypcall(xdr_ypreq_key,xdr_ypresp_val) ++@c libc_lock_lock @asulock @aculock ++@c strcmp ++@c yp_bind ++@c ypclnt_call ++@c clnt_call ++@c clnt_perror ++@c libc_lock_unlock @aculock ++@c yp_unbind_locked ++@c yp_unbind ++@c strcmp dup ok ++@c calloc dup @asulock @aculock @acsfd @acsmem ++@c yp_bind_file ++@c strlen dup ok ++@c snprintf dup @ascuheap @acsmem ++@c open dup @acsfd [cancelpt] ++@c pread dup [cancelpt] ++@c yp_bind_client_create ++@c close dup @acsfd [cancelpt] ++@c yp_bind_ypbindprog ++@c clnttcp_create ++@c clnt_destroy ++@c clnt_call(xdr_domainname,xdr_ypbind_resp) ++@c memset dup ok ++@c yp_bind_client_create ++@c free dup @asulock @aculock @acsfd @acsmem ++@c calloc dup @asulock @aculock @acsfd @acsmem ++@c free dup @asulock @aculock @acsfd @acsmem ++@c ypprot_err ++@c memcpy dup ok ++@c xdr_free(xdr_ypresp_val) ++@c xdr_ypresp_val ++@c xdr_ypstat ++@c xdr_enum ++@c XDR_PUTLONG ++@c *x_putlong ++@c XDR_GETLONG ++@c *x_getlong ++@c xdr_long ++@c XDR_PUTLONG dup ++@c XDR_GETLONG dup ++@c xdr_short ++@c XDR_PUTLONG dup ++@c XDR_GETLONG dup ++@c xdr_valdat ++@c xdr_bytes ++@c xdr_u_int ++@c XDR_PUTLONG dup ++@c XDR_GETLONG dup ++@c mem_alloc @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c xdr_opaque ++@c XDR_GETBYTES ++@c *x_getbytes ++@c XDR_PUTBYTES ++@c *x_putbytes ++@c mem_free @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c yperr2nss ok ++@c strchr dup ok ++@c _nls_default_nss @asuinit @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock ++@c init @asuinit^, @ascuheap @asulock @acucorrupt @acsmem @acsfd @aculock ++@c fopen dup @ascuheap @asulock @acsmem @acsfd @aculock ++@c fsetlocking ok [no concurrent uses] ++@c feof_unlocked dup ok ++@c getline dup @ascuheap @aculock @acucorrupt @acsmem ++@c isspace dup @mtslocale^^ ++@c strncmp dup ok ++@c free dup @asulock @acsmem @acsfd @aculock ++@c fclose dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c free dup @asulock @acsmem @acsfd @aculock ++@c mempcpy dup ok ++@c strncpy dup ok ++@c isspace dup @mtslocale^^ ++@c _nss_files_parse_pwent ok + This function is similar to @code{getpwuid} in that it returns + information about the user whose user ID is @var{uid}. However, it + fills the user supplied structure pointed to by @var{result_buf} with +@@ -1568,6 +2114,14 @@ + @comment pwd.h + @comment POSIX.1 + @deftypefun {struct passwd *} getpwnam (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:pwnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getpwnam @mtasurace:pwnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock + This function returns a pointer to a statically-allocated structure + containing information about the user whose user name is @var{name}. + This structure may be overwritten on subsequent calls to +@@ -1579,6 +2133,25 @@ + @comment pwd.h + @comment POSIX.1c + @deftypefun int getpwnam_r (const char *@var{name}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getpwnam_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getpwnam_r @ascuheap @asulock @aculock @acsfd @acsmem ++@c strlen dup ok ++@c nscd_getpw_r dup @ascuheap @asulock @aculock @acsfd @acsmem ++@c nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c ++@c _nss_files_getpwnam_r @mtslocale @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_lock dup @asulock @aculock ++@c internal_setent dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c internal_getent dup @mtslocale^ ++@c strcmp dup ok ++@c internal_endent dup @ascuheap @asulock @aculock @acsmem @acsfd ++@c libc_lock_unlock dup @aculock ++@c ++@c _nss_*_getpwnam_r (assumed) @asuinit @asulock @acucorrupt @aculock ++ + This function is similar to @code{getpwnam} in that is returns + information about the user whose user name is @var{name}. However, like + @code{getpwuid_r}, it fills the user supplied buffers in +@@ -1603,6 +2176,16 @@ + @comment pwd.h + @comment SVID + @deftypefun {struct passwd *} fgetpwent (FILE *@var{stream}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fpwent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}} ++@c fgetpwent @mtasurace:fpwent @asucorrupt @asulock @acucorrupt @aculock ++@c fgetpos dup @asucorrupt @aculock @acucorrupt ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c fgetpwent_r dup @asucorrupt @acucorrupt @aculock ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c fsetpos dup @asucorrupt @aculock @acucorrupt ++@c libc_lock_unlock dup @aculock + This function reads the next user entry from @var{stream} and returns a + pointer to the entry. The structure is statically allocated and is + rewritten on subsequent calls to @code{fgetpwent}. You must copy the +@@ -1615,6 +2198,14 @@ + @comment pwd.h + @comment GNU + @deftypefun int fgetpwent_r (FILE *@var{stream}, struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} ++@c fgetpwent_r @asucorrupt @acucorrupt @aculock ++@c flockfile dup @aculock ++@c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking] ++@c feof_unlocked dup ok ++@c funlockfile dup @aculock ++@c isspace dup @mtslocale^^ ++@c parse_line dup ok + This function is similar to @code{fgetpwent} in that it reads the next + user entry from @var{stream}. But the result is returned in the + structure pointed to by @var{result_buf}. The +@@ -1637,6 +2228,17 @@ + @comment pwd.h + @comment SVID, BSD + @deftypefun void setpwent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c setpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c nss_setent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c ** resolv's res_maybe_init not called here ++@c setup(nss_passwd_lookup2) @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *lookup_fct = nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:pwent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock @aculock + This function initializes a stream which @code{getpwent} and + @code{getpwent_r} use to read the user database. + @end deftypefun +@@ -1644,6 +2246,15 @@ + @comment pwd.h + @comment POSIX.1 + @deftypefun {struct passwd *} getpwent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtasurace{:pwentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getpwent @mtasurace:pwent @mtasurace:pwentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent(getpwent_r) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c malloc dup @ascuheap @acsmem ++@c *func = getpwent_r dup @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock + The @code{getpwent} function reads the next entry from the stream + initialized by @code{setpwent}. It returns a pointer to the entry. The + structure is statically allocated and is rewritten on subsequent calls +@@ -1655,7 +2266,21 @@ + + @comment pwd.h + @comment GNU +-@deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, int @var{buflen}, struct passwd **@var{result}) ++@deftypefun int getpwent_r (struct passwd *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct passwd **@var{result}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c The static buffer here is not the result_buf, but rather the ++@c variables that keep track of what nss backend we've last used, and ++@c whatever internal state the nss backend uses to keep track of the ++@c last read entry. ++@c getpwent_r @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nss_getent_r(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:pwent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *sfct.f @mtasurace:pwent @ascuplugin ++@c libc_lock_unlock dup @aculock + This function is similar to @code{getpwent} in that it returns the next + entry from the stream initialized by @code{setpwent}. Like + @code{fgetpwent_r}, it uses the user-supplied buffers in +@@ -1668,6 +2293,15 @@ + @comment pwd.h + @comment SVID, BSD + @deftypefun void endpwent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:pwent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endpwent @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock @asulock @aculock ++@c nss_endent(nss_passwd_lookup2) @mtasurace:pwent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c ** resolv's res_maybe_init not called here ++@c setup(nss_passwd_lookup2) dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @mtasurace:pwent @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_unlock @aculock + This function closes the internal stream used by @code{getpwent} or + @code{getpwent_r}. + @end deftypefun +@@ -1678,6 +2312,9 @@ + @comment pwd.h + @comment SVID + @deftypefun int putpwent (const struct passwd *@var{p}, FILE *@var{stream}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@asucorrupt{}}@acunsafe{@aculock{} @acucorrupt{}}} ++@c putpwent @mtslocale @asucorrupt @aculock @acucorrupt ++@c fprintf dup @mtslocale @asucorrupt @aculock @acucorrupt [no @ascuheap @acsmem] + This function writes the user entry @code{*@var{p}} to the stream + @var{stream}, in the format used for the standard user database + file. The return value is zero on success and nonzero on failure. +@@ -1751,6 +2388,9 @@ + @comment grp.h + @comment POSIX.1 + @deftypefun {struct group *} getgrgid (gid_t @var{gid}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:grgid} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getgrgid =~ getpwuid dup @mtasurace:grgid @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getgrgid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function returns a pointer to a statically-allocated structure + containing information about the group whose group ID is @var{gid}. + This structure may be overwritten by subsequent calls to +@@ -1762,6 +2402,26 @@ + @comment grp.h + @comment POSIX.1c + @deftypefun int getgrgid_r (gid_t @var{gid}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getgrgid_r =~ getpwuid_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getgrgid_r @ascuheap @acsfd @acsmem ++@c itoa_word dup ok ++@c nscd_getgr_r @ascuheap @acsfd @acsmem ++@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem ++@c nscd_cache_search dup ok ++@c nscd_open_socket dup @acsfd ++@c readvall ok ++@c readv dup ok ++@c memcpy dup ok ++@c wait_on_socket dup ok ++@c memcpy dup ok ++@c readall dup ok ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref dup @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c nss_group_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l -> _nss_*_getgrgid_r @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function is similar to @code{getgrgid} in that it returns + information about the group whose group ID is @var{gid}. However, it + fills the user supplied structure pointed to by @var{result_buf} with +@@ -1783,6 +2443,9 @@ + @comment grp.h + @comment SVID, BSD + @deftypefun {struct group *} getgrnam (const char *@var{name}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:grnam} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getgrnam =~ getpwnam dup @mtasurace:grnam @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c getgrnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function returns a pointer to a statically-allocated structure + containing information about the group whose group name is @var{name}. + This structure may be overwritten by subsequent calls to +@@ -1794,6 +2457,14 @@ + @comment grp.h + @comment POSIX.1c + @deftypefun int getgrnam_r (const char *@var{name}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) ++@safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getgrnam_r =~ getpwnam_r dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_getgrnam_r @ascuheap @asulock @aculock @acsfd @acsmem ++@c strlen dup ok ++@c nscd_getgr_r dup @ascuheap @asulock @aculock @acsfd @acsmem ++@c nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.l @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function is similar to @code{getgrnam} in that is returns + information about the group whose group name is @var{name}. Like + @code{getgrgid_r}, it uses the user supplied buffers in +@@ -1817,6 +2488,16 @@ + @comment grp.h + @comment SVID + @deftypefun {struct group *} fgetgrent (FILE *@var{stream}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:fgrent}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{}}} ++@c fgetgrent @mtasurace:fgrent @asucorrupt @asulock @acucorrupt @aculock ++@c fgetpos dup @asucorrupt @aculock @acucorrupt ++@c libc_lock_lock dup @asulock @aculock ++@c malloc dup @ascuheap @acsmem ++@c fgetgrent_r dup @asucorrupt @acucorrupt @aculock ++@c realloc dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c fsetpos dup @asucorrupt @aculock @acucorrupt ++@c libc_lock_unlock dup @aculock + The @code{fgetgrent} function reads the next entry from @var{stream}. + It returns a pointer to the entry. The structure is statically + allocated and is overwritten on subsequent calls to @code{fgetgrent}. You +@@ -1830,6 +2511,14 @@ + @comment grp.h + @comment GNU + @deftypefun int fgetgrent_r (FILE *@var{stream}, struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) ++@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{} @aculock{}}} ++@c fgetgrent_r @asucorrupt @acucorrupt @aculock ++@c flockfile dup @aculock ++@c fgets_unlocked @asucorrupt @acucorrupt [no @mtsrace due to explicit locking] ++@c feof_unlocked dup ok ++@c funlockfile dup @aculock ++@c isspace dup @mtslocale^^ ++@c parse_line dup ok + This function is similar to @code{fgetgrent} in that it reads the next + user entry from @var{stream}. But the result is returned in the + structure pointed to by @var{result_buf}. The first @var{buflen} bytes +@@ -1852,6 +2541,9 @@ + @comment grp.h + @comment SVID, BSD + @deftypefun void setgrent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c setgrent =~ setpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c ...*lookup_fct = nss_group_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function initializes a stream for reading from the group data base. + You use this stream by calling @code{getgrent} or @code{getgrent_r}. + @end deftypefun +@@ -1859,6 +2551,9 @@ + @comment grp.h + @comment SVID, BSD + @deftypefun {struct group *} getgrent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtasurace{:grentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getgrent =~ getpwent dup @mtasurace:grent @mtasurace:grentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *func = getgrent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + The @code{getgrent} function reads the next entry from the stream + initialized by @code{setgrent}. It returns a pointer to the entry. The + structure is statically allocated and is overwritten on subsequent calls +@@ -1869,6 +2564,8 @@ + @comment grp.h + @comment GNU + @deftypefun int getgrent_r (struct group *@var{result_buf}, char *@var{buffer}, size_t @var{buflen}, struct group **@var{result}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getgrent_r =~ getpwent_r dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function is similar to @code{getgrent} in that it returns the next + entry from the stream initialized by @code{setgrent}. Like + @code{fgetgrent_r}, it places the result in user-supplied buffers +@@ -1882,6 +2579,8 @@ + @comment grp.h + @comment SVID, BSD + @deftypefun void endgrent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:grent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endgrent =~ endpwent dup @mtasurace:grent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function closes the internal stream used by @code{getgrent} or + @code{getgrent_r}. + @end deftypefun +@@ -1966,6 +2665,40 @@ + @comment netdb.h + @comment BSD + @deftypefun int setnetgrent (const char *@var{netgroup}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c setnetgrent @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c nscd_setnetgrent @ascuheap @acsfd @acsmem ++@c __nscd_setnetgrent @ascuheap @acsfd @acsmem ++@c strlen dup ok ++@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem ++@c nscd_cache_search dup ok ++@c nscd_open_socket dup @acsfd ++@c malloc dup @ascuheap @acsmem ++@c readall dup ok ++@c free dup @ascuheap @acsmem ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref dup @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c internal_setnetgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c free_memory dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c internal_setnetgrent_reuse @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *endfct @ascuplugin ++@c (netgroup::)setup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_netgroup_lookup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_netgroup_lookup2 =~ nss_passwd_lookup2 dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct.f @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *endfct @ascuplugin ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c libc_lock_unlock dup @aculock + A call to this function initializes the internal state of the library to + allow following calls of the @code{getnetgrent} to iterate over all entries + in the netgroup with name @var{netgroup}. +@@ -1991,6 +2724,12 @@ + @comment netdb.h + @comment BSD + @deftypefun int getnetgrent (char **@var{hostp}, char **@var{userp}, char **@var{domainp}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtasurace{:netgrentbuf} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getnetgrent @mtasurace:netgrent @mtasurace:netgrentbuf @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c uses unsafely a static buffer allocated within a libc_once call ++@c allocate (libc_once) @ascuheap @acsmem ++@c malloc dup @ascuheap @acsmem ++@c getnetgrent_r dup @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem + This function returns the next unprocessed entry of the currently + selected netgroup. The string pointers, in which addresses are passed in + the arguments @var{hostp}, @var{userp}, and @var{domainp}, will contain +@@ -2005,7 +2744,20 @@ + + @comment netdb.h + @comment GNU +-@deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, int @var{buflen}) ++@deftypefun int getnetgrent_r (char **@var{hostp}, char **@var{userp}, char **@var{domainp}, char *@var{buffer}, size_t @var{buflen}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c getnetgrent_r @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c internal_getnetgrent_r @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *fct @ascuplugin ++@c nscd_getnetgrent ok ++@c rawmemchr dup ok ++@c internal_setnetgrent_reuse dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c strcmp dup ok ++@c malloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c libc_lock_unlock dup @aculock + This function is similar to @code{getnetgrent} with only one exception: + the strings the three string pointers @var{hostp}, @var{userp}, and + @var{domainp} point to, are placed in the buffer of @var{buflen} bytes +@@ -2024,6 +2776,13 @@ + @comment netdb.h + @comment BSD + @deftypefun void endnetgrent (void) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c endnetgrent @mtasurace:netgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c libc_lock_lock dup @asulock @aculock ++@c internal_endnetgrent @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c endnetgrent_hook dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c free_memory dup @ascuheap @acsmem ++@c libc_lock_unlock dup @aculock + This function frees all buffers which were allocated to process the last + selected netgroup. As a result all string pointers returned by calls + to @code{getnetgrent} are invalid afterwards. +@@ -2039,6 +2798,37 @@ + @comment netdb.h + @comment BSD + @deftypefun int innetgr (const char *@var{netgroup}, const char *@var{host}, const char *@var{user}, const char *@var{domain}) ++@safety{@prelim{}@mtunsafe{@mtasurace{:netgrent} @mtslocale{}}@asunsafe{@ascudlopen{} @ascuplugin{} @ascuheap{} @asulock{}}@acunsafe{@acucorrupt{} @aculock{} @acsfd{} @acsmem{}}} ++@c This function does not use the static data structure that the ++@c *netgrent* ones do, but since each nss must maintains internal state ++@c to support iteration and concurrent iteration will interfere ++@c destructively, we regard this internal state as a static buffer. ++@c getnetgrent_r iteration in each nss backend. ++@c innetgr @mtasurace:netgrent @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c nscd_innetgr @ascuheap @acsfd @acsmem ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c stpcpy dup ok ++@c nscd_get_map_ref dup @ascuheap @acsfd @acsmem ++@c nscd_cache_search dup ok ++@c nscd_open_socket dup @acsfd ++@c close_not_cancel_no_status dup @acsfd ++@c nscd_drop_map_ref dup @ascuheap @acsmem ++@c nscd_unmap dup @ascuheap @acsmem ++@c free dup @ascuheap @acsmem ++@c memset dup ok ++@c (netgroup::)setup dup @mtslocale @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *setfct.f @ascuplugin ++@c nss_lookup_function dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c *getfct @ascuplugin ++@c strcmp dup ok ++@c strlen dup ok ++@c malloc dup @ascuheap @acsmem ++@c memcpy dup ok ++@c strcasecmp dup ++@c *endfct @ascuplugin ++@c nss_next2 dup @ascudlopen @ascuplugin @ascuheap @asulock @acucorrupt @aculock @acsfd @acsmem ++@c free_memory dup @ascuheap @acsmem + This function tests whether the triple specified by the parameters + @var{hostp}, @var{userp}, and @var{domainp} is part of the netgroup + @var{netgroup}. Using this function has the advantage that +@@ -2062,3 +2852,7 @@ + itself is not found, the netgroup does not contain the triple or + internal errors occurred. + @end deftypefun ++ ++@c FIXME these are undocumented: ++@c setresgid ++@c setresuid diff --git a/SOURCES/glibc-ol7-strstr-sse4.patch b/SOURCES/glibc-ol7-strstr-sse4.patch new file mode 100755 index 00000000..b30f4ec6 --- /dev/null +++ b/SOURCES/glibc-ol7-strstr-sse4.patch @@ -0,0 +1,744 @@ +This patch file contains a backport of the following upstream commits, +which prevent segmentation faults due to unaligned accesses by sse4.2 +instructions. + +commit 584b18eb4df61ccd447db2dfe8c8a7901f8c8598 +Author: Ondej Blka +Date: Sat Dec 14 19:33:56 2 + + Add strstr with unaligned loads. Fixes bug 12100. + + A sse42 version of strstr used pcmpistr instruction which is quite + ineffective. A faster way is look for pairs of characters which is uses + sse2, is faster than pcmpistr and for real strings a pairs we look for + are relatively rare. + + For linear time complexity we use buy or rent technique which switches + to two-way algorithm when superlinear behaviour is detected. + +commit 1818483b15d22016b0eae41d37ee91cc87b37510 +Author: Andreas Schwab +Date: Wed Dec 18 11:53:27 + + Remove use of SSE4.2 functions for strstr on i686 + + The SSE4.2 have been removed from x86_64 by commit 584b18eb. This patch + fixes the build on i686, which attempts to use the removed files. + +diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-impl-list.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/ifunc-impl-list.c +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-impl-list.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/ifunc-impl-list.c 2014-07-01 05:38:25.138749032 -0400 +@@ -141,12 +141,6 @@ + IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, + __strcasecmp_l_ia32)) + +- /* Support sysdeps/i386/i686/multiarch/strcasestr.c. */ +- IFUNC_IMPL (i, name, strcasestr, +- IFUNC_IMPL_ADD (array, i, strcasestr, HAS_SSE4_2, +- __strcasestr_sse42) +- IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_ia32)) +- + /* Support sysdeps/i386/i686/multiarch/strcat.S. */ + IFUNC_IMPL (i, name, strcat, + IFUNC_IMPL_ADD (array, i, strcat, HAS_SSSE3, __strcat_ssse3) +@@ -234,11 +228,6 @@ + IFUNC_IMPL_ADD (array, i, strspn, HAS_SSE4_2, __strspn_sse42) + IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32)) + +- /* Support sysdeps/i386/i686/multiarch/strstr-c.c. */ +- IFUNC_IMPL (i, name, strstr, +- IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42) +- IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_ia32)) +- + /* Support sysdeps/i386/i686/multiarch/wcschr.S. */ + IFUNC_IMPL (i, name, wcschr, + IFUNC_IMPL_ADD (array, i, wcschr, HAS_SSE2, __wcschr_sse2) +diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Makefile glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/Makefile +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/Makefile 2014-07-01 05:37:15.985617738 -0400 +@@ -11,7 +11,7 @@ + memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \ + memset-sse2-rep bzero-sse2-rep strcmp-ssse3 \ + strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \ +- memcmp-ssse3 memcmp-sse4 strcasestr-nonascii varshift \ ++ memcmp-ssse3 memcmp-sse4 varshift \ + strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \ + strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 strcpy-sse2 \ + strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \ +@@ -25,14 +25,11 @@ + strncase_l-c strncase-c strncase_l-ssse3 \ + strcasecmp_l-sse4 strncase_l-sse4 + ifeq (yes,$(config-cflags-sse4)) +-sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c ++sysdep_routines += strcspn-c strpbrk-c strspn-c + CFLAGS-varshift.c += -msse4 + CFLAGS-strcspn-c.c += -msse4 + CFLAGS-strpbrk-c.c += -msse4 + CFLAGS-strspn-c.c += -msse4 +-CFLAGS-strstr.c += -msse4 +-CFLAGS-strcasestr.c += -msse4 +-CFLAGS-strcasestr-nonascii.c += -msse4 + endif + endif + +diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr.c +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-#include +diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strcasestr-nonascii.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,2 +0,0 @@ +-#include +-#include +diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr.c +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1 +0,0 @@ +-#include +diff -N -u -r glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr-c.c +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/i386/i686/multiarch/strstr-c.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,31 +0,0 @@ +-/* Multiple versions of strstr +- All versions must be listed in ifunc-impl-list.c. */ +- +-#define STRSTR __strstr_ia32 +-#if defined SHARED && defined DO_VERSIONING && !defined NO_HIDDEN +-#undef libc_hidden_builtin_def +-#define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strstr_ia32, __GI_strstr, __strstr_ia32); +-#endif +- +-/* Redefine strstr so that the compiler won't complain about the type +- mismatch with the IFUNC selector in strong_alias, below. */ +-#undef strstr +-#define strstr __redirect_strstr +- +-#include "string/strstr.c" +- +-#include "init-arch.h" +- +-extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden; +-extern __typeof (__redirect_strstr) __strstr_ia32 attribute_hidden; +- +-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle +- ifunc symbol properly. */ +-extern __typeof (__redirect_strstr) __libc_strstr; +-libc_ifunc (__libc_strstr, +- HAS_SSE4_2 && !use_unaligned_strstr () ? +- __strstr_sse42 : __strstr_ia32) +- +-#undef strstr +-strong_alias (__libc_strstr, strstr) +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/ifunc-impl-list.c +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/ifunc-impl-list.c 2014-06-30 10:58:16.637073138 -0400 +@@ -115,8 +115,6 @@ + + /* Support sysdeps/x86_64/multiarch/strcasestr.c. */ + IFUNC_IMPL (i, name, strcasestr, +- IFUNC_IMPL_ADD (array, i, strcasestr, HAS_SSE4_2, +- __strcasestr_sse42) + IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcat.S. */ +@@ -210,9 +210,7 @@ + + /* Support sysdeps/x86_64/multiarch/strstr-c.c. */ + IFUNC_IMPL (i, name, strstr, +- IFUNC_IMPL_ADD (array, i, strstr, use_unaligned_strstr (), +- __strstr_sse2_unaligned) +- IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42) ++ IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2)) + + /* Support sysdeps/x86_64/multiarch/wcscpy.S. */ +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/Makefile +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/Makefile 2014-06-30 10:55:08.343714449 -0400 +@@ -9,7 +9,7 @@ + sysdep_routines += strncat-c stpncpy-c strncpy-c strcmp-ssse3 strncmp-ssse3 \ + strend-sse4 memcmp-sse4 memcpy-ssse3 mempcpy-ssse3 \ + memmove-ssse3 memcpy-ssse3-back mempcpy-ssse3-back \ +- memmove-ssse3-back strcasestr-nonascii strcasecmp_l-ssse3 \ ++ memmove-ssse3-back strcasecmp_l-ssse3 \ + strncase_l-ssse3 strlen-sse4 strlen-sse2-no-bsf memset-x86-64 \ + strcpy-ssse3 strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 \ + strcpy-sse2-unaligned strncpy-sse2-unaligned \ +@@ -17,14 +17,11 @@ + strnlen-sse2-no-bsf strrchr-sse2-no-bsf strchr-sse2-no-bsf \ + memcmp-ssse3 strstr-sse2-unaligned + ifeq (yes,$(config-cflags-sse4)) +-sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c varshift ++sysdep_routines += strcspn-c strpbrk-c strspn-c varshift + CFLAGS-varshift.c += -msse4 + CFLAGS-strcspn-c.c += -msse4 + CFLAGS-strpbrk-c.c += -msse4 + CFLAGS-strspn-c.c += -msse4 +-CFLAGS-strstr.c += -msse4 +-CFLAGS-strcasestr.c += -msse4 +-CFLAGS-strcasestr-nonascii.c += -msse4 + endif + endif + +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr.c +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr.c 2014-06-30 11:01:34.394453519 -0400 +@@ -1,7 +1,13 @@ +-extern char *__strcasestr_sse42_nonascii (const unsigned char *s1, +- const unsigned char *s2) +- attribute_hidden; ++/* Multiple versions of strcasestr ++ All versions must be listed in ifunc-impl-list.c. */ + +-#define USE_AS_STRCASESTR +-#define STRSTR_SSE42 __strcasestr_sse42 +-#include "strstr.c" ++#include "init-arch.h" ++ ++#define STRCASESTR __strcasestr_sse2 ++ ++#include "string/strcasestr.c" ++ ++extern __typeof (__strcasestr_sse2) __strcasestr_sse2 attribute_hidden; ++ ++libc_ifunc (__strcasestr, ++ __strcasestr_sse2); +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-c.c +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-c.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,20 +0,0 @@ +-/* Multiple versions of strcasestr +- All versions must be listed in ifunc-impl-list.c. */ +- +-#include "init-arch.h" +- +-#define STRCASESTR __strcasestr_sse2 +- +-#include "string/strcasestr.c" +- +-extern char *__strcasestr_sse42 (const char *, const char *) attribute_hidden; +-extern __typeof (__strcasestr_sse2) __strcasestr_sse2 attribute_hidden; +- +-#if 1 +-libc_ifunc (__strcasestr, +- HAS_SSE4_2 && !use_unaligned_strstr () ? __strcasestr_sse42 : +- __strcasestr_sse2); +-#else +-libc_ifunc (__strcasestr, +- 0 ? __strcasestr_sse42 : __strcasestr_sse2); +-#endif +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-nonascii.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-nonascii.c +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-nonascii.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strcasestr-nonascii.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,50 +0,0 @@ +-/* strstr with SSE4.2 intrinsics +- Copyright (C) 2010 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- +-/* Similar to __m128i_strloadu. Convert to lower case for none-POSIX/C +- locale. */ +-static inline __m128i +-__m128i_strloadu_tolower (const unsigned char *p) +-{ +- union +- { +- char b[16]; +- __m128i x; +- } u; +- +- for (int i = 0; i < 16; ++i) +- if (p[i] == 0) +- { +- u.b[i] = 0; +- break; +- } +- else +- u.b[i] = tolower (p[i]); +- +- return u.x; +-} +- +- +-#define STRCASESTR_NONASCII +-#define USE_AS_STRCASESTR +-#define STRSTR_SSE42 __strcasestr_sse42_nonascii +-#include "strstr.c" +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr.c +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr.c 2014-06-30 11:26:55.025294484 -0400 +@@ -1,6 +1,6 @@ +-/* strstr with SSE4.2 intrinsics +- Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. +- Contributed by Intel Corporation. ++/* Multiple versions of strstr. ++ All versions must be listed in ifunc-impl-list.c. ++ Copyright (C) 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,368 +17,32 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include "varshift.h" +- +-#ifndef STRSTR_SSE42 +-# define STRSTR_SSE42 __strstr_sse42 +-#endif +- +-#ifdef USE_AS_STRCASESTR +-# include +-# include +- +-# define LOADBYTE(C) tolower (C) +-# define CMPBYTE(C1, C2) (tolower (C1) == tolower (C2)) +-#else +-# define LOADBYTE(C) (C) +-# define CMPBYTE(C1, C2) ((C1) == (C2)) ++/* Redefine strstr so that the compiler won't complain about the type ++ mismatch with the IFUNC selector in strong_alias, below. */ ++#undef strstr ++#define strstr __redirect_strstr ++#include ++#undef strstr ++ ++#define STRSTR __strstr_sse2 ++#ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strstr_sse2, __GI_strstr, __strstr_sse2); + #endif + +-/* We use 0xe ordered-compare: +- _SIDD_SBYTE_OPS +- | _SIDD_CMP_EQUAL_ORDER +- | _SIDD_LEAST_SIGNIFICANT +- on pcmpistri to do the scanning and string comparsion requirements of +- sub-string match. In the scanning phase, we process Cflag and ECX +- index to locate the first fragment match; once the first fragment +- match position has been identified, we do comparison of subsequent +- string fragments until we can conclude false or true match; whe +- n concluding a false match, we may need to repeat scanning process +- from next relevant offset in the target string. +- +- In the scanning phase we have 4 cases: +- case ECX CFlag ZFlag SFlag +- 1 16 0 0 0 +- 2a 16 0 0 1 +- 2b 16 0 1 0 +- 2c 16 0 1 1 +- +- 1. No ordered-comparison match, both 16B fragments are valid, so +- continue to next fragment. +- 2. No ordered-comparison match, there is EOS in either fragment, +- 2a. Zflg = 0, Sflg = 1, we continue +- 2b. Zflg = 1, Sflg = 0, we conclude no match and return. +- 2c. Zflg = 1, sflg = 1, lenth determine match or no match +- +- In the string comparison phase, the 1st fragment match is fixed up +- to produce ECX = 0. Subsequent fragment compare of nonzero index +- and no match conclude a false match. +- +- case ECX CFlag ZFlag SFlag +- 3 X 1 0 0/1 +- 4a 0 1 0 0 +- 4b 0 1 0 1 +- 4c 0 < X 1 0 0/1 +- 5 16 0 1 0 +- +- 3. An initial ordered-comparison fragment match, we fix up to do +- subsequent string comparison +- 4a. Continuation of fragment comparison of a string compare. +- 4b. EOS reached in the reference string, we conclude true match and +- return +- 4c. String compare failed if index is nonzero, we need to go back to +- scanning +- 5. failed string compare, go back to scanning +- */ +- +-/* Simple replacement of movdqu to address 4KB boundary cross issue. +- If EOS occurs within less than 16B before 4KB boundary, we don't +- cross to next page. */ +- +-static inline __m128i +-__m128i_strloadu (const unsigned char * p, __m128i zero) +-{ +- if (__builtin_expect ((int) ((size_t) p & 0xfff) > 0xff0, 0)) +- { +- size_t offset = ((size_t) p & (16 - 1)); +- __m128i a = _mm_load_si128 ((__m128i *) (p - offset)); +- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (a, zero)); +- if ((bmsk >> offset) != 0) +- return __m128i_shift_right (a, offset); +- } +- return _mm_loadu_si128 ((__m128i *) p); +-} +- +-#if defined USE_AS_STRCASESTR && !defined STRCASESTR_NONASCII +- +-/* Similar to __m128i_strloadu. Convert to lower case for POSIX/C +- locale and other which have single-byte letters only in the ASCII +- range. */ +-static inline __m128i +-__m128i_strloadu_tolower (const unsigned char *p, __m128i zero, __m128i uclow, +- __m128i uchigh, __m128i lcqword) +-{ +- __m128i frag = __m128i_strloadu (p, zero); +- +- /* Compare if 'Z' > bytes. Inverted way to get a mask for byte <= 'Z'. */ +- __m128i r2 = _mm_cmpgt_epi8 (uchigh, frag); +- /* Compare if bytes are > 'A' - 1. */ +- __m128i r1 = _mm_cmpgt_epi8 (frag, uclow); +- /* Mask byte == ff if byte(r2) <= 'Z' and byte(r1) > 'A' - 1. */ +- __m128i mask = _mm_and_si128 (r2, r1); +- /* Apply lowercase bit 6 mask for above mask bytes == ff. */ +- return _mm_or_si128 (frag, _mm_and_si128 (mask, lcqword)); +-} ++#include "string/strstr.c" + +-#endif ++extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden; ++extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden; + +-/* Calculate Knuth-Morris-Pratt string searching algorithm (or KMP +- algorithm) overlap for a fully populated 16B vector. +- Input parameter: 1st 16Byte loaded from the reference string of a +- strstr function. +- We don't use KMP algorithm if reference string is less than 16B. */ +-static int +-__inline__ __attribute__ ((__always_inline__,)) +-KMP16Bovrlap (__m128i s2) +-{ +- __m128i b = _mm_unpacklo_epi8 (s2, s2); +- __m128i a = _mm_unpacklo_epi8 (b, b); +- a = _mm_shuffle_epi32 (a, 0); +- b = _mm_srli_si128 (s2, sizeof (char)); +- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (b, a)); +- +- /* _BitScanForward(&k1, bmsk); */ +- int k1; +- __asm ("bsfl %[bmsk], %[k1]" : [k1] "=r" (k1) : [bmsk] "r" (bmsk)); +- if (!bmsk) +- return 16; +- else if (bmsk == 0x7fff) +- return 1; +- else if (!k1) +- { +- /* There are al least two distinct chars in s2. If byte 0 and 1 are +- idential and the distinct value lies farther down, we can deduce +- the next byte offset to restart full compare is least no earlier +- than byte 3. */ +- return 3; +- } +- else +- { +- /* Byte 1 is not degenerated to byte 0. */ +- return k1 + 1; +- } +-} +- +-char * +-__attribute__ ((section (".text.sse4.2"))) +-STRSTR_SSE42 (const unsigned char *s1, const unsigned char *s2) +-{ +-#define p1 s1 +- const unsigned char *p2 = s2; +- +-#ifndef STRCASESTR_NONASCII +- if (__builtin_expect (p2[0] == '\0', 0)) +- return (char *) p1; +- +- if (__builtin_expect (p1[0] == '\0', 0)) +- return NULL; +- +- /* Check if p1 length is 1 byte long. */ +- if (__builtin_expect (p1[1] == '\0', 0)) +- return p2[1] == '\0' && CMPBYTE (p1[0], p2[0]) ? (char *) p1 : NULL; +-#endif ++#include "init-arch.h" + +-#ifdef USE_AS_STRCASESTR +-# ifndef STRCASESTR_NONASCII +- if (__builtin_expect (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_NONASCII_CASE) +- != 0, 0)) +- return __strcasestr_sse42_nonascii (s1, s2); +- +- const __m128i uclow = _mm_set1_epi8 (0x40); +- const __m128i uchigh = _mm_set1_epi8 (0x5b); +- const __m128i lcqword = _mm_set1_epi8 (0x20); +- const __m128i zero = _mm_setzero_si128 (); +-# define strloadu(p) __m128i_strloadu_tolower (p, zero, uclow, uchigh, lcqword) +-# else +-# define strloadu __m128i_strloadu_tolower +-# define zero _mm_setzero_si128 () +-# endif +-#else +-# define strloadu(p) __m128i_strloadu (p, zero) +- const __m128i zero = _mm_setzero_si128 (); +-#endif ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++extern __typeof (__redirect_strstr) __libc_strstr; ++libc_ifunc (__libc_strstr, HAS_FAST_UNALIGNED_LOAD ? __strstr_sse2_unaligned : __strstr_sse2) + +- /* p1 > 1 byte long. Load up to 16 bytes of fragment. */ +- __m128i frag1 = strloadu (p1); + +- __m128i frag2; +- if (p2[1] != '\0') +- /* p2 is > 1 byte long. */ +- frag2 = strloadu (p2); +- else +- frag2 = _mm_insert_epi8 (zero, LOADBYTE (p2[0]), 0); +- +- /* Unsigned bytes, equal order, does frag2 has null? */ +- int cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- int cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- int cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- int cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c); +- if (cmp_s & cmp_c) +- { +- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (frag2, zero)); +- int len; +- __asm ("bsfl %[bmsk], %[len]" +- : [len] "=r" (len) : [bmsk] "r" (bmsk)); +- p1 += cmp; +- if ((len + cmp) <= 16) +- return (char *) p1; +- +- /* Load up to 16 bytes of fragment. */ +- frag1 = strloadu (p1); +- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c); +- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- if ((len + cmp) <= 16) +- return (char *) p1 + cmp; +- } +- +- if (cmp_s) +- { +- /* Adjust addr for 16B alginment in ensuing loop. */ +- while (!cmp_z) +- { +- p1 += cmp; +- /* Load up to 16 bytes of fragment. */ +- frag1 = strloadu (p1); +- cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- /* Because s2 < 16 bytes and we adjusted p1 by non-zero cmp +- once already, this time cmp will be zero and we can exit. */ +- if ((!cmp) & cmp_c) +- break; +- } +- +- if (!cmp_c) +- return NULL; +- +- /* Since s2 is less than 16 bytes, com_c is definitive +- determination of full match. */ +- return (char *) p1 + cmp; +- } +- +- /* General case, s2 is at least 16 bytes or more. +- First, the common case of false-match at first byte of p2. */ +- const unsigned char *pt = NULL; +- int kmp_fwd = 0; +-re_trace: +- while (!cmp_c) +- { +- /* frag1 has null. */ +- if (cmp_z) +- return NULL; +- +- /* frag 1 has no null, advance 16 bytes. */ +- p1 += 16; +- /* Load up to 16 bytes of fragment. */ +- frag1 = strloadu (p1); +- /* Unsigned bytes, equal order, is there a partial match? */ +- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- } +- +- /* Next, handle initial positive match as first byte of p2. We have +- a partial fragment match, make full determination until we reached +- end of s2. */ +- if (!cmp) +- { +- if (cmp_z) +- return (char *) p1; +- +- pt = p1; +- p1 += 16; +- p2 += 16; +- /* Load up to 16 bytes of fragment. */ +- frag2 = strloadu (p2); +- } +- else +- { +- /* Adjust 16B alignment. */ +- p1 += cmp; +- pt = p1; +- } +- +- /* Load up to 16 bytes of fragment. */ +- frag1 = strloadu (p1); +- +- /* Unsigned bytes, equal order, does frag2 has null? */ +- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c); +- while (!(cmp | cmp_z | cmp_s)) +- { +- p1 += 16; +- p2 += 16; +- /* Load up to 16 bytes of fragment. */ +- frag2 = strloadu (p2); +- /* Load up to 16 bytes of fragment. */ +- frag1 = strloadu (p1); +- /* Unsigned bytes, equal order, does frag2 has null? */ +- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- cmp_s = _mm_cmpistrs (frag2, frag1, 0x0c); +- } +- +- /* Full determination yielded a false result, retrace s1 to next +- starting position. +- Zflg 1 0 1 0/1 +- Sflg 0 1 1 0/1 +- cmp na 0 0 >0 +- action done done continue continue if s2 < s1 +- false match retrace s1 else false +- */ +- +- if (cmp_s & !cmp) +- return (char *) pt; +- if (cmp_z) +- { +- if (!cmp_s) +- return NULL; +- +- /* Handle both zero and sign flag set and s1 is shorter in +- length. */ +- int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (zero, frag2)); +- int bmsk1 = _mm_movemask_epi8 (_mm_cmpeq_epi8 (zero, frag1)); +- int len; +- int len1; +- __asm ("bsfl %[bmsk], %[len]" +- : [len] "=r" (len) : [bmsk] "r" (bmsk)); +- __asm ("bsfl %[bmsk1], %[len1]" +- : [len1] "=r" (len1) : [bmsk1] "r" (bmsk1)); +- if (len >= len1) +- return NULL; +- } +- else if (!cmp) +- return (char *) pt; +- +- /* Otherwise, we have to retrace and continue. Default of multiple +- paths that need to retrace from next byte in s1. */ +- p2 = s2; +- frag2 = strloadu (p2); +- +- if (!kmp_fwd) +- kmp_fwd = KMP16Bovrlap (frag2); +- +- /* KMP algorithm predicted overlap needs to be corrected for +- partial fragment compare. */ +- p1 = pt + (kmp_fwd > cmp ? cmp : kmp_fwd); +- +- /* Since s2 is at least 16 bytes long, we're certain there is no +- match. */ +- if (p1[0] == '\0') +- return NULL; +- +- /* Load up to 16 bytes of fragment. */ +- frag1 = strloadu (p1); +- +- /* Unsigned bytes, equal order, is there a partial match? */ +- cmp_c = _mm_cmpistrc (frag2, frag1, 0x0c); +- cmp = _mm_cmpistri (frag2, frag1, 0x0c); +- cmp_z = _mm_cmpistrz (frag2, frag1, 0x0c); +- goto re_trace; +-} ++#undef strstr ++strong_alias (__libc_strstr, strstr) +diff -N -u -r glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr-c.c +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686-hacked/sysdeps/x86_64/multiarch/strstr-c.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,50 +0,0 @@ +-/* Multiple versions of strstr. +- All versions must be listed in ifunc-impl-list.c. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* Redefine strstr so that the compiler won't complain about the type +- mismatch with the IFUNC selector in strong_alias, below. */ +-#undef strstr +-#define strstr __redirect_strstr +-#include +-#undef strstr +- +-#define STRSTR __strstr_sse2 +-#ifdef SHARED +-# undef libc_hidden_builtin_def +-# define libc_hidden_builtin_def(name) \ +- __hidden_ver1 (__strstr_sse2, __GI_strstr, __strstr_sse2); +-#endif +- +-#include "string/strstr.c" +- +-extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden; +-extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden; +-extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden; +- +-#include "init-arch.h" +- +-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle +- ifunc symbol properly. */ +-extern __typeof (__redirect_strstr) __libc_strstr; +-libc_ifunc (__libc_strstr, HAS_SSE4_2 ? (use_unaligned_strstr () ? +- __strstr_sse2_unaligned : +- __strstr_sse42) : __strstr_sse2) +- +-#undef strstr +-strong_alias (__libc_strstr, strstr) diff --git a/SOURCES/glibc-powerpc-ldbl_high.patch b/SOURCES/glibc-powerpc-ldbl_high.patch new file mode 100644 index 00000000..0cdc34fc --- /dev/null +++ b/SOURCES/glibc-powerpc-ldbl_high.patch @@ -0,0 +1,13 @@ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 19:59:00.000000000 -0500 +@@ -190,6 +190,9 @@ + # define ldbl_unpack default_ldbl_unpack + #endif + ++/* Extract high double. */ ++#define ldbl_high(x) ((double) x) ++ + /* Convert a finite long double to canonical form. + Does not handle +/-Inf properly. */ + static inline void diff --git a/SOURCES/glibc-ppc64le-01.patch b/SOURCES/glibc-ppc64le-01.patch new file mode 100644 index 00000000..a8a38883 --- /dev/null +++ b/SOURCES/glibc-ppc64le-01.patch @@ -0,0 +1,83 @@ +# commit 1695c7737655241e1773bdddc93e82c22d8d1584 +# Author: Adhemerval Zanella +# Date: Tue Feb 4 09:48:47 2014 -0200 +# +# abilist-pattern configurability +# +# This patch creates implicit rules to match the abifiles if +# abilist-pattern is defined in the architecture Makefile. This allows +# machine specific Makefiles to define different abifiles names +# (for instance *-le.abilist for powerpc64le). +# +diff -urN glibc-2.17-c758a686/Makerules glibc-2.17-c758a686/Makerules +--- glibc-2.17-c758a686/Makerules 2014-06-02 15:29:42.000000000 +0000 ++++ glibc-2.17-c758a686/Makerules 2014-06-02 15:25:21.000000000 +0000 +@@ -1152,6 +1152,14 @@ + LC_ALL=C $(OBJDUMP) --dynamic-syms $< > $@T + mv -f $@T $@ + ++# A sysdeps/.../Makefile can set abilist-pattern to something like ++# %-foo.abilist to look for libc-foo.abilist instead of libc.abilist. ++# This makes sense if multiple ABIs can be most cleanly supported by a ++# configuration without using separate sysdeps directories for each. ++ifdef abilist-pattern ++vpath $(abilist-pattern) $(+sysdep_dirs) ++endif ++ + vpath %.abilist $(+sysdep_dirs) + + # The .PRECIOUS rule prevents the files built by an implicit rule whose +@@ -1161,18 +1169,42 @@ + .PRECIOUS: %.symlist + generated += $(extra-libs:=.symlist) + ++ifdef abilist-pattern ++check-abi-%: $(common-objpfx)config.make $(abilist-pattern) $(objpfx)%.symlist ++ $(check-abi-pattern) ++check-abi-%: $(common-objpfx)config.make $(abilist-pattern) \ ++ $(common-objpfx)%.symlist ++ $(check-abi-pattern) ++endif + check-abi-%: $(common-objpfx)config.make %.abilist $(objpfx)%.symlist + $(check-abi) + check-abi-%: $(common-objpfx)config.make %.abilist $(common-objpfx)%.symlist + $(check-abi) ++define check-abi-pattern ++ diff -p -U 0 $(filter $(abilist-pattern),$^) $(filter %.symlist,$^) ++endef + define check-abi + diff -p -U 0 $(filter %.abilist,$^) $(filter %.symlist,$^) + endef + ++ifdef abilist-pattern ++update-abi-%: $(objpfx)%.symlist $(abilist-pattern) ++ $(update-abi-pattern) ++update-abi-%: $(common-objpfx)%.symlist $(abilist-pattern) ++ $(update-abi-pattern) ++endif + update-abi-%: $(objpfx)%.symlist %.abilist + $(update-abi) + update-abi-%: $(common-objpfx)%.symlist %.abilist + $(update-abi) ++define update-abi-pattern ++@if cmp -s $^ 2> /dev/null; \ ++ then \ ++ echo '+++ $(filter $(abilist-pattern),$^) is unchanged'; \ ++ else cp -f $^; \ ++ echo '*** Now check $(filter $(abilist-pattern),$^) changes for correctness ***'; \ ++ fi ++endef + define update-abi + @if cmp -s $^ 2> /dev/null; \ + then \ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/Makefile glibc-2.17-c758a686/sysdeps/powerpc/Makefile +--- glibc-2.17-c758a686/sysdeps/powerpc/Makefile 2014-06-02 15:29:42.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/powerpc/Makefile 2014-06-02 15:25:21.000000000 +0000 +@@ -27,3 +27,7 @@ + sysdep_headers += sys/platform/ppc.h + tests += test-gettimebase + endif ++ ++ifneq (,$(filter %le,$(config-machine))) ++abilist-pattern = %-le.abilist ++endif diff --git a/SOURCES/glibc-ppc64le-02.patch b/SOURCES/glibc-ppc64le-02.patch new file mode 100644 index 00000000..268f7930 --- /dev/null +++ b/SOURCES/glibc-ppc64le-02.patch @@ -0,0 +1,3197 @@ +# co`mmit c01603f763003cec55234ac757c7a934652caa55 +# Author: Adhemerval Zanella +# Date: Tue Feb 4 09:49:34 2014 -0200 +# +# PowerPC: powerpc64le abilist for 2.17 +# +# This patch is the abifiles for powerpc64le based on GLIBC 2.17. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/ld-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,11 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ __libc_memalign F ++ __libc_stack_end D 0x8 ++ __tls_get_addr F ++ _dl_mcount F ++ _r_debug D 0x28 ++ calloc F ++ free F ++ malloc F ++ realloc F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libBrokenLocale-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,3 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ __ctype_get_mb_cur_max F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libanl-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,6 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ gai_cancel F ++ gai_error F ++ gai_suspend F ++ getaddrinfo_a F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libc-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,2168 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ _Exit F ++ _IO_2_1_stderr_ D 0xe0 ++ _IO_2_1_stdin_ D 0xe0 ++ _IO_2_1_stdout_ D 0xe0 ++ _IO_adjust_column F ++ _IO_adjust_wcolumn F ++ _IO_default_doallocate F ++ _IO_default_finish F ++ _IO_default_pbackfail F ++ _IO_default_uflow F ++ _IO_default_xsgetn F ++ _IO_default_xsputn F ++ _IO_do_write F ++ _IO_doallocbuf F ++ _IO_fclose F ++ _IO_fdopen F ++ _IO_feof F ++ _IO_ferror F ++ _IO_fflush F ++ _IO_fgetpos F ++ _IO_fgetpos64 F ++ _IO_fgets F ++ _IO_file_attach F ++ _IO_file_close F ++ _IO_file_close_it F ++ _IO_file_doallocate F ++ _IO_file_finish F ++ _IO_file_fopen F ++ _IO_file_init F ++ _IO_file_jumps D 0xa8 ++ _IO_file_open F ++ _IO_file_overflow F ++ _IO_file_read F ++ _IO_file_seek F ++ _IO_file_seekoff F ++ _IO_file_setbuf F ++ _IO_file_stat F ++ _IO_file_sync F ++ _IO_file_underflow F ++ _IO_file_write F ++ _IO_file_xsputn F ++ _IO_flockfile F ++ _IO_flush_all F ++ _IO_flush_all_linebuffered F ++ _IO_fopen F ++ _IO_fprintf F ++ _IO_fputs F ++ _IO_fread F ++ _IO_free_backup_area F ++ _IO_free_wbackup_area F ++ _IO_fsetpos F ++ _IO_fsetpos64 F ++ _IO_ftell F ++ _IO_ftrylockfile F ++ _IO_funlockfile F ++ _IO_fwrite F ++ _IO_getc F ++ _IO_getline F ++ _IO_getline_info F ++ _IO_gets F ++ _IO_init F ++ _IO_init_marker F ++ _IO_init_wmarker F ++ _IO_iter_begin F ++ _IO_iter_end F ++ _IO_iter_file F ++ _IO_iter_next F ++ _IO_least_wmarker F ++ _IO_link_in F ++ _IO_list_all D 0x8 ++ _IO_list_lock F ++ _IO_list_resetlock F ++ _IO_list_unlock F ++ _IO_marker_delta F ++ _IO_marker_difference F ++ _IO_padn F ++ _IO_peekc_locked F ++ _IO_popen F ++ _IO_printf F ++ _IO_proc_close F ++ _IO_proc_open F ++ _IO_putc F ++ _IO_puts F ++ _IO_remove_marker F ++ _IO_seekmark F ++ _IO_seekoff F ++ _IO_seekpos F ++ _IO_seekwmark F ++ _IO_setb F ++ _IO_setbuffer F ++ _IO_setvbuf F ++ _IO_sgetn F ++ _IO_sprintf F ++ _IO_sputbackc F ++ _IO_sputbackwc F ++ _IO_sscanf F ++ _IO_str_init_readonly F ++ _IO_str_init_static F ++ _IO_str_overflow F ++ _IO_str_pbackfail F ++ _IO_str_seekoff F ++ _IO_str_underflow F ++ _IO_sungetc F ++ _IO_sungetwc F ++ _IO_switch_to_get_mode F ++ _IO_switch_to_main_wget_area F ++ _IO_switch_to_wbackup_area F ++ _IO_switch_to_wget_mode F ++ _IO_un_link F ++ _IO_ungetc F ++ _IO_unsave_markers F ++ _IO_unsave_wmarkers F ++ _IO_vfprintf F ++ _IO_vfscanf F ++ _IO_vsprintf F ++ _IO_wdefault_doallocate F ++ _IO_wdefault_finish F ++ _IO_wdefault_pbackfail F ++ _IO_wdefault_uflow F ++ _IO_wdefault_xsgetn F ++ _IO_wdefault_xsputn F ++ _IO_wdo_write F ++ _IO_wdoallocbuf F ++ _IO_wfile_jumps D 0xa8 ++ _IO_wfile_overflow F ++ _IO_wfile_seekoff F ++ _IO_wfile_sync F ++ _IO_wfile_underflow F ++ _IO_wfile_xsputn F ++ _IO_wmarker_delta F ++ _IO_wsetb F ++ __adjtimex F ++ __after_morecore_hook D 0x8 ++ __argz_count F ++ __argz_next F ++ __argz_stringify F ++ __asprintf F ++ __asprintf_chk F ++ __assert F ++ __assert_fail F ++ __assert_perror_fail F ++ __backtrace F ++ __backtrace_symbols F ++ __backtrace_symbols_fd F ++ __bsd_getpgrp F ++ __bzero F ++ __check_rhosts_file D 0x4 ++ __chk_fail F ++ __clone F ++ __close F ++ __cmsg_nxthdr F ++ __confstr_chk F ++ __connect F ++ __ctype_b_loc F ++ __ctype_get_mb_cur_max F ++ __ctype_tolower_loc F ++ __ctype_toupper_loc F ++ __curbrk D 0x8 ++ __cxa_at_quick_exit F ++ __cxa_atexit F ++ __cxa_finalize F ++ __cyg_profile_func_enter F ++ __cyg_profile_func_exit F ++ __daylight D 0x4 ++ __dcgettext F ++ __default_morecore F ++ __dgettext F ++ __dprintf_chk F ++ __dup2 F ++ __duplocale F ++ __endmntent F ++ __environ D 0x8 ++ __errno_location F ++ __fbufsize F ++ __fcntl F ++ __fdelt_chk F ++ __fdelt_warn F ++ __ffs F ++ __fgets_chk F ++ __fgets_unlocked_chk F ++ __fgetws_chk F ++ __fgetws_unlocked_chk F ++ __finite F ++ __finitef F ++ __finitel F ++ __flbf F ++ __fork F ++ __fpending F ++ __fprintf_chk F ++ __fpu_control D 0x4 ++ __fpurge F ++ __fread_chk F ++ __fread_unlocked_chk F ++ __freadable F ++ __freading F ++ __free_hook D 0x8 ++ __freelocale F ++ __fsetlocking F ++ __fwprintf_chk F ++ __fwritable F ++ __fwriting F ++ __fxstat F ++ __fxstat64 F ++ __fxstatat F ++ __fxstatat64 F ++ __getauxval F ++ __getcwd_chk F ++ __getdelim F ++ __getdomainname_chk F ++ __getgroups_chk F ++ __gethostname_chk F ++ __getlogin_r_chk F ++ __getmntent_r F ++ __getpagesize F ++ __getpgid F ++ __getpid F ++ __gets_chk F ++ __gettimeofday F ++ __getwd_chk F ++ __gmtime_r F ++ __h_errno_location F ++ __isalnum_l F ++ __isalpha_l F ++ __isascii_l F ++ __isblank_l F ++ __iscntrl_l F ++ __isctype F ++ __isdigit_l F ++ __isgraph_l F ++ __isinf F ++ __isinff F ++ __isinfl F ++ __islower_l F ++ __isnan F ++ __isnanf F ++ __isnanl F ++ __isoc99_fscanf F ++ __isoc99_fwscanf F ++ __isoc99_scanf F ++ __isoc99_sscanf F ++ __isoc99_swscanf F ++ __isoc99_vfscanf F ++ __isoc99_vfwscanf F ++ __isoc99_vscanf F ++ __isoc99_vsscanf F ++ __isoc99_vswscanf F ++ __isoc99_vwscanf F ++ __isoc99_wscanf F ++ __isprint_l F ++ __ispunct_l F ++ __isspace_l F ++ __isupper_l F ++ __iswalnum_l F ++ __iswalpha_l F ++ __iswblank_l F ++ __iswcntrl_l F ++ __iswctype F ++ __iswctype_l F ++ __iswdigit_l F ++ __iswgraph_l F ++ __iswlower_l F ++ __iswprint_l F ++ __iswpunct_l F ++ __iswspace_l F ++ __iswupper_l F ++ __iswxdigit_l F ++ __isxdigit_l F ++ __ivaliduser F ++ __key_decryptsession_pk_LOCAL D 0x8 ++ __key_encryptsession_pk_LOCAL D 0x8 ++ __key_gendes_LOCAL D 0x8 ++ __libc_allocate_rtsig F ++ __libc_calloc F ++ __libc_current_sigrtmax F ++ __libc_current_sigrtmin F ++ __libc_free F ++ __libc_freeres F ++ __libc_init_first F ++ __libc_mallinfo F ++ __libc_malloc F ++ __libc_mallopt F ++ __libc_memalign F ++ __libc_pvalloc F ++ __libc_realloc F ++ __libc_sa_len F ++ __libc_start_main F ++ __libc_valloc F ++ __longjmp_chk F ++ __lseek F ++ __lxstat F ++ __lxstat64 F ++ __malloc_hook D 0x8 ++ __malloc_initialize_hook D 0x8 ++ __mbrlen F ++ __mbrtowc F ++ __mbsnrtowcs_chk F ++ __mbsrtowcs_chk F ++ __mbstowcs_chk F ++ __memalign_hook D 0x8 ++ __memcpy_chk F ++ __memmove_chk F ++ __mempcpy F ++ __mempcpy_chk F ++ __mempcpy_small F ++ __memset_chk F ++ __monstartup F ++ __morecore D 0x8 ++ __nanosleep F ++ __newlocale F ++ __nl_langinfo_l F ++ __nldbl__IO_fprintf F ++ __nldbl__IO_printf F ++ __nldbl__IO_sprintf F ++ __nldbl__IO_sscanf F ++ __nldbl__IO_vfprintf F ++ __nldbl__IO_vfscanf F ++ __nldbl__IO_vsprintf F ++ __nldbl___asprintf F ++ __nldbl___asprintf_chk F ++ __nldbl___dprintf_chk F ++ __nldbl___fprintf_chk F ++ __nldbl___fwprintf_chk F ++ __nldbl___isoc99_fscanf F ++ __nldbl___isoc99_fwscanf F ++ __nldbl___isoc99_scanf F ++ __nldbl___isoc99_sscanf F ++ __nldbl___isoc99_swscanf F ++ __nldbl___isoc99_vfscanf F ++ __nldbl___isoc99_vfwscanf F ++ __nldbl___isoc99_vscanf F ++ __nldbl___isoc99_vsscanf F ++ __nldbl___isoc99_vswscanf F ++ __nldbl___isoc99_vwscanf F ++ __nldbl___isoc99_wscanf F ++ __nldbl___obstack_printf_chk F ++ __nldbl___obstack_vprintf_chk F ++ __nldbl___printf_chk F ++ __nldbl___printf_fp F ++ __nldbl___snprintf_chk F ++ __nldbl___sprintf_chk F ++ __nldbl___strfmon_l F ++ __nldbl___swprintf_chk F ++ __nldbl___syslog_chk F ++ __nldbl___vasprintf_chk F ++ __nldbl___vdprintf_chk F ++ __nldbl___vfprintf_chk F ++ __nldbl___vfscanf F ++ __nldbl___vfwprintf_chk F ++ __nldbl___vprintf_chk F ++ __nldbl___vsnprintf F ++ __nldbl___vsnprintf_chk F ++ __nldbl___vsprintf_chk F ++ __nldbl___vsscanf F ++ __nldbl___vstrfmon F ++ __nldbl___vstrfmon_l F ++ __nldbl___vswprintf_chk F ++ __nldbl___vsyslog_chk F ++ __nldbl___vwprintf_chk F ++ __nldbl___wprintf_chk F ++ __nldbl_asprintf F ++ __nldbl_dprintf F ++ __nldbl_fprintf F ++ __nldbl_fscanf F ++ __nldbl_fwprintf F ++ __nldbl_fwscanf F ++ __nldbl_obstack_printf F ++ __nldbl_obstack_vprintf F ++ __nldbl_printf F ++ __nldbl_printf_size F ++ __nldbl_scanf F ++ __nldbl_snprintf F ++ __nldbl_sprintf F ++ __nldbl_sscanf F ++ __nldbl_strfmon F ++ __nldbl_strfmon_l F ++ __nldbl_swprintf F ++ __nldbl_swscanf F ++ __nldbl_syslog F ++ __nldbl_vasprintf F ++ __nldbl_vdprintf F ++ __nldbl_vfprintf F ++ __nldbl_vfscanf F ++ __nldbl_vfwprintf F ++ __nldbl_vfwscanf F ++ __nldbl_vprintf F ++ __nldbl_vscanf F ++ __nldbl_vsnprintf F ++ __nldbl_vsprintf F ++ __nldbl_vsscanf F ++ __nldbl_vswprintf F ++ __nldbl_vswscanf F ++ __nldbl_vsyslog F ++ __nldbl_vwprintf F ++ __nldbl_vwscanf F ++ __nldbl_wprintf F ++ __nldbl_wscanf F ++ __nss_configure_lookup F ++ __nss_database_lookup F ++ __nss_group_lookup F ++ __nss_hostname_digits_dots F ++ __nss_hosts_lookup F ++ __nss_next F ++ __nss_passwd_lookup F ++ __obstack_printf_chk F ++ __obstack_vprintf_chk F ++ __open F ++ __open64 F ++ __open64_2 F ++ __open_2 F ++ __openat64_2 F ++ __openat_2 F ++ __overflow F ++ __pipe F ++ __poll F ++ __poll_chk F ++ __posix_getopt F ++ __ppc_get_timebase_freq F ++ __ppoll_chk F ++ __pread64 F ++ __pread64_chk F ++ __pread_chk F ++ __printf_chk F ++ __printf_fp F ++ __profile_frequency F ++ __progname D 0x8 ++ __progname_full D 0x8 ++ __ptsname_r_chk F ++ __pwrite64 F ++ __rawmemchr F ++ __rcmd_errstr D 0x8 ++ __read F ++ __read_chk F ++ __readlink_chk F ++ __readlinkat_chk F ++ __realloc_hook D 0x8 ++ __realpath_chk F ++ __recv_chk F ++ __recvfrom_chk F ++ __register_atfork F ++ __res_init F ++ __res_nclose F ++ __res_ninit F ++ __res_randomid F ++ __res_state F ++ __rpc_thread_createerr F ++ __rpc_thread_svc_fdset F ++ __rpc_thread_svc_max_pollfd F ++ __rpc_thread_svc_pollfd F ++ __sbrk F ++ __sched_cpualloc F ++ __sched_cpucount F ++ __sched_cpufree F ++ __sched_get_priority_max F ++ __sched_get_priority_min F ++ __sched_getparam F ++ __sched_getscheduler F ++ __sched_setscheduler F ++ __sched_yield F ++ __select F ++ __send F ++ __setmntent F ++ __setpgid F ++ __sigaction F ++ __sigaddset F ++ __sigdelset F ++ __sigismember F ++ __signbit F ++ __signbitf F ++ __signbitl F ++ __sigpause F ++ __sigsetjmp F ++ __sigsuspend F ++ __snprintf_chk F ++ __sprintf_chk F ++ __stack_chk_fail F ++ __statfs F ++ __stpcpy F ++ __stpcpy_chk F ++ __stpcpy_small F ++ __stpncpy F ++ __stpncpy_chk F ++ __strcasecmp F ++ __strcasecmp_l F ++ __strcasestr F ++ __strcat_chk F ++ __strcoll_l F ++ __strcpy_chk F ++ __strcpy_small F ++ __strcspn_c1 F ++ __strcspn_c2 F ++ __strcspn_c3 F ++ __strdup F ++ __strerror_r F ++ __strfmon_l F ++ __strftime_l F ++ __strncasecmp_l F ++ __strncat_chk F ++ __strncpy_chk F ++ __strndup F ++ __strpbrk_c2 F ++ __strpbrk_c3 F ++ __strsep_1c F ++ __strsep_2c F ++ __strsep_3c F ++ __strsep_g F ++ __strspn_c1 F ++ __strspn_c2 F ++ __strspn_c3 F ++ __strtod_internal F ++ __strtod_l F ++ __strtof_internal F ++ __strtof_l F ++ __strtok_r F ++ __strtok_r_1c F ++ __strtol_internal F ++ __strtol_l F ++ __strtold_internal F ++ __strtold_l F ++ __strtoll_internal F ++ __strtoll_l F ++ __strtoul_internal F ++ __strtoul_l F ++ __strtoull_internal F ++ __strtoull_l F ++ __strverscmp F ++ __strxfrm_l F ++ __swprintf_chk F ++ __sysconf F ++ __sysctl F ++ __syslog_chk F ++ __sysv_signal F ++ __timezone D 0x8 ++ __toascii_l F ++ __tolower_l F ++ __toupper_l F ++ __towctrans F ++ __towctrans_l F ++ __towlower_l F ++ __towupper_l F ++ __ttyname_r_chk F ++ __tzname D 0x10 ++ __uflow F ++ __underflow F ++ __uselocale F ++ __vasprintf_chk F ++ __vdprintf_chk F ++ __vfork F ++ __vfprintf_chk F ++ __vfscanf F ++ __vfwprintf_chk F ++ __vprintf_chk F ++ __vsnprintf F ++ __vsnprintf_chk F ++ __vsprintf_chk F ++ __vsscanf F ++ __vswprintf_chk F ++ __vsyslog_chk F ++ __vwprintf_chk F ++ __wait F ++ __waitpid F ++ __wcpcpy_chk F ++ __wcpncpy_chk F ++ __wcrtomb_chk F ++ __wcscasecmp_l F ++ __wcscat_chk F ++ __wcscoll_l F ++ __wcscpy_chk F ++ __wcsftime_l F ++ __wcsncasecmp_l F ++ __wcsncat_chk F ++ __wcsncpy_chk F ++ __wcsnrtombs_chk F ++ __wcsrtombs_chk F ++ __wcstod_internal F ++ __wcstod_l F ++ __wcstof_internal F ++ __wcstof_l F ++ __wcstol_internal F ++ __wcstol_l F ++ __wcstold_internal F ++ __wcstold_l F ++ __wcstoll_internal F ++ __wcstoll_l F ++ __wcstombs_chk F ++ __wcstoul_internal F ++ __wcstoul_l F ++ __wcstoull_internal F ++ __wcstoull_l F ++ __wcsxfrm_l F ++ __wctomb_chk F ++ __wctrans_l F ++ __wctype_l F ++ __wmemcpy_chk F ++ __wmemmove_chk F ++ __wmempcpy_chk F ++ __wmemset_chk F ++ __woverflow F ++ __wprintf_chk F ++ __write F ++ __wuflow F ++ __wunderflow F ++ __xmknod F ++ __xmknodat F ++ __xpg_basename F ++ __xpg_sigpause F ++ __xpg_strerror_r F ++ __xstat F ++ __xstat64 F ++ _authenticate F ++ _dl_mcount_wrapper F ++ _dl_mcount_wrapper_check F ++ _environ D 0x8 ++ _exit F ++ _flushlbf F ++ _libc_intl_domainname D 0x5 ++ _longjmp F ++ _mcleanup F ++ _mcount F ++ _nl_default_dirname D 0x12 ++ _nl_domain_bindings D 0x8 ++ _nl_msg_cat_cntr D 0x4 ++ _null_auth D 0x18 ++ _obstack_allocated_p F ++ _obstack_begin F ++ _obstack_begin_1 F ++ _obstack_free F ++ _obstack_memory_used F ++ _obstack_newchunk F ++ _res D 0x238 ++ _res_hconf D 0x48 ++ _rpc_dtablesize F ++ _seterr_reply F ++ _setjmp F ++ _sys_errlist D 0x438 ++ _sys_nerr D 0x4 ++ _sys_siglist D 0x208 ++ _tolower F ++ _toupper F ++ a64l F ++ abort F ++ abs F ++ accept F ++ accept4 F ++ access F ++ acct F ++ addmntent F ++ addseverity F ++ adjtime F ++ adjtimex F ++ advance F ++ alarm F ++ aligned_alloc F ++ alphasort F ++ alphasort64 F ++ argp_err_exit_status D 0x4 ++ argp_error F ++ argp_failure F ++ argp_help F ++ argp_parse F ++ argp_program_bug_address D 0x8 ++ argp_program_version D 0x8 ++ argp_program_version_hook D 0x8 ++ argp_state_help F ++ argp_usage F ++ argz_add F ++ argz_add_sep F ++ argz_append F ++ argz_count F ++ argz_create F ++ argz_create_sep F ++ argz_delete F ++ argz_extract F ++ argz_insert F ++ argz_next F ++ argz_replace F ++ argz_stringify F ++ asctime F ++ asctime_r F ++ asprintf F ++ atof F ++ atoi F ++ atol F ++ atoll F ++ authdes_create F ++ authdes_getucred F ++ authdes_pk_create F ++ authnone_create F ++ authunix_create F ++ authunix_create_default F ++ backtrace F ++ backtrace_symbols F ++ backtrace_symbols_fd F ++ basename F ++ bcmp F ++ bcopy F ++ bdflush F ++ bind F ++ bind_textdomain_codeset F ++ bindresvport F ++ bindtextdomain F ++ brk F ++ bsd_signal F ++ bsearch F ++ btowc F ++ bzero F ++ c16rtomb F ++ c32rtomb F ++ calloc F ++ callrpc F ++ canonicalize_file_name F ++ capget F ++ capset F ++ catclose F ++ catgets F ++ catopen F ++ cbc_crypt F ++ cfgetispeed F ++ cfgetospeed F ++ cfmakeraw F ++ cfree F ++ cfsetispeed F ++ cfsetospeed F ++ cfsetspeed F ++ chdir F ++ chflags F ++ chmod F ++ chown F ++ chroot F ++ clearenv F ++ clearerr F ++ clearerr_unlocked F ++ clnt_broadcast F ++ clnt_create F ++ clnt_pcreateerror F ++ clnt_perrno F ++ clnt_perror F ++ clnt_spcreateerror F ++ clnt_sperrno F ++ clnt_sperror F ++ clntraw_create F ++ clnttcp_create F ++ clntudp_bufcreate F ++ clntudp_create F ++ clntunix_create F ++ clock F ++ clock_adjtime F ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ clone F ++ close F ++ closedir F ++ closelog F ++ confstr F ++ connect F ++ copysign F ++ copysignf F ++ copysignl F ++ creat F ++ creat64 F ++ create_module F ++ ctermid F ++ ctime F ++ ctime_r F ++ cuserid F ++ daemon F ++ daylight D 0x4 ++ dcgettext F ++ dcngettext F ++ delete_module F ++ des_setparity F ++ dgettext F ++ difftime F ++ dirfd F ++ dirname F ++ div F ++ dl_iterate_phdr F ++ dngettext F ++ dprintf F ++ drand48 F ++ drand48_r F ++ dup F ++ dup2 F ++ dup3 F ++ duplocale F ++ dysize F ++ eaccess F ++ ecb_crypt F ++ ecvt F ++ ecvt_r F ++ endaliasent F ++ endfsent F ++ endgrent F ++ endhostent F ++ endmntent F ++ endnetent F ++ endnetgrent F ++ endprotoent F ++ endpwent F ++ endrpcent F ++ endservent F ++ endsgent F ++ endspent F ++ endttyent F ++ endusershell F ++ endutent F ++ endutxent F ++ environ D 0x8 ++ envz_add F ++ envz_entry F ++ envz_get F ++ envz_merge F ++ envz_remove F ++ envz_strip F ++ epoll_create F ++ epoll_create1 F ++ epoll_ctl F ++ epoll_pwait F ++ epoll_wait F ++ erand48 F ++ erand48_r F ++ err F ++ error F ++ error_at_line F ++ error_message_count D 0x4 ++ error_one_per_line D 0x4 ++ error_print_progname D 0x8 ++ errx F ++ ether_aton F ++ ether_aton_r F ++ ether_hostton F ++ ether_line F ++ ether_ntoa F ++ ether_ntoa_r F ++ ether_ntohost F ++ euidaccess F ++ eventfd F ++ eventfd_read F ++ eventfd_write F ++ execl F ++ execle F ++ execlp F ++ execv F ++ execve F ++ execvp F ++ execvpe F ++ exit F ++ faccessat F ++ fallocate F ++ fallocate64 F ++ fanotify_init F ++ fanotify_mark F ++ fattach F ++ fchdir F ++ fchflags F ++ fchmod F ++ fchmodat F ++ fchown F ++ fchownat F ++ fclose F ++ fcloseall F ++ fcntl F ++ fcvt F ++ fcvt_r F ++ fdatasync F ++ fdetach F ++ fdopen F ++ fdopendir F ++ feof F ++ feof_unlocked F ++ ferror F ++ ferror_unlocked F ++ fexecve F ++ fflush F ++ fflush_unlocked F ++ ffs F ++ ffsl F ++ ffsll F ++ fgetc F ++ fgetc_unlocked F ++ fgetgrent F ++ fgetgrent_r F ++ fgetpos F ++ fgetpos64 F ++ fgetpwent F ++ fgetpwent_r F ++ fgets F ++ fgets_unlocked F ++ fgetsgent F ++ fgetsgent_r F ++ fgetspent F ++ fgetspent_r F ++ fgetwc F ++ fgetwc_unlocked F ++ fgetws F ++ fgetws_unlocked F ++ fgetxattr F ++ fileno F ++ fileno_unlocked F ++ finite F ++ finitef F ++ finitel F ++ flistxattr F ++ flock F ++ flockfile F ++ fmemopen F ++ fmtmsg F ++ fnmatch F ++ fopen F ++ fopen64 F ++ fopencookie F ++ fork F ++ fpathconf F ++ fprintf F ++ fputc F ++ fputc_unlocked F ++ fputs F ++ fputs_unlocked F ++ fputwc F ++ fputwc_unlocked F ++ fputws F ++ fputws_unlocked F ++ fread F ++ fread_unlocked F ++ free F ++ freeaddrinfo F ++ freeifaddrs F ++ freelocale F ++ fremovexattr F ++ freopen F ++ freopen64 F ++ frexp F ++ frexpf F ++ frexpl F ++ fscanf F ++ fseek F ++ fseeko F ++ fseeko64 F ++ fsetpos F ++ fsetpos64 F ++ fsetxattr F ++ fstatfs F ++ fstatfs64 F ++ fstatvfs F ++ fstatvfs64 F ++ fsync F ++ ftell F ++ ftello F ++ ftello64 F ++ ftime F ++ ftok F ++ ftruncate F ++ ftruncate64 F ++ ftrylockfile F ++ fts_children F ++ fts_close F ++ fts_open F ++ fts_read F ++ fts_set F ++ ftw F ++ ftw64 F ++ funlockfile F ++ futimens F ++ futimes F ++ futimesat F ++ fwide F ++ fwprintf F ++ fwrite F ++ fwrite_unlocked F ++ fwscanf F ++ gai_strerror F ++ gcvt F ++ get_avphys_pages F ++ get_current_dir_name F ++ get_kernel_syms F ++ get_myaddress F ++ get_nprocs F ++ get_nprocs_conf F ++ get_phys_pages F ++ getaddrinfo F ++ getaliasbyname F ++ getaliasbyname_r F ++ getaliasent F ++ getaliasent_r F ++ getauxval F ++ getc F ++ getc_unlocked F ++ getchar F ++ getchar_unlocked F ++ getcontext F ++ getcwd F ++ getdate F ++ getdate_err D 0x4 ++ getdate_r F ++ getdelim F ++ getdirentries F ++ getdirentries64 F ++ getdomainname F ++ getdtablesize F ++ getegid F ++ getenv F ++ geteuid F ++ getfsent F ++ getfsfile F ++ getfsspec F ++ getgid F ++ getgrent F ++ getgrent_r F ++ getgrgid F ++ getgrgid_r F ++ getgrnam F ++ getgrnam_r F ++ getgrouplist F ++ getgroups F ++ gethostbyaddr F ++ gethostbyaddr_r F ++ gethostbyname F ++ gethostbyname2 F ++ gethostbyname2_r F ++ gethostbyname_r F ++ gethostent F ++ gethostent_r F ++ gethostid F ++ gethostname F ++ getifaddrs F ++ getipv4sourcefilter F ++ getitimer F ++ getline F ++ getloadavg F ++ getlogin F ++ getlogin_r F ++ getmntent F ++ getmntent_r F ++ getmsg F ++ getnameinfo F ++ getnetbyaddr F ++ getnetbyaddr_r F ++ getnetbyname F ++ getnetbyname_r F ++ getnetent F ++ getnetent_r F ++ getnetgrent F ++ getnetgrent_r F ++ getnetname F ++ getopt F ++ getopt_long F ++ getopt_long_only F ++ getpagesize F ++ getpass F ++ getpeername F ++ getpgid F ++ getpgrp F ++ getpid F ++ getpmsg F ++ getppid F ++ getpriority F ++ getprotobyname F ++ getprotobyname_r F ++ getprotobynumber F ++ getprotobynumber_r F ++ getprotoent F ++ getprotoent_r F ++ getpt F ++ getpublickey F ++ getpw F ++ getpwent F ++ getpwent_r F ++ getpwnam F ++ getpwnam_r F ++ getpwuid F ++ getpwuid_r F ++ getresgid F ++ getresuid F ++ getrlimit F ++ getrlimit64 F ++ getrpcbyname F ++ getrpcbyname_r F ++ getrpcbynumber F ++ getrpcbynumber_r F ++ getrpcent F ++ getrpcent_r F ++ getrpcport F ++ getrusage F ++ gets F ++ getsecretkey F ++ getservbyname F ++ getservbyname_r F ++ getservbyport F ++ getservbyport_r F ++ getservent F ++ getservent_r F ++ getsgent F ++ getsgent_r F ++ getsgnam F ++ getsgnam_r F ++ getsid F ++ getsockname F ++ getsockopt F ++ getsourcefilter F ++ getspent F ++ getspent_r F ++ getspnam F ++ getspnam_r F ++ getsubopt F ++ gettext F ++ gettimeofday F ++ getttyent F ++ getttynam F ++ getuid F ++ getusershell F ++ getutent F ++ getutent_r F ++ getutid F ++ getutid_r F ++ getutline F ++ getutline_r F ++ getutmp F ++ getutmpx F ++ getutxent F ++ getutxid F ++ getutxline F ++ getw F ++ getwc F ++ getwc_unlocked F ++ getwchar F ++ getwchar_unlocked F ++ getwd F ++ getxattr F ++ glob F ++ glob64 F ++ glob_pattern_p F ++ globfree F ++ globfree64 F ++ gmtime F ++ gmtime_r F ++ gnu_dev_major F ++ gnu_dev_makedev F ++ gnu_dev_minor F ++ gnu_get_libc_release F ++ gnu_get_libc_version F ++ grantpt F ++ group_member F ++ gsignal F ++ gtty F ++ h_errlist D 0x28 ++ h_nerr D 0x4 ++ hasmntopt F ++ hcreate F ++ hcreate_r F ++ hdestroy F ++ hdestroy_r F ++ herror F ++ host2netname F ++ hsearch F ++ hsearch_r F ++ hstrerror F ++ htonl F ++ htons F ++ iconv F ++ iconv_close F ++ iconv_open F ++ if_freenameindex F ++ if_indextoname F ++ if_nameindex F ++ if_nametoindex F ++ imaxabs F ++ imaxdiv F ++ in6addr_any D 0x10 ++ in6addr_loopback D 0x10 ++ index F ++ inet6_opt_append F ++ inet6_opt_find F ++ inet6_opt_finish F ++ inet6_opt_get_val F ++ inet6_opt_init F ++ inet6_opt_next F ++ inet6_opt_set_val F ++ inet6_option_alloc F ++ inet6_option_append F ++ inet6_option_find F ++ inet6_option_init F ++ inet6_option_next F ++ inet6_option_space F ++ inet6_rth_add F ++ inet6_rth_getaddr F ++ inet6_rth_init F ++ inet6_rth_reverse F ++ inet6_rth_segments F ++ inet6_rth_space F ++ inet_addr F ++ inet_aton F ++ inet_lnaof F ++ inet_makeaddr F ++ inet_netof F ++ inet_network F ++ inet_nsap_addr F ++ inet_nsap_ntoa F ++ inet_ntoa F ++ inet_ntop F ++ inet_pton F ++ init_module F ++ initgroups F ++ initstate F ++ initstate_r F ++ innetgr F ++ inotify_add_watch F ++ inotify_init F ++ inotify_init1 F ++ inotify_rm_watch F ++ insque F ++ ioctl F ++ iruserok F ++ iruserok_af F ++ isalnum F ++ isalnum_l F ++ isalpha F ++ isalpha_l F ++ isascii F ++ isastream F ++ isatty F ++ isblank F ++ isblank_l F ++ iscntrl F ++ iscntrl_l F ++ isctype F ++ isdigit F ++ isdigit_l F ++ isfdtype F ++ isgraph F ++ isgraph_l F ++ isinf F ++ isinff F ++ isinfl F ++ islower F ++ islower_l F ++ isnan F ++ isnanf F ++ isnanl F ++ isprint F ++ isprint_l F ++ ispunct F ++ ispunct_l F ++ isspace F ++ isspace_l F ++ isupper F ++ isupper_l F ++ iswalnum F ++ iswalnum_l F ++ iswalpha F ++ iswalpha_l F ++ iswblank F ++ iswblank_l F ++ iswcntrl F ++ iswcntrl_l F ++ iswctype F ++ iswctype_l F ++ iswdigit F ++ iswdigit_l F ++ iswgraph F ++ iswgraph_l F ++ iswlower F ++ iswlower_l F ++ iswprint F ++ iswprint_l F ++ iswpunct F ++ iswpunct_l F ++ iswspace F ++ iswspace_l F ++ iswupper F ++ iswupper_l F ++ iswxdigit F ++ iswxdigit_l F ++ isxdigit F ++ isxdigit_l F ++ jrand48 F ++ jrand48_r F ++ key_decryptsession F ++ key_decryptsession_pk F ++ key_encryptsession F ++ key_encryptsession_pk F ++ key_gendes F ++ key_get_conv F ++ key_secretkey_is_set F ++ key_setnet F ++ key_setsecret F ++ kill F ++ killpg F ++ klogctl F ++ l64a F ++ labs F ++ lchmod F ++ lchown F ++ lckpwdf F ++ lcong48 F ++ lcong48_r F ++ ldexp F ++ ldexpf F ++ ldexpl F ++ ldiv F ++ lfind F ++ lgetxattr F ++ link F ++ linkat F ++ listen F ++ listxattr F ++ llabs F ++ lldiv F ++ llistxattr F ++ llseek F ++ loc1 D 0x8 ++ loc2 D 0x8 ++ localeconv F ++ localtime F ++ localtime_r F ++ lockf F ++ lockf64 F ++ locs D 0x8 ++ longjmp F ++ lrand48 F ++ lrand48_r F ++ lremovexattr F ++ lsearch F ++ lseek F ++ lseek64 F ++ lsetxattr F ++ lutimes F ++ madvise F ++ makecontext F ++ mallinfo F ++ malloc F ++ malloc_get_state F ++ malloc_info F ++ malloc_set_state F ++ malloc_stats F ++ malloc_trim F ++ malloc_usable_size F ++ mallopt F ++ mallwatch D 0x8 ++ mblen F ++ mbrlen F ++ mbrtoc16 F ++ mbrtoc32 F ++ mbrtowc F ++ mbsinit F ++ mbsnrtowcs F ++ mbsrtowcs F ++ mbstowcs F ++ mbtowc F ++ mcheck F ++ mcheck_check_all F ++ mcheck_pedantic F ++ memalign F ++ memccpy F ++ memchr F ++ memcmp F ++ memcpy F ++ memfrob F ++ memmem F ++ memmove F ++ mempcpy F ++ memrchr F ++ memset F ++ mincore F ++ mkdir F ++ mkdirat F ++ mkdtemp F ++ mkfifo F ++ mkfifoat F ++ mkostemp F ++ mkostemp64 F ++ mkostemps F ++ mkostemps64 F ++ mkstemp F ++ mkstemp64 F ++ mkstemps F ++ mkstemps64 F ++ mktemp F ++ mktime F ++ mlock F ++ mlockall F ++ mmap F ++ mmap64 F ++ modf F ++ modff F ++ modfl F ++ moncontrol F ++ monstartup F ++ mount F ++ mprobe F ++ mprotect F ++ mrand48 F ++ mrand48_r F ++ mremap F ++ msgctl F ++ msgget F ++ msgrcv F ++ msgsnd F ++ msync F ++ mtrace F ++ munlock F ++ munlockall F ++ munmap F ++ muntrace F ++ name_to_handle_at F ++ nanosleep F ++ netname2host F ++ netname2user F ++ newlocale F ++ nfsservctl F ++ nftw F ++ nftw64 F ++ ngettext F ++ nice F ++ nl_langinfo F ++ nl_langinfo_l F ++ nrand48 F ++ nrand48_r F ++ ntohl F ++ ntohs F ++ ntp_adjtime F ++ ntp_gettime F ++ ntp_gettimex F ++ obstack_alloc_failed_handler D 0x8 ++ obstack_exit_failure D 0x4 ++ obstack_free F ++ obstack_printf F ++ obstack_vprintf F ++ on_exit F ++ open F ++ open64 F ++ open_by_handle_at F ++ open_memstream F ++ open_wmemstream F ++ openat F ++ openat64 F ++ opendir F ++ openlog F ++ optarg D 0x8 ++ opterr D 0x4 ++ optind D 0x4 ++ optopt D 0x4 ++ parse_printf_format F ++ passwd2des F ++ pathconf F ++ pause F ++ pclose F ++ perror F ++ personality F ++ pipe F ++ pipe2 F ++ pivot_root F ++ pmap_getmaps F ++ pmap_getport F ++ pmap_rmtcall F ++ pmap_set F ++ pmap_unset F ++ poll F ++ popen F ++ posix_fadvise F ++ posix_fadvise64 F ++ posix_fallocate F ++ posix_fallocate64 F ++ posix_madvise F ++ posix_memalign F ++ posix_openpt F ++ posix_spawn F ++ posix_spawn_file_actions_addclose F ++ posix_spawn_file_actions_adddup2 F ++ posix_spawn_file_actions_addopen F ++ posix_spawn_file_actions_destroy F ++ posix_spawn_file_actions_init F ++ posix_spawnattr_destroy F ++ posix_spawnattr_getflags F ++ posix_spawnattr_getpgroup F ++ posix_spawnattr_getschedparam F ++ posix_spawnattr_getschedpolicy F ++ posix_spawnattr_getsigdefault F ++ posix_spawnattr_getsigmask F ++ posix_spawnattr_init F ++ posix_spawnattr_setflags F ++ posix_spawnattr_setpgroup F ++ posix_spawnattr_setschedparam F ++ posix_spawnattr_setschedpolicy F ++ posix_spawnattr_setsigdefault F ++ posix_spawnattr_setsigmask F ++ posix_spawnp F ++ ppoll F ++ prctl F ++ pread F ++ pread64 F ++ preadv F ++ preadv64 F ++ printf F ++ printf_size F ++ printf_size_info F ++ prlimit F ++ prlimit64 F ++ process_vm_readv F ++ process_vm_writev F ++ profil F ++ program_invocation_name D 0x8 ++ program_invocation_short_name D 0x8 ++ pselect F ++ psiginfo F ++ psignal F ++ pthread_attr_destroy F ++ pthread_attr_getdetachstate F ++ pthread_attr_getinheritsched F ++ pthread_attr_getschedparam F ++ pthread_attr_getschedpolicy F ++ pthread_attr_getscope F ++ pthread_attr_init F ++ pthread_attr_setdetachstate F ++ pthread_attr_setinheritsched F ++ pthread_attr_setschedparam F ++ pthread_attr_setschedpolicy F ++ pthread_attr_setscope F ++ pthread_cond_broadcast F ++ pthread_cond_destroy F ++ pthread_cond_init F ++ pthread_cond_signal F ++ pthread_cond_timedwait F ++ pthread_cond_wait F ++ pthread_condattr_destroy F ++ pthread_condattr_init F ++ pthread_equal F ++ pthread_exit F ++ pthread_getschedparam F ++ pthread_mutex_destroy F ++ pthread_mutex_init F ++ pthread_mutex_lock F ++ pthread_mutex_unlock F ++ pthread_self F ++ pthread_setcancelstate F ++ pthread_setcanceltype F ++ pthread_setschedparam F ++ ptrace F ++ ptsname F ++ ptsname_r F ++ putc F ++ putc_unlocked F ++ putchar F ++ putchar_unlocked F ++ putenv F ++ putgrent F ++ putmsg F ++ putpmsg F ++ putpwent F ++ puts F ++ putsgent F ++ putspent F ++ pututline F ++ pututxline F ++ putw F ++ putwc F ++ putwc_unlocked F ++ putwchar F ++ putwchar_unlocked F ++ pvalloc F ++ pwrite F ++ pwrite64 F ++ pwritev F ++ pwritev64 F ++ qecvt F ++ qecvt_r F ++ qfcvt F ++ qfcvt_r F ++ qgcvt F ++ qsort F ++ qsort_r F ++ query_module F ++ quick_exit F ++ quotactl F ++ raise F ++ rand F ++ rand_r F ++ random F ++ random_r F ++ rawmemchr F ++ rcmd F ++ rcmd_af F ++ re_comp F ++ re_compile_fastmap F ++ re_compile_pattern F ++ re_exec F ++ re_match F ++ re_match_2 F ++ re_search F ++ re_search_2 F ++ re_set_registers F ++ re_set_syntax F ++ re_syntax_options D 0x8 ++ read F ++ readahead F ++ readdir F ++ readdir64 F ++ readdir64_r F ++ readdir_r F ++ readlink F ++ readlinkat F ++ readv F ++ realloc F ++ realpath F ++ reboot F ++ recv F ++ recvfrom F ++ recvmmsg F ++ recvmsg F ++ regcomp F ++ regerror F ++ regexec F ++ regfree F ++ register_printf_function F ++ register_printf_modifier F ++ register_printf_specifier F ++ register_printf_type F ++ registerrpc F ++ remap_file_pages F ++ remove F ++ removexattr F ++ remque F ++ rename F ++ renameat F ++ revoke F ++ rewind F ++ rewinddir F ++ rexec F ++ rexec_af F ++ rexecoptions D 0x4 ++ rindex F ++ rmdir F ++ rpc_createerr D 0x20 ++ rpmatch F ++ rresvport F ++ rresvport_af F ++ rtime F ++ ruserok F ++ ruserok_af F ++ ruserpass F ++ sbrk F ++ scalbn F ++ scalbnf F ++ scalbnl F ++ scandir F ++ scandir64 F ++ scandirat F ++ scandirat64 F ++ scanf F ++ sched_get_priority_max F ++ sched_get_priority_min F ++ sched_getaffinity F ++ sched_getcpu F ++ sched_getparam F ++ sched_getscheduler F ++ sched_rr_get_interval F ++ sched_setaffinity F ++ sched_setparam F ++ sched_setscheduler F ++ sched_yield F ++ secure_getenv F ++ seed48 F ++ seed48_r F ++ seekdir F ++ select F ++ semctl F ++ semget F ++ semop F ++ semtimedop F ++ send F ++ sendfile F ++ sendfile64 F ++ sendmmsg F ++ sendmsg F ++ sendto F ++ setaliasent F ++ setbuf F ++ setbuffer F ++ setcontext F ++ setdomainname F ++ setegid F ++ setenv F ++ seteuid F ++ setfsent F ++ setfsgid F ++ setfsuid F ++ setgid F ++ setgrent F ++ setgroups F ++ sethostent F ++ sethostid F ++ sethostname F ++ setipv4sourcefilter F ++ setitimer F ++ setjmp F ++ setlinebuf F ++ setlocale F ++ setlogin F ++ setlogmask F ++ setmntent F ++ setnetent F ++ setnetgrent F ++ setns F ++ setpgid F ++ setpgrp F ++ setpriority F ++ setprotoent F ++ setpwent F ++ setregid F ++ setresgid F ++ setresuid F ++ setreuid F ++ setrlimit F ++ setrlimit64 F ++ setrpcent F ++ setservent F ++ setsgent F ++ setsid F ++ setsockopt F ++ setsourcefilter F ++ setspent F ++ setstate F ++ setstate_r F ++ settimeofday F ++ setttyent F ++ setuid F ++ setusershell F ++ setutent F ++ setutxent F ++ setvbuf F ++ setxattr F ++ sgetsgent F ++ sgetsgent_r F ++ sgetspent F ++ sgetspent_r F ++ shmat F ++ shmctl F ++ shmdt F ++ shmget F ++ shutdown F ++ sigaction F ++ sigaddset F ++ sigaltstack F ++ sigandset F ++ sigblock F ++ sigdelset F ++ sigemptyset F ++ sigfillset F ++ siggetmask F ++ sighold F ++ sigignore F ++ siginterrupt F ++ sigisemptyset F ++ sigismember F ++ siglongjmp F ++ signal F ++ signalfd F ++ sigorset F ++ sigpause F ++ sigpending F ++ sigprocmask F ++ sigqueue F ++ sigrelse F ++ sigreturn F ++ sigset F ++ sigsetmask F ++ sigstack F ++ sigsuspend F ++ sigtimedwait F ++ sigvec F ++ sigwait F ++ sigwaitinfo F ++ sleep F ++ snprintf F ++ sockatmark F ++ socket F ++ socketpair F ++ splice F ++ sprintf F ++ sprofil F ++ srand F ++ srand48 F ++ srand48_r F ++ srandom F ++ srandom_r F ++ sscanf F ++ ssignal F ++ sstk F ++ statfs F ++ statfs64 F ++ statvfs F ++ statvfs64 F ++ stderr D 0x8 ++ stdin D 0x8 ++ stdout D 0x8 ++ step F ++ stime F ++ stpcpy F ++ stpncpy F ++ strcasecmp F ++ strcasecmp_l F ++ strcasestr F ++ strcat F ++ strchr F ++ strchrnul F ++ strcmp F ++ strcoll F ++ strcoll_l F ++ strcpy F ++ strcspn F ++ strdup F ++ strerror F ++ strerror_l F ++ strerror_r F ++ strfmon F ++ strfmon_l F ++ strfry F ++ strftime F ++ strftime_l F ++ strlen F ++ strncasecmp F ++ strncasecmp_l F ++ strncat F ++ strncmp F ++ strncpy F ++ strndup F ++ strnlen F ++ strpbrk F ++ strptime F ++ strptime_l F ++ strrchr F ++ strsep F ++ strsignal F ++ strspn F ++ strstr F ++ strtod F ++ strtod_l F ++ strtof F ++ strtof_l F ++ strtoimax F ++ strtok F ++ strtok_r F ++ strtol F ++ strtol_l F ++ strtold F ++ strtold_l F ++ strtoll F ++ strtoll_l F ++ strtoq F ++ strtoul F ++ strtoul_l F ++ strtoull F ++ strtoull_l F ++ strtoumax F ++ strtouq F ++ strverscmp F ++ strxfrm F ++ strxfrm_l F ++ stty F ++ svc_exit F ++ svc_fdset D 0x80 ++ svc_getreq F ++ svc_getreq_common F ++ svc_getreq_poll F ++ svc_getreqset F ++ svc_max_pollfd D 0x4 ++ svc_pollfd D 0x8 ++ svc_register F ++ svc_run F ++ svc_sendreply F ++ svc_unregister F ++ svcauthdes_stats D 0x18 ++ svcerr_auth F ++ svcerr_decode F ++ svcerr_noproc F ++ svcerr_noprog F ++ svcerr_progvers F ++ svcerr_systemerr F ++ svcerr_weakauth F ++ svcfd_create F ++ svcraw_create F ++ svctcp_create F ++ svcudp_bufcreate F ++ svcudp_create F ++ svcudp_enablecache F ++ svcunix_create F ++ svcunixfd_create F ++ swab F ++ swapcontext F ++ swapoff F ++ swapon F ++ swprintf F ++ swscanf F ++ symlink F ++ symlinkat F ++ sync F ++ sync_file_range F ++ syncfs F ++ sys_errlist D 0x438 ++ sys_nerr D 0x4 ++ sys_sigabbrev D 0x208 ++ sys_siglist D 0x208 ++ syscall F ++ sysconf F ++ sysctl F ++ sysinfo F ++ syslog F ++ system F ++ sysv_signal F ++ tcdrain F ++ tcflow F ++ tcflush F ++ tcgetattr F ++ tcgetpgrp F ++ tcgetsid F ++ tcsendbreak F ++ tcsetattr F ++ tcsetpgrp F ++ tdelete F ++ tdestroy F ++ tee F ++ telldir F ++ tempnam F ++ textdomain F ++ tfind F ++ time F ++ timegm F ++ timelocal F ++ timerfd_create F ++ timerfd_gettime F ++ timerfd_settime F ++ times F ++ timespec_get F ++ timezone D 0x8 ++ tmpfile F ++ tmpfile64 F ++ tmpnam F ++ tmpnam_r F ++ toascii F ++ tolower F ++ tolower_l F ++ toupper F ++ toupper_l F ++ towctrans F ++ towctrans_l F ++ towlower F ++ towlower_l F ++ towupper F ++ towupper_l F ++ tr_break F ++ truncate F ++ truncate64 F ++ tsearch F ++ ttyname F ++ ttyname_r F ++ ttyslot F ++ twalk F ++ tzname D 0x10 ++ tzset F ++ ualarm F ++ ulckpwdf F ++ ulimit F ++ umask F ++ umount F ++ umount2 F ++ uname F ++ ungetc F ++ ungetwc F ++ unlink F ++ unlinkat F ++ unlockpt F ++ unsetenv F ++ unshare F ++ updwtmp F ++ updwtmpx F ++ uselib F ++ uselocale F ++ user2netname F ++ usleep F ++ ustat F ++ utime F ++ utimensat F ++ utimes F ++ utmpname F ++ utmpxname F ++ valloc F ++ vasprintf F ++ vdprintf F ++ verr F ++ verrx F ++ versionsort F ++ versionsort64 F ++ vfork F ++ vfprintf F ++ vfscanf F ++ vfwprintf F ++ vfwscanf F ++ vhangup F ++ vlimit F ++ vmsplice F ++ vprintf F ++ vscanf F ++ vsnprintf F ++ vsprintf F ++ vsscanf F ++ vswprintf F ++ vswscanf F ++ vsyslog F ++ vtimes F ++ vwarn F ++ vwarnx F ++ vwprintf F ++ vwscanf F ++ wait F ++ wait3 F ++ wait4 F ++ waitid F ++ waitpid F ++ warn F ++ warnx F ++ wcpcpy F ++ wcpncpy F ++ wcrtomb F ++ wcscasecmp F ++ wcscasecmp_l F ++ wcscat F ++ wcschr F ++ wcschrnul F ++ wcscmp F ++ wcscoll F ++ wcscoll_l F ++ wcscpy F ++ wcscspn F ++ wcsdup F ++ wcsftime F ++ wcsftime_l F ++ wcslen F ++ wcsncasecmp F ++ wcsncasecmp_l F ++ wcsncat F ++ wcsncmp F ++ wcsncpy F ++ wcsnlen F ++ wcsnrtombs F ++ wcspbrk F ++ wcsrchr F ++ wcsrtombs F ++ wcsspn F ++ wcsstr F ++ wcstod F ++ wcstod_l F ++ wcstof F ++ wcstof_l F ++ wcstoimax F ++ wcstok F ++ wcstol F ++ wcstol_l F ++ wcstold F ++ wcstold_l F ++ wcstoll F ++ wcstoll_l F ++ wcstombs F ++ wcstoq F ++ wcstoul F ++ wcstoul_l F ++ wcstoull F ++ wcstoull_l F ++ wcstoumax F ++ wcstouq F ++ wcswcs F ++ wcswidth F ++ wcsxfrm F ++ wcsxfrm_l F ++ wctob F ++ wctomb F ++ wctrans F ++ wctrans_l F ++ wctype F ++ wctype_l F ++ wcwidth F ++ wmemchr F ++ wmemcmp F ++ wmemcpy F ++ wmemmove F ++ wmempcpy F ++ wmemset F ++ wordexp F ++ wordfree F ++ wprintf F ++ write F ++ writev F ++ wscanf F ++ xdecrypt F ++ xdr_accepted_reply F ++ xdr_array F ++ xdr_authdes_cred F ++ xdr_authdes_verf F ++ xdr_authunix_parms F ++ xdr_bool F ++ xdr_bytes F ++ xdr_callhdr F ++ xdr_callmsg F ++ xdr_char F ++ xdr_cryptkeyarg F ++ xdr_cryptkeyarg2 F ++ xdr_cryptkeyres F ++ xdr_des_block F ++ xdr_double F ++ xdr_enum F ++ xdr_float F ++ xdr_free F ++ xdr_getcredres F ++ xdr_hyper F ++ xdr_int F ++ xdr_int16_t F ++ xdr_int32_t F ++ xdr_int64_t F ++ xdr_int8_t F ++ xdr_key_netstarg F ++ xdr_key_netstres F ++ xdr_keybuf F ++ xdr_keystatus F ++ xdr_long F ++ xdr_longlong_t F ++ xdr_netnamestr F ++ xdr_netobj F ++ xdr_opaque F ++ xdr_opaque_auth F ++ xdr_pmap F ++ xdr_pmaplist F ++ xdr_pointer F ++ xdr_quad_t F ++ xdr_reference F ++ xdr_rejected_reply F ++ xdr_replymsg F ++ xdr_rmtcall_args F ++ xdr_rmtcallres F ++ xdr_short F ++ xdr_sizeof F ++ xdr_string F ++ xdr_u_char F ++ xdr_u_hyper F ++ xdr_u_int F ++ xdr_u_long F ++ xdr_u_longlong_t F ++ xdr_u_quad_t F ++ xdr_u_short F ++ xdr_uint16_t F ++ xdr_uint32_t F ++ xdr_uint64_t F ++ xdr_uint8_t F ++ xdr_union F ++ xdr_unixcred F ++ xdr_vector F ++ xdr_void F ++ xdr_wrapstring F ++ xdrmem_create F ++ xdrrec_create F ++ xdrrec_endofrecord F ++ xdrrec_eof F ++ xdrrec_skiprecord F ++ xdrstdio_create F ++ xencrypt F ++ xprt_register F ++ xprt_unregister F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libcrypt-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,9 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ crypt F ++ crypt_r F ++ encrypt F ++ encrypt_r F ++ fcrypt F ++ setkey F ++ setkey_r F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libdl-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,11 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ dladdr F ++ dladdr1 F ++ dlclose F ++ dlerror F ++ dlinfo F ++ dlmopen F ++ dlopen F ++ dlsym F ++ dlvsym F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libm-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,402 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ _LIB_VERSION D 0x4 ++ __acos_finite F ++ __acosf_finite F ++ __acosh_finite F ++ __acoshf_finite F ++ __acoshl_finite F ++ __acosl_finite F ++ __asin_finite F ++ __asinf_finite F ++ __asinl_finite F ++ __atan2_finite F ++ __atan2f_finite F ++ __atan2l_finite F ++ __atanh_finite F ++ __atanhf_finite F ++ __atanhl_finite F ++ __clog10 F ++ __clog10f F ++ __clog10l F ++ __cosh_finite F ++ __coshf_finite F ++ __coshl_finite F ++ __exp10_finite F ++ __exp10f_finite F ++ __exp10l_finite F ++ __exp2_finite F ++ __exp2f_finite F ++ __exp2l_finite F ++ __exp_finite F ++ __expf_finite F ++ __expl_finite F ++ __fe_dfl_env D 0x8 ++ __fe_enabled_env D 0x8 ++ __fe_nomask_env F ++ __fe_nonieee_env D 0x8 ++ __finite F ++ __finitef F ++ __finitel F ++ __fmod_finite F ++ __fmodf_finite F ++ __fmodl_finite F ++ __fpclassify F ++ __fpclassifyf F ++ __fpclassifyl F ++ __gamma_r_finite F ++ __gammaf_r_finite F ++ __gammal_r_finite F ++ __hypot_finite F ++ __hypotf_finite F ++ __hypotl_finite F ++ __j0_finite F ++ __j0f_finite F ++ __j0l_finite F ++ __j1_finite F ++ __j1f_finite F ++ __j1l_finite F ++ __jn_finite F ++ __jnf_finite F ++ __jnl_finite F ++ __lgamma_r_finite F ++ __lgammaf_r_finite F ++ __lgammal_r_finite F ++ __log10_finite F ++ __log10f_finite F ++ __log10l_finite F ++ __log2_finite F ++ __log2f_finite F ++ __log2l_finite F ++ __log_finite F ++ __logf_finite F ++ __logl_finite F ++ __nldbl_nexttowardf F ++ __pow_finite F ++ __powf_finite F ++ __powl_finite F ++ __remainder_finite F ++ __remainderf_finite F ++ __remainderl_finite F ++ __scalb_finite F ++ __scalbf_finite F ++ __scalbl_finite F ++ __signbit F ++ __signbitf F ++ __signbitl F ++ __sinh_finite F ++ __sinhf_finite F ++ __sinhl_finite F ++ __sqrt_finite F ++ __sqrtf_finite F ++ __sqrtl_finite F ++ __y0_finite F ++ __y0f_finite F ++ __y0l_finite F ++ __y1_finite F ++ __y1f_finite F ++ __y1l_finite F ++ __yn_finite F ++ __ynf_finite F ++ __ynl_finite F ++ acos F ++ acosf F ++ acosh F ++ acoshf F ++ acoshl F ++ acosl F ++ asin F ++ asinf F ++ asinh F ++ asinhf F ++ asinhl F ++ asinl F ++ atan F ++ atan2 F ++ atan2f F ++ atan2l F ++ atanf F ++ atanh F ++ atanhf F ++ atanhl F ++ atanl F ++ cabs F ++ cabsf F ++ cabsl F ++ cacos F ++ cacosf F ++ cacosh F ++ cacoshf F ++ cacoshl F ++ cacosl F ++ carg F ++ cargf F ++ cargl F ++ casin F ++ casinf F ++ casinh F ++ casinhf F ++ casinhl F ++ casinl F ++ catan F ++ catanf F ++ catanh F ++ catanhf F ++ catanhl F ++ catanl F ++ cbrt F ++ cbrtf F ++ cbrtl F ++ ccos F ++ ccosf F ++ ccosh F ++ ccoshf F ++ ccoshl F ++ ccosl F ++ ceil F ++ ceilf F ++ ceill F ++ cexp F ++ cexpf F ++ cexpl F ++ cimag F ++ cimagf F ++ cimagl F ++ clog F ++ clog10 F ++ clog10f F ++ clog10l F ++ clogf F ++ clogl F ++ conj F ++ conjf F ++ conjl F ++ copysign F ++ copysignf F ++ copysignl F ++ cos F ++ cosf F ++ cosh F ++ coshf F ++ coshl F ++ cosl F ++ cpow F ++ cpowf F ++ cpowl F ++ cproj F ++ cprojf F ++ cprojl F ++ creal F ++ crealf F ++ creall F ++ csin F ++ csinf F ++ csinh F ++ csinhf F ++ csinhl F ++ csinl F ++ csqrt F ++ csqrtf F ++ csqrtl F ++ ctan F ++ ctanf F ++ ctanh F ++ ctanhf F ++ ctanhl F ++ ctanl F ++ drem F ++ dremf F ++ dreml F ++ erf F ++ erfc F ++ erfcf F ++ erfcl F ++ erff F ++ erfl F ++ exp F ++ exp10 F ++ exp10f F ++ exp10l F ++ exp2 F ++ exp2f F ++ exp2l F ++ expf F ++ expl F ++ expm1 F ++ expm1f F ++ expm1l F ++ fabs F ++ fabsf F ++ fabsl F ++ fdim F ++ fdimf F ++ fdiml F ++ feclearexcept F ++ fedisableexcept F ++ feenableexcept F ++ fegetenv F ++ fegetexcept F ++ fegetexceptflag F ++ fegetround F ++ feholdexcept F ++ feraiseexcept F ++ fesetenv F ++ fesetexceptflag F ++ fesetround F ++ fetestexcept F ++ feupdateenv F ++ finite F ++ finitef F ++ finitel F ++ floor F ++ floorf F ++ floorl F ++ fma F ++ fmaf F ++ fmal F ++ fmax F ++ fmaxf F ++ fmaxl F ++ fmin F ++ fminf F ++ fminl F ++ fmod F ++ fmodf F ++ fmodl F ++ frexp F ++ frexpf F ++ frexpl F ++ gamma F ++ gammaf F ++ gammal F ++ hypot F ++ hypotf F ++ hypotl F ++ ilogb F ++ ilogbf F ++ ilogbl F ++ j0 F ++ j0f F ++ j0l F ++ j1 F ++ j1f F ++ j1l F ++ jn F ++ jnf F ++ jnl F ++ ldexp F ++ ldexpf F ++ ldexpl F ++ lgamma F ++ lgamma_r F ++ lgammaf F ++ lgammaf_r F ++ lgammal F ++ lgammal_r F ++ llrint F ++ llrintf F ++ llrintl F ++ llround F ++ llroundf F ++ llroundl F ++ log F ++ log10 F ++ log10f F ++ log10l F ++ log1p F ++ log1pf F ++ log1pl F ++ log2 F ++ log2f F ++ log2l F ++ logb F ++ logbf F ++ logbl F ++ logf F ++ logl F ++ lrint F ++ lrintf F ++ lrintl F ++ lround F ++ lroundf F ++ lroundl F ++ matherr F ++ modf F ++ modff F ++ modfl F ++ nan F ++ nanf F ++ nanl F ++ nearbyint F ++ nearbyintf F ++ nearbyintl F ++ nextafter F ++ nextafterf F ++ nextafterl F ++ nexttoward F ++ nexttowardf F ++ nexttowardl F ++ pow F ++ pow10 F ++ pow10f F ++ pow10l F ++ powf F ++ powl F ++ remainder F ++ remainderf F ++ remainderl F ++ remquo F ++ remquof F ++ remquol F ++ rint F ++ rintf F ++ rintl F ++ round F ++ roundf F ++ roundl F ++ scalb F ++ scalbf F ++ scalbl F ++ scalbln F ++ scalblnf F ++ scalblnl F ++ scalbn F ++ scalbnf F ++ scalbnl F ++ signgam D 0x4 ++ significand F ++ significandf F ++ significandl F ++ sin F ++ sincos F ++ sincosf F ++ sincosl F ++ sinf F ++ sinh F ++ sinhf F ++ sinhl F ++ sinl F ++ sqrt F ++ sqrtf F ++ sqrtl F ++ tan F ++ tanf F ++ tanh F ++ tanhf F ++ tanhl F ++ tanl F ++ tgamma F ++ tgammaf F ++ tgammal F ++ trunc F ++ truncf F ++ truncl F ++ y0 F ++ y0f F ++ y0l F ++ y1 F ++ y1f F ++ y1l F ++ yn F ++ ynf F ++ ynl F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libnsl-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,123 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ __free_fdresult F ++ __nis_default_access F ++ __nis_default_group F ++ __nis_default_owner F ++ __nis_default_ttl F ++ __nis_finddirectory F ++ __nis_hash F ++ __nisbind_connect F ++ __nisbind_create F ++ __nisbind_destroy F ++ __nisbind_next F ++ __yp_check F ++ nis_add F ++ nis_add_entry F ++ nis_addmember F ++ nis_checkpoint F ++ nis_clone_directory F ++ nis_clone_object F ++ nis_clone_result F ++ nis_creategroup F ++ nis_destroy_object F ++ nis_destroygroup F ++ nis_dir_cmp F ++ nis_domain_of F ++ nis_domain_of_r F ++ nis_first_entry F ++ nis_free_directory F ++ nis_free_object F ++ nis_free_request F ++ nis_freenames F ++ nis_freeresult F ++ nis_freeservlist F ++ nis_freetags F ++ nis_getnames F ++ nis_getservlist F ++ nis_ismember F ++ nis_leaf_of F ++ nis_leaf_of_r F ++ nis_lerror F ++ nis_list F ++ nis_local_directory F ++ nis_local_group F ++ nis_local_host F ++ nis_local_principal F ++ nis_lookup F ++ nis_mkdir F ++ nis_modify F ++ nis_modify_entry F ++ nis_name_of F ++ nis_name_of_r F ++ nis_next_entry F ++ nis_perror F ++ nis_ping F ++ nis_print_directory F ++ nis_print_entry F ++ nis_print_group F ++ nis_print_group_entry F ++ nis_print_link F ++ nis_print_object F ++ nis_print_result F ++ nis_print_rights F ++ nis_print_table F ++ nis_read_obj F ++ nis_remove F ++ nis_remove_entry F ++ nis_removemember F ++ nis_rmdir F ++ nis_servstate F ++ nis_sperrno F ++ nis_sperror F ++ nis_sperror_r F ++ nis_stats F ++ nis_verifygroup F ++ nis_write_obj F ++ readColdStartFile F ++ writeColdStartFile F ++ xdr_cback_data F ++ xdr_domainname F ++ xdr_keydat F ++ xdr_mapname F ++ xdr_obj_p F ++ xdr_peername F ++ xdr_valdat F ++ xdr_yp_buf F ++ xdr_ypall F ++ xdr_ypbind_binding F ++ xdr_ypbind_resp F ++ xdr_ypbind_resptype F ++ xdr_ypbind_setdom F ++ xdr_ypdelete_args F ++ xdr_ypmap_parms F ++ xdr_ypmaplist F ++ xdr_yppush_status F ++ xdr_yppushresp_xfr F ++ xdr_ypreq_key F ++ xdr_ypreq_nokey F ++ xdr_ypreq_xfr F ++ xdr_ypresp_all F ++ xdr_ypresp_key_val F ++ xdr_ypresp_maplist F ++ xdr_ypresp_master F ++ xdr_ypresp_order F ++ xdr_ypresp_val F ++ xdr_ypresp_xfr F ++ xdr_ypstat F ++ xdr_ypupdate_args F ++ xdr_ypxfrstat F ++ yp_all F ++ yp_bind F ++ yp_first F ++ yp_get_default_domain F ++ yp_maplist F ++ yp_master F ++ yp_match F ++ yp_next F ++ yp_order F ++ yp_unbind F ++ yp_update F ++ ypbinderr_string F ++ yperr_string F ++ ypprot_err F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libpthread-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,224 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ _IO_flockfile F ++ _IO_ftrylockfile F ++ _IO_funlockfile F ++ __close F ++ __connect F ++ __errno_location F ++ __fcntl F ++ __fork F ++ __h_errno_location F ++ __libc_allocate_rtsig F ++ __libc_current_sigrtmax F ++ __libc_current_sigrtmin F ++ __lseek F ++ __nanosleep F ++ __open F ++ __open64 F ++ __pread64 F ++ __pthread_cleanup_routine F ++ __pthread_getspecific F ++ __pthread_key_create F ++ __pthread_mutex_destroy F ++ __pthread_mutex_init F ++ __pthread_mutex_lock F ++ __pthread_mutex_trylock F ++ __pthread_mutex_unlock F ++ __pthread_mutexattr_destroy F ++ __pthread_mutexattr_init F ++ __pthread_mutexattr_settype F ++ __pthread_once F ++ __pthread_register_cancel F ++ __pthread_register_cancel_defer F ++ __pthread_rwlock_destroy F ++ __pthread_rwlock_init F ++ __pthread_rwlock_rdlock F ++ __pthread_rwlock_tryrdlock F ++ __pthread_rwlock_trywrlock F ++ __pthread_rwlock_unlock F ++ __pthread_rwlock_wrlock F ++ __pthread_setspecific F ++ __pthread_unregister_cancel F ++ __pthread_unregister_cancel_restore F ++ __pthread_unwind_next F ++ __pwrite64 F ++ __read F ++ __res_state F ++ __send F ++ __sigaction F ++ __vfork F ++ __wait F ++ __write F ++ _pthread_cleanup_pop F ++ _pthread_cleanup_pop_restore F ++ _pthread_cleanup_push F ++ _pthread_cleanup_push_defer F ++ accept F ++ close F ++ connect F ++ fcntl F ++ flockfile F ++ fork F ++ fsync F ++ ftrylockfile F ++ funlockfile F ++ longjmp F ++ lseek F ++ lseek64 F ++ msync F ++ nanosleep F ++ open F ++ open64 F ++ pause F ++ pread F ++ pread64 F ++ pthread_attr_destroy F ++ pthread_attr_getaffinity_np F ++ pthread_attr_getdetachstate F ++ pthread_attr_getguardsize F ++ pthread_attr_getinheritsched F ++ pthread_attr_getschedparam F ++ pthread_attr_getschedpolicy F ++ pthread_attr_getscope F ++ pthread_attr_getstack F ++ pthread_attr_getstackaddr F ++ pthread_attr_getstacksize F ++ pthread_attr_init F ++ pthread_attr_setaffinity_np F ++ pthread_attr_setdetachstate F ++ pthread_attr_setguardsize F ++ pthread_attr_setinheritsched F ++ pthread_attr_setschedparam F ++ pthread_attr_setschedpolicy F ++ pthread_attr_setscope F ++ pthread_attr_setstack F ++ pthread_attr_setstackaddr F ++ pthread_attr_setstacksize F ++ pthread_barrier_destroy F ++ pthread_barrier_init F ++ pthread_barrier_wait F ++ pthread_barrierattr_destroy F ++ pthread_barrierattr_getpshared F ++ pthread_barrierattr_init F ++ pthread_barrierattr_setpshared F ++ pthread_cancel F ++ pthread_cond_broadcast F ++ pthread_cond_destroy F ++ pthread_cond_init F ++ pthread_cond_signal F ++ pthread_cond_timedwait F ++ pthread_cond_wait F ++ pthread_condattr_destroy F ++ pthread_condattr_getclock F ++ pthread_condattr_getpshared F ++ pthread_condattr_init F ++ pthread_condattr_setclock F ++ pthread_condattr_setpshared F ++ pthread_create F ++ pthread_detach F ++ pthread_equal F ++ pthread_exit F ++ pthread_getaffinity_np F ++ pthread_getattr_np F ++ pthread_getconcurrency F ++ pthread_getcpuclockid F ++ pthread_getname_np F ++ pthread_getschedparam F ++ pthread_getspecific F ++ pthread_join F ++ pthread_key_create F ++ pthread_key_delete F ++ pthread_kill F ++ pthread_kill_other_threads_np F ++ pthread_mutex_consistent F ++ pthread_mutex_consistent_np F ++ pthread_mutex_destroy F ++ pthread_mutex_getprioceiling F ++ pthread_mutex_init F ++ pthread_mutex_lock F ++ pthread_mutex_setprioceiling F ++ pthread_mutex_timedlock F ++ pthread_mutex_trylock F ++ pthread_mutex_unlock F ++ pthread_mutexattr_destroy F ++ pthread_mutexattr_getkind_np F ++ pthread_mutexattr_getprioceiling F ++ pthread_mutexattr_getprotocol F ++ pthread_mutexattr_getpshared F ++ pthread_mutexattr_getrobust F ++ pthread_mutexattr_getrobust_np F ++ pthread_mutexattr_gettype F ++ pthread_mutexattr_init F ++ pthread_mutexattr_setkind_np F ++ pthread_mutexattr_setprioceiling F ++ pthread_mutexattr_setprotocol F ++ pthread_mutexattr_setpshared F ++ pthread_mutexattr_setrobust F ++ pthread_mutexattr_setrobust_np F ++ pthread_mutexattr_settype F ++ pthread_once F ++ pthread_rwlock_destroy F ++ pthread_rwlock_init F ++ pthread_rwlock_rdlock F ++ pthread_rwlock_timedrdlock F ++ pthread_rwlock_timedwrlock F ++ pthread_rwlock_tryrdlock F ++ pthread_rwlock_trywrlock F ++ pthread_rwlock_unlock F ++ pthread_rwlock_wrlock F ++ pthread_rwlockattr_destroy F ++ pthread_rwlockattr_getkind_np F ++ pthread_rwlockattr_getpshared F ++ pthread_rwlockattr_init F ++ pthread_rwlockattr_setkind_np F ++ pthread_rwlockattr_setpshared F ++ pthread_self F ++ pthread_setaffinity_np F ++ pthread_setcancelstate F ++ pthread_setcanceltype F ++ pthread_setconcurrency F ++ pthread_setname_np F ++ pthread_setschedparam F ++ pthread_setschedprio F ++ pthread_setspecific F ++ pthread_sigmask F ++ pthread_sigqueue F ++ pthread_spin_destroy F ++ pthread_spin_init F ++ pthread_spin_lock F ++ pthread_spin_trylock F ++ pthread_spin_unlock F ++ pthread_testcancel F ++ pthread_timedjoin_np F ++ pthread_tryjoin_np F ++ pthread_yield F ++ pwrite F ++ pwrite64 F ++ raise F ++ read F ++ recv F ++ recvfrom F ++ recvmsg F ++ sem_close F ++ sem_destroy F ++ sem_getvalue F ++ sem_init F ++ sem_open F ++ sem_post F ++ sem_timedwait F ++ sem_trywait F ++ sem_unlink F ++ sem_wait F ++ send F ++ sendmsg F ++ sendto F ++ sigaction F ++ siglongjmp F ++ sigwait F ++ system F ++ tcdrain F ++ vfork F ++ wait F ++ waitpid F ++ write F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libresolv-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,93 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ __b64_ntop F ++ __b64_pton F ++ __dn_comp F ++ __dn_count_labels F ++ __dn_expand F ++ __dn_skipname F ++ __fp_nquery F ++ __fp_query F ++ __fp_resstat F ++ __hostalias F ++ __loc_aton F ++ __loc_ntoa F ++ __p_cdname F ++ __p_cdnname F ++ __p_class F ++ __p_class_syms D 0xa8 ++ __p_fqname F ++ __p_fqnname F ++ __p_option F ++ __p_query F ++ __p_rcode F ++ __p_secstodate F ++ __p_time F ++ __p_type F ++ __p_type_syms D 0x450 ++ __putlong F ++ __putshort F ++ __res_close F ++ __res_dnok F ++ __res_hnok F ++ __res_hostalias F ++ __res_isourserver F ++ __res_mailok F ++ __res_mkquery F ++ __res_nameinquery F ++ __res_nmkquery F ++ __res_nquery F ++ __res_nquerydomain F ++ __res_nsearch F ++ __res_nsend F ++ __res_ownok F ++ __res_queriesmatch F ++ __res_query F ++ __res_querydomain F ++ __res_search F ++ __res_send F ++ __sym_ntop F ++ __sym_ntos F ++ __sym_ston F ++ _gethtbyaddr F ++ _gethtbyname F ++ _gethtbyname2 F ++ _gethtent F ++ _getlong F ++ _getshort F ++ _res_opcodes D 0x80 ++ _sethtent F ++ inet_net_ntop F ++ inet_net_pton F ++ inet_neta F ++ ns_datetosecs F ++ ns_format_ttl F ++ ns_get16 F ++ ns_get32 F ++ ns_initparse F ++ ns_makecanon F ++ ns_msg_getflag F ++ ns_name_compress F ++ ns_name_ntol F ++ ns_name_ntop F ++ ns_name_pack F ++ ns_name_pton F ++ ns_name_rollback F ++ ns_name_skip F ++ ns_name_uncompress F ++ ns_name_unpack F ++ ns_parse_ttl F ++ ns_parserr F ++ ns_put16 F ++ ns_put32 F ++ ns_samedomain F ++ ns_samename F ++ ns_skiprr F ++ ns_sprintrr F ++ ns_sprintrrf F ++ ns_subdomain F ++ res_gethostbyaddr F ++ res_gethostbyname F ++ res_gethostbyname2 F ++ res_send_setqhook F ++ res_send_setrhook F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librt-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,37 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ __mq_open_2 F ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ lio_listio F ++ lio_listio64 F ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libthread_db-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,42 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ td_init F ++ td_log F ++ td_symbol_list F ++ td_ta_clear_event F ++ td_ta_delete F ++ td_ta_enable_stats F ++ td_ta_event_addr F ++ td_ta_event_getmsg F ++ td_ta_get_nthreads F ++ td_ta_get_ph F ++ td_ta_get_stats F ++ td_ta_map_id2thr F ++ td_ta_map_lwp2thr F ++ td_ta_new F ++ td_ta_reset_stats F ++ td_ta_set_event F ++ td_ta_setconcurrency F ++ td_ta_thr_iter F ++ td_ta_tsd_iter F ++ td_thr_clear_event F ++ td_thr_dbresume F ++ td_thr_dbsuspend F ++ td_thr_event_enable F ++ td_thr_event_getmsg F ++ td_thr_get_info F ++ td_thr_getfpregs F ++ td_thr_getgregs F ++ td_thr_getxregs F ++ td_thr_getxregsize F ++ td_thr_set_event F ++ td_thr_setfpregs F ++ td_thr_setgregs F ++ td_thr_setprio F ++ td_thr_setsigpending F ++ td_thr_setxregs F ++ td_thr_sigsetmask F ++ td_thr_tls_get_addr F ++ td_thr_tlsbase F ++ td_thr_tsd F ++ td_thr_validate F +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist 1970-01-01 00:00:00.000000000 +0000 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/libutil-le.abilist 2014-06-02 15:22:40.000000000 +0000 +@@ -0,0 +1,8 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ forkpty F ++ login F ++ login_tty F ++ logout F ++ logwtmp F ++ openpty F diff --git a/SOURCES/glibc-ppc64le-03.patch b/SOURCES/glibc-ppc64le-03.patch new file mode 100644 index 00000000..b6886d4b --- /dev/null +++ b/SOURCES/glibc-ppc64le-03.patch @@ -0,0 +1,1617 @@ +# commit 9e54314bb06aace405553552f7e7b7d8c172968c +# Author: Joseph Myers +# Date: Thu Jun 6 19:02:09 2013 +0000 +# +# Update miscellaneous scripts from upstream. +# +diff -urN glibc-2.17-c758a686/scripts/config.guess glibc-2.17-c758a686/scripts/config.guess +--- glibc-2.17-c758a686/scripts/config.guess 2014-05-26 15:59:45.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/config.guess 2014-05-26 16:01:00.000000000 -0500 +@@ -1,14 +1,12 @@ + #! /bin/sh + # Attempt to guess a canonical system name. +-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +-# 2011, 2012 Free Software Foundation, Inc. ++# Copyright 1992-2013 Free Software Foundation, Inc. + +-timestamp='2012-09-25' ++timestamp='2013-11-29' + + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or ++# the Free Software Foundation; either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, but +@@ -22,19 +20,17 @@ + # As a special exception to the GNU General Public License, if you + # distribute this file as part of a program that contains a + # configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. +- +- +-# Originally written by Per Bothner. Please send patches (context +-# diff format) to and include a ChangeLog +-# entry. ++# the same distribution terms that you use for the rest of that ++# program. This Exception is an additional permission under section 7 ++# of the GNU General Public License, version 3 ("GPLv3"). + # +-# This script attempts to guess a canonical system name similar to +-# config.sub. If it succeeds, it prints the system name on stdout, and +-# exits with 0. Otherwise, it exits with 1. ++# Originally written by Per Bothner. + # + # You can get the latest version of this script from: + # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD ++# ++# Please send patches with a ChangeLog entry to config-patches@gnu.org. ++ + + me=`echo "$0" | sed -e 's,.*/,,'` + +@@ -54,9 +50,7 @@ + GNU config.guess ($timestamp) + + Originally written by Per Bothner. +-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +-Free Software Foundation, Inc. ++Copyright 1992-2013 Free Software Foundation, Inc. + + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +@@ -138,6 +132,27 @@ + UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown + UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + ++case "${UNAME_SYSTEM}" in ++Linux|GNU|GNU/*) ++ # If the system lacks a compiler, then just pick glibc. ++ # We could probably try harder. ++ LIBC=gnu ++ ++ eval $set_cc_for_build ++ cat <<-EOF > $dummy.c ++ #include ++ #if defined(__UCLIBC__) ++ LIBC=uclibc ++ #elif defined(__dietlibc__) ++ LIBC=dietlibc ++ #else ++ LIBC=gnu ++ #endif ++ EOF ++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` ++ ;; ++esac ++ + # Note: order is significant - the case branches are not exclusive. + + case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +@@ -859,21 +874,21 @@ + exit ;; + *:GNU:*:*) + # the GNU system +- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` ++ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland +- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu ++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in +@@ -886,59 +901,54 @@ + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 +- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi +- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; ++ arc:Linux:*:* | arceb:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then +- echo ${UNAME_MACHINE}-unknown-linux-gnueabi ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else +- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-gnu ++ echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-gnu ++ echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) +- LIBC=gnu +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #ifdef __dietlibc__ +- LIBC=dietlibc +- #endif +-EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` +- echo "${UNAME_MACHINE}-pc-linux-${LIBC}" ++ echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build +@@ -957,54 +967,63 @@ + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` +- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; ++ or1k:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} ++ exit ;; + or32:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) +- echo sparc-unknown-linux-gnu ++ echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) +- echo hppa64-unknown-linux-gnu ++ echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in +- PA7*) echo hppa1.1-unknown-linux-gnu ;; +- PA8*) echo hppa2.0-unknown-linux-gnu ;; +- *) echo hppa-unknown-linux-gnu ;; ++ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; ++ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; ++ *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) +- echo powerpc64-unknown-linux-gnu ++ echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) +- echo powerpc-unknown-linux-gnu ++ echo powerpc-unknown-linux-${LIBC} ++ exit ;; ++ ppc64le:Linux:*:*) ++ echo powerpc64le-unknown-linux-${LIBC} ++ exit ;; ++ ppcle:Linux:*:*) ++ echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) +- echo ${UNAME_MACHINE}-ibm-linux ++ echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) +- echo ${UNAME_MACHINE}-dec-linux-gnu ++ echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-gnu ++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. +@@ -1237,19 +1256,31 @@ + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown +- case $UNAME_PROCESSOR in +- i386) +- eval $set_cc_for_build +- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +- grep IS_64BIT_ARCH >/dev/null +- then +- UNAME_PROCESSOR="x86_64" +- fi +- fi ;; +- unknown) UNAME_PROCESSOR=powerpc ;; +- esac ++ eval $set_cc_for_build ++ if test "$UNAME_PROCESSOR" = unknown ; then ++ UNAME_PROCESSOR=powerpc ++ fi ++ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then ++ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then ++ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ ++ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ ++ grep IS_64BIT_ARCH >/dev/null ++ then ++ case $UNAME_PROCESSOR in ++ i386) UNAME_PROCESSOR=x86_64 ;; ++ powerpc) UNAME_PROCESSOR=powerpc64 ;; ++ esac ++ fi ++ fi ++ elif test "$UNAME_PROCESSOR" = i386 ; then ++ # Avoid executing cc on OS X 10.9, as it ships with a stub ++ # that puts up a graphical alert prompting to install ++ # developer tools. Any system running Mac OS X 10.7 or ++ # later (Darwin 11 and later) is required to have a 64-bit ++ # processor. This is not true of the ARM version of Darwin ++ # that Apple uses in portable devices. ++ UNAME_PROCESSOR=x86_64 ++ fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) +diff -urN glibc-2.17-c758a686/scripts/config.sub glibc-2.17-c758a686/scripts/config.sub +--- glibc-2.17-c758a686/scripts/config.sub 2014-05-26 15:59:45.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/config.sub 2014-05-26 16:00:52.000000000 -0500 +@@ -1,24 +1,18 @@ + #! /bin/sh + # Configuration validation subroutine script. +-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +-# 2011, 2012 Free Software Foundation, Inc. +- +-timestamp='2012-08-18' +- +-# This file is (in principle) common to ALL GNU software. +-# The presence of a machine in this file suggests that SOME GNU software +-# can handle that machine. It does not imply ALL GNU software can. +-# +-# This file is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2 of the License, or ++# Copyright 1992-2013 Free Software Foundation, Inc. ++ ++timestamp='2013-10-01' ++ ++# This file is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or + # (at your option) any later version. + # +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, see . +@@ -26,11 +20,12 @@ + # As a special exception to the GNU General Public License, if you + # distribute this file as part of a program that contains a + # configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. ++# the same distribution terms that you use for the rest of that ++# program. This Exception is an additional permission under section 7 ++# of the GNU General Public License, version 3 ("GPLv3"). + + +-# Please send patches to . Submit a context +-# diff and a properly formatted GNU ChangeLog entry. ++# Please send patches with a ChangeLog entry to config-patches@gnu.org. + # + # Configuration subroutine to validate and canonicalize a configuration type. + # Supply the specified configuration type as an argument. +@@ -73,9 +68,7 @@ + version="\ + GNU config.sub ($timestamp) + +-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +-Free Software Foundation, Inc. ++Copyright 1992-2013 Free Software Foundation, Inc. + + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +@@ -156,7 +149,7 @@ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ +- -apple | -axis | -knuth | -cray | -microblaze) ++ -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; +@@ -259,10 +252,12 @@ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ +- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ +- | be32 | be64 \ ++ | arc | arceb \ ++ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ ++ | avr | avr32 \ ++ | be32 | be64 \ + | bfin \ +- | c4x | clipper \ ++ | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ +@@ -270,10 +265,11 @@ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ ++ | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ +- | maxq | mb | microblaze | mcore | mep | metag \ ++ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ +@@ -291,16 +287,17 @@ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ ++ | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ +- | nios | nios2 \ ++ | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 \ +- | or32 \ ++ | or1k | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ +@@ -328,7 +325,7 @@ + c6x) + basic_machine=tic6x-unknown + ;; +- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) ++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; +@@ -370,13 +367,13 @@ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ +- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ ++ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ +- | clipper-* | craynv-* | cydra-* \ ++ | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ +@@ -385,11 +382,13 @@ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ ++ | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ +- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ ++ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ ++ | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ +@@ -407,12 +406,13 @@ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ ++ | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ +- | nios-* | nios2-* \ ++ | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ +@@ -788,7 +788,7 @@ + basic_machine=ns32k-utek + os=-sysv + ;; +- microblaze) ++ microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) +@@ -796,7 +796,7 @@ + os=-mingw64 + ;; + mingw32) +- basic_machine=i386-pc ++ basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) +@@ -832,7 +832,7 @@ + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) +- basic_machine=i386-pc ++ basic_machine=i686-pc + os=-msys + ;; + mvs) +@@ -1023,7 +1023,11 @@ + basic_machine=i586-unknown + os=-pw32 + ;; +- rdos) ++ rdos | rdos64) ++ basic_machine=x86_64-pc ++ os=-rdos ++ ;; ++ rdos32) + basic_machine=i386-pc + os=-rdos + ;; +@@ -1350,7 +1354,7 @@ + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ +- | -sym* | -kopensolaris* \ ++ | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ +@@ -1496,9 +1500,6 @@ + -aros*) + os=-aros + ;; +- -kaos*) +- os=-kaos +- ;; + -zvmoe) + os=-zvmoe + ;; +@@ -1547,6 +1548,9 @@ + c4x-* | tic4x-*) + os=-coff + ;; ++ c8051-*) ++ os=-elf ++ ;; + hexagon-*) + os=-elf + ;; +@@ -1590,6 +1594,9 @@ + mips*-*) + os=-elf + ;; ++ or1k-*) ++ os=-elf ++ ;; + or32-*) + os=-coff + ;; +diff -urN glibc-2.17-c758a686/scripts/install-sh glibc-2.17-c758a686/scripts/install-sh +--- glibc-2.17-c758a686/scripts/install-sh 2014-05-26 15:59:45.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/install-sh 2014-05-26 16:00:34.000000000 -0500 +@@ -1,250 +1,527 @@ +-#! /bin/sh +-# ++#!/bin/sh + # install - install a program, script, or datafile +-# This comes from X11R5 (mit/util/scripts/install.sh). ++ ++scriptversion=2011-11-20.07; # UTC ++ ++# This originates from X11R5 (mit/util/scripts/install.sh), which was ++# later released in X11R6 (xc/config/util/install.sh) with the ++# following copyright and license. ++# ++# Copyright (C) 1994 X Consortium ++# ++# Permission is hereby granted, free of charge, to any person obtaining a copy ++# of this software and associated documentation files (the "Software"), to ++# deal in the Software without restriction, including without limitation the ++# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or ++# sell copies of the Software, and to permit persons to whom the Software is ++# furnished to do so, subject to the following conditions: ++# ++# The above copyright notice and this permission notice shall be included in ++# all copies or substantial portions of the Software. ++# ++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN ++# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- ++# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++# ++# Except as contained in this notice, the name of the X Consortium shall not ++# be used in advertising or otherwise to promote the sale, use or other deal- ++# ings in this Software without prior written authorization from the X Consor- ++# tium. + # +-# Copyright 1991 by the Massachusetts Institute of Technology + # +-# Permission to use, copy, modify, distribute, and sell this software and its +-# documentation for any purpose is hereby granted without fee, provided that +-# the above copyright notice appear in all copies and that both that +-# copyright notice and this permission notice appear in supporting +-# documentation, and that the name of M.I.T. not be used in advertising or +-# publicity pertaining to distribution of the software without specific, +-# written prior permission. M.I.T. makes no representations about the +-# suitability of this software for any purpose. It is provided "as is" +-# without express or implied warranty. ++# FSF changes to this file are in the public domain. + # + # Calling this script install-sh is preferred over install.sh, to prevent +-# `make' implicit rules from creating a file called install from it ++# 'make' implicit rules from creating a file called install from it + # when there is no Makefile. + # + # This script is compatible with the BSD install script, but was written +-# from scratch. It can only install one file at a time, a restriction +-# shared with many OS's install programs. ++# from scratch. + ++nl=' ++' ++IFS=" "" $nl" + + # set DOITPROG to echo to test this script + + # Don't use :- since 4.3BSD and earlier shells don't like it. +-doit="${DOITPROG-}" +- +- +-# put in absolute paths if you don't have them in your path; or use env. vars. +- +-mvprog="${MVPROG-mv}" +-cpprog="${CPPROG-cp}" +-chmodprog="${CHMODPROG-chmod}" +-chownprog="${CHOWNPROG-chown}" +-chgrpprog="${CHGRPPROG-chgrp}" +-stripprog="${STRIPPROG-strip}" +-rmprog="${RMPROG-rm}" +-mkdirprog="${MKDIRPROG-mkdir}" +- +-transformbasename="" +-transform_arg="" +-instcmd="$mvprog" +-chmodcmd="$chmodprog 0755" +-chowncmd="" +-chgrpcmd="" +-stripcmd="" +-rmcmd="$rmprog -f" +-mvcmd="$mvprog" +-src="" +-dst="" +-dir_arg="" +- +-while [ x"$1" != x ]; do +- case $1 in +- -c) instcmd="$cpprog" +- shift +- continue;; +- +- -d) dir_arg=true +- shift +- continue;; +- +- -m) chmodcmd="$chmodprog $2" +- shift +- shift +- continue;; +- +- -o) chowncmd="$chownprog $2" +- shift +- shift +- continue;; +- +- -g) chgrpcmd="$chgrpprog $2" +- shift +- shift +- continue;; +- +- -s) stripcmd="$stripprog" +- shift +- continue;; +- +- -t=*) transformarg=`echo $1 | sed 's/-t=//'` +- shift +- continue;; +- +- -b=*) transformbasename=`echo $1 | sed 's/-b=//'` +- shift +- continue;; +- +- *) if [ x"$src" = x ] +- then +- src=$1 +- else +- # this colon is to work around a 386BSD /bin/sh bug +- : +- dst=$1 +- fi +- shift +- continue;; +- esac +-done +- +-if [ x"$src" = x ] +-then +- echo "install: no input file specified" +- exit 1 ++doit=${DOITPROG-} ++if test -z "$doit"; then ++ doit_exec=exec + else +- true ++ doit_exec=$doit + fi + +-if [ x"$dir_arg" != x ]; then +- dst=$src +- src="" +- +- if [ -d $dst ]; then +- instcmd=: +- else +- instcmd=mkdir +- fi +-else ++# Put in absolute file names if you don't have them in your path; ++# or use environment vars. + +-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +-# might cause directories to be created, which would be especially bad +-# if $src (and thus $dsttmp) contains '*'. +- +- if [ -f $src -o -d $src ] +- then +- true +- else +- echo "install: $src does not exist" +- exit 1 +- fi +- +- if [ x"$dst" = x ] +- then +- echo "install: no destination specified" +- exit 1 +- else +- true +- fi +- +-# If destination is a directory, append the input filename; if your system +-# does not like double slashes in filenames, you may need to add some logic +- +- if [ -d $dst ] +- then +- dst="$dst"/`basename $src` +- else +- true +- fi +-fi +- +-## this sed command emulates the dirname command +-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` ++chgrpprog=${CHGRPPROG-chgrp} ++chmodprog=${CHMODPROG-chmod} ++chownprog=${CHOWNPROG-chown} ++cmpprog=${CMPPROG-cmp} ++cpprog=${CPPROG-cp} ++mkdirprog=${MKDIRPROG-mkdir} ++mvprog=${MVPROG-mv} ++rmprog=${RMPROG-rm} ++stripprog=${STRIPPROG-strip} ++ ++posix_glob='?' ++initialize_posix_glob=' ++ test "$posix_glob" != "?" || { ++ if (set -f) 2>/dev/null; then ++ posix_glob= ++ else ++ posix_glob=: ++ fi ++ } ++' + +-# Make sure that the destination directory exists. +-# this part is taken from Noah Friedman's mkinstalldirs script ++posix_mkdir= + +-# Skip lots of stat calls in the usual case. +-if [ ! -d "$dstdir" ]; then +-defaultIFS=' +-' +-IFS="${IFS-${defaultIFS}}" ++# Desired mode of installed file. ++mode=0755 + +-oIFS="${IFS}" +-# Some sh's can't handle IFS=/ for some reason. +-IFS='%' +-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +-IFS="${oIFS}" +- +-pathcomp='' +- +-while [ $# -ne 0 ] ; do +- pathcomp="${pathcomp}${1}" +- shift +- +- if [ ! -d "${pathcomp}" ] ; +- then +- $mkdirprog "${pathcomp}" +- else +- true +- fi ++chgrpcmd= ++chmodcmd=$chmodprog ++chowncmd= ++mvcmd=$mvprog ++rmcmd="$rmprog -f" ++stripcmd= + +- pathcomp="${pathcomp}/" ++src= ++dst= ++dir_arg= ++dst_arg= ++ ++copy_on_change=false ++no_target_directory= ++ ++usage="\ ++Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE ++ or: $0 [OPTION]... SRCFILES... DIRECTORY ++ or: $0 [OPTION]... -t DIRECTORY SRCFILES... ++ or: $0 [OPTION]... -d DIRECTORIES... ++ ++In the 1st form, copy SRCFILE to DSTFILE. ++In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. ++In the 4th, create DIRECTORIES. ++ ++Options: ++ --help display this help and exit. ++ --version display version info and exit. ++ ++ -c (ignored) ++ -C install only if different (preserve the last data modification time) ++ -d create directories instead of installing files. ++ -g GROUP $chgrpprog installed files to GROUP. ++ -m MODE $chmodprog installed files to MODE. ++ -o USER $chownprog installed files to USER. ++ -s $stripprog installed files. ++ -t DIRECTORY install into DIRECTORY. ++ -T report an error if DSTFILE is a directory. ++ ++Environment variables override the default commands: ++ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG ++ RMPROG STRIPPROG ++" ++ ++while test $# -ne 0; do ++ case $1 in ++ -c) ;; ++ ++ -C) copy_on_change=true;; ++ ++ -d) dir_arg=true;; ++ ++ -g) chgrpcmd="$chgrpprog $2" ++ shift;; ++ ++ --help) echo "$usage"; exit $?;; ++ ++ -m) mode=$2 ++ case $mode in ++ *' '* | *' '* | *' ++'* | *'*'* | *'?'* | *'['*) ++ echo "$0: invalid mode: $mode" >&2 ++ exit 1;; ++ esac ++ shift;; ++ ++ -o) chowncmd="$chownprog $2" ++ shift;; ++ ++ -s) stripcmd=$stripprog;; ++ ++ -t) dst_arg=$2 ++ # Protect names problematic for 'test' and other utilities. ++ case $dst_arg in ++ -* | [=\(\)!]) dst_arg=./$dst_arg;; ++ esac ++ shift;; ++ ++ -T) no_target_directory=true;; ++ ++ --version) echo "$0 $scriptversion"; exit $?;; ++ ++ --) shift ++ break;; ++ ++ -*) echo "$0: invalid option: $1" >&2 ++ exit 1;; ++ ++ *) break;; ++ esac ++ shift + done ++ ++if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then ++ # When -d is used, all remaining arguments are directories to create. ++ # When -t is used, the destination is already specified. ++ # Otherwise, the last argument is the destination. Remove it from $@. ++ for arg ++ do ++ if test -n "$dst_arg"; then ++ # $@ is not empty: it contains at least $arg. ++ set fnord "$@" "$dst_arg" ++ shift # fnord ++ fi ++ shift # arg ++ dst_arg=$arg ++ # Protect names problematic for 'test' and other utilities. ++ case $dst_arg in ++ -* | [=\(\)!]) dst_arg=./$dst_arg;; ++ esac ++ done + fi + +-if [ x"$dir_arg" != x ] +-then +- $doit $instcmd $dst && +- +- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && +- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && +- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && +- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +-else ++if test $# -eq 0; then ++ if test -z "$dir_arg"; then ++ echo "$0: no input file specified." >&2 ++ exit 1 ++ fi ++ # It's OK to call 'install-sh -d' without argument. ++ # This can happen when creating conditional directories. ++ exit 0 ++fi + +-# If we're going to rename the final executable, determine the name now. ++if test -z "$dir_arg"; then ++ do_exit='(exit $ret); exit $ret' ++ trap "ret=129; $do_exit" 1 ++ trap "ret=130; $do_exit" 2 ++ trap "ret=141; $do_exit" 13 ++ trap "ret=143; $do_exit" 15 ++ ++ # Set umask so as not to create temps with too-generous modes. ++ # However, 'strip' requires both read and write access to temps. ++ case $mode in ++ # Optimize common cases. ++ *644) cp_umask=133;; ++ *755) cp_umask=22;; ++ ++ *[0-7]) ++ if test -z "$stripcmd"; then ++ u_plus_rw= ++ else ++ u_plus_rw='% 200' ++ fi ++ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; ++ *) ++ if test -z "$stripcmd"; then ++ u_plus_rw= ++ else ++ u_plus_rw=,u+rw ++ fi ++ cp_umask=$mode$u_plus_rw;; ++ esac ++fi + +- if [ x"$transformarg" = x ] +- then +- dstfile=`basename $dst` ++for src ++do ++ # Protect names problematic for 'test' and other utilities. ++ case $src in ++ -* | [=\(\)!]) src=./$src;; ++ esac ++ ++ if test -n "$dir_arg"; then ++ dst=$src ++ dstdir=$dst ++ test -d "$dstdir" ++ dstdir_status=$? ++ else ++ ++ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command ++ # might cause directories to be created, which would be especially bad ++ # if $src (and thus $dsttmp) contains '*'. ++ if test ! -f "$src" && test ! -d "$src"; then ++ echo "$0: $src does not exist." >&2 ++ exit 1 ++ fi ++ ++ if test -z "$dst_arg"; then ++ echo "$0: no destination specified." >&2 ++ exit 1 ++ fi ++ dst=$dst_arg ++ ++ # If destination is a directory, append the input filename; won't work ++ # if double slashes aren't ignored. ++ if test -d "$dst"; then ++ if test -n "$no_target_directory"; then ++ echo "$0: $dst_arg: Is a directory" >&2 ++ exit 1 ++ fi ++ dstdir=$dst ++ dst=$dstdir/`basename "$src"` ++ dstdir_status=0 ++ else ++ # Prefer dirname, but fall back on a substitute if dirname fails. ++ dstdir=` ++ (dirname "$dst") 2>/dev/null || ++ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ ++ X"$dst" : 'X\(//\)[^/]' \| \ ++ X"$dst" : 'X\(//\)$' \| \ ++ X"$dst" : 'X\(/\)' \| . 2>/dev/null || ++ echo X"$dst" | ++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)[^/].*/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\/\)$/{ ++ s//\1/ ++ q ++ } ++ /^X\(\/\).*/{ ++ s//\1/ ++ q ++ } ++ s/.*/./; q' ++ ` ++ ++ test -d "$dstdir" ++ dstdir_status=$? ++ fi ++ fi ++ ++ obsolete_mkdir_used=false ++ ++ if test $dstdir_status != 0; then ++ case $posix_mkdir in ++ '') ++ # Create intermediate dirs using mode 755 as modified by the umask. ++ # This is like FreeBSD 'install' as of 1997-10-28. ++ umask=`umask` ++ case $stripcmd.$umask in ++ # Optimize common cases. ++ *[2367][2367]) mkdir_umask=$umask;; ++ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; ++ ++ *[0-7]) ++ mkdir_umask=`expr $umask + 22 \ ++ - $umask % 100 % 40 + $umask % 20 \ ++ - $umask % 10 % 4 + $umask % 2 ++ `;; ++ *) mkdir_umask=$umask,go-w;; ++ esac ++ ++ # With -d, create the new directory with the user-specified mode. ++ # Otherwise, rely on $mkdir_umask. ++ if test -n "$dir_arg"; then ++ mkdir_mode=-m$mode + else +- dstfile=`basename $dst $transformbasename | +- sed $transformarg`$transformbasename ++ mkdir_mode= + fi + +-# don't allow the sed command to completely eliminate the filename ++ posix_mkdir=false ++ case $umask in ++ *[123567][0-7][0-7]) ++ # POSIX mkdir -p sets u+wx bits regardless of umask, which ++ # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ++ ;; ++ *) ++ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ ++ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 ++ ++ if (umask $mkdir_umask && ++ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 ++ then ++ if test -z "$dir_arg" || { ++ # Check for POSIX incompatibilities with -m. ++ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or ++ # other-writable bit of parent directory when it shouldn't. ++ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ++ ls_ld_tmpdir=`ls -ld "$tmpdir"` ++ case $ls_ld_tmpdir in ++ d????-?r-*) different_mode=700;; ++ d????-?--*) different_mode=755;; ++ *) false;; ++ esac && ++ $mkdirprog -m$different_mode -p -- "$tmpdir" && { ++ ls_ld_tmpdir_1=`ls -ld "$tmpdir"` ++ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" ++ } ++ } ++ then posix_mkdir=: ++ fi ++ rmdir "$tmpdir/d" "$tmpdir" ++ else ++ # Remove any dirs left behind by ancient mkdir implementations. ++ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null ++ fi ++ trap '' 0;; ++ esac;; ++ esac + +- if [ x"$dstfile" = x ] +- then +- dstfile=`basename $dst` ++ if ++ $posix_mkdir && ( ++ umask $mkdir_umask && ++ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ++ ) ++ then : ++ else ++ ++ # The umask is ridiculous, or mkdir does not conform to POSIX, ++ # or it failed possibly due to a race condition. Create the ++ # directory the slow way, step by step, checking for races as we go. ++ ++ case $dstdir in ++ /*) prefix='/';; ++ [-=\(\)!]*) prefix='./';; ++ *) prefix='';; ++ esac ++ ++ eval "$initialize_posix_glob" ++ ++ oIFS=$IFS ++ IFS=/ ++ $posix_glob set -f ++ set fnord $dstdir ++ shift ++ $posix_glob set +f ++ IFS=$oIFS ++ ++ prefixes= ++ ++ for d ++ do ++ test X"$d" = X && continue ++ ++ prefix=$prefix$d ++ if test -d "$prefix"; then ++ prefixes= + else +- true ++ if $posix_mkdir; then ++ (umask=$mkdir_umask && ++ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break ++ # Don't fail if two instances are running concurrently. ++ test -d "$prefix" || exit 1 ++ else ++ case $prefix in ++ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; ++ *) qprefix=$prefix;; ++ esac ++ prefixes="$prefixes '$qprefix'" ++ fi + fi ++ prefix=$prefix/ ++ done + +-# Make a temp file name in the proper directory. +- +- dsttmp=$dstdir/#inst.$$# +- +-# Move or copy the file name to the temp name +- +- $doit $instcmd $src $dsttmp && +- +- trap "rm -f ${dsttmp}" 0 && +- +-# and set any options; do chmod last to preserve setuid bits +- +-# If any of these fail, we abort the whole thing. If we want to +-# ignore errors from any of these, just make sure not to ignore +-# errors from the above "$doit $instcmd $src $dsttmp" command. +- +- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && +- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && +- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && +- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && +- +-# Now rename the file to the real destination. +- +- $doit $rmcmd -f $dstdir/$dstfile && +- $doit $mvcmd $dsttmp $dstdir/$dstfile +- +-fi && ++ if test -n "$prefixes"; then ++ # Don't fail if two instances are running concurrently. ++ (umask $mkdir_umask && ++ eval "\$doit_exec \$mkdirprog $prefixes") || ++ test -d "$dstdir" || exit 1 ++ obsolete_mkdir_used=true ++ fi ++ fi ++ fi ++ ++ if test -n "$dir_arg"; then ++ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && ++ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && ++ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || ++ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 ++ else ++ ++ # Make a couple of temp file names in the proper directory. ++ dsttmp=$dstdir/_inst.$$_ ++ rmtmp=$dstdir/_rm.$$_ ++ ++ # Trap to clean up those temp files at exit. ++ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 ++ ++ # Copy the file name to the temp name. ++ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && ++ ++ # and set any options; do chmod last to preserve setuid bits. ++ # ++ # If any of these fail, we abort the whole thing. If we want to ++ # ignore errors from any of these, just make sure not to ignore ++ # errors from the above "$doit $cpprog $src $dsttmp" command. ++ # ++ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && ++ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && ++ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && ++ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && ++ ++ # If -C, don't bother to copy if it wouldn't change the file. ++ if $copy_on_change && ++ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && ++ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && ++ ++ eval "$initialize_posix_glob" && ++ $posix_glob set -f && ++ set X $old && old=:$2:$4:$5:$6 && ++ set X $new && new=:$2:$4:$5:$6 && ++ $posix_glob set +f && ++ ++ test "$old" = "$new" && ++ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 ++ then ++ rm -f "$dsttmp" ++ else ++ # Rename the file to the real destination. ++ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || ++ ++ # The rename failed, perhaps because mv can't rename something else ++ # to itself, or perhaps because mv is so ancient that it does not ++ # support -f. ++ { ++ # Now remove or move aside any old file at destination location. ++ # We try this two ways since rm can't unlink itself on some ++ # systems and the destination file might be busy for other ++ # reasons. In this case, the final cleanup might fail but the new ++ # file should still install successfully. ++ { ++ test ! -f "$dst" || ++ $doit $rmcmd -f "$dst" 2>/dev/null || ++ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && ++ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } ++ } || ++ { echo "$0: cannot unlink or rename $dst" >&2 ++ (exit 1); exit 1 ++ } ++ } && ++ ++ # Now rename the file to the real destination. ++ $doit $mvcmd "$dsttmp" "$dst" ++ } ++ fi || exit 1 + ++ trap '' 0 ++ fi ++done + +-exit 0 ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-time-zone: "UTC" ++# time-stamp-end: "; # UTC" ++# End: +diff -urN glibc-2.17-c758a686/scripts/mkinstalldirs glibc-2.17-c758a686/scripts/mkinstalldirs +--- glibc-2.17-c758a686/scripts/mkinstalldirs 2014-05-26 15:59:45.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/mkinstalldirs 2014-05-26 16:00:34.000000000 -0500 +@@ -1,38 +1,162 @@ + #! /bin/sh + # mkinstalldirs --- make directory hierarchy +-# Author: Noah Friedman +-# Created: 1993-05-16 +-# Public domain + ++scriptversion=2009-04-28.21; # UTC ++ ++# Original author: Noah Friedman ++# Created: 1993-05-16 ++# Public domain. ++# ++# This file is maintained in Automake, please report ++# bugs to or send patches to ++# . ++ ++nl=' ++' ++IFS=" "" $nl" + errstatus=0 ++dirmode= ++ ++usage="\ ++Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... ++ ++Create each directory DIR (with mode MODE, if specified), including all ++leading file name components. ++ ++Report bugs to ." ++ ++# process command line arguments ++while test $# -gt 0 ; do ++ case $1 in ++ -h | --help | --h*) # -h for help ++ echo "$usage" ++ exit $? ++ ;; ++ -m) # -m PERM arg ++ shift ++ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } ++ dirmode=$1 ++ shift ++ ;; ++ --version) ++ echo "$0 $scriptversion" ++ exit $? ++ ;; ++ --) # stop option processing ++ shift ++ break ++ ;; ++ -*) # unknown option ++ echo "$usage" 1>&2 ++ exit 1 ++ ;; ++ *) # first non-opt arg ++ break ++ ;; ++ esac ++done + + for file + do +- set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` +- shift ++ if test -d "$file"; then ++ shift ++ else ++ break ++ fi ++done ++ ++case $# in ++ 0) exit 0 ;; ++esac ++ ++# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and ++# mkdir -p a/c at the same time, both will detect that a is missing, ++# one will create a, then the other will try to create a and die with ++# a "File exists" error. This is a problem when calling mkinstalldirs ++# from a parallel make. We use --version in the probe to restrict ++# ourselves to GNU mkdir, which is thread-safe. ++case $dirmode in ++ '') ++ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then ++ echo "mkdir -p -- $*" ++ exec mkdir -p -- "$@" ++ else ++ # On NextStep and OpenStep, the 'mkdir' command does not ++ # recognize any option. It will interpret all options as ++ # directories to create, and then abort because '.' already ++ # exists. ++ test -d ./-p && rmdir ./-p ++ test -d ./--version && rmdir ./--version ++ fi ++ ;; ++ *) ++ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && ++ test ! -d ./--version; then ++ echo "mkdir -m $dirmode -p -- $*" ++ exec mkdir -m "$dirmode" -p -- "$@" ++ else ++ # Clean up after NextStep and OpenStep mkdir. ++ for d in ./-m ./-p ./--version "./$dirmode"; ++ do ++ test -d $d && rmdir $d ++ done ++ fi ++ ;; ++esac + +- pathcomp= +- for d +- do +- pathcomp="$pathcomp$d" +- case "$pathcomp" in +- -* ) pathcomp=./$pathcomp ;; +- esac +- +- if test ! -d "$pathcomp"; then +- echo "mkdir $pathcomp" 1>&2 +- +- mkdir "$pathcomp" || lasterr=$? +- +- if test ! -d "$pathcomp"; then +- errstatus=$lasterr +- fi +- fi ++for file ++do ++ case $file in ++ /*) pathcomp=/ ;; ++ *) pathcomp= ;; ++ esac ++ oIFS=$IFS ++ IFS=/ ++ set fnord $file ++ shift ++ IFS=$oIFS ++ ++ for d ++ do ++ test "x$d" = x && continue ++ ++ pathcomp=$pathcomp$d ++ case $pathcomp in ++ -*) pathcomp=./$pathcomp ;; ++ esac ++ ++ if test ! -d "$pathcomp"; then ++ echo "mkdir $pathcomp" ++ ++ mkdir "$pathcomp" || lasterr=$? ++ ++ if test ! -d "$pathcomp"; then ++ errstatus=$lasterr ++ else ++ if test ! -z "$dirmode"; then ++ echo "chmod $dirmode $pathcomp" ++ lasterr= ++ chmod "$dirmode" "$pathcomp" || lasterr=$? ++ ++ if test ! -z "$lasterr"; then ++ errstatus=$lasterr ++ fi ++ fi ++ fi ++ fi + +- pathcomp="$pathcomp/" +- done ++ pathcomp=$pathcomp/ ++ done + done + + exit $errstatus + +-# mkinstalldirs ends here ++# Local Variables: ++# mode: shell-script ++# sh-indentation: 2 ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-time-zone: "UTC" ++# time-stamp-end: "; # UTC" ++# End: +diff -urN glibc-2.17-c758a686/scripts/move-if-change glibc-2.17-c758a686/scripts/move-if-change +--- glibc-2.17-c758a686/scripts/move-if-change 2014-05-26 15:59:45.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/move-if-change 2014-05-26 16:00:34.000000000 -0500 +@@ -1,17 +1,83 @@ + #!/bin/sh + # Like mv $1 $2, but if the files are the same, just delete $1. +-# Status is 0 if $2 is changed, 1 otherwise. +-if +-test -r $2 +-then +-if +-cmp -s $1 $2 +-then +-echo $2 is unchanged +-rm -f $1 ++# Status is zero if successful, nonzero otherwise. ++ ++VERSION='2012-01-06 07:23'; # UTC ++# The definition above must lie within the first 8 lines in order ++# for the Emacs time-stamp write hook (at end) to update it. ++# If you change this file with Emacs, please let the write hook ++# do its job. Otherwise, update this string manually. ++ ++# Copyright (C) 2002-2013 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++usage="usage: $0 SOURCE DEST" ++ ++help="$usage ++ or: $0 OPTION ++If SOURCE is different than DEST, then move it to DEST; else remove SOURCE. ++ ++ --help display this help and exit ++ --version output version information and exit ++ ++The variable CMPPROG can be used to specify an alternative to 'cmp'. ++ ++Report bugs to ." ++ ++version=`expr "$VERSION" : '\([^ ]*\)'` ++version="move-if-change (gnulib) $version ++Copyright (C) 2011 Free Software Foundation, Inc. ++License GPLv3+: GNU GPL version 3 or later ++This is free software: you are free to change and redistribute it. ++There is NO WARRANTY, to the extent permitted by law." ++ ++cmpprog=${CMPPROG-cmp} ++ ++for arg ++do ++ case $arg in ++ --help | --hel | --he | --h) ++ exec echo "$help" ;; ++ --version | --versio | --versi | --vers | --ver | --ve | --v) ++ exec echo "$version" ;; ++ --) ++ shift ++ break ;; ++ -*) ++ echo "$0: invalid option: $arg" >&2 ++ exit 1 ;; ++ *) ++ break ;; ++ esac ++done ++ ++test $# -eq 2 || { echo "$0: $usage" >&2; exit 1; } ++ ++if test -r "$2" && $cmpprog -- "$1" "$2" >/dev/null; then ++ rm -f -- "$1" + else +-mv -f $1 $2 +-fi +-else +-mv -f $1 $2 ++ if mv -f -- "$1" "$2"; then :; else ++ # Ignore failure due to a concurrent move-if-change. ++ test -r "$2" && $cmpprog -- "$1" "$2" >/dev/null && rm -f -- "$1" ++ fi + fi ++ ++## Local Variables: ++## eval: (add-hook 'write-file-hooks 'time-stamp) ++## time-stamp-start: "VERSION='" ++## time-stamp-format: "%:y-%02m-%02d %02H:%02M" ++## time-stamp-time-zone: "UTC" ++## time-stamp-end: "'; # UTC" ++## End: diff --git a/SOURCES/glibc-ppc64le-04.patch b/SOURCES/glibc-ppc64le-04.patch new file mode 100644 index 00000000..57612763 --- /dev/null +++ b/SOURCES/glibc-ppc64le-04.patch @@ -0,0 +1,676 @@ +# commit 9605ca6c085a749f29b6866a3e00bce1ba1a2698 +# Author: Alan Modra +# Date: Sat Aug 17 18:12:56 2013 +0930 +# +# IBM long double mechanical changes to support little-endian +# http://sourceware.org/ml/libc-alpha/2013-07/msg00001.html +# +# This patch starts the process of supporting powerpc64 little-endian +# long double in glibc. IBM long double is an array of two ieee +# doubles, so making union ibm_extended_long_double reflect this fact is +# the correct way to access fields of the doubles. +# +# * sysdeps/ieee754/ldbl-128ibm/ieee754.h +# (union ibm_extended_long_double): Define as an array of ieee754_double. +# (IBM_EXTENDED_LONG_DOUBLE_BIAS): Delete. +# * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c: Update all references +# to ibm_extended_long_double and IBM_EXTENDED_LONG_DOUBLE_BIAS. +# * sysdeps/ieee754/ldbl-128ibm/e_exp10l.c: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_expl.c: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/strtold_l.c: Likewise. +# * sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_exp10l.c 2014-05-26 21:08:10.000000000 -0500 +@@ -36,9 +36,9 @@ + else if (arg > LDBL_MAX_10_EXP + 1) + return LDBL_MAX * LDBL_MAX; + +- u.d = arg; +- arg_high = u.dd[0]; +- arg_low = u.dd[1]; ++ u.ld = arg; ++ arg_high = u.d[0].d; ++ arg_low = u.d[1].d; + exp_high = arg_high * log10_high; + exp_low = arg_high * log10_low + arg_low * M_LN10l; + return __ieee754_expl (exp_high) * __ieee754_expl (exp_low); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_expl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_expl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_expl.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_expl.c 2014-05-26 21:08:10.000000000 -0500 +@@ -162,39 +162,39 @@ + x = x + xl; + + /* Compute ex2 = 2^n_0 e^(argtable[tval1]) e^(argtable[tval2]). */ +- ex2_u.d = __expl_table[T_EXPL_RES1 + tval1] +- * __expl_table[T_EXPL_RES2 + tval2]; ++ ex2_u.ld = (__expl_table[T_EXPL_RES1 + tval1] ++ * __expl_table[T_EXPL_RES2 + tval2]); + n_i = (int)n; + /* 'unsafe' is 1 iff n_1 != 0. */ + unsafe = fabsl(n_i) >= -LDBL_MIN_EXP - 1; +- ex2_u.ieee.exponent += n_i >> unsafe; ++ ex2_u.d[0].ieee.exponent += n_i >> unsafe; + /* Fortunately, there are no subnormal lowpart doubles in + __expl_table, only normal values and zeros. + But after scaling it can be subnormal. */ +- exponent2 = ex2_u.ieee.exponent2 + (n_i >> unsafe); +- if (ex2_u.ieee.exponent2 == 0) +- /* assert ((ex2_u.ieee.mantissa2|ex2_u.ieee.mantissa3) == 0) */; ++ exponent2 = ex2_u.d[1].ieee.exponent + (n_i >> unsafe); ++ if (ex2_u.d[1].ieee.exponent == 0) ++ /* assert ((ex2_u.d[1].ieee.mantissa0|ex2_u.d[1].ieee.mantissa1) == 0) */; + else if (exponent2 > 0) +- ex2_u.ieee.exponent2 = exponent2; ++ ex2_u.d[1].ieee.exponent = exponent2; + else if (exponent2 <= -54) + { +- ex2_u.ieee.exponent2 = 0; +- ex2_u.ieee.mantissa2 = 0; +- ex2_u.ieee.mantissa3 = 0; ++ ex2_u.d[1].ieee.exponent = 0; ++ ex2_u.d[1].ieee.mantissa0 = 0; ++ ex2_u.d[1].ieee.mantissa1 = 0; + } + else + { + static const double + two54 = 1.80143985094819840000e+16, /* 4350000000000000 */ + twom54 = 5.55111512312578270212e-17; /* 3C90000000000000 */ +- ex2_u.dd[1] *= two54; +- ex2_u.ieee.exponent2 += n_i >> unsafe; +- ex2_u.dd[1] *= twom54; ++ ex2_u.d[1].d *= two54; ++ ex2_u.d[1].ieee.exponent += n_i >> unsafe; ++ ex2_u.d[1].d *= twom54; + } + + /* Compute scale = 2^n_1. */ +- scale_u.d = 1.0L; +- scale_u.ieee.exponent += n_i - (n_i >> unsafe); ++ scale_u.ld = 1.0L; ++ scale_u.d[0].ieee.exponent += n_i - (n_i >> unsafe); + + /* Approximate e^x2 - 1, using a seventh-degree polynomial, + with maximum error in [-2^-16-2^-53,2^-16+2^-53] +@@ -204,7 +204,7 @@ + /* Return result. */ + fesetenv (&oldenv); + +- result = x22 * ex2_u.d + ex2_u.d; ++ result = x22 * ex2_u.ld + ex2_u.ld; + + /* Now we can test whether the result is ultimate or if we are unsure. + In the later case we should probably call a mpn based routine to give +@@ -238,7 +238,7 @@ + if (!unsafe) + return result; + else +- return result * scale_u.d; ++ return result * scale_u.ld; + } + /* Exceptional cases: */ + else if (isless (x, himark)) +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h 2014-05-26 21:08:10.000000000 -0500 +@@ -180,29 +180,9 @@ + + union ibm_extended_long_double + { +- long double d; +- double dd[2]; +- +- /* This is the IBM extended format long double. */ +- struct +- { /* Big endian. There is no other. */ +- +- unsigned int negative:1; +- unsigned int exponent:11; +- /* Together Mantissa0-3 comprise the mantissa. */ +- unsigned int mantissa0:20; +- unsigned int mantissa1:32; +- +- unsigned int negative2:1; +- unsigned int exponent2:11; +- /* There is an implied 1 here? */ +- /* Together these comprise the mantissa. */ +- unsigned int mantissa2:20; +- unsigned int mantissa3:32; +- } ieee; +- }; +- +-#define IBM_EXTENDED_LONG_DOUBLE_BIAS 0x3ff /* Added to exponent. */ ++ long double ld; ++ union ieee754_double d[2]; ++ }; + + __END_DECLS + +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c 2014-05-26 21:08:10.000000000 -0500 +@@ -36,22 +36,22 @@ + union ibm_extended_long_double u; + unsigned long long hi, lo; + int ediff; +- u.d = value; ++ u.ld = value; + +- *is_neg = u.ieee.negative; +- *expt = (int) u.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ *is_neg = u.d[0].ieee.negative; ++ *expt = (int) u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS; + +- lo = ((long long) u.ieee.mantissa2 << 32) | u.ieee.mantissa3; +- hi = ((long long) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; ++ lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; ++ hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; + /* If the lower double is not a denomal or zero then set the hidden + 53rd bit. */ +- if (u.ieee.exponent2 > 0) ++ if (u.d[1].ieee.exponent > 0) + { + lo |= 1LL << 52; + + /* The lower double is normalized separately from the upper. We may + need to adjust the lower manitissa to reflect this. */ +- ediff = u.ieee.exponent - u.ieee.exponent2; ++ ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent; + if (ediff > 53) + lo = lo >> (ediff-53); + } +@@ -59,8 +59,8 @@ + difference between the long double and the rounded high double + value. This is indicated by a differnce between the signs of the + high and low doubles. */ +- if ((u.ieee.negative != u.ieee.negative2) +- && ((u.ieee.exponent2 != 0) && (lo != 0L))) ++ if ((u.d[0].ieee.negative != u.d[1].ieee.negative) ++ && ((u.d[1].ieee.exponent != 0) && (lo != 0L))) + { + lo = (1ULL << 53) - lo; + if (hi == 0LL) +@@ -92,7 +92,7 @@ + #define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \ + - (LDBL_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB))) + +- if (u.ieee.exponent == 0) ++ if (u.d[0].ieee.exponent == 0) + { + /* A biased exponent of zero is a special case. + Either it is a zero or it is a denormal number. */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-26 21:08:10.000000000 -0500 +@@ -14,28 +14,28 @@ + as bit 53 of the mantissa. */ + uint64_t hi, lo; + int ediff; +- union ibm_extended_long_double eldbl; +- eldbl.d = x; +- *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ union ibm_extended_long_double u; ++ u.ld = x; ++ *exp = u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS; + +- lo = ((int64_t)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; +- hi = ((int64_t)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; ++ lo = ((uint64_t)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; ++ hi = ((uint64_t)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; + /* If the lower double is not a denomal or zero then set the hidden + 53rd bit. */ +- if (eldbl.ieee.exponent2 > 0x001) ++ if (u.d[1].ieee.exponent > 0x001) + { + lo |= (1ULL << 52); + lo = lo << 7; /* pre-shift lo to match ieee854. */ + /* The lower double is normalized separately from the upper. We + may need to adjust the lower manitissa to reflect this. */ +- ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; ++ ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent; + if (ediff > 53) + lo = lo >> (ediff-53); + hi |= (1ULL << 52); + } + +- if ((eldbl.ieee.negative != eldbl.ieee.negative2) +- && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) ++ if ((u.d[0].ieee.negative != u.d[1].ieee.negative) ++ && ((u.d[1].ieee.exponent != 0) && (lo != 0LL))) + { + hi--; + lo = (1ULL << 60) - lo; +@@ -58,10 +58,10 @@ + unsigned long hidden2, lzcount; + unsigned long long hi, lo; + +- u.ieee.negative = sign; +- u.ieee.negative2 = sign; +- u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; +- u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ u.d[0].ieee.negative = sign; ++ u.d[1].ieee.negative = sign; ++ u.d[0].ieee.exponent = exp + IEEE754_DOUBLE_BIAS; ++ u.d[1].ieee.exponent = exp-53 + IEEE754_DOUBLE_BIAS; + /* Expect 113 bits (112 bits + hidden) right justified in two longs. + The low order 53 bits (52 + hidden) go into the lower double */ + lo = (lo64 >> 7)& ((1ULL << 53) - 1); +@@ -78,7 +78,7 @@ + if (hidden2) + { + hi++; +- u.ieee.negative2 = !sign; ++ u.d[1].ieee.negative = !sign; + lo = (1ULL << 53) - lo; + } + /* The hidden bit of the lo mantissa is zero so we need to +@@ -94,32 +94,32 @@ + lzcount = lzcount - 11; + if (lzcount > 0) + { +- int expnt2 = u.ieee.exponent2 - lzcount; ++ int expnt2 = u.d[1].ieee.exponent - lzcount; + if (expnt2 >= 1) + { + /* Not denormal. Normalize and set low exponent. */ + lo = lo << lzcount; +- u.ieee.exponent2 = expnt2; ++ u.d[1].ieee.exponent = expnt2; + } + else + { + /* Is denormal. */ + lo = lo << (lzcount + expnt2); +- u.ieee.exponent2 = 0; ++ u.d[1].ieee.exponent = 0; + } + } + } + else + { +- u.ieee.negative2 = 0; +- u.ieee.exponent2 = 0; ++ u.d[1].ieee.negative = 0; ++ u.d[1].ieee.exponent = 0; + } + +- u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); +- u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); +- u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); +- u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); +- return u.d; ++ u.d[1].ieee.mantissa1 = lo & ((1ULL << 32) - 1); ++ u.d[1].ieee.mantissa0 = (lo >> 32) & ((1ULL << 20) - 1); ++ u.d[0].ieee.mantissa1 = hi & ((1ULL << 32) - 1); ++ u.d[0].ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); ++ return u.ld; + } + + /* Handy utility functions to pack/unpack/cononicalize and find the nearbyint +@@ -128,18 +128,18 @@ + default_ldbl_pack (double a, double aa) + { + union ibm_extended_long_double u; +- u.dd[0] = a; +- u.dd[1] = aa; +- return u.d; ++ u.d[0].d = a; ++ u.d[1].d = aa; ++ return u.ld; + } + + static inline void + default_ldbl_unpack (long double l, double *a, double *aa) + { + union ibm_extended_long_double u; +- u.d = l; +- *a = u.dd[0]; +- *aa = u.dd[1]; ++ u.ld = l; ++ *a = u.d[0].d; ++ *aa = u.d[1].d; + } + + #ifndef ldbl_pack +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 2014-05-26 21:08:10.000000000 -0500 +@@ -34,11 +34,11 @@ + unsigned long long hi, lo; + int exponent2; + +- u.ieee.negative = sign; +- u.ieee.negative2 = sign; +- u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS; +- u.ieee.exponent2 = 0; +- exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ u.d[0].ieee.negative = sign; ++ u.d[1].ieee.negative = sign; ++ u.d[0].ieee.exponent = expt + IEEE754_DOUBLE_BIAS; ++ u.d[1].ieee.exponent = 0; ++ exponent2 = expt - 53 + IEEE754_DOUBLE_BIAS; + + #if BITS_PER_MP_LIMB == 32 + /* The low order 53 bits (52 + hidden) go into the lower double */ +@@ -74,15 +74,15 @@ + else + lzcount = lzcount + 42; + +- if (lzcount > u.ieee.exponent) ++ if (lzcount > u.d[0].ieee.exponent) + { +- lzcount = u.ieee.exponent; +- u.ieee.exponent = 0; ++ lzcount = u.d[0].ieee.exponent; ++ u.d[0].ieee.exponent = 0; + exponent2 -= lzcount; + } + else + { +- u.ieee.exponent -= (lzcount - 1); ++ u.d[0].ieee.exponent -= (lzcount - 1); + exponent2 -= (lzcount - 1); + } + +@@ -112,9 +112,9 @@ + { + if ((hi & (1LL << 53)) != 0) + hi -= 1LL << 52; +- u.ieee.exponent++; ++ u.d[0].ieee.exponent++; + } +- u.ieee.negative2 = !sign; ++ u.d[1].ieee.negative = !sign; + lo = (1LL << 53) - lo; + } + +@@ -135,17 +135,17 @@ + exponent2 = exponent2 - lzcount; + } + if (exponent2 > 0) +- u.ieee.exponent2 = exponent2; ++ u.d[1].ieee.exponent = exponent2; + else + lo >>= 1 - exponent2; + } + else +- u.ieee.negative2 = 0; ++ u.d[1].ieee.negative = 0; + +- u.ieee.mantissa3 = lo & 0xffffffffLL; +- u.ieee.mantissa2 = (lo >> 32) & 0xfffff; +- u.ieee.mantissa1 = hi & 0xffffffffLL; +- u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1); ++ u.d[1].ieee.mantissa1 = lo & 0xffffffffLL; ++ u.d[1].ieee.mantissa0 = (lo >> 32) & 0xfffff; ++ u.d[0].ieee.mantissa1 = hi & 0xffffffffLL; ++ u.d[0].ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1); + +- return u.d; ++ return u.ld; + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-26 21:08:10.000000000 -0500 +@@ -27,31 +27,31 @@ + unsigned long long int num0, num1; \ + unsigned long long hi, lo; \ + int ediff; \ +- union ibm_extended_long_double eldbl; \ +- eldbl.d = fpnum.ldbl.d; \ ++ union ibm_extended_long_double u; \ ++ u.ld = fpnum.ldbl.d; \ + \ + assert (sizeof (long double) == 16); \ + \ +- lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ +- hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ ++ lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; \ ++ hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; \ + lo <<= 7; /* pre-shift lo to match ieee854. */ \ + /* If the lower double is not a denomal or zero then set the hidden \ + 53rd bit. */ \ +- if (eldbl.ieee.exponent2 != 0) \ ++ if (u.d[1].ieee.exponent != 0) \ + lo |= (1ULL << (52 + 7)); \ + else \ + lo <<= 1; \ + /* The lower double is normalized separately from the upper. We \ + may need to adjust the lower manitissa to reflect this. */ \ +- ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ ++ ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent; \ + if (ediff > 53 + 63) \ + lo = 0; \ + else if (ediff > 53) \ + lo = lo >> (ediff - 53); \ +- else if (eldbl.ieee.exponent2 == 0 && ediff < 53) \ ++ else if (u.d[1].ieee.exponent == 0 && ediff < 53) \ + lo = lo << (53 - ediff); \ +- if (eldbl.ieee.negative != eldbl.ieee.negative2 \ +- && (eldbl.ieee.exponent2 != 0 || lo != 0L)) \ ++ if (u.d[0].ieee.negative != u.d[1].ieee.negative \ ++ && (u.d[1].ieee.exponent != 0 || lo != 0L)) \ + { \ + lo = (1ULL << 60) - lo; \ + if (hi == 0L) \ +@@ -59,7 +59,7 @@ + /* we have a borrow from the hidden bit, so shift left 1. */ \ + hi = 0xffffffffffffeLL | (lo >> 59); \ + lo = 0xfffffffffffffffLL & (lo << 1); \ +- eldbl.ieee.exponent--; \ ++ u.d[0].ieee.exponent--; \ + } \ + else \ + hi--; \ +@@ -110,9 +110,9 @@ + *--wnumstr = L'0'; \ + } \ + \ +- leading = eldbl.ieee.exponent == 0 ? '0' : '1'; \ ++ leading = u.d[0].ieee.exponent == 0 ? '0' : '1'; \ + \ +- exponent = eldbl.ieee.exponent; \ ++ exponent = u.d[0].ieee.exponent; \ + \ + if (exponent == 0) \ + { \ +@@ -122,18 +122,18 @@ + { \ + /* This is a denormalized number. */ \ + expnegative = 1; \ +- exponent = IBM_EXTENDED_LONG_DOUBLE_BIAS - 1; \ ++ exponent = IEEE754_DOUBLE_BIAS - 1; \ + } \ + } \ +- else if (exponent >= IBM_EXTENDED_LONG_DOUBLE_BIAS) \ ++ else if (exponent >= IEEE754_DOUBLE_BIAS) \ + { \ + expnegative = 0; \ +- exponent -= IBM_EXTENDED_LONG_DOUBLE_BIAS; \ ++ exponent -= IEEE754_DOUBLE_BIAS; \ + } \ + else \ + { \ + expnegative = 1; \ +- exponent = -(exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS); \ ++ exponent = -(exponent - IEEE754_DOUBLE_BIAS); \ + } \ + } while (0) + +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c 2014-05-26 21:08:10.000000000 -0500 +@@ -33,11 +33,11 @@ + fenv_t env; + static const long double TWO52 = 4503599627370496.0L; + union ibm_extended_long_double u; +- u.d = x; ++ u.ld = x; + +- if (fabs (u.dd[0]) < TWO52) ++ if (fabs (u.d[0].d) < TWO52) + { +- double high = u.dd[0]; ++ double high = u.d[0].d; + feholdexcept (&env); + if (high > 0.0) + { +@@ -51,11 +51,11 @@ + high += TWO52; + if (high == 0.0) high = -0.0; + } +- u.dd[0] = high; +- u.dd[1] = 0.0; ++ u.d[0].d = high; ++ u.d[1].d = 0.0; + fesetenv (&env); + } +- else if (fabs (u.dd[1]) < TWO52 && u.dd[1] != 0.0) ++ else if (fabs (u.d[1].d) < TWO52 && u.d[1].d != 0.0) + { + double high, low, tau; + /* In this case we have to round the low double and handle any +@@ -64,55 +64,55 @@ + may already be rounded and the low double may have the + opposite sign to compensate. */ + feholdexcept (&env); +- if (u.dd[0] > 0.0) ++ if (u.d[0].d > 0.0) + { +- if (u.dd[1] > 0.0) ++ if (u.d[1].d > 0.0) + { + /* If the high/low doubles are the same sign then simply + round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; ++ high = u.d[0].d; ++ low = u.d[1].d; + } +- else if (u.dd[1] < 0.0) ++ else if (u.d[1].d < 0.0) + { + /* Else the high double is pre rounded and we need to + adjust for that. */ + +- tau = __nextafter (u.dd[0], 0.0); +- tau = (u.dd[0] - tau) * 2.0; +- high = u.dd[0] - tau; +- low = u.dd[1] + tau; ++ tau = __nextafter (u.d[0].d, 0.0); ++ tau = (u.d[0].d - tau) * 2.0; ++ high = u.d[0].d - tau; ++ low = u.d[1].d + tau; + } + low += TWO52; + low -= TWO52; + } +- else if (u.dd[0] < 0.0) ++ else if (u.d[0].d < 0.0) + { +- if (u.dd[1] < 0.0) ++ if (u.d[1].d < 0.0) + { + /* If the high/low doubles are the same sign then simply + round the low double. */ +- high = u.dd[0]; +- low = u.dd[1]; ++ high = u.d[0].d; ++ low = u.d[1].d; + } +- else if (u.dd[1] > 0.0) ++ else if (u.d[1].d > 0.0) + { + /* Else the high double is pre rounded and we need to + adjust for that. */ +- tau = __nextafter (u.dd[0], 0.0); +- tau = (u.dd[0] - tau) * 2.0; +- high = u.dd[0] - tau; +- low = u.dd[1] + tau; ++ tau = __nextafter (u.d[0].d, 0.0); ++ tau = (u.d[0].d - tau) * 2.0; ++ high = u.d[0].d - tau; ++ low = u.d[1].d + tau; + } + low = TWO52 - low; + low = -(low - TWO52); + } +- u.dd[0] = high + low; +- u.dd[1] = high - u.dd[0] + low; ++ u.d[0].d = high + low; ++ u.d[1].d = high - u.d[0].d + low; + fesetenv (&env); + } + +- return u.d; ++ return u.ld; + } + + long_double_symbol (libm, __nearbyintl, nearbyintl); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/strtold_l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/strtold_l.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/strtold_l.c 2014-05-26 21:12:01.000000000 -0500 +@@ -43,12 +43,11 @@ + #define FLOAT_HUGE_VAL HUGE_VALL + # define SET_MANTISSA(flt, mant) \ + do { union ibm_extended_long_double u; \ +- u.d = (flt); \ +- if ((mant & 0xfffffffffffffULL) == 0) \ +- mant = 0x8000000000000ULL; \ +- u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff; \ +- u.ieee.mantissa1 = (mant) & 0xffffffff; \ +- (flt) = u.d; \ ++ u.ld = (flt); \ ++ u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.d[0].ieee_nan.mantissa1 = (mant); \ ++ if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ ++ (flt) = u.ld; \ + } while (0) + + #include +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c 2014-05-26 21:08:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c 2014-05-26 21:08:10.000000000 -0500 +@@ -89,23 +89,23 @@ + double vals[12]; + SET_RESTORE_ROUND (FE_TONEAREST); + union ibm_extended_long_double xu, yu; +- xu.d = x; +- yu.d = y; +- if (fabs (xu.dd[1]) < 0x1p-500) +- xu.dd[1] = 0.0; +- if (fabs (yu.dd[1]) < 0x1p-500) +- yu.dd[1] = 0.0; +- mul_split (&vals[1], &vals[0], xu.dd[0], xu.dd[0]); +- mul_split (&vals[3], &vals[2], xu.dd[0], xu.dd[1]); ++ xu.ld = x; ++ yu.ld = y; ++ if (fabs (xu.d[1].d) < 0x1p-500) ++ xu.d[1].d = 0.0; ++ if (fabs (yu.d[1].d) < 0x1p-500) ++ yu.d[1].d = 0.0; ++ mul_split (&vals[1], &vals[0], xu.d[0].d, xu.d[0].d); ++ mul_split (&vals[3], &vals[2], xu.d[0].d, xu.d[1].d); + vals[2] *= 2.0; + vals[3] *= 2.0; +- mul_split (&vals[5], &vals[4], xu.dd[1], xu.dd[1]); +- mul_split (&vals[7], &vals[6], yu.dd[0], yu.dd[0]); +- mul_split (&vals[9], &vals[8], yu.dd[0], yu.dd[1]); ++ mul_split (&vals[5], &vals[4], xu.d[1].d, xu.d[1].d); ++ mul_split (&vals[7], &vals[6], yu.d[0].d, yu.d[0].d); ++ mul_split (&vals[9], &vals[8], yu.d[0].d, yu.d[1].d); + vals[8] *= 2.0; + vals[9] *= 2.0; +- mul_split (&vals[11], &vals[10], yu.dd[1], yu.dd[1]); +- if (xu.dd[0] >= 0.75) ++ mul_split (&vals[11], &vals[10], yu.d[1].d, yu.d[1].d); ++ if (xu.d[0].d >= 0.75) + vals[1] -= 1.0; + else + { diff --git a/SOURCES/glibc-ppc64le-05.patch b/SOURCES/glibc-ppc64le-05.patch new file mode 100644 index 00000000..fcb37cc2 --- /dev/null +++ b/SOURCES/glibc-ppc64le-05.patch @@ -0,0 +1,486 @@ +# commit 4cf69995e26e16005d4e3843ad4d18c75cf21a04 +# Author: Alan Modra +# Date: Sat Aug 17 18:19:44 2013 +0930 +# +# Fix for [BZ #15680] IBM long double inaccuracy +# http://sourceware.org/ml/libc-alpha/2013-06/msg00919.html +# +# I discovered a number of places where denormals and other corner cases +# were being handled wrongly. +# +# - printf_fphex.c: Testing for the low double exponent being zero is +# unnecessary. If the difference in exponents is less than 53 then the +# high double exponent must be nearing the low end of its range, and the +# low double exponent hit rock bottom. +# +# - ldbl2mpn.c: A denormal (ie. exponent of zero) value is treated as +# if the exponent was one, so shift mantissa left by one. Code handling +# normalisation of the low double mantissa lacked a test for shift count +# greater than bits in type being shifted, and lacked anything to handle +# the case where the difference in exponents is less than 53 as in +# printf_fphex.c. +# +# - math_ldbl.h (ldbl_extract_mantissa): Same as above, but worse, with +# code testing for exponent > 1 for some reason, probably a typo for >= 1. +# +# - math_ldbl.h (ldbl_insert_mantissa): Round the high double as per +# mpn2ldbl.c (hi is odd or explicit mantissas non-zero) so that the +# number we return won't change when applying ldbl_canonicalize(). +# Add missing overflow checks and normalisation of high mantissa. +# Correct misleading comment: "The hidden bit of the lo mantissa is +# zero" is not always true as can be seen from the code rounding the hi +# mantissa. Also by inspection, lzcount can never be less than zero so +# remove that test. Lastly, masking bitfields to their widths can be +# left to the compiler. +# +# - mpn2ldbl.c: The overflow checks here on rounding of high double were +# just plain wrong. Incrementing the exponent must be accompanied by a +# shift right of the mantissa to keep the value unchanged. Above notes +# for ldbl_insert_mantissa are also relevant. +# +# [BZ #15680] +# * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c: Comment fix. +# * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +# (PRINT_FPHEX_LONG_DOUBLE): Tidy code by moving -53 into ediff +# calculation. Remove unnecessary test for denormal exponent. +# * sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c (__mpn_extract_long_double): +# Correct handling of denormals. Avoid undefined shift behaviour. +# Correct normalisation of low mantissa when low double is denormal. +# * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +# (ldbl_extract_mantissa): Likewise. Comment. Use uint64_t* for hi64. +# (ldbl_insert_mantissa): Make both hi64 and lo64 parms uint64_t. +# Correct normalisation of low mantissa. Test for overflow of high +# mantissa and normalise. +# (ldbl_nearbyint): Use more readable constant for two52. +# * sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c +# (__mpn_construct_long_double): Fix test for overflow of high +# mantissa and correct normalisation. Avoid undefined shift. +# +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 2014-05-27 19:13:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 2014-05-27 19:14:45.000000000 -0500 +@@ -243,7 +243,7 @@ + We split the 113 bits of the mantissa into 5 24bit integers + stored in a double array. */ + /* Make the IBM extended format 105 bit mantissa look like the ieee854 112 +- bit mantissa so the next operatation will give the correct result. */ ++ bit mantissa so the next operation will give the correct result. */ + ldbl_extract_mantissa (&ixd, &lxd, &exp, x); + exp = exp - 23; + /* This is faster than doing this in floating point, because we +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c 2014-05-27 19:13:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ldbl2mpn.c 2014-05-27 19:14:45.000000000 -0500 +@@ -36,6 +36,7 @@ + union ibm_extended_long_double u; + unsigned long long hi, lo; + int ediff; ++ + u.ld = value; + + *is_neg = u.d[0].ieee.negative; +@@ -43,27 +44,36 @@ + + lo = ((long long) u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; + hi = ((long long) u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; +- /* If the lower double is not a denomal or zero then set the hidden ++ ++ /* If the lower double is not a denormal or zero then set the hidden + 53rd bit. */ +- if (u.d[1].ieee.exponent > 0) +- { +- lo |= 1LL << 52; ++ if (u.d[1].ieee.exponent != 0) ++ lo |= 1ULL << 52; ++ else ++ lo = lo << 1; + +- /* The lower double is normalized separately from the upper. We may +- need to adjust the lower manitissa to reflect this. */ +- ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent; +- if (ediff > 53) +- lo = lo >> (ediff-53); ++ /* The lower double is normalized separately from the upper. We may ++ need to adjust the lower manitissa to reflect this. */ ++ ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; ++ if (ediff > 0) ++ { ++ if (ediff < 64) ++ lo = lo >> ediff; ++ else ++ lo = 0; + } ++ else if (ediff < 0) ++ lo = lo << -ediff; ++ + /* The high double may be rounded and the low double reflects the + difference between the long double and the rounded high double + value. This is indicated by a differnce between the signs of the + high and low doubles. */ +- if ((u.d[0].ieee.negative != u.d[1].ieee.negative) +- && ((u.d[1].ieee.exponent != 0) && (lo != 0L))) ++ if (u.d[0].ieee.negative != u.d[1].ieee.negative ++ && lo != 0) + { + lo = (1ULL << 53) - lo; +- if (hi == 0LL) ++ if (hi == 0) + { + /* we have a borrow from the hidden bit, so shift left 1. */ + hi = 0x0ffffffffffffeLL | (lo >> 51); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 19:13:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 19:51:13.000000000 -0500 +@@ -13,77 +13,118 @@ + the number before the decimal point and the second implicit bit + as bit 53 of the mantissa. */ + uint64_t hi, lo; +- int ediff; + union ibm_extended_long_double u; ++ + u.ld = x; + *exp = u.d[0].ieee.exponent - IEEE754_DOUBLE_BIAS; + + lo = ((uint64_t)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; + hi = ((uint64_t)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; +- /* If the lower double is not a denomal or zero then set the hidden +- 53rd bit. */ +- if (u.d[1].ieee.exponent > 0x001) +- { +- lo |= (1ULL << 52); +- lo = lo << 7; /* pre-shift lo to match ieee854. */ +- /* The lower double is normalized separately from the upper. We +- may need to adjust the lower manitissa to reflect this. */ +- ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent; +- if (ediff > 53) +- lo = lo >> (ediff-53); +- hi |= (1ULL << 52); +- } + +- if ((u.d[0].ieee.negative != u.d[1].ieee.negative) +- && ((u.d[1].ieee.exponent != 0) && (lo != 0LL))) ++ if (u.d[0].ieee.exponent != 0) + { +- hi--; +- lo = (1ULL << 60) - lo; +- if (hi < (1ULL << 52)) ++ int ediff; ++ ++ /* If not a denormal or zero then we have an implicit 53rd bit. */ ++ hi |= (uint64_t) 1 << 52; ++ ++ if (u.d[1].ieee.exponent != 0) ++ lo |= (uint64_t) 1 << 52; ++ else ++ /* A denormal is to be interpreted as having a biased exponent ++ of 1. */ ++ lo = lo << 1; ++ ++ /* We are going to shift 4 bits out of hi later, because we only ++ want 48 bits in *hi64. That means we want 60 bits in lo, but ++ we currently only have 53. Shift the value up. */ ++ lo = lo << 7; ++ ++ /* The lower double is normalized separately from the upper. ++ We may need to adjust the lower mantissa to reflect this. ++ The difference between the exponents can be larger than 53 ++ when the low double is much less than 1ULP of the upper ++ (in which case there are significant bits, all 0's or all ++ 1's, between the two significands). The difference between ++ the exponents can be less than 53 when the upper double ++ exponent is nearing its minimum value (in which case the low ++ double is denormal ie. has an exponent of zero). */ ++ ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; ++ if (ediff > 0) + { +- /* we have a borrow from the hidden bit, so shift left 1. */ +- hi = (hi << 1) | (lo >> 59); +- lo = 0xfffffffffffffffLL & (lo << 1); +- *exp = *exp - 1; ++ if (ediff < 64) ++ lo = lo >> ediff; ++ else ++ lo = 0; ++ } ++ else if (ediff < 0) ++ lo = lo << -ediff; ++ ++ if (u.d[0].ieee.negative != u.d[1].ieee.negative ++ && lo != 0) ++ { ++ hi--; ++ lo = ((uint64_t) 1 << 60) - lo; ++ if (hi < (uint64_t) 1 << 52) ++ { ++ /* We have a borrow from the hidden bit, so shift left 1. */ ++ hi = (hi << 1) | (lo >> 59); ++ lo = (((uint64_t) 1 << 60) - 1) & (lo << 1); ++ *exp = *exp - 1; ++ } + } + } ++ else ++ /* If the larger magnitude double is denormal then the smaller ++ one must be zero. */ ++ hi = hi << 1; ++ + *lo64 = (hi << 60) | lo; + *hi64 = hi >> 4; + } + + static inline long double +-ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) ++ldbl_insert_mantissa (int sign, int exp, int64_t hi64, uint64_t lo64) + { + union ibm_extended_long_double u; +- unsigned long hidden2, lzcount; +- unsigned long long hi, lo; ++ int expnt2; ++ uint64_t hi, lo; + + u.d[0].ieee.negative = sign; + u.d[1].ieee.negative = sign; + u.d[0].ieee.exponent = exp + IEEE754_DOUBLE_BIAS; +- u.d[1].ieee.exponent = exp-53 + IEEE754_DOUBLE_BIAS; ++ u.d[1].ieee.exponent = 0; ++ expnt2 = exp - 53 + IEEE754_DOUBLE_BIAS; ++ + /* Expect 113 bits (112 bits + hidden) right justified in two longs. + The low order 53 bits (52 + hidden) go into the lower double */ +- lo = (lo64 >> 7)& ((1ULL << 53) - 1); +- hidden2 = (lo64 >> 59) & 1ULL; ++ lo = (lo64 >> 7) & (((uint64_t) 1 << 53) - 1); + /* The high order 53 bits (52 + hidden) go into the upper double */ +- hi = (lo64 >> 60) & ((1ULL << 11) - 1); +- hi |= (hi64 << 4); ++ hi = lo64 >> 60; ++ hi |= hi64 << 4; + +- if (lo != 0LL) ++ if (lo != 0) + { +- /* hidden2 bit of low double controls rounding of the high double. +- If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) ++ int lzcount; ++ ++ /* hidden bit of low double controls rounding of the high double. ++ If hidden is '1' and either the explicit mantissa is non-zero ++ or hi is odd, then round up hi and adjust lo (2nd mantissa) + plus change the sign of the low double to compensate. */ +- if (hidden2) ++ if ((lo & ((uint64_t) 1 << 52)) != 0 ++ && ((hi & 1) != 0 || (lo & (((uint64_t) 1 << 52) - 1)) != 0)) + { + hi++; ++ if ((hi & ((uint64_t) 1 << 53)) != 0) ++ { ++ hi = hi >> 1; ++ u.d[0].ieee.exponent++; ++ } + u.d[1].ieee.negative = !sign; +- lo = (1ULL << 53) - lo; ++ lo = ((uint64_t) 1 << 53) - lo; + } +- /* The hidden bit of the lo mantissa is zero so we need to +- normalize the it for the low double. Shift it left until the +- hidden bit is '1' then adjust the 2nd exponent accordingly. */ ++ /* Normalize the low double. Shift the mantissa left until ++ the hidden bit is '1' and adjust the exponent accordingly. */ + + if (sizeof (lo) == sizeof (long)) + lzcount = __builtin_clzl (lo); +@@ -91,34 +132,30 @@ + lzcount = __builtin_clzl ((long) (lo >> 32)); + else + lzcount = __builtin_clzl ((long) lo) + 32; +- lzcount = lzcount - 11; +- if (lzcount > 0) ++ lzcount = lzcount - (64 - 53); ++ lo <<= lzcount; ++ expnt2 -= lzcount; ++ ++ if (expnt2 >= 1) ++ /* Not denormal. */ ++ u.d[1].ieee.exponent = expnt2; ++ else + { +- int expnt2 = u.d[1].ieee.exponent - lzcount; +- if (expnt2 >= 1) +- { +- /* Not denormal. Normalize and set low exponent. */ +- lo = lo << lzcount; +- u.d[1].ieee.exponent = expnt2; +- } ++ /* Is denormal. Note that biased exponent of 0 is treated ++ as if it was 1, hence the extra shift. */ ++ if (expnt2 > -53) ++ lo >>= 1 - expnt2; + else +- { +- /* Is denormal. */ +- lo = lo << (lzcount + expnt2); +- u.d[1].ieee.exponent = 0; +- } ++ lo = 0; + } + } + else +- { +- u.d[1].ieee.negative = 0; +- u.d[1].ieee.exponent = 0; +- } ++ u.d[1].ieee.negative = 0; + +- u.d[1].ieee.mantissa1 = lo & ((1ULL << 32) - 1); +- u.d[1].ieee.mantissa0 = (lo >> 32) & ((1ULL << 20) - 1); +- u.d[0].ieee.mantissa1 = hi & ((1ULL << 32) - 1); +- u.d[0].ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); ++ u.d[1].ieee.mantissa1 = lo; ++ u.d[1].ieee.mantissa0 = lo >> 32; ++ u.d[0].ieee.mantissa1 = hi; ++ u.d[0].ieee.mantissa0 = hi >> 32; + return u.ld; + } + +@@ -133,6 +170,10 @@ + return u.ld; + } + ++/* To suit our callers we return *hi64 and *lo64 as if they came from ++ an ieee854 112 bit mantissa, that is, 48 bits in *hi64 (plus one ++ implicit bit) and 64 bits in *lo64. */ ++ + static inline void + default_ldbl_unpack (long double l, double *a, double *aa) + { +@@ -162,13 +203,13 @@ + *aa = xl; + } + +-/* Simple inline nearbyint (double) function . ++/* Simple inline nearbyint (double) function. + Only works in the default rounding mode + but is useful in long double rounding functions. */ + static inline double + ldbl_nearbyint (double a) + { +- double two52 = 0x10000000000000LL; ++ double two52 = 0x1p52; + + if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) + { +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 2014-05-27 19:13:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 2014-05-27 19:14:45.000000000 -0500 +@@ -70,9 +70,9 @@ + else + lzcount = __builtin_clzl ((long) val) + 32; + if (hi) +- lzcount = lzcount - 11; ++ lzcount = lzcount - (64 - 53); + else +- lzcount = lzcount + 42; ++ lzcount = lzcount + 53 - (64 - 53); + + if (lzcount > u.d[0].ieee.exponent) + { +@@ -98,29 +98,27 @@ + } + } + +- if (lo != 0L) ++ if (lo != 0) + { +- /* hidden2 bit of low double controls rounding of the high double. +- If hidden2 is '1' and either the explicit mantissa is non-zero ++ /* hidden bit of low double controls rounding of the high double. ++ If hidden is '1' and either the explicit mantissa is non-zero + or hi is odd, then round up hi and adjust lo (2nd mantissa) + plus change the sign of the low double to compensate. */ + if ((lo & (1LL << 52)) != 0 +- && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)))) ++ && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)) != 0)) + { + hi++; +- if ((hi & ((1LL << 52) - 1)) == 0) ++ if ((hi & (1LL << 53)) != 0) + { +- if ((hi & (1LL << 53)) != 0) +- hi -= 1LL << 52; ++ hi >>= 1; + u.d[0].ieee.exponent++; + } + u.d[1].ieee.negative = !sign; + lo = (1LL << 53) - lo; + } + +- /* The hidden bit of the lo mantissa is zero so we need to normalize +- it for the low double. Shift it left until the hidden bit is '1' +- then adjust the 2nd exponent accordingly. */ ++ /* Normalize the low double. Shift the mantissa left until ++ the hidden bit is '1' and adjust the exponent accordingly. */ + + if (sizeof (lo) == sizeof (long)) + lzcount = __builtin_clzl (lo); +@@ -128,24 +126,24 @@ + lzcount = __builtin_clzl ((long) (lo >> 32)); + else + lzcount = __builtin_clzl ((long) lo) + 32; +- lzcount = lzcount - 11; +- if (lzcount > 0) +- { +- lo = lo << lzcount; +- exponent2 = exponent2 - lzcount; +- } ++ lzcount = lzcount - (64 - 53); ++ lo <<= lzcount; ++ exponent2 -= lzcount; ++ + if (exponent2 > 0) + u.d[1].ieee.exponent = exponent2; +- else ++ else if (exponent2 > -53) + lo >>= 1 - exponent2; ++ else ++ lo = 0; + } + else + u.d[1].ieee.negative = 0; + +- u.d[1].ieee.mantissa1 = lo & 0xffffffffLL; +- u.d[1].ieee.mantissa0 = (lo >> 32) & 0xfffff; +- u.d[0].ieee.mantissa1 = hi & 0xffffffffLL; +- u.d[0].ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1); ++ u.d[1].ieee.mantissa1 = lo; ++ u.d[1].ieee.mantissa0 = lo >> 32; ++ u.d[0].ieee.mantissa1 = hi; ++ u.d[0].ieee.mantissa0 = hi >> 32; + + return u.ld; + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-27 19:13:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-27 19:14:45.000000000 -0500 +@@ -43,15 +43,15 @@ + lo <<= 1; \ + /* The lower double is normalized separately from the upper. We \ + may need to adjust the lower manitissa to reflect this. */ \ +- ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent; \ +- if (ediff > 53 + 63) \ ++ ediff = u.d[0].ieee.exponent - u.d[1].ieee.exponent - 53; \ ++ if (ediff > 63) \ + lo = 0; \ +- else if (ediff > 53) \ +- lo = lo >> (ediff - 53); \ +- else if (u.d[1].ieee.exponent == 0 && ediff < 53) \ +- lo = lo << (53 - ediff); \ ++ else if (ediff > 0) \ ++ lo = lo >> ediff; \ ++ else if (ediff < 0) \ ++ lo = lo << -ediff; \ + if (u.d[0].ieee.negative != u.d[1].ieee.negative \ +- && (u.d[1].ieee.exponent != 0 || lo != 0L)) \ ++ && lo != 0) \ + { \ + lo = (1ULL << 60) - lo; \ + if (hi == 0L) \ diff --git a/SOURCES/glibc-ppc64le-06.patch b/SOURCES/glibc-ppc64le-06.patch new file mode 100644 index 00000000..ea9451a5 --- /dev/null +++ b/SOURCES/glibc-ppc64le-06.patch @@ -0,0 +1,652 @@ +# commit 1b6adf888de14675bc3207578dcb7132ed5f8ecc +# Author: Alan Modra +# Date: Sat Aug 17 18:21:58 2013 +0930 +# +# PowerPC floating point little-endian [1 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00081.html +# +# This is the first of a series of patches to ban ieee854_long_double +# and the ieee854_long_double macros when using IBM long double. union +# ieee854_long_double just isn't correct for IBM long double, especially +# when little-endian, and pretending it is OK has allowed a number of +# bugs to remain undetected in sysdeps/ieee754/ldbl-128ibm/. +# +# This changes the few places in generic code that use it. +# +# * stdio-common/printf_size.c (__printf_size): Don't use +# union ieee854_long_double in fpnum union. +# * stdio-common/printf_fphex.c (__printf_fphex): Likewise. Use +# signbit macro to retrieve sign from long double. +# * stdio-common/printf_fp.c (___printf_fp): Use signbit macro to +# retrieve sign from long double. +# * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c: Adjust for fpnum change. +# * sysdeps/ieee754/ldbl-128/printf_fphex.c: Likewise. +# * sysdeps/ieee754/ldbl-96/printf_fphex.c: Likewise. +# * sysdeps/x86_64/fpu/printf_fphex.c: Likewise. +# * math/test-misc.c (main): Don't use union ieee854_long_double. +# ports/ +# * sysdeps/ia64/fpu/printf_fphex.c: Adjust for fpnum change. +# +diff -urN glibc-2.17-c758a686/math/test-misc.c glibc-2.17-c758a686/math/test-misc.c +--- glibc-2.17-c758a686/math/test-misc.c 2014-05-27 19:53:22.000000000 -0500 ++++ glibc-2.17-c758a686/math/test-misc.c 2014-05-27 19:53:45.000000000 -0500 +@@ -721,300 +721,161 @@ + + #ifndef NO_LONG_DOUBLE + { +- union ieee854_long_double v1; +- union ieee854_long_double v2; +- long double ld; ++ long double v1, v2; + +- v1.d = ld = LDBL_MIN; +- if (fpclassify (ld) != FP_NORMAL) ++ v1 = LDBL_MIN; ++ if (fpclassify (v1) != FP_NORMAL) + { +- printf ("fpclassify (LDBL_MIN) failed: %d\n", fpclassify (ld)); ++ printf ("fpclassify (LDBL_MIN) failed: %d (%La)\n", ++ fpclassify (v1), v1); + result = 1; + } +- ld = nextafterl (ld, LDBL_MIN / 2.0); +- if (fpclassify (ld) != FP_SUBNORMAL) ++ v2 = nextafterl (v1, LDBL_MIN / 2.0); ++ if (fpclassify (v2) != FP_SUBNORMAL) + { + printf ("fpclassify (LDBL_MIN-epsilon) failed: %d (%La)\n", +- fpclassify (ld), ld); ++ fpclassify (v2), v2); + result = 1; + } +- v2.d = ld = nextafterl (ld, LDBL_MIN); +- if (fpclassify (ld) != FP_NORMAL) ++ v2 = nextafterl (v2, LDBL_MIN); ++ if (fpclassify (v2) != FP_NORMAL) + { + printf ("fpclassify (LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n", +- fpclassify (ld), ld); ++ fpclassify (v2), v2); + result = 1; + } + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) ++ if (v1 != v2) + { +- printf ("LDBL_MIN: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("LDBL_MIN: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) +- { +- printf ("LDBL_MIN: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); +- result = 1; +- } +- if (v1.ieee.negative != v2.ieee.negative) +- { +- printf ("LDBL_MIN: negative differs: %d vs %d\n", +- v1.ieee.negative, v2.ieee.negative); ++ printf ("LDBL_MIN-epsilon+epsilon != LDBL_MIN: %La vs %La\n", v2, v1); + result = 1; + } + +- v1.d = ld = -LDBL_MIN; +- if (fpclassify (ld) != FP_NORMAL) ++ v1 = -LDBL_MIN; ++ if (fpclassify (v1) != FP_NORMAL) + { +- printf ("fpclassify (-LDBL_MIN) failed: %d\n", fpclassify (ld)); ++ printf ("fpclassify (-LDBL_MIN) failed: %d (%La)\n", ++ fpclassify (v1), v1); + result = 1; + } +- ld = nextafterl (ld, -LDBL_MIN / 2.0); +- if (fpclassify (ld) != FP_SUBNORMAL) ++ v2 = nextafterl (v1, -LDBL_MIN / 2.0); ++ if (fpclassify (v2) != FP_SUBNORMAL) + { + printf ("fpclassify (-LDBL_MIN-epsilon) failed: %d (%La)\n", +- fpclassify (ld), ld); ++ fpclassify (v2), v2); + result = 1; + } +- v2.d = ld = nextafterl (ld, -LDBL_MIN); +- if (fpclassify (ld) != FP_NORMAL) ++ v2 = nextafterl (v2, -LDBL_MIN); ++ if (fpclassify (v2) != FP_NORMAL) + { + printf ("fpclassify (-LDBL_MIN-epsilon+epsilon) failed: %d (%La)\n", +- fpclassify (ld), ld); ++ fpclassify (v2), v2); + result = 1; + } + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) ++ if (v1 != v2) + { +- printf ("-LDBL_MIN: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("-LDBL_MIN: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) +- { +- printf ("-LDBL_MIN: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); +- result = 1; +- } +- if (v1.ieee.negative != v2.ieee.negative) +- { +- printf ("-LDBL_MIN: negative differs: %d vs %d\n", +- v1.ieee.negative, v2.ieee.negative); ++ printf ("-LDBL_MIN-epsilon+epsilon != -LDBL_MIN: %La vs %La\n", v2, v1); + result = 1; + } + +- ld = LDBL_MAX; +- if (fpclassify (ld) != FP_NORMAL) ++ v1 = LDBL_MAX; ++ if (fpclassify (v1) != FP_NORMAL) + { +- printf ("fpclassify (LDBL_MAX) failed: %d\n", fpclassify (ld)); ++ printf ("fpclassify (LDBL_MAX) failed: %d (%La)\n", ++ fpclassify (v1), v1); + result = 1; + } +- ld = nextafterl (ld, INFINITY); +- if (fpclassify (ld) != FP_INFINITE) ++ v2 = nextafterl (v1, INFINITY); ++ if (fpclassify (v2) != FP_INFINITE) + { +- printf ("fpclassify (LDBL_MAX+epsilon) failed: %d\n", fpclassify (ld)); ++ printf ("fpclassify (LDBL_MAX+epsilon) failed: %d (%La)\n", ++ fpclassify (v2), v2); + result = 1; + } + +- ld = -LDBL_MAX; +- if (fpclassify (ld) != FP_NORMAL) ++ v1 = -LDBL_MAX; ++ if (fpclassify (v1) != FP_NORMAL) + { +- printf ("fpclassify (-LDBL_MAX) failed: %d\n", fpclassify (ld)); ++ printf ("fpclassify (-LDBL_MAX) failed: %d (%La)\n", ++ fpclassify (v1), v1); + result = 1; + } +- ld = nextafterl (ld, -INFINITY); +- if (fpclassify (ld) != FP_INFINITE) ++ v2 = nextafterl (v1, -INFINITY); ++ if (fpclassify (v2) != FP_INFINITE) + { +- printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d\n", +- fpclassify (ld)); ++ printf ("fpclassify (-LDBL_MAX-epsilon) failed: %d (%La)\n", ++ fpclassify (v2), v2); + result = 1; + } + +- v1.d = ld = 0.0625; +- ld = nextafterl (ld, 0.0); +- v2.d = ld = nextafterl (ld, 1.0); ++ v1 = 0.0625; ++ v2 = nextafterl (v1, 0.0); ++ v2 = nextafterl (v2, 1.0); + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) +- { +- printf ("0.0625L down: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("0.0625L down: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) +- { +- printf ("0.0625L down: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); +- result = 1; +- } +- if (v1.ieee.negative != v2.ieee.negative) ++ if (v1 != v2) + { +- printf ("0.0625L down: negative differs: %d vs %d\n", +- v1.ieee.negative, v2.ieee.negative); ++ printf ("0.0625L-epsilon+epsilon != 0.0625L: %La vs %La\n", v2, v1); + result = 1; + } + +- v1.d = ld = 0.0625; +- ld = nextafterl (ld, 1.0); +- v2.d = ld = nextafterl (ld, 0.0); ++ v1 = 0.0625; ++ v2 = nextafterl (v1, 1.0); ++ v2 = nextafterl (v2, 0.0); + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) +- { +- printf ("0.0625L up: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("0.0625L up: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) ++ if (v1 != v2) + { +- printf ("0.0625L up: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); +- result = 1; +- } +- if (v1.ieee.negative != v2.ieee.negative) +- { +- printf ("0.0625L up: negative differs: %d vs %d\n", +- v1.ieee.negative, v2.ieee.negative); ++ printf ("0.0625L+epsilon-epsilon != 0.0625L: %La vs %La\n", v2, v1); + result = 1; + } + +- v1.d = ld = -0.0625; +- ld = nextafterl (ld, 0.0); +- v2.d = ld = nextafterl (ld, -1.0); ++ v1 = -0.0625; ++ v2 = nextafterl (v1, 0.0); ++ v2 = nextafterl (v2, -1.0); + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) +- { +- printf ("-0.0625L up: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("-0.0625L up: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) ++ if (v1 != v2) + { +- printf ("-0.0625L up: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); +- result = 1; +- } +- if (v1.ieee.negative != v2.ieee.negative) +- { +- printf ("-0.0625L up: negative differs: %d vs %d\n", +- v1.ieee.negative, v2.ieee.negative); ++ printf ("-0.0625L+epsilon-epsilon != -0.0625L: %La vs %La\n", v2, v1); + result = 1; + } + +- v1.d = ld = -0.0625; +- ld = nextafterl (ld, -1.0); +- v2.d = ld = nextafterl (ld, 0.0); ++ v1 = -0.0625; ++ v2 = nextafterl (v1, -1.0); ++ v2 = nextafterl (v2, 0.0); + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) +- { +- printf ("-0.0625L down: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) ++ if (v1 != v2) + { +- printf ("-0.0625L down: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) +- { +- printf ("-0.0625L down: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); +- result = 1; +- } +- if (v1.ieee.negative != v2.ieee.negative) +- { +- printf ("-0.0625L down: negative differs: %d vs %d\n", +- v1.ieee.negative, v2.ieee.negative); ++ printf ("-0.0625L-epsilon+epsilon != -0.0625L: %La vs %La\n", v2, v1); + result = 1; + } + +- v1.d = ld = 0.0; +- ld = nextafterl (ld, 1.0); +- v2.d = nextafterl (ld, -1.0); ++ v1 = 0.0; ++ v2 = nextafterl (v1, 1.0); ++ v2 = nextafterl (v2, -1.0); + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) +- { +- printf ("0.0L up: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("0.0L up: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) ++ if (v1 != v2) + { +- printf ("0.0L up: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); ++ printf ("0.0+epsilon-epsilon != 0.0L: %La vs %La\n", v2, v1); + result = 1; + } +- if (0 != v2.ieee.negative) ++ if (signbit (v2)) + { +- printf ("0.0L up: negative differs: 0 vs %d\n", +- v2.ieee.negative); ++ printf ("0.0+epsilon-epsilon is negative\n"); + result = 1; + } + +- v1.d = ld = 0.0; +- ld = nextafterl (ld, -1.0); +- v2.d = nextafterl (ld, 1.0); ++ v1 = 0.0; ++ v2 = nextafterl (v1, -1.0); ++ v2 = nextafterl (v2, 1.0); + +- if (v1.ieee.mantissa0 != v2.ieee.mantissa0) +- { +- printf ("0.0L down: mantissa0 differs: %8x vs %8x\n", +- v1.ieee.mantissa0, v2.ieee.mantissa0); +- result = 1; +- } +- if (v1.ieee.mantissa1 != v2.ieee.mantissa1) +- { +- printf ("0.0L down: mantissa1 differs: %8x vs %8x\n", +- v1.ieee.mantissa1, v2.ieee.mantissa1); +- result = 1; +- } +- if (v1.ieee.exponent != v2.ieee.exponent) ++ if (v1 != v2) + { +- printf ("0.0L down: exponent differs: %4x vs %4x\n", +- v1.ieee.exponent, v2.ieee.exponent); ++ printf ("0.0-epsilon+epsilon != 0.0L: %La vs %La\n", v2, v1); + result = 1; + } +- if (1 != v2.ieee.negative) ++ if (!signbit (v2)) + { +- printf ("0.0L down: negative differs: 1 vs %d\n", +- v2.ieee.negative); ++ printf ("0.0-epsilon+epsilon is positive\n"); + result = 1; + } + +diff -urN glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/printf_fphex.c glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/printf_fphex.c +--- glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/printf_fphex.c 2014-05-27 19:53:21.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/printf_fphex.c 2014-05-27 19:53:45.000000000 -0500 +@@ -25,9 +25,11 @@ + /* The "strange" 80 bit format on ia64 has an explicit \ + leading digit in the 64 bit mantissa. */ \ + unsigned long long int num; \ ++ union ieee854_long_double u; \ ++ u.d = fpnum.ldbl; \ + \ +- num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ +- | fpnum.ldbl.ieee.mantissa1); \ ++ num = (((unsigned long long int) u.ieee.mantissa0) << 32 \ ++ | u.ieee.mantissa1); \ + \ + zero_mantissa = num == 0; \ + \ +@@ -49,8 +51,8 @@ + \ + /* We have 3 bits from the mantissa in the leading nibble. \ + Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ +- exponent = fpnum.ldbl.ieee.exponent; \ +- \ ++ exponent = u.ieee.exponent; \ ++ \ + if (exponent == 0) \ + { \ + if (zero_mantissa) \ +diff -urN glibc-2.17-c758a686/stdio-common/printf_fp.c glibc-2.17-c758a686/stdio-common/printf_fp.c +--- glibc-2.17-c758a686/stdio-common/printf_fp.c 2014-05-27 19:53:22.000000000 -0500 ++++ glibc-2.17-c758a686/stdio-common/printf_fp.c 2014-05-27 19:53:45.000000000 -0500 +@@ -335,8 +335,7 @@ + int res; + if (__isnanl (fpnum.ldbl)) + { +- union ieee854_long_double u = { .d = fpnum.ldbl }; +- is_neg = u.ieee.negative != 0; ++ is_neg = signbit (fpnum.ldbl); + if (isupper (info->spec)) + { + special = "NAN"; +diff -urN glibc-2.17-c758a686/stdio-common/printf_fphex.c glibc-2.17-c758a686/stdio-common/printf_fphex.c +--- glibc-2.17-c758a686/stdio-common/printf_fphex.c 2014-05-27 19:53:22.000000000 -0500 ++++ glibc-2.17-c758a686/stdio-common/printf_fphex.c 2014-05-27 19:53:45.000000000 -0500 +@@ -93,7 +93,7 @@ + union + { + union ieee754_double dbl; +- union ieee854_long_double ldbl; ++ long double ldbl; + } + fpnum; + +@@ -162,12 +162,11 @@ + #ifndef __NO_LONG_DOUBLE_MATH + if (info->is_long_double && sizeof (long double) > sizeof (double)) + { +- fpnum.ldbl.d = *(const long double *) args[0]; ++ fpnum.ldbl = *(const long double *) args[0]; + + /* Check for special values: not a number or infinity. */ +- if (__isnanl (fpnum.ldbl.d)) ++ if (__isnanl (fpnum.ldbl)) + { +- negative = fpnum.ldbl.ieee.negative != 0; + if (isupper (info->spec)) + { + special = "NAN"; +@@ -181,8 +180,7 @@ + } + else + { +- int res = __isinfl (fpnum.ldbl.d); +- if (res) ++ if (__isinfl (fpnum.ldbl)) + { + if (isupper (info->spec)) + { +@@ -194,11 +192,9 @@ + special = "inf"; + wspecial = L"inf"; + } +- negative = res < 0; + } +- else +- negative = signbit (fpnum.ldbl.d); + } ++ negative = signbit (fpnum.ldbl); + } + else + #endif /* no long double */ +diff -urN glibc-2.17-c758a686/stdio-common/printf_size.c glibc-2.17-c758a686/stdio-common/printf_size.c +--- glibc-2.17-c758a686/stdio-common/printf_size.c 2014-05-27 19:53:22.000000000 -0500 ++++ glibc-2.17-c758a686/stdio-common/printf_size.c 2014-05-27 19:53:45.000000000 -0500 +@@ -103,7 +103,7 @@ + union + { + union ieee754_double dbl; +- union ieee854_long_double ldbl; ++ long double ldbl; + } + fpnum; + const void *ptr = &fpnum; +@@ -123,25 +123,25 @@ + #ifndef __NO_LONG_DOUBLE_MATH + if (info->is_long_double && sizeof (long double) > sizeof (double)) + { +- fpnum.ldbl.d = *(const long double *) args[0]; ++ fpnum.ldbl = *(const long double *) args[0]; + + /* Check for special values: not a number or infinity. */ +- if (__isnanl (fpnum.ldbl.d)) ++ if (__isnanl (fpnum.ldbl)) + { + special = "nan"; + wspecial = L"nan"; + // fpnum_sign = 0; Already zero + } +- else if ((res = __isinfl (fpnum.ldbl.d))) ++ else if ((res = __isinfl (fpnum.ldbl))) + { + fpnum_sign = res; + special = "inf"; + wspecial = L"inf"; + } + else +- while (fpnum.ldbl.d >= divisor && tag[1] != '\0') ++ while (fpnum.ldbl >= divisor && tag[1] != '\0') + { +- fpnum.ldbl.d /= divisor; ++ fpnum.ldbl /= divisor; + ++tag; + } + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128/printf_fphex.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128/printf_fphex.c 2014-05-27 19:53:45.000000000 -0500 +@@ -24,13 +24,15 @@ + digits we use only the implicit digits for the number before \ + the decimal point. */ \ + unsigned long long int num0, num1; \ ++ union ieee854_long_double u; \ ++ u.d = fpnum.ldbl; \ + \ + assert (sizeof (long double) == 16); \ + \ +- num0 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ +- | fpnum.ldbl.ieee.mantissa1); \ +- num1 = (((unsigned long long int) fpnum.ldbl.ieee.mantissa2) << 32 \ +- | fpnum.ldbl.ieee.mantissa3); \ ++ num0 = (((unsigned long long int) u.ieee.mantissa0) << 32 \ ++ | u.ieee.mantissa1); \ ++ num1 = (((unsigned long long int) u.ieee.mantissa2) << 32 \ ++ | u.ieee.mantissa3); \ + \ + zero_mantissa = (num0|num1) == 0; \ + \ +@@ -75,9 +77,9 @@ + *--wnumstr = L'0'; \ + } \ + \ +- leading = fpnum.ldbl.ieee.exponent == 0 ? '0' : '1'; \ ++ leading = u.ieee.exponent == 0 ? '0' : '1'; \ + \ +- exponent = fpnum.ldbl.ieee.exponent; \ ++ exponent = u.ieee.exponent; \ + \ + if (exponent == 0) \ + { \ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 2014-05-27 19:53:45.000000000 -0500 +@@ -28,14 +28,14 @@ + unsigned long long hi, lo; \ + int ediff; \ + union ibm_extended_long_double u; \ +- u.ld = fpnum.ldbl.d; \ ++ u.ld = fpnum.ldbl; \ + \ + assert (sizeof (long double) == 16); \ + \ + lo = ((long long)u.d[1].ieee.mantissa0 << 32) | u.d[1].ieee.mantissa1; \ + hi = ((long long)u.d[0].ieee.mantissa0 << 32) | u.d[0].ieee.mantissa1; \ + lo <<= 7; /* pre-shift lo to match ieee854. */ \ +- /* If the lower double is not a denomal or zero then set the hidden \ ++ /* If the lower double is not a denormal or zero then set the hidden \ + 53rd bit. */ \ + if (u.d[1].ieee.exponent != 0) \ + lo |= (1ULL << (52 + 7)); \ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-96/printf_fphex.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-96/printf_fphex.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-96/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-96/printf_fphex.c 2014-05-27 19:53:45.000000000 -0500 +@@ -25,11 +25,13 @@ + /* The "strange" 80 bit format on ix86 and m68k has an explicit \ + leading digit in the 64 bit mantissa. */ \ + unsigned long long int num; \ ++ union ieee854_long_double u; \ ++ u.d = fpnum.ldbl; \ + \ + assert (sizeof (long double) == 12); \ + \ +- num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ +- | fpnum.ldbl.ieee.mantissa1); \ ++ num = (((unsigned long long int) u.ieee.mantissa0) << 32 \ ++ | u.ieee.mantissa1); \ + \ + zero_mantissa = num == 0; \ + \ +@@ -62,7 +64,7 @@ + \ + /* We have 3 bits from the mantissa in the leading nibble. \ + Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ +- exponent = fpnum.ldbl.ieee.exponent; \ ++ exponent = u.ieee.exponent; \ + \ + if (exponent == 0) \ + { \ +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/fpu/printf_fphex.c glibc-2.17-c758a686/sysdeps/x86_64/fpu/printf_fphex.c +--- glibc-2.17-c758a686/sysdeps/x86_64/fpu/printf_fphex.c 2014-05-27 19:53:20.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/printf_fphex.c 2014-05-27 19:53:45.000000000 -0500 +@@ -25,10 +25,11 @@ + /* The "strange" 80 bit format on ix86 and m68k has an explicit \ + leading digit in the 64 bit mantissa. */ \ + unsigned long long int num; \ ++ union ieee854_long_double u; \ ++ u.d = fpnum.ldbl; \ + \ +- \ +- num = (((unsigned long long int) fpnum.ldbl.ieee.mantissa0) << 32 \ +- | fpnum.ldbl.ieee.mantissa1); \ ++ num = (((unsigned long long int) u.ieee.mantissa0) << 32 \ ++ | u.ieee.mantissa1); \ + \ + zero_mantissa = num == 0; \ + \ +@@ -61,7 +62,7 @@ + \ + /* We have 3 bits from the mantissa in the leading nibble. \ + Therefore we are here using `IEEE854_LONG_DOUBLE_BIAS + 3'. */ \ +- exponent = fpnum.ldbl.ieee.exponent; \ ++ exponent = u.ieee.exponent; \ + \ + if (exponent == 0) \ + { \ diff --git a/SOURCES/glibc-ppc64le-07.patch b/SOURCES/glibc-ppc64le-07.patch new file mode 100644 index 00000000..566501d9 --- /dev/null +++ b/SOURCES/glibc-ppc64le-07.patch @@ -0,0 +1,651 @@ +# commit 4ebd120cd983c8d2ac7a234884b3ac6805d82973 +# Author: Alan Modra +# Date: Sat Aug 17 18:24:05 2013 +0930 +# +# PowerPC floating point little-endian [2 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00082.html +# +# This patch replaces occurrences of GET_LDOUBLE_* and SET_LDOUBLE_* +# macros, and union ieee854_long_double_shape_type in ldbl-128ibm/, +# and a stray one in the 32-bit fpu support. These files have no +# significant changes apart from rewriting the long double bit access. +# +# * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h (ldbl_high): Define. +# * sysdeps/ieee754/ldbl-128ibm/e_acoshl.c (__ieee754_acoshl): Rewrite +# all uses of ieee854 long double macros and unions. +# * sysdeps/ieee754/ldbl-128ibm/e_acosl.c (__ieee754_acosl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_asinl.c (__ieee754_asinl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_atanhl.c (__ieee754_atanhl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_coshl.c (__ieee754_coshl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c (__ieee754_rem_pio2l): +# Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_sinhl.c (__ieee754_sinhl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/k_cosl.c (__kernel_cosl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/k_sincosl.c (__kernel_sincosl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/k_sinl.c (__kernel_sinl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_asinhl.c (__asinhl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_atanl.c (__atanl): Likewise. +# Simplify sign and nan test too. +# * sysdeps/ieee754/ldbl-128ibm/s_cosl.c (__cosl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_fabsl.c (__fabsl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_finitel.c (___finitel): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c (___fpclassifyl): +# Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_isnanl.c (___isnanl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_issignalingl.c (__issignalingl): +# Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_logbl.c (__logbl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_signbitl.c (___signbitl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_sincosl.c (__sincosl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_sinl.c (__sinl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_tanl.c (__tanl): Likewise. +# * sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c (__logbl): Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -36,8 +36,12 @@ + { + long double t; + int64_t hx; +- u_int64_t lx; +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ uint64_t lx; ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); + if(hx<0x3ff0000000000000LL) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x41b0000000000000LL) { /* x > 2**28 */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acosl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acosl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acosl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -151,26 +151,25 @@ + long double + __ieee754_acosl (long double x) + { +- long double z, r, w, p, q, s, t, f2; +- ieee854_long_double_shape_type u; ++ long double a, z, r, w, p, q, s, t, f2; + +- u.value = __builtin_fabsl (x); +- if (u.value == 1.0L) ++ a = __builtin_fabsl (x); ++ if (a == 1.0L) + { + if (x > 0.0L) + return 0.0; /* acos(1) = 0 */ + else + return (2.0 * pio2_hi) + (2.0 * pio2_lo); /* acos(-1)= pi */ + } +- else if (u.value > 1.0L) ++ else if (a > 1.0L) + { + return (x - x) / (x - x); /* acos(|x| > 1) is NaN */ + } +- if (u.value < 0.5L) ++ if (a < 0.5L) + { +- if (u.value < 6.938893903907228e-18L) /* |x| < 2**-57 */ ++ if (a < 6.938893903907228e-18L) /* |x| < 2**-57 */ + return pio2_hi + pio2_lo; +- if (u.value < 0.4375L) ++ if (a < 0.4375L) + { + /* Arcsine of x. */ + z = x * x; +@@ -199,7 +198,7 @@ + return z; + } + /* .4375 <= |x| < .5 */ +- t = u.value - 0.4375L; ++ t = a - 0.4375L; + p = ((((((((((P10 * t + + P9) * t + + P8) * t +@@ -230,9 +229,9 @@ + r = acosr4375 + r; + return r; + } +- else if (u.value < 0.625L) ++ else if (a < 0.625L) + { +- t = u.value - 0.5625L; ++ t = a - 0.5625L; + p = ((((((((((rS10 * t + + rS9) * t + + rS8) * t +@@ -264,7 +263,9 @@ + } + else + { /* |x| >= .625 */ +- z = (one - u.value) * 0.5; ++ double shi, slo; ++ ++ z = (one - a) * 0.5; + s = __ieee754_sqrtl (z); + /* Compute an extended precision square root from + the Newton iteration s -> 0.5 * (s + z / s). +@@ -273,12 +274,11 @@ + Express s = f1 + f2 where f1 * f1 is exactly representable. + w = (z - s^2)/2s = (z - f1^2 - 2 f1 f2 - f2^2)/2s . + s + w has extended precision. */ +- u.value = s; +- u.parts32.w2 = 0; +- u.parts32.w3 = 0; +- f2 = s - u.value; +- w = z - u.value * u.value; +- w = w - 2.0 * u.value * f2; ++ ldbl_unpack (s, &shi, &slo); ++ a = shi; ++ f2 = slo; ++ w = z - a * a; ++ w = w - 2.0 * a * f2; + w = w - f2 * f2; + w = w / (2.0 * s); + /* Arcsine of s. */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_asinl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_asinl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_asinl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_asinl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -131,19 +131,18 @@ + long double + __ieee754_asinl (long double x) + { +- long double t, w, p, q, c, r, s; ++ long double a, t, w, p, q, c, r, s; + int flag; +- ieee854_long_double_shape_type u; + + flag = 0; +- u.value = __builtin_fabsl (x); +- if (u.value == 1.0L) /* |x|>= 1 */ ++ a = __builtin_fabsl (x); ++ if (a == 1.0L) /* |x|>= 1 */ + return x * pio2_hi + x * pio2_lo; /* asin(1)=+-pi/2 with inexact */ +- else if (u.value >= 1.0L) ++ else if (a >= 1.0L) + return (x - x) / (x - x); /* asin(|x|>1) is NaN */ +- else if (u.value < 0.5L) ++ else if (a < 0.5L) + { +- if (u.value < 6.938893903907228e-18L) /* |x| < 2**-57 */ ++ if (a < 6.938893903907228e-18L) /* |x| < 2**-57 */ + { + if (huge + x > one) + return x; /* return x with inexact if x!=0 */ +@@ -155,9 +154,9 @@ + flag = 1; + } + } +- else if (u.value < 0.625L) ++ else if (a < 0.625L) + { +- t = u.value - 0.5625; ++ t = a - 0.5625; + p = ((((((((((rS10 * t + + rS9) * t + + rS8) * t +@@ -190,7 +189,7 @@ + else + { + /* 1 > |x| >= 0.625 */ +- w = one - u.value; ++ w = one - a; + t = w * 0.5; + } + +@@ -223,17 +222,14 @@ + } + + s = __ieee754_sqrtl (t); +- if (u.value > 0.975L) ++ if (a > 0.975L) + { + w = p / q; + t = pio2_hi - (2.0 * (s + s * w) - pio2_lo); + } + else + { +- u.value = s; +- u.parts32.w3 = 0; +- u.parts32.w2 = 0; +- w = u.value; ++ w = ldbl_high (s); + c = (t - w * w) / (s + w); + r = p / q; + p = 2.0 * s * r - (pio2_lo - 2.0 * c); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atanhl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -40,8 +40,10 @@ + { + long double t; + int64_t hx,ix; +- u_int64_t lx __attribute__ ((unused)); +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ double xhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + ix = hx&0x7fffffffffffffffLL; + if (ix >= 0x3ff0000000000000LL) { /* |x|>=1 */ + if (ix > 0x3ff0000000000000LL) +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_coshl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_coshl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_coshl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_coshl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -41,9 +41,11 @@ + { + long double t,w; + int64_t ix; ++ double xhi; + + /* High word of |x|. */ +- GET_LDOUBLE_MSW64(ix,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + ix &= 0x7fffffffffffffffLL; + + /* x is INF or NaN */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log2l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log2l.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log2l.c 2014-05-27 19:59:00.000000000 -0500 +@@ -177,11 +177,13 @@ + long double z; + long double y; + int e; +- int64_t hx, lx; ++ int64_t hx; ++ double xhi; + + /* Test for domain */ +- GET_LDOUBLE_WORDS64 (hx, lx, x); +- if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0) ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); ++ if ((hx & 0x7fffffffffffffffLL) == 0) + return (-1.0L / (x - x)); + if (hx < 0) + return (x - x) / (x - x); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_rem_pio2l.c 2014-05-27 19:59:00.000000000 -0500 +@@ -200,10 +200,11 @@ + double tx[8]; + int exp; + int64_t n, ix, hx, ixd; +- u_int64_t lx __attribute__ ((unused)); + u_int64_t lxd; ++ double xhi; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + ix = hx & 0x7fffffffffffffffLL; + if (ix <= 0x3fe921fb54442d10LL) /* x in <-pi/4, pi/4> */ + { +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sinhl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -38,9 +38,11 @@ + { + long double t,w,h; + int64_t ix,jx; ++ double xhi; + + /* High word of |x|. */ +- GET_LDOUBLE_MSW64(jx,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (jx, xhi); + ix = jx&0x7fffffffffffffffLL; + + /* x is INF or NaN */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_cosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_cosl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_cosl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_cosl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -81,8 +81,11 @@ + { + long double h, l, z, sin_l, cos_l_m1; + int64_t ix; +- u_int32_t tix, hix, index; +- GET_LDOUBLE_MSW64 (ix, x); ++ uint32_t tix, hix, index; ++ double xhi, hhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + tix = ((u_int64_t)ix) >> 32; + tix &= ~0x80000000; /* tix = |x|'s high 32 bits */ + if (tix < 0x3fc30000) /* |x| < 0.1484375 */ +@@ -136,7 +139,8 @@ + case 2: index = (hix - 0x3fc30000) >> 14; break; + } + */ +- SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0); ++ INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32); ++ h = hhi; + l = y - (h - x); + z = l * l; + sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5))))); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sincosl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -100,9 +100,12 @@ + { + long double h, l, z, sin_l, cos_l_m1; + int64_t ix; +- u_int32_t tix, hix, index; +- GET_LDOUBLE_MSW64 (ix, x); +- tix = ((u_int64_t)ix) >> 32; ++ uint32_t tix, hix, index; ++ double xhi, hhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); ++ tix = ((uint64_t)ix) >> 32; + tix &= ~0x80000000; /* tix = |x|'s high 32 bits */ + if (tix < 0x3fc30000) /* |x| < 0.1484375 */ + { +@@ -164,7 +167,8 @@ + case 2: index = (hix - 0x3fc30000) >> 14; break; + } + */ +- SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0); ++ INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32); ++ h = hhi; + if (iy) + l = y - (h - x); + else +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sinl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sinl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sinl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_sinl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -82,7 +82,10 @@ + long double h, l, z, sin_l, cos_l_m1; + int64_t ix; + u_int32_t tix, hix, index; +- GET_LDOUBLE_MSW64 (ix, x); ++ double xhi, hhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + tix = ((u_int64_t)ix) >> 32; + tix &= ~0x80000000; /* tix = |x|'s high 32 bits */ + if (tix < 0x3fc30000) /* |x| < 0.1484375 */ +@@ -132,7 +135,8 @@ + case 2: index = (hix - 0x3fc30000) >> 14; break; + } + */ +- SET_LDOUBLE_WORDS64(h, ((u_int64_t)hix) << 32, 0); ++ INSERT_WORDS64 (hhi, ((uint64_t)hix) << 32); ++ h = hhi; + if (iy) + l = (ix < 0 ? -y : y) - (h - x); + else +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_asinhl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -38,7 +38,10 @@ + { + long double t,w; + int64_t hx,ix; +- GET_LDOUBLE_MSW64(hx,x); ++ double xhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + ix = hx&0x7fffffffffffffffLL; + if(ix>=0x7ff0000000000000LL) return x+x; /* x is inf or NaN */ + if(ix< 0x3e20000000000000LL) { /* |x|<2**-29 */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_atanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_atanl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_atanl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_atanl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -173,23 +173,20 @@ + long double + __atanl (long double x) + { +- int k, sign; ++ int32_t k, sign, lx; + long double t, u, p, q; +- ieee854_long_double_shape_type s; ++ double xhi; + +- s.value = x; +- k = s.parts32.w0; +- if (k & 0x80000000) +- sign = 1; +- else +- sign = 0; ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS (k, lx, xhi); ++ sign = k & 0x80000000; + + /* Check for IEEE special cases. */ + k &= 0x7fffffff; + if (k >= 0x7ff00000) + { + /* NaN. */ +- if ((k & 0xfffff) | s.parts32.w1 ) ++ if (((k - 0x7ff00000) | lx) != 0) + return (x + x); + + /* Infinity. */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_cosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_cosl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_cosl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_cosl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -53,9 +53,11 @@ + { + long double y[2],z=0.0L; + int64_t n, ix; ++ double xhi; + + /* High word of x. */ +- GET_LDOUBLE_MSW64(ix,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffffffffffffLL; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fabsl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -29,10 +29,16 @@ + long double __fabsl(long double x) + { + u_int64_t hx, lx; +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); + lx = lx ^ ( hx & 0x8000000000000000LL ); + hx = hx & 0x7fffffffffffffffLL; +- SET_LDOUBLE_WORDS64(x,hx,lx); ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x; + } + long_double_symbol (libm, __fabsl, fabsl); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c 2014-05-27 19:59:00.000000000 -0500 +@@ -29,10 +29,14 @@ + int + ___finitel (long double x) + { +- int64_t hx; +- GET_LDOUBLE_MSW64(hx,x); +- return (int)((u_int64_t)((hx&0x7fffffffffffffffLL) +- -0x7ff0000000000000LL)>>63); ++ uint64_t hx; ++ double xhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); ++ hx &= 0x7fffffffffffffffLL; ++ hx -= 0x7ff0000000000000LL; ++ return hx >> 63; + } + hidden_ver (___finitel, __finitel) + weak_alias (___finitel, ____finitel) +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -46,8 +46,10 @@ + { + u_int64_t hx, lx; + int retval = FP_NORMAL; ++ double xhi, xlo; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); + if ((hx & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) { + /* +/-NaN or +/-Inf */ + if (hx & 0x000fffffffffffffULL) { +@@ -65,6 +67,7 @@ + retval = FP_NORMAL; + } else { + if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) { ++ EXTRACT_WORDS64 (lx, xlo); + if ((lx & 0x7fffffffffffffff) /* lower is non-zero */ + && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */ + /* +/- denormal */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c 2014-05-27 19:59:00.000000000 -0500 +@@ -29,12 +29,14 @@ + int + ___isnanl (long double x) + { +- int64_t hx; +- int64_t lx __attribute__ ((unused)); +- GET_LDOUBLE_WORDS64(hx,lx,x); +- hx &= 0x7fffffffffffffffLL; +- hx = 0x7ff0000000000000LL - hx; +- return (int)((u_int64_t)hx>>63); ++ uint64_t hx; ++ double xhi; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); ++ hx &= 0x7fffffffffffffffLL; ++ hx = 0x7ff0000000000000LL - hx; ++ return (int) (hx >> 63); + } + hidden_ver (___isnanl, __isnanl) + #ifndef IS_IN_libm +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c 2014-05-27 19:59:19.000000000 -0500 +@@ -27,9 +27,10 @@ + __logbl (long double x) + { + int64_t hx, rhx; +- int64_t lx __attribute__ ((unused)); ++ double xhi; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + hx &= 0x7fffffffffffffffLL; /* high |x| */ + if (hx == 0) + return -1.0 / fabs (x); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c 2014-05-27 19:59:19.000000000 -0500 +@@ -25,8 +25,10 @@ + ___signbitl (long double x) + { + int64_t e; ++ double xhi; + +- GET_LDOUBLE_MSW64 (e, x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (e, xhi); + return e < 0; + } + #ifdef IS_IN_libm +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sincosl.c 2014-05-27 19:59:19.000000000 -0500 +@@ -27,9 +27,11 @@ + __sincosl (long double x, long double *sinx, long double *cosx) + { + int64_t ix; ++ double xhi; + + /* High word of x. */ +- GET_LDOUBLE_MSW64 (ix, x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffffffffffffLL; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sinl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sinl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sinl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_sinl.c 2014-05-27 19:59:19.000000000 -0500 +@@ -53,9 +53,11 @@ + { + long double y[2],z=0.0L; + int64_t n, ix; ++ double xhi; + + /* High word of x. */ +- GET_LDOUBLE_MSW64(ix,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffffffffffffLL; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanl.c 2014-05-27 19:59:19.000000000 -0500 +@@ -53,9 +53,11 @@ + { + long double y[2],z=0.0L; + int64_t n, ix; ++ double xhi; + + /* High word of x. */ +- GET_LDOUBLE_MSW64(ix,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ix, xhi); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffffffffffffLL; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c 2014-05-27 19:58:07.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_logbl.c 2014-05-27 19:59:19.000000000 -0500 +@@ -35,14 +35,14 @@ + long double + __logbl (long double x) + { +- double xh, xl; ++ double xh; + double ret; + + if (__builtin_expect (x == 0.0L, 0)) + /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF]. */ + return -1.0L / __builtin_fabsl (x); + +- ldbl_unpack (x, &xh, &xl); ++ xh = ldbl_high (x); + /* ret = x & 0x7ff0000000000000; */ + asm ( + "xxland %x0,%x1,%x2\n" +@@ -58,9 +58,9 @@ + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ +- int64_t lx, hx; ++ int64_t hx; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); ++ EXTRACT_WORDS64 (hx, xh); + return (long double) (-1023 - (__builtin_clzll (hx) - 12)); + } + /* Test to avoid logb_downward (0.0) == -0.0. */ diff --git a/SOURCES/glibc-ppc64le-08.patch b/SOURCES/glibc-ppc64le-08.patch new file mode 100644 index 00000000..39911d0f --- /dev/null +++ b/SOURCES/glibc-ppc64le-08.patch @@ -0,0 +1,1235 @@ +# commit 765714cafcad7e6168518c61111f07bd955a9fee +# Author: Alan Modra +# Date: Sat Aug 17 18:24:58 2013 +0930 +# +# PowerPC floating point little-endian [3 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00083.html +# +# Further replacement of ieee854 macros and unions. These files also +# have some optimisations for comparison against 0.0L, infinity and nan. +# Since the ABI specifies that the high double of an IBM long double +# pair is the value rounded to double, a high double of 0.0 means the +# low double must also be 0.0. The ABI also says that infinity and +# nan are encoded in the high double, with the low double unspecified. +# This means that tests for 0.0L, +/-Infinity and +/-NaN need only check +# the high double. +# +# * sysdeps/ieee754/ldbl-128ibm/e_atan2l.c (__ieee754_atan2l): Rewrite +# all uses of ieee854 long double macros and unions. Simplify tests +# for long doubles that are fully specified by the high double. +# * sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c (__ieee754_gammal_r): +# Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c (__ieee754_ilogbl): Likewise. +# Remove dead code too. +# * sysdeps/ieee754/ldbl-128ibm/e_jnl.c (__ieee754_jnl): Likewise. +# (__ieee754_ynl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_log10l.c (__ieee754_log10l): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_logl.c (__ieee754_logl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/e_powl.c (__ieee754_powl): Likewise. +# Remove dead code too. +# * sysdeps/ieee754/ldbl-128ibm/k_tanl.c (__kernel_tanl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_expm1l.c (__expm1l): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c (__isinf_nsl): Likewise. +# Simplify. +# * sysdeps/ieee754/ldbl-128ibm/s_isinfl.c (___isinfl): Likewise. +# Simplify. +# * sysdeps/ieee754/ldbl-128ibm/s_log1pl.c (__log1pl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_modfl.c (__modfl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (__nextafterl): Likewise. +# Comment on variable precision. +# * sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c (__nexttoward): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c (__nexttowardf): +# Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_remquol.c (__remquol): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c (__scalblnl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c (__scalbnl): Likewise. +# * sysdeps/ieee754/ldbl-128ibm/s_tanhl.c (__tanhl): Likewise. +# * sysdeps/powerpc/fpu/libm-test-ulps: Adjust tan_towardzero ulps. +# +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_atan2l.c 2014-05-27 23:05:55.000000000 -0500 +@@ -56,11 +56,15 @@ + { + long double z; + int64_t k,m,hx,hy,ix,iy; +- u_int64_t lx,ly; ++ uint64_t lx; ++ double xhi, xlo, yhi; + +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); + ix = hx&0x7fffffffffffffffLL; +- GET_LDOUBLE_WORDS64(hy,ly,y); ++ yhi = ldbl_high (y); ++ EXTRACT_WORDS64 (hy, yhi); + iy = hy&0x7fffffffffffffffLL; + if(((ix)>0x7ff0000000000000LL)|| + ((iy)>0x7ff0000000000000LL)) /* x or y is NaN */ +@@ -70,7 +74,7 @@ + m = ((hy>>63)&1)|((hx>>62)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ +- if((iy|(ly&0x7fffffffffffffffLL))==0) { ++ if(iy==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ +@@ -79,7 +83,7 @@ + } + } + /* when x = 0 */ +- if((ix|(lx&0x7fffffffffffffff))==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; ++ if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7ff0000000000000LL) { +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_gammal_r.c 2014-05-27 23:05:55.000000000 -0500 +@@ -29,11 +29,12 @@ + and the exp function. But due to the required boundary + conditions we must check some values separately. */ + int64_t hx; +- u_int64_t lx; ++ double xhi; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + +- if (((hx | lx) & 0x7fffffffffffffffLL) == 0) ++ if ((hx & 0x7fffffffffffffffLL) == 0) + { + /* Return value for x == 0 is Inf with divide by zero exception. */ + *signgamp = 0; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_ilogbl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -31,26 +31,24 @@ + + int __ieee754_ilogbl(long double x) + { +- int64_t hx,lx; ++ int64_t hx; + int ix; ++ double xhi; + +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + hx &= 0x7fffffffffffffffLL; + if(hx <= 0x0010000000000000LL) { +- if((hx|(lx&0x7fffffffffffffffLL))==0) ++ if(hx==0) + return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */ + else /* subnormal x */ +- if(hx==0) { +- for (ix = -1043; lx>0; lx<<=1) ix -=1; +- } else { +- for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1; +- } ++ for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1; + return ix; + } + else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff; + else if (FP_ILOGBNAN != INT_MAX) { + /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */ +- if (((hx^0x7ff0000000000000LL)|lx) == 0) ++ if (hx==0x7ff0000000000000LL) + return INT_MAX; + } + return FP_ILOGBNAN; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_jnl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_jnl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_jnl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_jnl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -70,26 +70,25 @@ + long double + __ieee754_jnl (int n, long double x) + { +- u_int32_t se; ++ uint32_t se, lx; + int32_t i, ix, sgn; + long double a, b, temp, di; + long double z, w; +- ieee854_long_double_shape_type u; ++ double xhi; + + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + +- u.value = x; +- se = u.parts32.w0; ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS (se, lx, xhi); + ix = se & 0x7fffffff; + + /* if J(n,NaN) is NaN */ + if (ix >= 0x7ff00000) + { +- if ((u.parts32.w0 & 0xfffff) | u.parts32.w1 +- | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) ++ if (((ix - 0x7ff00000) | lx) != 0) + return x + x; + } + +@@ -298,21 +297,20 @@ + long double + __ieee754_ynl (int n, long double x) + { +- u_int32_t se; ++ uint32_t se, lx; + int32_t i, ix; + int32_t sign; + long double a, b, temp; +- ieee854_long_double_shape_type u; ++ double xhi; + +- u.value = x; +- se = u.parts32.w0; ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS (se, lx, xhi); + ix = se & 0x7fffffff; + + /* if Y(n,NaN) is NaN */ + if (ix >= 0x7ff00000) + { +- if ((u.parts32.w0 & 0xfffff) | u.parts32.w1 +- | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) ++ if (((ix - 0x7ff00000) | lx) != 0) + return x + x; + } + if (x <= 0.0L) +@@ -377,14 +375,16 @@ + a = __ieee754_y0l (x); + b = __ieee754_y1l (x); + /* quit if b is -inf */ +- u.value = b; +- se = u.parts32.w0 & 0xfff00000; ++ xhi = ldbl_high (b); ++ GET_HIGH_WORD (se, xhi); ++ se &= 0xfff00000; + for (i = 1; i < n && se != 0xfff00000; i++) + { + temp = b; + b = ((long double) (i + i) / x) * b - a; +- u.value = b; +- se = u.parts32.w0 & 0xfff00000; ++ xhi = ldbl_high (b); ++ GET_HIGH_WORD (se, xhi); ++ se &= 0xfff00000; + a = temp; + } + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log10l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log10l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log10l.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_log10l.c 2014-05-27 23:05:55.000000000 -0500 +@@ -182,11 +182,13 @@ + long double z; + long double y; + int e; +- int64_t hx, lx; ++ int64_t hx; ++ double xhi; + + /* Test for domain */ +- GET_LDOUBLE_WORDS64 (hx, lx, x); +- if (((hx & 0x7fffffffffffffffLL) | (lx & 0x7fffffffffffffffLL)) == 0) ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); ++ if ((hx & 0x7fffffffffffffffLL) == 0) + return (-1.0L / (x - x)); + if (hx < 0) + return (x - x) / (x - x); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_logl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_logl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_logl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_logl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -185,18 +185,20 @@ + long double + __ieee754_logl(long double x) + { +- long double z, y, w; +- ieee854_long_double_shape_type u, t; ++ long double z, y, w, t; + unsigned int m; + int k, e; ++ double xhi; ++ uint32_t hx, lx; + +- u.value = x; +- m = u.parts32.w0; ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS (hx, lx, xhi); ++ m = hx; + + /* Check for IEEE special cases. */ + k = m & 0x7fffffff; + /* log(0) = -infinity. */ +- if ((k | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0) ++ if ((k | lx) == 0) + { + return -0.5L / ZERO; + } +@@ -216,7 +218,7 @@ + { + z = x - 1.0L; + k = 64; +- t.value = 1.0L; ++ t = 1.0L; + e = 0; + } + else +@@ -233,10 +235,8 @@ + k = (m - 0xff000) >> 13; + /* t is the argument 0.5 + (k+26)/128 + of the nearest item to u in the lookup table. */ +- t.parts32.w0 = 0x3ff00000 + (k << 13); +- t.parts32.w1 = 0; +- t.parts32.w2 = 0; +- t.parts32.w3 = 0; ++ INSERT_WORDS (xhi, 0x3ff00000 + (k << 13), 0); ++ t = xhi; + w0 += 0x100000; + e -= 1; + k += 64; +@@ -244,17 +244,15 @@ + else + { + k = (m - 0xfe000) >> 14; +- t.parts32.w0 = 0x3fe00000 + (k << 14); +- t.parts32.w1 = 0; +- t.parts32.w2 = 0; +- t.parts32.w3 = 0; ++ INSERT_WORDS (xhi, 0x3fe00000 + (k << 14), 0); ++ t = xhi; + } +- u.value = __scalbnl (u.value, ((int) ((w0 - u.parts32.w0) * 2)) >> 21); ++ x = __scalbnl (x, ((int) ((w0 - hx) * 2)) >> 21); + /* log(u) = log( t u/t ) = log(t) + log(u/t) + log(t) is tabulated in the lookup table. + Express log(u/t) = log(1+z), where z = u/t - 1 = (u-t)/t. + cf. Cody & Waite. */ +- z = (u.value - t.value) / t.value; ++ z = (x - t) / t; + } + /* Series expansion of log(1+z). */ + w = z * z; +@@ -275,7 +273,7 @@ + y += e * ln2b; /* Base 2 exponent offset times ln(2). */ + y += z; + y += logtbl[k-26]; /* log(t) - (t-1) */ +- y += (t.value - 1.0L); ++ y += (t - 1.0L); + y += e * ln2a; + return y; + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_powl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_powl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_powl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_powl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -151,37 +151,32 @@ + long double y1, t1, t2, r, s, t, u, v, w; + long double s2, s_h, s_l, t_h, t_l, ay; + int32_t i, j, k, yisint, n; +- u_int32_t ix, iy; +- int32_t hx, hy; +- ieee854_long_double_shape_type o, p, q; ++ uint32_t ix, iy; ++ int32_t hx, hy, hax; ++ double ohi, xhi, xlo, yhi, ylo; ++ uint32_t lx, ly, lj; + +- p.value = x; +- hx = p.parts32.w0; ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS (hx, lx, xhi); + ix = hx & 0x7fffffff; + +- q.value = y; +- hy = q.parts32.w0; ++ ldbl_unpack (y, &yhi, &ylo); ++ EXTRACT_WORDS (hy, ly, yhi); + iy = hy & 0x7fffffff; + +- + /* y==zero: x**0 = 1 */ +- if ((iy | q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0) ++ if ((iy | ly) == 0) + return one; + + /* 1.0**y = 1; -1.0**+-Inf = 1 */ + if (x == one) + return one; +- if (x == -1.0L && iy == 0x7ff00000 +- && (q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0) ++ if (x == -1.0L && ((iy - 0x7ff00000) | ly) == 0) + return one; + + /* +-NaN return x+y */ +- if ((ix > 0x7ff00000) +- || ((ix == 0x7ff00000) +- && ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) != 0)) +- || (iy > 0x7ff00000) +- || ((iy == 0x7ff00000) +- && ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) != 0))) ++ if ((ix >= 0x7ff00000 && ((ix - 0x7ff00000) | lx) != 0) ++ || (iy >= 0x7ff00000 && ((iy - 0x7ff00000) | ly) != 0)) + return x + y; + + /* determine if y is an odd int when x < 0 +@@ -192,7 +187,10 @@ + yisint = 0; + if (hx < 0) + { +- if ((q.parts32.w2 & 0x7fffffff) >= 0x43400000) /* Low part >= 2^53 */ ++ uint32_t low_ye; ++ ++ GET_HIGH_WORD (low_ye, ylo); ++ if ((low_ye & 0x7fffffff) >= 0x43400000) /* Low part >= 2^53 */ + yisint = 2; /* even integer y */ + else if (iy >= 0x3ff00000) /* 1.0 */ + { +@@ -207,42 +205,43 @@ + } + } + ++ ax = fabsl (x); ++ + /* special value of y */ +- if ((q.parts32.w1 | (q.parts32.w2 & 0x7fffffff) | q.parts32.w3) == 0) ++ if (ly == 0) + { +- if (iy == 0x7ff00000 && q.parts32.w1 == 0) /* y is +-inf */ ++ if (iy == 0x7ff00000) /* y is +-inf */ + { +- if (((ix - 0x3ff00000) | p.parts32.w1 +- | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0) +- return y - y; /* inf**+-1 is NaN */ +- else if (ix > 0x3ff00000 || fabsl (x) > 1.0L) ++ if (ax > one) + /* (|x|>1)**+-inf = inf,0 */ + return (hy >= 0) ? y : zero; + else + /* (|x|<1)**-,+inf = inf,0 */ + return (hy < 0) ? -y : zero; + } +- if (iy == 0x3ff00000) +- { /* y is +-1 */ +- if (hy < 0) +- return one / x; +- else +- return x; +- } +- if (hy == 0x40000000) +- return x * x; /* y is 2 */ +- if (hy == 0x3fe00000) +- { /* y is 0.5 */ +- if (hx >= 0) /* x >= +0 */ +- return __ieee754_sqrtl (x); ++ if (ylo == 0.0) ++ { ++ if (iy == 0x3ff00000) ++ { /* y is +-1 */ ++ if (hy < 0) ++ return one / x; ++ else ++ return x; ++ } ++ if (hy == 0x40000000) ++ return x * x; /* y is 2 */ ++ if (hy == 0x3fe00000) ++ { /* y is 0.5 */ ++ if (hx >= 0) /* x >= +0 */ ++ return __ieee754_sqrtl (x); ++ } + } + } + +- ax = fabsl (x); + /* special value of x */ +- if ((p.parts32.w1 | (p.parts32.w2 & 0x7fffffff) | p.parts32.w3) == 0) ++ if (lx == 0) + { +- if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) ++ if (ix == 0x7ff00000 || ix == 0 || (ix == 0x3ff00000 && xlo == 0.0)) + { + z = ax; /*x is +-0,+-inf,+-1 */ + if (hy < 0) +@@ -294,8 +293,8 @@ + { + ax *= two113; + n -= 113; +- o.value = ax; +- ix = o.parts32.w0; ++ ohi = ldbl_high (ax); ++ GET_HIGH_WORD (ix, ohi); + } + n += ((ix) >> 20) - 0x3ff; + j = ix & 0x000fffff; +@@ -312,26 +311,19 @@ + ix -= 0x00100000; + } + +- o.value = ax; +- o.value = __scalbnl (o.value, ((int) ((ix - o.parts32.w0) * 2)) >> 21); +- ax = o.value; ++ ohi = ldbl_high (ax); ++ GET_HIGH_WORD (hax, ohi); ++ ax = __scalbnl (ax, ((int) ((ix - hax) * 2)) >> 21); + + /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ + u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ + v = one / (ax + bp[k]); + s = u * v; +- s_h = s; ++ s_h = ldbl_high (s); + +- o.value = s_h; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- s_h = o.value; + /* t_h=ax+bp[k] High */ + t_h = ax + bp[k]; +- o.value = t_h; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- t_h = o.value; ++ t_h = ldbl_high (t_h); + t_l = ax - (t_h - bp[k]); + s_l = v * ((u - s_h * t_h) - s_h * t_l); + /* compute log(ax) */ +@@ -342,30 +334,21 @@ + r += s_l * (s_h + s); + s2 = s_h * s_h; + t_h = 3.0 + s2 + r; +- o.value = t_h; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- t_h = o.value; ++ t_h = ldbl_high (t_h); + t_l = r - ((t_h - 3.0) - s2); + /* u+v = s*(1+...) */ + u = s_h * t_h; + v = s_l * t_h + t_l * s; + /* 2/(3log2)*(s+...) */ + p_h = u + v; +- o.value = p_h; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- p_h = o.value; ++ p_h = ldbl_high (p_h); + p_l = v - (p_h - u); + z_h = cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l * p_h + p_l * cp + dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (long double) n; + t1 = (((z_h + z_l) + dp_h[k]) + t); +- o.value = t1; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- t1 = o.value; ++ t1 = ldbl_high (t1); + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + + /* s (sign of result -ve**odd) = -1 else = 1 */ +@@ -374,21 +357,16 @@ + s = -one; /* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ +- y1 = y; +- o.value = y1; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- y1 = o.value; ++ y1 = ldbl_high (y); + p_l = (y - y1) * t1 + y * t2; + p_h = y1 * t1; + z = p_l + p_h; +- o.value = z; +- j = o.parts32.w0; ++ ohi = ldbl_high (z); ++ EXTRACT_WORDS (j, lj, ohi); + if (j >= 0x40d00000) /* z >= 16384 */ + { + /* if z > 16384 */ +- if (((j - 0x40d00000) | o.parts32.w1 +- | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0) ++ if (((j - 0x40d00000) | lj) != 0) + return s * huge * huge; /* overflow */ + else + { +@@ -399,8 +377,7 @@ + else if ((j & 0x7fffffff) >= 0x40d01b90) /* z <= -16495 */ + { + /* z < -16495 */ +- if (((j - 0xc0d01bc0) | o.parts32.w1 +- | (o.parts32.w2 & 0x7fffffff) | o.parts32.w3) != 0) ++ if (((j - 0xc0d01bc0) | lj) != 0) + return s * tiny * tiny; /* underflow */ + else + { +@@ -419,10 +396,7 @@ + p_h -= t; + } + t = p_l + p_h; +- o.value = t; +- o.parts32.w3 = 0; +- o.parts32.w2 = 0; +- t = o.value; ++ t = ldbl_high (t); + u = t * lg2_h; + v = (p_l - (t - p_h)) * lg2 + t * lg2_l; + z = u + v; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_tanl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_tanl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_tanl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/k_tanl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -85,17 +85,17 @@ + __kernel_tanl (long double x, long double y, int iy) + { + long double z, r, v, w, s; +- int32_t ix, sign; +- ieee854_long_double_shape_type u, u1; ++ int32_t ix, sign, hx, lx; ++ double xhi; + +- u.value = x; +- ix = u.parts32.w0 & 0x7fffffff; ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS (hx, lx, xhi); ++ ix = hx & 0x7fffffff; + if (ix < 0x3c600000) /* x < 2**-57 */ + { +- if ((int) x == 0) +- { /* generate inexact */ +- if ((ix | u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3 +- | (iy + 1)) == 0) ++ if ((int) x == 0) /* generate inexact */ ++ { ++ if ((ix | lx | (iy + 1)) == 0) + return one / fabs (x); + else + return (iy == 1) ? x : -one / x; +@@ -103,7 +103,7 @@ + } + if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */ + { +- if ((u.parts32.w0 & 0x80000000) != 0) ++ if ((hx & 0x80000000) != 0) + { + x = -x; + y = -y; +@@ -139,15 +139,13 @@ + { /* if allow error up to 2 ulp, + simply return -1.0/(x+r) here */ + /* compute -1.0/(x+r) accurately */ +- u1.value = w; +- u1.parts32.w2 = 0; +- u1.parts32.w3 = 0; +- v = r - (u1.value - x); /* u1+v = r+x */ ++ long double u1, z1; ++ ++ u1 = ldbl_high (w); ++ v = r - (u1 - x); /* u1+v = r+x */ + z = -1.0 / w; +- u.value = z; +- u.parts32.w2 = 0; +- u.parts32.w3 = 0; +- s = 1.0 + u.value * u1.value; +- return u.value + z * (s + u.value * v); ++ z1 = ldbl_high (z); ++ s = 1.0 + z1 * u1; ++ return z1 + z * (s + z1 * v); + } + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_expm1l.c 2014-05-27 23:05:55.000000000 -0500 +@@ -92,19 +92,19 @@ + __expm1l (long double x) + { + long double px, qx, xx; +- int32_t ix, sign; +- ieee854_long_double_shape_type u; ++ int32_t ix, lx, sign; + int k; ++ double xhi; + + /* Detect infinity and NaN. */ +- u.value = x; +- ix = u.parts32.w0; ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS (ix, lx, xhi); + sign = ix & 0x80000000; + ix &= 0x7fffffff; + if (ix >= 0x7ff00000) + { + /* Infinity. */ +- if (((ix & 0xfffff) | u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0) ++ if (((ix - 0x7ff00000) | lx) == 0) + { + if (sign) + return -1.0L; +@@ -116,7 +116,7 @@ + } + + /* expm1(+- 0) = +- 0. */ +- if ((ix == 0) && (u.parts32.w1 | (u.parts32.w2&0x7fffffff) | u.parts32.w3) == 0) ++ if ((ix | lx) == 0) + return x; + + /* Overflow. */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -36,16 +36,21 @@ + + long double __frexpl(long double x, int *eptr) + { +- u_int64_t hx, lx, ix, ixl; ++ uint64_t hx, lx, ix, ixl; + int64_t explo; +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); + ixl = 0x7fffffffffffffffULL&lx; + ix = 0x7fffffffffffffffULL&hx; + *eptr = 0; +- if(ix>=0x7ff0000000000000ULL||((ix|ixl)==0)) return x; /* 0,inf,nan */ ++ if(ix>=0x7ff0000000000000ULL||ix==0) return x; /* 0,inf,nan */ + if (ix<0x0010000000000000ULL) { /* subnormal */ + x *= two107; +- GET_LDOUBLE_MSW64(hx,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); + ix = hx&0x7fffffffffffffffULL; + *eptr = -107; + } +@@ -54,7 +59,7 @@ + if (ixl != 0ULL) { + explo = (ixl>>52) - (ix>>52) + 0x3fe; + if ((ixl&0x7ff0000000000000ULL) == 0LL) { +- /* the lower double is a denomal so we need to correct its ++ /* the lower double is a denormal so we need to correct its + mantissa and perhaps its exponent. */ + int cnt; + +@@ -73,7 +78,9 @@ + lx = 0ULL; + + hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL; +- SET_LDOUBLE_WORDS64(x,hx,lx); ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x; + } + #ifdef IS_IN_libm +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinf_nsl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -1,6 +1,7 @@ + /* + * __isinf_nsl(x) returns != 0 if x is ±inf, else 0; + * no branching! ++ * slightly dodgy in relying on signed shift right copying sign bit + */ + + #include +@@ -9,8 +10,14 @@ + int + __isinf_nsl (long double x) + { +- int64_t hx,lx; +- GET_LDOUBLE_WORDS64(hx,lx,x); +- return !((lx & 0x7fffffffffffffffLL) +- | ((hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL)); ++ double xhi; ++ int64_t hx, mask; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); ++ ++ mask = (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL; ++ mask |= -mask; ++ mask >>= 63; ++ return ~mask; + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -11,6 +11,7 @@ + /* + * isinfl(x) returns 1 if x is inf, -1 if x is -inf, else 0; + * no branching! ++ * slightly dodgy in relying on signed shift right copying sign bit + */ + + #include +@@ -20,12 +21,16 @@ + int + ___isinfl (long double x) + { +- int64_t hx,lx; +- GET_LDOUBLE_WORDS64(hx,lx,x); +- lx = (lx & 0x7fffffffffffffffLL); +- lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL; +- lx |= -lx; +- return ~(lx >> 63) & (hx >> 62); ++ double xhi; ++ int64_t hx, mask; ++ ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (hx, xhi); ++ ++ mask = (hx & 0x7fffffffffffffffLL) ^ 0x7ff0000000000000LL; ++ mask |= -mask; ++ mask >>= 63; ++ return ~mask & (hx >> 62); + } + hidden_ver (___isinfl, __isinfl) + #ifndef IS_IN_libm +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_log1pl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -126,19 +126,18 @@ + __log1pl (long double xm1) + { + long double x, y, z, r, s; +- ieee854_long_double_shape_type u; +- int32_t hx; ++ double xhi; ++ int32_t hx, lx; + int e; + + /* Test for NaN or infinity input. */ +- u.value = xm1; +- hx = u.parts32.w0; ++ xhi = ldbl_high (xm1); ++ EXTRACT_WORDS (hx, lx, xhi); + if (hx >= 0x7ff00000) + return xm1; + + /* log1p(+- 0) = +- 0. */ +- if (((hx & 0x7fffffff) == 0) +- && (u.parts32.w1 | (u.parts32.w2 & 0x7fffffff) | u.parts32.w3) == 0) ++ if (((hx & 0x7fffffff) | lx) == 0) + return xm1; + + x = xm1 + 1.0L; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_modfl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_modfl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_modfl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_modfl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -37,43 +37,54 @@ + { + int64_t i0,i1,j0; + u_int64_t i; +- GET_LDOUBLE_WORDS64(i0,i1,x); ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (i0, xhi); ++ EXTRACT_WORDS64 (i1, xlo); + i1 &= 0x000fffffffffffffLL; + j0 = ((i0>>52)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<52) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + /* *iptr = +-0 */ +- SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0); ++ INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); ++ *iptr = xhi; + return x; + } else { + i = (0x000fffffffffffffLL)>>j0; + if(((i0&i)|(i1&0x7fffffffffffffffLL))==0) { /* x is integral */ + *iptr = x; + /* return +-0 */ +- SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); ++ INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); ++ x = xhi; + return x; + } else { +- SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0); ++ INSERT_WORDS64 (xhi, i0&(~i)); ++ *iptr = xhi; + return x - *iptr; + } + } + } else if (j0>103) { /* no fraction part */ + *iptr = x*one; + /* We must handle NaNs separately. */ +- if (j0 == 0x400 && ((i0 & 0x000fffffffffffffLL) | i1)) ++ if ((i0 & 0x7fffffffffffffffLL) > 0x7ff0000000000000LL) + return x*one; + /* return +-0 */ +- SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); ++ INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); ++ x = xhi; + return x; + } else { /* fraction part in low x */ + i = -1ULL>>(j0-52); + if((i1&i)==0) { /* x is integral */ + *iptr = x; + /* return +-0 */ +- SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); ++ INSERT_WORDS64 (xhi, i0&0x8000000000000000ULL); ++ x = xhi; + return x; + } else { +- SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i)); ++ INSERT_WORDS64 (xhi, i0); ++ INSERT_WORDS64 (xlo, i1&(~i)); ++ *iptr = ldbl_pack (xhi, xlo); + return x - *iptr; + } + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -30,27 +30,28 @@ + + long double __nextafterl(long double x, long double y) + { +- int64_t hx,hy,ihx,ihy,ilx; +- u_int64_t lx; +- u_int64_t ly __attribute__ ((unused)); ++ int64_t hx,hy,ihx,ihy; ++ uint64_t lx; ++ double xhi, xlo, yhi; + +- GET_LDOUBLE_WORDS64(hx,lx,x); +- GET_LDOUBLE_WORDS64(hy,ly,y); ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); ++ yhi = ldbl_high (y); ++ EXTRACT_WORDS64 (hy, yhi); + ihx = hx&0x7fffffffffffffffLL; /* |hx| */ +- ilx = lx&0x7fffffffffffffffLL; /* |lx| */ + ihy = hy&0x7fffffffffffffffLL; /* |hy| */ + +- if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&& +- ((ihx&0x000fffffffffffffLL)!=0)) || /* x is nan */ +- (((ihy&0x7ff0000000000000LL)==0x7ff0000000000000LL)&& +- ((ihy&0x000fffffffffffffLL)!=0))) /* y is nan */ ++ if((ihx>0x7ff0000000000000LL) || /* x is nan */ ++ (ihy>0x7ff0000000000000LL)) /* y is nan */ + return x+y; /* signal the nan */ + if(x==y) + return y; /* x=y, return y */ +- if(ihx == 0 && ilx == 0) { /* x == 0 */ +- long double u; ++ if(ihx == 0) { /* x == 0 */ ++ long double u; /* return +-minsubnormal */ + hy = (hy & 0x8000000000000000ULL) | 1; +- SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */ ++ INSERT_WORDS64 (yhi, hy); ++ x = yhi; + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ +@@ -59,10 +60,16 @@ + + long double u; + if(x > y) { /* x > y, x -= ulp */ ++ /* This isn't the largest magnitude correctly rounded ++ long double as you can see from the lowest mantissa ++ bit being zero. It is however the largest magnitude ++ long double with a 106 bit mantissa, and nextafterl ++ is insane with variable precision. So to make ++ nextafterl sane we assume 106 bit precision. */ + if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL)) + return x+x; /* overflow, return -inf */ + if (hx >= 0x7ff0000000000000LL) { +- SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL); ++ u = 0x1.fffffffffffff7ffffffffffff8p+1023L; + return u; + } + if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ +@@ -77,16 +84,19 @@ + return x; + } + if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ +- SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); ++ INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52)); ++ u = yhi; + u *= 0x1.0000000000000p-105L; +- } else +- SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); ++ } else { ++ INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52)); ++ u = yhi; ++ } + return x - u; + } else { /* x < y, x += ulp */ + if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL)) + return x+x; /* overflow, return +inf */ +- if ((u_int64_t) hx >= 0xfff0000000000000ULL) { +- SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL); ++ if ((uint64_t) hx >= 0xfff0000000000000ULL) { ++ u = -0x1.fffffffffffff7ffffffffffff8p+1023L; + return u; + } + if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ +@@ -103,10 +113,13 @@ + return x; + } + if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ +- SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); ++ INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52)); ++ u = yhi; + u *= 0x1.0000000000000p-105L; +- } else +- SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); ++ } else { ++ INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52)); ++ u = yhi; ++ } + return x + u; + } + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c 2014-05-27 23:10:26.000000000 -0500 +@@ -34,23 +34,23 @@ + { + int32_t hx,ix; + int64_t hy,iy; +- u_int32_t lx; +- u_int64_t ly,uly; ++ uint32_t lx; ++ double yhi; ++ + + EXTRACT_WORDS(hx,lx,x); +- GET_LDOUBLE_WORDS64(hy,ly,y); ++ yhi = ldbl_high (y); ++ EXTRACT_WORDS64(hy,yhi); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffffffffffffLL; /* |y| */ +- uly = ly&0x7fffffffffffffffLL; /* |y| */ + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ +- ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0)) +- /* y is nan */ ++ iy>0x7ff0000000000000LL) /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if((ix|lx)==0) { /* x == 0 */ + double u; +- INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ ++ INSERT_WORDS(x,(uint32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ + u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c 2014-05-27 23:05:55.000000000 -0500 +@@ -27,16 +27,16 @@ + { + int32_t hx,ix; + int64_t hy,iy; +- u_int64_t ly, uly; ++ double yhi; + + GET_FLOAT_WORD(hx,x); +- GET_LDOUBLE_WORDS64(hy,ly,y); ++ yhi = ldbl_high (y); ++ EXTRACT_WORDS64 (hy, yhi); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffffffffffffLL; /* |y| */ +- uly = ly&0x7fffffffffffffffLL; /* |y| */ + + if((ix>0x7f800000) || /* x is nan */ +- ((iy>=0x7ff0000000000000LL)&&((iy-0x7ff0000000000000LL)|uly)!=0)) ++ (iy>0x7ff0000000000000LL)) + /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_remquol.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_remquol.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_remquol.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_remquol.c 2014-05-27 23:05:55.000000000 -0500 +@@ -33,20 +33,24 @@ + int64_t hx,hy; + u_int64_t sx,lx,ly,qs; + int cquo; ++ double xhi, xlo, yhi, ylo; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); +- GET_LDOUBLE_WORDS64 (hy, ly, y); ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); ++ ldbl_unpack (y, &yhi, &ylo); ++ EXTRACT_WORDS64 (hy, yhi); ++ EXTRACT_WORDS64 (ly, ylo); + sx = hx & 0x8000000000000000ULL; + qs = sx ^ (hy & 0x8000000000000000ULL); + hy &= 0x7fffffffffffffffLL; + hx &= 0x7fffffffffffffffLL; + + /* Purge off exception values. */ +- if ((hy | (ly & 0x7fffffffffffffff)) == 0) ++ if (hy == 0) + return (x * y) / (x * y); /* y = 0 */ + if ((hx >= 0x7ff0000000000000LL) /* x not finite */ +- || ((hy >= 0x7ff0000000000000LL) /* y is NaN */ +- && (((hy - 0x7ff0000000000000LL) | ly) != 0))) ++ || (hy > 0x7ff0000000000000LL)) /* y is NaN */ + return (x * y) / (x * y); + + if (hy <= 0x7fbfffffffffffffLL) +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalblnl.c 2014-05-27 23:15:30.000000000 -0500 +@@ -41,11 +41,15 @@ + { + int64_t k,l,hx,lx; + union { int64_t i; double d; } u; +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); + k = (hx>>52)&0x7ff; /* extract exponent */ + l = (lx>>52)&0x7ff; + if (k==0) { /* 0 or subnormal x */ +- if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */ ++ if ((hx&0x7fffffffffffffffULL)==0) return x; /* +-0 */ + u.i = hx; + u.d *= two54; + hx = u.i; +@@ -61,7 +65,9 @@ + if (k > 0) { /* normal result */ + hx = (hx&0x800fffffffffffffULL)|(k<<52); + if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */ +- SET_LDOUBLE_WORDS64(x,hx,lx); ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x; + } + if (l == 0) { /* low part subnormal */ +@@ -81,14 +87,19 @@ + u.d *= twom54; + lx = u.i; + } +- SET_LDOUBLE_WORDS64(x,hx,lx); ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x; + } + if (k <= -54) + return tiny*__copysignl(tiny,x); /*underflow*/ + k += 54; /* subnormal result */ + lx &= 0x8000000000000000ULL; +- SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx); ++ hx &= 0x800fffffffffffffULL; ++ INSERT_WORDS64 (xhi, hx|(k<<52)); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x*twolm54; + } + long_double_symbol (libm, __scalblnl, scalblnl); +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c 2014-05-27 23:16:25.000000000 -0500 +@@ -41,11 +41,15 @@ + { + int64_t k,l,hx,lx; + union { int64_t i; double d; } u; +- GET_LDOUBLE_WORDS64(hx,lx,x); ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); + k = (hx>>52)&0x7ff; /* extract exponent */ + l = (lx>>52)&0x7ff; + if (k==0) { /* 0 or subnormal x */ +- if (((hx|lx)&0x7fffffffffffffffULL)==0) return x; /* +-0 */ ++ if ((hx&0x7fffffffffffffffULL)==0) return x; /* +-0 */ + u.i = hx; + u.d *= two54; + hx = u.i; +@@ -61,7 +65,9 @@ + if (k > 0) { /* normal result */ + hx = (hx&0x800fffffffffffffULL)|(k<<52); + if ((lx & 0x7fffffffffffffffULL) == 0) { /* low part +-0 */ +- SET_LDOUBLE_WORDS64(x,hx,lx); ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x; + } + if (l == 0) { /* low part subnormal */ +@@ -81,14 +87,19 @@ + u.d *= twom54; + lx = u.i; + } +- SET_LDOUBLE_WORDS64(x,hx,lx); ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x; + } + if (k <= -54) + return tiny*__copysignl(tiny,x); /*underflow*/ + k += 54; /* subnormal result */ + lx &= 0x8000000000000000ULL; +- SET_LDOUBLE_WORDS64(x,(hx&0x800fffffffffffffULL)|(k<<52),lx); ++ hx &= 0x800fffffffffffffULL; ++ INSERT_WORDS64 (xhi, hx|(k<<52)); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); + return x*twolm54; + } + #ifdef IS_IN_libm +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_tanhl.c 2014-05-27 23:05:55.000000000 -0500 +@@ -47,10 +47,12 @@ + long double __tanhl(long double x) + { + long double t,z; +- int64_t jx,ix,lx; ++ int64_t jx,ix; ++ double xhi; + + /* High word of |x|. */ +- GET_LDOUBLE_WORDS64(jx,lx,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (jx, xhi); + ix = jx&0x7fffffffffffffffLL; + + /* x is INF or NaN */ +@@ -61,7 +63,7 @@ + + /* |x| < 22 */ + if (ix < 0x4036000000000000LL) { /* |x|<22 */ +- if ((ix | (lx&0x7fffffffffffffffLL)) == 0) ++ if (ix == 0) + return x; /* x == +-0 */ + if (ix<0x3c60000000000000LL) /* |x|<2**-57 */ + return x*(one+x); /* tanh(small) = small */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps 2014-05-27 23:05:51.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps 2014-05-27 23:08:26.000000000 -0500 +@@ -2641,6 +2641,9 @@ + ifloat: 1 + ildouble: 2 + ldouble: 2 ++Test "tan_towardzero (2)": ++ildouble: 1 ++ldouble: 1 + Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261": + float: 1 + ifloat: 1 diff --git a/SOURCES/glibc-ppc64le-09.patch b/SOURCES/glibc-ppc64le-09.patch new file mode 100644 index 00000000..bcf17b4d --- /dev/null +++ b/SOURCES/glibc-ppc64le-09.patch @@ -0,0 +1,567 @@ +# commit 650ef4bd7976e36831cba22d838b567d3b5f6e8f +# Author: Alan Modra +# Date: Sat Aug 17 18:25:51 2013 +0930 +# +# PowerPC floating point little-endian [4 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00084.html +# +# Another batch of ieee854 macros and union replacement. These four +# files also have bugs fixed with this patch. The fact that the two +# doubles in an IBM long double may have different signs means that +# negation and absolute value operations can't just twiddle one sign bit +# as you can with ieee864 style extended double. fmodl, remainderl, +# erfl and erfcl all had errors of this type. erfl also returned +1 for +# large magnitude negative input where it should return -1. The hypotl +# error is innocuous since the value adjusted twice is only used as a +# flag. The e_hypotl.c tests for large "a" and small "b" are mutually +# exclusive because we've already exited when x/y > 2**120. That allows +# some further small simplifications. +# +# [BZ #15734], [BZ #15735] +# * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Rewrite +# all uses of ieee875 long double macros and unions. Simplify test +# for 0.0L. Correct |x|<|y| and |x|=|y| test. Use +# ldbl_extract_mantissa value for ix,iy exponents. Properly +# normalize after ldbl_extract_mantissa, and don't add hidden bit +# already handled. Don't treat low word of ieee854 mantissa like +# low word of IBM long double and mask off bit when testing for +# zero. +# * sysdeps/ieee754/ldbl-128ibm/e_hypotl.c (__ieee754_hypotl): Rewrite +# all uses of ieee875 long double macros and unions. Simplify tests +# for 0.0L and inf. Correct double adjustment of k. Delete dead code +# adjusting ha,hb. Simplify code setting kld. Delete two600 and +# two1022, instead use their values. Recognise that tests for large +# "a" and small "b" are mutually exclusive. Rename vars. Comment. +# * sysdeps/ieee754/ldbl-128ibm/e_remainderl.c (__ieee754_remainderl): +# Rewrite all uses of ieee875 long double macros and unions. Simplify +# test for 0.0L and nan. Correct negation. +# * sysdeps/ieee754/ldbl-128ibm/s_erfl.c (__erfl): Rewrite all uses of +# ieee875 long double macros and unions. Correct output for large +# magnitude x. Correct absolute value calculation. +# (__erfcl): Likewise. +# * math/libm-test.inc: Add tests for errors discovered in IBM long +# double versions of fmodl, remainderl, erfl and erfcl. +# +diff -urN glibc-2.17-c758a686/math/libm-test.inc glibc-2.17-c758a686/math/libm-test.inc +--- glibc-2.17-c758a686/math/libm-test.inc 2014-05-27 20:02:29.000000000 -0500 ++++ glibc-2.17-c758a686/math/libm-test.inc 2014-05-27 20:09:59.000000000 -0500 +@@ -4040,6 +4040,10 @@ + TEST_f_f (erf, 2.0L, 0.995322265018952734162069256367252929L); + TEST_f_f (erf, 4.125L, 0.999999994576599200434933994687765914L); + TEST_f_f (erf, 27.0L, 1.0L); ++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 54 ++ /* The input is not exactly representable as a double. */ ++ TEST_f_f (erf, -0x1.fffffffffffff8p-2L, -0.5204998778130465132916303345518417673509L); ++#endif + + END (erf); + } +@@ -4071,6 +4075,10 @@ + TEST_f_f (erfc, 0x1.ffa002p+2L, 1.233585992097580296336099501489175967033e-29L); + TEST_f_f (erfc, 0x1.ffffc8p+2L, 1.122671365033056305522366683719541099329e-29L); + #ifdef TEST_LDOUBLE ++# if LDBL_MANT_DIG >= 54 ++ /* The input is not exactly representable as a double. */ ++ TEST_f_f (erfc, -0x1.fffffffffffff8p-2L, 1.52049987781304651329163033455184176735L); ++# endif + /* The result can only be represented in long double. */ + # if LDBL_MIN_10_EXP < -319 + TEST_f_f (erfc, 27.0L, 0.523704892378925568501606768284954709e-318L); +@@ -5634,6 +5642,13 @@ + #if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381 + TEST_ff_f (fmod, 0x0.fffffffffffffffep-16382L, 0x1p-16445L, plus_zero); + #endif ++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56 ++ TEST_ff_f (fmod, -0x1.00000000000004p+0L, 0x1.fffffffffffff8p-1L, -0x1p-53L); ++ TEST_ff_f (fmod, 0x1.fffffffffffffap-1L, 0x1.fffffffffffff8p-1L, 0x1p-56L); ++ TEST_ff_f (fmod, -0x1.fffffffffffffap-1L, 0x1.fffffffffffff8p-1L, -0x1p-56L); ++ TEST_ff_f (fmod, 0x1.fffffffffffffap-1L, -0x1.fffffffffffff8p-1L, 0x1p-56L); ++ TEST_ff_f (fmod, -0x1.fffffffffffffap-1L, -0x1.fffffffffffff8p-1L, -0x1p-56L); ++#endif + + END (fmod); + } +@@ -8642,6 +8657,9 @@ + TEST_ff_f (remainder, -1.625, -1.0, 0.375); + TEST_ff_f (remainder, 5.0, 2.0, 1.0); + TEST_ff_f (remainder, 3.0, 2.0, -1.0); ++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 56 ++ TEST_ff_f (remainder, -0x1.80000000000002p1L, 2.0, 0x1.fffffffffffff8p-1L); ++#endif + + END (remainder); + } +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c 2014-05-27 20:02:27.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c 2014-05-27 20:04:08.000000000 -0500 +@@ -27,76 +27,83 @@ + long double + __ieee754_fmodl (long double x, long double y) + { +- int64_t n,hx,hy,hz,ix,iy,sx, i; +- u_int64_t lx,ly,lz; +- int temp; +- +- GET_LDOUBLE_WORDS64(hx,lx,x); +- GET_LDOUBLE_WORDS64(hy,ly,y); ++ int64_t hx, hy, hz, sx, sy; ++ uint64_t lx, ly, lz; ++ int n, ix, iy; ++ double xhi, xlo, yhi, ylo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); ++ ldbl_unpack (y, &yhi, &ylo); ++ EXTRACT_WORDS64 (hy, yhi); ++ EXTRACT_WORDS64 (ly, ylo); + sx = hx&0x8000000000000000ULL; /* sign of x */ +- hx ^=sx; /* |x| */ +- hy &= 0x7fffffffffffffffLL; /* |y| */ ++ hx ^= sx; /* |x| */ ++ sy = hy&0x8000000000000000ULL; /* sign of y */ ++ hy ^= sy; /* |y| */ + + /* purge off exception values */ +- if(__builtin_expect((hy|(ly&0x7fffffffffffffff))==0 || ++ if(__builtin_expect(hy==0 || + (hx>=0x7ff0000000000000LL)|| /* y=0,or x not finite */ + (hy>0x7ff0000000000000LL),0)) /* or y is NaN */ + return (x*y)/(x*y); +- if(__builtin_expect(hx<=hy,0)) { +- if((hx>63]; /* |x|=|y| return x*0*/ ++ if (__builtin_expect (hx <= hy, 0)) ++ { ++ /* If |x| < |y| return x. */ ++ if (hx < hy) ++ return x; ++ /* At this point the absolute value of the high doubles of ++ x and y must be equal. */ ++ /* If the low double of y is the same sign as the high ++ double of y (ie. the low double increases |y|)... */ ++ if (((ly ^ sy) & 0x8000000000000000LL) == 0 ++ /* ... then a different sign low double to high double ++ for x or same sign but lower magnitude... */ ++ && (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy)) ++ /* ... means |x| < |y|. */ ++ return x; ++ /* If the low double of x differs in sign to the high ++ double of x (ie. the low double decreases |x|)... */ ++ if (((lx ^ sx) & 0x8000000000000000LL) != 0 ++ /* ... then a different sign low double to high double ++ for y with lower magnitude (we've already caught ++ the same sign for y case above)... */ ++ && (int64_t) (lx ^ sx) > (int64_t) (ly ^ sy)) ++ /* ... means |x| < |y|. */ ++ return x; ++ /* If |x| == |y| return x*0. */ ++ if ((lx ^ sx) == (ly ^ sy)) ++ return Zero[(uint64_t) sx >> 63]; + } + +- /* determine ix = ilogb(x) */ +- if(__builtin_expect(hx<0x0010000000000000LL,0)) { /* subnormal x */ +- if(hx==0) { +- for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; +- } else { +- for (ix = -1022, i=(hx<<11); i>0; i<<=1) ix -=1; +- } +- } else ix = (hx>>52)-0x3ff; +- +- /* determine iy = ilogb(y) */ +- if(__builtin_expect(hy<0x0010000000000000LL,0)) { /* subnormal y */ +- if(hy==0) { +- for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; +- } else { +- for (iy = -1022, i=(hy<<11); i>0; i<<=1) iy -=1; +- } +- } else iy = (hy>>52)-0x3ff; +- + /* Make the IBM extended format 105 bit mantissa look like the ieee854 112 + bit mantissa so the following operations will give the correct + result. */ +- ldbl_extract_mantissa(&hx, &lx, &temp, x); +- ldbl_extract_mantissa(&hy, &ly, &temp, y); ++ ldbl_extract_mantissa(&hx, &lx, &ix, x); ++ ldbl_extract_mantissa(&hy, &ly, &iy, y); + +- /* set up {hx,lx}, {hy,ly} and align y to x */ +- if(__builtin_expect(ix >= -1022, 1)) +- hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx); +- else { /* subnormal x, shift x to normal */ +- n = -1022-ix; +- if(n<=63) { +- hx = (hx<>(64-n)); +- lx <<= n; +- } else { +- hx = lx<<(n-64); +- lx = 0; +- } +- } +- if(__builtin_expect(iy >= -1022, 1)) +- hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy); +- else { /* subnormal y, shift y to normal */ +- n = -1022-iy; +- if(n<=63) { +- hy = (hy<>(64-n)); +- ly <<= n; +- } else { +- hy = ly<<(n-64); +- ly = 0; +- } +- } ++ if (__builtin_expect (ix == -IEEE754_DOUBLE_BIAS, 0)) ++ { ++ /* subnormal x, shift x to normal. */ ++ while ((hx & (1LL << 48)) == 0) ++ { ++ hx = (hx << 1) | (lx >> 63); ++ lx = lx << 1; ++ ix -= 1; ++ } ++ } ++ ++ if (__builtin_expect (iy == -IEEE754_DOUBLE_BIAS, 0)) ++ { ++ /* subnormal y, shift y to normal. */ ++ while ((hy & (1LL << 48)) == 0) ++ { ++ hy = (hy << 1) | (ly >> 63); ++ ly = ly << 1; ++ iy -= 1; ++ } ++ } + + /* fix point fmod */ + n = ix - iy; +@@ -104,7 +111,7 @@ + hz=hx-hy;lz=lx-ly; if(lx>63); lx = lx+lx;} + else { +- if((hz|(lz&0x7fffffffffffffff))==0) /* return sign(x)*0 */ ++ if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(u_int64_t)sx>>63]; + hx = hz+hz+(lz>>63); lx = lz+lz; + } +@@ -113,7 +120,7 @@ + if(hz>=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ +- if((hx|(lx&0x7fffffffffffffff))==0) /* return sign(x)*0 */ ++ if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(u_int64_t)sx>>63]; + while(hx<0x0001000000000000LL) { /* normalize x */ + hx = hx+hx+(lx>>63); lx = lx+lx; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c 2014-05-27 20:02:27.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_hypotl.c 2014-05-27 20:04:08.000000000 -0500 +@@ -45,76 +45,84 @@ + #include + #include + +-static const long double two600 = 0x1.0p+600L; +-static const long double two1022 = 0x1.0p+1022L; +- + long double + __ieee754_hypotl(long double x, long double y) + { +- long double a,b,t1,t2,y1,y2,w,kld; ++ long double a,b,a1,a2,b1,b2,w,kld; + int64_t j,k,ha,hb; ++ double xhi, yhi, hi, lo; + +- GET_LDOUBLE_MSW64(ha,x); ++ xhi = ldbl_high (x); ++ EXTRACT_WORDS64 (ha, xhi); ++ yhi = ldbl_high (y); ++ EXTRACT_WORDS64 (hb, yhi); + ha &= 0x7fffffffffffffffLL; +- GET_LDOUBLE_MSW64(hb,y); + hb &= 0x7fffffffffffffffLL; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + a = fabsl(a); /* a <- |a| */ + b = fabsl(b); /* b <- |b| */ +- if((ha-hb)>0x780000000000000LL) {return a+b;} /* x/y > 2**120 */ ++ if((ha-hb)>0x0780000000000000LL) {return a+b;} /* x/y > 2**120 */ + k=0; + kld = 1.0L; + if(ha > 0x5f30000000000000LL) { /* a>2**500 */ + if(ha >= 0x7ff0000000000000LL) { /* Inf or NaN */ +- u_int64_t low; + w = a+b; /* for sNaN */ +- GET_LDOUBLE_LSW64(low,a); +- if(((ha&0xfffffffffffffLL)|(low&0x7fffffffffffffffLL))==0) ++ if(ha == 0x7ff0000000000000LL) + w = a; +- GET_LDOUBLE_LSW64(low,b); +- if(((hb^0x7ff0000000000000LL)|(low&0x7fffffffffffffffLL))==0) ++ if(hb == 0x7ff0000000000000LL) + w = b; + return w; + } + /* scale a and b by 2**-600 */ +- ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 600; +- a /= two600; +- b /= two600; +- k += 600; +- kld = two600; ++ a *= 0x1p-600L; ++ b *= 0x1p-600L; ++ k = 600; ++ kld = 0x1p+600L; + } +- if(hb < 0x23d0000000000000LL) { /* b < 2**-450 */ ++ else if(hb < 0x23d0000000000000LL) { /* b < 2**-450 */ + if(hb <= 0x000fffffffffffffLL) { /* subnormal b or 0 */ +- u_int64_t low; +- GET_LDOUBLE_LSW64(low,b); +- if((hb|(low&0x7fffffffffffffffLL))==0) return a; +- t1=two1022; /* t1=2^1022 */ +- b *= t1; +- a *= t1; +- k -= 1022; +- kld = kld / two1022; ++ if(hb==0) return a; ++ a *= 0x1p+1022L; ++ b *= 0x1p+1022L; ++ k = -1022; ++ kld = 0x1p-1022L; + } else { /* scale a and b by 2^600 */ +- ha += 0x2580000000000000LL; /* a *= 2^600 */ +- hb += 0x2580000000000000LL; /* b *= 2^600 */ +- k -= 600; +- a *= two600; +- b *= two600; +- kld = kld / two600; ++ a *= 0x1p+600L; ++ b *= 0x1p+600L; ++ k = -600; ++ kld = 0x1p-600L; + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { +- SET_LDOUBLE_WORDS64(t1,ha,0); +- t2 = a-t1; +- w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); ++ ldbl_unpack (a, &hi, &lo); ++ a1 = hi; ++ a2 = lo; ++ /* a*a + b*b ++ = (a1+a2)*a + b*b ++ = a1*a + a2*a + b*b ++ = a1*(a1+a2) + a2*a + b*b ++ = a1*a1 + a1*a2 + a2*a + b*b ++ = a1*a1 + a2*(a+a1) + b*b */ ++ w = __ieee754_sqrtl(a1*a1-(b*(-b)-a2*(a+a1))); + } else { + a = a+a; +- SET_LDOUBLE_WORDS64(y1,hb,0); +- y2 = b - y1; +- SET_LDOUBLE_WORDS64(t1,ha+0x0010000000000000LL,0); +- t2 = a - t1; +- w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b))); ++ ldbl_unpack (b, &hi, &lo); ++ b1 = hi; ++ b2 = lo; ++ ldbl_unpack (a, &hi, &lo); ++ a1 = hi; ++ a2 = lo; ++ /* a*a + b*b ++ = a*a + (a-b)*(a-b) - (a-b)*(a-b) + b*b ++ = a*a + w*w - (a*a - 2*a*b + b*b) + b*b ++ = w*w + 2*a*b ++ = w*w + (a1+a2)*b ++ = w*w + a1*b + a2*b ++ = w*w + a1*(b1+b2) + a2*b ++ = w*w + a1*b1 + a1*b2 + a2*b */ ++ w = __ieee754_sqrtl(a1*b1-(w*(-w)-(a1*b2+a2*b))); + } + if(k!=0) + return w*kld; +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c 2014-05-27 20:02:27.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_remainderl.c 2014-05-27 20:04:08.000000000 -0500 +@@ -33,18 +33,22 @@ + int64_t hx,hp; + u_int64_t sx,lx,lp; + long double p_half; ++ double xhi, xlo, phi, plo; + +- GET_LDOUBLE_WORDS64(hx,lx,x); +- GET_LDOUBLE_WORDS64(hp,lp,p); ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); ++ ldbl_unpack (p, &phi, &plo); ++ EXTRACT_WORDS64 (hp, phi); ++ EXTRACT_WORDS64 (lp, plo); + sx = hx&0x8000000000000000ULL; + hp &= 0x7fffffffffffffffLL; + hx &= 0x7fffffffffffffffLL; + + /* purge off exception values */ +- if((hp|(lp&0x7fffffffffffffff))==0) return (x*p)/(x*p); /* p = 0 */ ++ if(hp==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7ff0000000000000LL)|| /* x not finite */ +- ((hp>=0x7ff0000000000000LL)&& /* p is NaN */ +- (((hp-0x7ff0000000000000LL)|lp)!=0))) ++ (hp>0x7ff0000000000000LL)) /* p is NaN */ + return (x*p)/(x*p); + + +@@ -64,8 +68,8 @@ + if(x>=p_half) x -= p; + } + } +- GET_LDOUBLE_MSW64(hx,x); +- SET_LDOUBLE_MSW64(x,hx^sx); ++ if (sx) ++ x = -x; + return x; + } + strong_alias (__ieee754_remainderl, __remainderl_finite) +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c 2014-05-27 20:02:27.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_erfl.c 2014-05-27 20:04:08.000000000 -0500 +@@ -760,16 +760,16 @@ + __erfl (long double x) + { + long double a, y, z; +- int32_t i, ix, sign; +- ieee854_long_double_shape_type u; ++ int32_t i, ix, hx; ++ double xhi; + +- u.value = x; +- sign = u.parts32.w0; +- ix = sign & 0x7fffffff; ++ xhi = ldbl_high (x); ++ GET_HIGH_WORD (hx, xhi); ++ ix = hx & 0x7fffffff; + + if (ix >= 0x7ff00000) + { /* erf(nan)=nan */ +- i = ((sign & 0xfff00000) >> 31) << 1; ++ i = ((uint32_t) hx >> 31) << 1; + return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ + } + +@@ -778,7 +778,7 @@ + if (ix >= 0x4039A0DE) + { + /* __erfcl (x) underflows if x > 25.6283 */ +- if (sign) ++ if ((hx & 0x80000000) == 0) + return one-tiny; + else + return tiny-one; +@@ -789,8 +789,9 @@ + return (one - y); + } + } +- u.parts32.w0 = ix; +- a = u.value; ++ a = x; ++ if ((hx & 0x80000000) != 0) ++ a = -a; + z = x * x; + if (ix < 0x3fec0000) /* a < 0.875 */ + { +@@ -814,7 +815,7 @@ + y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2); + } + +- if (sign & 0x80000000) /* x < 0 */ ++ if (hx & 0x80000000) /* x < 0 */ + y = -y; + return( y ); + } +@@ -824,18 +825,18 @@ + __erfcl (long double x) + { + long double y, z, p, r; +- int32_t i, ix, sign; +- ieee854_long_double_shape_type u; +- +- u.value = x; +- sign = u.parts32.w0; +- ix = sign & 0x7fffffff; +- u.parts32.w0 = ix; ++ int32_t i, ix; ++ uint32_t hx; ++ double xhi; ++ ++ xhi = ldbl_high (x); ++ GET_HIGH_WORD (hx, xhi); ++ ix = hx & 0x7fffffff; + + if (ix >= 0x7ff00000) + { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ +- return (long double) (((u_int32_t) sign >> 31) << 1) + one / x; ++ return (long double) ((hx >> 31) << 1) + one / x; + } + + if (ix < 0x3fd00000) /* |x| <1/4 */ +@@ -846,7 +847,8 @@ + } + if (ix < 0x3ff40000) /* 1.25 */ + { +- x = u.value; ++ if ((hx & 0x80000000) != 0) ++ x = -x; + i = 8.0 * x; + switch (i) + { +@@ -891,7 +893,7 @@ + y += C20a; + break; + } +- if (sign & 0x80000000) ++ if (hx & 0x80000000) + y = 2.0L - y; + return y; + } +@@ -899,10 +901,11 @@ + if (ix < 0x405ac000) + { + /* x < -9 */ +- if ((ix >= 0x40220000) && (sign & 0x80000000)) ++ if (hx >= 0xc0220000) + return two - tiny; + +- x = fabsl (x); ++ if ((hx & 0x80000000) != 0) ++ x = -x; + z = one / (x * x); + i = 8.0 / x; + switch (i) +@@ -933,21 +936,17 @@ + p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8); + break; + } +- u.value = x; +- u.parts32.w3 = 0; +- u.parts32.w2 = 0; +- u.parts32.w1 &= 0xf8000000; +- z = u.value; ++ z = (float) x; + r = __ieee754_expl (-z * z - 0.5625) * + __ieee754_expl ((z - x) * (z + x) + p); +- if ((sign & 0x80000000) == 0) ++ if ((hx & 0x80000000) == 0) + return r / x; + else + return two - r / x; + } + else + { +- if ((sign & 0x80000000) == 0) ++ if ((hx & 0x80000000) == 0) + return tiny * tiny; + else + return two - tiny; diff --git a/SOURCES/glibc-ppc64le-10.patch b/SOURCES/glibc-ppc64le-10.patch new file mode 100644 index 00000000..ac82dd73 --- /dev/null +++ b/SOURCES/glibc-ppc64le-10.patch @@ -0,0 +1,91 @@ +# commit 32c301dfc9b786453e59b61fe4a821a89e1a206b +# Author: Alan Modra +# Date: Sat Aug 17 18:26:39 2013 +0930 +# +# PowerPC floating point little-endian [5 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00085.html +# +# Rid ourselves of ieee854. +# +# * sysdeps/ieee754/ldbl-128ibm/ieee754.h (union ieee854_long_double): +# Delete. +# (IEEE854_LONG_DOUBLE_BIAS): Delete. +# * sysdeps/ieee754/ldbl-128ibm/math_ldbl.h: Don't include ieee854 +# version of math_ldbl.h. +# +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h 2014-05-27 22:10:43.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/ieee754.h 2014-05-27 22:11:10.000000000 -0500 +@@ -112,61 +112,6 @@ + #define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ + + +-union ieee854_long_double +- { +- long double d; +- +- /* This is the IEEE 854 quad-precision format. */ +- struct +- { +-#if __BYTE_ORDER == __BIG_ENDIAN +- unsigned int negative:1; +- unsigned int exponent:15; +- /* Together these comprise the mantissa. */ +- unsigned int mantissa0:16; +- unsigned int mantissa1:32; +- unsigned int mantissa2:32; +- unsigned int mantissa3:32; +-#endif /* Big endian. */ +-#if __BYTE_ORDER == __LITTLE_ENDIAN +- /* Together these comprise the mantissa. */ +- unsigned int mantissa3:32; +- unsigned int mantissa2:32; +- unsigned int mantissa1:32; +- unsigned int mantissa0:16; +- unsigned int exponent:15; +- unsigned int negative:1; +-#endif /* Little endian. */ +- } ieee; +- +- /* This format makes it easier to see if a NaN is a signalling NaN. */ +- struct +- { +-#if __BYTE_ORDER == __BIG_ENDIAN +- unsigned int negative:1; +- unsigned int exponent:15; +- unsigned int quiet_nan:1; +- /* Together these comprise the mantissa. */ +- unsigned int mantissa0:15; +- unsigned int mantissa1:32; +- unsigned int mantissa2:32; +- unsigned int mantissa3:32; +-#else +- /* Together these comprise the mantissa. */ +- unsigned int mantissa3:32; +- unsigned int mantissa2:32; +- unsigned int mantissa1:32; +- unsigned int mantissa0:15; +- unsigned int quiet_nan:1; +- unsigned int exponent:15; +- unsigned int negative:1; +-#endif +- } ieee_nan; +- }; +- +-#define IEEE854_LONG_DOUBLE_BIAS 0x3fff /* Added to exponent. */ +- +- + /* IBM extended format for long double. + + Each long double is made up of two IEEE doubles. The value of the +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 22:10:43.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h 2014-05-27 22:11:10.000000000 -0500 +@@ -2,7 +2,6 @@ + #error "Never use directly; include instead." + #endif + +-#include + #include + + static inline void diff --git a/SOURCES/glibc-ppc64le-11.patch b/SOURCES/glibc-ppc64le-11.patch new file mode 100644 index 00000000..ae68a41f --- /dev/null +++ b/SOURCES/glibc-ppc64le-11.patch @@ -0,0 +1,113 @@ +# commit 62a728aeff93507ce5975f245a5f1d2046fb4503 +# Author: Alan Modra +# Date: Sat Aug 17 18:27:19 2013 +0930 +# +# PowerPC floating point little-endian [6 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00197.html +# +# A rewrite to make this code correct for little-endian. +# +# * sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c (mynumber): Replace +# union 32-bit int array member with 64-bit int array. +# (t515, tm256): Double rather than long double. +# (__ieee754_sqrtl): Rewrite using 64-bit arithmetic. +# +diff -urN glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c 2014-05-27 22:20:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_sqrtl.c 2014-05-27 22:21:39.000000000 -0500 +@@ -34,15 +34,13 @@ + + #include + +-typedef unsigned int int4; +-typedef union {int4 i[4]; long double x; double d[2]; } mynumber; ++typedef union {int64_t i[2]; long double x; double d[2]; } mynumber; + +-static const mynumber +- t512 = {{0x5ff00000, 0x00000000, 0x00000000, 0x00000000 }}, /* 2^512 */ +- tm256 = {{0x2ff00000, 0x00000000, 0x00000000, 0x00000000 }}; /* 2^-256 */ + static const double +-two54 = 1.80143985094819840000e+16, /* 0x4350000000000000 */ +-twom54 = 5.55111512312578270212e-17; /* 0x3C90000000000000 */ ++ t512 = 0x1p512, ++ tm256 = 0x1p-256, ++ two54 = 0x1p54, /* 0x4350000000000000 */ ++ twom54 = 0x1p-54; /* 0x3C90000000000000 */ + + /*********************************************************************/ + /* An ultimate sqrt routine. Given an IEEE double machine number x */ +@@ -54,56 +52,53 @@ + static const long double big = 134217728.0, big1 = 134217729.0; + long double t,s,i; + mynumber a,c; +- int4 k, l, m; +- int n; ++ uint64_t k, l; ++ int64_t m, n; + double d; + + a.x=x; +- k=a.i[0] & 0x7fffffff; ++ k=a.i[0] & INT64_C(0x7fffffffffffffff); + /*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/ +- if (k>0x000fffff && k<0x7ff00000) { ++ if (k>INT64_C(0x000fffff00000000) && k> 21; +- m = (a.i[2] >> 20) & 0x7ff; ++ l = (k&INT64_C(0x001fffffffffffff))|INT64_C(0x3fe0000000000000); ++ if ((a.i[1] & INT64_C(0x7fffffffffffffff)) != 0) { ++ n = (int64_t) ((l - k) * 2) >> 53; ++ m = (a.i[1] >> 52) & 0x7ff; + if (m == 0) { + a.d[1] *= two54; +- m = ((a.i[2] >> 20) & 0x7ff) - 54; ++ m = ((a.i[1] >> 52) & 0x7ff) - 54; + } + m += n; +- if ((int) m > 0) +- a.i[2] = (a.i[2] & 0x800fffff) | (m << 20); +- else if ((int) m <= -54) { +- a.i[2] &= 0x80000000; +- a.i[3] = 0; ++ if (m > 0) ++ a.i[1] = (a.i[1] & INT64_C(0x800fffffffffffff)) | (m << 52); ++ else if (m <= -54) { ++ a.i[1] &= INT64_C(0x8000000000000000); + } else { + m += 54; +- a.i[2] = (a.i[2] & 0x800fffff) | (m << 20); ++ a.i[1] = (a.i[1] & INT64_C(0x800fffffffffffff)) | (m << 52); + a.d[1] *= twom54; + } + } + a.i[0] = l; + s = a.x; + d = __ieee754_sqrt (a.d[0]); +- c.i[0] = 0x20000000+((k&0x7fe00000)>>1); ++ c.i[0] = INT64_C(0x2000000000000000)+((k&INT64_C(0x7fe0000000000000))>>1); + c.i[1] = 0; +- c.i[2] = 0; +- c.i[3] = 0; + i = d; + t = 0.5L * (i + s / i); + i = 0.5L * (t + s / t); + return c.x * i; + } + else { +- if (k>=0x7ff00000) { +- if (a.i[0] == 0xfff00000 && a.i[1] == 0) ++ if (k>=INT64_C(0x7ff0000000000000)) { ++ if (a.i[0] == INT64_C(0xfff0000000000000)) + return (big1-big1)/(big-big); /* sqrt (-Inf) = NaN. */ + return x; /* sqrt (NaN) = NaN, sqrt (+Inf) = +Inf. */ + } + if (x == 0) return x; + if (x < 0) return (big1-big1)/(big-big); +- return tm256.x*__ieee754_sqrtl(x*t512.x); ++ return tm256*__ieee754_sqrtl(x*t512); + } + } + strong_alias (__ieee754_sqrtl, __sqrtl_finite) diff --git a/SOURCES/glibc-ppc64le-12.patch b/SOURCES/glibc-ppc64le-12.patch new file mode 100644 index 00000000..89e38066 --- /dev/null +++ b/SOURCES/glibc-ppc64le-12.patch @@ -0,0 +1,74 @@ +# commit 2ca85d2bbbaa60b9c83bf1f57a2801c84e0a3625 +# Author: Anton Blanchard +# Date: Sat Aug 17 18:28:06 2013 +0930 +# +# PowerPC floating point little-endian [7 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00086.html +# +# * sysdeps/powerpc/bits/mathinline.h (__signbitf): Use builtin. +# (__signbit): Likewise. Correct for little-endian. +# (__signbitl): Call __signbit. +# (lrint): Correct for little-endian. +# (lrintf): Call lrint. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/bits/mathinline.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/bits/mathinline.h +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/bits/mathinline.h 2014-05-27 22:28:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/bits/mathinline.h 2014-05-27 22:28:37.000000000 -0500 +@@ -62,21 +62,28 @@ + __MATH_INLINE int + __NTH (__signbitf (float __x)) + { ++#if __GNUC_PREREQ (4, 0) ++ return __builtin_signbitf (__x); ++#else + __extension__ union { float __f; int __i; } __u = { __f: __x }; + return __u.__i < 0; ++#endif + } + __MATH_INLINE int + __NTH (__signbit (double __x)) + { +- __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; +- return __u.__i[0] < 0; ++#if __GNUC_PREREQ (4, 0) ++ return __builtin_signbit (__x); ++#else ++ __extension__ union { double __d; long long __i; } __u = { __d: __x }; ++ return __u.__i < 0; ++#endif + } + # ifdef __LONG_DOUBLE_128__ + __MATH_INLINE int + __NTH (__signbitl (long double __x)) + { +- __extension__ union { long double __d; int __i[4]; } __u = { __d: __x }; +- return __u.__i[0] < 0; ++ return __signbit ((double) __x); + } + # endif + # endif +@@ -93,22 +100,17 @@ + { + union { + double __d; +- int __ll[2]; ++ long long __ll; + } __u; + __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x)); +- return __u.__ll[1]; ++ return __u.__ll; + } + + __MATH_INLINE long int lrintf (float __x) __THROW; + __MATH_INLINE long int + __NTH (lrintf (float __x)) + { +- union { +- double __d; +- int __ll[2]; +- } __u; +- __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x)); +- return __u.__ll[1]; ++ return lrint ((double) __x); + } + # endif diff --git a/SOURCES/glibc-ppc64le-13.patch b/SOURCES/glibc-ppc64le-13.patch new file mode 100644 index 00000000..1cc101f2 --- /dev/null +++ b/SOURCES/glibc-ppc64le-13.patch @@ -0,0 +1,283 @@ +# commit 4a28b3ca4bc52d9a3ac0d9edb53d3de510e1b77c +# Author: Anton Blanchard +# Date: Sat Aug 17 18:28:55 2013 +0930 +# +# PowerPC floating point little-endian [8 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00199.html +# +# Corrects floating-point environment code for little-endian. +# +# * sysdeps/powerpc/fpu/fenv_libc.h (fenv_union_t): Replace int +# array with long long. +# * sysdeps/powerpc/fpu/e_sqrt.c (__slow_ieee754_sqrt): Adjust. +# * sysdeps/powerpc/fpu/e_sqrtf.c (__slow_ieee754_sqrtf): Adjust. +# * sysdeps/powerpc/fpu/fclrexcpt.c (__feclearexcept): Adjust. +# * sysdeps/powerpc/fpu/fedisblxcpt.c (fedisableexcept): Adjust. +# * sysdeps/powerpc/fpu/feenablxcpt.c (feenableexcept): Adjust. +# * sysdeps/powerpc/fpu/fegetexcept.c (__fegetexcept): Adjust. +# * sysdeps/powerpc/fpu/feholdexcpt.c (feholdexcept): Adjust. +# * sysdeps/powerpc/fpu/fesetenv.c (__fesetenv): Adjust. +# * sysdeps/powerpc/fpu/feupdateenv.c (__feupdateenv): Adjust. +# * sysdeps/powerpc/fpu/fgetexcptflg.c (__fegetexceptflag): Adjust. +# * sysdeps/powerpc/fpu/fraiseexcpt.c (__feraiseexcept): Adjust. +# * sysdeps/powerpc/fpu/fsetexcptflg.c (__fesetexceptflag): Adjust. +# * sysdeps/powerpc/fpu/ftestexcept.c (fetestexcept): Adjust. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrt.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrt.c 2014-05-27 22:31:43.000000000 -0500 +@@ -145,7 +145,7 @@ + feraiseexcept (FE_INVALID_SQRT); + + fenv_union_t u = { .fenv = fegetenv_register () }; +- if ((u.l[1] & FE_INVALID) == 0) ++ if ((u.l & FE_INVALID) == 0) + #endif + feraiseexcept (FE_INVALID); + x = a_nan.value; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrtf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrtf.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrtf.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_sqrtf.c 2014-05-27 22:31:43.000000000 -0500 +@@ -121,7 +121,7 @@ + feraiseexcept (FE_INVALID_SQRT); + + fenv_union_t u = { .fenv = fegetenv_register () }; +- if ((u.l[1] & FE_INVALID) == 0) ++ if ((u.l & FE_INVALID) == 0) + #endif + feraiseexcept (FE_INVALID); + x = a_nan.value; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fclrexcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fclrexcpt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fclrexcpt.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fclrexcpt.c 2014-05-27 22:31:43.000000000 -0500 +@@ -28,8 +28,8 @@ + u.fenv = fegetenv_register (); + + /* Clear the relevant bits. */ +- u.l[1] = u.l[1] & ~((-(excepts >> (31 - FPSCR_VX) & 1) & FE_ALL_INVALID) +- | (excepts & FPSCR_STICKY_BITS)); ++ u.l = u.l & ~((-(excepts >> (31 - FPSCR_VX) & 1) & FE_ALL_INVALID) ++ | (excepts & FPSCR_STICKY_BITS)); + + /* Put the new state in effect. */ + fesetenv_register (u.fenv); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fedisblxcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fedisblxcpt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fedisblxcpt.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fedisblxcpt.c 2014-05-27 22:31:43.000000000 -0500 +@@ -32,15 +32,15 @@ + + fe.fenv = fegetenv_register (); + if (excepts & FE_INEXACT) +- fe.l[1] &= ~(1 << (31 - FPSCR_XE)); ++ fe.l &= ~(1 << (31 - FPSCR_XE)); + if (excepts & FE_DIVBYZERO) +- fe.l[1] &= ~(1 << (31 - FPSCR_ZE)); ++ fe.l &= ~(1 << (31 - FPSCR_ZE)); + if (excepts & FE_UNDERFLOW) +- fe.l[1] &= ~(1 << (31 - FPSCR_UE)); ++ fe.l &= ~(1 << (31 - FPSCR_UE)); + if (excepts & FE_OVERFLOW) +- fe.l[1] &= ~(1 << (31 - FPSCR_OE)); ++ fe.l &= ~(1 << (31 - FPSCR_OE)); + if (excepts & FE_INVALID) +- fe.l[1] &= ~(1 << (31 - FPSCR_VE)); ++ fe.l &= ~(1 << (31 - FPSCR_VE)); + fesetenv_register (fe.fenv); + + new = __fegetexcept (); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/feenablxcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/feenablxcpt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/feenablxcpt.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/feenablxcpt.c 2014-05-27 22:31:43.000000000 -0500 +@@ -32,15 +32,15 @@ + + fe.fenv = fegetenv_register (); + if (excepts & FE_INEXACT) +- fe.l[1] |= (1 << (31 - FPSCR_XE)); ++ fe.l |= (1 << (31 - FPSCR_XE)); + if (excepts & FE_DIVBYZERO) +- fe.l[1] |= (1 << (31 - FPSCR_ZE)); ++ fe.l |= (1 << (31 - FPSCR_ZE)); + if (excepts & FE_UNDERFLOW) +- fe.l[1] |= (1 << (31 - FPSCR_UE)); ++ fe.l |= (1 << (31 - FPSCR_UE)); + if (excepts & FE_OVERFLOW) +- fe.l[1] |= (1 << (31 - FPSCR_OE)); ++ fe.l |= (1 << (31 - FPSCR_OE)); + if (excepts & FE_INVALID) +- fe.l[1] |= (1 << (31 - FPSCR_VE)); ++ fe.l |= (1 << (31 - FPSCR_VE)); + fesetenv_register (fe.fenv); + + new = __fegetexcept (); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fegetexcept.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fegetexcept.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fegetexcept.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fegetexcept.c 2014-05-27 22:31:43.000000000 -0500 +@@ -27,15 +27,15 @@ + + fe.fenv = fegetenv_register (); + +- if (fe.l[1] & (1 << (31 - FPSCR_XE))) ++ if (fe.l & (1 << (31 - FPSCR_XE))) + result |= FE_INEXACT; +- if (fe.l[1] & (1 << (31 - FPSCR_ZE))) ++ if (fe.l & (1 << (31 - FPSCR_ZE))) + result |= FE_DIVBYZERO; +- if (fe.l[1] & (1 << (31 - FPSCR_UE))) ++ if (fe.l & (1 << (31 - FPSCR_UE))) + result |= FE_UNDERFLOW; +- if (fe.l[1] & (1 << (31 - FPSCR_OE))) ++ if (fe.l & (1 << (31 - FPSCR_OE))) + result |= FE_OVERFLOW; +- if (fe.l[1] & (1 << (31 - FPSCR_VE))) ++ if (fe.l & (1 << (31 - FPSCR_VE))) + result |= FE_INVALID; + + return result; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/feholdexcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/feholdexcpt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/feholdexcpt.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/feholdexcpt.c 2014-05-27 22:33:09.000000000 -0500 +@@ -30,13 +30,12 @@ + + /* Clear everything except for the rounding modes and non-IEEE arithmetic + flag. */ +- new.l[1] = old.l[1] & 7; +- new.l[0] = old.l[0]; ++ new.l = old.l & 0xffffffff00000007LL; + + /* If the old env had any eabled exceptions, then mask SIGFPE in the + MSR FE0/FE1 bits. This may allow the FPU to run faster because it + always takes the default action and can not generate SIGFPE. */ +- if ((old.l[1] & _FPU_MASK_ALL) != 0) ++ if ((old.l & _FPU_MASK_ALL) != 0) + (void)__fe_mask_env (); + + /* Put the new state in effect. */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fenv_libc.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/fenv_libc.h +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fenv_libc.h 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fenv_libc.h 2014-05-27 22:31:43.000000000 -0500 +@@ -69,7 +69,7 @@ + typedef union + { + fenv_t fenv; +- unsigned int l[2]; ++ unsigned long long l; + } fenv_union_t; + + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fesetenv.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fesetenv.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fesetenv.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fesetenv.c 2014-05-27 22:35:18.000000000 -0500 +@@ -36,14 +36,14 @@ + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put the + hardware into "precise mode" and may cause the FPU to run slower on some + hardware. */ +- if ((old.l[1] & _FPU_MASK_ALL) == 0 && (new.l[1] & _FPU_MASK_ALL) != 0) ++ if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void)__fe_nomask_env (); + + /* If the old env had any enabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ +- if ((old.l[1] & _FPU_MASK_ALL) != 0 && (new.l[1] & _FPU_MASK_ALL) == 0) ++ if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void)__fe_mask_env (); + + fesetenv_register (*envp); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/feupdateenv.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/feupdateenv.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/feupdateenv.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/feupdateenv.c 2014-05-27 22:34:23.000000000 -0500 +@@ -36,20 +36,20 @@ + /* Restore rounding mode and exception enable from *envp and merge + exceptions. Leave fraction rounded/inexact and FP result/CC bits + unchanged. */ +- new.l[1] = (old.l[1] & 0x1FFFFF00) | (new.l[1] & 0x1FF80FFF); ++ new.l = (old.l & 0xffffffff1fffff00LL) | (new.l & 0x1ff80fff); + + /* If the old env has no eabled exceptions and the new env has any enabled + exceptions, then unmask SIGFPE in the MSR FE0/FE1 bits. This will put + the hardware into "precise mode" and may cause the FPU to run slower on + some hardware. */ +- if ((old.l[1] & _FPU_MASK_ALL) == 0 && (new.l[1] & _FPU_MASK_ALL) != 0) ++ if ((old.l & _FPU_MASK_ALL) == 0 && (new.l & _FPU_MASK_ALL) != 0) + (void)__fe_nomask_env (); + + /* If the old env had any eabled exceptions and the new env has no enabled + exceptions, then mask SIGFPE in the MSR FE0/FE1 bits. This may allow the + FPU to run faster because it always takes the default action and can not + generate SIGFPE. */ +- if ((old.l[1] & _FPU_MASK_ALL) != 0 && (new.l[1] & _FPU_MASK_ALL) == 0) ++ if ((old.l & _FPU_MASK_ALL) != 0 && (new.l & _FPU_MASK_ALL) == 0) + (void)__fe_mask_env (); + + /* Atomically enable and raise (if appropriate) exceptions set in `new'. */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fgetexcptflg.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fgetexcptflg.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fgetexcptflg.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fgetexcptflg.c 2014-05-27 22:31:43.000000000 -0500 +@@ -28,7 +28,7 @@ + u.fenv = fegetenv_register (); + + /* Return (all of) it. */ +- *flagp = u.l[1] & excepts & FE_ALL_EXCEPT; ++ *flagp = u.l & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fraiseexcpt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fraiseexcpt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fraiseexcpt.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fraiseexcpt.c 2014-05-27 22:31:43.000000000 -0500 +@@ -34,11 +34,11 @@ + u.fenv = fegetenv_register (); + + /* Add the exceptions */ +- u.l[1] = (u.l[1] +- | (excepts & FPSCR_STICKY_BITS) +- /* Turn FE_INVALID into FE_INVALID_SOFTWARE. */ +- | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) +- & FE_INVALID_SOFTWARE)); ++ u.l = (u.l ++ | (excepts & FPSCR_STICKY_BITS) ++ /* Turn FE_INVALID into FE_INVALID_SOFTWARE. */ ++ | (excepts >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) ++ & FE_INVALID_SOFTWARE)); + + /* Store the new status word (along with the rest of the environment), + triggering any appropriate exceptions. */ +@@ -50,7 +50,7 @@ + don't have FE_INVALID_SOFTWARE implemented. Detect this + case and raise FE_INVALID_SNAN instead. */ + u.fenv = fegetenv_register (); +- if ((u.l[1] & FE_INVALID) == 0) ++ if ((u.l & FE_INVALID) == 0) + set_fpscr_bit (FPSCR_VXSNAN); + } + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fsetexcptflg.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/fsetexcptflg.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fsetexcptflg.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fsetexcptflg.c 2014-05-27 22:31:43.000000000 -0500 +@@ -32,10 +32,10 @@ + flag = *flagp & excepts; + + /* Replace the exception status */ +- u.l[1] = ((u.l[1] & ~(FPSCR_STICKY_BITS & excepts)) +- | (flag & FPSCR_STICKY_BITS) +- | (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) +- & FE_INVALID_SOFTWARE)); ++ u.l = ((u.l & ~(FPSCR_STICKY_BITS & excepts)) ++ | (flag & FPSCR_STICKY_BITS) ++ | (flag >> ((31 - FPSCR_VX) - (31 - FPSCR_VXSOFT)) ++ & FE_INVALID_SOFTWARE)); + + /* Store the new status word (along with the rest of the environment). + This may cause floating-point exceptions if the restored state +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/ftestexcept.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/ftestexcept.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/ftestexcept.c 2014-05-27 22:31:42.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/ftestexcept.c 2014-05-27 22:31:43.000000000 -0500 +@@ -28,6 +28,6 @@ + + /* The FE_INVALID bit is dealt with correctly by the hardware, so we can + just: */ +- return u.l[1] & excepts; ++ return u.l & excepts; + } + libm_hidden_def (fetestexcept) diff --git a/SOURCES/glibc-ppc64le-14.patch b/SOURCES/glibc-ppc64le-14.patch new file mode 100644 index 00000000..843ec216 --- /dev/null +++ b/SOURCES/glibc-ppc64le-14.patch @@ -0,0 +1,120 @@ +# commit 603e84104cdc709c8e7dcbac54b9a585bf8dff78 +# Author: Alan Modra +# Date: Sat Aug 17 18:29:43 2013 +0930 +# +# PowerPC floating point little-endian [9 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00200.html +# +# This works around the fact that vsx is disabled in current +# little-endian gcc. Also, float constants take 4 bytes in memory +# vs. 16 bytes for vector constants, and we don't need to write one lot +# of masks for double (register format) and another for float (mem +# format). +# +# * sysdeps/powerpc/fpu/s_float_bitwise.h (__float_and_test28): Don't +# use vector int constants. +# (__float_and_test24, __float_and8, __float_get_exp): Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_float_bitwise.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_float_bitwise.h +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_float_bitwise.h 2014-05-27 22:37:18.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_float_bitwise.h 2014-05-27 22:37:20.000000000 -0500 +@@ -23,18 +23,19 @@ + #include + + /* Returns (int)(num & 0x7FFFFFF0 == value) */ +-static inline +-int __float_and_test28 (float num, float value) ++static inline int ++__float_and_test28 (float num, float value) + { + float ret; + #ifdef _ARCH_PWR7 +- vector int mask = (vector int) { +- 0x7ffffffe, 0x00000000, 0x00000000, 0x0000000 +- }; ++ union { ++ int i; ++ float f; ++ } mask = { .i = 0x7ffffff0 }; + __asm__ ( +- /* the 'f' constrain is use on mask because we just need ++ /* the 'f' constraint is used on mask because we just need + * to compare floats, not full vector */ +- "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask) ++ "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); + #else + int32_t inum; +@@ -46,16 +47,17 @@ + } + + /* Returns (int)(num & 0x7FFFFF00 == value) */ +-static inline +-int __float_and_test24 (float num, float value) ++static inline int ++__float_and_test24 (float num, float value) + { + float ret; + #ifdef _ARCH_PWR7 +- vector int mask = (vector int) { +- 0x7fffffe0, 0x00000000, 0x00000000, 0x0000000 +- }; ++ union { ++ int i; ++ float f; ++ } mask = { .i = 0x7fffff00 }; + __asm__ ( +- "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask) ++ "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); + #else + int32_t inum; +@@ -67,16 +69,17 @@ + } + + /* Returns (float)(num & 0x7F800000) */ +-static inline +-float __float_and8 (float num) ++static inline float ++__float_and8 (float num) + { + float ret; + #ifdef _ARCH_PWR7 +- vector int mask = (vector int) { +- 0x7ff00000, 0x00000000, 0x00000000, 0x00000000 +- }; ++ union { ++ int i; ++ float f; ++ } mask = { .i = 0x7f800000 }; + __asm__ ( +- "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask) ++ "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); + #else + int32_t inum; +@@ -88,17 +91,18 @@ + } + + /* Returns ((int32_t)(num & 0x7F800000) >> 23) */ +-static inline +-int32_t __float_get_exp (float num) ++static inline int32_t ++__float_get_exp (float num) + { + int32_t inum; + #ifdef _ARCH_PWR7 + float ret; +- vector int mask = (vector int) { +- 0x7ff00000, 0x00000000, 0x00000000, 0x00000000 +- }; ++ union { ++ int i; ++ float f; ++ } mask = { .i = 0x7f800000 }; + __asm__ ( +- "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask) ++ "xxland %x0,%x1,%x2" : "=f" (ret) : "f" (num), "f" (mask.f) + ); + GET_FLOAT_WORD(inum, ret); + #else diff --git a/SOURCES/glibc-ppc64le-15.patch b/SOURCES/glibc-ppc64le-15.patch new file mode 100644 index 00000000..fbf68d02 --- /dev/null +++ b/SOURCES/glibc-ppc64le-15.patch @@ -0,0 +1,119 @@ +# commit da13146da10360436941e843834c90a9aef5fd7a +# Author: Alan Modra +# Date: Sat Aug 17 18:30:23 2013 +0930 +# +# PowerPC floating point little-endian [10 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00201.html +# +# These two functions oddly test x+1>0 when a double x is >= 0.0, and +# similarly when x is negative. I don't see the point of that since the +# test should always be true. I also don't see any need to convert x+1 +# to integer rather than simply using xr+1. Note that the standard +# allows these functions to return any value when the input is outside +# the range of long long, but it's not too hard to prevent xr+1 +# overflowing so that's what I've done. +# +# (With rounding mode FE_UPWARD, x+1 can be a lot more than what you +# might naively expect, but perhaps that situation was covered by the +# x - xrf < 1.0 test.) +# +# * sysdeps/powerpc/fpu/s_llround.c (__llround): Rewrite. +# * sysdeps/powerpc/fpu/s_llroundf.c (__llroundf): Rewrite. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:55.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2014-05-27 22:38:58.000000000 -0500 +@@ -19,29 +19,28 @@ + #include + #include + +-/* I think that what this routine is supposed to do is round a value +- to the nearest integer, with values exactly on the boundary rounded +- away from zero. */ +-/* This routine relies on (long long)x, when x is out of range of a long long, +- clipping to MAX_LLONG or MIN_LLONG. */ ++/* Round to the nearest integer, with values exactly on a 0.5 boundary ++ rounded away from zero, regardless of the current rounding mode. ++ If (long long)x, when x is out of range of a long long, clips at ++ LLONG_MAX or LLONG_MIN, then this implementation also clips. */ + + long long int + __llround (double x) + { +- double xrf; +- long long int xr; +- xr = (long long int) x; +- xrf = (double) xr; ++ long long xr = (long long) x; ++ double xrf = (double) xr; ++ + if (x >= 0.0) +- if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0) +- return x+1; +- else +- return x; ++ { ++ if (x - xrf >= 0.5) ++ xr += (long long) ((unsigned long long) xr + 1) > 0; ++ } + else +- if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0) +- return x-1; +- else +- return x; ++ { ++ if (xrf - x >= 0.5) ++ xr -= (long long) ((unsigned long long) xr - 1) < 0; ++ } ++ return xr; + } + weak_alias (__llround, llround) + #ifdef NO_LONG_DOUBLE +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:55.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llroundf.c 2014-05-27 22:38:58.000000000 -0500 +@@ -18,28 +18,27 @@ + + #include + +-/* I think that what this routine is supposed to do is round a value +- to the nearest integer, with values exactly on the boundary rounded +- away from zero. */ +-/* This routine relies on (long long)x, when x is out of range of a long long, +- clipping to MAX_LLONG or MIN_LLONG. */ ++/* Round to the nearest integer, with values exactly on a 0.5 boundary ++ rounded away from zero, regardless of the current rounding mode. ++ If (long long)x, when x is out of range of a long long, clips at ++ LLONG_MAX or LLONG_MIN, then this implementation also clips. */ + + long long int + __llroundf (float x) + { +- float xrf; +- long long int xr; +- xr = (long long int) x; +- xrf = (float) xr; ++ long long xr = (long long) x; ++ float xrf = (float) xr; ++ + if (x >= 0.0) +- if (x - xrf >= 0.5 && x - xrf < 1.0 && x+1 > 0) +- return x+1; +- else +- return x; ++ { ++ if (x - xrf >= 0.5) ++ xr += (long long) ((unsigned long long) xr + 1) > 0; ++ } + else +- if (xrf - x >= 0.5 && xrf - x < 1.0 && x-1 < 0) +- return x-1; +- else +- return x; ++ { ++ if (xrf - x >= 0.5) ++ xr -= (long long) ((unsigned long long) xr - 1) < 0; ++ } ++ return xr; + } + weak_alias (__llroundf, llroundf) diff --git a/SOURCES/glibc-ppc64le-16.patch b/SOURCES/glibc-ppc64le-16.patch new file mode 100644 index 00000000..24918f66 --- /dev/null +++ b/SOURCES/glibc-ppc64le-16.patch @@ -0,0 +1,163 @@ +# commit 9c008155b7d5d1bd81d909497850a2ece28aec50 +# Author: Alan Modra +# Date: Sat Aug 17 18:31:05 2013 +0930 +# +# PowerPC floating point little-endian [11 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00202.html +# +# Another little-endian fix. +# +# * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Rewrite using +# 64-bit int/double union. +# (_FPU_SETCW): Likewise. +# * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise. +# (_SET_DI_FPSCR, _GET_SI_FPSCR, _SET_SI_FPSCR): Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h 2014-05-27 22:40:18.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/fpu_control.h 2014-05-27 22:43:40.000000000 -0500 +@@ -45,22 +45,26 @@ + #define _FPU_IEEE 0x000000f0 + + /* Type of the control word. */ +-typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); ++typedef unsigned int fpu_control_t; + + /* Macros for accessing the hardware control word. */ +-#define _FPU_GETCW(__cw) ( { \ +- union { double d; fpu_control_t cw[2]; } \ +- tmp __attribute__ ((__aligned__(8))); \ +- __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ +- (__cw)=tmp.cw[1]; \ +- tmp.cw[1]; } ) +-#define _FPU_SETCW(__cw) { \ +- union { double d; fpu_control_t cw[2]; } \ +- tmp __attribute__ ((__aligned__(8))); \ +- tmp.cw[0] = 0xFFF80000; /* More-or-less arbitrary; this is a QNaN. */ \ +- tmp.cw[1] = __cw; \ +- __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \ +-} ++#define _FPU_GETCW(cw) \ ++ ({union { double __d; unsigned long long __ll; } __u; \ ++ register double __fr; \ ++ __asm__ ("mffs %0" : "=f" (__fr)); \ ++ __u.__d = __fr; \ ++ (cw) = (fpu_control_t) __u.__ll; \ ++ (fpu_control_t) __u.__ll; \ ++ }) ++ ++#define _FPU_SETCW(cw) \ ++ { union { double __d; unsigned long long __ll; } __u; \ ++ register double __fr; \ ++ __u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \ ++ __u.__ll |= (cw) & 0xffffffffLL; \ ++ __fr = __u.__d; \ ++ __asm__ ("mtfsf 255,%0" : : "f" (__fr)); \ ++ } + + /* Default control word set at startup. */ + extern fpu_control_t __fpu_control; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c 2014-05-27 22:40:18.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c 2014-05-27 22:40:21.000000000 -0500 +@@ -83,7 +83,7 @@ + return 0; + } + +-typedef unsigned long long di_fpscr_t __attribute__ ((__mode__ (__DI__))); ++typedef unsigned int di_fpscr_t __attribute__ ((__mode__ (__DI__))); + typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__))); + + #define _FPSCR_RESERVED 0xfffffff8ffffff04ULL +@@ -95,50 +95,51 @@ + #define _FPSCR_TEST1_RN 0x0000000000000002ULL + + /* Macros for accessing the hardware control word on Power6[x]. */ +-# define _GET_DI_FPSCR(__fpscr) ({ \ +- union { double d; \ +- di_fpscr_t fpscr; } \ +- tmp __attribute__ ((__aligned__(8))); \ +- __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ +- (__fpscr)=tmp.fpscr; \ +- tmp.fpscr; }) ++#define _GET_DI_FPSCR(__fpscr) \ ++ ({union { double d; di_fpscr_t fpscr; } u; \ ++ register double fr; \ ++ __asm__ ("mffs %0" : "=f" (fr)); \ ++ u.d = fr; \ ++ (__fpscr) = u.fpscr; \ ++ u.fpscr; \ ++ }) + +-/* We make sure to zero fp0 after we use it in order to prevent stale data ++/* We make sure to zero fp after we use it in order to prevent stale data + in an fp register from making a test-case pass erroneously. */ +-# define _SET_DI_FPSCR(__fpscr) { \ +- union { double d; di_fpscr_t fpscr; } \ +- tmp __attribute__ ((__aligned__(8))); \ +- tmp.fpscr = __fpscr; \ +- /* Set the entire 64-bit FPSCR. */ \ +- __asm__ ("lfd%U0 0,%0; " \ +- ".machine push; " \ +- ".machine \"power6\"; " \ +- "mtfsf 255,0,1,0; " \ +- ".machine pop" : : "m" (tmp.d) : "fr0"); \ +- tmp.d = 0; \ +- __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0"); \ +-} +- +-# define _GET_SI_FPSCR(__fpscr) ({ \ +- union { double d; \ +- si_fpscr_t cw[2]; } \ +- tmp __attribute__ ((__aligned__(8))); \ +- __asm__ ("mffs 0; stfd%U0 0,%0" : "=m" (tmp.d) : : "fr0"); \ +- (__fpscr)=tmp.cw[1]; \ +- tmp.cw[0]; }) ++# define _SET_DI_FPSCR(__fpscr) \ ++ { union { double d; di_fpscr_t fpscr; } u; \ ++ register double fr; \ ++ u.fpscr = __fpscr; \ ++ fr = u.d; \ ++ /* Set the entire 64-bit FPSCR. */ \ ++ __asm__ (".machine push; " \ ++ ".machine \"power6\"; " \ ++ "mtfsf 255,%0,1,0; " \ ++ ".machine pop" : : "f" (fr)); \ ++ fr = 0.0; \ ++ } ++ ++# define _GET_SI_FPSCR(__fpscr) \ ++ ({union { double d; di_fpscr_t fpscr; } u; \ ++ register double fr; \ ++ __asm__ ("mffs %0" : "=f" (fr)); \ ++ u.d = fr; \ ++ (__fpscr) = (si_fpscr_t) u.fpscr; \ ++ (si_fpscr_t) u.fpscr; \ ++ }) + +-/* We make sure to zero fp0 after we use it in order to prevent stale data ++/* We make sure to zero fp after we use it in order to prevent stale data + in an fp register from making a test-case pass erroneously. */ +-# define _SET_SI_FPSCR(__fpscr) { \ +- union { double d; si_fpscr_t fpscr[2]; } \ +- tmp __attribute__ ((__aligned__(8))); \ +- /* More-or-less arbitrary; this is a QNaN. */ \ +- tmp.fpscr[0] = 0xFFF80000; \ +- tmp.fpscr[1] = __fpscr; \ +- __asm__ ("lfd%U0 0,%0; mtfsf 255,0" : : "m" (tmp.d) : "fr0"); \ +- tmp.d = 0; \ +- __asm__("lfd%U0 0,%0" : : "m" (tmp.d) : "fr0"); \ +-} ++# define _SET_SI_FPSCR(__fpscr) \ ++ { union { double d; di_fpscr_t fpscr; } u; \ ++ register double fr; \ ++ /* More-or-less arbitrary; this is a QNaN. */ \ ++ u.fpscr = 0xfff80000ULL << 32; \ ++ u.fpscr |= __fpscr & 0xffffffffULL; \ ++ fr = u.d; \ ++ __asm__ ("mtfsf 255,%0" : : "f" (fr)); \ ++ fr = 0.0; \ ++ } + + void prime_special_regs(int which) + { diff --git a/SOURCES/glibc-ppc64le-17.patch b/SOURCES/glibc-ppc64le-17.patch new file mode 100644 index 00000000..a42eab07 --- /dev/null +++ b/SOURCES/glibc-ppc64le-17.patch @@ -0,0 +1,312 @@ +# commit 7b88401f3b25325b1381798a0eccb3efe7751fec +# Author: Alan Modra +# Date: Sat Aug 17 18:31:45 2013 +0930 +# +# PowerPC floating point little-endian [12 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00087.html +# +# Fixes for little-endian in 32-bit assembly. +# +# * sysdeps/powerpc/sysdep.h (LOWORD, HIWORD, HISHORT): Define. +# * sysdeps/powerpc/powerpc32/fpu/s_copysign.S: Load little-endian +# words of double from correct stack offsets. +# * sysdeps/powerpc/powerpc32/fpu/s_copysignl.S: Likewise. +# * sysdeps/powerpc/powerpc32/fpu/s_lrint.S: Likewise. +# * sysdeps/powerpc/powerpc32/fpu/s_lround.S: Likewise. +# * sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S: Likewise. +# * sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S: Likewise. +# * sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S: Likewise. +# * sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S: Likewise. +# * sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S: Likewise. +# * sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S: Likewise. +# * sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S: Likewise. +# * sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S: Likewise. +# * sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S: Use HISHORT. +# * sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S 2014-05-27 22:45:46.000000000 -0500 +@@ -29,7 +29,7 @@ + stwu r1,-16(r1) + cfi_adjust_cfa_offset (16) + stfd fp2,8(r1) +- lwz r3,8(r1) ++ lwz r3,8+HIWORD(r1) + cmpwi r3,0 + addi r1,r1,16 + cfi_adjust_cfa_offset (-16) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S 2014-05-27 22:45:46.000000000 -0500 +@@ -30,7 +30,7 @@ + fmr fp0,fp1 + fabs fp1,fp1 + fcmpu cr7,fp0,fp1 +- lwz r3,8(r1) ++ lwz r3,8+HIWORD(r1) + cmpwi cr6,r3,0 + addi r1,r1,16 + cfi_adjust_cfa_offset (-16) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lrint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lrint.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lrint.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lrint.S 2014-05-27 22:45:46.000000000 -0500 +@@ -24,10 +24,10 @@ + stwu r1,-16(r1) + fctiw fp13,fp1 + stfd fp13,8(r1) +- nop /* Insure the following load is in a different dispatch group */ ++ nop /* Ensure the following load is in a different dispatch group */ + nop /* to avoid pipe stall on POWER4&5. */ + nop +- lwz r3,12(r1) ++ lwz r3,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__lrint) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lround.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lround.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_lround.S 2014-05-27 22:45:46.000000000 -0500 +@@ -67,7 +67,7 @@ + nop /* Ensure the following load is in a different dispatch */ + nop /* group to avoid pipe stall on POWER4&5. */ + nop +- lwz r3,12(r1) /* Load return as integer. */ ++ lwz r3,8+LOWORD(r1) /* Load return as integer. */ + .Lout: + addi r1,r1,16 + blr +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrint.S 2014-05-27 22:48:09.000000000 -0500 +@@ -29,8 +29,8 @@ + nop /* Insure the following load is in a different dispatch group */ + nop /* to avoid pipe stall on POWER4&5. */ + nop +- lwz r3,8(r1) +- lwz r4,12(r1) ++ lwz r3,8+HIWORD(r1) ++ lwz r4,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__llrint) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llrintf.S 2014-05-27 22:48:44.000000000 -0500 +@@ -28,8 +28,8 @@ + nop /* Insure the following load is in a different dispatch group */ + nop /* to avoid pipe stall on POWER4&5. */ + nop +- lwz r3,8(r1) +- lwz r4,12(r1) ++ lwz r3,8+HIWORD(r1) ++ lwz r4,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__llrintf) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S 2014-05-27 22:45:46.000000000 -0500 +@@ -27,8 +27,8 @@ + ori r1,r1,0 + stfd fp1,24(r1) /* copy FPR to GPR */ + ori r1,r1,0 +- lwz r4,24(r1) +- lwz r5,28(r1) ++ lwz r4,24+HIWORD(r1) ++ lwz r5,24+LOWORD(r1) + lis r0,0x7ff0 /* const long r0 0x7ff00000 00000000 */ + clrlwi r4,r4,1 /* x = fabs(x) */ + cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_llround.S 2014-05-27 22:45:46.000000000 -0500 +@@ -39,8 +39,8 @@ + nop /* Ensure the following load is in a different dispatch */ + nop /* group to avoid pipe stall on POWER4&5. */ + nop +- lwz r4,12(r1) +- lwz r3,8(r1) ++ lwz r3,8+HIWORD(r1) ++ lwz r4,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__llround) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/fpu/s_lround.S 2014-05-27 22:45:46.000000000 -0500 +@@ -38,7 +38,7 @@ + nop /* Ensure the following load is in a different dispatch */ + nop /* group to avoid pipe stall on POWER4&5. */ + nop +- lwz r3,12(r1) ++ lwz r3,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__lround) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S 2014-05-27 22:45:46.000000000 -0500 +@@ -27,8 +27,8 @@ + ori r1,r1,0 + stfd fp1,24(r1) /* copy FPR to GPR */ + ori r1,r1,0 +- lwz r4,24(r1) +- lwz r5,28(r1) ++ lwz r4,24+HIWORD(r1) ++ lwz r5,24+LOWORD(r1) + lis r0,0x7ff0 /* const long r0 0x7ff00000 00000000 */ + clrlwi r4,r4,1 /* x = fabs(x) */ + cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrint.S 2014-05-27 22:46:52.000000000 -0500 +@@ -29,8 +29,8 @@ + /* Insure the following load is in a different dispatch group by + inserting "group ending nop". */ + ori r1,r1,0 +- lwz r3,8(r1) +- lwz r4,12(r1) ++ lwz r3,8+HIWORD(r1) ++ lwz r4,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__llrint) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llrintf.S 2014-05-27 22:47:29.000000000 -0500 +@@ -28,8 +28,8 @@ + /* Insure the following load is in a different dispatch group by + inserting "group ending nop". */ + ori r1,r1,0 +- lwz r3,8(r1) +- lwz r4,12(r1) ++ lwz r3,8+HIWORD(r1) ++ lwz r4,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__llrintf) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_llround.S 2014-05-27 22:45:46.000000000 -0500 +@@ -39,8 +39,8 @@ + /* Insure the following load is in a different dispatch group by + inserting "group ending nop". */ + ori r1,r1,0 +- lwz r4,12(r1) +- lwz r3,8(r1) ++ lwz r3,8+HIWORD(r1) ++ lwz r4,8+LOWORD(r1) + addi r1,r1,16 + blr + END (__llround) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S 2014-05-27 22:45:46.000000000 -0500 +@@ -54,9 +54,8 @@ + stfd fp1,8(r1) /* Transfer FP to GPR's. */ + + ori 2,2,0 /* Force a new dispatch group. */ +- lhz r0,8(r1) /* Fetch the upper portion of the high word of +- the FP value (where the exponent and sign bits +- are). */ ++ lhz r0,8+HISHORT(r1) /* Fetch the upper 16 bits of the FP value ++ (biased exponent and sign bit). */ + clrlwi r0,r0,17 /* r0 = abs(r0). */ + addi r1,r1,16 /* Reset the stack pointer. */ + cmpwi cr7,r0,0x7ff0 /* r4 == 0x7ff0?. */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S 2014-05-27 22:45:46.000000000 -0500 +@@ -48,14 +48,13 @@ + li r3,0 + bflr 29 /* If not INF, return. */ + +- /* Either we have -INF/+INF or a denormal. */ ++ /* Either we have +INF or -INF. */ + + stwu r1,-16(r1) /* Allocate stack space. */ + stfd fp1,8(r1) /* Transfer FP to GPR's. */ + ori 2,2,0 /* Force a new dispatch group. */ +- lhz r4,8(r1) /* Fetch the upper portion of the high word of +- the FP value (where the exponent and sign bits +- are). */ ++ lhz r4,8+HISHORT(r1) /* Fetch the upper 16 bits of the FP value ++ (biased exponent and sign bit). */ + addi r1,r1,16 /* Reset the stack pointer. */ + cmpwi cr7,r4,0x7ff0 /* r4 == 0x7ff0? */ + li r3,1 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S 2014-05-27 22:45:46.000000000 -0500 +@@ -53,8 +53,8 @@ + stwu r1,-16(r1) /* Allocate stack space. */ + stfd fp1,8(r1) /* Transfer FP to GPR's. */ + ori 2,2,0 /* Force a new dispatch group. */ +- lwz r4,8(r1) /* Load the upper half of the FP value. */ +- lwz r5,12(r1) /* Load the lower half of the FP value. */ ++ lwz r4,8+HIWORD(r1) /* Load the upper half of the FP value. */ ++ lwz r5,8+LOWORD(r1) /* Load the lower half of the FP value. */ + addi r1,r1,16 /* Reset the stack pointer. */ + lis r0,0x7ff0 /* Load the upper portion for an INF/NaN. */ + clrlwi r4,r4,1 /* r4 = abs(r4). */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S 2014-05-27 22:45:46.000000000 -0500 +@@ -39,10 +39,8 @@ + + stfd fp1,-16(r1) /* Transfer FP to GPR's. */ + ori 2,2,0 /* Force a new dispatch group. */ +- +- lhz r4,-16(r1) /* Fetch the upper portion of the high word of +- the FP value (where the exponent and sign bits +- are). */ ++ lhz r4,-16+HISHORT(r1) /* Fetch the upper 16 bits of the FP value ++ (biased exponent and sign bit). */ + clrlwi r4,r4,17 /* r4 = abs(r4). */ + cmpwi cr7,r4,0x7ff0 /* r4 == 0x7ff0? */ + bltlr cr7 /* LT means finite, other non-finite. */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S 2014-05-27 22:45:46.000000000 -0500 +@@ -38,9 +38,8 @@ + + stfd fp1,-16(r1) /* Transfer FP to GPR's. */ + ori 2,2,0 /* Force a new dispatch group. */ +- lhz r4,-16(r1) /* Fetch the upper portion of the high word of +- the FP value (where the exponent and sign bits +- are). */ ++ lhz r4,-16+HISHORT(r1) /* Fetch the upper 16 bits of the FP value ++ (biased exponent and sign bit). */ + cmpwi cr7,r4,0x7ff0 /* r4 == 0x7ff0? */ + li r3,1 + beqlr cr7 /* EQ means INF, otherwise -INF. */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h +--- glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h 2014-05-27 22:45:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h 2014-05-27 22:45:46.000000000 -0500 +@@ -144,6 +144,21 @@ + + #define VRSAVE 256 + ++/* The 32-bit words of a 64-bit dword are at these offsets in memory. */ ++#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN ++# define LOWORD 0 ++# define HIWORD 4 ++#else ++# define LOWORD 4 ++# define HIWORD 0 ++#endif ++ ++/* The high 16-bit word of a 64-bit dword is at this offset in memory. */ ++#if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN ++# define HISHORT 6 ++#else ++# define HISHORT 0 ++#endif + + /* This seems to always be the case on PPC. */ + #define ALIGNARG(log2) log2 diff --git a/SOURCES/glibc-ppc64le-18.patch b/SOURCES/glibc-ppc64le-18.patch new file mode 100644 index 00000000..22e408ea --- /dev/null +++ b/SOURCES/glibc-ppc64le-18.patch @@ -0,0 +1,81 @@ +# commit 6a31fe7f9cce72b69fce8fe499a2c6ad492c2311 +# Author: Alan Modra +# Date: Sat Aug 17 18:32:18 2013 +0930 +# +# PowerPC floating point little-endian [13 of 15] +# http://sourceware.org/ml/libc-alpha/2013-08/msg00088.html +# +# * sysdeps/powerpc/powerpc32/fpu/s_roundf.S: Increase alignment of +# constants to usual value for .cst8 section, and remove redundant +# high address load. +# * sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S: Use float +# constant for 0x1p52. Load little-endian words of double from +# correct stack offsets. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_roundf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_roundf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_roundf.S 2014-05-27 22:50:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_roundf.S 2014-05-27 22:50:13.000000000 -0500 +@@ -19,7 +19,7 @@ + #include + + .section .rodata.cst8,"aM",@progbits,8 +- .align 2 ++ .align 3 + .LC0: /* 2**23 */ + .long 0x4b000000 + .LC1: /* 0.5 */ +@@ -60,7 +60,6 @@ + #ifdef SHARED + lfs fp10,.LC1-.LC0(r9) + #else +- lis r9,.LC1@ha + lfs fp10,.LC1@l(r9) + #endif + ble- cr6,.L4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S 2014-05-27 22:50:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/s_llround.S 2014-05-27 22:50:13.000000000 -0500 +@@ -19,12 +19,10 @@ + #include + #include + +- .section .rodata.cst12,"aM",@progbits,12 ++ .section .rodata.cst8,"aM",@progbits,8 + .align 3 +- .LC0: /* 0x1.0000000000000p+52 == 2^52 */ +- .long 0x43300000 +- .long 0x00000000 +- .long 0x3f000000 /* Use this for 0.5 */ ++ .LC0: .long (52+127)<<23 /* 0x1p+52 */ ++ .long (-1+127)<<23 /* 0.5 */ + + .section ".text" + +@@ -57,12 +55,12 @@ + addi r9,r9,.LC0-got_label@l + mtlr r11 + cfi_same_value (lr) +- lfd fp9,0(r9) +- lfs fp10,8(r9) ++ lfs fp9,0(r9) ++ lfs fp10,4(r9) + #else + lis r9,.LC0@ha +- lfd fp9,.LC0@l(r9) /* Load 2^52 into fpr9. */ +- lfs fp10,.LC0@l+8(r9) /* Load 0.5 into fpr10. */ ++ lfs fp9,.LC0@l(r9) /* Load 2^52 into fpr9. */ ++ lfs fp10,.LC0@l+4(r9) /* Load 0.5 into fpr10. */ + #endif + fabs fp2,fp1 /* Get the absolute value of x. */ + fsub fp12,fp10,fp10 /* Compute 0.0 into fpr12. */ +@@ -80,8 +78,8 @@ + nop + nop + nop +- lwz r4,12(r1) /* Load return as integer. */ +- lwz r3,8(r1) ++ lwz r3,8+HIWORD(r1) /* Load return as integer. */ ++ lwz r4,8+LOWORD(r1) + .Lout: + addi r1,r1,16 + blr diff --git a/SOURCES/glibc-ppc64le-19.patch b/SOURCES/glibc-ppc64le-19.patch new file mode 100644 index 00000000..c0c650a2 --- /dev/null +++ b/SOURCES/glibc-ppc64le-19.patch @@ -0,0 +1,110 @@ +# commit 76a66d510a3737674563133a420f4fd22da42c1b +# Author: Anton Blanchard +# Date: Sat Aug 17 18:33:02 2013 +0930 +# +# PowerPC floating point little-endian [14 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00205.html +# +# These all wrongly specified float constants in a 64-bit word. +# +# * sysdeps/powerpc/powerpc64/fpu/s_ceilf.S: Correct float constants +# for little-endian. +# * sysdeps/powerpc/powerpc64/fpu/s_floorf.S: Likewise. +# * sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S: Likewise. +# * sysdeps/powerpc/powerpc64/fpu/s_rintf.S: Likewise. +# * sysdeps/powerpc/powerpc64/fpu/s_roundf.S: Likewise. +# * sysdeps/powerpc/powerpc64/fpu/s_truncf.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S 2014-05-27 22:52:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_ceilf.S 2014-05-27 22:52:18.000000000 -0500 +@@ -19,8 +19,10 @@ + #include + + .section ".toc","aw" ++ .p2align 3 + .LC0: /* 2**23 */ +- .tc FD_4b000000_0[TC],0x4b00000000000000 ++ .long 0x4b000000 ++ .long 0x0 + .section ".text" + + EALIGN (__ceilf, 4, 0) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_floorf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_floorf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_floorf.S 2014-05-27 22:52:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_floorf.S 2014-05-27 22:52:18.000000000 -0500 +@@ -19,8 +19,10 @@ + #include + + .section ".toc","aw" ++ .p2align 3 + .LC0: /* 2**23 */ +- .tc FD_4b000000_0[TC],0x4b00000000000000 ++ .long 0x4b000000 ++ .long 0x0 + .section ".text" + + EALIGN (__floorf, 4, 0) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S 2014-05-27 22:52:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S 2014-05-27 22:52:18.000000000 -0500 +@@ -26,8 +26,10 @@ + /* float [fp1] nearbyintf(float [fp1]) */ + + .section ".toc","aw" ++ .p2align 3 + .LC0: /* 2**23 */ +- .tc FD_4b000000_0[TC],0x4b00000000000000 ++ .long 0x4b000000 ++ .long 0x0 + .section ".text" + + EALIGN (__nearbyintf, 4, 0) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S 2014-05-27 22:52:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S 2014-05-27 22:52:18.000000000 -0500 +@@ -19,8 +19,10 @@ + #include + + .section ".toc","aw" ++ .p2align 3 + .LC0: /* 2**23 */ +- .tc FD_4b000000_0[TC],0x4b00000000000000 ++ .long 0x4b000000 ++ .long 0x0 + .section ".text" + + EALIGN (__rintf, 4, 0) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_roundf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_roundf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_roundf.S 2014-05-27 22:52:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_roundf.S 2014-05-27 22:52:18.000000000 -0500 +@@ -19,10 +19,12 @@ + #include + + .section ".toc","aw" ++ .p2align 3 + .LC0: /* 2**23 */ +- .tc FD_4b000000_0[TC],0x4b00000000000000 ++ .long 0x4b000000 + .LC1: /* 0.5 */ +- .tc FD_3f000000_0[TC],0x3f00000000000000 ++ .long 0x3f000000 ++ + .section ".text" + + /* float [fp1] roundf (float x [fp1]) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_truncf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_truncf.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_truncf.S 2014-05-27 22:52:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_truncf.S 2014-05-27 22:52:18.000000000 -0500 +@@ -19,8 +19,10 @@ + #include + + .section ".toc","aw" ++ .p2align 3 + .LC0: /* 2**23 */ +- .tc FD_4b000000_0[TC],0x4b00000000000000 ++ .long 0x4b000000 ++ .long 0x0 + .section ".text" + + /* float [fp1] truncf (float x [fp1]) diff --git a/SOURCES/glibc-ppc64le-20.patch b/SOURCES/glibc-ppc64le-20.patch new file mode 100644 index 00000000..2ec0d0e5 --- /dev/null +++ b/SOURCES/glibc-ppc64le-20.patch @@ -0,0 +1,41 @@ +# commit fef13a78ea30d4c26d6bab48d731ebe864ee31b0 +# Author: Alan Modra +# Date: Sat Aug 17 18:33:45 2013 +0930 +# +# PowerPC floating point little-endian [15 of 15] +# http://sourceware.org/ml/libc-alpha/2013-07/msg00206.html +# +# The union loses when little-endian. +# +# * sysdeps/powerpc/powerpc32/power4/hp-timing.h (HP_TIMING_NOW): +# Don't use a union to pack hi/low value. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h 2014-05-27 22:53:37.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h 2014-05-27 22:53:39.000000000 -0500 +@@ -87,18 +87,15 @@ + + #define HP_TIMING_NOW(Var) \ + do { \ +- union { long long ll; long ii[2]; } _var; \ +- long tmp; \ +- __asm__ __volatile__ ( \ +- "1: mfspr %0,269;" \ +- " mfspr %1,268;" \ +- " mfspr %2,269;" \ +- " cmpw %0,%2;" \ +- " bne 1b;" \ +- : "=r" (_var.ii[0]), "=r" (_var.ii[1]) , "=r" (tmp) \ +- : : "cr0" \ +- ); \ +- Var = _var.ll; \ ++ unsigned int hi, lo, tmp; \ ++ __asm__ __volatile__ ("1: mfspr %0,269;" \ ++ " mfspr %1,268;" \ ++ " mfspr %2,269;" \ ++ " cmpw %0,%2;" \ ++ " bne 1b;" \ ++ : "=&r" (hi), "=&r" (lo), "=&r" (tmp) \ ++ : : "cr0"); \ ++ Var = ((hp_timing_t) hi << 32) | lo; \ + } while (0) diff --git a/SOURCES/glibc-ppc64le-21.patch b/SOURCES/glibc-ppc64le-21.patch new file mode 100644 index 00000000..786bd228 --- /dev/null +++ b/SOURCES/glibc-ppc64le-21.patch @@ -0,0 +1,294 @@ +# commit be1e5d311342e08ae1f8013342df27b7ded2c156 +# Author: Anton Blanchard +# Date: Sat Aug 17 18:34:40 2013 +0930 +# +# PowerPC LE setjmp/longjmp +# http://sourceware.org/ml/libc-alpha/2013-08/msg00089.html +# +# Little-endian fixes for setjmp/longjmp. When writing these I noticed +# the setjmp code corrupts the non volatile VMX registers when using an +# unaligned buffer. Anton fixed this, and also simplified it quite a +# bit. +# +# The current code uses boilerplate for the case where we want to store +# 16 bytes to an unaligned address. For that we have to do a +# read/modify/write of two aligned 16 byte quantities. In our case we +# are storing a bunch of back to back data (consective VMX registers), +# and only the start and end of the region need the read/modify/write. +# +# [BZ #15723] +# * sysdeps/powerpc/jmpbuf-offsets.h: Comment fix. +# * sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S: Correct +# _dl_hwcap access for little-endian. +# * sysdeps/powerpc/powerpc32/fpu/setjmp-common.S: Likewise. Don't +# destroy vmx regs when saving unaligned. +# * sysdeps/powerpc/powerpc64/__longjmp-common.S: Correct CR load. +# * sysdeps/powerpc/powerpc64/setjmp-common.S: Likewise CR save. Don't +# destroy vmx regs when saving unaligned. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/jmpbuf-offsets.h glibc-2.17-c758a686/sysdeps/powerpc/jmpbuf-offsets.h +--- glibc-2.17-c758a686/sysdeps/powerpc/jmpbuf-offsets.h 2014-05-27 22:55:23.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/jmpbuf-offsets.h 2014-05-27 22:55:27.000000000 -0500 +@@ -21,12 +21,10 @@ + #define JB_LR 2 /* The address we will return to */ + #if __WORDSIZE == 64 + # define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18*2 words total. */ +-# define JB_CR 21 /* Condition code registers with the VRSAVE at */ +- /* offset 172 (low half of the double word. */ ++# define JB_CR 21 /* Shared dword with VRSAVE. CR word at offset 172. */ + # define JB_FPRS 22 /* FPRs 14 through 31 are saved, 18*2 words total. */ + # define JB_SIZE (64 * 8) /* As per PPC64-VMX ABI. */ +-# define JB_VRSAVE 21 /* VRSAVE shares a double word with the CR at offset */ +- /* 168 (high half of the double word). */ ++# define JB_VRSAVE 21 /* Shared dword with CR. VRSAVE word at offset 168. */ + # define JB_VRS 40 /* VRs 20 through 31 are saved, 12*4 words total. */ + #else + # define JB_GPRS 3 /* GPRs 14 through 31 are saved, 18 in total. */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S 2014-05-27 22:55:23.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S 2014-05-27 22:55:27.000000000 -0500 +@@ -46,16 +46,16 @@ + # endif + mtlr r6 + cfi_same_value (lr) +- lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r5) ++ lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r5) + # else + lwz r5,_dl_hwcap@got(r5) + mtlr r6 + cfi_same_value (lr) +- lwz r5,4(r5) ++ lwz r5,LOWORD(r5) + # endif + # else +- lis r5,(_dl_hwcap+4)@ha +- lwz r5,(_dl_hwcap+4)@l(r5) ++ lis r5,(_dl_hwcap+LOWORD)@ha ++ lwz r5,(_dl_hwcap+LOWORD)@l(r5) + # endif + andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16) + beq L(no_vmx) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S 2014-05-27 22:55:23.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S 2014-05-27 22:55:27.000000000 -0500 +@@ -97,14 +97,14 @@ + # else + lwz r5,_rtld_global_ro@got(r5) + # endif +- lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r5) ++ lwz r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r5) + # else + lwz r5,_dl_hwcap@got(r5) +- lwz r5,4(r5) ++ lwz r5,LOWORD(r5) + # endif + # else +- lis r6,(_dl_hwcap+4)@ha +- lwz r5,(_dl_hwcap+4)@l(r6) ++ lis r6,(_dl_hwcap+LOWORD)@ha ++ lwz r5,(_dl_hwcap+LOWORD)@l(r6) + # endif + andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16) + beq L(no_vmx) +@@ -114,44 +114,43 @@ + stw r0,((JB_VRSAVE)*4)(3) + addi r6,r5,16 + beq+ L(aligned_save_vmx) ++ + lvsr v0,0,r5 +- vspltisb v1,-1 /* set v1 to all 1's */ +- vspltisb v2,0 /* set v2 to all 0's */ +- vperm v3,v2,v1,v0 /* v3 contains shift mask with num all 1 bytes on left = misalignment */ +- +- +- /* Special case for v20 we need to preserve what is in save area below v20 before obliterating it */ +- lvx v5,0,r5 +- vperm v20,v20,v20,v0 +- vsel v5,v5,v20,v3 +- vsel v20,v20,v2,v3 +- stvx v5,0,r5 +- +-#define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \ +- addi addgpr,addgpr,32; \ +- vperm savevr,savevr,savevr,shiftvr; \ +- vsel hivr,prev_savevr,savevr,maskvr; \ +- stvx hivr,0,savegpr; +- +- save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5) +- save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6) +- save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5) +- save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6) +- save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5) +- save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6) +- save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5) +- save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6) +- save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5) +- save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6) +- +- /* Special case for r31 we need to preserve what is in save area above v31 before obliterating it */ +- addi r5,r5,32 +- vperm v31,v31,v31,v0 +- lvx v4,0,r5 +- vsel v5,v30,v31,v3 +- stvx v5,0,r6 +- vsel v4,v31,v4,v3 +- stvx v4,0,r5 ++ lvsl v1,0,r5 ++ addi r6,r5,-16 ++ ++# define save_misaligned_vmx(savevr,prevvr,shiftvr,tmpvr,savegpr,addgpr) \ ++ addi addgpr,addgpr,32; \ ++ vperm tmpvr,prevvr,savevr,shiftvr; \ ++ stvx tmpvr,0,savegpr ++ ++ /* ++ * We have to be careful not to corrupt the data below v20 and ++ * above v31. To keep things simple we just rotate both ends in ++ * the opposite direction to our main permute so we can use ++ * the common macro. ++ */ ++ ++ /* load and rotate data below v20 */ ++ lvx v2,0,r5 ++ vperm v2,v2,v2,v1 ++ save_misaligned_vmx(v20,v2,v0,v3,r5,r6) ++ save_misaligned_vmx(v21,v20,v0,v3,r6,r5) ++ save_misaligned_vmx(v22,v21,v0,v3,r5,r6) ++ save_misaligned_vmx(v23,v22,v0,v3,r6,r5) ++ save_misaligned_vmx(v24,v23,v0,v3,r5,r6) ++ save_misaligned_vmx(v25,v24,v0,v3,r6,r5) ++ save_misaligned_vmx(v26,v25,v0,v3,r5,r6) ++ save_misaligned_vmx(v27,v26,v0,v3,r6,r5) ++ save_misaligned_vmx(v28,v27,v0,v3,r5,r6) ++ save_misaligned_vmx(v29,v28,v0,v3,r6,r5) ++ save_misaligned_vmx(v30,v29,v0,v3,r5,r6) ++ save_misaligned_vmx(v31,v30,v0,v3,r6,r5) ++ /* load and rotate data above v31 */ ++ lvx v2,0,r6 ++ vperm v2,v2,v2,v1 ++ save_misaligned_vmx(v2,v31,v0,v3,r5,r6) ++ + b L(no_vmx) + + L(aligned_save_vmx): +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S 2014-05-27 22:55:23.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S 2014-05-27 22:55:27.000000000 -0500 +@@ -60,7 +60,7 @@ + beq L(no_vmx) + la r5,((JB_VRS)*8)(3) + andi. r6,r5,0xf +- lwz r0,((JB_VRSAVE)*8)(3) ++ lwz r0,((JB_VRSAVE)*8)(3) /* 32-bit VRSAVE. */ + mtspr VRSAVE,r0 + beq+ L(aligned_restore_vmx) + addi r6,r5,16 +@@ -156,7 +156,7 @@ + lfd fp21,((JB_FPRS+7)*8)(r3) + ld r22,((JB_GPRS+8)*8)(r3) + lfd fp22,((JB_FPRS+8)*8)(r3) +- ld r0,(JB_CR*8)(r3) ++ lwz r0,((JB_CR*8)+4)(r3) /* 32-bit CR. */ + ld r23,((JB_GPRS+9)*8)(r3) + lfd fp23,((JB_FPRS+9)*8)(r3) + ld r24,((JB_GPRS+10)*8)(r3) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-27 22:55:23.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-27 22:55:27.000000000 -0500 +@@ -98,7 +98,7 @@ + mfcr r0 + std r16,((JB_GPRS+2)*8)(3) + stfd fp16,((JB_FPRS+2)*8)(3) +- std r0,(JB_CR*8)(3) ++ stw r0,((JB_CR*8)+4)(3) /* 32-bit CR. */ + std r17,((JB_GPRS+3)*8)(3) + stfd fp17,((JB_FPRS+3)*8)(3) + std r18,((JB_GPRS+4)*8)(3) +@@ -142,50 +142,46 @@ + la r5,((JB_VRS)*8)(3) + andi. r6,r5,0xf + mfspr r0,VRSAVE +- stw r0,((JB_VRSAVE)*8)(3) ++ stw r0,((JB_VRSAVE)*8)(3) /* 32-bit VRSAVE. */ + addi r6,r5,16 + beq+ L(aligned_save_vmx) ++ + lvsr v0,0,r5 +- vspltisb v1,-1 /* set v1 to all 1's */ +- vspltisb v2,0 /* set v2 to all 0's */ +- vperm v3,v2,v1,v0 /* v3 contains shift mask with num all 1 bytes +- on left = misalignment */ +- +- +- /* Special case for v20 we need to preserve what is in save area +- below v20 before obliterating it */ +- lvx v5,0,r5 +- vperm v20,v20,v20,v0 +- vsel v5,v5,v20,v3 +- vsel v20,v20,v2,v3 +- stvx v5,0,r5 +- +-# define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \ +- addi addgpr,addgpr,32; \ +- vperm savevr,savevr,savevr,shiftvr; \ +- vsel hivr,prev_savevr,savevr,maskvr; \ +- stvx hivr,0,savegpr; +- +- save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5) +- save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6) +- save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5) +- save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6) +- save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5) +- save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6) +- save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5) +- save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6) +- save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5) +- save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6) +- +- /* Special case for r31 we need to preserve what is in save area +- above v31 before obliterating it */ +- addi r5,r5,32 +- vperm v31,v31,v31,v0 +- lvx v4,0,r5 +- vsel v5,v30,v31,v3 +- stvx v5,0,r6 +- vsel v4,v31,v4,v3 +- stvx v4,0,r5 ++ lvsl v1,0,r5 ++ addi r6,r5,-16 ++ ++# define save_misaligned_vmx(savevr,prevvr,shiftvr,tmpvr,savegpr,addgpr) \ ++ addi addgpr,addgpr,32; \ ++ vperm tmpvr,prevvr,savevr,shiftvr; \ ++ stvx tmpvr,0,savegpr ++ ++ /* ++ * We have to be careful not to corrupt the data below v20 and ++ * above v31. To keep things simple we just rotate both ends in ++ * the opposite direction to our main permute so we can use ++ * the common macro. ++ */ ++ ++ /* load and rotate data below v20 */ ++ lvx v2,0,r5 ++ vperm v2,v2,v2,v1 ++ save_misaligned_vmx(v20,v2,v0,v3,r5,r6) ++ save_misaligned_vmx(v21,v20,v0,v3,r6,r5) ++ save_misaligned_vmx(v22,v21,v0,v3,r5,r6) ++ save_misaligned_vmx(v23,v22,v0,v3,r6,r5) ++ save_misaligned_vmx(v24,v23,v0,v3,r5,r6) ++ save_misaligned_vmx(v25,v24,v0,v3,r6,r5) ++ save_misaligned_vmx(v26,v25,v0,v3,r5,r6) ++ save_misaligned_vmx(v27,v26,v0,v3,r6,r5) ++ save_misaligned_vmx(v28,v27,v0,v3,r5,r6) ++ save_misaligned_vmx(v29,v28,v0,v3,r6,r5) ++ save_misaligned_vmx(v30,v29,v0,v3,r5,r6) ++ save_misaligned_vmx(v31,v30,v0,v3,r6,r5) ++ /* load and rotate data above v31 */ ++ lvx v2,0,r6 ++ vperm v2,v2,v2,v1 ++ save_misaligned_vmx(v2,v31,v0,v3,r5,r6) ++ + b L(no_vmx) + + L(aligned_save_vmx): diff --git a/SOURCES/glibc-ppc64le-22.patch b/SOURCES/glibc-ppc64le-22.patch new file mode 100644 index 00000000..23e4872f --- /dev/null +++ b/SOURCES/glibc-ppc64le-22.patch @@ -0,0 +1,228 @@ +# commit 9b874b2f1eb2550e39d3e9c38772e64a767e9de2 +# Author: Alan Modra +# Date: Sat Aug 17 18:35:40 2013 +0930 +# +# PowerPC ugly symbol versioning +# http://sourceware.org/ml/libc-alpha/2013-08/msg00090.html +# +# This patch fixes symbol versioning in setjmp/longjmp. The existing +# code uses raw versions, which results in wrong symbol versioning when +# you want to build glibc with a base version of 2.19 for LE. +# +# Note that the merging the 64-bit and 32-bit versions in novmx-lonjmp.c +# and pt-longjmp.c doesn't result in GLIBC_2.0 versions for 64-bit, due +# to the base in shlib_versions. +# +# * sysdeps/powerpc/longjmp.c: Use proper symbol versioning macros. +# * sysdeps/powerpc/novmx-longjmp.c: Likewise. +# * sysdeps/powerpc/powerpc32/bsd-_setjmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/bsd-setjmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/fpu/__longjmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/fpu/setjmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/mcount.c: Likewise. +# * sysdeps/powerpc/powerpc32/setjmp.S: Likewise. +# * sysdeps/powerpc/powerpc64/setjmp.S: Likewise. +# * nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c: Likewise. +# +diff -urN glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c 2014-05-27 23:22:12.000000000 -0500 ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pt-longjmp.c 2014-05-27 23:23:44.000000000 -0500 +@@ -41,13 +41,8 @@ + __novmx__libc_longjmp (env, val); + } + +-# if __WORDSIZE == 64 +-symbol_version (__novmx_longjmp,longjmp,GLIBC_2.3); +-symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.3); +-# else +-symbol_version (__novmx_longjmp,longjmp,GLIBC_2.0); +-symbol_version (__novmx_siglongjmp,siglongjmp,GLIBC_2.0); +-# endif ++compat_symbol (libpthread, __novmx_longjmp, longjmp, GLIBC_2_0); ++compat_symbol (libpthread, __novmx_siglongjmp, siglongjmp, GLIBC_2_0); + #endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)) */ + + void +@@ -62,5 +57,5 @@ + __libc_siglongjmp (env, val); + } + +-versioned_symbol (libc, __vmx_longjmp, longjmp, GLIBC_2_3_4); +-versioned_symbol (libc, __vmx_siglongjmp, siglongjmp, GLIBC_2_3_4); ++versioned_symbol (libpthread, __vmx_longjmp, longjmp, GLIBC_2_3_4); ++versioned_symbol (libpthread, __vmx_siglongjmp, siglongjmp, GLIBC_2_3_4); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/longjmp.c glibc-2.17-c758a686/sysdeps/powerpc/longjmp.c +--- glibc-2.17-c758a686/sysdeps/powerpc/longjmp.c 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/longjmp.c 2014-05-27 23:22:12.000000000 -0500 +@@ -56,6 +56,6 @@ + + default_symbol_version (__vmx__libc_longjmp, __libc_longjmp, GLIBC_PRIVATE); + default_symbol_version (__vmx__libc_siglongjmp, __libc_siglongjmp, GLIBC_PRIVATE); +-default_symbol_version (__vmx_longjmp, _longjmp, GLIBC_2.3.4); +-default_symbol_version (__vmxlongjmp, longjmp, GLIBC_2.3.4); +-default_symbol_version (__vmxsiglongjmp, siglongjmp, GLIBC_2.3.4); ++versioned_symbol (libc, __vmx_longjmp, _longjmp, GLIBC_2_3_4); ++versioned_symbol (libc, __vmxlongjmp, longjmp, GLIBC_2_3_4); ++versioned_symbol (libc, __vmxsiglongjmp, siglongjmp, GLIBC_2_3_4); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/novmx-longjmp.c glibc-2.17-c758a686/sysdeps/powerpc/novmx-longjmp.c +--- glibc-2.17-c758a686/sysdeps/powerpc/novmx-longjmp.c 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/novmx-longjmp.c 2014-05-27 23:22:12.000000000 -0500 +@@ -51,13 +51,7 @@ + weak_alias (__novmx__libc_siglongjmp, __novmxlongjmp) + weak_alias (__novmx__libc_siglongjmp, __novmxsiglongjmp) + +-# if __WORDSIZE == 64 +-symbol_version (__novmx_longjmp,_longjmp,GLIBC_2.3); +-symbol_version (__novmxlongjmp,longjmp,GLIBC_2.3); +-symbol_version (__novmxsiglongjmp,siglongjmp,GLIBC_2.3); +-# else +-symbol_version (__novmx_longjmp,_longjmp,GLIBC_2.0); +-symbol_version (__novmxlongjmp,longjmp,GLIBC_2.0); +-symbol_version (__novmxsiglongjmp,siglongjmp,GLIBC_2.0); +-# endif ++compat_symbol (libc, __novmx_longjmp, _longjmp, GLIBC_2_0); ++compat_symbol (libc, __novmxlongjmp, longjmp, GLIBC_2_0); ++compat_symbol (libc, __novmxsiglongjmp, siglongjmp, GLIBC_2_0); + #endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)) */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S 2014-05-27 23:22:12.000000000 -0500 +@@ -32,7 +32,7 @@ + /* Build a versioned object for libc. */ + + # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) +-symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.0); ++compat_symbol (libc, __novmx_setjmp, _setjmp, GLIBC_2_0); + + ENTRY (BP_SYM (__novmx_setjmp)) + li r4,0 /* Set second argument to 0. */ +@@ -41,7 +41,7 @@ + libc_hidden_def (__novmx_setjmp) + # endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */ + +-default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4) ++versioned_symbol (libc, __vmx_setjmp, _setjmp, GLIBC_2_3_4) + /* __GI__setjmp prototype is needed for ntpl i.e. _setjmp is defined + as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c + if HAVE_CLEANUP_JMP_BUF is defined */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-setjmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-setjmp.S 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-setjmp.S 2014-05-27 23:22:12.000000000 -0500 +@@ -27,7 +27,7 @@ + b __novmx__sigsetjmp@local + END (__novmxsetjmp) + strong_alias (__novmxsetjmp, __novmx__setjmp) +-symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0) ++compat_symbol (libc, __novmxsetjmp, setjmp, GLIBC_2_0) + + #endif /* defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) ) */ + +@@ -37,4 +37,4 @@ + END (__vmxsetjmp) + strong_alias (__vmxsetjmp, __vmx__setjmp) + strong_alias (__vmx__setjmp, __setjmp) +-default_symbol_version (__vmxsetjmp,setjmp,GLIBC_2.3.4) ++versioned_symbol (libc, __vmxsetjmp, setjmp, GLIBC_2_3_4) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S 2014-05-27 23:22:12.000000000 -0500 +@@ -26,14 +26,14 @@ + + #else /* !NOT_IN_libc */ + /* Build a versioned object for libc. */ +-default_symbol_version (__vmx__longjmp,__longjmp,GLIBC_2.3.4); ++versioned_symbol (libc, __vmx__longjmp, __longjmp, GLIBC_2_3_4); + # define __longjmp __vmx__longjmp + # include "__longjmp-common.S" + + # if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) + # define __NO_VMX__ + # undef JB_SIZE +-symbol_version (__novmx__longjmp,__longjmp,GLIBC_2.0); ++compat_symbol (libc, __novmx__longjmp, __longjmp, GLIBC_2_0); + # undef __longjmp + # define __longjmp __novmx__longjmp + # include "__longjmp-common.S" +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S 2014-05-27 23:22:12.000000000 -0500 +@@ -26,7 +26,7 @@ + + #else /* !NOT_IN_libc */ + /* Build a versioned object for libc. */ +-default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4) ++versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) + # define __sigsetjmp __vmx__sigsetjmp + # define __sigjmp_save __vmx__sigjmp_save + # include "setjmp-common.S" +@@ -36,7 +36,7 @@ + # undef __sigsetjmp + # undef __sigjmp_save + # undef JB_SIZE +-symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.0) ++compat_symbol (libc, __novmx__sigsetjmp, __sigsetjmp, GLIBC_2_0) + # define __sigsetjmp __novmx__sigsetjmp + # define __sigjmp_save __novmx__sigjmp_save + # include "setjmp-common.S" +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/mcount.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/mcount.c +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/mcount.c 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/mcount.c 2014-05-27 23:22:12.000000000 -0500 +@@ -9,7 +9,7 @@ + /* __mcount_internal was added in glibc 2.15 with version GLIBC_PRIVATE, + but it should have been put in version GLIBC_2.15. Mark the + GLIBC_PRIVATE version obsolete and add it to GLIBC_2.16 instead. */ +-default_symbol_version (___mcount_internal, __mcount_internal, GLIBC_2.16); ++versioned_symbol (libc, ___mcount_internal, __mcount_internal, GLIBC_2_16); + + #if SHLIB_COMPAT (libc, GLIBC_2_15, GLIBC_2_16) + strong_alias (___mcount_internal, ___mcount_internal_private); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S 2014-05-27 23:22:12.000000000 -0500 +@@ -25,7 +25,7 @@ + + #else /* !NOT_IN_libc */ + /* Build a versioned object for libc. */ +-default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4) ++versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) + # define __sigsetjmp __vmx__sigsetjmp + # define __sigjmp_save __vmx__sigjmp_save + # include "setjmp-common.S" +@@ -35,7 +35,7 @@ + # undef __sigsetjmp + # undef __sigjmp_save + # undef JB_SIZE +-symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.0) ++compat_symbol (libc, __novmx__sigsetjmp, __sigsetjmp, GLIBC_2_0) + # define __sigsetjmp __novmx__sigsetjmp + # define __sigjmp_save __novmx__sigjmp_save + # include "setjmp-common.S" +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S 2014-05-27 23:22:10.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S 2014-05-27 23:22:12.000000000 -0500 +@@ -26,9 +26,9 @@ + + #else /* !NOT_IN_libc */ + /* Build a versioned object for libc. */ +-default_symbol_version (__vmxsetjmp, setjmp, GLIBC_2.3.4) +-default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4) +-default_symbol_version (__vmx__sigsetjmp,__sigsetjmp,GLIBC_2.3.4) ++versioned_symbol (libc, __vmxsetjmp, setjmp, GLIBC_2_3_4) ++versioned_symbol (libc, __vmx_setjmp, _setjmp, GLIBC_2_3_4) ++versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) + # define setjmp __vmxsetjmp + # define _setjmp __vmx_setjmp + # define __sigsetjmp __vmx__sigsetjmp +@@ -44,9 +44,9 @@ + # undef __sigjmp_save + # undef JB_SIZE + # define __NO_VMX__ +-symbol_version (__novmxsetjmp, setjmp, GLIBC_2.3) +-symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.3); +-symbol_version (__novmx__sigsetjmp,__sigsetjmp,GLIBC_2.3) ++compat_symbol (libc, __novmxsetjmp, setjmp, GLIBC_2_3) ++compat_symbol (libc, __novmx_setjmp,_setjmp, GLIBC_2_3); ++compat_symbol (libc, __novmx__sigsetjmp,__sigsetjmp, GLIBC_2_3) + # define setjmp __novmxsetjmp + # define _setjmp __novmx_setjmp + # define __sigsetjmp __novmx__sigsetjmp diff --git a/SOURCES/glibc-ppc64le-23.patch b/SOURCES/glibc-ppc64le-23.patch new file mode 100644 index 00000000..6e1cb23e --- /dev/null +++ b/SOURCES/glibc-ppc64le-23.patch @@ -0,0 +1,102 @@ +# commit 02f04a6c7fea2b474b026bbce721d8c658d71fda +# Author: Alan Modra +# Date: Sat Aug 17 18:36:11 2013 +0930 +# +# PowerPC LE _dl_hwcap access +# http://sourceware.org/ml/libc-alpha/2013-08/msg00091.html +# +# More LE support, correcting word accesses to _dl_hwcap. +# +# * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S: Use +# HIWORD/LOWORD. +# * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S: Ditto. +# * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S: Ditto. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S 2014-05-27 23:25:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext-common.S 2014-05-27 23:25:38.000000000 -0500 +@@ -151,15 +151,15 @@ + # ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 +- lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7) ++ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7) + # else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 +- lwz r7,4(r7) ++ lwz r7,LOWORD(r7) + # endif + # else +- lis r7,(_dl_hwcap+4)@ha +- lwz r7,(_dl_hwcap+4)@l(r7) ++ lis r7,(_dl_hwcap+LOWORD)@ha ++ lwz r7,(_dl_hwcap+LOWORD)@l(r7) + # endif + andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) + +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S 2014-05-27 23:25:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S 2014-05-27 23:25:38.000000000 -0500 +@@ -79,15 +79,15 @@ + # ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 +- lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7) ++ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7) + # else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 +- lwz r7,4(r7) ++ lwz r7,LOWORD(r7) + # endif + #else +- lis r7,(_dl_hwcap+4)@ha +- lwz r7,(_dl_hwcap+4)@l(r7) ++ lis r7,(_dl_hwcap+LOWORD)@ha ++ lwz r7,(_dl_hwcap+LOWORD)@l(r7) + #endif + + #ifdef __CONTEXT_ENABLE_FPRS +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S 2014-05-27 23:25:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext-common.S 2014-05-27 23:25:38.000000000 -0500 +@@ -152,15 +152,15 @@ + # ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) + mtlr r8 +- lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7) ++ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7) + # else + lwz r7,_dl_hwcap@got(r7) + mtlr r8 +- lwz r7,4(r7) ++ lwz r7,LOWORD(r7) + # endif + # else +- lis r7,(_dl_hwcap+4)@ha +- lwz r7,(_dl_hwcap+4)@l(r7) ++ lis r7,(_dl_hwcap+LOWORD)@ha ++ lwz r7,(_dl_hwcap+LOWORD)@l(r7) + # endif + + # ifdef __CONTEXT_ENABLE_VRS +@@ -308,14 +308,14 @@ + mtlr r8 + # ifdef SHARED + lwz r7,_rtld_global_ro@got(r7) +- lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7) ++ lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7) + # else + lwz r7,_dl_hwcap@got(r7) +- lwz r7,4(r7) ++ lwz r7,LOWORD(r7) + # endif + # else +- lis r7,(_dl_hwcap+4)@ha +- lwz r7,(_dl_hwcap+4)@l(r7) ++ lis r7,(_dl_hwcap+LOWORD)@ha ++ lwz r7,(_dl_hwcap+LOWORD)@l(r7) + # endif + andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) + la r10,(_UC_VREGS)(r31) diff --git a/SOURCES/glibc-ppc64le-24.patch b/SOURCES/glibc-ppc64le-24.patch new file mode 100644 index 00000000..8fdc4679 --- /dev/null +++ b/SOURCES/glibc-ppc64le-24.patch @@ -0,0 +1,55 @@ +# commit 0b2c2ace3601d5d59cf89130b16840e7f132f7a6 +# Author: Alan Modra +# Date: Sat Aug 17 18:36:45 2013 +0930 +# +# PowerPC makecontext +# http://sourceware.org/ml/libc-alpha/2013-08/msg00092.html +# +# Use conditional form of branch and link to avoid destroying the cpu +# link stack used to predict blr return addresses. +# +# * sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Use +# conditional form of branch and link when obtaining pc. +# * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S 2014-05-28 12:25:49.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S 2014-05-28 12:25:51.000000000 -0500 +@@ -47,7 +47,9 @@ + #ifdef PIC + mflr r0 + cfi_register(lr,r0) +- bl 1f ++ /* Use this conditional form of branch and link to avoid destroying ++ the cpu link stack used to predict blr return addresses. */ ++ bcl 20,31,1f + 1: mflr r6 + addi r6,r6,L(exitcode)-1b + mtlr r0 +@@ -136,7 +138,9 @@ + #ifdef PIC + mflr r0 + cfi_register(lr,r0) +- bl 1f ++ /* Use this conditional form of branch and link to avoid destroying ++ the cpu link stack used to predict blr return addresses. */ ++ bcl 20,31,1f + 1: mflr r6 + addi r6,r6,L(novec_exitcode)-1b + mtlr r0 +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-28 12:25:49.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-28 12:25:51.000000000 -0500 +@@ -124,8 +124,10 @@ + + /* If the target function returns we need to do some cleanup. We use a + code trick to get the address of our cleanup function into the link +- register. Do not add any code between here and L(exitcode). */ +- bl L(gotexitcodeaddr); ++ register. Do not add any code between here and L(exitcode). ++ Use this conditional form of branch and link to avoid destroying ++ the cpu link stack used to predict blr return addresses. */ ++ bcl 20,31,L(gotexitcodeaddr); + + /* This is the helper code which gets called if a function which + is registered with 'makecontext' returns. In this case we diff --git a/SOURCES/glibc-ppc64le-25.patch b/SOURCES/glibc-ppc64le-25.patch new file mode 100644 index 00000000..03f14e1f --- /dev/null +++ b/SOURCES/glibc-ppc64le-25.patch @@ -0,0 +1,411 @@ +# commit db9b4570c5dc550074140ac1d1677077fba29a26 +# Author: Alan Modra +# Date: Sat Aug 17 18:40:11 2013 +0930 +# +# PowerPC LE strlen +# http://sourceware.org/ml/libc-alpha/2013-08/msg00097.html +# +# This is the first of nine patches adding little-endian support to the +# existing optimised string and memory functions. I did spend some +# time with a power7 simulator looking at cycle by cycle behaviour for +# memchr, but most of these patches have not been run on cpu simulators +# to check that we are going as fast as possible. I'm sure PowerPC can +# do better. However, the little-endian support mostly leaves main +# loops unchanged, so I'm banking on previous authors having done a +# good job on big-endian.. As with most code you stare at long enough, +# I found some improvements for big-endian too. +# +# Little-endian support for strlen. Like most of the string functions, +# I leave the main word or multiple-word loops substantially unchanged, +# just needing to modify the tail. +# +# Removing the branch in the power7 functions is just a tidy. .align +# produces a branch anyway. Modifying regs in the non-power7 functions +# is to suit the new little-endian tail. +# +# * sysdeps/powerpc/powerpc64/power7/strlen.S (strlen): Add little-endian +# support. Don't branch over align. +# * sysdeps/powerpc/powerpc32/power7/strlen.S: Likewise. +# * sysdeps/powerpc/powerpc64/strlen.S (strlen): Add little-endian support. +# Rearrange tmp reg use to suit. Comment. +# * sysdeps/powerpc/powerpc32/strlen.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strlen.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strlen.S 2014-05-28 12:28:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strlen.S 2014-05-28 12:28:45.000000000 -0500 +@@ -31,7 +31,11 @@ + li r0,0 /* Word with null chars to use with cmpb. */ + li r5,-1 /* MASK = 0xffffffffffffffff. */ + lwz r12,0(r4) /* Load word from memory. */ ++#ifdef __LITTLE_ENDIAN__ ++ slw r5,r5,r6 ++#else + srw r5,r5,r6 /* MASK = MASK >> padding. */ ++#endif + orc r9,r12,r5 /* Mask bits that are not part of the string. */ + cmpb r10,r9,r0 /* Check for null bytes in WORD1. */ + cmpwi cr7,r10,0 /* If r10 == 0, no null's have been found. */ +@@ -49,9 +53,6 @@ + cmpb r10,r12,r0 + cmpwi cr7,r10,0 + bne cr7,L(done) +- b L(loop) /* We branch here (rather than falling through) +- to skip the nops due to heavy alignment +- of the loop below. */ + + /* Main loop to look for the end of the string. Since it's a + small loop (< 8 instructions), align it to 32-bytes. */ +@@ -88,9 +89,15 @@ + 0xff in the same position as the null byte in the original + word from the string. Use that to calculate the length. */ + L(done): +- cntlzw r0,r10 /* Count leading zeroes before the match. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi r9, r10, -1 /* Form a mask from trailing zeros. */ ++ andc r9, r9, r10 ++ popcntw r0, r9 /* Count the bits in the mask. */ ++#else ++ cntlzw r0,r10 /* Count leading zeros before the match. */ ++#endif + subf r5,r3,r4 +- srwi r0,r0,3 /* Convert leading zeroes to bytes. */ ++ srwi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r5,r0 /* Compute final length. */ + blr + END (BP_SYM (strlen)) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strlen.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strlen.S 2014-05-28 12:28:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strlen.S 2014-05-28 12:32:24.000000000 -0500 +@@ -31,7 +31,12 @@ + 1 is subtracted you get a value in the range 0x00-0x7f, none of which + have their high bit set. The expression here is + (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when +- there were no 0x00 bytes in the word. ++ there were no 0x00 bytes in the word. You get 0x80 in bytes that ++ match, but possibly false 0x80 matches in the next more significant ++ byte to a true match due to carries. For little-endian this is ++ of no consequence since the least significant match is the one ++ we're interested in, but big-endian needs method 2 to find which ++ byte matches. + + 2) Given a word 'x', we can test to see _which_ byte was zero by + calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f). +@@ -74,7 +79,7 @@ + + ENTRY (BP_SYM (strlen)) + +-#define rTMP1 r0 ++#define rTMP4 r0 + #define rRTN r3 /* incoming STR arg, outgoing result */ + #define rSTR r4 /* current string position */ + #define rPADN r5 /* number of padding bits we prepend to the +@@ -84,9 +89,9 @@ + #define rWORD1 r8 /* current string word */ + #define rWORD2 r9 /* next string word */ + #define rMASK r9 /* mask for first string word */ +-#define rTMP2 r10 +-#define rTMP3 r11 +-#define rTMP4 r12 ++#define rTMP1 r10 ++#define rTMP2 r11 ++#define rTMP3 r12 + + CHECK_BOUNDS_LOW (rRTN, rTMP1, rTMP2) + +@@ -96,15 +101,20 @@ + lwz rWORD1, 0(rSTR) + li rMASK, -1 + addi r7F7F, r7F7F, 0x7f7f +-/* That's the setup done, now do the first pair of words. +- We make an exception and use method (2) on the first two words, to reduce +- overhead. */ ++/* We use method (2) on the first two words, because rFEFE isn't ++ required which reduces setup overhead. Also gives a faster return ++ for small strings on big-endian due to needing to recalculate with ++ method (2) anyway. */ ++#ifdef __LITTLE_ENDIAN__ ++ slw rMASK, rMASK, rPADN ++#else + srw rMASK, rMASK, rPADN ++#endif + and rTMP1, r7F7F, rWORD1 + or rTMP2, r7F7F, rWORD1 + add rTMP1, rTMP1, r7F7F +- nor rTMP1, rTMP2, rTMP1 +- and. rWORD1, rTMP1, rMASK ++ nor rTMP3, rTMP2, rTMP1 ++ and. rTMP3, rTMP3, rMASK + mtcrf 0x01, rRTN + bne L(done0) + lis rFEFE, -0x101 +@@ -113,11 +123,12 @@ + bt 29, L(loop) + + /* Handle second word of pair. */ ++/* Perhaps use method (1) here for little-endian, saving one instruction? */ + lwzu rWORD1, 4(rSTR) + and rTMP1, r7F7F, rWORD1 + or rTMP2, r7F7F, rWORD1 + add rTMP1, rTMP1, r7F7F +- nor. rWORD1, rTMP2, rTMP1 ++ nor. rTMP3, rTMP2, rTMP1 + bne L(done0) + + /* The loop. */ +@@ -131,29 +142,53 @@ + add rTMP3, rFEFE, rWORD2 + nor rTMP4, r7F7F, rWORD2 + bne L(done1) +- and. rTMP1, rTMP3, rTMP4 ++ and. rTMP3, rTMP3, rTMP4 + beq L(loop) + ++#ifndef __LITTLE_ENDIAN__ + and rTMP1, r7F7F, rWORD2 + add rTMP1, rTMP1, r7F7F +- andc rWORD1, rTMP4, rTMP1 ++ andc rTMP3, rTMP4, rTMP1 + b L(done0) + + L(done1): + and rTMP1, r7F7F, rWORD1 + subi rSTR, rSTR, 4 + add rTMP1, rTMP1, r7F7F +- andc rWORD1, rTMP2, rTMP1 ++ andc rTMP3, rTMP2, rTMP1 + + /* When we get to here, rSTR points to the first word in the string that +- contains a zero byte, and the most significant set bit in rWORD1 is in that +- byte. */ ++ contains a zero byte, and rTMP3 has 0x80 for bytes that are zero, ++ and 0x00 otherwise. */ + L(done0): +- cntlzw rTMP3, rWORD1 ++ cntlzw rTMP3, rTMP3 + subf rTMP1, rRTN, rSTR + srwi rTMP3, rTMP3, 3 + add rRTN, rTMP1, rTMP3 + /* GKM FIXME: check high bound. */ + blr ++#else ++ ++L(done0): ++ addi rTMP1, rTMP3, -1 /* Form a mask from trailing zeros. */ ++ andc rTMP1, rTMP1, rTMP3 ++ cntlzw rTMP1, rTMP1 /* Count bits not in the mask. */ ++ subf rTMP3, rRTN, rSTR ++ subfic rTMP1, rTMP1, 32-7 ++ srwi rTMP1, rTMP1, 3 ++ add rRTN, rTMP1, rTMP3 ++ blr ++ ++L(done1): ++ addi rTMP3, rTMP1, -1 ++ andc rTMP3, rTMP3, rTMP1 ++ cntlzw rTMP3, rTMP3 ++ subf rTMP1, rRTN, rSTR ++ subfic rTMP3, rTMP3, 32-7-32 ++ srawi rTMP3, rTMP3, 3 ++ add rRTN, rTMP1, rTMP3 ++ blr ++#endif ++ + END (BP_SYM (strlen)) + libc_hidden_builtin_def (strlen) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strlen.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strlen.S 2014-05-28 12:28:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strlen.S 2014-05-28 12:28:45.000000000 -0500 +@@ -32,7 +32,11 @@ + with cmpb. */ + li r5,-1 /* MASK = 0xffffffffffffffff. */ + ld r12,0(r4) /* Load doubleword from memory. */ ++#ifdef __LITTLE_ENDIAN__ ++ sld r5,r5,r6 ++#else + srd r5,r5,r6 /* MASK = MASK >> padding. */ ++#endif + orc r9,r12,r5 /* Mask bits that are not part of the string. */ + cmpb r10,r9,r0 /* Check for null bytes in DWORD1. */ + cmpdi cr7,r10,0 /* If r10 == 0, no null's have been found. */ +@@ -50,9 +54,6 @@ + cmpb r10,r12,r0 + cmpdi cr7,r10,0 + bne cr7,L(done) +- b L(loop) /* We branch here (rather than falling through) +- to skip the nops due to heavy alignment +- of the loop below. */ + + /* Main loop to look for the end of the string. Since it's a + small loop (< 8 instructions), align it to 32-bytes. */ +@@ -89,9 +90,15 @@ + 0xff in the same position as the null byte in the original + doubleword from the string. Use that to calculate the length. */ + L(done): +- cntlzd r0,r10 /* Count leading zeroes before the match. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi r9, r10, -1 /* Form a mask from trailing zeros. */ ++ andc r9, r9, r10 ++ popcntd r0, r9 /* Count the bits in the mask. */ ++#else ++ cntlzd r0,r10 /* Count leading zeros before the match. */ ++#endif + subf r5,r3,r4 +- srdi r0,r0,3 /* Convert leading zeroes to bytes. */ ++ srdi r0,r0,3 /* Convert leading/trailing zeros to bytes. */ + add r3,r5,r0 /* Compute final length. */ + blr + END (BP_SYM (strlen)) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strlen.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strlen.S 2014-05-28 12:28:44.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strlen.S 2014-05-28 12:38:17.000000000 -0500 +@@ -31,7 +31,12 @@ + 1 is subtracted you get a value in the range 0x00-0x7f, none of which + have their high bit set. The expression here is + (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when +- there were no 0x00 bytes in the word. ++ there were no 0x00 bytes in the word. You get 0x80 in bytes that ++ match, but possibly false 0x80 matches in the next more significant ++ byte to a true match due to carries. For little-endian this is ++ of no consequence since the least significant match is the one ++ we're interested in, but big-endian needs method 2 to find which ++ byte matches. + + 2) Given a word 'x', we can test to see _which_ byte was zero by + calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f). +@@ -64,7 +69,7 @@ + Answer: + 1) Added a Data Cache Block Touch early to prefetch the first 128 + byte cache line. Adding dcbt instructions to the loop would not be +- effective since most strings will be shorter than the cache line.*/ ++ effective since most strings will be shorter than the cache line. */ + + /* Some notes on register usage: Under the SVR4 ABI, we can use registers + 0 and 3 through 12 (so long as we don't call any procedures) without +@@ -80,7 +85,7 @@ + ENTRY (BP_SYM (strlen)) + CALL_MCOUNT 1 + +-#define rTMP1 r0 ++#define rTMP4 r0 + #define rRTN r3 /* incoming STR arg, outgoing result */ + #define rSTR r4 /* current string position */ + #define rPADN r5 /* number of padding bits we prepend to the +@@ -90,9 +95,9 @@ + #define rWORD1 r8 /* current string doubleword */ + #define rWORD2 r9 /* next string doubleword */ + #define rMASK r9 /* mask for first string doubleword */ +-#define rTMP2 r10 +-#define rTMP3 r11 +-#define rTMP4 r12 ++#define rTMP1 r10 ++#define rTMP2 r11 ++#define rTMP3 r12 + + /* Note: The Bounded pointer support in this code is broken. This code + was inherited from PPC32 and that support was never completed. +@@ -109,30 +114,36 @@ + addi r7F7F, r7F7F, 0x7f7f + li rMASK, -1 + insrdi r7F7F, r7F7F, 32, 0 +-/* That's the setup done, now do the first pair of doublewords. +- We make an exception and use method (2) on the first two doublewords, +- to reduce overhead. */ +- srd rMASK, rMASK, rPADN ++/* We use method (2) on the first two doublewords, because rFEFE isn't ++ required which reduces setup overhead. Also gives a faster return ++ for small strings on big-endian due to needing to recalculate with ++ method (2) anyway. */ ++#ifdef __LITTLE_ENDIAN__ ++ sld rMASK, rMASK, rPADN ++#else ++ srd rMASK, rMASK, rPADN ++#endif + and rTMP1, r7F7F, rWORD1 + or rTMP2, r7F7F, rWORD1 + lis rFEFE, -0x101 + add rTMP1, rTMP1, r7F7F + addi rFEFE, rFEFE, -0x101 +- nor rTMP1, rTMP2, rTMP1 +- and. rWORD1, rTMP1, rMASK ++ nor rTMP3, rTMP2, rTMP1 ++ and. rTMP3, rTMP3, rMASK + mtcrf 0x01, rRTN + bne L(done0) +- sldi rTMP1, rFEFE, 32 +- add rFEFE, rFEFE, rTMP1 ++ sldi rTMP1, rFEFE, 32 ++ add rFEFE, rFEFE, rTMP1 + /* Are we now aligned to a doubleword boundary? */ + bt 28, L(loop) + + /* Handle second doubleword of pair. */ ++/* Perhaps use method (1) here for little-endian, saving one instruction? */ + ldu rWORD1, 8(rSTR) + and rTMP1, r7F7F, rWORD1 + or rTMP2, r7F7F, rWORD1 + add rTMP1, rTMP1, r7F7F +- nor. rWORD1, rTMP2, rTMP1 ++ nor. rTMP3, rTMP2, rTMP1 + bne L(done0) + + /* The loop. */ +@@ -146,29 +157,53 @@ + add rTMP3, rFEFE, rWORD2 + nor rTMP4, r7F7F, rWORD2 + bne L(done1) +- and. rTMP1, rTMP3, rTMP4 ++ and. rTMP3, rTMP3, rTMP4 + beq L(loop) + ++#ifndef __LITTLE_ENDIAN__ + and rTMP1, r7F7F, rWORD2 + add rTMP1, rTMP1, r7F7F +- andc rWORD1, rTMP4, rTMP1 ++ andc rTMP3, rTMP4, rTMP1 + b L(done0) + + L(done1): + and rTMP1, r7F7F, rWORD1 + subi rSTR, rSTR, 8 + add rTMP1, rTMP1, r7F7F +- andc rWORD1, rTMP2, rTMP1 ++ andc rTMP3, rTMP2, rTMP1 + + /* When we get to here, rSTR points to the first doubleword in the string that +- contains a zero byte, and the most significant set bit in rWORD1 is in that +- byte. */ ++ contains a zero byte, and rTMP3 has 0x80 for bytes that are zero, and 0x00 ++ otherwise. */ + L(done0): +- cntlzd rTMP3, rWORD1 ++ cntlzd rTMP3, rTMP3 + subf rTMP1, rRTN, rSTR + srdi rTMP3, rTMP3, 3 + add rRTN, rTMP1, rTMP3 + /* GKM FIXME: check high bound. */ + blr ++#else ++ ++L(done0): ++ addi rTMP1, rTMP3, -1 /* Form a mask from trailing zeros. */ ++ andc rTMP1, rTMP1, rTMP3 ++ cntlzd rTMP1, rTMP1 /* Count bits not in the mask. */ ++ subf rTMP3, rRTN, rSTR ++ subfic rTMP1, rTMP1, 64-7 ++ srdi rTMP1, rTMP1, 3 ++ add rRTN, rTMP1, rTMP3 ++ blr ++ ++L(done1): ++ addi rTMP3, rTMP1, -1 ++ andc rTMP3, rTMP3, rTMP1 ++ cntlzd rTMP3, rTMP3 ++ subf rTMP1, rRTN, rSTR ++ subfic rTMP3, rTMP3, 64-7-64 ++ sradi rTMP3, rTMP3, 3 ++ add rRTN, rTMP1, rTMP3 ++ blr ++#endif ++ + END (BP_SYM (strlen)) + libc_hidden_builtin_def (strlen) diff --git a/SOURCES/glibc-ppc64le-26.patch b/SOURCES/glibc-ppc64le-26.patch new file mode 100644 index 00000000..1a7dad76 --- /dev/null +++ b/SOURCES/glibc-ppc64le-26.patch @@ -0,0 +1,379 @@ +# commit 33ee81de05e83ce12f32a491270bb4c1611399c7 +# Author: Alan Modra +# Date: Sat Aug 17 18:40:48 2013 +0930 +# +# PowerPC LE strnlen +# http://sourceware.org/ml/libc-alpha/2013-08/msg00098.html +# +# The existing strnlen code has a number of defects, so this patch is more +# than just adding little-endian support. The changes here are similar to +# those for memchr. +# +# * sysdeps/powerpc/powerpc64/power7/strnlen.S (strnlen): Add +# little-endian support. Remove unnecessary "are we done" tests. +# Handle "s" wrapping around zero and extremely large "size". +# Correct main loop count. Handle single left-over word from main +# loop inline rather than by using small_loop. Correct comments. +# Delete "zero" tail, use "end_max" instead. +# * sysdeps/powerpc/powerpc32/power7/strnlen.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strnlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strnlen.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strnlen.S 2014-05-28 12:40:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strnlen.S 2014-05-28 12:44:52.000000000 -0500 +@@ -30,51 +30,47 @@ + add r7,r3,r4 /* Calculate the last acceptable address. */ + cmplwi r4,16 + li r0,0 /* Word with null chars. */ ++ addi r7,r7,-1 + ble L(small_range) + +- cmplw cr7,r3,r7 /* Is the address equal or less than r3? If +- it's equal or less, it means size is either 0 +- or a negative number. */ +- ble cr7,L(proceed) +- +- li r7,-1 /* Make r11 the biggest if r4 <= 0. */ +-L(proceed): + rlwinm r6,r3,3,27,28 /* Calculate padding. */ + lwz r12,0(r8) /* Load word from memory. */ + cmpb r10,r12,r0 /* Check for null bytes in DWORD1. */ ++#ifdef __LITTLE_ENDIAN__ ++ srw r10,r10,r6 ++ slw r10,r10,r6 ++#else + slw r10,r10,r6 + srw r10,r10,r6 ++#endif + cmplwi cr7,r10,0 /* If r10 == 0, no null's have been found. */ + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,4 +- cmplw cr6,r9,r7 +- bge cr6,L(end_max) +- ++ clrrwi r7,r7,2 /* Address of last word. */ + mtcrf 0x01,r8 + /* Are we now aligned to a doubleword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ + + bt 29,L(loop_setup) + +- /* Handle DWORD2 of pair. */ ++ /* Handle WORD2 of pair. */ + lwzu r12,4(r8) + cmpb r10,r12,r0 + cmplwi cr7,r10,0 + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,4 +- cmplw cr6,r9,r7 +- bge cr6,L(end_max) +- + L(loop_setup): +- sub r5,r7,r9 ++ /* The last word we want to read in the loop below is the one ++ containing the last byte of the string, ie. the word at ++ (s + size - 1) & ~3, or r7. The first word read is at ++ r8 + 4, we read 2 * cnt words, so the last word read will ++ be at r8 + 4 + 8 * cnt - 4. Solving for cnt gives ++ cnt = (r7 - r8) / 8 */ ++ sub r5,r7,r8 + srwi r6,r5,3 /* Number of loop iterations. */ + mtctr r6 /* Setup the counter. */ +- b L(loop) +- /* Main loop to look for the null byte backwards in the string. Since ++ ++ /* Main loop to look for the null byte in the string. Since + it's a small loop (< 8 instructions), align it to 32-bytes. */ + .p2align 5 + L(loop): +@@ -90,15 +86,18 @@ + cmplwi cr7,r5,0 + bne cr7,L(found) + bdnz L(loop) +- /* We're here because the counter reached 0, and that means we +- didn't have any matches for null in the whole range. Just return +- the original size. */ +- addi r9,r8,4 +- cmplw cr6,r9,r7 +- blt cr6,L(loop_small) ++ ++ /* We may have one more word to read. */ ++ cmplw cr6,r8,r7 ++ beq cr6,L(end_max) ++ ++ lwzu r12,4(r8) ++ cmpb r10,r12,r0 ++ cmplwi cr6,r10,0 ++ bne cr6,L(done) + + L(end_max): +- sub r3,r7,r3 ++ mr r3,r4 + blr + + /* OK, one (or both) of the words contains a null byte. Check +@@ -123,49 +122,56 @@ + We need to make sure the null char is *before* the end of the + range. */ + L(done): +- cntlzw r0,r10 /* Count leading zeroes before the match. */ +- srwi r0,r0,3 /* Convert leading zeroes to bytes. */ +- add r9,r8,r0 +- sub r6,r9,r3 /* Length until the match. */ +- cmplw r9,r7 +- bgt L(end_max) +- mr r3,r6 +- blr +- +- .align 4 +-L(zero): +- li r3,0 ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r10,-1 ++ andc r0,r0,r10 ++ popcntw r0,r0 ++#else ++ cntlzw r0,r10 /* Count leading zeros before the match. */ ++#endif ++ sub r3,r8,r3 ++ srwi r0,r0,3 /* Convert leading/trailing zeros to bytes. */ ++ add r3,r3,r0 /* Length until the match. */ ++ cmplw r3,r4 ++ blelr ++ mr r3,r4 + blr + +-/* Deals with size <= 32. */ ++/* Deals with size <= 16. */ + .align 4 + L(small_range): + cmplwi r4,0 +- beq L(zero) ++ beq L(end_max) ++ ++ clrrwi r7,r7,2 /* Address of last word. */ + + rlwinm r6,r3,3,27,28 /* Calculate padding. */ + lwz r12,0(r8) /* Load word from memory. */ + cmpb r10,r12,r0 /* Check for null bytes in WORD1. */ ++#ifdef __LITTLE_ENDIAN__ ++ srw r10,r10,r6 ++ slw r10,r10,r6 ++#else + slw r10,r10,r6 + srw r10,r10,r6 ++#endif + cmplwi cr7,r10,0 + bne cr7,L(done) + +- addi r9,r8,4 +- cmplw r9,r7 +- bge L(end_max) +- b L(loop_small) ++ cmplw r8,r7 ++ beq L(end_max) + + .p2align 5 + L(loop_small): + lwzu r12,4(r8) + cmpb r10,r12,r0 +- addi r9,r8,4 + cmplwi cr6,r10,0 + bne cr6,L(done) +- cmplw r9,r7 +- bge L(end_max) +- b L(loop_small) ++ cmplw r8,r7 ++ bne L(loop_small) ++ mr r3,r4 ++ blr ++ + END (BP_SYM (__strnlen)) + weak_alias (BP_SYM (__strnlen), BP_SYM(strnlen)) + libc_hidden_builtin_def (strnlen) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strnlen.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strnlen.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strnlen.S 2014-05-28 12:40:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strnlen.S 2014-05-28 13:24:41.000000000 -0500 +@@ -26,33 +26,29 @@ + ENTRY (BP_SYM (__strnlen)) + CALL_MCOUNT 2 + dcbt 0,r3 +- clrrdi r8,r3,3 ++ clrrdi r8,r3,3 + add r7,r3,r4 /* Calculate the last acceptable address. */ + cmpldi r4,32 + li r0,0 /* Doubleword with null chars. */ ++ addi r7,r7,-1 ++ + /* If we have less than 33 bytes to search, skip to a faster code. */ + ble L(small_range) + +- cmpld cr7,r3,r7 /* Is the address equal or less than r3? If +- it's equal or less, it means size is either 0 +- or a negative number. */ +- ble cr7,L(proceed) +- +- li r7,-1 /* Make r11 the biggest if r4 <= 0. */ +-L(proceed): + rlwinm r6,r3,3,26,28 /* Calculate padding. */ + ld r12,0(r8) /* Load doubleword from memory. */ + cmpb r10,r12,r0 /* Check for null bytes in DWORD1. */ ++#ifdef __LITTLE_ENDIAN__ ++ srd r10,r10,r6 ++ sld r10,r10,r6 ++#else + sld r10,r10,r6 + srd r10,r10,r6 ++#endif + cmpldi cr7,r10,0 /* If r10 == 0, no null's have been found. */ + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,8 +- cmpld cr6,r9,r7 +- bge cr6,L(end_max) +- ++ clrrdi r7,r7,3 /* Address of last doubleword. */ + mtcrf 0x01,r8 + /* Are we now aligned to a quadword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ +@@ -65,17 +61,18 @@ + cmpldi cr7,r10,0 + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,8 +- cmpld cr6,r9,r7 +- bge cr6,L(end_max) +- + L(loop_setup): +- sub r5,r7,r9 ++ /* The last dword we want to read in the loop below is the one ++ containing the last byte of the string, ie. the dword at ++ (s + size - 1) & ~7, or r7. The first dword read is at ++ r8 + 8, we read 2 * cnt dwords, so the last dword read will ++ be at r8 + 8 + 16 * cnt - 8. Solving for cnt gives ++ cnt = (r7 - r8) / 16 */ ++ sub r5,r7,r8 + srdi r6,r5,4 /* Number of loop iterations. */ + mtctr r6 /* Setup the counter. */ +- b L(loop) +- /* Main loop to look for the null byte backwards in the string. Since ++ ++ /* Main loop to look for the null byte in the string. Since + it's a small loop (< 8 instructions), align it to 32-bytes. */ + .p2align 5 + L(loop): +@@ -91,15 +88,18 @@ + cmpldi cr7,r5,0 + bne cr7,L(found) + bdnz L(loop) +- /* We're here because the counter reached 0, and that means we +- didn't have any matches for null in the whole range. Just return +- the original size. */ +- addi r9,r8,8 +- cmpld cr6,r9,r7 +- blt cr6,L(loop_small) ++ ++ /* We may have one more dword to read. */ ++ cmpld cr6,r8,r7 ++ beq cr6,L(end_max) ++ ++ ldu r12,8(r8) ++ cmpb r10,r12,r0 ++ cmpldi cr6,r10,0 ++ bne cr6,L(done) + + L(end_max): +- sub r3,r7,r3 ++ mr r3,r4 + blr + + /* OK, one (or both) of the doublewords contains a null byte. Check +@@ -121,52 +121,59 @@ + /* r10 has the output of the cmpb instruction, that is, it contains + 0xff in the same position as the null byte in the original + doubleword from the string. Use that to calculate the length. +- We need to make sure the null char is *before* the start of the +- range (since we're going backwards). */ ++ We need to make sure the null char is *before* the end of the ++ range. */ + L(done): +- cntlzd r0,r10 /* Count leading zeroes before the match. */ +- srdi r0,r0,3 /* Convert leading zeroes to bytes. */ +- add r9,r8,r0 +- sub r6,r9,r3 /* Length until the match. */ +- cmpld r9,r7 +- bgt L(end_max) +- mr r3,r6 +- blr +- +- .align 4 +-L(zero): +- li r3,0 ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r10,-1 ++ andc r0,r0,r10 ++ popcntd r0,r0 ++#else ++ cntlzd r0,r10 /* Count leading zeros before the match. */ ++#endif ++ sub r3,r8,r3 ++ srdi r0,r0,3 /* Convert leading/trailing zeros to bytes. */ ++ add r3,r3,r0 /* Length until the match. */ ++ cmpld r3,r4 ++ blelr ++ mr r3,r4 + blr + + /* Deals with size <= 32. */ + .align 4 + L(small_range): + cmpldi r4,0 +- beq L(zero) ++ beq L(end_max) ++ ++ clrrdi r7,r7,3 /* Address of last doubleword. */ + + rlwinm r6,r3,3,26,28 /* Calculate padding. */ +- ld r12,0(r8) /* Load word from memory. */ ++ ld r12,0(r8) /* Load doubleword from memory. */ + cmpb r10,r12,r0 /* Check for null bytes in DWORD1. */ ++#ifdef __LITTLE_ENDIAN__ ++ srd r10,r10,r6 ++ sld r10,r10,r6 ++#else + sld r10,r10,r6 + srd r10,r10,r6 ++#endif + cmpldi cr7,r10,0 + bne cr7,L(done) + +- addi r9,r8,8 +- cmpld r9,r7 +- bge L(end_max) +- b L(loop_small) ++ cmpld r8,r7 ++ beq L(end_max) + + .p2align 5 + L(loop_small): + ldu r12,8(r8) + cmpb r10,r12,r0 +- addi r9,r8,8 + cmpldi cr6,r10,0 + bne cr6,L(done) +- cmpld r9,r7 +- bge L(end_max) +- b L(loop_small) ++ cmpld r8,r7 ++ bne L(loop_small) ++ mr r3,r4 ++ blr ++ + END (BP_SYM (__strnlen)) + weak_alias (BP_SYM (__strnlen), BP_SYM(strnlen)) + libc_hidden_builtin_def (strnlen) diff --git a/SOURCES/glibc-ppc64le-27.patch b/SOURCES/glibc-ppc64le-27.patch new file mode 100644 index 00000000..f8d4f25c --- /dev/null +++ b/SOURCES/glibc-ppc64le-27.patch @@ -0,0 +1,861 @@ +# commit 8a7413f9b036da83ffde491a37d9d2340bc321a7 +# Author: Alan Modra +# Date: Sat Aug 17 18:41:17 2013 +0930 +# +# PowerPC LE strcmp and strncmp +# http://sourceware.org/ml/libc-alpha/2013-08/msg00099.html +# +# More little-endian support. I leave the main strcmp loops unchanged, +# (well, except for renumbering rTMP to something other than r0 since +# it's needed in an addi insn) and modify the tail for little-endian. +# +# I noticed some of the big-endian tail code was a little untidy so have +# cleaned that up too. +# +# * sysdeps/powerpc/powerpc64/strcmp.S (rTMP2): Define as r0. +# (rTMP): Define as r11. +# (strcmp): Add little-endian support. Optimise tail. +# * sysdeps/powerpc/powerpc32/strcmp.S: Similarly. +# * sysdeps/powerpc/powerpc64/strncmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/strncmp.S: Likewise. +# * sysdeps/powerpc/powerpc64/power4/strncmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/power4/strncmp.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/strncmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/strncmp.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/strncmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/strncmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/strncmp.S 2014-05-28 13:27:02.000000000 -0500 +@@ -26,7 +26,7 @@ + + EALIGN (BP_SYM(strncmp), 4, 0) + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -42,6 +42,7 @@ + #define r7F7F r9 /* constant 0x7f7f7f7f */ + #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */ + #define rBITDIF r11 /* bits that differ in s1 & s2 words */ ++#define rTMP r12 + + dcbt 0,rSTR1 + or rTMP, rSTR2, rSTR1 +@@ -80,12 +81,45 @@ + we don't compare two strings as different because of gunk beyond + the end of the strings... */ + ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ slwi rTMP, rTMP, 1 ++ addi rTMP2, rTMP, -1 ++ andc rTMP2, rTMP2, rTMP ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rldimi rTMP2, rWORD2, 24, 32 ++ rldimi rTMP, rWORD1, 24, 32 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr+ ++ ori rRTN, rTMP2, 1 ++ blr ++ ++L(different): ++ lwz rWORD1, -4(rSTR1) ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rldimi rTMP2, rWORD2, 24, 32 ++ rldimi rTMP, rWORD1, 24, 32 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr+ ++ ori rRTN, rTMP2, 1 ++ blr ++ ++#else + L(endstring): + and rTMP, r7F7F, rWORD1 + beq cr1, L(equal) + add rTMP, rTMP, r7F7F + xor. rBITDIF, rWORD1, rWORD2 +- + andc rNEG, rNEG, rTMP + blt- L(highbit) + cntlzw rBITDIF, rBITDIF +@@ -93,28 +127,20 @@ + addi rNEG, rNEG, 7 + cmpw cr1, rNEG, rBITDIF + sub rRTN, rWORD1, rWORD2 +- blt- cr1, L(equal) +- srawi rRTN, rRTN, 31 +- ori rRTN, rRTN, 1 +- blr ++ bgelr+ cr1 + L(equal): + li rRTN, 0 + blr + + L(different): +- lwzu rWORD1, -4(rSTR1) ++ lwz rWORD1, -4(rSTR1) + xor. rBITDIF, rWORD1, rWORD2 + sub rRTN, rWORD1, rWORD2 +- blt- L(highbit) +- srawi rRTN, rRTN, 31 +- ori rRTN, rRTN, 1 +- blr ++ bgelr+ + L(highbit): +- srwi rWORD2, rWORD2, 24 +- srwi rWORD1, rWORD1, 24 +- sub rRTN, rWORD1, rWORD2 ++ ori rRTN, rWORD2, 1 + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strncmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strncmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strncmp.S 2014-05-28 13:27:02.000000000 -0500 +@@ -28,7 +28,7 @@ + + EALIGN (BP_SYM(strncmp),5,0) + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -44,6 +44,7 @@ + #define r7F7F r9 /* constant 0x7f7f7f7f */ + #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */ + #define rBITDIF r11 /* bits that differ in s1 & s2 words */ ++#define rTMP r12 + + dcbt 0,rSTR1 + nop +@@ -83,13 +84,45 @@ + /* OK. We've hit the end of the string. We need to be careful that + we don't compare two strings as different because of gunk beyond + the end of the strings... */ ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ slwi rTMP, rTMP, 1 ++ addi rTMP2, rTMP, -1 ++ andc rTMP2, rTMP2, rTMP ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rldimi rTMP2, rWORD2, 24, 32 ++ rldimi rTMP, rWORD1, 24, 32 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr ++ ori rRTN, rTMP2, 1 ++ blr ++ ++L(different): ++ lwz rWORD1, -4(rSTR1) ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rldimi rTMP2, rWORD2, 24, 32 ++ rldimi rTMP, rWORD1, 24, 32 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr ++ ori rRTN, rTMP2, 1 ++ blr + ++#else + L(endstring): + and rTMP,r7F7F,rWORD1 + beq cr1,L(equal) + add rTMP,rTMP,r7F7F + xor. rBITDIF,rWORD1,rWORD2 +- + andc rNEG,rNEG,rTMP + blt L(highbit) + cntlzw rBITDIF,rBITDIF +@@ -97,28 +130,20 @@ + addi rNEG,rNEG,7 + cmpw cr1,rNEG,rBITDIF + sub rRTN,rWORD1,rWORD2 +- blt cr1,L(equal) +- srawi rRTN,rRTN,31 +- ori rRTN,rRTN,1 +- blr ++ bgelr cr1 + L(equal): + li rRTN,0 + blr + + L(different): +- lwzu rWORD1,-4(rSTR1) ++ lwz rWORD1,-4(rSTR1) + xor. rBITDIF,rWORD1,rWORD2 + sub rRTN,rWORD1,rWORD2 +- blt L(highbit) +- srawi rRTN,rRTN,31 +- ori rRTN,rRTN,1 +- blr ++ bgelr + L(highbit): +- srwi rWORD2,rWORD2,24 +- srwi rWORD1,rWORD1,24 +- sub rRTN,rWORD1,rWORD2 ++ ori rRTN, rWORD2, 1 + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcmp.S 2014-05-28 13:27:02.000000000 -0500 +@@ -26,7 +26,7 @@ + + EALIGN (BP_SYM (strcmp), 4, 0) + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -40,6 +40,7 @@ + #define r7F7F r8 /* constant 0x7f7f7f7f */ + #define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f) */ + #define rBITDIF r10 /* bits that differ in s1 & s2 words */ ++#define rTMP r11 + + CHECK_BOUNDS_LOW (rSTR1, rTMP, rHIGH1) + CHECK_BOUNDS_LOW (rSTR2, rTMP, rHIGH2) +@@ -64,10 +65,45 @@ + and. rTMP, rTMP, rNEG + cmpw cr1, rWORD1, rWORD2 + beq+ L(g0) +-L(endstring): ++ + /* OK. We've hit the end of the string. We need to be careful that + we don't compare two strings as different because of gunk beyond + the end of the strings... */ ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ addi rTMP2, rTMP, -1 ++ andc rTMP2, rTMP2, rTMP ++ rlwimi rTMP2, rTMP2, 1, 0, 30 ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rlwimi rTMP2, rWORD2, 24, 0, 7 ++ rlwimi rTMP, rWORD1, 24, 0, 7 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr+ ++ ori rRTN, rTMP2, 1 ++ blr ++ ++L(different): ++ lwz rWORD1, -4(rSTR1) ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rlwimi rTMP2, rWORD2, 24, 0, 7 ++ rlwimi rTMP, rWORD1, 24, 0, 7 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr+ ++ ori rRTN, rTMP2, 1 ++ blr ++ ++#else ++L(endstring): + and rTMP, r7F7F, rWORD1 + beq cr1, L(equal) + add rTMP, rTMP, r7F7F +@@ -94,7 +130,7 @@ + ori rRTN, rWORD2, 1 + /* GKM FIXME: check high bounds. */ + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strncmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strncmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strncmp.S 2014-05-28 13:27:02.000000000 -0500 +@@ -26,7 +26,7 @@ + + EALIGN (BP_SYM(strncmp), 4, 0) + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -40,6 +40,7 @@ + #define r7F7F r9 /* constant 0x7f7f7f7f */ + #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f) */ + #define rBITDIF r11 /* bits that differ in s1 & s2 words */ ++#define rTMP r12 + + dcbt 0,rSTR1 + or rTMP, rSTR2, rSTR1 +@@ -78,12 +79,45 @@ + we don't compare two strings as different because of gunk beyond + the end of the strings... */ + ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ slwi rTMP, rTMP, 1 ++ addi rTMP2, rTMP, -1 ++ andc rTMP2, rTMP2, rTMP ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rlwimi rTMP2, rWORD2, 24, 0, 7 ++ rlwimi rTMP, rWORD1, 24, 0, 7 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr+ ++ ori rRTN, rTMP2, 1 ++ blr ++ ++L(different): ++ lwz rWORD1, -4(rSTR1) ++ rlwinm rTMP2, rWORD2, 8, 0xffffffff /* Byte reverse word. */ ++ rlwinm rTMP, rWORD1, 8, 0xffffffff ++ rlwimi rTMP2, rWORD2, 24, 0, 7 ++ rlwimi rTMP, rWORD1, 24, 0, 7 ++ rlwimi rTMP2, rWORD2, 24, 16, 23 ++ rlwimi rTMP, rWORD1, 24, 16, 23 ++ xor. rBITDIF, rTMP, rTMP2 ++ sub rRTN, rTMP, rTMP2 ++ bgelr+ ++ ori rRTN, rTMP2, 1 ++ blr ++ ++#else + L(endstring): + and rTMP, r7F7F, rWORD1 + beq cr1, L(equal) + add rTMP, rTMP, r7F7F + xor. rBITDIF, rWORD1, rWORD2 +- + andc rNEG, rNEG, rTMP + blt- L(highbit) + cntlzw rBITDIF, rBITDIF +@@ -91,28 +125,20 @@ + addi rNEG, rNEG, 7 + cmpw cr1, rNEG, rBITDIF + sub rRTN, rWORD1, rWORD2 +- blt- cr1, L(equal) +- srawi rRTN, rRTN, 31 +- ori rRTN, rRTN, 1 +- blr ++ bgelr+ cr1 + L(equal): + li rRTN, 0 + blr + + L(different): +- lwzu rWORD1, -4(rSTR1) ++ lwz rWORD1, -4(rSTR1) + xor. rBITDIF, rWORD1, rWORD2 + sub rRTN, rWORD1, rWORD2 +- blt- L(highbit) +- srawi rRTN, rRTN, 31 +- ori rRTN, rRTN, 1 +- blr ++ bgelr+ + L(highbit): +- srwi rWORD2, rWORD2, 24 +- srwi rWORD1, rWORD1, 24 +- sub rRTN, rWORD1, rWORD2 ++ ori rRTN, rWORD2, 1 + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/strncmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/strncmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/strncmp.S 2014-05-28 13:27:02.000000000 -0500 +@@ -27,7 +27,7 @@ + EALIGN (BP_SYM(strncmp), 4, 0) + CALL_MCOUNT 3 + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -43,6 +43,7 @@ + #define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */ + #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ + #define rBITDIF r11 /* bits that differ in s1 & s2 words */ ++#define rTMP r12 + + dcbt 0,rSTR1 + or rTMP, rSTR2, rSTR1 +@@ -84,12 +85,59 @@ + we don't compare two strings as different because of gunk beyond + the end of the strings... */ + ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ addi rTMP2, rTMP, -1 ++ beq cr1, L(equal) ++ andc rTMP2, rTMP2, rTMP ++ rldimi rTMP2, rTMP2, 1, 0 ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ cmpd cr1, rWORD1, rWORD2 ++ beq cr1, L(equal) ++ xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */ ++ neg rNEG, rBITDIF ++ and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */ ++ cntlzd rNEG, rNEG /* bitcount of the bit. */ ++ andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */ ++ sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */ ++ sld rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt- L(highbit) ++ sradi rRTN, rRTN, 63 /* must return an int. */ ++ ori rRTN, rRTN, 1 ++ blr ++L(equal): ++ li rRTN, 0 ++ blr ++ ++L(different): ++ ld rWORD1, -8(rSTR1) ++ xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */ ++ neg rNEG, rBITDIF ++ and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */ ++ cntlzd rNEG, rNEG /* bitcount of the bit. */ ++ andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */ ++ sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */ ++ sld rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt- L(highbit) ++ sradi rRTN, rRTN, 63 ++ ori rRTN, rRTN, 1 ++ blr ++L(highbit): ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 ++ blr ++ ++#else + L(endstring): + and rTMP, r7F7F, rWORD1 + beq cr1, L(equal) + add rTMP, rTMP, r7F7F + xor. rBITDIF, rWORD1, rWORD2 +- + andc rNEG, rNEG, rTMP + blt- L(highbit) + cntlzd rBITDIF, rBITDIF +@@ -98,7 +146,7 @@ + cmpd cr1, rNEG, rBITDIF + sub rRTN, rWORD1, rWORD2 + blt- cr1, L(equal) +- sradi rRTN, rRTN, 63 ++ sradi rRTN, rRTN, 63 /* must return an int. */ + ori rRTN, rRTN, 1 + blr + L(equal): +@@ -106,7 +154,7 @@ + blr + + L(different): +- ldu rWORD1, -8(rSTR1) ++ ld rWORD1, -8(rSTR1) + xor. rBITDIF, rWORD1, rWORD2 + sub rRTN, rWORD1, rWORD2 + blt- L(highbit) +@@ -114,11 +162,10 @@ + ori rRTN, rRTN, 1 + blr + L(highbit): +- srdi rWORD2, rWORD2, 56 +- srdi rWORD1, rWORD1, 56 +- sub rRTN, rWORD1, rWORD2 ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strncmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strncmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strncmp.S 2014-05-28 13:27:02.000000000 -0500 +@@ -29,7 +29,7 @@ + EALIGN (BP_SYM(strncmp),5,0) + CALL_MCOUNT 3 + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -45,6 +45,7 @@ + #define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */ + #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ + #define rBITDIF r11 /* bits that differ in s1 & s2 words */ ++#define rTMP r12 + + dcbt 0,rSTR1 + nop +@@ -88,12 +89,57 @@ + we don't compare two strings as different because of gunk beyond + the end of the strings... */ + ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ addi rTMP2, rTMP, -1 ++ beq cr1, L(equal) ++ andc rTMP2, rTMP2, rTMP ++ rldimi rTMP2, rTMP2, 1, 0 ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ cmpd cr1, rWORD1, rWORD2 ++ beq cr1, L(equal) ++ cmpb rBITDIF, rWORD1, rWORD2 /* 0xff on equal bytes. */ ++ addi rNEG, rBITDIF, 1 ++ orc rNEG, rNEG, rBITDIF /* 0's below LS differing byte. */ ++ sldi rNEG, rNEG, 8 /* 1's above LS differing byte. */ ++ andc rWORD1, rWORD1, rNEG /* mask off MS bytes. */ ++ andc rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt L(highbit) ++ sradi rRTN, rRTN, 63 /* must return an int. */ ++ ori rRTN, rRTN, 1 ++ blr ++L(equal): ++ li rRTN, 0 ++ blr ++ ++L(different): ++ ld rWORD1, -8(rSTR1) ++ cmpb rBITDIF, rWORD1, rWORD2 /* 0xff on equal bytes. */ ++ addi rNEG, rBITDIF, 1 ++ orc rNEG, rNEG, rBITDIF /* 0's below LS differing byte. */ ++ sldi rNEG, rNEG, 8 /* 1's above LS differing byte. */ ++ andc rWORD1, rWORD1, rNEG /* mask off MS bytes. */ ++ andc rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt L(highbit) ++ sradi rRTN, rRTN, 63 ++ ori rRTN, rRTN, 1 ++ blr ++L(highbit): ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 ++ blr ++ ++#else + L(endstring): + and rTMP,r7F7F,rWORD1 + beq cr1,L(equal) + add rTMP,rTMP,r7F7F + xor. rBITDIF,rWORD1,rWORD2 +- + andc rNEG,rNEG,rTMP + blt L(highbit) + cntlzd rBITDIF,rBITDIF +@@ -102,7 +148,7 @@ + cmpd cr1,rNEG,rBITDIF + sub rRTN,rWORD1,rWORD2 + blt cr1,L(equal) +- sradi rRTN,rRTN,63 ++ sradi rRTN,rRTN,63 /* must return an int. */ + ori rRTN,rRTN,1 + blr + L(equal): +@@ -110,7 +156,7 @@ + blr + + L(different): +- ldu rWORD1,-8(rSTR1) ++ ld rWORD1,-8(rSTR1) + xor. rBITDIF,rWORD1,rWORD2 + sub rRTN,rWORD1,rWORD2 + blt L(highbit) +@@ -118,11 +164,10 @@ + ori rRTN,rRTN,1 + blr + L(highbit): +- srdi rWORD2,rWORD2,56 +- srdi rWORD1,rWORD1,56 +- sub rRTN,rWORD1,rWORD2 ++ sradi rRTN,rWORD2,63 ++ ori rRTN,rRTN,1 + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcmp.S 2014-05-28 13:37:15.000000000 -0500 +@@ -27,7 +27,7 @@ + EALIGN (BP_SYM(strcmp), 4, 0) + CALL_MCOUNT 2 + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -46,6 +46,7 @@ + #define r7F7F r8 /* constant 0x7f7f7f7f7f7f7f7f */ + #define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ + #define rBITDIF r10 /* bits that differ in s1 & s2 words */ ++#define rTMP r11 + + CHECK_BOUNDS_LOW (rSTR1, rTMP, rHIGH1) + CHECK_BOUNDS_LOW (rSTR2, rTMP, rHIGH2) +@@ -72,19 +73,66 @@ + ldu rWORD2, 8(rSTR2) + L(g1): add rTMP, rFEFE, rWORD1 + nor rNEG, r7F7F, rWORD1 +- + and. rTMP, rTMP, rNEG + cmpd cr1, rWORD1, rWORD2 + beq+ L(g0) +-L(endstring): ++ + /* OK. We've hit the end of the string. We need to be careful that + we don't compare two strings as different because of gunk beyond + the end of the strings... */ ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ addi rTMP2, rTMP, -1 ++ beq cr1, L(equal) ++ andc rTMP2, rTMP2, rTMP ++ rldimi rTMP2, rTMP2, 1, 0 ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ cmpd cr1, rWORD1, rWORD2 ++ beq cr1, L(equal) ++ xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */ ++ neg rNEG, rBITDIF ++ and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */ ++ cntlzd rNEG, rNEG /* bitcount of the bit. */ ++ andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */ ++ sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */ ++ sld rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt- L(highbit) ++ sradi rRTN, rRTN, 63 /* must return an int. */ ++ ori rRTN, rRTN, 1 ++ blr ++L(equal): ++ li rRTN, 0 ++ blr ++ ++L(different): ++ ld rWORD1, -8(rSTR1) ++ xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */ ++ neg rNEG, rBITDIF ++ and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */ ++ cntlzd rNEG, rNEG /* bitcount of the bit. */ ++ andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */ ++ sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */ ++ sld rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt- L(highbit) ++ sradi rRTN, rRTN, 63 ++ ori rRTN, rRTN, 1 ++ blr ++L(highbit): ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 ++ blr ++ ++#else ++L(endstring): + and rTMP, r7F7F, rWORD1 + beq cr1, L(equal) + add rTMP, rTMP, r7F7F + xor. rBITDIF, rWORD1, rWORD2 +- + andc rNEG, rNEG, rTMP + blt- L(highbit) + cntlzd rBITDIF, rBITDIF +@@ -93,7 +141,7 @@ + cmpd cr1, rNEG, rBITDIF + sub rRTN, rWORD1, rWORD2 + blt- cr1, L(equal) +- sradi rRTN, rRTN, 63 ++ sradi rRTN, rRTN, 63 /* must return an int. */ + ori rRTN, rRTN, 1 + blr + L(equal): +@@ -110,12 +158,11 @@ + ori rRTN, rRTN, 1 + blr + L(highbit): +- srdi rWORD2, rWORD2, 56 +- srdi rWORD1, rWORD1, 56 +- sub rRTN, rWORD1, rWORD2 ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 + /* GKM FIXME: check high bounds. */ + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strncmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strncmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strncmp.S 2014-05-28 13:26:59.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strncmp.S 2014-05-28 13:38:31.000000000 -0500 +@@ -27,7 +27,7 @@ + EALIGN (BP_SYM(strncmp), 4, 0) + CALL_MCOUNT 3 + +-#define rTMP r0 ++#define rTMP2 r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -41,6 +41,7 @@ + #define r7F7F r9 /* constant 0x7f7f7f7f7f7f7f7f */ + #define rNEG r10 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ + #define rBITDIF r11 /* bits that differ in s1 & s2 words */ ++#define rTMP r12 + + dcbt 0,rSTR1 + or rTMP, rSTR2, rSTR1 +@@ -81,13 +82,60 @@ + /* OK. We've hit the end of the string. We need to be careful that + we don't compare two strings as different because of gunk beyond + the end of the strings... */ +- ++ ++#ifdef __LITTLE_ENDIAN__ ++L(endstring): ++ addi rTMP2, rTMP, -1 ++ beq cr1, L(equal) ++ andc rTMP2, rTMP2, rTMP ++ rldimi rTMP2, rTMP2, 1, 0 ++ and rWORD2, rWORD2, rTMP2 /* Mask off gunk. */ ++ and rWORD1, rWORD1, rTMP2 ++ cmpd cr1, rWORD1, rWORD2 ++ beq cr1, L(equal) ++ xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */ ++ neg rNEG, rBITDIF ++ and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */ ++ cntlzd rNEG, rNEG /* bitcount of the bit. */ ++ andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */ ++ sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */ ++ sld rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt- L(highbit) ++ sradi rRTN, rRTN, 63 /* must return an int. */ ++ ori rRTN, rRTN, 1 ++ blr ++L(equal): ++ li rRTN, 0 ++ blr ++ ++L(different): ++ ld rWORD1, -8(rSTR1) ++ xor rBITDIF, rWORD1, rWORD2 /* rBITDIF has bits that differ. */ ++ neg rNEG, rBITDIF ++ and rNEG, rNEG, rBITDIF /* rNEG has LS bit that differs. */ ++ cntlzd rNEG, rNEG /* bitcount of the bit. */ ++ andi. rNEG, rNEG, 56 /* bitcount to LS byte that differs. */ ++ sld rWORD1, rWORD1, rNEG /* shift left to clear MS bytes. */ ++ sld rWORD2, rWORD2, rNEG ++ xor. rBITDIF, rWORD1, rWORD2 ++ sub rRTN, rWORD1, rWORD2 ++ blt- L(highbit) ++ sradi rRTN, rRTN, 63 ++ ori rRTN, rRTN, 1 ++ blr ++L(highbit): ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 ++ blr ++ ++#else + L(endstring): + and rTMP, r7F7F, rWORD1 + beq cr1, L(equal) + add rTMP, rTMP, r7F7F + xor. rBITDIF, rWORD1, rWORD2 +- + andc rNEG, rNEG, rTMP + blt- L(highbit) + cntlzd rBITDIF, rBITDIF +@@ -96,7 +144,7 @@ + cmpd cr1, rNEG, rBITDIF + sub rRTN, rWORD1, rWORD2 + blt- cr1, L(equal) +- sradi rRTN, rRTN, 63 ++ sradi rRTN, rRTN, 63 /* must return an int. */ + ori rRTN, rRTN, 1 + blr + L(equal): +@@ -104,7 +152,7 @@ + blr + + L(different): +- ldu rWORD1, -8(rSTR1) ++ ld rWORD1, -8(rSTR1) + xor. rBITDIF, rWORD1, rWORD2 + sub rRTN, rWORD1, rWORD2 + blt- L(highbit) +@@ -112,11 +160,10 @@ + ori rRTN, rRTN, 1 + blr + L(highbit): +- srdi rWORD2, rWORD2, 56 +- srdi rWORD1, rWORD1, 56 +- sub rRTN, rWORD1, rWORD2 ++ sradi rRTN, rWORD2, 63 ++ ori rRTN, rRTN, 1 + blr +- ++#endif + + /* Oh well. In this case, we just do a byte-by-byte comparison. */ + .align 4 diff --git a/SOURCES/glibc-ppc64le-28.patch b/SOURCES/glibc-ppc64le-28.patch new file mode 100644 index 00000000..e4451b1f --- /dev/null +++ b/SOURCES/glibc-ppc64le-28.patch @@ -0,0 +1,167 @@ +# commit 43b84013714c46e6dcae4a5564c5527777ad5e08 +# Author: Alan Modra +# Date: Sat Aug 17 18:45:31 2013 +0930 +# +# PowerPC LE strcpy +# http://sourceware.org/ml/libc-alpha/2013-08/msg00100.html +# +# The strcpy changes for little-endian are quite straight-forward, just +# a matter of rotating the last word differently. +# +# I'll note that the powerpc64 version of stpcpy is just begging to be +# converted to use 64-bit loads and stores.. +# +# * sysdeps/powerpc/powerpc64/strcpy.S: Add little-endian support: +# * sysdeps/powerpc/powerpc32/strcpy.S: Likewise. +# * sysdeps/powerpc/powerpc64/stpcpy.S: Likewise. +# * sysdeps/powerpc/powerpc32/stpcpy.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stpcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stpcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stpcpy.S 2014-05-28 13:40:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stpcpy.S 2014-05-28 13:40:01.000000000 -0500 +@@ -74,7 +74,22 @@ + + mr rALT, rWORD + /* We've hit the end of the string. Do the rest byte-by-byte. */ +-L(g1): rlwinm. rTMP, rALT, 8, 24, 31 ++L(g1): ++#ifdef __LITTLE_ENDIAN__ ++ rlwinm. rTMP, rALT, 0, 24, 31 ++ stbu rALT, 4(rDEST) ++ beqlr- ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stbu rTMP, 1(rDEST) ++ beqlr- ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stbu rTMP, 1(rDEST) ++ beqlr- ++ rlwinm rTMP, rALT, 8, 24, 31 ++ stbu rTMP, 1(rDEST) ++ blr ++#else ++ rlwinm. rTMP, rALT, 8, 24, 31 + stbu rTMP, 4(rDEST) + beqlr- + rlwinm. rTMP, rALT, 16, 24, 31 +@@ -87,6 +102,7 @@ + CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt) + STORE_RETURN_VALUE (rDEST) + blr ++#endif + + /* Oh well. In this case, we just do a byte-by-byte copy. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcpy.S 2014-05-28 13:40:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strcpy.S 2014-05-28 13:40:01.000000000 -0500 +@@ -78,7 +78,22 @@ + + mr rALT, rWORD + /* We've hit the end of the string. Do the rest byte-by-byte. */ +-L(g1): rlwinm. rTMP, rALT, 8, 24, 31 ++L(g1): ++#ifdef __LITTLE_ENDIAN__ ++ rlwinm. rTMP, rALT, 0, 24, 31 ++ stb rALT, 4(rDEST) ++ beqlr- ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stb rTMP, 5(rDEST) ++ beqlr- ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stb rTMP, 6(rDEST) ++ beqlr- ++ rlwinm rTMP, rALT, 8, 24, 31 ++ stb rTMP, 7(rDEST) ++ blr ++#else ++ rlwinm. rTMP, rALT, 8, 24, 31 + stb rTMP, 4(rDEST) + beqlr- + rlwinm. rTMP, rALT, 16, 24, 31 +@@ -90,6 +105,7 @@ + stb rALT, 7(rDEST) + /* GKM FIXME: check high bound. */ + blr ++#endif + + /* Oh well. In this case, we just do a byte-by-byte copy. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stpcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stpcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stpcpy.S 2014-05-28 13:40:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stpcpy.S 2014-05-28 13:40:01.000000000 -0500 +@@ -75,7 +75,22 @@ + + mr rALT, rWORD + /* We've hit the end of the string. Do the rest byte-by-byte. */ +-L(g1): rlwinm. rTMP, rALT, 8, 24, 31 ++L(g1): ++#ifdef __LITTLE_ENDIAN__ ++ rlwinm. rTMP, rALT, 0, 24, 31 ++ stbu rALT, 4(rDEST) ++ beqlr- ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stbu rTMP, 1(rDEST) ++ beqlr- ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stbu rTMP, 1(rDEST) ++ beqlr- ++ rlwinm rTMP, rALT, 8, 24, 31 ++ stbu rTMP, 1(rDEST) ++ blr ++#else ++ rlwinm. rTMP, rALT, 8, 24, 31 + stbu rTMP, 4(rDEST) + beqlr- + rlwinm. rTMP, rALT, 16, 24, 31 +@@ -88,6 +103,7 @@ + CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt) + STORE_RETURN_VALUE (rDEST) + blr ++#endif + + /* Oh well. In this case, we just do a byte-by-byte copy. */ + .align 4 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcpy.S 2014-05-28 13:40:01.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strcpy.S 2014-05-28 13:40:01.000000000 -0500 +@@ -90,6 +90,32 @@ + mr rALT, rWORD + /* We've hit the end of the string. Do the rest byte-by-byte. */ + L(g1): ++#ifdef __LITTLE_ENDIAN__ ++ extrdi. rTMP, rALT, 8, 56 ++ stb rALT, 8(rDEST) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 48 ++ stb rTMP, 9(rDEST) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 40 ++ stb rTMP, 10(rDEST) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 32 ++ stb rTMP, 11(rDEST) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 24 ++ stb rTMP, 12(rDEST) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 16 ++ stb rTMP, 13(rDEST) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 8 ++ stb rTMP, 14(rDEST) ++ beqlr- ++ extrdi rTMP, rALT, 8, 0 ++ stb rTMP, 15(rDEST) ++ blr ++#else + extrdi. rTMP, rALT, 8, 0 + stb rTMP, 8(rDEST) + beqlr- +@@ -114,6 +140,7 @@ + stb rALT, 15(rDEST) + /* GKM FIXME: check high bound. */ + blr ++#endif + + /* Oh well. In this case, we just do a byte-by-byte copy. */ + .align 4 diff --git a/SOURCES/glibc-ppc64le-29.patch b/SOURCES/glibc-ppc64le-29.patch new file mode 100644 index 00000000..ec5ee74f --- /dev/null +++ b/SOURCES/glibc-ppc64le-29.patch @@ -0,0 +1,642 @@ +# commit 664318c3eb07032e2bfcf47cb2aa3c89280c19e7 +# Author: Alan Modra +# Date: Sat Aug 17 18:46:05 2013 +0930 +# +# PowerPC LE strchr +# http://sourceware.org/ml/libc-alpha/2013-08/msg00101.html +# +# Adds little-endian support to optimised strchr assembly. I've also +# tweaked the big-endian code a little. In power7/strchr.S there's a +# check in the tail of the function that we didn't match 0 before +# finding a c match, done by comparing leading zero counts. It's just +# as valid, and quicker, to compare the raw output from cmpb. +# +# Another little tweak is to use rldimi/insrdi in place of rlwimi for +# the power7 strchr functions. Since rlwimi is cracked, it is a few +# cycles slower. rldimi can be used on the 32-bit power7 functions +# too. +# +# * sysdeps/powerpc/powerpc64/power7/strchr.S (strchr): Add little-endian +# support. Correct typos, formatting. Optimize tail. Use insrdi +# rather than rlwimi. +# * sysdeps/powerpc/powerpc32/power7/strchr.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/strchrnul.S (__strchrnul): Add +# little-endian support. Correct typos. +# * sysdeps/powerpc/powerpc32/power7/strchrnul.S: Likewise. Use insrdi +# rather than rlwimi. +# * sysdeps/powerpc/powerpc64/strchr.S (rTMP4, rTMP5): Define. Use +# in loop and entry code to keep "and." results. +# (strchr): Add little-endian support. Comment. Move cntlzd +# earlier in tail. +# * sysdeps/powerpc/powerpc32/strchr.S: Likewise. +# +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S +=================================================================== +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S.orig ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S +@@ -37,8 +37,8 @@ ENTRY (BP_SYM(strchr)) + beq cr7,L(null_match) + + /* Replicate byte to word. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 + + /* Now r4 has a word of c bytes and r0 has + a word of null bytes. */ +@@ -48,11 +48,17 @@ ENTRY (BP_SYM(strchr)) + + /* Move the words left and right to discard the bits that are + not part of the string and to bring them back as zeros. */ +- ++#ifdef __LITTLE_ENDIAN__ ++ srw r10,r10,r6 ++ srw r11,r11,r6 ++ slw r10,r10,r6 ++ slw r11,r11,r6 ++#else + slw r10,r10,r6 + slw r11,r11,r6 + srw r10,r10,r6 + srw r11,r11,r6 ++#endif + or r5,r10,r11 /* OR the results to speed things up. */ + cmpwi cr7,r5,0 /* If r5 == 0, no c or null bytes + have been found. */ +@@ -67,7 +73,7 @@ ENTRY (BP_SYM(strchr)) + + /* Handle WORD2 of pair. */ + lwzu r12,4(r8) +- cmpb r10,r12,r4 ++ cmpb r10,r12,r4 + cmpb r11,r12,r0 + or r5,r10,r11 + cmpwi cr7,r5,0 +@@ -102,22 +108,31 @@ L(loop): + bne cr6,L(done) + + /* The c/null byte must be in the second word. Adjust the address +- again and move the result of cmpb to r10 so we can calculate the +- pointer. */ ++ again and move the result of cmpb to r10/r11 so we can calculate ++ the pointer. */ + + mr r10,r6 + mr r11,r7 + addi r8,r8,4 + +- /* r5 has the output of the cmpb instruction, that is, it contains ++ /* r10/r11 have the output of the cmpb instructions, that is, + 0xff in the same position as the c/null byte in the original + word from the string. Use that to calculate the pointer. */ + L(done): +- cntlzw r4,r10 /* Count leading zeroes before c matches. */ +- cntlzw r0,r11 /* Count leading zeroes before null matches. */ +- cmplw cr7,r4,r0 ++#ifdef __LITTLE_ENDIAN__ ++ addi r3,r10,-1 ++ andc r3,r3,r10 ++ popcntw r0,r3 ++ addi r4,r11,-1 ++ andc r4,r4,r11 ++ cmplw cr7,r3,r4 ++ bgt cr7,L(no_match) ++#else ++ cntlzw r0,r10 /* Count leading zeros before c matches. */ ++ cmplw cr7,r11,r10 + bgt cr7,L(no_match) +- srwi r0,r4,3 /* Convert leading zeroes to bytes. */ ++#endif ++ srwi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of the matching c byte + or null in case c was not found. */ + blr +@@ -135,10 +150,14 @@ L(null_match): + cmpb r5,r12,r0 /* Compare each byte against null bytes. */ + + /* Move the words left and right to discard the bits that are +- not part of the string and to bring them back as zeros. */ +- ++ not part of the string and bring them back as zeros. */ ++#ifdef __LITTLE_ENDIAN__ ++ srw r5,r5,r6 ++ slw r5,r5,r6 ++#else + slw r5,r5,r6 + srw r5,r5,r6 ++#endif + cmpwi cr7,r5,0 /* If r10 == 0, no c or null bytes + have been found. */ + bne cr7,L(done_null) +@@ -193,7 +212,13 @@ L(loop_null): + 0xff in the same position as the null byte in the original + word from the string. Use that to calculate the pointer. */ + L(done_null): ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r5,-1 ++ andc r0,r0,r5 ++ popcntw r0,r0 ++#else + cntlzw r0,r5 /* Count leading zeros before the match. */ ++#endif + srwi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of the matching null byte. */ + blr +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S +=================================================================== +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S.orig ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S +@@ -29,8 +29,8 @@ ENTRY (BP_SYM(__strchrnul)) + clrrwi r8,r3,2 /* Align the address to word boundary. */ + + /* Replicate byte to word. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 + + rlwinm r6,r3,3,27,28 /* Calculate padding. */ + lwz r12,0(r8) /* Load word from memory. */ +@@ -45,10 +45,17 @@ ENTRY (BP_SYM(__strchrnul)) + + /* Move the words left and right to discard the bits that are + not part of the string and bring them back as zeros. */ ++#ifdef __LITTLE_ENDIAN__ ++ srw r10,r10,r6 ++ srw r9,r9,r6 ++ slw r10,r10,r6 ++ slw r9,r9,r6 ++#else + slw r10,r10,r6 + slw r9,r9,r6 + srw r10,r10,r6 + srw r9,r9,r6 ++#endif + or r5,r9,r10 /* OR the results to speed things up. */ + cmpwi cr7,r5,0 /* If r5 == 0, no c or null bytes + have been found. */ +@@ -56,7 +63,7 @@ ENTRY (BP_SYM(__strchrnul)) + + mtcrf 0x01,r8 + +- /* Are we now aligned to a quadword boundary? If so, skip to ++ /* Are we now aligned to a doubleword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ + + bt 29,L(loop) +@@ -78,7 +85,7 @@ L(loop): + single register for speed. This is an attempt + to speed up the null-checking process for bigger strings. */ + lwz r12,4(r8) +- lwzu r11,8(r8) ++ lwzu r11,8(r8) + cmpb r10,r12,r0 + cmpb r9,r12,r4 + cmpb r6,r11,r0 +@@ -97,9 +104,9 @@ L(loop): + addi r8,r8,-4 + bne cr6,L(done) + +- /* The c/null byte must be in the second word. Adjust the +- address again and move the result of cmpb to r10 so we can calculate +- the pointer. */ ++ /* The c/null byte must be in the second word. Adjust the address ++ again and move the result of cmpb to r5 so we can calculate the ++ pointer. */ + mr r5,r10 + addi r8,r8,4 + +@@ -107,7 +114,13 @@ L(loop): + 0xff in the same position as the c/null byte in the original + word from the string. Use that to calculate the pointer. */ + L(done): ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r5,-1 ++ andc r0,r0,r5 ++ popcntw r0,r0 ++#else + cntlzw r0,r5 /* Count leading zeros before the match. */ ++#endif + srwi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of matching c/null byte. */ + blr +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strchr.S +=================================================================== +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strchr.S.orig ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/strchr.S +@@ -44,6 +44,8 @@ ENTRY (BP_SYM (strchr)) + #define rIGN r10 /* number of bits we should ignore in the first word */ + #define rMASK r11 /* mask with the bits to ignore set to 0 */ + #define rTMP3 r12 ++#define rTMP4 rIGN ++#define rTMP5 rMASK + + CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2) + STORE_RETURN_BOUNDS (rTMP1, rTMP2) +@@ -59,53 +61,74 @@ ENTRY (BP_SYM (strchr)) + addi r7F7F, r7F7F, 0x7f7f + /* Test the first (partial?) word. */ + lwz rWORD, 0(rSTR) ++#ifdef __LITTLE_ENDIAN__ ++ slw rMASK, rMASK, rIGN ++#else + srw rMASK, rMASK, rIGN ++#endif + orc rWORD, rWORD, rMASK + add rTMP1, rFEFE, rWORD + nor rTMP2, r7F7F, rWORD +- and. rTMP1, rTMP1, rTMP2 ++ and. rTMP4, rTMP1, rTMP2 + xor rTMP3, rCHR, rWORD + orc rTMP3, rTMP3, rMASK + b L(loopentry) + + /* The loop. */ + +-L(loop):lwzu rWORD, 4(rSTR) +- and. rTMP1, rTMP1, rTMP2 ++L(loop): ++ lwzu rWORD, 4(rSTR) ++ and. rTMP5, rTMP1, rTMP2 + /* Test for 0. */ +- add rTMP1, rFEFE, rWORD +- nor rTMP2, r7F7F, rWORD ++ add rTMP1, rFEFE, rWORD /* x - 0x01010101. */ ++ nor rTMP2, r7F7F, rWORD /* ~(x | 0x7f7f7f7f) == ~x & 0x80808080. */ + bne L(foundit) +- and. rTMP1, rTMP1, rTMP2 ++ and. rTMP4, rTMP1, rTMP2 /* (x - 0x01010101) & ~x & 0x80808080. */ + /* Start test for the bytes we're looking for. */ + xor rTMP3, rCHR, rWORD + L(loopentry): + add rTMP1, rFEFE, rTMP3 + nor rTMP2, r7F7F, rTMP3 + beq L(loop) ++ + /* There is a zero byte in the word, but may also be a matching byte (either + before or after the zero byte). In fact, we may be looking for a +- zero byte, in which case we return a match. We guess that this hasn't +- happened, though. */ +-L(missed): +- and. rTMP1, rTMP1, rTMP2 ++ zero byte, in which case we return a match. */ ++ and. rTMP5, rTMP1, rTMP2 + li rRTN, 0 + STORE_RETURN_VALUE (rSTR) + beqlr +-/* It did happen. Decide which one was first... +- I'm not sure if this is actually faster than a sequence of +- rotates, compares, and branches (we use it anyway because it's shorter). */ ++/* At this point: ++ rTMP5 bytes are 0x80 for each match of c, 0 otherwise. ++ rTMP4 bytes are 0x80 for each match of 0, 0 otherwise. ++ But there may be false matches in the next most significant byte from ++ a true match due to carries. This means we need to recalculate the ++ matches using a longer method for big-endian. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi rTMP1, rTMP5, -1 ++ andc rTMP1, rTMP1, rTMP5 ++ cntlzw rCLZB, rTMP1 ++ addi rTMP2, rTMP4, -1 ++ andc rTMP2, rTMP2, rTMP4 ++ cmplw rTMP1, rTMP2 ++ bgtlr ++ subfic rCLZB, rCLZB, 32-7 ++#else ++/* I think we could reduce this by two instructions by keeping the "nor" ++ results from the loop for reuse here. See strlen.S tail. Similarly ++ one instruction could be pruned from L(foundit). */ + and rFEFE, r7F7F, rWORD +- or rMASK, r7F7F, rWORD ++ or rTMP5, r7F7F, rWORD + and rTMP1, r7F7F, rTMP3 +- or rIGN, r7F7F, rTMP3 ++ or rTMP4, r7F7F, rTMP3 + add rFEFE, rFEFE, r7F7F + add rTMP1, rTMP1, r7F7F +- nor rWORD, rMASK, rFEFE +- nor rTMP2, rIGN, rTMP1 ++ nor rWORD, rTMP5, rFEFE ++ nor rTMP2, rTMP4, rTMP1 ++ cntlzw rCLZB, rTMP2 + cmplw rWORD, rTMP2 + bgtlr +- cntlzw rCLZB, rTMP2 ++#endif + srwi rCLZB, rCLZB, 3 + add rRTN, rSTR, rCLZB + CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge) +@@ -113,13 +136,21 @@ L(missed): + blr + + L(foundit): ++#ifdef __LITTLE_ENDIAN__ ++ addi rTMP1, rTMP5, -1 ++ andc rTMP1, rTMP1, rTMP5 ++ cntlzw rCLZB, rTMP1 ++ subfic rCLZB, rCLZB, 32-7-32 ++ srawi rCLZB, rCLZB, 3 ++#else + and rTMP1, r7F7F, rTMP3 +- or rIGN, r7F7F, rTMP3 ++ or rTMP4, r7F7F, rTMP3 + add rTMP1, rTMP1, r7F7F +- nor rTMP2, rIGN, rTMP1 ++ nor rTMP2, rTMP4, rTMP1 + cntlzw rCLZB, rTMP2 + subi rSTR, rSTR, 4 + srwi rCLZB, rCLZB, 3 ++#endif + add rRTN, rSTR, rCLZB + CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, twlge) + STORE_RETURN_VALUE (rSTR) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchr.S +=================================================================== +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchr.S.orig ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchr.S +@@ -37,8 +37,8 @@ ENTRY (BP_SYM(strchr)) + beq cr7,L(null_match) + + /* Replicate byte to doubleword. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 + insrdi r4,r4,32,0 + + /* Now r4 has a doubleword of c bytes and r0 has +@@ -49,11 +49,17 @@ ENTRY (BP_SYM(strchr)) + + /* Move the doublewords left and right to discard the bits that are + not part of the string and bring them back as zeros. */ +- ++#ifdef __LITTLE_ENDIAN__ ++ srd r10,r10,r6 ++ srd r11,r11,r6 ++ sld r10,r10,r6 ++ sld r11,r11,r6 ++#else + sld r10,r10,r6 + sld r11,r11,r6 + srd r10,r10,r6 + srd r11,r11,r6 ++#endif + or r5,r10,r11 /* OR the results to speed things up. */ + cmpdi cr7,r5,0 /* If r5 == 0, no c or null bytes + have been found. */ +@@ -110,15 +116,24 @@ L(loop): + mr r11,r7 + addi r8,r8,8 + +- /* r5 has the output of the cmpb instruction, that is, it contains ++ /* r10/r11 have the output of the cmpb instructions, that is, + 0xff in the same position as the c/null byte in the original + doubleword from the string. Use that to calculate the pointer. */ + L(done): +- cntlzd r4,r10 /* Count leading zeroes before c matches. */ +- cntlzd r0,r11 /* Count leading zeroes before null matches. */ +- cmpld cr7,r4,r0 ++#ifdef __LITTLE_ENDIAN__ ++ addi r3,r10,-1 ++ andc r3,r3,r10 ++ popcntd r0,r3 ++ addi r4,r11,-1 ++ andc r4,r4,r11 ++ cmpld cr7,r3,r4 + bgt cr7,L(no_match) +- srdi r0,r4,3 /* Convert leading zeroes to bytes. */ ++#else ++ cntlzd r0,r10 /* Count leading zeros before c matches. */ ++ cmpld cr7,r11,r10 ++ bgt cr7,L(no_match) ++#endif ++ srdi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of the matching c byte + or null in case c was not found. */ + blr +@@ -137,9 +152,13 @@ L(null_match): + + /* Move the doublewords left and right to discard the bits that are + not part of the string and bring them back as zeros. */ +- ++#ifdef __LITTLE_ENDIAN__ ++ srd r5,r5,r6 ++ sld r5,r5,r6 ++#else + sld r5,r5,r6 + srd r5,r5,r6 ++#endif + cmpdi cr7,r5,0 /* If r10 == 0, no c or null bytes + have been found. */ + bne cr7,L(done_null) +@@ -194,7 +213,13 @@ L(loop_null): + 0xff in the same position as the null byte in the original + doubleword from the string. Use that to calculate the pointer. */ + L(done_null): ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r5,-1 ++ andc r0,r0,r5 ++ popcntd r0,r0 ++#else + cntlzd r0,r5 /* Count leading zeros before the match. */ ++#endif + srdi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of the matching null byte. */ + blr +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchrnul.S +=================================================================== +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchrnul.S.orig ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/strchrnul.S +@@ -29,8 +29,8 @@ ENTRY (BP_SYM(__strchrnul)) + clrrdi r8,r3,3 /* Align the address to doubleword boundary. */ + + /* Replicate byte to doubleword. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 + insrdi r4,r4,32,0 + + rlwinm r6,r3,3,26,28 /* Calculate padding. */ +@@ -46,10 +46,17 @@ ENTRY (BP_SYM(__strchrnul)) + + /* Move the doublewords left and right to discard the bits that are + not part of the string and to bring them back as zeros. */ ++#ifdef __LITTLE_ENDIAN__ ++ srd r10,r10,r6 ++ srd r9,r9,r6 ++ sld r10,r10,r6 ++ sld r9,r9,r6 ++#else + sld r10,r10,r6 + sld r9,r9,r6 + srd r10,r10,r6 + srd r9,r9,r6 ++#endif + or r5,r9,r10 /* OR the results to speed things up. */ + cmpdi cr7,r5,0 /* If r5 == 0, no c or null bytes + have been found. */ +@@ -99,7 +106,7 @@ L(loop): + bne cr6,L(done) + + /* The c/null byte must be in the second doubleword. Adjust the +- address again and move the result of cmpb to r10 so we can calculate ++ address again and move the result of cmpb to r5 so we can calculate + the pointer. */ + mr r5,r10 + addi r8,r8,8 +@@ -108,7 +115,13 @@ L(loop): + 0xff in the same position as the c/null byte in the original + doubleword from the string. Use that to calculate the pointer. */ + L(done): ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r5,-1 ++ andc r0,r0,r5 ++ popcntd r0,r0 ++#else + cntlzd r0,r5 /* Count leading zeros before the match. */ ++#endif + srdi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of matching c/null byte. */ + blr +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strchr.S +=================================================================== +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strchr.S.orig ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/strchr.S +@@ -50,14 +50,16 @@ ENTRY (BP_SYM (strchr)) + #define rIGN r10 /* number of bits we should ignore in the first word */ + #define rMASK r11 /* mask with the bits to ignore set to 0 */ + #define rTMP3 r12 ++#define rTMP4 rIGN ++#define rTMP5 rMASK + + CHECK_BOUNDS_LOW (rSTR, rTMP1, rTMP2) + STORE_RETURN_BOUNDS (rTMP1, rTMP2) + + dcbt 0,rRTN +- rlwimi rCHR, rCHR, 8, 16, 23 ++ insrdi rCHR, rCHR, 8, 48 + li rMASK, -1 +- rlwimi rCHR, rCHR, 16, 0, 15 ++ insrdi rCHR, rCHR, 16, 32 + rlwinm rIGN, rRTN, 3, 26, 28 + insrdi rCHR, rCHR, 32, 0 + lis rFEFE, -0x101 +@@ -70,53 +72,74 @@ ENTRY (BP_SYM (strchr)) + add rFEFE, rFEFE, rTMP1 + /* Test the first (partial?) word. */ + ld rWORD, 0(rSTR) ++#ifdef __LITTLE_ENDIAN__ ++ sld rMASK, rMASK, rIGN ++#else + srd rMASK, rMASK, rIGN ++#endif + orc rWORD, rWORD, rMASK + add rTMP1, rFEFE, rWORD + nor rTMP2, r7F7F, rWORD +- and. rTMP1, rTMP1, rTMP2 ++ and. rTMP4, rTMP1, rTMP2 + xor rTMP3, rCHR, rWORD + orc rTMP3, rTMP3, rMASK + b L(loopentry) + + /* The loop. */ + +-L(loop):ldu rWORD, 8(rSTR) +- and. rTMP1, rTMP1, rTMP2 ++L(loop): ++ ldu rWORD, 8(rSTR) ++ and. rTMP5, rTMP1, rTMP2 + /* Test for 0. */ +- add rTMP1, rFEFE, rWORD +- nor rTMP2, r7F7F, rWORD ++ add rTMP1, rFEFE, rWORD /* x - 0x01010101. */ ++ nor rTMP2, r7F7F, rWORD /* ~(x | 0x7f7f7f7f) == ~x & 0x80808080. */ + bne L(foundit) +- and. rTMP1, rTMP1, rTMP2 ++ and. rTMP4, rTMP1, rTMP2 /* (x - 0x01010101) & ~x & 0x80808080. */ + /* Start test for the bytes we're looking for. */ + xor rTMP3, rCHR, rWORD + L(loopentry): + add rTMP1, rFEFE, rTMP3 + nor rTMP2, r7F7F, rTMP3 + beq L(loop) ++ + /* There is a zero byte in the word, but may also be a matching byte (either + before or after the zero byte). In fact, we may be looking for a +- zero byte, in which case we return a match. We guess that this hasn't +- happened, though. */ +-L(missed): +- and. rTMP1, rTMP1, rTMP2 ++ zero byte, in which case we return a match. */ ++ and. rTMP5, rTMP1, rTMP2 + li rRTN, 0 + STORE_RETURN_VALUE (rSTR) + beqlr +-/* It did happen. Decide which one was first... +- I'm not sure if this is actually faster than a sequence of +- rotates, compares, and branches (we use it anyway because it's shorter). */ ++/* At this point: ++ rTMP5 bytes are 0x80 for each match of c, 0 otherwise. ++ rTMP4 bytes are 0x80 for each match of 0, 0 otherwise. ++ But there may be false matches in the next most significant byte from ++ a true match due to carries. This means we need to recalculate the ++ matches using a longer method for big-endian. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi rTMP1, rTMP5, -1 ++ andc rTMP1, rTMP1, rTMP5 ++ cntlzd rCLZB, rTMP1 ++ addi rTMP2, rTMP4, -1 ++ andc rTMP2, rTMP2, rTMP4 ++ cmpld rTMP1, rTMP2 ++ bgtlr ++ subfic rCLZB, rCLZB, 64-7 ++#else ++/* I think we could reduce this by two instructions by keeping the "nor" ++ results from the loop for reuse here. See strlen.S tail. Similarly ++ one instruction could be pruned from L(foundit). */ + and rFEFE, r7F7F, rWORD +- or rMASK, r7F7F, rWORD ++ or rTMP5, r7F7F, rWORD + and rTMP1, r7F7F, rTMP3 +- or rIGN, r7F7F, rTMP3 ++ or rTMP4, r7F7F, rTMP3 + add rFEFE, rFEFE, r7F7F + add rTMP1, rTMP1, r7F7F +- nor rWORD, rMASK, rFEFE +- nor rTMP2, rIGN, rTMP1 ++ nor rWORD, rTMP5, rFEFE ++ nor rTMP2, rTMP4, rTMP1 ++ cntlzd rCLZB, rTMP2 + cmpld rWORD, rTMP2 + bgtlr +- cntlzd rCLZB, rTMP2 ++#endif + srdi rCLZB, rCLZB, 3 + add rRTN, rSTR, rCLZB + CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge) +@@ -124,13 +147,21 @@ L(missed): + blr + + L(foundit): ++#ifdef __LITTLE_ENDIAN__ ++ addi rTMP1, rTMP5, -1 ++ andc rTMP1, rTMP1, rTMP5 ++ cntlzd rCLZB, rTMP1 ++ subfic rCLZB, rCLZB, 64-7-64 ++ sradi rCLZB, rCLZB, 3 ++#else + and rTMP1, r7F7F, rTMP3 +- or rIGN, r7F7F, rTMP3 ++ or rTMP4, r7F7F, rTMP3 + add rTMP1, rTMP1, r7F7F +- nor rTMP2, rIGN, rTMP1 ++ nor rTMP2, rTMP4, rTMP1 + cntlzd rCLZB, rTMP2 + subi rSTR, rSTR, 8 + srdi rCLZB, rCLZB, 3 ++#endif + add rRTN, rSTR, rCLZB + CHECK_BOUNDS_HIGH_RTN (rSTR, rTMP2, tdlge) + STORE_RETURN_VALUE (rSTR) diff --git a/SOURCES/glibc-ppc64le-30.patch b/SOURCES/glibc-ppc64le-30.patch new file mode 100644 index 00000000..68fa8261 --- /dev/null +++ b/SOURCES/glibc-ppc64le-30.patch @@ -0,0 +1,7383 @@ +# commit fe6e95d7171eba5f3e07848f081676fae4e86322 +# Author: Alan Modra +# Date: Sat Aug 17 18:46:47 2013 +0930 +# +# PowerPC LE memcmp +# http://sourceware.org/ml/libc-alpha/2013-08/msg00102.html +# +# This is a rather large patch due to formatting and renaming. The +# formatting changes were to make it possible to compare power7 and +# power4 versions of memcmp. Using different register defines came +# about while I was wrestling with the code, trying to find spare +# registers at one stage. I found it much simpler if we refer to a reg +# by the same name throughout a function, so it's better if short-term +# multiple use regs like rTMP are referred to using their register +# number. I made the cr field usage changes when attempting to reload +# rWORDn regs in the exit path to byte swap before comparing when +# little-endian. That proved a bad idea due to the pipelining involved +# in the main loop; Offsets to reload the regs were different first +# time around the loop.. Anyway, I left the cr field usage changes in +# place for consistency. +# +# Aside from these more-or-less cosmetic changes, I fixed a number of +# places where an early exit path restores regs unnecessarily, removed +# some dead code, and optimised one or two exits. +# +# * sysdeps/powerpc/powerpc64/power7/memcmp.S: Add little-endian support. +# Formatting. Consistently use rXXX register defines or rN defines. +# Use early exit labels that avoid restoring unused non-volatile regs. +# Make cr field use more consistent with rWORDn compares. Rename +# regs used as shift registers for unaligned loop, using rN defines +# for short lifetime/multiple use regs. +# * sysdeps/powerpc/powerpc64/power4/memcmp.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/memcmp.S: Likewise. Exit with +# addi 1,1,64 to pop stack frame. Simplify return value code. +# * sysdeps/powerpc/powerpc32/power4/memcmp.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcmp.S 2014-05-28 19:22:37.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcmp.S 2014-05-28 23:55:52.000000000 -0500 +@@ -1,4 +1,4 @@ +-/* Optimized strcmp implementation for PowerPC64. ++/* Optimized strcmp implementation for PowerPC32. + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -20,13 +20,14 @@ + #include + #include + +-/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5]) */ +- ++/* int [r3] memcmp (const char *s1 [r3], ++ const char *s2 [r4], ++ size_t size [r5]) */ ++ + .machine power4 + EALIGN (BP_SYM(memcmp), 4, 0) + CALL_MCOUNT + +-#define rTMP r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -37,33 +38,32 @@ + #define rWORD4 r9 /* next word in s2 */ + #define rWORD5 r10 /* next word in s1 */ + #define rWORD6 r11 /* next word in s2 */ +-#define rBITDIF r12 /* bits that differ in s1 & s2 words */ + #define rWORD7 r30 /* next word in s1 */ + #define rWORD8 r31 /* next word in s2 */ + +- xor rTMP, rSTR2, rSTR1 ++ xor r0, rSTR2, rSTR1 + cmplwi cr6, rN, 0 + cmplwi cr1, rN, 12 +- clrlwi. rTMP, rTMP, 30 +- clrlwi rBITDIF, rSTR1, 30 +- cmplwi cr5, rBITDIF, 0 ++ clrlwi. r0, r0, 30 ++ clrlwi r12, rSTR1, 30 ++ cmplwi cr5, r12, 0 + beq- cr6, L(zeroLength) +- dcbt 0,rSTR1 +- dcbt 0,rSTR2 ++ dcbt 0, rSTR1 ++ dcbt 0, rSTR2 + /* If less than 8 bytes or not aligned, use the unaligned + byte loop. */ + blt cr1, L(bytealigned) +- stwu 1,-64(1) ++ stwu 1, -64(r1) + cfi_adjust_cfa_offset(64) +- stw r31,48(1) +- cfi_offset(31,(48-64)) +- stw r30,44(1) +- cfi_offset(30,(44-64)) ++ stw rWORD8, 48(r1) ++ cfi_offset(rWORD8, (48-64)) ++ stw rWORD7, 44(r1) ++ cfi_offset(rWORD7, (44-64)) + bne L(unaligned) + /* At this point we know both strings have the same alignment and the +- compare length is at least 8 bytes. rBITDIF contains the low order ++ compare length is at least 8 bytes. r12 contains the low order + 2 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then we are already word ++ of r12 to 0. If r12 == 0 then we are already word + aligned and can perform the word aligned loop. + + Otherwise we know the two strings have the same alignment (but not +@@ -72,74 +72,95 @@ + eliminate bits preceeding the first byte. Since we want to join the + normal (word aligned) compare loop, starting at the second word, + we need to adjust the length (rN) and special case the loop +- versioning for the first word. This insures that the loop count is ++ versioning for the first word. This ensures that the loop count is + correct and the first word (shifted) is in the expected register pair. */ +- .align 4 ++ .align 4 + L(samealignment): + clrrwi rSTR1, rSTR1, 2 + clrrwi rSTR2, rSTR2, 2 + beq cr5, L(Waligned) +- add rN, rN, rBITDIF +- slwi r11, rBITDIF, 3 +- srwi rTMP, rN, 4 /* Divide by 16 */ +- andi. rBITDIF, rN, 12 /* Get the word remainder */ ++ add rN, rN, r12 ++ slwi rWORD6, r12, 3 ++ srwi r0, rN, 4 /* Divide by 16 */ ++ andi. r12, rN, 12 /* Get the word remainder */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 0(rSTR1) + lwz rWORD2, 0(rSTR2) +- cmplwi cr1, rBITDIF, 8 ++#endif ++ cmplwi cr1, r12, 8 + cmplwi cr7, rN, 16 + clrlwi rN, rN, 30 + beq L(dPs4) +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ + bgt cr1, L(dPs3) + beq cr1, L(dPs2) + + /* Remainder is 4 */ +- .align 3 ++ .align 3 + L(dsP1): +- slw rWORD5, rWORD1, r11 +- slw rWORD6, rWORD2, r11 ++ slw rWORD5, rWORD1, rWORD6 ++ slw rWORD6, rWORD2, rWORD6 + cmplw cr5, rWORD5, rWORD6 + blt cr7, L(dP1x) + /* Do something useful in this cycle since we have to branch anyway. */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 4(rSTR1) + lwz rWORD2, 4(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + b L(dP1e) + /* Remainder is 8 */ +- .align 4 ++ .align 4 + L(dPs2): +- slw rWORD5, rWORD1, r11 +- slw rWORD6, rWORD2, r11 ++ slw rWORD5, rWORD1, rWORD6 ++ slw rWORD6, rWORD2, rWORD6 + cmplw cr6, rWORD5, rWORD6 + blt cr7, L(dP2x) + /* Do something useful in this cycle since we have to branch anyway. */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD7, 4(rSTR1) + lwz rWORD8, 4(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 + b L(dP2e) + /* Remainder is 12 */ +- .align 4 ++ .align 4 + L(dPs3): +- slw rWORD3, rWORD1, r11 +- slw rWORD4, rWORD2, r11 ++ slw rWORD3, rWORD1, rWORD6 ++ slw rWORD4, rWORD2, rWORD6 + cmplw cr1, rWORD3, rWORD4 + b L(dP3e) + /* Count is a multiple of 16, remainder is 0 */ +- .align 4 ++ .align 4 + L(dPs4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- slw rWORD1, rWORD1, r11 +- slw rWORD2, rWORD2, r11 +- cmplw cr0, rWORD1, rWORD2 ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ slw rWORD1, rWORD1, rWORD6 ++ slw rWORD2, rWORD2, rWORD6 ++ cmplw cr7, rWORD1, rWORD2 + b L(dP4e) + + /* At this point we know both strings are word aligned and the + compare length is at least 8 bytes. */ +- .align 4 ++ .align 4 + L(Waligned): +- andi. rBITDIF, rN, 12 /* Get the word remainder */ +- srwi rTMP, rN, 4 /* Divide by 16 */ +- cmplwi cr1, rBITDIF, 8 ++ andi. r12, rN, 12 /* Get the word remainder */ ++ srwi r0, rN, 4 /* Divide by 16 */ ++ cmplwi cr1, r12, 8 + cmplwi cr7, rN, 16 + clrlwi rN, rN, 30 + beq L(dP4) +@@ -147,177 +168,352 @@ + beq cr1, L(dP2) + + /* Remainder is 4 */ +- .align 4 ++ .align 4 + L(dP1): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ + /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early + (8-15 byte compare), we want to use only volatile registers. This + means we can avoid restoring non-volatile registers since we did not + change any on the early exit path. The key here is the non-early + exit path only cares about the condition code (cr5), not about which + register pair was used. */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 0(rSTR1) + lwz rWORD6, 0(rSTR2) ++#endif + cmplw cr5, rWORD5, rWORD6 + blt cr7, L(dP1x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 4(rSTR1) + lwz rWORD2, 4(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + L(dP1e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 8(rSTR1) + lwz rWORD4, 8(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 12(rSTR1) + lwz rWORD6, 12(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 +- bne cr5, L(dLcr5) +- bne cr0, L(dLcr0) +- ++ bne cr5, L(dLcr5x) ++ bne cr7, L(dLcr7x) ++ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwzu rWORD7, 16(rSTR1) + lwzu rWORD8, 16(rSTR2) ++#endif + bne cr1, L(dLcr1) + cmplw cr5, rWORD7, rWORD8 + bdnz L(dLoop) + bne cr6, L(dLcr6) +- lwz r30,44(1) +- lwz r31,48(1) +- .align 3 ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++ .align 3 + L(dP1x): + slwi. r12, rN, 3 +- bne cr5, L(dLcr5) ++ bne cr5, L(dLcr5x) + subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ +- lwz 1,0(1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + bne L(d00) + li rRTN, 0 + blr + + /* Remainder is 8 */ +- .align 4 ++ .align 4 ++ cfi_adjust_cfa_offset(64) + L(dP2): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 0(rSTR1) + lwz rWORD6, 0(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 + blt cr7, L(dP2x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD7, 4(rSTR1) + lwz rWORD8, 4(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 + L(dP2e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 8(rSTR1) + lwz rWORD2, 8(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 12(rSTR1) + lwz rWORD4, 12(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 4 + addi rSTR2, rSTR2, 4 ++#endif + bne cr6, L(dLcr6) + bne cr5, L(dLcr5) + b L(dLoop2) + /* Again we are on a early exit path (16-23 byte compare), we want to + only use volatile registers and avoid restoring non-volatile + registers. */ +- .align 4 ++ .align 4 + L(dP2x): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 4(rSTR1) + lwz rWORD4, 4(rSTR2) +- cmplw cr5, rWORD3, rWORD4 ++#endif ++ cmplw cr1, rWORD3, rWORD4 + slwi. r12, rN, 3 +- bne cr6, L(dLcr6) ++ bne cr6, L(dLcr6x) ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 4 + addi rSTR2, rSTR2, 4 +- bne cr5, L(dLcr5) ++#endif ++ bne cr1, L(dLcr1x) + subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ +- lwz 1,0(1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + bne L(d00) + li rRTN, 0 + blr + + /* Remainder is 12 */ +- .align 4 ++ .align 4 ++ cfi_adjust_cfa_offset(64) + L(dP3): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 0(rSTR1) + lwz rWORD4, 0(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 + L(dP3e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 4(rSTR1) + lwz rWORD6, 4(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 + blt cr7, L(dP3x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD7, 8(rSTR1) + lwz rWORD8, 8(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 12(rSTR1) + lwz rWORD2, 12(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 ++#endif + bne cr1, L(dLcr1) + bne cr6, L(dLcr6) + b L(dLoop1) + /* Again we are on a early exit path (24-31 byte compare), we want to + only use volatile registers and avoid restoring non-volatile + registers. */ +- .align 4 ++ .align 4 + L(dP3x): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 8(rSTR1) + lwz rWORD2, 8(rSTR2) +- cmplw cr5, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + slwi. r12, rN, 3 +- bne cr1, L(dLcr1) ++ bne cr1, L(dLcr1x) ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +- bne cr6, L(dLcr6) ++#endif ++ bne cr6, L(dLcr6x) + subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ +- bne cr5, L(dLcr5) +- lwz 1,0(1) ++ bne cr7, L(dLcr7x) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + bne L(d00) + li rRTN, 0 + blr + + /* Count is a multiple of 16, remainder is 0 */ +- .align 4 ++ .align 4 ++ cfi_adjust_cfa_offset(64) + L(dP4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 0(rSTR1) + lwz rWORD2, 0(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + L(dP4e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 4(rSTR1) + lwz rWORD4, 4(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 8(rSTR1) + lwz rWORD6, 8(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwzu rWORD7, 12(rSTR1) + lwzu rWORD8, 12(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 +- bne cr0, L(dLcr0) ++ bne cr7, L(dLcr7) + bne cr1, L(dLcr1) + bdz- L(d24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ +- .align 4 ++ .align 4 + L(dLoop): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 4(rSTR1) + lwz rWORD2, 4(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 + bne cr6, L(dLcr6) + L(dLoop1): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 8(rSTR1) + lwz rWORD4, 8(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 + bne cr5, L(dLcr5) + L(dLoop2): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 12(rSTR1) + lwz rWORD6, 12(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 +- bne cr0, L(dLcr0) ++ bne cr7, L(dLcr7) + L(dLoop3): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwzu rWORD7, 16(rSTR1) + lwzu rWORD8, 16(rSTR2) ++#endif + bne- cr1, L(dLcr1) +- cmplw cr0, rWORD1, rWORD2 ++ cmplw cr7, rWORD1, rWORD2 + bdnz+ L(dLoop) + + L(dL4): +@@ -327,7 +523,7 @@ + bne cr5, L(dLcr5) + cmplw cr5, rWORD7, rWORD8 + L(d44): +- bne cr0, L(dLcr0) ++ bne cr7, L(dLcr7) + L(d34): + bne cr1, L(dLcr1) + L(d24): +@@ -336,69 +532,82 @@ + slwi. r12, rN, 3 + bne cr5, L(dLcr5) + L(d04): +- lwz r30,44(1) +- lwz r31,48(1) +- lwz 1,0(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ + beq L(zeroLength) + /* At this point we have a remainder of 1 to 3 bytes to compare. Since + we are aligned it is safe to load the whole word, and use +- shift right to eliminate bits beyond the compare length. */ ++ shift right to eliminate bits beyond the compare length. */ + L(d00): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 4(rSTR1) + lwz rWORD2, 4(rSTR2) ++#endif + srw rWORD1, rWORD1, rN + srw rWORD2, rWORD2, rN +- cmplw rWORD1,rWORD2 +- li rRTN,0 +- beqlr +- li rRTN,1 +- bgtlr +- li rRTN,-1 +- blr +- +- .align 4 +-L(dLcr0): +- lwz r30,44(1) +- lwz r31,48(1) ++ sub rRTN, rWORD1, rWORD2 ++ blr ++ ++ .align 4 ++ cfi_adjust_cfa_offset(64) ++L(dLcr7): ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++L(dLcr7x): + li rRTN, 1 +- lwz 1,0(1) +- bgtlr cr0 ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) ++ bgtlr cr7 + li rRTN, -1 + blr +- .align 4 ++ .align 4 ++ cfi_adjust_cfa_offset(64) + L(dLcr1): +- lwz r30,44(1) +- lwz r31,48(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++L(dLcr1x): + li rRTN, 1 +- lwz 1,0(1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + bgtlr cr1 + li rRTN, -1 + blr +- .align 4 ++ .align 4 ++ cfi_adjust_cfa_offset(64) + L(dLcr6): +- lwz r30,44(1) +- lwz r31,48(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++L(dLcr6x): + li rRTN, 1 +- lwz 1,0(1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + bgtlr cr6 + li rRTN, -1 + blr +- .align 4 ++ .align 4 ++ cfi_adjust_cfa_offset(64) + L(dLcr5): +- lwz r30,44(1) +- lwz r31,48(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) + L(dLcr5x): + li rRTN, 1 +- lwz 1,0(1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + bgtlr cr5 + li rRTN, -1 + blr + +- .align 4 ++ .align 4 + L(bytealigned): +- cfi_adjust_cfa_offset(-64) +- mtctr rN /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr rN /* Power4 wants mtctr 1st in dispatch group */ + + /* We need to prime this loop. This loop is swing modulo scheduled + to avoid pipe delays. The dependent instruction latencies (load to +@@ -413,7 +622,7 @@ + lbz rWORD1, 0(rSTR1) + lbz rWORD2, 0(rSTR2) + bdz- L(b11) +- cmplw cr0, rWORD1, rWORD2 ++ cmplw cr7, rWORD1, rWORD2 + lbz rWORD3, 1(rSTR1) + lbz rWORD4, 1(rSTR2) + bdz- L(b12) +@@ -421,11 +630,11 @@ + lbzu rWORD5, 2(rSTR1) + lbzu rWORD6, 2(rSTR2) + bdz- L(b13) +- .align 4 ++ .align 4 + L(bLoop): + lbzu rWORD1, 1(rSTR1) + lbzu rWORD2, 1(rSTR2) +- bne- cr0, L(bLcr0) ++ bne- cr7, L(bLcr7) + + cmplw cr6, rWORD5, rWORD6 + bdz- L(b3i) +@@ -434,7 +643,7 @@ + lbzu rWORD4, 1(rSTR2) + bne- cr1, L(bLcr1) + +- cmplw cr0, rWORD1, rWORD2 ++ cmplw cr7, rWORD1, rWORD2 + bdz- L(b2i) + + lbzu rWORD5, 1(rSTR1) +@@ -451,23 +660,23 @@ + tested. In this case we must complete the pending operations + before returning. */ + L(b1i): +- bne- cr0, L(bLcr0) ++ bne- cr7, L(bLcr7) + bne- cr1, L(bLcr1) + b L(bx56) +- .align 4 ++ .align 4 + L(b2i): + bne- cr6, L(bLcr6) +- bne- cr0, L(bLcr0) ++ bne- cr7, L(bLcr7) + b L(bx34) +- .align 4 ++ .align 4 + L(b3i): + bne- cr1, L(bLcr1) + bne- cr6, L(bLcr6) + b L(bx12) +- .align 4 +-L(bLcr0): ++ .align 4 ++L(bLcr7): + li rRTN, 1 +- bgtlr cr0 ++ bgtlr cr7 + li rRTN, -1 + blr + L(bLcr1): +@@ -482,36 +691,31 @@ + blr + + L(b13): +- bne- cr0, L(bx12) ++ bne- cr7, L(bx12) + bne- cr1, L(bx34) + L(bx56): + sub rRTN, rWORD5, rWORD6 + blr + nop + L(b12): +- bne- cr0, L(bx12) ++ bne- cr7, L(bx12) + L(bx34): + sub rRTN, rWORD3, rWORD4 + blr +- + L(b11): + L(bx12): + sub rRTN, rWORD1, rWORD2 + blr +- +- .align 4 +-L(zeroLengthReturn): +- ++ .align 4 + L(zeroLength): + li rRTN, 0 + blr + +- cfi_adjust_cfa_offset(64) +- .align 4 ++ .align 4 + /* At this point we know the strings have different alignment and the +- compare length is at least 8 bytes. rBITDIF contains the low order ++ compare length is at least 8 bytes. r12 contains the low order + 2 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then rStr1 is word aligned and can ++ of r12 to 0. If r12 == 0 then rStr1 is word aligned and can + perform the Wunaligned loop. + + Otherwise we know that rSTR1 is not aready word aligned yet. +@@ -520,79 +724,88 @@ + eliminate bits preceeding the first byte. Since we want to join the + normal (Wualigned) compare loop, starting at the second word, + we need to adjust the length (rN) and special case the loop +- versioning for the first W. This insures that the loop count is ++ versioning for the first W. This ensures that the loop count is + correct and the first W (shifted) is in the expected resister pair. */ + #define rSHL r29 /* Unaligned shift left count. */ + #define rSHR r28 /* Unaligned shift right count. */ +-#define rB r27 /* Left rotation temp for rWORD2. */ +-#define rD r26 /* Left rotation temp for rWORD4. */ +-#define rF r25 /* Left rotation temp for rWORD6. */ +-#define rH r24 /* Left rotation temp for rWORD8. */ +-#define rA r0 /* Right rotation temp for rWORD2. */ +-#define rC r12 /* Right rotation temp for rWORD4. */ +-#define rE r0 /* Right rotation temp for rWORD6. */ +-#define rG r12 /* Right rotation temp for rWORD8. */ ++#define rWORD8_SHIFT r27 /* Left rotation temp for rWORD2. */ ++#define rWORD2_SHIFT r26 /* Left rotation temp for rWORD4. */ ++#define rWORD4_SHIFT r25 /* Left rotation temp for rWORD6. */ ++#define rWORD6_SHIFT r24 /* Left rotation temp for rWORD8. */ ++ cfi_adjust_cfa_offset(64) + L(unaligned): +- stw r29,40(r1) +- cfi_offset(r29,(40-64)) ++ stw rSHL, 40(r1) ++ cfi_offset(rSHL, (40-64)) + clrlwi rSHL, rSTR2, 30 +- stw r28,36(r1) +- cfi_offset(r28,(36-64)) ++ stw rSHR, 36(r1) ++ cfi_offset(rSHR, (36-64)) + beq cr5, L(Wunaligned) +- stw r27,32(r1) +- cfi_offset(r27,(32-64)) ++ stw rWORD8_SHIFT, 32(r1) ++ cfi_offset(rWORD8_SHIFT, (32-64)) + /* Adjust the logical start of rSTR2 to compensate for the extra bits + in the 1st rSTR1 W. */ +- sub r27, rSTR2, rBITDIF ++ sub rWORD8_SHIFT, rSTR2, r12 + /* But do not attempt to address the W before that W that contains + the actual start of rSTR2. */ + clrrwi rSTR2, rSTR2, 2 +- stw r26,28(r1) +- cfi_offset(r26,(28-64)) +-/* Compute the left/right shift counts for the unalign rSTR2, ++ stw rWORD2_SHIFT, 28(r1) ++ cfi_offset(rWORD2_SHIFT, (28-64)) ++/* Compute the left/right shift counts for the unaligned rSTR2, + compensating for the logical (W aligned) start of rSTR1. */ +- clrlwi rSHL, r27, 30 ++ clrlwi rSHL, rWORD8_SHIFT, 30 + clrrwi rSTR1, rSTR1, 2 +- stw r25,24(r1) +- cfi_offset(r25,(24-64)) ++ stw rWORD4_SHIFT, 24(r1) ++ cfi_offset(rWORD4_SHIFT, (24-64)) + slwi rSHL, rSHL, 3 +- cmplw cr5, r27, rSTR2 +- add rN, rN, rBITDIF +- slwi r11, rBITDIF, 3 +- stw r24,20(r1) +- cfi_offset(r24,(20-64)) ++ cmplw cr5, rWORD8_SHIFT, rSTR2 ++ add rN, rN, r12 ++ slwi rWORD6, r12, 3 ++ stw rWORD6_SHIFT, 20(r1) ++ cfi_offset(rWORD6_SHIFT, (20-64)) + subfic rSHR, rSHL, 32 +- srwi rTMP, rN, 4 /* Divide by 16 */ +- andi. rBITDIF, rN, 12 /* Get the W remainder */ ++ srwi r0, rN, 4 /* Divide by 16 */ ++ andi. r12, rN, 12 /* Get the W remainder */ + /* We normally need to load 2 Ws to start the unaligned rSTR2, but in + this special case those bits may be discarded anyway. Also we + must avoid loading a W where none of the bits are part of rSTR2 as + this may cross a page boundary and cause a page fault. */ + li rWORD8, 0 + blt cr5, L(dus0) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD8, 0(rSTR2) +- la rSTR2, 4(rSTR2) ++ addi rSTR2, rSTR2, 4 ++#endif + slw rWORD8, rWORD8, rSHL + + L(dus0): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 0(rSTR1) + lwz rWORD2, 0(rSTR2) +- cmplwi cr1, rBITDIF, 8 ++#endif ++ cmplwi cr1, r12, 8 + cmplwi cr7, rN, 16 +- srw rG, rWORD2, rSHR ++ srw r12, rWORD2, rSHR + clrlwi rN, rN, 30 + beq L(duPs4) +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- or rWORD8, rG, rWORD8 ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ or rWORD8, r12, rWORD8 + bgt cr1, L(duPs3) + beq cr1, L(duPs2) + + /* Remainder is 4 */ +- .align 4 ++ .align 4 + L(dusP1): +- slw rB, rWORD2, rSHL +- slw rWORD7, rWORD1, r11 +- slw rWORD8, rWORD8, r11 ++ slw rWORD8_SHIFT, rWORD2, rSHL ++ slw rWORD7, rWORD1, rWORD6 ++ slw rWORD8, rWORD8, rWORD6 + bge cr7, L(duP1e) + /* At this point we exit early with the first word compare + complete and remainder of 0 to 3 bytes. See L(du14) for details on +@@ -602,95 +815,133 @@ + bne cr5, L(duLcr5) + cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD2, 4(rSTR2) +- srw rA, rWORD2, rSHR ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 8 */ +- .align 4 ++ .align 4 + L(duPs2): +- slw rH, rWORD2, rSHL +- slw rWORD5, rWORD1, r11 +- slw rWORD6, rWORD8, r11 ++ slw rWORD6_SHIFT, rWORD2, rSHL ++ slw rWORD5, rWORD1, rWORD6 ++ slw rWORD6, rWORD8, rWORD6 + b L(duP2e) + /* Remainder is 12 */ +- .align 4 ++ .align 4 + L(duPs3): +- slw rF, rWORD2, rSHL +- slw rWORD3, rWORD1, r11 +- slw rWORD4, rWORD8, r11 ++ slw rWORD4_SHIFT, rWORD2, rSHL ++ slw rWORD3, rWORD1, rWORD6 ++ slw rWORD4, rWORD8, rWORD6 + b L(duP3e) + /* Count is a multiple of 16, remainder is 0 */ +- .align 4 ++ .align 4 + L(duPs4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- or rWORD8, rG, rWORD8 +- slw rD, rWORD2, rSHL +- slw rWORD1, rWORD1, r11 +- slw rWORD2, rWORD8, r11 ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ or rWORD8, r12, rWORD8 ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ slw rWORD1, rWORD1, rWORD6 ++ slw rWORD2, rWORD8, rWORD6 + b L(duP4e) + + /* At this point we know rSTR1 is word aligned and the + compare length is at least 8 bytes. */ +- .align 4 ++ .align 4 + L(Wunaligned): +- stw r27,32(r1) +- cfi_offset(r27,(32-64)) ++ stw rWORD8_SHIFT, 32(r1) ++ cfi_offset(rWORD8_SHIFT, (32-64)) + clrrwi rSTR2, rSTR2, 2 +- stw r26,28(r1) +- cfi_offset(r26,(28-64)) +- srwi rTMP, rN, 4 /* Divide by 16 */ +- stw r25,24(r1) +- cfi_offset(r25,(24-64)) +- andi. rBITDIF, rN, 12 /* Get the W remainder */ +- stw r24,20(r1) +- cfi_offset(r24,(20-64)) ++ stw rWORD2_SHIFT, 28(r1) ++ cfi_offset(rWORD2_SHIFT, (28-64)) ++ srwi r0, rN, 4 /* Divide by 16 */ ++ stw rWORD4_SHIFT, 24(r1) ++ cfi_offset(rWORD4_SHIFT, (24-64)) ++ andi. r12, rN, 12 /* Get the W remainder */ ++ stw rWORD6_SHIFT, 20(r1) ++ cfi_offset(rWORD6_SHIFT, (20-64)) + slwi rSHL, rSHL, 3 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD6, 0(rSTR2) + lwzu rWORD8, 4(rSTR2) +- cmplwi cr1, rBITDIF, 8 ++#endif ++ cmplwi cr1, r12, 8 + cmplwi cr7, rN, 16 + clrlwi rN, rN, 30 + subfic rSHR, rSHL, 32 +- slw rH, rWORD6, rSHL ++ slw rWORD6_SHIFT, rWORD6, rSHL + beq L(duP4) +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ + bgt cr1, L(duP3) + beq cr1, L(duP2) + + /* Remainder is 4 */ +- .align 4 ++ .align 4 + L(duP1): +- srw rG, rWORD8, rSHR ++ srw r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else + lwz rWORD7, 0(rSTR1) +- slw rB, rWORD8, rSHL +- or rWORD8, rG, rH ++#endif ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP1x) + L(duP1e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 4(rSTR1) + lwz rWORD2, 4(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 +- srw rA, rWORD2, rSHR +- slw rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 8(rSTR1) + lwz rWORD4, 8(rSTR2) +- cmplw cr0, rWORD1, rWORD2 +- srw rC, rWORD4, rSHR +- slw rF, rWORD4, rSHL ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL + bne cr5, L(duLcr5) +- or rWORD4, rC, rD ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 12(rSTR1) + lwz rWORD6, 12(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 +- srw rE, rWORD6, rSHR +- slw rH, rWORD6, rSHL +- bne cr0, L(duLcr0) +- or rWORD6, rE, rF ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ bne cr7, L(duLcr7) ++ or rWORD6, r0, rWORD4_SHIFT + cmplw cr6, rWORD5, rWORD6 + b L(duLoop3) +- .align 4 ++ .align 4 + /* At this point we exit early with the first word compare + complete and remainder of 0 to 3 bytes. See L(du14) for details on + how we handle the remaining bytes. */ +@@ -700,186 +951,321 @@ + bne cr5, L(duLcr5) + cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) +- ld rWORD2, 8(rSTR2) +- srw rA, rWORD2, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD2, 8(rSTR2) ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 8 */ +- .align 4 ++ .align 4 + L(duP2): +- srw rE, rWORD8, rSHR ++ srw r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else + lwz rWORD5, 0(rSTR1) +- or rWORD6, rE, rH +- slw rH, rWORD8, rSHL ++#endif ++ or rWORD6, r0, rWORD6_SHIFT ++ slw rWORD6_SHIFT, rWORD8, rSHL + L(duP2e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD7, 4(rSTR1) + lwz rWORD8, 4(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 +- srw rG, rWORD8, rSHR +- slw rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP2x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 8(rSTR1) + lwz rWORD2, 8(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) +- srw rA, rWORD2, rSHR +- slw rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 12(rSTR1) + lwz rWORD4, 12(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + bne cr5, L(duLcr5) +- srw rC, rWORD4, rSHR +- slw rF, rWORD4, rSHL +- or rWORD4, rC, rD ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 4 + addi rSTR2, rSTR2, 4 ++#endif + cmplw cr1, rWORD3, rWORD4 + b L(duLoop2) +- .align 4 ++ .align 4 + L(duP2x): + cmplw cr5, rWORD7, rWORD8 ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 4 + addi rSTR2, rSTR2, 4 ++#endif + bne cr6, L(duLcr6) + slwi. rN, rN, 3 + bne cr5, L(duLcr5) + cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD2, 4(rSTR2) +- srw rA, rWORD2, rSHR ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + + /* Remainder is 12 */ +- .align 4 ++ .align 4 + L(duP3): +- srw rC, rWORD8, rSHR ++ srw r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else + lwz rWORD3, 0(rSTR1) +- slw rF, rWORD8, rSHL +- or rWORD4, rC, rH ++#endif ++ slw rWORD4_SHIFT, rWORD8, rSHL ++ or rWORD4, r12, rWORD6_SHIFT + L(duP3e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 4(rSTR1) + lwz rWORD6, 4(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 +- srw rE, rWORD6, rSHR +- slw rH, rWORD6, rSHL +- or rWORD6, rE, rF ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD7, 8(rSTR1) + lwz rWORD8, 8(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 + bne cr1, L(duLcr1) +- srw rG, rWORD8, rSHR +- slw rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP3x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 12(rSTR1) + lwz rWORD2, 12(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) +- srw rA, rWORD2, rSHR +- slw rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + b L(duLoop1) +- .align 4 ++ .align 4 + L(duP3x): ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 ++#endif ++#if 0 ++/* Huh? We've already branched on cr1! */ + bne cr1, L(duLcr1) ++#endif + cmplw cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) + slwi. rN, rN, 3 + bne cr5, L(duLcr5) + cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD2, 4(rSTR2) +- srw rA, rWORD2, rSHR ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + + /* Count is a multiple of 16, remainder is 0 */ +- .align 4 ++ .align 4 + L(duP4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- srw rA, rWORD8, rSHR ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ srw r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else + lwz rWORD1, 0(rSTR1) +- slw rD, rWORD8, rSHL +- or rWORD2, rA, rH ++#endif ++ slw rWORD2_SHIFT, rWORD8, rSHL ++ or rWORD2, r0, rWORD6_SHIFT + L(duP4e): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 4(rSTR1) + lwz rWORD4, 4(rSTR2) +- cmplw cr0, rWORD1, rWORD2 +- srw rC, rWORD4, rSHR +- slw rF, rWORD4, rSHL +- or rWORD4, rC, rD ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 8(rSTR1) + lwz rWORD6, 8(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 +- bne cr0, L(duLcr0) +- srw rE, rWORD6, rSHR +- slw rH, rWORD6, rSHL +- or rWORD6, rE, rF ++ bne cr7, L(duLcr7) ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwzu rWORD7, 12(rSTR1) + lwzu rWORD8, 12(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 + bne cr1, L(duLcr1) +- srw rG, rWORD8, rSHR +- slw rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + cmplw cr5, rWORD7, rWORD8 + bdz- L(du24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ +- .align 4 ++ .align 4 + L(duLoop): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD1, 4(rSTR1) + lwz rWORD2, 4(rSTR2) ++#endif + cmplw cr1, rWORD3, rWORD4 + bne cr6, L(duLcr6) +- srw rA, rWORD2, rSHR +- slw rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT + L(duLoop1): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD3, 8(rSTR1) + lwz rWORD4, 8(rSTR2) ++#endif + cmplw cr6, rWORD5, rWORD6 + bne cr5, L(duLcr5) +- srw rC, rWORD4, rSHR +- slw rF, rWORD4, rSHL +- or rWORD4, rC, rD ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT + L(duLoop2): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD5, 12(rSTR1) + lwz rWORD6, 12(rSTR2) ++#endif + cmplw cr5, rWORD7, rWORD8 +- bne cr0, L(duLcr0) +- srw rE, rWORD6, rSHR +- slw rH, rWORD6, rSHL +- or rWORD6, rE, rF ++ bne cr7, L(duLcr7) ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT + L(duLoop3): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else + lwzu rWORD7, 16(rSTR1) + lwzu rWORD8, 16(rSTR2) +- cmplw cr0, rWORD1, rWORD2 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + bne- cr1, L(duLcr1) +- srw rG, rWORD8, rSHR +- slw rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + bdnz+ L(duLoop) + + L(duL4): ++#if 0 ++/* Huh? We've already branched on cr1! */ + bne cr1, L(duLcr1) ++#endif + cmplw cr1, rWORD3, rWORD4 + bne cr6, L(duLcr6) + cmplw cr6, rWORD5, rWORD6 + bne cr5, L(duLcr5) + cmplw cr5, rWORD7, rWORD8 + L(du44): +- bne cr0, L(duLcr0) ++ bne cr7, L(duLcr7) + L(du34): + bne cr1, L(duLcr1) + L(du24): +@@ -889,95 +1275,101 @@ + bne cr5, L(duLcr5) + /* At this point we have a remainder of 1 to 3 bytes to compare. We use + shift right to eliminate bits beyond the compare length. ++ This allows the use of word subtract to compute the final result. + + However it may not be safe to load rWORD2 which may be beyond the + string length. So we compare the bit length of the remainder to + the right shift count (rSHR). If the bit count is less than or equal + we do not need to load rWORD2 (all significant bits are already in +- rB). */ ++ rWORD8_SHIFT). */ + cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else + lwz rWORD2, 4(rSTR2) +- srw rA, rWORD2, rSHR +- .align 4 ++#endif ++ srw r0, rWORD2, rSHR ++ .align 4 + L(dutrim): ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++#else + lwz rWORD1, 4(rSTR1) +- lwz r31,48(1) ++#endif ++ lwz rWORD8, 48(r1) + subfic rN, rN, 32 /* Shift count is 32 - (rN * 8). */ +- or rWORD2, rA, rB +- lwz r30,44(1) +- lwz r29,40(r1) ++ or rWORD2, r0, rWORD8_SHIFT ++ lwz rWORD7, 44(r1) ++ lwz rSHL, 40(r1) + srw rWORD1, rWORD1, rN + srw rWORD2, rWORD2, rN +- lwz r28,36(r1) +- lwz r27,32(r1) +- cmplw rWORD1,rWORD2 +- li rRTN,0 +- beq L(dureturn26) +- li rRTN,1 +- bgt L(dureturn26) +- li rRTN,-1 +- b L(dureturn26) +- .align 4 +-L(duLcr0): +- lwz r31,48(1) +- lwz r30,44(1) +- li rRTN, 1 +- bgt cr0, L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) ++ lwz rSHR, 36(r1) ++ lwz rWORD8_SHIFT, 32(r1) ++ sub rRTN, rWORD1, rWORD2 ++ b L(dureturn26) ++ .align 4 ++L(duLcr7): ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) ++ li rRTN, 1 ++ bgt cr7, L(dureturn29) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) + li rRTN, -1 + b L(dureturn27) +- .align 4 ++ .align 4 + L(duLcr1): +- lwz r31,48(1) +- lwz r30,44(1) ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) + li rRTN, 1 + bgt cr1, L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) + li rRTN, -1 + b L(dureturn27) +- .align 4 ++ .align 4 + L(duLcr6): +- lwz r31,48(1) +- lwz r30,44(1) ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) + li rRTN, 1 + bgt cr6, L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) + li rRTN, -1 + b L(dureturn27) +- .align 4 ++ .align 4 + L(duLcr5): +- lwz r31,48(1) +- lwz r30,44(1) ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) + li rRTN, 1 + bgt cr5, L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) + li rRTN, -1 + b L(dureturn27) + .align 3 + L(duZeroReturn): +- li rRTN,0 ++ li rRTN, 0 + .align 4 + L(dureturn): +- lwz r31,48(1) +- lwz r30,44(1) ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) + L(dureturn29): +- lwz r29,40(r1) +- lwz r28,36(r1) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) + L(dureturn27): +- lwz r27,32(r1) ++ lwz rWORD8_SHIFT, 32(r1) + L(dureturn26): +- lwz r26,28(r1) ++ lwz rWORD2_SHIFT, 28(r1) + L(dureturn25): +- lwz r25,24(r1) +- lwz r24,20(r1) +- lwz 1,0(1) ++ lwz rWORD4_SHIFT, 24(r1) ++ lwz rWORD6_SHIFT, 20(r1) ++ addi 1, 1, 64 ++ cfi_adjust_cfa_offset(-64) + blr + END (BP_SYM (memcmp)) + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcmp.S 2014-05-28 19:22:37.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcmp.S 2014-05-28 21:44:57.000000000 -0500 +@@ -25,10 +25,9 @@ + size_t size [r5]) */ + + .machine power7 +-EALIGN (BP_SYM(memcmp),4,0) ++EALIGN (BP_SYM(memcmp), 4, 0) + CALL_MCOUNT + +-#define rTMP r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ +@@ -39,35 +38,32 @@ + #define rWORD4 r9 /* next word in s2 */ + #define rWORD5 r10 /* next word in s1 */ + #define rWORD6 r11 /* next word in s2 */ +-#define rBITDIF r12 /* bits that differ in s1 & s2 words */ + #define rWORD7 r30 /* next word in s1 */ + #define rWORD8 r31 /* next word in s2 */ + +- xor rTMP,rSTR2,rSTR1 +- cmplwi cr6,rN,0 +- cmplwi cr1,rN,12 +- clrlwi. rTMP,rTMP,30 +- clrlwi rBITDIF,rSTR1,30 +- cmplwi cr5,rBITDIF,0 +- beq- cr6,L(zeroLength) +- dcbt 0,rSTR1 +- dcbt 0,rSTR2 +- +- /* If less than 8 bytes or not aligned, use the unaligned +- byte loop. */ +- +- blt cr1,L(bytealigned) +- stwu 1,-64(1) ++ xor r0, rSTR2, rSTR1 ++ cmplwi cr6, rN, 0 ++ cmplwi cr1, rN, 12 ++ clrlwi. r0, r0, 30 ++ clrlwi r12, rSTR1, 30 ++ cmplwi cr5, r12, 0 ++ beq- cr6, L(zeroLength) ++ dcbt 0, rSTR1 ++ dcbt 0, rSTR2 ++/* If less than 8 bytes or not aligned, use the unaligned ++ byte loop. */ ++ blt cr1, L(bytealigned) ++ stwu 1, -64(r1) + cfi_adjust_cfa_offset(64) +- stw r31,48(1) +- cfi_offset(31,(48-64)) +- stw r30,44(1) +- cfi_offset(30,(44-64)) ++ stw rWORD8, 48(r1) ++ cfi_offset(rWORD8, (48-64)) ++ stw rWORD7, 44(r1) ++ cfi_offset(rWORD7, (44-64)) + bne L(unaligned) + /* At this point we know both strings have the same alignment and the +- compare length is at least 8 bytes. rBITDIF contains the low order ++ compare length is at least 8 bytes. r12 contains the low order + 2 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then we are already word ++ of r12 to 0. If r12 == 0 then we are already word + aligned and can perform the word aligned loop. + + Otherwise we know the two strings have the same alignment (but not +@@ -76,332 +72,541 @@ + eliminate bits preceeding the first byte. Since we want to join the + normal (word aligned) compare loop, starting at the second word, + we need to adjust the length (rN) and special case the loop +- versioning for the first word. This insures that the loop count is ++ versioning for the first word. This ensures that the loop count is + correct and the first word (shifted) is in the expected register pair. */ + .align 4 + L(samealignment): +- clrrwi rSTR1,rSTR1,2 +- clrrwi rSTR2,rSTR2,2 +- beq cr5,L(Waligned) +- add rN,rN,rBITDIF +- slwi r11,rBITDIF,3 +- srwi rTMP,rN,4 /* Divide by 16 */ +- andi. rBITDIF,rN,12 /* Get the word remainder */ +- lwz rWORD1,0(rSTR1) +- lwz rWORD2,0(rSTR2) +- cmplwi cr1,rBITDIF,8 +- cmplwi cr7,rN,16 +- clrlwi rN,rN,30 ++ clrrwi rSTR1, rSTR1, 2 ++ clrrwi rSTR2, rSTR2, 2 ++ beq cr5, L(Waligned) ++ add rN, rN, r12 ++ slwi rWORD6, r12, 3 ++ srwi r0, rN, 4 /* Divide by 16 */ ++ andi. r12, rN, 12 /* Get the word remainder */ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 0(rSTR1) ++ lwz rWORD2, 0(rSTR2) ++#endif ++ cmplwi cr1, r12, 8 ++ cmplwi cr7, rN, 16 ++ clrlwi rN, rN, 30 + beq L(dPs4) +- mtctr rTMP +- bgt cr1,L(dPs3) +- beq cr1,L(dPs2) ++ mtctr r0 ++ bgt cr1, L(dPs3) ++ beq cr1, L(dPs2) + + /* Remainder is 4 */ + .align 3 + L(dsP1): +- slw rWORD5,rWORD1,r11 +- slw rWORD6,rWORD2,r11 +- cmplw cr5,rWORD5,rWORD6 +- blt cr7,L(dP1x) ++ slw rWORD5, rWORD1, rWORD6 ++ slw rWORD6, rWORD2, rWORD6 ++ cmplw cr5, rWORD5, rWORD6 ++ blt cr7, L(dP1x) + /* Do something useful in this cycle since we have to branch anyway. */ +- lwz rWORD1,4(rSTR1) +- lwz rWORD2,4(rSTR2) +- cmplw cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 4(rSTR1) ++ lwz rWORD2, 4(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 + b L(dP1e) + /* Remainder is 8 */ + .align 4 + L(dPs2): +- slw rWORD5,rWORD1,r11 +- slw rWORD6,rWORD2,r11 +- cmplw cr6,rWORD5,rWORD6 +- blt cr7,L(dP2x) ++ slw rWORD5, rWORD1, rWORD6 ++ slw rWORD6, rWORD2, rWORD6 ++ cmplw cr6, rWORD5, rWORD6 ++ blt cr7, L(dP2x) + /* Do something useful in this cycle since we have to branch anyway. */ +- lwz rWORD7,4(rSTR1) +- lwz rWORD8,4(rSTR2) +- cmplw cr5,rWORD7,rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD7, 4(rSTR1) ++ lwz rWORD8, 4(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 + b L(dP2e) + /* Remainder is 12 */ + .align 4 + L(dPs3): +- slw rWORD3,rWORD1,r11 +- slw rWORD4,rWORD2,r11 +- cmplw cr1,rWORD3,rWORD4 ++ slw rWORD3, rWORD1, rWORD6 ++ slw rWORD4, rWORD2, rWORD6 ++ cmplw cr1, rWORD3, rWORD4 + b L(dP3e) + /* Count is a multiple of 16, remainder is 0 */ + .align 4 + L(dPs4): +- mtctr rTMP +- slw rWORD1,rWORD1,r11 +- slw rWORD2,rWORD2,r11 +- cmplw cr0,rWORD1,rWORD2 ++ mtctr r0 ++ slw rWORD1, rWORD1, rWORD6 ++ slw rWORD2, rWORD2, rWORD6 ++ cmplw cr7, rWORD1, rWORD2 + b L(dP4e) + + /* At this point we know both strings are word aligned and the + compare length is at least 8 bytes. */ + .align 4 + L(Waligned): +- andi. rBITDIF,rN,12 /* Get the word remainder */ +- srwi rTMP,rN,4 /* Divide by 16 */ +- cmplwi cr1,rBITDIF,8 +- cmplwi cr7,rN,16 +- clrlwi rN,rN,30 ++ andi. r12, rN, 12 /* Get the word remainder */ ++ srwi r0, rN, 4 /* Divide by 16 */ ++ cmplwi cr1, r12, 8 ++ cmplwi cr7, rN, 16 ++ clrlwi rN, rN, 30 + beq L(dP4) +- bgt cr1,L(dP3) +- beq cr1,L(dP2) ++ bgt cr1, L(dP3) ++ beq cr1, L(dP2) + + /* Remainder is 4 */ + .align 4 + L(dP1): +- mtctr rTMP ++ mtctr r0 + /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early + (8-15 byte compare), we want to use only volatile registers. This + means we can avoid restoring non-volatile registers since we did not + change any on the early exit path. The key here is the non-early + exit path only cares about the condition code (cr5), not about which + register pair was used. */ +- lwz rWORD5,0(rSTR1) +- lwz rWORD6,0(rSTR2) +- cmplw cr5,rWORD5,rWORD6 +- blt cr7,L(dP1x) +- lwz rWORD1,4(rSTR1) +- lwz rWORD2,4(rSTR2) +- cmplw cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 0(rSTR1) ++ lwz rWORD6, 0(rSTR2) ++#endif ++ cmplw cr5, rWORD5, rWORD6 ++ blt cr7, L(dP1x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 4(rSTR1) ++ lwz rWORD2, 4(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 + L(dP1e): +- lwz rWORD3,8(rSTR1) +- lwz rWORD4,8(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- lwz rWORD5,12(rSTR1) +- lwz rWORD6,12(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- bne cr5,L(dLcr5) +- bne cr0,L(dLcr0) +- +- lwzu rWORD7,16(rSTR1) +- lwzu rWORD8,16(rSTR2) +- bne cr1,L(dLcr1) +- cmplw cr5,rWORD7,rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 8(rSTR1) ++ lwz rWORD4, 8(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 12(rSTR1) ++ lwz rWORD6, 12(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr5, L(dLcr5x) ++ bne cr7, L(dLcr7x) ++ ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwzu rWORD7, 16(rSTR1) ++ lwzu rWORD8, 16(rSTR2) ++#endif ++ bne cr1, L(dLcr1) ++ cmplw cr5, rWORD7, rWORD8 + bdnz L(dLoop) +- bne cr6,L(dLcr6) +- lwz r30,44(1) +- lwz r31,48(1) ++ bne cr6, L(dLcr6) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) + .align 3 + L(dP1x): +- slwi. r12,rN,3 +- bne cr5,L(dLcr5) +- subfic rN,r12,32 /* Shift count is 32 - (rN * 8). */ +- lwz 1,0(1) ++ slwi. r12, rN, 3 ++ bne cr5, L(dLcr5x) ++ subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + bne L(d00) +- li rRTN,0 ++ li rRTN, 0 + blr + + /* Remainder is 8 */ + .align 4 ++ cfi_adjust_cfa_offset(64) + L(dP2): +- mtctr rTMP +- lwz rWORD5,0(rSTR1) +- lwz rWORD6,0(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- blt cr7,L(dP2x) +- lwz rWORD7,4(rSTR1) +- lwz rWORD8,4(rSTR2) +- cmplw cr5,rWORD7,rWORD8 ++ mtctr r0 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 0(rSTR1) ++ lwz rWORD6, 0(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ blt cr7, L(dP2x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD7, 4(rSTR1) ++ lwz rWORD8, 4(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 + L(dP2e): +- lwz rWORD1,8(rSTR1) +- lwz rWORD2,8(rSTR2) +- cmplw cr0,rWORD1,rWORD2 +- lwz rWORD3,12(rSTR1) +- lwz rWORD4,12(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- addi rSTR1,rSTR1,4 +- addi rSTR2,rSTR2,4 +- bne cr6,L(dLcr6) +- bne cr5,L(dLcr5) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 8(rSTR1) ++ lwz rWORD2, 8(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 12(rSTR1) ++ lwz rWORD4, 12(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#endif ++ bne cr6, L(dLcr6) ++ bne cr5, L(dLcr5) + b L(dLoop2) + /* Again we are on a early exit path (16-23 byte compare), we want to + only use volatile registers and avoid restoring non-volatile + registers. */ + .align 4 + L(dP2x): +- lwz rWORD3,4(rSTR1) +- lwz rWORD4,4(rSTR2) +- cmplw cr5,rWORD3,rWORD4 +- slwi. r12,rN,3 +- bne cr6,L(dLcr6) +- addi rSTR1,rSTR1,4 +- addi rSTR2,rSTR2,4 +- bne cr5,L(dLcr5) +- subfic rN,r12,32 /* Shift count is 32 - (rN * 8). */ +- lwz 1,0(1) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 4(rSTR1) ++ lwz rWORD4, 4(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ slwi. r12, rN, 3 ++ bne cr6, L(dLcr6x) ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#endif ++ bne cr1, L(dLcr1x) ++ subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + bne L(d00) +- li rRTN,0 ++ li rRTN, 0 + blr + + /* Remainder is 12 */ + .align 4 ++ cfi_adjust_cfa_offset(64) + L(dP3): +- mtctr rTMP +- lwz rWORD3,0(rSTR1) +- lwz rWORD4,0(rSTR2) +- cmplw cr1,rWORD3,rWORD4 ++ mtctr r0 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 0(rSTR1) ++ lwz rWORD4, 0(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 + L(dP3e): +- lwz rWORD5,4(rSTR1) +- lwz rWORD6,4(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- blt cr7,L(dP3x) +- lwz rWORD7,8(rSTR1) +- lwz rWORD8,8(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- lwz rWORD1,12(rSTR1) +- lwz rWORD2,12(rSTR2) +- cmplw cr0,rWORD1,rWORD2 +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- bne cr1,L(dLcr1) +- bne cr6,L(dLcr6) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 4(rSTR1) ++ lwz rWORD6, 4(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ blt cr7, L(dP3x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD7, 8(rSTR1) ++ lwz rWORD8, 8(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 12(rSTR1) ++ lwz rWORD2, 12(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ bne cr1, L(dLcr1) ++ bne cr6, L(dLcr6) + b L(dLoop1) + /* Again we are on a early exit path (24-31 byte compare), we want to + only use volatile registers and avoid restoring non-volatile + registers. */ + .align 4 + L(dP3x): +- lwz rWORD1,8(rSTR1) +- lwz rWORD2,8(rSTR2) +- cmplw cr5,rWORD1,rWORD2 +- slwi. r12,rN,3 +- bne cr1,L(dLcr1) +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- bne cr6,L(dLcr6) +- subfic rN,r12,32 /* Shift count is 32 - (rN * 8). */ +- bne cr5,L(dLcr5) +- lwz 1,0(1) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 8(rSTR1) ++ lwz rWORD2, 8(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ slwi. r12, rN, 3 ++ bne cr1, L(dLcr1x) ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ bne cr6, L(dLcr6x) ++ subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ ++ bne cr7, L(dLcr7x) ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + bne L(d00) +- li rRTN,0 ++ li rRTN, 0 + blr + + /* Count is a multiple of 16, remainder is 0 */ + .align 4 ++ cfi_adjust_cfa_offset(64) + L(dP4): +- mtctr rTMP +- lwz rWORD1,0(rSTR1) +- lwz rWORD2,0(rSTR2) +- cmplw cr0,rWORD1,rWORD2 ++ mtctr r0 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 0(rSTR1) ++ lwz rWORD2, 0(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 + L(dP4e): +- lwz rWORD3,4(rSTR1) +- lwz rWORD4,4(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- lwz rWORD5,8(rSTR1) +- lwz rWORD6,8(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- lwzu rWORD7,12(rSTR1) +- lwzu rWORD8,12(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- bne cr0,L(dLcr0) +- bne cr1,L(dLcr1) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 4(rSTR1) ++ lwz rWORD4, 4(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 8(rSTR1) ++ lwz rWORD6, 8(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwzu rWORD7, 12(rSTR1) ++ lwzu rWORD8, 12(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ bne cr7, L(dLcr7) ++ bne cr1, L(dLcr1) + bdz- L(d24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ + .align 4 + L(dLoop): +- lwz rWORD1,4(rSTR1) +- lwz rWORD2,4(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- bne cr6,L(dLcr6) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 4(rSTR1) ++ lwz rWORD2, 4(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ bne cr6, L(dLcr6) + L(dLoop1): +- lwz rWORD3,8(rSTR1) +- lwz rWORD4,8(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- bne cr5,L(dLcr5) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 8(rSTR1) ++ lwz rWORD4, 8(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr5, L(dLcr5) + L(dLoop2): +- lwz rWORD5,12(rSTR1) +- lwz rWORD6,12(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- bne cr0,L(dLcr0) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 12(rSTR1) ++ lwz rWORD6, 12(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ bne cr7, L(dLcr7) + L(dLoop3): +- lwzu rWORD7,16(rSTR1) +- lwzu rWORD8,16(rSTR2) +- bne cr1,L(dLcr1) +- cmplw cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwzu rWORD7, 16(rSTR1) ++ lwzu rWORD8, 16(rSTR2) ++#endif ++ bne cr1, L(dLcr1) ++ cmplw cr7, rWORD1, rWORD2 + bdnz L(dLoop) + + L(dL4): +- cmplw cr1,rWORD3,rWORD4 +- bne cr6,L(dLcr6) +- cmplw cr6,rWORD5,rWORD6 +- bne cr5,L(dLcr5) +- cmplw cr5,rWORD7,rWORD8 ++ cmplw cr1, rWORD3, rWORD4 ++ bne cr6, L(dLcr6) ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr5, L(dLcr5) ++ cmplw cr5, rWORD7, rWORD8 + L(d44): +- bne cr0,L(dLcr0) ++ bne cr7, L(dLcr7) + L(d34): +- bne cr1,L(dLcr1) ++ bne cr1, L(dLcr1) + L(d24): +- bne cr6,L(dLcr6) ++ bne cr6, L(dLcr6) + L(d14): +- slwi. r12,rN,3 +- bne cr5,L(dLcr5) ++ slwi. r12, rN, 3 ++ bne cr5, L(dLcr5) + L(d04): +- lwz r30,44(1) +- lwz r31,48(1) +- lwz 1,0(1) +- subfic rN,r12,32 /* Shift count is 32 - (rN * 8). */ ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) ++ subfic rN, r12, 32 /* Shift count is 32 - (rN * 8). */ + beq L(zeroLength) + /* At this point we have a remainder of 1 to 3 bytes to compare. Since + we are aligned it is safe to load the whole word, and use +- shift right to eliminate bits beyond the compare length. */ ++ shift right to eliminate bits beyond the compare length. */ + L(d00): +- lwz rWORD1,4(rSTR1) +- lwz rWORD2,4(rSTR2) +- srw rWORD1,rWORD1,rN +- srw rWORD2,rWORD2,rN +- cmplw rWORD1,rWORD2 +- li rRTN,0 +- beqlr +- li rRTN,1 +- bgtlr +- li rRTN,-1 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 4(rSTR1) ++ lwz rWORD2, 4(rSTR2) ++#endif ++ srw rWORD1, rWORD1, rN ++ srw rWORD2, rWORD2, rN ++ sub rRTN, rWORD1, rWORD2 + blr + + .align 4 +-L(dLcr0): +- lwz r30,44(1) +- lwz r31,48(1) +- li rRTN,1 +- lwz 1,0(1) +- bgtlr cr0 +- li rRTN,-1 ++ cfi_adjust_cfa_offset(64) ++L(dLcr7): ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++L(dLcr7x): ++ li rRTN, 1 ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) ++ bgtlr cr7 ++ li rRTN, -1 + blr + .align 4 ++ cfi_adjust_cfa_offset(64) + L(dLcr1): +- lwz r30,44(1) +- lwz r31,48(1) +- li rRTN,1 +- lwz 1,0(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++L(dLcr1x): ++ li rRTN, 1 ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + bgtlr cr1 +- li rRTN,-1 ++ li rRTN, -1 + blr + .align 4 ++ cfi_adjust_cfa_offset(64) + L(dLcr6): +- lwz r30,44(1) +- lwz r31,48(1) +- li rRTN,1 +- lwz 1,0(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) ++L(dLcr6x): ++ li rRTN, 1 ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + bgtlr cr6 +- li rRTN,-1 ++ li rRTN, -1 + blr + .align 4 ++ cfi_adjust_cfa_offset(64) + L(dLcr5): +- lwz r30,44(1) +- lwz r31,48(1) ++ lwz rWORD7, 44(r1) ++ lwz rWORD8, 48(r1) + L(dLcr5x): +- li rRTN,1 +- lwz 1,0(1) ++ li rRTN, 1 ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + bgtlr cr5 +- li rRTN,-1 ++ li rRTN, -1 + blr + + .align 4 + L(bytealigned): +- cfi_adjust_cfa_offset(-64) + mtctr rN + + /* We need to prime this loop. This loop is swing modulo scheduled +@@ -413,38 +618,39 @@ + + So we must precondition some registers and condition codes so that + we don't exit the loop early on the first iteration. */ +- lbz rWORD1,0(rSTR1) +- lbz rWORD2,0(rSTR2) ++ ++ lbz rWORD1, 0(rSTR1) ++ lbz rWORD2, 0(rSTR2) + bdz L(b11) +- cmplw cr0,rWORD1,rWORD2 +- lbz rWORD3,1(rSTR1) +- lbz rWORD4,1(rSTR2) ++ cmplw cr7, rWORD1, rWORD2 ++ lbz rWORD3, 1(rSTR1) ++ lbz rWORD4, 1(rSTR2) + bdz L(b12) +- cmplw cr1,rWORD3,rWORD4 +- lbzu rWORD5,2(rSTR1) +- lbzu rWORD6,2(rSTR2) ++ cmplw cr1, rWORD3, rWORD4 ++ lbzu rWORD5, 2(rSTR1) ++ lbzu rWORD6, 2(rSTR2) + bdz L(b13) + .align 4 + L(bLoop): +- lbzu rWORD1,1(rSTR1) +- lbzu rWORD2,1(rSTR2) +- bne cr0,L(bLcr0) ++ lbzu rWORD1, 1(rSTR1) ++ lbzu rWORD2, 1(rSTR2) ++ bne cr7, L(bLcr7) + +- cmplw cr6,rWORD5,rWORD6 ++ cmplw cr6, rWORD5, rWORD6 + bdz L(b3i) + +- lbzu rWORD3,1(rSTR1) +- lbzu rWORD4,1(rSTR2) +- bne cr1,L(bLcr1) ++ lbzu rWORD3, 1(rSTR1) ++ lbzu rWORD4, 1(rSTR2) ++ bne cr1, L(bLcr1) + +- cmplw cr0,rWORD1,rWORD2 ++ cmplw cr7, rWORD1, rWORD2 + bdz L(b2i) + +- lbzu rWORD5,1(rSTR1) +- lbzu rWORD6,1(rSTR2) +- bne cr6,L(bLcr6) ++ lbzu rWORD5, 1(rSTR1) ++ lbzu rWORD6, 1(rSTR2) ++ bne cr6, L(bLcr6) + +- cmplw cr1,rWORD3,rWORD4 ++ cmplw cr1, rWORD3, rWORD4 + bdnz L(bLoop) + + /* We speculatively loading bytes before we have tested the previous +@@ -454,67 +660,62 @@ + tested. In this case we must complete the pending operations + before returning. */ + L(b1i): +- bne cr0,L(bLcr0) +- bne cr1,L(bLcr1) ++ bne cr7, L(bLcr7) ++ bne cr1, L(bLcr1) + b L(bx56) + .align 4 + L(b2i): +- bne cr6,L(bLcr6) +- bne cr0,L(bLcr0) ++ bne cr6, L(bLcr6) ++ bne cr7, L(bLcr7) + b L(bx34) + .align 4 + L(b3i): +- bne cr1,L(bLcr1) +- bne cr6,L(bLcr6) ++ bne cr1, L(bLcr1) ++ bne cr6, L(bLcr6) + b L(bx12) + .align 4 +-L(bLcr0): +- li rRTN,1 +- bgtlr cr0 +- li rRTN,-1 ++L(bLcr7): ++ li rRTN, 1 ++ bgtlr cr7 ++ li rRTN, -1 + blr + L(bLcr1): +- li rRTN,1 ++ li rRTN, 1 + bgtlr cr1 +- li rRTN,-1 ++ li rRTN, -1 + blr + L(bLcr6): +- li rRTN,1 ++ li rRTN, 1 + bgtlr cr6 +- li rRTN,-1 ++ li rRTN, -1 + blr + + L(b13): +- bne cr0,L(bx12) +- bne cr1,L(bx34) ++ bne cr7, L(bx12) ++ bne cr1, L(bx34) + L(bx56): +- sub rRTN,rWORD5,rWORD6 ++ sub rRTN, rWORD5, rWORD6 + blr + nop + L(b12): +- bne cr0,L(bx12) ++ bne cr7, L(bx12) + L(bx34): +- sub rRTN,rWORD3,rWORD4 ++ sub rRTN, rWORD3, rWORD4 + blr +- + L(b11): + L(bx12): +- sub rRTN,rWORD1,rWORD2 ++ sub rRTN, rWORD1, rWORD2 + blr +- + .align 4 +-L(zeroLengthReturn): +- + L(zeroLength): +- li rRTN,0 ++ li rRTN, 0 + blr + +- cfi_adjust_cfa_offset(64) + .align 4 + /* At this point we know the strings have different alignment and the +- compare length is at least 8 bytes. rBITDIF contains the low order ++ compare length is at least 8 bytes. r12 contains the low order + 2 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then rStr1 is word aligned and can ++ of r12 to 0. If r12 == 0 then rStr1 is word aligned and can + perform the Wunaligned loop. + + Otherwise we know that rSTR1 is not aready word aligned yet. +@@ -523,465 +724,654 @@ + eliminate bits preceeding the first byte. Since we want to join the + normal (Wualigned) compare loop, starting at the second word, + we need to adjust the length (rN) and special case the loop +- versioning for the first W. This insures that the loop count is ++ versioning for the first W. This ensures that the loop count is + correct and the first W (shifted) is in the expected resister pair. */ + #define rSHL r29 /* Unaligned shift left count. */ + #define rSHR r28 /* Unaligned shift right count. */ +-#define rB r27 /* Left rotation temp for rWORD2. */ +-#define rD r26 /* Left rotation temp for rWORD4. */ +-#define rF r25 /* Left rotation temp for rWORD6. */ +-#define rH r24 /* Left rotation temp for rWORD8. */ +-#define rA r0 /* Right rotation temp for rWORD2. */ +-#define rC r12 /* Right rotation temp for rWORD4. */ +-#define rE r0 /* Right rotation temp for rWORD6. */ +-#define rG r12 /* Right rotation temp for rWORD8. */ ++#define rWORD8_SHIFT r27 /* Left rotation temp for rWORD2. */ ++#define rWORD2_SHIFT r26 /* Left rotation temp for rWORD4. */ ++#define rWORD4_SHIFT r25 /* Left rotation temp for rWORD6. */ ++#define rWORD6_SHIFT r24 /* Left rotation temp for rWORD8. */ ++ cfi_adjust_cfa_offset(64) + L(unaligned): +- stw r29,40(r1) +- cfi_offset(r29,(40-64)) +- clrlwi rSHL,rSTR2,30 +- stw r28,36(r1) +- cfi_offset(r28,(36-64)) +- beq cr5,L(Wunaligned) +- stw r27,32(r1) +- cfi_offset(r27,(32-64)) ++ stw rSHL, 40(r1) ++ cfi_offset(rSHL, (40-64)) ++ clrlwi rSHL, rSTR2, 30 ++ stw rSHR, 36(r1) ++ cfi_offset(rSHR, (36-64)) ++ beq cr5, L(Wunaligned) ++ stw rWORD8_SHIFT, 32(r1) ++ cfi_offset(rWORD8_SHIFT, (32-64)) + /* Adjust the logical start of rSTR2 to compensate for the extra bits + in the 1st rSTR1 W. */ +- sub r27,rSTR2,rBITDIF ++ sub rWORD8_SHIFT, rSTR2, r12 + /* But do not attempt to address the W before that W that contains + the actual start of rSTR2. */ +- clrrwi rSTR2,rSTR2,2 +- stw r26,28(r1) +- cfi_offset(r26,(28-64)) +-/* Compute the left/right shift counts for the unalign rSTR2, ++ clrrwi rSTR2, rSTR2, 2 ++ stw rWORD2_SHIFT, 28(r1) ++ cfi_offset(rWORD2_SHIFT, (28-64)) ++/* Compute the left/right shift counts for the unaligned rSTR2, + compensating for the logical (W aligned) start of rSTR1. */ +- clrlwi rSHL,r27,30 +- clrrwi rSTR1,rSTR1,2 +- stw r25,24(r1) +- cfi_offset(r25,(24-64)) +- slwi rSHL,rSHL,3 +- cmplw cr5,r27,rSTR2 +- add rN,rN,rBITDIF +- slwi r11,rBITDIF,3 +- stw r24,20(r1) +- cfi_offset(r24,(20-64)) +- subfic rSHR,rSHL,32 +- srwi rTMP,rN,4 /* Divide by 16 */ +- andi. rBITDIF,rN,12 /* Get the W remainder */ ++ clrlwi rSHL, rWORD8_SHIFT, 30 ++ clrrwi rSTR1, rSTR1, 2 ++ stw rWORD4_SHIFT, 24(r1) ++ cfi_offset(rWORD4_SHIFT, (24-64)) ++ slwi rSHL, rSHL, 3 ++ cmplw cr5, rWORD8_SHIFT, rSTR2 ++ add rN, rN, r12 ++ slwi rWORD6, r12, 3 ++ stw rWORD6_SHIFT, 20(r1) ++ cfi_offset(rWORD6_SHIFT, (20-64)) ++ subfic rSHR, rSHL, 32 ++ srwi r0, rN, 4 /* Divide by 16 */ ++ andi. r12, rN, 12 /* Get the W remainder */ + /* We normally need to load 2 Ws to start the unaligned rSTR2, but in + this special case those bits may be discarded anyway. Also we + must avoid loading a W where none of the bits are part of rSTR2 as + this may cross a page boundary and cause a page fault. */ +- li rWORD8,0 +- blt cr5,L(dus0) +- lwz rWORD8,0(rSTR2) +- la rSTR2,4(rSTR2) +- slw rWORD8,rWORD8,rSHL ++ li rWORD8, 0 ++ blt cr5, L(dus0) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD8, 0(rSTR2) ++ addi rSTR2, rSTR2, 4 ++#endif ++ slw rWORD8, rWORD8, rSHL + + L(dus0): +- lwz rWORD1,0(rSTR1) +- lwz rWORD2,0(rSTR2) +- cmplwi cr1,rBITDIF,8 +- cmplwi cr7,rN,16 +- srw rG,rWORD2,rSHR +- clrlwi rN,rN,30 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 0(rSTR1) ++ lwz rWORD2, 0(rSTR2) ++#endif ++ cmplwi cr1, r12, 8 ++ cmplwi cr7, rN, 16 ++ srw r12, rWORD2, rSHR ++ clrlwi rN, rN, 30 + beq L(duPs4) +- mtctr rTMP +- or rWORD8,rG,rWORD8 +- bgt cr1,L(duPs3) +- beq cr1,L(duPs2) ++ mtctr r0 ++ or rWORD8, r12, rWORD8 ++ bgt cr1, L(duPs3) ++ beq cr1, L(duPs2) + + /* Remainder is 4 */ + .align 4 + L(dusP1): +- slw rB,rWORD2,rSHL +- slw rWORD7,rWORD1,r11 +- slw rWORD8,rWORD8,r11 +- bge cr7,L(duP1e) ++ slw rWORD8_SHIFT, rWORD2, rSHL ++ slw rWORD7, rWORD1, rWORD6 ++ slw rWORD8, rWORD8, rWORD6 ++ bge cr7, L(duP1e) + /* At this point we exit early with the first word compare + complete and remainder of 0 to 3 bytes. See L(du14) for details on + how we handle the remaining bytes. */ +- cmplw cr5,rWORD7,rWORD8 +- slwi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmplw cr7,rN,rSHR ++ cmplw cr5, rWORD7, rWORD8 ++ slwi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- lwz rWORD2,4(rSTR2) +- srw rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD2, 4(rSTR2) ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 8 */ + .align 4 + L(duPs2): +- slw rH,rWORD2,rSHL +- slw rWORD5,rWORD1,r11 +- slw rWORD6,rWORD8,r11 ++ slw rWORD6_SHIFT, rWORD2, rSHL ++ slw rWORD5, rWORD1, rWORD6 ++ slw rWORD6, rWORD8, rWORD6 + b L(duP2e) + /* Remainder is 12 */ + .align 4 + L(duPs3): +- slw rF,rWORD2,rSHL +- slw rWORD3,rWORD1,r11 +- slw rWORD4,rWORD8,r11 ++ slw rWORD4_SHIFT, rWORD2, rSHL ++ slw rWORD3, rWORD1, rWORD6 ++ slw rWORD4, rWORD8, rWORD6 + b L(duP3e) + /* Count is a multiple of 16, remainder is 0 */ + .align 4 + L(duPs4): +- mtctr rTMP +- or rWORD8,rG,rWORD8 +- slw rD,rWORD2,rSHL +- slw rWORD1,rWORD1,r11 +- slw rWORD2,rWORD8,r11 ++ mtctr r0 ++ or rWORD8, r12, rWORD8 ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ slw rWORD1, rWORD1, rWORD6 ++ slw rWORD2, rWORD8, rWORD6 + b L(duP4e) + + /* At this point we know rSTR1 is word aligned and the + compare length is at least 8 bytes. */ + .align 4 + L(Wunaligned): +- stw r27,32(r1) +- cfi_offset(r27,(32-64)) +- clrrwi rSTR2,rSTR2,2 +- stw r26,28(r1) +- cfi_offset(r26,(28-64)) +- srwi rTMP,rN,4 /* Divide by 16 */ +- stw r25,24(r1) +- cfi_offset(r25,(24-64)) +- andi. rBITDIF,rN,12 /* Get the W remainder */ +- stw r24,20(r1) +- cfi_offset(r24,(24-64)) +- slwi rSHL,rSHL,3 +- lwz rWORD6,0(rSTR2) +- lwzu rWORD8,4(rSTR2) +- cmplwi cr1,rBITDIF,8 +- cmplwi cr7,rN,16 +- clrlwi rN,rN,30 +- subfic rSHR,rSHL,32 +- slw rH,rWORD6,rSHL ++ stw rWORD8_SHIFT, 32(r1) ++ cfi_offset(rWORD8_SHIFT, (32-64)) ++ clrrwi rSTR2, rSTR2, 2 ++ stw rWORD2_SHIFT, 28(r1) ++ cfi_offset(rWORD2_SHIFT, (28-64)) ++ srwi r0, rN, 4 /* Divide by 16 */ ++ stw rWORD4_SHIFT, 24(r1) ++ cfi_offset(rWORD4_SHIFT, (24-64)) ++ andi. r12, rN, 12 /* Get the W remainder */ ++ stw rWORD6_SHIFT, 20(r1) ++ cfi_offset(rWORD6_SHIFT, (20-64)) ++ slwi rSHL, rSHL, 3 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD6, 0(rSTR2) ++ lwzu rWORD8, 4(rSTR2) ++#endif ++ cmplwi cr1, r12, 8 ++ cmplwi cr7, rN, 16 ++ clrlwi rN, rN, 30 ++ subfic rSHR, rSHL, 32 ++ slw rWORD6_SHIFT, rWORD6, rSHL + beq L(duP4) +- mtctr rTMP +- bgt cr1,L(duP3) +- beq cr1,L(duP2) ++ mtctr r0 ++ bgt cr1, L(duP3) ++ beq cr1, L(duP2) + + /* Remainder is 4 */ + .align 4 + L(duP1): +- srw rG,rWORD8,rSHR +- lwz rWORD7,0(rSTR1) +- slw rB,rWORD8,rSHL +- or rWORD8,rG,rH +- blt cr7,L(duP1x) ++ srw r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else ++ lwz rWORD7, 0(rSTR1) ++#endif ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ blt cr7, L(duP1x) + L(duP1e): +- lwz rWORD1,4(rSTR1) +- lwz rWORD2,4(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- srw rA,rWORD2,rSHR +- slw rD,rWORD2,rSHL +- or rWORD2,rA,rB +- lwz rWORD3,8(rSTR1) +- lwz rWORD4,8(rSTR2) +- cmplw cr0,rWORD1,rWORD2 +- srw rC,rWORD4,rSHR +- slw rF,rWORD4,rSHL +- bne cr5,L(duLcr5) +- or rWORD4,rC,rD +- lwz rWORD5,12(rSTR1) +- lwz rWORD6,12(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- srw rE,rWORD6,rSHR +- slw rH,rWORD6,rSHL +- bne cr0,L(duLcr0) +- or rWORD6,rE,rF +- cmplw cr6,rWORD5,rWORD6 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 4(rSTR1) ++ lwz rWORD2, 4(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 8(rSTR1) ++ lwz rWORD4, 8(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ bne cr5, L(duLcr5) ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 12(rSTR1) ++ lwz rWORD6, 12(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ bne cr7, L(duLcr7) ++ or rWORD6, r0, rWORD4_SHIFT ++ cmplw cr6, rWORD5, rWORD6 + b L(duLoop3) + .align 4 + /* At this point we exit early with the first word compare + complete and remainder of 0 to 3 bytes. See L(du14) for details on + how we handle the remaining bytes. */ + L(duP1x): +- cmplw cr5,rWORD7,rWORD8 +- slwi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmplw cr7,rN,rSHR ++ cmplw cr5, rWORD7, rWORD8 ++ slwi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- ld rWORD2,8(rSTR2) +- srw rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD2, 8(rSTR2) ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 8 */ + .align 4 + L(duP2): +- srw rE,rWORD8,rSHR +- lwz rWORD5,0(rSTR1) +- or rWORD6,rE,rH +- slw rH,rWORD8,rSHL ++ srw r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else ++ lwz rWORD5, 0(rSTR1) ++#endif ++ or rWORD6, r0, rWORD6_SHIFT ++ slw rWORD6_SHIFT, rWORD8, rSHL + L(duP2e): +- lwz rWORD7,4(rSTR1) +- lwz rWORD8,4(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- srw rG,rWORD8,rSHR +- slw rB,rWORD8,rSHL +- or rWORD8,rG,rH +- blt cr7,L(duP2x) +- lwz rWORD1,8(rSTR1) +- lwz rWORD2,8(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- bne cr6,L(duLcr6) +- srw rA,rWORD2,rSHR +- slw rD,rWORD2,rSHL +- or rWORD2,rA,rB +- lwz rWORD3,12(rSTR1) +- lwz rWORD4,12(rSTR2) +- cmplw cr0,rWORD1,rWORD2 +- bne cr5,L(duLcr5) +- srw rC,rWORD4,rSHR +- slw rF,rWORD4,rSHL +- or rWORD4,rC,rD +- addi rSTR1,rSTR1,4 +- addi rSTR2,rSTR2,4 +- cmplw cr1,rWORD3,rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD7, 4(rSTR1) ++ lwz rWORD8, 4(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ blt cr7, L(duP2x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 8(rSTR1) ++ lwz rWORD2, 8(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ bne cr6, L(duLcr6) ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 12(rSTR1) ++ lwz rWORD4, 12(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ bne cr5, L(duLcr5) ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#endif ++ cmplw cr1, rWORD3, rWORD4 + b L(duLoop2) + .align 4 + L(duP2x): +- cmplw cr5,rWORD7,rWORD8 +- addi rSTR1,rSTR1,4 +- addi rSTR2,rSTR2,4 +- bne cr6,L(duLcr6) +- slwi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmplw cr7,rN,rSHR ++ cmplw cr5, rWORD7, rWORD8 ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#endif ++ bne cr6, L(duLcr6) ++ slwi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- lwz rWORD2,4(rSTR2) +- srw rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD2, 4(rSTR2) ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + + /* Remainder is 12 */ + .align 4 + L(duP3): +- srw rC,rWORD8,rSHR +- lwz rWORD3,0(rSTR1) +- slw rF,rWORD8,rSHL +- or rWORD4,rC,rH ++ srw r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else ++ lwz rWORD3, 0(rSTR1) ++#endif ++ slw rWORD4_SHIFT, rWORD8, rSHL ++ or rWORD4, r12, rWORD6_SHIFT + L(duP3e): +- lwz rWORD5,4(rSTR1) +- lwz rWORD6,4(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- srw rE,rWORD6,rSHR +- slw rH,rWORD6,rSHL +- or rWORD6,rE,rF +- lwz rWORD7,8(rSTR1) +- lwz rWORD8,8(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- bne cr1,L(duLcr1) +- srw rG,rWORD8,rSHR +- slw rB,rWORD8,rSHL +- or rWORD8,rG,rH +- blt cr7,L(duP3x) +- lwz rWORD1,12(rSTR1) +- lwz rWORD2,12(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- bne cr6,L(duLcr6) +- srw rA,rWORD2,rSHR +- slw rD,rWORD2,rSHL +- or rWORD2,rA,rB +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- cmplw cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 4(rSTR1) ++ lwz rWORD6, 4(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD7, 8(rSTR1) ++ lwz rWORD8, 8(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr1, L(duLcr1) ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ blt cr7, L(duP3x) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 12(rSTR1) ++ lwz rWORD2, 12(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ bne cr6, L(duLcr6) ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ cmplw cr7, rWORD1, rWORD2 + b L(duLoop1) + .align 4 + L(duP3x): +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- bne cr1,L(duLcr1) +- cmplw cr5,rWORD7,rWORD8 +- bne cr6,L(duLcr6) +- slwi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmplw cr7,rN,rSHR ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++#if 0 ++/* Huh? We've already branched on cr1! */ ++ bne cr1, L(duLcr1) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ bne cr6, L(duLcr6) ++ slwi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- lwz rWORD2,4(rSTR2) +- srw rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD2, 4(rSTR2) ++#endif ++ srw r0, rWORD2, rSHR + b L(dutrim) + + /* Count is a multiple of 16, remainder is 0 */ + .align 4 + L(duP4): +- mtctr rTMP +- srw rA,rWORD8,rSHR +- lwz rWORD1,0(rSTR1) +- slw rD,rWORD8,rSHL +- or rWORD2,rA,rH ++ mtctr r0 ++ srw r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ addi rSTR1, rSTR1, 4 ++#else ++ lwz rWORD1, 0(rSTR1) ++#endif ++ slw rWORD2_SHIFT, rWORD8, rSHL ++ or rWORD2, r0, rWORD6_SHIFT + L(duP4e): +- lwz rWORD3,4(rSTR1) +- lwz rWORD4,4(rSTR2) +- cmplw cr0,rWORD1,rWORD2 +- srw rC,rWORD4,rSHR +- slw rF,rWORD4,rSHL +- or rWORD4,rC,rD +- lwz rWORD5,8(rSTR1) +- lwz rWORD6,8(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- bne cr0,L(duLcr0) +- srw rE,rWORD6,rSHR +- slw rH,rWORD6,rSHL +- or rWORD6,rE,rF +- lwzu rWORD7,12(rSTR1) +- lwzu rWORD8,12(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- bne cr1,L(duLcr1) +- srw rG,rWORD8,rSHR +- slw rB,rWORD8,rSHL +- or rWORD8,rG,rH +- cmplw cr5,rWORD7,rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 4(rSTR1) ++ lwz rWORD4, 4(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 8(rSTR1) ++ lwz rWORD6, 8(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ bne cr7, L(duLcr7) ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwzu rWORD7, 12(rSTR1) ++ lwzu rWORD8, 12(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr1, L(duLcr1) ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ cmplw cr5, rWORD7, rWORD8 + bdz L(du24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ + .align 4 + L(duLoop): +- lwz rWORD1,4(rSTR1) +- lwz rWORD2,4(rSTR2) +- cmplw cr1,rWORD3,rWORD4 +- bne cr6,L(duLcr6) +- srw rA,rWORD2,rSHR +- slw rD,rWORD2,rSHL +- or rWORD2,rA,rB ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD1, 4(rSTR1) ++ lwz rWORD2, 4(rSTR2) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ bne cr6, L(duLcr6) ++ srw r0, rWORD2, rSHR ++ slw rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT + L(duLoop1): +- lwz rWORD3,8(rSTR1) +- lwz rWORD4,8(rSTR2) +- cmplw cr6,rWORD5,rWORD6 +- bne cr5,L(duLcr5) +- srw rC,rWORD4,rSHR +- slw rF,rWORD4,rSHL +- or rWORD4,rC,rD ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD3, 0, rSTR1 ++ lwbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD3, 8(rSTR1) ++ lwz rWORD4, 8(rSTR2) ++#endif ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr5, L(duLcr5) ++ srw r12, rWORD4, rSHR ++ slw rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT + L(duLoop2): +- lwz rWORD5,12(rSTR1) +- lwz rWORD6,12(rSTR2) +- cmplw cr5,rWORD7,rWORD8 +- bne cr0,L(duLcr0) +- srw rE,rWORD6,rSHR +- slw rH,rWORD6,rSHL +- or rWORD6,rE,rF ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD5, 0, rSTR1 ++ lwbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD5, 12(rSTR1) ++ lwz rWORD6, 12(rSTR2) ++#endif ++ cmplw cr5, rWORD7, rWORD8 ++ bne cr7, L(duLcr7) ++ srw r0, rWORD6, rSHR ++ slw rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT + L(duLoop3): +- lwzu rWORD7,16(rSTR1) +- lwzu rWORD8,16(rSTR2) +- cmplw cr0,rWORD1,rWORD2 +- bne cr1,L(duLcr1) +- srw rG,rWORD8,rSHR +- slw rB,rWORD8,rSHL +- or rWORD8,rG,rH ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD7, 0, rSTR1 ++ lwbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwzu rWORD7, 16(rSTR1) ++ lwzu rWORD8, 16(rSTR2) ++#endif ++ cmplw cr7, rWORD1, rWORD2 ++ bne cr1, L(duLcr1) ++ srw r12, rWORD8, rSHR ++ slw rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + bdnz L(duLoop) + + L(duL4): +- bne cr1,L(duLcr1) +- cmplw cr1,rWORD3,rWORD4 +- bne cr6,L(duLcr6) +- cmplw cr6,rWORD5,rWORD6 +- bne cr5,L(duLcr5) +- cmplw cr5,rWORD7,rWORD8 ++#if 0 ++/* Huh? We've already branched on cr1! */ ++ bne cr1, L(duLcr1) ++#endif ++ cmplw cr1, rWORD3, rWORD4 ++ bne cr6, L(duLcr6) ++ cmplw cr6, rWORD5, rWORD6 ++ bne cr5, L(duLcr5) ++ cmplw cr5, rWORD7, rWORD8 + L(du44): +- bne cr0,L(duLcr0) ++ bne cr7, L(duLcr7) + L(du34): +- bne cr1,L(duLcr1) ++ bne cr1, L(duLcr1) + L(du24): +- bne cr6,L(duLcr6) ++ bne cr6, L(duLcr6) + L(du14): +- slwi. rN,rN,3 +- bne cr5,L(duLcr5) ++ slwi. rN, rN, 3 ++ bne cr5, L(duLcr5) + /* At this point we have a remainder of 1 to 3 bytes to compare. We use + shift right to eliminate bits beyond the compare length. ++ This allows the use of word subtract to compute the final result. + + However it may not be safe to load rWORD2 which may be beyond the + string length. So we compare the bit length of the remainder to + the right shift count (rSHR). If the bit count is less than or equal + we do not need to load rWORD2 (all significant bits are already in +- rB). */ +- cmplw cr7,rN,rSHR ++ rWORD8_SHIFT). */ ++ cmplw cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- lwz rWORD2,4(rSTR2) +- srw rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 4 ++#else ++ lwz rWORD2, 4(rSTR2) ++#endif ++ srw r0, rWORD2, rSHR + .align 4 + L(dutrim): +- lwz rWORD1,4(rSTR1) +- lwz r31,48(1) +- subfic rN,rN,32 /* Shift count is 32 - (rN * 8). */ +- or rWORD2,rA,rB +- lwz r30,44(1) +- lwz r29,40(r1) +- srw rWORD1,rWORD1,rN +- srw rWORD2,rWORD2,rN +- lwz r28,36(r1) +- lwz r27,32(r1) +- cmplw rWORD1,rWORD2 +- li rRTN,0 +- beq L(dureturn26) +- li rRTN,1 +- bgt L(dureturn26) +- li rRTN,-1 ++#ifdef __LITTLE_ENDIAN__ ++ lwbrx rWORD1, 0, rSTR1 ++#else ++ lwz rWORD1, 4(rSTR1) ++#endif ++ lwz rWORD8, 48(r1) ++ subfic rN, rN, 32 /* Shift count is 32 - (rN * 8). */ ++ or rWORD2, r0, rWORD8_SHIFT ++ lwz rWORD7, 44(r1) ++ lwz rSHL, 40(r1) ++ srw rWORD1, rWORD1, rN ++ srw rWORD2, rWORD2, rN ++ lwz rSHR, 36(r1) ++ lwz rWORD8_SHIFT, 32(r1) ++ sub rRTN, rWORD1, rWORD2 + b L(dureturn26) + .align 4 +-L(duLcr0): +- lwz r31,48(1) +- lwz r30,44(1) +- li rRTN,1 +- bgt cr0,L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) +- li rRTN,-1 ++L(duLcr7): ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) ++ li rRTN, 1 ++ bgt cr7, L(dureturn29) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr1): +- lwz r31,48(1) +- lwz r30,44(1) +- li rRTN,1 +- bgt cr1,L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) +- li rRTN,-1 ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) ++ li rRTN, 1 ++ bgt cr1, L(dureturn29) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr6): +- lwz r31,48(1) +- lwz r30,44(1) +- li rRTN,1 +- bgt cr6,L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) +- li rRTN,-1 ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) ++ li rRTN, 1 ++ bgt cr6, L(dureturn29) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr5): +- lwz r31,48(1) +- lwz r30,44(1) +- li rRTN,1 +- bgt cr5,L(dureturn29) +- lwz r29,40(r1) +- lwz r28,36(r1) +- li rRTN,-1 ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) ++ li rRTN, 1 ++ bgt cr5, L(dureturn29) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 3 + L(duZeroReturn): +- li rRTN,0 ++ li rRTN, 0 + .align 4 + L(dureturn): +- lwz r31,48(1) +- lwz r30,44(1) ++ lwz rWORD8, 48(r1) ++ lwz rWORD7, 44(r1) + L(dureturn29): +- lwz r29,40(r1) +- lwz r28,36(r1) ++ lwz rSHL, 40(r1) ++ lwz rSHR, 36(r1) + L(dureturn27): +- lwz r27,32(r1) ++ lwz rWORD8_SHIFT, 32(r1) + L(dureturn26): +- lwz r26,28(r1) ++ lwz rWORD2_SHIFT, 28(r1) + L(dureturn25): +- lwz r25,24(r1) +- lwz r24,20(r1) +- lwz 1,0(1) ++ lwz rWORD4_SHIFT, 24(r1) ++ lwz rWORD6_SHIFT, 20(r1) ++ addi r1, r1, 64 ++ cfi_adjust_cfa_offset(-64) + blr + END (BP_SYM (memcmp)) ++ + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp,bcmp) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcmp.S 2014-05-28 19:22:37.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcmp.S 2014-05-29 09:35:25.000000000 -0500 +@@ -1,5 +1,5 @@ +-/* Optimized strcmp implementation for PowerPC64. +- Copyright (C) 2003, 2006, 2011 Free Software Foundation, Inc. ++/* Optimized memcmp implementation for PowerPC64. ++ Copyright (C) 2003-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,307 +17,492 @@ + . */ + + #include +-#include +-#include + +-/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5]) */ ++/* int [r3] memcmp (const char *s1 [r3], ++ const char *s2 [r4], ++ size_t size [r5]) */ + + .machine power4 +-EALIGN (BP_SYM(memcmp), 4, 0) ++EALIGN (memcmp, 4, 0) + CALL_MCOUNT 3 + +-#define rTMP r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ + #define rN r5 /* max string length */ +-/* Note: The Bounded pointer support in this code is broken. This code +- was inherited from PPC32 and that support was never completed. +- Current PPC gcc does not support -fbounds-check or -fbounded-pointers. */ + #define rWORD1 r6 /* current word in s1 */ + #define rWORD2 r7 /* current word in s2 */ + #define rWORD3 r8 /* next word in s1 */ + #define rWORD4 r9 /* next word in s2 */ + #define rWORD5 r10 /* next word in s1 */ + #define rWORD6 r11 /* next word in s2 */ +-#define rBITDIF r12 /* bits that differ in s1 & s2 words */ + #define rWORD7 r30 /* next word in s1 */ + #define rWORD8 r31 /* next word in s2 */ + +- xor rTMP, rSTR2, rSTR1 ++ xor r0, rSTR2, rSTR1 + cmpldi cr6, rN, 0 + cmpldi cr1, rN, 12 +- clrldi. rTMP, rTMP, 61 +- clrldi rBITDIF, rSTR1, 61 +- cmpldi cr5, rBITDIF, 0 ++ clrldi. r0, r0, 61 ++ clrldi r12, rSTR1, 61 ++ cmpldi cr5, r12, 0 + beq- cr6, L(zeroLength) +- dcbt 0,rSTR1 +- dcbt 0,rSTR2 +-/* If less than 8 bytes or not aligned, use the unalligned ++ dcbt 0, rSTR1 ++ dcbt 0, rSTR2 ++/* If less than 8 bytes or not aligned, use the unaligned + byte loop. */ + blt cr1, L(bytealigned) +- std rWORD8,-8(r1) +- cfi_offset(rWORD8,-8) +- std rWORD7,-16(r1) +- cfi_offset(rWORD7,-16) ++ std rWORD8, -8(r1) ++ cfi_offset(rWORD8, -8) ++ std rWORD7, -16(r1) ++ cfi_offset(rWORD7, -16) + bne L(unaligned) + /* At this point we know both strings have the same alignment and the +- compare length is at least 8 bytes. rBITDIF containes the low order ++ compare length is at least 8 bytes. r12 contains the low order + 3 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then we are already double word +- aligned and can perform the DWaligned loop. +- ++ of r12 to 0. If r12 == 0 then we are already double word ++ aligned and can perform the DW aligned loop. ++ + Otherwise we know the two strings have the same alignment (but not +- yet DW). So we can force the string addresses to the next lower DW +- boundary and special case this first DW word using shift left to +- ellimiate bits preceeding the first byte. Since we want to join the +- normal (DWaligned) compare loop, starting at the second double word, ++ yet DW). So we force the string addresses to the next lower DW ++ boundary and special case this first DW using shift left to ++ eliminate bits preceding the first byte. Since we want to join the ++ normal (DW aligned) compare loop, starting at the second double word, + we need to adjust the length (rN) and special case the loop +- versioning for the first DW. This insures that the loop count is +- correct and the first DW (shifted) is in the expected resister pair. */ +- .align 4 ++ versioning for the first DW. This ensures that the loop count is ++ correct and the first DW (shifted) is in the expected register pair. */ ++ .align 4 + L(samealignment): + clrrdi rSTR1, rSTR1, 3 + clrrdi rSTR2, rSTR2, 3 + beq cr5, L(DWaligned) +- add rN, rN, rBITDIF +- sldi r11, rBITDIF, 3 +- srdi rTMP, rN, 5 /* Divide by 32 */ +- andi. rBITDIF, rN, 24 /* Get the DW remainder */ ++ add rN, rN, r12 ++ sldi rWORD6, r12, 3 ++ srdi r0, rN, 5 /* Divide by 32 */ ++ andi. r12, rN, 24 /* Get the DW remainder */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 0(rSTR1) + ld rWORD2, 0(rSTR2) +- cmpldi cr1, rBITDIF, 16 ++#endif ++ cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 + clrldi rN, rN, 61 + beq L(dPs4) +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ + bgt cr1, L(dPs3) + beq cr1, L(dPs2) + + /* Remainder is 8 */ +- .align 3 ++ .align 3 + L(dsP1): +- sld rWORD5, rWORD1, r11 +- sld rWORD6, rWORD2, r11 ++ sld rWORD5, rWORD1, rWORD6 ++ sld rWORD6, rWORD2, rWORD6 + cmpld cr5, rWORD5, rWORD6 + blt cr7, L(dP1x) + /* Do something useful in this cycle since we have to branch anyway. */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 8(rSTR1) + ld rWORD2, 8(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + b L(dP1e) + /* Remainder is 16 */ +- .align 4 ++ .align 4 + L(dPs2): +- sld rWORD5, rWORD1, r11 +- sld rWORD6, rWORD2, r11 ++ sld rWORD5, rWORD1, rWORD6 ++ sld rWORD6, rWORD2, rWORD6 + cmpld cr6, rWORD5, rWORD6 + blt cr7, L(dP2x) + /* Do something useful in this cycle since we have to branch anyway. */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD7, 8(rSTR1) + ld rWORD8, 8(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 + b L(dP2e) + /* Remainder is 24 */ +- .align 4 ++ .align 4 + L(dPs3): +- sld rWORD3, rWORD1, r11 +- sld rWORD4, rWORD2, r11 ++ sld rWORD3, rWORD1, rWORD6 ++ sld rWORD4, rWORD2, rWORD6 + cmpld cr1, rWORD3, rWORD4 + b L(dP3e) + /* Count is a multiple of 32, remainder is 0 */ +- .align 4 ++ .align 4 + L(dPs4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- sld rWORD1, rWORD1, r11 +- sld rWORD2, rWORD2, r11 +- cmpld cr0, rWORD1, rWORD2 ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ sld rWORD1, rWORD1, rWORD6 ++ sld rWORD2, rWORD2, rWORD6 ++ cmpld cr7, rWORD1, rWORD2 + b L(dP4e) + + /* At this point we know both strings are double word aligned and the + compare length is at least 8 bytes. */ +- .align 4 ++ .align 4 + L(DWaligned): +- andi. rBITDIF, rN, 24 /* Get the DW remainder */ +- srdi rTMP, rN, 5 /* Divide by 32 */ +- cmpldi cr1, rBITDIF, 16 ++ andi. r12, rN, 24 /* Get the DW remainder */ ++ srdi r0, rN, 5 /* Divide by 32 */ ++ cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 + clrldi rN, rN, 61 + beq L(dP4) + bgt cr1, L(dP3) + beq cr1, L(dP2) +- ++ + /* Remainder is 8 */ +- .align 4 ++ .align 4 + L(dP1): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ + /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early +- (8-15 byte compare), we want to use only volitile registers. This +- means we can avoid restoring non-volitile registers since we did not ++ (8-15 byte compare), we want to use only volatile registers. This ++ means we can avoid restoring non-volatile registers since we did not + change any on the early exit path. The key here is the non-early +- exit path only cares about the condition code (cr5), not about which ++ exit path only cares about the condition code (cr5), not about which + register pair was used. */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 0(rSTR1) + ld rWORD6, 0(rSTR2) ++#endif + cmpld cr5, rWORD5, rWORD6 + blt cr7, L(dP1x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 8(rSTR1) + ld rWORD2, 8(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + L(dP1e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 16(rSTR1) + ld rWORD4, 16(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 24(rSTR1) + ld rWORD6, 24(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 +- bne cr5, L(dLcr5) +- bne cr0, L(dLcr0) +- ++ bne cr5, L(dLcr5x) ++ bne cr7, L(dLcr7x) ++ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ldu rWORD7, 32(rSTR1) + ldu rWORD8, 32(rSTR2) ++#endif + bne cr1, L(dLcr1) + cmpld cr5, rWORD7, rWORD8 + bdnz L(dLoop) + bne cr6, L(dLcr6) +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- .align 3 ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ .align 3 + L(dP1x): + sldi. r12, rN, 3 +- bne cr5, L(dLcr5) ++ bne cr5, L(dLcr5x) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne L(d00) + li rRTN, 0 + blr +- ++ + /* Remainder is 16 */ +- .align 4 ++ .align 4 + L(dP2): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 0(rSTR1) + ld rWORD6, 0(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 + blt cr7, L(dP2x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD7, 8(rSTR1) + ld rWORD8, 8(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 + L(dP2e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 16(rSTR1) + ld rWORD2, 16(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 24(rSTR1) + ld rWORD4, 24(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 ++#endif + bne cr6, L(dLcr6) + bne cr5, L(dLcr5) + b L(dLoop2) + /* Again we are on a early exit path (16-23 byte compare), we want to +- only use volitile registers and avoid restoring non-volitile ++ only use volatile registers and avoid restoring non-volatile + registers. */ +- .align 4 ++ .align 4 + L(dP2x): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 8(rSTR1) + ld rWORD4, 8(rSTR2) +- cmpld cr5, rWORD3, rWORD4 ++#endif ++ cmpld cr1, rWORD3, rWORD4 + sldi. r12, rN, 3 +- bne cr6, L(dLcr6) ++ bne cr6, L(dLcr6x) ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +- bne cr5, L(dLcr5) ++#endif ++ bne cr1, L(dLcr1x) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne L(d00) + li rRTN, 0 + blr +- ++ + /* Remainder is 24 */ +- .align 4 ++ .align 4 + L(dP3): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 0(rSTR1) + ld rWORD4, 0(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 + L(dP3e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 8(rSTR1) + ld rWORD6, 8(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 + blt cr7, L(dP3x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD7, 16(rSTR1) + ld rWORD8, 16(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 24(rSTR1) + ld rWORD2, 24(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 ++#endif + bne cr1, L(dLcr1) + bne cr6, L(dLcr6) + b L(dLoop1) + /* Again we are on a early exit path (24-31 byte compare), we want to +- only use volitile registers and avoid restoring non-volitile ++ only use volatile registers and avoid restoring non-volatile + registers. */ +- .align 4 ++ .align 4 + L(dP3x): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 16(rSTR1) + ld rWORD2, 16(rSTR2) +- cmpld cr5, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + sldi. r12, rN, 3 +- bne cr1, L(dLcr1) ++ bne cr1, L(dLcr1x) ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 +- bne cr6, L(dLcr6) ++#endif ++ bne cr6, L(dLcr6x) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ +- bne cr5, L(dLcr5) ++ bne cr7, L(dLcr7x) + bne L(d00) + li rRTN, 0 + blr +- ++ + /* Count is a multiple of 32, remainder is 0 */ +- .align 4 ++ .align 4 + L(dP4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 0(rSTR1) + ld rWORD2, 0(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + L(dP4e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 8(rSTR1) + ld rWORD4, 8(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 16(rSTR1) + ld rWORD6, 16(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ldu rWORD7, 24(rSTR1) + ldu rWORD8, 24(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 +- bne cr0, L(dLcr0) ++ bne cr7, L(dLcr7) + bne cr1, L(dLcr1) + bdz- L(d24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ +- .align 4 ++ .align 4 + L(dLoop): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 8(rSTR1) + ld rWORD2, 8(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(dLcr6) + L(dLoop1): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 16(rSTR1) + ld rWORD4, 16(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 + bne cr5, L(dLcr5) + L(dLoop2): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 24(rSTR1) + ld rWORD6, 24(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 +- bne cr0, L(dLcr0) ++ bne cr7, L(dLcr7) + L(dLoop3): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ldu rWORD7, 32(rSTR1) + ldu rWORD8, 32(rSTR2) ++#endif + bne- cr1, L(dLcr1) +- cmpld cr0, rWORD1, rWORD2 +- bdnz+ L(dLoop) +- ++ cmpld cr7, rWORD1, rWORD2 ++ bdnz+ L(dLoop) ++ + L(dL4): + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(dLcr6) +@@ -325,84 +510,98 @@ + bne cr5, L(dLcr5) + cmpld cr5, rWORD7, rWORD8 + L(d44): +- bne cr0, L(dLcr0) ++ bne cr7, L(dLcr7) + L(d34): + bne cr1, L(dLcr1) + L(d24): + bne cr6, L(dLcr6) + L(d14): + sldi. r12, rN, 3 +- bne cr5, L(dLcr5) ++ bne cr5, L(dLcr5) + L(d04): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + beq L(zeroLength) + /* At this point we have a remainder of 1 to 7 bytes to compare. Since + we are aligned it is safe to load the whole double word, and use +- shift right double to elliminate bits beyond the compare length. */ ++ shift right double to eliminate bits beyond the compare length. */ + L(d00): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) ++ ld rWORD2, 8(rSTR2) ++#endif + srd rWORD1, rWORD1, rN + srd rWORD2, rWORD2, rN +- cmpld cr5, rWORD1, rWORD2 +- bne cr5, L(dLcr5x) ++ cmpld cr7, rWORD1, rWORD2 ++ bne cr7, L(dLcr7x) + li rRTN, 0 + blr +- .align 4 +-L(dLcr0): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ++ .align 4 ++L(dLcr7): ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dLcr7x): + li rRTN, 1 +- bgtlr cr0 ++ bgtlr cr7 + li rRTN, -1 + blr +- .align 4 ++ .align 4 + L(dLcr1): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dLcr1x): + li rRTN, 1 + bgtlr cr1 + li rRTN, -1 + blr +- .align 4 ++ .align 4 + L(dLcr6): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dLcr6x): + li rRTN, 1 + bgtlr cr6 + li rRTN, -1 + blr +- .align 4 ++ .align 4 + L(dLcr5): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + L(dLcr5x): + li rRTN, 1 + bgtlr cr5 + li rRTN, -1 + blr +- +- .align 4 ++ ++ .align 4 + L(bytealigned): +- mtctr rN /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr rN /* Power4 wants mtctr 1st in dispatch group */ ++#if 0 ++/* Huh? We've already branched on cr6! */ + beq- cr6, L(zeroLength) ++#endif + + /* We need to prime this loop. This loop is swing modulo scheduled +- to avoid pipe delays. The dependent instruction latencies (load to ++ to avoid pipe delays. The dependent instruction latencies (load to + compare to conditional branch) is 2 to 3 cycles. In this loop each + dispatch group ends in a branch and takes 1 cycle. Effectively +- the first iteration of the loop only serves to load operands and +- branches based on compares are delayed until the next loop. ++ the first iteration of the loop only serves to load operands and ++ branches based on compares are delayed until the next loop. + + So we must precondition some registers and condition codes so that + we don't exit the loop early on the first iteration. */ +- ++ + lbz rWORD1, 0(rSTR1) + lbz rWORD2, 0(rSTR2) + bdz- L(b11) +- cmpld cr0, rWORD1, rWORD2 ++ cmpld cr7, rWORD1, rWORD2 + lbz rWORD3, 1(rSTR1) + lbz rWORD4, 1(rSTR2) + bdz- L(b12) +@@ -410,20 +609,20 @@ + lbzu rWORD5, 2(rSTR1) + lbzu rWORD6, 2(rSTR2) + bdz- L(b13) +- .align 4 ++ .align 4 + L(bLoop): + lbzu rWORD1, 1(rSTR1) + lbzu rWORD2, 1(rSTR2) +- bne- cr0, L(bLcr0) ++ bne- cr7, L(bLcr7) + + cmpld cr6, rWORD5, rWORD6 + bdz- L(b3i) +- ++ + lbzu rWORD3, 1(rSTR1) + lbzu rWORD4, 1(rSTR2) + bne- cr1, L(bLcr1) + +- cmpld cr0, rWORD1, rWORD2 ++ cmpld cr7, rWORD1, rWORD2 + bdz- L(b2i) + + lbzu rWORD5, 1(rSTR1) +@@ -432,31 +631,31 @@ + + cmpld cr1, rWORD3, rWORD4 + bdnz+ L(bLoop) +- ++ + /* We speculatively loading bytes before we have tested the previous + bytes. But we must avoid overrunning the length (in the ctr) to +- prevent these speculative loads from causing a segfault. In this ++ prevent these speculative loads from causing a segfault. In this + case the loop will exit early (before the all pending bytes are + tested. In this case we must complete the pending operations + before returning. */ + L(b1i): +- bne- cr0, L(bLcr0) ++ bne- cr7, L(bLcr7) + bne- cr1, L(bLcr1) + b L(bx56) +- .align 4 ++ .align 4 + L(b2i): + bne- cr6, L(bLcr6) +- bne- cr0, L(bLcr0) ++ bne- cr7, L(bLcr7) + b L(bx34) +- .align 4 ++ .align 4 + L(b3i): + bne- cr1, L(bLcr1) + bne- cr6, L(bLcr6) + b L(bx12) +- .align 4 +-L(bLcr0): ++ .align 4 ++L(bLcr7): + li rRTN, 1 +- bgtlr cr0 ++ bgtlr cr7 + li rRTN, -1 + blr + L(bLcr1): +@@ -471,116 +670,121 @@ + blr + + L(b13): +- bne- cr0, L(bx12) ++ bne- cr7, L(bx12) + bne- cr1, L(bx34) + L(bx56): + sub rRTN, rWORD5, rWORD6 + blr + nop + L(b12): +- bne- cr0, L(bx12) +-L(bx34): ++ bne- cr7, L(bx12) ++L(bx34): + sub rRTN, rWORD3, rWORD4 + blr + L(b11): + L(bx12): + sub rRTN, rWORD1, rWORD2 + blr +- .align 4 +-L(zeroLengthReturn): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ .align 4 + L(zeroLength): + li rRTN, 0 + blr + +- .align 4 ++ .align 4 + /* At this point we know the strings have different alignment and the +- compare length is at least 8 bytes. rBITDIF containes the low order ++ compare length is at least 8 bytes. r12 contains the low order + 3 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then rStr1 is double word ++ of r12 to 0. If r12 == 0 then rStr1 is double word + aligned and can perform the DWunaligned loop. +- +- Otherwise we know that rSTR1 is not aready DW aligned yet. ++ ++ Otherwise we know that rSTR1 is not already DW aligned yet. + So we can force the string addresses to the next lower DW +- boundary and special case this first DW word using shift left to +- ellimiate bits preceeding the first byte. Since we want to join the ++ boundary and special case this first DW using shift left to ++ eliminate bits preceding the first byte. Since we want to join the + normal (DWaligned) compare loop, starting at the second double word, + we need to adjust the length (rN) and special case the loop +- versioning for the first DW. This insures that the loop count is ++ versioning for the first DW. This ensures that the loop count is + correct and the first DW (shifted) is in the expected resister pair. */ +-#define rSHL r29 /* Unaligned shift left count. */ +-#define rSHR r28 /* Unaligned shift right count. */ +-#define rB r27 /* Left rotation temp for rWORD2. */ +-#define rD r26 /* Left rotation temp for rWORD4. */ +-#define rF r25 /* Left rotation temp for rWORD6. */ +-#define rH r24 /* Left rotation temp for rWORD8. */ +-#define rA r0 /* Right rotation temp for rWORD2. */ +-#define rC r12 /* Right rotation temp for rWORD4. */ +-#define rE r0 /* Right rotation temp for rWORD6. */ +-#define rG r12 /* Right rotation temp for rWORD8. */ ++#define rSHL r29 /* Unaligned shift left count. */ ++#define rSHR r28 /* Unaligned shift right count. */ ++#define rWORD8_SHIFT r27 /* Left rotation temp for rWORD2. */ ++#define rWORD2_SHIFT r26 /* Left rotation temp for rWORD4. */ ++#define rWORD4_SHIFT r25 /* Left rotation temp for rWORD6. */ ++#define rWORD6_SHIFT r24 /* Left rotation temp for rWORD8. */ + L(unaligned): +- std r29,-24(r1) +- cfi_offset(r29,-24) ++ std rSHL, -24(r1) ++ cfi_offset(rSHL, -24) + clrldi rSHL, rSTR2, 61 + beq- cr6, L(duzeroLength) +- std r28,-32(r1) +- cfi_offset(r28,-32) ++ std rSHR, -32(r1) ++ cfi_offset(rSHR, -32) + beq cr5, L(DWunaligned) +- std r27,-40(r1) +- cfi_offset(r27,-40) +-/* Adjust the logical start of rSTR2 ro compensate for the extra bits ++ std rWORD8_SHIFT, -40(r1) ++ cfi_offset(rWORD8_SHIFT, -40) ++/* Adjust the logical start of rSTR2 to compensate for the extra bits + in the 1st rSTR1 DW. */ +- sub r27, rSTR2, rBITDIF ++ sub rWORD8_SHIFT, rSTR2, r12 + /* But do not attempt to address the DW before that DW that contains + the actual start of rSTR2. */ + clrrdi rSTR2, rSTR2, 3 +- std r26,-48(r1) +- cfi_offset(r26,-48) +-/* Compute the leaft/right shift counts for the unalign rSTR2, +- compensating for the logical (DW aligned) start of rSTR1. */ +- clrldi rSHL, r27, 61 +- clrrdi rSTR1, rSTR1, 3 +- std r25,-56(r1) +- cfi_offset(r25,-56) ++ std rWORD2_SHIFT, -48(r1) ++ cfi_offset(rWORD2_SHIFT, -48) ++/* Compute the left/right shift counts for the unaligned rSTR2, ++ compensating for the logical (DW aligned) start of rSTR1. */ ++ clrldi rSHL, rWORD8_SHIFT, 61 ++ clrrdi rSTR1, rSTR1, 3 ++ std rWORD4_SHIFT, -56(r1) ++ cfi_offset(rWORD4_SHIFT, -56) + sldi rSHL, rSHL, 3 +- cmpld cr5, r27, rSTR2 +- add rN, rN, rBITDIF +- sldi r11, rBITDIF, 3 +- std r24,-64(r1) +- cfi_offset(r24,-64) ++ cmpld cr5, rWORD8_SHIFT, rSTR2 ++ add rN, rN, r12 ++ sldi rWORD6, r12, 3 ++ std rWORD6_SHIFT, -64(r1) ++ cfi_offset(rWORD6_SHIFT, -64) + subfic rSHR, rSHL, 64 +- srdi rTMP, rN, 5 /* Divide by 32 */ +- andi. rBITDIF, rN, 24 /* Get the DW remainder */ ++ srdi r0, rN, 5 /* Divide by 32 */ ++ andi. r12, rN, 24 /* Get the DW remainder */ + /* We normally need to load 2 DWs to start the unaligned rSTR2, but in + this special case those bits may be discarded anyway. Also we + must avoid loading a DW where none of the bits are part of rSTR2 as + this may cross a page boundary and cause a page fault. */ + li rWORD8, 0 + blt cr5, L(dus0) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD8, 0(rSTR2) +- la rSTR2, 8(rSTR2) ++ addi rSTR2, rSTR2, 8 ++#endif + sld rWORD8, rWORD8, rSHL + + L(dus0): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 0(rSTR1) + ld rWORD2, 0(rSTR2) +- cmpldi cr1, rBITDIF, 16 ++#endif ++ cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 +- srd rG, rWORD2, rSHR ++ srd r12, rWORD2, rSHR + clrldi rN, rN, 61 + beq L(duPs4) +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- or rWORD8, rG, rWORD8 ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ or rWORD8, r12, rWORD8 + bgt cr1, L(duPs3) + beq cr1, L(duPs2) + + /* Remainder is 8 */ +- .align 4 ++ .align 4 + L(dusP1): +- sld rB, rWORD2, rSHL +- sld rWORD7, rWORD1, r11 +- sld rWORD8, rWORD8, r11 ++ sld rWORD8_SHIFT, rWORD2, rSHL ++ sld rWORD7, rWORD1, rWORD6 ++ sld rWORD8, rWORD8, rWORD6 + bge cr7, L(duP1e) + /* At this point we exit early with the first double word compare + complete and remainder of 0 to 7 bytes. See L(du14) for details on +@@ -590,95 +794,133 @@ + bne cr5, L(duLcr5) + cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD2, 8(rSTR2) +- srd rA, rWORD2, rSHR ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 16 */ +- .align 4 ++ .align 4 + L(duPs2): +- sld rH, rWORD2, rSHL +- sld rWORD5, rWORD1, r11 +- sld rWORD6, rWORD8, r11 ++ sld rWORD6_SHIFT, rWORD2, rSHL ++ sld rWORD5, rWORD1, rWORD6 ++ sld rWORD6, rWORD8, rWORD6 + b L(duP2e) + /* Remainder is 24 */ +- .align 4 ++ .align 4 + L(duPs3): +- sld rF, rWORD2, rSHL +- sld rWORD3, rWORD1, r11 +- sld rWORD4, rWORD8, r11 ++ sld rWORD4_SHIFT, rWORD2, rSHL ++ sld rWORD3, rWORD1, rWORD6 ++ sld rWORD4, rWORD8, rWORD6 + b L(duP3e) + /* Count is a multiple of 32, remainder is 0 */ +- .align 4 ++ .align 4 + L(duPs4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- or rWORD8, rG, rWORD8 +- sld rD, rWORD2, rSHL +- sld rWORD1, rWORD1, r11 +- sld rWORD2, rWORD8, r11 ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ or rWORD8, r12, rWORD8 ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ sld rWORD1, rWORD1, rWORD6 ++ sld rWORD2, rWORD8, rWORD6 + b L(duP4e) + + /* At this point we know rSTR1 is double word aligned and the + compare length is at least 8 bytes. */ +- .align 4 ++ .align 4 + L(DWunaligned): +- std r27,-40(r1) +- cfi_offset(r27,-40) ++ std rWORD8_SHIFT, -40(r1) ++ cfi_offset(rWORD8_SHIFT, -40) + clrrdi rSTR2, rSTR2, 3 +- std r26,-48(r1) +- cfi_offset(r26,-48) +- srdi rTMP, rN, 5 /* Divide by 32 */ +- std r25,-56(r1) +- cfi_offset(r25,-56) +- andi. rBITDIF, rN, 24 /* Get the DW remainder */ +- std r24,-64(r1) +- cfi_offset(r24,-64) ++ std rWORD2_SHIFT, -48(r1) ++ cfi_offset(rWORD2_SHIFT, -48) ++ srdi r0, rN, 5 /* Divide by 32 */ ++ std rWORD4_SHIFT, -56(r1) ++ cfi_offset(rWORD4_SHIFT, -56) ++ andi. r12, rN, 24 /* Get the DW remainder */ ++ std rWORD6_SHIFT, -64(r1) ++ cfi_offset(rWORD6_SHIFT, -64) + sldi rSHL, rSHL, 3 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD6, 0(rSTR2) + ldu rWORD8, 8(rSTR2) +- cmpldi cr1, rBITDIF, 16 ++#endif ++ cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 + clrldi rN, rN, 61 + subfic rSHR, rSHL, 64 +- sld rH, rWORD6, rSHL ++ sld rWORD6_SHIFT, rWORD6, rSHL + beq L(duP4) +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ + bgt cr1, L(duP3) + beq cr1, L(duP2) +- ++ + /* Remainder is 8 */ +- .align 4 ++ .align 4 + L(duP1): +- srd rG, rWORD8, rSHR ++ srd r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else + ld rWORD7, 0(rSTR1) +- sld rB, rWORD8, rSHL +- or rWORD8, rG, rH ++#endif ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP1x) + L(duP1e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 8(rSTR1) + ld rWORD2, 8(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 +- srd rA, rWORD2, rSHR +- sld rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 16(rSTR1) + ld rWORD4, 16(rSTR2) +- cmpld cr0, rWORD1, rWORD2 +- srd rC, rWORD4, rSHR +- sld rF, rWORD4, rSHL ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL + bne cr5, L(duLcr5) +- or rWORD4, rC, rD ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 24(rSTR1) + ld rWORD6, 24(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 +- srd rE, rWORD6, rSHR +- sld rH, rWORD6, rSHL +- bne cr0, L(duLcr0) +- or rWORD6, rE, rF ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ bne cr7, L(duLcr7) ++ or rWORD6, r0, rWORD4_SHIFT + cmpld cr6, rWORD5, rWORD6 +- b L(duLoop3) +- .align 4 ++ b L(duLoop3) ++ .align 4 + /* At this point we exit early with the first double word compare + complete and remainder of 0 to 7 bytes. See L(du14) for details on + how we handle the remaining bytes. */ +@@ -688,186 +930,321 @@ + bne cr5, L(duLcr5) + cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD2, 8(rSTR2) +- srd rA, rWORD2, rSHR ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 16 */ +- .align 4 ++ .align 4 + L(duP2): +- srd rE, rWORD8, rSHR ++ srd r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else + ld rWORD5, 0(rSTR1) +- or rWORD6, rE, rH +- sld rH, rWORD8, rSHL ++#endif ++ or rWORD6, r0, rWORD6_SHIFT ++ sld rWORD6_SHIFT, rWORD8, rSHL + L(duP2e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD7, 8(rSTR1) + ld rWORD8, 8(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 +- srd rG, rWORD8, rSHR +- sld rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP2x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 16(rSTR1) + ld rWORD2, 16(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) +- srd rA, rWORD2, rSHR +- sld rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 24(rSTR1) + ld rWORD4, 24(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + bne cr5, L(duLcr5) +- srd rC, rWORD4, rSHR +- sld rF, rWORD4, rSHL +- or rWORD4, rC, rD ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 ++#endif + cmpld cr1, rWORD3, rWORD4 + b L(duLoop2) +- .align 4 ++ .align 4 + L(duP2x): + cmpld cr5, rWORD7, rWORD8 ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 ++#endif + bne cr6, L(duLcr6) + sldi. rN, rN, 3 + bne cr5, L(duLcr5) + cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD2, 8(rSTR2) +- srd rA, rWORD2, rSHR ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) +- ++ + /* Remainder is 24 */ +- .align 4 ++ .align 4 + L(duP3): +- srd rC, rWORD8, rSHR ++ srd r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else + ld rWORD3, 0(rSTR1) +- sld rF, rWORD8, rSHL +- or rWORD4, rC, rH ++#endif ++ sld rWORD4_SHIFT, rWORD8, rSHL ++ or rWORD4, r12, rWORD6_SHIFT + L(duP3e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 8(rSTR1) + ld rWORD6, 8(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 +- srd rE, rWORD6, rSHR +- sld rH, rWORD6, rSHL +- or rWORD6, rE, rF ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD7, 16(rSTR1) + ld rWORD8, 16(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 + bne cr1, L(duLcr1) +- srd rG, rWORD8, rSHR +- sld rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP3x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 24(rSTR1) + ld rWORD2, 24(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) +- srd rA, rWORD2, rSHR +- sld rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + b L(duLoop1) +- .align 4 ++ .align 4 + L(duP3x): ++#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 ++#endif ++#if 0 ++/* Huh? We've already branched on cr1! */ + bne cr1, L(duLcr1) ++#endif + cmpld cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) + sldi. rN, rN, 3 + bne cr5, L(duLcr5) + cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD2, 8(rSTR2) +- srd rA, rWORD2, rSHR ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) +- ++ + /* Count is a multiple of 32, remainder is 0 */ +- .align 4 ++ .align 4 + L(duP4): +- mtctr rTMP /* Power4 wants mtctr 1st in dispatch group */ +- srd rA, rWORD8, rSHR ++ mtctr r0 /* Power4 wants mtctr 1st in dispatch group */ ++ srd r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else + ld rWORD1, 0(rSTR1) +- sld rD, rWORD8, rSHL +- or rWORD2, rA, rH ++#endif ++ sld rWORD2_SHIFT, rWORD8, rSHL ++ or rWORD2, r0, rWORD6_SHIFT + L(duP4e): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 8(rSTR1) + ld rWORD4, 8(rSTR2) +- cmpld cr0, rWORD1, rWORD2 +- srd rC, rWORD4, rSHR +- sld rF, rWORD4, rSHL +- or rWORD4, rC, rD ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 16(rSTR1) + ld rWORD6, 16(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 +- bne cr0, L(duLcr0) +- srd rE, rWORD6, rSHR +- sld rH, rWORD6, rSHL +- or rWORD6, rE, rF ++ bne cr7, L(duLcr7) ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ldu rWORD7, 24(rSTR1) + ldu rWORD8, 24(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 + bne cr1, L(duLcr1) +- srd rG, rWORD8, rSHR +- sld rB, rWORD8, rSHL +- or rWORD8, rG, rH ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + cmpld cr5, rWORD7, rWORD8 + bdz- L(du24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ +- .align 4 ++ .align 4 + L(duLoop): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD1, 8(rSTR1) + ld rWORD2, 8(rSTR2) ++#endif + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(duLcr6) +- srd rA, rWORD2, rSHR +- sld rD, rWORD2, rSHL +- or rWORD2, rA, rB ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT + L(duLoop1): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD3, 16(rSTR1) + ld rWORD4, 16(rSTR2) ++#endif + cmpld cr6, rWORD5, rWORD6 + bne cr5, L(duLcr5) +- srd rC, rWORD4, rSHR +- sld rF, rWORD4, rSHL +- or rWORD4, rC, rD ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT + L(duLoop2): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD5, 24(rSTR1) + ld rWORD6, 24(rSTR2) ++#endif + cmpld cr5, rWORD7, rWORD8 +- bne cr0, L(duLcr0) +- srd rE, rWORD6, rSHR +- sld rH, rWORD6, rSHL +- or rWORD6, rE, rF ++ bne cr7, L(duLcr7) ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT + L(duLoop3): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else + ldu rWORD7, 32(rSTR1) + ldu rWORD8, 32(rSTR2) +- cmpld cr0, rWORD1, rWORD2 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + bne- cr1, L(duLcr1) +- srd rG, rWORD8, rSHR +- sld rB, rWORD8, rSHL +- or rWORD8, rG, rH +- bdnz+ L(duLoop) +- ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ bdnz+ L(duLoop) ++ + L(duL4): ++#if 0 ++/* Huh? We've already branched on cr1! */ + bne cr1, L(duLcr1) ++#endif + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(duLcr6) + cmpld cr6, rWORD5, rWORD6 + bne cr5, L(duLcr5) + cmpld cr5, rWORD7, rWORD8 + L(du44): +- bne cr0, L(duLcr0) ++ bne cr7, L(duLcr7) + L(du34): + bne cr1, L(duLcr1) + L(du24): +@@ -876,106 +1253,113 @@ + sldi. rN, rN, 3 + bne cr5, L(duLcr5) + /* At this point we have a remainder of 1 to 7 bytes to compare. We use +- shift right double to elliminate bits beyond the compare length. +- This allows the use of double word subtract to compute the final +- result. ++ shift right double to eliminate bits beyond the compare length. + +- However it may not be safe to load rWORD2 which may be beyond the ++ However it may not be safe to load rWORD2 which may be beyond the + string length. So we compare the bit length of the remainder to + the right shift count (rSHR). If the bit count is less than or equal + we do not need to load rWORD2 (all significant bits are already in +- rB). */ ++ rWORD8_SHIFT). */ + cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA, 0 ++ li r0, 0 + ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else + ld rWORD2, 8(rSTR2) +- srd rA, rWORD2, rSHR +- .align 4 ++#endif ++ srd r0, rWORD2, rSHR ++ .align 4 + L(dutrim): ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++#else + ld rWORD1, 8(rSTR1) +- ld rWORD8,-8(r1) +- subfic rN, rN, 64 /* Shift count is 64 - (rN * 8). */ +- or rWORD2, rA, rB +- ld rWORD7,-16(r1) +- ld r29,-24(r1) ++#endif ++ ld rWORD8, -8(r1) ++ subfic rN, rN, 64 /* Shift count is 64 - (rN * 8). */ ++ or rWORD2, r0, rWORD8_SHIFT ++ ld rWORD7, -16(r1) ++ ld rSHL, -24(r1) + srd rWORD1, rWORD1, rN + srd rWORD2, rWORD2, rN +- ld r28,-32(r1) +- ld r27,-40(r1) ++ ld rSHR, -32(r1) ++ ld rWORD8_SHIFT, -40(r1) + li rRTN, 0 +- cmpld cr0, rWORD1, rWORD2 +- ld r26,-48(r1) +- ld r25,-56(r1) +- beq cr0, L(dureturn24) +- li rRTN, 1 +- ld r24,-64(r1) +- bgtlr cr0 +- li rRTN, -1 +- blr +- .align 4 +-L(duLcr0): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN, 1 +- bgt cr0, L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) ++ cmpld cr7, rWORD1, rWORD2 ++ ld rWORD2_SHIFT, -48(r1) ++ ld rWORD4_SHIFT, -56(r1) ++ beq cr7, L(dureturn24) ++ li rRTN, 1 ++ ld rWORD6_SHIFT, -64(r1) ++ bgtlr cr7 ++ li rRTN, -1 ++ blr ++ .align 4 ++L(duLcr7): ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ li rRTN, 1 ++ bgt cr7, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) + li rRTN, -1 + b L(dureturn27) +- .align 4 ++ .align 4 + L(duLcr1): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + li rRTN, 1 +- bgt cr1, L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) ++ bgt cr1, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) + li rRTN, -1 + b L(dureturn27) +- .align 4 ++ .align 4 + L(duLcr6): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + li rRTN, 1 +- bgt cr6, L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) ++ bgt cr6, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) + li rRTN, -1 + b L(dureturn27) +- .align 4 ++ .align 4 + L(duLcr5): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + li rRTN, 1 +- bgt cr5, L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) ++ bgt cr5, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) + li rRTN, -1 + b L(dureturn27) + .align 3 + L(duZeroReturn): +- li rRTN,0 ++ li rRTN, 0 + .align 4 + L(dureturn): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +-L(dureturn29): +- ld r29,-24(r1) +- ld r28,-32(r1) +-L(dureturn27): +- ld r27,-40(r1) +-L(dureturn26): +- ld r26,-48(r1) +-L(dureturn25): +- ld r25,-56(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dureturn29): ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) ++L(dureturn27): ++ ld rWORD8_SHIFT, -40(r1) ++L(dureturn26): ++ ld rWORD2_SHIFT, -48(r1) ++L(dureturn25): ++ ld rWORD4_SHIFT, -56(r1) + L(dureturn24): +- ld r24,-64(r1) ++ ld rWORD6_SHIFT, -64(r1) + blr + L(duzeroLength): +- li rRTN,0 ++ li rRTN, 0 + blr + +-END (BP_SYM (memcmp)) ++END (memcmp) + libc_hidden_builtin_def (memcmp) + weak_alias (memcmp, bcmp) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcmp.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcmp.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcmp.S 2014-05-28 19:22:37.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcmp.S 2014-05-29 09:35:08.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memcmp implementation for POWER7/PowerPC64. +- Copyright (C) 2010, 2011 Free Software Foundation, Inc. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,379 +17,576 @@ + . */ + + #include +-#include +-#include + + /* int [r3] memcmp (const char *s1 [r3], + const char *s2 [r4], + size_t size [r5]) */ + + .machine power7 +-EALIGN (BP_SYM(memcmp),4,0) ++EALIGN (memcmp, 4, 0) + CALL_MCOUNT 3 + +-#define rTMP r0 + #define rRTN r3 + #define rSTR1 r3 /* first string arg */ + #define rSTR2 r4 /* second string arg */ + #define rN r5 /* max string length */ +-/* Note: The Bounded pointer support in this code is broken. This code +- was inherited from PPC32 and that support was never completed. +- Current PPC gcc does not support -fbounds-check or -fbounded-pointers. */ + #define rWORD1 r6 /* current word in s1 */ + #define rWORD2 r7 /* current word in s2 */ + #define rWORD3 r8 /* next word in s1 */ + #define rWORD4 r9 /* next word in s2 */ + #define rWORD5 r10 /* next word in s1 */ + #define rWORD6 r11 /* next word in s2 */ +-#define rBITDIF r12 /* bits that differ in s1 & s2 words */ + #define rWORD7 r30 /* next word in s1 */ + #define rWORD8 r31 /* next word in s2 */ + +- xor rTMP,rSTR2,rSTR1 +- cmpldi cr6,rN,0 +- cmpldi cr1,rN,12 +- clrldi. rTMP,rTMP,61 +- clrldi rBITDIF,rSTR1,61 +- cmpldi cr5,rBITDIF,0 +- beq- cr6,L(zeroLength) +- dcbt 0,rSTR1 +- dcbt 0,rSTR2 +-/* If less than 8 bytes or not aligned, use the unalligned ++ xor r0, rSTR2, rSTR1 ++ cmpldi cr6, rN, 0 ++ cmpldi cr1, rN, 12 ++ clrldi. r0, r0, 61 ++ clrldi r12, rSTR1, 61 ++ cmpldi cr5, r12, 0 ++ beq- cr6, L(zeroLength) ++ dcbt 0, rSTR1 ++ dcbt 0, rSTR2 ++/* If less than 8 bytes or not aligned, use the unaligned + byte loop. */ +- blt cr1,L(bytealigned) +- std rWORD8,-8(r1) +- cfi_offset(rWORD8,-8) +- std rWORD7,-16(r1) +- cfi_offset(rWORD7,-16) ++ blt cr1, L(bytealigned) ++ std rWORD8, -8(r1) ++ cfi_offset(rWORD8, -8) ++ std rWORD7, -16(r1) ++ cfi_offset(rWORD7, -16) + bne L(unaligned) + /* At this point we know both strings have the same alignment and the +- compare length is at least 8 bytes. rBITDIF containes the low order ++ compare length is at least 8 bytes. r12 contains the low order + 3 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then we are already double word +- aligned and can perform the DWaligned loop. ++ of r12 to 0. If r12 == 0 then we are already double word ++ aligned and can perform the DW aligned loop. + + Otherwise we know the two strings have the same alignment (but not +- yet DW). So we can force the string addresses to the next lower DW +- boundary and special case this first DW word using shift left to +- ellimiate bits preceeding the first byte. Since we want to join the +- normal (DWaligned) compare loop, starting at the second double word, ++ yet DW). So we force the string addresses to the next lower DW ++ boundary and special case this first DW using shift left to ++ eliminate bits preceding the first byte. Since we want to join the ++ normal (DW aligned) compare loop, starting at the second double word, + we need to adjust the length (rN) and special case the loop +- versioning for the first DW. This insures that the loop count is +- correct and the first DW (shifted) is in the expected resister pair. */ ++ versioning for the first DW. This ensures that the loop count is ++ correct and the first DW (shifted) is in the expected register pair. */ + .align 4 + L(samealignment): +- clrrdi rSTR1,rSTR1,3 +- clrrdi rSTR2,rSTR2,3 +- beq cr5,L(DWaligned) +- add rN,rN,rBITDIF +- sldi r11,rBITDIF,3 +- srdi rTMP,rN,5 /* Divide by 32 */ +- andi. rBITDIF,rN,24 /* Get the DW remainder */ +- ld rWORD1,0(rSTR1) +- ld rWORD2,0(rSTR2) +- cmpldi cr1,rBITDIF,16 +- cmpldi cr7,rN,32 +- clrldi rN,rN,61 ++ clrrdi rSTR1, rSTR1, 3 ++ clrrdi rSTR2, rSTR2, 3 ++ beq cr5, L(DWaligned) ++ add rN, rN, r12 ++ sldi rWORD6, r12, 3 ++ srdi r0, rN, 5 /* Divide by 32 */ ++ andi. r12, rN, 24 /* Get the DW remainder */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 0(rSTR1) ++ ld rWORD2, 0(rSTR2) ++#endif ++ cmpldi cr1, r12, 16 ++ cmpldi cr7, rN, 32 ++ clrldi rN, rN, 61 + beq L(dPs4) +- mtctr rTMP +- bgt cr1,L(dPs3) +- beq cr1,L(dPs2) ++ mtctr r0 ++ bgt cr1, L(dPs3) ++ beq cr1, L(dPs2) + + /* Remainder is 8 */ + .align 3 + L(dsP1): +- sld rWORD5,rWORD1,r11 +- sld rWORD6,rWORD2,r11 +- cmpld cr5,rWORD5,rWORD6 +- blt cr7,L(dP1x) ++ sld rWORD5, rWORD1, rWORD6 ++ sld rWORD6, rWORD2, rWORD6 ++ cmpld cr5, rWORD5, rWORD6 ++ blt cr7, L(dP1x) + /* Do something useful in this cycle since we have to branch anyway. */ +- ld rWORD1,8(rSTR1) +- ld rWORD2,8(rSTR2) +- cmpld cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 8(rSTR1) ++ ld rWORD2, 8(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 + b L(dP1e) + /* Remainder is 16 */ + .align 4 + L(dPs2): +- sld rWORD5,rWORD1,r11 +- sld rWORD6,rWORD2,r11 +- cmpld cr6,rWORD5,rWORD6 +- blt cr7,L(dP2x) ++ sld rWORD5, rWORD1, rWORD6 ++ sld rWORD6, rWORD2, rWORD6 ++ cmpld cr6, rWORD5, rWORD6 ++ blt cr7, L(dP2x) + /* Do something useful in this cycle since we have to branch anyway. */ +- ld rWORD7,8(rSTR1) +- ld rWORD8,8(rSTR2) +- cmpld cr5,rWORD7,rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD7, 8(rSTR1) ++ ld rWORD8, 8(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 + b L(dP2e) + /* Remainder is 24 */ + .align 4 + L(dPs3): +- sld rWORD3,rWORD1,r11 +- sld rWORD4,rWORD2,r11 +- cmpld cr1,rWORD3,rWORD4 ++ sld rWORD3, rWORD1, rWORD6 ++ sld rWORD4, rWORD2, rWORD6 ++ cmpld cr1, rWORD3, rWORD4 + b L(dP3e) + /* Count is a multiple of 32, remainder is 0 */ + .align 4 + L(dPs4): +- mtctr rTMP +- sld rWORD1,rWORD1,r11 +- sld rWORD2,rWORD2,r11 +- cmpld cr0,rWORD1,rWORD2 ++ mtctr r0 ++ sld rWORD1, rWORD1, rWORD6 ++ sld rWORD2, rWORD2, rWORD6 ++ cmpld cr7, rWORD1, rWORD2 + b L(dP4e) + + /* At this point we know both strings are double word aligned and the + compare length is at least 8 bytes. */ + .align 4 + L(DWaligned): +- andi. rBITDIF,rN,24 /* Get the DW remainder */ +- srdi rTMP,rN,5 /* Divide by 32 */ +- cmpldi cr1,rBITDIF,16 +- cmpldi cr7,rN,32 +- clrldi rN,rN,61 ++ andi. r12, rN, 24 /* Get the DW remainder */ ++ srdi r0, rN, 5 /* Divide by 32 */ ++ cmpldi cr1, r12, 16 ++ cmpldi cr7, rN, 32 ++ clrldi rN, rN, 61 + beq L(dP4) +- bgt cr1,L(dP3) +- beq cr1,L(dP2) ++ bgt cr1, L(dP3) ++ beq cr1, L(dP2) + + /* Remainder is 8 */ + .align 4 + L(dP1): +- mtctr rTMP ++ mtctr r0 + /* Normally we'd use rWORD7/rWORD8 here, but since we might exit early +- (8-15 byte compare), we want to use only volitile registers. This +- means we can avoid restoring non-volitile registers since we did not ++ (8-15 byte compare), we want to use only volatile registers. This ++ means we can avoid restoring non-volatile registers since we did not + change any on the early exit path. The key here is the non-early + exit path only cares about the condition code (cr5), not about which + register pair was used. */ +- ld rWORD5,0(rSTR1) +- ld rWORD6,0(rSTR2) +- cmpld cr5,rWORD5,rWORD6 +- blt cr7,L(dP1x) +- ld rWORD1,8(rSTR1) +- ld rWORD2,8(rSTR2) +- cmpld cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 0(rSTR1) ++ ld rWORD6, 0(rSTR2) ++#endif ++ cmpld cr5, rWORD5, rWORD6 ++ blt cr7, L(dP1x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 8(rSTR1) ++ ld rWORD2, 8(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 + L(dP1e): +- ld rWORD3,16(rSTR1) +- ld rWORD4,16(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- ld rWORD5,24(rSTR1) +- ld rWORD6,24(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- bne cr5,L(dLcr5) +- bne cr0,L(dLcr0) +- +- ldu rWORD7,32(rSTR1) +- ldu rWORD8,32(rSTR2) +- bne cr1,L(dLcr1) +- cmpld cr5,rWORD7,rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 16(rSTR1) ++ ld rWORD4, 16(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 24(rSTR1) ++ ld rWORD6, 24(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr5, L(dLcr5x) ++ bne cr7, L(dLcr7x) ++ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ldu rWORD7, 32(rSTR1) ++ ldu rWORD8, 32(rSTR2) ++#endif ++ bne cr1, L(dLcr1) ++ cmpld cr5, rWORD7, rWORD8 + bdnz L(dLoop) +- bne cr6,L(dLcr6) +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ bne cr6, L(dLcr6) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + .align 3 + L(dP1x): +- sldi. r12,rN,3 +- bne cr5,L(dLcr5) +- subfic rN,r12,64 /* Shift count is 64 - (rN * 8). */ ++ sldi. r12, rN, 3 ++ bne cr5, L(dLcr5x) ++ subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne L(d00) +- li rRTN,0 ++ li rRTN, 0 + blr + + /* Remainder is 16 */ + .align 4 + L(dP2): +- mtctr rTMP +- ld rWORD5,0(rSTR1) +- ld rWORD6,0(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- blt cr7,L(dP2x) +- ld rWORD7,8(rSTR1) +- ld rWORD8,8(rSTR2) +- cmpld cr5,rWORD7,rWORD8 ++ mtctr r0 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 0(rSTR1) ++ ld rWORD6, 0(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ blt cr7, L(dP2x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD7, 8(rSTR1) ++ ld rWORD8, 8(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 + L(dP2e): +- ld rWORD1,16(rSTR1) +- ld rWORD2,16(rSTR2) +- cmpld cr0,rWORD1,rWORD2 +- ld rWORD3,24(rSTR1) +- ld rWORD4,24(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- bne cr6,L(dLcr6) +- bne cr5,L(dLcr5) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 16(rSTR1) ++ ld rWORD2, 16(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 24(rSTR1) ++ ld rWORD4, 24(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ bne cr6, L(dLcr6) ++ bne cr5, L(dLcr5) + b L(dLoop2) + /* Again we are on a early exit path (16-23 byte compare), we want to +- only use volitile registers and avoid restoring non-volitile ++ only use volatile registers and avoid restoring non-volatile + registers. */ + .align 4 + L(dP2x): +- ld rWORD3,8(rSTR1) +- ld rWORD4,8(rSTR2) +- cmpld cr5,rWORD3,rWORD4 +- sldi. r12,rN,3 +- bne cr6,L(dLcr6) +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- bne cr5,L(dLcr5) +- subfic rN,r12,64 /* Shift count is 64 - (rN * 8). */ ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 8(rSTR1) ++ ld rWORD4, 8(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ sldi. r12, rN, 3 ++ bne cr6, L(dLcr6x) ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ bne cr1, L(dLcr1x) ++ subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne L(d00) +- li rRTN,0 ++ li rRTN, 0 + blr + + /* Remainder is 24 */ + .align 4 + L(dP3): +- mtctr rTMP +- ld rWORD3,0(rSTR1) +- ld rWORD4,0(rSTR2) +- cmpld cr1,rWORD3,rWORD4 ++ mtctr r0 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 0(rSTR1) ++ ld rWORD4, 0(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 + L(dP3e): +- ld rWORD5,8(rSTR1) +- ld rWORD6,8(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- blt cr7,L(dP3x) +- ld rWORD7,16(rSTR1) +- ld rWORD8,16(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- ld rWORD1,24(rSTR1) +- ld rWORD2,24(rSTR2) +- cmpld cr0,rWORD1,rWORD2 +- addi rSTR1,rSTR1,16 +- addi rSTR2,rSTR2,16 +- bne cr1,L(dLcr1) +- bne cr6,L(dLcr6) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 8(rSTR1) ++ ld rWORD6, 8(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ blt cr7, L(dP3x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD7, 16(rSTR1) ++ ld rWORD8, 16(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 24(rSTR1) ++ ld rWORD2, 24(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 16 ++ addi rSTR2, rSTR2, 16 ++#endif ++ bne cr1, L(dLcr1) ++ bne cr6, L(dLcr6) + b L(dLoop1) + /* Again we are on a early exit path (24-31 byte compare), we want to +- only use volitile registers and avoid restoring non-volitile ++ only use volatile registers and avoid restoring non-volatile + registers. */ + .align 4 + L(dP3x): +- ld rWORD1,16(rSTR1) +- ld rWORD2,16(rSTR2) +- cmpld cr5,rWORD1,rWORD2 +- sldi. r12,rN,3 +- bne cr1,L(dLcr1) +- addi rSTR1,rSTR1,16 +- addi rSTR2,rSTR2,16 +- bne cr6,L(dLcr6) +- subfic rN,r12,64 /* Shift count is 64 - (rN * 8). */ +- bne cr5,L(dLcr5) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 16(rSTR1) ++ ld rWORD2, 16(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ sldi. r12, rN, 3 ++ bne cr1, L(dLcr1x) ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 16 ++ addi rSTR2, rSTR2, 16 ++#endif ++ bne cr6, L(dLcr6x) ++ subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ ++ bne cr7, L(dLcr7x) + bne L(d00) +- li rRTN,0 ++ li rRTN, 0 + blr + + /* Count is a multiple of 32, remainder is 0 */ + .align 4 + L(dP4): +- mtctr rTMP +- ld rWORD1,0(rSTR1) +- ld rWORD2,0(rSTR2) +- cmpld cr0,rWORD1,rWORD2 ++ mtctr r0 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 0(rSTR1) ++ ld rWORD2, 0(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 + L(dP4e): +- ld rWORD3,8(rSTR1) +- ld rWORD4,8(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- ld rWORD5,16(rSTR1) +- ld rWORD6,16(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- ldu rWORD7,24(rSTR1) +- ldu rWORD8,24(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- bne cr0,L(dLcr0) +- bne cr1,L(dLcr1) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 8(rSTR1) ++ ld rWORD4, 8(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 16(rSTR1) ++ ld rWORD6, 16(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ldu rWORD7, 24(rSTR1) ++ ldu rWORD8, 24(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ bne cr7, L(dLcr7) ++ bne cr1, L(dLcr1) + bdz- L(d24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ + .align 4 + L(dLoop): +- ld rWORD1,8(rSTR1) +- ld rWORD2,8(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- bne cr6,L(dLcr6) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 8(rSTR1) ++ ld rWORD2, 8(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ bne cr6, L(dLcr6) + L(dLoop1): +- ld rWORD3,16(rSTR1) +- ld rWORD4,16(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- bne cr5,L(dLcr5) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 16(rSTR1) ++ ld rWORD4, 16(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr5, L(dLcr5) + L(dLoop2): +- ld rWORD5,24(rSTR1) +- ld rWORD6,24(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- bne cr0,L(dLcr0) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 24(rSTR1) ++ ld rWORD6, 24(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ bne cr7, L(dLcr7) + L(dLoop3): +- ldu rWORD7,32(rSTR1) +- ldu rWORD8,32(rSTR2) +- bne cr1,L(dLcr1) +- cmpld cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ldu rWORD7, 32(rSTR1) ++ ldu rWORD8, 32(rSTR2) ++#endif ++ bne cr1, L(dLcr1) ++ cmpld cr7, rWORD1, rWORD2 + bdnz L(dLoop) + + L(dL4): +- cmpld cr1,rWORD3,rWORD4 +- bne cr6,L(dLcr6) +- cmpld cr6,rWORD5,rWORD6 +- bne cr5,L(dLcr5) +- cmpld cr5,rWORD7,rWORD8 ++ cmpld cr1, rWORD3, rWORD4 ++ bne cr6, L(dLcr6) ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr5, L(dLcr5) ++ cmpld cr5, rWORD7, rWORD8 + L(d44): +- bne cr0,L(dLcr0) ++ bne cr7, L(dLcr7) + L(d34): +- bne cr1,L(dLcr1) ++ bne cr1, L(dLcr1) + L(d24): +- bne cr6,L(dLcr6) ++ bne cr6, L(dLcr6) + L(d14): +- sldi. r12,rN,3 +- bne cr5,L(dLcr5) ++ sldi. r12, rN, 3 ++ bne cr5, L(dLcr5) + L(d04): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- subfic rN,r12,64 /* Shift count is 64 - (rN * 8). */ ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + beq L(zeroLength) + /* At this point we have a remainder of 1 to 7 bytes to compare. Since + we are aligned it is safe to load the whole double word, and use +- shift right double to elliminate bits beyond the compare length. */ ++ shift right double to eliminate bits beyond the compare length. */ + L(d00): +- ld rWORD1,8(rSTR1) +- ld rWORD2,8(rSTR2) +- srd rWORD1,rWORD1,rN +- srd rWORD2,rWORD2,rN +- cmpld cr5,rWORD1,rWORD2 +- bne cr5,L(dLcr5x) +- li rRTN,0 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 8(rSTR1) ++ ld rWORD2, 8(rSTR2) ++#endif ++ srd rWORD1, rWORD1, rN ++ srd rWORD2, rWORD2, rN ++ cmpld cr7, rWORD1, rWORD2 ++ bne cr7, L(dLcr7x) ++ li rRTN, 0 + blr ++ + .align 4 +-L(dLcr0): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 +- bgtlr cr0 +- li rRTN,-1 ++L(dLcr7): ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dLcr7x): ++ li rRTN, 1 ++ bgtlr cr7 ++ li rRTN, -1 + blr + .align 4 + L(dLcr1): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dLcr1x): ++ li rRTN, 1 + bgtlr cr1 +- li rRTN,-1 ++ li rRTN, -1 + blr + .align 4 + L(dLcr6): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++L(dLcr6x): ++ li rRTN, 1 + bgtlr cr6 +- li rRTN,-1 ++ li rRTN, -1 + blr + .align 4 + L(dLcr5): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + L(dLcr5x): +- li rRTN,1 ++ li rRTN, 1 + bgtlr cr5 +- li rRTN,-1 ++ li rRTN, -1 + blr + + .align 4 + L(bytealigned): + mtctr rN +- beq cr6,L(zeroLength) ++#if 0 ++/* Huh? We've already branched on cr6! */ ++ beq cr6, L(zeroLength) ++#endif + + /* We need to prime this loop. This loop is swing modulo scheduled + to avoid pipe delays. The dependent instruction latencies (load to +@@ -401,38 +598,38 @@ + So we must precondition some registers and condition codes so that + we don't exit the loop early on the first iteration. */ + +- lbz rWORD1,0(rSTR1) +- lbz rWORD2,0(rSTR2) ++ lbz rWORD1, 0(rSTR1) ++ lbz rWORD2, 0(rSTR2) + bdz L(b11) +- cmpld cr0,rWORD1,rWORD2 +- lbz rWORD3,1(rSTR1) +- lbz rWORD4,1(rSTR2) ++ cmpld cr7, rWORD1, rWORD2 ++ lbz rWORD3, 1(rSTR1) ++ lbz rWORD4, 1(rSTR2) + bdz L(b12) +- cmpld cr1,rWORD3,rWORD4 +- lbzu rWORD5,2(rSTR1) +- lbzu rWORD6,2(rSTR2) ++ cmpld cr1, rWORD3, rWORD4 ++ lbzu rWORD5, 2(rSTR1) ++ lbzu rWORD6, 2(rSTR2) + bdz L(b13) + .align 4 + L(bLoop): +- lbzu rWORD1,1(rSTR1) +- lbzu rWORD2,1(rSTR2) +- bne cr0,L(bLcr0) ++ lbzu rWORD1, 1(rSTR1) ++ lbzu rWORD2, 1(rSTR2) ++ bne cr7, L(bLcr7) + +- cmpld cr6,rWORD5,rWORD6 ++ cmpld cr6, rWORD5, rWORD6 + bdz L(b3i) + +- lbzu rWORD3,1(rSTR1) +- lbzu rWORD4,1(rSTR2) +- bne cr1,L(bLcr1) ++ lbzu rWORD3, 1(rSTR1) ++ lbzu rWORD4, 1(rSTR2) ++ bne cr1, L(bLcr1) + +- cmpld cr0,rWORD1,rWORD2 ++ cmpld cr7, rWORD1, rWORD2 + bdz L(b2i) + +- lbzu rWORD5,1(rSTR1) +- lbzu rWORD6,1(rSTR2) +- bne cr6,L(bLcr6) ++ lbzu rWORD5, 1(rSTR1) ++ lbzu rWORD6, 1(rSTR2) ++ bne cr6, L(bLcr6) + +- cmpld cr1,rWORD3,rWORD4 ++ cmpld cr1, rWORD3, rWORD4 + bdnz L(bLoop) + + /* We speculatively loading bytes before we have tested the previous +@@ -442,542 +639,727 @@ + tested. In this case we must complete the pending operations + before returning. */ + L(b1i): +- bne cr0,L(bLcr0) +- bne cr1,L(bLcr1) ++ bne cr7, L(bLcr7) ++ bne cr1, L(bLcr1) + b L(bx56) + .align 4 + L(b2i): +- bne cr6,L(bLcr6) +- bne cr0,L(bLcr0) ++ bne cr6, L(bLcr6) ++ bne cr7, L(bLcr7) + b L(bx34) + .align 4 + L(b3i): +- bne cr1,L(bLcr1) +- bne cr6,L(bLcr6) ++ bne cr1, L(bLcr1) ++ bne cr6, L(bLcr6) + b L(bx12) + .align 4 +-L(bLcr0): +- li rRTN,1 +- bgtlr cr0 +- li rRTN,-1 ++L(bLcr7): ++ li rRTN, 1 ++ bgtlr cr7 ++ li rRTN, -1 + blr + L(bLcr1): +- li rRTN,1 ++ li rRTN, 1 + bgtlr cr1 +- li rRTN,-1 ++ li rRTN, -1 + blr + L(bLcr6): +- li rRTN,1 ++ li rRTN, 1 + bgtlr cr6 +- li rRTN,-1 ++ li rRTN, -1 + blr + + L(b13): +- bne cr0,L(bx12) +- bne cr1,L(bx34) ++ bne cr7, L(bx12) ++ bne cr1, L(bx34) + L(bx56): +- sub rRTN,rWORD5,rWORD6 ++ sub rRTN, rWORD5, rWORD6 + blr + nop + L(b12): +- bne cr0,L(bx12) ++ bne cr7, L(bx12) + L(bx34): +- sub rRTN,rWORD3,rWORD4 ++ sub rRTN, rWORD3, rWORD4 + blr + L(b11): + L(bx12): +- sub rRTN,rWORD1,rWORD2 ++ sub rRTN, rWORD1, rWORD2 + blr + .align 4 +-L(zeroLengthReturn): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) + L(zeroLength): +- li rRTN,0 ++ li rRTN, 0 + blr + + .align 4 + /* At this point we know the strings have different alignment and the +- compare length is at least 8 bytes. rBITDIF containes the low order ++ compare length is at least 8 bytes. r12 contains the low order + 3 bits of rSTR1 and cr5 contains the result of the logical compare +- of rBITDIF to 0. If rBITDIF == 0 then rStr1 is double word ++ of r12 to 0. If r12 == 0 then rStr1 is double word + aligned and can perform the DWunaligned loop. + +- Otherwise we know that rSTR1 is not aready DW aligned yet. ++ Otherwise we know that rSTR1 is not already DW aligned yet. + So we can force the string addresses to the next lower DW +- boundary and special case this first DW word using shift left to +- ellimiate bits preceeding the first byte. Since we want to join the ++ boundary and special case this first DW using shift left to ++ eliminate bits preceding the first byte. Since we want to join the + normal (DWaligned) compare loop, starting at the second double word, + we need to adjust the length (rN) and special case the loop +- versioning for the first DW. This insures that the loop count is ++ versioning for the first DW. This ensures that the loop count is + correct and the first DW (shifted) is in the expected resister pair. */ +-#define rSHL r29 /* Unaligned shift left count. */ +-#define rSHR r28 /* Unaligned shift right count. */ +-#define rB r27 /* Left rotation temp for rWORD2. */ +-#define rD r26 /* Left rotation temp for rWORD4. */ +-#define rF r25 /* Left rotation temp for rWORD6. */ +-#define rH r24 /* Left rotation temp for rWORD8. */ +-#define rA r0 /* Right rotation temp for rWORD2. */ +-#define rC r12 /* Right rotation temp for rWORD4. */ +-#define rE r0 /* Right rotation temp for rWORD6. */ +-#define rG r12 /* Right rotation temp for rWORD8. */ ++#define rSHL r29 /* Unaligned shift left count. */ ++#define rSHR r28 /* Unaligned shift right count. */ ++#define rWORD8_SHIFT r27 /* Left rotation temp for rWORD2. */ ++#define rWORD2_SHIFT r26 /* Left rotation temp for rWORD4. */ ++#define rWORD4_SHIFT r25 /* Left rotation temp for rWORD6. */ ++#define rWORD6_SHIFT r24 /* Left rotation temp for rWORD8. */ + L(unaligned): +- std r29,-24(r1) +- cfi_offset(r29,-24) +- clrldi rSHL,rSTR2,61 +- beq cr6,L(duzeroLength) +- std r28,-32(r1) +- cfi_offset(r28,-32) +- beq cr5,L(DWunaligned) +- std r27,-40(r1) +- cfi_offset(r27,-40) +-/* Adjust the logical start of rSTR2 ro compensate for the extra bits ++ std rSHL, -24(r1) ++ cfi_offset(rSHL, -24) ++ clrldi rSHL, rSTR2, 61 ++ beq cr6, L(duzeroLength) ++ std rSHR, -32(r1) ++ cfi_offset(rSHR, -32) ++ beq cr5, L(DWunaligned) ++ std rWORD8_SHIFT, -40(r1) ++ cfi_offset(rWORD8_SHIFT, -40) ++/* Adjust the logical start of rSTR2 to compensate for the extra bits + in the 1st rSTR1 DW. */ +- sub r27,rSTR2,rBITDIF ++ sub rWORD8_SHIFT, rSTR2, r12 + /* But do not attempt to address the DW before that DW that contains + the actual start of rSTR2. */ +- clrrdi rSTR2,rSTR2,3 +- std r26,-48(r1) +- cfi_offset(r26,-48) +-/* Compute the leaft/right shift counts for the unalign rSTR2, ++ clrrdi rSTR2, rSTR2, 3 ++ std rWORD2_SHIFT, -48(r1) ++ cfi_offset(rWORD2_SHIFT, -48) ++/* Compute the left/right shift counts for the unaligned rSTR2, + compensating for the logical (DW aligned) start of rSTR1. */ +- clrldi rSHL,r27,61 +- clrrdi rSTR1,rSTR1,3 +- std r25,-56(r1) +- cfi_offset(r25,-56) +- sldi rSHL,rSHL,3 +- cmpld cr5,r27,rSTR2 +- add rN,rN,rBITDIF +- sldi r11,rBITDIF,3 +- std r24,-64(r1) +- cfi_offset(r24,-64) +- subfic rSHR,rSHL,64 +- srdi rTMP,rN,5 /* Divide by 32 */ +- andi. rBITDIF,rN,24 /* Get the DW remainder */ ++ clrldi rSHL, rWORD8_SHIFT, 61 ++ clrrdi rSTR1, rSTR1, 3 ++ std rWORD4_SHIFT, -56(r1) ++ cfi_offset(rWORD4_SHIFT, -56) ++ sldi rSHL, rSHL, 3 ++ cmpld cr5, rWORD8_SHIFT, rSTR2 ++ add rN, rN, r12 ++ sldi rWORD6, r12, 3 ++ std rWORD6_SHIFT, -64(r1) ++ cfi_offset(rWORD6_SHIFT, -64) ++ subfic rSHR, rSHL, 64 ++ srdi r0, rN, 5 /* Divide by 32 */ ++ andi. r12, rN, 24 /* Get the DW remainder */ + /* We normally need to load 2 DWs to start the unaligned rSTR2, but in + this special case those bits may be discarded anyway. Also we + must avoid loading a DW where none of the bits are part of rSTR2 as + this may cross a page boundary and cause a page fault. */ +- li rWORD8,0 +- blt cr5,L(dus0) +- ld rWORD8,0(rSTR2) +- la rSTR2,8(rSTR2) +- sld rWORD8,rWORD8,rSHL ++ li rWORD8, 0 ++ blt cr5, L(dus0) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD8, 0(rSTR2) ++ addi rSTR2, rSTR2, 8 ++#endif ++ sld rWORD8, rWORD8, rSHL + + L(dus0): +- ld rWORD1,0(rSTR1) +- ld rWORD2,0(rSTR2) +- cmpldi cr1,rBITDIF,16 +- cmpldi cr7,rN,32 +- srd rG,rWORD2,rSHR +- clrldi rN,rN,61 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 0(rSTR1) ++ ld rWORD2, 0(rSTR2) ++#endif ++ cmpldi cr1, r12, 16 ++ cmpldi cr7, rN, 32 ++ srd r12, rWORD2, rSHR ++ clrldi rN, rN, 61 + beq L(duPs4) +- mtctr rTMP +- or rWORD8,rG,rWORD8 +- bgt cr1,L(duPs3) +- beq cr1,L(duPs2) ++ mtctr r0 ++ or rWORD8, r12, rWORD8 ++ bgt cr1, L(duPs3) ++ beq cr1, L(duPs2) + + /* Remainder is 8 */ + .align 4 + L(dusP1): +- sld rB,rWORD2,rSHL +- sld rWORD7,rWORD1,r11 +- sld rWORD8,rWORD8,r11 +- bge cr7,L(duP1e) ++ sld rWORD8_SHIFT, rWORD2, rSHL ++ sld rWORD7, rWORD1, rWORD6 ++ sld rWORD8, rWORD8, rWORD6 ++ bge cr7, L(duP1e) + /* At this point we exit early with the first double word compare + complete and remainder of 0 to 7 bytes. See L(du14) for details on + how we handle the remaining bytes. */ +- cmpld cr5,rWORD7,rWORD8 +- sldi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmpld cr7,rN,rSHR ++ cmpld cr5, rWORD7, rWORD8 ++ sldi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- ld rWORD2,8(rSTR2) +- srd rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD2, 8(rSTR2) ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 16 */ + .align 4 + L(duPs2): +- sld rH,rWORD2,rSHL +- sld rWORD5,rWORD1,r11 +- sld rWORD6,rWORD8,r11 ++ sld rWORD6_SHIFT, rWORD2, rSHL ++ sld rWORD5, rWORD1, rWORD6 ++ sld rWORD6, rWORD8, rWORD6 + b L(duP2e) + /* Remainder is 24 */ + .align 4 + L(duPs3): +- sld rF,rWORD2,rSHL +- sld rWORD3,rWORD1,r11 +- sld rWORD4,rWORD8,r11 ++ sld rWORD4_SHIFT, rWORD2, rSHL ++ sld rWORD3, rWORD1, rWORD6 ++ sld rWORD4, rWORD8, rWORD6 + b L(duP3e) + /* Count is a multiple of 32, remainder is 0 */ + .align 4 + L(duPs4): +- mtctr rTMP +- or rWORD8,rG,rWORD8 +- sld rD,rWORD2,rSHL +- sld rWORD1,rWORD1,r11 +- sld rWORD2,rWORD8,r11 ++ mtctr r0 ++ or rWORD8, r12, rWORD8 ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ sld rWORD1, rWORD1, rWORD6 ++ sld rWORD2, rWORD8, rWORD6 + b L(duP4e) + + /* At this point we know rSTR1 is double word aligned and the + compare length is at least 8 bytes. */ + .align 4 + L(DWunaligned): +- std r27,-40(r1) +- cfi_offset(r27,-40) +- clrrdi rSTR2,rSTR2,3 +- std r26,-48(r1) +- cfi_offset(r26,-48) +- srdi rTMP,rN,5 /* Divide by 32 */ +- std r25,-56(r1) +- cfi_offset(r25,-56) +- andi. rBITDIF,rN,24 /* Get the DW remainder */ +- std r24,-64(r1) +- cfi_offset(r24,-64) +- sldi rSHL,rSHL,3 +- ld rWORD6,0(rSTR2) +- ldu rWORD8,8(rSTR2) +- cmpldi cr1,rBITDIF,16 +- cmpldi cr7,rN,32 +- clrldi rN,rN,61 +- subfic rSHR,rSHL,64 +- sld rH,rWORD6,rSHL ++ std rWORD8_SHIFT, -40(r1) ++ cfi_offset(rWORD8_SHIFT, -40) ++ clrrdi rSTR2, rSTR2, 3 ++ std rWORD2_SHIFT, -48(r1) ++ cfi_offset(rWORD2_SHIFT, -48) ++ srdi r0, rN, 5 /* Divide by 32 */ ++ std rWORD4_SHIFT, -56(r1) ++ cfi_offset(rWORD4_SHIFT, -56) ++ andi. r12, rN, 24 /* Get the DW remainder */ ++ std rWORD6_SHIFT, -64(r1) ++ cfi_offset(rWORD6_SHIFT, -64) ++ sldi rSHL, rSHL, 3 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD6, 0(rSTR2) ++ ldu rWORD8, 8(rSTR2) ++#endif ++ cmpldi cr1, r12, 16 ++ cmpldi cr7, rN, 32 ++ clrldi rN, rN, 61 ++ subfic rSHR, rSHL, 64 ++ sld rWORD6_SHIFT, rWORD6, rSHL + beq L(duP4) +- mtctr rTMP +- bgt cr1,L(duP3) +- beq cr1,L(duP2) ++ mtctr r0 ++ bgt cr1, L(duP3) ++ beq cr1, L(duP2) + + /* Remainder is 8 */ + .align 4 + L(duP1): +- srd rG,rWORD8,rSHR +- ld rWORD7,0(rSTR1) +- sld rB,rWORD8,rSHL +- or rWORD8,rG,rH +- blt cr7,L(duP1x) ++ srd r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else ++ ld rWORD7, 0(rSTR1) ++#endif ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ blt cr7, L(duP1x) + L(duP1e): +- ld rWORD1,8(rSTR1) +- ld rWORD2,8(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- srd rA,rWORD2,rSHR +- sld rD,rWORD2,rSHL +- or rWORD2,rA,rB +- ld rWORD3,16(rSTR1) +- ld rWORD4,16(rSTR2) +- cmpld cr0,rWORD1,rWORD2 +- srd rC,rWORD4,rSHR +- sld rF,rWORD4,rSHL +- bne cr5,L(duLcr5) +- or rWORD4,rC,rD +- ld rWORD5,24(rSTR1) +- ld rWORD6,24(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- srd rE,rWORD6,rSHR +- sld rH,rWORD6,rSHL +- bne cr0,L(duLcr0) +- or rWORD6,rE,rF +- cmpld cr6,rWORD5,rWORD6 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 8(rSTR1) ++ ld rWORD2, 8(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 16(rSTR1) ++ ld rWORD4, 16(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ bne cr5, L(duLcr5) ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 24(rSTR1) ++ ld rWORD6, 24(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ bne cr7, L(duLcr7) ++ or rWORD6, r0, rWORD4_SHIFT ++ cmpld cr6, rWORD5, rWORD6 + b L(duLoop3) + .align 4 + /* At this point we exit early with the first double word compare + complete and remainder of 0 to 7 bytes. See L(du14) for details on + how we handle the remaining bytes. */ + L(duP1x): +- cmpld cr5,rWORD7,rWORD8 +- sldi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmpld cr7,rN,rSHR ++ cmpld cr5, rWORD7, rWORD8 ++ sldi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- ld rWORD2,8(rSTR2) +- srd rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD2, 8(rSTR2) ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 16 */ + .align 4 + L(duP2): +- srd rE,rWORD8,rSHR +- ld rWORD5,0(rSTR1) +- or rWORD6,rE,rH +- sld rH,rWORD8,rSHL ++ srd r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else ++ ld rWORD5, 0(rSTR1) ++#endif ++ or rWORD6, r0, rWORD6_SHIFT ++ sld rWORD6_SHIFT, rWORD8, rSHL + L(duP2e): +- ld rWORD7,8(rSTR1) +- ld rWORD8,8(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- srd rG,rWORD8,rSHR +- sld rB,rWORD8,rSHL +- or rWORD8,rG,rH +- blt cr7,L(duP2x) +- ld rWORD1,16(rSTR1) +- ld rWORD2,16(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- bne cr6,L(duLcr6) +- srd rA,rWORD2,rSHR +- sld rD,rWORD2,rSHL +- or rWORD2,rA,rB +- ld rWORD3,24(rSTR1) +- ld rWORD4,24(rSTR2) +- cmpld cr0,rWORD1,rWORD2 +- bne cr5,L(duLcr5) +- srd rC,rWORD4,rSHR +- sld rF,rWORD4,rSHL +- or rWORD4,rC,rD +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- cmpld cr1,rWORD3,rWORD4 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD7, 8(rSTR1) ++ ld rWORD8, 8(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ blt cr7, L(duP2x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 16(rSTR1) ++ ld rWORD2, 16(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ bne cr6, L(duLcr6) ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 24(rSTR1) ++ ld rWORD4, 24(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ bne cr5, L(duLcr5) ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ cmpld cr1, rWORD3, rWORD4 + b L(duLoop2) + .align 4 + L(duP2x): +- cmpld cr5,rWORD7,rWORD8 +- addi rSTR1,rSTR1,8 +- addi rSTR2,rSTR2,8 +- bne cr6,L(duLcr6) +- sldi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmpld cr7,rN,rSHR ++ cmpld cr5, rWORD7, rWORD8 ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#endif ++ bne cr6, L(duLcr6) ++ sldi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- ld rWORD2,8(rSTR2) +- srd rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD2, 8(rSTR2) ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) + + /* Remainder is 24 */ + .align 4 + L(duP3): +- srd rC,rWORD8,rSHR +- ld rWORD3,0(rSTR1) +- sld rF,rWORD8,rSHL +- or rWORD4,rC,rH ++ srd r12, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else ++ ld rWORD3, 0(rSTR1) ++#endif ++ sld rWORD4_SHIFT, rWORD8, rSHL ++ or rWORD4, r12, rWORD6_SHIFT + L(duP3e): +- ld rWORD5,8(rSTR1) +- ld rWORD6,8(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- srd rE,rWORD6,rSHR +- sld rH,rWORD6,rSHL +- or rWORD6,rE,rF +- ld rWORD7,16(rSTR1) +- ld rWORD8,16(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- bne cr1,L(duLcr1) +- srd rG,rWORD8,rSHR +- sld rB,rWORD8,rSHL +- or rWORD8,rG,rH +- blt cr7,L(duP3x) +- ld rWORD1,24(rSTR1) +- ld rWORD2,24(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- bne cr6,L(duLcr6) +- srd rA,rWORD2,rSHR +- sld rD,rWORD2,rSHL +- or rWORD2,rA,rB +- addi rSTR1,rSTR1,16 +- addi rSTR2,rSTR2,16 +- cmpld cr0,rWORD1,rWORD2 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 8(rSTR1) ++ ld rWORD6, 8(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD7, 16(rSTR1) ++ ld rWORD8, 16(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr1, L(duLcr1) ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ blt cr7, L(duP3x) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 24(rSTR1) ++ ld rWORD2, 24(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ bne cr6, L(duLcr6) ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 16 ++ addi rSTR2, rSTR2, 16 ++#endif ++ cmpld cr7, rWORD1, rWORD2 + b L(duLoop1) + .align 4 + L(duP3x): +- addi rSTR1,rSTR1,16 +- addi rSTR2,rSTR2,16 +- bne cr1,L(duLcr1) +- cmpld cr5,rWORD7,rWORD8 +- bne cr6,L(duLcr6) +- sldi. rN,rN,3 +- bne cr5,L(duLcr5) +- cmpld cr7,rN,rSHR ++#ifndef __LITTLE_ENDIAN__ ++ addi rSTR1, rSTR1, 16 ++ addi rSTR2, rSTR2, 16 ++#endif ++#if 0 ++/* Huh? We've already branched on cr1! */ ++ bne cr1, L(duLcr1) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ bne cr6, L(duLcr6) ++ sldi. rN, rN, 3 ++ bne cr5, L(duLcr5) ++ cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- ld rWORD2,8(rSTR2) +- srd rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD2, 8(rSTR2) ++#endif ++ srd r0, rWORD2, rSHR + b L(dutrim) + + /* Count is a multiple of 32, remainder is 0 */ + .align 4 + L(duP4): +- mtctr rTMP +- srd rA,rWORD8,rSHR +- ld rWORD1,0(rSTR1) +- sld rD,rWORD8,rSHL +- or rWORD2,rA,rH ++ mtctr r0 ++ srd r0, rWORD8, rSHR ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ addi rSTR1, rSTR1, 8 ++#else ++ ld rWORD1, 0(rSTR1) ++#endif ++ sld rWORD2_SHIFT, rWORD8, rSHL ++ or rWORD2, r0, rWORD6_SHIFT + L(duP4e): +- ld rWORD3,8(rSTR1) +- ld rWORD4,8(rSTR2) +- cmpld cr0,rWORD1,rWORD2 +- srd rC,rWORD4,rSHR +- sld rF,rWORD4,rSHL +- or rWORD4,rC,rD +- ld rWORD5,16(rSTR1) +- ld rWORD6,16(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- bne cr0,L(duLcr0) +- srd rE,rWORD6,rSHR +- sld rH,rWORD6,rSHL +- or rWORD6,rE,rF +- ldu rWORD7,24(rSTR1) +- ldu rWORD8,24(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- bne cr1,L(duLcr1) +- srd rG,rWORD8,rSHR +- sld rB,rWORD8,rSHL +- or rWORD8,rG,rH +- cmpld cr5,rWORD7,rWORD8 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 8(rSTR1) ++ ld rWORD4, 8(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 16(rSTR1) ++ ld rWORD6, 16(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ bne cr7, L(duLcr7) ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ldu rWORD7, 24(rSTR1) ++ ldu rWORD8, 24(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr1, L(duLcr1) ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT ++ cmpld cr5, rWORD7, rWORD8 + bdz L(du24) /* Adjust CTR as we start with +4 */ + /* This is the primary loop */ + .align 4 + L(duLoop): +- ld rWORD1,8(rSTR1) +- ld rWORD2,8(rSTR2) +- cmpld cr1,rWORD3,rWORD4 +- bne cr6,L(duLcr6) +- srd rA,rWORD2,rSHR +- sld rD,rWORD2,rSHL +- or rWORD2,rA,rB ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD1, 8(rSTR1) ++ ld rWORD2, 8(rSTR2) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ bne cr6, L(duLcr6) ++ srd r0, rWORD2, rSHR ++ sld rWORD2_SHIFT, rWORD2, rSHL ++ or rWORD2, r0, rWORD8_SHIFT + L(duLoop1): +- ld rWORD3,16(rSTR1) +- ld rWORD4,16(rSTR2) +- cmpld cr6,rWORD5,rWORD6 +- bne cr5,L(duLcr5) +- srd rC,rWORD4,rSHR +- sld rF,rWORD4,rSHL +- or rWORD4,rC,rD ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD3, 0, rSTR1 ++ ldbrx rWORD4, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD3, 16(rSTR1) ++ ld rWORD4, 16(rSTR2) ++#endif ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr5, L(duLcr5) ++ srd r12, rWORD4, rSHR ++ sld rWORD4_SHIFT, rWORD4, rSHL ++ or rWORD4, r12, rWORD2_SHIFT + L(duLoop2): +- ld rWORD5,24(rSTR1) +- ld rWORD6,24(rSTR2) +- cmpld cr5,rWORD7,rWORD8 +- bne cr0,L(duLcr0) +- srd rE,rWORD6,rSHR +- sld rH,rWORD6,rSHL +- or rWORD6,rE,rF ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD5, 0, rSTR1 ++ ldbrx rWORD6, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD5, 24(rSTR1) ++ ld rWORD6, 24(rSTR2) ++#endif ++ cmpld cr5, rWORD7, rWORD8 ++ bne cr7, L(duLcr7) ++ srd r0, rWORD6, rSHR ++ sld rWORD6_SHIFT, rWORD6, rSHL ++ or rWORD6, r0, rWORD4_SHIFT + L(duLoop3): +- ldu rWORD7,32(rSTR1) +- ldu rWORD8,32(rSTR2) +- cmpld cr0,rWORD1,rWORD2 +- bne- cr1,L(duLcr1) +- srd rG,rWORD8,rSHR +- sld rB,rWORD8,rSHL +- or rWORD8,rG,rH ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD7, 0, rSTR1 ++ ldbrx rWORD8, 0, rSTR2 ++ addi rSTR1, rSTR1, 8 ++ addi rSTR2, rSTR2, 8 ++#else ++ ldu rWORD7, 32(rSTR1) ++ ldu rWORD8, 32(rSTR2) ++#endif ++ cmpld cr7, rWORD1, rWORD2 ++ bne cr1, L(duLcr1) ++ srd r12, rWORD8, rSHR ++ sld rWORD8_SHIFT, rWORD8, rSHL ++ or rWORD8, r12, rWORD6_SHIFT + bdnz L(duLoop) + + L(duL4): +- bne cr1,L(duLcr1) +- cmpld cr1,rWORD3,rWORD4 +- bne cr6,L(duLcr6) +- cmpld cr6,rWORD5,rWORD6 +- bne cr5,L(duLcr5) +- cmpld cr5,rWORD7,rWORD8 ++#if 0 ++/* Huh? We've already branched on cr1! */ ++ bne cr1, L(duLcr1) ++#endif ++ cmpld cr1, rWORD3, rWORD4 ++ bne cr6, L(duLcr6) ++ cmpld cr6, rWORD5, rWORD6 ++ bne cr5, L(duLcr5) ++ cmpld cr5, rWORD7, rWORD8 + L(du44): +- bne cr0,L(duLcr0) ++ bne cr7, L(duLcr7) + L(du34): +- bne cr1,L(duLcr1) ++ bne cr1, L(duLcr1) + L(du24): +- bne cr6,L(duLcr6) ++ bne cr6, L(duLcr6) + L(du14): +- sldi. rN,rN,3 +- bne cr5,L(duLcr5) ++ sldi. rN, rN, 3 ++ bne cr5, L(duLcr5) + /* At this point we have a remainder of 1 to 7 bytes to compare. We use +- shift right double to elliminate bits beyond the compare length. +- This allows the use of double word subtract to compute the final +- result. ++ shift right double to eliminate bits beyond the compare length. + + However it may not be safe to load rWORD2 which may be beyond the + string length. So we compare the bit length of the remainder to + the right shift count (rSHR). If the bit count is less than or equal + we do not need to load rWORD2 (all significant bits are already in +- rB). */ +- cmpld cr7,rN,rSHR ++ rWORD8_SHIFT). */ ++ cmpld cr7, rN, rSHR + beq L(duZeroReturn) +- li rA,0 +- ble cr7,L(dutrim) +- ld rWORD2,8(rSTR2) +- srd rA,rWORD2,rSHR ++ li r0, 0 ++ ble cr7, L(dutrim) ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD2, 0, rSTR2 ++ addi rSTR2, rSTR2, 8 ++#else ++ ld rWORD2, 8(rSTR2) ++#endif ++ srd r0, rWORD2, rSHR + .align 4 + L(dutrim): +- ld rWORD1,8(rSTR1) +- ld rWORD8,-8(r1) +- subfic rN,rN,64 /* Shift count is 64 - (rN * 8). */ +- or rWORD2,rA,rB +- ld rWORD7,-16(r1) +- ld r29,-24(r1) +- srd rWORD1,rWORD1,rN +- srd rWORD2,rWORD2,rN +- ld r28,-32(r1) +- ld r27,-40(r1) +- li rRTN,0 +- cmpld cr0,rWORD1,rWORD2 +- ld r26,-48(r1) +- ld r25,-56(r1) +- beq cr0,L(dureturn24) +- li rRTN,1 +- ld r24,-64(r1) +- bgtlr cr0 +- li rRTN,-1 +- blr +- .align 4 +-L(duLcr0): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 +- bgt cr0,L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) +- li rRTN,-1 ++#ifdef __LITTLE_ENDIAN__ ++ ldbrx rWORD1, 0, rSTR1 ++#else ++ ld rWORD1, 8(rSTR1) ++#endif ++ ld rWORD8, -8(r1) ++ subfic rN, rN, 64 /* Shift count is 64 - (rN * 8). */ ++ or rWORD2, r0, rWORD8_SHIFT ++ ld rWORD7, -16(r1) ++ ld rSHL, -24(r1) ++ srd rWORD1, rWORD1, rN ++ srd rWORD2, rWORD2, rN ++ ld rSHR, -32(r1) ++ ld rWORD8_SHIFT, -40(r1) ++ li rRTN, 0 ++ cmpld cr7, rWORD1, rWORD2 ++ ld rWORD2_SHIFT, -48(r1) ++ ld rWORD4_SHIFT, -56(r1) ++ beq cr7, L(dureturn24) ++ li rRTN, 1 ++ ld rWORD6_SHIFT, -64(r1) ++ bgtlr cr7 ++ li rRTN, -1 ++ blr ++ .align 4 ++L(duLcr7): ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ li rRTN, 1 ++ bgt cr7, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr1): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 +- bgt cr1,L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) +- li rRTN,-1 ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ li rRTN, 1 ++ bgt cr1, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr6): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 +- bgt cr6,L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) +- li rRTN,-1 ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ li rRTN, 1 ++ bgt cr6, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr5): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) +- li rRTN,1 +- bgt cr5,L(dureturn29) +- ld r29,-24(r1) +- ld r28,-32(r1) +- li rRTN,-1 ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) ++ li rRTN, 1 ++ bgt cr5, L(dureturn29) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) ++ li rRTN, -1 + b L(dureturn27) + .align 3 + L(duZeroReturn): +- li rRTN,0 ++ li rRTN, 0 + .align 4 + L(dureturn): +- ld rWORD8,-8(r1) +- ld rWORD7,-16(r1) ++ ld rWORD8, -8(r1) ++ ld rWORD7, -16(r1) + L(dureturn29): +- ld r29,-24(r1) +- ld r28,-32(r1) ++ ld rSHL, -24(r1) ++ ld rSHR, -32(r1) + L(dureturn27): +- ld r27,-40(r1) ++ ld rWORD8_SHIFT, -40(r1) + L(dureturn26): +- ld r26,-48(r1) ++ ld rWORD2_SHIFT, -48(r1) + L(dureturn25): +- ld r25,-56(r1) ++ ld rWORD4_SHIFT, -56(r1) + L(dureturn24): +- ld r24,-64(r1) ++ ld rWORD6_SHIFT, -64(r1) + blr + L(duzeroLength): +- li rRTN,0 ++ li rRTN, 0 + blr + +-END (BP_SYM (memcmp)) ++END (memcmp) + libc_hidden_builtin_def (memcmp) +-weak_alias (memcmp,bcmp) ++weak_alias (memcmp, bcmp) diff --git a/SOURCES/glibc-ppc64le-31.patch b/SOURCES/glibc-ppc64le-31.patch new file mode 100644 index 00000000..dfde2989 --- /dev/null +++ b/SOURCES/glibc-ppc64le-31.patch @@ -0,0 +1,2943 @@ +# commit 759cfef3ac4c07dba1ece0bbc1207e099348816d +# Author: Alan Modra +# Date: Sat Aug 17 18:47:22 2013 +0930 +# +# PowerPC LE memcpy +# http://sourceware.org/ml/libc-alpha/2013-08/msg00103.html +# +# LIttle-endian support for memcpy. I spent some time cleaning up the +# 64-bit power7 memcpy, in order to avoid the extra alignment traps +# power7 takes for little-endian. It probably would have been better +# to copy the linux kernel version of memcpy. +# +# * sysdeps/powerpc/powerpc32/power4/memcpy.S: Add little endian support. +# * sysdeps/powerpc/powerpc32/power6/memcpy.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/memcpy.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/mempcpy.S: Likewise. +# * sysdeps/powerpc/powerpc64/memcpy.S: Likewise. +# * sysdeps/powerpc/powerpc64/power4/memcpy.S: Likewise. +# * sysdeps/powerpc/powerpc64/power6/memcpy.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/memcpy.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/mempcpy.S: Likewise. Make better +# use of regs. Use power7 mtocrf. Tidy function tails. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memcpy.S 2014-05-29 13:04:56.000000000 -0500 +@@ -205,15 +205,28 @@ + blt cr6,5f + srwi 7,6,16 + bgt cr6,3f ++#ifdef __LITTLE_ENDIAN__ ++ sth 7,0(3) ++#else + sth 6,0(3) ++#endif + b 7f + .align 4 + 3: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,24 ++ stb 6,0(3) ++ sth 7,1(3) ++#else + stb 7,0(3) + sth 6,1(3) ++#endif + b 7f + .align 4 + 5: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,8 ++#endif + stb 6,0(3) + 7: + cmplwi cr1,10,16 +@@ -341,13 +354,23 @@ + bf 30,1f + + /* there are at least two words to copy, so copy them */ ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,6,10 ++ slw 8,7,9 ++#else + slw 0,6,10 /* shift 1st src word to left align it in R0 */ + srw 8,7,9 /* shift 2nd src word to right align it in R8 */ ++#endif + or 0,0,8 /* or them to get word to store */ + lwz 6,8(5) /* load the 3rd src word */ + stw 0,0(4) /* store the 1st dst word */ ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,7,10 ++ slw 8,6,9 ++#else + slw 0,7,10 /* now left align 2nd src word into R0 */ + srw 8,6,9 /* shift 3rd src word to right align it in R8 */ ++#endif + or 0,0,8 /* or them to get word to store */ + lwz 7,12(5) + stw 0,4(4) /* store the 2nd dst word */ +@@ -355,8 +378,13 @@ + addi 5,5,16 + bf 31,4f + /* there is a third word to copy, so copy it */ ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,6,10 ++ slw 8,7,9 ++#else + slw 0,6,10 /* shift 3rd src word to left align it in R0 */ + srw 8,7,9 /* shift 4th src word to right align it in R8 */ ++#endif + or 0,0,8 /* or them to get word to store */ + stw 0,0(4) /* store 3rd dst word */ + mr 6,7 +@@ -366,8 +394,13 @@ + b 4f + .align 4 + 1: ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,6,10 ++ slw 8,7,9 ++#else + slw 0,6,10 /* shift 1st src word to left align it in R0 */ + srw 8,7,9 /* shift 2nd src word to right align it in R8 */ ++#endif + addi 5,5,8 + or 0,0,8 /* or them to get word to store */ + bf 31,4f +@@ -380,23 +413,43 @@ + .align 4 + 4: + /* copy 16 bytes at a time */ ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,6,10 ++ slw 8,7,9 ++#else + slw 0,6,10 + srw 8,7,9 ++#endif + or 0,0,8 + lwz 6,0(5) + stw 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,7,10 ++ slw 8,6,9 ++#else + slw 0,7,10 + srw 8,6,9 ++#endif + or 0,0,8 + lwz 7,4(5) + stw 0,4(4) ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,6,10 ++ slw 8,7,9 ++#else + slw 0,6,10 + srw 8,7,9 ++#endif + or 0,0,8 + lwz 6,8(5) + stw 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,7,10 ++ slw 8,6,9 ++#else + slw 0,7,10 + srw 8,6,9 ++#endif + or 0,0,8 + lwz 7,12(5) + stw 0,12(4) +@@ -405,8 +458,13 @@ + bdnz+ 4b + 8: + /* calculate and store the final word */ ++#ifdef __LITTLE_ENDIAN__ ++ srw 0,6,10 ++ slw 8,7,9 ++#else + slw 0,6,10 + srw 8,7,9 ++#endif + or 0,0,8 + stw 0,0(4) + 3: +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memcpy.S 2014-05-29 13:04:56.000000000 -0500 +@@ -221,15 +221,28 @@ + blt cr6,5f + srwi 7,6,16 + bgt cr6,3f ++#ifdef __LITTLE_ENDIAN__ ++ sth 7,0(3) ++#else + sth 6,0(3) ++#endif + b 7f + .align 4 + 3: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,24 ++ stb 6,0(3) ++ sth 7,1(3) ++#else + stb 7,0(3) + sth 6,1(3) ++#endif + b 7f + .align 4 + 5: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,8 ++#endif + stb 6,0(3) + 7: + cmplwi cr1,10,16 +@@ -579,7 +592,11 @@ + lwz 6,-1(4) + cmplwi cr6,31,4 + srwi 8,31,5 /* calculate the 32 byte loop count */ ++#ifdef __LITTLE_ENDIAN__ ++ srwi 6,6,8 ++#else + slwi 6,6,8 ++#endif + clrlwi 31,31,27 /* The remaining bytes, < 32. */ + blt cr5,L(wdu1_32tail) + mtctr 8 +@@ -587,8 +604,12 @@ + + lwz 8,3(4) + lwz 7,4(4) ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,24,32 ++#else + /* Equivalent to: srwi 8,8,32-8; or 6,6,8 */ + rlwimi 6,8,8,(32-8),31 ++#endif + b L(wdu1_loop32x) + .align 4 + L(wdu1_loop32): +@@ -597,8 +618,12 @@ + lwz 7,4(4) + stw 10,-8(3) + stw 11,-4(3) ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,24,32 ++#else + /* Equivalent to srwi 8,8,32-8; or 6,6,8 */ + rlwimi 6,8,8,(32-8),31 ++#endif + L(wdu1_loop32x): + lwz 10,8(4) + lwz 11,12(4) +@@ -615,7 +640,11 @@ + stw 6,16(3) + stw 7,20(3) + addi 3,3,32 ++#ifdef __LITTLE_ENDIAN__ ++ srwi 6,8,8 ++#else + slwi 6,8,8 ++#endif + bdnz+ L(wdu1_loop32) + stw 10,-8(3) + stw 11,-4(3) +@@ -626,8 +655,12 @@ + blt cr6,L(wdu_4tail) + /* calculate and store the final word */ + lwz 8,3(4) +-/* Equivalent to: srwi 8,8,32-9; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,24,32 ++#else ++/* Equivalent to: srwi 8,8,32-8; or 6,6,8 */ + rlwimi 6,8,8,(32-8),31 ++#endif + b L(wdu_32tailx) + + L(wdu2_32): +@@ -635,7 +668,11 @@ + lwz 6,-2(4) + cmplwi cr6,31,4 + srwi 8,31,5 /* calculate the 32 byte loop count */ ++#ifdef __LITTLE_ENDIAN__ ++ srwi 6,6,16 ++#else + slwi 6,6,16 ++#endif + clrlwi 31,31,27 /* The remaining bytes, < 32. */ + blt cr5,L(wdu2_32tail) + mtctr 8 +@@ -643,8 +680,11 @@ + + lwz 8,2(4) + lwz 7,4(4) +-/* Equivalent to: srwi 8,8,32-8; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,16,32 ++#else + rlwimi 6,8,16,(32-16),31 ++#endif + b L(wdu2_loop32x) + .align 4 + L(wdu2_loop32): +@@ -653,8 +693,11 @@ + lwz 7,4(4) + stw 10,-8(3) + stw 11,-4(3) +-/* Equivalent to srwi 8,8,32-8; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,16,32 ++#else + rlwimi 6,8,16,(32-16),31 ++#endif + L(wdu2_loop32x): + lwz 10,8(4) + lwz 11,12(4) +@@ -672,7 +715,11 @@ + stw 6,16(3) + stw 7,20(3) + addi 3,3,32 ++#ifdef __LITTLE_ENDIAN__ ++ srwi 6,8,16 ++#else + slwi 6,8,16 ++#endif + bdnz+ L(wdu2_loop32) + stw 10,-8(3) + stw 11,-4(3) +@@ -683,8 +730,11 @@ + blt cr6,L(wdu_4tail) + /* calculate and store the final word */ + lwz 8,2(4) +-/* Equivalent to: srwi 8,8,32-9; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,16,32 ++#else + rlwimi 6,8,16,(32-16),31 ++#endif + b L(wdu_32tailx) + + L(wdu3_32): +@@ -692,7 +742,11 @@ + lwz 6,-3(4) + cmplwi cr6,31,4 + srwi 8,31,5 /* calculate the 32 byte loop count */ ++#ifdef __LITTLE_ENDIAN__ ++ srwi 6,6,24 ++#else + slwi 6,6,24 ++#endif + clrlwi 31,31,27 /* The remaining bytes, < 32. */ + blt cr5,L(wdu3_32tail) + mtctr 8 +@@ -700,8 +754,11 @@ + + lwz 8,1(4) + lwz 7,4(4) +-/* Equivalent to: srwi 8,8,32-8; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,8,32 ++#else + rlwimi 6,8,24,(32-24),31 ++#endif + b L(wdu3_loop32x) + .align 4 + L(wdu3_loop32): +@@ -710,8 +767,11 @@ + lwz 7,4(4) + stw 10,-8(3) + stw 11,-4(3) +-/* Equivalent to srwi 8,8,32-8; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,8,32 ++#else + rlwimi 6,8,24,(32-24),31 ++#endif + L(wdu3_loop32x): + lwz 10,8(4) + lwz 11,12(4) +@@ -728,7 +788,11 @@ + stw 6,16(3) + stw 7,20(3) + addi 3,3,32 ++#ifdef __LITTLE_ENDIAN__ ++ srwi 6,8,24 ++#else + slwi 6,8,24 ++#endif + bdnz+ L(wdu3_loop32) + stw 10,-8(3) + stw 11,-4(3) +@@ -739,8 +803,11 @@ + blt cr6,L(wdu_4tail) + /* calculate and store the final word */ + lwz 8,1(4) +-/* Equivalent to: srwi 8,8,32-9; or 6,6,8 */ ++#ifdef __LITTLE_ENDIAN__ ++ rldimi 6,8,8,32 ++#else + rlwimi 6,8,24,(32-24),31 ++#endif + b L(wdu_32tailx) + .align 4 + L(wdu_32tailx): +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memcpy.S 2014-05-29 13:04:56.000000000 -0500 +@@ -385,7 +385,7 @@ + + beq L(copy_GE_32_unaligned_cont) + +- /* SRC is not quadword aligned, get it aligned. */ ++ /* DST is not quadword aligned, get it aligned. */ + + mtcrf 0x01,0 + subf 31,0,5 +@@ -437,13 +437,21 @@ + mr 11,12 + mtcrf 0x01,9 + cmplwi cr6,9,1 ++#ifdef __LITTLE_ENDIAN__ ++ lvsr 5,0,12 ++#else + lvsl 5,0,12 ++#endif + lvx 3,0,12 + bf 31,L(setup_unaligned_loop) + + /* Copy another 16 bytes to align to 32-bytes due to the loop . */ + lvx 4,12,6 ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else + vperm 6,3,4,5 ++#endif + addi 11,12,16 + addi 10,3,16 + stvx 6,0,3 +@@ -463,11 +471,17 @@ + vector instructions though. */ + + lvx 4,11,6 /* vr4 = r11+16. */ +- vperm 6,3,4,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr6. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif + lvx 3,11,7 /* vr3 = r11+32. */ +- vperm 10,4,3,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr10. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm 10,3,4,5 ++#else ++ vperm 10,4,3,5 ++#endif + addi 11,11,32 + stvx 6,0,10 + stvx 10,10,6 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/mempcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/mempcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/mempcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/mempcpy.S 2014-05-29 13:04:56.000000000 -0500 +@@ -327,7 +327,7 @@ + + beq L(copy_GE_32_unaligned_cont) + +- /* SRC is not quadword aligned, get it aligned. */ ++ /* DST is not quadword aligned, get it aligned. */ + + mtcrf 0x01,0 + subf 31,0,5 +@@ -379,13 +379,21 @@ + mr 11,12 + mtcrf 0x01,9 + cmplwi cr6,9,1 +- lvsl 5,0,12 ++#ifdef __LITTLE_ENDIAN__ ++ lvsr 5,0,12 ++#else ++ lvsl 5,0,12 ++#endif + lvx 3,0,12 + bf 31,L(setup_unaligned_loop) + + /* Copy another 16 bytes to align to 32-bytes due to the loop . */ + lvx 4,12,6 +- vperm 6,3,4,5 ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif + addi 11,12,16 + addi 10,3,16 + stvx 6,0,3 +@@ -405,11 +413,17 @@ + vector instructions though. */ + + lvx 4,11,6 /* vr4 = r11+16. */ +- vperm 6,3,4,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr6. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif + lvx 3,11,7 /* vr3 = r11+32. */ +- vperm 10,4,3,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr10. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm 10,3,4,5 ++#else ++ vperm 10,4,3,5 ++#endif + addi 11,11,32 + stvx 6,0,10 + stvx 10,10,6 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memcpy.S 2014-05-29 13:04:56.000000000 -0500 +@@ -214,15 +214,28 @@ + blt cr6,5f + srdi 7,6,16 + bgt cr6,3f ++#ifdef __LITTLE_ENDIAN__ ++ sth 7,0(3) ++#else + sth 6,0(3) ++#endif + b 7f + .align 4 + 3: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,24 ++ stb 6,0(3) ++ sth 7,1(3) ++#else + stb 7,0(3) + sth 6,1(3) ++#endif + b 7f + .align 4 + 5: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,8 ++#endif + stb 6,0(3) + 7: + cmpldi cr1,10,16 +@@ -330,7 +343,11 @@ + ld 7,8(5) + subfic 9,10,64 + beq 2f ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++#else + sld 0,6,10 ++#endif + cmpldi 11,1 + mr 6,7 + addi 4,4,-8 +@@ -338,15 +355,25 @@ + b 1f + 2: addi 5,5,8 + .align 4 ++#ifdef __LITTLE_ENDIAN__ ++0: srd 0,6,10 ++ sld 8,7,9 ++#else + 0: sld 0,6,10 + srd 8,7,9 ++#endif + cmpldi 11,2 + ld 6,8(5) + or 0,0,8 + addi 11,11,-2 + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,7,10 ++1: sld 8,6,9 ++#else + sld 0,7,10 + 1: srd 8,6,9 ++#endif + or 0,0,8 + beq 8f + ld 7,16(5) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memcpy.S 2014-05-29 13:05:51.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memcpy implementation for PowerPC64. +- Copyright (C) 2003, 2006, 2011 Free Software Foundation, Inc. ++ Copyright (C) 2003-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,26 +17,24 @@ + . */ + + #include +-#include +-#include + + /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]); + Returns 'dst'. + +- Memcpy handles short copies (< 32-bytes) using a binary move blocks +- (no loops) of lwz/stw. The tail (remaining 1-3) bytes is handled +- with the appropriate combination of byte and halfword load/stores. +- There is minimal effort to optimize the alignment of short moves. ++ Memcpy handles short copies (< 32-bytes) using a binary move blocks ++ (no loops) of lwz/stw. The tail (remaining 1-3) bytes is handled ++ with the appropriate combination of byte and halfword load/stores. ++ There is minimal effort to optimize the alignment of short moves. + The 64-bit implementations of POWER3 and POWER4 do a reasonable job +- of handling unligned load/stores that do not cross 32-byte boundries. ++ of handling unaligned load/stores that do not cross 32-byte boundaries. + + Longer moves (>= 32-bytes) justify the effort to get at least the + destination doubleword (8-byte) aligned. Further optimization is +- posible when both source and destination are doubleword aligned. ++ possible when both source and destination are doubleword aligned. + Each case has a optimized unrolled loop. */ + + .machine power4 +-EALIGN (BP_SYM (memcpy), 5, 0) ++EALIGN (memcpy, 5, 0) + CALL_MCOUNT 3 + + cmpldi cr1,5,31 +@@ -44,20 +42,20 @@ + std 3,-16(1) + std 31,-8(1) + cfi_offset(31,-8) +- andi. 11,3,7 /* check alignement of dst. */ ++ andi. 11,3,7 /* check alignment of dst. */ + clrldi 0,0,61 /* Number of bytes until the 1st doubleword of dst. */ +- clrldi 10,4,61 /* check alignement of src. */ ++ clrldi 10,4,61 /* check alignment of src. */ + cmpldi cr6,5,8 + ble- cr1,.L2 /* If move < 32 bytes use short move code. */ +- cmpld cr6,10,11 ++ cmpld cr6,10,11 + mr 12,4 + srdi 9,5,3 /* Number of full double words remaining. */ + mtcrf 0x01,0 + mr 31,5 + beq .L0 +- ++ + subf 31,0,5 +- /* Move 0-7 bytes as needed to get the destination doubleword alligned. */ ++ /* Move 0-7 bytes as needed to get the destination doubleword aligned. */ + 1: bf 31,2f + lbz 6,0(12) + addi 12,12,1 +@@ -74,17 +72,17 @@ + stw 6,0(3) + addi 3,3,4 + 0: +- clrldi 10,12,61 /* check alignement of src again. */ ++ clrldi 10,12,61 /* check alignment of src again. */ + srdi 9,31,3 /* Number of full double words remaining. */ +- +- /* Copy doublewords from source to destination, assumpting the ++ ++ /* Copy doublewords from source to destination, assuming the + destination is aligned on a doubleword boundary. + + At this point we know there are at least 25 bytes left (32-7) to copy. +- The next step is to determine if the source is also doubleword aligned. ++ The next step is to determine if the source is also doubleword aligned. + If not branch to the unaligned move code at .L6. which uses + a load, shift, store strategy. +- ++ + Otherwise source and destination are doubleword aligned, and we can + the optimized doubleword copy loop. */ + .L0: +@@ -97,14 +95,14 @@ + Use a unrolled loop to copy 4 doubleword (32-bytes) per iteration. + If the copy is not an exact multiple of 32 bytes, 1-3 + doublewords are copied as needed to set up the main loop. After +- the main loop exits there may be a tail of 1-7 bytes. These byte are ++ the main loop exits there may be a tail of 1-7 bytes. These byte are + copied a word/halfword/byte at a time as needed to preserve alignment. */ + + srdi 8,31,5 + cmpldi cr1,9,4 + cmpldi cr6,11,0 + mr 11,12 +- ++ + bf 30,1f + ld 6,0(12) + ld 7,8(12) +@@ -115,7 +113,7 @@ + addi 10,3,16 + bf 31,4f + ld 0,16(12) +- std 0,16(3) ++ std 0,16(3) + blt cr1,3f + addi 11,12,24 + addi 10,3,24 +@@ -129,7 +127,7 @@ + addi 11,12,8 + std 6,0(3) + addi 10,3,8 +- ++ + .align 4 + 4: + ld 6,0(11) +@@ -144,7 +142,7 @@ + std 0,24(10) + addi 10,10,32 + bdnz 4b +-3: ++3: + + rldicr 0,31,0,60 + mtcrf 0x01,31 +@@ -152,9 +150,9 @@ + .L9: + add 3,3,0 + add 12,12,0 +- ++ + /* At this point we have a tail of 0-7 bytes and we know that the +- destiniation is double word aligned. */ ++ destination is double word aligned. */ + 4: bf 29,2f + lwz 6,0(12) + addi 12,12,4 +@@ -173,29 +171,29 @@ + ld 31,-8(1) + ld 3,-16(1) + blr +- +-/* Copy up to 31 bytes. This divided into two cases 0-8 bytes and 9-31 +- bytes. Each case is handled without loops, using binary (1,2,4,8) +- tests. +- ++ ++/* Copy up to 31 bytes. This divided into two cases 0-8 bytes and 9-31 ++ bytes. Each case is handled without loops, using binary (1,2,4,8) ++ tests. ++ + In the short (0-8 byte) case no attempt is made to force alignment +- of either source or destination. The hardware will handle the +- unaligned load/stores with small delays for crossing 32- 64-byte, and ++ of either source or destination. The hardware will handle the ++ unaligned load/stores with small delays for crossing 32- 64-byte, and + 4096-byte boundaries. Since these short moves are unlikely to be +- unaligned or cross these boundaries, the overhead to force ++ unaligned or cross these boundaries, the overhead to force + alignment is not justified. +- ++ + The longer (9-31 byte) move is more likely to cross 32- or 64-byte + boundaries. Since only loads are sensitive to the 32-/64-byte +- boundaries it is more important to align the source then the ++ boundaries it is more important to align the source then the + destination. If the source is not already word aligned, we first +- move 1-3 bytes as needed. Since we are only word aligned we don't +- use double word load/stores to insure that all loads are aligned. ++ move 1-3 bytes as needed. Since we are only word aligned we don't ++ use double word load/stores to insure that all loads are aligned. + While the destination and stores may still be unaligned, this + is only an issue for page (4096 byte boundary) crossing, which + should be rare for these short moves. The hardware handles this +- case automatically with a small delay. */ +- ++ case automatically with a small delay. */ ++ + .align 4 + .L2: + mtcrf 0x01,5 +@@ -216,15 +214,28 @@ + blt cr6,5f + srdi 7,6,16 + bgt cr6,3f ++#ifdef __LITTLE_ENDIAN__ ++ sth 7,0(3) ++#else + sth 6,0(3) ++#endif + b 7f + .align 4 + 3: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,24 ++ stb 6,0(3) ++ sth 7,1(3) ++#else + stb 7,0(3) + sth 6,1(3) ++#endif + b 7f + .align 4 + 5: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,8 ++#endif + stb 6,0(3) + 7: + cmpldi cr1,10,16 +@@ -258,11 +269,11 @@ + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) +- addi 3,3,4 ++ addi 3,3,4 + 2: /* Move 2-3 bytes. */ + bf 30,1f + lhz 6,0(12) +- sth 6,0(3) ++ sth 6,0(3) + bf 31,0f + lbz 7,2(12) + stb 7,2(3) +@@ -283,8 +294,8 @@ + mr 12,4 + bne cr6,4f + /* Would have liked to use use ld/std here but the 630 processors are +- slow for load/store doubles that are not at least word aligned. +- Unaligned Load/Store word execute with only a 1 cycle penaltity. */ ++ slow for load/store doubles that are not at least word aligned. ++ Unaligned Load/Store word execute with only a 1 cycle penalty. */ + lwz 6,0(4) + lwz 7,4(4) + stw 6,0(3) +@@ -299,14 +310,14 @@ + 6: + bf 30,5f + lhz 7,4(4) +- sth 7,4(3) ++ sth 7,4(3) + bf 31,0f + lbz 8,6(4) + stb 8,6(3) + ld 3,-16(1) + blr + .align 4 +-5: ++5: + bf 31,0f + lbz 6,4(4) + stb 6,4(3) +@@ -336,13 +347,23 @@ + bf 30,1f + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++ sld 8,7,9 ++#else + sld 0,6,10 + srd 8,7,9 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,7,10 ++ sld 8,6,9 ++#else + sld 0,7,10 + srd 8,6,9 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -351,8 +372,13 @@ + blt cr6,8f /* if total DWs = 3, then bypass loop */ + bf 31,4f + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++ sld 8,7,9 ++#else + sld 0,6,10 + srd 8,7,9 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -363,8 +389,13 @@ + b 4f + .align 4 + 1: ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++ sld 8,7,9 ++#else + sld 0,6,10 + srd 8,7,9 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,4f +@@ -375,23 +406,44 @@ + addi 4,4,8 + .align 4 + /* copy 32 bytes at a time */ +-4: sld 0,6,10 ++4: ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++ sld 8,7,9 ++#else ++ sld 0,6,10 + srd 8,7,9 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,7,10 ++ sld 8,6,9 ++#else + sld 0,7,10 + srd 8,6,9 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++ sld 8,7,9 ++#else + sld 0,6,10 + srd 8,7,9 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,7,10 ++ sld 8,6,9 ++#else + sld 0,7,10 + srd 8,6,9 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -401,9 +453,14 @@ + .align 4 + 8: + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srd 0,6,10 ++ sld 8,7,9 ++#else + sld 0,6,10 + srd 8,7,9 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + 3: + rldicr 0,31,0,60 +@@ -413,5 +470,5 @@ + ld 31,-8(1) + ld 3,-16(1) + blr +-END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS) ++END_GEN_TB (memcpy,TB_TOCLESS) + libc_hidden_builtin_def (memcpy) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memcpy.S 2014-05-29 13:05:27.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memcpy implementation for PowerPC64. +- Copyright (C) 2003, 2006, 2007, 2011 Free Software Foundation, Inc. ++ Copyright (C) 2003-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,52 +17,50 @@ + . */ + + #include +-#include +-#include + + /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]); + Returns 'dst'. + +- Memcpy handles short copies (< 32-bytes) using a binary move blocks +- (no loops) of lwz/stw. The tail (remaining 1-3) bytes is handled +- with the appropriate combination of byte and halfword load/stores. +- There is minimal effort to optimize the alignment of short moves. ++ Memcpy handles short copies (< 32-bytes) using a binary move blocks ++ (no loops) of lwz/stw. The tail (remaining 1-3) bytes is handled ++ with the appropriate combination of byte and halfword load/stores. ++ There is minimal effort to optimize the alignment of short moves. + The 64-bit implementations of POWER3 and POWER4 do a reasonable job +- of handling unligned load/stores that do not cross 32-byte boundries. ++ of handling unaligned load/stores that do not cross 32-byte boundaries. + + Longer moves (>= 32-bytes) justify the effort to get at least the + destination doubleword (8-byte) aligned. Further optimization is +- posible when both source and destination are doubleword aligned. +- Each case has a optimized unrolled loop. +- +- For POWER6 unaligned loads will take a 20+ cycle hicup for any ++ possible when both source and destination are doubleword aligned. ++ Each case has a optimized unrolled loop. ++ ++ For POWER6 unaligned loads will take a 20+ cycle hiccup for any + L1 cache miss that crosses a 32- or 128-byte boundary. Store +- is more forgiving and does not take a hicup until page or +- segment boundaries. So we require doubleword alignment for ++ is more forgiving and does not take a hiccup until page or ++ segment boundaries. So we require doubleword alignment for + the source but may take a risk and only require word alignment + for the destination. */ + + .machine "power6" +-EALIGN (BP_SYM (memcpy), 7, 0) ++EALIGN (memcpy, 7, 0) + CALL_MCOUNT 3 + + cmpldi cr1,5,31 + neg 0,3 + std 3,-16(1) + std 31,-8(1) +- andi. 11,3,7 /* check alignement of dst. */ ++ andi. 11,3,7 /* check alignment of dst. */ + clrldi 0,0,61 /* Number of bytes until the 1st doubleword of dst. */ +- clrldi 10,4,61 /* check alignement of src. */ ++ clrldi 10,4,61 /* check alignment of src. */ + cmpldi cr6,5,8 + ble- cr1,.L2 /* If move < 32 bytes use short move code. */ + mtcrf 0x01,0 +- cmpld cr6,10,11 ++ cmpld cr6,10,11 + srdi 9,5,3 /* Number of full double words remaining. */ + beq .L0 +- ++ + subf 5,0,5 +- /* Move 0-7 bytes as needed to get the destination doubleword alligned. +- Duplicate some code to maximize fall-throught and minimize agen delays. */ ++ /* Move 0-7 bytes as needed to get the destination doubleword aligned. ++ Duplicate some code to maximize fall-through and minimize agen delays. */ + 1: bf 31,2f + lbz 6,0(4) + stb 6,0(3) +@@ -78,7 +76,7 @@ + lwz 6,1(4) + stw 6,1(3) + b 0f +- ++ + 2: bf 30,4f + lhz 6,0(4) + sth 6,0(3) +@@ -86,26 +84,26 @@ + lwz 6,2(4) + stw 6,2(3) + b 0f +- ++ + 4: bf 29,0f + lwz 6,0(4) + stw 6,0(3) +-0: ++0: + /* Add the number of bytes until the 1st doubleword of dst to src and dst. */ + add 4,4,0 + add 3,3,0 +- +- clrldi 10,4,61 /* check alignement of src again. */ ++ ++ clrldi 10,4,61 /* check alignment of src again. */ + srdi 9,5,3 /* Number of full double words remaining. */ +- +- /* Copy doublewords from source to destination, assumpting the ++ ++ /* Copy doublewords from source to destination, assuming the + destination is aligned on a doubleword boundary. + + At this point we know there are at least 25 bytes left (32-7) to copy. +- The next step is to determine if the source is also doubleword aligned. ++ The next step is to determine if the source is also doubleword aligned. + If not branch to the unaligned move code at .L6. which uses + a load, shift, store strategy. +- ++ + Otherwise source and destination are doubleword aligned, and we can + the optimized doubleword copy loop. */ + .align 4 +@@ -123,14 +121,14 @@ + the main loop exits there may be a tail of 1-7 bytes. These byte + are copied a word/halfword/byte at a time as needed to preserve + alignment. +- ++ + For POWER6 the L1 is store-through and the L2 is store-in. The + L2 is clocked at half CPU clock so we can store 16 bytes every + other cycle. POWER6 also has a load/store bypass so we can do +- load, load, store, store every 2 cycles. +- ++ load, load, store, store every 2 cycles. ++ + The following code is sensitive to cache line alignment. Do not +- make any change with out first making sure thay don't result in ++ make any change with out first making sure they don't result in + splitting ld/std pairs across a cache line. */ + + mtcrf 0x02,5 +@@ -273,7 +271,7 @@ + std 8,16+96(10) + std 0,24+96(10) + ble cr5,L(das_loop_e) +- ++ + mtctr 12 + .align 4 + L(das_loop2): +@@ -326,10 +324,10 @@ + .align 4 + L(das_tail): + beq cr1,0f +- ++ + L(das_tail2): + /* At this point we have a tail of 0-7 bytes and we know that the +- destiniation is double word aligned. */ ++ destination is double word aligned. */ + 4: bf 29,2f + lwz 6,0(4) + stw 6,0(3) +@@ -344,7 +342,7 @@ + lbz 6,4(4) + stb 6,4(3) + b 0f +- ++ + 2: bf 30,1f + lhz 6,0(4) + sth 6,0(3) +@@ -352,7 +350,7 @@ + lbz 6,2(4) + stb 6,2(3) + b 0f +- ++ + 1: bf 31,0f + lbz 6,0(4) + stb 6,0(3) +@@ -361,7 +359,7 @@ + ld 3,-16(1) + blr + +-/* Copy up to 31 bytes. This divided into two cases 0-8 bytes and 9-31 ++/* Copy up to 31 bytes. This divided into two cases 0-8 bytes and 9-31 + bytes. Each case is handled without loops, using binary (1,2,4,8) + tests. + +@@ -402,15 +400,28 @@ + blt cr6,5f + srdi 7,6,16 + bgt cr6,3f ++#ifdef __LITTLE_ENDIAN__ ++ sth 7,0(3) ++#else + sth 6,0(3) ++#endif + b 7f + .align 4 + 3: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,24 ++ stb 6,0(3) ++ sth 7,1(3) ++#else + stb 7,0(3) + sth 6,1(3) ++#endif + b 7f + .align 4 + 5: ++#ifdef __LITTLE_ENDIAN__ ++ rotlwi 6,6,8 ++#endif + stb 6,0(3) + 7: + cmpldi cr1,10,16 +@@ -421,7 +432,7 @@ + /* At least 6 bytes left and the source is word aligned. This allows + some speculative loads up front. */ + /* We need to special case the fall-through because the biggest delays +- are due to address computation not being ready in time for the ++ are due to address computation not being ready in time for the + AGEN. */ + lwz 6,0(12) + lwz 7,4(12) +@@ -452,7 +463,7 @@ + ld 3,-16(1) + blr + .align 4 +-L(dus_tail16p8): /* less then 8 bytes left. */ ++L(dus_tail16p8): /* less than 8 bytes left. */ + beq cr1,L(dus_tailX) /* exactly 16 bytes, early exit. */ + cmpldi cr1,10,20 + bf 29,L(dus_tail16p2) +@@ -466,7 +477,7 @@ + ld 3,-16(1) + blr + .align 4 +-L(dus_tail16p4): /* less then 4 bytes left. */ ++L(dus_tail16p4): /* less than 4 bytes left. */ + addi 12,12,24 + addi 3,3,24 + bgt cr0,L(dus_tail2) +@@ -474,7 +485,7 @@ + ld 3,-16(1) + blr + .align 4 +-L(dus_tail16p2): /* 16 bytes moved, less then 4 bytes left. */ ++L(dus_tail16p2): /* 16 bytes moved, less than 4 bytes left. */ + addi 12,12,16 + addi 3,3,16 + b L(dus_tail2) +@@ -499,7 +510,7 @@ + ld 3,-16(1) + blr + .align 4 +-L(dus_tail8p4): /* less then 4 bytes left. */ ++L(dus_tail8p4): /* less than 4 bytes left. */ + addi 12,12,8 + addi 3,3,8 + bgt cr1,L(dus_tail2) +@@ -510,14 +521,14 @@ + .align 4 + L(dus_tail4): /* Move 4 bytes. */ + /* r6 already loaded speculatively. If we are here we know there is +- more then 4 bytes left. So there is no need to test. */ ++ more than 4 bytes left. So there is no need to test. */ + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 + L(dus_tail2): /* Move 2-3 bytes. */ + bf 30,L(dus_tail1) + lhz 6,0(12) +- sth 6,0(3) ++ sth 6,0(3) + bf 31,L(dus_tailX) + lbz 7,2(12) + stb 7,2(3) +@@ -537,7 +548,7 @@ + .LE8: + mr 12,4 + bne cr6,L(dus_4) +-/* Exactly 8 bytes. We may cross a 32-/128-byte boundry and take a ~20 ++/* Exactly 8 bytes. We may cross a 32-/128-byte boundary and take a ~20 + cycle delay. This case should be rare and any attempt to avoid this + would take most of 20 cycles any way. */ + ld 6,0(4) +@@ -552,7 +563,7 @@ + stw 6,0(3) + bf 30,L(dus_5) + lhz 7,4(4) +- sth 7,4(3) ++ sth 7,4(3) + bf 31,L(dus_0) + lbz 8,6(4) + stb 8,6(3) +@@ -590,20 +601,31 @@ + bge cr0, L(du4_do) + blt cr5, L(du1_do) + beq cr5, L(du2_do) +- b L(du3_do) +- ++ b L(du3_do) ++ + .align 4 + L(du1_do): + bf 30,L(du1_1dw) + + /* there are at least two DWs to copy */ ++ /* FIXME: can combine last shift and "or" into "rldimi" */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 8 ++ sldi 8,7, 64-8 ++#else + sldi 0,6, 8 + srdi 8,7, 64-8 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 8 ++ sldi 8,6, 64-8 ++#else + sldi 0,7, 8 + srdi 8,6, 64-8 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -612,8 +634,13 @@ + blt cr6,L(du1_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du1_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 8 ++ sldi 8,7, 64-8 ++#else + sldi 0,6, 8 + srdi 8,7, 64-8 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -624,8 +651,13 @@ + b L(du1_loop) + .align 4 + L(du1_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 8 ++ sldi 8,7, 64-8 ++#else + sldi 0,6, 8 + srdi 8,7, 64-8 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du1_loop) +@@ -637,23 +669,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du1_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 8 ++ sldi 8,7, 64-8 ++#else + sldi 0,6, 8 + srdi 8,7, 64-8 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 8 ++ sldi 8,6, 64-8 ++#else + sldi 0,7, 8 + srdi 8,6, 64-8 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 8 ++ sldi 8,7, 64-8 ++#else + sldi 0,6, 8 + srdi 8,7, 64-8 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 8 ++ sldi 8,6, 64-8 ++#else + sldi 0,7, 8 + srdi 8,6, 64-8 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -663,9 +715,14 @@ + .align 4 + L(du1_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 8 ++ sldi 8,7, 64-8 ++#else + sldi 0,6, 8 + srdi 8,7, 64-8 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) + +@@ -674,13 +731,23 @@ + bf 30,L(du2_1dw) + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 16 ++ sldi 8,7, 64-16 ++#else + sldi 0,6, 16 + srdi 8,7, 64-16 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 16 ++ sldi 8,6, 64-16 ++#else + sldi 0,7, 16 + srdi 8,6, 64-16 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -689,8 +756,13 @@ + blt cr6,L(du2_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du2_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 16 ++ sldi 8,7, 64-16 ++#else + sldi 0,6, 16 + srdi 8,7, 64-16 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -701,8 +773,13 @@ + b L(du2_loop) + .align 4 + L(du2_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 16 ++ sldi 8,7, 64-16 ++#else + sldi 0,6, 16 + srdi 8,7, 64-16 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du2_loop) +@@ -714,23 +791,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du2_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 16 ++ sldi 8,7, 64-16 ++#else + sldi 0,6, 16 + srdi 8,7, 64-16 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 16 ++ sldi 8,6, 64-16 ++#else + sldi 0,7, 16 + srdi 8,6, 64-16 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 16 ++ sldi 8,7, 64-16 ++#else + sldi 0,6, 16 + srdi 8,7, 64-16 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 16 ++ sldi 8,6, 64-16 ++#else + sldi 0,7, 16 + srdi 8,6, 64-16 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -740,9 +837,14 @@ + .align 4 + L(du2_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 16 ++ sldi 8,7, 64-16 ++#else + sldi 0,6, 16 + srdi 8,7, 64-16 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) + +@@ -751,13 +853,23 @@ + bf 30,L(du3_1dw) + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 24 ++ sldi 8,7, 64-24 ++#else + sldi 0,6, 24 + srdi 8,7, 64-24 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 24 ++ sldi 8,6, 64-24 ++#else + sldi 0,7, 24 + srdi 8,6, 64-24 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -766,8 +878,13 @@ + blt cr6,L(du3_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du3_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 24 ++ sldi 8,7, 64-24 ++#else + sldi 0,6, 24 + srdi 8,7, 64-24 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -778,8 +895,13 @@ + b L(du3_loop) + .align 4 + L(du3_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 24 ++ sldi 8,7, 64-24 ++#else + sldi 0,6, 24 + srdi 8,7, 64-24 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du3_loop) +@@ -791,23 +913,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du3_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 24 ++ sldi 8,7, 64-24 ++#else + sldi 0,6, 24 + srdi 8,7, 64-24 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 24 ++ sldi 8,6, 64-24 ++#else + sldi 0,7, 24 + srdi 8,6, 64-24 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 24 ++ sldi 8,7, 64-24 ++#else + sldi 0,6, 24 + srdi 8,7, 64-24 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 24 ++ sldi 8,6, 64-24 ++#else + sldi 0,7, 24 + srdi 8,6, 64-24 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -817,9 +959,14 @@ + .align 4 + L(du3_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 24 ++ sldi 8,7, 64-24 ++#else + sldi 0,6, 24 + srdi 8,7, 64-24 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) + +@@ -834,13 +981,23 @@ + bf 30,L(du4_1dw) + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 32 ++ sldi 8,7, 64-32 ++#else + sldi 0,6, 32 + srdi 8,7, 64-32 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 32 ++ sldi 8,6, 64-32 ++#else + sldi 0,7, 32 + srdi 8,6, 64-32 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -849,8 +1006,13 @@ + blt cr6,L(du4_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du4_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 32 ++ sldi 8,7, 64-32 ++#else + sldi 0,6, 32 + srdi 8,7, 64-32 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -861,8 +1023,13 @@ + b L(du4_loop) + .align 4 + L(du4_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 32 ++ sldi 8,7, 64-32 ++#else + sldi 0,6, 32 + srdi 8,7, 64-32 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du4_loop) +@@ -874,23 +1041,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du4_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 32 ++ sldi 8,7, 64-32 ++#else + sldi 0,6, 32 + srdi 8,7, 64-32 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 32 ++ sldi 8,6, 64-32 ++#else + sldi 0,7, 32 + srdi 8,6, 64-32 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 32 ++ sldi 8,7, 64-32 ++#else + sldi 0,6, 32 + srdi 8,7, 64-32 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 32 ++ sldi 8,6, 64-32 ++#else + sldi 0,7, 32 + srdi 8,6, 64-32 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -900,9 +1087,14 @@ + .align 4 + L(du4_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 32 ++ sldi 8,7, 64-32 ++#else + sldi 0,6, 32 + srdi 8,7, 64-32 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) + +@@ -911,13 +1103,23 @@ + bf 30,L(du5_1dw) + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 40 ++ sldi 8,7, 64-40 ++#else + sldi 0,6, 40 + srdi 8,7, 64-40 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 40 ++ sldi 8,6, 64-40 ++#else + sldi 0,7, 40 + srdi 8,6, 64-40 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -926,8 +1128,13 @@ + blt cr6,L(du5_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du5_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 40 ++ sldi 8,7, 64-40 ++#else + sldi 0,6, 40 + srdi 8,7, 64-40 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -938,8 +1145,13 @@ + b L(du5_loop) + .align 4 + L(du5_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 40 ++ sldi 8,7, 64-40 ++#else + sldi 0,6, 40 + srdi 8,7, 64-40 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du5_loop) +@@ -951,23 +1163,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du5_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 40 ++ sldi 8,7, 64-40 ++#else + sldi 0,6, 40 + srdi 8,7, 64-40 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 40 ++ sldi 8,6, 64-40 ++#else + sldi 0,7, 40 + srdi 8,6, 64-40 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 40 ++ sldi 8,7, 64-40 ++#else + sldi 0,6, 40 + srdi 8,7, 64-40 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 40 ++ sldi 8,6, 64-40 ++#else + sldi 0,7, 40 + srdi 8,6, 64-40 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -977,9 +1209,14 @@ + .align 4 + L(du5_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 40 ++ sldi 8,7, 64-40 ++#else + sldi 0,6, 40 + srdi 8,7, 64-40 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) + +@@ -988,13 +1225,23 @@ + bf 30,L(du6_1dw) + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 48 ++ sldi 8,7, 64-48 ++#else + sldi 0,6, 48 + srdi 8,7, 64-48 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 48 ++ sldi 8,6, 64-48 ++#else + sldi 0,7, 48 + srdi 8,6, 64-48 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -1003,8 +1250,13 @@ + blt cr6,L(du6_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du6_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 48 ++ sldi 8,7, 64-48 ++#else + sldi 0,6, 48 + srdi 8,7, 64-48 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -1015,8 +1267,13 @@ + b L(du6_loop) + .align 4 + L(du6_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 48 ++ sldi 8,7, 64-48 ++#else + sldi 0,6, 48 + srdi 8,7, 64-48 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du6_loop) +@@ -1028,23 +1285,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du6_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 48 ++ sldi 8,7, 64-48 ++#else + sldi 0,6, 48 + srdi 8,7, 64-48 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 48 ++ sldi 8,6, 64-48 ++#else + sldi 0,7, 48 + srdi 8,6, 64-48 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 48 ++ sldi 8,7, 64-48 ++#else + sldi 0,6, 48 + srdi 8,7, 64-48 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 48 ++ sldi 8,6, 64-48 ++#else + sldi 0,7, 48 + srdi 8,6, 64-48 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -1054,9 +1331,14 @@ + .align 4 + L(du6_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 48 ++ sldi 8,7, 64-48 ++#else + sldi 0,6, 48 + srdi 8,7, 64-48 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) + +@@ -1065,13 +1347,23 @@ + bf 30,L(du7_1dw) + + /* there are at least two DWs to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 56 ++ sldi 8,7, 64-56 ++#else + sldi 0,6, 56 + srdi 8,7, 64-56 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 56 ++ sldi 8,6, 64-56 ++#else + sldi 0,7, 56 + srdi 8,6, 64-56 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,8(4) +@@ -1080,8 +1372,13 @@ + blt cr6,L(du7_fini) /* if total DWs = 3, then bypass loop */ + bf 31,L(du7_loop) + /* there is a third DW to copy */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 56 ++ sldi 8,7, 64-56 ++#else + sldi 0,6, 56 + srdi 8,7, 64-56 ++#endif + or 0,0,8 + std 0,0(4) + mr 6,7 +@@ -1092,8 +1389,13 @@ + b L(du7_loop) + .align 4 + L(du7_1dw): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 56 ++ sldi 8,7, 64-56 ++#else + sldi 0,6, 56 + srdi 8,7, 64-56 ++#endif + addi 5,5,16 + or 0,0,8 + bf 31,L(du7_loop) +@@ -1105,23 +1407,43 @@ + .align 4 + /* copy 32 bytes at a time */ + L(du7_loop): ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 56 ++ sldi 8,7, 64-56 ++#else + sldi 0,6, 56 + srdi 8,7, 64-56 ++#endif + or 0,0,8 + ld 6,0(5) + std 0,0(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 56 ++ sldi 8,6, 64-56 ++#else + sldi 0,7, 56 + srdi 8,6, 64-56 ++#endif + or 0,0,8 + ld 7,8(5) + std 0,8(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 56 ++ sldi 8,7, 64-56 ++#else + sldi 0,6, 56 + srdi 8,7, 64-56 ++#endif + or 0,0,8 + ld 6,16(5) + std 0,16(4) ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,7, 56 ++ sldi 8,6, 64-56 ++#else + sldi 0,7, 56 + srdi 8,6, 64-56 ++#endif + or 0,0,8 + ld 7,24(5) + std 0,24(4) +@@ -1131,12 +1453,17 @@ + .align 4 + L(du7_fini): + /* calculate and store the final DW */ ++#ifdef __LITTLE_ENDIAN__ ++ srdi 0,6, 56 ++ sldi 8,7, 64-56 ++#else + sldi 0,6, 56 + srdi 8,7, 64-56 +- or 0,0,8 ++#endif ++ or 0,0,8 + std 0,0(4) + b L(du_done) +- ++ + .align 4 + L(du_done): + rldicr 0,31,0,60 +@@ -1144,9 +1471,9 @@ + beq cr1,0f /* If the tail is 0 bytes we are done! */ + + add 3,3,0 +- add 12,12,0 ++ add 12,12,0 + /* At this point we have a tail of 0-7 bytes and we know that the +- destiniation is double word aligned. */ ++ destination is double word aligned. */ + 4: bf 29,2f + lwz 6,0(12) + addi 12,12,4 +@@ -1165,5 +1492,5 @@ + ld 31,-8(1) + ld 3,-16(1) + blr +-END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS) ++END_GEN_TB (memcpy,TB_TOCLESS) + libc_hidden_builtin_def (memcpy) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memcpy.S 2014-05-29 13:05:40.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memcpy implementation for PowerPC64/POWER7. +- Copyright (C) 2010, 2011 Free Software Foundation, Inc. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. + Contributed by Luis Machado . + This file is part of the GNU C Library. + +@@ -18,425 +18,366 @@ + . */ + + #include +-#include +-#include + + + /* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]); + Returns 'dst'. */ + ++#define dst 11 /* Use r11 so r3 kept unchanged. */ ++#define src 4 ++#define cnt 5 ++ + .machine power7 +-EALIGN (BP_SYM (memcpy), 5, 0) ++EALIGN (memcpy, 5, 0) + CALL_MCOUNT 3 + +- cmpldi cr1,5,31 ++ cmpldi cr1,cnt,31 + neg 0,3 +- std 3,-16(1) +- std 31,-8(1) +- cfi_offset(31,-8) + ble cr1, L(copy_LT_32) /* If move < 32 bytes use short move + code. */ + +- andi. 11,3,7 /* Check alignment of DST. */ +- ++#ifdef __LITTLE_ENDIAN__ ++/* In little-endian mode, power7 takes an alignment trap on any lxvd2x ++ or stxvd2x crossing a 32-byte boundary, so ensure the aligned_copy ++ loop is only used for quadword aligned copies. */ ++ andi. 10,3,15 ++ clrldi 11,4,60 ++#else ++ andi. 10,3,7 /* Check alignment of DST. */ ++ clrldi 11,4,61 /* Check alignment of SRC. */ ++#endif ++ cmpld cr6,10,11 /* SRC and DST alignments match? */ + +- clrldi 10,4,61 /* Check alignment of SRC. */ +- cmpld cr6,10,11 /* SRC and DST alignments match? */ +- mr 12,4 +- mr 31,5 ++ mr dst,3 + bne cr6,L(copy_GE_32_unaligned) ++ beq L(aligned_copy) + +- srdi 9,5,3 /* Number of full quadwords remaining. */ +- +- beq L(copy_GE_32_aligned_cont) +- +- clrldi 0,0,61 +- mtcrf 0x01,0 +- subf 31,0,5 +- +- /* Get the SRC aligned to 8 bytes. */ +- +-1: bf 31,2f +- lbz 6,0(12) +- addi 12,12,1 +- stb 6,0(3) +- addi 3,3,1 +-2: bf 30,4f +- lhz 6,0(12) +- addi 12,12,2 +- sth 6,0(3) +- addi 3,3,2 +-4: bf 29,0f +- lwz 6,0(12) +- addi 12,12,4 +- stw 6,0(3) +- addi 3,3,4 +-0: +- clrldi 10,12,61 /* Check alignment of SRC again. */ +- srdi 9,31,3 /* Number of full doublewords remaining. */ +- +-L(copy_GE_32_aligned_cont): +- +- clrldi 11,31,61 +- mtcrf 0x01,9 +- +- srdi 8,31,5 +- cmpldi cr1,9,4 +- cmpldi cr6,11,0 +- mr 11,12 ++ mtocrf 0x01,0 ++#ifdef __LITTLE_ENDIAN__ ++ clrldi 0,0,60 ++#else ++ clrldi 0,0,61 ++#endif + +- /* Copy 1~3 doublewords so the main loop starts +- at a multiple of 32 bytes. */ +- +- bf 30,1f +- ld 6,0(12) +- ld 7,8(12) +- addi 11,12,16 +- mtctr 8 +- std 6,0(3) +- std 7,8(3) +- addi 10,3,16 +- bf 31,4f +- ld 0,16(12) +- std 0,16(3) +- blt cr1,3f +- addi 11,12,24 +- addi 10,3,24 +- b 4f +- +- .align 4 +-1: /* Copy 1 doubleword and set the counter. */ +- mr 10,3 +- mtctr 8 +- bf 31,4f +- ld 6,0(12) +- addi 11,12,8 +- std 6,0(3) +- addi 10,3,8 ++/* Get the DST and SRC aligned to 8 bytes (16 for little-endian). */ ++1: ++ bf 31,2f ++ lbz 6,0(src) ++ addi src,src,1 ++ stb 6,0(dst) ++ addi dst,dst,1 ++2: ++ bf 30,4f ++ lhz 6,0(src) ++ addi src,src,2 ++ sth 6,0(dst) ++ addi dst,dst,2 ++4: ++ bf 29,8f ++ lwz 6,0(src) ++ addi src,src,4 ++ stw 6,0(dst) ++ addi dst,dst,4 ++8: ++#ifdef __LITTLE_ENDIAN__ ++ bf 28,16f ++ ld 6,0(src) ++ addi src,src,8 ++ std 6,0(dst) ++ addi dst,dst,8 ++16: ++#endif ++ subf cnt,0,cnt + ++/* Main aligned copy loop. Copies 128 bytes at a time. */ + L(aligned_copy): +- /* Main aligned copy loop. Copies up to 128-bytes at a time. */ +- .align 4 +-4: +- /* check for any 32-byte or 64-byte lumps that are outside of a +- nice 128-byte range. R8 contains the number of 32-byte +- lumps, so drop this into the CR, and use the SO/EQ bits to help +- handle the 32- or 64- byte lumps. Then handle the rest with an +- unrolled 128-bytes-at-a-time copy loop. */ +- mtocrf 1,8 +- li 6,16 # 16() index +- li 7,32 # 32() index +- li 8,48 # 48() index +- +-L(aligned_32byte): +- /* if the SO bit (indicating a 32-byte lump) is not set, move along. */ +- bns cr7,L(aligned_64byte) +- lxvd2x 6,0,11 +- lxvd2x 7,11,6 +- addi 11,11,32 +- stxvd2x 6,0,10 +- stxvd2x 7,10,6 +- addi 10,10,32 +- +-L(aligned_64byte): +- /* if the EQ bit (indicating a 64-byte lump) is not set, move along. */ +- bne cr7,L(aligned_128setup) +- lxvd2x 6,0,11 +- lxvd2x 7,11,6 +- lxvd2x 8,11,7 +- lxvd2x 9,11,8 +- addi 11,11,64 +- stxvd2x 6,0,10 +- stxvd2x 7,10,6 +- stxvd2x 8,10,7 +- stxvd2x 9,10,8 +- addi 10,10,64 +- +-L(aligned_128setup): +- /* Set up for the 128-byte at a time copy loop. */ +- srdi 8,31,7 +- cmpdi 8,0 # Any 4x lumps left? +- beq 3f # if not, move along. +- lxvd2x 6,0,11 +- lxvd2x 7,11,6 +- mtctr 8 # otherwise, load the ctr and begin. +- li 8,48 # 48() index ++ li 6,16 ++ li 7,32 ++ li 8,48 ++ mtocrf 0x02,cnt ++ srdi 12,cnt,7 ++ cmpdi 12,0 ++ beq L(aligned_tail) ++ lxvd2x 6,0,src ++ lxvd2x 7,src,6 ++ mtctr 12 + b L(aligned_128loop) + ++ .align 4 + L(aligned_128head): + /* for the 2nd + iteration of this loop. */ +- lxvd2x 6,0,11 +- lxvd2x 7,11,6 ++ lxvd2x 6,0,src ++ lxvd2x 7,src,6 + L(aligned_128loop): +- lxvd2x 8,11,7 +- lxvd2x 9,11,8 +- stxvd2x 6,0,10 +- addi 11,11,64 +- stxvd2x 7,10,6 +- stxvd2x 8,10,7 +- stxvd2x 9,10,8 +- lxvd2x 6,0,11 +- lxvd2x 7,11,6 +- addi 10,10,64 +- lxvd2x 8,11,7 +- lxvd2x 9,11,8 +- addi 11,11,64 +- stxvd2x 6,0,10 +- stxvd2x 7,10,6 +- stxvd2x 8,10,7 +- stxvd2x 9,10,8 +- addi 10,10,64 ++ lxvd2x 8,src,7 ++ lxvd2x 9,src,8 ++ stxvd2x 6,0,dst ++ addi src,src,64 ++ stxvd2x 7,dst,6 ++ stxvd2x 8,dst,7 ++ stxvd2x 9,dst,8 ++ lxvd2x 6,0,src ++ lxvd2x 7,src,6 ++ addi dst,dst,64 ++ lxvd2x 8,src,7 ++ lxvd2x 9,src,8 ++ addi src,src,64 ++ stxvd2x 6,0,dst ++ stxvd2x 7,dst,6 ++ stxvd2x 8,dst,7 ++ stxvd2x 9,dst,8 ++ addi dst,dst,64 + bdnz L(aligned_128head) + +-3: +- /* Check for tail bytes. */ +- rldicr 0,31,0,60 +- mtcrf 0x01,31 +- beq cr6,0f +- +-.L9: +- add 3,3,0 +- add 12,12,0 +- +- /* At this point we have a tail of 0-7 bytes and we know that the +- destination is doubleword-aligned. */ +-4: /* Copy 4 bytes. */ +- bf 29,2f +- +- lwz 6,0(12) +- addi 12,12,4 +- stw 6,0(3) +- addi 3,3,4 +-2: /* Copy 2 bytes. */ +- bf 30,1f +- +- lhz 6,0(12) +- addi 12,12,2 +- sth 6,0(3) +- addi 3,3,2 +-1: /* Copy 1 byte. */ +- bf 31,0f +- +- lbz 6,0(12) +- stb 6,0(3) +-0: /* Return original DST pointer. */ +- ld 31,-8(1) +- ld 3,-16(1) ++L(aligned_tail): ++ mtocrf 0x01,cnt ++ bf 25,32f ++ lxvd2x 6,0,src ++ lxvd2x 7,src,6 ++ lxvd2x 8,src,7 ++ lxvd2x 9,src,8 ++ addi src,src,64 ++ stxvd2x 6,0,dst ++ stxvd2x 7,dst,6 ++ stxvd2x 8,dst,7 ++ stxvd2x 9,dst,8 ++ addi dst,dst,64 ++32: ++ bf 26,16f ++ lxvd2x 6,0,src ++ lxvd2x 7,src,6 ++ addi src,src,32 ++ stxvd2x 6,0,dst ++ stxvd2x 7,dst,6 ++ addi dst,dst,32 ++16: ++ bf 27,8f ++ lxvd2x 6,0,src ++ addi src,src,16 ++ stxvd2x 6,0,dst ++ addi dst,dst,16 ++8: ++ bf 28,4f ++ ld 6,0(src) ++ addi src,src,8 ++ std 6,0(dst) ++ addi dst,dst,8 ++4: /* Copies 4~7 bytes. */ ++ bf 29,L(tail2) ++ lwz 6,0(src) ++ stw 6,0(dst) ++ bf 30,L(tail5) ++ lhz 7,4(src) ++ sth 7,4(dst) ++ bflr 31 ++ lbz 8,6(src) ++ stb 8,6(dst) ++ /* Return original DST pointer. */ + blr + +- /* Handle copies of 0~31 bytes. */ +- .align 4 ++ ++/* Handle copies of 0~31 bytes. */ ++ .align 4 + L(copy_LT_32): +- cmpldi cr6,5,8 +- mr 12,4 +- mtcrf 0x01,5 ++ mr dst,3 ++ cmpldi cr6,cnt,8 ++ mtocrf 0x01,cnt + ble cr6,L(copy_LE_8) + + /* At least 9 bytes to go. */ + neg 8,4 +- clrrdi 11,4,2 +- andi. 0,8,3 +- cmpldi cr1,5,16 +- mr 10,5 ++ andi. 0,8,3 ++ cmpldi cr1,cnt,16 + beq L(copy_LT_32_aligned) + +- /* Force 4-bytes alignment for SRC. */ +- mtocrf 0x01,0 +- subf 10,0,5 +-2: bf 30,1f +- +- lhz 6,0(12) +- addi 12,12,2 +- sth 6,0(3) +- addi 3,3,2 +-1: bf 31,L(end_4bytes_alignment) +- +- lbz 6,0(12) +- addi 12,12,1 +- stb 6,0(3) +- addi 3,3,1 ++ /* Force 4-byte alignment for SRC. */ ++ mtocrf 0x01,0 ++ subf cnt,0,cnt ++2: ++ bf 30,1f ++ lhz 6,0(src) ++ addi src,src,2 ++ sth 6,0(dst) ++ addi dst,dst,2 ++1: ++ bf 31,L(end_4bytes_alignment) ++ lbz 6,0(src) ++ addi src,src,1 ++ stb 6,0(dst) ++ addi dst,dst,1 + +- .align 4 ++ .align 4 + L(end_4bytes_alignment): +- cmpldi cr1,10,16 +- mtcrf 0x01,10 ++ cmpldi cr1,cnt,16 ++ mtocrf 0x01,cnt + + L(copy_LT_32_aligned): + /* At least 6 bytes to go, and SRC is word-aligned. */ + blt cr1,8f + + /* Copy 16 bytes. */ +- lwz 6,0(12) +- lwz 7,4(12) +- stw 6,0(3) +- lwz 8,8(12) +- stw 7,4(3) +- lwz 6,12(12) +- addi 12,12,16 +- stw 8,8(3) +- stw 6,12(3) +- addi 3,3,16 ++ lwz 6,0(src) ++ lwz 7,4(src) ++ stw 6,0(dst) ++ lwz 8,8(src) ++ stw 7,4(dst) ++ lwz 6,12(src) ++ addi src,src,16 ++ stw 8,8(dst) ++ stw 6,12(dst) ++ addi dst,dst,16 + 8: /* Copy 8 bytes. */ +- bf 28,4f ++ bf 28,L(tail4) ++ lwz 6,0(src) ++ lwz 7,4(src) ++ addi src,src,8 ++ stw 6,0(dst) ++ stw 7,4(dst) ++ addi dst,dst,8 ++ ++ .align 4 ++/* Copies 4~7 bytes. */ ++L(tail4): ++ bf 29,L(tail2) ++ lwz 6,0(src) ++ stw 6,0(dst) ++ bf 30,L(tail5) ++ lhz 7,4(src) ++ sth 7,4(dst) ++ bflr 31 ++ lbz 8,6(src) ++ stb 8,6(dst) ++ /* Return original DST pointer. */ ++ blr + +- lwz 6,0(12) +- lwz 7,4(12) +- addi 12,12,8 +- stw 6,0(3) +- stw 7,4(3) +- addi 3,3,8 +-4: /* Copy 4 bytes. */ +- bf 29,2f +- +- lwz 6,0(12) +- addi 12,12,4 +- stw 6,0(3) +- addi 3,3,4 +-2: /* Copy 2-3 bytes. */ ++ .align 4 ++/* Copies 2~3 bytes. */ ++L(tail2): + bf 30,1f +- +- lhz 6,0(12) +- sth 6,0(3) +- bf 31,0f +- lbz 7,2(12) +- stb 7,2(3) +- ld 3,-16(1) ++ lhz 6,0(src) ++ sth 6,0(dst) ++ bflr 31 ++ lbz 7,2(src) ++ stb 7,2(dst) + blr + +- .align 4 +-1: /* Copy 1 byte. */ +- bf 31,0f ++ .align 4 ++L(tail5): ++ bflr 31 ++ lbz 6,4(src) ++ stb 6,4(dst) ++ blr + +- lbz 6,0(12) +- stb 6,0(3) +-0: /* Return original DST pointer. */ +- ld 3,-16(1) ++ .align 4 ++1: ++ bflr 31 ++ lbz 6,0(src) ++ stb 6,0(dst) ++ /* Return original DST pointer. */ + blr + +- /* Handles copies of 0~8 bytes. */ +- .align 4 ++ ++/* Handles copies of 0~8 bytes. */ ++ .align 4 + L(copy_LE_8): +- bne cr6,4f ++ bne cr6,L(tail4) + + /* Though we could've used ld/std here, they are still + slow for unaligned cases. */ + +- lwz 6,0(4) +- lwz 7,4(4) +- stw 6,0(3) +- stw 7,4(3) +- ld 3,-16(1) /* Return original DST pointers. */ ++ lwz 6,0(src) ++ lwz 7,4(src) ++ stw 6,0(dst) ++ stw 7,4(dst) + blr + +- .align 4 +-4: /* Copies 4~7 bytes. */ +- bf 29,2b + +- lwz 6,0(4) +- stw 6,0(3) +- bf 30,5f +- lhz 7,4(4) +- sth 7,4(3) +- bf 31,0f +- lbz 8,6(4) +- stb 8,6(3) +- ld 3,-16(1) +- blr +- +- .align 4 +-5: /* Copy 1 byte. */ +- bf 31,0f +- +- lbz 6,4(4) +- stb 6,4(3) +- +-0: /* Return original DST pointer. */ +- ld 3,-16(1) +- blr +- +- /* Handle copies of 32+ bytes where DST is aligned (to quadword) but +- SRC is not. Use aligned quadword loads from SRC, shifted to realign +- the data, allowing for aligned DST stores. */ +- .align 4 ++/* Handle copies of 32+ bytes where DST is aligned (to quadword) but ++ SRC is not. Use aligned quadword loads from SRC, shifted to realign ++ the data, allowing for aligned DST stores. */ ++ .align 4 + L(copy_GE_32_unaligned): +- clrldi 0,0,60 /* Number of bytes until the 1st +- quadword. */ +- andi. 11,3,15 /* Check alignment of DST (against +- quadwords). */ +- srdi 9,5,4 /* Number of full quadwords remaining. */ ++ clrldi 0,0,60 /* Number of bytes until the 1st dst quadword. */ ++#ifndef __LITTLE_ENDIAN__ ++ andi. 10,3,15 /* Check alignment of DST (against quadwords). */ ++#endif ++ srdi 9,cnt,4 /* Number of full quadwords remaining. */ + + beq L(copy_GE_32_unaligned_cont) + +- /* SRC is not quadword aligned, get it aligned. */ ++ /* DST is not quadword aligned, get it aligned. */ + +- mtcrf 0x01,0 +- subf 31,0,5 ++ mtocrf 0x01,0 ++ subf cnt,0,cnt + + /* Vector instructions work best when proper alignment (16-bytes) + is present. Move 0~15 bytes as needed to get DST quadword-aligned. */ +-1: /* Copy 1 byte. */ ++1: + bf 31,2f +- +- lbz 6,0(12) +- addi 12,12,1 +- stb 6,0(3) +- addi 3,3,1 +-2: /* Copy 2 bytes. */ ++ lbz 6,0(src) ++ addi src,src,1 ++ stb 6,0(dst) ++ addi dst,dst,1 ++2: + bf 30,4f +- +- lhz 6,0(12) +- addi 12,12,2 +- sth 6,0(3) +- addi 3,3,2 +-4: /* Copy 4 bytes. */ ++ lhz 6,0(src) ++ addi src,src,2 ++ sth 6,0(dst) ++ addi dst,dst,2 ++4: + bf 29,8f +- +- lwz 6,0(12) +- addi 12,12,4 +- stw 6,0(3) +- addi 3,3,4 +-8: /* Copy 8 bytes. */ ++ lwz 6,0(src) ++ addi src,src,4 ++ stw 6,0(dst) ++ addi dst,dst,4 ++8: + bf 28,0f +- +- ld 6,0(12) +- addi 12,12,8 +- std 6,0(3) +- addi 3,3,8 ++ ld 6,0(src) ++ addi src,src,8 ++ std 6,0(dst) ++ addi dst,dst,8 + 0: +- clrldi 10,12,60 /* Check alignment of SRC. */ +- srdi 9,31,4 /* Number of full quadwords remaining. */ ++ srdi 9,cnt,4 /* Number of full quadwords remaining. */ + + /* The proper alignment is present, it is OK to copy the bytes now. */ + L(copy_GE_32_unaligned_cont): + + /* Setup two indexes to speed up the indexed vector operations. */ +- clrldi 11,31,60 +- li 6,16 /* Index for 16-bytes offsets. */ ++ clrldi 10,cnt,60 ++ li 6,16 /* Index for 16-bytes offsets. */ + li 7,32 /* Index for 32-bytes offsets. */ +- cmpldi cr1,11,0 +- srdi 8,31,5 /* Setup the loop counter. */ +- mr 10,3 +- mr 11,12 +- mtcrf 0x01,9 +- cmpldi cr6,9,1 +- lvsl 5,0,12 +- lvx 3,0,12 +- bf 31,L(setup_unaligned_loop) +- +- /* Copy another 16 bytes to align to 32-bytes due to the loop . */ +- lvx 4,12,6 +- vperm 6,3,4,5 +- addi 11,12,16 +- addi 10,3,16 +- stvx 6,0,3 ++ cmpldi cr1,10,0 ++ srdi 8,cnt,5 /* Setup the loop counter. */ ++ mtocrf 0x01,9 ++ cmpldi cr6,9,1 ++#ifdef __LITTLE_ENDIAN__ ++ lvsr 5,0,src ++#else ++ lvsl 5,0,src ++#endif ++ lvx 3,0,src ++ li 0,0 ++ bf 31,L(setup_unaligned_loop) ++ ++ /* Copy another 16 bytes to align to 32-bytes due to the loop. */ ++ lvx 4,src,6 ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif ++ addi src,src,16 ++ stvx 6,0,dst ++ addi dst,dst,16 + vor 3,4,4 ++ clrrdi 0,src,60 + + L(setup_unaligned_loop): +- mtctr 8 +- ble cr6,L(end_unaligned_loop) ++ mtctr 8 ++ ble cr6,L(end_unaligned_loop) + + /* Copy 32 bytes at a time using vector instructions. */ +- .align 4 ++ .align 4 + L(unaligned_loop): + + /* Note: vr6/vr10 may contain data that was already copied, +@@ -444,63 +385,56 @@ + some portions again. This is faster than having unaligned + vector instructions though. */ + +- lvx 4,11,6 /* vr4 = r11+16. */ +- vperm 6,3,4,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr6. */ +- lvx 3,11,7 /* vr3 = r11+32. */ +- vperm 10,4,3,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr10. */ +- addi 11,11,32 +- stvx 6,0,10 +- stvx 10,10,6 +- addi 10,10,32 +- ++ lvx 4,src,6 ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif ++ lvx 3,src,7 ++#ifdef __LITTLE_ENDIAN__ ++ vperm 10,3,4,5 ++#else ++ vperm 10,4,3,5 ++#endif ++ addi src,src,32 ++ stvx 6,0,dst ++ stvx 10,dst,6 ++ addi dst,dst,32 + bdnz L(unaligned_loop) + +- .align 4 ++ clrrdi 0,src,60 ++ ++ .align 4 + L(end_unaligned_loop): + + /* Check for tail bytes. */ +- rldicr 0,31,0,59 +- mtcrf 0x01,31 +- beq cr1,0f ++ mtocrf 0x01,cnt ++ beqlr cr1 + +- add 3,3,0 +- add 12,12,0 ++ add src,src,0 + + /* We have 1~15 tail bytes to copy, and DST is quadword aligned. */ +-8: /* Copy 8 bytes. */ ++ /* Copy 8 bytes. */ + bf 28,4f +- +- lwz 6,0(12) +- lwz 7,4(12) +- addi 12,12,8 +- stw 6,0(3) +- stw 7,4(3) +- addi 3,3,8 +-4: /* Copy 4 bytes. */ +- bf 29,2f +- +- lwz 6,0(12) +- addi 12,12,4 +- stw 6,0(3) +- addi 3,3,4 +-2: /* Copy 2~3 bytes. */ +- bf 30,1f +- +- lhz 6,0(12) +- addi 12,12,2 +- sth 6,0(3) +- addi 3,3,2 +-1: /* Copy 1 byte. */ +- bf 31,0f +- +- lbz 6,0(12) +- stb 6,0(3) +-0: /* Return original DST pointer. */ +- ld 31,-8(1) +- ld 3,-16(1) ++ lwz 6,0(src) ++ lwz 7,4(src) ++ addi src,src,8 ++ stw 6,0(dst) ++ stw 7,4(dst) ++ addi dst,dst,8 ++4: /* Copy 4~7 bytes. */ ++ bf 29,L(tail2) ++ lwz 6,0(src) ++ stw 6,0(dst) ++ bf 30,L(tail5) ++ lhz 7,4(src) ++ sth 7,4(dst) ++ bflr 31 ++ lbz 8,6(src) ++ stb 8,6(dst) ++ /* Return original DST pointer. */ + blr + +-END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS) ++END_GEN_TB (memcpy,TB_TOCLESS) + libc_hidden_builtin_def (memcpy) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/mempcpy.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/mempcpy.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/mempcpy.S 2014-05-29 13:04:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/mempcpy.S 2014-05-29 13:04:56.000000000 -0500 +@@ -367,13 +367,21 @@ + mr 11,12 + mtcrf 0x01,9 + cmpldi cr6,9,1 +- lvsl 5,0,12 ++#ifdef __LITTLE_ENDIAN__ ++ lvsr 5,0,12 ++#else ++ lvsl 5,0,12 ++#endif + lvx 3,0,12 + bf 31,L(setup_unaligned_loop) + + /* Copy another 16 bytes to align to 32-bytes due to the loop . */ + lvx 4,12,6 +- vperm 6,3,4,5 ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif + addi 11,12,16 + addi 10,3,16 + stvx 6,0,3 +@@ -393,11 +401,17 @@ + vector instructions though. */ + + lvx 4,11,6 /* vr4 = r11+16. */ +- vperm 6,3,4,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr6. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm 6,4,3,5 ++#else ++ vperm 6,3,4,5 ++#endif + lvx 3,11,7 /* vr3 = r11+32. */ +- vperm 10,4,3,5 /* Merge the correctly-aligned portions +- of vr3/vr4 into vr10. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm 10,3,4,5 ++#else ++ vperm 10,4,3,5 ++#endif + addi 11,11,32 + stvx 6,0,10 + stvx 10,10,6 diff --git a/SOURCES/glibc-ppc64le-32.patch b/SOURCES/glibc-ppc64le-32.patch new file mode 100644 index 00000000..2553a5d0 --- /dev/null +++ b/SOURCES/glibc-ppc64le-32.patch @@ -0,0 +1,272 @@ +# commit 3be87c77d24c4456ccca4034363b6d1814cd0c84 +# Author: Alan Modra +# Date: Sat Aug 17 18:47:59 2013 +0930 +# +# PowerPC LE memset +# http://sourceware.org/ml/libc-alpha/2013-08/msg00104.html +# +# One of the things I noticed when looking at power7 timing is that rlwimi +# is cracked and the two resulting insns have a register dependency. +# That makes it a little slower than the equivalent rldimi. +# +# * sysdeps/powerpc/powerpc64/memset.S: Replace rlwimi with +# insrdi. Formatting. +# * sysdeps/powerpc/powerpc64/power4/memset.S: Likewise. +# * sysdeps/powerpc/powerpc64/power6/memset.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/memset.S: Likewise. +# * sysdeps/powerpc/powerpc32/power4/memset.S: Likewise. +# * sysdeps/powerpc/powerpc32/power6/memset.S: Likewise. +# * sysdeps/powerpc/powerpc32/power7/memset.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -52,7 +52,7 @@ + + /* Align to word boundary. */ + cmplwi cr5, rLEN, 31 +- rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */ ++ insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ + beq+ L(aligned) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 4 +@@ -67,7 +67,7 @@ + /* Handle the case of size < 31. */ + L(aligned): + mtcrf 0x01, rLEN +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x1C +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -50,7 +50,7 @@ + ble- cr1, L(small) + /* Align to word boundary. */ + cmplwi cr5, rLEN, 31 +- rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */ ++ insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ + beq+ L(aligned) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 4 +@@ -66,7 +66,7 @@ + /* Handle the case of size < 31. */ + L(aligned): + mtcrf 0x01, rLEN +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x1C +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -37,8 +37,8 @@ + cfi_offset(31,-8) + + /* Replicate byte to word. */ +- rlwimi 4,4,8,16,23 +- rlwimi 4,4,16,0,15 ++ insrdi 4,4,8,48 ++ insrdi 4,4,16,32 + + ble cr6,L(small) /* If length <= 8, use short copy code. */ + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -73,14 +73,14 @@ + + /* Align to doubleword boundary. */ + cmpldi cr5, rLEN, 31 +- rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */ ++ insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ + beq+ L(aligned2) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 8 + cror 28,30,31 /* Detect odd word aligned. */ + add rMEMP, rMEMP, rALIGN + sub rLEN, rLEN, rALIGN +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + bt 29, L(g4) + /* Process the even word of doubleword. */ + bf+ 31, L(g2) +@@ -102,14 +102,14 @@ + + /* Handle the case of size < 31. */ + L(aligned2): +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + L(aligned): + mtcrf 0x01, rLEN + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x18 + subfic rALIGN, rALIGN, 0x20 +- insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */ ++ insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */ + beq L(caligned) + mtcrf 0x01, rALIGN + add rMEMP, rMEMP, rALIGN +@@ -230,7 +230,7 @@ + /* Memset of 0-31 bytes. */ + .align 5 + L(medium): +- insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */ ++ insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */ + cmpldi cr1, rLEN, 16 + L(medium_tail2): + add rMEMP, rMEMP, rLEN +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -68,14 +68,14 @@ + + /* Align to doubleword boundary. */ + cmpldi cr5, rLEN, 31 +- rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */ ++ insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ + beq+ L(aligned2) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 8 + cror 28,30,31 /* Detect odd word aligned. */ + add rMEMP, rMEMP, rALIGN + sub rLEN, rLEN, rALIGN +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + bt 29, L(g4) + /* Process the even word of doubleword. */ + bf+ 31, L(g2) +@@ -97,14 +97,14 @@ + + /* Handle the case of size < 31. */ + L(aligned2): +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + L(aligned): + mtcrf 0x01, rLEN + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x18 + subfic rALIGN, rALIGN, 0x20 +- insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */ ++ insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */ + beq L(caligned) + mtcrf 0x01, rALIGN + add rMEMP, rMEMP, rALIGN +@@ -164,24 +164,24 @@ + L(getCacheAligned): + cmpldi cr1,rLEN,32 + andi. rTMP,rMEMP,127 +- blt cr1,L(handletail32) +- beq L(cacheAligned) ++ blt cr1,L(handletail32) ++ beq L(cacheAligned) + addi rMEMP,rMEMP,32 + addi rLEN,rLEN,-32 +- std rCHR,-32(rMEMP) +- std rCHR,-24(rMEMP) +- std rCHR,-16(rMEMP) +- std rCHR,-8(rMEMP) +- b L(getCacheAligned) ++ std rCHR,-32(rMEMP) ++ std rCHR,-24(rMEMP) ++ std rCHR,-16(rMEMP) ++ std rCHR,-8(rMEMP) ++ b L(getCacheAligned) + + /* Now we are aligned to the cache line and can use dcbz. */ + L(cacheAligned): + cmpld cr1,rLEN,rCLS +- blt cr1,L(handletail32) ++ blt cr1,L(handletail32) + dcbz 0,rMEMP + subf rLEN,rCLS,rLEN +- add rMEMP,rMEMP,rCLS +- b L(cacheAligned) ++ add rMEMP,rMEMP,rCLS ++ b L(cacheAligned) + + /* We are here because the cache line size was set and was not 32-bytes + and the remainder (rLEN) is less than the actual cache line size. +@@ -218,7 +218,7 @@ + /* Memset of 0-31 bytes. */ + .align 5 + L(medium): +- insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */ ++ insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */ + cmpldi cr1, rLEN, 16 + L(medium_tail2): + add rMEMP, rMEMP, rLEN +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -65,14 +65,14 @@ + + /* Align to doubleword boundary. */ + cmpldi cr5, rLEN, 31 +- rlwimi rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword. */ ++ insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ + beq+ L(aligned2) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 8 + cror 28,30,31 /* Detect odd word aligned. */ + add rMEMP, rMEMP, rALIGN + sub rLEN, rLEN, rALIGN +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + bt 29, L(g4) + /* Process the even word of doubleword. */ + bf+ 31, L(g2) +@@ -94,14 +94,14 @@ + + /* Handle the case of size < 31. */ + L(aligned2): +- rlwimi rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word. */ ++ insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ + L(aligned): + mtcrf 0x01, rLEN + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x18 + subfic rALIGN, rALIGN, 0x20 +- insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */ ++ insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */ + beq L(caligned) + mtcrf 0x01, rALIGN + add rMEMP, rMEMP, rALIGN +@@ -362,7 +362,7 @@ + /* Memset of 0-31 bytes. */ + .align 5 + L(medium): +- insrdi rCHR,rCHR,32,0 /* Replicate word to double word. */ ++ insrdi rCHR, rCHR, 32, 0 /* Replicate word to double word. */ + cmpldi cr1, rLEN, 16 + L(medium_tail2): + add rMEMP, rMEMP, rLEN +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S 2014-05-29 13:07:41.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S 2014-05-29 13:07:46.000000000 -0500 +@@ -34,8 +34,8 @@ + mr 10,3 + + /* Replicate byte to word. */ +- rlwimi 4,4,8,16,23 +- rlwimi 4,4,16,0,15 ++ insrdi 4,4,8,48 ++ insrdi 4,4,16,32 + ble cr6,L(small) /* If length <= 8, use short copy code. */ + + neg 0,3 +@@ -323,7 +323,7 @@ + clrldi 0,0,62 + beq L(medium_aligned) + +- /* Force 4-bytes alignment for SRC. */ ++ /* Force 4-bytes alignment for DST. */ + mtocrf 0x01,0 + subf 5,0,5 + 1: /* Copy 1 byte. */ diff --git a/SOURCES/glibc-ppc64le-33.patch b/SOURCES/glibc-ppc64le-33.patch new file mode 100644 index 00000000..cce1c397 --- /dev/null +++ b/SOURCES/glibc-ppc64le-33.patch @@ -0,0 +1,1255 @@ +# commit 466b03933234017473c12dd1d92bda5e7fe49df7 +# Author: Alan Modra +# Date: Sat Aug 17 18:48:36 2013 +0930 +# +# PowerPC LE memchr and memrchr +# http://sourceware.org/ml/libc-alpha/2013-08/msg00105.html +# +# Like strnlen, memchr and memrchr had a number of defects fixed by this +# patch as well as adding little-endian support. The first one I +# noticed was that the entry to the main loop needlessly checked for +# "are we done yet?" when we know the size is large enough that we can't +# be done. The second defect I noticed was that the main loop count was +# wrong, which in turn meant that the small loop needed to handle an +# extra word. Thirdly, there is nothing to say that the string can't +# wrap around zero, except of course that we'd normally hit a segfault +# on trying to read from address zero. Fixing that simplified a number +# of places: +# +# - /* Are we done already? */ +# - addi r9,r8,8 +# - cmpld r9,r7 +# - bge L(null) +# +# becomes +# +# + cmpld r8,r7 +# + beqlr +# +# However, the exit gets an extra test because I test for being on the +# last word then if so whether the byte offset is less than the end. +# Overall, the change is a win. +# +# Lastly, memrchr used the wrong cache hint. +# +# * sysdeps/powerpc/powerpc64/power7/memchr.S: Replace rlwimi with +# insrdi. Make better use of reg selection to speed exit slightly. +# Schedule entry path a little better. Remove useless "are we done" +# checks on entry to main loop. Handle wrapping around zero address. +# Correct main loop count. Handle single left-over word from main +# loop inline rather than by using loop_small. Remove extra word +# case in loop_small caused by wrong loop count. Add little-endian +# support. +# * sysdeps/powerpc/powerpc32/power7/memchr.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/memrchr.S: Likewise. Use proper +# cache hint. +# * sysdeps/powerpc/powerpc32/power7/memrchr.S: Likewise. +# * sysdeps/powerpc/powerpc64/power7/rawmemchr.S: Add little-endian +# support. Avoid rlwimi. +# * sysdeps/powerpc/powerpc32/power7/rawmemchr.S: Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memchr.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memchr.S 2014-05-29 13:09:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memchr.S 2014-05-29 13:13:37.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memchr implementation for PowerPC32/POWER7 using cmpb insn. +- Copyright (C) 2010-2012 Free Software Foundation, Inc. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. + Contributed by Luis Machado . + This file is part of the GNU C Library. + +@@ -18,116 +18,118 @@ + . */ + + #include +-#include +-#include + + /* int [r3] memchr (char *s [r3], int byte [r4], int size [r5]) */ + .machine power7 +-ENTRY (BP_SYM (__memchr)) ++ENTRY (__memchr) + CALL_MCOUNT + dcbt 0,r3 + clrrwi r8,r3,2 +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrwi r4,r4,8,16 /* Replicate byte to word. */ + add r7,r3,r5 /* Calculate the last acceptable address. */ ++ insrwi r4,r4,16,0 + cmplwi r5,16 ++ li r9, -1 ++ rlwinm r6,r3,3,27,28 /* Calculate padding. */ ++ addi r7,r7,-1 ++#ifdef __LITTLE_ENDIAN__ ++ slw r9,r9,r6 ++#else ++ srw r9,r9,r6 ++#endif + ble L(small_range) + +- cmplw cr7,r3,r7 /* Compare the starting address (r3) with the +- ending address (r7). If (r3 >= r7), the size +- passed in is zero or negative. */ +- ble cr7,L(proceed) +- +- li r7,-1 /* Artificially set our ending address (r7) +- such that we will exit early. */ +-L(proceed): +- rlwinm r6,r3,3,27,28 /* Calculate padding. */ +- cmpli cr6,r6,0 /* cr6 == Do we have padding? */ + lwz r12,0(r8) /* Load word from memory. */ +- cmpb r10,r12,r4 /* Check for BYTE's in WORD1. */ +- beq cr6,L(proceed_no_padding) +- slw r10,r10,r6 +- srw r10,r10,r6 +-L(proceed_no_padding): +- cmplwi cr7,r10,0 /* If r10 == 0, no BYTEs have been found. */ ++ cmpb r3,r12,r4 /* Check for BYTEs in WORD1. */ ++ and r3,r3,r9 ++ clrlwi r5,r7,30 /* Byte count - 1 in last word. */ ++ clrrwi r7,r7,2 /* Address of last word. */ ++ cmplwi cr7,r3,0 /* If r3 == 0, no BYTEs have been found. */ + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,4 +- cmplw cr6,r9,r7 +- bge cr6,L(null) +- + mtcrf 0x01,r8 + /* Are we now aligned to a doubleword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ +- + bt 29,L(loop_setup) + + /* Handle WORD2 of pair. */ + lwzu r12,4(r8) +- cmpb r10,r12,r4 +- cmplwi cr7,r10,0 ++ cmpb r3,r12,r4 ++ cmplwi cr7,r3,0 + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,4 +- cmplw cr6,r9,r7 +- bge cr6,L(null) +- + L(loop_setup): +- sub r5,r7,r9 +- srwi r6,r5,3 /* Number of loop iterations. */ ++ /* The last word we want to read in the loop below is the one ++ containing the last byte of the string, ie. the word at ++ (s + size - 1) & ~3, or r7. The first word read is at ++ r8 + 4, we read 2 * cnt words, so the last word read will ++ be at r8 + 4 + 8 * cnt - 4. Solving for cnt gives ++ cnt = (r7 - r8) / 8 */ ++ sub r6,r7,r8 ++ srwi r6,r6,3 /* Number of loop iterations. */ + mtctr r6 /* Setup the counter. */ +- b L(loop) +- /* Main loop to look for BYTE backwards in the string. Since +- it's a small loop (< 8 instructions), align it to 32-bytes. */ +- .p2align 5 ++ ++ /* Main loop to look for BYTE in the string. Since ++ it's a small loop (8 instructions), align it to 32-bytes. */ ++ .align 5 + L(loop): + /* Load two words, compare and merge in a + single register for speed. This is an attempt + to speed up the byte-checking process for bigger strings. */ + lwz r12,4(r8) + lwzu r11,8(r8) +- cmpb r10,r12,r4 ++ cmpb r3,r12,r4 + cmpb r9,r11,r4 +- or r5,r9,r10 /* Merge everything in one word. */ +- cmplwi cr7,r5,0 ++ or r6,r9,r3 /* Merge everything in one word. */ ++ cmplwi cr7,r6,0 + bne cr7,L(found) + bdnz L(loop) + +- /* We're here because the counter reached 0, and that means we +- didn't have any matches for BYTE in the whole range. */ +- subi r11,r7,4 +- cmplw cr6,r8,r11 +- blt cr6,L(loop_small) +- b L(null) ++ /* We may have one more dword to read. */ ++ cmplw r8,r7 ++ beqlr + ++ lwzu r12,4(r8) ++ cmpb r3,r12,r4 ++ cmplwi cr6,r3,0 ++ bne cr6,L(done) ++ blr ++ ++ .align 4 ++L(found): + /* OK, one (or both) of the words contains BYTE. Check + the first word and decrement the address in case the first + word really contains BYTE. */ +- .align 4 +-L(found): +- cmplwi cr6,r10,0 ++ cmplwi cr6,r3,0 + addi r8,r8,-4 + bne cr6,L(done) + + /* BYTE must be in the second word. Adjust the address +- again and move the result of cmpb to r10 so we can calculate the ++ again and move the result of cmpb to r3 so we can calculate the + pointer. */ + +- mr r10,r9 ++ mr r3,r9 + addi r8,r8,4 + +- /* r10 has the output of the cmpb instruction, that is, it contains ++ /* r3 has the output of the cmpb instruction, that is, it contains + 0xff in the same position as BYTE in the original + word from the string. Use that to calculate the pointer. + We need to make sure BYTE is *before* the end of the range. */ + L(done): +- cntlzw r0,r10 /* Count leading zeroes before the match. */ +- srwi r0,r0,3 /* Convert leading zeroes to bytes. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r3,-1 ++ andc r0,r0,r3 ++ popcntw r0,r0 /* Count trailing zeros. */ ++#else ++ cntlzw r0,r3 /* Count leading zeros before the match. */ ++#endif ++ cmplw r8,r7 /* Are we on the last word? */ ++ srwi r0,r0,3 /* Convert leading/trailing zeros to bytes. */ + add r3,r8,r0 +- cmplw r3,r7 +- bge L(null) ++ cmplw cr7,r0,r5 /* If on the last dword, check byte offset. */ ++ bnelr ++ blelr cr7 ++ li r3,0 + blr + + .align 4 +@@ -139,69 +141,44 @@ + .align 4 + L(small_range): + cmplwi r5,0 +- rlwinm r6,r3,3,27,28 /* Calculate padding. */ +- beq L(null) /* This branch is for the cmplwi r5,0 above */ ++ beq L(null) + lwz r12,0(r8) /* Load word from memory. */ +- cmplwi cr6,r6,0 /* cr6 == Do we have padding? */ +- cmpb r10,r12,r4 /* Check for BYTE in DWORD1. */ +- beq cr6,L(small_no_padding) +- slw r10,r10,r6 +- srw r10,r10,r6 +-L(small_no_padding): +- cmplwi cr7,r10,0 ++ cmpb r3,r12,r4 /* Check for BYTE in DWORD1. */ ++ and r3,r3,r9 ++ cmplwi cr7,r3,0 ++ clrlwi r5,r7,30 /* Byte count - 1 in last word. */ ++ clrrwi r7,r7,2 /* Address of last word. */ ++ cmplw r8,r7 /* Are we done already? */ + bne cr7,L(done) ++ beqlr + +- /* Are we done already? */ +- addi r9,r8,4 +- cmplw r9,r7 +- bge L(null) +- +-L(loop_small): /* loop_small has been unrolled. */ + lwzu r12,4(r8) +- cmpb r10,r12,r4 +- addi r9,r8,4 +- cmplwi cr6,r10,0 +- cmplw r9,r7 ++ cmpb r3,r12,r4 ++ cmplwi cr6,r3,0 ++ cmplw r8,r7 + bne cr6,L(done) +- bge L(null) ++ beqlr + + lwzu r12,4(r8) +- cmpb r10,r12,r4 +- addi r9,r8,4 +- cmplwi cr6,r10,0 +- cmplw r9,r7 ++ cmpb r3,r12,r4 ++ cmplwi cr6,r3,0 ++ cmplw r8,r7 + bne cr6,L(done) +- bge L(null) ++ beqlr + + lwzu r12,4(r8) +- cmpb r10,r12,r4 +- addi r9,r8,4 +- cmplwi cr6,r10,0 +- cmplw r9,r7 ++ cmpb r3,r12,r4 ++ cmplwi cr6,r3,0 ++ cmplw r8,r7 + bne cr6,L(done) +- bge L(null) ++ beqlr + + lwzu r12,4(r8) +- cmpb r10,r12,r4 +- addi r9,r8,4 +- cmplwi cr6,r10,0 +- cmplw r9,r7 ++ cmpb r3,r12,r4 ++ cmplwi cr6,r3,0 + bne cr6,L(done) +- bge L(null) +- +- /* For most cases we will never get here. Under some combinations of +- padding + length there is a leftover word that still needs to be +- checked. */ +- lwzu r12,4(r8) +- cmpb r10,r12,r4 +- addi r9,r8,4 +- cmplwi cr6,r10,0 +- bne cr6,L(done) +- +- /* save a branch and exit directly */ +- li r3,0 + blr + +-END (BP_SYM (__memchr)) +-weak_alias (BP_SYM (__memchr), BP_SYM(memchr)) ++END (__memchr) ++weak_alias (__memchr, memchr) + libc_hidden_builtin_def (memchr) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memrchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memrchr.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memrchr.S 2014-05-29 13:09:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memrchr.S 2014-05-29 13:13:47.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memrchr implementation for PowerPC32/POWER7 using cmpb insn. +- Copyright (C) 2010 Free Software Foundation, Inc. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. + Contributed by Luis Machado . + This file is part of the GNU C Library. + +@@ -18,124 +18,136 @@ + . */ + + #include +-#include +-#include + + /* int [r3] memrchr (char *s [r3], int byte [r4], int size [r5]) */ + .machine power7 +-ENTRY (BP_SYM (__memrchr)) ++ENTRY (__memrchr) + CALL_MCOUNT +- dcbt 0,r3 +- mr r7,r3 +- add r3,r7,r5 /* Calculate the last acceptable address. */ +- cmplw cr7,r3,r7 /* Is the address equal or less than r3? */ ++ add r7,r3,r5 /* Calculate the last acceptable address. */ ++ neg r0,r7 ++ addi r7,r7,-1 ++ mr r10,r3 ++ clrrwi r6,r7,7 ++ li r9,3<<5 ++ dcbt r9,r6,16 /* Stream hint, decreasing addresses. */ + + /* Replicate BYTE to word. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 +- bge cr7,L(proceed) +- +- li r3,-1 /* Make r11 the biggest if r4 <= 0. */ +-L(proceed): ++ insrwi r4,r4,8,16 ++ insrwi r4,r4,16,0 + li r6,-4 +- addi r9,r3,-1 +- clrrwi r8,r9,2 +- addi r8,r8,4 +- neg r0,r3 ++ li r9,-1 + rlwinm r0,r0,3,27,28 /* Calculate padding. */ +- ++ clrrwi r8,r7,2 ++ srw r9,r9,r0 + cmplwi r5,16 ++ clrrwi r0,r10,2 + ble L(small_range) + +- lwbrx r12,r8,r6 /* Load reversed word from memory. */ +- cmpb r10,r12,r4 /* Check for BYTE in WORD1. */ +- slw r10,r10,r0 +- srw r10,r10,r0 +- cmplwi cr7,r10,0 /* If r10 == 0, no BYTE's have been found. */ ++#ifdef __LITTLE_ENDIAN__ ++ lwzx r12,0,r8 ++#else ++ lwbrx r12,0,r8 /* Load reversed word from memory. */ ++#endif ++ cmpb r3,r12,r4 /* Check for BYTE in WORD1. */ ++ and r3,r3,r9 ++ cmplwi cr7,r3,0 /* If r3 == 0, no BYTEs have been found. */ + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,-4 +- cmplw cr6,r9,r7 +- ble cr6,L(null) +- + mtcrf 0x01,r8 + /* Are we now aligned to a doubleword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ +- mr r8,r9 +- bt 29,L(loop_setup) ++ bf 29,L(loop_setup) + + /* Handle WORD2 of pair. */ ++#ifdef __LITTLE_ENDIAN__ ++ lwzx r12,r8,r6 ++#else + lwbrx r12,r8,r6 +- cmpb r10,r12,r4 +- cmplwi cr7,r10,0 +- bne cr7,L(done) +- +- /* Are we done already? */ ++#endif + addi r8,r8,-4 +- cmplw cr6,r8,r7 +- ble cr6,L(null) ++ cmpb r3,r12,r4 ++ cmplwi cr7,r3,0 ++ bne cr7,L(done) + + L(loop_setup): +- li r0,-8 +- sub r5,r8,r7 +- srwi r9,r5,3 /* Number of loop iterations. */ ++ /* The last word we want to read in the loop below is the one ++ containing the first byte of the string, ie. the word at ++ s & ~3, or r0. The first word read is at r8 - 4, we ++ read 2 * cnt words, so the last word read will be at ++ r8 - 4 - 8 * cnt + 4. Solving for cnt gives ++ cnt = (r8 - r0) / 8 */ ++ sub r5,r8,r0 ++ addi r8,r8,-4 ++ srwi r9,r5,3 /* Number of loop iterations. */ + mtctr r9 /* Setup the counter. */ +- b L(loop) +- /* Main loop to look for BYTE backwards in the string. Since it's a +- small loop (< 8 instructions), align it to 32-bytes. */ +- .p2align 5 ++ ++ /* Main loop to look for BYTE backwards in the string. ++ FIXME: Investigate whether 32 byte align helps with this ++ 9 instruction loop. */ ++ .align 5 + L(loop): + /* Load two words, compare and merge in a + single register for speed. This is an attempt + to speed up the byte-checking process for bigger strings. */ + +- lwbrx r12,r8,r6 +- lwbrx r11,r8,r0 +- addi r8,r8,-4 +- cmpb r10,r12,r4 ++#ifdef __LITTLE_ENDIAN__ ++ lwzx r12,0,r8 ++ lwzx r11,r8,r6 ++#else ++ lwbrx r12,0,r8 ++ lwbrx r11,r8,r6 ++#endif ++ cmpb r3,r12,r4 + cmpb r9,r11,r4 +- or r5,r9,r10 /* Merge everything in one word. */ ++ or r5,r9,r3 /* Merge everything in one word. */ + cmplwi cr7,r5,0 + bne cr7,L(found) +- addi r8,r8,-4 ++ addi r8,r8,-8 + bdnz L(loop) +- /* We're here because the counter reached 0, and that means we +- didn't have any matches for BYTE in the whole range. Just return +- the original range. */ +- addi r9,r8,4 +- cmplw cr6,r9,r7 +- bgt cr6,L(loop_small) +- b L(null) + +- /* OK, one (or both) of the words contains BYTE. Check +- the first word and decrement the address in case the first +- word really contains BYTE. */ ++ /* We may have one more word to read. */ ++ cmplw r8,r0 ++ bnelr ++ ++#ifdef __LITTLE_ENDIAN__ ++ lwzx r12,0,r8 ++#else ++ lwbrx r12,0,r8 ++#endif ++ cmpb r3,r12,r4 ++ cmplwi cr7,r3,0 ++ bne cr7,L(done) ++ blr ++ + .align 4 + L(found): +- cmplwi cr6,r10,0 +- addi r8,r8,4 ++ /* OK, one (or both) of the words contains BYTE. Check ++ the first word. */ ++ cmplwi cr6,r3,0 + bne cr6,L(done) + + /* BYTE must be in the second word. Adjust the address +- again and move the result of cmpb to r10 so we can calculate the ++ again and move the result of cmpb to r3 so we can calculate the + pointer. */ + +- mr r10,r9 ++ mr r3,r9 + addi r8,r8,-4 + +- /* r10 has the output of the cmpb instruction, that is, it contains ++ /* r3 has the output of the cmpb instruction, that is, it contains + 0xff in the same position as BYTE in the original + word from the string. Use that to calculate the pointer. + We need to make sure BYTE is *before* the end of the + range. */ + L(done): +- cntlzw r0,r10 /* Count leading zeroes before the match. */ +- srwi r6,r0,3 /* Convert leading zeroes to bytes. */ +- addi r0,r6,1 ++ cntlzw r9,r3 /* Count leading zeros before the match. */ ++ cmplw r8,r0 /* Are we on the last word? */ ++ srwi r6,r9,3 /* Convert leading zeros to bytes. */ ++ addi r0,r6,-3 + sub r3,r8,r0 +- cmplw r3,r7 +- blt L(null) ++ cmplw cr7,r3,r10 ++ bnelr ++ bgelr cr7 ++ li r3,0 + blr + + .align 4 +@@ -149,29 +161,36 @@ + cmplwi r5,0 + beq L(null) + +- lwbrx r12,r8,r6 /* Load reversed word from memory. */ +- cmpb r10,r12,r4 /* Check for null bytes in WORD1. */ +- slw r10,r10,r0 +- srw r10,r10,r0 +- cmplwi cr7,r10,0 ++#ifdef __LITTLE_ENDIAN__ ++ lwzx r12,0,r8 ++#else ++ lwbrx r12,0,r8 /* Load reversed word from memory. */ ++#endif ++ cmpb r3,r12,r4 /* Check for BYTE in WORD1. */ ++ and r3,r3,r9 ++ cmplwi cr7,r3,0 + bne cr7,L(done) + ++ /* Are we done already? */ ++ cmplw r8,r0 + addi r8,r8,-4 +- cmplw r8,r7 +- ble L(null) +- b L(loop_small) ++ beqlr + +- .p2align 5 ++ .align 5 + L(loop_small): +- lwbrx r12,r8,r6 +- cmpb r10,r12,r4 +- cmplwi cr6,r10,0 +- bne cr6,L(done) ++#ifdef __LITTLE_ENDIAN__ ++ lwzx r12,0,r8 ++#else ++ lwbrx r12,0,r8 ++#endif ++ cmpb r3,r12,r4 ++ cmplw r8,r0 ++ cmplwi cr7,r3,0 ++ bne cr7,L(done) + addi r8,r8,-4 +- cmplw r8,r7 +- ble L(null) +- b L(loop_small) ++ bne L(loop_small) ++ blr + +-END (BP_SYM (__memrchr)) +-weak_alias (BP_SYM (__memrchr), BP_SYM(memrchr)) ++END (__memrchr) ++weak_alias (__memrchr, memrchr) + libc_hidden_builtin_def (memrchr) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/rawmemchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/rawmemchr.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/rawmemchr.S 2014-05-29 13:09:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/rawmemchr.S 2014-05-29 13:09:19.000000000 -0500 +@@ -29,16 +29,21 @@ + clrrwi r8,r3,2 /* Align the address to word boundary. */ + + /* Replicate byte to word. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ rldimi r4,r4,8,48 ++ rldimi r4,r4,16,32 + + /* Now r4 has a word of c bytes. */ + + rlwinm r6,r3,3,27,28 /* Calculate padding. */ + lwz r12,0(r8) /* Load word from memory. */ + cmpb r5,r12,r4 /* Compare each byte against c byte. */ ++#ifdef __LITTLE_ENDIAN__ ++ srw r5,r5,r6 ++ slw r5,r5,r6 ++#else + slw r5,r5,r6 /* Move left to discard ignored bits. */ + srw r5,r5,r6 /* Bring the bits back as zeros. */ ++#endif + cmpwi cr7,r5,0 /* If r5 == 0, no c bytes have been found. */ + bne cr7,L(done) + +@@ -92,8 +97,14 @@ + word from the string. Use that fact to find out what is + the position of the byte inside the string. */ + L(done): ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r5,-1 ++ andc r0,r0,r5 ++ popcntw r0,r0 ++#else + cntlzw r0,r5 /* Count leading zeros before the match. */ +- srwi r0,r0,3 /* Convert leading zeroes to bytes. */ ++#endif ++ srwi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of the matching char. */ + blr + END (BP_SYM (__rawmemchr)) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memchr.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memchr.S 2014-05-29 13:09:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memchr.S 2014-05-29 13:13:57.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memchr implementation for PowerPC64/POWER7 using cmpb insn. +- Copyright (C) 2010-2012 Free Software Foundation, Inc. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. + Contributed by Luis Machado . + This file is part of the GNU C Library. + +@@ -18,118 +18,119 @@ + . */ + + #include +-#include +-#include + + /* int [r3] memchr (char *s [r3], int byte [r4], int size [r5]) */ + .machine power7 +-ENTRY (BP_SYM (__memchr)) +- CALL_MCOUNT 2 ++ENTRY (__memchr) ++ CALL_MCOUNT 3 + dcbt 0,r3 + clrrdi r8,r3,3 +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 + add r7,r3,r5 /* Calculate the last acceptable address. */ ++ insrdi r4,r4,16,32 + cmpldi r5,32 ++ li r9, -1 ++ rlwinm r6,r3,3,26,28 /* Calculate padding. */ + insrdi r4,r4,32,0 ++ addi r7,r7,-1 ++#ifdef __LITTLE_ENDIAN__ ++ sld r9,r9,r6 ++#else ++ srd r9,r9,r6 ++#endif + ble L(small_range) + +- cmpld cr7,r3,r7 /* Compare the starting address (r3) with the +- ending address (r7). If (r3 >= r7), +- the size passed in was zero or negative. */ +- ble cr7,L(proceed) +- +- li r7,-1 /* Artificially set our ending address (r7) +- such that we will exit early. */ +- +-L(proceed): +- rlwinm r6,r3,3,26,28 /* Calculate padding. */ +- cmpldi cr6,r6,0 /* cr6 == Do we have padding? */ + ld r12,0(r8) /* Load doubleword from memory. */ +- cmpb r10,r12,r4 /* Check for BYTEs in DWORD1. */ +- beq cr6,L(proceed_no_padding) +- sld r10,r10,r6 +- srd r10,r10,r6 +-L(proceed_no_padding): +- cmpldi cr7,r10,0 /* Does r10 indicate we got a hit? */ ++ cmpb r3,r12,r4 /* Check for BYTEs in DWORD1. */ ++ and r3,r3,r9 ++ clrldi r5,r7,61 /* Byte count - 1 in last dword. */ ++ clrrdi r7,r7,3 /* Address of last doubleword. */ ++ cmpldi cr7,r3,0 /* Does r3 indicate we got a hit? */ + bne cr7,L(done) + +- /* See if we are at the last acceptable address yet. */ +- addi r9,r8,8 +- cmpld cr6,r9,r7 +- bge cr6,L(null) +- + mtcrf 0x01,r8 + /* Are we now aligned to a quadword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ +- + bt 28,L(loop_setup) + + /* Handle DWORD2 of pair. */ + ldu r12,8(r8) +- cmpb r10,r12,r4 +- cmpldi cr7,r10,0 ++ cmpb r3,r12,r4 ++ cmpldi cr7,r3,0 + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,8 +- cmpld cr6,r9,r7 +- bge cr6,L(null) +- + L(loop_setup): +- sub r5,r7,r9 +- srdi r6,r5,4 /* Number of loop iterations. */ ++ /* The last dword we want to read in the loop below is the one ++ containing the last byte of the string, ie. the dword at ++ (s + size - 1) & ~7, or r7. The first dword read is at ++ r8 + 8, we read 2 * cnt dwords, so the last dword read will ++ be at r8 + 8 + 16 * cnt - 8. Solving for cnt gives ++ cnt = (r7 - r8) / 16 */ ++ sub r6,r7,r8 ++ srdi r6,r6,4 /* Number of loop iterations. */ + mtctr r6 /* Setup the counter. */ +- b L(loop) +- /* Main loop to look for BYTE backwards in the string. Since +- it's a small loop (< 8 instructions), align it to 32-bytes. */ +- .p2align 5 ++ ++ /* Main loop to look for BYTE in the string. Since ++ it's a small loop (8 instructions), align it to 32-bytes. */ ++ .align 5 + L(loop): + /* Load two doublewords, compare and merge in a + single register for speed. This is an attempt + to speed up the byte-checking process for bigger strings. */ + ld r12,8(r8) + ldu r11,16(r8) +- cmpb r10,r12,r4 ++ cmpb r3,r12,r4 + cmpb r9,r11,r4 +- or r5,r9,r10 /* Merge everything in one doubleword. */ +- cmpldi cr7,r5,0 ++ or r6,r9,r3 /* Merge everything in one doubleword. */ ++ cmpldi cr7,r6,0 + bne cr7,L(found) + bdnz L(loop) + +- /* We're here because the counter reached 0, and that means we +- didn't have any matches for BYTE in the whole range. */ +- subi r11,r7,8 +- cmpld cr6,r8,r11 +- blt cr6,L(loop_small) +- b L(null) ++ /* We may have one more dword to read. */ ++ cmpld r8,r7 ++ beqlr + ++ ldu r12,8(r8) ++ cmpb r3,r12,r4 ++ cmpldi cr6,r3,0 ++ bne cr6,L(done) ++ blr ++ ++ .align 4 ++L(found): + /* OK, one (or both) of the doublewords contains BYTE. Check + the first doubleword and decrement the address in case the first + doubleword really contains BYTE. */ +- .align 4 +-L(found): +- cmpldi cr6,r10,0 ++ cmpldi cr6,r3,0 + addi r8,r8,-8 + bne cr6,L(done) + + /* BYTE must be in the second doubleword. Adjust the address +- again and move the result of cmpb to r10 so we can calculate the ++ again and move the result of cmpb to r3 so we can calculate the + pointer. */ + +- mr r10,r9 ++ mr r3,r9 + addi r8,r8,8 + +- /* r10 has the output of the cmpb instruction, that is, it contains ++ /* r3 has the output of the cmpb instruction, that is, it contains + 0xff in the same position as BYTE in the original + doubleword from the string. Use that to calculate the pointer. + We need to make sure BYTE is *before* the end of the range. */ + L(done): +- cntlzd r0,r10 /* Count leading zeroes before the match. */ +- srdi r0,r0,3 /* Convert leading zeroes to bytes. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r3,-1 ++ andc r0,r0,r3 ++ popcntd r0,r0 /* Count trailing zeros. */ ++#else ++ cntlzd r0,r3 /* Count leading zeros before the match. */ ++#endif ++ cmpld r8,r7 /* Are we on the last dword? */ ++ srdi r0,r0,3 /* Convert leading/trailing zeros to bytes. */ + add r3,r8,r0 +- cmpld r3,r7 +- bge L(null) ++ cmpld cr7,r0,r5 /* If on the last dword, check byte offset. */ ++ bnelr ++ blelr cr7 ++ li r3,0 + blr + + .align 4 +@@ -141,67 +142,44 @@ + .align 4 + L(small_range): + cmpldi r5,0 +- rlwinm r6,r3,3,26,28 /* Calculate padding. */ +- beq L(null) /* This branch is for the cmpldi r5,0 above. */ ++ beq L(null) + ld r12,0(r8) /* Load word from memory. */ +- cmpldi cr6,r6,0 /* cr6 == Do we have padding? */ +- cmpb r10,r12,r4 /* Check for BYTE in DWORD1. */ +- /* If no padding, skip the shifts. */ +- beq cr6,L(small_no_padding) +- sld r10,r10,r6 +- srd r10,r10,r6 +-L(small_no_padding): +- cmpldi cr7,r10,0 ++ cmpb r3,r12,r4 /* Check for BYTE in DWORD1. */ ++ and r3,r3,r9 ++ cmpldi cr7,r3,0 ++ clrldi r5,r7,61 /* Byte count - 1 in last dword. */ ++ clrrdi r7,r7,3 /* Address of last doubleword. */ ++ cmpld r8,r7 /* Are we done already? */ + bne cr7,L(done) +- +- /* Are we done already? */ +- addi r9,r8,8 +- cmpld r9,r7 +- bge L(null) +- /* If we're not done, drop through into loop_small. */ +- +-L(loop_small): /* loop_small has been unrolled. */ +- ldu r12,8(r8) +- cmpb r10,r12,r4 +- addi r9,r8,8 +- cmpldi cr6,r10,0 +- cmpld r9,r7 +- bne cr6,L(done) /* Found something. */ +- bge L(null) /* Hit end of string (length). */ ++ beqlr + + ldu r12,8(r8) +- cmpb r10,r12,r4 +- addi r9,r8,8 +- cmpldi cr6,r10,0 +- cmpld r9,r7 ++ cmpb r3,r12,r4 ++ cmpldi cr6,r3,0 ++ cmpld r8,r7 + bne cr6,L(done) /* Found something. */ +- bge L(null) ++ beqlr /* Hit end of string (length). */ + + ldu r12,8(r8) +- subi r11,r7,8 +- cmpb r10,r12,r4 +- cmpldi cr6,r10,0 +- ori r2,r2,0 /* Force a dispatch group. */ ++ cmpb r3,r12,r4 ++ cmpldi cr6,r3,0 ++ cmpld r8,r7 + bne cr6,L(done) ++ beqlr + +- cmpld r8,r11 /* At end of range? */ +- bge L(null) +- +- /* For most cases we will never get here. Under some combinations of +- padding + length there is a leftover double that still needs to be +- checked. */ +- ldu r12,8(r8) +- cmpb r10,r12,r4 +- addi r9,r8,8 +- cmpldi cr6,r10,0 +- cmpld r9,r7 +- bne cr6,L(done) /* Found something. */ ++ ldu r12,8(r8) ++ cmpb r3,r12,r4 ++ cmpldi cr6,r3,0 ++ cmpld r8,r7 ++ bne cr6,L(done) ++ beqlr + +- /* Save a branch and exit directly. */ +- li r3,0 ++ ldu r12,8(r8) ++ cmpb r3,r12,r4 ++ cmpldi cr6,r3,0 ++ bne cr6,L(done) + blr + +- +-END (BP_SYM (__memchr)) +-weak_alias (BP_SYM (__memchr), BP_SYM(memchr)) ++END (__memchr) ++weak_alias (__memchr, memchr) + libc_hidden_builtin_def (memchr) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memrchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memrchr.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memrchr.S 2014-05-29 13:09:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memrchr.S 2014-05-29 13:14:06.000000000 -0500 +@@ -1,5 +1,5 @@ + /* Optimized memrchr implementation for PowerPC64/POWER7 using cmpb insn. +- Copyright (C) 2010 Free Software Foundation, Inc. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. + Contributed by Luis Machado . + This file is part of the GNU C Library. + +@@ -18,125 +18,137 @@ + . */ + + #include +-#include +-#include + + /* int [r3] memrchr (char *s [r3], int byte [r4], int size [r5]) */ + .machine power7 +-ENTRY (BP_SYM (__memrchr)) +- CALL_MCOUNT +- dcbt 0,r3 +- mr r7,r3 +- add r3,r7,r5 /* Calculate the last acceptable address. */ +- cmpld cr7,r3,r7 /* Is the address equal or less than r3? */ ++ENTRY (__memrchr) ++ CALL_MCOUNT 3 ++ add r7,r3,r5 /* Calculate the last acceptable address. */ ++ neg r0,r7 ++ addi r7,r7,-1 ++ mr r10,r3 ++ clrrdi r6,r7,7 ++ li r9,3<<5 ++ dcbt r9,r6,8 /* Stream hint, decreasing addresses. */ + + /* Replicate BYTE to doubleword. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 + insrdi r4,r4,32,0 +- bge cr7,L(proceed) +- +- li r3,-1 /* Make r11 the biggest if r4 <= 0. */ +-L(proceed): + li r6,-8 +- addi r9,r3,-1 +- clrrdi r8,r9,3 +- addi r8,r8,8 +- neg r0,r3 ++ li r9,-1 + rlwinm r0,r0,3,26,28 /* Calculate padding. */ +- ++ clrrdi r8,r7,3 ++ srd r9,r9,r0 + cmpldi r5,32 ++ clrrdi r0,r10,3 + ble L(small_range) + +- ldbrx r12,r8,r6 /* Load reversed doubleword from memory. */ +- cmpb r10,r12,r4 /* Check for BYTE in DWORD1. */ +- sld r10,r10,r0 +- srd r10,r10,r0 +- cmpldi cr7,r10,0 /* If r10 == 0, no BYTE's have been found. */ ++#ifdef __LITTLE_ENDIAN__ ++ ldx r12,0,r8 ++#else ++ ldbrx r12,0,r8 /* Load reversed doubleword from memory. */ ++#endif ++ cmpb r3,r12,r4 /* Check for BYTE in DWORD1. */ ++ and r3,r3,r9 ++ cmpldi cr7,r3,0 /* If r3 == 0, no BYTEs have been found. */ + bne cr7,L(done) + +- /* Are we done already? */ +- addi r9,r8,-8 +- cmpld cr6,r9,r7 +- ble cr6,L(null) +- + mtcrf 0x01,r8 +- /* Are we now aligned to a doubleword boundary? If so, skip to ++ /* Are we now aligned to a quadword boundary? If so, skip to + the main loop. Otherwise, go through the alignment code. */ +- mr r8,r9 +- bt 28,L(loop_setup) ++ bf 28,L(loop_setup) + + /* Handle DWORD2 of pair. */ ++#ifdef __LITTLE_ENDIAN__ ++ ldx r12,r8,r6 ++#else + ldbrx r12,r8,r6 +- cmpb r10,r12,r4 +- cmpldi cr7,r10,0 +- bne cr7,L(done) +- +- /* Are we done already. */ ++#endif + addi r8,r8,-8 +- cmpld cr6,r8,r7 +- ble cr6,L(null) ++ cmpb r3,r12,r4 ++ cmpldi cr7,r3,0 ++ bne cr7,L(done) + + L(loop_setup): +- li r0,-16 +- sub r5,r8,r7 +- srdi r9,r5,4 /* Number of loop iterations. */ ++ /* The last dword we want to read in the loop below is the one ++ containing the first byte of the string, ie. the dword at ++ s & ~7, or r0. The first dword read is at r8 - 8, we ++ read 2 * cnt dwords, so the last dword read will be at ++ r8 - 8 - 16 * cnt + 8. Solving for cnt gives ++ cnt = (r8 - r0) / 16 */ ++ sub r5,r8,r0 ++ addi r8,r8,-8 ++ srdi r9,r5,4 /* Number of loop iterations. */ + mtctr r9 /* Setup the counter. */ +- b L(loop) +- /* Main loop to look for BYTE backwards in the string. Since it's a +- small loop (< 8 instructions), align it to 32-bytes. */ +- .p2align 5 ++ ++ /* Main loop to look for BYTE backwards in the string. ++ FIXME: Investigate whether 32 byte align helps with this ++ 9 instruction loop. */ ++ .align 5 + L(loop): + /* Load two doublewords, compare and merge in a + single register for speed. This is an attempt + to speed up the byte-checking process for bigger strings. */ + +- ldbrx r12,r8,r6 +- ldbrx r11,r8,r0 +- addi r8,r8,-8 +- cmpb r10,r12,r4 ++#ifdef __LITTLE_ENDIAN__ ++ ldx r12,0,r8 ++ ldx r11,r8,r6 ++#else ++ ldbrx r12,0,r8 ++ ldbrx r11,r8,r6 ++#endif ++ cmpb r3,r12,r4 + cmpb r9,r11,r4 +- or r5,r9,r10 /* Merge everything in one doubleword. */ ++ or r5,r9,r3 /* Merge everything in one doubleword. */ + cmpldi cr7,r5,0 + bne cr7,L(found) +- addi r8,r8,-8 ++ addi r8,r8,-16 + bdnz L(loop) +- /* We're here because the counter reached 0, and that means we +- didn't have any matches for BYTE in the whole range. Just return +- the original range. */ +- addi r9,r8,8 +- cmpld cr6,r9,r7 +- bgt cr6,L(loop_small) +- b L(null) +- +- /* OK, one (or both) of the words contains BYTE. Check +- the first word and decrement the address in case the first +- word really contains BYTE. */ ++ ++ /* We may have one more word to read. */ ++ cmpld r8,r0 ++ bnelr ++ ++#ifdef __LITTLE_ENDIAN__ ++ ldx r12,0,r8 ++#else ++ ldbrx r12,0,r8 ++#endif ++ cmpb r3,r12,r4 ++ cmpldi cr7,r3,0 ++ bne cr7,L(done) ++ blr ++ + .align 4 + L(found): +- cmpldi cr6,r10,0 +- addi r8,r8,8 ++ /* OK, one (or both) of the dwords contains BYTE. Check ++ the first dword. */ ++ cmpldi cr6,r3,0 + bne cr6,L(done) + + /* BYTE must be in the second word. Adjust the address +- again and move the result of cmpb to r10 so we can calculate the ++ again and move the result of cmpb to r3 so we can calculate the + pointer. */ + +- mr r10,r9 ++ mr r3,r9 + addi r8,r8,-8 + +- /* r10 has the output of the cmpb instruction, that is, it contains +- 0xff in the same position as the BYTE in the original ++ /* r3 has the output of the cmpb instruction, that is, it contains ++ 0xff in the same position as BYTE in the original + word from the string. Use that to calculate the pointer. + We need to make sure BYTE is *before* the end of the + range. */ + L(done): +- cntlzd r0,r10 /* Count leading zeroes before the match. */ +- srdi r6,r0,3 /* Convert leading zeroes to bytes. */ +- addi r0,r6,1 ++ cntlzd r9,r3 /* Count leading zeros before the match. */ ++ cmpld r8,r0 /* Are we on the last word? */ ++ srdi r6,r9,3 /* Convert leading zeros to bytes. */ ++ addi r0,r6,-7 + sub r3,r8,r0 +- cmpld r3,r7 +- blt L(null) ++ cmpld cr7,r3,r10 ++ bnelr ++ bgelr cr7 ++ li r3,0 + blr + + .align 4 +@@ -150,30 +162,36 @@ + cmpldi r5,0 + beq L(null) + +- ldbrx r12,r8,r6 /* Load reversed doubleword from memory. */ +- cmpb r10,r12,r4 /* Check for BYTE in DWORD1. */ +- sld r10,r10,r0 +- srd r10,r10,r0 +- cmpldi cr7,r10,0 ++#ifdef __LITTLE_ENDIAN__ ++ ldx r12,0,r8 ++#else ++ ldbrx r12,0,r8 /* Load reversed doubleword from memory. */ ++#endif ++ cmpb r3,r12,r4 /* Check for BYTE in DWORD1. */ ++ and r3,r3,r9 ++ cmpldi cr7,r3,0 + bne cr7,L(done) + + /* Are we done already? */ ++ cmpld r8,r0 + addi r8,r8,-8 +- cmpld r8,r7 +- ble L(null) +- b L(loop_small) ++ beqlr + +- .p2align 5 ++ .align 5 + L(loop_small): +- ldbrx r12,r8,r6 +- cmpb r10,r12,r4 +- cmpldi cr6,r10,0 +- bne cr6,L(done) ++#ifdef __LITTLE_ENDIAN__ ++ ldx r12,0,r8 ++#else ++ ldbrx r12,0,r8 ++#endif ++ cmpb r3,r12,r4 ++ cmpld r8,r0 ++ cmpldi cr7,r3,0 ++ bne cr7,L(done) + addi r8,r8,-8 +- cmpld r8,r7 +- ble L(null) +- b L(loop_small) ++ bne L(loop_small) ++ blr + +-END (BP_SYM (__memrchr)) +-weak_alias (BP_SYM (__memrchr), BP_SYM(memrchr)) ++END (__memrchr) ++weak_alias (__memrchr, memrchr) + libc_hidden_builtin_def (memrchr) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/rawmemchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/rawmemchr.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/rawmemchr.S 2014-05-29 13:09:17.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/rawmemchr.S 2014-05-29 13:09:19.000000000 -0500 +@@ -29,8 +29,8 @@ + clrrdi r8,r3,3 /* Align the address to doubleword boundary. */ + + /* Replicate byte to doubleword. */ +- rlwimi r4,r4,8,16,23 +- rlwimi r4,r4,16,0,15 ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 + insrdi r4,r4,32,0 + + /* Now r4 has a doubleword of c bytes. */ +@@ -38,8 +38,13 @@ + rlwinm r6,r3,3,26,28 /* Calculate padding. */ + ld r12,0(r8) /* Load doubleword from memory. */ + cmpb r5,r12,r4 /* Compare each byte against c byte. */ ++#ifdef __LITTLE_ENDIAN__ ++ srd r5,r5,r6 ++ sld r5,r5,r6 ++#else + sld r5,r5,r6 /* Move left to discard ignored bits. */ + srd r5,r5,r6 /* Bring the bits back as zeros. */ ++#endif + cmpdi cr7,r5,0 /* If r5 == 0, no c bytes have been found. */ + bne cr7,L(done) + +@@ -93,8 +98,14 @@ + doubleword from the string. Use that fact to find out what is + the position of the byte inside the string. */ + L(done): ++#ifdef __LITTLE_ENDIAN__ ++ addi r0,r5,-1 ++ andc r0,r0,r5 ++ popcntd r0,r0 /* Count trailing zeros. */ ++#else + cntlzd r0,r5 /* Count leading zeros before the match. */ +- srdi r0,r0,3 /* Convert leading zeroes to bytes. */ ++#endif ++ srdi r0,r0,3 /* Convert leading zeros to bytes. */ + add r3,r8,r0 /* Return address of the matching char. */ + blr + END (BP_SYM (__rawmemchr)) diff --git a/SOURCES/glibc-ppc64le-34.patch b/SOURCES/glibc-ppc64le-34.patch new file mode 100644 index 00000000..9b1bd5ff --- /dev/null +++ b/SOURCES/glibc-ppc64le-34.patch @@ -0,0 +1,68 @@ +# commit 8f9ebb08af1368962d9f24c4cfacb55cf8eee560 +# Author: Alan Modra +# Date: Thu Oct 3 14:03:03 2013 +0930 +# +# PowerPC LE configury +# http://sourceware.org/ml/libc-alpha/2013-08/msg00096.html +# +# This adds the basic configury bits for powerpc64le and powerpcle. +# +# * configure.in: Map powerpc64le and powerpcle to base_machine/machine. +# * configure: Regenerate. +# * nptl/shlib-versions: Powerpc*le starts at 2.18. +# * shlib-versions: Likewise. +# +# commit 0ff8246327401ae8779e2697d5c7348611cdbf8a +# Author: Adhemerval Zanella +# Date: Tue Feb 4 09:49:08 2014 -0200 +# +# PowerPC: Change powerpc64le start ABI to 2.17. +# +diff -urN glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure +--- glibc-2.17-c758a686/configure 2014-05-26 19:52:31.000000000 -0500 ++++ glibc-2.17-c758a686/configure 2014-05-26 19:54:13.000000000 -0500 +@@ -4195,8 +4195,8 @@ + # base_machine, we don't change it. + test -n "$base_machine" || case "$machine" in + i[34567]86) base_machine=i386 machine=i386/$machine ;; +-powerpc) base_machine=powerpc machine=powerpc/powerpc32 ;; +-powerpc64) base_machine=powerpc machine=powerpc/powerpc64 ;; ++powerpc64*) base_machine=powerpc machine=powerpc/powerpc64 ;; ++powerpc*) base_machine=powerpc machine=powerpc/powerpc32 ;; + s390) base_machine=s390 machine=s390/s390-32 ;; + s390x) base_machine=s390 machine=s390/s390-64 ;; + sh3*) base_machine=sh machine=sh/sh3 ;; +diff -urN glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in +--- glibc-2.17-c758a686/configure.in 2014-05-26 19:52:30.000000000 -0500 ++++ glibc-2.17-c758a686/configure.in 2014-05-26 19:54:45.000000000 -0500 +@@ -549,8 +549,8 @@ + # base_machine, we don't change it. + test -n "$base_machine" || case "$machine" in + i[34567]86) base_machine=i386 machine=i386/$machine ;; +-powerpc) base_machine=powerpc machine=powerpc/powerpc32 ;; +-powerpc64) base_machine=powerpc machine=powerpc/powerpc64 ;; ++powerpc64*) base_machine=powerpc machine=powerpc/powerpc64 ;; ++powerpc*) base_machine=powerpc machine=powerpc/powerpc32 ;; + s390) base_machine=s390 machine=s390/s390-32 ;; + s390x) base_machine=s390 machine=s390/s390-64 ;; + sh3*) base_machine=sh machine=sh/sh3 ;; +diff -urN glibc-2.17-c758a686/nptl/shlib-versions glibc-2.17-c758a686/nptl/shlib-versions +--- glibc-2.17-c758a686/nptl/shlib-versions 2014-05-26 19:52:31.000000000 -0500 ++++ glibc-2.17-c758a686/nptl/shlib-versions 2014-05-26 19:53:31.000000000 -0500 +@@ -2,4 +2,5 @@ + sh.*-.*-linux.* libpthread=0 GLIBC_2.2 + s390x-.*-linux.* libpthread=0 GLIBC_2.2 + powerpc64-.*-linux.* libpthread=0 GLIBC_2.3 ++powerpc.*le-.*-linux.* libpthread=0 GLIBC_2.17 + .*-.*-linux.* libpthread=0 +diff -urN glibc-2.17-c758a686/shlib-versions glibc-2.17-c758a686/shlib-versions +--- glibc-2.17-c758a686/shlib-versions 2014-05-26 19:52:31.000000000 -0500 ++++ glibc-2.17-c758a686/shlib-versions 2014-05-26 19:53:31.000000000 -0500 +@@ -23,6 +23,7 @@ + + s390x-.*-linux.* DEFAULT GLIBC_2.2 + powerpc64-.*-linux.* DEFAULT GLIBC_2.3 ++powerpc.*le-.*-linux.* DEFAULT GLIBC_2.17 + .*-.*-gnu-gnu.* DEFAULT GLIBC_2.2.6 + + # Configuration ABI Identifier for ABI data files diff --git a/SOURCES/glibc-ppc64le-35.patch b/SOURCES/glibc-ppc64le-35.patch new file mode 100644 index 00000000..05e4316b --- /dev/null +++ b/SOURCES/glibc-ppc64le-35.patch @@ -0,0 +1,106 @@ +# commit 5162e7dd96efcd9b45c1dc1471a964d45278b1e1 +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:41:52 2013 -0600 +# +# PowerPC64: Fix incorrect CFI in *context routines +# +# The context established by "makecontext" has a link register pointing +# back to an error path within the makecontext routine. This is currently +# covered by the CFI FDE for makecontext itself, which is simply wrong +# for the stack frame *inside* the context. When trying to unwind (e.g. +# doing a backtrace) in a routine inside a context created by makecontext, +# this can lead to uninitialized stack slots being accessed, causing the +# unwinder to crash in the worst case. +# +# Similarly, during parts of the "setcontext" routine, when the stack +# pointer has already been switched to point to the new context, the +# address range is still covered by the CFI FDE for setcontext. When +# trying to unwind in that situation (e.g. backtrace from an async +# signal handler for profiling), it is again possible that the unwinder +# crashes. +# +# Theses are all problems in existing code, but the changes in stack +# frame layout appear to make the "worst case" much more likely in +# the ELFv2 ABI context. This causes regressions e.g. in the libgo +# testsuite on ELFv2. +# +# This patch fixes this by ending the makecontext/setcontext FDEs +# before those problematic parts of the assembler, similar to what +# is already done on other platforms. This fixes the libgo +# regression on ELFv2. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:16:16.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:16:17.000000000 -0500 +@@ -129,6 +129,10 @@ + the cpu link stack used to predict blr return addresses. */ + bcl 20,31,L(gotexitcodeaddr); + ++ /* End FDE now, because while executing on the context's stack ++ the unwind info would be wrong otherwise. */ ++ cfi_endproc ++ + /* This is the helper code which gets called if a function which + is registered with 'makecontext' returns. In this case we + have to install the context listed in the uc_link element of +@@ -157,6 +161,11 @@ + #endif + b L(do_exit) + ++ /* Re-establish FDE for the rest of the actual makecontext routine. */ ++ cfi_startproc ++ cfi_offset (lr, FRAME_LR_SAVE) ++ cfi_adjust_cfa_offset (128) ++ + /* The address of the exit code is in the link register. Store the lr + in the ucontext as LNK so the target function will return to our + exit code. */ +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S 2014-05-29 13:16:16.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S 2014-05-29 13:16:17.000000000 -0500 +@@ -129,6 +129,10 @@ + lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31) + lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31) + ++ /* End FDE now, because the unwind info would be wrong while ++ we're reloading registers to switch to the new context. */ ++ cfi_endproc ++ + ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31) + ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31) + mtlr r0 +@@ -177,6 +181,11 @@ + ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31) + bctr + ++ /* Re-establish FDE for the rest of the actual setcontext routine. */ ++ cfi_startproc ++ cfi_offset (lr, FRAME_LR_SAVE) ++ cfi_adjust_cfa_offset (128) ++ + L(nv_error_exit): + ld r0,128+FRAME_LR_SAVE(r1) + addi r1,r1,128 +@@ -403,6 +412,10 @@ + lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31) + lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31) + ++ /* End FDE now, because the unwind info would be wrong while ++ we're reloading registers to switch to the new context. */ ++ cfi_endproc ++ + ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31) + ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31) + mtlr r0 +@@ -451,6 +464,11 @@ + ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31) + bctr + ++ /* Re-establish FDE for the rest of the actual setcontext routine. */ ++ cfi_startproc ++ cfi_offset (lr, FRAME_LR_SAVE) ++ cfi_adjust_cfa_offset (128) ++ + L(error_exit): + ld r0,128+FRAME_LR_SAVE(r1) + addi r1,r1,128 diff --git a/SOURCES/glibc-ppc64le-36.patch b/SOURCES/glibc-ppc64le-36.patch new file mode 100644 index 00000000..ddd41a2e --- /dev/null +++ b/SOURCES/glibc-ppc64le-36.patch @@ -0,0 +1,105 @@ +# commit 7ec07d9a7b501f1b7d740fda02ba5f39d6d684e5 +# Author: Alan Modra +# Date: Wed Dec 4 06:44:06 2013 -0600 +# +# PowerPC64: Report overflow on @h and @ha relocations +# +# This patch updates glibc in accordance with the binutils patch checked in here: +# https://sourceware.org/ml/binutils/2013-10/msg00372.html +# +# This changes the various R_PPC64_..._HI and _HA relocations to report +# 32-bit overflows. The motivation is that existing uses of @h / @ha +# are to build up 32-bit offsets (for the "medium model" TOC access +# that GCC now defaults to), and we'd really like to see failures at +# link / load time rather than silent truncations. +# +# For those rare cases where a modifier is needed to build up a 64-bit +# constant, new relocations _HIGH / _HIGHA are supported. +# +# The patch also fixes a bug in overflow checking for the R_PPC64_ADDR30 +# and R_PPC64_ADDR32 relocations. +# +diff -urN glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h +--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:17:35.000000000 -0500 ++++ glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:17:35.000000000 -0500 +@@ -2243,6 +2243,17 @@ + #define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ + #define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ + #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ ++#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */ ++#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */ ++#define R_PPC64_TOCSAVE 109 /* none */ ++ ++/* Added when HA and HI relocs were changed to report overflows. */ ++#define R_PPC64_ADDR16_HIGH 110 ++#define R_PPC64_ADDR16_HIGHA 111 ++#define R_PPC64_TPREL16_HIGH 112 ++#define R_PPC64_TPREL16_HIGHA 113 ++#define R_PPC64_DTPREL16_HIGH 114 ++#define R_PPC64_DTPREL16_HIGHA 115 + + /* GNU extension to support local ifunc. */ + #define R_PPC64_JMP_IREL 247 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:17:34.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:17:35.000000000 -0500 +@@ -663,11 +663,25 @@ + + case R_PPC64_TPREL16_HI: + value = elf_machine_tprel (map, sym_map, sym, reloc); ++ if (dont_expect (value + 0x80000000 >= 0x100000000LL)) ++ _dl_reloc_overflow (map, "R_PPC64_TPREL16_HI", reloc_addr, refsym); ++ *(Elf64_Half *) reloc_addr = PPC_HI (value); ++ break; ++ ++ case R_PPC64_TPREL16_HIGH: ++ value = elf_machine_tprel (map, sym_map, sym, reloc); + *(Elf64_Half *) reloc_addr = PPC_HI (value); + break; + + case R_PPC64_TPREL16_HA: + value = elf_machine_tprel (map, sym_map, sym, reloc); ++ if (dont_expect (value + 0x80008000 >= 0x100000000LL)) ++ _dl_reloc_overflow (map, "R_PPC64_TPREL16_HA", reloc_addr, refsym); ++ *(Elf64_Half *) reloc_addr = PPC_HA (value); ++ break; ++ ++ case R_PPC64_TPREL16_HIGHA: ++ value = elf_machine_tprel (map, sym_map, sym, reloc); + *(Elf64_Half *) reloc_addr = PPC_HA (value); + break; + +@@ -703,17 +717,23 @@ + break; + + case R_PPC64_ADDR16_HI: ++ if (dont_expect (value + 0x80000000 >= 0x100000000LL)) ++ _dl_reloc_overflow (map, "R_PPC64_ADDR16_HI", reloc_addr, refsym); ++ case R_PPC64_ADDR16_HIGH: + *(Elf64_Half *) reloc_addr = PPC_HI (value); + break; + + case R_PPC64_ADDR16_HA: ++ if (dont_expect (value + 0x80008000 >= 0x100000000LL)) ++ _dl_reloc_overflow (map, "R_PPC64_ADDR16_HA", reloc_addr, refsym); ++ case R_PPC64_ADDR16_HIGHA: + *(Elf64_Half *) reloc_addr = PPC_HA (value); + break; + + case R_PPC64_ADDR30: + { + Elf64_Addr delta = value - (Elf64_Xword) reloc_addr; +- if (dont_expect ((delta + 0x80000000) >= 0x10000000 ++ if (dont_expect ((delta + 0x80000000) >= 0x100000000LL + || (delta & 3) != 0)) + _dl_reloc_overflow (map, "R_PPC64_ADDR30", reloc_addr, refsym); + BIT_INSERT (*(Elf64_Word *) reloc_addr, delta, 0xfffffffc); +@@ -762,7 +782,7 @@ + return; + + case R_PPC64_ADDR32: +- if (dont_expect ((value + 0x80000000) >= 0x10000000)) ++ if (dont_expect ((value + 0x80000000) >= 0x100000000LL)) + _dl_reloc_overflow (map, "R_PPC64_ADDR32", reloc_addr, refsym); + *(Elf64_Word *) reloc_addr = value; + return; diff --git a/SOURCES/glibc-ppc64le-37.patch b/SOURCES/glibc-ppc64le-37.patch new file mode 100644 index 00000000..0e953631 --- /dev/null +++ b/SOURCES/glibc-ppc64le-37.patch @@ -0,0 +1,31 @@ +# commit b525166bb93b060e1146f0263b76a9c1e7455b06 +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:45:56 2013 -0600 +# +# PowerPC64: Add __private_ss field to TCB header +# +# The TCB header on Intel contains a field __private_ss that is used +# to efficiently implement the -fsplit-stack GCC feature. +# +# In order to prepare for a possible future implementation of that +# feature on powerpc64, we'd like to reserve a similar field in +# the TCB header as well. (It would be good if this went in with +# or before the ELFv2 patches to ensure that this field will be +# available always in the ELFv2 environment.) +# +# The field needs to be added at the front of tcbhead_t structure +# to avoid changing the ABI; see the recent discussion when adding +# the EBB fields. +# +diff -urN glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h +--- glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h 2014-05-29 13:19:25.000000000 -0500 ++++ glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h 2014-05-29 13:19:25.000000000 -0500 +@@ -61,6 +61,8 @@ + are private. */ + typedef struct + { ++ /* GCC split stack support. */ ++ void *__private_ss; + /* Reservation for the Event-Based Branching ABI. */ + uintptr_t ebb_handler; + uintptr_t ebb_ctx_pointer; diff --git a/SOURCES/glibc-ppc64le-38.patch b/SOURCES/glibc-ppc64le-38.patch new file mode 100644 index 00000000..ef1aabe4 --- /dev/null +++ b/SOURCES/glibc-ppc64le-38.patch @@ -0,0 +1,262 @@ +# commit d31beafa8e4ca69faa4cf362784796ef17299341 +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:49:15 2013 -0600 +# +# PowerPC64 ELFv2 ABI 1/6: Code refactoring +# +# This is the first patch to support the new ELFv2 ABI in glibc. +# +# As preparation, this patch simply refactors some of the powerpc64 assembler +# code to move all code related to creating function descriptors (.opd section) +# or using function descriptors (function pointer call) into a central place +# in sysdep.h. +# +# Note that most locations creating .opd entries were already using macros +# in sysdep.h, this patch simply extends this to the remaining places. +# +# No relevant change in generated code expected. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:56:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:56:37.000000000 -0500 +@@ -60,18 +60,8 @@ + .LC0: + .tc PREINIT_FUNCTION[TC], PREINIT_FUNCTION + #endif +- .type BODY_LABEL (_init), @function +- .globl _init +- .section ".opd", "aw" +- .align 3 +-_init: OPD_ENT (_init) +-#ifdef HAVE_ASM_GLOBAL_DOT_NAME +- .globl BODY_LABEL (_init) +- .size _init, 24 +-#else +- .type _init, @function +-#endif + .section ".init", "ax", @progbits ++ ENTRY_2(_init) + .align ALIGNARG (2) + BODY_LABEL (_init): + mflr 0 +@@ -87,18 +77,8 @@ + nop + 1: + +- .type BODY_LABEL (_fini), @function +- .globl _fini +- .section ".opd", "aw" +- .align 3 +-_fini: OPD_ENT (_fini) +-#ifdef HAVE_ASM_GLOBAL_DOT_NAME +- .globl BODY_LABEL (_fini) +- .size _fini, 24 +-#else +- .type _fini, @function +-#endif + .section ".fini", "ax", @progbits ++ ENTRY_2(_fini) + .align ALIGNARG (2) + BODY_LABEL (_fini): + mflr 0 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:56:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:56:37.000000000 -0500 +@@ -122,14 +122,7 @@ + #define RTLD_START \ + asm (".pushsection \".text\"\n" \ + " .align 2\n" \ +-" .type " BODY_PREFIX "_start,@function\n" \ +-" .pushsection \".opd\",\"aw\"\n" \ +-" .align 3\n" \ +-" .globl _start\n" \ + " " ENTRY_2(_start) "\n" \ +-"_start:\n" \ +-" " OPD_ENT(_start) "\n" \ +-" .popsection\n" \ + BODY_PREFIX "_start:\n" \ + /* We start with the following on the stack, from top: \ + argc (4 bytes); \ +@@ -154,11 +147,6 @@ + ".LT__start_name_end:\n" \ + " .align 2\n" \ + " " END_2(_start) "\n" \ +-" .globl _dl_start_user\n" \ +-" .pushsection \".opd\",\"aw\"\n" \ +-"_dl_start_user:\n" \ +-" " OPD_ENT(_dl_start_user) "\n" \ +-" .popsection\n" \ + " .pushsection \".toc\",\"aw\"\n" \ + DL_STARTING_UP_DEF \ + ".LC__rtld_local:\n" \ +@@ -170,7 +158,6 @@ + ".LC__dl_fini:\n" \ + " .tc _dl_fini[TC],_dl_fini\n" \ + " .popsection\n" \ +-" .type " BODY_PREFIX "_dl_start_user,@function\n" \ + " " ENTRY_2(_dl_start_user) "\n" \ + /* Now, we do our main work of calling initialisation procedures. \ + The ELF ABI doesn't say anything about parameters for these, \ +@@ -228,10 +215,7 @@ + /* Now, call the start function descriptor at r30... */ \ + " .globl ._dl_main_dispatch\n" \ + "._dl_main_dispatch:\n" \ +-" ld 0,0(30)\n" \ +-" ld 2,8(30)\n" \ +-" mtctr 0\n" \ +-" ld 11,16(30)\n" \ ++" " PPC64_LOAD_FUNCPTR(30) "\n" \ + " bctr\n" \ + ".LT__dl_start_user:\n" \ + " .long 0\n" \ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 13:56:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 13:56:37.000000000 -0500 +@@ -71,12 +71,8 @@ + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) + mtcrf 0xFF,r0 +-/* Load the target address, toc and static chain reg from the function +- descriptor returned by fixup. */ +- ld r0,0(r3) +- ld r2,8(r3) +- mtctr r0 +- ld r11,16(r3) ++/* Prepare for calling the function returned by fixup. */ ++ PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) + /* Unwind the stack frame, and jump. */ + addi r1,r1,FRAME_SIZE +@@ -322,13 +318,9 @@ + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) + mtcrf 0xFF,r0 +-/* Load the target address, toc and static chain reg from the function +- descriptor returned by fixup. */ +- ld r0,0(r3) +- ld r2,8(r3) +- ld r11,16(r3) ++/* Prepare for calling the function returned by fixup. */ ++ PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) +- mtctr r0 + /* Load the floating point registers. */ + lfd fp1,FPR_PARMS+0(r1) + lfd fp2,FPR_PARMS+8(r1) +@@ -386,14 +378,10 @@ + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) + mtcrf 0xFF,r0 +-/* Load the target address, toc and static chain reg from the function +- descriptor returned by fixup. */ +- ld r0,0(r3) ++/* Prepare for calling the function returned by fixup. */ + std r2,40(r1) +- ld r2,8(r3) +- ld r11,16(r3) ++ PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) +- mtctr r0 + /* Load the floating point registers. */ + lfd fp1,FPR_PARMS+0(r1) + lfd fp2,FPR_PARMS+8(r1) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:56:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:56:37.000000000 -0500 +@@ -74,6 +74,14 @@ + #endif + .endm + ++/* Macro to prepare for calling via a function pointer. */ ++ .macro PPC64_LOAD_FUNCPTR PTR ++ ld r12,0(\PTR) ++ ld r2,8(\PTR) ++ mtctr r12 ++ ld r11,16(\PTR) ++ .endm ++ + #ifdef USE_PPC64_OVERLAPPING_OPD + # define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase + #else +@@ -81,7 +89,6 @@ + #endif + + #define ENTRY_1(name) \ +- .section ".text"; \ + .type BODY_LABEL(name),@function; \ + .globl name; \ + .section ".opd","aw"; \ +@@ -110,6 +117,7 @@ + #endif + + #define ENTRY(name) \ ++ .section ".text"; \ + ENTRY_2(name) \ + .align ALIGNARG(2); \ + BODY_LABEL(name): \ +@@ -127,6 +135,7 @@ + /* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes + past a 2^alignt boundary. */ + #define EALIGN(name, alignt, words) \ ++ .section ".text"; \ + ENTRY_2(name) \ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ +@@ -286,24 +295,42 @@ + + #else /* !__ASSEMBLER__ */ + ++#define PPC64_LOAD_FUNCPTR(ptr) \ ++ "ld 12,0(" #ptr ");\n" \ ++ "ld 2,8(" #ptr ");\n" \ ++ "mtctr 12;\n" \ ++ "ld 11,16(" #ptr ");" ++ + #ifdef USE_PPC64_OVERLAPPING_OPD + # define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase;" + #else + # define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;" + #endif + ++#define ENTRY_1(name) \ ++ ".type " BODY_PREFIX #name ",@function;\n" \ ++ ".globl " #name ";\n" \ ++ ".pushsection \".opd\",\"aw\";\n" \ ++ ".align 3;\n" \ ++#name ":\n" \ ++ OPD_ENT (name) "\n" \ ++ ".popsection;" ++ + #ifdef HAVE_ASM_GLOBAL_DOT_NAME + # define DOT_PREFIX "." + # define BODY_PREFIX "." + # define ENTRY_2(name) \ + ".globl " BODY_PREFIX #name ";\n" \ ++ ENTRY_1(name) "\n" \ + ".size " #name ", 24;" + # define END_2(name) \ + ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";" + #else + # define DOT_PREFIX "" + # define BODY_PREFIX ".LY" +-# define ENTRY_2(name) ".type " #name ",@function;" ++# define ENTRY_2(name) \ ++ ".type " #name ",@function;\n" \ ++ ENTRY_1(name) + # define END_2(name) \ + ".size " #name ",.-" BODY_PREFIX #name ";\n" \ + ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";" +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S 2014-05-29 13:56:35.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S 2014-05-29 13:56:37.000000000 -0500 +@@ -104,9 +104,7 @@ + + std r2,40(r1) + /* Call procedure. */ +- ld r0,0(r30) +- ld r2,8(r30) +- mtctr r0 ++ PPC64_LOAD_FUNCPTR r30 + mr r3,r31 + bctrl + ld r2,40(r1) diff --git a/SOURCES/glibc-ppc64le-39.patch b/SOURCES/glibc-ppc64le-39.patch new file mode 100644 index 00000000..b8f4b436 --- /dev/null +++ b/SOURCES/glibc-ppc64le-39.patch @@ -0,0 +1,508 @@ +# commit 696caf1d002ff059ddd20fd5eaccd76229c14850 +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:51:11 2013 -0600 +# +# PowerPC64 ELFv2 ABI 2/6: Remove function descriptors +# +# This patch adds support for the ELFv2 ABI feature to remove function +# descriptors. See this GCC patch for in-depth discussion: +# http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01141.html +# +# This mostly involves two types of changes: updating assembler source +# files to the new logic, and updating the dynamic loader. +# +# After the refactoring in the previous patch, most of the assembler source +# changes can be handled simply by providing ELFv2 versions of the +# macros in sysdep.h. One somewhat non-obvious change is in __GI__setjmp: +# this used to "fall through" to the immediately following __setjmp ENTRY +# point. This is no longer safe in the ELFv2 since ENTRY defines both +# a global and a local entry point, and you cannot simply fall through +# to a global entry point as it requires r12 to be set up. +# +# Also, makecontext needs to be updated to set up registers according to +# the new ABI for calling into the context's start routine. +# +# The dynamic linker changes mostly consist of removing special code +# to handle function descriptors. We also need to support the new PLT +# and glink format used by the the ELFv2 linker, see: +# https://sourceware.org/ml/binutils/2013-10/msg00376.html +# +# In addition, the dynamic linker now verifies that the dynamic libraries +# it loads match its own ABI. +# +# The hack in VDSO_IFUNC_RET to "synthesize" a function descriptor +# for vDSO routines is also no longer necessary for ELFv2. +# +diff -urN glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h +--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:58:25.000000000 -0500 ++++ glibc-2.17-c758a686/elf/elf.h 2014-05-29 13:58:25.000000000 -0500 +@@ -2263,6 +2263,12 @@ + #define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ + #define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ + ++/* e_flags bits specifying ABI. ++ 1 for original function descriptor using ABI, ++ 2 for revised ABI without function descriptors, ++ 0 for unspecified or not using any features affected by the differences. */ ++#define EF_PPC64_ABI 3 ++ + /* PowerPC64 specific values for the Dyn d_tag field. */ + #define DT_PPC64_GLINK (DT_LOPROC + 0) + #define DT_PPC64_OPD (DT_LOPROC + 1) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:58:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 13:58:25.000000000 -0500 +@@ -64,6 +64,7 @@ + ENTRY_2(_init) + .align ALIGNARG (2) + BODY_LABEL (_init): ++ LOCALENTRY(_init) + mflr 0 + std 0, 16(r1) + stdu r1, -112(r1) +@@ -81,6 +82,7 @@ + ENTRY_2(_fini) + .align ALIGNARG (2) + BODY_LABEL (_fini): ++ LOCALENTRY(_fini) + mflr 0 + std 0, 16(r1) + stdu r1, -112(r1) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h 2014-05-29 13:58:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-irel.h 2014-05-29 13:58:25.000000000 -0500 +@@ -50,7 +50,11 @@ + { + Elf64_Addr *const reloc_addr = (void *) reloc->r_offset; + Elf64_Addr value = elf_ifunc_invoke(reloc->r_addend); ++#if _CALL_ELF != 2 + *(Elf64_FuncDesc *) reloc_addr = *(Elf64_FuncDesc *) value; ++#else ++ *reloc_addr = value; ++#endif + } + else + __libc_fatal ("unexpected reloc type in static binary"); +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 13:58:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:05:46.000000000 -0500 +@@ -31,6 +31,7 @@ + in l_info array. */ + #define DT_PPC64(x) (DT_PPC64_##x - DT_LOPROC + DT_NUM) + ++#if _CALL_ELF != 2 + /* A PowerPC64 function descriptor. The .plt (procedure linkage + table) and .opd (official procedure descriptor) sections are + arrays of these. */ +@@ -40,6 +41,7 @@ + Elf64_Addr fd_toc; + Elf64_Addr fd_aux; + } Elf64_FuncDesc; ++#endif + + #define ELF_MULT_MACHINES_SUPPORTED + +@@ -47,6 +49,18 @@ + static inline int + elf_machine_matches_host (const Elf64_Ehdr *ehdr) + { ++ /* Verify that the binary matches our ABI version. */ ++ if ((ehdr->e_flags & EF_PPC64_ABI) != 0) ++ { ++#if _CALL_ELF != 2 ++ if ((ehdr->e_flags & EF_PPC64_ABI) != 1) ++ return 0; ++#else ++ if ((ehdr->e_flags & EF_PPC64_ABI) != 2) ++ return 0; ++#endif ++ } ++ + return ehdr->e_machine == EM_PPC64; + } + +@@ -124,6 +138,7 @@ + " .align 2\n" \ + " " ENTRY_2(_start) "\n" \ + BODY_PREFIX "_start:\n" \ ++" " LOCALENTRY(_start) "\n" \ + /* We start with the following on the stack, from top: \ + argc (4 bytes); \ + arguments for program (terminated by NULL); \ +@@ -165,6 +180,7 @@ + Changing these is strongly discouraged (not least because argc is \ + passed by value!). */ \ + BODY_PREFIX "_dl_start_user:\n" \ ++" " LOCALENTRY(_dl_start_user) "\n" \ + /* the address of _start in r30. */ \ + " mr 30,3\n" \ + /* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */ \ +@@ -256,8 +272,22 @@ + relocations behave "normally", ie. always use the real address + like PLT relocations. So always set ELF_RTYPE_CLASS_PLT. */ + ++#if _CALL_ELF != 2 + #define elf_machine_type_class(type) \ + (ELF_RTYPE_CLASS_PLT | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) ++#else ++/* And now that you have read that large comment, you can disregard it ++ all for ELFv2. ELFv2 does need the special SHN_UNDEF treatment. */ ++#define IS_PPC64_TLS_RELOC(R) \ ++ (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) \ ++ || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA)) ++ ++#define elf_machine_type_class(type) \ ++ ((((type) == R_PPC64_JMP_SLOT \ ++ || (type) == R_PPC64_ADDR24 \ ++ || IS_PPC64_TLS_RELOC (type)) * ELF_RTYPE_CLASS_PLT) \ ++ | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) ++#endif + + /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ + #define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT +@@ -266,8 +296,19 @@ + #define ELF_MACHINE_NO_REL 1 + + /* Stuff for the PLT. */ ++#if _CALL_ELF != 2 + #define PLT_INITIAL_ENTRY_WORDS 3 ++#define PLT_ENTRY_WORDS 3 + #define GLINK_INITIAL_ENTRY_WORDS 8 ++/* The first 32k entries of glink can set an index and branch using two ++ instructions; past that point, glink uses three instructions. */ ++#define GLINK_ENTRY_WORDS(I) (((I) < 0x8000)? 2 : 3) ++#else ++#define PLT_INITIAL_ENTRY_WORDS 2 ++#define PLT_ENTRY_WORDS 1 ++#define GLINK_INITIAL_ENTRY_WORDS 8 ++#define GLINK_ENTRY_WORDS(I) 1 ++#endif + + #define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory") + #define PPC_DCBT(where) asm volatile ("dcbt 0,%0" : : "r"(where) : "memory") +@@ -312,17 +353,12 @@ + + if (lazy) + { +- /* The function descriptor of the appropriate trampline +- routine is used to set the 1st and 2nd doubleword of the +- plt_reserve. */ +- Elf64_FuncDesc *resolve_fd; + Elf64_Word glink_offset; +- /* the plt_reserve area is the 1st 3 doublewords of the PLT */ +- Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt; + Elf64_Word offset; ++ Elf64_Addr dlrr; + +- resolve_fd = (Elf64_FuncDesc *) (profile ? _dl_profile_resolve +- : _dl_runtime_resolve); ++ dlrr = (Elf64_Addr) (profile ? _dl_profile_resolve ++ : _dl_runtime_resolve); + if (profile && GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), map)) + /* This is the object we are looking for. Say that we really +@@ -330,20 +366,33 @@ + GL(dl_profile_map) = map; + + ++#if _CALL_ELF != 2 + /* We need to stuff the address/TOC of _dl_runtime_resolve + into doublewords 0 and 1 of plt_reserve. Then we need to + stuff the map address into doubleword 2 of plt_reserve. + This allows the GLINK0 code to transfer control to the + correct trampoline which will transfer control to fixup + in dl-machine.c. */ +- plt_reserve->fd_func = resolve_fd->fd_func; +- plt_reserve->fd_toc = resolve_fd->fd_toc; +- plt_reserve->fd_aux = (Elf64_Addr) map; ++ { ++ /* The plt_reserve area is the 1st 3 doublewords of the PLT. */ ++ Elf64_FuncDesc *plt_reserve = (Elf64_FuncDesc *) plt; ++ Elf64_FuncDesc *resolve_fd = (Elf64_FuncDesc *) dlrr; ++ plt_reserve->fd_func = resolve_fd->fd_func; ++ plt_reserve->fd_toc = resolve_fd->fd_toc; ++ plt_reserve->fd_aux = (Elf64_Addr) map; + #ifdef RTLD_BOOTSTRAP +- /* When we're bootstrapping, the opd entry will not have +- been relocated yet. */ +- plt_reserve->fd_func += l_addr; +- plt_reserve->fd_toc += l_addr; ++ /* When we're bootstrapping, the opd entry will not have ++ been relocated yet. */ ++ plt_reserve->fd_func += l_addr; ++ plt_reserve->fd_toc += l_addr; ++#endif ++ } ++#else ++ /* When we don't have function descriptors, the first doubleword ++ of the PLT holds the address of _dl_runtime_resolve, and the ++ second doubleword holds the map address. */ ++ plt[0] = dlrr; ++ plt[1] = (Elf64_Addr) map; + #endif + + /* Set up the lazy PLT entries. */ +@@ -354,14 +403,8 @@ + { + + plt[offset] = (Elf64_Xword) &glink[glink_offset]; +- offset += 3; +- /* The first 32k entries of glink can set an index and +- branch using two instructions; Past that point, +- glink uses three instructions. */ +- if (i < 0x8000) +- glink_offset += 2; +- else +- glink_offset += 3; ++ offset += PLT_ENTRY_WORDS; ++ glink_offset += GLINK_ENTRY_WORDS (i); + } + + /* Now, we've modified data. We need to write the changes from +@@ -389,6 +432,7 @@ + const Elf64_Rela *reloc, + Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) + { ++#if _CALL_ELF != 2 + Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; + Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr; + Elf64_Addr offset = 0; +@@ -426,6 +470,9 @@ + plt->fd_func = rel->fd_func + offset; + PPC_DCBST (&plt->fd_func); + PPC_ISYNC; ++#else ++ *reloc_addr = finaladdr; ++#endif + + return finaladdr; + } +@@ -433,6 +480,7 @@ + static inline void __attribute__ ((always_inline)) + elf_machine_plt_conflict (Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) + { ++#if _CALL_ELF != 2 + Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; + Elf64_FuncDesc *rel = (Elf64_FuncDesc *) finaladdr; + +@@ -443,6 +491,9 @@ + PPC_DCBST (&plt->fd_aux); + PPC_DCBST (&plt->fd_toc); + PPC_SYNC; ++#else ++ *reloc_addr = finaladdr; ++#endif + } + + /* Return the final value of a plt relocation. */ +@@ -512,6 +563,7 @@ + resolve_ifunc (Elf64_Addr value, + const struct link_map *map, const struct link_map *sym_map) + { ++#if _CALL_ELF != 2 + #ifndef RESOLVE_CONFLICT_FIND_MAP + /* The function we are calling may not yet have its opd entry relocated. */ + Elf64_FuncDesc opd; +@@ -529,6 +581,7 @@ + value = (Elf64_Addr) &opd; + } + #endif ++#endif + return ((Elf64_Addr (*) (unsigned long int)) value) (GLRO(dl_hwcap)); + } + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 13:58:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 14:00:27.000000000 -0500 +@@ -55,21 +55,22 @@ + that saves r2 since the call won't go via a plt call stub. See + bugz #269. __GI__setjmp is used in csu/libc-start.c when + HAVE_CLEANUP_JMP_BUF is defined. */ +-ENTRY (BP_SYM (__GI__setjmp)) ++ENTRY (__GI__setjmp) + std r2,40(r1) /* Save the callers TOC in the save area. */ +- cfi_endproc +-END_2 (BP_SYM (__GI__setjmp)) +-/* Fall thru. */ ++ CALL_MCOUNT 1 ++ li r4,0 /* Set second argument to 0. */ ++ b JUMPTARGET (GLUE(__sigsetjmp,_ent)) ++END (__GI__setjmp) + #endif + +-ENTRY (BP_SYM (_setjmp)) ++ENTRY (_setjmp) + CALL_MCOUNT 1 + li r4,0 /* Set second argument to 0. */ + b JUMPTARGET (GLUE(__sigsetjmp,_ent)) +-END (BP_SYM (_setjmp)) ++END (_setjmp) + libc_hidden_def (_setjmp) + +-ENTRY (BP_SYM (__sigsetjmp)) ++ENTRY (__sigsetjmp) + CALL_MCOUNT 2 + JUMPTARGET(GLUE(__sigsetjmp,_ent)): + CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) +@@ -215,18 +216,18 @@ + li r3,0 + blr + #elif defined SHARED +- b JUMPTARGET (BP_SYM (__sigjmp_save)) ++ b JUMPTARGET (__sigjmp_save) + #else + mflr r0 + std r0,16(r1) + stdu r1,-112(r1) + cfi_adjust_cfa_offset(112) + cfi_offset(lr,16) +- bl JUMPTARGET (BP_SYM (__sigjmp_save)) ++ bl JUMPTARGET (__sigjmp_save) + nop + ld r0,112+16(r1) + addi r1,r1,112 + mtlr r0 + blr + #endif +-END (BP_SYM (__sigsetjmp)) ++END (__sigsetjmp) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:58:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 13:58:25.000000000 -0500 +@@ -74,6 +74,8 @@ + #endif + .endm + ++#if _CALL_ELF != 2 ++ + /* Macro to prepare for calling via a function pointer. */ + .macro PPC64_LOAD_FUNCPTR PTR + ld r12,0(\PTR) +@@ -115,13 +117,37 @@ + .size name,.-BODY_LABEL(name); \ + .size BODY_LABEL(name),.-BODY_LABEL(name); + #endif ++#define LOCALENTRY(name) ++ ++#else /* _CALL_ELF */ ++ ++/* Macro to prepare for calling via a function pointer. */ ++ .macro PPC64_LOAD_FUNCPTR PTR ++ mr r12,\PTR ++ mtctr r12 ++ .endm ++ ++#define DOT_LABEL(X) X ++#define BODY_LABEL(X) X ++#define ENTRY_2(name) \ ++ .globl name; \ ++ .type name,@function; ++#define END_2(name) \ ++ .size name,.-name; ++#define LOCALENTRY(name) \ ++1: addis r2,r12,.TOC.-1b@ha; \ ++ addi r2,r2,.TOC.-1b@l; \ ++ .localentry name,.-name; ++ ++#endif /* _CALL_ELF */ + + #define ENTRY(name) \ + .section ".text"; \ + ENTRY_2(name) \ + .align ALIGNARG(2); \ + BODY_LABEL(name): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(name) + + #define EALIGN_W_0 /* No words to insert. */ + #define EALIGN_W_1 nop +@@ -140,7 +166,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(name): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(name) + + /* Local labels stripped out by the linker. */ + #undef L +@@ -295,6 +322,8 @@ + + #else /* !__ASSEMBLER__ */ + ++#if _CALL_ELF != 2 ++ + #define PPC64_LOAD_FUNCPTR(ptr) \ + "ld 12,0(" #ptr ");\n" \ + "ld 2,8(" #ptr ");\n" \ +@@ -335,5 +364,26 @@ + ".size " #name ",.-" BODY_PREFIX #name ";\n" \ + ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";" + #endif ++#define LOCALENTRY(name) ++ ++#else /* _CALL_ELF */ ++ ++#define PPC64_LOAD_FUNCPTR(ptr) \ ++ "mr 12," #ptr ";\n" \ ++ "mtctr 12;" ++ ++#define DOT_PREFIX "" ++#define BODY_PREFIX "" ++#define ENTRY_2(name) \ ++ ".type " #name ",@function;\n" \ ++ ".globl " #name ";" ++#define END_2(name) \ ++ ".size " #name ",.-" #name ";" ++#define LOCALENTRY(name) \ ++ "1: addis 2,12,.TOC.-1b@ha;\n" \ ++ "addi 2,2,.TOC.-1b@l;\n" \ ++ ".localentry " #name ",.-" #name ";" ++ ++#endif /* _CALL_ELF */ + + #endif /* __ASSEMBLER__ */ +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h 2014-05-29 13:58:24.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ldsodefs.h 2014-05-29 13:58:25.000000000 -0500 +@@ -23,6 +23,8 @@ + + /* Now define our stuff. */ + ++#if _CALL_ELF != 2 ++ + static __always_inline bool + _dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym) + { +@@ -73,4 +75,6 @@ + #define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \ + _dl_ppc64_addr_sym_match (L, SYM, MATCHSYM, ADDR) + ++#endif ++ + #endif /* ldsodefs.h */ +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:58:24.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S 2014-05-29 13:58:25.000000000 -0500 +@@ -111,6 +111,7 @@ + + L(noparms): + ++#if _CALL_ELF != 2 + /* Load the function address and TOC from the function descriptor + and store them in the ucontext as NIP and r2. Store the 3rd + field of the function descriptor into the ucontext as r11 in case +@@ -121,6 +122,12 @@ + std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) + std r10,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) + std r9,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3) ++#else ++ /* In the ELFv2 ABI, the function pointer is already the address. ++ Store it as NIP and r12 as required by the ABI. */ ++ std r4,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3) ++ std r4,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3) ++#endif + + /* If the target function returns we need to do some cleanup. We use a + code trick to get the address of our cleanup function into the link diff --git a/SOURCES/glibc-ppc64le-40.patch b/SOURCES/glibc-ppc64le-40.patch new file mode 100644 index 00000000..30acfb5d --- /dev/null +++ b/SOURCES/glibc-ppc64le-40.patch @@ -0,0 +1,159 @@ +# commit 122b66defdb9e4ded3ccc5c2b290f0520c6fa3cd +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:52:40 2013 -0600 +# +# PowerPC64 ELFv2 ABI 3/6: PLT local entry point optimization +# +# This is a follow-on to the previous patch to support the ELFv2 ABI in the +# dynamic loader, split off into its own patch since it is just an optional +# optimization. +# +# In the ELFv2 ABI, most functions define both a global and a local entry +# point; the local entry requires r2 to be already set up by the caller +# to point to the callee's TOC; while the global entry does not require +# the caller to know about the callee's TOC, but it needs to set up r12 +# to the callee's entry point address. +# +# Now, when setting up a PLT slot, the dynamic linker will usually need +# to enter the target function's global entry point. However, if the +# linker can prove that the target function is in the same DSO as the +# PLT slot itself, and the whole DSO only uses a single TOC (which the +# linker will let ld.so know via a DT_PPC64_OPT entry), then it is +# possible to actually enter the local entry point address into the +# PLT slot, for a slight improvement in performance. +# +# Note that this uncovered a problem on the first call via _dl_runtime_resolve, +# because that routine neglected to restore the caller's TOC before calling +# the target function for the first time, since it assumed that function +# would always reload its own TOC anyway ... +# +diff -urN glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h +--- glibc-2.17-c758a686/elf/elf.h 2014-05-29 14:08:44.000000000 -0500 ++++ glibc-2.17-c758a686/elf/elf.h 2014-05-29 14:08:44.000000000 -0500 +@@ -2273,8 +2273,19 @@ + #define DT_PPC64_GLINK (DT_LOPROC + 0) + #define DT_PPC64_OPD (DT_LOPROC + 1) + #define DT_PPC64_OPDSZ (DT_LOPROC + 2) ++#define DT_PPC64_OPT (DT_LOPROC + 3) + #define DT_PPC64_NUM 3 + ++/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */ ++#define PPC64_OPT_TLS 1 ++#define PPC64_OPT_MULTI_TOC 2 ++ ++/* PowerPC64 specific values for the Elf64_Sym st_other field. */ ++#define STO_PPC64_LOCAL_BIT 5 ++#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) ++#define PPC64_LOCAL_ENTRY_OFFSET(other) \ ++ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2) ++ + + /* ARM specific declarations */ + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:08:40.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:08:44.000000000 -0500 +@@ -425,6 +425,42 @@ + return lazy; + } + ++#if _CALL_ELF == 2 ++/* If the PLT entry whose reloc is 'reloc' resolves to a function in ++ the same object, return the target function's local entry point ++ offset if usable. */ ++static inline Elf64_Addr __attribute__ ((always_inline)) ++ppc64_local_entry_offset (struct link_map *map, lookup_t sym_map, ++ const Elf64_Rela *reloc) ++{ ++ const Elf64_Sym *symtab; ++ const Elf64_Sym *sym; ++ ++ /* If the target function is in a different object, we cannot ++ use the local entry point. */ ++ if (sym_map != map) ++ return 0; ++ ++ /* If the linker inserted multiple TOCs, we cannot use the ++ local entry point. */ ++ if (map->l_info[DT_PPC64(OPT)] ++ && (map->l_info[DT_PPC64(OPT)]->d_un.d_val & PPC64_OPT_MULTI_TOC)) ++ return 0; ++ ++ /* Otherwise, we can use the local entry point. Retrieve its offset ++ from the symbol's ELF st_other field. */ ++ symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); ++ sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; ++ ++ /* If the target function is an ifunc then the local entry offset is ++ for the resolver, not the final destination. */ ++ if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) ++ return 0; ++ ++ return PPC64_LOCAL_ENTRY_OFFSET (sym->st_other); ++} ++#endif ++ + /* Change the PLT entry whose reloc is 'reloc' to call the actual + routine. */ + static inline Elf64_Addr __attribute__ ((always_inline)) +@@ -471,6 +507,7 @@ + PPC_DCBST (&plt->fd_func); + PPC_ISYNC; + #else ++ finaladdr += ppc64_local_entry_offset (map, sym_map, reloc); + *reloc_addr = finaladdr; + #endif + +@@ -478,7 +515,9 @@ + } + + static inline void __attribute__ ((always_inline)) +-elf_machine_plt_conflict (Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) ++elf_machine_plt_conflict (struct link_map *map, lookup_t sym_map, ++ const Elf64_Rela *reloc, ++ Elf64_Addr *reloc_addr, Elf64_Addr finaladdr) + { + #if _CALL_ELF != 2 + Elf64_FuncDesc *plt = (Elf64_FuncDesc *) reloc_addr; +@@ -492,6 +531,7 @@ + PPC_DCBST (&plt->fd_toc); + PPC_SYNC; + #else ++ finaladdr += ppc64_local_entry_offset (map, sym_map, reloc); + *reloc_addr = finaladdr; + #endif + } +@@ -641,7 +681,7 @@ + /* Fall thru */ + case R_PPC64_JMP_SLOT: + #ifdef RESOLVE_CONFLICT_FIND_MAP +- elf_machine_plt_conflict (reloc_addr, value); ++ elf_machine_plt_conflict (map, sym_map, reloc, reloc_addr, value); + #else + elf_machine_fixup_plt (map, sym_map, reloc, reloc_addr, value); + #endif +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:08:40.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:08:44.000000000 -0500 +@@ -74,6 +74,10 @@ + /* Prepare for calling the function returned by fixup. */ + PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) ++#if _CALL_ELF == 2 ++/* Restore the caller's TOC in case we jump to a local entry point. */ ++ ld r2,FRAME_SIZE+40(r1) ++#endif + /* Unwind the stack frame, and jump. */ + addi r1,r1,FRAME_SIZE + bctr +@@ -321,6 +325,10 @@ + /* Prepare for calling the function returned by fixup. */ + PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) ++#if _CALL_ELF == 2 ++/* Restore the caller's TOC in case we jump to a local entry point. */ ++ ld r2,FRAME_SIZE+40(r1) ++#endif + /* Load the floating point registers. */ + lfd fp1,FPR_PARMS+0(r1) + lfd fp2,FPR_PARMS+8(r1) diff --git a/SOURCES/glibc-ppc64le-41.patch b/SOURCES/glibc-ppc64le-41.patch new file mode 100644 index 00000000..800894c8 --- /dev/null +++ b/SOURCES/glibc-ppc64le-41.patch @@ -0,0 +1,764 @@ +# commit 8b8a692cfd7d80f1ee7c8b9ab356a259367dd187 +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:55:03 2013 -0600 +# +# PowerPC64 ELFv2 ABI 4/6: Stack frame layout changes +# +# This updates glibc for the changes in the ELFv2 relating to the +# stack frame layout. These are described in more detail here: +# http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html +# http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01146.html +# +# Specifically, the "compiler and linker doublewords" were removed, +# which has the effect that the save slot for the TOC register is +# now at offset 24 rather than 40 to the stack pointer. +# +# In addition, a function may now no longer necessarily assume that +# its caller has set up a 64-byte register save area its use. +# +# To address the first change, the patch goes through all assembler +# files and replaces immediate offsets in instructions accessing the +# ABI-defined stack slots by symbolic offsets. Those already were +# defined in ucontext_i.sym and used in some of the context routines, +# but that doesn't really seem like the right place for those defines. +# +# The patch instead defines those symbolic offsets in sysdeps.h, +# in two variants for the old and new ABI, and uses them systematically +# in all assembler files, not just the context routines. +# +# The second change only affected a few assembler files that used +# the save area to temporarily store some registers. In those +# cases where this happens within a leaf function, this patch +# changes the code to store those registers to the "red zone" +# below the stack pointer. Otherwise, the functions already allocate +# a stack frame, and the patch changes them to add extra space in +# these frames as temporary space for the ELFv2 ABI. +# +diff -urN glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h 2014-05-29 14:10:00.000000000 -0500 ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h 2014-05-29 14:10:00.000000000 -0500 +@@ -31,6 +31,14 @@ + # define DASHDASHPFX(str) __##str + # endif + ++#if _CALL_ELF == 2 ++#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16+48) ++#define CANCEL_PARM_SAVE (FRAME_MIN_SIZE+16) ++#else ++#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16) ++#define CANCEL_PARM_SAVE (CANCEL_FRAMESIZE+FRAME_PARM_SAVE) ++#endif ++ + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ + .section ".text"; \ +@@ -44,52 +52,52 @@ + PSEUDO_RET; \ + .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel); \ + .Lpseudo_cancel: \ +- stdu 1,-128(1); \ +- cfi_adjust_cfa_offset (128); \ ++ stdu 1,-CANCEL_FRAMESIZE(1); \ ++ cfi_adjust_cfa_offset (CANCEL_FRAMESIZE); \ + mflr 9; \ +- std 9,128+16(1); \ +- cfi_offset (lr, 16); \ ++ std 9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1); \ ++ cfi_offset (lr, FRAME_LR_SAVE); \ + DOCARGS_##args; /* save syscall args around CENABLE. */ \ + CENABLE; \ +- std 3,112(1); /* store CENABLE return value (MASK). */ \ ++ std 3,FRAME_MIN_SIZE(1); /* store CENABLE return value (MASK). */ \ + UNDOCARGS_##args; /* restore syscall args. */ \ + DO_CALL (SYS_ify (syscall_name)); \ + mfcr 0; /* save CR/R3 around CDISABLE. */ \ +- std 3,120(1); \ +- std 0,128+8(1); \ +- cfi_offset (cr, 8); \ +- ld 3,112(1); /* pass MASK to CDISABLE. */ \ ++ std 3,FRAME_MIN_SIZE+8(1); \ ++ std 0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1); \ ++ cfi_offset (cr, FRAME_CR_SAVE); \ ++ ld 3,FRAME_MIN_SIZE(1); /* pass MASK to CDISABLE. */ \ + CDISABLE; \ +- ld 9,128+16(1); \ +- ld 0,128+8(1); /* restore CR/R3. */ \ +- ld 3,120(1); \ ++ ld 9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1); \ ++ ld 0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1); /* restore CR/R3. */ \ ++ ld 3,FRAME_MIN_SIZE+8(1); \ + mtlr 9; \ + mtcr 0; \ +- addi 1,1,128; \ +- cfi_adjust_cfa_offset (-128); \ ++ addi 1,1,CANCEL_FRAMESIZE; \ ++ cfi_adjust_cfa_offset (-CANCEL_FRAMESIZE); \ + cfi_restore (lr); \ + cfi_restore (cr) + + # define DOCARGS_0 + # define UNDOCARGS_0 + +-# define DOCARGS_1 std 3,128+48(1); DOCARGS_0 +-# define UNDOCARGS_1 ld 3,128+48(1); UNDOCARGS_0 ++# define DOCARGS_1 std 3,CANCEL_PARM_SAVE(1); DOCARGS_0 ++# define UNDOCARGS_1 ld 3,CANCEL_PARM_SAVE(1); UNDOCARGS_0 + +-# define DOCARGS_2 std 4,128+56(1); DOCARGS_1 +-# define UNDOCARGS_2 ld 4,128+56(1); UNDOCARGS_1 ++# define DOCARGS_2 std 4,CANCEL_PARM_SAVE+8(1); DOCARGS_1 ++# define UNDOCARGS_2 ld 4,CANCEL_PARM_SAVE+8(1); UNDOCARGS_1 + +-# define DOCARGS_3 std 5,128+64(1); DOCARGS_2 +-# define UNDOCARGS_3 ld 5,128+64(1); UNDOCARGS_2 ++# define DOCARGS_3 std 5,CANCEL_PARM_SAVE+16(1); DOCARGS_2 ++# define UNDOCARGS_3 ld 5,CANCEL_PARM_SAVE+16(1); UNDOCARGS_2 + +-# define DOCARGS_4 std 6,128+72(1); DOCARGS_3 +-# define UNDOCARGS_4 ld 6,128+72(1); UNDOCARGS_3 ++# define DOCARGS_4 std 6,CANCEL_PARM_SAVE+24(1); DOCARGS_3 ++# define UNDOCARGS_4 ld 6,CANCEL_PARM_SAVE+24(1); UNDOCARGS_3 + +-# define DOCARGS_5 std 7,128+80(1); DOCARGS_4 +-# define UNDOCARGS_5 ld 7,128+80(1); UNDOCARGS_4 ++# define DOCARGS_5 std 7,CANCEL_PARM_SAVE+32(1); DOCARGS_4 ++# define UNDOCARGS_5 ld 7,CANCEL_PARM_SAVE+32(1); UNDOCARGS_4 + +-# define DOCARGS_6 std 8,128+88(1); DOCARGS_5 +-# define UNDOCARGS_6 ld 8,128+88(1); UNDOCARGS_5 ++# define DOCARGS_6 std 8,CANCEL_PARM_SAVE+40(1); DOCARGS_5 ++# define UNDOCARGS_6 ld 8,CANCEL_PARM_SAVE+40(1); UNDOCARGS_5 + + # ifdef IS_IN_libpthread + # ifdef SHARED +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S 2014-05-29 14:10:00.000000000 -0500 +@@ -133,7 +133,7 @@ + ld r14,((JB_GPRS+0)*8)(r3) + lfd fp14,((JB_FPRS+0)*8)(r3) + #if defined SHARED && !defined IS_IN_rtld +- std r2,40(r1) /* Restore the callers TOC save area. */ ++ std r2,FRAME_TOC_SAVE(r1) /* Restore the callers TOC save area. */ + #endif + ld r15,((JB_GPRS+1)*8)(r3) + lfd fp15,((JB_FPRS+1)*8)(r3) +@@ -151,7 +151,7 @@ + PTR_DEMANGLE2 (r0, r25) + #endif + mtlr r0 +-/* std r2,40(r1) Restore the TOC save area. */ ++/* std r2,FRAME_TOC_SAVE(r1) Restore the TOC save area. */ + ld r21,((JB_GPRS+7)*8)(r3) + lfd fp21,((JB_FPRS+7)*8)(r3) + ld r22,((JB_GPRS+8)*8)(r3) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crti.S 2014-05-29 14:10:00.000000000 -0500 +@@ -66,8 +66,8 @@ + BODY_LABEL (_init): + LOCALENTRY(_init) + mflr 0 +- std 0, 16(r1) +- stdu r1, -112(r1) ++ std 0, FRAME_LR_SAVE(r1) ++ stdu r1, -FRAME_MIN_SIZE_PARM(r1) + #if PREINIT_FUNCTION_WEAK + addis r9, r2, .LC0@toc@ha + ld r0, .LC0@toc@l(r9) +@@ -84,5 +84,5 @@ + BODY_LABEL (_fini): + LOCALENTRY(_fini) + mflr 0 +- std 0, 16(r1) +- stdu r1, -112(r1) ++ std 0, FRAME_LR_SAVE(r1) ++ stdu r1, -FRAME_MIN_SIZE_PARM(r1) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crtn.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crtn.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crtn.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/crtn.S 2014-05-29 14:10:00.000000000 -0500 +@@ -39,13 +39,13 @@ + #include + + .section .init,"ax",@progbits +- addi r1, r1, 112 +- ld r0, 16(r1) ++ addi r1, r1, FRAME_MIN_SIZE_PARM ++ ld r0, FRAME_LR_SAVE(r1) + mtlr r0 + blr + + .section .fini,"ax",@progbits +- addi r1, r1, 112 +- ld r0, 16(r1) ++ addi r1, r1, FRAME_MIN_SIZE_PARM ++ ld r0, FRAME_LR_SAVE(r1) + mtlr r0 + blr +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:10:00.000000000 -0500 +@@ -26,13 +26,13 @@ + parm1 (r3) and the index (r0) need to be converted to an offset + (index * 24) in parm2 (r4). */ + +-#define FRAME_SIZE 176 ++#define FRAME_SIZE (FRAME_MIN_SIZE+64) + /* We need to save the registers used to pass parameters, ie. r3 thru + r10; Use local var space rather than the parameter save area, + because gcc as of 2010/05 doesn't allocate a proper stack frame for + a function that makes no calls except for __tls_get_addr and we + might be here resolving the __tls_get_addr call. */ +-#define INT_PARMS 112 ++#define INT_PARMS FRAME_MIN_SIZE + EALIGN(_dl_runtime_resolve, 4, 0) + stdu r1,-FRAME_SIZE(r1) + cfi_adjust_cfa_offset (FRAME_SIZE) +@@ -48,25 +48,25 @@ + mflr r0 + std r8,INT_PARMS+40(r1) + /* Store the LR in the LR Save area. */ +- std r0,FRAME_SIZE+16(r1) +- cfi_offset (lr, 16) ++ std r0,FRAME_SIZE+FRAME_LR_SAVE(r1) ++ cfi_offset (lr, FRAME_LR_SAVE) + mfcr r0 + std r9,INT_PARMS+48(r1) + std r10,INT_PARMS+56(r1) + /* I'm almost certain we don't have to save cr... be safe. */ +- std r0,FRAME_SIZE+8(r1) ++ std r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + bl JUMPTARGET(_dl_fixup) + #ifndef SHARED + nop + #endif + /* Put the registers back. */ +- ld r0,FRAME_SIZE+16(r1) ++ ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + ld r10,INT_PARMS+56(r1) + ld r9,INT_PARMS+48(r1) + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 +- ld r0,FRAME_SIZE+8(r1) ++ ld r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) +@@ -76,7 +76,7 @@ + ld r3,INT_PARMS+0(r1) + #if _CALL_ELF == 2 + /* Restore the caller's TOC in case we jump to a local entry point. */ +- ld r2,FRAME_SIZE+40(r1) ++ ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1) + #endif + /* Unwind the stack frame, and jump. */ + addi r1,r1,FRAME_SIZE +@@ -86,6 +86,7 @@ + #undef INT_PARMS + + /* Stack layout: ++ (Note: some of these are not required for the ELFv2 ABI.) + +592 previous backchain + +584 spill_r31 + +576 spill_r30 +@@ -147,10 +148,11 @@ + +64 parm3 + +56 parm2 + +48 parm1 +- * Parameter save area, Allocated by the call, at least 8 double words +- +40 TOC save area +- +32 Reserved for linker +- +24 Reserved for compiler ++ * Parameter save area ++ * (v1 ABI: Allocated by the call, at least 8 double words) ++ +40 v1 ABI: TOC save area ++ +32 v1 ABI: Reserved for linker ++ +24 v1 ABI: Reserved for compiler / v2 ABI: TOC save area + +16 LR save area + +8 CR save area + r1+0 stack back chain +@@ -206,15 +208,15 @@ + /* Store the LR in the LR Save area of the previous frame. */ + /* XXX Do we have to do this? */ + la r8,FRAME_SIZE(r1) +- std r5,FRAME_SIZE+16(r1) +- cfi_offset (lr, 16) ++ std r5,FRAME_SIZE+FRAME_LR_SAVE(r1) ++ cfi_offset (lr, FRAME_LR_SAVE) + std r5,CALLING_LR(r1) + mfcr r0 + std r9,INT_PARMS+48(r1) + std r10,INT_PARMS+56(r1) + std r8,CALLING_SP(r1) + /* I'm almost certain we don't have to save cr... be safe. */ +- std r0,FRAME_SIZE+8(r1) ++ std r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r12,.LC__dl_hwcap@toc(r2) + #ifdef SHARED + /* Load _rtld_local_ro._dl_hwcap. */ +@@ -311,13 +313,13 @@ + lvx v12,r11,r10 + lvx v13,r11,r9 + L(restoreFXR): +- ld r0,FRAME_SIZE+16(r1) ++ ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + ld r10,INT_PARMS+56(r1) + ld r9,INT_PARMS+48(r1) + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 +- ld r0,FRAME_SIZE+8(r1) ++ ld r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) +@@ -327,7 +329,7 @@ + ld r3,INT_PARMS+0(r1) + #if _CALL_ELF == 2 + /* Restore the caller's TOC in case we jump to a local entry point. */ +- ld r2,FRAME_SIZE+40(r1) ++ ld r2,FRAME_SIZE+FRAME_TOC_SAVE(r1) + #endif + /* Load the floating point registers. */ + lfd fp1,FPR_PARMS+0(r1) +@@ -375,19 +377,19 @@ + lvx v12,r11,r10 + lvx v13,r11,r9 + L(restoreFXR2): +- ld r0,FRAME_SIZE+16(r1) ++ ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + ld r10,INT_PARMS+56(r1) + ld r9,INT_PARMS+48(r1) + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 +- ld r0,FRAME_SIZE+8(r1) ++ ld r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) + mtcrf 0xFF,r0 + /* Prepare for calling the function returned by fixup. */ +- std r2,40(r1) ++ std r2,FRAME_TOC_SAVE(r1) + PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) + /* Load the floating point registers. */ +@@ -406,7 +408,7 @@ + lfd fp13,FPR_PARMS+96(r1) + /* Call the target function. */ + bctrl +- ld r2,40(r1) ++ ld r2,FRAME_TOC_SAVE(r1) + lwz r12,VR_VRSAVE(r1) + /* But return here and store the return values. */ + std r3,INT_RTN(r1) +@@ -441,7 +443,7 @@ + beq L(pltexitreturn) + lvx v2,0,r10 + L(pltexitreturn): +- ld r0,FRAME_SIZE+16(r1) ++ ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + ld r31,584(r1) + ld r30,576(r1) + mtlr r0 +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/ppc-mcount.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/ppc-mcount.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/ppc-mcount.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/ppc-mcount.S 2014-05-29 14:10:00.000000000 -0500 +@@ -24,16 +24,16 @@ + ENTRY(_mcount) + mflr r4 + ld r11, 0(r1) +- stdu r1,-112(r1) +- cfi_adjust_cfa_offset (112) +- std r4, 128(r1) +- cfi_offset (lr, 16) +- ld r3, 16(r11) ++ stdu r1,-FRAME_MIN_SIZE(r1) ++ cfi_adjust_cfa_offset (FRAME_MIN_SIZE) ++ std r4, FRAME_MIN_SIZE+FRAME_LR_SAVE(r1) ++ cfi_offset (lr, FRAME_LR_SAVE) ++ ld r3, FRAME_LR_SAVE(r11) + bl JUMPTARGET(__mcount_internal) + nop +- ld r0, 128(r1) ++ ld r0, FRAME_MIN_SIZE+FRAME_LR_SAVE(r1) + mtlr r0 +- addi r1,r1,112 ++ addi r1,r1,FRAME_MIN_SIZE + blr + END(_mcount) + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S 2014-05-29 14:10:00.000000000 -0500 +@@ -56,7 +56,7 @@ + bugz #269. __GI__setjmp is used in csu/libc-start.c when + HAVE_CLEANUP_JMP_BUF is defined. */ + ENTRY (__GI__setjmp) +- std r2,40(r1) /* Save the callers TOC in the save area. */ ++ std r2,FRAME_TOC_SAVE(r1) /* Save the callers TOC in the save area. */ + CALL_MCOUNT 1 + li r4,0 /* Set second argument to 0. */ + b JUMPTARGET (GLUE(__sigsetjmp,_ent)) +@@ -83,7 +83,7 @@ + #endif + mflr r0 + #if defined SHARED && !defined IS_IN_rtld +- ld r5,40(r1) /* Retrieve the callers TOC. */ ++ ld r5,FRAME_TOC_SAVE(r1) /* Retrieve the callers TOC. */ + std r5,(JB_GPR2*8)(3) + #else + std r2,(JB_GPR2*8)(3) +@@ -219,14 +219,14 @@ + b JUMPTARGET (__sigjmp_save) + #else + mflr r0 +- std r0,16(r1) +- stdu r1,-112(r1) +- cfi_adjust_cfa_offset(112) +- cfi_offset(lr,16) ++ std r0,FRAME_LR_SAVE(r1) ++ stdu r1,-FRAME_MIN_SIZE(r1) ++ cfi_adjust_cfa_offset(FRAME_MIN_SIZE) ++ cfi_offset(lr,FRAME_LR_SAVE) + bl JUMPTARGET (__sigjmp_save) + nop +- ld r0,112+16(r1) +- addi r1,r1,112 ++ ld r0,FRAME_MIN_SIZE+FRAME_LR_SAVE(r1) ++ addi r1,r1,FRAME_MIN_SIZE + mtlr r0 + blr + #endif +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h 2014-05-29 14:10:00.000000000 -0500 +@@ -20,25 +20,67 @@ + + #ifdef __ASSEMBLER__ + ++/* Stack frame offsets. */ ++#if _CALL_ELF != 2 ++#define FRAME_MIN_SIZE 112 ++#define FRAME_MIN_SIZE_PARM 112 ++#define FRAME_BACKCHAIN 0 ++#define FRAME_CR_SAVE 8 ++#define FRAME_LR_SAVE 16 ++#define FRAME_TOC_SAVE 40 ++#define FRAME_PARM_SAVE 48 ++#define FRAME_PARM1_SAVE 48 ++#define FRAME_PARM2_SAVE 56 ++#define FRAME_PARM3_SAVE 64 ++#define FRAME_PARM4_SAVE 72 ++#define FRAME_PARM5_SAVE 80 ++#define FRAME_PARM6_SAVE 88 ++#define FRAME_PARM7_SAVE 96 ++#define FRAME_PARM8_SAVE 104 ++#define FRAME_PARM9_SAVE 112 ++#else ++#define FRAME_MIN_SIZE 32 ++#define FRAME_MIN_SIZE_PARM 96 ++#define FRAME_BACKCHAIN 0 ++#define FRAME_CR_SAVE 8 ++#define FRAME_LR_SAVE 16 ++#define FRAME_TOC_SAVE 24 ++#define FRAME_PARM_SAVE 32 ++#define FRAME_PARM1_SAVE 32 ++#define FRAME_PARM2_SAVE 40 ++#define FRAME_PARM3_SAVE 48 ++#define FRAME_PARM4_SAVE 56 ++#define FRAME_PARM5_SAVE 64 ++#define FRAME_PARM6_SAVE 72 ++#define FRAME_PARM7_SAVE 80 ++#define FRAME_PARM8_SAVE 88 ++#define FRAME_PARM9_SAVE 96 ++#endif ++ + /* Support macros for CALL_MCOUNT. */ ++#if _CALL_ELF == 2 ++#define call_mcount_parm_offset (-64) ++#else ++#define call_mcount_parm_offset FRAME_PARM_SAVE ++#endif + .macro SAVE_ARG NARG + .if \NARG + SAVE_ARG \NARG-1 +- std 2+\NARG,40+8*(\NARG)(1) ++ std 2+\NARG,call_mcount_parm_offset-8+8*(\NARG)(1) + .endif + .endm + + .macro REST_ARG NARG + .if \NARG + REST_ARG \NARG-1 +- ld 2+\NARG,112+40+8*(\NARG)(1) ++ ld 2+\NARG,FRAME_MIN_SIZE_PARM+call_mcount_parm_offset-8+8*(\NARG)(1) + .endif + .endm + + .macro CFI_SAVE_ARG NARG + .if \NARG + CFI_SAVE_ARG \NARG-1 +- cfi_offset(2+\NARG,40+8*(\NARG)) ++ cfi_offset(2+\NARG,call_mcount_parm_offset-8+8*(\NARG)) + .endif + .endm + +@@ -55,20 +97,20 @@ + #ifdef PROF + mflr r0 + SAVE_ARG \NARG +- std r0,16(r1) +- stdu r1,-112(r1) +- cfi_adjust_cfa_offset(112) +- cfi_offset(lr,16) ++ std r0,FRAME_LR_SAVE(r1) ++ stdu r1,-FRAME_MIN_SIZE_PARM(r1) ++ cfi_adjust_cfa_offset(FRAME_MIN_SIZE_PARM) ++ cfi_offset(lr,FRAME_LR_SAVE) + CFI_SAVE_ARG \NARG + bl JUMPTARGET (_mcount) + #ifndef SHARED + nop + #endif +- ld r0,128(r1) ++ ld r0,FRAME_MIN_SIZE_PARM+FRAME_LR_SAVE(r1) + REST_ARG \NARG + mtlr r0 +- addi r1,r1,112 +- cfi_adjust_cfa_offset(-112) ++ addi r1,r1,FRAME_MIN_SIZE_PARM ++ cfi_adjust_cfa_offset(-FRAME_MIN_SIZE_PARM) + cfi_restore(lr) + CFI_REST_ARG \NARG + #endif +@@ -267,15 +309,15 @@ + .else; \ + .Local_syscall_error: \ + mflr 0; \ +- std 0,16(1); \ +- stdu 1,-112(1); \ +- cfi_adjust_cfa_offset(112); \ +- cfi_offset(lr,16); \ ++ std 0,FRAME_LR_SAVE(1); \ ++ stdu 1,-FRAME_MIN_SIZE(1); \ ++ cfi_adjust_cfa_offset(FRAME_MIN_SIZE); \ ++ cfi_offset(lr,FRAME_LR_SAVE); \ + bl JUMPTARGET(__syscall_error); \ + nop; \ +- ld 0,112+16(1); \ +- addi 1,1,112; \ +- cfi_adjust_cfa_offset(-112); \ ++ ld 0,FRAME_MIN_SIZE+FRAME_LR_SAVE(1); \ ++ addi 1,1,FRAME_MIN_SIZE; \ ++ cfi_adjust_cfa_offset(-FRAME_MIN_SIZE); \ + mtlr 0; \ + cfi_restore(lr); \ + blr; \ +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S 2014-05-29 14:10:00.000000000 -0500 +@@ -33,24 +33,24 @@ + cmpld reg, r1; \ + bge+ .Lok; \ + mflr r0; \ +- std r0,16(r1); \ ++ std r0,FRAME_LR_SAVE(r1); \ + mr r31,r3; \ + mr r30,r4; \ +- stdu r1,-144(r1); \ ++ stdu r1,-FRAME_MIN_SIZE-32(r1); \ + cfi_remember_state; \ +- cfi_adjust_cfa_offset (144); \ +- cfi_offset (lr, 16); \ ++ cfi_adjust_cfa_offset (FRAME_MIN_SIZE+32); \ ++ cfi_offset (lr, FRAME_LR_SAVE); \ + li r3,0; \ +- addi r4,r1,112; \ ++ addi r4,r1,FRAME_MIN_SIZE; \ + li r0,__NR_sigaltstack; \ + sc; \ + /* Without working sigaltstack we cannot perform the test. */ \ + bso .Lok2; \ +- lwz r0,112+8(r1); \ ++ lwz r0,FRAME_MIN_SIZE+8(r1); \ + andi. r4,r0,1; \ + beq .Lfail; \ +- ld r0,112+16(r1); \ +- ld r4,112(r1); \ ++ ld r0,FRAME_MIN_SIZE+16(r1); \ ++ ld r4,FRAME_MIN_SIZE(r1); \ + add r4,r4,r0; \ + sub r3,r3,reg; \ + cmpld r3,r0; \ +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S 2014-05-29 14:10:00.000000000 -0500 +@@ -31,9 +31,9 @@ + CALL_MCOUNT 1 + DISCARD_BOUNDS (r3) /* the bounds are meaningless, so toss 'em. */ + +- std r3,48(r1) ++ std r3,-8(r1) + DO_CALL(SYS_ify(brk)) +- ld r6,48(r1) ++ ld r6,-8(r1) + ld r5,.LC__curbrk@toc(r2) + std r3,0(r5) + cmpld r6,r3 +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S 2014-05-29 14:10:00.000000000 -0500 +@@ -45,22 +45,22 @@ + cror cr0*4+eq,cr1*4+eq,cr0*4+eq + beq- cr0,L(badargs) + +- /* Save some regs in parm save area. */ ++ /* Save some regs in the "red zone". */ + #ifdef RESET_PID +- std r29,48(r1) ++ std r29,-24(r1) + #endif +- std r30,56(r1) +- std r31,64(r1) ++ std r30,-16(r1) ++ std r31,-8(r1) + #ifdef RESET_PID +- cfi_offset(r29,48) ++ cfi_offset(r29,-24) + #endif +- cfi_offset(r30,56) +- cfi_offset(r31,64) ++ cfi_offset(r30,-16) ++ cfi_offset(r31,-8) + + /* Set up stack frame for child. */ + clrrdi r4,r4,4 + li r0,0 +- stdu r0,-112(r4) /* min stack frame is 112 bytes per ABI */ ++ stdu r0,-FRAME_MIN_SIZE_PARM(r4) + + /* Save fn, args, stack across syscall. */ + mr r30,r3 /* Function in r30. */ +@@ -102,12 +102,12 @@ + L(oldpid): + #endif + +- std r2,40(r1) ++ std r2,FRAME_TOC_SAVE(r1) + /* Call procedure. */ + PPC64_LOAD_FUNCPTR r30 + mr r3,r31 + bctrl +- ld r2,40(r1) ++ ld r2,FRAME_TOC_SAVE(r1) + /* Call _exit with result from procedure. */ + #ifdef SHARED + b JUMPTARGET(__GI__exit) +@@ -126,15 +126,15 @@ + L(parent): + /* Parent. Restore registers & return. */ + #ifdef RESET_PID +- cfi_offset(r29,48) ++ cfi_offset(r29,-24) + #endif +- cfi_offset(r30,56) +- cfi_offset(r31,64) ++ cfi_offset(r30,-16) ++ cfi_offset(r31,-8) + #ifdef RESET_PID +- ld r29,48(r1) ++ ld r29,-24(r1) + #endif +- ld r30,56(r1) +- ld r31,64(r1) ++ ld r30,-16(r1) ++ ld r31,-8(r1) + #ifdef RESET_PID + cfi_restore(r29) + #endif +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S 2014-05-29 14:10:00.000000000 -0500 +@@ -46,8 +46,13 @@ + # endif + #endif + +-#define FRAMESIZE 128 +-#define stackblock FRAMESIZE+48 /* offset to parm save area. */ ++#if _CALL_ELF == 2 ++#define FRAMESIZE (FRAME_MIN_SIZE+16+64) ++#define stackblock (FRAME_MIN_SIZE+16) ++#else ++#define FRAMESIZE (FRAME_MIN_SIZE+16) ++#define stackblock (FRAMESIZE+FRAME_PARM_SAVE) /* offset to parm save area. */ ++#endif + + .text + ENTRY(__socket) +@@ -98,22 +103,22 @@ + .Lsocket_cancel: + cfi_adjust_cfa_offset(FRAMESIZE) + mflr r9 +- std r9,FRAMESIZE+16(r1) +- cfi_offset (lr, 16) ++ std r9,FRAMESIZE+FRAME_LR_SAVE(r1) ++ cfi_offset (lr, FRAME_LR_SAVE) + CENABLE +- std r3,120(r1) ++ std r3,FRAME_MIN_SIZE+8(r1) + li r3,P(SOCKOP_,socket) + addi r4,r1,stackblock + DO_CALL(SYS_ify(socketcall)) + mfcr r0 +- std r3,112(r1) +- std r0,FRAMESIZE+8(r1) +- cfi_offset (cr, 8) +- ld r3,120(r1) ++ std r3,FRAME_MIN_SIZE(r1) ++ std r0,FRAMESIZE+FRAME_CR_SAVE(r1) ++ cfi_offset (cr, FRAME_CR_SAVE) ++ ld r3,FRAME_MIN_SIZE+8(r1) + CDISABLE +- ld r4,FRAMESIZE+16(r1) +- ld r0,FRAMESIZE+8(r1) +- ld r3,112(r1) ++ ld r4,FRAMESIZE+FRAME_LR_SAVE(r1) ++ ld r0,FRAMESIZE+FRAME_CR_SAVE(r1) ++ ld r3,FRAME_MIN_SIZE(r1) + mtlr r4 + mtcr r0 + addi r1,r1,FRAMESIZE +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym 2014-05-29 14:09:56.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym 2014-05-29 14:10:00.000000000 -0500 +@@ -8,27 +8,6 @@ + SIG_SETMASK + + +--- Offsets of the fields in the powerpc64 ABI stack frame. +--- XXX Do these correspond to some struct? +- +-FRAME_BACKCHAIN 0 +-FRAME_CR_SAVE 8 +-FRAME_LR_SAVE 16 +-FRAME_COMPILER_DW 24 +-FRAME_LINKER_DW 32 +-FRAME_TOC_SAVE 40 +-FRAME_PARM_SAVE 48 +-FRAME_PARM1_SAVE 48 +-FRAME_PARM2_SAVE 56 +-FRAME_PARM3_SAVE 64 +-FRAME_PARM4_SAVE 72 +-FRAME_PARM5_SAVE 80 +-FRAME_PARM6_SAVE 88 +-FRAME_PARM7_SAVE 96 +-FRAME_PARM8_SAVE 104 +-FRAME_PARM9_SAVE 112 +- +- + -- Offsets of the fields in the ucontext_t structure. + #define ucontext(member) offsetof (ucontext_t, member) + #define mcontext(member) ucontext (uc_mcontext.member) diff --git a/SOURCES/glibc-ppc64le-42.patch b/SOURCES/glibc-ppc64le-42.patch new file mode 100644 index 00000000..06d5db1d --- /dev/null +++ b/SOURCES/glibc-ppc64le-42.patch @@ -0,0 +1,404 @@ +# commit 61cd8fe4017c251617dd300818917e61a12ab48e +# Author: Ulrich Weigand +# Date: Wed Dec 4 06:59:37 2013 -0600 +# +# PowerPC64 ELFv2 ABI 5/6: LD_AUDIT interface changes +# +# The ELFv2 ABI changes the calling convention by passing and returning +# structures in registers in more cases than the old ABI: +# http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html +# http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html +# +# For the most part, this does not affect glibc, since glibc assembler +# files do not use structure parameters / return values. However, one +# place is affected: the LD_AUDIT interface provides a structure to +# the audit routine that contains all registers holding function +# argument and return values for the intercepted PLT call. +# +# Since the new ABI now sometimes uses registers to return values +# that were never used for this purpose in the old ABI, this structure +# has to be extended. To force audit routines to be modified for the +# new ABI if necessary, the patch defines v2 variants of the la_ppc64 +# types and routines. +# +# In addition, the patch contains two unrelated changes to the +# PLT trampoline routines: it fixes a bug where FPR return values +# were stored in the wrong place, and it removes the unnecessary +# save/restore of CR. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/bits/link.h glibc-2.17-c758a686/sysdeps/powerpc/bits/link.h +--- glibc-2.17-c758a686/sysdeps/powerpc/bits/link.h 2014-05-29 14:11:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/bits/link.h 2014-05-29 14:11:20.000000000 -0500 +@@ -63,7 +63,7 @@ + + __END_DECLS + +-#else ++#elif _CALL_ELF != 2 + + /* Registers for entry into PLT on PPC64. */ + typedef struct La_ppc64_regs +@@ -107,4 +107,48 @@ + + __END_DECLS + ++#else ++ ++/* Registers for entry into PLT on PPC64 in the ELFv2 ABI. */ ++typedef struct La_ppc64v2_regs ++{ ++ uint64_t lr_reg[8]; ++ double lr_fp[13]; ++ uint32_t __padding; ++ uint32_t lr_vrsave; ++ uint32_t lr_vreg[12][4] __attribute__ ((aligned (16))); ++ uint64_t lr_r1; ++ uint64_t lr_lr; ++} La_ppc64v2_regs; ++ ++/* Return values for calls from PLT on PPC64 in the ELFv2 ABI. */ ++typedef struct La_ppc64v2_retval ++{ ++ uint64_t lrv_r3; ++ uint64_t lrv_r4; ++ double lrv_fp[10]; ++ uint32_t lrv_vreg[8][4] __attribute__ ((aligned (16))); ++} La_ppc64v2_retval; ++ ++ ++__BEGIN_DECLS ++ ++extern Elf64_Addr la_ppc64v2_gnu_pltenter (Elf64_Sym *__sym, ++ unsigned int __ndx, ++ uintptr_t *__refcook, ++ uintptr_t *__defcook, ++ La_ppc64v2_regs *__regs, ++ unsigned int *__flags, ++ const char *__symname, ++ long int *__framesizep); ++extern unsigned int la_ppc64v2_gnu_pltexit (Elf64_Sym *__sym, ++ unsigned int __ndx, ++ uintptr_t *__refcook, ++ uintptr_t *__defcook, ++ const La_ppc64v2_regs *__inregs, ++ La_ppc64v2_retval *__outregs, ++ const char *__symname); ++ ++__END_DECLS ++ + #endif +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/ldsodefs.h glibc-2.17-c758a686/sysdeps/powerpc/ldsodefs.h +--- glibc-2.17-c758a686/sysdeps/powerpc/ldsodefs.h 2014-05-29 14:11:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/ldsodefs.h 2014-05-29 14:11:20.000000000 -0500 +@@ -25,6 +25,8 @@ + struct La_ppc32_retval; + struct La_ppc64_regs; + struct La_ppc64_retval; ++struct La_ppc64v2_regs; ++struct La_ppc64v2_retval; + + #define ARCH_PLTENTER_MEMBERS \ + Elf32_Addr (*ppc32_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, \ +@@ -34,7 +36,12 @@ + Elf64_Addr (*ppc64_gnu_pltenter) (Elf64_Sym *, unsigned int, uintptr_t *, \ + uintptr_t *, struct La_ppc64_regs *, \ + unsigned int *, const char *name, \ +- long int *framesizep) ++ long int *framesizep); \ ++ Elf64_Addr (*ppc64v2_gnu_pltenter) (Elf64_Sym *, unsigned int, \ ++ uintptr_t *, uintptr_t *, \ ++ struct La_ppc64v2_regs *, \ ++ unsigned int *, const char *name, \ ++ long int *framesizep) + + #define ARCH_PLTEXIT_MEMBERS \ + unsigned int (*ppc32_gnu_pltexit) (Elf32_Sym *, unsigned int, \ +@@ -47,7 +54,14 @@ + uintptr_t *, \ + uintptr_t *, \ + const struct La_ppc64_regs *, \ +- struct La_ppc64_retval *, const char *) ++ struct La_ppc64_retval *, \ ++ const char *); \ ++ unsigned int (*ppc64v2_gnu_pltexit) (Elf64_Sym *, unsigned int, \ ++ uintptr_t *, \ ++ uintptr_t *, \ ++ const struct La_ppc64v2_regs *,\ ++ struct La_ppc64v2_retval *, \ ++ const char *) + + #include_next + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:11:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-05-29 14:11:20.000000000 -0500 +@@ -546,8 +546,13 @@ + + + /* Names of the architecture-specific auditing callback functions. */ ++#if _CALL_ELF != 2 + #define ARCH_LA_PLTENTER ppc64_gnu_pltenter + #define ARCH_LA_PLTEXIT ppc64_gnu_pltexit ++#else ++#define ARCH_LA_PLTENTER ppc64v2_gnu_pltenter ++#define ARCH_LA_PLTEXIT ppc64v2_gnu_pltexit ++#endif + + #endif /* dl_machine_h */ + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:11:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-trampoline.S 2014-05-29 14:11:20.000000000 -0500 +@@ -50,11 +50,8 @@ + /* Store the LR in the LR Save area. */ + std r0,FRAME_SIZE+FRAME_LR_SAVE(r1) + cfi_offset (lr, FRAME_LR_SAVE) +- mfcr r0 + std r9,INT_PARMS+48(r1) + std r10,INT_PARMS+56(r1) +-/* I'm almost certain we don't have to save cr... be safe. */ +- std r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + bl JUMPTARGET(_dl_fixup) + #ifndef SHARED + nop +@@ -66,11 +63,9 @@ + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 +- ld r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) +- mtcrf 0xFF,r0 + /* Prepare for calling the function returned by fixup. */ + PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) +@@ -85,18 +80,30 @@ + #undef FRAME_SIZE + #undef INT_PARMS + +- /* Stack layout: +- (Note: some of these are not required for the ELFv2 ABI.) +- +592 previous backchain +- +584 spill_r31 +- +576 spill_r30 +- +560 v1 +- +552 fp4 +- +544 fp3 +- +536 fp2 +- +528 fp1 +- +520 r4 +- +512 r3 ++ /* Stack layout: ELFv2 ABI. ++ +752 previous backchain ++ +744 spill_r31 ++ +736 spill_r30 ++ +720 v8 ++ +704 v7 ++ +688 v6 ++ +672 v5 ++ +656 v4 ++ +640 v3 ++ +624 v2 ++ +608 v1 ++ +600 fp10 ++ ELFv1 ABI +592 fp9 ++ +592 previous backchain +584 fp8 ++ +584 spill_r31 +576 fp7 ++ +576 spill_r30 +568 fp6 ++ +560 v1 +560 fp5 ++ +552 fp4 +552 fp4 ++ +544 fp3 +544 fp3 ++ +536 fp2 +536 fp2 ++ +528 fp1 +528 fp1 ++ +520 r4 +520 r4 ++ +512 r3 +512 r3 + return values + +504 free + +496 stackframe +@@ -157,10 +164,15 @@ + +8 CR save area + r1+0 stack back chain + */ +-#define FRAME_SIZE 592 ++#if _CALL_ELF == 2 ++# define FRAME_SIZE 752 ++# define VR_RTN 608 ++#else ++# define FRAME_SIZE 592 ++# define VR_RTN 560 ++#endif + #define INT_RTN 512 + #define FPR_RTN 528 +-#define VR_RTN 560 + #define STACK_FRAME 496 + #define CALLING_LR 488 + #define CALLING_SP 480 +@@ -205,18 +217,14 @@ + mflr r5 + std r7,INT_PARMS+32(r1) + std r8,INT_PARMS+40(r1) +-/* Store the LR in the LR Save area of the previous frame. */ +-/* XXX Do we have to do this? */ ++/* Store the LR in the LR Save area. */ + la r8,FRAME_SIZE(r1) + std r5,FRAME_SIZE+FRAME_LR_SAVE(r1) + cfi_offset (lr, FRAME_LR_SAVE) + std r5,CALLING_LR(r1) +- mfcr r0 + std r9,INT_PARMS+48(r1) + std r10,INT_PARMS+56(r1) + std r8,CALLING_SP(r1) +-/* I'm almost certain we don't have to save cr... be safe. */ +- std r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r12,.LC__dl_hwcap@toc(r2) + #ifdef SHARED + /* Load _rtld_local_ro._dl_hwcap. */ +@@ -319,11 +327,9 @@ + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 +- ld r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) +- mtcrf 0xFF,r0 + /* Prepare for calling the function returned by fixup. */ + PPC64_LOAD_FUNCPTR r3 + ld r3,INT_PARMS+0(r1) +@@ -346,10 +352,11 @@ + lfd fp12,FPR_PARMS+88(r1) + lfd fp13,FPR_PARMS+96(r1) + /* Unwind the stack frame, and jump. */ +- ld r31,584(r1) +- ld r30,576(r1) ++ ld r31,FRAME_SIZE-8(r1) ++ ld r30,FRAME_SIZE-16(r1) + addi r1,r1,FRAME_SIZE + bctr ++ + L(do_pltexit): + la r10,(VR_PARMS+0)(r1) + la r9,(VR_PARMS+16)(r1) +@@ -383,11 +390,9 @@ + ld r8,INT_PARMS+40(r1) + ld r7,INT_PARMS+32(r1) + mtlr r0 +- ld r0,FRAME_SIZE+FRAME_CR_SAVE(r1) + ld r6,INT_PARMS+24(r1) + ld r5,INT_PARMS+16(r1) + ld r4,INT_PARMS+8(r1) +- mtcrf 0xFF,r0 + /* Prepare for calling the function returned by fixup. */ + std r2,FRAME_TOC_SAVE(r1) + PPC64_LOAD_FUNCPTR r3 +@@ -413,16 +418,37 @@ + /* But return here and store the return values. */ + std r3,INT_RTN(r1) + std r4,INT_RTN+8(r1) +- stfd fp1,FPR_PARMS+0(r1) +- stfd fp2,FPR_PARMS+8(r1) ++ stfd fp1,FPR_RTN+0(r1) ++ stfd fp2,FPR_RTN+8(r1) + cmpdi cr0,r12,0 + la r10,VR_RTN(r1) +- stfd fp3,FPR_PARMS+16(r1) +- stfd fp4,FPR_PARMS+24(r1) ++ stfd fp3,FPR_RTN+16(r1) ++ stfd fp4,FPR_RTN+24(r1) ++#if _CALL_ELF == 2 ++ la r12,VR_RTN+16(r1) ++ stfd fp5,FPR_RTN+32(r1) ++ stfd fp6,FPR_RTN+40(r1) ++ li r5,32 ++ li r6,64 ++ stfd fp7,FPR_RTN+48(r1) ++ stfd fp8,FPR_RTN+56(r1) ++ stfd fp9,FPR_RTN+64(r1) ++ stfd fp10,FPR_RTN+72(r1) ++#endif + mr r3,r31 + mr r4,r30 + beq L(callpltexit) + stvx v2,0,r10 ++#if _CALL_ELF == 2 ++ stvx v3,0,r12 ++ stvx v4,r5,r10 ++ stvx v5,r5,r12 ++ addi r5,r5,64 ++ stvx v6,r6,r10 ++ stvx v7,r6,r12 ++ stvx v8,r5,r10 ++ stvx v9,r5,r12 ++#endif + L(callpltexit): + addi r5,r1,INT_PARMS + addi r6,r1,INT_RTN +@@ -434,18 +460,39 @@ + lwz r12,VR_VRSAVE(r1) + ld r3,INT_RTN(r1) + ld r4,INT_RTN+8(r1) +- lfd fp1,FPR_PARMS+0(r1) +- lfd fp2,FPR_PARMS+8(r1) ++ lfd fp1,FPR_RTN+0(r1) ++ lfd fp2,FPR_RTN+8(r1) + cmpdi cr0,r12,0 +- la r10,VR_RTN(r1) +- lfd fp3,FPR_PARMS+16(r1) +- lfd fp4,FPR_PARMS+24(r1) ++ la r11,VR_RTN(r1) ++ lfd fp3,FPR_RTN+16(r1) ++ lfd fp4,FPR_RTN+24(r1) ++#if _CALL_ELF == 2 ++ la r12,VR_RTN+16(r1) ++ lfd fp5,FPR_RTN+32(r1) ++ lfd fp6,FPR_RTN+40(r1) ++ li r30,32 ++ li r31,64 ++ lfd fp7,FPR_RTN+48(r1) ++ lfd fp8,FPR_RTN+56(r1) ++ lfd fp9,FPR_RTN+64(r1) ++ lfd fp10,FPR_RTN+72(r1) ++#endif + beq L(pltexitreturn) +- lvx v2,0,r10 ++ lvx v2,0,r11 ++#if _CALL_ELF == 2 ++ lvx v3,0,r12 ++ lvx v4,r30,r11 ++ lvx v5,r30,r12 ++ addi r30,r30,64 ++ lvx v6,r31,r11 ++ lvx v7,r31,r12 ++ lvx v8,r30,r11 ++ lvx v9,r30,r12 ++#endif + L(pltexitreturn): + ld r0,FRAME_SIZE+FRAME_LR_SAVE(r1) +- ld r31,584(r1) +- ld r30,576(r1) ++ ld r31,FRAME_SIZE-8(r1) ++ ld r30,FRAME_SIZE-16(r1) + mtlr r0 + ld r1,0(r1) + blr +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/tst-audit.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/tst-audit.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/tst-audit.h 2014-05-29 14:11:12.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/tst-audit.h 2014-05-29 14:11:20.000000000 -0500 +@@ -18,8 +18,16 @@ + License along with the GNU C Library. If not, see + . */ + ++#if _CALL_ELF != 2 + #define pltenter la_ppc64_gnu_pltenter + #define pltexit la_ppc64_gnu_pltexit + #define La_regs La_ppc64_regs + #define La_retval La_ppc64_retval + #define int_retval lrv_r3 ++#else ++#define pltenter la_ppc64v2_gnu_pltenter ++#define pltexit la_ppc64v2_gnu_pltexit ++#define La_regs La_ppc64v2_regs ++#define La_retval La_ppc64v2_retval ++#define int_retval lrv_r3 ++#endif diff --git a/SOURCES/glibc-ppc64le-43.patch b/SOURCES/glibc-ppc64le-43.patch new file mode 100644 index 00000000..a480c02f --- /dev/null +++ b/SOURCES/glibc-ppc64le-43.patch @@ -0,0 +1,248 @@ +# commit 5b118558f9fb0620508d51c34c2cb5ba4f1f01c2 +# Author: Ulrich Weigand +# Date: Wed Dec 4 07:08:48 2013 -0600 +# +# PowerPC64 ELFv2 ABI 6/6: Bump ld.so soname version number +# +# To avoid having a ELFv2 binary accidentally picking up an old ABI ld.so, +# this patch bumps the soname to ld64.so.2. +# +# In theory (or for testing purposes) this will also allow co-installing +# ld.so versions for both ABIs on the same system. Note that the kernel +# will already be able to load executables of both ABIs. However, there +# is currently no plan to use that theoretical possibility in a any +# supported distribution environment ... +# +# Note that in order to check which ABI to use, we need to invoke the +# compiler to check the _CALL_ELF macro; this is done in a new configure +# check in sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac, +# replacing the hard-coded value of default-abi in the Makefile. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile 2014-05-29 14:12:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile 2014-05-29 14:12:30.000000000 -0500 +@@ -1,9 +1,12 @@ +-abi-variants := 32 64 ++abi-variants := 32 64-v1 64-v2 + abi-32-options := -U__powerpc64__ + abi-32-condition := __WORDSIZE == 32 +-abi-64-options := -D__powerpc64__ +-abi-64-condition := __WORDSIZE == 64 +-abi-64-ld-soname := ld64.so.1 ++abi-64-v1-options := -D__powerpc64__ -U_CALL_ELF -D_CALL_ELF=1 ++abi-64-v1-condition := __WORDSIZE == 64 && _CALL_ELF != 2 ++abi-64-v1-ld-soname := ld64.so.1 ++abi-64-v2-options := -D__powerpc64__ -U_CALL_ELF -D_CALL_ELF=2 ++abi-64-v2-condition := __WORDSIZE == 64 && _CALL_ELF == 2 ++abi-64-v2-ld-soname := ld64.so.2 + + ifeq ($(subdir),rt) + librt-routines += rt-sysdep +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldconfig.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldconfig.h +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldconfig.h 2014-05-29 14:12:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldconfig.h 2014-05-29 14:12:30.000000000 -0500 +@@ -20,7 +20,8 @@ + + #define SYSDEP_KNOWN_INTERPRETER_NAMES \ + { "/lib/ld.so.1", FLAG_ELF_LIBC6 }, \ +- { "/lib64/ld64.so.1", FLAG_ELF_LIBC6 }, ++ { "/lib64/ld64.so.1", FLAG_ELF_LIBC6 }, \ ++ { "/lib64/ld64.so.2", FLAG_ELF_LIBC6 }, + #define SYSDEP_KNOWN_LIBRARY_NAMES \ + { "libc.so.6", FLAG_ELF_LIBC6 }, \ + { "libm.so.6", FLAG_ELF_LIBC6 }, +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile 2014-05-29 14:12:25.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile 1969-12-31 18:00:00.000000000 -0600 +@@ -1,2 +0,0 @@ +-# See Makeconfig regarding the use of default-abi. +-default-abi := 64 +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure 1969-12-31 18:00:00.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure 2014-05-29 14:12:30.000000000 -0500 +@@ -0,0 +1,166 @@ ++# This file is generated from configure.ac by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/unix/sysv/linux/powerpc/powerpc64/. ++ ++# Define default-abi according to compiler flags. ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 ++$as_echo_n "checking for grep that handles long lines and -e... " >&6; } ++if ${ac_cv_path_GREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if test -z "$GREP"; then ++ ac_path_GREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in grep ggrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue ++# Check for GNU ac_path_GREP and select it if it is found. ++ # Check for GNU $ac_path_GREP ++case `"$ac_path_GREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'GREP' >> "conftest.nl" ++ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_GREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_GREP="$ac_path_GREP" ++ ac_path_GREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_GREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_GREP"; then ++ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_GREP=$GREP ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 ++$as_echo "$ac_cv_path_GREP" >&6; } ++ GREP="$ac_cv_path_GREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 ++$as_echo_n "checking for egrep... " >&6; } ++if ${ac_cv_path_EGREP+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 ++ then ac_cv_path_EGREP="$GREP -E" ++ else ++ if test -z "$EGREP"; then ++ ac_path_EGREP_found=false ++ # Loop through the user's path and test for each of PROGNAME-LIST ++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR ++for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin ++do ++ IFS=$as_save_IFS ++ test -z "$as_dir" && as_dir=. ++ for ac_prog in egrep; do ++ for ac_exec_ext in '' $ac_executable_extensions; do ++ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" ++ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue ++# Check for GNU ac_path_EGREP and select it if it is found. ++ # Check for GNU $ac_path_EGREP ++case `"$ac_path_EGREP" --version 2>&1` in ++*GNU*) ++ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; ++*) ++ ac_count=0 ++ $as_echo_n 0123456789 >"conftest.in" ++ while : ++ do ++ cat "conftest.in" "conftest.in" >"conftest.tmp" ++ mv "conftest.tmp" "conftest.in" ++ cp "conftest.in" "conftest.nl" ++ $as_echo 'EGREP' >> "conftest.nl" ++ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break ++ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ++ as_fn_arith $ac_count + 1 && ac_count=$as_val ++ if test $ac_count -gt ${ac_path_EGREP_max-0}; then ++ # Best one so far, save it but keep looking for a better one ++ ac_cv_path_EGREP="$ac_path_EGREP" ++ ac_path_EGREP_max=$ac_count ++ fi ++ # 10*(2^10) chars as input seems more than enough ++ test $ac_count -gt 10 && break ++ done ++ rm -f conftest.in conftest.tmp conftest.nl conftest.out;; ++esac ++ ++ $ac_path_EGREP_found && break 3 ++ done ++ done ++ done ++IFS=$as_save_IFS ++ if test -z "$ac_cv_path_EGREP"; then ++ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 ++ fi ++else ++ ac_cv_path_EGREP=$EGREP ++fi ++ ++ fi ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 ++$as_echo "$ac_cv_path_EGREP" >&6; } ++ EGREP="$ac_cv_path_EGREP" ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the PowerPC64 ELFv2 ABI" >&5 ++$as_echo_n "checking whether the compiler is using the PowerPC64 ELFv2 ABI... " >&6; } ++if ${libc_cv_ppc64_elfv2_abi+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++#if _CALL_ELF == 2 ++ yes ++ #endif ++ ++_ACEOF ++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++ $EGREP "yes" >/dev/null 2>&1; then : ++ libc_cv_ppc64_elfv2_abi=yes ++else ++ libc_cv_ppc64_elfv2_abi=no ++fi ++rm -f conftest* ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ppc64_elfv2_abi" >&5 ++$as_echo "$libc_cv_ppc64_elfv2_abi" >&6; } ++if test $libc_cv_ppc64_elfv2_abi = yes; then ++ config_vars="$config_vars ++default-abi = 64-v2" ++else ++ config_vars="$config_vars ++default-abi = 64-v1" ++fi +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac 1969-12-31 18:00:00.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/configure.ac 2014-05-29 14:12:30.000000000 -0500 +@@ -0,0 +1,15 @@ ++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. ++# Local configure fragment for sysdeps/unix/sysv/linux/powerpc/powerpc64/. ++ ++# Define default-abi according to compiler flags. ++AC_CACHE_CHECK([whether the compiler is using the PowerPC64 ELFv2 ABI], ++ [libc_cv_ppc64_elfv2_abi], ++ [AC_EGREP_CPP(yes,[#if _CALL_ELF == 2 ++ yes ++ #endif ++ ], libc_cv_ppc64_elfv2_abi=yes, libc_cv_ppc64_elfv2_abi=no)]) ++if test $libc_cv_ppc64_elfv2_abi = yes; then ++ LIBC_CONFIG_VAR([default-abi], [64-v2]) ++else ++ LIBC_CONFIG_VAR([default-abi], [64-v1]) ++fi diff --git a/SOURCES/glibc-ppc64le-44.patch b/SOURCES/glibc-ppc64le-44.patch new file mode 100644 index 00000000..a3468a8a --- /dev/null +++ b/SOURCES/glibc-ppc64le-44.patch @@ -0,0 +1,26 @@ +# commit c859b32e9d76afe8a3f20bb9528961a573c06937 +# Author: Alan Modra +# Date: Tue Apr 1 14:07:42 2014 +1030 +# +# Fix s_copysign stack temp for PowerPC64 ELFv2 +# +# [BZ #16786] +# * sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Don't trash stack. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S 2014-05-29 14:13:47.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S 2014-05-29 14:13:50.000000000 -0500 +@@ -27,11 +27,11 @@ + /* double [f1] copysign (double [f1] x, double [f2] y); + copysign(x,y) returns a value with the magnitude of x and + with the sign bit of y. */ +- stfd fp2,56(r1) ++ stfd fp2,-8(r1) + nop + nop + nop +- ld r3,56(r1) ++ ld r3,-8(r1) + cmpdi r3,0 + blt L(0) + fabs fp1,fp1 diff --git a/SOURCES/glibc-ppc64le-45.patch b/SOURCES/glibc-ppc64le-45.patch new file mode 100644 index 00000000..9030fc25 --- /dev/null +++ b/SOURCES/glibc-ppc64le-45.patch @@ -0,0 +1,33 @@ +# +# For PPC64LE only! +# +# This is fixed upstream by the removal of Versions.def +# and auto-generation of the SHLIB_COMPAT required entries. +# See: https://sourceware.org/ml/libc-alpha/2014-02/msg00818.html +# Backporting that infrastructure to RHEL 7.x is too much work +# at this junction for little reward. Instead we simply fix up +# the Versions.def to include GLIBC_2.3 which is used by +# nptl/old_pthread_atfork.c, otherwise ppc64le will get +# pthread_atfork in libpthread.so.0 when it should not. +# +# The ABI testing for libpthread.so now passes for ppc64le. +# +diff -urN glibc-2.17-c758a686/Versions.def glibc-2.17-c758a686/Versions.def +--- glibc-2.17-c758a686/Versions.def 2014-06-02 21:13:12.000000000 +0000 ++++ glibc-2.17-c758a686/Versions.def 2014-06-02 21:14:38.000000000 +0000 +@@ -92,6 +92,7 @@ + GLIBC_2.2 + GLIBC_2.2.3 + GLIBC_2.2.6 ++ GLIBC_2.3 + GLIBC_2.3.2 + GLIBC_2.3.3 + GLIBC_2.3.4 +@@ -99,6 +100,7 @@ + GLIBC_2.6 + GLIBC_2.11 + GLIBC_2.12 ++ GLIBC_2.17 + GLIBC_PRIVATE + } + libresolv { diff --git a/SOURCES/glibc-ppc64le-46.patch b/SOURCES/glibc-ppc64le-46.patch new file mode 100644 index 00000000..6f3d1d9e --- /dev/null +++ b/SOURCES/glibc-ppc64le-46.patch @@ -0,0 +1,22 @@ +# +# On POWER this patch also fixes test-ildoubl and test-ldouble failures where tan +# rounded toward zero had acceptable 1 ULP error. Upstream is using 3 ULP, but +# we prefer to keep the bound tighter unless we have a reason not to. +# +# This is the ppc64le version which is required becuase it applies *after* another +# ppc64le patch that touches the same ULPs file. See glibc-power-libm-test-ulps.patch +# for the ppc64/ppc version. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps 2014-07-25 22:07:06.280020855 -0400 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/libm-test-ulps 2014-07-25 22:26:54.650021033 -0400 +@@ -2644,6 +2644,9 @@ + Test "tan_towardzero (2)": + ildouble: 1 + ldouble: 1 ++Test "tan_towardzero (2) == -2.1850398632615189916433061023136825434320": ++ildouble: 1 ++ldouble: 1 + Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261": + float: 1 + ifloat: 1 diff --git a/SOURCES/glibc-rh1000923.patch b/SOURCES/glibc-rh1000923.patch new file mode 100644 index 00000000..2745a201 --- /dev/null +++ b/SOURCES/glibc-rh1000923.patch @@ -0,0 +1,32 @@ +commit 595aba70a4c676f7efaf6a012f54cd22aa189c5b +Author: Siddhesh Poyarekar +Date: Mon Aug 26 15:42:29 2013 +0530 + + Initialize res_hconf in nscd + + Fixes BZ #15890. + +diff -pruN glibc-2.17-c758a686/nscd/aicache.c glibc-2.17-c758a686/nscd/aicache.c +--- glibc-2.17-c758a686/nscd/aicache.c 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.17-c758a686/nscd/aicache.c 2013-08-26 11:10:25.843470413 +0530 +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include "dbg_log.h" + #include "nscd.h" +@@ -100,8 +101,11 @@ addhstaiX (struct database_dyn *db, int + no_more = __nss_database_lookup ("hosts", NULL, + "dns [!UNAVAIL=return] files", &nip); + ++ /* Initialize configurations. */ ++ if (__builtin_expect (!_res_hconf.initialized, 0)) ++ _res_hconf_init (); + if (__res_maybe_init (&_res, 0) == -1) +- no_more = 1; ++ no_more = 1; + + /* If we are looking for both IPv4 and IPv6 address we don't want + the lookup functions to automatically promote IPv4 addresses to diff --git a/SOURCES/glibc-rh1008298.patch b/SOURCES/glibc-rh1008298.patch new file mode 100644 index 00000000..024957dd --- /dev/null +++ b/SOURCES/glibc-rh1008298.patch @@ -0,0 +1,46 @@ +diff --git glibc-2.17-c758a686/malloc/malloc.c glibc-2.17-c758a686/malloc/malloc.c +index 3148c5f..f7718a9 100644 +--- glibc-2.17-c758a686/malloc/malloc.c ++++ glibc-2.17-c758a686/malloc/malloc.c +@@ -3015,6 +3015,13 @@ __libc_memalign(size_t alignment, size_t bytes) + /* Otherwise, ensure that it is at least a minimum chunk size */ + if (alignment < MINSIZE) alignment = MINSIZE; + ++ /* Check for overflow. */ ++ if (bytes > SIZE_MAX - alignment - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + arena_get(ar_ptr, bytes + alignment + MINSIZE); + if(!ar_ptr) + return 0; +@@ -3046,6 +3046,13 @@ __libc_valloc(size_t bytes) + + size_t pagesz = GLRO(dl_pagesize); + ++ /* Check for overflow. */ ++ if (bytes > SIZE_MAX - pagesz - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t, + const __malloc_ptr_t)) = + force_reg (__memalign_hook); +@@ -3082,6 +3082,13 @@ __libc_pvalloc(size_t bytes) + size_t page_mask = GLRO(dl_pagesize) - 1; + size_t rounded_bytes = (bytes + page_mask) & ~(page_mask); + ++ /* Check for overflow. */ ++ if (bytes > SIZE_MAX - 2*pagesz - MINSIZE) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + __malloc_ptr_t (*hook) __MALLOC_PMT ((size_t, size_t, + const __malloc_ptr_t)) = + force_reg (__memalign_hook); diff --git a/SOURCES/glibc-rh1020637.patch b/SOURCES/glibc-rh1020637.patch new file mode 100644 index 00000000..5493a038 --- /dev/null +++ b/SOURCES/glibc-rh1020637.patch @@ -0,0 +1,128 @@ +commit acd98a8ed1460497e788c701eb92616f1df9b446 +Author: Andreas Krebbel +Date: Fri Nov 29 09:57:04 2013 +0100 + + [BZ #16214] S/390: Fix TLS GOT pointer setup. + +diff --git glibc-2.17-c758a686/sysdeps/s390/Versions glibc-2.17-c758a686/sysdeps/s390/Versions +index e18617c..baf9842 100644 +--- glibc-2.17-c758a686/sysdeps/s390/Versions ++++ glibc-2.17-c758a686/sysdeps/s390/Versions +@@ -3,4 +3,8 @@ ld { + # runtime interface to TLS + __tls_get_offset; + } ++ GLIBC_PRIVATE { ++ # Exported by ld used by libc. ++ __tls_get_addr_internal; ++ } + } +diff --git glibc-2.17-c758a686/sysdeps/s390/dl-tls.h glibc-2.17-c758a686/sysdeps/s390/dl-tls.h +index 68a5af4..52192a2 100644 +--- glibc-2.17-c758a686/sysdeps/s390/dl-tls.h ++++ glibc-2.17-c758a686/sysdeps/s390/dl-tls.h +@@ -26,11 +26,26 @@ typedef struct + + + #ifdef SHARED +-/* This is the prototype for the GNU version. */ +-extern void *__tls_get_addr (tls_index *ti) attribute_hidden; ++ + extern unsigned long __tls_get_offset (unsigned long got_offset); + + # ifdef IS_IN_rtld ++ ++# include ++ ++extern void *__tls_get_addr (tls_index *ti) attribute_hidden; ++/* Make a temporary alias of __tls_get_addr to remove the hidden ++ attribute. Then export __tls_get_addr as __tls_get_addr_internal ++ for use from libc. We do not want to export __tls_get_addr, but we ++ do need to use it from libc when looking up the address of a TLS ++ variable. We don't use __tls_get_offset because it requires r12 to ++ be setup and that might not always be true. Either way it's more ++ optimal to use __tls_get_addr directly (that's what ++ __tls_get_offset does anyways). */ ++strong_alias (__tls_get_addr, __tls_get_addr_internal_tmp); ++versioned_symbol (ld, __tls_get_addr_internal_tmp, ++ __tls_get_addr_internal, GLIBC_PRIVATE); ++ + /* The special thing about the s390 TLS ABI is that we do not have the + standard __tls_get_addr function but the __tls_get_offset function + which differs in two important aspects: +@@ -63,15 +78,21 @@ __tls_get_offset:\n\ + 1: .long __tls_get_addr - 0b\n\ + "); + # endif +-# endif ++# else /* IS_IN_rtld */ ++extern void *__tls_get_addr_internal (tls_index *ti); ++# endif /* !IS_IN_rtld */ + + # define GET_ADDR_OFFSET \ + (ti->ti_offset - (unsigned long) __builtin_thread_pointer ()) + +-# define __TLS_GET_ADDR(__ti) \ +- ({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden; \ +- (void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_) \ +- + (unsigned long) __builtin_thread_pointer (); }) ++/* Use the privately exported __tls_get_addr_internal instead of ++ __tls_get_offset in order to avoid the __tls_get_offset special ++ linkage requiring the GOT pointer to be set up in r12. The ++ compiler will take care of setting up r12 only if itself issued the ++ __tls_get_offset call. */ ++# define __TLS_GET_ADDR(__ti) \ ++ ({ (void *) __tls_get_addr_internal ((char *) (__ti)) \ ++ + (unsigned long) __builtin_thread_pointer (); }) + + #endif + +diff --git glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h +index 8a0ad58..a592d81 100644 +--- glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/tls-macros.h +@@ -8,12 +8,15 @@ + + #ifdef PIC + # define TLS_IE(x) \ +- ({ unsigned long __offset; \ ++ ({ unsigned long __offset, __got; \ + asm ("bras %0,1f\n" \ +- "0:\t.long " #x "@gotntpoff\n" \ +- "1:\tl %0,0(%0)\n\t" \ +- "l %0,0(%0,%%r12):tls_load:" #x \ +- : "=&a" (__offset) : : "cc" ); \ ++ "0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \ ++ ".long " #x "@gotntpoff\n" \ ++ "1:\tl %1,0(%0)\n\t" \ ++ "la %1,0(%1,%0)\n\t" \ ++ "l %0,4(%0)\n\t" \ ++ "l %0,0(%0,%1):tls_load:" #x "\n" \ ++ : "=&a" (__offset), "=&a" (__got) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) + #else + # define TLS_IE(x) \ +diff --git glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h +index be8aa6c..3c59436 100644 +--- glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/tls-macros.h +@@ -8,12 +8,13 @@ + + #ifdef PIC + # define TLS_IE(x) \ +- ({ unsigned long __offset; \ +- asm ("bras %0,1f\n" \ +- "0:\t.quad " #x "@gotntpoff\n" \ +- "1:\tlg %0,0(%0)\n\t" \ +- "lg %0,0(%0,%%r12):tls_load:" #x \ +- : "=&a" (__offset) : : "cc" ); \ ++ ({ unsigned long __offset, __got; \ ++ asm ("bras %0,0f\n\t" \ ++ ".quad " #x "@gotntpoff\n" \ ++ "0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \ ++ "lg %0,0(%0)\n\t" \ ++ "lg %0,0(%0,%1):tls_load:" #x "\n" \ ++ : "=&a" (__offset), "=&a" (__got) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) + #else + # define TLS_IE(x) \ diff --git a/SOURCES/glibc-rh1025612.patch b/SOURCES/glibc-rh1025612.patch new file mode 100644 index 00000000..3e2f6e68 --- /dev/null +++ b/SOURCES/glibc-rh1025612.patch @@ -0,0 +1,50 @@ +commit 7cbcdb3699584db8913ca90f705d6337633ee10f +Author: Siddhesh Poyarekar +Date: Fri Oct 25 10:22:12 2013 +0530 + + Fix stack overflow due to large AF_INET6 requests + + Resolves #16072 (CVE-2013-4458). + + This patch fixes another stack overflow in getaddrinfo when it is + called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914, + but the AF_INET6 case went undetected back then. + +diff --git glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +index e6ce4cf..8ff74b4 100644 +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -197,7 +197,22 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, + &rc, &herrno, NULL, &localcanon)); \ + if (rc != ERANGE || herrno != NETDB_INTERNAL) \ + break; \ +- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \ ++ if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \ ++ tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \ ++ alloca_used); \ ++ else \ ++ { \ ++ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \ ++ 2 * tmpbuflen); \ ++ if (newp == NULL) \ ++ { \ ++ result = -EAI_MEMORY; \ ++ goto free_and_return; \ ++ } \ ++ tmpbuf = newp; \ ++ malloc_tmpbuf = true; \ ++ tmpbuflen = 2 * tmpbuflen; \ ++ } \ + } \ + if (status == NSS_STATUS_SUCCESS && rc == 0) \ + h = &th; \ +@@ -209,7 +224,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, + { \ + __set_h_errno (herrno); \ + _res.options |= old_res_options & RES_USE_INET6; \ +- return -EAI_SYSTEM; \ ++ result = -EAI_SYSTEM; \ ++ goto free_and_return; \ + } \ + if (herrno == TRY_AGAIN) \ + no_data = EAI_AGAIN; \ diff --git a/SOURCES/glibc-rh1025934.patch b/SOURCES/glibc-rh1025934.patch new file mode 100644 index 00000000..47302ad2 --- /dev/null +++ b/SOURCES/glibc-rh1025934.patch @@ -0,0 +1,143 @@ +Mostly equivalent upstream commit: + +commit 0699f766b10c86912b75f35bef697106b70c1cf6 +Author: Carlos O'Donell +Date: Thu Apr 10 18:31:53 2014 -0400 + + nscd: Make SELinux checks dynamic. + +diff --git glibc-2.17-c758a686/nscd/selinux.c glibc-2.17-c758a686/nscd/selinux.c +index 0866c44..ba55b04 100644 +--- glibc-2.17-c758a686/nscd/selinux.c ++++ glibc-2.17-c758a686/nscd/selinux.c +@@ -44,35 +44,31 @@ + /* Global variable to tell if the kernel has SELinux support. */ + int selinux_enabled; + +-/* Define mappings of access vector permissions to request types. */ +-static const access_vector_t perms[LASTREQ] = ++/* Define mappings of request type to AVC permission name. */ ++static const char *perms[LASTREQ] = + { +- [GETPWBYNAME] = NSCD__GETPWD, +- [GETPWBYUID] = NSCD__GETPWD, +- [GETGRBYNAME] = NSCD__GETGRP, +- [GETGRBYGID] = NSCD__GETGRP, +- [GETHOSTBYNAME] = NSCD__GETHOST, +- [GETHOSTBYNAMEv6] = NSCD__GETHOST, +- [GETHOSTBYADDR] = NSCD__GETHOST, +- [GETHOSTBYADDRv6] = NSCD__GETHOST, +- [GETSTAT] = NSCD__GETSTAT, +- [SHUTDOWN] = NSCD__ADMIN, +- [INVALIDATE] = NSCD__ADMIN, +- [GETFDPW] = NSCD__SHMEMPWD, +- [GETFDGR] = NSCD__SHMEMGRP, +- [GETFDHST] = NSCD__SHMEMHOST, +- [GETAI] = NSCD__GETHOST, +- [INITGROUPS] = NSCD__GETGRP, +-#ifdef NSCD__GETSERV +- [GETSERVBYNAME] = NSCD__GETSERV, +- [GETSERVBYPORT] = NSCD__GETSERV, +- [GETFDSERV] = NSCD__SHMEMSERV, +-#endif +-#ifdef NSCD__GETNETGRP +- [GETNETGRENT] = NSCD__GETNETGRP, +- [INNETGR] = NSCD__GETNETGRP, +- [GETFDNETGR] = NSCD__SHMEMNETGRP, +-#endif ++ [GETPWBYNAME] = "getpwd", ++ [GETPWBYUID] = "getpwd", ++ [GETGRBYNAME] = "getgrp", ++ [GETGRBYGID] = "getgrp", ++ [GETHOSTBYNAME] = "gethost", ++ [GETHOSTBYNAMEv6] = "gethost", ++ [GETHOSTBYADDR] = "gethost", ++ [GETHOSTBYADDRv6] = "gethost", ++ [SHUTDOWN] = "admin", ++ [GETSTAT] = "getstat", ++ [INVALIDATE] = "admin", ++ [GETFDPW] = "shmempwd", ++ [GETFDGR] = "shmemgrp", ++ [GETFDHST] = "shmemhost", ++ [GETAI] = "gethost", ++ [INITGROUPS] = "getgrp", ++ [GETSERVBYNAME] = "getserv", ++ [GETSERVBYPORT] = "getserv", ++ [GETFDSERV] = "shmemserv", ++ [GETNETGRENT] = "getnetgrp", ++ [INNETGR] = "getnetgrp", ++ [GETFDNETGR] = "shmemnetgrp", + }; + + /* Store an entry ref to speed AVC decisions. */ +@@ -344,7 +340,18 @@ nscd_avc_init (void) + + + /* Check the permission from the caller (via getpeercon) to nscd. +- Returns 0 if access is allowed, 1 if denied, and -1 on error. */ ++ Returns 0 if access is allowed, 1 if denied, and -1 on error. ++ ++ Implementation note: ++ The SELinux policy, enablement, and permission bits are all dynamic ++ and the caching done by glibc is not entirely correct. This nscd ++ support should be rewritten to use selinux_check_permission. ++ A rewrite is risky though and requires some refactoring fist. ++ Instead we use symbolic mappings instead of compile time ++ constants (which selinux upstream says are going away), and use ++ security_deny_unknown to determine what to do if selinux-policy ++ doesn't have a definition for the the permission or object class ++ we are looking up. */ + int + nscd_request_avc_has_perm (int fd, request_type req) + { +@@ -354,6 +361,33 @@ nscd_request_avc_has_perm (int fd, request_type req) + security_id_t ssid = NULL; + security_id_t tsid = NULL; + int rc = -1; ++ security_class_t sc_nscd = 0; ++ access_vector_t perm = 0; ++ int avc_deny_unknown = 0; ++ ++ /* Check if SELinux denys or allows unknown object classes ++ and permissions. It is 0 if they are allowed, 1 if they ++ are not allowed and -1 on error. */ ++ if ((avc_deny_unknown = security_deny_unknown ()) == -1) ++ dbg_log (_("Error querying policy for undefined object classes " ++ "or permissions.")); ++ ++ /* Get the security class for nscd. If this fails we will likely be ++ unable to do anything unless avc_deny_unknown is 0. */ ++ if ((sc_nscd = string_to_security_class ("nscd")) == 0 ++ && avc_deny_unknown == 1) ++ dbg_log (_("Error getting security class for nscd.")); ++ ++ /* Convert permission to AVC bits. */ ++ perm = string_to_av_perm (sc_nscd, perms[req]); ++ if (perm == 0 && avc_deny_unknown == 1) ++ dbg_log (_("Error translating permission name " ++ "\"%s\" to access vector bit."), perms[req]); ++ ++ /* If the nscd security class was not found or perms were not ++ found and AVC does not deny unknown values then allow it. */ ++ if ((sc_nscd == 0 || perm == 0) && avc_deny_unknown == 0) ++ return 0; + + if (getpeercon (fd, &scon) < 0) + { +@@ -372,15 +406,7 @@ nscd_request_avc_has_perm (int fd, request_type req) + goto out; + } + +-#ifndef NSCD__GETSERV +- if (perms[req] == 0) +- { +- dbg_log (_("compile-time support for database policy missing")); +- goto out; +- } +-#endif +- +- rc = avc_has_perm (ssid, tsid, SECCLASS_NSCD, perms[req], &aeref, NULL) < 0; ++ rc = avc_has_perm (ssid, tsid, sc_nscd, perm, &aeref, NULL) < 0; + + out: + if (scon) diff --git a/SOURCES/glibc-rh1027101.patch b/SOURCES/glibc-rh1027101.patch new file mode 100644 index 00000000..ffee8427 --- /dev/null +++ b/SOURCES/glibc-rh1027101.patch @@ -0,0 +1,58 @@ +commit 362b47fe09ca9a928d444c7e2f7992f7f61bfc3e +Author: Maxim Kuvyrkov +Date: Tue Dec 24 09:44:50 2013 +1300 + + Fix race in free() of fastbin chunk: BZ #15073 + + Perform sanity check only if we have_lock. Due to lockless nature of fastbins + we need to be careful derefencing pointers to fastbin entries (chunksize(old) + in this case) in multithreaded environments. + + The fix is to add have_lock to the if-condition checks. The rest of the patch + only makes code more readable. + + * malloc/malloc.c (_int_free): Perform sanity check only if we + have_lock. + +Index: b/malloc/malloc.c +=================================================================== +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -3909,25 +3909,29 @@ _int_free(mstate av, mchunkptr p, int ha + unsigned int idx = fastbin_index(size); + fb = &fastbin (av, idx); + +- mchunkptr fd; +- mchunkptr old = *fb; ++ /* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */ ++ mchunkptr old = *fb, old2; + unsigned int old_idx = ~0u; + do + { +- /* Another simple check: make sure the top of the bin is not the +- record we are going to add (i.e., double free). */ ++ /* Check that the top of the bin is not the record we are going to add ++ (i.e., double free). */ + if (__builtin_expect (old == p, 0)) + { + errstr = "double free or corruption (fasttop)"; + goto errout; + } +- if (old != NULL) ++ /* Check that size of fastbin chunk at the top is the same as ++ size of the chunk that we are adding. We can dereference OLD ++ only if we have the lock, otherwise it might have already been ++ deallocated. See use of OLD_IDX below for the actual check. */ ++ if (have_lock && old != NULL) + old_idx = fastbin_index(chunksize(old)); +- p->fd = fd = old; ++ p->fd = old2 = old; + } +- while ((old = catomic_compare_and_exchange_val_rel (fb, p, fd)) != fd); ++ while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2); + +- if (fd != NULL && __builtin_expect (old_idx != idx, 0)) ++ if (have_lock && old != NULL && __builtin_expect (old_idx != idx, 0)) + { + errstr = "invalid fastbin entry (free)"; + goto errout; diff --git a/SOURCES/glibc-rh1027348-1.patch b/SOURCES/glibc-rh1027348-1.patch new file mode 100644 index 00000000..ab6335a9 --- /dev/null +++ b/SOURCES/glibc-rh1027348-1.patch @@ -0,0 +1,280 @@ +Backporting the C11 atomic support will allow future algorithms +to be more easily backported to RHEL7. This is initially backported +to support the new semaphore algorithm which is now in RHEL7 +(rhbz#1027348). + +commit 1ea339b69725cb2f30b5a84cb7ca96111c9a637b +Author: Torvald Riegel +Date: Sat Oct 18 01:02:59 2014 +0200 + + Add arch-specific configuration for C11 atomics support. + + This sets __HAVE_64B_ATOMICS if provided. It also sets + USE_ATOMIC_COMPILER_BUILTINS to true if the existing atomic ops use the + __atomic* builtins (aarch64, mips partially) or if this has been + tested (x86_64); otherwise, this is set to false so that C11 atomics will + be based on the existing atomic operations. + +Index: glibc-2.17-c758a686/ports/sysdeps/aarch64/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/aarch64/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/bits/atomic.h +@@ -36,6 +36,8 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 1 + + /* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ +Index: glibc-2.17-c758a686/ports/sysdeps/alpha/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/alpha/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/alpha/bits/atomic.h +@@ -42,6 +42,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + #ifdef UP + # define __MB /* nothing */ +Index: glibc-2.17-c758a686/ports/sysdeps/arm/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/arm/bits/atomic.h +@@ -33,6 +33,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 0 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + void __arm_link_error (void); + + /* Use the atomic builtins provided by GCC in case the backend provides +Index: glibc-2.17-c758a686/sysdeps/i386/i486/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i486/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/i386/i486/bits/atomic.h +@@ -54,6 +54,9 @@ typedef uintmax_t uatomic_max_t; + # endif + #endif + ++#define __HAVE_64B_ATOMICS 0 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + __sync_val_compare_and_swap (mem, oldval, newval) +Index: glibc-2.17-c758a686/ports/sysdeps/ia64/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/ia64/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/bits/atomic.h +@@ -43,6 +43,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + #define __arch_compare_and_exchange_bool_8_acq(mem, newval, oldval) \ + (abort (), 0) +Index: glibc-2.17-c758a686/ports/sysdeps/m68k/coldfire/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/m68k/coldfire/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/m68k/coldfire/bits/atomic.h +@@ -49,6 +49,10 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++/* If we have just non-atomic operations, we can as well make them wide. */ ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + /* The only basic operation needed is compare and exchange. */ + #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + ({ __typeof (mem) __gmemp = (mem); \ +Index: glibc-2.17-c758a686/ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/m68k/m680x0/m68020/bits/atomic.h +@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + ({ __typeof (*(mem)) __ret; \ + __asm __volatile ("cas%.b %0,%2,%1" \ +Index: glibc-2.17-c758a686/ports/sysdeps/mips/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/mips/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/mips/bits/atomic.h +@@ -43,6 +43,12 @@ typedef uintmax_t uatomic_max_t; + #define MIPS_PUSH_MIPS2 + #endif + ++#if _MIPS_SIM == _ABIO32 ++#define __HAVE_64B_ATOMICS 0 ++#else ++#define __HAVE_64B_ATOMICS 1 ++#endif ++ + /* See the comments in about the use of the sync instruction. */ + #ifndef MIPS_SYNC + # define MIPS_SYNC sync +@@ -82,6 +88,8 @@ typedef uintmax_t uatomic_max_t; + /* The __atomic_* builtins are available in GCC 4.7 and later, but MIPS + support for their efficient implementation was added only in GCC 4.8. */ + ++#define USE_ATOMIC_COMPILER_BUILTINS 1 ++ + /* Compare and exchange. + For all "bool" routines, we return FALSE if exchange succesful. */ + +@@ -204,6 +212,8 @@ typedef uintmax_t uatomic_max_t; + /* This implementation using inline assembly will be removed once glibc + requires GCC 4.8 or later to build. */ + ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + /* Compare and exchange. For all of the "xxx" routines, we expect a + "__prev" and a "__cmp" variable to be provided by the enclosing scope, + in which values are returned. */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bits/atomic.h +@@ -33,6 +33,9 @@ + # define MUTEX_HINT_REL + #endif + ++#define __HAVE_64B_ATOMICS 0 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + /* + * The 32-bit exchange_bool is different on powerpc64 because the subf + * does signed 64-bit arthmatic while the lwarx is 32-bit unsigned +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/bits/atomic.h +@@ -33,6 +33,9 @@ + # define MUTEX_HINT_REL + #endif + ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + /* The 32-bit exchange_bool is different on powerpc64 because the subf + does signed 64-bit arthmatic while the lwarx is 32-bit unsigned + (a load word and zero (high 32) form) load. +Index: glibc-2.17-c758a686/sysdeps/s390/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/s390/bits/atomic.h +@@ -43,6 +43,8 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) +@@ -59,6 +61,7 @@ typedef uintmax_t uatomic_max_t; + __archold; }) + + #ifdef __s390x__ ++# define __HAVE_64B_ATOMICS 1 + # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ + ({ __typeof (mem) __archmem = (mem); \ + __typeof (*mem) __archold = (oldval); \ +@@ -67,6 +70,7 @@ typedef uintmax_t uatomic_max_t; + : "d" ((long) (newval)), "m" (*__archmem) : "cc", "memory" ); \ + __archold; }) + #else ++# define __HAVE_64B_ATOMICS 0 + /* For 31 bit we do not really need 64-bit compare-and-exchange. We can + implement them by use of the csd instruction. The straightforward + implementation causes warnings so we skip the definition for now. */ +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc32/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc32/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/bits/atomic.h +@@ -47,6 +47,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 0 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + /* We have no compare and swap, just test and set. + The following implementation contends on 64 global locks +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h +@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 0 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/bits/atomic.h +@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 1 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + + #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + (abort (), (__typeof (*mem)) 0) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h +@@ -44,6 +44,9 @@ typedef uintptr_t uatomicptr_t; + typedef intmax_t atomic_max_t; + typedef uintmax_t uatomic_max_t; + ++#define __HAVE_64B_ATOMICS 0 ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++ + /* prev = *addr; + if (prev == old) + *addr = new; +Index: glibc-2.17-c758a686/sysdeps/x86_64/bits/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/bits/atomic.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/bits/atomic.h +@@ -55,6 +55,12 @@ typedef uintmax_t uatomic_max_t; + # endif + #endif + ++#define __HAVE_64B_ATOMICS 1 ++#if __GNUC_PREREQ (4, 7) ++#define USE_ATOMIC_COMPILER_BUILTINS 1 ++#else ++#define USE_ATOMIC_COMPILER_BUILTINS 0 ++#endif + + #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \ + __sync_val_compare_and_swap (mem, oldval, newval) diff --git a/SOURCES/glibc-rh1027348-2.patch b/SOURCES/glibc-rh1027348-2.patch new file mode 100644 index 00000000..0361fd81 --- /dev/null +++ b/SOURCES/glibc-rh1027348-2.patch @@ -0,0 +1,229 @@ +commit ff8714269c9312d9164456279a56b6f6c47e2771 +Author: Torvald Riegel +Date: Sun Sep 14 20:04:54 2014 +0200 + + Add atomic operations similar to those provided by C11. + +Index: glibc-2.17-c758a686/include/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/atomic.h ++++ glibc-2.17-c758a686/include/atomic.h +@@ -542,6 +542,218 @@ + ({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; }) + #endif + ++/* This is equal to 1 iff the architecture supports 64b atomic operations. */ ++#ifndef __HAVE_64B_ATOMICS ++#error Unable to determine if 64-bit atomics are present. ++#endif ++ ++/* The following functions are a subset of the atomic operations provided by ++ C11. Usually, a function named atomic_OP_MO(args) is equivalent to C11's ++ atomic_OP_explicit(args, memory_order_MO); exceptions noted below. */ ++ ++/* Each arch can request to use compiler built-ins for C11 atomics. If it ++ does, all atomics will be based on these. */ ++#if USE_ATOMIC_COMPILER_BUILTINS ++ ++/* We require 32b atomic operations; some archs also support 64b atomic ++ operations. */ ++void __atomic_link_error (void); ++# if __HAVE_64B_ATOMICS == 1 ++# define __atomic_check_size(mem) \ ++ if ((sizeof (*mem) != 4) && (sizeof (*mem) != 8)) \ ++ __atomic_link_error (); ++# else ++# define __atomic_check_size(mem) \ ++ if (sizeof (*mem) != 4) \ ++ __atomic_link_error (); ++# endif ++ ++# define atomic_thread_fence_acquire() \ ++ __atomic_thread_fence (__ATOMIC_ACQUIRE) ++# define atomic_thread_fence_release() \ ++ __atomic_thread_fence (__ATOMIC_RELEASE) ++# define atomic_thread_fence_seq_cst() \ ++ __atomic_thread_fence (__ATOMIC_SEQ_CST) ++ ++# define atomic_load_relaxed(mem) \ ++ ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_RELAXED); }) ++# define atomic_load_acquire(mem) \ ++ ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_ACQUIRE); }) ++ ++# define atomic_store_relaxed(mem, val) \ ++ do { \ ++ __atomic_check_size((mem)); \ ++ __atomic_store_n ((mem), (val), __ATOMIC_RELAXED); \ ++ } while (0) ++# define atomic_store_release(mem, val) \ ++ do { \ ++ __atomic_check_size((mem)); \ ++ __atomic_store_n ((mem), (val), __ATOMIC_RELEASE); \ ++ } while (0) ++ ++/* On failure, this CAS has memory_order_relaxed semantics. */ ++# define atomic_compare_exchange_weak_relaxed(mem, expected, desired) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_compare_exchange_n ((mem), (expected), (desired), 1, \ ++ __ATOMIC_RELAXED, __ATOMIC_RELAXED); }) ++# define atomic_compare_exchange_weak_acquire(mem, expected, desired) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_compare_exchange_n ((mem), (expected), (desired), 1, \ ++ __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); }) ++# define atomic_compare_exchange_weak_release(mem, expected, desired) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_compare_exchange_n ((mem), (expected), (desired), 1, \ ++ __ATOMIC_RELEASE, __ATOMIC_RELAXED); }) ++ ++# define atomic_exchange_acquire(mem, desired) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_exchange_n ((mem), (desired), __ATOMIC_ACQUIRE); }) ++# define atomic_exchange_release(mem, desired) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_exchange_n ((mem), (desired), __ATOMIC_RELEASE); }) ++ ++# define atomic_fetch_add_relaxed(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_add ((mem), (operand), __ATOMIC_RELAXED); }) ++# define atomic_fetch_add_acquire(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQUIRE); }) ++# define atomic_fetch_add_release(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_add ((mem), (operand), __ATOMIC_RELEASE); }) ++# define atomic_fetch_add_acq_rel(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQ_REL); }) ++ ++# define atomic_fetch_and_acquire(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_and ((mem), (operand), __ATOMIC_ACQUIRE); }) ++ ++# define atomic_fetch_or_relaxed(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_or ((mem), (operand), __ATOMIC_RELAXED); }) ++# define atomic_fetch_or_acquire(mem, operand) \ ++ ({ __atomic_check_size((mem)); \ ++ __atomic_fetch_or ((mem), (operand), __ATOMIC_ACQUIRE); }) ++ ++#else /* !USE_ATOMIC_COMPILER_BUILTINS */ ++ ++/* By default, we assume that read, write, and full barriers are equivalent ++ to acquire, release, and seq_cst barriers. Archs for which this does not ++ hold have to provide custom definitions of the fences. */ ++# ifndef atomic_thread_fence_acquire ++# define atomic_thread_fence_acquire() atomic_read_barrier () ++# endif ++# ifndef atomic_thread_fence_release ++# define atomic_thread_fence_release() atomic_write_barrier () ++# endif ++# ifndef atomic_thread_fence_seq_cst ++# define atomic_thread_fence_seq_cst() atomic_full_barrier () ++# endif ++ ++# ifndef atomic_load_relaxed ++# define atomic_load_relaxed(mem) \ ++ ({ __typeof (*(mem)) __atg100_val; \ ++ __asm ("" : "=r" (__atg100_val) : "0" (*(mem))); \ ++ __atg100_val; }) ++# endif ++# ifndef atomic_load_acquire ++# define atomic_load_acquire(mem) \ ++ ({ __typeof (*(mem)) __atg101_val = atomic_load_relaxed (mem); \ ++ atomic_thread_fence_acquire (); \ ++ __atg101_val; }) ++# endif ++ ++# ifndef atomic_store_relaxed ++/* XXX Use inline asm here? */ ++# define atomic_store_relaxed(mem, val) do { *(mem) = (val); } while (0) ++# endif ++# ifndef atomic_store_release ++# define atomic_store_release(mem, val) \ ++ do { \ ++ atomic_thread_fence_release (); \ ++ atomic_store_relaxed ((mem), (val)); \ ++ } while (0) ++# endif ++ ++/* On failure, this CAS has memory_order_relaxed semantics. */ ++/* XXX This potentially has one branch more than necessary, but archs ++ currently do not define a CAS that returns both the previous value and ++ the success flag. */ ++# ifndef atomic_compare_exchange_weak_acquire ++# define atomic_compare_exchange_weak_acquire(mem, expected, desired) \ ++ ({ typeof (*(expected)) __atg102_expected = *(expected); \ ++ *(expected) = \ ++ atomic_compare_and_exchange_val_acq ((mem), (desired), *(expected)); \ ++ *(expected) == __atg102_expected; }) ++# endif ++# ifndef atomic_compare_exchange_weak_relaxed ++/* XXX Fall back to CAS with acquire MO because archs do not define a weaker ++ CAS. */ ++# define atomic_compare_exchange_weak_relaxed(mem, expected, desired) \ ++ atomic_compare_exchange_weak_acquire ((mem), (expected), (desired)) ++# endif ++# ifndef atomic_compare_exchange_weak_release ++# define atomic_compare_exchange_weak_release(mem, expected, desired) \ ++ ({ typeof (*(expected)) __atg103_expected = *(expected); \ ++ *(expected) = \ ++ atomic_compare_and_exchange_val_rel ((mem), (desired), *(expected)); \ ++ *(expected) == __atg103_expected; }) ++# endif ++ ++# ifndef atomic_exchange_acquire ++# define atomic_exchange_acquire(mem, val) \ ++ atomic_exchange_acq ((mem), (val)) ++# endif ++# ifndef atomic_exchange_release ++# define atomic_exchange_release(mem, val) \ ++ atomic_exchange_rel ((mem), (val)) ++# endif ++ ++# ifndef atomic_fetch_add_acquire ++# define atomic_fetch_add_acquire(mem, operand) \ ++ atomic_exchange_and_add_acq ((mem), (operand)) ++# endif ++# ifndef atomic_fetch_add_relaxed ++/* XXX Fall back to acquire MO because the MO semantics of ++ atomic_exchange_and_add are not documented; the generic version falls back ++ to atomic_exchange_and_add_acq if atomic_exchange_and_add is not defined, ++ and vice versa. */ ++# define atomic_fetch_add_relaxed(mem, operand) \ ++ atomic_fetch_add_acquire ((mem), (operand)) ++# endif ++# ifndef atomic_fetch_add_release ++# define atomic_fetch_add_release(mem, operand) \ ++ atomic_exchange_and_add_rel ((mem), (operand)) ++# endif ++# ifndef atomic_fetch_add_acq_rel ++# define atomic_fetch_add_acq_rel(mem, operand) \ ++ ({ atomic_thread_fence_release (); \ ++ atomic_exchange_and_add_acq ((mem), (operand)); }) ++# endif ++ ++/* XXX The default for atomic_and_val has acquire semantics, but this is not ++ documented. */ ++# ifndef atomic_fetch_and_acquire ++# define atomic_fetch_and_acquire(mem, operand) \ ++ atomic_and_val ((mem), (operand)) ++# endif ++ ++/* XXX The default for atomic_or_val has acquire semantics, but this is not ++ documented. */ ++# ifndef atomic_fetch_or_acquire ++# define atomic_fetch_or_acquire(mem, operand) \ ++ atomic_or_val ((mem), (operand)) ++# endif ++/* XXX Fall back to acquire MO because archs do not define a weaker ++ atomic_or_val. */ ++# ifndef atomic_fetch_or_relaxed ++# define atomic_fetch_or_relaxed(mem, operand) \ ++ atomic_fetch_or_acquire ((mem), (operand)) ++# endif ++ ++#endif /* !USE_ATOMIC_COMPILER_BUILTINS */ ++ + + #ifndef atomic_delay + # define atomic_delay() do { /* nothing */ } while (0) diff --git a/SOURCES/glibc-rh1027348-3.patch b/SOURCES/glibc-rh1027348-3.patch new file mode 100644 index 00000000..cc72784b --- /dev/null +++ b/SOURCES/glibc-rh1027348-3.patch @@ -0,0 +1,144 @@ +commit 88ed594f5d431d855256edbe7e886c8cf4b575dc +Author: Roland McGrath +Date: Tue May 19 15:04:41 2015 -0700 + + BZ#18434: Fix sem_post EOVERFLOW check for [!__HAVE_64B_ATOMICS]. + +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -224,6 +224,7 @@ tests = tst-typesizes \ + tst-key1 tst-key2 tst-key3 tst-key4 \ + tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \ + tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 tst-sem13 tst-sem14 \ ++ tst-sem15 \ + tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \ + tst-align tst-align2 tst-align3 \ + tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ +Index: glibc-2.17-c758a686/nptl/tst-sem15.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-sem15.c +@@ -0,0 +1,99 @@ ++/* Test for SEM_VALUE_MAX overflow detection: BZ #18434. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++static int ++do_test (void) ++{ ++ sem_t s; ++ ++ if (sem_init (&s, 0, SEM_VALUE_MAX)) ++ { ++ printf ("sem_init: %m\n"); ++ return 1; ++ } ++ ++ int result = 0; ++ ++ int value = 0xdeadbeef; ++ if (sem_getvalue (&s, &value)) ++ { ++ printf ("sem_getvalue: %m\n"); ++ result = 1; ++ } ++ else ++ { ++ printf ("sem_getvalue after init: %d\n", value); ++ if (value != SEM_VALUE_MAX) ++ { ++ printf ("\tshould be %d\n", SEM_VALUE_MAX); ++ result = 1; ++ } ++ } ++ ++ errno = 0; ++ if (sem_post(&s) == 0) ++ { ++ puts ("sem_post at SEM_VALUE_MAX succeeded!"); ++ result = 1; ++ } ++ else ++ { ++ printf ("sem_post at SEM_VALUE_MAX: %m (%d)\n", errno); ++ if (errno != EOVERFLOW) ++ { ++ printf ("\tshould be %s (EOVERFLOW = %d)\n", ++ strerror (EOVERFLOW), EOVERFLOW); ++ result = 1; ++ } ++ } ++ ++ value = 0xbad1d00d; ++ if (sem_getvalue (&s, &value)) ++ { ++ printf ("sem_getvalue: %m\n"); ++ result = 1; ++ } ++ else ++ { ++ printf ("sem_getvalue after post: %d\n", value); ++ if (value != SEM_VALUE_MAX) ++ { ++ printf ("\tshould be %d\n", SEM_VALUE_MAX); ++ result = 1; ++ } ++ } ++ ++ if (sem_destroy (&s)) ++ { ++ printf ("sem_destroy: %m\n"); ++ result = 1; ++ } ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_post.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c +@@ -83,14 +83,14 @@ __new_sem_post (sem_t *sem) + unsigned int v = atomic_load_relaxed (&isem->value); + do + { +- if ((v << SEM_VALUE_SHIFT) == SEM_VALUE_MAX) ++ if ((v >> SEM_VALUE_SHIFT) == SEM_VALUE_MAX) + { + __set_errno (EOVERFLOW); + return -1; + } + } +- while (!atomic_compare_exchange_weak_release (&isem->value, +- &v, v + (1 << SEM_VALUE_SHIFT))); ++ while (!atomic_compare_exchange_weak_release ++ (&isem->value, &v, v + (1 << SEM_VALUE_SHIFT))); + + /* If there is any potentially blocked waiter, wake one of them. */ + if ((v & SEM_NWAITERS_MASK) != 0) diff --git a/SOURCES/glibc-rh1027348-4.patch b/SOURCES/glibc-rh1027348-4.patch new file mode 100644 index 00000000..b8dffcc2 --- /dev/null +++ b/SOURCES/glibc-rh1027348-4.patch @@ -0,0 +1,105 @@ +commit c2f5813ae0a68f6c6d69e66dac2da6e46b9df034 +Author: Joseph Myers +Date: Wed Mar 18 17:05:38 2015 +0000 + + Make sem_timedwait use FUTEX_CLOCK_REALTIME (bug 18138). + + sem_timedwait converts absolute timeouts to relative to pass them to + the futex syscall. (Before the recent reimplementation, on x86_64 it + used FUTEX_CLOCK_REALTIME, but not on other architectures.) + + Correctly implementing POSIX requirements, however, requires use of + FUTEX_CLOCK_REALTIME; passing a relative timeout to the kernel does + not conform to POSIX. The POSIX specification for sem_timedwait says + "The timeout shall be based on the CLOCK_REALTIME clock.". The POSIX + specification for clock_settime says "If the value of the + CLOCK_REALTIME clock is set via clock_settime(), the new value of the + clock shall be used to determine the time of expiration for absolute + time services based upon the CLOCK_REALTIME clock. This applies to the + time at which armed absolute timers expire. If the absolute time + requested at the invocation of such a time service is before the new + value of the clock, the time service shall expire immediately as if + the clock had reached the requested time normally.". If a relative + timeout is passed to the kernel, it is interpreted according to the + CLOCK_MONOTONIC clock, and so fails to meet that POSIX requirement in + the event of clock changes. + + This patch makes sem_timedwait use lll_futex_timed_wait_bitset with + FUTEX_CLOCK_REALTIME when possible, as done in some other places in + NPTL. FUTEX_CLOCK_REALTIME is always available for supported Linux + kernel versions; unavailability of lll_futex_timed_wait_bitset is only + an issue for hppa (an issue noted in + , and fixed by the + unreviewed + that + removes the hppa lowlevellock.h completely). + + In the FUTEX_CLOCK_REALTIME case, the glibc code still needs to check + for negative tv_sec and handle that as timeout, because the Linux + kernel returns EINVAL not ETIMEDOUT for that case, so resulting in + failures of nptl/tst-abstime and nptl/tst-sem13 in the absence of that + check. If we're trying to distinguish between Linux-specific and + generic-futex NPTL code, I suppose having this in an nptl/ file isn't + ideal, but there doesn't seem to be any better place at present. + + It's not possible to add a testcase for this issue to the testsuite + because of the requirement to change the system clock as part of a + test (this is a case where testing would require some form of + container, with root in that container, and one whose CLOCK_REALTIME + is isolated from that of the host; I'm not sure what forms of + containers, short of a full virtual machine, provide that clock + isolation). + + Tested for x86_64. Also tested for powerpc with the testcase included + in the bug. + + [BZ #18138] + * nptl/sem_waitcommon.c: Include . + (futex_abstimed_wait) + [__ASSUME_FUTEX_CLOCK_REALTIME && lll_futex_timed_wait_bitset]: + Use lll_futex_timed_wait_bitset with FUTEX_CLOCK_REALTIME instead + of lll_futex_timed_wait. + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c +@@ -17,6 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include + #include + #include +@@ -45,6 +46,13 @@ futex_abstimed_wait (unsigned int* futex + } + else + { ++#if (defined __ASSUME_FUTEX_CLOCK_REALTIME \ ++ && defined lll_futex_timed_wait_bitset) ++ /* The Linux kernel returns EINVAL for this, but in userspace ++ such a value is valid. */ ++ if (abstime->tv_sec < 0) ++ return ETIMEDOUT; ++#else + struct timeval tv; + struct timespec rt; + int sec, nsec; +@@ -68,9 +76,16 @@ futex_abstimed_wait (unsigned int* futex + /* Do wait. */ + rt.tv_sec = sec; + rt.tv_nsec = nsec; ++#endif + if (cancel) + oldtype = __pthread_enable_asynccancel (); ++#if (defined __ASSUME_FUTEX_CLOCK_REALTIME \ ++ && defined lll_futex_timed_wait_bitset) ++ err = lll_futex_timed_wait_bitset (futex, expected, abstime, ++ FUTEX_CLOCK_REALTIME, private); ++#else + err = lll_futex_timed_wait (futex, expected, &rt, private); ++#endif + if (cancel) + __pthread_disable_asynccancel (oldtype); + } diff --git a/SOURCES/glibc-rh1027348.patch b/SOURCES/glibc-rh1027348.patch new file mode 100644 index 00000000..326f533a --- /dev/null +++ b/SOURCES/glibc-rh1027348.patch @@ -0,0 +1,3917 @@ +Torvald Riegel's semaphore reimplemenation to fix upstream swbz#12674. + +commit 042e1521c794a945edc43b5bfa7e69ad70420524 +Author: Carlos O'Donell +Date: Wed Jan 21 00:46:16 2015 -0500 + + Fix semaphore destruction (bug 12674). + + This commit fixes semaphore destruction by either using 64b atomic + operations (where available), or by using two separate fields when only + 32b atomic operations are available. In the latter case, we keep a + conservative estimate of whether there are any waiting threads in one + bit of the field that counts the number of available tokens, thus + allowing sem_post to atomically both add a token and determine whether + it needs to call futex_wake. + + See: + https://sourceware.org/ml/libc-alpha/2014-12/msg00155.html + +Notes: +* For x86_64 and i686, rather than movign to the generic lll_futex_wake + we fix the existing versions to return the syscall result and to be + usable as an R-value. +* We also backport fixes for swbz#18434, and swbz#18138. +* We ignore swbz#17870 because it applies only to x32. + +Index: glibc-2.17-c758a686/nptl/DESIGN-sem.txt +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/DESIGN-sem.txt ++++ /dev/null +@@ -1,46 +0,0 @@ +-Semaphores pseudocode +-============================== +- +- int sem_wait(sem_t * sem); +- int sem_trywait(sem_t * sem); +- int sem_post(sem_t * sem); +- int sem_getvalue(sem_t * sem, int * sval); +- +-struct sem_t { +- +- unsigned int count; +- - current semaphore count, also used as a futex +-} +- +-sem_wait(sem_t *sem) +-{ +- for (;;) { +- +- if (atomic_decrement_if_positive(sem->count)) +- break; +- +- futex_wait(&sem->count, 0) +- } +-} +- +-sem_post(sem_t *sem) +-{ +- n = atomic_increment(sem->count); +- // Pass the new value of sem->count +- futex_wake(&sem->count, n + 1); +-} +- +-sem_trywait(sem_t *sem) +-{ +- if (atomic_decrement_if_positive(sem->count)) { +- return 0; +- } else { +- return EAGAIN; +- } +-} +- +-sem_getvalue(sem_t *sem, int *sval) +-{ +- *sval = sem->count; +- read_barrier(); +-} +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -95,7 +95,7 @@ libpthread-routines = nptl-init vars eve + sem_init sem_destroy \ + sem_open sem_close sem_unlink \ + sem_getvalue \ +- sem_wait sem_trywait sem_timedwait sem_post \ ++ sem_wait sem_timedwait sem_post \ + cleanup cleanup_defer cleanup_compat \ + cleanup_defer_compat unwind \ + pt-longjmp pt-cleanup\ +Index: glibc-2.17-c758a686/nptl/sem_getvalue.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sem_getvalue.c ++++ glibc-2.17-c758a686/nptl/sem_getvalue.c +@@ -19,23 +19,37 @@ + #include + #include + #include "semaphoreP.h" ++#include + + + int +-__new_sem_getvalue (sem, sval) +- sem_t *sem; +- int *sval; ++__new_sem_getvalue (sem_t *sem, int *sval) + { + struct new_sem *isem = (struct new_sem *) sem; + + /* XXX Check for valid SEM parameter. */ ++ /* FIXME This uses relaxed MO, even though POSIX specifies that this function ++ should be linearizable. However, its debatable whether linearizability ++ is the right requirement. We need to follow up with POSIX and, if ++ necessary, use a stronger MO here and elsewhere (e.g., potentially ++ release MO in all places where we consume a token). */ + +- *sval = isem->value; ++#if __HAVE_64B_ATOMICS ++ *sval = atomic_load_relaxed (&isem->data) & SEM_VALUE_MASK; ++#else ++ *sval = atomic_load_relaxed (&isem->value) >> SEM_VALUE_SHIFT; ++#endif + + return 0; + } + versioned_symbol (libpthread, __new_sem_getvalue, sem_getvalue, GLIBC_2_1); + #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +-strong_alias (__new_sem_getvalue, __old_sem_getvalue) ++int ++__old_sem_getvalue (sem_t *sem, int *sval) ++{ ++ struct old_sem *isem = (struct old_sem *) sem; ++ *sval = isem->value; ++ return 0; ++} + compat_symbol (libpthread, __old_sem_getvalue, sem_getvalue, GLIBC_2_0); + #endif +Index: glibc-2.17-c758a686/nptl/sem_init.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sem_init.c ++++ glibc-2.17-c758a686/nptl/sem_init.c +@@ -18,17 +18,28 @@ + + #include + #include +-#include + #include + #include "semaphoreP.h" + #include + ++/* Returns FUTEX_PRIVATE if pshared is zero and private futexes are supported; ++ returns FUTEX_SHARED otherwise. ++ TODO Remove when cleaning up the futex API throughout glibc. */ ++static __always_inline int ++futex_private_if_supported (int pshared) ++{ ++ if (pshared != 0) ++ return LLL_SHARED; ++#ifdef __ASSUME_PRIVATE_FUTEX ++ return LLL_PRIVATE; ++#else ++ return THREAD_GETMEM (THREAD_SELF, header.private_futex) ++ ^ FUTEX_PRIVATE_FLAG; ++#endif ++} + + int +-__new_sem_init (sem, pshared, value) +- sem_t *sem; +- int pshared; +- unsigned int value; ++__new_sem_init (sem_t *sem, int pshared, unsigned int value) + { + /* Parameter sanity check. */ + if (__builtin_expect (value > SEM_VALUE_MAX, 0)) +@@ -40,16 +51,15 @@ __new_sem_init (sem, pshared, value) + /* Map to the internal type. */ + struct new_sem *isem = (struct new_sem *) sem; + +- /* Use the values the user provided. */ +- isem->value = value; +-#ifdef __ASSUME_PRIVATE_FUTEX +- isem->private = pshared ? 0 : FUTEX_PRIVATE_FLAG; ++ /* Use the values the caller provided. */ ++#if __HAVE_64B_ATOMICS ++ isem->data = value; + #else +- isem->private = pshared ? 0 : THREAD_GETMEM (THREAD_SELF, +- header.private_futex); ++ isem->value = value << SEM_VALUE_SHIFT; ++ isem->nwaiters = 0; + #endif + +- isem->nwaiters = 0; ++ isem->private = futex_private_if_supported (pshared); + + return 0; + } +Index: glibc-2.17-c758a686/nptl/sem_open.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sem_open.c ++++ glibc-2.17-c758a686/nptl/sem_open.c +@@ -307,9 +307,14 @@ sem_open (const char *name, int oflag, . + struct new_sem newsem; + } sem; + +- sem.newsem.value = value; +- sem.newsem.private = 0; ++#if __HAVE_64B_ATOMICS ++ sem.newsem.data = value; ++#else ++ sem.newsem.value = value << SEM_VALUE_SHIFT; + sem.newsem.nwaiters = 0; ++#endif ++ /* This always is a shared semaphore. */ ++ sem.newsem.private = LLL_SHARED; + + /* Initialize the remaining bytes as well. */ + memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0', +Index: glibc-2.17-c758a686/nptl/tst-sem11.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/tst-sem11.c ++++ glibc-2.17-c758a686/nptl/tst-sem11.c +@@ -34,8 +34,11 @@ main (void) + puts ("sem_init failed"); + return 1; + } +- ++#if __HAVE_64B_ATOMICS ++ if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0) ++#else + if (u.ns.nwaiters != 0) ++#endif + { + puts ("nwaiters not initialized"); + return 1; +@@ -68,7 +71,11 @@ main (void) + goto again; + } + ++#if __HAVE_64B_ATOMICS ++ if ((u.ns.data >> SEM_NWAITERS_SHIFT) != 0) ++#else + if (u.ns.nwaiters != 0) ++#endif + { + puts ("nwaiters not reset"); + return 1; +Index: glibc-2.17-c758a686/nptl/tst-sem13.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/tst-sem13.c ++++ glibc-2.17-c758a686/nptl/tst-sem13.c +@@ -33,9 +33,14 @@ do_test (void) + perror ("sem_timedwait did not fail with EINVAL"); + return 1; + } +- if (u.ns.nwaiters != 0) ++#if __HAVE_64B_ATOMICS ++ unsigned int nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT); ++#else ++ unsigned int nwaiters = u.ns.nwaiters; ++#endif ++ if (nwaiters != 0) + { +- printf ("sem_timedwait modified nwaiters: %ld\n", u.ns.nwaiters); ++ printf ("sem_timedwait modified nwaiters: %d\n", nwaiters); + return 1; + } + +@@ -52,9 +57,14 @@ do_test (void) + perror ("2nd sem_timedwait did not fail with ETIMEDOUT"); + return 1; + } +- if (u.ns.nwaiters != 0) ++#if __HAVE_64B_ATOMICS ++ nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT); ++#else ++ nwaiters = u.ns.nwaiters; ++#endif ++ if (nwaiters != 0) + { +- printf ("2nd sem_timedwait modified nwaiters: %ld\n", u.ns.nwaiters); ++ printf ("2nd sem_timedwait modified nwaiters: %d\n", nwaiters); + return 1; + } + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S ++++ /dev/null +@@ -1,151 +0,0 @@ +-/* Copyright (C) 2002,2003,2005,2007,2008,2011-2012 +- Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +- +- .text +- +- .globl __new_sem_post +- .type __new_sem_post,@function +- .align 16 +-__new_sem_post: +- cfi_startproc +- pushl %ebx +- cfi_adjust_cfa_offset(4) +- cfi_offset(%ebx, -8) +- +- movl 8(%esp), %ebx +- +-#if VALUE == 0 +- movl (%ebx), %eax +-#else +- movl VALUE(%ebx), %eax +-#endif +-0: cmpl $SEM_VALUE_MAX, %eax +- je 3f +- leal 1(%eax), %edx +- LOCK +-#if VALUE == 0 +- cmpxchgl %edx, (%ebx) +-#else +- cmpxchgl %edx, VALUE(%ebx) +-#endif +- jnz 0b +- +- cmpl $0, NWAITERS(%ebx) +- je 2f +- +- movl $FUTEX_WAKE, %ecx +- orl PRIVATE(%ebx), %ecx +- movl $1, %edx +- movl $SYS_futex, %eax +- ENTER_KERNEL +- +- testl %eax, %eax +- js 1f +- +-2: xorl %eax, %eax +- popl %ebx +- cfi_adjust_cfa_offset(-4) +- cfi_restore(%ebx) +- ret +- +- cfi_adjust_cfa_offset(4) +- cfi_offset(%ebx, -8) +-1: +-#ifdef PIC +- SETUP_PIC_REG(bx) +-#else +- movl $4f, %ebx +-4: +-#endif +- addl $_GLOBAL_OFFSET_TABLE_, %ebx +-#ifdef NO_TLS_DIRECT_SEG_REFS +- movl errno@gotntpoff(%ebx), %edx +- addl %gs:0, %edx +- movl $EINVAL, (%edx) +-#else +- movl errno@gotntpoff(%ebx), %edx +- movl $EINVAL, %gs:(%edx) +-#endif +- +- orl $-1, %eax +- popl %ebx +- ret +- +-3: +-#ifdef PIC +- SETUP_PIC_REG(bx) +-#else +- movl $5f, %ebx +-5: +-#endif +- addl $_GLOBAL_OFFSET_TABLE_, %ebx +-#ifdef NO_TLS_DIRECT_SEG_REFS +- movl errno@gotntpoff(%ebx), %edx +- addl %gs:0, %edx +- movl $EOVERFLOW, (%edx) +-#else +- movl errno@gotntpoff(%ebx), %edx +- movl $EOVERFLOW, %gs:(%edx) +-#endif +- +- orl $-1, %eax +- popl %ebx +- cfi_adjust_cfa_offset(-4) +- cfi_restore(%ebx) +- ret +- cfi_endproc +- .size __new_sem_post,.-__new_sem_post +- versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1) +-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +- .global __old_sem_post +- .type __old_sem_post,@function +-__old_sem_post: +- cfi_startproc +- pushl %ebx +- cfi_adjust_cfa_offset(4) +- cfi_offset(%ebx, -8) +- +- movl 8(%esp), %ebx +- LOCK +- addl $1, (%ebx) +- +- movl $SYS_futex, %eax +- movl $FUTEX_WAKE, %ecx +- movl $1, %edx +- ENTER_KERNEL +- +- testl %eax, %eax +- js 1b +- +- xorl %eax, %eax +- popl %ebx +- cfi_adjust_cfa_offset(-4) +- cfi_restore(%ebx) +- ret +- cfi_endproc +- .size __old_sem_post,.-__old_sem_post +- compat_symbol(libpthread, __old_sem_post, sem_post, GLIBC_2_0) +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S ++++ /dev/null +@@ -1,327 +0,0 @@ +-/* Copyright (C) 2002-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +- +-#if VALUE != 0 +-# error "code needs to be rewritten for VALUE != 0" +-#endif +- +- +- .text +- +- .globl sem_timedwait +- .type sem_timedwait,@function +- .align 16 +-sem_timedwait: +-.LSTARTCODE: +- movl 4(%esp), %ecx +- +- movl (%ecx), %eax +-2: testl %eax, %eax +- je 1f +- +- leal -1(%eax), %edx +- LOCK +- cmpxchgl %edx, (%ecx) +- jne 2b +- +- xorl %eax, %eax +- ret +- +- /* Check whether the timeout value is valid. */ +-1: pushl %esi +-.Lpush_esi: +- pushl %edi +-.Lpush_edi: +- pushl %ebx +-.Lpush_ebx: +- subl $12, %esp +-.Lsub_esp: +- +- movl 32(%esp), %edi +- +- /* Check for invalid nanosecond field. */ +- cmpl $1000000000, 4(%edi) +- movl $EINVAL, %esi +- jae .Lerrno_exit +- +- LOCK +- incl NWAITERS(%ecx) +- +-7: xorl %ecx, %ecx +- movl %esp, %ebx +- movl %ecx, %edx +- movl $__NR_gettimeofday, %eax +- ENTER_KERNEL +- +- /* Compute relative timeout. */ +- movl 4(%esp), %eax +- movl $1000, %edx +- mul %edx /* Milli seconds to nano seconds. */ +- movl (%edi), %ecx +- movl 4(%edi), %edx +- subl (%esp), %ecx +- subl %eax, %edx +- jns 5f +- addl $1000000000, %edx +- subl $1, %ecx +-5: testl %ecx, %ecx +- movl $ETIMEDOUT, %esi +- js 6f /* Time is already up. */ +- +- movl %ecx, (%esp) /* Store relative timeout. */ +- movl %edx, 4(%esp) +- +-.LcleanupSTART: +- call __pthread_enable_asynccancel +- movl %eax, 8(%esp) +- +- movl 28(%esp), %ebx /* Load semaphore address. */ +-#if FUTEX_WAIT == 0 +- movl PRIVATE(%ebx), %ecx +-#else +- movl $FUTEX_WAIT, %ecx +- orl PRIVATE(%ebx), %ecx +-#endif +- movl %esp, %esi +- xorl %edx, %edx +- movl $SYS_futex, %eax +- ENTER_KERNEL +- movl %eax, %esi +- +- movl 8(%esp), %eax +- call __pthread_disable_asynccancel +-.LcleanupEND: +- +- testl %esi, %esi +- je 9f +- cmpl $-EWOULDBLOCK, %esi +- jne 3f +- +-9: movl (%ebx), %eax +-8: testl %eax, %eax +- je 7b +- +- leal -1(%eax), %ecx +- LOCK +- cmpxchgl %ecx, (%ebx) +- jne 8b +- +- xorl %eax, %eax +- +- LOCK +- decl NWAITERS(%ebx) +- +-10: addl $12, %esp +-.Ladd_esp: +- popl %ebx +-.Lpop_ebx: +- popl %edi +-.Lpop_edi: +- popl %esi +-.Lpop_esi: +- ret +- +-.Lafter_ret: +-3: negl %esi +-6: +- movl 28(%esp), %ebx /* Load semaphore address. */ +- LOCK +- decl NWAITERS(%ebx) +-.Lerrno_exit: +-#ifdef PIC +- SETUP_PIC_REG(bx) +-#else +- movl $4f, %ebx +-4: +-#endif +- addl $_GLOBAL_OFFSET_TABLE_, %ebx +-#ifdef NO_TLS_DIRECT_SEG_REFS +- movl errno@gotntpoff(%ebx), %edx +- addl %gs:0, %edx +- movl %esi, (%edx) +-#else +- movl errno@gotntpoff(%ebx), %edx +- movl %esi, %gs:(%edx) +-#endif +- +- orl $-1, %eax +- jmp 10b +- .size sem_timedwait,.-sem_timedwait +- +- +- .type sem_wait_cleanup,@function +-sem_wait_cleanup: +- LOCK +- decl NWAITERS(%ebx) +- movl %eax, (%esp) +-.LcallUR: +- call _Unwind_Resume@PLT +- hlt +-.LENDCODE: +- .size sem_wait_cleanup,.-sem_wait_cleanup +- +- +- .section .gcc_except_table,"a",@progbits +-.LexceptSTART: +- .byte 0xff # @LPStart format (omit) +- .byte 0xff # @TType format (omit) +- .byte 0x01 # call-site format +- # DW_EH_PE_uleb128 +- .uleb128 .Lcstend-.Lcstbegin +-.Lcstbegin: +- .uleb128 .LcleanupSTART-.LSTARTCODE +- .uleb128 .LcleanupEND-.LcleanupSTART +- .uleb128 sem_wait_cleanup-.LSTARTCODE +- .uleb128 0 +- .uleb128 .LcallUR-.LSTARTCODE +- .uleb128 .LENDCODE-.LcallUR +- .uleb128 0 +- .uleb128 0 +-.Lcstend: +- +- +- .section .eh_frame,"a",@progbits +-.LSTARTFRAME: +- .long .LENDCIE-.LSTARTCIE # Length of the CIE. +-.LSTARTCIE: +- .long 0 # CIE ID. +- .byte 1 # Version number. +-#ifdef SHARED +- .string "zPLR" # NUL-terminated augmentation +- # string. +-#else +- .string "zPL" # NUL-terminated augmentation +- # string. +-#endif +- .uleb128 1 # Code alignment factor. +- .sleb128 -4 # Data alignment factor. +- .byte 8 # Return address register +- # column. +-#ifdef SHARED +- .uleb128 7 # Augmentation value length. +- .byte 0x9b # Personality: DW_EH_PE_pcrel +- # + DW_EH_PE_sdata4 +- # + DW_EH_PE_indirect +- .long DW.ref.__gcc_personality_v0-. +- .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel +- # + DW_EH_PE_sdata4. +- .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel +- # + DW_EH_PE_sdata4. +-#else +- .uleb128 6 # Augmentation value length. +- .byte 0x0 # Personality: absolute +- .long __gcc_personality_v0 +- .byte 0x0 # LSDA Encoding: absolute +-#endif +- .byte 0x0c # DW_CFA_def_cfa +- .uleb128 4 +- .uleb128 4 +- .byte 0x88 # DW_CFA_offset, column 0x10 +- .uleb128 1 +- .align 4 +-.LENDCIE: +- +- .long .LENDFDE-.LSTARTFDE # Length of the FDE. +-.LSTARTFDE: +- .long .LSTARTFDE-.LSTARTFRAME # CIE pointer. +-#ifdef SHARED +- .long .LSTARTCODE-. # PC-relative start address +- # of the code. +-#else +- .long .LSTARTCODE # Start address of the code. +-#endif +- .long .LENDCODE-.LSTARTCODE # Length of the code. +- .uleb128 4 # Augmentation size +-#ifdef SHARED +- .long .LexceptSTART-. +-#else +- .long .LexceptSTART +-#endif +- +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpush_esi-.LSTARTCODE +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 8 +- .byte 0x86 # DW_CFA_offset %esi +- .uleb128 2 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpush_edi-.Lpush_esi +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 12 +- .byte 0x87 # DW_CFA_offset %edi +- .uleb128 3 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpush_ebx-.Lpush_edi +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 16 +- .byte 0x83 # DW_CFA_offset %ebx +- .uleb128 4 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lsub_esp-.Lpush_ebx +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 28 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Ladd_esp-.Lsub_esp +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 16 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpop_ebx-.Ladd_esp +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 12 +- .byte 0xc3 # DW_CFA_restore %ebx +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpop_edi-.Lpop_ebx +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 8 +- .byte 0xc7 # DW_CFA_restore %edi +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpop_esi-.Lpop_edi +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 4 +- .byte 0xc6 # DW_CFA_restore %esi +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lafter_ret-.Lpop_esi +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 28 +- .byte 0x86 # DW_CFA_offset %esi +- .uleb128 2 +- .byte 0x87 # DW_CFA_offset %edi +- .uleb128 3 +- .byte 0x83 # DW_CFA_offset %ebx +- .uleb128 4 +- .align 4 +-.LENDFDE: +- +- +-#ifdef SHARED +- .hidden DW.ref.__gcc_personality_v0 +- .weak DW.ref.__gcc_personality_v0 +- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits +- .align 4 +- .type DW.ref.__gcc_personality_v0, @object +- .size DW.ref.__gcc_personality_v0, 4 +-DW.ref.__gcc_personality_v0: +- .long __gcc_personality_v0 +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_trywait.S ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* Copyright (C) 2002-2003, 2005, 2007, 2011-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +- +- .text +- +- .globl __new_sem_trywait +- .type __new_sem_trywait,@function +- .align 16 +-__new_sem_trywait: +- movl 4(%esp), %ecx +- +- movl (%ecx), %eax +-2: testl %eax, %eax +- jz 1f +- +- leal -1(%eax), %edx +- LOCK +- cmpxchgl %edx, (%ecx) +- jne 2b +- xorl %eax, %eax +- ret +- +-1: +-#ifdef PIC +- SETUP_PIC_REG(cx) +-#else +- movl $3f, %ecx +-3: +-#endif +- addl $_GLOBAL_OFFSET_TABLE_, %ecx +-#ifdef NO_TLS_DIRECT_SEG_REFS +- movl errno@gotntpoff(%ecx), %edx +- addl %gs:0, %edx +- movl $EAGAIN, (%edx) +-#else +- movl errno@gotntpoff(%ecx), %edx +- movl $EAGAIN, %gs:(%edx) +-#endif +- orl $-1, %eax +- ret +- .size __new_sem_trywait,.-__new_sem_trywait +- versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1) +-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +- .global __old_sem_trywait +-__old_sem_trywait = __new_sem_trywait +- compat_symbol(libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0) +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_wait.S ++++ /dev/null +@@ -1,343 +0,0 @@ +-/* Copyright (C) 2002-2003, 2005, 2007, 2011-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +- +-#if VALUE != 0 +-# error "code needs to be rewritten for VALUE != 0" +-#endif +- +- .text +- +- .globl __new_sem_wait +- .type __new_sem_wait,@function +- .align 16 +-__new_sem_wait: +-.LSTARTCODE: +- pushl %ebx +-.Lpush_ebx: +- pushl %esi +-.Lpush_esi: +- subl $4, %esp +-.Lsub_esp: +- +- movl 16(%esp), %ebx +- +- movl (%ebx), %eax +-2: testl %eax, %eax +- je 1f +- +- leal -1(%eax), %edx +- LOCK +- cmpxchgl %edx, (%ebx) +- jne 2b +-7: xorl %eax, %eax +- +-9: movl 4(%esp), %esi +- movl 8(%esp), %ebx +- addl $12, %esp +-.Ladd_esp: +- ret +- +-.Lafter_ret: +-1: LOCK +- incl NWAITERS(%ebx) +- +-.LcleanupSTART: +-6: call __pthread_enable_asynccancel +- movl %eax, (%esp) +- +-#if FUTEX_WAIT == 0 +- movl PRIVATE(%ebx), %ecx +-#else +- movl $FUTEX_WAIT, %ecx +- orl PRIVATE(%ebx), %ecx +-#endif +- xorl %esi, %esi +- xorl %edx, %edx +- movl $SYS_futex, %eax +- ENTER_KERNEL +- movl %eax, %esi +- +- movl (%esp), %eax +- call __pthread_disable_asynccancel +-.LcleanupEND: +- +- testl %esi, %esi +- je 3f +- cmpl $-EWOULDBLOCK, %esi +- jne 4f +- +-3: +- movl (%ebx), %eax +-5: testl %eax, %eax +- je 6b +- +- leal -1(%eax), %edx +- LOCK +- cmpxchgl %edx, (%ebx) +- jne 5b +- +- LOCK +- decl NWAITERS(%ebx) +- jmp 7b +- +-4: LOCK +- decl NWAITERS(%ebx) +- +- negl %esi +-#ifdef PIC +- SETUP_PIC_REG(bx) +-#else +- movl $8f, %ebx +-8: +-#endif +- addl $_GLOBAL_OFFSET_TABLE_, %ebx +-#ifdef NO_TLS_DIRECT_SEG_REFS +- movl errno@gotntpoff(%ebx), %edx +- addl %gs:0, %edx +- movl %esi, (%edx) +-#else +- movl errno@gotntpoff(%ebx), %edx +- movl %esi, %gs:(%edx) +-#endif +- orl $-1, %eax +- +- jmp 9b +- .size __new_sem_wait,.-__new_sem_wait +- versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1) +- +- +- .type sem_wait_cleanup,@function +-sem_wait_cleanup: +- LOCK +- decl NWAITERS(%ebx) +- movl %eax, (%esp) +-.LcallUR: +- call _Unwind_Resume@PLT +- hlt +-.LENDCODE: +- .size sem_wait_cleanup,.-sem_wait_cleanup +- +- +- .section .gcc_except_table,"a",@progbits +-.LexceptSTART: +- .byte 0xff # @LPStart format (omit) +- .byte 0xff # @TType format (omit) +- .byte 0x01 # call-site format +- # DW_EH_PE_uleb128 +- .uleb128 .Lcstend-.Lcstbegin +-.Lcstbegin: +- .uleb128 .LcleanupSTART-.LSTARTCODE +- .uleb128 .LcleanupEND-.LcleanupSTART +- .uleb128 sem_wait_cleanup-.LSTARTCODE +- .uleb128 0 +- .uleb128 .LcallUR-.LSTARTCODE +- .uleb128 .LENDCODE-.LcallUR +- .uleb128 0 +- .uleb128 0 +-.Lcstend: +- +- +- .section .eh_frame,"a",@progbits +-.LSTARTFRAME: +- .long .LENDCIE-.LSTARTCIE # Length of the CIE. +-.LSTARTCIE: +- .long 0 # CIE ID. +- .byte 1 # Version number. +-#ifdef SHARED +- .string "zPLR" # NUL-terminated augmentation +- # string. +-#else +- .string "zPL" # NUL-terminated augmentation +- # string. +-#endif +- .uleb128 1 # Code alignment factor. +- .sleb128 -4 # Data alignment factor. +- .byte 8 # Return address register +- # column. +-#ifdef SHARED +- .uleb128 7 # Augmentation value length. +- .byte 0x9b # Personality: DW_EH_PE_pcrel +- # + DW_EH_PE_sdata4 +- # + DW_EH_PE_indirect +- .long DW.ref.__gcc_personality_v0-. +- .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel +- # + DW_EH_PE_sdata4. +- .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel +- # + DW_EH_PE_sdata4. +-#else +- .uleb128 6 # Augmentation value length. +- .byte 0x0 # Personality: absolute +- .long __gcc_personality_v0 +- .byte 0x0 # LSDA Encoding: absolute +-#endif +- .byte 0x0c # DW_CFA_def_cfa +- .uleb128 4 +- .uleb128 4 +- .byte 0x88 # DW_CFA_offset, column 0x10 +- .uleb128 1 +- .align 4 +-.LENDCIE: +- +- .long .LENDFDE-.LSTARTFDE # Length of the FDE. +-.LSTARTFDE: +- .long .LSTARTFDE-.LSTARTFRAME # CIE pointer. +-#ifdef SHARED +- .long .LSTARTCODE-. # PC-relative start address +- # of the code. +-#else +- .long .LSTARTCODE # Start address of the code. +-#endif +- .long .LENDCODE-.LSTARTCODE # Length of the code. +- .uleb128 4 # Augmentation size +-#ifdef SHARED +- .long .LexceptSTART-. +-#else +- .long .LexceptSTART +-#endif +- +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpush_ebx-.LSTARTCODE +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 8 +- .byte 0x83 # DW_CFA_offset %ebx +- .uleb128 2 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lpush_esi-.Lpush_ebx +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 12 +- .byte 0x86 # DW_CFA_offset %esi +- .uleb128 3 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lsub_esp-.Lpush_esi +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 16 +- .byte 4 # DW_CFA_advance_loc4 +- .long .Ladd_esp-.Lsub_esp +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 4 +- .byte 0xc3 # DW_CFA_restore %ebx +- .byte 0xc6 # DW_CFA_restore %esi +- .byte 4 # DW_CFA_advance_loc4 +- .long .Lafter_ret-.Ladd_esp +- .byte 14 # DW_CFA_def_cfa_offset +- .uleb128 16 +- .byte 0x83 # DW_CFA_offset %ebx +- .uleb128 2 +- .byte 0x86 # DW_CFA_offset %esi +- .uleb128 3 +- .align 4 +-.LENDFDE: +- +- +-#ifdef SHARED +- .hidden DW.ref.__gcc_personality_v0 +- .weak DW.ref.__gcc_personality_v0 +- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits +- .align 4 +- .type DW.ref.__gcc_personality_v0, @object +- .size DW.ref.__gcc_personality_v0, 4 +-DW.ref.__gcc_personality_v0: +- .long __gcc_personality_v0 +-#endif +- +- +-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +- .section ".text.compat", "ax" +- .global __old_sem_wait +- .type __old_sem_wait,@function +- .align 16 +- cfi_startproc +-__old_sem_wait: +- pushl %ebx +- cfi_adjust_cfa_offset(4) +- pushl %esi +- cfi_adjust_cfa_offset(4) +- subl $4, %esp +- cfi_adjust_cfa_offset(4) +- +- movl 16(%esp), %ebx +- cfi_offset(ebx, -8) +- +- cfi_offset(esi, -12) +-3: movl (%ebx), %eax +-2: testl %eax, %eax +- je 1f +- +- leal -1(%eax), %edx +- LOCK +- cmpxchgl %edx, (%ebx) +- jne 2b +- xorl %eax, %eax +- +-5: movl 4(%esp), %esi +- movl 8(%esp), %ebx +- addl $12, %esp +- cfi_restore(ebx) +- cfi_restore(esi) +- cfi_adjust_cfa_offset(-12) +- ret +- +- cfi_adjust_cfa_offset(12) +- cfi_offset(ebx, -8) +- cfi_offset(esi, -12) +-1: call __pthread_enable_asynccancel +- movl %eax, (%esp) +- +- xorl %esi, %esi +- movl $SYS_futex, %eax +- movl %esi, %ecx +- movl %esi, %edx +- ENTER_KERNEL +- movl %eax, %esi +- +- movl (%esp), %eax +- call __pthread_disable_asynccancel +- +- testl %esi, %esi +- je 3b +- cmpl $-EWOULDBLOCK, %esi +- je 3b +- negl %esi +-#ifdef PIC +- SETUP_PIC_REG(bx) +-#else +- movl $4f, %ebx +-4: +-#endif +- addl $_GLOBAL_OFFSET_TABLE_, %ebx +-#ifdef NO_TLS_DIRECT_SEG_REFS +- movl errno@gotntpoff(%ebx), %edx +- addl %gs:0, %edx +- movl %esi, (%edx) +-#else +- movl errno@gotntpoff(%ebx), %edx +- movl %esi, %gs:(%edx) +-#endif +- orl $-1, %eax +- jmp 5b +- cfi_endproc +- .size __old_sem_wait,.-__old_sem_wait +- compat_symbol(libpthread, __old_sem_wait, sem_wait, GLIBC_2_0) +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_post.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_post.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_timedwait.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_timedwait.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_trywait.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_trywait.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i586/sem_wait.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_wait.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_post.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_post.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_timedwait.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_timedwait.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_trywait.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_trywait.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/sem_wait.S ++++ /dev/null +@@ -1,19 +0,0 @@ +-/* Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include "../i486/sem_wait.S" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/internaltypes.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/internaltypes.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/internaltypes.h +@@ -20,6 +20,8 @@ + #define _INTERNALTYPES_H 1 + + #include ++#include ++#include + + + struct pthread_attr +@@ -141,9 +143,29 @@ struct pthread_key_struct + /* Semaphore variable structure. */ + struct new_sem + { ++#if __HAVE_64B_ATOMICS ++ /* The data field holds both value (in the least-significant 32 bytes) and ++ nwaiters. */ ++# if __BYTE_ORDER == __LITTLE_ENDIAN ++# define SEM_VALUE_OFFSET 0 ++# elif __BYTE_ORDER == __BIG_ENDIAN ++# define SEM_VALUE_OFFSET 1 ++# else ++# error Unsupported byte order. ++# endif ++# define SEM_NWAITERS_SHIFT 32 ++# define SEM_VALUE_MASK (~(unsigned int)0) ++ unsigned long int data; ++ int private; ++ int pad; ++#else ++# define SEM_VALUE_SHIFT 1 ++# define SEM_NWAITERS_MASK ((unsigned int)1) + unsigned int value; + int private; +- unsigned long int nwaiters; ++ int pad; ++ unsigned int nwaiters; ++#endif + }; + + struct old_sem +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/sem_post.c ++++ /dev/null +@@ -1,71 +0,0 @@ +-/* sem_post -- post to a POSIX semaphore. Powerpc version. +- Copyright (C) 2003-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Paul Mackerras , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-int +-__new_sem_post (sem_t *sem) +-{ +- struct new_sem *isem = (struct new_sem *) sem; +- +- __asm __volatile (__lll_rel_instr ::: "memory"); +- atomic_increment (&isem->value); +- __asm __volatile (__lll_acq_instr ::: "memory"); +- if (isem->nwaiters > 0) +- { +- int err = lll_futex_wake (&isem->value, 1, +- isem->private ^ FUTEX_PRIVATE_FLAG); +- if (__builtin_expect (err, 0) < 0) +- { +- __set_errno (-err); +- return -1; +- } +- } +- return 0; +-} +-versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1); +- +-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) +- +-int +-attribute_compat_text_section +-__old_sem_post (sem_t *sem) +-{ +- int *futex = (int *) sem; +- +- __asm __volatile (__lll_rel_instr ::: "memory"); +- (void) atomic_increment_val (futex); +- /* We always have to assume it is a shared semaphore. */ +- int err = lll_futex_wake (futex, 1, LLL_SHARED); +- if (__builtin_expect (err, 0) < 0) +- { +- __set_errno (-err); +- return -1; +- } +- return 0; +-} +- +-compat_symbol (libpthread, __old_sem_post, sem_post, GLIBC_2_0); +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_post.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_post.c +@@ -25,34 +25,78 @@ + + #include + ++/* Wrapper for lll_futex_wake, with error checking. ++ TODO Remove when cleaning up the futex API throughout glibc. */ ++static __always_inline void ++futex_wake (unsigned int* futex, int processes_to_wake, int private) ++{ ++ int res = lll_futex_wake (futex, processes_to_wake, private); ++ /* No error. Ignore the number of woken processes. */ ++ if (res >= 0) ++ return; ++ switch (res) ++ { ++ case -EFAULT: /* Could have happened due to memory reuse. */ ++ case -EINVAL: /* Could be either due to incorrect alignment (a bug in ++ glibc or in the application) or due to memory being ++ reused for a PI futex. We cannot distinguish between the ++ two causes, and one of them is correct use, so we do not ++ act in this case. */ ++ return; ++ case -ENOSYS: /* Must have been caused by a glibc bug. */ ++ /* No other errors are documented at this time. */ ++ default: ++ abort (); ++ } ++} ++ ++ ++/* See sem_wait for an explanation of the algorithm. */ + int + __new_sem_post (sem_t *sem) + { + struct new_sem *isem = (struct new_sem *) sem; ++ int private = isem->private; + +- __typeof (isem->value) cur; ++#if __HAVE_64B_ATOMICS ++ /* Add a token to the semaphore. We use release MO to make sure that a ++ thread acquiring this token synchronizes with us and other threads that ++ added tokens before (the release sequence includes atomic RMW operations ++ by other threads). */ ++ /* TODO Use atomic_fetch_add to make it scale better than a CAS loop? */ ++ unsigned long int d = atomic_load_relaxed (&isem->data); + do + { +- cur = isem->value; +- if (isem->value == SEM_VALUE_MAX) ++ if ((d & SEM_VALUE_MASK) == SEM_VALUE_MAX) + { + __set_errno (EOVERFLOW); + return -1; + } + } +- while (atomic_compare_and_exchange_bool_rel (&isem->value, cur + 1, cur)); ++ while (!atomic_compare_exchange_weak_release (&isem->data, &d, d + 1)); + +- atomic_full_barrier (); +- if (isem->nwaiters > 0) ++ /* If there is any potentially blocked waiter, wake one of them. */ ++ if ((d >> SEM_NWAITERS_SHIFT) > 0) ++ futex_wake (((unsigned int *) &isem->data) + SEM_VALUE_OFFSET, 1, private); ++#else ++ /* Add a token to the semaphore. Similar to 64b version. */ ++ unsigned int v = atomic_load_relaxed (&isem->value); ++ do + { +- int err = lll_futex_wake (&isem->value, 1, +- isem->private ^ FUTEX_PRIVATE_FLAG); +- if (__builtin_expect (err, 0) < 0) ++ if ((v << SEM_VALUE_SHIFT) == SEM_VALUE_MAX) + { +- __set_errno (-err); ++ __set_errno (EOVERFLOW); + return -1; + } + } ++ while (!atomic_compare_exchange_weak_release (&isem->value, ++ &v, v + (1 << SEM_VALUE_SHIFT))); ++ ++ /* If there is any potentially blocked waiter, wake one of them. */ ++ if ((v & SEM_NWAITERS_MASK) != 0) ++ futex_wake (&isem->value, 1, private); ++#endif ++ + return 0; + } + versioned_symbol (libpthread, __new_sem_post, sem_post, GLIBC_2_1); +@@ -65,6 +109,9 @@ __old_sem_post (sem_t *sem) + { + int *futex = (int *) sem; + ++ /* We must need to synchronize with consumers of this token, so the atomic ++ increment must have release MO semantics. */ ++ atomic_write_barrier (); + (void) atomic_increment_val (futex); + /* We always have to assume it is a shared semaphore. */ + int err = lll_futex_wake (futex, 1, LLL_SHARED); +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_timedwait.c +@@ -1,5 +1,5 @@ +-/* sem_timedwait -- wait on a semaphore. Generic futex-using version. +- Copyright (C) 2003, 2007, 2012 Free Software Foundation, Inc. ++/* sem_timedwait -- wait on a semaphore with timeout. ++ Copyright (C) 2003-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Mackerras , 2003. + +@@ -17,42 +17,13 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +- +-extern void __sem_wait_cleanup (void *arg) attribute_hidden; +- +-/* This is in a seperate function in order to make sure gcc +- puts the call site into an exception region, and thus the +- cleanups get properly run. */ +-static int +-__attribute__ ((noinline)) +-do_futex_timed_wait (struct new_sem *isem, struct timespec *rt) +-{ +- int err, oldtype = __pthread_enable_asynccancel (); +- +- err = lll_futex_timed_wait (&isem->value, 0, rt, +- isem->private ^ FUTEX_PRIVATE_FLAG); +- +- __pthread_disable_asynccancel (oldtype); +- return err; +-} ++#include "sem_waitcommon.c" + ++/* This is in a separate file because because sem_timedwait is only provided ++ if __USE_XOPEN2K is defined. */ + int + sem_timedwait (sem_t *sem, const struct timespec *abstime) + { +- struct new_sem *isem = (struct new_sem *) sem; +- int err; +- +- if (atomic_decrement_if_positive (&isem->value) > 0) +- return 0; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + { +@@ -60,57 +31,8 @@ sem_timedwait (sem_t *sem, const struct + return -1; + } + +- atomic_increment (&isem->nwaiters); +- +- pthread_cleanup_push (__sem_wait_cleanup, isem); +- +- while (1) +- { +- struct timeval tv; +- struct timespec rt; +- int sec, nsec; +- +- /* Get the current time. */ +- __gettimeofday (&tv, NULL); +- +- /* Compute relative timeout. */ +- sec = abstime->tv_sec - tv.tv_sec; +- nsec = abstime->tv_nsec - tv.tv_usec * 1000; +- if (nsec < 0) +- { +- nsec += 1000000000; +- --sec; +- } +- +- /* Already timed out? */ +- if (sec < 0) +- { +- __set_errno (ETIMEDOUT); +- err = -1; +- break; +- } +- +- /* Do wait. */ +- rt.tv_sec = sec; +- rt.tv_nsec = nsec; +- err = do_futex_timed_wait(isem, &rt); +- if (err != 0 && err != -EWOULDBLOCK) +- { +- __set_errno (-err); +- err = -1; +- break; +- } +- +- if (atomic_decrement_if_positive (&isem->value) > 0) +- { +- err = 0; +- break; +- } +- } +- +- pthread_cleanup_pop (0); +- +- atomic_decrement (&isem->nwaiters); +- +- return err; ++ if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0) ++ return 0; ++ else ++ return __new_sem_wait_slow((struct new_sem *) sem, abstime); + } +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_trywait.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_trywait.c ++++ /dev/null +@@ -1,49 +0,0 @@ +-/* sem_trywait -- wait on a semaphore. Generic futex-using version. +- Copyright (C) 2003 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Paul Mackerras , 2003. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include +- +- +-int +-__new_sem_trywait (sem_t *sem) +-{ +- int *futex = (int *) sem; +- int val; +- +- if (*futex > 0) +- { +- val = atomic_decrement_if_positive (futex); +- if (val > 0) +- return 0; +- } +- +- __set_errno (EAGAIN); +- return -1; +-} +-versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1); +-#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) +-strong_alias (__new_sem_trywait, __old_sem_trywait) +-compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0); +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_wait.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sem_wait.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_wait.c +@@ -17,79 +17,18 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +- +-void +-attribute_hidden +-__sem_wait_cleanup (void *arg) +-{ +- struct new_sem *isem = (struct new_sem *) arg; +- +- atomic_decrement (&isem->nwaiters); +-} +- +-/* This is in a seperate function in order to make sure gcc +- puts the call site into an exception region, and thus the +- cleanups get properly run. */ +-static int +-__attribute__ ((noinline)) +-do_futex_wait (struct new_sem *isem) +-{ +- int err, oldtype = __pthread_enable_asynccancel (); +- +- err = lll_futex_wait (&isem->value, 0, isem->private ^ FUTEX_PRIVATE_FLAG); +- +- __pthread_disable_asynccancel (oldtype); +- return err; +-} ++#include "sem_waitcommon.c" + + int + __new_sem_wait (sem_t *sem) + { +- struct new_sem *isem = (struct new_sem *) sem; +- int err; +- +- if (atomic_decrement_if_positive (&isem->value) > 0) ++ if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0) + return 0; +- +- atomic_increment (&isem->nwaiters); +- +- pthread_cleanup_push (__sem_wait_cleanup, isem); +- +- while (1) +- { +- err = do_futex_wait(isem); +- if (err != 0 && err != -EWOULDBLOCK) +- { +- __set_errno (-err); +- err = -1; +- break; +- } +- +- if (atomic_decrement_if_positive (&isem->value) > 0) +- { +- err = 0; +- break; +- } +- } +- +- pthread_cleanup_pop (0); +- +- atomic_decrement (&isem->nwaiters); +- +- return err; ++ else ++ return __new_sem_wait_slow((struct new_sem *) sem, NULL); + } + versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1); + +- + #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) + int + attribute_compat_text_section +@@ -120,3 +59,34 @@ __old_sem_wait (sem_t *sem) + + compat_symbol (libpthread, __old_sem_wait, sem_wait, GLIBC_2_0); + #endif ++ ++int ++__new_sem_trywait (sem_t *sem) ++{ ++ /* We must not fail spuriously, so require a definitive result even if this ++ may lead to a long execution time. */ ++ if (__new_sem_wait_fast ((struct new_sem *) sem, 1) == 0) ++ return 0; ++ __set_errno (EAGAIN); ++ return -1; ++} ++versioned_symbol (libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1); ++#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_1) ++int ++__old_sem_trywait (sem_t *sem) ++{ ++ int *futex = (int *) sem; ++ int val; ++ ++ if (*futex > 0) ++ { ++ val = atomic_decrement_if_positive (futex); ++ if (val > 0) ++ return 0; ++ } ++ ++ __set_errno (EAGAIN); ++ return -1; ++} ++compat_symbol (libpthread, __old_sem_trywait, sem_trywait, GLIBC_2_0); ++#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c +@@ -0,0 +1,467 @@ ++/* sem_waitcommon -- wait on a semaphore, shared code. ++ Copyright (C) 2003-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Paul Mackerras , 2003. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* Wrapper for lll_futex_wait with absolute timeout and error checking. ++ TODO Remove when cleaning up the futex API throughout glibc. */ ++static __always_inline int ++futex_abstimed_wait (unsigned int* futex, unsigned int expected, ++ const struct timespec* abstime, int private, bool cancel) ++{ ++ int err, oldtype; ++ if (abstime == NULL) ++ { ++ if (cancel) ++ oldtype = __pthread_enable_asynccancel (); ++ err = lll_futex_wait (futex, expected, private); ++ if (cancel) ++ __pthread_disable_asynccancel (oldtype); ++ } ++ else ++ { ++ struct timeval tv; ++ struct timespec rt; ++ int sec, nsec; ++ ++ /* Get the current time. */ ++ __gettimeofday (&tv, NULL); ++ ++ /* Compute relative timeout. */ ++ sec = abstime->tv_sec - tv.tv_sec; ++ nsec = abstime->tv_nsec - tv.tv_usec * 1000; ++ if (nsec < 0) ++ { ++ nsec += 1000000000; ++ --sec; ++ } ++ ++ /* Already timed out? */ ++ if (sec < 0) ++ return ETIMEDOUT; ++ ++ /* Do wait. */ ++ rt.tv_sec = sec; ++ rt.tv_nsec = nsec; ++ if (cancel) ++ oldtype = __pthread_enable_asynccancel (); ++ err = lll_futex_timed_wait (futex, expected, &rt, private); ++ if (cancel) ++ __pthread_disable_asynccancel (oldtype); ++ } ++ switch (err) ++ { ++ case 0: ++ case -EAGAIN: ++ case -EINTR: ++ case -ETIMEDOUT: ++ return -err; ++ ++ case -EFAULT: /* Must have been caused by a glibc or application bug. */ ++ case -EINVAL: /* Either due to wrong alignment or due to the timeout not ++ being normalized. Must have been caused by a glibc or ++ application bug. */ ++ case -ENOSYS: /* Must have been caused by a glibc bug. */ ++ /* No other errors are documented at this time. */ ++ default: ++ abort (); ++ } ++} ++ ++/* Wrapper for lll_futex_wake, with error checking. ++ TODO Remove when cleaning up the futex API throughout glibc. */ ++static __always_inline void ++futex_wake (unsigned int* futex, int processes_to_wake, int private) ++{ ++ int res = lll_futex_wake (futex, processes_to_wake, private); ++ /* No error. Ignore the number of woken processes. */ ++ if (res >= 0) ++ return; ++ switch (res) ++ { ++ case -EFAULT: /* Could have happened due to memory reuse. */ ++ case -EINVAL: /* Could be either due to incorrect alignment (a bug in ++ glibc or in the application) or due to memory being ++ reused for a PI futex. We cannot distinguish between the ++ two causes, and one of them is correct use, so we do not ++ act in this case. */ ++ return; ++ case -ENOSYS: /* Must have been caused by a glibc bug. */ ++ /* No other errors are documented at this time. */ ++ default: ++ abort (); ++ } ++} ++ ++ ++/* The semaphore provides two main operations: sem_post adds a token to the ++ semaphore; sem_wait grabs a token from the semaphore, potentially waiting ++ until there is a token available. A sem_wait needs to synchronize with ++ the sem_post that provided the token, so that whatever lead to the sem_post ++ happens before the code after sem_wait. ++ ++ Conceptually, available tokens can simply be counted; let's call that the ++ value of the semaphore. However, we also want to know whether there might ++ be a sem_wait that is blocked on the value because it was zero (using a ++ futex with the value being the futex variable); if there is no blocked ++ sem_wait, sem_post does not need to execute a futex_wake call. Therefore, ++ we also need to count the number of potentially blocked sem_wait calls ++ (which we call nwaiters). ++ ++ What makes this tricky is that POSIX requires that a semaphore can be ++ destroyed as soon as the last remaining sem_wait has returned, and no ++ other sem_wait or sem_post calls are executing concurrently. However, the ++ sem_post call whose token was consumed by the last sem_wait is considered ++ to have finished once it provided the token to the sem_wait. ++ Thus, sem_post must not access the semaphore struct anymore after it has ++ made a token available; IOW, it needs to be able to atomically provide ++ a token and check whether any blocked sem_wait calls might exist. ++ ++ This is straightforward to do if the architecture provides 64b atomics ++ because we can just put both the value and nwaiters into one variable that ++ we access atomically: This is the data field, the value is in the ++ least-significant 32 bits, and nwaiters in the other bits. When sem_post ++ makes a value available, it can atomically check nwaiters. ++ ++ If we have only 32b atomics available, we cannot put both nwaiters and ++ value into one 32b value because then we might have too few bits for both ++ of those counters. Therefore, we need to use two distinct fields. ++ ++ To allow sem_post to atomically make a token available and check for ++ blocked sem_wait calls, we use one bit in value to indicate whether ++ nwaiters is nonzero. That allows sem_post to use basically the same ++ algorithm as with 64b atomics, but requires sem_wait to update the bit; it ++ can't do this atomically with another access to nwaiters, but it can compute ++ a conservative value for the bit because it's benign if the bit is set ++ even if nwaiters is zero (all we get is an unnecessary futex wake call by ++ sem_post). ++ Specifically, sem_wait will unset the bit speculatively if it believes that ++ there is no other concurrently executing sem_wait. If it misspeculated, ++ it will have to clean up by waking any other sem_wait call (i.e., what ++ sem_post would do otherwise). This does not conflict with the destruction ++ requirement because the semaphore must not be destructed while any sem_wait ++ is still executing. */ ++ ++/* Set this to true if you assume that, in contrast to current Linux futex ++ documentation, lll_futex_wake can return -EINTR only if interrupted by a ++ signal, not spuriously due to some other reason. ++ TODO Discuss EINTR conditions with the Linux kernel community. For ++ now, we set this to true to not change behavior of semaphores compared ++ to previous glibc builds. */ ++static const int sem_assume_only_signals_cause_futex_EINTR = 1; ++ ++#if !__HAVE_64B_ATOMICS ++static void ++__sem_wait_32_finish (struct new_sem *sem); ++#endif ++ ++static void ++__sem_wait_cleanup (void *arg) ++{ ++ struct new_sem *sem = (struct new_sem *) arg; ++ ++#if __HAVE_64B_ATOMICS ++ /* Stop being registered as a waiter. See below for MO. */ ++ atomic_fetch_add_relaxed (&sem->data, -(1UL << SEM_NWAITERS_SHIFT)); ++#else ++ __sem_wait_32_finish (sem); ++#endif ++} ++ ++/* Wait until at least one token is available, possibly with a timeout. ++ This is in a separate function in order to make sure gcc ++ puts the call site into an exception region, and thus the ++ cleanups get properly run. TODO still necessary? Other futex_wait ++ users don't seem to need it. */ ++static int ++__attribute__ ((noinline)) ++do_futex_wait (struct new_sem *sem, const struct timespec *abstime) ++{ ++ int err; ++ ++#if __HAVE_64B_ATOMICS ++ err = futex_abstimed_wait ((unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, ++ abstime, sem->private, true); ++#else ++ err = futex_abstimed_wait (&sem->value, SEM_NWAITERS_MASK, abstime, ++ sem->private, true); ++#endif ++ ++ return err; ++} ++ ++/* Fast path: Try to grab a token without blocking. */ ++static int ++__new_sem_wait_fast (struct new_sem *sem, int definitive_result) ++{ ++ /* We need acquire MO if we actually grab a token, so that this ++ synchronizes with all token providers (i.e., the RMW operation we read ++ from or all those before it in modification order; also see sem_post). ++ We do not need to guarantee any ordering if we observed that there is ++ no token (POSIX leaves it unspecified whether functions that fail ++ synchronize memory); thus, relaxed MO is sufficient for the initial load ++ and the failure path of the CAS. If the weak CAS fails and we need a ++ definitive result, retry. */ ++#if __HAVE_64B_ATOMICS ++ unsigned long d = atomic_load_relaxed (&sem->data); ++ do ++ { ++ if ((d & SEM_VALUE_MASK) == 0) ++ break; ++ if (atomic_compare_exchange_weak_acquire (&sem->data, &d, d - 1)) ++ return 0; ++ } ++ while (definitive_result); ++ return -1; ++#else ++ unsigned int v = atomic_load_relaxed (&sem->value); ++ do ++ { ++ if ((v >> SEM_VALUE_SHIFT) == 0) ++ break; ++ if (atomic_compare_exchange_weak_acquire (&sem->value, ++ &v, v - (1 << SEM_VALUE_SHIFT))) ++ return 0; ++ } ++ while (definitive_result); ++ return -1; ++#endif ++} ++ ++/* Slow path that blocks. */ ++static int ++__attribute__ ((noinline)) ++__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime) ++{ ++ int err = 0; ++ ++#if __HAVE_64B_ATOMICS ++ /* Add a waiter. Relaxed MO is sufficient because we can rely on the ++ ordering provided by the RMW operations we use. */ ++ unsigned long d = atomic_fetch_add_relaxed (&sem->data, ++ 1UL << SEM_NWAITERS_SHIFT); ++ ++ pthread_cleanup_push (__sem_wait_cleanup, sem); ++ ++ /* Wait for a token to be available. Retry until we can grab one. */ ++ for (;;) ++ { ++ /* If there is no token available, sleep until there is. */ ++ if ((d & SEM_VALUE_MASK) == 0) ++ { ++ err = do_futex_wait (sem, abstime); ++ /* A futex return value of 0 or EAGAIN is due to a real or spurious ++ wake-up, or due to a change in the number of tokens. We retry in ++ these cases. ++ If we timed out, forward this to the caller. ++ EINTR could be either due to being interrupted by a signal, or ++ due to a spurious wake-up. Thus, we cannot distinguish between ++ both, and are not allowed to return EINTR to the caller but have ++ to retry; this is because we may not have been interrupted by a ++ signal. However, if we assume that only signals cause a futex ++ return of EINTR, we forward EINTR to the caller. ++ ++ Retrying on EINTR is technically always allowed because to ++ reliably interrupt sem_wait with a signal, the signal handler ++ must call sem_post (which is AS-Safe). In executions where the ++ signal handler does not do that, the implementation can correctly ++ claim that sem_wait hadn't actually started to execute yet, and ++ thus the signal never actually interrupted sem_wait. We make no ++ timing guarantees, so the program can never observe that sem_wait ++ actually did start to execute. Thus, in a correct program, we ++ can expect a signal that wanted to interrupt the sem_wait to have ++ provided a token, and can just try to grab this token if ++ futex_wait returns EINTR. */ ++ if (err == ETIMEDOUT || ++ (err == EINTR && sem_assume_only_signals_cause_futex_EINTR)) ++ { ++ __set_errno (err); ++ err = -1; ++ /* Stop being registered as a waiter. */ ++ atomic_fetch_add_relaxed (&sem->data, ++ -(1UL << SEM_NWAITERS_SHIFT)); ++ break; ++ } ++ /* Relaxed MO is sufficient; see below. */ ++ d = atomic_load_relaxed (&sem->data); ++ } ++ else ++ { ++ /* Try to grab both a token and stop being a waiter. We need ++ acquire MO so this synchronizes with all token providers (i.e., ++ the RMW operation we read from or all those before it in ++ modification order; also see sem_post). On the failure path, ++ relaxed MO is sufficient because we only eventually need the ++ up-to-date value; the futex_wait or the CAS perform the real ++ work. */ ++ if (atomic_compare_exchange_weak_acquire (&sem->data, ++ &d, d - 1 - (1UL << SEM_NWAITERS_SHIFT))) ++ { ++ err = 0; ++ break; ++ } ++ } ++ } ++ ++ pthread_cleanup_pop (0); ++#else ++ /* The main difference to the 64b-atomics implementation is that we need to ++ access value and nwaiters in separate steps, and that the nwaiters bit ++ in the value can temporarily not be set even if nwaiters is nonzero. ++ We work around incorrectly unsetting the nwaiters bit by letting sem_wait ++ set the bit again and waking the number of waiters that could grab a ++ token. There are two additional properties we need to ensure: ++ (1) We make sure that whenever unsetting the bit, we see the increment of ++ nwaiters by the other thread that set the bit. IOW, we will notice if ++ we make a mistake. ++ (2) When setting the nwaiters bit, we make sure that we see the unsetting ++ of the bit by another waiter that happened before us. This avoids having ++ to blindly set the bit whenever we need to block on it. We set/unset ++ the bit while having incremented nwaiters (i.e., are a registered ++ waiter), and the problematic case only happens when one waiter indeed ++ followed another (i.e., nwaiters was never larger than 1); thus, this ++ works similarly as with a critical section using nwaiters (see the MOs ++ and related comments below). ++ ++ An alternative approach would be to unset the bit after decrementing ++ nwaiters; however, that would result in needing Dekker-like ++ synchronization and thus full memory barriers. We also would not be able ++ to prevent misspeculation, so this alternative scheme does not seem ++ beneficial. */ ++ unsigned int v; ++ ++ /* Add a waiter. We need acquire MO so this synchronizes with the release ++ MO we use when decrementing nwaiters below; it ensures that if another ++ waiter unset the bit before us, we see that and set it again. Also see ++ property (2) above. */ ++ atomic_fetch_add_acquire (&sem->nwaiters, 1); ++ ++ pthread_cleanup_push (__sem_wait_cleanup, sem); ++ ++ /* Wait for a token to be available. Retry until we can grab one. */ ++ /* We do not need any ordering wrt. to this load's reads-from, so relaxed ++ MO is sufficient. The acquire MO above ensures that in the problematic ++ case, we do see the unsetting of the bit by another waiter. */ ++ v = atomic_load_relaxed (&sem->value); ++ do ++ { ++ do ++ { ++ /* We are about to block, so make sure that the nwaiters bit is ++ set. We need release MO on the CAS to ensure that when another ++ waiter unsets the nwaiters bit, it will also observe that we ++ incremented nwaiters in the meantime (also see the unsetting of ++ the bit below). Relaxed MO on CAS failure is sufficient (see ++ above). */ ++ do ++ { ++ if ((v & SEM_NWAITERS_MASK) != 0) ++ break; ++ } ++ while (!atomic_compare_exchange_weak_release (&sem->value, ++ &v, v | SEM_NWAITERS_MASK)); ++ /* If there is no token, wait. */ ++ if ((v >> SEM_VALUE_SHIFT) == 0) ++ { ++ /* See __HAVE_64B_ATOMICS variant. */ ++ err = do_futex_wait(sem, abstime); ++ if (err == ETIMEDOUT || ++ (err == EINTR && sem_assume_only_signals_cause_futex_EINTR)) ++ { ++ __set_errno (err); ++ err = -1; ++ goto error; ++ } ++ err = 0; ++ /* We blocked, so there might be a token now. Relaxed MO is ++ sufficient (see above). */ ++ v = atomic_load_relaxed (&sem->value); ++ } ++ } ++ /* If there is no token, we must not try to grab one. */ ++ while ((v >> SEM_VALUE_SHIFT) == 0); ++ } ++ /* Try to grab a token. We need acquire MO so this synchronizes with ++ all token providers (i.e., the RMW operation we read from or all those ++ before it in modification order; also see sem_post). */ ++ while (!atomic_compare_exchange_weak_acquire (&sem->value, ++ &v, v - (1 << SEM_VALUE_SHIFT))); ++ ++error: ++ pthread_cleanup_pop (0); ++ ++ __sem_wait_32_finish (sem); ++#endif ++ ++ return err; ++} ++ ++/* Stop being a registered waiter (non-64b-atomics code only). */ ++#if !__HAVE_64B_ATOMICS ++static void ++__sem_wait_32_finish (struct new_sem *sem) ++{ ++ /* The nwaiters bit is still set, try to unset it now if this seems ++ necessary. We do this before decrementing nwaiters so that the unsetting ++ is visible to other waiters entering after us. Relaxed MO is sufficient ++ because we are just speculating here; a stronger MO would not prevent ++ misspeculation. */ ++ unsigned int wguess = atomic_load_relaxed (&sem->nwaiters); ++ if (wguess == 1) ++ /* We might be the last waiter, so unset. This needs acquire MO so that ++ it syncronizes with the release MO when setting the bit above; if we ++ overwrite someone else that set the bit, we'll read in the following ++ decrement of nwaiters at least from that release sequence, so we'll ++ see if the other waiter is still active or if another writer entered ++ in the meantime (i.e., using the check below). */ ++ atomic_fetch_and_acquire (&sem->value, ~SEM_NWAITERS_MASK); ++ ++ /* Now stop being a waiter, and see whether our guess was correct. ++ This needs release MO so that it synchronizes with the acquire MO when ++ a waiter increments nwaiters; this makes sure that newer writers see that ++ we reset the waiters_present bit. */ ++ unsigned int wfinal = atomic_fetch_add_release (&sem->nwaiters, -1); ++ if (wfinal > 1 && wguess == 1) ++ { ++ /* We guessed wrong, and so need to clean up after the mistake and ++ unblock any waiters that could have not been woken. There is no ++ additional ordering that we need to set up, so relaxed MO is ++ sufficient. */ ++ unsigned int v = atomic_fetch_or_relaxed (&sem->value, ++ SEM_NWAITERS_MASK); ++ /* If there are available tokens, then wake as many waiters. If there ++ aren't any, then there is no need to wake anyone because there is ++ none to grab for another waiter. If tokens become available ++ subsequently, then the respective sem_post calls will do the wake-up ++ due to us having set the nwaiters bit again. */ ++ v >>= SEM_VALUE_SHIFT; ++ if (v > 0) ++ futex_wake (&sem->value, v, sem->private); ++ } ++} ++#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/structsem.sym +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/structsem.sym ++++ /dev/null +@@ -1,12 +0,0 @@ +-#include +-#include +-#include +-#include +-#include "internaltypes.h" +- +--- +- +-VALUE offsetof (struct new_sem, value) +-PRIVATE offsetof (struct new_sem, private) +-NWAITERS offsetof (struct new_sem, nwaiters) +-SEM_VALUE_MAX SEM_VALUE_MAX +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S ++++ /dev/null +@@ -1,75 +0,0 @@ +-/* Copyright (C) 2002,2003,2005,2007,2008,2011 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +- +- .text +- +- .globl sem_post +- .type sem_post,@function +- .align 16 +-sem_post: +-#if VALUE == 0 +- movl (%rdi), %eax +-#else +- movl VALUE(%rdi), %eax +-#endif +-0: cmpl $SEM_VALUE_MAX, %eax +- je 3f +- leal 1(%rax), %esi +- LOCK +-#if VALUE == 0 +- cmpxchgl %esi, (%rdi) +-#else +- cmpxchgl %esi, VALUE(%rdi) +-#endif +- jnz 0b +- +- LP_OP(cmp) $0, NWAITERS(%rdi) +- je 2f +- +- movl $SYS_futex, %eax +- movl $FUTEX_WAKE, %esi +- orl PRIVATE(%rdi), %esi +- movl $1, %edx +- syscall +- +- testq %rax, %rax +- js 1f +- +-2: xorl %eax, %eax +- retq +- +-1: +- movl $EINVAL, %eax +- jmp 4f +- +-3: +- movl $EOVERFLOW, %eax +- +-4: +- movq errno@gottpoff(%rip), %rdx +- movl %eax, %fs:(%rdx) +- orl $-1, %eax +- retq +- .size sem_post,.-sem_post +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S ++++ /dev/null +@@ -1,380 +0,0 @@ +-/* Copyright (C) 2002,2003,2005,2007,2009,2010,2011 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +- .text +- +- .globl sem_timedwait +- .type sem_timedwait,@function +- .align 16 +-sem_timedwait: +-.LSTARTCODE: +- cfi_startproc +-#ifdef SHARED +- cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, +- DW.ref.__gcc_personality_v0) +- cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) +-#else +- cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0) +- cfi_lsda(DW_EH_PE_udata4, .LexceptSTART) +-#endif +-#if VALUE == 0 +- movl (%rdi), %eax +-#else +- movl VALUE(%rdi), %eax +-#endif +-2: testl %eax, %eax +- je 1f +- +- leaq -1(%rax), %rdx +- LOCK +-#if VALUE == 0 +- cmpxchgl %edx, (%rdi) +-#else +- cmpxchgl %edx, VALUE(%rdi) +-#endif +- jne 2b +- +- xorl %eax, %eax +- retq +- +- /* Check whether the timeout value is valid. */ +-1: cmpq $1000000000, 8(%rsi) +- jae 6f +- +-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME +-# ifdef PIC +- cmpl $0, __have_futex_clock_realtime(%rip) +-# else +- cmpl $0, __have_futex_clock_realtime +-# endif +- je .Lreltmo +-#endif +- +- cmpq $0, (%rsi) +- js 16f +- +- /* This push is only needed to store the sem_t pointer for the +- exception handler. */ +- pushq %rdi +- cfi_adjust_cfa_offset(8) +- +- movq %rsi, %r10 +- +- LOCK +- LP_OP(add) $1, NWAITERS(%rdi) +- +-.LcleanupSTART: +-13: call __pthread_enable_asynccancel +- movl %eax, %r8d +- +-#if VALUE != 0 +- leaq VALUE(%rdi), %rdi +-#endif +- movl $0xffffffff, %r9d +- movl $FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi +- orl PRIVATE(%rdi), %esi +- movl $SYS_futex, %eax +- xorl %edx, %edx +- syscall +- movq %rax, %r9 +-#if VALUE != 0 +- leaq -VALUE(%rdi), %rdi +-#endif +- +- xchgq %r8, %rdi +- call __pthread_disable_asynccancel +-.LcleanupEND: +- movq %r8, %rdi +- +- testq %r9, %r9 +- je 11f +- cmpq $-EWOULDBLOCK, %r9 +- jne 3f +- +-11: +-#if VALUE == 0 +- movl (%rdi), %eax +-#else +- movl VALUE(%rdi), %eax +-#endif +-14: testl %eax, %eax +- je 13b +- +- leaq -1(%rax), %rcx +- LOCK +-#if VALUE == 0 +- cmpxchgl %ecx, (%rdi) +-#else +- cmpxchgl %ecx, VALUE(%rdi) +-#endif +- jne 14b +- +- xorl %eax, %eax +- +-15: LOCK +- LP_OP(sub) $1, NWAITERS(%rdi) +- +- leaq 8(%rsp), %rsp +- cfi_adjust_cfa_offset(-8) +- retq +- +- cfi_adjust_cfa_offset(8) +-3: negq %r9 +- movq errno@gottpoff(%rip), %rdx +- movl %r9d, %fs:(%rdx) +- +- orl $-1, %eax +- jmp 15b +- +- cfi_adjust_cfa_offset(-8) +-6: +- movq errno@gottpoff(%rip), %rdx +- movl $EINVAL, %fs:(%rdx) +- +- orl $-1, %eax +- +- retq +- +-16: +- movq errno@gottpoff(%rip), %rdx +- movl $ETIMEDOUT, %fs:(%rdx) +- +- orl $-1, %eax +- +- retq +- +-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME +-.Lreltmo: +- pushq %r12 +- cfi_adjust_cfa_offset(8) +- cfi_rel_offset(%r12, 0) +- pushq %r13 +- cfi_adjust_cfa_offset(8) +- cfi_rel_offset(%r13, 0) +- pushq %r14 +- cfi_adjust_cfa_offset(8) +- cfi_rel_offset(%r14, 0) +- +-#ifdef __ASSUME_FUTEX_CLOCK_REALTIME +-# define STACKFRAME 8 +-#else +-# define STACKFRAME 24 +-#endif +- subq $STACKFRAME, %rsp +- cfi_adjust_cfa_offset(STACKFRAME) +- +- movq %rdi, %r12 +- movq %rsi, %r13 +- +- LOCK +- LP_OP(add) $1, NWAITERS(%r12) +- +-7: xorl %esi, %esi +- movq %rsp,%rdi +- /* This call works because we directly jump to a system call entry +- which preserves all the registers. */ +- call JUMPTARGET(__gettimeofday) +- +- /* Compute relative timeout. */ +- movq 8(%rsp), %rax +- movl $1000, %edi +- mul %rdi /* Milli seconds to nano seconds. */ +- movq (%r13), %rdi +- movq 8(%r13), %rsi +- subq (%rsp), %rdi +- subq %rax, %rsi +- jns 5f +- addq $1000000000, %rsi +- decq %rdi +-5: testq %rdi, %rdi +- movl $ETIMEDOUT, %r14d +- js 36f /* Time is already up. */ +- +- movq %rdi, (%rsp) /* Store relative timeout. */ +- movq %rsi, 8(%rsp) +- +-.LcleanupSTART2: +- call __pthread_enable_asynccancel +- movl %eax, 16(%rsp) +- +- movq %rsp, %r10 +-# if VALUE == 0 +- movq %r12, %rdi +-# else +- leaq VALUE(%r12), %rdi +-# endif +-# if FUTEX_WAIT == 0 +- movl PRIVATE(%rdi), %esi +-# else +- movl $FUTEX_WAIT, %esi +- orl PRIVATE(%rdi), %esi +-# endif +- movl $SYS_futex, %eax +- xorl %edx, %edx +- syscall +- movq %rax, %r14 +- +- movl 16(%rsp), %edi +- call __pthread_disable_asynccancel +-.LcleanupEND2: +- +- testq %r14, %r14 +- je 9f +- cmpq $-EWOULDBLOCK, %r14 +- jne 33f +- +-9: +-# if VALUE == 0 +- movl (%r12), %eax +-# else +- movl VALUE(%r12), %eax +-# endif +-8: testl %eax, %eax +- je 7b +- +- leaq -1(%rax), %rcx +- LOCK +-# if VALUE == 0 +- cmpxchgl %ecx, (%r12) +-# else +- cmpxchgl %ecx, VALUE(%r12) +-# endif +- jne 8b +- +- xorl %eax, %eax +- +-45: LOCK +- LP_OP(sub) $1, NWAITERS(%r12) +- +- addq $STACKFRAME, %rsp +- cfi_adjust_cfa_offset(-STACKFRAME) +- popq %r14 +- cfi_adjust_cfa_offset(-8) +- cfi_restore(%r14) +- popq %r13 +- cfi_adjust_cfa_offset(-8) +- cfi_restore(%r13) +- popq %r12 +- cfi_adjust_cfa_offset(-8) +- cfi_restore(%r12) +- retq +- +- cfi_adjust_cfa_offset(STACKFRAME + 3 * 8) +- cfi_rel_offset(%r12, STACKFRAME + 2 * 8) +- cfi_rel_offset(%r13, STACKFRAME + 1 * 8) +- cfi_rel_offset(%r14, STACKFRAME) +-33: negq %r14 +-36: +- movq errno@gottpoff(%rip), %rdx +- movl %r14d, %fs:(%rdx) +- +- orl $-1, %eax +- jmp 45b +-#endif +- cfi_endproc +- .size sem_timedwait,.-sem_timedwait +- +- +- .type sem_timedwait_cleanup,@function +-sem_timedwait_cleanup: +- cfi_startproc +- cfi_adjust_cfa_offset(8) +- +- movq (%rsp), %rdi +- LOCK +- LP_OP(sub) $1, NWAITERS(%rdi) +- movq %rax, %rdi +-.LcallUR: +- call _Unwind_Resume@PLT +- hlt +-.LENDCODE: +- cfi_endproc +- .size sem_timedwait_cleanup,.-sem_timedwait_cleanup +- +- +-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME +- .type sem_timedwait_cleanup2,@function +-sem_timedwait_cleanup2: +- cfi_startproc +- cfi_adjust_cfa_offset(STACKFRAME + 3 * 8) +- cfi_rel_offset(%r12, STACKFRAME + 2 * 8) +- cfi_rel_offset(%r13, STACKFRAME + 1 * 8) +- cfi_rel_offset(%r14, STACKFRAME) +- +- LOCK +- LP_OP(sub) $1, NWAITERS(%r12) +- movq %rax, %rdi +- movq STACKFRAME(%rsp), %r14 +- movq STACKFRAME+8(%rsp), %r13 +- movq STACKFRAME+16(%rsp), %r12 +-.LcallUR2: +- call _Unwind_Resume@PLT +- hlt +-.LENDCODE2: +- cfi_endproc +- .size sem_timedwait_cleanup2,.-sem_timedwait_cleanup2 +-#endif +- +- +- .section .gcc_except_table,"a",@progbits +-.LexceptSTART: +- .byte DW_EH_PE_omit # @LPStart format +- .byte DW_EH_PE_omit # @TType format +- .byte DW_EH_PE_uleb128 # call-site format +- .uleb128 .Lcstend-.Lcstbegin +-.Lcstbegin: +- .uleb128 .LcleanupSTART-.LSTARTCODE +- .uleb128 .LcleanupEND-.LcleanupSTART +- .uleb128 sem_timedwait_cleanup-.LSTARTCODE +- .uleb128 0 +-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME +- .uleb128 .LcleanupSTART2-.LSTARTCODE +- .uleb128 .LcleanupEND2-.LcleanupSTART2 +- .uleb128 sem_timedwait_cleanup2-.LSTARTCODE +- .uleb128 0 +-#endif +- .uleb128 .LcallUR-.LSTARTCODE +- .uleb128 .LENDCODE-.LcallUR +- .uleb128 0 +- .uleb128 0 +-#ifndef __ASSUME_FUTEX_CLOCK_REALTIME +- .uleb128 .LcallUR2-.LSTARTCODE +- .uleb128 .LENDCODE2-.LcallUR2 +- .uleb128 0 +- .uleb128 0 +-#endif +-.Lcstend: +- +- +-#ifdef SHARED +- .hidden DW.ref.__gcc_personality_v0 +- .weak DW.ref.__gcc_personality_v0 +- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits +- .align LP_SIZE +- .type DW.ref.__gcc_personality_v0, @object +- .size DW.ref.__gcc_personality_v0, LP_SIZE +-DW.ref.__gcc_personality_v0: +- ASM_ADDR __gcc_personality_v0 +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_trywait.S ++++ /dev/null +@@ -1,47 +0,0 @@ +-/* Copyright (C) 2002, 2003, 2005, 2007, 2011 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +- +- .text +- +- .globl sem_trywait +- .type sem_trywait,@function +- .align 16 +-sem_trywait: +- movl (%rdi), %eax +-2: testl %eax, %eax +- jz 1f +- +- leal -1(%rax), %edx +- LOCK +- cmpxchgl %edx, (%rdi) +- jne 2b +- +- xorl %eax, %eax +- retq +- +-1: +- movq errno@gottpoff(%rip), %rdx +- movl $EAGAIN, %fs:(%rdx) +- orl $-1, %eax +- retq +- .size sem_trywait,.-sem_trywait +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S ++++ /dev/null +@@ -1,176 +0,0 @@ +-/* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2011 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2002. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +- +- .text +- +- .globl sem_wait +- .type sem_wait,@function +- .align 16 +-sem_wait: +-.LSTARTCODE: +- cfi_startproc +-#ifdef SHARED +- cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, +- DW.ref.__gcc_personality_v0) +- cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) +-#else +- cfi_personality(DW_EH_PE_udata4, __gcc_personality_v0) +- cfi_lsda(DW_EH_PE_udata4, .LexceptSTART) +-#endif +- +-#if VALUE == 0 +- movl (%rdi), %eax +-#else +- movl VALUE(%rdi), %eax +-#endif +-2: testl %eax, %eax +- je 1f +- +- leal -1(%rax), %edx +- LOCK +-#if VALUE == 0 +- cmpxchgl %edx, (%rdi) +-#else +- cmpxchgl %edx, VALUE(%rdi) +-#endif +- jne 2b +- +- xorl %eax, %eax +- retq +- +- /* This push is only needed to store the sem_t pointer for the +- exception handler. */ +-1: pushq %rdi +- cfi_adjust_cfa_offset(8) +- +- LOCK +- LP_OP(add) $1, NWAITERS(%rdi) +- +-.LcleanupSTART: +-6: call __pthread_enable_asynccancel +- movl %eax, %r8d +- +- xorq %r10, %r10 +- movl $SYS_futex, %eax +-#if FUTEX_WAIT == 0 +- movl PRIVATE(%rdi), %esi +-#else +- movl $FUTEX_WAIT, %esi +- orl PRIVATE(%rdi), %esi +-#endif +- xorl %edx, %edx +- syscall +- movq %rax, %rcx +- +- xchgq %r8, %rdi +- call __pthread_disable_asynccancel +-.LcleanupEND: +- movq %r8, %rdi +- +- testq %rcx, %rcx +- je 3f +- cmpq $-EWOULDBLOCK, %rcx +- jne 4f +- +-3: +-#if VALUE == 0 +- movl (%rdi), %eax +-#else +- movl VALUE(%rdi), %eax +-#endif +-5: testl %eax, %eax +- je 6b +- +- leal -1(%rax), %edx +- LOCK +-#if VALUE == 0 +- cmpxchgl %edx, (%rdi) +-#else +- cmpxchgl %edx, VALUE(%rdi) +-#endif +- jne 5b +- +- xorl %eax, %eax +- +-9: LOCK +- LP_OP(sub) $1, NWAITERS(%rdi) +- +- leaq 8(%rsp), %rsp +- cfi_adjust_cfa_offset(-8) +- +- retq +- +- cfi_adjust_cfa_offset(8) +-4: negq %rcx +- movq errno@gottpoff(%rip), %rdx +- movl %ecx, %fs:(%rdx) +- orl $-1, %eax +- +- jmp 9b +- .size sem_wait,.-sem_wait +- +- +- .type sem_wait_cleanup,@function +-sem_wait_cleanup: +- movq (%rsp), %rdi +- LOCK +- LP_OP(sub) $1, NWAITERS(%rdi) +- movq %rax, %rdi +-.LcallUR: +- call _Unwind_Resume@PLT +- hlt +-.LENDCODE: +- cfi_endproc +- .size sem_wait_cleanup,.-sem_wait_cleanup +- +- +- .section .gcc_except_table,"a",@progbits +-.LexceptSTART: +- .byte DW_EH_PE_omit # @LPStart format +- .byte DW_EH_PE_omit # @TType format +- .byte DW_EH_PE_uleb128 # call-site format +- .uleb128 .Lcstend-.Lcstbegin +-.Lcstbegin: +- .uleb128 .LcleanupSTART-.LSTARTCODE +- .uleb128 .LcleanupEND-.LcleanupSTART +- .uleb128 sem_wait_cleanup-.LSTARTCODE +- .uleb128 0 +- .uleb128 .LcallUR-.LSTARTCODE +- .uleb128 .LENDCODE-.LcallUR +- .uleb128 0 +- .uleb128 0 +-.Lcstend: +- +- +-#ifdef SHARED +- .hidden DW.ref.__gcc_personality_v0 +- .weak DW.ref.__gcc_personality_v0 +- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits +- .align LP_SIZE +- .type DW.ref.__gcc_personality_v0, @object +- .size DW.ref.__gcc_personality_v0, LP_SIZE +-DW.ref.__gcc_personality_v0: +- ASM_ADDR __gcc_personality_v0 +-#endif +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sem_post.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/sem_post.c ++++ /dev/null +@@ -1,5 +0,0 @@ +-/* ??? This is an ass-backwards way to do this. We should simply define +- the acquire/release semantics of atomic_exchange_and_add. And even if +- we don't do this, we should be using atomic_full_barrier or otherwise. */ +-#define __lll_rel_instr "mb" +-#include +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_post.S ++++ /dev/null +@@ -1,111 +0,0 @@ +-/* Copyright (C) 2003-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include "lowlevel-atomic.h" +- +- +- .text +- +- .globl __new_sem_post +- .type __new_sem_post,@function +- .align 5 +- cfi_startproc +-__new_sem_post: +- mov.l @(VALUE,r4), r2 +-0: +- mov.l .Lmax, r1 +- cmp/eq r1, r2 +- bt/s 3f +- mov r2, r3 +- mov r3, r5 +- add #1, r5 +- CMPXCHG (r3, @(VALUE,r4), r5, r2) +- bf 0b +- mov.l @(NWAITERS,r4), r2 +- tst r2, r2 +- bt 2f +- mov #FUTEX_WAKE, r5 +- mov.l @(PRIVATE,r4), r1 +- or r1, r5 +- mov #1, r6 +- mov #0, r7 +- mov #SYS_futex, r3 +- extu.b r3, r3 +- trapa #0x14 +- SYSCALL_INST_PAD +- +- cmp/pz r0 +- bf 1f +-2: +- rts +- mov #0, r0 +- +-1: +- bra 4f +- mov #EINVAL, r2 +- +-3: +- mov #EOVERFLOW, r2 +-4: +- mov.l r12, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r12, 0) +- mov.l r8, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r8, 0) +- sts.l pr, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (pr, 0) +- mova .Lgot3, r0 +- mov.l .Lgot3, r12 +- add r0, r12 +- +- mov.l .Lerrno3, r0 +- stc gbr, r1 +- mov.l @(r0, r12), r0 +- bra .Lexit +- add r1, r0 +- .align 2 +-.Lerrno3: +- .long errno@GOTTPOFF +-.Lexit: +- mov.l r2, @r0 +- lds.l @r15+, pr +- cfi_adjust_cfa_offset (-4) +- cfi_restore (pr) +- mov.l @r15+, r8 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r8) +- mov.l @r15+, r12 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r12) +- rts +- mov #-1, r0 +- cfi_endproc +- +- .align 2 +-.Lmax: +- .long SEM_VALUE_MAX +-.Lgot3: +- .long _GLOBAL_OFFSET_TABLE_ +- .size __new_sem_post,.-__new_sem_post +- versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_timedwait.S ++++ /dev/null +@@ -1,281 +0,0 @@ +-/* Copyright (C) 2003-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include "lowlevel-atomic.h" +- +- +-#if VALUE != 0 +-# error "code needs to be rewritten for VALUE != 0" +-#endif +- +- .text +- +- .globl sem_timedwait +- .type sem_timedwait,@function +- .align 5 +- cfi_startproc +-sem_timedwait: +-.LSTARTCODE: +-#ifdef SHARED +- cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, +- DW.ref.__gcc_personality_v0) +- cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) +-#else +- cfi_personality(DW_EH_PE_absptr, __gcc_personality_v0) +- cfi_lsda(DW_EH_PE_absptr, .LexceptSTART) +-#endif +- mov.l @r4, r0 +-2: +- tst r0, r0 +- bt 1f +- mov r0, r3 +- mov r0, r6 +- add #-1, r3 +- CMPXCHG (r6, @r4, r3, r2) +- bf/s 2b +- mov r2, r0 +- rts +- mov #0, r0 +- +-1: +- /* Check whether the timeout value is valid. */ +- mov.l r8, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r8, 0) +- mov.l r9, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r9, 0) +- mov.l r10, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r10, 0) +- mov.l r12, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r12, 0) +- sts.l pr, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (pr, 0) +- add #-8, r15 +- cfi_adjust_cfa_offset (8) +- +- mov r4, r8 +- mov r5, r9 +- +- /* Check for invalid nanosecond field. */ +- mov.l @(4,r9), r0 +- mov.l .L1g, r1 +- cmp/hs r1, r0 +- bt/s .Lerrno_exit +- mov #EINVAL, r10 +- INC (@(NWAITERS,r8),r2) +- +-7: +- /* Compute relative timeout. */ +- mov r15, r4 +- mov #0, r5 +- mov #__NR_gettimeofday, r3 +- trapa #0x12 +- SYSCALL_INST_PAD +- +- mov.l @(4,r15), r0 +- mov.w .L1k, r1 +- dmulu.l r0, r1 /* Milli seconds to nano seconds. */ +- mov.l @r9, r2 +- mov.l @(4,r9), r3 +- mov.l @r15, r0 +- sts macl, r1 +- sub r0, r2 +- clrt +- subc r1, r3 +- bf 5f +- mov.l .L1g, r1 +- add r1, r3 +- add #-1, r2 +-5: +- cmp/pz r2 +- bf/s 6f /* Time is already up. */ +- mov #ETIMEDOUT, r0 +- +- /* Store relative timeout. */ +- mov.l r2, @r15 +- mov.l r3, @(4,r15) +- +-.LcleanupSTART: +- mov.l .Lenable0, r1 +- bsrf r1 +- nop +-.Lenable0b: +- mov r0, r10 +- +- mov r8, r4 +-#if FUTEX_WAIT == 0 +- mov.l @(PRIVATE,r8), r5 +-#else +- mov.l @(PRIVATE,r8), r5 +- mov #FUTEX_WAIT, r0 +- or r0, r5 +-#endif +- mov #0, r6 +- mov r15, r7 +- mov #SYS_futex, r3 +- extu.b r3, r3 +- trapa #0x14 +- SYSCALL_INST_PAD +- +- mov.l .Ldisable0, r1 +- mov r10, r4 +- bsrf r1 +- mov r0, r10 +-.Ldisable0b: +- mov r10, r0 +-.LcleanupEND: +- +- tst r0, r0 +- bt 9f +- cmp/eq #-EWOULDBLOCK, r0 +- bf 3f +-9: +- mov.l @r8, r0 +-8: +- tst r0, r0 +- bt 7b +- +- mov r0, r3 +- mov r0, r4 +- add #-1, r3 +- CMPXCHG (r4, @r8, r3, r2) +- bf/s 8b +- mov r2, r0 +- +- DEC (@(NWAITERS,r8), r2) +- mov #0, r0 +- +-10: +- cfi_remember_state +- add #8, r15 +- cfi_adjust_cfa_offset (-8) +- lds.l @r15+, pr +- cfi_adjust_cfa_offset (-4) +- cfi_restore (pr) +- mov.l @r15+, r12 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r12) +- mov.l @r15+, r10 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r10) +- mov.l @r15+, r9 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r9) +- mov.l @r15+, r8 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r8) +- rts +- nop +- cfi_restore_state +- +-3: +- neg r0, r0 +-6: +- mov r0, r10 +- DEC (@(NWAITERS,r8), r2) +-.Lerrno_exit: +- mova .Lgot2, r0 +- mov.l .Lgot2, r12 +- add r0, r12 +- +- mov.l .Lerrno2, r0 +- stc gbr, r1 +- mov.l @(r0, r12), r0 +- bra .Lexit +- add r1, r0 +- .align 2 +-.Lerrno2: +- .long errno@GOTTPOFF +-.Lexit: +- mov.l r10, @r0 +- bra 10b +- mov #-1, r0 +- +-.L1k: +- .word 1000 +- .align 2 +-.L1g: +- .long 1000000000 +-.Lgot2: +- .long _GLOBAL_OFFSET_TABLE_ +-.Lenable0: +- .long __pthread_enable_asynccancel-.Lenable0b +-.Ldisable0: +- .long __pthread_disable_asynccancel-.Ldisable0b +- .size sem_timedwait,.-sem_timedwait +- +- .type sem_wait_cleanup,@function +-sem_wait_cleanup: +- DEC (@(NWAITERS,r8), r2) +-.LcallUR: +- mov.l .Lresume, r1 +-#ifdef PIC +- add r12, r1 +-#endif +- jsr @r1 +- nop +- sleep +- +- .align 2 +-.Lresume: +-#ifdef PIC +- .long _Unwind_Resume@GOTOFF +-#else +- .long _Unwind_Resume +-#endif +-.LENDCODE: +- cfi_endproc +- .size sem_wait_cleanup,.-sem_wait_cleanup +- +- +- .section .gcc_except_table,"a",@progbits +-.LexceptSTART: +- .byte DW_EH_PE_omit ! @LPStart format (omit) +- .byte DW_EH_PE_omit ! @TType format (omit) +- .byte DW_EH_PE_uleb128 ! call-site format +- .uleb128 .Lcstend-.Lcstbegin +-.Lcstbegin: +- .uleb128 .LcleanupSTART-.LSTARTCODE +- .uleb128 .LcleanupEND-.LcleanupSTART +- .uleb128 sem_wait_cleanup-.LSTARTCODE +- .uleb128 0 +- .uleb128 .LcallUR-.LSTARTCODE +- .uleb128 .LENDCODE-.LcallUR +- .uleb128 0 +- .uleb128 0 +-.Lcstend: +- +-#ifdef SHARED +- .hidden DW.ref.__gcc_personality_v0 +- .weak DW.ref.__gcc_personality_v0 +- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits +- .align 4 +- .type DW.ref.__gcc_personality_v0, @object +- .size DW.ref.__gcc_personality_v0, 4 +-DW.ref.__gcc_personality_v0: +- .long __gcc_personality_v0 +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_trywait.S ++++ /dev/null +@@ -1,102 +0,0 @@ +-/* Copyright (C) 2003-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include "lowlevel-atomic.h" +- +- +- .text +- +- .globl __new_sem_trywait +- .type __new_sem_trywait,@function +- .align 5 +- cfi_startproc +-__new_sem_trywait: +- mov.l r12, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r12, 0) +- mov.l r8, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r8, 0) +- sts.l pr, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (pr, 0) +- mov r4, r8 +- mov.l @r8, r0 +-2: +- tst r0, r0 +- bt 1f +- +- mov r0, r3 +- mov r0, r4 +- add #-1, r3 +- CMPXCHG (r4, @r8, r3, r2) +- bf/s 2b +- mov r2, r0 +- +- cfi_remember_state +- lds.l @r15+, pr +- cfi_adjust_cfa_offset (-4) +- cfi_restore (pr) +- mov.l @r15+, r8 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r8) +- mov.l @r15+, r12 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r12) +- rts +- mov #0, r0 +- cfi_restore_state +- +-1: +- mov #EAGAIN, r8 +- mova .Lgot1, r0 +- mov.l .Lgot1, r12 +- add r0, r12 +- +- mov.l .Lerrno1, r0 +- stc gbr, r1 +- mov.l @(r0, r12), r0 +- bra .Lexit +- add r1, r0 +- .align 2 +-.Lerrno1: +- .long errno@GOTTPOFF +-.Lexit: +- mov.l r8, @r0 +- lds.l @r15+, pr +- cfi_adjust_cfa_offset (-4) +- cfi_restore (pr) +- mov.l @r15+, r8 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r8) +- mov.l @r15+, r12 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r12) +- rts +- mov #-1, r0 +- +- cfi_endproc +- +- .align 2 +-.Lgot1: +- .long _GLOBAL_OFFSET_TABLE_ +- .size __new_sem_trywait,.-__new_sem_trywait +- versioned_symbol(libpthread, __new_sem_trywait, sem_trywait, GLIBC_2_1) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sem_wait.S ++++ /dev/null +@@ -1,229 +0,0 @@ +-/* Copyright (C) 2003-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include "lowlevel-atomic.h" +- +- +-#if VALUE != 0 +-# error "code needs to be rewritten for VALUE != 0" +-#endif +- +- .text +- +- .globl __new_sem_wait +- .type __new_sem_wait,@function +- .align 5 +- cfi_startproc +-__new_sem_wait: +-.LSTARTCODE: +-#ifdef SHARED +- cfi_personality(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect, +- DW.ref.__gcc_personality_v0) +- cfi_lsda(DW_EH_PE_pcrel | DW_EH_PE_sdata4, .LexceptSTART) +-#else +- cfi_personality(DW_EH_PE_absptr, __gcc_personality_v0) +- cfi_lsda(DW_EH_PE_absptr, .LexceptSTART) +-#endif +- mov.l r8, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r8, 0) +- mov.l r10, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r10, 0) +- mov.l r12, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (r12, 0) +- sts.l pr, @-r15 +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (pr, 0) +- +- mov r4, r8 +- mov.l @r8, r0 +-2: +- tst r0, r0 +- bt 1f +- mov r0, r3 +- mov r0, r4 +- add #-1, r3 +- CMPXCHG (r4, @r8, r3, r2) +- bf/s 2b +- mov r2, r0 +-7: +- mov #0, r0 +-9: +- cfi_remember_state +- lds.l @r15+, pr +- cfi_adjust_cfa_offset (-4) +- cfi_restore (pr) +- mov.l @r15+, r12 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r12) +- mov.l @r15+, r10 +- cfi_adjust_cfa_offset (-4) +- cfi_restore (r10) +- rts +- mov.l @r15+, r8 +- /* Omit CFI for restore in delay slot. */ +- cfi_restore_state +- +-.Lafter_ret: +-1: +- INC (@(NWAITERS,r8),r2) +- +-.LcleanupSTART: +-6: +- mov.l .Lenable0, r1 +- bsrf r1 +- nop +-.Lenable0b: +- mov r0, r10 +- +- mov r8, r4 +-#if FUTEX_WAIT == 0 +- mov.l @(PRIVATE,r8), r5 +-#else +- mov.l @(PRIVATE,r8), r5 +- mov #FUTEX_WAIT, r0 +- or r0, r5 +-#endif +- mov #0, r6 +- mov #0, r7 +- mov #SYS_futex, r3 +- extu.b r3, r3 +- trapa #0x14 +- SYSCALL_INST_PAD +- +- mov.l .Ldisable0, r1 +- mov r10, r4 +- bsrf r1 +- mov r0, r10 +-.Ldisable0b: +- mov r10, r0 +-.LcleanupEND: +- +- tst r0, r0 +- bt 3f +- cmp/eq #-EWOULDBLOCK, r0 +- bf 4f +- +-3: +- mov.l @r8, r0 +-5: +- tst r0, r0 +- bt 6b +- +- mov r0, r3 +- mov r0, r4 +- add #-1, r3 +- CMPXCHG (r4, @r8, r3, r2) +- bf/s 5b +- mov r2, r0 +- +- DEC (@(NWAITERS,r8), r2) +- bra 7b +- nop +- +-4: +- neg r0, r0 +- mov r0, r4 +- DEC (@(NWAITERS,r8), r2) +- mov r4, r8 +- mova .Lgot0, r0 +- mov.l .Lgot0, r12 +- add r0, r12 +- +- mov.l .Lerrno0, r0 +- stc gbr, r1 +- mov.l @(r0, r12), r0 +- bra .Lexit +- add r1, r0 +- .align 2 +-.Lerrno0: +- .long errno@GOTTPOFF +-.Lexit: +- mov.l r8, @r0 +- bra 9b +- mov #-1, r0 +- +- .align 2 +-.Lgot0: +- .long _GLOBAL_OFFSET_TABLE_ +-.Lenable0: +- .long __pthread_enable_asynccancel-.Lenable0b +-.Ldisable0: +- .long __pthread_disable_asynccancel-.Ldisable0b +- .size __new_sem_wait,.-__new_sem_wait +- versioned_symbol(libpthread, __new_sem_wait, sem_wait, GLIBC_2_1) +- +- +- .type sem_wait_cleanup,@function +-sem_wait_cleanup: +- DEC (@(NWAITERS,r8), r2) +-.LcallUR: +- mov.l .Lresume, r1 +-#ifdef PIC +- add r12, r1 +-#endif +- jsr @r1 +- nop +- sleep +- +- .align 2 +-.Lresume: +-#ifdef PIC +- .long _Unwind_Resume@GOTOFF +-#else +- .long _Unwind_Resume +-#endif +-.LENDCODE: +- cfi_endproc +- .size sem_wait_cleanup,.-sem_wait_cleanup +- +- +- .section .gcc_except_table,"a",@progbits +-.LexceptSTART: +- .byte DW_EH_PE_omit ! @LPStart format (omit) +- .byte DW_EH_PE_omit ! @TType format (omit) +- .byte DW_EH_PE_uleb128 ! call-site format +- .uleb128 .Lcstend-.Lcstbegin +-.Lcstbegin: +- .uleb128 .LcleanupSTART-.LSTARTCODE +- .uleb128 .LcleanupEND-.LcleanupSTART +- .uleb128 sem_wait_cleanup-.LSTARTCODE +- .uleb128 0 +- .uleb128 .LcallUR-.LSTARTCODE +- .uleb128 .LENDCODE-.LcallUR +- .uleb128 0 +- .uleb128 0 +-.Lcstend: +- +-#ifdef SHARED +- .hidden DW.ref.__gcc_personality_v0 +- .weak DW.ref.__gcc_personality_v0 +- .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits +- .align 4 +- .type DW.ref.__gcc_personality_v0, @object +- .size DW.ref.__gcc_personality_v0, 4 +-DW.ref.__gcc_personality_v0: +- .long __gcc_personality_v0 +-#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/Makefile ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/Makefile +@@ -24,8 +24,7 @@ libpthread-sysdep_routines += pt-fork pt + + gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \ + lowlevelbarrier.sym unwindbuf.sym \ +- lowlevelrobustlock.sym pthread-pi-defines.sym \ +- structsem.sym ++ lowlevelrobustlock.sym pthread-pi-defines.sym + endif + + ifeq ($(subdir),posix) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +@@ -225,17 +225,18 @@ LLL_STUB_UNWIND_INFO_END + + + #define lll_futex_wake(futex, nr, private) \ +- do { \ +- int __ignore; \ ++ ({ \ ++ int __status; \ + register __typeof (nr) _nr __asm ("edx") = (nr); \ + LIBC_PROBE (lll_futex_wake, 3, futex, nr, private); \ + __asm __volatile ("syscall" \ +- : "=a" (__ignore) \ ++ : "=a" (__status) \ + : "0" (SYS_futex), "D" (futex), \ + "S" (__lll_private_flag (FUTEX_WAKE, private)), \ + "d" (_nr) \ + : "memory", "cc", "r10", "r11", "cx"); \ +- } while (0) ++ __status; \ ++ }) + + + /* NB: in the lll_trylock macro we simply return the value in %eax +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +@@ -224,20 +224,21 @@ LLL_STUB_UNWIND_INFO_END + + + #define lll_futex_wake(futex, nr, private) \ +- do { \ +- int __ignore; \ ++ ({ \ ++ int __status; \ + register __typeof (nr) _nr asm ("edx") = (nr); \ + LIBC_PROBE (lll_futex_wake, 3, futex, nr, private); \ + __asm __volatile (LLL_EBX_LOAD \ + LLL_ENTER_KERNEL \ + LLL_EBX_LOAD \ +- : "=a" (__ignore) \ ++ : "=a" (__status) \ + : "0" (SYS_futex), LLL_EBX_REG (futex), \ + "c" (__lll_private_flag (FUTEX_WAKE, private)), \ + "d" (_nr), \ + "i" (0) /* phony, to align next arg's number */, \ + "i" (offsetof (tcbhead_t, sysinfo))); \ +- } while (0) ++ __status; \ ++ }) + + + /* NB: in the lll_trylock macro we simply return the value in %eax diff --git a/SOURCES/glibc-rh1028652.patch b/SOURCES/glibc-rh1028652.patch new file mode 100644 index 00000000..0d933268 --- /dev/null +++ b/SOURCES/glibc-rh1028652.patch @@ -0,0 +1,96 @@ +# +# Upstream power patch to increase MINSIGSTKSZ and SIGSTKSZ to +# account for the kernel signal frame size increase. +# +# commit f7c399cff5bd04ee9dc117fb6b0f39597dc047c6 +# Author: Alan Modra +# Date: Sat Aug 17 18:37:18 2013 +0930 +# +# PowerPC SIGSTKSZ +# http://sourceware.org/ml/libc-alpha/2013-08/msg00093.html +# +# This copies the sparc version of sigstack.h, which gives powerpc +# #define MINSIGSTKSZ 4096 +# #define SIGSTKSZ 16384 +# +# Before the VSX changes, struct rt_sigframe size was 1920 plus 128 for +# __SIGNAL_FRAMESIZE giving ppc64 exactly the default MINSIGSTKSZ of +# 2048. +# +# After VSX, ucontext increased by 256 bytes. Oops, we're over +# MINSIGSTKSZ, so powerpc has been using the wrong value for quite a +# while. Add another ucontext for TM and rt_sigframe is now at 3872, +# giving actual MINSIGSTKSZ of 4000. +# +# The glibc testcase that I was looking at was tst-cancel21, which +# allocates 2*SIGSTKSZ (not because the test is trying to be +# conservative, but because the test actually has nested signal stack +# frames). We blew the allocation by 48 bytes when using current +# mainline gcc to compile glibc (le ppc64). +# +# The required stack depth in _dl_lookup_symbol_x from the top of the +# next signal frame was 10944 bytes. I guess you'd want to add 288 to +# that, implying an actual SIGSTKSZ of 11232. +# +# * sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h: New file. +# +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h +new file mode 100644 +index 0000000..33be9e8 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/sigstack.h +@@ -0,0 +1,54 @@ ++/* sigstack, sigaltstack definitions. ++ Copyright (C) 1998-2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SIGNAL_H ++# error "Never include this file directly. Use instead" ++#endif ++ ++ ++/* Structure describing a signal stack (obsolete). */ ++struct sigstack ++ { ++ void *ss_sp; /* Signal stack pointer. */ ++ int ss_onstack; /* Nonzero if executing on this stack. */ ++ }; ++ ++ ++/* Possible values for `ss_flags.'. */ ++enum ++{ ++ SS_ONSTACK = 1, ++#define SS_ONSTACK SS_ONSTACK ++ SS_DISABLE ++#define SS_DISABLE SS_DISABLE ++}; ++ ++/* Minimum stack size for a signal handler. */ ++#define MINSIGSTKSZ 4096 ++ ++/* System default stack size. */ ++#define SIGSTKSZ 16384 ++ ++ ++/* Alternate, preferred interface. */ ++typedef struct sigaltstack ++ { ++ void *ss_sp; ++ int ss_flags; ++ size_t ss_size; ++ } stack_t; diff --git a/SOURCES/glibc-rh1032435.patch b/SOURCES/glibc-rh1032435.patch new file mode 100644 index 00000000..cfc253df --- /dev/null +++ b/SOURCES/glibc-rh1032435.patch @@ -0,0 +1,390 @@ +commit 977f4b31b7ca4a4e498c397f3fd70510694bbd86 +Author: Siddhesh Poyarekar +Date: Wed Oct 30 16:13:37 2013 +0530 + + Fix reads for sizes larger than INT_MAX in AF_INET lookup + + Currently for AF_INET lookups from the hosts file, buffer sizes larger + than INT_MAX silently overflow and may result in access beyond bounds + of a buffer. This happens when the number of results in an AF_INET + lookup in /etc/hosts are very large. + + There are two aspects to the problem. One problem is that the size + computed from the buffer size is stored into an int, which results in + overflow for large sizes. Additionally, even if this size was + expanded, the function used to read content into the buffer (fgets) + accepts only int sizes. As a result, the fix is to have a function + wrap around fgets that calls it multiple times with int sizes if + necessary. + +(The previous commit fixes upstream bug 16071.) + +commit ac60763eac3d43b7234dd21286ad3ec3f17957fc +Author: Andreas Schwab +Date: Mon Jun 23 10:24:45 2014 +0200 + + Don't ignore too long lines in nss_files (BZ #17079) + +commit e07aabba73ea62e7dfa0512507c92efb851fbdbe +Author: Florian Weimer +Date: Tue Sep 22 13:20:18 2015 +0200 + + Add test case for bug 18287 + +commit 90fa42a1d7b78de0d75f7e3af362275b2abe807f +Author: Florian Weimer +Date: Tue Sep 22 13:40:17 2015 +0200 + + Test in commit e07aabba73ea62e7dfa0512507c92efb851fbdbe is for bug 17079 + +diff -u b/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c +--- b/nss/nss_files/files-XXX.c ++++ b/nss/nss_files/files-XXX.c +@@ -179,8 +179,53 @@ + return NSS_STATUS_SUCCESS; + } + +-/* Parsing the database file into `struct STRUCTURE' data structures. */ + ++typedef enum ++{ ++ gcr_ok = 0, ++ gcr_error = -1, ++ gcr_overflow = -2 ++} get_contents_ret; ++ ++/* Hack around the fact that fgets only accepts int sizes. */ ++static get_contents_ret ++get_contents (char *linebuf, size_t len, FILE *stream) ++{ ++ size_t remaining_len = len; ++ char *curbuf = linebuf; ++ ++ do ++ { ++ int curlen = ((remaining_len > (size_t) INT_MAX) ? INT_MAX ++ : remaining_len); ++ ++ /* Terminate the line so that we can test for overflow. */ ++ ((unsigned char *) curbuf)[curlen - 1] = 0xff; ++ ++ char *p = fgets_unlocked (curbuf, curlen, stream); ++ ++ /* EOF or read error. */ ++ if (p == NULL) ++ return gcr_error; ++ ++ /* Done reading in the line. */ ++ if (((unsigned char *) curbuf)[curlen - 1] == 0xff) ++ return gcr_ok; ++ ++ /* Drop the terminating '\0'. */ ++ remaining_len -= curlen - 1; ++ curbuf += curlen - 1; ++ } ++ /* fgets copies one less than the input length. Our last iteration is of ++ REMAINING_LEN and once that is done, REMAINING_LEN is decremented by ++ REMAINING_LEN - 1, leaving the result as 1. */ ++ while (remaining_len > 1); ++ ++ /* This means that the current buffer was not large enough. */ ++ return gcr_overflow; ++} ++ ++/* Parsing the database file into `struct STRUCTURE' data structures. */ + static enum nss_status + internal_getent (struct STRUCTURE *result, + char *buffer, size_t buflen, int *errnop H_ERRNO_PROTO +@@ -188,7 +233,7 @@ + { + char *p; + struct parser_data *data = (void *) buffer; +- int linebuflen = buffer + buflen - data->linebuffer; ++ size_t linebuflen = buffer + buflen - data->linebuffer; + int parse_result; + + if (buflen < sizeof *data + 2) +@@ -200,17 +245,16 @@ + + do + { +- /* Terminate the line so that we can test for overflow. */ +- ((unsigned char *) data->linebuffer)[linebuflen - 1] = '\xff'; ++ get_contents_ret r = get_contents (data->linebuffer, linebuflen, stream); + +- p = fgets_unlocked (data->linebuffer, linebuflen, stream); +- if (p == NULL) ++ if (r == gcr_error) + { + /* End of file or read error. */ + H_ERRNO_SET (HOST_NOT_FOUND); + return NSS_STATUS_NOTFOUND; + } +- else if (((unsigned char *) data->linebuffer)[linebuflen - 1] != 0xff) ++ ++ if (r == gcr_overflow) + { + /* The line is too long. Give the user the opportunity to + enlarge the buffer. */ +@@ -219,7 +263,8 @@ + return NSS_STATUS_TRYAGAIN; + } + +- /* Skip leading blanks. */ ++ /* Everything OK. Now skip leading blanks. */ ++ p = data->linebuffer; + while (isspace (*p)) + ++p; + } + +diff a/nss/bug17079.c b/nss/bug17079.c +--- /dev/null ++++ b/nss/bug17079.c +@@ -0,0 +1,236 @@ ++/* Test for bug 17079: heap overflow in NSS with small buffers. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Check if two passwd structs contain the same data. */ ++static bool ++equal (const struct passwd *a, const struct passwd *b) ++{ ++ return strcmp (a->pw_name, b->pw_name) == 0 ++ && strcmp (a->pw_passwd, b->pw_passwd) == 0 ++ && a->pw_uid == b->pw_uid ++ && a->pw_gid == b->pw_gid ++ && strcmp (a->pw_gecos, b->pw_gecos) == 0 ++ && strcmp (a->pw_dir, b->pw_dir) == 0 ++ && strcmp (a->pw_shell, b->pw_shell) == 0; ++} ++ ++enum { MAX_TEST_ITEMS = 10 }; ++static struct passwd test_items[MAX_TEST_ITEMS]; ++static int test_count; ++ ++/* Initialize test_items and test_count above, with data from the ++ passwd database. */ ++static bool ++init_test_items (void) ++{ ++ setpwent (); ++ do ++ { ++ struct passwd *pwd = getpwent (); ++ if (pwd == NULL) ++ break; ++ struct passwd *target = test_items + test_count; ++ target->pw_name = strdup (pwd->pw_name); ++ target->pw_passwd = strdup (pwd->pw_passwd); ++ target->pw_uid = pwd->pw_uid; ++ target->pw_gid = pwd->pw_gid; ++ target->pw_gecos = strdup (pwd->pw_gecos); ++ target->pw_dir = strdup (pwd->pw_dir); ++ target->pw_shell = strdup (pwd->pw_shell); ++ } ++ while (++test_count < MAX_TEST_ITEMS); ++ endpwent (); ++ ++ /* Filter out those test items which cannot be looked up by name or ++ UID. */ ++ bool found = false; ++ for (int i = 0; i < test_count; ++i) ++ { ++ struct passwd *pwd1 = getpwnam (test_items[i].pw_name); ++ struct passwd *pwd2 = getpwuid (test_items[i].pw_uid); ++ if (pwd1 == NULL || !equal (pwd1, test_items + i) ++ || pwd2 == NULL || !equal (pwd2, test_items + i)) ++ test_items[i].pw_name = NULL; ++ else ++ found = true; ++ } ++ ++ if (!found) ++ puts ("error: no accounts found which can be looked up by name and UID."); ++ return found; ++} ++ ++/* Set to true if an error is encountered. */ ++static bool errors; ++ ++/* Return true if the padding has not been tampered with. */ ++static bool ++check_padding (char *buffer, size_t size, char pad) ++{ ++ char *end = buffer + size; ++ while (buffer < end) ++ { ++ if (*buffer != pad) ++ return false; ++ ++buffer; ++ } ++ return true; ++} ++ ++/* Test one buffer size and padding combination. */ ++static void ++test_one (const struct passwd *item, size_t buffer_size, ++ char pad, size_t padding_size) ++{ ++ char *buffer = malloc (buffer_size + padding_size); ++ if (buffer == NULL) ++ { ++ puts ("error: malloc failure"); ++ errors = true; ++ return; ++ } ++ ++ struct passwd pwd; ++ struct passwd *result; ++ int ret; ++ ++ /* Test getpwname_r. */ ++ memset (buffer, pad, buffer_size + padding_size); ++ pwd = (struct passwd) {}; ++ ret = getpwnam_r (item->pw_name, &pwd, buffer, buffer_size, &result); ++ if (!check_padding (buffer + buffer_size, padding_size, pad)) ++ { ++ printf ("error: padding change: " ++ "name \"%s\", buffer size %zu, padding size %zu, pad 0x%02x\n", ++ item->pw_name, buffer_size, padding_size, (unsigned char) pad); ++ errors = true; ++ } ++ if (ret == 0) ++ { ++ if (result == NULL) ++ { ++ printf ("error: no data: name \"%s\", buffer size %zu\n", ++ item->pw_name, buffer_size); ++ errors = true; ++ } ++ else if (!equal (item, result)) ++ { ++ printf ("error: lookup mismatch: name \"%s\", buffer size %zu\n", ++ item->pw_name, buffer_size); ++ errors = true; ++ } ++ } ++ else if (ret != ERANGE) ++ { ++ errno = ret; ++ printf ("error: lookup failure for name \"%s\": %m (%d)\n", ++ item->pw_name, ret); ++ errors = true; ++ } ++ ++ /* Test getpwuid_r. */ ++ memset (buffer, pad, buffer_size + padding_size); ++ pwd = (struct passwd) {}; ++ ret = getpwuid_r (item->pw_uid, &pwd, buffer, buffer_size, &result); ++ if (!check_padding (buffer + buffer_size, padding_size, pad)) ++ { ++ printf ("error: padding change: " ++ "UID %ld, buffer size %zu, padding size %zu, pad 0x%02x\n", ++ (long) item->pw_uid, buffer_size, padding_size, ++ (unsigned char) pad); ++ errors = true; ++ } ++ if (ret == 0) ++ { ++ if (result == NULL) ++ { ++ printf ("error: no data: UID %ld, buffer size %zu\n", ++ (long) item->pw_uid, buffer_size); ++ errors = true; ++ } ++ else if (!equal (item, result)) ++ { ++ printf ("error: lookup mismatch: UID %ld, buffer size %zu\n", ++ (long) item->pw_uid, buffer_size); ++ errors = true; ++ } ++ } ++ else if (ret != ERANGE) ++ { ++ errno = ret; ++ printf ("error: lookup failure for UID \"%ld\": %m (%d)\n", ++ (long) item->pw_uid, ret); ++ errors = true; ++ } ++ ++ free (buffer); ++} ++ ++/* Test one buffer size with different paddings. */ ++static void ++test_buffer_size (size_t buffer_size) ++{ ++ for (int i = 0; i < test_count; ++i) ++ for (size_t padding_size = 0; padding_size < 3; ++padding_size) ++ { ++ test_one (test_items + i, buffer_size, '\0', padding_size); ++ if (padding_size > 0) ++ { ++ test_one (test_items + i, buffer_size, ':', padding_size); ++ test_one (test_items + i, buffer_size, '\n', padding_size); ++ test_one (test_items + i, buffer_size, '\xff', padding_size); ++ test_one (test_items + i, buffer_size, '@', padding_size); ++ } ++ } ++} ++ ++int ++do_test (void) ++{ ++ if (!init_test_items ()) ++ return 1; ++ printf ("info: %d test items\n", test_count); ++ ++ for (size_t buffer_size = 0; buffer_size <= 65; ++buffer_size) ++ test_buffer_size (buffer_size); ++ for (size_t buffer_size = 64 + 4; buffer_size < 256; buffer_size += 4) ++ test_buffer_size (buffer_size); ++ test_buffer_size (255); ++ test_buffer_size (257); ++ for (size_t buffer_size = 256; buffer_size < 512; buffer_size += 8) ++ test_buffer_size (buffer_size); ++ test_buffer_size (511); ++ test_buffer_size (513); ++ test_buffer_size (1024); ++ test_buffer_size (2048); ++ ++ if (errors) ++ return 1; ++ else ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff a/nss/Makefile b/nss/Makefile +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -39,6 +39,6 @@ + extra-objs += $(makedb-modules:=.o) + +-tests = test-netdb tst-nss-test1 ++tests = test-netdb tst-nss-test1 bug17079 + xtests = bug-erange + + include ../Makeconfig diff --git a/SOURCES/glibc-rh1039496.patch b/SOURCES/glibc-rh1039496.patch new file mode 100644 index 00000000..e856f181 --- /dev/null +++ b/SOURCES/glibc-rh1039496.patch @@ -0,0 +1,102 @@ +diff -urNglibc-2.17-c758a686/libio/tst-widetext.inputglibc-2.17-c758a686/libio/tst-widetext.input +--- glibc-2.17-c758a686/libio/tst-widetext.input 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/libio/tst-widetext.input 2013-12-11 09:48:30.760084849 -0500 +@@ -126,7 +126,7 @@ + ઀◌àªâ—Œàª‚ઃ઄અઆઇઈઉઊઋઌàªàªŽàªàªàª‘઒ઓઔકખગઘઙચછજàªàªžàªŸàª àª¡àª¢àª£àª¤àª¥àª¦àª§àª¨àª©àªªàª«àª¬àª­àª®àª¯àª°àª±àª²àª³àª´àªµàª¶àª·àª¸àª¹àªºàª»â—Œàª¼àª½àª¾àª¿ + ી◌à«â—Œà«‚◌ૃ◌ૄ◌ૅ૆◌ે◌ૈૉ૊ોૌ◌à«à«Žà«à«à«‘૒૓૔૕૖૗૘૙૚૛૜à«à«žà«Ÿà« à«¡à«¢à«£à«¤à«¥à«¦à«§à«¨à«©à«ªà««à«¬à«­à«®à«¯à«°à«±à«²à«³à«´à«µà«¶à«·à«¸à«¹à«ºà«»à«¼à«½à«¾à«¿ + +-Oriya (U+0B00-U+0B7F): ++Odia (U+0B00-U+0B7F): + + ଀◌à¬à¬‚ଃ଄ଅଆଇଈଉଊଋଌà¬à¬Žà¬à¬à¬‘଒ଓଔକଖଗଘଙଚଛଜà¬à¬žà¬Ÿà¬ à¬¡à¬¢à¬£à¬¤à¬¥à¬¦à¬§à¬¨à¬©à¬ªà¬«à¬¬à¬­à¬®à¬¯à¬°à¬±à¬²à¬³à¬´à¬µà¬¶à¬·à¬¸à¬¹à¬ºà¬»â—Œà¬¼à¬½à¬¾â—Œà¬¿ + ୀ◌à­â—Œà­‚◌ୃୄ୅୆େୈ୉୊ୋୌ◌à­à­Žà­à­à­‘୒୓୔୕◌ୖୗ୘୙୚୛ଡ଼à­à­žà­Ÿà­ à­¡à­¢à­£à­¤à­¥à­¦à­§à­¨à­©à­ªà­«à­¬à­­à­®à­¯à­°à­±à­²à­³à­´à­µà­¶à­·à­¸à­¹à­ºà­»à­¼à­½à­¾à­¿ +diff -urNglibc-2.17-c758a686/locale/iso-639.defglibc-2.17-c758a686/locale/iso-639.def +--- glibc-2.17-c758a686/locale/iso-639.def 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/locale/iso-639.def 2013-12-11 09:58:58.414959856 -0500 +@@ -181,7 +181,7 @@ + DEFINE_LANGUAGE_CODE ("Greek, Modern (1453-)", el, ell, gre) + DEFINE_LANGUAGE_CODE ("Guarani", gn, grn, grn) + DEFINE_LANGUAGE_CODE ("Gujarati", gu, guj, guj) +-DEFINE_LANGUAGE_CODE3 ("Gwich´in", gwi, gwi) ++DEFINE_LANGUAGE_CODE3 ("Gwich´in", gwi, gwi) + DEFINE_LANGUAGE_CODE3 ("Haida", hai, hai) + DEFINE_LANGUAGE_CODE ("Haitian; Haitian Creole", ht, hat, hat) + DEFINE_LANGUAGE_CODE ("Hausa", ha, hau, hau) +@@ -337,7 +337,7 @@ + DEFINE_LANGUAGE_CODE3 ("North American Indian", nai, nai) + DEFINE_LANGUAGE_CODE ("Northern Sami", se, sme, sme) + DEFINE_LANGUAGE_CODE3 ("Northern Sotho; Pedi; Sepedi", nso, nso) +-DEFINE_LANGUAGE_CODE ("Norwegian Bokmål", nb, nob, nob) ++DEFINE_LANGUAGE_CODE ("Norwegian BokmÃ¥l", nb, nob, nob) + DEFINE_LANGUAGE_CODE ("Norwegian Nynorsk", nn, nno, nno) + DEFINE_LANGUAGE_CODE ("Norwegian", no, nor, nor) + DEFINE_LANGUAGE_CODE3 ("Nubian languages", nub, nub) +@@ -345,9 +345,9 @@ + DEFINE_LANGUAGE_CODE3 ("Nyankole", nyn, nyn) + DEFINE_LANGUAGE_CODE3 ("Nyoro", nyo, nyo) + DEFINE_LANGUAGE_CODE3 ("Nzima", nzi, nzi) +-DEFINE_LANGUAGE_CODE ("Occitan (post 1500); Provençal", oc, oci, oci) ++DEFINE_LANGUAGE_CODE ("Occitan (post 1500); Provençal", oc, oci, oci) + DEFINE_LANGUAGE_CODE ("Ojibwa", oj, oji, oji) +-DEFINE_LANGUAGE_CODE ("Oriya", or, ori, ori) ++DEFINE_LANGUAGE_CODE ("Odia", or, ori, ori) + DEFINE_LANGUAGE_CODE ("Oromo", om, orm, orm) + DEFINE_LANGUAGE_CODE3 ("Osage", osa, osa) + DEFINE_LANGUAGE_CODE ("Ossetian; Ossetic", os, oss, oss) +@@ -368,7 +368,7 @@ + DEFINE_LANGUAGE_CODE ("Polish", pl, pol, pol) + DEFINE_LANGUAGE_CODE ("Portuguese", pt, por, por) + DEFINE_LANGUAGE_CODE3 ("Prakrit languages", pra, pra) +-DEFINE_LANGUAGE_CODE3 ("Provençal, Old (to 1500)", pro, pro) ++DEFINE_LANGUAGE_CODE3 ("Provençal, Old (to 1500)", pro, pro) + DEFINE_LANGUAGE_CODE ("Pushto", ps, pus, pus) + DEFINE_LANGUAGE_CODE ("Quechua", qu, que, que) + DEFINE_LANGUAGE_CODE ("Raeto-Romance", rm, roh, roh) +@@ -476,7 +476,7 @@ + DEFINE_LANGUAGE_CODE3 ("Vai", vai, vai) + DEFINE_LANGUAGE_CODE ("Venda", ve, ven, ven) + DEFINE_LANGUAGE_CODE ("Vietnamese", vi, vie, vie) +-DEFINE_LANGUAGE_CODE ("Volapük", vo, vol, vol) ++DEFINE_LANGUAGE_CODE ("Volapük", vo, vol, vol) + DEFINE_LANGUAGE_CODE3 ("Votic", vot, vot) + DEFINE_LANGUAGE_CODE3 ("Wakashan languages", wak, wak) + DEFINE_LANGUAGE_CODE3 ("Walser", wae, wae) +diff -urNglibc-2.17-c758a686/localedata/locales/or_INglibc-2.17-c758a686/localedata/locales/or_IN +--- glibc-2.17-c758a686/localedata/locales/or_IN 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/localedata/locales/or_IN 2013-12-11 09:52:26.932931534 -0500 +@@ -1,19 +1,19 @@ + comment_char % + escape_char / + +-% Oriya locale for India. ++% Odia locale for India. + % Contributed by Masahide Washizawa + + %%%%%%%%%%%%% + LC_IDENTIFICATION +-title "Oriya language locale for India" ++title "Odia language locale for India" + source "IBM AP Linux Technology Center, Yamato Software Laboratory" + address "1623-14, Shimotsuruma, Yamato-shi, Kanagawa-ken, 242-8502, Japan" + contact "" + email "bug-glibc@gnu.org" + tel "" + fax "" +-language "Oriya" ++language "Odia" + territory "India" + revision "1.0" + date "2006-05-25" +@@ -35,10 +35,10 @@ + LC_CTYPE + copy "i18n" + +-% Oriya uses the alternate digits U+0B66..U+0B6F ++% Odia uses the alternate digits U+0B66..U+0B6F + outdigit .. + +-% This is used in the scanf family of functions to read Oriya numbers ++% This is used in the scanf family of functions to read Odia numbers + % using "%Id" and such. + map to_inpunct; / + (,); / diff --git a/SOURCES/glibc-rh1039970.patch b/SOURCES/glibc-rh1039970.patch new file mode 100644 index 00000000..f7986a6f --- /dev/null +++ b/SOURCES/glibc-rh1039970.patch @@ -0,0 +1,135 @@ +commit 9a3c6a6ff602c88d7155139a7d7d0000b7b7e946 +Author: Siddhesh Poyarekar +Date: Thu Jan 2 10:05:27 2014 +0530 + + Fix return code from getent netgroup when the netgroup is not found (bz #16366) + +diff -pruN glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +--- glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-03 20:41:12.000000000 -0500 ++++ glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-19 08:36:52.253000000 -0500 +@@ -65,6 +65,55 @@ struct dataset + char strdata[0]; + }; + ++/* Sends a notfound message and prepares a notfound dataset to write to the ++ cache. Returns true if there was enough memory to allocate the dataset and ++ returns the dataset in DATASETP, total bytes to write in TOTALP and the ++ timeout in TIMEOUTP. KEY_COPY is set to point to the copy of the key in the ++ dataset. */ ++static bool ++do_notfound (struct database_dyn *db, int fd, request_header *req, ++ const char *key, struct dataset **datasetp, ssize_t *totalp, ++ time_t *timeoutp, char **key_copy) ++{ ++ struct dataset *dataset; ++ ssize_t total; ++ time_t timeout; ++ bool cacheable = false; ++ ++ total = sizeof (notfound); ++ timeout = time (NULL) + db->negtimeout; ++ ++ if (fd != -1) ++ TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL)); ++ ++ dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1); ++ /* If we cannot permanently store the result, so be it. */ ++ if (dataset != NULL) ++ { ++ dataset->head.allocsize = sizeof (struct dataset) + req->key_len; ++ dataset->head.recsize = total; ++ dataset->head.notfound = true; ++ dataset->head.nreloads = 0; ++ dataset->head.usable = true; ++ ++ /* Compute the timeout time. */ ++ timeout = dataset->head.timeout = time (NULL) + db->negtimeout; ++ dataset->head.ttl = db->negtimeout; ++ ++ /* This is the reply. */ ++ memcpy (&dataset->resp, ¬found, total); ++ ++ /* Copy the key data. */ ++ memcpy (dataset->strdata, key, req->key_len); ++ *key_copy = dataset->strdata; ++ ++ cacheable = true; ++ } ++ *timeoutp = timeout; ++ *totalp = total; ++ *datasetp = dataset; ++ return cacheable; ++} + + static time_t + addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, +@@ -84,6 +133,7 @@ addgetnetgrentX (struct database_dyn *db + struct dataset *dataset; + bool cacheable = false; + ssize_t total; ++ bool found = false; + + char *key_copy = NULL; + struct __netgrent data; +@@ -103,35 +153,8 @@ addgetnetgrentX (struct database_dyn *db + && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database)) + { + /* No such service. */ +- total = sizeof (notfound); +- timeout = time (NULL) + db->negtimeout; +- +- if (fd != -1) +- TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL)); +- +- dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1); +- /* If we cannot permanently store the result, so be it. */ +- if (dataset != NULL) +- { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = time (NULL) + db->negtimeout; +- dataset->head.ttl = db->negtimeout; +- +- /* This is the reply. */ +- memcpy (&dataset->resp, ¬found, total); +- +- /* Copy the key data. */ +- memcpy (dataset->strdata, key, req->key_len); +- +- cacheable = true; +- } +- ++ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, ++ &key_copy); + goto writeout; + } + +@@ -167,6 +190,7 @@ addgetnetgrentX (struct database_dyn *db + + if (status == NSS_STATUS_SUCCESS) + { ++ found = true; + union + { + enum nss_status (*f) (struct __netgrent *, char *, size_t, +@@ -325,6 +349,15 @@ addgetnetgrentX (struct database_dyn *db + } + } + ++ /* No results. Return a failure and write out a notfound record in the ++ cache. */ ++ if (!found) ++ { ++ cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout, ++ &key_copy); ++ goto writeout; ++ } ++ + total = buffilled; + + /* Fill in the dataset. */ diff --git a/SOURCES/glibc-rh1046199.patch b/SOURCES/glibc-rh1046199.patch new file mode 100644 index 00000000..6909e326 --- /dev/null +++ b/SOURCES/glibc-rh1046199.patch @@ -0,0 +1,23 @@ +commit d41242129ba693cdbc8db85b846fcaccf9f0b7c4 +Author: Siddhesh Poyarekar +Date: Thu Jan 2 10:03:12 2014 +0530 + + Fix infinite loop in nscd when netgroup is empty (bz #16365) + +diff -pruN glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +--- glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-20 04:38:40.432000000 -0500 ++++ glibc-2.17-c758a686/nscd/netgroupcache.c 2013-12-20 04:37:29.945000000 -0500 +@@ -204,9 +204,10 @@ addgetnetgrentX (struct database_dyn *db + int e; + status = getfct.f (&data, buffer + buffilled, + buflen - buffilled, &e); +- if (status == NSS_STATUS_RETURN) +- /* This was the last one for this group. Look +- at next group if available. */ ++ if (status == NSS_STATUS_RETURN ++ || status == NSS_STATUS_NOTFOUND) ++ /* This was either the last one for this group or the ++ group was empty. Look at next group if available. */ + break; + if (status == NSS_STATUS_SUCCESS) + { diff --git a/SOURCES/glibc-rh1047983.patch b/SOURCES/glibc-rh1047983.patch new file mode 100644 index 00000000..9a740f6a --- /dev/null +++ b/SOURCES/glibc-rh1047983.patch @@ -0,0 +1,555 @@ +commit 5a4c6d53f50b264d60cf6453576ca2810c7890b7 +Author: Siddhesh Poyarekar +Date: Thu Nov 28 17:18:12 2013 +0530 + + Get canonical name in getaddrinfo from hosts file for AF_INET (fixes 16077) + + AF_INET lookup in hosts file uses _nss_files_gethostbyname2_r, which + is not capable of returning a canonical name if it has found one. + This change adds _nss_files_gethostbyname3_r, which wraps around + _nss_files_gethostbyname2_r and then returns result.h_name as the + canonical name. + +diff --git glibc-2.17-c758a686/nss/Versions glibc-2.17-c758a686/nss/Versions +index d13d570..f8ababc 100644 +--- glibc-2.17-c758a686/nss/Versions ++++ glibc-2.17-c758a686/nss/Versions +@@ -40,6 +40,7 @@ libnss_files { + _nss_files_endhostent; + _nss_files_gethostbyaddr_r; + _nss_files_gethostbyname2_r; ++ _nss_files_gethostbyname3_r; + _nss_files_gethostbyname4_r; + _nss_files_gethostbyname_r; + _nss_files_gethostent_r; +diff --git glibc-2.17-c758a686/nss/nss_files/files-hosts.c glibc-2.17-c758a686/nss/nss_files/files-hosts.c +index 6db2535..957c9aa 100644 +--- glibc-2.17-c758a686/nss/nss_files/files-hosts.c ++++ glibc-2.17-c758a686/nss/nss_files/files-hosts.c +@@ -97,262 +97,12 @@ LINE_PARSER + STRING_FIELD (result->h_name, isspace, 1); + }) + +- +- +-#define HOST_DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \ +-enum nss_status \ +-_nss_files_get##name##_r (proto, \ +- struct STRUCTURE *result, char *buffer, \ +- size_t buflen, int *errnop H_ERRNO_PROTO) \ +-{ \ +- uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data); \ +- buffer += pad; \ +- buflen = buflen > pad ? buflen - pad : 0; \ +- \ +- __libc_lock_lock (lock); \ +- \ +- /* Reset file pointer to beginning or open file. */ \ +- enum nss_status status = internal_setent (keep_stream); \ +- \ +- if (status == NSS_STATUS_SUCCESS) \ +- { \ +- /* Tell getent function that we have repositioned the file pointer. */ \ +- last_use = getby; \ +- \ +- while ((status = internal_getent (result, buffer, buflen, errnop \ +- H_ERRNO_ARG EXTRA_ARGS_VALUE)) \ +- == NSS_STATUS_SUCCESS) \ +- { break_if_match } \ +- \ +- if (status == NSS_STATUS_SUCCESS \ +- && _res_hconf.flags & HCONF_FLAG_MULTI) \ +- { \ +- /* We have to get all host entries from the file. */ \ +- size_t tmp_buflen = MIN (buflen, 4096); \ +- char tmp_buffer_stack[tmp_buflen] \ +- __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\ +- char *tmp_buffer = tmp_buffer_stack; \ +- struct hostent tmp_result_buf; \ +- int naddrs = 1; \ +- int naliases = 0; \ +- char *bufferend; \ +- bool tmp_buffer_malloced = false; \ +- \ +- while (result->h_aliases[naliases] != NULL) \ +- ++naliases; \ +- \ +- bufferend = (char *) &result->h_aliases[naliases + 1]; \ +- \ +- again: \ +- while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \ +- tmp_buflen, errnop H_ERRNO_ARG \ +- EXTRA_ARGS_VALUE)) \ +- == NSS_STATUS_SUCCESS) \ +- { \ +- int matches = 1; \ +- struct hostent *old_result = result; \ +- result = &tmp_result_buf; \ +- /* The following piece is a bit clumsy but we want to use the \ +- `break_if_match' value. The optimizer should do its \ +- job. */ \ +- do \ +- { \ +- break_if_match \ +- result = old_result; \ +- } \ +- while ((matches = 0)); \ +- \ +- if (matches) \ +- { \ +- /* We could be very clever and try to recycle a few bytes \ +- in the buffer instead of generating new arrays. But \ +- we are not doing this here since it's more work than \ +- it's worth. Simply let the user provide a bit bigger \ +- buffer. */ \ +- char **new_h_addr_list; \ +- char **new_h_aliases; \ +- int newaliases = 0; \ +- size_t newstrlen = 0; \ +- int cnt; \ +- \ +- /* Count the new aliases and the length of the strings. */ \ +- while (tmp_result_buf.h_aliases[newaliases] != NULL) \ +- { \ +- char *cp = tmp_result_buf.h_aliases[newaliases]; \ +- ++newaliases; \ +- newstrlen += strlen (cp) + 1; \ +- } \ +- /* If the real name is different add it also to the \ +- aliases. This means that there is a duplication \ +- in the alias list but this is really the user's \ +- problem. */ \ +- if (strcmp (old_result->h_name, \ +- tmp_result_buf.h_name) != 0) \ +- { \ +- ++newaliases; \ +- newstrlen += strlen (tmp_result_buf.h_name) + 1; \ +- } \ +- \ +- /* Make sure bufferend is aligned. */ \ +- assert ((bufferend - (char *) 0) % sizeof (char *) == 0); \ +- \ +- /* Now we can check whether the buffer is large enough. \ +- 16 is the maximal size of the IP address. */ \ +- if (bufferend + 16 + (naddrs + 2) * sizeof (char *) \ +- + roundup (newstrlen, sizeof (char *)) \ +- + (naliases + newaliases + 1) * sizeof (char *) \ +- >= buffer + buflen) \ +- { \ +- *errnop = ERANGE; \ +- *herrnop = NETDB_INTERNAL; \ +- status = NSS_STATUS_TRYAGAIN; \ +- goto out; \ +- } \ +- \ +- new_h_addr_list = \ +- (char **) (bufferend \ +- + roundup (newstrlen, sizeof (char *)) \ +- + 16); \ +- new_h_aliases = \ +- (char **) ((char *) new_h_addr_list \ +- + (naddrs + 2) * sizeof (char *)); \ +- \ +- /* Copy the old data in the new arrays. */ \ +- for (cnt = 0; cnt < naddrs; ++cnt) \ +- new_h_addr_list[cnt] = old_result->h_addr_list[cnt]; \ +- \ +- for (cnt = 0; cnt < naliases; ++cnt) \ +- new_h_aliases[cnt] = old_result->h_aliases[cnt]; \ +- \ +- /* Store the new strings. */ \ +- cnt = 0; \ +- while (tmp_result_buf.h_aliases[cnt] != NULL) \ +- { \ +- new_h_aliases[naliases++] = bufferend; \ +- bufferend = (__stpcpy (bufferend, \ +- tmp_result_buf.h_aliases[cnt]) \ +- + 1); \ +- ++cnt; \ +- } \ +- \ +- if (cnt < newaliases) \ +- { \ +- new_h_aliases[naliases++] = bufferend; \ +- bufferend = __stpcpy (bufferend, \ +- tmp_result_buf.h_name) + 1; \ +- } \ +- \ +- /* Final NULL pointer. */ \ +- new_h_aliases[naliases] = NULL; \ +- \ +- /* Round up the buffer end address. */ \ +- bufferend += (sizeof (char *) \ +- - ((bufferend - (char *) 0) \ +- % sizeof (char *))) % sizeof (char *); \ +- \ +- /* Now the new address. */ \ +- new_h_addr_list[naddrs++] = \ +- memcpy (bufferend, tmp_result_buf.h_addr, \ +- tmp_result_buf.h_length); \ +- \ +- /* Also here a final NULL pointer. */ \ +- new_h_addr_list[naddrs] = NULL; \ +- \ +- /* Store the new array pointers. */ \ +- old_result->h_aliases = new_h_aliases; \ +- old_result->h_addr_list = new_h_addr_list; \ +- \ +- /* Compute the new buffer end. */ \ +- bufferend = (char *) &new_h_aliases[naliases + 1]; \ +- assert (bufferend <= buffer + buflen); \ +- \ +- result = old_result; \ +- } \ +- } \ +- \ +- if (status == NSS_STATUS_TRYAGAIN) \ +- { \ +- size_t newsize = 2 * tmp_buflen; \ +- if (tmp_buffer_malloced) \ +- { \ +- char *newp = realloc (tmp_buffer, newsize); \ +- if (newp != NULL) \ +- { \ +- assert ((((uintptr_t) newp) \ +- & (__alignof__ (struct hostent_data) - 1)) \ +- == 0); \ +- tmp_buffer = newp; \ +- tmp_buflen = newsize; \ +- goto again; \ +- } \ +- } \ +- else if (!__libc_use_alloca (buflen + newsize)) \ +- { \ +- tmp_buffer = malloc (newsize); \ +- if (tmp_buffer != NULL) \ +- { \ +- assert ((((uintptr_t) tmp_buffer) \ +- & (__alignof__ (struct hostent_data) - 1)) \ +- == 0); \ +- tmp_buffer_malloced = true; \ +- tmp_buflen = newsize; \ +- goto again; \ +- } \ +- } \ +- else \ +- { \ +- tmp_buffer \ +- = extend_alloca (tmp_buffer, tmp_buflen, \ +- newsize \ +- + __alignof__ (struct hostent_data)); \ +- tmp_buffer = (char *) (((uintptr_t) tmp_buffer \ +- + __alignof__ (struct hostent_data) \ +- - 1) \ +- & ~(__alignof__ (struct hostent_data)\ +- - 1)); \ +- goto again; \ +- } \ +- } \ +- else \ +- status = NSS_STATUS_SUCCESS; \ +- out: \ +- if (tmp_buffer_malloced) \ +- free (tmp_buffer); \ +- } \ +- \ +- \ +- if (! keep_stream) \ +- internal_endent (); \ +- } \ +- \ +- __libc_lock_unlock (lock); \ +- \ +- return status; \ +-} +- +- + #define EXTRA_ARGS_VALUE \ + , ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \ + ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0) + #include "files-XXX.c" +-HOST_DB_LOOKUP (hostbyname, ,, +- { +- LOOKUP_NAME_CASE (h_name, h_aliases) +- }, const char *name) + #undef EXTRA_ARGS_VALUE + +- +-/* XXX Is using _res to determine whether we want to convert IPv4 addresses +- to IPv6 addresses really the right thing to do? */ +-#define EXTRA_ARGS_VALUE \ +- , af, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0) +-HOST_DB_LOOKUP (hostbyname2, ,, +- { +- LOOKUP_NAME_CASE (h_name, h_aliases) +- }, const char *name, int af) +-#undef EXTRA_ARGS_VALUE +- +- + /* We only need to consider IPv4 mapped addresses if the input to the + gethostbyaddr() function is an IPv6 address. */ + #define EXTRA_ARGS_VALUE \ +@@ -365,6 +115,263 @@ DB_LOOKUP (hostbyaddr, ,,, + }, const void *addr, socklen_t len, int af) + #undef EXTRA_ARGS_VALUE + ++enum nss_status ++_nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result, ++ char *buffer, size_t buflen, int *errnop, ++ int *herrnop, int32_t *ttlp, char **canonp) ++{ ++ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct hostent_data); ++ buffer += pad; ++ buflen = buflen > pad ? buflen - pad : 0; ++ ++ __libc_lock_lock (lock); ++ ++ /* Reset file pointer to beginning or open file. */ ++ enum nss_status status = internal_setent (keep_stream); ++ ++ if (status == NSS_STATUS_SUCCESS) ++ { ++ /* XXX Is using _res to determine whether we want to convert IPv4 ++ addresses to IPv6 addresses really the right thing to do? */ ++ int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0); ++ ++ /* Tell getent function that we have repositioned the file pointer. */ ++ last_use = getby; ++ ++ while ((status = internal_getent (result, buffer, buflen, errnop, ++ herrnop, af, flags)) ++ == NSS_STATUS_SUCCESS) ++ { ++ LOOKUP_NAME_CASE (h_name, h_aliases) ++ } ++ ++ if (status == NSS_STATUS_SUCCESS ++ && _res_hconf.flags & HCONF_FLAG_MULTI) ++ { ++ /* We have to get all host entries from the file. */ ++ size_t tmp_buflen = MIN (buflen, 4096); ++ char tmp_buffer_stack[tmp_buflen] ++ __attribute__ ((__aligned__ (__alignof__ (struct hostent_data)))); ++ char *tmp_buffer = tmp_buffer_stack; ++ struct hostent tmp_result_buf; ++ int naddrs = 1; ++ int naliases = 0; ++ char *bufferend; ++ bool tmp_buffer_malloced = false; ++ ++ while (result->h_aliases[naliases] != NULL) ++ ++naliases; ++ ++ bufferend = (char *) &result->h_aliases[naliases + 1]; ++ ++ again: ++ while ((status = internal_getent (&tmp_result_buf, tmp_buffer, ++ tmp_buflen, errnop, herrnop, af, ++ flags)) ++ == NSS_STATUS_SUCCESS) ++ { ++ int matches = 1; ++ struct hostent *old_result = result; ++ result = &tmp_result_buf; ++ /* The following piece is a bit clumsy but we want to use the ++ `LOOKUP_NAME_CASE' value. The optimizer should do its ++ job. */ ++ do ++ { ++ LOOKUP_NAME_CASE (h_name, h_aliases) ++ result = old_result; ++ } ++ while ((matches = 0)); ++ ++ if (matches) ++ { ++ /* We could be very clever and try to recycle a few bytes ++ in the buffer instead of generating new arrays. But ++ we are not doing this here since it's more work than ++ it's worth. Simply let the user provide a bit bigger ++ buffer. */ ++ char **new_h_addr_list; ++ char **new_h_aliases; ++ int newaliases = 0; ++ size_t newstrlen = 0; ++ int cnt; ++ ++ /* Count the new aliases and the length of the strings. */ ++ while (tmp_result_buf.h_aliases[newaliases] != NULL) ++ { ++ char *cp = tmp_result_buf.h_aliases[newaliases]; ++ ++newaliases; ++ newstrlen += strlen (cp) + 1; ++ } ++ /* If the real name is different add it also to the ++ aliases. This means that there is a duplication ++ in the alias list but this is really the user's ++ problem. */ ++ if (strcmp (old_result->h_name, ++ tmp_result_buf.h_name) != 0) ++ { ++ ++newaliases; ++ newstrlen += strlen (tmp_result_buf.h_name) + 1; ++ } ++ ++ /* Make sure bufferend is aligned. */ ++ assert ((bufferend - (char *) 0) % sizeof (char *) == 0); ++ ++ /* Now we can check whether the buffer is large enough. ++ 16 is the maximal size of the IP address. */ ++ if (bufferend + 16 + (naddrs + 2) * sizeof (char *) ++ + roundup (newstrlen, sizeof (char *)) ++ + (naliases + newaliases + 1) * sizeof (char *) ++ >= buffer + buflen) ++ { ++ *errnop = ERANGE; ++ *herrnop = NETDB_INTERNAL; ++ status = NSS_STATUS_TRYAGAIN; ++ goto out; ++ } ++ ++ new_h_addr_list = ++ (char **) (bufferend ++ + roundup (newstrlen, sizeof (char *)) ++ + 16); ++ new_h_aliases = ++ (char **) ((char *) new_h_addr_list ++ + (naddrs + 2) * sizeof (char *)); ++ ++ /* Copy the old data in the new arrays. */ ++ for (cnt = 0; cnt < naddrs; ++cnt) ++ new_h_addr_list[cnt] = old_result->h_addr_list[cnt]; ++ ++ for (cnt = 0; cnt < naliases; ++cnt) ++ new_h_aliases[cnt] = old_result->h_aliases[cnt]; ++ ++ /* Store the new strings. */ ++ cnt = 0; ++ while (tmp_result_buf.h_aliases[cnt] != NULL) ++ { ++ new_h_aliases[naliases++] = bufferend; ++ bufferend = (__stpcpy (bufferend, ++ tmp_result_buf.h_aliases[cnt]) ++ + 1); ++ ++cnt; ++ } ++ ++ if (cnt < newaliases) ++ { ++ new_h_aliases[naliases++] = bufferend; ++ bufferend = __stpcpy (bufferend, ++ tmp_result_buf.h_name) + 1; ++ } ++ ++ /* Final NULL pointer. */ ++ new_h_aliases[naliases] = NULL; ++ ++ /* Round up the buffer end address. */ ++ bufferend += (sizeof (char *) ++ - ((bufferend - (char *) 0) ++ % sizeof (char *))) % sizeof (char *); ++ ++ /* Now the new address. */ ++ new_h_addr_list[naddrs++] = ++ memcpy (bufferend, tmp_result_buf.h_addr, ++ tmp_result_buf.h_length); ++ ++ /* Also here a final NULL pointer. */ ++ new_h_addr_list[naddrs] = NULL; ++ ++ /* Store the new array pointers. */ ++ old_result->h_aliases = new_h_aliases; ++ old_result->h_addr_list = new_h_addr_list; ++ ++ /* Compute the new buffer end. */ ++ bufferend = (char *) &new_h_aliases[naliases + 1]; ++ assert (bufferend <= buffer + buflen); ++ ++ result = old_result; ++ } ++ } ++ ++ if (status == NSS_STATUS_TRYAGAIN) ++ { ++ size_t newsize = 2 * tmp_buflen; ++ if (tmp_buffer_malloced) ++ { ++ char *newp = realloc (tmp_buffer, newsize); ++ if (newp != NULL) ++ { ++ assert ((((uintptr_t) newp) ++ & (__alignof__ (struct hostent_data) - 1)) ++ == 0); ++ tmp_buffer = newp; ++ tmp_buflen = newsize; ++ goto again; ++ } ++ } ++ else if (!__libc_use_alloca (buflen + newsize)) ++ { ++ tmp_buffer = malloc (newsize); ++ if (tmp_buffer != NULL) ++ { ++ assert ((((uintptr_t) tmp_buffer) ++ & (__alignof__ (struct hostent_data) - 1)) ++ == 0); ++ tmp_buffer_malloced = true; ++ tmp_buflen = newsize; ++ goto again; ++ } ++ } ++ else ++ { ++ tmp_buffer ++ = extend_alloca (tmp_buffer, tmp_buflen, ++ newsize ++ + __alignof__ (struct hostent_data)); ++ tmp_buffer = (char *) (((uintptr_t) tmp_buffer ++ + __alignof__ (struct hostent_data) ++ - 1) ++ & ~(__alignof__ (struct hostent_data) ++ - 1)); ++ goto again; ++ } ++ } ++ else ++ status = NSS_STATUS_SUCCESS; ++ out: ++ if (tmp_buffer_malloced) ++ free (tmp_buffer); ++ } ++ ++ if (! keep_stream) ++ internal_endent (); ++ } ++ ++ if (canonp && status == NSS_STATUS_SUCCESS) ++ *canonp = result->h_name; ++ ++ __libc_lock_unlock (lock); ++ ++ return status; ++} ++ ++enum nss_status ++_nss_files_gethostbyname_r (const char *name, struct hostent *result, ++ char *buffer, size_t buflen, int *errnop, ++ int *herrnop) ++{ ++ int af = ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET); ++ ++ return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen, ++ errnop, herrnop, NULL, NULL); ++} ++ ++enum nss_status ++_nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result, ++ char *buffer, size_t buflen, int *errnop, ++ int *herrnop) ++{ ++ return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen, ++ errnop, herrnop, NULL, NULL); ++} + + enum nss_status + _nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, diff --git a/SOURCES/glibc-rh1048036.patch b/SOURCES/glibc-rh1048036.patch new file mode 100644 index 00000000..95c7ba4f --- /dev/null +++ b/SOURCES/glibc-rh1048036.patch @@ -0,0 +1,29 @@ +diff --git glibc-2.17-c758a686/libio/wfileops.c glibc-2.17-c758a686/libio/wfileops.c +index 87d3cdc..877fc1f 100644 +--- glibc-2.17-c758a686/libio/wfileops.c ++++ glibc-2.17-c758a686/libio/wfileops.c +@@ -715,7 +715,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + - fp->_wide_data->_IO_write_base) / clen; + else + { +- enum __codecvt_result status; ++ enum __codecvt_result status = __codecvt_ok; + delta = (fp->_wide_data->_IO_write_ptr + - fp->_wide_data->_IO_write_base); + const wchar_t *write_base = fp->_wide_data->_IO_write_base; +@@ -728,9 +728,12 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + flush buffers for every ftell. */ + do + { +- /* Ugh, no point trying to avoid the flush. Just do it +- and go back to how it was with the read mode. */ +- if (delta > 0 && new_write_ptr == fp->_IO_buf_end) ++ /* There is not enough space in the buffer to do the entire ++ conversion, so there is no point trying to avoid the ++ buffer flush. Just do it and go back to how it was with ++ the read mode. */ ++ if (status == __codecvt_partial ++ || (delta > 0 && new_write_ptr == fp->_IO_buf_end)) + { + if (_IO_switch_to_wget_mode (fp)) + return WEOF; diff --git a/SOURCES/glibc-rh1048123.patch b/SOURCES/glibc-rh1048123.patch new file mode 100644 index 00000000..7edc4bca --- /dev/null +++ b/SOURCES/glibc-rh1048123.patch @@ -0,0 +1,515 @@ +commit 0582f6b3d6fab2128ee43a06250571922ee7c1e3 +Author: Andreas Schwab +Date: Sun Dec 23 09:45:07 2012 +0100 + + nscd: don't fork twice + +commit 532a60357ef4c5852cc1bf836cfd9d6f093ef204 +Author: Siddhesh Poyarekar +Date: Mon Mar 3 22:51:39 2014 +0530 + + nscd: Improved support for tracking startup failure in nscd service (BZ #16639) + + Currently, the nscd parent process parses commandline options and + configuration, forks on startup and immediately exits with a success. + If the child process encounters some error after this, it goes + undetected and any services started up after it may have to repeatedly + check to make sure that the nscd service did actually start up and is + serving requests. + + To make this process more reliable, I have added a pipe between the + parent and child process, through which the child process sends a + notification to the parent informing it of its status. The parent + waits for this status and once it receives it, exits with the + corresponding exit code. So if the child service sends a success + status (0), the parent exits with a success status. Similarly for + error conditions, the child sends the non-zero status code, which the + parent passes on as the exit code. + + This, along with setting the nscd service type to forking in its + systemd configuration file, allows systemd to be certain that the nscd + service is ready and is accepting connections. + + +diff --git glibc-2.17-c758a686/nscd/connections.c glibc-2.17-c758a686/nscd/connections.c +index f463f45..180ae77 100644 +--- glibc-2.17-c758a686/nscd/connections.c ++++ glibc-2.17-c758a686/nscd/connections.c +@@ -649,8 +649,8 @@ cannot create read-only descriptor for \"%s\"; no mmap"), + close (fd); + } + else if (errno == EACCES) +- error (EXIT_FAILURE, 0, _("cannot access '%s'"), +- dbs[cnt].db_filename); ++ do_exit (EXIT_FAILURE, 0, _("cannot access '%s'"), ++ dbs[cnt].db_filename); + } + + if (dbs[cnt].head == NULL) +@@ -699,8 +699,7 @@ cannot create read-only descriptor for \"%s\"; no mmap"), + { + dbg_log (_("database for %s corrupted or simultaneously used; remove %s manually if necessary and restart"), + dbnames[cnt], dbs[cnt].db_filename); +- // XXX Correct way to terminate? +- exit (1); ++ do_exit (1, 0, NULL); + } + + if (dbs[cnt].persistent) +@@ -867,7 +866,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), + if (sock < 0) + { + dbg_log (_("cannot open socket: %s"), strerror (errno)); +- exit (errno == EACCES ? 4 : 1); ++ do_exit (errno == EACCES ? 4 : 1, 0, NULL); + } + /* Bind a name to the socket. */ + struct sockaddr_un sock_addr; +@@ -876,7 +875,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), + if (bind (sock, (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0) + { + dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno)); +- exit (errno == EACCES ? 4 : 1); ++ do_exit (errno == EACCES ? 4 : 1, 0, NULL); + } + + #ifndef __ASSUME_SOCK_CLOEXEC +@@ -888,7 +887,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), + { + dbg_log (_("cannot change socket to nonblocking mode: %s"), + strerror (errno)); +- exit (1); ++ do_exit (1, 0, NULL); + } + + /* The descriptor needs to be closed on exec. */ +@@ -896,7 +895,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), + { + dbg_log (_("cannot set socket to close on exec: %s"), + strerror (errno)); +- exit (1); ++ do_exit (1, 0, NULL); + } + } + #endif +@@ -909,7 +908,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), + { + dbg_log (_("cannot enable socket to accept connections: %s"), + strerror (errno)); +- exit (1); ++ do_exit (1, 0, NULL); + } + + #ifdef HAVE_NETLINK +@@ -953,7 +952,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"), + dbg_log (_("\ + cannot change socket to nonblocking mode: %s"), + strerror (errno)); +- exit (1); ++ do_exit (1, 0, NULL); + } + + /* The descriptor needs to be closed on exec. */ +@@ -962,7 +961,7 @@ cannot change socket to nonblocking mode: %s"), + { + dbg_log (_("cannot set socket to close on exec: %s"), + strerror (errno)); +- exit (1); ++ do_exit (1, 0, NULL); + } + } + # endif +@@ -2392,7 +2391,7 @@ start_threads (void) + if (pthread_cond_init (&dbs[i].prune_cond, &condattr) != 0) + { + dbg_log (_("could not initialize conditional variable")); +- exit (1); ++ do_exit (1, 0, NULL); + } + + pthread_t th; +@@ -2400,7 +2399,7 @@ start_threads (void) + && pthread_create (&th, &attr, nscd_run_prune, (void *) i) != 0) + { + dbg_log (_("could not start clean-up thread; terminating")); +- exit (1); ++ do_exit (1, 0, NULL); + } + } + +@@ -2414,13 +2413,17 @@ start_threads (void) + if (i == 0) + { + dbg_log (_("could not start any worker thread; terminating")); +- exit (1); ++ do_exit (1, 0, NULL); + } + + break; + } + } + ++ /* Now it is safe to let the parent know that we're doing fine and it can ++ exit. */ ++ notify_parent (0); ++ + /* Determine how much room for descriptors we should initially + allocate. This might need to change later if we cap the number + with MAXCONN. */ +@@ -2465,8 +2468,8 @@ begin_drop_privileges (void) + if (pwd == NULL) + { + dbg_log (_("Failed to run nscd as user '%s'"), server_user); +- error (EXIT_FAILURE, 0, _("Failed to run nscd as user '%s'"), +- server_user); ++ do_exit (EXIT_FAILURE, 0, ++ _("Failed to run nscd as user '%s'"), server_user); + } + + server_uid = pwd->pw_uid; +@@ -2483,7 +2486,8 @@ begin_drop_privileges (void) + { + /* This really must never happen. */ + dbg_log (_("Failed to run nscd as user '%s'"), server_user); +- error (EXIT_FAILURE, errno, _("initial getgrouplist failed")); ++ do_exit (EXIT_FAILURE, errno, ++ _("initial getgrouplist failed")); + } + + server_groups = (gid_t *) xmalloc (server_ngroups * sizeof (gid_t)); +@@ -2492,7 +2496,7 @@ begin_drop_privileges (void) + == -1) + { + dbg_log (_("Failed to run nscd as user '%s'"), server_user); +- error (EXIT_FAILURE, errno, _("getgrouplist failed")); ++ do_exit (EXIT_FAILURE, errno, _("getgrouplist failed")); + } + } + +@@ -2510,7 +2514,7 @@ finish_drop_privileges (void) + if (setgroups (server_ngroups, server_groups) == -1) + { + dbg_log (_("Failed to run nscd as user '%s'"), server_user); +- error (EXIT_FAILURE, errno, _("setgroups failed")); ++ do_exit (EXIT_FAILURE, errno, _("setgroups failed")); + } + + int res; +@@ -2521,8 +2525,7 @@ finish_drop_privileges (void) + if (res == -1) + { + dbg_log (_("Failed to run nscd as user '%s'"), server_user); +- perror ("setgid"); +- exit (4); ++ do_exit (4, errno, "setgid"); + } + + if (paranoia) +@@ -2532,8 +2535,7 @@ finish_drop_privileges (void) + if (res == -1) + { + dbg_log (_("Failed to run nscd as user '%s'"), server_user); +- perror ("setuid"); +- exit (4); ++ do_exit (4, errno, "setuid"); + } + + #if defined HAVE_LIBAUDIT && defined HAVE_LIBCAP +diff --git glibc-2.17-c758a686/nscd/nscd.c glibc-2.17-c758a686/nscd/nscd.c +index 63d9d83..5680378 100644 +--- glibc-2.17-c758a686/nscd/nscd.c ++++ glibc-2.17-c758a686/nscd/nscd.c +@@ -39,6 +39,8 @@ + #include + #include + #include ++#include ++#include + + #include "dbg_log.h" + #include "nscd.h" +@@ -101,6 +103,7 @@ gid_t old_gid; + + static int check_pid (const char *file); + static int write_pid (const char *file); ++static int monitor_child (int fd); + + /* Name and version of program. */ + static void print_version (FILE *stream, struct argp_state *state); +@@ -142,6 +145,7 @@ static struct argp argp = + + /* True if only statistics are requested. */ + static bool get_stats; ++static int parent_fd = -1; + + int + main (int argc, char **argv) +@@ -196,11 +200,27 @@ main (int argc, char **argv) + /* Behave like a daemon. */ + if (run_mode == RUN_DAEMONIZE) + { ++ int fd[2]; ++ ++ if (pipe (fd) != 0) ++ error (EXIT_FAILURE, errno, ++ _("cannot create a pipe to talk to the child")); ++ + pid = fork (); + if (pid == -1) + error (EXIT_FAILURE, errno, _("cannot fork")); + if (pid != 0) +- exit (0); ++ { ++ /* The parent only reads from the child. */ ++ close (fd[1]); ++ exit (monitor_child (fd[0])); ++ } ++ else ++ { ++ /* The child only writes to the parent. */ ++ close (fd[0]); ++ parent_fd = fd[1]; ++ } + } + + int nullfd = open (_PATH_DEVNULL, O_RDWR); +@@ -242,7 +262,8 @@ main (int argc, char **argv) + char *endp; + long int fdn = strtol (dirent->d_name, &endp, 10); + +- if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd) ++ if (*endp == '\0' && fdn != dfdn && fdn >= min_close_fd ++ && fdn != parent_fd) + close ((int) fdn); + } + +@@ -250,22 +271,14 @@ main (int argc, char **argv) + } + else + for (i = min_close_fd; i < getdtablesize (); i++) +- close (i); ++ if (i != parent_fd) ++ close (i); + +- if (run_mode == RUN_DAEMONIZE) +- { +- pid = fork (); +- if (pid == -1) +- error (EXIT_FAILURE, errno, _("cannot fork")); +- if (pid != 0) +- exit (0); +- } +- + setsid (); + + if (chdir ("/") != 0) +- error (EXIT_FAILURE, errno, +- _("cannot change current working directory to \"/\"")); ++ do_exit (EXIT_FAILURE, errno, ++ _("cannot change current working directory to \"/\"")); + + openlog ("nscd", LOG_CONS | LOG_ODELAY, LOG_DAEMON); + +@@ -592,3 +614,79 @@ write_pid (const char *file) + + return result; + } ++ ++static int ++monitor_child (int fd) ++{ ++ int child_ret = 0; ++ int ret = read (fd, &child_ret, sizeof (child_ret)); ++ ++ /* The child terminated with an error, either via exit or some other abnormal ++ method, like a segfault. */ ++ if (ret <= 0 || child_ret != 0) ++ { ++ int err = wait (&child_ret); ++ ++ if (err < 0) ++ { ++ fprintf (stderr, _("wait failed")); ++ return 1; ++ } ++ ++ fprintf (stderr, _("child exited with status %d"), ++ WEXITSTATUS (child_ret)); ++ if (WIFSIGNALED (child_ret)) ++ fprintf (stderr, _(", terminated by signal %d.\n"), ++ WTERMSIG (child_ret)); ++ else ++ fprintf (stderr, ".\n"); ++ } ++ ++ /* We have the child status, so exit with that code. */ ++ close (fd); ++ ++ return child_ret; ++} ++ ++void ++do_exit (int child_ret, int errnum, const char *format, ...) ++{ ++ if (parent_fd != -1) ++ { ++ int ret = write (parent_fd, &child_ret, sizeof (child_ret)); ++ assert (ret == sizeof (child_ret)); ++ close (parent_fd); ++ } ++ ++ if (format != NULL) ++ { ++ /* Emulate error() since we don't have a va_list variant for it. */ ++ va_list argp; ++ ++ fflush (stdout); ++ ++ fprintf (stderr, "%s: ", program_invocation_name); ++ ++ va_start (argp, format); ++ vfprintf (stderr, format, argp); ++ va_end (argp); ++ ++ fprintf (stderr, ": %s\n", strerror (errnum)); ++ fflush (stderr); ++ } ++ ++ /* Finally, exit. */ ++ exit (child_ret); ++} ++ ++void ++notify_parent (int child_ret) ++{ ++ if (parent_fd == -1) ++ return; ++ ++ int ret = write (parent_fd, &child_ret, sizeof (child_ret)); ++ assert (ret == sizeof (child_ret)); ++ close (parent_fd); ++ parent_fd = -1; ++} +diff --git glibc-2.17-c758a686/nscd/nscd.h glibc-2.17-c758a686/nscd/nscd.h +index 972f462..529b3f5 100644 +--- glibc-2.17-c758a686/nscd/nscd.h ++++ glibc-2.17-c758a686/nscd/nscd.h +@@ -205,6 +205,8 @@ extern gid_t old_gid; + /* nscd.c */ + extern void termination_handler (int signum) __attribute__ ((__noreturn__)); + extern int nscd_open_socket (void); ++void notify_parent (int child_ret); ++void do_exit (int child_ret, int errnum, const char *format, ...); + + /* connections.c */ + extern void nscd_init (void); +diff --git glibc-2.17-c758a686/nscd/selinux.c glibc-2.17-c758a686/nscd/selinux.c +index e477254..46b0ea9 100644 +--- glibc-2.17-c758a686/nscd/selinux.c ++++ glibc-2.17-c758a686/nscd/selinux.c +@@ -179,7 +179,7 @@ preserve_capabilities (void) + if (prctl (PR_SET_KEEPCAPS, 1) == -1) + { + dbg_log (_("Failed to set keep-capabilities")); +- error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed")); ++ do_exit (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed")); + /* NOTREACHED */ + } + +@@ -194,7 +194,7 @@ preserve_capabilities (void) + cap_free (tmp_caps); + + dbg_log (_("Failed to initialize drop of capabilities")); +- error (EXIT_FAILURE, 0, _("cap_init failed")); ++ do_exit (EXIT_FAILURE, 0, _("cap_init failed")); + } + + /* There is no reason why these should not work. */ +@@ -216,7 +216,7 @@ preserve_capabilities (void) + { + cap_free (new_caps); + dbg_log (_("Failed to drop capabilities")); +- error (EXIT_FAILURE, 0, _("cap_set_proc failed")); ++ do_exit (EXIT_FAILURE, 0, _("cap_set_proc failed")); + } + + return new_caps; +@@ -233,7 +233,7 @@ install_real_capabilities (cap_t new_caps) + { + cap_free (new_caps); + dbg_log (_("Failed to drop capabilities")); +- error (EXIT_FAILURE, 0, _("cap_set_proc failed")); ++ do_exit (EXIT_FAILURE, 0, _("cap_set_proc failed")); + /* NOTREACHED */ + } + +@@ -242,7 +242,7 @@ install_real_capabilities (cap_t new_caps) + if (prctl (PR_SET_KEEPCAPS, 0) == -1) + { + dbg_log (_("Failed to unset keep-capabilities")); +- error (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed")); ++ do_exit (EXIT_FAILURE, errno, _("prctl(KEEPCAPS) failed")); + /* NOTREACHED */ + } + } +@@ -258,7 +258,7 @@ nscd_selinux_enabled (int *selinux_enabled) + if (*selinux_enabled < 0) + { + dbg_log (_("Failed to determine if kernel supports SELinux")); +- exit (EXIT_FAILURE); ++ do_exit (EXIT_FAILURE, 0, NULL); + } + } + +@@ -272,7 +272,7 @@ avc_create_thread (void (*run) (void)) + rc = + pthread_create (&avc_notify_thread, NULL, (void *(*) (void *)) run, NULL); + if (rc != 0) +- error (EXIT_FAILURE, rc, _("Failed to start AVC thread")); ++ do_exit (EXIT_FAILURE, rc, _("Failed to start AVC thread")); + + return &avc_notify_thread; + } +@@ -294,7 +294,7 @@ avc_alloc_lock (void) + + avc_mutex = malloc (sizeof (pthread_mutex_t)); + if (avc_mutex == NULL) +- error (EXIT_FAILURE, errno, _("Failed to create AVC lock")); ++ do_exit (EXIT_FAILURE, errno, _("Failed to create AVC lock")); + pthread_mutex_init (avc_mutex, NULL); + + return avc_mutex; +@@ -334,7 +334,7 @@ nscd_avc_init (void) + avc_entry_ref_init (&aeref); + + if (avc_init ("avc", NULL, &log_cb, &thread_cb, &lock_cb) < 0) +- error (EXIT_FAILURE, errno, _("Failed to start AVC")); ++ do_exit (EXIT_FAILURE, errno, _("Failed to start AVC")); + else + dbg_log (_("Access Vector Cache (AVC) started")); + #ifdef HAVE_LIBAUDIT +--- glibc-2.17-c758a686/releng/nscd.service 2012-11-06 03:03:19.000000000 +0530 ++++ glibc-2.17-c758a686/releng/nscd.service 2014-02-28 16:59:51.096630222 +0530 +@@ -1,10 +1,13 @@ ++# systemd service file for nscd ++ + [Unit] + Description=Name Service Cache Daemon + After=syslog.target + + [Service] ++Type=forking + EnvironmentFile=-/etc/sysconfig/nscd +-ExecStart=/usr/sbin/nscd --foreground $NSCD_OPTIONS ++ExecStart=/usr/sbin/nscd $NSCD_OPTIONS + ExecStop=/usr/sbin/nscd --shutdown + ExecReload=/usr/sbin/nscd -i passwd + ExecReload=/usr/sbin/nscd -i group +@@ -12,6 +14,7 @@ + ExecReload=/usr/sbin/nscd -i services + ExecReload=/usr/sbin/nscd -i netgroup + Restart=always ++PIDFile=/run/nscd/nscd.pid + + [Install] + WantedBy=multi-user.target diff --git a/SOURCES/glibc-rh1063681.patch b/SOURCES/glibc-rh1063681.patch new file mode 100644 index 00000000..30269d75 --- /dev/null +++ b/SOURCES/glibc-rh1063681.patch @@ -0,0 +1,948 @@ +diff --git glibc-2.17-c758a686/libio/Makefile glibc-2.17-c758a686/libio/Makefile +index 22dbcae..488ee51 100644 +--- glibc-2.17-c758a686/libio/Makefile ++++ glibc-2.17-c758a686/libio/Makefile +@@ -60,7 +60,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ + tst-wmemstream1 tst-wmemstream2 \ + bug-memstream1 bug-wmemstream1 \ + tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ +- tst-fwrite-error ++ tst-fwrite-error tst-ftell-active-handler + ifeq (yes,$(build-shared)) + # Add test-fopenloc only if shared library is enabled since it depends on + # shared localedata objects. +diff --git glibc-2.17-c758a686/libio/fileops.c glibc-2.17-c758a686/libio/fileops.c +index a3499be..2e7bc8d 100644 +--- glibc-2.17-c758a686/libio/fileops.c ++++ glibc-2.17-c758a686/libio/fileops.c +@@ -929,6 +929,93 @@ _IO_file_sync_mmap (_IO_FILE *fp) + return 0; + } + ++/* Get the current file offset using a system call. This is the safest method ++ to get the current file offset, since we are sure that we get the current ++ state of the file. Before the stream handle is activated (by using fread, ++ fwrite, etc.), an application may alter the state of the file descriptor ++ underlying it by calling read/write/lseek on it. Using a cached offset at ++ this point will result in returning the incorrect value. Same is the case ++ when one switches from reading in a+ mode to writing, where the buffer has ++ not been flushed - the cached offset would reflect the reading position ++ while the actual write position would be at the end of the file. ++ ++ do_ftell and do_ftell_wide may resort to using the cached offset in some ++ special cases instead of calling get_file_offset, but those cases should be ++ thoroughly described. */ ++_IO_off64_t ++get_file_offset (_IO_FILE *fp) ++{ ++ if ((fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING) ++ { ++ struct stat64 st; ++ bool ret = (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)); ++ if (ret) ++ return st.st_size; ++ else ++ return EOF; ++ } ++ else ++ return _IO_SYSSEEK (fp, 0, _IO_seek_cur); ++} ++ ++ ++/* ftell{,o} implementation. Don't modify any state of the file pointer while ++ we try to get the current state of the stream. */ ++static _IO_off64_t ++do_ftell (_IO_FILE *fp) ++{ ++ _IO_off64_t result = 0; ++ bool use_cached_offset = false; ++ ++ /* No point looking at unflushed data if we haven't allocated buffers ++ yet. */ ++ if (fp->_IO_buf_base != NULL) ++ { ++ bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base ++ || _IO_in_put_mode (fp)); ++ ++ /* Adjust for unflushed data. */ ++ if (!was_writing) ++ result -= fp->_IO_read_end - fp->_IO_read_ptr; ++ else ++ result += fp->_IO_write_ptr - fp->_IO_read_end; ++ ++ /* It is safe to use the cached offset when available if there is ++ unbuffered data (indicating that the file handle is active) and the ++ handle is not for a file open in a+ mode. The latter condition is ++ because there could be a scenario where there is a switch from read ++ mode to write mode using an fseek to an arbitrary position. In this ++ case, there would be unbuffered data due to be appended to the end of ++ the file, but the offset may not necessarily be the end of the ++ file. It is fine to use the cached offset when the a+ stream is in ++ read mode though, since the offset is maintained correctly in that ++ case. Note that this is not a comprehensive set of cases when the ++ offset is reliable. The offset may be reliable even in some cases ++ where there is no unflushed input and the handle is active, but it's ++ just that we don't have a way to identify that condition reliably. */ ++ use_cached_offset = (result != 0 && fp->_offset != _IO_pos_BAD ++ && ((fp->_flags & (_IO_IS_APPENDING | _IO_NO_READS)) ++ == (_IO_IS_APPENDING | _IO_NO_READS) ++ && was_writing)); ++ } ++ ++ if (use_cached_offset) ++ result += fp->_offset; ++ else ++ result += get_file_offset (fp); ++ ++ if (result == EOF) ++ return result; ++ ++ if (result < 0) ++ { ++ __set_errno (EINVAL); ++ return EOF; ++ } ++ ++ return result; ++} ++ + + _IO_off64_t + _IO_new_file_seekoff (fp, offset, dir, mode) +@@ -940,6 +1027,13 @@ _IO_new_file_seekoff (fp, offset, dir, mode) + _IO_off64_t result; + _IO_off64_t delta, new_offset; + long count; ++ ++ /* Short-circuit into a separate function. We don't want to mix any ++ functionality and we don't want to touch anything inside the FILE ++ object. */ ++ if (mode == 0) ++ return do_ftell (fp); ++ + /* POSIX.1 8.2.3.7 says that after a call the fflush() the file + offset of the underlying file must be exact. */ + int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end +@@ -948,9 +1042,6 @@ _IO_new_file_seekoff (fp, offset, dir, mode) + bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base + || _IO_in_put_mode (fp)); + +- if (mode == 0) +- dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ +- + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set +@@ -958,7 +1049,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode) + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-mapped files. */ +- else if (was_writing && _IO_switch_to_get_mode (fp)) ++ if (was_writing && _IO_switch_to_get_mode (fp)) + return EOF; + + if (fp->_IO_buf_base == NULL) +@@ -978,30 +1069,10 @@ _IO_new_file_seekoff (fp, offset, dir, mode) + { + case _IO_seek_cur: + /* Adjust for read-ahead (bytes is buffer). */ +- if (mode != 0 || !was_writing) +- offset -= fp->_IO_read_end - fp->_IO_read_ptr; +- else +- { +- /* _IO_read_end coincides with fp._offset, so the actual file position +- is fp._offset - (_IO_read_end - new_write_ptr). This is fine +- even if fp._offset is not set, since fp->_IO_read_end is then at +- _IO_buf_base and this adjustment is for unbuffered output. */ +- offset -= fp->_IO_read_end - fp->_IO_write_ptr; +- } ++ offset -= fp->_IO_read_end - fp->_IO_read_ptr; + + if (fp->_offset == _IO_pos_BAD) +- { +- if (mode != 0) +- goto dumb; +- else +- { +- result = _IO_SYSSEEK (fp, 0, dir); +- if (result == EOF) +- return result; +- +- fp->_offset = result; +- } +- } ++ goto dumb; + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; + if (offset < 0) +@@ -1028,10 +1099,6 @@ _IO_new_file_seekoff (fp, offset, dir, mode) + } + /* At this point, dir==_IO_seek_set. */ + +- /* If we are only interested in the current position we've found it now. */ +- if (mode == 0) +- return offset; +- + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) +diff --git glibc-2.17-c758a686/libio/iofdopen.c glibc-2.17-c758a686/libio/iofdopen.c +index 066ff19..3f266f7 100644 +--- glibc-2.17-c758a686/libio/iofdopen.c ++++ glibc-2.17-c758a686/libio/iofdopen.c +@@ -141,9 +141,6 @@ _IO_new_fdopen (fd, mode) + #ifdef _IO_MTSAFE_IO + new_f->fp.file._lock = &new_f->lock; + #endif +- /* Set up initially to use the `maybe_mmap' jump tables rather than using +- __fopen_maybe_mmap to do it, because we need them in place before we +- call _IO_file_attach or else it will allocate a buffer immediately. */ + _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, + #ifdef _G_HAVE_MMAP + (use_mmap && (read_write & _IO_NO_WRITES)) +@@ -159,13 +156,12 @@ _IO_new_fdopen (fd, mode) + #if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; + #endif +- if (_IO_file_attach ((_IO_FILE *) &new_f->fp, fd) == NULL) +- { +- _IO_setb (&new_f->fp.file, NULL, NULL, 0); +- _IO_un_link (&new_f->fp); +- free (new_f); +- return NULL; +- } ++ /* We only need to record the fd because _IO_file_init will have unset the ++ offset. It is important to unset the cached offset because the real ++ offset in the file could change between now and when the handle is ++ activated and we would then mislead ftell into believing that we have a ++ valid offset. */ ++ new_f->fp.file._fileno = fd; + new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE; + + _IO_mask_flags (&new_f->fp.file, read_write, +diff --git glibc-2.17-c758a686/libio/iofwide.c glibc-2.17-c758a686/libio/iofwide.c +index 5cff632..64187e4 100644 +--- glibc-2.17-c758a686/libio/iofwide.c ++++ glibc-2.17-c758a686/libio/iofwide.c +@@ -199,12 +199,6 @@ _IO_fwide (fp, mode) + + /* From now on use the wide character callback functions. */ + ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable; +- +- /* One last twist: we get the current stream position. The wide +- char streams have much more problems with not knowing the +- current position and so we should disable the optimization +- which allows the functions without knowing the position. */ +- fp->_offset = _IO_SYSSEEK (fp, 0, _IO_seek_cur); + } + + /* Set the mode now. */ +diff --git glibc-2.17-c758a686/libio/libioP.h glibc-2.17-c758a686/libio/libioP.h +index 4ca723c..8a7b85b 100644 +--- glibc-2.17-c758a686/libio/libioP.h ++++ glibc-2.17-c758a686/libio/libioP.h +@@ -397,6 +397,7 @@ extern void _IO_wdoallocbuf (_IO_FILE *) __THROW; + libc_hidden_proto (_IO_wdoallocbuf) + extern void _IO_unsave_wmarkers (_IO_FILE *) __THROW; + extern unsigned _IO_adjust_wcolumn (unsigned, const wchar_t *, int) __THROW; ++extern _IO_off64_t get_file_offset (_IO_FILE *fp); + + /* Marker-related function. */ + +diff --git glibc-2.17-c758a686/libio/tst-ftell-active-handler.c glibc-2.17-c758a686/libio/tst-ftell-active-handler.c +new file mode 100644 +index 0000000..175e904 +--- /dev/null ++++ glibc-2.17-c758a686/libio/tst-ftell-active-handler.c +@@ -0,0 +1,384 @@ ++/* Verify that ftell returns the correct value at various points before and ++ after the handler on which it is called becomes active. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int do_test (void); ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++#define get_handles_fdopen(filename, fd, fp, fd_mode, mode) \ ++({ \ ++ int ret = 0; \ ++ (fd) = open ((filename), (fd_mode), 0); \ ++ if ((fd) == -1) \ ++ { \ ++ printf ("open failed: %m\n"); \ ++ ret = 1; \ ++ } \ ++ else \ ++ { \ ++ (fp) = fdopen ((fd), (mode)); \ ++ if ((fp) == NULL) \ ++ { \ ++ printf ("fdopen failed: %m\n"); \ ++ close (fd); \ ++ ret = 1; \ ++ } \ ++ } \ ++ ret; \ ++}) ++ ++#define get_handles_fopen(filename, fd, fp, mode) \ ++({ \ ++ int ret = 0; \ ++ (fp) = fopen ((filename), (mode)); \ ++ if ((fp) == NULL) \ ++ { \ ++ printf ("fopen failed: %m\n"); \ ++ ret = 1; \ ++ } \ ++ else \ ++ { \ ++ (fd) = fileno (fp); \ ++ if ((fd) == -1) \ ++ { \ ++ printf ("fileno failed: %m\n"); \ ++ ret = 1; \ ++ } \ ++ } \ ++ ret; \ ++}) ++ ++/* data points to either char_data or wide_data, depending on whether we're ++ testing regular file mode or wide mode respectively. Similarly, ++ fputs_func points to either fputs or fputws. data_len keeps track of the ++ length of the current data and file_len maintains the current file ++ length. */ ++static const void *data; ++static const char *char_data = "abcdef"; ++static const wchar_t *wide_data = L"abcdef"; ++static size_t data_len; ++static size_t file_len; ++ ++typedef int (*fputs_func_t) (const void *data, FILE *fp); ++fputs_func_t fputs_func; ++ ++/* Test that the value of ftell is not cached when the stream handle is not ++ active. */ ++static int ++do_ftell_test (const char *filename) ++{ ++ int ret = 0; ++ struct test ++ { ++ const char *mode; ++ int fd_mode; ++ size_t old_off; ++ size_t new_off; ++ } test_modes[] = { ++ /* In w, w+ and r+ modes, the file position should be at the ++ beginning of the file. After the write, the offset should be ++ updated to data_len. */ ++ {"w", O_WRONLY, 0, data_len}, ++ {"w+", O_RDWR, 0, data_len}, ++ {"r+", O_RDWR, 0, data_len}, ++ /* For 'a' and 'a+' modes, the initial file position should be the ++ current end of file. After the write, the offset has data_len ++ added to the old value. */ ++ {"a", O_WRONLY, data_len, 2 * data_len}, ++ {"a+", O_RDWR, 2 * data_len, 3 * data_len}, ++ }; ++ for (int j = 0; j < 2; j++) ++ { ++ for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) ++ { ++ FILE *fp; ++ int fd; ++ printf ("\tftell: %s (file, \"%s\"): ", j == 0 ? "fdopen" : "fopen", ++ test_modes[i].mode); ++ ++ if (j == 0) ++ ret = get_handles_fdopen (filename, fd, fp, test_modes[i].fd_mode, ++ test_modes[i].mode); ++ else ++ ret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ ++ if (ret != 0) ++ return ret; ++ ++ long off = ftell (fp); ++ if (off != test_modes[i].old_off) ++ { ++ printf ("Incorrect old offset. Expected %zu but got %ld, ", ++ test_modes[i].old_off, off); ++ ret |= 1; ++ } ++ else ++ printf ("old offset = %ld, ", off); ++ ++ /* The effect of this write on the offset should be seen in the ftell ++ call that follows it. */ ++ int ret = write (fd, data, data_len); ++ off = ftell (fp); ++ ++ if (off != test_modes[i].new_off) ++ { ++ printf ("Incorrect new offset. Expected %zu but got %ld\n", ++ test_modes[i].old_off, off); ++ ret |= 1; ++ } ++ else ++ printf ("new offset = %ld\n", off); ++ ++ fclose (fp); ++ } ++ } ++ ++ return ret; ++} ++ ++/* This test opens the file for writing, moves the file offset of the ++ underlying file, writes out data and then checks if ftell trips on it. */ ++static int ++do_write_test (const char *filename) ++{ ++ FILE *fp = NULL; ++ int fd; ++ int ret = 0; ++ struct test ++ { ++ const char *mode; ++ int fd_mode; ++ } test_modes[] = { ++ {"w", O_WRONLY}, ++ {"w+", O_RDWR}, ++ {"r+", O_RDWR} ++ }; ++ ++ for (int j = 0; j < 2; j++) ++ { ++ for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) ++ { ++ printf ("\twrite: %s (file, \"%s\"): ", j == 0 ? "fopen" : "fdopen", ++ test_modes[i].mode); ++ ++ if (j == 0) ++ ret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ else ++ ret = get_handles_fdopen (filename, fd, fp, test_modes[i].fd_mode, ++ test_modes[i].mode); ++ ++ if (ret != 0) ++ return ret; ++ ++ /* Move offset to just before the end of the file. */ ++ off_t ret = lseek (fd, file_len - 1, SEEK_SET); ++ if (ret == -1) ++ { ++ printf ("lseek failed: %m\n"); ++ ret |= 1; ++ } ++ ++ /* Write some data. */ ++ size_t written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs[1] failed to write data\n"); ++ ret |= 1; ++ } ++ ++ /* Verify that the offset points to the end of the file. The length ++ of the file would be the original length + the length of data ++ written to it - the amount by which we moved the offset using ++ lseek. */ ++ long offset = ftell (fp); ++ file_len = file_len - 1 + data_len; ++ ++ if (offset != file_len) ++ { ++ printf ("Incorrect offset. Expected %zu, but got %ld\n", ++ file_len, offset); ++ ++ ret |= 1; ++ } ++ ++ printf ("offset = %ld\n", offset); ++ fclose (fp); ++ } ++ } ++ ++ return ret; ++} ++ ++/* This test opens a file in append mode, writes some data, and then verifies ++ that ftell does not trip over it. */ ++static int ++do_append_test (const char *filename) ++{ ++ FILE *fp = NULL; ++ int ret = 0; ++ int fd; ++ ++ struct test ++ { ++ const char *mode; ++ int fd_mode; ++ } test_modes[] = { ++ {"a", O_WRONLY}, ++ {"a+", O_RDWR} ++ }; ++ ++ for (int j = 0; j < 2; j++) ++ { ++ for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) ++ { ++ printf ("\tappend: %s (file, \"%s\"): ", j == 0 ? "fopen" : "fdopen", ++ test_modes[i].mode); ++ ++ if (j == 0) ++ ret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ else ++ ret = get_handles_fdopen (filename, fd, fp, test_modes[i].fd_mode, ++ test_modes[i].mode); ++ ++ if (ret != 0) ++ return ret; ++ ++ /* Write some data. */ ++ size_t written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs[1] failed to write all data\n"); ++ ret |= 1; ++ } ++ ++ /* Verify that the offset points to the end of the file. The file ++ len is maintained by adding data_len each time to reflect the data ++ written to it. */ ++ long offset = ftell (fp); ++ file_len += data_len; ++ ++ if (offset != file_len) ++ { ++ printf ("Incorrect offset. Expected %zu, but got %ld\n", ++ file_len, offset); ++ ++ ret |= 1; ++ } ++ ++ printf ("offset = %ld\n", offset); ++ fclose (fp); ++ } ++ } ++ ++ return ret; ++} ++ ++static int ++do_one_test (const char *filename) ++{ ++ int ret = 0; ++ ++ ret |= do_ftell_test (filename); ++ ret |= do_write_test (filename); ++ ret |= do_append_test (filename); ++ ++ return ret; ++} ++ ++/* Run a set of tests for ftell for regular files and wide mode files. */ ++static int ++do_test (void) ++{ ++ int ret = 0; ++ FILE *fp = NULL; ++ char *filename; ++ size_t written; ++ int fd = create_temp_file ("tst-active-handler-tmp.", &filename); ++ ++ if (fd == -1) ++ { ++ printf ("create_temp_file: %m\n"); ++ return 1; ++ } ++ ++ fp = fdopen (fd, "w"); ++ if (fp == NULL) ++ { ++ printf ("fdopen[0]: %m\n"); ++ close (fd); ++ return 1; ++ } ++ ++ data = char_data; ++ data_len = strlen (char_data); ++ file_len = strlen (char_data); ++ written = fputs (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs[1] failed to write data\n"); ++ ret = 1; ++ } ++ ++ fclose (fp); ++ if (ret) ++ return ret; ++ ++ /* Tests for regular files. */ ++ puts ("Regular mode:"); ++ fputs_func = (fputs_func_t) fputs; ++ data = char_data; ++ data_len = strlen (char_data); ++ ret |= do_one_test (filename); ++ ++ /* Truncate the file before repeating the tests in wide mode. */ ++ fp = fopen (filename, "w"); ++ if (fp == NULL) ++ { ++ printf ("fopen failed %m\n"); ++ return 1; ++ } ++ fclose (fp); ++ ++ /* Tests for wide files. */ ++ puts ("Wide mode:"); ++ if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) ++ { ++ printf ("Cannot set en_US.UTF-8 locale.\n"); ++ return 1; ++ } ++ fputs_func = (fputs_func_t) fputws; ++ data = wide_data; ++ data_len = wcslen (wide_data); ++ ret |= do_one_test (filename); ++ ++ return ret; ++} +diff --git glibc-2.17-c758a686/libio/wfileops.c glibc-2.17-c758a686/libio/wfileops.c +index 9cebe77..8b2e108 100644 +--- glibc-2.17-c758a686/libio/wfileops.c ++++ glibc-2.17-c758a686/libio/wfileops.c +@@ -596,29 +596,25 @@ done: + return 0; + } + +-_IO_off64_t +-_IO_wfile_seekoff (fp, offset, dir, mode) +- _IO_FILE *fp; +- _IO_off64_t offset; +- int dir; +- int mode; ++/* ftell{,o} implementation for wide mode. Don't modify any state of the file ++ pointer while we try to get the current state of the stream. */ ++static _IO_off64_t ++do_ftell_wide (_IO_FILE *fp) + { +- _IO_off64_t result; +- _IO_off64_t delta, new_offset; +- long int count; +- /* POSIX.1 8.2.3.7 says that after a call the fflush() the file +- offset of the underlying file must be exact. */ +- int must_be_exact = ((fp->_wide_data->_IO_read_base +- == fp->_wide_data->_IO_read_end) +- && (fp->_wide_data->_IO_write_base +- == fp->_wide_data->_IO_write_ptr)); ++ _IO_off64_t result, offset = 0; ++ bool use_cached_offset = false; + +- bool was_writing = ((fp->_wide_data->_IO_write_ptr +- > fp->_wide_data->_IO_write_base) +- || _IO_in_put_mode (fp)); +- +- if (mode == 0) ++ /* No point looking for offsets in the buffer if it hasn't even been ++ allocated. */ ++ if (fp->_wide_data->_IO_buf_base != NULL) + { ++ const wchar_t *wide_read_base; ++ const wchar_t *wide_read_ptr; ++ const wchar_t *wide_read_end; ++ bool was_writing = ((fp->_wide_data->_IO_write_ptr ++ > fp->_wide_data->_IO_write_base) ++ || _IO_in_put_mode (fp)); ++ + /* XXX For wide stream with backup store it is not very + reasonable to determine the offset. The pushed-back + character might require a state change and we need not be +@@ -633,14 +629,142 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + return -1; + } + +- /* There is no more data in the backup buffer. We can +- switch back. */ +- _IO_switch_to_main_wget_area (fp); ++ /* Nothing in the backup store, so note the backed up pointers ++ without changing the state. */ ++ wide_read_base = fp->_wide_data->_IO_save_base; ++ wide_read_ptr = wide_read_base; ++ wide_read_end = fp->_wide_data->_IO_save_end; ++ } ++ else ++ { ++ wide_read_base = fp->_wide_data->_IO_read_base; ++ wide_read_ptr = fp->_wide_data->_IO_read_ptr; ++ wide_read_end = fp->_wide_data->_IO_read_end; ++ } ++ ++ struct _IO_codecvt *cv = fp->_codecvt; ++ int clen = (*cv->__codecvt_do_encoding) (cv); ++ ++ if (!was_writing) ++ { ++ if (clen > 0) ++ { ++ offset -= (wide_read_end - wide_read_ptr) * clen; ++ offset -= fp->_IO_read_end - fp->_IO_read_ptr; ++ } ++ else ++ { ++ int nread; ++ ++ size_t delta = wide_read_ptr - wide_read_base; ++ __mbstate_t state = fp->_wide_data->_IO_last_state; ++ nread = (*cv->__codecvt_do_length) (cv, &state, ++ fp->_IO_read_base, ++ fp->_IO_read_end, delta); ++ offset -= fp->_IO_read_end - fp->_IO_read_base - nread; ++ } ++ } ++ else ++ { ++ if (clen > 0) ++ offset += (fp->_wide_data->_IO_write_ptr ++ - fp->_wide_data->_IO_write_base) * clen; ++ else ++ { ++ size_t delta = (fp->_wide_data->_IO_write_ptr ++ - fp->_wide_data->_IO_write_base); ++ ++ /* Allocate enough space for the conversion. */ ++ size_t outsize = delta * sizeof (wchar_t); ++ char *out = malloc (outsize); ++ char *outstop = out; ++ const wchar_t *in = fp->_wide_data->_IO_write_base; ++ ++ enum __codecvt_result status; ++ ++ __mbstate_t state = fp->_wide_data->_IO_last_state; ++ status = (*cv->__codecvt_do_out) (cv, &state, ++ in, in + delta, &in, ++ out, out + outsize, &outstop); ++ ++ /* We don't check for __codecvt_partial because it can be ++ returned on one of two conditions: either the output ++ buffer is full or the input sequence is incomplete. We ++ take care to allocate enough buffer and our input ++ sequences must be complete since they are accepted as ++ wchar_t; if not, then that is an error. */ ++ if (__glibc_unlikely (status != __codecvt_ok)) ++ return WEOF; ++ ++ offset += outstop - out; ++ } ++ ++ /* _IO_read_end coincides with fp._offset, so the actual file ++ position is fp._offset - (_IO_read_end - new_write_ptr). */ ++ offset -= fp->_IO_read_end - fp->_IO_write_ptr; + } + +- dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */ ++ /* It is safe to use the cached offset when available if there is ++ unbuffered data (indicating that the file handle is active) and ++ the handle is not for a file open in a+ mode. The latter ++ condition is because there could be a scenario where there is a ++ switch from read mode to write mode using an fseek to an arbitrary ++ position. In this case, there would be unbuffered data due to be ++ appended to the end of the file, but the offset may not ++ necessarily be the end of the file. It is fine to use the cached ++ offset when the a+ stream is in read mode though, since the offset ++ is maintained correctly in that case. Note that this is not a ++ comprehensive set of cases when the offset is reliable. The ++ offset may be reliable even in some cases where there is no ++ unflushed input and the handle is active, but it's just that we ++ don't have a way to identify that condition reliably. */ ++ use_cached_offset = (offset != 0 && fp->_offset != _IO_pos_BAD ++ && ((fp->_flags & (_IO_IS_APPENDING | _IO_NO_READS)) ++ == (_IO_IS_APPENDING | _IO_NO_READS) ++ && was_writing)); + } + ++ if (use_cached_offset) ++ result = fp->_offset; ++ else ++ result = get_file_offset (fp); ++ ++ if (result == EOF) ++ return result; ++ ++ result += offset; ++ ++ return result; ++} ++ ++_IO_off64_t ++_IO_wfile_seekoff (fp, offset, dir, mode) ++ _IO_FILE *fp; ++ _IO_off64_t offset; ++ int dir; ++ int mode; ++{ ++ _IO_off64_t result; ++ _IO_off64_t delta, new_offset; ++ long int count; ++ ++ /* Short-circuit into a separate function. We don't want to mix any ++ functionality and we don't want to touch anything inside the FILE ++ object. */ ++ if (mode == 0) ++ return do_ftell_wide (fp); ++ ++ /* POSIX.1 8.2.3.7 says that after a call the fflush() the file ++ offset of the underlying file must be exact. */ ++ int must_be_exact = ((fp->_wide_data->_IO_read_base ++ == fp->_wide_data->_IO_read_end) ++ && (fp->_wide_data->_IO_write_base ++ == fp->_wide_data->_IO_write_ptr)); ++ ++ bool was_writing = ((fp->_wide_data->_IO_write_ptr ++ > fp->_wide_data->_IO_write_base) ++ || _IO_in_put_mode (fp)); ++ + /* Flush unwritten characters. + (This may do an unneeded write if we seek within the buffer. + But to be able to switch to reading, we would need to set +@@ -648,7 +772,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + which assumes file_ptr() is eGptr. Anyway, since we probably + end up flushing when we close(), it doesn't make much difference.) + FIXME: simulate mem-mapped files. */ +- else if (was_writing && _IO_switch_to_wget_mode (fp)) ++ if (was_writing && _IO_switch_to_wget_mode (fp)) + return WEOF; + + if (fp->_wide_data->_IO_buf_base == NULL) +@@ -693,7 +817,6 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + { + int nread; + +- flushed: + delta = (fp->_wide_data->_IO_read_ptr + - fp->_wide_data->_IO_read_base); + fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; +@@ -706,80 +829,9 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + offset -= fp->_IO_read_end - fp->_IO_read_base - nread; + } + } +- else +- { +- char *new_write_ptr = fp->_IO_write_ptr; +- +- if (clen > 0) +- offset += (fp->_wide_data->_IO_write_ptr +- - fp->_wide_data->_IO_write_base) / clen; +- else +- { +- enum __codecvt_result status = __codecvt_ok; +- delta = (fp->_wide_data->_IO_write_ptr +- - fp->_wide_data->_IO_write_base); +- const wchar_t *write_base = fp->_wide_data->_IO_write_base; +- +- /* FIXME: This actually ends up in two iterations of conversion, +- one here and the next when the buffer actually gets flushed. +- It may be possible to optimize this in future so that +- wdo_write identifies already converted content and does not +- redo it. In any case, this is much better than having to +- flush buffers for every ftell. */ +- do +- { +- /* There is not enough space in the buffer to do the entire +- conversion, so there is no point trying to avoid the +- buffer flush. Just do it and go back to how it was with +- the read mode. */ +- if (status == __codecvt_partial +- || (delta > 0 && new_write_ptr == fp->_IO_buf_end)) +- { +- if (_IO_switch_to_wget_mode (fp)) +- return WEOF; +- goto flushed; +- } +- +- const wchar_t *new_wbase = fp->_wide_data->_IO_write_base; +- fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; +- status = (*cv->__codecvt_do_out) (cv, +- &fp->_wide_data->_IO_state, +- write_base, +- write_base + delta, +- &new_wbase, +- new_write_ptr, +- fp->_IO_buf_end, +- &new_write_ptr); +- +- delta -= new_wbase - write_base; +- +- /* If there was an error, then return WEOF. +- TODO: set buffer state. */ +- if (__builtin_expect (status == __codecvt_error, 0)) +- return WEOF; +- } +- while (delta > 0); +- } +- +- /* _IO_read_end coincides with fp._offset, so the actual file position +- is fp._offset - (_IO_read_end - new_write_ptr). This is fine +- even if fp._offset is not set, since fp->_IO_read_end is then at +- _IO_buf_base and this adjustment is for unbuffered output. */ +- offset -= fp->_IO_read_end - new_write_ptr; +- } + + if (fp->_offset == _IO_pos_BAD) +- { +- if (mode != 0) +- goto dumb; +- else +- { +- result = _IO_SYSSEEK (fp, 0, dir); +- if (result == EOF) +- return result; +- fp->_offset = result; +- } +- } ++ goto dumb; + + /* Make offset absolute, assuming current pointer is file_ptr(). */ + offset += fp->_offset; +@@ -802,10 +854,6 @@ _IO_wfile_seekoff (fp, offset, dir, mode) + } + /* At this point, dir==_IO_seek_set. */ + +- /* If we are only interested in the current position we've found it now. */ +- if (mode == 0) +- return offset; +- + /* If destination is within current buffer, optimize: */ + if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL + && !_IO_in_backup (fp)) diff --git a/SOURCES/glibc-rh1064063.patch b/SOURCES/glibc-rh1064063.patch new file mode 100644 index 00000000..c8a347ef --- /dev/null +++ b/SOURCES/glibc-rh1064063.patch @@ -0,0 +1,70 @@ +commit a3e5b4feeb54cb92657ec2bc6d9be1fcef9e8575 +Author: Paul E. Murphy +Date: Mon Jan 11 17:24:04 2016 -0500 + + Fix race in tst-mqueue5 + + The check is done on line 117 by a thread spawned + from do_child(), forked from do_test(). This test + generates a signal in the forked process. + + Either thread may handle the signal, and on ppc, + it happens to be done on do_child, on the thread + which is not doing the check on line 117. + + This exposes a race condition whereby the test + incorrectly fails as the signal is caught during + or after the check. + + This is mitigated by ensuring the signal is blocked + in the child thread while thread is running. + + 2016-01-15 Martin Sebor + + [BZ #19432] +diff --git a/rt/tst-mqueue5.c b/rt/tst-mqueue5.c +index aa74fa3..25042bc 100644 +--- a/rt/tst-mqueue5.c ++++ b/rt/tst-mqueue5.c +@@ -116,7 +116,7 @@ thr (void *arg) + + if (rtmin_cnt != 2) + { +- puts ("SIGRTMIN signal in child did not arrive"); ++ puts ("SIGRTMIN signal in thread did not arrive"); + result = 1; + } + else if (rtmin_pid != getppid () +@@ -403,6 +403,16 @@ do_child (const char *name, pthread_barrier_t *b2, pthread_barrier_t *b3, + result = 1; + } + ++ /* Ensure the thr thread gets the signal, not us. */ ++ sigset_t set; ++ sigemptyset (&set); ++ sigaddset (&set, SIGRTMIN); ++ if (pthread_sigmask (SIG_BLOCK, &set, NULL)) ++ { ++ printf ("Failed to block SIGRTMIN in child: %m\n"); ++ result = 1; ++ } ++ + (void) pthread_barrier_wait (b2); + + /* Parent calls mqsend (q), which should wake up mqrecv (q) +@@ -514,7 +524,14 @@ do_child (const char *name, pthread_barrier_t *b2, pthread_barrier_t *b3, + result = 1; + } + +- void *thr_ret; ++ /* Reenable test signals before cleaning up the thread. */ ++ if (pthread_sigmask (SIG_UNBLOCK, &set, NULL)) ++ { ++ printf ("Failed to unblock SIGRTMIN in child: %m\n"); ++ result = 1; ++ } ++ ++ void *thr_ret; + ret = pthread_join (th, &thr_ret); + if (ret) + { diff --git a/SOURCES/glibc-rh1064066.patch b/SOURCES/glibc-rh1064066.patch new file mode 100644 index 00000000..751fd36b --- /dev/null +++ b/SOURCES/glibc-rh1064066.patch @@ -0,0 +1,32 @@ +--- /var/lib/mock/glibc-2.17-79.el7/root/builddir/build/BUILD/glibc-2.17-c758a686/math/libm-test.inc 2015-04-06 17:36:33.268209956 -0400 ++++ glibc-2.17-c758a686/math/libm-test.inc 2015-04-07 12:00:03.102360299 -0400 +@@ -521,7 +521,8 @@ + } + + +-static void __attribute__ ((noinline)) ++/* Attributes work around suspected gcc 4.8 bug #1209619. */ ++static void __attribute__ ((noclone, noinline)) + check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, + FLOAT max_ulp, int xfail, int exceptions, + FLOAT *curr_max_error) +@@ -610,7 +611,8 @@ + } + + +-static void __attribute__ ((noinline)) ++/* Attributes work around suspected gcc 4.8 bug #1209619. */ ++static void __attribute__ ((noclone, noinline)) + check_float (const char *test_name, FLOAT computed, FLOAT expected, + FLOAT max_ulp, int xfail, int exceptions) + { +@@ -619,7 +621,8 @@ + } + + +-static void __attribute__ ((noinline)) ++/* Attributes work around suspected gcc 4.8 bug #1209619. */ ++static void __attribute__ ((noclone, noinline)) + check_complex (const char *test_name, __complex__ FLOAT computed, + __complex__ FLOAT expected, + __complex__ FLOAT max_ulp, __complex__ int xfail, diff --git a/SOURCES/glibc-rh1064945.patch b/SOURCES/glibc-rh1064945.patch new file mode 100644 index 00000000..ee7165ee --- /dev/null +++ b/SOURCES/glibc-rh1064945.patch @@ -0,0 +1,77 @@ +commit 736c304a1ab4cee36a2f3343f1698bc0abae4608 +Author: Adhemerval Zanella +Date: Thu Jan 16 06:53:18 2014 -0600 + + PowerPC: Fix ftime gettimeofday internal call returning bogus data + + This patches fixes BZ#16430 by setting a different symbol for internal + GLIBC calls that points to ifunc resolvers. For PPC32, if the symbol + is defined as hidden (which is the case for gettimeofday and time) the + compiler will create local branches (symbol@local) and linker will not + create PLT calls (required for IFUNC). This will leads to internal symbol + calling the IFUNC resolver instead of the resolved symbol. + For PPC64 this behavior does not occur because a call to a function in + another translation unit might use a different toc pointer thus requiring + a PLT call. + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +index 29a5e08..2085b68 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +@@ -44,8 +44,24 @@ asm (".type __gettimeofday, %gnu_indirect_function"); + /* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't + let us do it in C because it doesn't know we're defining __gettimeofday + here in this file. */ +-asm (".globl __GI___gettimeofday\n" +- "__GI___gettimeofday = __gettimeofday"); ++asm (".globl __GI___gettimeofday"); ++ ++/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the ++ compiler make a local call (symbol@local) for internal GLIBC usage. It ++ means the PLT won't be used and the ifunc resolver will be called directly. ++ For ppc64 a call to a function in another translation unit might use a ++ different toc pointer thus disallowing direct branchess and making internal ++ ifuncs calls safe. */ ++#ifdef __powerpc64__ ++asm ("__GI___gettimeofday = __gettimeofday"); ++#else ++int ++__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz) ++{ ++ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz); ++} ++asm ("__GI___gettimeofday = __gettimeofday_vsyscall"); ++#endif + + #else + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c +index 089d0b6..023bc02 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c +@@ -54,8 +54,24 @@ asm (".type time, %gnu_indirect_function"); + /* This is doing "libc_hidden_def (time)" but the compiler won't + * let us do it in C because it doesn't know we're defining time + * here in this file. */ +-asm (".globl __GI_time\n" +- "__GI_time = time"); ++asm (".globl __GI_time"); ++ ++/* __GI_time is defined as hidden and for ppc32 it enables the ++ compiler make a local call (symbol@local) for internal GLIBC usage. It ++ means the PLT won't be used and the ifunc resolver will be called directly. ++ For ppc64 a call to a function in another translation unit might use a ++ different toc pointer thus disallowing direct branchess and making internal ++ ifuncs calls safe. */ ++#ifdef __powerpc64__ ++asm ("__GI_time = time"); ++#else ++time_t ++__time_vsyscall (time_t *t) ++{ ++ return INLINE_VSYSCALL (time, 1, t); ++} ++asm ("__GI_time = __time_vsyscall"); ++#endif + + #else diff --git a/SOURCES/glibc-rh1067755.patch b/SOURCES/glibc-rh1067755.patch new file mode 100644 index 00000000..15dc1188 --- /dev/null +++ b/SOURCES/glibc-rh1067755.patch @@ -0,0 +1,123 @@ +diff --git glibc-2.17-c758a686/elf/tst-stackguard1.c glibc-2.17-c758a686/elf/tst-stackguard1.c +index 2b4fd9a..fba60bd 100644 +--- glibc-2.17-c758a686/elf/tst-stackguard1.c ++++ glibc-2.17-c758a686/elf/tst-stackguard1.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + + static const char *command; +diff --git glibc-2.17-c758a686/include/errno.h glibc-2.17-c758a686/include/errno.h +index 98c6080..f1b93a8 100644 +--- glibc-2.17-c758a686/include/errno.h ++++ glibc-2.17-c758a686/include/errno.h +@@ -17,7 +17,7 @@ + # define errno rtld_errno + extern int rtld_errno attribute_hidden; + +-# else ++# elif !defined NOT_IN_libc || defined IN_LIB + + # include + +@@ -29,7 +29,7 @@ extern int rtld_errno attribute_hidden; + # endif + extern __thread int errno attribute_tls_model_ie; + +-# endif /* RTLD_PRIVATE_ERRNO */ ++# endif /* !NOT_IN_libc || IN_LIB */ + + # define __set_errno(val) (errno = (val)) + +diff --git glibc-2.17-c758a686/include/netdb.h glibc-2.17-c758a686/include/netdb.h +index 3f2ae06..8a569ba 100644 +--- glibc-2.17-c758a686/include/netdb.h ++++ glibc-2.17-c758a686/include/netdb.h +@@ -3,18 +3,20 @@ + + #ifndef _ISOMAC + /* Macros for accessing h_errno from inside libc. */ +-# undef h_errno +-# ifdef _LIBC_REENTRANT +-# include +-# ifndef NOT_IN_libc +-# define h_errno __libc_h_errno +-# else +-# define h_errno h_errno /* For #ifndef h_errno tests. */ +-# endif ++# if !defined NOT_IN_libc || defined IN_LIB ++# undef h_errno ++# ifdef _LIBC_REENTRANT ++# include ++# ifndef NOT_IN_libc ++# define h_errno __libc_h_errno ++# else ++# define h_errno h_errno /* For #ifndef h_errno tests. */ ++# endif + extern __thread int h_errno attribute_tls_model_ie; +-# else ++# else + extern int h_errno; +-# endif /* _LIBC_REENTRANT */ ++# endif /* _LIBC_REENTRANT */ ++# endif /* !NOT_IN_libc || IN_LIB */ + # define __set_h_errno(x) (h_errno = (x)) + + libc_hidden_proto (hstrerror) +diff --git glibc-2.17-c758a686/nptl/tst-cancel14.c glibc-2.17-c758a686/nptl/tst-cancel14.c +index fbaed49..ca9042d 100644 +--- glibc-2.17-c758a686/nptl/tst-cancel14.c ++++ glibc-2.17-c758a686/nptl/tst-cancel14.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + + static pthread_barrier_t bar; +diff --git glibc-2.17-c758a686/nptl/tst-cancel15.c glibc-2.17-c758a686/nptl/tst-cancel15.c +index 0119cc7..3f320ad 100644 +--- glibc-2.17-c758a686/nptl/tst-cancel15.c ++++ glibc-2.17-c758a686/nptl/tst-cancel15.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + + static pthread_barrier_t bar; +diff --git glibc-2.17-c758a686/nptl/tst-mutex9.c glibc-2.17-c758a686/nptl/tst-mutex9.c +index adb3b61..1d689bd 100644 +--- glibc-2.17-c758a686/nptl/tst-mutex9.c ++++ glibc-2.17-c758a686/nptl/tst-mutex9.c +@@ -18,10 +18,13 @@ + + #include + #include ++#include + #include ++#include + #include + #include + #include ++#include + #include + + +diff --git glibc-2.17-c758a686/nptl/tst-stackguard1.c glibc-2.17-c758a686/nptl/tst-stackguard1.c +index f0f707f..57a48ad 100644 +--- glibc-2.17-c758a686/nptl/tst-stackguard1.c ++++ glibc-2.17-c758a686/nptl/tst-stackguard1.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + + static const char *command; diff --git a/SOURCES/glibc-rh1070458.patch b/SOURCES/glibc-rh1070458.patch new file mode 100644 index 00000000..c798ded0 --- /dev/null +++ b/SOURCES/glibc-rh1070458.patch @@ -0,0 +1,124 @@ +Backport of commit f8b4877a75765b14432a6f83ead11dcecc5b1985 +Author: Marcus Shawcroft +Date: Fri Jul 26 08:29:17 2013 +0100 + + [AArch64] Provide symbol version for _mcount. + +2013-07-26 Marcus Shawcroft + + * sysdeps/aarch64/Versions: New file. + * sysdeps/aarch64/machine-gmon.h: New file. + * sysdeps/aarch64/mcount.c: New file. + * sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist (_mcount): Add. + + + +diff -ruNp glibc-2.17-c758a686/ports/sysdeps/aarch64/machine-gmon.h glibc-2.17-c758a686/ports/sysdeps/aarch64/machine-gmon.h +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/machine-gmon.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/machine-gmon.h 2014-03-27 12:06:51.361046886 -0400 +@@ -1,5 +1,5 @@ +-/* Copyright (C) 2011-2012 Free Software Foundation, Inc. +- ++/* AArch64 definitions for profiling support. ++ Copyright (C) 1996-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -13,13 +13,22 @@ + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library. If not, see ++ License along with the GNU C Library; if not, see + . */ + +-#define _MCOUNT_DECL(from, self) \ +- void __mcount_internal (u_long from, u_long self) +- +-/* Call __mcount_internal with our the return PC for our caller, and +- the return PC our caller will return to. Empty since we use an +- assembly stub instead. */ +-#define MCOUNT ++/* Accept 'frompc' address as argument from the function that calls ++ __mcount for profiling. Use __builtin_return_address (0) ++ for the 'selfpc' address. */ ++ ++#include ++ ++static void mcount_internal (u_long frompc, u_long selfpc); ++ ++#define _MCOUNT_DECL(frompc, selfpc) \ ++static inline void mcount_internal (u_long frompc, u_long selfpc) ++ ++#define MCOUNT \ ++void __mcount (void *frompc) \ ++{ \ ++ mcount_internal ((u_long) frompc, (u_long) RETURN_ADDRESS (0)); \ ++} +diff -ruNp glibc-2.17-c758a686/ports/sysdeps/aarch64/mcount.c glibc-2.17-c758a686/ports/sysdeps/aarch64/mcount.c +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/mcount.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/mcount.c 2014-03-27 11:54:54.435418262 -0400 +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++ ++#include ++ ++/* We forgot to add _mcount in glibc 2.17. We added it in 2.18 ++ therefore we want it to be added with version GLIBC_2_18. However, ++ setting the version is not straight forward because a generic ++ Version file includes an earlier 2.xx version for each this symbol ++ and the linker uses the first version it sees. */ ++ ++#if SHLIB_COMPAT (libc, GLIBC_2_17, GLIBC_2_18) ++versioned_symbol (libc, __mcount, _mcount, GLIBC_2_18); ++#else ++strong_alias (__mcount, _mcount); ++#endif +diff -ruNp glibc-2.17-c758a686/ports/sysdeps/aarch64/Versions glibc-2.17-c758a686/ports/sysdeps/aarch64/Versions +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/Versions 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/Versions 2014-03-27 11:54:54.435418262 -0400 +@@ -0,0 +1,5 @@ ++libc { ++ GLIBC_2.18 { ++ _mcount; ++ } ++} +diff -ruNp glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libc.abilist 2014-03-27 11:54:54.495412015 -0400 +@@ -2077,3 +2077,6 @@ GLIBC_2.17 + xencrypt F + xprt_register F + xprt_unregister F ++GLIBC_2.18 ++ GLIBC_2.18 A ++ _mcount F +diff -ruNp glibc-2.17-c758a686/Versions.def glibc-2.17-c758a686/Versions.def +--- glibc-2.17-c758a686/Versions.def 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/Versions.def 2014-03-27 11:54:54.535407851 -0400 +@@ -34,6 +34,7 @@ libc { + GLIBC_2.15 + GLIBC_2.16 + GLIBC_2.17 ++ GLIBC_2.18 + HURD_CTHREADS_0.3 + %ifdef EXPORT_UNWIND_FIND_FDE + GCC_3.0 diff --git a/SOURCES/glibc-rh1070471.patch b/SOURCES/glibc-rh1070471.patch new file mode 100644 index 00000000..fb7fe736 --- /dev/null +++ b/SOURCES/glibc-rh1070471.patch @@ -0,0 +1,53 @@ +Backport of commit 052aff95782fefe9c63566471063e8b20836bfb8 +Author: Joseph Myers +Date: Wed Jan 23 00:42:51 2013 +0000 + + Make bits/wchar.h correct for all architectures (bug 15036). + +2013-01-23 Joseph Myers + + [BZ #15036] + * bits/wchar.h (__WCHAR_MAX): Define based on __WCHAR_MAX__, or + based on [L'\0' - 1 > 0] if [!__WCHAR_MAX__]. + (__WCHAR_MIN): Likewise, using __WCHAR_MIN__. + * sysdeps/unix/sysv/linux/x86/bits/wchar.h: Remove. + + + +diff -ruNp glibc-2.17-c758a686/bits/wchar.h glibc-2.17-c758a686/bits/wchar.h +--- glibc-2.17-c758a686/bits/wchar.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/bits/wchar.h 2014-03-27 14:53:45.940914030 -0400 +@@ -19,7 +19,31 @@ + #ifndef _BITS_WCHAR_H + #define _BITS_WCHAR_H 1 + +-#define __WCHAR_MIN (-2147483647 - 1) +-#define __WCHAR_MAX (2147483647) ++/* The fallback definitions, for when __WCHAR_MAX__ or __WCHAR_MIN__ ++ are not defined, give the right value and type as long as both int ++ and wchar_t are 32-bit types. Adding L'\0' to a constant value ++ ensures that the type is correct; it is necessary to use (L'\0' + ++ 0) rather than just L'\0' so that the type in C++ is the promoted ++ version of wchar_t rather than the distinct wchar_t type itself. ++ Because wchar_t in preprocessor #if expressions is treated as ++ intmax_t or uintmax_t, the expression (L'\0' - 1) would have the ++ wrong value for WCHAR_MAX in such expressions and so cannot be used ++ to define __WCHAR_MAX in the unsigned case. */ ++ ++#ifdef __WCHAR_MAX__ ++# define __WCHAR_MAX __WCHAR_MAX__ ++#elif L'\0' - 1 > 0 ++# define __WCHAR_MAX (0xffffffffu + L'\0') ++#else ++# define __WCHAR_MAX (0x7fffffff + L'\0') ++#endif ++ ++#ifdef __WCHAR_MIN__ ++# define __WCHAR_MIN __WCHAR_MIN__ ++#elif L'\0' - 1 > 0 ++# define __WCHAR_MIN (L'\0' + 0) ++#else ++# define __WCHAR_MIN (-__WCHAR_MAX - 1) ++#endif + + #endif /* bits/wchar.h */ diff --git a/SOURCES/glibc-rh1070806.patch b/SOURCES/glibc-rh1070806.patch new file mode 100644 index 00000000..f2a397fa --- /dev/null +++ b/SOURCES/glibc-rh1070806.patch @@ -0,0 +1,118 @@ +Comprehensive stack protector support was added to upstream glibc with +this commit: + +commit cecbc7967f0bcac718b6f8f8942b58403c0e917c +Author: Nick Alcock +Date: Mon Dec 26 10:09:10 2016 +0100 + + Enable -fstack-protector=* when requested by configure [BZ #7065] + +It is a superset of the functionality in this patch. + +diff -urN glibc-2.17-c758a686/config.make.in glibc-2.17-c758a686/config.make.in +--- glibc-2.17-c758a686/config.make.in 2014-02-27 10:33:11.466763885 -0500 ++++ glibc-2.17-c758a686/config.make.in 2014-02-27 10:36:44.481320149 -0500 +@@ -62,6 +62,7 @@ + have-as-vis3 = @libc_cv_sparc_as_vis3@ + gnu89-inline-CFLAGS = @gnu89_inline@ + have-ssp = @libc_cv_ssp@ ++have-ssp-strong = @libc_cv_ssp_strong@ + have-selinux = @have_selinux@ + have-libaudit = @have_libaudit@ + have-libcap = @have_libcap@ +diff -urN glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure +--- glibc-2.17-c758a686/configure 2014-02-27 10:33:11.561763687 -0500 ++++ glibc-2.17-c758a686/configure 2014-02-27 10:32:28.885852593 -0500 +@@ -610,6 +610,7 @@ + libc_cv_cc_submachine + exceptions + gnu89_inline ++libc_cv_ssp_strong + libc_cv_ssp + fno_unit_at_a_time + libc_cv_output_format +@@ -6758,6 +6759,27 @@ + $as_echo "$libc_cv_ssp" >&6; } + + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5 ++$as_echo_n "checking for -fstack-protector-strong... " >&6; } ++if ${libc_cv_ssp_strong+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-strong -xc /dev/null -S -o /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then : ++ libc_cv_ssp_strong=yes ++else ++ libc_cv_ssp_strong=no ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_strong" >&5 ++$as_echo "$libc_cv_ssp_strong" >&6; } ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fgnu89-inline" >&5 + $as_echo_n "checking for -fgnu89-inline... " >&6; } + if ${libc_cv_gnu89_inline+:} false; then : +diff -urN glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in +--- glibc-2.17-c758a686/configure.in 2014-02-27 10:33:11.469763878 -0500 ++++ glibc-2.17-c758a686/configure.in 2014-02-27 10:32:09.171893663 -0500 +@@ -1682,6 +1682,13 @@ + ]) + AC_SUBST(libc_cv_ssp) + ++AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl ++LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong], ++ [libc_cv_ssp_strong=yes], ++ [libc_cv_ssp_strong=no]) ++]) ++AC_SUBST(libc_cv_ssp_strong) ++ + AC_CACHE_CHECK(for -fgnu89-inline, libc_cv_gnu89_inline, [dnl + cat > conftest.c < +Date: Mon May 20 10:19:31 2013 +0200 + + AArch64: Don't clobber argument for tail call to __sigjmp_save in sigsetjmp + +diff --git glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +index cff81c7..10e0709 100644 +--- glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +@@ -44,8 +44,14 @@ ENTRY (__sigsetjmp) + stp d10, d11, [x0, #JB_D10<<3] + stp d12, d13, [x0, #JB_D12<<3] + stp d14, d15, [x0, #JB_D14<<3] +- mov x1, sp +- str x1, [x0, #JB_SP<<3] ++ mov x2, sp ++ str x2, [x0, #JB_SP<<3] ++#if defined NOT_IN_libc && defined IS_IN_rtld ++ /* In ld.so we never save the signal mask */ ++ mov w0, #0 ++ RET ++#else + b C_SYMBOL_NAME(__sigjmp_save) ++#endif + END (__sigsetjmp) + hidden_def (__sigsetjmp) +diff --git glibc-2.17-c758a686/setjmp/Makefile glibc-2.17-c758a686/setjmp/Makefile +index 6124333..913359c 100644 +--- glibc-2.17-c758a686/setjmp/Makefile ++++ glibc-2.17-c758a686/setjmp/Makefile +@@ -25,7 +25,8 @@ headers := setjmp.h bits/setjmp.h bits/setjmp2.h + routines := setjmp sigjmp bsd-setjmp bsd-_setjmp \ + longjmp __longjmp jmp-unwind + +-tests := tst-setjmp jmpbug bug269-setjmp ++tests := tst-setjmp jmpbug bug269-setjmp \ ++ tst-sigsetjmp + + + include ../Rules +diff --git glibc-2.17-c758a686/setjmp/tst-sigsetjmp.c glibc-2.17-c758a686/setjmp/tst-sigsetjmp.c +new file mode 100644 +index 0000000..467c26a +--- /dev/null ++++ glibc-2.17-c758a686/setjmp/tst-sigsetjmp.c +@@ -0,0 +1,44 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Test case for BZ #15493 */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ sigjmp_buf sj; ++ sigset_t m; ++ ++ sigemptyset (&m); ++ sigprocmask (SIG_SETMASK, &m, NULL); ++ if (sigsetjmp (sj, 0) == 0) ++ { ++ sigaddset (&m, SIGUSR1); ++ sigprocmask (SIG_SETMASK, &m, NULL); ++ siglongjmp (sj, 1); ++ return EXIT_FAILURE; ++ } ++ sigprocmask (SIG_SETMASK, NULL, &m); ++ return sigismember (&m, SIGUSR1) ? EXIT_SUCCESS : EXIT_FAILURE; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh1074410-2.patch b/SOURCES/glibc-rh1074410-2.patch new file mode 100644 index 00000000..7724dbd8 --- /dev/null +++ b/SOURCES/glibc-rh1074410-2.patch @@ -0,0 +1,258 @@ +commit e8b9e065a1ae9d7d8b888909ae761cbd5cf7be32 +Author: Siddhesh Poyarekar +Date: Wed Mar 19 00:42:30 2014 +0530 + + Fix offset computation for append+ mode on switching from read (BZ #16724) + + The offset computation in write mode uses the fact that _IO_read_end + is kept in sync with the external file offset. This however is not + true when O_APPEND is in effect since switching to write mode ought to + send the external file offset to the end of file without making the + necessary adjustment to _IO_read_end. + + Hence in append mode, offset computation when writing should only + consider the effect of unflushed writes, i.e. from _IO_write_base to + _IO_write_ptr. + +diff --git glibc-2.17-c758a686/libio/Makefile glibc-2.17-c758a686/libio/Makefile +index 69c25c0..4bedfad 100644 +--- glibc-2.17-c758a686/libio/Makefile ++++ glibc-2.17-c758a686/libio/Makefile +@@ -60,7 +60,8 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ + tst-wmemstream1 tst-wmemstream2 \ + bug-memstream1 bug-wmemstream1 \ + tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ +- tst-fwrite-error tst-ftell-active-handler ++ tst-fwrite-error tst-ftell-active-handler \ ++ tst-ftell-append + ifeq (yes,$(build-shared)) + # Add test-fopenloc only if shared library is enabled since it depends on + # shared localedata objects. +diff --git glibc-2.17-c758a686/libio/fileops.c glibc-2.17-c758a686/libio/fileops.c +index cf68dbf..204cfea 100644 +--- glibc-2.17-c758a686/libio/fileops.c ++++ glibc-2.17-c758a686/libio/fileops.c +@@ -91,7 +91,9 @@ extern struct __gconv_trans_data __libio_translit attribute_hidden; + + The position in the buffer that corresponds to the position + in external file system is normally _IO_read_end, except in putback +- mode, when it is _IO_save_end. ++ mode, when it is _IO_save_end and also when the file is in append mode, ++ since switching from read to write mode automatically sends the position in ++ the external file system to the end of file. + If the field _fb._offset is >= 0, it gives the offset in + the file as a whole corresponding to eGptr(). (?) + +@@ -966,6 +968,14 @@ do_ftell (_IO_FILE *fp) + /* Adjust for unflushed data. */ + if (!was_writing) + offset -= fp->_IO_read_end - fp->_IO_read_ptr; ++ /* We don't trust _IO_read_end to represent the current file offset when ++ writing in append mode because the value would have to be shifted to ++ the end of the file during a flush. Use the write base instead, along ++ with the new offset we got above when we did a seek to the end of the ++ file. */ ++ else if (append_mode) ++ offset += fp->_IO_write_ptr - fp->_IO_write_base; ++ /* For all other modes, _IO_read_end represents the file offset. */ + else + offset += fp->_IO_write_ptr - fp->_IO_read_end; + } +diff --git glibc-2.17-c758a686/libio/tst-ftell-append.c glibc-2.17-c758a686/libio/tst-ftell-append.c +new file mode 100644 +index 0000000..604dc03 +--- /dev/null ++++ glibc-2.17-c758a686/libio/tst-ftell-append.c +@@ -0,0 +1,169 @@ ++/* Verify that ftell returns the correct value after a read and a write on a ++ file opened in a+ mode. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* data points to either char_data or wide_data, depending on whether we're ++ testing regular file mode or wide mode respectively. Similarly, ++ fputs_func points to either fputs or fputws. data_len keeps track of the ++ length of the current data and file_len maintains the current file ++ length. */ ++#define BUF_LEN 4 ++static void *buf; ++static char char_buf[BUF_LEN]; ++static wchar_t wide_buf[BUF_LEN]; ++static const void *data; ++static const char *char_data = "abcdefghijklmnopqrstuvwxyz"; ++static const wchar_t *wide_data = L"abcdefghijklmnopqrstuvwxyz"; ++static size_t data_len; ++static size_t file_len; ++ ++typedef int (*fputs_func_t) (const void *data, FILE *fp); ++fputs_func_t fputs_func; ++ ++typedef void *(*fgets_func_t) (void *s, int size, FILE *stream); ++fgets_func_t fgets_func; ++ ++static int do_test (void); ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++static FILE * ++init_file (const char *filename) ++{ ++ FILE *fp = fopen (filename, "w"); ++ if (fp == NULL) ++ { ++ printf ("fopen: %m\n"); ++ return NULL; ++ } ++ ++ int written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs failed to write data\n"); ++ fclose (fp); ++ return NULL; ++ } ++ ++ file_len = data_len; ++ ++ fclose (fp); ++ ++ fp = fopen (filename, "a+"); ++ if (fp == NULL) ++ { ++ printf ("fopen(a+): %m\n"); ++ return NULL; ++ } ++ ++ return fp; ++} ++ ++static int ++do_one_test (const char *filename) ++{ ++ FILE *fp = init_file (filename); ++ ++ if (fp == NULL) ++ return 1; ++ ++ void *ret = fgets_func (buf, BUF_LEN, fp); ++ ++ if (ret == NULL) ++ { ++ printf ("read failed: %m\n"); ++ fclose (fp); ++ return 1; ++ } ++ ++ int written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs failed to write data\n"); ++ fclose (fp); ++ return 1; ++ } ++ ++ file_len += data_len; ++ ++ long off = ftell (fp); ++ ++ if (off != file_len) ++ { ++ printf ("Incorrect offset %ld, expected %zu\n", off, file_len); ++ fclose (fp); ++ return 1; ++ } ++ else ++ printf ("Correct offset %ld after write.\n", off); ++ ++ return 0; ++} ++ ++/* Run the tests for regular files and wide mode files. */ ++static int ++do_test (void) ++{ ++ int ret = 0; ++ char *filename; ++ int fd = create_temp_file ("tst-ftell-append-tmp.", &filename); ++ ++ if (fd == -1) ++ { ++ printf ("create_temp_file: %m\n"); ++ return 1; ++ } ++ ++ close (fd); ++ ++ /* Tests for regular files. */ ++ puts ("Regular mode:"); ++ fputs_func = (fputs_func_t) fputs; ++ fgets_func = (fgets_func_t) fgets; ++ data = char_data; ++ buf = char_buf; ++ data_len = strlen (char_data); ++ ret |= do_one_test (filename); ++ ++ /* Tests for wide files. */ ++ puts ("Wide mode:"); ++ if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) ++ { ++ printf ("Cannot set en_US.UTF-8 locale.\n"); ++ return 1; ++ } ++ fputs_func = (fputs_func_t) fputws; ++ fgets_func = (fgets_func_t) fgetws; ++ data = wide_data; ++ buf = wide_buf; ++ data_len = wcslen (wide_data); ++ ret |= do_one_test (filename); ++ ++ return ret; ++} +diff --git glibc-2.17-c758a686/libio/wfileops.c glibc-2.17-c758a686/libio/wfileops.c +index 3199861..f123add 100644 +--- glibc-2.17-c758a686/libio/wfileops.c ++++ glibc-2.17-c758a686/libio/wfileops.c +@@ -713,9 +713,16 @@ do_ftell_wide (_IO_FILE *fp) + offset += outstop - out; + } + +- /* _IO_read_end coincides with fp._offset, so the actual file +- position is fp._offset - (_IO_read_end - new_write_ptr). */ +- offset -= fp->_IO_read_end - fp->_IO_write_ptr; ++ /* We don't trust _IO_read_end to represent the current file offset ++ when writing in append mode because the value would have to be ++ shifted to the end of the file during a flush. Use the write base ++ instead, along with the new offset we got above when we did a seek ++ to the end of the file. */ ++ if (append_mode) ++ offset += fp->_IO_write_ptr - fp->_IO_write_base; ++ /* For all other modes, _IO_read_end represents the file offset. */ ++ else ++ offset += fp->_IO_write_ptr - fp->_IO_read_end; + } + } diff --git a/SOURCES/glibc-rh1074410.patch b/SOURCES/glibc-rh1074410.patch new file mode 100644 index 00000000..fb142cbf --- /dev/null +++ b/SOURCES/glibc-rh1074410.patch @@ -0,0 +1,655 @@ +commit ae42bbc55a9e05976269026ddabcfb917f6e922f +Author: Siddhesh Poyarekar +Date: Mon Mar 17 18:42:53 2014 +0530 + + Change offset in fdopen only if setting O_APPEND + + fdopen should only be allowed to change the offset in the file it + attaches to if it is setting O_APPEND. If O_APPEND is already set, it + should not change the state of the handle. + +commit ea33158c96c53a64402a772186956c1f5cb556ae +Author: Siddhesh Poyarekar +Date: Tue Mar 11 17:04:49 2014 +0530 + + Fix offset caching for streams and use it for ftell (BZ #16680) + + The ftell implementation was made conservative to ensure that + incorrectly cached offsets never affect it. However, this causes + problems for append mode when a file stream is rewound. Additionally, + the 'clever' trick of using stat to get position for append mode files + caused more problems than it solved and broke old behavior. I have + described the various problems that it caused and then finally the + solution. + + For a and a+ mode files, rewinding the stream should result in ftell + returning 0 as the offset, but the stat() trick caused it to + (incorrectly) always return the end of file. Now I couldn't find + anything in POSIX that specifies the stream position after rewind() + for a file opened in 'a' mode, but for 'a+' mode it should be set to + 0. For 'a' mode too, it probably makes sense to keep it set to 0 in + the interest of retaining old behavior. + + The initial file position for append mode files is implementation + defined, so the implementation could either retain the current file + position or move the position to the end of file. The earlier ftell + implementation would move the offset to end of file for append-only + mode, but retain the old offset for a+ mode. It would also cache the + offset (this detail is important). My patch broke this and would set + the initial position to end of file for both append modes, thus + breaking old behavior. I was ignorant enough to write an incorrect + test case for it too. + + The Change: + + I have now brought back the behavior of seeking to end of file for + append-only streams, but with a slight difference. I don't cache the + offset though, since we would want ftell to query the current file + position through lseek while the stream is not active. Since the + offset is moved to the end of file, we can rely on the file position + reported by lseek and we don't need to resort to the stat() nonsense. + + Finally, the cache is always reliable, except when there are unflished + writes in an append mode stream (i.e. both a and a+). In the latter + case, it is safe to just do an lseek to SEEK_END. The value can be + safely cached too, since the file handle is already active at this + point. Incidentally, this is the only state change we affect in the + file handle (apart from taking locks of course). + + I have also updated the test case to correct my impression of the + initial file position for a+ streams to the initial behavior. I have + verified that this does not break any existing tests in the testsuite + and also passes with the new tests. + +commit b1dbb426e164ad1236c2c76268e03fec5c7a7bbe +Author: Siddhesh Poyarekar +Date: Mon Mar 10 16:20:01 2014 +0530 + + Fix up return codes for tests in tst-ftell-active-handler + + The test functions used a variable ret to store failure codes for + individual tests, but the variable was incorrectly used to record + other failure codes too, resulting in overwriting of the tests status. + This is now fixed by making sure that the ret variable is used only + for recording test failures. + + * libio/tst-ftell-active-handler.c (do_ftell_test): Don't mix + up test status with function return status. + (do_write_test): Likewise. + (do_append_test): Likewise. +diff --git glibc-2.17-c758a686/libio/fileops.c glibc-2.17-c758a686/libio/fileops.c +index 2e7bc8d..cf68dbf 100644 +--- glibc-2.17-c758a686/libio/fileops.c ++++ glibc-2.17-c758a686/libio/fileops.c +@@ -232,13 +232,18 @@ _IO_file_open (fp, filename, posix_mode, prot, read_write, is32not64) + return NULL; + fp->_fileno = fdesc; + _IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); +- if ((read_write & _IO_IS_APPENDING) && (read_write & _IO_NO_READS)) +- if (_IO_SEEKOFF (fp, (_IO_off64_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT) +- == _IO_pos_BAD && errno != ESPIPE) +- { +- close_not_cancel (fdesc); +- return NULL; +- } ++ /* For append mode, send the file offset to the end of the file. Don't ++ update the offset cache though, since the file handle is not active. */ ++ if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS)) ++ == (_IO_IS_APPENDING | _IO_NO_READS)) ++ { ++ _IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end); ++ if (new_pos == _IO_pos_BAD && errno != ESPIPE) ++ { ++ close_not_cancel (fdesc); ++ return NULL; ++ } ++ } + _IO_link_in ((struct _IO_FILE_plus *) fp); + return fp; + } +@@ -929,43 +934,13 @@ _IO_file_sync_mmap (_IO_FILE *fp) + return 0; + } + +-/* Get the current file offset using a system call. This is the safest method +- to get the current file offset, since we are sure that we get the current +- state of the file. Before the stream handle is activated (by using fread, +- fwrite, etc.), an application may alter the state of the file descriptor +- underlying it by calling read/write/lseek on it. Using a cached offset at +- this point will result in returning the incorrect value. Same is the case +- when one switches from reading in a+ mode to writing, where the buffer has +- not been flushed - the cached offset would reflect the reading position +- while the actual write position would be at the end of the file. +- +- do_ftell and do_ftell_wide may resort to using the cached offset in some +- special cases instead of calling get_file_offset, but those cases should be +- thoroughly described. */ +-_IO_off64_t +-get_file_offset (_IO_FILE *fp) +-{ +- if ((fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING) +- { +- struct stat64 st; +- bool ret = (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode)); +- if (ret) +- return st.st_size; +- else +- return EOF; +- } +- else +- return _IO_SYSSEEK (fp, 0, _IO_seek_cur); +-} +- +- +-/* ftell{,o} implementation. Don't modify any state of the file pointer while +- we try to get the current state of the stream. */ ++/* ftell{,o} implementation. The only time we modify the state of the stream ++ is when we have unflushed writes. In that case we seek to the end and ++ record that offset in the stream object. */ + static _IO_off64_t + do_ftell (_IO_FILE *fp) + { +- _IO_off64_t result = 0; +- bool use_cached_offset = false; ++ _IO_off64_t result, offset = 0; + + /* No point looking at unflushed data if we haven't allocated buffers + yet. */ +@@ -974,39 +949,37 @@ do_ftell (_IO_FILE *fp) + bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base + || _IO_in_put_mode (fp)); + ++ bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING; ++ ++ /* When we have unflushed writes in append mode, seek to the end of the ++ file and record that offset. This is the only time we change the file ++ stream state and it is safe since the file handle is active. */ ++ if (was_writing && append_mode) ++ { ++ result = _IO_SYSSEEK (fp, 0, _IO_seek_end); ++ if (result == _IO_pos_BAD) ++ return EOF; ++ else ++ fp->_offset = result; ++ } ++ + /* Adjust for unflushed data. */ + if (!was_writing) +- result -= fp->_IO_read_end - fp->_IO_read_ptr; ++ offset -= fp->_IO_read_end - fp->_IO_read_ptr; + else +- result += fp->_IO_write_ptr - fp->_IO_read_end; +- +- /* It is safe to use the cached offset when available if there is +- unbuffered data (indicating that the file handle is active) and the +- handle is not for a file open in a+ mode. The latter condition is +- because there could be a scenario where there is a switch from read +- mode to write mode using an fseek to an arbitrary position. In this +- case, there would be unbuffered data due to be appended to the end of +- the file, but the offset may not necessarily be the end of the +- file. It is fine to use the cached offset when the a+ stream is in +- read mode though, since the offset is maintained correctly in that +- case. Note that this is not a comprehensive set of cases when the +- offset is reliable. The offset may be reliable even in some cases +- where there is no unflushed input and the handle is active, but it's +- just that we don't have a way to identify that condition reliably. */ +- use_cached_offset = (result != 0 && fp->_offset != _IO_pos_BAD +- && ((fp->_flags & (_IO_IS_APPENDING | _IO_NO_READS)) +- == (_IO_IS_APPENDING | _IO_NO_READS) +- && was_writing)); ++ offset += fp->_IO_write_ptr - fp->_IO_read_end; + } + +- if (use_cached_offset) +- result += fp->_offset; ++ if (fp->_offset != _IO_pos_BAD) ++ result = fp->_offset; + else +- result += get_file_offset (fp); ++ result = _IO_SYSSEEK (fp, 0, _IO_seek_cur); + + if (result == EOF) + return result; + ++ result += offset; ++ + if (result < 0) + { + __set_errno (EINVAL); +@@ -1016,7 +989,6 @@ do_ftell (_IO_FILE *fp) + return result; + } + +- + _IO_off64_t + _IO_new_file_seekoff (fp, offset, dir, mode) + _IO_FILE *fp; +diff --git glibc-2.17-c758a686/libio/iofdopen.c glibc-2.17-c758a686/libio/iofdopen.c +index 3f266f7..b36d21d 100644 +--- glibc-2.17-c758a686/libio/iofdopen.c ++++ glibc-2.17-c758a686/libio/iofdopen.c +@@ -59,6 +59,11 @@ _IO_new_fdopen (fd, mode) + int i; + int use_mmap = 0; + ++ /* Decide whether we modify the offset of the file we attach to and seek to ++ the end of file. We only do this if the mode is 'a' and if the file ++ descriptor did not have O_APPEND in its flags already. */ ++ bool do_seek = false; ++ + switch (*mode) + { + case 'r': +@@ -128,6 +133,7 @@ _IO_new_fdopen (fd, mode) + */ + if ((posix_mode & O_APPEND) && !(fd_flags & O_APPEND)) + { ++ do_seek = true; + #ifdef F_SETFL + if (_IO_fcntl (fd, F_SETFL, fd_flags | O_APPEND) == -1) + #endif +@@ -167,6 +173,16 @@ _IO_new_fdopen (fd, mode) + _IO_mask_flags (&new_f->fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); + ++ /* For append mode, set the file offset to the end of the file if we added ++ O_APPEND to the file descriptor flags. Don't update the offset cache ++ though, since the file handle is not active. */ ++ if (do_seek && ((read_write & (_IO_IS_APPENDING | _IO_NO_READS)) ++ == (_IO_IS_APPENDING | _IO_NO_READS))) ++ { ++ _IO_off64_t new_pos = _IO_SYSSEEK (&new_f->fp.file, 0, _IO_seek_end); ++ if (new_pos == _IO_pos_BAD && errno != ESPIPE) ++ return NULL; ++ } + return &new_f->fp.file; + } + libc_hidden_ver (_IO_new_fdopen, _IO_fdopen) +diff --git glibc-2.17-c758a686/libio/tst-ftell-active-handler.c glibc-2.17-c758a686/libio/tst-ftell-active-handler.c +index 54bfe63..e9dc7b3 100644 +--- glibc-2.17-c758a686/libio/tst-ftell-active-handler.c ++++ glibc-2.17-c758a686/libio/tst-ftell-active-handler.c +@@ -88,6 +88,107 @@ static size_t file_len; + typedef int (*fputs_func_t) (const void *data, FILE *fp); + fputs_func_t fputs_func; + ++/* Test that ftell output after a rewind is correct. */ ++static int ++do_rewind_test (const char *filename) ++{ ++ int ret = 0; ++ struct test ++ { ++ const char *mode; ++ int fd_mode; ++ size_t old_off; ++ size_t new_off; ++ } test_modes[] = { ++ {"w", O_WRONLY, 0, data_len}, ++ {"w+", O_RDWR, 0, data_len}, ++ {"r+", O_RDWR, 0, data_len}, ++ /* The new offsets for 'a' and 'a+' modes have to factor in the ++ previous writes since they always append to the end of the ++ file. */ ++ {"a", O_WRONLY, 0, 3 * data_len}, ++ {"a+", O_RDWR, 0, 4 * data_len}, ++ }; ++ ++ /* Empty the file before the test so that our offsets are simple to ++ calculate. */ ++ FILE *fp = fopen (filename, "w"); ++ if (fp == NULL) ++ { ++ printf ("Failed to open file for emptying\n"); ++ return 1; ++ } ++ fclose (fp); ++ ++ for (int j = 0; j < 2; j++) ++ { ++ for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) ++ { ++ FILE *fp; ++ int fd; ++ int fileret; ++ ++ printf ("\trewind: %s (file, \"%s\"): ", j == 0 ? "fdopen" : "fopen", ++ test_modes[i].mode); ++ ++ if (j == 0) ++ fileret = get_handles_fdopen (filename, fd, fp, ++ test_modes[i].fd_mode, ++ test_modes[i].mode); ++ else ++ fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ ++ if (fileret != 0) ++ return fileret; ++ ++ /* Write some content to the file, rewind and ensure that the ftell ++ output after the rewind is 0. POSIX does not specify what the ++ behavior is when a file is rewound in 'a' mode, so we retain ++ current behavior, which is to keep the 0 offset. */ ++ size_t written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs[1] failed to write data\n"); ++ ret |= 1; ++ } ++ ++ rewind (fp); ++ long offset = ftell (fp); ++ ++ if (offset != test_modes[i].old_off) ++ { ++ printf ("Incorrect old offset. Expected %zu, but got %ld, ", ++ test_modes[i].old_off, offset); ++ ret |= 1; ++ } ++ else ++ printf ("old offset = %ld, ", offset); ++ ++ written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs[1] failed to write data\n"); ++ ret |= 1; ++ } ++ ++ /* After this write, the offset in append modes should factor in the ++ implicit lseek to the end of file. */ ++ offset = ftell (fp); ++ if (offset != test_modes[i].new_off) ++ { ++ printf ("Incorrect new offset. Expected %zu, but got %ld\n", ++ test_modes[i].new_off, offset); ++ ret |= 1; ++ } ++ else ++ printf ("new offset = %ld\n", offset); ++ } ++ } ++ return ret; ++} ++ + /* Test that the value of ftell is not cached when the stream handle is not + active. */ + static int +@@ -107,11 +208,13 @@ do_ftell_test (const char *filename) + {"w", O_WRONLY, 0, data_len}, + {"w+", O_RDWR, 0, data_len}, + {"r+", O_RDWR, 0, data_len}, +- /* For 'a' and 'a+' modes, the initial file position should be the ++ /* For the 'a' mode, the initial file position should be the + current end of file. After the write, the offset has data_len +- added to the old value. */ ++ added to the old value. For a+ mode however, the initial file ++ position is the file position of the underlying file descriptor, ++ since it is initially assumed to be in read mode. */ + {"a", O_WRONLY, data_len, 2 * data_len}, +- {"a+", O_RDWR, 2 * data_len, 3 * data_len}, ++ {"a+", O_RDWR, 0, 3 * data_len}, + }; + for (int j = 0; j < 2; j++) + { +@@ -119,17 +222,20 @@ do_ftell_test (const char *filename) + { + FILE *fp; + int fd; ++ int fileret; ++ + printf ("\tftell: %s (file, \"%s\"): ", j == 0 ? "fdopen" : "fopen", + test_modes[i].mode); + + if (j == 0) +- ret = get_handles_fdopen (filename, fd, fp, test_modes[i].fd_mode, +- test_modes[i].mode); ++ fileret = get_handles_fdopen (filename, fd, fp, ++ test_modes[i].fd_mode, ++ test_modes[i].mode); + else +- ret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + +- if (ret != 0) +- return ret; ++ if (fileret != 0) ++ return fileret; + + long off = ftell (fp); + if (off != test_modes[i].old_off) +@@ -143,13 +249,18 @@ do_ftell_test (const char *filename) + + /* The effect of this write on the offset should be seen in the ftell + call that follows it. */ +- int ret = write (fd, data, data_len); ++ int write_ret = write (fd, data, data_len); ++ if (write_ret != data_len) ++ { ++ printf ("write failed (%m)\n"); ++ ret |= 1; ++ } + off = ftell (fp); + + if (off != test_modes[i].new_off) + { + printf ("Incorrect new offset. Expected %zu but got %ld\n", +- test_modes[i].old_off, off); ++ test_modes[i].new_off, off); + ret |= 1; + } + else +@@ -184,21 +295,23 @@ do_write_test (const char *filename) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { ++ int fileret; + printf ("\twrite: %s (file, \"%s\"): ", j == 0 ? "fopen" : "fdopen", + test_modes[i].mode); + + if (j == 0) +- ret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + else +- ret = get_handles_fdopen (filename, fd, fp, test_modes[i].fd_mode, +- test_modes[i].mode); ++ fileret = get_handles_fdopen (filename, fd, fp, ++ test_modes[i].fd_mode, ++ test_modes[i].mode); + +- if (ret != 0) +- return ret; ++ if (fileret != 0) ++ return fileret; + + /* Move offset to just before the end of the file. */ +- off_t ret = lseek (fd, file_len - 1, SEEK_SET); +- if (ret == -1) ++ off_t seek_ret = lseek (fd, file_len - 1, SEEK_SET); ++ if (seek_ret == -1) + { + printf ("lseek failed: %m\n"); + ret |= 1; +@@ -258,17 +371,20 @@ do_append_test (const char *filename) + { + for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) + { ++ int fileret; ++ + printf ("\tappend: %s (file, \"%s\"): ", j == 0 ? "fopen" : "fdopen", + test_modes[i].mode); + + if (j == 0) +- ret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); + else +- ret = get_handles_fdopen (filename, fd, fp, test_modes[i].fd_mode, +- test_modes[i].mode); ++ fileret = get_handles_fdopen (filename, fd, fp, ++ test_modes[i].fd_mode, ++ test_modes[i].mode); + +- if (ret != 0) +- return ret; ++ if (fileret != 0) ++ return fileret; + + /* Write some data. */ + size_t written = fputs_func (data, fp); +@@ -298,6 +414,61 @@ do_append_test (const char *filename) + } + } + ++ /* For fdopen in 'a' mode, the file descriptor should not change if the file ++ is already open with the O_APPEND flag set. */ ++ fd = open (filename, O_WRONLY | O_APPEND, 0); ++ if (fd == -1) ++ { ++ printf ("open(O_APPEND) failed: %m\n"); ++ return 1; ++ } ++ ++ off_t seek_ret = lseek (fd, file_len - 1, SEEK_SET); ++ if (seek_ret == -1) ++ { ++ printf ("lseek[O_APPEND][0] failed: %m\n"); ++ ret |= 1; ++ } ++ ++ fp = fdopen (fd, "a"); ++ if (fp == NULL) ++ { ++ printf ("fdopen(O_APPEND) failed: %m\n"); ++ close (fd); ++ return 1; ++ } ++ ++ off_t new_seek_ret = lseek (fd, 0, SEEK_CUR); ++ if (seek_ret == -1) ++ { ++ printf ("lseek[O_APPEND][1] failed: %m\n"); ++ ret |= 1; ++ } ++ ++ printf ("\tappend: fdopen (file, \"a\"): O_APPEND: "); ++ ++ if (seek_ret != new_seek_ret) ++ { ++ printf ("incorrectly modified file offset to %ld, should be %ld", ++ new_seek_ret, seek_ret); ++ ret |= 1; ++ } ++ else ++ printf ("retained current file offset %ld", seek_ret); ++ ++ new_seek_ret = ftello (fp); ++ ++ if (seek_ret != new_seek_ret) ++ { ++ printf (", ftello reported incorrect offset %ld, should be %ld\n", ++ new_seek_ret, seek_ret); ++ ret |= 1; ++ } ++ else ++ printf (", ftello reported correct offset %ld\n", seek_ret); ++ ++ fclose (fp); ++ + return ret; + } + +@@ -309,6 +480,7 @@ do_one_test (const char *filename) + ret |= do_ftell_test (filename); + ret |= do_write_test (filename); + ret |= do_append_test (filename); ++ ret |= do_rewind_test (filename); + + return ret; + } +diff --git glibc-2.17-c758a686/libio/wfileops.c glibc-2.17-c758a686/libio/wfileops.c +index 8b2e108..3199861 100644 +--- glibc-2.17-c758a686/libio/wfileops.c ++++ glibc-2.17-c758a686/libio/wfileops.c +@@ -597,12 +597,12 @@ done: + } + + /* ftell{,o} implementation for wide mode. Don't modify any state of the file +- pointer while we try to get the current state of the stream. */ ++ pointer while we try to get the current state of the stream except in one ++ case, which is when we have unflushed writes in append mode. */ + static _IO_off64_t + do_ftell_wide (_IO_FILE *fp) + { + _IO_off64_t result, offset = 0; +- bool use_cached_offset = false; + + /* No point looking for offsets in the buffer if it hasn't even been + allocated. */ +@@ -615,6 +615,20 @@ do_ftell_wide (_IO_FILE *fp) + > fp->_wide_data->_IO_write_base) + || _IO_in_put_mode (fp)); + ++ bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING; ++ ++ /* When we have unflushed writes in append mode, seek to the end of the ++ file and record that offset. This is the only time we change the file ++ stream state and it is safe since the file handle is active. */ ++ if (was_writing && append_mode) ++ { ++ result = _IO_SYSSEEK (fp, 0, _IO_seek_end); ++ if (result == _IO_pos_BAD) ++ return EOF; ++ else ++ fp->_offset = result; ++ } ++ + /* XXX For wide stream with backup store it is not very + reasonable to determine the offset. The pushed-back + character might require a state change and we need not be +@@ -703,37 +717,24 @@ do_ftell_wide (_IO_FILE *fp) + position is fp._offset - (_IO_read_end - new_write_ptr). */ + offset -= fp->_IO_read_end - fp->_IO_write_ptr; + } +- +- /* It is safe to use the cached offset when available if there is +- unbuffered data (indicating that the file handle is active) and +- the handle is not for a file open in a+ mode. The latter +- condition is because there could be a scenario where there is a +- switch from read mode to write mode using an fseek to an arbitrary +- position. In this case, there would be unbuffered data due to be +- appended to the end of the file, but the offset may not +- necessarily be the end of the file. It is fine to use the cached +- offset when the a+ stream is in read mode though, since the offset +- is maintained correctly in that case. Note that this is not a +- comprehensive set of cases when the offset is reliable. The +- offset may be reliable even in some cases where there is no +- unflushed input and the handle is active, but it's just that we +- don't have a way to identify that condition reliably. */ +- use_cached_offset = (offset != 0 && fp->_offset != _IO_pos_BAD +- && ((fp->_flags & (_IO_IS_APPENDING | _IO_NO_READS)) +- == (_IO_IS_APPENDING | _IO_NO_READS) +- && was_writing)); + } + +- if (use_cached_offset) ++ if (fp->_offset != _IO_pos_BAD) + result = fp->_offset; + else +- result = get_file_offset (fp); ++ result = _IO_SYSSEEK (fp, 0, _IO_seek_cur); + + if (result == EOF) + return result; + + result += offset; + ++ if (result < 0) ++ { ++ __set_errno (EINVAL); ++ return EOF; ++ } ++ + return result; + } diff --git a/SOURCES/glibc-rh1077389-p1.patch b/SOURCES/glibc-rh1077389-p1.patch new file mode 100644 index 00000000..5ace322a --- /dev/null +++ b/SOURCES/glibc-rh1077389-p1.patch @@ -0,0 +1,77 @@ +# +# commit 76a9b9986141b1a7d9fd290c349d27fcee780c7a +# Author: Adhemerval Zanella +# Date: Thu Nov 7 05:34:22 2013 -0600 +# +# PowerPC: Fix vDSO missing ODP entries +# +# This patch fixes the vDSO symbol used directed in IFUNC resolver where +# they do not have an associated ODP entry leading to undefined behavior +# in some cases. It adds an artificial OPD static entry to such cases +# and set its TOC to non 0 to avoid triggering lazy resolutions. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2015-01-15 16:05:08.853681325 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2015-01-15 16:06:11.451747716 -0500 +@@ -34,12 +34,32 @@ + + extern void *__vdso_time; + +-/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO +- symbol. This works because _dl_vdso_vsym always return the function +- address, and no vDSO symbols use the TOC or chain pointers from the OPD +- so we can allow them to be garbage. */ +-#if defined(__PPC64__) || defined(__powerpc64__) +-#define VDSO_IFUNC_RET(value) ((void *) &(value)) ++/* The correct solution is for _dl_vdso_vsym to return the address of the OPD ++ for the kernel VDSO function. That address would then be stored in the ++ __vdso_* variables and returned as the result of the IFUNC resolver function. ++ Yet, the kernel does not contain any OPD entries for the VDSO functions ++ (incomplete implementation). However, PLT relocations for IFUNCs still expect ++ the address of an OPD to be returned from the IFUNC resolver function (since ++ PLT entries on PPC64 are just copies of OPDs). The solution for now is to ++ create an artificial static OPD for each VDSO function returned by a resolver ++ function. The TOC value is set to a non-zero value to avoid triggering lazy ++ symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT ++ sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None ++ of the kernel VDSO routines use the TOC or AUX values so any non-zero value ++ will work. Note that function pointer comparisons will not use this artificial ++ static OPD since those are resolved via ADDR64 relocations and will point at ++ the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations ++ are processed immediately at startup the resolver functions and this code need ++ not be thread-safe, but if the caller writes to a PLT slot it must do so in a ++ thread-safe manner with all the required barriers. */ ++#if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2 ++#define VDSO_IFUNC_RET(value) \ ++ ({ \ ++ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \ ++ vdso_opd.fd_func = (Elf64_Addr)value; \ ++ &vdso_opd; \ ++ }) ++ + #else + #define VDSO_IFUNC_RET(value) ((void *) (value)) + #endif +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2015-01-15 16:05:08.912679502 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2015-01-15 16:06:11.451747716 -0500 +@@ -21,6 +21,7 @@ + + # include + # include ++# include + + void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday"); + +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c 2015-01-15 16:05:08.912679502 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c 2015-01-15 16:06:11.451747716 -0500 +@@ -20,7 +20,9 @@ + + # include + # include ++# include + # include ++# include + + void *time_ifunc (void) asm ("time"); diff --git a/SOURCES/glibc-rh1077389-p2.patch b/SOURCES/glibc-rh1077389-p2.patch new file mode 100644 index 00000000..a454607d --- /dev/null +++ b/SOURCES/glibc-rh1077389-p2.patch @@ -0,0 +1,52 @@ +# +# commit d98720e07f67fbeec00f9e1347840404240d3c48 +# Author: Adhemerval Zanella +# Date: Mon Jan 20 12:29:51 2014 -0600 +# +# PowerPC: Fix gettimeofday ifunc selection +# +# The IFUNC selector for gettimeofday runs before _libc_vdso_platform_setup where +# __vdso_gettimeofday is set. The selector then sets __gettimeofday (the internal +# version used within GLIBC) to use the system call version instead of the vDSO one. +# This patch changes the check if vDSO is available to get its value directly +# instead of rely on __vdso_gettimeofday. +# +# This patch changes it by getting the vDSO value directly. +# +# It fixes BZ#16431. +# +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2015-01-15 16:07:59.167420456 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c 2015-01-15 16:07:41.408969001 -0500 +@@ -34,9 +34,12 @@ + void * + gettimeofday_ifunc (void) + { ++ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565); ++ + /* If the vDSO is not available we fall back syscall. */ +- return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday) +- : __gettimeofday_syscall); ++ void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615); ++ return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday) ++ : (void*)__gettimeofday_syscall); + } + asm (".type __gettimeofday, %gnu_indirect_function"); + +diff -urN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c 2015-01-15 16:07:59.168420425 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c 2015-01-15 16:07:41.408969001 -0500 +@@ -45,9 +45,12 @@ + void * + time_ifunc (void) + { ++ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565); ++ + /* If the vDSO is not available we fall back to the syscall. */ +- return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time) +- : time_syscall); ++ void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615); ++ return (vdso_time ? VDSO_IFUNC_RET (vdso_time) ++ : (void*)time_syscall); + } + asm (".type time, %gnu_indirect_function"); diff --git a/SOURCES/glibc-rh1078225.patch b/SOURCES/glibc-rh1078225.patch new file mode 100644 index 00000000..9c434e21 --- /dev/null +++ b/SOURCES/glibc-rh1078225.patch @@ -0,0 +1,46 @@ +From 3a3acb6afc753475675b5724f206e619d0c9590d Mon Sep 17 00:00:00 2001 +From: Tom Tromey +Date: Mon, 20 Jan 2014 12:58:03 +0000 +Subject: [PATCH] [AArch64] BZ #16169 Add CFI directives to clone.S + +[BZ #16169] Add CFI directives to the AArch64 clone.S implementation +and ensure that the FP in the child is zero'd in order to comply with +AAPCS. +--- + NEWS | 8 ++++---- + ports/ChangeLog.aarch64 | 6 ++++++ + ports/sysdeps/unix/sysv/linux/aarch64/clone.S | 7 ++++++- + 3 files changed, 16 insertions(+), 5 deletions(-) + +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S +=================================================================== +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/clone.S +@@ -63,6 +63,7 @@ ENTRY(__clone) + mov x8, #SYS_ify(clone) + /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid. */ + svc 0x0 ++ cfi_endproc + cmp x0, #0 + beq 2f + blt C_SYMBOL_NAME(__syscall_error) +@@ -71,6 +72,9 @@ ENTRY(__clone) + b syscall_error + + 2: ++ cfi_startproc ++ cfi_undefined (x30) ++ mov x29, 0 + #ifdef RESET_PID + tbnz x5, #CLONE_THREAD_BIT, 3f + mov x0, #-1 +@@ -92,7 +96,8 @@ ENTRY(__clone) + + /* We are done, pass the return value through x0. */ + b HIDDEN_JUMPTARGET(_exit) +- ++ cfi_endproc ++ cfi_startproc + PSEUDO_END (__clone) + + weak_alias (__clone, clone) diff --git a/SOURCES/glibc-rh1080766.patch b/SOURCES/glibc-rh1080766.patch new file mode 100644 index 00000000..b98fac26 --- /dev/null +++ b/SOURCES/glibc-rh1080766.patch @@ -0,0 +1,57 @@ +commit fbd6b5a4052316f7eb03c4617eebfaafc59dcc06 +Author: Siddhesh Poyarekar +Date: Thu Mar 27 07:15:22 2014 +0530 + + Fix nscd lookup for innetgr when netgroup has wildcards (BZ #16758) + + nscd works correctly when the request in innetgr is a wildcard, + i.e. when one or more of host, user or domain parameters is NULL. + However, it does not work when the the triplet in the netgroup + definition has a wildcard. This is easy to reproduce for a triplet + defined as follows: + + foonet (,foo,) + + Here, an innetgr call that looks like this: + + innetgr ("foonet", "foohost", "foo", NULL); + + should succeed and so should: + + innetgr ("foonet", NULL, "foo", "foodomain"); + + It does succeed with nscd disabled, but not with nscd enabled. This + fix adds this additional check for all three parts of the triplet so + that it gives the correct result. + + [BZ #16758] + * nscd/netgroupcache.c (addinnetgrX): Succeed if triplet has + blank values. + +diff --git glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +index 5ba1e1f..5d15aa4 100644 +--- glibc-2.17-c758a686/nscd/netgroupcache.c ++++ glibc-2.17-c758a686/nscd/netgroupcache.c +@@ -560,15 +560,19 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + { + bool success = true; + +- if (host != NULL) ++ /* For the host, user and domain in each triplet, we assume success ++ if the value is blank because that is how the wildcard entry to ++ match anything is stored in the netgroup cache. */ ++ if (host != NULL && *triplets != '\0') + success = strcmp (host, triplets) == 0; + triplets = (const char *) rawmemchr (triplets, '\0') + 1; + +- if (success && user != NULL) ++ if (success && user != NULL && *triplets != '\0') + success = strcmp (user, triplets) == 0; + triplets = (const char *) rawmemchr (triplets, '\0') + 1; + +- if (success && (domain == NULL || strcmp (domain, triplets) == 0)) ++ if (success && (domain == NULL || *triplets == '\0' ++ || strcmp (domain, triplets) == 0)) + { + dataset->resp.result = 1; + break; diff --git a/SOURCES/glibc-rh1083644.patch b/SOURCES/glibc-rh1083644.patch new file mode 100644 index 00000000..bc8d441f --- /dev/null +++ b/SOURCES/glibc-rh1083644.patch @@ -0,0 +1,63 @@ +commit ea7d8b95e2fcb81f68b04ed7787a3dbda023991a +Author: Siddhesh Poyarekar +Date: Thu Mar 27 19:48:15 2014 +0530 + + Avoid overlapping addresses to stpcpy calls in nscd (BZ #16760) + + Calls to stpcpy from nscd netgroups code will have overlapping source + and destination when all three values in the returned triplet are + non-NULL and in the expected (host,user,domain) order. This is seen + in valgrind as: + + ==3181== Source and destination overlap in stpcpy(0x19973b48, 0x19973b48) + ==3181== at 0x4C2F30A: stpcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) + ==3181== by 0x12567A: addgetnetgrentX (string3.h:111) + ==3181== by 0x12722D: addgetnetgrent (netgroupcache.c:665) + ==3181== by 0x11114C: nscd_run_worker (connections.c:1338) + ==3181== by 0x4E3C102: start_thread (pthread_create.c:309) + ==3181== by 0x59B81AC: clone (clone.S:111) + ==3181== + + Fix this by using memmove instead of stpcpy. + +diff --git glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +index 5d15aa4..820d823 100644 +--- glibc-2.17-c758a686/nscd/netgroupcache.c ++++ glibc-2.17-c758a686/nscd/netgroupcache.c +@@ -216,6 +216,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + const char *nuser = data.val.triple.user; + const char *ndomain = data.val.triple.domain; + ++ size_t hostlen = strlen (nhost ?: "") + 1; ++ size_t userlen = strlen (nuser ?: "") + 1; ++ size_t domainlen = strlen (ndomain ?: "") + 1; ++ + if (nhost == NULL || nuser == NULL || ndomain == NULL + || nhost > nuser || nuser > ndomain) + { +@@ -233,9 +237,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + : last + strlen (last) + 1 - buffer); + + /* We have to make temporary copies. */ +- size_t hostlen = strlen (nhost ?: "") + 1; +- size_t userlen = strlen (nuser ?: "") + 1; +- size_t domainlen = strlen (ndomain ?: "") + 1; + size_t needed = hostlen + userlen + domainlen; + + if (buflen - req->key_len - bufused < needed) +@@ -269,9 +270,12 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + + char *wp = buffer + buffilled; +- wp = stpcpy (wp, nhost) + 1; +- wp = stpcpy (wp, nuser) + 1; +- wp = stpcpy (wp, ndomain) + 1; ++ wp = memmove (wp, nhost ?: "", hostlen); ++ wp += hostlen; ++ wp = memmove (wp, nuser ?: "", userlen); ++ wp += userlen; ++ wp = memmove (wp, ndomain ?: "", domainlen); ++ wp += domainlen; + buffilled = wp - buffer; + ++nentries; + } diff --git a/SOURCES/glibc-rh1083646.patch b/SOURCES/glibc-rh1083646.patch new file mode 100644 index 00000000..99718768 --- /dev/null +++ b/SOURCES/glibc-rh1083646.patch @@ -0,0 +1,398 @@ +commit bc8f194c8c29e46e8ee4034f06e46988dfff38f7 +Author: Siddhesh Poyarekar +Date: Wed Apr 30 12:00:39 2014 +0530 + + Initialize all of datahead structure in nscd (BZ #16791) + + The datahead structure has an unused padding field that remains + uninitialized. Valgrind prints out a warning for it on querying a + netgroups entry. This is harmless, but is a potential data leak since + it would result in writing out an uninitialized byte to the cache + file. Besides, this happens only when there is a cache miss, so we're + not adding computation to any fast path. + +commit 1cdeb2372ddecac0dfe0c132a033e9590ffa07d2 +Author: Siddhesh Poyarekar +Date: Wed Apr 30 11:57:09 2014 +0530 + + Consolidate code to initialize nscd dataset header + + This patch consolidates the code to initialize the header of a dataset + into a single set of functions (one for positive and another for + negative datasets) primarily to reduce repetition of code. The + secondary reason is to simplify Patch 2/2 which fixes the problem of + an uninitialized byte in the header by initializing an unused field in + the structure and hence preventing a possible data leak into the cache + file. + +diff --git glibc-2.17-c758a686/nscd/aicache.c glibc-2.17-c758a686/nscd/aicache.c +index 98d40a1..d7966bd 100644 +--- glibc-2.17-c758a686/nscd/aicache.c ++++ glibc-2.17-c758a686/nscd/aicache.c +@@ -383,17 +383,12 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + cp = family; + } + +- /* Fill in the rest of the dataset. */ +- dataset->head.allocsize = total + req->key_len; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl; +- timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl; ++ timeout = datahead_init_pos (&dataset->head, total + req->key_len, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ ttl == INT32_MAX ? db->postimeout : ttl); + ++ /* Fill in the rest of the dataset. */ + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; + dataset->resp.naddrs = naddrs; +@@ -528,15 +523,9 @@ next_nip: + else if ((dataset = mempool_alloc (db, (sizeof (struct dataset) + + req->key_len), 1)) != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = time (NULL) + db->negtimeout; +- dataset->head.ttl = db->negtimeout; ++ timeout = datahead_init_neg (&dataset->head, ++ sizeof (struct dataset) + req->key_len, ++ total, db->negtimeout); + + /* This is the reply. */ + memcpy (&dataset->resp, ¬found, total); +diff --git glibc-2.17-c758a686/nscd/grpcache.c glibc-2.17-c758a686/nscd/grpcache.c +index b5a33eb..df59fa7 100644 +--- glibc-2.17-c758a686/nscd/grpcache.c ++++ glibc-2.17-c758a686/nscd/grpcache.c +@@ -128,14 +128,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req, + } + else if ((dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1)) != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = t + db->negtimeout; ++ timeout = datahead_init_neg (&dataset->head, ++ (sizeof (struct dataset) ++ + req->key_len), total, ++ db->negtimeout); + + /* This is the reply. */ + memcpy (&dataset->resp, ¬found, total); +@@ -232,14 +228,10 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req, + dataset_temporary = true; + } + +- dataset->head.allocsize = total + n; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = t + db->postimeout; ++ timeout = datahead_init_pos (&dataset->head, total + n, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ db->postimeout); + + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; +diff --git glibc-2.17-c758a686/nscd/hstcache.c glibc-2.17-c758a686/nscd/hstcache.c +index a79b67a..d4f1ad2 100644 +--- glibc-2.17-c758a686/nscd/hstcache.c ++++ glibc-2.17-c758a686/nscd/hstcache.c +@@ -152,15 +152,11 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, + else if ((dataset = mempool_alloc (db, (sizeof (struct dataset) + + req->key_len), 1)) != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- dataset->head.ttl = ttl == INT32_MAX ? db->negtimeout : ttl; +- timeout = dataset->head.timeout = t + dataset->head.ttl; ++ timeout = datahead_init_neg (&dataset->head, ++ (sizeof (struct dataset) ++ + req->key_len), total, ++ (ttl == INT32_MAX ++ ? db->negtimeout : ttl)); + + /* This is the reply. */ + memcpy (&dataset->resp, resp, total); +@@ -257,15 +253,10 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req, + alloca_used = true; + } + +- dataset->head.allocsize = total + req->key_len; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- dataset->head.ttl = ttl == INT32_MAX ? db->postimeout : ttl; +- timeout = dataset->head.timeout = t + dataset->head.ttl; ++ timeout = datahead_init_pos (&dataset->head, total + req->key_len, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ ttl == INT32_MAX ? db->postimeout : ttl); + + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; +diff --git glibc-2.17-c758a686/nscd/initgrcache.c glibc-2.17-c758a686/nscd/initgrcache.c +index 1bf9f0d..361319f 100644 +--- glibc-2.17-c758a686/nscd/initgrcache.c ++++ glibc-2.17-c758a686/nscd/initgrcache.c +@@ -213,14 +213,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, + else if ((dataset = mempool_alloc (db, (sizeof (struct dataset) + + req->key_len), 1)) != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = time (NULL) + db->negtimeout; ++ timeout = datahead_init_neg (&dataset->head, ++ (sizeof (struct dataset) ++ + req->key_len), total, ++ db->negtimeout); + + /* This is the reply. */ + memcpy (&dataset->resp, ¬found, total); +@@ -276,14 +272,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, + alloca_used = true; + } + +- dataset->head.allocsize = total + req->key_len; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = time (NULL) + db->postimeout; ++ timeout = datahead_init_pos (&dataset->head, total + req->key_len, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ db->postimeout); + + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; +diff --git glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +index 820d823..b3d40e9 100644 +--- glibc-2.17-c758a686/nscd/netgroupcache.c ++++ glibc-2.17-c758a686/nscd/netgroupcache.c +@@ -90,15 +90,9 @@ do_notfound (struct database_dyn *db, int fd, request_header *req, + /* If we cannot permanently store the result, so be it. */ + if (dataset != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = time (NULL) + db->negtimeout; +- dataset->head.ttl = db->negtimeout; ++ timeout = datahead_init_neg (&dataset->head, ++ sizeof (struct dataset) + req->key_len, ++ total, db->negtimeout); + + /* This is the reply. */ + memcpy (&dataset->resp, ¬found, total); +@@ -359,13 +353,10 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + + /* Fill in the dataset. */ + dataset = (struct dataset *) buffer; +- dataset->head.allocsize = total + req->key_len; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- dataset->head.ttl = db->postimeout; +- timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl; ++ timeout = datahead_init_pos (&dataset->head, total + req->key_len, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ db->postimeout); + + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; +@@ -541,12 +532,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req, + dataset = &dataset_mem; + } + +- dataset->head.allocsize = sizeof (*dataset) + req->key_len; +- dataset->head.recsize = sizeof (innetgroup_response_header); ++ datahead_init_pos (&dataset->head, sizeof (*dataset) + req->key_len, ++ sizeof (innetgroup_response_header), ++ he == NULL ? 0 : dh->nreloads + 1, result->head.ttl); ++ /* Set the notfound status and timeout based on the result from ++ getnetgrent. */ + dataset->head.notfound = result->head.notfound; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- dataset->head.ttl = result->head.ttl; + dataset->head.timeout = timeout; + + dataset->resp.version = NSCD_VERSION; +diff --git glibc-2.17-c758a686/nscd/nscd-client.h glibc-2.17-c758a686/nscd/nscd-client.h +index 98f77e7..ee16df6 100644 +--- glibc-2.17-c758a686/nscd/nscd-client.h ++++ glibc-2.17-c758a686/nscd/nscd-client.h +@@ -236,6 +236,48 @@ struct datahead + } data[0]; + }; + ++static inline time_t ++datahead_init_common (struct datahead *head, nscd_ssize_t allocsize, ++ nscd_ssize_t recsize, uint32_t ttl) ++{ ++ /* Initialize so that we don't write out junk in uninitialized data to the ++ cache. */ ++ memset (head, 0, sizeof (*head)); ++ ++ head->allocsize = allocsize; ++ head->recsize = recsize; ++ head->usable = true; ++ ++ head->ttl = ttl; ++ ++ /* Compute and return the timeout time. */ ++ return head->timeout = time (NULL) + ttl; ++} ++ ++static inline time_t ++datahead_init_pos (struct datahead *head, nscd_ssize_t allocsize, ++ nscd_ssize_t recsize, uint8_t nreloads, uint32_t ttl) ++{ ++ time_t ret = datahead_init_common (head, allocsize, recsize, ttl); ++ ++ head->notfound = false; ++ head->nreloads = nreloads; ++ ++ return ret; ++} ++ ++static inline time_t ++datahead_init_neg (struct datahead *head, nscd_ssize_t allocsize, ++ nscd_ssize_t recsize, uint32_t ttl) ++{ ++ time_t ret = datahead_init_common (head, allocsize, recsize, ttl); ++ ++ /* We don't need to touch nreloads here since it is set to our desired value ++ (0) when we clear the structure. */ ++ head->notfound = true; ++ ++ return ret; ++} + + /* Structure for one hash table entry. */ + struct hashentry +diff --git glibc-2.17-c758a686/nscd/pwdcache.c glibc-2.17-c758a686/nscd/pwdcache.c +index fa355c3..41c245b 100644 +--- glibc-2.17-c758a686/nscd/pwdcache.c ++++ glibc-2.17-c758a686/nscd/pwdcache.c +@@ -135,14 +135,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req, + else if ((dataset = mempool_alloc (db, (sizeof (struct dataset) + + req->key_len), 1)) != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = t + db->negtimeout; ++ timeout = datahead_init_neg (&dataset->head, ++ (sizeof (struct dataset) ++ + req->key_len), total, ++ db->negtimeout); + + /* This is the reply. */ + memcpy (&dataset->resp, ¬found, total); +@@ -215,14 +211,10 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req, + alloca_used = true; + } + +- dataset->head.allocsize = total + n; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = t + db->postimeout; ++ timeout = datahead_init_pos (&dataset->head, total + n, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ db->postimeout); + + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; +diff --git glibc-2.17-c758a686/nscd/servicescache.c glibc-2.17-c758a686/nscd/servicescache.c +index 12ce9b2..95bdcfe 100644 +--- glibc-2.17-c758a686/nscd/servicescache.c ++++ glibc-2.17-c758a686/nscd/servicescache.c +@@ -120,14 +120,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req, + else if ((dataset = mempool_alloc (db, (sizeof (struct dataset) + + req->key_len), 1)) != NULL) + { +- dataset->head.allocsize = sizeof (struct dataset) + req->key_len; +- dataset->head.recsize = total; +- dataset->head.notfound = true; +- dataset->head.nreloads = 0; +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = t + db->negtimeout; ++ timeout = datahead_init_neg (&dataset->head, ++ (sizeof (struct dataset) ++ + req->key_len), total, ++ db->negtimeout); + + /* This is the reply. */ + memcpy (&dataset->resp, ¬found, total); +@@ -207,14 +203,10 @@ cache_addserv (struct database_dyn *db, int fd, request_header *req, + alloca_used = true; + } + +- dataset->head.allocsize = total + req->key_len; +- dataset->head.recsize = total - offsetof (struct dataset, resp); +- dataset->head.notfound = false; +- dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1); +- dataset->head.usable = true; +- +- /* Compute the timeout time. */ +- timeout = dataset->head.timeout = t + db->postimeout; ++ timeout = datahead_init_pos (&dataset->head, total + req->key_len, ++ total - offsetof (struct dataset, resp), ++ he == NULL ? 0 : dh->nreloads + 1, ++ db->postimeout); + + dataset->resp.version = NSCD_VERSION; + dataset->resp.found = 1; diff --git a/SOURCES/glibc-rh1083647.patch b/SOURCES/glibc-rh1083647.patch new file mode 100644 index 00000000..995ad043 --- /dev/null +++ b/SOURCES/glibc-rh1083647.patch @@ -0,0 +1,26 @@ +commit c44496df2f090a56d3bf75df930592dac6bba46f +Author: Siddhesh Poyarekar +Date: Wed Mar 12 17:27:22 2014 +0530 + + Provide correct buffer length to netgroup queries in nscd (BZ #16695) + + The buffer to query netgroup entries is allocated sufficient space for + the netgroup entries and the key to be appended at the end, but it + sends in an incorrect available length to the NSS netgroup query + functions, resulting in overflow of the buffer in some special cases. + The fix here is to factor in the key length when sending the available + buffer and buffer length to the query functions. + +diff --git glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +index 426d3c5..5ba1e1f 100644 +--- glibc-2.17-c758a686/nscd/netgroupcache.c ++++ glibc-2.17-c758a686/nscd/netgroupcache.c +@@ -202,7 +202,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + { + int e; + status = getfct.f (&data, buffer + buffilled, +- buflen - buffilled, &e); ++ buflen - buffilled - req->key_len, &e); + if (status == NSS_STATUS_RETURN + || status == NSS_STATUS_NOTFOUND) + /* This was either the last one for this group or the diff --git a/SOURCES/glibc-rh1084089.patch b/SOURCES/glibc-rh1084089.patch new file mode 100644 index 00000000..83cdcec0 --- /dev/null +++ b/SOURCES/glibc-rh1084089.patch @@ -0,0 +1,65 @@ +diff -pruN glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/lowlevellock.c glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/lowlevellock.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/lowlevellock.c 2014-09-05 21:50:56.982975803 +0530 +@@ -21,11 +21,13 @@ + #include + #include + #include ++#include + + + void + __lll_lock_wait_private (int *futex) + { ++ LIBC_PROBE (lll_lock_wait_private, 1, futex); + if (*futex == 2) + lll_futex_wait (futex, 2, LLL_PRIVATE); + +@@ -39,6 +42,7 @@ __lll_lock_wait_private (int *futex) + void + __lll_lock_wait (int *futex, int private) + { ++ LIBC_PROBE (lll_lock_wait, 2, futex, FUTEX_WAIT | private); + if (*futex == 2) + lll_futex_wait (futex, 2, private); + +diff -pruN glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h 2014-09-05 21:51:58.722483631 +0530 +@@ -19,6 +19,8 @@ + #ifndef _LOWLEVELLOCK_H + #define _LOWLEVELLOCK_H 1 + ++#include ++ + #include + #include + #include +@@ -106,6 +108,7 @@ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ ++ LIBC_PROBE (lll_futex_wake, 3, futexp, nr, private); \ + __ret = INTERNAL_SYSCALL (futex, __err, 4, (futexp), \ + __lll_private_flag (FUTEX_WAKE, private), \ + (nr), 0); \ +diff -pruN glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h 2014-09-05 21:51:58.722483631 +0530 +@@ -19,6 +19,8 @@ + #ifndef _LOWLEVELLOCK_H + #define _LOWLEVELLOCK_H 1 + ++#include ++ + #include + #include + #include +@@ -122,6 +124,7 @@ + register unsigned long int __r4 asm ("4") = (unsigned long int) (nr); \ + register unsigned long int __result asm ("2"); \ + \ ++ LIBC_PROBE (lll_futex_wake, 3, futex, nr, private); \ + __asm __volatile ("svc %b1" \ + : "=d" (__result) \ + : "i" (SYS_futex), "0" (__r2), "d" (__r3), "d" (__r4) \ diff --git a/SOURCES/glibc-rh1084395.patch b/SOURCES/glibc-rh1084395.patch new file mode 100644 index 00000000..9e9c8d5d --- /dev/null +++ b/SOURCES/glibc-rh1084395.patch @@ -0,0 +1,28895 @@ +diff -urN glibc-2.17-c758a686/benchtests/acosh-inputs glibc-2.17-c758a686/benchtests/acosh-inputs +--- glibc-2.17-c758a686/benchtests/acosh-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/acosh-inputs 2015-06-20 21:22:16.295458166 -0400 +@@ -0,0 +1,303 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.6d46e7252da2fp388 ++0x1.c18cc3982093ep775 ++0x1.2e9a406645b9bp609 ++0x1.006d075b935c9p0 ++0x1.4d49f6cda4ceap0 ++0x1.e0ba4580ef871p21 ++0x1.ffab14f637eaap733 ++0x1.f0a22293c4ecbp852 ++0x1.24baf479f025cp0 ++0x1.91bc310a7648ep243 ++0x1.93d4c19692fbfp80 ++0x1.9eb0b40303dcap843 ++0x1.945a20aa092e2p4 ++0x1.ac2677a0ed292p0 ++0x1.64c6a3d5a0867p304 ++0x1.e0d6324c882e9p0 ++0x1.7e0ba7c987b9ep7 ++0x1.3975f02686229p10 ++0x1.cc4916f089070p25 ++0x1.729be339c67b2p0 ++0x1.c64b8297569c4p207 ++0x1.2c1544d816155p340 ++0x1.ad443265c6b4ap845 ++0x1.f53624533eb2cp0 ++0x1.92e4800542f83p108 ++0x1.f873e456e1975p0 ++0x1.84a7b4b80f227p4 ++0x1.46dd43031fe1fp0 ++0x1.e28b805a73a97p0 ++0x1.9e11325b1c3c4p22 ++0x1.5c76b43d66941p15 ++0x1.98109155dd7bfp21 ++0x1.3d88b121650aap8 ++0x1.adff01fab2117p0 ++0x1.5e76d52c7f729p15 ++0x1.0a46e3262c2b8p20 ++0x1.52f9a11ad6e66p0 ++0x1.96f8f26a41c3bp122 ++0x1.161fd6fd320d5p745 ++0x1.c5fb927d2cb09p8 ++0x1.265a61a0bb1d4p0 ++0x1.09a5d681397d0p0 ++0x1.ebef22f6aa8aap0 ++0x1.3ac9b75c613bdp160 ++0x1.b77615a1e2a3ap0 ++0x1.68f9d755d5eadp0 ++0x1.ed2c9188571d9p0 ++0x1.e8f886346b284p15 ++0x1.f65bd2ce4416ap0 ++0x1.4574341b05968p656 ++0x1.5c2cb3414299cp154 ++0x1.c4ea7682d0661p832 ++0x1.b221562a61af2p0 ++0x1.d7f9c739e0b26p561 ++0x1.eb28429726661p423 ++0x1.e7a5f5b2cc9e8p902 ++0x1.9fd093db922f4p0 ++0x1.c1cb5159d4e46p0 ++0x1.a0bed3234b8cdp0 ++0x1.bc8ff7e59e82ep18 ++0x1.de8f25287ff7cp0 ++0x1.a1ab66b8f9098p0 ++0x1.c36c11c290063p20 ++0x1.72e9e736d6e41p0 ++0x1.38b134391f71ep21 ++0x1.a500e5cf1a2cfp246 ++0x1.253da08c9c318p144 ++0x1.f5efb379e3b3fp952 ++0x1.07c767a225a7bp21 ++0x1.f82770adf361dp19 ++0x1.39e42524c048ep894 ++0x1.a4ae84e202a44p0 ++0x1.e17e23b598415p925 ++0x1.08fa931bd21f5p10 ++0x1.b52541759872ep0 ++0x1.91bf33cdb6804p710 ++0x1.5c18505e522d6p0 ++0x1.9fe7c5ca15212p9 ++0x1.62c360b992b13p10 ++0x1.57a000ceee049p800 ++0x1.da296671c3e5cp0 ++0x1.ff43325a40608p0 ++0x1.295d65809666fp111 ++0x1.2781e3f5d0e0fp249 ++0x1.875d5703776fcp0 ++0x1.0f8045a313158p26 ++0x1.bd30a3b638a67p11 ++0x1.0a3184db8d287p0 ++0x1.c6d33006f978ep0 ++0x1.8c6476a610245p0 ++0x1.aa7fc36f3cea9p461 ++0x1.afb5c0c4f933ap6 ++0x1.20b75365bd50fp16 ++0x1.69c8245c09535p19 ++0x1.30dcf0414c561p292 ++0x1.c2323455e5501p0 ++0x1.c2e3d08f78fb2p0 ++0x1.f479457ec8f4fp25 ++0x1.4c1e32e79005dp7 ++0x1.86b9a4aed3300p26 ++0x1.ee654167b045bp0 ++0x1.a339c796ccd9fp0 ++0x1.75f6f32348765p4 ++0x1.6120d7e4e5d9ep498 ++0x1.01c843ae8b440p20 ++0x1.034a67c534113p0 ++0x1.94d6d681be7e6p0 ++0x1.2576745f4cca6p22 ++0x1.813994f759a60p171 ++0x1.0308a4c5b820dp0 ++0x1.d073e0e895907p580 ++0x1.6094d2dc7af3bp0 ++0x1.3348d7ba303bep0 ++0x1.a0830483382afp2 ++0x1.e3558408e36dep0 ++0x1.d55db05590c97p0 ++0x1.95680648261ecp0 ++0x1.d54c401b55bd9p18 ++0x1.584be75027a11p872 ++0x1.594273cdd339dp4 ++0x1.85d9676b1ae49p752 ++0x1.38f122e7f7be0p220 ++0x1.75c3a575deb13p251 ++0x1.2c85f1a74ac0fp0 ++0x1.0dc9e789128acp947 ++0x1.51dbf3461a224p0 ++0x1.61c9644526617p809 ++0x1.89494217ed887p204 ++0x1.2a57014d8c24bp317 ++0x1.c4d527df0d553p762 ++0x1.ad2717638f0adp986 ++0x1.63352752d72c5p847 ++0x1.d124a052e9410p0 ++0x1.373d228ee6061p505 ++0x1.0bbe63d8b48d2p0 ++0x1.0b5115dd5774dp4 ++0x1.f50d62ef77ac6p3 ++0x1.4cb6110ea61e4p1 ++0x1.b056b690aef8ap0 ++0x1.a32cd47340669p2 ++0x1.f917868895288p872 ++0x1.332a86c10c0e1p14 ++0x1.07f7c34023735p881 ++0x1.7935f21efcfadp24 ++0x1.644ad1a392b18p0 ++0x1.f930b772bba49p0 ++0x1.019a86d2e2300p18 ++0x1.a25af297e68fep194 ++0x1.80ab316f210c8p0 ++0x1.f73a3049f9d76p16 ++0x1.8b1a0407ae636p7 ++0x1.9bdf23a917930p2 ++0x1.d139574e3913ep168 ++0x1.caf9468b5f459p0 ++0x1.c3b5f0096df0dp24 ++0x1.d3451096baf1ep0 ++0x1.7bb5671e2bfcap719 ++0x1.64b7e3621a6ddp0 ++0x1.08b544290bb37p0 ++0x1.2b65c78ec87a4p0 ++0x1.993a6363227e2p12 ++0x1.a09d26d2a558fp216 ++0x1.daff104bb08a5p25 ++0x1.7d77308fd73cap655 ++0x1.8946b691ecf5ap10 ++0x1.8ec222d562aa9p25 ++0x1.b7da17cd3268ap0 ++0x1.250500a0b4266p831 ++0x1.8e6f071075758p0 ++0x1.984146d8a6c69p20 ++0x1.558480e0da8bdp15 ++0x1.b6bea5e996fdbp11 ++0x1.f289853c632ddp11 ++0x1.8fbe179f273aap0 ++0x1.6b4382f669e8dp0 ++0x1.a966a17972ca9p601 ++0x1.dbd635362ec6bp6 ++0x1.899e75c43e065p675 ++0x1.f11c07e219bafp7 ++0x1.3ab637a02ed36p0 ++0x1.36b913a68fe70p901 ++0x1.049fe294eb450p0 ++0x1.0547247e7518ap677 ++0x1.9e07054aa7309p743 ++0x1.aff281fbb3a6ap874 ++0x1.6c1b6312efacfp783 ++0x1.a38c639c0df57p243 ++0x1.f07b95fd415ccp9 ++0x1.ca1c23fd6ce37p7 ++0x1.9ed9906a6f029p18 ++0x1.f1a483c62adecp74 ++0x1.617df662bbf02p0 ++0x1.22e1608c31f55p13 ++0x1.d840853d46285p15 ++0x1.023fd69d438dep12 ++0x1.8184a3fcc1ac3p942 ++0x1.25c5071d2dc6ep8 ++0x1.0eec25d2a59ccp27 ++0x1.d55b11ee07cc4p0 ++0x1.175347bf29152p23 ++0x1.546624c66c38bp0 ++0x1.212fc4abebddep723 ++0x1.75f1269063e4dp5 ++0x1.3b51233fed0a5p381 ++0x1.486e24ad660e1p686 ++0x1.7788055510c4dp23 ++0x1.55bf96fcf9458p905 ++0x1.0a5aa2d61be59p0 ++0x1.5da757c1a95c6p895 ++0x1.d596e1ea9dcefp0 ++0x1.e91b460893372p0 ++0x1.d934d6ea17649p728 ++0x1.cd74423b4c4aep15 ++0x1.dc3151a1b4289p0 ++0x1.5799c072442dep0 ++0x1.97ae606371057p22 ++0x1.7369c3195238ap0 ++0x1.43a1d0e6eae29p109 ++0x1.7fd922252a24ep425 ++0x1.bf01d7e826d2cp0 ++0x1.a397b7c711fcfp14 ++0x1.7b40809d9f6b5p0 ++0x1.58098134bf6afp0 ++0x1.567e92bdee806p3 ++0x1.641866cfab5e7p382 ++0x1.11d483657f659p0 ++0x1.f0b1d4cd82236p18 ++0x1.a18365ad84301p6 ++0x1.4f749259eb02dp140 ++0x1.4b1d721633901p747 ++0x1.fa9e9543d1dfbp5 ++0x1.ae33e3ae5e0ecp0 ++0x1.29c444207fa90p0 ++0x1.b55e708600082p19 ++0x1.bb1464c1f136fp0 ++0x1.d36f165b63b8fp880 ++0x1.c1a0d0ee96f75p27 ++0x1.9b1376e7377a3p0 ++0x1.6e88361aa13bbp619 ++0x1.d109f410d341bp822 ++0x1.654255768c727p0 ++0x1.c938959e450d6p0 ++0x1.26fd92ae3e170p356 ++0x1.157c240adb715p982 ++0x1.749735f182597p15 ++0x1.2291e3ab7501cp0 ++0x1.96d320a0153bap383 ++0x1.b569919b79b6fp214 ++0x1.0872c2cff972dp276 ++0x1.bd98342544357p0 ++0x1.853327d0e2f4dp11 ++0x1.23438314fb10bp0 ++0x1.342f35eabf622p707 ++0x1.d19f05a5a1fe4p13 ++0x1.67c566bcf73aap0 ++0x1.2ce065238fb73p27 ++0x1.5219d2e05f184p0 ++0x1.4a163440f7c98p4 ++0x1.d780c4711b212p0 ++0x1.395461c5f96a6p5 ++0x1.21efa25110e19p12 ++0x1.c9ddf4f375933p17 ++0x1.3da0800fe1f5ep0 ++0x1.90f147b3d0164p829 ++0x1.001d955d8a436p344 ++0x1.c6b2115b84675p319 ++0x1.650441a7059bdp554 ++0x1.3a49216bbe75ep0 ++0x1.fdd3c3404c763p750 ++0x1.0b97d555f912cp1 ++0x1.95c32605e6c59p20 ++0x1.6acfa746531b2p0 ++0x1.13f4d3bbd6417p8 ++0x1.ac31b628eaa2cp0 ++0x1.4293b3d3169d2p8 ++0x1.6e8a94f758a02p802 ++0x1.701604374d526p0 ++0x1.bec162f84a16cp13 ++0x1.2015764e98ea6p481 ++0x1.b9d12441e91a7p11 ++0x1.55a4c648ebcc2p378 ++0x1.65b6e4f33cc66p0 ++0x1.b12c01289b0c4p15 ++0x1.ce91f580c5091p228 ++0x1.719ec056f57fep1 ++0x1.0b2c87979b28cp23 ++0x1.218c0592aa7fcp95 ++0x1.ec1e878f29cf8p97 ++0x1.adc8d213f43b1p0 ++0x1.e788f6152fe51p0 ++0x1.a026b0485c0e8p12 ++0x1.f181e3ec38f77p3 ++0x1.dafd9764a705fp13 ++0x1.a292f29dfe6c4p0 ++0x1.661d765a50087p13 ++0x1.f619932e8e376p1010 ++0x1.4a1600b2e95dbp880 ++0x1.f5b95104bb64dp320 ++0x1.a7a935f93958ap22 ++0x1.5fe3a6a58526dp20 +diff -urN glibc-2.17-c758a686/benchtests/acos-inputs glibc-2.17-c758a686/benchtests/acos-inputs +--- glibc-2.17-c758a686/benchtests/acos-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/acos-inputs 2015-06-20 21:22:16.295458166 -0400 +@@ -0,0 +1,2712 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.e9ba80c1b0cc6p-1 ++0x1.0c06540e252bdp-3 ++0x1.eda8e7c0a34bfp-1 ++-0x1.fe8e777376d24p-1 ++0x1.cb1673c92f0c9p-1 ++0x1.e9ec316d0de94p-1 ++0x1.7307e45a9bfb6p-5 ++0x1.c16b847c92f30p-3 ++0x1.cf0d270e371f6p-1 ++0x1.129af5729ef19p-1 ++0x1.bce5d0689ab4ep-1 ++0x1.2952217220937p-1 ++0x1.1c76822aee340p-1 ++0x1.e24a2187c1a7ap-1 ++0x1.f952508426fa4p-1 ++-0x1.e800444223cecp-1 ++0x1.edbc56657e3b4p-1 ++0x1.5bcc935e4afc7p-1 ++-0x1.e008619377db7p-1 ++0x1.e7ca21e5cb233p-1 ++0x1.c426411a0bd0ep-1 ++-0x1.54b193e5a6106p-1 ++0x1.ef45d30d3aaeap-1 ++-0x1.0a7fa1bbcb68ep-18 ++0x1.7b4f05763d852p-1 ++0x1.dbc0233bcbacdp-1 ++-0x1.f9ecd08896017p-1 ++0x1.933a30bb5aecbp-1 ++0x1.d87450bf54160p-2 ++0x1.e74342dc955f8p-1 ++0x1.e46ab59e4b1eep-1 ++0x1.fde01341b468cp-1 ++-0x1.989e4472a3f0cp-1 ++0x1.e098a4166e777p-1 ++0x1.566335c979611p-1 ++0x1.596d3268f925ap-1 ++0x1.219017042f1fep-1 ++0x1.ecc867fb960bfp-1 ++0x1.b60655bef4f13p-3 ++0x1.f4a57127c7a0cp-1 ++-0x1.f62ee5fe0cadfp-1 ++0x1.3cd7211d9ad3dp-1 ++0x1.9df0943df0ed7p-1 ++0x1.ea161524e7d47p-1 ++0x1.e55a50493b1a9p-1 ++0x1.ec8561690ba28p-1 ++0x1.f16282757d76ap-1 ++0x1.51e1f7c96d12bp-1 ++-0x1.9e34b40c77bdbp-1 ++0x1.1703345163fc4p-1 ++0x1.4bc66758655fap-1 ++0x1.b153d53781d7dp-1 ++-0x1.f9ad04c73d758p-6 ++0x1.ee83a64fcc712p-1 ++-0x1.26b3228cfdb15p-1 ++0x1.a2c1325da062fp-1 ++0x1.eacf918428269p-1 ++0x1.210c161c12427p-1 ++0x1.8f4653c521ef3p-1 ++-0x1.3d666235ebc4dp-1 ++0x1.fbf321159facbp-1 ++0x1.fb0ae69837b58p-1 ++0x1.e7add59a28c21p-1 ++-0x1.b3931490e5c15p-22 ++-0x1.62bb903865b73p-7 ++0x1.d8d4c3d683cd2p-1 ++-0x1.f414e43e31308p-1 ++0x1.e85ef4b7677afp-1 ++0x1.8e5c2284c58ebp-1 ++0x1.350fc6069df8ap-1 ++0x1.b156a051f0bd8p-1 ++-0x1.cd2350b2a476cp-3 ++0x1.f2cd66a92c33ap-1 ++-0x1.e9d4a5abc7463p-1 ++0x1.edf3474fdf1bfp-1 ++0x1.ded3e00b45be7p-1 ++0x1.ecca5018f3375p-1 ++-0x1.f784a20ae007ep-1 ++0x1.79cd244068e29p-3 ++0x1.0520d4698e9c4p-1 ++0x1.df7633193349fp-1 ++0x1.eeacc7895ee01p-1 ++-0x1.cbddd66bebde8p-1 ++0x1.eaaab5eed4d48p-1 ++-0x1.b786c6d51b98dp-1 ++-0x1.61c366c7c79fap-3 ++0x1.f6f55566f3c9dp-1 ++-0x1.8455d26a48743p-1 ++-0x1.f027619f4ec1cp-1 ++0x1.4de6d77cd7b97p-2 ++-0x1.2d45e43d1b629p-1 ++0x1.dd061720e456ap-1 ++0x1.3bfb31bd7ed4ep-3 ++0x1.f35563c6fc9e1p-1 ++-0x1.da4995d5cee72p-1 ++0x1.a96983d9102b9p-1 ++0x1.e004440ae8f05p-1 ++0x1.e53b304fb4d06p-3 ++-0x1.f03185a1019d1p-1 ++0x1.8676b01d07ce0p-1 ++0x1.ea1916d533f0dp-1 ++0x1.03a04519c4e1fp-1 ++-0x1.e8ac5756ef915p-1 ++0x1.4d6bf1a203446p-4 ++0x1.d981a70cd845bp-1 ++0x1.1c125719eaaf8p-3 ++0x1.e85fb3990f27ap-1 ++0x1.e8e035a26d083p-1 ++0x1.cbfe848a09c42p-3 ++-0x1.e06e527c5ae19p-14 ++-0x1.bbd103472cef1p-25 ++-0x1.feed81508a469p-1 ++-0x1.dab671cd03097p-2 ++0x1.ea30578b17269p-1 ++0x1.6d0684ce3aa60p-8 ++0x1.66d50185eedb5p-2 ++0x1.e74243adbcc15p-1 ++-0x1.f64db1b1939aap-1 ++-0x1.ebd6465bc4b63p-1 ++0x1.e006e50dea620p-3 ++-0x1.c2fcf77c4861dp-1 ++-0x1.e632b5939513cp-1 ++-0x1.9ab8b4c3cb0b4p-1 ++-0x1.3a3bc41b1b0fcp-2 ++0x1.3372c7d8d3206p-25 ++-0x1.fd74373268dbbp-1 ++0x1.f4e100915be05p-1 ++0x1.9bc0232dfa0efp-1 ++-0x1.cc03e1478de39p-4 ++0x1.e93d0775eb299p-1 ++-0x1.a2bb4749faabep-3 ++-0x1.f052a40d8e48bp-1 ++0x1.c07334b1aac33p-26 ++-0x1.13463673ea539p-3 ++0x1.d66e5598d3262p-25 ++0x1.0dae423f0189ep-2 ++0x1.df1a0195dfca4p-1 ++-0x1.598e9260d11fdp-1 ++0x1.67c773c2070cep-1 ++-0x1.ed1f510c9ce11p-1 ++0x1.dae297d5d3bafp-2 ++-0x1.39af35b44da1fp-2 ++-0x1.c679d76fc2b15p-3 ++0x1.88f507621e546p-2 ++0x1.f702c7007d0f8p-1 ++0x1.f2ef13107c805p-1 ++0x1.e4bcf61e9db8ep-1 ++0x1.3bbb12f88beeap-1 ++-0x1.fdb1502db4889p-1 ++0x1.3318578e20bc0p-1 ++0x1.e9de7563a7493p-1 ++0x1.6188f44707072p-1 ++0x1.f8903254e120cp-1 ++-0x1.f38db4b985d52p-1 ++-0x1.cbccf0e19cc7fp-3 ++-0x1.be12773f273cdp-10 ++-0x1.2b3e149bb0426p-2 ++0x1.ad69976c033a1p-1 ++0x1.edd13194f87aep-1 ++-0x1.18a974fd7bbebp-1 ++0x1.9f1fc231a2241p-1 ++0x1.10e56678c706ap-25 ++-0x1.da0f94397e1efp-1 ++-0x1.76c026d8ec2b4p-1 ++0x1.0a089692fa9d6p-1 ++-0x1.da1ff0b273cd7p-3 ++-0x1.f97015d611b73p-1 ++0x1.dbe9c72d38923p-1 ++0x1.bad6c26512dbcp-1 ++-0x1.fb6fb5159af3ep-1 ++-0x1.9198b69ff20eep-3 ++-0x1.fe0c97242979ap-1 ++0x1.2287403404baep-1 ++-0x1.f3f5449170a5dp-1 ++0x1.f3a6840c57d33p-1 ++-0x1.03c0045400546p-1 ++0x1.f838e0db37795p-1 ++-0x1.7accc66f1a867p-1 ++0x1.e82562eb8444fp-1 ++0x1.df27b76e86704p-1 ++0x1.f4da573b55ec2p-1 ++0x1.efe5a6e5fbe8bp-1 ++0x1.0659847830f85p-1 ++0x1.e32184673d6a3p-1 ++-0x1.fea5968e2edf9p-1 ++0x1.466c21bdb53d6p-1 ++0x1.e7078679d9affp-1 ++0x1.befbe4ecbe8cbp-1 ++-0x1.e2d534c706c26p-18 ++0x1.32616231a62c1p-26 ++0x1.54edc38ae367fp-1 ++-0x1.3007019386da4p-5 ++-0x1.a336f67af7129p-1 ++-0x1.8c2257c536d60p-2 ++-0x1.84d896f47ecd4p-1 ++0x1.977af609a6d12p-18 ++0x1.e932a72cac166p-2 ++0x1.2945179c842bap-1 ++0x1.4a5182138dbd3p-3 ++0x1.dbe2458d35539p-1 ++0x1.1f1092dd29f91p-1 ++0x1.dc693710eb9b2p-1 ++0x1.ecb8b2274a503p-1 ++0x1.412eb424708fap-1 ++0x1.93ca610ea7b0cp-1 ++0x1.563fa238b86bfp-3 ++0x1.6cc3c369c6079p-1 ++0x1.f783b429dc0f3p-1 ++0x1.9b875417727f6p-1 ++-0x1.a03c44361af74p-1 ++0x1.f577461815545p-1 ++-0x1.1b83d2880ad3bp-1 ++-0x1.2850a5ece60c7p-22 ++0x1.03ce907b337a2p-7 ++0x1.e13907a8a623bp-1 ++0x1.ea3a84b97d192p-1 ++-0x1.a41072eb8d471p-1 ++0x1.eb4c15b45d01ep-1 ++-0x1.101d32f8c74c8p-1 ++0x1.0193b3f4d9074p-3 ++-0x1.537154d5f6ae7p-3 ++0x1.bfaf90a91ac01p-1 ++-0x1.0c10917ddebb8p-1 ++-0x1.8eadf732729dcp-21 ++0x1.e86b603c02c7fp-1 ++-0x1.e1d732a3d845ep-1 ++0x1.f11cd0a6f6f03p-13 ++0x1.8d26805424934p-3 ++0x1.f145109d6bdccp-1 ++0x1.c543a6761e121p-1 ++-0x1.c25a322cf34eap-2 ++-0x1.865940819f5fcp-1 ++0x1.dc04807986da6p-1 ++0x1.ed429667932c9p-1 ++-0x1.76fd636ed6498p-2 ++-0x1.e53ac26588b25p-1 ++-0x1.8f5d4684f487ap-1 ++0x1.e09a34d1ff29bp-1 ++-0x1.fa9d102a95505p-1 ++0x1.1b05e56138440p-3 ++0x1.1bc9a7f1d79eap-3 ++-0x1.6811368ab0abbp-1 ++0x1.ed98e0214a336p-1 ++0x1.e7e686da575a0p-1 ++-0x1.965f75ff798a9p-1 ++0x1.80eaa23a91ec2p-1 ++-0x1.d36fb043f6300p-5 ++0x1.7018a38a05ffdp-2 ++0x1.fae070244fb19p-1 ++0x1.d0dd401b30198p-1 ++0x1.42f142dadfa1dp-1 ++0x1.ec68818823d1dp-1 ++0x1.85f3e7bec93a0p-1 ++0x1.af29d1ff6c1dap-2 ++0x1.35c4a6805cca0p-1 ++0x1.df0b063501081p-1 ++0x1.5bcd000b70207p-2 ++0x1.a24de48ee748dp-1 ++-0x1.6a318265b0ce0p-1 ++0x1.c534f40a7def8p-3 ++-0x1.9f4e543169174p-1 ++0x1.f2de70648aed5p-1 ++0x1.fe8ab52a90cb0p-1 ++-0x1.f680253c19250p-1 ++-0x1.fc63569b7f833p-1 ++-0x1.6b2935d76744bp-1 ++0x1.ea5f006b8edcep-1 ++-0x1.5342e394b5397p-1 ++0x1.ec4706c41bd83p-16 ++-0x1.b7a5b13013786p-3 ++0x1.efc8b1d13cab4p-1 ++0x1.f524140aa4f9fp-1 ++-0x1.8d59b2246d1b5p-2 ++-0x1.e10a8025fd5c2p-1 ++0x1.ffe555d68b776p-1 ++0x1.5ccb0133fca6ep-2 ++0x1.47b60350a0542p-1 ++0x1.f3d4414a57242p-1 ++-0x1.4c94d139f13e8p-1 ++-0x1.f598238e275f3p-1 ++0x1.818fb41d76b85p-1 ++-0x1.fa14d2d9c0775p-11 ++0x1.f16ec2400aebap-1 ++-0x1.eac587507894dp-1 ++0x1.f20e64bfc7419p-1 ++-0x1.85ce9765938ccp-3 ++0x1.92bff695a5d90p-1 ++-0x1.8d0a2047280efp-2 ++-0x1.2559e3d4e777dp-22 ++0x1.e8390104997a7p-1 ++0x1.e99044f21a5c8p-1 ++-0x1.ea12258aac145p-1 ++0x1.f68a246001b3cp-1 ++0x1.db5b870d933e5p-1 ++0x1.a140f339c5bdep-20 ++0x1.8193402b5c8ecp-1 ++-0x1.04d5676a38199p-12 ++0x1.a455655209ff8p-1 ++-0x1.e63ba4f3d8c3ep-1 ++-0x1.6a28d15928650p-1 ++-0x1.64b6d0a25c33dp-9 ++0x1.46915799cfaccp-1 ++-0x1.fbd157a2c23b1p-3 ++0x1.ffa3663aba6d5p-1 ++0x1.411d129126d0dp-1 ++0x1.7063d30f52d4dp-1 ++0x1.8201c2f453059p-1 ++-0x1.f27a071cddd3bp-15 ++0x1.7aca32522bbf5p-6 ++0x1.c9846775a72c1p-3 ++0x1.6d082285276a9p-15 ++0x1.c6a6b4f8f837ep-24 ++0x1.ee27e42a2b26bp-1 ++0x1.e191c47dea938p-1 ++0x1.44b0e7864ee92p-2 ++0x1.9c4882b7b62cap-1 ++0x1.20b6f0f17af05p-3 ++0x1.0301e36c00af6p-1 ++0x1.dfe705d59ecb0p-1 ++-0x1.dbead5cf594d7p-1 ++0x1.f12b06bbb4e7bp-3 ++0x1.efe8c7612f386p-1 ++-0x1.eb9e2463b8a3ap-1 ++-0x1.faf13348b1a37p-1 ++0x1.cd50167950c5ep-1 ++0x1.dba5c79d7a05ep-1 ++-0x1.a334d05fa6dd2p-1 ++0x1.8cb1a630bb9c2p-1 ++-0x1.9681e2cf54b70p-1 ++0x1.39aca667fcf3fp-1 ++-0x1.e8bd029d083e4p-2 ++-0x1.50e857e4f8090p-1 ++0x1.dc16134a07952p-1 ++0x1.2c4bb22847712p-1 ++0x1.e7b0645e8a0abp-9 ++-0x1.8fc066ee56befp-11 ++0x1.edbf80f8c492cp-1 ++0x1.e3d6a1c24d10cp-1 ++-0x1.fbd4f63a7219dp-1 ++0x1.f6fd10b1bdf09p-3 ++-0x1.6530f1b557057p-1 ++0x1.b88262a6e1331p-1 ++-0x1.eb0e3015adc06p-1 ++-0x1.26cfc26e19c43p-3 ++0x1.59bc70a355e7fp-2 ++0x1.5fee801ec378cp-1 ++0x1.154984a08fb2ap-1 ++-0x1.75a356a8a9292p-5 ++0x1.ea9314dc90613p-1 ++0x1.ea2107288cf84p-1 ++-0x1.ebe7414198207p-1 ++0x1.65aee12e3ceffp-1 ++-0x1.51ba6636b9f2fp-15 ++-0x1.c626d4507f69ap-1 ++-0x1.e2e3f55bb23a1p-1 ++0x1.98b000eb73a71p-1 ++0x1.43af03a6b9b8dp-3 ++-0x1.7f2ab3a80ac43p-1 ++0x1.d9d2a5d6d0097p-1 ++0x1.e3f984fc9c133p-1 ++-0x1.afeb916e3177fp-21 ++0x1.4e04b4277b006p-1 ++0x1.efe0107fb5684p-1 ++-0x1.4515b4c2b21dap-1 ++0x1.11a6b0c515920p-1 ++0x1.6164a6618d12ep-21 ++0x1.dae745520e0c5p-1 ++-0x1.dd2d72e85c929p-1 ++0x1.6d9ef5d5611fbp-1 ++-0x1.f0f797fed0a55p-1 ++0x1.2eab0154ef308p-1 ++0x1.ed1fd3af0b556p-1 ++-0x1.e71b754c98246p-2 ++-0x1.2590214dd2a24p-3 ++0x1.fdd1961109848p-1 ++0x1.7eb1071ff2770p-1 ++-0x1.15bd45916de1ep-2 ++-0x1.44d715ad68f89p-1 ++-0x1.7641422787614p-1 ++0x1.eefe328d3d881p-1 ++-0x1.eca8704b551c7p-1 ++0x1.2ee67226d5529p-1 ++0x1.e8ac53c1395d3p-1 ++-0x1.64646108e67cbp-1 ++0x1.db91c36140425p-1 ++0x1.4605c5134237bp-1 ++0x1.f903e462cc94dp-1 ++-0x1.73f4c75c9d5f2p-1 ++-0x1.dac8a6d776479p-1 ++-0x1.2b4492bd73b64p-15 ++-0x1.373103fbf2dbbp-26 ++0x1.851581e8ee5f8p-8 ++0x1.ebca3047b32cfp-1 ++-0x1.07c16329a6368p-1 ++0x1.fccc50d54ff1fp-1 ++0x1.fe9de2486d607p-1 ++0x1.ef48b46c9b643p-1 ++0x1.e8ef618c8024bp-1 ++0x1.993fe684e622bp-1 ++0x1.460b45e598a8cp-12 ++-0x1.d9e786749e8b9p-3 ++-0x1.559071a09ac62p-1 ++0x1.ef7432ff2df38p-1 ++0x1.e45a36a5fb72fp-3 ++0x1.b3d5275cfb554p-1 ++-0x1.98e8e522e4a82p-23 ++-0x1.02aed44057b67p-2 ++0x1.2197f1f7c6e26p-1 ++0x1.0837b5e1cec38p-1 ++-0x1.ca8a4237c9e0cp-17 ++0x1.6006c4b0268aap-1 ++-0x1.7208a0ee99588p-18 ++0x1.b4b1e471a5f5fp-26 ++0x1.8fe1f13a9702cp-1 ++0x1.f02b227033d9ap-1 ++0x1.d97ec10440781p-1 ++0x1.f76fb1e91d5b2p-1 ++0x1.deb247936f19fp-1 ++0x1.8af0f66d4b0dcp-12 ++-0x1.b64be0350cfd6p-1 ++-0x1.f932f26d539d5p-1 ++0x1.e82a219e74d13p-1 ++-0x1.7e09139513a33p-26 ++0x1.18f8069a74b77p-1 ++0x1.dc6726bfa7475p-1 ++0x1.08c813e4436a5p-2 ++-0x1.d8320749306c8p-16 ++0x1.9472944ec390dp-1 ++-0x1.a99987154cea1p-1 ++0x1.c882368b557a4p-1 ++-0x1.1aa794570d691p-3 ++0x1.5c77249e4aea0p-1 ++0x1.eb9813be6a2b6p-1 ++0x1.f431a44ef4d40p-1 ++0x1.eea5d7d2221dap-1 ++0x1.2c6291d7f2ad7p-2 ++0x1.ac443697d70fdp-1 ++0x1.e20ca7c2912a5p-1 ++0x1.7ab1d7104d182p-18 ++0x1.339513d5d0ee8p-1 ++0x1.f589b5ee62b16p-1 ++-0x1.fad8f2a47e9f4p-1 ++-0x1.1dd663fac6b4fp-1 ++-0x1.0f9652222f8e9p-1 ++0x1.f35714209b7bdp-1 ++0x1.6834569b7a1fap-1 ++0x1.00dd565cc9ccfp-15 ++0x1.65da25ab2220cp-1 ++0x1.d84fa7357d48fp-1 ++-0x1.c51a11571e3e9p-1 ++0x1.f381b3df02583p-1 ++0x1.fbf8c33676a44p-1 ++0x1.82bc413c6aff0p-1 ++0x1.0dca9008fbcebp-2 ++0x1.235506540c7b9p-1 ++-0x1.3e3c739c48dc4p-1 ++-0x1.f73153b059fbap-1 ++0x1.cc56d349d03bap-2 ++-0x1.53099013f8190p-2 ++0x1.e53de61c37f3ap-1 ++0x1.a6a246bf1a535p-22 ++0x1.91d3b66fca3a2p-1 ++0x1.0f5d16ce3edabp-12 ++-0x1.9a7b92e12b5f7p-1 ++-0x1.76ca124cf6f47p-3 ++-0x1.c41b9411e2424p-1 ++-0x1.34c885f2eb328p-1 ++0x1.ec1e45f6f7b9dp-1 ++0x1.0a4775720ed55p-1 ++-0x1.31efb599b0c90p-1 ++0x1.edbe60062d7a3p-1 ++0x1.2319304ed36b5p-1 ++-0x1.cb6aa416f444fp-4 ++0x1.504f676650b1ep-1 ++0x1.3d1aa4401c058p-3 ++-0x1.f60c37def0ad1p-1 ++0x1.f9792648513f5p-1 ++0x1.94a7e574d0288p-1 ++0x1.94f7926ce6fbcp-18 ++-0x1.f6fad097104e4p-1 ++0x1.3088005339ad3p-1 ++0x1.f03355e0191c2p-1 ++0x1.dcd3d17610280p-1 ++0x1.e05d2667abb1fp-1 ++0x1.e82525f9fbf01p-1 ++-0x1.de3ca0ef987b7p-1 ++0x1.f59943ba80acep-1 ++-0x1.e960c36a66790p-1 ++0x1.9d26903f5cd50p-10 ++-0x1.89bec5921086fp-1 ++-0x1.f4e8b5ec98f6cp-20 ++-0x1.711982a677be4p-3 ++0x1.f46112d3fe843p-1 ++0x1.083e13f8fffefp-1 ++-0x1.baf382671db8ap-1 ++0x1.e0d881ff65497p-1 ++-0x1.45bc320aa4dfep-2 ++0x1.40e3e60b110dcp-1 ++-0x1.f4e3046089560p-1 ++-0x1.ea56c46279081p-1 ++0x1.e9e48261cb26ep-1 ++0x1.4d48f2887cd66p-2 ++0x1.e51d745ef2138p-1 ++0x1.ae3d476739166p-1 ++-0x1.3b19c402e1ab5p-1 ++0x1.93db32ee991c6p-1 ++0x1.159cd3c2eac06p-2 ++0x1.f2196713b8de3p-3 ++0x1.c3c4d2e87e40cp-5 ++0x1.546b31afe7b81p-3 ++0x1.1cd7423631f45p-23 ++-0x1.f98921eb79da8p-1 ++0x1.da4473bb667adp-1 ++0x1.f6d1c21979168p-1 ++-0x1.f83452138ebc1p-1 ++-0x1.77e2149e4a15bp-1 ++-0x1.e374023473851p-1 ++0x1.6135557835b0ep-1 ++0x1.116497cc82db6p-1 ++-0x1.d604e43246f1ap-1 ++0x1.e03ba16e3b2d0p-1 ++-0x1.fbcc51c3d0adap-1 ++-0x1.230833754cbadp-1 ++-0x1.e859b3f551706p-1 ++0x1.8ed6352b2279fp-1 ++0x1.e833c05936a7ep-1 ++-0x1.f45f124fb19f4p-1 ++-0x1.bcc7e5fa33d67p-1 ++0x1.cb5bf39c4168fp-1 ++0x1.d913109c549a2p-6 ++-0x1.5df3a69b09a81p-3 ++0x1.e92f739ce65adp-1 ++0x1.eddff4fa793e3p-1 ++0x1.fd0d826c5a1d9p-1 ++0x1.f01142b6404c5p-2 ++0x1.ed3e7235fb716p-1 ++-0x1.3f08a31b67052p-6 ++0x1.6c6bd2dd525cdp-1 ++0x1.e42d42ade6dd4p-2 ++-0x1.7c4f407d91487p-8 ++-0x1.1441528bd2bc9p-8 ++0x1.e5db61dfac951p-1 ++-0x1.cf52b5c3c6b19p-1 ++0x1.e83f57fd71bfcp-1 ++0x1.ae8f91695d74cp-1 ++0x1.545021fa9de9cp-1 ++-0x1.45c9266ea4970p-1 ++0x1.eafea77c551aep-1 ++0x1.eba4171524f40p-1 ++-0x1.425187f18c762p-18 ++-0x1.485fe6e78b76fp-1 ++-0x1.db6f1755478ccp-1 ++0x1.f8e25686998acp-1 ++0x1.ccbba7e740751p-1 ++0x1.7816a0d6522cep-1 ++-0x1.0cad003c37274p-22 ++-0x1.4249d37181745p-3 ++-0x1.1aea32c571f90p-2 ++0x1.eff2c75d80ec9p-1 ++0x1.dedbb5aa065c5p-1 ++0x1.022c15ed03102p-2 ++0x1.e28cc0a25217ep-1 ++-0x1.e75507711de7bp-1 ++0x1.6994d6b07313bp-1 ++-0x1.93938552d7672p-3 ++0x1.e9f062935639ep-1 ++0x1.efc9111829a30p-1 ++0x1.e82d352bd52d4p-1 ++0x1.8aefc30a2949bp-1 ++0x1.e829e785fe6bcp-1 ++0x1.906de67167cd7p-1 ++0x1.3cf7801ab3ddcp-1 ++-0x1.d674412d314f7p-1 ++0x1.b8f3652b4e782p-8 ++0x1.0797f77b05b64p-1 ++0x1.fa845330ec5ebp-1 ++-0x1.513a3093d637fp-1 ++-0x1.a0ae922b44732p-1 ++0x1.eb5b41b522564p-1 ++0x1.e9e54719a6384p-1 ++0x1.dc6a025cdf557p-1 ++0x1.8e2720ee32c68p-1 ++-0x1.08a965eef1feep-1 ++-0x1.fa6306dd46e3fp-1 ++0x1.155615f73dc49p-1 ++-0x1.ad5ce2c9a061dp-2 ++0x1.3a6b650c8bc49p-1 ++0x1.1d1f86d1e1e30p-1 ++0x1.cc1b051550465p-1 ++-0x1.eb9871c6f4d8dp-11 ++-0x1.9da0d78b9cbe4p-2 ++0x1.e6cb460ebeeebp-1 ++-0x1.ebcbb7d352b98p-1 ++0x1.f10602c31c4ffp-1 ++0x1.f83d00511f1a6p-1 ++0x1.e70ef18e894dcp-1 ++0x1.f42747759511dp-1 ++-0x1.e210555e48210p-1 ++0x1.e8be424104e58p-1 ++0x1.e269c29bcef60p-1 ++0x1.f85ef0fd21f0bp-1 ++0x1.937141f2672e0p-1 ++0x1.38ec61bd517ccp-1 ++-0x1.d6e9722dc24fcp-1 ++0x1.f8d1b326b2ed1p-1 ++0x1.d86da58fba185p-1 ++0x1.65efb1356114ap-3 ++0x1.f72791c9cf436p-1 ++0x1.0ae4753a5c894p-13 ++0x1.f7415347bb40bp-1 ++0x1.dc65a4f6e740cp-1 ++0x1.d88607a3797e0p-1 ++0x1.eed61776e402fp-1 ++0x1.ee0df44fb77d0p-1 ++-0x1.f450159e992b8p-1 ++0x1.e29cb14cdbcd0p-1 ++0x1.f653a3375d51dp-1 ++-0x1.f57f5552ab569p-1 ++0x1.6480d3d0c5efep-20 ++0x1.38e266cf4e67bp-23 ++0x1.d51cd22b5b6cap-1 ++0x1.dc3de7d2fc8d2p-1 ++-0x1.312a5566cde3fp-1 ++-0x1.fab1d3aa238acp-1 ++-0x1.95bac47704824p-3 ++-0x1.891b43164f852p-2 ++-0x1.80e9f033f4793p-2 ++0x1.df255385153fbp-1 ++0x1.de67748161291p-1 ++-0x1.777e66869b5a2p-2 ++0x1.95b610da4b767p-1 ++-0x1.0eaeb02390875p-24 ++0x1.ed4d9348c4329p-1 ++-0x1.96df34af5a088p-21 ++0x1.f2d162c70d8b5p-1 ++-0x1.deb665e66d761p-1 ++-0x1.0f044763f2eaap-3 ++-0x1.9c3784de626cbp-3 ++0x1.ad40b341217cep-1 ++0x1.a3d8456656f09p-1 ++-0x1.30688704ba934p-13 ++-0x1.f3cf5294a6a88p-1 ++0x1.e906911183a95p-1 ++0x1.d875b2a4cfad9p-1 ++0x1.e9ecd5820a5eap-1 ++-0x1.948a52ed5c31bp-5 ++0x1.f9c6e1a503f35p-1 ++-0x1.ec4f82e92c41cp-1 ++-0x1.2ee365574b66ap-6 ++-0x1.cf7594c4759eep-19 ++-0x1.a0d5f18128988p-2 ++-0x1.806c918e71aeep-1 ++0x1.df5d715846162p-1 ++0x1.f67f859e5cfe0p-1 ++0x1.ecc2b558d729fp-1 ++0x1.ff9fd0805bf30p-2 ++0x1.432fe2eead4f4p-1 ++-0x1.8366e3d1a2b7cp-1 ++0x1.e3f070eec2596p-1 ++0x1.30ba2715f8514p-1 ++0x1.e977633ddb6c8p-1 ++0x1.ecfff5d1ed4fcp-1 ++0x1.6e88143883032p-1 ++-0x1.e95fa37e7e7bbp-1 ++-0x1.b83c53c09f546p-1 ++0x1.517d53ed1b833p-1 ++0x1.db8f51d5f71aep-1 ++-0x1.1678154436606p-2 ++-0x1.fc21417ad3694p-1 ++0x1.1c843518d2e94p-25 ++0x1.e8eee13ebc573p-1 ++0x1.fee6721632c37p-23 ++-0x1.f6a87247c9154p-1 ++0x1.fe6af4fb98692p-1 ++0x1.e7c390a9bbc3dp-2 ++-0x1.e0f877f179d56p-1 ++0x1.d96bf428df776p-1 ++0x1.fc1c23962674cp-1 ++0x1.b198a6962238ep-1 ++0x1.033e6517daa6fp-5 ++-0x1.2d2db09cc6e86p-21 ++-0x1.1ed1f46145a42p-1 ++-0x1.aceee1f163bb0p-1 ++0x1.e775b65834bfap-1 ++0x1.b59893a929786p-1 ++-0x1.0e4bb0b067b5bp-1 ++-0x1.ff1285390535cp-1 ++-0x1.f8d0963809a50p-1 ++-0x1.e5a865ab089bcp-1 ++0x1.c6d112328b280p-1 ++0x1.f013574be1027p-1 ++-0x1.e0a691caa2943p-1 ++0x1.2506d6a72e424p-15 ++0x1.0e385386801e9p-1 ++-0x1.2c8ac0b1cee68p-6 ++-0x1.e44cf154f7837p-3 ++-0x1.9c7c24975ad82p-1 ++0x1.0d8d44f6a38b9p-1 ++-0x1.fb5c33ee7ffa5p-2 ++0x1.4ce97693eab63p-1 ++0x1.2d57b32c61adep-1 ++-0x1.ddc8c1bd6b2f6p-1 ++-0x1.60a8174ee182cp-2 ++-0x1.fe3ab0326a9ebp-1 ++0x1.c99672ad8233dp-1 ++-0x1.a05f0442a1f89p-11 ++0x1.f4efa58696ba2p-1 ++0x1.e8f0874ac9593p-1 ++0x1.697a477d1fbd3p-2 ++0x1.66b7a3a5f4bbcp-2 ++0x1.ec3a1130d87e6p-1 ++-0x1.5faae7d3bcf38p-1 ++0x1.be54761e95348p-1 ++0x1.d053b71612732p-1 ++0x1.f13a35b68c59ap-1 ++-0x1.ffd2875be2cf2p-1 ++0x1.e62df4c494b61p-1 ++-0x1.3471231cca442p-6 ++-0x1.a7b9e784d9434p-16 ++0x1.ece3f29820bdfp-1 ++0x1.ef6b47f54b2d8p-1 ++-0x1.df2c8655fc70dp-1 ++0x1.eda0969bec905p-1 ++0x1.488f14cfb8987p-1 ++0x1.feb910bbdd186p-1 ++-0x1.ed55067dcc2e0p-2 ++0x1.dee9b5b493f34p-1 ++0x1.37f0201120141p-2 ++0x1.bcf1c52c54526p-1 ++0x1.e2e2e4afd49aep-1 ++-0x1.a828f2fd070e9p-1 ++0x1.0995c67dde325p-2 ++-0x1.b9cee2442f243p-11 ++0x1.b5ffd6affbe68p-1 ++-0x1.898db08ff9e7ep-3 ++-0x1.eea7123455743p-1 ++0x1.e22364d8d2ffbp-25 ++0x1.9bc512637b567p-1 ++0x1.908f41ab382c6p-1 ++0x1.daa6242404908p-3 ++0x1.354d96ce0c1f1p-3 ++0x1.e4909407d6b04p-1 ++-0x1.ae60e50c81658p-1 ++0x1.d83d9616cffd1p-1 ++0x1.68d57679fbad0p-1 ++0x1.ee2a61e036810p-1 ++0x1.ff2523154e342p-1 ++0x1.e80a234204ccep-1 ++0x1.ee12e03c07731p-3 ++-0x1.f53bb6a0244b9p-1 ++0x1.a7d1d4d25fc9bp-15 ++-0x1.0d5e226bae52dp-3 ++-0x1.f7553430f26b9p-1 ++0x1.561a2200e4797p-1 ++0x1.dda171643a8f8p-3 ++-0x1.e9a0822672116p-1 ++0x1.9c8ad39c801dep-1 ++0x1.50fe36a2e907bp-1 ++-0x1.f5cb55c5f89b0p-1 ++0x1.e55b90ffc4db3p-1 ++-0x1.f580e64339dfbp-1 ++-0x1.c786d16c31b03p-1 ++0x1.ab3d818097c47p-1 ++0x1.f628956df2bddp-1 ++0x1.3c1983a14fe08p-1 ++0x1.ea6977319eac4p-26 ++-0x1.a2b2a3cf330a0p-2 ++0x1.e06d66507bd76p-1 ++0x1.ed4aa34d83d9dp-1 ++0x1.adbf4089e4bf0p-1 ++0x1.169462af69653p-1 ++0x1.7cdae69e34be4p-23 ++-0x1.f476a5d67b80dp-3 ++0x1.e4f9a4e8edcabp-1 ++0x1.fcb451b72ca3ap-1 ++0x1.bbee334a41744p-2 ++-0x1.e669334dbdbb2p-1 ++0x1.e1ef409647a27p-3 ++0x1.e2f3d0f200912p-1 ++-0x1.0ee0376cb5980p-1 ++-0x1.cd90d53a85604p-24 ++0x1.da2ee339cc169p-1 ++-0x1.91bee2eec93ebp-1 ++-0x1.db27252020025p-3 ++-0x1.ac0763a2833a8p-1 ++0x1.ed7de7964d7b7p-1 ++0x1.387816b7132c2p-15 ++0x1.bde1b11fb418ep-14 ++-0x1.f4b0e44a782a9p-1 ++0x1.c85742cc49d4ep-1 ++-0x1.2ae4206794c97p-2 ++0x1.e8ede2eca6ebcp-1 ++0x1.e83ec2bd612adp-1 ++0x1.cec725af1011dp-1 ++-0x1.f3f110dc11f36p-3 ++-0x1.82c441472b814p-1 ++0x1.12aee0aad581cp-1 ++0x1.d843d56f7661dp-1 ++-0x1.0fa9100cde2b7p-1 ++0x1.fbb577823c6b2p-1 ++-0x1.e7e0f30c7c41bp-1 ++0x1.ead455b35dcfcp-1 ++-0x1.af50723be988fp-1 ++-0x1.c6df54f302009p-2 ++-0x1.f69220aac2bb2p-1 ++0x1.db2795c5314edp-1 ++0x1.f0e804039007cp-1 ++0x1.16e3c0bc73e90p-1 ++0x1.56f925b7342efp-2 ++0x1.2b1a40efca711p-1 ++-0x1.c95572af1befbp-1 ++-0x1.ea363656402fcp-1 ++0x1.9fcea6314eb53p-3 ++0x1.c384447b8f44dp-2 ++0x1.d9cb8501968aep-1 ++0x1.d213669b363a3p-1 ++0x1.dbbce7d0130a1p-1 ++0x1.ef1b07c170256p-1 ++0x1.e5d87723e3720p-1 ++-0x1.dc9450089dc1dp-1 ++-0x1.a400e154e4d4ep-22 ++0x1.f0b8639dae8c0p-1 ++-0x1.c0d7a6d0e58c3p-22 ++0x1.ebe277900a6d5p-1 ++0x1.ddc883853f7b1p-1 ++-0x1.f26d718326d24p-1 ++0x1.b444f4ecea2d4p-1 ++0x1.db5285f43880ap-1 ++0x1.ec2a704fa7ba7p-1 ++0x1.d9d38554f4ae7p-1 ++0x1.40a287e0245c7p-1 ++-0x1.bb5997a01dc09p-1 ++0x1.dbfe825428361p-1 ++0x1.eab9e61d0bb13p-1 ++0x1.dbf8477b40f85p-1 ++0x1.5977a5e9562d5p-2 ++-0x1.6d6582d27a94ep-3 ++0x1.ef98c62116f6bp-1 ++0x1.b195e01c1649fp-1 ++0x1.ed47e34ba7118p-1 ++-0x1.2e1b55053587cp-1 ++0x1.f46e72b797c76p-1 ++0x1.e58d17977d4c7p-1 ++-0x1.78044314faf55p-12 ++0x1.e67de4828d079p-1 ++-0x1.f72481a2b0f3ap-1 ++0x1.ef6de28920541p-1 ++0x1.81a907ff59256p-1 ++0x1.121bf667b781ap-1 ++0x1.e41ba30cd763ap-1 ++0x1.1e76d67046217p-1 ++-0x1.1250820739879p-1 ++-0x1.d15f33646b553p-2 ++0x1.e90c01d074c50p-1 ++-0x1.dc98c564661f8p-2 ++0x1.aab3b79abd652p-22 ++-0x1.12c3e674c7017p-3 ++0x1.207186d6329bap-23 ++-0x1.e9de504c45574p-1 ++-0x1.87494270ac164p-1 ++-0x1.e88cd321ec1dap-1 ++-0x1.9317565e1a195p-19 ++-0x1.350c40dd7d78ep-1 ++0x1.75b8a20113b5ap-3 ++0x1.ae0882e067102p-3 ++-0x1.313bb034e4980p-1 ++0x1.944cd3352094fp-1 ++0x1.e845447d64568p-1 ++0x1.fe614045bdde4p-5 ++0x1.c23a220bff5cfp-5 ++0x1.e4e1454ecf85dp-1 ++-0x1.fcf1e7da10e5ep-1 ++0x1.ee9f80c3fe210p-1 ++-0x1.dae080dc56bf7p-1 ++0x1.f8b43563a02aep-1 ++-0x1.debb0319481e9p-1 ++-0x1.f1d9c2f758defp-1 ++0x1.deb7334be5d7ep-1 ++0x1.e24ac198b2950p-1 ++-0x1.4b4613f445564p-13 ++-0x1.faf37271307aep-1 ++0x1.6a02646fd3199p-1 ++-0x1.e520507f83ff0p-1 ++0x1.974227fac5c71p-1 ++0x1.fe97f4454153cp-1 ++0x1.64cc47f51d1ebp-1 ++0x1.e0aeb2661bc7ep-1 ++0x1.865c7062df26ep-1 ++0x1.2b9d94fd96933p-1 ++0x1.dc43445d9d6c0p-1 ++-0x1.0bcd5161b4780p-1 ++0x1.e8eba118b0a26p-1 ++0x1.c838228508974p-1 ++-0x1.712d5001098d3p-14 ++0x1.eaafe5872fba9p-1 ++0x1.badc0660a7f51p-1 ++0x1.e66ca4a1fdcf4p-1 ++-0x1.ed40630f17ef4p-19 ++-0x1.eab7a154b753bp-1 ++0x1.8610d1e8e6c64p-3 ++-0x1.fd61a56639941p-1 ++0x1.26cb23fb114cep-3 ++-0x1.bf3de5d1277c8p-3 ++0x1.eda2c028553a7p-1 ++0x1.e0be233591f18p-1 ++0x1.fa64112d9b7bdp-1 ++-0x1.f5e2246ae2dd4p-1 ++-0x1.57b0e23b39e09p-1 ++0x1.d97671e65ea90p-1 ++-0x1.e6be223004611p-1 ++0x1.d56357592f5acp-2 ++0x1.6475907a120e3p-1 ++-0x1.f47e6381c6551p-1 ++-0x1.f2b9635cc6607p-1 ++-0x1.5277123e133e3p-1 ++0x1.47e5a403ff975p-15 ++-0x1.3b47975249d03p-1 ++-0x1.2d4395c82f1adp-2 ++0x1.1450373bbdbf4p-1 ++-0x1.f3f605106ccd2p-1 ++0x1.e4fb505afc536p-1 ++-0x1.c45f37ee28f93p-1 ++-0x1.ea50f192e21edp-1 ++0x1.eb0711bcb2188p-1 ++0x1.b7a016b696338p-1 ++0x1.623046e714274p-3 ++0x1.43e5923d7c3c7p-1 ++0x1.2fa122f6646a9p-1 ++0x1.f4f6b5de34b5ep-23 ++0x1.f469264200881p-1 ++0x1.655d872a08e7bp-1 ++-0x1.efbc035d5241cp-1 ++0x1.eecee67cb7c37p-1 ++0x1.ef23215f6de12p-1 ++-0x1.9157d3c02c3b2p-1 ++0x1.c15691eeda91ap-3 ++0x1.f39d271893c42p-1 ++-0x1.e4f743d28a786p-1 ++-0x1.e3439360d1751p-2 ++-0x1.e307d799961afp-1 ++0x1.e25a6469a523ep-1 ++0x1.f220a525222a6p-1 ++-0x1.e47060fdcc071p-1 ++0x1.36f464d433610p-1 ++0x1.d2182142a2d5cp-1 ++0x1.eeae3359ec957p-1 ++0x1.9af5d2ec8ebd9p-1 ++0x1.e11a171b22e03p-1 ++0x1.b610305edff4ep-19 ++0x1.ed7ab363b3447p-1 ++-0x1.e41a54d8498d1p-1 ++0x1.51de25b587b24p-1 ++-0x1.c0e965c3967f1p-24 ++-0x1.c773d52b04af3p-3 ++0x1.d986851c611b7p-1 ++0x1.c82c83eaf14c7p-3 ++0x1.f7cc714398d27p-1 ++0x1.cb56a41743a82p-1 ++-0x1.c101b1037e3f5p-1 ++0x1.70704180d156ap-1 ++0x1.f2d9a4e18b93ep-1 ++-0x1.70f794d622807p-3 ++0x1.ea0c748947c48p-1 ++-0x1.a1436628d7964p-2 ++0x1.e577a48f03d8cp-1 ++0x1.fb333192c3fd8p-1 ++-0x1.849bb070f27dcp-3 ++0x1.ef97766ebf4d8p-1 ++0x1.bba5845fd0c44p-1 ++0x1.cc35e07310ee9p-1 ++0x1.bbf8c7bb9c20fp-1 ++0x1.e52107bcb90ccp-1 ++-0x1.53078258ff064p-6 ++-0x1.1d3673a2a8700p-8 ++0x1.eb3ae6f949eb2p-1 ++-0x1.8a2f305b13ed1p-2 ++-0x1.30fbb21b54296p-12 ++-0x1.448976b9db4f3p-4 ++-0x1.fba6c7b54d231p-1 ++-0x1.1f9010499bc15p-19 ++0x1.bf8d6212e3c0dp-1 ++-0x1.c3658532b752dp-17 ++-0x1.e40de71a02d0dp-1 ++-0x1.c7ef32e8414f7p-3 ++0x1.ecf661eaa759fp-1 ++0x1.5030f4f39c66fp-1 ++-0x1.a724314a500bcp-2 ++0x1.9999d51105133p-1 ++0x1.d9f6e4d727d70p-1 ++0x1.ed1fc550f095ap-1 ++0x1.503b14d81b366p-1 ++0x1.34b7d05a78c28p-1 ++-0x1.2cba67b857796p-1 ++-0x1.d77251ee3df8ap-1 ++0x1.59f032ff510d6p-2 ++0x1.4f88d744710e7p-1 ++0x1.d9e8209b73ea1p-1 ++-0x1.ffb86378c6e93p-1 ++0x1.ea73f543c07f7p-1 ++-0x1.87a6e44eaf473p-14 ++0x1.8db074f7cba71p-1 ++0x1.38b80586e18e2p-5 ++0x1.f8be8469e0f90p-1 ++0x1.821ca4290f63bp-1 ++-0x1.0dd78014ef1a2p-3 ++-0x1.149aa666c3c46p-2 ++0x1.eeb59431123bfp-1 ++-0x1.c253e67cccb47p-23 ++-0x1.1721b193cb808p-1 ++-0x1.f29d328022c9bp-1 ++0x1.dd6ca355705abp-1 ++0x1.d7e5a3e80c978p-1 ++-0x1.ff693303d6a1bp-1 ++-0x1.9792d040f6098p-1 ++0x1.e1bf0284f90b9p-15 ++-0x1.f841c459354cfp-1 ++-0x1.ea326681d6327p-1 ++0x1.ec41879c45965p-1 ++0x1.fa2d97e552ed9p-1 ++0x1.5522431c3f1d5p-1 ++0x1.f52c75ff3d843p-3 ++0x1.df7ff289d597ep-1 ++0x1.89e6d140f4474p-1 ++-0x1.f5e8400a879eep-1 ++0x1.d0ee108472a16p-1 ++0x1.22c9e3d23737bp-2 ++-0x1.f180d30e2ee8fp-1 ++0x1.dc4355da08d39p-1 ++0x1.83cc96505115ep-1 ++0x1.df1a927ae2d49p-1 ++0x1.f7cb87ac643cbp-24 ++-0x1.b5b5e40f69460p-1 ++0x1.b768756962650p-1 ++0x1.385d044ddae6ep-1 ++-0x1.20b4a1a53c3d5p-1 ++0x1.7a97a05587a0dp-1 ++0x1.f298d21034624p-17 ++0x1.0f4422ec03b3ap-1 ++0x1.8c67965cd0051p-1 ++0x1.cee130d0b5a2bp-3 ++0x1.3dc4e295f1f30p-1 ++0x1.808b2220ea364p-1 ++-0x1.fd05a69ce67b4p-22 ++0x1.c6af341fa003ap-1 ++0x1.ecd747e9c09c1p-1 ++-0x1.551e1792426dap-1 ++-0x1.fdc4b78598f6dp-1 ++0x1.e705a3952cb55p-1 ++-0x1.e302b444c2d4ap-1 ++0x1.6079b20e499ddp-1 ++0x1.9deca443255dap-1 ++0x1.6c4eb3d0781b2p-1 ++0x1.ea66d20e1b503p-1 ++0x1.eaed6246abfe5p-1 ++0x1.e9b823bbcfc07p-1 ++-0x1.ce30a300a911ap-3 ++0x1.a87ec3c5f01d2p-2 ++0x1.bb25e46a7f518p-1 ++0x1.edf7166512c36p-1 ++-0x1.efe7a1f38e957p-14 ++0x1.ea9ef4d1cf987p-1 ++0x1.8eba239546037p-13 ++0x1.4e7173f8c3108p-25 ++0x1.e87141103b5edp-1 ++0x1.fe1db59696078p-1 ++0x1.f81a9367f49ecp-1 ++-0x1.1c8ca3340ee9ep-2 ++0x1.f4be90d6a08a2p-1 ++0x1.a57e54c302ffcp-1 ++0x1.3f689114ae747p-1 ++0x1.ba3652b8cb6e8p-25 ++0x1.d83d808a7f332p-1 ++0x1.dfd2264b6c472p-1 ++-0x1.e800e2c46ef54p-1 ++0x1.df8f111ae2866p-1 ++-0x1.6d6c5532e2cd9p-21 ++-0x1.1e2c81ace6c11p-22 ++0x1.e953222af7df2p-1 ++0x1.e925616ce5429p-1 ++-0x1.b26906bfadf37p-1 ++0x1.dbe1f423f0122p-1 ++0x1.8610709c83c3ep-5 ++-0x1.e659010e4489dp-7 ++-0x1.e69494ce3841fp-20 ++0x1.d8ff513fd08dfp-1 ++-0x1.fe6e319c28462p-1 ++-0x1.9d64d47733225p-3 ++0x1.c32282721051fp-2 ++0x1.eb3df7f6d191dp-1 ++0x1.8a44534c5fa47p-1 ++-0x1.4f6d93821061bp-2 ++-0x1.f52714fc5d094p-1 ++0x1.9de7e1e0dc8cbp-1 ++0x1.eeed020905613p-1 ++0x1.ec28d5dadfc7dp-2 ++0x1.aa36c26dcd467p-1 ++-0x1.8e87e6677fbfbp-2 ++0x1.ff84d1966abbdp-1 ++-0x1.f63e406386a93p-1 ++-0x1.f6203420a49e8p-1 ++-0x1.a48a93694dd80p-1 ++-0x1.61a7645eb7ec4p-1 ++0x1.e090c1a2c9b9fp-1 ++0x1.9b45d32c1533ap-1 ++-0x1.b11a761584f00p-1 ++0x1.9ad421a6de914p-1 ++0x1.79dbd61da7b2fp-3 ++-0x1.fc26a4aba22d2p-1 ++0x1.64105318b86d4p-1 ++-0x1.e9789541ac5d2p-1 ++0x1.fd9ec29f78db6p-1 ++-0x1.f14366570d3b6p-1 ++0x1.4b13d01bf21b3p-1 ++-0x1.f4eaf42e7ec78p-1 ++-0x1.339060228fa99p-5 ++-0x1.e744b298a1822p-1 ++0x1.deb6d20e46c2dp-1 ++0x1.292d24ec19bafp-3 ++-0x1.1e8a967a738a4p-1 ++0x1.dc10c61f240a2p-1 ++0x1.de2966eee1343p-1 ++0x1.e19d91e1c7907p-1 ++0x1.79c3b49ea70d1p-1 ++0x1.16e6f6035c12cp-2 ++0x1.decaf4a1bae55p-1 ++0x1.ab70f734c29e0p-1 ++-0x1.efe2c7ae66583p-1 ++-0x1.8bbb01f526908p-1 ++-0x1.aaac637a729e4p-21 ++-0x1.d8db236a8dc8dp-9 ++0x1.e36122ce4d0a1p-1 ++0x1.ea4005dd159f9p-1 ++0x1.b6a77767d4c9dp-1 ++0x1.e40c047e086a2p-1 ++-0x1.5dba61bbcf1dep-1 ++0x1.e5bc071b94585p-1 ++-0x1.f9215050b4d45p-1 ++0x1.fdafc34a31724p-1 ++0x1.869e353529f40p-1 ++-0x1.e2eda692286a9p-1 ++0x1.31642078c9c6dp-2 ++0x1.97e501e8fe7cfp-1 ++0x1.eb18e737043a5p-1 ++-0x1.e18a12334f770p-1 ++-0x1.d507b06c3df31p-18 ++-0x1.d0ec3013892e4p-3 ++-0x1.26c875185533dp-15 ++0x1.efbe6148f56fdp-1 ++0x1.c16d712b4bb1fp-3 ++0x1.8b04c70b3ddcap-1 ++-0x1.ab136560e555dp-22 ++0x1.f7af22a6b572dp-1 ++-0x1.d85926848cf29p-1 ++-0x1.ec59c307396f8p-1 ++0x1.e83fc488dacd6p-1 ++0x1.de8b34bf410c9p-1 ++-0x1.0d4466176e9fcp-1 ++0x1.29c0d4ecd2366p-2 ++-0x1.7c821349cb30fp-23 ++-0x1.f21cf62567c8ap-1 ++0x1.9475e0bee269cp-1 ++-0x1.360155ce19621p-1 ++-0x1.ab61b161880c5p-3 ++-0x1.687a92d61065ap-16 ++0x1.a07a83ec307b4p-3 ++-0x1.ced6825d25e04p-1 ++-0x1.3fd4120c4bf01p-3 ++-0x1.98615085cae70p-1 ++-0x1.565f25ad39799p-1 ++0x1.ff04d61b0df50p-1 ++0x1.3b887244ca6ebp-1 ++-0x1.faf3f337442b8p-1 ++0x1.c2857627f9c6ap-1 ++0x1.414391eae82a7p-2 ++0x1.ed4c041a3ead6p-1 ++-0x1.7720c11df55fep-3 ++-0x1.20dd07160306ap-3 ++0x1.eb79153ce9fddp-1 ++-0x1.0b7c366b28640p-1 ++0x1.0c37b2dba00aep-19 ++0x1.df2997df1e98ap-1 ++-0x1.db81e304bef8ep-2 ++0x1.d061109803210p-1 ++-0x1.f29f3377fe46bp-1 ++-0x1.9d69119b79677p-17 ++-0x1.fe18e3a9ee189p-1 ++-0x1.2ba7052c8bd80p-1 ++0x1.e241853578931p-1 ++-0x1.fb0854c5d75f0p-1 ++0x1.ee3cd20ce4f5ap-1 ++0x1.ee40d08bb49e3p-1 ++-0x1.cc9fa732730b4p-1 ++0x1.070692620b71cp-1 ++0x1.e0d2859d0d97dp-1 ++-0x1.82f763fdb686ep-1 ++-0x1.763cb2cf0a32dp-3 ++0x1.e43b37d8f0ddfp-1 ++0x1.a3880141b2dd3p-3 ++0x1.3befe215a78c6p-1 ++0x1.9d6604d4efeddp-2 ++0x1.b5a3d7eddda00p-1 ++0x1.cc7993074c20bp-1 ++0x1.aac5e5dc62767p-24 ++0x1.bed3226c9cf5ap-2 ++-0x1.efd3965c7e5acp-1 ++0x1.fe2aa46b77528p-1 ++0x1.e098e320da0bap-1 ++0x1.67e7248b818b3p-3 ++-0x1.6ad6002662fadp-2 ++0x1.decaa3bcdaa08p-1 ++-0x1.d58d16202023dp-10 ++0x1.ff00b5fcb622fp-1 ++0x1.32ef66d1351e1p-1 ++-0x1.f16585e5f84ebp-1 ++0x1.1f8845720550bp-3 ++-0x1.597ae70396752p-24 ++0x1.29d207dd78ad9p-3 ++-0x1.c50354e1919fdp-1 ++-0x1.f33b17f4530b4p-1 ++-0x1.01ede4cf1745cp-1 ++0x1.ca3f36b0aa65cp-1 ++0x1.40e9902e7c79ap-3 ++-0x1.59f3c5b673712p-1 ++0x1.916dc64eee2aap-1 ++-0x1.ef8c343a179b1p-1 ++-0x1.4a43014a489a2p-18 ++0x1.ea9994a3eea40p-1 ++0x1.7c24d44e7ad13p-1 ++0x1.f81f66a100c06p-1 ++-0x1.e7cb21c3e16e5p-1 ++-0x1.660cf02b53207p-1 ++0x1.9d1775b1ea06fp-2 ++-0x1.fb6e3107f4ab7p-1 ++0x1.ec9ed646b54a4p-1 ++0x1.eb877429ca44ep-1 ++0x1.57f90558e0cd2p-1 ++0x1.ee6127d9b9cd3p-1 ++0x1.eeace5528bcaep-1 ++0x1.abfa31533bf17p-1 ++0x1.af6d31714c4fap-3 ++0x1.1b88e568085eep-3 ++0x1.27d0012eda11fp-1 ++0x1.e4c3a00a353dcp-1 ++-0x1.a4d2513d6da08p-3 ++0x1.eac9041cf24d0p-1 ++0x1.eba880a52b2a0p-1 ++0x1.fc9815cf6cf07p-1 ++0x1.e9306397ac8d9p-1 ++0x1.b43cd65692d19p-1 ++0x1.ffed705f1a4ecp-22 ++-0x1.758b46be117efp-23 ++0x1.32f4b633ba0e9p-1 ++0x1.ebf364bf44defp-1 ++0x1.eb2c318fe1fd1p-1 ++-0x1.c4f6f0a35fd4cp-1 ++0x1.f94de7e900a23p-1 ++0x1.e040d6464605fp-1 ++-0x1.219fc52102aa7p-1 ++-0x1.453271b5e1e0cp-1 ++0x1.269653d6653a0p-10 ++0x1.a48e700ea9b1fp-1 ++-0x1.f41ec1c712c7fp-1 ++0x1.c96de70665e99p-2 ++0x1.ff20b67f593dcp-1 ++0x1.e13e27d7f0352p-1 ++0x1.e81bf743c0369p-1 ++0x1.c50ba323bc984p-5 ++0x1.2109349c356f8p-2 ++-0x1.8bdbe0b9e2d2bp-10 ++0x1.f668a1d8022d9p-1 ++-0x1.3e06e4a0baeedp-1 ++0x1.fb63f1e25d668p-1 ++-0x1.b8e1e27336860p-1 ++-0x1.f2700673bb386p-1 ++-0x1.b2daa6e18bec1p-1 ++0x1.8e8b67f0920cap-3 ++0x1.fdeba0a282ee5p-1 ++0x1.ed9061cac7a5fp-1 ++0x1.e697822f3ef41p-2 ++-0x1.a073961b21017p-3 ++0x1.eae16553c8c57p-1 ++-0x1.ef11308a723a0p-3 ++0x1.4db6f0d5fc8b1p-1 ++0x1.9db7a4e909c22p-1 ++0x1.d963f3e2377acp-1 ++-0x1.f4b2a27475355p-1 ++0x1.5ceea7934431fp-1 ++0x1.e006175a5233bp-1 ++0x1.db398369c7f83p-1 ++-0x1.6da6930d66d07p-1 ++0x1.6cc7155575699p-2 ++0x1.8958a513b1a3dp-16 ++0x1.e4d423f8e48d5p-1 ++0x1.f61e572c416f1p-1 ++-0x1.dce6b232fc21ep-1 ++-0x1.f76ac4a2a56ebp-1 ++-0x1.effa02c2a5b57p-1 ++-0x1.3277074adeefap-2 ++-0x1.f820b07829307p-1 ++-0x1.9ce743a0e44b1p-22 ++0x1.5a60c5b18ae7ep-1 ++-0x1.627064608ff5ep-1 ++-0x1.f18541418b0c8p-1 ++0x1.df5a362b58df6p-1 ++0x1.5a1c12189882bp-1 ++0x1.042eb250936bep-1 ++-0x1.1cb73699e8924p-1 ++0x1.bd81501f6c6dbp-1 ++0x1.ea461047bbbaap-1 ++-0x1.987e70cb208c9p-1 ++0x1.ebb7b667c93a9p-1 ++-0x1.e64087ec5398bp-1 ++-0x1.da4060f493507p-10 ++0x1.edf6c4bdb283ap-1 ++0x1.e56aa246ff0e4p-2 ++-0x1.5ee2870e9e6e3p-1 ++0x1.890c70d8e4854p-15 ++-0x1.9d713407fd722p-1 ++0x1.d81051269ec58p-1 ++-0x1.21a6c4b3b5c44p-1 ++-0x1.ff1743cc5a35ap-1 ++-0x1.bdd804759a629p-1 ++0x1.ecabd624ed76bp-1 ++0x1.f4fc4755c5257p-20 ++0x1.ef9f51187fe83p-1 ++-0x1.bcfe530a93051p-3 ++-0x1.04437668e59f9p-22 ++0x1.f9deb62170ec6p-1 ++-0x1.f95ff4e30111cp-1 ++0x1.b9bcd47a04014p-1 ++0x1.e986346f71ee7p-1 ++0x1.e870a1536e60dp-1 ++-0x1.f45142b039fd9p-1 ++-0x1.f9a361114e127p-1 ++0x1.a39e45adb3fcbp-1 ++0x1.eedee6a9faf61p-1 ++-0x1.2d7dd63289e16p-3 ++-0x1.ea1224bded243p-1 ++-0x1.4bdd4503c4c63p-1 ++0x1.6c88456adc480p-3 ++0x1.e2b3a4b24383cp-1 ++0x1.e5fc97f64aecbp-1 ++-0x1.1b6bb0f6cd48dp-1 ++-0x1.b303858a80ca8p-1 ++0x1.e7ab923c42554p-1 ++0x1.0a9275a4041e2p-1 ++-0x1.f8c00391024e6p-1 ++0x1.e35757a76e130p-1 ++0x1.e79240313e889p-1 ++0x1.65b7c5e770a90p-1 ++-0x1.c932d35cb0882p-1 ++0x1.6bdae68159ee5p-2 ++-0x1.a10396bb69be7p-1 ++0x1.385d508691b4ap-1 ++-0x1.879d741b2c118p-23 ++0x1.44ecc2c03843ap-1 ++-0x1.ff8f3716b5256p-3 ++-0x1.595040318030ep-3 ++-0x1.bcfdf5e4c6970p-1 ++0x1.0f3c92514126ep-1 ++0x1.3dc123067ed3fp-1 ++-0x1.ecbe16bf69bfbp-1 ++0x1.9ee9220c8f948p-2 ++0x1.dda1a2c40b3a6p-1 ++0x1.c24c85e28024fp-1 ++0x1.28b060d622339p-1 ++0x1.ef1b944c9f858p-1 ++-0x1.f476a1ba386d0p-1 ++0x1.83edf16dfff50p-1 ++0x1.e7ee358e79562p-1 ++0x1.e31ec6e0b4fc4p-1 ++0x1.dd98613b70372p-1 ++0x1.da5505c9b5082p-1 ++0x1.24f756f5e8490p-22 ++0x1.2c5d704de00e2p-3 ++0x1.e8faf051d09cbp-1 ++-0x1.ff78b2a719f69p-1 ++0x1.db133789d06a7p-1 ++0x1.66c0e08344febp-1 ++0x1.406506bfcfb11p-1 ++-0x1.55ac10a3a8641p-3 ++0x1.fce4f63c2836bp-11 ++0x1.a49c5484fe1ecp-1 ++0x1.ec7bc658a8951p-1 ++0x1.e84b3736a7b34p-1 ++0x1.ac8f6552a58dep-1 ++0x1.f42ee4d7dac9dp-1 ++0x1.3951052bb8e1fp-1 ++0x1.bec8b0e3edbb6p-1 ++0x1.33855463baf99p-1 ++-0x1.177641b2f5da9p-2 ++0x1.df40141a3b57dp-1 ++0x1.e92b22c10a9ddp-1 ++-0x1.f0bf840efa02bp-1 ++0x1.19a5c7f4ac19ap-1 ++-0x1.f06581e9738c7p-22 ++0x1.fa84d6fc1bfb4p-1 ++-0x1.ff5cc72dade88p-1 ++0x1.e0942271d057fp-1 ++0x1.02338781af33bp-3 ++0x1.696c8704c0adep-1 ++-0x1.f1687635d3527p-1 ++0x1.8fd781a156526p-1 ++0x1.fe1874b71dffap-1 ++0x1.8651325797215p-3 ++0x1.bc3c71925e5b6p-1 ++-0x1.1e9543b9189ebp-4 ++0x1.e4e8c2f4a4892p-1 ++0x1.9cec761d69c12p-1 ++0x1.b823a13640780p-1 ++0x1.1340e0318b586p-1 ++0x1.ecea93cc4e282p-1 ++0x1.381af30c8bbacp-3 ++0x1.269575fbaa2a4p-1 ++-0x1.806dd0823096dp-1 ++-0x1.e052374d36a4bp-1 ++0x1.fea3254b1eafap-3 ++0x1.2d5970ca26f6cp-1 ++-0x1.f4dea4866c50bp-1 ++0x1.f69344c9b9904p-1 ++-0x1.a3903178cc914p-1 ++0x1.ef5191f3a5593p-1 ++0x1.f5f3548da6996p-1 ++-0x1.f643440d6b06cp-1 ++-0x1.f002c7269a37ep-1 ++-0x1.fa75252a58e2dp-1 ++0x1.d9f9e3d739f44p-1 ++0x1.634732e2952fap-10 ++0x1.f218003f765f8p-1 ++0x1.606f8100c1742p-2 ++-0x1.e755f3286db4ap-1 ++0x1.a51346ad161ffp-1 ++-0x1.fb568187a36cdp-1 ++-0x1.e9fb506e00816p-1 ++0x1.ef4ba09903242p-1 ++0x1.decac67825caep-1 ++0x1.e87f025e48684p-1 ++0x1.e3f8778ca9756p-1 ++0x1.def1462172dfbp-1 ++0x1.311253501f3f2p-3 ++0x1.b47cd28626b01p-1 ++0x1.ea01327b06539p-1 ++0x1.f29325d22a5b5p-1 ++-0x1.63cce0ecc9f3fp-2 ++-0x1.cbec261c8745fp-2 ++0x1.839f62344ed35p-1 ++0x1.db5e820db1f0dp-1 ++0x1.eb10463897a41p-1 ++-0x1.01a9b60073fd1p-2 ++0x1.820c4727f0297p-1 ++0x1.defe9157b25b9p-1 ++0x1.95acf5bfa2f77p-3 ++-0x1.f829a7cd489c0p-1 ++-0x1.f78f2515a0c93p-1 ++0x1.e40934a3f3e57p-1 ++-0x1.fb0a94ad8c18dp-1 ++-0x1.8f0b53139648dp-20 ++0x1.d801c522cfcf4p-1 ++0x1.d91a30bb3e15dp-1 ++0x1.e41a80baf531bp-1 ++0x1.e96113c21b2e6p-1 ++0x1.cbb5955832906p-1 ++-0x1.faaf461b00258p-1 ++0x1.2c7b264df7e18p-2 ++0x1.cdf68750f625fp-1 ++-0x1.ab062115542b8p-2 ++0x1.cd73a32168810p-2 ++-0x1.f3f1411a81959p-1 ++0x1.57c7a2ace0a72p-1 ++0x1.efb2212f852c5p-1 ++0x1.8e0f47ea636f7p-1 ++0x1.ea6d312855164p-1 ++0x1.31a3e53d9d779p-1 ++0x1.bc55404efb12dp-19 ++-0x1.b6f9a6276a135p-1 ++-0x1.c3e361caeb9f1p-1 ++-0x1.e0eca0ecd7cb7p-1 ++0x1.f847f61015d15p-1 ++0x1.ed36e1f48a48ap-1 ++0x1.f41ca43bda5ffp-1 ++-0x1.ad50f432557fap-1 ++-0x1.114fa24a19444p-2 ++0x1.36def65bab425p-1 ++0x1.fe05623afcc36p-1 ++-0x1.ef66a308f97d2p-1 ++0x1.8d4b844dd2993p-1 ++-0x1.d6cff1d46ff9bp-9 ++-0x1.ee29a33d89217p-1 ++-0x1.f132f2992494fp-1 ++-0x1.de7153b5aad60p-3 ++0x1.d915353edaa25p-1 ++0x1.ea64823156f61p-1 ++0x1.4d3ba3c4d2e24p-1 ++0x1.ba92542786897p-1 ++-0x1.fffed63ad096dp-1 ++0x1.e97f8083149abp-1 ++0x1.b79ba1d3be769p-1 ++-0x1.eab325c5fbbe8p-1 ++-0x1.c3e3470150bafp-1 ++0x1.e3b610f2a9a12p-1 ++0x1.091a864ba6574p-3 ++-0x1.462ed634d347cp-2 ++0x1.ed90006d31696p-1 ++-0x1.c62a454b8d40bp-1 ++0x1.371a12446cb76p-2 ++0x1.eb63b3e34705ep-1 ++0x1.edf750cfdec5ap-1 ++-0x1.308fe73061dc7p-1 ++-0x1.ee05e10877512p-1 ++-0x1.d67e0577a6507p-1 ++-0x1.ed2eb7554cecap-2 ++0x1.dca2a028e0226p-1 ++0x1.d30c963d41488p-1 ++0x1.7530e7c8620bfp-1 ++0x1.d417a562c0d61p-1 ++0x1.e20e43f399e37p-1 ++0x1.ea15f4adca008p-1 ++-0x1.f3b7c47cb6dc6p-1 ++-0x1.154f81f240248p-7 ++-0x1.151356f0736d8p-1 ++0x1.f6ee472b8805fp-1 ++0x1.92518330d7f45p-1 ++-0x1.dc476211ce07dp-1 ++0x1.e848464011e2bp-1 ++-0x1.46a8919520b17p-1 ++-0x1.77fe90512eacfp-1 ++-0x1.9acbd0bea7745p-2 ++-0x1.443961a482f0fp-2 ++0x1.dc9150d6da395p-1 ++0x1.8f0b30b8722ebp-11 ++-0x1.ec2db037a82dcp-1 ++0x1.e3e7f06de29f4p-1 ++-0x1.f321806888b14p-1 ++0x1.bcc2d238d4ddbp-25 ++-0x1.b5d02551d5671p-10 ++0x1.5b65c47382c9ap-3 ++-0x1.fcbdd2b050f64p-1 ++0x1.ea5c13904e3b2p-1 ++0x1.ef36a448b7555p-1 ++0x1.dfdfd6c700acfp-1 ++0x1.4236c13576e0ep-2 ++0x1.8df8a16525f39p-3 ++0x1.e0ad97d2cf238p-1 ++-0x1.38f0542ca311ap-1 ++0x1.d87891d37859cp-1 ++0x1.e10e138b446a6p-1 ++0x1.0f92764f7b2e4p-1 ++0x1.aade166075ea0p-1 ++-0x1.902df59995e2fp-15 ++0x1.de7c758e0561ep-1 ++-0x1.bbcb739c535d8p-3 ++0x1.750fa027faf9ep-1 ++0x1.af8d62c66fb2cp-1 ++0x1.ea9ec240b76fap-1 ++0x1.ef92f02323e66p-1 ++0x1.410642b877d0fp-1 ++0x1.ecec322ab031cp-1 ++0x1.88a7042cf26e3p-1 ++0x1.d91c147875780p-1 ++-0x1.891bb78017f41p-3 ++0x1.ecbf764fb7f74p-1 ++0x1.8ae814193f661p-1 ++-0x1.9ab562e85a368p-1 ++0x1.eafad3737c504p-1 ++0x1.f172b00025f8dp-1 ++0x1.9625e4660a46ep-1 ++0x1.ff2847663862cp-23 ++-0x1.f876845608312p-1 ++0x1.f988f6376ddcep-1 ++-0x1.32096643967c8p-24 ++0x1.862f469d3b6b5p-1 ++0x1.e409002dbe096p-1 ++0x1.ebae12a190827p-1 ++-0x1.c73c104933177p-3 ++-0x1.e67b111d9643ap-1 ++0x1.e14005d42553cp-1 ++0x1.6bcdd5585b74ep-1 ++0x1.d01df07e10013p-1 ++-0x1.aa01a6ca96ca1p-1 ++0x1.9adaa0b3675d2p-1 ++0x1.abf414448c2c7p-1 ++0x1.e5c940ebf6cffp-1 ++0x1.5cf30257670ddp-1 ++-0x1.c572d1625cc9ap-1 ++0x1.c46f07973a003p-1 ++-0x1.e9edf7eef925cp-1 ++0x1.e2db71253b231p-1 ++-0x1.f18a81c759b6ep-1 ++-0x1.0484943b8972bp-14 ++0x1.e8ba541de4c3dp-1 ++0x1.e86031182f48ap-1 ++0x1.edf485b87d989p-1 ++0x1.ed7b63e2ae6e5p-1 ++0x1.441ba0eeee084p-1 ++-0x1.f157124313805p-7 ++-0x1.592b96408f745p-15 ++-0x1.aa9f35bb8710cp-3 ++0x1.dd79933eb4823p-1 ++0x1.8105f3b2d415bp-1 ++0x1.e959042778f64p-1 ++0x1.eb1923875839bp-1 ++0x1.f0f3621f3d303p-1 ++-0x1.fb9d116c1740ap-15 ++0x1.ee3e232a76cbdp-1 ++0x1.a720e17021d30p-1 ++0x1.4496d3d77e50dp-3 ++0x1.29b2708c3a747p-1 ++0x1.49f6619c13dd0p-2 ++0x1.01593434a17a8p-2 ++0x1.0c56546e3c83ep-2 ++-0x1.fd7591cf4e231p-1 ++0x1.f28e37cddaa63p-1 ++-0x1.21c025a637570p-2 ++0x1.e47fc5993f6c7p-1 ++0x1.85a2015249f9ap-1 ++0x1.ccac70b0bde88p-1 ++-0x1.b0c634676faacp-4 ++-0x1.f91d34193e0cap-1 ++0x1.ea81015237620p-1 ++0x1.e0f6a48d7e9c9p-1 ++0x1.fae08655a51a3p-1 ++0x1.4f28f1201b762p-3 ++0x1.e8e030f4ea7e4p-1 ++0x1.e1db95f200e1bp-1 ++0x1.f425e3cced4c7p-3 ++0x1.bdc8679163915p-18 ++0x1.febcf6c28536ap-1 ++0x1.92f204914b1bap-1 ++0x1.ecd8933b172edp-1 ++0x1.f0bb0482d6c17p-1 ++-0x1.1011a24690b17p-1 ++0x1.6597b5c278c94p-1 ++0x1.c03a92b120e58p-1 ++-0x1.0eed14bd5c463p-1 ++0x1.e84d0157c4875p-1 ++0x1.e0fa54716960fp-1 ++-0x1.e70102ffd26f4p-2 ++-0x1.a5029085d091bp-1 ++-0x1.ff504589e4c56p-1 ++0x1.cd7171df2e295p-3 ++-0x1.c2e6249c7296ap-21 ++0x1.96c5c059d54afp-1 ++-0x1.e6f51087203f2p-9 ++-0x1.515e3214390b1p-2 ++-0x1.e0a141c4f0b16p-1 ++0x1.eb7451be325a0p-1 ++0x1.e0d083fcb5089p-1 ++-0x1.fee190f2fc2b8p-2 ++0x1.fe9b45e910698p-1 ++0x1.a1bb4745dadf5p-1 ++-0x1.f652e1fdb6a40p-1 ++0x1.ddcf1291a5226p-1 ++-0x1.43cbc08a959f6p-3 ++0x1.dbf877fb563dcp-3 ++0x1.ca0a70766ed38p-1 ++-0x1.fb8063fd22722p-1 ++-0x1.fa4ed780ebffap-1 ++0x1.ef75b5fbc2038p-1 ++0x1.d8fad2d484f9cp-1 ++0x1.eb8ca278a8b79p-1 ++0x1.0fde2500275a5p-2 ++0x1.e71ef4f74efa5p-1 ++0x1.df0c61f2a0f01p-1 ++-0x1.bb5c7578b90a7p-1 ++-0x1.2e84858cbd9e2p-1 ++0x1.096bd4970cd0dp-22 ++-0x1.f41217509723dp-1 ++-0x1.32d10136b1f12p-1 ++0x1.4c6af75e75c32p-1 ++0x1.3fe9d75c1f312p-1 ++0x1.9ef980d30524ap-1 ++0x1.828b0390e301ap-3 ++0x1.f62692b289857p-1 ++0x1.5cb4743cbb81ep-13 ++0x1.ef86868247137p-1 ++-0x1.da44b5b4e6c6fp-1 ++0x1.dbcd94da0d8b8p-1 ++0x1.ec9c878cfb5f0p-1 ++-0x1.5f64a17e9500dp-2 ++0x1.5c75e768472b4p-2 ++-0x1.a787c4bfd3b9dp-1 ++-0x1.cca7367cafebcp-1 ++-0x1.11bc51c1a6b71p-1 ++-0x1.f6df90b887fc3p-1 ++0x1.7a9fb439b7a47p-1 ++0x1.e33c401410e8dp-1 ++0x1.fb4ee1a050156p-1 ++0x1.e89fb349c715bp-9 ++0x1.9b1db0483a855p-20 ++0x1.a913b3a187ee1p-17 ++-0x1.ef7701b74636cp-1 ++0x1.828184fbbeaa0p-2 ++0x1.f4d8e628050abp-1 ++0x1.133d81d6ae23cp-3 ++0x1.f013f7c35659bp-1 ++0x1.efd682aa7da6dp-1 ++0x1.f1dc00f5ef3a9p-1 ++0x1.96072389d627dp-1 ++0x1.ea1691abf195ep-1 ++-0x1.cca2538d384bap-5 ++0x1.e92007ba8df2ap-1 ++-0x1.e141a1fc347e7p-1 ++0x1.ed08437e94ea2p-1 ++0x1.4445e5b18f130p-1 ++0x1.f66bb10cf125cp-1 ++0x1.704f576926a3ep-1 ++-0x1.1e2b763ff1c1bp-16 ++0x1.a257b5f59a887p-1 ++0x1.ee0771d865c59p-1 ++0x1.debf16684ec06p-1 ++0x1.dbdf762ec9500p-1 ++0x1.e60b71ca4175bp-1 ++0x1.30f9a5a27b4a8p-1 ++-0x1.f34ff26c85784p-1 ++-0x1.d1b2d7ceae413p-1 ++0x1.fdcf071e072d3p-1 ++-0x1.a3f255af4ee16p-1 ++-0x1.ea5db637383c4p-20 ++0x1.e23fd346a1c24p-1 ++0x1.398d4660919b3p-1 ++-0x1.2341b61c4a232p-6 ++0x1.e7ddc42b3a4a8p-1 ++-0x1.ff0942c4470a9p-1 ++0x1.fa0f0780123aap-1 ++-0x1.56f2e58d53fc9p-1 ++0x1.37fd262f2ef5ap-1 ++0x1.e9de764260ee7p-1 ++0x1.3b0da25eac967p-18 ++0x1.e4394344a153bp-1 ++0x1.ee5d6207f7775p-1 ++0x1.e1241012fada1p-1 ++0x1.e2e61171c55e6p-1 ++-0x1.fa0e3517f47f8p-1 ++0x1.e811955ba544ap-1 ++0x1.4003e18e34c12p-23 ++0x1.f4f195748771bp-1 ++-0x1.ef0f34f9f356fp-1 ++0x1.391e008ea4619p-3 ++-0x1.bb0300053577dp-2 ++0x1.612ec16edaa00p-1 ++-0x1.53edf5aa8e452p-1 ++0x1.267ce71264f70p-1 ++-0x1.b0c102e4ded61p-1 ++0x1.b7b2671933257p-1 ++0x1.ea53f7e49d1fep-1 ++-0x1.ea6bc6967c364p-1 ++0x1.95d8a522476fap-1 ++0x1.f99470c182bf6p-1 ++-0x1.ef0df4884c963p-3 ++0x1.e6157493cd764p-1 ++-0x1.12b6e5b410e7fp-1 ++0x1.f67435d502e6dp-1 ++-0x1.f4ec823b0125dp-1 ++-0x1.f638561f1eccbp-1 ++-0x1.b967b16c72982p-21 ++-0x1.842b3414ac978p-1 ++0x1.ef15c079cf311p-1 ++0x1.1d6fb030321d5p-2 ++0x1.ea147124ef4abp-1 ++0x1.e342f70874ef2p-1 ++0x1.e7afc67c34250p-1 ++0x1.19db65ff74336p-1 ++0x1.df80158c55f1bp-1 ++0x1.542a0182909a7p-1 ++0x1.057365e07e692p-2 ++-0x1.fb0d257f569cdp-1 ++-0x1.de3c10fe462f9p-1 ++-0x1.ecf8e686be7cep-1 ++0x1.55e863f86981dp-1 ++-0x1.eb05376e22db1p-1 ++-0x1.e83e578b67404p-1 ++0x1.1d7bf26bcd34ep-2 ++-0x1.ec5af0c2ccbc9p-1 ++0x1.ddd3d27a5b4aep-1 ++-0x1.eaf4048fe077cp-1 ++0x1.00801354b719ap-21 ++0x1.3e3a6224576bap-3 ++0x1.ed89f7096981cp-1 ++-0x1.daf4c6895a475p-2 ++-0x1.27b5065556c47p-1 ++-0x1.62e816a332a1ep-1 ++0x1.c38e7517dd45fp-12 ++0x1.915a220e086dfp-1 ++0x1.dd5754e2b6f70p-1 ++0x1.d84720817bef5p-1 ++-0x1.04b965445d524p-1 ++-0x1.e882f75e4f37fp-1 ++0x1.d8e1258d3e967p-1 ++-0x1.f4ad6308371a8p-1 ++0x1.0924a114faa3bp-1 ++-0x1.ee8ea3f68169fp-1 ++-0x1.db6440c16c293p-1 ++0x1.a260a5cf0493bp-1 ++0x1.ead6a5782d24dp-1 ++0x1.e049c5ecc67fcp-1 ++-0x1.480570f907c0ap-25 ++-0x1.e6a7c54bbfa5ap-1 ++0x1.fe6ad355328e4p-1 ++0x1.e2d7666a25355p-1 ++0x1.eec3b242762cep-1 ++0x1.c85773ca329d7p-1 ++-0x1.f163118d145f0p-1 ++-0x1.f79036a3f4459p-1 ++-0x1.204f96baed60dp-3 ++0x1.f9dc71e534411p-1 ++0x1.67b372a69cd0bp-3 ++0x1.eaa614d2c63c8p-1 ++0x1.bb01a3a90cd08p-3 ++-0x1.0bc192dba3daep-1 ++0x1.a7184731a11b4p-1 ++-0x1.bfb485fa7f5f4p-16 ++-0x1.3688a0346cbf4p-2 ++-0x1.f153e2327fc20p-1 ++0x1.658b516343b5ap-1 ++0x1.edd205a535cf6p-1 ++0x1.e2e360aa13064p-1 ++-0x1.c24710eb7be22p-3 ++0x1.041a67e3e8f28p-1 ++-0x1.eb8aa64a05087p-1 ++0x1.e30cf7c07f903p-1 ++-0x1.b9c3a3088d677p-1 ++0x1.713eb1ab5e4c9p-1 ++-0x1.6ad805c841fcap-1 ++-0x1.f885a3f0e8ba8p-1 ++0x1.f46dc196d78d6p-1 ++0x1.fc84242c90e1fp-1 ++-0x1.03cb72be8da0fp-1 ++0x1.876157be34442p-1 ++0x1.df7a00f91ede0p-1 ++-0x1.7aadc22f765e8p-1 ++0x1.c49f353c0eea6p-2 ++-0x1.6942e78790b68p-1 ++0x1.f09820d53213dp-1 ++0x1.f0d7d51f16eafp-1 ++0x1.dd09f317d4844p-1 ++0x1.c37884de423eep-2 ++-0x1.d888e3c9b6736p-2 ++-0x1.0f9db3fc68bccp-5 ++0x1.b6a6c3eebea0cp-1 ++0x1.45f1f16329902p-1 ++0x1.ea8ca34a12e96p-1 ++0x1.e301b33695f69p-1 ++0x1.68a5b3e8dc41fp-1 ++-0x1.31ff6639336e0p-1 ++0x1.5a9b126abc66ap-1 ++0x1.1973b36468d97p-1 ++0x1.efe1f56bd3534p-1 ++0x1.e5ab36d2f2409p-1 ++-0x1.45d6537260c70p-3 ++-0x1.56f5410b90154p-15 ++-0x1.7d8cb3c9cb5d8p-1 ++0x1.c96a64375fd43p-1 ++0x1.deb991e8ad26ep-1 ++0x1.f2cdb2dedca59p-1 ++-0x1.aca5d6e0cebc8p-1 ++0x1.eb42940a8517bp-1 ++0x1.ae1b403368423p-1 ++0x1.ade411f3da571p-1 ++0x1.3e1116e4de263p-1 ++0x1.8973c30a0bb9cp-1 ++-0x1.156c062335d7dp-1 ++-0x1.9acbe0ee1240fp-3 ++0x1.ec00c6a3e141ep-1 ++0x1.dc4b32a234a23p-1 ++0x1.e6c20026a69cfp-1 ++-0x1.8fa041d702f22p-3 ++0x1.c5f6f61e0882cp-1 ++0x1.ca32d645bd50ap-1 ++-0x1.eebfe7785b810p-1 ++0x1.d855e4e635750p-23 ++-0x1.c4f8e0df2acbdp-3 ++-0x1.7f7681cf8b0a8p-2 ++0x1.834e43d519f57p-20 ++-0x1.e6c711f8a07a2p-1 ++0x1.37e074e9bd23fp-3 ++0x1.e07616c72f309p-1 ++0x1.eb6786e4bb963p-1 ++0x1.19099015cd289p-1 ++0x1.e1a391292b6e3p-1 ++0x1.e2db651834387p-13 ++-0x1.fe98b265f6c23p-1 ++0x1.e2bfd7dc71f91p-1 ++0x1.ee47140384e38p-1 ++-0x1.001567470f803p-2 ++0x1.05bdf1d57b74ap-3 ++-0x1.9f9bb738e7354p-2 ++-0x1.e2b5a72fffc26p-1 ++0x1.e33c52a03a341p-1 ++0x1.c210e6a7521b4p-1 ++-0x1.89280419666a0p-3 ++0x1.ef4386066c43ap-1 ++0x1.617cf4e80da72p-2 ++0x1.ca67862290507p-1 ++0x1.d2db6598cfaf0p-1 ++0x1.4c52d70f696f4p-3 ++0x1.fd31e495b8cd4p-1 ++0x1.97d8c7b4c9114p-1 ++-0x1.f0fc72689286ep-1 ++0x1.93a7216be0c5dp-2 ++0x1.d3115794c28e9p-1 ++0x1.e285e72ab6c83p-1 ++0x1.e318d24b8b39ep-1 ++-0x1.eef6d32a0b85fp-1 ++0x1.8d1c623935f00p-2 ++0x1.69f611e882192p-3 ++-0x1.815743a3562efp-1 ++-0x1.eb08c0c39511ep-1 ++0x1.c59db4bbac95fp-1 ++0x1.7d0722deb44afp-1 ++-0x1.8315d64e9546ep-1 ++0x1.9dd1600231fb9p-1 ++0x1.e2e2e02cfc885p-1 ++-0x1.10e173bc56bedp-1 ++-0x1.fef5368baa990p-1 ++-0x1.ffa8a2b9fe667p-2 ++0x1.dffc77beb4240p-1 ++0x1.eeb121fd09f87p-1 ++-0x1.e90be055f4bc5p-1 ++-0x1.f41e016289c7cp-1 ++0x1.af5152f1a61dap-26 ++-0x1.fd48f58baaff1p-1 ++-0x1.4b0f8437f1bc3p-1 ++0x1.d4cc178e13728p-1 ++0x1.ce7265a719e49p-1 ++0x1.e9eff57262b39p-1 ++-0x1.f13f718045fb6p-1 ++0x1.e6bb77d8971e1p-1 ++0x1.b551834380757p-1 ++0x1.da0f873b6aa41p-1 ++0x1.f142b0d6cd227p-1 ++0x1.e9ab41fff09b7p-1 ++0x1.942ed2f7475d2p-2 ++-0x1.bb5fe6c2388bcp-20 ++-0x1.a2e262533502fp-4 ++0x1.dd9583ec5db42p-1 ++0x1.90fad5e8a6031p-1 ++-0x1.0373e4dddeb2ap-2 ++0x1.fd2901f3c9671p-1 ++-0x1.b260a79be9a1bp-6 ++-0x1.984e45ef80148p-1 ++0x1.5356962ebfc1cp-1 ++0x1.571e352fdd0f0p-2 ++0x1.f89e41aa2fad5p-1 ++-0x1.e6a1f419a0176p-1 ++0x1.e2d58615983eap-1 ++0x1.ded7b522b64c3p-1 ++0x1.db41972b5b7e1p-1 ++0x1.1b0912987dcf2p-3 ++0x1.e1d26340eb5b3p-1 ++0x1.209d16e918bdfp-1 ++0x1.9d1bd742b6cd9p-1 ++0x1.d8ce209dfe849p-1 ++-0x1.d12fc215483dfp-9 ++-0x1.a4c0d4697fa72p-1 ++0x1.617954103f059p-2 ++0x1.3137f5baf9af4p-1 ++-0x1.507947ccbeeb1p-1 ++0x1.b292e4143ab7fp-1 ++0x1.d82640b61d4f4p-1 ++-0x1.5fe5b15734ccdp-16 ++0x1.f2d0e2931043bp-1 ++0x1.2fd917731a612p-22 ++0x1.f48e103407199p-2 ++0x1.7e2db343d2518p-6 ++0x1.49aec36586d2dp-1 ++-0x1.06ef250e87d2dp-9 ++-0x1.dce7e25ee3f06p-1 ++-0x1.f9667561ea716p-1 ++0x1.ef305027835abp-1 ++0x1.fda044b85c0c4p-1 ++0x1.e184b71badf21p-1 ++-0x1.8f7ec3e278b93p-3 ++0x1.f09ed78d95c96p-1 ++0x1.db5114278e29ap-1 ++-0x1.a56dd3341013ep-3 ++0x1.dc3843f1a56fep-1 ++0x1.2038f78b9bcc0p-2 ++-0x1.acd041b591f89p-1 ++0x1.e739901525d14p-1 ++0x1.e6ab002c0fd58p-1 ++0x1.ea88c7564fe3cp-1 ++0x1.fc9c210385ec5p-1 ++0x1.300c178b2707bp-2 ++0x1.64adc3a6fd19ap-1 ++-0x1.fd26d46627291p-1 ++-0x1.50b1823ecd041p-1 ++-0x1.0460742bc8cdbp-1 ++0x1.ee1d52dfb4db7p-1 ++-0x1.f8df26ac867ecp-1 ++-0x1.101697bd3de35p-3 ++-0x1.f08df75686ba5p-1 ++-0x1.ace67097f9affp-2 ++0x1.e8d044bdd2df4p-1 ++0x1.f567c745b44b1p-1 ++-0x1.293da15462edcp-3 ++-0x1.ff6a619be98e6p-1 ++0x1.870715d5a6b13p-3 ++-0x1.0c6132d48b23ap-1 ++0x1.bfcac730c5b46p-20 ++-0x1.eede64d01dd85p-1 ++0x1.4a0014931f1a7p-1 ++0x1.c04bc2fc8d9a7p-1 ++0x1.2ab9e2f378d0ap-3 ++0x1.5fd3677becabcp-2 ++-0x1.28cef33a72793p-1 ++-0x1.b17535ce5f5e3p-1 ++0x1.126fb704975d2p-2 ++0x1.f5e136218d473p-1 ++0x1.922b42c5e0ed7p-19 ++0x1.ace8606018cd4p-1 ++0x1.2b74811bfc23dp-2 ++-0x1.ef2a370ffe51ep-1 ++0x1.f9f6a148adee0p-1 ++0x1.f4021476db864p-1 ++0x1.95f375fe34bb5p-23 ++0x1.eca2876cca9d0p-1 ++0x1.d7351318c57d6p-20 ++-0x1.c5b4f73fa50c8p-25 ++-0x1.c94d46e4a466ap-1 ++0x1.901222b3eb03fp-1 ++-0x1.f2f094f1075f9p-1 ++-0x1.f86a7137c57dcp-1 ++-0x1.8e3c37a819136p-3 ++0x1.4ec1702690f49p-1 ++0x1.7af330368dd58p-11 ++0x1.84a1865b3e5f0p-1 ++-0x1.e4e0305c7b1bbp-1 ++0x1.ff49a7d7f6d62p-3 ++0x1.f2bad6b8e3ad9p-1 ++0x1.ff22f34c30d58p-1 ++0x1.eff9a7f819fecp-1 ++0x1.c32c91193429cp-13 ++0x1.5d40255ad5479p-2 ++-0x1.841801a2f578cp-1 ++-0x1.dbd584ff2c565p-1 ++0x1.a291c450afde5p-1 ++0x1.eae6f79c5a22bp-1 ++0x1.e6a5815c8e911p-1 ++0x1.effbb6d1ea58dp-1 ++-0x1.7b2d0222d18edp-1 ++-0x1.629942502fa18p-2 ++0x1.4d83c5fd055fap-1 ++0x1.878e4270d439cp-1 ++0x1.e9d9730db6039p-1 ++-0x1.1e06e6cea4258p-2 ++0x1.f65ff39e90426p-1 ++-0x1.cdb98479835c6p-9 ++0x1.d768f6851ecbcp-1 ++0x1.f69e2232d6a42p-1 ++0x1.ec53932232948p-1 ++0x1.f67aa7a0b8826p-1 ++-0x1.fabca4ba5ef23p-1 ++0x1.ee69c2e52baf8p-1 ++0x1.26f0054eb2e0ep-2 ++0x1.0713f52f5375ep-2 ++-0x1.cbe100e36ed62p-1 ++-0x1.40a8260114e62p-1 ++0x1.f3063795bb159p-1 ++0x1.c716b64d97f72p-1 ++0x1.8981a41813d96p-3 ++0x1.d7c1209925c7ap-1 ++-0x1.ff581104611a1p-1 ++0x1.0c85d2b6d6e9dp-1 ++-0x1.8e8714dc38c74p-20 ++-0x1.b03cb5319aa16p-1 ++0x1.d72834d33b477p-1 ++-0x1.f01b11376becdp-1 ++-0x1.415a16a005c76p-20 ++-0x1.fe90e5f9be415p-1 ++0x1.dde612d789020p-1 ++0x1.d9f3738b76c1fp-1 ++0x1.db5327bba31b5p-1 ++0x1.adc4400d2246cp-22 ++-0x1.ff88333427dbap-1 ++0x1.eb26276420df2p-1 ++-0x1.b6c7247c84ca1p-2 ++0x1.e02a848a05a70p-1 ++0x1.043b03cb8172fp-3 ++-0x1.33d676f26127ep-3 ++-0x1.7608255d04435p-3 ++0x1.04f80268e9ce1p-1 ++0x1.464bc0a199508p-1 ++0x1.29ef60c6d1649p-2 ++0x1.ee97e455401a2p-1 ++-0x1.fd9ed1b43f715p-1 ++0x1.eb715394fd91dp-1 ++0x1.d7233283a8bd9p-3 ++-0x1.1df410fa478c5p-1 ++0x1.d594f6ab26103p-3 ++0x1.a08f83fd80dc8p-1 ++-0x1.de90b76d413e4p-3 ++-0x1.6084126e687f0p-8 ++-0x1.ff9375ff924dap-1 ++0x1.eaef2277ad27bp-1 ++-0x1.567a6656d28acp-1 ++0x1.db239524e4064p-1 ++0x1.ea15917f3ccbdp-1 ++-0x1.aecd11f1ad305p-1 ++-0x1.3f3391d575ab0p-1 ++0x1.2065b112d45b7p-1 ++0x1.eefeb58f716edp-1 ++-0x1.752456499480ap-2 ++0x1.f628431ac8afbp-1 ++-0x1.d4f5807797fcdp-3 ++0x1.52b317a0f2bb4p-2 ++-0x1.36be46b7fbb08p-2 ++0x1.e57282515307ap-1 ++0x1.8cb3963d2de1dp-1 ++0x1.f86d8777ff85dp-1 ++0x1.dbec93d39559cp-1 ++0x1.ef15079437d86p-1 ++0x1.9912915e0e9d2p-1 ++0x1.eddfa64b338bcp-1 ++-0x1.05d235555bca1p-1 ++-0x1.fb398088adb40p-1 ++-0x1.8529e4f0cd31ap-6 ++-0x1.daf8854d3e5e7p-1 ++0x1.562e8760fd24dp-1 ++-0x1.2bb627405320cp-3 ++-0x1.dbbe424b49782p-1 ++0x1.db7c6724b9b5cp-1 ++-0x1.86c5e771c6e89p-1 ++0x1.eb6cc05b2299fp-1 ++0x1.cbdfe416b513ap-16 ++0x1.e80bd7a912478p-1 ++0x1.e20654791ee42p-1 ++0x1.e7c99604f72c5p-13 ++0x1.e384454b782e3p-1 ++-0x1.2f821736b5783p-1 ++0x1.ec2dc7a3f7b9ap-1 ++-0x1.f58cb69431ff8p-1 ++0x1.291eb281d5031p-2 ++-0x1.22d8d0d689c58p-2 ++0x1.edae94523b924p-1 ++-0x1.dc31f75dbd8bap-1 ++-0x1.f41750df779c1p-1 ++0x1.1dbe97dccb13ap-24 ++0x1.fb352364b9b84p-1 ++-0x1.2f5617c2cdd47p-1 ++0x1.69d035f7a7ee7p-8 ++0x1.72e2e6f704395p-8 ++0x1.f86e40ec67bd7p-1 ++-0x1.d74544791ed55p-3 ++0x1.ee79c2eaca96bp-1 ++-0x1.97f484b97f423p-1 ++0x1.ecca71ea821fbp-1 ++0x1.cb2254385c652p-1 ++-0x1.e83561b46f5e8p-1 ++0x1.bd9f3198d30dep-25 ++0x1.e9e7b30a7666fp-1 ++0x1.b768a1d09af67p-3 ++0x1.0345e3f133efep-2 ++0x1.b45fb3fc48819p-1 ++0x1.426bd7fd10932p-1 ++-0x1.57e6c01243fa0p-1 ++0x1.1f4821c5d7096p-1 ++-0x1.de19b73619e5dp-1 ++0x1.53cb05c92ecbfp-1 ++0x1.90754146fad63p-1 ++0x1.4973979c27e9cp-2 ++0x1.ae33e7c0fbf30p-4 ++0x1.e032e42a2040ep-1 ++-0x1.ea40a3cab079fp-1 ++-0x1.6907e6c0916a9p-1 ++-0x1.1c59c6555ce1ep-3 ++-0x1.12fce6ee5e120p-3 ++0x1.747724780a0a7p-1 ++-0x1.3c6f734ef61e6p-1 ++0x1.dcd584c6d27cbp-1 ++-0x1.c27d81c83efabp-1 ++0x1.d990c3dac50c1p-20 ++0x1.a3c463d5b6e67p-1 ++-0x1.0820a1102e865p-1 ++-0x1.ab2a1549ea8ebp-3 ++0x1.dcde36cbc878bp-1 ++-0x1.42374083a3e0fp-4 ++0x1.ef0c857a36fa3p-1 ++0x1.e9e3a68ecccb7p-1 ++0x1.7f05d2127fea2p-1 ++0x1.e87935312ca1ap-1 ++-0x1.eb7110ff0f66ap-1 ++-0x1.c15fb366cfcf9p-1 ++0x1.f08de63d6483ep-1 ++-0x1.c72931d050543p-6 ++0x1.1cb62361bff83p-2 ++0x1.22db1186e6583p-10 ++0x1.e862d28475fb9p-1 ++-0x1.727515872cde2p-25 ++0x1.1a80e5cb79b32p-14 ++-0x1.c48fc05bc06adp-1 ++0x1.ef6a04b724d4ap-1 ++-0x1.70ba1780348d9p-1 ++0x1.e68fd1d34efdcp-1 ++-0x1.edbeb6d147be3p-1 ++-0x1.ffb8054bd5bb2p-1 ++-0x1.205784cd6e44ap-1 ++0x1.b9eea1cf61152p-8 ++0x1.ead9f4facbad9p-1 ++0x1.41f1177f3aa4dp-3 ++0x1.1cb3c7898c6c5p-21 ++0x1.3b9562043baf3p-2 ++0x1.9a03f093bbf71p-1 ++0x1.22d245b843dc6p-1 ++0x1.fe6b7655a7c27p-1 ++-0x1.f53d46b53474cp-1 ++0x1.edc8174da0475p-1 ++0x1.453ef06515377p-1 ++-0x1.cf39e3a140966p-3 ++0x1.b3870738c9a7fp-1 ++0x1.c03ff7b9aa3ccp-1 ++0x1.d88de462de411p-1 ++0x1.907531b1ec30bp-1 ++0x1.e807c59e08986p-1 ++0x1.d01ee7e80196dp-1 ++0x1.eb29729cac7d4p-1 ++-0x1.9b6ff25e8b37bp-1 ++0x1.06cb55e19f50bp-1 ++-0x1.c969c47d61594p-2 ++0x1.2f8fd229e5a28p-1 ++0x1.ec5d65428be39p-1 ++0x1.e3f1f13dd3842p-1 ++-0x1.6fdf45f0448e4p-1 ++0x1.c693d3e0c3d93p-1 ++0x1.ec2b351c3d553p-1 ++-0x1.023bb65902175p-2 ++-0x1.e41b13bb1ae98p-1 ++0x1.ed5233df8f1b0p-1 ++0x1.d3745523a5b72p-3 ++0x1.b11183467f9f4p-1 ++0x1.f96977e343f28p-1 ++0x1.647e07d72c3ccp-1 ++-0x1.dd7b40d163147p-1 ++0x1.a955c3158f95ap-3 ++0x1.ddbbe2e244b52p-1 ++-0x1.dd9476201ab1ep-1 ++-0x1.c173b1455120cp-10 ++-0x1.4849770c21219p-1 ++-0x1.e9c224c0132f3p-1 ++-0x1.9c7115f5fa7edp-23 ++-0x1.ededb18a270f5p-1 ++-0x1.dc41f5d54e145p-1 ++0x1.f260631aa28c5p-1 ++0x1.dd80538515b09p-1 ++0x1.e45ea178c9b30p-1 ++0x1.d98ee1fe8fa72p-1 ++0x1.ec3b7502ba31bp-1 ++0x1.9202f7b61b23cp-1 ++-0x1.e90160c48172dp-1 ++0x1.029cb182129c5p-1 ++-0x1.ecf921278c665p-1 ++0x1.f1df6352de955p-19 ++0x1.e820a1d008c40p-1 ++0x1.cf1bc071e7b1dp-13 ++-0x1.a7f9c47f84b4bp-11 ++-0x1.91d2b301a130ep-6 ++0x1.eb7e233b26b9cp-1 ++0x1.5285126c10af6p-11 ++-0x1.413ff2f91c7e0p-1 ++-0x1.909622a8afce0p-9 ++0x1.91f83092eaa5bp-1 ++0x1.e9f0072632510p-1 ++-0x1.4291a2d3c6a6ep-1 ++-0x1.91a7814a1afe7p-2 ++-0x1.f2e5c1ddfca4dp-1 ++0x1.4ed7f0ccb3beap-1 ++-0x1.56758387f3eb7p-1 ++0x1.0817c57f66fd7p-1 ++0x1.92ba54b90cb1fp-1 ++0x1.8393d0a315e11p-1 ++-0x1.ebf5435363845p-1 ++-0x1.182971e71f1c4p-25 ++0x1.30bad35036ebep-1 ++0x1.e6a7c48aae965p-1 ++0x1.5c09f0643688cp-1 ++0x1.bdb701415b22ap-1 ++-0x1.80b045165e5bep-1 ++0x1.ec2a609f9c95bp-1 ++0x1.fdf1358d71fa7p-1 ++0x1.f38ae51ef650dp-1 ++0x1.c3b5220ba05abp-2 ++0x1.64e7b7d518cdap-16 ++0x1.e3172710f85acp-1 ++0x1.c3d957db61cd0p-16 ++-0x1.76789202c62c6p-10 ++0x1.b9314508fdd23p-1 ++0x1.fbc7e244da846p-1 ++-0x1.feea04702b990p-1 ++0x1.c77664b2ebec3p-1 ++0x1.eb18f40a3c0a1p-1 ++0x1.f3d57719d5a66p-1 ++0x1.a1b9e5f02c25fp-1 ++0x1.d9db75669d2e1p-1 ++0x1.85d832f631a51p-2 ++0x1.9485a38e25cb3p-1 ++-0x1.1afd8636d88a6p-4 ++0x1.05798672f5ea3p-2 ++0x1.ffe9232e1641fp-1 ++0x1.f578d77058051p-1 ++0x1.32f086b72fc47p-3 ++-0x1.f80cc6c503e0bp-1 ++0x1.f28b64ae14d36p-1 ++0x1.db3f10c932ea3p-1 ++-0x1.fcdff69481c76p-1 ++0x1.b0b1822e2d791p-1 ++0x1.e47cf5ea94794p-1 ++-0x1.edbb01a598c24p-1 ++-0x1.f2d2c4f587093p-1 ++0x1.d810f191b7661p-1 ++0x1.f93393613674ap-1 ++0x1.be82e4ac9bddbp-1 ++-0x1.0579e7d148859p-8 ++-0x1.c7f3c1fdcabf4p-3 ++0x1.efad546ed467cp-1 ++0x1.fd6a251b4821ep-1 ++0x1.0315f5c097414p-3 ++-0x1.7db404e004dd9p-1 ++-0x1.fdabb5f507142p-1 ++0x1.c64fd560d1b67p-2 ++0x1.ca0d01c21706dp-1 ++0x1.e45216887ff71p-1 ++0x1.df2ec764ef6adp-1 ++-0x1.8e65606bed199p-3 ++0x1.dbc053fc0855cp-1 ++0x1.6b8ba297a525cp-1 ++-0x1.00882585a29eep-1 ++0x1.d353f591637b8p-1 ++-0x1.79f546d33544bp-3 ++0x1.efa4e409fde87p-1 ++0x1.ee1163afd0a03p-1 ++-0x1.fad96389524bfp-1 ++0x1.e85bb560bc75dp-1 ++-0x1.f069332e76f6dp-1 ++-0x1.6fb4348faf5c4p-3 ++-0x1.ce9367ceb44dap-9 ++-0x1.f0a930040729ap-1 ++-0x1.505075bc12d92p-16 ++0x1.947d6278f2ca8p-1 ++-0x1.f086970443d28p-1 ++0x1.d025216b99be2p-5 ++0x1.dcfa56e705532p-1 ++-0x1.f30504c59eceep-1 ++0x1.dd52d7e19870ap-1 ++0x1.02ddf0359bf9fp-1 ++-0x1.4f4065a22973ap-23 ++0x1.f40f75a7770a1p-1 ++0x1.59ae8671b31e8p-26 ++-0x1.536450991d17cp-2 ++-0x1.ae0193af9d6a2p-3 ++-0x1.27ba2598fa425p-1 ++-0x1.77f897e89fff8p-5 ++0x1.eff8918d7a81cp-1 ++0x1.e8f05228d4ca1p-1 ++-0x1.7c509777a588ep-1 ++0x1.2176d0b801649p-3 ++-0x1.e69f374a699d8p-1 ++-0x1.bed374f104cadp-3 ++0x1.f3a922a74a827p-1 ++0x1.762275548f202p-1 ++-0x1.f566226c407c7p-1 ++0x1.4cdae1fead7dbp-1 ++-0x1.eb4487592a9adp-1 ++0x1.edeeb5688f291p-1 ++0x1.e99891b04ddafp-1 ++0x1.f86cf3b9e83a7p-1 ++0x1.c3f7a686c78b0p-2 ++-0x1.6150a09268c74p-1 ++-0x1.dcee02e875157p-1 ++0x1.eb1bf69818892p-1 ++-0x1.e5a480f554f3dp-16 ++0x1.84afb5f1ed3adp-1 ++-0x1.df31c5eae509fp-3 ++0x1.ff99528e27db8p-1 ++-0x1.e1a5a6243d05dp-3 ++-0x1.85fce11104791p-21 ++-0x1.fb51005dfdc02p-1 ++0x1.dcb463175cfcep-2 ++0x1.82519454bb349p-1 ++-0x1.fdcdf349a6f25p-1 ++0x1.602547dc6ecefp-24 ++0x1.bec560986a04ap-1 ++0x1.2011857db1424p-26 ++0x1.e1eec570b4a79p-1 ++-0x1.e77cb3d6aba48p-1 ++-0x1.8836556db32e5p-11 ++-0x1.e73505baf1ce0p-1 ++-0x1.e9d165420d859p-1 ++-0x1.ea73d35821c98p-1 ++-0x1.fc7083dcfce44p-1 ++0x1.4eaa72b0ad80bp-3 ++0x1.ee9b055b272f4p-1 ++-0x1.fc77850c869d8p-1 ++0x1.df2253bc59523p-23 ++0x1.ea0197e40cc09p-1 ++-0x1.e12937d9b5de6p-1 ++0x1.b78007f752b47p-1 ++-0x1.caf0a20a2e374p-3 ++0x1.403b25eaecdebp-3 ++-0x1.f09981083beb5p-1 ++0x1.1dfac77800264p-1 ++-0x1.f968b772c835fp-1 ++0x1.4183f2511d03ep-1 ++0x1.14fe334ed4841p-13 ++-0x1.ef68700ccd1ddp-1 ++0x1.495424a43a336p-1 ++0x1.f9f556f848f73p-1 ++0x1.e700764aa6a73p-1 ++0x1.c65e964229e7ap-1 ++-0x1.e91f7469d5670p-1 ++0x1.8d72537de0726p-1 ++0x1.d77df54bf42f3p-3 ++-0x1.e3f4e3f7cff28p-1 ++-0x1.980ec5ab0c67bp-1 ++0x1.82b481c2cab01p-1 ++0x1.e92fc79dc3af8p-1 ++-0x1.84edb030c6673p-1 ++0x1.134ed3adb9b89p-1 ++-0x1.5b0384147576ap-1 ++0x1.ec38f12ad09b0p-1 ++-0x1.9d3d5705b61bfp-1 ++0x1.e9a5111dca87fp-1 ++0x1.5ec077d61d074p-1 ++-0x1.8bb177f1b45d0p-1 ++0x1.026085634ea4fp-1 ++0x1.5dece01fa73aap-1 ++-0x1.f282f0325a811p-1 ++0x1.4e17a4a822867p-2 ++0x1.b710142936fc4p-1 ++-0x1.ea74f086de3c2p-1 ++-0x1.b5bb322363d88p-1 ++0x1.e01382ce9664ap-1 ++0x1.ec9d46fe101abp-1 ++0x1.e080f6a0dd5a1p-17 ++-0x1.dc4d67b50cadcp-1 ++0x1.bb0924c1b5c65p-1 ++-0x1.e4d98477aac5ep-4 ++0x1.ed52a73ea36ddp-1 ++0x1.d20927aa97a9bp-3 ++0x1.b1865059b9e39p-1 ++-0x1.b0caf4d4e58fap-22 ++0x1.f1a1076fec8e1p-13 ++0x1.6c6f93492c70fp-3 ++0x1.adf6648fd1042p-1 ++0x1.eff466a400727p-1 ++0x1.8e77870756612p-4 ++0x1.e4c511850f25dp-1 ++0x1.cced71fd52d9ap-1 ++0x1.ebb466b23c3bep-2 ++0x1.6669639648fa3p-1 ++0x1.7302146a6f168p-8 ++0x1.350056b6cb901p-2 ++-0x1.eede45da2f03ap-2 ++0x1.ac0623cd70a73p-1 ++0x1.87b2d4dcffaf9p-1 ++0x1.edaf06121f8e1p-1 ++0x1.e825a4e96f86cp-1 ++0x1.168a051460dc0p-1 ++0x1.eaa75704957d3p-1 ++-0x1.e142463188648p-1 ++0x1.d81356fe7e9b0p-1 ++0x1.e99b85f839547p-1 ++-0x1.f1296188d7fd8p-1 ++-0x1.a3b6f7aed0ad8p-1 ++0x1.6b0c23fcd3f91p-3 ++0x1.dab904f709a95p-1 ++-0x1.841256a82781ep-1 ++0x1.d26af3ab7517ep-1 ++0x1.e325a078e329bp-1 ++0x1.8aa5a22125090p-1 ++-0x1.b0fb607111e72p-3 ++0x1.e45197e7efcdbp-1 ++0x1.d9c6b1b971945p-1 ++-0x1.5fb6e7f514f55p-16 ++0x1.fa1f54af3ad94p-1 ++0x1.e8e045abf094fp-1 ++-0x1.5b9f05ea1adb3p-3 ++0x1.eee721d6726d1p-1 ++0x1.f1df37430f58ap-1 ++0x1.e58f617f2d384p-1 ++0x1.eb68943e2deb4p-1 ++0x1.dba9c1307a5c6p-1 ++-0x1.edb676b500699p-1 ++0x1.cb6e21730fca5p-8 ++-0x1.a314d11caa5dfp-1 ++-0x1.58d865bce598fp-22 ++-0x1.9da4077805769p-1 ++0x1.bca24367daca5p-3 ++0x1.408035d6251e7p-2 ++0x1.8e30509588bc3p-1 ++0x1.dac374698d877p-1 ++0x1.dc95570330076p-1 ++0x1.ed72961c6499fp-1 ++0x1.e267d33665809p-1 ++-0x1.1fd1b6af697a5p-1 ++0x1.b199976061c55p-1 ++0x1.640c203fbc506p-1 ++0x1.e67287d997f06p-2 ++-0x1.e8092359ccf4ap-1 ++0x1.479fe3a388580p-3 ++-0x1.1c9d850480123p-1 ++0x1.f6b3e32b9007ep-1 ++0x1.ee40207bb6d7ap-1 ++-0x1.3e0fd5ef49ea8p-1 ++0x1.48352432fcd1ep-5 ++-0x1.488b1538a5682p-2 ++0x1.70fc57b129bcfp-18 ++-0x1.ee0460d9eea8dp-1 ++0x1.262c4237b3aa2p-4 ++0x1.24f1f0887a167p-1 ++0x1.bc7813a548ecbp-1 ++0x1.dd3682e648173p-1 ++0x1.1a8247328b1eep-3 ++-0x1.461fb55f0c643p-1 ++0x1.e89a03c027e50p-1 ++-0x1.6445d488fb56fp-1 ++-0x1.f30720b9f9272p-1 ++0x1.10fef55d9e170p-1 ++-0x1.7e6e516a67284p-2 ++0x1.803b652c34127p-4 ++0x1.23e746d6a07b5p-1 ++-0x1.9b0893a2dbf31p-1 ++0x1.df6b52d932cacp-1 ++0x1.eba142e0d30f9p-1 ++0x1.e207a62a59fcfp-1 ++-0x1.f59ff5ac905bep-1 ++-0x1.2252f1f145275p-1 ++0x1.e99bb7a320afdp-1 ++0x1.528a81b8c8b43p-25 ++0x1.66e7a5c93cffdp-9 ++0x1.d8a270540bc22p-1 ++-0x1.8d0303f6f1f62p-3 ++-0x1.032112989c73fp-1 ++0x1.edd9f404d15d9p-1 ++-0x1.d8e2928b59a29p-1 ++0x1.e9fbd325bdd05p-1 ++-0x1.f6c115f45ea83p-1 ++0x1.9dbc024e5215bp-1 ++0x1.ea052157d8d3dp-1 ++0x1.e97b1034a0d7cp-1 ++-0x1.3868c3fb4119cp-3 ++-0x1.6547c3be6a0acp-3 ++-0x1.f0f7210f0ebc5p-1 ++0x1.dbd1b3d836677p-1 ++-0x1.87ba7548c0c70p-1 ++0x1.f32ba685b010ap-2 ++-0x1.5707a4571ae80p-19 ++-0x1.190106b7f25c8p-3 ++0x1.b1b2b37a33650p-6 ++0x1.b7da5623c2a54p-1 ++0x1.a12f204462a9dp-1 ++-0x1.8e33904e6f50ep-3 ++0x1.bac7d494af41dp-1 ++-0x1.5bd7769cc02b9p-6 ++0x1.e2549512a7f87p-1 ++0x1.a34fb7f76f669p-1 ++-0x1.fc4f82b958521p-3 ++0x1.f03885d69275dp-1 ++0x1.93c937306bc8dp-1 ++0x1.ef66f0124ea6fp-1 ++0x1.8683e2fd856ebp-1 ++-0x1.00e2e49d1662bp-1 ++-0x1.240eb5bacc34ap-15 ++0x1.f782b34dadcd6p-1 ++0x1.685494fdc570dp-16 ++0x1.f6f324645f159p-2 ++0x1.f1fc5526b9729p-1 ++0x1.941db204468a9p-1 ++-0x1.fb8797543c4b1p-1 ++-0x1.f19ce1482169bp-1 ++-0x1.e83cf6df11013p-1 ++0x1.ec0474051022dp-1 ++0x1.9b0074ea40e80p-1 ++-0x1.b110618fb5339p-1 ++0x1.e310d4b197c1dp-1 ++0x1.3e4a143f9f023p-1 ++-0x1.c3dc834396667p-24 ++0x1.72d485fe0970ap-2 ++-0x1.4792b4bea367fp-3 ++-0x1.fb6f90001c47fp-1 ++-0x1.563f503456ca4p-6 ++0x1.f49c77ef6eec4p-1 ++-0x1.f3f604ec44843p-1 ++0x1.e5b073ba13507p-1 ++0x1.dfcd37b56a082p-1 ++-0x1.ec7c15c1bc9b7p-1 ++-0x1.f3e33346bb4dfp-1 ++-0x1.70bea3753575bp-1 ++0x1.0ad654e7bcdb2p-1 ++0x1.d84772ae3d0c8p-1 ++0x1.db9382f54f801p-1 ++-0x1.3a0d506141a45p-5 ++0x1.decef09b22fd6p-1 ++0x1.e990941dd115ap-1 ++-0x1.4ac55461df70ep-1 ++0x1.caba758c29af2p-1 ++0x1.e8b807c00d6bcp-1 ++0x1.fadb16bea03d0p-1 ++0x1.7b8f62c69b8a2p-13 ++0x1.db1814c6b7c5cp-1 ++0x1.d8a437361ed5ep-1 ++0x1.f044936247105p-1 ++-0x1.f29923dbc3facp-1 ++0x1.ede3135347315p-1 ++0x1.ecb6a131593d5p-1 ++0x1.69be27f5085c2p-2 ++0x1.d87e91b7e07b7p-1 ++0x1.3e1573b76d74cp-13 ++-0x1.7110638b16bc4p-1 ++-0x1.2b60914429455p-2 ++-0x1.45e0c3984738ap-3 ++0x1.042141ca2ed6cp-18 ++0x1.384f45b294648p-1 ++0x1.feba34573e769p-1 ++-0x1.ea047532c3043p-1 ++0x1.fbe731d9f7db8p-1 ++0x1.b7b916674f33fp-1 ++0x1.fb43d2c826ee8p-1 ++0x1.df7c8777dba5ap-1 ++0x1.ed5ea12bfef39p-1 ++-0x1.638ad761f476ap-1 ++0x1.fc4bf5179e5d6p-1 ++0x1.e3b6708ecfee8p-1 ++0x1.dbce065bbf8a3p-1 ++0x1.7ce703c2bf2a6p-1 ++-0x1.ea19b32b1c2dfp-1 ++-0x1.fa1886281c79bp-1 ++0x1.40057632df635p-3 ++0x1.be3342c4dacb3p-1 ++0x1.e20274fe208a9p-1 ++-0x1.e15a87fb65354p-1 ++0x1.f9c7e2ecd680bp-13 ++0x1.e3c93361c3a97p-1 ++0x1.f0aa055bc4ec5p-1 ++0x1.1d7f011b0caa7p-1 ++0x1.27ef5716d9743p-1 ++0x1.0109b001e0b16p-1 ++0x1.06fcb4f915884p-1 ++0x1.d912e662c11fdp-1 ++0x1.f459c0e5d6307p-1 ++0x1.33b182a9dd437p-7 ++0x1.f050a642bbd28p-1 ++0x1.67dd05510a128p-1 ++0x1.f508c0df81a84p-1 ++0x1.dc24f6d5d88e9p-1 ++-0x1.1de410116c6abp-3 ++-0x1.ce8021cd33ff0p-20 ++-0x1.df8e14d8335ccp-1 ++-0x1.d944534af1d02p-1 ++-0x1.7a7641865ee08p-1 ++0x1.0a79566e358dcp-2 ++0x1.e1ddb24870183p-1 ++0x1.0be5106302396p-1 ++0x1.e84a706f6d265p-1 ++-0x1.fb54f05a586f3p-1 ++0x1.d7f7810bbad7cp-1 ++-0x1.e911418959876p-1 ++-0x1.eef2e7388b0b8p-1 ++-0x1.096cd55dea973p-2 ++0x1.e3edc46730656p-1 ++0x1.1f999553c9965p-1 ++0x1.53bff03662b79p-1 ++0x1.cc4591ffd8c8fp-1 ++0x1.32edf494b513fp-1 ++0x1.f92963d71b0a5p-1 ++0x1.ca73a41b238a2p-1 ++0x1.a08fc5e1724bfp-1 ++0x1.3e603689d203ap-1 ++-0x1.995221a7cd650p-1 ++0x1.dee8b256137cdp-1 ++-0x1.053fb553b89f8p-1 ++-0x1.496161b184764p-1 ++0x1.eb38128f82439p-1 ++-0x1.f613a094bcd5bp-1 ++0x1.d97577265ac94p-1 ++0x1.b2613742a87f2p-1 ++-0x1.9ae634697f924p-2 ++-0x1.fc2075806621dp-1 ++0x1.e0a975f696bc8p-2 ++0x1.f6f6b7b5834b8p-1 ++-0x1.fe1f228d0b462p-1 ++0x1.f70a91841af44p-1 ++0x1.e2f9c07852f70p-1 ++0x1.7273722e70f48p-2 ++0x1.db9c019d4ecbbp-11 ++-0x1.59ab151c1482cp-1 ++-0x1.c2a3b1d7f7890p-1 ++0x1.e700830d53942p-1 ++0x1.6324a18a48715p-1 ++-0x1.f8d06493cf734p-1 ++0x1.f80b9422bce4ap-6 ++-0x1.23b475322f69dp-9 ++0x1.25489233b69fep-3 ++0x1.a305e63ca5b92p-1 ++-0x1.ff6614d7db93dp-1 ++0x1.52b3468ba247fp-19 ++0x1.f631f6454296ap-1 ++-0x1.0ccec227b1aa8p-1 ++0x1.1c0a50f58ee7ep-1 ++0x1.eb1881275a5fap-1 ++0x1.e5a3c6b686c17p-1 ++-0x1.5abd34f01cc55p-25 ++# acos multiple precision fallback. ++# Implemented in __cos32 in sysdeps/ieee754/dbl-64/sincos32.c ++## name: slow ++0x1.91744378d312fp-25 ++0x1.e31933dfcae5ep-6 ++0x1.560a94c69898dp-28 ++0x1.4ede34c4c5b9cp-39 ++-0x1.b5caf13967673p-28 ++-0x1.d242039676722p-32 +diff -urN glibc-2.17-c758a686/benchtests/asinh-inputs glibc-2.17-c758a686/benchtests/asinh-inputs +--- glibc-2.17-c758a686/benchtests/asinh-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/asinh-inputs 2015-06-20 21:22:16.295458166 -0400 +@@ -0,0 +1,303 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.408fb643484cep-11 ++0x1.f0763423f1d52p-23 ++-0x1.681573418e494p4 ++-0x1.87cc25833f74bp16 ++-0x1.ad3df5eb7db54p24 ++0x1.90f147b3d0164p829 ++-0x1.60b1066c6712ep71 ++-0x1.5997c27aac9ccp332 ++-0x1.2cb3142c669a0p15 ++-0x1.ec882168157e6p191 ++0x1.43a1d0e6eae29p109 ++-0x1.2b43c388e1857p672 ++0x1.f11c07e219bafp7 ++0x1.f5efb379e3b3fp952 ++-0x1.405cf322b684cp-13 ++-0x1.fa64c4090d337p43 ++0x1.a98724f016a93p-13 ++-0x1.5743f3604a7fbp10 ++0x1.042971d37879bp-17 ++0x1.d4cda5814c00fp-2 ++0x1.ec1e878f29cf8p97 ++-0x1.6a4cd37896c5fp-24 ++0x1.da85d34b19160p-10 ++0x1.c068c277d171fp-17 ++-0x1.b3e2d1ead4160p-1 ++-0x1.ac8a62deb27c3p521 ++-0x1.e28e32ce20a25p-1 ++-0x1.e70635022c5fdp315 ++0x1.984146d8a6c69p20 ++-0x1.67cf155405aadp747 ++-0x1.a852444a7de0ep-23 ++0x1.92e4800542f83p108 ++-0x1.564ba0e9ad540p-7 ++0x1.c36c11c290063p20 ++0x1.4723d5459434cp-26 ++-0x1.43c1535cd024bp-11 ++0x1.6d46e7252da2fp388 ++0x1.756f2685e9ca9p-26 ++-0x1.72268726f4141p22 ++0x1.558480e0da8bdp15 ++0x1.ef0970332ed6fp-3 ++0x1.2015764e98ea6p481 ++-0x1.3a0f66a229b60p871 ++-0x1.c833f28187420p-25 ++-0x1.a0ea74513cffbp778 ++-0x1.d2dde734625d1p13 ++-0x1.996507c01ea97p25 ++0x1.d36f165b63b8fp880 ++0x1.445234d59e32bp-2 ++0x1.cd74423b4c4aep15 ++-0x1.c0b6631621425p-1 ++0x1.a2e0f00779702p-25 ++-0x1.fcf5c0266c2f2p-22 ++-0x1.af38a56120728p-21 ++-0x1.9ec217ea497dap1 ++0x1.57a000ceee049p800 ++0x1.6c1b6312efacfp783 ++0x1.afb5c0c4f933ap6 ++-0x1.f9267499e3327p16 ++-0x1.9b5ba5b496ae5p10 ++0x1.3975f02686229p10 ++0x1.36b913a68fe70p901 ++0x1.8946b691ecf5ap10 ++-0x1.efbb62a588bccp24 ++0x1.f3de8628048d9p-8 ++0x1.8ec222d562aa9p25 ++-0x1.ac03e6a0d863cp22 ++-0x1.6d9d94c1e0b6fp23 ++0x1.9807337060f87p-10 ++0x1.0f8045a313158p26 ++0x1.fe8cd64528951p-16 ++-0x1.51c184460cfafp-26 ++-0x1.74b0f442763c7p20 ++-0x1.d30da53c93e10p18 ++0x1.749735f182597p15 ++0x1.253da08c9c318p144 ++-0x1.2714417156ae3p693 ++-0x1.189320570f30bp26 ++-0x1.a2e120ac12626p756 ++0x1.ce724582eabcfp-24 ++0x1.30dcf0414c561p292 ++-0x1.1a1790d8a72d1p452 ++0x1.3242254b631b3p-26 ++-0x1.b5890305f1b78p11 ++0x1.019a86d2e2300p18 ++0x1.0e9cc39a3bff8p-14 ++0x1.bc8ff7e59e82ep18 ++-0x1.235a45afa3842p25 ++0x1.0b2c87979b28cp23 ++0x1.c717951ecf869p-9 ++0x1.daff104bb08a5p25 ++-0x1.b14b119b47d4ep5 ++0x1.6e8a94f758a02p802 ++0x1.7788055510c4dp23 ++0x1.6120d7e4e5d9ep498 ++0x1.1154e15c2c284p-24 ++0x1.eb28429726661p423 ++-0x1.b9faa23669003p9 ++-0x1.a615746664b00p339 ++-0x1.835384e92d59cp56 ++0x1.1fb4b0fe36aacp-3 ++-0x1.e440c3183f046p-19 ++-0x1.1e714012cae50p22 ++-0x1.1821b0014d9cep-16 ++-0x1.5de4c1e0a1bfep-24 ++-0x1.c1e5c78840e91p25 ++0x1.f0b1d4cd82236p18 ++-0x1.450ff3ad26e5bp984 ++0x1.23438314fb10bp0 ++-0x1.82be43e413126p14 ++-0x1.5c70206fd22f7p628 ++0x1.7e213160ec541p-15 ++0x1.5487358228cedp-14 ++0x1.4a163440f7c98p4 ++0x1.ad443265c6b4ap845 ++-0x1.732c509382338p-2 ++0x1.929ba224e2240p-17 ++0x1.a026b0485c0e8p12 ++-0x1.fa4e77f1b2343p-12 ++-0x1.3a2ac1c73ae50p5 ++0x1.0c4a80d41a2f7p-20 ++-0x1.1c57b37023dcep150 ++-0x1.2c1b509030e5dp26 ++-0x1.c7cdd089827cdp-26 ++0x1.3d88b121650aap8 ++-0x1.1583f2a9d2d5dp618 ++0x1.295d65809666fp111 ++-0x1.3dc8c1a73f146p-3 ++-0x1.4dc715a6ae290p999 ++-0x1.3808360307701p464 ++-0x1.adf4158880f7bp2 ++-0x1.3913104f0eea6p-16 ++0x1.8c91558dbd886p-2 ++-0x1.d67f73ef2736ap11 ++0x1.218c0592aa7fcp95 ++0x1.4c1e32e79005dp7 ++0x1.395461c5f96a6p5 ++-0x1.a311a7fbb5afap-12 ++0x1.f07b95fd415ccp9 ++-0x1.08745233a4ce8p-13 ++0x1.38f122e7f7be0p220 ++0x1.8c9c967e8e99ap-5 ++-0x1.3353e4fc6b002p987 ++0x1.945a20aa092e2p4 ++0x1.a7a935f93958ap22 ++-0x1.946865aa1c43cp-20 ++0x1.001d955d8a436p344 ++-0x1.5146c4a1225eep-22 ++0x1.ffab14f637eaap733 ++-0x1.3d50819d9de92p-8 ++0x1.84a7b4b80f227p4 ++0x1.73af93193478dp-6 ++0x1.3ac9b75c613bdp160 ++0x1.dafd9764a705fp13 ++0x1.91bc310a7648ep243 ++-0x1.531fa4a4bac3ap713 ++0x1.95c32605e6c59p20 ++-0x1.012141d71b636p-2 ++-0x1.eb4540a49b927p20 ++0x1.9c4716594b306p-24 ++-0x1.242df1aa8bf7ep642 ++-0x1.2d1fc7cf19d2ap-27 ++0x1.161fd6fd320d5p745 ++-0x1.3aaa34f975620p811 ++0x1.9e11325b1c3c4p22 ++-0x1.a838b07a6641ap5 ++0x1.8b1a0407ae636p7 ++-0x1.eb717004808e1p469 ++-0x1.d166757807df4p-6 ++0x1.2a57014d8c24bp317 ++-0x1.5ea093bc15910p468 ++-0x1.2545b7ec8b35fp-3 ++-0x1.e47ca00d1f14ep929 ++0x1.af09542db1b29p-18 ++-0x1.8d4bc4f005536p6 ++-0x1.8d564435d4d3fp-9 ++0x1.993a6363227e2p12 ++0x1.bec162f84a16cp13 ++0x1.f0a22293c4ecbp852 ++0x1.9eb0b40303dcap843 ++-0x1.0cdae1dc93ed0p22 ++0x1.21efa25110e19p12 ++-0x1.cf1531a43c397p144 ++-0x1.a043f6a911bdep-16 ++0x1.816c4063e718ap-15 ++0x1.e23b95950e47dp-21 ++0x1.a0830483382afp2 ++-0x1.52e49239a95d4p957 ++0x1.f73a3049f9d76p16 ++-0x1.1304063a4fbe5p316 ++0x1.f5b95104bb64dp320 ++0x1.661d765a50087p13 ++0x1.7bb5671e2bfcap719 ++0x1.3e14e736580b3p-20 ++-0x1.11340035e5609p-25 ++0x1.c4d527df0d553p762 ++-0x1.731bc7cf3026ap7 ++-0x1.079c1776f403fp965 ++0x1.e6879000598aep-28 ++-0x1.d3bee1e831937p25 ++0x1.c3b5f0096df0dp24 ++0x1.667d70b10ce7ep-6 ++0x1.c780d2406b7d1p-26 ++-0x1.df8fd3fe95d12p27 ++0x1.89494217ed887p204 ++-0x1.ea94d70c825d3p764 ++-0x1.04366739a80cbp11 ++0x1.75f1269063e4dp5 ++0x1.0a46e3262c2b8p20 ++-0x1.92c337d25b414p-4 ++0x1.5c2cb3414299cp154 ++0x1.07f7c34023735p881 ++0x1.c64b8297569c4p207 ++0x1.13f4d3bbd6417p8 ++0x1.bde9c42ffd9ecp-15 ++0x1.9e07054aa7309p743 ++-0x1.dd8c11c0073a4p-16 ++-0x1.e04d9283ac8d4p20 ++-0x1.c0f2e29b30840p10 ++0x1.55a4c648ebcc2p378 ++-0x1.7b0c92c6d8687p658 ++-0x1.ed8bb5ef46109p24 ++0x1.5cc2904baa4d2p-18 ++-0x1.b688c6944fa1dp-3 ++-0x1.2330768204f78p754 ++0x1.650441a7059bdp554 ++-0x1.0d1c66b57d36bp493 ++-0x1.54e35714807acp368 ++-0x1.6165d7bebf894p776 ++0x1.7e0ba7c987b9ep7 ++0x1.d139574e3913ep168 ++-0x1.40cc4145ea64ep19 ++0x1.0db7e5339af44p-8 ++-0x1.87410240fe22cp-9 ++-0x1.d0f46605d4a27p18 ++0x1.d1e8b19cca04dp-19 ++0x1.979981827668ap-21 ++0x1.2576745f4cca6p22 ++-0x1.1f02e2c0c288dp14 ++-0x1.77bab17202acap-13 ++0x1.25c5071d2dc6ep8 ++-0x1.306185b351fdap26 ++-0x1.ad6e853661ee0p587 ++0x1.f389b34d6b10fp-13 ++0x1.08fa931bd21f5p10 ++-0x1.b65bf00b921e8p-24 ++-0x1.cbb5f173385aep82 ++0x1.a32cd47340669p2 ++-0x1.a83fd05f605e6p-25 ++0x1.8184a3fcc1ac3p942 ++0x1.61c9644526617p809 ++0x1.b12c01289b0c4p15 ++-0x1.16a4a50f1192bp-17 ++-0x1.5658b26bd2888p-9 ++-0x1.8c5563528e33bp-14 ++-0x1.fd7e32bd8a9adp-23 ++-0x1.1106a6a425747p-18 ++0x1.98109155dd7bfp21 ++0x1.dbd635362ec6bp6 ++0x1.4a1600b2e95dbp880 ++-0x1.2fd6819d3d81cp361 ++-0x1.28f5b629029b5p12 ++0x1.64c6a3d5a0867p304 ++0x1.97ae606371057p22 ++-0x1.d61a76409f8f9p-25 ++0x1.a4c67223582ffp-27 ++0x1.b569919b79b6fp214 ++0x1.1bf0416ef51a4p-28 ++-0x1.1b9502079e873p-25 ++-0x1.a94006dd19303p355 ++-0x1.78bd67abffa91p20 ++0x1.96d320a0153bap383 ++0x1.f82770adf361dp19 ++0x1.ee0725a2dbe84p-28 ++0x1.93d4c19692fbfp80 ++0x1.d69c251aa0003p-3 ++-0x1.36c310f2a5894p-26 ++-0x1.7bbce527b5784p19 ++0x1.5a90f2032fb5ap-14 ++-0x1.194fe079c05eep1002 ++0x1.2e9a406645b9bp609 ++-0x1.c566e4a419660p-14 ++0x1.f917868895288p872 ++0x1.a966a17972ca9p601 ++-0x1.6d5eb4970b882p-20 ++0x1.c1a0d0ee96f75p27 ++0x1.958fd1185d839p-24 ++-0x1.c738b5fffeeb2p4 ++0x1.91bf33cdb6804p710 ++-0x1.66e0a7e4034dbp224 ++-0x1.dd6e42f5992c4p667 ++-0x1.6e17000848200p951 ++-0x1.f625958e05264p-1 ++-0x1.63e025fbcdcacp442 ++0x1.c5fb927d2cb09p8 ++-0x1.d7e514672b2ddp987 ++0x1.0eec25d2a59ccp27 ++0x1.342f35eabf622p707 ++-0x1.6ffad140301c8p609 ++-0x1.5b10b0ca4ea9dp-21 +diff -urN glibc-2.17-c758a686/benchtests/asin-inputs glibc-2.17-c758a686/benchtests/asin-inputs +--- glibc-2.17-c758a686/benchtests/asin-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/asin-inputs 2015-06-20 21:22:16.296458135 -0400 +@@ -0,0 +1,2511 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.350fc6069df8ap-1 ++-0x1.eee2112c4876bp-1 ++-0x1.236b62ec50852p-1 ++0x1.edc5c63489e51p-1 ++-0x1.fd62800520adfp-1 ++0x1.d475f0f7403afp-1 ++0x1.e90832724b53cp-1 ++0x1.f609c0391a573p-14 ++-0x1.feea04702b990p-1 ++0x1.e8d6535b0d1c2p-1 ++-0x1.9c7115f5fa7edp-23 ++0x1.08d826c7ee854p-1 ++0x1.e8e045abf094fp-1 ++-0x1.5278029b07e33p-3 ++-0x1.ea9383079d41fp-1 ++-0x1.f4e3046089560p-1 ++-0x1.fb398088adb40p-1 ++-0x1.3e3c739c48dc4p-1 ++0x1.7817337fddb7bp-3 ++0x1.7dd391d9fc392p-3 ++0x1.41afe6440736cp-1 ++0x1.bfb881b8085a3p-1 ++-0x1.e6707556b55cdp-1 ++0x1.db3e67625fe65p-1 ++-0x1.1bbd53433ed31p-1 ++0x1.6188f44707072p-1 ++-0x1.75a356a8a9292p-5 ++-0x1.ddb0166dd02a0p-1 ++0x1.e50b5048cb701p-1 ++-0x1.f8ad822c7b0e3p-1 ++0x1.9800b2fed7f04p-1 ++0x1.b1dc245081b6cp-1 ++-0x1.f72481a2b0f3ap-1 ++0x1.597d37e0d6f70p-21 ++0x1.ef40e79b3e65ap-1 ++-0x1.5ba123fb3ff91p-1 ++0x1.45bfc165da8f7p-1 ++0x1.ccac70b0bde88p-1 ++-0x1.f41a414f7827cp-1 ++0x1.9b875417727f6p-1 ++-0x1.c62a454b8d40bp-1 ++-0x1.e0a141c4f0b16p-1 ++0x1.4264601195208p-2 ++-0x1.46119179eb783p-1 ++-0x1.dfc3024659454p-1 ++-0x1.e14ee796afcc8p-1 ++-0x1.e99e96ab82107p-1 ++0x1.e234b67ec84f9p-1 ++0x1.d53303c005425p-16 ++0x1.ed5b0764a14a2p-1 ++0x1.b5e0c3ea9c8e9p-1 ++-0x1.db7d6214c24c6p-1 ++0x1.85d832f631a51p-2 ++-0x1.0be2d5dd39df0p-2 ++-0x1.9ba4068536d4ep-1 ++0x1.e3b6708ecfee8p-1 ++0x1.f81a9367f49ecp-1 ++-0x1.e4347223f7a7bp-1 ++0x1.a8d8b60a820e6p-2 ++-0x1.ec157180be1bdp-1 ++-0x1.eb95b087e8c43p-1 ++-0x1.6bdd166779c0bp-1 ++0x1.8bb3345d66b47p-1 ++-0x1.e02f643898ecap-1 ++-0x1.ab494400a4aabp-1 ++-0x1.01f7d442b79e4p-3 ++0x1.ea5ab67fbbf14p-1 ++0x1.f603237a71369p-3 ++0x1.f4a57127c7a0cp-1 ++0x1.69a0a717bd007p-2 ++-0x1.64fb05d3406f4p-1 ++-0x1.a6a73323151a3p-1 ++-0x1.22fcf3cc1a298p-1 ++-0x1.d166868f2b02fp-3 ++0x1.350857bbe150fp-3 ++0x1.ea03400cda450p-1 ++0x1.934551bfdd4f7p-1 ++0x1.a1bf13ff7e529p-1 ++0x1.40e3e60b110dcp-1 ++0x1.ebf2d1787c1b0p-1 ++0x1.bf44e6858ccc2p-1 ++0x1.efb2212f852c5p-1 ++0x1.e4bcf61e9db8ep-1 ++-0x1.f67e4278236dbp-1 ++0x1.72e2e6f704395p-8 ++0x1.eb18e737043a5p-1 ++0x1.c11e3263f847dp-19 ++0x1.6c8dc764c7ce3p-1 ++0x1.3a30f3a82e677p-2 ++0x1.5d3554f6157efp-3 ++0x1.d7e135698a916p-16 ++-0x1.9a0b900abb552p-1 ++-0x1.db02f20dbc26bp-13 ++0x1.dbf69357aebd4p-1 ++0x1.1c15c1b6076dbp-1 ++-0x1.98e8e522e4a82p-23 ++-0x1.60da4694b88e1p-1 ++-0x1.e82085e53dbf0p-1 ++-0x1.0cce4159c974dp-1 ++-0x1.edebc49f4f3bcp-1 ++-0x1.d5d0b54aec8f3p-3 ++-0x1.b6c7247c84ca1p-2 ++0x1.566d76162c4a2p-1 ++0x1.1f8126af6a5eep-1 ++-0x1.4042c01dfeb13p-1 ++0x1.3745936ce6406p-2 ++0x1.e845447d64568p-1 ++0x1.e9e5d6a4f999ep-1 ++-0x1.881fb480c1717p-2 ++-0x1.632ec650a0086p-1 ++0x1.ea79105af3018p-1 ++-0x1.e87f8637d44ffp-1 ++0x1.2038f78b9bcc0p-2 ++0x1.888731b818bb9p-1 ++0x1.247cb5abaf830p-1 ++0x1.71d2a5d08bb38p-3 ++-0x1.30f5d4f0d5da3p-1 ++0x1.e8eee13ebc573p-1 ++0x1.35a443a6ef606p-22 ++0x1.1f4110dbc1d7cp-1 ++0x1.ab85b5da29994p-1 ++-0x1.080f952236c35p-1 ++-0x1.2b5b02e6cc1b2p-3 ++0x1.ac830678d8c8ep-4 ++0x1.0ba5029d5c201p-1 ++-0x1.2b3e149bb0426p-2 ++0x1.eaa744fd96fbap-1 ++-0x1.ebf5435363845p-1 ++-0x1.f47ea66f3af8ap-19 ++0x1.e9c7d49d082bfp-1 ++0x1.ea64823156f61p-1 ++0x1.ea9222fcef492p-1 ++-0x1.38ca90ff41214p-3 ++0x1.98b000eb73a71p-1 ++-0x1.3fb91174bf8cep-1 ++0x1.6831750c7d576p-8 ++-0x1.e6c711f8a07a2p-1 ++-0x1.e10a8025fd5c2p-1 ++0x1.df7c8777dba5ap-1 ++-0x1.6c92c2bf14b20p-11 ++0x1.c2b9937c51413p-10 ++0x1.ed9a717edd7eap-1 ++0x1.26cb23fb114cep-3 ++0x1.a1dd30e8d133ap-1 ++-0x1.596e3118407aap-1 ++-0x1.815f557e4dd72p-1 ++0x1.91d3b66fca3a2p-1 ++0x1.aee2069bb58c2p-1 ++0x1.410da160d3759p-6 ++-0x1.efd3965c7e5acp-1 ++0x1.ebcc105c3c99dp-1 ++0x1.f9c7e2ecd680bp-13 ++-0x1.0d0876f871020p-1 ++-0x1.1cb73699e8924p-1 ++-0x1.f33b17f4530b4p-1 ++-0x1.cd90d53a85604p-24 ++-0x1.e7b7065c2a56bp-1 ++0x1.4325b7a1b9323p-2 ++-0x1.3007019386da4p-5 ++-0x1.2afe01c77967ap-13 ++-0x1.dd2f071cce027p-1 ++0x1.79dbd61da7b2fp-3 ++0x1.90a0030825b71p-1 ++-0x1.3b898257384cap-1 ++-0x1.5c13731da33bap-2 ++-0x1.df2c8655fc70dp-1 ++0x1.1dbe97dccb13ap-24 ++-0x1.fad96389524bfp-1 ++0x1.ddccc6b661857p-2 ++-0x1.fb6fb5159af3ep-1 ++0x1.d94283b31661cp-1 ++-0x1.a08b373392dc9p-1 ++0x1.bb7ec42dcb619p-2 ++-0x1.f450159e992b8p-1 ++0x1.6959f4fae20f8p-24 ++0x1.36f464d433610p-1 ++-0x1.c2cc227b47f2bp-1 ++-0x1.3eb9f3e9ab4fep-1 ++0x1.655d872a08e7bp-1 ++0x1.426bd7fd10932p-1 ++-0x1.bd54d6b8bf754p-25 ++-0x1.ca48c150acb42p-1 ++0x1.fba5275cb7d91p-1 ++-0x1.de01b625f1851p-3 ++0x1.ed715043085c5p-1 ++-0x1.e4bed6f91c84bp-1 ++-0x1.0c6132d48b23ap-1 ++-0x1.8740844edfccfp-1 ++-0x1.f5ea24dfceaccp-1 ++-0x1.4e1ea0cb718b9p-10 ++-0x1.e2e3f55bb23a1p-1 ++-0x1.ef8592238558ap-1 ++0x1.ba09c237c2a98p-1 ++-0x1.1c02e1ae8e614p-3 ++-0x1.e3480667a3c1dp-1 ++0x1.e098e320da0bap-1 ++-0x1.020e63d1fb6b3p-10 ++0x1.156314d8b8b9ep-1 ++-0x1.a6d562a0b9b68p-1 ++-0x1.a556923b876e4p-1 ++-0x1.005624a6a1606p-2 ++-0x1.4515b4c2b21dap-1 ++-0x1.00882585a29eep-1 ++-0x1.4e97477367b64p-1 ++0x1.e56aa246ff0e4p-2 ++0x1.f69774c91b3a3p-1 ++-0x1.edbeb6d147be3p-1 ++-0x1.d044d435326e6p-1 ++0x1.9dd6d688e8b6ap-1 ++0x1.8832042b08d37p-1 ++-0x1.e755f3286db4ap-1 ++-0x1.7741b1eae9cc5p-1 ++-0x1.ec4f82e92c41cp-1 ++0x1.c470754b52d70p-3 ++-0x1.cdf6e43174ac0p-3 ++0x1.b54d76dc019edp-1 ++0x1.de1511c382622p-1 ++-0x1.1b6bb0f6cd48dp-1 ++0x1.f8f3a7b3d26dbp-10 ++-0x1.e8a697e00810dp-1 ++0x1.029cb182129c5p-1 ++-0x1.82fb23737c09ap-1 ++-0x1.ba3f8283bda3cp-1 ++0x1.32ef66d1351e1p-1 ++-0x1.ff0942c4470a9p-1 ++0x1.e861824f0b0c5p-1 ++0x1.0ad654e7bcdb2p-1 ++0x1.94bf67e731b1dp-21 ++-0x1.ce92262e12415p-3 ++-0x1.b11a761584f00p-1 ++-0x1.ee0375698a186p-1 ++0x1.72968114620fbp-3 ++0x1.38a8e30dd439dp-2 ++0x1.ef7a104666151p-1 ++0x1.1b8030b9ef132p-1 ++0x1.e52ab2d0668d7p-1 ++-0x1.00e2e49d1662bp-1 ++0x1.7aa0818bb671bp-23 ++-0x1.ecf921278c665p-1 ++0x1.e53b304fb4d06p-3 ++0x1.3748859f74cebp-1 ++-0x1.e96cd6cb3a5dap-1 ++-0x1.eadbe1b00f3bap-1 ++0x1.34b8b20a231ebp-1 ++-0x1.a133128a2cac6p-1 ++0x1.f0ffe198f98f8p-3 ++-0x1.a978c66c2b77ep-21 ++0x1.e0afd4eddd684p-1 ++-0x1.eb3b238d0737ap-1 ++-0x1.e514d20443604p-1 ++-0x1.9d64d47733225p-3 ++-0x1.e589d06cb88d4p-1 ++-0x1.360155ce19621p-1 ++0x1.db3d40b252ac3p-1 ++0x1.1fbe750678f55p-1 ++0x1.033e6517daa6fp-5 ++-0x1.ed55067dcc2e0p-2 ++0x1.df2253bc59523p-23 ++-0x1.879d741b2c118p-23 ++0x1.b47fc608b2e66p-1 ++0x1.d74ca166c7f3bp-1 ++0x1.f5f1256f888b1p-1 ++-0x1.e06af0ec49382p-14 ++-0x1.e97461cc47dabp-1 ++-0x1.e6fe5447590afp-1 ++-0x1.e86c3331f93a8p-1 ++-0x1.aacae317ef936p-1 ++0x1.b41644690944cp-1 ++-0x1.8209c34d990bap-1 ++0x1.712d01d18f1acp-1 ++0x1.ed0c5662218c3p-1 ++0x1.90d8e69b9ce07p-1 ++-0x1.a7b9e784d9434p-16 ++0x1.f91c375372b6fp-1 ++-0x1.bf83e21f654b3p-1 ++-0x1.e38cc36ff8c63p-1 ++-0x1.842b3414ac978p-1 ++0x1.161e221d66041p-2 ++-0x1.e9a1529dfa710p-1 ++0x1.164f53c3dbd36p-1 ++-0x1.e2a192784167ap-1 ++0x1.d2f31136d5558p-1 ++-0x1.0cad003c37274p-22 ++-0x1.e402a7e83b556p-1 ++0x1.d0ee108472a16p-1 ++-0x1.0eb530c4ce24ap-13 ++-0x1.ef29f4bd04e93p-1 ++0x1.dc65a4f6e740cp-1 ++-0x1.97d975a6ad4f1p-1 ++-0x1.b427d0ab69502p-2 ++-0x1.f84bc3e23afa0p-1 ++-0x1.eada1177b2a78p-1 ++0x1.f9f556f848f73p-1 ++0x1.5da9b1ed0a67dp-2 ++-0x1.b09c16fdb0e04p-1 ++0x1.8099017d801c4p-1 ++-0x1.86a880766a1c9p-1 ++-0x1.303886d1999d3p-2 ++-0x1.3b32d4601049dp-2 ++0x1.9af5d2ec8ebd9p-1 ++0x1.7b7961500158ap-3 ++-0x1.850fc657a7c8dp-1 ++-0x1.679055ba9585fp-2 ++-0x1.a334d05fa6dd2p-1 ++0x1.54edc38ae367fp-1 ++-0x1.149aa666c3c46p-2 ++0x1.db29728be3d13p-1 ++0x1.ef2d366fb9622p-1 ++0x1.85d2c6d29e956p-1 ++0x1.6cc7155575699p-2 ++-0x1.070fb3b78d7bap-13 ++0x1.b996c3cc0af1dp-1 ++-0x1.ecd953aeda13ap-1 ++0x1.4b4da5a783ab2p-1 ++-0x1.da0f94397e1efp-1 ++-0x1.eebfe7785b810p-1 ++0x1.bbbd81413465ap-2 ++-0x1.db37b245824d8p-2 ++0x1.b18707b322819p-6 ++-0x1.63aaf1836f8f5p-4 ++-0x1.73b5c0ef358ffp-1 ++-0x1.f3f5449170a5dp-1 ++0x1.679742e395bb2p-3 ++0x1.0f5d16ce3edabp-12 ++0x1.6868a3065fa6ap-1 ++0x1.e09861e83936cp-1 ++0x1.426c2703c1edbp-2 ++-0x1.784ef6124eac0p-10 ++0x1.f4da573b55ec2p-1 ++-0x1.1250820739879p-1 ++-0x1.926f219c2ebc7p-1 ++-0x1.b03cb5319aa16p-1 ++-0x1.432597af65dc0p-1 ++0x1.f2ef13107c805p-1 ++-0x1.debb0319481e9p-1 ++-0x1.e6c9b767c2e47p-1 ++-0x1.1cfef6b1b5391p-3 ++0x1.a3495200a739dp-1 ++0x1.bb7d031207cbcp-1 ++-0x1.a1e1472875de1p-1 ++-0x1.fef5368baa990p-1 ++-0x1.ffa8a2b9fe667p-2 ++-0x1.db17773676353p-1 ++-0x1.7744f61c58e3dp-2 ++0x1.94efe0d3de07ep-2 ++0x1.d28cd2f0b7253p-1 ++0x1.71ec10c132d7dp-1 ++0x1.eec3c508f7debp-1 ++-0x1.84c3358f28de2p-1 ++-0x1.e88bb44ebcca7p-1 ++0x1.c8dfe2e844f26p-1 ++-0x1.5764f1562f46cp-1 ++0x1.dd7fc52e06795p-1 ++0x1.ead0e0dd735c1p-2 ++-0x1.d9c472df196e8p-1 ++0x1.47397541dfafap-1 ++-0x1.efe2c7ae66583p-1 ++0x1.f39bc1d029169p-1 ++0x1.388e371209c65p-1 ++-0x1.cf7594c4759eep-19 ++0x1.93ba85eda890cp-2 ++0x1.ef7e57c04e5e5p-21 ++0x1.3a13625122b61p-1 ++0x1.f03355e0191c2p-1 ++-0x1.eaa0b7cbc4b05p-1 ++0x1.dc64653df1bc8p-1 ++-0x1.da0274b24d4e5p-1 ++0x1.1ef635c892de4p-1 ++0x1.7985928fa8ea5p-2 ++0x1.e8af54cc7a4a1p-1 ++-0x1.4ecfd3add4ca1p-1 ++0x1.edae154f725f1p-1 ++-0x1.f841c459354cfp-1 ++0x1.640c203fbc506p-1 ++0x1.e1334385061fbp-1 ++-0x1.e4af910db6fb1p-1 ++0x1.eef8e75eeff24p-1 ++0x1.52b3468ba247fp-19 ++-0x1.c3007317cdb73p-1 ++0x1.793397c5de6cfp-1 ++-0x1.56f0f40ef4f93p-5 ++0x1.7137163d0b95cp-26 ++0x1.d97632e6c0216p-1 ++-0x1.58f200ed16778p-1 ++-0x1.e333144686ce6p-1 ++0x1.ecfff5d1ed4fcp-1 ++-0x1.bbcb739c535d8p-3 ++-0x1.b83b54ffc1ce3p-1 ++-0x1.c5b4f73fa50c8p-25 ++-0x1.f0dcf6647d4a6p-17 ++-0x1.e2a0b2142f471p-1 ++-0x1.6811368ab0abbp-1 ++-0x1.dc98c564661f8p-2 ++-0x1.51a64736cca11p-1 ++0x1.a87ec3c5f01d2p-2 ++-0x1.13c43714b5577p-4 ++0x1.ecb79537e7c0bp-1 ++0x1.8ad66704aa830p-1 ++0x1.8b81a17344821p-3 ++0x1.fbea24d5ecac7p-1 ++-0x1.d5b456504afabp-1 ++-0x1.68a3377a06206p-1 ++-0x1.e52744bcbb1bfp-2 ++0x1.968042aade389p-1 ++0x1.e02467b79461bp-22 ++-0x1.effa02c2a5b57p-1 ++0x1.6148d164ff733p-3 ++0x1.a257b5f59a887p-1 ++-0x1.ecd6e096725c1p-1 ++0x1.4dcd868b1c423p-1 ++0x1.b518559ba2afep-1 ++-0x1.fd36e5f6ae177p-17 ++0x1.7ab1d7104d182p-18 ++-0x1.a0b161ecebb24p-24 ++0x1.eaef2277ad27bp-1 ++0x1.5537a12ead14fp-1 ++-0x1.a353d51793c9ep-1 ++0x1.d974c464f7ce7p-1 ++-0x1.e9d4a5abc7463p-1 ++0x1.8dfc202611058p-8 ++0x1.49c49777c6afcp-1 ++0x1.f8be91c860c1ep-1 ++-0x1.744184b2f352fp-3 ++0x1.4f7741d4eac81p-1 ++0x1.fbcca55ea9e6ap-1 ++-0x1.e859d3e460e92p-1 ++0x1.5d39a31f530ddp-3 ++-0x1.99da728aaed87p-1 ++-0x1.c773d52b04af3p-3 ++-0x1.27fc667b6fe57p-2 ++-0x1.ee4664ab8f311p-1 ++-0x1.240eb5bacc34ap-15 ++0x1.aab10790e80c0p-1 ++-0x1.1c32437314611p-1 ++-0x1.e3aae42688852p-1 ++-0x1.2b97b6959b92ap-1 ++-0x1.124df14d190d5p-22 ++0x1.d29df3ade00f8p-21 ++-0x1.e70102ffd26f4p-2 ++0x1.c9846775a72c1p-3 ++0x1.2ee67226d5529p-1 ++-0x1.d84381008f610p-1 ++0x1.fae6228180a55p-1 ++-0x1.d1cb30475aba6p-1 ++0x1.475825caac544p-3 ++0x1.e2d180d75310fp-1 ++0x1.8860226237168p-1 ++-0x1.bdb8f33f2142bp-6 ++-0x1.aecd11f1ad305p-1 ++-0x1.50e857e4f8090p-1 ++0x1.09a7b4c454c6ap-1 ++0x1.33a1b5c1f5142p-2 ++-0x1.d473c0c10260ap-1 ++-0x1.e6bcc76ef1341p-8 ++0x1.e9a025b19d4e7p-1 ++-0x1.e61c564b19c20p-1 ++0x1.b1c890371859cp-1 ++-0x1.e9de02e7fa0f7p-1 ++0x1.8eae41c2d6d3bp-1 ++-0x1.a043635f96fd5p-1 ++-0x1.18077176e1632p-24 ++0x1.7063d30f52d4dp-1 ++0x1.e82d46287af59p-1 ++0x1.e77a63eb49c28p-1 ++-0x1.2e923371f4df7p-1 ++0x1.32f392b11aa13p-2 ++0x1.cf48a104a230ap-1 ++-0x1.ffb8054bd5bb2p-1 ++0x1.d961a7444a368p-1 ++-0x1.2908136966a6ep-1 ++-0x1.e8e5f46caed20p-1 ++-0x1.cca7367cafebcp-1 ++0x1.8a7d3113e9871p-1 ++-0x1.9c20d073da00dp-1 ++0x1.685602f47ee38p-17 ++0x1.dbe65032e6aafp-1 ++0x1.e39cc443d68bep-1 ++0x1.ef75b5fbc2038p-1 ++0x1.6fd3f20dabcdep-3 ++0x1.ef2e5742cbc3bp-1 ++-0x1.a139a4f96363fp-1 ++-0x1.f936e3257b29bp-1 ++-0x1.e83e578b67404p-1 ++0x1.809f14efba3abp-1 ++0x1.ef0cc05585683p-1 ++-0x1.e0ab6532e03e6p-1 ++0x1.e825a4e96f86cp-1 ++0x1.944c53b6fcba2p-24 ++-0x1.eef7764fb6703p-1 ++0x1.dbd546810ad04p-1 ++-0x1.ed82202786af0p-1 ++-0x1.e744b298a1822p-1 ++-0x1.f66403b0db0f6p-1 ++0x1.b823a13640780p-1 ++-0x1.8fd743dba9526p-1 ++-0x1.6ad6002662fadp-2 ++0x1.af29d1ff6c1dap-2 ++0x1.a40a30c84d9d2p-1 ++-0x1.eef1466de9bbcp-1 ++-0x1.ea451649dac69p-1 ++-0x1.be12773f273cdp-10 ++-0x1.2ea1f2cfba778p-22 ++-0x1.ed2eb7554cecap-2 ++0x1.5604a6ebad5aap-3 ++-0x1.dcb4e5d23da48p-1 ++-0x1.e0e2d4e18e11fp-1 ++0x1.7cbf026e8d176p-1 ++-0x1.e92df6fb8cb14p-1 ++-0x1.e0f877f179d56p-1 ++-0x1.0460742bc8cdbp-1 ++0x1.f9c6e1a503f35p-1 ++-0x1.de3ca0ef987b7p-1 ++0x1.ee2a61e036810p-1 ++0x1.eb29729cac7d4p-1 ++-0x1.dc41f5d54e145p-1 ++-0x1.ee27548fb036dp-1 ++0x1.8676b01d07ce0p-1 ++-0x1.9eb434f5e23dfp-10 ++0x1.95688374a65cep-1 ++0x1.d8b331ab26940p-1 ++-0x1.ec5af0c2ccbc9p-1 ++0x1.bca24367daca5p-3 ++0x1.4c5f30d4e8c83p-1 ++-0x1.990c52576b03bp-1 ++0x1.279527d6f3123p-2 ++0x1.e7d10654db7cfp-1 ++0x1.afabd749d11aap-1 ++-0x1.e54870e856fc8p-1 ++-0x1.a9b6e450b1736p-3 ++-0x1.e4b0c74cbee31p-1 ++-0x1.77a9538ce58c8p-10 ++0x1.aab3b79abd652p-22 ++0x1.efdfd56aee773p-1 ++0x1.1dfac77800264p-1 ++-0x1.f5e7d3b5fa6b2p-1 ++0x1.569077a89293cp-9 ++-0x1.f086970443d28p-1 ++-0x1.1e2b763ff1c1bp-16 ++0x1.fa84d6fc1bfb4p-1 ++0x1.fbf321159facbp-1 ++-0x1.56f5410b90154p-15 ++0x1.ec2962b60792cp-1 ++0x1.82723136c1041p-1 ++0x1.66ec3602d5c0ep-2 ++0x1.6006c4b0268aap-1 ++0x1.db8e205953140p-1 ++-0x1.6f4ec45af7480p-1 ++0x1.713b02f6a04eap-26 ++-0x1.63b1454647238p-1 ++-0x1.f2d2c4f587093p-1 ++0x1.dbec93d39559cp-1 ++0x1.f59e8219eeb3dp-2 ++-0x1.973c3291c4d50p-1 ++0x1.30a10510388bap-1 ++0x1.f1f61783e79d0p-23 ++-0x1.c101b1037e3f5p-1 ++0x1.d257940a5137fp-3 ++-0x1.f470523c426b8p-1 ++0x1.0c37b2dba00aep-19 ++-0x1.ebcbb7d352b98p-1 ++-0x1.f45c0719f0ef0p-3 ++-0x1.9fa667856a81ep-1 ++-0x1.3706e59f06a0cp-1 ++0x1.e87165a85bf00p-1 ++0x1.d9f9e3d739f44p-1 ++-0x1.e26fb2a17aaa7p-1 ++0x1.0be6a11da1596p-1 ++0x1.f8d1b326b2ed1p-1 ++-0x1.ee19b06500228p-1 ++-0x1.e40de71a02d0dp-1 ++0x1.98bc15dbd69bcp-1 ++-0x1.eb16f70b61cccp-1 ++0x1.93a7216be0c5dp-2 ++-0x1.8bdbe0b9e2d2bp-10 ++0x1.ff0fa32b3accap-1 ++0x1.e7b000c9475a2p-1 ++0x1.e4c7b30bac6b0p-1 ++0x1.e82ba33a4ce9dp-1 ++0x1.db41972b5b7e1p-1 ++0x1.e2fab75688c77p-1 ++-0x1.d674412d314f7p-1 ++-0x1.a05a64a3c376cp-16 ++0x1.d57127f394c23p-1 ++-0x1.8bb3428cca392p-1 ++0x1.66540667f4775p-3 ++0x1.df8192132032ep-1 ++0x1.16be46faa5fd0p-1 ++-0x1.8f5d4684f487ap-1 ++-0x1.515e3214390b1p-2 ++-0x1.e9c224c0132f3p-1 ++-0x1.4792b4bea367fp-3 ++0x1.f683c622269b9p-1 ++-0x1.fd61a56639941p-1 ++-0x1.edb8f5b456c1ep-1 ++-0x1.1227a7cbdc567p-1 ++-0x1.daf8854d3e5e7p-1 ++0x1.aee25650abb06p-1 ++-0x1.513f8376de706p-1 ++-0x1.a96f12a5be2cdp-1 ++0x1.ec7da7eb5220ep-1 ++0x1.a010e6eeba432p-1 ++-0x1.e73721ebf9720p-1 ++0x1.d827e42f715f6p-1 ++0x1.53cad6d41476cp-2 ++-0x1.5921d3708a0c3p-1 ++-0x1.c05b22303587cp-1 ++-0x1.97f484b97f423p-1 ++-0x1.2b4492bd73b64p-15 ++-0x1.eb0e768cad7c1p-1 ++-0x1.fe0c97242979ap-1 ++-0x1.ec354776dd3bbp-1 ++0x1.cf0d270e371f6p-1 ++0x1.66e7a5c93cffdp-9 ++0x1.fd0d826c5a1d9p-1 ++0x1.afbca363725d1p-1 ++-0x1.d77251ee3df8ap-1 ++0x1.1692a2cdd5549p-3 ++0x1.6e88143883032p-1 ++-0x1.f41ec1c712c7fp-1 ++-0x1.a6386135c889ap-1 ++0x1.de45269a5dce2p-1 ++0x1.c6a6b4f8f837ep-24 ++0x1.33d06466c6b9bp-1 ++-0x1.860fd51abe700p-1 ++0x1.fbd696b6938a5p-3 ++-0x1.e83e45de922aep-1 ++0x1.ec4e74a3a5175p-1 ++-0x1.7a9f95d8c3a13p-1 ++0x1.3cd2b0e0024b4p-2 ++0x1.c5b6f70209b78p-5 ++0x1.e5b073ba13507p-1 ++0x1.c5914768121eap-1 ++0x1.9e87f2c6f8986p-1 ++-0x1.835ef3aca7e57p-1 ++-0x1.dc7de37754abap-1 ++-0x1.8635367864672p-1 ++0x1.d6fcd19613123p-1 ++0x1.713322dda040ap-26 ++0x1.b301916b3e546p-1 ++-0x1.5907373541318p-1 ++0x1.b67804eb47f52p-1 ++-0x1.01d6c56bc4577p-1 ++-0x1.268026d7131f6p-1 ++-0x1.8a2f305b13ed1p-2 ++-0x1.b110618fb5339p-1 ++0x1.1e2ec7a7b3ffbp-1 ++-0x1.eeac0378d3c2dp-1 ++-0x1.a8d514f3e4860p-18 ++-0x1.3c73f2a282f70p-1 ++0x1.4b69664a697c8p-1 ++-0x1.5ac3218682dafp-9 ++0x1.d9d2a5d6d0097p-1 ++0x1.ea88c7564fe3cp-1 ++-0x1.01b182a357b89p-1 ++0x1.ef3d33758c65cp-1 ++0x1.755957a759d6bp-1 ++0x1.dc5b74cf50867p-1 ++-0x1.173f6772617c0p-21 ++0x1.edbf80f8c492cp-1 ++0x1.d53f03f943012p-1 ++0x1.8a3cb07f33bafp-3 ++0x1.03af809e77795p-2 ++-0x1.eaeaa63245741p-1 ++-0x1.f97c70509940cp-2 ++0x1.da0741692c059p-1 ++0x1.ade411f3da571p-1 ++-0x1.b2a12164a95c7p-3 ++-0x1.8fa041d702f22p-3 ++-0x1.97f1b066c701bp-3 ++0x1.b707763754484p-3 ++0x1.e499e4e2ad8e9p-1 ++0x1.311253501f3f2p-3 ++0x1.259d37e26150cp-1 ++-0x1.dfb6e365f91ecp-1 ++-0x1.aa22065b8f2c3p-1 ++-0x1.da1ff0b273cd7p-3 ++0x1.be2cb0d8c5b44p-1 ++-0x1.3439a53555121p-2 ++-0x1.e210555e48210p-1 ++-0x1.d85926848cf29p-1 ++-0x1.e9a0822672116p-1 ++-0x1.aa5ad517117bep-2 ++-0x1.8f0b53139648dp-20 ++-0x1.f86a7137c57dcp-1 ++0x1.bb51b4278652ep-3 ++0x1.0e4d9562788afp-1 ++0x1.7ce703c2bf2a6p-1 ++-0x1.059cc53835908p-10 ++0x1.89b894e0e9e37p-1 ++0x1.9d6604d4efeddp-2 ++0x1.aa6bf1e6b5ff3p-1 ++0x1.d053b71612732p-1 ++0x1.c58290a57b35bp-2 ++-0x1.e79c23c2f87cbp-1 ++-0x1.ef28737769e8cp-1 ++0x1.e1bf0284f90b9p-15 ++0x1.b8c1328d43f30p-1 ++0x1.ff61460c87dbbp-1 ++-0x1.ea06f3c18052fp-1 ++-0x1.929a25bc4e316p-1 ++-0x1.462ed634d347cp-2 ++-0x1.f89887250e6fcp-1 ++-0x1.bc99a3c89c1e3p-22 ++0x1.5c75e768472b4p-2 ++0x1.8f6fa012e2770p-1 ++0x1.f7af22a6b572dp-1 ++-0x1.3f54f252e3acdp-2 ++-0x1.ed3fa609dbee7p-1 ++0x1.dfbca7880638fp-1 ++0x1.3e1116e4de263p-1 ++0x1.dc6a025cdf557p-1 ++-0x1.8bfbe75d98041p-1 ++0x1.e9e2b495fa2c1p-1 ++-0x1.2642422821515p-1 ++0x1.edfca7dddb0f9p-1 ++-0x1.ee8ea3f68169fp-1 ++0x1.ad17b2686c65fp-1 ++-0x1.c4f6f0a35fd4cp-1 ++-0x1.ef6f43ea3e075p-1 ++0x1.4f28f1201b762p-3 ++-0x1.ef68700ccd1ddp-1 ++-0x1.d63ec71b1db72p-1 ++0x1.eece451c9800bp-1 ++-0x1.e374023473851p-1 ++-0x1.dae080dc56bf7p-1 ++-0x1.f41933cd4db1ep-1 ++0x1.8df8a16525f39p-3 ++0x1.f5c64629537c0p-3 ++-0x1.74e212eb04e5ap-1 ++-0x1.c78c50a1f0152p-1 ++0x1.ec1a10580c98bp-1 ++0x1.aadfa2e96b6e0p-3 ++0x1.9c1383ae4954fp-1 ++0x1.dfb2223aa208cp-1 ++-0x1.cfffa4412b604p-3 ++0x1.cee130d0b5a2bp-3 ++-0x1.e307d799961afp-1 ++0x1.fe1874b71dffap-1 ++-0x1.f0dd20e110586p-1 ++-0x1.e6f124bc80f9bp-3 ++0x1.a84f50096564fp-1 ++-0x1.eb54d7123b641p-1 ++0x1.dde4d0a43d6ccp-1 ++0x1.460c714b7fc02p-1 ++-0x1.eb14401a251dfp-1 ++-0x1.6d6c5532e2cd9p-21 ++-0x1.b0c634676faacp-4 ++-0x1.ab062115542b8p-2 ++-0x1.12c3e674c7017p-3 ++0x1.f2f2a467a4711p-1 ++-0x1.b410a265bf2edp-1 ++-0x1.e142463188648p-1 ++-0x1.1e06e6cea4258p-2 ++0x1.60e380d477367p-2 ++0x1.ecabd7e786fccp-1 ++-0x1.ea047532c3043p-1 ++-0x1.e64087ec5398bp-1 ++-0x1.8192b282dc78ap-3 ++0x1.bc3be459c0118p-2 ++0x1.e848464011e2bp-1 ++-0x1.1635a3dbd5aaep-3 ++-0x1.f027619f4ec1cp-1 ++-0x1.cc5b228bab092p-2 ++-0x1.54c7045181291p-1 ++-0x1.d878651499cdcp-1 ++-0x1.2c92931e89713p-1 ++0x1.eea2d2cca4e34p-1 ++0x1.5cb4743cbb81ep-13 ++0x1.4e17a4a822867p-2 ++-0x1.dbb357be5deebp-1 ++0x1.e59516797b352p-1 ++0x1.db51b6a627095p-1 ++-0x1.60c746f7d0703p-1 ++-0x1.ea37c48f25f9dp-1 ++-0x1.7ac0566338086p-2 ++-0x1.baf382671db8ap-1 ++-0x1.27b5065556c47p-1 ++0x1.dc8714f787413p-1 ++-0x1.51c9858d1404ap-1 ++-0x1.72de44d96ac46p-26 ++0x1.f425e3cced4c7p-3 ++-0x1.687a92d61065ap-16 ++0x1.f524140aa4f9fp-1 ++-0x1.e23a916eb0f6cp-13 ++-0x1.d99af531c1d7dp-1 ++0x1.33fc239565e36p-15 ++-0x1.77fe57818f84dp-8 ++0x1.e2f6076e57cc4p-1 ++-0x1.e97d25cf4a4c9p-1 ++-0x1.ced6825d25e04p-1 ++-0x1.e6a1f419a0176p-1 ++0x1.a8ad7301a9c3bp-20 ++-0x1.c6256777394b3p-1 ++-0x1.15deb4ca612fep-2 ++-0x1.1fd1b6af697a5p-1 ++-0x1.e9ad92c7a5f42p-1 ++-0x1.ee43843342288p-1 ++-0x1.3c312578414bdp-3 ++0x1.ec27f19113a4dp-1 ++-0x1.9ccbd7e827a55p-3 ++0x1.efe3727b0e23ap-1 ++-0x1.acfd7757af602p-1 ++-0x1.841256a82781ep-1 ++-0x1.dea3e5358e22ep-1 ++0x1.7a5d14b31d63cp-1 ++0x1.b45264dd5b6ccp-1 ++0x1.a955c3158f95ap-3 ++0x1.5a2a14a8001cap-1 ++0x1.d80407959de45p-1 ++-0x1.e63ba4f3d8c3ep-1 ++0x1.83edf16dfff50p-1 ++0x1.b747536ef6e0ap-2 ++-0x1.db91b03d5de78p-1 ++-0x1.04e9366e2d6bdp-1 ++0x1.868a14adc5d9ap-2 ++0x1.e004440ae8f05p-1 ++0x1.b892e7a52e191p-1 ++-0x1.a31672a711e3bp-3 ++0x1.f1a246788caa4p-1 ++0x1.2712839082804p-1 ++-0x1.e15a87fb65354p-1 ++0x1.c8b2f2a807b30p-1 ++-0x1.4604a175e993ap-24 ++0x1.ebfed39cc2c8bp-1 ++0x1.46b9055c4ca9fp-1 ++0x1.306ca7dee4864p-2 ++-0x1.54b193e5a6106p-1 ++0x1.d915353edaa25p-1 ++-0x1.559071a09ac62p-1 ++-0x1.dfd05503dd9c9p-1 ++0x1.6372147e80a9bp-2 ++0x1.1d6c4659b2302p-15 ++-0x1.51678029a9639p-1 ++-0x1.93c504552cc8ap-1 ++0x1.500db1270ff22p-1 ++-0x1.a84a143781395p-2 ++-0x1.e0eef33df7060p-1 ++0x1.a5b9342b2a503p-1 ++-0x1.7e31e007182c1p-23 ++-0x1.cbe100e36ed62p-1 ++-0x1.e91f7469d5670p-1 ++0x1.eb0711bcb2188p-1 ++-0x1.d9e340faf4907p-1 ++-0x1.d3eaf468140d5p-1 ++-0x1.f046a692dfbe5p-1 ++0x1.eef541125402cp-1 ++0x1.164721f247577p-1 ++-0x1.948565494d763p-2 ++-0x1.88826288be33dp-13 ++0x1.e66022a174720p-1 ++-0x1.74bb306267089p-1 ++0x1.0e806680dde9bp-19 ++-0x1.36bf209f8d75ap-1 ++-0x1.fdb1502db4889p-1 ++-0x1.dc58a3a509822p-3 ++-0x1.ff1285390535cp-1 ++0x1.e697822f3ef41p-2 ++0x1.f0b895823caf7p-1 ++0x1.ee8a003f19352p-1 ++0x1.86cef6dc903e7p-1 ++-0x1.b06d1232385aep-1 ++0x1.f7415347bb40bp-1 ++-0x1.1849f3c6d3a7fp-24 ++0x1.d8bb0536d10cbp-1 ++-0x1.7134b61c665cap-26 ++-0x1.63c4664215f4dp-1 ++-0x1.4af2b05df7423p-3 ++-0x1.ec83e4b62417bp-1 ++-0x1.ea94d7a68205ap-1 ++-0x1.758b46be117efp-23 ++-0x1.e67b111d9643ap-1 ++0x1.c7fba1185bbb7p-1 ++0x1.3ee093dfa7bc7p-9 ++0x1.761e6712c456dp-1 ++-0x1.4147f16c16ab0p-1 ++0x1.a19ce52b4f906p-1 ++-0x1.480570f907c0ap-25 ++0x1.9b1db0483a855p-20 ++0x1.e1ef409647a27p-3 ++0x1.4c8792308f4c7p-3 ++0x1.11dc218d362eap-3 ++-0x1.ee64f1975f7e6p-1 ++-0x1.2693204eaf09bp-1 ++0x1.834e43d519f57p-20 ++-0x1.f321806888b14p-1 ++-0x1.912d845baba7cp-1 ++0x1.f0d7d51f16eafp-1 ++-0x1.98615085cae70p-1 ++-0x1.3254856940809p-1 ++0x1.f5e36613814c9p-1 ++0x1.f43be6f8db5a1p-2 ++-0x1.d999f12e66f25p-1 ++0x1.795a0759e9a8dp-1 ++-0x1.731ba13d1957bp-26 ++0x1.df2806ba55640p-1 ++0x1.93b6b433d212dp-8 ++-0x1.de2d26a9b9821p-1 ++-0x1.c253e67cccb47p-23 ++0x1.d896e2d45c8e1p-1 ++-0x1.e9d165420d859p-1 ++-0x1.7ed393dd2a80ep-3 ++-0x1.72e6237bb4f8dp-1 ++-0x1.77dcd46971c3fp-1 ++-0x1.0f7294284d3d2p-1 ++-0x1.ee0460d9eea8dp-1 ++0x1.f593219765d24p-1 ++0x1.ef4575e02694ep-1 ++-0x1.88ed60dd3430cp-1 ++0x1.e83fc488dacd6p-1 ++-0x1.f6b1f794f743fp-1 ++-0x1.f6fad097104e4p-1 ++0x1.f578d77058051p-1 ++-0x1.ead825875d99ap-1 ++0x1.e47714a63f73ap-1 ++-0x1.faf0f514a94b4p-1 ++0x1.67c2f0fa8047bp-1 ++0x1.eafad3737c504p-1 ++0x1.dd79933eb4823p-1 ++-0x1.d8e09754f9b03p-1 ++-0x1.622a31c8a4a1dp-1 ++-0x1.c3658532b752dp-17 ++0x1.4653f0b895ddep-1 ++0x1.4b7f774a00827p-1 ++0x1.5671004a1fee4p-1 ++0x1.ed1eb4107075cp-1 ++-0x1.e91e34b9e7e08p-1 ++-0x1.40a8260114e62p-1 ++0x1.fcd51406408b5p-1 ++-0x1.b41136108fbfcp-3 ++-0x1.ea510117fd3ecp-1 ++0x1.9875d57574880p-1 ++0x1.8e6821b32b65bp-1 ++0x1.7b7895c4df3f3p-3 ++-0x1.0f9652222f8e9p-1 ++-0x1.e20bc23074b3bp-1 ++0x1.71c19505b627cp-1 ++-0x1.50acd256c1190p-9 ++-0x1.f88e41f893405p-1 ++0x1.04c507eebef8dp-2 ++-0x1.088452ad3c759p-1 ++0x1.087d627cadb98p-10 ++0x1.9dd3f239428bep-1 ++-0x1.ac5f04341a72fp-1 ++-0x1.df87628ca53cfp-1 ++0x1.d963f3e2377acp-1 ++-0x1.bc583247a7cb5p-3 ++-0x1.19bbe7224c70bp-1 ++0x1.e51196492219ap-1 ++0x1.f8be8469e0f90p-1 ++-0x1.9d7b07a7045cfp-1 ++0x1.7f288239bc808p-6 ++-0x1.f06ed4e303e99p-1 ++-0x1.edb676b500699p-1 ++-0x1.11c8041a56a40p-1 ++-0x1.8fa0020067b9ap-1 ++-0x1.e38a3096c29f9p-1 ++0x1.8bd9a2320c1eap-3 ++0x1.ec3a1130d87e6p-1 ++-0x1.f041e6d4d3221p-1 ++-0x1.ec3ed491bab06p-1 ++-0x1.e82ed1f92fb3dp-1 ++0x1.d97577265ac94p-1 ++0x1.e0dc4301d27ffp-1 ++-0x1.3c6f734ef61e6p-1 ++0x1.d481020b94331p-1 ++-0x1.084e305313b99p-17 ++-0x1.e379862ec0fddp-1 ++0x1.c59db4bbac95fp-1 ++-0x1.d65bd11324f1bp-1 ++-0x1.c59a52083041ep-3 ++-0x1.f7db5704a4985p-1 ++-0x1.e962d3ae18889p-2 ++-0x1.53c9205e774e8p-1 ++-0x1.e911418959876p-1 ++-0x1.eede64d01dd85p-1 ++-0x1.567a6656d28acp-1 ++-0x1.e6aa85d031c63p-1 ++-0x1.eb05376e22db1p-1 ++-0x1.7f6913662676cp-1 ++-0x1.495606dbbbe93p-7 ++-0x1.ec3000dc4aabap-1 ++0x1.ec4706c41bd83p-16 ++-0x1.e6a7c54bbfa5ap-1 ++-0x1.7a7641865ee08p-1 ++0x1.b53be3ce487cbp-1 ++0x1.40e9902e7c79ap-3 ++-0x1.eb3282a56efc8p-1 ++-0x1.dc476211ce07dp-1 ++0x1.fbb577823c6b2p-1 ++0x1.db89870b0b16dp-1 ++-0x1.efa8f6daf9d6ep-1 ++0x1.decb623f19c20p-1 ++0x1.34c3170fae6e6p-1 ++-0x1.eb66f41c573b3p-1 ++-0x1.42fa605e3ab02p-18 ++0x1.62f563b214a71p-1 ++-0x1.ebfe83dfbd7bfp-1 ++-0x1.d8320749306c8p-16 ++0x1.096bd4970cd0dp-22 ++-0x1.34db46c5d25f9p-1 ++-0x1.e584302e3a118p-1 ++0x1.279d83bbed431p-3 ++0x1.e267d33665809p-1 ++0x1.e7dfa379e70a6p-7 ++-0x1.db6095b37c495p-1 ++0x1.e8fc0548a8effp-1 ++0x1.df80158c55f1bp-1 ++0x1.085252cff6318p-2 ++0x1.e8b2a51a22aedp-1 ++-0x1.6c2551b909220p-1 ++-0x1.6b160460a6dafp-1 ++-0x1.ab45345443095p-1 ++-0x1.6deca2af052c9p-3 ++0x1.837e7496593b3p-1 ++-0x1.bf1280b399b44p-3 ++-0x1.846896e4714edp-1 ++0x1.a87ef4867a7b7p-20 ++-0x1.ebcf01f1f9c05p-1 ++0x1.ee9f7221b6d23p-1 ++0x1.f218003f765f8p-1 ++-0x1.dee46627c2030p-1 ++0x1.eff7e643f253bp-1 ++-0x1.3e07f3ef0c1aep-3 ++-0x1.7c2b31f076e73p-11 ++-0x1.806c918e71aeep-1 ++0x1.0db187d31341cp-2 ++0x1.8a44534c5fa47p-1 ++-0x1.dbd3606da38ebp-1 ++0x1.4c41a22828d0ap-1 ++-0x1.9eb9358ded573p-3 ++0x1.e080f6a0dd5a1p-17 ++-0x1.edc7b0c6d7c61p-1 ++0x1.1672e0cfb0ae6p-1 ++0x1.bcc2d238d4ddbp-25 ++0x1.ef15079437d86p-1 ++-0x1.e8c624ef9c950p-1 ++0x1.8543e62f380d5p-3 ++0x1.fef15658b7b3dp-17 ++0x1.fdaef64e92ad5p-1 ++-0x1.ed9495fb211ccp-1 ++0x1.66b7a3a5f4bbcp-2 ++-0x1.e4b4d29f62b3ep-1 ++-0x1.af4687b7a9dd1p-1 ++-0x1.1b8575ec2f1bcp-3 ++0x1.719ad2699f7f4p-1 ++-0x1.2ae4206794c97p-2 ++-0x1.f697d28a52766p-1 ++-0x1.4de5a4d1044b1p-1 ++-0x1.e859b3f551706p-1 ++-0x1.995221a7cd650p-1 ++0x1.5b44a5441ff42p-1 ++0x1.b40b1223b8731p-1 ++0x1.f41ca43bda5ffp-1 ++-0x1.d64953db536f6p-1 ++0x1.f237a08dabbebp-8 ++0x1.2ab9e2f378d0ap-3 ++0x1.748f13fdb7757p-1 ++-0x1.85fce11104791p-21 ++0x1.e8fb12ed42b85p-1 ++-0x1.b9be13f0400a5p-3 ++0x1.5cf593bcc75fap-1 ++0x1.e62c06763ca98p-1 ++-0x1.ef83347913d46p-1 ++0x1.8cd87241429ddp-1 ++0x1.ed52a73ea36ddp-1 ++0x1.eb1fb7b4361a5p-1 ++0x1.659040150dccep-1 ++-0x1.e84f02088580bp-1 ++-0x1.31efb599b0c90p-1 ++-0x1.3d71f7cc5cbb8p-14 ++-0x1.a7947303093c0p-2 ++0x1.d9d164d5dd4b4p-1 ++-0x1.a6a84397e3686p-1 ++-0x1.dbfc05a512685p-1 ++-0x1.5b0384147576ap-1 ++0x1.24925361ccdf7p-1 ++-0x1.ff78b2a719f69p-1 ++0x1.ed23979169478p-1 ++-0x1.aca5d6e0cebc8p-1 ++-0x1.ef3d97ca40548p-1 ++0x1.b18ed204df0bep-1 ++-0x1.8bb177f1b45d0p-1 ++0x1.eea5d7d2221dap-1 ++0x1.7f86226cc352bp-7 ++-0x1.e8690599a1b6bp-1 ++0x1.c62b97c2b228ap-3 ++-0x1.a1283741d2ae6p-2 ++-0x1.36bf72bd2813ep-1 ++0x1.02ff0102590a7p-1 ++0x1.81aef093e519fp-1 ++-0x1.e5788391286c7p-1 ++-0x1.373103fbf2dbbp-26 ++0x1.34e2d1a2d3f9bp-6 ++-0x1.f8d06493cf734p-1 ++-0x1.c24710eb7be22p-3 ++0x1.d2db6598cfaf0p-1 ++-0x1.da7e74a47298fp-1 ++-0x1.9af47030895e7p-12 ++-0x1.891952e265231p-1 ++-0x1.092645a64f8d3p-20 ++0x1.4f75862316ad1p-25 ++-0x1.fe90e5f9be415p-1 ++0x1.fb4ee1a050156p-1 ++-0x1.ec39744c1f0c8p-1 ++0x1.ba15c60d9db6fp-1 ++-0x1.87a6e44eaf473p-14 ++-0x1.346b35da45de2p-1 ++0x1.8db9c701a763cp-25 ++-0x1.db34b430e32a8p-2 ++-0x1.629942502fa18p-2 ++-0x1.e413c088c0673p-1 ++-0x1.1f6e31af5699fp-1 ++-0x1.ed7495c0fc882p-1 ++0x1.abee977c43f44p-1 ++-0x1.66cc97e31eaf9p-1 ++-0x1.e215564a14206p-1 ++-0x1.2c8ac0b1cee68p-6 ++0x1.d44c706157084p-1 ++0x1.60e11610c7ee0p-1 ++-0x1.30bba0afa8fb3p-1 ++0x1.bee52516c6958p-2 ++0x1.704ea3b5ecd74p-1 ++0x1.9e8346c8dd9e3p-1 ++-0x1.8d20a7a73971bp-1 ++-0x1.fee190f2fc2b8p-2 ++0x1.2412133b85638p-1 ++0x1.e12c42ed2cf35p-1 ++0x1.ab2c11f181602p-1 ++-0x1.3792d18b82986p-2 ++0x1.8201c2f453059p-1 ++-0x1.a787c4bfd3b9dp-1 ++-0x1.21cfc16c9dd00p-15 ++-0x1.fe18e3a9ee189p-1 ++-0x1.e0a0474a78619p-2 ++-0x1.f2b9635cc6607p-1 ++-0x1.ead0a07de749ep-1 ++-0x1.51be7174fb83ep-1 ++0x1.ce044606c1030p-1 ++-0x1.7ea081641e5c0p-1 ++-0x1.a3b065b4875e9p-1 ++-0x1.dfdae0cbe44cdp-1 ++-0x1.ed7ef264fedb8p-1 ++-0x1.ef5091c5626a8p-1 ++-0x1.dc56039dc4ef6p-1 ++-0x1.495862db7188cp-18 ++0x1.f702c7007d0f8p-1 ++0x1.af0a752686e3dp-3 ++0x1.e30a96a56e0a2p-1 ++-0x1.9e27251b3702fp-13 ++0x1.d09934bc80099p-1 ++0x1.0e94e36bb88f6p-2 ++0x1.e6ddf06e94dd2p-1 ++-0x1.07c16329a6368p-1 ++-0x1.ba2ae6c81ef86p-19 ++-0x1.0c0a94e27bcffp-1 ++0x1.dd58042e78413p-1 ++-0x1.e659010e4489dp-7 ++0x1.0214d6e90f72ap-1 ++-0x1.cf4586cf33876p-2 ++-0x1.b70207125cf48p-1 ++-0x1.df4870eb61dfap-2 ++-0x1.f57f5552ab569p-1 ++0x1.dfcf57952b0f5p-1 ++-0x1.e8c51781e0f5ap-1 ++-0x1.e482f48b7b06fp-1 ++0x1.ebaf12ac1ca9ep-1 ++0x1.e737501a3ae33p-2 ++0x1.ecd747e9c09c1p-1 ++0x1.e862d221950bfp-1 ++-0x1.11bc51c1a6b71p-1 ++-0x1.8b32c03c1f3fep-1 ++-0x1.45d6537260c70p-3 ++-0x1.eab7a154b753bp-1 ++0x1.dc3de7d2fc8d2p-1 ++0x1.ebba47c789bf9p-1 ++0x1.e9ecf3956d1f2p-1 ++-0x1.b9b423bd8562fp-16 ++0x1.ea80b59543ec4p-1 ++-0x1.4c94d139f13e8p-1 ++-0x1.6e83b5a2a8fe5p-19 ++0x1.e543336eb0ac0p-1 ++0x1.e1ebe4a9d8a89p-1 ++0x1.ed72033a5db2ap-1 ++-0x1.e266b288cfc87p-1 ++0x1.027c5616cc343p-1 ++-0x1.e35a95def4819p-1 ++-0x1.413b8018c5b35p-1 ++0x1.25c3a3e3119f1p-1 ++0x1.29429685f155dp-1 ++-0x1.daec27668718ap-1 ++0x1.066c27f6a6cfep-1 ++-0x1.ece86688b8215p-1 ++0x1.e7fb31fd3c964p-1 ++-0x1.7208a0ee99588p-18 ++0x1.e55e406d573cap-1 ++0x1.e8af41ef26febp-1 ++0x1.371c35f823ee3p-1 ++0x1.d17522ea5e064p-1 ++-0x1.7accc66f1a867p-1 ++0x1.1b88e568085eep-3 ++0x1.efa964a3049c3p-1 ++0x1.0ae4753a5c894p-13 ++-0x1.e5dc4522b9124p-1 ++-0x1.eea0521dad0ebp-4 ++0x1.852e91bce0883p-1 ++-0x1.dd70c04d30a3ap-1 ++-0x1.10e344fda4288p-3 ++0x1.f8ed93cccdd32p-1 ++-0x1.9b2a127bc4877p-1 ++-0x1.3ae99644caf6fp-2 ++0x1.2011857db1424p-26 ++-0x1.e901933e634b8p-1 ++0x1.c426411a0bd0ep-1 ++0x1.a5edb0220c08ep-1 ++-0x1.effdf2686cde6p-1 ++0x1.c32c91193429cp-13 ++-0x1.51f3b17d298a4p-1 ++-0x1.7f189788a9871p-1 ++-0x1.6df8f3b40a7d7p-20 ++-0x1.cc9fa732730b4p-1 ++-0x1.e800e2c46ef54p-1 ++-0x1.0036b44e98fb9p-1 ++0x1.545021fa9de9cp-1 ++-0x1.dbd584ff2c565p-1 ++0x1.f4ea010d09590p-1 ++0x1.0838d097bf35fp-2 ++-0x1.a1da024b0b5d7p-8 ++0x1.e8d72663b3bb6p-1 ++0x1.bd21611d957b4p-1 ++-0x1.e632b5939513cp-1 ++0x1.ef5182ea9b9f9p-1 ++0x1.1f999553c9965p-1 ++-0x1.b47b81b50fe30p-2 ++-0x1.ec1d2221cef9fp-1 ++-0x1.ff88333427dbap-1 ++-0x1.f9b0f160d4715p-1 ++0x1.000f60ec89995p-2 ++0x1.03ce907b337a2p-7 ++-0x1.a63a42293fa26p-3 ++0x1.292904fec9be4p-1 ++0x1.820c4727f0297p-1 ++-0x1.ee77e35aa0adep-1 ++-0x1.ecc08254e2ca3p-2 ++0x1.f5e2939c7c8abp-1 ++0x1.fe103302da0f0p-1 ++-0x1.ee18039175978p-1 ++-0x1.d7c305801dc47p-6 ++-0x1.f7bb55bddabc2p-1 ++-0x1.f3f604ec44843p-1 ++-0x1.6fbae21dcab06p-1 ++-0x1.f613a094bcd5bp-1 ++-0x1.9b44300f94ca8p-1 ++0x1.ebb413b8af6a7p-1 ++0x1.8ff5319a0c60fp-1 ++0x1.21f49780f87b2p-1 ++0x1.edc3445e3d359p-2 ++0x1.be0ce0e44a018p-3 ++-0x1.ee9ef2f6c17b3p-2 ++-0x1.c27d81c83efabp-1 ++0x1.ac8f6552a58dep-1 ++0x1.711ce469b9c2cp-8 ++0x1.fa3c9399c63afp-1 ++-0x1.432c76363edb9p-2 ++0x1.ea3e827115c9dp-1 ++-0x1.ea73d35821c98p-1 ++0x1.bf34426cf512cp-1 ++-0x1.1445f5830a831p-21 ++-0x1.ee29a33d89217p-1 ++0x1.8ccbb1dcc318bp-1 ++0x1.25b4539e355fdp-1 ++0x1.d9f2a66cb195ap-1 ++0x1.1d3cb7d6c6a5ap-1 ++0x1.b1b470d44d8e1p-1 ++0x1.a8b3a413894e6p-10 ++0x1.e85bb560bc75dp-1 ++0x1.5f70e6661a987p-3 ++-0x1.e607b65d13651p-1 ++-0x1.7133562954a55p-26 ++0x1.e8d044bdd2df4p-1 ++-0x1.6d61c0b3f3e7ap-1 ++0x1.b036d56c1ea88p-1 ++0x1.db9765d455c4cp-1 ++-0x1.d67e0577a6507p-1 ++0x1.1149b4f4323d5p-1 ++-0x1.61dc625616ea4p-1 ++0x1.e7e686da575a0p-1 ++0x1.1f8845720550bp-3 ++0x1.181681ffa6887p-1 ++-0x1.f9a361114e127p-1 ++-0x1.2daf678a502f3p-1 ++0x1.e9d467bd4f063p-1 ++0x1.6bdae68159ee5p-2 ++0x1.31f72092e0a01p-3 ++-0x1.0257216dc5462p-1 ++0x1.a3eba171994e9p-1 ++-0x1.76ca124cf6f47p-3 ++0x1.edaef15ec1849p-23 ++-0x1.55ac10a3a8641p-3 ++-0x1.c41062b424a37p-1 ++-0x1.d92890d75b595p-1 ++0x1.dcfb53f8d12a7p-1 ++-0x1.e282c640ea6f9p-1 ++0x1.d213669b363a3p-1 ++-0x1.e38275a589425p-1 ++-0x1.8ae0d1a8a37fbp-1 ++0x1.2e4ef4f93f824p-1 ++-0x1.e41b13bb1ae98p-1 ++0x1.086eb6e0f5f9bp-1 ++-0x1.e5a480f554f3dp-16 ++0x1.247007cd3459dp-9 ++0x1.126fb704975d2p-2 ++0x1.ead2c179b0748p-1 ++0x1.e2a9b69b414cfp-1 ++0x1.dd5754e2b6f70p-1 ++-0x1.aa3c46accda7bp-1 ++-0x1.eac543bc70794p-1 ++-0x1.3e5ed5df8f9b3p-3 ++0x1.c87902a9dc843p-2 ++-0x1.7488404424d8fp-1 ++0x1.0a0993e0464fep-1 ++0x1.ec89e597c1fb8p-1 ++0x1.ff68c644002e1p-1 ++-0x1.57e6c01243fa0p-1 ++0x1.e6e2b58850fbcp-1 ++-0x1.ee92e612cb066p-1 ++0x1.e3f070eec2596p-1 ++0x1.a3a1677955b56p-1 ++-0x1.bcc7e5fa33d67p-1 ++0x1.594fe3ac79583p-1 ++0x1.50ec000b8e4acp-3 ++-0x1.f9295717cfd6fp-1 ++0x1.ef55f3c40b195p-1 ++-0x1.fb0bc0bcae0e5p-1 ++0x1.ef1e83db4a781p-1 ++-0x1.e24192e4c76d5p-1 ++-0x1.b008d5aeca3d0p-1 ++0x1.e8f7b7904e38ap-1 ++-0x1.ee3126a0a120bp-1 ++-0x1.261cb76f274a4p-1 ++-0x1.e693d2d796ecap-3 ++-0x1.ddbba60a316aap-1 ++-0x1.f79761f4b586fp-10 ++-0x1.ea326681d6327p-1 ++-0x1.30688704ba934p-13 ++-0x1.e7cb21c3e16e5p-1 ++0x1.587605ae10952p-1 ++-0x1.e19505b39f2c0p-1 ++-0x1.e18a12334f770p-1 ++-0x1.0837757b9d39dp-2 ++0x1.d5a6b0de0792ap-3 ++0x1.f99470c182bf6p-1 ++0x1.ed070744db724p-1 ++-0x1.73b2737edc5c7p-26 ++0x1.b936968f91883p-3 ++-0x1.ea40a3cab079fp-1 ++0x1.38e266cf4e67bp-23 ++0x1.eef1a663ee7c0p-1 ++-0x1.b714f5eded91ep-1 ++0x1.dbc6676e6b672p-1 ++0x1.eb6416d4263a2p-1 ++-0x1.cd5f86a8d0aa0p-1 ++0x1.6f9df5f49001bp-2 ++-0x1.6c0f802e7de00p-1 ++-0x1.171c4382a49b5p-1 ++-0x1.6b40229004e64p-1 ++-0x1.9b6996025da1cp-1 ++-0x1.efbc035d5241cp-1 ++-0x1.8d6cd1d2f1d24p-2 ++0x1.387816b7132c2p-15 ++-0x1.222651699e523p-1 ++0x1.3b2d21d75094ap-2 ++0x1.e81bf743c0369p-1 ++0x1.ee2044b7efb74p-1 ++-0x1.ff5cc72dade88p-1 ++-0x1.c932d35cb0882p-1 ++-0x1.e12937d9b5de6p-1 ++-0x1.bb5fe6c2388bcp-20 ++0x1.e2f9c07852f70p-1 ++0x1.389e508c2d4a1p-3 ++0x1.4e0e70421f589p-3 ++0x1.cc1262f95c14cp-1 ++0x1.fc9c210385ec5p-1 ++0x1.9984459a46260p-1 ++0x1.e4e8c2f4a4892p-1 ++0x1.e37f56ad5d374p-1 ++-0x1.d604e43246f1ap-1 ++0x1.dd2cb52e3f946p-1 ++-0x1.ad5ce2c9a061dp-2 ++-0x1.e304f24cdfffbp-1 ++0x1.06c562663d3d5p-1 ++-0x1.80d703d704546p-1 ++0x1.24f756f5e8490p-22 ++0x1.ef88e7a892892p-1 ++-0x1.8acf064a612ebp-11 ++0x1.f85ef0fd21f0bp-1 ++-0x1.f2d7b573896eep-1 ++-0x1.c41b9411e2424p-1 ++-0x1.0eed14bd5c463p-1 ++-0x1.ecf8e686be7cep-1 ++-0x1.965f75ff798a9p-1 ++0x1.6411e12b18fc4p-1 ++-0x1.11af90316a631p-9 ++-0x1.da5f66b16e89ep-1 ++0x1.085d72e4cc8a6p-1 ++-0x1.dd2c9123047c4p-1 ++0x1.ead1c7993f167p-2 ++0x1.d9b8b3488e2c9p-1 ++0x1.e3ba8654faf94p-1 ++0x1.b12e97910d2fbp-3 ++0x1.8ca403a109b30p-3 ++-0x1.e5f2937058787p-1 ++0x1.1a16c20b59c20p-8 ++-0x1.11098610b5ed6p-16 ++0x1.892e670d4f005p-1 ++-0x1.2648b2df313ccp-1 ++-0x1.dfc21746825a5p-1 ++-0x1.4f866516769a4p-1 ++-0x1.e913c2d94e14ep-12 ++0x1.50e5c3abd6b3ep-1 ++0x1.ddb931972f706p-1 ++0x1.66d50185eedb5p-2 ++0x1.178457d5f3122p-1 ++0x1.0a089692fa9d6p-1 ++0x1.53e8b3a99a9ffp-21 ++0x1.faccb45f4e2f8p-3 ++0x1.0fba936e6a028p-2 ++-0x1.b6f9a6276a135p-1 ++0x1.67cbb33515663p-6 ++0x1.3ac2c7ff47442p-1 ++0x1.fd2901f3c9671p-1 ++0x1.a95ba191e3d37p-20 ++0x1.ecfdc74673b2ep-1 ++0x1.e33344b0b2b7dp-1 ++0x1.d6b6c30ea8c56p-2 ++-0x1.3e18951be4c2ap-10 ++0x1.06544747d23b7p-1 ++-0x1.6530f1b557057p-1 ++-0x1.e141a1fc347e7p-1 ++-0x1.c209253da05dfp-1 ++-0x1.5abd34f01cc55p-25 ++0x1.da55f059b4805p-1 ++0x1.b15ad1f0f8186p-1 ++-0x1.e2f6324aebb6cp-1 ++0x1.e6cf20c6b3bd3p-1 ++-0x1.d9f586a99ac1dp-1 ++-0x1.ea5db6c802980p-1 ++-0x1.eef205ef8bf9cp-1 ++-0x1.e77cb3d6aba48p-1 ++-0x1.efb0238767d34p-1 ++0x1.eac576f6fcc93p-1 ++-0x1.9d69119b79677p-17 ++0x1.95acf5bfa2f77p-3 ++-0x1.551e1792426dap-1 ++-0x1.dbe0e257f280cp-1 ++-0x1.f69220aac2bb2p-1 ++0x1.57b2160efdbf5p-2 ++0x1.e58de281a1a07p-1 ++0x1.084020b03e4d2p-6 ++0x1.d87e91b7e07b7p-1 ++-0x1.99cda400ce3b7p-2 ++-0x1.e362932c8c92fp-1 ++-0x1.da4995d5cee72p-1 ++0x1.87b2d4dcffaf9p-1 ++0x1.3ea5128eaaf2dp-1 ++-0x1.5faae7d3bcf38p-1 ++0x1.3aec5799bb1d9p-19 ++-0x1.ec3797b899976p-1 ++0x1.8aefc30a2949bp-1 ++0x1.bd62a0a521e27p-2 ++-0x1.ab7df36836c3fp-1 ++0x1.91ab544ac879fp-2 ++0x1.f80f9015de12ep-1 ++0x1.aa572325d6916p-1 ++0x1.efb673b18111ap-1 ++-0x1.dbb4625b1b6d4p-1 ++0x1.ddbbe2e244b52p-1 ++-0x1.f79ea4af0ff39p-1 ++-0x1.c16b5501eff50p-1 ++0x1.ea4315c9c663fp-1 ++0x1.ade22053744afp-1 ++-0x1.e4b1a6febdb21p-1 ++0x1.ec9464048b26cp-1 ++0x1.e3c1e7f51cf59p-3 ++-0x1.dc8fa6420fb87p-1 ++-0x1.f052a40d8e48bp-1 ++0x1.cb7bf6c1858f8p-17 ++0x1.e4fbf10139e0ap-1 ++-0x1.df2192fe7f98dp-1 ++-0x1.062da16c62ccep-1 ++0x1.0dca9008fbcebp-2 ++-0x1.0fd4c304627a5p-11 ++-0x1.f7ad343c1ffafp-1 ++-0x1.3de2247c0ac76p-1 ++0x1.a8f991857abcfp-3 ++0x1.b42d56efb9226p-1 ++0x1.410fc200873e5p-1 ++0x1.b2a8837671aa6p-1 ++0x1.adf61664fadc1p-1 ++-0x1.858b722a5427bp-1 ++-0x1.e20ac139c6d90p-1 ++0x1.ec4a72202abfbp-1 ++-0x1.bf067665f434dp-3 ++0x1.b78865ebf7179p-1 ++-0x1.0634566d8abcep-1 ++-0x1.e6a6172392825p-3 ++-0x1.e6fc2655bf4fep-1 ++-0x1.e543e6d75248fp-1 ++-0x1.e88fc53e3e4b0p-1 ++-0x1.eb40e4f889a53p-1 ++0x1.e79ef6eba9adbp-3 ++-0x1.96df34af5a088p-21 ++0x1.65efb1356114ap-3 ++-0x1.8d4e57db12a07p-3 ++-0x1.5d616093177aap-1 ++0x1.df0754bc48a37p-1 ++0x1.d025216b99be2p-5 ++0x1.e739901525d14p-1 ++0x1.e8d122ec89b8ap-1 ++0x1.e8c93262e04f1p-1 ++0x1.ffd00163380e1p-1 ++0x1.95d3428efb513p-1 ++0x1.ea9674065a5c0p-1 ++0x1.44b2453851f94p-1 ++0x1.f42ee4d7dac9dp-1 ++-0x1.e976c2fccc26ap-1 ++-0x1.27ba2598fa425p-1 ++-0x1.817945ade05b6p-1 ++-0x1.6d6582d27a94ep-3 ++0x1.ea59d39e18322p-1 ++0x1.2c7d24a2d4e9dp-2 ++0x1.f44e04251a793p-1 ++-0x1.3778036172b36p-2 ++0x1.eed61776e402fp-1 ++-0x1.799ba18a53c8bp-1 ++-0x1.6fb4348faf5c4p-3 ++0x1.ddc2869dc18a5p-1 ++-0x1.e343665d40ccap-1 ++-0x1.3f73605325ab0p-3 ++-0x1.3ba0f05c1755fp-1 ++0x1.ed92048ac9d47p-1 ++-0x1.e1a5a6243d05dp-3 ++0x1.e4fd73980b5e1p-1 ++0x1.33b9002a95e7ep-2 ++0x1.ecba4619d36bcp-1 ++0x1.6a7a22a449e86p-1 ++-0x1.a2bb4749faabep-3 ++0x1.8248f68a7e1ffp-1 ++-0x1.e21ad7da85c70p-1 ++-0x1.dd8e86ce2c248p-1 ++0x1.5d40255ad5479p-2 ++0x1.a5fa20bad74b8p-1 ++-0x1.f99406b4197a3p-1 ++0x1.d2f1b785de5d5p-1 ++-0x1.e2d534c706c26p-18 ++0x1.aeb5736c743fbp-2 ++0x1.dfc7324805273p-1 ++-0x1.2d2db09cc6e86p-21 ++0x1.edae94523b924p-1 ++-0x1.dc31f75dbd8bap-1 ++-0x1.dce536216941cp-1 ++0x1.a96985facec4bp-1 ++-0x1.e5ce57ae15fa4p-1 ++-0x1.dbd6a23f8b933p-1 ++0x1.8d6b062af3681p-2 ++-0x1.2590214dd2a24p-3 ++0x1.d0f7e414c0f7bp-1 ++0x1.eec205a0f3bfcp-1 ++-0x1.5cf1a0c8c1ccdp-2 ++0x1.ca9b05da55e1dp-3 ++0x1.e7078679d9affp-1 ++-0x1.dee200a7c99b0p-1 ++-0x1.aea74698a65c1p-3 ++-0x1.eef2e7388b0b8p-1 ++0x1.9475e0bee269cp-1 ++0x1.e8ede2eca6ebcp-1 ++-0x1.3a3f5430a9d73p-1 ++-0x1.da99616adbb35p-1 ++0x1.40a287e0245c7p-1 ++-0x1.db6f1755478ccp-1 ++0x1.4b37359e5a442p-1 ++-0x1.fabca4ba5ef23p-1 ++0x1.bdb701415b22ap-1 ++0x1.ece78508bb8c1p-1 ++0x1.4a0d37fdc5a79p-16 ++0x1.d81ca025d90bcp-1 ++0x1.eacf140a099a8p-1 ++0x1.ec31331b47ad9p-1 ++0x1.ffd881703db66p-1 ++-0x1.2f5617c2cdd47p-1 ++-0x1.de2e87858ebd7p-1 ++-0x1.3fc366eb32e48p-1 ++0x1.da5505c9b5082p-1 ++-0x1.c13e200d12a13p-1 ++-0x1.eb29615918644p-1 ++-0x1.530e61ff0420fp-21 ++-0x1.e904b6785c98cp-1 ++0x1.dd8612e5b6eb4p-1 ++-0x1.339060228fa99p-5 ++-0x1.3b19c402e1ab5p-1 ++-0x1.3af4f28b24131p-1 ++0x1.fdcf071e072d3p-1 ++0x1.a02143cfecad9p-1 ++-0x1.a33832573766ep-8 ++0x1.f013574be1027p-1 ++0x1.6bbb23e29bd56p-2 ++0x1.c2e0b4f123c1dp-19 ++0x1.0bd860a759addp-1 ++-0x1.ea778377c1e47p-1 ++-0x1.e415749cde067p-1 ++-0x1.f0a930040729ap-1 ++0x1.f0e804039007cp-1 ++-0x1.dc12b607e76dap-1 ++-0x1.3a0d506141a45p-5 ++-0x1.bc3fa1c91bbc5p-2 ++-0x1.61f91720d48f9p-2 ++-0x1.b682b0abe4889p-2 ++0x1.e2ecf4b017e0dp-1 ++0x1.161d419e7dff1p-3 ++-0x1.daf7532488e10p-1 ++-0x1.c80936da67635p-1 ++-0x1.f79a56103c6bcp-1 ++-0x1.ea6bc6967c364p-1 ++0x1.eb55c5889afdap-1 ++0x1.31373491f9fd9p-1 ++0x1.80eaa23a91ec2p-1 ++-0x1.fd9ed1b43f715p-1 ++-0x1.02c3e70019c89p-1 ++0x1.daa6242404908p-3 ++0x1.e8a1b27cb8dd3p-1 ++0x1.caa1a29c0a137p-3 ++0x1.e925463516258p-1 ++0x1.dfb4b65646ab3p-1 ++-0x1.4c1900363e38bp-3 ++-0x1.ea072277e9de6p-1 ++0x1.eb1bf69818892p-1 ++-0x1.c7891601871cfp-1 ++-0x1.e9c811e32475fp-1 ++0x1.09ffc56919a5dp-8 ++-0x1.1afd8636d88a6p-4 ++-0x1.d5faa18bb319cp-24 ++-0x1.5a73f23f4d005p-3 ++-0x1.f12a419b4a7e1p-1 ++-0x1.f3f813fc62e9ap-1 ++0x1.882457f6307dfp-3 ++0x1.cc79d0b17437bp-3 ++0x1.f849007c8fc5bp-1 ++-0x1.582d615ec34e3p-1 ++0x1.406506bfcfb11p-1 ++0x1.b6a6c3eebea0cp-1 ++-0x1.e88b2722a8806p-1 ++0x1.31b3642d568c4p-2 ++-0x1.b5ca91453fe3fp-1 ++0x1.3137f5baf9af4p-1 ++-0x1.ebd6465bc4b63p-1 ++-0x1.a49977d4938ccp-1 ++0x1.e71ef4f74efa5p-1 ++-0x1.7992140ccce3ep-3 ++0x1.e2d9f4354faf7p-1 ++-0x1.a282a4f738fe1p-2 ++-0x1.864a6783972d3p-1 ++0x1.ba4587f6ddfafp-1 ++-0x1.b9dc1365a48d6p-1 ++0x1.9b24d0442a8bdp-1 ++0x1.de51365f22198p-10 ++0x1.4b5e2197433cdp-2 ++0x1.be54761e95348p-1 ++-0x1.fb51005dfdc02p-1 ++-0x1.fa7fb41bdf4ecp-1 ++-0x1.da30d147aa840p-1 ++0x1.a0b8a727a25c6p-1 ++0x1.f298d21034624p-17 ++0x1.e9cfa7a7fd217p-1 ++-0x1.f4e8b5ec98f6cp-20 ++0x1.7302146a6f168p-8 ++0x1.5799928b1b254p-1 ++0x1.d704c60ab009dp-1 ++-0x1.9681e2cf54b70p-1 ++-0x1.e48e4276acf60p-1 ++-0x1.edd8a455629a7p-1 ++-0x1.f37d96501f78bp-3 ++-0x1.b7a5b13013786p-3 ++-0x1.e960c36a66790p-1 ++0x1.b63de6d713d58p-1 ++0x1.e47cf5ea94794p-1 ++0x1.ff99528e27db8p-1 ++0x1.6c20d6e995703p-20 ++0x1.dd82403aa55b3p-1 ++-0x1.bdf2b69afaaa0p-19 ++0x1.debfb38f72c41p-1 ++-0x1.caf0a20a2e374p-3 ++-0x1.c786d16c31b03p-1 ++-0x1.be5512ecf8b31p-2 ++0x1.eb74f08f7bea6p-1 ++0x1.41f8565f967afp-1 ++-0x1.df40e5c3806e3p-1 ++0x1.915a220e086dfp-1 ++-0x1.eab325c5fbbe8p-1 ++-0x1.811ee0ee26a13p-5 ++-0x1.deea07f1077cdp-1 ++-0x1.a4b6326d457f6p-21 ++0x1.29b2708c3a747p-1 ++0x1.c0d8d07a22f7fp-3 ++-0x1.56bf84f095b88p-2 ++0x1.d8e426b246e44p-1 ++-0x1.621014d0872dcp-1 ++0x1.7307e45a9bfb6p-5 ++0x1.dde4a27afa00ap-7 ++0x1.dbce065bbf8a3p-1 ++0x1.e1207083bb09fp-1 ++0x1.1daa53018212fp-1 ++-0x1.496161b184764p-1 ++0x1.be4077f0a12bep-23 ++-0x1.ba4832d143c1ap-1 ++0x1.eae16553c8c57p-1 ++-0x1.dcd236d0485fbp-1 ++-0x1.e2b5a72fffc26p-1 ++0x1.eb42940a8517bp-1 ++-0x1.e06e527c5ae19p-14 ++0x1.ae15b592e3128p-1 ++-0x1.ca92520c405e5p-2 ++0x1.7db9b3fa53090p-1 ++0x1.64105318b86d4p-1 ++-0x1.ed5ce02997ae3p-1 ++-0x1.30fbb21b54296p-12 ++0x1.bc360678ba681p-7 ++0x1.e5d335374c24cp-1 ++-0x1.e0749468e2cc8p-1 ++-0x1.ee3570ed32c54p-2 ++-0x1.3a8df06a429efp-2 ++-0x1.ce3772c129db8p-13 ++0x1.15ba83dfe3904p-3 ++0x1.08f5e344993d5p-1 ++-0x1.ed8e061bb76b0p-3 ++0x1.f8ffe57a8dde1p-1 ++0x1.e66a85eaf4ee0p-1 ++-0x1.fea40127cc2f2p-1 ++0x1.f2aab1284b4b0p-1 ++-0x1.cc03e1478de39p-4 ++-0x1.e912d49635d92p-1 ++-0x1.f1687635d3527p-1 ++-0x1.627064608ff5ep-1 ++-0x1.eb5a8287935edp-1 ++-0x1.1857a62740addp-1 ++0x1.5b65c47382c9ap-3 ++0x1.ecb1a4e85bbefp-1 ++-0x1.a7fea62a8476fp-3 ++0x1.ccdc351ffc956p-19 ++0x1.f8d674c4fbe5fp-3 ++-0x1.fa49b4283ce9ap-1 ++-0x1.ed8ea55dfb46cp-1 ++0x1.c552618b4fd1ap-1 ++-0x1.b9fbf215a6137p-3 ++0x1.edea1355a361cp-1 ++0x1.ba92542786897p-1 ++-0x1.a7307747e4eedp-1 ++-0x1.41cb43cc57a37p-1 ++0x1.ffe9232e1641fp-1 ++0x1.556ed63589177p-12 ++-0x1.cd6f16bc335c9p-1 ++-0x1.f2b6338523771p-2 ++0x1.db2795c5314edp-1 ++-0x1.de2267c10bed6p-1 ++0x1.ea9e158ead810p-1 ++0x1.bec560986a04ap-1 ++0x1.ef3db6de27565p-1 ++-0x1.3393b6059cb76p-23 ++0x1.b980f402882acp-3 ++-0x1.e259b369989a0p-14 ++-0x1.ff6ac3ef8dac8p-1 ++0x1.7e5081826dfc6p-1 ++-0x1.0c6c55fecc746p-1 ++0x1.ef97766ebf4d8p-1 ++-0x1.ddae26391e016p-1 ++0x1.fc6cf6ab5b808p-1 ++0x1.dc2b369f4fb97p-1 ++0x1.3e0cd4bcc78f9p-2 ++-0x1.0e4bb0b067b5bp-1 ++0x1.b79ba1d3be769p-1 ++-0x1.ea50436bfcdb0p-1 ++-0x1.fa0d71fd79cc3p-1 ++0x1.3dc4e295f1f30p-1 ++-0x1.703d419656c71p-1 ++-0x1.fa7f5390f9fbcp-1 ++-0x1.e70a30da2cfa1p-1 ++-0x1.fdabb5f507142p-1 ++0x1.f64dc541cc1fap-1 ++0x1.eb319784bca19p-1 ++-0x1.f3bc56a59b92fp-1 ++-0x1.b8a0d2c98b8e0p-1 ++0x1.425107976f0d2p-20 ++0x1.4ad290cb36082p-3 ++-0x1.b5bb322363d88p-1 ++-0x1.e7ce322063c1ep-1 ++-0x1.c48fc05bc06adp-1 ++-0x1.e74004feba25dp-1 ++0x1.19099015cd289p-1 ++0x1.9df0943df0ed7p-1 ++-0x1.a337f087e6047p-1 ++-0x1.7d8cb3c9cb5d8p-1 ++0x1.11a6b0c515920p-1 ++0x1.c693d3e0c3d93p-1 ++0x1.f141608e6aec1p-1 ++0x1.a9bde0091b760p-1 ++0x1.c93a76be71d45p-1 ++0x1.d7597098112a3p-1 ++0x1.edf6c4bdb283ap-1 ++-0x1.205784cd6e44ap-1 ++-0x1.a0d5f18128988p-2 ++-0x1.e40666614e59fp-25 ++0x1.121bf667b781ap-1 ++-0x1.668da74298814p-7 ++-0x1.616fc1a66c4d6p-1 ++-0x1.ee112212f8aa0p-1 ++-0x1.ed6ef73d531a4p-1 ++-0x1.c15fb366cfcf9p-1 ++-0x1.efffe322b6ac1p-1 ++0x1.96c5c059d54afp-1 ++0x1.e4e1454ecf85dp-1 ++0x1.db2913c8fc219p-1 ++-0x1.7f66a643bfb7ep-1 ++-0x1.27f944d4ad8d6p-1 ++-0x1.6426726aee6cfp-1 ++0x1.d9c0506986f5ap-1 ++-0x1.eeaad7939baecp-1 ++0x1.bd5a077c9fc90p-1 ++-0x1.38a69239f073cp-1 ++-0x1.f932f26d539d5p-1 ++-0x1.b260a79be9a1bp-6 ++0x1.ef9f51187fe83p-1 ++-0x1.dce6b232fc21ep-1 ++0x1.ee14f4ba14235p-1 ++0x1.eb85a30d4a2e5p-1 ++0x1.b11031019577cp-2 ++0x1.b58be17f9d847p-2 ++-0x1.d9cbe370eb0ecp-1 ++-0x1.d517b3ce2b655p-1 ++-0x1.ec41e5fb51583p-1 ++0x1.8df301a855975p-25 ++-0x1.e889435c34b7dp-19 ++-0x1.134640672cf7ap-2 ++0x1.49ae67009c731p-3 ++0x1.e80a234204ccep-1 ++-0x1.eb9c151577abap-1 ++0x1.f0b6320c75315p-1 ++0x1.b8ccb51a3d918p-1 ++-0x1.98e3649200763p-1 ++-0x1.dbe723ecfc7f0p-1 ++-0x1.db9dd79228607p-1 ++-0x1.dcb17195a4c60p-1 ++0x1.dce077ee88b26p-1 ++0x1.c85742cc49d4ep-1 ++-0x1.815743a3562efp-1 ++-0x1.dc9450089dc1dp-1 ++0x1.5e56a1bca2c1ep-1 ++-0x1.5e48b383d64fbp-1 ++-0x1.de4c64b5bc273p-1 ++-0x1.f2700673bb386p-1 ++-0x1.c1301186b73c3p-18 ++-0x1.b17535ce5f5e3p-1 ++0x1.400e032ed6125p-3 ++-0x1.128c733eb080ap-1 ++-0x1.9cf7f3c30c74fp-1 ++0x1.dc24f6d5d88e9p-1 ++0x1.f78a43cc77de0p-1 ++0x1.543a72675a6aap-1 ++-0x1.45dd4628eecd9p-24 ++0x1.fffd225b95d9fp-1 ++-0x1.363de4b85c86dp-3 ++-0x1.db6440c16c293p-1 ++-0x1.e09c81e7a33a5p-1 ++-0x1.af90f6124102cp-1 ++0x1.b4106515dc5c5p-2 ++-0x1.daa2769ff6e50p-2 ++0x1.002e426741e10p-2 ++-0x1.ee228647b7dbap-1 ++-0x1.22ec95cf2a12dp-1 ++-0x1.e93e916c943dbp-1 ++-0x1.14b932254ccd8p-9 ++-0x1.909622a8afce0p-9 ++-0x1.b5b5e40f69460p-1 ++-0x1.0b42e197effbap-1 ++0x1.3bdc443663478p-1 ++0x1.fb7b75d00f267p-1 ++-0x1.f06581e9738c7p-22 ++0x1.bcb3805a8b0acp-1 ++-0x1.9b6ff25e8b37bp-1 ++0x1.f9cb94e42bc3dp-1 ++0x1.ecd805ed64887p-1 ++-0x1.a65c4560a2138p-2 ++-0x1.56dff1b743c85p-1 ++0x1.e5298138fd89cp-1 ++-0x1.156c062335d7dp-1 ++0x1.df59064910717p-1 ++0x1.af0516501c6d6p-1 ++0x1.d2dbb56e8dd5fp-3 ++0x1.d0b523fc1ceb1p-1 ++0x1.bcf543a18c01fp-1 ++-0x1.709413363b142p-26 ++-0x1.f8c00391024e6p-1 ++0x1.5aa701b2476b0p-1 ++0x1.44865784caf4ap-8 ++0x1.e998073d61296p-1 ++0x1.8eb830a476bb7p-1 ++0x1.ff036620f55bbp-1 ++-0x1.f64585ccfeb6dp-1 ++0x1.ae9611b635f6ep-1 ++-0x1.24d9e5b7dfc26p-12 ++0x1.9a25d27526795p-1 ++-0x1.ec0cf6bf16995p-1 ++-0x1.5f64a17e9500dp-2 ++-0x1.ef0f34f9f356fp-1 ++0x1.974b13f3e4673p-5 ++0x1.09de90f53b65ep-1 ++-0x1.e1b0771809c44p-1 ++-0x1.0b7c366b28640p-1 ++-0x1.4e93f479a0cc6p-1 ++0x1.cd2b95c2df3d4p-1 ++0x1.dd556108d9ee4p-1 ++0x1.d9c6a408e180ap-1 ++-0x1.852ba5ea09204p-2 ++-0x1.6a318265b0ce0p-1 ++0x1.8187a65639248p-3 ++0x1.bed3226c9cf5ap-2 ++-0x1.bf96c5540152cp-1 ++-0x1.1c9d850480123p-1 ++0x1.d8a65092223e5p-1 ++0x1.52c841c5f3d66p-1 ++0x1.0498d6413da66p-1 ++0x1.dac374698d877p-1 ++-0x1.fc1bd618e87e8p-2 ++0x1.ebe4c1cec3060p-1 ++0x1.983b20ca0cd67p-1 ++0x1.ec96e031167b4p-1 ++0x1.ea4ee28054fa3p-1 ++0x1.edae74719dd10p-1 ++-0x1.6162424ab4689p-1 ++0x1.d9e3a0d3c4a69p-1 ++0x1.f8cc86f846007p-19 ++-0x1.f48764fc3cc92p-1 ++0x1.ec5d65428be39p-1 ++0x1.ebbdc16a6c83cp-1 ++0x1.f4021476db864p-1 ++-0x1.e537b490c8ebbp-1 ++0x1.1a8247328b1eep-3 ++0x1.ded3e00b45be7p-1 ++-0x1.12fce6ee5e120p-3 ++0x1.e8faf051d09cbp-1 ++0x1.67c444811ab4dp-3 ++-0x1.20b4a1a53c3d5p-1 ++0x1.71a901abd5ee1p-3 ++0x1.32e467615008ep-22 ++-0x1.ea1224bded243p-1 ++0x1.de9582df5c7f5p-1 ++-0x1.b8e1e27336860p-1 ++0x1.ec8561690ba28p-1 ++-0x1.daee03fa90d5cp-1 ++-0x1.3a3bc41b1b0fcp-2 ++0x1.e38b32f89a15fp-1 ++0x1.2a7a67c6a7f5fp-1 ++0x1.ad2e378f343e2p-14 ++-0x1.755da68905d10p-1 ++0x1.79c3b49ea70d1p-1 ++-0x1.8a29b0ff7fef3p-3 ++0x1.e6e791aad1f3ap-1 ++0x1.67b372a69cd0bp-3 ++0x1.f3d57719d5a66p-1 ++0x1.c96a64375fd43p-1 ++-0x1.eb6f12c7214f3p-1 ++0x1.7c2a71b780eadp-1 ++-0x1.ebcbf2f5b7eb8p-1 ++0x1.9c2ac06be1e36p-1 ++0x1.47b60350a0542p-1 ++-0x1.e81352ef49d80p-1 ++0x1.e2fde24e7441dp-1 ++-0x1.cfc297f098209p-1 ++-0x1.9f3a958bc4d8dp-9 ++-0x1.ebed30f465969p-1 ++0x1.851581e8ee5f8p-8 ++0x1.b29d24839a5c2p-1 ++-0x1.d996e18e1756fp-1 ++-0x1.e945641fd4421p-1 ++-0x1.7567a1368f83dp-20 ++0x1.eda764a20b53bp-1 ++-0x1.d90ed36b67dd1p-1 ++-0x1.1721b193cb808p-1 ++-0x1.1aa794570d691p-3 ++-0x1.486275b31eff1p-1 ++-0x1.7932031d98446p-3 ++0x1.082044740fb11p-1 ++-0x1.bc5005352d983p-1 ++-0x1.9e34b40c77bdbp-1 ++0x1.f8960738dba77p-3 ++0x1.0d8d44f6a38b9p-1 ++-0x1.ef2a370ffe51ep-1 ++-0x1.885af3b2b9117p-1 ++0x1.ab5dd30d3b0d9p-1 ++0x1.658572e828c0dp-3 ++0x1.00801354b719ap-21 ++0x1.ead7729f447e2p-1 ++0x1.73fe964bcb9b8p-26 ++-0x1.eb9e2463b8a3ap-1 ++0x1.dcc7f49496bbbp-1 ++0x1.e322464ccedbcp-1 ++-0x1.f3f1411a81959p-1 ++-0x1.b806d3a207c7fp-2 ++-0x1.9e3cf02520c9bp-1 ++-0x1.a3903178cc914p-1 ++-0x1.9157d3c02c3b2p-1 ++-0x1.a828f2fd070e9p-1 ++-0x1.dfe122ce59486p-1 ++-0x1.e0c5f12e4aee9p-1 ++-0x1.096d23efa8b4cp-1 ++-0x1.eeb2b02957428p-1 ++0x1.9bd135009e628p-1 ++0x1.dcfa56e705532p-1 ++-0x1.dcc733e36743ap-1 ++-0x1.f13ac5b2f066dp-1 ++-0x1.ee5a97d9a8b48p-1 ++-0x1.2421b26321192p-3 ++0x1.4bdfb654355fap-1 ++0x1.e9ab41fff09b7p-1 ++0x1.6c39f77452a13p-2 ++0x1.f2d9a4e18b93ep-1 ++0x1.f588f66b070a4p-1 ++0x1.c0b604407eb47p-1 ++0x1.907b33485084dp-1 ++0x1.e58d17977d4c7p-1 ++-0x1.e9c1b44e07fecp-1 ++0x1.5978b562d5348p-2 ++0x1.f69e2232d6a42p-1 ++-0x1.ea1b37e291f39p-1 ++0x1.a9c704aff0411p-1 ++0x1.0f4422ec03b3ap-1 ++0x1.0c01d7eb6c807p-1 ++-0x1.e24961f09bb8fp-1 ++-0x1.6ad805c841fcap-1 ++-0x1.f30f95a858a13p-1 ++-0x1.7509a50c46facp-13 ++0x1.0a4725eca19ecp-1 ++0x1.f041143af7d9cp-2 ++0x1.c39ee2c592617p-3 ++-0x1.b389464f1c401p-1 ++-0x1.eeb6a2abaa396p-1 ++-0x1.26b3228cfdb15p-1 ++-0x1.f7553430f26b9p-1 ++-0x1.fbb1f12faf4e4p-1 ++0x1.97b404be9b207p-3 ++-0x1.6b2935d76744bp-1 ++0x1.ee2bd4e26496ap-1 ++0x1.69d035f7a7ee7p-8 ++-0x1.5adfd2a30ceadp-1 ++0x1.81131610d528cp-2 ++0x1.81f87126313b8p-1 ++-0x1.7cb4d0d3ae749p-1 ++0x1.00a5000f3784dp-1 ++-0x1.ec020225e8d1ap-1 ++-0x1.dcfbc732dc4ccp-1 ++-0x1.f54ad24e2bdd7p-2 ++0x1.eb4c931e3f233p-1 ++0x1.ef6013aa5bd6dp-1 ++-0x1.ec4fc7eb42446p-1 ++-0x1.963eb08b090e2p-1 ++0x1.eb5787014c22cp-1 ++-0x1.c474572d53337p-1 ++-0x1.7e09139513a33p-26 ++-0x1.f9340275d9995p-1 ++-0x1.edcf16351be04p-1 ++-0x1.7d78a4e9dc91bp-1 ++-0x1.1e30752523e09p-2 ++0x1.dc4b32a234a23p-1 ++-0x1.edbb01a598c24p-1 ++0x1.6367c4f49a449p-1 ++0x1.eb1db52a22a45p-1 ++0x1.e8eba118b0a26p-1 ++-0x1.ce8021cd33ff0p-20 ++0x1.f988f6376ddcep-1 ++0x1.eabac25c2fc1ep-2 ++-0x1.e132c034f9071p-1 ++0x1.bda2b45f18ea7p-2 ++-0x1.eeab70c49e827p-1 ++0x1.d85d41c05db82p-1 ++0x1.e4003425db812p-16 ++-0x1.753ca74c55212p-3 ++0x1.98ee323f505cep-1 ++0x1.e95be276dd667p-1 ++0x1.2287403404baep-1 ++0x1.0ed8c38a3bdcep-2 ++0x1.c82792be9bbadp-1 ++-0x1.38a9d3998d79ap-1 ++0x1.e805f6d3a6c5dp-1 ++-0x1.32ebc7c55a58ep-1 ++-0x1.048b622297845p-13 ++-0x1.efb5c6983ac39p-1 ++-0x1.415a16a005c76p-20 ++-0x1.eb8aa64a05087p-1 ++0x1.a18684e94695ap-14 ++0x1.de2666acb5762p-1 ++0x1.0a79566e358dcp-2 ++-0x1.f282f0325a811p-1 ++-0x1.3f08a31b67052p-6 ++0x1.3a747651ea759p-1 ++0x1.8c22845eca245p-2 ++0x1.c1aed42df3035p-3 ++-0x1.a01057abedfe5p-1 ++-0x1.eb57d2b4d4247p-1 ++0x1.27a880bdbfcbfp-1 ++0x1.d51cd22b5b6cap-1 ++0x1.c96de70665e99p-2 ++-0x1.afeb916e3177fp-21 ++0x1.8e00d6126d657p-2 ++0x1.799d63f173a45p-1 ++-0x1.cd29463be0ee8p-1 ++-0x1.4f47a58e04b54p-1 ++0x1.ea2f35262d1a7p-1 ++-0x1.279997c5505d9p-1 ++0x1.fbe731d9f7db8p-1 ++-0x1.60d116a6cc97fp-1 ++0x1.e9d9730db6039p-1 ++-0x1.78fc83b456074p-2 ++-0x1.03c0045400546p-1 ++-0x1.f29f3377fe46bp-1 ++-0x1.33d676f26127ep-3 ++-0x1.efdd474021500p-1 ++-0x1.bab9f2ecd85b4p-6 ++0x1.c628a3529714fp-3 ++0x1.e36ae1b514d1bp-1 ++-0x1.db1e13827a88ap-1 ++0x1.dbf1b775cf9d2p-1 ++0x1.57a975b3f7f83p-2 ++0x1.1deb94df7dd48p-2 ++-0x1.8f4e44c99669ap-1 ++0x1.4ed720c5a163ap-1 ++-0x1.db81e304bef8ep-2 ++0x1.de5485ca4d9dfp-1 ++0x1.db26f3b39fe6bp-1 ++0x1.6c88456adc480p-3 ++0x1.c5a8961391ccfp-1 ++-0x1.b78ea5581fef3p-24 ++-0x1.6547c3be6a0acp-3 ++0x1.e19d1283e35b5p-1 ++0x1.e80e54a58d337p-1 ++-0x1.449b6754bba00p-11 ++0x1.e41026d50deabp-1 ++-0x1.1844f685c97cap-1 ++0x1.efa0e345c59b0p-1 ++0x1.3121f641ffbd3p-10 ++0x1.edb070c60119ap-1 ++0x1.a52c94e4dfaa9p-23 ++0x1.e5fc97f64aecbp-1 ++-0x1.f652e1fdb6a40p-1 ++-0x1.fc21417ad3694p-1 ++0x1.750fa027faf9ep-1 ++-0x1.9260f684b0d63p-3 ++0x1.e896c4a4401bcp-1 ++-0x1.7e6e516a67284p-2 ++0x1.8c32f1a45f352p-3 ++0x1.366796f5b5a00p-1 ++-0x1.763cb2cf0a32dp-3 ++-0x1.ad50f432557fap-1 ++0x1.f220a525222a6p-1 ++-0x1.e2d4f63884af4p-3 ++0x1.7796f74179cbap-1 ++-0x1.cd55d3c51d8fep-1 ++-0x1.e221669031d28p-1 ++-0x1.eeffa2c5a9c49p-1 ++0x1.ecf741dda7320p-1 ++0x1.a2a1569ae5d32p-1 ++-0x1.e680d5195362ep-1 ++-0x1.f83452138ebc1p-1 ++0x1.30e2369a99e1bp-3 ++-0x1.1a18425ff66a7p-1 ++0x1.eb7451be325a0p-1 ++-0x1.cd4ba71c2a541p-1 ++-0x1.dc4f109832464p-1 ++-0x1.eb97e24e4691ap-21 ++0x1.718a40fa573d8p-3 ++0x1.df0c61f2a0f01p-1 ++-0x1.ab0051b1239f5p-1 ++0x1.070692620b71cp-1 ++-0x1.b3cea41f5ebbfp-22 ++0x1.fa09813a0f08cp-1 ++-0x1.0e9b76f265fe9p-3 ++-0x1.dceb234e0d00cp-1 ++-0x1.8836556db32e5p-11 ++0x1.47d5509f852b6p-2 ++0x1.bb4174dfebc1ep-1 ++0x1.83be00af14ad6p-10 ++-0x1.9a44d54a49874p-1 ++-0x1.903962db8447ep-1 ++-0x1.ac0763a2833a8p-1 ++-0x1.c09d42b039fa3p-1 ++0x1.e2fec0234b979p-1 ++-0x1.e3f2b40c3e54cp-2 ++0x1.dd6694410bcf0p-1 ++-0x1.032c51b1d2105p-1 ++-0x1.d80bd4a4cf64ap-1 ++0x1.f89e41aa2fad5p-1 ++-0x1.daf4c6895a475p-2 ++-0x1.0579e7d148859p-8 ++0x1.e318d24b8b39ep-1 ++-0x1.91d2b301a130ep-6 ++-0x1.d8d40797b1ffap-1 ++-0x1.3ee1c1db473d2p-2 ++-0x1.45ebc3d70bdd6p-24 ++-0x1.6a73670891036p-1 ++-0x1.dd2d72e85c929p-1 ++-0x1.c572d1625cc9ap-1 ++-0x1.9007645684de8p-1 ++-0x1.982b1646a3406p-2 ++-0x1.e8dee29e55a00p-1 ++-0x1.867e95cfae0a8p-1 ++-0x1.57b0e23b39e09p-1 ++0x1.04807172fbb6fp-1 ++-0x1.70bea3753575bp-1 ++-0x1.cc28a3c0fb5ffp-3 ++-0x1.0663157daee85p-3 ++0x1.d83d9616cffd1p-1 ++0x1.d56357592f5acp-2 ++0x1.e006175a5233bp-1 ++0x1.ded7b522b64c3p-1 ++0x1.f11a872f5d26ep-1 ++-0x1.e3a22384a6de8p-1 ++-0x1.e8316413e3ebdp-1 ++-0x1.0da5059829177p-2 ++0x1.f67aa7a0b8826p-1 ++0x1.eb8604ab96d0bp-1 ++-0x1.c1ccb6174f89dp-1 ++-0x1.834806f8654c9p-1 ++-0x1.ef7701b74636cp-1 ++-0x1.e6fc661a4e39bp-1 ++0x1.dd3682e648173p-1 ++-0x1.7e27e712723ddp-1 ++0x1.e12486db8dca7p-6 ++-0x1.a7f9c47f84b4bp-11 ++0x1.e5dd42f5422e1p-1 ++-0x1.7f1a6320cfa79p-1 ++0x1.eb14a509edab1p-1 ++-0x1.b39b65fdaaaf4p-2 ++0x1.edf1a44e79d77p-1 ++-0x1.16c4316ff435cp-12 ++-0x1.eb0e3015adc06p-1 ++0x1.cf1bc071e7b1dp-13 ++-0x1.dacfb650325cfp-1 ++-0x1.3868c3fb4119cp-3 ++-0x1.c2a3b1d7f7890p-1 ++-0x1.e64092b0d86f7p-1 ++-0x1.53ca0177e6f37p-1 ++-0x1.4ea952cfb8453p-25 ++-0x1.e84792001e697p-1 ++0x1.ef23215f6de12p-1 ++-0x1.2152c36f9028dp-1 ++0x1.9a5905b3dd7bep-1 ++0x1.db5e820db1f0dp-1 ++0x1.2dd320b0909e6p-3 ++-0x1.027577673d37dp-1 ++0x1.e4909407d6b04p-1 ++0x1.527324f607a26p-17 ++-0x1.ed9414384d45ep-1 ++-0x1.7c4f407d91487p-8 ++-0x1.eb3f971bcf807p-1 ++0x1.d0dc12f7b7649p-18 ++0x1.4dcbd35bad403p-1 ++0x1.15ad81b482de6p-1 ++0x1.e8f0874ac9593p-1 ++-0x1.cec574569cb1bp-1 ++0x1.ebb2d275b5529p-1 ++-0x1.035e76eeac96dp-21 ++0x1.eb1e73025e051p-1 ++0x1.82b481c2cab01p-1 ++0x1.f4d8e628050abp-1 ++-0x1.4bc9841532205p-1 ++-0x1.a03cd248fa8dbp-3 ++-0x1.34a3238e9e3b0p-14 ++-0x1.442444137aebep-1 ++-0x1.17d6571c1eb38p-9 ++-0x1.ed8e345382564p-1 ++-0x1.8f2122c52c06bp-1 ++-0x1.2e84858cbd9e2p-1 ++0x1.ed5ea12bfef39p-1 ++0x1.e255d16fe29c9p-1 ++-0x1.e7c0a4791e7d1p-1 ++0x1.ea9ef4d1cf987p-1 ++0x1.bf8761b110b5bp-1 ++-0x1.d8ffa13349771p-1 ++-0x1.0dd222acc160ap-1 ++0x1.828184fbbeaa0p-2 ++-0x1.ff5bd6a9242abp-1 ++0x1.d91a30bb3e15dp-1 ++0x1.c38e7517dd45fp-12 ++-0x1.0caa231ede96dp-3 ++0x1.bf75f1da5b9f4p-3 ++0x1.07c4f43f44017p-1 ++0x1.d97165152ffeep-1 ++0x1.f565d33b8ac0fp-1 ++-0x1.9e2736ae6b655p-13 ++-0x1.12528787f6e56p-1 ++0x1.1b0912987dcf2p-3 ++-0x1.59f3c5b673712p-1 ++-0x1.bde56690f6eccp-1 ++0x1.d28502cfb2092p-5 ++0x1.ddc5738e8f925p-1 ++-0x1.7b2d0222d18edp-1 ++0x1.495424a43a336p-1 ++-0x1.bbee92a22bc1dp-1 ++-0x1.e8092359ccf4ap-1 ++0x1.d986b716394bap-1 ++-0x1.348db24936e14p-1 ++-0x1.2c3e37771fce2p-1 ++0x1.813c34a44eb1ap-14 ++-0x1.dfcb1799d0b1ep-1 ++-0x1.148f93639ab8ap-1 ++0x1.e9d8e507b6b7dp-1 ++0x1.adc4400d2246cp-22 ++-0x1.f9941587a0f90p-1 ++-0x1.0763c2612613cp-8 ++-0x1.ec59c307396f8p-1 ++0x1.f8e25686998acp-1 ++-0x1.d1b2d7ceae413p-1 ++-0x1.15af64d6bc1c9p-17 ++-0x1.4f4065a22973ap-23 ++-0x1.eb6ea004c88a2p-1 ++-0x1.b2daa6e18bec1p-1 ++-0x1.f95c5323bece4p-2 ++0x1.e1d682232cc70p-1 ++0x1.ecec70e666347p-1 ++-0x1.d0e1b0d47cce6p-1 ++-0x1.ef7c05da00ccbp-1 ++0x1.8f83f2b021978p-1 ++-0x1.18204301e710fp-3 ++0x1.eac881dd6e573p-1 ++0x1.46f83671cca25p-1 ++0x1.e30cf7c07f903p-1 ++-0x1.eba9678c3f1c2p-1 ++0x1.e64eb73adb2c1p-1 ++0x1.bd81501f6c6dbp-1 ++0x1.6c6bd2dd525cdp-1 ++0x1.205b7320c006cp-4 ++0x1.ff04d61b0df50p-1 ++-0x1.eeff51ab9dd14p-1 ++-0x1.948a52ed5c31bp-5 ++-0x1.e1c5c6487033bp-1 ++-0x1.e217c080561c1p-1 ++-0x1.3248c214e0d26p-3 ++0x1.ed0872a63647dp-1 ++0x1.e851875a532ddp-1 ++0x1.e7ab52befacc0p-1 ++-0x1.259fe08399b90p-3 ++-0x1.ededb18a270f5p-1 ++0x1.70704180d156ap-1 ++0x1.9f8db14d87da8p-1 ++0x1.e86395d65171ap-1 ++-0x1.b845d7262e0bap-3 ++0x1.4183f2511d03ep-1 ++0x1.61a7f6c5ef7d1p-22 ++-0x1.0bf534b51583ap-2 ++-0x1.ebfb153952f46p-1 ++-0x1.f432a5c40b5aep-1 ++0x1.de1315467998fp-1 ++0x1.043b03cb8172fp-3 ++0x1.ef435338a09fbp-1 ++-0x1.e3682482abf80p-2 ++0x1.8cb1a630bb9c2p-1 ++0x1.2118379e034c2p-19 ++0x1.f7d1a7b4d3511p-2 ++-0x1.befed649c5772p-1 ++-0x1.ea5613210aa70p-1 ++-0x1.5b9f05ea1adb3p-3 ++0x1.da3dc7fb7e865p-1 ++-0x1.56f2e58d53fc9p-1 ++-0x1.a4c0d4697fa72p-1 ++-0x1.4fe86735879b5p-25 ++-0x1.dbe9a120dc24dp-1 ++0x1.7e1f516ae8558p-1 ++-0x1.0ccec227b1aa8p-1 ++0x1.5a21f14dfa7b0p-1 ++-0x1.98c8e5b444e4dp-1 ++-0x1.a390457106bfbp-1 ++0x1.7834478f6c2ccp-1 ++-0x1.d355d23d9f129p-1 ++-0x1.dfbdc0246898dp-1 ++0x1.0de5e5de3ee03p-23 ++-0x1.48701720e6bd6p-3 ++0x1.da1b02240fa23p-1 ++-0x1.ff76554d1cd62p-1 ++0x1.5cf30257670ddp-1 ++0x1.f37672c4384dap-1 ++-0x1.20811778def78p-14 ++-0x1.ea363656402fcp-1 ++0x1.ef8c5245acfe3p-1 ++-0x1.d9bcb4e8d3e79p-1 ++-0x1.1372f51c095bep-1 ++-0x1.e6d7e64d3a2a2p-1 ++0x1.8d887665a4aa4p-12 ++-0x1.543b1625c6f47p-3 ++0x1.e2cfd418793d3p-1 ++0x1.e2365579a754ep-1 ++-0x1.806dd0823096dp-1 ++0x1.057365e07e692p-2 ++0x1.e13e27d7f0352p-1 ++-0x1.e170f02eef343p-1 ++-0x1.8a8b96c57e126p-1 ++0x1.300c178b2707bp-2 ++0x1.84277430fd97ep-2 ++0x1.ebace7e63c155p-1 ++0x1.7e2db343d2518p-6 ++-0x1.f53d46b53474cp-1 ++0x1.c0e313323e560p-14 ++-0x1.445786093a311p-1 ++-0x1.a073961b21017p-3 ++0x1.eb2c92dd8595ap-1 ++-0x1.dfd9b023c2058p-1 ++-0x1.9cc0608e5c256p-3 ++-0x1.1e8a967a738a4p-1 ++0x1.df31c544e9d67p-1 ++0x1.d2fad1936930ep-1 ++0x1.d8d4c3d683cd2p-1 ++0x1.e8712202731adp-1 ++-0x1.ea4834441eb39p-1 ++0x1.eda472e60d745p-1 ++0x1.e25ac2048fb9ap-1 ++0x1.4a70d01fd57a4p-1 ++-0x1.1c3704a91d838p-1 ++-0x1.df8e14d8335ccp-1 ++-0x1.e95d04451bcd5p-1 ++-0x1.ea74f086de3c2p-1 ++0x1.dda9e26e84162p-1 ++0x1.74f4f4a9a7630p-1 ++-0x1.bb4fb52218d17p-1 ++0x1.4f6f80226f31ap-1 ++-0x1.684814485308cp-3 ++0x1.7fc4e1d16dcf5p-1 ++-0x1.fe6bd006411a7p-1 ++-0x1.e0f5e654664e4p-1 ++0x1.4dd366975a5b3p-2 ++0x1.d94e10f7f2ec8p-1 ++0x1.d8c8d21926f4cp-1 ++0x1.571e352fdd0f0p-2 ++0x1.ea0f558903c1ap-1 ++0x1.f6c9d5f09ac9ep-2 ++0x1.a3c463d5b6e67p-1 ++0x1.48352432fcd1ep-5 ++0x1.bda1811e8c6b1p-14 ++-0x1.ee04d3c3f2263p-1 ++0x1.e58f617f2d384p-1 ++0x1.8e41e2bcbf28ep-3 ++0x1.191df1d6a15d8p-1 ++0x1.b0c6938c36b0ap-1 ++-0x1.d944534af1d02p-1 ++0x1.31642078c9c6dp-2 ++-0x1.841801a2f578cp-1 ++0x1.ebbb1323e8b84p-1 ++0x1.e12481b18bc72p-1 ++0x1.fa64112d9b7bdp-1 ++0x1.682c32ff96a0fp-1 ++0x1.31dd87a025af2p-1 ++0x1.df5f54d95cc0dp-1 ++0x1.4b9ce3268e639p-2 ++0x1.c206d0139362fp-1 ++0x1.e3a8a24e59ea9p-13 ++0x1.dfd890e7db3d1p-9 ++-0x1.bb5997a01dc09p-1 ++-0x1.9da2876b31f04p-1 ++-0x1.205fe30c96672p-1 ++0x1.fa4b1032a01ecp-1 ++0x1.e2db71253b231p-1 ++-0x1.5cd7b6880daedp-3 ++-0x1.dd712109d9432p-1 ++-0x1.f4c2f4098a73bp-3 ++-0x1.df4df687c5149p-1 ++0x1.a7184731a11b4p-1 ++-0x1.b717a69cb0326p-1 ++0x1.eedaa2dbb184cp-1 ++-0x1.fb6f90001c47fp-1 ++-0x1.4141539f32f56p-1 ++-0x1.9da4077805769p-1 ++-0x1.ab8c92a8ec751p-1 ++-0x1.fb9d60929751ep-1 ++-0x1.e1f9e6fd5632ap-1 ++-0x1.ef20c3a53e72fp-1 ++0x1.3a55c400f2026p-1 ++0x1.bc55404efb12dp-19 ++0x1.82c2a5d140048p-2 ++0x1.f613e22df463bp-1 ++0x1.2c6291d7f2ad7p-2 ++0x1.2319304ed36b5p-1 ++0x1.ef526669efbebp-1 ++-0x1.b3dec74769b6fp-1 ++-0x1.7fa021510350ep-1 ++-0x1.c22a90b77021ap-24 ++-0x1.e89606e911505p-1 ++-0x1.ee05e10877512p-1 ++-0x1.a748b03895981p-1 ++0x1.db4745b9604cdp-1 ++0x1.0eab126351bb9p-3 ++0x1.2b74811bfc23dp-2 ++-0x1.425187f18c762p-18 ++0x1.afbbc6e1f9f84p-1 ++-0x1.e8ac5756ef915p-1 ++-0x1.0f9400d75348bp-16 ++0x1.916dc64eee2aap-1 ++# asin multiple precision fallback path ++# Implemented in __sin32 in sysdeps/ieee754/dbl-64/sincos32.c ++## name: slow ++0x1.c88b2415431cbp-23 ++0x1.84a360ccf288dp-20 ++0x1.7eff5496b7ed2p-21 ++0x1.4360a7a7b5c14p-23 ++0x1.71374498ed714p-26 +diff -urN glibc-2.17-c758a686/benchtests/atanh-inputs glibc-2.17-c758a686/benchtests/atanh-inputs +--- glibc-2.17-c758a686/benchtests/atanh-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/atanh-inputs 2015-06-20 21:22:16.296458135 -0400 +@@ -0,0 +1,203 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.5a2730bacd94ap-1 ++-0x1.b57eb40fc048ep-21 ++-0x1.c0b185fb450e2p-17 ++-0x1.bd6e1642bb727p-1 ++-0x1.4cfdd35756bc5p-10 ++0x1.aadb5767b3ae4p-1 ++0x1.827ab42a1416dp-1 ++0x1.6d4e56dd0ff53p-14 ++0x1.667d8313f78d2p-1 ++0x1.672230c640ef3p-1 ++-0x1.35ec261f6be52p-19 ++0x1.9cf3279d8ff3ep-21 ++-0x1.a60896128036fp-1 ++0x1.ad5067d5aa573p-1 ++-0x1.8a4421ee0d23ap-1 ++0x1.aba153a252f9bp-14 ++-0x1.2498611880effp-1 ++-0x1.aa2c423f024dep-26 ++-0x1.43d972a3632b8p-1 ++0x1.12d690cf283ebp-25 ++-0x1.eec6a3a873b98p-1 ++-0x1.987b43a58457ap-21 ++0x1.96a646ec9ba90p-11 ++0x1.b961f358d8f43p-3 ++-0x1.51d594fababdep-1 ++-0x1.72a777e07e732p-8 ++-0x1.21fcd11e4d773p-1 ++-0x1.094ea21018a32p-1 ++-0x1.79ea722d33e33p-9 ++0x1.c63fc48261538p-5 ++0x1.b1c0b7e618a20p-3 ++-0x1.9957f1ba37225p-19 ++-0x1.ecc6037c6538ap-21 ++0x1.7e0bc46e556bcp-1 ++0x1.4e7cd59b97811p-22 ++-0x1.6b2773f7bf9c1p-27 ++0x1.db9e07d2c1d81p-1 ++0x1.293835cf8c06bp-1 ++0x1.f59e8473488f7p-1 ++0x1.094c253414b65p-22 ++-0x1.922cb3b58f124p-3 ++0x1.8a9b4773d8067p-1 ++0x1.59e1848e51b3fp-1 ++-0x1.77eb61d6b55b3p-1 ++0x1.63e245bf37393p-1 ++-0x1.8adb670e973d8p-1 ++-0x1.c34f8232a8efap-1 ++0x1.83f2e5bd4e680p-25 ++-0x1.6b8d336fb28b2p-1 ++-0x1.f50ce1076f808p-23 ++0x1.ceb5a49139809p-19 ++-0x1.3d0616e8d067dp-11 ++-0x1.5ff057a79950ap-1 ++0x1.263f96335fa00p-25 ++0x1.5d5fa0d6d5003p-9 ++-0x1.5070a3937a84bp-7 ++-0x1.299707cfa0a5ap-5 ++-0x1.64f623f5a4713p-3 ++0x1.2bc994ee38c37p-3 ++-0x1.e27d9435b978ap-1 ++0x1.8092d58d5c790p-21 ++-0x1.9c31372efb7c2p-25 ++-0x1.b3e4409bf591ap-11 ++-0x1.fc9e4603f0a42p-16 ++0x1.7d4f167842e1ep-1 ++0x1.d220d2dea0517p-25 ++-0x1.f327d6a043438p-9 ++0x1.0fbf54939b136p-16 ++-0x1.9d4c17b3aa3e3p-18 ++-0x1.6ab736c8be0aep-5 ++0x1.ecff81aec235cp-1 ++-0x1.102122d6bf984p-1 ++-0x1.44a7f0d39a7cbp-18 ++0x1.369d17b6b92d9p-1 ++0x1.2c1ec48113977p-1 ++0x1.b2a4a2cd6ddbfp-1 ++0x1.1aa8449c2cce7p-18 ++-0x1.2083e1015b457p-1 ++-0x1.1589761b30c7bp-1 ++0x1.e3c782bba8f90p-1 ++-0x1.e08b0317d404dp-1 ++0x1.290f1622d1939p-8 ++0x1.7edf2261fcf95p-1 ++-0x1.521241688012fp-2 ++-0x1.0307d4e8caa52p-18 ++-0x1.ccb366715602cp-1 ++-0x1.95aa45bfdf88bp-1 ++0x1.83b6d2241735cp-13 ++0x1.4977776659f91p-21 ++0x1.265e670e3a504p-1 ++0x1.857de2b5f1f7cp-1 ++-0x1.6e69d509bec68p-24 ++0x1.d4f0109417b1ap-1 ++0x1.9ab2842033f1fp-15 ++-0x1.17d9b0f3c22a2p-1 ++0x1.75a321c41a6b0p-1 ++0x1.53a5d3faa91ffp-1 ++-0x1.618c00bcdbb72p-1 ++0x1.e99bd19956904p-1 ++-0x1.89c34195ab10dp-21 ++-0x1.82b1234ed4accp-21 ++0x1.6b0486d8d09fbp-1 ++-0x1.4259822aefa37p-1 ++-0x1.ecfff733e7bb3p-2 ++-0x1.90eac37875516p-1 ++-0x1.ba38b666e3abap-6 ++0x1.1ebbb6284200ap-22 ++0x1.6c2ee1790a8b6p-1 ++-0x1.0c2d8105dd990p-1 ++-0x1.6d7264d3662ffp-1 ++-0x1.43fe90e13fc36p-4 ++0x1.46eb6152db91dp-10 ++0x1.e4e26333b349ep-4 ++-0x1.96ef543f5383cp-1 ++0x1.47dca56a5b223p-1 ++0x1.08ea668aed516p-4 ++0x1.ef8f3428ca661p-6 ++0x1.5b2b8480c515fp-10 ++-0x1.2762d191e5fa5p-1 ++0x1.508d56e0f5ca9p-1 ++-0x1.2f616558f0888p-24 ++0x1.0260d42d27c09p-11 ++-0x1.0988f69b99e16p-1 ++-0x1.d35697fcfb7b6p-14 ++0x1.ffaf01135dec7p-1 ++0x1.0afa01afd6afep-1 ++0x1.c7cbb635b5af3p-6 ++-0x1.23eb629a0abe4p-1 ++-0x1.b87e61aeac49bp-1 ++0x1.1646f4a28d191p-18 ++0x1.4cd3a045b9783p-1 ++-0x1.5c7a8599ffe9ap-14 ++-0x1.9457a34399b4ap-1 ++0x1.a154f6f6548e8p-1 ++0x1.ba8ad1105bb80p-6 ++0x1.af9176505fbeep-1 ++-0x1.430563677bff8p-8 ++0x1.a2a2d2a0778c3p-1 ++0x1.df4c731f44b97p-1 ++-0x1.d049e60c0ecd3p-23 ++-0x1.325e341d79998p-1 ++0x1.3da4954669e1fp-27 ++-0x1.88d501c9b4a1bp-8 ++0x1.f41c064c0c9bdp-1 ++-0x1.2e7715356184dp-16 ++-0x1.ab8a55eb84adfp-1 ++-0x1.b5e7918f752d5p-1 ++-0x1.c958c1faf2e05p-12 ++-0x1.0a0b95fda6377p-1 ++0x1.b05f4635c8e79p-1 ++0x1.a216642c8c3c6p-8 ++0x1.3049c686e99b7p-27 ++0x1.e5ea44ec320c1p-1 ++-0x1.884175facb7a0p-5 ++0x1.45aa62e647503p-13 ++-0x1.634bc7ff5c615p-1 ++0x1.b68125750b075p-9 ++-0x1.97abf0534746cp-15 ++0x1.f687e58a3b36ap-5 ++-0x1.1040e1ed1d1e7p-25 ++-0x1.6ba8e7fc4221fp-10 ++0x1.16e38001e0edbp-1 ++0x1.df2ad20740b3dp-26 ++-0x1.8e1172ae8c333p-1 ++-0x1.b22640bb7e540p-19 ++-0x1.fa5552ca0ed82p-13 ++-0x1.e8ad873f75a2dp-1 ++0x1.c91491a1a5938p-26 ++-0x1.4ec4473b27d56p-1 ++0x1.5f1862dba68cbp-1 ++-0x1.dce0e6290bc85p-1 ++0x1.fa68d22f5773bp-1 ++-0x1.919486a495542p-1 ++0x1.d303d564c000fp-1 ++-0x1.afff55716fe0bp-23 ++0x1.28b7d3631da7ap-16 ++0x1.9ca493208bbdep-1 ++-0x1.542a05a6b369fp-1 ++-0x1.f7e79460fc57ep-7 ++0x1.bb029019558b5p-15 ++0x1.bba002729f3d6p-1 ++0x1.1ada3533fa957p-1 ++-0x1.896d956b5743fp-21 ++-0x1.3a30147e08f69p-1 ++0x1.25644490a1259p-14 ++-0x1.4ef3744b5e468p-4 ++0x1.04dac7a84b2d7p-1 ++0x1.d46464683c4f8p-1 ++0x1.9c4674b85fc58p-9 ++-0x1.da6bd2cb0a530p-1 ++-0x1.eb2076f05f6f8p-1 ++0x1.4aeba21a72c73p-11 ++0x1.af7910337420fp-6 ++0x1.04ad609a3e62bp-1 ++0x1.eafe16a4433afp-1 ++0x1.1c65e51ff0cacp-1 ++-0x1.4eb61140c3e34p-1 ++-0x1.693d851f3cfeep-10 ++0x1.254d73366914dp-2 ++-0x1.ff34f15f5e3e6p-3 +diff -urN glibc-2.17-c758a686/benchtests/atan-inputs glibc-2.17-c758a686/benchtests/atan-inputs +--- glibc-2.17-c758a686/benchtests/atan-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/atan-inputs 2015-06-20 21:22:16.296458135 -0400 +@@ -0,0 +1,809 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.642175414a222p-3 ++0x1.32f96343ff094p47 ++0x1.63961340f55e3p-4 ++-0x1.404c80c42d2d7p3 ++0x1.ff0297a7f4cf9p-4 ++-0x1.3514d0a630343p2 ++-0x1.9cd792d24de9cp-13 ++0x1.48de0536fa639p-26 ++0x1.df679233e616cp3 ++-0x1.3672036e3b5dbp46 ++-0x1.a6af31fe26a67p1 ++-0x1.601447d82000cp-23 ++0x1.6978a3d8cdd0cp34 ++-0x1.bcf7074f6ad00p-20 ++0x1.4560113d34322p1 ++-0x1.88e3f71039a4bp-4 ++0x1.016652052d70ep6 ++0x1.4eeee5387c40fp-11 ++0x1.1a93e2edc9a70p-1 ++0x1.2a86a6b000b1bp19 ++0x1.b550a52791570p19 ++0x1.4f55e0fd66533p6 ++0x1.179893d68a175p0 ++0x1.c587a48440d49p18 ++0x1.c4d736b34755ep41 ++-0x1.0b00d1e309baap15 ++0x1.d3ddd7a4105b8p-17 ++0x1.907795ee90c71p1 ++0x1.1c0ee51bf3fbbp-26 ++0x1.6e21857f657b5p-3 ++0x1.522870681be34p0 ++-0x1.47fc357b48019p2 ++-0x1.fc80d2478d003p44 ++0x1.6b6af109c6d11p-2 ++-0x1.557b744e3f2b2p-2 ++-0x1.c0bd72f9dcc6fp-3 ++-0x1.5dad543b37a02p2 ++-0x1.d95b35b36eadep38 ++0x1.645042fa42207p-2 ++-0x1.139444200b144p1 ++-0x1.28a691f56455fp-24 ++0x1.d97ff36594800p-2 ++-0x1.c46e817205691p-1 ++0x1.189121c162006p-21 ++0x1.b22526da1b4b3p-25 ++0x1.89097738a1f84p23 ++-0x1.3de8b3a71241ep-4 ++0x1.d539d73aa3a6bp4 ++0x1.9f3aa3d8be109p-8 ++-0x1.28df31604ae5fp-2 ++-0x1.a5ba03c7f21c6p39 ++-0x1.0aa65539c9639p44 ++-0x1.596756edc8d29p-1 ++0x1.bf89523d6d9a8p18 ++0x1.245712c9030a1p-9 ++-0x1.e70de078fe520p-3 ++0x1.0a6a653edc9c8p-1 ++0x1.cc69116b071cdp-2 ++0x1.2f24c0cf8fcb2p-16 ++0x1.ed2ac30efc4e7p41 ++-0x1.db4970624d850p-4 ++-0x1.bb1260bff835cp-4 ++0x1.d685f1157cf4ap-4 ++-0x1.27241256d29b8p1 ++0x1.ec5380eff6d2ap-3 ++-0x1.fd7d8132290bep-1 ++0x1.228426a24d54dp-17 ++0x1.2ea847880a2cdp39 ++-0x1.89a5c5d485ab4p3 ++-0x1.fbd930c90d22cp3 ++-0x1.86674787bedeap3 ++0x1.ab27809f97987p1 ++0x1.c17c653258848p2 ++0x1.a3f615b4aa2afp-4 ++-0x1.e8bff4a769203p46 ++0x1.2fbb90ef75a25p-4 ++0x1.d9d246c3e5da7p10 ++0x1.1adf65737ce63p2 ++-0x1.4bbf56383d2c4p-20 ++0x1.1bc9009943672p2 ++-0x1.84cd8442450bcp24 ++-0x1.05cbc2307bc60p0 ++0x1.b18fc1de83969p-2 ++-0x1.a63bf1a32c82cp-26 ++0x1.08e7e57369c93p4 ++0x1.97e8f20d0a9f8p33 ++0x1.1358340c23f9dp-13 ++-0x1.f3a987156a953p-15 ++0x1.cc4fe36fcebc5p-3 ++0x1.d858d5bee5222p-2 ++0x1.8911076ba1dfep-5 ++0x1.5ab4754566467p1 ++0x1.854547561eabbp1 ++-0x1.830ce306fc8c4p-13 ++0x1.b181a4ed4c25ep-19 ++0x1.f77112499c880p30 ++-0x1.5124040e757ddp43 ++0x1.751c061e72f3dp-1 ++0x1.b88d87c4c86b2p-8 ++0x1.52c5b76c6ef89p-10 ++0x1.e89130ee99ce5p-4 ++0x1.2a2ed7a0b1956p-1 ++-0x1.47b533d254eb8p3 ++0x1.b4d0b69a8f4a8p-24 ++0x1.8316a4af1bf68p-18 ++-0x1.9e1ef1ccdd020p15 ++-0x1.88bde5f29b2d9p3 ++-0x1.365034bff4761p0 ++0x1.7e40940c2d5adp-17 ++-0x1.2c37625bfd76dp-18 ++0x1.707642d37610fp0 ++-0x1.afd1d0135cf31p3 ++-0x1.4b0d1755bbf42p-11 ++0x1.c4ed75b07c727p0 ++-0x1.5e2db71616c7ap1 ++0x1.050223b1cd624p3 ++-0x1.3b3db4aa80820p-10 ++0x1.5ccb8047d5d1ap12 ++0x1.175282b52f29cp0 ++0x1.aabc424c47eafp9 ++-0x1.1a90445a04e18p0 ++0x1.3da941dc72acdp2 ++0x1.501726cf3e259p-12 ++-0x1.1b3006e74e325p4 ++-0x1.ad42977bf9a2bp-1 ++0x1.73d0e25d9335ap-3 ++0x1.0a514560b1915p-4 ++0x1.9b955619c595bp-3 ++0x1.c1bde2d25803bp-2 ++-0x1.c9c450db85015p-24 ++-0x1.b93f27a390fc9p-3 ++0x1.394074cfa62d3p1 ++0x1.815072f52a2e6p0 ++0x1.1e52d6ee6069fp-1 ++0x1.1f90737198ea5p-19 ++0x1.13341218923f7p-23 ++0x1.348b0774c87ffp2 ++0x1.d2580731da42cp2 ++0x1.87b5a06e57762p-5 ++0x1.b40fd58aea62ap0 ++0x1.9cd365175d628p28 ++-0x1.4094703aac68bp-24 ++0x1.56af03795574fp21 ++-0x1.e189800006571p-26 ++-0x1.9dfb51f7b789cp47 ++0x1.9bc2e73963ca7p11 ++0x1.b5a1c0632322cp0 ++0x1.205e5539779c2p51 ++-0x1.6c47a5b0217f6p2 ++0x1.791cd37782384p-2 ++0x1.231d31372c140p1 ++0x1.91e2d31efbcaap-3 ++0x1.34fa969626571p30 ++-0x1.6bc04360963b5p-11 ++0x1.8add0065da1d5p-4 ++-0x1.d346e1877a7fdp-2 ++-0x1.725697ff5c03dp1 ++0x1.a8e2a686fd172p-1 ++-0x1.8bd725c48f410p3 ++-0x1.3b0537b22c0bbp-1 ++-0x1.2c0db2781aad0p28 ++0x1.4c6a110727b7fp-16 ++0x1.b8d171996cbe1p0 ++0x1.e6c6d70c497a0p19 ++-0x1.15a9f10771286p2 ++-0x1.c30f24893d7a3p-3 ++-0x1.d73aa26a08a23p38 ++-0x1.58b7549a93d13p-4 ++0x1.169012651035fp1 ++0x1.197ee4c04ae17p25 ++0x1.3fba00276eae3p1 ++0x1.941d03c4bf6a6p-4 ++0x1.7f21c64e2abb7p-2 ++0x1.7581d56332d79p0 ++0x1.971980a7e2435p27 ++-0x1.e44690996dde4p-8 ++-0x1.3133113da7775p-20 ++0x1.31d201884c815p30 ++0x1.1f46672b184b2p-20 ++-0x1.bbbc31b0259d6p7 ++-0x1.ff6f625bf7eadp-1 ++-0x1.3dd6a5e841573p-1 ++-0x1.294b2242985c5p-5 ++0x1.80c6d17d3b82ep41 ++0x1.66a703915eafdp-4 ++0x1.c16431985801dp28 ++-0x1.66cc363cc169cp-13 ++-0x1.445ac6d7de615p29 ++-0x1.78d803eac6a4fp-17 ++0x1.7d17f2f5981bdp-4 ++-0x1.be3452bcdc974p28 ++0x1.83dff4dfc4757p42 ++0x1.451781735f844p14 ++-0x1.4dab41db1c970p3 ++0x1.3373037f37040p2 ++0x1.20f7623057a1cp-4 ++0x1.b74c37f7006cfp36 ++0x1.6d17f13894ea6p-8 ++-0x1.9084f58ffff58p1 ++-0x1.c57ef7f9833e1p-3 ++-0x1.943ce31bfd282p-26 ++-0x1.75a42576fe1cdp1 ++0x1.ff0257a993250p2 ++-0x1.63ef308e427d4p0 ++0x1.de26003f5ba7ep16 ++0x1.15333549fa76fp29 ++0x1.66bfb50c269e7p0 ++0x1.a49604cc4d7f9p-4 ++-0x1.15003315471d9p-4 ++-0x1.38bed20a51ff5p-9 ++0x1.7d97f5b7805ddp-19 ++-0x1.7a3244a0e1b3ep-2 ++0x1.ed0681d4ee226p50 ++-0x1.15a691a22afc6p-4 ++-0x1.d2c15149a171cp48 ++-0x1.d395408686509p1 ++0x1.d121d5a063487p-27 ++-0x1.159dc08e6bae4p-18 ++0x1.835914ed4ac69p46 ++-0x1.f45bc1593e631p-2 ++-0x1.abaf42742e1aep0 ++0x1.f67cc57a82279p22 ++-0x1.3cdc56ba8ad80p0 ++-0x1.5a8f042e5c06dp-4 ++0x1.306774727b9c8p-5 ++-0x1.0f21118d78a86p1 ++-0x1.abbcc62ae1185p-17 ++-0x1.ff75940794858p3 ++-0x1.6048b6174f2dap-3 ++-0x1.84f4968e9a1a0p3 ++-0x1.ecc9025c45c61p-9 ++0x1.d9cd03dc0d910p-18 ++0x1.cd846319c00c5p-3 ++0x1.6366066bd94a6p3 ++-0x1.8ebc74865b7b3p1 ++-0x1.b87c63e47576cp-3 ++0x1.c45cb0d4685f5p-3 ++-0x1.e702b4a6029fcp35 ++0x1.fc6300b9b675ap3 ++-0x1.3f43a795e244ep0 ++-0x1.f1cd009ef1604p3 ++-0x1.d2fbd2cc79418p11 ++0x1.907fd4f15d9d3p-10 ++0x1.a371220d3cd1ep43 ++0x1.df8544d34e26dp26 ++0x1.acb3279e8da17p-18 ++0x1.b1ea21e59afd9p-4 ++-0x1.e0dff1828b454p-4 ++0x1.ef38b267b4663p39 ++-0x1.baba241cd2232p-13 ++0x1.4fe7c7cd05a69p46 ++-0x1.988073a34d2c8p29 ++0x1.7599e0ac9a522p-8 ++0x1.251b26c85badap52 ++-0x1.a27c560a7da35p0 ++-0x1.f091c7c2304a2p17 ++-0x1.d0e1114b97abfp-13 ++0x1.33ee35cf8c72ap1 ++-0x1.e714e1fed73c4p-2 ++0x1.1292e4e843885p-3 ++-0x1.03fcc540c9867p22 ++0x1.a53c8268c5213p-2 ++-0x1.f16e3196353c0p-20 ++0x1.e88a97bf39b0cp14 ++0x1.4f00111aae17fp13 ++-0x1.388bf2c171982p-1 ++0x1.0f70b2319de14p-3 ++0x1.e95a75a9609e3p-1 ++-0x1.1047552b4d153p2 ++0x1.091e73082965cp0 ++0x1.2560a7de1090ep-26 ++0x1.b7fde3097d182p-20 ++0x1.c7f115eabfdedp-4 ++-0x1.e99523e282a43p40 ++-0x1.960706b024814p-3 ++0x1.6ca4d098808a9p41 ++-0x1.782a50dd85179p50 ++-0x1.26e3c42a5f2d2p1 ++0x1.ca282036f2b8cp-10 ++0x1.87d031409e3e4p-17 ++0x1.a80f97461a0f4p-3 ++0x1.66ed5379b1601p45 ++-0x1.081bb51f6296ep21 ++-0x1.a51801c3b0ab4p-3 ++-0x1.f9af91b1e0eacp-4 ++0x1.f59650108c48fp1 ++0x1.085c309bbe310p0 ++-0x1.b9fea5e346036p1 ++-0x1.453542b905ad4p24 ++-0x1.e66c14b55c117p1 ++-0x1.90a6830407ac7p40 ++0x1.9bc93234caf93p26 ++0x1.4b94104f5f41ap-3 ++-0x1.c7b564e75a382p50 ++-0x1.c2b250afb59e8p13 ++-0x1.bfb283faeefbfp2 ++-0x1.173235dbdbca5p-10 ++-0x1.ac62c7b5e878bp-4 ++-0x1.c2a9461c28ecdp-17 ++0x1.1e1bf4bfee9b2p1 ++-0x1.c6a1a78876ab6p0 ++-0x1.e6fb5111565c8p3 ++-0x1.8932b58866bcfp-19 ++0x1.6407a070f3a3fp12 ++0x1.87a1b1adaed03p-4 ++0x1.e5ebf4ac465b1p-4 ++-0x1.f8d5e0b5c2957p20 ++0x1.42836589a8c0dp31 ++-0x1.d1ad755010ed1p-4 ++0x1.3d1f16896735ep-1 ++0x1.fdaba0fd40c7cp31 ++0x1.3311135efe06dp-3 ++0x1.b5dc02c3070d2p-2 ++-0x1.04d741eec5058p-23 ++0x1.a80bc579c9a9bp3 ++0x1.4766230792559p1 ++-0x1.a5cbe4d7cc609p-3 ++-0x1.ba1d23d80c32fp-11 ++-0x1.daaf8434d9034p-13 ++-0x1.c65d358dac3fep-11 ++-0x1.3f4da10042b42p2 ++0x1.262fa4579b063p-7 ++0x1.914e60ffdbed8p-4 ++-0x1.efac261144868p-9 ++0x1.ce397251fa408p-4 ++0x1.be05d28ca250ap-11 ++-0x1.7479b7fa984ddp-3 ++-0x1.ac20c42062d2fp2 ++0x1.9a487118946dap-4 ++0x1.2a124744f9fa4p47 ++0x1.b1981261f9020p-1 ++0x1.fbf7179ce5846p-2 ++0x1.22fbd75358604p-23 ++0x1.b1b2a4bcce5acp34 ++0x1.84e62689c678dp-19 ++-0x1.0b3bf5d136f5fp-25 ++0x1.f93ce18d93227p-15 ++0x1.bbd3b6a42bc58p-22 ++-0x1.47b315f8194ebp27 ++-0x1.827896462fb0cp-18 ++0x1.2947c23116c19p-2 ++0x1.3466e4652adedp1 ++-0x1.23c2a01c6daddp-11 ++-0x1.5831b4a29e94ep-2 ++0x1.4a7fb41fb32ccp-24 ++0x1.77544628d33f4p2 ++0x1.40a5220c05f84p43 ++-0x1.859503fac777cp-1 ++0x1.629111fdc02f9p49 ++0x1.f72960081155dp-24 ++0x1.100cb00f41850p0 ++-0x1.1280f391f830bp8 ++-0x1.2e93552200855p1 ++-0x1.4621063cd9ecdp-12 ++0x1.1c4111533addep-25 ++-0x1.569560309d6bbp-22 ++-0x1.7a8124168d622p3 ++0x1.17fba47954943p-4 ++0x1.0672546df1e40p-4 ++0x1.3157a7fbb3b2ap2 ++0x1.a82f370a40ce4p2 ++-0x1.a8fac6ce90f3cp1 ++0x1.0f28d09b57a07p0 ++0x1.da30a55a75636p2 ++-0x1.4a8a0783b2ccdp-3 ++-0x1.79e674173ab88p-1 ++0x1.c89b61641fceep31 ++-0x1.0f8107e6388fbp3 ++-0x1.f720f120f5f1fp-22 ++0x1.144b44598ac02p-4 ++-0x1.ceb152c076922p-3 ++-0x1.4b12e43d683a4p0 ++0x1.c0ae8156c4455p-3 ++0x1.85c10724ee68cp-3 ++0x1.3c4635592b9ffp-3 ++-0x1.d59892bee5390p-4 ++-0x1.cd1280ceab8c4p-3 ++0x1.b622b71aa922bp8 ++-0x1.2795c18e21649p-15 ++-0x1.639d32c619c4bp-19 ++-0x1.e8f917ef054dfp-8 ++0x1.c9eca4e44a7b1p1 ++0x1.be86276e10fa9p3 ++0x1.750cd40dd63b8p-24 ++-0x1.033ab125bb64ep-18 ++-0x1.9679b2912fcecp-4 ++0x1.f7b3a1afd048dp-23 ++-0x1.9f2863bcb1fd6p1 ++0x1.c7fed1051dcb2p4 ++0x1.c23ec470a9239p-7 ++-0x1.1e5006f62ba49p1 ++-0x1.0d9f216fea290p3 ++0x1.bd8340ad169bap46 ++0x1.dac8831aa29d9p3 ++0x1.7c191598763c2p1 ++-0x1.121aa313ac95bp33 ++-0x1.b0996534e93cep-2 ++-0x1.6c8353699c9c6p-1 ++-0x1.5df8208f06792p3 ++-0x1.4657113ffa73fp28 ++0x1.48a901159abe7p0 ++0x1.70e4b3448f927p50 ++-0x1.e120d621edccap-4 ++-0x1.4f2900d44caa5p1 ++-0x1.848165627b209p-5 ++-0x1.4cd082b565a11p-16 ++-0x1.d9d2d7967af18p-1 ++-0x1.222be1230bd8dp0 ++-0x1.361e6586e20d9p16 ++-0x1.3ddd364c29946p-19 ++0x1.3ee601f53dafap-18 ++0x1.e37ab68eb3013p45 ++-0x1.0b8a978bd97b9p2 ++-0x1.9589707e8a6ddp-20 ++0x1.b7ca368b81375p-4 ++0x1.2a7b114a80983p0 ++-0x1.8c0fd1048891ep-4 ++0x1.c32454b620d43p-26 ++0x1.853192a0e3bbbp-14 ++0x1.172b96d182f82p-2 ++0x1.4156741896c30p-3 ++-0x1.dd08573a1dc08p-3 ++-0x1.f112f2dfd0c38p23 ++0x1.f07ef18d186acp-9 ++0x1.b0b643dc8187bp-2 ++0x1.edf9044a400ccp-26 ++-0x1.420ee09a253bbp-16 ++-0x1.ce5f43fa6c0e8p0 ++-0x1.b49ed6fe33c01p-2 ++0x1.bc1e67b736d93p27 ++0x1.18f252a5a70f2p-1 ++0x1.3bd3528a6b5c3p-25 ++0x1.042f039297e45p0 ++0x1.890e26c77777ap2 ++0x1.ec331761880b9p39 ++-0x1.12aec65364402p2 ++-0x1.b09600801c6c9p7 ++0x1.4c14331304537p36 ++-0x1.366b32ae15936p-9 ++-0x1.d04011bd2f923p-27 ++-0x1.bb73e632734cap51 ++-0x1.22df928d0db2bp14 ++-0x1.84d2c65e8a597p-4 ++-0x1.248ce4d82f9e1p-3 ++-0x1.a89a16ab8fc98p41 ++-0x1.22061604a7bbep-1 ++-0x1.9b7790ad6cfcap37 ++0x1.e146126a58363p-20 ++0x1.8bf9d0bee4587p-6 ++-0x1.74eec1eb48a38p18 ++-0x1.1eca65e42c0e2p-24 ++-0x1.5f6e27219b443p5 ++-0x1.95f64657f34b0p1 ++-0x1.ad0923f0c8747p-14 ++-0x1.71b7472c93381p2 ++-0x1.e88ec0fa2b8e2p40 ++0x1.0efad07b1325cp-2 ++-0x1.d614b725644c2p-11 ++-0x1.87f104d664989p-4 ++0x1.db8bf75a3dabcp25 ++0x1.18a07441e9358p-3 ++0x1.c52552071ba9dp2 ++0x1.4eee532e1cf42p-2 ++-0x1.acd7a7d0cb2d2p49 ++-0x1.efdbb63ba4cd9p3 ++-0x1.c0dbd4011e3dbp14 ++0x1.a8b9053cd4ae7p-26 ++0x1.950f208f9f314p-3 ++0x1.62bc1534e8779p1 ++0x1.ec8712224e21dp5 ++-0x1.dcf2f55094df3p-4 ++-0x1.13a10025de14cp1 ++-0x1.275ce549521b9p-1 ++-0x1.2d3995ba1b17bp-5 ++-0x1.a76630717c0c6p3 ++-0x1.b2ec655611d3ep38 ++-0x1.9bd4a62004f97p-20 ++-0x1.49dcb6df53770p1 ++-0x1.2b34c0811030cp-3 ++0x1.99ee70ec910aap-21 ++0x1.35b201aa1e70bp-3 ++-0x1.92a3000ee8dd4p-2 ++-0x1.d69d60b48249fp3 ++0x1.eee73555cf4d5p-3 ++-0x1.07de748dacd3ap12 ++-0x1.a8ea7383f8f09p8 ++-0x1.eca3120c1f7cep1 ++-0x1.8b4b26d9f4eabp51 ++0x1.167433f50737ep-23 ++0x1.585657c46c25ap-20 ++0x1.0e0447b473e54p2 ++0x1.b28d209b03f59p-4 ++0x1.9a8d34b2b2855p-25 ++0x1.948ac6afc0f37p3 ++-0x1.563cf374c073fp-4 ++0x1.fa49e687bce32p42 ++0x1.c42c2624133c2p48 ++-0x1.001e573a69113p2 ++-0x1.4dfb17453411bp-3 ++-0x1.d9b9b553ab45fp23 ++0x1.55496452db316p3 ++-0x1.8420d7f1ac33ep3 ++-0x1.ac7cd42b0f63ep2 ++0x1.ce2970c35394cp2 ++-0x1.de2ce25feb1e3p-16 ++0x1.4fe2152fd9407p-2 ++0x1.4d4233d0400d2p1 ++0x1.f4c640fdd48b2p-10 ++0x1.1512c1316465ap37 ++0x1.b584b29dc1d4bp22 ++-0x1.695e973f8db94p-1 ++0x1.7373d677b7679p24 ++0x1.f899a57b746b9p-22 ++-0x1.f5ad761b38217p0 ++0x1.daf950a02a029p1 ++0x1.a9c47461369bcp-7 ++0x1.a66902e961fe5p-2 ++-0x1.f6bc5292eadcep2 ++-0x1.0377673b5656cp20 ++-0x1.269297562701dp-4 ++0x1.13d1e1e922a15p3 ++-0x1.ddf1d5cfbfb4dp-20 ++0x1.6c21328fa2eacp0 ++0x1.953fe3186fbacp0 ++-0x1.2ed5d49aee19cp-15 ++-0x1.d3e9f10d61fa8p-4 ++0x1.5315517278bffp-4 ++-0x1.aeeb36df95b57p26 ++0x1.9f55b3bd1d398p2 ++0x1.894151536709bp3 ++-0x1.93a3d5c645e3fp22 ++-0x1.37803538f3548p43 ++-0x1.d5dde10bc588fp-23 ++0x1.f145117569f10p4 ++-0x1.ca23009d83541p0 ++-0x1.fc4063d4a4afep23 ++-0x1.ec88c7edb5ae2p-6 ++-0x1.2d5973fcaa823p-21 ++0x1.437a141589287p2 ++-0x1.9104e694ef44ap-2 ++-0x1.b70572032d576p-7 ++0x1.d10452e3eae69p2 ++0x1.2874b443d01bcp0 ++0x1.fa66d12189a72p20 ++-0x1.303e443c556d3p46 ++0x1.4b5d557e8fe56p44 ++0x1.602bb4e791b87p-20 ++-0x1.158f81cbcb150p-3 ++-0x1.36a3939175212p3 ++-0x1.826092fe525c4p-19 ++-0x1.a72da4879bcb1p-26 ++0x1.839626b74c51ap-1 ++-0x1.bd2da6527d628p5 ++0x1.3257e0dc99c46p-23 ++-0x1.b3ebe0c2317c6p3 ++0x1.1164968b6d3d2p-4 ++0x1.bd5404092a649p30 ++-0x1.dd0e00246fdf1p-3 ++-0x1.4167e56920aa2p6 ++-0x1.b035570fa59c8p-1 ++0x1.7853f4cf90bbcp15 ++0x1.bc20a74a4c2dbp-18 ++0x1.0e3ee3d24bf54p3 ++-0x1.95aab56378e9cp45 ++-0x1.4930a7aa51e8dp1 ++0x1.ea77407c9a5f1p-1 ++0x1.4fac93644de62p-3 ++0x1.a2ed87cc0f417p43 ++0x1.14d2d0a33df56p2 ++-0x1.3473f6f77b6c5p11 ++0x1.b647101dc4177p3 ++-0x1.4e0b92acc66bfp23 ++0x1.2a3797d36ee30p-4 ++0x1.ce10973c013ebp-14 ++0x1.b6cef57406772p2 ++-0x1.326762c9ea656p-22 ++0x1.56473079b28aap24 ++-0x1.46f3d42d9a8dap-11 ++-0x1.6d4e52e373151p-7 ++0x1.622a0570fc4abp11 ++-0x1.7e0bb32e21466p-6 ++0x1.55a1a3d809d3ep1 ++-0x1.d7492480e11f5p32 ++0x1.835730d6b3ef6p-18 ++0x1.2d9cf79f070e8p-9 ++-0x1.6cee95c1d9445p26 ++0x1.45c58441f2822p-3 ++0x1.2f01d75200b30p21 ++-0x1.014c5172af434p0 ++0x1.9d96552d416d8p3 ++0x1.f878a3fc8f55fp-3 ++0x1.1206f1aa29231p1 ++0x1.998bc480cbf5dp-3 ++0x1.2160c0ab74e78p41 ++0x1.66cce4923857ap-6 ++-0x1.47bf27bfba3adp-3 ++-0x1.88b9442658583p-13 ++0x1.baf0076743831p2 ++-0x1.d7a664adbb965p-22 ++0x1.8bfbf37ef0c90p22 ++-0x1.a2b137086be2cp9 ++0x1.b8fa2667197acp29 ++0x1.2e9ee649d720ap-2 ++0x1.fd42f19ae5dfdp-15 ++0x1.b4c7c70a22018p38 ++0x1.6fee027ca714ap-18 ++0x1.b986a428fdeebp-9 ++-0x1.f63c6744cafc4p-7 ++-0x1.860b9508a01c2p-4 ++0x1.c9dbe26d13605p-7 ++-0x1.e5af65a0da055p-4 ++0x1.2f48357a95e60p-3 ++0x1.afac3209945f4p-11 ++0x1.e24230fc8430fp-1 ++0x1.555f1605043d9p40 ++-0x1.42c7b6d8c6b89p-4 ++0x1.f5e416fab1768p24 ++0x1.4379506da570ep10 ++-0x1.c38b2527d3a6ap0 ++-0x1.ecf007e1a6728p-3 ++0x1.636eb2220b2c2p-18 ++0x1.7609e702937b8p2 ++0x1.2db5d31780fa5p3 ++-0x1.221c240b15183p-3 ++0x1.084b249033af8p-19 ++-0x1.69c8f54230d4cp2 ++-0x1.5458a621ac511p0 ++0x1.c8b53281fbad0p-15 ++0x1.0c8ac2d6bf8cep-22 ++-0x1.28b804bea1e7fp3 ++0x1.919d64a75bf39p-9 ++0x1.4c0b078f754a4p-1 ++-0x1.dd7405983ab97p-20 ++0x1.ba2103a39b033p19 ++-0x1.b21fc106586d2p0 ++0x1.eacb558bbd5dap1 ++-0x1.058304cdc51f1p-2 ++-0x1.e530d67d5c413p15 ++0x1.9efc141496268p-21 ++0x1.9e43436405397p-2 ++0x1.d6c5d5f5dcc9fp-22 ++0x1.2f0540658e814p1 ++0x1.89ea31cb96062p1 ++0x1.c9d690079576dp-7 ++0x1.9b1ef5b23f047p-2 ++-0x1.c1e61429c45fbp43 ++0x1.248b34f22e7e1p-26 ++0x1.0dc2918fd3196p-15 ++0x1.a17a2260c8d58p18 ++-0x1.a088140ade389p19 ++0x1.8b92c2168e33fp40 ++0x1.69ab67a22bbbcp0 ++-0x1.343232b010a37p-17 ++-0x1.0c4932248f574p0 ++-0x1.2bdc378a38991p-2 ++0x1.2d563370110dap-12 ++0x1.a27134171f37dp-4 ++0x1.fa63324eb71a3p26 ++0x1.6f50c55b7950ep-21 ++-0x1.0486e73eca0d8p45 ++-0x1.fa20f7947f447p-3 ++0x1.0439c6fe1a62ep2 ++0x1.4e5d366349911p2 ++0x1.985933b0a27d6p-2 ++0x1.bf592781e0417p-4 ++0x1.bd39f070daca3p-4 ++0x1.0130b7296f20dp0 ++-0x1.299cc68ec2149p2 ++-0x1.6d9fc7a6e0946p0 ++0x1.b42110fb94ad0p31 ++0x1.b59970f83df8ep1 ++0x1.c4083529ddeb8p38 ++0x1.ac3bb44cafe59p1 ++0x1.6d66733b81b71p-11 ++0x1.20beb78f7ceeep-16 ++0x1.d285f704a02d5p-4 ++0x1.bf37a3dc305b1p37 ++-0x1.8852a20307706p1 ++0x1.8129a11b33c67p31 ++0x1.1b31565ac4d26p38 ++0x1.efe3d79df1a25p0 ++-0x1.df4fc61097087p34 ++-0x1.801e6310f70c4p1 ++0x1.de7fc178da718p1 ++0x1.82cd96b74c33bp-3 ++0x1.14ce177c73acbp2 ++-0x1.b8bfa6f20bf6cp-4 ++0x1.04ff06087395bp-9 ++-0x1.8327b171d58abp-4 ++-0x1.8cabe7b5327bap-3 ++-0x1.82c492035cf5bp24 ++-0x1.d85a267d87555p-24 ++-0x1.efdc44b7fb121p24 ++0x1.ea99c6cf2fd74p-17 ++0x1.3fb6671f607b1p1 ++0x1.97dce09249de2p-3 ++-0x1.9dc4f0331f52cp43 ++0x1.ea7d727d27334p41 ++-0x1.ec9d516a85c75p-25 ++-0x1.bb2176abaedd1p-3 ++-0x1.71eeb273dd3adp-15 ++-0x1.7be385146ccdep25 ++0x1.c1f987ad8af62p-6 ++0x1.2159279f1c89ap2 ++-0x1.4805b43babc89p-17 ++-0x1.c16834d0d845ap-20 ++0x1.c52f537caeb0ep10 ++0x1.14d5e5a6c66f8p52 ++0x1.2f929423ad32fp0 ++0x1.e9ce62b513428p-4 ++-0x1.8a14f3724eb37p32 ++0x1.64013151734fdp3 ++-0x1.9090f39f49889p23 ++0x1.be6b47a137a52p-12 ++0x1.59a42749fd7c3p1 ++0x1.8603f544b0976p-15 ++-0x1.4d2ba3dfaeb93p-2 ++-0x1.7d770619d5bc3p12 ++0x1.edfb87aaee9b1p1 ++-0x1.f23d94e870be7p-4 ++-0x1.21500514f25d3p41 ++0x1.cb8712f937eedp-15 ++0x1.fb47c7a69d8a4p-24 ++0x1.f1c904cd2e471p-12 ++-0x1.31e6e3b7073f8p0 ++-0x1.facd32a72c5a8p2 ++-0x1.9823a41a9780ap-3 ++0x1.3db1f5e2a9a51p51 ++0x1.6344057f1cca6p-1 ++-0x1.8be6128041ebfp-13 ++0x1.6f07c272d7fe9p38 ++-0x1.fd48060bf89bfp-5 ++-0x1.82eb1727ca16ep-2 ++0x1.26e0a24f2ec11p-18 ++-0x1.74a1c0cb9d677p-14 ++-0x1.bb0c36f1bb121p0 ++-0x1.56a4873461187p1 ++-0x1.d01e65e325d8dp2 ++-0x1.5250308bc28a5p36 ++-0x1.83c6f31f2de0fp-24 ++-0x1.41ae76e29ab40p1 ++-0x1.d738a56bac094p1 ++0x1.1a5247926ba82p-14 ++0x1.d703938b24ac4p-22 ++-0x1.cc5566621df4fp-4 ++-0x1.4144e3f175873p-4 ++0x1.a41e208bd59c2p-4 ++-0x1.8588a53e4e022p8 ++0x1.cf4331e97df52p-27 ++-0x1.d70843f5b2a7bp-8 ++-0x1.b1a912cdf744ep-3 ++0x1.ad44072bba2efp-15 ++-0x1.735cf794885b0p25 ++-0x1.94d98257a7443p-4 ++-0x1.61dac14e8c1f2p1 ++0x1.f71585bdc20e7p-20 ++-0x1.3338f2e1ebed7p-2 ++-0x1.044ab29dd3fd8p-1 ++0x1.b230868e79405p-25 ++0x1.c3539439a1ce3p15 ++-0x1.2998d58d65498p-4 ++0x1.7273d75dd90f5p0 ++-0x1.6214d3e6a209fp32 ++-0x1.3b2aa66ea6fd8p-3 ++-0x1.6cc910ca7817ap-4 ++-0x1.1194f4be56f5bp28 ++-0x1.6dc3114d423c9p2 ++-0x1.b447e098a3c6fp18 ++-0x1.705865523468cp15 ++-0x1.8e6752f060479p38 ++-0x1.ebe665ab9b23ap3 ++0x1.df6ee1073afd0p32 ++-0x1.35ce11e0f4a42p5 ++0x1.7c26f0a48edd9p-3 ++0x1.af1996c678e0dp28 ++0x1.c4ea4704b4de2p2 ++0x1.697b37d6b070dp19 ++0x1.49fa574ba1eccp52 ++-0x1.695ee7cc1ce8ep48 ++-0x1.169c757dd823dp-23 ++0x1.207273ac379a1p-4 ++0x1.7c2dc5c85d916p23 ++0x1.fe02e67c4ccbfp-24 ++0x1.accc401e13286p49 ++-0x1.af3426c709c78p-18 ++-0x1.ab2ca07faba33p-4 ++0x1.aeaaf4f90a9c1p-4 ++-0x1.84f781f4efe2cp-9 ++-0x1.d885871aa2240p-9 ++-0x1.a618720ac58c4p-22 ++-0x1.9b995257a7ee5p-6 ++-0x1.f68b46a30839ep-18 ++0x1.e1443653f9257p3 ++0x1.ce1a94d5c772cp-22 ++0x1.b24255d0a3ce2p38 ++0x1.2eaa6690d786ep2 ++0x1.b5bb45a608da6p0 ++-0x1.ead7509b0d69ep26 ++0x1.86fa30e0b406ep3 ++-0x1.acd451c3cb8b6p49 ++# atan slow path with 144bit precision ++# Implemented in sysdeps/ieee754/dbl-64/mpatan.c ++## name: 144bits ++0x1.000000c5cba87p0 ++0x1.000001883003bp0 ++0x1.00000dfb2b675p0 +diff -urN glibc-2.17-c758a686/benchtests/bench-bcopy.c glibc-2.17-c758a686/benchtests/bench-bcopy.c +--- glibc-2.17-c758a686/benchtests/bench-bcopy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-bcopy.c 2015-06-20 21:22:16.296458135 -0400 +@@ -0,0 +1,20 @@ ++/* Measure bcopy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_BCOPY ++#include "bench-memmove.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-bzero.c glibc-2.17-c758a686/benchtests/bench-bzero.c +--- glibc-2.17-c758a686/benchtests/bench-bzero.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-bzero.c 2015-06-20 21:22:16.296458135 -0400 +@@ -0,0 +1,19 @@ ++/* Measure bzero functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#define TEST_BZERO ++#include "bench-memset.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-malloc-thread.c glibc-2.17-c758a686/benchtests/bench-malloc-thread.c +--- glibc-2.17-c758a686/benchtests/bench-malloc-thread.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-malloc-thread.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,302 @@ ++/* Benchmark malloc and free functions. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "bench-timing.h" ++#include "json-lib.h" ++ ++/* Benchmark duration in seconds. */ ++#define BENCHMARK_DURATION 60 ++#define RAND_SEED 88 ++ ++#ifndef NUM_THREADS ++# define NUM_THREADS 1 ++#endif ++ ++/* Maximum memory that can be allocated at any one time is: ++ ++ NUM_THREADS * WORKING_SET_SIZE * MAX_ALLOCATION_SIZE ++ ++ However due to the distribution of the random block sizes ++ the typical amount allocated will be much smaller. */ ++#define WORKING_SET_SIZE 1024 ++ ++#define MIN_ALLOCATION_SIZE 4 ++#define MAX_ALLOCATION_SIZE 32768 ++ ++/* Get a random block size with an inverse square distribution. */ ++static unsigned int ++get_block_size (unsigned int rand_data) ++{ ++ /* Inverse square. */ ++ const float exponent = -2; ++ /* Minimum value of distribution. */ ++ const float dist_min = MIN_ALLOCATION_SIZE; ++ /* Maximum value of distribution. */ ++ const float dist_max = MAX_ALLOCATION_SIZE; ++ ++ float min_pow = powf (dist_min, exponent + 1); ++ float max_pow = powf (dist_max, exponent + 1); ++ ++ float r = (float) rand_data / RAND_MAX; ++ ++ return (unsigned int) powf ((max_pow - min_pow) * r + min_pow, ++ 1 / (exponent + 1)); ++} ++ ++#define NUM_BLOCK_SIZES 8000 ++#define NUM_OFFSETS ((WORKING_SET_SIZE) * 4) ++ ++static unsigned int random_block_sizes[NUM_BLOCK_SIZES]; ++static unsigned int random_offsets[NUM_OFFSETS]; ++ ++static void ++init_random_values (void) ++{ ++ for (size_t i = 0; i < NUM_BLOCK_SIZES; i++) ++ random_block_sizes[i] = get_block_size (rand ()); ++ ++ for (size_t i = 0; i < NUM_OFFSETS; i++) ++ random_offsets[i] = rand () % WORKING_SET_SIZE; ++} ++ ++static unsigned int ++get_random_block_size (unsigned int *state) ++{ ++ unsigned int idx = *state; ++ ++ if (idx >= NUM_BLOCK_SIZES - 1) ++ idx = 0; ++ else ++ idx++; ++ ++ *state = idx; ++ ++ return random_block_sizes[idx]; ++} ++ ++static unsigned int ++get_random_offset (unsigned int *state) ++{ ++ unsigned int idx = *state; ++ ++ if (idx >= NUM_OFFSETS - 1) ++ idx = 0; ++ else ++ idx++; ++ ++ *state = idx; ++ ++ return random_offsets[idx]; ++} ++ ++static volatile bool timeout; ++ ++static void ++alarm_handler (int signum) ++{ ++ timeout = true; ++} ++ ++/* Allocate and free blocks in a random order. */ ++static size_t ++malloc_benchmark_loop (void **ptr_arr) ++{ ++ unsigned int offset_state = 0, block_state = 0; ++ size_t iters = 0; ++ ++ while (!timeout) ++ { ++ unsigned int next_idx = get_random_offset (&offset_state); ++ unsigned int next_block = get_random_block_size (&block_state); ++ ++ free (ptr_arr[next_idx]); ++ ++ ptr_arr[next_idx] = malloc (next_block); ++ ++ iters++; ++ } ++ ++ return iters; ++} ++ ++struct thread_args ++{ ++ size_t iters; ++ void **working_set; ++ timing_t elapsed; ++}; ++ ++static void * ++benchmark_thread (void *arg) ++{ ++ struct thread_args *args = (struct thread_args *) arg; ++ size_t iters; ++ void *thread_set = args->working_set; ++ timing_t start, stop; ++ ++ TIMING_NOW (start); ++ iters = malloc_benchmark_loop (thread_set); ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (args->elapsed, start, stop); ++ args->iters = iters; ++ ++ return NULL; ++} ++ ++static timing_t ++do_benchmark (size_t num_threads, size_t *iters) ++{ ++ timing_t elapsed = 0; ++ ++ if (num_threads == 1) ++ { ++ timing_t start, stop; ++ void *working_set[WORKING_SET_SIZE]; ++ ++ memset (working_set, 0, sizeof (working_set)); ++ ++ TIMING_NOW (start); ++ *iters = malloc_benchmark_loop (working_set); ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (elapsed, start, stop); ++ } ++ else ++ { ++ struct thread_args args[num_threads]; ++ void *working_set[num_threads][WORKING_SET_SIZE]; ++ pthread_t threads[num_threads]; ++ ++ memset (working_set, 0, sizeof (working_set)); ++ ++ *iters = 0; ++ ++ for (size_t i = 0; i < num_threads; i++) ++ { ++ args[i].working_set = working_set[i]; ++ pthread_create(&threads[i], NULL, benchmark_thread, &args[i]); ++ } ++ ++ for (size_t i = 0; i < num_threads; i++) ++ { ++ pthread_join(threads[i], NULL); ++ TIMING_ACCUM (elapsed, args[i].elapsed); ++ *iters += args[i].iters; ++ } ++ } ++ return elapsed; ++} ++ ++static void usage(const char *name) ++{ ++ fprintf (stderr, "%s: \n", name); ++ exit (1); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ timing_t cur; ++ size_t iters = 0, num_threads = 1; ++ unsigned long res; ++ json_ctx_t json_ctx; ++ double d_total_s, d_total_i; ++ struct sigaction act; ++ ++ if (argc == 1) ++ num_threads = 1; ++ else if (argc == 2) ++ { ++ long ret; ++ ++ errno = 0; ++ ret = strtol(argv[1], NULL, 10); ++ ++ if (errno || ret == 0) ++ usage(argv[0]); ++ ++ num_threads = ret; ++ } ++ else ++ usage(argv[0]); ++ ++ init_random_values (); ++ ++ json_init (&json_ctx, 0, stdout); ++ ++ json_document_begin (&json_ctx); ++ ++ json_attr_string (&json_ctx, "timing_type", TIMING_TYPE); ++ ++ json_attr_object_begin (&json_ctx, "functions"); ++ ++ json_attr_object_begin (&json_ctx, "malloc"); ++ ++ json_attr_object_begin (&json_ctx, ""); ++ ++ TIMING_INIT (res); ++ ++ (void) res; ++ ++ memset (&act, 0, sizeof (act)); ++ act.sa_handler = &alarm_handler; ++ ++ sigaction (SIGALRM, &act, NULL); ++ ++ alarm (BENCHMARK_DURATION); ++ ++ cur = do_benchmark (num_threads, &iters); ++ ++ struct rusage usage; ++ getrusage(RUSAGE_SELF, &usage); ++ ++ d_total_s = cur; ++ d_total_i = iters; ++ ++ json_attr_double (&json_ctx, "duration", d_total_s); ++ json_attr_double (&json_ctx, "iterations", d_total_i); ++ json_attr_double (&json_ctx, "time_per_iteration", d_total_s / d_total_i); ++ json_attr_double (&json_ctx, "max_rss", usage.ru_maxrss); ++ ++ json_attr_double (&json_ctx, "threads", num_threads); ++ json_attr_double (&json_ctx, "min_size", MIN_ALLOCATION_SIZE); ++ json_attr_double (&json_ctx, "max_size", MAX_ALLOCATION_SIZE); ++ json_attr_double (&json_ctx, "random_seed", RAND_SEED); ++ ++ json_attr_object_end (&json_ctx); ++ ++ json_attr_object_end (&json_ctx); ++ ++ json_attr_object_end (&json_ctx); ++ ++ json_document_end (&json_ctx); ++ ++ return 0; ++} +diff -urN glibc-2.17-c758a686/benchtests/bench-memccpy.c glibc-2.17-c758a686/benchtests/bench-memccpy.c +--- glibc-2.17-c758a686/benchtests/bench-memccpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memccpy.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,163 @@ ++/* Measure memccpy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "memccpy" ++#include "bench-string.h" ++ ++void *simple_memccpy (void *, const void *, int, size_t); ++void *stupid_memccpy (void *, const void *, int, size_t); ++ ++IMPL (stupid_memccpy, 0) ++IMPL (simple_memccpy, 0) ++IMPL (memccpy, 1) ++ ++void * ++simple_memccpy (void *dst, const void *src, int c, size_t n) ++{ ++ const char *s = src; ++ char *d = dst; ++ ++ while (n-- > 0) ++ if ((*d++ = *s++) == (char) c) ++ return d; ++ ++ return NULL; ++} ++ ++void * ++stupid_memccpy (void *dst, const void *src, int c, size_t n) ++{ ++ void *p = memchr (src, c, n); ++ ++ if (p != NULL) ++ return mempcpy (dst, src, p - src + 1); ++ ++ memcpy (dst, src, n); ++ return NULL; ++} ++ ++typedef void *(*proto_t) (void *, const void *, int c, size_t); ++ ++static void ++do_one_test (impl_t *impl, void *dst, const void *src, int c, size_t len, ++ size_t n) ++{ ++ void *expect = len > n ? NULL : (char *) dst + len; ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (CALL (impl, dst, src, c, n) != expect) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ CALL (impl, dst, src, c, n), expect); ++ ret = 1; ++ return; ++ } ++ ++ if (memcmp (dst, src, len > n ? n : len) != 0) ++ { ++ error (0, 0, "Wrong result in function %s", impl->name); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, dst, src, c, n); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, int c, size_t len, size_t n, ++ int max_char) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ align1 &= 7; ++ if (align1 + len >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + len >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0; i < len - 1; ++i) ++ { ++ s1[i] = 32 + 23 * i % (max_char - 32); ++ if (s1[i] == (char) c) ++ --s1[i]; ++ } ++ s1[len - 1] = c; ++ for (i = len; i + align1 < page_size && i < len + 64; ++i) ++ s1[i] = 32 + 32 * i % (max_char - 32); ++ ++ printf ("Length %4zd, n %4zd, char %d, alignment %2zd/%2zd:", len, n, c, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s2, s1, c, len, n); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%28s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, i, 12, 16, 16, 127); ++ do_test (i, i, 23, 16, 16, 255); ++ do_test (i, 2 * i, 28, 16, 16, 127); ++ do_test (2 * i, i, 31, 16, 16, 255); ++ do_test (8 - i, 2 * i, 1, 1 << i, 2 << i, 127); ++ do_test (2 * i, 8 - i, 17, 2 << i, 1 << i, 127); ++ do_test (8 - i, 2 * i, 0, 1 << i, 2 << i, 255); ++ do_test (2 * i, 8 - i, i, 2 << i, 1 << i, 255); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, i, 4 << i, 8 << i, 127); ++ do_test (0, 0, i, 16 << i, 8 << i, 127); ++ do_test (8 - i, 2 * i, i, 4 << i, 8 << i, 127); ++ do_test (8 - i, 2 * i, i, 16 << i, 8 << i, 127); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memchr.c glibc-2.17-c758a686/benchtests/bench-memchr.c +--- glibc-2.17-c758a686/benchtests/bench-memchr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memchr.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,133 @@ ++/* Measure memchr functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef USE_AS_MEMRCHR ++# define TEST_MAIN ++# define TEST_NAME "memchr" ++# include "bench-string.h" ++ ++typedef char *(*proto_t) (const char *, int, size_t); ++char *simple_memchr (const char *, int, size_t); ++ ++IMPL (simple_memchr, 0) ++IMPL (memchr, 1) ++ ++char * ++simple_memchr (const char *s, int c, size_t n) ++{ ++ while (n--) ++ if (*s++ == (char) c) ++ return (char *) s - 1; ++ return NULL; ++} ++#endif ++ ++static void ++do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res) ++{ ++ char *res = CALL (impl, s, c, n); ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (res != exp_res) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ res, exp_res); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, c, n); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t pos, size_t len, int seek_char) ++{ ++ size_t i; ++ char *result; ++ ++ align &= 7; ++ if (align + len >= page_size) ++ return; ++ ++ for (i = 0; i < len; ++i) ++ { ++ buf1[align + i] = 1 + 23 * i % 127; ++ if (buf1[align + i] == seek_char) ++ buf1[align + i] = seek_char + 1; ++ } ++ buf1[align + len] = 0; ++ ++ if (pos < len) ++ { ++ buf1[align + pos] = seek_char; ++ buf1[align + len] = -seek_char; ++ result = (char *) (buf1 + align + pos); ++ } ++ else ++ { ++ result = NULL; ++ buf1[align + len] = seek_char; ++ } ++ ++ printf ("Length %4zd, alignment %2zd:", pos, align); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%20s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 2048, 23); ++ do_test (i, 64, 256, 23); ++ do_test (0, 16 << i, 2048, 0); ++ do_test (i, 64, 256, 0); ++ } ++ for (i = 1; i < 32; ++i) ++ { ++ do_test (0, i, i + 1, 23); ++ do_test (0, i, i + 1, 0); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memcmp.c glibc-2.17-c758a686/benchtests/bench-memcmp.c +--- glibc-2.17-c758a686/benchtests/bench-memcmp.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memcmp.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,177 @@ ++/* Measure memcmp functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifdef WIDE ++# define TEST_NAME "wmemcmp" ++#else ++# define TEST_NAME "memcmp" ++#endif ++#include "bench-string.h" ++#ifdef WIDE ++# include ++# include ++ ++# define MEMCMP wmemcmp ++# define MEMCPY wmemcpy ++# define SIMPLE_MEMCMP simple_wmemcmp ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define CHARBYTES 4 ++# define CHAR__MIN WCHAR_MIN ++# define CHAR__MAX WCHAR_MAX ++int ++simple_wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n) ++{ ++ int ret = 0; ++ /* Warning! ++ wmemcmp has to use SIGNED comparison for elements. ++ memcmp has to use UNSIGNED comparison for elemnts. ++ */ ++ while (n-- && (ret = *s1 < *s2 ? -1 : *s1 == *s2 ? 0 : 1) == 0) {s1++; s2++;} ++ return ret; ++} ++#else ++# include ++ ++# define MEMCMP memcmp ++# define MEMCPY memcpy ++# define SIMPLE_MEMCMP simple_memcmp ++# define CHAR char ++# define MAX_CHAR 255 ++# define UCHAR unsigned char ++# define CHARBYTES 1 ++# define CHAR__MIN CHAR_MIN ++# define CHAR__MAX CHAR_MAX ++ ++int ++simple_memcmp (const char *s1, const char *s2, size_t n) ++{ ++ int ret = 0; ++ ++ while (n-- && (ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) == 0); ++ return ret; ++} ++#endif ++ ++typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); ++ ++IMPL (SIMPLE_MEMCMP, 0) ++IMPL (MEMCMP, 1) ++ ++static void ++do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t len, ++ int exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2, len); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, int exp_result) ++{ ++ size_t i; ++ CHAR *s1, *s2; ++ ++ if (len == 0) ++ return; ++ ++ align1 &= 63; ++ if (align1 + (len + 1) * CHARBYTES >= page_size) ++ return; ++ ++ align2 &= 63; ++ if (align2 + (len + 1) * CHARBYTES >= page_size) ++ return; ++ ++ s1 = (CHAR *) (buf1 + align1); ++ s2 = (CHAR *) (buf2 + align2); ++ ++ for (i = 0; i < len; i++) ++ s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % CHAR__MAX; ++ ++ s1[len] = align1; ++ s2[len] = align2; ++ s2[len - 1] -= exp_result; ++ ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, len, exp_result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 16; ++i) ++ { ++ do_test (i * CHARBYTES, i * CHARBYTES, i, 0); ++ do_test (i * CHARBYTES, i * CHARBYTES, i, 1); ++ do_test (i * CHARBYTES, i * CHARBYTES, i, -1); ++ } ++ ++ for (i = 0; i < 16; ++i) ++ { ++ do_test (0, 0, i, 0); ++ do_test (0, 0, i, 1); ++ do_test (0, 0, i, -1); ++ } ++ ++ for (i = 1; i < 10; ++i) ++ { ++ do_test (0, 0, 2 << i, 0); ++ do_test (0, 0, 2 << i, 1); ++ do_test (0, 0, 2 << i, -1); ++ do_test (0, 0, 16 << i, 0); ++ do_test ((8 - i) * CHARBYTES, (2 * i) * CHARBYTES, 16 << i, 0); ++ do_test (0, 0, 16 << i, 1); ++ do_test (0, 0, 16 << i, -1); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 0); ++ do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, 1); ++ do_test (i * CHARBYTES, 2 * (i * CHARBYTES), 8 << i, -1); ++ } ++ ++ return ret; ++} ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memcpy.c glibc-2.17-c758a686/benchtests/bench-memcpy.c +--- glibc-2.17-c758a686/benchtests/bench-memcpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memcpy.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,157 @@ ++/* Measure memcpy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef MEMCPY_RESULT ++# define MEMCPY_RESULT(dst, len) dst ++# define MIN_PAGE_SIZE 131072 ++# define TEST_MAIN ++# define TEST_NAME "memcpy" ++# include "bench-string.h" ++ ++char *simple_memcpy (char *, const char *, size_t); ++char *builtin_memcpy (char *, const char *, size_t); ++ ++IMPL (simple_memcpy, 0) ++IMPL (builtin_memcpy, 0) ++IMPL (memcpy, 1) ++ ++char * ++simple_memcpy (char *dst, const char *src, size_t n) ++{ ++ char *ret = dst; ++ while (n--) ++ *dst++ = *src++; ++ return ret; ++} ++ ++char * ++builtin_memcpy (char *dst, const char *src, size_t n) ++{ ++ return __builtin_memcpy (dst, src, n); ++} ++#endif ++ ++typedef char *(*proto_t) (char *, const char *, size_t); ++ ++static void ++do_one_test (impl_t *impl, char *dst, const char *src, ++ size_t len) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (CALL (impl, dst, src, len) != MEMCPY_RESULT (dst, len)) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ CALL (impl, dst, src, len), MEMCPY_RESULT (dst, len)); ++ ret = 1; ++ return; ++ } ++ ++ if (memcmp (dst, src, len) != 0) ++ { ++ error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", ++ impl->name, dst, src); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, dst, src, len); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len) ++{ ++ size_t i, j; ++ char *s1, *s2; ++ ++ align1 &= 63; ++ if (align1 + len >= page_size) ++ return; ++ ++ align2 &= 63; ++ if (align2 + len >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0, j = 1; i < len; i++, j += 23) ++ s1[i] = j; ++ ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s2, s1, len); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 18; ++i) ++ { ++ do_test (0, 0, 1 << i); ++ do_test (i, 0, 1 << i); ++ do_test (0, i, 1 << i); ++ do_test (i, i, 1 << i); ++ } ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, 0, i); ++ do_test (i, 0, i); ++ do_test (0, i, i); ++ do_test (i, i, i); ++ } ++ ++ for (i = 3; i < 32; ++i) ++ { ++ if ((i & (i - 1)) == 0) ++ continue; ++ do_test (0, 0, 16 * i); ++ do_test (i, 0, 16 * i); ++ do_test (0, i, 16 * i); ++ do_test (i, i, 16 * i); ++ } ++ ++ do_test (0, 0, getpagesize ()); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memmem.c glibc-2.17-c758a686/benchtests/bench-memmem.c +--- glibc-2.17-c758a686/benchtests/bench-memmem.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memmem.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,164 @@ ++/* Measure memmem functions. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "memmem" ++#define BUF1PAGES 20 ++#define ITERATIONS 500 ++#include "bench-string.h" ++ ++typedef char *(*proto_t) (const void *, size_t, const void *, size_t); ++void *simple_memmem (const void *, size_t, const void *, size_t); ++ ++IMPL (simple_memmem, 0) ++IMPL (memmem, 1) ++ ++void * ++simple_memmem (const void *haystack, size_t haystack_len, const void *needle, ++ size_t needle_len) ++{ ++ const char *begin; ++ const char *const last_possible ++ = (const char *) haystack + haystack_len - needle_len; ++ ++ if (needle_len == 0) ++ /* The first occurrence of the empty string is deemed to occur at ++ the beginning of the string. */ ++ return (void *) haystack; ++ ++ /* Sanity check, otherwise the loop might search through the whole ++ memory. */ ++ if (__glibc_unlikely (haystack_len < needle_len)) ++ return NULL; ++ ++ for (begin = (const char *) haystack; begin <= last_possible; ++begin) ++ if (begin[0] == ((const char *) needle)[0] && ++ !memcmp ((const void *) &begin[1], ++ (const void *) ((const char *) needle + 1), ++ needle_len - 1)) ++ return (void *) begin; ++ ++ return NULL; ++} ++ ++static void ++do_one_test (impl_t *impl, const void *haystack, size_t haystack_len, ++ const void *needle, size_t needle_len, const void *expected) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, haystack, haystack_len, needle, needle_len); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (const char *str, size_t len, size_t idx) ++{ ++ char tmpbuf[len]; ++ ++ memcpy (tmpbuf, buf1 + idx, len); ++ memcpy (buf1 + idx, str, len); ++ ++ printf ("String %s, offset %zd:", str, idx); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx); ++ ++ memcpy (buf1 + idx, tmpbuf, len); ++ ++ putchar ('\n'); ++} ++ ++static void ++do_random_tests (void) ++{ ++ for (size_t n = 0; n < ITERATIONS; ++n) ++ { ++ char tmpbuf[32]; ++ ++ size_t shift = random () % 11; ++ size_t rel = random () % ((2 << (shift + 1)) * 64); ++ size_t idx = MIN ((2 << shift) * 64 + rel, BUF1PAGES * page_size - 2); ++ size_t len = random () % (sizeof (tmpbuf) - 1) + 1; ++ len = MIN (len, BUF1PAGES * page_size - idx - 1); ++ memcpy (tmpbuf, buf1 + idx, len); ++ for (size_t i = random () % len / 2 + 1; i > 0; --i) ++ { ++ size_t off = random () % len; ++ char ch = '0' + random () % 10; ++ ++ buf1[idx + off] = ch; ++ } ++ ++ printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len, ++ buf1 + idx); ++ ++ putchar ('\n'); ++ ++ memcpy (buf1 + idx, tmpbuf, len); ++ } ++} ++ ++static const char *const strs[] = ++ { ++ "00000", "00112233", "0123456789", "0000111100001111", ++ "00000111110000022222", "012345678901234567890", ++ "abc0", "aaaa0", "abcabc0" ++ }; ++ ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < BUF1PAGES * page_size; ++i) ++ buf1[i] = 60 + random () % 32; ++ ++ for (i = 0; i < sizeof (strs) / sizeof (strs[0]); ++i) ++ for (size_t j = 0; j < 120; j += 7) ++ { ++ size_t len = strlen (strs[i]); ++ ++ do_test (strs[i], len, j); ++ } ++ ++ do_random_tests (); ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memmove.c glibc-2.17-c758a686/benchtests/bench-memmove.c +--- glibc-2.17-c758a686/benchtests/bench-memmove.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memmove.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,182 @@ ++/* Measure memmove functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifdef TEST_BCOPY ++# define TEST_NAME "bcopy" ++#else ++# define TEST_NAME "memmove" ++#endif ++#include "bench-string.h" ++ ++char *simple_memmove (char *, const char *, size_t); ++ ++#ifdef TEST_BCOPY ++typedef void (*proto_t) (const char *, char *, size_t); ++void simple_bcopy (const char *, char *, size_t); ++ ++IMPL (simple_bcopy, 0) ++IMPL (bcopy, 1) ++ ++void ++simple_bcopy (const char *src, char *dst, size_t n) ++{ ++ simple_memmove (dst, src, n); ++} ++#else ++typedef char *(*proto_t) (char *, const char *, size_t); ++ ++IMPL (simple_memmove, 0) ++IMPL (memmove, 1) ++#endif ++ ++char * ++inhibit_loop_to_libcall ++simple_memmove (char *dst, const char *src, size_t n) ++{ ++ char *ret = dst; ++ if (src < dst) ++ { ++ dst += n; ++ src += n; ++ while (n--) ++ *--dst = *--src; ++ } ++ else ++ while (n--) ++ *dst++ = *src++; ++ return ret; ++} ++ ++static void ++do_one_test (impl_t *impl, char *dst, char *src, const char *orig_src, ++ size_t len) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ memcpy (src, orig_src, len); ++#ifdef TEST_BCOPY ++ CALL (impl, src, dst, len); ++#else ++ char *res; ++ ++ res = CALL (impl, dst, src, len); ++ if (res != dst) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ res, dst); ++ ret = 1; ++ return; ++ } ++#endif ++ ++ if (memcmp (dst, orig_src, len) != 0) ++ { ++ error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", ++ impl->name, dst, src); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++#ifdef TEST_BCOPY ++ CALL (impl, src, dst, len); ++#else ++ CALL (impl, dst, src, len); ++#endif ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len) ++{ ++ size_t i, j; ++ char *s1, *s2; ++ ++ align1 &= 63; ++ if (align1 + len >= page_size) ++ return; ++ ++ align2 &= 63; ++ if (align2 + len >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0, j = 1; i < len; i++, j += 23) ++ s1[i] = j; ++ ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s2, (char *) (buf2 + align1), s1, len); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 14; ++i) ++ { ++ do_test (0, 32, 1 << i); ++ do_test (32, 0, 1 << i); ++ do_test (0, i, 1 << i); ++ do_test (i, 0, 1 << i); ++ } ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, 32, i); ++ do_test (32, 0, i); ++ do_test (0, i, i); ++ do_test (i, 0, i); ++ } ++ ++ for (i = 3; i < 32; ++i) ++ { ++ if ((i & (i - 1)) == 0) ++ continue; ++ do_test (0, 32, 16 * i); ++ do_test (32, 0, 16 * i); ++ do_test (0, i, 16 * i); ++ do_test (i, 0, 16 * i); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-mempcpy.c glibc-2.17-c758a686/benchtests/bench-mempcpy.c +--- glibc-2.17-c758a686/benchtests/bench-mempcpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-mempcpy.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,37 @@ ++/* Measure mempcpy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define MEMCPY_RESULT(dst, len) (dst) + (len) ++#define TEST_MAIN ++#define TEST_NAME "mempcpy" ++#include "bench-string.h" ++ ++char *simple_mempcpy (char *, const char *, size_t); ++ ++IMPL (simple_mempcpy, 0) ++IMPL (mempcpy, 1) ++ ++char * ++simple_mempcpy (char *dst, const char *src, size_t n) ++{ ++ while (n--) ++ *dst++ = *src++; ++ return dst; ++} ++ ++#include "bench-memcpy.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memrchr.c glibc-2.17-c758a686/benchtests/bench-memrchr.c +--- glibc-2.17-c758a686/benchtests/bench-memrchr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memrchr.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,40 @@ ++/* Measure memrchr functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "memrchr" ++#include "bench-string.h" ++ ++typedef char *(*proto_t) (const char *, int, size_t); ++char *simple_memrchr (const char *, int, size_t); ++ ++IMPL (simple_memrchr, 0) ++IMPL (memrchr, 1) ++ ++char * ++simple_memrchr (const char *s, int c, size_t n) ++{ ++ s = s + n; ++ while (n--) ++ if (*--s == (char) c) ++ return (char *) s; ++ return NULL; ++} ++ ++#define USE_AS_MEMRCHR ++#include "bench-memchr.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-memset.c glibc-2.17-c758a686/benchtests/bench-memset.c +--- glibc-2.17-c758a686/benchtests/bench-memset.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-memset.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,167 @@ ++/* Measure memset functions. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifdef TEST_BZERO ++# define TEST_NAME "bzero" ++#else ++# define TEST_NAME "memset" ++#endif ++#define MIN_PAGE_SIZE 131072 ++#include "bench-string.h" ++ ++char *simple_memset (char *, int, size_t); ++ ++#ifdef TEST_BZERO ++typedef void (*proto_t) (char *, size_t); ++void simple_bzero (char *, size_t); ++void builtin_bzero (char *, size_t); ++ ++IMPL (simple_bzero, 0) ++IMPL (builtin_bzero, 0) ++IMPL (bzero, 1) ++ ++void ++simple_bzero (char *s, size_t n) ++{ ++ simple_memset (s, 0, n); ++} ++ ++void ++builtin_bzero (char *s, size_t n) ++{ ++ __builtin_bzero (s, n); ++} ++#else ++typedef char *(*proto_t) (char *, int, size_t); ++char *builtin_memset (char *, int, size_t); ++ ++IMPL (simple_memset, 0) ++IMPL (builtin_memset, 0) ++IMPL (memset, 1) ++ ++char * ++builtin_memset (char *s, int c, size_t n) ++{ ++ return __builtin_memset (s, c, n); ++} ++#endif ++ ++char * ++inhibit_loop_to_libcall ++simple_memset (char *s, int c, size_t n) ++{ ++ char *r = s, *end = s + n; ++ while (r < end) ++ *r++ = c; ++ return s; ++} ++ ++static void ++do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ char tstbuf[n]; ++#ifdef TEST_BZERO ++ simple_bzero (tstbuf, n); ++ CALL (impl, s, n); ++ if (memcmp (s, tstbuf, n) != 0) ++#else ++ char *res = CALL (impl, s, c, n); ++ if (res != s ++ || simple_memset (tstbuf, c, n) != tstbuf ++ || memcmp (s, tstbuf, n) != 0) ++#endif ++ { ++ error (0, 0, "Wrong result in function %s", impl->name); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++#ifdef TEST_BZERO ++ CALL (impl, s, n); ++#else ++ CALL (impl, s, c, n); ++#endif ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, int c, size_t len) ++{ ++ align &= 7; ++ if (align + len > page_size) ++ return; ++ ++ printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (char *) buf1 + align, c, len); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ int c = 0; ++ ++ test_init (); ++ ++ printf ("%24s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++#ifndef TEST_BZERO ++ for (c = -65; c <= 130; c += 65) ++#endif ++ { ++ for (i = 0; i < 18; ++i) ++ do_test (0, c, 1 << i); ++ for (i = 1; i < 32; ++i) ++ { ++ do_test (i, c, i); ++ if (i & (i - 1)) ++ do_test (0, c, i); ++ } ++ for (i = 32; i < 512; i+=32) ++ { ++ do_test (0, c, i); ++ do_test (i, c, i); ++ } ++ do_test (1, c, 14); ++ do_test (3, c, 1024); ++ do_test (4, c, 64); ++ do_test (2, c, 25); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-rawmemchr.c glibc-2.17-c758a686/benchtests/bench-rawmemchr.c +--- glibc-2.17-c758a686/benchtests/bench-rawmemchr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-rawmemchr.c 2015-06-20 21:22:16.297458105 -0400 +@@ -0,0 +1,126 @@ ++/* Measure memchr functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define TEST_MAIN ++#define TEST_NAME "rawmemchr" ++#include "bench-string.h" ++ ++typedef char *(*proto_t) (const char *, int); ++char *simple_rawmemchr (const char *, int); ++ ++IMPL (simple_rawmemchr, 0) ++IMPL (rawmemchr, 1) ++ ++char * ++simple_rawmemchr (const char *s, int c) ++{ ++ while (1) ++ if (*s++ == (char) c) ++ return (char *) s - 1; ++ return NULL; ++} ++ ++static void ++do_one_test (impl_t *impl, const char *s, int c, char *exp_res) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ char *res = CALL (impl, s, c); ++ if (res != exp_res) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ res, exp_res); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, c); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t pos, size_t len, int seek_char) ++{ ++ size_t i; ++ char *result; ++ ++ align &= 7; ++ if (align + len >= page_size) ++ return; ++ ++ for (i = 0; i < len; ++i) ++ { ++ buf1[align + i] = 1 + 23 * i % 127; ++ if (buf1[align + i] == seek_char) ++ buf1[align + i] = seek_char + 1; ++ } ++ buf1[align + len] = 0; ++ ++ assert (pos < len); ++ ++ buf1[align + pos] = seek_char; ++ buf1[align + len] = -seek_char; ++ result = (char *) (buf1 + align + pos); ++ ++ printf ("Length %4zd, alignment %2zd:", pos, align); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (char *) (buf1 + align), seek_char, result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%20s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 7; ++i) ++ { ++ do_test (0, 16 << i, 2048, 23); ++ do_test (i, 64, 256, 23); ++ do_test (0, 16 << i, 2048, 0); ++ do_test (i, 64, 256, 0); ++ } ++ for (i = 1; i < 32; ++i) ++ { ++ do_test (0, i, i + 1, 23); ++ do_test (0, i, i + 1, 0); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-skeleton.c glibc-2.17-c758a686/benchtests/bench-skeleton.c +--- glibc-2.17-c758a686/benchtests/bench-skeleton.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-skeleton.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,154 @@ ++/* Skeleton for benchmark programs. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bench-timing.h" ++#include "json-lib.h" ++ ++volatile unsigned int dontoptimize = 0; ++ ++void ++startup (void) ++{ ++ /* This loop should cause CPU to switch to maximal freqency. ++ This makes subsequent measurement more accurate. We need a side effect ++ to prevent the loop being deleted by compiler. ++ This should be enough to cause CPU to speed up and it is simpler than ++ running loop for constant time. This is used when user does not have root ++ access to set a constant freqency. */ ++ for (int k = 0; k < 10000000; k++) ++ dontoptimize += 23 * dontoptimize + 2; ++} ++ ++#define TIMESPEC_AFTER(a, b) \ ++ (((a).tv_sec == (b).tv_sec) ? \ ++ ((a).tv_nsec > (b).tv_nsec) : \ ++ ((a).tv_sec > (b).tv_sec)) ++int ++main (int argc, char **argv) ++{ ++ unsigned long i, k; ++ struct timespec runtime; ++ timing_t start, end; ++ bool detailed = false; ++ json_ctx_t json_ctx; ++ ++ if (argc == 2 && !strcmp (argv[1], "-d")) ++ detailed = true; ++ ++ startup(); ++ ++ memset (&runtime, 0, sizeof (runtime)); ++ ++ unsigned long iters, res; ++ ++#ifdef BENCH_INIT ++ BENCH_INIT (); ++#endif ++ TIMING_INIT (res); ++ ++ iters = 1000 * res; ++ ++ json_init (&json_ctx, 2, stdout); ++ ++ /* Begin function. */ ++ json_attr_object_begin (&json_ctx, FUNCNAME); ++ ++ for (int v = 0; v < NUM_VARIANTS; v++) ++ { ++ /* Run for approximately DURATION seconds. */ ++ clock_gettime (CLOCK_MONOTONIC_RAW, &runtime); ++ runtime.tv_sec += DURATION; ++ ++ double d_total_i = 0; ++ timing_t total = 0, max = 0, min = 0x7fffffffffffffff; ++ int64_t c = 0; ++ while (1) ++ { ++ for (i = 0; i < NUM_SAMPLES (v); i++) ++ { ++ uint64_t cur; ++ TIMING_NOW (start); ++ for (k = 0; k < iters; k++) ++ BENCH_FUNC (v, i); ++ TIMING_NOW (end); ++ ++ TIMING_DIFF (cur, start, end); ++ ++ if (cur > max) ++ max = cur; ++ ++ if (cur < min) ++ min = cur; ++ ++ TIMING_ACCUM (total, cur); ++ /* Accumulate timings for the value. In the end we will divide ++ by the total iterations. */ ++ RESULT_ACCUM (cur, v, i, c * iters, (c + 1) * iters); ++ ++ d_total_i += iters; ++ } ++ c++; ++ struct timespec curtime; ++ ++ memset (&curtime, 0, sizeof (curtime)); ++ clock_gettime (CLOCK_MONOTONIC_RAW, &curtime); ++ if (TIMESPEC_AFTER (curtime, runtime)) ++ goto done; ++ } ++ ++ double d_total_s; ++ double d_iters; ++ ++ done: ++ d_total_s = total; ++ d_iters = iters; ++ ++ /* Begin variant. */ ++ json_attr_object_begin (&json_ctx, VARIANT (v)); ++ ++ json_attr_double (&json_ctx, "duration", d_total_s); ++ json_attr_double (&json_ctx, "iterations", d_total_i); ++ json_attr_double (&json_ctx, "max", max / d_iters); ++ json_attr_double (&json_ctx, "min", min / d_iters); ++ json_attr_double (&json_ctx, "mean", d_total_s / d_total_i); ++ ++ if (detailed) ++ { ++ json_array_begin (&json_ctx, "timings"); ++ ++ for (int i = 0; i < NUM_SAMPLES (v); i++) ++ json_element_double (&json_ctx, RESULT (v, i)); ++ ++ json_array_end (&json_ctx); ++ } ++ ++ /* End variant. */ ++ json_attr_object_end (&json_ctx); ++ } ++ ++ /* End function. */ ++ json_attr_object_end (&json_ctx); ++ ++ return 0; ++} +diff -urN glibc-2.17-c758a686/benchtests/bench-stpcpy.c glibc-2.17-c758a686/benchtests/bench-stpcpy.c +--- glibc-2.17-c758a686/benchtests/bench-stpcpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-stpcpy.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,36 @@ ++/* Measure stpcpy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRCPY_RESULT(dst, len) ((dst) + (len)) ++#define TEST_MAIN ++#define TEST_NAME "stpcpy" ++#include "bench-string.h" ++ ++char *simple_stpcpy (char *, const char *); ++ ++IMPL (simple_stpcpy, 0) ++IMPL (stpcpy, 1) ++ ++char * ++simple_stpcpy (char *dst, const char *src) ++{ ++ while ((*dst++ = *src++) != '\0'); ++ return dst - 1; ++} ++ ++#include "bench-strcpy.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-stpcpy_chk.c glibc-2.17-c758a686/benchtests/bench-stpcpy_chk.c +--- glibc-2.17-c758a686/benchtests/bench-stpcpy_chk.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-stpcpy_chk.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,45 @@ ++/* Measure stpcpy checking functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRCPY_RESULT(dst, len) ((dst) + (len)) ++#define TEST_MAIN ++#define TEST_NAME "stpcpy_chk" ++#include "bench-string.h" ++ ++extern void __attribute__ ((noreturn)) __chk_fail (void); ++char *simple_stpcpy_chk (char *, const char *, size_t); ++extern char *normal_stpcpy (char *, const char *, size_t) ++ __asm ("stpcpy"); ++extern char *__stpcpy_chk (char *, const char *, size_t); ++ ++IMPL (simple_stpcpy_chk, 0) ++IMPL (normal_stpcpy, 1) ++IMPL (__stpcpy_chk, 2) ++ ++char * ++simple_stpcpy_chk (char *dst, const char *src, size_t len) ++{ ++ if (! len) ++ __chk_fail (); ++ while ((*dst++ = *src++) != '\0') ++ if (--len == 0) ++ __chk_fail (); ++ return dst - 1; ++} ++ ++#include "bench-strcpy_chk.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-stpncpy.c glibc-2.17-c758a686/benchtests/bench-stpncpy.c +--- glibc-2.17-c758a686/benchtests/bench-stpncpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-stpncpy.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,59 @@ ++/* Measure stpncpy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len))) ++#define TEST_MAIN ++#define TEST_NAME "stpncpy" ++#include "bench-string.h" ++ ++char *simple_stpncpy (char *, const char *, size_t); ++char *stupid_stpncpy (char *, const char *, size_t); ++ ++IMPL (stupid_stpncpy, 0) ++IMPL (simple_stpncpy, 0) ++IMPL (stpncpy, 1) ++ ++char * ++simple_stpncpy (char *dst, const char *src, size_t n) ++{ ++ while (n--) ++ if ((*dst++ = *src++) == '\0') ++ { ++ size_t i; ++ ++ for (i = 0; i < n; ++i) ++ dst[i] = '\0'; ++ return dst - 1; ++ } ++ return dst; ++} ++ ++char * ++stupid_stpncpy (char *dst, const char *src, size_t n) ++{ ++ size_t nc = strnlen (src, n); ++ size_t i; ++ ++ for (i = 0; i < nc; ++i) ++ dst[i] = src[i]; ++ for (; i < n; ++i) ++ dst[i] = '\0'; ++ return dst + nc; ++} ++ ++#include "bench-strncpy.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strcasecmp.c glibc-2.17-c758a686/benchtests/bench-strcasecmp.c +--- glibc-2.17-c758a686/benchtests/bench-strcasecmp.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcasecmp.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,176 @@ ++/* Measure strcasecmp functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#define TEST_MAIN ++#define TEST_NAME "strcasecmp" ++#include "bench-string.h" ++ ++typedef int (*proto_t) (const char *, const char *); ++static int simple_strcasecmp (const char *, const char *); ++static int stupid_strcasecmp (const char *, const char *); ++ ++IMPL (stupid_strcasecmp, 0) ++IMPL (simple_strcasecmp, 0) ++IMPL (strcasecmp, 1) ++ ++static int ++simple_strcasecmp (const char *s1, const char *s2) ++{ ++ int ret; ++ ++ while ((ret = ((unsigned char) tolower (*s1) ++ - (unsigned char) tolower (*s2))) == 0 ++ && *s1++) ++ ++s2; ++ return ret; ++} ++ ++static int ++stupid_strcasecmp (const char *s1, const char *s2) ++{ ++ size_t ns1 = strlen (s1) + 1, ns2 = strlen (s2) + 1; ++ size_t n = ns1 < ns2 ? ns1 : ns2; ++ int ret = 0; ++ ++ while (n--) ++ { ++ if ((ret = ((unsigned char) tolower (*s1) ++ - (unsigned char) tolower (*s2))) != 0) ++ break; ++ ++s1; ++ ++s2; ++ } ++ return ret; ++} ++ ++static void ++do_one_test (impl_t *impl, const char *s1, const char *s2, int exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ int result = CALL (impl, s1, s2); ++ if ((exp_result == 0 && result != 0) ++ || (exp_result < 0 && result >= 0) ++ || (exp_result > 0 && result <= 0)) ++ { ++ error (0, 0, "Wrong result in function %s %d %d", impl->name, ++ result, exp_result); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, int max_char, ++ int exp_result) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ if (len == 0) ++ return; ++ ++ align1 &= 7; ++ if (align1 + len + 1 >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + len + 1 >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0; i < len; i++) ++ { ++ s1[i] = toupper (1 + 23 * i % max_char); ++ s2[i] = tolower (s1[i]); ++ } ++ ++ s1[len] = s2[len] = 0; ++ s1[len + 1] = 23; ++ s2[len + 1] = 24 + exp_result; ++ if ((s2[len - 1] == 'z' && exp_result == -1) ++ || (s2[len - 1] == 'a' && exp_result == 1)) ++ s1[len - 1] += exp_result; ++ else ++ s2[len - 1] -= exp_result; ++ ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, exp_result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 16; ++i) ++ { ++ do_test (i, i, i, 127, 0); ++ do_test (i, i, i, 127, 1); ++ do_test (i, i, i, 127, -1); ++ } ++ ++ for (i = 1; i < 10; ++i) ++ { ++ do_test (0, 0, 2 << i, 127, 0); ++ do_test (0, 0, 2 << i, 254, 0); ++ do_test (0, 0, 2 << i, 127, 1); ++ do_test (0, 0, 2 << i, 254, 1); ++ do_test (0, 0, 2 << i, 127, -1); ++ do_test (0, 0, 2 << i, 254, -1); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, 8 << i, 127, 0); ++ do_test (2 * i, i, 8 << i, 254, 0); ++ do_test (i, 2 * i, 8 << i, 127, 1); ++ do_test (2 * i, i, 8 << i, 254, 1); ++ do_test (i, 2 * i, 8 << i, 127, -1); ++ do_test (2 * i, i, 8 << i, 254, -1); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strcasestr.c glibc-2.17-c758a686/benchtests/bench-strcasestr.c +--- glibc-2.17-c758a686/benchtests/bench-strcasestr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcasestr.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,180 @@ ++/* Measure strcasestr functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strcasestr" ++#include "bench-string.h" ++ ++ ++#define STRCASESTR simple_strcasestr ++#define NO_ALIAS ++#define __strncasecmp strncasecmp ++#include "../string/strcasestr.c" ++ ++ ++static char * ++stupid_strcasestr (const char *s1, const char *s2) ++{ ++ ssize_t s1len = strlen (s1); ++ ssize_t s2len = strlen (s2); ++ ++ if (s2len > s1len) ++ return NULL; ++ ++ for (ssize_t i = 0; i <= s1len - s2len; ++i) ++ { ++ size_t j; ++ for (j = 0; j < s2len; ++j) ++ if (tolower (s1[i + j]) != tolower (s2[j])) ++ break; ++ if (j == s2len) ++ return (char *) s1 + i; ++ } ++ ++ return NULL; ++} ++ ++ ++typedef char *(*proto_t) (const char *, const char *); ++ ++IMPL (stupid_strcasestr, 0) ++IMPL (simple_strcasestr, 0) ++IMPL (strcasestr, 1) ++ ++ ++static void ++do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++ ++static void ++do_test (size_t align1, size_t align2, size_t len1, size_t len2, ++ int fail) ++{ ++ char *s1 = (char *) (buf1 + align1); ++ char *s2 = (char *) (buf2 + align2); ++ ++ static const char d[] = "1234567890abcxyz"; ++#define dl (sizeof (d) - 1) ++ char *ss2 = s2; ++ for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ ss2 = mempcpy (ss2, d, t); ++ } ++ s2[len2] = '\0'; ++ ++ if (fail) ++ { ++ char *ss1 = s1; ++ for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ memcpy (ss1, d, t); ++ ++ss1[len2 > 7 ? 7 : len2 - 1]; ++ ss1 += t; ++ } ++ } ++ else ++ { ++ memset (s1, '0', len1); ++ for (size_t i = 0; i < len2; ++i) ++ s1[len1 - len2 + i] = toupper (s2[i]); ++ } ++ s1[len1] = '\0'; ++ ++ printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", ++ len1, len2, align1, align2, fail ? "fail" : "found"); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); ++ ++ putchar ('\n'); ++} ++ ++static int ++test_main (void) ++{ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (size_t klen = 2; klen < 32; ++klen) ++ for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen) ++ { ++ do_test (0, 0, hlen, klen, 0); ++ do_test (0, 0, hlen, klen, 1); ++ do_test (0, 3, hlen, klen, 0); ++ do_test (0, 3, hlen, klen, 1); ++ do_test (0, 9, hlen, klen, 0); ++ do_test (0, 9, hlen, klen, 1); ++ do_test (0, 15, hlen, klen, 0); ++ do_test (0, 15, hlen, klen, 1); ++ ++ do_test (3, 0, hlen, klen, 0); ++ do_test (3, 0, hlen, klen, 1); ++ do_test (3, 3, hlen, klen, 0); ++ do_test (3, 3, hlen, klen, 1); ++ do_test (3, 9, hlen, klen, 0); ++ do_test (3, 9, hlen, klen, 1); ++ do_test (3, 15, hlen, klen, 0); ++ do_test (3, 15, hlen, klen, 1); ++ ++ do_test (9, 0, hlen, klen, 0); ++ do_test (9, 0, hlen, klen, 1); ++ do_test (9, 3, hlen, klen, 0); ++ do_test (9, 3, hlen, klen, 1); ++ do_test (9, 9, hlen, klen, 0); ++ do_test (9, 9, hlen, klen, 1); ++ do_test (9, 15, hlen, klen, 0); ++ do_test (9, 15, hlen, klen, 1); ++ ++ do_test (15, 0, hlen, klen, 0); ++ do_test (15, 0, hlen, klen, 1); ++ do_test (15, 3, hlen, klen, 0); ++ do_test (15, 3, hlen, klen, 1); ++ do_test (15, 9, hlen, klen, 0); ++ do_test (15, 9, hlen, klen, 1); ++ do_test (15, 15, hlen, klen, 0); ++ do_test (15, 15, hlen, klen, 1); ++ } ++ ++ do_test (0, 0, page_size - 1, 16, 0); ++ do_test (0, 0, page_size - 1, 16, 1); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strcat.c glibc-2.17-c758a686/benchtests/bench-strcat.c +--- glibc-2.17-c758a686/benchtests/bench-strcat.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcat.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,148 @@ ++/* Measure strcat functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strcat" ++#include "bench-string.h" ++ ++typedef char *(*proto_t) (char *, const char *); ++char *simple_strcat (char *, const char *); ++ ++IMPL (simple_strcat, 0) ++IMPL (strcat, 1) ++ ++char * ++simple_strcat (char *dst, const char *src) ++{ ++ char *ret = dst; ++ while (*dst++ != '\0'); ++ --dst; ++ while ((*dst++ = *src++) != '\0'); ++ return ret; ++} ++ ++static void ++do_one_test (impl_t *impl, char *dst, const char *src) ++{ ++ size_t k = strlen (dst), i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (CALL (impl, dst, src) != dst) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ CALL (impl, dst, src), dst); ++ ret = 1; ++ return; ++ } ++ ++ if (strcmp (dst + k, src) != 0) ++ { ++ error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", ++ impl->name, dst, src); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ dst[k] = '\0'; ++ CALL (impl, dst, src); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ align1 &= 7; ++ if (align1 + len1 >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + len1 + len2 >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0; i < len1; ++i) ++ s1[i] = 32 + 23 * i % (max_char - 32); ++ s1[len1] = '\0'; ++ ++ for (i = 0; i < len2; i++) ++ s2[i] = 32 + 23 * i % (max_char - 32); ++ ++ printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len1, len2, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ s2[len2] = '\0'; ++ do_one_test (impl, s2, s1); ++ } ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%28s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 16; ++i) ++ { ++ do_test (0, 0, i, i, 127); ++ do_test (0, 0, i, i, 255); ++ do_test (0, i, i, i, 127); ++ do_test (i, 0, i, i, 255); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, 8 << i, 127); ++ do_test (8 - i, 2 * i, 8 << i, 8 << i, 127); ++ do_test (0, 0, 8 << i, 2 << i, 127); ++ do_test (8 - i, 2 * i, 8 << i, 2 << i, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, 8 << i, 1, 127); ++ do_test (2 * i, i, 8 << i, 1, 255); ++ do_test (i, i, 8 << i, 10, 127); ++ do_test (i, i, 8 << i, 10, 255); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strchr.c glibc-2.17-c758a686/benchtests/bench-strchr.c +--- glibc-2.17-c758a686/benchtests/bench-strchr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strchr.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,200 @@ ++/* Measure STRCHR functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifndef WIDE ++# ifdef USE_FOR_STRCHRNUL ++# define TEST_NAME "strchrnul" ++# else ++# define TEST_NAME "strchr" ++# endif ++#else ++# define TEST_NAME "wcschr" ++#endif ++#include "bench-string.h" ++ ++#ifndef WIDE ++# ifdef USE_FOR_STRCHRNUL ++# define STRCHR strchrnul ++# define stupid_STRCHR stupid_STRCHRNUL ++# define simple_STRCHR simple_STRCHRNUL ++# else ++# define STRCHR strchr ++# endif ++# define STRLEN strlen ++# define CHAR char ++# define BIG_CHAR CHAR_MAX ++# define MIDDLE_CHAR 127 ++# define SMALL_CHAR 23 ++# define UCHAR unsigned char ++#else ++# include ++# define STRCHR wcschr ++# define STRLEN wcslen ++# define CHAR wchar_t ++# define BIG_CHAR WCHAR_MAX ++# define MIDDLE_CHAR 1121 ++# define SMALL_CHAR 851 ++# define UCHAR wchar_t ++#endif ++ ++#ifdef USE_FOR_STRCHRNUL ++# define NULLRET(endptr) endptr ++#else ++# define NULLRET(endptr) NULL ++#endif ++ ++ ++typedef CHAR *(*proto_t) (const CHAR *, int); ++ ++CHAR * ++simple_STRCHR (const CHAR *s, int c) ++{ ++ for (; *s != (CHAR) c; ++s) ++ if (*s == '\0') ++ return NULLRET ((CHAR *) s); ++ return (CHAR *) s; ++} ++ ++CHAR * ++stupid_STRCHR (const CHAR *s, int c) ++{ ++ size_t n = STRLEN (s) + 1; ++ ++ while (n--) ++ if (*s++ == (CHAR) c) ++ return (CHAR *) s - 1; ++ return NULLRET ((CHAR *) s - 1); ++} ++ ++IMPL (stupid_STRCHR, 0) ++IMPL (simple_STRCHR, 0) ++IMPL (STRCHR, 1) ++ ++static void ++do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, c); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char) ++/* For wcschr: align here means align not in bytes, ++ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)) ++ len for wcschr here isn't in bytes but it's number of wchar_t symbols. */ ++{ ++ size_t i; ++ CHAR *result; ++ CHAR *buf = (CHAR *) buf1; ++ align &= 15; ++ if ((align + len) * sizeof (CHAR) >= page_size) ++ return; ++ ++ for (i = 0; i < len; ++i) ++ { ++ buf[align + i] = 32 + 23 * i % max_char; ++ if (buf[align + i] == seek_char) ++ buf[align + i] = seek_char + 1; ++ else if (buf[align + i] == 0) ++ buf[align + i] = 1; ++ } ++ buf[align + len] = 0; ++ ++ if (pos < len) ++ { ++ buf[align + pos] = seek_char; ++ result = buf + align + pos; ++ } ++ else if (seek_char == 0) ++ result = buf + align + len; ++ else ++ result = NULLRET (buf + align + len); ++ ++ printf ("Length %4zd, alignment in bytes %2zd:", ++ pos, align * sizeof (CHAR)); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, buf + align, seek_char, result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%20s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR); ++ do_test (i, 16 << i, 2048, SMALL_CHAR, MIDDLE_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 64, 256, SMALL_CHAR, MIDDLE_CHAR); ++ do_test (i, 64, 256, SMALL_CHAR, BIG_CHAR); ++ } ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, i, i + 1, SMALL_CHAR, MIDDLE_CHAR); ++ do_test (0, i, i + 1, SMALL_CHAR, BIG_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 2048, 0, MIDDLE_CHAR); ++ do_test (i, 16 << i, 2048, 0, MIDDLE_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 64, 256, 0, MIDDLE_CHAR); ++ do_test (i, 64, 256, 0, BIG_CHAR); ++ } ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, i, i + 1, 0, MIDDLE_CHAR); ++ do_test (0, i, i + 1, 0, BIG_CHAR); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strchrnul.c glibc-2.17-c758a686/benchtests/bench-strchrnul.c +--- glibc-2.17-c758a686/benchtests/bench-strchrnul.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strchrnul.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,20 @@ ++/* Measure strchrnul function. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_FOR_STRCHRNUL 1 ++#include "bench-strchr.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strcmp.c glibc-2.17-c758a686/benchtests/bench-strcmp.c +--- glibc-2.17-c758a686/benchtests/bench-strcmp.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcmp.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,241 @@ ++/* Measure strcmp and wcscmp functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifdef WIDE ++# define TEST_NAME "wcscmp" ++#else ++# define TEST_NAME "strcmp" ++#endif ++#include "bench-string.h" ++ ++#ifdef WIDE ++# include ++ ++# define L(str) L##str ++# define STRCMP wcscmp ++# define STRCPY wcscpy ++# define STRLEN wcslen ++# define MEMCPY wmemcpy ++# define SIMPLE_STRCMP simple_wcscmp ++# define STUPID_STRCMP stupid_wcscmp ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define CHARBYTES 4 ++# define CHARBYTESLOG 2 ++# define CHARALIGN __alignof__ (CHAR) ++# define MIDCHAR 0x7fffffff ++# define LARGECHAR 0xfffffffe ++# define CHAR__MAX WCHAR_MAX ++# define CHAR__MIN WCHAR_MIN ++ ++/* Wcscmp uses signed semantics for comparison, not unsigned */ ++/* Avoid using substraction since possible overflow */ ++ ++int ++simple_wcscmp (const wchar_t *s1, const wchar_t *s2) ++{ ++ wchar_t c1, c2; ++ do ++ { ++ c1 = *s1++; ++ c2 = *s2++; ++ if (c2 == L'\0') ++ return c1 - c2; ++ } ++ while (c1 == c2); ++ ++ return c1 < c2 ? -1 : 1; ++} ++ ++int ++stupid_wcscmp (const wchar_t *s1, const wchar_t *s2) ++{ ++ size_t ns1 = wcslen (s1) + 1; ++ size_t ns2 = wcslen (s2) + 1; ++ size_t n = ns1 < ns2 ? ns1 : ns2; ++ int ret = 0; ++ ++ wchar_t c1, c2; ++ ++ while (n--) { ++ c1 = *s1++; ++ c2 = *s2++; ++ if ((ret = c1 < c2 ? -1 : c1 == c2 ? 0 : 1) != 0) ++ break; ++ } ++ return ret; ++} ++ ++#else ++# include ++ ++# define L(str) str ++# define STRCMP strcmp ++# define STRCPY strcpy ++# define STRLEN strlen ++# define MEMCPY memcpy ++# define SIMPLE_STRCMP simple_strcmp ++# define STUPID_STRCMP stupid_strcmp ++# define CHAR char ++# define UCHAR unsigned char ++# define CHARBYTES 1 ++# define CHARBYTESLOG 0 ++# define CHARALIGN 1 ++# define MIDCHAR 0x7f ++# define LARGECHAR 0xfe ++# define CHAR__MAX CHAR_MAX ++# define CHAR__MIN CHAR_MIN ++ ++/* Strcmp uses unsigned semantics for comparison. */ ++int ++simple_strcmp (const char *s1, const char *s2) ++{ ++ int ret; ++ ++ while ((ret = *(unsigned char *) s1 - *(unsigned char*) s2++) == 0 && *s1++); ++ return ret; ++} ++ ++int ++stupid_strcmp (const char *s1, const char *s2) ++{ ++ size_t ns1 = strlen (s1) + 1; ++ size_t ns2 = strlen (s2) + 1; ++ size_t n = ns1 < ns2 ? ns1 : ns2; ++ int ret = 0; ++ ++ while (n--) ++ if ((ret = *(unsigned char *) s1++ - *(unsigned char *) s2++) != 0) ++ break; ++ return ret; ++} ++#endif ++ ++typedef int (*proto_t) (const CHAR *, const CHAR *); ++ ++IMPL (STUPID_STRCMP, 1) ++IMPL (SIMPLE_STRCMP, 1) ++IMPL (STRCMP, 1) ++ ++static void ++do_one_test (impl_t *impl, ++ const CHAR *s1, const CHAR *s2, ++ int exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, int max_char, ++ int exp_result) ++{ ++ size_t i; ++ ++ CHAR *s1, *s2; ++ ++ if (len == 0) ++ return; ++ ++ align1 &= 63; ++ if (align1 + (len + 1) * CHARBYTES >= page_size) ++ return; ++ ++ align2 &= 63; ++ if (align2 + (len + 1) * CHARBYTES >= page_size) ++ return; ++ ++ /* Put them close to the end of page. */ ++ i = align1 + CHARBYTES * (len + 2); ++ s1 = (CHAR *) (buf1 + ((page_size - i) / 16 * 16) + align1); ++ i = align2 + CHARBYTES * (len + 2); ++ s2 = (CHAR *) (buf2 + ((page_size - i) / 16 * 16) + align2); ++ ++ for (i = 0; i < len; i++) ++ s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char; ++ ++ s1[len] = s2[len] = 0; ++ s1[len + 1] = 23; ++ s2[len + 1] = 24 + exp_result; ++ s2[len - 1] -= exp_result; ++ ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, exp_result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 32; ++i) ++ { ++ do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 0); ++ do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, 1); ++ do_test (CHARBYTES * i, CHARBYTES * i, i, MIDCHAR, -1); ++ } ++ ++ for (i = 1; i < 10 + CHARBYTESLOG; ++i) ++ { ++ do_test (0, 0, 2 << i, MIDCHAR, 0); ++ do_test (0, 0, 2 << i, LARGECHAR, 0); ++ do_test (0, 0, 2 << i, MIDCHAR, 1); ++ do_test (0, 0, 2 << i, LARGECHAR, 1); ++ do_test (0, 0, 2 << i, MIDCHAR, -1); ++ do_test (0, 0, 2 << i, LARGECHAR, -1); ++ do_test (0, CHARBYTES * i, 2 << i, MIDCHAR, 1); ++ do_test (CHARBYTES * i, CHARBYTES * (i + 1), 2 << i, LARGECHAR, 1); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 0); ++ do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 0); ++ do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, 1); ++ do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, 1); ++ do_test (CHARBYTES * i, 2 * CHARBYTES * i, 8 << i, MIDCHAR, -1); ++ do_test (2 * CHARBYTES * i, CHARBYTES * i, 8 << i, LARGECHAR, -1); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strcpy.c glibc-2.17-c758a686/benchtests/bench-strcpy.c +--- glibc-2.17-c758a686/benchtests/bench-strcpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcpy.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,193 @@ ++/* Measure strcpy functions. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef WIDE ++# include ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define sfmt "ls" ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++# define STRCMP wcscmp ++# define MEMCMP wmemcmp ++# define MEMSET wmemset ++#else ++# define CHAR char ++# define UCHAR unsigned char ++# define sfmt "s" ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++# define STRCMP strcmp ++# define MEMCMP memcmp ++# define MEMSET memset ++#endif ++ ++#ifndef STRCPY_RESULT ++# define STRCPY_RESULT(dst, len) dst ++# define TEST_MAIN ++# ifndef WIDE ++# define TEST_NAME "strcpy" ++# else ++# define TEST_NAME "wcscpy" ++# endif ++# include "bench-string.h" ++# ifndef WIDE ++# define SIMPLE_STRCPY simple_strcpy ++# define STRCPY strcpy ++# else ++# define SIMPLE_STRCPY simple_wcscpy ++# define STRCPY wcscpy ++# endif ++ ++CHAR *SIMPLE_STRCPY (CHAR *, const CHAR *); ++ ++IMPL (SIMPLE_STRCPY, 0) ++IMPL (STRCPY, 1) ++ ++CHAR * ++SIMPLE_STRCPY (CHAR *dst, const CHAR *src) ++{ ++ CHAR *ret = dst; ++ while ((*dst++ = *src++) != '\0'); ++ return ret; ++} ++#endif ++ ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *); ++ ++static void ++do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, ++ size_t len __attribute__((unused))) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (CALL (impl, dst, src) != STRCPY_RESULT (dst, len)) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ CALL (impl, dst, src), STRCPY_RESULT (dst, len)); ++ ret = 1; ++ return; ++ } ++ ++ if (STRCMP (dst, src) != 0) ++ { ++ error (0, 0, ++ "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"", ++ impl->name, dst, src); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, dst, src); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, int max_char) ++{ ++ size_t i; ++ CHAR *s1, *s2; ++/* For wcscpy: align1 and align2 here mean alignment not in bytes, ++ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)) ++ len for wcschr here isn't in bytes but it's number of wchar_t symbols. */ ++ align1 &= 7; ++ if ((align1 + len) * sizeof(CHAR) >= page_size) ++ return; ++ ++ align2 &= 7; ++ if ((align2 + len) * sizeof(CHAR) >= page_size) ++ return; ++ ++ s1 = (CHAR *) (buf1) + align1; ++ s2 = (CHAR *) (buf2) + align2; ++ ++ for (i = 0; i < len; i++) ++ s1[i] = 32 + 23 * i % (max_char - 32); ++ s1[len] = 0; ++ ++ printf ("Length %4zd, alignments in bytes %2zd/%2zd:", len, align1 * sizeof(CHAR), align2 * sizeof(CHAR)); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s2, s1, len); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 16; ++i) ++ { ++ do_test (0, 0, i, SMALL_CHAR); ++ do_test (0, 0, i, BIG_CHAR); ++ do_test (0, i, i, SMALL_CHAR); ++ do_test (i, 0, i, BIG_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, SMALL_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, 8 << i, SMALL_CHAR); ++ do_test (2 * i, i, 8 << i, BIG_CHAR); ++ do_test (i, i, 8 << i, SMALL_CHAR); ++ do_test (i, i, 8 << i, BIG_CHAR); ++ } ++ ++ for (i = 16; i <= 512; i+=4) ++ { ++ do_test (0, 4, i, SMALL_CHAR); ++ do_test (4, 0, i, BIG_CHAR); ++ do_test (4, 4, i, SMALL_CHAR); ++ do_test (2, 2, i, BIG_CHAR); ++ do_test (2, 6, i, SMALL_CHAR); ++ do_test (6, 2, i, BIG_CHAR); ++ do_test (1, 7, i, SMALL_CHAR); ++ do_test (7, 1, i, BIG_CHAR); ++ do_test (3, 4, i, SMALL_CHAR); ++ do_test (4, 3, i, BIG_CHAR); ++ do_test (5, 7, i, SMALL_CHAR); ++ do_test (7, 5, i, SMALL_CHAR); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strcpy_chk.c glibc-2.17-c758a686/benchtests/bench-strcpy_chk.c +--- glibc-2.17-c758a686/benchtests/bench-strcpy_chk.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcpy_chk.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,243 @@ ++/* Measure __strcpy_chk functions. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRCPY_RESULT ++# define STRCPY_RESULT(dst, len) dst ++# define TEST_MAIN ++# define TEST_NAME "strcpy_chk" ++# include "bench-string.h" ++ ++/* This test case implicitly tests the availability of the __chk_fail ++ symbol, which is part of the public ABI and may be used ++ externally. */ ++extern void __attribute__ ((noreturn)) __chk_fail (void); ++char *simple_strcpy_chk (char *, const char *, size_t); ++extern char *normal_strcpy (char *, const char *, size_t) ++ __asm ("strcpy"); ++extern char *__strcpy_chk (char *, const char *, size_t); ++ ++IMPL (simple_strcpy_chk, 0) ++IMPL (normal_strcpy, 1) ++IMPL (__strcpy_chk, 2) ++ ++char * ++simple_strcpy_chk (char *dst, const char *src, size_t len) ++{ ++ char *ret = dst; ++ if (! len) ++ __chk_fail (); ++ while ((*dst++ = *src++) != '\0') ++ if (--len == 0) ++ __chk_fail (); ++ return ret; ++} ++#endif ++ ++#include ++#include ++#include ++#include ++ ++static int test_main (void); ++#include "../test-skeleton.c" ++ ++volatile int chk_fail_ok; ++jmp_buf chk_fail_buf; ++ ++static void ++handler (int sig) ++{ ++ if (chk_fail_ok) ++ { ++ chk_fail_ok = 0; ++ longjmp (chk_fail_buf, 1); ++ } ++ else ++ _exit (127); ++} ++ ++typedef char *(*proto_t) (char *, const char *, size_t); ++ ++static void ++do_one_test (impl_t *impl, char *dst, const char *src, ++ size_t len, size_t dlen) ++{ ++ char *res; ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (dlen <= len) ++ { ++ if (impl->test == 1) ++ return; ++ ++ chk_fail_ok = 1; ++ if (setjmp (chk_fail_buf) == 0) ++ { ++ res = CALL (impl, dst, src, dlen); ++ printf ("*** Function %s (%zd; %zd) did not __chk_fail\n", ++ impl->name, len, dlen); ++ chk_fail_ok = 0; ++ ret = 1; ++ } ++ return; ++ } ++ else ++ res = CALL (impl, dst, src, dlen); ++ ++ if (res != STRCPY_RESULT (dst, len)) ++ { ++ printf ("Wrong result in function %s %p %p\n", impl->name, ++ res, STRCPY_RESULT (dst, len)); ++ ret = 1; ++ return; ++ } ++ ++ if (strcmp (dst, src) != 0) ++ { ++ printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n", ++ impl->name, dst, src); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, dst, src, dlen); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, size_t dlen, int max_char) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ align1 &= 7; ++ if (align1 + len >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + len >= page_size) ++ return; ++ ++ s1 = (char *) buf1 + align1; ++ s2 = (char *) buf2 + align2; ++ ++ for (i = 0; i < len; i++) ++ s1[i] = 32 + 23 * i % (max_char - 32); ++ s1[len] = 0; ++ ++ if (dlen > len) ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s2, s1, len, dlen); ++ ++ if (dlen > len) ++ putchar ('\n'); ++} ++ ++static int ++test_main (void) ++{ ++ size_t i; ++ ++ set_fortify_handler (handler); ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 16; ++i) ++ { ++ do_test (0, 0, i, i + 1, 127); ++ do_test (0, 0, i, i + 1, 255); ++ do_test (0, i, i, i + 1, 127); ++ do_test (i, 0, i, i + 1, 255); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, (8 << i) + 1, 127); ++ do_test (8 - i, 2 * i, (8 << i), (8 << i) + 1, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, (8 << i), (8 << i) + 1, 127); ++ do_test (2 * i, i, (8 << i), (8 << i) + 1, 255); ++ do_test (i, i, (8 << i), (8 << i) + 1, 127); ++ do_test (i, i, (8 << i), (8 << i) + 1, 255); ++ } ++ ++ for (i = 0; i < 16; ++i) ++ { ++ do_test (0, 0, i, i + 256, 127); ++ do_test (0, 0, i, i + 256, 255); ++ do_test (0, i, i, i + 256, 127); ++ do_test (i, 0, i, i + 256, 255); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, (8 << i) + 256, 127); ++ do_test (8 - i, 2 * i, (8 << i), (8 << i) + 256, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, (8 << i), (8 << i) + 256, 127); ++ do_test (2 * i, i, (8 << i), (8 << i) + 256, 255); ++ do_test (i, i, (8 << i), (8 << i) + 256, 127); ++ do_test (i, i, (8 << i), (8 << i) + 256, 255); ++ } ++ ++ for (i = 0; i < 16; ++i) ++ { ++ do_test (0, 0, i, i, 127); ++ do_test (0, 0, i, i + 2, 255); ++ do_test (0, i, i, i + 3, 127); ++ do_test (i, 0, i, i + 4, 255); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, (8 << i) - 15, 127); ++ do_test (8 - i, 2 * i, (8 << i), (8 << i) + 5, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, (8 << i), (8 << i) + i, 127); ++ do_test (2 * i, i, (8 << i), (8 << i) + (i - 1), 255); ++ do_test (i, i, (8 << i), (8 << i) + i + 2, 127); ++ do_test (i, i, (8 << i), (8 << i) + i + 3, 255); ++ } ++ ++ return 0; ++} +diff -urN glibc-2.17-c758a686/benchtests/bench-strcspn.c glibc-2.17-c758a686/benchtests/bench-strcspn.c +--- glibc-2.17-c758a686/benchtests/bench-strcspn.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strcspn.c 2015-06-20 21:22:16.298458075 -0400 +@@ -0,0 +1,59 @@ ++/* Measure strcspn functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRPBRK_RESULT(s, pos) (pos) ++#define RES_TYPE size_t ++#define TEST_MAIN ++#define TEST_NAME "strcspn" ++#include "bench-string.h" ++ ++typedef size_t (*proto_t) (const char *, const char *); ++size_t simple_strcspn (const char *, const char *); ++size_t stupid_strcspn (const char *, const char *); ++ ++IMPL (stupid_strcspn, 0) ++IMPL (simple_strcspn, 0) ++IMPL (strcspn, 1) ++ ++size_t ++simple_strcspn (const char *s, const char *rej) ++{ ++ const char *r, *str = s; ++ char c; ++ ++ while ((c = *s++) != '\0') ++ for (r = rej; *r != '\0'; ++r) ++ if (*r == c) ++ return s - str - 1; ++ return s - str - 1; ++} ++ ++size_t ++stupid_strcspn (const char *s, const char *rej) ++{ ++ size_t ns = strlen (s), nrej = strlen (rej); ++ size_t i, j; ++ ++ for (i = 0; i < ns; ++i) ++ for (j = 0; j < nrej; ++j) ++ if (s[i] == rej[j]) ++ return i; ++ return i; ++} ++ ++#include "bench-strpbrk.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-string.h glibc-2.17-c758a686/benchtests/bench-string.h +--- glibc-2.17-c758a686/benchtests/bench-string.h 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-string.h 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,201 @@ ++/* Measure string and memory functions. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++typedef struct ++{ ++ const char *name; ++ void (*fn) (void); ++ long test; ++} impl_t; ++extern impl_t __start_impls[], __stop_impls[]; ++ ++#define IMPL(name, test) \ ++ impl_t tst_ ## name \ ++ __attribute__ ((section ("impls"), aligned (sizeof (void *)))) \ ++ = { __STRING (name), (void (*) (void))name, test }; ++ ++#ifdef TEST_MAIN ++ ++# ifndef _GNU_SOURCE ++# define _GNU_SOURCE ++# endif ++ ++# undef __USE_STRING_INLINES ++ ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# define GL(x) _##x ++# define GLRO(x) _##x ++# include "bench-timing.h" ++ ++ ++# define TEST_FUNCTION test_main () ++# define TIMEOUT (4 * 60) ++# define OPT_ITERATIONS 10000 ++# define OPT_RANDOM 10001 ++# define OPT_SEED 10002 ++ ++# define INNER_LOOP_ITERS 64 ++ ++unsigned char *buf1, *buf2; ++int ret, do_srandom; ++unsigned int seed; ++size_t page_size; ++ ++# ifndef ITERATIONS ++size_t iterations = 100000; ++# define ITERATIONS_OPTIONS \ ++ { "iterations", required_argument, NULL, OPT_ITERATIONS }, ++# define ITERATIONS_PROCESS \ ++ case OPT_ITERATIONS: \ ++ iterations = strtoul (optarg, NULL, 0); \ ++ break; ++# define ITERATIONS iterations ++# else ++# define ITERATIONS_OPTIONS ++# define ITERATIONS_PROCESS ++# endif ++ ++# define CMDLINE_OPTIONS ITERATIONS_OPTIONS \ ++ { "random", no_argument, NULL, OPT_RANDOM }, \ ++ { "seed", required_argument, NULL, OPT_SEED }, ++# define CMDLINE_PROCESS ITERATIONS_PROCESS \ ++ case OPT_RANDOM: \ ++ { \ ++ int fdr = open ("/dev/urandom", O_RDONLY); \ ++ \ ++ if (fdr < 0 || read (fdr, &seed, sizeof(seed)) != sizeof (seed)) \ ++ seed = time (NULL); \ ++ if (fdr >= 0) \ ++ close (fdr); \ ++ do_srandom = 1; \ ++ break; \ ++ } \ ++ \ ++ case OPT_SEED: \ ++ seed = strtoul (optarg, NULL, 0); \ ++ do_srandom = 1; \ ++ break; ++ ++# define CALL(impl, ...) \ ++ (* (proto_t) (impl)->fn) (__VA_ARGS__) ++ ++# ifdef TEST_NAME ++/* Increase size of FUNC_LIST if assert is triggered at run-time. */ ++static struct libc_ifunc_impl func_list[32]; ++static int func_count; ++static int impl_count = -1; ++static impl_t *impl_array; ++ ++# define FOR_EACH_IMPL(impl, notall) \ ++ impl_t *impl; \ ++ int count; \ ++ if (impl_count == -1) \ ++ { \ ++ impl_count = 0; \ ++ if (func_count != 0) \ ++ { \ ++ int f; \ ++ impl_t *skip = NULL, *a; \ ++ for (impl = __start_impls; impl < __stop_impls; ++impl) \ ++ if (strcmp (impl->name, TEST_NAME) == 0) \ ++ skip = impl; \ ++ else \ ++ impl_count++; \ ++ a = impl_array = malloc ((impl_count + func_count) * \ ++ sizeof (impl_t)); \ ++ for (impl = __start_impls; impl < __stop_impls; ++impl) \ ++ if (impl != skip) \ ++ *a++ = *impl; \ ++ for (f = 0; f < func_count; f++) \ ++ if (func_list[f].usable) \ ++ { \ ++ a->name = func_list[f].name; \ ++ a->fn = func_list[f].fn; \ ++ a->test = 1; \ ++ a++; \ ++ } \ ++ impl_count = a - impl_array; \ ++ } \ ++ else \ ++ { \ ++ impl_count = __stop_impls - __start_impls; \ ++ impl_array = __start_impls; \ ++ } \ ++ } \ ++ impl = impl_array; \ ++ for (count = 0; count < impl_count; ++count, ++impl) \ ++ if (!notall || impl->test) ++# else /* !TEST_NAME */ ++# define FOR_EACH_IMPL(impl, notall) \ ++ for (impl_t *impl = __start_impls; impl < __stop_impls; ++impl) \ ++ if (!notall || impl->test) ++# endif /* !TEST_NAME */ ++ ++# ifndef BUF1PAGES ++# define BUF1PAGES 1 ++# endif ++ ++static void ++test_init (void) ++{ ++# ifdef TEST_NAME ++ func_count = __libc_ifunc_impl_list (TEST_NAME, func_list, ++ (sizeof func_list ++ / sizeof func_list[0])); ++# endif ++ ++ page_size = 2 * getpagesize (); ++# ifdef MIN_PAGE_SIZE ++ if (page_size < MIN_PAGE_SIZE) ++ page_size = MIN_PAGE_SIZE; ++# endif ++ buf1 = mmap (0, (BUF1PAGES + 1) * page_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, 0); ++ if (buf1 == MAP_FAILED) ++ error (EXIT_FAILURE, errno, "mmap failed"); ++ if (mprotect (buf1 + BUF1PAGES * page_size, page_size, PROT_NONE)) ++ error (EXIT_FAILURE, errno, "mprotect failed"); ++ buf2 = mmap (0, 2 * page_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANON, -1, 0); ++ if (buf2 == MAP_FAILED) ++ error (EXIT_FAILURE, errno, "mmap failed"); ++ if (mprotect (buf2 + page_size, page_size, PROT_NONE)) ++ error (EXIT_FAILURE, errno, "mprotect failed"); ++ if (do_srandom) ++ { ++ printf ("Setting seed to 0x%x\n", seed); ++ srandom (seed); ++ } ++ ++ memset (buf1, 0xa5, BUF1PAGES * page_size); ++ memset (buf2, 0x5a, page_size); ++} ++ ++#endif /* TEST_MAIN */ +diff -urN glibc-2.17-c758a686/benchtests/bench-strlen.c glibc-2.17-c758a686/benchtests/bench-strlen.c +--- glibc-2.17-c758a686/benchtests/bench-strlen.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strlen.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,142 @@ ++/* Measure STRLEN functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifndef WIDE ++# define TEST_NAME "strlen" ++#else ++# define TEST_NAME "wcslen" ++#endif ++#include "bench-string.h" ++ ++#ifndef WIDE ++# define STRLEN strlen ++# define CHAR char ++# define MAX_CHAR CHAR_MAX ++#else ++# include ++# define STRLEN wcslen ++# define CHAR wchar_t ++# define MAX_CHAR WCHAR_MAX ++#endif ++ ++typedef size_t (*proto_t) (const CHAR *); ++ ++size_t ++simple_STRLEN (const CHAR *s) ++{ ++ const CHAR *p; ++ ++ for (p = s; *p; ++p); ++ return p - s; ++} ++ ++#ifndef WIDE ++size_t ++builtin_strlen (const CHAR *p) ++{ ++ return __builtin_strlen (p); ++} ++IMPL (builtin_strlen, 0) ++#endif ++ ++IMPL (simple_STRLEN, 0) ++IMPL (STRLEN, 1) ++ ++ ++static void ++do_one_test (impl_t *impl, const CHAR *s, size_t exp_len) ++{ ++ size_t len = CALL (impl, s), i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (len != exp_len) ++ { ++ error (0, 0, "Wrong result in function %s %zd %zd", impl->name, ++ len, exp_len); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t len) ++{ ++ size_t i; ++ ++ align &= 63; ++ if (align + sizeof(CHAR) * len >= page_size) ++ return; ++ ++ CHAR *buf = (CHAR *) (buf1); ++ ++ for (i = 0; i < len; ++i) ++ buf[align + i] = 1 + 11111 * i % MAX_CHAR; ++ buf[align + len] = 0; ++ ++ printf ("Length %4zd, alignment %2zd:", len, align); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (CHAR *) (buf + align), len); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%20s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ /* Checking with only 4 * N alignments for wcslen, other alignments are wrong for wchar_t type arrays*/ ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (sizeof(CHAR) * i, i); ++ do_test (0, i); ++ } ++ ++ for (i = 2; i <= 12; ++i) ++ { ++ do_test (0, 1 << i); ++ do_test (sizeof(CHAR) * 7, 1 << i); ++ do_test (sizeof(CHAR) * i, 1 << i); ++ do_test (sizeof(CHAR) * i, (size_t)((1 << i) / 1.5)); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strncasecmp.c glibc-2.17-c758a686/benchtests/bench-strncasecmp.c +--- glibc-2.17-c758a686/benchtests/bench-strncasecmp.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strncasecmp.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,207 @@ ++/* Measure strncasecmp functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#define TEST_MAIN ++#define TEST_NAME "strncasecmp" ++#include "bench-string.h" ++ ++typedef int (*proto_t) (const char *, const char *, size_t); ++static int simple_strncasecmp (const char *, const char *, size_t); ++static int stupid_strncasecmp (const char *, const char *, size_t); ++ ++IMPL (stupid_strncasecmp, 0) ++IMPL (simple_strncasecmp, 0) ++IMPL (strncasecmp, 1) ++ ++static int ++simple_strncasecmp (const char *s1, const char *s2, size_t n) ++{ ++ int ret; ++ ++ if (n == 0) ++ return 0; ++ ++ while ((ret = ((unsigned char) tolower (*s1) ++ - (unsigned char) tolower (*s2))) == 0 ++ && *s1++) ++ { ++ if (--n == 0) ++ return 0; ++ ++s2; ++ } ++ return ret; ++} ++ ++static int ++stupid_strncasecmp (const char *s1, const char *s2, size_t max) ++{ ++ size_t ns1 = strlen (s1) + 1; ++ size_t ns2 = strlen (s2) + 1; ++ size_t n = ns1 < ns2 ? ns1 : ns2; ++ if (n > max) ++ n = max; ++ int ret = 0; ++ ++ while (n--) ++ { ++ if ((ret = ((unsigned char) tolower (*s1) ++ - (unsigned char) tolower (*s2))) != 0) ++ break; ++ ++s1; ++ ++s2; ++ } ++ return ret; ++} ++ ++static void ++do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, ++ int exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2, n); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, ++ int exp_result) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ if (len == 0) ++ return; ++ ++ align1 &= 7; ++ if (align1 + len + 1 >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + len + 1 >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0; i < len; i++) ++ { ++ s1[i] = toupper (1 + 23 * i % max_char); ++ s2[i] = tolower (s1[i]); ++ } ++ ++ s1[len] = s2[len] = 0; ++ s1[len + 1] = 23; ++ s2[len + 1] = 24 + exp_result; ++ if ((s2[len - 1] == 'z' && exp_result == -1) ++ || (s2[len - 1] == 'a' && exp_result == 1)) ++ s1[len - 1] += exp_result; ++ else ++ s2[len - 1] -= exp_result; ++ ++ printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, n, exp_result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 16; ++i) ++ { ++ do_test (i, i, i - 1, i, 127, 0); ++ ++ do_test (i, i, i, i, 127, 0); ++ do_test (i, i, i, i, 127, 1); ++ do_test (i, i, i, i, 127, -1); ++ ++ do_test (i, i, i + 1, i, 127, 0); ++ do_test (i, i, i + 1, i, 127, 1); ++ do_test (i, i, i + 1, i, 127, -1); ++ } ++ ++ for (i = 1; i < 10; ++i) ++ { ++ do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0); ++ do_test (0, 0, 2 << i, 2 << i, 254, 0); ++ do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0); ++ ++ do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0); ++ ++ do_test (0, 0, 2 << i, 2 << i, 127, 1); ++ do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1); ++ ++ do_test (0, 0, 2 << i, 2 << i, 254, 1); ++ do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1); ++ ++ do_test (0, 0, 2 << i, 2 << i, 127, -1); ++ do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1); ++ ++ do_test (0, 0, 2 << i, 2 << i, 254, -1); ++ do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0); ++ do_test (i, 2 * i, 8 << i, 8 << i, 127, 0); ++ do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0); ++ ++ do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0); ++ do_test (2 * i, i, 8 << i, 8 << i, 254, 0); ++ do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0); ++ ++ do_test (i, 2 * i, 8 << i, 8 << i, 127, 1); ++ do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1); ++ ++ do_test (2 * i, i, 8 << i, 8 << i, 254, 1); ++ do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1); ++ ++ do_test (i, 2 * i, 8 << i, 8 << i, 127, -1); ++ do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1); ++ ++ do_test (2 * i, i, 8 << i, 8 << i, 254, -1); ++ do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strncat.c glibc-2.17-c758a686/benchtests/bench-strncat.c +--- glibc-2.17-c758a686/benchtests/bench-strncat.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strncat.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,162 @@ ++/* Measure strncat functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strncat" ++#include "bench-string.h" ++ ++typedef char *(*proto_t) (char *, const char *, size_t); ++char *stupid_strncat (char *, const char *, size_t); ++char *simple_strncat (char *, const char *, size_t); ++ ++IMPL (stupid_strncat, 0) ++IMPL (strncat, 2) ++ ++char * ++stupid_strncat (char *dst, const char *src, size_t n) ++{ ++ char *ret = dst; ++ while (*dst++ != '\0'); ++ --dst; ++ while (n--) ++ if ( (*dst++ = *src++) == '\0') ++ return ret; ++ *dst = '\0'; ++ return ret; ++} ++ ++static void ++do_one_test (impl_t *impl, char *dst, const char *src, size_t n) ++{ ++ size_t k = strlen (dst), i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (CALL (impl, dst, src, n) != dst) ++ { ++ error (0, 0, "Wrong result in function %s %p != %p", impl->name, ++ CALL (impl, dst, src, n), dst); ++ ret = 1; ++ return; ++ } ++ ++ size_t len = strlen (src); ++ if (memcmp (dst + k, src, len + 1 > n ? n : len + 1) != 0) ++ { ++ error (0, 0, "Incorrect cancatination in function %s", ++ impl->name); ++ ret = 1; ++ return; ++ } ++ if (n < len && dst[k + n] != '\0') ++ { ++ error (0, 0, "There is no zero in the end of output string in %s", ++ impl->name); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ dst[k] = '\0'; ++ CALL (impl, dst, src, n); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len1, size_t len2, ++ size_t n, int max_char) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ align1 &= 7; ++ if (align1 + len1 >= page_size) ++ return; ++ if (align1 + n > page_size) ++ return; ++ align2 &= 7; ++ if (align2 + len1 + len2 >= page_size) ++ return; ++ if (align2 + len1 + n > page_size) ++ return; ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0; i < len1; ++i) ++ s1[i] = 32 + 23 * i % (max_char - 32); ++ s1[len1] = '\0'; ++ ++ for (i = 0; i < len2; i++) ++ s2[i] = 32 + 23 * i % (max_char - 32); ++ ++ printf ("Length %4zd/%4zd, alignment %2zd/%2zd, N %4zd:", ++ len1, len2, align1, align2, n); ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ s2[len2] = '\0'; ++ do_one_test (impl, s2, s1, n); ++ } ++ ++ putchar ('\n'); ++} ++ ++int ++main (void) ++{ ++ size_t i, n; ++ ++ test_init (); ++ ++ printf ("%28s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (n = 2; n <= 2048; n*=4) ++ { ++ do_test (0, 2, 2, 2, n, 127); ++ do_test (0, 0, 4, 4, n, 127); ++ do_test (4, 0, 4, 4, n, 255); ++ do_test (0, 0, 8, 8, n, 127); ++ do_test (0, 8, 8, 8, n, 127); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, 8 << i, n, 127); ++ do_test (8 - i, 2 * i, 8 << i, 8 << i, n, 127); ++ do_test (0, 0, 8 << i, 2 << i, n, 127); ++ do_test (8 - i, 2 * i, 8 << i, 2 << i, n, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 2 * i, 8 << i, 1, n, 127); ++ do_test (2 * i, i, 8 << i, 1, n, 255); ++ do_test (i, i, 8 << i, 10, n, 127); ++ } ++ } ++ ++ return ret; ++} +diff -urN glibc-2.17-c758a686/benchtests/bench-strncmp.c glibc-2.17-c758a686/benchtests/bench-strncmp.c +--- glibc-2.17-c758a686/benchtests/bench-strncmp.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strncmp.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,239 @@ ++/* Measure strncmp functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strncmp" ++#include "bench-string.h" ++ ++typedef int (*proto_t) (const char *, const char *, size_t); ++int simple_strncmp (const char *, const char *, size_t); ++int stupid_strncmp (const char *, const char *, size_t); ++ ++IMPL (stupid_strncmp, 0) ++IMPL (simple_strncmp, 0) ++IMPL (strncmp, 1) ++ ++int ++simple_strncmp (const char *s1, const char *s2, size_t n) ++{ ++ int ret = 0; ++ ++ while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0 ++ && *s1++); ++ return ret; ++} ++ ++int ++stupid_strncmp (const char *s1, const char *s2, size_t n) ++{ ++ size_t ns1 = strnlen (s1, n) + 1, ns2 = strnlen (s2, n) + 1; ++ int ret = 0; ++ ++ n = ns1 < n ? ns1 : n; ++ n = ns2 < n ? ns2 : n; ++ while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0); ++ return ret; ++} ++ ++static void ++do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, ++ int exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2, n); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, ++ int exp_result) ++{ ++ size_t i, align_n; ++ char *s1, *s2; ++ ++ if (n == 0) ++ { ++ s1 = (char*)(buf1 + page_size); ++ s2 = (char*)(buf2 + page_size); ++ printf ("Length %4zd/%4zd:", len, n); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, n, 0); ++ ++ putchar ('\n'); ++ ++ return; ++ } ++ ++ align1 &= 15; ++ align2 &= 15; ++ align_n = (page_size - n) & 15; ++ ++ s1 = (char*)(buf1 + page_size - n); ++ s2 = (char*)(buf2 + page_size - n); ++ ++ if (align1 < align_n) ++ s1 -= (align_n - align1); ++ ++ if (align2 < align_n) ++ s2 -= (align_n - align2); ++ ++ for (i = 0; i < n; i++) ++ s1[i] = s2[i] = 1 + 23 * i % max_char; ++ ++ if (len < n) ++ { ++ s1[len] = 0; ++ s2[len] = 0; ++ if (exp_result < 0) ++ s2[len] = 32; ++ else if (exp_result > 0) ++ s1[len] = 64; ++ } ++ ++ printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, n, exp_result); ++ ++ putchar ('\n'); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, ++ int exp_result) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ if (n == 0) ++ return; ++ ++ align1 &= 7; ++ if (align1 + n + 1 >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + n + 1 >= page_size) ++ return; ++ ++ s1 = (char*)(buf1 + align1); ++ s2 = (char*)(buf2 + align2); ++ ++ for (i = 0; i < n; i++) ++ s1[i] = s2[i] = 1 + 23 * i % max_char; ++ ++ s1[n] = 24 + exp_result; ++ s2[n] = 23; ++ s1[len] = 0; ++ s2[len] = 0; ++ if (exp_result < 0) ++ s2[len] = 32; ++ else if (exp_result > 0) ++ s1[len] = 64; ++ if (len >= n) ++ s2[n - 1] -= exp_result; ++ ++ printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i =0; i < 16; ++i) ++ { ++ do_test (0, 0, 8, i, 127, 0); ++ do_test (0, 0, 8, i, 127, -1); ++ do_test (0, 0, 8, i, 127, 1); ++ do_test (i, i, 8, i, 127, 0); ++ do_test (i, i, 8, i, 127, 1); ++ do_test (i, i, 8, i, 127, -1); ++ do_test (i, 2 * i, 8, i, 127, 0); ++ do_test (2 * i, i, 8, i, 127, 1); ++ do_test (i, 3 * i, 8, i, 127, -1); ++ do_test (0, 0, 8, i, 255, 0); ++ do_test (0, 0, 8, i, 255, -1); ++ do_test (0, 0, 8, i, 255, 1); ++ do_test (i, i, 8, i, 255, 0); ++ do_test (i, i, 8, i, 255, 1); ++ do_test (i, i, 8, i, 255, -1); ++ do_test (i, 2 * i, 8, i, 255, 0); ++ do_test (2 * i, i, 8, i, 255, 1); ++ do_test (i, 3 * i, 8, i, 255, -1); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 8 << i, 16 << i, 127, 0); ++ do_test (0, 0, 8 << i, 16 << i, 127, 1); ++ do_test (0, 0, 8 << i, 16 << i, 127, -1); ++ do_test (0, 0, 8 << i, 16 << i, 255, 0); ++ do_test (0, 0, 8 << i, 16 << i, 255, 1); ++ do_test (0, 0, 8 << i, 16 << i, 255, -1); ++ do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 0); ++ do_test (8 - i, 2 * i, 8 << i, 16 << i, 127, 1); ++ do_test (2 * i, i, 8 << i, 16 << i, 255, 0); ++ do_test (2 * i, i, 8 << i, 16 << i, 255, 1); ++ } ++ ++ do_test_limit (0, 0, 0, 0, 127, 0); ++ do_test_limit (4, 0, 21, 20, 127, 0); ++ do_test_limit (0, 4, 21, 20, 127, 0); ++ do_test_limit (8, 0, 25, 24, 127, 0); ++ do_test_limit (0, 8, 25, 24, 127, 0); ++ ++ for (i = 0; i < 8; ++i) ++ { ++ do_test_limit (0, 0, 17 - i, 16 - i, 127, 0); ++ do_test_limit (0, 0, 17 - i, 16 - i, 255, 0); ++ do_test_limit (0, 0, 15 - i, 16 - i, 127, 0); ++ do_test_limit (0, 0, 15 - i, 16 - i, 127, 1); ++ do_test_limit (0, 0, 15 - i, 16 - i, 127, -1); ++ do_test_limit (0, 0, 15 - i, 16 - i, 255, 0); ++ do_test_limit (0, 0, 15 - i, 16 - i, 255, 1); ++ do_test_limit (0, 0, 15 - i, 16 - i, 255, -1); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strncpy.c glibc-2.17-c758a686/benchtests/bench-strncpy.c +--- glibc-2.17-c758a686/benchtests/bench-strncpy.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strncpy.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,174 @@ ++/* Measure strncpy functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRNCPY_RESULT ++# define STRNCPY_RESULT(dst, len, n) dst ++# define TEST_MAIN ++# define TEST_NAME "strncpy" ++# include "bench-string.h" ++ ++char *simple_strncpy (char *, const char *, size_t); ++char *stupid_strncpy (char *, const char *, size_t); ++ ++IMPL (stupid_strncpy, 0) ++IMPL (simple_strncpy, 0) ++IMPL (strncpy, 1) ++ ++char * ++simple_strncpy (char *dst, const char *src, size_t n) ++{ ++ char *ret = dst; ++ while (n--) ++ if ((*dst++ = *src++) == '\0') ++ { ++ while (n--) ++ *dst++ = '\0'; ++ return ret; ++ } ++ return ret; ++} ++ ++char * ++stupid_strncpy (char *dst, const char *src, size_t n) ++{ ++ size_t nc = strnlen (src, n); ++ size_t i; ++ ++ for (i = 0; i < nc; ++i) ++ dst[i] = src[i]; ++ for (; i < n; ++i) ++ dst[i] = '\0'; ++ return dst; ++} ++#endif ++ ++typedef char *(*proto_t) (char *, const char *, size_t); ++ ++static void ++do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n)) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ CALL (impl, dst, src, n), dst); ++ ret = 1; ++ return; ++ } ++ ++ if (memcmp (dst, src, len > n ? n : len) != 0) ++ { ++ error (0, 0, "Wrong result in function %s", impl->name); ++ ret = 1; ++ return; ++ } ++ ++ if (n > len) ++ { ++ size_t i; ++ ++ for (i = len; i < n; ++i) ++ if (dst [i] != '\0') ++ { ++ error (0, 0, "Wrong result in function %s", impl->name); ++ ret = 1; ++ return; ++ } ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, dst, src, n); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) ++{ ++ size_t i; ++ char *s1, *s2; ++ ++ align1 &= 7; ++ if (align1 + len >= page_size) ++ return; ++ ++ align2 &= 7; ++ if (align2 + len >= page_size) ++ return; ++ ++ s1 = (char *) (buf1 + align1); ++ s2 = (char *) (buf2 + align2); ++ ++ for (i = 0; i < len; ++i) ++ s1[i] = 32 + 23 * i % (max_char - 32); ++ s1[len] = 0; ++ for (i = len + 1; i + align1 < page_size && i < len + 64; ++i) ++ s1[i] = 32 + 32 * i % (max_char - 32); ++ ++ printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s2, s1, len, n); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%28s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, i, 16, 16, 127); ++ do_test (i, i, 16, 16, 255); ++ do_test (i, 2 * i, 16, 16, 127); ++ do_test (2 * i, i, 16, 16, 255); ++ do_test (8 - i, 2 * i, 1 << i, 2 << i, 127); ++ do_test (2 * i, 8 - i, 2 << i, 1 << i, 127); ++ do_test (8 - i, 2 * i, 1 << i, 2 << i, 255); ++ do_test (2 * i, 8 - i, 2 << i, 1 << i, 255); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 0, 4 << i, 8 << i, 127); ++ do_test (0, 0, 16 << i, 8 << i, 127); ++ do_test (8 - i, 2 * i, 4 << i, 8 << i, 127); ++ do_test (8 - i, 2 * i, 16 << i, 8 << i, 127); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strnlen.c glibc-2.17-c758a686/benchtests/bench-strnlen.c +--- glibc-2.17-c758a686/benchtests/bench-strnlen.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strnlen.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,132 @@ ++/* Measure strlen functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strnlen" ++#include "bench-string.h" ++ ++typedef size_t (*proto_t) (const char *, size_t); ++size_t simple_strnlen (const char *, size_t); ++ ++IMPL (simple_strnlen, 0) ++IMPL (strnlen, 1) ++ ++size_t ++simple_strnlen (const char *s, size_t maxlen) ++{ ++ size_t i; ++ ++ for (i = 0; i < maxlen && s[i]; ++i); ++ return i; ++} ++ ++static void ++do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len) ++{ ++ size_t len = CALL (impl, s, maxlen), i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (len != exp_len) ++ { ++ error (0, 0, "Wrong result in function %s %zd %zd", impl->name, ++ len, exp_len); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, maxlen); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t len, size_t maxlen, int max_char) ++{ ++ size_t i; ++ ++ align &= 7; ++ if (align + len >= page_size) ++ return; ++ ++ for (i = 0; i < len; ++i) ++ buf1[align + i] = 1 + 7 * i % max_char; ++ buf1[align + len] = 0; ++ ++ printf ("Length %4zd, alignment %2zd:", len, align); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen)); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%20s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, i, i - 1, 127); ++ do_test (0, i, i, 127); ++ do_test (0, i, i + 1, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, i, i - 1, 127); ++ do_test (i, i, i, 127); ++ do_test (i, i, i + 1, 127); ++ } ++ ++ for (i = 2; i <= 10; ++i) ++ { ++ do_test (0, 1 << i, 5000, 127); ++ do_test (1, 1 << i, 5000, 127); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ do_test (0, i, 5000, 255); ++ ++ for (i = 1; i < 8; ++i) ++ do_test (i, i, 5000, 255); ++ ++ for (i = 2; i <= 10; ++i) ++ { ++ do_test (0, 1 << i, 5000, 255); ++ do_test (1, 1 << i, 5000, 255); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strpbrk.c glibc-2.17-c758a686/benchtests/bench-strpbrk.c +--- glibc-2.17-c758a686/benchtests/bench-strpbrk.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strpbrk.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,176 @@ ++/* Measure strpbrk functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef STRPBRK_RESULT ++# define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL) ++# define RES_TYPE char * ++# define TEST_MAIN ++# define TEST_NAME "strpbrk" ++# include "bench-string.h" ++ ++typedef char *(*proto_t) (const char *, const char *); ++char *simple_strpbrk (const char *, const char *); ++char *stupid_strpbrk (const char *, const char *); ++ ++IMPL (stupid_strpbrk, 0) ++IMPL (simple_strpbrk, 0) ++IMPL (strpbrk, 1) ++ ++char * ++simple_strpbrk (const char *s, const char *rej) ++{ ++ const char *r; ++ char c; ++ ++ while ((c = *s++) != '\0') ++ for (r = rej; *r != '\0'; ++r) ++ if (*r == c) ++ return (char *) s - 1; ++ return NULL; ++} ++ ++char * ++stupid_strpbrk (const char *s, const char *rej) ++{ ++ size_t ns = strlen (s), nrej = strlen (rej); ++ size_t i, j; ++ ++ for (i = 0; i < ns; ++i) ++ for (j = 0; j < nrej; ++j) ++ if (s[i] == rej[j]) ++ return (char *) s + i; ++ return NULL; ++} ++#endif ++ ++static void ++do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res) ++{ ++ RES_TYPE res = CALL (impl, s, rej); ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (res != exp_res) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ (void *) res, (void *) exp_res); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, rej); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t pos, size_t len) ++{ ++ size_t i; ++ int c; ++ RES_TYPE result; ++ char *rej, *s; ++ ++ align &= 7; ++ if (align + pos + 10 >= page_size || len > 240) ++ return; ++ ++ rej = (char *) (buf2 + (random () & 255)); ++ s = (char *) (buf1 + align); ++ ++ for (i = 0; i < len; ++i) ++ { ++ rej[i] = random () & 255; ++ if (!rej[i]) ++ rej[i] = random () & 255; ++ if (!rej[i]) ++ rej[i] = 1 + (random () & 127); ++ } ++ rej[len] = '\0'; ++ for (c = 1; c <= 255; ++c) ++ if (strchr (rej, c) == NULL) ++ break; ++ ++ for (i = 0; i < pos; ++i) ++ { ++ s[i] = random () & 255; ++ if (strchr (rej, s[i])) ++ { ++ s[i] = random () & 255; ++ if (strchr (rej, s[i])) ++ s[i] = c; ++ } ++ } ++ s[pos] = rej[random () % (len + 1)]; ++ if (s[pos]) ++ { ++ for (i = pos + 1; i < pos + 10; ++i) ++ s[i] = random () & 255; ++ s[i] = '\0'; ++ } ++ result = STRPBRK_RESULT (s, pos); ++ ++ printf ("Length %4zd, alignment %2zd, rej len %2zd:", pos, align, len); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s, rej, result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%32s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, 512, i); ++ do_test (i, 512, i); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 4); ++ do_test (i, 16 << i, 4); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ do_test (i, 64, 10); ++ ++ for (i = 0; i < 64; ++i) ++ do_test (0, i, 6); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strrchr.c glibc-2.17-c758a686/benchtests/bench-strrchr.c +--- glibc-2.17-c758a686/benchtests/bench-strrchr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strrchr.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,184 @@ ++/* Measure STRCHR functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#ifdef WIDE ++# define TEST_NAME "wcsrchr" ++#else ++# define TEST_NAME "strrchr" ++#endif ++#include "bench-string.h" ++ ++#ifdef WIDE ++# include ++# define SIMPLE_STRRCHR simple_wcsrchr ++# define STRRCHR wcsrchr ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#else ++# define SIMPLE_STRRCHR simple_strrchr ++# define STRRCHR strrchr ++# define CHAR char ++# define UCHAR unsigned char ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#endif ++ ++typedef CHAR *(*proto_t) (const CHAR *, int); ++CHAR *SIMPLE_STRRCHR (const CHAR *, int); ++ ++IMPL (SIMPLE_STRRCHR, 0) ++IMPL (STRRCHR, 1) ++ ++CHAR * ++SIMPLE_STRRCHR (const CHAR *s, int c) ++{ ++ const CHAR *ret = NULL; ++ ++ for (; *s != '\0'; ++s) ++ if (*s == (CHAR) c) ++ ret = s; ++ ++ return (CHAR *) (c == '\0' ? s : ret); ++} ++ ++static void ++do_one_test (impl_t *impl, const CHAR *s, int c, CHAR *exp_res) ++{ ++ CHAR *res = CALL (impl, s, c); ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (res != exp_res) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ res, exp_res); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, c); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t pos, size_t len, int seek_char, int max_char) ++/* For wcsrchr: align here means align not in bytes, ++ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)) ++ len for wcschr here isn't in bytes but it's number of wchar_t symbols. */ ++{ ++ size_t i; ++ CHAR *result; ++ CHAR *buf = (CHAR *) buf1; ++ ++ align &= 7; ++ if ((align + len) * sizeof (CHAR) >= page_size) ++ return; ++ ++ for (i = 0; i < len; ++i) ++ { ++ buf[align + i] = (random () * random ()) & max_char; ++ if (!buf[align + i]) ++ buf[align + i] = (random () * random ()) & max_char; ++ if (!buf[align + i]) ++ buf[align + i] = 1; ++ if ((i > pos || pos >= len) && buf[align + i] == seek_char) ++ buf[align + i] = seek_char + 10 + (random () & 15); ++ } ++ buf[align + len] = 0; ++ ++ if (pos < len) ++ { ++ buf[align + pos] = seek_char; ++ result = (CHAR *) (buf + align + pos); ++ } ++ else if (seek_char == 0) ++ result = (CHAR *) (buf + align + len); ++ else ++ result = NULL; ++ ++ printf ("Length %4zd, alignment in bytes %2zd:", len, align * sizeof (CHAR)); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, (CHAR *) (buf + align), seek_char, result); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%20s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 2048, 23, SMALL_CHAR); ++ do_test (i, 16 << i, 2048, 23, SMALL_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 64, 256, 23, SMALL_CHAR); ++ do_test (i, 64, 256, 23, BIG_CHAR); ++ } ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, i, i + 1, 23, SMALL_CHAR); ++ do_test (0, i, i + 1, 23, BIG_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 2048, 0, SMALL_CHAR); ++ do_test (i, 16 << i, 2048, 0, SMALL_CHAR); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (i, 64, 256, 0, SMALL_CHAR); ++ do_test (i, 64, 256, 0, BIG_CHAR); ++ } ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, i, i + 1, 0, SMALL_CHAR); ++ do_test (0, i, i + 1, 0, BIG_CHAR); ++ } ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strsep.c glibc-2.17-c758a686/benchtests/bench-strsep.c +--- glibc-2.17-c758a686/benchtests/bench-strsep.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strsep.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,174 @@ ++/* Measure strsep functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strsep" ++#include "bench-string.h" ++ ++char * ++simple_strsep (char **s1, char *s2) ++{ ++ char *begin; ++ char *s; ++ size_t j = 0; ++ ++ begin = *s1; ++ s = begin; ++ if (begin == NULL) ++ return NULL; ++ ssize_t s2len = strlen (s2); ++ while (*s) ++ { ++ for (j = 0; j < s2len; j++) ++ { ++ if (*s == s2[j]) ++ { ++ s[0] = '\0'; ++ *s1 = s + 1; ++ return begin; ++ } ++ } ++ s++; ++ } ++ *s1 = NULL; ++ return begin; ++} ++ ++typedef char *(*proto_t) (const char **, const char *); ++ ++IMPL (simple_strsep, 0) ++IMPL (strsep, 1) ++ ++static void ++do_one_test (impl_t * impl, const char *s1, const char *s2) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, &s1, s2); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align1, size_t align2, size_t len1, size_t len2, int fail) ++{ ++ char *s2 = (char *) (buf2 + align2); ++ static const char d[] = "1234567890abcdef"; ++#define dl (sizeof (d) - 1) ++ char *ss2 = s2; ++ for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ ss2 = mempcpy (ss2, d, t); ++ } ++ s2[len2] = '\0'; ++ ++ printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", ++ len1, len2, align1, align2, fail ? "fail" : "found"); ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ char *s1 = (char *) (buf1 + align1); ++ if (fail) ++ { ++ char *ss1 = s1; ++ for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ memcpy (ss1, d, t); ++ ++ss1[len2 > 7 ? 7 : len2 - 1]; ++ ss1 += t; ++ } ++ } ++ else ++ { ++ memset (s1, '0', len1); ++ memcpy (s1 + (len1 - len2) - 2, s2, len2); ++ if ((len1 / len2) > 4) ++ memcpy (s1 + (len1 - len2) - (3 * len2), s2, len2); ++ } ++ s1[len1] = '\0'; ++ do_one_test (impl, s1, s2); ++ } ++ putchar ('\n'); ++} ++ ++static int ++test_main (void) ++{ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (size_t klen = 2; klen < 32; ++klen) ++ for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen) ++ { ++ do_test (0, 0, hlen, klen, 0); ++ do_test (0, 0, hlen, klen, 1); ++ do_test (0, 3, hlen, klen, 0); ++ do_test (0, 3, hlen, klen, 1); ++ do_test (0, 9, hlen, klen, 0); ++ do_test (0, 9, hlen, klen, 1); ++ do_test (0, 15, hlen, klen, 0); ++ do_test (0, 15, hlen, klen, 1); ++ ++ do_test (3, 0, hlen, klen, 0); ++ do_test (3, 0, hlen, klen, 1); ++ do_test (3, 3, hlen, klen, 0); ++ do_test (3, 3, hlen, klen, 1); ++ do_test (3, 9, hlen, klen, 0); ++ do_test (3, 9, hlen, klen, 1); ++ do_test (3, 15, hlen, klen, 0); ++ do_test (3, 15, hlen, klen, 1); ++ ++ do_test (9, 0, hlen, klen, 0); ++ do_test (9, 0, hlen, klen, 1); ++ do_test (9, 3, hlen, klen, 0); ++ do_test (9, 3, hlen, klen, 1); ++ do_test (9, 9, hlen, klen, 0); ++ do_test (9, 9, hlen, klen, 1); ++ do_test (9, 15, hlen, klen, 0); ++ do_test (9, 15, hlen, klen, 1); ++ ++ do_test (15, 0, hlen, klen, 0); ++ do_test (15, 0, hlen, klen, 1); ++ do_test (15, 3, hlen, klen, 0); ++ do_test (15, 3, hlen, klen, 1); ++ do_test (15, 9, hlen, klen, 0); ++ do_test (15, 9, hlen, klen, 1); ++ do_test (15, 15, hlen, klen, 0); ++ do_test (15, 15, hlen, klen, 1); ++ } ++ do_test (0, 0, page_size - 1, 16, 0); ++ do_test (0, 0, page_size - 1, 16, 1); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strspn.c glibc-2.17-c758a686/benchtests/bench-strspn.c +--- glibc-2.17-c758a686/benchtests/bench-strspn.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strspn.c 2015-06-20 21:22:16.299458044 -0400 +@@ -0,0 +1,167 @@ ++/* Measure strspn functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strspn" ++#include "bench-string.h" ++ ++typedef size_t (*proto_t) (const char *, const char *); ++size_t simple_strspn (const char *, const char *); ++size_t stupid_strspn (const char *, const char *); ++ ++IMPL (stupid_strspn, 0) ++IMPL (simple_strspn, 0) ++IMPL (strspn, 1) ++ ++size_t ++simple_strspn (const char *s, const char *acc) ++{ ++ const char *r, *str = s; ++ char c; ++ ++ while ((c = *s++) != '\0') ++ { ++ for (r = acc; *r != '\0'; ++r) ++ if (*r == c) ++ break; ++ if (*r == '\0') ++ return s - str - 1; ++ } ++ return s - str - 1; ++} ++ ++size_t ++stupid_strspn (const char *s, const char *acc) ++{ ++ size_t ns = strlen (s), nacc = strlen (acc); ++ size_t i, j; ++ ++ for (i = 0; i < ns; ++i) ++ { ++ for (j = 0; j < nacc; ++j) ++ if (s[i] == acc[j]) ++ break; ++ if (j == nacc) ++ return i; ++ } ++ return i; ++} ++ ++static void ++do_one_test (impl_t *impl, const char *s, const char *acc, size_t exp_res) ++{ ++ size_t res = CALL (impl, s, acc), i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ if (res != exp_res) ++ { ++ error (0, 0, "Wrong result in function %s %p %p", impl->name, ++ (void *) res, (void *) exp_res); ++ ret = 1; ++ return; ++ } ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s, acc); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++static void ++do_test (size_t align, size_t pos, size_t len) ++{ ++ size_t i; ++ char *acc, *s; ++ ++ align &= 7; ++ if (align + pos + 10 >= page_size || len > 240 || ! len) ++ return; ++ ++ acc = (char *) (buf2 + (random () & 255)); ++ s = (char *) (buf1 + align); ++ ++ for (i = 0; i < len; ++i) ++ { ++ acc[i] = random () & 255; ++ if (!acc[i]) ++ acc[i] = random () & 255; ++ if (!acc[i]) ++ acc[i] = 1 + (random () & 127); ++ } ++ acc[len] = '\0'; ++ ++ for (i = 0; i < pos; ++i) ++ s[i] = acc[random () % len]; ++ s[pos] = random () & 255; ++ if (strchr (acc, s[pos])) ++ s[pos] = '\0'; ++ else ++ { ++ for (i = pos + 1; i < pos + 10; ++i) ++ s[i] = random () & 255; ++ s[i] = '\0'; ++ } ++ ++ printf ("Length %4zd, alignment %2zd, acc len %2zd:", pos, align, len); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s, acc, pos); ++ ++ putchar ('\n'); ++} ++ ++int ++test_main (void) ++{ ++ size_t i; ++ ++ test_init (); ++ ++ printf ("%32s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (i = 0; i < 32; ++i) ++ { ++ do_test (0, 512, i); ++ do_test (i, 512, i); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ { ++ do_test (0, 16 << i, 4); ++ do_test (i, 16 << i, 4); ++ } ++ ++ for (i = 1; i < 8; ++i) ++ do_test (i, 64, 10); ++ ++ for (i = 0; i < 64; ++i) ++ do_test (0, i, 6); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strstr.c glibc-2.17-c758a686/benchtests/bench-strstr.c +--- glibc-2.17-c758a686/benchtests/bench-strstr.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strstr.c 2015-06-20 21:22:16.300458014 -0400 +@@ -0,0 +1,177 @@ ++/* Measure strstr functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strstr" ++#include "bench-string.h" ++ ++ ++#define STRSTR simple_strstr ++#include "../string/strstr.c" ++ ++ ++static char * ++stupid_strstr (const char *s1, const char *s2) ++{ ++ ssize_t s1len = strlen (s1); ++ ssize_t s2len = strlen (s2); ++ ++ if (s2len > s1len) ++ return NULL; ++ ++ for (ssize_t i = 0; i <= s1len - s2len; ++i) ++ { ++ size_t j; ++ for (j = 0; j < s2len; ++j) ++ if (s1[i + j] != s2[j]) ++ break; ++ if (j == s2len) ++ return (char *) s1 + i; ++ } ++ ++ return NULL; ++} ++ ++ ++typedef char *(*proto_t) (const char *, const char *); ++ ++IMPL (stupid_strstr, 0) ++IMPL (simple_strstr, 0) ++IMPL (strstr, 1) ++ ++ ++static void ++do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++} ++ ++ ++static void ++do_test (size_t align1, size_t align2, size_t len1, size_t len2, ++ int fail) ++{ ++ char *s1 = (char *) (buf1 + align1); ++ char *s2 = (char *) (buf2 + align2); ++ ++ static const char d[] = "1234567890abcdef"; ++#define dl (sizeof (d) - 1) ++ char *ss2 = s2; ++ for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ ss2 = mempcpy (ss2, d, t); ++ } ++ s2[len2] = '\0'; ++ ++ if (fail) ++ { ++ char *ss1 = s1; ++ for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ memcpy (ss1, d, t); ++ ++ss1[len2 > 7 ? 7 : len2 - 1]; ++ ss1 += t; ++ } ++ } ++ else ++ { ++ memset (s1, '0', len1); ++ memcpy (s1 + len1 - len2, s2, len2); ++ } ++ s1[len1] = '\0'; ++ ++ printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", ++ len1, len2, align1, align2, fail ? "fail" : "found"); ++ ++ FOR_EACH_IMPL (impl, 0) ++ do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); ++ ++ putchar ('\n'); ++} ++ ++static int ++test_main (void) ++{ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (size_t klen = 2; klen < 32; ++klen) ++ for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen) ++ { ++ do_test (0, 0, hlen, klen, 0); ++ do_test (0, 0, hlen, klen, 1); ++ do_test (0, 3, hlen, klen, 0); ++ do_test (0, 3, hlen, klen, 1); ++ do_test (0, 9, hlen, klen, 0); ++ do_test (0, 9, hlen, klen, 1); ++ do_test (0, 15, hlen, klen, 0); ++ do_test (0, 15, hlen, klen, 1); ++ ++ do_test (3, 0, hlen, klen, 0); ++ do_test (3, 0, hlen, klen, 1); ++ do_test (3, 3, hlen, klen, 0); ++ do_test (3, 3, hlen, klen, 1); ++ do_test (3, 9, hlen, klen, 0); ++ do_test (3, 9, hlen, klen, 1); ++ do_test (3, 15, hlen, klen, 0); ++ do_test (3, 15, hlen, klen, 1); ++ ++ do_test (9, 0, hlen, klen, 0); ++ do_test (9, 0, hlen, klen, 1); ++ do_test (9, 3, hlen, klen, 0); ++ do_test (9, 3, hlen, klen, 1); ++ do_test (9, 9, hlen, klen, 0); ++ do_test (9, 9, hlen, klen, 1); ++ do_test (9, 15, hlen, klen, 0); ++ do_test (9, 15, hlen, klen, 1); ++ ++ do_test (15, 0, hlen, klen, 0); ++ do_test (15, 0, hlen, klen, 1); ++ do_test (15, 3, hlen, klen, 0); ++ do_test (15, 3, hlen, klen, 1); ++ do_test (15, 9, hlen, klen, 0); ++ do_test (15, 9, hlen, klen, 1); ++ do_test (15, 15, hlen, klen, 0); ++ do_test (15, 15, hlen, klen, 1); ++ } ++ ++ do_test (0, 0, page_size - 1, 16, 0); ++ do_test (0, 0, page_size - 1, 16, 1); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strtod.c glibc-2.17-c758a686/benchtests/bench-strtod.c +--- glibc-2.17-c758a686/benchtests/bench-strtod.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strtod.c 2015-06-20 21:22:16.300458014 -0400 +@@ -0,0 +1,120 @@ ++/* Measure strtod implementation. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strtod" ++ ++#include ++#include ++#include "bench-timing.h" ++ ++#undef INNER_LOOP_ITERS ++#define INNER_LOOP_ITERS 65536 ++ ++static const char *inputs[] = ++{ ++ "1e308", ++ "100000000e300", ++ "0x1p1023", ++ "0x1000p1011", ++ "0x1p1020", ++ "0x0.00001p1040" "1e-307", ++ "0.000001e-301", ++ "0.0000001e-300", ++ "0.00000001e-299", ++ "1000000e-313", ++ "10000000e-314", ++ "100000000e-315", ++ "0x1p-1021", ++ "0x1000p-1033", ++ "0x10000p-1037", ++ "0x0.001p-1009", ++ "0x0.0001p-1005", ++ "12.345", ++ "12.345e19", ++ "-.1e+9", ++ ".125", ++ "1e20", ++ "0e-19", ++ "4\00012", ++ "5.9e-76", ++ "0x1.4p+3", ++ "0xAp0", ++ "0x0Ap0", ++ "0x0A", ++ "0xA0", ++ "0x0.A0p8", ++ "0x0.50p9", ++ "0x0.28p10", ++ "0x0.14p11", ++ "0x0.0A0p12", ++ "0x0.050p13", ++ "0x0.028p14", ++ "0x0.014p15", ++ "0x00.00A0p16", ++ "0x00.0050p17", ++ "0x00.0028p18", ++ "0x00.0014p19", ++ "0x1p-1023", ++ "0x0.8p-1022", ++ "Inf", ++ "-Inf", ++ "+InFiNiTy", ++ "0x80000Ap-23", ++ "1e-324", ++ "0x100000000000008p0", ++ "0x100000000000008.p0", ++ "0x100000000000008.00p0", ++ "0x10000000000000800p0", ++ "0x10000000000000801p0", ++ NULL ++}; ++ ++int ++do_bench (void) ++{ ++ const size_t iters = INNER_LOOP_ITERS; ++ timing_t res __attribute__ ((unused)); ++ ++ TIMING_INIT (res); ++ ++ for (size_t i = 0; inputs[i] != NULL; ++i) ++ { ++ char *ep; ++ timing_t start, stop, cur; ++ ++ printf ("Input %-24s:", inputs[i]); ++ TIMING_NOW (start); ++ for (size_t j = 0; j < iters; ++j) ++ strtod (inputs[i], &ep); ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++ putchar ('\n'); ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_bench () ++ ++/* On slower platforms this test needs more than the default 2 seconds. */ ++#define TIMEOUT 10 ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-strtok.c glibc-2.17-c758a686/benchtests/bench-strtok.c +--- glibc-2.17-c758a686/benchtests/bench-strtok.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-strtok.c 2015-06-20 21:22:16.300458014 -0400 +@@ -0,0 +1,152 @@ ++/* Measure strtok functions. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_MAIN ++#define TEST_NAME "strtok" ++#include "bench-string.h" ++ ++#define STRTOK strtok_string ++#include ++ ++ ++typedef char *(*proto_t) (const char *, const char *); ++ ++IMPL (strtok_string, 0) ++IMPL (strtok, 1) ++ ++static void ++do_one_test (impl_t * impl, const char *s1, const char *s2) ++{ ++ size_t i, iters = INNER_LOOP_ITERS; ++ timing_t start, stop, cur; ++ TIMING_NOW (start); ++ for (i = 0; i < iters; ++i) ++ { ++ CALL (impl, s1, s2); ++ CALL (impl, NULL, s2); ++ CALL (impl, NULL, s2); ++ } ++ TIMING_NOW (stop); ++ ++ TIMING_DIFF (cur, start, stop); ++ ++ TIMING_PRINT_MEAN ((double) cur, (double) iters); ++ ++} ++ ++ ++static void ++do_test (size_t align1, size_t align2, size_t len1, size_t len2, int fail) ++{ ++ char *s2 = (char *) (buf2 + align2); ++ static const char d[] = "1234567890abcdef"; ++#define dl (sizeof (d) - 1) ++ char *ss2 = s2; ++ for (size_t l = len2; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ ss2 = mempcpy (ss2, d, t); ++ } ++ s2[len2] = '\0'; ++ ++ printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", ++ len1, len2, align1, align2, fail ? "fail" : "found"); ++ ++ FOR_EACH_IMPL (impl, 0) ++ { ++ char *s1 = (char *) (buf1 + align1); ++ if (fail) ++ { ++ char *ss1 = s1; ++ for (size_t l = len1; l > 0; l = l > dl ? l - dl : 0) ++ { ++ size_t t = l > dl ? dl : l; ++ memcpy (ss1, d, t); ++ ++ss1[len2 > 7 ? 7 : len2 - 1]; ++ ss1 += t; ++ } ++ } ++ else ++ { ++ memset (s1, '0', len1); ++ memcpy (s1 + (len1 - len2) - 2, s2, len2); ++ if ((len1 / len2) > 4) ++ memcpy (s1 + (len1 - len2) - (3 * len2), s2, len2); ++ } ++ s1[len1] = '\0'; ++ do_one_test (impl, s1, s2); ++ } ++ putchar ('\n'); ++} ++ ++static int ++test_main (void) ++{ ++ test_init (); ++ ++ printf ("%23s", ""); ++ FOR_EACH_IMPL (impl, 0) ++ printf ("\t%s", impl->name); ++ putchar ('\n'); ++ ++ for (size_t klen = 2; klen < 32; ++klen) ++ for (size_t hlen = 2 * klen; hlen < 16 * klen; hlen += klen) ++ { ++ do_test (0, 0, hlen, klen, 0); ++ do_test (0, 0, hlen, klen, 1); ++ do_test (0, 3, hlen, klen, 0); ++ do_test (0, 3, hlen, klen, 1); ++ do_test (0, 9, hlen, klen, 0); ++ do_test (0, 9, hlen, klen, 1); ++ do_test (0, 15, hlen, klen, 0); ++ do_test (0, 15, hlen, klen, 1); ++ ++ do_test (3, 0, hlen, klen, 0); ++ do_test (3, 0, hlen, klen, 1); ++ do_test (3, 3, hlen, klen, 0); ++ do_test (3, 3, hlen, klen, 1); ++ do_test (3, 9, hlen, klen, 0); ++ do_test (3, 9, hlen, klen, 1); ++ do_test (3, 15, hlen, klen, 0); ++ do_test (3, 15, hlen, klen, 1); ++ ++ do_test (9, 0, hlen, klen, 0); ++ do_test (9, 0, hlen, klen, 1); ++ do_test (9, 3, hlen, klen, 0); ++ do_test (9, 3, hlen, klen, 1); ++ do_test (9, 9, hlen, klen, 0); ++ do_test (9, 9, hlen, klen, 1); ++ do_test (9, 15, hlen, klen, 0); ++ do_test (9, 15, hlen, klen, 1); ++ ++ do_test (15, 0, hlen, klen, 0); ++ do_test (15, 0, hlen, klen, 1); ++ do_test (15, 3, hlen, klen, 0); ++ do_test (15, 3, hlen, klen, 1); ++ do_test (15, 9, hlen, klen, 0); ++ do_test (15, 9, hlen, klen, 1); ++ do_test (15, 15, hlen, klen, 0); ++ do_test (15, 15, hlen, klen, 1); ++ } ++ do_test (0, 0, page_size - 1, 16, 0); ++ do_test (0, 0, page_size - 1, 16, 1); ++ ++ return ret; ++} ++ ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/benchtests/bench-timing.h glibc-2.17-c758a686/benchtests/bench-timing.h +--- glibc-2.17-c758a686/benchtests/bench-timing.h 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-timing.h 2015-06-20 21:22:16.300458014 -0400 +@@ -0,0 +1,64 @@ ++/* Define timing macros. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#if HP_TIMING_AVAIL && !defined USE_CLOCK_GETTIME ++# define GL(x) _##x ++# define GLRO(x) _##x ++typedef hp_timing_t timing_t; ++ ++# define TIMING_TYPE "hp_timing" ++ ++# define TIMING_INIT(res) ({ (res) = 1; }) ++ ++# define TIMING_NOW(var) HP_TIMING_NOW (var) ++# define TIMING_DIFF(diff, start, end) HP_TIMING_DIFF ((diff), (start), (end)) ++# define TIMING_ACCUM(sum, diff) HP_TIMING_ACCUM_NT ((sum), (diff)) ++ ++#else ++ ++#include ++typedef uint64_t timing_t; ++ ++# define TIMING_TYPE "clock_gettime" ++ ++/* Measure the resolution of the clock so we can scale the number of ++ benchmark iterations by this value. */ ++# define TIMING_INIT(res) \ ++({ \ ++ struct timespec start; \ ++ clock_getres (CLOCK_PROCESS_CPUTIME_ID, &start); \ ++ (res) = start.tv_nsec; \ ++}) ++ ++# define TIMING_NOW(var) \ ++({ \ ++ struct timespec tv; \ ++ clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &tv); \ ++ (var) = (uint64_t) (tv.tv_nsec + (uint64_t) 1000000000 * tv.tv_sec); \ ++}) ++ ++# define TIMING_DIFF(diff, start, end) (diff) = (end) - (start) ++# define TIMING_ACCUM(sum, diff) (sum) += (diff) ++ ++#endif ++ ++#define TIMING_PRINT_MEAN(d_total_s, d_iters) \ ++ printf ("\t%g", (d_total_s) / (d_iters)) +diff -urN glibc-2.17-c758a686/benchtests/bench-timing-type.c glibc-2.17-c758a686/benchtests/bench-timing-type.c +--- glibc-2.17-c758a686/benchtests/bench-timing-type.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/bench-timing-type.c 2015-06-20 21:22:16.300458014 -0400 +@@ -0,0 +1,27 @@ ++/* Print out the timing type used by the benchmark run. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "bench-timing.h" ++#include ++ ++int ++main (int argc, char **argv) ++{ ++ puts (TIMING_TYPE); ++ return 0; ++} +diff -urN glibc-2.17-c758a686/benchtests/cosh-inputs glibc-2.17-c758a686/benchtests/cosh-inputs +--- glibc-2.17-c758a686/benchtests/cosh-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/cosh-inputs 2015-06-20 21:22:16.300458014 -0400 +@@ -0,0 +1,403 @@ ++## args: double ++## ret: double ++## includes: math.h ++-0x1.630fb3c419c60p9 ++0x1.631844f7a96d0p9 ++-0x1.f56fa7db86bf4p5 ++-0x1.631675fa3bc04p9 ++0x1.1946f04588844p-371 ++-0x1.62fac5eb878c6p9 ++0x1.c2f1e6340f9acp-1 ++0x1.38d5f6796e1c6p-172 ++0x1.652cb53670db0p6 ++0x1.bab6037e306ecp4 ++-0x1.d6cc6557b9fe1p-224 ++0x1.2a4a35f11dc8bp-1 ++0x1.7acdf3096f467p-2 ++0x1.62ea1202d9816p9 ++-0x1.ab3a9254e8794p5 ++-0x1.7581c71bf2925p3 ++0x1.6335078d8f6f1p9 ++-0x1.562ea1c51f0f0p7 ++-0x1.5ad3171705e85p2 ++-0x1.a28481bf5abc7p6 ++-0x1.07f19394102cap-155 ++0x1.714f115ded7edp-395 ++-0x1.e3b4e57228498p-226 ++0x1.62ecb5c679f45p9 ++0x1.f5ef70c4d6fe3p-947 ++0x1.07c7d5461c4c1p2 ++0x1.230e2092aaa0ep5 ++0x1.62edf5f8ef2d6p9 ++0x1.633c66e5307e9p9 ++-0x1.ca74063b21508p1 ++-0x1.4517c5d83e40fp-1 ++-0x1.3d480025e3245p7 ++0x1.6307c4b105e8bp9 ++0x1.dac293f73d850p5 ++0x1.ddc3c42ec39bap6 ++0x1.df804326360d0p4 ++-0x1.a729d2ed077a7p8 ++0x1.62e6b6e528603p9 ++0x1.630252d0050e1p9 ++-0x1.d9e2923618018p-312 ++-0x1.da7d05daf1653p-360 ++0x1.632b742e1d0c9p9 ++-0x1.62fdf19fea01cp9 ++0x1.6328531b0a130p9 ++0x1.626da3cbd279bp-65 ++0x1.632cc11415f53p9 ++0x1.99320680205a9p-799 ++-0x1.3a7903b952ff1p-83 ++-0x1.895200d5fefb6p-119 ++-0x1.c26a3720198fcp2 ++-0x1.9fa0e43bb03e6p-2 ++0x1.62e6378477ec7p9 ++-0x1.5a5f3792646e9p-860 ++0x1.1080911dae7d0p-1013 ++0x1.6304f3ed14c82p9 ++0x1.6337149eda940p9 ++0x1.62ec21c319df7p9 ++-0x1.239ff60f28877p6 ++0x1.dec232d4b4a3fp-2 ++-0x1.6655b35bcb861p-951 ++0x1.6322f270f7ff5p9 ++0x1.62e67590a0733p9 ++-0x1.3bd6d2de5b059p-627 ++-0x1.4d2140c9727ddp8 ++0x1.6316835c7cf05p9 ++-0x1.150951ee1275fp0 ++-0x1.8c4344a80043fp-2 ++-0x1.633196bcef4aap9 ++0x1.af57d51a27e27p-747 ++-0x1.7f4191bd896cbp-2 ++-0x1.88703361b4ad5p3 ++0x1.24aa7790e8d36p2 ++-0x1.62faa7a46d17bp9 ++-0x1.9a47f1cda4652p3 ++-0x1.6315b48bf51f2p9 ++-0x1.141d54326d8a1p7 ++0x1.23ffc38155c52p-233 ++-0x1.57b2662e0cbc1p2 ++-0x1.1929f6abc031bp8 ++-0x1.590710edec44dp-817 ++0x1.94c7749a2b80cp-457 ++-0x1.87d6401ddca88p-676 ++-0x1.81cfd513f4ab9p-623 ++-0x1.69fad03b43d66p-700 ++0x1.79300023a52c8p0 ++-0x1.ba2396d33e90cp8 ++-0x1.63057386325ebp9 ++-0x1.728176d7c18f0p-24 ++-0x1.c69e923a07adcp6 ++-0x1.e07082cab8c82p-573 ++0x1.632b31037059ap9 ++-0x1.6336976d5e8adp9 ++0x1.b6cf07dd00ddep-140 ++-0x1.633c1105ee490p9 ++-0x1.1284f1b6941f8p1 ++-0x1.6c8b7360c8e61p0 ++0x1.6d20f44123714p7 ++0x1.cc4af059aa66ap8 ++-0x1.8a2a250959686p-57 ++0x1.f02ac609a5cc1p-87 ++-0x1.a754215ca985dp-2 ++0x1.2825d1de625c8p6 ++0x1.3c1dd34b185a1p6 ++0x1.5486c13874548p-359 ++-0x1.6c62d6c0af55fp6 ++0x1.5947c680bd235p1 ++-0x1.d1ecf009b1e3ap8 ++0x1.d6c6f6b983d6cp7 ++-0x1.d3c651d1da802p0 ++0x1.248074c8c7fd2p1 ++0x1.630c71268199ap9 ++0x1.22379013a9834p-349 ++0x1.6387b36f3b875p8 ++-0x1.632dc46b7230cp9 ++-0x1.216292f12973ap-436 ++0x1.0223b02b8d96bp-459 ++0x1.4512d30165887p1 ++0x1.2762305f5efcbp0 ++-0x1.8982d0e78510bp-802 ++0x1.8713c2f7dd25ap-6 ++0x1.f690a6c3716cbp-3 ++0x1.afe4e13938837p-689 ++0x1.62ff7470df95dp9 ++-0x1.66b997e7d1793p3 ++0x1.aa64953830f35p-1 ++-0x1.05cbb323669c8p7 ++0x1.df98b1662cf01p8 ++-0x1.84acb4c33fff9p1 ++-0x1.75d6f3839dffbp2 ++0x1.6302c49c75ac4p9 ++0x1.54c5f63777d5ap0 ++-0x1.5329b46ad494ep8 ++0x1.62f1d7dc4e8bfp9 ++0x1.5e2af7dfe1034p9 ++0x1.46b0f34a60c14p-276 ++0x1.6302b7464cd16p9 ++0x1.6acba1328de25p-2 ++0x1.214126ebc9ba2p0 ++-0x1.c6abd4778861bp3 ++0x1.62ee439267fe4p9 ++-0x1.019e020b2eed3p-918 ++0x1.67c174b511e76p-194 ++-0x1.a61b930d87e17p-197 ++0x1.6326673bf0ee0p9 ++0x1.62fb546601bb5p9 ++-0x1.630397a6b37e0p9 ++-0x1.487513da26b06p5 ++-0x1.026fa5d7b42fcp-1 ++0x1.a585d6604b0b1p-686 ++0x1.f9dfc189a7a8dp-2 ++-0x1.68c8d3ca045f0p0 ++0x1.0de7b0af3eca8p-424 ++0x1.9bceb245013d8p-1 ++-0x1.b47a67fa0f535p-238 ++0x1.31a6458858034p7 ++-0x1.0baf3575dd3b1p-968 ++0x1.5d07807c20bb9p1 ++0x1.eb7555bb47463p5 ++0x1.6300e31dc8554p9 ++0x1.56bd211140702p-963 ++-0x1.62fc3361285d3p9 ++0x1.6329f34ef70a1p9 ++0x1.3b63d61257d13p4 ++0x1.861950f440148p-1 ++0x1.a37ad4ec1d969p-346 ++-0x1.632b611f08364p9 ++-0x1.52594428d68c5p1 ++-0x1.6323360b63d60p9 ++-0x1.cbeb65785a18cp3 ++-0x1.35d973c1b14fbp1 ++-0x1.dd4d80673e7d0p-159 ++0x1.1610c328054c1p-749 ++0x1.d69ba47595c68p3 ++-0x1.21c707e50660dp4 ++-0x1.0608868eedbc7p-439 ++0x1.633cd176d9771p9 ++-0x1.fb2f329c0bb96p6 ++0x1.b7ed468fb04f9p-2 ++-0x1.23f9c5b9b41c5p6 ++-0x1.9629f1520f28bp-230 ++-0x1.6303c0b5329e9p9 ++0x1.0738a10cb2383p6 ++0x1.6949236f0fb13p0 ++0x1.9356878778911p4 ++0x1.6318527f69db0p9 ++-0x1.915ff68d55569p5 ++-0x1.3c0e136ebb1d3p8 ++0x1.21c663cb76efbp-712 ++0x1.631510cd8cc49p9 ++-0x1.8a9232ce1ce75p-685 ++-0x1.62e9313aabeb2p9 ++-0x1.160a431da0f5ep-1 ++-0x1.50420407b4980p-540 ++0x1.3db012d4e554dp5 ++0x1.07fe346846679p2 ++0x1.e7b8c3d24cd12p-603 ++0x1.6e9e4075373bbp-2 ++0x1.99e534ba6b8c9p1 ++-0x1.ac4ea356f7e7ap-1 ++0x1.26d654fd77e51p-126 ++0x1.630a6325d4276p9 ++0x1.63018139cc344p9 ++0x1.62f446bf431b8p9 ++-0x1.62fa736043269p9 ++0x1.62f6f6ca932f5p9 ++-0x1.db3ff2317460fp-401 ++0x1.182092617c182p-902 ++-0x1.633510495d169p9 ++0x1.07f565702a6dbp-1 ++-0x1.62f3821bac3f3p9 ++-0x1.de739010d6091p7 ++-0x1.f6a97309476d8p6 ++-0x1.92e537f3ea327p-2 ++0x1.630181fc28954p9 ++-0x1.baead70b0c2bap4 ++0x1.6329675608d9fp9 ++0x1.631ca21fe1f5ap9 ++0x1.12e5e651f43bep0 ++0x1.5c1404cdf4b6dp-653 ++-0x1.6327e1c51ff78p9 ++-0x1.8b5c643c1f677p-1 ++0x1.f017e3196ac82p3 ++-0x1.320c539d2690cp8 ++0x1.3232266740c50p1 ++-0x1.9fb7342efeec0p-903 ++0x1.65f6b5e818e38p2 ++0x1.f608f27517700p-132 ++-0x1.6701731068abfp-476 ++0x1.62f873b46c417p9 ++-0x1.10ab76257be04p-134 ++-0x1.71aa41f376409p3 ++0x1.aa3c546601d68p6 ++0x1.330af2c1875b4p-584 ++0x1.467a936424936p8 ++0x1.402ca060e1497p8 ++0x1.8195955afb315p7 ++0x1.e422c06fda329p-252 ++-0x1.9725c1ddcc807p5 ++-0x1.0a669663e4824p1 ++0x1.da54851488f44p-650 ++-0x1.2bf936af0bb54p4 ++0x1.c7b7361a9d625p5 ++0x1.fbafe37560e23p0 ++0x1.32a202fb0895dp7 ++0x1.8507b472339c2p3 ++-0x1.b0498135f2cf1p-40 ++-0x1.34b9e14e1af56p5 ++-0x1.6316075c46ee9p9 ++-0x1.d96f3088164d1p-771 ++0x1.64ec801c7fc0cp1 ++-0x1.6330b03f5aa48p9 ++0x1.8752740d1aff0p2 ++-0x1.b276e5fc0915ap8 ++0x1.3fcdd73dbc27ep-603 ++-0x1.09774517f3944p7 ++-0x1.6319f733c541fp9 ++-0x1.7019f600db82cp7 ++-0x1.6317b78869f21p9 ++0x1.903ff6c315937p-2 ++0x1.fcd75555d1bf5p2 ++0x1.a552c2076a2c0p4 ++0x1.92c1858903f0ap-668 ++-0x1.c91a744e3a0b7p-1 ++-0x1.596c614756426p-305 ++-0x1.cc5644d829eacp-167 ++-0x1.bc96e1aaf042bp0 ++0x1.6337b63365473p9 ++-0x1.ca384346f16a9p8 ++0x1.465d81dad540ep7 ++0x1.632396c691df1p9 ++-0x1.5695b6e7fcd02p6 ++-0x1.f9a446420cdc7p3 ++0x1.f0ad831c3abb4p-46 ++-0x1.ce3bf20083050p8 ++0x1.0b72226f94781p3 ++0x1.2f75110873a31p8 ++0x1.3877f0875dea2p5 ++0x1.632045a8a7ef9p9 ++0x1.62f1877c1501ep9 ++0x1.6310e758dfd28p9 ++0x1.630e01d39d028p9 ++0x1.62f23680e783cp9 ++0x1.83f8e51d82968p6 ++0x1.7e0aa46083883p-2 ++0x1.00e73296682cap7 ++0x1.e333e66e5016ep-1 ++0x1.62f9213f8bc1fp9 ++-0x1.1043c4ca951fbp-23 ++-0x1.231e514c403e4p2 ++0x1.493644a3cb32cp9 ++0x1.6303738c05d04p9 ++0x1.6336a46b6c9bap9 ++0x1.9d2f87fc603f4p5 ++-0x1.633a822e16e6fp9 ++-0x1.62f55568a253dp9 ++-0x1.1262a6a8b160cp-166 ++0x1.ee36b15df2fc4p7 ++-0x1.761b008109568p-95 ++-0x1.62eff1edf3d60p9 ++0x1.aeceb373ec08dp5 ++0x1.1f00608d6c2abp-663 ++0x1.691f4114ddb68p1 ++0x1.3e57e666e2e04p3 ++-0x1.d897a0d2877f2p3 ++-0x1.2cd5b784df531p-548 ++0x1.dde5178b689c3p5 ++-0x1.9a5ff5ea279f8p6 ++0x1.434c61151b76bp-266 ++-0x1.ebd04328781a7p-781 ++-0x1.a7a0d286d7cc0p0 ++-0x1.7cd5764bf11ffp7 ++-0x1.632432d0e9e8fp9 ++-0x1.62e861c33ae29p9 ++0x1.fe89236cc6a12p-1 ++-0x1.daa2368bfcef6p-410 ++-0x1.a69a66dbd2ea1p8 ++0x1.91b5b4560bceap3 ++-0x1.0d2823f9d0f72p3 ++-0x1.630ef52917607p9 ++-0x1.2a2bb2e417439p6 ++0x1.cfd2c4878fd4ep6 ++-0x1.e6ef0724cf5d8p-2 ++-0x1.d3e823224ebe4p8 ++-0x1.79d546d7ccac5p-130 ++-0x1.632752aab262cp9 ++-0x1.98df07527c0bbp8 ++0x1.6312d35913b55p9 ++0x1.600ef62445c5ep4 ++-0x1.62e93642f1118p9 ++0x1.d0378703154bap3 ++-0x1.a3c9c5aedad89p-819 ++0x1.9150c46f64e72p-59 ++-0x1.631537abd1539p9 ++0x1.4eb503a5e519cp6 ++-0x1.c276053dd303bp-733 ++-0x1.f9d4144b54ba6p1 ++0x1.d0d367337f7f6p1 ++0x1.2b2582d457cd0p6 ++-0x1.8c1a422a7d8b8p4 ++-0x1.633754b36f51ap9 ++-0x1.62f596dff99e7p9 ++0x1.d63fe6b5c7c89p7 ++-0x1.6300b68646dc7p9 ++-0x1.630544284f262p9 ++-0x1.2a94d776d7790p3 ++0x1.33e954a4d5c5fp-916 ++0x1.25e337d99f414p-965 ++-0x1.06277554e7c06p-460 ++0x1.883ee57d70e7dp-31 ++0x1.bb0de68e6b79bp-2 ++0x1.62f667f0092adp9 ++-0x1.496ec324e967fp5 ++-0x1.9d6b07d830151p-355 ++0x1.666da5675e27fp1 ++-0x1.f7cdd2a74fc06p1 ++-0x1.2cdd0674e4abfp7 ++-0x1.0d6877109150dp-846 ++-0x1.cf43b2546254bp-1 ++0x1.0078e7f84d8d8p6 ++0x1.62ef2138efd07p9 ++0x1.b6e1c50cdb9d1p-553 ++0x1.90eb01a683bc0p-2 ++0x1.ea80c14d17262p4 ++0x1.e3928304b1b20p7 ++-0x1.5fc8a731a1822p-692 ++-0x1.1de0320fc0737p9 ++-0x1.b07147eb43dd0p4 ++0x1.62fa155e6e26ep9 ++0x1.213554dad3888p9 ++-0x1.66e894b6d218cp6 ++-0x1.7b67d6318a255p7 ++-0x1.1b005777a51cdp7 ++0x1.62e9f2b4a0744p9 ++0x1.d181a480e6c92p-478 ++-0x1.fe14d1c964b0dp-493 ++-0x1.6632749cd8f5fp-320 ++0x1.d038a32d61933p8 ++0x1.632a66cd5c94bp9 ++0x1.631f833e694f8p9 ++0x1.e111c646e8043p-139 ++-0x1.631ec3cf4a7b9p9 ++0x1.6311f75346d75p9 ++-0x1.c6d344d145206p5 ++0x1.ad42672f6fed7p0 ++-0x1.f4d3f0d1b85eep7 ++0x1.d35412055367bp7 ++-0x1.8e94d1fb70dcep2 ++0x1.04c9f0425e693p2 ++-0x1.b0bb57c60b6a0p5 ++0x1.73d4f770b54e0p5 ++0x1.bcb6129b5ff2bp8 ++-0x1.c82390742c1b2p-832 ++-0x1.bed2624f0b283p3 ++-0x1.62fbd7e6a4400p9 ++0x1.262d57250d7cfp-656 ++-0x1.1ebe27d65ffa7p6 ++0x1.7ab2a69e414b6p1 ++0x1.579870e61406fp2 ++0x1.baaef71d93bc9p-22 ++-0x1.6321d7d010e1ap9 +diff -urN glibc-2.17-c758a686/benchtests/cos-inputs glibc-2.17-c758a686/benchtests/cos-inputs +--- glibc-2.17-c758a686/benchtests/cos-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/cos-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,2411 @@ ++## args: double ++## ret: double ++## includes: math.h ++-0x1.5500006d24c56p657 ++-0x1.74eb14d50ab58p838 ++0x1.b6e5537112339p2 ++-0x1.5320f43535558p30 ++0x1.a5d743be1ed81p19 ++-0x1.e44a771e82dd8p325 ++-0x1.37c07097b1e0bp19 ++0x1.b6da163b3a193p-8 ++0x1.9c1d26a5a4d15p19 ++0x1.24fb45187e1cfp25 ++-0x1.8a7204656d1c5p17 ++-0x1.a59a742066c34p34 ++0x1.8907a5632a248p35 ++-0x1.e481d625714fbp0 ++-0x1.ef80132f1ffafp-12 ++-0x1.e9da155008608p671 ++0x1.7a6085f1f7a0bp24 ++0x1.2d6d6713a3cb3p9 ++-0x1.109665062930bp0 ++-0x1.65ded44238895p20 ++-0x1.4debb5bad15c9p411 ++-0x1.b6c131e9e2a95p414 ++-0x1.896a57dbdc990p0 ++0x1.345f96c1b84cbp46 ++-0x1.e54805da72fa3p-24 ++-0x1.d54bf16b395bcp23 ++-0x1.47f9c5e27f6f3p707 ++-0x1.b8a5440ee9fd7p9 ++0x1.5ff3170744344p-18 ++0x1.266593131001bp1020 ++0x1.42e0f5708b4d1p23 ++-0x1.6279c65ab2acap3 ++-0x1.e5ef0437f662ap15 ++-0x1.0750602edf46ap562 ++0x1.249941e897f8dp44 ++0x1.436c067c4c00cp26 ++-0x1.4334507e7a73bp-5 ++-0x1.5f99b4d006698p25 ++0x1.11697571c9c99p502 ++0x1.253f915648fd2p46 ++-0x1.2ecfb6fd18ffcp332 ++-0x1.2b6e350fc35dap25 ++-0x1.a26f8116b1f53p195 ++-0x1.491d341c65181p-7 ++0x1.3c13e14118343p38 ++-0x1.a6a105deff5e0p5 ++-0x1.fbe7761b1e8d2p18 ++0x1.6709c7306f030p26 ++-0x1.adbf8321968d5p112 ++0x1.d9a53349d7df5p624 ++0x1.5454e1450ae1cp463 ++-0x1.5e0c04637d573p724 ++0x1.7951c309d6e27p850 ++0x1.285dc7fdae1ccp26 ++-0x1.c8c2c6e7107dcp40 ++-0x1.b5afc39812d5cp73 ++-0x1.dbf7863f7522dp-9 ++0x1.6ac6347189089p36 ++0x1.27b04425488afp31 ++0x1.cf38e00daa5afp370 ++0x1.303432a81f7e0p189 ++-0x1.8c05308efd7dbp0 ++-0x1.249b044f1f591p-1 ++-0x1.bf68624ae32d8p315 ++0x1.66c281dc83c31p327 ++-0x1.486c663f75760p2 ++-0x1.feab128c4d050p878 ++0x1.f2db6323e2bc8p47 ++0x1.aba1300582abfp-1 ++-0x1.70b692602f649p28 ++0x1.63bbd511e2d1cp1019 ++-0x1.ad48262c26df0p-23 ++0x1.e7a7573e40d0dp1 ++0x1.5081452ccba88p449 ++-0x1.0198677d57aaap19 ++0x1.78cc5057c8ea8p319 ++-0x1.fbf866574db56p1 ++-0x1.13cf375475387p0 ++0x1.9e05552a6ebdbp5 ++0x1.fe8ec1124c5b2p17 ++0x1.801683636a380p854 ++0x1.bed635dab7cc3p10 ++0x1.29d4d1734709ap23 ++-0x1.692a2422044fbp14 ++-0x1.5a8db25d26e70p0 ++0x1.65e3870f3c860p309 ++0x1.3caf03947f677p1 ++0x1.0a60b6ecb0107p22 ++0x1.8cbcc6715593ep30 ++0x1.faa85328a30d0p858 ++-0x1.700da718a4a31p0 ++0x1.59c2127ae8e32p20 ++0x1.a5e3214dc3d15p647 ++-0x1.1db30365f086dp1 ++-0x1.0399c3c28453ap0 ++-0x1.dd8f835681c23p1017 ++0x1.2751c6b1cde31p478 ++-0x1.b881719d9f6bdp-16 ++0x1.22f885319d1b5p-20 ++0x1.e5d4d0d25845ap-23 ++0x1.0045944e09121p37 ++0x1.3fa8c311b4a60p38 ++0x1.e55e21efd912dp46 ++0x1.6d5f5310aea1bp646 ++-0x1.d3570603de208p23 ++0x1.3365358de2fe1p161 ++-0x1.629526ed15f02p26 ++-0x1.e62dc4d44fab1p40 ++0x1.e1f9c02374c6dp24 ++-0x1.90a100664e089p-21 ++0x1.8dafd569a76b4p26 ++-0x1.406e919853bcfp694 ++0x1.931d703570765p711 ++-0x1.6973e3885a11ep0 ++0x1.9e6a122e9eb4ap8 ++0x1.35a7e5d0935fdp222 ++-0x1.2d6c2408f3370p667 ++0x1.e08e82243180fp0 ++-0x1.ec6237ba9b765p906 ++-0x1.f01e76edc5f71p0 ++-0x1.5cbd54e60a98ep-1 ++0x1.9e0250bdd8df6p426 ++0x1.d78115ab10587p107 ++-0x1.2d739249672fbp17 ++0x1.fedb779d35b35p41 ++-0x1.8f0c6774e24acp889 ++0x1.0244d1b6b4fe3p31 ++-0x1.c2bfd0a931704p3 ++-0x1.1cf0950e0a018p15 ++-0x1.ec54b3a8ffc12p24 ++-0x1.88c5a3114de94p492 ++-0x1.30b5d5aec851cp940 ++-0x1.5b9bc4ee38a1bp-24 ++0x1.3341961dfc2ddp659 ++-0x1.c78046362a6a5p3 ++0x1.2d6e122696618p750 ++-0x1.4730d67c27d89p-3 ++-0x1.e6f9821fd5f72p21 ++-0x1.dc9c33c3b4affp11 ++0x1.f0390127af37bp1 ++0x1.a105328b91461p904 ++0x1.ca3296a765ee9p29 ++0x1.9ed025781f734p-8 ++-0x1.38b913b9a8502p54 ++0x1.80cf557137b99p40 ++-0x1.ef48673d98d25p20 ++0x1.e98c94063264ep314 ++-0x1.98cf55855bf23p0 ++0x1.a20040bbc9705p24 ++-0x1.bbaa1373a6b04p-13 ++0x1.3a05a58adde58p-26 ++0x1.c286149c7e9f5p470 ++-0x1.6b81753989e5ap25 ++0x1.25b0b093ed7f8p2 ++-0x1.0fa8f1bcd9638p467 ++-0x1.58a1939b34f60p25 ++0x1.dbd641b5c98edp117 ++0x1.1fb4562dd42aap-16 ++0x1.14e3242e58954p0 ++0x1.d3a2230b9e01ep897 ++-0x1.53b4b1f9012a0p497 ++-0x1.024f21758b27ep0 ++-0x1.c507e0d80c18bp388 ++0x1.7a51e62e9bbf7p489 ++-0x1.964e538ed6a85p29 ++0x1.273937c7e6db5p315 ++0x1.d1cd90de0d573p1 ++0x1.d879906814a5cp-24 ++0x1.9c0153b0ede21p46 ++-0x1.956a15502cadcp-23 ++0x1.445f06629acb9p24 ++-0x1.01310510ba8afp37 ++-0x1.3fe9d1eac62fbp773 ++-0x1.25ab5749018d2p611 ++-0x1.80cfc67e14b4fp26 ++0x1.7ecf27b07b148p23 ++0x1.43101294381abp26 ++0x1.6c2761f81b901p-23 ++0x1.ba9fe7138c3cep112 ++-0x1.21d97415b6ba7p15 ++-0x1.6e0e76aaf7d3ep-7 ++0x1.776856675164ep4 ++0x1.e6da629a8c493p-19 ++-0x1.08d20753e957dp657 ++0x1.3e58548ada7d0p-14 ++-0x1.c101c29c2ca2bp671 ++0x1.f81ae7d44a371p151 ++0x1.ceebb1e9b0ac5p25 ++0x1.1efb100681836p1 ++0x1.8af3458dfddf7p13 ++-0x1.2568259ec877fp15 ++0x1.63c373ca8604cp-19 ++0x1.bc2476e5f6203p26 ++0x1.d21a939613119p14 ++0x1.7a7d113ec8249p0 ++-0x1.1cc05529e617cp4 ++0x1.78fad183e2167p6 ++-0x1.9416a783a4e38p25 ++-0x1.51e6d29257863p47 ++-0x1.382e97b6481f3p45 ++0x1.17fc047aebf99p10 ++0x1.40c8b1a325f9bp33 ++0x1.d5bbf4c199cbap29 ++-0x1.df5752482cfe6p-20 ++-0x1.12c1f684ae960p14 ++0x1.2a8757492a1acp29 ++-0x1.891c334662682p16 ++0x1.8d82378077273p6 ++0x1.166da45911fe3p154 ++-0x1.202fe7e0931ecp25 ++0x1.f671a5c525c60p25 ++-0x1.a16666f2d0d73p0 ++0x1.341e9765a7c3dp26 ++-0x1.1e626406b087dp-21 ++-0x1.790a818b2e25cp26 ++-0x1.b42b75a1c17cep11 ++0x1.57a50372893aap129 ++0x1.c9f2355b4664ap6 ++-0x1.670df37270a5dp47 ++0x1.8e63d0b3e0c9ap533 ++-0x1.8c842353144b7p0 ++0x1.14bfe1e6692bfp3 ++-0x1.8daca557ecbc8p0 ++0x1.0f66604e1cae6p1 ++0x1.6b4b447033d3cp17 ++-0x1.34fbd3e9490bfp343 ++0x1.9a8b8523a35d1p0 ++-0x1.bacaa7bb3931cp709 ++-0x1.6ce3907ecd3eap27 ++-0x1.6329f65be40dfp388 ++0x1.9f4407a6b30dbp-4 ++-0x1.c64231dff1ff8p-1 ++-0x1.f9d481e9d8a98p21 ++-0x1.3150861950cb4p7 ++0x1.709e700648c1dp3 ++0x1.0248a23a58372p-11 ++-0x1.ca6a851aa0470p12 ++0x1.b24d336cb3971p0 ++0x1.2ad5a72281833p24 ++-0x1.4043b11fad8b6p-24 ++-0x1.e73a03bba587cp0 ++0x1.46cfe1fec14f8p40 ++-0x1.7dfd30173d85cp39 ++-0x1.628c71e6500b1p0 ++-0x1.7e77e7b456aebp16 ++0x1.1df3c34e26e48p21 ++0x1.1ac7a39becc9fp29 ++0x1.1515d5cb1c51cp1 ++-0x1.67cab45949d3bp22 ++0x1.e4e286c86c45fp-16 ++-0x1.8cd97769969d7p483 ++0x1.ce30758136824p27 ++0x1.95b154a54a24cp37 ++0x1.acffd079cb0c5p412 ++-0x1.411c8332662bfp0 ++-0x1.7bc4041696bdbp1 ++0x1.c4ab9624d294fp445 ++-0x1.d1fcb4363c5bep-20 ++-0x1.bea1604dd499dp23 ++0x1.a108a042c4592p1 ++-0x1.04fb706aa9341p17 ++0x1.6a7111c6128c2p20 ++0x1.193151e0fd7c5p-10 ++-0x1.4b06317e471c3p119 ++0x1.cecb95b038037p792 ++-0x1.a561975e1d17ap44 ++-0x1.a8c170e426f1fp1 ++-0x1.53be42cd2bdebp7 ++-0x1.7ccd663e6d70fp-25 ++-0x1.182736e3f62e0p466 ++0x1.ac67800768ebcp12 ++-0x1.09a9d58fea51ap7 ++-0x1.75fc03701c53ep13 ++-0x1.3d9615a1f4a5dp-23 ++0x1.0e7e11092806bp343 ++-0x1.348fe488f91eep46 ++-0x1.1fad639f2da7bp8 ++-0x1.40aae476e0ed5p662 ++0x1.9f70f2da0cc95p132 ++-0x1.da5486badb181p-1 ++-0x1.3b3f076f46893p-9 ++-0x1.0b5187929e913p22 ++0x1.781ca4f1df000p0 ++0x1.6ceb8227b17f8p0 ++-0x1.5445a1397c2f2p751 ++0x1.5418512e0a8a1p8 ++-0x1.533876ccfba74p477 ++0x1.3396d7a19dc51p644 ++0x1.3cdb768fc6e00p-17 ++-0x1.1810260402476p2 ++-0x1.e2815264307f0p21 ++0x1.fb7b8378ba7b1p3 ++-0x1.7bc8c6f28c24bp0 ++-0x1.de5186502e418p-3 ++0x1.cc6417710e32dp9 ++-0x1.b74806ec02f90p-3 ++0x1.7b297737f89a6p0 ++-0x1.e7bf0149253d7p0 ++-0x1.691d818b4a914p-27 ++0x1.ffcfb3b604abep25 ++-0x1.0fd1f4204dd47p26 ++-0x1.349960924dd94p25 ++0x1.330097fdd7ff0p15 ++0x1.bb7555f93a67cp0 ++-0x1.e8d0023eb9798p-15 ++0x1.457db3a13df89p23 ++-0x1.d439a114e34d3p43 ++-0x1.33a971d3908ffp1 ++-0x1.8074051196a9fp35 ++-0x1.36caa6f4f6150p20 ++-0x1.e5047468eb004p36 ++-0x1.e2c677eef9254p479 ++0x1.043ad02a44c86p18 ++0x1.a762226b8977fp6 ++-0x1.d1eff1baa8a00p915 ++0x1.73f354e9bec57p0 ++-0x1.5e04c7be5d65ap26 ++0x1.32e6133ae3ba2p973 ++-0x1.130bb36a9180dp0 ++-0x1.0f8635fd75c96p-25 ++0x1.ac6c73500f7f1p977 ++0x1.5f47f080916d2p747 ++-0x1.7c13d0ffb2d1bp0 ++0x1.8cc7a6557936fp0 ++-0x1.3d20c6693cf4dp963 ++0x1.2252e753aae06p32 ++0x1.6102c79abd114p776 ++-0x1.ea41c6f9badc0p22 ++-0x1.4566d3374234ap942 ++0x1.48c290edccc4dp4 ++-0x1.5eb5d6958df05p41 ++0x1.3097218c10affp24 ++-0x1.5f51d4fbc2a24p866 ++-0x1.d961e32aa4458p24 ++0x1.2bd1132581a0bp17 ++0x1.31bf077fdc502p-13 ++0x1.dbc9d0ecfecffp958 ++-0x1.d9474275f8dbbp37 ++-0x1.7f9391c99c32cp38 ++-0x1.b22c9445db1a7p613 ++0x1.cf566724b6a87p-10 ++0x1.850211bd3bb55p93 ++-0x1.9ac2c530689d4p0 ++-0x1.be62f5b130b8dp0 ++0x1.032d004bc7a43p692 ++0x1.322f5733ea1fbp0 ++0x1.bed011520ae63p195 ++-0x1.441d84290be35p763 ++-0x1.444960b6d3e89p180 ++-0x1.ec5922981de7ap37 ++-0x1.75d2e1678af63p343 ++-0x1.10eba74970e62p11 ++0x1.62e1e19894307p10 ++0x1.e97543610b789p164 ++-0x1.eda7b7f647b42p15 ++-0x1.fe0c2274f3185p-4 ++-0x1.c0bce3cb049e5p33 ++0x1.aa0523e5fa5d6p0 ++0x1.213f833485611p5 ++0x1.599313c2534f2p-22 ++0x1.1ae571e1bc724p5 ++-0x1.c24055d80a5f8p-11 ++-0x1.a12e65804366bp46 ++0x1.76dc549f2274ap741 ++-0x1.03d390d8997e4p26 ++-0x1.1b36c4cf581c8p841 ++-0x1.56ae7518949d6p36 ++0x1.d86b40100783bp47 ++-0x1.56d0c378ca190p1 ++-0x1.da917388c2c69p830 ++-0x1.fd3906fa866c4p-1 ++0x1.fcc2828b80e39p24 ++0x1.927092bfc1613p62 ++0x1.364ce530c3b8bp14 ++-0x1.a5dd07a7a1b6bp-3 ++-0x1.7039c188c446ep372 ++0x1.ecc00543c4179p34 ++0x1.70a557bff1d19p43 ++0x1.053ac4631eb6ep42 ++-0x1.6e93c69519311p684 ++0x1.fddc610f652bfp25 ++0x1.5d23c14e5347cp10 ++0x1.28b57726066c6p21 ++-0x1.e34b009469f8bp26 ++0x1.8ec3a1532803ep25 ++0x1.2334b34f842cap73 ++0x1.a3f9461f83fc7p44 ++-0x1.bdb5217da4e12p-24 ++-0x1.87ce777fef3e9p0 ++0x1.b994e0f9d64e4p-1 ++-0x1.f051e48eb0a27p-1 ++-0x1.71fc03a2c0dc4p37 ++0x1.d4a7259ec9671p182 ++0x1.af2936d3b5356p18 ++0x1.b19b2069e1487p741 ++0x1.0c4f54d908dbbp842 ++0x1.9633b6cc8f95fp31 ++-0x1.f7f0b10fc7abbp-12 ++0x1.7dcef7488ef54p42 ++0x1.71d9a29951d30p979 ++0x1.9eecb676902eap12 ++-0x1.197a371161a1ap-6 ++-0x1.970b549202f75p15 ++-0x1.5673b2bc3c890p7 ++-0x1.0be9a65ae3299p45 ++0x1.64c4365cb4456p9 ++-0x1.6cc886298a2a6p209 ++-0x1.e3a8a52c483c1p1007 ++-0x1.82ab5565c6bf7p595 ++0x1.8aea2679ef0aap-13 ++-0x1.b37ea43570d83p697 ++-0x1.f5f545093efa8p10 ++0x1.133a54b78232bp-24 ++0x1.b401802bf603fp253 ++0x1.975cf4fe7de01p-13 ++0x1.dfffb229e4a31p33 ++-0x1.d728e796c4c59p46 ++0x1.dbce063607663p-9 ++-0x1.dcfdf7d58b834p32 ++0x1.05a416fb1e983p-20 ++-0x1.b64004211a42ep8 ++0x1.be8fe6328bdc8p503 ++0x1.a7a376a6bfebbp0 ++-0x1.3ade54ae52634p-6 ++-0x1.85b2e43641c2bp6 ++0x1.cf97d457a0958p-1 ++-0x1.f6ec45c2a3b4ap-2 ++0x1.cbcf649cc02d7p19 ++0x1.1e1317c82a6a9p21 ++0x1.a5bca61a82ec3p46 ++-0x1.fc551214a234ap33 ++-0x1.72ac7403760e3p0 ++0x1.bb03d7536d4ccp698 ++-0x1.af4ec32e9fce3p71 ++-0x1.c778f2c7ac74dp17 ++0x1.86c4360709304p1 ++0x1.028015715c76bp0 ++0x1.bfb74117c6ff9p33 ++-0x1.3feed1dd39ce9p40 ++0x1.f14981f4a8d29p16 ++-0x1.b525b5d886fd7p7 ++-0x1.abf156a96afc7p923 ++-0x1.9c1ed568f3cb9p16 ++0x1.7c041208761a6p0 ++0x1.3886e66f106abp151 ++0x1.839cb78b2b4abp30 ++0x1.9a5742c86fb7ep20 ++0x1.91ef725e99f72p592 ++0x1.d36ce6c1fd001p24 ++0x1.e750762ade5ffp0 ++0x1.e92b20a39491ep379 ++-0x1.32e291ee286c8p33 ++0x1.5b7642273a0eep40 ++-0x1.5ea1b0ccd8f28p98 ++0x1.2b80736f4a9d0p9 ++-0x1.2b42618941bb9p395 ++-0x1.7d0ad22761616p26 ++-0x1.7762272cba5e3p25 ++0x1.58954232affb6p25 ++-0x1.34ad53c58a47fp23 ++0x1.8975855985d19p501 ++-0x1.d1f4d79c31380p566 ++-0x1.a32851cc2be65p390 ++0x1.916815589e4b1p0 ++-0x1.5b8b64c9f96a2p30 ++-0x1.d058606fb9e48p15 ++0x1.262a7428526b9p1 ++0x1.96f7c5b3e3919p0 ++-0x1.f5a3a1fc53c6fp1 ++-0x1.30a2d4c407270p46 ++-0x1.6178648438383p19 ++0x1.af13d500f7cc9p30 ++0x1.b9e6172f71258p-6 ++0x1.e27fc1f8aa119p21 ++-0x1.bd9da3d73cd01p6 ++0x1.921da05fc12eap26 ++-0x1.6902454fef7ffp-10 ++0x1.584fc276a6b2bp4 ++0x1.c4b586982c7fep20 ++0x1.942c82ac0f530p4 ++0x1.c1f2b55b51948p4 ++0x1.c34ec3fccc805p5 ++-0x1.a34d9538665cep-15 ++-0x1.8ec031fad3fa4p466 ++-0x1.2f68a72835eefp45 ++0x1.d87c03eaaa1bfp12 ++-0x1.4dad353827827p7 ++-0x1.a61fa78ccb76dp8 ++0x1.f02425994e790p-1 ++0x1.7872164950239p44 ++-0x1.448fa3fa91514p0 ++-0x1.356365717ef4fp3 ++-0x1.27996239e2d4ap25 ++0x1.bfe2746ef36fbp168 ++-0x1.b1a050e0ed3fep16 ++-0x1.657e858ddef02p932 ++0x1.7b7466e89a978p0 ++-0x1.94e103a446f68p185 ++0x1.b0f5135086da8p39 ++0x1.9fa8e6d1aa67ep39 ++-0x1.565ac73db7728p76 ++-0x1.597aa2da93d2ap-14 ++-0x1.79d053e42f35cp0 ++-0x1.e756a7899b592p566 ++0x1.cc02d40dd176fp3 ++0x1.5853f727a0382p931 ++0x1.7f9ff133dd7fcp7 ++-0x1.54eae1e948c26p13 ++0x1.f463812c9625ep194 ++0x1.4200608051042p26 ++0x1.acb924d665d6ep25 ++-0x1.ee69c20fc82d7p25 ++0x1.b62ca2d803314p-17 ++0x1.99ad868f85696p323 ++-0x1.1fc20334bb246p25 ++-0x1.85488755819b0p25 ++0x1.91bae5f4012f6p0 ++-0x1.878693a7343c8p192 ++0x1.a7e580acde1afp634 ++-0x1.5c9f455bb898ep0 ++0x1.717d31fc4eecap15 ++0x1.43716097fef0ep16 ++-0x1.a9073787b0452p15 ++-0x1.2fea30a1d7acbp0 ++-0x1.d46bc3926e9b0p382 ++0x1.307b62ea850b3p0 ++-0x1.17732119c2eedp507 ++-0x1.0508c4bc0aa93p-9 ++-0x1.ff22636c40955p-4 ++0x1.3819811e7b876p10 ++0x1.b46c414c3d879p-24 ++0x1.86ce2688839fep13 ++0x1.f6f5e13195f14p-6 ++-0x1.86a78458de8a7p26 ++0x1.7c3c148fa8c8fp33 ++-0x1.fd9c067d42344p25 ++-0x1.b93722d8573eap717 ++0x1.78daf3e05d2dep999 ++-0x1.1759c00e1539cp26 ++0x1.9cdc12562cdd8p0 ++0x1.0bbb00fcd3fcap-24 ++-0x1.2db1a21b9553cp26 ++-0x1.8cac849c4c14cp-14 ++0x1.20e652e2b31e5p-10 ++0x1.b871e12ae1a1cp523 ++0x1.e06945e6b136bp-1 ++-0x1.8b8870eefb9b2p6 ++-0x1.b692c7b8371d6p24 ++-0x1.90c2846a01900p31 ++0x1.9cd6c3cdf6af2p901 ++-0x1.1a9d210cc532fp23 ++-0x1.334ff5833e6c7p32 ++0x1.32b22205b182ap26 ++0x1.b63623cddd9a3p355 ++-0x1.003b72665acecp-5 ++-0x1.a39c1457f6db7p0 ++0x1.47209333843c4p4 ++-0x1.52f9a306b7dbcp-11 ++-0x1.4cdef0e2215dap22 ++-0x1.8504b5f49eaf5p538 ++-0x1.749866e19666bp28 ++-0x1.d770a34b092aep23 ++0x1.8f64b6b7d5992p16 ++-0x1.89bff2ce038f9p4 ++-0x1.6ba252e9fb2b1p5 ++0x1.4af34179805a3p0 ++0x1.5089668042774p9 ++-0x1.448240d8f0474p-19 ++-0x1.72c886f82bcb8p0 ++0x1.0960b155ba27ep814 ++-0x1.a13513169019ap24 ++-0x1.575773fdcb9fdp30 ++0x1.82fd844618c3bp0 ++-0x1.d64c423ea7fa5p-25 ++0x1.8b29a1a6c049bp5 ++-0x1.e6b4610657578p7 ++-0x1.401257d46dbd8p7 ++-0x1.9fff55074713dp0 ++-0x1.c95e85b6e7218p1 ++-0x1.4651a74f2b3d3p615 ++0x1.a9e7c5c808ecbp-26 ++-0x1.9ba7158986b2bp46 ++-0x1.5c655039f3748p24 ++0x1.b3b0b23e6a1d2p30 ++0x1.7295033ed096ep26 ++-0x1.4d7931d25197fp12 ++0x1.968f207ccf926p25 ++-0x1.93d7b0b7b7859p419 ++-0x1.e5f0c57320518p17 ++-0x1.a17e305c0d250p2 ++-0x1.541eb51e65168p932 ++-0x1.36367707fd0d7p28 ++-0x1.9ed6914905c92p-25 ++0x1.3c46e4b5f0410p10 ++0x1.629ba311169efp10 ++0x1.b790745db6677p999 ++0x1.08ebf45d987edp547 ++-0x1.d8c5051fe47d4p-1 ++0x1.94738125e02b5p907 ++0x1.aa0ce7ffd5ea7p9 ++-0x1.bed4e59348203p806 ++-0x1.41f0976d7f84cp21 ++0x1.6c848429f2c56p924 ++0x1.dcaed6b16da0ep800 ++0x1.adb6d492b974bp1 ++0x1.5a3ab5ecb42b9p22 ++0x1.0992e56329420p540 ++-0x1.b45d52586efc0p27 ++-0x1.b513872f9e108p8 ++-0x1.61b56231fa37cp522 ++-0x1.f38fb1bdbc53dp-11 ++-0x1.b70f1554498d9p49 ++0x1.75b9409a5eff5p28 ++-0x1.01efc62c97c1cp-19 ++0x1.27b536506d0cbp31 ++-0x1.d125456feb4c1p23 ++-0x1.19edb0407ceaap9 ++-0x1.15c9c7f0c69d9p16 ++-0x1.c32963b133dd2p45 ++0x1.6fa8f2041aba3p13 ++0x1.6a15556ab5bf1p-27 ++-0x1.375b96248e95ap629 ++-0x1.fd70c62ca1cc4p20 ++0x1.f53dc1f7f194dp40 ++0x1.1a33e660a7ed3p-22 ++-0x1.94bc6555a7c85p818 ++0x1.419555793d713p74 ++0x1.dd482322ed590p714 ++0x1.fb7ff0dcc63bfp-10 ++-0x1.af039600c8f91p24 ++0x1.767755fe16937p15 ++0x1.c2e47788f82c0p-20 ++0x1.de0757a27a2a0p990 ++0x1.fc40504c8efc7p274 ++0x1.56f37190581d9p15 ++-0x1.6a00039c1ded9p-27 ++0x1.385920f5fb50bp-17 ++-0x1.2ee5a2d829252p266 ++0x1.3511772922eb5p14 ++0x1.d77d763b7eec1p983 ++-0x1.3cb083116259cp9 ++0x1.e91ba1e8e7175p9 ++-0x1.a6b130fb1911bp848 ++0x1.a586d7a33557ep35 ++-0x1.592d642efd386p36 ++-0x1.48a3d6fe9d98fp18 ++0x1.304a33a14b6f1p0 ++-0x1.fd5d90db5e04ap21 ++0x1.f58fc63af014fp-2 ++-0x1.544891c6a1929p-7 ++-0x1.889fd1ca54008p18 ++0x1.cfe531a280790p25 ++0x1.720db29d32cb3p582 ++0x1.d0fdb1492e856p5 ++-0x1.d56587d8858a8p9 ++0x1.a97c6235bbdcfp0 ++-0x1.4dce63f19060fp217 ++-0x1.8a9771ecb1855p0 ++-0x1.023f571ba1300p33 ++0x1.598c20141d1f8p24 ++-0x1.115037892f8bfp25 ++0x1.e354332ab1ca7p346 ++0x1.0d27f1e52cfa3p102 ++-0x1.90e2e2c9434d0p47 ++-0x1.320164348c448p834 ++-0x1.ae1856db3911ep4 ++0x1.856b70cf9eae4p-21 ++-0x1.cdee4539c3a1cp16 ++-0x1.d00240ecaa28ep25 ++0x1.7265d25cb9ab5p0 ++-0x1.644f30279ec2ep16 ++0x1.44df430f5990ap6 ++-0x1.ac22a7e22ec86p4 ++-0x1.414fc579fa14ap15 ++0x1.6f74f627319b6p548 ++0x1.8849e2ffee284p42 ++-0x1.7cea50d8c8b5fp417 ++-0x1.986f67d38b434p0 ++-0x1.7e4044f0e0c65p-4 ++-0x1.b43eb556b532bp485 ++0x1.e2f103744c2fap-4 ++0x1.88ff52ba9330bp615 ++0x1.15db777586675p-9 ++0x1.ffbf701645e70p-1 ++0x1.8896a6f755077p34 ++-0x1.f0eb53cb17860p573 ++0x1.dc88960657275p28 ++-0x1.6af3872d10978p26 ++-0x1.db51518cc915ep9 ++-0x1.f1f4f230cbea7p14 ++-0x1.567352d25a29fp22 ++-0x1.6f6a60e8d7141p954 ++0x1.386626ca69274p23 ++0x1.30bc15e924ff3p26 ++-0x1.c601867be84dap676 ++-0x1.8c5cf7ac29180p941 ++0x1.9754c36e6ca27p-7 ++-0x1.d9167485813bcp4 ++0x1.8a9eb61165392p40 ++-0x1.df3b769ec4c96p-1 ++-0x1.aafc6751f5386p253 ++-0x1.b072707cc49e5p29 ++-0x1.b562e7eada4c3p45 ++0x1.1154b5e420252p20 ++-0x1.937f02df19998p0 ++-0x1.804dc53bf9844p933 ++-0x1.0267e6c4ce393p1 ++0x1.f2c7f1e6e1534p197 ++-0x1.55f2356cd0abap972 ++-0x1.eebc90d7dec4bp177 ++-0x1.650c65a8a6542p21 ++0x1.9826f11e25813p344 ++-0x1.3e070089db4e1p703 ++0x1.d88a20b249b8dp1005 ++0x1.44563581a1019p1 ++-0x1.b66482abc4601p29 ++0x1.829554468c236p12 ++-0x1.7f2f11a4e65b1p-17 ++0x1.c04c2222afa22p30 ++0x1.4dd7900e1a08dp9 ++-0x1.66bb03d2fbf4ap9 ++0x1.1752710b1f584p-3 ++-0x1.055de27bd3b43p21 ++-0x1.177c652007c06p1 ++-0x1.c4d410fc991ccp25 ++0x1.a53887384e01cp813 ++-0x1.7d36f1b5ee4b7p46 ++-0x1.8a3f57ff7521fp0 ++-0x1.2fcfb59864120p2 ++0x1.63bf91d1f143bp26 ++-0x1.1bc1e358d198ep56 ++-0x1.9adb13c70e083p396 ++-0x1.4e9ae34467457p-3 ++0x1.628da3632dc72p1003 ++-0x1.a01d83e08cfb9p-21 ++0x1.9854a0ff4c3c3p-9 ++-0x1.1894e1cc4b5c0p26 ++-0x1.b605c795c2cd5p45 ++-0x1.28016505a4ab7p19 ++-0x1.9c4a66c7f24a4p-24 ++0x1.26f715e1d2ef7p452 ++0x1.b66ee1e12b4ecp47 ++-0x1.fb7db206b4875p22 ++-0x1.a221962184559p15 ++-0x1.4315f238ebbbfp25 ++-0x1.44b0927e3dcb5p5 ++-0x1.6022167aa76c9p960 ++0x1.1259e16e64f7dp29 ++0x1.da683184db9ccp13 ++0x1.5e07800f8606ep21 ++0x1.30c430b6d2d47p394 ++-0x1.398662e38c15ap-26 ++-0x1.04edf4ca12198p3 ++0x1.a4d145fb27f2bp465 ++0x1.30bda21f3afa6p15 ++0x1.0ebb86cb6163fp927 ++0x1.01bca68bab9e1p-6 ++0x1.5dcff2791e7e2p-23 ++-0x1.7477f426ff684p0 ++-0x1.992ad047940bfp0 ++0x1.70c0d7fa4a49bp189 ++-0x1.9318a5d65755dp0 ++-0x1.91b161e6af6acp0 ++0x1.a51cf75f7df96p14 ++0x1.cad757aac0da3p25 ++-0x1.47af44137a0c3p940 ++-0x1.d3da77b5e1989p-5 ++-0x1.3173656fb06fap26 ++-0x1.9964b375b39cbp0 ++-0x1.500c76e1f87e0p18 ++-0x1.dcfa37b54ad38p18 ++-0x1.bcad45697b430p16 ++-0x1.7a8be3382c9a5p31 ++0x1.4a3a85b1486b2p0 ++-0x1.ccd230880d201p17 ++-0x1.c74536f317306p873 ++0x1.1f59624634972p826 ++-0x1.1e977673ce6f6p0 ++0x1.f9ed278dfc568p0 ++0x1.b5a1814d13bc2p23 ++-0x1.ef62a02276044p285 ++0x1.718856c9a1082p26 ++0x1.f7e3b2d10b444p4 ++-0x1.c41dc5c3b92f0p581 ++-0x1.2ce447adba33ep5 ++-0x1.6a15768a53241p29 ++0x1.cd9ba3f5a9474p938 ++-0x1.e753a161f7e24p104 ++-0x1.68b5a5b58c840p-11 ++0x1.267bc533526ecp23 ++-0x1.5ead471bb5306p22 ++-0x1.3618e2e425fdep23 ++-0x1.41b337f5c5f44p9 ++-0x1.6437239c568dfp243 ++-0x1.5f41d0fc227d0p-27 ++-0x1.6a89673ac0a5fp0 ++-0x1.4e2923e9941a7p-8 ++0x1.9700e4b914258p0 ++-0x1.de0e43654118ep659 ++-0x1.9f16a2675e209p-12 ++0x1.0eccb10931828p30 ++-0x1.a6d1862e5ab17p0 ++0x1.d6a1b57219403p18 ++-0x1.25c22185ff5fdp808 ++0x1.1e04b2fdb62a6p-18 ++0x1.a82b630c08134p0 ++0x1.18cb459f47a4ap31 ++0x1.77e887170bc28p0 ++-0x1.2b99174c675c6p847 ++0x1.9ddd3290f738dp9 ++0x1.4042e241ce62bp38 ++0x1.7ba716eb70543p35 ++-0x1.fb6b36a908fc7p157 ++-0x1.e5c7a7899d8dfp0 ++0x1.d222d21ce6da7p34 ++0x1.b87b679527a2ep14 ++-0x1.9abaa5ec33759p0 ++-0x1.37793205a45aap678 ++0x1.028c812928615p38 ++-0x1.feaab4fec9522p35 ++-0x1.b013e711ad8e0p-1 ++-0x1.33de92c99a948p526 ++0x1.752f25454e1bfp-25 ++-0x1.5559104e2af4ap42 ++-0x1.a569120980616p732 ++0x1.231e95b5db287p6 ++-0x1.48714153b9d5bp485 ++0x1.5f3cd25ed07ccp14 ++-0x1.3661771e7c25ep413 ++-0x1.8ee636d9e84dap21 ++-0x1.a599810bec6c0p19 ++0x1.0f3b961f24967p1 ++-0x1.1ed78232bd0ebp966 ++-0x1.7ca333893a545p9 ++-0x1.9b66327d0cb13p20 ++0x1.414327ade9b80p36 ++-0x1.c451b34ce3a1bp229 ++-0x1.ab62b00de54ebp906 ++-0x1.3b3791fe60796p28 ++-0x1.173ee0b983fd2p26 ++0x1.8f2ec3e1de32fp26 ++0x1.51bcd5ff9710ep353 ++0x1.ebaf95aef2672p1018 ++-0x1.751cd519e4a6dp0 ++-0x1.934f442067e49p0 ++-0x1.10e3913276d32p13 ++-0x1.f6b2a6a750390p24 ++-0x1.ae5b2603c4837p25 ++0x1.651942861820ap12 ++-0x1.7751460cb1104p27 ++-0x1.fe38f6d1c1756p23 ++-0x1.b17a57a6c2225p4 ++0x1.22e2f677963f1p35 ++-0x1.c406818f13a49p18 ++-0x1.f97e8481e23f1p-22 ++0x1.5cba77f17a861p37 ++-0x1.f476733bebfbbp-6 ++0x1.8258b766dee50p19 ++0x1.157fe5ff5048fp24 ++-0x1.d325f6274ab68p-12 ++-0x1.fddf647bdbeccp13 ++-0x1.c0ee32a9428dbp5 ++0x1.859d472c2aacap31 ++0x1.4880b54af8cf8p997 ++-0x1.b538b5c254d41p18 ++-0x1.677ac5634507dp21 ++0x1.815a103ec2700p95 ++0x1.32d130c393addp-21 ++-0x1.9ad38426fb1d4p14 ++-0x1.d809c40a02a12p-9 ++0x1.22da530cb9f27p14 ++0x1.cb2077ae707b1p6 ++0x1.32fcf058b7cc1p-25 ++0x1.e2e535f4c34a9p14 ++0x1.11f25046cd068p44 ++-0x1.418de55c6ae70p26 ++-0x1.aad2d3f89507fp530 ++-0x1.f88f75721f852p19 ++-0x1.f1d5a5aa4a842p-1 ++-0x1.3d902309ccfaep285 ++0x1.81c1606ce67d2p-9 ++-0x1.923fc4debf6e8p653 ++-0x1.6f31b3345c4d1p27 ++-0x1.c844d70062456p209 ++-0x1.97b2e18f6c883p0 ++0x1.f85c655d1c235p47 ++-0x1.4ba763d3c0937p20 ++-0x1.97e2e38237ddfp991 ++0x1.3701d45e325fap-15 ++-0x1.fceb0021c01aep-16 ++0x1.3929b7bbecc6fp19 ++-0x1.03c5042796010p938 ++0x1.e6a2b1ce3c89cp5 ++-0x1.8462c75fc795dp0 ++0x1.91a9b66ac4b2bp-2 ++0x1.a9adb0a7e864dp13 ++0x1.a222963d65a5fp18 ++0x1.fb3f11b5edae9p19 ++0x1.d279f26eb8775p-23 ++0x1.843003a410f87p585 ++-0x1.3781e023929a1p12 ++0x1.2f9ea3013e0c3p20 ++-0x1.65fb7629d55f9p618 ++0x1.5420d77378e62p1 ++-0x1.2c9cb0653355fp18 ++0x1.e5fec6e9b62cfp887 ++-0x1.04671129ac1b4p1 ++-0x1.8e99f30cb98e2p11 ++-0x1.80c376dbeab92p3 ++0x1.5d03e053a3f66p-13 ++0x1.6a609415d4822p3 ++0x1.4b0c946ec7a18p10 ++-0x1.6ce16241882f4p1008 ++-0x1.9ca3b5624a1f7p1 ++0x1.adeb34123b9a7p783 ++0x1.657df688fca05p4 ++0x1.7ec760fb6453ep971 ++-0x1.00bd533686e8ap8 ++0x1.ddc5b4c3146fap8 ++-0x1.dabfe4e152cc1p5 ++-0x1.9a83878c11a1bp195 ++-0x1.136c90eb454fdp38 ++-0x1.b129d413e2968p17 ++-0x1.bb21f5afd3c12p17 ++0x1.aeebb6948401fp25 ++-0x1.d10366f45a92ap5 ++0x1.66a9f0a63563fp19 ++0x1.8faa7348340a6p0 ++-0x1.5770156e64fe3p46 ++-0x1.0729f6a9d0fcdp5 ++-0x1.98c0e5d74567cp14 ++0x1.ba55a5ebf7965p36 ++0x1.1d6121dab3ef9p111 ++0x1.fa14c03e032b3p938 ++0x1.9c853700c2470p145 ++0x1.6a17454e5a6d1p-27 ++-0x1.1788b486450c5p1 ++0x1.edb9e180065b6p24 ++0x1.7b14f0a7c6c73p18 ++-0x1.40b0e4d7ee3b2p15 ++0x1.8711c71648cfcp16 ++-0x1.3e46a54242738p11 ++0x1.87dbb061d7c81p1 ++-0x1.6c23a559a0b0bp33 ++0x1.eedc82db40e8fp535 ++0x1.6e44b32d58e96p26 ++0x1.2ce240a6fb9e0p0 ++-0x1.8aa3e3dafbd1cp82 ++-0x1.be96c2479bfb8p6 ++-0x1.827e97ba4a30cp-19 ++-0x1.df8f04c1be1a0p8 ++0x1.9177448bb2b38p31 ++0x1.1048a637ba992p316 ++-0x1.3c865406d78e5p25 ++0x1.0bce74034850ap9 ++0x1.72cc021c86b4ap847 ++-0x1.935a854cd1476p-26 ++-0x1.c209c22dded2ap46 ++-0x1.bfa07289be7dfp-14 ++-0x1.9180653f54946p-18 ++-0x1.c135d03366185p15 ++-0x1.b40e326cb48f5p0 ++-0x1.c675728b6bb2dp1013 ++0x1.19da179d6babdp725 ++0x1.978d06c2067edp17 ++-0x1.cdb5141b33586p645 ++-0x1.9773558b653ecp25 ++0x1.3b567232f3129p632 ++-0x1.786a8125b5258p104 ++-0x1.5ed511cf3e2a8p11 ++-0x1.3f2b56cc2b7c4p806 ++-0x1.9c1a73744e1f5p34 ++-0x1.3c4627661ba9bp42 ++0x1.6fee415f36b1bp24 ++-0x1.f37db348601b2p47 ++0x1.48d277f108c4dp26 ++0x1.664a14b032392p-4 ++0x1.b50335690a9cep403 ++-0x1.327550e6d7fc6p307 ++0x1.6d0f1274d1dbdp541 ++0x1.1c10d39266f66p29 ++-0x1.5a7b45e2f574bp519 ++0x1.0ea38771f6368p22 ++-0x1.34aa02c4c29a6p276 ++-0x1.f3e1a33c418cep-25 ++0x1.30ede40680d9bp632 ++-0x1.030c57ef82307p854 ++-0x1.1f71476c9daf5p8 ++-0x1.dd4640ef11f44p-1 ++0x1.29f9e4b905d41p20 ++-0x1.c33d15648e005p23 ++0x1.6fb53008a6b5ep8 ++-0x1.19f050cc3775ap41 ++-0x1.141935fe4ebddp37 ++-0x1.06c48202a2cbdp0 ++0x1.e9a6e18ebee69p15 ++0x1.2967e001ffd42p22 ++-0x1.8c9c860e895d3p0 ++0x1.68db63ee856a6p16 ++0x1.39e5c24814662p-26 ++0x1.7766a41257495p0 ++-0x1.5e9c33d60ff5fp25 ++0x1.522da4c04faf8p8 ++-0x1.dba0a5618fbf4p34 ++-0x1.c0d3761bbcf56p-1 ++0x1.17a5f7795ad55p40 ++0x1.55f1834a06b07p704 ++0x1.3e78a1243c4fcp26 ++0x1.659c33e8bdffcp43 ++-0x1.f24077bc9318bp661 ++-0x1.ab7d700809e49p782 ++0x1.40584524cb947p0 ++0x1.997c3124d8d86p0 ++0x1.6498074e6f48ap18 ++-0x1.3cc550fa2907bp-16 ++-0x1.3c5527246d6e0p22 ++0x1.a9ca27fe5c9fap22 ++-0x1.28bbb66ee75c7p-24 ++0x1.3feb704d719c4p33 ++0x1.a85103490c12fp0 ++0x1.23edf714f214cp12 ++-0x1.f89114f814a26p10 ++-0x1.8b4005ac68fe8p40 ++0x1.d0c2c73a140f4p18 ++0x1.f12744da61839p938 ++-0x1.4972e012e3bf3p13 ++-0x1.5f6516206cdfcp36 ++-0x1.78f5a5f3d9d8ep13 ++0x1.abdad6b9b65ffp11 ++-0x1.628061c2a64c3p13 ++-0x1.36f50079f514cp26 ++-0x1.26cff62e0a07fp16 ++-0x1.3396e025b96fbp1 ++-0x1.de90b2fae57c1p994 ++0x1.8e5f7741ef5e3p923 ++0x1.9328e3f117564p152 ++-0x1.846ea1da5dc69p615 ++-0x1.4ef3442b14b4dp8 ++-0x1.930c272b3b81dp0 ++0x1.9937743f54e33p-6 ++0x1.64fbc187d66ddp38 ++0x1.653842167c192p12 ++-0x1.99a6209d27f46p10 ++0x1.8ccf525e85a45p25 ++-0x1.0e66241e41d8ep14 ++0x1.740b47e3b8ba6p354 ++-0x1.be957129fb4d2p30 ++0x1.e735d2e16e62dp16 ++0x1.e06c66d10af7ep2 ++-0x1.70c843db3c498p24 ++-0x1.356eb6baad693p592 ++0x1.ac5906747d463p22 ++-0x1.4c81404800155p-18 ++0x1.c24ba6d35df27p-1 ++-0x1.df3b814baebc5p-7 ++-0x1.4fbe7514e3468p4 ++-0x1.71a020b06860bp35 ++-0x1.7ea9145079ffdp0 ++-0x1.43f857a537751p8 ++-0x1.5be44475bd43cp12 ++0x1.55b1d5d904e1ep-24 ++-0x1.abd0b159d0c99p5 ++0x1.7dad06b80c10cp25 ++0x1.7b5dc3d6f8d01p0 ++0x1.1afd7477d74e6p24 ++-0x1.68b33313d93cap20 ++0x1.d68ef5c08f978p46 ++-0x1.256832b9bea68p-23 ++0x1.86deb6e0c31c7p24 ++-0x1.009863c410effp29 ++0x1.dec46182fd6afp25 ++-0x1.7cb163ac511e3p14 ++0x1.354831ca22ed5p19 ++0x1.3047707ea0defp-8 ++0x1.2c09254310224p1 ++-0x1.3d3c872e8b875p0 ++0x1.3fd2c5814d3c4p8 ++-0x1.9b7303763a412p555 ++-0x1.0e34256cf4983p12 ++-0x1.23e1a4d5f82aap22 ++-0x1.515492c6d3c3dp45 ++0x1.7007916be678cp-2 ++-0x1.569787a433b8bp814 ++-0x1.ec3d210f868dep-1 ++-0x1.6b75355e1f926p5 ++-0x1.625c03a0df70ap22 ++0x1.966563060d94ep40 ++-0x1.ba81f6776bb22p37 ++0x1.6cf5927b93cfcp-5 ++0x1.70cbc6b62c369p483 ++0x1.9e8c70de208cap19 ++-0x1.9f463097a5d99p11 ++-0x1.58c534ba51fb4p40 ++0x1.4f8b82099edeep26 ++0x1.d09bf7ba88cb7p24 ++-0x1.6c7af75665821p13 ++0x1.6e97b1ae6f120p17 ++-0x1.7bdcf42df8f3dp148 ++-0x1.2ee1e501c5c44p8 ++-0x1.c07117e66c01fp3 ++-0x1.b6624589e86f8p39 ++-0x1.3d3b360fdb23dp7 ++-0x1.2582b11ecc116p336 ++0x1.7481a321f5256p31 ++-0x1.222ab3691571ep19 ++-0x1.1e419246f958dp1 ++0x1.ab51c6feeab27p23 ++-0x1.7250449530cacp12 ++0x1.163fa61f55b34p4 ++0x1.8191c3fab648bp26 ++0x1.e574e641e9953p36 ++0x1.bcb7d57a8be21p19 ++-0x1.cdbdf1f04e27dp713 ++0x1.619bf59c7d8c9p-2 ++0x1.efd0252da4206p9 ++0x1.37a88102e8fb0p484 ++0x1.cc89f0ea997bfp-22 ++0x1.8dedf0760d306p629 ++-0x1.a13e8382b5f97p0 ++-0x1.a82aa369fc6ecp430 ++-0x1.beffb6d4defb8p-22 ++0x1.f1a644b10c6d9p7 ++0x1.9dfa508a997e0p7 ++0x1.0daa03637d98ap162 ++-0x1.b8c876b5e4a9dp0 ++0x1.ff125371e1bc4p-1 ++-0x1.949833005771cp0 ++0x1.c0c55430f9cbdp3 ++-0x1.714f570923bd4p926 ++-0x1.ab5b85f19aa66p0 ++-0x1.65c85390b2408p781 ++0x1.ec07655eaaf47p38 ++-0x1.e544715929a02p494 ++0x1.7ed0279df0f77p-17 ++0x1.6fb3a12754691p36 ++-0x1.41ab405178a11p142 ++-0x1.db6871f3c584dp0 ++-0x1.c0d186c2b6b34p25 ++-0x1.186545efdec01p15 ++-0x1.e4dd47a4fe36cp12 ++-0x1.2be85575eb960p9 ++-0x1.7514576624239p636 ++0x1.ca44724938996p20 ++0x1.c00ea79ff62a3p15 ++0x1.e4b5b4ced3371p18 ++-0x1.e802b666b8b3bp576 ++-0x1.0f58d230a2735p37 ++0x1.20b346f87c5fap5 ++0x1.0f1be20502191p13 ++0x1.d5b9262dfe8cep16 ++0x1.1c8e4596c422dp25 ++-0x1.3046a7fbcb787p28 ++0x1.c936670321b1bp624 ++-0x1.3b7c709a4d739p25 ++-0x1.3ad3b52b7a8bbp6 ++-0x1.9c77c3ed0da77p534 ++-0x1.b430a641670b4p9 ++0x1.bb4e427cf8f00p5 ++-0x1.bdd570ddd9f21p498 ++-0x1.5fffb06dce6d9p0 ++-0x1.31b725a7f4c50p-1 ++-0x1.4a5e165da5c90p257 ++-0x1.7a9d706ea21aap632 ++-0x1.c13902aa3b501p-16 ++-0x1.34378127441dep16 ++0x1.1899667507aa0p8 ++0x1.b2199455cf381p17 ++-0x1.4c1941a32328ap13 ++0x1.18f575bcb47d3p15 ++0x1.24c4f7f41c27fp17 ++-0x1.778b636eb24aap31 ++0x1.c76120a96993dp19 ++0x1.0900d47dafcf3p702 ++-0x1.89c9464bb2574p0 ++0x1.8504779144b5dp0 ++-0x1.726f662aba5b1p20 ++-0x1.1c5ca2fd655c3p26 ++0x1.b5b0544ca94dbp910 ++0x1.c9930669c935ep-18 ++-0x1.fa0ed41cc58c8p37 ++-0x1.6b60a27346578p-27 ++0x1.5219873f67d7cp12 ++-0x1.7a2c7684be1c6p0 ++-0x1.613492313ae4ap7 ++0x1.806334d1e4496p711 ++-0x1.88e563a4c9a58p7 ++0x1.33c076dccc763p13 ++0x1.11ed850120464p839 ++-0x1.75ea967c17be9p495 ++-0x1.ba72f7be7c7ccp14 ++0x1.7589e0d04c4b8p189 ++0x1.8417412710306p3 ++-0x1.cade31e811061p437 ++-0x1.974b573315304p-24 ++-0x1.ac42144bfc176p24 ++-0x1.7bed32fc75c59p11 ++-0x1.4825d5ba1f52bp13 ++-0x1.c3bbd693a499dp6 ++0x1.38c470d825bc5p3 ++0x1.4ed3556f8eb84p411 ++-0x1.a632636e736fep4 ++0x1.211be5b96be3ep-22 ++-0x1.8cdba14cb1ed8p12 ++-0x1.9a7b35414dc4dp16 ++-0x1.d5d9a0afa77cfp634 ++0x1.c34cb68989b32p17 ++-0x1.84ba041f02caap0 ++0x1.61a51738c63e5p18 ++-0x1.3f37a3e362c12p-5 ++-0x1.b0166656ecf80p20 ++0x1.45f4822152389p13 ++-0x1.ac54855cc74bfp25 ++0x1.b9ddc53febefap453 ++0x1.cfc301950d687p1015 ++0x1.1cb21718dca32p23 ++-0x1.232350a52c4f7p983 ++0x1.d6e6a10d548e5p23 ++0x1.977056a2668eap292 ++-0x1.ffc1c328d34b1p3 ++0x1.91d0e100810d6p-9 ++-0x1.3e0756498d337p1 ++-0x1.b68aa43ff9110p45 ++0x1.a53200b957e9dp-6 ++-0x1.c39415555077fp-6 ++-0x1.aef7328553c7cp0 ++0x1.f2059429fcdd8p23 ++0x1.8a50e7c0eec78p17 ++-0x1.c21e6658d1fe7p-1 ++0x1.9ce192ed63b28p23 ++0x1.da1012047ba28p41 ++-0x1.b09f87dd277f2p10 ++0x1.e58ab4f8ef73fp22 ++0x1.9672675520b23p0 ++0x1.010b17f807152p45 ++-0x1.92d967fe78b7dp831 ++-0x1.a71196fb66603p303 ++-0x1.2786d24ce59c8p-20 ++-0x1.ad6e7205f5d75p150 ++-0x1.6c9037f2ec353p44 ++-0x1.800ee1d7cd409p914 ++-0x1.cac7e495263ffp605 ++-0x1.d6a7e7ccedfefp796 ++-0x1.1ee981d337986p-9 ++0x1.bbb3427565a92p474 ++-0x1.c42631df1cefap44 ++-0x1.e04a92f8f896bp-1 ++0x1.d2a2e5778cc7ep899 ++-0x1.bc30d7beea737p986 ++-0x1.7ede11aa7d47fp18 ++-0x1.489a02a167b04p32 ++-0x1.9257b27ecc0d6p6 ++0x1.12ab65c6d3b81p46 ++0x1.d50d624f63097p24 ++0x1.e88f961d0afddp23 ++-0x1.1f8fd098fdee0p-14 ++-0x1.5c8862170e148p-16 ++-0x1.abd9759e682c6p4 ++-0x1.f1ac241ecfa70p-16 ++-0x1.bf27001863e98p558 ++-0x1.c3a843ee1f309p15 ++-0x1.5458e7f6ecfeap22 ++0x1.af31467613f65p0 ++0x1.665d563797d5ap13 ++0x1.f305a29da24c2p4 ++-0x1.4062318aed418p12 ++0x1.7b7721549420bp0 ++-0x1.ed9ce71907bf6p15 ++-0x1.95a9a284af0c1p843 ++-0x1.0f46820718da8p16 ++0x1.305e23b30adf3p859 ++0x1.3c1fb3275314dp15 ++0x1.e58eb396e0188p31 ++-0x1.7c43c46f53c30p8 ++0x1.4cd3202666397p-6 ++-0x1.ca6216ef28d3ep784 ++-0x1.7435667810fd5p-20 ++-0x1.adf8179db7d4dp23 ++-0x1.dc08b58090270p28 ++0x1.d1f4356f2e4a6p27 ++0x1.eb1f447c6659cp13 ++0x1.f2d524e96e3f9p523 ++0x1.1ca5d135f4a81p5 ++-0x1.b7cd435089283p499 ++0x1.9b3f745c109c0p25 ++-0x1.aebc724bc9f13p917 ++-0x1.0cba50c3750c5p922 ++0x1.5f59539f3c424p8 ++-0x1.08889270ebac4p549 ++0x1.d6d2815236c18p37 ++-0x1.f53a4227c3cbbp10 ++0x1.8d29342fe90aap22 ++-0x1.491bf16e3b738p36 ++0x1.8fb153cddee3cp34 ++0x1.cad7f140e42e8p1020 ++0x1.0ae2e6fd71d2cp30 ++-0x1.e84ee3f73d212p-1 ++-0x1.7231326f8e61fp650 ++0x1.ac0311909abe5p966 ++0x1.d5f7e441a9096p411 ++-0x1.75e293eb1043dp24 ++0x1.7be84683271cep572 ++0x1.5f8ff3c680e11p36 ++0x1.cf03874ee3db3p334 ++-0x1.58c8c1e8be2edp632 ++-0x1.baee66c1245c4p9 ++0x1.8ced030bb09e6p108 ++-0x1.fda225f8ecb2dp368 ++0x1.63d8c15566bc3p-1 ++0x1.9bbd74b01b538p2 ++-0x1.16ed44021834bp12 ++-0x1.0235450de863ap29 ++0x1.9428b5952ead7p23 ++0x1.a512872ac8875p0 ++-0x1.8f7e94f6ce64ep-24 ++0x1.9d9de34f631a6p0 ++0x1.02ee55a75cb5dp-3 ++-0x1.0b6532e2c6919p-24 ++0x1.9caaa1946b56dp0 ++-0x1.efc845be18280p258 ++-0x1.4177b13af435cp16 ++0x1.564ad7ff494fep20 ++-0x1.21e081ad2d02cp312 ++-0x1.a4da0315686e9p0 ++0x1.663bb46627e4bp40 ++0x1.618f84e86d1aep22 ++0x1.4dedf383d4291p888 ++-0x1.bb9d0678f7888p3 ++0x1.5319a1e934edap186 ++0x1.1c0897fc41663p10 ++0x1.8b6dd26fc7f0cp21 ++-0x1.342a0316bd81bp20 ++-0x1.ca34766b88f7bp553 ++0x1.8a65224d8b44fp188 ++-0x1.3637e3eee59b1p-24 ++0x1.549801faaed00p14 ++-0x1.a08912a6fa581p39 ++-0x1.06bd137276b59p226 ++0x1.4368a18959df2p17 ++-0x1.b4bca5db9d268p-1 ++0x1.394126b0c3cf8p3 ++-0x1.8654666821399p831 ++-0x1.f79af4f836b2cp21 ++0x1.9942b024fb0d3p0 ++-0x1.1ebad7277d725p-12 ++-0x1.fedb203dad286p19 ++-0x1.40a4d27a54422p29 ++-0x1.a27013a6b5db3p-16 ++-0x1.eca7e4e273765p951 ++-0x1.dedf0543ecdcfp12 ++0x1.7b7ec1819cff0p24 ++0x1.064b131f15337p24 ++-0x1.a5f5949b9f801p9 ++0x1.a3bcf0c3c2f0cp184 ++-0x1.83b94461ba34ap-6 ++-0x1.5992353ea24efp17 ++-0x1.194a036ff1ae4p43 ++0x1.e0d7d07382e99p42 ++0x1.8ad3f033a34f7p31 ++-0x1.c9fdd72e0cce7p8 ++0x1.ac66c27ae4518p-14 ++0x1.1aad20c97ef2bp-24 ++0x1.c687a7e1b3bb2p771 ++0x1.02ce270f74c87p-10 ++0x1.1562759c45e83p-2 ++-0x1.5bf0b43affc94p40 ++-0x1.eb88d184013f1p25 ++-0x1.bcd3d71c4a84dp15 ++-0x1.feb5845a4017ep2 ++-0x1.6e1c807e05452p36 ++0x1.450494828da68p25 ++0x1.7fe6d347bc643p75 ++-0x1.1b70f1ea5a1a4p23 ++-0x1.2171070c39370p460 ++0x1.c0bfd441a9070p172 ++-0x1.dff6d1ed042eap155 ++0x1.1064c4ba80b64p916 ++-0x1.ef5113553c112p310 ++0x1.8dcbe38231eafp-11 ++0x1.48d1a6fc900a2p519 ++-0x1.bce42351af42dp20 ++0x1.a169a56cb6b12p-13 ++-0x1.750fd2fdd73d5p-25 ++0x1.b92933b734341p24 ++0x1.a50cf516689b3p19 ++0x1.5de0c597781e3p17 ++0x1.bd70b0b71c3e5p351 ++0x1.eacc7731e857cp495 ++0x1.a3fb42a165580p22 ++-0x1.8f76c56e255b4p-14 ++-0x1.9fbdb32a35c6cp141 ++0x1.c3c477621a74bp378 ++-0x1.8c380783af50ap2 ++-0x1.a05d50261fe1fp5 ++0x1.e088235d1a76dp25 ++0x1.5011713801c4dp5 ++0x1.264d4420ae3abp15 ++-0x1.d2ac4569a1c6ap785 ++0x1.0411b74a91529p199 ++-0x1.4657b01035e58p26 ++-0x1.d25ad603e04e0p23 ++-0x1.0bfd05a085350p26 ++-0x1.974fb15d3aa9bp10 ++-0x1.06b730454c09ap1 ++0x1.20a7a61fe0c14p23 ++0x1.2a3e5568a88d1p-15 ++0x1.478f810da74a7p34 ++0x1.13486653f1c89p0 ++0x1.37e3105c65d09p2 ++0x1.d8db173b39e12p685 ++0x1.f33e80726ece4p-1 ++-0x1.27e633778cc62p-9 ++0x1.f4af54734e49ep36 ++0x1.94e76082b3cfep20 ++0x1.bf1ca6e0f5864p23 ++-0x1.901a9197545a8p0 ++0x1.132c37fab90d3p-16 ++0x1.83d2770599e1cp470 ++0x1.2091760b362aap-5 ++0x1.04e4c158364eap250 ++-0x1.c44196bcbc78ep23 ++-0x1.7698c2d4504ecp0 ++0x1.74db0716d3237p857 ++0x1.86c78536631bcp0 ++-0x1.28dad63946e6bp21 ++0x1.3fb691eee1a19p24 ++-0x1.3a048091bbb1cp21 ++-0x1.fc9b13357eec8p14 ++-0x1.11f6d7b366483p-4 ++-0x1.1d2690d2fc3c9p13 ++-0x1.b404c2560d76ep34 ++0x1.f7ed62a6e49d8p18 ++0x1.7245829fb1c45p500 ++-0x1.27b61792a550dp581 ++-0x1.e51cb307c265cp20 ++0x1.f12564eb04cecp0 ++0x1.fb9b7593d9ae8p843 ++0x1.94abf50c1ae27p26 ++-0x1.bb7a62f317dccp221 ++-0x1.659ae30b4af07p674 ++0x1.eeda462ccc67cp9 ++-0x1.d6ec454444ad5p30 ++0x1.edc3b03486bc9p-1 ++0x1.8c359325387c4p169 ++0x1.a46ec36418dfbp0 ++-0x1.668df7872660ap231 ++-0x1.7a3f30b53dbbdp20 ++-0x1.186542f9de11ap13 ++-0x1.ac3103ff8d0dep956 ++-0x1.1701e1f4b7a28p45 ++-0x1.a77534a41661bp26 ++-0x1.805b83ca4a983p741 ++0x1.9b8e34cafe7d1p237 ++-0x1.7d6591476c813p11 ++0x1.2564573a6270ep10 ++-0x1.34d5721bd9e2fp205 ++-0x1.2d24c4f0d1402p21 ++0x1.3975d02ae228ap26 ++-0x1.c520231d589a8p12 ++0x1.841ed75a75d69p0 ++-0x1.6c6be6fa5913ep39 ++0x1.c44db37db2cafp267 ++0x1.92d8e08dcc638p24 ++0x1.87c7a090d5ce1p-16 ++0x1.3130f2cb35283p773 ++0x1.87fc94babfa17p14 ++-0x1.35d156f2365eap663 ++0x1.7f0c71af5cf7fp-2 ++0x1.c1171538bad68p509 ++-0x1.6d8c4522af157p8 ++0x1.6923c7c62dd28p43 ++-0x1.cc29d0dd1d0a8p7 ++0x1.b35e40c13ab28p12 ++-0x1.9771f23aa28b8p2 ++0x1.fc625426d9743p-1 ++0x1.f2eac0a3b585bp18 ++0x1.1bf6e59ca97eap-26 ++-0x1.1a5641181130dp574 ++0x1.c65aa7a45b0efp25 ++0x1.db74347a72291p23 ++0x1.82abe2590802fp0 ++-0x1.021815669b26cp643 ++-0x1.4b5f153d3a4a7p37 ++-0x1.3ffba4bbd1cf6p15 ++-0x1.06b1963b06e9fp75 ++0x1.1f230613bbeacp18 ++0x1.65da91ad037c7p25 ++0x1.efbe10dba52b5p690 ++0x1.dc82d7dbf1ef2p4 ++-0x1.a78d8512d1313p5 ++-0x1.87f2d6caba40cp20 ++0x1.6e4bb6102226ap500 ++0x1.a88fe25344e53p45 ++-0x1.cf03e69d00b76p16 ++-0x1.a69333452a9c5p12 ++0x1.dd2e13a94b242p6 ++-0x1.ce73036c98611p23 ++0x1.91e9d1ac14305p10 ++-0x1.68e6a230c0c32p26 ++-0x1.167d022857473p12 ++-0x1.c4d8a56a3c59fp21 ++0x1.76fd938c01180p0 ++-0x1.9f3023d3fe5cfp-9 ++-0x1.25c1b071f9f0ep744 ++0x1.d3a0d06d79bd8p447 ++-0x1.205561bc373c0p70 ++-0x1.bb14c219cf119p39 ++0x1.3fc332e6a45d1p1001 ++0x1.a94ac5e537ddcp31 ++-0x1.455b03fb1f252p19 ++-0x1.398ff64a119b4p164 ++0x1.a6d3422953772p7 ++0x1.e4f53738724b7p35 ++-0x1.e3c923a871c32p20 ++0x1.3f7a33b9f877cp625 ++-0x1.b08cd29c8af3cp41 ++0x1.41e0545a9fd41p44 ++-0x1.37adf744bfbf4p781 ++-0x1.f9b3e0086091dp-9 ++0x1.c7cd625a6ffd9p27 ++0x1.44dac65c6e037p527 ++-0x1.b465f6c0968a6p0 ++0x1.145960c880918p400 ++0x1.bdda37840188cp16 ++0x1.31f306f18f6bbp3 ++0x1.4e51a42a59d1dp465 ++-0x1.84b5b6411630dp-9 ++0x1.b91e57055ad75p9 ++0x1.4873658bb25a1p27 ++-0x1.f03661c52ba71p15 ++-0x1.eacd674476419p5 ++0x1.aaae40a57b08ap41 ++-0x1.549d609dbc23ep7 ++0x1.b9b6227653d8dp4 ++-0x1.1bded0f0b7680p561 ++-0x1.e92355003abc3p-20 ++0x1.dad677e6137b5p29 ++-0x1.e196a69741820p21 ++-0x1.635324c3f6b71p45 ++-0x1.0e1687acad9b8p823 ++0x1.a1d7a6774c9a9p0 ++0x1.cbca47ac9b582p11 ++-0x1.acda422c4bea7p-7 ++0x1.621f73a497a57p-16 ++-0x1.b8c9242605781p864 ++-0x1.db3792a5149fbp0 ++0x1.8862c65ee2160p-17 ++0x1.d6dd16228de1fp-10 ++-0x1.b88502e85c4e6p3 ++-0x1.c1a4c6ca9cb90p23 ++-0x1.cc1cf066e7a33p25 ++-0x1.b5e1749178cf6p744 ++0x1.dfc7054b12578p12 ++-0x1.29ec85df3a58cp334 ++-0x1.85b8b0c95dbd5p13 ++0x1.7257e1349b295p33 ++0x1.9d85520001790p129 ++-0x1.793fe72cc8c1bp215 ++0x1.739df4f1e7750p25 ++-0x1.a98cd0bd8bf08p22 ++0x1.cd8da092fb8dap89 ++0x1.8c16c534ebb2bp-11 ++-0x1.abb2c2ad80b34p14 ++0x1.2de7338716d92p-18 ++0x1.9211d060f4465p-3 ++-0x1.72fc35651040dp0 ++0x1.2a26d2667b91cp29 ++-0x1.f4b0d40e31bbcp19 ++0x1.fbbe40d2d31c3p25 ++-0x1.9f4c04b486a5ep19 ++-0x1.45193205aa9c4p164 ++-0x1.37a8b60e2d5cep6 ++-0x1.3988f220e6441p-26 ++0x1.493d31fd3c02ap82 ++0x1.2b3340bd6f2a1p39 ++-0x1.54cbb04f2304ap-1 ++0x1.926940fdef273p38 ++-0x1.45ea2765ca2dfp24 ++-0x1.ed0821bb849eep479 ++0x1.4fba868adf04bp16 ++-0x1.e9d417e0bc17cp0 ++-0x1.f4f965b3faf30p17 ++0x1.7d7f77efe5d3fp23 ++0x1.50cfc50c2f640p24 ++-0x1.cf1df3c5ffe17p46 ++0x1.f936b6dca473cp211 ++-0x1.8a1406e6ee482p11 ++0x1.463197698d0d5p101 ++0x1.2409659b805cep7 ++-0x1.3b3d65813a051p191 ++0x1.06ce059e85ca0p0 ++0x1.b60c06f9f5398p6 ++0x1.d60fe7ff7c31cp12 ++-0x1.07b0f652e0470p5 ++-0x1.4580b6d0afe76p50 ++0x1.e21807ed764cep-18 ++0x1.fdc865ca4cd63p-1 ++-0x1.c499a71b0ca05p269 ++0x1.0d75e2b8a7955p160 ++0x1.6a04420a71954p-27 ++0x1.763e053587862p7 ++-0x1.39ef5367547b0p5 ++-0x1.2b2e67b7a8bcfp24 ++0x1.86f6e7b54f573p2 ++0x1.c2b6e3acd3d96p35 ++-0x1.e97ef093600a2p11 ++-0x1.c572f3826cf29p980 ++0x1.796b642ff617cp-3 ++0x1.601b631f840c9p-14 ++-0x1.8eba049870e51p902 ++-0x1.3b17c1c67a109p25 ++0x1.d305139f10a36p17 ++0x1.ec817466d70a7p0 ++-0x1.1265c21b2d99fp245 ++0x1.d1fe37e14bb77p-1 ++-0x1.f178f690d9f42p6 ++0x1.40e3362b70ed9p481 ++-0x1.6a04a793aaf0fp-12 ++-0x1.8245c6bdd8165p16 ++-0x1.7264a53f935a8p10 ++-0x1.13fba79ae44ccp18 ++-0x1.eb9557cea7ac8p0 ++-0x1.8ec847721bf13p26 ++0x1.74d974321f101p-12 ++-0x1.bb1c86a8ca6a4p35 ++-0x1.0c4b1052754aep459 ++0x1.067f874c51947p15 ++-0x1.9cdeb085dbf66p-25 ++0x1.e03a470b607f6p32 ++0x1.3f70e0d5faf68p782 ++-0x1.0d7ac25499901p39 ++-0x1.d0c8711803183p-4 ++0x1.dddfb43ab15dbp49 ++0x1.80dc4549bc143p-2 ++-0x1.8432c6e6dbcb8p46 ++-0x1.e7a2c04ccff8ep46 ++-0x1.453a2503dad3bp-26 ++0x1.3bf04538c0bcfp706 ++0x1.b909a6eac3c92p21 ++-0x1.7a6db4a0188cap9 ++-0x1.1d3e80b32c07ep-11 ++-0x1.43fbf1bf87d6ap978 ++-0x1.d24c3457d0d3cp15 ++0x1.106e24eadb4efp207 ++-0x1.291f20d923034p-15 ++0x1.910ca4ab8908dp12 ++-0x1.8f25f39b6831dp-23 ++-0x1.eb0a55dd34df9p25 ++-0x1.6aa47787b6253p834 ++-0x1.7574d59d3717bp41 ++-0x1.cf28f24daf9f0p234 ++0x1.7760660a714d0p0 ++-0x1.a38422219ffe8p25 ++0x1.52d2453a853c0p47 ++0x1.905551119e9e1p930 ++-0x1.5f7e4096319e3p844 ++0x1.9c7951ed1ddf7p11 ++0x1.a16287317c9fcp879 ++-0x1.0804647cb4089p-1 ++0x1.a886323cf0d4ap512 ++0x1.1ff6b66d5ebe7p41 ++0x1.4ab1627ed8fe0p12 ++-0x1.a32a8757fb5eep542 ++0x1.5f89860e18209p24 ++0x1.7dcfd293f582ap-8 ++-0x1.13f813514eaafp591 ++-0x1.e5e046e81a4a0p315 ++0x1.f4b365dbf8bf5p874 ++0x1.c8a4e5e39c9c2p1018 ++0x1.fa6c62b3010cep649 ++0x1.c2de84df7c3e5p934 ++0x1.af51a42607dc8p-18 ++0x1.88a3d1f1000cfp874 ++-0x1.7a4744d42926cp0 ++0x1.aa8de5d123c00p-1 ++-0x1.5255469b0b1a0p21 ++-0x1.ddce133b21c51p426 ++-0x1.324320eae37c5p23 ++0x1.ae4c1209db983p-5 ++-0x1.b856a600fbd98p38 ++0x1.6f4d04c321f75p21 ++0x1.01475416807a5p9 ++0x1.9d38235f415fdp-13 ++0x1.206ec06d9ab68p-10 ++0x1.bb75b35deec78p33 ++-0x1.1696b22d64f95p113 ++0x1.c1df8560b5cbdp18 ++0x1.52a872c448619p39 ++-0x1.1ef841f17fc34p85 ++-0x1.f133c2e3045d9p-2 ++-0x1.129596a5af08ap-7 ++-0x1.c93715d49ac3ap41 ++0x1.603ac7f2c733dp10 ++-0x1.d3fbb47476501p143 ++-0x1.8cacb5e52c001p26 ++-0x1.a3c87118d19b3p33 ++0x1.222aa2db4190ap25 ++-0x1.5409a38a92aa7p872 ++0x1.38cf32c6b7d09p-9 ++0x1.a4ec535aa90d5p25 ++-0x1.42daf51bf5934p839 ++-0x1.316b8421f5fd1p-15 ++0x1.b1f814b0326e5p697 ++0x1.a9ffc120ca209p668 ++0x1.d058e125f023fp790 ++-0x1.5112b5102f58ep137 ++-0x1.4202328599a61p29 ++0x1.da41b5d447aa6p454 ++-0x1.ef77a65167e5cp24 ++-0x1.0e6276669fc5bp32 ++0x1.b0a6d77eb6c83p-4 ++0x1.1a345788bd44dp546 ++0x1.41f4053900144p-19 ++0x1.057f512cc3bc7p14 ++0x1.6e8b02db1ffd6p105 ++0x1.7ce35635e252ap0 ++-0x1.b96b40b776baep24 ++0x1.ff4ab03720fa9p-4 ++-0x1.adf7c2f3f7875p14 ++0x1.e870529e21dcfp17 ++0x1.d63b208262928p25 ++-0x1.3891962477405p7 ++-0x1.437ff414d0fa9p19 ++-0x1.291a550edea92p5 ++0x1.9ec093b7eb3b2p375 ++-0x1.8ed4f1b3bafe7p626 ++-0x1.b41a54850cf23p712 ++-0x1.a6bc42ea33f9fp767 ++-0x1.2d9bb56ea445ap35 ++-0x1.aece85e37b54ap0 ++0x1.246751c26d13bp296 ++0x1.f2e7f697a2d1fp29 ++0x1.6c37a490520bcp26 ++-0x1.ff8603bbcf498p2 ++0x1.362023b6cd6b2p31 ++0x1.cf2d87e53206ap0 ++0x1.8fe7a627af176p9 ++0x1.8a1ba043b40b9p6 ++-0x1.8615b0b70103fp0 ++0x1.7db401923e93dp923 ++0x1.6f54e4a864f17p0 ++-0x1.86c5665be0ef3p43 ++0x1.6b5066bfcc388p26 ++0x1.20d1f69be6b86p3 ++-0x1.d177e68f841d5p-1 ++0x1.fc49110300d0dp-2 ++-0x1.bd5bb6e1c5f43p-1 ++-0x1.139a94e47ca10p-9 ++-0x1.ac36349c2d3e8p6 ++0x1.7698522ba5c25p216 ++-0x1.62a700634c519p228 ++0x1.dc4a17d8c584ep-13 ++-0x1.052aa2ae959adp25 ++0x1.d6adb0d709d68p17 ++-0x1.0c4c506cc6c2bp79 ++0x1.7977c290c1798p0 ++-0x1.684b477bd74e1p39 ++0x1.bae964ed32d31p-2 ++-0x1.aa5d80bdd8324p24 ++0x1.b8ba85fbfb8adp21 ++0x1.e4eb26b6aaa01p20 ++-0x1.ec2a365168686p41 ++0x1.28dcc3ac950f9p173 ++-0x1.906e052eb7470p-20 ++-0x1.707e251ce768ap440 ++-0x1.821b023683ae3p37 ++-0x1.4db457ffe8a62p742 ++0x1.0670c3d7576b1p8 ++-0x1.f44a632b6a2d4p2 ++-0x1.b75b407bea318p-1 ++0x1.507f63e62851ep-25 ++0x1.bd10460d75116p15 ++0x1.fc3ba353f04b8p13 ++-0x1.2af436412167ap34 ++0x1.8e58408a0b161p30 ++-0x1.cb1884deacccap677 ++0x1.112e30c8147d8p288 ++-0x1.03a724eaa0da3p14 ++-0x1.58a7a7304d337p4 ++-0x1.d3d8600450d2fp46 ++0x1.6784927c4db75p3 ++0x1.925e011c2be99p-19 ++0x1.ebfaf6c6dfd75p-1 ++-0x1.0730625f34e2cp622 ++-0x1.0c78f6f77f4a0p16 ++0x1.4e7226251590fp34 ++0x1.c2d2c2bcfe176p45 ++0x1.92a40269de752p262 ++-0x1.6b17d4e0e4095p47 ++-0x1.b35df39dbe7bap23 ++-0x1.2433941ea6c1dp181 ++-0x1.156bc71aaf929p26 ++-0x1.c0a2337b73d37p-25 ++0x1.c4a1144dd5788p47 ++0x1.61d1b135895c0p26 ++0x1.defc76272ee65p473 ++0x1.d28a2698c470dp0 ++0x1.94f6142bed738p0 ++-0x1.7f782459fa34fp18 ++-0x1.a68016b127852p46 ++-0x1.8c8512f7601a6p559 ++-0x1.296f002678629p0 ++-0x1.6713546c2b7dcp24 ++0x1.5820400b8ca32p-17 ++-0x1.986947ed54745p28 ++0x1.5589220a8d908p2 ++-0x1.bb73c7db6c6b5p18 ++0x1.57545758dc374p1020 ++0x1.3c61573e1df6cp860 ++0x1.b5ba913c8b04ap43 ++0x1.152d60fff636ap25 ++0x1.9dfde0143fc3bp664 ++0x1.8002f4ae0cd26p546 ++-0x1.5555972687f97p44 ++0x1.d4cd0108a77b8p-22 ++0x1.d605a75200cfdp799 ++0x1.8f1ed35661061p13 ++-0x1.aa357490e4b15p16 ++0x1.c616b347d6c7cp47 ++-0x1.5c1bb32908a9dp37 ++0x1.3e63c3071d00ep10 ++0x1.f6a851a65eb40p16 ++-0x1.09293376e5ff7p3 ++-0x1.d28c834a48febp-1 ++0x1.5d1f711534ffap8 ++-0x1.ab58768a06b4fp0 ++-0x1.c305e4720570cp1 ++-0x1.fd01f697e68f3p6 ++0x1.20aa374d16fa9p-7 ++-0x1.640d51133a28dp7 ++-0x1.4cbd82a906116p-20 ++0x1.e728b313e9290p20 ++0x1.2f00b66b200eep2 ++0x1.e70cd0870834dp22 ++-0x1.424f62131a07dp440 ++-0x1.8ffdb1a359d44p8 ++-0x1.d14c66613a0afp47 ++-0x1.bb9dc4d8f0b60p23 ++0x1.8cfc42cbf93fep21 ++-0x1.bff987c5b24f7p40 ++0x1.acb444767500cp404 ++-0x1.e3a3278c0889cp615 ++-0x1.c7c03410ee559p1 ++0x1.1aeb262f169afp9 ++-0x1.c00d57ef36176p16 ++-0x1.54b5c337ab8c7p26 ++-0x1.fca5308d5a5f0p-1 ++-0x1.ee65a575ad332p6 ++-0x1.73d3b5be2d412p4 ++0x1.994532de92cc3p288 ++-0x1.7b3b402cd684ap672 ++-0x1.5581914c736a3p26 ++0x1.8691a1510a8ddp26 ++0x1.439e202ffc78ap31 ++-0x1.00f1f1c0a534dp5 ++-0x1.e787a060a1beap-1 ++-0x1.a40b4564248ddp33 ++0x1.9db0f66a7c69ap758 ++-0x1.29df95676f2f3p29 ++-0x1.c1e2a39fad4f9p30 ++-0x1.2398052cf9970p5 ++0x1.9584270d98e8ap34 ++-0x1.9c3a8363c08d6p-9 ++-0x1.c3ae6326607b1p0 ++0x1.0e33e435785a9p24 ++0x1.3e1547010b972p30 ++-0x1.00e45198f46adp12 ++0x1.cab9d2d70a0ecp176 ++0x1.3cad136952e75p0 ++-0x1.b690f763014a7p-1 ++0x1.5d5f04e7e601ap840 ++0x1.687d04cf256e2p17 ++0x1.fef58250afa5ap733 ++0x1.bf55465c8726dp10 ++-0x1.879cf61bde347p0 ++0x1.41fa061534bfbp1000 ++-0x1.3547166ae0563p18 ++-0x1.29b792c792304p0 ++0x1.44f0c244630e4p4 ++0x1.b44fa2fd3ba45p-10 ++-0x1.ee70d4ee2a313p20 ++0x1.e09a910e6fec6p47 ++0x1.df08c242a0825p41 ++0x1.1b9f438519594p25 ++-0x1.009e65b886832p23 ++-0x1.b211e177c4878p-25 ++0x1.cf4f511036953p-22 ++-0x1.a331a056fd10dp15 ++0x1.78b95045b3821p20 ++0x1.9741d0c92a811p19 ++0x1.0799369efbf5ep23 ++-0x1.aa78545af6518p25 ++0x1.a4f3e0e422feep826 ++-0x1.67f8d1c373dd4p871 ++-0x1.e4d67454ffbcbp11 ++-0x1.c55dd363dd674p3 ++0x1.6402e3d9defaap15 ++0x1.8b5f257d1ec68p-16 ++0x1.af29726910ee4p42 ++0x1.99bc46ffb746dp0 ++-0x1.a1375601023eep810 ++0x1.85c587e566703p737 ++-0x1.f7c1e1a4d0636p-4 ++0x1.969d9183c03dbp558 ++0x1.f049b22399098p34 ++0x1.943ec10617417p5 ++-0x1.e2dd46c8c4c7ap353 ++0x1.fda825f2618b4p4 ++0x1.be0c71a4be7fap24 ++0x1.253fc5016e602p26 ++-0x1.f40770706a468p19 ++0x1.a93453e7eedafp544 ++0x1.4cbf20bbaffe4p0 ++0x1.8523e43195d20p0 ++0x1.ef3fe0d51ca0ap869 ++-0x1.7bfd906b4bc4cp0 ++-0x1.eb85c2e781ca5p834 ++-0x1.c72973927a11bp11 ++-0x1.07bc71bed30b3p39 ++0x1.ca2691e190f22p-24 ++0x1.cb48f51c1417ep44 ++-0x1.567c86970707bp44 ++-0x1.1328459387024p19 ++0x1.8dbca5e6ae26bp-20 ++-0x1.0ea782b471c95p7 ++0x1.885d949bd233ep25 ++0x1.5706b40d7d8d3p-11 ++-0x1.99ffd54628c49p0 ++0x1.4dd434ac6f7e8p150 ++0x1.e33c777463aa2p25 ++-0x1.f7ee12177cdddp285 ++-0x1.13f2e7648aeb4p8 ++-0x1.bb3e114af14ffp386 ++0x1.0ea653cfc5144p86 ++-0x1.97afd730cab3ap0 ++-0x1.1b4a96ad1229ep44 ++0x1.e6b573ec87b1bp172 ++0x1.2f0542b4e0611p533 ++-0x1.b95a733cdd7ddp20 ++-0x1.d47cf66eebb8ep-15 ++0x1.78f0b5f53a39cp33 ++-0x1.8c35d7a87e6fep18 ++-0x1.5273b2382ccd0p15 ++0x1.286441ca5714dp-20 ++0x1.136ee1c73224fp872 ++-0x1.96c0235d8d55cp24 ++-0x1.732f95c827773p35 ++0x1.667404de0f089p374 ++-0x1.2c5137dddd70ep38 ++-0x1.7ac64352f8731p311 ++-0x1.375d526b9499bp10 ++-0x1.608744f90585bp46 ++-0x1.b152d1cd9d10bp11 ++0x1.ac15612e56ca9p23 ++-0x1.1e20923124ba0p18 ++-0x1.976ff6fbebe0cp483 ++0x1.19c89663c0f50p1 ++-0x1.5d4732b848227p0 ++0x1.bce080a10af4ep71 ++0x1.4b5181670d98ep1 ++-0x1.88ef56cab1b8bp0 ++-0x1.124bc48a15e4ep560 ++0x1.16aa8030446c5p1 ++0x1.ea3d708440531p-5 ++0x1.9a933630408d3p0 ++0x1.25c992f62ef85p21 ++-0x1.892203bbd6e79p787 ++-0x1.b69e12ed65962p-12 ++-0x1.213bc173722c7p858 ++0x1.9ec5648d542b0p0 ++0x1.e49be4cdb62fep9 ++-0x1.b51b42ddbf7d6p656 ++-0x1.d98793002d34ap0 ++0x1.8365b15d3d1c8p17 ++0x1.512fb18d70d75p39 ++-0x1.6de981933ee82p136 ++-0x1.985c12bed07e0p13 ++-0x1.a5fbc7fc45b3ap-1 ++-0x1.8710f55f8c2d7p-24 ++-0x1.e21315a4ae92cp40 ++-0x1.b9e2943771bf3p0 ++0x1.da6de76a482d9p458 ++0x1.5599148b4cf81p7 ++0x1.d71ea41f64e8ap776 ++0x1.89d6b23942ee9p0 ++0x1.9fd7d5273c695p21 ++0x1.817ca791272d0p1021 ++-0x1.3452f5175f006p-2 ++0x1.f3af654e608f2p13 ++0x1.1d0a0528d7bdep21 ++0x1.2c2aa710a863fp924 ++-0x1.77b2852f5e175p8 ++0x1.9f48d30a1e11bp47 ++-0x1.54f600b66c2fep12 ++0x1.56b3a59e3e2f4p751 ++-0x1.641b67eda77fdp23 ++-0x1.62d64749736ebp-5 ++0x1.a481622af3746p911 ++-0x1.96cec2f358260p24 ++-0x1.f82d54d558421p19 ++0x1.5c4330323eb8bp34 ++-0x1.9f86b23c7fe1fp17 ++0x1.5994062e8e0f1p22 ++-0x1.b33505561d1cap905 ++-0x1.ccdf732c7d20bp680 ++-0x1.d6a84378ac8b9p23 ++-0x1.a877d1dcede4fp4 ++0x1.9c4fb2b271fa0p-17 ++-0x1.edb1d145f200ep836 ++-0x1.f9a466fe6d9c0p36 ++-0x1.e07ab7c21cb33p-5 ++-0x1.1c05b681bc11bp12 ++-0x1.dfea704995e47p0 ++0x1.3ec9e0020df9bp261 ++-0x1.2de113c0c0abcp840 ++0x1.d523551d1301bp301 ++0x1.d57ff49633b0ap16 ++-0x1.60e00540a4916p43 ++-0x1.ae7cd0ead2707p-21 ++0x1.59c5a3da56943p646 ++0x1.a0f1e02dc546fp0 ++-0x1.90c74581ad4c2p804 ++-0x1.3df5a6745c7b4p279 ++0x1.b1dbd7c284f4ap0 ++-0x1.53a8236e11ad5p613 ++0x1.d01ae4b6ec723p5 ++-0x1.4f07c42ad516ep38 ++-0x1.3f42955e43c60p164 ++-0x1.cef08022a889fp-22 ++-0x1.a104038d6d3aep-11 ++0x1.6ab276053bf58p64 ++-0x1.fa13e25fded10p682 ++0x1.1346116d1b13ep-24 ++-0x1.5cc635b87a547p7 ++-0x1.1c6e458e45611p918 ++0x1.4da2b3a7d743fp588 ++-0x1.5867132e9910dp-6 ++-0x1.866e226885b36p3 ++-0x1.e4af96c89ac8dp7 ++-0x1.32c417258beabp1 ++0x1.ec6d23817ac87p136 ++0x1.4c42234c4cb83p26 ++0x1.627095699f9f2p21 ++0x1.29d5932425be5p19 ++-0x1.59c3a61405350p997 ++0x1.0e0152a02da15p-11 ++-0x1.cbd9001dbd84dp-23 ++0x1.395d53fa21924p970 ++-0x1.21ea97d900ce4p-18 ++-0x1.3857250897e85p18 ++0x1.23e571394fd82p-12 ++-0x1.957af33a560cep-26 ++0x1.7a62d3a97c082p-20 ++0x1.219ec6b246176p5 ++0x1.6a0b96bc3a98ep-27 ++-0x1.b3c5f05c06d11p48 ++0x1.acb0a26d67df5p-10 ++0x1.ce255615d9492p812 ++-0x1.977ad219e6c61p0 ++0x1.de2041abcf313p10 ++-0x1.b942620b8acfep4 ++0x1.a66fb3fbc1f3cp5 ++0x1.35a9b2e6488d6p26 ++-0x1.c36cc56721b05p198 ++-0x1.b9edf7dff3578p-1 ++-0x1.ffbad564ba12ep16 ++0x1.50e3f66a70bd1p485 ++-0x1.a6e547a36e5a4p465 ++0x1.54e875c76edc9p0 ++-0x1.7333a63971418p341 ++0x1.c39a24f08faebp18 ++-0x1.850e4447fd121p3 ++0x1.69b2d631a085bp42 ++0x1.7d5f03a544ce5p647 ++-0x1.54b9f0c3790dap369 ++0x1.b5db54f60d7fcp3 ++0x1.bfede6bcbdab5p14 ++0x1.c49ed00de612fp3 ++0x1.fdd5778773204p20 ++-0x1.ea24548478072p-20 ++-0x1.bbafb75c3ff50p30 ++-0x1.9b0e77b958919p841 ++-0x1.ad3172fd06e85p2 ++0x1.2d24d32d0d341p203 ++0x1.7c2480162bf05p42 ++0x1.e028339f344a0p3 ++-0x1.5dd47591cf023p11 ++-0x1.a20940b9cb5b8p693 ++0x1.d9eef5eef22a0p-16 ++-0x1.f0f51635acaf5p873 ++-0x1.c4353793f8e09p954 ++-0x1.3df5f51c831ccp17 ++0x1.e5b497ae4cae6p23 ++0x1.43162012fdb57p-10 ++-0x1.ba6782c6cca02p394 ++-0x1.1f4d15ce5c886p976 ++0x1.afa4370e97c87p44 ++-0x1.4b72433cea7f4p34 ++-0x1.01d1a13ce3762p-1 ++0x1.4a5b4081f8482p599 ++-0x1.e5b132f5337d4p30 ++0x1.4812553307bb4p25 ++-0x1.2d6ce79efbffap26 ++-0x1.102777593c0e7p425 ++-0x1.d6cf8795449a2p9 ++0x1.0c80d756d5c0bp-19 ++-0x1.9950064153b61p25 ++-0x1.8e3d83d000c70p30 ++-0x1.462b54d1612b6p38 ++-0x1.4c6a67184b714p2 ++-0x1.0e4572028b0bcp7 ++0x1.3e6a630eef30fp822 ++0x1.a291d6c857b9bp19 ++-0x1.0e87122715084p23 ++-0x1.ab4990691ca4fp891 ++-0x1.7675c774d88f1p26 ++-0x1.76d935c0d01acp957 ++-0x1.f86d4487dc29ep39 ++-0x1.2ab3d736f572ap-1 ++0x1.846c74b34d14bp0 ++0x1.a789a2d158e61p3 ++-0x1.82c2e4943b305p7 ++-0x1.4668a4a069757p184 ++-0x1.4bc1d2b00fc7ap14 ++-0x1.a544825f32188p12 ++-0x1.e2f896a71d084p40 ++-0x1.d4f317c77cf8dp34 ++0x1.2fcfb6146b469p18 ++-0x1.fc0ef70d94a57p992 ++-0x1.8bc622e9b81a9p332 ++0x1.ab3d255d05066p0 ++0x1.032294d998d40p895 ++0x1.597286cff2ddcp-9 ++-0x1.448590f2dfdf1p13 ++-0x1.ec7a74fefbef8p30 ++-0x1.fec72598e90e7p698 ++-0x1.739c7600c2aa3p0 ++-0x1.1532224ccff07p604 ++-0x1.adb0720f88c1cp671 ++-0x1.0f5c60e6cdf52p918 ++-0x1.cd43b383af967p12 ++-0x1.412293a10f35bp12 ++0x1.637192a10a8c0p35 ++-0x1.1310d6c648b59p25 ++0x1.d8c161c67b50ap28 ++0x1.c64b8175f853ap3 ++0x1.db34f69efdf5ep20 ++0x1.308bc4c848b55p65 ++0x1.9bde77693f64ep0 ++0x1.df5fb02f5fb43p41 ++0x1.511f0030d8e62p12 ++-0x1.623861243cc06p9 ++-0x1.f5db61e5469b9p8 ++0x1.5b6cb194d89edp18 ++-0x1.12c0876a1b15ep18 ++-0x1.939f8667ccc46p-8 ++-0x1.56cdd13279359p25 ++0x1.91eb17eaeb8c4p11 ++-0x1.5e31156143a7dp37 ++-0x1.46ba04e866f63p7 ++0x1.dbfed0411bc7fp538 ++0x1.f69893a985cc9p17 ++-0x1.11278358c2510p141 ++0x1.6c07667947649p10 ++0x1.1b5c9235ff249p852 ++-0x1.1e9e57d76a9a9p37 ++-0x1.388491cbdac70p17 ++-0x1.c2eea2091b3f8p-1 ++-0x1.cd087524966a7p25 ++0x1.f6adc5d4459cap600 ++-0x1.f57ff5b713a99p3 ++0x1.f2d9b467e8ee0p-8 ++-0x1.ee0bd3710bef0p-14 ++0x1.a61cc024a420cp-24 ++0x1.e902f4b561c63p3 ++0x1.9955d0ecba68cp-21 ++0x1.60eb50fec72a7p-20 ++-0x1.09f0677aee265p1005 ++-0x1.8812968970db4p721 ++0x1.8dcc40b01b324p112 ++-0x1.3a90164a6fb2dp26 ++0x1.3802f5cdcda63p6 ++0x1.e21a052adc0d0p0 ++0x1.a948854deaa16p-11 ++-0x1.274d4065edf3cp25 ++-0x1.9193532bbe2c9p16 ++-0x1.2e26e362aa597p472 ++0x1.550114f8cd6b0p16 ++-0x1.1c39a294dfb51p946 ++-0x1.1ac3f37ca8f9ep6 ++-0x1.d0cfd15066c8dp673 ++0x1.1b1f153f16bbdp29 ++0x1.56b9b46a42022p12 ++-0x1.89e4012cc6deap0 ++-0x1.d6fb928514d12p1004 ++-0x1.a136f5a490ae4p664 ++0x1.36932245e98cbp26 ++0x1.b1fb46c217a41p277 ++0x1.7b54923209cb7p587 ++0x1.caaf81b413ec0p608 ++0x1.ab5a96a090df8p6 ++-0x1.630330ace2d7cp41 ++0x1.ee7e47e57812bp-4 ++0x1.4351e41d03816p21 ++-0x1.aafe0659a5c58p11 ++0x1.2748836e9b331p41 ++0x1.fe7b979d71d95p598 ++-0x1.48c5920336400p-7 ++-0x1.b223b4be25585p382 ++0x1.a94e62298c7a1p45 ++-0x1.5217e3915a0e8p11 ++-0x1.2e65032ba771fp-9 ++0x1.6a3d4382141ebp-6 ++0x1.468a9481d74e4p169 ++0x1.b3bf676408855p20 ++0x1.ee41d72d85a88p23 ++0x1.0f1525458e264p557 ++0x1.a601a30301754p-22 ++-0x1.71d595d59b86cp566 ++-0x1.62e7f03cb1f31p12 ++-0x1.73f5402ab4e19p-8 ++-0x1.72c1f709ea5c2p13 ++-0x1.3919a5ad625dcp-4 ++0x1.fd017587ee830p310 ++0x1.b7518131b5253p0 ++-0x1.f348906bc1126p-6 ++-0x1.fc7ac7285a79ap0 ++-0x1.59f1d57e68057p17 ++0x1.bdd572c2631e7p19 ++0x1.bdf7f6ea49a0dp300 ++-0x1.8c4877c037477p29 ++-0x1.5da7b5197c995p15 ++0x1.67de61ebfcad3p107 ++-0x1.9096f72642477p323 ++0x1.e5fc51f35ab90p15 ++0x1.9f7bf6c845f55p0 ++0x1.6a59935f352f0p23 ++0x1.1f7b41c8d8513p20 ++-0x1.86d8339a09175p637 ++-0x1.3fa5c32fca635p6 ++0x1.23faf483fef1ep-18 ++-0x1.408f70d527f00p40 ++-0x1.9440f7b969c8ap209 ++-0x1.4e380016a4d6cp987 ++0x1.a20616e878c04p1023 ++0x1.2a9f54471780ap3 ++0x1.75dbe2c1ec783p-23 ++0x1.67c2221fc3804p23 ++0x1.bcdeb6f3c5549p30 ++-0x1.bb12215c52f92p779 ++0x1.8ffeb3898d1c8p-19 ++0x1.1fb8b50205437p2 ++-0x1.5a4a653146e40p32 ++-0x1.0c6b30ada1b09p23 ++-0x1.8b5c231e30042p0 ++0x1.1f16455d89ad8p882 ++-0x1.513c3208d3047p6 ++-0x1.cee964e33c448p30 ++0x1.af44434d9c9c6p0 ++-0x1.0276334fd570bp-15 ++0x1.5dedf26999173p0 ++-0x1.1b2e4780cd70fp417 ++0x1.534237e205b0ap8 ++-0x1.29c1563c96376p41 ++0x1.8a3457a805380p776 ++-0x1.47fc55d109066p332 ++0x1.793aa09de6e04p1006 ++-0x1.bf3fb2020504fp896 ++-0x1.7366b3b52b79ap-3 ++-0x1.b95a21c326d4fp754 ++-0x1.8f992737bdb7dp526 ++0x1.e0f1212c81cf0p21 ++-0x1.5299f2819f9dep19 ++0x1.ae0255b511d01p4 ++0x1.8fc2a4bf7afe8p261 ++-0x1.91f2f0444f31ap634 ++-0x1.a8ad341b55868p7 ++-0x1.b33f97a647507p4 ++-0x1.ac58d36c99905p0 ++0x1.717660662d7f4p618 ++0x1.747371ab298bap14 ++0x1.d500a4ff90ba3p9 ++-0x1.c49132a3807d3p18 ++0x1.775041f5adf79p40 ++0x1.d196f39ecbbfdp-15 ++-0x1.955a20c2e98a8p10 ++-0x1.eb44149e132e3p20 ++-0x1.91fc970666340p-10 ++-0x1.8cbd518d4e97ap9 ++0x1.446762982f5a5p30 ++-0x1.243fd3db30072p7 ++0x1.7f9b147083efep863 ++0x1.02e06605707fcp11 ++-0x1.f943c41c8d938p36 ++-0x1.66297706f7c14p727 ++-0x1.6b59c16db566cp26 ++0x1.5d48f15c59f58p452 ++-0x1.e8f5230318f79p-1 ++0x1.31fad3c41d123p34 ++-0x1.6757e2c0a08a7p11 ++0x1.7f07e07a0a269p288 ++# cos slow path at 768 bits ++# Implemented in sysdeps/ieee754/dbl-64/sincos32.c ++## name: 768bits ++0x1.000000cf4a2a2p0 ++0x1.0000010b239a9p0 ++0x1.00000162a932bp0 ++0x1.000002d452a10p0 ++0x1.000005bc7d86dp0 ++0x1.47c453f752654p637 ++0x1.b27df119d2861p78 ++0x1.b073672e47988p835 ++0x1.f2f5607cc76e1p157 ++-0x1.3c7b45a1446e9p349 ++0x1.544a364a05b26p228 ++0x1.157fa0b2ffd20p164 ++-0x1.f4ba7359080d6p172 ++-0x1.7698941fce366p651 ++-0x1.9875603af20dbp433 ++-0x1.b00f872fa6260p918 ++0x1.468e65e8e3656p661 ++-0x1.6cbd47b10d74bp464 ++-0x1.2c2c62a2f067ap197 ++-0x1.8e3db452cbb07p810 ++0x1.8446c34a2644cp277 ++-0x1.b0f6f1b8db81ap179 ++0x1.93b574629bf16p748 ++0x1.b6b6e0a06cb05p344 ++-0x1.7cbc2702fbd97p922 ++-0x1.887a36760f072p336 ++0x1.17b9c169b2efep714 ++-0x1.e947b36ae0940p794 ++-0x1.d70d15a2338b8p884 ++0x1.0a98017bf55bep935 ++-0x1.bc07c6c7cc03bp538 ++-0x1.c42d477462280p949 ++-0x1.9c6dc4908a248p536 ++0x1.37a0d35e7fd14p74 ++-0x1.9c9cf14390543p64 ++0x1.7c0a43fe4ef89p409 ++-0x1.cc1fa7c639575p65 ++0x1.df36548f960eep769 ++-0x1.d3f102775834fp176 ++-0x1.0a6bf05ba56c4p713 ++-0x1.4775c1ce2834ep903 ++-0x1.7ade6237217c2p272 ++-0x1.35ebc7dee67bep898 ++0x1.26ded2ecd7486p728 ++0x1.90c6535aa78d1p591 ++-0x1.dd85c54160392p296 ++-0x1.1ee7b2598c033p904 ++0x1.28de547f9a6a7p156 ++0x1.bb7ff11e74372p775 ++0x1.bb4da1ff7cd43p113 ++0x1.52f2e13f3ddcfp430 ++0x1.7aa0c44aa3950p964 ++0x1.33ffd1540eeaap899 ++-0x1.a8c7f7947c6efp453 ++-0x1.3a8f54a1dfe1cp193 ++0x1.fedb8178dbabap386 ++0x1.b53776fb33667p290 ++-0x1.1dbc12b1b9e1ep632 ++0x1.ed4db1eaa237cp454 ++-0x1.e43334d044861p32 ++0x1.db66f595e3e93p165 ++0x1.6c6af169f717ap165 ++0x1.d14cf2d2b8875p589 ++-0x1.1661f59554000p419 ++0x1.f76c50b4e5bd1p276 ++-0x1.b00253e803df0p175 ++-0x1.8ec0a6121e3b6p8 ++0x1.5e1195ad8957fp899 ++0x1.ec89e4f11ac8fp433 ++-0x1.1d38a4ee578e9p339 ++0x1.4377875dce8fdp326 ++0x1.ee58a172d118cp745 ++0x1.ff0232a89efd3p913 ++-0x1.a6c9c19756962p883 ++0x1.dbb6b6a957161p710 ++0x1.12fd57b2e5ebbp83 ++0x1.e9e364fad4bcbp329 ++0x1.cbe8b375ad172p953 ++-0x1.08a4b728fde64p598 ++0x1.60f510ee233d5p828 ++0x1.ba51673480a49p100 ++-0x1.b04114708e216p378 ++-0x1.9fd7b6bc2ce33p61 ++0x1.c32ea014657c0p820 ++0x1.1d3621e24b581p110 ++-0x1.4139a7fc5b5dep135 ++-0x1.2399c1ea2ea2fp729 ++0x1.aa2a835f87dbcp650 ++0x1.948dc5cd26e75p371 ++-0x1.a5a520d06d146p940 ++-0x1.191a55bfe7786p1013 ++-0x1.a46e0156a6bf3p525 ++-0x1.91fd2519f735bp372 ++0x1.1a78a3d726d73p617 ++0x1.428c901b2d569p906 ++-0x1.9f415555f701bp238 ++0x1.a7e133e2c9f01p315 ++0x1.e565b67830fabp1009 ++-0x1.9e88b6ff1a777p31 ++0x1.8ec4d30c1daebp710 ++-0x1.5c35d25455dabp540 ++-0x1.5957f35326911p855 ++0x1.5e8414f558911p832 ++0x1.fadce712c669ap551 ++-0x1.7b0554f4a1530p340 +diff -urN glibc-2.17-c758a686/benchtests/exp2-inputs glibc-2.17-c758a686/benchtests/exp2-inputs +--- glibc-2.17-c758a686/benchtests/exp2-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/exp2-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,105 @@ ++## args: double ++## ret: double ++## includes: math.h ++-0x1.8235e0aa4aab1p814 ++0x1.0e1220dfad80dp1006 ++-0x1.e6a710eed0706p919 ++0x1.11def1bbe9bc3p-471 ++0x1.05e9b1fc591d9p-1007 ++0x1.a58906c628b46p984 ++0x1.772627fce1208p-256 ++-0x1.461c146b65f2cp-62 ++-0x1.6cf046992fa9ep-876 ++-0x1.eaca47d76382cp-413 ++0x1.5056d0027ca2bp-634 ++0x1.1be8235cf2515p-300 ++0x1.f667e36bb79d2p913 ++0x1.b9ae233039c9cp-721 ++0x1.b70ec546dac57p589 ++-0x1.3ef895a695202p-318 ++-0x1.e73d755c17ecap-901 ++-0x1.f0a09005d2fdcp-52 ++0x1.77520292c8ea7p786 ++0x1.e5c0a38dccd6fp-510 ++-0x1.21dd1410a13fdp469 ++-0x1.f1ea1752b167cp-855 ++0x1.149395c6b1dfcp237 ++-0x1.22cfe4ceb2a85p244 ++0x1.061a75f02c856p-417 ++-0x1.04aaf4e1a4962p-645 ++-0x1.b962f2c49c11ap169 ++0x1.6074818509343p-151 ++-0x1.6b9946b997353p350 ++-0x1.6b8631635d607p-328 ++0x1.6893162dc2973p923 ++-0x1.0a1c40492986dp-371 ++-0x1.23ae72061594ap-113 ++0x1.d73d84becb49dp-816 ++0x1.545894ebc8944p-487 ++-0x1.c006c29733c62p325 ++-0x1.745dc305eeb06p-994 ++0x1.6cdeb63076b54p420 ++0x1.c8f137c690673p906 ++-0x1.170ab5609f77cp205 ++-0x1.0b11b685a3349p-46 ++0x1.7f68672b92eb1p-622 ++0x1.66d431dee4bfdp-333 ++-0x1.e43304b22a96dp228 ++0x1.58ac069095de9p-419 ++-0x1.3fcaa6e1f1ac3p654 ++-0x1.437ed00080554p-88 ++0x1.717ad5a379c50p531 ++0x1.9688d6a6dd841p127 ++-0x1.189c3732f9ac8p505 ++-0x1.8c5da688a249ep871 ++0x1.808015df2809ep-647 ++0x1.54ccb260c52f6p183 ++0x1.ec1574f23f1b5p757 ++-0x1.2de0222e50454p-176 ++-0x1.dc5715d5ac4f3p-882 ++0x1.6fa963199b1fbp389 ++-0x1.0a143338c0ff3p149 ++0x1.c278a3ec4071cp240 ++0x1.7bdb071d7e6ffp-360 ++-0x1.e9b7a0af460ddp-809 ++0x1.d069e62cf695bp535 ++0x1.0f7ba1b172a18p-887 ++-0x1.96af5166829b7p399 ++-0x1.8f70240823cdbp-65 ++-0x1.fcd2d5a63a217p-971 ++-0x1.089241ad467f2p-247 ++-0x1.3fa3940d58aa8p1022 ++-0x1.aff1c0aec4e7dp814 ++-0x1.6bad319cfc3bcp-378 ++0x1.9c8956c66ba36p-579 ++-0x1.6d9393f52ee3fp411 ++0x1.e529d23501328p926 ++0x1.3ec71520af29cp690 ++0x1.787576a795b83p194 ++-0x1.ef38147d2dc40p107 ++-0x1.22a125ccbb1b2p-308 ++0x1.5f5c074be0351p-928 ++-0x1.377ed64bec482p390 ++-0x1.09eae6f62d4b8p-41 ++0x1.9f3fd03635c92p-104 ++0x1.cb7d07d13c9efp599 ++0x1.49e8154de36a7p538 ++-0x1.d68343fe573bfp-736 ++-0x1.4beba6b79ba1ep-811 ++0x1.927774a125013p221 ++-0x1.e4a1e48c33931p-152 ++-0x1.b8a3123361eb5p641 ++-0x1.909ea08b262f3p960 ++0x1.0d1b30600d5b0p822 ++-0x1.392420cf4ce19p-690 ++-0x1.f9e1f71c0f3a2p-349 ++-0x1.75600638cbf0ep-527 ++-0x1.788911851a5abp-193 ++-0x1.2ab1045fa9103p-471 ++-0x1.d9c7f1a19cefdp-44 ++0x1.ef5a66b13a5f8p171 ++0x1.261c24ba6cdfbp539 ++0x1.641945dc01d29p-620 ++0x1.5c190276797a1p935 ++-0x1.ea76b6a8a9d4ap-656 ++0x1.41a117e9931f0p-169 +diff -urN glibc-2.17-c758a686/benchtests/exp-inputs glibc-2.17-c758a686/benchtests/exp-inputs +--- glibc-2.17-c758a686/benchtests/exp-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/exp-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,589 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.6200315ce81efp9 ++0x1.0000000031579p0 ++0x1.000000009b551p0 ++0x1.000000067ace6p0 ++0x1.6200315ad0fc0p9 ++0x1.0000000000060p0 ++0x1.00000004237a7p0 ++0x1.6200315ad0fb2p9 ++0x1.0000000054ac1p0 ++0x1.6200315c98bcdp9 ++0x1.0000000002d96p0 ++0x1.0000000000038p256 ++0x1.6200315ad0fafp9 ++0x1.6200315d680ecp9 ++0x1.0000000000042p0 ++0x1.0000000000048p256 ++0x1.6200315ad0fbcp9 ++0x1.000000000000dp256 ++0x1.000000000001ep256 ++0x1.0000000000015p256 ++0x1.0000000000018p-256 ++0x1.000000000002ep0 ++0x1.000000000004ep-256 ++0x1.000000000001dp-256 ++0x1.6200315ad0fb4p9 ++0x1.00000002ca5f8p0 ++0x1.0000000000017p256 ++0x1.0000000000022p0 ++0x1.0000000000059p256 ++0x1.0000000000028p0 ++0x1.6200315ad0fa7p9 ++0x1.000000048059cp0 ++0x1.0000000000023p256 ++0x1.000000000003ap-256 ++0x1.0000000000022p-256 ++0x1.6200315f211bep9 ++0x1.000000000002ep-256 ++0x1.0000000000041p256 ++0x1.0000000000042p-256 ++0x1.6200315ad0fcfp9 ++0x1.6200315ad0fd7p9 ++0x1.000000004bd6fp0 ++0x1.000000000000dp-256 ++0x1.6200315ad0fb7p9 ++0x1.000000000001fp0 ++0x1.0000000000024p-256 ++0x1.0000000000058p256 ++0x1.6200315ad0fc5p9 ++0x1.620030025fbe9p9 ++0x1.000000000003dp-256 ++0x1.000000000003fp-256 ++0x1.0000000000009p256 ++0x1.00000005c7304p0 ++0x1.0000000000045p-256 ++0x1.0000000000011p-256 ++0x1.0000000000033p-256 ++0x1.0000000000036p256 ++0x1.0000000000059p-256 ++0x1.0000000000001p-256 ++0x1.0000000000052p-256 ++0x1.000000045baafp0 ++0x1.0000000000032p0 ++0x1.00000004a5089p0 ++0x1.00000005edb68p0 ++0x1.6200315ad0fd1p9 ++0x1.0000000080d5bp0 ++0x1.0000000000038p0 ++0x1.6200315ad0fdbp9 ++0x1.000000000005fp256 ++0x1.0000000291b1ep0 ++0x1.6200315af4bedp9 ++0x1.0000000000031p-256 ++0x1.6200315aea99bp9 ++0x1.00000005ab569p0 ++0x1.6200315d47b24p9 ++0x1.6200315ad0fd9p9 ++0x1.000000000003bp256 ++0x1.6200315d31eb9p9 ++0x1.000000059a297p0 ++0x1.0000000000011p256 ++0x1.0000000000021p-256 ++0x1.0000000000041p-256 ++0x1.0000000000049p0 ++0x1.00000006857afp0 ++0x1.6200315ceb300p9 ++0x1.000000000003bp-256 ++0x1.6200315bcaec3p9 ++0x1.0000000000018p256 ++0x1.00000002f3b77p0 ++0x1.6200315ad0fb5p9 ++0x1.0000000000027p-256 ++0x1.000000054447dp0 ++0x1.6200315e84846p9 ++0x1.0000000172fefp0 ++0x1.00000001c8808p0 ++0x1.0000000000003p256 ++0x1.000000000003ep-256 ++0x1.00000002ed36ep0 ++0x1.000000000002ap0 ++0x1.00000002ae08bp0 ++0x1.000000000005dp-256 ++0x1.0000000000063p256 ++0x1.000000000003ep0 ++0x1.0000000000037p256 ++0x1.6200315ad0fb6p9 ++0x1.000000000005ep0 ++0x1.000000000002ap256 ++0x1.0000000000056p256 ++0x1.0000000266056p0 ++0x1.6200315ad0fdap9 ++0x1.000000000002dp0 ++0x1.000000000004cp0 ++0x1.6200315ad0fb8p9 ++0x1.0000000000039p0 ++0x1.000000000002ap-256 ++0x1.6200315ad0fa5p9 ++0x1.0000000000035p256 ++0x1.000000000005ep256 ++0x1.000000000004cp-256 ++0x1.0000000000039p256 ++0x1.000000055574fp0 ++0x1.0000000000033p256 ++0x1.6200315ad0fc2p9 ++0x1.62003001fc398p9 ++0x1.000000000004ap-256 ++0x1.000000000001ap256 ++0x1.000000005d813p0 ++0x1.6200315ad0fe4p9 ++0x1.0000000000030p-256 ++0x1.0000000000020p-256 ++0x1.0000000066565p0 ++0x1.0000000000029p-256 ++0x1.6200315ad0fc7p9 ++0x1.000000049e880p0 ++0x1.0000000609903p0 ++0x1.00000005e309fp0 ++0x1.0000000000013p256 ++0x1.0000000000026p0 ++0x1.000000000002dp-256 ++0x1.6200315ad0fbdp9 ++0x1.000000000000fp256 ++0x1.00000001a9d52p0 ++0x1.000000000002cp256 ++0x1.0000000479d93p0 ++0x1.0000000000016p256 ++0x1.00000001d7d63p0 ++0x1.6200315bd5b13p9 ++0x1.00000001097e9p0 ++0x1.0000000000030p0 ++0x1.6200315d37392p9 ++0x1.6200315ad0fe0p9 ++0x1.6200315ba6119p9 ++0x1.000000000003ep256 ++0x1.00000000e87eap0 ++0x1.0000000000002p256 ++0x1.00000006501c2p0 ++0x1.000000000004bp256 ++0x1.620030022b98ap9 ++0x1.000000000003fp0 ++0x1.00000002d0e01p0 ++0x1.00000001f6819p0 ++0x1.0000000000020p256 ++0x1.0000000000021p0 ++0x1.000000000005cp256 ++0x1.6200315ad0faep9 ++0x1.6200315c61515p9 ++0x1.0000000000008p256 ++0x1.0000000000056p-256 ++0x1.00000004f2923p0 ++0x1.000000000001ep0 ++0x1.0000000000028p256 ++0x1.000000000004fp256 ++0x1.000000000002cp-256 ++0x1.0000000000025p0 ++0x1.6200315e1215ap9 ++0x1.6200315ad0fb3p9 ++0x1.6200315e921dap9 ++0x1.6200315ad0fd6p9 ++0x1.0000000000049p256 ++0x1.000000000004dp256 ++0x1.0000000000042p256 ++0x1.0000000000051p0 ++0x1.6200315d83129p9 ++0x1.0000000690278p0 ++0x1.0000000000036p0 ++0x1.0000000000026p256 ++0x1.000000000005fp-256 ++0x1.000000000000cp256 ++0x1.0000000000007p256 ++0x1.000000050a3fep0 ++0x1.000000000001fp-256 ++0x1.000000000002ep256 ++0x1.000000000004ep256 ++0x1.6200315f00e77p9 ++0x1.6200315ad0fd2p9 ++0x1.6200315d4ee5bp9 ++0x1.00000004552a6p0 ++0x1.6200315ad0fe3p9 ++0x1.000000003a2cbp0 ++0x1.6200315ad0fdfp9 ++0x1.00000002b4894p0 ++0x1.0000000000022p256 ++0x1.000000023a58ep0 ++0x1.6200315ad0fd8p9 ++0x1.0000000000029p256 ++0x1.6200315efe051p9 ++0x1.0000000205d74p0 ++0x1.0000000000045p256 ++0x1.6200315ad0fb0p9 ++0x1.6200315d77cc5p9 ++0x1.000000065ac8bp0 ++0x1.0000000000037p0 ++0x1.6200315ad0fbfp9 ++0x1.6200315dacc95p9 ++0x1.000000000002fp-256 ++0x1.000000000000ep256 ++0x1.00000006bf05cp0 ++0x1.0000000000051p256 ++0x1.0000000000062p0 ++0x1.0000000000031p256 ++0x1.6200315be943dp9 ++0x1.000000000005bp0 ++0x1.0000000000045p0 ++0x1.6200315e08505p9 ++0x1.000000000001bp256 ++0x1.0000000000005p256 ++0x1.000000000005dp256 ++0x1.6200315ad0fc9p9 ++0x1.6200315e97676p9 ++0x1.0000000000024p0 ++0x1.0000000000003p-256 ++0x1.6200315ad0fd4p9 ++0x1.6200315ee2c3bp9 ++0x1.0000000000020p0 ++0x1.6200315ad0fdcp9 ++0x1.0000000000053p-256 ++0x1.000000000004bp-256 ++0x1.6200315cafb6ep9 ++0x1.000000000003ap256 ++0x1.0000000000013p-256 ++0x1.0000000000060p256 ++0x1.6200315ad0fd3p9 ++0x1.0000000000009p-256 ++0x1.000000000005cp-256 ++0x1.00000000acff5p0 ++0x1.000000000004dp0 ++0x1.0000000000050p256 ++0x1.6200315e34fc6p9 ++0x1.0000000000044p-256 ++0x1.000000000002dp256 ++0x1.0000000000062p256 ++0x1.6200315bf4442p9 ++0x1.6200315ad0fabp9 ++0x1.000000000003cp0 ++0x1.0000000000019p256 ++0x1.000000000000cp-256 ++0x1.000000000000bp-256 ++0x1.0000000000063p0 ++0x1.000000000003cp256 ++0x1.0000000000061p-256 ++0x1.6200315ad0fb1p9 ++0x1.00000006456f9p0 ++0x1.6200315ad0fb9p9 ++0x1.6200315ad0fccp9 ++0x1.6200315ad0fd5p9 ++0x1.6200315ad0fd0p9 ++0x1.0000000353687p0 ++0x1.6200315ad0facp9 ++0x1.000000000005bp256 ++0x1.6200315e8bb51p9 ++0x1.6200315d73094p9 ++0x1.000000027bdbap0 ++0x1.000000006f2b7p0 ++0x1.0000000000057p0 ++0x1.0000000298327p0 ++0x1.000000019a7f7p0 ++0x1.6200315b7b9ddp9 ++0x1.000000041cf9ep0 ++0x1.0000000000040p256 ++0x1.0000000000059p0 ++0x1.6200315ad0fe2p9 ++0x1.0000000000056p0 ++0x1.0000000000034p-256 ++0x1.6200315cf49aep9 ++0x1.0000000000017p-256 ++0x1.000000000bae8p0 ++0x1.6200315ad0fc1p9 ++0x1.00000004c336dp0 ++0x1.0000000000032p256 ++0x1.6200315ae9fb5p9 ++0x1.000000000004cp256 ++0x1.0000000000057p-256 ++0x1.0000000000035p-256 ++0x1.6200315d4d455p9 ++42 ++0x1.6200315ad0fa8p9 ++0x1.00000002502f2p0 ++0x1.6200315ad0fa3p9 ++0x1.000000000005dp0 ++0x1.0000000000012p-256 ++0x1.0000000000006p256 ++0x1.0000000000028p-256 ++0x1.0000000000044p256 ++0x1.000000000004ap0 ++0x1.00000000927ffp0 ++0x1.0000000000044p0 ++0x1.00000006f8909p0 ++0x1.6200315ad0fc8p9 ++0x1.0000000000061p0 ++0x1.000000012a7e8p0 ++0x1.000000000000fp-256 ++0x1.6200315b6f0a0p9 ++0x1.00000001b92adp0 ++0x1.000000000005ep-256 ++0x1.6200315d436fep9 ++0x1.000000004301dp0 ++0x1.0000000000023p0 ++0x1.000000000005ap0 ++0x1.6200315e7189ap9 ++0x1.0000000000033p0 ++0x1.6200315c19f20p9 ++0x1.0000000000040p-256 ++0x1.0000000000031p0 ++0x1.0000000000027p0 ++0x1.6200315d1dfeap9 ++0x1.0000000588fc5p0 ++0x1.000000015ad42p0 ++0x1.6200300248616p9 ++0x1.0000000000021p256 ++0x1.6200315ad0fcap9 ++0x1.6200315ad0fbbp9 ++0x1.6200315ad0fbep9 ++0x1.0000000000052p0 ++0x1.0000000000016p-256 ++0x1.0000000000005p-256 ++0x1.0000000000046p256 ++0x1.000000000003cp-256 ++0x1.0000000000054p0 ++0x1.000000034ce7ep0 ++0x1.0000000000050p-256 ++0x1.000000000002fp256 ++0x1.6200315f2a44bp9 ++0x1.6200315ad0fa2p9 ++0x1.6200315f53addp9 ++0x1.0000000000043p256 ++0x1.000000000002bp0 ++0x1.6200315b9a51fp9 ++0x1.62003002148e6p9 ++0x1.0000000000039p-256 ++0x1.0000000000023p-256 ++0x1.00000006d45eep0 ++0x1.000000000002cp0 ++0x1.0000000000055p256 ++0x1.000000000000ap256 ++0x1.0000000000010p-256 ++0x1.0000000000047p-256 ++0x1.000000000002fp0 ++0x1.0000000000001p256 ++0x1.000000040ff8cp0 ++0x1.0000000121a96p0 ++0x1.6200315c8b9bcp9 ++0x1.000000000001cp-256 ++0x1.0000000000063p-256 ++0x1.0000000000006p-256 ++0x1.000000000001ap-256 ++0x1.6200300247b12p9 ++0x1.0000000000046p0 ++0x1.0000000000036p-256 ++0x1.00000004bcb64p0 ++0x1.0000000000032p-256 ++0x1.0000000000057p256 ++0x1.6200315e03518p9 ++0x1.00000005331abp0 ++0x1.000000000001ep-256 ++0x1.6200315f76ad3p9 ++0x1.000000000004dp-256 ++0x1.000000000003bp0 ++0x1.00000005b6032p0 ++0x1.0000000000007p-256 ++0x1.6200315ad0fc4p9 ++0x1.0000000000051p-256 ++0x1.000000000005cp0 ++0x1.6200315ad0fc6p9 ++0x1.0000000100a97p0 ++0x1.0000000000040p0 ++0x1.000000000004fp0 ++0x1.000000000003dp0 ++0x1.0000000000027p256 ++0x1.0000000000000p-256 ++0x1.6200315b10d8dp9 ++0x1.0000000000060p-256 ++0x1.6200315ad0fcdp9 ++0x1.6200315ad0fa4p9 ++0x1.6200315d07f8ep9 ++0x1.000000000001bp-256 ++0x1.0000000000041p0 ++0x1.6200315ad0fe1p9 ++0x1.0000000000053p0 ++0x1.00000003168edp0 ++0x1.0000000000000p256 ++0x1.0000000000002p-256 ++0x1.6200315bd4cecp9 ++0x1.0000000000047p256 ++0x1.6200315b2b8adp9 ++0x1.000000000002bp256 ++0x1.0000000000055p-256 ++0x1.000000000004ap256 ++0x1.00000006c9b25p0 ++0x1.0000000000054p-256 ++0x1.0000000000047p0 ++0x1.6200315d8ee5dp9 ++0x1.6200315b74b4cp9 ++0x1.000000000005ap256 ++0x1.0000000000043p-256 ++0x1.0000000000055p0 ++0x1.0000000000019p-256 ++0x1.000000031d0f6p0 ++0x1.00000006ede40p0 ++0x1.00000002152cfp0 ++0x1.6200315f61210p9 ++0x1.6200315ad0fadp9 ++0x1.000000044ea9dp0 ++0x1.0000000000050p0 ++0x1.0000000000024p256 ++0x1.000000022b033p0 ++0x1.0000000000043p0 ++0x1.000000000001fp256 ++0x1.0000000000034p0 ++0x1.0000000000025p-256 ++0x1.0000000000034p256 ++0x1.000000000001dp0 ++0x1.000000000005ap-256 ++0x1.6200315ad0fddp9 ++0x1.0000000577cf3p0 ++0x1.000000051b6d0p0 ++0x1.00000006143ccp0 ++0x1.0000000000010p256 ++0x1.000000061ee95p0 ++0x1.6200315c3eed5p9 ++0x1.00000000dfa98p0 ++0x1.0000000000049p-256 ++0x1.0000000000052p256 ++0x1.0000000000053p256 ++0x1.000000000005bp-256 ++0x1.000000000000ep-256 ++0x1.6200315e8ca3cp9 ++0x1.6200315ad0faap9 ++0x1.0000000142a95p0 ++0x1.6200315ad0fcep9 ++0x1.6200315ad0fcbp9 ++0x1.6200315ef86c6p9 ++0x1.0000000000026p-256 ++0x1.6200315ed1587p9 ++0x1.000000067021dp0 ++0x1.00000001e72bep0 ++0x1.6200315ad0fbap9 ++0x1.00000000d6d46p0 ++0x1.0000000000058p0 ++0x1.00000000a42a3p0 ++0x1.6200315b50c42p9 ++0x1.6200315c4ee10p9 ++0x1.0000000416795p0 ++0x1.0000000000014p-256 ++0x1.0000000000037p-256 ++0x1.6200315ad0fa6p9 ++0x1.0000000000004p-256 ++0x1.0000000000054p256 ++0x1.000000018254ap0 ++0x1.6200315dc2365p9 ++0x1.0000000000015p-256 ++0x1.000000000004fp-256 ++0x1.0000000665754p0 ++0x1.0000000000046p-256 ++0x1.6200315b2ba38p9 ++0x1.000000000002bp-256 ++0x1.6200315ba202ep9 ++0x1.0000000000008p-256 ++0x1.0000000359e90p0 ++0x1.00000004dae48p0 ++0x1.000000000001cp256 ++0x1.0000000000062p-256 ++0x1.0000000000048p0 ++0x1.000000000003fp256 ++0x1.6200315bcd48bp9 ++0x1.6200315ad0fa9p9 ++0x1.0000000000030p256 ++0x1.6200315d64448p9 ++0x1.0000000089aadp0 ++0x1.6200315f0aa29p9 ++0x1.00000005d1dcdp0 ++0x1.6200315ad0fdep9 ++0x1.0000000000061p256 ++0x1.0000000000058p-256 ++0x1.0000000000012p256 ++0x1.000000000005fp0 ++0x1.000000000003ap0 ++0x1.000000000000bp256 ++0x1.000000000004bp0 ++0x1.0000000000038p-256 ++0x1.0000000000029p0 ++0x1.0000000000025p256 ++0x1.000000000001dp256 ++0x1.0000000000004p256 ++0x1.6200315e2240ep9 ++0x1.6200315ad0fc3p9 ++0x1.6200315b2bbc3p9 ++0x1.0000000000014p256 ++0x1.0000000078009p0 ++0x1.000000000003dp256 ++0x1.6200315db488fp9 ++0x1.000000000000ap-256 ++0x1.000000000004ep0 ++0x1.0000000000035p0 ++0x1.0000000000048p-256 ++# Slow path with computation in 144 bit precision. ++# Implemented in: sysdeps/ieee754/dbl-64/mpexp.c ++## name: 144bits ++0x1.0000000002d96p0 ++0x1.000000000bae8p0 ++0x1.0000000031579p0 ++0x1.000000003a2cbp0 ++0x1.000000004301dp0 ++0x1.000000004bd6fp0 ++0x1.0000000054ac1p0 ++0x1.000000005d813p0 ++0x1.00000005ab569p0 ++0x1.00000005b6032p0 ++0x1.00000005c7304p0 ++0x1.00000005d1dcdp0 ++0x1.00000005e309fp0 ++0x1.00000005edb68p0 ++0x1.0000000609903p0 ++0x1.00000006143ccp0 ++0x1.000000061ee95p0 ++0x1.00000006456f9p0 ++0x1.00000006501c2p0 ++0x1.000000065ac8bp0 ++0x1.0000000665754p0 ++0x1.000000067021dp0 ++0x1.000000067ace6p0 ++0x1.00000006857afp0 ++0x1.0000000690278p0 ++0x1.00000006bf05cp0 ++0x1.00000006c9b25p0 ++0x1.00000006d45eep0 ++0x1.00000006ede40p0 ++0x1.00000006f8909p0 ++0x1.62003000076d2p9 ++0x1.6200300017e2cp9 ++0x1.6200300023ffbp9 ++0x1.620030002b135p9 ++0x1.6200300030a8bp9 ++0x1.620030003123fp9 ++0x1.62003000652b3p9 ++0x1.620030007bf4ap9 ++0x1.6200300081a79p9 ++0x1.6200300090289p9 ++0x1.620030009dcbbp9 ++0x1.62003000c07cep9 ++0x1.62003000ee5dbp9 ++0x1.62003000fa646p9 ++0x1.62003000fe2cap9 ++0x1.6200300125996p9 ++0x1.6200300130865p9 ++0x1.6200300133673p9 ++0x1.6200300136fdfp9 ++0x1.6200300150360p9 ++0x1.620030016c416p9 ++0x1.6200315ee2c3bp9 ++0x1.6200315ef86c6p9 ++0x1.6200315efe051p9 ++0x1.6200315f00e77p9 ++0x1.6200315f0aa29p9 ++0x1.6200315f211bep9 ++0x1.6200315f2a44bp9 ++0x1.6200315f53addp9 ++0x1.6200315f61210p9 ++0x1.6200315f76ad3p9 ++# Slowest path with computation in 768 bit precision. ++# Implemented in: sysdeps/ieee754/dbl-64/mpexp.c ++## name: 768bits ++708.00096423260981737257679924368858 ++0x1.00000027f5496p0 ++0x1.0000015853da7p0 ++0x1.0000098e5e007p0 ++0x1.0000099a1ac59p0 +diff -urN glibc-2.17-c758a686/benchtests/ffs-inputs glibc-2.17-c758a686/benchtests/ffs-inputs +--- glibc-2.17-c758a686/benchtests/ffs-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/ffs-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,103 @@ ++## args: int ++## ret: int ++## includes: strings.h ++0x33ed4 ++0x2b ++0xba3f6965 ++0x4 ++0x927e0ceb ++0x7 ++0x0 ++0x3418b ++0x318c ++0x19a7402 ++0x699d4586 ++0x392e4 ++0x66 ++0x7fc86 ++0x13d ++0x2aa7a61 ++0x29d ++0x1d729b2 ++0x13a ++0x7 ++0x11b958 ++0x3a6a23 ++0x1b0d749 ++0x1f12ecb ++0x21 ++0x285a ++0x24702 ++0x88799 ++0x10b ++0x5 ++0x572739 ++0x12f0 ++0xa36c89 ++0x1 ++0x1f58 ++0x33743ce8 ++0xbefe ++0x7 ++0x3 ++0xdc ++0x1713e ++0x8d28 ++0xbb0ef6d ++0x3c7 ++0x2 ++0xd0e53fcc ++0x2e2 ++0x762 ++0xf ++0x35 ++0x2fc6e7a ++0x105 ++0x58e3 ++0x3 ++0x16aa ++0x7b1b38 ++0x0 ++0x2b ++0x99538d ++0xb3234 ++0x322 ++0x806bd ++0xd73 ++0x503a ++0x7d ++0xb88bb919 ++0x4f5 ++0x1f757c4f ++0xc37e5 ++0xd9e519 ++0xf0a ++0xe9f1e8d ++0x4664 ++0x4 ++0x1 ++0x1 ++0x0 ++0x1ee25 ++0x75a24 ++0x73c57b0 ++0x300e9 ++0x9 ++0x5b ++0x6d25 ++0x38bf436e ++0xf4724994 ++0x2b ++0xb8a5de ++0x4a ++0x281da ++0x905db8 ++0x3d606 ++0x6c200855 ++0x21 ++0x354e0dfa ++0x2 ++0x1 ++0xf8297c3 ++0x2fed30 ++0xd4ab7 +diff -urN glibc-2.17-c758a686/benchtests/ffsll-inputs glibc-2.17-c758a686/benchtests/ffsll-inputs +--- glibc-2.17-c758a686/benchtests/ffsll-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/ffsll-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,103 @@ ++## args: long long ++## ret: int ++## includes: string.h ++0xedada05aba9463 ++0x7c4e52bbc75241 ++0x16ab7ad ++0x20ec623a4ccdb ++0x1e24e9ed059d ++0x3acf ++0x6eb28fbb803a274 ++0xc1 ++0x25fc2148c092529f ++0x1d10ba752e5 ++0x322bd878b3 ++0x26fa11b70e20 ++0x30cd6a05a17ca14b ++0x1591d3a2d0cc7 ++0x8119d76e910c1a ++0x2b24d878fee314 ++0x1c ++0x3022a3955 ++0xedc7b7b6a818 ++0x40 ++0xf28 ++0xa2ecb ++0x56a7e4211a2ca38 ++0x6a0ee2316382 ++0x634 ++0x58 ++0x4fad66fb43f5 ++0x1f004b76 ++0x7 ++0x6ff84575bb70af ++0x5d5b4e ++0xaa614b130 ++0x15504 ++0x1a2e2e7e ++0x54b0f28b383cc ++0x6 ++0x2a2a3440b7 ++0x158a132dc0c20836 ++0x77aa8e9c91c43b1 ++0x33f526901fc08594 ++0x7bf156c ++0xb458b5e ++0x6289fcb44 ++0x4d84973bbd8c00 ++0x2e8c2de648 ++0x150fab ++0x16ebb7bae02934 ++0x485285b6065272 ++0xfdde0b16299 ++0x747d3c940cb ++0x1bdb379 ++0xfcb26a ++0x20b90cc92bbef ++0x46 ++0xf0e681aaec28b2d5 ++0x10c738cf1109 ++0x8509bef69993908 ++0x3332 ++0x219167d ++0x7eb19c6f88f ++0x32a1b4ead441e65 ++0xdc93 ++0x327a7e6676802312 ++0xcc7296c957 ++0xb0b20c47c6b500a ++0x55d614072f1 ++0x3c8e4 ++0x1a ++0x5809b7ae ++0x2 ++0x1525 ++0x13 ++0x6e ++0x1b ++0x7c58cf ++0x2f5347197bcf6 ++0x516a0d576e2c3 ++0x4f3cf315 ++0x3c16a7531f3a1 ++0xa929f8 ++0x1ce88e5 ++0x6ab464e92bc3 ++0x3ff39bb2 ++0xea9921 ++0xb3009 ++0x39b037793bef0da0 ++0x5d ++0x39a9989019c92 ++0x108bae ++0x239c1c ++0x1851dc9178f4 ++0x1fc6f70 ++0x38 ++0xa8f606a147 ++0x30dac66b ++0x76d377c20b0e836 ++0x2425 ++0x4e5a82884 ++0x7a1f128a894728 ++0xb5f0af24e3f7347 +diff -urN glibc-2.17-c758a686/benchtests/json-lib.c glibc-2.17-c758a686/benchtests/json-lib.c +--- glibc-2.17-c758a686/benchtests/json-lib.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/json-lib.c 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,178 @@ ++/* Simple library for printing JSON data. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include "json-lib.h" ++ ++void ++json_init (json_ctx_t *ctx, unsigned int indent_level, FILE *fp) ++{ ++ ctx->indent_level = indent_level; ++ ctx->fp = fp; ++ ctx->first_element = true; ++} ++ ++static void ++do_indent (json_ctx_t *ctx) ++{ ++ char indent_buf[ctx->indent_level + 1]; ++ ++ memset (indent_buf, ' ', ctx->indent_level + 1); ++ indent_buf[ctx->indent_level] = '\0'; ++ ++ fputs (indent_buf, ctx->fp); ++} ++ ++void ++json_document_begin (json_ctx_t *ctx) ++{ ++ do_indent (ctx); ++ ++ fputs ("{\n", ctx->fp); ++ ++ ctx->indent_level++; ++ ctx->first_element = true; ++} ++ ++void ++json_document_end (json_ctx_t *ctx) ++{ ++ ctx->indent_level--; ++ ++ do_indent (ctx); ++ ++ fputs ("\n}", ctx->fp); ++} ++ ++void ++json_attr_object_begin (json_ctx_t *ctx, const char *name) ++{ ++ if (!ctx->first_element) ++ fprintf (ctx->fp, ",\n"); ++ ++ do_indent (ctx); ++ ++ fprintf (ctx->fp, "\"%s\": {\n", name); ++ ++ ctx->indent_level++; ++ ctx->first_element = true; ++} ++ ++void ++json_attr_object_end (json_ctx_t *ctx) ++{ ++ ctx->indent_level--; ++ ctx->first_element = false; ++ ++ fputs ("\n", ctx->fp); ++ ++ do_indent (ctx); ++ ++ fputs ("}", ctx->fp); ++} ++ ++void ++json_attr_string (json_ctx_t *ctx, const char *name, const char *s) ++{ ++ if (!ctx->first_element) ++ fprintf (ctx->fp, ",\n"); ++ else ++ ctx->first_element = false; ++ ++ do_indent (ctx); ++ ++ fprintf (ctx->fp, "\"%s\": \"%s\"", name, s); ++} ++ ++void ++json_attr_double (json_ctx_t *ctx, const char *name, double d) ++{ ++ if (!ctx->first_element) ++ fprintf (ctx->fp, ",\n"); ++ else ++ ctx->first_element = false; ++ ++ do_indent (ctx); ++ ++ fprintf (ctx->fp, "\"%s\": %g", name, d); ++} ++ ++void ++json_array_begin (json_ctx_t *ctx, const char *name) ++{ ++ if (!ctx->first_element) ++ fprintf (ctx->fp, ",\n"); ++ ++ do_indent (ctx); ++ ++ fprintf (ctx->fp, "\"%s\": [", name); ++ ++ ctx->indent_level++; ++ ctx->first_element = true; ++} ++ ++void ++json_array_end (json_ctx_t *ctx) ++{ ++ ctx->indent_level--; ++ ctx->first_element = false; ++ ++ fputs ("]", ctx->fp); ++} ++ ++void ++json_element_double (json_ctx_t *ctx, double d) ++{ ++ if (!ctx->first_element) ++ fprintf (ctx->fp, ", %g", d); ++ else ++ { ++ fprintf (ctx->fp, "%g", d); ++ ctx->first_element = false; ++ } ++} ++ ++void ++json_element_object_begin (json_ctx_t *ctx) ++{ ++ if (!ctx->first_element) ++ fprintf (ctx->fp, ","); ++ ++ fputs ("\n", ctx->fp); ++ ++ do_indent (ctx); ++ ++ fputs ("{\n", ctx->fp); ++ ++ ctx->indent_level++; ++ ctx->first_element = true; ++} ++ ++void ++json_element_object_end (json_ctx_t *ctx) ++{ ++ ctx->indent_level--; ++ ctx->first_element = false; ++ ++ fputs ("\n", ctx->fp); ++ ++ do_indent (ctx); ++ ++ fputs ("}", ctx->fp); ++} +diff -urN glibc-2.17-c758a686/benchtests/json-lib.h glibc-2.17-c758a686/benchtests/json-lib.h +--- glibc-2.17-c758a686/benchtests/json-lib.h 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/json-lib.h 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,47 @@ ++/* Simple library for printing JSON data. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef __JSON_LIB_H__ ++#define __JSON_LIB_H__ ++ ++#include ++#include ++ ++struct json_ctx ++{ ++ FILE *fp; ++ unsigned int indent_level; ++ bool first_element; ++}; ++ ++typedef struct json_ctx json_ctx_t; ++ ++void json_init (json_ctx_t *ctx, unsigned int indent_level, FILE *fp); ++void json_document_begin (json_ctx_t *ctx); ++void json_document_end (json_ctx_t *ctx); ++void json_attr_object_begin (json_ctx_t *ctx, const char *name); ++void json_attr_object_end (json_ctx_t *ctx); ++void json_attr_string (json_ctx_t *ctx, const char *name, const char *s); ++void json_attr_double (json_ctx_t *ctx, const char *name, double d); ++void json_array_begin (json_ctx_t *ctx, const char *name); ++void json_array_end (json_ctx_t *ctx); ++void json_element_double (json_ctx_t *ctx, double d); ++void json_element_object_begin (json_ctx_t *ctx); ++void json_element_object_end (json_ctx_t *ctx); ++ ++#endif +diff -urN glibc-2.17-c758a686/benchtests/log2-inputs glibc-2.17-c758a686/benchtests/log2-inputs +--- glibc-2.17-c758a686/benchtests/log2-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/log2-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,203 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.fe80b73f2f763p-485 ++0x1.63fbf19a1a79ap-572 ++0x1.63fb4717f36abp-594 ++0x1.6a75240c62b59p-162 ++0x1.43ad207275c97p-830 ++0x1.1c24c26efbca5p-673 ++0x1.c37f23c54205ap655 ++0x1.fdc0e348d5bbbp722 ++0x1.0e2e51e9645a9p503 ++0x1.3291a6e483d75p-941 ++0x1.6b4f9118d9ddfp329 ++0x1.618e84faa68d1p-696 ++0x1.7f8a7417686dbp577 ++0x1.3fc6a169fc1a2p662 ++0x1.6631142da8476p-11 ++0x1.67cc768721f6ep159 ++0x1.7439b48fb7f01p-744 ++0x1.17cad4e754e3fp-833 ++0x1.6ca873e653646p35 ++0x1.6283941b425d9p-322 ++0x1.38de764542fc9p-939 ++0x1.6a5706bcca88ep318 ++0x1.8b9e71efccf99p-671 ++0x1.61d7a07ca117fp-246 ++0x1.66707402ed87fp468 ++0x1.650ff2faef0c4p-185 ++0x1.6afe3332695d8p-382 ++0x1.5c05817f1aec0p861 ++0x1.61bb62e0a68cdp625 ++0x1.678e93ded24cep-614 ++0x1.d2b6e60469afdp-753 ++0x1.abb9a6eed73b2p-731 ++0x1.21a4014034f31p-718 ++0x1.bdbe3237b3785p779 ++0x1.0f115229b9a52p-437 ++0x1.6154e26a722b2p388 ++0x1.64e982a82df60p346 ++0x1.61bdc663af57bp799 ++0x1.091f7362aa8bfp-871 ++0x1.e35153cac25b3p873 ++0x1.6402b62fbebf7p-329 ++0x1.680d413ef3777p775 ++0x1.8620d183bd0a7p-670 ++0x1.e0e017206206ep-129 ++0x1.66d9419f2852cp-526 ++0x1.5a07e14aa7e55p-888 ++0x1.b91ed57fdd3f2p1017 ++0x1.7c58838087ef5p519 ++0x1.2d0676720fb21p-145 ++0x1.64bcd3d675a60p-390 ++0x1.6204f6b121d0dp255 ++0x1.6af30218cdccfp-955 ++0x1.dcf3f2c2809e1p-821 ++0x1.6269366dd0672p436 ++0x1.dd117726eefe5p93 ++0x1.65de442c50bedp-28 ++0x1.10c8b6ab1a5f0p-313 ++0x1.6855f7474d2eep828 ++0x1.6659b0863e8d0p-545 ++0x1.7a80b6736105cp-566 ++0x1.3ff7a01b0590cp560 ++0x1.6559f386d6ca3p-696 ++0x1.68e96369693cep812 ++0x1.8d29a4b500b0dp537 ++0x1.65b347d411765p826 ++0x1.669080c6f3a8bp-121 ++0x1.faabb750c7baep548 ++0x1.670f72a6f1cd1p834 ++0x1.6b75063adb10dp396 ++0x1.f030420faed63p-788 ++0x1.a20214aeefbe0p186 ++0x1.8b3af704f3526p449 ++0x1.6663a7e181023p-643 ++0x1.e1f6d671b95f6p978 ++0x1.6aea24ab9c956p84 ++0x1.6318c0bc48f9bp-996 ++0x1.6603e22b2d2d1p-257 ++0x1.6b59906a87ddfp-896 ++0x1.665307aea1415p-153 ++0x1.6d9be19aca354p-887 ++0x1.640977cfbd7dep-564 ++0x1.1c6de3bf6f82ep909 ++0x1.24c452230e994p705 ++0x1.6b2c473cd0623p-626 ++0x1.beab17bff5e9ap-708 ++0x1.680445b6d430bp465 ++0x1.454de219171f0p158 ++0x1.6818a49dfb38dp20 ++0x1.15cb95403d2a4p622 ++0x1.1338a5210da9ap-78 ++0x1.651fc5045320ep-861 ++0x1.657ed41aace5bp-2 ++0x1.ff563189469ffp-44 ++0x1.62c811ba1d5e4p1 ++0x1.61f23108289f9p-422 ++0x1.168066765d078p875 ++0x1.a671a61b114a2p124 ++0x1.4471a372f703ep252 ++0x1.623ae599ffa3fp98 ++0x1.531085de4958bp441 ++0x1.4d6172de45534p-911 ++0x1.e5dcc2b3d23acp-437 ++0x1.67cac1dccdfcdp985 ++0x1.0ac1a5608baf9p-896 ++0x1.654cd778b1e36p837 ++0x1.929004c882902p-552 ++0x1.594a8c88348b0p-970 ++0x1.dc7f4509ddfd6p-832 ++0x1.d49846a313b79p998 ++0x1.6314b3a5ac85bp1018 ++0x1.d1d1325f66b7ep-763 ++0x1.6592a24f64047p403 ++0x1.bd47a2a1cc99fp-486 ++0x1.644266dda9ad2p778 ++0x1.6b2e821002783p26 ++0x1.69936648ba64ap-143 ++0x1.61d2a2a99f470p-970 ++0x1.6599c252868bap-840 ++0x1.3590b2e6af870p56 ++0x1.6b8311b9abc91p-961 ++0x1.29d1a705c6a3bp-660 ++0x1.6815d5d44778ap945 ++0x1.6ae36036fcee1p153 ++0x1.2034b640f0f4ap-3 ++0x1.84fec67d11992p85 ++0x1.1fa1a74c0af59p-478 ++0x1.64de9092a8789p-784 ++0x1.701bf3e5b0120p243 ++0x1.63ac048ca107bp-666 ++0x1.0095c464cfc5ap58 ++0x1.5f2d0041e5db2p362 ++0x1.62fa34a5c1bcap-412 ++0x1.cacf042abda4fp-54 ++0x1.647a95ef487b3p224 ++0x1.f8c2353681cbep905 ++0x1.67bfe67714076p366 ++0x1.6779865baf78fp-291 ++0x1.9395b1beca360p361 ++0x1.6521449e5ffe2p-671 ++0x1.667567cd5db59p-293 ++0x1.511df0b72a30bp30 ++0x1.65f8251162417p642 ++0x1.d0a0825ffb10cp210 ++0x1.63f2f5ba5415ap-716 ++0x1.65681206c6030p-580 ++0x1.5254d49bacf90p-849 ++0x1.49dd92d7cf7fep-208 ++0x1.688f565603c25p473 ++0x1.6439333b5f705p-589 ++0x1.663922acbdbb0p208 ++0x1.5a2631eb8325cp490 ++0x1.6171d410fcbbfp683 ++0x1.6ae4d6f8f091ep511 ++0x1.ae8ff53250e31p-1012 ++0x1.f182e535fab45p-332 ++0x1.653f84e9e8c3fp-34 ++0x1.99a737ac5cdadp328 ++0x1.301bb0b8607cbp232 ++0x1.706fa3fcd1d85p337 ++0x1.b650863c8ead0p227 ++0x1.64b9045b2d59dp740 ++0x1.681c66eda34d4p-113 ++0x1.f881050ae3a0cp-51 ++0x1.08bb778ebc5b6p-28 ++0x1.815fe4e6e4b72p100 ++0x1.691b6172a5798p-576 ++0x1.684f74d76367cp1010 ++0x1.64d044c4779d2p-207 ++0x1.690c021b1ae97p454 ++0x1.9d0ec359f67d5p77 ++0x1.43686724be426p774 ++0x1.678821f848886p-43 ++0x1.17abd1fcb3d3bp532 ++0x1.616ee4093684fp-43 ++0x1.631ec6e8ef9a7p264 ++0x1.63aa97d7de121p795 ++0x1.b172e7750d144p841 ++0x1.6836107e18e77p-826 ++0x1.65957572dedc3p-339 ++0x1.66b8d2cad9382p301 ++0x1.c8f410709f858p-761 ++0x1.6a2093c2b009dp-1013 ++0x1.b97a45fb7dad5p660 ++0x1.8150734f7fc95p40 ++0x1.6ab8a053c9089p-246 ++0x1.6b81e74a6293ep-813 ++0x1.251a74cf150acp779 ++0x1.44cf3370a55eap703 ++0x1.32e2e35cc77f3p-4 ++0x1.c0c6049562d13p-997 ++0x1.a050f54285fb8p-397 ++0x1.68ada319f3033p748 ++0x1.b2f37264e0acbp753 ++0x1.617614c5ecea7p137 ++0x1.b01c803ac06b1p559 ++0x1.4a19f60ad4238p-223 ++0x1.6314648785495p-40 ++0x1.6936664ef255fp943 ++0x1.6208f15a6484fp464 ++0x1.6b1244514989ep-886 +diff -urN glibc-2.17-c758a686/benchtests/log-inputs glibc-2.17-c758a686/benchtests/log-inputs +--- glibc-2.17-c758a686/benchtests/log-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/log-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,295 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.0c5e3365a2d95p0 ++0x1.037414ff63ab9p0 ++0x1.fc9366fa4c3a0p-1 ++0x1.f710159a37ab9p-1 ++0x1.5576e114e4f7cp-961 ++0x1.9d3382c6679b7p-1 ++0x1.f9e37774c7510p-1 ++0x1.058622e63af9dp0 ++0x1.fa62a3b5d47b5p-1 ++0x1.01fb737f14c41p250 ++0x1.fc7952a4bde83p-1 ++0x1.b68a54ad54fb4p-320 ++0x1.b8978216476a5p837 ++0x1.345bf2c9c6238p-638 ++0x1.580da4a80849ap197 ++0x1.fb0f43269facap-1 ++0x1.065f47ccd6b6cp0 ++0x1.db1317a87c872p-928 ++0x1.f563a1330ee1bp-1 ++0x1.8352661de852dp-1 ++0x1.887750a7ad5d0p315 ++0x1.385ed12583117p674 ++0x1.ff610285e1e46p-1 ++0x1.02e063a2777f0p-254 ++0x1.6b0f9482349a9p-489 ++0x1.f0413135a3a88p430 ++0x1.1ec910ecf9419p2 ++0x1.caab24b23bfdap-1 ++0x1.42d83712a1fabp-995 ++0x1.01d4b06dc2ce1p-2 ++0x1.c10a94cb4f93dp2 ++0x1.071a5441b3cabp0 ++0x1.04e8940083142p504 ++0x1.5083603bf110cp-660 ++0x1.f5312171625f3p-1 ++0x1.f15370065e66dp-1 ++0x1.f4de71c3efa90p-1 ++0x1.072a679084c2ep0 ++0x1.f89d125e68705p-1 ++0x1.31a5450e17b4fp10 ++0x1.036d1462f82d5p-1 ++0x1.54f131208767bp0 ++0x1.016fc65a58dd9p0 ++0x1.24b2c009625bfp-512 ++0x1.2898b1cc9ddc8p-1 ++0x1.0270851f17bb1p-241 ++0x1.eb1f03c6aa4d3p38 ++0x1.d29a93f1faf4fp964 ++0x1.d31de19a4e829p140 ++0x1.f8d260eeb5cefp-1 ++0x1.f259a4bc8f770p-1 ++0x1.8b9016448c4ccp-105 ++0x1.240f40168110bp-253 ++0x1.06fb26943be9bp0 ++0x1.9bae861967209p87 ++0x1.51fcc64d69563p-48 ++0x1.f4ff2413b004bp-1 ++0x1.387d65055d963p4 ++0x1.1c5705c916859p929 ++0x1.073be54be8356p0 ++0x1.544871c917766p-1 ++0x1.398536e090d37p-79 ++0x1.f34707ce261e5p-1 ++0x1.2e5792109f59bp593 ++0x1.075bd0ce07ef0p0 ++0x1.0ef545b2e5627p0 ++0x1.b2aa170bed688p-919 ++0x1.e341461098908p984 ++0x1.eacd43dea8eb2p-1 ++0x1.18c2a0ab6598bp265 ++0x1.219df5338fbc1p482 ++0x1.a9a0d4ceb201dp2 ++0x1.c0a6467baf54dp-23 ++0x1.0b499489342c1p361 ++0x1.f7c1f18cae6f4p-42 ++0x1.d8dea4350fb7fp627 ++0x1.0541421affe22p0 ++0x1.574bd3c94bdc9p-528 ++0x1.9aa814150ab62p-1 ++0x1.cab9532515b30p10 ++0x1.01e446e6b365ep0 ++0x1.04ef17a8014c7p0 ++0x1.fd91b3dc4e166p-98 ++0x1.9e879318176aap-448 ++0x1.605e9760da702p457 ++0x1.3e1d3541f8a73p131 ++0x1.ce2a303076cbap-9 ++0x1.f72021eaea3b7p-547 ++0x1.3384548e90a6dp222 ++0x1.0215143216bbap0 ++0x1.f546109b8e222p-1 ++0x1.b828c4971379dp779 ++0x1.0465440f18b39p0 ++0x1.00a302042eb49p0 ++0x1.9914e6bc2d08dp-637 ++0x1.aa8176fc83146p3 ++0x1.0dc041c8c9084p788 ++0x1.c17f14032741cp157 ++0x1.f8c3355f2c74fp-1 ++0x1.c0c373cb8d3abp-568 ++0x1.ffb897f081c1cp-1 ++0x1.7da4d5c6ecca5p666 ++0x1.1f8dd20fc3029p-196 ++0x1.f39d30de8b00cp-1 ++0x1.5710417d88db0p526 ++0x1.f552e4572e2e0p-1 ++0x1.ce97f507ac81ep-196 ++0x1.fe0b407a35cf9p-1 ++0x1.ffba3091bc8d9p-1 ++0x1.f79207f982a95p907 ++0x1.f3bc85de399b1p-1 ++0x1.f6a9075959280p-1 ++0x1.9971a0d49cffcp0 ++0x1.fdd4d11db35dcp-1 ++0x1.9f453762d3790p-708 ++0x1.d1122424ad397p717 ++0x1.fd71a20e66628p-1 ++0x1.007c20fefd661p0 ++0x1.0137d702a29bdp0 ++0x1.93e9047c983bfp-16 ++0x1.10cdf415042b5p0 ++0x1.fe6d8639abca0p-1 ++0x1.f7278572f6b66p-1 ++0x1.0673e76436ebcp550 ++0x1.f34833c8c70bcp-1 ++0x1.1b530128cc02dp8 ++0x1.ae48a5851e7a3p-236 ++0x1.98bdb6dff9d19p74 ++0x1.fbfd85f14418ep-1 ++0x1.070dd2780fcdap22 ++0x1.07a8f5726ae12p0 ++0x1.9a2ac2db753f8p-892 ++0x1.1461250716450p57 ++0x1.3b5be316bc364p-3 ++0x1.a2143693816d1p862 ++0x1.9418a18831f94p-502 ++0x1.ea8306738954cp993 ++0x1.fff14533df4f3p-1 ++0x1.0693706ddc70cp1 ++0x1.59e3947bce39dp-4 ++0x1.fa64a24c3030ap-1 ++0x1.044ce02e484e6p0 ++0x1.a272b5bdc397ep327 ++0x1.1c4577fcbe052p4 ++0x1.00ede267fbd99p0 ++0x1.028e26e56b7dfp0 ++0x1.005cf758f0dd7p635 ++0x1.bca6110bd6b05p46 ++0x1.11e7148e3f7e4p137 ++0x1.616e31d9c78afp898 ++0x1.f2eff0abf8fa1p-1 ++0x1.fd2275eabbc55p-1 ++0x1.e8f5a410e1a82p-1 ++0x1.7124e6de4fec6p342 ++0x1.95b03344f67d4p74 ++0x1.fb46137fbdd00p-1 ++0x1.78f9961f0c11bp936 ++0x1.2d3230575fa1dp-23 ++0x1.5cd631b404c9dp564 ++0x1.6a7645d7bc818p-901 ++0x1.1daca63403190p-160 ++0x1.64b4929d7185dp7 ++0x1.f95a819a0c75ep-1 ++0x1.fa2a9599f61c2p-1 ++0x1.f68b82c96e845p-1 ++0x1.b5c634c9a19f0p-551 ++0x1.706c63689c814p917 ++0x1.fa1134f93ff1bp0 ++0x1.b8e642ca65132p12 ++0x1.fdb645fc3558fp-1 ++0x1.9909b15771ca6p2 ++0x1.f4f6132242443p-1 ++0x1.c02b65da31a5cp-9 ++0x1.8b40c0afd5a42p679 ++0x1.1d9f80f2849ebp1015 ++0x1.3426c343358d6p608 ++0x1.f634874d073bep-1 ++0x1.016ab0aff9b7dp0 ++0x1.f1f34486c65e2p-1 ++0x1.022e8230e4320p0 ++0x1.fbe0104a4b316p-1 ++0x1.55323737c4d7bp-69 ++0x1.fa3d13e0efecep-1 ++0x1.2a7e11b35214bp281 ++0x1.9a2c33af22120p-1 ++0x1.986983a9d6f51p-1 ++0x1.f2f723416775fp-1 ++0x1.5d8565304a570p2 ++0x1.f3999057087ebp-1 ++0x1.fff027a147cc4p-1 ++0x1.f369333fdcaa7p-1 ++0x1.15ee471de5adcp-537 ++0x1.faa9f49088862p-1 ++0x1.0138239c244bcp0 ++0x1.8c28955e4efb3p-1 ++0x1.c3db66d450094p-916 ++0x1.dc4b70539f21cp-390 ++0x1.f7a363909f425p501 ++0x1.fb86b76e851a5p-1 ++0x1.010290232f8fcp-97 ++0x1.650a4595be763p510 ++0x1.fbd7a36081ccdp-1 ++0x1.073f0084dc154p0 ++0x1.fb7951f83410dp868 ++0x1.0404d08738d62p0 ++0x1.f1d895b2a5fdap-1 ++0x1.55472046b4703p351 ++0x1.f63882efa2ec0p-1 ++0x1.f367c590b00e1p-1 ++0x1.5251b7177fe50p501 ++0x1.49f2a03e6057ap-140 ++0x1.d5a68682d9946p-1 ++0x1.fcdd65a9229b0p-1 ++0x1.98bea1a0d0fbep681 ++0x1.260d06b5edc4bp-336 ++0x1.f5d520240b30ap-1 ++0x1.f8715777db2f7p-1 ++0x1.b3b0b64c86e27p-1 ++0x1.ae637316fa604p2 ++0x1.79919761b73adp43 ++0x1.bd55c268d4f40p-1 ++0x1.c81103f744ee1p4 ++0x1.deeeb24db6f46p-1 ++0x1.1056a7ba848e4p566 ++0x1.b167817c24607p-513 ++0x1.95d245973230bp798 ++0x1.04d551a6da2dcp-921 ++0x1.df2572264569fp92 ++0x1.fb105105409c1p-1 ++0x1.277ce2d7a1945p20 ++0x1.fc93d4234f18bp-1 ++0x1.be9f65acd2fa6p-911 ++0x1.0548c4cb78cd1p400 ++0x1.794c300f69a14p688 ++0x1.7dda15569e759p731 ++0x1.fdc9d6a00fb8ep-1 ++0x1.faae623a143f1p-1 ++0x1.8128373a5b95ep-608 ++0x1.c2e13445f6ca7p316 ++0x1.01d3a3dd89524p0 ++0x1.aee2578e3f114p-1 ++0x1.863ff7799e878p-266 ++0x1.ea8897550748bp-262 ++0x1.0652f24fd5820p0 ++0x1.56114467afa90p1 ++0x1.01b4561c918a5p0 ++0x1.21cd64b06baebp339 ++0x1.3d6384a8fd1b3p-35 ++0x1.01af659ea1389p0 ++0x1.fa8ed0ab15042p-724 ++0x1.47c1f4babad96p785 ++0x1.fc47829fd7bdfp-1 ++0x1.f3d2241382331p-1 ++0x1.0a0897e048564p0 ++0x1.957ab3f18f8e3p-446 ++0x1.5aad466994dacp506 ++0x1.fba8a2b4ab119p-1 ++0x1.003c906ab1a79p0 ++0x1.7039f057a155fp-678 ++0x1.f85964e37aae8p-1 ++0x1.53e2e0469deecp-711 ++0x1.f0cb530a2bf7dp658 ++0x1.af8d471733d1dp-1022 ++0x1.a684e3b3af12dp-239 ++0x1.fd26d7fa466b5p1 ++0x1.ebd3605467082p163 ++0x1.e29567ed6afecp-11 ++0x1.073757004a5a1p0 ++0x1.022334168530bp0 ++0x1.d4a6e162f4ceap575 ++0x1.00dbb330a556fp0 ++0x1.276b872c49045p0 ++0x1.51e835ab51aafp-7 ++0x1.e3c106b648377p-184 ++0x1.5a46f2460d290p-46 ++0x1.199a05d85e80dp-258 ++0x1.cde614a60f60ap-1 ++0x1.50f3a79e68493p-152 ++0x1.2c9af562aa58dp0 ++0x1.f695411839d24p-1 ++0x1.e53e5125bcdffp413 ++0x1.03e4c3218f178p0 ++0x1.d66213dc2e585p-820 ++0x1.ff5b9106a784ep-1 ++0x1.4d4990f481852p-15 ++0x1.39a5976ee7210p-879 ++0x1.f5e4d494092e7p-1 ++0x1.2bb040585ffdep-28 ++0x1.f707b3cd873d2p-1 ++0x1.fc1a353ea30eap-1 ++0x1.fc44366f2d5c7p-1 ++0x1.f9fb832b4f54fp-1 +diff -urN glibc-2.17-c758a686/benchtests/Makefile glibc-2.17-c758a686/benchtests/Makefile +--- glibc-2.17-c758a686/benchtests/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/Makefile 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,164 @@ ++# Copyright (C) 2013-2015 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++ ++# Makefile for benchmark tests. The only useful target here is `bench`. ++# Add benchmark functions in alphabetical order. ++ ++# Run python scripts with $(PYTHON). ++PYTHON := python ++ ++subdir := benchtests ++ ++include ../Makeconfig ++bench-math := acos acosh asin asinh atan atanh cos cosh exp exp2 ffs ffsll \ ++ log log2 modf pow rint sin sincos sinh sqrt tan tanh ++ ++bench-pthread := pthread_once ++ ++bench := $(bench-math) $(bench-pthread) ++ ++# String function benchmarks. ++string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ ++ mempcpy memset rawmemchr stpcpy stpncpy strcasecmp strcasestr \ ++ strcat strchr strchrnul strcmp strcpy strcspn strlen \ ++ strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ ++ strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok ++string-bench-all := $(string-bench) ++ ++stdlib-bench := strtod ++ ++benchset := $(string-bench-all) $(stdlib-bench) ++ ++CFLAGS-bench-ffs.c += -fno-builtin ++CFLAGS-bench-ffsll.c += -fno-builtin ++ ++bench-malloc := malloc-thread ++ ++$(addprefix $(objpfx)bench-,$(bench-math)): $(libm) ++$(addprefix $(objpfx)bench-,$(bench-pthread)): $(shared-thread-library) ++$(objpfx)bench-malloc-thread: $(shared-thread-library) ++ ++ ++ ++# Rules to build and execute the benchmarks. Do not put any benchmark ++# parameters beyond this point. ++ ++# We don't want the benchmark programs to run in parallel since that could ++# affect their performance. ++.NOTPARALLEL: ++ ++include ../Rules ++ ++binaries-bench := $(addprefix $(objpfx)bench-,$(bench)) ++binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset)) ++binaries-bench-malloc := $(addprefix $(objpfx)bench-,$(bench-malloc)) ++ ++# The default duration: 10 seconds. ++ifndef BENCH_DURATION ++BENCH_DURATION := 10 ++endif ++ ++CPPFLAGS-nonlib += -DDURATION=$(BENCH_DURATION) ++ ++# Use clock_gettime to measure performance of functions. The default is to use ++# HP_TIMING if it is available. ++ifdef USE_CLOCK_GETTIME ++CPPFLAGS-nonlib += -DUSE_CLOCK_GETTIME ++endif ++ ++DETAILED_OPT := ++ ++ifdef DETAILED ++DETAILED_OPT := -d ++endif ++ ++# This makes sure CPPFLAGS-nonlib and CFLAGS-nonlib are passed ++# for all these modules. ++cpp-srcs-left := $(binaries-benchset:=.c) $(binaries-bench:=.c) \ ++ $(binaries-bench-malloc:=.c) ++lib := nonlib ++include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) ++ ++extra-objs += json-lib.o ++ ++bench-deps := bench-skeleton.c bench-timing.h Makefile ++ ++run-bench = $(test-wrapper-env) \ ++ $(run-program-env) \ ++ $($*-ENV) $(rtld-prefix) $${run} ++ ++timing-type := $(objpfx)bench-timing-type ++ ++bench-clean: ++ rm -f $(binaries-bench) $(addsuffix .o,$(binaries-bench)) ++ rm -f $(binaries-benchset) $(addsuffix .o,$(binaries-benchset)) ++ rm -f $(binaries-bench-malloc) $(addsuffix .o,$(binaries-bench-malloc)) ++ rm -f $(timing-type) $(addsuffix .o,$(timing-type)) ++ ++bench: $(timing-type) bench-set bench-func bench-malloc ++ ++bench-set: $(binaries-benchset) ++ for run in $^; do \ ++ echo "Running $${run}"; \ ++ $(run-bench) > $${run}.out; \ ++ done ++ ++bench-malloc: $(binaries-bench-malloc) ++ run=$(objpfx)bench-malloc-thread; \ ++ for thr in 1 8 16 32; do \ ++ echo "Running $${run} $${thr}"; \ ++ $(run-bench) $${thr} > $${run}-$${thr}.out; \ ++ done ++ ++# Build and execute the benchmark functions. This target generates JSON ++# formatted bench.out. Each of the programs produce independent JSON output, ++# so one could even execute them individually and process it using any JSON ++# capable language or tool. ++bench-func: $(binaries-bench) ++ { timing_type=$$($(timing-type)); \ ++ echo "{\"timing_type\": \"$${timing_type}\","; \ ++ echo " \"functions\": {"; \ ++ for run in $^; do \ ++ if ! [ "x$${run}" = "x$<" ]; then \ ++ echo ","; \ ++ fi; \ ++ echo "Running $${run}" >&2; \ ++ $(run-bench) $(DETAILED_OPT); \ ++ done; \ ++ echo; \ ++ echo " }"; \ ++ echo "}"; } > $(objpfx)bench.out-tmp; \ ++ if [ -f $(objpfx)bench.out ]; then \ ++ mv -f $(objpfx)bench.out $(objpfx)bench.out.old; \ ++ fi; \ ++ mv -f $(objpfx)bench.out-tmp $(objpfx)bench.out ++ $(PYTHON) scripts/validate_benchout.py $(objpfx)bench.out \ ++ scripts/benchout.schema.json ++ ++$(timing-type) $(binaries-bench) $(binaries-benchset) \ ++ $(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \ ++ $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ ++ $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) ++ $(+link) ++ ++$(objpfx)bench-%.c: %-inputs $(bench-deps) ++ { if [ -n "$($*-INCLUDE)" ]; then \ ++ cat $($*-INCLUDE); \ ++ fi; \ ++ $(PYTHON) scripts/bench.py $(patsubst %-inputs,%,$<); } > $@-tmp ++ mv -f $@-tmp $@ +diff -urN glibc-2.17-c758a686/benchtests/modf-inputs glibc-2.17-c758a686/benchtests/modf-inputs +--- glibc-2.17-c758a686/benchtests/modf-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/modf-inputs 2015-06-20 21:22:16.301457983 -0400 +@@ -0,0 +1,4 @@ ++## includes: math.h ++## args: double: ++42.0 ++-42.0 +diff -urN glibc-2.17-c758a686/pow-inputs glibc-2.17-c758a686/benchtests/pow-inputs +--- glibc-2.17-c758a686/benchtests/pow-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/pow-inputs 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,511 @@ ++## args: double:double ++## ret: double ++## includes: math.h ++42.0, 42.0 ++-0x1.086f771a2b37bp696, 0x1.592b453fe869fp-81 ++0x1.19eb12518e61bp-217, 0x1.c87753325f271p59 ++0x1.5c68b7b390060p-869, -0x1.0000000000000p-64 ++0x1.d96cb2cd196ebp3, 0x1.0000000000000p-64 ++-0x1.f7cb93ee0ba9bp-238, 0x1.b7f046c622df6p691 ++0x1.5cf5307b64e94p-233, 0x1.4499d7e88a731p124 ++0x1.58bc610fde155p756, -0x1.0000000000000p-64 ++0x1.11e4c61e2489ep9, 0x1.f3ddd0aadf9e9p94 ++0x1.064765103f18ap-245, 0x1.a413811779c11p89 ++-0x1.a26e540b1b5e0p77, 0x1.5987a1b0f6368p897 ++0x1.465db461ffd24p681, -0x1.0000000000000p-64 ++-0x1.b986d646b93b4p-100, -0x1.936ff2a7c8adep-420 ++0x1.af0d371d0a43dp-197, 0x1.f185f2aba0958p217 ++0x1.13ce451492820p115, -0x1.1598c3d54c625p81 ++0x1.d5ec14b6de205p-604, -0x1.0000000000000p-64 ++0x1.cf8ad6a495d19p-100, 0x1.8d2563e08105dp7 ++0x1.1a7d3100f9ef4p-636, -0x1.0000000000000p-64 ++-0x1.6dd9a7d0122f5p421, 0x1.199895f013a09p49 ++0x1.b892e5125d7d1p-345, 0x1.0000000000000p-64 ++0x1.5dfa7063ce092p996, 0x1.0000000000000p-64 ++0x1.9e7d74cdbf190p512, -0x1.3d1b5206e8127p237 ++0x1.b941e202e240dp-325, -0x1.0000000000000p-64 ++-0x1.fbe85766fae96p-463, 0x1.91c903c89b075p85 ++0x1.eab5553bcdfbap-957, 0x1.ab0a06811189cp90 ++0x1.4c2c90f483a09p917, -0x1.0000000000000p-64 ++0x1.014bc72248db8p439, -0x1.e1bef116ca6d9p112 ++-0x1.6733d0746880bp-316, 0x1.8a34e6c887c39p-107 ++-0x1.5a9b05cc4e1c4p461, -0x1.88d2560562b17p-798 ++0x1.9690663e74e47p967, -0x1.0000000000000p-64 ++-0x1.125986687c812p-159, -0x1.bd3236342d0f4p550 ++0x1.3d6422e5177bep-951, 0x1.3878a292f55d9p226 ++-0x1.9922669366d2dp590, -0x1.ae14d63976e00p-684 ++0x1.d838c66e05cc9p256, 0x1.0000000000000p-64 ++0x1.c319328022c2cp890, -0x1.4a627098d6e49p170 ++0x1.0deee25028507p461, 0x1.310f343ce0281p94 ++0x1.279923dac3d31p147, 0x1.0000000000000p-64 ++0x1.e27fe364ee0b4p963, -0x1.107d33f004629p245 ++-0x1.8160e4b7efcecp833, -0x1.9612560bf9302p-472 ++-0x1.7814633c7452bp-821, -0x1.d36af1ef2c42fp636 ++0x1.bac865bccd66ep113, -0x1.454be507db267p19 ++0x1.c75b53051ead0p-931, -0x1.0000000000000p-64 ++-0x1.cab4e5935aeaep318, -0x1.6794550b87520p-257 ++0x1.088056b5fbc0dp-459, 0x1.0000000000000p-64 ++0x1.1f8eb28937183p748, -0x1.b2a940cf17bc0p217 ++0x1.ba85352faba13p-796, -0x1.0000000000000p-64 ++0x1.1d3984c620975p460, 0x1.0000000000000p-64 ++0x1.37acd13a9ea78p1019, 0x1.0000000000000p-64 ++0x1.0e9d041b054d3p-411, 0x1.0000000000000p-64 ++0x1.a156c095ec992p102, -0x1.46f561fd1fda9p98 ++-0x1.273ca2d449455p471, -0x1.fa6c92046c475p-860 ++-0x1.7b475167ae88ep-116, -0x1.eba627003ccc5p-339 ++0x1.2996c344cf7dcp-564, 0x1.21df51e88e157p161 ++-0x1.7d29f253d3e79p636, -0x1.8e30a1ba55f7fp77 ++0x1.99ffe6fb747bep1003, -0x1.8b1047a0ed3b3p67 ++0x1.248c46b353471p251, -0x1.3aa8631084564p8 ++-0x1.500c56dfd8fa0p-869, 0x1.819212336e2afp-523 ++0x1.012185cb5e155p-672, 0x1.dcbc907d906f0p203 ++0x1.964221fe0b0c5p-260, -0x1.0000000000000p-64 ++-0x1.172f10899cbcep669, 0x1.e4e656fea6c19p663 ++0x1.e356e63b681dep989, -0x1.dd9d772868663p41 ++0x1.ccd0118265376p287, -0x1.22ae0058250b6p184 ++0x1.3de177d6762ebp742, -0x1.ebc180d571e12p58 ++0x1.04caa30a223c6p-294, 0x1.0000000000000p-64 ++-0x1.e0ffa63b800fcp-938, 0x1.0a2c229973ed9p149 ++0x1.e0ffa63b800fcp-938, 0x1.0a2c229973ed9p149 ++0x1.d43815bff9e7dp-685, 0x1.825755f8cae4bp168 ++0x1.fe3b21bec8806p456, 0x1.0000000000000p-64 ++0x1.b26d766ab1f27p-162, 0x1.184f242e49092p249 ++-0x1.1c70d750f61abp-899, 0x1.e3f3e7ec803dap759 ++0x1.220fe763e4353p897, 0x1.6a6f650adecc0p141 ++0x1.d6f7716723825p-58, 0x1.0000000000000p-64 ++0x1.2b0242282c767p308, 0x1.c9dd84f859214p104 ++0x1.7d0ee4b3bb946p-563, -0x1.9d1683c6f5c5ap226 ++-0x1.8547b5d202937p967, -0x1.14e58570b43a5p-765 ++-0x1.568636c53d51fp-638, 0x1.164257f3ab632p-455 ++0x1.6d7936f1f5553p-435, 0x1.8f26767f92ccbp147 ++0x1.7c18551f15775p147, -0x1.0000000000000p-64 ++-0x1.f2ac8209992fbp-965, 0x1.5faaf4ec0340cp-236 ++-0x1.f57620fa5afd6p-69, -0x1.096166fce916ep-683 ++-0x1.5054f3c0b1320p-215, 0x1.8c01c0a19db1bp-285 ++0x1.e41e64f79a6a9p404, 0x1.0000000000000p-64 ++0x1.71fc41e25fe85p-413, 0x1.4acb80e80f0b2p214 ++0x1.fbf477dec9138p-661, 0x1.0000000000000p-64 ++0x1.7575c7cd67604p498, 0x1.0000000000000p-64 ++-0x1.f4dd41d434b62p-205, -0x1.981f66551fd64p805 ++0x1.76ac564847250p-870, -0x1.0000000000000p-64 ++0x1.bb0e222493e31p-632, 0x1.16ad202a7c871p27 ++-0x1.079a76db55d95p-974, -0x1.19d4717967203p-409 ++0x1.68a7c79597132p-227, 0x1.6c3871ff9ad60p195 ++0x1.4961c76e0940cp271, -0x1.0000000000000p-64 ++0x1.04cf75ca8337cp-273, -0x1.0000000000000p-64 ++0x1.4fffe4a25f260p152, -0x1.a0e3a7e58a0d3p149 ++0x1.c125c40bb88b6p-281, 0x1.bedf8672d605fp215 ++0x1.bcd59440339b5p67, -0x1.d225c2cc02d3bp60 ++0x1.670e80ab2399bp-841, 0x1.887061c29e4afp131 ++0x1.7c6ef76479beep839, -0x1.0f72a2967e041p98 ++0x1.272f8550905f7p-961, 0x1.21a6d4787c14cp190 ++0x1.0a33d4e39655cp-424, 0x1.4dafa3da87794p162 ++0x1.a34e21945e568p-641, 0x1.3a0a05d61f5e4p119 ++-0x1.b57493dffe1c3p68, -0x1.8e19843fbbd1ep515 ++0x1.a8ce11ea61121p248, -0x1.7b2376aa515e8p115 ++-0x1.5feca3ddab161p-509, 0x1.3e0c341715e1cp217 ++0x1.6695a0cf6063fp-689, 0x1.1852d463ea98ep37 ++0x1.9367127039f77p-293, 0x1.adbe75323caaap47 ++0x1.6ad5c2f704166p-336, -0x1.9bf7b7271daefp100 ++0x1.6791a1f6e89bap-845, 0x1.07e4c362cf895p92 ++-0x1.20d7f6086ddb2p143, 0x1.687a7454403f4p337 ++-0x1.9bd727a165453p-810, 0x1.742fe1f2bf2dbp-551 ++0x1.40c3b16a0dba0p438, -0x1.67a872ec62dadp90 ++0x1.5e0ab0f983abfp629, -0x1.0000000000000p-64 ++0x1.c929a231173cfp844, -0x1.f25c7501c8144p116 ++-0x1.410ad6057e935p204, 0x1.bdb5a3d649e74p-928 ++0x1.9f222254cab3fp-817, -0x1.0000000000000p-64 ++0x1.7f7d22b44403fp1007, -0x1.2299d752e308dp177 ++0x1.41f824f624f36p511, -0x1.0000000000000p-64 ++0x1.9fbb158e5d5dfp-525, 0x1.f803767193e3fp31 ++-0x1.e6a1216cab6d4p-260, 0x1.100d3600b5996p935 ++-0x1.dd23855d0cc3ep1003, 0x1.3411e38397aaep-158 ++-0x1.3a9e0585f7979p-827, -0x1.db64725e35a3cp-259 ++0x1.ce93a02ba2924p866, 0x1.0000000000000p-64 ++0x1.445bf157156d4p-100, 0x1.0000000000000p-64 ++-0x1.ba1ca38fc92ebp-848, -0x1.9270247b4b009p-609 ++-0x1.5ac2b6a0c0476p-172, -0x1.595d419d9babdp-399 ++-0x1.94f2b24fd7b65p839, -0x1.a42b466df80e1p519 ++0x1.bf66704c603f1p-859, 0x1.430eb110359f6p-63 ++0x1.e9ccb07667b5fp-435, 0x1.e7cec7c8e2138p229 ++-0x1.bcd59440339b5p67, -0x1.d225c2cc02d3bp60 ++0x1.a5e7c0a9c79d2p-503, -0x1.0000000000000p-64 ++0x1.91aa125544e6ep681, -0x1.0000000000000p-64 ++0x1.5371f5af7cd6ep-628, 0x1.078a57c0c5e30p147 ++-0x1.2890a668b0252p-207, 0x1.ec956130d1ea0p411 ++0x1.70f496a3b1319p-183, 0x1.9f04e4dd9dee0p159 ++-0x1.ab4c0689a295cp375, 0x1.ec1627c9f2374p-617 ++-0x1.390d459924f44p-348, -0x1.8e36a55756005p481 ++0x1.c1b483579742ap101, 0x1.a05a357f2d54fp236 ++0x1.d0a84005691b7p763, -0x1.68f840a20c734p60 ++0x1.f32d34d1fffd4p-40, 0x1.fc09869af26f1p131 ++-0x1.e693e5dbee2e0p207, 0x1.2301f18cd9d27p817 ++0x1.1f72a3d4f7881p-764, 0x1.4617565381163p177 ++-0x1.7f69c3aee139ep-648, 0x1.1f42e1d53ae48p597 ++-0x1.adc7f1f9fdc02p38, -0x1.a07af4087ad66p1011 ++-0x1.923d01b1c3960p-276, 0x1.2c6710910e47ap889 ++0x1.6b60a2accafe3p977, -0x1.78f4404c514b7p170 ++-0x1.0a2a3540be5a3p302, 0x1.3259b15ad5075p-333 ++-0x1.11e4c61e2489ep9, 0x1.f3ddd0aadf9e9p94 ++0x1.e02943925b096p-651, 0x1.3e5010a3be270p137 ++0x1.9887e07a7b4bdp-835, -0x1.0000000000000p-64 ++0x1.fb9fd6c57d283p-969, -0x1.eb21f1c75479dp195 ++0x1.55fb70ae2db62p-910, 0x1.b77402b5190d5p10 ++-0x1.38b1775c225eep723, 0x1.7595a59a7ba8dp901 ++0x1.fbdc30f777a6ap649, -0x1.ea19f696739e0p183 ++0x1.c2b5309403401p760, -0x1.0000000000000p-64 ++-0x1.3d6de154feafep496, -0x1.9763760be8c9dp-161 ++0x1.1c0a33e2b3719p-116, -0x1.0000000000000p-64 ++0x1.06b1024b8b4bap471, -0x1.cd9f24d503076p59 ++-0x1.6d0d67d7d2ad2p627, 0x1.35c77413a4d2fp190 ++-0x1.881467b6c56d5p-194, -0x1.465995072de7cp707 ++0x1.1147d4d59a3a5p-952, -0x1.0000000000000p-64 ++-0x1.c319328022c2cp890, -0x1.4a627098d6e49p170 ++0x1.993864ddbc05dp562, 0x1.0000000000000p-64 ++0x1.f9abd78250a64p633, -0x1.f104e2772f8cep141 ++-0x1.4d87f27b51978p-916, 0x1.073e35dc85a96p-1003 ++0x1.1e8e0347dd99bp278, 0x1.0000000000000p-64 ++0x1.7fbfc71fde6edp891, -0x1.0000000000000p-64 ++-0x1.ae86836ca4d83p659, -0x1.5153616fefc6ap-61 ++0x1.0452d237e1de7p-518, 0x1.296675c74320cp87 ++0x1.12fc06ee54ac1p615, -0x1.0000000000000p-64 ++0x1.887c234a8cc63p-708, 0x1.ae5fb57f66c84p175 ++0x1.4978c021c25cbp-130, -0x1.115a65f48b23cp80 ++-0x1.a1e733c9fd87fp552, 0x1.cef7045a6012ap811 ++0x1.f98611b7c6a51p538, -0x1.0000000000000p-64 ++-0x1.858f201dffc93p26, 0x1.6a110485981d4p-285 ++0x1.84297333218cep712, 0x1.497396c926ddfp73 ++0x1.12c3e319b6a54p-783, 0x1.0000000000000p-64 ++-0x1.8ee011da43d65p-879, 0x1.7b6cf1473438ep670 ++-0x1.4978c021c25cbp-130, -0x1.115a65f48b23cp80 ++0x1.f057a19099427p-736, 0x1.0000000000000p-64 ++0x1.407a2417c0b48p413, -0x1.90cbb0161a8c6p12 ++0x1.04f492d848a39p-816, 0x1.ec7fb651e4df9p225 ++-0x1.5290f79114db5p-971, -0x1.feede687f8cf3p-101 ++0x1.fb0cc227fae39p-669, 0x1.924f06f662685p143 ++-0x1.7d10c2a023848p734, -0x1.86a912207d0c3p757 ++-0x1.5ebd0337bf9f3p945, 0x1.cb53f1b618ab5p465 ++0x1.cef8d3cce5e81p531, -0x1.0000000000000p-64 ++0x1.cdc7962fdc900p51, 0x1.0000000000000p-64 ++-0x1.04f492d848a39p-816, 0x1.ec7fb651e4df9p225 ++-0x1.23221091a234fp828, -0x1.b08e262c8eca5p972 ++0x1.bc16f113ad6ebp-101, 0x1.7c8311241b744p169 ++0x1.e1c163876ccdcp843, -0x1.0000000000000p-64 ++0x1.3daea5a429d79p-639, 0x1.0000000000000p-64 ++0x1.e99204b546e58p215, -0x1.0000000000000p-64 ++-0x1.950493326e8b2p679, 0x1.fdc874cefc875p-615 ++0x1.016dd4fb0abd2p853, -0x1.c82dd72b4ab44p102 ++0x1.d0f6737fbcdbbp-353, 0x1.081a8002b8e53p211 ++0x1.f1d1f5c67bb5ap-321, 0x1.d64ec22c49552p176 ++-0x1.8a60721e2686ap880, -0x1.936f75de69956p-750 ++0x1.8368e4ed700bbp-57, 0x1.0000000000000p-64 ++-0x1.7c5d037e915cep538, -0x1.aa30914f141e5p-886 ++-0x1.9ff485cb26fa7p227, 0x1.82c1703140ceep465 ++-0x1.bc56157fec778p-542, -0x1.898e228074677p-385 ++0x1.eb16d56eb1d78p-224, 0x1.393ef32f107adp205 ++-0x1.10bf71d60a4d1p-524, 0x1.335ac0ca90f62p1004 ++0x1.392bc7ade8723p528, -0x1.50ea12907473fp21 ++0x1.a26d44e3b408fp-896, 0x1.beda15a2a2799p129 ++0x1.6d0d67d7d2ad2p627, 0x1.35c77413a4d2fp190 ++-0x1.47a744db0c087p689, -0x1.0445309d5d5bdp-205 ++0x1.0d3c074692057p781, -0x1.885716d3dcfbap146 ++0x1.5feca3ddab161p-509, 0x1.3e0c341715e1cp217 ++0x1.001af5dcc9beep589, 0x1.0000000000000p-64 ++0x1.0b0f700297c73p388, 0x1.0000000000000p-64 ++-0x1.4591e2de659a7p796, 0x1.4ab1a273f0697p736 ++0x1.1e68964b6cc85p6, -0x1.d50762f9e9ce4p59 ++0x1.40a7f08b7509dp-373, 0x1.6784b7c373049p207 ++0x1.c43b310d38279p-924, 0x1.d4b5d23a0b96dp239 ++0x1.421436f55761ep-12, 0x1.320481b0055a7p227 ++-0x1.135fa0f337e6ep856, -0x1.ed172226e05edp335 ++-0x1.d0a84005691b7p763, -0x1.68f840a20c734p60 ++-0x1.6153c39025700p908, -0x1.87eff6801054cp257 ++0x1.ad64258a1c8aep201, -0x1.eb202553cc800p129 ++0x1.09a810c8ff945p866, -0x1.0000000000000p-64 ++0x1.d14433f742c09p-360, 0x1.f4ff819b628ddp21 ++0x1.0c04a59d1fa4fp562, 0x1.66b354392a531p134 ++-0x1.84297333218cep712, 0x1.497396c926ddfp73 ++-0x1.fb9fd6c57d283p-969, -0x1.eb21f1c75479dp195 ++0x1.dd87e7279e72bp748, -0x1.0000000000000p-64 ++0x1.e494b3d72a143p612, -0x1.3b94e6aa337a0p-57 ++0x1.4a6b277bdabe4p-613, -0x1.0000000000000p-64 ++0x1.aa78012aaa9c7p338, 0x1.0000000000000p-64 ++-0x1.ab74577adade9p149, -0x1.2057c78ee21ccp31 ++0x1.3974c5e1e2049p105, -0x1.d3dbb0fb0baf1p54 ++0x1.c83bb023360a9p879, -0x1.0c6922624c625p97 ++-0x1.e21c0605b5f2bp-634, 0x1.f28232c2ebba3p-74 ++0x1.e61ed69f4f3e5p558, -0x1.0ee6a03187e13p128 ++0x1.d32cb4d190af4p-556, -0x1.0000000000000p-64 ++0x1.97a202fe3d99bp812, -0x1.12eba5e07e17fp131 ++0x1.5cbf140578025p750, -0x1.0000000000000p-64 ++0x1.8754d2c071fd1p-796, -0x1.0000000000000p-64 ++-0x1.c24a21659e391p874, 0x1.8fca31719d26fp-203 ++0x1.db5587ed33e3dp-392, -0x1.0000000000000p-64 ++0x1.59b6e3bd2734fp959, -0x1.0000000000000p-64 ++-0x1.2f68f32a5979ep367, 0x1.d77b92aecf0f8p-414 ++0x1.73e621f69389dp222, -0x1.1235366e0a84bp216 ++0x1.076b75274a516p-7, -0x1.0000000000000p-64 ++0x1.2505e4b701385p-178, -0x1.0000000000000p-64 ++0x1.ae0c974a70a8fp607, 0x1.0000000000000p-64 ++0x1.b2c344636c704p595, -0x1.9d1b879d64e7dp213 ++-0x1.a6f695e9d29eep-629, 0x1.dad8811e62691p422 ++0x1.e5aca4566a08ap234, -0x1.645ed34f63b48p65 ++0x1.67faa10de96c9p-929, 0x1.0000000000000p-64 ++0x1.503a50f3f36c9p-313, 0x1.a1b537c589279p212 ++-0x1.e62711b5b18aap-336, 0x1.176d22b7c6703p-81 ++-0x1.78e6d2fb3c6c8p-802, -0x1.4354b70f8d56ap-407 ++-0x1.a9b890e6a309bp-974, -0x1.fc73521e05c84p446 ++0x1.605c070891e95p751, -0x1.00e8a0f55071cp255 ++-0x1.8e249352e8ed4p-690, -0x1.d751a5bb2c420p-254 ++0x1.67246027c2465p584, 0x1.3aaa16d492946p178 ++0x1.c53735a56d1edp610, -0x1.630662efaf0c6p60 ++0x1.d54a131bae182p142, -0x1.a313606a0459dp220 ++0x1.38afe5f1ed5b4p-779, 0x1.0000000000000p-64 ++0x1.f2aa76462ad42p-982, 0x1.0000000000000p-64 ++0x1.e188a166c06b6p45, 0x1.0000000000000p-64 ++0x1.fbe85766fae96p-463, 0x1.91c903c89b075p85 ++0x1.3342d36ecf081p28, -0x1.0000000000000p-64 ++0x1.c2b0a036a1828p719, 0x1.0000000000000p-64 ++0x1.ba7f308dc60ddp517, -0x1.b38d014638da6p246 ++-0x1.075aa7ba85f42p624, -0x1.a357d32f45a61p-867 ++0x1.1fbb4362bf313p995, 0x1.d039c2c0e18bfp-6 ++-0x1.150426e803137p622, -0x1.9bafe2efa3e89p39 ++-0x1.3f2456d5cba52p116, 0x1.fa9ec45f18306p-389 ++0x1.8e58945bd1087p-701, 0x1.0000000000000p-64 ++-0x1.ab0ef29932d78p111, 0x1.4313d75c1df97p658 ++0x1.ee3e13dd00d34p1016, 0x1.d6b3d3b9034c1p85 ++-0x1.7f0bd006c0d62p-324, 0x1.8210646a5ccddp871 ++-0x1.c004d2256a5b8p402, -0x1.a01df480fdcb7p98 ++-0x1.3717c2e75f865p-749, -0x1.628ab47e4b9c7p-879 ++-0x1.dfb414ca1e89fp780, -0x1.b1a6d17b59340p927 ++0x1.2bb340a5c99b8p772, -0x1.4cb4a208cd38ap49 ++0x1.983d90ffcdc95p-131, 0x1.294857e7a5d9dp66 ++0x1.0789a00a3ff0fp-950, -0x1.0000000000000p-64 ++0x1.6816c6cd93ea9p112, 0x1.985412f1ac3d6p104 ++0x1.3c0e604f8974bp-226, 0x1.0000000000000p-64 ++0x1.07acb29e12fc1p687, -0x1.edff80d6b306fp107 ++0x1.22c1d3b2c0e45p135, -0x1.9a5dc703e46dbp204 ++0x1.ede956a719d56p248, -0x1.80e8e672e144fp156 ++-0x1.ff6263662c8fbp-263, 0x1.cf3867b2bac05p652 ++0x1.f01e46c129d76p-5, 0x1.00d113cf96023p137 ++0x1.45cf928146851p636, 0x1.26b1c5666d711p131 ++-0x1.768376c2f7584p563, 0x1.017143ae97b27p545 ++-0x1.1f72a3d4f7881p-764, 0x1.4617565381163p177 ++0x1.dd9431675dbb5p-114, 0x1.0000000000000p-64 ++-0x1.64cc1762105b7p-569, -0x1.2d69b27570067p840 ++0x1.bd1077dadd530p235, 0x1.0000000000000p-64 ++0x1.0aa166c2b93bdp488, -0x1.48d03430453b8p213 ++-0x1.b513845f09747p-331, -0x1.d04e154527b26p685 ++0x1.5c97b3a12df62p696, -0x1.e160e008f7d3ap89 ++0x1.8eec91bde3d69p-376, -0x1.0000000000000p-64 ++0x1.7d29f253d3e79p636, -0x1.8e30a1ba55f7fp77 ++0x1.c004d2256a5b8p402, -0x1.a01df480fdcb7p98 ++0x1.52b9d41aaa1e9p-589, -0x1.292cb15f1459dp46 ++-0x1.ea9ca6fa0919ep-279, -0x1.601e44b6a588cp40 ++# pow slow path at 240 bits ++# Implemented in sysdeps/ieee754/dbl-64/slowpow.c ++## name: 240bits ++0x1.01fcd33493ea3p596, -0x1.724bd4e887783p-14 ++0x1.032ff59ab34fdp-540, -0x1.61e3632080b87p-24 ++0x1.045c337b80f53p304, 0x1.dc3404c30fa69p-56 ++0x1.0681338469475p-294, -0x1.3562210f27dfap-51 ++0x1.0b55c01eab2a6p-447, -0x1.cd7162fecd483p-48 ++0x1.0b74d4b709002p-811, -0x1.0af1478682e96p-50 ++0x1.0e4d10f3aabc8p664, 0x1.e2bde3471eaa1p-55 ++0x1.110607de11aa5p120, 0x1.dcec269cfd865p-47 ++0x1.132aa4cc6f38bp-751, 0x1.366ca7979d9bbp-8 ++0x1.138ae6f5a6dadp-680, 0x1.890a0755fce7ap-40 ++0x1.1b7b95bdc6400p467, 0x1.ec36f5f75ce4cp-8 ++0x1.1c20e7f14086cp-788, 0x1.f22967f8b5d7cp-48 ++0x1.278262637b59cp446, -0x1.1aab83169f61cp-10 ++0x1.2936f2eb01500p-234, -0x1.aa25c56c7a42ap-51 ++0x1.2991068d7df8dp-895, -0x1.e22e0335a6813p-19 ++0x1.2a4320a5a4e06p342, 0x1.a60de202d0f39p0 ++0x1.2baa57016f98bp445, -0x1.19b39156d7af6p-42 ++0x1.3003b731560f2p189, -0x1.d03a35d7809bbp-6 ++0x1.3098f631b79b3p322, 0x1.936cf77d12901p-58 ++0x1.329f9083895d6p-470, 0x1.c4e0407eac9e1p-60 ++0x1.32e62120a48dep-373, 0x1.8c03970ea6143p-15 ++0x1.3b69741c89827p-951, 0x1.d7e2d50ab916bp-13 ++0x1.46d346d411a30p-451, -0x1.5bed1300261dcp-37 ++0x1.48d0870fc99a7p-691, -0x1.4f6541a43b8cdp-5 ++0x1.49ae5141ea416p-825, 0x1.cfc4b51dbe592p-24 ++0x1.4d1fb5a2a4d73p738, -0x1.d2a54658b1df9p-50 ++0x1.4ddb12f9500cbp962, 0x1.48bc1158eb70ap-15 ++0x1.4f51d32b02376p758, 0x1.11d1409aaea9fp-27 ++0x1.54f723dd63e3bp605, 0x1.6c02f2514de2ap-23 ++0x1.5529070b8d631p-489, 0x1.1c3dd76010b92p-37 ++0x1.569bf17eb40dfp217, -0x1.8cb97627ae884p-31 ++0x1.5e2892c719a5ap817, 0x1.f0e3d4b66e9c0p-11 ++0x1.619a049c49284p329, -0x1.0bc7b3735d182p-12 ++0x1.62e6745b17235p344, 0x1.86dcb0cd4e584p-39 ++0x1.6532120398cb6p374, -0x1.dd57d385dde4ap-56 ++0x1.6ab9873394341p712, 0x1.6cec233df7f19p-59 ++0x1.6d7c56b0ec1f9p723, -0x1.864ae3aa72d4ap-11 ++0x1.6decf38117b3ap-629, 0x1.e1c8b1eaebfbbp-27 ++0x1.6f57771705979p518, -0x1.44fbe6fcf4182p-24 ++0x1.6f57b14f5f248p880, 0x1.e2554493e7f0cp-2 ++0x1.6fee9735004b7p-71, 0x1.8eaf1527d88bep-48 ++0x1.7190e00c6cae0p-495, 0x1.705594f79ee43p-33 ++0x1.7238a1904c29cp40, 0x1.d454673e675eep-30 ++0x1.76aa529cae2a7p-457, -0x1.0652207d202acp-45 ++0x1.78e630a117b59p-105, 0x1.ecb1a67d5b9dcp-32 ++0x1.7d0976b552b5bp-316, -0x1.9c52a2a02f146p1 ++0x1.80a10162f3c9ep-462, 0x1.af6ef1f1d004ep-54 ++0x1.8794943d6e34bp-745, -0x1.0c7df064d51e9p-10 ++0x1.8a3d749288cbcp-469, 0x1.a9bf9202d914fp-46 ++0x1.8da421e64749bp-540, -0x1.494a81df89b6bp-26 ++0x1.8e05154795810p247, 0x1.3c04802f44ddcp-47 ++0x1.91b9d616c0878p-313, 0x1.a3c9263d26b2ap-30 ++0x1.95e973a94d414p-229, 0x1.d83d8244e6566p-28 ++0x1.9a3217b4fb0e5p-990, 0x1.82853149b1e30p-42 ++0x1.9e2556775fc02p-377, -0x1.a6ec93193a127p-38 ++0x1.9e83d7b0c831fp-906, 0x1.6a3485e3e4fe8p-21 ++0x1.a51cf0f0f49f7p751, 0x1.07b941a3af664p-12 ++0x1.a883c2cef7802p-432, 0x1.b5ee3711a8260p-34 ++0x1.aca70602f90f3p205, -0x1.a40d85c2b0ddap-55 ++0x1.b118069c4e0f8p133, 0x1.85ed946b41169p0 ++0x1.b1ada0a8ca383p-699, 0x1.ddfec76f67c1fp-37 ++0x1.b236b6872f638p419, 0x1.fa8f6525758b6p-5 ++0x1.b2413258b83b1p892, -0x1.bcea65c80772bp-12 ++0x1.b51563dac9885p-571, 0x1.7a1e16e485fdcp-30 ++0x1.b5e4833e40f76p-445, 0x1.44e23325bcc3fp-22 ++0x1.b6a2168ec3212p-674, -0x1.35bda0265f18bp-30 ++0x1.b8dd676727fa1p124, 0x1.3605e6ec76006p-29 ++0x1.b95437f961192p-500, 0x1.9276767f94721p-10 ++0x1.bb6647f65218ap741, -0x1.b9dd250927a8ap-6 ++0x1.bffdf0efb5c4ep-703, 0x1.85fac77188c01p-9 ++0x1.c0345583020c9p236, 0x1.de31b044cb918p-37 ++0x1.c4b9163604b90p548, 0x1.0a51f116977d3p-17 ++0x1.c66ec323be811p-726, -0x1.8829c716f5ddbp-24 ++0x1.c69da72348031p-390, 0x1.109f77bb4a2a2p-37 ++0x1.c712558c00177p-883, -0x1.9cf047e60fa38p-8 ++0x1.c74df6d64da29p-154, -0x1.bdba55e26ef07p2 ++0x1.c75fa2c065d1dp731, 0x1.fa827749d723cp-21 ++0x1.c8f5b7f54aa5fp-998, 0x1.59fa40e2d7a95p-10 ++0x1.c957e3768f0c2p-102, 0x1.0047f59669535p-5 ++0x1.ce0615637c099p-737, 0x1.b1795333136d6p-59 ++0x1.d1a7872210098p245, -0x1.afd8c410a1918p-16 ++0x1.d39ee7b8cae5ep722, 0x1.639a1575eb95cp-56 ++0x1.d4b4276a02096p-5, -0x1.7ff8354a6ba9cp-21 ++0x1.d500d1daf1bfcp-352, 0x1.e4c7243104fa7p-34 ++0x1.d684c68e86321p-661, -0x1.11305765580a9p-13 ++0x1.db08f6fcae9f5p-637, -0x1.a8cba163bd1dep-21 ++0x1.db09e6535414dp809, -0x1.0b10e70ed8d88p-48 ++0x1.e50573d07ecc0p41, 0x1.19ec44b6d99e6p-58 ++0x1.e59505ef043e0p926, -0x1.3201c7a1e8882p-62 ++0x1.e6b9b28e678a4p546, 0x1.70e042daa89e7p-30 ++0x1.e9a4e6bbbf235p-851, -0x1.1d70f7b787412p-21 ++0x1.ea68a16e4b7c9p-733, -0x1.ee7f337779825p-34 ++0x1.f0e76025ece1cp642, -0x1.bdc0d0d7020d5p-57 ++0x1.f1bcb1d70f84bp-568, 0x1.98c5d3b11e934p-21 ++0x1.f568146a8c658p240, 0x1.4def9749a6a7ep-44 ++0x1.f75bd43867225p-454, 0x1.34b1e5cb0df40p-16 ++0x1.fae7a09d10f34p955, -0x1.f7f8439082552p-31 ++0x1.fae913d4f952ep-809, -0x1.4b649402fce63p-6 ++0x1.fe6d725408f24p484, -0x1.25f4f6441d2e4p-12 ++0x1.ff6393f9150ccp-718, 0x1.a0cb50a9bf2f3p-31 ++# pow slowest path at 768 bits ++# Implemented in sysdeps/ieee754/dbl-64/slowpow.c ++## name: 768bits ++1.0000000000000020, 1.5 ++0x1.006777b4b61dep843, -0x1.67e3145491872p-1 ++0x1.0477a5cfb1972p-402, 0x1.8742e7a1ce99dp-1 ++0x1.0827a160ab475p-239, 0x1.fcae51d2d997dp-1 ++0x1.083723672b1a4p-204, 0x1.baddc57f1404cp-2 ++0x1.0b39f4b2f5c4fp-546, 0x1.7d02a31183f36p-1 ++0x1.0e2d62ea9d078p-68, 0x1.8afb43919ece2p3 ++0x1.0fedd1fd9bdc5p-1011, 0x1.c0ce64b178832p-6 ++0x1.10b984764821ep724, -0x1.36e872083e630p-4 ++0x1.12424342d99bbp686, -0x1.f8d4e18b1b309p-5 ++0x1.1335f40a059c7p1014, -0x1.5818e19224448p-2 ++0x1.14185484cbdb2p-780, 0x1.23f8d7d596280p-4 ++0x1.14f5b49e12b8fp-751, 0x1.522c717bca3eap0 ++0x1.15fe345b21e2bp399, -0x1.0a09061cd1de9p-1 ++0x1.17c3e75436530p104, -0x1.ef30d09c541e9p0 ++0x1.1e5296bbfeea7p747, -0x1.f68df5996bfedp-1 ++0x1.1efdd081a8d35p-90, 0x1.7c7d10d98a3c9p-1 ++0x1.203101f62452ap317, -0x1.3be834bfd34fap-1 ++0x1.29cb8617add92p968, -0x1.9cbe73f892a16p-6 ++0x1.2d75353d5df74p719, -0x1.e2f317d7b2c01p-1 ++0x1.2f08247664913p592, -0x1.35ab9793384a5p-2 ++0x1.2ff58217e86d7p725, -0x1.2c98b6be067ccp-2 ++0x1.3113614c8b9e1p159, -0x1.fc2f4279c8cbep-1 ++0x1.3115402118c24p134, -0x1.d435f65f0eefcp1 ++0x1.32e5a1ba96cdap52, -0x1.f7d8248930c17p-1 ++0x1.346f712d4c234p78, -0x1.830235fa4eb2cp3 ++0x1.35ea84ad8b4fap742, -0x1.728dd1bc7d70cp-3 ++0x1.36b91497c147ep579, -0x1.b7e7b0d1ad44dp-2 ++0x1.3752c6b5da9e6p351, -0x1.2a00f003acdd1p-1 ++0x1.3bccb31761b21p-193, 0x1.bdd7b5da189c8p1 ++0x1.42c0b561c10bep-850, 0x1.dcdee5de63ebcp-3 ++0x1.4520f56ca1422p-471, 0x1.348c312c9f319p-1 ++0x1.46e7406c8e11ep546, -0x1.876f67bed28c4p0 ++0x1.4ba3f35d2f4afp-333, 0x1.6e39f0895a072p-3 ++0x1.4cb3303ab8786p-838, 0x1.fe88a032de46ap-1 ++0x1.4d61505a36a60p234, -0x1.45c3e271db1fep1 ++0x1.4fcff0e946b1ep909, -0x1.90fa07de4eea5p-1 ++0x1.5172c6b32f2aep293, -0x1.fb0fa58fc74abp-2 ++0x1.51e4b4afeb58ap-2, 0x1.f184d702a5f4bp3 ++0x1.5212b31c06068p306, -0x1.e8e5c1b09f30dp-2 ++0x1.55c7413fbdd0cp-168, 0x1.68687102fa0b8p-3 ++0x1.5975f5580b29cp361, -0x1.cda627a0b0899p-3 ++0x1.5b3d77ff20607p-694, 0x1.95877099718f5p-4 ++0x1.5b85e6f45d26fp763, -0x1.b727a35d92656p-4 ++0x1.5c83b2d038766p-984, 0x1.4232c330c81b9p-1 ++0x1.5ec6e7e275af2p773, -0x1.8da470ca7dd62p-1 ++0x1.60b0e6123149bp-743, 0x1.25a696ab5fc09p-4 ++0x1.6567f1ab52caap-769, 0x1.ff57c1e78cc81p-3 ++0x1.689cb423d7ec7p95, -0x1.71d3f5a46c36fp-2 ++0x1.69e2a022e3db6p-672, 0x1.209f77b27f146p-1 ++0x1.6a6bb05202fd0p-621, 0x1.bc1f316194126p-5 ++0x1.72b181bf25fd7p303, -0x1.629be448db4f7p1 ++0x1.7667d46544feap887, -0x1.e92ef7681c985p-3 ++0x1.776f45edc5aa6p967, -0x1.8b34366de0584p-3 ++0x1.77d4e3169e8fdp889, -0x1.7159c5a0e440ep-4 ++0x1.792c56f01b25ep-474, 0x1.45237144dc76dp-2 ++0x1.7c4d814b67ce3p-30, 0x1.32f4217aa69bfp2 ++0x1.7fec1487cd8c2p-790, 0x1.373ec1a13952fp-4 ++0x1.8280e15921e7bp-544, 0x1.17f4d1f294f23p-2 ++0x1.8be4858d98288p395, -0x1.8ecf7076c1cadp-3 ++0x1.8c1a3651b2a3cp251, -0x1.fe464693b592fp-1 ++0x1.95b8339b15437p-805, 0x1.c590d48f70e09p-4 ++0x1.9ea712eab015cp643, -0x1.9f9a2005cd04dp-2 ++0x1.9ec010ebb0fb4p966, -0x1.322de55e2f27dp-3 ++0x1.a055b4cacfb90p692, -0x1.45a6d0302680bp-4 ++0x1.a2541721f7549p508, -0x1.46b5008fed93ap0 ++0x1.aa4ea2a62e6d3p146, -0x1.4948a7f0b9447p-2 ++0x1.aeab6627bd7fep-883, 0x1.e334b6e331bcfp-4 ++0x1.afc9062dd5d6cp285, -0x1.704640b7e8a60p0 ++0x1.b2e0e5768b8a4p700, -0x1.e3cc63841415cp-1 ++0x1.b44dd7483ff8fp762, -0x1.376275f0c7542p0 ++0x1.b461c649ef81fp-297, 0x1.757d3606ad420p-2 ++0x1.b47177acf880bp162, -0x1.dbc2c7336fcdcp-3 ++0x1.b5d597a5647bep312, -0x1.0d87f0669fd98p-3 ++0x1.b5f5f6894898fp824, -0x1.aeec9752febccp-2 ++0x1.b78b84a583db6p711, -0x1.443983558960ap-1 ++0x1.ba15f474f95a7p250, -0x1.9d46c49adf4ecp1 ++0x1.ba6e74fdcaafap685, -0x1.c69a403d3e719p-3 ++0x1.c14ed18d4eb53p652, -0x1.231bb32f82a5fp-1 ++0x1.c44727ecf4620p-965, 0x1.c61391aad6567p-6 ++0x1.c492c6882ec27p-423, 0x1.6bb9123ab40fdp-1 ++0x1.c525d219db143p-681, 0x1.5e10738bb6aefp-5 ++0x1.ca9510663b619p878, -0x1.8966f1a726428p-2 ++0x1.d2d4d70d57384p-769, 0x1.eec5e348f3c65p-5 ++0x1.d3275243b3fd2p-203, 0x1.a56f87acf7afbp1 ++0x1.d5d3022665384p-509, 0x1.d4f984b477a34p-5 ++0x1.dabf72e2c886fp642, -0x1.e930d581ea0c3p-3 ++0x1.daffa04064cf7p799, -0x1.b944c271f477bp-1 ++0x1.db25c4ae37695p710, -0x1.ff84b0c08defdp-3 ++0x1.dc06652f06a70p-689, 0x1.f2eb368dd304ap-3 ++0x1.e09726def851ap-784, 0x1.8d62918b2f6a5p-5 ++0x1.e1561576de8f5p-470, 0x1.983137f5396b2p-2 ++0x1.e5e4c7891da9bp-871, 0x1.5775130263654p-5 ++0x1.eca182884f17fp-295, 0x1.af55d3375f461p-3 ++0x1.f1c172bc4f401p-360, 0x1.f40476496c282p-4 ++0x1.f244722a51df2p548, -0x1.20f7a2f2fc3e8p-2 ++0x1.f422f159f235bp126, -0x1.339620de97b69p1 ++0x1.f43463d9cef16p-845, 0x1.2c364792462fep-3 ++0x1.f8b79758182dap-884, 0x1.ed6174093fca4p-6 ++0x1.fa5c677254961p133, -0x1.c91962524971ep-1 ++0x1.ff0544adacb78p649, -0x1.6c17c3a7210e2p-1 +diff -urN glibc-2.17-c758a686/benchtests/pthread_once-inputs glibc-2.17-c758a686/benchtests/pthread_once-inputs +--- glibc-2.17-c758a686/benchtests/pthread_once-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/pthread_once-inputs 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,9 @@ ++# This tests the common-case scenario for pthread_once. ++# We have a single thread that runs a no-op initialization once and then ++# repeatedly runs checks of the initialization (i.e., an acquire load and ++# conditional jump) in a tight loop. ++# scripts/bench.py doesn't handle function pointers, so we just use void *: ++## args: pthread_once_t *:void * ++## includes: pthread.h ++## include-sources: pthread_once-source.c ++&once, once_handler +diff -urN glibc-2.17-c758a686/pthread_once-source.c glibc-2.17-c758a686/benchtests/pthread_once-source.c +--- glibc-2.17-c758a686/benchtests/pthread_once-source.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/pthread_once-source.c 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,25 @@ ++/* Measure pthread_once best-case latency (i.e., when already initialized. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++static pthread_once_t once = PTHREAD_ONCE_INIT; ++ ++static void ++once_handler (void) ++{ ++} +diff -urN glibc-2.17-c758a686/benchtests/README glibc-2.17-c758a686/benchtests/README +--- glibc-2.17-c758a686/benchtests/README 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/README 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,99 @@ ++Using the glibc microbenchmark suite ++==================================== ++ ++The glibc microbenchmark suite automatically generates code for specified ++functions, builds and calls them repeatedly for given inputs to give some ++basic performance properties of the function. ++ ++Running the benchmark: ++===================== ++ ++The benchmark needs python 2.7 or later in addition to the ++dependencies required to build the GNU C Library. One may run the ++benchmark by invoking make as follows: ++ ++ $ make bench ++ ++This runs each function for 10 seconds and appends its output to ++benchtests/bench.out. To ensure that the tests are rebuilt, one could run: ++ ++ $ make bench-clean ++ ++The duration of each test can be configured setting the BENCH_DURATION variable ++in the call to make. One should run `make bench-clean' before changing ++BENCH_DURATION. ++ ++ $ make BENCH_DURATION=1 bench ++ ++The benchmark suite does function call measurements using architecture-specific ++high precision timing instructions whenever available. When such support is ++not available, it uses clock_gettime (CLOCK_PROCESS_CPUTIME_ID). One can force ++the benchmark to use clock_gettime by invoking make as follows: ++ ++ $ make USE_CLOCK_GETTIME=1 bench ++ ++Again, one must run `make bench-clean' before changing the measurement method. ++ ++Adding a function to benchtests: ++=============================== ++ ++If the name of the function is `foo', then the following procedure should allow ++one to add `foo' to the bench tests: ++ ++- Append the function name to the bench variable in the Makefile. ++ ++- Make a file called `foo-inputs` to provide the definition and input for the ++ function. The file should have some directives telling the parser script ++ about the function and then one input per line. Directives are lines that ++ have a special meaning for the parser and they begin with two hashes '##'. ++ The following directives are recognized: ++ ++ - args: This should be assigned a colon separated list of types of the input ++ arguments. This directive may be skipped if the function does not take any ++ inputs. One may identify output arguments by nesting them in <>. The ++ generator will create variables to get outputs from the calling function. ++ - ret: This should be assigned the type that the function returns. This ++ directive may be skipped if the function does not return a value. ++ - includes: This should be assigned a comma-separated list of headers that ++ need to be included to provide declarations for the function and types it ++ may need (specifically, this includes using "#include
"). ++ - include-sources: This should be assigned a comma-separated list of source ++ files that need to be included to provide definitions of global variables ++ and functions (specifically, this includes using "#include "source"). ++ See pthread_once-inputs and pthreads_once-source.c for an example of how ++ to use this to benchmark a function that needs state across several calls. ++ - init: Name of an initializer function to call to initialize the benchtest. ++ - name: See following section for instructions on how to use this directive. ++ ++ Lines beginning with a single hash '#' are treated as comments. See ++ pow-inputs for an example of an input file. ++ ++Multiple execution units per function: ++===================================== ++ ++Some functions have distinct performance characteristics for different input ++domains and it may be necessary to measure those separately. For example, some ++math functions perform computations at different levels of precision (64-bit vs ++240-bit vs 768-bit) and mixing them does not give a very useful picture of the ++performance of these functions. One could separate inputs for these domains in ++the same file by using the `name' directive that looks something like this: ++ ++ ##name: 240bit ++ ++See the pow-inputs file for an example of what such a partitioned input file ++would look like. ++ ++Benchmark Sets: ++============== ++ ++In addition to standard benchmarking of functions, one may also generate ++custom outputs for a set of functions. This is currently used by string ++function benchmarks where the aim is to compare performance between ++implementations at various alignments and for various sizes. ++ ++To add a benchset for `foo': ++ ++- Add `foo' to the benchset variable. ++- Write your bench-foo.c that prints out the measurements to stdout. ++- On execution, a bench-foo.out is created in $(objpfx) with the contents of ++ stdout. +diff -urN glibc-2.17-c758a686/rint-inputs glibc-2.17-c758a686/benchtests/rint-inputs +--- glibc-2.17-c758a686/benchtests/rint-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/rint-inputs 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,7 @@ ++## args: double ++## ret: double ++## includes: math.h ++78.5 ++-78.5 ++4503599627370497.0 ++-4503599627370497.0 +diff -urN glibc-2.17-c758a686/benchtests/scripts/benchout.schema.json glibc-2.17-c758a686/benchtests/scripts/benchout.schema.json +--- glibc-2.17-c758a686/benchtests/scripts/benchout.schema.json 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/scripts/benchout.schema.json 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,42 @@ ++{ ++ "title": "benchmark", ++ "type": "object", ++ "properties": { ++ "timing-type": { ++ "type": "string" ++ }, ++ "functions": { ++ "title": "Associative array of functions", ++ "type": "object", ++ "patternProperties": { ++ "^[_a-zA-Z][_a-zA-Z0-9]+$": { ++ "title": "Function names", ++ "type": "object", ++ "patternProperties": { ++ "^[_a-zA-Z0-9]*$": { ++ "title": "Function variants", ++ "type": "object", ++ "properties": { ++ "duration": {"type": "number"}, ++ "iterations": {"type": "number"}, ++ "max": {"type": "number"}, ++ "min": {"type": "number"}, ++ "mean": {"type": "number"}, ++ "timings": { ++ "type": "array", ++ "items": {"type": "number"} ++ } ++ }, ++ "required": ["duration", "iterations", "max", "min", "mean"], ++ "additionalProperties": false ++ } ++ }, ++ "additionalProperties": false ++ } ++ }, ++ "minProperties": 1 ++ } ++ }, ++ "required": ["timing-type", "functions"], ++ "additionalProperties": false ++} +diff -urN glibc-2.17-c758a686/benchtests/scripts/bench.py glibc-2.17-c758a686/benchtests/scripts/bench.py +--- glibc-2.17-c758a686/benchtests/scripts/bench.py 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/scripts/bench.py 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,308 @@ ++#!/usr/bin/python ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++"""Benchmark program generator script ++ ++This script takes a function name as input and generates a program using ++an input file located in the benchtests directory. The name of the ++input file should be of the form foo-inputs where 'foo' is the name of ++the function. ++""" ++ ++from __future__ import print_function ++import sys ++import os ++import itertools ++ ++# Macro definitions for functions that take no arguments. For functions ++# that take arguments, the STRUCT_TEMPLATE, ARGS_TEMPLATE and ++# VARIANTS_TEMPLATE are used instead. ++DEFINES_TEMPLATE = ''' ++#define CALL_BENCH_FUNC(v, i) %(func)s () ++#define NUM_VARIANTS (1) ++#define NUM_SAMPLES(v) (1) ++#define VARIANT(v) FUNCNAME "()" ++''' ++ ++# Structures to store arguments for the function call. A function may ++# have its inputs partitioned to represent distinct performance ++# characteristics or distinct flavors of the function. Each such ++# variant is represented by the _VARIANT structure. The ARGS structure ++# represents a single set of arguments. ++STRUCT_TEMPLATE = ''' ++#define CALL_BENCH_FUNC(v, i) %(func)s (%(func_args)s) ++ ++struct args ++{ ++%(args)s ++ double timing; ++}; ++ ++struct _variants ++{ ++ const char *name; ++ int count; ++ struct args *in; ++}; ++''' ++ ++# The actual input arguments. ++ARGS_TEMPLATE = ''' ++struct args in%(argnum)d[%(num_args)d] = { ++%(args)s ++}; ++''' ++ ++# The actual variants, along with macros defined to access the variants. ++VARIANTS_TEMPLATE = ''' ++struct _variants variants[%(num_variants)d] = { ++%(variants)s ++}; ++ ++#define NUM_VARIANTS %(num_variants)d ++#define NUM_SAMPLES(i) (variants[i].count) ++#define VARIANT(i) (variants[i].name) ++''' ++ ++# Epilogue for the generated source file. ++EPILOGUE = ''' ++#define RESULT(__v, __i) (variants[(__v)].in[(__i)].timing) ++#define RESULT_ACCUM(r, v, i, old, new) \\ ++ ((RESULT ((v), (i))) = (RESULT ((v), (i)) * (old) + (r)) / ((new) + 1)) ++#define BENCH_FUNC(i, j) ({%(getret)s CALL_BENCH_FUNC (i, j);}) ++#define FUNCNAME "%(func)s" ++#include "bench-skeleton.c"''' ++ ++ ++def gen_source(func, directives, all_vals): ++ """Generate source for the function ++ ++ Generate the C source for the function from the values and ++ directives. ++ ++ Args: ++ func: The function name ++ directives: A dictionary of directives applicable to this function ++ all_vals: A dictionary input values ++ """ ++ # The includes go in first. ++ for header in directives['includes']: ++ print('#include <%s>' % header) ++ ++ for header in directives['include-sources']: ++ print('#include "%s"' % header) ++ ++ # Print macros. This branches out to a separate routine if ++ # the function takes arguments. ++ if not directives['args']: ++ print(DEFINES_TEMPLATE % {'func': func}) ++ outargs = [] ++ else: ++ outargs = _print_arg_data(func, directives, all_vals) ++ ++ # Print the output variable definitions if necessary. ++ for out in outargs: ++ print(out) ++ ++ # If we have a return value from the function, make sure it is ++ # assigned to prevent the compiler from optimizing out the ++ # call. ++ if directives['ret']: ++ print('static %s volatile ret;' % directives['ret']) ++ getret = 'ret = ' ++ else: ++ getret = '' ++ ++ # Test initialization. ++ if directives['init']: ++ print('#define BENCH_INIT %s' % directives['init']) ++ ++ print(EPILOGUE % {'getret': getret, 'func': func}) ++ ++ ++def _print_arg_data(func, directives, all_vals): ++ """Print argument data ++ ++ This is a helper function for gen_source that prints structure and ++ values for arguments and their variants and returns output arguments ++ if any are found. ++ ++ Args: ++ func: Function name ++ directives: A dictionary of directives applicable to this function ++ all_vals: A dictionary input values ++ ++ Returns: ++ Returns a list of definitions for function arguments that act as ++ output parameters. ++ """ ++ # First, all of the definitions. We process writing of ++ # CALL_BENCH_FUNC, struct args and also the output arguments ++ # together in a single traversal of the arguments list. ++ func_args = [] ++ arg_struct = [] ++ outargs = [] ++ ++ for arg, i in zip(directives['args'], itertools.count()): ++ if arg[0] == '<' and arg[-1] == '>': ++ pos = arg.rfind('*') ++ if pos == -1: ++ die('Output argument must be a pointer type') ++ ++ outargs.append('static %s out%d;' % (arg[1:pos], i)) ++ func_args.append(' &out%d' % i) ++ else: ++ arg_struct.append(' %s volatile arg%d;' % (arg, i)) ++ func_args.append('variants[v].in[i].arg%d' % i) ++ ++ print(STRUCT_TEMPLATE % {'args' : '\n'.join(arg_struct), 'func': func, ++ 'func_args': ', '.join(func_args)}) ++ ++ # Now print the values. ++ variants = [] ++ for (k, vals), i in zip(all_vals.items(), itertools.count()): ++ out = [' {%s, 0},' % v for v in vals] ++ ++ # Members for the variants structure list that we will ++ # print later. ++ variants.append(' {"%s", %d, in%d},' % (k, len(vals), i)) ++ print(ARGS_TEMPLATE % {'argnum': i, 'num_args': len(vals), ++ 'args': '\n'.join(out)}) ++ ++ # Print the variants and the last set of macros. ++ print(VARIANTS_TEMPLATE % {'num_variants': len(all_vals), ++ 'variants': '\n'.join(variants)}) ++ return outargs ++ ++ ++def _process_directive(d_name, d_val): ++ """Process a directive. ++ ++ Evaluate the directive name and value passed and return the ++ processed value. This is a helper function for parse_file. ++ ++ Args: ++ d_name: Name of the directive ++ d_val: The string value to process ++ ++ Returns: ++ The processed value, which may be the string as it is or an object ++ that describes the directive. ++ """ ++ # Process the directive values if necessary. name and ret don't ++ # need any processing. ++ if d_name.startswith('include'): ++ d_val = d_val.split(',') ++ elif d_name == 'args': ++ d_val = d_val.split(':') ++ ++ # Return the values. ++ return d_val ++ ++ ++def parse_file(func): ++ """Parse an input file ++ ++ Given a function name, open and parse an input file for the function ++ and get the necessary parameters for the generated code and the list ++ of inputs. ++ ++ Args: ++ func: The function name ++ ++ Returns: ++ A tuple of two elements, one a dictionary of directives and the ++ other a dictionary of all input values. ++ """ ++ all_vals = {} ++ # Valid directives. ++ directives = { ++ 'name': '', ++ 'args': [], ++ 'includes': [], ++ 'include-sources': [], ++ 'ret': '', ++ 'init': '' ++ } ++ ++ try: ++ with open('%s-inputs' % func) as f: ++ for line in f: ++ # Look for directives and parse it if found. ++ if line.startswith('##'): ++ try: ++ d_name, d_val = line[2:].split(':', 1) ++ d_name = d_name.strip() ++ d_val = d_val.strip() ++ directives[d_name] = _process_directive(d_name, d_val) ++ except (IndexError, KeyError): ++ die('Invalid directive: %s' % line[2:]) ++ ++ # Skip blank lines and comments. ++ line = line.split('#', 1)[0].rstrip() ++ if not line: ++ continue ++ ++ # Otherwise, we're an input. Add to the appropriate ++ # input set. ++ cur_name = directives['name'] ++ all_vals.setdefault(cur_name, []) ++ all_vals[cur_name].append(line) ++ except IOError as ex: ++ die("Failed to open input file (%s): %s" % (ex.filename, ex.strerror)) ++ ++ return directives, all_vals ++ ++ ++def die(msg): ++ """Exit with an error ++ ++ Prints an error message to the standard error stream and exits with ++ a non-zero status. ++ ++ Args: ++ msg: The error message to print to standard error ++ """ ++ print('%s\n' % msg, file=sys.stderr) ++ sys.exit(os.EX_DATAERR) ++ ++ ++def main(args): ++ """Main function ++ ++ Use the first command line argument as function name and parse its ++ input file to generate C source that calls the function repeatedly ++ for the input. ++ ++ Args: ++ args: The command line arguments with the program name dropped ++ ++ Returns: ++ os.EX_USAGE on error and os.EX_OK on success. ++ """ ++ if len(args) != 1: ++ print('Usage: %s ' % sys.argv[0]) ++ return os.EX_USAGE ++ ++ directives, all_vals = parse_file(args[0]) ++ gen_source(args[0], directives, all_vals) ++ return os.EX_OK ++ ++ ++if __name__ == '__main__': ++ sys.exit(main(sys.argv[1:])) +diff -urN glibc-2.17-c758a686/benchtests/scripts/validate_benchout.py glibc-2.17-c758a686/benchtests/scripts/validate_benchout.py +--- glibc-2.17-c758a686/benchtests/scripts/validate_benchout.py 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/scripts/validate_benchout.py 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,85 @@ ++#!/usr/bin/python ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++"""Benchmark output validator ++ ++Given a benchmark output file in json format and a benchmark schema file, ++validate the output against the schema. ++""" ++ ++from __future__ import print_function ++import json ++import sys ++import os ++ ++try: ++ import jsonschema ++except ImportError: ++ print('Could not find jsonschema module. Output not validated.') ++ # Return success because we don't want the bench target to fail just ++ # because the jsonschema module was not found. ++ sys.exit(os.EX_OK) ++ ++ ++def validate_bench(benchfile, schemafile): ++ """Validate benchmark file ++ ++ Validate a benchmark output file against a JSON schema. ++ ++ Args: ++ benchfile: The file name of the bench.out file. ++ schemafile: The file name of the JSON schema file to validate ++ bench.out against. ++ ++ Exceptions: ++ jsonschema.ValidationError: When bench.out is not valid ++ jsonschema.SchemaError: When the JSON schema is not valid ++ IOError: If any of the files are not found. ++ """ ++ with open(benchfile, 'r') as bfile: ++ with open(schemafile, 'r') as sfile: ++ bench = json.load(bfile) ++ schema = json.load(sfile) ++ jsonschema.validate(bench, schema) ++ ++ # If we reach here, we're all good. ++ print("Benchmark output in %s is valid." % benchfile) ++ ++ ++def main(args): ++ """Main entry point ++ ++ Args: ++ args: The command line arguments to the program ++ ++ Returns: ++ 0 on success or a non-zero failure code ++ ++ Exceptions: ++ Exceptions thrown by validate_bench ++ """ ++ if len(args) != 2: ++ print("Usage: %s " % sys.argv[0], ++ file=sys.stderr) ++ return os.EX_USAGE ++ ++ validate_bench(args[0], args[1]) ++ return os.EX_OK ++ ++ ++if __name__ == '__main__': ++ sys.exit(main(sys.argv[1:])) +diff -urN glibc-2.17-c758a686/benchtests/sincos-inputs glibc-2.17-c758a686/benchtests/sincos-inputs +--- glibc-2.17-c758a686/benchtests/sincos-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/sincos-inputs 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,27 @@ ++## includes: math.h ++## args: double:: ++0.9 ++2.3 ++3.7 ++3.9 ++4.0 ++4.7 ++5.9 ++0x1.000000cf4a2a1p0 ++0x1.0000010b239a8p0 ++0x1.00000162a932ap0 ++0x1.000002d452a11p0 ++0x1.000005bc7d86cp0 ++## name: 768bits ++0.93340582292648832662962377071381 ++2.3328432680770916363144351635128 ++3.7439477503636453548097051680088 ++3.9225160069792437411706487182528 ++4.0711651639931289992091478779912 ++4.7858438478542097982426639646292 ++5.9840767662578002727968851104379 ++0x1.000000cf4a2a2p0 ++0x1.0000010b239a9p0 ++0x1.00000162a932bp0 ++0x1.000002d452a10p0 ++0x1.000005bc7d86dp0 +diff -urN glibc-2.17-c758a686/benchtests/sinh-inputs glibc-2.17-c758a686/benchtests/sinh-inputs +--- glibc-2.17-c758a686/benchtests/sinh-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/sinh-inputs 2015-06-20 21:22:16.302457953 -0400 +@@ -0,0 +1,303 @@ ++## args: double ++## ret: double ++## includes: math.h ++0x1.bcb6129b5ff2bp8 ++-0x1.63057386325ebp9 ++0x1.62f1d7dc4e8bfp9 ++0x1.d038a32d61933p8 ++-0x1.e471c1bac1ce4p-7 ++0x1.a552c2076a2c0p4 ++0x1.ea80c14d17262p4 ++0x1.62e67590a0733p9 ++0x1.62edf5f8ef2d6p9 ++-0x1.23f9c5b9b41c5p6 ++-0x1.62fac5eb878c6p9 ++0x1.3e57e666e2e04p3 ++0x1.bab6037e306ecp4 ++0x1.aeceb373ec08dp5 ++0x1.62ff7470df95dp9 ++-0x1.6c62d6c0af55fp6 ++-0x1.633c1105ee490p9 ++-0x1.c6d344d145206p5 ++0x1.50fc32aba8311p-15 ++-0x1.62eff1edf3d60p9 ++-0x1.7019f600db82cp7 ++-0x1.ecea83f0b3977p-4 ++0x1.6302c49c75ac4p9 ++-0x1.1929f6abc031bp8 ++-0x1.c6abd4778861bp3 ++0x1.df98b1662cf01p8 ++-0x1.0a9950e69a9dep-23 ++0x1.62f873b46c417p9 ++-0x1.6300b68646dc7p9 ++-0x1.465a556d29a85p-7 ++0x1.63018139cc344p9 ++0x1.62f23680e783cp9 ++-0x1.0469009da6a29p-16 ++0x1.baaef71d93bc9p-22 ++0x1.62f446bf431b8p9 ++0x1.62ecb5c679f45p9 ++0x1.632045a8a7ef9p9 ++-0x1.66e894b6d218cp6 ++0x1.62ee439267fe4p9 ++-0x1.632432d0e9e8fp9 ++0x1.5d07807c20bb9p1 ++0x1.aa3c546601d68p6 ++-0x1.2cdd0674e4abfp7 ++0x1.62e9f2b4a0744p9 ++0x1.631844f7a96d0p9 ++-0x1.2bf936af0bb54p4 ++-0x1.848c54c9d08a5p-13 ++-0x1.a38c970185777p-6 ++0x1.b1d18499dc98dp-27 ++0x1.02c7030513fd7p-15 ++-0x1.bdcec5aecd2eep-17 ++0x1.633c66e5307e9p9 ++0x1.6061d09a4b532p-10 ++0x1.eb7555bb47463p5 ++-0x1.6327e1c51ff78p9 ++-0x1.316943f542202p-26 ++0x1.6e54069de0b49p-9 ++0x1.bd8310798ec44p-8 ++0x1.cc4af059aa66ap8 ++-0x1.9a5ff5ea279f8p6 ++-0x1.9725c1ddcc807p5 ++-0x1.6317b78869f21p9 ++0x1.9d2f87fc603f4p5 ++0x1.213554dad3888p9 ++0x1.6302b7464cd16p9 ++0x1.493644a3cb32cp9 ++0x1.62f1877c1501ep9 ++-0x1.6315b48bf51f2p9 ++0x1.633cd176d9771p9 ++0x1.6328531b0a130p9 ++0x1.6304f3ed14c82p9 ++-0x1.62e9313aabeb2p9 ++-0x1.c1b3f715f7ad9p-6 ++-0x1.c43692f7b838cp-24 ++-0x1.6323360b63d60p9 ++-0x1.562ea1c51f0f0p7 ++0x1.600ef62445c5ep4 ++-0x1.7f4191bd896cbp-2 ++-0x1.f4d3f0d1b85eep7 ++-0x1.62fc3361285d3p9 ++0x1.3395d7ec1a5dbp-18 ++-0x1.3ccc114df227ap-23 ++-0x1.5bb910de6973fp-24 ++0x1.83f8e51d82968p6 ++-0x1.a729d2ed077a7p8 ++-0x1.1b005777a51cdp7 ++-0x1.62fa736043269p9 ++0x1.97df8447ce884p-22 ++-0x1.09774517f3944p7 ++-0x1.d042739a998a6p-27 ++0x1.8a1a0335512a5p-23 ++0x1.632396c691df1p9 ++0x1.0f45b5a6c79f5p-21 ++-0x1.0d68a2dbd6a04p-2 ++-0x1.239ff60f28877p6 ++0x1.632b742e1d0c9p9 ++0x1.ee36b15df2fc4p7 ++0x1.7e02f6f960a46p-18 ++0x1.f1a48503e33b1p-22 ++-0x1.6319f733c541fp9 ++-0x1.5f2434426cd39p-16 ++0x1.630c71268199ap9 ++-0x1.4d2140c9727ddp8 ++0x1.8713c2f7dd25ap-6 ++0x1.69bb815d57e03p-22 ++-0x1.633a822e16e6fp9 ++0x1.62f667f0092adp9 ++-0x1.ba2396d33e90cp8 ++-0x1.62fdf19fea01cp9 ++0x1.8195955afb315p7 ++0x1.6337149eda940p9 ++-0x1.633754b36f51ap9 ++0x1.9356878778911p4 ++0x1.6318527f69db0p9 ++-0x1.ee0742d151b97p-18 ++-0x1.88703361b4ad5p3 ++-0x1.631675fa3bc04p9 ++-0x1.f2bd954cf1c51p-27 ++-0x1.d897a0d2877f2p3 ++-0x1.630fb3c419c60p9 ++-0x1.62e861c33ae29p9 ++-0x1.84acb4c33fff9p1 ++-0x1.378b42b89d79dp-22 ++0x1.2825d1de625c8p6 ++0x1.631f833e694f8p9 ++-0x1.36853687b4e6dp-20 ++0x1.9b9a335db58d1p-21 ++0x1.e3928304b1b20p7 ++0x1.6316835c7cf05p9 ++0x1.6303738c05d04p9 ++-0x1.3c0e136ebb1d3p8 ++0x1.96cf3250cc987p-8 ++0x1.652cb53670db0p6 ++0x1.6440639342e8ep-4 ++0x1.4512d30165887p1 ++0x1.6337b63365473p9 ++0x1.449ee05b6ff3ep-12 ++-0x1.d1ecf009b1e3ap8 ++-0x1.be8e1102ed7f3p-12 ++0x1.62fa155e6e26ep9 ++-0x1.de739010d6091p7 ++-0x1.8c1a422a7d8b8p4 ++0x1.465d81dad540ep7 ++0x1.3db012d4e554dp5 ++-0x1.5329b46ad494ep8 ++-0x1.5695b6e7fcd02p6 ++0x1.6300e31dc8554p9 ++0x1.630252d0050e1p9 ++0x1.8d80571cb3337p-11 ++-0x1.62e93642f1118p9 ++-0x1.fb2f329c0bb96p6 ++0x1.9d18d4dc71c0bp-15 ++0x1.6311f75346d75p9 ++-0x1.7498c57682670p-9 ++0x1.f690a6c3716cbp-3 ++0x1.d63fe6b5c7c89p7 ++-0x1.a2388127452f0p-19 ++0x1.0738a10cb2383p6 ++-0x1.ca36b52292e65p-3 ++0x1.62ea1202d9816p9 ++0x1.1e4701aec3142p-22 ++0x1.6322f270f7ff5p9 ++0x1.62e6b6e528603p9 ++0x1.54c5f63777d5ap0 ++-0x1.02a544984fd67p-5 ++-0x1.ab3a9254e8794p5 ++-0x1.6321d7d010e1ap9 ++0x1.6335078d8f6f1p9 ++0x1.6336a46b6c9bap9 ++-0x1.630397a6b37e0p9 ++-0x1.baead70b0c2bap4 ++0x1.988527731f959p-20 ++0x1.cfd2c4878fd4ep6 ++-0x1.ce3bf20083050p8 ++-0x1.d3e823224ebe4p8 ++0x1.31a6458858034p7 ++-0x1.62f3821bac3f3p9 ++-0x1.1043c4ca951fbp-23 ++-0x1.074b075fe582ap-6 ++0x1.62f9213f8bc1fp9 ++0x1.415f919197b6cp-26 ++0x1.d6c6f6b983d6cp7 ++-0x1.631537abd1539p9 ++0x1.631ca21fe1f5ap9 ++-0x1.b276e5fc0915ap8 ++0x1.630a6325d4276p9 ++-0x1.3c6721ec5fd14p-11 ++-0x1.6330b03f5aa48p9 ++-0x1.30b15478c1933p-5 ++-0x1.630ef52917607p9 ++0x1.d20df37103516p-21 ++-0x1.a69a66dbd2ea1p8 ++-0x1.c69e923a07adcp6 ++0x1.6a7f505fea5d9p-17 ++-0x1.ca384346f16a9p8 ++0x1.32a202fb0895dp7 ++-0x1.320c539d2690cp8 ++0x1.10c193b381a23p-10 ++-0x1.2a2bb2e417439p6 ++-0x1.d1b6a4e76701bp-10 ++0x1.ba51c02ad2c00p-8 ++0x1.4eb503a5e519cp6 ++0x1.632b31037059ap9 ++-0x1.f03c46b9d44dbp-25 ++0x1.0810152df1887p-4 ++-0x1.f6a97309476d8p6 ++-0x1.f56fa7db86bf4p5 ++0x1.df804326360d0p4 ++-0x1.141d54326d8a1p7 ++0x1.0078e7f84d8d8p6 ++0x1.cef6f7b56f8c2p-19 ++0x1.0d0ce07e697a5p-15 ++0x1.6326673bf0ee0p9 ++0x1.3c1dd34b185a1p6 ++0x1.ddc3c42ec39bap6 ++-0x1.632752aab262cp9 ++0x1.630e01d39d028p9 ++0x1.dac293f73d850p5 ++0x1.631510cd8cc49p9 ++-0x1.028ed1e8dd32dp-17 ++-0x1.b0bb57c60b6a0p5 ++-0x1.783bf33152679p-18 ++0x1.c5d5e473ebbbbp-26 ++-0x1.915ff68d55569p5 ++-0x1.633510495d169p9 ++0x1.6312d35913b55p9 ++0x1.6d20f44123714p7 ++-0x1.6303c0b5329e9p9 ++-0x1.62faa7a46d17bp9 ++-0x1.633196bcef4aap9 ++0x1.6329f34ef70a1p9 ++0x1.3877f0875dea2p5 ++-0x1.413e167d515b4p-8 ++0x1.f017e3196ac82p3 ++0x1.230e2092aaa0ep5 ++-0x1.7b67d6318a255p7 ++0x1.04c9f0425e693p2 ++-0x1.1ebe27d65ffa7p6 ++-0x1.62f596dff99e7p9 ++-0x1.496ec324e967fp5 ++0x1.2f75110873a31p8 ++0x1.62ec21c319df7p9 ++-0x1.487513da26b06p5 ++0x1.6329675608d9fp9 ++-0x1.1de0320fc0737p9 ++0x1.73d4f770b54e0p5 ++0x1.62ef2138efd07p9 ++-0x1.7cd5764bf11ffp7 ++0x1.402ca060e1497p8 ++0x1.632cc11415f53p9 ++-0x1.631ec3cf4a7b9p9 ++-0x1.278e06c2c4ea4p-17 ++-0x1.62f55568a253dp9 ++0x1.6310e758dfd28p9 ++-0x1.3d480025e3245p7 ++-0x1.4517c5d83e40fp-1 ++0x1.6307c4b105e8bp9 ++0x1.630181fc28954p9 ++-0x1.8d2e660962aa3p-9 ++-0x1.98df07527c0bbp8 ++-0x1.a27ee2e3a28adp-10 ++0x1.6387b36f3b875p8 ++-0x1.05cbb323669c8p7 ++-0x1.52594428d68c5p1 ++-0x1.4c9235b765b89p-18 ++0x1.632a66cd5c94bp9 ++-0x1.62fbd7e6a4400p9 ++-0x1.728176d7c18f0p-24 ++0x1.62e6378477ec7p9 ++-0x1.632b611f08364p9 ++-0x1.25a7b6bd7d0d0p-3 ++0x1.00efd61470d55p-10 ++-0x1.6336976d5e8adp9 ++-0x1.359ca2cc9fc70p-12 ++0x1.5e2af7dfe1034p9 ++0x1.62fb546601bb5p9 ++-0x1.630544284f262p9 ++0x1.0b72226f94781p3 ++-0x1.1fb7b0f3e9cecp-22 ++0x1.c7b7361a9d625p5 ++0x1.dde5178b689c3p5 ++-0x1.13d52288f4693p-15 ++0x1.1868b4ff4df0bp-22 ++-0x1.a9369360a2239p-18 ++0x1.d35412055367bp7 ++-0x1.35d973c1b14fbp1 ++-0x1.6316075c46ee9p9 ++0x1.7c96f7ff40e1ep-25 ++0x1.2b2582d457cd0p6 ++-0x1.a28481bf5abc7p6 ++0x1.467a936424936p8 ++0x1.a1ca4036cbf56p-4 ++-0x1.34b9e14e1af56p5 ++0x1.00e73296682cap7 ++-0x1.01f6e4bd76df4p-13 ++-0x1.d84f005ebcd13p-7 ++-0x1.632dc46b7230cp9 ++-0x1.724f81862e781p-25 ++0x1.62f6f6ca932f5p9 ++-0x1.b07147eb43dd0p4 +diff -urN glibc-2.17-c758a686/benchtests/sin-inputs glibc-2.17-c758a686/benchtests/sin-inputs +--- glibc-2.17-c758a686/benchtests/sin-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/sin-inputs 2015-06-20 21:22:16.303457923 -0400 +@@ -0,0 +1,2913 @@ ++## includes: math.h ++## args: double ++## ret: double ++0x1.4e31719759424p353 ++-0x1.202ae0c324949p20 ++-0x1.0f8c771855528p-8 ++-0x1.339f22dc85e76p22 ++-0x1.904e251c945aap343 ++0x1.e13c5531993aep-2 ++0x1.5b05529d780f3p-24 ++0x1.41e8f0676cd4ep8 ++0x1.411e056bd6bcap-2 ++-0x1.0ca910674bec9p11 ++0x1.0c7df3a6a06b7p0 ++0x1.ef4075c4a3c3bp-11 ++0x1.52224219293bbp791 ++0x1.c227d66030144p3 ++0x1.b2a5d2451fcc7p0 ++-0x1.56a2c78366fcfp19 ++0x1.0e02525c58105p26 ++-0x1.e39c357c7c18bp404 ++-0x1.a4b3865993274p15 ++0x1.871d4238016f0p1 ++0x1.9c0ff32380748p-12 ++0x1.89db74b290234p-4 ++-0x1.46c0d53d48490p40 ++0x1.d2b7221564888p739 ++0x1.1ed4f44792d40p30 ++-0x1.f4cff05c7df9fp24 ++-0x1.130783c5347b2p19 ++0x1.f439e3a751c06p0 ++-0x1.630814d89b60ep23 ++0x1.e641156ac4981p28 ++0x1.b09f366ca1e8dp-1 ++-0x1.5e9a670db3d03p33 ++-0x1.130fb139e93b7p546 ++0x1.138355fdffae2p36 ++-0x1.20908459428fep42 ++0x1.8a1293891effap-2 ++0x1.d3fd23a93e82cp0 ++0x1.9c95c4a9d8f7fp848 ++-0x1.23c7340f1b756p-8 ++-0x1.aa82b642da2d7p304 ++0x1.1d4f233dfb177p26 ++-0x1.b55807b7ef532p-2 ++-0x1.971032fa3d5e8p21 ++0x1.d4e9e5d2cb6eap29 ++0x1.bc051494f7144p23 ++-0x1.661bf799c255fp201 ++0x1.052840edc4f07p24 ++0x1.0551d741e16d9p10 ++-0x1.3c365242efbadp690 ++-0x1.a1bcf06ea66e7p244 ++-0x1.4b20e44b06e11p14 ++0x1.3e5112fb02b33p45 ++-0x1.89cb01f331009p18 ++-0x1.de6db48d64d8ap-1 ++-0x1.d0bce02378eb6p24 ++0x1.3a9b24b4ad685p32 ++-0x1.e0c1554a97eabp136 ++0x1.398670a088410p23 ++0x1.7c2150ddf2a1bp-1 ++0x1.2153d792ddc8bp599 ++-0x1.ed7986b460920p34 ++0x1.6de72477b695fp789 ++0x1.0a1a8631872ccp1 ++-0x1.df4c22cbd016fp14 ++0x1.1b96201522f46p28 ++-0x1.8c8ea54e4ea92p13 ++-0x1.e36b62515b546p725 ++-0x1.62b4633089889p965 ++0x1.e1dcf4a52ec6ap23 ++0x1.3d7fb4750aed3p34 ++-0x1.ede78680f7292p40 ++0x1.96c0917ba637bp959 ++-0x1.e051760806b8bp-2 ++-0x1.e86f230e487d2p-16 ++-0x1.1d3397349ac97p8 ++-0x1.ddf236157546cp743 ++-0x1.70c031efdc4f9p415 ++0x1.233ff3c09d84ap9 ++0x1.3edab4c5f3a26p0 ++0x1.6c93b47873059p436 ++-0x1.3237841f0b0bep237 ++-0x1.8760d1293a1f3p-13 ++-0x1.a18c37bc89a24p1 ++-0x1.3f2766f7d26b6p542 ++-0x1.bec6222bee7a6p-1 ++0x1.f26ce5fd59845p456 ++0x1.5b32c136e1f9dp18 ++-0x1.b7ed411870c8fp6 ++-0x1.72aa75c106ffap42 ++0x1.db2c644144982p915 ++0x1.1415b4c83775bp24 ++-0x1.25a7566e7f67cp10 ++-0x1.9facd2a3d5418p18 ++0x1.78e1e40bdde9cp47 ++-0x1.5c33011915d84p0 ++0x1.ff6852a9c8d2cp22 ++-0x1.cc23573b9a1c2p37 ++-0x1.824f12c733c82p-2 ++-0x1.3cab932de7796p37 ++-0x1.1c4df62e7d177p1 ++0x1.c1b95025989fcp14 ++0x1.832e22eeb5989p-5 ++0x1.452f327db73f8p10 ++-0x1.290d05147591cp1002 ++-0x1.beaa851f05e92p-1 ++0x1.ad58373023277p513 ++0x1.f93821eb50de3p42 ++0x1.1bda02f0f3f9fp1 ++-0x1.38d441441abf9p33 ++-0x1.624000e54a29cp631 ++-0x1.d98c1179cdcb5p22 ++-0x1.c44511ec2f8b4p28 ++-0x1.30ef1448b9e93p-2 ++-0x1.c308f108883c4p333 ++0x1.12e7d2402f07ep7 ++-0x1.e74a96ae3bb5fp132 ++0x1.c31f54a536722p4 ++-0x1.56e14428bc436p-6 ++0x1.edb3a48cb14d9p-1 ++-0x1.f027b77ce5bddp14 ++-0x1.0c53346de6015p40 ++0x1.b19cf55c66693p14 ++-0x1.a19e001e2c6a1p16 ++-0x1.0e2865378e3aep3 ++-0x1.f65794e9df99fp47 ++0x1.e1ee854626d4ep536 ++-0x1.940bd6337c84cp-13 ++-0x1.2cbf8175aa84ap17 ++-0x1.961bc1591e602p3 ++-0x1.87b2b0601d2fap1 ++-0x1.772c74a581f96p751 ++-0x1.59e08127aee39p23 ++0x1.a527c23e0a4e1p0 ++0x1.eb60950795a35p-2 ++-0x1.1e46f002c96a2p-2 ++-0x1.9acc80758e051p8 ++0x1.a45c62bacde78p29 ++-0x1.5d26d76eeb16fp39 ++0x1.326df3a5344d2p18 ++0x1.adc29195a1e2dp15 ++0x1.ff9265140dcf4p89 ++0x1.76b20648c5b8dp19 ++0x1.5ca4265555944p-1 ++-0x1.9cc0e0deeb24bp2 ++-0x1.325eb43fe815fp-11 ++0x1.36bcc00217c62p393 ++0x1.b78b3134ed03ap8 ++-0x1.889c50b50e994p355 ++-0x1.03938396f299ep13 ++0x1.8f76b03720eeep25 ++-0x1.2ff306722b5a0p-20 ++-0x1.9166f7eede8c9p753 ++-0x1.ac96117a61cb3p35 ++-0x1.cf3642f86351ep5 ++-0x1.65ef55c9472d7p28 ++-0x1.d7e391105fa79p978 ++0x1.1c6cd319235fap46 ++-0x1.aa7970ac6beb8p40 ++-0x1.cff1e6c12b98dp27 ++-0x1.d0e054e560649p39 ++0x1.fe0175557d0dap-2 ++0x1.862a0150c14c8p24 ++0x1.ab0df0da7ef0dp0 ++0x1.452292fcc9743p-2 ++0x1.b525530505534p991 ++0x1.80e514cb850ebp14 ++0x1.e83385b509520p673 ++0x1.f73857e61fd2ep36 ++-0x1.c140a422bbc7ap10 ++0x1.6a3836b018674p666 ++0x1.420174d78cfd8p11 ++0x1.34bb45e923e9dp1 ++0x1.b90f228298b54p25 ++-0x1.399605f4445a3p203 ++0x1.c95d15ef0ce1ep-1 ++0x1.6ed1160abd68ep8 ++-0x1.40bbe306fa9b5p46 ++0x1.da8267a8f6494p46 ++0x1.6407626ac4921p3 ++0x1.5635a0a1b6c48p0 ++0x1.a2e9e58ba39c0p31 ++0x1.d4e0d618fbcfap697 ++0x1.973f27485658dp166 ++0x1.d17c3143c6d80p529 ++0x1.d936e70a9f908p16 ++-0x1.0a8ba2bc9bb3ap107 ++0x1.17e910c087095p26 ++0x1.4e23340e98273p991 ++-0x1.5f6a72e7950c9p-1 ++0x1.d29737bd89976p187 ++0x1.a7db27e5bb0fbp33 ++-0x1.dbcf01f3ac92fp19 ++-0x1.40aa778cc7865p-2 ++0x1.f16163407b344p-1 ++-0x1.32b196585adb2p26 ++-0x1.c83eb643cf122p165 ++0x1.291fa0c5f8d40p-4 ++-0x1.7ab62403e1a78p680 ++0x1.68f2830723d8dp-2 ++-0x1.54cf77dd7d83fp11 ++0x1.aee6014383723p16 ++-0x1.39ced0bf900c2p-2 ++-0x1.e3ce76406226fp-25 ++-0x1.7e5623b6bd702p20 ++0x1.478a64a7d9020p369 ++0x1.8888438f4aa60p495 ++0x1.804b902d0663ep-6 ++0x1.74c501d7381dcp0 ++0x1.65c56626b3f5dp20 ++0x1.7ca955c1db56bp-2 ++-0x1.3257f754500c2p6 ++0x1.93b0e2b87951bp807 ++0x1.78c226a06ff9dp881 ++-0x1.2a61e2ec72661p26 ++0x1.515561fe9c724p109 ++0x1.f04611a3f263cp-5 ++0x1.ef0196a9c0554p25 ++0x1.58bb53a309d66p147 ++-0x1.b67d94ed2b039p22 ++-0x1.a08f75ea1519bp-24 ++-0x1.9b14260bb0430p855 ++0x1.018fe4f13cc1ep563 ++-0x1.42f125d031ba6p663 ++0x1.7cdb837d7a326p8 ++-0x1.885d54001463ap0 ++0x1.e315d2bcdedaap0 ++0x1.cbd6f6692bc81p-3 ++0x1.f5be652eb0059p4 ++0x1.260be58c40562p84 ++-0x1.0fe3d67fb0d33p0 ++-0x1.a665d08300b9bp21 ++-0x1.879cf57ffe1b5p18 ++-0x1.8896d5a45e3d5p-2 ++0x1.182964987bd99p15 ++0x1.ae4ed76c12ddcp-1 ++-0x1.2b387213c40c0p10 ++-0x1.190326f5c5c9bp506 ++0x1.fc8ab2a922d40p56 ++0x1.84ba0399b0479p34 ++0x1.196320ea67543p801 ++0x1.c6f8306ba2e53p541 ++0x1.f79d44a0719afp7 ++0x1.8ca3c3000d226p7 ++-0x1.c434b33e05c76p-5 ++0x1.868d10df4adcbp-2 ++0x1.d365237c3ee46p-1 ++-0x1.2f53a0332a1b2p949 ++0x1.23fb93f05a5acp40 ++0x1.7170c1501bd5ap-26 ++0x1.bbb7d3ba1b005p650 ++0x1.41c1575e5df36p6 ++0x1.46d3f4d9169a3p39 ++0x1.c9fa657c758adp16 ++-0x1.c463d1e0760e3p5 ++0x1.0ef4e317bbeb3p45 ++-0x1.6b8f175a47735p1022 ++-0x1.9cbcb495f934fp0 ++0x1.b035202e76644p429 ++0x1.dfea1413ef865p-1 ++0x1.c30c667184d73p4 ++-0x1.6e4350ad76c38p6 ++0x1.11023720f1a27p-17 ++0x1.7d39738644047p5 ++0x1.08e8904336050p26 ++-0x1.a0f4632092bf4p31 ++-0x1.31db61e58f2c6p327 ++-0x1.216362a55985cp21 ++0x1.59afd473ae079p620 ++0x1.a67b229194875p0 ++-0x1.102f35c99abdcp408 ++0x1.7c8930f344010p8 ++-0x1.236814c694776p26 ++-0x1.69695069a7660p-2 ++-0x1.4833d2eb288d6p23 ++-0x1.6253b6dbdbdf0p-2 ++-0x1.cebd11d7b8c60p23 ++-0x1.6e47719d8cbdap23 ++-0x1.bc0e60a3d372cp-24 ++-0x1.aea4a37abf07bp-2 ++0x1.a424422079a3cp0 ++0x1.5f4ad2d1ae141p0 ++0x1.9d1c7329661c5p4 ++0x1.c95da42d6a20ap5 ++-0x1.637d860a40277p911 ++-0x1.777bf17319cfep11 ++-0x1.b8f294e0feb0bp5 ++0x1.f8dab5af1a40fp44 ++-0x1.4e822143a7e22p-6 ++-0x1.30f1a29272a12p0 ++0x1.ec9c45a34f565p548 ++0x1.5b2031d5f55c2p9 ++-0x1.596311decda04p24 ++-0x1.88dea317671eep84 ++0x1.1672932dd9083p-1 ++-0x1.dceba122a6c97p3 ++0x1.2a5880f1f8375p15 ++0x1.db8507740bf47p19 ++0x1.51a6f417b2d0bp-25 ++0x1.17296500d6e03p26 ++-0x1.05a473760addep-1 ++-0x1.95e0b2c256513p20 ++-0x1.150cf2ae9f714p19 ++0x1.f69660154e06fp0 ++-0x1.9aab65d69ac86p25 ++0x1.097f676316fabp8 ++0x1.e60dc42ce17c8p356 ++-0x1.6f236799d0618p18 ++-0x1.ddef96de04f2fp-3 ++-0x1.4f76b349a0943p-25 ++0x1.e41e1113025c6p779 ++0x1.026094b0f4060p17 ++0x1.69b29144b9540p-1 ++-0x1.b55194638c050p34 ++-0x1.b78f56c9abb41p38 ++0x1.eda3e2bbf366bp4 ++-0x1.dd66f0d648089p-2 ++0x1.f70f54c519e03p5 ++0x1.b2ed91264f4b0p736 ++-0x1.7e89b7cbfeef2p790 ++0x1.9ebdd376c6af6p669 ++-0x1.31bcf466a0f71p38 ++-0x1.db600765a5820p880 ++0x1.83720115e49bap19 ++-0x1.72f7158f3031dp485 ++0x1.b493a52c77e8ap262 ++-0x1.61b575ab7671cp-1 ++-0x1.d872154df6929p25 ++-0x1.966b0439fdb8ap949 ++-0x1.48ec6657af67cp-2 ++0x1.b79c505f0f0cap0 ++0x1.8cb2918d277b2p556 ++-0x1.57d9c07b3aff9p-1 ++-0x1.928615736e2c3p0 ++-0x1.89a736dbeb43ep273 ++0x1.78484185770a7p-1 ++-0x1.9716820109e97p82 ++0x1.e772957d51225p36 ++0x1.082be0a48a4ddp23 ++-0x1.fcb8f111481cbp-2 ++0x1.9221f605bd679p8 ++-0x1.4901b4e9ae99fp19 ++-0x1.107b70bf37787p19 ++0x1.116bf43b5a0c9p-1 ++-0x1.aaf0763749048p25 ++0x1.9958546576d59p2 ++0x1.7f1374d7f65b5p13 ++0x1.2b12a66cfcbfcp24 ++-0x1.032e0018d5e31p93 ++-0x1.b47f10ba68386p-22 ++-0x1.3d2b81e149a51p-1 ++-0x1.421ff5c85a241p24 ++0x1.e600548bb210dp-18 ++-0x1.678015108956ep-1 ++-0x1.e02ab7babc6e4p21 ++0x1.209470304e32ap9 ++-0x1.e80132771d75dp0 ++-0x1.a3344487bd369p27 ++0x1.e1eb2267b7fdcp496 ++-0x1.7721478b2d466p14 ++-0x1.9f701607ace6bp32 ++-0x1.3b5b74d34ada7p-12 ++0x1.2477a5441ffd0p9 ++0x1.d66a76c489eb1p3 ++-0x1.5bed268942217p0 ++0x1.2f7b251d454efp3 ++0x1.7e30f5f452228p10 ++0x1.eb98508ea666dp-10 ++0x1.2fcfe5c7591f1p0 ++-0x1.a0ac164173a04p17 ++-0x1.468a06a5522b9p21 ++-0x1.5824c7106d618p16 ++0x1.eb81c45f51ccdp40 ++-0x1.a3e486adaff0ep479 ++0x1.1974e0f299718p592 ++-0x1.e5a1e74789b73p45 ++-0x1.619690cc59a49p807 ++-0x1.aebff5a970e6cp15 ++-0x1.bfffc1c94a5fcp203 ++0x1.c6ca100bb7092p674 ++0x1.b95db5be3c216p-9 ++0x1.1f43a01f3499cp875 ++-0x1.de5737f187a25p6 ++-0x1.b0bb15e917960p24 ++0x1.26c0670524e93p17 ++-0x1.809321a40d4a8p-1 ++0x1.9dcd443d72518p484 ++0x1.6dbde56f8d28fp28 ++0x1.0842a4feb907ap1011 ++0x1.e22643ea2d366p840 ++-0x1.5a6d36e2f784fp0 ++0x1.941a537fbac6bp-19 ++0x1.735171a8af18ep390 ++-0x1.6c21854e6ac4ep-2 ++-0x1.4966b64a86f86p13 ++-0x1.9151a1dcc653ap-2 ++0x1.d39194332f055p-2 ++0x1.3441f2d9046a4p45 ++-0x1.63827188db8d2p27 ++0x1.6638414088a1ep-1 ++-0x1.a6bfc2a427d20p12 ++-0x1.a69f971d4e130p25 ++-0x1.d3300078065d9p46 ++0x1.4f37818518d61p356 ++-0x1.ad6bd45d98764p32 ++-0x1.2fbf90a8a2c99p877 ++-0x1.ff71d39bd81cap22 ++0x1.5fdec455fd1a8p20 ++-0x1.226887072ca0ap377 ++0x1.f72e43d6cf555p951 ++0x1.dc26c361d9df5p2 ++-0x1.0294c7e317c97p24 ++-0x1.7ed5874833105p-1 ++0x1.719536cabadbep803 ++-0x1.ec79d4096ea8fp27 ++0x1.eec6d47320e53p261 ++0x1.a1f7f00ab9ef0p19 ++-0x1.131f85094d6b2p-3 ++-0x1.62fd06cec62e9p920 ++0x1.3ac61495513e6p-10 ++0x1.38a2e3a18c65dp-1 ++0x1.4a7fb2f2fb6e3p-7 ++-0x1.2d23b2b1b0716p467 ++0x1.654b17175f19dp-17 ++-0x1.9e9791bea55b9p12 ++-0x1.1ba351d709f03p-20 ++-0x1.17cf2637f69aep956 ++0x1.e97fa01af0da4p12 ++-0x1.2fc4818397878p805 ++-0x1.cde053fdf18dep33 ++0x1.1e57e7c749fb6p907 ++-0x1.b6423794860bcp-2 ++-0x1.5f6ab21f70061p39 ++-0x1.a8d663f09366ap694 ++-0x1.ec4db28b5e248p-2 ++0x1.56f98549fccb5p7 ++0x1.94cd10662c26cp21 ++0x1.22fce3cdc1d23p258 ++-0x1.c59f864bc9d01p336 ++-0x1.265292b9f7156p26 ++-0x1.f079443577dbbp24 ++-0x1.361ac7035cb65p1 ++-0x1.e74096e5beb90p12 ++-0x1.7230603fa3279p47 ++-0x1.e9cbe08e63864p0 ++-0x1.6ebb6528c0777p27 ++0x1.5c5af7dbb0328p928 ++0x1.fa7c83278e735p19 ++0x1.331b21b0a2c88p2 ++0x1.f56ef59955713p32 ++-0x1.248d826402212p822 ++-0x1.2a96722b314a5p11 ++0x1.ce7975ddf3677p-19 ++-0x1.954ab0cb2f1dfp0 ++-0x1.ee8861dc9cd21p1 ++0x1.b8c9d509b7774p0 ++-0x1.accac3020df12p24 ++-0x1.c0b1048baa584p13 ++-0x1.247b04589de3bp32 ++0x1.7908215d3793ap-22 ++-0x1.8a0a5596f99e3p283 ++-0x1.30e8b0467a611p-14 ++0x1.7688417c5e950p25 ++0x1.071177de1d758p-1 ++-0x1.55a7203e5bb54p-11 ++-0x1.4beda7f02fc58p0 ++-0x1.8e6c752f1efcfp30 ++-0x1.c96c975bef932p31 ++-0x1.8123d67897403p24 ++-0x1.bd6ae1f640868p426 ++0x1.9fecb3cbf41c7p490 ++-0x1.a15bc3ae996e6p8 ++-0x1.05b3619b69842p14 ++-0x1.0442141ed67adp13 ++-0x1.e57d71c2d90aap6 ++-0x1.509d16f50ec01p544 ++-0x1.9010e6a39e0aep831 ++-0x1.e7b93430ad1d5p1 ++-0x1.5f96469e388c6p418 ++-0x1.2d5ed5dc35c75p134 ++0x1.85cd87f4cc346p-2 ++0x1.8b37f442cf6e9p0 ++0x1.9b1ae7a4ae625p0 ++-0x1.53c115a7be97bp38 ++-0x1.ff32d7edcd704p-14 ++-0x1.953fa5f60bd50p8 ++-0x1.f45e927d7ec3fp-1 ++-0x1.45de4402c93edp-1 ++-0x1.8fab8457e4c73p2 ++-0x1.e062920d6e2b6p-2 ++0x1.d85f469b95361p577 ++-0x1.98b8e736546f7p21 ++0x1.baf561d55a741p17 ++0x1.a72bd7daabe8bp105 ++-0x1.1ef7f1c2e5c9bp-18 ++0x1.0435b73182174p18 ++0x1.561e661a58867p-13 ++-0x1.2f150336c7ec0p3 ++0x1.ac91a59fb0bcap3 ++-0x1.078942a38f20cp1 ++-0x1.718d90b3efe95p-1 ++0x1.8dba84562c1a1p-25 ++0x1.9f94a2a92cc63p25 ++0x1.529ab6f344416p15 ++0x1.a005943ddb8eep0 ++0x1.ac93d3c825de4p19 ++-0x1.1140b5380990ep-2 ++-0x1.8ef2408d49792p9 ++-0x1.ca5042b95a883p11 ++0x1.7c287447df731p599 ++-0x1.e15023bd4744cp210 ++0x1.657882484d13fp23 ++0x1.e88f328b258fdp23 ++0x1.855dc0e37b99ap395 ++0x1.598187ea5ae51p33 ++-0x1.637ae365b4384p-1 ++-0x1.1923e00bf8e04p1 ++-0x1.5f4ed07d8a997p16 ++0x1.268767573e897p22 ++0x1.ad3f47ad94f57p227 ++-0x1.05cc81c2d4884p25 ++0x1.bc8e47678920ap0 ++-0x1.f772a716fb113p-22 ++0x1.bcdc73da531a3p-7 ++-0x1.b526f046be5e2p-2 ++-0x1.f888c3eda4f44p92 ++0x1.6f90f7637cce6p924 ++0x1.6ae52307d05c4p18 ++-0x1.40ea87b7fb3a9p2 ++0x1.270c426bb2c09p38 ++0x1.d82674e4cec0cp874 ++0x1.2dc86702ce991p122 ++0x1.e15520525a088p19 ++-0x1.ea28530234be7p17 ++0x1.9ba9b4938d1fep8 ++-0x1.8dcf703e176e2p12 ++-0x1.cc265742b5c6ep0 ++0x1.0065329f84432p554 ++-0x1.161137df0d91bp1 ++0x1.8fb0027634696p0 ++0x1.b9fa22d8a4cfep0 ++-0x1.667ba642c426bp628 ++0x1.6ea694c30205bp27 ++0x1.49f3651093200p822 ++-0x1.79f5a0df3fcebp667 ++-0x1.b53dd3f934f2ep427 ++-0x1.0565b1cf6e355p20 ++-0x1.7ef691c9c2091p-1 ++0x1.2f6062f73a03ap-2 ++0x1.d4f4c36b692b3p3 ++-0x1.945c555415314p3 ++-0x1.e1efa2575c11bp284 ++0x1.daa7f3648ccb3p680 ++-0x1.5ad77206e5e6ap-2 ++0x1.c79a40f6473f6p29 ++0x1.48fcb0b8cc309p73 ++-0x1.c0cb8090ed1dbp-8 ++-0x1.9411631355aa0p2 ++-0x1.4a1e129f65869p234 ++-0x1.7619e7382b57bp-7 ++-0x1.80f5c7807337ep5 ++0x1.e30ba2147b72ap23 ++0x1.faaab405c970ap10 ++-0x1.8db3b01985f05p-17 ++0x1.b155055e2c9bcp-12 ++0x1.7b1531e9dea19p16 ++-0x1.3f4041f462a08p35 ++-0x1.809d32d7edc1cp18 ++-0x1.261472134e23bp-6 ++0x1.9a6785f0bd19bp406 ++0x1.8227140a3e10dp491 ++-0x1.ef5aa000c8afbp845 ++0x1.41c582661c062p2 ++0x1.67fca3ca351fdp-2 ++-0x1.eb4e319782bc5p0 ++0x1.2f2de7f12ed11p0 ++0x1.f5a6b78c7b2e5p4 ++-0x1.1297c67142642p1007 ++-0x1.e1f4a032a77f6p0 ++-0x1.088754e6657a4p1 ++-0x1.75e1d72e80fbap30 ++0x1.78b350a1f00e8p22 ++0x1.271167a076a83p44 ++0x1.e70f437159d71p-2 ++0x1.87e957b57fa84p75 ++-0x1.677a102f413c2p0 ++0x1.8fc497cbb0095p-20 ++-0x1.d25da5b15d323p-1 ++0x1.76e7f1f9d8687p72 ++-0x1.36d924ab23541p25 ++0x1.b6964733ca4b5p1003 ++-0x1.fb16015e8942bp-1 ++-0x1.70a972441252ap981 ++0x1.7e76507a8675bp-17 ++-0x1.1cd0058f54456p122 ++-0x1.c0fb733c7fc31p-3 ++0x1.9eeeb2ae4b3ebp710 ++-0x1.adb9d02c6d361p1 ++-0x1.8043944ab395cp-2 ++-0x1.3929134a7aa22p6 ++-0x1.afef537037707p22 ++0x1.f95dd74ff9bd0p265 ++-0x1.46ee17ceaa71fp-1 ++-0x1.7f6ea716e7feep317 ++-0x1.1e22240f16846p-1 ++-0x1.20a474cb7609fp24 ++0x1.70e043acc61e5p16 ++-0x1.7eefa2d58eb0ep337 ++-0x1.5f0916075f895p25 ++0x1.587ca1f01e2f3p4 ++0x1.ec1f57978ca5fp-3 ++0x1.03b1a7547b5f9p313 ++0x1.b92e15306ee93p-1 ++-0x1.b52f21e5fe14bp-17 ++0x1.0e10b6ab5a214p-8 ++0x1.8c4b96284f26ap24 ++0x1.5f0360b127d60p-1 ++-0x1.9b60e1c781a78p501 ++0x1.20dad3315b635p586 ++0x1.34af961f320dep220 ++-0x1.300e85c202993p41 ++-0x1.4d8eb16113ddap-6 ++-0x1.73d644b4030d5p0 ++-0x1.368a658fa09f8p2 ++0x1.0c89d6b268d24p20 ++0x1.bb1a765ce28fdp47 ++0x1.8f4006e283f2fp13 ++0x1.92eb72301aaadp-20 ++0x1.d3c0d2e0def1cp14 ++-0x1.5bb3b4c71a538p268 ++-0x1.64f9c74e4f02cp409 ++0x1.092eb44978cc3p1 ++-0x1.871aa3260142cp12 ++0x1.b2231204c9adcp14 ++0x1.169a93b39b7c8p-2 ++-0x1.aea221c5784dep439 ++-0x1.bc398053cf866p725 ++0x1.5c55063fa98a0p26 ++-0x1.6d60d14fab3ffp19 ++-0x1.61a907b23322ep26 ++-0x1.3e2aa7e0685c7p28 ++0x1.1870b10038923p-1 ++0x1.3a52b1e143ab8p28 ++0x1.7bb547d4e8b19p18 ++-0x1.1f24978e6140fp507 ++-0x1.a95f874fe9ca8p42 ++0x1.65ecb6f9f87dap0 ++-0x1.71a20409c9197p0 ++0x1.385a123a7bc69p-22 ++-0x1.2f9e350b93eefp0 ++-0x1.1485e2b270712p19 ++0x1.3ac6f562d19b3p-2 ++0x1.6476142969e6cp325 ++-0x1.56463176cb1a3p283 ++0x1.20e5f768ccce0p0 ++0x1.319f01a378b2cp2 ++-0x1.8969458ad3464p-2 ++0x1.b1f7254761461p-2 ++-0x1.6cf2f4320d01fp0 ++-0x1.7906d597ec6d3p806 ++0x1.4efb250a0b393p-20 ++-0x1.6c12c573e5d7dp5 ++0x1.daafd30c1507cp24 ++0x1.9d6185d00050ep996 ++0x1.934ac1f1b9ed3p231 ++-0x1.1a45e56568952p-2 ++0x1.65bfa7b4278fcp16 ++-0x1.1aace0acffbdbp1 ++-0x1.68d463926e0dep-1 ++0x1.b1dab378ca1c2p25 ++-0x1.506cf2a809fddp704 ++0x1.358a15ae4294dp-13 ++-0x1.42c3c05c5826ap390 ++0x1.2fcbf708a00e3p3 ++-0x1.3677e200ab18ap-15 ++0x1.2873c5d55c2cfp-22 ++-0x1.2724526c9752dp-21 ++0x1.8d9b06275b83dp12 ++-0x1.b12f058122586p181 ++0x1.527573274a8d4p8 ++0x1.195f40a45ebb6p0 ++0x1.27e087658825dp-1 ++-0x1.2fa5c194bf350p8 ++0x1.aee9b799e7960p9 ++0x1.e7068384c91e9p19 ++-0x1.9c15b7bbbe8efp786 ++0x1.5e87f540349a7p36 ++0x1.4c6543847dd73p496 ++0x1.c589e3ee9a17ap33 ++0x1.c807c6669378cp-1 ++0x1.3adbb27f40e7ep0 ++0x1.5b0442a02b1cfp23 ++-0x1.4603d2868b08bp-2 ++-0x1.28a4e5eda874ep277 ++-0x1.a25a728b6e591p147 ++-0x1.12e453911f316p808 ++-0x1.e2b24769906d4p32 ++0x1.f884d2ae76492p-1 ++0x1.fda586dbd3223p18 ++-0x1.3f09d311f4081p893 ++0x1.289fb3f9141abp16 ++-0x1.41f333066913dp19 ++0x1.dee9e7bf987c9p976 ++-0x1.32a5b4fa2e6b2p0 ++-0x1.e20aa461c2157p34 ++-0x1.4a66f2ea0a5c0p45 ++-0x1.5ff44343e926dp0 ++-0x1.c88e22ba7c82cp0 ++-0x1.4026b50f54360p0 ++-0x1.7afb6345c0c15p24 ++-0x1.c17db7ae50ae9p8 ++-0x1.120ae360cb67dp11 ++-0x1.4cb780f424d93p13 ++-0x1.27eb05143f027p25 ++-0x1.20c813e3aed73p709 ++-0x1.86d2e433d192fp889 ++0x1.0961e47b86039p0 ++-0x1.8abfe08bbc72cp599 ++-0x1.d6de9255f915fp0 ++0x1.37c9063f4c54fp34 ++0x1.ef29e5cc63bd3p8 ++0x1.b0e307f445021p34 ++-0x1.2dd254b5abc94p5 ++0x1.774825660c90bp-8 ++-0x1.059295ecd45d1p0 ++0x1.4fedc45fad571p26 ++0x1.f40711380db13p7 ++-0x1.b95cb138eca91p35 ++-0x1.51ef12b10b034p-2 ++0x1.ed7034a4ba5fdp26 ++0x1.3407c59c49bd0p0 ++0x1.103160b4631c0p21 ++0x1.e19f639692ac0p261 ++-0x1.9fae70cb2d56cp31 ++0x1.38ee669963b88p21 ++0x1.99cb42f6c9388p355 ++-0x1.bcda7573c7ce4p927 ++-0x1.6291301099b9bp30 ++-0x1.d782c2e2c92bbp15 ++-0x1.784e8037661c5p19 ++0x1.36744643c4a42p36 ++0x1.c381c73ba6b44p5 ++-0x1.8e6584afbb6bap29 ++0x1.60ef319355c1dp478 ++0x1.754fa41b33911p888 ++-0x1.dc27a33bf6306p-18 ++0x1.b33d46d5e22fdp18 ++0x1.2bc62656f694ap827 ++0x1.3d75b544d079fp-2 ++0x1.e054c651bc3dep960 ++0x1.1a72c20a37235p14 ++0x1.aed6f37f159a8p4 ++-0x1.01992507d64dcp11 ++0x1.3b56f71608c5ep0 ++-0x1.d7e042bfb55fcp16 ++-0x1.eb3e0216540efp894 ++-0x1.4fd1c1f7dd5c2p46 ++0x1.02f127955effep0 ++0x1.cdbb710ee6b4bp40 ++0x1.090911a7b9637p-2 ++0x1.d74c64e6dda8dp29 ++-0x1.98a6009907880p158 ++0x1.a5cc91ee0faa7p41 ++0x1.943d06841a6c8p34 ++0x1.8ac7d5e70a232p-2 ++0x1.ba2c04cc3ef8dp3 ++-0x1.b58f95aa564d9p0 ++-0x1.973e5700e6b4bp20 ++0x1.b7a3524725846p0 ++-0x1.128721b885a46p17 ++0x1.bc6b54987973cp19 ++0x1.b4ad251ee68e4p-2 ++-0x1.50fc219493101p842 ++0x1.d58ae142787d9p-1 ++0x1.316d83c961b95p4 ++0x1.34d343338acc5p9 ++-0x1.8045f5444a6b6p24 ++-0x1.839b72308621ep1 ++-0x1.0e7452e31d1a4p17 ++-0x1.24c7e44469182p1 ++0x1.da29e623ef67ep-2 ++-0x1.0dbce3889c2c5p800 ++0x1.3bcca50129997p-2 ++-0x1.6b0ab247362d3p806 ++-0x1.600922864a5cbp12 ++0x1.0389370f595d0p-17 ++0x1.7ccf72e3efcffp23 ++-0x1.cb8b1074ff472p-2 ++0x1.b7a66671d9bc0p557 ++-0x1.c55a54873485dp5 ++-0x1.ed643182b4f8fp-1 ++0x1.3d6fb3a57bc7ap-2 ++-0x1.20776336f7781p1 ++0x1.42b72105c6ed8p612 ++0x1.06a4d6dd3a5c4p-2 ++0x1.830a33db5faf6p0 ++-0x1.bec3309e61a85p25 ++-0x1.cdd4202956c13p9 ++-0x1.456894b0fe5e2p-9 ++-0x1.5e75c7bfd1c26p13 ++0x1.2511840847d4ap1 ++-0x1.311d36a26ce96p25 ++0x1.7b3583c108d12p368 ++0x1.2b3ea65fb3fb0p3 ++0x1.9d531434f54aap1 ++0x1.b097301ac5504p16 ++0x1.8c8b55474e5dbp0 ++-0x1.1e79f18b6a2e0p44 ++0x1.ff9ad1733ab79p-2 ++0x1.475ca4f6bbc44p937 ++-0x1.bf0114ace534bp177 ++-0x1.b91072375d8a4p-2 ++0x1.84fcc3902af81p971 ++-0x1.81eec4a99819fp18 ++-0x1.18a9e42a54f34p0 ++-0x1.4019e136b83dcp-2 ++-0x1.78f283c624525p-2 ++0x1.2701b12d4f844p22 ++0x1.36fc85bbb6070p401 ++0x1.6b35225fd0908p94 ++0x1.e6e2131951debp279 ++-0x1.b82af00e76418p14 ++0x1.be658653e6766p256 ++-0x1.385b70831cafap29 ++0x1.d3f5c24cbc413p-2 ++0x1.f93972d50cfb3p-1 ++0x1.3b7813b2681acp0 ++-0x1.7f27f0e41cc47p24 ++-0x1.eb9b45f3358c3p9 ++-0x1.236842aae5290p1 ++-0x1.69135229dc5c9p4 ++-0x1.a81f93c59e748p11 ++0x1.21ed75692e14fp32 ++0x1.7ce2f7e7f462dp30 ++0x1.f9bfe445d11b5p2 ++-0x1.80d5201176135p10 ++-0x1.6502724d070d2p26 ++-0x1.756325ea0de70p357 ++-0x1.14982063b0f3bp18 ++-0x1.b62bd1473f7b4p683 ++-0x1.cbc8c7e76a18dp22 ++0x1.01ff77285718bp-1 ++0x1.149063aaa5e7fp26 ++0x1.36a8923cacda4p25 ++-0x1.3db72554025e2p10 ++-0x1.445e35540ca90p493 ++0x1.51bf04c8ae132p-25 ++0x1.6f5394c33dd94p5 ++-0x1.1ff746f462c25p-21 ++-0x1.109b702903094p10 ++-0x1.d5c5e7e8246e0p2 ++-0x1.52b9318533d0ep8 ++-0x1.73c380e23710fp11 ++0x1.63a440fa11bbbp230 ++-0x1.5d2961e3f707ap704 ++0x1.8b42849cca6abp1 ++0x1.8bc2e1537e745p10 ++-0x1.406c125032124p701 ++0x1.50850019bb449p-7 ++0x1.7df5d165411e6p-21 ++-0x1.c089e1db09fa1p24 ++0x1.fd15959b89b57p18 ++0x1.722ac54ce4ca6p28 ++0x1.9ed9928e455fep-9 ++-0x1.58698376f1cc9p4 ++-0x1.0cf1601dabfd0p-13 ++-0x1.23afd7ed7fb9dp-1 ++0x1.be965057282e2p112 ++-0x1.696652132ab94p18 ++0x1.77458321cdbd7p549 ++-0x1.417ae73977eeep-22 ++0x1.85abf3e024aacp-12 ++-0x1.b9cc71340e0abp-1 ++-0x1.2f5e246efd99ap1 ++0x1.700f73433df7ep-1 ++0x1.6016960e7dd29p205 ++0x1.fb0380828c4cbp39 ++-0x1.630bb6882ef0cp8 ++0x1.f6646483933acp-1 ++-0x1.aa81e7a2dc38fp614 ++-0x1.0a2d10e978ec2p154 ++-0x1.7df4b33b5344fp5 ++0x1.d702811d5c6abp984 ++-0x1.ec22926e5a82ep-21 ++0x1.34039400fe24cp11 ++-0x1.bd6547ae731d4p0 ++-0x1.ab8f03598b253p-1 ++-0x1.2c2aa517d17b7p152 ++0x1.d5afc263e2f26p7 ++0x1.2f1b33b063f94p0 ++-0x1.45a626aafd49ap45 ++-0x1.a819d0880c43ap8 ++-0x1.6fd166b7cf8a9p28 ++0x1.8f14c6d951680p-2 ++-0x1.f95a164067f69p-6 ++0x1.89b4a08a38cb0p14 ++0x1.a4b996c33a6bdp37 ++0x1.4aeb0322ec440p-1 ++-0x1.a420305ddf0dep20 ++0x1.5b68332d5fe77p189 ++-0x1.6929678422be5p19 ++0x1.dd2126a36ab02p10 ++0x1.98f53759e6cc2p776 ++0x1.c327955ab4d9cp600 ++0x1.c152d36d52060p-1 ++0x1.794e9268cf1f9p-3 ++0x1.0fd9b34cf9e14p0 ++-0x1.f1c2c3f721d38p24 ++-0x1.c2f18449c0b1cp-13 ++0x1.1f6f72691226fp26 ++-0x1.9eba60739e9fdp22 ++0x1.55e6b0539f3bap982 ++-0x1.deaf371270943p6 ++-0x1.9d3ae228b1311p12 ++-0x1.fecfd748896e1p0 ++0x1.fd5a059f9c172p-2 ++0x1.c7a7c29f81427p24 ++0x1.36ca81fa9a1adp684 ++0x1.8c3ff49ca4904p12 ++0x1.1d0d849df4253p1 ++0x1.f52c4094b100fp36 ++0x1.3349a0a047c9ap24 ++0x1.397f1147f1b4ap-7 ++-0x1.c7ea6242b1fa7p12 ++-0x1.01f5933842764p38 ++0x1.81c1a5562ef0dp29 ++-0x1.71a012ad6b2dap-2 ++0x1.4e0114b92be2dp846 ++-0x1.ea54b35d3f7e3p11 ++-0x1.8758771ca14b1p580 ++-0x1.a17a467fd6aadp8 ++0x1.f18514b3d4bc4p0 ++-0x1.acfaf20b2d004p15 ++0x1.5985717523c39p8 ++-0x1.8c04a7df8a0dfp-1 ++-0x1.2f9d510841af2p-1 ++0x1.153361ad245bep11 ++-0x1.85103699de39cp16 ++0x1.2df047f79c291p201 ++-0x1.489e6110776d9p0 ++-0x1.6b8242e1f61e9p-1 ++-0x1.9bb0554427766p995 ++-0x1.5661e39faa45ap14 ++-0x1.6c4da055e41c0p24 ++-0x1.d4e2a3a4090cdp175 ++-0x1.e5e790e8baa1bp-14 ++-0x1.129e75c7aff37p6 ++0x1.5375038c8dd70p27 ++-0x1.c04a313036171p992 ++-0x1.e12566734cc7bp976 ++-0x1.ed8b413aed34dp716 ++0x1.a3e0646c6265dp738 ++0x1.74a4333e87a2bp9 ++0x1.5d02455d1bb3dp15 ++0x1.712c9673a7d13p-26 ++0x1.4840b2e17f6edp1006 ++0x1.2053e5b7f6eedp26 ++-0x1.b5a30398cb230p-14 ++0x1.fe83c131a134dp0 ++-0x1.63f1305740debp8 ++0x1.ff796761e132ep34 ++-0x1.7d193269b00f9p22 ++0x1.94e78186aeac5p25 ++-0x1.278cb595be809p-2 ++0x1.d4ccc2ff780b8p42 ++-0x1.ef8b614873906p0 ++0x1.c8b7f506376c4p33 ++-0x1.97b4b07142435p-2 ++0x1.1efd54bfbe9fbp100 ++0x1.1560d1a87593fp27 ++0x1.5e8c0545cfcf4p26 ++0x1.9c69e6fd6459ep637 ++-0x1.4b25e05d58b46p863 ++-0x1.81ec10a304cf8p774 ++-0x1.1f9604ed5dc18p-1 ++0x1.becfd05c673b6p20 ++0x1.bde267b487883p183 ++-0x1.d917f2a793ddbp5 ++0x1.e85f16573a72dp919 ++-0x1.0cc5657e9b661p1 ++-0x1.446982673e881p9 ++0x1.e84e42461caddp326 ++-0x1.a479565cee358p-2 ++-0x1.2e7db1f9f89dap3 ++-0x1.6807f62188ee4p19 ++-0x1.f9a73671b8d07p1 ++0x1.1beef08374679p0 ++0x1.1dafc2f5778abp25 ++0x1.9250a762e1ba1p20 ++0x1.f9812520917ecp12 ++-0x1.0da0d4531229dp416 ++-0x1.72ff65f41d183p-2 ++-0x1.164d766bf45fep19 ++-0x1.3c7a02cb96b62p-1 ++0x1.3fd9603c15434p-1 ++0x1.6ed333c5adb05p-15 ++-0x1.b35ad0e907efcp23 ++0x1.ee8f5619a8d0cp-1 ++0x1.4523c70e30a5ep45 ++0x1.74f607e52d238p-1 ++-0x1.0fc6108958cecp1 ++0x1.9ccf57ca88ef6p621 ++-0x1.0809650c00191p20 ++0x1.ccf645ad30624p-2 ++0x1.40a22315ce02ap10 ++-0x1.4b4f6440c04d3p0 ++0x1.e846d4c3490f2p593 ++0x1.f92f20b5d8cafp-7 ++0x1.b90bb5fd78cd4p786 ++0x1.16afb2cf4deb8p538 ++-0x1.1aa4248addfffp5 ++-0x1.587286bdceb7cp1 ++-0x1.2ce667139fd6ep26 ++0x1.2fe84506f5385p963 ++0x1.3acb00c272448p-16 ++0x1.e0a3c2d64fee3p719 ++-0x1.b487d227fdec7p-2 ++0x1.faa152bb52391p18 ++-0x1.e79f5357231aep15 ++0x1.c65bb6c53d3dap-23 ++-0x1.ddfa475af1db1p674 ++0x1.d15766ea575b6p754 ++0x1.cc77931bf80adp1 ++-0x1.39d87172d2d3ap955 ++0x1.eee6f4a4110bdp829 ++0x1.a81e612359044p-12 ++-0x1.2876e2ba2738cp-2 ++-0x1.281e96b11431ap20 ++0x1.1679654620215p634 ++-0x1.c19584949678cp0 ++0x1.b8da124791494p-2 ++-0x1.e18f25739b74dp607 ++-0x1.4b5b316466f4ep-1 ++-0x1.c3f2d4a621a5fp12 ++0x1.7ca620f840a2cp828 ++-0x1.e2a1c45179529p-6 ++0x1.03b8346424511p-2 ++0x1.b135621e69725p551 ++0x1.28f6635324af0p1 ++0x1.ce24171b296d6p23 ++0x1.7fca444e86945p24 ++-0x1.de18458a2ee35p699 ++-0x1.10aaf42a372b8p-10 ++0x1.3175567afe205p25 ++0x1.b3ea9658f5c1ep-2 ++0x1.5cdfe0c3508c0p27 ++0x1.718706e31a168p-12 ++0x1.4b2475de57328p581 ++0x1.7e06534da3912p26 ++-0x1.bc4683ab53857p24 ++-0x1.dcbd172495052p-11 ++0x1.953bb577e3442p8 ++0x1.c704b77880f42p960 ++-0x1.e1cdd796bd369p25 ++0x1.c6f0846cfe9e4p-2 ++-0x1.6a35f6969e604p22 ++-0x1.648dc686aa66dp-1 ++-0x1.7362b1dd212ddp198 ++0x1.7311f4cc57a57p-2 ++0x1.437536a391f64p-16 ++0x1.989c90dd19204p34 ++-0x1.8382a5f03a8c2p-10 ++0x1.ef9bf32947b5ap8 ++0x1.4e8642971464ep9 ++-0x1.873e050c19a35p403 ++0x1.3b96e14be3ce6p9 ++-0x1.acdfb08fca270p9 ++0x1.a48c61da23d9ep255 ++-0x1.f23d367e7d312p-1 ++0x1.8657c785cda01p21 ++0x1.b834d785cb551p0 ++0x1.2e9e363624743p-1 ++0x1.d6bc40afd2e5cp1 ++-0x1.b28dd3c03580bp25 ++0x1.464f2654be753p15 ++0x1.0e66174c1a5b8p57 ++0x1.9513603120188p-11 ++0x1.d8f947940be48p462 ++0x1.f555e2ba605b4p15 ++-0x1.39e4b7d1c13c1p2 ++0x1.77b477c4ce082p450 ++0x1.db29e26cbb155p12 ++-0x1.09437624580b4p1 ++-0x1.54e64408c718dp-8 ++0x1.bc6023572bcc5p24 ++-0x1.b434a601701d7p601 ++-0x1.f4b1d689b2dd0p11 ++-0x1.0169d2091a98fp-2 ++0x1.3f8ff3fa74d41p-5 ++-0x1.8c80c2779ce0cp2 ++0x1.868886f5a1110p10 ++0x1.9c4df0b876ebfp-25 ++-0x1.71f585d4559b8p0 ++0x1.8de525de7f0b7p2 ++0x1.4176a6a108549p39 ++-0x1.5f815601d20b9p-2 ++-0x1.a38f23bfc9035p19 ++0x1.c5d840b1da838p-1 ++-0x1.34bd228405e26p24 ++0x1.57512021aabcap26 ++-0x1.bca9f6e287c33p-14 ++0x1.5ac0c1a2f4fafp24 ++-0x1.994ab36e7d723p2 ++-0x1.328d45a5fc470p341 ++-0x1.64af70ee7def2p-4 ++0x1.ee1db2f62022fp0 ++0x1.5f2dd10e6a6ecp-20 ++-0x1.838631f252728p42 ++-0x1.19cf34161b21dp11 ++0x1.9f91840121c5ap-22 ++0x1.9dbe335793b39p41 ++-0x1.839fc42eeae8cp103 ++0x1.eef9e6c8ffb8ap6 ++0x1.8541c004e3180p22 ++-0x1.8c1920d4c1503p85 ++0x1.b218a059a4570p-2 ++-0x1.a58d75620b198p667 ++-0x1.6efd621a14b0cp17 ++-0x1.099e53d938376p14 ++-0x1.18d6e5d70b10fp-1 ++-0x1.5788e732cd976p11 ++0x1.07ef71676445cp34 ++-0x1.ca4487363d2c1p27 ++0x1.dc926279d77cep263 ++0x1.8753049e6d5e1p-24 ++0x1.65f042ee1fc9dp47 ++0x1.bc3453e531abap-1 ++0x1.bcc4873bb393bp6 ++0x1.116535b98ffadp42 ++0x1.de18a3376458ep8 ++0x1.db06306746181p13 ++0x1.84c37202fcf43p1 ++0x1.866395219626bp18 ++-0x1.141071db29322p257 ++-0x1.73ef56ec1f623p950 ++0x1.e4d520d681029p25 ++-0x1.9eeee3bb51702p1 ++0x1.f0d4059310340p11 ++0x1.5183a5f0807cap12 ++0x1.1bfe251a8c4a8p21 ++-0x1.1a87e14b480c2p0 ++-0x1.7edd86bc0ed71p628 ++-0x1.ab66712e5be65p12 ++-0x1.5780654d83cf9p20 ++0x1.0e08e43c171b7p-23 ++-0x1.88da66ec65c0dp324 ++0x1.5c5926ec4f1a2p-2 ++0x1.decdf19a88501p4 ++-0x1.5bb127177c60fp935 ++0x1.7744646704854p0 ++-0x1.cddb237f3dfcdp672 ++-0x1.8c87310c7aa0ep16 ++0x1.1a8aa57389535p-1 ++-0x1.b27e20d250282p26 ++-0x1.facbf497fa225p576 ++0x1.fac832440d064p-1 ++-0x1.228927aeb745fp-2 ++0x1.3cd4a0cdd1361p47 ++-0x1.85c831564ddeap1 ++-0x1.83f066bfc1359p14 ++-0x1.b753f35ab1670p14 ++-0x1.76e0b3655bb28p30 ++0x1.4ef00786f3c9fp27 ++0x1.2621a3ae6c888p2 ++0x1.f0f6471c67c9bp-2 ++-0x1.ad9653d2d06aep-2 ++-0x1.f6717146079e5p22 ++-0x1.27ea06c37db0dp982 ++0x1.567a43608f4dcp8 ++0x1.c2aec319a9eb1p3 ++-0x1.0c9f22529d27dp-3 ++0x1.f675c28973d34p6 ++-0x1.b1ba46b0c8b89p-9 ++-0x1.348066bcb437ap-1 ++-0x1.c1e203c94dc06p19 ++-0x1.bd2d4187954e7p30 ++-0x1.85eb466fe1e41p-13 ++-0x1.2ce2532f3a652p11 ++0x1.ee2be60192dfep-2 ++0x1.7c77736361d2ep619 ++-0x1.9bb2716c8b4e1p21 ++0x1.458cc63edc9ebp16 ++0x1.427fa56cf1226p791 ++-0x1.cd4a90f4529cfp0 ++0x1.5a66116e3a525p585 ++-0x1.a44717a44cee8p9 ++-0x1.89c766e207c5bp47 ++0x1.8497829793fafp-2 ++-0x1.b169742951e02p18 ++-0x1.6f4840b361b11p-23 ++-0x1.caa2b00a5545ap22 ++0x1.158d27d29b47cp25 ++-0x1.c113704bba518p0 ++0x1.ad9bf10cb5ff8p14 ++-0x1.4e0a32305965bp-2 ++0x1.067fe63e938a4p-23 ++0x1.b96914a1b3a21p438 ++0x1.63dfb19a046cep34 ++0x1.db0804f3c7c9ep0 ++-0x1.8410d2e1034b3p0 ++-0x1.d1aaf2398a33dp-2 ++-0x1.bbb454f7f7f07p24 ++-0x1.c9acc42e8d061p19 ++0x1.203d60670cd9fp-8 ++-0x1.767535411c076p-1 ++0x1.60cc4040d39f1p422 ++-0x1.d10600cb8001bp29 ++0x1.b8e581930f94dp-1 ++-0x1.355566120a0b9p1 ++0x1.45b580cae60afp18 ++0x1.d911332e98370p0 ++-0x1.91177292f4cabp8 ++-0x1.418ad2d34bae0p-10 ++0x1.8291b4650a69ep-1 ++-0x1.79d9f4f590c73p24 ++0x1.a6c83045cbf27p20 ++0x1.671f710ecd668p1008 ++0x1.318ea4b002d99p-10 ++0x1.a7b8b355e681ap46 ++-0x1.8f1101e38969cp61 ++0x1.be31961f3aa50p160 ++0x1.0836b413055ffp647 ++-0x1.95d046a1ab722p919 ++0x1.fc127769b2558p421 ++-0x1.fa2d535dfb0ffp0 ++-0x1.19df965ee45d7p653 ++0x1.c409446d99c17p615 ++0x1.259ea3875295cp42 ++0x1.1d90964dac75cp23 ++0x1.2019d5248771cp42 ++-0x1.328307633514ap1 ++0x1.a28317d7099c2p23 ++0x1.ac9cd6e82d051p19 ++-0x1.32f0c45d72d8dp0 ++0x1.76fa3642a2e9ap2 ++-0x1.f5cac7ebb5a18p7 ++0x1.76df575b7cff4p12 ++-0x1.714c26d8c8d24p-26 ++0x1.14a3e3533f825p2 ++-0x1.aca7465e17036p-1 ++-0x1.6ea6365296b7fp37 ++0x1.903ff0fd1d1d1p816 ++-0x1.0acae1b832bffp618 ++0x1.0b9fb4c808dd7p15 ++-0x1.fc968462e80a1p42 ++0x1.971fe623dd7bbp-12 ++0x1.b2c787b5a85fbp10 ++0x1.6af4437902edap-26 ++0x1.eafdf13258e48p22 ++0x1.40dcf08370d64p-16 ++0x1.3c49f4603b25ep158 ++0x1.7d156688d9d5ep203 ++0x1.ea6ec75e3a3f8p14 ++-0x1.39770057684f9p335 ++-0x1.203f737ae7869p-12 ++0x1.820394211c83fp551 ++0x1.2a2466c9759cfp21 ++0x1.d7edd63490c31p-1 ++0x1.da78c7461ca5cp20 ++-0x1.5eada05f63f1ap12 ++0x1.4d0466560feb1p23 ++0x1.f840d32accedbp576 ++0x1.f017d5329baeep34 ++-0x1.28f2e2a8c25a1p6 ++-0x1.3b6705c364a3bp-12 ++-0x1.dce5f1df42de0p0 ++0x1.0d48966683a4ep1 ++-0x1.1c63a7cadb22ap-22 ++-0x1.16ba8367f31fdp156 ++-0x1.8b3e13c7f3a03p21 ++0x1.97fcd0035fe76p23 ++0x1.bec9562483afbp1 ++-0x1.88e6d0eac076bp3 ++0x1.5b15217b8879ep10 ++0x1.aedeb39054577p271 ++0x1.3fb5b2335be6dp-15 ++-0x1.c331a14d8c473p-5 ++-0x1.bfc2a2cb84079p17 ++0x1.3c11d271df1bap24 ++-0x1.13ea25a9e3f6bp108 ++0x1.2e2b40a38617ap-1 ++-0x1.f528b5d80128cp-21 ++0x1.6aadf20c0b366p542 ++-0x1.f50a1346f56cep306 ++0x1.2d5b105aa946fp0 ++0x1.f5a63052565cdp15 ++-0x1.cdc68541a84efp8 ++0x1.bd32141c6c295p25 ++-0x1.4ddb2056462ccp24 ++0x1.7830865a59204p23 ++0x1.468106f7529f8p5 ++-0x1.025cc0f22a1fbp37 ++-0x1.c00d57ad60ac5p0 ++-0x1.2a4135493a5ccp35 ++-0x1.2afa33c25a200p603 ++0x1.74f407f05f616p8 ++0x1.5b8937978050fp21 ++0x1.7a5db0fda57f4p16 ++0x1.4695f2bc976e0p0 ++0x1.f481e2cf35d18p-2 ++0x1.c262e34521fb6p-1 ++0x1.2cbc860c13474p17 ++0x1.64d371b08759ep15 ++0x1.da18e713e4cb9p-5 ++0x1.abc9a6f91a6d6p-8 ++0x1.2df6d29bbc5b5p1012 ++0x1.aa2cb76cdfa0bp0 ++-0x1.5fe9976d6cd0bp12 ++0x1.85f14525bfb00p-1 ++0x1.49b43399b1c42p106 ++-0x1.9cd354c208505p-15 ++-0x1.9d4235a514407p2 ++0x1.ee0a16b3daac7p17 ++0x1.fcc165f31733fp0 ++0x1.e5e150a67c9f2p-4 ++-0x1.75a4c2ba36cecp26 ++0x1.e94cf46939e6cp755 ++-0x1.0b7b352b6c592p-1 ++0x1.d4f714edbb965p21 ++-0x1.e1e8645c60564p747 ++0x1.0a3fd37d282e1p-1 ++0x1.9621f5e7054c9p-2 ++-0x1.c1a72478daa53p867 ++-0x1.985c42bec01c7p0 ++-0x1.1cf386cd14914p8 ++-0x1.5f67a73764c42p614 ++-0x1.522cd68c1bf68p26 ++-0x1.d799532d49d5ap674 ++0x1.46bb22a16728cp5 ++0x1.389933b0164ffp10 ++0x1.a5f50513df15bp99 ++-0x1.be02a2624e3e2p-6 ++0x1.842b00d07b638p18 ++0x1.2411e326586bap-1 ++-0x1.e39ec39ec78acp100 ++-0x1.9a0136520b211p-20 ++0x1.473bd1a29d139p-12 ++0x1.5997d3e7d9cfcp596 ++0x1.c569803b425e1p13 ++-0x1.a38fc2debd07bp914 ++-0x1.e7a0c727b8c85p-13 ++0x1.fec181572dc93p143 ++-0x1.9d59b64a201eep-2 ++0x1.730c81ab84d39p18 ++0x1.0b25801e3ab2dp4 ++0x1.23a5f5c54b7b8p1 ++0x1.322b0576073e0p0 ++-0x1.c1f8e33410fe8p-11 ++0x1.867ef74ad8684p499 ++0x1.364d612cd2496p1 ++-0x1.caec529ba1df2p42 ++-0x1.b99d77d2009bdp0 ++-0x1.4bf4f0d4925c5p909 ++-0x1.79d630227d604p512 ++-0x1.fbbc014403c00p855 ++0x1.32e5e1654b2a2p-1 ++0x1.c94ed499f75c2p25 ++-0x1.805ce3fcfd6cap236 ++-0x1.38c217951cfeap14 ++0x1.d2c6423a89b18p32 ++0x1.fa9fb7906c851p8 ++0x1.6a2e105660a34p460 ++-0x1.3bb4055b92b4bp20 ++0x1.19b7d1cb31d88p5 ++-0x1.b710d75b84f62p30 ++-0x1.abc2246751c8dp-2 ++0x1.a9454155ad3bap5 ++-0x1.8107e221264ecp30 ++0x1.3554a38510ef4p-2 ++-0x1.8c392588b88aap-2 ++0x1.6a61e531ae636p-1 ++0x1.522c04ef79576p-2 ++-0x1.585b113866998p935 ++0x1.6572d38c4566bp324 ++-0x1.01c407a78269bp-2 ++0x1.c667704230cf4p119 ++-0x1.c26e3294a15b7p609 ++0x1.398957506d8ebp0 ++0x1.e0b6730234a2ap12 ++0x1.5f55247076d4cp886 ++0x1.91a7e436c803ap85 ++-0x1.b405442f13b0dp-1 ++-0x1.89197589af46bp12 ++0x1.b689827fcf442p0 ++0x1.e511f183f3761p38 ++0x1.8bbf8044036dap-21 ++0x1.a6f9739fb14bdp715 ++-0x1.e0b26088aa820p260 ++0x1.7ba5e059f9881p23 ++0x1.fe66a754c0fd2p25 ++0x1.6c6a32bf8575ep-1 ++0x1.eaaca56a33a78p-1 ++0x1.9015009c0d6f2p359 ++-0x1.6cb7f41a689d7p511 ++0x1.aacc71d5bacbdp95 ++0x1.29e4c477b18a8p36 ++-0x1.ef83a0fc79d14p-3 ++0x1.32e2c2a316640p21 ++0x1.ec0675ef5c64dp18 ++-0x1.dbfc56a89d5c5p-17 ++-0x1.cbf486a4cadf0p927 ++0x1.07936134292b1p8 ++0x1.b151d4537a8d3p192 ++0x1.67efc2818dc90p323 ++-0x1.9cd295f2ce662p16 ++-0x1.821820585b1efp0 ++-0x1.e5de90be0509ap-6 ++0x1.d26fa3ccb06acp-1 ++0x1.0f26767f7e19ep9 ++0x1.9732e3a149dcfp2 ++-0x1.738c626bee029p22 ++0x1.ebc397d721a35p-10 ++0x1.628a90978e6e9p313 ++-0x1.7e31f7114dea8p15 ++0x1.79cc77a2bab11p10 ++0x1.2983d646690f3p588 ++-0x1.5eafc23db65cbp32 ++0x1.8942a552364e4p-2 ++0x1.e3ccf6eb08b48p25 ++0x1.7880661b82c3cp13 ++-0x1.960bb106193b4p3 ++0x1.512562f1663f3p-9 ++0x1.d73bb4b91b054p-1 ++0x1.da72a35c1109ap0 ++0x1.b7ab22fa83736p844 ++0x1.d13c003e58e8fp-1 ++-0x1.ad34c4a774bafp-2 ++0x1.215ee10881727p787 ++0x1.94e87183d84f5p-2 ++0x1.e67e95b1bfec2p5 ++-0x1.13b3721046567p433 ++-0x1.3496b371b7047p-20 ++0x1.a20233bcdcf1ep478 ++-0x1.8b2493a06a535p-1 ++0x1.a84f74a1a6298p15 ++0x1.20bc40cdba97ep-2 ++0x1.d77ea17713c46p99 ++-0x1.6206e0239f1adp43 ++-0x1.d3e2555f60ea3p-1 ++0x1.aac214994c1dap-23 ++0x1.b16e41716b9a4p1012 ++-0x1.bff49465bba1fp-5 ++0x1.3922b5075dd33p-23 ++-0x1.826d62aa4fc16p1 ++0x1.c787f3022d540p17 ++0x1.0e8f744f79d08p8 ++0x1.8224508569db1p4 ++0x1.3551056491610p39 ++-0x1.d97a27aa772f1p24 ++-0x1.080464f37e4f9p-1 ++-0x1.ef7ec170b1cc7p-14 ++-0x1.56a34672be8a3p0 ++0x1.568ce0836dad1p0 ++0x1.68e4d1349211cp0 ++-0x1.cdd5647152dccp0 ++-0x1.df937407c9261p-2 ++0x1.dbedf324f26c8p42 ++0x1.e61e938251d5bp-26 ++0x1.27aa70e4f9180p10 ++-0x1.2beb30d17d09fp11 ++0x1.fc2f613c865cfp612 ++-0x1.18a437c0c0337p989 ++0x1.497f7636bc81ep5 ++0x1.eefc152fee26ap-1 ++0x1.e01e636b8c0e8p13 ++0x1.641203e8ff6c4p10 ++0x1.7cd5f6dc77b45p-1 ++-0x1.a8c463d05a384p-18 ++-0x1.939935c60bc6dp32 ++-0x1.112004f389f0bp26 ++-0x1.e3dd8706dbb77p-2 ++-0x1.06660332f032dp0 ++-0x1.2df664008c6b8p946 ++-0x1.db05f1c0a68afp-2 ++-0x1.c148b6e43e444p8 ++-0x1.5de1353d73697p4 ++0x1.66fdf2d6b465bp9 ++-0x1.62c167e6e4b10p23 ++0x1.9eaa3110cddb2p86 ++0x1.88c261dc17162p11 ++0x1.1309b29673b81p-2 ++-0x1.2bb1f6b417cb9p30 ++0x1.087814c0ec7fap624 ++-0x1.e0c945389d582p8 ++0x1.7943a676a5441p24 ++-0x1.320c04ceb42ffp-21 ++0x1.d909361bb3862p45 ++0x1.3b65434a04806p23 ++-0x1.afd001facc7b1p-2 ++0x1.0b19c619a640ep-10 ++0x1.0957e03dfef54p38 ++0x1.24e94466217eap-8 ++0x1.63119435659e9p0 ++0x1.3f3e90058cdf8p32 ++0x1.9c5120fa60573p-20 ++0x1.4582f3a60e340p46 ++-0x1.909e3202d81a4p4 ++-0x1.0437d4ebf5610p-9 ++0x1.6539d39ccc38ap568 ++-0x1.41a5b0bbfb9bcp6 ++0x1.7e8bb37871e1cp19 ++-0x1.ad8ad1bbd74e5p18 ++0x1.de4de49f18b51p25 ++0x1.826ba7055be5dp0 ++-0x1.ef63f73ede073p13 ++0x1.3beb24857264ap-16 ++-0x1.6f4b015987fdfp13 ++-0x1.a1c3d13b1c1efp38 ++0x1.e54744ab0b987p-18 ++-0x1.30d3903b0fef8p0 ++0x1.221cb2580e640p-2 ++-0x1.3686a2b46f392p20 ++-0x1.953a23666db27p23 ++-0x1.0e27f512156c1p41 ++0x1.8aeac1aea8951p507 ++0x1.859272081065cp24 ++-0x1.1421f542a190ap22 ++-0x1.13f9b5260c5c6p1 ++0x1.26e7e7db18108p-1 ++-0x1.5c5fa31066b6fp24 ++-0x1.f561528837944p47 ++-0x1.296430993cfacp6 ++-0x1.2d27a23459f85p12 ++-0x1.532a550f8785ap8 ++-0x1.97da24484f8b4p1002 ++-0x1.6dd96318f0afdp-20 ++0x1.c22a23981d826p880 ++-0x1.bb6595d952b59p-9 ++0x1.9d303417d2283p-8 ++0x1.2fad41ad10377p3 ++0x1.0fa034dfdbfacp97 ++0x1.ac9f668620937p201 ++-0x1.0926c03aab751p431 ++-0x1.1122f714c565bp-24 ++0x1.85b8127865850p194 ++-0x1.70a2c17f946dcp41 ++-0x1.41fda46167f73p23 ++-0x1.25ad23c987dc1p11 ++-0x1.8b7901317fc7dp-14 ++0x1.3a39378fff8f4p7 ++-0x1.27d681a249f5cp30 ++0x1.cb79b21c83a00p65 ++0x1.6682c62f9ee17p544 ++0x1.9722e5ad48a83p0 ++-0x1.6877c6503e926p-11 ++0x1.60bdc18e9615ap38 ++0x1.71209215d4d4dp166 ++0x1.3b3083c9e79aep29 ++0x1.226c15a2738fbp20 ++-0x1.850e61bf2adc0p46 ++0x1.cf59c1a465033p4 ++-0x1.f28f75a1e366ap-2 ++-0x1.ddfe107392c51p752 ++0x1.ad9a867a0f388p7 ++0x1.c190d52d7d990p-2 ++0x1.40f39083588dcp0 ++-0x1.72a507fb05048p23 ++-0x1.cb11020748b01p915 ++0x1.1af08708ba5cap15 ++-0x1.627c101f73406p530 ++0x1.689206a8915abp318 ++-0x1.cb6761b5dea79p634 ++0x1.c2e0d162c326cp404 ++-0x1.718305de4f896p17 ++-0x1.e93fc085fd701p-2 ++0x1.11ece54e13460p5 ++0x1.8727425cf3cd8p24 ++-0x1.b42da698277c1p45 ++-0x1.6596f74580a61p749 ++0x1.5527e4a40304ap13 ++0x1.e44661960fc6ep861 ++-0x1.f172b70a99607p-1 ++-0x1.0551459f69b31p1 ++0x1.fe53e03d64618p-23 ++-0x1.32fa65f2e7445p-18 ++0x1.d186c41b4314ep15 ++0x1.554651879adf5p21 ++0x1.11ffd2256e002p-2 ++0x1.af32d40afb747p25 ++0x1.7f07047f01402p46 ++-0x1.7d6eb6b631adep325 ++0x1.368db60e46f81p0 ++-0x1.7dff648d5243bp2 ++-0x1.8c2ec01e5fedcp0 ++0x1.2a285014439ffp25 ++0x1.97d7a7e9d1488p267 ++-0x1.aa7e802105b2bp3 ++0x1.71f44577ef0e0p30 ++-0x1.c348a7a1cf0cap-5 ++-0x1.e3c124e128e3cp513 ++0x1.6382e3388fe7ep0 ++-0x1.535d11123ca67p-1 ++0x1.cb8544daa77adp232 ++0x1.c711c1bebf09bp-2 ++-0x1.5af6028fa5346p944 ++-0x1.96048340a5514p22 ++0x1.f72ff33637c6bp22 ++0x1.19acb5b9c1f96p849 ++0x1.2812a646b9299p-1 ++0x1.75f772acd0271p614 ++-0x1.182e332b82935p951 ++-0x1.20dda567e407ap389 ++-0x1.aabc54e09bf9fp5 ++0x1.e6b50061378a4p40 ++0x1.2f68852bc70d7p0 ++-0x1.823b97f7229a4p-15 ++0x1.c4e326b2e2dbfp21 ++0x1.7e4f6774b8a2ep-1 ++0x1.1ab614657417dp98 ++0x1.f3e634c32e8b7p3 ++0x1.e9e836b498598p-9 ++-0x1.1c64235980810p10 ++-0x1.aafc1207ad818p-2 ++0x1.9f3d233a5c111p-5 ++0x1.7999c2260403cp31 ++-0x1.f30211be994f6p24 ++-0x1.0c43722a9bbbep-6 ++0x1.930ee35921be4p-1 ++-0x1.5d6213b5f1254p22 ++-0x1.7d22615123c54p1 ++0x1.83b3112e046efp46 ++0x1.f41974f304112p603 ++-0x1.3a66e15aa8fe4p20 ++0x1.a13001aba9f6bp852 ++0x1.412aa2c7532c4p-14 ++-0x1.c81352e8264c2p23 ++-0x1.591d02625a9b5p22 ++-0x1.c41166b01542dp20 ++-0x1.5131d3c932102p2 ++0x1.3e0812627d769p0 ++-0x1.42230381aec5ep24 ++-0x1.f2b3323fb84d7p10 ++0x1.eb6774d11a107p309 ++0x1.66bfe7efc9981p413 ++0x1.7393b483ef4c9p18 ++0x1.1c23a0ccf4a1fp5 ++0x1.f726a29f3c7b0p-1 ++0x1.56a6c4b8f4c03p0 ++-0x1.d81fc1be44ccap0 ++0x1.acb2a2c71b283p0 ++-0x1.fc027711d2a95p42 ++0x1.fc337688991dap0 ++0x1.199a1661ea960p13 ++-0x1.3b86d2611c320p27 ++-0x1.61c2d21282edfp26 ++-0x1.64e50317eefc2p785 ++0x1.def315b3fe290p780 ++0x1.cf1e17c160022p-18 ++-0x1.38eda7d8530bep24 ++-0x1.808c94ffe4d91p-1 ++0x1.4610f3e719abep7 ++-0x1.1e9381dc4ec70p-11 ++0x1.43cba0bf131a0p13 ++-0x1.dc42b575ed4d3p1013 ++-0x1.6ed8149cc7bc6p-1 ++0x1.4a60f7c0d69e4p13 ++-0x1.538585ddb4696p23 ++-0x1.0864d6a255b66p19 ++0x1.fbb200de88ab3p20 ++0x1.0121e4f96ae33p19 ++0x1.d249f66c94efap-26 ++0x1.f22cd10757b66p-17 ++-0x1.dc648333c448cp28 ++-0x1.bd93661102aabp6 ++0x1.111ac7383f502p24 ++-0x1.2b702455abc46p3 ++-0x1.0a6586568a0d4p0 ++-0x1.66ac624962909p45 ++0x1.28169042cc3a5p12 ++0x1.f66474e488ef9p22 ++-0x1.9537062a41765p14 ++0x1.c121e1e9723f6p-20 ++-0x1.9f26e345e6c69p45 ++-0x1.c04f565228f00p23 ++-0x1.3f2a165966b01p14 ++0x1.e49031acb773fp4 ++0x1.45d4862b31a5dp14 ++0x1.d3f8a349399cdp651 ++-0x1.95bf4422cf479p21 ++-0x1.5e80e7683c406p38 ++0x1.cf9e839f22581p-13 ++-0x1.bcbd040073ae7p42 ++0x1.0dbf80c846440p1 ++0x1.b967a548e9278p25 ++-0x1.09f7d6e2794a9p36 ++0x1.f52b73cf4435bp957 ++-0x1.7bc586cbd1a46p12 ++0x1.ec2ca0ba0169fp956 ++0x1.7b4ec7011ab15p-14 ++0x1.9590d2642b855p2 ++-0x1.1792b47e89a3ep-2 ++0x1.096e8355c6a33p387 ++-0x1.0309a65ffc7d0p389 ++0x1.bbe450a514bbbp23 ++-0x1.c2a0c154c1ea8p22 ++0x1.8c8840b2a87e4p-1 ++0x1.bc053744b4d71p525 ++-0x1.0bad1023cf416p26 ++0x1.6c74f2f70249fp-2 ++-0x1.df29e2bbca95ep-20 ++0x1.541ef0a6c96dap25 ++0x1.228634785edb5p959 ++-0x1.2e5246cb79ea9p-2 ++-0x1.e27d61cf42df9p-1 ++0x1.92d2218c0d244p-3 ++-0x1.28dab0f8375dbp19 ++-0x1.6a69c59ed57f1p24 ++0x1.bc5c338bdaad2p9 ++0x1.1b86b1509d103p-2 ++0x1.96f70720b437fp-1 ++0x1.ec2dd7a3ff01bp11 ++0x1.6d674707f674dp24 ++0x1.8ccc84df77093p467 ++-0x1.fce2734699b46p131 ++0x1.78c0233339f48p-24 ++-0x1.10d36236e14f4p-22 ++0x1.0e5087309073ap0 ++-0x1.964d52d42dd8bp184 ++0x1.ae23e780b9411p-21 ++-0x1.54204161ed466p836 ++-0x1.954a4649af744p41 ++0x1.bdbbb7d31f152p-1 ++-0x1.56e0943fe5998p-22 ++-0x1.36a8e4332551dp927 ++0x1.020b52f89937ap23 ++0x1.d7a20332bdd63p11 ++0x1.3b0dd5979b6adp-2 ++0x1.c0e8434f16674p-10 ++0x1.87e7f538c365dp25 ++0x1.d3e821a1bc5a8p7 ++-0x1.96b7d456e788bp25 ++-0x1.3ad9e1e70f896p943 ++0x1.53ee76bc80972p-3 ++0x1.96fa10c429e87p-9 ++-0x1.8056956d2cfadp24 ++0x1.c741b2b122791p6 ++0x1.ba3a96c89b1b3p166 ++-0x1.83990344b014bp766 ++-0x1.3e571252648bap15 ++-0x1.3bb1972c795a9p9 ++0x1.adb4d3351c887p43 ++-0x1.ff802660bf9a5p0 ++0x1.6e469006517f7p47 ++-0x1.900d500fb6d49p26 ++-0x1.c76ab659c3834p25 ++0x1.e521b219c20dbp-7 ++0x1.921a034787ed3p10 ++0x1.e995010c15b21p8 ++0x1.8c2b466dd9540p47 ++-0x1.04c05174f23b9p12 ++-0x1.93b6b3adbef7bp392 ++0x1.c56de7617c8d9p-1 ++0x1.5160533d35ef7p19 ++0x1.e130936be6602p-1 ++-0x1.739414d989802p16 ++0x1.31b1d2c632ab2p-1 ++-0x1.c31d635f38768p22 ++0x1.bbb4f5b78c9c5p32 ++-0x1.e445c444330bcp388 ++-0x1.8c4be45fbe950p-1 ++-0x1.837291c50b911p-2 ++0x1.a8e1958326948p22 ++0x1.3489902ffcd05p89 ++0x1.3937a140c8ebdp102 ++0x1.6e18d2c91a6ddp-1 ++-0x1.ca05a2df5e759p-7 ++0x1.2cfef3c22cd0bp130 ++-0x1.4cf717964a9bfp7 ++0x1.54579498874b1p24 ++0x1.c107738f9b691p12 ++0x1.7bff9229e04d2p-2 ++-0x1.d03de2576ff0fp3 ++0x1.5f7b7021a52d5p45 ++-0x1.1942d4250cc59p402 ++-0x1.e0e3e37700163p34 ++0x1.e9b38334f06d3p655 ++-0x1.58ee600866d4ep189 ++0x1.5ef6e7cc455f0p289 ++-0x1.2c28461a00b92p4 ++0x1.10d365a1e8d8ap21 ++0x1.468d92dd56b89p7 ++-0x1.6abfb0ce30badp23 ++-0x1.5f89a14d0efd0p-2 ++0x1.15d3e3cd4669ep539 ++0x1.4713f780aa584p-2 ++0x1.3b21b2c71e99bp26 ++-0x1.48b56671059e1p-11 ++0x1.1bc1d481ce9dbp69 ++-0x1.b1ae27d09baa0p-2 ++0x1.33d7670cbf8a4p8 ++-0x1.6ac4255cad8dfp-8 ++0x1.62dab6f6b3009p34 ++0x1.425c721226be2p442 ++-0x1.275535869b097p9 ++0x1.ecb7c62bea980p0 ++0x1.bbcc660f5e0a8p15 ++-0x1.1f9e74b3579c2p0 ++0x1.fd7275569c113p36 ++0x1.dea7467ccaa26p-2 ++0x1.a791b0a57606ap24 ++-0x1.82cad3f8be955p22 ++-0x1.4157360076d26p-1 ++0x1.c97d10ced4329p0 ++-0x1.932787d6383efp2 ++-0x1.c01812d3d51a9p-2 ++-0x1.1c84d6fec1316p609 ++-0x1.0f01559dc82d6p-25 ++0x1.00f5458920f43p4 ++-0x1.43719306d3215p1 ++0x1.c656d370d0ffbp354 ++0x1.0e11c40e388b9p26 ++-0x1.290134e6aff9cp35 ++0x1.1040550bddeb0p-9 ++0x1.9a7781da48013p4 ++-0x1.0a9e5772e3233p-8 ++-0x1.0d91b0bf21e8ap-1 ++0x1.948055d3de56dp27 ++-0x1.3e88a1b46969ep40 ++0x1.bbcbb014c46c2p10 ++0x1.e9d0279c4b0a1p20 ++-0x1.b6238112f8687p398 ++-0x1.e242654542bebp-11 ++0x1.a762d2287829dp988 ++0x1.9bd01053b4464p8 ++-0x1.f8cd636f4e283p837 ++0x1.aa1c81bd7973bp47 ++0x1.970f71af84cc4p21 ++-0x1.aeb236cb2b17ep431 ++-0x1.93c0e6c9d5101p4 ++0x1.6a8314d7ab46ep14 ++-0x1.dff0340ed9b5fp23 ++-0x1.20d4206297414p0 ++-0x1.bfe4e19c4431ep16 ++-0x1.e364e69ce1acbp-2 ++0x1.da3807b2bef2cp5 ++0x1.7d5bf5fdf17d8p3 ++0x1.403cb40fa6ed7p-2 ++-0x1.e5eb014cd4696p-2 ++-0x1.12c867efadb58p-1 ++-0x1.17b9111cd2dedp47 ++0x1.5fbd06f46a166p20 ++0x1.3fa931008c3ddp12 ++-0x1.671603ed400c7p39 ++-0x1.f3a3f55752ffap381 ++-0x1.06d0b08cc2f3ap19 ++-0x1.20f970c57de9fp405 ++0x1.26bca4618e8c6p450 ++-0x1.e84bc67cbae25p21 ++-0x1.847b219c71e8ap-19 ++0x1.6485a7df487c2p-5 ++0x1.79e9b12eaade0p0 ++-0x1.ea3177ec5e17ap1 ++0x1.9061b7ce1ba79p-11 ++0x1.aabb7153d3d41p0 ++-0x1.cd05349e06fb9p453 ++-0x1.387bd166fd5c6p6 ++-0x1.5b7dc65df367ap16 ++-0x1.f014b7e23834fp0 ++0x1.be4041821c70ap5 ++-0x1.bb11127a3673ep-2 ++-0x1.69b7a36b6d3a1p44 ++-0x1.d182b403ec2d6p435 ++-0x1.fa162577a34bfp356 ++0x1.837c5378cbac9p1 ++0x1.f6aa460693a38p25 ++-0x1.30e5c6ba6d18bp0 ++0x1.f26723819b91ap-1 ++-0x1.a81dc27444846p14 ++0x1.3ec314460be45p-21 ++-0x1.a92ed0de504fdp25 ++0x1.026645ce3b546p5 ++-0x1.d783568871061p-20 ++-0x1.94e5527db2c75p27 ++-0x1.67f7371aa18ffp23 ++0x1.d3c365bbdea80p4 ++-0x1.9e1a5225f6428p211 ++-0x1.258ad3e2c8fa6p28 ++0x1.3136354b964fdp-2 ++-0x1.96d4f40d26403p10 ++0x1.095bd56107f24p5 ++0x1.9fce92abc33f3p19 ++-0x1.ce7553d981cd1p-1 ++-0x1.e601531fa6475p22 ++-0x1.6ab42170809bcp2 ++-0x1.b251d2575cac5p-18 ++-0x1.4c41d161ca889p-20 ++-0x1.1072d2e8dc7acp42 ++-0x1.59f0d7ec9545cp27 ++0x1.60e971fce2225p-1 ++-0x1.cae6a23b7284cp7 ++0x1.65457653e73cep10 ++0x1.e5d2c1b0f8814p-6 ++-0x1.2379c4cafa4c7p2 ++-0x1.a10a970cc1572p1023 ++-0x1.ca2f3652ecb2bp0 ++0x1.eef9a3fc5f760p19 ++-0x1.e34471bd585d3p0 ++0x1.c01c5448e8150p12 ++-0x1.bc8e94cc562d0p-1 ++-0x1.df2934c9a3eb9p-19 ++0x1.932107520d49bp0 ++-0x1.664d64c583dc0p26 ++-0x1.df503401587dep23 ++0x1.ff26b5f73eb26p0 ++0x1.223f61fd260f6p15 ++-0x1.388ca56b6eb09p-9 ++0x1.c843f6cbf0218p0 ++-0x1.5b55b55f69e3dp12 ++-0x1.55d2b6c9ccac1p-17 ++0x1.8fab8647c1b20p25 ++-0x1.c39c1323c517cp26 ++0x1.9b8cb5c150892p567 ++-0x1.075482bdba47ap11 ++-0x1.9eb9c5f4e9bfep-12 ++0x1.9301916eb43c8p-2 ++-0x1.8b05471774a4dp36 ++0x1.0cd1f741bc013p-1 ++-0x1.4dcce7d816178p952 ++0x1.5bb4d5a081463p313 ++-0x1.512e913b3aec4p43 ++-0x1.4363149bdc7b9p13 ++-0x1.363bc2214c09bp1 ++0x1.773a72172fd88p-1 ++0x1.585f6579ec411p13 ++0x1.d5f6f68d24a76p-2 ++0x1.69fd3358c8b0ap-23 ++-0x1.a4b6f1189e5dbp6 ++0x1.0de1b1a9735c3p-2 ++-0x1.dce0808027bddp22 ++0x1.0e7ce079de804p-8 ++0x1.9f5a738b4d6eep-2 ++-0x1.8462d5daae41ap11 ++-0x1.68674675a393bp24 ++-0x1.e10d4227c6195p-2 ++0x1.9efc93f7ae5e0p856 ++0x1.b21722c3599a5p998 ++-0x1.9230777d2e819p2 ++-0x1.234b04e484f07p-1 ++0x1.f0a83169e44f8p21 ++-0x1.551ab52bbf836p10 ++-0x1.954191e744c98p778 ++0x1.2b5df36e4639ap687 ++0x1.6febe142407c9p-1 ++0x1.b0a7d19a8a36bp14 ++-0x1.283335399df8ap582 ++-0x1.ff008550804a8p21 ++-0x1.7b3e67a391ce4p23 ++0x1.1d85929407a6dp24 ++0x1.5da834d23e5a3p447 ++-0x1.4692871c1db20p8 ++-0x1.afc295fcdbcb4p12 ++-0x1.9f23a78c18795p-1 ++0x1.6080b280acfddp17 ++-0x1.2e5266ef4d581p26 ++-0x1.24b7b38d26da1p257 ++-0x1.c53977510263cp4 ++-0x1.fb19403b773a8p-1 ++-0x1.244143543f68cp-9 ++-0x1.de8675a5953d7p-10 ++-0x1.127a02301391cp25 ++-0x1.e81cd0632e8f1p-6 ++-0x1.8f0832d2d654fp23 ++0x1.8d0592c41d57fp-1 ++-0x1.5bb7a2c85295ap829 ++0x1.5d0f05a6628d0p33 ++0x1.0fa8504e8dc88p26 ++0x1.efa587af6be2ep1 ++0x1.0e33b1aa5c9bap7 ++0x1.2910965c221adp24 ++0x1.7117912e9cc38p-19 ++-0x1.14f1f66cce91bp309 ++0x1.253d965df51d6p-2 ++0x1.c129f2121f395p8 ++0x1.725be7dae8d66p19 ++-0x1.93edb5e7fb6cfp5 ++0x1.5018651cc719fp-1 ++-0x1.cb02c64f918bfp46 ++-0x1.f46340a22bb84p21 ++0x1.8f68f646ec9f2p43 ++-0x1.6d9a331135c58p25 ++-0x1.170ac534d5637p44 ++0x1.a4a742eb49b6dp25 ++-0x1.7020056638407p607 ++0x1.48deb525372e9p-1 ++-0x1.33e8601f36771p-1 ++0x1.ec3874c4618a1p96 ++0x1.fc37d39694eb5p39 ++-0x1.ff4071cb454c4p10 ++-0x1.ed9d16ccafc18p730 ++0x1.7745c1d7844b9p-2 ++0x1.577ea4e34c3b6p437 ++-0x1.3207305c1a799p0 ++0x1.0917100431cc1p-21 ++0x1.2c183093fa529p603 ++-0x1.2c5d51ba70531p14 ++0x1.608c1509bfa83p148 ++-0x1.f839c173e805dp14 ++-0x1.98e12705bc31ep995 ++0x1.3a50f5332c5c9p123 ++0x1.a3c53078bbb14p14 ++0x1.7774161aba4aep38 ++0x1.f77d9613e7c1dp-1 ++0x1.087e662e1679bp0 ++-0x1.f6a5441a51460p9 ++-0x1.943ec15bcfd0fp-24 ++0x1.ca08a5623522dp836 ++-0x1.b94390a4ec03bp21 ++0x1.f028210e4643ep86 ++-0x1.a08b00ea57565p0 ++-0x1.d32a26194266ep33 ++0x1.f9c00577e6bdap14 ++0x1.2aa9d7f90174dp-2 ++-0x1.a73675bf09391p24 ++0x1.8e42320f970aap-5 ++-0x1.456e713f4c160p26 ++0x1.0a7c735c32ef7p370 ++-0x1.599d856aa3f83p126 ++-0x1.a2aeb2b04f0a4p-1 ++0x1.1b9611214c8efp38 ++0x1.b79443495fae2p555 ++0x1.bb96e62f437c0p449 ++-0x1.d8628272405eep331 ++0x1.3e7d077075b34p3 ++0x1.f02863b1964cfp-18 ++0x1.bc64148bb2bcbp963 ++-0x1.abbfa06274d7ep-2 ++0x1.4124c7371ae20p-12 ++0x1.01bea1cd85371p-2 ++-0x1.86f4c7d558b23p365 ++-0x1.2d7045098fc2bp6 ++0x1.12cdd38e1f1fcp40 ++-0x1.cf87f031ba281p-1 ++0x1.900f77d2e17b8p-3 ++-0x1.780482ed78ed2p0 ++-0x1.c0b7e330a1569p622 ++0x1.e964c06440769p21 ++-0x1.0575c6582a7e8p219 ++0x1.014cb3689dba2p364 ++0x1.757270c3f8b5ep6 ++0x1.f4b96482cda61p25 ++0x1.b56110293d311p31 ++0x1.c319d66d3a8c0p-15 ++0x1.42d33307c41bdp14 ++0x1.ea5575e42d23ap17 ++-0x1.a6e025cb863c7p0 ++0x1.cc5d70ede499dp27 ++0x1.e359a47239531p0 ++-0x1.d8d93754b2b11p29 ++-0x1.8ca7b5053585fp1000 ++0x1.d9d5310c25ca5p-1 ++0x1.8d9430af4511fp961 ++-0x1.66d8a6638d99bp512 ++0x1.b41ad75a8801bp9 ++-0x1.6a1f971fa26b6p-14 ++0x1.ab5c81ae14fe6p-1 ++0x1.1f8577d10b9c5p971 ++0x1.cdd440ab2d669p9 ++0x1.4951f5844ad5ep4 ++0x1.ec76109115f59p10 ++-0x1.5e9a80ad92f6cp0 ++0x1.a0e386b6ccb40p253 ++-0x1.987135136f652p-15 ++-0x1.4972078157c11p18 ++0x1.71af54cd3edcbp-22 ++0x1.2cb9c16feca61p4 ++-0x1.881612ba1bac0p23 ++-0x1.a1bc462181294p6 ++0x1.59e7f20d1a85ap20 ++0x1.6efbf694bc721p795 ++-0x1.194d02c8696c5p1 ++-0x1.c29f770300210p40 ++-0x1.465474694864dp5 ++-0x1.be79c39a626abp-2 ++0x1.a84f059ce3c46p0 ++0x1.7aa4e54b620c4p8 ++0x1.3da7c7bc6677fp-8 ++0x1.f69225fe61ad2p28 ++-0x1.64de33982551ap-1 ++-0x1.914f65e648df9p27 ++0x1.8a6b04c753621p4 ++0x1.9bbe37ce952f4p151 ++-0x1.dde326d0cc835p989 ++0x1.98c0d3cdf20d3p21 ++-0x1.284c014de6027p-7 ++0x1.88d835cac3b12p0 ++-0x1.b6db809206af5p2 ++-0x1.e565b22e34e93p32 ++0x1.749c6053c4d99p27 ++-0x1.117985fc29082p-3 ++-0x1.4aea6753378aep18 ++0x1.e0dab03922291p582 ++0x1.6215370395220p-11 ++0x1.c6fd922332304p23 ++0x1.634a06577ffe6p14 ++0x1.7a0794ef5f1b2p-17 ++0x1.12abd5b589964p-2 ++-0x1.7dc825820bbc5p-1 ++0x1.8dac9227f7521p19 ++-0x1.152a74beb6671p0 ++0x1.91c8274862218p-1 ++0x1.6b46c437366a9p2 ++0x1.91be1642b829cp-4 ++-0x1.9bbe55e1e875bp0 ++0x1.cf53d39670350p30 ++-0x1.6106a19021fd0p25 ++0x1.b4f8156fc19c5p951 ++0x1.e681709062081p40 ++-0x1.d940928c3f987p2 ++0x1.691480d2f533ap737 ++-0x1.85c093aaae1ecp900 ++-0x1.5affb35c6bf7fp26 ++-0x1.dc84061a932cfp17 ++0x1.ee1e42315879ep25 ++0x1.678d23f005c62p764 ++-0x1.ec9774244565cp535 ++-0x1.9271662cb2093p16 ++-0x1.f83131ca71ccdp-17 ++0x1.ca7930f286682p13 ++0x1.a7255589c90d3p-11 ++0x1.53ac82fd92bd9p14 ++0x1.a47a64b427441p43 ++-0x1.3a1722f39b3dep25 ++-0x1.9f33140b8a810p312 ++0x1.d03d52df1c72bp688 ++-0x1.1c6fc748fa1e5p43 ++0x1.0b3414a9938eep2 ++0x1.dd0da78a5d1d8p633 ++-0x1.4c4580f79db55p36 ++-0x1.92c9b7d98ad52p16 ++0x1.33a582ad335b4p8 ++0x1.8412d4cdc4b13p2 ++-0x1.6d70c0e74843fp-1 ++-0x1.094ee77340bdep25 ++0x1.29f1d2a5785f4p1014 ++-0x1.d15b11be3fe7bp7 ++0x1.58a4143823bb5p291 ++0x1.902405ab3dbd7p-12 ++-0x1.927bb2a52a3a0p22 ++0x1.72dfe5a32fb2bp26 ++-0x1.84fd5529c70e0p-2 ++-0x1.309e3082bb94bp3 ++0x1.1f345701b89f5p1 ++0x1.7dad63072bcb5p20 ++-0x1.ade4901d73471p99 ++-0x1.c22aa72bdcd7cp-24 ++-0x1.f59845faa6563p18 ++-0x1.ad6e102c9bc28p18 ++0x1.0fb34286e7064p0 ++0x1.94a631bd3477bp-13 ++0x1.210a974f1dccfp10 ++-0x1.2e4bb56104384p0 ++-0x1.baefd380be2d4p9 ++0x1.ed1987f86a22ap36 ++0x1.774a94a24ef7fp21 ++-0x1.2df7e52525ce2p23 ++-0x1.b56ff18142c84p244 ++0x1.5cf265da00a46p0 ++0x1.2301239fc121cp8 ++0x1.422ed28d49c39p695 ++0x1.737c10c4444c9p-15 ++0x1.2d1c455042173p729 ++-0x1.7ab92567a3677p47 ++-0x1.a93bc46c3f91cp-1 ++0x1.a84da7b1e13e8p764 ++0x1.01b0716556196p7 ++0x1.9279d0b582281p52 ++0x1.87062189adde4p283 ++0x1.1b0bf0a2108b2p36 ++-0x1.5eb4d47d17207p46 ++-0x1.2d48f70490ef9p41 ++0x1.02a927e62e4ccp229 ++0x1.64ece5d8585f1p-10 ++0x1.f348233a76acap526 ++0x1.18ae26a877ec0p-2 ++0x1.f29784bc68275p47 ++0x1.6001f45f7971bp12 ++0x1.a22b2698b25fap352 ++-0x1.e03a853c027d9p29 ++-0x1.a95c30e27b155p978 ++0x1.54ba70dc907bbp8 ++0x1.2973942fbefc1p-2 ++-0x1.d880a44876022p-2 ++-0x1.5714a530cbfe6p-8 ++-0x1.cafc377dc6968p152 ++-0x1.d75a05f2b42e7p32 ++0x1.457431b89e9fap-1 ++-0x1.1459601867581p0 ++0x1.d012824c3e9bdp-2 ++0x1.cba0151869ee4p-15 ++-0x1.28514551cf3c2p41 ++0x1.1a8f5790ecb1bp-2 ++-0x1.e3ca859ef8af9p-20 ++0x1.61d8824c0577cp17 ++0x1.0dbc60263979ap0 ++0x1.13ae60bcf616cp11 ++0x1.2b64749c50115p1 ++-0x1.d4d6b06398109p6 ++0x1.62482046dcfa3p-10 ++-0x1.144d5089806e4p0 ++-0x1.2a84e1516c3b9p-3 ++0x1.a4a9c383e277ep15 ++-0x1.b6a4a184f369cp14 ++0x1.0934a50d726c4p-2 ++0x1.9fac46d3bac78p-2 ++-0x1.0f3d41801c34ap830 ++-0x1.ddf6e4b3ae58dp14 ++-0x1.f8c654fd8faf6p578 ++-0x1.83e3d444fb99cp9 ++-0x1.29462350fde9fp18 ++0x1.c2d23298201f5p32 ++0x1.38dbe21a97dc9p765 ++0x1.b0ff117ae0c79p4 ++-0x1.936ba48a606fep-8 ++-0x1.5ed053069752fp9 ++0x1.73c4c4bf7d0eep5 ++-0x1.e7005748bed43p-1 ++-0x1.5f9f348eb0d61p-14 ++-0x1.fd0626e287666p-10 ++0x1.272f865f58d3fp1 ++0x1.89aa61b27b617p19 ++0x1.d3c0a3db910c4p703 ++-0x1.28c846d807abfp17 ++-0x1.ff57f267de4afp650 ++0x1.2f37531444d22p-1 ++0x1.295914905d114p-2 ++-0x1.a2cc76af10462p-2 ++-0x1.7e2a733986885p-12 ++-0x1.b026f4918478bp581 ++-0x1.940790b8f17d3p-17 ++0x1.0bea736dfa349p20 ++0x1.4c5ab26cb0893p17 ++0x1.cb8c42b26858cp4 ++-0x1.65eb419220961p8 ++-0x1.49628342f28b6p25 ++-0x1.0b70b20ac9274p-17 ++0x1.22d8177d1ee00p1 ++-0x1.df4a5041f3718p-24 ++-0x1.ad8cf7fdfad7fp-1 ++0x1.a24842645f612p5 ++0x1.36eac1a4ee651p13 ++0x1.f72fc2f8c5b6cp0 ++0x1.60901647c0c3bp18 ++0x1.983594e2c3028p2 ++-0x1.ae2e63b37144dp-2 ++0x1.63d9f29bc831cp3 ++-0x1.3f91157ed1b34p30 ++-0x1.f6a1a206c06cfp791 ++0x1.e5ba950e3dd7dp9 ++0x1.3db5f00ed6a5bp-2 ++-0x1.e758d3fa84fb9p14 ++0x1.26a215493eb73p-1 ++-0x1.9fbdd53b4633ap25 ++0x1.c6bd362b83b42p28 ++0x1.a57c06d6537a5p-3 ++-0x1.4d5ac675483eap-1 ++0x1.1b5483494381dp10 ++-0x1.a5e0731359db6p-17 ++0x1.d3285119915d0p-1 ++-0x1.9be71114e21b1p18 ++-0x1.ea8b7689adf04p125 ++0x1.78fea6e183fbep3 ++0x1.f0cf91eb94836p278 ++-0x1.3306524c34930p191 ++-0x1.4a2f071f69873p17 ++-0x1.ff2122f77561ap-2 ++0x1.511377046730fp229 ++0x1.14d73581dc669p976 ++-0x1.eb7e33dcfee72p35 ++-0x1.f4dbe5a5ff877p6 ++-0x1.d825938e1c238p6 ++0x1.5f0be541c74cap-6 ++0x1.079e24e0494c1p18 ++-0x1.34a8d3f3b42a6p901 ++0x1.34dc83fb0c6e7p-2 ++0x1.cf75150d00db1p0 ++-0x1.f031f0e0356b2p882 ++0x1.6b7973cd0aa93p862 ++-0x1.310095a968ce1p-2 ++-0x1.2866d1eec6cc3p-16 ++0x1.8191b0738f308p613 ++0x1.456f53f700f99p7 ++0x1.62847459e8128p183 ++-0x1.ba63e002b502dp-1 ++-0x1.1fc736191f77ep2 ++0x1.37572263819e5p-2 ++-0x1.7ae3b64ce441bp0 ++0x1.202e1625823d7p11 ++0x1.789183b6d53c2p33 ++-0x1.9f1015a572e03p27 ++0x1.ac19f4c66f202p21 ++0x1.3ffd935b47f14p827 ++-0x1.21ec60724c4d4p-23 ++-0x1.7d92c063e1943p794 ++-0x1.3329c4f9bcf9fp-1 ++-0x1.fb79b1e12f1b9p-1 ++-0x1.b453f204e2828p572 ++-0x1.05e91426fc791p287 ++-0x1.a0aca06187ac4p-2 ++-0x1.944d07402e20dp10 ++0x1.8b84302c454dap-1 ++0x1.57da67e840d07p-2 ++-0x1.5e139699b437cp0 ++-0x1.9611421dfe9a2p2 ++-0x1.dfe0a6790c2a1p15 ++-0x1.8d68a527dc4fep9 ++0x1.75d6920bfd64fp1 ++0x1.6ea3c72a463d9p0 ++0x1.017036841b9aep45 ++-0x1.b24cc456e7eecp11 ++-0x1.8fddc0abaff9ap16 ++-0x1.2415b665f8c99p26 ++0x1.8e6f32ff35e01p12 ++-0x1.e26252412c215p-2 ++0x1.955a700a5a653p-8 ++0x1.0ea7178825459p46 ++0x1.296d37b08b64ep140 ++0x1.166047ebdfbedp977 ++-0x1.4bcc33f01f7a1p36 ++-0x1.98d541beb3ab0p367 ++0x1.d75a350666c4ep36 ++0x1.c04822eb730fcp105 ++0x1.da66e151417f3p296 ++0x1.cb5376938dbe0p20 ++0x1.2bf8f7b48e8f0p15 ++0x1.8258537a3087ap19 ++-0x1.3f6af42d9b4e8p19 ++-0x1.123aa03954350p38 ++-0x1.768367b440c00p2 ++-0x1.406233b0d0f57p1 ++0x1.d8af4507de888p270 ++0x1.1ed46343e62d9p16 ++-0x1.0d2394e306c24p25 ++-0x1.2a47265c02b22p13 ++0x1.67f5d015d7adfp-2 ++0x1.6c7e32a8599bep24 ++0x1.4ff3f3faf1308p-17 ++0x1.6035a2fc3ea56p-2 ++-0x1.e85e0106abbc3p764 ++0x1.86eae4c63027cp-1 ++0x1.c79935bc19ae9p24 ++0x1.a99b811fcf714p-3 ++0x1.dc958723955fap32 ++-0x1.f256339f1d6d3p-1 ++0x1.fb29c0800abbep8 ++0x1.bfad063d46fa8p37 ++0x1.12b4c290f307cp0 ++-0x1.8cd584141bce7p26 ++-0x1.ba60a391b830dp4 ++-0x1.56d524c7c30dap41 ++0x1.6ffee3009fd2bp26 ++0x1.8bb180dc99719p8 ++0x1.6e1fe42f432d5p-10 ++-0x1.37a006c891712p46 ++0x1.2f1c942c39c55p402 ++-0x1.238be2f2d8cf2p863 ++-0x1.2b9d539b3b59ap21 ++0x1.73b8e458a50b9p21 ++-0x1.2768e227b49b5p-2 ++0x1.1516936960c2ep26 ++-0x1.ddde71ae89716p47 ++0x1.cde9e237806c8p332 ++0x1.14df62ffadc86p22 ++-0x1.cef3d59d11bbfp0 ++0x1.147587cc39596p11 ++-0x1.184116faeabd4p6 ++-0x1.52c9054a194efp532 ++0x1.00f111e190f7cp18 ++0x1.d7f525064b7ccp536 ++0x1.0d44e7cc02644p100 ++-0x1.16d8e062f9b27p33 ++-0x1.57b431dc4ddc9p-25 ++0x1.b6ece13eb981ep-18 ++-0x1.ef7cd24e26cddp28 ++-0x1.bedb764df5e91p14 ++-0x1.7a53f5bc491f2p-2 ++-0x1.c75c474186d48p-21 ++-0x1.7948a2340f8ccp27 ++0x1.7f28459c4c5b7p-3 ++0x1.7dba412384bdap24 ++0x1.f1a1763482009p751 ++0x1.e89f662826886p703 ++-0x1.cac75138c3526p13 ++0x1.39e786d2dc05dp9 ++-0x1.c0de8654d9d2cp-23 ++-0x1.b5b83454d5726p24 ++0x1.dfd9b4f326a02p9 ++0x1.5a792494bf6a7p602 ++0x1.c4f9f5fc40745p-1 ++-0x1.dec4154d34035p22 ++-0x1.d20985b372880p13 ++0x1.e08322497ccc7p34 ++-0x1.088f34cbb4570p-3 ++0x1.153a418434cf5p-1 ++0x1.e10de5e9186fep0 ++-0x1.dd6d97c9413f8p14 ++0x1.2386d6bba99b2p22 ++0x1.feb6a2da00daap-2 ++0x1.e1ce1507325e8p33 ++-0x1.282147169eea5p755 ++0x1.bb36d35a952fep-2 ++-0x1.f78ac5d6e92e7p31 ++-0x1.3fbb37d76149cp464 ++0x1.c565b245f458ap-2 ++0x1.63dd7410e99b0p46 ++0x1.374ad2ddaa195p20 ++-0x1.7679872738853p47 ++0x1.9d2e621a95f51p10 ++-0x1.63681742e61f1p160 ++0x1.723377f56685fp25 ++0x1.d4b42063b45aap-10 ++0x1.faa64445b0a9fp5 ++0x1.9f13f08a2c68cp24 ++0x1.5e08863f90e4ep634 ++0x1.3520f14a3d100p12 ++-0x1.6dec1180c4a30p23 ++-0x1.363ad7dd94e15p91 ++0x1.957711c469872p4 ++0x1.6a78174e047cdp283 ++0x1.e9ce64d645dcbp25 ++-0x1.aa5cc3fc79e94p540 ++0x1.313657c5c4981p298 ++0x1.6c129238ecbdbp0 ++0x1.817ff5141d57ep0 ++-0x1.a1a6536a8fe4cp926 ++0x1.bbd8e12bdc612p0 ++0x1.1a0a03f67cd7bp2 ++-0x1.415d0133cd310p2 ++0x1.08b0c1e34b29dp35 ++-0x1.e428432cbb7d5p9 ++-0x1.b9bd67795f0c3p0 ++-0x1.a893152e49e16p5 ++-0x1.e81760a539c99p33 ++-0x1.9d53d5c59a937p38 ++-0x1.cefea277671d9p11 ++0x1.ff43248d63df5p24 ++0x1.593914af16198p-21 ++-0x1.f34910fa15b18p0 ++0x1.58dab48d5e553p0 ++0x1.0a37f2b44bad6p35 ++-0x1.fc5f828ec77eap-15 ++-0x1.6592d152f9b08p472 ++-0x1.85a5754cd7c5bp12 ++-0x1.3c3e25ef48b5ap726 ++0x1.d27767aecb29dp5 ++-0x1.ee967500bcd88p19 ++0x1.be64452b706aap-2 ++0x1.9406e7378ff47p3 ++0x1.ca3c24bcd59c8p25 ++0x1.407c766a773cdp29 ++0x1.26ef70700dfa8p789 ++-0x1.b493b77a34bb6p-21 ++-0x1.2d5334bdb970ap3 ++-0x1.f31ed51dda243p-1 ++-0x1.561677af890b4p-2 ++-0x1.52ad65df5e675p29 ++-0x1.46d5938b70d32p22 ++0x1.bd8b859bdf9eep23 ++0x1.a515f6afc22e2p8 ++0x1.697520652bfd6p-1 ++-0x1.cca3159203943p11 ++0x1.c7a4967c92f5ep21 ++-0x1.e4076083ff124p118 ++0x1.4795b3dc73be5p21 ++0x1.4f5cc76450352p25 ++0x1.5d66d43044e72p-12 ++0x1.6e6e764a0b517p376 ++-0x1.3c2c46d020cafp0 ++-0x1.71878383e54a0p11 ++-0x1.90106128d6098p13 ++-0x1.345da3083c0cap37 ++0x1.1f3a52c232082p1 ++-0x1.b387718274c28p28 ++0x1.c4c15722ddd7dp4 ++-0x1.c67b533fc5d98p18 ++0x1.9ec4236ad4513p0 ++-0x1.262a57b5908ddp581 ++0x1.138ff2f62ed96p924 ++-0x1.2a3377ef850f0p9 ++-0x1.558bc5f67ee33p-14 ++0x1.e888750254606p-22 ++-0x1.f9d0d50d11f2ep37 ++-0x1.777ae766c28a2p29 ++-0x1.09e346e656647p17 ++0x1.eb546416c8f84p293 ++0x1.174e663e83926p36 ++-0x1.ba27457883c9dp-13 ++0x1.0e21179146e72p1 ++-0x1.dc30b5c7227e5p-1 ++0x1.1c5330a65cc14p-23 ++0x1.776655ee11a36p634 ++-0x1.4c06c77fa9d4cp21 ++0x1.0d94e52fa5002p19 ++0x1.7401000fb7cacp24 ++-0x1.d7d3544b26309p0 ++0x1.93c922c6fe31ep-2 ++-0x1.a3a0a3914f51ep-1 ++-0x1.4059b70d2e1ecp24 ++-0x1.8d2e12a9a241dp38 ++0x1.0a7df2e2ab942p296 ++-0x1.8b1a329e5ca50p0 ++-0x1.006b53dc2aef5p1 ++0x1.e69e734d01bbep21 ++-0x1.8586769b7591ap20 ++0x1.e609e60aa3770p804 ++-0x1.f62974bd1fcbfp13 ++0x1.c487460dd09fep7 ++-0x1.301c302e779c3p20 ++0x1.c142e3e9c59afp-1 ++0x1.37b9223a076c1p0 ++0x1.9ed467a1acc4ap7 ++0x1.85f744c68532ap-20 ++0x1.a76c83c5cb5abp9 ++0x1.2e4d91120cf95p743 ++0x1.20a2a661fc64cp6 ++-0x1.de8b904fc74c5p17 ++-0x1.3efab0ae9c967p390 ++-0x1.baaaa4beb4737p-1 ++0x1.c7a8c31fb995dp292 ++0x1.0ac905d847bf4p-1 ++0x1.3e16b224f5c6bp0 ++0x1.f24711f81bd86p-13 ++0x1.278ae68d14b89p25 ++0x1.13031191b1bbbp357 ++-0x1.0ef5a328fd16ep13 ++0x1.725d3352c48d0p-1 ++-0x1.4b4e915a26043p4 ++0x1.14d3f243c8183p21 ++-0x1.0adfb179858e8p-12 ++0x1.2048f1cff6f18p1 ++-0x1.56b496d283959p-2 ++0x1.0ae9d3320c997p1 ++0x1.76b1309a080c2p-1 ++0x1.40edd36c748b1p37 ++0x1.cf356041cb269p20 ++-0x1.2a6e248dc8560p40 ++-0x1.565ee78e2b2e6p-23 ++-0x1.8958f521381a8p1 ++0x1.fd0df44606563p-22 ++-0x1.a9612691423a1p-22 ++-0x1.16bab391b0ce9p13 ++-0x1.0c3ef5c0a4b6ep-13 ++0x1.930b260dda0a5p13 ++0x1.82c01684f4c65p678 ++0x1.2c88b588e9bcap4 ++-0x1.e11bd2ef6de2ep-1 ++0x1.8944d76626ab7p669 ++-0x1.693890da99eb1p708 ++0x1.78b1c579b4d4bp1 ++0x1.745707b19c6c6p-2 ++-0x1.89a741e1dfe7bp23 ++-0x1.d99707ee6300ap8 ++0x1.635006e567dddp168 ++-0x1.37f2423f6167ap0 ++-0x1.736a4513d92c2p-10 ++-0x1.676693b285b0ep584 ++-0x1.8c741522b0a01p15 ++-0x1.34b35744794b8p30 ++-0x1.0d6de0053f3f3p1 ++0x1.e1acd5fefb9f4p551 ++-0x1.288825d0eac71p480 ++0x1.7e1cc30d3316bp25 ++0x1.2b46a2786f662p10 ++-0x1.e35d76793d823p18 ++0x1.b36c0651aa89ap949 ++-0x1.ead715358b740p-1 ++0x1.87c461d4ae342p29 ++-0x1.7582e22ec0fffp682 ++0x1.ccee33c7e403cp-1 ++-0x1.c129832b83460p26 ++-0x1.a73d4529d4d51p-1 ++-0x1.7a9417de1e482p-2 ++-0x1.cfe415b09159fp5 ++0x1.9937b7d8057d3p-25 ++-0x1.1185143f94830p33 ++-0x1.d243651a4c153p41 ++0x1.738c07ff28a5fp33 ++-0x1.8c5de38eee632p1 ++-0x1.c81275f494f57p-1 ++-0x1.9fd4660ed63a1p25 ++0x1.18e380b5f2781p44 ++-0x1.497f37a345aa8p934 ++0x1.0bc797ce995e4p47 ++-0x1.490600f788389p539 ++-0x1.92e3e1c5eb894p4 ++0x1.d6977199168acp335 ++0x1.d06137ede4884p959 ++0x1.b25ac40cef705p432 ++0x1.695eb77a3a499p-1 ++-0x1.7e5900737e9ebp17 ++0x1.639e337b89a9dp238 ++0x1.e967a4713d5a0p43 ++0x1.56f9e4a16d041p346 ++0x1.b90fe0e573bd2p902 ++0x1.8fc2151c3268ap13 ++-0x1.0c5b50a95ef55p-19 ++-0x1.cd09619d8ede1p5 ++0x1.e23a368aeff4bp45 ++0x1.a299d6fc56011p-2 ++-0x1.7946b6c035ce1p6 ++0x1.f0c2d3f3f6809p23 ++-0x1.857651fc6cb0bp22 ++0x1.8b6c9589243edp28 ++0x1.d0063763af7b7p-6 ++0x1.a03a279df3b61p-12 ++-0x1.8f6440dd3a571p15 ++0x1.5702115e3395dp11 ++0x1.753293dcaaa78p0 ++0x1.691ec4d9bd585p165 ++-0x1.b671f3877ed27p0 ++0x1.97af437bbd99bp36 ++0x1.664c00fb70dcap26 ++-0x1.94f1c6757b92ap27 ++0x1.97dd3222f8901p36 ++-0x1.ab2ec50e36b5ap16 ++-0x1.42ab81528cdc5p29 ++0x1.9537a3e475a1bp-1 ++0x1.69ba402842bdfp-2 ++0x1.204fa031269b9p12 ++0x1.acd0117b50401p10 ++-0x1.6f1e24963cba0p24 ++-0x1.3678853a3c342p17 ++-0x1.1c7fc2d0f2645p1 ++-0x1.af8373184d592p-2 ++-0x1.f931f3789237ep3 ++0x1.05b356c5c6808p-10 ++0x1.e49f04420f1a3p0 ++0x1.f535c5c0909a8p198 ++-0x1.82dc21619e2b7p34 ++0x1.479b9359aa14bp35 ++0x1.92d325fbe6eecp11 ++0x1.909ea21f78d00p1 ++0x1.435cd7c1ee887p8 ++-0x1.3a9fc4354363cp44 ++-0x1.00b646dd4b498p10 ++-0x1.11a1e6e51f4f5p115 ++0x1.1a7ac52b21875p-2 ++0x1.e6a8849733aefp-19 ++0x1.6962c39edf43dp25 ++-0x1.ea1d7661b1044p68 ++0x1.0337f102c6521p26 ++-0x1.762915df91144p289 ++0x1.446ae20aa874cp-2 ++0x1.94e331e8c93a0p16 ++-0x1.7c7b439118666p25 ++-0x1.5f8ad60de99e9p6 ++0x1.549137cc746edp-21 ++-0x1.21d9e6074ed97p0 ++-0x1.574861d5d2449p6 ++0x1.331650a915232p11 ++0x1.e646a1f117d41p25 ++0x1.2018d63454393p-2 ++0x1.4cb4c39f91e0dp28 ++-0x1.5dcfb2b00277cp-14 ++0x1.daa065c9d4747p-3 ++-0x1.628af5ece9cb0p-9 ++-0x1.0443e4cad7780p-1 ++-0x1.dedc5001517b5p0 ++-0x1.9605a6741836bp-2 ++-0x1.0eac403d3a375p-8 ++-0x1.907957a46c55dp33 ++-0x1.bdd996400fb39p366 ++0x1.5d60d6c3bc1e3p13 ++-0x1.f684f28967382p-9 ++0x1.d2bc13e424342p0 ++0x1.1306d48e431d2p123 ++0x1.a44ac34907179p254 ++0x1.80a0b504d05cfp46 ++-0x1.c4c130a5a2ab3p4 ++0x1.aa9875a0ad120p42 ++0x1.92f40304c3502p-1 ++-0x1.5a086217bae89p-1 ++-0x1.7f92461fb7863p221 ++0x1.dcaa21c629a7bp20 ++0x1.973c70526c1c4p10 ++-0x1.58f6b3cebb936p0 ++0x1.366af7287b353p26 ++-0x1.a150963ef219bp-13 ++0x1.8dcb25a44c4a5p25 ++-0x1.abb293ca64809p16 ++-0x1.55ce241f8abe8p4 ++0x1.e0113452c0f03p38 ++-0x1.27fc007f4c82bp-1 ++0x1.abcb74a6eeb53p1009 ++0x1.53b0f0bb07b86p14 ++-0x1.54c8141b03f12p36 ++-0x1.0736e6ee73839p30 ++0x1.75f8001aae382p33 ++-0x1.024ad6d77126bp1 ++0x1.57d661a9e1759p778 ++-0x1.28dc4531d726dp-20 ++0x1.34b0271d50e17p1 ++-0x1.13b720a462992p0 ++-0x1.f2dec31d45c7ap0 ++0x1.51ddf26d6dc8fp14 ++0x1.4f8eb36cd79c9p15 ++-0x1.a3eab77c6bc5ap-2 ++0x1.3536c2505e758p24 ++-0x1.a48c91ce6acf6p1 ++-0x1.cfe614d084590p-1 ++-0x1.37c223479d8e5p34 ++0x1.3ab302a5e1187p19 ++-0x1.19bfb39635af3p9 ++0x1.50f1731d7f698p-2 ++-0x1.c5f92281bfc73p35 ++-0x1.f69343f49bb20p13 ++-0x1.82723036a9e57p7 ++0x1.e4ed355b3c00ap-23 ++0x1.7ebd829292355p0 ++0x1.6a20975fc296dp6 ++0x1.814aa1f83ddc5p19 ++-0x1.e9fb42073effdp883 ++0x1.61d877698a956p25 ++0x1.dcc1f7b93cb11p-2 ++0x1.fcbe6062a5d86p-1 ++0x1.b28d50696ad27p44 ++0x1.57bab70bb9f72p-5 ++0x1.f8c9631dd7bebp4 ++-0x1.cd4e077c60321p453 ++0x1.8f7c10d20a751p700 ++-0x1.9e3aa6a16e660p16 ++-0x1.4e1b47763daf8p3 ++-0x1.2039d5a282e43p45 ++0x1.15d7a3ccd36b3p12 ++0x1.b32b804c5c7bbp21 ++0x1.bc2f721362d31p-21 ++-0x1.a77f51d99609ap-2 ++-0x1.78254470e56f2p885 ++0x1.065b616a9cb9ep20 ++0x1.a455362c38b73p17 ++0x1.7cd9012d31cc5p19 ++0x1.f38b658d5c5c8p13 ++0x1.a1d8c7cb3e755p46 ++-0x1.8720419fcf071p861 ++0x1.c9d664de86fa0p11 ++-0x1.3032c7cb3f4f5p20 ++-0x1.4c5cb2dee8a4cp15 ++-0x1.af5bd3377809ep32 ++-0x1.8a3584d35cbb4p3 ++-0x1.5173771549c2cp3 ++0x1.70c313d51072cp6 ++0x1.f6f0b32aae83fp321 ++-0x1.cec9d1bb2b60cp624 ++-0x1.cd421185a053cp-2 ++0x1.7195806a8c89dp23 ++0x1.2ad661d2aa35bp324 ++0x1.72be4126e7236p523 ++0x1.d9a36630b8946p-10 ++0x1.7fa3815765425p19 ++-0x1.70c7d60688adbp-10 ++-0x1.eaa751f3372a5p0 ++0x1.bdeaf5b08c989p-24 ++-0x1.3a9f0155171a9p33 ++0x1.3cdd52c4dc184p0 ++-0x1.1bd7b2d4c4423p-1 ++-0x1.9f5150c2b709ap20 ++-0x1.89d8068abc6f1p842 ++-0x1.ceec2438b810bp21 ++-0x1.a948a503102a9p21 ++-0x1.cf78364f7fc71p27 ++-0x1.08deb24991385p0 ++0x1.70133227579bep-2 ++0x1.6205800dc93f8p0 ++-0x1.4e2a376e6f0e0p721 ++0x1.e30d43adb903bp35 ++0x1.f64210657b93ap12 ++-0x1.28618129a1956p14 ++-0x1.47e9104d7daf9p-1 ++-0x1.a032301a639dcp0 ++0x1.64d8d4817d586p22 ++0x1.bfbe973aefd26p17 ++-0x1.a99ba07350567p196 ++-0x1.8683c572cc281p545 ++0x1.904e746fd5521p26 ++-0x1.1ab434d351229p0 ++0x1.78bb5749ecc74p-24 ++-0x1.5a1f9122af4e0p-1 ++-0x1.0096f76176198p1014 ++-0x1.c374b2142bb05p-23 ++-0x1.14c5717c7ab84p46 ++0x1.304756bf39c0dp26 ++0x1.032157b7ad5b4p12 ++0x1.0167a4376c0c5p404 ++-0x1.2b33e07d94903p815 ++-0x1.0546b04e2f28ep1 ++0x1.4e7a67202b6c7p222 ++-0x1.1569c5f7c9a43p22 ++-0x1.7a4f25a89b8d7p0 ++-0x1.b19b42481db05p7 ++0x1.2fb006b058a81p44 ++0x1.41bb26e7ea591p22 ++0x1.9edc565a8a7ccp750 ++0x1.da4e0046b9d06p9 ++0x1.53b98665e609cp0 ++-0x1.42b700ad8d530p18 ++0x1.1fdfb58958afdp414 ++-0x1.56b4353a278a4p43 ++-0x1.f706a5edd47b4p691 ++0x1.ac72f4f2109fcp59 ++0x1.77e333e16d85dp13 ++0x1.ee51c6871309bp605 ++-0x1.c61080b14654fp0 ++# sin slowest path at 768 bits ++# Implemented in sysdeps/ieee754/dbl-64/sincos32.c ++## name: 768bits ++0.93340582292648832662962377071381 ++2.3328432680770916363144351635128 ++3.7439477503636453548097051680088 ++3.9225160069792437411706487182528 ++4.0711651639931289992091478779912 ++4.7858438478542097982426639646292 ++5.9840767662578002727968851104379 ++-0x1.946913945ef0bp919 ++0x1.1c8780f7a4682p611 ++-0x1.e5baa0e086df7p435 ++0x1.215b6544ccd9dp988 ++-0x1.0400243513f3ep355 ++0x1.af2591e3a6c8dp352 ++-0x1.8469102c2b910p496 ++-0x1.ad614701ebe00p373 ++-0x1.53d895d79f028p79 ++-0x1.c1f47655dbf06p748 ++0x1.955383c0fe4dbp236 ++0x1.fd00b10489e25p1017 ++-0x1.1ac573f72a900p617 ++-0x1.e6c5a2c754d63p668 ++-0x1.c04c06d3c9bb6p169 ++-0x1.6b50c75d0379fp154 ++-0x1.e404e32d17aa6p374 ++-0x1.13f7e64dd059fp981 ++0x1.b83c446cc221fp197 ++-0x1.6884818ec1e2bp34 ++-0x1.efaea6e07ba1ep118 ++-0x1.2f4a042ea2aa5p925 ++-0x1.7f2ce5eec3a1ap435 ++0x1.e099963c33c2ep382 ++-0x1.9e21f646e47e4p72 ++-0x1.1276c444b2602p767 ++-0x1.091891781b177p631 ++0x1.623ba2d6dd62dp940 ++0x1.b41e736053e23p204 ++0x1.0fdab611b5e72p853 ++0x1.e438955b23efap180 ++-0x1.743616457e1abp981 ++0x1.06b554eea34dep70 ++-0x1.83d775bab0aa6p260 ++-0x1.2389541676301p787 ++0x1.ec20d06255fc4p43 ++0x1.f4b9d28ce2dd6p729 ++-0x1.aa5f20f1a2b4ap222 ++0x1.17d374c688e49p844 ++0x1.3adc16a4b2461p173 ++0x1.3b87c3935314ep829 ++-0x1.6c5b05b13f352p661 ++0x1.c76c8671f2d00p207 ++-0x1.a19d949bd5ef8p301 ++-0x1.ff232524cd4f5p699 ++0x1.b23a63ccbf933p429 ++-0x1.260cc706b7092p86 ++-0x1.b4b845158c16fp607 ++-0x1.6b29c047caf4ap1003 ++-0x1.5451e75d6c4e5p93 ++-0x1.1ce9d2b02f8b8p173 ++-0x1.5f9141de74c66p228 ++-0x1.8477c7f84ee2fp795 ++0x1.8c20366e61996p771 ++-0x1.fa14b5d1e2278p929 ++-0x1.7838e2f1f3458p630 ++-0x1.908427a2b2b25p89 ++-0x1.4f35846a0e4f5p906 ++-0x1.6ad7d5bd4f80bp26 ++-0x1.e079761c09377p692 ++0x1.98ac66fb30c7dp342 ++0x1.cfe96007166fdp648 ++0x1.2554008adbf67p470 ++0x1.37c43698bc76cp113 ++0x1.0eb237971695bp629 ++-0x1.dbd26599b0a10p295 ++-0x1.72a877adef21ap763 ++0x1.cb57400936f56p750 ++-0x1.82def1457c813p937 ++0x1.b16f3533cdb98p897 ++0x1.67f3805325585p654 ++-0x1.673ba2ec64800p409 ++-0x1.ce15a75f15e94p464 ++0x1.fa20f59a4d4efp447 ++0x1.4ac8c2d45ccbfp105 ++0x1.a47d934601d32p685 ++0x1.1c4d64b15b946p989 ++-0x1.c8409231e383ap884 ++0x1.1c4ff63867e5ep479 ++-0x1.569bb7635282ep208 ++0x1.27e6e0f904293p386 ++-0x1.8d4e92ca6aaa5p455 ++0x1.0da3b3fbc6164p128 ++-0x1.0808e0778b59fp148 ++0x1.c13a5641139ebp550 ++-0x1.908b307add0ebp662 ++0x1.49eb1291c429ap216 ++0x1.fc58c4ac0478cp86 ++0x1.6a2e33b334902p445 ++0x1.27f611aee303bp387 ++0x1.5ddb515b26a4ap933 ++0x1.437534c005adep412 ++0x1.55de40b98c58bp151 ++-0x1.98d521c355be2p813 ++-0x1.6e04203014222p146 ++0x1.e4d52737fa44fp179 ++-0x1.1e3fa3fb95c37p782 ++-0x1.082555c869c25p980 ++-0x1.1b1e726bdbf7ep429 ++0x1.f475c1183eeb5p844 +diff -urN glibc-2.17-c758a686/benchtests/sqrt-inputs glibc-2.17-c758a686/benchtests/sqrt-inputs +--- glibc-2.17-c758a686/benchtests/sqrt-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/sqrt-inputs 2015-06-20 21:22:16.303457923 -0400 +@@ -0,0 +1,10 @@ ++## args: double ++## ret: double ++## includes: math.h ++0.25 ++0.75 ++2.0 ++4.0 ++2209.0 ++6642.25 ++15190.5625 +diff -urN glibc-2.17-c758a686/benchtests/tanh-inputs glibc-2.17-c758a686/benchtests/tanh-inputs +--- glibc-2.17-c758a686/benchtests/tanh-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/tanh-inputs 2015-06-20 21:22:16.303457923 -0400 +@@ -0,0 +1,203 @@ ++## args: double ++## ret: double ++## includes: math.h ++-0x1.79ea722d33e33p-9 ++-0x1.94d4e0c3df9bcp3 ++-0x1.b63e91ff711e0p0 ++-0x1.299707cfa0a5ap-5 ++-0x1.35ec261f6be52p-19 ++-0x1.d139c624e1f41p-49 ++-0x1.ba38b666e3abap-6 ++-0x1.83f902d2c81afp3 ++-0x1.dc37227180c76p-51 ++-0x1.922cb3b58f124p-3 ++0x1.3579562644365p1 ++0x1.3d52b2702b0dap3 ++-0x1.f7e79460fc57ep-7 ++-0x1.3f96b4611fb28p0 ++-0x1.a82265377c4bbp1 ++-0x1.ced121527ff6ap0 ++0x1.e4e26333b349ep-4 ++0x1.8c5fd0ab12b60p-40 ++0x1.c1b891cbc8f77p0 ++-0x1.223b80efcf234p-33 ++0x1.7184670fd30eep-41 ++-0x1.8a4421ee0d23ap-1 ++-0x1.67e981e763866p-41 ++-0x1.368b80b14c57bp1 ++-0x1.66353498bb0efp-39 ++0x1.1aa8449c2cce7p-18 ++-0x1.d70654bb75b1ep-43 ++0x1.c84f96b02d6f2p2 ++-0x1.f327d6a043438p-9 ++0x1.212b318a2bf91p-49 ++0x1.6253304db0fedp3 ++0x1.ca25248faffc4p-32 ++0x1.d502b71784735p2 ++-0x1.5c6891472b6bdp-29 ++-0x1.c05af046daa21p0 ++-0x1.3f35f7d788487p4 ++0x1.f71314c80ac27p1 ++0x1.ffb1e0c514641p2 ++0x1.cad8c2d932d94p-32 ++-0x1.ff34f15f5e3e6p-3 ++0x1.6156d70921443p-53 ++-0x1.4b5a84c95c083p0 ++0x1.c22fd4b9cc811p3 ++0x1.3fa1e66f4df60p2 ++-0x1.90f3f58afd000p-52 ++0x1.0d16c5632879dp1 ++0x1.421a752ee683cp1 ++-0x1.4b25106b6dd56p3 ++0x1.ac89b6ae063b4p0 ++-0x1.f5a005d7de302p1 ++0x1.263f96335fa00p-25 ++-0x1.81c160ff9fde2p2 ++-0x1.4c0a56228350bp4 ++-0x1.2c2e339d063c9p-47 ++-0x1.b57eb40fc048ep-21 ++-0x1.53a807e326e09p-39 ++0x1.535963f5cea8ap-43 ++-0x1.d049e60c0ecd3p-23 ++-0x1.ad3f8713c45ccp1 ++-0x1.b955931acef5cp-35 ++0x1.480e5368b9fb9p-33 ++0x1.9f8f61aff6da0p-54 ++-0x1.80ed544374dd1p2 ++0x1.0a15b06364b72p-42 ++-0x1.2700a6bd0f1cbp3 ++0x1.8257449cfd281p-42 ++-0x1.a96977ae27fb0p1 ++0x1.0fbf54939b136p-16 ++-0x1.68dc338c13b02p0 ++-0x1.08c49666633fcp1 ++0x1.7112c1edd1600p1 ++0x1.45aa62e647503p-13 ++0x1.24318616e191cp1 ++0x1.2712f5e21b96ap-52 ++0x1.cd76975043db0p-32 ++0x1.9ab2842033f1fp-15 ++0x1.9cf3279d8ff3ep-21 ++0x1.dccc3241d912ep-48 ++-0x1.b2a4e543a5268p0 ++-0x1.9802a51e2fa5ap0 ++0x1.3da4954669e1fp-27 ++-0x1.d4670486ae6c5p-50 ++0x1.12d690cf283ebp-25 ++0x1.34763296811bdp-39 ++-0x1.2f5427f0973cdp1 ++-0x1.44a7f0d39a7cbp-18 ++0x1.c954869657fd0p-45 ++0x1.c99220da8d555p3 ++0x1.a067b10753d0cp2 ++-0x1.4cfdd35756bc5p-10 ++0x1.5090825895bd5p-43 ++0x1.bbbc049609e09p-34 ++-0x1.d79730d4df424p1 ++0x1.4aeba21a72c73p-11 ++0x1.72115177d9511p2 ++-0x1.3a4015774746fp3 ++0x1.555713307b9b4p-37 ++0x1.a877a7a5a6963p-46 ++0x1.ba8ad1105bb80p-6 ++0x1.e500b2666c494p0 ++-0x1.7c7801ef98594p1 ++-0x1.89c34195ab10dp-21 ++-0x1.9653b765a54c3p1 ++0x1.cbc5464770c96p1 ++0x1.80dd335890daap-29 ++0x1.a88610813e760p-35 ++0x1.3bf7077dcaeb2p1 ++-0x1.58fc25c99925ep-51 ++0x1.99f184fd14ba6p-37 ++0x1.a5c077f3ec9fbp3 ++0x1.1676a1bd6d7fdp-31 ++-0x1.151f61d509024p0 ++-0x1.82b1234ed4accp-21 ++-0x1.9c78a7464a06ap2 ++0x1.81db55fe7d6a8p0 ++-0x1.403546a25090dp3 ++-0x1.884175facb7a0p-5 ++-0x1.8cd807cf97147p2 ++0x1.28b7d3631da7ap-16 ++-0x1.dbdfc6a3b7a56p3 ++-0x1.93ca444439063p2 ++-0x1.863014637e6b2p-40 ++0x1.6f0606cba779fp-48 ++0x1.e4bb004a92da3p0 ++0x1.4e7cd59b97811p-22 ++0x1.d82513d934824p0 ++0x1.08ea668aed516p-4 ++-0x1.4eb052c08e36ep3 ++-0x1.947540f62626bp-38 ++-0x1.9d4c17b3aa3e3p-18 ++0x1.ffdc334c6a7a3p3 ++-0x1.f01e851ab2990p-45 ++-0x1.040ac02963464p-37 ++0x1.deca67ef259e8p3 ++0x1.7ea616ef23425p-31 ++-0x1.5ad5526a35b13p1 ++-0x1.18477773e1136p2 ++-0x1.da68368e73652p1 ++0x1.d47856d151708p-32 ++-0x1.8dff62e84740bp2 ++0x1.512c92bc3fd5ap-42 ++0x1.0d46e50f3e34bp-38 ++-0x1.f2cba4b66f7aep3 ++-0x1.1bd6063435779p1 ++-0x1.314a92dc0593ap1 ++0x1.78e992e23299dp3 ++0x1.547ba4fcc9d15p1 ++-0x1.10b63582d5e5fp1 ++0x1.2bc994ee38c37p-3 ++-0x1.8edd86fbebfb1p3 ++-0x1.0f5bf4ace5c69p-54 ++0x1.e38d83d2c8025p-43 ++-0x1.9c31372efb7c2p-25 ++-0x1.01ea8256aa697p3 ++0x1.b68125750b075p-9 ++-0x1.49f40645faf47p0 ++-0x1.72a777e07e732p-8 ++0x1.198ea0f0d15eep1 ++-0x1.ecc6037c6538ap-21 ++-0x1.e649c0259ccc7p3 ++0x1.06f1640c8e2a4p0 ++-0x1.693d851f3cfeep-10 ++-0x1.0087454a6db2ep1 ++-0x1.05519085ee41cp-51 ++-0x1.df8af593c9a6dp2 ++-0x1.fa5552ca0ed82p-13 ++0x1.5d5fa0d6d5003p-9 ++0x1.726ff56109b1fp2 ++-0x1.17fe022e20687p2 ++0x1.261da31e2fd34p-35 ++-0x1.55b5028331f05p1 ++-0x1.5b3682390c9a9p2 ++-0x1.2e7715356184dp-16 ++0x1.5be03400eeeb7p0 ++-0x1.b530c329abc95p2 ++0x1.b3c9837089937p-50 ++0x1.9286b5e44023fp3 ++0x1.106137779070bp2 ++0x1.df2ad20740b3dp-26 ++-0x1.1ae7653a10472p4 ++0x1.1cecd7b22c032p4 ++0x1.e16190519649ep-48 ++-0x1.43ad33cd63d71p3 ++0x1.f978d68c76a16p2 ++0x1.340975e58a8a7p2 ++0x1.2ca3d4cef3844p3 ++-0x1.75fb149690f20p0 ++0x1.1c6be31b1d0b9p4 ++0x1.1b54873bb0292p0 ++-0x1.73c327f48e34fp-33 ++0x1.0e0354caf6818p-54 ++-0x1.168b022d669ccp1 ++-0x1.816c547ac8d97p-45 ++-0x1.ee86709f7750bp2 ++-0x1.137d50ed8e775p1 ++0x1.094c253414b65p-22 ++0x1.87a6a3e8c8b4fp-37 ++0x1.9c4674b85fc58p-9 ++0x1.2ba8d7d38efa2p-43 ++0x1.35e7234d9a485p4 +diff -urN glibc-2.17-c758a686/benchtests/tan-inputs glibc-2.17-c758a686/benchtests/tan-inputs +--- glibc-2.17-c758a686/benchtests/tan-inputs 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/benchtests/tan-inputs 2015-06-20 21:22:16.304457892 -0400 +@@ -0,0 +1,3456 @@ ++## args: double ++## ret: double ++## includes: math.h ++-0x1.8223b3a325943p573 ++0x1.a8a424675610fp845 ++0x1.923370ded0653p554 ++-0x1.759b34bb0cfdbp553 ++-0x1.a390469582e59p924 ++-0x1.cd9252152d901p462 ++-0x1.e2d1d2e34fd97p568 ++-0x1.b59d71a85565ep-15 ++-0x1.be1224d8f2474p629 ++-0x1.327c5786c74fbp559 ++0x1.75e1260927766p519 ++-0x1.d1ae866714e99p662 ++0x1.a086249ef7bb6p159 ++-0x1.008130223996dp463 ++-0x1.f77636d051905p336 ++0x1.dfed4714271cdp574 ++0x1.7204451a9cfdfp372 ++-0x1.31ab43b06eac7p703 ++0x1.4866b5a4dfafdp978 ++-0x1.cf2ba523a76c6p815 ++-0x1.25bc94b7d96b8p604 ++-0x1.b986e7275d085p225 ++-0x1.8d4ed15015b22p740 ++-0x1.58d231c6a5340p390 ++0x1.5f14b443ceb0fp0 ++0x1.40ae43729ddcap969 ++-0x1.d4e9674fd10a8p528 ++0x1.24d8e4308a916p413 ++-0x1.b143609970b27p101 ++0x1.b609b67cc8c6fp974 ++-0x1.8fc291f86553fp171 ++0x1.b24a7238fb771p275 ++-0x1.cde032076fb81p545 ++0x1.bbb5f22a04b44p794 ++0x1.5bdaf73cb6febp803 ++-0x1.58c180ec8edecp408 ++0x1.b5e6345064274p152 ++-0x1.83bd627132077p50 ++-0x1.bb46e4e6e61a0p585 ++0x1.bb9757f54f100p733 ++0x1.c55d070f0ac5fp438 ++0x1.3476a63166a0ep648 ++-0x1.a15f134f42095p828 ++-0x1.32e840e69acadp392 ++-0x1.bf17857e50b11p559 ++0x1.f73021afd46e7p407 ++0x1.9f00e7f88fb55p775 ++0x1.f64fe31245205p510 ++-0x1.857c82089e8dbp933 ++-0x1.e7c0240150699p244 ++0x1.85f1e1ff46b97p607 ++-0x1.8ac482283b408p507 ++0x1.655985eb933b4p332 ++-0x1.6e7ad10117706p577 ++-0x1.9f9b018c5a565p944 ++0x1.e15694711c05bp690 ++0x1.623803fd581a2p555 ++-0x1.58f8b25bde0c0p477 ++-0x1.e019f3e23ca4fp648 ++-0x1.6f1b061695e57p6 ++-0x1.c4e4506f6c270p698 ++-0x1.9249404f2bd69p-12 ++0x1.f6df00b66684ap227 ++-0x1.0a5ff4bbd59fap973 ++-0x1.783723759a83fp66 ++-0x1.f21b84834aef7p246 ++-0x1.8e49927eadea1p587 ++-0x1.eca7d45f5234dp631 ++0x1.41b1c5ef9873cp95 ++0x1.d449a6e011e9ep107 ++-0x1.7caa53d604056p443 ++0x1.7288a5f18c0aep556 ++0x1.8d7ba3b2300e6p183 ++-0x1.1747478ffe5b4p148 ++-0x1.769a84af31c8ap851 ++-0x1.e41b6039c9d89p23 ++-0x1.273bf4a49e223p408 ++-0x1.2d74708a8d553p7 ++-0x1.71a9314bbf5abp11 ++0x1.63c804f1dcb3bp654 ++0x1.a81bb1a86a2f5p368 ++-0x1.bbb1d0d267af6p679 ++0x1.574264e94bcacp646 ++-0x1.1ee57113a55bbp916 ++-0x1.e043311b22e8ap45 ++-0x1.2fd7c5340e069p842 ++-0x1.2faa426020fadp642 ++-0x1.92507362ad808p175 ++-0x1.9318c5c281337p897 ++-0x1.aeada555a018ep178 ++0x1.04d4f6535e33fp367 ++-0x1.e49b378f96eb8p749 ++-0x1.064e801d2dc83p75 ++-0x1.64deb34cefc2fp403 ++0x1.6d2e677f31896p467 ++-0x1.466ac0cf4dd29p746 ++-0x1.609c83df01cf5p137 ++0x1.d960e2cbe66a9p449 ++-0x1.602bd715ecb91p46 ++-0x1.b0af218f7c6a5p629 ++-0x1.21a921acce2fdp22 ++-0x1.f83004121d518p837 ++0x1.4ca7a2fb63bc5p156 ++0x1.191295449db9bp54 ++0x1.c9bd7171fde58p949 ++-0x1.e4162302d0c20p397 ++0x1.077f42760d255p258 ++0x1.a3b173403bf03p644 ++-0x1.c9ff841ec836dp889 ++0x1.acf92502f5b3cp624 ++-0x1.b8c23518af5e3p508 ++-0x1.88e416ff6ad6dp268 ++0x1.6280e7b9872b9p807 ++-0x1.7cd6b732512b1p212 ++-0x1.67ee930f4dcfcp388 ++0x1.64f4659e0b759p93 ++0x1.6cfa374d378c3p788 ++0x1.c1082531b7386p261 ++-0x1.b8d1e18e1c2ccp953 ++-0x1.46d403df71732p268 ++0x1.07f2566a38fafp589 ++-0x1.cb5ed766d06c9p356 ++0x1.64e9c5f032a8bp358 ++-0x1.a81485a8eb7a9p15 ++-0x1.29d6113c439ffp960 ++0x1.46f14425dfb7cp-22 ++-0x1.46d884db8e124p760 ++0x1.b6b2023f59712p442 ++-0x1.f8fea40ac8ffep855 ++-0x1.d363d57ed5fe2p800 ++0x1.385f65d4ccb30p812 ++-0x1.b13d912fc1851p600 ++-0x1.189687400f8b5p930 ++-0x1.3359b450bf3bfp285 ++-0x1.64d114ac159fep767 ++-0x1.9bc8e4afa247fp213 ++0x1.1299f68a1c892p327 ++0x1.8bca15f2a63b3p771 ++0x1.92d6366b40cd5p704 ++-0x1.c7cbe0307540ap1005 ++0x1.d2bfc0eb2f0f9p665 ++0x1.788336461cdf9p887 ++0x1.64c99758893dbp728 ++0x1.364825de23c96p378 ++-0x1.033600f7ce301p531 ++-0x1.34862202e7ecap256 ++0x1.6a6f4552a83b5p949 ++-0x1.a55017d2ab992p179 ++-0x1.a70fc12d64d86p591 ++-0x1.7f00f4d75d44fp563 ++-0x1.58a4c1d691cb1p209 ++0x1.37a2726f0d414p445 ++0x1.b7c3035071ef7p459 ++-0x1.3c5d37b781aecp256 ++0x1.a979508d7bd0dp576 ++0x1.708213f2fd915p528 ++-0x1.2054b2257c924p889 ++-0x1.0446b4b20cd97p573 ++0x1.9cba327cc49c7p207 ++0x1.f14ce310e4517p147 ++-0x1.8e4313d57243bp405 ++0x1.32f131e4e2c5dp-7 ++0x1.7b7d4171a5b89p761 ++-0x1.768b96404272dp319 ++0x1.e389677da758ap725 ++-0x1.f7f1270f6df26p963 ++0x1.97bd878c7b4e3p597 ++-0x1.b35ac52109914p372 ++0x1.86a351193c827p418 ++0x1.c78c9454775e2p325 ++-0x1.f7093192ede9bp819 ++-0x1.8f7823d7fe58fp200 ++-0x1.2068039af64a2p944 ++0x1.95a951ef8e07ap424 ++0x1.98b5776341626p241 ++-0x1.661af6c71f830p275 ++-0x1.bded24148bf8fp265 ++-0x1.da06d35c1e049p352 ++0x1.50c4c103b3adep946 ++-0x1.d89fc3a1a0038p683 ++0x1.e01904f9e518bp65 ++-0x1.904ac477905adp21 ++-0x1.566ae646625edp938 ++0x1.3fec71e5f5cbcp514 ++-0x1.88db248db4dbfp865 ++-0x1.5dc2c3388d7bbp213 ++-0x1.b5ac97796d94cp400 ++-0x1.7bbad1b8269a2p305 ++0x1.2115275214bf2p809 ++-0x1.b6727037ce307p726 ++0x1.983327e1249b5p120 ++-0x1.d10951541ff1fp728 ++-0x1.4f84e0b4a8cd1p28 ++0x1.0dbc3589068fdp241 ++0x1.1e9a9359bb743p399 ++0x1.a923364cdc026p924 ++-0x1.20ab54a355b5ap996 ++-0x1.90c1f77a05003p285 ++-0x1.2772c2d8adf26p15 ++-0x1.d75d54bd7efd8p221 ++0x1.5d0352b2cac14p335 ++0x1.92297454b3ba4p203 ++-0x1.e74193f05cdd7p411 ++0x1.e526b6137b06ep800 ++0x1.e99bb5f69bb23p558 ++-0x1.12fb97edc8ef7p509 ++0x1.93f9f4c363c48p114 ++-0x1.7da8c406ad9edp290 ++-0x1.681230393be1dp694 ++-0x1.c8ec5071ed259p771 ++-0x1.1010810f5ddd5p158 ++0x1.c74a81bf3dfe1p502 ++0x1.1a36b350bffb4p326 ++0x1.9997153de8d50p936 ++-0x1.2a4b83a44adb1p262 ++0x1.143135a73f62dp112 ++-0x1.a9fb66d704d20p924 ++0x1.52ad267e9e691p941 ++-0x1.960237aa0b476p456 ++-0x1.86f60247145c7p1002 ++-0x1.40fc032059f50p822 ++0x1.36e3e02584408p699 ++-0x1.19f154949871bp690 ++0x1.955050762de4dp982 ++0x1.da92c16dc3379p408 ++-0x1.7db2843ebc2e9p106 ++-0x1.5ed053da6629fp251 ++0x1.7a438137d5cf5p379 ++0x1.848bf06d16cb5p742 ++-0x1.10c327274daf3p243 ++0x1.e7d565d867a08p675 ++-0x1.fe4a75adfcf0ep507 ++-0x1.27ffc345d783ap83 ++0x1.7505c7af55362p582 ++0x1.e91a6585b3efep39 ++-0x1.c3f6c7813dc77p258 ++0x1.aa1a94fbb80afp391 ++-0x1.f91010d34d5a1p575 ++-0x1.d1c5e776352f8p81 ++-0x1.42ed75713379fp760 ++-0x1.443db008d07f8p671 ++-0x1.62b031d37d269p872 ++-0x1.e74ca5fa66410p11 ++-0x1.24c032fc2a37cp54 ++0x1.b10d0082d4525p430 ++-0x1.52a7436543c32p449 ++0x1.80de825c86b09p478 ++0x1.aeb2530eace81p186 ++-0x1.069422760f985p379 ++0x1.d254b2b61ba52p468 ++0x1.859f00c1dfdb4p946 ++0x1.b77c51fdbe932p801 ++-0x1.d84b803d9a2a9p653 ++0x1.fdeee09bb33b3p522 ++-0x1.977296b455844p588 ++-0x1.4da2b665db234p110 ++0x1.6e4656ff0b546p687 ++-0x1.427ef58be39fep749 ++0x1.5458b4f78e18bp1020 ++0x1.dbf6b5a443ad8p63 ++0x1.fabc4531c35d3p786 ++0x1.750be012c6154p365 ++0x1.d406b5ad76da9p348 ++-0x1.136ac7e63a7a4p852 ++0x1.f38d97e18ed30p770 ++-0x1.86eb94206ac9bp845 ++-0x1.9fd97758ea039p519 ++0x1.57e104a418329p842 ++-0x1.f47a53b612eedp131 ++-0x1.8c7f907591c6ep317 ++-0x1.7797a7c218b28p683 ++0x1.a65d35c8b88bfp445 ++0x1.e2eb60871eb89p30 ++0x1.569f174caec6bp914 ++-0x1.b83cc28d283bdp-9 ++0x1.4e3625ca8ae68p798 ++-0x1.5b0a1690ba66cp1010 ++-0x1.b964703464db3p516 ++0x1.594d72f510320p234 ++0x1.e0fd20fb450c9p195 ++-0x1.4c71468889a23p828 ++-0x1.b0550500c4f1ap615 ++-0x1.0660b078d6f3ep275 ++0x1.1aea54022a7c9p566 ++0x1.944f35657817bp909 ++-0x1.b918b7742beb2p620 ++0x1.30c8214b4ebd4p1003 ++0x1.b4b1127df81bbp636 ++0x1.499bc35bdb268p230 ++0x1.239303c6019cep75 ++-0x1.2ddf17942d7abp335 ++-0x1.c1cd51bb6ef20p219 ++0x1.317ef522313edp576 ++0x1.6622455a81f5ap165 ++0x1.a7cd35a9a03cfp611 ++0x1.55f8a593d1051p681 ++-0x1.8ac0e40f85b62p207 ++0x1.339c053ef2e4fp974 ++0x1.07bac767e2915p807 ++0x1.0572243093b94p336 ++-0x1.7e6d32d8e9b1fp573 ++0x1.05f97096a8c08p301 ++0x1.a0f3f063dc5c8p319 ++0x1.079d71aaef5c9p133 ++0x1.aae49653bc771p-9 ++-0x1.de13b5b4f8b8bp779 ++0x1.ed07835644d79p859 ++-0x1.86ae6094e5cb8p640 ++0x1.f45d03d3167a8p44 ++-0x1.1c9161ed1811ap657 ++0x1.ba5ae0f7f6255p730 ++0x1.3dc4917e05df6p199 ++-0x1.637eb2e09fc81p-20 ++-0x1.35c8010ca51abp558 ++0x1.46b46213d42d3p263 ++0x1.e82bb7d6f0966p439 ++-0x1.4a5335f72040ep748 ++-0x1.9150364d7a3e8p521 ++0x1.811436d27e101p345 ++0x1.1e6fd3d8c4c47p24 ++-0x1.d3dd14d8c8a72p195 ++0x1.7f6fa7878270ep615 ++0x1.0e23f7c6192b9p883 ++-0x1.64fb914120bf9p181 ++-0x1.5b9b402c6b12dp216 ++-0x1.67072619357dfp556 ++0x1.cb6d523053edcp116 ++0x1.0400b6f327cadp209 ++-0x1.cb1c2559a73a8p538 ++-0x1.0832e6f8f9389p562 ++-0x1.e237659a26998p113 ++-0x1.d390a323282adp250 ++-0x1.2abb75708ac0ep1000 ++0x1.93bcf2432f778p707 ++0x1.bbdbe0f57dba0p780 ++0x1.9ce4a245e8487p56 ++-0x1.f65290202bc33p297 ++0x1.2286377c2a7bep402 ++-0x1.25ba94a2a1b39p23 ++-0x1.7e7034f66b646p226 ++0x1.dfd3921f61b6fp865 ++0x1.8e77026d1dd42p947 ++-0x1.259a210ae8dbbp883 ++-0x1.ff947770042f4p50 ++-0x1.b11b83cbe34a6p138 ++-0x1.ed02f523ba5fap948 ++0x1.fae0c20538cfdp378 ++-0x1.f106f16618a36p390 ++0x1.12f06118a71a6p435 ++0x1.f459e36013ac6p193 ++-0x1.b71e601c8937ep647 ++0x1.741dd54a711bap303 ++-0x1.5fd0806197195p648 ++0x1.c08a364cba1c4p476 ++-0x1.0fae377d13b6bp376 ++-0x1.284b125539b1bp740 ++0x1.1b26509b3d375p643 ++-0x1.b3d3e132b5f3ep409 ++0x1.f5e2c4a09c6f3p579 ++-0x1.27c3958127ffcp568 ++0x1.3d88f5ed5e951p522 ++0x1.9f271783e03d7p573 ++-0x1.e470858d1dc67p587 ++0x1.cb625701aabb5p297 ++-0x1.583541c8ef4a9p519 ++-0x1.cff7a379366fdp449 ++0x1.ff5284d44492bp734 ++-0x1.36bec43199ee1p-24 ++0x1.21c7f78d864fep503 ++0x1.e84e55708a34cp1003 ++-0x1.bc6db2028ef2dp357 ++-0x1.03dc7515aba2fp362 ++0x1.d36d2291f6b57p427 ++-0x1.6b09f585f9193p808 ++-0x1.9c94e5c6b368fp214 ++-0x1.b637e724f9976p589 ++0x1.c782220738d46p18 ++-0x1.55e0e443747ecp298 ++-0x1.ae36671f9deb3p951 ++-0x1.ab18e77da892bp237 ++-0x1.b8214411e595cp533 ++-0x1.905e068e442f4p539 ++-0x1.9dac66939446bp803 ++-0x1.30d441b8ea8f2p401 ++0x1.2023c219ba756p306 ++0x1.9b83c3efed8c5p14 ++-0x1.3f0ef3440cb1ap1000 ++0x1.fe50609963492p823 ++-0x1.b29653a0b816dp53 ++0x1.3cb0a7690e4f5p279 ++-0x1.3bfba620e087ap429 ++-0x1.82e784a2946a4p187 ++-0x1.f2a2a27a31febp659 ++-0x1.1f6e730cbc7f3p330 ++0x1.232570e622955p1006 ++0x1.815d92a977bc4p742 ++-0x1.afefb62db66b2p361 ++-0x1.393f51c4b001fp-21 ++0x1.2e0a56d573c24p551 ++-0x1.85c9e0d20fc03p13 ++-0x1.ddf8e355bc110p27 ++-0x1.c421925083f29p63 ++-0x1.477b658be3782p332 ++-0x1.dfa7e1f25247bp101 ++-0x1.0ef1e0f8a34ebp836 ++-0x1.9736b5b40d3a6p328 ++-0x1.fc2130e5cb2ddp72 ++0x1.cb19b23ae4117p87 ++0x1.5e908222450d6p683 ++0x1.83d3300fda787p465 ++-0x1.1f75315eae92cp312 ++-0x1.4f87c66f9c24bp218 ++-0x1.20a0c7bb5ab06p713 ++-0x1.4379a08c0b472p507 ++-0x1.37c013509290bp25 ++0x1.30733493bc82ap796 ++0x1.451a0144b107fp12 ++0x1.d3b5609052753p696 ++-0x1.baded35e9b11fp215 ++-0x1.9010f587e1588p838 ++0x1.0e02515adc0f5p656 ++-0x1.786204df84f7ap400 ++0x1.cd5976e18d08ap562 ++0x1.a3b8b07edd8a5p695 ++0x1.272c360b4a09cp240 ++0x1.c76272882f071p807 ++-0x1.05a6b23f98b31p854 ++-0x1.309684da428b4p519 ++-0x1.b0b45682b1411p156 ++0x1.16d122510e170p482 ++0x1.d219a347bf3b0p121 ++0x1.76ddc05352dfep610 ++0x1.2f8b83aa236f5p634 ++-0x1.bff5136871c7cp321 ++-0x1.449411e1a1534p786 ++-0x1.6b9964e711a38p523 ++0x1.610080e646a92p572 ++-0x1.5a2035384b325p183 ++0x1.2f15b33162e14p520 ++0x1.5edd45422f82ep694 ++0x1.adc571bdc2896p1021 ++0x1.11ede09781861p818 ++-0x1.384970657fe1cp731 ++-0x1.b93df7e5ba775p747 ++-0x1.80e8650f78da7p617 ++-0x1.ceac833c51ddfp745 ++0x1.6531a38ced12cp46 ++0x1.91fb517112447p535 ++0x1.52a4566db4283p745 ++0x1.dc0275f484b73p935 ++-0x1.a14ae7206183fp724 ++-0x1.b3dcb3a37ca8cp-6 ++-0x1.e79600282da96p149 ++0x1.b8758421e1862p507 ++-0x1.2547846b083e9p-6 ++-0x1.84e3629cbab35p361 ++-0x1.c716339c7bd00p830 ++0x1.d39d1592b1957p616 ++-0x1.c416c32a4efa9p963 ++-0x1.c966d274ac272p421 ++-0x1.39623033efda7p13 ++-0x1.47b562fb33e7ap61 ++-0x1.908e8784678e6p615 ++0x1.90b9900e518b3p163 ++0x1.836e560de08e8p164 ++0x1.772670b0b8d27p226 ++0x1.7fd2e348de960p918 ++-0x1.3cd1201cba22fp198 ++-0x1.a7dbd2320565cp159 ++0x1.ca98f6aef3966p325 ++-0x1.d0c1a2329035bp2 ++-0x1.c0d31445503d7p530 ++0x1.c4b027bbc1746p567 ++0x1.32341565ed07ep159 ++-0x1.8c7b4695abfe2p513 ++-0x1.4578608c13f56p-22 ++0x1.5bab8379ff00cp49 ++0x1.306e7570eda77p869 ++0x1.732110fa64bafp393 ++-0x1.1146f698db29bp160 ++0x1.6885a0cfa919ap211 ++0x1.714b252420ac9p858 ++-0x1.486b66411fe7ap398 ++0x1.18421057ffa6ep237 ++-0x1.e731c4f710eddp197 ++0x1.7cff352552c84p37 ++-0x1.6abf14aa70dacp746 ++-0x1.f29b55bb8fe31p416 ++0x1.a77473515adf8p195 ++-0x1.4922814b5a637p498 ++-0x1.9ce303b95ccc7p511 ++-0x1.fc646726a5f20p951 ++-0x1.21eac2c21fe54p113 ++-0x1.e4e213df08c2ap265 ++-0x1.887dd5a85818ep912 ++-0x1.bbb2171b888c8p103 ++0x1.8b34a46c873c2p501 ++0x1.70e367db79ea0p241 ++0x1.7ce0039ed7da4p808 ++-0x1.c7fc26380f6c6p101 ++0x1.18c360c75aad0p234 ++0x1.fee2f67629486p962 ++0x1.a4d7a588fe8bbp-3 ++0x1.570291341d887p437 ++-0x1.a10e9531b0df8p337 ++-0x1.ca6825fbb4bf7p602 ++-0x1.c8d000ca12af8p113 ++0x1.b74a232faf0c9p-10 ++0x1.1dfd417243258p88 ++0x1.c755e373bd292p806 ++-0x1.3124b71499691p1020 ++0x1.a84680e1992ccp483 ++0x1.c5b2c448b0259p534 ++0x1.c54e340119590p56 ++0x1.42d4e3fc4a7dbp943 ++-0x1.6f81959716f0ep600 ++0x1.38fac2222482ap313 ++0x1.aa4840527639dp-25 ++0x1.9ad706bfe85f3p1020 ++0x1.2f2da18ecac33p825 ++0x1.6ee875bc8e577p747 ++0x1.da3412d07c978p387 ++0x1.cd8e14f3d97dep105 ++0x1.cd6cc00d3cff1p360 ++-0x1.f7bd4156bade4p679 ++0x1.9d89611d9047ep925 ++-0x1.2b41b1691def0p18 ++-0x1.806210fa000dfp258 ++-0x1.2f49e07812d94p116 ++0x1.339605b7fab92p1020 ++-0x1.0c09f7db12243p891 ++-0x1.81a2a42a061d3p903 ++0x1.a791057d419b5p888 ++0x1.581315b6920c6p-21 ++-0x1.c5f64504ae5f4p791 ++0x1.8982e6ced130fp227 ++-0x1.d0db364678c1fp12 ++0x1.43aa32552d958p657 ++0x1.899c234387f3ap633 ++-0x1.41470481079e0p614 ++-0x1.2aa723c52c3c4p920 ++-0x1.bcede1fa49331p512 ++-0x1.f37ac77972cdap-18 ++-0x1.e22c64e877035p779 ++0x1.754480a7b3bf9p898 ++0x1.6ae1a66d4b83dp6 ++-0x1.90c107ffacd38p913 ++0x1.b9381618da422p371 ++0x1.a981920976fa2p680 ++0x1.3a6ec4b57bc2ap15 ++-0x1.28dcc1f6d20bdp108 ++0x1.4326147c15728p335 ++-0x1.2259a0e73e4f4p122 ++-0x1.11cc764de91bbp18 ++0x1.f481816abfcb9p72 ++-0x1.c1d2d049ee85fp-23 ++0x1.61e4d0a08bebdp12 ++0x1.d86ed0f586a17p516 ++0x1.b100560d69d98p432 ++-0x1.50b8331476685p30 ++0x1.9f32c7425b9f6p739 ++-0x1.d89d2066c2887p0 ++-0x1.61ee079dde498p465 ++-0x1.3602968762b9ap32 ++0x1.4c2c9725ac92ep-20 ++-0x1.3a0d7321c02abp108 ++-0x1.b1325468e8fdbp781 ++-0x1.613d634860a5cp756 ++0x1.41f616b0ffe33p752 ++-0x1.61a3765afebf9p788 ++-0x1.538be659aab9ap199 ++0x1.da3661b9d7828p8 ++-0x1.76e835de4916dp-21 ++0x1.83db501e98db6p965 ++0x1.184bd1b938793p927 ++-0x1.6352b0ec9b3bbp851 ++-0x1.e00891c81db9fp966 ++0x1.6d2bc0bc2c25fp29 ++0x1.16f205d5ea0efp341 ++-0x1.222b02360aa21p423 ++-0x1.c43fc00ad0827p175 ++0x1.4a9da6ed14181p96 ++0x1.742f7252b3888p-24 ++0x1.e3a1434f237eap-6 ++0x1.788f015a48ed8p487 ++0x1.fdd0a707a7b24p120 ++0x1.bab124b6990f7p10 ++0x1.c8ffe2cf83b94p755 ++0x1.2372c778a1441p348 ++0x1.612b072d760cbp958 ++0x1.609f218942867p274 ++0x1.0483c3df44e59p24 ++-0x1.6f1a40a16d5e7p406 ++-0x1.784bf15a26f31p173 ++-0x1.7fd4e7bec6056p611 ++-0x1.c478c30401e95p33 ++0x1.0bbaf1e77d127p947 ++-0x1.0e6da7540b809p122 ++-0x1.47a8d09dbc89ap895 ++0x1.bc06021871563p927 ++-0x1.f89bc1de14148p464 ++0x1.98a2f4afe66b7p674 ++0x1.5f0bb5633b7dbp833 ++-0x1.8ce676f64c1f2p25 ++-0x1.4c8a51a1b0cbap555 ++-0x1.8210c69bcd3f0p26 ++-0x1.0b4731be2b020p855 ++0x1.73d857da7baa2p23 ++0x1.01075749d6fc6p689 ++-0x1.112e67981aa71p146 ++0x1.b01dd2c3cacd8p793 ++-0x1.cd5737ff4c257p433 ++-0x1.3e519196e9292p729 ++0x1.5b65b0284bd0dp839 ++-0x1.1c4762b976c53p-10 ++0x1.794245506f756p32 ++-0x1.4e1c35958207bp707 ++0x1.c3913360602d8p800 ++0x1.83f2621884b92p26 ++0x1.c069f020301dcp328 ++0x1.b27b85f417892p184 ++0x1.e004a34aff785p750 ++0x1.29fc70b6808adp70 ++0x1.2ec1a69b905fcp919 ++0x1.df6a235533225p599 ++0x1.438a2370d9eebp231 ++-0x1.dddd767c99337p889 ++0x1.0568d154a2870p18 ++-0x1.3363041710f4ap216 ++-0x1.64eb7482628abp653 ++-0x1.3772b3ab575c6p0 ++-0x1.1bdee549c535bp184 ++0x1.d556148c8ea18p820 ++0x1.6d31247f5cf60p84 ++0x1.aec7658e1d55ep-7 ++-0x1.df40a65c08fd9p16 ++-0x1.359021a96067ep851 ++-0x1.47ef93788827ep585 ++-0x1.d9a6960c12269p688 ++0x1.67a8b27b1b917p158 ++-0x1.d6d2a6399e8d2p292 ++0x1.431a4325d3651p320 ++0x1.b274e747ec490p365 ++0x1.d042571362911p3 ++0x1.3ffff11ae8155p254 ++-0x1.ea8cf38a078e5p25 ++-0x1.da1f81d728183p288 ++-0x1.d2f442f6baea0p3 ++-0x1.1125e418910dbp22 ++0x1.e28ee7f211bc6p608 ++-0x1.c7b590b383ae1p490 ++-0x1.ec07032c9fe8ap417 ++-0x1.2f82b55eebd81p266 ++-0x1.2d0c72c2a6eaap3 ++0x1.7654c41150714p-8 ++-0x1.cb7ba6fe71addp17 ++-0x1.ea76b17ba5274p1 ++-0x1.cee634f158cf0p478 ++0x1.9389c0f24345cp-5 ++0x1.ff0ab7bfdc77ep0 ++-0x1.5a2a9634b735ep118 ++0x1.a99a656f9766fp9 ++0x1.25e6b6c33e77ap760 ++0x1.5c07b3fdfc784p24 ++0x1.659bd21884363p21 ++0x1.a1e2d2a599b2cp-2 ++-0x1.b669c6b9ff4eap954 ++-0x1.227fe1b1d363dp375 ++-0x1.9d8815914355cp23 ++0x1.08f9c73e5d0b1p58 ++0x1.06ebc1e205a69p11 ++-0x1.c475c33c6e4d9p419 ++0x1.26e2f03c3b568p952 ++0x1.142e653198e2ap876 ++0x1.a17610c798c44p385 ++-0x1.5d25b7f4ed01ap784 ++-0x1.553e05b0c2d7fp1 ++0x1.ac28301a1a99dp-5 ++0x1.1e2830cae9f10p585 ++-0x1.89ecf76a7976bp784 ++-0x1.36a6c7f575816p91 ++-0x1.3290c1e3ab0fap439 ++0x1.571f2024af517p407 ++-0x1.9e9f16af2b7f2p-19 ++0x1.547107a4abf1ap556 ++0x1.8d9bb18e74c7fp327 ++0x1.6bf844726431dp79 ++0x1.6882c40a36829p521 ++0x1.5e33a37495769p499 ++0x1.aa1c25076a0c0p54 ++0x1.af11a32c8711cp844 ++0x1.842ef2865faebp19 ++0x1.69ab61853a58ap25 ++0x1.9955a12bf91eap155 ++0x1.e8a7220cbb889p593 ++0x1.c275a73192796p259 ++0x1.f79d74bb2c42ep261 ++-0x1.b80435f49efd4p25 ++-0x1.a3f243a5aba38p960 ++0x1.ab2a83515090ep837 ++-0x1.b93c62ada1c23p12 ++0x1.b042d7b712ce3p608 ++0x1.e173865ea2fbfp711 ++-0x1.c721e58a282efp25 ++0x1.b7dd57c5e569fp171 ++0x1.a148e142f39b9p699 ++0x1.2a5fa6d540fa0p62 ++0x1.34bb57427099cp574 ++0x1.6f2dc0bc39621p500 ++-0x1.0cc9448729503p734 ++-0x1.c234d03687945p494 ++0x1.7bccb6482f77ep4 ++-0x1.8c5e908aa7fb5p831 ++0x1.b1df92d2ec3b8p283 ++0x1.e333354359049p989 ++-0x1.e892b0f07a619p220 ++-0x1.ec44220b9f17ep8 ++0x1.f25a34ac7fbc6p7 ++-0x1.7472b4254d705p367 ++0x1.22e011afd6d0ep345 ++0x1.065d20ae2ee95p117 ++-0x1.6418273399593p831 ++0x1.388612f03819dp40 ++-0x1.dfc0d7643e76fp-6 ++-0x1.7689e01d3ef5fp189 ++0x1.f48a26de3d1a5p673 ++-0x1.3a86439ca37c9p-23 ++-0x1.de0cb3b3a1df8p355 ++0x1.8fca33d3d5d24p550 ++-0x1.5ee022e10d5ecp145 ++0x1.d65386a7e7b24p408 ++0x1.a75471ed7f723p3 ++0x1.84a43795ffed7p-25 ++0x1.270743fc743fdp404 ++0x1.3fdc27ff3d6f6p16 ++0x1.c2ca7781852bdp415 ++0x1.783d81633686dp295 ++0x1.0c62c5098c3c2p-4 ++0x1.abe5e0d2c9c74p9 ++0x1.8763249337c43p522 ++-0x1.354a300bdf2b4p9 ++0x1.77f8512b9b058p494 ++0x1.85e423863bfb1p299 ++-0x1.ff6a529c5f799p582 ++-0x1.af91845aed73dp292 ++0x1.bbe7d76864319p838 ++-0x1.6b92a5b928341p42 ++-0x1.bc96d3fe8ae11p453 ++-0x1.4cf8e5fdb6606p14 ++0x1.d7a286a93d573p552 ++-0x1.1e168326fabfcp619 ++0x1.2b78d4cf920a5p-11 ++-0x1.8b6761d15a192p11 ++0x1.7e41058d14f88p444 ++0x1.4ed112f6fe397p276 ++-0x1.4db517680987fp623 ++-0x1.2224f5210184cp332 ++0x1.bebb126a84646p845 ++-0x1.3890a2fcd6ed1p771 ++-0x1.ff3303971888bp-10 ++-0x1.c088d7303166fp9 ++0x1.3da6a7f5bc078p14 ++0x1.151f505312964p29 ++-0x1.3d0bb60c7b363p104 ++-0x1.6b9a26936754ap496 ++-0x1.9199b437eccc0p127 ++-0x1.aa36d2b9371b7p445 ++-0x1.0b8f350ea5f8cp-22 ++-0x1.f1f4b4b0405cdp-11 ++0x1.3105b5f0ba9bcp-15 ++-0x1.aa88d154a4ddep551 ++-0x1.0f68f1251f868p291 ++-0x1.9f078781f160cp1012 ++-0x1.9cabe23aae521p577 ++-0x1.4dae06e7b4120p16 ++-0x1.e43e623d48c49p-18 ++-0x1.29ccb1801e4c7p77 ++-0x1.6adca332f1fe7p-13 ++0x1.4d98f1ff8002dp-9 ++-0x1.b5a3575f4713fp470 ++-0x1.6374a29768141p237 ++0x1.af58667bcfbf2p127 ++0x1.128ff1d95cbe2p22 ++-0x1.1cd1c2bf75c3dp394 ++-0x1.911146b47e563p965 ++0x1.c9b034c25b038p1003 ++-0x1.f45070caf3082p630 ++0x1.dab7970bc1de9p1 ++0x1.4aea409a375dfp287 ++0x1.59d34792a5525p482 ++-0x1.50cd458fc25dep253 ++-0x1.759d44cd1fd81p269 ++-0x1.04a6060096d96p-3 ++-0x1.604b42f7ccab0p419 ++0x1.c30db3408e834p20 ++0x1.f7d0003cef355p465 ++-0x1.d33647c71ddf6p713 ++0x1.941117709cdfdp23 ++-0x1.8aaa468ff284bp786 ++-0x1.4c6536f0b6777p-16 ++0x1.8c86677fee3afp133 ++-0x1.0b1b35dbd7737p325 ++0x1.de2f93f581a04p12 ++-0x1.5a3ba4b477d56p15 ++0x1.e83645234e293p24 ++-0x1.3fca1310ff561p74 ++-0x1.2aeb7470b2da6p635 ++-0x1.3f3ad4cd76224p25 ++0x1.09752219591d6p-12 ++0x1.bc88b48080aa6p31 ++-0x1.e98923b202a64p20 ++0x1.bf0474f0f41e2p104 ++0x1.a4e9d3f2451a8p3 ++-0x1.3541735027a8bp560 ++-0x1.f73dd55c810dfp23 ++-0x1.505b10dc0eae6p912 ++0x1.3649c1c465dd4p17 ++-0x1.c777e501c8dfcp21 ++-0x1.5701a0b3897a4p11 ++-0x1.c320c380b445cp712 ++-0x1.1b36c09e0a14ep663 ++0x1.f60ea3f1a14cbp561 ++0x1.c6a3005c06a44p-18 ++0x1.af722598ce867p659 ++0x1.d636c36a5d8afp187 ++-0x1.16a3c0a4e81aap-7 ++-0x1.8f3db57790c2ap-19 ++0x1.703ca04fb8f62p-17 ++0x1.f73de47c2fb9ep35 ++0x1.973a34ff90b9dp-18 ++-0x1.d08281fbb5c2cp838 ++-0x1.be0f904e8c33fp342 ++-0x1.e01d440fbebdap-18 ++-0x1.df0f220b1c2acp-15 ++-0x1.bcc990cf09edap-25 ++0x1.8a350004b6021p21 ++0x1.0746671992572p12 ++0x1.bca1f2ae769dap-25 ++0x1.1c0ee394715fap13 ++0x1.bc9a351ecab48p356 ++-0x1.3e4cb5ef07939p17 ++-0x1.f2b664e58004dp1 ++-0x1.f42ee6d0e89ddp19 ++0x1.5f0a34dcee39dp20 ++-0x1.1debc4db7ecf6p20 ++0x1.0fc713f5c5de6p-3 ++-0x1.5d4db109cd5c4p5 ++0x1.73e807d8297f3p-17 ++-0x1.676ce231eda86p861 ++0x1.ebfa67a80676ep-10 ++-0x1.b9f6a30ee6469p-21 ++-0x1.c73277e6727fdp601 ++0x1.74de03b6dea40p159 ++-0x1.2259c59f68e46p-16 ++-0x1.cd68d2e6479f4p-23 ++-0x1.47b7f6102f2c2p10 ++0x1.cf24a2347776cp-27 ++-0x1.b725b137fdd1dp-3 ++-0x1.009047102718cp993 ++0x1.0771b34af6f2fp-8 ++0x1.049d06f739b38p699 ++-0x1.e8c0710c55d89p-17 ++0x1.23b5322648c9dp-12 ++0x1.cf0fe10d20725p2 ++0x1.50052516748d2p0 ++-0x1.afddd01d4ff78p2 ++-0x1.3e0df401f7903p381 ++-0x1.c9fc3321d1d88p8 ++-0x1.8b10a044fbcabp-16 ++-0x1.89260258d6e7bp14 ++0x1.db24554246421p-25 ++-0x1.420505cd0119bp521 ++-0x1.917894697053fp264 ++0x1.4e4bc6a5bd810p-22 ++0x1.613766f0b8925p-21 ++0x1.96bde6095382ap-1 ++0x1.0028d14831ce2p18 ++-0x1.c2174546c88c0p1017 ++0x1.83ec835c217c5p-10 ++0x1.fe32319f71affp913 ++0x1.3fa26558eafebp-9 ++-0x1.170bc0306f9d3p14 ++-0x1.2da6158b9104bp-6 ++0x1.da4016ececc3cp23 ++0x1.4aeb75f4274a8p74 ++0x1.0feda4108c230p-11 ++-0x1.9e9580350379ap975 ++0x1.8c72429a6c6b8p803 ++-0x1.753eb56c15fc4p205 ++-0x1.a8d226aa188ddp10 ++0x1.552f237c39a5cp24 ++-0x1.5101e740c55d2p-2 ++0x1.f83282678cd2bp87 ++0x1.380e51076f80ep17 ++-0x1.4e58c2d312887p1011 ++-0x1.709a10ec34872p-8 ++0x1.c115c4b52dd81p-11 ++0x1.dbf4f68b24b22p175 ++0x1.fdcfc21030c47p13 ++0x1.e3c234340a70cp870 ++-0x1.7ef4c3f9f118ep-17 ++0x1.4d8ec7ddbe0a5p-5 ++-0x1.ca4ae67422cf1p46 ++-0x1.1e79333cf2819p-16 ++0x1.088641b858387p14 ++-0x1.93191290365a6p163 ++0x1.f321d1dd96f4fp756 ++0x1.e771b71cceff9p8 ++-0x1.ae56c771a7cffp18 ++0x1.4ba1448b1d144p408 ++0x1.8439648ab93dep17 ++0x1.65f514736d787p943 ++0x1.fb6472b3bce83p334 ++-0x1.73e6857d4cf54p879 ++-0x1.0cb95433e6b2fp-1 ++-0x1.27ae632085c5ap2 ++0x1.f68fe052bec12p753 ++0x1.a8cc8446b7afcp17 ++-0x1.9e2494726de25p25 ++0x1.d825d64df0641p10 ++-0x1.ba99b6fb023c9p141 ++-0x1.53a8b1ea85f56p11 ++0x1.bfa5e68028b9cp930 ++0x1.feccf31f1a983p-5 ++-0x1.88d3a0062385ap-16 ++0x1.50f3313a7d76cp24 ++0x1.3ba8870e96502p727 ++0x1.fffc900187a9bp761 ++-0x1.683c12d0f5288p-5 ++0x1.89f8430bf5854p895 ++-0x1.dd1c76087e343p-11 ++-0x1.2be8706763f1ep-9 ++0x1.359462ac17cd2p15 ++-0x1.a972c2fa07af1p1 ++-0x1.fce055f5fd92fp397 ++0x1.93d615d9775fdp7 ++-0x1.a734a251665eap-21 ++-0x1.96aec33f91274p3 ++-0x1.d088b0ef518b3p24 ++-0x1.e36ff2227faa0p664 ++-0x1.968c9528f761cp-18 ++-0x1.55feb6226d9c6p-12 ++-0x1.c5fbf2dc0f1d5p374 ++-0x1.30df34bf0f038p-5 ++0x1.75ff2344da2ebp638 ++-0x1.6c95073fd64f5p-3 ++-0x1.80ecb21eaf859p23 ++0x1.a395a3209e01ep24 ++-0x1.08fa41560be83p-17 ++0x1.f5129125f47e1p-24 ++0x1.ea61c1b68dbaep-25 ++0x1.f9980204cad5bp13 ++0x1.ca5571cae9585p300 ++0x1.1457460444b6fp308 ++0x1.f75fc7df35e9bp463 ++-0x1.259877b2c7433p808 ++0x1.4c4fd2558a03dp-2 ++-0x1.77e600a0f8d1ap10 ++0x1.ce0a20f8622dbp782 ++-0x1.163735c430e54p21 ++-0x1.077f533341f7ap-25 ++-0x1.5bbea1334dce3p22 ++0x1.17edb056a1e69p582 ++-0x1.ab2f3216588abp-8 ++0x1.ad5473156bcecp608 ++0x1.495167c77e0b7p1002 ++0x1.ce1fb4d50c2d2p-2 ++0x1.0b6367a2e5b51p-13 ++0x1.4bebf24710022p18 ++0x1.cf035256dea51p-15 ++-0x1.b2d165e3c4438p329 ++-0x1.415066810a6ebp5 ++0x1.231e43a52fc6cp759 ++-0x1.3ad3866e7e5a8p-23 ++-0x1.f5ac52c3f7320p364 ++-0x1.3d01b455ea097p-23 ++0x1.a57f56aa1cc32p9 ++0x1.043250b5cbb79p892 ++0x1.49de321920550p721 ++0x1.c870766bd9d53p80 ++-0x1.c4fd755e743ffp21 ++-0x1.b37d062015770p-2 ++0x1.5022353402118p0 ++-0x1.c896463f5386cp-7 ++0x1.6f2f169391729p-17 ++0x1.bd8476b405432p250 ++0x1.322de42f4c84ap22 ++0x1.c3a2c33bf9e6ap43 ++0x1.9793e2027ca1bp19 ++-0x1.cced16209f116p-5 ++-0x1.535c83351d7dap13 ++0x1.5ab2e7182498ep1 ++0x1.c2aa0412973d9p19 ++0x1.6d5087c15f8b6p8 ++-0x1.cd9e619dfc1f9p272 ++-0x1.a291f0cf8c7f3p491 ++-0x1.7726454f22bc9p16 ++0x1.01d737edff679p-18 ++-0x1.2eee17c89d93ep18 ++0x1.d690a2fbc75ddp17 ++0x1.e477309fee5e9p-5 ++0x1.265176315b6b7p548 ++0x1.d036d3c6d89f6p4 ++-0x1.70e42649dec93p26 ++0x1.685656f96535ap21 ++-0x1.1cfd02fa51fdep-2 ++0x1.75d1455fcfa44p590 ++-0x1.718613f6ca999p645 ++-0x1.b254238b7bab4p472 ++0x1.7afe534d5251bp-9 ++-0x1.b3cdb07891d41p-2 ++-0x1.f956817bbdd80p704 ++0x1.e04a74104462dp14 ++-0x1.d953d153059f4p43 ++0x1.9a4fa2868350dp878 ++0x1.7efdd4f9e156dp671 ++0x1.940ad2c424e0dp69 ++-0x1.4d5ad6e0fa515p-12 ++-0x1.975f1701f1516p10 ++0x1.686ff10e39dcbp-18 ++-0x1.47c80041fd8f7p-6 ++0x1.0bbcf0786c446p-1 ++-0x1.7dc7163623c62p-16 ++0x1.c773a0bde09abp14 ++-0x1.59776427dd29ep22 ++-0x1.c428306233d02p1 ++-0x1.2b34449d61818p18 ++0x1.946545746e430p568 ++0x1.fc5d70b15d6a1p-12 ++-0x1.33c530a2e703ap198 ++0x1.4586c7aaed300p23 ++0x1.4047f3cea71fcp21 ++0x1.d95a0359eb81ep13 ++-0x1.2027133fa9651p-15 ++0x1.4c9c737d289bbp993 ++0x1.29ed82663c830p19 ++0x1.2a2431406668dp964 ++0x1.140c003d7b003p692 ++-0x1.ca47d1c5105abp778 ++-0x1.1e42d4bc3a5bbp621 ++-0x1.c487c6add8db4p104 ++0x1.5240c7e94fca2p346 ++0x1.8a21e49e99f87p739 ++-0x1.ec7a3732512efp665 ++-0x1.e7e0c60c72a8dp666 ++-0x1.4b2df12f55803p16 ++-0x1.1a11950ff7262p253 ++0x1.913010e21977cp22 ++-0x1.557b91af754ddp548 ++-0x1.1a5a85b93333cp0 ++-0x1.152436888890cp10 ++0x1.6242f32a2b3a9p24 ++-0x1.33e4b774b0406p79 ++0x1.4d20507145703p18 ++0x1.805ee638666c7p1001 ++0x1.2088f31deb3dep26 ++-0x1.2136d4a8edf58p369 ++-0x1.a5c002d03e071p350 ++0x1.8e25144772023p619 ++-0x1.49c336247aab8p20 ++0x1.209f141d6a3f0p905 ++-0x1.7df363dd844bbp301 ++-0x1.d8c5a2fad0ddcp843 ++0x1.955904e859e69p-2 ++0x1.b78170f9c0f21p396 ++-0x1.1856132fbf136p-1 ++0x1.daadd2d9a8fb5p366 ++-0x1.904c42e144851p840 ++-0x1.1086823c84588p579 ++-0x1.eee3b28d8e277p18 ++-0x1.601eb2587f407p532 ++-0x1.e77f45947cdeap646 ++0x1.ac9d1257a463dp8 ++-0x1.6022b4ad26dfbp0 ++0x1.35d246dce052dp257 ++-0x1.d87a368873c5ap11 ++0x1.b79c7081c299ep249 ++-0x1.e9b573eed4beep380 ++0x1.87fb012c6dbe8p22 ++0x1.9ff675e52fd5ap10 ++-0x1.e768e1c4dc0c4p336 ++0x1.eadd71dae6ae0p12 ++0x1.8097a2036b3f4p926 ++0x1.88fb542f66420p9 ++0x1.6548027f7a3a1p23 ++-0x1.9830129387949p17 ++0x1.c3d7c15bf28c5p4 ++-0x1.53daf69f10b1dp0 ++-0x1.b90f21ac330e5p21 ++-0x1.9b0a377b76cdep21 ++-0x1.d0a0a05604f38p-1 ++0x1.e3e8b72617fc0p17 ++0x1.ed2f26a4f9de4p19 ++0x1.af91858c30b58p20 ++0x1.4abc00b2bfabfp24 ++0x1.dc67b22b6d111p5 ++-0x1.c247046a455a1p9 ++-0x1.fb41c728f7cbcp14 ++-0x1.891962b6634f3p7 ++-0x1.7cbac2b76a18ep13 ++-0x1.fb101566432dcp25 ++0x1.90448733f0f47p23 ++-0x1.8884367e47700p13 ++-0x1.37d7a4bfa5918p15 ++0x1.778a11c7fccd0p22 ++-0x1.33526112284dbp22 ++0x1.acb6870fb9e6ap21 ++-0x1.5a7ec1b268139p0 ++-0x1.0ea0c6bcbb4cdp17 ++0x1.0eeb153b1d5cep-2 ++0x1.2915060d6792dp19 ++-0x1.f1c193bf9731cp7 ++-0x1.a37b92d1c834bp17 ++0x1.ea6c164f563d3p5 ++-0x1.c1a342aeeff9cp18 ++0x1.341f80345a109p18 ++-0x1.b96f42fb8bf4ep21 ++0x1.ed99773e5e0b2p-3 ++-0x1.1b9c620a22bdcp20 ++-0x1.93a342bce9d83p25 ++-0x1.5647879df4c39p5 ++0x1.1b5a74379d8bcp22 ++-0x1.f65e80bbc64e4p1 ++-0x1.f514118cd579cp14 ++-0x1.d72c805888cd1p20 ++0x1.891fc407363cbp0 ++-0x1.f5f910e2a922ap21 ++0x1.13ab76a6396c5p6 ++-0x1.779c34504754cp7 ++-0x1.0f44243ca88f6p4 ++-0x1.94d8e73e1e8d3p14 ++-0x1.86ae04f21b804p22 ++-0x1.dbaf1624ab130p11 ++-0x1.e2b2534178f87p5 ++-0x1.cd1f04e46ab89p4 ++-0x1.534e73dbf82d9p6 ++0x1.d77307aacf285p16 ++-0x1.d02d057014609p22 ++0x1.63c7f14ec1826p18 ++-0x1.4700d06054318p23 ++-0x1.8c9e77f2c5169p20 ++-0x1.4440d5499645bp13 ++0x1.f830d1530dc5cp6 ++-0x1.3158f1b64b60dp16 ++-0x1.fa3cd6daa1a84p14 ++-0x1.6f453297966cfp2 ++-0x1.b50c62db9fa33p24 ++-0x1.1f01b348e43cfp3 ++0x1.f96f42e962369p15 ++-0x1.d42235ed34040p11 ++0x1.6a97b4ebe527ap25 ++-0x1.069365a978478p19 ++-0x1.301312077210ep5 ++-0x1.079ed7eb88a2cp20 ++0x1.e181d27a14ee9p22 ++-0x1.1a6ef1e1b02b6p1 ++0x1.605322092fdb1p16 ++0x1.28cc961d4d565p1 ++-0x1.0d1b956eefd65p21 ++0x1.136a46db7583dp12 ++-0x1.463a51e655419p3 ++0x1.06b280c58f749p4 ++-0x1.81a8422a0e891p10 ++-0x1.36d660b754afep2 ++-0x1.869b518b7abf6p23 ++-0x1.ca5da55d82232p6 ++0x1.c7b553dac1cd9p7 ++-0x1.5c85b71c923d3p9 ++0x1.cd38e05f93bd8p23 ++-0x1.72322760da308p6 ++0x1.2696c6205df80p-2 ++-0x1.c31466f5abe12p5 ++0x1.53ca818613b56p15 ++-0x1.6d0e32af8c7fap25 ++-0x1.82c493bc254bfp7 ++0x1.29b5476d3c003p-3 ++0x1.545ad52476bedp2 ++0x1.210de622c50fcp13 ++-0x1.4ce9501256fecp7 ++0x1.bec8f2a75761fp-4 ++-0x1.ef455712f7403p24 ++-0x1.05ac51c61d35dp10 ++-0x1.179912e48e4d8p2 ++0x1.8309468cee051p-1 ++0x1.4ba7338d7adb9p-4 ++-0x1.86fb84d7687fbp13 ++-0x1.b440d2dfa7cfdp-3 ++-0x1.f21935fed929cp24 ++0x1.248647fb68621p9 ++-0x1.49cbf71886ed9p-4 ++-0x1.46b18502c494cp6 ++0x1.d60453a7627dcp9 ++0x1.90d72030622a0p-3 ++-0x1.99dc012169112p20 ++0x1.5b1582ba1840ep26 ++-0x1.a2d0e6722064cp10 ++0x1.51d930a0faa1cp-1 ++-0x1.e2f5b411dfbe0p11 ++-0x1.8978d711c2457p-3 ++0x1.9f390111d8e17p-4 ++-0x1.64e526c906dd9p15 ++0x1.3442b50cfed58p17 ++0x1.696de2ba96decp3 ++-0x1.1797a538e22cfp14 ++0x1.6b9a91b6bc0b6p15 ++-0x1.230dd7b9de0efp25 ++-0x1.c570875d25b1cp17 ++-0x1.4e93f3cd23d0ep7 ++0x1.836bf1949fdd9p-1 ++0x1.d55994d3bc6a5p22 ++0x1.34976081e3c93p0 ++0x1.325232301be88p-2 ++-0x1.724d85212c2bep21 ++0x1.f6ea543e490d8p16 ++0x1.9816822b9c9eap5 ++-0x1.2c5942e617f9fp25 ++0x1.9916d5a987c95p4 ++-0x1.9e10b7e75a799p17 ++0x1.cd41449ad1c08p14 ++0x1.bfbd219130397p10 ++-0x1.d299552d58110p20 ++-0x1.10990673db383p24 ++0x1.6860579da3e41p4 ++0x1.57c17718caa8fp16 ++-0x1.d480c713e380cp2 ++-0x1.5ef770cc4fd6fp-2 ++0x1.63fe54f142182p-3 ++-0x1.e57fe1748c166p25 ++0x1.38e472a1b69aep-1 ++-0x1.d7eb84d9725a8p19 ++0x1.979751083fa46p0 ++0x1.af7d8295ca361p0 ++0x1.93d6033938ce4p16 ++0x1.60d5f07b31fe1p23 ++0x1.d345416a2b360p14 ++-0x1.1451d5a8abe28p26 ++-0x1.da4ba1007d69fp7 ++-0x1.5c7583f8bbbb3p22 ++0x1.8c85070cab228p20 ++0x1.bc26967cda999p17 ++0x1.bcfc7238281b7p14 ++-0x1.f936f6a071917p0 ++0x1.c00e11c935746p0 ++0x1.759dc14fe7eb9p10 ++0x1.26c7d5b4b926ep5 ++0x1.c6512134c5122p-3 ++-0x1.9ebe3455ed58fp9 ++-0x1.be4832965373ep17 ++0x1.7f68b772cfc9ep18 ++0x1.baca2181e77dep17 ++-0x1.c2f755dd7a244p19 ++0x1.c4de32af2dd91p18 ++0x1.589f6697070fap22 ++-0x1.4a37b4210f303p8 ++-0x1.4ecfe0a126fb0p5 ++0x1.89dcb692c40e7p10 ++0x1.7d6342e0df42fp21 ++-0x1.0aec35f5f853bp-3 ++-0x1.7f68335d52ca5p10 ++-0x1.84f6e31758356p5 ++0x1.3a5a166d0b827p16 ++-0x1.eba706d2de457p8 ++0x1.489f72add92f9p5 ++-0x1.da6b250d6a545p23 ++-0x1.e50b35770abc5p-4 ++0x1.4b1b40263e386p6 ++-0x1.e6864361f583bp6 ++-0x1.bf8ca4dc53bfcp23 ++0x1.5de1b4a13724fp5 ++-0x1.3ccf14da239a8p16 ++-0x1.2c352220b6d92p19 ++-0x1.7a1a04680b72bp9 ++-0x1.63e577fdaa152p15 ++0x1.8dd7323abf3d4p-2 ++-0x1.7896d1e003d8cp5 ++-0x1.b4a72034750d1p19 ++-0x1.c9752551240f4p0 ++0x1.88c816d89c028p7 ++-0x1.e765347c03b1bp1 ++-0x1.f5a3e6d431f22p10 ++-0x1.bcbd4269b3468p-3 ++0x1.27d5c33a2b9cdp24 ++0x1.c24173c80f8fap-3 ++0x1.e5d8c7f661bdfp12 ++0x1.f248554706676p23 ++0x1.6b9b012dc2faap25 ++-0x1.c53702c39d6b5p10 ++-0x1.ba8441a0e4b94p13 ++0x1.6276f46c87421p23 ++-0x1.cab117d6a7540p2 ++-0x1.696a408d00cd8p22 ++0x1.a85c0033d55eap20 ++-0x1.f1d5338e62f8fp17 ++-0x1.cab73716e3a08p6 ++0x1.7ff7625f9ca6dp23 ++0x1.fee2e4e051542p25 ++-0x1.898ec4cbce2fap13 ++0x1.054c5714bee5bp1 ++-0x1.e769a1325c9b3p18 ++-0x1.00ef90bb0ea31p13 ++0x1.d99cf6f223a12p7 ++-0x1.4802b635a9faep6 ++0x1.5c49e6bca57d7p9 ++0x1.9cfa3500116d8p3 ++0x1.20a380697021fp22 ++-0x1.cc9ee1c701912p-2 ++-0x1.159814f41ffddp12 ++0x1.bcdae38e2096bp19 ++-0x1.a4c564a58485ep0 ++-0x1.b3ccf11be8cb0p3 ++-0x1.2e036784747fdp-4 ++0x1.3178b79bf23d6p15 ++0x1.762022e7db160p3 ++-0x1.19abb2ad29c47p0 ++0x1.702aa52a2b081p2 ++-0x1.3b2f85e3448eap15 ++0x1.fba527184dd2dp0 ++-0x1.0e13b3dc07053p5 ++-0x1.6e3d0266ae8b8p5 ++0x1.5a2d64a6aa882p14 ++-0x1.409c93e21717ap0 ++-0x1.90c8d5e8d4dbbp-1 ++-0x1.c6f751e442d8dp14 ++0x1.ba19007f25633p1 ++-0x1.30f675c6b9d89p10 ++0x1.f5966161ca0f3p19 ++0x1.8f2fb44baebe3p-1 ++0x1.974bc69c68cabp24 ++0x1.c56de726c32d3p0 ++-0x1.10dc876280044p10 ++-0x1.0aae85d11cbc7p3 ++0x1.fc6cb52005104p15 ++0x1.05e5130ff091ap25 ++0x1.e1ba941321d52p1 ++0x1.66c5a13cdadc8p5 ++-0x1.55c8322221dc9p14 ++-0x1.92bdc5556bd73p14 ++0x1.096e742861630p1 ++0x1.2a16e7c69bc3bp4 ++0x1.da44529305931p16 ++-0x1.c2d2d332c16bfp24 ++0x1.20c675f6fe727p5 ++-0x1.d38d6225474d3p23 ++-0x1.481de5e77c136p2 ++0x1.d279c02f61ae3p2 ++-0x1.e7d9573de4581p11 ++0x1.35fe74c080235p-1 ++-0x1.ac005162cad81p12 ++-0x1.13b0a70cb376fp22 ++-0x1.ebb45106c5803p24 ++-0x1.1dc057ac89a8ap3 ++-0x1.b8c0d151742e0p16 ++0x1.970375264e6a1p10 ++0x1.7e866527c9d49p12 ++0x1.c2ddf22b1bccbp1 ++-0x1.ab4174efa2f0ap15 ++-0x1.e253067271c08p2 ++0x1.0d4fb486d614ep1 ++-0x1.abd6e292f5548p17 ++0x1.eda5e7728b075p14 ++0x1.1454a6c45a426p23 ++-0x1.25e591a6a9a8cp0 ++-0x1.7cfbf5669ec46p12 ++-0x1.4679e1cbdf113p8 ++-0x1.ce9af0afc0c65p4 ++0x1.62f4634b7620ep4 ++0x1.62a9b3c2b9823p23 ++-0x1.1769864efbd8dp3 ++0x1.f34715ef52c0fp-4 ++-0x1.8b62623c188c7p8 ++0x1.7975e1f8c7996p-4 ++-0x1.3bb2403639e82p0 ++0x1.b19f02fc16c82p17 ++0x1.570b03b60ea6ap25 ++0x1.7b12645745ec7p25 ++0x1.c49c016ba07efp-3 ++-0x1.9654e0923906cp1 ++0x1.df287182db6fap-1 ++0x1.8082a573c5c90p9 ++0x1.067783759fc7ap1 ++-0x1.0193d3485481bp19 ++-0x1.f21fe48c86139p25 ++0x1.3b79f760c1f6bp6 ++-0x1.dfea72f0a3541p24 ++-0x1.6c0bc68338735p4 ++-0x1.585dc43d90bdcp-4 ++0x1.0b4a74ddaeffbp7 ++-0x1.96334231685ddp-1 ++0x1.f6f5538f88159p3 ++0x1.9b4c653dc6242p-4 ++0x1.8be735e377e26p-1 ++0x1.e11465e6856f1p0 ++-0x1.7198d0b28bc64p-1 ++0x1.dcbed3c85165ap9 ++-0x1.75cf96486fb5fp8 ++0x1.bc5d4762ed95ap18 ++-0x1.b4ab765a2ce10p2 ++0x1.eb8d56eda92c4p6 ++0x1.513d51d6c544ep21 ++-0x1.724cb58ad93ecp-2 ++-0x1.ae2f075a1c1e9p-4 ++0x1.3b27a36ab9d59p18 ++-0x1.3d35f4b149caap20 ++0x1.5d2301f5b984dp10 ++-0x1.b4f9911c7cbd5p5 ++-0x1.3c85c4e8893f2p0 ++0x1.ff16d24d0bd20p-1 ++-0x1.587e438ccd381p17 ++0x1.ef7cf5c296d36p22 ++0x1.e83847d5313bep18 ++0x1.7e01f150d09a5p4 ++0x1.d1c293dd145c8p3 ++-0x1.585e926cd5b1bp-2 ++-0x1.fb42f3ec59b27p3 ++-0x1.59b854f3c58b0p13 ++-0x1.f841b3d82549ap6 ++0x1.4aaa17e78776ap13 ++0x1.be3491ea08398p19 ++-0x1.8157656f77f49p10 ++-0x1.ef5b133a05238p9 ++-0x1.a84b3275b47aep-2 ++0x1.d2d40379eed33p-2 ++-0x1.b38e5132a2518p1 ++0x1.0b583593881eap1 ++0x1.de0c21d2e13f6p2 ++0x1.e57f91ef79d08p21 ++-0x1.35787426e7659p0 ++-0x1.2fc096d91558cp10 ++0x1.ca92d112801e6p-1 ++0x1.c130f673f9d00p3 ++0x1.ab43360e99861p7 ++-0x1.dfc494915cb98p16 ++-0x1.662a1708721aep23 ++-0x1.632a633f7b779p10 ++0x1.900746f103c7bp18 ++-0x1.1725a276c7758p13 ++-0x1.01e616e258a20p10 ++0x1.161df51eb42d5p16 ++-0x1.9116109f57baep-4 ++0x1.0924248619f04p-3 ++-0x1.528a30859b8aap1 ++0x1.3214b1efe1264p11 ++-0x1.279bd7646bb1fp14 ++0x1.9cac25e81f355p5 ++-0x1.c1b4e4b65f4c8p15 ++0x1.b9446219929c9p24 ++0x1.85dbc095a8b7ap15 ++-0x1.71a3c59471916p19 ++0x1.390f94db871c9p3 ++-0x1.667266143481ep-1 ++-0x1.3f41661ad1011p-3 ++0x1.39e7b0627a056p4 ++0x1.4be6257d4db36p1 ++-0x1.42b4f39ad58a8p21 ++-0x1.0ddfc3c773e9cp0 ++0x1.3e0b505a62bfep23 ++0x1.17ae947b55a16p3 ++-0x1.450e033bf3474p3 ++0x1.fc5a706652876p3 ++-0x1.ec85a78011932p-2 ++-0x1.1a2587c2acc7ap19 ++-0x1.0413c7bd307d9p-3 ++-0x1.c14f93438c9c7p24 ++0x1.c23452cc49201p0 ++-0x1.822bd11a73bb1p-4 ++-0x1.50a39655d03a3p19 ++0x1.93da259e63c6bp19 ++0x1.2b38c33777246p0 ++0x1.16ab521fc8f08p-2 ++-0x1.bd2e1426c0b97p9 ++-0x1.3f66f1cab29c2p24 ++-0x1.89542080e7b23p2 ++-0x1.a57e9572fab9ap-4 ++-0x1.ea38e30d4f2e9p-1 ++-0x1.6980315b826ffp21 ++-0x1.5f0ed5102c7e4p23 ++-0x1.bcee5575ad4e3p25 ++-0x1.f9a690462f13fp-4 ++0x1.b19d857513a36p20 ++-0x1.b14a15fcc1146p8 ++0x1.949ce3f3aeaedp13 ++0x1.d8b3403249e60p16 ++0x1.b42cd3bb4ca54p-2 ++0x1.805807a27361bp7 ++0x1.fa5ab42962ce2p24 ++-0x1.390543514c4d6p7 ++-0x1.a786543bad777p8 ++0x1.d38f169be1c02p18 ++0x1.a22dd22ff3ad6p3 ++0x1.5dafb7808dbe5p-4 ++0x1.c9dde4e221c90p-2 ++0x1.ad9804a975e98p7 ++-0x1.6b6343d804919p-4 ++0x1.40efa3258a7e0p-2 ++0x1.4994104561818p15 ++-0x1.202c76ef257b1p10 ++0x1.9dabc7786d2c8p3 ++-0x1.1bcf75d5e6e6ap4 ++-0x1.8802471c77a93p1 ++-0x1.8edc21142d145p2 ++0x1.21c2c22bbc29cp10 ++-0x1.6a6c82b8898ddp4 ++0x1.a3adf1a7b1a13p3 ++0x1.49d3d7c9f2254p13 ++0x1.b79d130f9431dp-1 ++0x1.0d1b7459c7e69p1 ++0x1.ab10c361ca6dep6 ++-0x1.fc0e761dad4fbp3 ++0x1.c45ad1e916b60p-4 ++0x1.077d3554fe489p0 ++0x1.dc36d78d24b31p3 ++0x1.60ae735b6f4b7p0 ++0x1.ee39527f71eb4p15 ++-0x1.6e7213bcc9467p0 ++0x1.431002c64536ep16 ++0x1.e5be6089f8d20p1 ++0x1.5e46b0f01f53dp23 ++0x1.69fff66d50910p0 ++-0x1.a0e9131bb56dbp18 ++0x1.674805aee7412p-1 ++-0x1.dabff64ead53ap0 ++0x1.d4a2274cff182p-1 ++0x1.fb3a27edc048bp1 ++0x1.a82744aaa00eap-4 ++0x1.302d4443c6c04p0 ++-0x1.2dc450ab7367fp-2 ++0x1.3cada637e6251p23 ++-0x1.1ba7f471bf8cep18 ++-0x1.a9a1b0bc1f9f7p1 ++-0x1.21a6435313043p-4 ++-0x1.72f020a7330b1p20 ++-0x1.9d4906d826708p-1 ++-0x1.b78fc5f05bc95p3 ++-0x1.156706eda9f85p4 ++-0x1.59c5832441b87p11 ++-0x1.de49e509aa110p9 ++0x1.e395a4ef1ad69p-2 ++-0x1.085cd295378c4p5 ++0x1.3a3167bb15567p19 ++0x1.f1c1f7a981956p17 ++-0x1.d57eb0ccc1192p24 ++0x1.49c4a7fce174dp12 ++0x1.42a6f5366340bp3 ++0x1.c73946000ef3cp15 ++0x1.31ce910c8f277p-4 ++0x1.0e1e520b20462p7 ++0x1.3c2672f8a2c03p12 ++0x1.0f9a64fdeb055p7 ++0x1.922625557e01ep-1 ++-0x1.abd306314559dp0 ++-0x1.1cdb82c46c748p22 ++0x1.f8b26607a6659p12 ++0x1.e5f5a3659806ep16 ++0x1.8a997615a5e47p4 ++-0x1.9a88b64eed8c5p12 ++-0x1.d685f50d87896p23 ++0x1.817095a80c3b6p-1 ++0x1.6142c7c1265e2p14 ++-0x1.d148003201454p5 ++0x1.2e8a76f17e51dp14 ++0x1.427402f1c86dcp0 ++0x1.9b2d423fdfa51p-4 ++-0x1.86f0c60e56f2ep-2 ++0x1.b32e43a763dc8p-1 ++-0x1.8cff449c1e97dp24 ++-0x1.880110436ba05p-1 ++-0x1.97b7d36271db4p1 ++0x1.f30b30d1aa293p-4 ++0x1.e5ada37f74455p19 ++-0x1.c26e223a61790p22 ++0x1.13a14657deeb3p4 ++-0x1.6478570f08c98p0 ++0x1.ceda65c15f255p11 ++-0x1.f62630fc890a7p22 ++-0x1.7782824757591p24 ++-0x1.98bfd567b54f1p-1 ++0x1.1c6955755acc0p3 ++0x1.65ac87fd01210p4 ++0x1.7bf572a17df2bp-2 ++-0x1.10ba33750f2b8p12 ++0x1.0eb2a5c9e5ab7p11 ++-0x1.a36377f89ac61p9 ++-0x1.1ef0e24d3ae7ep25 ++-0x1.754f03aa6e28dp4 ++0x1.ee53f7fbf6eafp-2 ++0x1.f50fe52b03ffbp2 ++-0x1.638950b33d379p1 ++0x1.3995d5405f180p2 ++-0x1.9d77e47674aa8p8 ++-0x1.32a0f62f354a3p21 ++0x1.26dbc38bc8937p22 ++0x1.3b7b3206286bdp-1 ++-0x1.4ee7f59ce5c39p4 ++-0x1.d6a1e75344b65p13 ++-0x1.d718e5bc70942p10 ++0x1.3f5d423f663fcp13 ++0x1.f01b35c0d9d59p25 ++-0x1.8bcc84208bd5dp-3 ++-0x1.181ad4f3244b1p16 ++0x1.0273210f71286p18 ++0x1.d29bc36a4515dp11 ++0x1.a20d92a1419efp15 ++0x1.2f51d558be78cp16 ++-0x1.5e6b84e9ec483p10 ++-0x1.16a2b6ee1de0cp11 ++-0x1.569474dd1954cp16 ++0x1.fb10a07b26f8fp19 ++0x1.8585c235045a7p5 ++0x1.d3337464c4076p2 ++-0x1.972fd5ff17f98p3 ++-0x1.2ed312782dbfbp17 ++-0x1.efa051135e1aap8 ++-0x1.f710d597fef71p8 ++0x1.aa8dd6f8a9beap9 ++0x1.9f1dc377cf120p2 ++0x1.62c3a7358a4f6p11 ++0x1.34efa6be82f88p14 ++-0x1.184f25cf949f5p0 ++-0x1.3f7491d3e3894p12 ++-0x1.f221e4559b24dp3 ++-0x1.f342571a6ca3ep1 ++-0x1.b50c874b791dcp23 ++-0x1.6b12a335d95e7p-2 ++0x1.73cf16b52cc79p2 ++-0x1.b18fd6ef0fcc4p-4 ++0x1.261c17c736b83p0 ++-0x1.c86005afe1b46p0 ++0x1.0fd231c7aab56p-3 ++0x1.3b66100eade0cp-4 ++0x1.1b62615d4579dp1 ++0x1.cadb62a061c44p24 ++0x1.3ae06343b6bcbp14 ++0x1.f291c2e85d959p-3 ++-0x1.061340896769bp1 ++-0x1.2bd0077f3cf19p-2 ++-0x1.ad7016b69a63fp-4 ++-0x1.e62a635c849dap20 ++-0x1.0b91a74b137c8p13 ++-0x1.90d2306d27347p8 ++0x1.844f36ffbcbf5p7 ++0x1.a43987044698dp3 ++0x1.4b28a54b06fd8p2 ++-0x1.13f7a05c3396fp-1 ++-0x1.a7f08659fdc44p7 ++-0x1.6230f3bb15667p1 ++-0x1.bb4c27fb03a6fp19 ++-0x1.abd3330e2907dp0 ++0x1.a10a926b01f22p20 ++0x1.4ef4737029ef8p20 ++-0x1.4fbc07dc0319fp21 ++0x1.4f5cf32c6f33fp20 ++0x1.9246404054591p0 ++-0x1.6556d1b2edaedp-2 ++-0x1.8609762c8b440p19 ++0x1.f7e69735662a3p25 ++-0x1.e924f3e7030bep15 ++-0x1.9288c5e79cf59p-1 ++-0x1.576322583b5e2p3 ++-0x1.36e724118914dp17 ++0x1.5af0268d084b3p0 ++-0x1.8677c0dacd6e4p3 ++-0x1.5499134382165p4 ++0x1.bbca46c3b4d52p0 ++-0x1.163cb68bf3dccp-1 ++0x1.cef2e67ee56dfp5 ++0x1.f6364662207f1p22 ++-0x1.c2e3f1f65d52dp1 ++-0x1.9d8c95af70b3fp2 ++0x1.a14de64f1781ep1 ++0x1.b20186799badbp14 ++-0x1.399014458c7f0p-3 ++-0x1.0fc4b2f3ed7c7p-4 ++-0x1.eded7159875dep0 ++-0x1.a263c32babe5cp-1 ++0x1.f58cb01f888cap-4 ++-0x1.697672487c482p18 ++0x1.5c460397011dbp-1 ++0x1.07b5c65ec8ad3p15 ++-0x1.4eb6a36be78ecp-4 ++0x1.e310154adf232p-4 ++-0x1.da842458624edp2 ++0x1.35a40221fabbbp3 ++0x1.ffcc323b881e2p-4 ++0x1.ee99c7c780be9p-4 ++-0x1.f901049a4f638p11 ++0x1.d3e7502eab4b6p-3 ++-0x1.253ef59d5b22bp3 ++0x1.059d75fdfb006p1 ++0x1.cbbfe23e9b204p1 ++0x1.d708f03a832c7p-1 ++-0x1.ab75a3d27c91ep-4 ++-0x1.6be4347f71cc1p-4 ++-0x1.e8c9e1c74124ep-2 ++-0x1.0e5f50bd9ab17p0 ++-0x1.057b22cc1ca57p-2 ++-0x1.4214a3145eee7p16 ++-0x1.8ff493b4d0161p3 ++0x1.ff71c54ac0722p1 ++-0x1.cbeb16791916dp2 ++-0x1.dbaa7305da875p2 ++-0x1.9e4ca5923b8f7p5 ++0x1.85a4e1dc18565p4 ++-0x1.66a210312f4fcp3 ++-0x1.60ff74a0b47d6p-4 ++0x1.2262b5f1adeacp-1 ++0x1.4c7db0b6a7422p4 ++0x1.e3e8f16cceb2ep6 ++0x1.ff5074ef37c49p0 ++-0x1.10e6c770bce9bp4 ++0x1.c6a3a0025e5dap22 ++-0x1.0bb1439478f5dp-2 ++-0x1.6fb0156408828p2 ++0x1.b28ff518979b6p1 ++0x1.9f63566d75ba1p0 ++-0x1.cdbd94929acf6p16 ++0x1.f3dd143481244p-4 ++0x1.5769939835a80p-1 ++-0x1.6b4ea312b9249p-2 ++-0x1.a73b84ba8d9a0p-1 ++-0x1.841c832628699p-2 ++0x1.15d930c5d9513p4 ++0x1.41317671877f1p24 ++0x1.c75165ddd78c0p0 ++0x1.693575a9d1138p3 ++-0x1.717b171687985p16 ++-0x1.945b94a09037dp-4 ++0x1.927ee26038e68p2 ++-0x1.f599772ffd90bp19 ++-0x1.5c5b47eaa8583p0 ++0x1.89ecc1f399ce5p2 ++-0x1.9feaa603120d3p-4 ++-0x1.61b0d15368a4cp19 ++-0x1.dd65243b8102ap-3 ++-0x1.d01653391399cp-4 ++0x1.a6fa353616c25p-1 ++-0x1.186f755c9547ap13 ++0x1.8ea3a743322dbp4 ++0x1.01f3d2122c4b1p13 ++-0x1.b43ad29df2703p2 ++-0x1.7ae312c61df29p2 ++0x1.b8bdf3bef563bp11 ++0x1.f8e434e9db303p-3 ++-0x1.f2c9a511ea803p1 ++-0x1.97c2f0e9d43b1p-1 ++-0x1.116c80ce25470p-4 ++-0x1.5a980694bcb2fp-2 ++-0x1.32e545c122be7p17 ++0x1.fa5101a1db44ep1 ++-0x1.acbb05a4fcad6p2 ++0x1.9c7b63462ad27p-1 ++-0x1.0b5fc67ab2279p-3 ++-0x1.db886026a7769p3 ++-0x1.fc0015986ba7dp3 ++0x1.08da532d7c2d8p2 ++0x1.1efed083d86d2p3 ++-0x1.93ddc734949adp-1 ++-0x1.8139b09417df1p5 ++0x1.b19e95af39a66p-4 ++0x1.fa36f74895f3dp-3 ++-0x1.8a50f1b23e664p2 ++0x1.eb65d4abdfdddp24 ++-0x1.5b58c5cf71143p11 ++-0x1.93789271d3e79p1 ++0x1.32d8d3818df7fp-1 ++0x1.a02656baff621p3 ++0x1.456822523692ep-1 ++0x1.9e821342b14aep24 ++-0x1.bacbd3affeb41p1 ++-0x1.5b4543a6420e3p1 ++0x1.94c0e4a504564p20 ++0x1.12189312e1789p3 ++-0x1.5465839d51246p16 ++0x1.212ec63d1fc28p-2 ++0x1.ea2df3e7023d5p-3 ++0x1.de0b83c02018ap3 ++-0x1.8240253b43da4p2 ++0x1.767607eab92e7p0 ++0x1.d9ccb717b987ap0 ++-0x1.98dee08d0a3adp3 ++-0x1.dcfca0020809dp-1 ++0x1.7f869312366ebp22 ++0x1.cd961413f209cp-1 ++-0x1.3221407824fffp2 ++0x1.2ade9658e1126p2 ++0x1.b34083bdc8115p2 ++-0x1.980922c6e082cp-2 ++0x1.799832b5bfa6bp26 ++-0x1.a56c15d91cd8bp-4 ++0x1.44a3a79631f72p-1 ++0x1.dda0957785a67p-3 ++-0x1.c54b66b69cac8p2 ++-0x1.b0cc178214892p0 ++-0x1.c1e5f06ea400fp17 ++-0x1.d29493a595f5ep2 ++0x1.8bdae6ba44b4bp-3 ++0x1.8d26f713baf31p13 ++0x1.8cb220c346946p3 ++0x1.71de257cb436dp3 ++-0x1.a52e1674a0f6dp-2 ++-0x1.418065835e8cfp2 ++-0x1.a4d5d76840286p-4 ++-0x1.3ed0116e38f5ep2 ++-0x1.87c515996b87cp20 ++0x1.35d67495a3d85p13 ++-0x1.430b146120c64p13 ++0x1.ce7d04c15930bp2 ++-0x1.704f325206940p2 ++-0x1.9e18f50e6cf7fp2 ++0x1.5269e51b29116p0 ++0x1.227c74bba7565p4 ++0x1.a81c022b943a6p-1 ++-0x1.a105212679fabp-2 ++0x1.b87ac53cacaf7p18 ++0x1.e71b216138183p17 ++-0x1.1668a6b611528p3 ++-0x1.586af282ee66ap3 ++-0x1.a646106bb9884p1 ++-0x1.781022484b783p2 ++0x1.4c9ab7f28c644p10 ++-0x1.c6dbc36bae35bp-1 ++0x1.55352240eedc3p4 ++0x1.b6f2b21a2eae2p22 ++0x1.9664d29b9e356p3 ++0x1.f3919543276fcp3 ++0x1.7cc834f6358cbp-2 ++0x1.9f07d58ef3ac7p5 ++0x1.9de5b20a4a764p1 ++-0x1.8aea705541631p18 ++-0x1.0952739540b5ap4 ++0x1.2993d67ddc894p0 ++-0x1.cecb056b46a86p3 ++-0x1.585ba625ce37dp4 ++-0x1.2c85b49135c11p6 ++0x1.1b03f53976b8bp2 ++0x1.804b5294eab8bp2 ++-0x1.15f090515ae7ap1 ++-0x1.c40c30eea2397p2 ++-0x1.d222d4cc61156p0 ++0x1.491254db782e2p9 ++0x1.089244b067d20p3 ++0x1.847fe11643736p3 ++0x1.aae600dfbb0d6p0 ++-0x1.c60c05a64e456p2 ++0x1.d3772608146aap16 ++0x1.210261c1bad19p19 ++0x1.7f61635ba6212p1 ++0x1.e03d05d58d78dp1 ++0x1.6fa5277426dffp2 ++0x1.7dd7a003f1fc5p8 ++0x1.d3c3c54fb269bp0 ++0x1.456084e1be432p-1 ++-0x1.9f35500c78f46p-4 ++0x1.b17ad24d5328bp21 ++0x1.45a4a452108b8p3 ++0x1.ee7835a4a15cap2 ++-0x1.5c88834020c4dp4 ++0x1.8195e389f02f0p1 ++-0x1.4d25e7891a5e3p1 ++0x1.a368603b90642p2 ++-0x1.fc1e4287a59a4p2 ++-0x1.087e41d357143p12 ++0x1.ccdb52d850e64p14 ++-0x1.ae95e02bbf2c6p2 ++0x1.d32c40fb7eed5p1 ++0x1.f4be74fc543aep-3 ++-0x1.c549772b73225p-3 ++-0x1.8e5cd0178d9fdp20 ++0x1.c81356a2c080ep-1 ++0x1.ed40040dadbe7p8 ++0x1.9914806c4c867p20 ++-0x1.501a27c66dd4ep21 ++0x1.dad8e19368949p18 ++0x1.4d9500c7ef7d7p0 ++-0x1.dc10c31391064p-4 ++-0x1.fc9d741aa8b78p15 ++0x1.467ff5c092692p6 ++-0x1.57a300f11a56dp10 ++-0x1.3289b70ab408bp-3 ++-0x1.406e2614c2a4ep4 ++-0x1.7320110d87bd1p17 ++0x1.ad9f174b85f67p-4 ++-0x1.6c05d0f81d05ap5 ++0x1.4d9fc757d40a4p2 ++-0x1.900c147490e47p1 ++-0x1.9bf4951c2d822p2 ++-0x1.f57e420cd00b7p3 ++0x1.748fa1fba98f6p-2 ++-0x1.7a48c776cf20ep3 ++0x1.5e1a45452622dp-2 ++0x1.ed24031124eddp-5 ++0x1.e691f37be2dacp3 ++0x1.231531dd30f1dp-2 ++-0x1.564fa0bfd60b1p18 ++-0x1.ac70324dce95dp1 ++0x1.a0d493588e057p23 ++0x1.f98780fb132a7p2 ++0x1.90ebc38d03a87p0 ++0x1.ff96e2f54d04dp24 ++-0x1.bf74b63ca40bbp2 ++0x1.9af727dde69f1p0 ++-0x1.e44071bd7b86bp1 ++-0x1.28d786fdcd052p26 ++0x1.8692e232cdae6p3 ++0x1.9b50469f50d88p-4 ++0x1.3ab662a7c7a65p-1 ++-0x1.d085169ef3012p2 ++0x1.bade31b1d2841p13 ++0x1.264cf12a5f18cp-3 ++0x1.eaf301a2af660p1 ++0x1.e09f42ccc01f3p3 ++0x1.4fef37206f995p20 ++0x1.3e7ff15ec0784p4 ++0x1.6ef7504e7c351p0 ++-0x1.65bfb1e6dffa7p4 ++0x1.034610cc74f21p4 ++-0x1.e7cdf2d5b5d7ap1 ++-0x1.56d207d3b7f15p26 ++0x1.9ade7656cdb52p-4 ++0x1.da34f1f8ba414p-4 ++-0x1.0620a0b7e0120p25 ++0x1.0aa527ccceddep12 ++-0x1.ff9b102c34c06p-1 ++-0x1.680934192f0eep-4 ++0x1.633c770deedcdp4 ++0x1.ac3d562aa3882p23 ++-0x1.fd93150cab59cp13 ++-0x1.2e68b5aeb1933p1 ++0x1.16a1b3634e220p4 ++-0x1.9a3017378b041p2 ++-0x1.9c6406add3380p-1 ++0x1.d28307b34902fp10 ++0x1.a256a6fc28529p0 ++-0x1.fc32d7015c25ap3 ++-0x1.90fe456ab6cd4p-3 ++-0x1.d82302f16ed56p3 ++0x1.e29194bbd8108p-4 ++0x1.ba28875f65f3fp2 ++0x1.aa02215f4279dp3 ++0x1.04b274650ae6dp16 ++0x1.5720460ea9547p4 ++0x1.d3565193466b6p25 ++-0x1.18ab75ac729b0p3 ++0x1.62b49423eac50p13 ++-0x1.5d5f51118764fp4 ++-0x1.0d11554e6379ep-3 ++-0x1.f7b3b55dfdf96p-5 ++0x1.d97d4089c87fdp3 ++-0x1.74dd56532f950p-3 ++0x1.f41ba46bbb346p3 ++0x1.15305286fef88p26 ++-0x1.6c32d3a71f573p20 ++-0x1.65a80408231a7p-2 ++-0x1.ef3b14f8fa244p15 ++-0x1.4060641b877f0p7 ++0x1.bb6e36c2071b4p20 ++-0x1.3a30a6c1a2f5dp3 ++-0x1.74ae12ec6a97bp1 ++0x1.29d196ea1da27p2 ++0x1.bfbfc35e1396cp2 ++-0x1.967993d8f656bp3 ++0x1.7f6f16b033158p15 ++0x1.9e5a06b632d09p2 ++-0x1.de52b7137b48ap-1 ++0x1.42702419de7adp18 ++0x1.87fba15348b74p-4 ++0x1.f1d4d2ed50b91p1 ++-0x1.f58ce2e3bed62p20 ++-0x1.0343179c7f2d3p4 ++0x1.c08e07f343f5fp0 ++0x1.c1bfa71d8698ep2 ++-0x1.3b5384007645cp3 ++-0x1.985c0097100f5p8 ++-0x1.31a462d00219dp14 ++-0x1.a1d1359744ef1p19 ++-0x1.4a50169190a5dp19 ++-0x1.47152657669dcp26 ++0x1.08ae25f622e03p0 ++-0x1.4a3ce79774730p1 ++0x1.4a69800ca5d1ep0 ++0x1.f5fc930d18d8dp4 ++0x1.643412561c61fp-4 ++-0x1.e07966a7404c6p11 ++-0x1.e6fbf6a0a6034p3 ++-0x1.fbd6e37a14101p2 ++-0x1.5a7960250d793p2 ++-0x1.a26cb448f2963p11 ++0x1.d54cc4dab0dc2p0 ++0x1.d49952cff6480p20 ++-0x1.a34ce477fb20bp-3 ++-0x1.9cec55870bb73p14 ++-0x1.cc4e1541cff60p15 ++0x1.17e2f5c7ae2dap0 ++-0x1.de61b653424aep5 ++-0x1.9f6f34286c574p10 ++0x1.d2b86784608d6p-2 ++-0x1.3395902eb25c8p20 ++0x1.69cdb5f2237f6p21 ++-0x1.50aa7555719afp1 ++0x1.450902d00dba0p14 ++-0x1.3581552b644e7p17 ++0x1.0c1ca2229363cp1 ++-0x1.aa0c55ea1366ap-2 ++0x1.935996dd54b32p16 ++0x1.3506f3b2a8c5bp4 ++-0x1.9ef4a31a3a5b3p21 ++0x1.6aed610ee94e6p3 ++0x1.9ec537389a85fp2 ++-0x1.b61b32703965cp0 ++-0x1.47b533489ac3cp14 ++-0x1.7a086173ea69ep-4 ++-0x1.9096e7b165d22p-1 ++-0x1.832a11dca8760p15 ++0x1.b46a101d0d0d8p-1 ++-0x1.754e34245b1d5p2 ++0x1.bd9a871af2cbcp19 ++0x1.91cd45ac60878p6 ++-0x1.f90ce27d3136fp-1 ++0x1.c793155aaf605p-2 ++-0x1.43c3752dba4e3p4 ++0x1.734ff4f414827p0 ++-0x1.5694b43404e9dp1 ++0x1.15ff858370de7p17 ++-0x1.6cb074bf09b29p-1 ++0x1.e15824dff4832p0 ++-0x1.a49b82d01f413p15 ++0x1.4e92a530645fap10 ++-0x1.0fb4501d2b553p8 ++0x1.6722853482a22p2 ++-0x1.e5ff02b36b547p3 ++0x1.8fd106fbca583p1 ++-0x1.cd3b94e6e9646p-2 ++-0x1.67e73006e1cbbp25 ++-0x1.798fe4eef94dap4 ++-0x1.9f845051b854ap0 ++-0x1.1801059eda986p-2 ++-0x1.e43bb3c1ba526p18 ++-0x1.858b7675fe3fep15 ++-0x1.95e2345d5fe0bp4 ++-0x1.3c5416ca090bap19 ++-0x1.495fa628eb2fcp-2 ++-0x1.7ef11453fd131p0 ++0x1.97369592c74a1p20 ++0x1.e538f5fd514c9p-4 ++0x1.3bdd939d79b75p1 ++0x1.51de3650db77cp13 ++0x1.0f1761cd1a600p-4 ++0x1.148233b993d99p2 ++0x1.93cd375850c5ep12 ++0x1.27629514fe508p-1 ++0x1.bb10511526fa8p-2 ++0x1.02fab5f81d1e0p11 ++0x1.59dbf0784024cp1 ++0x1.83fca118a0f13p11 ++0x1.549503148702ep20 ++-0x1.ebc3651a9536ap0 ++-0x1.a174916f8923ap10 ++-0x1.e62893a7af3aap-2 ++-0x1.f566616109d72p7 ++-0x1.6270b6860dc86p4 ++0x1.a88e8569e224ap2 ++-0x1.4f3ae6b9b7d44p15 ++0x1.565a510728736p3 ++0x1.ae5ff3ea9acf8p10 ++-0x1.cdaad52eecbb7p-2 ++0x1.14fe36e4c388fp-4 ++-0x1.b0fac12481c0cp-2 ++0x1.4f9e7648c99dcp24 ++0x1.fff1f1682d85cp23 ++-0x1.4e07d1cba1b3ep22 ++-0x1.aece66271bb23p-3 ++-0x1.480661fd12984p3 ++-0x1.cc42214f97882p9 ++0x1.9f8941c90d141p1 ++-0x1.a7cb21d392653p-4 ++0x1.f45fb2a44f985p21 ++-0x1.73ea53f7b5a83p0 ++0x1.ae0e97a5a226ap2 ++0x1.7116e4f8efeb7p13 ++0x1.b8689636e09d7p1 ++0x1.f87ea145c3eeap4 ++-0x1.7fb3d33c4b6f7p1 ++0x1.816ed7aac792bp-1 ++0x1.d46e75812b0cfp17 ++0x1.a94d05d52e058p-3 ++0x1.857ca451b8d1dp21 ++-0x1.dfe14188b48a1p14 ++0x1.7c5cb7db4b247p-3 ++-0x1.5b00f07b798c2p26 ++0x1.4927153475bd8p3 ++-0x1.659684713be27p-1 ++0x1.4b69e654ab5ecp14 ++0x1.599ca7a34504cp7 ++-0x1.e234942683626p-4 ++0x1.2dc9e2b98afd5p12 ++-0x1.11eff3e09aa18p1 ++0x1.66a8713d0f478p-4 ++0x1.ae07b611b2ed9p25 ++0x1.e5d5673df6e1ep2 ++-0x1.bc9a57d63d9cap-3 ++-0x1.f150f7c1a2718p22 ++0x1.a39e27b64a20ep0 ++-0x1.662a54062851dp4 ++0x1.c17bb0a5e2ee3p-2 ++0x1.2cde97703beb8p3 ++0x1.76c2a0f2dca13p1 ++0x1.44ef2264d458cp13 ++-0x1.39785220a1e11p3 ++0x1.0a9a846a9e8e0p3 ++-0x1.4c66f2ff6cd5fp26 ++-0x1.a3cf306fe7875p2 ++-0x1.f8fad771fd336p-4 ++0x1.56cce173621b0p23 ++-0x1.8b40322bb8a97p1 ++0x1.e9b391467db49p8 ++-0x1.c0b11253299d7p2 ++0x1.ce6213f40c4ddp3 ++0x1.98a4658fa2de2p0 ++-0x1.7714e7503ccfcp1 ++-0x1.e2c751117856dp-3 ++-0x1.116370d84cda0p1 ++-0x1.8a95106b4dd41p1 ++-0x1.83a101240371bp-1 ++0x1.a87241ef9f0afp1 ++-0x1.887e6438b7d77p0 ++-0x1.c51f915cee016p21 ++-0x1.90afb3af83a46p-2 ++-0x1.dd69445e1bce5p7 ++0x1.52ede1630d384p25 ++0x1.e5cb3017006a4p-3 ++0x1.7b37a1ae9bea3p22 ++-0x1.564077be3ff7dp19 ++0x1.0127514e5d65fp-1 ++-0x1.86f6945344917p2 ++-0x1.e27824003e156p-4 ++0x1.20f513644333bp6 ++-0x1.4d48e7c7bd1c2p17 ++0x1.df4f418ae8bcdp0 ++0x1.b530d7eb8c491p14 ++0x1.ae84640c8c195p-3 ++-0x1.99d503f399970p3 ++-0x1.7bac758737ddcp23 ++-0x1.b2e7529718232p5 ++0x1.d99e875cf2a8dp12 ++0x1.ad3fa0d2f24b0p-2 ++0x1.fd0875247597fp17 ++-0x1.d28dd391af036p8 ++-0x1.18c393d58dd4ep10 ++-0x1.7a2a73ac407fep10 ++0x1.885ec3882da73p1 ++-0x1.f4c664113f0d4p1 ++0x1.dc61d2bd58699p-3 ++0x1.50f330caf00fdp9 ++-0x1.2b4c2627a3648p24 ++-0x1.bddb32bea8700p-1 ++0x1.e55ac08bf2b42p0 ++0x1.e75cf1f0cd76ap0 ++-0x1.aeb8e3625b94ap-2 ++0x1.75a741f3c5a9ap-1 ++-0x1.017500e83e2dap7 ++-0x1.935241a43297ep2 ++-0x1.8c08819bbaca3p12 ++0x1.28f7569578c0fp15 ++0x1.9a68f5a0e6cb9p25 ++0x1.e99ce04bdef98p-1 ++-0x1.566b2614bedb3p22 ++-0x1.eb5840a35fdc6p25 ++0x1.75489211def83p19 ++-0x1.832cc5ad826a8p4 ++0x1.746297f53d755p1 ++-0x1.a92422038c33dp23 ++0x1.c94a716ac9472p2 ++-0x1.a780f5b351552p11 ++0x1.39b4a689dc65fp15 ++-0x1.063fd407d19b2p17 ++0x1.6c96851c4c0bbp-3 ++0x1.343a53f0ac710p-1 ++-0x1.78da56a8efd89p-4 ++-0x1.2e08371fa4c1dp1 ++-0x1.9cb170edaa8d6p0 ++-0x1.c47b95e92d85fp5 ++0x1.22d540cd4e25bp0 ++0x1.c0d7f6f009ad8p11 ++-0x1.694c81226c9d5p0 ++0x1.559fe2c8a2cb1p15 ++-0x1.be71b00f82b6dp-4 ++-0x1.949d26f8956a4p0 ++-0x1.e794823d81668p2 ++-0x1.913cc722037aep4 ++-0x1.6c89e06ae49a0p7 ++-0x1.d85ac741cf404p-1 ++0x1.827ce70a4080ep-4 ++0x1.d00906b80e8fep1 ++0x1.a5eb32c312d71p3 ++-0x1.1c82507185876p-4 ++-0x1.2745f53788520p8 ++-0x1.d59f5009d4e5cp2 ++0x1.cc2070bdb8850p18 ++0x1.1720074ab1a4ep1 ++0x1.8cd267087035ep1 ++-0x1.e5066000552e0p1 ++-0x1.894bb7d7746d1p0 ++-0x1.ffc9031f3af42p16 ++-0x1.9867b7cae951ep11 ++0x1.33ffa6ff96953p-4 ++0x1.18b8b52580f2dp-1 ++0x1.8036540909c52p1 ++0x1.cf69072d92af2p9 ++0x1.980aa121c5e65p1 ++0x1.5f89c3f3a61c7p25 ++-0x1.2e09a10012e1fp5 ++-0x1.a585c7402c27ep-2 ++-0x1.485eb3f6d7ecep-3 ++-0x1.f9bd852a74583p10 ++-0x1.3b7f83fbcda42p1 ++-0x1.6591217c65a71p17 ++-0x1.7b21e6ee5ca9cp17 ++-0x1.c979f792dbca7p11 ++-0x1.77bf75c469ac6p0 ++0x1.d16b6275c0f7dp14 ++0x1.4917f41f8b6a2p1 ++-0x1.19cd525e86beap9 ++-0x1.6e5003f71a811p14 ++-0x1.370ab7f9719f2p14 ++0x1.386006d492b82p3 ++0x1.1a58e03059f7cp12 ++0x1.2500012feb2d9p7 ++0x1.4d36d2e22e8d4p5 ++-0x1.f3e1a009ee07cp23 ++0x1.4668d78d78095p12 ++0x1.79aa13307ebf8p3 ++-0x1.c487960e89b2bp2 ++-0x1.06e8a5658fb35p-2 ++0x1.55c7f05a491fdp24 ++-0x1.0523e2d088c7bp11 ++-0x1.f62864f5158c9p19 ++0x1.c49ce5492ee6dp-3 ++0x1.cdb9120e5b67ep17 ++0x1.8f8a5268e820ep-4 ++0x1.6ee1e30d592a4p0 ++-0x1.812844c5cb134p2 ++0x1.6df1755141fd4p24 ++-0x1.728300fa1781fp14 ++0x1.8947c3e79ed66p0 ++-0x1.9844d48620c7fp8 ++0x1.23655019dc226p2 ++0x1.a9e1473cc8a13p12 ++0x1.66305231c4640p7 ++0x1.82af66fe8c503p2 ++-0x1.bc6b01062138ep15 ++-0x1.896955bc6c769p-1 ++-0x1.a9ee65b00a2e8p21 ++0x1.f4c3e6cd69231p-5 ++0x1.9013f5a753f8ep8 ++-0x1.d92d8497ba609p24 ++-0x1.2e2681d1e84bap3 ++0x1.8be4435259a45p7 ++0x1.79c7f5a2e6e62p2 ++0x1.acdbe4eb4b925p22 ++-0x1.35aae23bd5519p3 ++-0x1.733ba7e8564aep20 ++0x1.f77991555ff26p-5 ++-0x1.1c5745f873d55p-3 ++-0x1.1b14e11d332dcp-3 ++-0x1.c731514f4f896p20 ++0x1.a0c5c483ebf17p7 ++-0x1.36b1d13cb2c7ap19 ++-0x1.7a38c0bb685a4p2 ++0x1.6236e4c6b17b5p10 ++-0x1.f2b9767a6798ep1 ++-0x1.3958443bc6781p3 ++0x1.d6f1f3d9224a2p13 ++0x1.81b9f2569be9bp-2 ++-0x1.8f52243d1205fp2 ++0x1.2e2e25cd3e4a7p3 ++0x1.d34c76b790df9p2 ++0x1.7a91752f07156p26 ++-0x1.454b06030e52cp1 ++0x1.2c40025ab0e66p3 ++-0x1.76d66036ed303p18 ++0x1.667592a8df4efp25 ++0x1.415511ec79f5ep1 ++-0x1.7bbb12490183cp26 ++0x1.824ec336555b6p1 ++-0x1.b8dd16e17d94dp-1 ++0x1.7df770031af25p3 ++0x1.7bff02b791614p-3 ++0x1.13f597d144c47p4 ++0x1.81e4962b19a23p0 ++0x1.3900731ded692p13 ++0x1.9ed1c64a3942bp0 ++-0x1.e87ae52969fcdp-4 ++0x1.79bb77cc1f90cp2 ++0x1.14693020af9bfp23 ++0x1.8b61256862012p0 ++0x1.edae80414ab70p3 ++-0x1.93ab70cfa5b06p20 ++0x1.8ba9c535f5d61p1 ++-0x1.805ee155735acp1 ++-0x1.838ec4acbd018p-2 ++0x1.f32f63eb94fabp2 ++0x1.e241b1649d3b8p5 ++-0x1.3253458419677p10 ++0x1.e0df72e4e1543p11 ++0x1.e11d606072ff9p3 ++0x1.86c16681265b6p5 ++0x1.8628f44708c8bp23 ++-0x1.e00f07434fc92p9 ++-0x1.c17540870ee47p3 ++-0x1.9e5bb19dd040bp3 ++-0x1.4b2ae7e7eb36bp7 ++0x1.563c647e67c1cp14 ++0x1.9fd3804bf753ap1 ++-0x1.e01b361851110p5 ++0x1.f4c404c183defp3 ++0x1.91f9d60737e96p3 ++0x1.c2b2e43a35dc2p3 ++-0x1.93d6f51eaa6b7p0 ++0x1.077b77efc4f82p4 ++-0x1.5a77916ce4424p4 ++-0x1.68b4d3263da38p21 ++-0x1.f374766b6ed6ap2 ++-0x1.a9a9833b70761p0 ++0x1.e32a36975f82ep13 ++-0x1.faee82ffb3f86p3 ++0x1.e36e2752045d0p24 ++-0x1.65cd92ab90cd5p3 ++-0x1.2c9e444e88b94p3 ++0x1.f120d034d2381p10 ++-0x1.a9a8f0b3f6514p-4 ++0x1.936706bd2d06ep1 ++0x1.a0c1379968e55p15 ++-0x1.857891fb49f2dp0 ++-0x1.56d056a4a7495p25 ++0x1.903154bd06e72p0 ++0x1.6682d268e3100p4 ++0x1.3193534e62ce4p10 ++-0x1.8436b490e2355p3 ++0x1.c780d229e6f70p1 ++-0x1.c56866de11a8fp3 ++0x1.882d57bffac4ep17 ++0x1.5c9b122b1d7fcp-3 ++0x1.844794defc7edp0 ++0x1.ee2d82135ae68p-4 ++0x1.85279651395efp16 ++-0x1.2cd1153d349f2p19 ++0x1.7b6dd3b4f477ep12 ++-0x1.7288f46a576b0p1 ++-0x1.f8c0e0fc4bb49p2 ++-0x1.183706bd54880p3 ++0x1.ba0d572401eb1p-2 ++0x1.ca518633bac17p7 ++0x1.cd57538cf882cp-3 ++-0x1.8381b568c9479p9 ++0x1.1e9183ce544bcp13 ++0x1.6acba6699c0b9p4 ++-0x1.ec73039e9f0d4p20 ++-0x1.6477f2857b071p-3 ++0x1.e4a176c91821cp9 ++-0x1.8c0b56ccb6472p4 ++0x1.88bb9270ccca0p0 ++0x1.01872043ef4f6p26 ++0x1.a699a703d54f0p2 ++-0x1.4f9480c72527fp11 ++-0x1.f3922598eb070p25 ++0x1.ec1122cf73e00p11 ++0x1.1a5df470f93f2p3 ++0x1.2c4ac04f45ad8p2 ++0x1.420df3f07e2e9p1 ++-0x1.da3007b6e32e6p-3 ++0x1.c58594ba64852p5 ++0x1.97f94564a530ep1 ++-0x1.8f2f3232703fap23 ++-0x1.3aced1c22945fp3 ++-0x1.9fc3b1f2df6bap18 ++-0x1.2f9400213bfacp26 ++-0x1.5a93a1aecd7f8p23 ++0x1.e21fb377f0629p3 ++-0x1.60d2b29133715p2 ++-0x1.b35fd552a06bdp2 ++0x1.f888f3bf0894ap3 ++0x1.6179c63df740ap2 ++-0x1.1b57e16b67305p12 ++0x1.2df7a492a55aap3 ++0x1.f5a8c595b66f3p12 ++0x1.eb9b31a499310p0 ++-0x1.fa29138391d8dp24 ++-0x1.31e9737787955p22 ++-0x1.50bec0d665bd3p4 ++0x1.240336c6f50ecp20 ++-0x1.234332620141dp2 ++-0x1.494922947d1dep13 ++-0x1.4589500e3dc0cp-4 ++-0x1.c5b106e6c98c4p3 ++-0x1.8e5975aebe391p1 ++0x1.4acbd1eca3685p16 ++0x1.3767b5309ae35p25 ++-0x1.ab55b215961b5p19 ++0x1.9bbb7240953bcp6 ++0x1.2a69c6c2ce166p-4 ++0x1.236446d855ea1p26 ++0x1.007d67d2f6ae5p14 ++-0x1.465752c4bba54p4 ++0x1.c2c120ada26efp24 ++0x1.89d8e773ca030p0 ++-0x1.47d112473b7d2p23 ++-0x1.961ec43a6ac1bp0 ++0x1.cb149641f5e31p25 ++-0x1.445105fd4a114p13 ++-0x1.fbecb12a6b027p23 ++-0x1.7d2f532f070e7p24 ++0x1.8623305d4e6b2p12 ++0x1.9d4e770b846b6p20 ++0x1.2e6f72255a4e3p25 ++0x1.217f53ffa3517p18 ++-0x1.114cf59a17da7p22 ++-0x1.9058c29b9c42cp0 ++0x1.8b4964313d448p0 ++-0x1.1324f4ac83d84p17 ++0x1.8cdc938858e1cp1 ++-0x1.8e3ac7bd1d9bap1 ++0x1.91dd306db21b7p3 ++0x1.1dabf17b5d5ecp11 ++-0x1.8c5023b0520fbp17 ++0x1.519133d1a30c1p0 ++-0x1.83f8b0095f08fp11 ++0x1.a2c384402e2dep0 ++-0x1.99604221a841bp-3 ++-0x1.238c553c5b382p11 ++0x1.255263c1e7ea1p-2 ++-0x1.f6abe2ca3fa18p-4 ++-0x1.28b610d704296p2 ++0x1.7fe030dd6870bp21 ++-0x1.9277b3b585daap1 ++0x1.4aba5560a518fp18 ++0x1.d8b2d183392ffp12 ++0x1.606e50d62a689p3 ++-0x1.c9fe06391a2ffp6 ++0x1.33a2c66357454p2 ++-0x1.c14834e7cc6fep20 ++0x1.70fe71d9a61a1p10 ++0x1.9124214c779abp0 ++0x1.36fe96d18bbb1p5 ++0x1.ac0886bed0cbap-3 ++0x1.c394c39ec727ep21 ++0x1.8ede90b9ad083p1 ++-0x1.63f723efeb8aap6 ++-0x1.8006a11624d6fp9 ++-0x1.991dd79a46696p14 ++0x1.624f7005c927ap-3 ++-0x1.5a1bc5448ef00p15 ++-0x1.a1b2d04dd23dbp22 ++0x1.fbdae5e7003fep9 ++0x1.77e2f5191b00ap26 ++0x1.6acd972fb203ep7 ++-0x1.92e403fb5cd1fp1 ++-0x1.bdb8819563c37p3 ++-0x1.978c07f231d8cp-4 ++0x1.d394c0387504bp3 ++0x1.2ad084ae8150fp2 ++0x1.1c84d77148aeep-3 ++0x1.6cdec2610b6e2p9 ++-0x1.ad36f42f1539cp10 ++0x1.6b7736f489b84p23 ++0x1.428d260202acdp-3 ++-0x1.ac7df640f2e9dp-3 ++-0x1.383325e10f339p16 ++-0x1.9072c3baac08ep2 ++-0x1.8d25202dfe5e9p1 ++0x1.56cce34ce0a0fp3 ++-0x1.87e0b26002871p0 ++0x1.e58bf4dbae4e0p8 ++0x1.f721c656141c5p-5 ++0x1.936a122b128a9p3 ++-0x1.9d77a3df09bffp0 ++0x1.fee682c2083b1p-5 ++0x1.0df346c938fa6p20 ++-0x1.79a4807dc1c7cp12 ++0x1.43cb96fb17819p15 ++-0x1.f6cba0b606489p3 ++0x1.279ff1f5aa40ep2 ++-0x1.4a0200fac8a92p13 ++-0x1.5bb4a64995a2fp6 ++-0x1.8cfdf28a87367p1 ++0x1.b33a47d6a5006p12 ++-0x1.2d44128359d7ap3 ++0x1.8e27c5f19370ep1 ++0x1.b172a51df2790p12 ++0x1.9418b67f79674p2 ++-0x1.18472016853adp-4 ++0x1.429a944c7fc15p-3 ++-0x1.848c2357e315bp0 ++0x1.94ffc4b0437b7p-3 ++0x1.0ab3c61460bf1p23 ++0x1.c46df37c82e74p3 ++0x1.ae4073dbb6faap1 ++-0x1.333756903e0d4p2 ++0x1.9897d041ad55ap0 ++-0x1.dc34d00205413p-3 ++0x1.11d895596200dp0 ++0x1.2c40f229821eap3 ++0x1.cdf886a7aa583p1 ++0x1.981c0286db7cep1 ++-0x1.9e091230bd3a4p0 ++0x1.793f34193764dp-4 ++0x1.bb2a40332c042p-3 ++-0x1.f14492192a73fp-4 ++0x1.706253767db02p-1 ++-0x1.89a6c7e27292bp0 ++-0x1.9ecc544fb92bbp0 ++-0x1.929732055c207p3 ++0x1.7446d51c7b42dp-3 ++-0x1.86ed158a74c67p0 ++0x1.514041392ff26p2 ++0x1.82d476bb8edb4p0 ++0x1.7fd9b27331c05p-1 ++0x1.f5b7d49823843p3 ++-0x1.f69264abeafa3p3 ++-0x1.3b9c9235047b1p-3 ++-0x1.618cb26e482adp3 ++-0x1.7ff1014b720ddp2 ++0x1.89c1b5f05dc6ep0 ++0x1.8433102ecaabcp0 ++0x1.1a6f4686b08cbp-4 ++0x1.f6e9f6c4c11d8p2 ++0x1.f420f4826d0ebp3 ++-0x1.07e6c7ee77297p-4 ++-0x1.883073624792fp0 ++-0x1.413bd59318f29p10 ++-0x1.eccdd630f04c1p-5 ++0x1.ca83404a9139bp-4 ++-0x1.2fb1d040fa704p2 ++-0x1.ec2965839cdf8p-4 ++-0x1.980927a49fc8ep0 ++-0x1.8891479510a4cp0 ++-0x1.160f00148547bp4 ++0x1.2c829387de51dp3 ++-0x1.b823d3652d1f6p-4 ++0x1.610211fe18f2cp4 ++-0x1.4814c0233ff45p4 ++-0x1.910a500100124p3 ++-0x1.938eb41b840f3p2 ++0x1.8b3dc18cdc10cp-3 ++0x1.82bbb15b4a321p0 ++-0x1.7ca807b240b48p0 ++-0x1.e41654090b761p-6 ++0x1.2e37b710fc120p2 ++0x1.f6b7940e7b623p3 ++0x1.110c63611fdc6p3 ++0x1.02ee201bcaac4p-1 ++-0x1.15cc478b9585fp-3 ++0x1.eaa6a5dba0880p-3 ++-0x1.5064263da0e06p18 ++0x1.29e4125754701p2 ++-0x1.9877831252381p-4 ++0x1.8f2e232e9ac5dp2 ++0x1.2d80559c80ef0p3 ++-0x1.9254d7b9c8444p0 ++-0x1.f4e9e64183d12p-1 ++-0x1.f4c7a7634e935p3 ++-0x1.9abbe3194229cp0 ++-0x1.9919748132712p0 ++0x1.5f26256acb653p3 ++0x1.5763e1d0c726bp1 ++-0x1.94ff2678d1f72p-3 ++-0x1.a90bb2e15f04ap0 ++0x1.2dd9e546986a5p3 ++-0x1.f740c1ba3020dp2 ++0x1.c64395e34728dp-2 ++0x1.e3d0458eabfd8p1 ++-0x1.ed0765e6ea0f5p-3 ++0x1.dab346294cbdap-4 ++0x1.f61623d7e20b5p3 ++0x1.af9281c09646cp1 ++0x1.1b1e15cd3bcc5p16 ++0x1.06c4c10e6c8dep-4 ++0x1.dd07569c3c3ccp-2 ++-0x1.c15824199f02ep1 ++0x1.5243561208a38p-4 ++-0x1.f416f571790f9p2 ++-0x1.caef3657e7abbp1 ++0x1.83fbe5b4af7dcp0 ++-0x1.8853d6f37a1efp0 ++-0x1.46da6147a1b10p4 ++0x1.302416be4e2a1p2 ++-0x1.f2f8a5dc53cf4p2 ++0x1.6055e6e35bb41p-1 ++0x1.143d145693511p2 ++-0x1.6950a182bf9a2p-4 ++-0x1.8fcc8236972a5p2 ++0x1.e9cb13665b011p14 ++-0x1.f393f56d36bd5p2 ++-0x1.6965240cd8bcap3 ++0x1.941dd006b64ffp2 ++-0x1.f1e3d41258e12p1 ++-0x1.fccf763e37c40p-2 ++-0x1.b796d71e63f83p0 ++-0x1.92b6c5b1be835p3 ++0x1.9ce932c77615dp0 ++-0x1.73fbf1729d68fp2 ++0x1.478eb664414a1p4 ++0x1.56d8470b12ea3p1 ++-0x1.3e8954f72e006p1 ++0x1.f65e065d156a7p3 ++0x1.84664031b46b2p4 ++-0x1.f47a93802ea52p2 ++-0x1.e9592161077e5p-1 ++-0x1.2bd1669992834p3 ++0x1.6e2943a16b8e1p-3 ++-0x1.e7d855d59c297p-4 ++0x1.8f433768a46fdp1 ++-0x1.e515d3f871f61p-4 ++0x1.90af17c3b46a3p1 ++0x1.888852da31b55p0 ++0x1.2b2b219aba250p-4 ++0x1.acd68248a4138p3 ++0x1.2e88f26ed5c10p4 ++-0x1.93d8526e03271p2 ++0x1.326cd7502e35dp3 ++0x1.97cf340cdd0aap1 ++0x1.9bf172a79ddddp1 ++0x1.f762e63f6aa11p3 ++-0x1.a352761c52850p-4 ++-0x1.8ca4b46938898p0 ++0x1.5faf86ccf0263p3 ++-0x1.59de804f2786ep-3 ++-0x1.1411b2e66b984p4 ++0x1.c1744154cb07cp-2 ++-0x1.e470062fd9902p-4 ++0x1.96cdb4f1f7df7p1 ++0x1.23fc15223f81ep2 ++0x1.36a273c93939cp-4 ++-0x1.cc76161ba5551p2 ++0x1.30a473160c957p2 ++-0x1.2b9fd42df7d03p11 ++0x1.96269286b7ffdp1 ++-0x1.26acf7d9c5873p-4 ++0x1.4e9a05aed7b47p-2 ++0x1.8c2310e286165p3 ++0x1.2e7ea55e6bab4p3 ++-0x1.947447e283cf8p0 ++-0x1.5def45dd8c82dp3 ++-0x1.3562b72377e9dp17 ++-0x1.827dc1096f2c7p2 ++-0x1.864d742b9a86ap0 ++0x1.020c84197b2d6p-4 ++-0x1.c2b3209b520f2p3 ++0x1.4d46507b92ebfp1 ++0x1.f7a911dc6f5edp3 ++0x1.546ab7b47b80dp-4 ++-0x1.8e74270390650p0 ++0x1.798ef3689843dp4 ++0x1.e4ed141ca4042p2 ++-0x1.912b60e8b2288p1 ++-0x1.a446f3b0c931fp-3 ++0x1.8a8ca0324e319p1 ++0x1.85f9f17f3303bp-4 ++-0x1.8da4b789837fbp0 ++0x1.e0c1b65e1731fp0 ++0x1.51d9359cbafe5p0 ++-0x1.8c93e53362a95p0 ++0x1.2cb685f56e9c7p3 ++-0x1.24ca32a7d2e7fp-4 ++-0x1.f3a7d55be814ap2 ++-0x1.5f5563552f3dbp1 ++0x1.9651239a8f51cp23 ++0x1.7883f140d86e3p4 ++-0x1.f5d4704cadef3p3 ++-0x1.1a8b81c161806p-4 ++0x1.13a766d95ae15p-3 ++-0x1.788d1565e8c73p0 ++-0x1.5a00b1d8bf722p4 ++-0x1.142ef555a9f1dp2 ++-0x1.9f5fd239129c0p1 ++-0x1.9234030e398e9p0 ++-0x1.de3ee1a88c608p25 ++0x1.98b413f614dd1p1 ++0x1.919893496d760p0 ++0x1.cb4c6209daacdp1 ++0x1.716aa6b3989dep0 ++0x1.388236a8a2105p17 ++0x1.2d8ea65a5418ep3 ++0x1.8d3b6586a1f83p1 ++0x1.2ee22305d240cp2 ++0x1.513c50ad7096ap0 ++0x1.274f61da084fcp21 ++0x1.8e999360ff9bfp2 ++-0x1.634ee01f1e244p3 ++0x1.f56b84f17d59ep3 ++0x1.90cd66c769319p3 ++0x1.948793a745cb3p1 ++-0x1.922cc64d4c613p2 ++0x1.9202f01408a2ep1 ++0x1.647af0f3e78e8p0 ++0x1.92c404a15ff85p3 ++0x1.296510b2025d9p3 ++0x1.8af4d01937e3dp1 ++-0x1.905807696feddp2 ++-0x1.c5e746b866817p3 ++-0x1.74abf60c7458dp11 ++0x1.9fd310b80fc3fp-1 ++-0x1.0088c702d520ep3 ++0x1.99e684301b40dp1 ++0x1.9e40e369cece9p0 ++0x1.9a10f4d7ad560p0 ++-0x1.119517d95be1dp0 ++0x1.6507f65c0a11ap-10 ++-0x1.8d7e97db6ee5dp1 ++0x1.77b3e74ff2733p0 ++-0x1.9142f42793975p2 ++0x1.b08f86307ef40p0 ++-0x1.07f605feceabcp6 ++0x1.847750d22aedap0 ++0x1.da8917abe3345p-1 ++0x1.996981db39a5cp1 ++0x1.84af267337c45p0 ++-0x1.2d1e62cdb58fep3 ++0x1.57eb741c405e9p0 ++-0x1.9306d461c4f0dp1 ++0x1.97511167e78b7p1 ++0x1.a378c189bb9f2p0 ++0x1.9f116139e3045p3 ++0x1.0e56b2d056bd2p1 ++0x1.9022d6b0f776ap2 ++-0x1.9a66b69d283d3p16 ++0x1.93f2d78fa20b8p2 ++-0x1.960097e81f663p1 ++-0x1.f16b11682801ap2 ++0x1.7c5836e306cd7p4 ++0x1.931ce13cf2e8ep3 ++-0x1.9604801aef305p1 ++-0x1.6047b5e1f6282p4 ++0x1.8afcb3ed73526p1 ++0x1.f6f66374ec272p3 ++-0x1.637a71d0dd8cap3 ++-0x1.f503c3e728412p3 ++-0x1.6752748f04736p12 ++0x1.c39482bf49bafp0 ++-0x1.776fc1f105341p1 ++-0x1.1c8c0693eea0ep4 ++0x1.bf500107c5bf8p1 ++-0x1.c8cc1330ebb0fp3 ++-0x1.9fc43100011e3p1 ++-0x1.0218334d9287bp4 ++-0x1.873dc40133dc7p2 ++-0x1.6108e6ac3ce75p2 ++0x1.827f54be95fd2p2 ++-0x1.b3b9c1b2bc85bp1 ++0x1.6a566601abe51p1 ++-0x1.1838e51e22a74p3 ++-0x1.ec20a2f393847p-1 ++0x1.50e3f2decb26bp0 ++0x1.9e5c631aefd23p1 ++0x1.e380f3f3d1435p1 ++0x1.2d2396f6e3d53p21 ++-0x1.d37267e0da8b8p2 ++-0x1.dc488296aade7p-5 ++0x1.46ec674ce2a5dp13 ++0x1.554101eac799cp13 ++0x1.2f3013f5a6c54p8 ++0x1.6f83a66c663f4p4 ++-0x1.2b08f43aab39cp11 ++-0x1.e1e0d1853224dp-1 ++0x1.d771b17516553p6 ++-0x1.887044239cfe8p1 ++-0x1.a1db55509e8a4p1 ++-0x1.bfa480fc2440ep0 ++-0x1.6d6e63cfe5182p16 ++-0x1.fb48863e0822ep0 ++0x1.9f00e03bd225cp2 ++0x1.759ad7d2fd408p-6 ++0x1.127da379773a8p0 ++0x1.f29402cc634ddp2 ++-0x1.9952a78ed61b8p2 ++0x1.97dd5139447c3p1 ++-0x1.a76e765e68c3cp1 ++0x1.8e67566cd5e8ep2 ++0x1.1b03a778e2d96p0 ++0x1.5082b4b12d87dp0 ++-0x1.b7f804e64ad6dp-1 ++-0x1.fd8ec1fbdfc91p-1 ++-0x1.c72146ec63767p0 ++-0x1.535215502bb28p9 ++-0x1.7b86638bd0a8ep4 ++0x1.2ee16587be28ap25 ++0x1.e01b63e9ed441p-5 ++0x1.694304bf328eep8 ++0x1.ad55c78d3654dp3 ++0x1.9eee975660a8ap3 ++-0x1.c8b2561c9f81cp3 ++0x1.8283c7a80a610p0 ++0x1.5b20d2df32431p4 ++0x1.9cd6a2f10b171p1 ++-0x1.420cc50d7cdc2p8 ++-0x1.dd9861944bbb3p3 ++0x1.34a7a7976a495p0 ++-0x1.d583650030438p-6 ++0x1.d460c5cf3f543p0 ++-0x1.d465b0c30b6edp1 ++0x1.3c7da5c7e5924p1 ++0x1.2346875c60507p2 ++0x1.8a7b81be25ee8p2 ++-0x1.397700c5fcc57p2 ++-0x1.69d2e1c810103p14 ++0x1.a85411bd063ccp1 ++-0x1.0e29e1cbda382p1 ++0x1.9a5e601081659p1 ++-0x1.a7889779ffa67p0 ++-0x1.438e04868ccc9p4 ++-0x1.baa5420b07fdap0 ++-0x1.6db8900accb05p19 ++0x1.a8aec73d93c27p3 ++-0x1.77d4072c1ccf2p0 ++-0x1.21f6b21bc817ep2 ++-0x1.f6a2f62a6cb31p2 ++-0x1.fc06459a51fb8p2 ++-0x1.9af657156b1f3p2 ++0x1.506bb4f11e78cp0 ++-0x1.33ebc72ee6932p2 ++0x1.ae86415f42273p2 ++-0x1.9bf4a6fe8e910p1 ++-0x1.e96e9164690fcp21 ++0x1.6947f51227604p2 ++0x1.6013a22a2ddd3p1 ++-0x1.6af96677a90abp4 ++0x1.8afb44943c65ep3 ++0x1.8edc46a59110dp1 ++-0x1.27672769919c5p3 ++-0x1.965194e8561b3p0 ++0x1.3b1025ed73e67p1 ++-0x1.847770922125cp3 ++-0x1.dd5f522fb2873p-5 ++-0x1.5efb85cc876f7p4 ++-0x1.e68de705848ebp-5 ++0x1.7ead02ce67bbcp1 ++0x1.a051e272e6562p1 ++-0x1.86e703217068ep2 ++-0x1.9f42e3ab98d72p1 ++0x1.67ed973022fefp1 ++0x1.2fecd6c002277p9 ++0x1.78c3e7b8861cdp1 ++-0x1.a871661620c12p-6 ++0x1.f44003f7dc467p1 ++-0x1.8de9c11f74395p0 ++-0x1.e819107f5c6e2p3 ++0x1.95cc935ccd8b3p3 ++-0x1.8f4ed509b97e5p0 ++0x1.69451445560b1p1 ++-0x1.95ef447fbd184p3 ++0x1.86f83259b5fd7p0 ++0x1.0477224f543aep4 ++-0x1.84b8700c2e94ap2 ++-0x1.d83170e4e3d42p23 ++-0x1.8f0f6463688c9p3 ++-0x1.627477b68d92cp4 ++0x1.b08cf6f35c65fp1 ++0x1.408dd4780aba4p6 ++0x1.1086512459ff1p9 ++0x1.3909f67380c33p3 ++-0x1.949b71c1a11cep2 ++-0x1.8d1345e55533bp3 ++-0x1.8713c256b3756p2 ++-0x1.dbc685c55e3f5p25 ++0x1.fa1540a9be9a3p3 ++0x1.861632597290fp21 ++0x1.8a92623188bf5p2 ++-0x1.306816f3567cdp3 ++-0x1.46c942568bb98p4 ++-0x1.493192769939fp-5 ++0x1.6c7626b593bc1p15 ++-0x1.de9ae14ed3b14p-5 ++-0x1.9ceab67fd3361p17 ++-0x1.4635c7e723683p14 ++-0x1.f66857bcde805p5 ++0x1.1404718e327a9p5 ++-0x1.8bead04147772p0 ++0x1.67f23030a3b9cp-5 ++-0x1.605b1167aec6bp26 ++0x1.c492b71449ac9p-5 ++-0x1.896c46f57416fp0 ++0x1.f67af48b080f1p4 ++-0x1.2bf7f4c847654p2 ++0x1.d16a349978580p5 ++-0x1.62f916740779cp8 ++0x1.88d1874b175c6p0 ++-0x1.44bb24ced7803p23 ++-0x1.8b3367f4a1c9ap1 ++0x1.f904679db18c3p10 ++0x1.8af0b3bf1bc0ap1 ++0x1.91bd642036dc7p-5 ++0x1.e05700bd746ecp-5 ++0x1.442c71d7052dfp11 ++-0x1.c0860397d57f6p-5 ++0x1.22fa512afd525p15 ++-0x1.17963471d9c22p9 ++0x1.dc53e5919c4e9p-5 ++-0x1.f0ab744dd7c5ap12 ++0x1.6c6b174f1b2ddp25 ++-0x1.c0e8e1d4be4ddp21 ++-0x1.527b6735e78fdp-5 ++-0x1.eb2570edcb498p-6 ++-0x1.827ee5ca4565ep17 ++-0x1.d312763bdbfc9p-5 ++-0x1.1be7c35c5187dp21 ++0x1.bb05e3cf5bed1p8 ++0x1.2b35242e28392p2 ++0x1.2c478726c2eadp3 ++-0x1.f601e4eb21834p-7 ++-0x1.aa9224d5c7b99p12 ++0x1.ee4f61f98712ap25 ++-0x1.f11477e64dd5fp25 ++-0x1.eacea5fdf0447p22 ++0x1.8090172f53488p-5 ++-0x1.874452a514b8ap-5 ++0x1.b09b7525da067p-5 ++-0x1.a4a65761b73e4p19 ++-0x1.3edf87b67bac9p11 ++0x1.40df32ab49b60p16 ++0x1.ad82d260cd27cp12 ++-0x1.79d575123f3d3p4 ++0x1.1a420309f1acfp19 ++-0x1.e3d2815fcea1ap-5 ++0x1.9564275cad6b1p20 ++0x1.b22d964fa5da9p16 ++-0x1.ac6ec099f3767p12 ++-0x1.3a56c36fd71f8p5 ++-0x1.10a2668b9a962p19 ++-0x1.f582e4fb4b9fcp3 ++-0x1.c91490880d0abp9 ++-0x1.ed1516dd4512ap-5 ++-0x1.bd52b3aaf56cbp20 ++-0x1.5f8674c2c25b3p3 ++-0x1.0c0c55ef2b998p20 ++-0x1.d192227536e73p24 ++-0x1.2faaa2ecfe577p24 ++-0x1.b90651cb301d0p-5 ++-0x1.ac3b63b519eadp-5 ++-0x1.2bd446f3ca7f3p2 ++0x1.a430460e6a9b6p12 ++-0x1.b3d576f970023p-5 ++-0x1.a78456f24ad8bp21 ++-0x1.8e6d24c106191p-5 ++-0x1.445ac22c0535bp10 ++0x1.6006b3be58fcdp5 ++0x1.e2c9a30fed3dbp-5 ++0x1.a9c595abf1803p17 ++-0x1.dda6a16942918p5 ++0x1.882b80046b531p-5 ++0x1.e312c4711d211p-5 ++-0x1.ffc9304847f6ep23 ++0x1.e2bdf53a0e7eap-6 ++0x1.aafe55c56b961p4 ++-0x1.a42c00873fe91p19 ++-0x1.6e05225136648p14 ++0x1.8b6d7748a44d0p1 ++-0x1.4f9b15e74489bp24 ++-0x1.d0f83650acd18p10 ++0x1.75d88737c154ep10 ++0x1.fd9f30446da4cp12 ++-0x1.ea0f976d9c95fp8 ++-0x1.2e7ce0068807bp3 ++0x1.408f556f1b433p22 ++-0x1.33dd44ccdcad4p9 ++-0x1.1392b23681ed7p22 ++-0x1.a07451f59178ap0 ++0x1.4be7960b80101p-5 ++-0x1.c35dd7637fabbp3 ++-0x1.14eaf252d4e69p24 ++-0x1.eb5cb6f319984p12 ++-0x1.ff5795cc9e8c9p25 ++0x1.f373c7948157ap2 ++0x1.8b11d503c9621p9 ++-0x1.a6fba484a1e0dp23 ++0x1.185dc1c0b0020p9 ++-0x1.4205d4a32810fp8 ++0x1.ba7665e0e6ca3p-6 ++-0x1.9114139572d64p2 ++0x1.8550d5a435556p6 ++0x1.9217f777d16afp1 ++0x1.523d75d52216bp22 ++0x1.eaf44618ace9cp25 ++-0x1.0ce264ba236dep25 ++-0x1.dd0c66bca284fp4 ++0x1.e133b560a7249p-5 ++0x1.2e73200b72efcp3 ++0x1.31d3f1c22bbefp-5 ++-0x1.160c73ebb453bp9 ++0x1.725517d421c01p23 ++-0x1.b322115912690p8 ++0x1.3123b6c190157p15 ++-0x1.f7c6d4c05900ep2 ++0x1.4199c1016ddbep21 ++-0x1.939ab538fcf52p1 ++-0x1.fe9b67751e8e2p16 ++0x1.8194d6944c477p15 ++0x1.84ddc763e1a66p0 ++-0x1.4e1de2c8b8b84p-5 ++0x1.f2b9c3f27bde1p11 ++-0x1.616ef1dab5092p3 ++0x1.f592e4f2759fep3 ++0x1.4aa7e080f1cdbp11 ++0x1.ce0a91e4edc80p-6 ++0x1.534af4542f502p9 ++0x1.9a5816c8c9b58p-5 ++0x1.71ed06e256291p11 ++0x1.1a3b208fc7a34p17 ++0x1.93a935a59f8c6p2 ++0x1.d0cc856988238p6 ++-0x1.1aba30a4c9984p9 ++-0x1.f8c461cdebee7p21 ++-0x1.899a449c6c3ebp20 ++0x1.363ec045afdeep9 ++0x1.439216bc4453bp8 ++0x1.4447c6df4c7afp17 ++-0x1.9911c1e4c62abp15 ++0x1.e16500b58f801p-6 ++-0x1.b705b75ed89fbp22 ++-0x1.01e46049e5a39p20 ++-0x1.932304c2d6686p-5 ++-0x1.e6d670226ad2ap-6 ++-0x1.bd07e41c8e8bcp18 ++0x1.4a0e422534f2bp-8 ++-0x1.6940b30465840p8 ++0x1.d733705bedd6ep-6 ++0x1.d5cc051d8c218p19 ++-0x1.2c33e54a305f1p3 ++-0x1.e8b8d19effe41p-7 ++-0x1.3251544f616aep10 ++0x1.7695f68f3e6c7p15 ++0x1.8b4f237050232p1 ++0x1.0f3804c1ac573p26 ++0x1.63b6402daf587p25 ++-0x1.ef19b46fc82d1p-5 ++0x1.5b24532eef37bp8 ++0x1.e3cc25433e63dp8 ++-0x1.6adbc65e81bf0p-6 ++0x1.4af2127550ba6p19 ++0x1.0b0534813be5dp10 ++0x1.406e85cef6faep18 ++0x1.3624f311203b4p24 ++0x1.c539d648b5762p4 ++0x1.d33de1b06857cp22 ++0x1.088795083936fp26 ++-0x1.46d32700ac723p13 ++0x1.90cd33bd76f26p3 ++-0x1.bc8b039abda5dp-5 ++0x1.118c66b20ff59p24 ++0x1.86aa4299069edp17 ++-0x1.8c0d566b825bdp6 ++0x1.a2f000766a5dcp-8 ++0x1.f125b5925ecdcp9 ++-0x1.42e27168a01e5p-6 ++0x1.8d07c5da62627p-5 ++-0x1.300382649922bp25 ++-0x1.c6af64d64da9bp21 ++-0x1.dbf9b7e4544d8p-5 ++-0x1.ae66a3b7f8d1ep8 ++-0x1.68cae1e2a98b1p25 ++-0x1.d9d0e40f5b316p18 ++0x1.9240a42e12154p4 ++-0x1.85efc5a65c092p5 ++0x1.c25b32c0f3a22p21 ++-0x1.8ce4e51fc72bcp20 ++0x1.2d88a67e7f4d5p6 ++-0x1.f9fab7bee125dp2 ++0x1.d5ab6667f00aap-5 ++-0x1.8de195b535d34p0 ++0x1.856a236431247p5 ++-0x1.9355b20d3597fp3 ++0x1.c86242004b43bp16 ++-0x1.f075e5ac52efcp7 ++0x1.128a500680aadp22 ++-0x1.e05591544f544p21 ++0x1.93efc221f8e59p2 ++0x1.ab2f462bf74fcp5 ++0x1.c49bd6a3c1818p4 ++0x1.7b8ad50c7bfecp13 ++0x1.fc4e96888c2d1p-6 ++-0x1.58d6c2c5e054cp-5 ++-0x1.2f6ec7a1377e0p14 ++0x1.c58a842a616dbp3 ++0x1.834dd78309187p18 ++-0x1.c3a496c1450d1p-5 ++0x1.f4d2b45c847dfp3 ++0x1.8c356160ce725p1 ++0x1.3142d7811c731p2 ++0x1.93a9516a96a0bp3 ++0x1.a1bee68429794p7 ++0x1.b95dc334a2bc6p8 ++-0x1.19cef672a9a47p-6 ++-0x1.d27957ab51079p-5 ++-0x1.f326d3c218f96p-7 ++-0x1.3663f5c2f7a7ep21 ++0x1.92d2c298efc0ep3 ++0x1.0c0ac140813e9p14 ++0x1.f042d0f375d37p-5 ++-0x1.33d93108cefb4p17 ++0x1.49bb63dc63385p26 ++-0x1.6c4a43fe47766p15 ++0x1.ef7b348d27a11p-5 ++0x1.75c9e12812395p26 ++0x1.646c466065168p13 ++0x1.c6a595a4cf1eep-5 ++0x1.633eb2bb2135cp13 ++0x1.1d6fd48d68d10p16 ++0x1.909086ce4aa7bp19 ++0x1.33e475eaa77c1p6 ++0x1.dd76962579da8p4 ++0x1.2f6ff6e564b1cp2 ++-0x1.250d605076831p-5 ++-0x1.eb5e5279788d8p-5 ++-0x1.8d7a8777145a7p1 ++0x1.987364729a434p19 ++0x1.dabe4125b97b3p-5 ++0x1.b17e331eb6789p6 ++0x1.6db837fb7d483p-5 ++0x1.974bf2de99250p-5 ++0x1.eb7783df9a7d7p24 ++0x1.d4a382fdca607p-5 ++0x1.c819b06815072p-5 ++-0x1.884961789ce26p0 ++-0x1.49abd42b2da4ap11 ++-0x1.c22025eda45c0p-5 ++0x1.1507f3d165044p4 ++0x1.98d962253bc23p0 ++0x1.91d604536b2ddp1 ++-0x1.97e455ad89b74p14 ++-0x1.e048a7162e609p24 ++-0x1.b0f2a035fc460p-5 ++-0x1.dfae87af15a41p-5 ++0x1.5957d3127c4ecp-5 ++-0x1.e19520fdfdde8p18 ++0x1.14bbb5a3d4a9ep-5 ++0x1.40e1e0445bbe9p20 ++0x1.d11a60dfe5ccbp13 ++-0x1.2864a79b70a9fp12 ++-0x1.d586268ab9766p-5 ++0x1.e86f11c2cfc20p-6 ++0x1.44cca2c6d41b2p-6 ++-0x1.96a014873a351p-5 ++-0x1.8d81a234eaeb3p21 ++0x1.3a1533e669917p5 ++0x1.8ba860cf520bep1 ++0x1.4265b33954e48p10 ++-0x1.a249f7fe5c4e5p17 ++-0x1.2e1957e00bdd5p4 ++-0x1.8240d5065f3b6p17 ++0x1.8d74a29263a5ap0 ++0x1.951506f271652p1 ++0x1.e92041ee927e3p-6 ++0x1.ed2dc6dcf4002p-6 ++0x1.2c92337f90e49p2 ++-0x1.683c21e808cdep-5 ++-0x1.9a0b940509413p-6 ++0x1.98f7007ee0945p1 ++0x1.a2320700475bbp-7 ++0x1.bd43201cd4e31p-5 ++-0x1.cc04710864fd6p-5 ++0x1.a21c8714da14ep-5 ++0x1.773693ef8fa14p-5 ++0x1.79803001fe5dap-5 ++-0x1.2c32c75512fe9p2 ++0x1.844f25e75eb2fp0 ++-0x1.95d877a17a280p2 ++0x1.948a43d9d7741p1 ++0x1.971c84f87b377p0 ++0x1.9127e7382bcc8p-5 ++0x1.93fe639e0db3dp0 ++0x1.2f4d04d0c8b60p3 ++-0x1.902934f6cec25p0 ++-0x1.97e5e2e8c9690p0 ++-0x1.2e7f34a41089ap2 ++-0x1.dbf4d63956dabp-5 ++0x1.7de270a1cef9dp-5 ++-0x1.a8cfd796dd749p-5 ++-0x1.867323de7c548p0 ++-0x1.583b54858a854p-5 ++0x1.5a32b5f87c731p-6 ++-0x1.a893c3b3f116dp-5 ++0x1.8dba0559b03f2p-5 ++-0x1.8fddc49a817aap0 ++0x1.8dfc56712ea84p1 ++-0x1.5ec35128245fbp3 ++0x1.2ed721b3e7cf3p2 ++0x1.f6f6b38e4a725p2 ++0x1.8d7636d60e4a2p0 ++0x1.f53e24706a8adp2 ++-0x1.2b8e75888ccddp2 ++0x1.798c20cba7df8p4 ++-0x1.c28770144413dp3 ++0x1.99b0411242349p1 ++-0x1.899d668f66224p0 ++-0x1.9584c477164dfp1 ++0x1.894db4cfedf00p0 ++0x1.478fe109931cbp4 ++0x1.60ecc69ceb31cp3 ++-0x1.2daad0f631f1ap3 ++-0x1.90c0775e5bbd9p3 ++-0x1.9563261499472p1 ++-0x1.8cce8733835a8p1 ++-0x1.8e5bd67aad0bdp1 ++0x1.2f88b005dd5c1p3 ++0x1.2f79b51aa1b2ep3 ++0x1.c5ba9020db5c7p3 ++-0x1.91834694280eap3 ++-0x1.f59d31d57b57cp3 ++0x1.9f12216e6b6e5p0 ++0x1.9094e7026c1ebp3 ++0x1.155cc046ffb5bp4 ++-0x1.848890adc4715p0 ++0x1.90ad119b10f12p2 ++-0x1.8d9a028100e2cp0 ++0x1.c60477c5553dfp3 ++0x1.91b295b42732dp3 ++-0x1.93e8041f128acp3 ++0x1.88cc56d1e4905p0 ++-0x1.925832396eb4ap3 ++0x1.8a73075e37e87p1 ++-0x1.138d60f880517p4 ++-0x1.97cf677cc2b69p1 ++0x1.915aa29d49dbcp1 ++0x1.873b8780d5106p0 ++0x1.94c856a2d7bb6p1 ++-0x1.90628588db51ap3 ++-0x1.8f5770d7d1d70p1 ++0x1.c5579491935bbp3 ++-0x1.78da03f27aa07p4 ++0x1.9209877319a62p1 ++-0x1.2aea80b631733p2 ++0x1.2f75e48cddd2cp3 ++-0x1.5fb7273fcc453p3 ++-0x1.8488702ff0c32p0 ++-0x1.93dda7bee871ep0 ++-0x1.93b653501d3c1p2 ++0x1.9205222724e5bp1 ++0x1.2df4a1196323ep2 ++0x1.6108a416f100ap3 ++-0x1.8db7954424fc7p0 ++0x1.2bb8a1817846fp3 ++-0x1.8abed04ecb123p0 ++0x1.92d5f27ca693fp0 ++-0x1.2a3e75ea2ae07p2 ++-0x1.90fb35edc8d06p0 ++0x1.9a76161e739c7p0 ++# tan slow path at 240 bits ++# Implemented in sysdeps/ieee754/dbl-64/mptan.c ++# Range reduction is done using mp arithmetic. ++## name: 240bits ++0x1.ee5a221c1ec30p750 ++0x1.d0b7237b90954p983 ++0x1.50aee539c99e6p817 ++-0x1.63457438d44aap53 ++-0x1.294211dbd13e4p213 ++-0x1.d71b609ef9723p651 ++0x1.9c3fc4df7e48ep242 ++0x1.ab8b7376e687ep989 ++-0x1.23f9a2342724ap746 ++0x1.119932858dd5ap966 ++0x1.172f40abffae1p573 ++-0x1.f9bb63afd3e82p824 ++0x1.1d49b6073fd25p1018 ++0x1.3825a112069d0p360 ++0x1.8e64d153eac98p839 ++0x1.e87296bff194bp410 ++0x1.607562a57b7cbp149 ++0x1.79bab59092899p902 ++0x1.de5304e52acddp608 ++-0x1.418357b7072b6p987 ++-0x1.b86e0050bf853p732 ++-0x1.a1efd6e7ed2f7p903 ++-0x1.d8f94109ae4a3p874 ++0x1.4f3247a1eea1ep815 ++0x1.bdea912ba38d1p109 ++-0x1.c8df81ba65338p846 ++0x1.fdeb13595a17bp798 ++0x1.767af536202fcp99 ++-0x1.2a30021aae9e6p527 ++-0x1.28dee7f401161p970 ++0x1.4619840d88992p101 ++0x1.6bfc225d005a2p837 ++0x1.1e1af0e150b94p594 ++0x1.bb40b53e0e710p107 ++-0x1.509896c78f606p883 ++0x1.d89291baa92acp34 ++-0x1.3d17f161b743ep327 ++-0x1.39c6a16a6c7c6p264 ++0x1.c76d60078cecfp545 ++-0x1.154493e3be839p980 ++-0x1.b3df5360e6cbfp245 ++-0x1.f0c52280d0aadp653 ++-0x1.d93ce79dfe195p45 ++0x1.88dd7769601fep966 ++0x1.a903f553288eap298 ++0x1.4ecba03f7132fp152 ++-0x1.ee34e7eac85fap992 ++-0x1.010e46c3cd107p876 ++-0x1.b56fd64fe1fbdp323 ++0x1.2c50c6911febep742 ++0x1.740dc6b962c9bp422 ++-0x1.617e2227cbff6p224 ++-0x1.1ad286314c58bp940 ++0x1.ac1745b651b5fp649 ++0x1.fddce309449cfp982 ++0x1.73aa443462592p182 ++0x1.7d2e10f57bf82p306 ++-0x1.93eef4d8c4abep433 ++0x1.3d9bd192c5d05p408 ++0x1.1ba6707e8de9ap833 ++-0x1.c2f6f7c9e74b3p766 ++0x1.404e24bccecfcp457 ++-0x1.7a40f3ff05d01p530 ++-0x1.10de718a052b3p202 ++0x1.406e1464adc55p557 ++0x1.9e19028382754p550 ++0x1.635c94cbc7020p982 ++0x1.984492142a1c0p81 ++0x1.4b64a03a03816p428 ++0x1.247c4191da022p961 ++0x1.c141e714fe35cp908 ++0x1.1b3621a4c2bafp257 ++0x1.53d5e3c854773p294 ++0x1.0747d33080a32p824 ++0x1.1632770278ce8p845 ++-0x1.c782e7d005b27p622 ++0x1.593837dacc255p851 ++-0x1.ec2ff0a8e0bcdp569 ++-0x1.b594936bb511ep82 ++0x1.9b45519d36598p976 ++-0x1.9b8684eaa71c6p944 ++-0x1.a3d743632fed4p395 ++-0x1.b73bd248a7a07p401 ++-0x1.dbc2269986a9dp213 ++0x1.1db1d61aaef59p102 ++0x1.2e8bb0f1ad8e5p797 ++0x1.e883f6710822bp235 ++-0x1.869ff130d5a8ap348 ++0x1.2fa330ffa7b9bp49 ++-0x1.0504a5188eddbp500 ++-0x1.0d0a04316e717p622 ++0x1.e020a6a980593p957 ++0x1.869895a12103dp1011 ++-0x1.a069a71af1389p432 ++-0x1.814d711d1c525p904 ++0x1.3648160c04db0p640 ++-0x1.fafcf58cb570cp724 ++-0x1.00bdd7f58135ep394 ++0x1.e4d721588529ep259 ++-0x1.2b364691f9147p192 ++-0x1.7932c5bb927a9p463 ++0x1.d185a23e7a264p121 ++-0x1.d82395a639e87p578 ++0x1.d19bd28cdb538p1020 ++-0x1.91e123b92a975p528 ++-0x1.f5b921ff6813fp866 ++-0x1.f233e109dede1p346 ++0x1.22b5274acfea5p28 ++-0x1.b12c358527025p560 ++0x1.87f9c3636f7a7p770 ++-0x1.b7cfb4bd9ef9fp559 ++0x1.ab30f4cdb2826p927 ++0x1.3121e66534c09p996 ++0x1.32ff26e56b243p66 ++-0x1.6a3155c7bbc49p381 ++0x1.0629119d19fe7p306 ++0x1.666f07ccc3516p444 ++-0x1.71b82433bfd05p656 ++0x1.787bb435c6119p237 ++-0x1.bb81028d4e92ep822 ++-0x1.f956b52f53507p930 ++-0x1.9f75e34d740f3p394 ++0x1.babfd6b429321p307 ++-0x1.0546727a98f2fp892 ++-0x1.24e7a5b4ab558p36 ++0x1.91b656ffc9015p48 ++0x1.f214d6691dbc8p813 ++-0x1.7508047526de4p708 ++-0x1.6e0884d03f494p595 ++-0x1.abf2f140b46a1p958 ++0x1.cd37e24ae01d2p996 ++0x1.874b5349798ddp791 ++0x1.5db704095417cp479 ++-0x1.385f265e0be6dp529 ++-0x1.77d7f72971477p254 ++0x1.c1d572032a2bcp231 ++0x1.c5f3b1b1e6cb1p985 ++0x1.112e0044fe943p152 ++-0x1.c39e821cde6d0p860 ++0x1.70f7800567a4cp831 ++-0x1.bf2987be14b54p43 ++0x1.005dc191f8155p428 ++0x1.15ae534e6771bp286 ++0x1.c90422cac4067p433 ++0x1.ce9e737328102p189 ++0x1.809d12529d2fcp385 ++0x1.1063e5c391f7dp222 ++0x1.d2ec86f035aecp981 ++-0x1.196f9101def40p684 ++0x1.c63095b4787cbp964 ++-0x1.974c637b88001p971 ++-0x1.1f4ff59ad6375p982 ++-0x1.fd2845fc76df9p832 ++0x1.1e2872f75696dp150 ++0x1.550941834ba74p642 ++0x1.0d163506e72bbp960 ++-0x1.c4ac9745073bap738 ++0x1.8fd3f61e48e52p625 ++-0x1.5f9425e8039f3p636 ++0x1.3e4f37281e892p558 ++0x1.3373f1db8806cp990 ++-0x1.038965f403b17p774 ++-0x1.bd5b377d53669p945 ++-0x1.07b3f085c6733p689 ++0x1.3544b2eed1abfp262 ++0x1.1532c11ac2507p832 ++-0x1.c00c9609102c4p786 ++0x1.ad9637e0c897bp581 ++-0x1.fe4bc0f718a8cp569 ++0x1.0692371444ef5p700 ++0x1.cb4e64433e84cp965 ++-0x1.69d26008baa73p236 ++0x1.62f9711ed5d1ep464 ++0x1.e930d2860dadap435 ++-0x1.909f574e6549cp658 ++0x1.00e4f31691d23p399 ++-0x1.0d5823a83628bp540 ++-0x1.c7b743f92fb3fp569 ++0x1.7dee11c9dafa3p670 ++0x1.529be63463210p939 ++0x1.62bd520c84081p874 ++0x1.c993466a75c4cp61 ++-0x1.33b0260c2549bp495 ++0x1.09e87208ab6ffp625 ++0x1.0ae9e4d036946p291 ++0x1.07d5649391891p165 ++-0x1.bee4e05b04714p586 ++0x1.2b0994ee5f218p167 ++0x1.ebfc830d19d34p992 ++0x1.382612ecb922ap979 ++-0x1.21c82431ac446p1022 ++0x1.6196b60f1c50fp190 ++-0x1.c25ea71d737a2p248 ++0x1.d024774408b26p335 ++-0x1.f5ce472da3a21p644 ++-0x1.81a011e0b6271p851 ++0x1.9cd0227a58f39p939 ++-0x1.8698a10662bffp544 ++0x1.a07c20fa799d8p622 ++-0x1.d126c657c582bp880 ++# tan slowest path at 768 bits ++# Implemented in sysdeps/ieee754/dbl-64/mptan.c ++## name: 768bits ++0x1.dffffffffff1fp-22 ++0x1.810f60836538dp143 ++-0x1.e877a52501e08p134 +diff -urN glibc-2.17-c758a686/debug/test-strcpy_chk.c glibc-2.17-c758a686/debug/test-strcpy_chk.c +--- glibc-2.17-c758a686/debug/test-strcpy_chk.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/debug/test-strcpy_chk.c 2015-06-20 21:22:16.304457892 -0400 +@@ -54,6 +54,10 @@ + #include + #include + ++static int test_main (void); ++#define TEST_FUNCTION test_main () ++#include "../test-skeleton.c" ++ + volatile int chk_fail_ok; + jmp_buf chk_fail_buf; + +@@ -110,24 +114,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused));; +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, dst, src, dlen); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -151,14 +137,8 @@ + s1[i] = 32 + 23 * i % (max_char - 32); + s1[len] = 0; + +- if (HP_TIMING_AVAIL && dlen > len) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, len, dlen); +- +- if (HP_TIMING_AVAIL && dlen > len) +- putchar ('\n'); + } + + static void +@@ -290,28 +270,12 @@ + } + } + +-int ++static int + test_main (void) + { + size_t i; + +- struct sigaction sa; +- sa.sa_handler = handler; +- sa.sa_flags = 0; +- sigemptyset (&sa.sa_mask); +- +- sigaction (SIGABRT, &sa, NULL); +- +- /* Avoid all the buffer overflow messages on stderr. */ +- int fd = open (_PATH_DEVNULL, O_WRONLY); +- if (fd == -1) +- close (STDERR_FILENO); +- else +- { +- dup2 (fd, STDERR_FILENO); +- close (fd); +- } +- setenv ("LIBC_FATAL_STDERR_", "1", 1); ++ set_fortify_handler (handler); + + test_init (); + +@@ -389,5 +353,3 @@ + do_random_tests (); + return ret; + } +- +-#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/debug/tst-chk1.c glibc-2.17-c758a686/debug/tst-chk1.c +--- glibc-2.17-c758a686/debug/tst-chk1.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/debug/tst-chk1.c 2015-06-20 21:22:16.304457892 -0400 +@@ -20,7 +20,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -119,23 +118,7 @@ + static int + do_test (void) + { +- struct sigaction sa; +- sa.sa_handler = handler; +- sa.sa_flags = 0; +- sigemptyset (&sa.sa_mask); +- +- sigaction (SIGABRT, &sa, NULL); +- +- /* Avoid all the buffer overflow messages on stderr. */ +- int fd = open (_PATH_DEVNULL, O_WRONLY); +- if (fd == -1) +- close (STDERR_FILENO); +- else +- { +- dup2 (fd, STDERR_FILENO); +- close (fd); +- } +- setenv ("LIBC_FATAL_STDERR_", "1", 1); ++ set_fortify_handler (handler); + + struct A { char buf1[9]; char buf2[1]; } a; + struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa; +@@ -1366,7 +1349,7 @@ + ret = 1; + } + +- fd = posix_openpt (O_RDWR); ++ int fd = posix_openpt (O_RDWR); + if (fd != -1) + { + char enough[1000]; +diff -urN glibc-2.17-c758a686/debug/tst-longjmp_chk.c glibc-2.17-c758a686/debug/tst-longjmp_chk.c +--- glibc-2.17-c758a686/debug/tst-longjmp_chk.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/debug/tst-longjmp_chk.c 2015-06-20 21:22:16.305457862 -0400 +@@ -1,3 +1,5 @@ ++/* Basic test to make sure doing a longjmp to a jmpbuf with an invalid sp ++ is caught by the fortification code. */ + #include + #include + #include +@@ -8,6 +10,12 @@ + #include + #include + ++ ++static int do_test(void); ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++ + static jmp_buf b; + + +@@ -43,26 +51,10 @@ + } + + +-int +-main (void) ++static int ++do_test (void) + { +- struct sigaction sa; +- sa.sa_handler = handler; +- sa.sa_flags = 0; +- sigemptyset (&sa.sa_mask); +- +- sigaction (SIGABRT, &sa, NULL); +- +- /* Avoid all the buffer overflow messages on stderr. */ +- int fd = open (_PATH_DEVNULL, O_WRONLY); +- if (fd == -1) +- close (STDERR_FILENO); +- else +- { +- dup2 (fd, STDERR_FILENO); +- close (fd); +- } +- setenv ("LIBC_FATAL_STDERR_", "1", 1); ++ set_fortify_handler (handler); + + + expected_to_fail = false; +diff -urN glibc-2.17-c758a686/elf/dl-support.c glibc-2.17-c758a686/elf/dl-support.c +--- glibc-2.17-c758a686/elf/dl-support.c 2015-06-20 23:38:08.194095607 -0400 ++++ glibc-2.17-c758a686/elf/dl-support.c 2015-06-20 22:00:26.531904072 -0400 +@@ -90,12 +90,6 @@ + /* Get architecture specific initializer. */ + #include + +-/* We expect less than a second for relocation. */ +-#ifdef HP_SMALL_TIMING_AVAIL +-# undef HP_TIMING_AVAIL +-# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL +-#endif +- + /* Initial value of the CPU clock. */ + #ifndef HP_TIMING_NONAVAIL + hp_timing_t _dl_cpuclock_offset; +@@ -265,7 +259,7 @@ + internal_function + _dl_non_dynamic_init (void) + { +- if (HP_TIMING_AVAIL) ++ if (HP_SMALL_TIMING_AVAIL) + HP_TIMING_NOW (_dl_cpuclock_offset); + + if (!_dl_pagesize) +diff -urN glibc-2.17-c758a686/elf/rtld.c glibc-2.17-c758a686/elf/rtld.c +--- glibc-2.17-c758a686/elf/rtld.c 2015-06-20 23:38:08.170096325 -0400 ++++ glibc-2.17-c758a686/elf/rtld.c 2015-06-20 22:06:24.194043066 -0400 +@@ -193,12 +193,6 @@ + static struct libname_list _dl_rtld_libname; + static struct libname_list _dl_rtld_libname2; + +-/* We expect less than a second for relocation. */ +-#ifdef HP_SMALL_TIMING_AVAIL +-# undef HP_TIMING_AVAIL +-# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL +-#endif +- + /* Variable for statistics. */ + #ifndef HP_TIMING_NONAVAIL + static hp_timing_t relocate_time; +@@ -268,7 +262,7 @@ + { + ElfW(Addr) start_addr; + +- if (HP_TIMING_AVAIL) ++ if (HP_SMALL_TIMING_AVAIL) + { + /* If it hasn't happen yet record the startup time. */ + if (! HP_TIMING_INLINE) +@@ -277,9 +271,6 @@ + else + start_time = info->start_time; + #endif +- +- /* Initialize the timing functions. */ +- HP_TIMING_DIFF_INIT (); + } + + /* Transfer data about ourselves to the permanent link_map structure. */ +@@ -315,9 +306,7 @@ + + #endif + +-#if HP_TIMING_AVAIL + HP_TIMING_NOW (GL(dl_cpuclock_offset)); +-#endif + + /* Initialize the stack end variable. */ + __libc_stack_end = __builtin_frame_address (0); +@@ -330,7 +319,7 @@ + + #ifndef HP_TIMING_NONAVAIL + hp_timing_t rtld_total_time; +- if (HP_TIMING_AVAIL) ++ if (HP_SMALL_TIMING_AVAIL) + { + hp_timing_t end_time; + +@@ -372,7 +361,7 @@ + #define RESOLVE_MAP(sym, version, flags) (&bootstrap_map) + #include "dynamic-link.h" + +- if (HP_TIMING_INLINE && HP_TIMING_AVAIL) ++ if (HP_TIMING_INLINE && HP_SMALL_TIMING_AVAIL) + #ifdef DONT_USE_BOOTSTRAP_MAP + HP_TIMING_NOW (start_time); + #else +@@ -2720,7 +2709,7 @@ + char *wp; + + /* Total time rtld used. */ +- if (HP_TIMING_AVAIL) ++ if (HP_SMALL_TIMING_AVAIL) + { + HP_TIMING_PRINT (buf, sizeof (buf), *rtld_total_timep); + _dl_debug_printf ("\nruntime linker statistics:\n" +@@ -2788,7 +2777,7 @@ + + #ifndef HP_TIMING_NONAVAIL + /* Time spend while loading the object and the dependencies. */ +- if (HP_TIMING_AVAIL) ++ if (HP_SMALL_TIMING_AVAIL) + { + char pbuf[30]; + HP_TIMING_PRINT (buf, sizeof (buf), load_time); +diff -urN glibc-2.17-c758a686/Makefile.in glibc-2.17-c758a686/Makefile.in +--- glibc-2.17-c758a686/Makefile.in 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/Makefile.in 2015-06-20 21:22:16.305457862 -0400 +@@ -3,7 +3,7 @@ + # Uncomment the line below if you want to do parallel build. + # PARALLELMFLAGS = -j 4 + +-.PHONY: all install ++.PHONY: all install bench + + all .DEFAULT: + $(MAKE) -r PARALLELMFLAGS="$(PARALLELMFLAGS)" -C $(srcdir) objdir=`pwd` $@ +@@ -11,3 +11,6 @@ + install: + LANGUAGE=C LC_ALL=C; export LANGUAGE LC_ALL; \ + $(MAKE) -r PARALLELMFLAGS="$(PARALLELMFLAGS)" -C $(srcdir) objdir=`pwd` $@ ++ ++bench bench-clean: ++ $(MAKE) -C $(srcdir)/benchtests $(PARALLELMFLAGS) objdir=`pwd` $@ +diff -urN glibc-2.17-c758a686/ports/sysdeps/alpha/hp-timing.h glibc-2.17-c758a686/ports/sysdeps/alpha/hp-timing.h +--- glibc-2.17-c758a686/ports/sysdeps/alpha/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/alpha/hp-timing.h 2015-06-20 21:44:22.241186366 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. Alpha version. +- Copyright (C) 2001 Free Software Foundation, Inc. ++ Copyright (C) 2001-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson , 2001. + +@@ -20,52 +20,6 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +- +-/* The macros defined here use the timestamp counter in IA-64. They +- provide a very accurate way to measure the time with very little +- overhead. The time values themself have no real meaning, only +- differences are interesting. +- +- The list of macros we need includes the following: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +-*/ +- + /* We always have the timestamp register, but it's got only a 4 second + range. Use it for ld.so profiling only. */ + #define HP_TIMING_AVAIL (0) +@@ -77,9 +31,6 @@ + /* We use 32 bit values for the times. */ + typedef unsigned int hp_timing_t; + +-/* Set timestamp value to zero. */ +-#define HP_TIMING_ZERO(VAR) (VAR) = (0) +- + /* The "rpcc" instruction returns a 32-bit counting half and a 32-bit + "virtual cycle counter displacement". Subtracting the two gives us + a virtual cycle count. */ +@@ -90,28 +41,6 @@ + (VAR) = (int) (x_) - (int) (x_ >> 32); \ + } while (0) + +-/* ??? Two rpcc instructions can be scheduled simultaneously. */ +-#define HP_TIMING_DIFF_INIT() do { } while (0) +- +-/* It's simple arithmetic for us. */ +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-/* ??? Don't bother, since we're only used for ld.so. */ +-#define HP_TIMING_ACCUM(Sum, Diff) not implemented +- +-/* No threads, no extra work. */ +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-/* Print the time value. */ +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa_word (Val, __buf + sizeof (__buf), 10, 0); \ +- int __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.c glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.c +--- glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,23 +0,0 @@ +-/* Support for high precision, low overhead timing functions. IA-64 version. +- Copyright (C) 2001, 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 2001. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-/* We have to define the variable for the overhead. */ +-hp_timing_t _dl_hp_timing_overhead; +diff -urN glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.h glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.h +--- glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/hp-timing.h 2015-06-20 21:44:03.984740754 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. IA-64 version. +- Copyright (C) 2001-2012 Free Software Foundation, Inc. ++ Copyright (C) 2001-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2001. + +@@ -20,56 +20,9 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +-#include +- +-/* The macros defined here use the timestamp counter in IA-64. They +- provide a very accurate way to measure the time with very little +- overhead. The time values themself have no real meaning, only +- differences are interesting. +- +- The list of macros we need includes the following: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +- +-*/ +- + /* We always assume having the timestamp register. */ + #define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) + + /* We indeed have inlined functions. */ + #define HP_TIMING_INLINE (1) +@@ -77,10 +30,6 @@ + /* We use 64bit values for the times. */ + typedef unsigned long int hp_timing_t; + +-/* Set timestamp value to zero. */ +-#define HP_TIMING_ZERO(Var) (Var) = (0) +- +- + /* The Itanium/Merced has a bug where the ar.itc register value read + is not correct in some situations. The solution is to read again. + For now we always do this until we know how to recognize a fixed +@@ -95,53 +44,6 @@ + while (REPEAT_READ (__itc)); \ + Var = __itc; }) + +-/* Use two 'ar.itc' instructions in a row to find out how long it takes. */ +-#define HP_TIMING_DIFF_INIT() \ +- do { \ +- int __cnt = 5; \ +- GLRO(dl_hp_timing_overhead) = ~0ul; \ +- do \ +- { \ +- hp_timing_t __t1, __t2; \ +- HP_TIMING_NOW (__t1); \ +- HP_TIMING_NOW (__t2); \ +- if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ +- GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ +- } \ +- while (--__cnt > 0); \ +- } while (0) +- +-/* It's simple arithmetic for us. */ +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-/* We have to jump through hoops to get this correctly implemented. */ +-#define HP_TIMING_ACCUM(Sum, Diff) \ +- do { \ +- hp_timing_t __oldval; \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- hp_timing_t __newval; \ +- do \ +- { \ +- __oldval = (Sum); \ +- __newval = __oldval + __diff; \ +- } \ +- while (! __sync_bool_compare_and_swap (&Sum, __oldvar, __newval)); \ +- } while (0) +- +-/* No threads, no extra work. */ +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-/* Print the time value. */ +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa_word (Val, __buf + sizeof (__buf), 10, 0); \ +- int __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " clock cycles", MIN (__len, \ +- (int) sizeof (" clock cycles"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/ports/sysdeps/ia64/Makefile glibc-2.17-c758a686/ports/sysdeps/ia64/Makefile +--- glibc-2.17-c758a686/ports/sysdeps/ia64/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/Makefile 2015-06-20 22:31:17.725704221 -0400 +@@ -7,8 +7,6 @@ + + ifeq ($(subdir), csu) + CPPFLAGS-start.S = -D__ASSEMBLY__ +-sysdep_routines += hp-timing +-elide-routines.os += hp-timing + + ifeq (yes,$(build-shared)) + # Compatibility +diff -urN glibc-2.17-c758a686/Rules glibc-2.17-c758a686/Rules +--- glibc-2.17-c758a686/Rules 2015-06-20 23:38:08.446088067 -0400 ++++ glibc-2.17-c758a686/Rules 2015-06-20 21:22:16.305457862 -0400 +@@ -83,7 +83,7 @@ + + # This makes all the auxiliary and test programs. + +-.PHONY: others tests ++.PHONY: others tests bench + ifeq ($(multi-arch),no) + tests := $(filter-out $(tests-ifunc), $(tests)) + xtests := $(filter-out $(xtests-ifunc), $(xtests)) +@@ -192,6 +192,7 @@ + $(make-test-out) > $@ + + endif # tests ++ + + .PHONY: distclean realclean subdir_distclean subdir_realclean \ + subdir_clean subdir_mostlyclean subdir_testclean +diff -urN glibc-2.17-c758a686/scripts/pylint glibc-2.17-c758a686/scripts/pylint +--- glibc-2.17-c758a686/scripts/pylint 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/pylint 2015-06-20 21:22:16.305457862 -0400 +@@ -0,0 +1,5 @@ ++#!/bin/sh ++# Simple wrapper around the pylint program that uses the pylintrc file to ++# validate the source code in files passed on command line. ++ ++exec pylint --rcfile "${0%/*}/pylintrc" "$@" +diff -urN glibc-2.17-c758a686/scripts/pylintrc glibc-2.17-c758a686/scripts/pylintrc +--- glibc-2.17-c758a686/scripts/pylintrc 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/scripts/pylintrc 2015-06-20 21:22:16.305457862 -0400 +@@ -0,0 +1,274 @@ ++[MASTER] ++ ++# Specify a configuration file. ++#rcfile= ++ ++# Python code to execute, usually for sys.path manipulation such as ++# pygtk.require(). ++#init-hook= ++ ++# Profiled execution. ++profile=no ++ ++# Add files or directories to the blacklist. They should be base names, not ++# paths. ++ignore=CVS ++ ++# Pickle collected data for later comparisons. ++persistent=yes ++ ++# List of plugins (as comma separated values of python modules names) to load, ++# usually to register additional checkers. ++load-plugins= ++ ++ ++[MESSAGES CONTROL] ++ ++# Enable the message, report, category or checker with the given id(s). You can ++# either give multiple identifier separated by comma (,) or put this option ++# multiple time. See also the "--disable" option for examples. ++#enable= ++ ++# Disable the message, report, category or checker with the given id(s). You ++# can either give multiple identifiers separated by comma (,) or put this ++# option multiple times (only on the command line, not in the configuration ++# file where it should appear only once).You can also use "--disable=all" to ++# disable everything first and then reenable specific checks. For example, if ++# you want to run only the similarities checker, you can use "--disable=all ++# --enable=similarities". If you want to run only the classes checker, but have ++# no Warning level messages displayed, use"--disable=all --enable=classes ++# --disable=W" ++#disable= ++ ++ ++[REPORTS] ++ ++# Set the output format. Available formats are text, parseable, colorized, msvs ++# (visual studio) and html. You can also give a reporter class, eg ++# mypackage.mymodule.MyReporterClass. ++output-format=text ++ ++# Put messages in a separate file for each module / package specified on the ++# command line instead of printing them on stdout. Reports (if any) will be ++# written in a file name "pylint_global.[txt|html]". ++files-output=no ++ ++# Tells whether to display a full report or only the messages ++reports=yes ++ ++# Python expression which should return a note less than 10 (10 is the highest ++# note). You have access to the variables errors warning, statement which ++# respectively contain the number of errors / warnings messages and the total ++# number of statements analyzed. This is used by the global evaluation report ++# (RP0004). ++evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) ++ ++# Add a comment according to your evaluation note. This is used by the global ++# evaluation report (RP0004). ++comment=no ++ ++# Template used to display messages. This is a python new-style format string ++# used to format the massage information. See doc for all details ++#msg-template= ++ ++ ++[MISCELLANEOUS] ++ ++# List of note tags to take in consideration, separated by a comma. ++notes=FIXME,XXX,TODO ++ ++ ++[SIMILARITIES] ++ ++# Minimum lines number of a similarity. ++min-similarity-lines=4 ++ ++# Ignore comments when computing similarities. ++ignore-comments=yes ++ ++# Ignore docstrings when computing similarities. ++ignore-docstrings=yes ++ ++# Ignore imports when computing similarities. ++ignore-imports=no ++ ++ ++[BASIC] ++ ++# Required attributes for module, separated by a comma ++required-attributes= ++ ++# List of builtins function names that should not be used, separated by a comma ++bad-functions=map,filter,apply,input ++ ++# Regular expression which should only match correct module names ++module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ ++ ++# Regular expression which should only match correct module level names ++const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ ++ ++# Regular expression which should only match correct class names ++class-rgx=[A-Z_][a-zA-Z0-9]+$ ++ ++# Regular expression which should only match correct function names ++function-rgx=[a-z_][a-z0-9_]{2,30}$ ++ ++# Regular expression which should only match correct method names ++method-rgx=[a-z_][a-z0-9_]{2,30}$ ++ ++# Regular expression which should only match correct instance attribute names ++attr-rgx=[a-z_][a-z0-9_]{2,30}$ ++ ++# Regular expression which should only match correct argument names ++argument-rgx=[a-z_][a-z0-9_]{2,30}$ ++ ++# Regular expression which should only match correct variable names ++variable-rgx=[a-z_][a-z0-9_]{2,30}$ ++ ++# Regular expression which should only match correct attribute names in class ++# bodies ++class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ ++ ++# Regular expression which should only match correct list comprehension / ++# generator expression variable names ++inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ ++ ++# Good variable names which should always be accepted, separated by a comma ++# f is a useful name for a file descriptor ++good-names=f,i,j,k,ex,Run,_ ++ ++# Bad variable names which should always be refused, separated by a comma ++bad-names=foo,bar,baz,toto,tutu,tata ++ ++# Regular expression which should only match function or class names that do ++# not require a docstring. ++no-docstring-rgx=__.*__ ++ ++# Minimum line length for functions/classes that require docstrings, shorter ++# ones are exempt. ++docstring-min-length=-1 ++ ++ ++[VARIABLES] ++ ++# Tells whether we should check for unused import in __init__ files. ++init-import=no ++ ++# A regular expression matching the beginning of the name of dummy variables ++# (i.e. not used). ++dummy-variables-rgx=_$|dummy ++ ++# List of additional names supposed to be defined in builtins. Remember that ++# you should avoid to define new builtins when possible. ++additional-builtins= ++ ++ ++[FORMAT] ++ ++# Maximum number of characters on a single line. ++max-line-length=79 ++ ++# Regexp for a line that is allowed to be longer than the limit. ++ignore-long-lines=^\s*(# )??$ ++ ++# Maximum number of lines in a module ++max-module-lines=1000 ++ ++# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 ++# tab). ++indent-string=' ' ++ ++ ++[TYPECHECK] ++ ++# Tells whether missing members accessed in mixin class should be ignored. A ++# mixin class is detected if its name ends with "mixin" (case insensitive). ++ignore-mixin-members=yes ++ ++# List of classes names for which member attributes should not be checked ++# (useful for classes with attributes dynamically set). ++ignored-classes=SQLObject ++ ++# When zope mode is activated, add a predefined set of Zope acquired attributes ++# to generated-members. ++zope=no ++ ++# List of members which are set dynamically and missed by pylint inference ++# system, and so shouldn't trigger E0201 when accessed. Python regular ++# expressions are accepted. ++generated-members=REQUEST,acl_users,aq_parent ++ ++ ++[CLASSES] ++ ++# List of interface methods to ignore, separated by a comma. This is used for ++# instance to not check methods defines in Zope's Interface base class. ++ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by ++ ++# List of method names used to declare (i.e. assign) instance attributes. ++defining-attr-methods=__init__,__new__,setUp ++ ++# List of valid names for the first argument in a class method. ++valid-classmethod-first-arg=cls ++ ++# List of valid names for the first argument in a metaclass class method. ++valid-metaclass-classmethod-first-arg=mcs ++ ++ ++[IMPORTS] ++ ++# Deprecated modules which should not be used, separated by a comma ++deprecated-modules=regsub,TERMIOS,Bastion,rexec ++ ++# Create a graph of every (i.e. internal and external) dependencies in the ++# given file (report RP0402 must not be disabled) ++import-graph= ++ ++# Create a graph of external dependencies in the given file (report RP0402 must ++# not be disabled) ++ext-import-graph= ++ ++# Create a graph of internal dependencies in the given file (report RP0402 must ++# not be disabled) ++int-import-graph= ++ ++ ++[DESIGN] ++ ++# Maximum number of arguments for function / method ++max-args=5 ++ ++# Argument names that match this expression will be ignored. Default to name ++# with leading underscore ++ignored-argument-names=_.* ++ ++# Maximum number of locals for function / method body ++max-locals=15 ++ ++# Maximum number of return / yield for function / method body ++max-returns=6 ++ ++# Maximum number of branch for function / method body ++max-branches=12 ++ ++# Maximum number of statements in function / method body ++max-statements=50 ++ ++# Maximum number of parents for a class (see R0901). ++max-parents=7 ++ ++# Maximum number of attributes for a class (see R0902). ++max-attributes=7 ++ ++# Minimum number of public methods for a class (see R0903). ++min-public-methods=2 ++ ++# Maximum number of public methods for a class (see R0904). ++max-public-methods=20 ++ ++ ++[EXCEPTIONS] ++ ++# Exceptions that will emit a warning when being caught. Defaults to ++# "Exception" ++overgeneral-exceptions=Exception +diff -urN glibc-2.17-c758a686/string/strtok.c glibc-2.17-c758a686/string/strtok.c +--- glibc-2.17-c758a686/string/strtok.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/strtok.c 2015-06-20 21:22:16.305457862 -0400 +@@ -23,6 +23,10 @@ + + #undef strtok + ++#ifndef STRTOK ++# define STRTOK strtok ++#endif ++ + /* Parse S into tokens separated by characters in DELIM. + If S is NULL, the last string strtok() was called with is + used. For example: +@@ -33,9 +37,7 @@ + // s = "abc\0=-def\0" + */ + char * +-strtok (s, delim) +- char *s; +- const char *delim; ++STRTOK (char *s, const char *delim) + { + char *token; + +diff -urN glibc-2.17-c758a686/string/test-memccpy.c glibc-2.17-c758a686/string/test-memccpy.c +--- glibc-2.17-c758a686/string/test-memccpy.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-memccpy.c 2015-06-20 23:36:49.734443244 -0400 +@@ -74,24 +74,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute__ ((unused)); +- hp_timing_t stop __attribute__ ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, dst, src, c, n); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -122,14 +104,8 @@ + for (i = len; i + align1 < page_size && i < len + 64; ++i) + s1[i] = 32 + 32 * i % (max_char - 32); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, n %4zd, char %d, alignment %2zd/%2zd:", len, n, c, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, c, len, n); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-memchr.c glibc-2.17-c758a686/string/test-memchr.c +--- glibc-2.17-c758a686/string/test-memchr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-memchr.c 2015-06-20 23:36:49.736443184 -0400 +@@ -47,24 +47,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, c, n); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -97,14 +79,8 @@ + buf1[align + len] = seek_char; + } + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd:", pos, align); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-memcmp.c glibc-2.17-c758a686/string/test-memcmp.c +--- glibc-2.17-c758a686/string/test-memcmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-memcmp.c 2015-06-20 23:36:49.736443184 -0400 +@@ -100,24 +100,6 @@ + { + if (check_result (impl, s1, s2, len, exp_result) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2, len); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -147,14 +129,8 @@ + s2[len] = align2; + s2[len - 1] -= exp_result; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, len, exp_result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-memcpy.c glibc-2.17-c758a686/string/test-memcpy.c +--- glibc-2.17-c758a686/string/test-memcpy.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-memcpy.c 2015-06-20 23:36:49.736443184 -0400 +@@ -68,24 +68,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, dst, src, len); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -108,14 +90,8 @@ + for (i = 0, j = 1; i < len; i++, j += 23) + s1[i] = j; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, len); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-memmem.c glibc-2.17-c758a686/string/test-memmem.c +--- glibc-2.17-c758a686/string/test-memmem.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-memmem.c 2015-06-20 23:36:49.736443184 -0400 +@@ -82,24 +82,6 @@ + if (check_result (impl, haystack, haystack_len, needle, needle_len, + expected) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, haystack, haystack_len, needle, needle_len); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -110,16 +92,10 @@ + memcpy (tmpbuf, buf1 + idx, len); + memcpy (buf1 + idx, str, len); + +- if (HP_TIMING_AVAIL) +- printf ("String %s, offset %zd:", str, idx); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, buf1, BUF1PAGES * page_size, str, len, buf1 + idx); + + memcpy (buf1 + idx, tmpbuf, len); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +@@ -143,16 +119,10 @@ + buf1[idx + off] = ch; + } + +- if (HP_TIMING_AVAIL) +- printf ("String %.*s, offset %zd:", (int) len, buf1 + idx, idx); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, buf1, BUF1PAGES * page_size, buf1 + idx, len, + buf1 + idx); + +- if (HP_TIMING_AVAIL) +- putchar ('\n'); +- + memcpy (buf1 + idx, tmpbuf, len); + } + } +diff -urN glibc-2.17-c758a686/string/test-memmove.c glibc-2.17-c758a686/string/test-memmove.c +--- glibc-2.17-c758a686/string/test-memmove.c 2015-06-20 23:38:08.186095846 -0400 ++++ glibc-2.17-c758a686/string/test-memmove.c 2015-06-20 23:36:49.737443154 -0400 +@@ -91,28 +91,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +-#ifdef TEST_BCOPY +- CALL (impl, src, dst, len); +-#else +- CALL (impl, dst, src, len); +-#endif +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -135,14 +113,8 @@ + for (i = 0, j = 1; i < len; i++, j += 23) + s1[i] = j; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, (char *) (buf2 + align1), s1, len); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-memset.c glibc-2.17-c758a686/string/test-memset.c +--- glibc-2.17-c758a686/string/test-memset.c 2015-06-20 23:38:08.186095846 -0400 ++++ glibc-2.17-c758a686/string/test-memset.c 2015-06-20 23:36:49.737443154 -0400 +@@ -92,29 +92,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +-#ifdef TEST_BZERO +- CALL (impl, s, n); +-#else +- CALL (impl, s, c, n); +-#endif +- +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -124,14 +101,8 @@ + if (align + len > page_size) + return; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (char *) buf1 + align, c, len); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + #ifndef TEST_BZERO +diff -urN glibc-2.17-c758a686/string/test-rawmemchr.c glibc-2.17-c758a686/string/test-rawmemchr.c +--- glibc-2.17-c758a686/string/test-rawmemchr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-rawmemchr.c 2015-06-20 23:36:49.737443154 -0400 +@@ -49,24 +49,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, c); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -93,14 +75,8 @@ + buf1[align + len] = -seek_char; + result = (char *) (buf1 + align + pos); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd:", pos, align); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (char *) (buf1 + align), seek_char, result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strcasecmp.c glibc-2.17-c758a686/string/test-strcasecmp.c +--- glibc-2.17-c758a686/string/test-strcasecmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strcasecmp.c 2015-06-20 23:36:49.737443154 -0400 +@@ -73,24 +73,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -129,14 +111,8 @@ + else + s2[len - 1] -= exp_result; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, exp_result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strcasestr.c glibc-2.17-c758a686/string/test-strcasestr.c +--- glibc-2.17-c758a686/string/test-strcasestr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strcasestr.c 2015-06-20 23:36:49.737443154 -0400 +@@ -78,24 +78,6 @@ + { + if (check_result (impl, s1, s2, exp_result) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~(hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + +@@ -135,15 +117,8 @@ + } + s1[len1] = '\0'; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", +- len1, len2, align1, align2, fail ? "fail" : "found"); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strcat.c glibc-2.17-c758a686/string/test-strcat.c +--- glibc-2.17-c758a686/string/test-strcat.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strcat.c 2015-06-20 23:36:49.737443154 -0400 +@@ -56,25 +56,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- dst[k] = '\0'; +- HP_TIMING_NOW (start); +- CALL (impl, dst, src); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -101,17 +82,11 @@ + for (i = 0; i < len2; i++) + s2[i] = 32 + 23 * i % (max_char - 32); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len1, len2, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + { + s2[len2] = '\0'; + do_one_test (impl, s2, s1); + } +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strchr.c glibc-2.17-c758a686/string/test-strchr.c +--- glibc-2.17-c758a686/string/test-strchr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strchr.c 2015-06-20 23:36:49.737443154 -0400 +@@ -107,24 +107,6 @@ + { + if (check_result (impl, s, c, exp_res) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, c); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -160,15 +142,8 @@ + else + result = NULLRET (buf + align + len); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment in bytes %2zd:", +- pos, align * sizeof (CHAR)); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, buf + align, seek_char, result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strcmp.c glibc-2.17-c758a686/string/test-strcmp.c +--- glibc-2.17-c758a686/string/test-strcmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strcmp.c 2015-06-20 23:36:49.737443154 -0400 +@@ -161,24 +161,6 @@ + { + if (check_result (impl, s1, s2, exp_result) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -214,14 +196,8 @@ + s2[len + 1] = 24 + exp_result; + s2[len - 1] -= exp_result; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, exp_result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strcpy.c glibc-2.17-c758a686/string/test-strcpy.c +--- glibc-2.17-c758a686/string/test-strcpy.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strcpy.c 2015-06-20 23:36:49.737443154 -0400 +@@ -92,24 +92,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused));; +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, dst, src); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -135,14 +117,8 @@ + s1[i] = 32 + 23 * i % (max_char - 32); + s1[len] = 0; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignments in bytes %2zd/%2zd:", len, align1 * sizeof(CHAR), align2 * sizeof(CHAR)); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, len); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-string.h glibc-2.17-c758a686/string/test-string.h +--- glibc-2.17-c758a686/string/test-string.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-string.h 2015-06-20 21:48:02.050511490 -0400 +@@ -1,5 +1,5 @@ + /* Test and measure string and memory functions. +- Copyright (C) 1999-2012 Free Software Foundation, Inc. ++ Copyright (C) 1999-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Jakub Jelinek , 1999. + +@@ -53,7 +53,6 @@ + #include + #define GL(x) _##x + #define GLRO(x) _##x +-#include + + + # define TEST_FUNCTION test_main () +@@ -67,8 +66,6 @@ + unsigned int seed; + size_t page_size; + +-hp_timing_t _dl_hp_timing_overhead; +- + # ifndef ITERATIONS + size_t iterations = 100000; + # define ITERATIONS_OPTIONS \ +@@ -107,7 +104,7 @@ + #define CALL(impl, ...) \ + (* (proto_t) (impl)->fn) (__VA_ARGS__) + +-#if defined TEST_IFUNC && defined TEST_NAME ++#ifdef TEST_NAME + /* Increase size of FUNC_LIST if assert is triggered at run-time. */ + static struct libc_ifunc_impl func_list[32]; + static int func_count; +@@ -159,16 +156,6 @@ + if (!notall || impl->test) + #endif + +-#define HP_TIMING_BEST(best_time, start, end) \ +- do \ +- { \ +- hp_timing_t tmptime; \ +- HP_TIMING_DIFF (tmptime, start + _dl_hp_timing_overhead, end); \ +- if (best_time > tmptime) \ +- best_time = tmptime; \ +- } \ +- while (0) +- + #ifndef BUF1PAGES + # define BUF1PAGES 1 + #endif +@@ -176,7 +163,7 @@ + static void + test_init (void) + { +-#if defined TEST_IFUNC && defined TEST_NAME ++#ifdef TEST_NAME + func_count = __libc_ifunc_impl_list (TEST_NAME, func_list, + (sizeof func_list + / sizeof func_list[0])); +@@ -199,7 +186,6 @@ + error (EXIT_FAILURE, errno, "mmap failed"); + if (mprotect (buf2 + page_size, page_size, PROT_NONE)) + error (EXIT_FAILURE, errno, "mprotect failed"); +- HP_TIMING_DIFF_INIT (); + if (do_srandom) + { + printf ("Setting seed to 0x%x\n", seed); +diff -urN glibc-2.17-c758a686/string/test-strlen.c glibc-2.17-c758a686/string/test-strlen.c +--- glibc-2.17-c758a686/string/test-strlen.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strlen.c 2015-06-20 23:36:59.693145264 -0400 +@@ -72,24 +72,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -107,14 +89,8 @@ + buf[align + i] = 1 + 11111 * i % MAX_CHAR; + buf[align + len] = 0; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd:", len, align); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (CHAR *) (buf + align), len); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strncasecmp.c glibc-2.17-c758a686/string/test-strncasecmp.c +--- glibc-2.17-c758a686/string/test-strncasecmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strncasecmp.c 2015-06-20 23:36:59.694145234 -0400 +@@ -94,24 +94,6 @@ + { + if (check_result (impl, s1, s2, n, exp_result) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2, n); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -150,14 +132,8 @@ + else + s2[len - 1] -= exp_result; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd/%2zd:", len, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, n, exp_result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strncat.c glibc-2.17-c758a686/string/test-strncat.c +--- glibc-2.17-c758a686/string/test-strncat.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strncat.c 2015-06-20 23:36:59.694145234 -0400 +@@ -67,24 +67,6 @@ + ret = 1; + return; + } +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- dst[k] = '\0'; +- HP_TIMING_NOW (start); +- CALL (impl, dst, src, n); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -114,18 +96,11 @@ + for (i = 0; i < len2; i++) + s2[i] = 32 + 23 * i % (max_char - 32); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%4zd, alignment %2zd/%2zd, N %4zd:", +- len1, len2, align1, align2, n); +- + FOR_EACH_IMPL (impl, 0) + { + s2[len2] = '\0'; + do_one_test (impl, s2, s1, n); + } +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strncmp.c glibc-2.17-c758a686/string/test-strncmp.c +--- glibc-2.17-c758a686/string/test-strncmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strncmp.c 2015-06-20 23:36:59.694145234 -0400 +@@ -75,24 +75,6 @@ + { + if (check_result (impl, s1, s2, n, exp_result) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2, n); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -106,15 +88,10 @@ + { + s1 = (char*)(buf1 + page_size); + s2 = (char*)(buf2 + page_size); +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%4zd:", len, n); + + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, n, 0); + +- if (HP_TIMING_AVAIL) +- putchar ('\n'); +- + return; + } + +@@ -144,14 +121,8 @@ + s1[len] = 64; + } + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, n, exp_result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +@@ -189,14 +160,8 @@ + if (len >= n) + s2[n - 1] -= exp_result; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strncpy.c glibc-2.17-c758a686/string/test-strncpy.c +--- glibc-2.17-c758a686/string/test-strncpy.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strncpy.c 2015-06-20 23:36:59.695145204 -0400 +@@ -90,24 +90,6 @@ + return; + } + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute__ ((unused)); +- hp_timing_t stop __attribute__ ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, dst, src, n); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -133,14 +115,8 @@ + for (i = len + 1; i + align1 < page_size && i < len + 64; ++i) + s1[i] = 32 + 32 * i % (max_char - 32); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s2, s1, len, n); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strnlen.c glibc-2.17-c758a686/string/test-strnlen.c +--- glibc-2.17-c758a686/string/test-strnlen.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strnlen.c 2015-06-20 23:36:59.695145204 -0400 +@@ -47,24 +47,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, maxlen); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -80,14 +62,8 @@ + buf1[align + i] = 1 + 7 * i % max_char; + buf1[align + len] = 0; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd:", len, align); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen)); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strpbrk.c glibc-2.17-c758a686/string/test-strpbrk.c +--- glibc-2.17-c758a686/string/test-strpbrk.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strpbrk.c 2015-06-20 23:36:59.695145204 -0400 +@@ -70,24 +70,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, rej); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -137,14 +119,8 @@ + } + result = STRPBRK_RESULT (s, pos); + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd, rej len %2zd:", pos, align, len); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s, rej, result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strrchr.c glibc-2.17-c758a686/string/test-strrchr.c +--- glibc-2.17-c758a686/string/test-strrchr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strrchr.c 2015-06-20 23:36:59.695145204 -0400 +@@ -73,24 +73,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, c); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -129,14 +111,8 @@ + else + result = NULL; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment in bytes %2zd:", pos, align * sizeof(CHAR)); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (CHAR *) (buf + align), seek_char, result); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strspn.c glibc-2.17-c758a686/string/test-strspn.c +--- glibc-2.17-c758a686/string/test-strspn.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strspn.c 2015-06-20 23:36:59.696145174 -0400 +@@ -74,24 +74,6 @@ + ret = 1; + return; + } +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~ (hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s, acc); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + static void +@@ -129,14 +111,8 @@ + s[i] = '\0'; + } + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd, alignment %2zd, acc len %2zd:", pos, align, len); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s, acc, pos); +- +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/string/test-strstr.c glibc-2.17-c758a686/string/test-strstr.c +--- glibc-2.17-c758a686/string/test-strstr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/string/test-strstr.c 2015-06-20 23:36:59.696145174 -0400 +@@ -77,24 +77,6 @@ + { + if (check_result (impl, s1, s2, exp_result) < 0) + return; +- +- if (HP_TIMING_AVAIL) +- { +- hp_timing_t start __attribute ((unused)); +- hp_timing_t stop __attribute ((unused)); +- hp_timing_t best_time = ~(hp_timing_t) 0; +- size_t i; +- +- for (i = 0; i < 32; ++i) +- { +- HP_TIMING_NOW (start); +- CALL (impl, s1, s2); +- HP_TIMING_NOW (stop); +- HP_TIMING_BEST (best_time, start, stop); +- } +- +- printf ("\t%zd", (size_t) best_time); +- } + } + + +@@ -133,15 +115,9 @@ + } + s1[len1] = '\0'; + +- if (HP_TIMING_AVAIL) +- printf ("Length %4zd/%zd, alignment %2zd/%2zd, %s:", +- len1, len2, align1, align2, fail ? "fail" : "found"); +- + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, fail ? NULL : s1 + len1 - len2); + +- if (HP_TIMING_AVAIL) +- putchar ('\n'); + } + + static void +diff -urN glibc-2.17-c758a686/sysdeps/generic/hp-timing-common.h glibc-2.17-c758a686/sysdeps/generic/hp-timing-common.h +--- glibc-2.17-c758a686/sysdeps/generic/hp-timing-common.h 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/generic/hp-timing-common.h 2015-06-20 21:34:49.496580235 -0400 +@@ -0,0 +1,62 @@ ++/* High precision, low overhead timing functions. Generic version. ++ Copyright (C) 1998-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Ulrich Drepper , 1998. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* In case a platform supports timers in the hardware the following macros ++ and types must be defined: ++ ++ - HP_TIMING_AVAIL: test for availability. ++ ++ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not ++ implemented using function calls but instead uses some inlined code ++ which might simply consist of a few assembler instructions. We have to ++ know this since we might want to use the macros here in places where we ++ cannot make function calls. ++ ++ - hp_timing_t: This is the type for variables used to store the time ++ values. This type must be integral. ++ ++ - HP_TIMING_NOW: place timestamp for current time in variable given as ++ parameter. ++*/ ++ ++/* The target supports hp-timing. Share the common infrastructure. */ ++ ++#include ++#include ++#include <_itoa.h> ++ ++/* Compute the difference between START and END, storing into DIFF. */ ++#define HP_TIMING_DIFF(Diff, Start, End) ((Diff) = (End) - (Start)) ++ ++/* Accumulate ADD into SUM. No attempt is made to be thread-safe. */ ++#define HP_TIMING_ACCUM_NT(Sum, Diff) ((Sum) += (Diff)) ++ ++/* Write a decimal representation of the timing value into the given string. */ ++#define HP_TIMING_PRINT(Dest, Len, Val) \ ++ do { \ ++ char __buf[20]; \ ++ char *__dest = (Dest); \ ++ size_t __len = (Len); \ ++ char *__cp = _itoa ((Val), __buf + sizeof (__buf), 10, 0); \ ++ size_t __cp_len = MIN (__buf + sizeof (__buf) - __cp, __len); \ ++ memcpy (__dest, __cp, __cp_len); \ ++ memcpy (__dest + __cp_len, " cycles", \ ++ MIN (__len - __cp_len, sizeof (" cycles"))); \ ++ __dest[__len - 1] = '\0'; \ ++ } while (0) +diff -urN glibc-2.17-c758a686/sysdeps/generic/hp-timing.h glibc-2.17-c758a686/sysdeps/generic/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/generic/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/generic/hp-timing.h 2015-06-20 21:36:22.190764717 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. Generic version. +- Copyright (C) 1998, 2000 Free Software Foundation, Inc. ++ Copyright (C) 1998-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1998. + +@@ -20,59 +20,17 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +- + /* There are no generic definitions for the times. We could write something + using the `gettimeofday' system call where available but the overhead of +- the system call might be too high. +- +- In case a platform supports timers in the hardware the following macros +- and types must be defined: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +- +-*/ ++ the system call might be too high. */ + + /* Provide dummy definitions. */ + #define HP_TIMING_AVAIL (0) ++#define HP_SMALL_TIMING_AVAIL (0) + #define HP_TIMING_INLINE (0) + typedef int hp_timing_t; +-#define HP_TIMING_ZERO(Var) + #define HP_TIMING_NOW(var) +-#define HP_TIMING_DIFF_INIT() + #define HP_TIMING_DIFF(Diff, Start, End) +-#define HP_TIMING_ACCUM(Sum, Diff) + #define HP_TIMING_ACCUM_NT(Sum, Diff) + #define HP_TIMING_PRINT(Buf, Len, Val) + +diff -urN glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +--- glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2015-06-20 23:38:08.609083190 -0400 ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2015-06-20 22:07:15.207493957 -0400 +@@ -315,7 +315,7 @@ + /* The object to be initialized first. */ + EXTERN struct link_map *_dl_initfirst; + +-#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL ++#if HP_SMALL_TIMING_AVAIL + /* Start time on CPU clock. */ + EXTERN hp_timing_t _dl_cpuclock_offset; + #endif +@@ -538,11 +538,6 @@ + /* All search directories defined at startup. */ + EXTERN struct r_search_path_elem *_dl_init_all_dirs; + +-#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL +- /* Overhead of a high-precision timing measurement. */ +- EXTERN hp_timing_t _dl_hp_timing_overhead; +-#endif +- + #ifdef NEED_DL_SYSINFO + /* Syscall handling improvements. This is very specific to x86. */ + EXTERN uintptr_t _dl_sysinfo; +diff -urN glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.c glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.c +--- glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,23 +0,0 @@ +-/* Support for high precision, low overhead timing functions. i686 version. +- Copyright (C) 1998, 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 1998. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-/* We have to define the variable for the overhead. */ +-hp_timing_t _dl_hp_timing_overhead; +diff -urN glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.h glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/i386/i686/hp-timing.h 2015-06-20 23:03:58.919192570 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. i686 version. +- Copyright (C) 1998, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. ++ Copyright (C) 1998-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1998. + +@@ -20,62 +20,9 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +- +-/* The macros defined here use the timestamp counter in i586 and up versions +- of the x86 processors. They provide a very accurate way to measure the +- time with very little overhead. The time values themself have no real +- meaning, only differences are interesting. +- +- This version is for the i686 processors. The difference to the i586 +- version is that the timerstamp register is unconditionally used. This is +- not the case for the i586 version where we have to perform runtime test +- whether the processor really has this capability. We have to make this +- distinction since the sysdeps/i386/i586 code is supposed to work on all +- platforms while the i686 already contains i686-specific code. +- +- The list of macros we need includes the following: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +- +-*/ +- + /* We always assume having the timestamp register. */ + #define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) + + /* We indeed have inlined functions. */ + #define HP_TIMING_INLINE (1) +@@ -83,9 +30,6 @@ + /* We use 64bit values for the times. */ + typedef unsigned long long int hp_timing_t; + +-/* Set timestamp value to zero. */ +-#define HP_TIMING_ZERO(Var) (Var) = (0) +- + /* That's quite simple. Use the `rdtsc' instruction. Note that the value + might not be 100% accurate since there might be some more instructions + running in this moment. This could be changed by using a barrier like +@@ -93,64 +37,6 @@ + in accurate clock cycles here so we don't do this. */ + #define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rdtsc" : "=A" (Var)) + +-/* Use two 'rdtsc' instructions in a row to find out how long it takes. */ +-#define HP_TIMING_DIFF_INIT() \ +- do { \ +- if (GLRO(dl_hp_timing_overhead) == 0) \ +- { \ +- int __cnt = 5; \ +- GLRO(dl_hp_timing_overhead) = ~0ull; \ +- do \ +- { \ +- hp_timing_t __t1, __t2; \ +- HP_TIMING_NOW (__t1); \ +- HP_TIMING_NOW (__t2); \ +- if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ +- GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ +- } \ +- while (--__cnt > 0); \ +- } \ +- } while (0) +- +-/* It's simple arithmetic for us. */ +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-/* We have to jump through hoops to get this correctly implemented. */ +-#define HP_TIMING_ACCUM(Sum, Diff) \ +- do { \ +- int __not_done; \ +- hp_timing_t __oldval = (Sum); \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- do \ +- { \ +- hp_timing_t __newval = __oldval + __diff; \ +- int __temp0, __temp1; \ +- __asm__ __volatile__ ("xchgl %0, %%ebx\n\t" \ +- "lock; cmpxchg8b %1\n\t" \ +- "sete %%bl\n\t" \ +- "xchgl %0, %%ebx" \ +- : "=SD" (__not_done), "=m" (Sum), \ +- "=A" (__oldval), "=c" (__temp0) \ +- : "m" (Sum), "2" (__oldval), \ +- "3" ((unsigned int) (__newval >> 32)), \ +- "0" ((unsigned int) __newval)); \ +- } \ +- while ((unsigned char) __not_done); \ +- } while (0) +- +-/* No threads, no extra work. */ +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-/* Print the time value. */ +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \ +- size_t __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/i386/i686/Makefile glibc-2.17-c758a686/sysdeps/i386/i686/Makefile +--- glibc-2.17-c758a686/sysdeps/i386/i686/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/i386/i686/Makefile 2015-06-20 21:22:16.306457831 -0400 +@@ -1,8 +1,3 @@ +-ifeq ($(subdir),csu) +-sysdep_routines += hp-timing +-elide-routines.os += hp-timing +-endif +- + # So that we can test __m128's alignment + stack-align-test-flags += -msse + +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/hp-timing.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/hp-timing.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,81 +0,0 @@ +-/* High precision, low overhead timing functions. Linux/PPC32 version. +- Copyright (C) 2005 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#ifndef _HP_TIMING_H +-#define _HP_TIMING_H 1 +- +- +-/* There are no generic definitions for the times. We could write something +- using the `gettimeofday' system call where available but the overhead of +- the system call might be too high. +- +- In case a platform supports timers in the hardware the following macros +- and types must be defined: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +- +-*/ +- +-/* Provide dummy definitions. */ +-#define HP_TIMING_AVAIL (0) +-#define HP_TIMING_INLINE (0) +-typedef unsigned long long int hp_timing_t; +-#define HP_TIMING_ZERO(Var) +-#define HP_TIMING_NOW(var) +-#define HP_TIMING_DIFF_INIT() +-#define HP_TIMING_DIFF(Diff, Start, End) +-#define HP_TIMING_ACCUM(Sum, Diff) +-#define HP_TIMING_ACCUM_NT(Sum, Diff) +-#define HP_TIMING_PRINT(Buf, Len, Val) +- +-/* Since this implementation is not available we tell the user about it. */ +-#define HP_TIMING_NONAVAIL 1 +- +-#endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.c +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,24 +0,0 @@ +-/* Support for high precision, low overhead timing functions. +- powerpc64 version. +- Copyright (C) 2005, 2008 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 1998. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-/* We have to define the variable for the overhead. */ +-hp_timing_t _dl_hp_timing_overhead; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h 2015-06-20 23:38:08.326091657 -0400 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/hp-timing.h 2015-06-20 21:38:56.874066681 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. powerpc64 version. +- Copyright (C) 2005, 2008 Free Software Foundation, Inc. ++ Copyright (C) 2005-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1998. + +@@ -20,55 +20,9 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +-#include +- +-/* The macros defined here use the powerpc 64-bit time base register. +- The time base is nominally clocked at 1/8th the CPU clock, but this +- can vary. +- +- The list of macros we need includes the following: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +- +-*/ +- + /* We always assume having the timestamp register. */ + #define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) + + /* We indeed have inlined functions. */ + #define HP_TIMING_INLINE (1) +@@ -76,13 +30,10 @@ + /* We use 64bit values for the times. */ + typedef unsigned long long int hp_timing_t; + +-/* Set timestamp value to zero. */ +-#define HP_TIMING_ZERO(Var) (Var) = (0) +- + /* That's quite simple. Use the `mftb' instruction. Note that the value + might not be 100% accurate since there might be some more instructions + running in this moment. This could be changed by using a barrier like +- 'lwsync' right before the `mftb' instruciton. But we are not interested ++ 'lwsync' right before the `mftb' instruction. But we are not interested + in accurate clock cycles here so we don't do this. */ + + #define HP_TIMING_NOW(Var) \ +@@ -98,51 +49,6 @@ + Var = ((hp_timing_t) hi << 32) | lo; \ + } while (0) + +- +-/* Use two 'mftb' instructions in a row to find out how long it takes. +- On current POWER4, POWER5, and 970 processors mftb take ~10 cycles. */ +-#define HP_TIMING_DIFF_INIT() \ +- do { \ +- if (GLRO(dl_hp_timing_overhead) == 0) \ +- { \ +- int __cnt = 5; \ +- GLRO(dl_hp_timing_overhead) = ~0ull; \ +- do \ +- { \ +- hp_timing_t __t1, __t2; \ +- HP_TIMING_NOW (__t1); \ +- HP_TIMING_NOW (__t2); \ +- if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ +- GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ +- } \ +- while (--__cnt > 0); \ +- } \ +- } while (0) +- +-/* It's simple arithmetic in 64-bit. */ +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-/* We need to insure that this add is atomic in threaded environments. We use +- __arch_atomic_exchange_and_add_64 from atomic.h to get thread safety. */ +-#define HP_TIMING_ACCUM(Sum, Diff) \ +- do { \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- __arch_atomic_exchange_and_add_64 (&(Sum), __diff); \ +- } while (0) +- +-/* No threads, no extra work. */ +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-/* Print the time value. */ +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \ +- size_t __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " ticks", MIN (__len, sizeof (" ticks"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.c +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,24 +0,0 @@ +-/* Support for high precision, low overhead timing functions. +- powerpc64 version. +- Copyright (C) 2005 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Ulrich Drepper , 1998. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-/* We have to define the variable for the overhead. */ +-hp_timing_t _dl_hp_timing_overhead; +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/hp-timing.h 2015-06-20 21:42:32.315524442 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. powerpc64 version. +- Copyright (C) 2005, 2008 Free Software Foundation, Inc. ++ Copyright (C) 2005-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1998. + +@@ -20,55 +20,9 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +-#include +- +-/* The macros defined here use the powerpc 64-bit time base register. +- The time base is nominally clocked at 1/8th the CPU clock, but this +- can vary. +- +- The list of macros we need includes the following: +- +- - HP_TIMING_AVAIL: test for availability. +- +- - HP_TIMING_INLINE: this macro is non-zero if the functionality is not +- implemented using function calls but instead uses some inlined code +- which might simply consist of a few assembler instructions. We have to +- know this since we might want to use the macros here in places where we +- cannot make function calls. +- +- - hp_timing_t: This is the type for variables used to store the time +- values. +- +- - HP_TIMING_ZERO: clear `hp_timing_t' object. +- +- - HP_TIMING_NOW: place timestamp for current time in variable given as +- parameter. +- +- - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the +- HP_TIMING_DIFF macro. +- +- - HP_TIMING_DIFF: compute difference between two times and store it +- in a third. Source and destination might overlap. +- +- - HP_TIMING_ACCUM: add time difference to another variable. This might +- be a bit more complicated to implement for some platforms as the +- operation should be thread-safe and 64bit arithmetic on 32bit platforms +- is not. +- +- - HP_TIMING_ACCUM_NT: this is the variant for situations where we know +- there are no threads involved. +- +- - HP_TIMING_PRINT: write decimal representation of the timing value into +- the given string. This operation need not be inline even though +- HP_TIMING_INLINE is specified. +- +-*/ +- + /* We always assume having the timestamp register. */ + #define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) + + /* We indeed have inlined functions. */ + #define HP_TIMING_INLINE (1) +@@ -76,13 +30,10 @@ + /* We use 64bit values for the times. */ + typedef unsigned long long int hp_timing_t; + +-/* Set timestamp value to zero. */ +-#define HP_TIMING_ZERO(Var) (Var) = (0) +- + /* That's quite simple. Use the `mftb' instruction. Note that the value + might not be 100% accurate since there might be some more instructions + running in this moment. This could be changed by using a barrier like +- 'lwsync' right before the `mftb' instruciton. But we are not interested ++ 'lwsync' right before the `mftb' instruction. But we are not interested + in accurate clock cycles here so we don't do this. */ + #ifdef _ARCH_PWR4 + #define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mfspr %0,268" : "=r" (Var)) +@@ -90,50 +41,6 @@ + #define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mftb %0" : "=r" (Var)) + #endif + +-/* Use two 'mftb' instructions in a row to find out how long it takes. +- On current POWER4, POWER5, and 970 processors mftb take ~10 cycles. */ +-#define HP_TIMING_DIFF_INIT() \ +- do { \ +- if (GLRO(dl_hp_timing_overhead) == 0) \ +- { \ +- int __cnt = 5; \ +- GLRO(dl_hp_timing_overhead) = ~0ull; \ +- do \ +- { \ +- hp_timing_t __t1, __t2; \ +- HP_TIMING_NOW (__t1); \ +- HP_TIMING_NOW (__t2); \ +- if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ +- GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ +- } \ +- while (--__cnt > 0); \ +- } \ +- } while (0) +- +-/* It's simple arithmetic in 64-bit. */ +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-/* We need to insure that this add is atomic in threaded environments. We use +- __arch_atomic_exchange_and_add_64 from atomic.h to get thread safety. */ +-#define HP_TIMING_ACCUM(Sum, Diff) \ +- do { \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- __arch_atomic_exchange_and_add_64 (&(Sum), __diff); \ +- } while (0) +- +-/* No threads, no extra work. */ +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-/* Print the time value. */ +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \ +- size_t __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " ticks", MIN (__len, sizeof (" ticks"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile 2015-06-20 23:38:08.082098958 -0400 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/Makefile 2015-06-20 21:22:16.306457831 -0400 +@@ -37,11 +37,6 @@ + + CFLAGS-libc-start.c += -fno-asynchronous-unwind-tables + +-ifeq ($(subdir),csu) +-sysdep_routines += hp-timing +-elide-routines.os += hp-timing +-endif +- + ifeq ($(subdir),elf) + # help gcc inline asm code from dl-machine.h + +cflags += -finline-limit=2000 +diff -urN glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.c glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.c +--- glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,23 +0,0 @@ +-/* Support for high precision, low overhead timing functions. sparcv9 version. +- Copyright (C) 2001, 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by David S. Miller , 2001. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-/* We have to define the variable for the overhead. */ +-hp_timing_t _dl_hp_timing_overhead; +diff -urN glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.h glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/hp-timing.h 2015-06-20 21:43:48.754203254 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. sparcv9 version. +- Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ++ Copyright (C) 2001-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller , 2001. + +@@ -20,67 +20,17 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +- + #define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) + #define HP_TIMING_INLINE (1) + + typedef unsigned long long int hp_timing_t; + +-#define HP_TIMING_ZERO(Var) (Var) = (0) +- + #define HP_TIMING_NOW(Var) \ + __asm__ __volatile__ ("rd %%tick, %L0\n\t" \ + "srlx %L0, 32, %H0" \ + : "=r" (Var)) + +-#define HP_TIMING_DIFF_INIT() \ +- do { \ +- int __cnt = 5; \ +- GLRO(dl_hp_timing_overhead) = ~0ull; \ +- do \ +- { \ +- hp_timing_t __t1, __t2; \ +- HP_TIMING_NOW (__t1); \ +- HP_TIMING_NOW (__t2); \ +- if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ +- GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ +- } \ +- while (--__cnt > 0); \ +- } while (0) +- +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-#define HP_TIMING_ACCUM(Sum, Diff) \ +-do { \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- __asm__ __volatile__("srl %L0, 0, %%g1\n\t" \ +- "sllx %H0, 32, %%g6\n\t" \ +- "or %%g1, %%g6, %%g1\n\t" \ +- "1: ldx [%1], %%g5\n\t" \ +- "add %%g5, %%g1, %%g6\n\t" \ +- "casx [%1], %%g5, %%g6\n\t" \ +- "cmp %%g5, %%g6\n\t" \ +- "bne,pn %%xcc, 1b\n\t" \ +- " nop" \ +- : /* no outputs */ \ +- : "r" (__diff), "r" (&(Sum)) \ +- : "memory", "g1", "g5", "g6"); \ +-} while(0) +- +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \ +- int __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/Makefile glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/Makefile +--- glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/Makefile 2015-06-20 21:22:16.307457801 -0400 +@@ -1,10 +1,5 @@ + sysdep-CFLAGS += -mcpu=ultrasparc -Wa,-Av9a + +-ifeq ($(subdir),csu) +-sysdep_routines += hp-timing +-elide-routines.os += hp-timing +-endif +- + ifeq ($(have-as-vis3),yes) + ASFLAGS-.o += -Wa,-Av9d + ASFLAGS-.os += -Wa,-Av9d +diff -urN glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.c glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.c +--- glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,23 +0,0 @@ +-/* Support for high precision, low overhead timing functions. sparc64 version. +- Copyright (C) 2001, 2002 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by David S. Miller , 2001. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +- +-/* We have to define the variable for the overhead. */ +-hp_timing_t _dl_hp_timing_overhead; +diff -urN glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.h glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/hp-timing.h 2015-06-20 21:48:51.809000490 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. sparc64 version. +- Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. ++ Copyright (C) 2001-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David S. Miller , 2001. + +@@ -20,62 +20,14 @@ + #ifndef _HP_TIMING_H + #define _HP_TIMING_H 1 + +-#include +-#include +-#include <_itoa.h> +- + #define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) + #define HP_TIMING_INLINE (1) + + typedef unsigned long int hp_timing_t; + +-#define HP_TIMING_ZERO(Var) (Var) = (0) +- + #define HP_TIMING_NOW(Var) __asm__ __volatile__ ("rd %%tick, %0" : "=r" (Var)) + +-#define HP_TIMING_DIFF_INIT() \ +- do { \ +- int __cnt = 5; \ +- GLRO(dl_hp_timing_overhead) = ~0ull; \ +- do \ +- { \ +- hp_timing_t __t1, __t2; \ +- HP_TIMING_NOW (__t1); \ +- HP_TIMING_NOW (__t2); \ +- if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \ +- GLRO(dl_hp_timing_overhead) = __t2 - __t1; \ +- } \ +- while (--__cnt > 0); \ +- } while (0) +- +-#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start)) +- +-#define HP_TIMING_ACCUM(Sum, Diff) \ +-do { \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- hp_timing_t tmp1, tmp2; \ +- __asm__ __volatile__("1: ldx [%3], %0\n\t" \ +- "add %0, %2, %1\n\t" \ +- "casx [%3], %0, %1\n\t" \ +- "cmp %0, %1\n\t" \ +- "bne,pn %%xcc, 1b\n\t" \ +- " nop" \ +- : "=&r" (tmp1), "=&r" (tmp2) \ +- : "r" (__diff), "r" (&(Sum)) \ +- : "memory", "g1", "g5", "g6"); \ +-} while(0) +- +-#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff) +- +-#define HP_TIMING_PRINT(Buf, Len, Val) \ +- do { \ +- char __buf[20]; \ +- char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \ +- int __len = (Len); \ +- char *__dest = (Buf); \ +- while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ +- *__dest++ = *__cp++; \ +- memcpy (__dest, " clock cycles", MIN (__len, sizeof (" clock cycles"))); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/sparc/sparc64/Makefile glibc-2.17-c758a686/sysdeps/sparc/sparc64/Makefile +--- glibc-2.17-c758a686/sysdeps/sparc/sparc64/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/Makefile 2015-06-20 21:22:16.307457801 -0400 +@@ -1,8 +1,3 @@ +-ifeq ($(subdir),csu) +-sysdep_routines += hp-timing +-elide-routines.os += hp-timing +-endif +- + ifeq ($(subdir),string) + sysdep_routines += align-cpy + endif +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.c glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.c +--- glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,2 +0,0 @@ +-/* We can use the i686 implementation without changes. */ +-#include +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.h glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.h +--- glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/hp-timing.h 2015-06-20 21:43:09.403398207 -0400 +@@ -1,5 +1,5 @@ + /* High precision, low overhead timing functions. x86-64 version. +- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. ++ Copyright (C) 2002-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,24 +17,24 @@ + . */ + + #ifndef _HP_TIMING_H ++#define _HP_TIMING_H 1 + +-/* We can use some of the i686 implementation without changes. */ +-# include ++/* We always assume having the timestamp register. */ ++#define HP_TIMING_AVAIL (1) ++#define HP_SMALL_TIMING_AVAIL (1) ++ ++/* We indeed have inlined functions. */ ++#define HP_TIMING_INLINE (1) ++ ++/* We use 64bit values for the times. */ ++typedef unsigned long long int hp_timing_t; + + /* The "=A" constraint used in 32-bit mode does not work in 64-bit mode. */ +-# undef HP_TIMING_NOW +-# define HP_TIMING_NOW(Var) \ ++#define HP_TIMING_NOW(Var) \ + ({ unsigned int _hi, _lo; \ + asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \ + (Var) = ((unsigned long long int) _hi << 32) | _lo; }) + +-/* The funny business for 32-bit mode is not required here. */ +-# undef HP_TIMING_ACCUM +-# define HP_TIMING_ACCUM(Sum, Diff) \ +- do { \ +- hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ +- __asm__ __volatile__ ("lock; addq %1, %0" \ +- : "=m" (Sum) : "r" (__diff), "m" (Sum)); \ +- } while (0) ++#include + + #endif /* hp-timing.h */ +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/Makefile glibc-2.17-c758a686/sysdeps/x86_64/Makefile +--- glibc-2.17-c758a686/sysdeps/x86_64/Makefile 2015-06-20 23:38:08.530085553 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/Makefile 2015-06-20 21:22:16.307457801 -0400 +@@ -2,8 +2,6 @@ + long-double-fcts = yes + + ifeq ($(subdir),csu) +-sysdep_routines += hp-timing +-elide-routines.os += hp-timing + gen-as-const-headers += link-defines.sym + endif + +diff -urN glibc-2.17-c758a686/test-skeleton.c glibc-2.17-c758a686/test-skeleton.c +--- glibc-2.17-c758a686/test-skeleton.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/test-skeleton.c 2015-06-20 21:22:16.307457801 -0400 +@@ -18,8 +18,10 @@ + . */ + + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -194,6 +196,32 @@ + exit (1); + } + ++/* Set fortification error handler. Used when tests want to verify that bad ++ code is caught by the library. */ ++static void ++__attribute__ ((unused)) ++set_fortify_handler (void (*handler) (int sig)) ++{ ++ struct sigaction sa; ++ ++ sa.sa_handler = handler; ++ sa.sa_flags = 0; ++ sigemptyset (&sa.sa_mask); ++ ++ sigaction (SIGABRT, &sa, NULL); ++ ++ /* Avoid all the buffer overflow messages on stderr. */ ++ int fd = open (_PATH_DEVNULL, O_WRONLY); ++ if (fd == -1) ++ close (STDERR_FILENO); ++ else ++ { ++ dup2 (fd, STDERR_FILENO); ++ close (fd); ++ } ++ setenv ("LIBC_FATAL_STDERR_", "1", 1); ++} ++ + /* We provide the entry point here. */ + int + main (int argc, char *argv[]) diff --git a/SOURCES/glibc-rh1085290.patch b/SOURCES/glibc-rh1085290.patch new file mode 100644 index 00000000..8b60857d --- /dev/null +++ b/SOURCES/glibc-rh1085290.patch @@ -0,0 +1,60 @@ +commit dd3022d75e6fb8957843d6d84257a5d8457822d5 +Author: Siddhesh Poyarekar +Date: Thu Mar 27 19:49:51 2014 +0530 + + Return NULL for wildcard values in getnetgrent from nscd (BZ #16759) + + getnetgrent is supposed to return NULL for values that are wildcards + in the (host, user, domain) triplet. This works correctly with nscd + disabled, but with it enabled, it returns a blank ("") instead of a + NULL. This is easily seen with the output of `getent netgroup foonet` + for a netgroup foonet defined as follows in /etc/netgroup: + + foonet (,foo,) + + The output with nscd disabled is: + + foonet ( ,foo,) + + while with nscd enabled, it is: + + foonet (,foo,) + + The extra space with nscd disabled is due to the fact that `getent + netgroup` adds it if the return value from getnetgrent is NULL for + either host or user. + +diff --git glibc-2.17-c758a686/inet/getnetgrent_r.c glibc-2.17-c758a686/inet/getnetgrent_r.c +index 62cdfda..f6d064d 100644 +--- glibc-2.17-c758a686/inet/getnetgrent_r.c ++++ glibc-2.17-c758a686/inet/getnetgrent_r.c +@@ -235,6 +235,14 @@ endnetgrent (void) + __libc_lock_unlock (lock); + } + ++static const char * ++get_nonempty_val (const char *in) ++{ ++ if (*in == '\0') ++ return NULL; ++ return in; ++} ++ + #ifdef USE_NSCD + static enum nss_status + nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen, +@@ -243,11 +251,11 @@ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen, + return NSS_STATUS_UNAVAIL; + + datap->type = triple_val; +- datap->val.triple.host = datap->cursor; ++ datap->val.triple.host = get_nonempty_val (datap->cursor); + datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1; +- datap->val.triple.user = datap->cursor; ++ datap->val.triple.user = get_nonempty_val (datap->cursor); + datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1; +- datap->val.triple.domain = datap->cursor; ++ datap->val.triple.domain = get_nonempty_val (datap->cursor); + datap->cursor = (char *) __rawmemchr (datap->cursor, '\0') + 1; + + return NSS_STATUS_SUCCESS; diff --git a/SOURCES/glibc-rh1085313.patch b/SOURCES/glibc-rh1085313.patch new file mode 100644 index 00000000..26c96db4 --- /dev/null +++ b/SOURCES/glibc-rh1085313.patch @@ -0,0 +1,34 @@ +commit 58b930ae216bfa98cd60212b954b07b9963d6d04 +Author: Siddhesh Poyarekar +Date: Wed Sep 10 21:51:50 2014 +0530 + + Return failure in getnetgrent only when all netgroups have been searched (#17363) + + The netgroups lookup code fails when one of the groups in the search + tree is empty. In such a case it only returns the leaves of the tree + after the blank netgroup. This is because the line parser returns a + NOTFOUND status when the netgroup exists but is empty. The + __getnetgrent_internal implementation needs to be fixed to try + remaining groups if the current group is entry. This patch implements + this fix. Tested on x86_64. + + [BZ #17363] + * inet/getnetgrent_r.c (__internal_getnetgrent_r): Try next + group if the current group is empty. + +diff --git glibc-2.17-c758a686/inet/getnetgrent_r.c glibc-2.17-c758a686/inet/getnetgrent_r.c +index f6d064d..e101537 100644 +--- glibc-2.17-c758a686/inet/getnetgrent_r.c ++++ glibc-2.17-c758a686/inet/getnetgrent_r.c +@@ -297,7 +297,10 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp, + { + status = DL_CALL_FCT (*fct, (datap, buffer, buflen, &errno)); + +- if (status == NSS_STATUS_RETURN) ++ if (status == NSS_STATUS_RETURN ++ /* The service returned a NOTFOUND, but there are more groups that we ++ need to resolve before we give up. */ ++ || (status == NSS_STATUS_NOTFOUND && datap->needed_groups != NULL)) + { + /* This was the last one for this group. Look at next group + if available. */ diff --git a/SOURCES/glibc-rh1098042.patch b/SOURCES/glibc-rh1098042.patch new file mode 100644 index 00000000..6cc8fd00 --- /dev/null +++ b/SOURCES/glibc-rh1098042.patch @@ -0,0 +1,28 @@ +commit cf26a0cb6a0bbaca46a01ddad6662e5e5159a32a +Author: Siddhesh Poyarekar +Date: Thu May 15 12:33:11 2014 +0530 + + Return EAI_AGAIN for AF_UNSPEC when herrno is TRY_AGAIN (BZ #16849) + + getaddrinfo correctly returns EAI_AGAIN for AF_INET and AF_INET6 + queries. For AF_UNSPEC however, an older change + (a682a1bf553b1efe4dbb03207fece5b719cec482) broke the check and due to + that the returned error was EAI_NONAME. + + This patch fixes the check so that a non-authoritative not-found is + returned as EAI_AGAIN to the user instead of EAI_NONAME. + +diff --git glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +index 6258330..8f392b9 100644 +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -867,8 +867,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + if (status != NSS_STATUS_TRYAGAIN + || rc != ERANGE || herrno != NETDB_INTERNAL) + { +- if (status == NSS_STATUS_TRYAGAIN +- && herrno == TRY_AGAIN) ++ if (herrno == TRY_AGAIN) + no_data = EAI_AGAIN; + else + no_data = herrno == NO_DATA; diff --git a/SOURCES/glibc-rh1098047.patch b/SOURCES/glibc-rh1098047.patch new file mode 100644 index 00000000..bec040ca --- /dev/null +++ b/SOURCES/glibc-rh1098047.patch @@ -0,0 +1,247 @@ +commit 16b293a7a6f65d8ff348a603d19e8fd4372fa3a9 +Author: Siddhesh Poyarekar +Date: Wed Apr 30 11:48:43 2014 +0530 + + Do not fail if one of the two responses to AF_UNSPEC fails (BZ #14308) + + [Fixes BZ #14308, #12994, #13651] + + AF_UNSPEC results in sending two queries in parallel, one for the A + record and the other for the AAAA record. If one of these is a + referral, then the query fails, which is wrong. It should return at + least the one successful response. + + The fix has two parts. The first part makes the referral fall back to + the SERVFAIL path, which results in using the successful response. + There is a bug in that path however, due to which the second part is + necessary. The bug here is that if the first response is a failure + and the second succeeds, __libc_res_nsearch does not detect that and + assumes a failure. The case where the first response is a success and + the second fails, works correctly. + + This condition is produced by buggy routers, so here's a crude + interposable library that can simulate such a condition. The library + overrides the recvfrom syscall and modifies the header of the packet + received to reproduce this scenario. It has two key variables: + mod_packet and first_error. + + The mod_packet variable when set to 0, results in odd packets being + modified to be a referral. When set to 1, even packets are modified + to be a referral. + + The first_error causes the first response to be a failure so that a + domain-appended search is performed to test the second part of the + __libc_nsearch fix. + + The driver for this fix is a simple getaddrinfo program that does an + AF_UNSPEC query. I have omitted this since it should be easy to + implement. + + I have tested this on x86_64. + + The interceptor library source: + + /* Override recvfrom and modify the header of the first DNS response to make it + a referral and reproduce bz #845218. We have to resort to this ugly hack + because we cannot make bind return the buggy response of a referral for the + AAAA record and an authoritative response for the A record. */ + #define _GNU_SOURCE + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /* Lifted from resolv/arpa/nameser_compat.h. */ + typedef struct { + unsigned id :16; /*%< query identification number */ + #if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /*%< response flag */ + unsigned opcode: 4; /*%< purpose of message */ + unsigned aa: 1; /*%< authoritive answer */ + unsigned tc: 1; /*%< truncated message */ + unsigned rd: 1; /*%< recursion desired */ + /* fields + * in + * fourth + * byte + * */ + unsigned ra: 1; /*%< recursion available */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned rcode :4; /*%< response code */ + #endif + #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields + * in + * third + * byte + * */ + unsigned rd :1; /*%< recursion desired */ + unsigned tc :1; /*%< truncated message */ + unsigned aa :1; /*%< authoritive answer */ + unsigned opcode :4; /*%< purpose of message */ + unsigned qr :1; /*%< response flag */ + /* fields + * in + * fourth + * byte + * */ + unsigned rcode :4; /*%< response code */ + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned ad: 1; /*%< authentic data from named */ + unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /*%< recursion available */ + #endif + /* remaining + * bytes + * */ + unsigned qdcount :16; /*%< number of question entries */ + unsigned ancount :16; /*%< number of answer entries */ + unsigned nscount :16; /*%< number of authority entries */ + unsigned arcount :16; /*%< number of resource entries */ + } HEADER; + + static int done = 0; + + /* Packets to modify. 0 for the odd packets and 1 for even packets. */ + static const int mod_packet = 0; + + /* Set to true if the first request should result in an error, resulting in a + search query. */ + static bool first_error = true; + + static ssize_t (*real_recvfrom) (int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen); + + void + __attribute__ ((constructor)) + init (void) + { + real_recvfrom = dlsym (RTLD_NEXT, "recvfrom"); + + if (real_recvfrom == NULL) + { + printf ("Failed to get reference to recvfrom: %s\n", dlerror ()); + printf ("Cannot simulate test\n"); + abort (); + } + } + + /* Modify the second packet that we receive to set the header in a manner as to + reproduce BZ #845218. */ + static void + mod_buf (HEADER *h, int port) + { + if (done % 2 == mod_packet || (first_error && done == 1)) + { + printf ("(Modifying header)"); + + if (first_error && done == 1) + h->rcode = 3; + else + h->rcode = 0; /* NOERROR == 0. */ + h->ancount = 0; + h->aa = 0; + h->ra = 0; + h->arcount = 0; + } + done++; + } + + ssize_t + recvfrom (int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) + { + ssize_t ret = real_recvfrom (sockfd, buf, len, flags, src_addr, addrlen); + int port = htons (((struct sockaddr_in *) src_addr)->sin_port); + struct in_addr addr = ((struct sockaddr_in *) src_addr)->sin_addr; + const char *host = inet_ntoa (addr); + printf ("\n*** From %s:%d: ", host, port); + + mod_buf (buf, port); + + printf ("returned %zd\n", ret); + return ret; + } + + ChangeLog | 11 +++++++++++ + NEWS | 14 +++++++------- + resolv/res_query.c | 7 +++++-- + resolv/res_send.c | 2 +- + 4 files changed, 24 insertions(+), 10 deletions(-) + +commit e35c53e397e7abbd41fedacdedcfa5af7b5c2c52 +Author: Siddhesh Poyarekar +Date: Tue Jul 8 16:40:24 2014 +0530 + + Check value at resplen2 if it is not NULL + + There was a typo in the previous patch due to which resplen2 was + checked for non-zero instead of the value at resplen2. Fix that and + improve the condition by checking resplen2 for non-NULL (instead of + answerp2) and also adding the check in a third place. + + ChangeLog | 3 +++ + resolv/res_query.c | 9 +++++---- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff -pruN glibc-2.17-c758a686/resolv/res_query.c glibc-2.17-c758a686/resolv/res_query.c +--- glibc-2.17-c758a686/resolv/res_query.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/resolv/res_query.c 2014-09-05 14:28:06.439191017 +0530 +@@ -378,7 +378,9 @@ __libc_res_nsearch(res_state statp, + ret = __libc_res_nquerydomain(statp, name, NULL, class, type, + answer, anslen, answerp, + answerp2, nanswerp2, resplen2); +- if (ret > 0 || trailing_dot) ++ if (ret > 0 || trailing_dot ++ /* If the second response is valid then we use that. */ ++ || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) + return (ret); + saved_herrno = h_errno; + tried_as_is++; +@@ -418,7 +420,8 @@ __libc_res_nsearch(res_state statp, + answer, anslen, answerp, + answerp2, nanswerp2, + resplen2); +- if (ret > 0) ++ if (ret > 0 || (ret == 0 && resplen2 != NULL ++ && *resplen2 > 0)) + return (ret); + + if (answerp && *answerp != answer) { +@@ -487,7 +490,8 @@ __libc_res_nsearch(res_state statp, + ret = __libc_res_nquerydomain(statp, name, NULL, class, type, + answer, anslen, answerp, + answerp2, nanswerp2, resplen2); +- if (ret > 0) ++ if (ret > 0 || (ret == 0 && resplen2 != NULL ++ && *resplen2 > 0)) + return (ret); + } + +diff -pruN glibc-2.17-c758a686/resolv/res_send.c glibc-2.17-c758a686/resolv/res_send.c +--- glibc-2.17-c758a686/resolv/res_send.c 2014-09-05 14:28:30.039337246 +0530 ++++ glibc-2.17-c758a686/resolv/res_send.c 2014-09-05 14:28:06.439191017 +0530 +@@ -1343,6 +1343,7 @@ send_dg(res_state statp, + (*thisresplenp > *thisanssizp) + ? *thisanssizp : *thisresplenp); + ++ next_ns: + if (recvresp1 || (buf2 != NULL && recvresp2)) { + *resplen2 = 0; + return resplen; +@@ -1360,7 +1361,6 @@ send_dg(res_state statp, + goto wait; + } + +- next_ns: + __res_iclose(statp, false); + /* don't retry if called from dig */ + if (!statp->pfcode) diff --git a/SOURCES/glibc-rh1103856.patch b/SOURCES/glibc-rh1103856.patch new file mode 100644 index 00000000..8f3e9d17 --- /dev/null +++ b/SOURCES/glibc-rh1103856.patch @@ -0,0 +1,27 @@ +commit 4d653a59ffeae0f46f76a40230e2cfa9587b7e7e +Author: Siddhesh Poyarekar +Date: Fri May 30 22:43:52 2014 +0530 + + Add mmap usage in malloc_info output + + The current malloc_info xml output only has information about + allocations on the heap. Display information about number of mappings + and total mmapped size to this to complete the picture. + +diff -pruN glibc-2.17-c758a686/malloc/malloc.c glibc-2.17-c758a686/malloc/malloc.c +--- glibc-2.17-c758a686/malloc/malloc.c 2014-06-02 07:35:22.573256155 +0530 ++++ glibc-2.17-c758a686/malloc/malloc.c 2014-06-02 07:34:58.856257177 +0530 +@@ -6553,12 +6553,14 @@ malloc_info (int options, FILE *fp) + fprintf (fp, + "\n" + "\n" ++ "\n" + "\n" + "\n" + "\n" + "\n" + "\n", + total_nfastblocks, total_fastavail, total_nblocks, total_avail, ++ mp_.n_mmaps, mp_.mmapped_mem, + total_system, total_max_system, + total_aspace, total_aspace_mprotect); diff --git a/SOURCES/glibc-rh1103874.patch b/SOURCES/glibc-rh1103874.patch new file mode 100644 index 00000000..424d3f01 --- /dev/null +++ b/SOURCES/glibc-rh1103874.patch @@ -0,0 +1,152 @@ +diff -pruN glibc-2.17-c758a686/nptl/sysdeps/pthread/unwind-forcedunwind.c glibc-2.17-c758a686/nptl/sysdeps/pthread/unwind-forcedunwind.c +--- glibc-2.17-c758a686/nptl/sysdeps/pthread/unwind-forcedunwind.c 2010-05-04 16:57:23.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/unwind-forcedunwind.c 2014-06-02 23:00:02.901013275 +0530 +@@ -45,8 +45,10 @@ pthread_cancel_init (void) + + if (__builtin_expect (libgcc_s_handle != NULL, 1)) + { +- /* Force gcc to reload all values. */ +- asm volatile ("" ::: "memory"); ++ /* Order reads so as to prevent speculation of loads ++ of libgcc_s_{resume,personality,forcedunwind,getcfa} ++ to points prior to the write barrier. */ ++ atomic_read_barrier (); + return; + } + +@@ -72,9 +74,14 @@ pthread_cancel_init (void) + libgcc_s_forcedunwind = forcedunwind; + PTR_MANGLE (getcfa); + libgcc_s_getcfa = getcfa; +- /* Make sure libgcc_s_handle is written last. Otherwise, +- pthread_cancel_init might return early even when the pointer the +- caller is interested in is not initialized yet. */ ++ /* At the point at which any thread writes the handle ++ to libgcc_s_handle, the initialization is complete. ++ The writing of libgcc_s_handle is atomic. All other ++ threads reading libgcc_s_handle do so atomically. Any ++ thread that does not execute this function must issue ++ a read barrier to ensure that all of the above has ++ actually completed and that the values of the ++ function pointers are correct. */ + atomic_write_barrier (); + libgcc_s_handle = handle; + } +@@ -91,13 +98,19 @@ __unwind_freeres (void) + } + } + +-void +-_Unwind_Resume (struct _Unwind_Exception *exc) ++static __always_inline void ++_maybe_pthread_cancel_init (void) + { + if (__builtin_expect (libgcc_s_handle == NULL, 0)) + pthread_cancel_init (); + else + atomic_read_barrier (); ++} ++ ++void ++_Unwind_Resume (struct _Unwind_Exception *exc) ++{ ++ _maybe_pthread_cancel_init (); + + void (*resume) (struct _Unwind_Exception *exc) = libgcc_s_resume; + PTR_DEMANGLE (resume); +@@ -108,10 +123,7 @@ __gcc_personality_v0 (int version, _Unwi + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) + { +- if (__builtin_expect (libgcc_s_handle == NULL, 0)) +- pthread_cancel_init (); +- else +- atomic_read_barrier (); ++ _maybe_pthread_cancel_init (); + + _Unwind_Reason_Code (*personality) + (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, +@@ -122,10 +136,7 @@ _Unwind_Reason_Code + _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop, + void *stop_argument) + { +- if (__builtin_expect (libgcc_s_handle == NULL, 0)) +- pthread_cancel_init (); +- else +- atomic_read_barrier (); ++ _maybe_pthread_cancel_init (); + + _Unwind_Reason_Code (*forcedunwind) + (struct _Unwind_Exception *, _Unwind_Stop_Fn, void *) +@@ -135,10 +148,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exc + _Unwind_Word + _Unwind_GetCFA (struct _Unwind_Context *context) + { +- if (__builtin_expect (libgcc_s_handle == NULL, 0)) +- pthread_cancel_init (); +- else +- atomic_read_barrier (); ++ _maybe_pthread_cancel_init (); + + _Unwind_Word (*getcfa) (struct _Unwind_Context *) = libgcc_s_getcfa; + PTR_DEMANGLE (getcfa); +diff -pruN glibc-2.17-c758a686/sysdeps/gnu/unwind-resume.c glibc-2.17-c758a686/sysdeps/gnu/unwind-resume.c +--- glibc-2.17-c758a686/sysdeps/gnu/unwind-resume.c 2010-05-04 16:57:23.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/gnu/unwind-resume.c 2014-06-02 23:02:26.812007078 +0530 +@@ -20,8 +20,11 @@ + #include + #include + #include ++#include ++#include + #include + ++static void *libgcc_s_handle; + static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); + static _Unwind_Reason_Code (*libgcc_s_personality) + (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, +@@ -42,13 +45,32 @@ init (void) + + libgcc_s_resume = resume; + libgcc_s_personality = personality; ++ atomic_write_barrier (); ++ /* At the point at which any thread writes the handle ++ to libgcc_s_handle, the initialization is complete. ++ The writing of libgcc_s_handle is atomic. All other ++ threads reading libgcc_s_handle do so atomically. Any ++ thread that does not execute this function must issue ++ a read barrier to ensure that all of the above has ++ actually completed and that the values of the ++ function pointers are correct. */ ++ libgcc_s_handle = handle; + } + ++static __always_inline void ++_maybe_init (void) ++{ ++ if (__builtin_expect (libgcc_s_handle == NULL, 0)) ++ init (); ++ else ++ atomic_read_barrier (); ++} ++ ++ + void + _Unwind_Resume (struct _Unwind_Exception *exc) + { +- if (__builtin_expect (libgcc_s_resume == NULL, 0)) +- init (); ++ _maybe_init (); + libgcc_s_resume (exc); + } + +@@ -58,8 +80,7 @@ __gcc_personality_v0 (int version, _Unwi + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) + { +- if (__builtin_expect (libgcc_s_personality == NULL, 0)) +- init (); ++ _maybe_init (); + return libgcc_s_personality (version, actions, exception_class, + ue_header, context); + } diff --git a/SOURCES/glibc-rh1120490-int128.patch b/SOURCES/glibc-rh1120490-int128.patch new file mode 100644 index 00000000..b6c7c220 --- /dev/null +++ b/SOURCES/glibc-rh1120490-int128.patch @@ -0,0 +1,60 @@ +Upstream patches to allow older compilers to use link.h: + +commit 30477995dc8a680283b4d6e02039bca09de83cf9 +Author: Marko Myllynen +Date: Fri May 30 10:50:21 2014 -0700 + + Replace __int128 with __int128_t + + * sysdeps/x86_64/link-defines.sym (BND_SIZE): Replace __int128 + with __int128_t. + +commit 48332d822090e41253692053a00dfe224d3ebec0 +Author: H.J. Lu +Date: Fri Apr 25 09:33:41 2014 -0700 + + Replace __int128 with __int128_t in bits/link.h + + __int128 was added in GCC 4.6 and __int128_t was added before x86-64 + was supported. This patch replaces __int128 with __int128_t so that + the installed bits/link.h can be used with older GCC. + + * sysdeps/x86/bits/link.h (La_x86_64_regs): Replace __int128 + with __int128_t. + (La_x86_64_retval): Likewise. + +diff -urN glibc-2.17-c758a686/sysdeps/x86/bits/link.h glibc-2.17-c758a686/sysdeps/x86/bits/link.h +--- glibc-2.17-c758a686/sysdeps/x86/bits/link.h 2014-11-05 13:39:09.888988366 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86/bits/link.h 2014-11-05 13:39:52.800863646 -0500 +@@ -94,7 +94,7 @@ + La_x86_64_xmm lr_xmm[8]; + La_x86_64_vector lr_vector[8]; + #ifndef __ILP32__ +- __int128 lr_bnd[4]; ++ __int128_t lr_bnd[4]; + #endif + } La_x86_64_regs; + +@@ -110,8 +110,8 @@ + La_x86_64_vector lrv_vector0; + La_x86_64_vector lrv_vector1; + #ifndef __ILP32__ +- __int128 lrv_bnd0; +- __int128 lrv_bnd1; ++ __int128_t lrv_bnd0; ++ __int128_t lrv_bnd1; + #endif + } La_x86_64_retval; + +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym +--- glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym 2014-11-05 13:39:09.889988363 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym 2014-11-05 13:39:52.800863646 -0500 +@@ -6,7 +6,7 @@ + XMM_SIZE sizeof (La_x86_64_xmm) + YMM_SIZE sizeof (La_x86_64_ymm) + ZMM_SIZE sizeof (La_x86_64_zmm) +-BND_SIZE sizeof (__int128) ++BND_SIZE sizeof (__int128_t) + + LR_SIZE sizeof (struct La_x86_64_regs) + LR_RDX_OFFSET offsetof (struct La_x86_64_regs, lr_rdx) diff --git a/SOURCES/glibc-rh1120490.patch b/SOURCES/glibc-rh1120490.patch new file mode 100644 index 00000000..ccf6f337 --- /dev/null +++ b/SOURCES/glibc-rh1120490.patch @@ -0,0 +1,190 @@ +commit 602f80ec8b966cfad3b61914cbe14ee606cedf6e +Author: Siddhesh Poyarekar +Date: Tue Sep 16 22:16:01 2014 +0530 + + Make __extern_always_inline usable on clang++ again + + The fix for BZ #17266 (884ddc5081278f488ef8cd49951f41cfdbb480ce) + removed changes that had gone into cdefs.h to make + __extern_always_inline usable with clang++. This patch adds back + support for clang to detect if GNU inlining semantics are available, + this time without breaking the gcc use case. The check put here is + based on the earlier patch and assertion[1] that checking if + __GNUC_STDC_INLINE__ or __GNUC_GNU_INLINE__ is defined is sufficient + to determine that clang++ suports GNU inlining semantics. + + Tested with a simple program that builds with __extern_always_inline + with the patch and fails compilation without it. + + #include + #include + + extern void foo_alias (void) __asm ("foo"); + + __extern_always_inline void + foo (void) + { + puts ("hi oh world!"); + return foo_alias (); + } + + void + foo_alias (void) + { + puts ("hell oh world"); + } + + int + main () + { + foo (); + } + + [1] https://sourceware.org/ml/libc-alpha/2012-12/msg00306.html + + [BZ #17266] + * misc/sys/cdefs.h: Define __extern_always_inline for clang + 4.2 and newer. + +commit 884ddc5081278f488ef8cd49951f41cfdbb480ce +Author: Siddhesh Poyarekar +Date: Tue Sep 16 14:08:48 2014 +0530 + + Revert to defining __extern_inline only for gcc-4.3+ (BZ #17266) + + The check for only __GNUC_STDC_INLINE__ and __GNUC_GNU_INLINE__ may + not be sufficient since those flags were added during initial support + for C99 inlining semantics. There is also a problem with always + defining __extern_inline and __extern_always_inline, since it enables + inline wrapper functions even when GNU inlining semantics are not + guaranteed. This, along with the possibility of such wrappers using + redirection (btowc for example) could result in compiler generating an + infinitely recusrive call to the function. + + In fact it was such a recursion that led to this code being written + the way it was; see: + + https://bugzilla.redhat.com/show_bug.cgi?id=186410 + + The initial change was to fix bugs 14530 and 13741, but they can be + resolved by checking if __fortify_function and/or + __extern_always_inline are defined, as it has been done in this patch. + In addition, I have audited uses of __extern_always_inline to make + sure that none of the uses result in compilation errors. + + There is however a regression in this patch for llvm, since it reverts + the llvm expectation that __GNUC_STDC_INLINE__ or __GNUC_GNU_INLINE__ + definition imply proper extern inline semantics. + + 2014-09-16 Siddhesh Poyarekar + Jakub Jelinek + + [BZ #17266] + * libio/stdio.h: Check definition of __fortify_function + instead of __extern_always_inline to include bits/stdio2.h. + * math/bits/math-finite.h [__USE_XOPEN || __USE_ISOC99]: Also + check if __extern_always_inline is defined. + [__USE_MISC || __USE_XOPEN]: Likewise. + [__USE_ISOC99] Likewise. + * misc/sys/cdefs.h (__fortify_function): Define only if + __extern_always_inline is defined. + [!__cplusplus || __GNUC_PREREQ (4,3)]: Revert to defining + __extern_always_inline and __extern_inline only for g++-4.3 + and newer or a compatible gcc. + +diff --git glibc-2.17-c758a686/libio/stdio.h glibc-2.17-c758a686/libio/stdio.h +index d8c0bdb..1f4f837 100644 +--- glibc-2.17-c758a686/libio/stdio.h ++++ glibc-2.17-c758a686/libio/stdio.h +@@ -932,7 +932,7 @@ extern void funlockfile (FILE *__stream) __THROW; + #ifdef __USE_EXTERN_INLINES + # include + #endif +-#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline ++#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function + # include + #endif + #ifdef __LDBL_COMPAT +diff --git glibc-2.17-c758a686/math/bits/math-finite.h glibc-2.17-c758a686/math/bits/math-finite.h +index aa755de..0656645 100644 +--- glibc-2.17-c758a686/math/bits/math-finite.h ++++ glibc-2.17-c758a686/math/bits/math-finite.h +@@ -251,7 +251,8 @@ extern long double __REDIRECT_NTH (lgammal_r, (long double, int *), + # endif + #endif + +-#if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99 ++#if ((defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99) \ ++ && defined __extern_always_inline) + /* lgamma. */ + __extern_always_inline double __NTH (lgamma (double __d)) + { +@@ -284,7 +285,8 @@ __extern_always_inline long double __NTH (lgammal (long double __d)) + # endif + #endif + +-#if defined __USE_MISC || defined __USE_XOPEN ++#if ((defined __USE_MISC || defined __USE_XOPEN) \ ++ && defined __extern_always_inline) + /* gamma. */ + __extern_always_inline double __NTH (gamma (double __d)) + { +@@ -422,7 +424,7 @@ extern long double __REDIRECT_NTH (sqrtl, (long double), __sqrtl_finite); + # endif + #endif + +-#ifdef __USE_ISOC99 ++#if defined __USE_ISOC99 && defined __extern_always_inline + /* tgamma. */ + extern double __gamma_r_finite (double, int *); + __extern_always_inline double __NTH (tgamma (double __d)) +diff --git glibc-2.17-c758a686/misc/sys/cdefs.h glibc-2.17-c758a686/misc/sys/cdefs.h +index 04db956..01e81ba 100644 +--- glibc-2.17-c758a686/misc/sys/cdefs.h ++++ glibc-2.17-c758a686/misc/sys/cdefs.h +@@ -131,7 +131,6 @@ + /* Fortify support. */ + #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) + #define __bos0(ptr) __builtin_object_size (ptr, 0) +-#define __fortify_function __extern_always_inline __attribute_artificial__ + + #if __GNUC_PREREQ (4,3) + # define __warndecl(name, msg) \ +@@ -319,8 +318,17 @@ + #endif + + /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 +- inline semantics, unless -fgnu89-inline is used. */ +-#if (!defined __cplusplus || __GNUC_PREREQ (4,3)) && defined __GNUC__ ++ inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__ ++ or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions ++ older than 4.3 may define these macros and still not guarantee GNU inlining ++ semantics. ++ ++ clang++ identifies itself as gcc-4.2, but has support for GNU inlining ++ semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and ++ __GNUC_GNU_INLINE__ macro definitions. */ ++#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \ ++ || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \ ++ || defined __GNUC_GNU_INLINE__))) + # if defined __GNUC_STDC_INLINE__ || defined __cplusplus + # define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) + # define __extern_always_inline \ +@@ -329,13 +337,10 @@ + # define __extern_inline extern __inline + # define __extern_always_inline extern __always_inline + # endif +-#elif defined __GNUC__ /* C++ and GCC <4.3. */ +-# define __extern_inline extern __inline +-# define __extern_always_inline \ +- extern __always_inline +-#else /* Not GCC. */ +-# define __extern_inline /* Ignore */ +-# define __extern_always_inline /* Ignore */ ++#endif ++ ++#ifdef __extern_always_inline ++# define __fortify_function __extern_always_inline __attribute_artificial__ + #endif + + /* GCC 4.3 and above allow passing all anonymous arguments of an diff --git a/SOURCES/glibc-rh1125306.patch b/SOURCES/glibc-rh1125306.patch new file mode 100644 index 00000000..835a3eba --- /dev/null +++ b/SOURCES/glibc-rh1125306.patch @@ -0,0 +1,20 @@ +commit a11892631d92f594c690d0d50a642b0d1aba58b8 +Author: OndÅ™ej Bílka +Date: Wed May 7 14:08:57 2014 +0200 + + Fix typo in nscd/selinux.c + +diff --git glibc-2.17-c758a686/nscd/selinux.c glibc-2.17-c758a686/nscd/selinux.c +index 9a8a5a8..eaed6dd 100644 +--- glibc-2.17-c758a686/nscd/selinux.c ++++ glibc-2.17-c758a686/nscd/selinux.c +@@ -372,7 +372,7 @@ nscd_request_avc_has_perm (int fd, request_type req) + /* Get the security class for nscd. If this fails we will likely be + unable to do anything unless avc_deny_unknown is 0. */ +- if ((sc_nscd = string_to_security_class ("nscd")) == 0 +- && avc_deny_unknown == 1) ++ sc_nscd = string_to_security_class ("nscd"); ++ if (sc_nscd == 0 && avc_deny_unknown == 1) + dbg_log (_("Error getting security class for nscd.")); + + /* Convert permission to AVC bits. */ diff --git a/SOURCES/glibc-rh1132518-mpx.patch b/SOURCES/glibc-rh1132518-mpx.patch new file mode 100644 index 00000000..ec4495dd --- /dev/null +++ b/SOURCES/glibc-rh1132518-mpx.patch @@ -0,0 +1,386 @@ +# MPX Support for glibc: +# +# Note: Renamed configure.ac changes to configure.in changes. +# +# commit ea8ba7cd14d0f479bae8365ae5c4ef177bdd0aad +# Author: Igor Zamyatin +# Date: Wed Apr 16 14:43:16 2014 -0700 +# +# Save/restore bound registers for _dl_runtime_profile +# +# This patch saves and restores bound registers in x86-64 PLT for +# ld.so profile and LD_AUDIT: +# +# * sysdeps/x86_64/bits/link.h (La_x86_64_regs): Add lr_bnd. +# (La_x86_64_retval): Add lrv_bnd0 and lrv_bnd1. +# * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Save +# Intel MPX bound registers before _dl_profile_fixup. +# * sysdeps/x86_64/dl-trampoline.h: Restore Intel MPX bound +# registers after _dl_profile_fixup. Save and restore bound +# registers bnd0/bnd1 when calling _dl_call_pltexit. +# * sysdeps/x86_64/link-defines.sym (BND_SIZE): New. +# (LR_BND_OFFSET): Likewise. +# (LRV_BND0_OFFSET): Likewise. +# (LRV_BND1_OFFSET): Likewise. +# +# commit a4c75cfd56e536c2b18556e8a482d88dffa0fffc +# Author: Igor Zamyatin +# Date: Tue Apr 1 10:16:04 2014 -0700 +# +# Save/restore bound registers in _dl_runtime_resolve +# +# This patch saves and restores bound registers in symbol lookup for x86-64: +# +# 1. Branches without BND prefix clear bound registers. +# 2. x86-64 pass bounds in bound registers as specified in MPX psABI +# extension on hjl/mpx/master branch at +# +# https://github.com/hjl-tools/x86-64-psABI +# https://groups.google.com/forum/#!topic/x86-64-abi/KFsB0XTgWYc +# +# Binutils has been updated to create an alternate PLT to add BND prefix +# when branching to ld.so. +# +# * config.h.in (HAVE_MPX_SUPPORT): New #undef. +# * sysdeps/x86_64/configure.ac: Set HAVE_MPX_SUPPORT. +# * sysdeps/x86_64/configure: Regenerated. +# * sysdeps/x86_64/dl-trampoline.S (REGISTER_SAVE_AREA): New +# macro. +# (REGISTER_SAVE_RAX): Likewise. +# (REGISTER_SAVE_RCX): Likewise. +# (REGISTER_SAVE_RDX): Likewise. +# (REGISTER_SAVE_RSI): Likewise. +# (REGISTER_SAVE_RDI): Likewise. +# (REGISTER_SAVE_R8): Likewise. +# (REGISTER_SAVE_R9): Likewise. +# (REGISTER_SAVE_BND0): Likewise. +# (REGISTER_SAVE_BND1): Likewise. +# (REGISTER_SAVE_BND2): Likewise. +# (_dl_runtime_resolve): Use them. Save and restore Intel MPX +# bound registers when calling _dl_fixup. +# +diff -urN glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686/config.h.in +--- glibc-2.17-c758a686/config.h.in 2014-09-10 23:26:03.467045808 -0400 ++++ glibc-2.17-c758a686/config.h.in 2014-09-10 23:27:41.532851928 -0400 +@@ -107,6 +107,9 @@ + /* Define if assembler supports AVX512. */ + #undef HAVE_AVX512_ASM_SUPPORT + ++/* Define if assembler supports Intel MPX. */ ++#undef HAVE_MPX_SUPPORT ++ + /* Define if gcc supports FMA4. */ + #undef HAVE_FMA4_SUPPORT + +diff -urN glibc-2.17-c758a686/sysdeps/x86/bits/link.h glibc-2.17-c758a686/sysdeps/x86/bits/link.h +--- glibc-2.17-c758a686/sysdeps/x86/bits/link.h 2014-09-10 23:26:03.467045808 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86/bits/link.h 2014-09-10 23:27:41.533851926 -0400 +@@ -93,6 +93,9 @@ + uint64_t lr_rsp; + La_x86_64_xmm lr_xmm[8]; + La_x86_64_vector lr_vector[8]; ++#ifndef __ILP32__ ++ __int128 lr_bnd[4]; ++#endif + } La_x86_64_regs; + + /* Return values for calls from PLT on x86-64. */ +@@ -106,6 +109,10 @@ + long double lrv_st1; + La_x86_64_vector lrv_vector0; + La_x86_64_vector lrv_vector1; ++#ifndef __ILP32__ ++ __int128 lrv_bnd0; ++ __int128 lrv_bnd1; ++#endif + } La_x86_64_retval; + + #define La_x32_regs La_x86_64_regs +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure glibc-2.17-c758a686/sysdeps/x86_64/configure +--- glibc-2.17-c758a686/sysdeps/x86_64/configure 2014-09-10 23:26:03.573045598 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/configure 2014-09-10 23:27:41.532851928 -0400 +@@ -212,6 +212,33 @@ + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_novzeroupper" >&5 + $as_echo "$libc_cv_cc_novzeroupper" >&6; } + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Intel MPX support" >&5 ++$as_echo_n "checking for Intel MPX support... " >&6; } ++if ${libc_cv_asm_mpx+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.s <<\EOF ++ bndmov %bnd0,(%rsp) ++EOF ++if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ libc_cv_asm_mpx=yes ++else ++ libc_cv_asm_mpx=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_mpx" >&5 ++$as_echo "$libc_cv_asm_mpx" >&6; } ++if test $libc_cv_asm_mpx == yes; then ++ $as_echo "#define HAVE_MPX_SUPPORT 1" >>confdefs.h ++ ++fi ++ + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + + # work around problem with autoconf and empty lines at the end of files +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure.in glibc-2.17-c758a686/sysdeps/x86_64/configure.in +--- glibc-2.17-c758a686/sysdeps/x86_64/configure.in 2014-09-10 23:26:03.468045806 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/configure.in 2014-09-10 23:27:41.532851928 -0400 +@@ -70,6 +70,21 @@ + [libc_cv_cc_novzeroupper=no]) + ]) + ++dnl Check whether asm supports Intel MPX ++AC_CACHE_CHECK(for Intel MPX support, libc_cv_asm_mpx, [dnl ++cat > conftest.s <<\EOF ++ bndmov %bnd0,(%rsp) ++EOF ++if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then ++ libc_cv_asm_mpx=yes ++else ++ libc_cv_asm_mpx=no ++fi ++rm -f conftest*]) ++if test $libc_cv_asm_mpx == yes; then ++ AC_DEFINE(HAVE_MPX_SUPPORT) ++fi ++ + dnl It is always possible to access static and hidden symbols in an + dnl position independent way. + AC_DEFINE(PI_STATIC_AND_HIDDEN) +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h +--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h 2014-09-10 23:26:03.468045806 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h 2014-09-10 23:27:41.535851922 -0400 +@@ -63,6 +63,20 @@ + movaps (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp), %xmm6 + movaps (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp), %xmm7 + ++#ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov (LR_BND_OFFSET)(%rsp), %bnd0 # Restore bound ++ bndmov (LR_BND_OFFSET + BND_SIZE)(%rsp), %bnd1 # registers. ++ bndmov (LR_BND_OFFSET + BND_SIZE*2)(%rsp), %bnd2 ++ bndmov (LR_BND_OFFSET + BND_SIZE*3)(%rsp), %bnd3 ++# else ++ .byte 0x66,0x0f,0x1a,0x84,0x24;.long (LR_BND_OFFSET) ++ .byte 0x66,0x0f,0x1a,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE) ++ .byte 0x66,0x0f,0x1a,0x94,0x24;.long (LR_BND_OFFSET + BND_SIZE*2) ++ .byte 0x66,0x0f,0x1a,0x9c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3) ++# endif ++#endif ++ + #ifdef RESTORE_AVX + /* Check if any xmm0-xmm7 registers are changed by audit + module. */ +@@ -222,6 +236,16 @@ + vmovdqa %xmm1, (LRV_SIZE + XMM_SIZE)(%rcx) + #endif + ++#ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov %bnd0, LRV_BND0_OFFSET(%rcx) # Preserve returned bounds. ++ bndmov %bnd1, LRV_BND1_OFFSET(%rcx) ++# else ++ .byte 0x66,0x0f,0x1b,0x81;.long (LRV_BND0_OFFSET) ++ .byte 0x66,0x0f,0x1b,0x89;.long (LRV_BND1_OFFSET) ++# endif ++#endif ++ + fstpt LRV_ST0_OFFSET(%rcx) + fstpt LRV_ST1_OFFSET(%rcx) + +@@ -254,6 +278,16 @@ + 1: + #endif + ++#ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov LRV_BND0_OFFSET(%rcx), %bnd0 # Restore bound registers. ++ bndmov LRV_BND1_OFFSET(%rcx), %bnd1 ++# else ++ .byte 0x66,0x0f,0x1a,0x81;.long (LRV_BND0_OFFSET) ++ .byte 0x66,0x0f,0x1a,0x89;.long (LRV_BND1_OFFSET) ++# endif ++#endif ++ + fldt LRV_ST1_OFFSET(%rsp) + fldt LRV_ST0_OFFSET(%rsp) + +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S 2014-09-10 23:26:03.468045806 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S 2014-09-10 23:27:41.534851924 -0400 +@@ -24,6 +24,30 @@ + # error RTLD_SAVESPACE_SSE must be aligned to 32 bytes + #endif + ++/* Area on stack to save and restore registers used for parameter ++ passing when calling _dl_fixup. */ ++#ifdef __ILP32__ ++/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX. */ ++# define REGISTER_SAVE_AREA (8 * 7) ++# define REGISTER_SAVE_RAX 0 ++#else ++/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as BND0, ++ BND1, BND2, BND3. */ ++# define REGISTER_SAVE_AREA (8 * 7 + 16 * 4) ++/* Align bound register save area to 16 bytes. */ ++# define REGISTER_SAVE_BND0 0 ++# define REGISTER_SAVE_BND1 (REGISTER_SAVE_BND0 + 16) ++# define REGISTER_SAVE_BND2 (REGISTER_SAVE_BND1 + 16) ++# define REGISTER_SAVE_BND3 (REGISTER_SAVE_BND2 + 16) ++# define REGISTER_SAVE_RAX (REGISTER_SAVE_BND3 + 16) ++#endif ++#define REGISTER_SAVE_RCX (REGISTER_SAVE_RAX + 8) ++#define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8) ++#define REGISTER_SAVE_RSI (REGISTER_SAVE_RDX + 8) ++#define REGISTER_SAVE_RDI (REGISTER_SAVE_RSI + 8) ++#define REGISTER_SAVE_R8 (REGISTER_SAVE_RDI + 8) ++#define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8) ++ + .text + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function +@@ -31,28 +55,63 @@ + cfi_startproc + _dl_runtime_resolve: + cfi_adjust_cfa_offset(16) # Incorporate PLT +- subq $56,%rsp +- cfi_adjust_cfa_offset(56) +- movq %rax,(%rsp) # Preserve registers otherwise clobbered. +- movq %rcx, 8(%rsp) +- movq %rdx, 16(%rsp) +- movq %rsi, 24(%rsp) +- movq %rdi, 32(%rsp) +- movq %r8, 40(%rsp) +- movq %r9, 48(%rsp) +- movq 64(%rsp), %rsi # Copy args pushed by PLT in register. +- movq 56(%rsp), %rdi # %rdi: link_map, %rsi: reloc_index ++ subq $REGISTER_SAVE_AREA,%rsp ++ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) ++ # Preserve registers otherwise clobbered. ++ movq %rax, REGISTER_SAVE_RAX(%rsp) ++ movq %rcx, REGISTER_SAVE_RCX(%rsp) ++ movq %rdx, REGISTER_SAVE_RDX(%rsp) ++ movq %rsi, REGISTER_SAVE_RSI(%rsp) ++ movq %rdi, REGISTER_SAVE_RDI(%rsp) ++ movq %r8, REGISTER_SAVE_R8(%rsp) ++ movq %r9, REGISTER_SAVE_R9(%rsp) ++#ifndef __ILP32__ ++ # We also have to preserve bound registers. These are nops if ++ # Intel MPX isn't available or disabled. ++# ifdef HAVE_MPX_SUPPORT ++ bndmov %bnd0, REGISTER_SAVE_BND0(%rsp) ++ bndmov %bnd1, REGISTER_SAVE_BND1(%rsp) ++ bndmov %bnd2, REGISTER_SAVE_BND2(%rsp) ++ bndmov %bnd3, REGISTER_SAVE_BND3(%rsp) ++# else ++ .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0 ++ .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1 ++ .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2 ++ .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3 ++# endif ++#endif ++ # Copy args pushed by PLT in register. ++ # %rdi: link_map, %rsi: reloc_index ++ movq (REGISTER_SAVE_AREA + 8)(%rsp), %rsi ++ movq REGISTER_SAVE_AREA(%rsp), %rdi + call _dl_fixup # Call resolver. + movq %rax, %r11 # Save return value +- movq 48(%rsp), %r9 # Get register content back. +- movq 40(%rsp), %r8 +- movq 32(%rsp), %rdi +- movq 24(%rsp), %rsi +- movq 16(%rsp), %rdx +- movq 8(%rsp), %rcx +- movq (%rsp), %rax +- addq $72, %rsp # Adjust stack(PLT did 2 pushes) +- cfi_adjust_cfa_offset(-72) ++#ifndef __ILP32__ ++ # Restore bound registers. These are nops if Intel MPX isn't ++ # avaiable or disabled. ++# ifdef HAVE_MPX_SUPPORT ++ bndmov REGISTER_SAVE_BND3(%rsp), %bnd3 ++ bndmov REGISTER_SAVE_BND2(%rsp), %bnd2 ++ bndmov REGISTER_SAVE_BND1(%rsp), %bnd1 ++ bndmov REGISTER_SAVE_BND0(%rsp), %bnd0 ++# else ++ .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3 ++ .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2 ++ .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1 ++ .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0 ++# endif ++#endif ++ # Get register content back. ++ movq REGISTER_SAVE_R9(%rsp), %r9 ++ movq REGISTER_SAVE_R8(%rsp), %r8 ++ movq REGISTER_SAVE_RDI(%rsp), %rdi ++ movq REGISTER_SAVE_RSI(%rsp), %rsi ++ movq REGISTER_SAVE_RDX(%rsp), %rdx ++ movq REGISTER_SAVE_RCX(%rsp), %rcx ++ movq REGISTER_SAVE_RAX(%rsp), %rax ++ # Adjust stack(PLT did 2 pushes) ++ addq $(REGISTER_SAVE_AREA + 16), %rsp ++ cfi_adjust_cfa_offset(-(REGISTER_SAVE_AREA + 16)) + jmp *%r11 # Jump to function address. + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve +@@ -130,6 +189,20 @@ + movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp) + movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp) + ++# ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov %bnd0, (LR_BND_OFFSET)(%rsp) # Preserve bound ++ bndmov %bnd1, (LR_BND_OFFSET + BND_SIZE)(%rsp) # registers. Nops if ++ bndmov %bnd2, (LR_BND_OFFSET + BND_SIZE*2)(%rsp) # MPX not available ++ bndmov %bnd3, (LR_BND_OFFSET + BND_SIZE*3)(%rsp) # or disabled. ++# else ++ .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET) ++ .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE) ++ .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET + BND_SIZE*2) ++ .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3) ++# endif ++# endif ++ + # if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT + .data + L(have_avx): +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym +--- glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym 2014-09-10 23:26:03.468045806 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym 2014-09-10 23:27:41.535851922 -0400 +@@ -6,6 +6,7 @@ + XMM_SIZE sizeof (La_x86_64_xmm) + YMM_SIZE sizeof (La_x86_64_ymm) + ZMM_SIZE sizeof (La_x86_64_zmm) ++BND_SIZE sizeof (__int128) + + LR_SIZE sizeof (struct La_x86_64_regs) + LR_RDX_OFFSET offsetof (struct La_x86_64_regs, lr_rdx) +@@ -18,6 +19,9 @@ + LR_RSP_OFFSET offsetof (struct La_x86_64_regs, lr_rsp) + LR_XMM_OFFSET offsetof (struct La_x86_64_regs, lr_xmm) + LR_VECTOR_OFFSET offsetof (struct La_x86_64_regs, lr_vector) ++#ifndef __ILP32__ ++LR_BND_OFFSET offsetof (struct La_x86_64_regs, lr_bnd) ++#endif + + LRV_SIZE sizeof (struct La_x86_64_retval) + LRV_RAX_OFFSET offsetof (struct La_x86_64_retval, lrv_rax) +@@ -28,3 +32,7 @@ + LRV_ST1_OFFSET offsetof (struct La_x86_64_retval, lrv_st1) + LRV_VECTOR0_OFFSET offsetof (struct La_x86_64_retval, lrv_vector0) + LRV_VECTOR1_OFFSET offsetof (struct La_x86_64_retval, lrv_vector1) ++#ifndef __ILP32__ ++LRV_BND0_OFFSET offsetof (struct La_x86_64_retval, lrv_bnd0) ++LRV_BND1_OFFSET offsetof (struct La_x86_64_retval, lrv_bnd1) ++#endif diff --git a/SOURCES/glibc-rh1133812-1.patch b/SOURCES/glibc-rh1133812-1.patch new file mode 100644 index 00000000..0ca6f221 --- /dev/null +++ b/SOURCES/glibc-rh1133812-1.patch @@ -0,0 +1,207 @@ +commit a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8 +Author: Florian Weimer +Date: Tue Aug 26 19:38:59 2014 +0200 + + __gconv_translit_find: Disable function [BZ #17187] + + This functionality has never worked correctly, and the implementation + contained a security vulnerability (CVE-2014-5119). + +2014-08-21 Florian Weimer + + [BZ #17187] + * iconv/gconv_trans.c (struct known_trans, search_tree, lock, + trans_compare, open_translit, __gconv_translit_find): + Remove module loading code. + +diff --git glibc-2.17-c758a686/iconv/gconv_trans.c glibc-2.17-c758a686/iconv/gconv_trans.c +index 1e25854..d71c029 100644 +--- glibc-2.17-c758a686/iconv/gconv_trans.c ++++ glibc-2.17-c758a686/iconv/gconv_trans.c +@@ -238,181 +238,11 @@ __gconv_transliterate (struct __gconv_step *step, + return __GCONV_ILLEGAL_INPUT; + } + +- +-/* Structure to represent results of found (or not) transliteration +- modules. */ +-struct known_trans +-{ +- /* This structure must remain the first member. */ +- struct trans_struct info; +- +- char *fname; +- void *handle; +- int open_count; +-}; +- +- +-/* Tree with results of previous calls to __gconv_translit_find. */ +-static void *search_tree; +- +-/* We modify global data. */ +-__libc_lock_define_initialized (static, lock); +- +- +-/* Compare two transliteration entries. */ +-static int +-trans_compare (const void *p1, const void *p2) +-{ +- const struct known_trans *s1 = (const struct known_trans *) p1; +- const struct known_trans *s2 = (const struct known_trans *) p2; +- +- return strcmp (s1->info.name, s2->info.name); +-} +- +- +-/* Open (maybe reopen) the module named in the struct. Get the function +- and data structure pointers we need. */ +-static int +-open_translit (struct known_trans *trans) +-{ +- __gconv_trans_query_fct queryfct; +- +- trans->handle = __libc_dlopen (trans->fname); +- if (trans->handle == NULL) +- /* Not available. */ +- return 1; +- +- /* Find the required symbol. */ +- queryfct = __libc_dlsym (trans->handle, "gconv_trans_context"); +- if (queryfct == NULL) +- { +- /* We cannot live with that. */ +- close_and_out: +- __libc_dlclose (trans->handle); +- trans->handle = NULL; +- return 1; +- } +- +- /* Get the context. */ +- if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames) +- != 0) +- goto close_and_out; +- +- /* Of course we also have to have the actual function. */ +- trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans"); +- if (trans->info.trans_fct == NULL) +- goto close_and_out; +- +- /* Now the optional functions. */ +- trans->info.trans_init_fct = +- __libc_dlsym (trans->handle, "gconv_trans_init"); +- trans->info.trans_context_fct = +- __libc_dlsym (trans->handle, "gconv_trans_context"); +- trans->info.trans_end_fct = +- __libc_dlsym (trans->handle, "gconv_trans_end"); +- +- trans->open_count = 1; +- +- return 0; +-} +- +- + int + internal_function + __gconv_translit_find (struct trans_struct *trans) + { +- struct known_trans **found; +- const struct path_elem *runp; +- int res = 1; +- +- /* We have to have a name. */ +- assert (trans->name != NULL); +- +- /* Acquire the lock. */ +- __libc_lock_lock (lock); +- +- /* See whether we know this module already. */ +- found = __tfind (trans, &search_tree, trans_compare); +- if (found != NULL) +- { +- /* Is this module available? */ +- if ((*found)->handle != NULL) +- { +- /* Maybe we have to reopen the file. */ +- if ((*found)->handle != (void *) -1) +- /* The object is not unloaded. */ +- res = 0; +- else if (open_translit (*found) == 0) +- { +- /* Copy the data. */ +- *trans = (*found)->info; +- (*found)->open_count++; +- res = 0; +- } +- } +- } +- else +- { +- size_t name_len = strlen (trans->name) + 1; +- int need_so = 0; +- struct known_trans *newp; +- +- /* We have to continue looking for the module. */ +- if (__gconv_path_elem == NULL) +- __gconv_get_path (); +- +- /* See whether we have to append .so. */ +- if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0) +- need_so = 1; +- +- /* Create a new entry. */ +- newp = (struct known_trans *) malloc (sizeof (struct known_trans) +- + (__gconv_max_path_elem_len +- + name_len + 3) +- + name_len); +- if (newp != NULL) +- { +- char *cp; +- +- /* Clear the struct. */ +- memset (newp, '\0', sizeof (struct known_trans)); +- +- /* Store a copy of the module name. */ +- newp->info.name = cp = (char *) (newp + 1); +- cp = __mempcpy (cp, trans->name, name_len); +- +- newp->fname = cp; +- +- /* Search in all the directories. */ +- for (runp = __gconv_path_elem; runp->name != NULL; ++runp) +- { +- cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name), +- trans->name, name_len); +- if (need_so) +- memcpy (cp, ".so", sizeof (".so")); +- +- if (open_translit (newp) == 0) +- { +- /* We found a module. */ +- res = 0; +- break; +- } +- } +- +- if (res) +- newp->fname = NULL; +- +- /* In any case we'll add the entry to our search tree. */ +- if (__tsearch (newp, &search_tree, trans_compare) == NULL) +- { +- /* Yickes, this should not happen. Unload the object. */ +- res = 1; +- /* XXX unload here. */ +- } +- } +- } +- +- __libc_lock_unlock (lock); +- +- return res; ++ /* This function always fails. Transliteration module loading is ++ not implemented. */ ++ return 1; + } +-- +1.9.3 diff --git a/SOURCES/glibc-rh1133812-2.patch b/SOURCES/glibc-rh1133812-2.patch new file mode 100644 index 00000000..ba61a116 --- /dev/null +++ b/SOURCES/glibc-rh1133812-2.patch @@ -0,0 +1,631 @@ +commit 585367266923156ac6fb789939a923641ba5aaf4 +Author: Florian Weimer +Date: Wed May 28 14:05:03 2014 +0200 + + manual: Update the locale documentation + +commit 4e8f95a0df7c2300b830ec12c0ae1e161bc8a8a3 +Author: Florian Weimer +Date: Mon May 12 15:24:12 2014 +0200 + + _nl_find_locale: Improve handling of crafted locale names [BZ #17137] + + Prevent directory traversal in locale-related environment variables + (CVE-2014-0475). + +commit d183645616b0533b3acee28f1a95570bffbdf50f +Author: Florian Weimer +Date: Wed May 28 14:41:52 2014 +0200 + + setlocale: Use the heap for the copy of the locale argument + + This avoids alloca calls with potentially large arguments. + +diff -pruN glibc-2.17-c758a686/locale/findlocale.c glibc-2.17-c758a686/locale/findlocale.c +--- glibc-2.17-c758a686/locale/findlocale.c 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.17-c758a686/locale/findlocale.c 2014-08-26 16:14:50.403253778 +0530 +@@ -17,6 +17,7 @@ + . */ + + #include ++#include + #include + #include + #include +@@ -57,6 +58,45 @@ struct loaded_l10nfile *_nl_locale_file_ + + const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR; + ++/* Checks if the name is actually present, that is, not NULL and not ++ empty. */ ++static inline int ++name_present (const char *name) ++{ ++ return name != NULL && name[0] != '\0'; ++} ++ ++/* Checks that the locale name neither extremely long, nor contains a ++ ".." path component (to prevent directory traversal). */ ++static inline int ++valid_locale_name (const char *name) ++{ ++ /* Not set. */ ++ size_t namelen = strlen (name); ++ /* Name too long. The limit is arbitrary and prevents stack overflow ++ issues later. */ ++ if (__glibc_unlikely (namelen > 255)) ++ return 0; ++ /* Directory traversal attempt. */ ++ static const char slashdot[4] = {'/', '.', '.', '/'}; ++ if (__glibc_unlikely (memmem (name, namelen, ++ slashdot, sizeof (slashdot)) != NULL)) ++ return 0; ++ if (namelen == 2 && __glibc_unlikely (name[0] == '.' && name [1] == '.')) ++ return 0; ++ if (namelen >= 3 ++ && __glibc_unlikely (((name[0] == '.' ++ && name[1] == '.' ++ && name[2] == '/') ++ || (name[namelen - 3] == '/' ++ && name[namelen - 2] == '.' ++ && name[namelen - 1] == '.')))) ++ return 0; ++ /* If there is a slash in the name, it must start with one. */ ++ if (__glibc_unlikely (memchr (name, '/', namelen) != NULL) && name[0] != '/') ++ return 0; ++ return 1; ++} + + struct __locale_data * + internal_function +@@ -65,7 +105,7 @@ _nl_find_locale (const char *locale_path + { + int mask; + /* Name of the locale for this category. */ +- char *loc_name; ++ char *loc_name = (char *) *name; + const char *language; + const char *modifier; + const char *territory; +@@ -73,31 +113,39 @@ _nl_find_locale (const char *locale_path + const char *normalized_codeset; + struct loaded_l10nfile *locale_file; + +- if ((*name)[0] == '\0') ++ if (loc_name[0] == '\0') + { + /* The user decides which locale to use by setting environment + variables. */ +- *name = getenv ("LC_ALL"); +- if (*name == NULL || (*name)[0] == '\0') +- *name = getenv (_nl_category_names.str ++ loc_name = getenv ("LC_ALL"); ++ if (!name_present (loc_name)) ++ loc_name = getenv (_nl_category_names.str + + _nl_category_name_idxs[category]); +- if (*name == NULL || (*name)[0] == '\0') +- *name = getenv ("LANG"); ++ if (!name_present (loc_name)) ++ loc_name = getenv ("LANG"); ++ if (!name_present (loc_name)) ++ loc_name = (char *) _nl_C_name; + } + +- if (*name == NULL || (*name)[0] == '\0' +- || (__builtin_expect (__libc_enable_secure, 0) +- && strchr (*name, '/') != NULL)) +- *name = (char *) _nl_C_name; ++ /* We used to fall back to the C locale if the name contains a slash ++ character '/', but we now check for directory traversal in ++ valid_locale_name, so this is no longer necessary. */ + +- if (__builtin_expect (strcmp (*name, _nl_C_name), 1) == 0 +- || __builtin_expect (strcmp (*name, _nl_POSIX_name), 1) == 0) ++ if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0 ++ || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0) + { + /* We need not load anything. The needed data is contained in + the library itself. */ + *name = (char *) _nl_C_name; + return _nl_C[category]; + } ++ else if (!valid_locale_name (loc_name)) ++ { ++ __set_errno (EINVAL); ++ return NULL; ++ } ++ ++ *name = loc_name; + + /* We really have to load some data. First we try the archive, + but only if there was no LOCPATH environment variable specified. */ +diff -pruN glibc-2.17-c758a686/locale/setlocale.c glibc-2.17-c758a686/locale/setlocale.c +--- glibc-2.17-c758a686/locale/setlocale.c 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.17-c758a686/locale/setlocale.c 2014-08-26 16:14:50.401253764 +0530 +@@ -272,6 +272,8 @@ setlocale (int category, const char *loc + of entries of the form `CATEGORY=VALUE'. */ + const char *newnames[__LC_LAST]; + struct __locale_data *newdata[__LC_LAST]; ++ /* Copy of the locale argument, for in-place splitting. */ ++ char *locale_copy = NULL; + + /* Set all name pointers to the argument name. */ + for (category = 0; category < __LC_LAST; ++category) +@@ -281,7 +283,13 @@ setlocale (int category, const char *loc + if (__builtin_expect (strchr (locale, ';') != NULL, 0)) + { + /* This is a composite name. Make a copy and split it up. */ +- char *np = strdupa (locale); ++ locale_copy = strdup (locale); ++ if (__glibc_unlikely (locale_copy == NULL)) ++ { ++ __libc_rwlock_unlock (__libc_setlocale_lock); ++ return NULL; ++ } ++ char *np = locale_copy; + char *cp; + int cnt; + +@@ -299,6 +307,7 @@ setlocale (int category, const char *loc + { + error_return: + __libc_rwlock_unlock (__libc_setlocale_lock); ++ free (locale_copy); + + /* Bogus category name. */ + ERROR_RETURN; +@@ -391,8 +400,9 @@ setlocale (int category, const char *loc + /* Critical section left. */ + __libc_rwlock_unlock (__libc_setlocale_lock); + +- /* Free the resources (the locale path variable). */ ++ /* Free the resources. */ + free (locale_path); ++ free (locale_copy); + + return composite; + } +diff -pruN glibc-2.17-c758a686/localedata/Makefile glibc-2.17-c758a686/localedata/Makefile +--- glibc-2.17-c758a686/localedata/Makefile 2014-08-26 16:15:22.656474571 +0530 ++++ glibc-2.17-c758a686/localedata/Makefile 2014-08-26 16:14:50.403253778 +0530 +@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_is + + tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \ + tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \ +- tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 ++ tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3 + ifeq (yes,$(build-shared)) + ifneq (no,$(PERL)) + tests: $(objpfx)mtrace-tst-leaks +diff -pruN glibc-2.17-c758a686/localedata/tst-setlocale3.c glibc-2.17-c758a686/localedata/tst-setlocale3.c +--- glibc-2.17-c758a686/localedata/tst-setlocale3.c 1970-01-01 05:30:00.000000000 +0530 ++++ glibc-2.17-c758a686/localedata/tst-setlocale3.c 2014-08-26 16:14:50.403253778 +0530 +@@ -0,0 +1,203 @@ ++/* Regression test for setlocale invalid environment variable handling. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* The result of setlocale may be overwritten by subsequent calls, so ++ this wrapper makes a copy. */ ++static char * ++setlocale_copy (int category, const char *locale) ++{ ++ const char *result = setlocale (category, locale); ++ if (result == NULL) ++ return NULL; ++ return strdup (result); ++} ++ ++static char *de_locale; ++ ++static void ++setlocale_fail (const char *envstring) ++{ ++ setenv ("LC_CTYPE", envstring, 1); ++ if (setlocale (LC_CTYPE, "") != NULL) ++ { ++ printf ("unexpected setlocale success for \"%s\" locale\n", envstring); ++ exit (1); ++ } ++ const char *newloc = setlocale (LC_CTYPE, NULL); ++ if (strcmp (newloc, de_locale) != 0) ++ { ++ printf ("failed setlocale call \"%s\" changed locale to \"%s\"\n", ++ envstring, newloc); ++ exit (1); ++ } ++} ++ ++static void ++setlocale_success (const char *envstring) ++{ ++ setenv ("LC_CTYPE", envstring, 1); ++ char *newloc = setlocale_copy (LC_CTYPE, ""); ++ if (newloc == NULL) ++ { ++ printf ("setlocale for \"%s\": %m\n", envstring); ++ exit (1); ++ } ++ if (strcmp (newloc, de_locale) == 0) ++ { ++ printf ("setlocale with LC_CTYPE=\"%s\" left locale at \"%s\"\n", ++ envstring, de_locale); ++ exit (1); ++ } ++ if (setlocale (LC_CTYPE, de_locale) == NULL) ++ { ++ printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n", ++ de_locale, envstring); ++ exit (1); ++ } ++ char *newloc2 = setlocale_copy (LC_CTYPE, newloc); ++ if (newloc2 == NULL) ++ { ++ printf ("restoring locale \"%s\" following \"%s\": %m\n", ++ newloc, envstring); ++ exit (1); ++ } ++ if (strcmp (newloc, newloc2) != 0) ++ { ++ printf ("representation of locale \"%s\" changed from \"%s\" to \"%s\"", ++ envstring, newloc, newloc2); ++ exit (1); ++ } ++ free (newloc); ++ free (newloc2); ++ ++ if (setlocale (LC_CTYPE, de_locale) == NULL) ++ { ++ printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n", ++ de_locale, envstring); ++ exit (1); ++ } ++} ++ ++/* Checks that a known-good locale still works if LC_ALL contains a ++ value which should be ignored. */ ++static void ++setlocale_ignore (const char *to_ignore) ++{ ++ const char *fr_locale = "fr_FR.UTF-8"; ++ setenv ("LC_CTYPE", fr_locale, 1); ++ char *expected_locale = setlocale_copy (LC_CTYPE, ""); ++ if (expected_locale == NULL) ++ { ++ printf ("setlocale with LC_CTYPE=\"%s\" failed: %m\n", fr_locale); ++ exit (1); ++ } ++ if (setlocale (LC_CTYPE, de_locale) == NULL) ++ { ++ printf ("failed to restore locale: %m\n"); ++ exit (1); ++ } ++ unsetenv ("LC_CTYPE"); ++ ++ setenv ("LC_ALL", to_ignore, 1); ++ setenv ("LC_CTYPE", fr_locale, 1); ++ const char *actual_locale = setlocale (LC_CTYPE, ""); ++ if (actual_locale == NULL) ++ { ++ printf ("setlocale with LC_ALL, LC_CTYPE=\"%s\" failed: %m\n", ++ fr_locale); ++ exit (1); ++ } ++ if (strcmp (actual_locale, expected_locale) != 0) ++ { ++ printf ("setlocale under LC_ALL failed: got \"%s\", expected \"%s\"\n", ++ actual_locale, expected_locale); ++ exit (1); ++ } ++ unsetenv ("LC_CTYPE"); ++ setlocale_success (fr_locale); ++ unsetenv ("LC_ALL"); ++ free (expected_locale); ++} ++ ++static int ++do_test (void) ++{ ++ /* The glibc test harness sets this environment variable ++ uncondionally. */ ++ unsetenv ("LC_ALL"); ++ ++ de_locale = setlocale_copy (LC_CTYPE, "de_DE.UTF-8"); ++ if (de_locale == NULL) ++ { ++ printf ("setlocale (LC_CTYPE, \"de_DE.UTF-8\"): %m\n"); ++ return 1; ++ } ++ setlocale_success ("C"); ++ setlocale_success ("en_US.UTF-8"); ++ setlocale_success ("/en_US.UTF-8"); ++ setlocale_success ("//en_US.UTF-8"); ++ setlocale_ignore (""); ++ ++ setlocale_fail ("does-not-exist"); ++ setlocale_fail ("/"); ++ setlocale_fail ("/../localedata/en_US.UTF-8"); ++ setlocale_fail ("en_US.UTF-8/"); ++ setlocale_fail ("en_US.UTF-8/.."); ++ setlocale_fail ("en_US.UTF-8/../en_US.UTF-8"); ++ setlocale_fail ("../localedata/en_US.UTF-8"); ++ { ++ size_t large_length = 1024; ++ char *large_name = malloc (large_length + 1); ++ if (large_name == NULL) ++ { ++ puts ("malloc failure"); ++ return 1; ++ } ++ memset (large_name, '/', large_length); ++ const char *suffix = "en_US.UTF-8"; ++ strcpy (large_name + large_length - strlen (suffix), suffix); ++ setlocale_fail (large_name); ++ free (large_name); ++ } ++ { ++ size_t huge_length = 64 * 1024 * 1024; ++ char *huge_name = malloc (huge_length + 1); ++ if (huge_name == NULL) ++ { ++ puts ("malloc failure"); ++ return 1; ++ } ++ memset (huge_name, 'X', huge_length); ++ huge_name[huge_length] = '\0'; ++ /* Construct a composite locale specification. */ ++ const char *prefix = "LC_CTYPE=de_DE.UTF-8;LC_TIME="; ++ memcpy (huge_name, prefix, strlen (prefix)); ++ setlocale_fail (huge_name); ++ free (huge_name); ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -pruN glibc-2.17-c758a686/manual/locale.texi glibc-2.17-c758a686/manual/locale.texi +--- glibc-2.17-c758a686/manual/locale.texi 2013-08-11 04:22:55.000000000 +0530 ++++ glibc-2.17-c758a686/manual/locale.texi 2014-08-26 16:14:50.404253785 +0530 +@@ -29,6 +29,7 @@ will follow the conventions preferred by + * Setting the Locale:: How a program specifies the locale + with library functions. + * Standard Locales:: Locale names available on all systems. ++* Locale Names:: Format of system-specific locale names. + * Locale Information:: How to access the information for the locale. + * Formatting Numbers:: A dedicated function to format numbers. + * Yes-or-No Questions:: Check a Response against the locale. +@@ -99,14 +100,16 @@ locale named @samp{espana-castellano} to + most of Spain. + + The set of locales supported depends on the operating system you are +-using, and so do their names. We can't make any promises about what +-locales will exist, except for one standard locale called @samp{C} or +-@samp{POSIX}. Later we will describe how to construct locales. +-@comment (@pxref{Building Locale Files}). ++using, and so do their names, except that the standard locale called ++@samp{C} or @samp{POSIX} always exist. @xref{Locale Names}. ++ ++In order to force the system to always use the default locale, the ++user can set the @code{LC_ALL} environment variable to @samp{C}. + + @cindex combining locales +-A user also has the option of specifying different locales for different +-purposes---in effect, choosing a mixture of multiple locales. ++A user also has the option of specifying different locales for ++different purposes---in effect, choosing a mixture of multiple ++locales. @xref{Locale Categories}. + + For example, the user might specify the locale @samp{espana-castellano} + for most purposes, but specify the locale @samp{usa-english} for +@@ -120,7 +123,7 @@ which locales apply. However, the user + for a particular subset of those purposes. + + @node Locale Categories, Setting the Locale, Choosing Locale, Locales +-@section Categories of Activities that Locales Affect ++@section Locale Categories + @cindex categories for locales + @cindex locale categories + +@@ -128,7 +131,11 @@ The purposes that locales serve are grou + that a user or a program can choose the locale for each category + independently. Here is a table of categories; each name is both an + environment variable that a user can set, and a macro name that you can +-use as an argument to @code{setlocale}. ++use as the first argument to @code{setlocale}. ++ ++The contents of the environment variable (or the string in the second ++argument to @code{setlocale}) has to be a valid locale name. ++@xref{Locale Names}. + + @vtable @code + @comment locale.h +@@ -172,7 +179,7 @@ for affirmative and negative responses. + @comment locale.h + @comment ISO + @item LC_ALL +-This is not an environment variable; it is only a macro that you can use ++This is not a category; it is only a macro that you can use + with @code{setlocale} to set a single locale for all purposes. Setting + this environment variable overwrites all selections by the other + @code{LC_*} variables or @code{LANG}. +@@ -225,13 +232,7 @@ The symbols in this section are defined + @comment ISO + @deftypefun {char *} setlocale (int @var{category}, const char *@var{locale}) + The function @code{setlocale} sets the current locale for category +-@var{category} to @var{locale}. A list of all the locales the system +-provides can be created by running +- +-@pindex locale +-@smallexample +- locale -a +-@end smallexample ++@var{category} to @var{locale}. + + If @var{category} is @code{LC_ALL}, this specifies the locale for all + purposes. The other possible values of @var{category} specify an +@@ -256,10 +257,9 @@ is passed in as @var{locale} parameter. + + When you read the current locale for category @code{LC_ALL}, the value + encodes the entire combination of selected locales for all categories. +-In this case, the value is not just a single locale name. In fact, we +-don't make any promises about what it looks like. But if you specify +-the same ``locale name'' with @code{LC_ALL} in a subsequent call to +-@code{setlocale}, it restores the same combination of locale selections. ++If you specify the same ``locale name'' with @code{LC_ALL} in a ++subsequent call to @code{setlocale}, it restores the same combination ++of locale selections. + + To be sure you can use the returned string encoding the currently selected + locale at a later time, you must make a copy of the string. It is not +@@ -275,20 +275,15 @@ for @var{category}. + If a nonempty string is given for @var{locale}, then the locale of that + name is used if possible. + ++The effective locale name (either the second argument to ++@code{setlocale}, or if the argument is an empty string, the name ++obtained from the process environment) must be valid locale name. ++@xref{Locale Names}. ++ + If you specify an invalid locale name, @code{setlocale} returns a null + pointer and leaves the current locale unchanged. + @end deftypefun + +-The path used for finding locale data can be set using the +-@code{LOCPATH} environment variable. The default path for finding +-locale data is system specific. It is computed from the value given +-as the prefix while configuring the C library. This value normally is +-@file{/usr} or @file{/}. For the former the complete path is: +- +-@smallexample +-/usr/lib/locale +-@end smallexample +- + Here is an example showing how you might use @code{setlocale} to + temporarily switch to a new locale. + +@@ -328,7 +323,7 @@ locale categories, and future versions o + portability, assume that any symbol beginning with @samp{LC_} might be + defined in @file{locale.h}. + +-@node Standard Locales, Locale Information, Setting the Locale, Locales ++@node Standard Locales, Locale Names, Setting the Locale, Locales + @section Standard Locales + + The only locale names you can count on finding on all operating systems +@@ -362,7 +357,94 @@ with the environment, rather than trying + locale explicitly by name. Remember, different machines might have + different sets of locales installed. + +-@node Locale Information, Formatting Numbers, Standard Locales, Locales ++@node Locale Names, Locale Information, Standard Locales, Locales ++@section Locale Names ++ ++The following command prints a list of locales supported by the ++system: ++ ++@pindex locale ++@smallexample ++ locale -a ++@end smallexample ++ ++@strong{Portability Note:} With the notable exception of the standard ++locale names @samp{C} and @samp{POSIX}, locale names are ++system-specific. ++ ++Most locale names follow XPG syntax and consist of up to four parts: ++ ++@smallexample ++@var{language}[_@var{territory}[.@var{codeset}]][@@@var{modifier}] ++@end smallexample ++ ++Beside the first part, all of them are allowed to be missing. If the ++full specified locale is not found, less specific ones are looked for. ++The various parts will be stripped off, in the following order: ++ ++@enumerate ++@item ++codeset ++@item ++normalized codeset ++@item ++territory ++@item ++modifier ++@end enumerate ++ ++For example, the locale name @samp{de_AT.iso885915@@euro} denotes a ++German-language locale for use in Austria, using the ISO-8859-15 ++(Latin-9) character set, and with the Euro as the currency symbol. ++ ++In addition to locale names which follow XPG syntax, systems may ++provide aliases such as @samp{german}. Both categories of names must ++not contain the slash character @samp{/}. ++ ++If the locale name starts with a slash @samp{/}, it is treated as a ++path relative to the configured locale directories; see @code{LOCPATH} ++below. The specified path must not contain a component @samp{..}, or ++the name is invalid, and @code{setlocale} will fail. ++ ++@strong{Portability Note:} POSIX suggests that if a locale name starts ++with a slash @samp{/}, it is resolved as an absolute path. However, ++@theglibc{} treats it as a relative path under the directories listed ++in @code{LOCPATH} (or the default locale directory if @code{LOCPATH} ++is unset). ++ ++Locale names which are longer than an implementation-defined limit are ++invalid and cause @code{setlocale} to fail. ++ ++As a special case, locale names used with @code{LC_ALL} can combine ++several locales, reflecting different locale settings for different ++categories. For example, you might want to use a U.S. locale with ISO ++A4 paper format, so you set @code{LANG} to @samp{en_US.UTF-8}, and ++@code{LC_PAPER} to @samp{de_DE.UTF-8}. In this case, the ++@code{LC_ALL}-style combined locale name is ++ ++@smallexample ++LC_CTYPE=en_US.UTF-8;LC_TIME=en_US.UTF-8;LC_PAPER=de_DE.UTF-8;@dots{} ++@end smallexample ++ ++followed by other category settings not shown here. ++ ++@vindex LOCPATH ++The path used for finding locale data can be set using the ++@code{LOCPATH} environment variable. This variable lists the ++directories in which to search for locale definitions, separated by a ++colon @samp{:}. ++ ++The default path for finding locale data is system specific. A typical ++value for the @code{LOCPATH} default is: ++ ++@smallexample ++/usr/share/locale ++@end smallexample ++ ++The value of @code{LOCPATH} is ignored by privileged programs for ++security reasons, and only the default directory is used. ++ ++@node Locale Information, Formatting Numbers, Locale Names, Locales + @section Accessing Locale Information + + There are several ways to access locale information. The simplest diff --git a/SOURCES/glibc-rh1133812-3.patch b/SOURCES/glibc-rh1133812-3.patch new file mode 100644 index 00000000..985a0087 --- /dev/null +++ b/SOURCES/glibc-rh1133812-3.patch @@ -0,0 +1,474 @@ +commit 2bf1804182cc4bd671193587c8d5e3de45a9618e +Author: Joseph Myers +Date: Wed Jun 4 23:37:25 2014 +0000 + + Include LOCPATH in default test environment. + + Tests run using the default $(make-test-out) automatically get + GCONV_PATH and LC_ALL set, whether or not those environment variables + are actually needed for the individual test. However, they do not get + LOCPATH set, meaning that a large number of tests have -ENV settings + just to set LOCPATH. + + This patch moves LOCPATH into the default environment used for all + tests, on the principle that like GCONV_PATH any settings needed to + use files associated with the newly built library, rather than any old + installed files, are appropriate to use by default. + + A further motivation is that various tests using .sh files also set + some combination of LC_ALL, GCONV_PATH and LOCPATH. Preferably .sh + files should also use the default environment with any additions + required for the individual test. Now, it was suggested in + that + various Makefile variables used in testing should be derived by + composing the -before-env and -after-env variables used when explicit + environment settings are required. With such a change, it's also + natural for those variables to include the default settings (via some + intermediate makefile variable also used in make-test-out). + + Because some .sh files only set variables that correspond to the + default settings, or a subset thereof, and this applies to more of the + .sh files once LOCPATH is in the default settings, doing so reduces + the size of a revised version of + : scripts + only needing the (expanded) default settings will not need to receive + the separate -before-env and -after-env variables, only the single + variable they do at present. So moving LOCPATH into the default + settings can reduce churn caused by subsequent patches. + + Tested x86_64 and x86. + + * Rules (make-test-out): Include + LOCPATH=$(common-objpfx)localedata in default environment. + * debug/Makefile (tst-chk1-ENV): Remove variable. + (tst-chk2-ENV): Likewise. + (tst-chk3-ENV): Likewise. + (tst-chk4-ENV): Likewise. + (tst-chk5-ENV): Likewise. + (tst-chk6-ENV): Likewise. + (tst-lfschk1-ENV): Likewise. + (tst-lfschk2-ENV): Likewise. + (tst-lfschk3-ENV): Likewise. + (tst-lfschk4-ENV): Likewise. + (tst-lfschk5-ENV): Likewise. + (tst-lfschk6-ENV): Likewise. + * iconvdata/Makefile (bug-iconv6-ENV): Likewise. + (tst-iconv7-ENV): Likewise. + * intl/Makefile (LOCPATH-ENV): Likewise. + (tst-codeset-ENV): Likewise. + (tst-gettext3-ENV): Likewise. + (tst-gettext5-ENV): Likewise. + * libio/Makefile (tst-widetext-ENV): Don't set LOCPATH. + (tst-fopenloc-ENV): Likewise. + (tst-fgetws-ENV): Remove variable. + (tst-ungetwc1-ENV): Likewise. + (tst-ungetwc2-ENV): Likewise. + (bug-ungetwc2-ENV): Likewise. + (tst-swscanf-ENV): Likewise. + (bug-ftell-ENV): Likewise. + (tst-fgetwc-ENV): Likewise. + (tst-fseek-ENV): Likewise. + (tst-ftell-partial-wide-ENV): Likewise. + (tst-ftell-active-handler-ENV): Likewise. + (tst-ftell-append-ENV): Likewise. + * posix/Makefile (tst-fnmatch-ENV): Likewise. + (tst-regexloc-ENV): Likewise. + (bug-regex1-ENV): Likewise. + (tst-regex-ENV): Likewise. + (tst-regex2-ENV): Likewise. + (bug-regex5-ENV): Likewise. + (bug-regex6-ENV): Likewise. + (bug-regex17-ENV): Likewise. + (bug-regex18-ENV): Likewise. + (bug-regex19-ENV): Likewise. + (bug-regex20-ENV): Likewise. + (bug-regex22-ENV): Likewise. + (bug-regex23-ENV): Likewise. + (bug-regex25-ENV): Likewise. + (bug-regex26-ENV): Likewise. + (bug-regex30-ENV): Likewise. + (bug-regex32-ENV): Likewise. + (bug-regex33-ENV): Likewise. + (bug-regex34-ENV): Likewise. + (bug-regex35-ENV): Likewise. + (tst-rxspencer-ENV): Likewise. + (tst-rxspencer-no-utf8-ENV): Likewise. + * stdio-common/Makefile (tst-sprintf-ENV): Likewise. + (tst-sscanf-ENV): Likewise. + (tst-swprintf-ENV): Likewise. + (tst-swscanf-ENV): Likewise. + (test-vfprintf-ENV): Likewise. + (scanf13-ENV): Likewise. + (bug14-ENV): Likewise. + (tst-grouping-ENV): Likewise. + * stdlib/Makefile (tst-strtod-ENV): Likewise. + (tst-strtod3-ENV): Likewise. + (tst-strtod4-ENV): Likewise. + (tst-strtod5-ENV): Likewise. + (testmb2-ENV): Likewise./ + * string/Makefile (tst-strxfrm-ENV): Likewise. + (tst-strxfrm2-ENV): Likewise. + (bug-strcoll1-ENV): Likewise. + (test-strcasecmp-ENV): Likewise. + (test-strncasecmp-ENV): Likewise. + * time/Makefile (tst-strptime-ENV): Likewise. + (tst-ftime_l-ENV): Likewise. + * wcsmbs/Makefile (tst-btowc-ENV): Likewise. + (tst-mbrtowc-ENV): Likewise. + (tst-wcrtomb-ENV): Likewise. + (tst-mbrtowc2-ENV): Likewise. + (tst-c16c32-1-ENV): Likewise. + (tst-mbsnrtowcs-ENV): Likewise. + + localedata/ChangeLog: + * Makefile (TEST_MBWC_ENV): Remove variable. + (tst_iswalnum-ENV): Likewise. + (tst_iswalpha-ENV): Likewise. + (tst_iswcntrl-ENV): Likewise. + (tst_iswctype-ENV): Likewise. + (tst_iswdigit-ENV): Likewise. + (tst_iswgraph-ENV): Likewise. + (tst_iswlower-ENV): Likewise. + (tst_iswprint-ENV): Likewise. + (tst_iswpunct-ENV): Likewise. + (tst_iswspace-ENV): Likewise. + (tst_iswupper-ENV): Likewise. + (tst_iswxdigit-ENV): Likewise. + (tst_mblen-ENV): Likewise. + (tst_mbrlen-ENV): Likewise. + (tst_mbrtowc-ENV): Likewise. + (tst_mbsrtowcs-ENV): Likewise. + (tst_mbstowcs-ENV): Likewise. + (tst_mbtowc-ENV): Likewise. + (tst_strcoll-ENV): Likewise. + (tst_strfmon-ENV): Likewise. + (tst_strxfrm-ENV): Likewise. + (tst_swscanf-ENV): Likewise. + (tst_towctrans-ENV): Likewise. + (tst_towlower-ENV): Likewise. + (tst_towupper-ENV): Likewise. + (tst_wcrtomb-ENV): Likewise. + (tst_wcscat-ENV): Likewise. + (tst_wcschr-ENV): Likewise. + (tst_wcscmp-ENV): Likewise. + (tst_wcscoll-ENV): Likewise. + (tst_wcscpy-ENV): Likewise. + (tst_wcscspn-ENV): Likewise. + (tst_wcslen-ENV): Likewise. + (tst_wcsncat-ENV): Likewise. + (tst_wcsncmp-ENV): Likewise. + (tst_wcsncpy-ENV): Likewise. + (tst_wcspbrk-ENV): Likewise. + (tst_wcsrtombs-ENV): Likewise. + (tst_wcsspn-ENV): Likewise. + (tst_wcsstr-ENV): Likewise. + (tst_wcstod-ENV): Likewise. + (tst_wcstok-ENV): Likewise. + (tst_wcstombs-ENV): Likewise. + (tst_wcswidth-ENV): Likewise. + (tst_wcsxfrm-ENV): Likewise. + (tst_wctob-ENV): Likewise. + (tst_wctomb-ENV): Likewise. + (tst_wctrans-ENV): Likewise. + (tst_wctype-ENV): Likewise. + (tst_wcwidth-ENV): Likewise. + (tst-digits-ENV): Likewise. + (tst-mbswcs6-ENV): Likewise. + (tst-xlocale1-ENV): Likewise. + (tst-xlocale2-ENV): Likewise. + (tst-strfmon1-ENV): Likewise. + (tst-strptime-ENV): Likewise. + (tst-setlocale-ENV): Don't set LOCPATH. + (bug-iconv-trans-ENV): Remove variable. + (tst-sscanf-ENV): Likewise. + (tst-leaks-ENV): Don't set LOCPATH. + (bug-setlocale1-ENV): Remove variable. + (bug-setlocale1-static-ENV): Likewise. + (tst-setlocale2-ENV): Likewise. + +diff --git glibc-2.17-c758a686/Rules glibc-2.17-c758a686/Rules +index feb304d..9f1a445 100644 +--- glibc-2.17-c758a686/Rules ++++ glibc-2.17-c758a686/Rules +@@ -191,7 +191,8 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" "" + # from the test programs and whatever input files are present. + + make-test-out = $(test-wrapper-env) \ +- GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \ ++ GCONV_PATH=$(common-objpfx)iconvdata \ ++ LOCPATH=$(common-objpfx)localedata LC_ALL=C \ + $($*-ENV) $(host-built-program-cmd) $($*-ARGS) + $(objpfx)%-bp.out: %.input $(objpfx)%-bp + $(make-test-out) > $@ < $(word 1,$^) +diff --git glibc-2.17-c758a686/debug/Makefile glibc-2.17-c758a686/debug/Makefile +index b599a22..c284c51 100644 +--- glibc-2.17-c758a686/debug/Makefile ++++ glibc-2.17-c758a686/debug/Makefile +@@ -109,18 +109,6 @@ CFLAGS-tst-lfschk3.c = -Wno-format + CFLAGS-tst-lfschk4.cc = -Wno-format + CFLAGS-tst-lfschk5.cc = -Wno-format + CFLAGS-tst-lfschk6.cc = -Wno-format +-tst-chk1-ENV = LOCPATH=$(common-objpfx)localedata +-tst-chk2-ENV = LOCPATH=$(common-objpfx)localedata +-tst-chk3-ENV = LOCPATH=$(common-objpfx)localedata +-tst-chk4-ENV = LOCPATH=$(common-objpfx)localedata +-tst-chk5-ENV = LOCPATH=$(common-objpfx)localedata +-tst-chk6-ENV = LOCPATH=$(common-objpfx)localedata +-tst-lfschk1-ENV = LOCPATH=$(common-objpfx)localedata +-tst-lfschk2-ENV = LOCPATH=$(common-objpfx)localedata +-tst-lfschk3-ENV = LOCPATH=$(common-objpfx)localedata +-tst-lfschk4-ENV = LOCPATH=$(common-objpfx)localedata +-tst-lfschk5-ENV = LOCPATH=$(common-objpfx)localedata +-tst-lfschk6-ENV = LOCPATH=$(common-objpfx)localedata + LDLIBS-tst-chk4 = -lstdc++ + LDLIBS-tst-chk5 = -lstdc++ + LDLIBS-tst-chk6 = -lstdc++ +diff --git glibc-2.17-c758a686/iconvdata/Makefile glibc-2.17-c758a686/iconvdata/Makefile +index 074d330..d98b6bd 100644 +--- glibc-2.17-c758a686/iconvdata/Makefile ++++ glibc-2.17-c758a686/iconvdata/Makefile +@@ -73,9 +73,6 @@ tests += bug-iconv3 + endif + + test-srcs := tst-table-from tst-table-to +- +-bug-iconv6-ENV = LOCPATH=$(common-objpfx)localedata +-tst-iconv7-ENV = LOCPATH=$(common-objpfx)localedata + endif + + # No code here is in libc.so. +diff --git glibc-2.17-c758a686/intl/Makefile glibc-2.17-c758a686/intl/Makefile +index f11449d..10051f6 100644 +--- glibc-2.17-c758a686/intl/Makefile ++++ glibc-2.17-c758a686/intl/Makefile +@@ -118,11 +118,6 @@ CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(objpfx)\" + CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\" + CFLAGS-tst-gettext6.c = -DOBJPFX=\"$(objpfx)\" + +-LOCPATH-ENV = LOCPATH=$(common-objpfx)localedata +-tst-codeset-ENV = $(LOCPATH-ENV) +-tst-gettext3-ENV = $(LOCPATH-ENV) +-tst-gettext5-ENV = $(LOCPATH-ENV) +- + ifeq ($(have-thread-library),yes) + ifeq (yes,$(build-shared)) + $(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library) +diff --git glibc-2.17-c758a686/libio/Makefile glibc-2.17-c758a686/libio/Makefile +index b324ccc..4552360 100644 +--- glibc-2.17-c758a686/libio/Makefile ++++ glibc-2.17-c758a686/libio/Makefile +@@ -148,17 +148,8 @@ CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\" + + tst_wprintf2-ARGS = "Some Text" + +-tst-widetext-ENV = LOCPATH=$(common-objpfx)localedata LANGUAGE=C +-tst-fopenloc-ENV = LOCPATH=$(common-objpfx)localedata \ +- MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace +-tst-fgetws-ENV = LOCPATH=$(common-objpfx)localedata +-tst-ungetwc1-ENV = LOCPATH=$(common-objpfx)localedata +-tst-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata +-bug-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata +-tst-swscanf-ENV = LOCPATH=$(common-objpfx)localedata +-bug-ftell-ENV = LOCPATH=$(common-objpfx)localedata +-tst-fgetwc-ENV = LOCPATH=$(common-objpfx)localedata +-tst-fseek-ENV = LOCPATH=$(common-objpfx)localedata ++tst-widetext-ENV = LANGUAGE=C ++tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace + + generated = tst-fopenloc.mtrace tst-fopenloc.check + +diff --git glibc-2.17-c758a686/localedata/Makefile glibc-2.17-c758a686/localedata/Makefile +index d7ab445..20da00c 100644 +--- glibc-2.17-c758a686/localedata/Makefile ++++ glibc-2.17-c758a686/localedata/Makefile +@@ -215,79 +215,13 @@ + $(addprefix --prefix=,$(install_root)) $$locale; \ + echo ' done'; \ + +-# The mbwc-tests need some environment setup to find the locale data files +-TEST_MBWC_ENV:= LOCPATH=$(common-objpfx)localedata +-tst_iswalnum-ENV = $(TEST_MBWC_ENV) +-tst_iswalpha-ENV = $(TEST_MBWC_ENV) +-tst_iswcntrl-ENV = $(TEST_MBWC_ENV) +-tst_iswctype-ENV = $(TEST_MBWC_ENV) +-tst_iswdigit-ENV = $(TEST_MBWC_ENV) +-tst_iswgraph-ENV = $(TEST_MBWC_ENV) +-tst_iswlower-ENV = $(TEST_MBWC_ENV) +-tst_iswprint-ENV = $(TEST_MBWC_ENV) +-tst_iswpunct-ENV = $(TEST_MBWC_ENV) +-tst_iswspace-ENV = $(TEST_MBWC_ENV) +-tst_iswupper-ENV = $(TEST_MBWC_ENV) +-tst_iswxdigit-ENV = $(TEST_MBWC_ENV) +-tst_mblen-ENV = $(TEST_MBWC_ENV) +-tst_mbrlen-ENV = $(TEST_MBWC_ENV) +-tst_mbrtowc-ENV = $(TEST_MBWC_ENV) +-tst_mbsrtowcs-ENV = $(TEST_MBWC_ENV) +-tst_mbstowcs-ENV = $(TEST_MBWC_ENV) +-tst_mbtowc-ENV = $(TEST_MBWC_ENV) +-tst_strcoll-ENV = $(TEST_MBWC_ENV) +-tst_strfmon-ENV = $(TEST_MBWC_ENV) +-tst_strxfrm-ENV = $(TEST_MBWC_ENV) +-tst_swscanf-ENV = $(TEST_MBWC_ENV) +-tst_towctrans-ENV = $(TEST_MBWC_ENV) +-tst_towlower-ENV = $(TEST_MBWC_ENV) +-tst_towupper-ENV = $(TEST_MBWC_ENV) +-tst_wcrtomb-ENV = $(TEST_MBWC_ENV) +-tst_wcscat-ENV = $(TEST_MBWC_ENV) +-tst_wcschr-ENV = $(TEST_MBWC_ENV) +-tst_wcscmp-ENV = $(TEST_MBWC_ENV) +-tst_wcscoll-ENV = $(TEST_MBWC_ENV) +-tst_wcscpy-ENV = $(TEST_MBWC_ENV) +-tst_wcscspn-ENV = $(TEST_MBWC_ENV) +-tst_wcslen-ENV = $(TEST_MBWC_ENV) +-tst_wcsncat-ENV = $(TEST_MBWC_ENV) +-tst_wcsncmp-ENV = $(TEST_MBWC_ENV) +-tst_wcsncpy-ENV = $(TEST_MBWC_ENV) +-tst_wcspbrk-ENV = $(TEST_MBWC_ENV) +-tst_wcsrtombs-ENV = $(TEST_MBWC_ENV) +-tst_wcsspn-ENV = $(TEST_MBWC_ENV) +-tst_wcsstr-ENV = $(TEST_MBWC_ENV) +-tst_wcstod-ENV = $(TEST_MBWC_ENV) +-tst_wcstok-ENV = $(TEST_MBWC_ENV) +-tst_wcstombs-ENV = $(TEST_MBWC_ENV) +-tst_wcswidth-ENV = $(TEST_MBWC_ENV) +-tst_wcsxfrm-ENV = $(TEST_MBWC_ENV) +-tst_wctob-ENV = $(TEST_MBWC_ENV) +-tst_wctomb-ENV = $(TEST_MBWC_ENV) +-tst_wctrans-ENV = $(TEST_MBWC_ENV) +-tst_wctype-ENV = $(TEST_MBWC_ENV) +-tst_wcwidth-ENV = $(TEST_MBWC_ENV) +-tst-digits-ENV = $(TEST_MBWC_ENV) +-tst-mbswcs6-ENV = $(TEST_MBWC_ENV) +-tst-xlocale1-ENV = $(TEST_MBWC_ENV) +-tst-xlocale2-ENV = $(TEST_MBWC_ENV) +-tst-strfmon1-ENV = $(TEST_MBWC_ENV) +-tst-strptime-ENV = $(TEST_MBWC_ENV) ++tst-setlocale-ENV = LC_ALL=ja_JP.EUC-JP + +-tst-setlocale-ENV = LOCPATH=$(common-objpfx)localedata LC_ALL=ja_JP.EUC-JP +- +-bug-iconv-trans-ENV = LOCPATH=$(common-objpfx)localedata +- +-tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata +- +-tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace \ +- LOCPATH=$(common-objpfx)localedata ++tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace + $(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@ + +-bug-setlocale1-ENV = LOCPATH=$(common-objpfx)localedata + bug-setlocale1-ARGS = $(common-objpfx) +-tst-setlocale2-ENV = LOCPATH=$(common-objpfx)localedata + + $(objdir)/iconvdata/gconv-modules: + $(MAKE) -C ../iconvdata subdir=iconvdata $@ +diff --git glibc-2.17-c758a686/posix/Makefile glibc-2.17-c758a686/posix/Makefile +index 328c2c5..3d75971 100644 +--- glibc-2.17-c758a686/posix/Makefile ++++ glibc-2.17-c758a686/posix/Makefile +@@ -203,27 +203,7 @@ tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir); + tst-chmod-ARGS = $(objdir) + tst-vfork3-ARGS = --test-dir=$(objpfx) + +-tst-fnmatch-ENV = LOCPATH=$(common-objpfx)localedata +-tst-regexloc-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex1-ENV = LOCPATH=$(common-objpfx)localedata +-tst-regex-ENV = LOCPATH=$(common-objpfx)localedata +-tst-regex2-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex5-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex6-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex17-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex18-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex19-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex20-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex22-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex23-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex25-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex26-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex30-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex32-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex33-ENV = LOCPATH=$(common-objpfx)localedata +-bug-regex34-ENV = LOCPATH=$(common-objpfx)localedata + tst-rxspencer-ARGS = --utf8 rxspencer/tests +-tst-rxspencer-ENV = LOCPATH=$(common-objpfx)localedata + tst-pcre-ARGS = PCRE.tests + tst-boost-ARGS = BOOST.tests + bug-glob1-ARGS = "$(objpfx)" +diff --git glibc-2.17-c758a686/stdio-common/Makefile glibc-2.17-c758a686/stdio-common/Makefile +index f179eab..5f8e534 100644 +--- glibc-2.17-c758a686/stdio-common/Makefile ++++ glibc-2.17-c758a686/stdio-common/Makefile +@@ -118,13 +118,6 @@ CFLAGS-scanf17.c = -I../libio -I../stdlib -I../wcsmbs -I../time -I../string \ + + # We know the test has a format string problem. + CFLAGS-tst-sprintf.c = -Wno-format +-tst-sprintf-ENV = LOCPATH=$(common-objpfx)localedata +-tst-sscanf-ENV = LOCPATH=$(common-objpfx)localedata +-tst-swprintf-ENV = LOCPATH=$(common-objpfx)localedata +-test-vfprintf-ENV = LOCPATH=$(common-objpfx)localedata +-scanf13-ENV = LOCPATH=$(common-objpfx)localedata +-bug14-ENV = LOCPATH=$(common-objpfx)localedata +-tst-grouping-ENV = LOCPATH=$(common-objpfx)localedata + + CPPFLAGS += $(libio-mtsafe) + +diff --git glibc-2.17-c758a686/stdlib/Makefile glibc-2.17-c758a686/stdlib/Makefile +index d7a562f..0fdf7cc 100644 +--- glibc-2.17-c758a686/stdlib/Makefile ++++ glibc-2.17-c758a686/stdlib/Makefile +@@ -123,11 +123,6 @@ include ../Rules + # Testdir has to be named stdlib and needs to be writable + test-canon-ARGS = --test-dir=${common-objpfx}stdlib + +-tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata +-tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata +-tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata +-tst-strtod5-ENV = LOCPATH=$(common-objpfx)localedata +-testmb2-ENV = LOCPATH=$(common-objpfx)localedata + bug-fmtmsg1-ENV = SEV_LEVEL=foo,11,newsev + + # Run a test on the header files we use. +diff --git glibc-2.17-c758a686/string/Makefile glibc-2.17-c758a686/string/Makefile +index 5a76872..70b9c19 100644 +--- glibc-2.17-c758a686/string/Makefile ++++ glibc-2.17-c758a686/string/Makefile +@@ -67,9 +67,6 @@ include ../Rules + tester-ENV = LANGUAGE=C + inl-tester-ENV = LANGUAGE=C + noinl-tester-ENV = LANGUAGE=C +-tst-strxfrm-ENV = LOCPATH=$(common-objpfx)localedata +-tst-strxfrm2-ENV = LOCPATH=$(common-objpfx)localedata +-bug-strcoll1-ENV = LOCPATH=$(common-objpfx)localedata + CFLAGS-inl-tester.c = -fno-builtin + CFLAGS-noinl-tester.c = -fno-builtin + CFLAGS-tst-strlen.c = -fno-builtin +diff --git glibc-2.17-c758a686/time/Makefile glibc-2.17-c758a686/time/Makefile +index b7f3dba..a07c041 100644 +--- glibc-2.17-c758a686/time/Makefile ++++ glibc-2.17-c758a686/time/Makefile +@@ -55,7 +55,4 @@ CFLAGS-test_time.c = -Wno-format + tst-getdate-ENV= DATEMSK=datemsk TZDIR=${common-objpfx}timezone/testdata + test_time-ARGS= EST5EDT CST + +-tst-strptime-ENV = LOCPATH=${common-objpfx}localedata +-tst-ftime_l-ENV = LOCPATH=${common-objpfx}localedata +- + bug-getdate1-ARGS = ${objpfx}bug-getdate1-fmt +diff --git glibc-2.17-c758a686/wcsmbs/Makefile glibc-2.17-c758a686/wcsmbs/Makefile +index 197ca7d..42843a6 100644 +--- glibc-2.17-c758a686/wcsmbs/Makefile ++++ glibc-2.17-c758a686/wcsmbs/Makefile +@@ -80,10 +80,3 @@ CPPFLAGS += $(libio-mtsafe) + + # We need to find the default version of strtold_l in stdlib. + CPPFLAGS-wcstold_l.c = -I../stdlib +- +-tst-btowc-ENV = LOCPATH=$(common-objpfx)localedata +-tst-mbrtowc-ENV = LOCPATH=$(common-objpfx)localedata +-tst-wcrtomb-ENV = LOCPATH=$(common-objpfx)localedata +-tst-mbrtowc2-ENV = LOCPATH=$(common-objpfx)localedata +-tst-c16c32-1-ENV = LOCPATH=$(common-objpfx)localedata +-tst-mbsnrtowcs-ENV = LOCPATH=$(common-objpfx)localedata +--- glibc-2.17-c758a686/localedata/Makefile 2014-08-26 21:38:56.564751630 +0530 ++++ glibc-2.17-c758a686/localedata/Makefile.new 2014-08-26 21:40:16.596223207 +0530 diff --git a/SOURCES/glibc-rh1138520.patch b/SOURCES/glibc-rh1138520.patch new file mode 100644 index 00000000..8437bb02 --- /dev/null +++ b/SOURCES/glibc-rh1138520.patch @@ -0,0 +1,144 @@ +commit af37a8a3496327a6e5617a2c76f17aa1e8db835e +Author: Siddhesh Poyarekar +Date: Mon Jan 27 11:32:44 2014 +0530 + + Avoid undefined behaviour in netgroupcache + + Using a buffer after it has been reallocated is undefined behaviour, + so get offsets of the triplets in the old buffer before reallocating + it. + +commit 5d41dadf31bc8a2f9c34c40d52a442d3794e405c +Author: Siddhesh Poyarekar +Date: Fri Jan 24 13:51:15 2014 +0530 + + Adjust pointers to triplets in netgroup query data (BZ #16474) + + The _nss_*_getnetgrent_r query populates the netgroup results in the + allocated buffer and then sets the result triplet to point to strings + in the buffer. This is a problem when the buffer is reallocated since + the pointers to the triplet strings are no longer valid. The pointers + need to be adjusted so that they now point to strings in the + reallocated buffer. + +commit 980cb5180e1b71224a57ca52b995c959b7148c09 +Author: Siddhesh Poyarekar +Date: Thu Jan 16 10:20:22 2014 +0530 + + Don't use alloca in addgetnetgrentX (BZ #16453) + + addgetnetgrentX has a buffer which is grown as per the needs of the + requested size either by using alloca or by falling back to malloc if + the size is larger than 1K. There are two problems with the alloca + bits: firstly, it doesn't really extend the buffer since it does not + use the return value of the extend_alloca macro, which is the location + of the reallocated buffer. Due to this the buffer does not actually + extend itself and hence a subsequent write may overwrite stuff on the + stack. + + The second problem is more subtle - the buffer growth on the stack is + discontinuous due to block scope local variables. Combine that with + the fact that unlike realloc, extend_alloca does not copy over old + content and you have a situation where the buffer just has garbage in + the space where it should have had data. + + This could have been fixed by adding code to copy over old data + whenever we call extend_alloca, but it seems unnecessarily + complicated. This code is not exactly a performance hotspot (it's + called when there is a cache miss, so factors like network lookup or + file reads will dominate over memory allocation/reallocation), so this + premature optimization is unnecessary. + + Thanks Brad Hubbard for his help with debugging + the problem. + +diff -pruN glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +--- glibc-2.17-c758a686/nscd/netgroupcache.c 2014-04-09 12:13:58.618582111 +0530 ++++ glibc-2.17-c758a686/nscd/netgroupcache.c 2014-04-09 12:07:21.486598665 +0530 +@@ -93,7 +93,6 @@ addgetnetgrentX (struct database_dyn *db + size_t buffilled = sizeof (*dataset); + char *buffer = NULL; + size_t nentries = 0; +- bool use_malloc = false; + size_t group_len = strlen (key) + 1; + union + { +@@ -138,7 +137,7 @@ addgetnetgrentX (struct database_dyn *db + } + + memset (&data, '\0', sizeof (data)); +- buffer = alloca (buflen); ++ buffer = xmalloc (buflen); + first_needed.elem.next = &first_needed.elem; + memcpy (first_needed.elem.name, key, group_len); + data.needed_groups = &first_needed.elem; +@@ -218,21 +217,24 @@ addgetnetgrentX (struct database_dyn *db + + if (buflen - req->key_len - bufused < needed) + { +- size_t newsize = MAX (2 * buflen, +- buflen + 2 * needed); +- if (use_malloc || newsize > 1024 * 1024) +- { +- buflen = newsize; +- char *newbuf = xrealloc (use_malloc +- ? buffer +- : NULL, +- buflen); +- +- buffer = newbuf; +- use_malloc = true; +- } +- else +- extend_alloca (buffer, buflen, newsize); ++ buflen += MAX (buflen, 2 * needed); ++ /* Save offset in the old buffer. We don't ++ bother with the NULL check here since ++ we'll do that later anyway. */ ++ size_t nhostdiff = nhost - buffer; ++ size_t nuserdiff = nuser - buffer; ++ size_t ndomaindiff = ndomain - buffer; ++ ++ char *newbuf = xrealloc (buffer, buflen); ++ /* Fix up the triplet pointers into the new ++ buffer. */ ++ nhost = (nhost ? newbuf + nhostdiff ++ : NULL); ++ nuser = (nuser ? newbuf + nuserdiff ++ : NULL); ++ ndomain = (ndomain ? newbuf + ndomaindiff ++ : NULL); ++ buffer = newbuf; + } + + nhost = memcpy (buffer + bufused, +@@ -299,18 +301,8 @@ addgetnetgrentX (struct database_dyn *db + } + else if (status == NSS_STATUS_UNAVAIL && e == ERANGE) + { +- size_t newsize = 2 * buflen; +- if (use_malloc || newsize > 1024 * 1024) +- { +- buflen = newsize; +- char *newbuf = xrealloc (use_malloc +- ? buffer : NULL, buflen); +- +- buffer = newbuf; +- use_malloc = true; +- } +- else +- extend_alloca (buffer, buflen, newsize); ++ buflen *= 2; ++ buffer = xrealloc (buffer, buflen); + } + } + +@@ -446,8 +438,7 @@ addgetnetgrentX (struct database_dyn *db + } + + out: +- if (use_malloc) +- free (buffer); ++ free (buffer); + + *resultp = dataset; diff --git a/SOURCES/glibc-rh1140250.patch b/SOURCES/glibc-rh1140250.patch new file mode 100644 index 00000000..e820ed58 --- /dev/null +++ b/SOURCES/glibc-rh1140250.patch @@ -0,0 +1,346 @@ +commit 7fe9e2e089f4990b7d18d0798f591ab276b15f2b +Author: Florian Weimer +Date: Fri Jun 5 10:50:38 2015 +0200 + + posix_fallocate: Emulation fixes and documentation [BZ #15661] + + Handle signed integer overflow correctly. Detect and reject O_APPEND. + Document drawbacks of emulation. + + This does not completely address bug 15661, but improves the situation + somewhat. + +commit 543ef578c3304661713950b37abd0c916f52ecf0 +Author: Paul Eggert +Date: Tue Aug 25 23:42:01 2015 -0700 + + Fix broken overflow check in posix_fallocate [BZ 18873] + + * sysdeps/posix/posix_fallocate.c (posix_fallocate): + * sysdeps/posix/posix_fallocate64.c (__posix_fallocate64_l64): + Fix parenthesization typo. + +Index: b/manual/filesys.texi +=================================================================== +--- a/manual/filesys.texi ++++ b/manual/filesys.texi +@@ -1723,6 +1723,7 @@ modify the attributes of a file. + access a file. + * File Times:: About the time attributes of a file. + * File Size:: Manually changing the size of a file. ++* Storage Allocation:: Allocate backing storage for files. + @end menu + + @node Attribute Meanings +@@ -3232,6 +3233,99 @@ is a requirement of @code{mmap}. The pr + real size, and when it has finished a final @code{ftruncate} call should + set the real size of the file. + ++@node Storage Allocation ++@subsection Storage Allocation ++@cindex allocating file storage ++@cindex file allocation ++@cindex storage allocating ++ ++@cindex file fragmentation ++@cindex fragmentation of files ++@cindex sparse files ++@cindex files, sparse ++Most file systems support allocating large files in a non-contiguous ++fashion: the file is split into @emph{fragments} which are allocated ++sequentially, but the fragments themselves can be scattered across the ++disk. File systems generally try to avoid such fragmentation because it ++decreases performance, but if a file gradually increases in size, there ++might be no other option than to fragment it. In addition, many file ++systems support @emph{sparse files} with @emph{holes}: regions of null ++bytes for which no backing storage has been allocated by the file ++system. When the holes are finally overwritten with data, fragmentation ++can occur as well. ++ ++Explicit allocation of storage for yet-unwritten parts of the file can ++help the system to avoid fragmentation. Additionally, if storage ++pre-allocation fails, it is possible to report the out-of-disk error ++early, often without filling up the entire disk. However, due to ++deduplication, copy-on-write semantics, and file compression, such ++pre-allocation may not reliably prevent the out-of-disk-space error from ++occurring later. Checking for write errors is still required, and ++writes to memory-mapped regions created with @code{mmap} can still ++result in @code{SIGBUS}. ++ ++@deftypefun int posix_fallocate (int @var{fd}, off_t @var{offset}, off_t @var{length}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++@c If the file system does not support allocation, ++@c @code{posix_fallocate} has a race with file extension (if ++@c @var{length} is zero) or with concurrent writes of non-NUL bytes (if ++@c @var{length} is positive). ++ ++Allocate backing store for the region of @var{length} bytes starting at ++byte @var{offset} in the file for the descriptor @var{fd}. The file ++length is increased to @samp{@var{length} + @var{offset}} if necessary. ++ ++@var{fd} must be a regular file opened for writing, or @code{EBADF} is ++returned. If there is insufficient disk space to fulfill the allocation ++request, @code{ENOSPC} is returned. ++ ++@strong{Note:} If @code{fallocate} is not available (because the file ++system does not support it), @code{posix_fallocate} is emulated, which ++has the following drawbacks: ++ ++@itemize @bullet ++@item ++It is very inefficient because all file system blocks in the requested ++range need to be examined (even if they have been allocated before) and ++potentially rewritten. In contrast, with proper @code{fallocate} ++support (see below), the file system can examine the internal file ++allocation data structures and eliminate holes directly, maybe even ++using unwritten extents (which are pre-allocated but uninitialized on ++disk). ++ ++@item ++There is a race condition if another thread or process modifies the ++underlying file in the to-be-allocated area. Non-null bytes could be ++overwritten with null bytes. ++ ++@item ++If @var{fd} has been opened with the @code{O_APPEND} flag, the function ++will fail with an @code{errno} value of @code{EBADF}. ++ ++@item ++If @var{length} is zero, @code{ftruncate} is used to increase the file ++size as requested, without allocating file system blocks. There is a ++race condition which means that @code{ftruncate} can accidentally ++truncate the file if it has been extended concurrently. ++@end itemize ++ ++On Linux, if an application does not benefit from emulation or if the ++emulation is harmful due to its inherent race conditions, the ++application can use the Linux-specific @code{fallocate} function, with a ++zero flag argument. For the @code{fallocate} function, @theglibc{} does ++not perform allocation emulation if the file system does not support ++allocation. Instead, an @code{EOPNOTSUPP} is returned to the caller. ++ ++@end deftypefun ++ ++@deftypefun int posix_fallocate64 (int @var{fd}, off64_t @var{length}, off64_t @var{offset}) ++@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} ++ ++This function is a variant of @code{posix_fallocate64} which accepts ++64-bit file offsets on all platforms. ++ ++@end deftypefun ++ + @node Making Special Files + @section Making Special Files + @cindex creating special files +Index: b/sysdeps/posix/posix_fallocate.c +=================================================================== +--- a/sysdeps/posix/posix_fallocate.c ++++ b/sysdeps/posix/posix_fallocate.c +@@ -18,26 +18,36 @@ + #include + #include + #include ++#include ++#include + #include + #include + +-/* Reserve storage for the data of the file associated with FD. */ ++/* Reserve storage for the data of the file associated with FD. This ++ emulation is far from perfect, but the kernel cannot do not much ++ better for network file systems, either. */ + + int + posix_fallocate (int fd, __off_t offset, __off_t len) + { + struct stat64 st; +- struct statfs f; + +- /* `off_t' is a signed type. Therefore we can determine whether +- OFFSET + LEN is too large if it is a negative value. */ + if (offset < 0 || len < 0) + return EINVAL; +- if (offset + len < 0) ++ ++ /* Perform overflow check. The outer cast relies on a GCC ++ extension. */ ++ if ((__off_t) ((uint64_t) offset + (uint64_t) len) < 0) + return EFBIG; + +- /* First thing we have to make sure is that this is really a regular +- file. */ ++ /* pwrite below will not do the right thing in O_APPEND mode. */ ++ { ++ int flags = __fcntl (fd, F_GETFL, 0); ++ if (flags < 0 || (flags & O_APPEND) != 0) ++ return EBADF; ++ } ++ ++ /* We have to make sure that this is really a regular file. */ + if (__fxstat64 (_STAT_VER, fd, &st) != 0) + return EBADF; + if (S_ISFIFO (st.st_mode)) +@@ -47,6 +57,8 @@ posix_fallocate (int fd, __off_t offset, + + if (len == 0) + { ++ /* This is racy, but there is no good way to satisfy a ++ zero-length allocation request. */ + if (st.st_size < offset) + { + int ret = __ftruncate (fd, offset); +@@ -58,19 +70,36 @@ posix_fallocate (int fd, __off_t offset, + return 0; + } + +- /* We have to know the block size of the filesystem to get at least some +- sort of performance. */ +- if (__fstatfs (fd, &f) != 0) +- return errno; +- +- /* Try to play safe. */ +- if (f.f_bsize == 0) +- f.f_bsize = 512; +- +- /* Write something to every block. */ +- for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize) ++ /* Minimize data transfer for network file systems, by issuing ++ single-byte write requests spaced by the file system block size. ++ (Most local file systems have fallocate support, so this fallback ++ code is not used there.) */ ++ ++ unsigned increment; ++ { ++ struct statfs64 f; ++ ++ if (__fstatfs64 (fd, &f) != 0) ++ return errno; ++ if (f.f_bsize == 0) ++ increment = 512; ++ else if (f.f_bsize < 4096) ++ increment = f.f_bsize; ++ else ++ /* NFS does not propagate the block size of the underlying ++ storage and may report a much larger value which would still ++ leave holes after the loop below, so we cap the increment at ++ 4096. */ ++ increment = 4096; ++ } ++ ++ /* Write a null byte to every block. This is racy; we currently ++ lack a better option. Compare-and-swap against a file mapping ++ might additional local races, but requires interposition of a ++ signal handler to catch SIGBUS. */ ++ for (offset += (len - 1) % increment; len > 0; offset += increment) + { +- len -= f.f_bsize; ++ len -= increment; + + if (offset < st.st_size) + { +Index: b/sysdeps/posix/posix_fallocate64.c +=================================================================== +--- a/sysdeps/posix/posix_fallocate64.c ++++ b/sysdeps/posix/posix_fallocate64.c +@@ -18,26 +18,36 @@ + #include + #include + #include ++#include ++#include + #include + #include + +-/* Reserve storage for the data of the file associated with FD. */ ++/* Reserve storage for the data of the file associated with FD. This ++ emulation is far from perfect, but the kernel cannot do not much ++ better for network file systems, either. */ + + int + __posix_fallocate64_l64 (int fd, __off64_t offset, __off64_t len) + { + struct stat64 st; +- struct statfs64 f; + +- /* `off64_t' is a signed type. Therefore we can determine whether +- OFFSET + LEN is too large if it is a negative value. */ + if (offset < 0 || len < 0) + return EINVAL; +- if (offset + len < 0) ++ ++ /* Perform overflow check. The outer cast relies on a GCC ++ extension. */ ++ if ((__off64_t) ((uint64_t) offset + (uint64_t) len) < 0) + return EFBIG; + +- /* First thing we have to make sure is that this is really a regular +- file. */ ++ /* pwrite64 below will not do the right thing in O_APPEND mode. */ ++ { ++ int flags = __fcntl (fd, F_GETFL, 0); ++ if (flags < 0 || (flags & O_APPEND) != 0) ++ return EBADF; ++ } ++ ++ /* We have to make sure that this is really a regular file. */ + if (__fxstat64 (_STAT_VER, fd, &st) != 0) + return EBADF; + if (S_ISFIFO (st.st_mode)) +@@ -47,6 +57,8 @@ __posix_fallocate64_l64 (int fd, __off64 + + if (len == 0) + { ++ /* This is racy, but there is no good way to satisfy a ++ zero-length allocation request. */ + if (st.st_size < offset) + { + int ret = __ftruncate64 (fd, offset); +@@ -58,19 +70,36 @@ __posix_fallocate64_l64 (int fd, __off64 + return 0; + } + +- /* We have to know the block size of the filesystem to get at least some +- sort of performance. */ +- if (__fstatfs64 (fd, &f) != 0) +- return errno; +- +- /* Try to play safe. */ +- if (f.f_bsize == 0) +- f.f_bsize = 512; +- +- /* Write something to every block. */ +- for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize) ++ /* Minimize data transfer for network file systems, by issuing ++ single-byte write requests spaced by the file system block size. ++ (Most local file systems have fallocate support, so this fallback ++ code is not used there.) */ ++ ++ unsigned increment; ++ { ++ struct statfs64 f; ++ ++ if (__fstatfs64 (fd, &f) != 0) ++ return errno; ++ if (f.f_bsize == 0) ++ increment = 512; ++ else if (f.f_bsize < 4096) ++ increment = f.f_bsize; ++ else ++ /* NFS clients do not propagate the block size of the underlying ++ storage and may report a much larger value which would still ++ leave holes after the loop below, so we cap the increment at ++ 4096. */ ++ increment = 4096; ++ } ++ ++ /* Write a null byte to every block. This is racy; we currently ++ lack a better option. Compare-and-swap against a file mapping ++ might address local races, but requires interposition of a signal ++ handler to catch SIGBUS. */ ++ for (offset += (len - 1) % increment; len > 0; offset += increment) + { +- len -= f.f_bsize; ++ len -= increment; + + if (offset < st.st_size) + { diff --git a/SOURCES/glibc-rh1140272-avx512.patch b/SOURCES/glibc-rh1140272-avx512.patch new file mode 100644 index 00000000..f1029691 --- /dev/null +++ b/SOURCES/glibc-rh1140272-avx512.patch @@ -0,0 +1,1158 @@ +# +# AVX-512 support for glibc: +# +# Notes: Renamed configure.ac changes to configure.in. +# +# commit aa4de9cea5c07d43caeaca9722c2d417e9a2919c +# Author: H.J. Lu +# Date: Fri Mar 14 08:51:25 2014 -0700 +# +# Check AVX-512 assembler support first +# +# It checks AVX-512 assembler support first and sets libc_cv_cc_avx512 to +# $libc_cv_asm_avx512, instead of yes. GCC won't support AVX-512 if +# assembler doesn't support it. +# +# * sysdeps/x86_64/configure.ac: Check AVX-512 assembler support +# first. Disable AVX-512 GCC support if assembler doesn't support +# it. +# * sysdeps/x86_64/configure: Regenerated. +# +# commit 2d63a517e4084ec80403cd9f278690fa8b676cc4 +# Author: Igor Zamyatin +# Date: Thu Mar 13 11:10:22 2014 -0700 +# +# Save and restore AVX-512 zmm registers to x86-64 ld.so +# +# AVX-512 ISA adds 512-bit zmm registers. This patch updates +# _dl_runtime_profile to pass zmm registers to run-time audit. It also +# changes _dl_x86_64_save_sse and _dl_x86_64_restore_sse to upport zmm +# registers, which are called when only when RTLD_PREPARE_FOREIGN_CALL +# is used. Its performance impact is minimum. +# +# * config.h.in (HAVE_AVX512_SUPPORT): New #undef. +# (HAVE_AVX512_ASM_SUPPORT): Likewise. +# * sysdeps/x86_64/bits/link.h (La_x86_64_zmm): New. +# (La_x86_64_vector): Add zmm. +# * sysdeps/x86_64/Makefile (tests): Add tst-audit10. +# (modules-names): Add tst-auditmod10a and tst-auditmod10b. +# ($(objpfx)tst-audit10): New target. +# ($(objpfx)tst-audit10.out): Likewise. +# (tst-audit10-ENV): New. +# (AVX512-CFLAGS): Likewise. +# (CFLAGS-tst-audit10.c): Likewise. +# (CFLAGS-tst-auditmod10a.c): Likewise. +# (CFLAGS-tst-auditmod10b.c): Likewise. +# * sysdeps/x86_64/configure.ac: Set config-cflags-avx512, +# HAVE_AVX512_SUPPORT and HAVE_AVX512_ASM_SUPPORT. +# * sysdeps/x86_64/configure: Regenerated. +# * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Add +# AVX-512 zmm register support. +# (_dl_x86_64_save_sse): Likewise. +# (_dl_x86_64_restore_sse): Likewise. +# * sysdeps/x86_64/dl-trampoline.h: Updated to support different +# size vector registers. +# * sysdeps/x86_64/link-defines.sym (YMM_SIZE): New. +# (ZMM_SIZE): Likewise. +# * sysdeps/x86_64/tst-audit10.c: New file. +# * sysdeps/x86_64/tst-auditmod10a.c: Likewise. +# * sysdeps/x86_64/tst-auditmod10b.c: Likewise. +# +# In addition adds: +# https://sourceware.org/ml/libc-alpha/2014-09/msg00228.html +# To extend zmm register checking. +# +diff -urN glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686/config.h.in +--- glibc-2.17-c758a686/config.h.in 2014-09-10 23:11:14.605787816 -0400 ++++ glibc-2.17-c758a686/config.h.in 2014-09-10 23:16:36.331167056 -0400 +@@ -101,6 +101,12 @@ + /* Define if gcc supports VEX encoding. */ + #undef HAVE_SSE2AVX_SUPPORT + ++/* Define if compiler supports AVX512. */ ++#undef HAVE_AVX512_SUPPORT ++ ++/* Define if assembler supports AVX512. */ ++#undef HAVE_AVX512_ASM_SUPPORT ++ + /* Define if gcc supports FMA4. */ + #undef HAVE_FMA4_SUPPORT + +diff -urN glibc-2.17-c758a686/sysdeps/x86/bits/link.h glibc-2.17-c758a686/sysdeps/x86/bits/link.h +--- glibc-2.17-c758a686/sysdeps/x86/bits/link.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86/bits/link.h 2014-09-10 23:16:36.331167056 -0400 +@@ -66,6 +66,8 @@ + typedef float La_x86_64_xmm __attribute__ ((__vector_size__ (16))); + typedef float La_x86_64_ymm + __attribute__ ((__vector_size__ (32), __aligned__ (16))); ++typedef double La_x86_64_zmm ++ __attribute__ ((__vector_size__ (64), __aligned__ (16))); + # else + typedef float La_x86_64_xmm __attribute__ ((__mode__ (__V4SF__))); + # endif +@@ -74,6 +76,7 @@ + { + # if __GNUC_PREREQ (4,0) + La_x86_64_ymm ymm[2]; ++ La_x86_64_zmm zmm[1]; + # endif + La_x86_64_xmm xmm[4]; + } La_x86_64_vector __attribute__ ((__aligned__ (16))); +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure glibc-2.17-c758a686/sysdeps/x86_64/configure +--- glibc-2.17-c758a686/sysdeps/x86_64/configure 2014-09-10 23:11:15.000787061 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/configure 2014-09-10 23:16:36.338167042 -0400 +@@ -91,6 +91,59 @@ + + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX512 support in assembler" >&5 ++$as_echo_n "checking for AVX512 support in assembler... " >&6; } ++if ${libc_cv_asm_avx512+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.s <<\EOF ++ vmovdqu64 %zmm0, (%rsp) ++EOF ++if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ libc_cv_asm_avx512=yes ++else ++ libc_cv_asm_avx512=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_avx512" >&5 ++$as_echo "$libc_cv_asm_avx512" >&6; } ++if test $libc_cv_asm_avx512 == yes; then ++ $as_echo "#define HAVE_AVX512_ASM_SUPPORT 1" >>confdefs.h ++ ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX512 support" >&5 ++$as_echo_n "checking for AVX512 support... " >&6; } ++if ${libc_cv_cc_avx512+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ if { ac_try='${CC-cc} -mavx512f -xc /dev/null -S -o /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then : ++ libc_cv_cc_avx512=$libc_cv_asm_avx512 ++else ++ libc_cv_cc_avx512=no ++fi ++ ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_avx512" >&5 ++$as_echo "$libc_cv_cc_avx512" >&6; } ++if test $libc_cv_cc_avx512 = yes; then ++ $as_echo "#define HAVE_AVX512_SUPPORT 1" >>confdefs.h ++ ++fi ++config_vars="$config_vars ++config-cflags-avx512 = $libc_cv_cc_avx512" ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX encoding of SSE instructions" >&5 + $as_echo_n "checking for AVX encoding of SSE instructions... " >&6; } + if ${libc_cv_cc_sse2avx+:} false; then : +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/configure.in glibc-2.17-c758a686/sysdeps/x86_64/configure.in +--- glibc-2.17-c758a686/sysdeps/x86_64/configure.in 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/configure.in 2014-09-10 23:16:36.338167042 -0400 +@@ -21,6 +21,30 @@ + AC_DEFINE(HAVE_AVX_SUPPORT) + fi + ++dnl Check if asm supports AVX512. ++AC_CACHE_CHECK(for AVX512 support in assembler, libc_cv_asm_avx512, [dnl ++cat > conftest.s <<\EOF ++ vmovdqu64 %zmm0, (%rsp) ++EOF ++if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then ++ libc_cv_asm_avx512=yes ++else ++ libc_cv_asm_avx512=no ++fi ++rm -f conftest*]) ++if test $libc_cv_asm_avx512 == yes; then ++ AC_DEFINE(HAVE_AVX512_ASM_SUPPORT) ++fi ++ ++dnl Check if -mavx512f works. ++AC_CACHE_CHECK(for AVX512 support, libc_cv_cc_avx512, [dnl ++LIBC_TRY_CC_OPTION([-mavx512f], [libc_cv_cc_avx512=$libc_cv_asm_avx512], [libc_cv_cc_avx512=no]) ++]) ++if test $libc_cv_cc_avx512 = yes; then ++ AC_DEFINE(HAVE_AVX512_SUPPORT) ++fi ++LIBC_CONFIG_VAR([config-cflags-avx512], [$libc_cv_cc_avx512]) ++ + dnl Check if -msse2avx works. + AC_CACHE_CHECK(for AVX encoding of SSE instructions, libc_cv_cc_sse2avx, [dnl + LIBC_TRY_CC_OPTION([-msse2avx], +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h +--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h 2014-09-10 23:16:36.334167050 -0400 +@@ -19,14 +19,14 @@ + + #ifdef RESTORE_AVX + /* This is to support AVX audit modules. */ +- vmovdqu %ymm0, (LR_VECTOR_OFFSET)(%rsp) +- vmovdqu %ymm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp) +- vmovdqu %ymm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp) +- vmovdqu %ymm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp) +- vmovdqu %ymm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp) +- vmovdqu %ymm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp) +- vmovdqu %ymm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp) +- vmovdqu %ymm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp) ++ VMOV %VEC(0), (LR_VECTOR_OFFSET)(%rsp) ++ VMOV %VEC(1), (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp) ++ VMOV %VEC(2), (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp) ++ VMOV %VEC(3), (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp) ++ VMOV %VEC(4), (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp) ++ VMOV %VEC(5), (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp) ++ VMOV %VEC(6), (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp) ++ VMOV %VEC(7), (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp) + + /* Save xmm0-xmm7 registers to detect if any of them are + changed by audit module. */ +@@ -72,7 +72,7 @@ + je 2f + vmovdqa %xmm0, (LR_VECTOR_OFFSET)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET)(%rsp), %ymm0 ++2: VMOV (LR_VECTOR_OFFSET)(%rsp), %VEC(0) + vmovdqa %xmm0, (LR_XMM_OFFSET)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm8 +@@ -81,7 +81,7 @@ + je 2f + vmovdqa %xmm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %ymm1 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %VEC(1) + vmovdqa %xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*2)(%rsp), %xmm2, %xmm8 +@@ -90,7 +90,7 @@ + je 2f + vmovdqa %xmm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %ymm2 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %VEC(2) + vmovdqa %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*3)(%rsp), %xmm3, %xmm8 +@@ -99,7 +99,7 @@ + je 2f + vmovdqa %xmm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %ymm3 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %VEC(3) + vmovdqa %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*4)(%rsp), %xmm4, %xmm8 +@@ -108,7 +108,7 @@ + je 2f + vmovdqa %xmm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %ymm4 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %VEC(4) + vmovdqa %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*5)(%rsp), %xmm5, %xmm8 +@@ -117,7 +117,7 @@ + je 2f + vmovdqa %xmm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %ymm5 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %VEC(5) + vmovdqa %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*6)(%rsp), %xmm6, %xmm8 +@@ -126,7 +126,7 @@ + je 2f + vmovdqa %xmm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %ymm6 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %VEC(6) + vmovdqa %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*7)(%rsp), %xmm7, %xmm8 +@@ -135,7 +135,7 @@ + je 2f + vmovdqa %xmm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp) + jmp 1f +-2: vmovdqu (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %ymm7 ++2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %VEC(7) + vmovdqa %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp) + + 1: +@@ -213,8 +213,8 @@ + + #ifdef RESTORE_AVX + /* This is to support AVX audit modules. */ +- vmovdqu %ymm0, LRV_VECTOR0_OFFSET(%rcx) +- vmovdqu %ymm1, LRV_VECTOR1_OFFSET(%rcx) ++ VMOV %VEC(0), LRV_VECTOR0_OFFSET(%rcx) ++ VMOV %VEC(1), LRV_VECTOR1_OFFSET(%rcx) + + /* Save xmm0/xmm1 registers to detect if they are changed + by audit module. */ +@@ -243,13 +243,13 @@ + vpmovmskb %xmm2, %esi + cmpl $0xffff, %esi + jne 1f +- vmovdqu LRV_VECTOR0_OFFSET(%rsp), %ymm0 ++ VMOV LRV_VECTOR0_OFFSET(%rsp), %VEC(0) + + 1: vpcmpeqq (LRV_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm2 + vpmovmskb %xmm2, %esi + cmpl $0xffff, %esi + jne 1f +- vmovdqu LRV_VECTOR1_OFFSET(%rsp), %ymm1 ++ VMOV LRV_VECTOR1_OFFSET(%rsp), %VEC(1) + + 1: + #endif +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S 2014-09-10 23:16:36.334167050 -0400 +@@ -96,7 +96,7 @@ + + /* Actively align the La_x86_64_regs structure. */ + andq $0xfffffffffffffff0, %rsp +-# ifdef HAVE_AVX_SUPPORT ++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT + /* sizeof(La_x86_64_regs). Need extra space for 8 SSE registers + to detect if any xmm0-xmm7 registers are changed by audit + module. */ +@@ -130,7 +130,7 @@ + movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp) + movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp) + +-# ifdef HAVE_AVX_SUPPORT ++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT + .data + L(have_avx): + .zero 4 +@@ -138,7 +138,7 @@ + .previous + + cmpl $0, L(have_avx)(%rip) +- jne 1f ++ jne L(defined) + movq %rbx, %r11 # Save rbx + movl $1, %eax + cpuid +@@ -147,18 +147,54 @@ + // AVX and XSAVE supported? + andl $((1 << 28) | (1 << 27)), %ecx + cmpl $((1 << 28) | (1 << 27)), %ecx +- jne 2f ++ jne 10f ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ // AVX512 supported in processor? ++ movq %rbx, %r11 # Save rbx ++ xorl %ecx, %ecx ++ mov $0x7, %eax ++ cpuid ++ andl $(1 << 16), %ebx ++# endif + xorl %ecx, %ecx + // Get XFEATURE_ENABLED_MASK + xgetbv +- andl $0x6, %eax +-2: subl $0x5, %eax ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ test %ebx, %ebx ++ movq %r11, %rbx # Restore rbx ++ je 20f ++ // Verify that XCR0[7:5] = '111b' and ++ // XCR0[2:1] = '11b' which means ++ // that zmm state is enabled ++ andl $0xe6, %eax ++ cmpl $0xe6, %eax ++ jne 20f ++ movl %eax, L(have_avx)(%rip) ++L(avx512): ++# define RESTORE_AVX ++# define VMOV vmovdqu64 ++# define VEC(i) zmm##i ++# define MORE_CODE ++# include "dl-trampoline.h" ++# undef VMOV ++# undef VEC ++# undef RESTORE_AVX ++# endif ++20: andl $0x6, %eax ++10: subl $0x5, %eax + movl %eax, L(have_avx)(%rip) + cmpl $0, %eax + +-1: js L(no_avx) ++L(defined): ++ js L(no_avx) ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ cmpl $0xe6, L(have_avx)(%rip) ++ je L(avx512) ++# endif + + # define RESTORE_AVX ++# define VMOV vmovdqu ++# define VEC(i) ymm##i + # define MORE_CODE + # include "dl-trampoline.h" + +@@ -180,9 +216,9 @@ + .align 16 + cfi_startproc + _dl_x86_64_save_sse: +-# ifdef HAVE_AVX_SUPPORT ++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT + cmpl $0, L(have_avx)(%rip) +- jne 1f ++ jne L(defined_5) + movq %rbx, %r11 # Save rbx + movl $1, %eax + cpuid +@@ -191,21 +227,43 @@ + // AVX and XSAVE supported? + andl $((1 << 28) | (1 << 27)), %ecx + cmpl $((1 << 28) | (1 << 27)), %ecx +- jne 2f ++ jne 1f ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ // AVX512 supported in a processor? ++ movq %rbx, %r11 # Save rbx ++ xorl %ecx,%ecx ++ mov $0x7,%eax ++ cpuid ++ andl $(1 << 16), %ebx ++# endif + xorl %ecx, %ecx + // Get XFEATURE_ENABLED_MASK + xgetbv +- andl $0x6, %eax +- cmpl $0x6, %eax +- // Nonzero if SSE and AVX state saving is enabled. +- sete %al +-2: leal -1(%eax,%eax), %eax ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ test %ebx, %ebx ++ movq %r11, %rbx # Restore rbx ++ je 2f ++ // Verify that XCR0[7:5] = '111b' and ++ // XCR0[2:1] = '11b' which means ++ // that zmm state is enabled ++ andl $0xe6, %eax ++ movl %eax, L(have_avx)(%rip) ++ cmpl $0xe6, %eax ++ je L(avx512_5) ++# endif ++ ++2: andl $0x6, %eax ++1: subl $0x5, %eax + movl %eax, L(have_avx)(%rip) + cmpl $0, %eax + +-1: js L(no_avx5) ++L(defined_5): ++ js L(no_avx5) ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ cmpl $0xe6, L(have_avx)(%rip) ++ je L(avx512_5) ++# endif + +-# define YMM_SIZE 32 + vmovdqa %ymm0, %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE + vmovdqa %ymm1, %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE + vmovdqa %ymm2, %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE +@@ -215,6 +273,18 @@ + vmovdqa %ymm6, %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE + vmovdqa %ymm7, %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE + ret ++# ifdef HAVE_AVX512_ASM_SUPPORT ++L(avx512_5): ++ vmovdqu64 %zmm0, %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE ++ vmovdqu64 %zmm1, %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE ++ vmovdqu64 %zmm2, %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE ++ vmovdqu64 %zmm3, %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE ++ vmovdqu64 %zmm4, %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE ++ vmovdqu64 %zmm5, %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE ++ vmovdqu64 %zmm6, %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE ++ vmovdqu64 %zmm7, %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE ++ ret ++# endif + L(no_avx5): + # endif + movdqa %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE +@@ -235,9 +305,13 @@ + .align 16 + cfi_startproc + _dl_x86_64_restore_sse: +-# ifdef HAVE_AVX_SUPPORT ++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT + cmpl $0, L(have_avx)(%rip) + js L(no_avx6) ++# ifdef HAVE_AVX512_ASM_SUPPORT ++ cmpl $0xe6, L(have_avx)(%rip) ++ je L(avx512_6) ++# endif + + vmovdqa %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE, %ymm0 + vmovdqa %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE, %ymm1 +@@ -248,6 +322,18 @@ + vmovdqa %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE, %ymm6 + vmovdqa %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE, %ymm7 + ret ++# ifdef HAVE_AVX512_ASM_SUPPORT ++L(avx512_6): ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE, %zmm0 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE, %zmm1 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE, %zmm2 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE, %zmm3 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE, %zmm4 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE, %zmm5 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE, %zmm6 ++ vmovdqu64 %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE, %zmm7 ++ ret ++# endif + L(no_avx6): + # endif + movdqa %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE, %xmm0 +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym +--- glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/link-defines.sym 2014-09-10 23:16:36.335167048 -0400 +@@ -4,6 +4,8 @@ + -- + VECTOR_SIZE sizeof (La_x86_64_vector) + XMM_SIZE sizeof (La_x86_64_xmm) ++YMM_SIZE sizeof (La_x86_64_ymm) ++ZMM_SIZE sizeof (La_x86_64_zmm) + + LR_SIZE sizeof (struct La_x86_64_regs) + LR_RDX_OFFSET offsetof (struct La_x86_64_regs, lr_rdx) +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/Makefile glibc-2.17-c758a686/sysdeps/x86_64/Makefile +--- glibc-2.17-c758a686/sysdeps/x86_64/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/Makefile 2014-09-10 23:22:04.269518711 -0400 +@@ -37,6 +37,20 @@ + + $(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o + $(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o ++ ++tests += tst-audit10 ++modules-names += tst-auditmod10a tst-auditmod10b ++ ++$(objpfx)tst-audit10: $(objpfx)tst-auditmod10a.so ++$(objpfx)tst-audit10.out: $(objpfx)tst-auditmod10b.so ++tst-audit10-ENV = LD_AUDIT=$(objpfx)tst-auditmod10b.so ++ ++ifeq (yes,$(config-cflags-avx512)) ++AVX512-CFLAGS = -mavx512f ++CFLAGS-tst-audit10.c += $(AVX512-CFLAGS) ++CFLAGS-tst-auditmod10a.c += $(AVX512-CFLAGS) ++CFLAGS-tst-auditmod10b.c += $(AVX512-CFLAGS) ++endif + endif + + ifeq ($(subdir),csu) +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/tst-audit10.c glibc-2.17-c758a686/sysdeps/x86_64/tst-audit10.c +--- glibc-2.17-c758a686/sysdeps/x86_64/tst-audit10.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-audit10.c 2014-09-10 23:16:36.335167048 -0400 +@@ -0,0 +1,70 @@ ++/* Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Test case for x86-64 preserved registers in dynamic linker. */ ++ ++#ifdef __AVX512F__ ++#include ++#include ++#include ++#include ++ ++static int ++avx512_enabled (void) ++{ ++ unsigned int eax, ebx, ecx, edx; ++ ++ if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 ++ || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) ++ return 0; ++ ++ __cpuid_count (7, 0, eax, ebx, ecx, edx); ++ if (!(ebx & bit_AVX512F)) ++ return 0; ++ ++ asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); ++ ++ /* Verify that ZMM, YMM and XMM states are enabled. */ ++ return (eax & 0xe6) == 0xe6; ++} ++ ++ ++extern __m512i audit_test (__m512i, __m512i, __m512i, __m512i, ++ __m512i, __m512i, __m512i, __m512i); ++int ++main (void) ++{ ++ /* Run AVX512 test only if AVX512 is supported. */ ++ if (avx512_enabled ()) ++ { ++ __m512i zmm = _mm512_setzero_si512 (); ++ __m512i ret = audit_test (zmm, zmm, zmm, zmm, zmm, zmm, zmm, zmm); ++ ++ zmm = _mm512_set1_epi64 (0x12349876); ++ ++ if (memcmp (&zmm, &ret, sizeof (ret))) ++ abort (); ++ } ++ return 0; ++} ++#else ++int ++main (void) ++{ ++ return 0; ++} ++#endif +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10a.c glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10a.c +--- glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10a.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10a.c 2014-09-10 23:16:36.335167048 -0400 +@@ -0,0 +1,65 @@ ++/* Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Test case for x86-64 preserved registers in dynamic linker. */ ++ ++#ifdef __AVX512F__ ++#include ++#include ++#include ++ ++__m512i ++audit_test (__m512i x0, __m512i x1, __m512i x2, __m512i x3, ++ __m512i x4, __m512i x5, __m512i x6, __m512i x7) ++{ ++ __m512i zmm; ++ ++ zmm = _mm512_set1_epi64 (1); ++ if (memcmp (&zmm, &x0, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (2); ++ if (memcmp (&zmm, &x1, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (3); ++ if (memcmp (&zmm, &x2, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (4); ++ if (memcmp (&zmm, &x3, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (5); ++ if (memcmp (&zmm, &x4, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (6); ++ if (memcmp (&zmm, &x5, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (7); ++ if (memcmp (&zmm, &x6, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi64 (8); ++ if (memcmp (&zmm, &x7, sizeof (zmm))) ++ abort (); ++ ++ return _mm512_setzero_si512 (); ++} ++#endif +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10b.c glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10b.c +--- glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10b.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-auditmod10b.c 2014-09-10 23:16:36.336167046 -0400 +@@ -0,0 +1,219 @@ ++/* Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Verify that changing AVX512 registers in audit library won't affect ++ function parameter passing/return. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ setlinebuf (stdout); ++ ++ printf ("version: %u\n", v); ++ ++ char buf[20]; ++ sprintf (buf, "%u", v); ++ ++ return v; ++} ++ ++void ++la_activity (uintptr_t *cookie, unsigned int flag) ++{ ++ if (flag == LA_ACT_CONSISTENT) ++ printf ("activity: consistent\n"); ++ else if (flag == LA_ACT_ADD) ++ printf ("activity: add\n"); ++ else if (flag == LA_ACT_DELETE) ++ printf ("activity: delete\n"); ++ else ++ printf ("activity: unknown activity %u\n", flag); ++} ++ ++char * ++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) ++{ ++ char buf[100]; ++ const char *flagstr; ++ if (flag == LA_SER_ORIG) ++ flagstr = "LA_SET_ORIG"; ++ else if (flag == LA_SER_LIBPATH) ++ flagstr = "LA_SER_LIBPATH"; ++ else if (flag == LA_SER_RUNPATH) ++ flagstr = "LA_SER_RUNPATH"; ++ else if (flag == LA_SER_CONFIG) ++ flagstr = "LA_SER_CONFIG"; ++ else if (flag == LA_SER_DEFAULT) ++ flagstr = "LA_SER_DEFAULT"; ++ else if (flag == LA_SER_SECURE) ++ flagstr = "LA_SER_SECURE"; ++ else ++ { ++ sprintf (buf, "unknown flag %d", flag); ++ flagstr = buf; ++ } ++ printf ("objsearch: %s, %s\n", name, flagstr); ++ ++ return (char *) name; ++} ++ ++unsigned int ++la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie) ++{ ++ printf ("objopen: %ld, %s\n", lmid, l->l_name); ++ ++ return 3; ++} ++ ++void ++la_preinit (uintptr_t *cookie) ++{ ++ printf ("preinit\n"); ++} ++ ++unsigned int ++la_objclose (uintptr_t *cookie) ++{ ++ printf ("objclose\n"); ++ return 0; ++} ++ ++uintptr_t ++la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, unsigned int *flags, const char *symname) ++{ ++ printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", ++ symname, (long int) sym->st_value, ndx, *flags); ++ ++ return sym->st_value; ++} ++ ++#include ++ ++#ifdef __AVX512F__ ++#include ++#include ++ ++static int ++check_avx512 (void) ++{ ++ unsigned int eax, ebx, ecx, edx; ++ ++ if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 ++ || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) ++ return 0; ++ ++ __cpuid_count (7, 0, eax, ebx, ecx, edx); ++ if (!(ebx & bit_AVX512F)) ++ return 0; ++ ++ asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); ++ ++ /* Verify that ZMM, YMM and XMM states are enabled. */ ++ return (eax & 0xe6) == 0xe6; ++} ++ ++#else ++#include ++#endif ++ ++ElfW(Addr) ++pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, La_regs *regs, unsigned int *flags, ++ const char *symname, long int *framesizep) ++{ ++ printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", ++ symname, (long int) sym->st_value, ndx, *flags); ++ ++#ifdef __AVX512F__ ++ if (check_avx512 () && strcmp (symname, "audit_test") == 0) ++ { ++ __m512i zero = _mm512_setzero_si512 (); ++ if (memcmp (®s->lr_vector[0], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[1], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[2], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[3], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[4], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[5], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[6], &zero, sizeof (zero)) ++ || memcmp (®s->lr_vector[7], &zero, sizeof (zero))) ++ abort (); ++ ++ for (int i = 0; i < 8; i++) ++ regs->lr_vector[i].zmm[0] ++ = (La_x86_64_zmm) _mm512_set1_epi64 (i + 1); ++ ++ __m512i zmm = _mm512_set1_epi64 (-1); ++ asm volatile ("vmovdqa64 %0, %%zmm0" : : "x" (zmm) : "xmm0" ); ++ asm volatile ("vmovdqa64 %0, %%zmm1" : : "x" (zmm) : "xmm1" ); ++ asm volatile ("vmovdqa64 %0, %%zmm2" : : "x" (zmm) : "xmm2" ); ++ asm volatile ("vmovdqa64 %0, %%zmm3" : : "x" (zmm) : "xmm3" ); ++ asm volatile ("vmovdqa64 %0, %%zmm4" : : "x" (zmm) : "xmm4" ); ++ asm volatile ("vmovdqa64 %0, %%zmm5" : : "x" (zmm) : "xmm5" ); ++ asm volatile ("vmovdqa64 %0, %%zmm6" : : "x" (zmm) : "xmm6" ); ++ asm volatile ("vmovdqa64 %0, %%zmm7" : : "x" (zmm) : "xmm7" ); ++ ++ *framesizep = 1024; ++ } ++#endif ++ ++ return sym->st_value; ++} ++ ++unsigned int ++pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook, ++ uintptr_t *defcook, const La_regs *inregs, La_retval *outregs, ++ const char *symname) ++{ ++ printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", ++ symname, (long int) sym->st_value, ndx, ++ (ptrdiff_t) outregs->int_retval); ++ ++#ifdef __AVX512F__ ++ if (check_avx512 () && strcmp (symname, "audit_test") == 0) ++ { ++ __m512i zero = _mm512_setzero_si512 (); ++ if (memcmp (&outregs->lrv_vector0, &zero, sizeof (zero))) ++ abort (); ++ ++ for (int i = 0; i < 8; i++) ++ { ++ __m512i zmm = _mm512_set1_epi64 (i + 1); ++ if (memcmp (&inregs->lr_vector[i], &zmm, sizeof (zmm)) != 0) ++ abort (); ++ } ++ ++ outregs->lrv_vector0.zmm[0] ++ = (La_x86_64_zmm) _mm512_set1_epi64 (0x12349876); ++ ++ __m512i zmm = _mm512_set1_epi64 (-1); ++ asm volatile ("vmovdqa64 %0, %%zmm0" : : "x" (zmm) : "xmm0" ); ++ asm volatile ("vmovdqa64 %0, %%zmm1" : : "x" (zmm) : "xmm1" ); ++ } ++#endif ++ ++ return 0; ++} +diff -urN glibc-2.17-c758a686/sysdeps/x86/Makefile glibc-2.17-c758a686/sysdeps/x86/Makefile +--- glibc-2.17-c758a686/sysdeps/x86/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86/Makefile 2014-09-11 16:06:03.121319867 -0400 +@@ -2,8 +2,8 @@ + CFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\ + -mno-sse -mno-mmx) + +-tests: $(objpfx)tst-xmmymm.out +-$(objpfx)tst-xmmymm.out: ../sysdeps/x86/tst-xmmymm.sh $(objpfx)ld.so ++tests: $(objpfx)tst-xmmymmzmm.out ++$(objpfx)tst-xmmymmzmm.out: ../sysdeps/x86/tst-xmmymmzmm.sh $(objpfx)ld.so + @echo "Checking ld.so for SSE register use. This will take a few seconds..." + $(SHELL) $< $(objpfx) '$(NM)' '$(OBJDUMP)' '$(READELF)' > $@ + endif +diff -urN glibc-2.17-c758a686/sysdeps/x86/tst-xmmymm.sh glibc-2.17-c758a686/sysdeps/x86/tst-xmmymm.sh +--- glibc-2.17-c758a686/sysdeps/x86/tst-xmmymm.sh 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86/tst-xmmymm.sh 1969-12-31 19:00:00.000000000 -0500 +@@ -1,103 +0,0 @@ +-#! /bin/bash +-# Make sure no code in ld.so uses xmm/ymm registers on x86-64. +-# Copyright (C) 2009-2012 Free Software Foundation, Inc. +-# This file is part of the GNU C Library. +- +-# The GNU C Library is free software; you can redistribute it and/or +-# modify it under the terms of the GNU Lesser General Public +-# License as published by the Free Software Foundation; either +-# version 2.1 of the License, or (at your option) any later version. +- +-# The GNU C Library is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# Lesser General Public License for more details. +- +-# You should have received a copy of the GNU Lesser General Public +-# License along with the GNU C Library; if not, see +-# . +- +-set -e +- +-objpfx="$1" +-NM="$2" +-OBJDUMP="$3" +-READELF="$4" +- +-tmp=$(mktemp ${objpfx}tst-xmmymm.XXXXXX) +-trap 'rm -f "$tmp"' 1 2 3 15 +- +-# List of object files we have to test +-rtldobjs=$($READELF -W -wi ${objpfx}dl-allobjs.os | +- awk '/^ "$tmp" +-declare -a objects +-objects=($(cat "$tmp")) +- +-objs="dl-runtime.os" +-tocheck="dl-runtime.os" +- +-while test -n "$objs"; do +- this="$objs" +- objs="" +- +- for f in $this; do +- undef=$($NM -u "$objpfx"../*/"$f" | awk '{print $2}') +- if test -n "$undef"; then +- for s in $undef; do +- for obj in ${objects[*]} "_GLOBAL_OFFSET_TABLE_"; do +- if test "$obj" = "$s"; then +- continue 2 +- fi +- done +- for o in $rtldobjs; do +- ro=$(echo "$objpfx"../*/"$o") +- if $NM -g --defined-only "$ro" | egrep -qs " $s\$"; then +- if ! (echo "$tocheck $objs" | fgrep -qs "$o"); then +- echo "$o needed for $s" +- objs="$objs $o" +- fi +- break; +- fi +- done +- done +- fi +- done +- tocheck="$tocheck$objs" +-done +- +-echo +-echo +-echo "object files needed: $tocheck" +- +-cp /dev/null "$tmp" +-for f in $tocheck; do +- $OBJDUMP -d "$objpfx"../*/"$f" | +- awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xy]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' | +- while read fct; do +- if test "$fct" = "_dl_runtime_profile" -o "$fct" = "_dl_x86_64_restore_sse"; then +- continue; +- fi +- echo "function $fct in $f modifies xmm/ymm" >> "$tmp" +- result=1 +- done +-done +- +-if test -s "$tmp"; then +- echo +- echo +- cat "$tmp" +- result=1 +-else +- result=0 +-fi +- +-rm "$tmp" +-exit $result +diff -urN glibc-2.17-c758a686/sysdeps/x86/tst-xmmymmzmm.sh glibc-2.17-c758a686/sysdeps/x86/tst-xmmymmzmm.sh +--- glibc-2.17-c758a686/sysdeps/x86/tst-xmmymmzmm.sh 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/x86/tst-xmmymmzmm.sh 2014-09-11 16:05:10.073426623 -0400 +@@ -0,0 +1,103 @@ ++#! /bin/bash ++# Make sure no code in ld.so uses xmm/ymm/zmm registers on x86-64. ++# Copyright (C) 2009-2012 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++set -e ++ ++objpfx="$1" ++NM="$2" ++OBJDUMP="$3" ++READELF="$4" ++ ++tmp=$(mktemp ${objpfx}tst-xmmymmzmm.XXXXXX) ++trap 'rm -f "$tmp"' 1 2 3 15 ++ ++# List of object files we have to test ++rtldobjs=$($READELF -W -wi ${objpfx}dl-allobjs.os | ++ awk '/^ "$tmp" ++declare -a objects ++objects=($(cat "$tmp")) ++ ++objs="dl-runtime.os" ++tocheck="dl-runtime.os" ++ ++while test -n "$objs"; do ++ this="$objs" ++ objs="" ++ ++ for f in $this; do ++ undef=$($NM -u "$objpfx"../*/"$f" | awk '{print $2}') ++ if test -n "$undef"; then ++ for s in $undef; do ++ for obj in ${objects[*]} "_GLOBAL_OFFSET_TABLE_"; do ++ if test "$obj" = "$s"; then ++ continue 2 ++ fi ++ done ++ for o in $rtldobjs; do ++ ro=$(echo "$objpfx"../*/"$o") ++ if $NM -g --defined-only "$ro" | egrep -qs " $s\$"; then ++ if ! (echo "$tocheck $objs" | fgrep -qs "$o"); then ++ echo "$o needed for $s" ++ objs="$objs $o" ++ fi ++ break; ++ fi ++ done ++ done ++ fi ++ done ++ tocheck="$tocheck$objs" ++done ++ ++echo ++echo ++echo "object files needed: $tocheck" ++ ++cp /dev/null "$tmp" ++for f in $tocheck; do ++ $OBJDUMP -d "$objpfx"../*/"$f" | ++ awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xyz]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' | ++ while read fct; do ++ if test "$fct" = "_dl_runtime_profile" -o "$fct" = "_dl_x86_64_restore_sse"; then ++ continue; ++ fi ++ echo "function $fct in $f modifies xmm/ymm/zmm" >> "$tmp" ++ result=1 ++ done ++done ++ ++if test -s "$tmp"; then ++ echo ++ echo ++ cat "$tmp" ++ result=1 ++else ++ result=0 ++fi ++ ++rm "$tmp" ++exit $result diff --git a/SOURCES/glibc-rh1140474.patch b/SOURCES/glibc-rh1140474.patch new file mode 100644 index 00000000..2382b84d --- /dev/null +++ b/SOURCES/glibc-rh1140474.patch @@ -0,0 +1,154 @@ +commit 41488498b6d9440ee66ab033808cce8323bba7ac +Author: Florian Weimer +Date: Wed Sep 3 19:45:43 2014 +0200 + + CVE-2014-6040: Crashes on invalid input in IBM gconv modules [BZ #17325] + + These changes are based on the fix for BZ #14134 in commit + 6e230d11837f3ae7b375ea69d7905f0d18eb79e5. + +diff --git glibc-2.17-c758a686/iconvdata/Makefile glibc-2.17-c758a686/iconvdata/Makefile +index 0a410a1..b6327d6 100644 +--- glibc-2.17-c758a686/iconvdata/Makefile ++++ glibc-2.17-c758a686/iconvdata/Makefile +@@ -297,6 +297,7 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \ + $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) \ + $(common-objdir)/iconv/iconv_prog TESTS ++ iconv_modules="$(modules)" \ + $(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@ + + $(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \ +diff --git glibc-2.17-c758a686/iconvdata/ibm1364.c glibc-2.17-c758a686/iconvdata/ibm1364.c +index 0b5484f..cf80993 100644 +--- glibc-2.17-c758a686/iconvdata/ibm1364.c ++++ glibc-2.17-c758a686/iconvdata/ibm1364.c +@@ -221,7 +221,8 @@ enum + ++rp2; \ + \ + uint32_t res; \ +- if (__builtin_expect (ch < rp2->start, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ ++ || __builtin_expect (ch < rp2->start, 0) \ + || (res = DB_TO_UCS4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ + { \ +diff --git glibc-2.17-c758a686/iconvdata/ibm932.c glibc-2.17-c758a686/iconvdata/ibm932.c +index f5dca59..aa69d65 100644 +--- glibc-2.17-c758a686/iconvdata/ibm932.c ++++ glibc-2.17-c758a686/iconvdata/ibm932.c +@@ -74,11 +74,12 @@ + } \ + \ + ch = (ch * 0x100) + inptr[1]; \ ++ /* ch was less than 0xfd. */ \ ++ assert (ch < 0xfd00); \ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ +- || __builtin_expect (ch < rp2->start, 0) \ ++ if (__builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm932db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, '\1') == 0 && ch !=0)) \ + { \ +diff --git glibc-2.17-c758a686/iconvdata/ibm933.c glibc-2.17-c758a686/iconvdata/ibm933.c +index f46dfb5..461fb5e 100644 +--- glibc-2.17-c758a686/iconvdata/ibm933.c ++++ glibc-2.17-c758a686/iconvdata/ibm933.c +@@ -162,7 +162,7 @@ enum + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm933db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +diff --git glibc-2.17-c758a686/iconvdata/ibm935.c glibc-2.17-c758a686/iconvdata/ibm935.c +index a8e4e6c..132d816 100644 +--- glibc-2.17-c758a686/iconvdata/ibm935.c ++++ glibc-2.17-c758a686/iconvdata/ibm935.c +@@ -162,7 +162,7 @@ enum + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm935db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +diff --git glibc-2.17-c758a686/iconvdata/ibm937.c glibc-2.17-c758a686/iconvdata/ibm937.c +index 239be61..69b154d 100644 +--- glibc-2.17-c758a686/iconvdata/ibm937.c ++++ glibc-2.17-c758a686/iconvdata/ibm937.c +@@ -162,7 +162,7 @@ enum + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm937db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +diff --git glibc-2.17-c758a686/iconvdata/ibm939.c glibc-2.17-c758a686/iconvdata/ibm939.c +index 5d0db36..9936e2c 100644 +--- glibc-2.17-c758a686/iconvdata/ibm939.c ++++ glibc-2.17-c758a686/iconvdata/ibm939.c +@@ -162,7 +162,7 @@ enum + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ ++ if (__builtin_expect (rp2->start == 0xffff, 0) \ + || __builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm939db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, L'\1') == L'\0' && ch != '\0')) \ +diff --git glibc-2.17-c758a686/iconvdata/ibm943.c glibc-2.17-c758a686/iconvdata/ibm943.c +index be0c14f..c5d5742 100644 +--- glibc-2.17-c758a686/iconvdata/ibm943.c ++++ glibc-2.17-c758a686/iconvdata/ibm943.c +@@ -75,11 +75,12 @@ + } \ + \ + ch = (ch * 0x100) + inptr[1]; \ ++ /* ch was less than 0xfd. */ \ ++ assert (ch < 0xfd00); \ + while (ch > rp2->end) \ + ++rp2; \ + \ +- if (__builtin_expect (rp2 == NULL, 0) \ +- || __builtin_expect (ch < rp2->start, 0) \ ++ if (__builtin_expect (ch < rp2->start, 0) \ + || (res = __ibm943db_to_ucs4[ch + rp2->idx], \ + __builtin_expect (res, '\1') == 0 && ch !=0)) \ + { \ +diff --git glibc-2.17-c758a686/iconvdata/run-iconv-test.sh glibc-2.17-c758a686/iconvdata/run-iconv-test.sh +index c98c929..5dfb69f 100755 +--- glibc-2.17-c758a686/iconvdata/run-iconv-test.sh ++++ glibc-2.17-c758a686/iconvdata/run-iconv-test.sh +@@ -184,6 +184,24 @@ while read utf8 from filename; do + + done < TESTS2 + ++# Check for crashes in decoders. ++printf '\016\377\377\377\377\377\377\377' > $temp1 ++for from in $iconv_modules ; do ++ echo $ac_n "test decoder $from $ac_c" ++ PROG=`eval echo $ICONV` ++ if $PROG < $temp1 >/dev/null 2>&1 ; then ++ : # fall through ++ else ++ status=$? ++ if test $status -gt 1 ; then ++ echo "/FAILED" ++ failed=1 ++ continue ++ fi ++ fi ++ echo "OK" ++done ++ + exit $failed + # Local Variables: + # mode:shell-script diff --git a/SOURCES/glibc-rh1144133.patch b/SOURCES/glibc-rh1144133.patch new file mode 100644 index 00000000..360cbae0 --- /dev/null +++ b/SOURCES/glibc-rh1144133.patch @@ -0,0 +1,55 @@ +commit 62058ce612ed3459501b4c4332e268edfe977f59 +Author: Carlos O'Donell +Date: Mon Sep 29 13:14:21 2014 -0400 + + Correctly size profiling reloc table (bug 17411) + + During auditing or profiling modes the dynamic loader + builds a cache of the relocated PLT entries in order + to reuse them when called again through the same PLT + entry. This way the PLT entry is never completed and + the call into the resolver always results in profiling + or auditing code running. + + The problem is that the PLT relocation cache size + is not computed correctly. The size of the cache + should be "Size of a relocation result structure" + x "Number of PLT-related relocations". Instead the + code erroneously computes "Size of a relocation + result" x "Number of bytes worth of PLT-related + relocations". I can only assume this was a mistake + in the understanding of the value of DT_PLTRELSZ + which is the number of bytes of PLT-related relocs. + We do have a DT_RELACOUNT entry, which is a count + for dynamic relative relocs, but we have no + DT_PLTRELCOUNT and thus we need to compute it. + + This patch corrects the computation of the size of the + relocation table used by the glibc profiling code. + + For more details see: + https://sourceware.org/ml/libc-alpha/2014-09/msg00513.html + + [BZ #17411] + * elf/dl-reloc.c (_dl_relocate_object): Allocate correct amount for + l_reloc_result. + +diff --git glibc-2.17-c758a686/elf/dl-reloc.c glibc-2.17-c758a686/elf/dl-reloc.c +index d2c6dac..97a7119 100644 +--- glibc-2.17-c758a686/elf/dl-reloc.c ++++ glibc-2.17-c758a686/elf/dl-reloc.c +@@ -279,8 +279,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], + l->l_name); + } + +- l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), +- l->l_info[DT_PLTRELSZ]->d_un.d_val); ++ size_t sizeofrel = l->l_info[DT_PLTREL]->d_un.d_val == DT_RELA ++ ? sizeof (ElfW(Rela)) ++ : sizeof (ElfW(Rel)); ++ size_t relcount = l->l_info[DT_PLTRELSZ]->d_un.d_val / sizeofrel; ++ l->l_reloc_result = calloc (sizeof (l->l_reloc_result[0]), relcount); ++ + if (l->l_reloc_result == NULL) + { + errstring = N_("\ diff --git a/SOURCES/glibc-rh1144516.patch b/SOURCES/glibc-rh1144516.patch new file mode 100644 index 00000000..8c45e740 --- /dev/null +++ b/SOURCES/glibc-rh1144516.patch @@ -0,0 +1,47 @@ +commit cfa4df95003c963c16d2102aef9c806f8175f373 +Author: Marcus Shawcroft +Date: Tue Sep 24 12:59:06 2013 +0100 + + [AArch64] Adding sigcontextinfo.h + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h b/ports/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h +new file mode 100644 +index 0000000..42ff38e +--- /dev/null ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h +@@ -0,0 +1,35 @@ ++/* AArch64 definitions for signal handling calling conventions. ++ Copyright (C) 1996-2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include "kernel-features.h" ++ ++#define SIGCONTEXT siginfo_t *_si, struct ucontext * ++#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.pc) ++ ++/* There is no reliable way to get the sigcontext unless we use a ++ three-argument signal handler. */ ++#define __sigaction(sig, act, oact) ({ \ ++ (act)->sa_flags |= SA_SIGINFO; \ ++ (__sigaction) (sig, act, oact); \ ++}) ++ ++#define sigaction(sig, act, oact) ({ \ ++ (act)->sa_flags |= SA_SIGINFO; \ ++ (sigaction) (sig, act, oact); \ ++}) diff --git a/SOURCES/glibc-rh1150282.patch b/SOURCES/glibc-rh1150282.patch new file mode 100644 index 00000000..1db72327 --- /dev/null +++ b/SOURCES/glibc-rh1150282.patch @@ -0,0 +1,515 @@ +This patch provides a compatibility kludge for legacy applications +which do not provide proper stack alignment. It cannot be upstreamed. + +The kludge is active for both i386 and x86-64, but it is actually only +needed on i386. + +In Fedora, the same effect was achieved by disabling multi-arch +altogether: + + https://bugzilla.redhat.com/show_bug.cgi?id=1471427 + +Further discussion is on this internal bug: + + https://bugzilla.redhat.com/show_bug.cgi?id=1478332 + + +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c 2012-12-24 20:02:13.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c 2015-04-20 09:04:11.826569951 -0600 +@@ -212,6 +212,8 @@ + + /* Support sysdeps/x86_64/multiarch/strstr-c.c. */ + IFUNC_IMPL (i, name, strstr, ++ IFUNC_IMPL_ADD (array, i, strstr, use_unaligned_strstr (), ++ __strstr_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42) + IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2)) + +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.h 2012-12-24 20:02:13.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.h 2015-04-20 12:15:17.984742925 -0600 +@@ -63,6 +63,34 @@ + #else /* __ASSEMBLER__ */ + + # include ++# include ++# include ++# include ++ ++/* Ugly hack to make it possible to select a strstr and strcasestr ++ implementation that avoids using the stack for 16-byte aligned ++ SSE temporaries. Doing so makes it possible to call the functions ++ with a stack that's not 16-byte aligned as can happen, for example, ++ as a result of compiling the functions' callers with the GCC ++ -mpreferred-stack-boubdary=2 or =3 option, or with the ICC ++ -falign-stack=assume-4-byte option. See rhbz 1150282 for details. ++ ++ The ifunc selector uses the unaligned version by default if this ++ file exists and is accessible. */ ++# define ENABLE_STRSTR_UNALIGNED_PATHNAME \ ++ "/etc/sysconfig/64bit_strstr_via_64bit_strstr_sse2_unaligned" ++ ++static bool __attribute__ ((unused)) ++use_unaligned_strstr (void) ++{ ++ struct stat unaligned_strstr_etc_sysconfig_file; ++ ++ /* TLS may not have been set up yet, so avoid using stat since it tries to ++ set errno. */ ++ return INTERNAL_SYSCALL (stat, , 2, ++ ENABLE_STRSTR_UNALIGNED_PATHNAME, ++ &unaligned_strstr_etc_sysconfig_file) == 0; ++} + + enum + { +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile 2012-12-24 20:02:13.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile 2015-04-20 09:04:11.854569626 -0600 +@@ -17,7 +17,7 @@ + strcat-sse2-unaligned strncat-sse2-unaligned \ + strcat-ssse3 strncat-ssse3 strlen-sse2-pminub \ + strnlen-sse2-no-bsf strrchr-sse2-no-bsf strchr-sse2-no-bsf \ +- memcmp-ssse3 ++ memcmp-ssse3 strstr-sse2-unaligned + ifeq (yes,$(config-cflags-sse4)) + sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c varshift + CFLAGS-varshift.c += -msse4 +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c 2012-12-24 20:02:13.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c 2015-04-20 09:04:11.861569545 -0600 +@@ -12,7 +12,8 @@ + + #if 1 + libc_ifunc (__strcasestr, +- HAS_SSE4_2 ? __strcasestr_sse42 : __strcasestr_sse2); ++ HAS_SSE4_2 && !use_unaligned_strstr () ? __strcasestr_sse42 : ++ __strcasestr_sse2); + #else + libc_ifunc (__strcasestr, + 0 ? __strcasestr_sse42 : __strcasestr_sse2); +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c 2012-12-24 20:02:13.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c 2015-04-20 09:04:11.866569487 -0600 +@@ -34,6 +34,7 @@ + #include "string/strstr.c" + + extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden; ++extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden; + extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden; + + #include "init-arch.h" +@@ -41,7 +42,9 @@ + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + extern __typeof (__redirect_strstr) __libc_strstr; +-libc_ifunc (__libc_strstr, HAS_SSE4_2 ? __strstr_sse42 : __strstr_sse2) ++libc_ifunc (__libc_strstr, HAS_SSE4_2 ? (use_unaligned_strstr () ? ++ __strstr_sse2_unaligned : ++ __strstr_sse42) : __strstr_sse2) + + #undef strstr + strong_alias (__libc_strstr, strstr) +--- glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S 2015-04-20 09:04:11.866569487 -0600 +@@ -0,0 +1,374 @@ ++/* strstr with unaligned loads ++ Copyright (C) 2009-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++ENTRY(__strstr_sse2_unaligned) ++ movzbl (%rsi), %eax ++ testb %al, %al ++ je L(empty) ++ movzbl 1(%rsi), %edx ++ testb %dl, %dl ++ je L(strchr) ++ movd %eax, %xmm1 ++ movd %edx, %xmm2 ++ movq %rdi, %rax ++ andl $4095, %eax ++ punpcklbw %xmm1, %xmm1 ++ cmpq $4031, %rax ++ punpcklbw %xmm2, %xmm2 ++ punpcklwd %xmm1, %xmm1 ++ punpcklwd %xmm2, %xmm2 ++ pshufd $0, %xmm1, %xmm1 ++ pshufd $0, %xmm2, %xmm2 ++ ja L(cross_page) ++ movdqu (%rdi), %xmm3 ++ pxor %xmm5, %xmm5 ++ movdqu 1(%rdi), %xmm4 ++ movdqa %xmm3, %xmm6 ++ pcmpeqb %xmm1, %xmm3 ++ pcmpeqb %xmm2, %xmm4 ++ movdqu 16(%rdi), %xmm0 ++ pcmpeqb %xmm5, %xmm6 ++ pminub %xmm4, %xmm3 ++ movdqa %xmm3, %xmm4 ++ movdqu 17(%rdi), %xmm3 ++ pcmpeqb %xmm0, %xmm5 ++ pcmpeqb %xmm2, %xmm3 ++ por %xmm6, %xmm4 ++ pcmpeqb %xmm1, %xmm0 ++ pminub %xmm3, %xmm0 ++ por %xmm5, %xmm0 ++ pmovmskb %xmm4, %r8d ++ pmovmskb %xmm0, %eax ++ salq $16, %rax ++ orq %rax, %r8 ++ je L(next_32_bytes) ++L(next_pair_index): ++ bsf %r8, %rax ++ addq %rdi, %rax ++ cmpb $0, (%rax) ++ je L(zero1) ++ movzbl 2(%rsi), %edx ++ testb %dl, %dl ++ je L(found1) ++ cmpb 2(%rax), %dl ++ jne L(next_pair) ++ xorl %edx, %edx ++ jmp L(pair_loop_start) ++ ++ .p2align 4 ++L(strchr): ++ movzbl %al, %esi ++ jmp __strchr_sse2 ++ ++ .p2align 4 ++L(pair_loop): ++ addq $1, %rdx ++ cmpb 2(%rax,%rdx), %cl ++ jne L(next_pair) ++L(pair_loop_start): ++ movzbl 3(%rsi,%rdx), %ecx ++ testb %cl, %cl ++ jne L(pair_loop) ++L(found1): ++ ret ++L(zero1): ++ xorl %eax, %eax ++ ret ++ ++ .p2align 4 ++L(next_pair): ++ leaq -1(%r8), %rax ++ andq %rax, %r8 ++ jne L(next_pair_index) ++ ++ .p2align 4 ++L(next_32_bytes): ++ movdqu 32(%rdi), %xmm3 ++ pxor %xmm5, %xmm5 ++ movdqu 33(%rdi), %xmm4 ++ movdqa %xmm3, %xmm6 ++ pcmpeqb %xmm1, %xmm3 ++ pcmpeqb %xmm2, %xmm4 ++ movdqu 48(%rdi), %xmm0 ++ pcmpeqb %xmm5, %xmm6 ++ pminub %xmm4, %xmm3 ++ movdqa %xmm3, %xmm4 ++ movdqu 49(%rdi), %xmm3 ++ pcmpeqb %xmm0, %xmm5 ++ pcmpeqb %xmm2, %xmm3 ++ por %xmm6, %xmm4 ++ pcmpeqb %xmm1, %xmm0 ++ pminub %xmm3, %xmm0 ++ por %xmm5, %xmm0 ++ pmovmskb %xmm4, %eax ++ salq $32, %rax ++ pmovmskb %xmm0, %r8d ++ salq $48, %r8 ++ orq %rax, %r8 ++ je L(loop_header) ++L(next_pair2_index): ++ bsfq %r8, %rax ++ addq %rdi, %rax ++ cmpb $0, (%rax) ++ je L(zero2) ++ movzbl 2(%rsi), %edx ++ testb %dl, %dl ++ je L(found2) ++ cmpb 2(%rax), %dl ++ jne L(next_pair2) ++ xorl %edx, %edx ++ jmp L(pair_loop2_start) ++ ++ .p2align 4 ++L(pair_loop2): ++ addq $1, %rdx ++ cmpb 2(%rax,%rdx), %cl ++ jne L(next_pair2) ++L(pair_loop2_start): ++ movzbl 3(%rsi,%rdx), %ecx ++ testb %cl, %cl ++ jne L(pair_loop2) ++L(found2): ++ ret ++ L(zero2): ++ xorl %eax, %eax ++ ret ++L(empty): ++ mov %rdi, %rax ++ ret ++ ++ .p2align 4 ++L(next_pair2): ++ leaq -1(%r8), %rax ++ andq %rax, %r8 ++ jne L(next_pair2_index) ++L(loop_header): ++ movq $-512, %r11 ++ movq %rdi, %r9 ++ ++ pxor %xmm7, %xmm7 ++ andq $-64, %rdi ++ ++ .p2align 4 ++L(loop): ++ movdqa 64(%rdi), %xmm3 ++ movdqu 63(%rdi), %xmm6 ++ movdqa %xmm3, %xmm0 ++ pxor %xmm2, %xmm3 ++ pxor %xmm1, %xmm6 ++ movdqa 80(%rdi), %xmm10 ++ por %xmm3, %xmm6 ++ pminub %xmm10, %xmm0 ++ movdqu 79(%rdi), %xmm3 ++ pxor %xmm2, %xmm10 ++ pxor %xmm1, %xmm3 ++ movdqa 96(%rdi), %xmm9 ++ por %xmm10, %xmm3 ++ pminub %xmm9, %xmm0 ++ pxor %xmm2, %xmm9 ++ movdqa 112(%rdi), %xmm8 ++ addq $64, %rdi ++ pminub %xmm6, %xmm3 ++ movdqu 31(%rdi), %xmm4 ++ pminub %xmm8, %xmm0 ++ pxor %xmm2, %xmm8 ++ pxor %xmm1, %xmm4 ++ por %xmm9, %xmm4 ++ pminub %xmm4, %xmm3 ++ movdqu 47(%rdi), %xmm5 ++ pxor %xmm1, %xmm5 ++ por %xmm8, %xmm5 ++ pminub %xmm5, %xmm3 ++ pminub %xmm3, %xmm0 ++ pcmpeqb %xmm7, %xmm0 ++ pmovmskb %xmm0, %eax ++ testl %eax, %eax ++ je L(loop) ++ pminub (%rdi), %xmm6 ++ pminub 32(%rdi),%xmm4 ++ pminub 48(%rdi),%xmm5 ++ pcmpeqb %xmm7, %xmm6 ++ pcmpeqb %xmm7, %xmm5 ++ pmovmskb %xmm6, %edx ++ movdqa 16(%rdi), %xmm8 ++ pcmpeqb %xmm7, %xmm4 ++ movdqu 15(%rdi), %xmm0 ++ pmovmskb %xmm5, %r8d ++ movdqa %xmm8, %xmm3 ++ pmovmskb %xmm4, %ecx ++ pcmpeqb %xmm1,%xmm0 ++ pcmpeqb %xmm2,%xmm3 ++ salq $32, %rcx ++ pcmpeqb %xmm7,%xmm8 ++ salq $48, %r8 ++ pminub %xmm0,%xmm3 ++ orq %rcx, %rdx ++ por %xmm3,%xmm8 ++ orq %rdx, %r8 ++ pmovmskb %xmm8, %eax ++ salq $16, %rax ++ orq %rax, %r8 ++ je L(loop) ++L(next_pair_index3): ++ bsfq %r8, %rcx ++ addq %rdi, %rcx ++ cmpb $0, (%rcx) ++ je L(zero) ++ xorl %eax, %eax ++ movzbl 2(%rsi), %edx ++ testb %dl, %dl ++ je L(success3) ++ cmpb 1(%rcx), %dl ++ jne L(next_pair3) ++ jmp L(pair_loop_start3) ++ ++ .p2align 4 ++L(pair_loop3): ++ addq $1, %rax ++ cmpb 1(%rcx,%rax), %dl ++ jne L(next_pair3) ++L(pair_loop_start3): ++ movzbl 3(%rsi,%rax), %edx ++ testb %dl, %dl ++ jne L(pair_loop3) ++L(success3): ++ lea -1(%rcx), %rax ++ ret ++ ++ .p2align 4 ++L(next_pair3): ++ addq %rax, %r11 ++ movq %rdi, %rax ++ subq %r9, %rax ++ cmpq %r11, %rax ++ jl L(switch_strstr) ++ leaq -1(%r8), %rax ++ andq %rax, %r8 ++ jne L(next_pair_index3) ++ jmp L(loop) ++ ++ .p2align 4 ++L(switch_strstr): ++ movq %rdi, %rdi ++ jmp __strstr_sse2 ++ ++ .p2align 4 ++L(cross_page): ++ ++ movq %rdi, %rax ++ pxor %xmm0, %xmm0 ++ andq $-64, %rax ++ movdqa (%rax), %xmm3 ++ movdqu -1(%rax), %xmm4 ++ movdqa %xmm3, %xmm8 ++ movdqa 16(%rax), %xmm5 ++ pcmpeqb %xmm1, %xmm4 ++ pcmpeqb %xmm0, %xmm8 ++ pcmpeqb %xmm2, %xmm3 ++ movdqa %xmm5, %xmm7 ++ pminub %xmm4, %xmm3 ++ movdqu 15(%rax), %xmm4 ++ pcmpeqb %xmm0, %xmm7 ++ por %xmm3, %xmm8 ++ movdqa %xmm5, %xmm3 ++ movdqa 32(%rax), %xmm5 ++ pcmpeqb %xmm1, %xmm4 ++ pcmpeqb %xmm2, %xmm3 ++ movdqa %xmm5, %xmm6 ++ pmovmskb %xmm8, %ecx ++ pminub %xmm4, %xmm3 ++ movdqu 31(%rax), %xmm4 ++ por %xmm3, %xmm7 ++ movdqa %xmm5, %xmm3 ++ pcmpeqb %xmm0, %xmm6 ++ movdqa 48(%rax), %xmm5 ++ pcmpeqb %xmm1, %xmm4 ++ pmovmskb %xmm7, %r8d ++ pcmpeqb %xmm2, %xmm3 ++ pcmpeqb %xmm5, %xmm0 ++ pminub %xmm4, %xmm3 ++ movdqu 47(%rax), %xmm4 ++ por %xmm3, %xmm6 ++ movdqa %xmm5, %xmm3 ++ salq $16, %r8 ++ pcmpeqb %xmm1, %xmm4 ++ pcmpeqb %xmm2, %xmm3 ++ pmovmskb %xmm6, %r10d ++ pminub %xmm4, %xmm3 ++ por %xmm3, %xmm0 ++ salq $32, %r10 ++ orq %r10, %r8 ++ orq %rcx, %r8 ++ movl %edi, %ecx ++ pmovmskb %xmm0, %edx ++ subl %eax, %ecx ++ salq $48, %rdx ++ orq %rdx, %r8 ++ shrq %cl, %r8 ++ je L(loop_header) ++L(next_pair_index4): ++ bsfq %r8, %rax ++ addq %rdi, %rax ++ cmpb $0, (%rax) ++ je L(zero) ++ ++ cmpq %rax,%rdi ++ je L(next_pair4) ++ ++ movzbl 2(%rsi), %edx ++ testb %dl, %dl ++ je L(found3) ++ cmpb 1(%rax), %dl ++ jne L(next_pair4) ++ xorl %edx, %edx ++ jmp L(pair_loop_start4) ++ ++ .p2align 4 ++L(pair_loop4): ++ addq $1, %rdx ++ cmpb 1(%rax,%rdx), %cl ++ jne L(next_pair4) ++L(pair_loop_start4): ++ movzbl 3(%rsi,%rdx), %ecx ++ testb %cl, %cl ++ jne L(pair_loop4) ++L(found3): ++ subq $1, %rax ++ ret ++ ++ .p2align 4 ++L(next_pair4): ++ leaq -1(%r8), %rax ++ andq %rax, %r8 ++ jne L(next_pair_index4) ++ jmp L(loop_header) ++ ++ .p2align 4 ++L(found): ++ rep ++ ret ++ ++ .p2align 4 ++L(zero): ++ xorl %eax, %eax ++ ret ++ ++ ++END(__strstr_sse2_unaligned) +--- glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c 2012-12-24 20:02:13.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c 2015-04-20 09:04:11.876569371 -0600 +@@ -1,8 +1,6 @@ + /* Multiple versions of strstr + All versions must be listed in ifunc-impl-list.c. */ + +-#include "init-arch.h" +- + #define STRSTR __strstr_ia32 + #if defined SHARED && defined DO_VERSIONING && !defined NO_HIDDEN + #undef libc_hidden_builtin_def +@@ -17,13 +15,17 @@ + + #include "string/strstr.c" + ++#include "init-arch.h" ++ + extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden; + extern __typeof (__redirect_strstr) __strstr_ia32 attribute_hidden; + + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + extern __typeof (__redirect_strstr) __libc_strstr; +-libc_ifunc (__libc_strstr, HAS_SSE4_2 ? __strstr_sse42 : __strstr_ia32) ++libc_ifunc (__libc_strstr, ++ HAS_SSE4_2 && !use_unaligned_strstr () ? ++ __strstr_sse42 : __strstr_ia32) + + #undef strstr + strong_alias (__libc_strstr, strstr) diff --git a/SOURCES/glibc-rh1156331.patch b/SOURCES/glibc-rh1156331.patch new file mode 100644 index 00000000..bc669bb2 --- /dev/null +++ b/SOURCES/glibc-rh1156331.patch @@ -0,0 +1,202 @@ +commit be349d7042de84c3c5157a5c1fbcad580aed33e1 +Author: Siddhesh Poyarekar +Date: Thu Dec 4 08:08:37 2014 +0530 + + ftell: seek to end only when there are unflushed bytes (BZ #17647) + + Currently we seek to end of file if there are unflushed writes or the + stream is in write mode, to get the current offset for writing in + append mode, which is the end of file. The latter case (i.e. stream + is in write mode, but no unflushed writes) is unnecessary since it + will only happen when the stream has just been flushed, in which case + the recorded offset ought to be reliable. + + Removing that case lets ftell give the correct offset when it follows + an ftruncate. The latter truncates the file, but does not change the + file position, due to which it is permissible to call ftell without an + intervening fseek call. + + Tested on x86_64 to verify that the added test case fails without the + patch and succeeds with it, and that there are no additional + regressions due to it. + + [BZ #17647] + * libio/fileops.c (do_ftell): Seek only when there are + unflushed writes. + * libio/wfileops.c (do_ftell_wide): Likewise. + * libio/tst-ftell-active-handler.c (do_ftruncate_test): New + test case. + (do_one_test): Call it. + +diff --git glibc-2.17-c758a686/libio/fileops.c glibc-2.17-c758a686/libio/fileops.c +index e0d7b76..1fc5719 100644 +--- glibc-2.17-c758a686/libio/fileops.c ++++ glibc-2.17-c758a686/libio/fileops.c +@@ -943,15 +943,14 @@ do_ftell (_IO_FILE *fp) + yet. */ + if (fp->_IO_buf_base != NULL) + { +- bool was_writing = (fp->_IO_write_ptr > fp->_IO_write_base +- || _IO_in_put_mode (fp)); ++ bool unflushed_writes = (fp->_IO_write_ptr > fp->_IO_write_base); + + bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING; + + /* When we have unflushed writes in append mode, seek to the end of the + file and record that offset. This is the only time we change the file + stream state and it is safe since the file handle is active. */ +- if (was_writing && append_mode) ++ if (unflushed_writes && append_mode) + { + result = _IO_SYSSEEK (fp, 0, _IO_seek_end); + if (result == _IO_pos_BAD) +@@ -961,7 +960,7 @@ do_ftell (_IO_FILE *fp) + } + + /* Adjust for unflushed data. */ +- if (!was_writing) ++ if (!unflushed_writes) + offset -= fp->_IO_read_end - fp->_IO_read_ptr; + /* We don't trust _IO_read_end to represent the current file offset when + writing in append mode because the value would have to be shifted to +diff --git glibc-2.17-c758a686/libio/tst-ftell-active-handler.c glibc-2.17-c758a686/libio/tst-ftell-active-handler.c +index e9dc7b3..9f23c55 100644 +--- glibc-2.17-c758a686/libio/tst-ftell-active-handler.c ++++ glibc-2.17-c758a686/libio/tst-ftell-active-handler.c +@@ -88,6 +88,95 @@ static size_t file_len; + typedef int (*fputs_func_t) (const void *data, FILE *fp); + fputs_func_t fputs_func; + ++/* This test verifies that the offset reported by ftell is correct after the ++ file is truncated using ftruncate. ftruncate does not change the file ++ offset on truncation and hence, SEEK_CUR should continue to point to the ++ old offset and not be changed to the new offset. */ ++static int ++do_ftruncate_test (const char *filename) ++{ ++ FILE *fp = NULL; ++ int fd; ++ int ret = 0; ++ struct test ++ { ++ const char *mode; ++ int fd_mode; ++ } test_modes[] = { ++ {"r+", O_RDWR}, ++ {"w", O_WRONLY}, ++ {"w+", O_RDWR}, ++ {"a", O_WRONLY}, ++ {"a+", O_RDWR} ++ }; ++ ++ for (int j = 0; j < 2; j++) ++ { ++ for (int i = 0; i < sizeof (test_modes) / sizeof (struct test); i++) ++ { ++ int fileret; ++ printf ("\tftruncate: %s (file, \"%s\"): ", ++ j == 0 ? "fopen" : "fdopen", ++ test_modes[i].mode); ++ ++ if (j == 0) ++ fileret = get_handles_fopen (filename, fd, fp, test_modes[i].mode); ++ else ++ fileret = get_handles_fdopen (filename, fd, fp, ++ test_modes[i].fd_mode, ++ test_modes[i].mode); ++ ++ if (fileret != 0) ++ return fileret; ++ ++ /* Write some data. */ ++ size_t written = fputs_func (data, fp); ++ ++ if (written == EOF) ++ { ++ printf ("fputs[1] failed to write data\n"); ++ ret |= 1; ++ } ++ ++ /* Record the offset. */ ++ long offset = ftell (fp); ++ ++ /* Flush data to allow switching active handles. */ ++ if (fflush (fp)) ++ { ++ printf ("Flush failed: %m\n"); ++ ret |= 1; ++ } ++ ++ /* Now truncate the file. */ ++ if (ftruncate (fd, 0) != 0) ++ { ++ printf ("Failed to truncate file: %m\n"); ++ ret |= 1; ++ } ++ ++ /* ftruncate does not change the offset, so there is no need to call ++ anything to be able to switch active handles. */ ++ long new_offset = ftell (fp); ++ ++ /* The offset should remain unchanged since ftruncate does not update ++ it. */ ++ if (offset != new_offset) ++ { ++ printf ("Incorrect offset. Expected %zu, but got %ld\n", ++ offset, new_offset); ++ ++ ret |= 1; ++ } ++ else ++ printf ("offset = %ld\n", offset); ++ ++ fclose (fp); ++ } ++ } ++ ++ return ret; ++} + /* Test that ftell output after a rewind is correct. */ + static int + do_rewind_test (const char *filename) +@@ -481,6 +570,7 @@ do_one_test (const char *filename) + ret |= do_write_test (filename); + ret |= do_append_test (filename); + ret |= do_rewind_test (filename); ++ ret |= do_ftruncate_test (filename); + + return ret; + } +diff --git glibc-2.17-c758a686/libio/wfileops.c glibc-2.17-c758a686/libio/wfileops.c +index 6a088b1..71281c1 100644 +--- glibc-2.17-c758a686/libio/wfileops.c ++++ glibc-2.17-c758a686/libio/wfileops.c +@@ -626,16 +626,15 @@ do_ftell_wide (_IO_FILE *fp) + const wchar_t *wide_read_base; + const wchar_t *wide_read_ptr; + const wchar_t *wide_read_end; +- bool was_writing = ((fp->_wide_data->_IO_write_ptr +- > fp->_wide_data->_IO_write_base) +- || _IO_in_put_mode (fp)); ++ bool unflushed_writes = (fp->_wide_data->_IO_write_ptr ++ > fp->_wide_data->_IO_write_base); + + bool append_mode = (fp->_flags & _IO_IS_APPENDING) == _IO_IS_APPENDING; + + /* When we have unflushed writes in append mode, seek to the end of the + file and record that offset. This is the only time we change the file + stream state and it is safe since the file handle is active. */ +- if (was_writing && append_mode) ++ if (unflushed_writes && append_mode) + { + result = _IO_SYSSEEK (fp, 0, _IO_seek_end); + if (result == _IO_pos_BAD) +@@ -674,7 +673,7 @@ do_ftell_wide (_IO_FILE *fp) + struct _IO_codecvt *cv = fp->_codecvt; + int clen = (*cv->__codecvt_do_encoding) (cv); + +- if (!was_writing) ++ if (!unflushed_writes) + { + if (clen > 0) + { diff --git a/SOURCES/glibc-rh1159169.patch b/SOURCES/glibc-rh1159169.patch new file mode 100644 index 00000000..b03006c3 --- /dev/null +++ b/SOURCES/glibc-rh1159169.patch @@ -0,0 +1,41 @@ +commit ed6b0fe710b631b99ed9fc28cefedfe69a16dc55 +Author: Brad Hubbard +Date: Wed Mar 18 14:51:26 2015 +0530 + + Use calloc to allocate xports (BZ #17542) + + If xports is NULL in xprt_register we malloc it but if sock > + _rpc_dtablesize() that memory does not get initialised and may in theory + contain any value. Later we make a conditional jump in svc_getreq_common + based on the uninitialised memory and this caused a general protection + fault in rpc.statd on an older version of glibc but this code has not + changed since that version. + + Following is the valgrind warning. + + ==26802== Conditional jump or move depends on uninitialised value(s) + ==26802== at 0x5343A25: svc_getreq_common (in /lib64/libc-2.5.so) + ==26802== by 0x534357B: svc_getreqset (in /lib64/libc-2.5.so) + ==26802== by 0x10DE1F: ??? (in /sbin/rpc.statd) + ==26802== by 0x10D0EF: main (in /sbin/rpc.statd) + ==26802== Uninitialised value was created by a heap allocation + ==26802== at 0x4C2210C: malloc (vg_replace_malloc.c:195) + ==26802== by 0x53438BE: xprt_register (in /lib64/libc-2.5.so) + ==26802== by 0x53450DF: svcudp_bufcreate (in /lib64/libc-2.5.so) + ==26802== by 0x10FE32: ??? (in /sbin/rpc.statd) + ==26802== by 0x10D13E: main (in /sbin/rpc.statd) + +diff --git glibc-2.17-c758a686/sunrpc/svc.c glibc-2.17-c758a686/sunrpc/svc.c +index 8c4e8a5..c6ccf10 100644 +--- glibc-2.17-c758a686/sunrpc/svc.c ++++ glibc-2.17-c758a686/sunrpc/svc.c +@@ -97,8 +97,8 @@ xprt_register (SVCXPRT *xprt) + + if (xports == NULL) + { +- xports = (SVCXPRT **) malloc (_rpc_dtablesize () * sizeof (SVCXPRT *)); +- if (xports == NULL) /* Don´t add handle */ ++ xports = (SVCXPRT **) calloc (_rpc_dtablesize (), sizeof (SVCXPRT *)); ++ if (xports == NULL) /* Don't add handle */ + return; + } diff --git a/SOURCES/glibc-rh1161666.patch b/SOURCES/glibc-rh1161666.patch new file mode 100644 index 00000000..96a75411 --- /dev/null +++ b/SOURCES/glibc-rh1161666.patch @@ -0,0 +1,125 @@ +commit 533bb7c2ae156ff2d49b2e0b20b33810ba5e2721 +Author: Siddhesh Poyarekar +Date: Wed Nov 12 19:30:24 2014 +0530 + + Fix stack alignment when loader is invoked directly + + The s390 ABI requires the stack pointer to be aligned at 8-bytes. + When a program is invoked as an argument to the dynamic linker, + _dl_start_user adjusts the stack to remove the dynamic linker + arguments so that the program sees only its name and arguments. This + may result in the stack being misaligned since each argument shift is + only a word and not a double-word. + + This is now fixed shifting argv and envp down instead of shifting argc + up and reclaiming the stack. This requires _dl_argv to be adjusted + and hence, is no longer relro. + +diff --git glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-machine.h glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-machine.h +index c56185c..79f8ef9 100644 +--- glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-machine.h ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-machine.h +@@ -166,18 +166,49 @@ _dl_start_user:\n\ + # See if we were run as a command with the executable file\n\ + # name as an extra leading argument.\n\ + l %r1,_dl_skip_args@GOT12(0,%r12)\n\ +- l %r1,0(%r1) # load _dl_skip_args\n\ ++ l %r1,0(%r1) # load _dl_skip_args\n\ ++ ltr %r1,%r1\n\ ++ je .L4 # Skip the arg adjustment if there were none.\n\ + # Get the original argument count.\n\ + l %r0,96(%r15)\n\ + # Subtract _dl_skip_args from it.\n\ + sr %r0,%r1\n\ +- # Adjust the stack pointer to skip _dl_skip_args words.\n\ +- sll %r1,2\n\ +- ar %r15,%r1\n\ +- # Set the back chain to zero again\n\ +- xc 0(4,%r15),0(%r15)\n\ + # Store back the modified argument count.\n\ + st %r0,96(%r15)\n\ ++ # Copy argv and envp forward to account for skipped argv entries.\n\ ++ # We skipped at least one argument or we would not get here.\n\ ++ la %r6,100(%r15) # Destination pointer i.e. &argv[0]\n\ ++ lr %r5,%r6\n\ ++ lr %r0,%r1\n\ ++ sll %r0,2\n # Number of skipped bytes.\n\ ++ ar %r5,%r0 # Source pointer = Dest + Skipped args.\n\ ++ # argv copy loop:\n\ ++.L1: l %r7,0(%r5) # Load a word from the source.\n\ ++ st %r7,0(%r6) # Store the word in the destination.\n\ ++ ahi %r5,4\n\ ++ ahi %r6,4\n\ ++ ltr %r7,%r7\n\ ++ jne .L1 # Stop after copying the NULL.\n\ ++ # envp copy loop:\n\ ++.L2: l %r7,0(%r5) # Load a word from the source.\n\ ++ st %r7,0(%r6) # Store the word in the destination.\n\ ++ ahi %r5,4\n\ ++ ahi %r6,4\n\ ++ ltr %r7,%r7\n\ ++ jne .L2 # Stop after copying the NULL.\n\ ++ # Now we have to zero out the envp entries after NULL to allow\n\ ++ # start.S to properly find auxv by skipping zeroes.\n\ ++ # zero out loop:\n\ ++ lhi %r7,0\n\ ++.L3: st %r7,0(%r6) # Store zero.\n\ ++ ahi %r6,4 # Advance dest pointer.\n\ ++ ahi %r1,-1 # Subtract one from the word count.\n\ ++ ltr %r1,%r1\n\ ++ jne .L3 # Keep copying if the word count is non-zero.\n\ ++ # Adjust _dl_argv\n\ ++ la %r6,100(%r15)\n\ ++ l %r1,_dl_argv@GOT12(0,%r12)\n\ ++ st %r6,0(%r1)\n\ + # The special initializer gets called with the stack just\n\ + # as the application's entry point will see it; it can\n\ + # switch stacks if it moves these contents over.\n\ +@@ -185,7 +216,7 @@ _dl_start_user:\n\ + # Call the function to run the initializers.\n\ + # Load the parameters:\n\ + # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\ +- l %r2,_rtld_local@GOT(%r12)\n\ ++.L4: l %r2,_rtld_local@GOT(%r12)\n\ + l %r2,0(%r2)\n\ + l %r3,96(%r15)\n\ + la %r4,100(%r15)\n\ +@@ -198,6 +229,9 @@ _dl_start_user:\n\ + l %r14,_dl_fini@GOT(%r12)\n\ + # Free stack frame\n\ + ahi %r15,96\n\ ++ # Reload argc and argv for the user's entry point.\n\ ++ # l %r2,0(%r15)\n\ ++ # la %r3,4(%r15)\n\ + # Jump to the user's entry point (saved in %r8).\n\ + br %r8\n\ + .Llit:\n\ +diff --git glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-sysdep.h glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-sysdep.h +new file mode 100644 +index 0000000..b992778 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-sysdep.h +@@ -0,0 +1,23 @@ ++/* System-specific settings for dynamic linker code. S/390 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include_next ++ ++/* _dl_argv cannot be attribute_relro, because _dl_start_user ++ might write into it after _dl_start returns. */ ++#define DL_ARGV_NOT_RELRO 1 diff --git a/SOURCES/glibc-rh1162847-p1.patch b/SOURCES/glibc-rh1162847-p1.patch new file mode 100644 index 00000000..2b417a99 --- /dev/null +++ b/SOURCES/glibc-rh1162847-p1.patch @@ -0,0 +1,104 @@ +# +# commit f8e3e9f31bfd71641418897228fa1732170b69cc +# Author: Alan Modra +# Date: Thu Oct 3 13:51:52 2013 +0930 +# +# Correct little-endian relocation of UADDR64,32,16. +# +# * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela): +# Correct handling of unaligned relocs for little-endian. +# * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): Likewise. +# +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c 2014-11-11 18:51:36.140570654 -0500 +@@ -423,6 +423,12 @@ + Elf32_Addr const finaladdr, + int rinfo) + { ++ union unaligned ++ { ++ unsigned u2 __attribute__ ((mode (HI))); ++ unsigned u4 __attribute__ ((mode (SI))); ++ } __attribute__((__packed__)); ++ + switch (rinfo) + { + case R_PPC_NONE: +@@ -439,10 +445,7 @@ + return; + + case R_PPC_UADDR32: +- ((char *) reloc_addr)[0] = finaladdr >> 24; +- ((char *) reloc_addr)[1] = finaladdr >> 16; +- ((char *) reloc_addr)[2] = finaladdr >> 8; +- ((char *) reloc_addr)[3] = finaladdr; ++ ((union unaligned *) reloc_addr)->u4 = finaladdr; + break; + + case R_PPC_ADDR24: +@@ -460,8 +463,7 @@ + case R_PPC_UADDR16: + if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0)) + _dl_reloc_overflow (map, "R_PPC_UADDR16", reloc_addr, refsym); +- ((char *) reloc_addr)[0] = finaladdr >> 8; +- ((char *) reloc_addr)[1] = finaladdr; ++ ((union unaligned *) reloc_addr)->u2 = finaladdr; + break; + + case R_PPC_ADDR16_LO: +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h 2014-11-11 18:51:36.141570651 -0500 +@@ -561,6 +561,12 @@ + Elf64_Addr *const reloc_addr = reloc_addr_arg; + const int r_type = ELF64_R_TYPE (reloc->r_info); + const Elf64_Sym *const refsym = sym; ++ union unaligned ++ { ++ unsigned u2 __attribute__ ((mode (HI))); ++ unsigned u4 __attribute__ ((mode (SI))); ++ unsigned u8 __attribute__ ((mode (DI))); ++ } __attribute__((__packed__)); + + if (r_type == R_PPC64_RELATIVE) + { +@@ -742,23 +748,11 @@ + return; + + case R_PPC64_UADDR64: +- /* We are big-endian. */ +- ((char *) reloc_addr_arg)[0] = (value >> 56) & 0xff; +- ((char *) reloc_addr_arg)[1] = (value >> 48) & 0xff; +- ((char *) reloc_addr_arg)[2] = (value >> 40) & 0xff; +- ((char *) reloc_addr_arg)[3] = (value >> 32) & 0xff; +- ((char *) reloc_addr_arg)[4] = (value >> 24) & 0xff; +- ((char *) reloc_addr_arg)[5] = (value >> 16) & 0xff; +- ((char *) reloc_addr_arg)[6] = (value >> 8) & 0xff; +- ((char *) reloc_addr_arg)[7] = (value >> 0) & 0xff; ++ ((union unaligned *) reloc_addr)->u8 = value; + return; + + case R_PPC64_UADDR32: +- /* We are big-endian. */ +- ((char *) reloc_addr_arg)[0] = (value >> 24) & 0xff; +- ((char *) reloc_addr_arg)[1] = (value >> 16) & 0xff; +- ((char *) reloc_addr_arg)[2] = (value >> 8) & 0xff; +- ((char *) reloc_addr_arg)[3] = (value >> 0) & 0xff; ++ ((union unaligned *) reloc_addr)->u4 = value; + return; + + case R_PPC64_ADDR32: +@@ -782,10 +776,8 @@ + case R_PPC64_UADDR16: + if (dont_expect ((value + 0x8000) >= 0x10000)) + _dl_reloc_overflow (map, "R_PPC64_UADDR16", reloc_addr, refsym); +- /* We are big-endian. */ +- ((char *) reloc_addr_arg)[0] = (value >> 8) & 0xff; +- ((char *) reloc_addr_arg)[1] = (value >> 0) & 0xff; +- break; ++ ((union unaligned *) reloc_addr)->u2 = value; ++ return; + + case R_PPC64_ADDR16_DS: + if (dont_expect ((value + 0x8000) >= 0x10000 || (value & 3) != 0)) diff --git a/SOURCES/glibc-rh1162847-p2.patch b/SOURCES/glibc-rh1162847-p2.patch new file mode 100644 index 00000000..895aca5a --- /dev/null +++ b/SOURCES/glibc-rh1162847-p2.patch @@ -0,0 +1,45 @@ +# +# commit 4cb81307b3771672864fa3a7498bd39c13267a00 +# Author: Alan Modra +# Date: Fri Oct 4 12:48:51 2013 +0930 +# +# Use stdint.h types in union unaligned. +# +# * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela): +# Use stdint types in rather than __attribute__((mode())). +# * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): Likewise. +# +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c +index f81899a..aba3618 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/dl-machine.c +@@ -418,8 +418,8 @@ __process_machine_rela (struct link_map *map, + { + union unaligned + { +- unsigned u2 __attribute__ ((mode (HI))); +- unsigned u4 __attribute__ ((mode (SI))); ++ uint16_t u2; ++ uint32_t u4; + } __attribute__((__packed__)); + + switch (rinfo) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +index b69a1ce..18cf157 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/dl-machine.h +@@ -563,10 +563,10 @@ elf_machine_rela (struct link_map *map, + const Elf64_Sym *const refsym = sym; + union unaligned + { +- unsigned u2 __attribute__ ((mode (HI))); +- unsigned u4 __attribute__ ((mode (SI))); +- unsigned u8 __attribute__ ((mode (DI))); +- } __attribute__((__packed__)); ++ uint16_t u2; ++ uint32_t u4; ++ uint64_t u8; ++ } __attribute__ ((__packed__)); + + if (r_type == R_PPC64_RELATIVE) + { diff --git a/SOURCES/glibc-rh1162895-1.patch b/SOURCES/glibc-rh1162895-1.patch new file mode 100644 index 00000000..baf93e92 --- /dev/null +++ b/SOURCES/glibc-rh1162895-1.patch @@ -0,0 +1,23 @@ +commit f6c44d475104e931bab2b4ffa499961088de673c +Author: Alan Modra +Date: Mon Jul 14 21:14:50 2014 +0930 + + Correct DT_PPC64_NUM + + [BZ #17153] + * elf/elf.h (DT_PPC64_NUM): Correct value. + * NEWS: Add to fixed bug list. + +diff --git glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h +index 40e87b2..78815e8 100644 +--- glibc-2.17-c758a686/elf/elf.h ++++ glibc-2.17-c758a686/elf/elf.h +@@ -2283,7 +2283,7 @@ typedef Elf32_Addr Elf32_Conflict; + #define DT_PPC64_OPD (DT_LOPROC + 1) + #define DT_PPC64_OPDSZ (DT_LOPROC + 2) + #define DT_PPC64_OPT (DT_LOPROC + 3) +-#define DT_PPC64_NUM 3 ++#define DT_PPC64_NUM 4 + + /* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */ + #define PPC64_OPT_TLS 1 diff --git a/SOURCES/glibc-rh1162895-2.patch b/SOURCES/glibc-rh1162895-2.patch new file mode 100644 index 00000000..e80750f6 --- /dev/null +++ b/SOURCES/glibc-rh1162895-2.patch @@ -0,0 +1,200 @@ +commit aa5f0ff11ad2cc85277c64cf65c723a9664e1149 +Author: Alan Modra +Date: Wed Apr 16 19:33:32 2014 +0930 + + Correct IBM long double frexpl. + + Besides fixing the bugzilla, this also fixes corner-cases where the high + and low double differ greatly in magnitude, and handles a denormal + input without resorting to a fp rescale. + + [BZ #16740] + [BZ #16619] + * sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Rewrite. + * math/libm-test.inc (frexp_test_data): Add tests. + +diff --git glibc-2.17-c758a686/math/libm-test.inc glibc-2.17-c758a686/math/libm-test.inc +index 5e6789f..a4bf0b8 100644 +--- glibc-2.17-c758a686/math/libm-test.inc ++++ glibc-2.17-c758a686/math/libm-test.inc +@@ -5691,6 +5691,15 @@ frexp_test (void) + TEST_fI_f1 (frexp, 12.8L, 0.8L, 4); + TEST_fI_f1 (frexp, -27.34L, -0.854375L, 5); + ++#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 ++ TEST_fI_f1 (frexp, 1.0L-0x1p-106L, 1.0L-0x1p-106L, 0), ++ TEST_fI_f1 (frexp, 1.0L, 0.5L, 1), ++ TEST_fI_f1 (frexp, 1.0L+0x1p-105L, 0.5L+0x1p-106L, 1), ++ TEST_fI_f1 (frexp, -1.0L+0x1p-106L, -1.0L+0x1p-106L, 0), ++ TEST_fI_f1 (frexp, -1.0L, -0.5L, 1), ++ TEST_fI_f1 (frexp, -1.0L-0x1p-105L, -0.5L-0x1p-106L, 1), ++#endif ++ + END (frexp); + } + +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c 2015-06-16 15:37:44.293960271 -0400 ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c 2015-06-16 13:53:25.578700428 -0400 +@@ -31,57 +31,115 @@ + #include + #include + +-static const long double +-two107 = 162259276829213363391578010288128.0; /* 0x4670000000000000, 0 */ +- + long double __frexpl(long double x, int *eptr) + { +- uint64_t hx, lx, ix, ixl; +- int64_t explo; +- double xhi, xlo; +- +- ldbl_unpack (x, &xhi, &xlo); +- EXTRACT_WORDS64 (hx, xhi); +- EXTRACT_WORDS64 (lx, xlo); +- ixl = 0x7fffffffffffffffULL&lx; +- ix = 0x7fffffffffffffffULL&hx; +- *eptr = 0; +- if(ix>=0x7ff0000000000000ULL||ix==0) return x; /* 0,inf,nan */ +- if (ix<0x0010000000000000ULL) { /* subnormal */ +- x *= two107; +- xhi = ldbl_high (x); +- EXTRACT_WORDS64 (hx, xhi); +- ix = hx&0x7fffffffffffffffULL; +- *eptr = -107; ++ uint64_t hx, lx, ix, ixl; ++ int64_t explo, expon; ++ double xhi, xlo; ++ ++ ldbl_unpack (x, &xhi, &xlo); ++ EXTRACT_WORDS64 (hx, xhi); ++ EXTRACT_WORDS64 (lx, xlo); ++ ixl = 0x7fffffffffffffffULL & lx; ++ ix = 0x7fffffffffffffffULL & hx; ++ expon = 0; ++ if (ix >= 0x7ff0000000000000ULL || ix == 0) ++ { ++ /* 0,inf,nan. */ ++ *eptr = expon; ++ return x; ++ } ++ expon = ix >> 52; ++ if (expon == 0) ++ { ++ /* Denormal high double, the low double must be 0.0. */ ++ int cnt; ++ ++ /* Normalize. */ ++ if (sizeof (ix) == sizeof (long)) ++ cnt = __builtin_clzl (ix); ++ else if ((ix >> 32) != 0) ++ cnt = __builtin_clzl ((long) (ix >> 32)); ++ else ++ cnt = __builtin_clzl ((long) ix) + 32; ++ cnt = cnt - 12; ++ expon -= cnt; ++ ix <<= cnt + 1; ++ } ++ expon -= 1022; ++ ix &= 0x000fffffffffffffULL; ++ hx &= 0x8000000000000000ULL; ++ hx |= (1022LL << 52) | ix; ++ ++ if (ixl != 0) ++ { ++ /* If the high double is an exact power of two and the low ++ double has the opposite sign, then the exponent calculated ++ from the high double is one too big. */ ++ if (ix == 0 ++ && (int64_t) (hx ^ lx) < 0) ++ { ++ hx += 1LL << 52; ++ expon -= 1; ++ } ++ ++ explo = ixl >> 52; ++ if (explo == 0) ++ { ++ /* The low double started out as a denormal. Normalize its ++ mantissa and adjust the exponent. */ ++ int cnt; ++ ++ if (sizeof (ixl) == sizeof (long)) ++ cnt = __builtin_clzl (ixl); ++ else if ((ixl >> 32) != 0) ++ cnt = __builtin_clzl ((long) (ixl >> 32)); ++ else ++ cnt = __builtin_clzl ((long) ixl) + 32; ++ cnt = cnt - 12; ++ explo -= cnt; ++ ixl <<= cnt + 1; ++ } ++ ++ /* With variable precision we can't assume much about the ++ magnitude of the returned low double. It may even be a ++ denormal. */ ++ explo -= expon; ++ ixl &= 0x000fffffffffffffULL; ++ lx &= 0x8000000000000000ULL; ++ if (explo <= 0) ++ { ++ /* Handle denormal low double. */ ++ if (explo > -52) ++ { ++ ixl |= 1LL << 52; ++ ixl >>= 1 - explo; ++ } ++ else ++ { ++ ixl = 0; ++ lx = 0; ++ if ((hx & 0x7ff0000000000000ULL) == (1023LL << 52)) ++ { ++ /* Oops, the adjustment we made above for values a ++ little smaller than powers of two turned out to ++ be wrong since the returned low double will be ++ zero. This can happen if the input was ++ something weird like 0x1p1000 - 0x1p-1000. */ ++ hx -= 1LL << 52; ++ expon += 1; ++ } ++ } ++ explo = 0; + } +- *eptr += (ix>>52)-1022; ++ lx |= (explo << 52) | ixl; ++ } + +- if (ixl != 0ULL) { +- explo = (ixl>>52) - (ix>>52) + 0x3fe; +- if ((ixl&0x7ff0000000000000ULL) == 0LL) { +- /* the lower double is a denormal so we need to correct its +- mantissa and perhaps its exponent. */ +- int cnt; +- +- if (sizeof (ixl) == sizeof (long)) +- cnt = __builtin_clzl (ixl); +- else if ((ixl >> 32) != 0) +- cnt = __builtin_clzl ((long) (ixl >> 32)); +- else +- cnt = __builtin_clzl ((long) ixl) + 32; +- cnt = cnt - 12; +- lx = (lx&0x8000000000000000ULL) | ((explo-cnt)<<52) +- | ((ixl<<(cnt+1))&0x000fffffffffffffULL); +- } else +- lx = (lx&0x800fffffffffffffULL) | (explo<<52); +- } else +- lx = 0ULL; +- +- hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL; +- INSERT_WORDS64 (xhi, hx); +- INSERT_WORDS64 (xlo, lx); +- x = ldbl_pack (xhi, xlo); +- return x; ++ INSERT_WORDS64 (xhi, hx); ++ INSERT_WORDS64 (xlo, lx); ++ x = ldbl_pack (xhi, xlo); ++ *eptr = expon; ++ return x; + } + #ifdef IS_IN_libm + long_double_symbol (libm, __frexpl, frexpl); diff --git a/SOURCES/glibc-rh1162895-3.patch b/SOURCES/glibc-rh1162895-3.patch new file mode 100644 index 00000000..c6e24f1c --- /dev/null +++ b/SOURCES/glibc-rh1162895-3.patch @@ -0,0 +1,123 @@ +commit b0abbc21034f0e5edc49023d8fda0616173faf17 +Author: Alan Modra +Date: Wed Apr 2 13:46:19 2014 +1030 + + Correct IBM long double nextafterl. + + Fix for values near a power of two, and some tidies. + + [BZ #16739] + * sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (__nextafterl): Correct + output when value is near a power of two. Use int64_t for lx and + remove casts. Use decimal rather than hex exponent constants. + Don't use long double multiplication when double will suffice. + * math/libm-test.inc (nextafter_test_data): Add tests. + * NEWS: Add 16739 and 16786 to bug list. + +diff --git glibc-2.17-c758a686/math/libm-test.inc glibc-2.17-c758a686/math/libm-test.inc +index 19194f6..967b679 100644 +--- glibc-2.17-c758a686/math/libm-test.inc ++++ glibc-2.17-c758a686/math/libm-test.inc +@@ -8199,6 +8208,14 @@ pow_test (void) + #if defined TEST_DOUBLE || defined TEST_LDOUBLE + TEST_ff_f (pow, -7.49321e+133, -9.80818e+16, 0, UNDERFLOW_EXCEPTION); + #endif ++#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106 ++ TEST_ff_f (nextafter, 1.0L, -10.0L, 1.0L-0x1p-106L, NO_EXCEPTION), ++ TEST_ff_f (nextafter, 1.0L, 10.0L, 1.0L+0x1p-105L, NO_EXCEPTION), ++ TEST_ff_f (nextafter, 1.0L-0x1p-106L, 10.0L, 1.0L, NO_EXCEPTION), ++ TEST_ff_f (nextafter, -1.0L, -10.0L, -1.0L-0x1p-105L, NO_EXCEPTION), ++ TEST_ff_f (nextafter, -1.0L, 10.0L, -1.0L+0x1p-106L, NO_EXCEPTION), ++ TEST_ff_f (nextafter, -1.0L+0x1p-106L, -10.0L, -1.0L, NO_EXCEPTION), ++#endif + + TEST_ff_f (pow, -1.0, -0xffffff, -1.0); + TEST_ff_f (pow, -1.0, -0x1fffffe, 1.0); +diff --git glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c +index 30b1540..bf57cb8 100644 +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c +@@ -30,8 +30,7 @@ static char rcsid[] = "$NetBSD: $"; + + long double __nextafterl(long double x, long double y) + { +- int64_t hx,hy,ihx,ihy; +- uint64_t lx; ++ int64_t hx, hy, ihx, ihy, lx; + double xhi, xlo, yhi; + + ldbl_unpack (x, &xhi, &xlo); +@@ -79,19 +78,28 @@ long double __nextafterl(long double x, long double y) + u = math_opt_barrier (x); + x -= __LDBL_DENORM_MIN__; + if (ihx < 0x0360000000000000LL +- || (hx > 0 && (int64_t) lx <= 0) +- || (hx < 0 && (int64_t) lx > 1)) { ++ || (hx > 0 && lx <= 0) ++ || (hx < 0 && lx > 1)) { + u = u * u; + math_force_eval (u); /* raise underflow flag */ + } + return x; + } +- if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ +- INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52)); +- u = yhi; +- u *= 0x1.0000000000000p-105L; ++ /* If the high double is an exact power of two and the low ++ double is the opposite sign, then 1ulp is one less than ++ what we might determine from the high double. Similarly ++ if X is an exact power of two, and positive, because ++ making it a little smaller will result in the exponent ++ decreasing by one and normalisation of the mantissa. */ ++ if ((hx & 0x000fffffffffffffLL) == 0 ++ && ((lx != 0 && (hx ^ lx) < 0) ++ || (lx == 0 && hx >= 0))) ++ ihx -= 1LL << 52; ++ if (ihx < (106LL << 52)) { /* ulp will denormal */ ++ INSERT_WORDS64 (yhi, ihx & (0x7ffLL<<52)); ++ u = yhi * 0x1p-105; + } else { +- INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52)); ++ INSERT_WORDS64 (yhi, (ihx & (0x7ffLL<<52))-(105LL<<52)); + u = yhi; + } + return x - u; +@@ -109,8 +117,8 @@ long double __nextafterl(long double x, long double y) + u = math_opt_barrier (x); + x += __LDBL_DENORM_MIN__; + if (ihx < 0x0360000000000000LL +- || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL) +- || (hx < 0 && (int64_t) lx >= 0)) { ++ || (hx > 0 && lx < 0 && lx != 0x8000000000000001LL) ++ || (hx < 0 && lx >= 0)) { + u = u * u; + math_force_eval (u); /* raise underflow flag */ + } +@@ -118,12 +126,21 @@ long double __nextafterl(long double x, long double y) + x = -0.0L; + return x; + } +- if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ +- INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52)); +- u = yhi; +- u *= 0x1.0000000000000p-105L; ++ /* If the high double is an exact power of two and the low ++ double is the opposite sign, then 1ulp is one less than ++ what we might determine from the high double. Similarly ++ if X is an exact power of two, and negative, because ++ making it a little larger will result in the exponent ++ decreasing by one and normalisation of the mantissa. */ ++ if ((hx & 0x000fffffffffffffLL) == 0 ++ && ((lx != 0 && (hx ^ lx) < 0) ++ || (lx == 0 && hx < 0))) ++ ihx -= 1LL << 52; ++ if (ihx < (106LL << 52)) { /* ulp will denormal */ ++ INSERT_WORDS64 (yhi, ihx & (0x7ffLL<<52)); ++ u = yhi * 0x1p-105; + } else { +- INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52)); ++ INSERT_WORDS64 (yhi, (ihx & (0x7ffLL<<52))-(105LL<<52)); + u = yhi; + } + return x + u; diff --git a/SOURCES/glibc-rh1165192.patch b/SOURCES/glibc-rh1165192.patch new file mode 100644 index 00000000..60656944 --- /dev/null +++ b/SOURCES/glibc-rh1165192.patch @@ -0,0 +1,150 @@ +commit 03d2730b44cc2236318fd978afa2651753666c55 +Author: Florian Weimer +Date: Wed Apr 29 14:41:25 2015 +0200 + + CVE-2014-8121: Do not close NSS files database during iteration [BZ #18007] + +diff -up glibc-2.17-c758a686/nss/Makefile.rh1165192 glibc-2.17-c758a686/nss/Makefile +--- glibc-2.17-c758a686/nss/Makefile.rh1165192 2015-01-14 21:22:57.558006945 +0100 ++++ glibc-2.17-c758a686/nss/Makefile 2015-01-14 21:44:59.657777124 +0100 +@@ -38,7 +38,7 @@ install-bin := getent makedb + makedb-modules = xmalloc hash-string + extra-objs += $(makedb-modules:=.o) + +-tests = test-netdb tst-nss-test1 bug17079 ++tests = test-netdb tst-nss-test1 bug17079 tst-nss-getpwent + xtests = bug-erange + + include ../Makeconfig +diff -up glibc-2.17-c758a686/nss/nss_files/files-XXX.c.rh1165192 glibc-2.17-c758a686/nss/nss_files/files-XXX.c +--- glibc-2.17-c758a686/nss/nss_files/files-XXX.c.rh1165192 2015-01-14 21:22:14.630721754 +0100 ++++ glibc-2.17-c758a686/nss/nss_files/files-XXX.c 2015-01-14 21:22:15.072725814 +0100 +@@ -135,7 +135,7 @@ CONCAT(_nss_files_set,ENTNAME) (int stay + + __libc_lock_lock (lock); + +- status = internal_setent (stayopen); ++ status = internal_setent (1); + + if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0) + { +diff -up glibc-2.17-c758a686/nss/tst-nss-getpwent.c.rh1165192 glibc-2.17-c758a686/nss/tst-nss-getpwent.c +--- glibc-2.17-c758a686/nss/tst-nss-getpwent.c.rh1165192 2015-01-14 21:23:50.003236107 +0100 ++++ glibc-2.17-c758a686/nss/tst-nss-getpwent.c 2015-01-14 21:46:39.912194368 +0100 +@@ -0,0 +1,116 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++int ++do_test (void) ++{ ++ /* Count the number of entries in the password database, and fetch ++ data from the first and last entries. */ ++ size_t count = 0; ++ struct passwd * pw; ++ char *first_name = NULL; ++ uid_t first_uid = 0; ++ char *last_name = NULL; ++ uid_t last_uid = 0; ++ setpwent (); ++ while ((pw = getpwent ()) != NULL) ++ { ++ if (first_name == NULL) ++ { ++ first_name = strdup (pw->pw_name); ++ if (first_name == NULL) ++ { ++ printf ("strdup: %m\n"); ++ return 1; ++ } ++ first_uid = pw->pw_uid; ++ } ++ ++ free (last_name); ++ last_name = strdup (pw->pw_name); ++ if (last_name == NULL) ++ { ++ printf ("strdup: %m\n"); ++ return 1; ++ } ++ last_uid = pw->pw_uid; ++ ++count; ++ } ++ endpwent (); ++ ++ if (count == 0) ++ { ++ printf ("No entries in the password database.\n"); ++ return 0; ++ } ++ ++ /* Try again, this time interleaving with name-based and UID-based ++ lookup operations. The counts do not match if the interleaved ++ lookups affected the enumeration. */ ++ size_t new_count = 0; ++ setpwent (); ++ while ((pw = getpwent ()) != NULL) ++ { ++ if (new_count == count) ++ { ++ printf ("Additional entry in the password database.\n"); ++ return 1; ++ } ++ ++new_count; ++ struct passwd *pw2 = getpwnam (first_name); ++ if (pw2 == NULL) ++ { ++ printf ("getpwnam (%s) failed: %m\n", first_name); ++ return 1; ++ } ++ pw2 = getpwnam (last_name); ++ if (pw2 == NULL) ++ { ++ printf ("getpwnam (%s) failed: %m\n", last_name); ++ return 1; ++ } ++ pw2 = getpwuid (first_uid); ++ if (pw2 == NULL) ++ { ++ printf ("getpwuid (%llu) failed: %m\n", (unsigned long long) first_uid); ++ return 1; ++ } ++ pw2 = getpwuid (last_uid); ++ if (pw2 == NULL) ++ { ++ printf ("getpwuid (%llu) failed: %m\n", (unsigned long long) last_uid); ++ return 1; ++ } ++ } ++ endpwent (); ++ if (new_count < count) ++ { ++ printf ("Missing entry in the password database.\n"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh1165212.patch b/SOURCES/glibc-rh1165212.patch new file mode 100644 index 00000000..7835fbff --- /dev/null +++ b/SOURCES/glibc-rh1165212.patch @@ -0,0 +1,336 @@ +# +# This is a special patch for rhel-6 to fix recursive dlopen. +# It is likely the upstream patch will always be too risky for +# rhel-6 and will involve reorganizing the way in which recursive +# dlopen is allowed to operate and how the _r_debug and stap +# points are used by gdb for the recursive case. +# +# This fix changes the internal API to duplicate the ldconfig +# cache data. This means that at any point the cache can be +# unmapped without any consequences. The caller is responsible +# fore freeing the returned string. +# +# A regression test is added to verify the assertion for _r_debug +# is no longer triggered due to the recursive dlopen. The test to +# verify the fix in _dl_load_cache_lookup is not automated and +# has to be run by hand. +# +# The original version of this patch was based on the first version +# of the upstream patch posted here: +# https://sourceware.org/ml/libc-alpha/2014-12/msg00446.html +# The current version has been modified to reflect the changes +# made in the revision of the patch committed to trunk after +# being posted for review here: +# https://sourceware.org/ml/libc-alpha/2014-12/msg00483.html + +This was committed upstream as: + +commit ccdb048df457d581f6ac7ede8b0c7a593a891dfa +Author: Carlos O'Donell +Date: Wed Jan 21 01:51:10 2015 -0500 + + Fix recursive dlopen. + +--- glibc-2.17-c758a686/dlfcn/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/dlfcn/Makefile 2015-06-22 12:44:41.000000000 -0400 +@@ -35,12 +35,12 @@ endif + ifeq (yes,$(build-shared)) + tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ + bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ +- bug-atexit3 tstatexit ++ bug-atexit3 tstatexit tst-rec-dlopen + endif + modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ + defaultmod2 errmsg1mod modatexit modcxaatexit \ + bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \ +- bug-atexit2-lib bug-atexit3-lib ++ bug-atexit2-lib bug-atexit3-lib moddummy1 moddummy2 + + failtestmod.so-no-z-defs = yes + glreflib2.so-no-z-defs = yes +@@ -122,6 +122,8 @@ LDLIBS-bug-atexit3-lib.so = -lstdc++ -lg + $(objpfx)bug-atexit3: $(libdl) + $(objpfx)bug-atexit3.out: $(objpfx)bug-atexit3-lib.so + ++$(objpfx)tst-rec-dlopen: $(libdl) ++$(objpfx)tst-rec-dlopen.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so + + # Depend on libc.so so a DT_NEEDED is generated in the shared objects. + # This ensures they will load libc.so for needed symbols if loaded by +--- glibc-2.17-c758a686/elf/dl-cache.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/elf/dl-cache.c 2015-06-22 12:44:39.000000000 -0400 +@@ -174,9 +174,12 @@ _dl_cache_libcmp (const char *p1, const + + + /* Look up NAME in ld.so.cache and return the file name stored there, +- or null if none is found. */ +- +-const char * ++ or null if none is found. ++ The caller is responsible for freeing the returned string. The ld.so.cache ++ may be unmapped at any time by a completing recursive dlopen and ++ this function must take care that it does not return references to ++ any data in the mapping. */ ++char * + internal_function + _dl_load_cache_lookup (const char *name) + { +@@ -289,7 +292,17 @@ _dl_load_cache_lookup (const char *name) + && best != NULL) + _dl_debug_printf (" trying file=%s\n", best); + +- return best; ++ if (best == NULL) ++ return NULL; ++ ++ /* The double copy is *required* since malloc may be interposed ++ and call dlopen itself whose completion would unmap the data ++ we are accessing. Therefore we must make the copy of the ++ mapping data without using malloc. */ ++ char *temp; ++ temp = alloca (strlen (best) + 1); ++ strcpy (temp, best); ++ return strdup (temp); + } + + #ifndef MAP_COPY +--- glibc-2.17-c758a686/elf/dl-load.c 2015-06-22 12:41:10.748836414 -0400 ++++ glibc-2.17-c758a686/elf/dl-load.c 2015-06-22 12:44:39.000000000 -0400 +@@ -2232,7 +2232,7 @@ _dl_map_object (struct link_map *loader, + { + /* Check the list of libraries in the file /etc/ld.so.cache, + for compatibility with Linux's ldconfig program. */ +- const char *cached = _dl_load_cache_lookup (name); ++ char *cached = _dl_load_cache_lookup (name); + + if (cached != NULL) + { +@@ -2262,6 +2262,7 @@ _dl_map_object (struct link_map *loader, + if (memcmp (cached, dirp, system_dirs_len[cnt]) == 0) + { + /* The prefix matches. Don't use the entry. */ ++ free (cached); + cached = NULL; + break; + } +@@ -2278,14 +2279,9 @@ _dl_map_object (struct link_map *loader, + &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded, + LA_SER_CONFIG, &found_other_class, false); + if (__builtin_expect (fd != -1, 1)) +- { +- realname = local_strdup (cached); +- if (realname == NULL) +- { +- __close (fd); +- fd = -1; +- } +- } ++ realname = cached; ++ else ++ free (cached); + } + } + } +--- glibc-2.17-c758a686/elf/dl-open.c 2015-06-22 12:41:16.348913620 -0400 ++++ glibc-2.17-c758a686/elf/dl-open.c 2015-06-22 12:44:40.000000000 -0400 +@@ -221,7 +221,11 @@ dl_open_worker (void *a) + } + } + +- assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); ++ /* One might be tempted to assert that we are RT_CONSISTENT at this point, but that ++ may not be true if this is a recursive call to dlopen. ++ TODO: Fix all of the debug state so we end up at RT_CONSISTENT only when the last ++ recursive dlopen completes. */ ++ _dl_debug_initialize (0, args->nsid); + + /* Load the named object. */ + struct link_map *new; +--- glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2015-06-22 12:41:16.328913344 -0400 ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2015-06-22 12:44:41.000000000 -0400 +@@ -895,8 +895,8 @@ + internal_function; + + /* Look up NAME in ld.so.cache and return the file name stored there, +- or null if none is found. */ +-extern const char *_dl_load_cache_lookup (const char *name) ++ or null if none is found. Caller must free returned string. */ ++extern char *_dl_load_cache_lookup (const char *name) + internal_function; + + /* If the system does not support MAP_COPY we cannot leave the file open +--- glibc-2.17-c758a686/dlfcn/tst-rec-dlopen.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/dlfcn/tst-rec-dlopen.c 2015-06-22 12:44:41.000000000 -0400 +@@ -0,0 +1,143 @@ ++/* Test recursive dlopen using malloc hooks. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#define DSO "moddummy1.so" ++#define FUNC "dummy1" ++ ++#define DSO1 "moddummy2.so" ++#define FUNC1 "dummy2" ++ ++/* Result of the called function. */ ++int func_result; ++ ++/* Prototype for my hook. */ ++void *custom_malloc_hook (size_t, const void *); ++ ++/* Pointer to old malloc hooks. */ ++void *(*old_malloc_hook) (size_t, const void *); ++ ++/* Call function func_name in DSO dso_name via dlopen. */ ++void ++call_func (const char *dso_name, const char *func_name) ++{ ++ int ret; ++ void *dso; ++ int (*func) (void); ++ char *err; ++ ++ /* Open the DSO. */ ++ dso = dlopen (dso_name, RTLD_NOW|RTLD_GLOBAL); ++ if (dso == NULL) ++ { ++ err = dlerror (); ++ fprintf (stderr, "%s\n", err); ++ exit (1); ++ } ++ /* Clear any errors. */ ++ dlerror (); ++ ++ /* Lookup func. */ ++ func = (int (*) (void)) dlsym (dso, func_name); ++ if (func == NULL) ++ { ++ err = dlerror (); ++ if (err != NULL) ++ { ++ fprintf (stderr, "%s\n", err); ++ exit (1); ++ } ++ } ++ /* Call func. */ ++ func_result = (*func) (); ++ ++ /* Close the library and look for errors too. */ ++ ret = dlclose (dso); ++ if (ret != 0) ++ { ++ err = dlerror (); ++ fprintf (stderr, "%s\n", err); ++ exit (1); ++ } ++ ++} ++ ++/* Empty hook that does nothing. */ ++void * ++custom_malloc_hook (size_t size, const void *caller) ++{ ++ void *result; ++ /* Restore old hooks. */ ++ __malloc_hook = old_malloc_hook; ++ /* First call a function in another library via dlopen. */ ++ call_func (DSO1, FUNC1); ++ /* Called recursively. */ ++ result = malloc (size); ++ /* Restore new hooks. */ ++ __malloc_hook = custom_malloc_hook; ++ return result; ++} ++ ++static int ++do_test (void) ++{ ++ /* Save old hook. */ ++ old_malloc_hook = __malloc_hook; ++ /* Install new hook. */ ++ __malloc_hook = custom_malloc_hook; ++ ++ /* Bug 17702 fixes two things: ++ * A recursive dlopen unmapping the ld.so.cache. ++ * An assertion that _r_debug is RT_CONSISTENT at entry to dlopen. ++ We can only test the latter. Testing the former requires modifying ++ ld.so.conf to cache the dummy libraries, then running ldconfig, ++ then run the test. If you do all of that (and glibc's test ++ infrastructure doesn't support that yet) then the test will ++ SEGFAULT without the fix. If you don't do that, then the test ++ will abort because of the assert described in detail below. */ ++ call_func (DSO, FUNC); ++ ++ /* Restore old hook. */ ++ __malloc_hook = old_malloc_hook; ++ ++ /* The function dummy2() is called by the malloc hook. Check to ++ see that it was called. This ensures the second recursive ++ dlopen happened and we called the function in that library. ++ Before the fix you either get a SIGSEGV when accessing mmap'd ++ ld.so.cache data or an assertion failure about _r_debug not ++ beint RT_CONSISTENT. We don't test for the SIGSEGV since it ++ would require finding moddummy1 or moddummy2 in the cache and ++ we don't have any infrastructure to test that, but the _r_debug ++ assertion triggers. */ ++ printf ("Returned result is %d\n", func_result); ++ if (func_result <= 0) ++ { ++ printf ("FAIL: Function call_func() not called.\n"); ++ exit (1); ++ } ++ ++ printf ("PASS: Function call_func() called more than once.\n"); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- glibc-2.17-c758a686/dlfcn/moddummy1.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/dlfcn/moddummy1.c 2015-06-22 12:44:41.000000000 -0400 +@@ -0,0 +1,10 @@ ++/* Provide a dummy DSO for tst-rec-dlopen to use. */ ++#include ++#include ++ ++int ++dummy1 (void) ++{ ++ printf ("Called dummy1()\n"); ++ return 1; ++} +--- glibc-2.17-c758a686/dlfcn/moddummy2.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/dlfcn/moddummy2.c 2015-06-22 12:44:41.000000000 -0400 +@@ -0,0 +1,13 @@ ++/* Provide a dummy DSO for tst-rec-dlopen to use. */ ++#include ++#include ++ ++int ++dummy2 (void) ++{ ++ printf ("Called dummy2()\n"); ++ /* If the outer dlopen is not dummy1 (becuase of some error) ++ then tst-rec-dlopen will see a value of -1 as the returned ++ result and fail. */ ++ return -1; ++} diff --git a/SOURCES/glibc-rh1170118-CVE-2014-7817.patch b/SOURCES/glibc-rh1170118-CVE-2014-7817.patch new file mode 100644 index 00000000..574eaf7e --- /dev/null +++ b/SOURCES/glibc-rh1170118-CVE-2014-7817.patch @@ -0,0 +1,163 @@ +# +# commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c +# Author: Carlos O'Donell +# Date: Wed Nov 19 11:44:12 2014 -0500 +# +# CVE-2014-7817: wordexp fails to honour WRDE_NOCMD. +# +# The function wordexp() fails to properly handle the WRDE_NOCMD +# flag when processing arithmetic inputs in the form of "$((... ``))" +# where "..." can be anything valid. The backticks in the arithmetic +# epxression are evaluated by in a shell even if WRDE_NOCMD forbade +# command substitution. This allows an attacker to attempt to pass +# dangerous commands via constructs of the above form, and bypass +# the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD +# in exec_comm(), the only place that can execute a shell. All other +# checks for WRDE_NOCMD are superfluous and removed. +# +# We expand the testsuite and add 3 new regression tests of roughly +# the same form but with a couple of nested levels. +# +# On top of the 3 new tests we add fork validation to the WRDE_NOCMD +# testing. If any forks are detected during the execution of a wordexp() +# call with WRDE_NOCMD, the test is marked as failed. This is slightly +# heuristic since vfork might be used in the future, but it provides a +# higher level of assurance that no shells were executed as part of +# command substitution with WRDE_NOCMD in effect. In addition it doesn't +# require libpthread or libdl, instead we use the public implementation +# namespace function __register_atfork (already part of the public ABI +# for libpthread). +# +# Tested on x86_64 with no regressions. +# +diff --git glibc-2.17-c758a686/posix/wordexp-test.c glibc-2.17-c758a686/posix/wordexp-test.c +index 4957006..bdd65e4 100644 +--- glibc-2.17-c758a686/posix/wordexp-test.c ++++ glibc-2.17-c758a686/posix/wordexp-test.c +@@ -27,6 +27,25 @@ + + #define IFS " \n\t" + ++extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden"))); ++extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *); ++ ++static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void)) ++{ ++ return __register_atfork (prepare, parent, child, ++ &__dso_handle == NULL ? NULL : __dso_handle); ++} ++ ++/* Number of forks seen. */ ++static int registered_forks; ++ ++/* For each fork increment the fork count. */ ++static void ++register_fork (void) ++{ ++ registered_forks++; ++} ++ + struct test_case_struct + { + int retval; +@@ -206,6 +225,12 @@ struct test_case_struct + { WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS }, + { WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS }, + { WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS }, ++ /* Test for CVE-2014-7817. We test 3 combinations of command ++ substitution inside an arithmetic expression to make sure that ++ no commands are executed and error is returned. */ ++ { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS }, ++ { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS }, ++ { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS }, + + { -1, NULL, NULL, 0, 0, { NULL, }, IFS }, + }; +@@ -258,6 +283,15 @@ main (int argc, char *argv[]) + return -1; + } + ++ /* If we are not allowed to do command substitution, we install ++ fork handlers to verify that no forks happened. No forks should ++ happen at all if command substitution is disabled. */ ++ if (__app_register_atfork (register_fork, NULL, NULL) != 0) ++ { ++ printf ("Failed to register fork handler.\n"); ++ return -1; ++ } ++ + for (test = 0; test_case[test].retval != -1; test++) + if (testit (&test_case[test])) + ++fail; +@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc) + + printf ("Test %d (%s): ", ++tests, tc->words); + ++ if (tc->flags & WRDE_NOCMD) ++ registered_forks = 0; ++ + if (tc->flags & WRDE_APPEND) + { + /* initial wordexp() call, to be appended to */ +@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc) + } + retval = wordexp (tc->words, &we, tc->flags); + ++ if ((tc->flags & WRDE_NOCMD) ++ && (registered_forks > 0)) ++ { ++ printf ("FAILED fork called for WRDE_NOCMD\n"); ++ return 1; ++ } ++ + if (tc->flags & WRDE_DOOFFS) + start_offs = sav_we.we_offs; + +diff --git glibc-2.17-c758a686/posix/wordexp.c glibc-2.17-c758a686/posix/wordexp.c +index b6b65dd..26f3a26 100644 +--- glibc-2.17-c758a686/posix/wordexp.c ++++ glibc-2.17-c758a686/posix/wordexp.c +@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length, + pid_t pid; + int noexec = 0; + ++ /* Do nothing if command substitution should not succeed. */ ++ if (flags & WRDE_NOCMD) ++ return WRDE_CMDSUB; ++ + /* Don't fork() unless necessary */ + if (!comm || !*comm) + return 0; +@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length, + } + } + +- if (flags & WRDE_NOCMD) +- return WRDE_CMDSUB; +- + (*offset) += 2; + return parse_comm (word, word_length, max_length, words, offset, flags, + quoted? NULL : pwordexp, ifs, ifs_white); +@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length, + break; + + case '`': +- if (flags & WRDE_NOCMD) +- return WRDE_CMDSUB; +- + ++(*offset); + error = parse_backtick (word, word_length, max_length, words, + offset, flags, NULL, NULL, NULL); +@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags) + break; + + case '`': +- if (flags & WRDE_NOCMD) +- { +- error = WRDE_CMDSUB; +- goto do_error; +- } +- + ++words_offset; + error = parse_backtick (&word, &word_length, &max_length, words, + &words_offset, flags, pwordexp, ifs, diff --git a/SOURCES/glibc-rh1173238.patch b/SOURCES/glibc-rh1173238.patch new file mode 100644 index 00000000..fd166860 --- /dev/null +++ b/SOURCES/glibc-rh1173238.patch @@ -0,0 +1,380 @@ +Cannot be upstreamed. rtkaio was removed from Fedora. + +diff -u --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio-le.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio-le.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio-le.abilist 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio-le.abilist 2015-04-28 19:44:03.038050864 -0400 +@@ -0,0 +1,41 @@ ++GLIBC_2.17 ++ GLIBC_2.17 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ lio_listio F ++ lio_listio64 F ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F +diff -ru --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/nptl/librtkaio.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/nptl/librtkaio.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/nptl/librtkaio.abilist 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/nptl/librtkaio.abilist 2015-04-23 17:51:48.159155741 -0600 +@@ -0,0 +1,49 @@ ++GLIBC_2.1 ++ GLIBC_2.1 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ lio_listio F ++ lio_listio64 F ++GLIBC_2.2 ++ GLIBC_2.2 A ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.4 ++ GLIBC_2.3.4 A ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++GLIBC_2.4 ++ GLIBC_2.4 A ++ lio_listio F ++ lio_listio64 F +diff -ru --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/librtkaio.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/librtkaio.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/librtkaio.abilist 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/librtkaio.abilist 2015-04-23 17:50:38.059113789 -0600 +@@ -0,0 +1,49 @@ ++GLIBC_2.1 ++ GLIBC_2.1 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ lio_listio F ++ lio_listio64 F ++GLIBC_2.2 ++ GLIBC_2.2 A ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.4 ++ GLIBC_2.3.4 A ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++GLIBC_2.4 ++ GLIBC_2.4 A ++ lio_listio F ++ lio_listio64 F +diff -ru --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio.abilist 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/librtkaio.abilist 2015-04-23 21:19:41.204953576 -0600 +@@ -0,0 +1,54 @@ ++GLIBC_2.3 ++ GLIBC_2.3 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ lio_listio F ++ lio_listio64 F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.3 ++ GLIBC_2.3.3 A ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.4 ++ GLIBC_2.3.4 A ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++GLIBC_2.4 ++ GLIBC_2.4 A ++ lio_listio F ++ lio_listio64 F +diff -ru --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/nptl/librtkaio.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/nptl/librtkaio.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/nptl/librtkaio.abilist 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/nptl/librtkaio.abilist 2015-04-23 17:50:54.671886744 -0600 +@@ -0,0 +1,49 @@ ++GLIBC_2.1 ++ GLIBC_2.1 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ lio_listio F ++ lio_listio64 F ++GLIBC_2.2 ++ GLIBC_2.2 A ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.4 ++ GLIBC_2.3.4 A ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++GLIBC_2.4 ++ GLIBC_2.4 A ++ lio_listio F ++ lio_listio64 F +diff -ru --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/nptl/librtkaio.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/nptl/librtkaio.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/nptl/librtkaio.abilist 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/nptl/librtkaio.abilist 2015-04-23 17:52:01.366975232 -0600 +@@ -0,0 +1,54 @@ ++GLIBC_2.2 ++ GLIBC_2.2 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ lio_listio F ++ lio_listio64 F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.3 ++ GLIBC_2.3.3 A ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.4 ++ GLIBC_2.3.4 A ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++GLIBC_2.4 ++ GLIBC_2.4 A ++ lio_listio F ++ lio_listio64 F +diff -ru --new-file glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/nptl/librtkaio.abilist glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/nptl/librtkaio.abilist +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/nptl/librtkaio.abilist 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/nptl/librtkaio.abilist 2015-04-23 17:51:12.091648671 -0600 +@@ -0,0 +1,54 @@ ++GLIBC_2.2.5 ++ GLIBC_2.2.5 A ++ aio_cancel F ++ aio_cancel64 F ++ aio_error F ++ aio_error64 F ++ aio_fsync F ++ aio_fsync64 F ++ aio_init F ++ aio_read F ++ aio_read64 F ++ aio_return F ++ aio_return64 F ++ aio_suspend F ++ aio_suspend64 F ++ aio_write F ++ aio_write64 F ++ clock_getcpuclockid F ++ clock_getres F ++ clock_gettime F ++ clock_nanosleep F ++ clock_settime F ++ lio_listio F ++ lio_listio64 F ++ shm_open F ++ shm_unlink F ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.3 ++ GLIBC_2.3.3 A ++ timer_create F ++ timer_delete F ++ timer_getoverrun F ++ timer_gettime F ++ timer_settime F ++GLIBC_2.3.4 ++ GLIBC_2.3.4 A ++ mq_close F ++ mq_getattr F ++ mq_notify F ++ mq_open F ++ mq_receive F ++ mq_send F ++ mq_setattr F ++ mq_timedreceive F ++ mq_timedsend F ++ mq_unlink F ++GLIBC_2.4 ++ GLIBC_2.4 A ++ lio_listio F ++ lio_listio64 F diff --git a/SOURCES/glibc-rh1173537.patch b/SOURCES/glibc-rh1173537.patch new file mode 100644 index 00000000..963252a6 --- /dev/null +++ b/SOURCES/glibc-rh1173537.patch @@ -0,0 +1,65 @@ +commit c3ec475c5dd16499aa040908e11d382c3ded9692 +Author: Siddhesh Poyarekar +Date: Mon May 26 11:40:08 2014 +0530 + + Use NSS_STATUS_TRYAGAIN to indicate insufficient buffer (BZ #16878) + + The netgroups nss modules in the glibc tree use NSS_STATUS_UNAVAIL + (with errno as ERANGE) when the supplied buffer does not have + sufficient space for the result. This is wrong, because the canonical + way to indicate insufficient buffer is to set the errno to ERANGE and + the status to NSS_STATUS_TRYAGAIN, as is used by all other modules. + + This fixes nscd behaviour when the nss_ldap module returns + NSS_STATUS_TRYAGAIN to indicate that a netgroup entry is too long to + fit into the supplied buffer. + +diff --git glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +index b3d40e9..edab174 100644 +--- glibc-2.17-c758a686/nscd/netgroupcache.c ++++ glibc-2.17-c758a686/nscd/netgroupcache.c +@@ -197,11 +197,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + int e; + status = getfct.f (&data, buffer + buffilled, + buflen - buffilled - req->key_len, &e); +- if (status == NSS_STATUS_RETURN +- || status == NSS_STATUS_NOTFOUND) +- /* This was either the last one for this group or the +- group was empty. Look at next group if available. */ +- break; + if (status == NSS_STATUS_SUCCESS) + { + if (data.type == triple_val) +@@ -320,11 +315,18 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + } + } +- else if (status == NSS_STATUS_UNAVAIL && e == ERANGE) ++ else if (status == NSS_STATUS_TRYAGAIN && e == ERANGE) + { + buflen *= 2; + buffer = xrealloc (buffer, buflen); + } ++ else if (status == NSS_STATUS_RETURN ++ || status == NSS_STATUS_NOTFOUND ++ || status == NSS_STATUS_UNAVAIL) ++ /* This was either the last one for this group or the ++ group was empty or the NSS module had an internal ++ failure. Look at next group if available. */ ++ break; + } + + enum nss_status (*endfct) (struct __netgrent *); +diff --git glibc-2.17-c758a686/nss/nss_files/files-netgrp.c glibc-2.17-c758a686/nss/nss_files/files-netgrp.c +index 34eae4c..bc0b367 100644 +--- glibc-2.17-c758a686/nss/nss_files/files-netgrp.c ++++ glibc-2.17-c758a686/nss/nss_files/files-netgrp.c +@@ -252,7 +252,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result, + if (cp - host > buflen) + { + *errnop = ERANGE; +- status = NSS_STATUS_UNAVAIL; ++ status = NSS_STATUS_TRYAGAIN; + } + else + { diff --git a/SOURCES/glibc-rh1176906.patch b/SOURCES/glibc-rh1176906.patch new file mode 100644 index 00000000..448bb7e9 --- /dev/null +++ b/SOURCES/glibc-rh1176906.patch @@ -0,0 +1,22 @@ +commit 7d81e8d6db95c112c297930a8f2f9617c305529a +Author: Florian Weimer +Date: Tue Dec 23 16:16:32 2014 +0100 + + iconvdata/run-iconv-test.sh: Actually test iconv modules + + Arjun Shankar noticed that this test case was not testing anything + because iconv was invoked without the required arguments. + +diff --git glibc-2.17-c758a686/iconvdata/run-iconv-test.sh glibc-2.17-c758a686/iconvdata/run-iconv-test.sh +index 5dfb69f..1d0bf52 100755 +--- glibc-2.17-c758a686/iconvdata/run-iconv-test.sh ++++ glibc-2.17-c758a686/iconvdata/run-iconv-test.sh +@@ -189,7 +189,7 @@ printf '\016\377\377\377\377\377\377\377' > $temp1 + for from in $iconv_modules ; do + echo $ac_n "test decoder $from $ac_c" + PROG=`eval echo $ICONV` +- if $PROG < $temp1 >/dev/null 2>&1 ; then ++ if $PROG -f $from -t UTF8 < $temp1 >/dev/null 2>&1 ; then + : # fall through + else + status=$? diff --git a/SOURCES/glibc-rh1183456.patch b/SOURCES/glibc-rh1183456.patch new file mode 100644 index 00000000..3982973c --- /dev/null +++ b/SOURCES/glibc-rh1183456.patch @@ -0,0 +1,40 @@ +commit 3cb26316b45b23dc5cfecbafdc489b28c3a52029 +Author: Siddhesh Poyarekar +Date: Thu Jan 29 10:30:09 2015 +0530 + + Initialize nscd stats data [BZ #17892] + + The padding bytes in the statsdata struct are not initialized, due to + which valgrind throws a warning: + + ==11384== Memcheck, a memory error detector + ==11384== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. + ==11384== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info + ==11384== Command: nscd -d + ==11384== + Fri 25 Apr 2014 10:34:53 AM CEST - 11384: handle_request: request received (Version = 2) from PID 11396 + Fri 25 Apr 2014 10:34:53 AM CEST - 11384: GETSTAT + ==11384== Thread 6: + ==11384== Syscall param socketcall.sendto(msg) points to uninitialised byte(s) + ==11384== at 0x4E4ACDC: send (in /lib64/libpthread-2.12.so) + ==11384== by 0x11AF6B: send_stats (in /usr/sbin/nscd) + ==11384== by 0x112F75: nscd_run_worker (in /usr/sbin/nscd) + ==11384== by 0x4E439D0: start_thread (in /lib64/libpthread-2.12.so) + ==11384== by 0x599AB6C: clone (in /lib64/libc-2.12.so) + ==11384== Address 0x15708395 is on thread 6's stack + + Fix the warning by initializing the structure. + +diff --git glibc-2.17-c758a686/nscd/nscd_stat.c glibc-2.17-c758a686/nscd/nscd_stat.c +index 0f1f3c0..7aaa21b 100644 +--- glibc-2.17-c758a686/nscd/nscd_stat.c ++++ glibc-2.17-c758a686/nscd/nscd_stat.c +@@ -94,6 +94,8 @@ send_stats (int fd, struct database_dyn dbs[lastdb]) + struct statdata data; + int cnt; + ++ memset (&data, 0, sizeof (data)); ++ + memcpy (data.version, compilation, sizeof (compilation)); + data.debug_level = debug_level; + data.runtime = time (NULL) - start_time; diff --git a/SOURCES/glibc-rh1183545.patch b/SOURCES/glibc-rh1183545.patch new file mode 100644 index 00000000..2db1019f --- /dev/null +++ b/SOURCES/glibc-rh1183545.patch @@ -0,0 +1,233 @@ +commit d5dd6189d506068ed11c8bfa1e1e9bffde04decd +Author: Andreas Schwab +Date: Mon Jan 21 17:41:28 2013 +0100 + + Fix parsing of numeric hosts in gethostbyname_r + +diff --git glibc-2.17-c758a686/nss/Makefile glibc-2.17-c758a686/nss/Makefile +index 449a258..553eafa 100644 +--- glibc-2.17-c758a686/nss/Makefile ++++ glibc-2.17-c758a686/nss/Makefile +@@ -37,7 +37,8 @@ install-bin := getent makedb + makedb-modules = xmalloc hash-string + extra-objs += $(makedb-modules:=.o) + +-tests = test-netdb tst-nss-test1 bug17079 tst-nss-getpwent ++tests = test-netdb tst-nss-test1 bug17079 tst-nss-getpwent \ ++ test-digits-dots + xtests = bug-erange + + include ../Makeconfig +diff --git glibc-2.17-c758a686/nss/digits_dots.c glibc-2.17-c758a686/nss/digits_dots.c +index 2b86295..e007ef4 100644 +--- glibc-2.17-c758a686/nss/digits_dots.c ++++ glibc-2.17-c758a686/nss/digits_dots.c +@@ -46,7 +46,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + { + if (h_errnop) + *h_errnop = NETDB_INTERNAL; +- *result = NULL; ++ if (buffer_size == NULL) ++ *status = NSS_STATUS_TRYAGAIN; ++ else ++ *result = NULL; + return -1; + } + +@@ -83,14 +86,16 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + } + + size_needed = (sizeof (*host_addr) +- + sizeof (*h_addr_ptrs) + strlen (name) + 1); ++ + sizeof (*h_addr_ptrs) ++ + sizeof (*h_alias_ptr) + strlen (name) + 1); + + if (buffer_size == NULL) + { + if (buflen < size_needed) + { ++ *status = NSS_STATUS_TRYAGAIN; + if (h_errnop != NULL) +- *h_errnop = TRY_AGAIN; ++ *h_errnop = NETDB_INTERNAL; + __set_errno (ERANGE); + goto done; + } +@@ -109,7 +114,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + *buffer_size = 0; + __set_errno (save); + if (h_errnop != NULL) +- *h_errnop = TRY_AGAIN; ++ *h_errnop = NETDB_INTERNAL; + *result = NULL; + goto done; + } +@@ -149,7 +154,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + if (! ok) + { + *h_errnop = HOST_NOT_FOUND; +- if (buffer_size) ++ if (buffer_size == NULL) ++ *status = NSS_STATUS_NOTFOUND; ++ else + *result = NULL; + goto done; + } +@@ -190,7 +197,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + if (buffer_size == NULL) + *status = NSS_STATUS_SUCCESS; + else +- *result = resbuf; ++ *result = resbuf; + goto done; + } + +@@ -201,15 +208,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + + if ((isxdigit (name[0]) && strchr (name, ':') != NULL) || name[0] == ':') + { +- const char *cp; +- char *hostname; +- typedef unsigned char host_addr_t[16]; +- host_addr_t *host_addr; +- typedef char *host_addr_list_t[2]; +- host_addr_list_t *h_addr_ptrs; +- size_t size_needed; +- int addr_size; +- + switch (af) + { + default: +@@ -225,7 +223,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + /* This is not possible. We cannot represent an IPv6 address + in an `struct in_addr' variable. */ + *h_errnop = HOST_NOT_FOUND; +- *result = NULL; ++ if (buffer_size == NULL) ++ *status = NSS_STATUS_NOTFOUND; ++ else ++ *result = NULL; + goto done; + + case AF_INET6: +@@ -233,42 +234,6 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + break; + } + +- size_needed = (sizeof (*host_addr) +- + sizeof (*h_addr_ptrs) + strlen (name) + 1); +- +- if (buffer_size == NULL && buflen < size_needed) +- { +- if (h_errnop != NULL) +- *h_errnop = TRY_AGAIN; +- __set_errno (ERANGE); +- goto done; +- } +- else if (buffer_size != NULL && *buffer_size < size_needed) +- { +- char *new_buf; +- *buffer_size = size_needed; +- new_buf = realloc (*buffer, *buffer_size); +- +- if (new_buf == NULL) +- { +- save = errno; +- free (*buffer); +- __set_errno (save); +- *buffer = NULL; +- *buffer_size = 0; +- *result = NULL; +- goto done; +- } +- *buffer = new_buf; +- } +- +- memset (*buffer, '\0', size_needed); +- +- host_addr = (host_addr_t *) *buffer; +- h_addr_ptrs = (host_addr_list_t *) +- ((char *) host_addr + sizeof (*host_addr)); +- hostname = (char *) h_addr_ptrs + sizeof (*h_addr_ptrs); +- + for (cp = name;; ++cp) + { + if (!*cp) +@@ -281,7 +246,9 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + if (inet_pton (AF_INET6, name, host_addr) <= 0) + { + *h_errnop = HOST_NOT_FOUND; +- if (buffer_size) ++ if (buffer_size == NULL) ++ *status = NSS_STATUS_NOTFOUND; ++ else + *result = NULL; + goto done; + } +diff --git glibc-2.17-c758a686/nss/getXXbyYY_r.c glibc-2.17-c758a686/nss/getXXbyYY_r.c +index 1067744..44d00f4 100644 +--- glibc-2.17-c758a686/nss/getXXbyYY_r.c ++++ glibc-2.17-c758a686/nss/getXXbyYY_r.c +@@ -179,6 +179,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, + case -1: + return errno; + case 1: ++#ifdef NEED_H_ERRNO ++ any_service = true; ++#endif + goto done; + } + #endif +@@ -288,7 +291,7 @@ done: + /* This happens when we weren't able to use a service for reasons other + than the module not being found. In such a case, we'd want to tell the + caller that errno has the real reason for failure. */ +- *h_errnop = NETDB_INTERNAL; ++ *h_errnop = NETDB_INTERNAL; + else if (status != NSS_STATUS_SUCCESS && !any_service) + /* We were not able to use any service. */ + *h_errnop = NO_RECOVERY; +diff --git glibc-2.17-c758a686/nss/test-digits-dots.c glibc-2.17-c758a686/nss/test-digits-dots.c +new file mode 100644 +index 0000000..1efa344 +--- /dev/null ++++ glibc-2.17-c758a686/nss/test-digits-dots.c +@@ -0,0 +1,38 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Testcase for BZ #15014 */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char buf[32]; ++ struct hostent *result = NULL; ++ struct hostent ret; ++ int h_err = 0; ++ int err; ++ ++ err = gethostbyname_r ("1.2.3.4", &ret, buf, sizeof (buf), &result, &h_err); ++ return err == ERANGE && h_err == NETDB_INTERNAL ? EXIT_SUCCESS : EXIT_FAILURE; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh1186491.patch b/SOURCES/glibc-rh1186491.patch new file mode 100644 index 00000000..7db4eaa7 --- /dev/null +++ b/SOURCES/glibc-rh1186491.patch @@ -0,0 +1,32 @@ +Patch not applicable to upstream, but the test failures not visible +there anymore. (The math tests have been reorganized.) + +--- glibc-2.17-c758a686/math/libm-test.inc 2015-01-22 10:53:11.015331338 -0500 ++++ glibc-2.17-c758a686/math/libm-test.inc 2015-01-26 16:46:24.631769811 -0500 +@@ -521,7 +521,7 @@ + } + + +-static void ++static void __attribute__ ((noinline)) + check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, + FLOAT max_ulp, int xfail, int exceptions, + FLOAT *curr_max_error) +@@ -610,7 +610,7 @@ + } + + +-static void ++static void __attribute__ ((noinline)) + check_float (const char *test_name, FLOAT computed, FLOAT expected, + FLOAT max_ulp, int xfail, int exceptions) + { +@@ -619,7 +619,7 @@ + } + + +-static void ++static void __attribute__ ((noinline)) + check_complex (const char *test_name, __complex__ FLOAT computed, + __complex__ FLOAT expected, + __complex__ FLOAT max_ulp, __complex__ int xfail, diff --git a/SOURCES/glibc-rh1186620.patch b/SOURCES/glibc-rh1186620.patch new file mode 100644 index 00000000..c2e307eb --- /dev/null +++ b/SOURCES/glibc-rh1186620.patch @@ -0,0 +1,95 @@ +commit 3e3002ffead0526d088c353f97475400367087da +Author: Siddhesh Poyarekar +Date: Tue Feb 24 12:57:26 2015 +0530 + + Skip logging for DNSSEC responses [BZ 14841] + + DNSSEC defines a number of response types that one me expect when the + DO bit is set. We don't process any of them, but since we do allow + setting the DO bit, skip them without logging an error since it is + only a nuisance. + + Tested on x86_64. + + [BZ #14841] + * resolv/gethnamaddr.c (getanswer): Skip logging if + RES_USE_DNSSEC is set. + * resolv/nss_dns/dns-host.c (getanswer_r): Likewise. + +diff --git glibc-2.17-c758a686/resolv/gethnamaddr.c glibc-2.17-c758a686/resolv/gethnamaddr.c +index a861a84..7fd0e49 100644 +--- glibc-2.17-c758a686/resolv/gethnamaddr.c ++++ glibc-2.17-c758a686/resolv/gethnamaddr.c +@@ -331,23 +331,18 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + buflen -= n; + continue; + } +- if ((type == T_SIG) || (type == T_KEY) || (type == T_NXT)) { +- /* We don't support DNSSEC yet. For now, ignore +- * the record and send a low priority message +- * to syslog. +- */ +- syslog(LOG_DEBUG|LOG_AUTH, +- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", +- qname, p_class(C_IN), p_type(qtype), +- p_type(type)); +- cp += n; +- continue; +- } + if (type != qtype) { +- syslog(LOG_NOTICE|LOG_AUTH, ++ /* Log a low priority message if we get an unexpected ++ * record, but skip it if we are using DNSSEC since it ++ * uses many different types in responses that do not ++ * match QTYPE. ++ */ ++ if ((_res.options & RES_USE_DNSSEC) == 0) { ++ syslog(LOG_NOTICE|LOG_AUTH, + "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", +- qname, p_class(C_IN), p_type(qtype), +- p_type(type)); ++ qname, p_class(C_IN), p_type(qtype), ++ p_type(type)); ++ } + cp += n; + continue; /* XXX - had_error++ ? */ + } +diff --git glibc-2.17-c758a686/resolv/nss_dns/dns-host.c glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +index f715ab0..b16b0dd 100644 +--- glibc-2.17-c758a686/resolv/nss_dns/dns-host.c ++++ glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +@@ -820,26 +820,19 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + linebuflen -= n; + continue; + } +- if (__builtin_expect (type == T_SIG, 0) +- || __builtin_expect (type == T_KEY, 0) +- || __builtin_expect (type == T_NXT, 0)) +- { +- /* We don't support DNSSEC yet. For now, ignore the record +- and send a low priority message to syslog. */ +- syslog (LOG_DEBUG | LOG_AUTH, +- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", +- qname, p_class (C_IN), p_type(qtype), p_type (type)); +- cp += n; +- continue; +- } + + if (type == T_A && qtype == T_AAAA && map) + have_to_map = 1; + else if (__builtin_expect (type != qtype, 0)) + { +- syslog (LOG_NOTICE | LOG_AUTH, +- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", +- qname, p_class (C_IN), p_type (qtype), p_type (type)); ++ /* Log a low priority message if we get an unexpected record, but ++ skip it if we are using DNSSEC since it uses many different types ++ in responses that do not match QTYPE. */ ++ if ((_res.options & RES_USE_DNSSEC) == 0) ++ syslog (LOG_NOTICE | LOG_AUTH, ++ "gethostby*.getanswer: asked for \"%s %s %s\", " ++ "got type \"%s\"", ++ qname, p_class (C_IN), p_type (qtype), p_type (type)); + cp += n; + continue; /* XXX - had_error++ ? */ + } diff --git a/SOURCES/glibc-rh1188235.patch b/SOURCES/glibc-rh1188235.patch new file mode 100644 index 00000000..8510391f --- /dev/null +++ b/SOURCES/glibc-rh1188235.patch @@ -0,0 +1,89 @@ +commit 5bd80bfe9ca0d955bfbbc002781bc7b01b6bcb06 +Author: Paul Pluzhnikov +Date: Fri Feb 6 00:30:42 2015 -0500 + + CVE-2015-1472: wscanf allocates too little memory + + BZ #16618 + + Under certain conditions wscanf can allocate too little memory for the + to-be-scanned arguments and overflow the allocated buffer. The + implementation now correctly computes the required buffer size when + using malloc. + + A regression test was added to tst-sscanf. + +--- glibc-2.17-c758a686/stdio-common/vfscanf.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/stdio-common/vfscanf.c 2015-05-28 14:01:58.512816390 -0400 +@@ -272,9 +272,10 @@ + if (__builtin_expect (wpsize == wpmax, 0)) \ + { \ + CHAR_T *old = wp; \ +- size_t newsize = (UCHAR_MAX + 1 > 2 * wpmax \ +- ? UCHAR_MAX + 1 : 2 * wpmax); \ +- if (use_malloc || !__libc_use_alloca (newsize)) \ ++ bool fits = __glibc_likely (wpmax <= SIZE_MAX / sizeof (CHAR_T) / 2); \ ++ size_t wpneed = MAX (UCHAR_MAX + 1, 2 * wpmax); \ ++ size_t newsize = fits ? wpneed * sizeof (CHAR_T) : SIZE_MAX; \ ++ if (!__libc_use_alloca (newsize)) \ + { \ + wp = realloc (use_malloc ? wp : NULL, newsize); \ + if (wp == NULL) \ +@@ -286,14 +287,13 @@ + } \ + if (! use_malloc) \ + MEMCPY (wp, old, wpsize); \ +- wpmax = newsize; \ ++ wpmax = wpneed; \ + use_malloc = true; \ + } \ + else \ + { \ + size_t s = wpmax * sizeof (CHAR_T); \ +- wp = (CHAR_T *) extend_alloca (wp, s, \ +- newsize * sizeof (CHAR_T)); \ ++ wp = (CHAR_T *) extend_alloca (wp, s, newsize); \ + wpmax = s / sizeof (CHAR_T); \ + if (old != NULL) \ + MEMCPY (wp, old, wpsize); \ +--- glibc-2.17-c758a686/stdio-common/tst-sscanf.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/stdio-common/tst-sscanf.c 2015-06-03 13:56:10.883924259 -0400 +@@ -196,5 +196,38 @@ + } + } + ++ /* BZ #16618 ++ The test will segfault during SSCANF if the buffer overflow ++ is not fixed. The size of `s` is such that it forces the use ++ of malloc internally and this triggers the incorrect computation. ++ Thus the value for SIZE is arbitrariy high enough that malloc ++ is used. */ ++ { ++#define SIZE 131072 ++ CHAR *s = malloc ((SIZE + 1) * sizeof (*s)); ++ if (s == NULL) ++ abort (); ++ for (size_t i = 0; i < SIZE; i++) ++ s[i] = L('0'); ++ s[SIZE] = L('\0'); ++ int i = 42; ++ /* Scan multi-digit zero into `i`. */ ++ if (SSCANF (s, L("%d"), &i) != 1) ++ { ++ printf ("FAIL: bug16618: SSCANF did not read one input item.\n"); ++ result = 1; ++ } ++ if (i != 0) ++ { ++ printf ("FAIL: bug16618: Value of `i` was not zero as expected.\n"); ++ result = 1; ++ } ++ free (s); ++ if (result != 1) ++ printf ("PASS: bug16618: Did not crash.\n"); ++#undef SIZE ++ } ++ ++ + return result; + } diff --git a/SOURCES/glibc-rh1189278-1.patch b/SOURCES/glibc-rh1189278-1.patch new file mode 100644 index 00000000..7783c4c0 --- /dev/null +++ b/SOURCES/glibc-rh1189278-1.patch @@ -0,0 +1,67 @@ +# +# In rhel-6.x the Makerules are not entirely as mature as they are +# in glibc 2.21 (from which the example link-libc-args is taken from). +# In rhel-6.x the applications are not built like their counterpart +# real applications, and because of that compiling DSOs that use TLS +# will fail with undefined references to __tls_get_addr which resides +# in ld.so and is never included in the link. This patch enhances +# only the build-module and build-module-asneeded targets to include +# a more fully and correct link line as the compiler driver would use +# when constructing an application or DSO. We do not adjust the link +# lines used to build lib* targets. +# +# The rest of this patch is brought in by glibc-rh1292018-0a.patch +# where we need to link against ld.so from libm.so. +# + +commit fab7ce3f5b4060bf62659e8b58529de4156b5a2f +Author: Joseph Myers +Date: Fri May 31 16:16:33 2013 +0000 + + Link extra-libs consistently with libc and ld.so. + +diff -urN glibc-2.17-c758a686/Makerules glibc-2.17-c758a686/Makerules +--- glibc-2.17-c758a686/Makerules 2015-02-18 19:53:00.000000000 -0500 ++++ glibc-2.17-c758a686/Makerules 2015-02-18 20:08:33.299000028 -0500 +@@ -437,6 +437,25 @@ + load-map-file = $(map-file:%=-Wl,--version-script=%) + endif + ++# Compiler arguments to use to link a shared object with libc and ++# ld.so. This is intended to be as similar as possible to a default ++# link with an installed libc. ++link-libc-args = -Wl,--start-group \ ++ $(libc-for-link) \ ++ $(common-objpfx)libc_nonshared.a \ ++ $(as-needed) $(elf-objpfx)ld.so $(no-as-needed) \ ++ -Wl,--end-group ++ ++# The corresponding shared libc to use. This may be modified for a ++# particular target. ++libc-for-link = $(common-objpfx)libc.so ++ ++# The corresponding dependencies. As these are used in dependencies, ++# not just commands, they cannot use target-specific variables so need ++# to name both possible libc.so objects. ++link-libc-deps = $(common-objpfx)libc.so $(common-objpfx)linkobj/libc.so \ ++ $(common-objpfx)libc_nonshared.a $(elf-objpfx)ld.so ++ + # Pattern rule to build a shared object from an archive of PIC objects. + # This must come after the installation rules so Make doesn't try to + # build shared libraries in place from the installed *_pic.a files. +@@ -518,12 +537,13 @@ + # not for shared objects + define build-module + $(build-module-helper) -o $@ $(shlib-lds-flags) \ +- $(csu-objpfx)abi-note.o $(build-module-objlist) ++ $(csu-objpfx)abi-note.o $(build-module-objlist) $(link-libc-args) + endef + define build-module-asneeded + $(build-module-helper) -o $@ $(shlib-lds-flags) \ + $(csu-objpfx)abi-note.o \ +- -Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed ++ -Wl,--as-needed $(build-module-objlist) -Wl,--no-as-needed \ ++ $(link-libc-args) + endef + + build-module-helper-objlist = \ diff --git a/SOURCES/glibc-rh1189278.patch b/SOURCES/glibc-rh1189278.patch new file mode 100644 index 00000000..01e2ffcb --- /dev/null +++ b/SOURCES/glibc-rh1189278.patch @@ -0,0 +1,407 @@ +# +# Based on this upstream commit: +# +# commit d8dd00805b8f3a011735d7a407097fb1c408d867 +# Author: H.J. Lu +# Date: Fri Nov 28 07:54:07 2014 -0800 +# +# Resize DTV if the current DTV isn't big enough +# +# This patch changes _dl_allocate_tls_init to resize DTV if the current DTV +# isn't big enough. Tested on X86-64, x32 and ia32. +# +# [BZ #13862] +# * elf/dl-tls.c: Include . +# (oom): Remove #ifdef SHARED/#endif. +# (_dl_static_dtv, _dl_initial_dtv): Moved before ... +# (_dl_resize_dtv): This. Extracted from _dl_update_slotinfo. +# (_dl_allocate_tls_init): Resize DTV if the current DTV isn't +# big enough. +# (_dl_update_slotinfo): Call _dl_resize_dtv to resize DTV. +# * nptl/Makefile (tests): Add tst-stack4. +# (modules-names): Add tst-stack4mod. +# ($(objpfx)tst-stack4): New. +# (tst-stack4mod.sos): Likewise. +# ($(objpfx)tst-stack4.out): Likewise. +# ($(tst-stack4mod.sos)): Likewise. +# (clean): Likewise. +# * nptl/tst-stack4.c: New file. +# * nptl/tst-stack4mod.c: Likewise. +# +diff -urN glibc-2.17-c758a686/elf/dl-tls.c glibc-2.17-c758a686/elf/dl-tls.c +--- glibc-2.17-c758a686/elf/dl-tls.c 2015-02-18 14:15:28.078461873 -0500 ++++ glibc-2.17-c758a686/elf/dl-tls.c 2015-02-18 14:38:37.630374771 -0500 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -35,14 +36,12 @@ + + + /* Out-of-memory handler. */ +-#ifdef SHARED + static void + __attribute__ ((__noreturn__)) + oom (void) + { + _dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n"); + } +-#endif + + + size_t +@@ -392,6 +391,52 @@ + return result; + } + ++static dtv_t * ++_dl_resize_dtv (dtv_t *dtv) ++{ ++ /* Resize the dtv. */ ++ dtv_t *newp; ++ /* Load GL(dl_tls_max_dtv_idx) atomically since it may be written to by ++ other threads concurrently. -- We don't have the required atomic ++ infrastructure to load dl_tls_max_dtv_idx atomically, but on all the ++ architectures we care about it should load atomically. If this had ++ an atomic_load_acquire we would still be missing the releases for ++ the writes. */ ++ size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS; ++ size_t oldsize = dtv[-1].counter; ++ ++#if SHARED ++ if (dtv == GL(dl_initial_dtv)) ++ { ++ /* This is the initial dtv that was either statically allocated in ++ __libc_setup_tls or allocated during rtld startup using the ++ dl-minimal.c malloc instead of the real malloc. We can't free ++ it, we have to abandon the old storage. */ ++ ++ newp = malloc ((2 + newsize) * sizeof (dtv_t)); ++ if (newp == NULL) ++ oom (); ++ memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t)); ++ } ++ else ++#endif ++ { ++ newp = realloc (&dtv[-1], ++ (2 + newsize) * sizeof (dtv_t)); ++ if (newp == NULL) ++ oom (); ++ } ++ ++ newp[0].counter = newsize; ++ ++ /* Clear the newly allocated part. */ ++ memset (newp + 2 + oldsize, '\0', ++ (newsize - oldsize) * sizeof (dtv_t)); ++ ++ /* Return the generation counter. */ ++ return &newp[1]; ++} ++ + + void * + internal_function +@@ -406,6 +451,16 @@ + size_t total = 0; + size_t maxgen = 0; + ++ /* Check if the current dtv is big enough. */ ++ if (dtv[-1].counter < GL(dl_tls_max_dtv_idx)) ++ { ++ /* Resize the dtv. */ ++ dtv = _dl_resize_dtv (dtv); ++ ++ /* Install this new dtv in the thread data structures. */ ++ INSTALL_DTV (result, &dtv[-1]); ++ } ++ + /* We have to prepare the dtv for all currently loaded modules using + TLS. For those which are dynamically loaded we add the values + indicating deferred allocation. */ +@@ -637,41 +692,10 @@ + assert (total + cnt == modid); + if (dtv[-1].counter < modid) + { +- /* Reallocate the dtv. */ +- dtv_t *newp; +- size_t newsize = GL(dl_tls_max_dtv_idx) + DTV_SURPLUS; +- size_t oldsize = dtv[-1].counter; +- +- assert (map->l_tls_modid <= newsize); +- +- if (dtv == GL(dl_initial_dtv)) +- { +- /* This is the initial dtv that was allocated +- during rtld startup using the dl-minimal.c +- malloc instead of the real malloc. We can't +- free it, we have to abandon the old storage. */ +- +- newp = malloc ((2 + newsize) * sizeof (dtv_t)); +- if (newp == NULL) +- oom (); +- memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t)); +- } +- else +- { +- newp = realloc (&dtv[-1], +- (2 + newsize) * sizeof (dtv_t)); +- if (newp == NULL) +- oom (); +- } +- +- newp[0].counter = newsize; +- +- /* Clear the newly allocated part. */ +- memset (newp + 2 + oldsize, '\0', +- (newsize - oldsize) * sizeof (dtv_t)); ++ /* Resize the dtv. */ ++ dtv = _dl_resize_dtv (dtv); + +- /* Point dtv to the generation counter. */ +- dtv = &newp[1]; ++ assert (modid <= dtv[-1].counter); + + /* Install this new dtv in the thread data + structures. */ +diff -urN glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686/nptl/Makefile +--- glibc-2.17-c758a686/nptl/Makefile 2015-02-18 14:15:28.073462028 -0500 ++++ glibc-2.17-c758a686/nptl/Makefile 2015-02-18 14:15:49.817786667 -0500 +@@ -251,7 +251,7 @@ + tst-exec1 tst-exec2 tst-exec3 tst-exec4 \ + tst-exit1 tst-exit2 tst-exit3 \ + tst-stdio1 tst-stdio2 \ +- tst-stack1 tst-stack2 tst-stack3 tst-pthread-getattr \ ++ tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \ + tst-unload \ + tst-dlsym1 \ + tst-sysconf \ +@@ -297,7 +297,7 @@ + + modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ + tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ +- tst-tls5modd tst-tls5mode tst-tls5modf \ ++ tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ + tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod + extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o + test-extras += $(modules-names) tst-cleanup4aux +@@ -459,6 +459,19 @@ + $(common-objpfx)malloc/mtrace $(objpfx)tst-stack3.mtrace > $@ + generated += tst-stack3-mem tst-stack3.mtrace + ++$(objpfx)tst-stack4: $(libdl) $(shared-thread-library) ++tst-stack4mod.sos=$(shell for i in 0 1 2 3 4 5 6 7 8 9 10 \ ++ 11 12 13 14 15 16 17 18 19; do \ ++ for j in 0 1 2 3 4 5 6 7 8 9 10 \ ++ 11 12 13 14 15 16 17 18 19; do \ ++ echo $(objpfx)tst-stack4mod-$$i-$$j.so; \ ++ done; done) ++$(objpfx)tst-stack4.out: $(tst-stack4mod.sos) ++$(tst-stack4mod.sos): $(objpfx)tst-stack4mod.so ++ cp -f $< $@ ++clean: ++ rm -f $(tst-stack4mod.sos) ++ + $(objpfx)tst-cleanup4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library) + $(objpfx)tst-cleanupx4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library) + +diff -urN glibc-2.17-c758a686/nptl/tst-stack4.c glibc-2.17-c758a686/nptl/tst-stack4.c +--- glibc-2.17-c758a686/nptl/tst-stack4.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/nptl/tst-stack4.c 2015-02-18 14:15:49.817786667 -0500 +@@ -0,0 +1,159 @@ ++/* Test DTV size oveflow when pthread_create reuses old DTV and TLS is ++ used by dlopened shared object. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* The choices of thread count, and file counts are arbitary. ++ The point is simply to run enough threads that an exiting ++ thread has it's stack reused by another thread at the same ++ time as new libraries have been loaded. */ ++#define DSO_SHARED_FILES 20 ++#define DSO_OPEN_THREADS 20 ++#define DSO_EXEC_THREADS 2 ++ ++/* Used to make sure that only one thread is calling dlopen and dlclose ++ at a time. */ ++pthread_mutex_t g_lock; ++ ++typedef void (*function) (void); ++ ++void * ++dso_invoke(void *dso_fun) ++{ ++ function *fun_vec = (function *) dso_fun; ++ int dso; ++ ++ for (dso = 0; dso < DSO_SHARED_FILES; dso++) ++ (*fun_vec[dso]) (); ++ ++ pthread_exit (NULL); ++} ++ ++void * ++dso_process (void * p) ++{ ++ void *handle[DSO_SHARED_FILES]; ++ function fun_vec[DSO_SHARED_FILES]; ++ char dso_path[DSO_SHARED_FILES][100]; ++ int dso; ++ uintptr_t t = (uintptr_t) p; ++ ++ /* Open DSOs and get a function. */ ++ for (dso = 0; dso < DSO_SHARED_FILES; dso++) ++ { ++ sprintf (dso_path[dso], "tst-stack4mod-%i-%i.so", t, dso); ++ ++ pthread_mutex_lock (&g_lock); ++ ++ handle[dso] = dlopen (dso_path[dso], RTLD_NOW); ++ assert (handle[dso]); ++ ++ fun_vec[dso] = (function) dlsym (handle[dso], "function"); ++ assert (fun_vec[dso]); ++ ++ pthread_mutex_unlock (&g_lock); ++ } ++ ++ /* Spawn workers. */ ++ pthread_t thread[DSO_EXEC_THREADS]; ++ int i, ret; ++ uintptr_t result = 0; ++ for (i = 0; i < DSO_EXEC_THREADS; i++) ++ { ++ pthread_mutex_lock (&g_lock); ++ ret = pthread_create (&thread[i], NULL, dso_invoke, (void *) fun_vec); ++ if (ret != 0) ++ { ++ printf ("pthread_create failed: %d\n", ret); ++ result = 1; ++ } ++ pthread_mutex_unlock (&g_lock); ++ } ++ ++ if (!result) ++ for (i = 0; i < DSO_EXEC_THREADS; i++) ++ { ++ ret = pthread_join (thread[i], NULL); ++ if (ret != 0) ++ { ++ printf ("pthread_join failed: %d\n", ret); ++ result = 1; ++ } ++ } ++ ++ /* Close all DSOs. */ ++ for (dso = 0; dso < DSO_SHARED_FILES; dso++) ++ { ++ pthread_mutex_lock (&g_lock); ++ dlclose (handle[dso]); ++ pthread_mutex_unlock (&g_lock); ++ } ++ ++ /* Exit. */ ++ pthread_exit ((void *) result); ++} ++ ++static int ++do_test (void) ++{ ++ pthread_t thread[DSO_OPEN_THREADS]; ++ int i,j; ++ int ret; ++ int result = 0; ++ ++ pthread_mutex_init (&g_lock, NULL); ++ ++ /* 100 is arbitrary here and is known to trigger PR 13862. */ ++ for (j = 0; j < 100; j++) ++ { ++ for (i = 0; i < DSO_OPEN_THREADS; i++) ++ { ++ ret = pthread_create (&thread[i], NULL, dso_process, ++ (void *) (uintptr_t) i); ++ if (ret != 0) ++ { ++ printf ("pthread_create failed: %d\n", ret); ++ result = 1; ++ } ++ } ++ ++ if (result) ++ break; ++ ++ for (i = 0; i < DSO_OPEN_THREADS; i++) ++ { ++ ret = pthread_join (thread[i], NULL); ++ if (ret != 0) ++ { ++ printf ("pthread_join failed: %d\n", ret); ++ result = 1; ++ } ++ } ++ } ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#define TIMEOUT 100 ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/nptl/tst-stack4mod.c glibc-2.17-c758a686/nptl/tst-stack4mod.c +--- glibc-2.17-c758a686/nptl/tst-stack4mod.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/nptl/tst-stack4mod.c 2015-02-18 14:15:49.817786667 -0500 +@@ -0,0 +1,28 @@ ++/* This tests DTV usage with TLS in dlopened shared object. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* 256 is arbitrary here and is known to trigger PR 13862. */ ++__thread int var[256] attribute_hidden = {0}; ++ ++void ++function (void) ++{ ++ int i; ++ for (i = 0; i < sizeof (var) / sizeof (int); i++) ++ var[i] = i; ++} diff --git a/SOURCES/glibc-rh1193797.patch b/SOURCES/glibc-rh1193797.patch new file mode 100644 index 00000000..d52d5252 --- /dev/null +++ b/SOURCES/glibc-rh1193797.patch @@ -0,0 +1,803 @@ +commit cf9313e7d1dd42addd6cf8c9277f0f18a62cdeff +Author: Carlos O'Donell +Date: Fri Mar 13 09:49:24 2015 -0400 + + Enhance nscd's inotify support (Bug 14906). + +--- glibc-2.17-c758a686/nscd/cache.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nscd/cache.c 2015-05-13 13:45:57.259958374 -0400 +@@ -272,28 +272,38 @@ + while (runp != NULL) + { + #ifdef HAVE_INOTIFY +- if (runp->inotify_descr == -1) ++ if (runp->inotify_descr[TRACED_FILE] == -1) + #endif + { + struct stat64 st; + + if (stat64 (runp->fname, &st) < 0) + { ++ /* Print a diagnostic that the traced file was missing. ++ We must not disable tracing since the file might return ++ shortly and we want to reload it at the next pruning. ++ Disabling tracing here would go against the configuration ++ as specified by the user via check-files. */ + char buf[128]; +- /* We cannot stat() the file, disable file checking if the +- file does not exist. */ +- dbg_log (_("cannot stat() file `%s': %s"), ++ dbg_log (_("checking for monitored file `%s': %s"), + runp->fname, strerror_r (errno, buf, sizeof (buf))); +- if (errno == ENOENT) +- table->check_file = 0; + } + else + { +- if (st.st_mtime != table->file_mtime) ++ /* This must be `!=` to catch cases where users turn the ++ clocks back and we still want to detect any time difference ++ in mtime. */ ++ if (st.st_mtime != runp->mtime) + { +- /* The file changed. Invalidate all entries. */ ++ dbg_log (_("monitored file `%s` changed (mtime)"), ++ runp->fname); ++ /* The file changed. Invalidate all entries. */ + now = LONG_MAX; +- table->file_mtime = st.st_mtime; ++ runp->mtime = st.st_mtime; ++#ifdef HAVE_INOTIFY ++ /* Attempt to install a watch on the file. */ ++ install_watches (runp); ++#endif + } + } + } +--- glibc-2.17-c758a686/nscd/connections.c 2015-05-12 15:03:02.870274443 -0400 ++++ glibc-2.17-c758a686/nscd/connections.c 2015-05-13 13:45:57.259958374 -0400 +@@ -974,6 +974,44 @@ + finish_drop_privileges (); + } + ++#ifdef HAVE_INOTIFY ++#define TRACED_FILE_MASK (IN_DELETE_SELF | IN_CLOSE_WRITE | IN_MOVE_SELF) ++#define TRACED_DIR_MASK (IN_DELETE_SELF | IN_CREATE | IN_MOVED_TO | IN_MOVE_SELF) ++void ++install_watches (struct traced_file *finfo) ++{ ++ /* Use inotify support if we have it. */ ++ if (finfo->inotify_descr[TRACED_FILE] < 0) ++ finfo->inotify_descr[TRACED_FILE] = inotify_add_watch (inotify_fd, ++ finfo->fname, ++ TRACED_FILE_MASK); ++ if (finfo->inotify_descr[TRACED_FILE] < 0) ++ { ++ dbg_log (_("disabled inotify-based monitoring for file `%s': %s"), ++ finfo->fname, strerror (errno)); ++ return; ++ } ++ dbg_log (_("monitoring file `%s` (%d)"), ++ finfo->fname, finfo->inotify_descr[TRACED_FILE]); ++ /* Additionally listen for events in the file's parent directory. ++ We do this because the file to be watched might be ++ deleted and then added back again. When it is added back again ++ we must re-add the watch. We must also cover IN_MOVED_TO to ++ detect a file being moved into the directory. */ ++ if (finfo->inotify_descr[TRACED_DIR] < 0) ++ finfo->inotify_descr[TRACED_DIR] = inotify_add_watch (inotify_fd, ++ finfo->dname, ++ TRACED_DIR_MASK); ++ if (finfo->inotify_descr[TRACED_DIR] < 0) ++ { ++ dbg_log (_("disabled inotify-based monitoring for directory `%s': %s"), ++ finfo->fname, strerror (errno)); ++ return; ++ } ++ dbg_log (_("monitoring directory `%s` (%d)"), ++ finfo->dname, finfo->inotify_descr[TRACED_DIR]); ++} ++#endif + + void + register_traced_file (size_t dbidx, struct traced_file *finfo) +@@ -982,30 +1020,24 @@ + return; + + if (__builtin_expect (debug_level > 0, 0)) +- dbg_log (_("register trace file %s for database %s"), +- finfo->fname, dbnames[dbidx]); ++ dbg_log (_("monitoring file `%s' for database `%s' (%d)"), ++ finfo->fname, dbnames[dbidx], ++ finfo->inotify_descr[TRACED_DIR]); + + #ifdef HAVE_INOTIFY +- if (inotify_fd < 0 +- || (finfo->inotify_descr = inotify_add_watch (inotify_fd, finfo->fname, +- IN_DELETE_SELF +- | IN_MODIFY)) < 0) ++ install_watches (finfo); + #endif +- { +- /* We need the modification date of the file. */ +- struct stat64 st; +- +- if (stat64 (finfo->fname, &st) < 0) +- { +- /* We cannot stat() the file, disable file checking. */ +- dbg_log (_("cannot stat() file `%s': %s"), +- finfo->fname, strerror (errno)); +- return; +- } + +- finfo->inotify_descr = -1; +- finfo->mtime = st.st_mtime; ++ struct stat64 st; ++ if (stat64 (finfo->fname, &st) < 0) ++ { ++ /* We cannot stat() the file. Set mtime to zero and try again later. */ ++ dbg_log (_("stat failed for file `%s'; will try again later: %s"), ++ finfo->fname, strerror (errno)); ++ finfo->mtime = 0; + } ++ else ++ finfo->mtime = st.st_mtime; + + /* Queue up the file name. */ + finfo->next = dbs[dbidx].traced_files; +@@ -1030,20 +1062,27 @@ + for (number = pwddb; number < lastdb; ++number) + if (strcmp (key, dbnames[number]) == 0) + { +- if (number == hstdb) ++ struct traced_file *runp = dbs[number].traced_files; ++ while (runp != NULL) + { +- struct traced_file *runp = dbs[hstdb].traced_files; +- while (runp != NULL) +- if (runp->call_res_init) +- { +- res_init (); +- break; +- } +- else +- runp = runp->next; ++ /* Make sure we reload from file when checking mtime. */ ++ runp->mtime = 0; ++#ifdef HAVE_INOTIFY ++ /* During an invalidation we try to reload the traced ++ file watches. This allows the user to re-sync if ++ inotify events were lost. Similar to what we do during ++ pruning. */ ++ install_watches (runp); ++#endif ++ if (runp->call_res_init) ++ { ++ res_init (); ++ break; ++ } ++ runp = runp->next; + } + break; +- } ++ } + + if (number == lastdb) + { +@@ -1871,6 +1910,234 @@ + static time_t *starttime; + + ++#ifdef HAVE_INOTIFY ++/* Inotify event for changed file. */ ++union __inev ++{ ++ struct inotify_event i; ++# ifndef PATH_MAX ++# define PATH_MAX 1024 ++# endif ++ char buf[sizeof (struct inotify_event) + PATH_MAX]; ++}; ++ ++/* Returns 0 if the file is there otherwise -1. */ ++int ++check_file (struct traced_file *finfo) ++{ ++ struct stat64 st; ++ /* We could check mtime and if different re-add ++ the watches, and invalidate the database, but we ++ don't because we are called from inotify_check_files ++ which should be doing that work. If sufficient inotify ++ events were lost then the next pruning or invalidation ++ will do the stat and mtime check. We don't do it here to ++ keep the logic simple. */ ++ if (stat64 (finfo->fname, &st) < 0) ++ return -1; ++ return 0; ++} ++ ++/* Process the inotify event in INEV. If the event matches any of the files ++ registered with a database then mark that database as requiring its cache ++ to be cleared. We indicate the cache needs clearing by setting ++ TO_CLEAR[DBCNT] to true for the matching database. */ ++static void ++inotify_check_files (bool *to_clear, union __inev *inev) ++{ ++ /* Check which of the files changed. */ ++ for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt) ++ { ++ struct traced_file *finfo = dbs[dbcnt].traced_files; ++ ++ while (finfo != NULL) ++ { ++ /* The configuration file was moved or deleted. ++ We stop watching it at that point, and reinitialize. */ ++ if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd ++ && ((inev->i.mask & IN_MOVE_SELF) ++ || (inev->i.mask & IN_DELETE_SELF) ++ || (inev->i.mask & IN_IGNORED))) ++ { ++ int ret; ++ bool moved = (inev->i.mask & IN_MOVE_SELF) != 0; ++ ++ if (check_file (finfo) == 0) ++ { ++ dbg_log (_("ignored inotify event for `%s` (file exists)"), ++ finfo->fname); ++ return; ++ } ++ ++ dbg_log (_("monitored file `%s` was %s, removing watch"), ++ finfo->fname, moved ? "moved" : "deleted"); ++ /* File was moved out, remove the watch. Watches are ++ automatically removed when the file is deleted. */ ++ if (moved) ++ { ++ ret = inotify_rm_watch (inotify_fd, inev->i.wd); ++ if (ret < 0) ++ dbg_log (_("failed to remove file watch `%s`: %s"), ++ finfo->fname, strerror (errno)); ++ } ++ finfo->inotify_descr[TRACED_FILE] = -1; ++ to_clear[dbcnt] = true; ++ if (finfo->call_res_init) ++ res_init (); ++ return; ++ } ++ /* The configuration file was open for writing and has just closed. ++ We reset the cache and reinitialize. */ ++ if (finfo->inotify_descr[TRACED_FILE] == inev->i.wd ++ && inev->i.mask & IN_CLOSE_WRITE) ++ { ++ /* Mark cache as needing to be cleared and reinitialize. */ ++ dbg_log (_("monitored file `%s` was written to"), finfo->fname); ++ to_clear[dbcnt] = true; ++ if (finfo->call_res_init) ++ res_init (); ++ return; ++ } ++ /* The parent directory was moved or deleted. We trigger one last ++ invalidation. At the next pruning or invalidation we may add ++ this watch back if the file is present again. */ ++ if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd ++ && ((inev->i.mask & IN_DELETE_SELF) ++ || (inev->i.mask & IN_MOVE_SELF) ++ || (inev->i.mask & IN_IGNORED))) ++ { ++ bool moved = (inev->i.mask & IN_MOVE_SELF) != 0; ++ /* The directory watch may have already been removed ++ but we don't know so we just remove it again and ++ ignore the error. Then we remove the file watch. ++ Note: watches are automatically removed for deleted ++ files. */ ++ if (moved) ++ inotify_rm_watch (inotify_fd, inev->i.wd); ++ if (finfo->inotify_descr[TRACED_FILE] != -1) ++ { ++ dbg_log (_("monitored parent directory `%s` was %s, removing watch on `%s`"), ++ finfo->dname, moved ? "moved" : "deleted", finfo->fname); ++ if (inotify_rm_watch (inotify_fd, finfo->inotify_descr[TRACED_FILE]) < 0) ++ dbg_log (_("failed to remove file watch `%s`: %s"), ++ finfo->dname, strerror (errno)); ++ } ++ finfo->inotify_descr[TRACED_FILE] = -1; ++ finfo->inotify_descr[TRACED_DIR] = -1; ++ to_clear[dbcnt] = true; ++ if (finfo->call_res_init) ++ res_init (); ++ /* Continue to the next entry since this might be the ++ parent directory for multiple registered files and ++ we want to remove watches for all registered files. */ ++ continue; ++ } ++ /* The parent directory had a create or moved to event. */ ++ if (finfo->inotify_descr[TRACED_DIR] == inev->i.wd ++ && ((inev->i.mask & IN_MOVED_TO) ++ || (inev->i.mask & IN_CREATE)) ++ && strcmp (inev->i.name, finfo->sfname) == 0) ++ { ++ /* We detected a directory change. We look for the creation ++ of the file we are tracking or the move of the same file ++ into the directory. */ ++ int ret; ++ dbg_log (_("monitored file `%s` was %s, adding watch"), ++ finfo->fname, ++ inev->i.mask & IN_CREATE ? "created" : "moved into place"); ++ /* File was moved in or created. Regenerate the watch. */ ++ if (finfo->inotify_descr[TRACED_FILE] != -1) ++ inotify_rm_watch (inotify_fd, ++ finfo->inotify_descr[TRACED_FILE]); ++ ++ ret = inotify_add_watch (inotify_fd, ++ finfo->fname, ++ TRACED_FILE_MASK); ++ if (ret < 0) ++ dbg_log (_("failed to add file watch `%s`: %s"), ++ finfo->fname, strerror (errno)); ++ ++ finfo->inotify_descr[TRACED_FILE] = ret; ++ ++ /* The file is new or moved so mark cache as needing to ++ be cleared and reinitialize. */ ++ to_clear[dbcnt] = true; ++ if (finfo->call_res_init) ++ res_init (); ++ ++ /* Done re-adding the watch. Don't return, we may still ++ have other files in this same directory, same watch ++ descriptor, and need to process them. */ ++ } ++ /* Other events are ignored, and we move on to the next file. */ ++ finfo = finfo->next; ++ } ++ } ++} ++ ++/* If an entry in the array of booleans TO_CLEAR is TRUE then clear the cache ++ for the associated database, otherwise do nothing. The TO_CLEAR array must ++ have LASTDB entries. */ ++static inline void ++clear_db_cache (bool *to_clear) ++{ ++ for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt) ++ if (to_clear[dbcnt]) ++ { ++ pthread_mutex_lock (&dbs[dbcnt].prune_lock); ++ dbs[dbcnt].clear_cache = 1; ++ pthread_mutex_unlock (&dbs[dbcnt].prune_lock); ++ pthread_cond_signal (&dbs[dbcnt].prune_cond); ++ } ++} ++ ++int ++handle_inotify_events (void) ++{ ++ bool to_clear[lastdb] = { false, }; ++ union __inev inev; ++ ++ /* Read all inotify events for files registered via ++ register_traced_file(). */ ++ while (1) ++ { ++ /* Potentially read multiple events into buf. */ ++ ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, ++ &inev.buf, ++ sizeof (inev))); ++ if (nb < (ssize_t) sizeof (struct inotify_event)) ++ { ++ /* Not even 1 event. */ ++ if (__glibc_unlikely (nb == -1 && errno != EAGAIN)) ++ return -1; ++ /* Done reading events that are ready. */ ++ break; ++ } ++ /* Process all events. The normal inotify interface delivers ++ complete events on a read and never a partial event. */ ++ char *eptr = &inev.buf[0]; ++ ssize_t count; ++ while (1) ++ { ++ /* Check which of the files changed. */ ++ inotify_check_files (to_clear, &inev); ++ count = sizeof (struct inotify_event) + inev.i.len; ++ eptr += count; ++ nb -= count; ++ if (nb >= (ssize_t) sizeof (struct inotify_event)) ++ memcpy (&inev, eptr, nb); ++ else ++ break; ++ } ++ continue; ++ } ++ /* Actually perform the cache clearing. */ ++ clear_db_cache (to_clear); ++ return 0; ++} ++ ++#endif ++ + static void + __attribute__ ((__noreturn__)) + main_loop_poll (void) +@@ -1975,72 +2242,21 @@ + { + if (conns[1].revents != 0) + { +- bool to_clear[lastdb] = { false, }; +- union +- { +-# ifndef PATH_MAX +-# define PATH_MAX 1024 +-# endif +- struct inotify_event i; +- char buf[sizeof (struct inotify_event) + PATH_MAX]; +- } inev; +- +- while (1) +- { +- ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev, +- sizeof (inev))); +- if (nb < (ssize_t) sizeof (struct inotify_event)) +- { +- if (__builtin_expect (nb == -1 && errno != EAGAIN, +- 0)) +- { +- /* Something went wrong when reading the inotify +- data. Better disable inotify. */ +- dbg_log (_("\ +-disabled inotify after read error %d"), +- errno); +- conns[1].fd = -1; +- firstfree = 1; +- if (nused == 2) +- nused = 1; +- close (inotify_fd); +- inotify_fd = -1; +- } +- break; +- } +- +- /* Check which of the files changed. */ +- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt) +- { +- struct traced_file *finfo = dbs[dbcnt].traced_files; +- +- while (finfo != NULL) +- { +- if (finfo->inotify_descr == inev.i.wd) +- { +- to_clear[dbcnt] = true; +- if (finfo->call_res_init) +- res_init (); +- goto next; +- } +- +- finfo = finfo->next; +- } +- } +- next:; +- } +- +- /* Actually perform the cache clearing. */ +- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt) +- if (to_clear[dbcnt]) +- { +- pthread_mutex_lock (&dbs[dbcnt].prune_lock); +- dbs[dbcnt].clear_cache = 1; +- pthread_mutex_unlock (&dbs[dbcnt].prune_lock); +- pthread_cond_signal (&dbs[dbcnt].prune_cond); +- } +- +- --n; ++ int ret; ++ ret = handle_inotify_events (); ++ if (ret == -1) ++ { ++ /* Something went wrong when reading the inotify ++ data. Better disable inotify. */ ++ dbg_log (_("disabled inotify-based monitoring after read error %d"), errno); ++ conns[1].fd = -1; ++ firstfree = 1; ++ if (nused == 2) ++ nused = 1; ++ close (inotify_fd); ++ inotify_fd = -1; ++ } ++ --n; + } + + first = 2; +@@ -2207,64 +2423,18 @@ + # ifdef HAVE_INOTIFY + else if (revs[cnt].data.fd == inotify_fd) + { +- bool to_clear[lastdb] = { false, }; +- union +- { +- struct inotify_event i; +- char buf[sizeof (struct inotify_event) + PATH_MAX]; +- } inev; +- +- while (1) ++ int ret; ++ ret = handle_inotify_events (); ++ if (ret == -1) + { +- ssize_t nb = TEMP_FAILURE_RETRY (read (inotify_fd, &inev, +- sizeof (inev))); +- if (nb < (ssize_t) sizeof (struct inotify_event)) +- { +- if (__builtin_expect (nb == -1 && errno != EAGAIN, 0)) +- { +- /* Something went wrong when reading the inotify +- data. Better disable inotify. */ +- dbg_log (_("disabled inotify after read error %d"), +- errno); +- (void) epoll_ctl (efd, EPOLL_CTL_DEL, inotify_fd, +- NULL); +- close (inotify_fd); +- inotify_fd = -1; +- } +- break; +- } +- +- /* Check which of the files changed. */ +- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt) +- { +- struct traced_file *finfo = dbs[dbcnt].traced_files; +- +- while (finfo != NULL) +- { +- if (finfo->inotify_descr == inev.i.wd) +- { +- to_clear[dbcnt] = true; +- if (finfo->call_res_init) +- res_init (); +- goto next; +- } +- +- finfo = finfo->next; +- } +- } +- next:; +- } +- +- /* Actually perform the cache clearing. */ +- for (size_t dbcnt = 0; dbcnt < lastdb; ++dbcnt) +- if (to_clear[dbcnt]) +- { +- pthread_mutex_lock (&dbs[dbcnt].prune_lock); +- dbs[dbcnt].clear_cache = 1; +- pthread_mutex_unlock (&dbs[dbcnt].prune_lock); +- pthread_cond_signal (&dbs[dbcnt].prune_cond); +- } +- } ++ /* Something went wrong when reading the inotify ++ data. Better disable inotify. */ ++ dbg_log (_("disabled inotify-based monitoring after read error %d"), errno); ++ close (inotify_fd); ++ inotify_fd = -1; ++ break; ++ } ++ } + # endif + # ifdef HAVE_NETLINK + else if (revs[cnt].data.fd == nl_status_fd) +@@ -2300,7 +2470,9 @@ + no reply in too long of a time. */ + time_t laststart = now - ACCEPT_TIMEOUT; + assert (starttime[sock] == 0); ++# ifdef HAVE_INOTIFY + assert (inotify_fd == -1 || starttime[inotify_fd] == 0); ++# endif + assert (nl_status_fd == -1 || starttime[nl_status_fd] == 0); + for (int cnt = highest; cnt > STDERR_FILENO; --cnt) + if (starttime[cnt] != 0 && starttime[cnt] < laststart) +--- glibc-2.17-c758a686/nscd/nscd.h 2015-05-12 15:03:02.870274443 -0400 ++++ glibc-2.17-c758a686/nscd/nscd.h 2015-05-13 13:45:57.259958374 -0400 +@@ -61,17 +61,67 @@ + 80% of the thread stack size. */ + #define MAX_STACK_USE ((8 * NSCD_THREAD_STACKSIZE) / 10) + +- +-/* Registered filename used to fill database. */ ++/* Records the file registered per database that when changed ++ or modified requires invalidating the database. */ + struct traced_file + { ++ /* Tracks the last modified time of the traced file. */ + time_t mtime; ++ /* Support multiple registered files per database. */ + struct traced_file *next; + int call_res_init; +- int inotify_descr; ++ /* Requires Inotify support to do anything useful. */ ++#define TRACED_FILE 0 ++#define TRACED_DIR 1 ++ int inotify_descr[2]; ++# ifndef PATH_MAX ++# define PATH_MAX 1024 ++# endif ++ /* The parent directory is used to scan for creation/deletion. */ ++ char dname[PATH_MAX]; ++ /* Just the name of the file with no directory component. */ ++ char *sfname; ++ /* The full-path name of the registered file. */ + char fname[]; + }; + ++/* Initialize a `struct traced_file`. As input we need the name ++ of the file, and if invalidation requires calling res_init. ++ If CRINIT is 1 then res_init will be called after invalidation ++ or if the traced file is changed in any way, otherwise it will ++ not. */ ++static inline void ++init_traced_file(struct traced_file *file, const char *fname, int crinit) ++{ ++ char *dname; ++ file->mtime = 0; ++ file->inotify_descr[TRACED_FILE] = -1; ++ file->inotify_descr[TRACED_DIR] = -1; ++ strcpy (file->fname, fname); ++ /* Compute the parent directory name and store a copy. The copy makes ++ it much faster to add/remove watches while nscd is running instead ++ of computing this over and over again in a temp buffer. */ ++ file->dname[0] = '\0'; ++ dname = strrchr (fname, '/'); ++ if (dname != NULL) ++ { ++ size_t len = (size_t)(dname - fname); ++ if (len > sizeof (file->dname)) ++ abort (); ++ strncpy (file->dname, file->fname, len); ++ file->dname[len] = '\0'; ++ } ++ /* The basename is the name just after the last forward slash. */ ++ file->sfname = &dname[1]; ++ file->call_res_init = crinit; ++} ++ ++#define define_traced_file(id, filename) \ ++static union \ ++{ \ ++ struct traced_file file; \ ++ char buf[sizeof (struct traced_file) + sizeof (filename)]; \ ++} id##_traced_file; + + /* Structure describing dynamic part of one database. */ + struct database_dyn +@@ -90,7 +140,6 @@ + int propagate; + struct traced_file *traced_files; + const char *db_filename; +- time_t file_mtime; + size_t suggested_module; + size_t max_db_size; + +@@ -216,6 +265,9 @@ + /* connections.c */ + extern void nscd_init (void); + extern void register_traced_file (size_t dbidx, struct traced_file *finfo); ++#ifdef HAVE_INOTIFY ++extern void install_watches (struct traced_file *finfo); ++#endif + extern void close_sockets (void); + extern void start_threads (void) __attribute__ ((__noreturn__)); + +--- glibc-2.17-c758a686/nss/nss_db/db-init.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nss/nss_db/db-init.c 2015-05-13 13:45:57.269958504 -0400 +@@ -22,35 +22,25 @@ + #include + #include + +-static union +-{ +- struct traced_file file; +- char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "passwd.db")]; +-} pwd_traced_file; +- +-static union +-{ +- struct traced_file file; +- char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "group.db")]; +-} grp_traced_file; ++#define PWD_FILENAME (_PATH_VARDB "passwd.db") ++define_traced_file (pwd, PWD_FILENAME); + +-static union +-{ +- struct traced_file file; +- char buf[sizeof (struct traced_file) + sizeof (_PATH_VARDB "services.db")]; +-} serv_traced_file; ++#define GRP_FILENAME (_PATH_VARDB "group.db") ++define_traced_file (grp, GRP_FILENAME); + ++#define SERV_FILENAME (_PATH_VARDB "services.db") ++define_traced_file (serv, SERV_FILENAME); + + void + _nss_db_init (void (*cb) (size_t, struct traced_file *)) + { +- strcpy (pwd_traced_file.file.fname,_PATH_VARDB "passwd.db"); ++ init_traced_file (&pwd_traced_file.file, PWD_FILENAME, 0); + cb (pwddb, &pwd_traced_file.file); + +- strcpy (grp_traced_file.file.fname, _PATH_VARDB "group.db"); ++ init_traced_file (&grp_traced_file.file, GRP_FILENAME, 0); + cb (grpdb, &grp_traced_file.file); + +- strcpy (serv_traced_file.file.fname, _PATH_VARDB "services.db"); ++ init_traced_file (&serv_traced_file.file, SERV_FILENAME, 0); + cb (servdb, &serv_traced_file.file); + } + +--- glibc-2.17-c758a686/nss/nss_files/files-init.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nss/nss_files/files-init.c 2015-05-13 13:45:57.269958504 -0400 +@@ -18,43 +18,46 @@ + + #ifdef USE_NSCD + ++#include + #include + ++#define PWD_FILENAME "/etc/passwd" ++define_traced_file (pwd, PWD_FILENAME); + +-#define TF(id, filename, ...) \ +-static union \ +-{ \ +- struct traced_file file; \ +- char buf[sizeof (struct traced_file) + sizeof (filename)]; \ +-} id##_traced_file = \ +- { \ +- .file = \ +- { \ +- .fname = filename, ## __VA_ARGS__ \ +- } \ +- } +- +-TF (pwd, "/etc/passwd"); +-TF (grp, "/etc/group"); +-TF (hst, "/etc/hosts"); +-TF (resolv, "/etc/resolv.conf", .call_res_init = 1); +-TF (serv, "/etc/services"); +-TF (netgr, "/etc/netgroup"); +- +- ++#define GRP_FILENAME "/etc/group" ++define_traced_file (grp, GRP_FILENAME); ++ ++#define HST_FILENAME "/etc/hosts" ++define_traced_file (hst, HST_FILENAME); ++ ++#define RESOLV_FILENAME "/etc/resolv.conf" ++define_traced_file (resolv, RESOLV_FILENAME); ++ ++#define SERV_FILENAME "/etc/services" ++define_traced_file (serv, SERV_FILENAME); ++ ++#define NETGR_FILENAME "/etc/netgroup" ++define_traced_file (netgr, NETGR_FILENAME); ++ + void + _nss_files_init (void (*cb) (size_t, struct traced_file *)) + { ++ init_traced_file (&pwd_traced_file.file, PWD_FILENAME, 0); + cb (pwddb, &pwd_traced_file.file); + ++ init_traced_file (&grp_traced_file.file, GRP_FILENAME, 0); + cb (grpdb, &grp_traced_file.file); + ++ init_traced_file (&hst_traced_file.file, HST_FILENAME, 0); + cb (hstdb, &hst_traced_file.file); + ++ init_traced_file (&resolv_traced_file.file, RESOLV_FILENAME, 1); + cb (hstdb, &resolv_traced_file.file); + ++ init_traced_file (&serv_traced_file.file, SERV_FILENAME, 0); + cb (servdb, &serv_traced_file.file); +- ++ ++ init_traced_file (&netgr_traced_file.file, NETGR_FILENAME, 0); + cb (netgrdb, &netgr_traced_file.file); + } diff --git a/SOURCES/glibc-rh1194143.patch b/SOURCES/glibc-rh1194143.patch new file mode 100644 index 00000000..e1f878ba --- /dev/null +++ b/SOURCES/glibc-rh1194143.patch @@ -0,0 +1,18 @@ +commit f9d2d03254a58d92635a311a42253eeed5a40a47 +Author: Andreas Schwab +Date: Mon May 26 18:01:31 2014 +0200 + + Fix invalid file descriptor reuse while sending DNS query (BZ #15946) + +diff --git glibc-2.17-c758a686/resolv/res_send.c glibc-2.17-c758a686/resolv/res_send.c +index 3273d55..af42b8a 100644 +--- glibc-2.17-c758a686/resolv/res_send.c ++++ glibc-2.17-c758a686/resolv/res_send.c +@@ -1410,6 +1410,7 @@ send_dg(res_state statp, + retval = reopen (statp, terrno, ns); + if (retval <= 0) + return retval; ++ pfd[0].fd = EXT(statp).nssocks[ns]; + } + } + goto wait; diff --git a/SOURCES/glibc-rh1195762.patch b/SOURCES/glibc-rh1195762.patch new file mode 100644 index 00000000..f18d5eef --- /dev/null +++ b/SOURCES/glibc-rh1195762.patch @@ -0,0 +1,33 @@ +commit bdf1ff052a8e23d637f2c838fa5642d78fcedc33 +Author: Paul Pluzhnikov +Date: Sun Feb 22 12:01:47 2015 -0800 + + Fix BZ #17269 -- _IO_wstr_overflow integer overflow + +diff --git a/libio/wstrops.c b/libio/wstrops.c +index 43d847d..3993579 100644 +--- a/libio/wstrops.c ++++ b/libio/wstrops.c +@@ -95,8 +95,11 @@ _IO_wstr_overflow (fp, c) + wchar_t *old_buf = fp->_wide_data->_IO_buf_base; + size_t old_wblen = _IO_wblen (fp); + _IO_size_t new_size = 2 * old_wblen + 100; +- if (new_size < old_wblen) ++ ++ if (__glibc_unlikely (new_size < old_wblen) ++ || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t))) + return EOF; ++ + new_buf + = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size + * sizeof (wchar_t)); +@@ -186,6 +189,9 @@ enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) + return 1; + + _IO_size_t newsize = offset + 100; ++ if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t))) ++ return 1; ++ + wchar_t *oldbuf = wd->_IO_buf_base; + wchar_t *newbuf + = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize diff --git a/SOURCES/glibc-rh1197730-1.patch b/SOURCES/glibc-rh1197730-1.patch new file mode 100644 index 00000000..5aa0f060 --- /dev/null +++ b/SOURCES/glibc-rh1197730-1.patch @@ -0,0 +1,104 @@ +commit b3a9f56ba59c3d8eadd3135a1c25c37a63151450 +Author: Andreas Schwab +Date: Wed Jun 18 11:58:45 2014 +0200 + + Don't read past end of pattern in fnmatch (BZ #17062) + +diff --git glibc-2.17-c758a686/posix/fnmatch_loop.c glibc-2.17-c758a686/posix/fnmatch_loop.c +index f79d051..544769b 100644 +--- glibc-2.17-c758a686/posix/fnmatch_loop.c ++++ glibc-2.17-c758a686/posix/fnmatch_loop.c +@@ -899,11 +899,8 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used) + + matched: + /* Skip the rest of the [...] that already matched. */ +- do ++ while ((c = *p++) != L (']')) + { +- ignore_next: +- c = *p++; +- + if (c == L('\0')) + /* [... (unterminated) loses. */ + return FNM_NOMATCH; +@@ -931,12 +928,11 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used) + + if (c < L('a') || c >= L('z')) + { +- p = startp; +- goto ignore_next; ++ p = startp - 2; ++ break; + } + } + p += 2; +- c = *p++; + } + else if (c == L('[') && *p == L('=')) + { +@@ -947,7 +943,6 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used) + if (c != L('=') || p[1] != L(']')) + return FNM_NOMATCH; + p += 2; +- c = *p++; + } + else if (c == L('[') && *p == L('.')) + { +@@ -962,10 +957,8 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used) + break; + } + p += 2; +- c = *p++; + } + } +- while (c != L(']')); + if (not) + return FNM_NOMATCH; + } +diff --git glibc-2.17-c758a686/posix/tst-fnmatch3.c glibc-2.17-c758a686/posix/tst-fnmatch3.c +new file mode 100644 +index 0000000..2a83c1b +--- /dev/null ++++ glibc-2.17-c758a686/posix/tst-fnmatch3.c +@@ -0,0 +1,30 @@ ++/* Test for fnmatch not reading past the end of the pattern. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int ++do_test (void) ++{ ++ const char *pattern = "[[:alpha:]'[:alpha:]\0]"; ++ ++ return fnmatch (pattern, "a", 0) != FNM_NOMATCH; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- glibc-2.17-c758a686/posix/Makefile 2015-05-15 16:00:01.000000000 -0400 ++++ glibc-2.17-c758a686/posix/Makefile 2015-05-29 18:34:07.507240952 -0400 +@@ -87,7 +87,7 @@ + tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \ + bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \ + bug-getopt5 tst-getopt_long1 bug-regex34 \ +- tst-pathconf ++ tst-pathconf tst-fnmatch3 + xtests := bug-ga2 + ifeq (yes,$(build-shared)) + test-srcs := globtest diff --git a/SOURCES/glibc-rh1197730-2.patch b/SOURCES/glibc-rh1197730-2.patch new file mode 100644 index 00000000..3923a247 --- /dev/null +++ b/SOURCES/glibc-rh1197730-2.patch @@ -0,0 +1,46 @@ +commit 4a28f4d55a6cc33474c0792fe93b5942d81bf185 +Author: Andreas Schwab +Date: Thu Feb 26 14:55:24 2015 +0100 + + Fix read past end of pattern in fnmatch (bug 18032) + +diff --git glibc-2.17-c758a686/posix/fnmatch_loop.c glibc-2.17-c758a686/posix/fnmatch_loop.c +index c0cb2fc..72c5d8f 100644 +--- glibc-2.17-c758a686/posix/fnmatch_loop.c ++++ glibc-2.17-c758a686/posix/fnmatch_loop.c +@@ -945,14 +945,13 @@ FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used) + } + else if (c == L('[') && *p == L('.')) + { +- ++p; + while (1) + { + c = *++p; +- if (c == '\0') ++ if (c == L('\0')) + return FNM_NOMATCH; + +- if (*p == L('.') && p[1] == L(']')) ++ if (c == L('.') && p[1] == L(']')) + break; + } + p += 2; +diff --git glibc-2.17-c758a686/posix/tst-fnmatch3.c glibc-2.17-c758a686/posix/tst-fnmatch3.c +index d27a557..75bc00a 100644 +--- glibc-2.17-c758a686/posix/tst-fnmatch3.c ++++ glibc-2.17-c758a686/posix/tst-fnmatch3.c +@@ -21,9 +21,11 @@ + int + do_test (void) + { +- const char *pattern = "[[:alpha:]'[:alpha:]\0]"; +- +- return fnmatch (pattern, "a", 0) != FNM_NOMATCH; ++ if (fnmatch ("[[:alpha:]'[:alpha:]\0]", "a", 0) != FNM_NOMATCH) ++ return 1; ++ if (fnmatch ("[a[.\0.]]", "a", 0) != FNM_NOMATCH) ++ return 1; ++ return 0; + } + + #define TEST_FUNCTION do_test () diff --git a/SOURCES/glibc-rh1197730-3.patch b/SOURCES/glibc-rh1197730-3.patch new file mode 100644 index 00000000..9da1dbeb --- /dev/null +++ b/SOURCES/glibc-rh1197730-3.patch @@ -0,0 +1,62 @@ +commit c2c6d39fab901c97c18fa3a3a3658d9dc3f7df61 +Author: Paul Pluzhnikov +Date: Mon Mar 2 13:34:22 2015 -0800 + + Fix BZ 18036 buffer overflow (read past end of buffer) in internal_fnmatch + +--- glibc-2.17-c758a686/posix/fnmatch_loop.c ++++ glibc-2.17-c758a686/posix/fnmatch_loop.c +@@ -1036,7 +1036,12 @@ END (const CHAR *pattern) + } + else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@') + || *p == L('!')) && p[1] == L('(')) +- p = END (p + 1); ++ { ++ p = END (p + 1); ++ if (*p == L('\0')) ++ /* This is an invalid pattern. */ ++ return pattern; ++ } + else if (*p == L(')')) + break; + +diff --git glibc-2.17-c758a686/posix/tst-fnmatch3.c glibc-2.17-c758a686/posix/tst-fnmatch3.c +index 75bc00a..fdf9934 100644 +--- glibc-2.17-c758a686/posix/tst-fnmatch3.c ++++ glibc-2.17-c758a686/posix/tst-fnmatch3.c +@@ -17,6 +17,26 @@ + . */ + + #include ++#include ++#include ++#include ++ ++int ++do_bz18036 (void) ++{ ++ const char p[] = "**(!()"; ++ const int pagesize = getpagesize (); ++ ++ char *pattern = mmap (0, 2 * pagesize, PROT_READ|PROT_WRITE, ++ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); ++ if (pattern == MAP_FAILED) return 1; ++ ++ mprotect (pattern + pagesize, pagesize, PROT_NONE); ++ memset (pattern, ' ', pagesize); ++ strcpy (pattern, p); ++ ++ return fnmatch (pattern, p, FNM_EXTMATCH); ++} + + int + do_test (void) +@@ -25,7 +45,7 @@ do_test (void) + return 1; + if (fnmatch ("[a[.\0.]]", "a", 0) != FNM_NOMATCH) + return 1; +- return 0; ++ return do_bz18036 (); + } + + #define TEST_FUNCTION do_test () diff --git a/SOURCES/glibc-rh1199525.patch b/SOURCES/glibc-rh1199525.patch new file mode 100644 index 00000000..8af91ca0 --- /dev/null +++ b/SOURCES/glibc-rh1199525.patch @@ -0,0 +1,20 @@ +commit 2959eda9272a033863c271aff62095abd01bd4e3 +Author: Arjun Shankar +Date: Tue Apr 21 14:06:31 2015 +0200 + + CVE-2015-1781: resolv/nss_dns/dns-host.c buffer overflow [BZ#18287] + +diff --git glibc-2.17-c758a686/resolv/nss_dns/dns-host.c glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +index b16b0dd..d8c5579 100644 +--- glibc-2.17-c758a686/resolv/nss_dns/dns-host.c ++++ glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +@@ -613,7 +613,8 @@ + int have_to_map = 0; + uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); + buffer += pad; +- if (__builtin_expect (buflen < sizeof (struct host_data) + pad, 0)) ++ buflen = buflen > pad ? buflen - pad : 0; ++ if (__builtin_expect (buflen < sizeof (struct host_data), 0)) + { + /* The buffer is too small. */ + too_small: diff --git a/SOURCES/glibc-rh1202952.patch b/SOURCES/glibc-rh1202952.patch new file mode 100644 index 00000000..2dc4c506 --- /dev/null +++ b/SOURCES/glibc-rh1202952.patch @@ -0,0 +1,636 @@ +# +# commit f8aeae347377f3dfa8cbadde057adf1827fb1d44 +# Author: Alexandre Oliva +# Date: Tue Mar 17 01:14:11 2015 -0300 +# +# Fix DTV race, assert, DTV_SURPLUS Static TLS limit, and nptl_db garbage +# +# for ChangeLog +# +# [BZ #17090] +# [BZ #17620] +# [BZ #17621] +# [BZ #17628] +# * NEWS: Update. +# * elf/dl-tls.c (_dl_update_slotinfo): Clean up outdated DTV +# entries with Static TLS too. Skip entries past the end of the +# allocated DTV, from Alan Modra. +# (tls_get_addr_tail): Update to glibc_likely/unlikely. Move +# Static TLS DTV entry set up from... +# (_dl_allocate_tls_init): ... here (fix modid assertion), ... +# * elf/dl-reloc.c (_dl_nothread_init_static_tls): ... here... +# * nptl/allocatestack.c (init_one_static_tls): ... and here... +# * elf/dlopen.c (dl_open_worker): Drop l_tls_modid upper bound +# for Static TLS. +# * elf/tlsdeschtab.h (map_generation): Return size_t. Check +# that the slot we find is associated with the given map before +# using its generation count. +# * nptl_db/db_info.c: Include ldsodefs.h. +# (rtld_global, dtv_slotinfo_list, dtv_slotinfo): New typedefs. +# * nptl_db/structs.def (DB_RTLD_VARIABLE): New macro. +# (DB_MAIN_VARIABLE, DB_RTLD_GLOBAL_FIELD): Likewise. +# (link_map::l_tls_offset): New struct field. +# (dtv_t::counter): Likewise. +# (rtld_global): New struct. +# (_rtld_global): New rtld variable. +# (dl_tls_dtv_slotinfo_list): New rtld global field. +# (dtv_slotinfo_list): New struct. +# (dtv_slotinfo): Likewise. +# * nptl_db/td_symbol_list.c: Drop gnu/lib-names.h include. +# (td_lookup): Rename to... +# (td_mod_lookup): ... this. Use new mod parameter instead of +# LIBPTHREAD_SO. +# * nptl_db/td_thr_tlsbase.c: Include link.h. +# (dtv_slotinfo_list, dtv_slotinfo): New functions. +# (td_thr_tlsbase): Check DTV generation. Compute Static TLS +# addresses even if the DTV is out of date or missing them. +# * nptl_db/fetch-value.c (_td_locate_field): Do not refuse to +# index zero-length arrays. +# * nptl_db/thread_dbP.h: Include gnu/lib-names.h. +# (td_lookup): Make it a macro implemented in terms of... +# (td_mod_lookup): ... this declaration. +# * nptl_db/db-symbols.awk (DB_RTLD_VARIABLE): Override. +# (DB_MAIN_VARIABLE): Likewise. +# +diff -urN glibc-2.17-c758a686/elf/dl-open.c glibc-2.17-c758a686/elf/dl-open.c +--- glibc-2.17-c758a686/elf/dl-open.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/elf/dl-open.c 2015-03-17 14:39:47.746505786 -0400 +@@ -535,17 +535,7 @@ + && imap->l_tls_blocksize > 0) + { + /* For static TLS we have to allocate the memory here and +- now. This includes allocating memory in the DTV. But we +- cannot change any DTV other than our own. So, if we +- cannot guarantee that there is room in the DTV we don't +- even try it and fail the load. +- +- XXX We could track the minimum DTV slots allocated in +- all threads. */ +- if (! RTLD_SINGLE_THREAD_P && imap->l_tls_modid > DTV_SURPLUS) +- _dl_signal_error (0, "dlopen", NULL, N_("\ +-cannot load any more object with static TLS")); +- ++ now, but we can delay updating the DTV. */ + imap->l_need_tls_init = 0; + #ifdef SHARED + /* Update the slot information data for at least the +diff -urN glibc-2.17-c758a686/elf/dl-reloc.c glibc-2.17-c758a686/elf/dl-reloc.c +--- glibc-2.17-c758a686/elf/dl-reloc.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/elf/dl-reloc.c 2015-03-17 14:39:47.747505754 -0400 +@@ -136,12 +136,6 @@ + # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" + #endif + +- /* Fill in the DTV slot so that a later LD/GD access will find it. */ +- dtv_t *dtv = THREAD_DTV (); +- assert (map->l_tls_modid <= dtv[-1].counter); +- dtv[map->l_tls_modid].pointer.val = dest; +- dtv[map->l_tls_modid].pointer.is_static = true; +- + /* Initialize the memory. */ + memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size), + '\0', map->l_tls_blocksize - map->l_tls_initimage_size); +diff -urN glibc-2.17-c758a686/elf/dl-tls.c glibc-2.17-c758a686/elf/dl-tls.c +--- glibc-2.17-c758a686/elf/dl-tls.c 2015-03-17 14:39:31.335019227 -0400 ++++ glibc-2.17-c758a686/elf/dl-tls.c 2015-03-17 14:42:48.443852579 -0400 +@@ -432,17 +432,14 @@ + assert (listp->slotinfo[cnt].gen <= GL(dl_tls_generation)); + maxgen = MAX (maxgen, listp->slotinfo[cnt].gen); + ++ dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED; ++ dtv[map->l_tls_modid].pointer.is_static = false; ++ + if (map->l_tls_offset == NO_TLS_OFFSET + || map->l_tls_offset == FORCED_DYNAMIC_TLS_OFFSET) +- { +- /* For dynamically loaded modules we simply store +- the value indicating deferred allocation. */ +- dtv[map->l_tls_modid].pointer.val = TLS_DTV_UNALLOCATED; +- dtv[map->l_tls_modid].pointer.is_static = false; +- continue; +- } ++ continue; + +- assert (map->l_tls_modid == cnt); ++ assert (map->l_tls_modid == total + cnt); + assert (map->l_tls_blocksize >= map->l_tls_initimage_size); + #if TLS_TCB_AT_TP + assert ((size_t) map->l_tls_offset >= map->l_tls_blocksize); +@@ -454,8 +451,6 @@ + #endif + + /* Copy the initialization image and clear the BSS part. */ +- dtv[map->l_tls_modid].pointer.val = dest; +- dtv[map->l_tls_modid].pointer.is_static = true; + memset (__mempcpy (dest, map->l_tls_initimage, + map->l_tls_initimage_size), '\0', + map->l_tls_blocksize - map->l_tls_initimage_size); +@@ -623,13 +618,16 @@ + struct link_map *map = listp->slotinfo[cnt].map; + if (map == NULL) + { +- /* If this modid was used at some point the memory +- might still be allocated. */ +- if (! dtv[total + cnt].pointer.is_static +- && dtv[total + cnt].pointer.val != TLS_DTV_UNALLOCATED) ++ if (dtv[-1].counter >= total + cnt) + { +- free (dtv[total + cnt].pointer.val); ++ /* If this modid was used at some point the memory ++ might still be allocated. */ ++ if (! dtv[total + cnt].pointer.is_static ++ && (dtv[total + cnt].pointer.val ++ != TLS_DTV_UNALLOCATED)) ++ free (dtv[total + cnt].pointer.val); + dtv[total + cnt].pointer.val = TLS_DTV_UNALLOCATED; ++ dtv[total + cnt].pointer.is_static = false; + } + + continue; +@@ -693,10 +691,8 @@ + memalign and not malloc. */ + free (dtv[modid].pointer.val); + +- /* This module is loaded dynamically- We defer memory +- allocation. */ +- dtv[modid].pointer.is_static = false; + dtv[modid].pointer.val = TLS_DTV_UNALLOCATED; ++ dtv[modid].pointer.is_static = false; + + if (modid == req_modid) + the_map = map; +@@ -734,13 +730,12 @@ + the_map = listp->slotinfo[idx].map; + } + +- again: + /* Make sure that, if a dlopen running in parallel forces the + variable into static storage, we'll wait until the address in the + static TLS block is set up, and use that. If we're undecided + yet, make sure we make the decision holding the lock as well. */ +- if (__builtin_expect (the_map->l_tls_offset +- != FORCED_DYNAMIC_TLS_OFFSET, 0)) ++ if (__glibc_unlikely (the_map->l_tls_offset ++ != FORCED_DYNAMIC_TLS_OFFSET)) + { + __rtld_lock_lock_recursive (GL(dl_load_lock)); + if (__builtin_expect (the_map->l_tls_offset == NO_TLS_OFFSET, 1)) +@@ -748,22 +743,28 @@ + the_map->l_tls_offset = FORCED_DYNAMIC_TLS_OFFSET; + __rtld_lock_unlock_recursive (GL(dl_load_lock)); + } +- else ++ else if (__glibc_likely (the_map->l_tls_offset ++ != FORCED_DYNAMIC_TLS_OFFSET)) + { ++#if TLS_TCB_AT_TP ++ void *p = (char *) THREAD_SELF - the_map->l_tls_offset; ++#elif TLS_DTV_AT_TP ++ void *p = (char *) THREAD_SELF + the_map->l_tls_offset + TLS_PRE_TCB_SIZE; ++#else ++# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" ++#endif + __rtld_lock_unlock_recursive (GL(dl_load_lock)); +- if (__builtin_expect (the_map->l_tls_offset +- != FORCED_DYNAMIC_TLS_OFFSET, 1)) +- { +- void *p = dtv[GET_ADDR_MODULE].pointer.val; +- if (__builtin_expect (p == TLS_DTV_UNALLOCATED, 0)) +- goto again; ++ dtv[GET_ADDR_MODULE].pointer.is_static = true; ++ dtv[GET_ADDR_MODULE].pointer.val = p; + +- return (char *) p + GET_ADDR_OFFSET; +- } ++ return (char *) p + GET_ADDR_OFFSET; + } ++ else ++ __rtld_lock_unlock_recursive (GL(dl_load_lock)); ++ + } + void *p = dtv[GET_ADDR_MODULE].pointer.val = allocate_and_init (the_map); +- dtv[GET_ADDR_MODULE].pointer.is_static = false; ++ assert (!dtv[GET_ADDR_MODULE].pointer.is_static); + + return (char *) p + GET_ADDR_OFFSET; + } +diff -urN glibc-2.17-c758a686/elf/tlsdeschtab.h glibc-2.17-c758a686/elf/tlsdeschtab.h +--- glibc-2.17-c758a686/elf/tlsdeschtab.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/elf/tlsdeschtab.h 2015-03-17 14:39:47.747505754 -0400 +@@ -42,7 +42,7 @@ + return tdp->tlsinfo.ti_offset == tdq->tlsinfo.ti_offset; + } + +-inline static int ++inline static size_t + map_generation (struct link_map *map) + { + size_t idx = map->l_tls_modid; +@@ -58,7 +58,7 @@ + we can assume that, if the generation count is zero, we + still haven't determined the generation count for this + module. */ +- if (listp->slotinfo[idx].gen) ++ if (listp->slotinfo[idx].map == map && listp->slotinfo[idx].gen) + return listp->slotinfo[idx].gen; + else + break; +diff -urN glibc-2.17-c758a686/nptl/allocatestack.c glibc-2.17-c758a686/nptl/allocatestack.c +--- glibc-2.17-c758a686/nptl/allocatestack.c 2015-03-17 14:39:31.342019008 -0400 ++++ glibc-2.17-c758a686/nptl/allocatestack.c 2015-03-17 14:39:47.747505754 -0400 +@@ -1157,7 +1157,6 @@ + static inline void __attribute__((always_inline)) + init_one_static_tls (struct pthread *curp, struct link_map *map) + { +- dtv_t *dtv = GET_DTV (TLS_TPADJ (curp)); + # if TLS_TCB_AT_TP + void *dest = (char *) curp - map->l_tls_offset; + # elif TLS_DTV_AT_TP +@@ -1166,11 +1165,9 @@ + # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" + # endif + +- /* Fill in the DTV slot so that a later LD/GD access will find it. */ +- dtv[map->l_tls_modid].pointer.val = dest; +- dtv[map->l_tls_modid].pointer.is_static = true; +- +- /* Initialize the memory. */ ++ /* We cannot delay the initialization of the Static TLS area, since ++ it can be accessed with LE or IE, but since the DTV is only used ++ by GD and LD, we can delay its update to avoid a race. */ + memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size), + '\0', map->l_tls_blocksize - map->l_tls_initimage_size); + } +diff -urN glibc-2.17-c758a686/nptl_db/db_info.c glibc-2.17-c758a686/nptl_db/db_info.c +--- glibc-2.17-c758a686/nptl_db/db_info.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/db_info.c 2015-03-17 14:39:47.747505754 -0400 +@@ -20,6 +20,7 @@ + + #include "thread_dbP.h" + #include ++#include + + typedef struct pthread pthread; + typedef struct pthread_key_struct pthread_key_struct; +@@ -36,6 +37,9 @@ + } dtv; + + typedef struct link_map link_map; ++typedef struct rtld_global rtld_global; ++typedef struct dtv_slotinfo_list dtv_slotinfo_list; ++typedef struct dtv_slotinfo dtv_slotinfo; + + /* Actually static in nptl/init.c, but we only need it for typeof. */ + extern bool __nptl_initial_report_events; +diff -urN glibc-2.17-c758a686/nptl_db/db-symbols.awk glibc-2.17-c758a686/nptl_db/db-symbols.awk +--- glibc-2.17-c758a686/nptl_db/db-symbols.awk 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/db-symbols.awk 2015-03-17 14:39:47.747505754 -0400 +@@ -2,6 +2,8 @@ + # we've just built. It checks for all the symbols used in td_symbol_list. + + BEGIN { ++%define DB_RTLD_VARIABLE(name) /* Nothing. */ ++%define DB_MAIN_VARIABLE(name) /* Nothing. */ + %define DB_LOOKUP_NAME(idx, name) required[STRINGIFY (name)] = 1; + %define DB_LOOKUP_NAME_TH_UNIQUE(idx, name) th_unique[STRINGIFY (name)] = 1; + %include "db-symbols.h" +diff -urN glibc-2.17-c758a686/nptl_db/fetch-value.c glibc-2.17-c758a686/nptl_db/fetch-value.c +--- glibc-2.17-c758a686/nptl_db/fetch-value.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/fetch-value.c 2015-03-17 14:39:47.747505754 -0400 +@@ -68,7 +68,8 @@ + } + } + +- if (idx != 0 && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc)) ++ if (idx != 0 && DB_DESC_NELEM (desc) != 0 ++ && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc)) + /* This is an internal indicator to callers with nonzero IDX + that the IDX value is too big. */ + return TD_NOAPLIC; +diff -urN glibc-2.17-c758a686/nptl_db/structs.def glibc-2.17-c758a686/nptl_db/structs.def +--- glibc-2.17-c758a686/nptl_db/structs.def 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/structs.def 2015-03-17 14:44:29.779682236 -0400 +@@ -22,6 +22,28 @@ + # define STRUCTS_DEF_DEFAULTS 1 + #endif + ++#ifndef DB_RTLD_VARIABLE ++# define DB_RTLD_VARIABLE(name) DB_VARIABLE (name) ++#endif ++ ++#ifndef DB_MAIN_VARIABLE ++# define DB_MAIN_VARIABLE(name) DB_VARIABLE (name) ++#endif ++ ++#ifndef DB_RTLD_GLOBAL_FIELD ++# if !defined IS_IN_libpthread ++# define DB_RTLD_GLOBAL_FIELD(field) \ ++ DB_STRUCT_FIELD (rtld_global, _##field) \ ++ DB_MAIN_VARIABLE (_##field) ++# elif defined SHARED ++# define DB_RTLD_GLOBAL_FIELD(field) \ ++ DB_STRUCT_FIELD (rtld_global, _##field) ++# else ++# define DB_RTLD_GLOBAL_FIELD(field) \ ++ DB_MAIN_VARIABLE (_##field) ++# endif ++#endif /* DB_RTLD_GLOBAL_FIELD */ ++ + DB_STRUCT (pthread) + DB_STRUCT_FIELD (pthread, list) + DB_STRUCT_FIELD (pthread, report_events) +@@ -70,14 +92,31 @@ + DB_STRUCT_ARRAY_FIELD (pthread_key_data_level2, data) + + DB_STRUCT_FIELD (link_map, l_tls_modid) ++DB_STRUCT_FIELD (link_map, l_tls_offset) + + DB_STRUCT_ARRAY_FIELD (dtv, dtv) + #define pointer_val pointer.val /* Field of anonymous struct in dtv_t. */ + DB_STRUCT_FIELD (dtv_t, pointer_val) ++DB_STRUCT_FIELD (dtv_t, counter) + #if !defined IS_IN_libpthread || TLS_TCB_AT_TP + DB_STRUCT_FIELD (pthread, dtvp) + #endif + ++#if !(defined IS_IN_libpthread && !defined SHARED) ++DB_STRUCT (rtld_global) ++DB_RTLD_VARIABLE (_rtld_global) ++#endif ++DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list) ++ ++DB_STRUCT (dtv_slotinfo_list) ++DB_STRUCT_FIELD (dtv_slotinfo_list, len) ++DB_STRUCT_FIELD (dtv_slotinfo_list, next) ++DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo) ++ ++DB_STRUCT (dtv_slotinfo) ++DB_STRUCT_FIELD (dtv_slotinfo, gen) ++DB_STRUCT_FIELD (dtv_slotinfo, map) ++ + #ifdef STRUCTS_DEF_DEFAULTS + # undef DB_STRUCT_ARRAY_FIELD + # undef DB_ARRAY_VARIABLE +diff -urN glibc-2.17-c758a686/nptl_db/td_symbol_list.c glibc-2.17-c758a686/nptl_db/td_symbol_list.c +--- glibc-2.17-c758a686/nptl_db/td_symbol_list.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/td_symbol_list.c 2015-03-17 14:39:47.747505754 -0400 +@@ -18,7 +18,6 @@ + . */ + + #include +-#include + #include "thread_dbP.h" + + static const char *symbol_list_arr[] = +@@ -41,12 +40,12 @@ + + + ps_err_e +-td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr) ++td_mod_lookup (struct ps_prochandle *ps, const char *mod, ++ int idx, psaddr_t *sym_addr) + { + ps_err_e result; + assert (idx >= 0 && idx < SYM_NUM_MESSAGES); +- result = ps_pglobal_lookup (ps, LIBPTHREAD_SO, symbol_list_arr[idx], +- sym_addr); ++ result = ps_pglobal_lookup (ps, mod, symbol_list_arr[idx], sym_addr); + + #ifdef HAVE_ASM_GLOBAL_DOT_NAME + /* For PowerPC, 64-bit uses dot symbols but 32-bit does not. +diff -urN glibc-2.17-c758a686/nptl_db/td_thr_tlsbase.c glibc-2.17-c758a686/nptl_db/td_thr_tlsbase.c +--- glibc-2.17-c758a686/nptl_db/td_thr_tlsbase.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/td_thr_tlsbase.c 2015-03-17 14:39:47.748505723 -0400 +@@ -17,14 +17,118 @@ + . */ + + #include "thread_dbP.h" ++#include + ++/* Get the DTV slotinfo list head entry from the dynamic loader state ++ into *LISTHEAD. */ ++static td_err_e ++dtv_slotinfo_list (td_thragent_t *ta, ++ psaddr_t *listhead) ++{ ++ td_err_e err; ++ psaddr_t head; ++ ++ if (ta->ta_addr__rtld_global == 0 ++ && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global, ++ &ta->ta_addr__rtld_global) != PS_OK) ++ ta->ta_addr__rtld_global = (void*)-1; ++ ++ if (ta->ta_addr__rtld_global != (void*)-1) ++ { ++ err = DB_GET_FIELD (head, ta, ta->ta_addr__rtld_global, ++ rtld_global, _dl_tls_dtv_slotinfo_list, 0); ++ if (err != TD_OK) ++ return err; ++ } ++ else ++ { ++ if (ta->ta_addr__dl_tls_dtv_slotinfo_list == 0 ++ && td_mod_lookup (ta->ph, NULL, SYM__dl_tls_dtv_slotinfo_list, ++ &ta->ta_addr__dl_tls_dtv_slotinfo_list) != PS_OK) ++ return TD_ERR; ++ ++ err = _td_fetch_value (ta, ta->ta_var__dl_tls_dtv_slotinfo_list, ++ SYM_DESC__dl_tls_dtv_slotinfo_list, ++ 0, ta->ta_addr__dl_tls_dtv_slotinfo_list, &head); ++ if (err != TD_OK) ++ return err; ++ } ++ ++ *listhead = head; ++ return TD_OK; ++} ++ ++/* Get the address of the DTV slotinfo entry for MODID into ++ *DTVSLOTINFO. */ ++static td_err_e ++dtv_slotinfo (td_thragent_t *ta, ++ unsigned long int modid, ++ psaddr_t *dtvslotinfo) ++{ ++ td_err_e err; ++ psaddr_t slot, temp; ++ size_t slbase = 0; ++ ++ err = dtv_slotinfo_list (ta, &slot); ++ if (err != TD_OK) ++ return err; ++ ++ while (slot) ++ { ++ /* Get the number of entries in this list entry's array. */ ++ err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list, len, 0); ++ if (err != TD_OK) ++ return err; ++ size_t len = (uintptr_t)temp; ++ ++ /* Did we find the list entry for modid? */ ++ if (modid < slbase + len) ++ break; ++ ++ /* We didn't, so get the next list entry. */ ++ slbase += len; ++ err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list, ++ next, 0); ++ if (err != TD_OK) ++ return err; ++ slot = temp; ++ } ++ ++ /* We reached the end of the list and found nothing. */ ++ if (!slot) ++ return TD_ERR; ++ ++ /* Take the slotinfo for modid from the list entry. */ ++ err = DB_GET_FIELD_ADDRESS (temp, ta, slot, dtv_slotinfo_list, ++ slotinfo, modid - slbase); ++ if (err != TD_OK) ++ return err; ++ slot = temp; ++ ++ *dtvslotinfo = slot; ++ return TD_OK; ++} ++ ++/* Return in *BASE the base address of the TLS block for MODID within ++ TH. ++ ++ It should return success and yield the correct pointer in any ++ circumstance where the TLS block for the module and thread ++ requested has already been initialized. ++ ++ It should fail with TD_TLSDEFER only when the thread could not ++ possibly have observed any values in that TLS block. That way, the ++ debugger can fall back to showing initial values from the PT_TLS ++ segment (and refusing attempts to mutate) for the TD_TLSDEFER case, ++ and never fail to make the values the program will actually see ++ available to the user of the debugger. */ + td_err_e + td_thr_tlsbase (const td_thrhandle_t *th, + unsigned long int modid, + psaddr_t *base) + { + td_err_e err; +- psaddr_t dtv, dtvslot, dtvptr; ++ psaddr_t dtv, dtvslot, dtvptr, temp; + + if (modid < 1) + return TD_NOTLS; +@@ -50,11 +154,75 @@ + return TD_TLSDEFER; + } + ++ err = dtv_slotinfo (th->th_ta_p, modid, &temp); ++ if (err != TD_OK) ++ return err; ++ ++ psaddr_t slot; ++ err = DB_GET_STRUCT (slot, th->th_ta_p, temp, dtv_slotinfo); ++ if (err != TD_OK) ++ return err; ++ ++ /* Take the link_map from the slotinfo. */ ++ psaddr_t map; ++ err = DB_GET_FIELD_LOCAL (map, th->th_ta_p, slot, dtv_slotinfo, map, 0); ++ if (err != TD_OK) ++ return err; ++ if (!map) ++ return TD_ERR; ++ ++ /* Ok, the modid is good, now find out what DTV generation it ++ requires. */ ++ err = DB_GET_FIELD_LOCAL (temp, th->th_ta_p, slot, dtv_slotinfo, gen, 0); ++ if (err != TD_OK) ++ return err; ++ size_t modgen = (uintptr_t)temp; ++ + /* Get the DTV pointer from the thread descriptor. */ + err = DB_GET_FIELD (dtv, th->th_ta_p, pd, pthread, dtvp, 0); + if (err != TD_OK) + return err; + ++ psaddr_t dtvgenloc; ++ /* Get the DTV generation count at dtv[0].counter. */ ++ err = DB_GET_FIELD_ADDRESS (dtvgenloc, th->th_ta_p, dtv, dtv, dtv, 0); ++ if (err != TD_OK) ++ return err; ++ err = DB_GET_FIELD (temp, th->th_ta_p, dtvgenloc, dtv_t, counter, 0); ++ if (err != TD_OK) ++ return err; ++ size_t dtvgen = (uintptr_t)temp; ++ ++ /* Is the DTV current enough? */ ++ if (dtvgen < modgen) ++ { ++ try_static_tls: ++ /* If the module uses Static TLS, we're still good. */ ++ err = DB_GET_FIELD (temp, th->th_ta_p, map, link_map, l_tls_offset, 0); ++ if (err != TD_OK) ++ return err; ++ ptrdiff_t tlsoff = (uintptr_t)temp; ++ ++ if (tlsoff != FORCED_DYNAMIC_TLS_OFFSET ++ && tlsoff != NO_TLS_OFFSET) ++ { ++ psaddr_t tp = pd; ++ ++#if TLS_TCB_AT_TP ++ dtvptr = tp - tlsoff; ++#elif TLS_DTV_AT_TP ++ dtvptr = tp + tlsoff + TLS_PRE_TCB_SIZE; ++#else ++# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" ++#endif ++ ++ *base = dtvptr; ++ return TD_OK; ++ } ++ ++ return TD_TLSDEFER; ++ } ++ + /* Find the corresponding entry in the DTV. */ + err = DB_GET_FIELD_ADDRESS (dtvslot, th->th_ta_p, dtv, dtv, dtv, modid); + if (err != TD_OK) +@@ -68,7 +236,7 @@ + /* It could be that the memory for this module is not allocated for + the given thread. */ + if ((uintptr_t) dtvptr & 1) +- return TD_TLSDEFER; ++ goto try_static_tls; + + *base = dtvptr; + return TD_OK; +diff -urN glibc-2.17-c758a686/nptl_db/thread_dbP.h glibc-2.17-c758a686/nptl_db/thread_dbP.h +--- glibc-2.17-c758a686/nptl_db/thread_dbP.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nptl_db/thread_dbP.h 2015-03-17 14:39:47.748505723 -0400 +@@ -29,6 +29,7 @@ + #include "thread_db.h" + #include "../nptl/pthreadP.h" /* This is for *_BITMASK only. */ + #include ++#include + + /* Indeces for the symbol names. */ + enum +@@ -139,11 +140,11 @@ + } + + +-/* Internal wrapper around ps_pglobal_lookup. */ +-extern ps_err_e td_lookup (struct ps_prochandle *ps, +- int idx, psaddr_t *sym_addr) attribute_hidden; +- +- ++/* Internal wrappers around ps_pglobal_lookup. */ ++extern ps_err_e td_mod_lookup (struct ps_prochandle *ps, const char *modname, ++ int idx, psaddr_t *sym_addr) attribute_hidden; ++#define td_lookup(ps, idx, sym_addr) \ ++ td_mod_lookup ((ps), LIBPTHREAD_SO, (idx), (sym_addr)) + + + /* Store in psaddr_t VAR the address of inferior's symbol NAME. */ diff --git a/SOURCES/glibc-rh1207032.patch b/SOURCES/glibc-rh1207032.patch new file mode 100644 index 00000000..765fa474 --- /dev/null +++ b/SOURCES/glibc-rh1207032.patch @@ -0,0 +1,649 @@ +commit fff94fa2245612191123a8015eac94eb04f001e2 +Author: Siddhesh Poyarekar +Date: Tue May 19 06:40:37 2015 +0530 + + Avoid deadlock in malloc on backtrace (BZ #16159) + + When the malloc subsystem detects some kind of memory corruption, + depending on the configuration it prints the error, a backtrace, a + memory map and then aborts the process. In this process, the + backtrace() call may result in a call to malloc, resulting in + various kinds of problematic behavior. + + In one case, the malloc it calls may detect a corruption and call + backtrace again, and a stack overflow may result due to the infinite + recursion. In another case, the malloc it calls may deadlock on an + arena lock with the malloc (or free, realloc, etc.) that detected the + corruption. In yet another case, if the program is linked with + pthreads, backtrace may do a pthread_once initialization, which + deadlocks on itself. + + In all these cases, the program exit is not as intended. This is + avoidable by marking the arena that malloc detected a corruption on, + as unusable. The following patch does that. Features of this patch + are as follows: + + - A flag is added to the mstate struct of the arena to indicate if the + arena is corrupt. + + - The flag is checked whenever malloc functions try to get a lock on + an arena. If the arena is unusable, a NULL is returned, causing the + malloc to use mmap or try the next arena. + + - malloc_printerr sets the corrupt flag on the arena when it detects a + corruption + + - free does not concern itself with the flag at all. It is not + important since the backtrace workflow does not need free. A free + in a parallel thread may cause another corruption, but that's not + new + + - The flag check and set are not atomic and may race. This is fine + since we don't care about contention during the flag check. We want + to make sure that the malloc call in the backtrace does not trip on + itself and all that action happens in the same thread and not across + threads. + + I verified that the test case does not show any regressions due to + this patch. I also ran the malloc benchmarks and found an + insignificant difference in timings (< 2%). + + +The follow-on test-suite fix has been folded into the patch below, but +to keep it minimal, ignore_stderr is put directly into +tst-malloc-backtrace.c. + +commit 02242448bf431a69fd0b8c929ca4408a05479baa +Author: Tulio Magno Quites Machado Filho +Date: Tue Jun 2 10:32:25 2015 -0300 + + Avoid outputting to TTY after an expected memory corruption in testcase + + Protect TTY against an expected memory corruption from testcase + tst-malloc-backtrace, which is expected to SIGABRT after a forced memory + corruption. + + +Index: b/malloc/arena.c +=================================================================== +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -119,7 +119,7 @@ int __malloc_initialized = -1; + + #ifdef PER_THREAD + # define arena_lock(ptr, size) do { \ +- if(ptr) \ ++ if(ptr && !arena_is_corrupt (ptr)) \ + (void)mutex_lock(&ptr->mutex); \ + else \ + ptr = arena_get2(ptr, (size), NULL); \ +@@ -808,7 +808,7 @@ reused_arena (mstate avoid_arena) + result = next_to_use; + do + { +- if (!mutex_trylock(&result->mutex)) ++ if (!arena_is_corrupt (result) && !mutex_trylock(&result->mutex)) + goto out; + + result = result->next; +@@ -820,7 +820,21 @@ reused_arena (mstate avoid_arena) + if (result == avoid_arena) + result = result->next; + +- /* No arena available. Wait for the next in line. */ ++ /* Make sure that the arena we get is not corrupted. */ ++ mstate begin = result; ++ while (arena_is_corrupt (result) || result == avoid_arena) ++ { ++ result = result->next; ++ if (result == begin) ++ break; ++ } ++ ++ /* We could not find any arena that was either not corrupted or not the one ++ we wanted to avoid. */ ++ if (result == begin || result == avoid_arena) ++ return NULL; ++ ++ /* No arena available without contention. Wait for the next in line. */ + LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena); + (void)mutex_lock(&result->mutex); + +Index: b/malloc/hooks.c +=================================================================== +--- a/malloc/hooks.c ++++ b/malloc/hooks.c +@@ -109,7 +109,8 @@ malloc_check_get_size(mchunkptr p) + size -= c) { + if(c<=0 || size<(c+2*SIZE_SZ)) { + malloc_printerr(check_action, "malloc_check_get_size: memory corruption", +- chunk2mem(p)); ++ chunk2mem(p), ++ chunk_is_mmapped (p) ? NULL : arena_for_chunk (p)); + return 0; + } + } +@@ -221,7 +222,8 @@ top_check(void) + return 0; + + mutex_unlock(&main_arena); +- malloc_printerr (check_action, "malloc: top chunk is corrupt", t); ++ malloc_printerr (check_action, "malloc: top chunk is corrupt", t, ++ &main_arena); + mutex_lock(&main_arena); + + /* Try to set up a new top chunk. */ +@@ -276,7 +278,8 @@ free_check(void* mem, const void *caller + if(!p) { + (void)mutex_unlock(&main_arena.mutex); + +- malloc_printerr(check_action, "free(): invalid pointer", mem); ++ malloc_printerr(check_action, "free(): invalid pointer", mem, ++ &main_arena); + return; + } + if (chunk_is_mmapped(p)) { +@@ -308,7 +311,8 @@ realloc_check(void* oldmem, size_t bytes + const mchunkptr oldp = mem2chunk_check(oldmem, &magic_p); + (void)mutex_unlock(&main_arena.mutex); + if(!oldp) { +- malloc_printerr(check_action, "realloc(): invalid pointer", oldmem); ++ malloc_printerr(check_action, "realloc(): invalid pointer", oldmem, ++ &main_arena); + return malloc_check(bytes, NULL); + } + const INTERNAL_SIZE_T oldsize = chunksize(oldp); +Index: b/malloc/Makefile +=================================================================== +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -25,7 +25,8 @@ all: + dist-headers := malloc.h + headers := $(dist-headers) obstack.h mcheck.h + tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ +- tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 tst-malloc-usable ++ tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \ ++ tst-malloc-usable tst-malloc-backtrace + test-srcs = tst-mtrace + + routines = malloc morecore mcheck mtrace obstack +@@ -40,6 +41,9 @@ extra-libs-others = $(extra-libs) + libmemusage-routines = memusage + libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) + ++$(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \ ++ $(common-objpfx)nptl/libpthread_nonshared.a ++ + # These should be removed by `make clean'. + extra-objs = mcheck-init.o libmcheck.a + +Index: b/malloc/malloc.c +=================================================================== +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1060,7 +1060,7 @@ static void* _int_realloc(mstate, mchun + static void* _int_memalign(mstate, size_t, size_t); + static void* _int_valloc(mstate, size_t); + static void* _int_pvalloc(mstate, size_t); +-static void malloc_printerr(int action, const char *str, void *ptr); ++static void malloc_printerr(int action, const char *str, void *ptr, mstate av); + + static void* internal_function mem2mem_check(void *p, size_t sz); + static int internal_function top_check(void); +@@ -1430,7 +1430,8 @@ typedef struct malloc_chunk* mbinptr; + BK = P->bk; \ + if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) { \ + mutex_unlock(&(AV)->mutex); \ +- malloc_printerr (check_action, "corrupted double-linked list", P); \ ++ malloc_printerr (check_action, "corrupted double-linked list", P, \ ++ AV); \ + mutex_lock(&(AV)->mutex); \ + } else { \ + FD->bk = BK; \ +@@ -1670,6 +1671,15 @@ typedef struct malloc_chunk* mfastbinptr + #define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT) + #define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT) + ++/* ARENA_CORRUPTION_BIT is set if a memory corruption was detected on the ++ arena. Such an arena is no longer used to allocate chunks. Chunks ++ allocated in that arena before detecting corruption are not freed. */ ++ ++#define ARENA_CORRUPTION_BIT (4U) ++ ++#define arena_is_corrupt(A) (((A)->flags & ARENA_CORRUPTION_BIT)) ++#define set_arena_corrupt(A) ((A)->flags |= ARENA_CORRUPTION_BIT) ++ + /* + Set value of max_fast. + Use impossibly small value if 0. +@@ -2281,8 +2291,9 @@ static void* sysmalloc(INTERNAL_SIZE_T n + rather than expanding top. + */ + +- if ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) && +- (mp_.n_mmaps < mp_.n_mmaps_max)) { ++ if (av == NULL ++ || ((unsigned long) (nb) >= (unsigned long) (mp_.mmap_threshold) ++ && (mp_.n_mmaps < mp_.n_mmaps_max))) { + + char* mm; /* return value from mmap call*/ + +@@ -2354,6 +2365,10 @@ static void* sysmalloc(INTERNAL_SIZE_T n + } + } + ++ /* There are no usable arenas and mmap also failed. */ ++ if (av == NULL) ++ return 0; ++ + /* Record incoming configuration of top */ + + old_top = av->top; +@@ -2519,7 +2534,7 @@ static void* sysmalloc(INTERNAL_SIZE_T n + else if (contiguous(av) && old_size && brk < old_end) { + /* Oops! Someone else killed our space.. Can't touch anything. */ + mutex_unlock(&av->mutex); +- malloc_printerr (3, "break adjusted to free malloc space", brk); ++ malloc_printerr (3, "break adjusted to free malloc space", brk, av); + mutex_lock(&av->mutex); + } + +@@ -2793,7 +2808,7 @@ munmap_chunk(mchunkptr p) + if (__builtin_expect (((block | total_size) & (GLRO(dl_pagesize) - 1)) != 0, 0)) + { + malloc_printerr (check_action, "munmap_chunk(): invalid pointer", +- chunk2mem (p)); ++ chunk2mem (p), NULL); + return; + } + +@@ -2861,21 +2876,20 @@ __libc_malloc(size_t bytes) + if (__builtin_expect (hook != NULL, 0)) + return (*hook)(bytes, RETURN_ADDRESS (0)); + +- arena_lookup(ar_ptr); ++ arena_get(ar_ptr, bytes); + +- arena_lock(ar_ptr, bytes); +- if(!ar_ptr) +- return 0; + victim = _int_malloc(ar_ptr, bytes); +- if(!victim) { ++ /* Retry with another arena only if we were able to find a usable arena ++ before. */ ++ if (!victim && ar_ptr != NULL) { + LIBC_PROBE (memory_malloc_retry, 1, bytes); + ar_ptr = arena_get_retry(ar_ptr, bytes); +- if (__builtin_expect(ar_ptr != NULL, 1)) { +- victim = _int_malloc(ar_ptr, bytes); +- (void)mutex_unlock(&ar_ptr->mutex); +- } +- } else ++ victim = _int_malloc (ar_ptr, bytes); ++ } ++ ++ if (ar_ptr != NULL) + (void)mutex_unlock(&ar_ptr->mutex); ++ + assert(!victim || chunk_is_mmapped(mem2chunk(victim)) || + ar_ptr == arena_for_chunk(mem2chunk(victim))); + return victim; +@@ -2946,6 +2960,11 @@ __libc_realloc(void* oldmem, size_t byte + /* its size */ + const INTERNAL_SIZE_T oldsize = chunksize(oldp); + ++ if (chunk_is_mmapped (oldp)) ++ ar_ptr = NULL; ++ else ++ ar_ptr = arena_for_chunk (oldp); ++ + /* Little security check which won't hurt performance: the + allocator never wrapps around at the end of the address space. + Therefore we can exclude some size values which might appear +@@ -2953,7 +2972,8 @@ __libc_realloc(void* oldmem, size_t byte + if (__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0) + || __builtin_expect (misaligned_chunk (oldp), 0)) + { +- malloc_printerr (check_action, "realloc(): invalid pointer", oldmem); ++ malloc_printerr (check_action, "realloc(): invalid pointer", oldmem, ++ ar_ptr); + return NULL; + } + +@@ -2977,7 +2997,6 @@ __libc_realloc(void* oldmem, size_t byte + return newmem; + } + +- ar_ptr = arena_for_chunk(oldp); + #if THREAD_STATS + if(!mutex_trylock(&ar_ptr->mutex)) + ++(ar_ptr->stat_lock_direct); +@@ -3043,18 +3062,17 @@ __libc_memalign(size_t alignment, size_t + } + + arena_get(ar_ptr, bytes + alignment + MINSIZE); +- if(!ar_ptr) +- return 0; ++ + p = _int_memalign(ar_ptr, alignment, bytes); +- if(!p) { ++ if(!p && ar_ptr != NULL) { + LIBC_PROBE (memory_memalign_retry, 2, bytes, alignment); + ar_ptr = arena_get_retry (ar_ptr, bytes); +- if (__builtin_expect(ar_ptr != NULL, 1)) { +- p = _int_memalign(ar_ptr, alignment, bytes); +- (void)mutex_unlock(&ar_ptr->mutex); +- } +- } else ++ p = _int_memalign (ar_ptr, alignment, bytes); ++ } ++ ++ if (ar_ptr != NULL) + (void)mutex_unlock(&ar_ptr->mutex); ++ + assert(!p || chunk_is_mmapped(mem2chunk(p)) || + ar_ptr == arena_for_chunk(mem2chunk(p))); + return p; +@@ -3088,18 +3106,16 @@ __libc_valloc(size_t bytes) + return (*hook)(pagesz, bytes, RETURN_ADDRESS (0)); + + arena_get(ar_ptr, bytes + pagesz + MINSIZE); +- if(!ar_ptr) +- return 0; + p = _int_valloc(ar_ptr, bytes); +- if(!p) { ++ if(!p && ar_ptr != NULL) { + LIBC_PROBE (memory_valloc_retry, 1, bytes); + ar_ptr = arena_get_retry (ar_ptr, bytes); +- if (__builtin_expect(ar_ptr != NULL, 1)) { +- p = _int_memalign(ar_ptr, pagesz, bytes); +- (void)mutex_unlock(&ar_ptr->mutex); +- } +- } else ++ p = _int_memalign(ar_ptr, pagesz, bytes); ++ } ++ ++ if (ar_ptr != NULL) + (void)mutex_unlock (&ar_ptr->mutex); ++ + assert(!p || chunk_is_mmapped(mem2chunk(p)) || + ar_ptr == arena_for_chunk(mem2chunk(p))); + +@@ -3134,15 +3150,15 @@ __libc_pvalloc(size_t bytes) + + arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE); + p = _int_pvalloc(ar_ptr, bytes); +- if(!p) { ++ if(!p && ar_ptr != NULL) { + LIBC_PROBE (memory_pvalloc_retry, 1, bytes); + ar_ptr = arena_get_retry (ar_ptr, bytes + 2*pagesz + MINSIZE); +- if (__builtin_expect(ar_ptr != NULL, 1)) { +- p = _int_memalign(ar_ptr, pagesz, rounded_bytes); +- (void)mutex_unlock(&ar_ptr->mutex); +- } +- } else ++ p = _int_memalign(ar_ptr, pagesz, rounded_bytes); ++ } ++ ++ if (ar_ptr != NULL) + (void)mutex_unlock(&ar_ptr->mutex); ++ + assert(!p || chunk_is_mmapped(mem2chunk(p)) || + ar_ptr == arena_for_chunk(mem2chunk(p))); + +@@ -3184,43 +3200,54 @@ __libc_calloc(size_t n, size_t elem_size + sz = bytes; + + arena_get(av, sz); +- if(!av) +- return 0; ++ if(av) ++ { + +- /* Check if we hand out the top chunk, in which case there may be no +- need to clear. */ ++ /* Check if we hand out the top chunk, in which case there may be no ++ need to clear. */ + #if MORECORE_CLEARS +- oldtop = top(av); +- oldtopsize = chunksize(top(av)); +-#if MORECORE_CLEARS < 2 +- /* Only newly allocated memory is guaranteed to be cleared. */ +- if (av == &main_arena && +- oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop) +- oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop); ++ oldtop = top(av); ++ oldtopsize = chunksize(top(av)); ++# if MORECORE_CLEARS < 2 ++ /* Only newly allocated memory is guaranteed to be cleared. */ ++ if (av == &main_arena && ++ oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop) ++ oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop); ++# endif ++ if (av != &main_arena) ++ { ++ heap_info *heap = heap_for_ptr (oldtop); ++ if (oldtopsize < ((char *) heap + heap->mprotect_size - ++ (char *) oldtop)) ++ oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop; ++ } + #endif +- if (av != &main_arena) +- { +- heap_info *heap = heap_for_ptr (oldtop); +- if (oldtopsize < (char *) heap + heap->mprotect_size - (char *) oldtop) +- oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop; + } +-#endif ++ else ++ { ++ /* No usable arenas. */ ++ oldtop = 0; ++ oldtopsize = 0; ++ } + mem = _int_malloc(av, sz); + + + assert(!mem || chunk_is_mmapped(mem2chunk(mem)) || + av == arena_for_chunk(mem2chunk(mem))); + +- if (mem == 0) { ++ if (mem == 0 && av != NULL) { + LIBC_PROBE (memory_calloc_retry, 1, sz); + av = arena_get_retry (av, sz); +- if (__builtin_expect(av != NULL, 1)) { +- mem = _int_malloc(av, sz); +- (void)mutex_unlock(&av->mutex); +- } +- if (mem == 0) return 0; +- } else ++ mem = _int_malloc(av, sz); ++ } ++ ++ if (av != NULL) + (void)mutex_unlock(&av->mutex); ++ ++ /* Allocation failed even after a retry. */ ++ if (mem == 0) ++ return 0; ++ + p = mem2chunk(mem); + + /* Two optional cases in which clearing not necessary */ +@@ -3310,6 +3337,16 @@ _int_malloc(mstate av, size_t bytes) + + checked_request2size(bytes, nb); + ++ /* There are no usable arenas. Fall back to sysmalloc to get a chunk from ++ mmap. */ ++ if (__glibc_unlikely (av == NULL)) ++ { ++ void *p = sysmalloc (nb, av); ++ if (p != NULL) ++ alloc_perturb (p, bytes); ++ return p; ++ } ++ + /* + If the size qualifies as a fastbin, first check corresponding bin. + This code is safe to execute even if av is not yet initialized, so we +@@ -3334,7 +3371,7 @@ _int_malloc(mstate av, size_t bytes) + errstr = "malloc(): memory corruption (fast)"; + errout: + mutex_unlock(&av->mutex); +- malloc_printerr (check_action, errstr, chunk2mem (victim)); ++ malloc_printerr (check_action, errstr, chunk2mem (victim), av); + mutex_lock(&av->mutex); + return NULL; + } +@@ -3421,9 +3458,9 @@ _int_malloc(mstate av, size_t bytes) + if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0) + || __builtin_expect (victim->size > av->system_mem, 0)) + { +- void *p = chunk2mem(victim); + mutex_unlock(&av->mutex); +- malloc_printerr (check_action, "malloc(): memory corruption", p); ++ malloc_printerr (check_action, "malloc(): memory corruption", ++ chunk2mem (victim), av); + mutex_lock(&av->mutex); + } + size = chunksize(victim); +@@ -3801,7 +3838,7 @@ _int_free(mstate av, mchunkptr p, int ha + errout: + if (have_lock || locked) + (void)mutex_unlock(&av->mutex); +- malloc_printerr (check_action, errstr, chunk2mem(p)); ++ malloc_printerr (check_action, errstr, chunk2mem(p), av); + if (have_lock) + mutex_lock(&av->mutex); + return; +@@ -4196,7 +4233,7 @@ _int_realloc(mstate av, mchunkptr oldp, + errstr = "realloc(): invalid old size"; + errout: + mutex_unlock(&av->mutex); +- malloc_printerr (check_action, errstr, chunk2mem(oldp)); ++ malloc_printerr (check_action, errstr, chunk2mem(oldp), av); + mutex_lock(&av->mutex); + return NULL; + } +@@ -4436,7 +4473,7 @@ static void* + _int_valloc(mstate av, size_t bytes) + { + /* Ensure initialization/consolidation */ +- if (have_fastchunks(av)) malloc_consolidate(av); ++ if (av && have_fastchunks(av)) malloc_consolidate(av); + return _int_memalign(av, GLRO(dl_pagesize), bytes); + } + +@@ -4451,7 +4488,7 @@ _int_pvalloc(mstate av, size_t bytes) + size_t pagesz; + + /* Ensure initialization/consolidation */ +- if (have_fastchunks(av)) malloc_consolidate(av); ++ if (av && have_fastchunks(av)) malloc_consolidate(av); + pagesz = GLRO(dl_pagesize); + return _int_memalign(av, pagesz, (bytes + pagesz - 1) & ~(pagesz - 1)); + } +@@ -4463,6 +4500,10 @@ _int_pvalloc(mstate av, size_t bytes) + + static int mtrim(mstate av, size_t pad) + { ++ /* Don't touch corrupt arenas. */ ++ if (arena_is_corrupt (av)) ++ return 0; ++ + /* Ensure initialization/consolidation */ + malloc_consolidate (av); + +@@ -4956,8 +4997,14 @@ libc_hidden_def (__libc_mallopt) + extern char **__libc_argv attribute_hidden; + + static void +-malloc_printerr(int action, const char *str, void *ptr) ++malloc_printerr(int action, const char *str, void *ptr, mstate ar_ptr) + { ++ /* Avoid using this arena in future. We do not attempt to synchronize this ++ with anything else because we minimally want to ensure that __libc_message ++ gets its resources safely without stumbling on the current corruption. */ ++ if (ar_ptr) ++ set_arena_corrupt (ar_ptr); ++ + if ((action & 5) == 5) + __libc_message (action & 2, "%s\n", str); + else if (action & 1) +Index: b/malloc/tst-malloc-backtrace.c +=================================================================== +--- /dev/null ++++ b/malloc/tst-malloc-backtrace.c +@@ -0,0 +1,71 @@ ++/* Verify that backtrace does not deadlock on itself on memory corruption. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include ++#include ++#include ++#include ++ ++#define SIZE 4096 ++ ++/* Avoid all the buffer overflow messages on stderr. */ ++static void ++ignore_stderr (void) ++{ ++ int fd = open (_PATH_DEVNULL, O_WRONLY); ++ if (fd == -1) ++ close (STDERR_FILENO); ++ else ++ { ++ dup2 (fd, STDERR_FILENO); ++ close (fd); ++ } ++ setenv ("LIBC_FATAL_STDERR_", "1", 1); ++} ++ ++/* Wrap free with a function to prevent gcc from optimizing it out. */ ++static void ++__attribute__((noinline)) ++call_free (void *ptr) ++{ ++ free (ptr); ++ *(size_t *)(ptr - sizeof (size_t)) = 1; ++} ++ ++int ++do_test (void) ++{ ++ void *ptr1 = malloc (SIZE); ++ void *ptr2 = malloc (SIZE); ++ ++ /* Avoid unwanted output to TTY after an expected memory corruption. */ ++ ignore_stderr (); ++ ++ call_free ((void *) ptr1); ++ ptr1 = malloc (SIZE); ++ ++ /* Not reached. The return statement is to put ptr2 into use so that gcc ++ doesn't optimize out that malloc call. */ ++ return (ptr1 == ptr2); ++} ++ ++#define TEST_FUNCTION do_test () ++#define EXPECTED_SIGNAL SIGABRT ++ ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh1211100.patch b/SOURCES/glibc-rh1211100.patch new file mode 100644 index 00000000..70154cc5 --- /dev/null +++ b/SOURCES/glibc-rh1211100.patch @@ -0,0 +1,522 @@ +commit a1b85ae88b1a664e93ca0182c82f7763dd5a1754 +Author: Florian Weimer +Date: Mon Nov 9 16:52:31 2015 +0100 + + ld.so: Add original DSO name if overridden by audit module [BZ #18251] + +Index: b/elf/Makefile +=================================================================== +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -119,7 +119,8 @@ $(inst_auditdir)/sotruss-lib.so: $(objpf + endif + + tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \ +- tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 ++ tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 \ ++ tst-audit11 tst-audit12 + tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \ + tst-leaks1-static tst-array1-static tst-array5-static \ + tst-ptrguard1-static +@@ -216,7 +217,9 @@ modules-names = testobj1 testobj2 testob + tst-initorder2a tst-initorder2b tst-initorder2c \ + tst-initorder2d \ + tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \ +- tst-array5dep ++ tst-array5dep \ ++ tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \ ++ tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12 + ifeq (yesyes,$(have-fpie)$(build-shared)) + modules-names += tst-piemod1 + tests += tst-pie1 +@@ -1210,3 +1213,15 @@ $(objpfx)tst-unused-dep.out: $(objpfx)te + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $< > $@ + cmp $@ /dev/null > /dev/null ++ ++$(objpfx)tst-audit11.out: $(objpfx)tst-auditmod11.so $(objpfx)tst-audit11mod1.so ++$(objpfx)tst-audit11: $(libdl) ++tst-audit11-ENV = LD_AUDIT=$(objpfx)tst-auditmod11.so ++$(objpfx)tst-audit11mod1.so: $(objpfx)tst-audit11mod2.so ++LDFLAGS-tst-audit11mod2.so = -Wl,--version-script=tst-audit11mod2.map,-soname,tst-audit11mod2.so ++ ++$(objpfx)tst-audit12.out: $(objpfx)tst-auditmod12.so $(objpfx)tst-audit12mod1.so $(objpfx)tst-audit12mod3.so ++$(objpfx)tst-audit12: $(libdl) ++tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so ++$(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so ++LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map +Index: b/elf/dl-load.c +=================================================================== +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -909,9 +909,10 @@ lose (int code, int fd, const char *name + static + #endif + struct link_map * +-_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, +- char *realname, struct link_map *loader, int l_type, +- int mode, void **stack_endp, Lmid_t nsid) ++_dl_map_object_from_fd (const char *name, const char *origname, int fd, ++ struct filebuf *fbp, char *realname, ++ struct link_map *loader, int l_type, int mode, ++ void **stack_endp, Lmid_t nsid) + { + struct link_map *l = NULL; + const ElfW(Ehdr) *header; +@@ -1582,6 +1583,17 @@ cannot enable executable stack as shared + l->l_dev = st.st_dev; + l->l_ino = st.st_ino; + ++#ifdef SHARED ++ /* When auditing is used the recorded names might not include the ++ name by which the DSO is actually known. Add that as well. */ ++ if (__glibc_unlikely (origname != NULL)) ++ add_name_to_object (l, origname); ++#else ++ /* Audit modules only exist when linking is dynamic so ORIGNAME ++ cannot be non-NULL. */ ++ assert (origname == NULL); ++#endif ++ + /* When we profile the SONAME might be needed for something else but + loading. Add it right away. */ + if (__builtin_expect (GLRO(dl_profile) != NULL, 0) +@@ -2081,6 +2093,7 @@ _dl_map_object (struct link_map *loader, + int type, int trace_mode, int mode, Lmid_t nsid) + { + int fd; ++ const char *origname = NULL; + char *realname; + char *name_copy; + struct link_map *l; +@@ -2144,6 +2157,7 @@ _dl_map_object (struct link_map *loader, + { + if (afct->objsearch != NULL) + { ++ const char *before = name; + name = afct->objsearch (name, &loader->l_audit[cnt].cookie, + LA_SER_ORIG); + if (name == NULL) +@@ -2152,6 +2166,15 @@ _dl_map_object (struct link_map *loader, + fd = -1; + goto no_file; + } ++ if (before != name && strcmp (before, name) != 0) ++ { ++ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) ++ _dl_debug_printf ("audit changed filename %s -> %s\n", ++ before, name); ++ ++ if (origname == NULL) ++ origname = before; ++ } + } + + afct = afct->next; +@@ -2371,8 +2394,8 @@ _dl_map_object (struct link_map *loader, + } + + void *stack_end = __libc_stack_end; +- return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode, +- &stack_end, nsid); ++ return _dl_map_object_from_fd (name, origname, fd, &fb, realname, loader, ++ type, mode, &stack_end, nsid); + } + + +Index: b/elf/tst-audit11.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit11.c +@@ -0,0 +1,36 @@ ++/* Test version symbol binding can find a DSO replaced by la_objsearch. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++do_test (void) ++{ ++ puts ("Start"); ++ if (dlopen ("$ORIGIN/tst-audit11mod1.so", RTLD_LAZY) == NULL) ++ { ++ printf ("module not loaded: %s\n", dlerror ()); ++ return 1; ++ } ++ puts ("OK"); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: b/elf/tst-audit11mod1.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit11mod1.c +@@ -0,0 +1,24 @@ ++/* DSO directly opened by tst-audit11. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++extern int f2 (void); ++int ++f1 (void) ++{ ++ return f2 (); ++} +Index: b/elf/tst-audit11mod2.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit11mod2.c +@@ -0,0 +1,23 @@ ++/* DSO indirectly opened by tst-audit11, with symbol versioning. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++f2 (void) ++{ ++ return 42; ++} +Index: b/elf/tst-audit11mod2.map +=================================================================== +--- /dev/null ++++ b/elf/tst-audit11mod2.map +@@ -0,0 +1,22 @@ ++/* Symbol versioning for the DSO indirectly opened by tst-audit11. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++V1 { ++ global: f2; ++ local: *; ++}; +Index: b/elf/tst-audit12.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit12.c +@@ -0,0 +1,49 @@ ++/* Test that symbol is bound to a DSO replaced by la_objsearch. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++do_test (void) ++{ ++ puts ("Start"); ++ void *h = dlopen ("$ORIGIN/tst-audit12mod1.so", RTLD_LAZY); ++ if (h == NULL) ++ { ++ printf ("module not loaded: %s\n", dlerror ()); ++ return 1; ++ } ++ int (*fp) (void) = (int (*) (void)) dlsym (h, "f1"); ++ if (fp == NULL) ++ { ++ printf ("function f1 not found: %s\n", dlerror ()); ++ return 1; ++ } ++ int res = fp (); ++ if (res != 43) ++ { ++ puts ("incorrect function f2 called"); ++ return 1; ++ } ++ printf ("%d is OK\n", res); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: b/elf/tst-audit12mod1.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit12mod1.c +@@ -0,0 +1,24 @@ ++/* DSO directly opened by tst-audit12. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++extern int f2 (void); ++int ++f1 (void) ++{ ++ return f2 (); ++} +Index: b/elf/tst-audit12mod2.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit12mod2.c +@@ -0,0 +1,23 @@ ++/* Replaced DSO referenced by tst-audit12mod1.so, for tst-audit12. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++f2 (void) ++{ ++ return 42; ++} +Index: b/elf/tst-audit12mod2.map +=================================================================== +--- /dev/null ++++ b/elf/tst-audit12mod2.map +@@ -0,0 +1,22 @@ ++/* Symbol versioning for tst-audit12mod2.so used by tst-audit12. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++V1 { ++ global: f2; ++ local: *; ++}; +Index: b/elf/tst-audit12mod3.c +=================================================================== +--- /dev/null ++++ b/elf/tst-audit12mod3.c +@@ -0,0 +1,23 @@ ++/* Replacement DSO loaded by the audit module, for tst-audit12. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++int ++f2 (void) ++{ ++ return 43; ++} +Index: b/elf/tst-auditmod11.c +=================================================================== +--- /dev/null ++++ b/elf/tst-auditmod11.c +@@ -0,0 +1,39 @@ ++/* Audit module for tst-audit11. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return version; ++} ++ ++char * ++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) ++{ ++ if (strcmp (name, "tst-audit11mod2.so") == 0) ++ { ++ return (char *) "$ORIGIN/tst-audit11mod2.so"; ++ } ++ return (char *) name; ++} +Index: b/elf/tst-auditmod12.c +=================================================================== +--- /dev/null ++++ b/elf/tst-auditmod12.c +@@ -0,0 +1,43 @@ ++/* Audit module for tst-audit12. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int ++la_version (unsigned int version) ++{ ++ return version; ++} ++ ++char * ++la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag) ++{ ++ const char target[] = "tst-audit12mod2.so"; ++ ++ size_t namelen = strlen (name); ++ if (namelen >= sizeof (target) - 1 ++ && strcmp (name + namelen - (sizeof (target) - 1), target) == 0) ++ { ++ return (char *) "$ORIGIN/tst-audit12mod3.so"; ++ } ++ return (char *) name; ++} +Index: b/sysdeps/mach/hurd/dl-sysdep.c +=================================================================== +--- a/sysdeps/mach/hurd/dl-sysdep.c ++++ b/sysdeps/mach/hurd/dl-sysdep.c +@@ -187,7 +187,7 @@ unfmh(); /* XXX */ + assert_perror (err); + + lastslash = strrchr (p, '/'); +- l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p, ++ l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p, NULL, + memobj, strdup (p), 0); + + /* Squirrel away the memory object port where it diff --git a/SOURCES/glibc-rh1211823.patch b/SOURCES/glibc-rh1211823.patch new file mode 100644 index 00000000..84f4d668 --- /dev/null +++ b/SOURCES/glibc-rh1211823.patch @@ -0,0 +1,29005 @@ +commit f22bc486c1ce5e92380a0d06b98fbba639d170e4 +Author: Andreas Schwab +Date: Thu Jan 10 17:46:49 2013 +0100 + + Update BIG5-HKSCS charmap to HKSCS-2008 + +diff --git a/iconvdata/BIG5HKSCS.irreversible b/iconvdata/BIG5HKSCS.irreversible +index d873dfa..34a261e 100644 +--- a/iconvdata/BIG5HKSCS.irreversible ++++ b/iconvdata/BIG5HKSCS.irreversible +@@ -1,5 +1,3 @@ +-0x8BF8 0x9F9C +-0x957A 0x8728 + 0xA27E 0x256D + 0xA2A1 0x256E + 0xA2A2 0x2570 +diff --git a/iconvdata/BIG5HKSCS.precomposed b/iconvdata/BIG5HKSCS.precomposed +new file mode 100644 +index 0000000..3ebb1f5 +--- /dev/null ++++ b/iconvdata/BIG5HKSCS.precomposed +@@ -0,0 +1,4 @@ ++0x88A3 0x00EA 0x0304 ++0x88A5 0x00EA 0x030C ++0x8862 0x00CA 0x0304 ++0x8864 0x00CA 0x030C +diff --git a/iconvdata/big5hkscs.c b/iconvdata/big5hkscs.c +index 18e413d..5487323 100644 +--- a/iconvdata/big5hkscs.c ++++ b/iconvdata/big5hkscs.c +@@ -29,8 +29,7 @@ + /* Table for Big5 to UCS conversion. + + With HKSCS mappings 0x8140-0xA0FE and 0xFA40-0xFEFE added; more info: +- http://www.digital21.gov.hk/eng/hkscs/index.html +- - spacehunt 07/01/2000 ++ http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/hkscs/ + + Using the charmap: + +@@ -43,7 +42,7 @@ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + while (<>) { + local($big5, $ucs) = split; +- $big5 = hex($big5) - 0x8840; ++ $big5 = hex($big5) - 0x8740; + local($ridx) = int($big5 / 256) * 195 + $big5 % 256; + printf "\n " if (($n % 4) == 0); + ++$n; +@@ -54,4545 +53,4621 @@ + */ + static const uint32_t big5hkscs_to_ucs[] = + { +- [ 0] = 0xF303, [ 1] = 0xF304, [ 2] = 0xF305, [ 3] = 0xF306, +- [ 4] = 0xF307, [ 5] = 0xF308, [ 6] = 0xF309, [ 7] = 0xF30A, +- [ 8] = 0xF30B, [ 9] = 0xF30C, [ 10] = 0xF30D, [ 11] = 0xF30E, +- [ 12] = 0xF30F, [ 13] = 0xF310, [ 14] = 0xF311, [ 15] = 0xF312, +- [ 16] = 0xF313, [ 17] = 0xF314, [ 18] = 0xF315, [ 19] = 0xF316, +- [ 20] = 0xF317, [ 21] = 0xF318, [ 22] = 0x0100, [ 23] = 0x00C1, +- [ 24] = 0x01CD, [ 25] = 0x00C0, [ 26] = 0x0112, [ 27] = 0x00C9, +- [ 28] = 0x011A, [ 29] = 0x00C8, [ 30] = 0x014C, [ 31] = 0x00D3, +- [ 32] = 0x01D1, [ 33] = 0x00D2, [ 34] = 0xF325, [ 35] = 0x1EBE, +- [ 36] = 0xF327, [ 37] = 0x1EC0, [ 38] = 0x00CA, [ 39] = 0x0101, +- [ 40] = 0x00E1, [ 41] = 0x01CE, [ 42] = 0x00E0, [ 43] = 0x0251, +- [ 44] = 0x0113, [ 45] = 0x00E9, [ 46] = 0x011B, [ 47] = 0x00E8, +- [ 48] = 0x012B, [ 49] = 0x00ED, [ 50] = 0x01D0, [ 51] = 0x00EC, +- [ 52] = 0x014D, [ 53] = 0x00F3, [ 54] = 0x01D2, [ 55] = 0x00F2, +- [ 56] = 0x016B, [ 57] = 0x00FA, [ 58] = 0x01D4, [ 59] = 0x00F9, +- [ 60] = 0x01D6, [ 61] = 0x01D8, [ 62] = 0x01DA, [ 97] = 0x01DC, +- [ 98] = 0x00FC, [ 99] = 0xF344, [ 100] = 0x1EBF, [ 101] = 0xF346, +- [ 102] = 0x1EC1, [ 103] = 0x00EA, [ 104] = 0x0261, [ 105] = 0xF34A, +- [ 106] = 0xF34B, [ 195] = 0x2A3A9, [ 196] = 0xF3A1, [ 198] = 0x650A, +- [ 201] = 0x4E3D, [ 202] = 0x6EDD, [ 203] = 0x9D4E, [ 204] = 0x91DF, +- [ 207] = 0x27735, [ 208] = 0x6491, [ 209] = 0x4F1A, [ 210] = 0x4F28, +- [ 211] = 0x4FA8, [ 212] = 0x5156, [ 213] = 0x5174, [ 214] = 0x519C, +- [ 215] = 0x51E4, [ 216] = 0x52A1, [ 217] = 0x52A8, [ 218] = 0x533B, +- [ 219] = 0x534E, [ 220] = 0x53D1, [ 221] = 0x53D8, [ 222] = 0x56E2, +- [ 223] = 0x58F0, [ 224] = 0x5904, [ 225] = 0x5907, [ 226] = 0x5932, +- [ 227] = 0x5934, [ 228] = 0x5B66, [ 229] = 0x5B9E, [ 230] = 0x5B9F, +- [ 231] = 0x5C9A, [ 232] = 0x5E86, [ 233] = 0x603B, [ 234] = 0x6589, +- [ 235] = 0x67FE, [ 236] = 0x6804, [ 237] = 0x6865, [ 238] = 0x6D4E, +- [ 239] = 0x70BC, [ 240] = 0x7535, [ 241] = 0x7EA4, [ 242] = 0x7EAC, +- [ 243] = 0x7EBA, [ 244] = 0x7EC7, [ 245] = 0x7ECF, [ 246] = 0x7EDF, +- [ 247] = 0x7F06, [ 248] = 0x7F37, [ 249] = 0x827A, [ 250] = 0x82CF, +- [ 251] = 0x836F, [ 252] = 0x89C6, [ 253] = 0x8BBE, [ 254] = 0x8BE2, +- [ 255] = 0x8F66, [ 256] = 0x8F67, [ 257] = 0x8F6E, [ 292] = 0x7411, +- [ 293] = 0x7CFC, [ 294] = 0x7DCD, [ 295] = 0x6946, [ 296] = 0x7AC9, +- [ 297] = 0x5227, [ 302] = 0x918C, [ 303] = 0x78B8, [ 304] = 0x915E, +- [ 305] = 0x80BC, [ 307] = 0x8D0B, [ 308] = 0x80F6, [ 309] = 0xF3F0, +- [ 312] = 0x809F, [ 313] = 0x9EC7, [ 314] = 0x4CCD, [ 315] = 0x9DC9, +- [ 316] = 0x9E0C, [ 317] = 0x4C3E, [ 318] = 0xF3F9, [ 319] = 0x2700E, +- [ 320] = 0x9E0A, [ 321] = 0xF3FC, [ 322] = 0x35C1, [ 324] = 0x6E9A, +- [ 325] = 0x823E, [ 326] = 0x7519, [ 328] = 0x4911, [ 329] = 0x9A6C, +- [ 330] = 0x9A8F, [ 331] = 0x9F99, [ 332] = 0x7987, [ 333] = 0xF408, +- [ 334] = 0x21DCA, [ 335] = 0x205D0, [ 336] = 0xF40B, [ 337] = 0x4E24, +- [ 338] = 0x4E81, [ 339] = 0x4E80, [ 340] = 0x4E87, [ 341] = 0x4EBF, +- [ 342] = 0x4EEB, [ 343] = 0x4F37, [ 344] = 0x344C, [ 345] = 0x4FBD, +- [ 346] = 0x3E48, [ 347] = 0x5003, [ 348] = 0x5088, [ 349] = 0x347D, +- [ 350] = 0x3493, [ 351] = 0x34A5, [ 352] = 0x5186, [ 353] = 0x5905, +- [ 354] = 0x51DB, [ 355] = 0x51FC, [ 356] = 0x5205, [ 357] = 0x4E89, +- [ 358] = 0x5279, [ 359] = 0x5290, [ 360] = 0x5327, [ 361] = 0x35C7, +- [ 362] = 0x53A9, [ 363] = 0x3551, [ 364] = 0x53B0, [ 365] = 0x3553, +- [ 366] = 0x53C2, [ 367] = 0x5423, [ 368] = 0x356D, [ 369] = 0x3572, +- [ 370] = 0x3681, [ 371] = 0x5493, [ 372] = 0x54A3, [ 373] = 0x54B4, +- [ 374] = 0x54B9, [ 375] = 0x54D0, [ 376] = 0x54EF, [ 377] = 0x5518, +- [ 378] = 0x5523, [ 379] = 0x5528, [ 380] = 0x3598, [ 381] = 0x553F, +- [ 382] = 0x35A5, [ 383] = 0x35BF, [ 384] = 0x55D7, [ 385] = 0x35C5, +- [ 390] = 0xF43D, [ 391] = 0x5525, [ 393] = 0x20C42, [ 394] = 0xF441, +- [ 395] = 0xF442, [ 396] = 0x5590, [ 397] = 0x22CC6, [ 398] = 0x39EC, +- [ 399] = 0x20341, [ 400] = 0x8E46, [ 401] = 0x24DB8, [ 402] = 0xF449, +- [ 403] = 0x4053, [ 404] = 0x280BE, [ 405] = 0x777A, [ 406] = 0xF44D, +- [ 407] = 0x3A34, [ 408] = 0x47D5, [ 409] = 0xF450, [ 410] = 0x269F2, +- [ 411] = 0x24DEA, [ 412] = 0x64DD, [ 413] = 0xF454, [ 414] = 0x20FB4, +- [ 415] = 0x20CD5, [ 416] = 0x210F4, [ 417] = 0x648D, [ 418] = 0x8E7E, +- [ 419] = 0xF45A, [ 420] = 0xF45B, [ 421] = 0xF45C, [ 422] = 0xF45D, +- [ 423] = 0x28256, [ 424] = 0x244D3, [ 426] = 0x20D46, [ 427] = 0xF462, +- [ 428] = 0x280E9, [ 429] = 0x47F4, [ 430] = 0xF465, [ 431] = 0xF466, +- [ 432] = 0x9AB2, [ 433] = 0x3A67, [ 434] = 0xF469, [ 435] = 0x3FED, +- [ 436] = 0x3506, [ 437] = 0x252C7, [ 438] = 0xF46D, [ 439] = 0xF46E, +- [ 440] = 0xF46F, [ 441] = 0x9D6E, [ 442] = 0x9815, [ 444] = 0x43D9, +- [ 445] = 0x260A5, [ 446] = 0x64B4, [ 447] = 0x54E3, [ 448] = 0xF477, +- [ 449] = 0xF478, [ 450] = 0x21077, [ 451] = 0x39FB, [ 452] = 0x2106F, +- [ 487] = 0xF47C, [ 488] = 0xF47D, [ 489] = 0xF47E, [ 490] = 0x64EA, +- [ 491] = 0xF480, [ 492] = 0x20C43, [ 493] = 0x8E68, [ 494] = 0x221A1, +- [ 495] = 0x28B4C, [ 496] = 0xF485, [ 498] = 0x480B, [ 499] = 0xF488, +- [ 500] = 0x3FFA, [ 501] = 0x5873, [ 502] = 0xF48B, [ 504] = 0xF48D, +- [ 505] = 0x204FC, [ 506] = 0xF48F, [ 507] = 0xF490, [ 508] = 0xF491, +- [ 509] = 0x5579, [ 510] = 0x40BB, [ 511] = 0x43BA, [ 513] = 0x4AB4, +- [ 514] = 0xF497, [ 515] = 0xF498, [ 516] = 0x81AA, [ 517] = 0x98F5, +- [ 518] = 0xF49B, [ 519] = 0x6379, [ 520] = 0x39FE, [ 521] = 0x22775, +- [ 522] = 0x8DC0, [ 523] = 0x56A1, [ 524] = 0x647C, [ 525] = 0x3E43, +- [ 527] = 0xF4A4, [ 528] = 0x20E09, [ 529] = 0x22ACF, [ 530] = 0xF4A7, +- [ 532] = 0x210C8, [ 533] = 0xF4AA, [ 534] = 0x3992, [ 535] = 0x3A06, +- [ 536] = 0xF4AD, [ 537] = 0x3578, [ 538] = 0xF4AF, [ 539] = 0x220C7, +- [ 540] = 0x5652, [ 541] = 0x20F31, [ 542] = 0xF4B3, [ 543] = 0xF4B4, +- [ 544] = 0x34BC, [ 545] = 0x6C3D, [ 546] = 0xF4B7, [ 549] = 0xF4BA, +- [ 550] = 0xF4BB, [ 551] = 0xF4BC, [ 552] = 0xF4BD, [ 553] = 0x28CCD, +- [ 554] = 0x20E7A, [ 555] = 0xF4C0, [ 556] = 0xF4C1, [ 557] = 0x7F93, +- [ 558] = 0xF4C3, [ 559] = 0x22803, [ 560] = 0x22939, [ 561] = 0x35FB, +- [ 562] = 0x251E3, [ 563] = 0xF4C8, [ 564] = 0x20F8D, [ 565] = 0x20EAA, +- [ 566] = 0x3F93, [ 567] = 0x20F30, [ 568] = 0x20D47, [ 569] = 0xF4CE, +- [ 570] = 0xF4CF, [ 572] = 0x20EAB, [ 573] = 0xF4D2, [ 574] = 0x20D48, +- [ 575] = 0x210C0, [ 576] = 0x2113D, [ 577] = 0x3FF9, [ 578] = 0x22696, +- [ 579] = 0x6432, [ 580] = 0x20FAD, [ 585] = 0x233F4, [ 586] = 0x27639, +- [ 587] = 0x22BCE, [ 588] = 0x20D7E, [ 589] = 0x20D7F, [ 590] = 0x22C51, +- [ 591] = 0x22C55, [ 592] = 0x3A18, [ 593] = 0xF4E2, [ 594] = 0x210C7, +- [ 595] = 0x20F2E, [ 596] = 0xF4E5, [ 597] = 0x26B50, [ 598] = 0xF4E7, +- [ 599] = 0xF4E8, [ 600] = 0xF4E9, [ 601] = 0x95AA, [ 602] = 0x54CC, +- [ 603] = 0x82C4, [ 604] = 0x55B9, [ 606] = 0x29EC3, [ 607] = 0x9C26, +- [ 608] = 0x9AB6, [ 609] = 0x2775E, [ 610] = 0xF4F3, [ 611] = 0x7140, +- [ 612] = 0x816D, [ 613] = 0x80EC, [ 614] = 0x5C1C, [ 615] = 0x26572, +- [ 616] = 0x8134, [ 617] = 0x3797, [ 618] = 0x535F, [ 619] = 0x280BD, +- [ 620] = 0x91B6, [ 621] = 0x20EFA, [ 622] = 0x20E0F, [ 623] = 0x20E77, +- [ 624] = 0x20EFB, [ 625] = 0x35DD, [ 626] = 0x24DEB, [ 627] = 0x3609, +- [ 628] = 0x20CD6, [ 629] = 0x56AF, [ 630] = 0x227B5, [ 631] = 0x210C9, +- [ 632] = 0x20E10, [ 633] = 0x20E78, [ 634] = 0x21078, [ 635] = 0x21148, +- [ 636] = 0x28207, [ 637] = 0x21455, [ 638] = 0x20E79, [ 639] = 0x24E50, +- [ 640] = 0x22DA4, [ 641] = 0x5A54, [ 642] = 0x2101D, [ 643] = 0x2101E, +- [ 644] = 0x210F5, [ 645] = 0x210F6, [ 646] = 0x579C, [ 647] = 0x20E11, +- [ 682] = 0x27694, [ 683] = 0x282CD, [ 684] = 0x20FB5, [ 685] = 0x20E7B, +- [ 686] = 0x2517E, [ 687] = 0x3703, [ 688] = 0x20FB6, [ 689] = 0x21180, +- [ 690] = 0x252D8, [ 691] = 0xF522, [ 692] = 0xF523, [ 693] = 0x2183A, +- [ 694] = 0xF525, [ 695] = 0xF526, [ 696] = 0x5899, [ 697] = 0x5268, +- [ 698] = 0x361A, [ 699] = 0xF52A, [ 700] = 0x7BB2, [ 701] = 0x5B68, +- [ 702] = 0x4800, [ 703] = 0x4B2C, [ 704] = 0x9F27, [ 705] = 0x49E7, +- [ 706] = 0x9C1F, [ 707] = 0x9B8D, [ 708] = 0x25B74, [ 709] = 0x2313D, +- [ 710] = 0x55FB, [ 711] = 0x35F2, [ 712] = 0x5689, [ 713] = 0x4E28, +- [ 714] = 0x5902, [ 715] = 0xF53A, [ 716] = 0xF53B, [ 717] = 0x9751, +- [ 718] = 0xF53D, [ 719] = 0x4E5B, [ 720] = 0x4EBB, [ 721] = 0x353E, +- [ 722] = 0x5C23, [ 723] = 0x5F51, [ 724] = 0x5FC4, [ 725] = 0x38FA, +- [ 726] = 0x624C, [ 727] = 0x6535, [ 728] = 0x6B7A, [ 729] = 0x6C35, +- [ 730] = 0x6C3A, [ 731] = 0x706C, [ 732] = 0x722B, [ 733] = 0x4E2C, +- [ 734] = 0x72AD, [ 735] = 0xF54E, [ 736] = 0x7F52, [ 737] = 0x793B, +- [ 738] = 0x7CF9, [ 739] = 0x7F53, [ 740] = 0xF553, [ 741] = 0x34C1, +- [ 743] = 0xF556, [ 744] = 0x8002, [ 745] = 0x8080, [ 746] = 0xF559, +- [ 747] = 0xF55A, [ 748] = 0x535D, [ 749] = 0x8864, [ 750] = 0x89C1, +- [ 751] = 0xF55E, [ 752] = 0x8BA0, [ 753] = 0x8D1D, [ 754] = 0x9485, +- [ 755] = 0x9578, [ 756] = 0x957F, [ 757] = 0x95E8, [ 758] = 0xF565, +- [ 759] = 0x97E6, [ 760] = 0x9875, [ 761] = 0x98CE, [ 762] = 0x98DE, +- [ 763] = 0x9963, [ 764] = 0xF56B, [ 765] = 0x9C7C, [ 766] = 0x9E1F, +- [ 767] = 0x9EC4, [ 768] = 0x6B6F, [ 769] = 0x9F9C, [ 770] = 0x4E37, +- [ 771] = 0xF572, [ 772] = 0x961D, [ 773] = 0x6237, [ 774] = 0x94A2, +- [ 1007] = 0x5D3E, [ 1008] = 0x5D48, [ 1009] = 0x5D56, [ 1010] = 0x3DFC, +- [ 1011] = 0x380F, [ 1012] = 0x5DA4, [ 1013] = 0x5DB9, [ 1014] = 0x3820, +- [ 1015] = 0x3838, [ 1016] = 0x5E42, [ 1017] = 0x5EBD, [ 1018] = 0x5F25, +- [ 1019] = 0x5F83, [ 1020] = 0x3908, [ 1021] = 0x3914, [ 1022] = 0x393F, +- [ 1023] = 0x394D, [ 1024] = 0x60D7, [ 1025] = 0x613D, [ 1026] = 0x5CE5, +- [ 1027] = 0x3989, [ 1028] = 0x61B7, [ 1029] = 0x61B9, [ 1030] = 0x61CF, +- [ 1031] = 0x39B8, [ 1032] = 0x622C, [ 1033] = 0x6290, [ 1034] = 0x62E5, +- [ 1035] = 0x6318, [ 1036] = 0x39F8, [ 1037] = 0x56B1, [ 1072] = 0x3A03, +- [ 1073] = 0x63E2, [ 1074] = 0x63FB, [ 1075] = 0x6407, [ 1076] = 0x645A, +- [ 1077] = 0x3A4B, [ 1078] = 0x64C0, [ 1079] = 0x5D15, [ 1080] = 0x5621, +- [ 1081] = 0x9F9F, [ 1082] = 0x3A97, [ 1083] = 0x6586, [ 1084] = 0x3ABD, +- [ 1085] = 0x65FF, [ 1086] = 0x6653, [ 1087] = 0x3AF2, [ 1088] = 0x6692, +- [ 1089] = 0x3B22, [ 1090] = 0x6716, [ 1091] = 0x3B42, [ 1092] = 0x67A4, +- [ 1093] = 0x6800, [ 1094] = 0x3B58, [ 1095] = 0x684A, [ 1096] = 0x6884, +- [ 1097] = 0x3B72, [ 1098] = 0x3B71, [ 1099] = 0x3B7B, [ 1100] = 0x6909, +- [ 1101] = 0x6943, [ 1102] = 0x725C, [ 1103] = 0x6964, [ 1104] = 0x699F, +- [ 1105] = 0x6985, [ 1106] = 0x3BBC, [ 1107] = 0x69D6, [ 1108] = 0x3BDD, +- [ 1109] = 0x6A65, [ 1110] = 0x6A74, [ 1111] = 0x6A71, [ 1112] = 0x6A82, +- [ 1113] = 0x3BEC, [ 1114] = 0x6A99, [ 1115] = 0x3BF2, [ 1116] = 0x6AAB, +- [ 1117] = 0x6AB5, [ 1118] = 0x6AD4, [ 1119] = 0x6AF6, [ 1120] = 0x6B81, +- [ 1121] = 0x6BC1, [ 1122] = 0x6BEA, [ 1123] = 0x6C75, [ 1124] = 0x6CAA, +- [ 1125] = 0x3CCB, [ 1126] = 0x6D02, [ 1127] = 0x6D06, [ 1128] = 0x6D26, +- [ 1129] = 0x6D81, [ 1130] = 0x3CEF, [ 1131] = 0x6DA4, [ 1132] = 0x6DB1, +- [ 1133] = 0x6E15, [ 1134] = 0x6E18, [ 1135] = 0x6E29, [ 1136] = 0x6E86, +- [ 1137] = 0x289C0, [ 1138] = 0x6EBB, [ 1139] = 0x6EE2, [ 1140] = 0x6EDA, +- [ 1141] = 0x9F7F, [ 1142] = 0x6EE8, [ 1143] = 0x6EE9, [ 1144] = 0x6F24, +- [ 1145] = 0x6F34, [ 1146] = 0x3D46, [ 1147] = 0x23F41, [ 1148] = 0x6F81, +- [ 1149] = 0x6FBE, [ 1150] = 0x3D6A, [ 1151] = 0x3D75, [ 1152] = 0x71B7, +- [ 1153] = 0x5C99, [ 1154] = 0x3D8A, [ 1155] = 0x702C, [ 1156] = 0x3D91, +- [ 1157] = 0x7050, [ 1158] = 0x7054, [ 1159] = 0x706F, [ 1160] = 0x707F, +- [ 1161] = 0x7089, [ 1162] = 0x20325, [ 1163] = 0x43C1, [ 1164] = 0x35F1, +- [ 1165] = 0xF6B0, [ 1170] = 0xE311, [ 1171] = 0x57BE, [ 1172] = 0x26ED3, +- [ 1173] = 0x713E, [ 1174] = 0x257E0, [ 1175] = 0x364E, [ 1176] = 0x69A2, +- [ 1177] = 0x28BE9, [ 1178] = 0x5B74, [ 1179] = 0x7A49, [ 1180] = 0x258E1, +- [ 1181] = 0x294D9, [ 1182] = 0x7A65, [ 1183] = 0x7A7D, [ 1184] = 0x259AC, +- [ 1185] = 0x7ABB, [ 1186] = 0x7AB0, [ 1187] = 0x7AC2, [ 1188] = 0x7AC3, +- [ 1189] = 0x71D1, [ 1190] = 0xE325, [ 1191] = 0x41CA, [ 1192] = 0x7ADA, +- [ 1193] = 0x7ADD, [ 1194] = 0x7AEA, [ 1195] = 0x41EF, [ 1196] = 0x54B2, +- [ 1197] = 0x25C01, [ 1198] = 0x7B0B, [ 1199] = 0x7B55, [ 1200] = 0x7B29, +- [ 1201] = 0xE330, [ 1202] = 0x25CFE, [ 1203] = 0x7BA2, [ 1204] = 0x7B6F, +- [ 1205] = 0x839C, [ 1206] = 0x25BB4, [ 1207] = 0x26C7F, [ 1208] = 0x7BD0, +- [ 1209] = 0x8421, [ 1210] = 0x7B92, [ 1212] = 0x23FF0, [ 1213] = 0x3DAD, +- [ 1214] = 0x25C65, [ 1215] = 0x8492, [ 1216] = 0x7BFA, [ 1218] = 0x7C35, +- [ 1219] = 0x25CC1, [ 1220] = 0x7C44, [ 1221] = 0x7C83, [ 1222] = 0xE345, +- [ 1223] = 0x7CA6, [ 1224] = 0x667D, [ 1225] = 0x24578, [ 1226] = 0x7CC9, +- [ 1227] = 0x7CC7, [ 1228] = 0x7CE6, [ 1229] = 0x7C74, [ 1230] = 0x7CF3, +- [ 1231] = 0x7CF5, [ 1267] = 0x7E67, [ 1268] = 0x451D, [ 1269] = 0x26E44, +- [ 1270] = 0x7D5D, [ 1271] = 0x26ED6, [ 1272] = 0x748D, [ 1273] = 0x7D89, +- [ 1274] = 0x7DAB, [ 1275] = 0x7135, [ 1276] = 0x7DB3, [ 1278] = 0x24057, +- [ 1279] = 0x26029, [ 1280] = 0x7DE4, [ 1281] = 0x3D13, [ 1282] = 0x7DF5, +- [ 1283] = 0x217F9, [ 1284] = 0x7DE5, [ 1285] = 0xE362, [ 1287] = 0x26121, +- [ 1288] = 0x2615A, [ 1289] = 0x7E6E, [ 1290] = 0x7E92, [ 1291] = 0x432B, +- [ 1292] = 0x946C, [ 1293] = 0x7E27, [ 1294] = 0x7F40, [ 1295] = 0x7F41, +- [ 1296] = 0x7F47, [ 1297] = 0x7936, [ 1298] = 0x262D0, [ 1299] = 0x99E1, +- [ 1300] = 0x7F97, [ 1301] = 0x26351, [ 1302] = 0x7FA3, [ 1303] = 0x21661, +- [ 1304] = 0x20068, [ 1305] = 0x455C, [ 1306] = 0x23766, [ 1307] = 0x4503, +- [ 1308] = 0x2833A, [ 1309] = 0x7FFA, [ 1310] = 0x26489, [ 1312] = 0x8008, +- [ 1313] = 0x801D, [ 1315] = 0x802F, [ 1316] = 0xE381, [ 1317] = 0xE382, +- [ 1318] = 0x803B, [ 1319] = 0x803C, [ 1320] = 0x8061, [ 1321] = 0xE386, +- [ 1322] = 0x4989, [ 1323] = 0x26626, [ 1324] = 0xE389, [ 1325] = 0x266E8, +- [ 1326] = 0x6725, [ 1327] = 0x80A7, [ 1328] = 0x28A48, [ 1329] = 0x8107, +- [ 1330] = 0x811A, [ 1331] = 0x58B0, [ 1332] = 0x226F6, [ 1333] = 0x6C7F, +- [ 1334] = 0x26498, [ 1335] = 0xE394, [ 1336] = 0x64E7, [ 1337] = 0xE396, +- [ 1338] = 0x8218, [ 1339] = 0x2185E, [ 1340] = 0x6A53, [ 1341] = 0x24A65, +- [ 1342] = 0x24A95, [ 1343] = 0x447A, [ 1344] = 0x8229, [ 1345] = 0xE39E, +- [ 1346] = 0x26A52, [ 1347] = 0xE3A0, [ 1348] = 0x4FF9, [ 1349] = 0x214FD, +- [ 1350] = 0x84E2, [ 1351] = 0x8362, [ 1352] = 0x26B0A, [ 1353] = 0x249A7, +- [ 1354] = 0x23530, [ 1355] = 0x21773, [ 1356] = 0x23DF8, [ 1357] = 0x82AA, +- [ 1358] = 0x691B, [ 1359] = 0x2F994, [ 1360] = 0x41DB, [ 1365] = 0x854B, +- [ 1366] = 0x82D0, [ 1367] = 0x831A, [ 1368] = 0x20E16, [ 1369] = 0x217B4, +- [ 1370] = 0x36C1, [ 1371] = 0xE3B4, [ 1372] = 0x2355A, [ 1373] = 0x827B, +- [ 1374] = 0x82E2, [ 1375] = 0x8318, [ 1376] = 0x23E8B, [ 1377] = 0x26DA3, +- [ 1378] = 0xE3BB, [ 1379] = 0x26B97, [ 1380] = 0x235CE, [ 1381] = 0x3DBF, +- [ 1382] = 0x831D, [ 1383] = 0x55EC, [ 1384] = 0x8385, [ 1385] = 0x450B, +- [ 1386] = 0x26DA5, [ 1387] = 0x83AC, [ 1389] = 0x83D3, [ 1390] = 0x347E, +- [ 1391] = 0x26ED4, [ 1392] = 0x6A57, [ 1393] = 0x855A, [ 1394] = 0x3496, +- [ 1395] = 0x26E42, [ 1396] = 0xE3CD, [ 1397] = 0x8458, [ 1398] = 0xE3CF, +- [ 1399] = 0x8471, [ 1400] = 0x3DD3, [ 1401] = 0x44E4, [ 1402] = 0x6AA7, +- [ 1403] = 0x844A, [ 1404] = 0xE3D5, [ 1405] = 0x7958, [ 1407] = 0x26B96, +- [ 1408] = 0x26E77, [ 1409] = 0x26E43, [ 1410] = 0x84DE, [ 1412] = 0x8391, +- [ 1413] = 0x44A0, [ 1414] = 0x8493, [ 1415] = 0x84E4, [ 1416] = 0xE3E1, +- [ 1417] = 0x4240, [ 1418] = 0x25CC0, [ 1419] = 0x4543, [ 1420] = 0x8534, +- [ 1421] = 0x5AF2, [ 1422] = 0xE3E7, [ 1423] = 0x4527, [ 1424] = 0x8573, +- [ 1425] = 0x4516, [ 1426] = 0x67BF, [ 1427] = 0x8616, [ 1462] = 0x28625, +- [ 1463] = 0x2863B, [ 1464] = 0x85C1, [ 1465] = 0xE3F0, [ 1466] = 0x8602, +- [ 1467] = 0xE3F2, [ 1468] = 0x270CD, [ 1469] = 0xE3F4, [ 1470] = 0x456A, +- [ 1471] = 0x8628, [ 1472] = 0x3648, [ 1473] = 0x218A2, [ 1474] = 0x53F7, +- [ 1475] = 0x2739A, [ 1476] = 0x867E, [ 1477] = 0x8771, [ 1478] = 0x2A0F8, +- [ 1479] = 0x87EE, [ 1480] = 0x22C27, [ 1481] = 0x87B1, [ 1482] = 0x87DA, +- [ 1483] = 0x880F, [ 1484] = 0x5661, [ 1485] = 0x866C, [ 1486] = 0x6856, +- [ 1487] = 0x460F, [ 1488] = 0x8845, [ 1489] = 0x8846, [ 1490] = 0x275E0, +- [ 1491] = 0x23DB9, [ 1492] = 0x275E4, [ 1493] = 0x885E, [ 1494] = 0x889C, +- [ 1495] = 0x465B, [ 1496] = 0x88B4, [ 1497] = 0x88B5, [ 1498] = 0x63C1, +- [ 1499] = 0x88C5, [ 1500] = 0x7777, [ 1501] = 0x2770F, [ 1502] = 0x8987, +- [ 1503] = 0x898A, [ 1506] = 0x89A7, [ 1507] = 0x89BC, [ 1508] = 0x28A25, +- [ 1509] = 0x89E7, [ 1510] = 0x27924, [ 1511] = 0x27ABD, [ 1512] = 0x8A9C, +- [ 1513] = 0x7793, [ 1514] = 0x91FE, [ 1515] = 0x8A90, [ 1516] = 0x27A59, +- [ 1517] = 0x7AE9, [ 1518] = 0x27B3A, [ 1519] = 0xE426, [ 1520] = 0x4713, +- [ 1521] = 0x27B38, [ 1522] = 0x717C, [ 1523] = 0x8B0C, [ 1524] = 0x8B1F, +- [ 1525] = 0x25430, [ 1526] = 0x25565, [ 1527] = 0x8B3F, [ 1528] = 0x8B4C, +- [ 1529] = 0x8B4D, [ 1530] = 0x8AA9, [ 1531] = 0x24A7A, [ 1532] = 0x8B90, +- [ 1533] = 0x8B9B, [ 1534] = 0x8AAF, [ 1535] = 0xE436, [ 1536] = 0x4615, +- [ 1537] = 0x884F, [ 1538] = 0x8C9B, [ 1539] = 0x27D54, [ 1540] = 0x27D8F, +- [ 1541] = 0x2F9D4, [ 1542] = 0x3725, [ 1543] = 0x27D53, [ 1544] = 0x8CD6, +- [ 1545] = 0x27D98, [ 1546] = 0x27DBD, [ 1547] = 0x8D12, [ 1548] = 0x8D03, +- [ 1549] = 0x21910, [ 1550] = 0x8CDB, [ 1551] = 0x705C, [ 1552] = 0x8D11, +- [ 1553] = 0xE448, [ 1554] = 0x3ED0, [ 1560] = 0x8DA9, [ 1561] = 0x28002, +- [ 1562] = 0xE44D, [ 1563] = 0x2498A, [ 1564] = 0x3B7C, [ 1565] = 0xE450, +- [ 1566] = 0x2710C, [ 1567] = 0x7AE7, [ 1568] = 0x8EAD, [ 1569] = 0x8EB6, +- [ 1570] = 0x8EC3, [ 1571] = 0x92D4, [ 1572] = 0x8F19, [ 1573] = 0x8F2D, +- [ 1574] = 0x28365, [ 1575] = 0x28412, [ 1576] = 0x8FA5, [ 1577] = 0x9303, +- [ 1578] = 0x2A29F, [ 1579] = 0x20A50, [ 1580] = 0x8FB3, [ 1581] = 0x492A, +- [ 1582] = 0x289DE, [ 1583] = 0x2853D, [ 1584] = 0x23DBB, [ 1585] = 0x5EF8, +- [ 1586] = 0x23262, [ 1587] = 0x8FF9, [ 1588] = 0xE467, [ 1589] = 0xE468, +- [ 1590] = 0xE469, [ 1591] = 0x22325, [ 1592] = 0x3980, [ 1593] = 0x26ED7, +- [ 1594] = 0x9037, [ 1595] = 0x2853C, [ 1596] = 0x27ABE, [ 1597] = 0x9061, +- [ 1598] = 0x2856C, [ 1599] = 0x2860B, [ 1600] = 0x90A8, [ 1601] = 0xE474, +- [ 1602] = 0x90C4, [ 1603] = 0x286E6, [ 1604] = 0x90AE, [ 1606] = 0x9167, +- [ 1607] = 0x3AF0, [ 1608] = 0x91A9, [ 1609] = 0x91C4, [ 1610] = 0x7CAC, +- [ 1611] = 0x28933, [ 1612] = 0x21E89, [ 1613] = 0x920E, [ 1614] = 0x6C9F, +- [ 1615] = 0x9241, [ 1616] = 0x9262, [ 1617] = 0x255B9, [ 1619] = 0x28AC6, +- [ 1620] = 0x23C9B, [ 1621] = 0x28B0C, [ 1622] = 0x255DB, [ 1657] = 0xE48A, +- [ 1658] = 0x932C, [ 1659] = 0x936B, [ 1660] = 0x28AE1, [ 1661] = 0x28BEB, +- [ 1662] = 0x708F, [ 1663] = 0x5AC3, [ 1664] = 0x28AE2, [ 1665] = 0x28AE5, +- [ 1666] = 0x4965, [ 1667] = 0x9244, [ 1668] = 0x28BEC, [ 1669] = 0x28C39, +- [ 1670] = 0x28BFF, [ 1671] = 0x9373, [ 1672] = 0x945B, [ 1673] = 0x8EBC, +- [ 1674] = 0x9585, [ 1675] = 0x95A6, [ 1676] = 0x9426, [ 1677] = 0x95A0, +- [ 1678] = 0x6FF6, [ 1679] = 0x42B9, [ 1680] = 0xE4A1, [ 1681] = 0x286D8, +- [ 1682] = 0x2127C, [ 1683] = 0x23E2E, [ 1684] = 0x49DF, [ 1685] = 0x6C1C, +- [ 1686] = 0x967B, [ 1687] = 0x9696, [ 1688] = 0x416C, [ 1689] = 0x96A3, +- [ 1690] = 0x26ED5, [ 1691] = 0x61DA, [ 1692] = 0x96B6, [ 1693] = 0x78F5, +- [ 1694] = 0x28AE0, [ 1695] = 0x96BD, [ 1696] = 0x53CC, [ 1697] = 0x49A1, +- [ 1698] = 0x26CB8, [ 1699] = 0x20274, [ 1700] = 0x26410, [ 1701] = 0x290AF, +- [ 1702] = 0x290E5, [ 1703] = 0x24AD1, [ 1704] = 0x21915, [ 1705] = 0x2330A, +- [ 1706] = 0x9731, [ 1707] = 0x8642, [ 1708] = 0x9736, [ 1709] = 0x4A0F, +- [ 1710] = 0x453D, [ 1711] = 0x4585, [ 1712] = 0xE4C1, [ 1713] = 0x7075, +- [ 1714] = 0x5B41, [ 1715] = 0x971B, [ 1717] = 0xE4C6, [ 1718] = 0x9757, +- [ 1719] = 0x5B4A, [ 1720] = 0x291EB, [ 1721] = 0x975F, [ 1722] = 0x9425, +- [ 1723] = 0x50D0, [ 1724] = 0x230B7, [ 1725] = 0x230BC, [ 1726] = 0x9789, +- [ 1727] = 0x979F, [ 1728] = 0x97B1, [ 1729] = 0x97BE, [ 1730] = 0x97C0, +- [ 1731] = 0x97D2, [ 1732] = 0x97E0, [ 1733] = 0x2546C, [ 1734] = 0x97EE, +- [ 1735] = 0x741C, [ 1736] = 0x29433, [ 1738] = 0x97F5, [ 1739] = 0x2941D, +- [ 1740] = 0xE4DD, [ 1741] = 0x4AD1, [ 1742] = 0x9834, [ 1743] = 0x9833, +- [ 1744] = 0x984B, [ 1745] = 0x9866, [ 1746] = 0x3B0E, [ 1747] = 0x27175, +- [ 1748] = 0x3D51, [ 1749] = 0x20630, [ 1750] = 0x2415C, [ 1755] = 0x25706, +- [ 1756] = 0x98CA, [ 1757] = 0x98B7, [ 1758] = 0x98C8, [ 1759] = 0x98C7, +- [ 1760] = 0x4AFF, [ 1761] = 0x26D27, [ 1762] = 0x216D3, [ 1763] = 0x55B0, +- [ 1764] = 0x98E1, [ 1765] = 0x98E6, [ 1766] = 0x98EC, [ 1767] = 0x9378, +- [ 1768] = 0x9939, [ 1769] = 0x24A29, [ 1770] = 0x4B72, [ 1771] = 0x29857, +- [ 1772] = 0x29905, [ 1773] = 0x99F5, [ 1774] = 0x9A0C, [ 1775] = 0x9A3B, +- [ 1776] = 0x9A10, [ 1777] = 0x9A58, [ 1778] = 0x25725, [ 1779] = 0x36C4, +- [ 1780] = 0x290B1, [ 1781] = 0x29BD5, [ 1782] = 0x9AE0, [ 1783] = 0x9AE2, +- [ 1784] = 0x29B05, [ 1785] = 0x9AF4, [ 1786] = 0x4C0E, [ 1787] = 0x9B14, +- [ 1788] = 0x9B2D, [ 1789] = 0x28600, [ 1790] = 0x5034, [ 1791] = 0x9B34, +- [ 1792] = 0x269A8, [ 1793] = 0x38C3, [ 1794] = 0x2307D, [ 1795] = 0x9B50, +- [ 1796] = 0x9B40, [ 1797] = 0x29D3E, [ 1798] = 0x5A45, [ 1799] = 0x21863, +- [ 1800] = 0x9B8E, [ 1801] = 0x2424B, [ 1802] = 0x9C02, [ 1803] = 0x9BFF, +- [ 1804] = 0x9C0C, [ 1805] = 0x29E68, [ 1806] = 0x9DD4, [ 1807] = 0x29FB7, +- [ 1808] = 0x2A192, [ 1809] = 0xE51E, [ 1810] = 0x2A0E1, [ 1811] = 0x2A123, +- [ 1812] = 0x2A1DF, [ 1813] = 0x9D7E, [ 1814] = 0x9D83, [ 1815] = 0xE524, +- [ 1816] = 0x9E0E, [ 1817] = 0x6888, [ 1852] = 0x9DC4, [ 1853] = 0xE528, +- [ 1854] = 0x2A193, [ 1855] = 0x2A220, [ 1856] = 0x2193B, [ 1857] = 0x2A233, +- [ 1858] = 0x9D39, [ 1859] = 0xE52E, [ 1860] = 0xE52F, [ 1861] = 0x9E90, +- [ 1862] = 0x9E95, [ 1863] = 0x9E9E, [ 1864] = 0x9EA2, [ 1865] = 0x4D34, +- [ 1866] = 0x9EAA, [ 1867] = 0x9EAF, [ 1868] = 0x24364, [ 1869] = 0x9EC1, +- [ 1870] = 0x3B60, [ 1871] = 0x39E5, [ 1872] = 0x3D1D, [ 1873] = 0x4F32, +- [ 1874] = 0x37BE, [ 1875] = 0x28C2B, [ 1876] = 0x9F02, [ 1877] = 0x9F08, +- [ 1878] = 0x4B96, [ 1879] = 0x9424, [ 1880] = 0x26DA2, [ 1881] = 0x9F17, +- [ 1883] = 0x9F39, [ 1884] = 0x569F, [ 1885] = 0x568A, [ 1886] = 0x9F45, +- [ 1887] = 0x99B8, [ 1888] = 0x2908B, [ 1889] = 0x97F2, [ 1890] = 0x847F, +- [ 1891] = 0x9F62, [ 1892] = 0x9F69, [ 1893] = 0x7ADC, [ 1894] = 0x9F8E, +- [ 1895] = 0x7216, [ 1896] = 0x4BBE, [ 1897] = 0x24975, [ 1898] = 0x249BB, +- [ 1899] = 0x7177, [ 1900] = 0x249F8, [ 1901] = 0x24348, [ 1902] = 0x24A51, +- [ 1903] = 0x739E, [ 1904] = 0x28BDA, [ 1905] = 0x218FA, [ 1906] = 0x799F, +- [ 1907] = 0x2897E, [ 1908] = 0x28E36, [ 1909] = 0x9369, [ 1910] = 0x93F3, +- [ 1911] = 0x28A44, [ 1912] = 0x92EC, [ 1913] = 0x9381, [ 1914] = 0x93CB, +- [ 1915] = 0x2896C, [ 1916] = 0x244B9, [ 1917] = 0x7217, [ 1918] = 0x3EEB, +- [ 1919] = 0x7772, [ 1920] = 0x7A43, [ 1921] = 0x70D0, [ 1922] = 0xE56D, +- [ 1923] = 0x243F8, [ 1924] = 0x717E, [ 1925] = 0xE570, [ 1926] = 0x70A3, +- [ 1927] = 0x218BE, [ 1928] = 0x23599, [ 1929] = 0x3EC7, [ 1930] = 0x21885, +- [ 1931] = 0x2542F, [ 1932] = 0x217F8, [ 1933] = 0x3722, [ 1934] = 0x216FB, +- [ 1935] = 0xE57A, [ 1936] = 0x36E1, [ 1937] = 0x21774, [ 1938] = 0xE57D, +- [ 1939] = 0x25F4B, [ 1940] = 0x3723, [ 1941] = 0x216C0, [ 1942] = 0x575B, +- [ 1943] = 0x24A25, [ 1944] = 0x213FE, [ 1945] = 0xE584, [ 1950] = 0x213C6, +- [ 1951] = 0x214B6, [ 1952] = 0x8503, [ 1953] = 0x236A6, [ 1955] = 0x8455, +- [ 1956] = 0xE58B, [ 1957] = 0x27165, [ 1958] = 0x23E31, [ 1959] = 0x2555C, +- [ 1960] = 0x23EFB, [ 1961] = 0x27052, [ 1962] = 0x44F4, [ 1963] = 0x236EE, +- [ 1964] = 0x2999D, [ 1965] = 0x26F26, [ 1966] = 0x67F9, [ 1967] = 0x3733, +- [ 1968] = 0x3C15, [ 1969] = 0x3DE7, [ 1970] = 0x586C, [ 1971] = 0xE59A, +- [ 1972] = 0x6810, [ 1973] = 0x4057, [ 1974] = 0x2373F, [ 1975] = 0xE59E, +- [ 1976] = 0x2408B, [ 1977] = 0xE5A0, [ 1978] = 0x26C21, [ 1979] = 0x54CB, +- [ 1980] = 0x569E, [ 1981] = 0x266B1, [ 1982] = 0x5692, [ 1983] = 0xE5A6, +- [ 1984] = 0x20BA8, [ 1985] = 0x20E0D, [ 1986] = 0x93C6, [ 1987] = 0xE5AA, +- [ 1988] = 0x939C, [ 1989] = 0x4EF8, [ 1990] = 0x512B, [ 1991] = 0x3819, +- [ 1992] = 0x24436, [ 1993] = 0x4EBC, [ 1994] = 0x20465, [ 1995] = 0x2037F, +- [ 1996] = 0x4F4B, [ 1997] = 0x4F8A, [ 1998] = 0x25651, [ 1999] = 0x5A68, +- [ 2000] = 0x201AB, [ 2001] = 0x203CB, [ 2002] = 0x3999, [ 2003] = 0x2030A, +- [ 2004] = 0x20414, [ 2005] = 0x3435, [ 2006] = 0x4F29, [ 2007] = 0x202C0, +- [ 2008] = 0x28EB3, [ 2009] = 0x20275, [ 2010] = 0x8ADA, [ 2011] = 0xE5C2, +- [ 2012] = 0x4E98, [ 2047] = 0x50CD, [ 2048] = 0x510D, [ 2049] = 0x4FA2, +- [ 2050] = 0x4F03, [ 2051] = 0xE5C8, [ 2052] = 0x23E8A, [ 2053] = 0x4F42, +- [ 2054] = 0x502E, [ 2055] = 0x506C, [ 2056] = 0x5081, [ 2057] = 0x4FCC, +- [ 2058] = 0x4FE5, [ 2059] = 0x5058, [ 2060] = 0x50FC, [ 2065] = 0x6E76, +- [ 2066] = 0x23595, [ 2067] = 0xE5D8, [ 2068] = 0x23EBF, [ 2069] = 0x6D72, +- [ 2070] = 0x21884, [ 2071] = 0x23E89, [ 2072] = 0x51A8, [ 2073] = 0x51C3, +- [ 2074] = 0x205E0, [ 2075] = 0x44DD, [ 2076] = 0x204A3, [ 2077] = 0x20492, +- [ 2078] = 0x20491, [ 2079] = 0x8D7A, [ 2080] = 0x28A9C, [ 2081] = 0x2070E, +- [ 2082] = 0x5259, [ 2083] = 0x52A4, [ 2084] = 0x20873, [ 2085] = 0x52E1, +- [ 2087] = 0x467A, [ 2088] = 0x718C, [ 2089] = 0x2438C, [ 2090] = 0x20C20, +- [ 2091] = 0x249AC, [ 2092] = 0xE5F1, [ 2093] = 0x69D1, [ 2094] = 0x20E1D, +- [ 2096] = 0x3EDE, [ 2097] = 0x7499, [ 2098] = 0x7414, [ 2099] = 0x7456, +- [ 2100] = 0x7398, [ 2101] = 0x4B8E, [ 2102] = 0x24ABC, [ 2103] = 0x2408D, +- [ 2104] = 0x53D0, [ 2105] = 0x3584, [ 2106] = 0x720F, [ 2107] = 0x240C9, +- [ 2108] = 0x55B4, [ 2109] = 0x20345, [ 2110] = 0x54CD, [ 2111] = 0x20BC6, +- [ 2112] = 0x571D, [ 2113] = 0x925D, [ 2114] = 0x96F4, [ 2115] = 0x9366, +- [ 2116] = 0x57DD, [ 2117] = 0x578D, [ 2118] = 0x577F, [ 2119] = 0x363E, +- [ 2120] = 0x58CB, [ 2121] = 0x5A99, [ 2122] = 0x28A46, [ 2123] = 0x216FA, +- [ 2124] = 0x2176F, [ 2125] = 0x21710, [ 2126] = 0x5A2C, [ 2127] = 0x59B8, +- [ 2128] = 0x928F, [ 2129] = 0x5A7E, [ 2130] = 0x5ACF, [ 2131] = 0x5A12, +- [ 2132] = 0xE619, [ 2133] = 0x219F3, [ 2134] = 0x21861, [ 2135] = 0xE61C, +- [ 2136] = 0x36F5, [ 2137] = 0x6D05, [ 2138] = 0x7443, [ 2139] = 0x5A21, +- [ 2140] = 0x25E83, [ 2145] = 0x5A81, [ 2146] = 0x28BD7, [ 2147] = 0x20413, +- [ 2148] = 0x93E0, [ 2149] = 0x748C, [ 2150] = 0x21303, [ 2151] = 0x7105, +- [ 2152] = 0x4972, [ 2153] = 0x9408, [ 2154] = 0x289FB, [ 2155] = 0x93BD, +- [ 2156] = 0x37A0, [ 2157] = 0x5C1E, [ 2158] = 0x5C9E, [ 2159] = 0x5E5E, +- [ 2160] = 0x5E48, [ 2161] = 0x21996, [ 2162] = 0x2197C, [ 2163] = 0x23AEE, +- [ 2164] = 0x5ECD, [ 2165] = 0x5B4F, [ 2166] = 0x21903, [ 2167] = 0x21904, +- [ 2168] = 0x3701, [ 2169] = 0x218A0, [ 2170] = 0x36DD, [ 2171] = 0x216FE, +- [ 2172] = 0x36D3, [ 2173] = 0x812A, [ 2174] = 0x28A47, [ 2175] = 0x21DBA, +- [ 2176] = 0x23472, [ 2177] = 0x289A8, [ 2178] = 0x5F0C, [ 2179] = 0x5F0E, +- [ 2180] = 0x21927, [ 2181] = 0xE646, [ 2182] = 0x5A6B, [ 2183] = 0x2173B, +- [ 2184] = 0x5B44, [ 2185] = 0x8614, [ 2186] = 0x275FD, [ 2187] = 0x8860, +- [ 2188] = 0x607E, [ 2189] = 0x22860, [ 2190] = 0x2262B, [ 2191] = 0x5FDB, +- [ 2192] = 0x3EB8, [ 2193] = 0x225AF, [ 2194] = 0x225BE, [ 2195] = 0xE654, +- [ 2196] = 0x26F73, [ 2197] = 0x61C0, [ 2198] = 0x2003E, [ 2199] = 0x20046, +- [ 2200] = 0x2261B, [ 2201] = 0x6199, [ 2202] = 0x6198, [ 2203] = 0x6075, +- [ 2204] = 0x22C9B, [ 2205] = 0x22D07, [ 2206] = 0x246D4, [ 2207] = 0xE660, +- [ 2242] = 0x6471, [ 2243] = 0x24665, [ 2244] = 0x22B6A, [ 2245] = 0x3A29, +- [ 2246] = 0x22B22, [ 2247] = 0x23450, [ 2248] = 0x298EA, [ 2249] = 0x22E78, +- [ 2250] = 0x6337, [ 2251] = 0xE66A, [ 2252] = 0x64B6, [ 2253] = 0x6331, +- [ 2254] = 0x63D1, [ 2255] = 0x249E3, [ 2256] = 0x22D67, [ 2257] = 0x62A4, +- [ 2258] = 0x22CA1, [ 2259] = 0x643B, [ 2260] = 0x656B, [ 2261] = 0x6972, +- [ 2262] = 0x3BF4, [ 2263] = 0x2308E, [ 2264] = 0x232AD, [ 2265] = 0x24989, +- [ 2266] = 0x232AB, [ 2267] = 0x550D, [ 2268] = 0x232E0, [ 2269] = 0x218D9, +- [ 2270] = 0xE67D, [ 2271] = 0x66CE, [ 2272] = 0x23289, [ 2273] = 0xE680, +- [ 2274] = 0x3AE0, [ 2275] = 0x4190, [ 2276] = 0x25584, [ 2277] = 0x28B22, +- [ 2278] = 0x2558F, [ 2279] = 0x216FC, [ 2280] = 0x2555B, [ 2281] = 0x25425, +- [ 2282] = 0x78EE, [ 2283] = 0x23103, [ 2284] = 0x2182A, [ 2285] = 0x23234, +- [ 2286] = 0x3464, [ 2287] = 0xE68E, [ 2288] = 0x23182, [ 2289] = 0x242C9, +- [ 2290] = 0x668E, [ 2291] = 0x26D24, [ 2292] = 0x666B, [ 2293] = 0x4B93, +- [ 2294] = 0x6630, [ 2295] = 0x27870, [ 2296] = 0xE697, [ 2297] = 0x6663, +- [ 2298] = 0x232D2, [ 2299] = 0x232E1, [ 2300] = 0x661E, [ 2301] = 0x25872, +- [ 2302] = 0x38D1, [ 2303] = 0xE69E, [ 2304] = 0x237BC, [ 2305] = 0x3B99, +- [ 2306] = 0x237A2, [ 2307] = 0x233FE, [ 2308] = 0x74D0, [ 2309] = 0x3B96, +- [ 2310] = 0x678F, [ 2311] = 0x2462A, [ 2312] = 0x68B6, [ 2313] = 0x681E, +- [ 2314] = 0x3BC4, [ 2315] = 0x6ABE, [ 2316] = 0x3863, [ 2317] = 0x237D5, +- [ 2318] = 0x24487, [ 2319] = 0x6A33, [ 2320] = 0x6A52, [ 2321] = 0x6AC9, +- [ 2322] = 0x6B05, [ 2323] = 0x21912, [ 2324] = 0x6511, [ 2325] = 0x6898, +- [ 2326] = 0x6A4C, [ 2327] = 0x3BD7, [ 2328] = 0x6A7A, [ 2329] = 0x6B57, +- [ 2330] = 0x23FC0, [ 2331] = 0x23C9A, [ 2332] = 0x93A0, [ 2333] = 0x92F2, +- [ 2334] = 0x28BEA, [ 2335] = 0x28ACB, [ 2340] = 0x9289, [ 2341] = 0xE6C0, +- [ 2342] = 0x289DC, [ 2343] = 0x9467, [ 2344] = 0x6DA5, [ 2345] = 0x6F0B, +- [ 2346] = 0xE6C5, [ 2348] = 0x23F7F, [ 2349] = 0x3D8F, [ 2350] = 0x6E04, +- [ 2351] = 0x2403C, [ 2352] = 0x5A3D, [ 2353] = 0x6E0A, [ 2354] = 0x5847, +- [ 2355] = 0x6D24, [ 2356] = 0x7842, [ 2357] = 0x713B, [ 2358] = 0x2431A, +- [ 2359] = 0x24276, [ 2360] = 0x70F1, [ 2361] = 0x7250, [ 2362] = 0x7287, +- [ 2363] = 0x7294, [ 2364] = 0x2478F, [ 2365] = 0x24725, [ 2366] = 0x5179, +- [ 2367] = 0x24AA4, [ 2368] = 0x205EB, [ 2369] = 0x747A, [ 2370] = 0x23EF8, +- [ 2371] = 0xE6DE, [ 2372] = 0xE6DF, [ 2373] = 0x24917, [ 2374] = 0x25FE1, +- [ 2375] = 0x3F06, [ 2376] = 0x3EB1, [ 2377] = 0x24ADF, [ 2378] = 0x28C23, +- [ 2379] = 0x23F35, [ 2380] = 0x60A7, [ 2381] = 0x3EF3, [ 2382] = 0x74CC, +- [ 2383] = 0x743C, [ 2384] = 0x9387, [ 2385] = 0x7437, [ 2386] = 0x449F, +- [ 2387] = 0x26DEA, [ 2388] = 0x4551, [ 2389] = 0x7583, [ 2390] = 0x3F63, +- [ 2391] = 0x24CD9, [ 2392] = 0x24D06, [ 2393] = 0x3F58, [ 2394] = 0x7555, +- [ 2395] = 0x7673, [ 2396] = 0x2A5C6, [ 2397] = 0x3B19, [ 2398] = 0x7468, +- [ 2399] = 0x28ACC, [ 2400] = 0x249AB, [ 2401] = 0x2498E, [ 2402] = 0x3AFB, +- [ 2437] = 0x3DCD, [ 2438] = 0x24A4E, [ 2439] = 0x3EFF, [ 2440] = 0xE701, +- [ 2441] = 0x248F3, [ 2442] = 0x91FA, [ 2443] = 0x5732, [ 2444] = 0x9342, +- [ 2445] = 0x28AE3, [ 2446] = 0x21864, [ 2447] = 0x50DF, [ 2448] = 0x25221, +- [ 2449] = 0x251E7, [ 2450] = 0x7778, [ 2451] = 0x23232, [ 2452] = 0x770E, +- [ 2453] = 0x770F, [ 2454] = 0x777B, [ 2455] = 0x24697, [ 2456] = 0x23781, +- [ 2457] = 0x3A5E, [ 2458] = 0xE713, [ 2459] = 0x7438, [ 2460] = 0x749B, +- [ 2461] = 0x3EBF, [ 2462] = 0x24ABA, [ 2463] = 0x24AC7, [ 2464] = 0x40C8, +- [ 2465] = 0x24A96, [ 2466] = 0x261AE, [ 2467] = 0x9307, [ 2468] = 0x25581, +- [ 2469] = 0x781E, [ 2470] = 0x788D, [ 2471] = 0x7888, [ 2472] = 0x78D2, +- [ 2473] = 0x73D0, [ 2474] = 0x7959, [ 2475] = 0x27741, [ 2476] = 0xE725, +- [ 2477] = 0x410E, [ 2479] = 0x8496, [ 2480] = 0x79A5, [ 2481] = 0x6A2D, +- [ 2482] = 0x23EFA, [ 2483] = 0x7A3A, [ 2484] = 0x79F4, [ 2485] = 0x416E, +- [ 2486] = 0x216E6, [ 2487] = 0x4132, [ 2488] = 0x9235, [ 2489] = 0x79F1, +- [ 2490] = 0x20D4C, [ 2491] = 0x2498C, [ 2492] = 0x20299, [ 2493] = 0x23DBA, +- [ 2494] = 0x2176E, [ 2495] = 0x3597, [ 2496] = 0x556B, [ 2497] = 0x3570, +- [ 2498] = 0x36AA, [ 2499] = 0x201D4, [ 2500] = 0xE73D, [ 2501] = 0x7AE2, +- [ 2502] = 0x5A59, [ 2503] = 0x226F5, [ 2504] = 0xE741, [ 2505] = 0x25A9C, +- [ 2506] = 0x5A0D, [ 2507] = 0x2025B, [ 2508] = 0x78F0, [ 2509] = 0x5A2A, +- [ 2510] = 0x25BC6, [ 2511] = 0x7AFE, [ 2512] = 0x41F9, [ 2513] = 0x7C5D, +- [ 2514] = 0x7C6D, [ 2515] = 0x4211, [ 2516] = 0x25BB3, [ 2517] = 0x25EBC, +- [ 2518] = 0x25EA6, [ 2519] = 0x7CCD, [ 2520] = 0x249F9, [ 2521] = 0xE752, +- [ 2522] = 0x7C8E, [ 2523] = 0x7C7C, [ 2524] = 0x7CAE, [ 2525] = 0x6AB2, +- [ 2526] = 0x7DDC, [ 2527] = 0x7E07, [ 2528] = 0x7DD3, [ 2529] = 0x7F4E, +- [ 2530] = 0x26261, [ 2535] = 0x2615C, [ 2536] = 0xE75D, [ 2537] = 0x7D97, +- [ 2538] = 0x25E82, [ 2539] = 0x426A, [ 2540] = 0xE761, [ 2541] = 0x20916, +- [ 2542] = 0x67D6, [ 2543] = 0x2004E, [ 2544] = 0x235CF, [ 2545] = 0x57C4, +- [ 2546] = 0x26412, [ 2547] = 0xE768, [ 2548] = 0x24962, [ 2549] = 0x7FDD, +- [ 2550] = 0x7B27, [ 2551] = 0x2082C, [ 2552] = 0x25AE9, [ 2553] = 0x25D43, +- [ 2554] = 0x7B0C, [ 2555] = 0x25E0E, [ 2556] = 0x99E6, [ 2557] = 0x8645, +- [ 2558] = 0x9A63, [ 2559] = 0x6A1C, [ 2560] = 0xE775, [ 2561] = 0x39E2, +- [ 2562] = 0x249F7, [ 2563] = 0x265AD, [ 2564] = 0x9A1F, [ 2565] = 0xE77A, +- [ 2566] = 0x8480, [ 2567] = 0x27127, [ 2568] = 0xE77D, [ 2569] = 0x44EA, +- [ 2570] = 0x8137, [ 2571] = 0x4402, [ 2572] = 0x80C6, [ 2573] = 0x8109, +- [ 2574] = 0x8142, [ 2575] = 0x267B4, [ 2576] = 0x98C3, [ 2577] = 0x26A42, +- [ 2578] = 0x8262, [ 2579] = 0x8265, [ 2580] = 0x26A51, [ 2581] = 0x8453, +- [ 2582] = 0x26DA7, [ 2583] = 0x8610, [ 2584] = 0x2721B, [ 2585] = 0x5A86, +- [ 2586] = 0x417F, [ 2587] = 0xE790, [ 2588] = 0x5B2B, [ 2589] = 0x218A1, +- [ 2590] = 0x5AE4, [ 2591] = 0x218D8, [ 2592] = 0x86A0, [ 2593] = 0x8728, +- [ 2594] = 0xE797, [ 2595] = 0x882D, [ 2596] = 0x27422, [ 2597] = 0x5A02, +- [ 2632] = 0x886E, [ 2633] = 0x4F45, [ 2634] = 0x8887, [ 2635] = 0x88BF, +- [ 2636] = 0x88E6, [ 2637] = 0x8965, [ 2638] = 0x894D, [ 2639] = 0x25683, +- [ 2640] = 0x8954, [ 2641] = 0x27785, [ 2642] = 0x27784, [ 2643] = 0xE7A6, +- [ 2644] = 0x28BD9, [ 2645] = 0x28B9C, [ 2646] = 0x289F9, [ 2647] = 0x3EAD, +- [ 2648] = 0x84A3, [ 2649] = 0x46F5, [ 2650] = 0x46CF, [ 2651] = 0x37F2, +- [ 2652] = 0x8A3D, [ 2653] = 0x8A1C, [ 2654] = 0x29448, [ 2655] = 0x5F4D, +- [ 2656] = 0x922B, [ 2657] = 0xE7B4, [ 2658] = 0x65D4, [ 2659] = 0x7129, +- [ 2660] = 0x70C4, [ 2661] = 0x21845, [ 2662] = 0x9D6D, [ 2663] = 0x8C9F, +- [ 2664] = 0x8CE9, [ 2665] = 0x27DDC, [ 2666] = 0x599A, [ 2667] = 0x77C3, +- [ 2668] = 0x59F0, [ 2669] = 0x436E, [ 2670] = 0x36D4, [ 2671] = 0x8E2A, +- [ 2672] = 0x8EA7, [ 2673] = 0x24C09, [ 2674] = 0x8F30, [ 2675] = 0x8F4A, +- [ 2676] = 0x42F4, [ 2677] = 0x6C58, [ 2678] = 0x6FBB, [ 2679] = 0x22321, +- [ 2680] = 0x489B, [ 2681] = 0x6F79, [ 2682] = 0x6E8B, [ 2683] = 0x217DA, +- [ 2684] = 0x9BE9, [ 2685] = 0x36B5, [ 2686] = 0x2492F, [ 2687] = 0x90BB, +- [ 2689] = 0x5571, [ 2690] = 0x4906, [ 2691] = 0x91BB, [ 2692] = 0x9404, +- [ 2693] = 0x28A4B, [ 2694] = 0x4062, [ 2695] = 0xE7DA, [ 2696] = 0x9427, +- [ 2697] = 0x28C1D, [ 2698] = 0xE7DD, [ 2699] = 0x84E5, [ 2700] = 0x8A2B, +- [ 2701] = 0x9599, [ 2702] = 0x95A7, [ 2703] = 0x9597, [ 2704] = 0x9596, +- [ 2705] = 0x28D34, [ 2706] = 0x7445, [ 2707] = 0x3EC2, [ 2708] = 0x248FF, +- [ 2709] = 0xE7E8, [ 2710] = 0xE7E9, [ 2711] = 0x3EE7, [ 2712] = 0x23225, +- [ 2713] = 0x968F, [ 2714] = 0xE7ED, [ 2715] = 0x28E66, [ 2716] = 0x28E65, +- [ 2717] = 0x3ECC, [ 2718] = 0xE7F1, [ 2719] = 0x24A78, [ 2720] = 0x23FEE, +- [ 2721] = 0x7412, [ 2722] = 0x746B, [ 2723] = 0x3EFC, [ 2724] = 0x9741, +- [ 2725] = 0x290B0, [ 2730] = 0x6847, [ 2731] = 0x4A1D, [ 2732] = 0xE7FB, +- [ 2733] = 0xE7FC, [ 2735] = 0x9368, [ 2736] = 0x28989, [ 2737] = 0xE800, +- [ 2738] = 0x28B2F, [ 2739] = 0x263BE, [ 2740] = 0x92BA, [ 2741] = 0x5B11, +- [ 2742] = 0x8B69, [ 2743] = 0x493C, [ 2744] = 0x73F9, [ 2745] = 0x2421B, +- [ 2746] = 0x979B, [ 2747] = 0x9771, [ 2748] = 0x9938, [ 2749] = 0xE80C, +- [ 2750] = 0x5DC1, [ 2751] = 0x28BC5, [ 2752] = 0x24AB2, [ 2753] = 0x981F, +- [ 2754] = 0x294DA, [ 2755] = 0x92F6, [ 2756] = 0xE813, [ 2757] = 0x91E5, +- [ 2758] = 0x44C0, [ 2759] = 0x28B50, [ 2760] = 0x24A67, [ 2761] = 0x28B64, +- [ 2762] = 0x98DC, [ 2763] = 0x28A45, [ 2764] = 0x3F00, [ 2765] = 0x922A, +- [ 2766] = 0x4925, [ 2767] = 0x8414, [ 2768] = 0x993B, [ 2769] = 0x994D, +- [ 2770] = 0xE821, [ 2771] = 0x3DFD, [ 2772] = 0x999B, [ 2773] = 0x4B6F, +- [ 2774] = 0x99AA, [ 2775] = 0x9A5C, [ 2776] = 0x28B65, [ 2777] = 0xE828, +- [ 2778] = 0x6A8F, [ 2779] = 0x9A21, [ 2780] = 0x5AFE, [ 2781] = 0x9A2F, +- [ 2782] = 0xE82D, [ 2783] = 0x4B90, [ 2784] = 0xE82F, [ 2785] = 0x99BC, +- [ 2786] = 0x4BBD, [ 2787] = 0x4B97, [ 2788] = 0x937D, [ 2789] = 0x5872, +- [ 2790] = 0x21302, [ 2791] = 0x5822, [ 2792] = 0x249B8, [ 2827] = 0x214E8, +- [ 2828] = 0x7844, [ 2829] = 0x2271F, [ 2830] = 0x23DB8, [ 2831] = 0x68C5, +- [ 2832] = 0x3D7D, [ 2833] = 0x9458, [ 2834] = 0x3927, [ 2835] = 0x6150, +- [ 2836] = 0x22781, [ 2837] = 0x2296B, [ 2838] = 0x6107, [ 2839] = 0x9C4F, +- [ 2840] = 0x9C53, [ 2841] = 0x9C7B, [ 2842] = 0x9C35, [ 2843] = 0x9C10, +- [ 2844] = 0x9B7F, [ 2845] = 0x9BCF, [ 2846] = 0x29E2D, [ 2847] = 0x9B9F, +- [ 2848] = 0xE84D, [ 2849] = 0x2A0FE, [ 2850] = 0x9D21, [ 2851] = 0x4CAE, +- [ 2852] = 0x24104, [ 2853] = 0x9E18, [ 2854] = 0x4CB0, [ 2855] = 0x9D0C, +- [ 2856] = 0xE855, [ 2857] = 0xE856, [ 2858] = 0x2A0F3, [ 2859] = 0x2992F, +- [ 2860] = 0x9DA5, [ 2861] = 0x84BD, [ 2862] = 0xE85B, [ 2863] = 0x26FDF, +- [ 2864] = 0xE85D, [ 2865] = 0x85FC, [ 2866] = 0x4533, [ 2867] = 0x26DA4, +- [ 2868] = 0x26E84, [ 2869] = 0x26DF0, [ 2870] = 0x8420, [ 2871] = 0x85EE, +- [ 2872] = 0xE865, [ 2873] = 0x237D7, [ 2874] = 0x26064, [ 2875] = 0x79E2, +- [ 2876] = 0x2359C, [ 2877] = 0x23640, [ 2878] = 0x492D, [ 2879] = 0x249DE, +- [ 2880] = 0x3D62, [ 2881] = 0x93DB, [ 2882] = 0x92BE, [ 2883] = 0x9348, +- [ 2884] = 0x202BF, [ 2885] = 0x78B9, [ 2886] = 0x9277, [ 2887] = 0x944D, +- [ 2888] = 0x4FE4, [ 2889] = 0x3440, [ 2890] = 0x9064, [ 2891] = 0x2555D, +- [ 2892] = 0x783D, [ 2893] = 0x7854, [ 2894] = 0x78B6, [ 2895] = 0x784B, +- [ 2896] = 0x21757, [ 2897] = 0x231C9, [ 2898] = 0x24941, [ 2899] = 0x369A, +- [ 2900] = 0x4F72, [ 2901] = 0x6FDA, [ 2902] = 0x6FD9, [ 2904] = 0x701E, +- [ 2905] = 0x5414, [ 2906] = 0xE887, [ 2907] = 0x57BB, [ 2908] = 0x58F3, +- [ 2909] = 0x578A, [ 2910] = 0x9D16, [ 2911] = 0x57D7, [ 2912] = 0x7134, +- [ 2913] = 0x34AF, [ 2914] = 0xE88F, [ 2915] = 0x71EB, [ 2916] = 0xE891, +- [ 2917] = 0x24F97, [ 2919] = 0x217B5, [ 2920] = 0x28A49, [ 2925] = 0x610C, +- [ 2926] = 0x5ACE, [ 2927] = 0x5A0B, [ 2928] = 0x42BC, [ 2929] = 0x24488, +- [ 2930] = 0x372C, [ 2931] = 0x4B7B, [ 2932] = 0x289FC, [ 2933] = 0x93BB, +- [ 2934] = 0x93B8, [ 2935] = 0x218D6, [ 2936] = 0xE8A1, [ 2937] = 0x8472, +- [ 2938] = 0x26CC0, [ 2939] = 0xE8A4, [ 2940] = 0x242FA, [ 2941] = 0x22C26, +- [ 2942] = 0x243C1, [ 2943] = 0x5994, [ 2944] = 0x23DB7, [ 2945] = 0x26741, +- [ 2946] = 0x7DA8, [ 2947] = 0x2615B, [ 2948] = 0x260A4, [ 2949] = 0x249B9, +- [ 2950] = 0x2498B, [ 2951] = 0x289FA, [ 2952] = 0x92E5, [ 2953] = 0x73E2, +- [ 2954] = 0x3EE9, [ 2955] = 0x74B4, [ 2956] = 0x28B63, [ 2957] = 0x2189F, +- [ 2958] = 0x3EE1, [ 2959] = 0x24AB3, [ 2960] = 0x6AD8, [ 2961] = 0x73F3, +- [ 2962] = 0x73FB, [ 2963] = 0x3ED6, [ 2964] = 0x24A3E, [ 2965] = 0x24A94, +- [ 2966] = 0x217D9, [ 2967] = 0x24A66, [ 2968] = 0x203A7, [ 2969] = 0xE8C2, +- [ 2970] = 0xE8C3, [ 2971] = 0x7448, [ 2972] = 0x24916, [ 2973] = 0x70A5, +- [ 2974] = 0x24976, [ 2975] = 0x9284, [ 2976] = 0x73E6, [ 2977] = 0x935F, +- [ 2978] = 0x204FE, [ 2979] = 0x9331, [ 2980] = 0xE8CD, [ 2981] = 0x28A16, +- [ 2982] = 0x9386, [ 2983] = 0x28BE7, [ 2984] = 0x255D5, [ 2985] = 0x4935, +- [ 2986] = 0x28A82, [ 2987] = 0x716B, [ 3022] = 0xE8D5, [ 3023] = 0xE8D6, +- [ 3024] = 0x56A4, [ 3025] = 0x2061A, [ 3026] = 0xE8D9, [ 3027] = 0xE8DA, +- [ 3028] = 0x5502, [ 3029] = 0x79C4, [ 3030] = 0x217FA, [ 3031] = 0x7DFE, +- [ 3032] = 0x216C2, [ 3033] = 0x24A50, [ 3034] = 0xE8E1, [ 3035] = 0x452E, +- [ 3036] = 0x9401, [ 3037] = 0x370A, [ 3038] = 0xE8E5, [ 3039] = 0x249AD, +- [ 3040] = 0x59B0, [ 3041] = 0x218BF, [ 3042] = 0x21883, [ 3043] = 0x27484, +- [ 3044] = 0x5AA1, [ 3045] = 0x36E2, [ 3046] = 0x23D5B, [ 3047] = 0x36B0, +- [ 3048] = 0x925F, [ 3049] = 0x5A79, [ 3050] = 0x28A81, [ 3051] = 0x21862, +- [ 3052] = 0x9374, [ 3053] = 0x3CCD, [ 3054] = 0x20AB4, [ 3055] = 0x4A96, +- [ 3056] = 0x398A, [ 3057] = 0x50F4, [ 3058] = 0x3D69, [ 3059] = 0x3D4C, +- [ 3060] = 0x2139C, [ 3061] = 0x7175, [ 3062] = 0x42FB, [ 3063] = 0xE8FE, +- [ 3064] = 0x6E0F, [ 3065] = 0x290E4, [ 3066] = 0x44EB, [ 3067] = 0x6D57, +- [ 3068] = 0x27E4F, [ 3069] = 0x7067, [ 3070] = 0x6CAF, [ 3071] = 0x3CD6, +- [ 3072] = 0x23FED, [ 3073] = 0x23E2D, [ 3074] = 0x6E02, [ 3075] = 0x6F0C, +- [ 3076] = 0x3D6F, [ 3077] = 0x203F5, [ 3078] = 0x7551, [ 3079] = 0x36BC, +- [ 3080] = 0x34C8, [ 3081] = 0x4680, [ 3082] = 0x3EDA, [ 3083] = 0x4871, +- [ 3084] = 0x59C4, [ 3085] = 0x926E, [ 3086] = 0x493E, [ 3087] = 0x8F41, +- [ 3088] = 0xE917, [ 3089] = 0xE918, [ 3090] = 0x5812, [ 3091] = 0x57C8, +- [ 3092] = 0x36D6, [ 3093] = 0x21452, [ 3094] = 0x70FE, [ 3095] = 0x24362, +- [ 3096] = 0xE91F, [ 3097] = 0x22FE3, [ 3098] = 0x212B0, [ 3099] = 0x223BD, +- [ 3100] = 0x68B9, [ 3101] = 0x6967, [ 3102] = 0xE925, [ 3103] = 0x234E5, +- [ 3104] = 0x27BF4, [ 3105] = 0x236DF, [ 3106] = 0x28A83, [ 3107] = 0x237D6, +- [ 3108] = 0xE92B, [ 3109] = 0x24C9F, [ 3110] = 0x6A1A, [ 3111] = 0x236AD, +- [ 3112] = 0x26CB7, [ 3113] = 0x843E, [ 3114] = 0x44DF, [ 3115] = 0x44CE, +- [ 3120] = 0x26D26, [ 3121] = 0xE934, [ 3122] = 0x26C82, [ 3123] = 0x26FDE, +- [ 3124] = 0x6F17, [ 3125] = 0x27109, [ 3126] = 0x833D, [ 3127] = 0x2173A, +- [ 3128] = 0x83ED, [ 3129] = 0x26C80, [ 3130] = 0x27053, [ 3131] = 0x217DB, +- [ 3132] = 0x5989, [ 3133] = 0x5A82, [ 3134] = 0x217B3, [ 3135] = 0x5A61, +- [ 3136] = 0x5A71, [ 3137] = 0x21905, [ 3138] = 0x241FC, [ 3139] = 0x372D, +- [ 3140] = 0x59EF, [ 3141] = 0x2173C, [ 3142] = 0x36C7, [ 3143] = 0x718E, +- [ 3144] = 0x9390, [ 3145] = 0x669A, [ 3146] = 0x242A5, [ 3147] = 0x5A6E, +- [ 3148] = 0x5A2B, [ 3149] = 0xE950, [ 3150] = 0x6A2B, [ 3151] = 0x23EF9, +- [ 3152] = 0x27736, [ 3153] = 0x2445B, [ 3154] = 0x242CA, [ 3155] = 0x711D, +- [ 3156] = 0x24259, [ 3157] = 0x289E1, [ 3158] = 0x4FB0, [ 3159] = 0x26D28, +- [ 3160] = 0x5CC2, [ 3161] = 0x244CE, [ 3162] = 0x27E4D, [ 3163] = 0x243BD, +- [ 3164] = 0x6A0C, [ 3165] = 0x24256, [ 3166] = 0x21304, [ 3167] = 0x70A6, +- [ 3168] = 0x7133, [ 3169] = 0x243E9, [ 3170] = 0x3DA5, [ 3171] = 0x6CDF, +- [ 3172] = 0xE967, [ 3173] = 0x24A4F, [ 3174] = 0x7E65, [ 3175] = 0x59EB, +- [ 3176] = 0x5D2F, [ 3177] = 0x3DF3, [ 3178] = 0x5F5C, [ 3179] = 0xE96E, +- [ 3180] = 0xE96F, [ 3181] = 0x7DA4, [ 3182] = 0x8426, [ 3217] = 0x5485, +- [ 3218] = 0xE973, [ 3219] = 0x23300, [ 3220] = 0x20214, [ 3221] = 0x577E, +- [ 3222] = 0xE977, [ 3223] = 0x20619, [ 3224] = 0x3FE5, [ 3225] = 0xE97A, +- [ 3226] = 0xE97B, [ 3227] = 0x7003, [ 3228] = 0xE97D, [ 3229] = 0x5D70, +- [ 3230] = 0x738F, [ 3231] = 0x7CD3, [ 3232] = 0x28A59, [ 3233] = 0xE982, +- [ 3234] = 0x4FC8, [ 3235] = 0x7FE7, [ 3236] = 0x72CD, [ 3237] = 0x7310, +- [ 3238] = 0x27AF4, [ 3239] = 0x7338, [ 3240] = 0x7339, [ 3241] = 0x256F6, +- [ 3242] = 0x7341, [ 3243] = 0x7348, [ 3244] = 0x3EA9, [ 3245] = 0x27B18, +- [ 3246] = 0x906C, [ 3247] = 0x71F5, [ 3248] = 0xE991, [ 3249] = 0x73E1, +- [ 3250] = 0x81F6, [ 3251] = 0x3ECA, [ 3252] = 0x770C, [ 3253] = 0x3ED1, +- [ 3254] = 0x6CA2, [ 3255] = 0x56FD, [ 3256] = 0x7419, [ 3257] = 0x741E, +- [ 3258] = 0x741F, [ 3259] = 0x3EE2, [ 3260] = 0x3EF0, [ 3261] = 0x3EF4, +- [ 3262] = 0x3EFA, [ 3263] = 0x74D3, [ 3264] = 0x3F0E, [ 3265] = 0x3F53, +- [ 3266] = 0x7542, [ 3267] = 0x756D, [ 3268] = 0x7572, [ 3269] = 0x758D, +- [ 3270] = 0x3F7C, [ 3271] = 0x75C8, [ 3272] = 0x75DC, [ 3273] = 0x3FC0, +- [ 3274] = 0x764D, [ 3275] = 0x3FD7, [ 3276] = 0x7674, [ 3277] = 0x3FDC, +- [ 3278] = 0x767A, [ 3279] = 0x24F5C, [ 3280] = 0x7188, [ 3281] = 0x5623, +- [ 3282] = 0x8980, [ 3283] = 0x5869, [ 3284] = 0x401D, [ 3285] = 0x7743, +- [ 3286] = 0x4039, [ 3287] = 0x6761, [ 3288] = 0x4045, [ 3289] = 0x35DB, +- [ 3290] = 0x7798, [ 3291] = 0x406A, [ 3292] = 0x406F, [ 3293] = 0x5C5E, +- [ 3294] = 0x77BE, [ 3295] = 0x77CB, [ 3296] = 0x58F2, [ 3297] = 0x7818, +- [ 3298] = 0x70B9, [ 3299] = 0x781C, [ 3300] = 0x40A8, [ 3301] = 0x7839, +- [ 3302] = 0x7847, [ 3303] = 0x7851, [ 3304] = 0x7866, [ 3305] = 0x8448, +- [ 3306] = 0xE9CB, [ 3307] = 0x7933, [ 3308] = 0x6803, [ 3309] = 0x7932, +- [ 3310] = 0x4103, [ 3315] = 0x4109, [ 3316] = 0x7991, [ 3317] = 0x7999, +- [ 3318] = 0x8FBB, [ 3319] = 0x7A06, [ 3320] = 0x8FBC, [ 3321] = 0x4167, +- [ 3322] = 0x7A91, [ 3323] = 0x41B2, [ 3324] = 0x7ABC, [ 3325] = 0x8279, +- [ 3326] = 0x41C4, [ 3327] = 0x7ACF, [ 3328] = 0x7ADB, [ 3329] = 0x41CF, +- [ 3330] = 0x4E21, [ 3331] = 0x7B62, [ 3332] = 0x7B6C, [ 3333] = 0x7B7B, +- [ 3334] = 0x7C12, [ 3335] = 0x7C1B, [ 3336] = 0x4260, [ 3337] = 0x427A, +- [ 3338] = 0x7C7B, [ 3339] = 0x7C9C, [ 3340] = 0x428C, [ 3341] = 0x7CB8, +- [ 3342] = 0x4294, [ 3343] = 0x7CED, [ 3344] = 0x8F93, [ 3345] = 0x70C0, +- [ 3346] = 0x20CCF, [ 3347] = 0x7DCF, [ 3348] = 0x7DD4, [ 3349] = 0x7DD0, +- [ 3350] = 0x7DFD, [ 3351] = 0x7FAE, [ 3352] = 0x7FB4, [ 3353] = 0x729F, +- [ 3354] = 0x4397, [ 3355] = 0x8020, [ 3356] = 0x8025, [ 3357] = 0x7B39, +- [ 3358] = 0x802E, [ 3359] = 0x8031, [ 3360] = 0x8054, [ 3361] = 0x3DCC, +- [ 3362] = 0x57B4, [ 3363] = 0x70A0, [ 3364] = 0x80B7, [ 3365] = 0x80E9, +- [ 3366] = 0x43ED, [ 3367] = 0x810C, [ 3368] = 0x732A, [ 3369] = 0x810E, +- [ 3370] = 0x8112, [ 3371] = 0x7560, [ 3372] = 0x8114, [ 3373] = 0x4401, +- [ 3374] = 0x3B39, [ 3375] = 0x8156, [ 3376] = 0x8159, [ 3377] = 0x815A, +- [ 3412] = 0x4413, [ 3413] = 0x583A, [ 3414] = 0x817C, [ 3415] = 0x8184, +- [ 3416] = 0x4425, [ 3417] = 0x8193, [ 3418] = 0x442D, [ 3419] = 0x81A5, +- [ 3420] = 0x57EF, [ 3421] = 0x81C1, [ 3422] = 0x81E4, [ 3423] = 0x8254, +- [ 3424] = 0x448F, [ 3425] = 0x82A6, [ 3426] = 0x8276, [ 3427] = 0x82CA, +- [ 3428] = 0x82D8, [ 3429] = 0x82FF, [ 3430] = 0x44B0, [ 3431] = 0x8357, +- [ 3432] = 0x9669, [ 3433] = 0x698A, [ 3434] = 0x8405, [ 3435] = 0x70F5, +- [ 3436] = 0x8464, [ 3437] = 0x60E3, [ 3438] = 0x8488, [ 3439] = 0x4504, +- [ 3440] = 0x84BE, [ 3441] = 0x84E1, [ 3442] = 0x84F8, [ 3443] = 0x8510, +- [ 3444] = 0x8538, [ 3445] = 0x8552, [ 3446] = 0x453B, [ 3447] = 0x856F, +- [ 3448] = 0x8570, [ 3449] = 0x85E0, [ 3450] = 0x4577, [ 3451] = 0x8672, +- [ 3452] = 0x8692, [ 3453] = 0x86B2, [ 3454] = 0x86EF, [ 3455] = 0x9645, +- [ 3456] = 0x878B, [ 3457] = 0x4606, [ 3458] = 0x4617, [ 3459] = 0x88AE, +- [ 3460] = 0x88FF, [ 3461] = 0x8924, [ 3462] = 0x8947, [ 3463] = 0x8991, +- [ 3464] = 0x27967, [ 3465] = 0x8A29, [ 3466] = 0x8A38, [ 3467] = 0x8A94, +- [ 3468] = 0x8AB4, [ 3469] = 0x8C51, [ 3470] = 0x8CD4, [ 3471] = 0x8CF2, +- [ 3472] = 0x8D1C, [ 3473] = 0x4798, [ 3474] = 0x585F, [ 3475] = 0x8DC3, +- [ 3476] = 0x47ED, [ 3477] = 0x4EEE, [ 3478] = 0x8E3A, [ 3479] = 0x55D8, +- [ 3480] = 0x5754, [ 3481] = 0x8E71, [ 3482] = 0x55F5, [ 3483] = 0x8EB0, +- [ 3484] = 0x4837, [ 3485] = 0x8ECE, [ 3486] = 0x8EE2, [ 3487] = 0x8EE4, +- [ 3488] = 0x8EED, [ 3489] = 0x8EF2, [ 3490] = 0x8FB7, [ 3491] = 0x8FC1, +- [ 3492] = 0x8FCA, [ 3493] = 0x8FCC, [ 3494] = 0x9033, [ 3495] = 0x99C4, +- [ 3496] = 0x48AD, [ 3497] = 0x98E0, [ 3498] = 0x9213, [ 3499] = 0x491E, +- [ 3500] = 0x9228, [ 3501] = 0x9258, [ 3502] = 0x926B, [ 3503] = 0x92B1, +- [ 3504] = 0x92AE, [ 3505] = 0x92BF, [ 3510] = 0x92E3, [ 3511] = 0x92EB, +- [ 3512] = 0x92F3, [ 3513] = 0x92F4, [ 3514] = 0x92FD, [ 3515] = 0x9343, +- [ 3516] = 0x9384, [ 3517] = 0x93AD, [ 3518] = 0x4945, [ 3519] = 0x4951, +- [ 3520] = 0x9EBF, [ 3521] = 0x9417, [ 3522] = 0x5301, [ 3523] = 0x941D, +- [ 3524] = 0x942D, [ 3525] = 0x943E, [ 3526] = 0x496A, [ 3527] = 0x9454, +- [ 3528] = 0x9479, [ 3529] = 0x952D, [ 3530] = 0x95A2, [ 3531] = 0x49A7, +- [ 3532] = 0x95F4, [ 3533] = 0x9633, [ 3534] = 0x49E5, [ 3535] = 0x67A0, +- [ 3536] = 0x4A24, [ 3537] = 0x9740, [ 3538] = 0x4A35, [ 3539] = 0x97B2, +- [ 3540] = 0x97C2, [ 3541] = 0x5654, [ 3542] = 0x4AE4, [ 3543] = 0x60E8, +- [ 3544] = 0x98B9, [ 3545] = 0x4B19, [ 3546] = 0x98F1, [ 3547] = 0x5844, +- [ 3548] = 0x990E, [ 3549] = 0x9919, [ 3550] = 0x51B4, [ 3551] = 0x991C, +- [ 3552] = 0x9937, [ 3553] = 0x9942, [ 3554] = 0x995D, [ 3555] = 0x9962, +- [ 3556] = 0x4B70, [ 3557] = 0x99C5, [ 3558] = 0x4B9D, [ 3559] = 0x9A3C, +- [ 3560] = 0x9B0F, [ 3561] = 0x7A83, [ 3562] = 0x9B69, [ 3563] = 0x9B81, +- [ 3564] = 0x9BDD, [ 3565] = 0x9BF1, [ 3566] = 0x9BF4, [ 3567] = 0x4C6D, +- [ 3568] = 0x9C20, [ 3569] = 0x376F, [ 3570] = 0xEAA9, [ 3571] = 0x9D49, +- [ 3572] = 0x9C3A, [ 3607] = 0x9EFE, [ 3608] = 0x5650, [ 3609] = 0x9D93, +- [ 3610] = 0x9DBD, [ 3611] = 0x9DC0, [ 3612] = 0x9DFC, [ 3613] = 0x94F6, +- [ 3614] = 0x8FB6, [ 3615] = 0x9E7B, [ 3616] = 0x9EAC, [ 3617] = 0x9EB1, +- [ 3618] = 0x9EBD, [ 3619] = 0x9EC6, [ 3620] = 0x94DC, [ 3621] = 0x9EE2, +- [ 3622] = 0x9EF1, [ 3623] = 0x9EF8, [ 3624] = 0x7AC8, [ 3625] = 0x9F44, +- [ 3626] = 0xEABF, [ 3627] = 0xEAC0, [ 3628] = 0xEAC1, [ 3629] = 0x691A, +- [ 3630] = 0x94C3, [ 3631] = 0x59AC, [ 3632] = 0xEAC5, [ 3633] = 0x5840, +- [ 3634] = 0x94C1, [ 3635] = 0x37B9, [ 3636] = 0xEAC9, [ 3637] = 0xEACA, +- [ 3638] = 0xEACB, [ 3639] = 0xEACC, [ 3640] = 0x5757, [ 3641] = 0x7173, +- [ 3642] = 0xEACF, [ 3643] = 0xEAD0, [ 3644] = 0xEAD1, [ 3645] = 0x546A, +- [ 3646] = 0xEAD3, [ 3647] = 0xEAD4, [ 3648] = 0x549E, [ 3649] = 0xEAD6, +- [ 3650] = 0xEAD7, [ 3651] = 0x20C53, [ 3652] = 0xEAD9, [ 3653] = 0xEADA, +- [ 3654] = 0x60E7, [ 3655] = 0xEADC, [ 3656] = 0x567A, [ 3657] = 0xEADE, +- [ 3658] = 0xEADF, [ 3659] = 0xEAE0, [ 3660] = 0xEAE1, [ 3661] = 0xEAE2, +- [ 3662] = 0xEAE3, [ 3663] = 0x6955, [ 3664] = 0x9C2F, [ 3665] = 0x87A5, +- [ 3666] = 0xEAE7, [ 3667] = 0x20E0E, [ 3668] = 0xEAE9, [ 3669] = 0xEAEA, +- [ 3670] = 0x20F2D, [ 3671] = 0xEAEC, [ 3672] = 0x5C20, [ 3673] = 0xEAEE, +- [ 3674] = 0x5E0B, [ 3675] = 0xEAF0, [ 3676] = 0xEAF1, [ 3677] = 0x21076, +- [ 3678] = 0x671E, [ 3679] = 0x2107B, [ 3680] = 0xEAF5, [ 3681] = 0xEAF6, +- [ 3682] = 0x3647, [ 3683] = 0xEAF8, [ 3684] = 0xEAF9, [ 3685] = 0xEAFA, +- [ 3686] = 0xEAFB, [ 3687] = 0x5364, [ 3688] = 0x84AD, [ 3689] = 0x212E3, +- [ 3690] = 0xEAFF, [ 3691] = 0xEB00, [ 3692] = 0x8B81, [ 3693] = 0xEB02, +- [ 3694] = 0xEB03, [ 3695] = 0xEB04, [ 3696] = 0xEB05, [ 3697] = 0x4E78, +- [ 3698] = 0x70BB, [ 3699] = 0xEB08, [ 3700] = 0xEB09, [ 3705] = 0xEB0A, +- [ 3706] = 0xEB0B, [ 3707] = 0xEB0C, [ 3708] = 0xEB0D, [ 3709] = 0xEB0E, +- [ 3710] = 0xEB0F, [ 3711] = 0x62C3, [ 3712] = 0x21ED5, [ 3713] = 0xEB12, +- [ 3714] = 0x7198, [ 3715] = 0x6855, [ 3716] = 0xEB15, [ 3717] = 0x69E9, +- [ 3718] = 0x36C8, [ 3719] = 0x2227C, [ 3720] = 0xEB19, [ 3721] = 0xEB1A, +- [ 3722] = 0xEB1B, [ 3723] = 0xEB1C, [ 3724] = 0xEB1D, [ 3725] = 0x82FD, +- [ 3726] = 0xEB1F, [ 3727] = 0xEB20, [ 3728] = 0x22AD5, [ 3729] = 0x89A5, +- [ 3730] = 0xEB23, [ 3731] = 0x8FA0, [ 3732] = 0xEB25, [ 3733] = 0x97B8, +- [ 3734] = 0xEB27, [ 3735] = 0x9847, [ 3736] = 0x9ABD, [ 3737] = 0xEB2A, +- [ 3739] = 0xEB2C, [ 3740] = 0xEB2D, [ 3741] = 0xEB2E, [ 3742] = 0x22D08, +- [ 3743] = 0xEB30, [ 3744] = 0xEB31, [ 3745] = 0xEB32, [ 3746] = 0xEB33, +- [ 3747] = 0xEB34, [ 3748] = 0xEB35, [ 3749] = 0xEB36, [ 3750] = 0xEB37, +- [ 3751] = 0xEB38, [ 3752] = 0xEB39, [ 3753] = 0x5FB1, [ 3754] = 0x6648, +- [ 3755] = 0x66BF, [ 3756] = 0xEB3D, [ 3757] = 0xEB3E, [ 3758] = 0xEB3F, +- [ 3760] = 0x249BA, [ 3762] = 0xEB43, [ 3763] = 0xEB44, [ 3765] = 0x20346, +- [ 3766] = 0x58B5, [ 3767] = 0x670E, [ 3802] = 0x6918, [ 3803] = 0xEB4A, +- [ 3804] = 0x27657, [ 3805] = 0x25FE2, [ 3806] = 0xEB4D, [ 3807] = 0xEB4E, +- [ 3808] = 0x275FE, [ 3809] = 0x2209A, [ 3810] = 0x48D0, [ 3811] = 0x4AB8, +- [ 3812] = 0xEB53, [ 3813] = 0x28A9A, [ 3814] = 0xEB55, [ 3815] = 0xEB56, +- [ 3816] = 0x2403B, [ 3817] = 0xEB58, [ 3818] = 0x24396, [ 3819] = 0xEB5A, +- [ 3820] = 0xEB5B, [ 3821] = 0x51D2, [ 3822] = 0x20611, [ 3823] = 0x599F, +- [ 3824] = 0x21EA8, [ 3825] = 0x3BBE, [ 3826] = 0x23CFF, [ 3827] = 0xEB62, +- [ 3828] = 0xEB63, [ 3829] = 0x5788, [ 3830] = 0xEB65, [ 3831] = 0x399B, +- [ 3832] = 0xEB67, [ 3833] = 0xEB68, [ 3834] = 0xEB69, [ 3835] = 0x3762, +- [ 3836] = 0x221C3, [ 3837] = 0x8B5E, [ 3838] = 0x28B4E, [ 3840] = 0xEB6F, +- [ 3841] = 0xEB70, [ 3842] = 0xEB71, [ 3843] = 0x7209, [ 3844] = 0xEB73, +- [ 3845] = 0x20C78, [ 3846] = 0x5965, [ 3847] = 0xEB76, [ 3848] = 0xEB77, +- [ 3849] = 0x20779, [ 3850] = 0x8EDA, [ 3851] = 0xEB7A, [ 3852] = 0x528F, +- [ 3853] = 0x573F, [ 3854] = 0x7171, [ 3855] = 0xEB7E, [ 3856] = 0xEB7F, +- [ 3857] = 0xEB80, [ 3858] = 0x24AA7, [ 3859] = 0x55BC, [ 3860] = 0xEB83, +- [ 3861] = 0x2546E, [ 3862] = 0x26B52, [ 3864] = 0x3473, [ 3865] = 0xEB88, +- [ 3866] = 0x27632, [ 3867] = 0xEB8A, [ 3868] = 0x4718, [ 3869] = 0xEB8C, +- [ 3870] = 0x25566, [ 3871] = 0x257C7, [ 3872] = 0x2493F, [ 3873] = 0xEB90, +- [ 3874] = 0x5066, [ 3875] = 0x34FB, [ 3876] = 0xEB93, [ 3878] = 0xEB95, +- [ 3879] = 0x477C, [ 3880] = 0x28948, [ 3881] = 0x25AAE, [ 3882] = 0xEB99, +- [ 3883] = 0x25C06, [ 3884] = 0xEB9B, [ 3885] = 0x57A1, [ 3886] = 0x7151, +- [ 3888] = 0xEB9F, [ 3889] = 0x27C12, [ 3890] = 0x9056, [ 3891] = 0xEBA2, +- [ 3892] = 0x24F9A, [ 3893] = 0x8B62, [ 3894] = 0xEBA5, [ 3895] = 0xEBA6, +- [ 3900] = 0x5D5B, [ 3901] = 0x26BF7, [ 3903] = 0xEBAA, [ 3904] = 0xEBAB, +- [ 3905] = 0x8AEA, [ 3906] = 0x249F6, [ 3907] = 0xEBAE, [ 3908] = 0x23FEF, +- [ 3909] = 0x26512, [ 3910] = 0x4BC0, [ 3911] = 0xEBB2, [ 3912] = 0xEBB3, +- [ 3913] = 0x2271B, [ 3914] = 0x9465, [ 3915] = 0x257E1, [ 3916] = 0x6195, +- [ 3917] = 0x5A27, [ 3918] = 0x2F8CD, [ 3920] = 0x56B9, [ 3921] = 0x24521, +- [ 3922] = 0xEBBD, [ 3923] = 0x4E6A, [ 3924] = 0xEBBF, [ 3925] = 0x9656, +- [ 3926] = 0x6D8F, [ 3927] = 0x26CBD, [ 3928] = 0x3618, [ 3929] = 0x8977, +- [ 3930] = 0xEBC5, [ 3931] = 0x2686E, [ 3932] = 0x26411, [ 3933] = 0x2685E, +- [ 3935] = 0xEBCA, [ 3936] = 0x7B42, [ 3937] = 0xEBCC, [ 3938] = 0x20A11, +- [ 3939] = 0xEBCE, [ 3941] = 0xEBD0, [ 3942] = 0x7A45, [ 3944] = 0x269FA, +- [ 3945] = 0x9A26, [ 3946] = 0xEBD5, [ 3947] = 0x365F, [ 3948] = 0xEBD7, +- [ 3949] = 0xEBD8, [ 3950] = 0x7983, [ 3951] = 0xEBDA, [ 3952] = 0xEBDB, +- [ 3953] = 0x5D2C, [ 3954] = 0xEBDD, [ 3956] = 0xEBDF, [ 3957] = 0x46D0, +- [ 3958] = 0xEBE1, [ 3959] = 0x753B, [ 3960] = 0x8865, [ 3961] = 0xEBE4, +- [ 3962] = 0x58B6, [ 3997] = 0x371C, [ 3998] = 0x2258D, [ 3999] = 0xEBE8, +- [ 4000] = 0xEBE9, [ 4001] = 0x3C54, [ 4002] = 0xEBEB, [ 4003] = 0xEBEC, +- [ 4004] = 0x9281, [ 4005] = 0x2217A, [ 4006] = 0xEBEF, [ 4007] = 0x9330, +- [ 4008] = 0x272E6, [ 4009] = 0xEBF2, [ 4010] = 0x6C39, [ 4011] = 0x949F, +- [ 4012] = 0xEBF5, [ 4013] = 0x20EF8, [ 4014] = 0x8827, [ 4015] = 0x88F5, +- [ 4016] = 0xEBF9, [ 4017] = 0xEBFA, [ 4018] = 0x217B1, [ 4019] = 0x6EB8, +- [ 4020] = 0x24A2A, [ 4021] = 0xEBFE, [ 4022] = 0x39A4, [ 4023] = 0x36B9, +- [ 4026] = 0x453F, [ 4027] = 0x66B6, [ 4028] = 0x29CAD, [ 4029] = 0x298A4, +- [ 4030] = 0x8943, [ 4031] = 0xEC08, [ 4032] = 0xEC09, [ 4033] = 0x56D6, +- [ 4034] = 0x40DF, [ 4035] = 0x2160A, [ 4036] = 0x39A1, [ 4037] = 0x2372F, +- [ 4038] = 0xEC0F, [ 4039] = 0x213C5, [ 4040] = 0x71AD, [ 4041] = 0x8366, +- [ 4042] = 0xEC13, [ 4043] = 0x291A8, [ 4045] = 0x4CB7, [ 4046] = 0x270AF, +- [ 4047] = 0x289AB, [ 4048] = 0xEC19, [ 4049] = 0xEC1A, [ 4050] = 0xEC1B, +- [ 4051] = 0xEC1C, [ 4052] = 0x2417A, [ 4053] = 0x7B43, [ 4054] = 0x797E, +- [ 4055] = 0x28009, [ 4056] = 0x6FB5, [ 4057] = 0x2A2DF, [ 4058] = 0x6A03, +- [ 4059] = 0xEC24, [ 4060] = 0x53A2, [ 4061] = 0xEC26, [ 4062] = 0x93BF, +- [ 4063] = 0x6836, [ 4064] = 0x975D, [ 4065] = 0x2816F, [ 4066] = 0xEC2B, +- [ 4067] = 0x269B5, [ 4068] = 0x213ED, [ 4069] = 0x2322F, [ 4070] = 0xEC2F, +- [ 4071] = 0x5D85, [ 4072] = 0x28C30, [ 4073] = 0xEC32, [ 4074] = 0x5715, +- [ 4075] = 0x9823, [ 4076] = 0x28949, [ 4077] = 0x5DAB, [ 4078] = 0x24988, +- [ 4079] = 0x65BE, [ 4080] = 0x69D5, [ 4081] = 0x53D2, [ 4082] = 0x24AA5, +- [ 4083] = 0x23F81, [ 4084] = 0x3C11, [ 4085] = 0x6736, [ 4086] = 0xEC3F, +- [ 4087] = 0x280F4, [ 4088] = 0x2812E, [ 4089] = 0x21FA1, [ 4090] = 0xEC43, +- [ 4095] = 0xEC44, [ 4096] = 0xEC45, [ 4097] = 0xEC46, [ 4098] = 0xEC47, +- [ 4099] = 0xEC48, [ 4100] = 0xEC49, [ 4101] = 0x35CA, [ 4102] = 0xEC4B, +- [ 4103] = 0x286AA, [ 4104] = 0x48FA, [ 4105] = 0x63E6, [ 4106] = 0xEC4F, +- [ 4107] = 0x7808, [ 4108] = 0x9255, [ 4109] = 0xEC52, [ 4110] = 0x43F2, +- [ 4111] = 0xEC54, [ 4112] = 0x43DF, [ 4113] = 0xEC56, [ 4114] = 0xEC57, +- [ 4115] = 0xEC58, [ 4116] = 0x59F8, [ 4117] = 0xEC5A, [ 4119] = 0xEC5C, +- [ 4120] = 0xEC5D, [ 4122] = 0x29110, [ 4123] = 0xEC60, [ 4124] = 0x3DF7, +- [ 4125] = 0xEC62, [ 4126] = 0xEC63, [ 4127] = 0x8FD0, [ 4128] = 0x728F, +- [ 4129] = 0x568B, [ 4130] = 0xEC67, [ 4131] = 0x295E9, [ 4132] = 0xEC69, +- [ 4133] = 0xEC6A, [ 4134] = 0xEC6B, [ 4135] = 0xEC6C, [ 4136] = 0xEC6D, +- [ 4137] = 0x2996A, [ 4138] = 0xEC6F, [ 4139] = 0xEC70, [ 4140] = 0x29B0E, +- [ 4141] = 0xEC72, [ 4142] = 0xEC73, [ 4143] = 0x7E9F, [ 4144] = 0xEC75, +- [ 4145] = 0x29F23, [ 4146] = 0x4CA4, [ 4147] = 0x9547, [ 4148] = 0xEC79, +- [ 4149] = 0x71A2, [ 4150] = 0xEC7B, [ 4151] = 0x4D91, [ 4152] = 0x9012, +- [ 4153] = 0xEC7E, [ 4154] = 0x4D9C, [ 4155] = 0x20C9C, [ 4156] = 0x8FBE, +- [ 4157] = 0x55C1, [ 4192] = 0x8FBA, [ 4193] = 0xEC84, [ 4194] = 0x8FB9, +- [ 4195] = 0x24A93, [ 4196] = 0x4509, [ 4197] = 0x7E7F, [ 4198] = 0x6F56, +- [ 4199] = 0x6AB1, [ 4200] = 0x4EEA, [ 4201] = 0x34E4, [ 4202] = 0x28B2C, +- [ 4203] = 0xEC8E, [ 4204] = 0x373A, [ 4205] = 0x8E80, [ 4206] = 0x217F5, +- [ 4207] = 0xEC92, [ 4208] = 0x28B6C, [ 4209] = 0x28B99, [ 4210] = 0xEC95, +- [ 4211] = 0x266AF, [ 4212] = 0x3DEB, [ 4213] = 0x27655, [ 4214] = 0x23CB7, +- [ 4215] = 0x25635, [ 4216] = 0x25956, [ 4217] = 0x4E9A, [ 4218] = 0x25E81, +- [ 4219] = 0x26258, [ 4220] = 0x56BF, [ 4221] = 0x20E6D, [ 4222] = 0x8E0E, +- [ 4223] = 0x5B6D, [ 4224] = 0x23E88, [ 4225] = 0x24C9E, [ 4226] = 0x63DE, +- [ 4228] = 0x217F6, [ 4229] = 0x2187B, [ 4230] = 0x6530, [ 4231] = 0x562D, +- [ 4232] = 0x25C4A, [ 4233] = 0x541A, [ 4234] = 0x25311, [ 4235] = 0x3DC6, +- [ 4236] = 0xECAF, [ 4237] = 0x4C7D, [ 4238] = 0x5622, [ 4239] = 0x561E, +- [ 4240] = 0x7F49, [ 4241] = 0x25ED8, [ 4242] = 0x5975, [ 4243] = 0xECB6, +- [ 4244] = 0x8770, [ 4245] = 0x4E1C, [ 4246] = 0x20FEA, [ 4247] = 0x20D49, +- [ 4248] = 0x236BA, [ 4249] = 0x8117, [ 4250] = 0x9D5E, [ 4251] = 0x8D18, +- [ 4252] = 0x763B, [ 4253] = 0x9C45, [ 4254] = 0x764E, [ 4255] = 0x77B9, +- [ 4256] = 0x9345, [ 4257] = 0x5432, [ 4258] = 0x8148, [ 4259] = 0x82F7, +- [ 4260] = 0x5625, [ 4261] = 0x8132, [ 4262] = 0x8418, [ 4263] = 0x80BD, +- [ 4264] = 0x55EA, [ 4265] = 0x7962, [ 4266] = 0x5643, [ 4267] = 0x5416, +- [ 4268] = 0xECCF, [ 4269] = 0x35CE, [ 4270] = 0x5605, [ 4271] = 0x55F1, +- [ 4272] = 0x66F1, [ 4273] = 0x282E2, [ 4274] = 0x362D, [ 4275] = 0x7534, +- [ 4276] = 0x55F0, [ 4277] = 0x55BA, [ 4278] = 0x5497, [ 4279] = 0x5572, +- [ 4280] = 0x20C41, [ 4281] = 0xECDC, [ 4282] = 0x5ED0, [ 4283] = 0x25148, +- [ 4284] = 0x20E76, [ 4285] = 0xECE0, [ 4290] = 0xECE1, [ 4291] = 0x9EAB, +- [ 4292] = 0x7D5A, [ 4293] = 0x55DE, [ 4294] = 0x21075, [ 4295] = 0x629D, +- [ 4296] = 0x976D, [ 4297] = 0x5494, [ 4298] = 0x8CCD, [ 4299] = 0x71F6, +- [ 4300] = 0x9176, [ 4301] = 0x63FC, [ 4302] = 0x63B9, [ 4303] = 0x63FE, +- [ 4304] = 0x5569, [ 4305] = 0xECF0, [ 4306] = 0x9C72, [ 4307] = 0xECF2, +- [ 4308] = 0x519A, [ 4309] = 0x34DF, [ 4310] = 0x20DA7, [ 4311] = 0x51A7, +- [ 4312] = 0x544D, [ 4313] = 0x551E, [ 4314] = 0x5513, [ 4315] = 0x7666, +- [ 4316] = 0x8E2D, [ 4317] = 0xECFC, [ 4318] = 0x75B1, [ 4319] = 0x80B6, +- [ 4320] = 0x8804, [ 4321] = 0x8786, [ 4322] = 0x88C7, [ 4323] = 0x81B6, +- [ 4324] = 0x841C, [ 4325] = 0x210C1, [ 4326] = 0x44EC, [ 4327] = 0x7304, +- [ 4328] = 0x24706, [ 4329] = 0x5B90, [ 4330] = 0x830B, [ 4331] = 0x26893, +- [ 4332] = 0x567B, [ 4333] = 0x226F4, [ 4334] = 0x27D2F, [ 4335] = 0x241A3, +- [ 4336] = 0x27D73, [ 4337] = 0x26ED0, [ 4338] = 0xED11, [ 4339] = 0x9170, +- [ 4340] = 0x211D9, [ 4341] = 0x9208, [ 4342] = 0x23CFC, [ 4343] = 0x2A6A9, +- [ 4344] = 0x20EAC, [ 4345] = 0x20EF9, [ 4346] = 0x7266, [ 4347] = 0x21CA2, +- [ 4348] = 0x474E, [ 4349] = 0x24FC2, [ 4350] = 0xED1D, [ 4351] = 0x20FEB, +- [ 4352] = 0x40FA, [ 4387] = 0x9C5D, [ 4388] = 0x651F, [ 4389] = 0x22DA0, +- [ 4390] = 0x48F3, [ 4391] = 0xED24, [ 4392] = 0x29D7C, [ 4393] = 0x20FEC, +- [ 4394] = 0x20E0A, [ 4396] = 0xED29, [ 4397] = 0x20FED, [ 4399] = 0xED2C, +- [ 4400] = 0x21187, [ 4401] = 0x71A3, [ 4402] = 0x7E8E, [ 4403] = 0x9D50, +- [ 4404] = 0x4E1A, [ 4405] = 0x4E04, [ 4406] = 0x3577, [ 4407] = 0x5B0D, +- [ 4408] = 0x6CB2, [ 4409] = 0x5367, [ 4410] = 0x36AC, [ 4411] = 0x39DC, +- [ 4412] = 0x537D, [ 4413] = 0x36A5, [ 4414] = 0xED3B, [ 4415] = 0x589A, +- [ 4416] = 0x24B6E, [ 4417] = 0x822D, [ 4418] = 0x544B, [ 4419] = 0x57AA, +- [ 4420] = 0xED41, [ 4421] = 0x20979, [ 4423] = 0x3A52, [ 4424] = 0x22465, +- [ 4425] = 0x7374, [ 4426] = 0x29EAC, [ 4427] = 0x4D09, [ 4428] = 0x9BED, +- [ 4429] = 0x23CFE, [ 4430] = 0x29F30, [ 4431] = 0x4C5B, [ 4432] = 0x24FA9, +- [ 4433] = 0x2959E, [ 4434] = 0xED4F, [ 4435] = 0x845C, [ 4436] = 0x23DB6, +- [ 4437] = 0xED52, [ 4438] = 0x267B3, [ 4439] = 0x23720, [ 4440] = 0x632E, +- [ 4441] = 0x7D25, [ 4442] = 0x23EF7, [ 4443] = 0x23E2C, [ 4444] = 0x3A2A, +- [ 4445] = 0x9008, [ 4446] = 0x52CC, [ 4447] = 0x3E74, [ 4448] = 0x367A, +- [ 4449] = 0x45E9, [ 4450] = 0xED5F, [ 4451] = 0x7640, [ 4452] = 0x5AF0, +- [ 4453] = 0x20EB6, [ 4454] = 0x787A, [ 4455] = 0x47B6, [ 4456] = 0x58A7, +- [ 4457] = 0x40BF, [ 4458] = 0x567C, [ 4459] = 0x9B8B, [ 4460] = 0x5D74, +- [ 4461] = 0x7654, [ 4462] = 0xED6B, [ 4463] = 0x9E85, [ 4464] = 0x4CE1, +- [ 4466] = 0x37FB, [ 4467] = 0x6119, [ 4468] = 0x230DA, [ 4469] = 0x243F2, +- [ 4471] = 0x565D, [ 4472] = 0x212A9, [ 4473] = 0x57A7, [ 4474] = 0x24963, +- [ 4475] = 0xED78, [ 4476] = 0x5234, [ 4477] = 0x270AE, [ 4478] = 0x35AD, +- [ 4480] = 0x9D7C, [ 4485] = 0x7C56, [ 4486] = 0x9B39, [ 4487] = 0x57DE, +- [ 4488] = 0x2176C, [ 4489] = 0x5C53, [ 4490] = 0x64D3, [ 4491] = 0xED84, +- [ 4492] = 0xED85, [ 4493] = 0x27164, [ 4494] = 0x86AD, [ 4495] = 0xED88, +- [ 4496] = 0x26D22, [ 4497] = 0x24AE2, [ 4498] = 0xED8B, [ 4500] = 0x51FE, +- [ 4501] = 0xED8E, [ 4502] = 0x5D8E, [ 4503] = 0x9703, [ 4504] = 0x21DD1, +- [ 4505] = 0x9E81, [ 4506] = 0x904C, [ 4507] = 0x7B1F, [ 4508] = 0x9B02, +- [ 4509] = 0x5CD1, [ 4510] = 0x7BA3, [ 4511] = 0x6268, [ 4512] = 0x6335, +- [ 4513] = 0x9AFF, [ 4514] = 0x7BCF, [ 4515] = 0x9B2A, [ 4516] = 0x7C7E, +- [ 4518] = 0x7C42, [ 4519] = 0x7C86, [ 4520] = 0x9C15, [ 4521] = 0x7BFC, +- [ 4522] = 0x9B09, [ 4524] = 0x9C1B, [ 4525] = 0x2493E, [ 4526] = 0x9F5A, +- [ 4527] = 0x5573, [ 4528] = 0x5BC3, [ 4529] = 0x4FFD, [ 4530] = 0x9E98, +- [ 4531] = 0x4FF2, [ 4532] = 0x5260, [ 4533] = 0x3E06, [ 4534] = 0x52D1, +- [ 4535] = 0x5767, [ 4536] = 0x5056, [ 4537] = 0x59B7, [ 4538] = 0x5E12, +- [ 4539] = 0x97C8, [ 4540] = 0x9DAB, [ 4541] = 0x8F5C, [ 4542] = 0x5469, +- [ 4543] = 0x97B4, [ 4544] = 0x9940, [ 4545] = 0x97BA, [ 4546] = 0x532C, +- [ 4547] = 0x6130, [ 4582] = 0x692C, [ 4583] = 0x53DA, [ 4584] = 0x9C0A, +- [ 4585] = 0x9D02, [ 4586] = 0x4C3B, [ 4587] = 0x9641, [ 4588] = 0x6980, +- [ 4589] = 0x50A6, [ 4590] = 0x7546, [ 4591] = 0x2176D, [ 4592] = 0x99DA, +- [ 4593] = 0x5273, [ 4595] = 0x9159, [ 4596] = 0x9681, [ 4597] = 0x915C, +- [ 4599] = 0x9151, [ 4600] = 0xEDCF, [ 4601] = 0x637F, [ 4602] = 0x26D23, +- [ 4603] = 0x6ACA, [ 4604] = 0x5611, [ 4605] = 0x918E, [ 4606] = 0x757A, +- [ 4607] = 0x6285, [ 4608] = 0x203FC, [ 4609] = 0x734F, [ 4610] = 0x7C70, +- [ 4611] = 0xEDDA, [ 4612] = 0x23CFD, [ 4614] = 0x24919, [ 4615] = 0x76D6, +- [ 4616] = 0x9B9D, [ 4617] = 0x4E2A, [ 4618] = 0x20CD4, [ 4619] = 0x83BE, +- [ 4620] = 0x8842, [ 4622] = 0x5C4A, [ 4623] = 0x69C0, [ 4625] = 0x577A, +- [ 4626] = 0x521F, [ 4627] = 0x5DF5, [ 4628] = 0x4ECE, [ 4629] = 0x6C31, +- [ 4630] = 0xEDED, [ 4631] = 0x4F39, [ 4632] = 0x549C, [ 4633] = 0x54DA, +- [ 4634] = 0x529A, [ 4635] = 0x8D82, [ 4636] = 0x35FE, [ 4638] = 0x35F3, +- [ 4640] = 0x6B52, [ 4641] = 0x917C, [ 4642] = 0x9FA5, [ 4643] = 0x9B97, +- [ 4644] = 0x982E, [ 4645] = 0x98B4, [ 4646] = 0x9ABA, [ 4647] = 0x9EA8, +- [ 4648] = 0x9E84, [ 4649] = 0x717A, [ 4650] = 0x7B14, [ 4652] = 0x6BFA, +- [ 4653] = 0x8818, [ 4654] = 0x7F78, [ 4656] = 0x5620, [ 4657] = 0xEE08, +- [ 4658] = 0x8E77, [ 4659] = 0x9F53, [ 4661] = 0x8DD4, [ 4662] = 0x8E4F, +- [ 4663] = 0x9E1C, [ 4664] = 0x8E01, [ 4665] = 0x6282, [ 4666] = 0x2837D, +- [ 4667] = 0x8E28, [ 4668] = 0x8E75, [ 4669] = 0x7AD3, [ 4670] = 0x24A77, +- [ 4671] = 0x7A3E, [ 4672] = 0x78D8, [ 4673] = 0x6CEA, [ 4674] = 0x8A67, +- [ 4675] = 0x7607, [ 4680] = 0x28A5A, [ 4681] = 0x9F26, [ 4682] = 0x6CCE, +- [ 4683] = 0x87D6, [ 4684] = 0x75C3, [ 4685] = 0x2A2B2, [ 4686] = 0x7853, +- [ 4687] = 0x2F840, [ 4688] = 0x8D0C, [ 4689] = 0x72E2, [ 4690] = 0x7371, +- [ 4691] = 0x8B2D, [ 4692] = 0x7302, [ 4693] = 0x74F1, [ 4694] = 0x8CEB, +- [ 4695] = 0x24ABB, [ 4696] = 0x862F, [ 4697] = 0x5FBA, [ 4698] = 0x88A0, +- [ 4699] = 0x44B7, [ 4701] = 0x2183B, [ 4702] = 0x26E05, [ 4704] = 0x8A7E, +- [ 4705] = 0x2251B, [ 4707] = 0x60FD, [ 4708] = 0x7667, [ 4709] = 0x9AD7, +- [ 4710] = 0x9D44, [ 4711] = 0x936E, [ 4712] = 0x9B8F, [ 4713] = 0x87F5, +- [ 4716] = 0x8CF7, [ 4717] = 0x732C, [ 4718] = 0x9721, [ 4719] = 0x9BB0, +- [ 4720] = 0x35D6, [ 4721] = 0x72B2, [ 4722] = 0x4C07, [ 4723] = 0x7C51, +- [ 4724] = 0x994A, [ 4725] = 0x26159, [ 4726] = 0x6159, [ 4727] = 0x4C04, +- [ 4728] = 0x9E96, [ 4729] = 0x617D, [ 4731] = 0x575F, [ 4732] = 0x616F, +- [ 4733] = 0x62A6, [ 4734] = 0x6239, [ 4736] = 0x3A5C, [ 4737] = 0x61E2, +- [ 4738] = 0x53AA, [ 4739] = 0x233F5, [ 4740] = 0x6364, [ 4741] = 0x6802, +- [ 4742] = 0x35D2, [ 4777] = 0x5D57, [ 4778] = 0x28BC2, [ 4779] = 0x8FDA, +- [ 4780] = 0xEE5D, [ 4782] = 0x50D9, [ 4783] = 0x21D46, [ 4784] = 0x7906, +- [ 4785] = 0x5332, [ 4786] = 0x9638, [ 4787] = 0x20F3B, [ 4788] = 0x4065, +- [ 4790] = 0x77FE, [ 4792] = 0x7CC2, [ 4793] = 0xEE6A, [ 4794] = 0x7CDA, +- [ 4795] = 0x7A2D, [ 4796] = 0x8066, [ 4797] = 0x8063, [ 4798] = 0x7D4D, +- [ 4799] = 0x7505, [ 4800] = 0x74F2, [ 4801] = 0x8994, [ 4802] = 0x821A, +- [ 4803] = 0x670C, [ 4804] = 0x8062, [ 4805] = 0x27486, [ 4806] = 0x805B, +- [ 4807] = 0x74F0, [ 4808] = 0x8103, [ 4809] = 0x7724, [ 4810] = 0x8989, +- [ 4811] = 0x267CC, [ 4812] = 0x7553, [ 4813] = 0x26ED1, [ 4814] = 0x87A9, +- [ 4815] = 0x87CE, [ 4816] = 0x81C8, [ 4817] = 0x878C, [ 4818] = 0x8A49, +- [ 4819] = 0x8CAD, [ 4820] = 0x8B43, [ 4821] = 0x772B, [ 4822] = 0x74F8, +- [ 4823] = 0x84DA, [ 4824] = 0x3635, [ 4825] = 0x69B2, [ 4826] = 0x8DA6, +- [ 4828] = 0x89A9, [ 4830] = 0x6DB9, [ 4831] = 0x87C1, [ 4832] = 0x24011, +- [ 4833] = 0x74E7, [ 4834] = 0x3DDB, [ 4835] = 0x7176, [ 4836] = 0x60A4, +- [ 4837] = 0x619C, [ 4838] = 0x3CD1, [ 4840] = 0x6077, [ 4842] = 0x7F71, +- [ 4843] = 0x28B2D, [ 4845] = 0x60E9, [ 4846] = 0x4B7E, [ 4847] = 0x5220, +- [ 4848] = 0x3C18, [ 4849] = 0x23CC7, [ 4850] = 0x25ED7, [ 4851] = 0x27656, +- [ 4852] = 0xEEA5, [ 4853] = 0x21944, [ 4854] = 0x212FE, [ 4855] = 0x29903, +- [ 4856] = 0x26DDC, [ 4857] = 0x270AD, [ 4858] = 0x5CC1, [ 4859] = 0x261AD, +- [ 4860] = 0x28A0F, [ 4861] = 0x23677, [ 4862] = 0x200EE, [ 4863] = 0xEEB0, +- [ 4864] = 0x24F0E, [ 4865] = 0x4562, [ 4866] = 0x5B1F, [ 4867] = 0xEEB4, +- [ 4868] = 0x9F50, [ 4869] = 0x9EA6, [ 4870] = 0xEEB7, [ 4875] = 0x3000, +- [ 4876] = 0xFF0C, [ 4877] = 0x3001, [ 4878] = 0x3002, [ 4879] = 0xFF0E, +- [ 4880] = 0x2022, [ 4881] = 0xFF1B, [ 4882] = 0xFF1A, [ 4883] = 0xFF1F, +- [ 4884] = 0xFF01, [ 4885] = 0xFE30, [ 4886] = 0x2026, [ 4887] = 0x2025, +- [ 4888] = 0xFE50, [ 4889] = 0xFF64, [ 4890] = 0xFE52, [ 4891] = 0x00B7, +- [ 4892] = 0xFE54, [ 4893] = 0xFE55, [ 4894] = 0xFE56, [ 4895] = 0xFE57, +- [ 4896] = 0xFF5C, [ 4897] = 0x2013, [ 4898] = 0xFE31, [ 4899] = 0x2014, +- [ 4900] = 0xFE33, [ 4902] = 0xFE34, [ 4903] = 0xFE4F, [ 4904] = 0xFF08, +- [ 4905] = 0xFF09, [ 4906] = 0xFE35, [ 4907] = 0xFE36, [ 4908] = 0xFF5B, +- [ 4909] = 0xFF5D, [ 4910] = 0xFE37, [ 4911] = 0xFE38, [ 4912] = 0x3014, +- [ 4913] = 0x3015, [ 4914] = 0xFE39, [ 4915] = 0xFE3A, [ 4916] = 0x3010, +- [ 4917] = 0x3011, [ 4918] = 0xFE3B, [ 4919] = 0xFE3C, [ 4920] = 0x300A, +- [ 4921] = 0x300B, [ 4922] = 0xFE3D, [ 4923] = 0xFE3E, [ 4924] = 0x3008, +- [ 4925] = 0x3009, [ 4926] = 0xFE3F, [ 4927] = 0xFE40, [ 4928] = 0x300C, +- [ 4929] = 0x300D, [ 4930] = 0xFE41, [ 4931] = 0xFE42, [ 4932] = 0x300E, +- [ 4933] = 0x300F, [ 4934] = 0xFE43, [ 4935] = 0xFE44, [ 4936] = 0xFE59, +- [ 4937] = 0xFE5A, [ 4972] = 0xFE5B, [ 4973] = 0xFE5C, [ 4974] = 0xFE5D, +- [ 4975] = 0xFE5E, [ 4976] = 0x2018, [ 4977] = 0x2019, [ 4978] = 0x201C, +- [ 4979] = 0x201D, [ 4980] = 0x301D, [ 4981] = 0x301E, [ 4982] = 0x2035, +- [ 4983] = 0x2032, [ 4984] = 0xFF03, [ 4985] = 0xFF06, [ 4986] = 0xFF0A, +- [ 4987] = 0x203B, [ 4988] = 0x00A7, [ 4989] = 0x3003, [ 4990] = 0x25CB, +- [ 4991] = 0x25CF, [ 4992] = 0x25B3, [ 4993] = 0x25B2, [ 4994] = 0x25CE, +- [ 4995] = 0x2606, [ 4996] = 0x2605, [ 4997] = 0x25C7, [ 4998] = 0x25C6, +- [ 4999] = 0x25A1, [ 5000] = 0x25A0, [ 5001] = 0x25BD, [ 5002] = 0x25BC, +- [ 5003] = 0x32A3, [ 5004] = 0x2105, [ 5005] = 0x203E, [ 5007] = 0xFF3F, +- [ 5009] = 0xFE49, [ 5010] = 0xFE4A, [ 5011] = 0xFE4D, [ 5012] = 0xFE4E, +- [ 5013] = 0xFE4B, [ 5014] = 0xFE4C, [ 5015] = 0xFE5F, [ 5016] = 0xFE60, +- [ 5017] = 0xFE61, [ 5018] = 0xFF0B, [ 5019] = 0xFF0D, [ 5020] = 0x00D7, +- [ 5021] = 0x00F7, [ 5022] = 0x00B1, [ 5023] = 0x221A, [ 5024] = 0xFF1C, +- [ 5025] = 0xFF1E, [ 5026] = 0xFF1D, [ 5027] = 0x2266, [ 5028] = 0x2267, +- [ 5029] = 0x2260, [ 5030] = 0x221E, [ 5031] = 0x2252, [ 5032] = 0x2261, +- [ 5033] = 0xFE62, [ 5034] = 0xFE63, [ 5035] = 0xFE64, [ 5036] = 0xFE65, +- [ 5037] = 0xFE66, [ 5038] = 0x223C, [ 5039] = 0x2229, [ 5040] = 0x222A, +- [ 5041] = 0x22A5, [ 5042] = 0x2220, [ 5043] = 0x221F, [ 5044] = 0x22BF, +- [ 5045] = 0x33D2, [ 5046] = 0x33D1, [ 5047] = 0x222B, [ 5048] = 0x222E, +- [ 5049] = 0x2235, [ 5050] = 0x2234, [ 5051] = 0x2640, [ 5052] = 0x2642, +- [ 5053] = 0x2641, [ 5054] = 0x2609, [ 5055] = 0x2191, [ 5056] = 0x2193, +- [ 5057] = 0x2190, [ 5058] = 0x2192, [ 5059] = 0x2196, [ 5060] = 0x2197, +- [ 5061] = 0x2199, [ 5062] = 0x2198, [ 5063] = 0x2225, [ 5064] = 0x2223, +- [ 5071] = 0xFF0F, [ 5072] = 0xFF3C, [ 5073] = 0xFF04, [ 5074] = 0x00A5, +- [ 5075] = 0x3012, [ 5076] = 0x00A2, [ 5077] = 0x00A3, [ 5078] = 0xFF05, +- [ 5079] = 0xFF20, [ 5080] = 0x2103, [ 5081] = 0x2109, [ 5082] = 0xFE69, +- [ 5083] = 0xFE6A, [ 5084] = 0xFE6B, [ 5085] = 0x33D5, [ 5086] = 0x339C, +- [ 5087] = 0x339D, [ 5088] = 0x339E, [ 5089] = 0x33CE, [ 5090] = 0x33A1, +- [ 5091] = 0x338E, [ 5092] = 0x338F, [ 5093] = 0x33C4, [ 5094] = 0x00B0, +- [ 5095] = 0x5159, [ 5096] = 0x515B, [ 5097] = 0x515E, [ 5098] = 0x515D, +- [ 5099] = 0x5161, [ 5100] = 0x5163, [ 5101] = 0x55E7, [ 5102] = 0x74E9, +- [ 5103] = 0x7CCE, [ 5104] = 0x2581, [ 5105] = 0x2582, [ 5106] = 0x2583, +- [ 5107] = 0x2584, [ 5108] = 0x2585, [ 5109] = 0x2586, [ 5110] = 0x2587, +- [ 5111] = 0x2588, [ 5112] = 0x258F, [ 5113] = 0x258E, [ 5114] = 0x258D, +- [ 5115] = 0x258C, [ 5116] = 0x258B, [ 5117] = 0x258A, [ 5118] = 0x2589, +- [ 5119] = 0x253C, [ 5120] = 0x2534, [ 5121] = 0x252C, [ 5122] = 0x2524, +- [ 5123] = 0x251C, [ 5124] = 0x2594, [ 5125] = 0x2500, [ 5126] = 0x2502, +- [ 5127] = 0x2595, [ 5128] = 0x250C, [ 5129] = 0x2510, [ 5130] = 0x2514, +- [ 5131] = 0x2518, [ 5132] = 0x256D, [ 5167] = 0x256E, [ 5168] = 0x2570, +- [ 5169] = 0x256F, [ 5170] = 0x2550, [ 5171] = 0x255E, [ 5172] = 0x256A, +- [ 5173] = 0x2561, [ 5174] = 0x25E2, [ 5175] = 0x25E3, [ 5176] = 0x25E5, +- [ 5177] = 0x25E4, [ 5178] = 0x2571, [ 5179] = 0x2572, [ 5180] = 0x2573, +- [ 5181] = 0xFF10, [ 5182] = 0xFF11, [ 5183] = 0xFF12, [ 5184] = 0xFF13, +- [ 5185] = 0xFF14, [ 5186] = 0xFF15, [ 5187] = 0xFF16, [ 5188] = 0xFF17, +- [ 5189] = 0xFF18, [ 5190] = 0xFF19, [ 5191] = 0x2160, [ 5192] = 0x2161, +- [ 5193] = 0x2162, [ 5194] = 0x2163, [ 5195] = 0x2164, [ 5196] = 0x2165, +- [ 5197] = 0x2166, [ 5198] = 0x2167, [ 5199] = 0x2168, [ 5200] = 0x2169, +- [ 5201] = 0x3021, [ 5202] = 0x3022, [ 5203] = 0x3023, [ 5204] = 0x3024, +- [ 5205] = 0x3025, [ 5206] = 0x3026, [ 5207] = 0x3027, [ 5208] = 0x3028, +- [ 5209] = 0x3029, [ 5211] = 0x5344, [ 5213] = 0xFF21, [ 5214] = 0xFF22, +- [ 5215] = 0xFF23, [ 5216] = 0xFF24, [ 5217] = 0xFF25, [ 5218] = 0xFF26, +- [ 5219] = 0xFF27, [ 5220] = 0xFF28, [ 5221] = 0xFF29, [ 5222] = 0xFF2A, +- [ 5223] = 0xFF2B, [ 5224] = 0xFF2C, [ 5225] = 0xFF2D, [ 5226] = 0xFF2E, +- [ 5227] = 0xFF2F, [ 5228] = 0xFF30, [ 5229] = 0xFF31, [ 5230] = 0xFF32, +- [ 5231] = 0xFF33, [ 5232] = 0xFF34, [ 5233] = 0xFF35, [ 5234] = 0xFF36, +- [ 5235] = 0xFF37, [ 5236] = 0xFF38, [ 5237] = 0xFF39, [ 5238] = 0xFF3A, +- [ 5239] = 0xFF41, [ 5240] = 0xFF42, [ 5241] = 0xFF43, [ 5242] = 0xFF44, +- [ 5243] = 0xFF45, [ 5244] = 0xFF46, [ 5245] = 0xFF47, [ 5246] = 0xFF48, +- [ 5247] = 0xFF49, [ 5248] = 0xFF4A, [ 5249] = 0xFF4B, [ 5250] = 0xFF4C, +- [ 5251] = 0xFF4D, [ 5252] = 0xFF4E, [ 5253] = 0xFF4F, [ 5254] = 0xFF50, +- [ 5255] = 0xFF51, [ 5256] = 0xFF52, [ 5257] = 0xFF53, [ 5258] = 0xFF54, +- [ 5259] = 0xFF55, [ 5260] = 0xFF56, [ 5265] = 0xFF57, [ 5266] = 0xFF58, +- [ 5267] = 0xFF59, [ 5268] = 0xFF5A, [ 5269] = 0x0391, [ 5270] = 0x0392, +- [ 5271] = 0x0393, [ 5272] = 0x0394, [ 5273] = 0x0395, [ 5274] = 0x0396, +- [ 5275] = 0x0397, [ 5276] = 0x0398, [ 5277] = 0x0399, [ 5278] = 0x039A, +- [ 5279] = 0x039B, [ 5280] = 0x039C, [ 5281] = 0x039D, [ 5282] = 0x039E, +- [ 5283] = 0x039F, [ 5284] = 0x03A0, [ 5285] = 0x03A1, [ 5286] = 0x03A3, +- [ 5287] = 0x03A4, [ 5288] = 0x03A5, [ 5289] = 0x03A6, [ 5290] = 0x03A7, +- [ 5291] = 0x03A8, [ 5292] = 0x03A9, [ 5293] = 0x03B1, [ 5294] = 0x03B2, +- [ 5295] = 0x03B3, [ 5296] = 0x03B4, [ 5297] = 0x03B5, [ 5298] = 0x03B6, +- [ 5299] = 0x03B7, [ 5300] = 0x03B8, [ 5301] = 0x03B9, [ 5302] = 0x03BA, +- [ 5303] = 0x03BB, [ 5304] = 0x03BC, [ 5305] = 0x03BD, [ 5306] = 0x03BE, +- [ 5307] = 0x03BF, [ 5308] = 0x03C0, [ 5309] = 0x03C1, [ 5310] = 0x03C3, +- [ 5311] = 0x03C4, [ 5312] = 0x03C5, [ 5313] = 0x03C6, [ 5314] = 0x03C7, +- [ 5315] = 0x03C8, [ 5316] = 0x03C9, [ 5317] = 0x3105, [ 5318] = 0x3106, +- [ 5319] = 0x3107, [ 5320] = 0x3108, [ 5321] = 0x3109, [ 5322] = 0x310A, +- [ 5323] = 0x310B, [ 5324] = 0x310C, [ 5325] = 0x310D, [ 5326] = 0x310E, +- [ 5327] = 0x310F, [ 5362] = 0x3110, [ 5363] = 0x3111, [ 5364] = 0x3112, +- [ 5365] = 0x3113, [ 5366] = 0x3114, [ 5367] = 0x3115, [ 5368] = 0x3116, +- [ 5369] = 0x3117, [ 5370] = 0x3118, [ 5371] = 0x3119, [ 5372] = 0x311A, +- [ 5373] = 0x311B, [ 5374] = 0x311C, [ 5375] = 0x311D, [ 5376] = 0x311E, +- [ 5377] = 0x311F, [ 5378] = 0x3120, [ 5379] = 0x3121, [ 5380] = 0x3122, +- [ 5381] = 0x3123, [ 5382] = 0x3124, [ 5383] = 0x3125, [ 5384] = 0x3126, +- [ 5385] = 0x3127, [ 5386] = 0x3128, [ 5387] = 0x3129, [ 5388] = 0x02D9, +- [ 5389] = 0x02C9, [ 5390] = 0x02CA, [ 5391] = 0x02C7, [ 5392] = 0x02CB, +- [ 5460] = 0x4E00, [ 5461] = 0x4E59, [ 5462] = 0x4E01, [ 5463] = 0x4E03, +- [ 5464] = 0x4E43, [ 5465] = 0x4E5D, [ 5466] = 0x4E86, [ 5467] = 0x4E8C, +- [ 5468] = 0x4EBA, [ 5469] = 0x513F, [ 5470] = 0x5165, [ 5471] = 0x516B, +- [ 5472] = 0x51E0, [ 5473] = 0x5200, [ 5474] = 0x5201, [ 5475] = 0x529B, +- [ 5476] = 0x5315, [ 5477] = 0x5341, [ 5478] = 0x535C, [ 5479] = 0x53C8, +- [ 5480] = 0x4E09, [ 5481] = 0x4E0B, [ 5482] = 0x4E08, [ 5483] = 0x4E0A, +- [ 5484] = 0x4E2B, [ 5485] = 0x4E38, [ 5486] = 0x51E1, [ 5487] = 0x4E45, +- [ 5488] = 0x4E48, [ 5489] = 0x4E5F, [ 5490] = 0x4E5E, [ 5491] = 0x4E8E, +- [ 5492] = 0x4EA1, [ 5493] = 0x5140, [ 5494] = 0x5203, [ 5495] = 0x52FA, +- [ 5496] = 0x5343, [ 5497] = 0x53C9, [ 5498] = 0x53E3, [ 5499] = 0x571F, +- [ 5500] = 0x58EB, [ 5501] = 0x5915, [ 5502] = 0x5927, [ 5503] = 0x5973, +- [ 5504] = 0x5B50, [ 5505] = 0x5B51, [ 5506] = 0x5B53, [ 5507] = 0x5BF8, +- [ 5508] = 0x5C0F, [ 5509] = 0x5C22, [ 5510] = 0x5C38, [ 5511] = 0x5C71, +- [ 5512] = 0x5DDD, [ 5513] = 0x5DE5, [ 5514] = 0x5DF1, [ 5515] = 0x5DF2, +- [ 5516] = 0x5DF3, [ 5517] = 0x5DFE, [ 5518] = 0x5E72, [ 5519] = 0x5EFE, +- [ 5520] = 0x5F0B, [ 5521] = 0x5F13, [ 5522] = 0x624D, [ 5557] = 0x4E11, +- [ 5558] = 0x4E10, [ 5559] = 0x4E0D, [ 5560] = 0x4E2D, [ 5561] = 0x4E30, +- [ 5562] = 0x4E39, [ 5563] = 0x4E4B, [ 5564] = 0x5C39, [ 5565] = 0x4E88, +- [ 5566] = 0x4E91, [ 5567] = 0x4E95, [ 5568] = 0x4E92, [ 5569] = 0x4E94, +- [ 5570] = 0x4EA2, [ 5571] = 0x4EC1, [ 5572] = 0x4EC0, [ 5573] = 0x4EC3, +- [ 5574] = 0x4EC6, [ 5575] = 0x4EC7, [ 5576] = 0x4ECD, [ 5577] = 0x4ECA, +- [ 5578] = 0x4ECB, [ 5579] = 0x4EC4, [ 5580] = 0x5143, [ 5581] = 0x5141, +- [ 5582] = 0x5167, [ 5583] = 0x516D, [ 5584] = 0x516E, [ 5585] = 0x516C, +- [ 5586] = 0x5197, [ 5587] = 0x51F6, [ 5588] = 0x5206, [ 5589] = 0x5207, +- [ 5590] = 0x5208, [ 5591] = 0x52FB, [ 5592] = 0x52FE, [ 5593] = 0x52FF, +- [ 5594] = 0x5316, [ 5595] = 0x5339, [ 5596] = 0x5348, [ 5597] = 0x5347, +- [ 5598] = 0x5345, [ 5599] = 0x535E, [ 5600] = 0x5384, [ 5601] = 0x53CB, +- [ 5602] = 0x53CA, [ 5603] = 0x53CD, [ 5604] = 0x58EC, [ 5605] = 0x5929, +- [ 5606] = 0x592B, [ 5607] = 0x592A, [ 5608] = 0x592D, [ 5609] = 0x5B54, +- [ 5610] = 0x5C11, [ 5611] = 0x5C24, [ 5612] = 0x5C3A, [ 5613] = 0x5C6F, +- [ 5614] = 0x5DF4, [ 5615] = 0x5E7B, [ 5616] = 0x5EFF, [ 5617] = 0x5F14, +- [ 5618] = 0x5F15, [ 5619] = 0x5FC3, [ 5620] = 0x6208, [ 5621] = 0x6236, +- [ 5622] = 0x624B, [ 5623] = 0x624E, [ 5624] = 0x652F, [ 5625] = 0x6587, +- [ 5626] = 0x6597, [ 5627] = 0x65A4, [ 5628] = 0x65B9, [ 5629] = 0x65E5, +- [ 5630] = 0x66F0, [ 5631] = 0x6708, [ 5632] = 0x6728, [ 5633] = 0x6B20, +- [ 5634] = 0x6B62, [ 5635] = 0x6B79, [ 5636] = 0x6BCB, [ 5637] = 0x6BD4, +- [ 5638] = 0x6BDB, [ 5639] = 0x6C0F, [ 5640] = 0x6C34, [ 5641] = 0x706B, +- [ 5642] = 0x722A, [ 5643] = 0x7236, [ 5644] = 0x723B, [ 5645] = 0x7247, +- [ 5646] = 0x7259, [ 5647] = 0x725B, [ 5648] = 0x72AC, [ 5649] = 0x738B, +- [ 5650] = 0x4E19, [ 5655] = 0x4E16, [ 5656] = 0x4E15, [ 5657] = 0x4E14, +- [ 5658] = 0x4E18, [ 5659] = 0x4E3B, [ 5660] = 0x4E4D, [ 5661] = 0x4E4F, +- [ 5662] = 0x4E4E, [ 5663] = 0x4EE5, [ 5664] = 0x4ED8, [ 5665] = 0x4ED4, +- [ 5666] = 0x4ED5, [ 5667] = 0x4ED6, [ 5668] = 0x4ED7, [ 5669] = 0x4EE3, +- [ 5670] = 0x4EE4, [ 5671] = 0x4ED9, [ 5672] = 0x4EDE, [ 5673] = 0x5145, +- [ 5674] = 0x5144, [ 5675] = 0x5189, [ 5676] = 0x518A, [ 5677] = 0x51AC, +- [ 5678] = 0x51F9, [ 5679] = 0x51FA, [ 5680] = 0x51F8, [ 5681] = 0x520A, +- [ 5682] = 0x52A0, [ 5683] = 0x529F, [ 5684] = 0x5305, [ 5685] = 0x5306, +- [ 5686] = 0x5317, [ 5687] = 0x531D, [ 5688] = 0x4EDF, [ 5689] = 0x534A, +- [ 5690] = 0x5349, [ 5691] = 0x5361, [ 5692] = 0x5360, [ 5693] = 0x536F, +- [ 5694] = 0x536E, [ 5695] = 0x53BB, [ 5696] = 0x53EF, [ 5697] = 0x53E4, +- [ 5698] = 0x53F3, [ 5699] = 0x53EC, [ 5700] = 0x53EE, [ 5701] = 0x53E9, +- [ 5702] = 0x53E8, [ 5703] = 0x53FC, [ 5704] = 0x53F8, [ 5705] = 0x53F5, +- [ 5706] = 0x53EB, [ 5707] = 0x53E6, [ 5708] = 0x53EA, [ 5709] = 0x53F2, +- [ 5710] = 0x53F1, [ 5711] = 0x53F0, [ 5712] = 0x53E5, [ 5713] = 0x53ED, +- [ 5714] = 0x53FB, [ 5715] = 0x56DB, [ 5716] = 0x56DA, [ 5717] = 0x5916, +- [ 5752] = 0x592E, [ 5753] = 0x5931, [ 5754] = 0x5974, [ 5755] = 0x5976, +- [ 5756] = 0x5B55, [ 5757] = 0x5B83, [ 5758] = 0x5C3C, [ 5759] = 0x5DE8, +- [ 5760] = 0x5DE7, [ 5761] = 0x5DE6, [ 5762] = 0x5E02, [ 5763] = 0x5E03, +- [ 5764] = 0x5E73, [ 5765] = 0x5E7C, [ 5766] = 0x5F01, [ 5767] = 0x5F18, +- [ 5768] = 0x5F17, [ 5769] = 0x5FC5, [ 5770] = 0x620A, [ 5771] = 0x6253, +- [ 5772] = 0x6254, [ 5773] = 0x6252, [ 5774] = 0x6251, [ 5775] = 0x65A5, +- [ 5776] = 0x65E6, [ 5777] = 0x672E, [ 5778] = 0x672C, [ 5779] = 0x672A, +- [ 5780] = 0x672B, [ 5781] = 0x672D, [ 5782] = 0x6B63, [ 5783] = 0x6BCD, +- [ 5784] = 0x6C11, [ 5785] = 0x6C10, [ 5786] = 0x6C38, [ 5787] = 0x6C41, +- [ 5788] = 0x6C40, [ 5789] = 0x6C3E, [ 5790] = 0x72AF, [ 5791] = 0x7384, +- [ 5792] = 0x7389, [ 5793] = 0x74DC, [ 5794] = 0x74E6, [ 5795] = 0x7518, +- [ 5796] = 0x751F, [ 5797] = 0x7528, [ 5798] = 0x7529, [ 5799] = 0x7530, +- [ 5800] = 0x7531, [ 5801] = 0x7532, [ 5802] = 0x7533, [ 5803] = 0x758B, +- [ 5804] = 0x767D, [ 5805] = 0x76AE, [ 5806] = 0x76BF, [ 5807] = 0x76EE, +- [ 5808] = 0x77DB, [ 5809] = 0x77E2, [ 5810] = 0x77F3, [ 5811] = 0x793A, +- [ 5812] = 0x79BE, [ 5813] = 0x7A74, [ 5814] = 0x7ACB, [ 5815] = 0x4E1E, +- [ 5816] = 0x4E1F, [ 5817] = 0x4E52, [ 5818] = 0x4E53, [ 5819] = 0x4E69, +- [ 5820] = 0x4E99, [ 5821] = 0x4EA4, [ 5822] = 0x4EA6, [ 5823] = 0x4EA5, +- [ 5824] = 0x4EFF, [ 5825] = 0x4F09, [ 5826] = 0x4F19, [ 5827] = 0x4F0A, +- [ 5828] = 0x4F15, [ 5829] = 0x4F0D, [ 5830] = 0x4F10, [ 5831] = 0x4F11, +- [ 5832] = 0x4F0F, [ 5833] = 0x4EF2, [ 5834] = 0x4EF6, [ 5835] = 0x4EFB, +- [ 5836] = 0x4EF0, [ 5837] = 0x4EF3, [ 5838] = 0x4EFD, [ 5839] = 0x4F01, +- [ 5840] = 0x4F0B, [ 5841] = 0x5149, [ 5842] = 0x5147, [ 5843] = 0x5146, +- [ 5844] = 0x5148, [ 5845] = 0x5168, [ 5850] = 0x5171, [ 5851] = 0x518D, +- [ 5852] = 0x51B0, [ 5853] = 0x5217, [ 5854] = 0x5211, [ 5855] = 0x5212, +- [ 5856] = 0x520E, [ 5857] = 0x5216, [ 5858] = 0x52A3, [ 5859] = 0x5308, +- [ 5860] = 0x5321, [ 5861] = 0x5320, [ 5862] = 0x5370, [ 5863] = 0x5371, +- [ 5864] = 0x5409, [ 5865] = 0x540F, [ 5866] = 0x540C, [ 5867] = 0x540A, +- [ 5868] = 0x5410, [ 5869] = 0x5401, [ 5870] = 0x540B, [ 5871] = 0x5404, +- [ 5872] = 0x5411, [ 5873] = 0x540D, [ 5874] = 0x5408, [ 5875] = 0x5403, +- [ 5876] = 0x540E, [ 5877] = 0x5406, [ 5878] = 0x5412, [ 5879] = 0x56E0, +- [ 5880] = 0x56DE, [ 5881] = 0x56DD, [ 5882] = 0x5733, [ 5883] = 0x5730, +- [ 5884] = 0x5728, [ 5885] = 0x572D, [ 5886] = 0x572C, [ 5887] = 0x572F, +- [ 5888] = 0x5729, [ 5889] = 0x5919, [ 5890] = 0x591A, [ 5891] = 0x5937, +- [ 5892] = 0x5938, [ 5893] = 0x5984, [ 5894] = 0x5978, [ 5895] = 0x5983, +- [ 5896] = 0x597D, [ 5897] = 0x5979, [ 5898] = 0x5982, [ 5899] = 0x5981, +- [ 5900] = 0x5B57, [ 5901] = 0x5B58, [ 5902] = 0x5B87, [ 5903] = 0x5B88, +- [ 5904] = 0x5B85, [ 5905] = 0x5B89, [ 5906] = 0x5BFA, [ 5907] = 0x5C16, +- [ 5908] = 0x5C79, [ 5909] = 0x5DDE, [ 5910] = 0x5E06, [ 5911] = 0x5E76, +- [ 5912] = 0x5E74, [ 5947] = 0x5F0F, [ 5948] = 0x5F1B, [ 5949] = 0x5FD9, +- [ 5950] = 0x5FD6, [ 5951] = 0x620E, [ 5952] = 0x620C, [ 5953] = 0x620D, +- [ 5954] = 0x6210, [ 5955] = 0x6263, [ 5956] = 0x625B, [ 5957] = 0x6258, +- [ 5958] = 0x6536, [ 5959] = 0x65E9, [ 5960] = 0x65E8, [ 5961] = 0x65EC, +- [ 5962] = 0x65ED, [ 5963] = 0x66F2, [ 5964] = 0x66F3, [ 5965] = 0x6709, +- [ 5966] = 0x673D, [ 5967] = 0x6734, [ 5968] = 0x6731, [ 5969] = 0x6735, +- [ 5970] = 0x6B21, [ 5971] = 0x6B64, [ 5972] = 0x6B7B, [ 5973] = 0x6C16, +- [ 5974] = 0x6C5D, [ 5975] = 0x6C57, [ 5976] = 0x6C59, [ 5977] = 0x6C5F, +- [ 5978] = 0x6C60, [ 5979] = 0x6C50, [ 5980] = 0x6C55, [ 5981] = 0x6C61, +- [ 5982] = 0x6C5B, [ 5983] = 0x6C4D, [ 5984] = 0x6C4E, [ 5985] = 0x7070, +- [ 5986] = 0x725F, [ 5987] = 0x725D, [ 5988] = 0x767E, [ 5989] = 0x7AF9, +- [ 5990] = 0x7C73, [ 5991] = 0x7CF8, [ 5992] = 0x7F36, [ 5993] = 0x7F8A, +- [ 5994] = 0x7FBD, [ 5995] = 0x8001, [ 5996] = 0x8003, [ 5997] = 0x800C, +- [ 5998] = 0x8012, [ 5999] = 0x8033, [ 6000] = 0x807F, [ 6001] = 0x8089, +- [ 6002] = 0x808B, [ 6003] = 0x808C, [ 6004] = 0x81E3, [ 6005] = 0x81EA, +- [ 6006] = 0x81F3, [ 6007] = 0x81FC, [ 6008] = 0x820C, [ 6009] = 0x821B, +- [ 6010] = 0x821F, [ 6011] = 0x826E, [ 6012] = 0x8272, [ 6013] = 0x827E, +- [ 6014] = 0x866B, [ 6015] = 0x8840, [ 6016] = 0x884C, [ 6017] = 0x8863, +- [ 6018] = 0x897F, [ 6019] = 0x9621, [ 6020] = 0x4E32, [ 6021] = 0x4EA8, +- [ 6022] = 0x4F4D, [ 6023] = 0x4F4F, [ 6024] = 0x4F47, [ 6025] = 0x4F57, +- [ 6026] = 0x4F5E, [ 6027] = 0x4F34, [ 6028] = 0x4F5B, [ 6029] = 0x4F55, +- [ 6030] = 0x4F30, [ 6031] = 0x4F50, [ 6032] = 0x4F51, [ 6033] = 0x4F3D, +- [ 6034] = 0x4F3A, [ 6035] = 0x4F38, [ 6036] = 0x4F43, [ 6037] = 0x4F54, +- [ 6038] = 0x4F3C, [ 6039] = 0x4F46, [ 6040] = 0x4F63, [ 6045] = 0x4F5C, +- [ 6046] = 0x4F60, [ 6047] = 0x4F2F, [ 6048] = 0x4F4E, [ 6049] = 0x4F36, +- [ 6050] = 0x4F59, [ 6051] = 0x4F5D, [ 6052] = 0x4F48, [ 6053] = 0x4F5A, +- [ 6054] = 0x514C, [ 6055] = 0x514B, [ 6056] = 0x514D, [ 6057] = 0x5175, +- [ 6058] = 0x51B6, [ 6059] = 0x51B7, [ 6060] = 0x5225, [ 6061] = 0x5224, +- [ 6062] = 0x5229, [ 6063] = 0x522A, [ 6064] = 0x5228, [ 6065] = 0x52AB, +- [ 6066] = 0x52A9, [ 6067] = 0x52AA, [ 6068] = 0x52AC, [ 6069] = 0x5323, +- [ 6070] = 0x5373, [ 6071] = 0x5375, [ 6072] = 0x541D, [ 6073] = 0x542D, +- [ 6074] = 0x541E, [ 6075] = 0x543E, [ 6076] = 0x5426, [ 6077] = 0x544E, +- [ 6078] = 0x5427, [ 6079] = 0x5446, [ 6080] = 0x5443, [ 6081] = 0x5433, +- [ 6082] = 0x5448, [ 6083] = 0x5442, [ 6084] = 0x541B, [ 6085] = 0x5429, +- [ 6086] = 0x544A, [ 6087] = 0x5439, [ 6088] = 0x543B, [ 6089] = 0x5438, +- [ 6090] = 0x542E, [ 6091] = 0x5435, [ 6092] = 0x5436, [ 6093] = 0x5420, +- [ 6094] = 0x543C, [ 6095] = 0x5440, [ 6096] = 0x5431, [ 6097] = 0x542B, +- [ 6098] = 0x541F, [ 6099] = 0x542C, [ 6100] = 0x56EA, [ 6101] = 0x56F0, +- [ 6102] = 0x56E4, [ 6103] = 0x56EB, [ 6104] = 0x574A, [ 6105] = 0x5751, +- [ 6106] = 0x5740, [ 6107] = 0x574D, [ 6142] = 0x5747, [ 6143] = 0x574E, +- [ 6144] = 0x573E, [ 6145] = 0x5750, [ 6146] = 0x574F, [ 6147] = 0x573B, +- [ 6148] = 0x58EF, [ 6149] = 0x593E, [ 6150] = 0x599D, [ 6151] = 0x5992, +- [ 6152] = 0x59A8, [ 6153] = 0x599E, [ 6154] = 0x59A3, [ 6155] = 0x5999, +- [ 6156] = 0x5996, [ 6157] = 0x598D, [ 6158] = 0x59A4, [ 6159] = 0x5993, +- [ 6160] = 0x598A, [ 6161] = 0x59A5, [ 6162] = 0x5B5D, [ 6163] = 0x5B5C, +- [ 6164] = 0x5B5A, [ 6165] = 0x5B5B, [ 6166] = 0x5B8C, [ 6167] = 0x5B8B, +- [ 6168] = 0x5B8F, [ 6169] = 0x5C2C, [ 6170] = 0x5C40, [ 6171] = 0x5C41, +- [ 6172] = 0x5C3F, [ 6173] = 0x5C3E, [ 6174] = 0x5C90, [ 6175] = 0x5C91, +- [ 6176] = 0x5C94, [ 6177] = 0x5C8C, [ 6178] = 0x5DEB, [ 6179] = 0x5E0C, +- [ 6180] = 0x5E8F, [ 6181] = 0x5E87, [ 6182] = 0x5E8A, [ 6183] = 0x5EF7, +- [ 6184] = 0x5F04, [ 6185] = 0x5F1F, [ 6186] = 0x5F64, [ 6187] = 0x5F62, +- [ 6188] = 0x5F77, [ 6189] = 0x5F79, [ 6190] = 0x5FD8, [ 6191] = 0x5FCC, +- [ 6192] = 0x5FD7, [ 6193] = 0x5FCD, [ 6194] = 0x5FF1, [ 6195] = 0x5FEB, +- [ 6196] = 0x5FF8, [ 6197] = 0x5FEA, [ 6198] = 0x6212, [ 6199] = 0x6211, +- [ 6200] = 0x6284, [ 6201] = 0x6297, [ 6202] = 0x6296, [ 6203] = 0x6280, +- [ 6204] = 0x6276, [ 6205] = 0x6289, [ 6206] = 0x626D, [ 6207] = 0x628A, +- [ 6208] = 0x627C, [ 6209] = 0x627E, [ 6210] = 0x6279, [ 6211] = 0x6273, +- [ 6212] = 0x6292, [ 6213] = 0x626F, [ 6214] = 0x6298, [ 6215] = 0x626E, +- [ 6216] = 0x6295, [ 6217] = 0x6293, [ 6218] = 0x6291, [ 6219] = 0x6286, +- [ 6220] = 0x6539, [ 6221] = 0x653B, [ 6222] = 0x6538, [ 6223] = 0x65F1, +- [ 6224] = 0x66F4, [ 6225] = 0x675F, [ 6226] = 0x674E, [ 6227] = 0x674F, +- [ 6228] = 0x6750, [ 6229] = 0x6751, [ 6230] = 0x675C, [ 6231] = 0x6756, +- [ 6232] = 0x675E, [ 6233] = 0x6749, [ 6234] = 0x6746, [ 6235] = 0x6760, +- [ 6240] = 0x6753, [ 6241] = 0x6757, [ 6242] = 0x6B65, [ 6243] = 0x6BCF, +- [ 6244] = 0x6C42, [ 6245] = 0x6C5E, [ 6246] = 0x6C99, [ 6247] = 0x6C81, +- [ 6248] = 0x6C88, [ 6249] = 0x6C89, [ 6250] = 0x6C85, [ 6251] = 0x6C9B, +- [ 6252] = 0x6C6A, [ 6253] = 0x6C7A, [ 6254] = 0x6C90, [ 6255] = 0x6C70, +- [ 6256] = 0x6C8C, [ 6257] = 0x6C68, [ 6258] = 0x6C96, [ 6259] = 0x6C92, +- [ 6260] = 0x6C7D, [ 6261] = 0x6C83, [ 6262] = 0x6C72, [ 6263] = 0x6C7E, +- [ 6264] = 0x6C74, [ 6265] = 0x6C86, [ 6266] = 0x6C76, [ 6267] = 0x6C8D, +- [ 6268] = 0x6C94, [ 6269] = 0x6C98, [ 6270] = 0x6C82, [ 6271] = 0x7076, +- [ 6272] = 0x707C, [ 6273] = 0x707D, [ 6274] = 0x7078, [ 6275] = 0x7262, +- [ 6276] = 0x7261, [ 6277] = 0x7260, [ 6278] = 0x72C4, [ 6279] = 0x72C2, +- [ 6280] = 0x7396, [ 6281] = 0x752C, [ 6282] = 0x752B, [ 6283] = 0x7537, +- [ 6284] = 0x7538, [ 6285] = 0x7682, [ 6286] = 0x76EF, [ 6287] = 0x77E3, +- [ 6288] = 0x79C1, [ 6289] = 0x79C0, [ 6290] = 0x79BF, [ 6291] = 0x7A76, +- [ 6292] = 0x7CFB, [ 6293] = 0x7F55, [ 6294] = 0x8096, [ 6295] = 0x8093, +- [ 6296] = 0x809D, [ 6297] = 0x8098, [ 6298] = 0x809B, [ 6299] = 0x809A, +- [ 6300] = 0x80B2, [ 6301] = 0x826F, [ 6302] = 0x8292, [ 6337] = 0x828B, +- [ 6338] = 0x828D, [ 6339] = 0x898B, [ 6340] = 0x89D2, [ 6341] = 0x8A00, +- [ 6342] = 0x8C37, [ 6343] = 0x8C46, [ 6344] = 0x8C55, [ 6345] = 0x8C9D, +- [ 6346] = 0x8D64, [ 6347] = 0x8D70, [ 6348] = 0x8DB3, [ 6349] = 0x8EAB, +- [ 6350] = 0x8ECA, [ 6351] = 0x8F9B, [ 6352] = 0x8FB0, [ 6353] = 0x8FC2, +- [ 6354] = 0x8FC6, [ 6355] = 0x8FC5, [ 6356] = 0x8FC4, [ 6357] = 0x5DE1, +- [ 6358] = 0x9091, [ 6359] = 0x90A2, [ 6360] = 0x90AA, [ 6361] = 0x90A6, +- [ 6362] = 0x90A3, [ 6363] = 0x9149, [ 6364] = 0x91C6, [ 6365] = 0x91CC, +- [ 6366] = 0x9632, [ 6367] = 0x962E, [ 6368] = 0x9631, [ 6369] = 0x962A, +- [ 6370] = 0x962C, [ 6371] = 0x4E26, [ 6372] = 0x4E56, [ 6373] = 0x4E73, +- [ 6374] = 0x4E8B, [ 6375] = 0x4E9B, [ 6376] = 0x4E9E, [ 6377] = 0x4EAB, +- [ 6378] = 0x4EAC, [ 6379] = 0x4F6F, [ 6380] = 0x4F9D, [ 6381] = 0x4F8D, +- [ 6382] = 0x4F73, [ 6383] = 0x4F7F, [ 6384] = 0x4F6C, [ 6385] = 0x4F9B, +- [ 6386] = 0x4F8B, [ 6387] = 0x4F86, [ 6388] = 0x4F83, [ 6389] = 0x4F70, +- [ 6390] = 0x4F75, [ 6391] = 0x4F88, [ 6392] = 0x4F69, [ 6393] = 0x4F7B, +- [ 6394] = 0x4F96, [ 6395] = 0x4F7E, [ 6396] = 0x4F8F, [ 6397] = 0x4F91, +- [ 6398] = 0x4F7A, [ 6399] = 0x5154, [ 6400] = 0x5152, [ 6401] = 0x5155, +- [ 6402] = 0x5169, [ 6403] = 0x5177, [ 6404] = 0x5176, [ 6405] = 0x5178, +- [ 6406] = 0x51BD, [ 6407] = 0x51FD, [ 6408] = 0x523B, [ 6409] = 0x5238, +- [ 6410] = 0x5237, [ 6411] = 0x523A, [ 6412] = 0x5230, [ 6413] = 0x522E, +- [ 6414] = 0x5236, [ 6415] = 0x5241, [ 6416] = 0x52BE, [ 6417] = 0x52BB, +- [ 6418] = 0x5352, [ 6419] = 0x5354, [ 6420] = 0x5353, [ 6421] = 0x5351, +- [ 6422] = 0x5366, [ 6423] = 0x5377, [ 6424] = 0x5378, [ 6425] = 0x5379, +- [ 6426] = 0x53D6, [ 6427] = 0x53D4, [ 6428] = 0x53D7, [ 6429] = 0x5473, +- [ 6430] = 0x5475, [ 6435] = 0x5496, [ 6436] = 0x5478, [ 6437] = 0x5495, +- [ 6438] = 0x5480, [ 6439] = 0x547B, [ 6440] = 0x5477, [ 6441] = 0x5484, +- [ 6442] = 0x5492, [ 6443] = 0x5486, [ 6444] = 0x547C, [ 6445] = 0x5490, +- [ 6446] = 0x5471, [ 6447] = 0x5476, [ 6448] = 0x548C, [ 6449] = 0x549A, +- [ 6450] = 0x5462, [ 6451] = 0x5468, [ 6452] = 0x548B, [ 6453] = 0x547D, +- [ 6454] = 0x548E, [ 6455] = 0x56FA, [ 6456] = 0x5783, [ 6457] = 0x5777, +- [ 6458] = 0x576A, [ 6459] = 0x5769, [ 6460] = 0x5761, [ 6461] = 0x5766, +- [ 6462] = 0x5764, [ 6463] = 0x577C, [ 6464] = 0x591C, [ 6465] = 0x5949, +- [ 6466] = 0x5947, [ 6467] = 0x5948, [ 6468] = 0x5944, [ 6469] = 0x5954, +- [ 6470] = 0x59BE, [ 6471] = 0x59BB, [ 6472] = 0x59D4, [ 6473] = 0x59B9, +- [ 6474] = 0x59AE, [ 6475] = 0x59D1, [ 6476] = 0x59C6, [ 6477] = 0x59D0, +- [ 6478] = 0x59CD, [ 6479] = 0x59CB, [ 6480] = 0x59D3, [ 6481] = 0x59CA, +- [ 6482] = 0x59AF, [ 6483] = 0x59B3, [ 6484] = 0x59D2, [ 6485] = 0x59C5, +- [ 6486] = 0x5B5F, [ 6487] = 0x5B64, [ 6488] = 0x5B63, [ 6489] = 0x5B97, +- [ 6490] = 0x5B9A, [ 6491] = 0x5B98, [ 6492] = 0x5B9C, [ 6493] = 0x5B99, +- [ 6494] = 0x5B9B, [ 6495] = 0x5C1A, [ 6496] = 0x5C48, [ 6497] = 0x5C45, +- [ 6532] = 0x5C46, [ 6533] = 0x5CB7, [ 6534] = 0x5CA1, [ 6535] = 0x5CB8, +- [ 6536] = 0x5CA9, [ 6537] = 0x5CAB, [ 6538] = 0x5CB1, [ 6539] = 0x5CB3, +- [ 6540] = 0x5E18, [ 6541] = 0x5E1A, [ 6542] = 0x5E16, [ 6543] = 0x5E15, +- [ 6544] = 0x5E1B, [ 6545] = 0x5E11, [ 6546] = 0x5E78, [ 6547] = 0x5E9A, +- [ 6548] = 0x5E97, [ 6549] = 0x5E9C, [ 6550] = 0x5E95, [ 6551] = 0x5E96, +- [ 6552] = 0x5EF6, [ 6553] = 0x5F26, [ 6554] = 0x5F27, [ 6555] = 0x5F29, +- [ 6556] = 0x5F80, [ 6557] = 0x5F81, [ 6558] = 0x5F7F, [ 6559] = 0x5F7C, +- [ 6560] = 0x5FDD, [ 6561] = 0x5FE0, [ 6562] = 0x5FFD, [ 6563] = 0x5FF5, +- [ 6564] = 0x5FFF, [ 6565] = 0x600F, [ 6566] = 0x6014, [ 6567] = 0x602F, +- [ 6568] = 0x6035, [ 6569] = 0x6016, [ 6570] = 0x602A, [ 6571] = 0x6015, +- [ 6572] = 0x6021, [ 6573] = 0x6027, [ 6574] = 0x6029, [ 6575] = 0x602B, +- [ 6576] = 0x601B, [ 6577] = 0x6216, [ 6578] = 0x6215, [ 6579] = 0x623F, +- [ 6580] = 0x623E, [ 6581] = 0x6240, [ 6582] = 0x627F, [ 6583] = 0x62C9, +- [ 6584] = 0x62CC, [ 6585] = 0x62C4, [ 6586] = 0x62BF, [ 6587] = 0x62C2, +- [ 6588] = 0x62B9, [ 6589] = 0x62D2, [ 6590] = 0x62DB, [ 6591] = 0x62AB, +- [ 6592] = 0x62D3, [ 6593] = 0x62D4, [ 6594] = 0x62CB, [ 6595] = 0x62C8, +- [ 6596] = 0x62A8, [ 6597] = 0x62BD, [ 6598] = 0x62BC, [ 6599] = 0x62D0, +- [ 6600] = 0x62D9, [ 6601] = 0x62C7, [ 6602] = 0x62CD, [ 6603] = 0x62B5, +- [ 6604] = 0x62DA, [ 6605] = 0x62B1, [ 6606] = 0x62D8, [ 6607] = 0x62D6, +- [ 6608] = 0x62D7, [ 6609] = 0x62C6, [ 6610] = 0x62AC, [ 6611] = 0x62CE, +- [ 6612] = 0x653E, [ 6613] = 0x65A7, [ 6614] = 0x65BC, [ 6615] = 0x65FA, +- [ 6616] = 0x6614, [ 6617] = 0x6613, [ 6618] = 0x660C, [ 6619] = 0x6606, +- [ 6620] = 0x6602, [ 6621] = 0x660E, [ 6622] = 0x6600, [ 6623] = 0x660F, +- [ 6624] = 0x6615, [ 6625] = 0x660A, [ 6630] = 0x6607, [ 6631] = 0x670D, +- [ 6632] = 0x670B, [ 6633] = 0x676D, [ 6634] = 0x678B, [ 6635] = 0x6795, +- [ 6636] = 0x6771, [ 6637] = 0x679C, [ 6638] = 0x6773, [ 6639] = 0x6777, +- [ 6640] = 0x6787, [ 6641] = 0x679D, [ 6642] = 0x6797, [ 6643] = 0x676F, +- [ 6644] = 0x6770, [ 6645] = 0x677F, [ 6646] = 0x6789, [ 6647] = 0x677E, +- [ 6648] = 0x6790, [ 6649] = 0x6775, [ 6650] = 0x679A, [ 6651] = 0x6793, +- [ 6652] = 0x677C, [ 6653] = 0x676A, [ 6654] = 0x6772, [ 6655] = 0x6B23, +- [ 6656] = 0x6B66, [ 6657] = 0x6B67, [ 6658] = 0x6B7F, [ 6659] = 0x6C13, +- [ 6660] = 0x6C1B, [ 6661] = 0x6CE3, [ 6662] = 0x6CE8, [ 6663] = 0x6CF3, +- [ 6664] = 0x6CB1, [ 6665] = 0x6CCC, [ 6666] = 0x6CE5, [ 6667] = 0x6CB3, +- [ 6668] = 0x6CBD, [ 6669] = 0x6CBE, [ 6670] = 0x6CBC, [ 6671] = 0x6CE2, +- [ 6672] = 0x6CAB, [ 6673] = 0x6CD5, [ 6674] = 0x6CD3, [ 6675] = 0x6CB8, +- [ 6676] = 0x6CC4, [ 6677] = 0x6CB9, [ 6678] = 0x6CC1, [ 6679] = 0x6CAE, +- [ 6680] = 0x6CD7, [ 6681] = 0x6CC5, [ 6682] = 0x6CF1, [ 6683] = 0x6CBF, +- [ 6684] = 0x6CBB, [ 6685] = 0x6CE1, [ 6686] = 0x6CDB, [ 6687] = 0x6CCA, +- [ 6688] = 0x6CAC, [ 6689] = 0x6CEF, [ 6690] = 0x6CDC, [ 6691] = 0x6CD6, +- [ 6692] = 0x6CE0, [ 6727] = 0x7095, [ 6728] = 0x708E, [ 6729] = 0x7092, +- [ 6730] = 0x708A, [ 6731] = 0x7099, [ 6732] = 0x722C, [ 6733] = 0x722D, +- [ 6734] = 0x7238, [ 6735] = 0x7248, [ 6736] = 0x7267, [ 6737] = 0x7269, +- [ 6738] = 0x72C0, [ 6739] = 0x72CE, [ 6740] = 0x72D9, [ 6741] = 0x72D7, +- [ 6742] = 0x72D0, [ 6743] = 0x73A9, [ 6744] = 0x73A8, [ 6745] = 0x739F, +- [ 6746] = 0x73AB, [ 6747] = 0x73A5, [ 6748] = 0x753D, [ 6749] = 0x759D, +- [ 6750] = 0x7599, [ 6751] = 0x759A, [ 6752] = 0x7684, [ 6753] = 0x76C2, +- [ 6754] = 0x76F2, [ 6755] = 0x76F4, [ 6756] = 0x77E5, [ 6757] = 0x77FD, +- [ 6758] = 0x793E, [ 6759] = 0x7940, [ 6760] = 0x7941, [ 6761] = 0x79C9, +- [ 6762] = 0x79C8, [ 6763] = 0x7A7A, [ 6764] = 0x7A79, [ 6765] = 0x7AFA, +- [ 6766] = 0x7CFE, [ 6767] = 0x7F54, [ 6768] = 0x7F8C, [ 6769] = 0x7F8B, +- [ 6770] = 0x8005, [ 6771] = 0x80BA, [ 6772] = 0x80A5, [ 6773] = 0x80A2, +- [ 6774] = 0x80B1, [ 6775] = 0x80A1, [ 6776] = 0x80AB, [ 6777] = 0x80A9, +- [ 6778] = 0x80B4, [ 6779] = 0x80AA, [ 6780] = 0x80AF, [ 6781] = 0x81E5, +- [ 6782] = 0x81FE, [ 6783] = 0x820D, [ 6784] = 0x82B3, [ 6785] = 0x829D, +- [ 6786] = 0x8299, [ 6787] = 0x82AD, [ 6788] = 0x82BD, [ 6789] = 0x829F, +- [ 6790] = 0x82B9, [ 6791] = 0x82B1, [ 6792] = 0x82AC, [ 6793] = 0x82A5, +- [ 6794] = 0x82AF, [ 6795] = 0x82B8, [ 6796] = 0x82A3, [ 6797] = 0x82B0, +- [ 6798] = 0x82BE, [ 6799] = 0x82B7, [ 6800] = 0x864E, [ 6801] = 0x8671, +- [ 6802] = 0x521D, [ 6803] = 0x8868, [ 6804] = 0x8ECB, [ 6805] = 0x8FCE, +- [ 6806] = 0x8FD4, [ 6807] = 0x8FD1, [ 6808] = 0x90B5, [ 6809] = 0x90B8, +- [ 6810] = 0x90B1, [ 6811] = 0x90B6, [ 6812] = 0x91C7, [ 6813] = 0x91D1, +- [ 6814] = 0x9577, [ 6815] = 0x9580, [ 6816] = 0x961C, [ 6817] = 0x9640, +- [ 6818] = 0x963F, [ 6819] = 0x963B, [ 6820] = 0x9644, [ 6825] = 0x9642, +- [ 6826] = 0x96B9, [ 6827] = 0x96E8, [ 6828] = 0x9752, [ 6829] = 0x975E, +- [ 6830] = 0x4E9F, [ 6831] = 0x4EAD, [ 6832] = 0x4EAE, [ 6833] = 0x4FE1, +- [ 6834] = 0x4FB5, [ 6835] = 0x4FAF, [ 6836] = 0x4FBF, [ 6837] = 0x4FE0, +- [ 6838] = 0x4FD1, [ 6839] = 0x4FCF, [ 6840] = 0x4FDD, [ 6841] = 0x4FC3, +- [ 6842] = 0x4FB6, [ 6843] = 0x4FD8, [ 6844] = 0x4FDF, [ 6845] = 0x4FCA, +- [ 6846] = 0x4FD7, [ 6847] = 0x4FAE, [ 6848] = 0x4FD0, [ 6849] = 0x4FC4, +- [ 6850] = 0x4FC2, [ 6851] = 0x4FDA, [ 6852] = 0x4FCE, [ 6853] = 0x4FDE, +- [ 6854] = 0x4FB7, [ 6855] = 0x5157, [ 6856] = 0x5192, [ 6857] = 0x5191, +- [ 6858] = 0x51A0, [ 6859] = 0x524E, [ 6860] = 0x5243, [ 6861] = 0x524A, +- [ 6862] = 0x524D, [ 6863] = 0x524C, [ 6864] = 0x524B, [ 6865] = 0x5247, +- [ 6866] = 0x52C7, [ 6867] = 0x52C9, [ 6868] = 0x52C3, [ 6869] = 0x52C1, +- [ 6870] = 0x530D, [ 6871] = 0x5357, [ 6872] = 0x537B, [ 6873] = 0x539A, +- [ 6874] = 0x53DB, [ 6875] = 0x54AC, [ 6876] = 0x54C0, [ 6877] = 0x54A8, +- [ 6878] = 0x54CE, [ 6879] = 0x54C9, [ 6880] = 0x54B8, [ 6881] = 0x54A6, +- [ 6882] = 0x54B3, [ 6883] = 0x54C7, [ 6884] = 0x54C2, [ 6885] = 0x54BD, +- [ 6886] = 0x54AA, [ 6887] = 0x54C1, [ 6922] = 0x54C4, [ 6923] = 0x54C8, +- [ 6924] = 0x54AF, [ 6925] = 0x54AB, [ 6926] = 0x54B1, [ 6927] = 0x54BB, +- [ 6928] = 0x54A9, [ 6929] = 0x54A7, [ 6930] = 0x54BF, [ 6931] = 0x56FF, +- [ 6932] = 0x5782, [ 6933] = 0x578B, [ 6934] = 0x57A0, [ 6935] = 0x57A3, +- [ 6936] = 0x57A2, [ 6937] = 0x57CE, [ 6938] = 0x57AE, [ 6939] = 0x5793, +- [ 6940] = 0x5955, [ 6941] = 0x5951, [ 6942] = 0x594F, [ 6943] = 0x594E, +- [ 6944] = 0x5950, [ 6945] = 0x59DC, [ 6946] = 0x59D8, [ 6947] = 0x59FF, +- [ 6948] = 0x59E3, [ 6949] = 0x59E8, [ 6950] = 0x5A03, [ 6951] = 0x59E5, +- [ 6952] = 0x59EA, [ 6953] = 0x59DA, [ 6954] = 0x59E6, [ 6955] = 0x5A01, +- [ 6956] = 0x59FB, [ 6957] = 0x5B69, [ 6958] = 0x5BA3, [ 6959] = 0x5BA6, +- [ 6960] = 0x5BA4, [ 6961] = 0x5BA2, [ 6962] = 0x5BA5, [ 6963] = 0x5C01, +- [ 6964] = 0x5C4E, [ 6965] = 0x5C4F, [ 6966] = 0x5C4D, [ 6967] = 0x5C4B, +- [ 6968] = 0x5CD9, [ 6969] = 0x5CD2, [ 6970] = 0x5DF7, [ 6971] = 0x5E1D, +- [ 6972] = 0x5E25, [ 6973] = 0x5E1F, [ 6974] = 0x5E7D, [ 6975] = 0x5EA0, +- [ 6976] = 0x5EA6, [ 6977] = 0x5EFA, [ 6978] = 0x5F08, [ 6979] = 0x5F2D, +- [ 6980] = 0x5F65, [ 6981] = 0x5F88, [ 6982] = 0x5F85, [ 6983] = 0x5F8A, +- [ 6984] = 0x5F8B, [ 6985] = 0x5F87, [ 6986] = 0x5F8C, [ 6987] = 0x5F89, +- [ 6988] = 0x6012, [ 6989] = 0x601D, [ 6990] = 0x6020, [ 6991] = 0x6025, +- [ 6992] = 0x600E, [ 6993] = 0x6028, [ 6994] = 0x604D, [ 6995] = 0x6070, +- [ 6996] = 0x6068, [ 6997] = 0x6062, [ 6998] = 0x6046, [ 6999] = 0x6043, +- [ 7000] = 0x606C, [ 7001] = 0x606B, [ 7002] = 0x606A, [ 7003] = 0x6064, +- [ 7004] = 0x6241, [ 7005] = 0x62DC, [ 7006] = 0x6316, [ 7007] = 0x6309, +- [ 7008] = 0x62FC, [ 7009] = 0x62ED, [ 7010] = 0x6301, [ 7011] = 0x62EE, +- [ 7012] = 0x62FD, [ 7013] = 0x6307, [ 7014] = 0x62F1, [ 7015] = 0x62F7, +- [ 7020] = 0x62EF, [ 7021] = 0x62EC, [ 7022] = 0x62FE, [ 7023] = 0x62F4, +- [ 7024] = 0x6311, [ 7025] = 0x6302, [ 7026] = 0x653F, [ 7027] = 0x6545, +- [ 7028] = 0x65AB, [ 7029] = 0x65BD, [ 7030] = 0x65E2, [ 7031] = 0x6625, +- [ 7032] = 0x662D, [ 7033] = 0x6620, [ 7034] = 0x6627, [ 7035] = 0x662F, +- [ 7036] = 0x661F, [ 7037] = 0x6628, [ 7038] = 0x6631, [ 7039] = 0x6624, +- [ 7040] = 0x66F7, [ 7041] = 0x67FF, [ 7042] = 0x67D3, [ 7043] = 0x67F1, +- [ 7044] = 0x67D4, [ 7045] = 0x67D0, [ 7046] = 0x67EC, [ 7047] = 0x67B6, +- [ 7048] = 0x67AF, [ 7049] = 0x67F5, [ 7050] = 0x67E9, [ 7051] = 0x67EF, +- [ 7052] = 0x67C4, [ 7053] = 0x67D1, [ 7054] = 0x67B4, [ 7055] = 0x67DA, +- [ 7056] = 0x67E5, [ 7057] = 0x67B8, [ 7058] = 0x67CF, [ 7059] = 0x67DE, +- [ 7060] = 0x67F3, [ 7061] = 0x67B0, [ 7062] = 0x67D9, [ 7063] = 0x67E2, +- [ 7064] = 0x67DD, [ 7065] = 0x67D2, [ 7066] = 0x6B6A, [ 7067] = 0x6B83, +- [ 7068] = 0x6B86, [ 7069] = 0x6BB5, [ 7070] = 0x6BD2, [ 7071] = 0x6BD7, +- [ 7072] = 0x6C1F, [ 7073] = 0x6CC9, [ 7074] = 0x6D0B, [ 7075] = 0x6D32, +- [ 7076] = 0x6D2A, [ 7077] = 0x6D41, [ 7078] = 0x6D25, [ 7079] = 0x6D0C, +- [ 7080] = 0x6D31, [ 7081] = 0x6D1E, [ 7082] = 0x6D17, [ 7117] = 0x6D3B, +- [ 7118] = 0x6D3D, [ 7119] = 0x6D3E, [ 7120] = 0x6D36, [ 7121] = 0x6D1B, +- [ 7122] = 0x6CF5, [ 7123] = 0x6D39, [ 7124] = 0x6D27, [ 7125] = 0x6D38, +- [ 7126] = 0x6D29, [ 7127] = 0x6D2E, [ 7128] = 0x6D35, [ 7129] = 0x6D0E, +- [ 7130] = 0x6D2B, [ 7131] = 0x70AB, [ 7132] = 0x70BA, [ 7133] = 0x70B3, +- [ 7134] = 0x70AC, [ 7135] = 0x70AF, [ 7136] = 0x70AD, [ 7137] = 0x70B8, +- [ 7138] = 0x70AE, [ 7139] = 0x70A4, [ 7140] = 0x7230, [ 7141] = 0x7272, +- [ 7142] = 0x726F, [ 7143] = 0x7274, [ 7144] = 0x72E9, [ 7145] = 0x72E0, +- [ 7146] = 0x72E1, [ 7147] = 0x73B7, [ 7148] = 0x73CA, [ 7149] = 0x73BB, +- [ 7150] = 0x73B2, [ 7151] = 0x73CD, [ 7152] = 0x73C0, [ 7153] = 0x73B3, +- [ 7154] = 0x751A, [ 7155] = 0x752D, [ 7156] = 0x754F, [ 7157] = 0x754C, +- [ 7158] = 0x754E, [ 7159] = 0x754B, [ 7160] = 0x75AB, [ 7161] = 0x75A4, +- [ 7162] = 0x75A5, [ 7163] = 0x75A2, [ 7164] = 0x75A3, [ 7165] = 0x7678, +- [ 7166] = 0x7686, [ 7167] = 0x7687, [ 7168] = 0x7688, [ 7169] = 0x76C8, +- [ 7170] = 0x76C6, [ 7171] = 0x76C3, [ 7172] = 0x76C5, [ 7173] = 0x7701, +- [ 7174] = 0x76F9, [ 7175] = 0x76F8, [ 7176] = 0x7709, [ 7177] = 0x770B, +- [ 7178] = 0x76FE, [ 7179] = 0x76FC, [ 7180] = 0x7707, [ 7181] = 0x77DC, +- [ 7182] = 0x7802, [ 7183] = 0x7814, [ 7184] = 0x780C, [ 7185] = 0x780D, +- [ 7186] = 0x7946, [ 7187] = 0x7949, [ 7188] = 0x7948, [ 7189] = 0x7947, +- [ 7190] = 0x79B9, [ 7191] = 0x79BA, [ 7192] = 0x79D1, [ 7193] = 0x79D2, +- [ 7194] = 0x79CB, [ 7195] = 0x7A7F, [ 7196] = 0x7A81, [ 7197] = 0x7AFF, +- [ 7198] = 0x7AFD, [ 7199] = 0x7C7D, [ 7200] = 0x7D02, [ 7201] = 0x7D05, +- [ 7202] = 0x7D00, [ 7203] = 0x7D09, [ 7204] = 0x7D07, [ 7205] = 0x7D04, +- [ 7206] = 0x7D06, [ 7207] = 0x7F38, [ 7208] = 0x7F8E, [ 7209] = 0x7FBF, +- [ 7210] = 0x8004, [ 7215] = 0x8010, [ 7216] = 0x800D, [ 7217] = 0x8011, +- [ 7218] = 0x8036, [ 7219] = 0x80D6, [ 7220] = 0x80E5, [ 7221] = 0x80DA, +- [ 7222] = 0x80C3, [ 7223] = 0x80C4, [ 7224] = 0x80CC, [ 7225] = 0x80E1, +- [ 7226] = 0x80DB, [ 7227] = 0x80CE, [ 7228] = 0x80DE, [ 7229] = 0x80E4, +- [ 7230] = 0x80DD, [ 7231] = 0x81F4, [ 7232] = 0x8222, [ 7233] = 0x82E7, +- [ 7234] = 0x8303, [ 7235] = 0x8305, [ 7236] = 0x82E3, [ 7237] = 0x82DB, +- [ 7238] = 0x82E6, [ 7239] = 0x8304, [ 7240] = 0x82E5, [ 7241] = 0x8302, +- [ 7242] = 0x8309, [ 7243] = 0x82D2, [ 7244] = 0x82D7, [ 7245] = 0x82F1, +- [ 7246] = 0x8301, [ 7247] = 0x82DC, [ 7248] = 0x82D4, [ 7249] = 0x82D1, +- [ 7250] = 0x82DE, [ 7251] = 0x82D3, [ 7252] = 0x82DF, [ 7253] = 0x82EF, +- [ 7254] = 0x8306, [ 7255] = 0x8650, [ 7256] = 0x8679, [ 7257] = 0x867B, +- [ 7258] = 0x867A, [ 7259] = 0x884D, [ 7260] = 0x886B, [ 7261] = 0x8981, +- [ 7262] = 0x89D4, [ 7263] = 0x8A08, [ 7264] = 0x8A02, [ 7265] = 0x8A03, +- [ 7266] = 0x8C9E, [ 7267] = 0x8CA0, [ 7268] = 0x8D74, [ 7269] = 0x8D73, +- [ 7270] = 0x8DB4, [ 7271] = 0x8ECD, [ 7272] = 0x8ECC, [ 7273] = 0x8FF0, +- [ 7274] = 0x8FE6, [ 7275] = 0x8FE2, [ 7276] = 0x8FEA, [ 7277] = 0x8FE5, +- [ 7312] = 0x8FED, [ 7313] = 0x8FEB, [ 7314] = 0x8FE4, [ 7315] = 0x8FE8, +- [ 7316] = 0x90CA, [ 7317] = 0x90CE, [ 7318] = 0x90C1, [ 7319] = 0x90C3, +- [ 7320] = 0x914B, [ 7321] = 0x914A, [ 7322] = 0x91CD, [ 7323] = 0x9582, +- [ 7324] = 0x9650, [ 7325] = 0x964B, [ 7326] = 0x964C, [ 7327] = 0x964D, +- [ 7328] = 0x9762, [ 7329] = 0x9769, [ 7330] = 0x97CB, [ 7331] = 0x97ED, +- [ 7332] = 0x97F3, [ 7333] = 0x9801, [ 7334] = 0x98A8, [ 7335] = 0x98DB, +- [ 7336] = 0x98DF, [ 7337] = 0x9996, [ 7338] = 0x9999, [ 7339] = 0x4E58, +- [ 7340] = 0x4EB3, [ 7341] = 0x500C, [ 7342] = 0x500D, [ 7343] = 0x5023, +- [ 7344] = 0x4FEF, [ 7345] = 0x5026, [ 7346] = 0x5025, [ 7347] = 0x4FF8, +- [ 7348] = 0x5029, [ 7349] = 0x5016, [ 7350] = 0x5006, [ 7351] = 0x503C, +- [ 7352] = 0x501F, [ 7353] = 0x501A, [ 7354] = 0x5012, [ 7355] = 0x5011, +- [ 7356] = 0x4FFA, [ 7357] = 0x5000, [ 7358] = 0x5014, [ 7359] = 0x5028, +- [ 7360] = 0x4FF1, [ 7361] = 0x5021, [ 7362] = 0x500B, [ 7363] = 0x5019, +- [ 7364] = 0x5018, [ 7365] = 0x4FF3, [ 7366] = 0x4FEE, [ 7367] = 0x502D, +- [ 7368] = 0x502A, [ 7369] = 0x4FFE, [ 7370] = 0x502B, [ 7371] = 0x5009, +- [ 7372] = 0x517C, [ 7373] = 0x51A4, [ 7374] = 0x51A5, [ 7375] = 0x51A2, +- [ 7376] = 0x51CD, [ 7377] = 0x51CC, [ 7378] = 0x51C6, [ 7379] = 0x51CB, +- [ 7380] = 0x5256, [ 7381] = 0x525C, [ 7382] = 0x5254, [ 7383] = 0x525B, +- [ 7384] = 0x525D, [ 7385] = 0x532A, [ 7386] = 0x537F, [ 7387] = 0x539F, +- [ 7388] = 0x539D, [ 7389] = 0x53DF, [ 7390] = 0x54E8, [ 7391] = 0x5510, +- [ 7392] = 0x5501, [ 7393] = 0x5537, [ 7394] = 0x54FC, [ 7395] = 0x54E5, +- [ 7396] = 0x54F2, [ 7397] = 0x5506, [ 7398] = 0x54FA, [ 7399] = 0x5514, +- [ 7400] = 0x54E9, [ 7401] = 0x54ED, [ 7402] = 0x54E1, [ 7403] = 0x5509, +- [ 7404] = 0x54EE, [ 7405] = 0x54EA, [ 7410] = 0x54E6, [ 7411] = 0x5527, +- [ 7412] = 0x5507, [ 7413] = 0x54FD, [ 7414] = 0x550F, [ 7415] = 0x5703, +- [ 7416] = 0x5704, [ 7417] = 0x57C2, [ 7418] = 0x57D4, [ 7419] = 0x57CB, +- [ 7420] = 0x57C3, [ 7421] = 0x5809, [ 7422] = 0x590F, [ 7423] = 0x5957, +- [ 7424] = 0x5958, [ 7425] = 0x595A, [ 7426] = 0x5A11, [ 7427] = 0x5A18, +- [ 7428] = 0x5A1C, [ 7429] = 0x5A1F, [ 7430] = 0x5A1B, [ 7431] = 0x5A13, +- [ 7432] = 0x59EC, [ 7433] = 0x5A20, [ 7434] = 0x5A23, [ 7435] = 0x5A29, +- [ 7436] = 0x5A25, [ 7437] = 0x5A0C, [ 7438] = 0x5A09, [ 7439] = 0x5B6B, +- [ 7440] = 0x5C58, [ 7441] = 0x5BB0, [ 7442] = 0x5BB3, [ 7443] = 0x5BB6, +- [ 7444] = 0x5BB4, [ 7445] = 0x5BAE, [ 7446] = 0x5BB5, [ 7447] = 0x5BB9, +- [ 7448] = 0x5BB8, [ 7449] = 0x5C04, [ 7450] = 0x5C51, [ 7451] = 0x5C55, +- [ 7452] = 0x5C50, [ 7453] = 0x5CED, [ 7454] = 0x5CFD, [ 7455] = 0x5CFB, +- [ 7456] = 0x5CEA, [ 7457] = 0x5CE8, [ 7458] = 0x5CF0, [ 7459] = 0x5CF6, +- [ 7460] = 0x5D01, [ 7461] = 0x5CF4, [ 7462] = 0x5DEE, [ 7463] = 0x5E2D, +- [ 7464] = 0x5E2B, [ 7465] = 0x5EAB, [ 7466] = 0x5EAD, [ 7467] = 0x5EA7, +- [ 7468] = 0x5F31, [ 7469] = 0x5F92, [ 7470] = 0x5F91, [ 7471] = 0x5F90, +- [ 7472] = 0x6059, [ 7507] = 0x6063, [ 7508] = 0x6065, [ 7509] = 0x6050, +- [ 7510] = 0x6055, [ 7511] = 0x606D, [ 7512] = 0x6069, [ 7513] = 0x606F, +- [ 7514] = 0x6084, [ 7515] = 0x609F, [ 7516] = 0x609A, [ 7517] = 0x608D, +- [ 7518] = 0x6094, [ 7519] = 0x608C, [ 7520] = 0x6085, [ 7521] = 0x6096, +- [ 7522] = 0x6247, [ 7523] = 0x62F3, [ 7524] = 0x6308, [ 7525] = 0x62FF, +- [ 7526] = 0x634E, [ 7527] = 0x633E, [ 7528] = 0x632F, [ 7529] = 0x6355, +- [ 7530] = 0x6342, [ 7531] = 0x6346, [ 7532] = 0x634F, [ 7533] = 0x6349, +- [ 7534] = 0x633A, [ 7535] = 0x6350, [ 7536] = 0x633D, [ 7537] = 0x632A, +- [ 7538] = 0x632B, [ 7539] = 0x6328, [ 7540] = 0x634D, [ 7541] = 0x634C, +- [ 7542] = 0x6548, [ 7543] = 0x6549, [ 7544] = 0x6599, [ 7545] = 0x65C1, +- [ 7546] = 0x65C5, [ 7547] = 0x6642, [ 7548] = 0x6649, [ 7549] = 0x664F, +- [ 7550] = 0x6643, [ 7551] = 0x6652, [ 7552] = 0x664C, [ 7553] = 0x6645, +- [ 7554] = 0x6641, [ 7555] = 0x66F8, [ 7556] = 0x6714, [ 7557] = 0x6715, +- [ 7558] = 0x6717, [ 7559] = 0x6821, [ 7560] = 0x6838, [ 7561] = 0x6848, +- [ 7562] = 0x6846, [ 7563] = 0x6853, [ 7564] = 0x6839, [ 7565] = 0x6842, +- [ 7566] = 0x6854, [ 7567] = 0x6829, [ 7568] = 0x68B3, [ 7569] = 0x6817, +- [ 7570] = 0x684C, [ 7571] = 0x6851, [ 7572] = 0x683D, [ 7573] = 0x67F4, +- [ 7574] = 0x6850, [ 7575] = 0x6840, [ 7576] = 0x683C, [ 7577] = 0x6843, +- [ 7578] = 0x682A, [ 7579] = 0x6845, [ 7580] = 0x6813, [ 7581] = 0x6818, +- [ 7582] = 0x6841, [ 7583] = 0x6B8A, [ 7584] = 0x6B89, [ 7585] = 0x6BB7, +- [ 7586] = 0x6C23, [ 7587] = 0x6C27, [ 7588] = 0x6C28, [ 7589] = 0x6C26, +- [ 7590] = 0x6C24, [ 7591] = 0x6CF0, [ 7592] = 0x6D6A, [ 7593] = 0x6D95, +- [ 7594] = 0x6D88, [ 7595] = 0x6D87, [ 7596] = 0x6D66, [ 7597] = 0x6D78, +- [ 7598] = 0x6D77, [ 7599] = 0x6D59, [ 7600] = 0x6D93, [ 7605] = 0x6D6C, +- [ 7606] = 0x6D89, [ 7607] = 0x6D6E, [ 7608] = 0x6D5A, [ 7609] = 0x6D74, +- [ 7610] = 0x6D69, [ 7611] = 0x6D8C, [ 7612] = 0x6D8A, [ 7613] = 0x6D79, +- [ 7614] = 0x6D85, [ 7615] = 0x6D65, [ 7616] = 0x6D94, [ 7617] = 0x70CA, +- [ 7618] = 0x70D8, [ 7619] = 0x70E4, [ 7620] = 0x70D9, [ 7621] = 0x70C8, +- [ 7622] = 0x70CF, [ 7623] = 0x7239, [ 7624] = 0x7279, [ 7625] = 0x72FC, +- [ 7626] = 0x72F9, [ 7627] = 0x72FD, [ 7628] = 0x72F8, [ 7629] = 0x72F7, +- [ 7630] = 0x7386, [ 7631] = 0x73ED, [ 7632] = 0x7409, [ 7633] = 0x73EE, +- [ 7634] = 0x73E0, [ 7635] = 0x73EA, [ 7636] = 0x73DE, [ 7637] = 0x7554, +- [ 7638] = 0x755D, [ 7639] = 0x755C, [ 7640] = 0x755A, [ 7641] = 0x7559, +- [ 7642] = 0x75BE, [ 7643] = 0x75C5, [ 7644] = 0x75C7, [ 7645] = 0x75B2, +- [ 7646] = 0x75B3, [ 7647] = 0x75BD, [ 7648] = 0x75BC, [ 7649] = 0x75B9, +- [ 7650] = 0x75C2, [ 7651] = 0x75B8, [ 7652] = 0x768B, [ 7653] = 0x76B0, +- [ 7654] = 0x76CA, [ 7655] = 0x76CD, [ 7656] = 0x76CE, [ 7657] = 0x7729, +- [ 7658] = 0x771F, [ 7659] = 0x7720, [ 7660] = 0x7728, [ 7661] = 0x77E9, +- [ 7662] = 0x7830, [ 7663] = 0x7827, [ 7664] = 0x7838, [ 7665] = 0x781D, +- [ 7666] = 0x7834, [ 7667] = 0x7837, [ 7702] = 0x7825, [ 7703] = 0x782D, +- [ 7704] = 0x7820, [ 7705] = 0x781F, [ 7706] = 0x7832, [ 7707] = 0x7955, +- [ 7708] = 0x7950, [ 7709] = 0x7960, [ 7710] = 0x795F, [ 7711] = 0x7956, +- [ 7712] = 0x795E, [ 7713] = 0x795D, [ 7714] = 0x7957, [ 7715] = 0x795A, +- [ 7716] = 0x79E4, [ 7717] = 0x79E3, [ 7718] = 0x79E7, [ 7719] = 0x79DF, +- [ 7720] = 0x79E6, [ 7721] = 0x79E9, [ 7722] = 0x79D8, [ 7723] = 0x7A84, +- [ 7724] = 0x7A88, [ 7725] = 0x7AD9, [ 7726] = 0x7B06, [ 7727] = 0x7B11, +- [ 7728] = 0x7C89, [ 7729] = 0x7D21, [ 7730] = 0x7D17, [ 7731] = 0x7D0B, +- [ 7732] = 0x7D0A, [ 7733] = 0x7D20, [ 7734] = 0x7D22, [ 7735] = 0x7D14, +- [ 7736] = 0x7D10, [ 7737] = 0x7D15, [ 7738] = 0x7D1A, [ 7739] = 0x7D1C, +- [ 7740] = 0x7D0D, [ 7741] = 0x7D19, [ 7742] = 0x7D1B, [ 7743] = 0x7F3A, +- [ 7744] = 0x7F5F, [ 7745] = 0x7F94, [ 7746] = 0x7FC5, [ 7747] = 0x7FC1, +- [ 7748] = 0x8006, [ 7749] = 0x8018, [ 7750] = 0x8015, [ 7751] = 0x8019, +- [ 7752] = 0x8017, [ 7753] = 0x803D, [ 7754] = 0x803F, [ 7755] = 0x80F1, +- [ 7756] = 0x8102, [ 7757] = 0x80F0, [ 7758] = 0x8105, [ 7759] = 0x80ED, +- [ 7760] = 0x80F4, [ 7761] = 0x8106, [ 7762] = 0x80F8, [ 7763] = 0x80F3, +- [ 7764] = 0x8108, [ 7765] = 0x80FD, [ 7766] = 0x810A, [ 7767] = 0x80FC, +- [ 7768] = 0x80EF, [ 7769] = 0x81ED, [ 7770] = 0x81EC, [ 7771] = 0x8200, +- [ 7772] = 0x8210, [ 7773] = 0x822A, [ 7774] = 0x822B, [ 7775] = 0x8228, +- [ 7776] = 0x822C, [ 7777] = 0x82BB, [ 7778] = 0x832B, [ 7779] = 0x8352, +- [ 7780] = 0x8354, [ 7781] = 0x834A, [ 7782] = 0x8338, [ 7783] = 0x8350, +- [ 7784] = 0x8349, [ 7785] = 0x8335, [ 7786] = 0x8334, [ 7787] = 0x834F, +- [ 7788] = 0x8332, [ 7789] = 0x8339, [ 7790] = 0x8336, [ 7791] = 0x8317, +- [ 7792] = 0x8340, [ 7793] = 0x8331, [ 7794] = 0x8328, [ 7795] = 0x8343, +- [ 7800] = 0x8654, [ 7801] = 0x868A, [ 7802] = 0x86AA, [ 7803] = 0x8693, +- [ 7804] = 0x86A4, [ 7805] = 0x86A9, [ 7806] = 0x868C, [ 7807] = 0x86A3, +- [ 7808] = 0x869C, [ 7809] = 0x8870, [ 7810] = 0x8877, [ 7811] = 0x8881, +- [ 7812] = 0x8882, [ 7813] = 0x887D, [ 7814] = 0x8879, [ 7815] = 0x8A18, +- [ 7816] = 0x8A10, [ 7817] = 0x8A0E, [ 7818] = 0x8A0C, [ 7819] = 0x8A15, +- [ 7820] = 0x8A0A, [ 7821] = 0x8A17, [ 7822] = 0x8A13, [ 7823] = 0x8A16, +- [ 7824] = 0x8A0F, [ 7825] = 0x8A11, [ 7826] = 0x8C48, [ 7827] = 0x8C7A, +- [ 7828] = 0x8C79, [ 7829] = 0x8CA1, [ 7830] = 0x8CA2, [ 7831] = 0x8D77, +- [ 7832] = 0x8EAC, [ 7833] = 0x8ED2, [ 7834] = 0x8ED4, [ 7835] = 0x8ECF, +- [ 7836] = 0x8FB1, [ 7837] = 0x9001, [ 7838] = 0x9006, [ 7839] = 0x8FF7, +- [ 7840] = 0x9000, [ 7841] = 0x8FFA, [ 7842] = 0x8FF4, [ 7843] = 0x9003, +- [ 7844] = 0x8FFD, [ 7845] = 0x9005, [ 7846] = 0x8FF8, [ 7847] = 0x9095, +- [ 7848] = 0x90E1, [ 7849] = 0x90DD, [ 7850] = 0x90E2, [ 7851] = 0x9152, +- [ 7852] = 0x914D, [ 7853] = 0x914C, [ 7854] = 0x91D8, [ 7855] = 0x91DD, +- [ 7856] = 0x91D7, [ 7857] = 0x91DC, [ 7858] = 0x91D9, [ 7859] = 0x9583, +- [ 7860] = 0x9662, [ 7861] = 0x9663, [ 7862] = 0x9661, [ 7897] = 0x965B, +- [ 7898] = 0x965D, [ 7899] = 0x9664, [ 7900] = 0x9658, [ 7901] = 0x965E, +- [ 7902] = 0x96BB, [ 7903] = 0x98E2, [ 7904] = 0x99AC, [ 7905] = 0x9AA8, +- [ 7906] = 0x9AD8, [ 7907] = 0x9B25, [ 7908] = 0x9B32, [ 7909] = 0x9B3C, +- [ 7910] = 0x4E7E, [ 7911] = 0x507A, [ 7912] = 0x507D, [ 7913] = 0x505C, +- [ 7914] = 0x5047, [ 7915] = 0x5043, [ 7916] = 0x504C, [ 7917] = 0x505A, +- [ 7918] = 0x5049, [ 7919] = 0x5065, [ 7920] = 0x5076, [ 7921] = 0x504E, +- [ 7922] = 0x5055, [ 7923] = 0x5075, [ 7924] = 0x5074, [ 7925] = 0x5077, +- [ 7926] = 0x504F, [ 7927] = 0x500F, [ 7928] = 0x506F, [ 7929] = 0x506D, +- [ 7930] = 0x515C, [ 7931] = 0x5195, [ 7932] = 0x51F0, [ 7933] = 0x526A, +- [ 7934] = 0x526F, [ 7935] = 0x52D2, [ 7936] = 0x52D9, [ 7937] = 0x52D8, +- [ 7938] = 0x52D5, [ 7939] = 0x5310, [ 7940] = 0x530F, [ 7941] = 0x5319, +- [ 7942] = 0x533F, [ 7943] = 0x5340, [ 7944] = 0x533E, [ 7945] = 0x53C3, +- [ 7946] = 0x66FC, [ 7947] = 0x5546, [ 7948] = 0x556A, [ 7949] = 0x5566, +- [ 7950] = 0x5544, [ 7951] = 0x555E, [ 7952] = 0x5561, [ 7953] = 0x5543, +- [ 7954] = 0x554A, [ 7955] = 0x5531, [ 7956] = 0x5556, [ 7957] = 0x554F, +- [ 7958] = 0x5555, [ 7959] = 0x552F, [ 7960] = 0x5564, [ 7961] = 0x5538, +- [ 7962] = 0x552E, [ 7963] = 0x555C, [ 7964] = 0x552C, [ 7965] = 0x5563, +- [ 7966] = 0x5533, [ 7967] = 0x5541, [ 7968] = 0x5557, [ 7969] = 0x5708, +- [ 7970] = 0x570B, [ 7971] = 0x5709, [ 7972] = 0x57DF, [ 7973] = 0x5805, +- [ 7974] = 0x580A, [ 7975] = 0x5806, [ 7976] = 0x57E0, [ 7977] = 0x57E4, +- [ 7978] = 0x57FA, [ 7979] = 0x5802, [ 7980] = 0x5835, [ 7981] = 0x57F7, +- [ 7982] = 0x57F9, [ 7983] = 0x5920, [ 7984] = 0x5962, [ 7985] = 0x5A36, +- [ 7986] = 0x5A41, [ 7987] = 0x5A49, [ 7988] = 0x5A66, [ 7989] = 0x5A6A, +- [ 7990] = 0x5A40, [ 7995] = 0x5A3C, [ 7996] = 0x5A62, [ 7997] = 0x5A5A, +- [ 7998] = 0x5A46, [ 7999] = 0x5A4A, [ 8000] = 0x5B70, [ 8001] = 0x5BC7, +- [ 8002] = 0x5BC5, [ 8003] = 0x5BC4, [ 8004] = 0x5BC2, [ 8005] = 0x5BBF, +- [ 8006] = 0x5BC6, [ 8007] = 0x5C09, [ 8008] = 0x5C08, [ 8009] = 0x5C07, +- [ 8010] = 0x5C60, [ 8011] = 0x5C5C, [ 8012] = 0x5C5D, [ 8013] = 0x5D07, +- [ 8014] = 0x5D06, [ 8015] = 0x5D0E, [ 8016] = 0x5D1B, [ 8017] = 0x5D16, +- [ 8018] = 0x5D22, [ 8019] = 0x5D11, [ 8020] = 0x5D29, [ 8021] = 0x5D14, +- [ 8022] = 0x5D19, [ 8023] = 0x5D24, [ 8024] = 0x5D27, [ 8025] = 0x5D17, +- [ 8026] = 0x5DE2, [ 8027] = 0x5E38, [ 8028] = 0x5E36, [ 8029] = 0x5E33, +- [ 8030] = 0x5E37, [ 8031] = 0x5EB7, [ 8032] = 0x5EB8, [ 8033] = 0x5EB6, +- [ 8034] = 0x5EB5, [ 8035] = 0x5EBE, [ 8036] = 0x5F35, [ 8037] = 0x5F37, +- [ 8038] = 0x5F57, [ 8039] = 0x5F6C, [ 8040] = 0x5F69, [ 8041] = 0x5F6B, +- [ 8042] = 0x5F97, [ 8043] = 0x5F99, [ 8044] = 0x5F9E, [ 8045] = 0x5F98, +- [ 8046] = 0x5FA1, [ 8047] = 0x5FA0, [ 8048] = 0x5F9C, [ 8049] = 0x607F, +- [ 8050] = 0x60A3, [ 8051] = 0x6089, [ 8052] = 0x60A0, [ 8053] = 0x60A8, +- [ 8054] = 0x60CB, [ 8055] = 0x60B4, [ 8056] = 0x60E6, [ 8057] = 0x60BD, +- [ 8092] = 0x60C5, [ 8093] = 0x60BB, [ 8094] = 0x60B5, [ 8095] = 0x60DC, +- [ 8096] = 0x60BC, [ 8097] = 0x60D8, [ 8098] = 0x60D5, [ 8099] = 0x60C6, +- [ 8100] = 0x60DF, [ 8101] = 0x60B8, [ 8102] = 0x60DA, [ 8103] = 0x60C7, +- [ 8104] = 0x621A, [ 8105] = 0x621B, [ 8106] = 0x6248, [ 8107] = 0x63A0, +- [ 8108] = 0x63A7, [ 8109] = 0x6372, [ 8110] = 0x6396, [ 8111] = 0x63A2, +- [ 8112] = 0x63A5, [ 8113] = 0x6377, [ 8114] = 0x6367, [ 8115] = 0x6398, +- [ 8116] = 0x63AA, [ 8117] = 0x6371, [ 8118] = 0x63A9, [ 8119] = 0x6389, +- [ 8120] = 0x6383, [ 8121] = 0x639B, [ 8122] = 0x636B, [ 8123] = 0x63A8, +- [ 8124] = 0x6384, [ 8125] = 0x6388, [ 8126] = 0x6399, [ 8127] = 0x63A1, +- [ 8128] = 0x63AC, [ 8129] = 0x6392, [ 8130] = 0x638F, [ 8131] = 0x6380, +- [ 8132] = 0x637B, [ 8133] = 0x6369, [ 8134] = 0x6368, [ 8135] = 0x637A, +- [ 8136] = 0x655D, [ 8137] = 0x6556, [ 8138] = 0x6551, [ 8139] = 0x6559, +- [ 8140] = 0x6557, [ 8141] = 0x555F, [ 8142] = 0x654F, [ 8143] = 0x6558, +- [ 8144] = 0x6555, [ 8145] = 0x6554, [ 8146] = 0x659C, [ 8147] = 0x659B, +- [ 8148] = 0x65AC, [ 8149] = 0x65CF, [ 8150] = 0x65CB, [ 8151] = 0x65CC, +- [ 8152] = 0x65CE, [ 8153] = 0x665D, [ 8154] = 0x665A, [ 8155] = 0x6664, +- [ 8156] = 0x6668, [ 8157] = 0x6666, [ 8158] = 0x665E, [ 8159] = 0x66F9, +- [ 8160] = 0x52D7, [ 8161] = 0x671B, [ 8162] = 0x6881, [ 8163] = 0x68AF, +- [ 8164] = 0x68A2, [ 8165] = 0x6893, [ 8166] = 0x68B5, [ 8167] = 0x687F, +- [ 8168] = 0x6876, [ 8169] = 0x68B1, [ 8170] = 0x68A7, [ 8171] = 0x6897, +- [ 8172] = 0x68B0, [ 8173] = 0x6883, [ 8174] = 0x68C4, [ 8175] = 0x68AD, +- [ 8176] = 0x6886, [ 8177] = 0x6885, [ 8178] = 0x6894, [ 8179] = 0x689D, +- [ 8180] = 0x68A8, [ 8181] = 0x689F, [ 8182] = 0x68A1, [ 8183] = 0x6882, +- [ 8184] = 0x6B32, [ 8185] = 0x6BBA, [ 8190] = 0x6BEB, [ 8191] = 0x6BEC, +- [ 8192] = 0x6C2B, [ 8193] = 0x6D8E, [ 8194] = 0x6DBC, [ 8195] = 0x6DF3, +- [ 8196] = 0x6DD9, [ 8197] = 0x6DB2, [ 8198] = 0x6DE1, [ 8199] = 0x6DCC, +- [ 8200] = 0x6DE4, [ 8201] = 0x6DFB, [ 8202] = 0x6DFA, [ 8203] = 0x6E05, +- [ 8204] = 0x6DC7, [ 8205] = 0x6DCB, [ 8206] = 0x6DAF, [ 8207] = 0x6DD1, +- [ 8208] = 0x6DAE, [ 8209] = 0x6DDE, [ 8210] = 0x6DF9, [ 8211] = 0x6DB8, +- [ 8212] = 0x6DF7, [ 8213] = 0x6DF5, [ 8214] = 0x6DC5, [ 8215] = 0x6DD2, +- [ 8216] = 0x6E1A, [ 8217] = 0x6DB5, [ 8218] = 0x6DDA, [ 8219] = 0x6DEB, +- [ 8220] = 0x6DD8, [ 8221] = 0x6DEA, [ 8222] = 0x6DF1, [ 8223] = 0x6DEE, +- [ 8224] = 0x6DE8, [ 8225] = 0x6DC6, [ 8226] = 0x6DC4, [ 8227] = 0x6DAA, +- [ 8228] = 0x6DEC, [ 8229] = 0x6DBF, [ 8230] = 0x6DE6, [ 8231] = 0x70F9, +- [ 8232] = 0x7109, [ 8233] = 0x710A, [ 8234] = 0x70FD, [ 8235] = 0x70EF, +- [ 8236] = 0x723D, [ 8237] = 0x727D, [ 8238] = 0x7281, [ 8239] = 0x731C, +- [ 8240] = 0x731B, [ 8241] = 0x7316, [ 8242] = 0x7313, [ 8243] = 0x7319, +- [ 8244] = 0x7387, [ 8245] = 0x7405, [ 8246] = 0x740A, [ 8247] = 0x7403, +- [ 8248] = 0x7406, [ 8249] = 0x73FE, [ 8250] = 0x740D, [ 8251] = 0x74E0, +- [ 8252] = 0x74F6, [ 8287] = 0x74F7, [ 8288] = 0x751C, [ 8289] = 0x7522, +- [ 8290] = 0x7565, [ 8291] = 0x7566, [ 8292] = 0x7562, [ 8293] = 0x7570, +- [ 8294] = 0x758F, [ 8295] = 0x75D4, [ 8296] = 0x75D5, [ 8297] = 0x75B5, +- [ 8298] = 0x75CA, [ 8299] = 0x75CD, [ 8300] = 0x768E, [ 8301] = 0x76D4, +- [ 8302] = 0x76D2, [ 8303] = 0x76DB, [ 8304] = 0x7737, [ 8305] = 0x773E, +- [ 8306] = 0x773C, [ 8307] = 0x7736, [ 8308] = 0x7738, [ 8309] = 0x773A, +- [ 8310] = 0x786B, [ 8311] = 0x7843, [ 8312] = 0x784E, [ 8313] = 0x7965, +- [ 8314] = 0x7968, [ 8315] = 0x796D, [ 8316] = 0x79FB, [ 8317] = 0x7A92, +- [ 8318] = 0x7A95, [ 8319] = 0x7B20, [ 8320] = 0x7B28, [ 8321] = 0x7B1B, +- [ 8322] = 0x7B2C, [ 8323] = 0x7B26, [ 8324] = 0x7B19, [ 8325] = 0x7B1E, +- [ 8326] = 0x7B2E, [ 8327] = 0x7C92, [ 8328] = 0x7C97, [ 8329] = 0x7C95, +- [ 8330] = 0x7D46, [ 8331] = 0x7D43, [ 8332] = 0x7D71, [ 8333] = 0x7D2E, +- [ 8334] = 0x7D39, [ 8335] = 0x7D3C, [ 8336] = 0x7D40, [ 8337] = 0x7D30, +- [ 8338] = 0x7D33, [ 8339] = 0x7D44, [ 8340] = 0x7D2F, [ 8341] = 0x7D42, +- [ 8342] = 0x7D32, [ 8343] = 0x7D31, [ 8344] = 0x7F3D, [ 8345] = 0x7F9E, +- [ 8346] = 0x7F9A, [ 8347] = 0x7FCC, [ 8348] = 0x7FCE, [ 8349] = 0x7FD2, +- [ 8350] = 0x801C, [ 8351] = 0x804A, [ 8352] = 0x8046, [ 8353] = 0x812F, +- [ 8354] = 0x8116, [ 8355] = 0x8123, [ 8356] = 0x812B, [ 8357] = 0x8129, +- [ 8358] = 0x8130, [ 8359] = 0x8124, [ 8360] = 0x8202, [ 8361] = 0x8235, +- [ 8362] = 0x8237, [ 8363] = 0x8236, [ 8364] = 0x8239, [ 8365] = 0x838E, +- [ 8366] = 0x839E, [ 8367] = 0x8398, [ 8368] = 0x8378, [ 8369] = 0x83A2, +- [ 8370] = 0x8396, [ 8371] = 0x83BD, [ 8372] = 0x83AB, [ 8373] = 0x8392, +- [ 8374] = 0x838A, [ 8375] = 0x8393, [ 8376] = 0x8389, [ 8377] = 0x83A0, +- [ 8378] = 0x8377, [ 8379] = 0x837B, [ 8380] = 0x837C, [ 8385] = 0x8386, +- [ 8386] = 0x83A7, [ 8387] = 0x8655, [ 8388] = 0x5F6A, [ 8389] = 0x86C7, +- [ 8390] = 0x86C0, [ 8391] = 0x86B6, [ 8392] = 0x86C4, [ 8393] = 0x86B5, +- [ 8394] = 0x86C6, [ 8395] = 0x86CB, [ 8396] = 0x86B1, [ 8397] = 0x86AF, +- [ 8398] = 0x86C9, [ 8399] = 0x8853, [ 8400] = 0x889E, [ 8401] = 0x8888, +- [ 8402] = 0x88AB, [ 8403] = 0x8892, [ 8404] = 0x8896, [ 8405] = 0x888D, +- [ 8406] = 0x888B, [ 8407] = 0x8993, [ 8408] = 0x898F, [ 8409] = 0x8A2A, +- [ 8410] = 0x8A1D, [ 8411] = 0x8A23, [ 8412] = 0x8A25, [ 8413] = 0x8A31, +- [ 8414] = 0x8A2D, [ 8415] = 0x8A1F, [ 8416] = 0x8A1B, [ 8417] = 0x8A22, +- [ 8418] = 0x8C49, [ 8419] = 0x8C5A, [ 8420] = 0x8CA9, [ 8421] = 0x8CAC, +- [ 8422] = 0x8CAB, [ 8423] = 0x8CA8, [ 8424] = 0x8CAA, [ 8425] = 0x8CA7, +- [ 8426] = 0x8D67, [ 8427] = 0x8D66, [ 8428] = 0x8DBE, [ 8429] = 0x8DBA, +- [ 8430] = 0x8EDB, [ 8431] = 0x8EDF, [ 8432] = 0x9019, [ 8433] = 0x900D, +- [ 8434] = 0x901A, [ 8435] = 0x9017, [ 8436] = 0x9023, [ 8437] = 0x901F, +- [ 8438] = 0x901D, [ 8439] = 0x9010, [ 8440] = 0x9015, [ 8441] = 0x901E, +- [ 8442] = 0x9020, [ 8443] = 0x900F, [ 8444] = 0x9022, [ 8445] = 0x9016, +- [ 8446] = 0x901B, [ 8447] = 0x9014, [ 8482] = 0x90E8, [ 8483] = 0x90ED, +- [ 8484] = 0x90FD, [ 8485] = 0x9157, [ 8486] = 0x91CE, [ 8487] = 0x91F5, +- [ 8488] = 0x91E6, [ 8489] = 0x91E3, [ 8490] = 0x91E7, [ 8491] = 0x91ED, +- [ 8492] = 0x91E9, [ 8493] = 0x9589, [ 8494] = 0x966A, [ 8495] = 0x9675, +- [ 8496] = 0x9673, [ 8497] = 0x9678, [ 8498] = 0x9670, [ 8499] = 0x9674, +- [ 8500] = 0x9676, [ 8501] = 0x9677, [ 8502] = 0x966C, [ 8503] = 0x96C0, +- [ 8504] = 0x96EA, [ 8505] = 0x96E9, [ 8506] = 0x7AE0, [ 8507] = 0x7ADF, +- [ 8508] = 0x9802, [ 8509] = 0x9803, [ 8510] = 0x9B5A, [ 8511] = 0x9CE5, +- [ 8512] = 0x9E75, [ 8513] = 0x9E7F, [ 8514] = 0x9EA5, [ 8515] = 0x9EBB, +- [ 8516] = 0x50A2, [ 8517] = 0x508D, [ 8518] = 0x5085, [ 8519] = 0x5099, +- [ 8520] = 0x5091, [ 8521] = 0x5080, [ 8522] = 0x5096, [ 8523] = 0x5098, +- [ 8524] = 0x509A, [ 8525] = 0x6700, [ 8526] = 0x51F1, [ 8527] = 0x5272, +- [ 8528] = 0x5274, [ 8529] = 0x5275, [ 8530] = 0x5269, [ 8531] = 0x52DE, +- [ 8532] = 0x52DD, [ 8533] = 0x52DB, [ 8534] = 0x535A, [ 8535] = 0x53A5, +- [ 8536] = 0x557B, [ 8537] = 0x5580, [ 8538] = 0x55A7, [ 8539] = 0x557C, +- [ 8540] = 0x558A, [ 8541] = 0x559D, [ 8542] = 0x5598, [ 8543] = 0x5582, +- [ 8544] = 0x559C, [ 8545] = 0x55AA, [ 8546] = 0x5594, [ 8547] = 0x5587, +- [ 8548] = 0x558B, [ 8549] = 0x5583, [ 8550] = 0x55B3, [ 8551] = 0x55AE, +- [ 8552] = 0x559F, [ 8553] = 0x553E, [ 8554] = 0x55B2, [ 8555] = 0x559A, +- [ 8556] = 0x55BB, [ 8557] = 0x55AC, [ 8558] = 0x55B1, [ 8559] = 0x557E, +- [ 8560] = 0x5589, [ 8561] = 0x55AB, [ 8562] = 0x5599, [ 8563] = 0x570D, +- [ 8564] = 0x582F, [ 8565] = 0x582A, [ 8566] = 0x5834, [ 8567] = 0x5824, +- [ 8568] = 0x5830, [ 8569] = 0x5831, [ 8570] = 0x5821, [ 8571] = 0x581D, +- [ 8572] = 0x5820, [ 8573] = 0x58F9, [ 8574] = 0x58FA, [ 8575] = 0x5960, +- [ 8580] = 0x5A77, [ 8581] = 0x5A9A, [ 8582] = 0x5A7F, [ 8583] = 0x5A92, +- [ 8584] = 0x5A9B, [ 8585] = 0x5AA7, [ 8586] = 0x5B73, [ 8587] = 0x5B71, +- [ 8588] = 0x5BD2, [ 8589] = 0x5BCC, [ 8590] = 0x5BD3, [ 8591] = 0x5BD0, +- [ 8592] = 0x5C0A, [ 8593] = 0x5C0B, [ 8594] = 0x5C31, [ 8595] = 0x5D4C, +- [ 8596] = 0x5D50, [ 8597] = 0x5D34, [ 8598] = 0x5D47, [ 8599] = 0x5DFD, +- [ 8600] = 0x5E45, [ 8601] = 0x5E3D, [ 8602] = 0x5E40, [ 8603] = 0x5E43, +- [ 8604] = 0x5E7E, [ 8605] = 0x5ECA, [ 8606] = 0x5EC1, [ 8607] = 0x5EC2, +- [ 8608] = 0x5EC4, [ 8609] = 0x5F3C, [ 8610] = 0x5F6D, [ 8611] = 0x5FA9, +- [ 8612] = 0x5FAA, [ 8613] = 0x5FA8, [ 8614] = 0x60D1, [ 8615] = 0x60E1, +- [ 8616] = 0x60B2, [ 8617] = 0x60B6, [ 8618] = 0x60E0, [ 8619] = 0x611C, +- [ 8620] = 0x6123, [ 8621] = 0x60FA, [ 8622] = 0x6115, [ 8623] = 0x60F0, +- [ 8624] = 0x60FB, [ 8625] = 0x60F4, [ 8626] = 0x6168, [ 8627] = 0x60F1, +- [ 8628] = 0x610E, [ 8629] = 0x60F6, [ 8630] = 0x6109, [ 8631] = 0x6100, +- [ 8632] = 0x6112, [ 8633] = 0x621F, [ 8634] = 0x6249, [ 8635] = 0x63A3, +- [ 8636] = 0x638C, [ 8637] = 0x63CF, [ 8638] = 0x63C0, [ 8639] = 0x63E9, +- [ 8640] = 0x63C9, [ 8641] = 0x63C6, [ 8642] = 0x63CD, [ 8677] = 0x63D2, +- [ 8678] = 0x63E3, [ 8679] = 0x63D0, [ 8680] = 0x63E1, [ 8681] = 0x63D6, +- [ 8682] = 0x63ED, [ 8683] = 0x63EE, [ 8684] = 0x6376, [ 8685] = 0x63F4, +- [ 8686] = 0x63EA, [ 8687] = 0x63DB, [ 8688] = 0x6452, [ 8689] = 0x63DA, +- [ 8690] = 0x63F9, [ 8691] = 0x655E, [ 8692] = 0x6566, [ 8693] = 0x6562, +- [ 8694] = 0x6563, [ 8695] = 0x6591, [ 8696] = 0x6590, [ 8697] = 0x65AF, +- [ 8698] = 0x666E, [ 8699] = 0x6670, [ 8700] = 0x6674, [ 8701] = 0x6676, +- [ 8702] = 0x666F, [ 8703] = 0x6691, [ 8704] = 0x667A, [ 8705] = 0x667E, +- [ 8706] = 0x6677, [ 8707] = 0x66FE, [ 8708] = 0x66FF, [ 8709] = 0x671F, +- [ 8710] = 0x671D, [ 8711] = 0x68FA, [ 8712] = 0x68D5, [ 8713] = 0x68E0, +- [ 8714] = 0x68D8, [ 8715] = 0x68D7, [ 8716] = 0x6905, [ 8717] = 0x68DF, +- [ 8718] = 0x68F5, [ 8719] = 0x68EE, [ 8720] = 0x68E7, [ 8721] = 0x68F9, +- [ 8722] = 0x68D2, [ 8723] = 0x68F2, [ 8724] = 0x68E3, [ 8725] = 0x68CB, +- [ 8726] = 0x68CD, [ 8727] = 0x690D, [ 8728] = 0x6912, [ 8729] = 0x690E, +- [ 8730] = 0x68C9, [ 8731] = 0x68DA, [ 8732] = 0x696E, [ 8733] = 0x68FB, +- [ 8734] = 0x6B3E, [ 8735] = 0x6B3A, [ 8736] = 0x6B3D, [ 8737] = 0x6B98, +- [ 8738] = 0x6B96, [ 8739] = 0x6BBC, [ 8740] = 0x6BEF, [ 8741] = 0x6C2E, +- [ 8742] = 0x6C2F, [ 8743] = 0x6C2C, [ 8744] = 0x6E2F, [ 8745] = 0x6E38, +- [ 8746] = 0x6E54, [ 8747] = 0x6E21, [ 8748] = 0x6E32, [ 8749] = 0x6E67, +- [ 8750] = 0x6E4A, [ 8751] = 0x6E20, [ 8752] = 0x6E25, [ 8753] = 0x6E23, +- [ 8754] = 0x6E1B, [ 8755] = 0x6E5B, [ 8756] = 0x6E58, [ 8757] = 0x6E24, +- [ 8758] = 0x6E56, [ 8759] = 0x6E6E, [ 8760] = 0x6E2D, [ 8761] = 0x6E26, +- [ 8762] = 0x6E6F, [ 8763] = 0x6E34, [ 8764] = 0x6E4D, [ 8765] = 0x6E3A, +- [ 8766] = 0x6E2C, [ 8767] = 0x6E43, [ 8768] = 0x6E1D, [ 8769] = 0x6E3E, +- [ 8770] = 0x6ECB, [ 8775] = 0x6E89, [ 8776] = 0x6E19, [ 8777] = 0x6E4E, +- [ 8778] = 0x6E63, [ 8779] = 0x6E44, [ 8780] = 0x6E72, [ 8781] = 0x6E69, +- [ 8782] = 0x6E5F, [ 8783] = 0x7119, [ 8784] = 0x711A, [ 8785] = 0x7126, +- [ 8786] = 0x7130, [ 8787] = 0x7121, [ 8788] = 0x7136, [ 8789] = 0x716E, +- [ 8790] = 0x711C, [ 8791] = 0x724C, [ 8792] = 0x7284, [ 8793] = 0x7280, +- [ 8794] = 0x7336, [ 8795] = 0x7325, [ 8796] = 0x7334, [ 8797] = 0x7329, +- [ 8798] = 0x743A, [ 8799] = 0x742A, [ 8800] = 0x7433, [ 8801] = 0x7422, +- [ 8802] = 0x7425, [ 8803] = 0x7435, [ 8804] = 0x7436, [ 8805] = 0x7434, +- [ 8806] = 0x742F, [ 8807] = 0x741B, [ 8808] = 0x7426, [ 8809] = 0x7428, +- [ 8810] = 0x7525, [ 8811] = 0x7526, [ 8812] = 0x756B, [ 8813] = 0x756A, +- [ 8814] = 0x75E2, [ 8815] = 0x75DB, [ 8816] = 0x75E3, [ 8817] = 0x75D9, +- [ 8818] = 0x75D8, [ 8819] = 0x75DE, [ 8820] = 0x75E0, [ 8821] = 0x767B, +- [ 8822] = 0x767C, [ 8823] = 0x7696, [ 8824] = 0x7693, [ 8825] = 0x76B4, +- [ 8826] = 0x76DC, [ 8827] = 0x774F, [ 8828] = 0x77ED, [ 8829] = 0x785D, +- [ 8830] = 0x786C, [ 8831] = 0x786F, [ 8832] = 0x7A0D, [ 8833] = 0x7A08, +- [ 8834] = 0x7A0B, [ 8835] = 0x7A05, [ 8836] = 0x7A00, [ 8837] = 0x7A98, +- [ 8872] = 0x7A97, [ 8873] = 0x7A96, [ 8874] = 0x7AE5, [ 8875] = 0x7AE3, +- [ 8876] = 0x7B49, [ 8877] = 0x7B56, [ 8878] = 0x7B46, [ 8879] = 0x7B50, +- [ 8880] = 0x7B52, [ 8881] = 0x7B54, [ 8882] = 0x7B4D, [ 8883] = 0x7B4B, +- [ 8884] = 0x7B4F, [ 8885] = 0x7B51, [ 8886] = 0x7C9F, [ 8887] = 0x7CA5, +- [ 8888] = 0x7D5E, [ 8889] = 0x7D50, [ 8890] = 0x7D68, [ 8891] = 0x7D55, +- [ 8892] = 0x7D2B, [ 8893] = 0x7D6E, [ 8894] = 0x7D72, [ 8895] = 0x7D61, +- [ 8896] = 0x7D66, [ 8897] = 0x7D62, [ 8898] = 0x7D70, [ 8899] = 0x7D73, +- [ 8900] = 0x5584, [ 8901] = 0x7FD4, [ 8902] = 0x7FD5, [ 8903] = 0x800B, +- [ 8904] = 0x8052, [ 8905] = 0x8085, [ 8906] = 0x8155, [ 8907] = 0x8154, +- [ 8908] = 0x814B, [ 8909] = 0x8151, [ 8910] = 0x814E, [ 8911] = 0x8139, +- [ 8912] = 0x8146, [ 8913] = 0x813E, [ 8914] = 0x814C, [ 8915] = 0x8153, +- [ 8916] = 0x8174, [ 8917] = 0x8212, [ 8918] = 0x821C, [ 8919] = 0x83E9, +- [ 8920] = 0x8403, [ 8921] = 0x83F8, [ 8922] = 0x840D, [ 8923] = 0x83E0, +- [ 8924] = 0x83C5, [ 8925] = 0x840B, [ 8926] = 0x83C1, [ 8927] = 0x83EF, +- [ 8928] = 0x83F1, [ 8929] = 0x83F4, [ 8930] = 0x8457, [ 8931] = 0x840A, +- [ 8932] = 0x83F0, [ 8933] = 0x840C, [ 8934] = 0x83CC, [ 8935] = 0x83FD, +- [ 8936] = 0x83F2, [ 8937] = 0x83CA, [ 8938] = 0x8438, [ 8939] = 0x840E, +- [ 8940] = 0x8404, [ 8941] = 0x83DC, [ 8942] = 0x8407, [ 8943] = 0x83D4, +- [ 8944] = 0x83DF, [ 8945] = 0x865B, [ 8946] = 0x86DF, [ 8947] = 0x86D9, +- [ 8948] = 0x86ED, [ 8949] = 0x86D4, [ 8950] = 0x86DB, [ 8951] = 0x86E4, +- [ 8952] = 0x86D0, [ 8953] = 0x86DE, [ 8954] = 0x8857, [ 8955] = 0x88C1, +- [ 8956] = 0x88C2, [ 8957] = 0x88B1, [ 8958] = 0x8983, [ 8959] = 0x8996, +- [ 8960] = 0x8A3B, [ 8961] = 0x8A60, [ 8962] = 0x8A55, [ 8963] = 0x8A5E, +- [ 8964] = 0x8A3C, [ 8965] = 0x8A41, [ 8970] = 0x8A54, [ 8971] = 0x8A5B, +- [ 8972] = 0x8A50, [ 8973] = 0x8A46, [ 8974] = 0x8A34, [ 8975] = 0x8A3A, +- [ 8976] = 0x8A36, [ 8977] = 0x8A56, [ 8978] = 0x8C61, [ 8979] = 0x8C82, +- [ 8980] = 0x8CAF, [ 8981] = 0x8CBC, [ 8982] = 0x8CB3, [ 8983] = 0x8CBD, +- [ 8984] = 0x8CC1, [ 8985] = 0x8CBB, [ 8986] = 0x8CC0, [ 8987] = 0x8CB4, +- [ 8988] = 0x8CB7, [ 8989] = 0x8CB6, [ 8990] = 0x8CBF, [ 8991] = 0x8CB8, +- [ 8992] = 0x8D8A, [ 8993] = 0x8D85, [ 8994] = 0x8D81, [ 8995] = 0x8DCE, +- [ 8996] = 0x8DDD, [ 8997] = 0x8DCB, [ 8998] = 0x8DDA, [ 8999] = 0x8DD1, +- [ 9000] = 0x8DCC, [ 9001] = 0x8DDB, [ 9002] = 0x8DC6, [ 9003] = 0x8EFB, +- [ 9004] = 0x8EF8, [ 9005] = 0x8EFC, [ 9006] = 0x8F9C, [ 9007] = 0x902E, +- [ 9008] = 0x9035, [ 9009] = 0x9031, [ 9010] = 0x9038, [ 9011] = 0x9032, +- [ 9012] = 0x9036, [ 9013] = 0x9102, [ 9014] = 0x90F5, [ 9015] = 0x9109, +- [ 9016] = 0x90FE, [ 9017] = 0x9163, [ 9018] = 0x9165, [ 9019] = 0x91CF, +- [ 9020] = 0x9214, [ 9021] = 0x9215, [ 9022] = 0x9223, [ 9023] = 0x9209, +- [ 9024] = 0x921E, [ 9025] = 0x920D, [ 9026] = 0x9210, [ 9027] = 0x9207, +- [ 9028] = 0x9211, [ 9029] = 0x9594, [ 9030] = 0x958F, [ 9031] = 0x958B, +- [ 9032] = 0x9591, [ 9067] = 0x9593, [ 9068] = 0x9592, [ 9069] = 0x958E, +- [ 9070] = 0x968A, [ 9071] = 0x968E, [ 9072] = 0x968B, [ 9073] = 0x967D, +- [ 9074] = 0x9685, [ 9075] = 0x9686, [ 9076] = 0x968D, [ 9077] = 0x9672, +- [ 9078] = 0x9684, [ 9079] = 0x96C1, [ 9080] = 0x96C5, [ 9081] = 0x96C4, +- [ 9082] = 0x96C6, [ 9083] = 0x96C7, [ 9084] = 0x96EF, [ 9085] = 0x96F2, +- [ 9086] = 0x97CC, [ 9087] = 0x9805, [ 9088] = 0x9806, [ 9089] = 0x9808, +- [ 9090] = 0x98E7, [ 9091] = 0x98EA, [ 9092] = 0x98EF, [ 9093] = 0x98E9, +- [ 9094] = 0x98F2, [ 9095] = 0x98ED, [ 9096] = 0x99AE, [ 9097] = 0x99AD, +- [ 9098] = 0x9EC3, [ 9099] = 0x9ECD, [ 9100] = 0x9ED1, [ 9101] = 0x4E82, +- [ 9102] = 0x50AD, [ 9103] = 0x50B5, [ 9104] = 0x50B2, [ 9105] = 0x50B3, +- [ 9106] = 0x50C5, [ 9107] = 0x50BE, [ 9108] = 0x50AC, [ 9109] = 0x50B7, +- [ 9110] = 0x50BB, [ 9111] = 0x50AF, [ 9112] = 0x50C7, [ 9113] = 0x527F, +- [ 9114] = 0x5277, [ 9115] = 0x527D, [ 9116] = 0x52DF, [ 9117] = 0x52E6, +- [ 9118] = 0x52E4, [ 9119] = 0x52E2, [ 9120] = 0x52E3, [ 9121] = 0x532F, +- [ 9122] = 0x55DF, [ 9123] = 0x55E8, [ 9124] = 0x55D3, [ 9125] = 0x55E6, +- [ 9126] = 0x55CE, [ 9127] = 0x55DC, [ 9128] = 0x55C7, [ 9129] = 0x55D1, +- [ 9130] = 0x55E3, [ 9131] = 0x55E4, [ 9132] = 0x55EF, [ 9133] = 0x55DA, +- [ 9134] = 0x55E1, [ 9135] = 0x55C5, [ 9136] = 0x55C6, [ 9137] = 0x55E5, +- [ 9138] = 0x55C9, [ 9139] = 0x5712, [ 9140] = 0x5713, [ 9141] = 0x585E, +- [ 9142] = 0x5851, [ 9143] = 0x5858, [ 9144] = 0x5857, [ 9145] = 0x585A, +- [ 9146] = 0x5854, [ 9147] = 0x586B, [ 9148] = 0x584C, [ 9149] = 0x586D, +- [ 9150] = 0x584A, [ 9151] = 0x5862, [ 9152] = 0x5852, [ 9153] = 0x584B, +- [ 9154] = 0x5967, [ 9155] = 0x5AC1, [ 9156] = 0x5AC9, [ 9157] = 0x5ACC, +- [ 9158] = 0x5ABE, [ 9159] = 0x5ABD, [ 9160] = 0x5ABC, [ 9165] = 0x5AB3, +- [ 9166] = 0x5AC2, [ 9167] = 0x5AB2, [ 9168] = 0x5D69, [ 9169] = 0x5D6F, +- [ 9170] = 0x5E4C, [ 9171] = 0x5E79, [ 9172] = 0x5EC9, [ 9173] = 0x5EC8, +- [ 9174] = 0x5F12, [ 9175] = 0x5F59, [ 9176] = 0x5FAC, [ 9177] = 0x5FAE, +- [ 9178] = 0x611A, [ 9179] = 0x610F, [ 9180] = 0x6148, [ 9181] = 0x611F, +- [ 9182] = 0x60F3, [ 9183] = 0x611B, [ 9184] = 0x60F9, [ 9185] = 0x6101, +- [ 9186] = 0x6108, [ 9187] = 0x614E, [ 9188] = 0x614C, [ 9189] = 0x6144, +- [ 9190] = 0x614D, [ 9191] = 0x613E, [ 9192] = 0x6134, [ 9193] = 0x6127, +- [ 9194] = 0x610D, [ 9195] = 0x6106, [ 9196] = 0x6137, [ 9197] = 0x6221, +- [ 9198] = 0x6222, [ 9199] = 0x6413, [ 9200] = 0x643E, [ 9201] = 0x641E, +- [ 9202] = 0x642A, [ 9203] = 0x642D, [ 9204] = 0x643D, [ 9205] = 0x642C, +- [ 9206] = 0x640F, [ 9207] = 0x641C, [ 9208] = 0x6414, [ 9209] = 0x640D, +- [ 9210] = 0x6436, [ 9211] = 0x6416, [ 9212] = 0x6417, [ 9213] = 0x6406, +- [ 9214] = 0x656C, [ 9215] = 0x659F, [ 9216] = 0x65B0, [ 9217] = 0x6697, +- [ 9218] = 0x6689, [ 9219] = 0x6687, [ 9220] = 0x6688, [ 9221] = 0x6696, +- [ 9222] = 0x6684, [ 9223] = 0x6698, [ 9224] = 0x668D, [ 9225] = 0x6703, +- [ 9226] = 0x6994, [ 9227] = 0x696D, [ 9262] = 0x695A, [ 9263] = 0x6977, +- [ 9264] = 0x6960, [ 9265] = 0x6954, [ 9266] = 0x6975, [ 9267] = 0x6930, +- [ 9268] = 0x6982, [ 9269] = 0x694A, [ 9270] = 0x6968, [ 9271] = 0x696B, +- [ 9272] = 0x695E, [ 9273] = 0x6953, [ 9274] = 0x6979, [ 9275] = 0x6986, +- [ 9276] = 0x695D, [ 9277] = 0x6963, [ 9278] = 0x695B, [ 9279] = 0x6B47, +- [ 9280] = 0x6B72, [ 9281] = 0x6BC0, [ 9282] = 0x6BBF, [ 9283] = 0x6BD3, +- [ 9284] = 0x6BFD, [ 9285] = 0x6EA2, [ 9286] = 0x6EAF, [ 9287] = 0x6ED3, +- [ 9288] = 0x6EB6, [ 9289] = 0x6EC2, [ 9290] = 0x6E90, [ 9291] = 0x6E9D, +- [ 9292] = 0x6EC7, [ 9293] = 0x6EC5, [ 9294] = 0x6EA5, [ 9295] = 0x6E98, +- [ 9296] = 0x6EBC, [ 9297] = 0x6EBA, [ 9298] = 0x6EAB, [ 9299] = 0x6ED1, +- [ 9300] = 0x6E96, [ 9301] = 0x6E9C, [ 9302] = 0x6EC4, [ 9303] = 0x6ED4, +- [ 9304] = 0x6EAA, [ 9305] = 0x6EA7, [ 9306] = 0x6EB4, [ 9307] = 0x714E, +- [ 9308] = 0x7159, [ 9309] = 0x7169, [ 9310] = 0x7164, [ 9311] = 0x7149, +- [ 9312] = 0x7167, [ 9313] = 0x715C, [ 9314] = 0x716C, [ 9315] = 0x7166, +- [ 9316] = 0x714C, [ 9317] = 0x7165, [ 9318] = 0x715E, [ 9319] = 0x7146, +- [ 9320] = 0x7168, [ 9321] = 0x7156, [ 9322] = 0x723A, [ 9323] = 0x7252, +- [ 9324] = 0x7337, [ 9325] = 0x7345, [ 9326] = 0x733F, [ 9327] = 0x733E, +- [ 9328] = 0x746F, [ 9329] = 0x745A, [ 9330] = 0x7455, [ 9331] = 0x745F, +- [ 9332] = 0x745E, [ 9333] = 0x7441, [ 9334] = 0x743F, [ 9335] = 0x7459, +- [ 9336] = 0x745B, [ 9337] = 0x745C, [ 9338] = 0x7576, [ 9339] = 0x7578, +- [ 9340] = 0x7600, [ 9341] = 0x75F0, [ 9342] = 0x7601, [ 9343] = 0x75F2, +- [ 9344] = 0x75F1, [ 9345] = 0x75FA, [ 9346] = 0x75FF, [ 9347] = 0x75F4, +- [ 9348] = 0x75F3, [ 9349] = 0x76DE, [ 9350] = 0x76DF, [ 9351] = 0x775B, +- [ 9352] = 0x776B, [ 9353] = 0x7766, [ 9354] = 0x775E, [ 9355] = 0x7763, +- [ 9360] = 0x7779, [ 9361] = 0x776A, [ 9362] = 0x776C, [ 9363] = 0x775C, +- [ 9364] = 0x7765, [ 9365] = 0x7768, [ 9366] = 0x7762, [ 9367] = 0x77EE, +- [ 9368] = 0x788E, [ 9369] = 0x78B0, [ 9370] = 0x7897, [ 9371] = 0x7898, +- [ 9372] = 0x788C, [ 9373] = 0x7889, [ 9374] = 0x787C, [ 9375] = 0x7891, +- [ 9376] = 0x7893, [ 9377] = 0x787F, [ 9378] = 0x797A, [ 9379] = 0x797F, +- [ 9380] = 0x7981, [ 9381] = 0x842C, [ 9382] = 0x79BD, [ 9383] = 0x7A1C, +- [ 9384] = 0x7A1A, [ 9385] = 0x7A20, [ 9386] = 0x7A14, [ 9387] = 0x7A1F, +- [ 9388] = 0x7A1E, [ 9389] = 0x7A9F, [ 9390] = 0x7AA0, [ 9391] = 0x7B77, +- [ 9392] = 0x7BC0, [ 9393] = 0x7B60, [ 9394] = 0x7B6E, [ 9395] = 0x7B67, +- [ 9396] = 0x7CB1, [ 9397] = 0x7CB3, [ 9398] = 0x7CB5, [ 9399] = 0x7D93, +- [ 9400] = 0x7D79, [ 9401] = 0x7D91, [ 9402] = 0x7D81, [ 9403] = 0x7D8F, +- [ 9404] = 0x7D5B, [ 9405] = 0x7F6E, [ 9406] = 0x7F69, [ 9407] = 0x7F6A, +- [ 9408] = 0x7F72, [ 9409] = 0x7FA9, [ 9410] = 0x7FA8, [ 9411] = 0x7FA4, +- [ 9412] = 0x8056, [ 9413] = 0x8058, [ 9414] = 0x8086, [ 9415] = 0x8084, +- [ 9416] = 0x8171, [ 9417] = 0x8170, [ 9418] = 0x8178, [ 9419] = 0x8165, +- [ 9420] = 0x816E, [ 9421] = 0x8173, [ 9422] = 0x816B, [ 9457] = 0x8179, +- [ 9458] = 0x817A, [ 9459] = 0x8166, [ 9460] = 0x8205, [ 9461] = 0x8247, +- [ 9462] = 0x8482, [ 9463] = 0x8477, [ 9464] = 0x843D, [ 9465] = 0x8431, +- [ 9466] = 0x8475, [ 9467] = 0x8466, [ 9468] = 0x846B, [ 9469] = 0x8449, +- [ 9470] = 0x846C, [ 9471] = 0x845B, [ 9472] = 0x843C, [ 9473] = 0x8435, +- [ 9474] = 0x8461, [ 9475] = 0x8463, [ 9476] = 0x8469, [ 9477] = 0x846D, +- [ 9478] = 0x8446, [ 9479] = 0x865E, [ 9480] = 0x865C, [ 9481] = 0x865F, +- [ 9482] = 0x86F9, [ 9483] = 0x8713, [ 9484] = 0x8708, [ 9485] = 0x8707, +- [ 9486] = 0x8700, [ 9487] = 0x86FE, [ 9488] = 0x86FB, [ 9489] = 0x8702, +- [ 9490] = 0x8703, [ 9491] = 0x8706, [ 9492] = 0x870A, [ 9493] = 0x8859, +- [ 9494] = 0x88DF, [ 9495] = 0x88D4, [ 9496] = 0x88D9, [ 9497] = 0x88DC, +- [ 9498] = 0x88D8, [ 9499] = 0x88DD, [ 9500] = 0x88E1, [ 9501] = 0x88CA, +- [ 9502] = 0x88D5, [ 9503] = 0x88D2, [ 9504] = 0x899C, [ 9505] = 0x89E3, +- [ 9506] = 0x8A6B, [ 9507] = 0x8A72, [ 9508] = 0x8A73, [ 9509] = 0x8A66, +- [ 9510] = 0x8A69, [ 9511] = 0x8A70, [ 9512] = 0x8A87, [ 9513] = 0x8A7C, +- [ 9514] = 0x8A63, [ 9515] = 0x8AA0, [ 9516] = 0x8A71, [ 9517] = 0x8A85, +- [ 9518] = 0x8A6D, [ 9519] = 0x8A62, [ 9520] = 0x8A6E, [ 9521] = 0x8A6C, +- [ 9522] = 0x8A79, [ 9523] = 0x8A7B, [ 9524] = 0x8A3E, [ 9525] = 0x8A68, +- [ 9526] = 0x8C62, [ 9527] = 0x8C8A, [ 9528] = 0x8C89, [ 9529] = 0x8CCA, +- [ 9530] = 0x8CC7, [ 9531] = 0x8CC8, [ 9532] = 0x8CC4, [ 9533] = 0x8CB2, +- [ 9534] = 0x8CC3, [ 9535] = 0x8CC2, [ 9536] = 0x8CC5, [ 9537] = 0x8DE1, +- [ 9538] = 0x8DDF, [ 9539] = 0x8DE8, [ 9540] = 0x8DEF, [ 9541] = 0x8DF3, +- [ 9542] = 0x8DFA, [ 9543] = 0x8DEA, [ 9544] = 0x8DE4, [ 9545] = 0x8DE6, +- [ 9546] = 0x8EB2, [ 9547] = 0x8F03, [ 9548] = 0x8F09, [ 9549] = 0x8EFE, +- [ 9550] = 0x8F0A, [ 9555] = 0x8F9F, [ 9556] = 0x8FB2, [ 9557] = 0x904B, +- [ 9558] = 0x904A, [ 9559] = 0x9053, [ 9560] = 0x9042, [ 9561] = 0x9054, +- [ 9562] = 0x903C, [ 9563] = 0x9055, [ 9564] = 0x9050, [ 9565] = 0x9047, +- [ 9566] = 0x904F, [ 9567] = 0x904E, [ 9568] = 0x904D, [ 9569] = 0x9051, +- [ 9570] = 0x903E, [ 9571] = 0x9041, [ 9572] = 0x9112, [ 9573] = 0x9117, +- [ 9574] = 0x916C, [ 9575] = 0x916A, [ 9576] = 0x9169, [ 9577] = 0x91C9, +- [ 9578] = 0x9237, [ 9579] = 0x9257, [ 9580] = 0x9238, [ 9581] = 0x923D, +- [ 9582] = 0x9240, [ 9583] = 0x923E, [ 9584] = 0x925B, [ 9585] = 0x924B, +- [ 9586] = 0x9264, [ 9587] = 0x9251, [ 9588] = 0x9234, [ 9589] = 0x9249, +- [ 9590] = 0x924D, [ 9591] = 0x9245, [ 9592] = 0x9239, [ 9593] = 0x923F, +- [ 9594] = 0x925A, [ 9595] = 0x9598, [ 9596] = 0x9698, [ 9597] = 0x9694, +- [ 9598] = 0x9695, [ 9599] = 0x96CD, [ 9600] = 0x96CB, [ 9601] = 0x96C9, +- [ 9602] = 0x96CA, [ 9603] = 0x96F7, [ 9604] = 0x96FB, [ 9605] = 0x96F9, +- [ 9606] = 0x96F6, [ 9607] = 0x9756, [ 9608] = 0x9774, [ 9609] = 0x9776, +- [ 9610] = 0x9810, [ 9611] = 0x9811, [ 9612] = 0x9813, [ 9613] = 0x980A, +- [ 9614] = 0x9812, [ 9615] = 0x980C, [ 9616] = 0x98FC, [ 9617] = 0x98F4, +- [ 9652] = 0x98FD, [ 9653] = 0x98FE, [ 9654] = 0x99B3, [ 9655] = 0x99B1, +- [ 9656] = 0x99B4, [ 9657] = 0x9AE1, [ 9658] = 0x9CE9, [ 9659] = 0x9E82, +- [ 9660] = 0x9F0E, [ 9661] = 0x9F13, [ 9662] = 0x9F20, [ 9663] = 0x50E7, +- [ 9664] = 0x50EE, [ 9665] = 0x50E5, [ 9666] = 0x50D6, [ 9667] = 0x50ED, +- [ 9668] = 0x50DA, [ 9669] = 0x50D5, [ 9670] = 0x50CF, [ 9671] = 0x50D1, +- [ 9672] = 0x50F1, [ 9673] = 0x50CE, [ 9674] = 0x50E9, [ 9675] = 0x5162, +- [ 9676] = 0x51F3, [ 9677] = 0x5283, [ 9678] = 0x5282, [ 9679] = 0x5331, +- [ 9680] = 0x53AD, [ 9681] = 0x55FE, [ 9682] = 0x5600, [ 9683] = 0x561B, +- [ 9684] = 0x5617, [ 9685] = 0x55FD, [ 9686] = 0x5614, [ 9687] = 0x5606, +- [ 9688] = 0x5609, [ 9689] = 0x560D, [ 9690] = 0x560E, [ 9691] = 0x55F7, +- [ 9692] = 0x5616, [ 9693] = 0x561F, [ 9694] = 0x5608, [ 9695] = 0x5610, +- [ 9696] = 0x55F6, [ 9697] = 0x5718, [ 9698] = 0x5716, [ 9699] = 0x5875, +- [ 9700] = 0x587E, [ 9701] = 0x5883, [ 9702] = 0x5893, [ 9703] = 0x588A, +- [ 9704] = 0x5879, [ 9705] = 0x5885, [ 9706] = 0x587D, [ 9707] = 0x58FD, +- [ 9708] = 0x5925, [ 9709] = 0x5922, [ 9710] = 0x5924, [ 9711] = 0x596A, +- [ 9712] = 0x5969, [ 9713] = 0x5AE1, [ 9714] = 0x5AE6, [ 9715] = 0x5AE9, +- [ 9716] = 0x5AD7, [ 9717] = 0x5AD6, [ 9718] = 0x5AD8, [ 9719] = 0x5AE3, +- [ 9720] = 0x5B75, [ 9721] = 0x5BDE, [ 9722] = 0x5BE7, [ 9723] = 0x5BE1, +- [ 9724] = 0x5BE5, [ 9725] = 0x5BE6, [ 9726] = 0x5BE8, [ 9727] = 0x5BE2, +- [ 9728] = 0x5BE4, [ 9729] = 0x5BDF, [ 9730] = 0x5C0D, [ 9731] = 0x5C62, +- [ 9732] = 0x5D84, [ 9733] = 0x5D87, [ 9734] = 0x5E5B, [ 9735] = 0x5E63, +- [ 9736] = 0x5E55, [ 9737] = 0x5E57, [ 9738] = 0x5E54, [ 9739] = 0x5ED3, +- [ 9740] = 0x5ED6, [ 9741] = 0x5F0A, [ 9742] = 0x5F46, [ 9743] = 0x5F70, +- [ 9744] = 0x5FB9, [ 9745] = 0x6147, [ 9750] = 0x613F, [ 9751] = 0x614B, +- [ 9752] = 0x6177, [ 9753] = 0x6162, [ 9754] = 0x6163, [ 9755] = 0x615F, +- [ 9756] = 0x615A, [ 9757] = 0x6158, [ 9758] = 0x6175, [ 9759] = 0x622A, +- [ 9760] = 0x6487, [ 9761] = 0x6458, [ 9762] = 0x6454, [ 9763] = 0x64A4, +- [ 9764] = 0x6478, [ 9765] = 0x645F, [ 9766] = 0x647A, [ 9767] = 0x6451, +- [ 9768] = 0x6467, [ 9769] = 0x6434, [ 9770] = 0x646D, [ 9771] = 0x647B, +- [ 9772] = 0x6572, [ 9773] = 0x65A1, [ 9774] = 0x65D7, [ 9775] = 0x65D6, +- [ 9776] = 0x66A2, [ 9777] = 0x66A8, [ 9778] = 0x669D, [ 9779] = 0x699C, +- [ 9780] = 0x69A8, [ 9781] = 0x6995, [ 9782] = 0x69C1, [ 9783] = 0x69AE, +- [ 9784] = 0x69D3, [ 9785] = 0x69CB, [ 9786] = 0x699B, [ 9787] = 0x69B7, +- [ 9788] = 0x69BB, [ 9789] = 0x69AB, [ 9790] = 0x69B4, [ 9791] = 0x69D0, +- [ 9792] = 0x69CD, [ 9793] = 0x69AD, [ 9794] = 0x69CC, [ 9795] = 0x69A6, +- [ 9796] = 0x69C3, [ 9797] = 0x69A3, [ 9798] = 0x6B49, [ 9799] = 0x6B4C, +- [ 9800] = 0x6C33, [ 9801] = 0x6F33, [ 9802] = 0x6F14, [ 9803] = 0x6EFE, +- [ 9804] = 0x6F13, [ 9805] = 0x6EF4, [ 9806] = 0x6F29, [ 9807] = 0x6F3E, +- [ 9808] = 0x6F20, [ 9809] = 0x6F2C, [ 9810] = 0x6F0F, [ 9811] = 0x6F02, +- [ 9812] = 0x6F22, [ 9847] = 0x6EFF, [ 9848] = 0x6EEF, [ 9849] = 0x6F06, +- [ 9850] = 0x6F31, [ 9851] = 0x6F38, [ 9852] = 0x6F32, [ 9853] = 0x6F23, +- [ 9854] = 0x6F15, [ 9855] = 0x6F2B, [ 9856] = 0x6F2F, [ 9857] = 0x6F88, +- [ 9858] = 0x6F2A, [ 9859] = 0x6EEC, [ 9860] = 0x6F01, [ 9861] = 0x6EF2, +- [ 9862] = 0x6ECC, [ 9863] = 0x6EF7, [ 9864] = 0x7194, [ 9865] = 0x7199, +- [ 9866] = 0x717D, [ 9867] = 0x718A, [ 9868] = 0x7184, [ 9869] = 0x7192, +- [ 9870] = 0x723E, [ 9871] = 0x7292, [ 9872] = 0x7296, [ 9873] = 0x7344, +- [ 9874] = 0x7350, [ 9875] = 0x7464, [ 9876] = 0x7463, [ 9877] = 0x746A, +- [ 9878] = 0x7470, [ 9879] = 0x746D, [ 9880] = 0x7504, [ 9881] = 0x7591, +- [ 9882] = 0x7627, [ 9883] = 0x760D, [ 9884] = 0x760B, [ 9885] = 0x7609, +- [ 9886] = 0x7613, [ 9887] = 0x76E1, [ 9888] = 0x76E3, [ 9889] = 0x7784, +- [ 9890] = 0x777D, [ 9891] = 0x777F, [ 9892] = 0x7761, [ 9893] = 0x78C1, +- [ 9894] = 0x789F, [ 9895] = 0x78A7, [ 9896] = 0x78B3, [ 9897] = 0x78A9, +- [ 9898] = 0x78A3, [ 9899] = 0x798E, [ 9900] = 0x798F, [ 9901] = 0x798D, +- [ 9902] = 0x7A2E, [ 9903] = 0x7A31, [ 9904] = 0x7AAA, [ 9905] = 0x7AA9, +- [ 9906] = 0x7AED, [ 9907] = 0x7AEF, [ 9908] = 0x7BA1, [ 9909] = 0x7B95, +- [ 9910] = 0x7B8B, [ 9911] = 0x7B75, [ 9912] = 0x7B97, [ 9913] = 0x7B9D, +- [ 9914] = 0x7B94, [ 9915] = 0x7B8F, [ 9916] = 0x7BB8, [ 9917] = 0x7B87, +- [ 9918] = 0x7B84, [ 9919] = 0x7CB9, [ 9920] = 0x7CBD, [ 9921] = 0x7CBE, +- [ 9922] = 0x7DBB, [ 9923] = 0x7DB0, [ 9924] = 0x7D9C, [ 9925] = 0x7DBD, +- [ 9926] = 0x7DBE, [ 9927] = 0x7DA0, [ 9928] = 0x7DCA, [ 9929] = 0x7DB4, +- [ 9930] = 0x7DB2, [ 9931] = 0x7DB1, [ 9932] = 0x7DBA, [ 9933] = 0x7DA2, +- [ 9934] = 0x7DBF, [ 9935] = 0x7DB5, [ 9936] = 0x7DB8, [ 9937] = 0x7DAD, +- [ 9938] = 0x7DD2, [ 9939] = 0x7DC7, [ 9940] = 0x7DAC, [ 9945] = 0x7F70, +- [ 9946] = 0x7FE0, [ 9947] = 0x7FE1, [ 9948] = 0x7FDF, [ 9949] = 0x805E, +- [ 9950] = 0x805A, [ 9951] = 0x8087, [ 9952] = 0x8150, [ 9953] = 0x8180, +- [ 9954] = 0x818F, [ 9955] = 0x8188, [ 9956] = 0x818A, [ 9957] = 0x817F, +- [ 9958] = 0x8182, [ 9959] = 0x81E7, [ 9960] = 0x81FA, [ 9961] = 0x8207, +- [ 9962] = 0x8214, [ 9963] = 0x821E, [ 9964] = 0x824B, [ 9965] = 0x84C9, +- [ 9966] = 0x84BF, [ 9967] = 0x84C6, [ 9968] = 0x84C4, [ 9969] = 0x8499, +- [ 9970] = 0x849E, [ 9971] = 0x84B2, [ 9972] = 0x849C, [ 9973] = 0x84CB, +- [ 9974] = 0x84B8, [ 9975] = 0x84C0, [ 9976] = 0x84D3, [ 9977] = 0x8490, +- [ 9978] = 0x84BC, [ 9979] = 0x84D1, [ 9980] = 0x84CA, [ 9981] = 0x873F, +- [ 9982] = 0x871C, [ 9983] = 0x873B, [ 9984] = 0x8722, [ 9985] = 0x8725, +- [ 9986] = 0x8734, [ 9987] = 0x8718, [ 9988] = 0x8755, [ 9989] = 0x8737, +- [ 9990] = 0x8729, [ 9991] = 0x88F3, [ 9992] = 0x8902, [ 9993] = 0x88F4, +- [ 9994] = 0x88F9, [ 9995] = 0x88F8, [ 9996] = 0x88FD, [ 9997] = 0x88E8, +- [ 9998] = 0x891A, [ 9999] = 0x88EF, [10000] = 0x8AA6, [10001] = 0x8A8C, +- [10002] = 0x8A9E, [10003] = 0x8AA3, [10004] = 0x8A8D, [10005] = 0x8AA1, +- [10006] = 0x8A93, [10007] = 0x8AA4, [10042] = 0x8AAA, [10043] = 0x8AA5, +- [10044] = 0x8AA8, [10045] = 0x8A98, [10046] = 0x8A91, [10047] = 0x8A9A, +- [10048] = 0x8AA7, [10049] = 0x8C6A, [10050] = 0x8C8D, [10051] = 0x8C8C, +- [10052] = 0x8CD3, [10053] = 0x8CD1, [10054] = 0x8CD2, [10055] = 0x8D6B, +- [10056] = 0x8D99, [10057] = 0x8D95, [10058] = 0x8DFC, [10059] = 0x8F14, +- [10060] = 0x8F12, [10061] = 0x8F15, [10062] = 0x8F13, [10063] = 0x8FA3, +- [10064] = 0x9060, [10065] = 0x9058, [10066] = 0x905C, [10067] = 0x9063, +- [10068] = 0x9059, [10069] = 0x905E, [10070] = 0x9062, [10071] = 0x905D, +- [10072] = 0x905B, [10073] = 0x9119, [10074] = 0x9118, [10075] = 0x911E, +- [10076] = 0x9175, [10077] = 0x9178, [10078] = 0x9177, [10079] = 0x9174, +- [10080] = 0x9278, [10081] = 0x9280, [10082] = 0x9285, [10083] = 0x9298, +- [10084] = 0x9296, [10085] = 0x927B, [10086] = 0x9293, [10087] = 0x929C, +- [10088] = 0x92A8, [10089] = 0x927C, [10090] = 0x9291, [10091] = 0x95A1, +- [10092] = 0x95A8, [10093] = 0x95A9, [10094] = 0x95A3, [10095] = 0x95A5, +- [10096] = 0x95A4, [10097] = 0x9699, [10098] = 0x969C, [10099] = 0x969B, +- [10100] = 0x96CC, [10101] = 0x96D2, [10102] = 0x9700, [10103] = 0x977C, +- [10104] = 0x9785, [10105] = 0x97F6, [10106] = 0x9817, [10107] = 0x9818, +- [10108] = 0x98AF, [10109] = 0x98B1, [10110] = 0x9903, [10111] = 0x9905, +- [10112] = 0x990C, [10113] = 0x9909, [10114] = 0x99C1, [10115] = 0x9AAF, +- [10116] = 0x9AB0, [10117] = 0x9AE6, [10118] = 0x9B41, [10119] = 0x9B42, +- [10120] = 0x9CF4, [10121] = 0x9CF6, [10122] = 0x9CF3, [10123] = 0x9EBC, +- [10124] = 0x9F3B, [10125] = 0x9F4A, [10126] = 0x5104, [10127] = 0x5100, +- [10128] = 0x50FB, [10129] = 0x50F5, [10130] = 0x50F9, [10131] = 0x5102, +- [10132] = 0x5108, [10133] = 0x5109, [10134] = 0x5105, [10135] = 0x51DC, +- [10140] = 0x5287, [10141] = 0x5288, [10142] = 0x5289, [10143] = 0x528D, +- [10144] = 0x528A, [10145] = 0x52F0, [10146] = 0x53B2, [10147] = 0x562E, +- [10148] = 0x563B, [10149] = 0x5639, [10150] = 0x5632, [10151] = 0x563F, +- [10152] = 0x5634, [10153] = 0x5629, [10154] = 0x5653, [10155] = 0x564E, +- [10156] = 0x5657, [10157] = 0x5674, [10158] = 0x5636, [10159] = 0x562F, +- [10160] = 0x5630, [10161] = 0x5880, [10162] = 0x589F, [10163] = 0x589E, +- [10164] = 0x58B3, [10165] = 0x589C, [10166] = 0x58AE, [10167] = 0x58A9, +- [10168] = 0x58A6, [10169] = 0x596D, [10170] = 0x5B09, [10171] = 0x5AFB, +- [10172] = 0x5B0B, [10173] = 0x5AF5, [10174] = 0x5B0C, [10175] = 0x5B08, +- [10176] = 0x5BEE, [10177] = 0x5BEC, [10178] = 0x5BE9, [10179] = 0x5BEB, +- [10180] = 0x5C64, [10181] = 0x5C65, [10182] = 0x5D9D, [10183] = 0x5D94, +- [10184] = 0x5E62, [10185] = 0x5E5F, [10186] = 0x5E61, [10187] = 0x5EE2, +- [10188] = 0x5EDA, [10189] = 0x5EDF, [10190] = 0x5EDD, [10191] = 0x5EE3, +- [10192] = 0x5EE0, [10193] = 0x5F48, [10194] = 0x5F71, [10195] = 0x5FB7, +- [10196] = 0x5FB5, [10197] = 0x6176, [10198] = 0x6167, [10199] = 0x616E, +- [10200] = 0x615D, [10201] = 0x6155, [10202] = 0x6182, [10237] = 0x617C, +- [10238] = 0x6170, [10239] = 0x616B, [10240] = 0x617E, [10241] = 0x61A7, +- [10242] = 0x6190, [10243] = 0x61AB, [10244] = 0x618E, [10245] = 0x61AC, +- [10246] = 0x619A, [10247] = 0x61A4, [10248] = 0x6194, [10249] = 0x61AE, +- [10250] = 0x622E, [10251] = 0x6469, [10252] = 0x646F, [10253] = 0x6479, +- [10254] = 0x649E, [10255] = 0x64B2, [10256] = 0x6488, [10257] = 0x6490, +- [10258] = 0x64B0, [10259] = 0x64A5, [10260] = 0x6493, [10261] = 0x6495, +- [10262] = 0x64A9, [10263] = 0x6492, [10264] = 0x64AE, [10265] = 0x64AD, +- [10266] = 0x64AB, [10267] = 0x649A, [10268] = 0x64AC, [10269] = 0x6499, +- [10270] = 0x64A2, [10271] = 0x64B3, [10272] = 0x6575, [10273] = 0x6577, +- [10274] = 0x6578, [10275] = 0x66AE, [10276] = 0x66AB, [10277] = 0x66B4, +- [10278] = 0x66B1, [10279] = 0x6A23, [10280] = 0x6A1F, [10281] = 0x69E8, +- [10282] = 0x6A01, [10283] = 0x6A1E, [10284] = 0x6A19, [10285] = 0x69FD, +- [10286] = 0x6A21, [10287] = 0x6A13, [10288] = 0x6A0A, [10289] = 0x69F3, +- [10290] = 0x6A02, [10291] = 0x6A05, [10292] = 0x69ED, [10293] = 0x6A11, +- [10294] = 0x6B50, [10295] = 0x6B4E, [10296] = 0x6BA4, [10297] = 0x6BC5, +- [10298] = 0x6BC6, [10299] = 0x6F3F, [10300] = 0x6F7C, [10301] = 0x6F84, +- [10302] = 0x6F51, [10303] = 0x6F66, [10304] = 0x6F54, [10305] = 0x6F86, +- [10306] = 0x6F6D, [10307] = 0x6F5B, [10308] = 0x6F78, [10309] = 0x6F6E, +- [10310] = 0x6F8E, [10311] = 0x6F7A, [10312] = 0x6F70, [10313] = 0x6F64, +- [10314] = 0x6F97, [10315] = 0x6F58, [10316] = 0x6ED5, [10317] = 0x6F6F, +- [10318] = 0x6F60, [10319] = 0x6F5F, [10320] = 0x719F, [10321] = 0x71AC, +- [10322] = 0x71B1, [10323] = 0x71A8, [10324] = 0x7256, [10325] = 0x729B, +- [10326] = 0x734E, [10327] = 0x7357, [10328] = 0x7469, [10329] = 0x748B, +- [10330] = 0x7483, [10335] = 0x747E, [10336] = 0x7480, [10337] = 0x757F, +- [10338] = 0x7620, [10339] = 0x7629, [10340] = 0x761F, [10341] = 0x7624, +- [10342] = 0x7626, [10343] = 0x7621, [10344] = 0x7622, [10345] = 0x769A, +- [10346] = 0x76BA, [10347] = 0x76E4, [10348] = 0x778E, [10349] = 0x7787, +- [10350] = 0x778C, [10351] = 0x7791, [10352] = 0x778B, [10353] = 0x78CB, +- [10354] = 0x78C5, [10355] = 0x78BA, [10356] = 0x78CA, [10357] = 0x78BE, +- [10358] = 0x78D5, [10359] = 0x78BC, [10360] = 0x78D0, [10361] = 0x7A3F, +- [10362] = 0x7A3C, [10363] = 0x7A40, [10364] = 0x7A3D, [10365] = 0x7A37, +- [10366] = 0x7A3B, [10367] = 0x7AAF, [10368] = 0x7AAE, [10369] = 0x7BAD, +- [10370] = 0x7BB1, [10371] = 0x7BC4, [10372] = 0x7BB4, [10373] = 0x7BC6, +- [10374] = 0x7BC7, [10375] = 0x7BC1, [10376] = 0x7BA0, [10377] = 0x7BCC, +- [10378] = 0x7CCA, [10379] = 0x7DE0, [10380] = 0x7DF4, [10381] = 0x7DEF, +- [10382] = 0x7DFB, [10383] = 0x7DD8, [10384] = 0x7DEC, [10385] = 0x7DDD, +- [10386] = 0x7DE8, [10387] = 0x7DE3, [10388] = 0x7DDA, [10389] = 0x7DDE, +- [10390] = 0x7DE9, [10391] = 0x7D9E, [10392] = 0x7DD9, [10393] = 0x7DF2, +- [10394] = 0x7DF9, [10395] = 0x7F75, [10396] = 0x7F77, [10397] = 0x7FAF, +- [10432] = 0x7FE9, [10433] = 0x8026, [10434] = 0x819B, [10435] = 0x819C, +- [10436] = 0x819D, [10437] = 0x81A0, [10438] = 0x819A, [10439] = 0x8198, +- [10440] = 0x8517, [10441] = 0x853D, [10442] = 0x851A, [10443] = 0x84EE, +- [10444] = 0x852C, [10445] = 0x852D, [10446] = 0x8513, [10447] = 0x8511, +- [10448] = 0x8523, [10449] = 0x8521, [10450] = 0x8514, [10451] = 0x84EC, +- [10452] = 0x8525, [10453] = 0x84FF, [10454] = 0x8506, [10455] = 0x8782, +- [10456] = 0x8774, [10457] = 0x8776, [10458] = 0x8760, [10459] = 0x8766, +- [10460] = 0x8778, [10461] = 0x8768, [10462] = 0x8759, [10463] = 0x8757, +- [10464] = 0x874C, [10465] = 0x8753, [10466] = 0x885B, [10467] = 0x885D, +- [10468] = 0x8910, [10469] = 0x8907, [10470] = 0x8912, [10471] = 0x8913, +- [10472] = 0x8915, [10473] = 0x890A, [10474] = 0x8ABC, [10475] = 0x8AD2, +- [10476] = 0x8AC7, [10477] = 0x8AC4, [10478] = 0x8A95, [10479] = 0x8ACB, +- [10480] = 0x8AF8, [10481] = 0x8AB2, [10482] = 0x8AC9, [10483] = 0x8AC2, +- [10484] = 0x8ABF, [10485] = 0x8AB0, [10486] = 0x8AD6, [10487] = 0x8ACD, +- [10488] = 0x8AB6, [10489] = 0x8AB9, [10490] = 0x8ADB, [10491] = 0x8C4C, +- [10492] = 0x8C4E, [10493] = 0x8C6C, [10494] = 0x8CE0, [10495] = 0x8CDE, +- [10496] = 0x8CE6, [10497] = 0x8CE4, [10498] = 0x8CEC, [10499] = 0x8CED, +- [10500] = 0x8CE2, [10501] = 0x8CE3, [10502] = 0x8CDC, [10503] = 0x8CEA, +- [10504] = 0x8CE1, [10505] = 0x8D6D, [10506] = 0x8D9F, [10507] = 0x8DA3, +- [10508] = 0x8E2B, [10509] = 0x8E10, [10510] = 0x8E1D, [10511] = 0x8E22, +- [10512] = 0x8E0F, [10513] = 0x8E29, [10514] = 0x8E1F, [10515] = 0x8E21, +- [10516] = 0x8E1E, [10517] = 0x8EBA, [10518] = 0x8F1D, [10519] = 0x8F1B, +- [10520] = 0x8F1F, [10521] = 0x8F29, [10522] = 0x8F26, [10523] = 0x8F2A, +- [10524] = 0x8F1C, [10525] = 0x8F1E, [10530] = 0x8F25, [10531] = 0x9069, +- [10532] = 0x906E, [10533] = 0x9068, [10534] = 0x906D, [10535] = 0x9077, +- [10536] = 0x9130, [10537] = 0x912D, [10538] = 0x9127, [10539] = 0x9131, +- [10540] = 0x9187, [10541] = 0x9189, [10542] = 0x918B, [10543] = 0x9183, +- [10544] = 0x92C5, [10545] = 0x92BB, [10546] = 0x92B7, [10547] = 0x92EA, +- [10548] = 0x92AC, [10549] = 0x92E4, [10550] = 0x92C1, [10551] = 0x92B3, +- [10552] = 0x92BC, [10553] = 0x92D2, [10554] = 0x92C7, [10555] = 0x92F0, +- [10556] = 0x92B2, [10557] = 0x95AD, [10558] = 0x95B1, [10559] = 0x9704, +- [10560] = 0x9706, [10561] = 0x9707, [10562] = 0x9709, [10563] = 0x9760, +- [10564] = 0x978D, [10565] = 0x978B, [10566] = 0x978F, [10567] = 0x9821, +- [10568] = 0x982B, [10569] = 0x981C, [10570] = 0x98B3, [10571] = 0x990A, +- [10572] = 0x9913, [10573] = 0x9912, [10574] = 0x9918, [10575] = 0x99DD, +- [10576] = 0x99D0, [10577] = 0x99DF, [10578] = 0x99DB, [10579] = 0x99D1, +- [10580] = 0x99D5, [10581] = 0x99D2, [10582] = 0x99D9, [10583] = 0x9AB7, +- [10584] = 0x9AEE, [10585] = 0x9AEF, [10586] = 0x9B27, [10587] = 0x9B45, +- [10588] = 0x9B44, [10589] = 0x9B77, [10590] = 0x9B6F, [10591] = 0x9D06, +- [10592] = 0x9D09, [10627] = 0x9D03, [10628] = 0x9EA9, [10629] = 0x9EBE, +- [10630] = 0x9ECE, [10631] = 0x58A8, [10632] = 0x9F52, [10633] = 0x5112, +- [10634] = 0x5118, [10635] = 0x5114, [10636] = 0x5110, [10637] = 0x5115, +- [10638] = 0x5180, [10639] = 0x51AA, [10640] = 0x51DD, [10641] = 0x5291, +- [10642] = 0x5293, [10643] = 0x52F3, [10644] = 0x5659, [10645] = 0x566B, +- [10646] = 0x5679, [10647] = 0x5669, [10648] = 0x5664, [10649] = 0x5678, +- [10650] = 0x566A, [10651] = 0x5668, [10652] = 0x5665, [10653] = 0x5671, +- [10654] = 0x566F, [10655] = 0x566C, [10656] = 0x5662, [10657] = 0x5676, +- [10658] = 0x58C1, [10659] = 0x58BE, [10660] = 0x58C7, [10661] = 0x58C5, +- [10662] = 0x596E, [10663] = 0x5B1D, [10664] = 0x5B34, [10665] = 0x5B78, +- [10666] = 0x5BF0, [10667] = 0x5C0E, [10668] = 0x5F4A, [10669] = 0x61B2, +- [10670] = 0x6191, [10671] = 0x61A9, [10672] = 0x618A, [10673] = 0x61CD, +- [10674] = 0x61B6, [10675] = 0x61BE, [10676] = 0x61CA, [10677] = 0x61C8, +- [10678] = 0x6230, [10679] = 0x64C5, [10680] = 0x64C1, [10681] = 0x64CB, +- [10682] = 0x64BB, [10683] = 0x64BC, [10684] = 0x64DA, [10685] = 0x64C4, +- [10686] = 0x64C7, [10687] = 0x64C2, [10688] = 0x64CD, [10689] = 0x64BF, +- [10690] = 0x64D2, [10691] = 0x64D4, [10692] = 0x64BE, [10693] = 0x6574, +- [10694] = 0x66C6, [10695] = 0x66C9, [10696] = 0x66B9, [10697] = 0x66C4, +- [10698] = 0x66C7, [10699] = 0x66B8, [10700] = 0x6A3D, [10701] = 0x6A38, +- [10702] = 0x6A3A, [10703] = 0x6A59, [10704] = 0x6A6B, [10705] = 0x6A58, +- [10706] = 0x6A39, [10707] = 0x6A44, [10708] = 0x6A62, [10709] = 0x6A61, +- [10710] = 0x6A4B, [10711] = 0x6A47, [10712] = 0x6A35, [10713] = 0x6A5F, +- [10714] = 0x6A48, [10715] = 0x6B59, [10716] = 0x6B77, [10717] = 0x6C05, +- [10718] = 0x6FC2, [10719] = 0x6FB1, [10720] = 0x6FA1, [10725] = 0x6FC3, +- [10726] = 0x6FA4, [10727] = 0x6FC1, [10728] = 0x6FA7, [10729] = 0x6FB3, +- [10730] = 0x6FC0, [10731] = 0x6FB9, [10732] = 0x6FB6, [10733] = 0x6FA6, +- [10734] = 0x6FA0, [10735] = 0x6FB4, [10736] = 0x71BE, [10737] = 0x71C9, +- [10738] = 0x71D0, [10739] = 0x71D2, [10740] = 0x71C8, [10741] = 0x71D5, +- [10742] = 0x71B9, [10743] = 0x71CE, [10744] = 0x71D9, [10745] = 0x71DC, +- [10746] = 0x71C3, [10747] = 0x71C4, [10748] = 0x7368, [10749] = 0x749C, +- [10750] = 0x74A3, [10751] = 0x7498, [10752] = 0x749F, [10753] = 0x749E, +- [10754] = 0x74E2, [10755] = 0x750C, [10756] = 0x750D, [10757] = 0x7634, +- [10758] = 0x7638, [10759] = 0x763A, [10760] = 0x76E7, [10761] = 0x76E5, +- [10762] = 0x77A0, [10763] = 0x779E, [10764] = 0x779F, [10765] = 0x77A5, +- [10766] = 0x78E8, [10767] = 0x78DA, [10768] = 0x78EC, [10769] = 0x78E7, +- [10770] = 0x79A6, [10771] = 0x7A4D, [10772] = 0x7A4E, [10773] = 0x7A46, +- [10774] = 0x7A4C, [10775] = 0x7A4B, [10776] = 0x7ABA, [10777] = 0x7BD9, +- [10778] = 0x7C11, [10779] = 0x7BC9, [10780] = 0x7BE4, [10781] = 0x7BDB, +- [10782] = 0x7BE1, [10783] = 0x7BE9, [10784] = 0x7BE6, [10785] = 0x7CD5, +- [10786] = 0x7CD6, [10787] = 0x7E0A, [10822] = 0x7E11, [10823] = 0x7E08, +- [10824] = 0x7E1B, [10825] = 0x7E23, [10826] = 0x7E1E, [10827] = 0x7E1D, +- [10828] = 0x7E09, [10829] = 0x7E10, [10830] = 0x7F79, [10831] = 0x7FB2, +- [10832] = 0x7FF0, [10833] = 0x7FF1, [10834] = 0x7FEE, [10835] = 0x8028, +- [10836] = 0x81B3, [10837] = 0x81A9, [10838] = 0x81A8, [10839] = 0x81FB, +- [10840] = 0x8208, [10841] = 0x8258, [10842] = 0x8259, [10843] = 0x854A, +- [10844] = 0x8559, [10845] = 0x8548, [10846] = 0x8568, [10847] = 0x8569, +- [10848] = 0x8543, [10849] = 0x8549, [10850] = 0x856D, [10851] = 0x856A, +- [10852] = 0x855E, [10853] = 0x8783, [10854] = 0x879F, [10855] = 0x879E, +- [10856] = 0x87A2, [10857] = 0x878D, [10858] = 0x8861, [10859] = 0x892A, +- [10860] = 0x8932, [10861] = 0x8925, [10862] = 0x892B, [10863] = 0x8921, +- [10864] = 0x89AA, [10865] = 0x89A6, [10866] = 0x8AE6, [10867] = 0x8AFA, +- [10868] = 0x8AEB, [10869] = 0x8AF1, [10870] = 0x8B00, [10871] = 0x8ADC, +- [10872] = 0x8AE7, [10873] = 0x8AEE, [10874] = 0x8AFE, [10875] = 0x8B01, +- [10876] = 0x8B02, [10877] = 0x8AF7, [10878] = 0x8AED, [10879] = 0x8AF3, +- [10880] = 0x8AF6, [10881] = 0x8AFC, [10882] = 0x8C6B, [10883] = 0x8C6D, +- [10884] = 0x8C93, [10885] = 0x8CF4, [10886] = 0x8E44, [10887] = 0x8E31, +- [10888] = 0x8E34, [10889] = 0x8E42, [10890] = 0x8E39, [10891] = 0x8E35, +- [10892] = 0x8F3B, [10893] = 0x8F2F, [10894] = 0x8F38, [10895] = 0x8F33, +- [10896] = 0x8FA8, [10897] = 0x8FA6, [10898] = 0x9075, [10899] = 0x9074, +- [10900] = 0x9078, [10901] = 0x9072, [10902] = 0x907C, [10903] = 0x907A, +- [10904] = 0x9134, [10905] = 0x9192, [10906] = 0x9320, [10907] = 0x9336, +- [10908] = 0x92F8, [10909] = 0x9333, [10910] = 0x932F, [10911] = 0x9322, +- [10912] = 0x92FC, [10913] = 0x932B, [10914] = 0x9304, [10915] = 0x931A, +- [10920] = 0x9310, [10921] = 0x9326, [10922] = 0x9321, [10923] = 0x9315, +- [10924] = 0x932E, [10925] = 0x9319, [10926] = 0x95BB, [10927] = 0x96A7, +- [10928] = 0x96A8, [10929] = 0x96AA, [10930] = 0x96D5, [10931] = 0x970E, +- [10932] = 0x9711, [10933] = 0x9716, [10934] = 0x970D, [10935] = 0x9713, +- [10936] = 0x970F, [10937] = 0x975B, [10938] = 0x975C, [10939] = 0x9766, +- [10940] = 0x9798, [10941] = 0x9830, [10942] = 0x9838, [10943] = 0x983B, +- [10944] = 0x9837, [10945] = 0x982D, [10946] = 0x9839, [10947] = 0x9824, +- [10948] = 0x9910, [10949] = 0x9928, [10950] = 0x991E, [10951] = 0x991B, +- [10952] = 0x9921, [10953] = 0x991A, [10954] = 0x99ED, [10955] = 0x99E2, +- [10956] = 0x99F1, [10957] = 0x9AB8, [10958] = 0x9ABC, [10959] = 0x9AFB, +- [10960] = 0x9AED, [10961] = 0x9B28, [10962] = 0x9B91, [10963] = 0x9D15, +- [10964] = 0x9D23, [10965] = 0x9D26, [10966] = 0x9D28, [10967] = 0x9D12, +- [10968] = 0x9D1B, [10969] = 0x9ED8, [10970] = 0x9ED4, [10971] = 0x9F8D, +- [10972] = 0x9F9C, [10973] = 0x512A, [10974] = 0x511F, [10975] = 0x5121, +- [10976] = 0x5132, [10977] = 0x52F5, [10978] = 0x568E, [10979] = 0x5680, +- [10980] = 0x5690, [10981] = 0x5685, [10982] = 0x5687, [11017] = 0x568F, +- [11018] = 0x58D5, [11019] = 0x58D3, [11020] = 0x58D1, [11021] = 0x58CE, +- [11022] = 0x5B30, [11023] = 0x5B2A, [11024] = 0x5B24, [11025] = 0x5B7A, +- [11026] = 0x5C37, [11027] = 0x5C68, [11028] = 0x5DBC, [11029] = 0x5DBA, +- [11030] = 0x5DBD, [11031] = 0x5DB8, [11032] = 0x5E6B, [11033] = 0x5F4C, +- [11034] = 0x5FBD, [11035] = 0x61C9, [11036] = 0x61C2, [11037] = 0x61C7, +- [11038] = 0x61E6, [11039] = 0x61CB, [11040] = 0x6232, [11041] = 0x6234, +- [11042] = 0x64CE, [11043] = 0x64CA, [11044] = 0x64D8, [11045] = 0x64E0, +- [11046] = 0x64F0, [11047] = 0x64E6, [11048] = 0x64EC, [11049] = 0x64F1, +- [11050] = 0x64E2, [11051] = 0x64ED, [11052] = 0x6582, [11053] = 0x6583, +- [11054] = 0x66D9, [11055] = 0x66D6, [11056] = 0x6A80, [11057] = 0x6A94, +- [11058] = 0x6A84, [11059] = 0x6AA2, [11060] = 0x6A9C, [11061] = 0x6ADB, +- [11062] = 0x6AA3, [11063] = 0x6A7E, [11064] = 0x6A97, [11065] = 0x6A90, +- [11066] = 0x6AA0, [11067] = 0x6B5C, [11068] = 0x6BAE, [11069] = 0x6BDA, +- [11070] = 0x6C08, [11071] = 0x6FD8, [11072] = 0x6FF1, [11073] = 0x6FDF, +- [11074] = 0x6FE0, [11075] = 0x6FDB, [11076] = 0x6FE4, [11077] = 0x6FEB, +- [11078] = 0x6FEF, [11079] = 0x6F80, [11080] = 0x6FEC, [11081] = 0x6FE1, +- [11082] = 0x6FE9, [11083] = 0x6FD5, [11084] = 0x6FEE, [11085] = 0x6FF0, +- [11086] = 0x71E7, [11087] = 0x71DF, [11088] = 0x71EE, [11089] = 0x71E6, +- [11090] = 0x71E5, [11091] = 0x71ED, [11092] = 0x71EC, [11093] = 0x71F4, +- [11094] = 0x71E0, [11095] = 0x7235, [11096] = 0x7246, [11097] = 0x7370, +- [11098] = 0x7372, [11099] = 0x74A9, [11100] = 0x74B0, [11101] = 0x74A6, +- [11102] = 0x74A8, [11103] = 0x7646, [11104] = 0x7642, [11105] = 0x764C, +- [11106] = 0x76EA, [11107] = 0x77B3, [11108] = 0x77AA, [11109] = 0x77B0, +- [11110] = 0x77AC, [11115] = 0x77A7, [11116] = 0x77AD, [11117] = 0x77EF, +- [11118] = 0x78F7, [11119] = 0x78FA, [11120] = 0x78F4, [11121] = 0x78EF, +- [11122] = 0x7901, [11123] = 0x79A7, [11124] = 0x79AA, [11125] = 0x7A57, +- [11126] = 0x7ABF, [11127] = 0x7C07, [11128] = 0x7C0D, [11129] = 0x7BFE, +- [11130] = 0x7BF7, [11131] = 0x7C0C, [11132] = 0x7BE0, [11133] = 0x7CE0, +- [11134] = 0x7CDC, [11135] = 0x7CDE, [11136] = 0x7CE2, [11137] = 0x7CDF, +- [11138] = 0x7CD9, [11139] = 0x7CDD, [11140] = 0x7E2E, [11141] = 0x7E3E, +- [11142] = 0x7E46, [11143] = 0x7E37, [11144] = 0x7E32, [11145] = 0x7E43, +- [11146] = 0x7E2B, [11147] = 0x7E3D, [11148] = 0x7E31, [11149] = 0x7E45, +- [11150] = 0x7E41, [11151] = 0x7E34, [11152] = 0x7E39, [11153] = 0x7E48, +- [11154] = 0x7E35, [11155] = 0x7E3F, [11156] = 0x7E2F, [11157] = 0x7F44, +- [11158] = 0x7FF3, [11159] = 0x7FFC, [11160] = 0x8071, [11161] = 0x8072, +- [11162] = 0x8070, [11163] = 0x806F, [11164] = 0x8073, [11165] = 0x81C6, +- [11166] = 0x81C3, [11167] = 0x81BA, [11168] = 0x81C2, [11169] = 0x81C0, +- [11170] = 0x81BF, [11171] = 0x81BD, [11172] = 0x81C9, [11173] = 0x81BE, +- [11174] = 0x81E8, [11175] = 0x8209, [11176] = 0x8271, [11177] = 0x85AA, +- [11212] = 0x8584, [11213] = 0x857E, [11214] = 0x859C, [11215] = 0x8591, +- [11216] = 0x8594, [11217] = 0x85AF, [11218] = 0x859B, [11219] = 0x8587, +- [11220] = 0x85A8, [11221] = 0x858A, [11222] = 0x8667, [11223] = 0x87C0, +- [11224] = 0x87D1, [11225] = 0x87B3, [11226] = 0x87D2, [11227] = 0x87C6, +- [11228] = 0x87AB, [11229] = 0x87BB, [11230] = 0x87BA, [11231] = 0x87C8, +- [11232] = 0x87CB, [11233] = 0x893B, [11234] = 0x8936, [11235] = 0x8944, +- [11236] = 0x8938, [11237] = 0x893D, [11238] = 0x89AC, [11239] = 0x8B0E, +- [11240] = 0x8B17, [11241] = 0x8B19, [11242] = 0x8B1B, [11243] = 0x8B0A, +- [11244] = 0x8B20, [11245] = 0x8B1D, [11246] = 0x8B04, [11247] = 0x8B10, +- [11248] = 0x8C41, [11249] = 0x8C3F, [11250] = 0x8C73, [11251] = 0x8CFA, +- [11252] = 0x8CFD, [11253] = 0x8CFC, [11254] = 0x8CF8, [11255] = 0x8CFB, +- [11256] = 0x8DA8, [11257] = 0x8E49, [11258] = 0x8E4B, [11259] = 0x8E48, +- [11260] = 0x8E4A, [11261] = 0x8F44, [11262] = 0x8F3E, [11263] = 0x8F42, +- [11264] = 0x8F45, [11265] = 0x8F3F, [11266] = 0x907F, [11267] = 0x907D, +- [11268] = 0x9084, [11269] = 0x9081, [11270] = 0x9082, [11271] = 0x9080, +- [11272] = 0x9139, [11273] = 0x91A3, [11274] = 0x919E, [11275] = 0x919C, +- [11276] = 0x934D, [11277] = 0x9382, [11278] = 0x9328, [11279] = 0x9375, +- [11280] = 0x934A, [11281] = 0x9365, [11282] = 0x934B, [11283] = 0x9318, +- [11284] = 0x937E, [11285] = 0x936C, [11286] = 0x935B, [11287] = 0x9370, +- [11288] = 0x935A, [11289] = 0x9354, [11290] = 0x95CA, [11291] = 0x95CB, +- [11292] = 0x95CC, [11293] = 0x95C8, [11294] = 0x95C6, [11295] = 0x96B1, +- [11296] = 0x96B8, [11297] = 0x96D6, [11298] = 0x971C, [11299] = 0x971E, +- [11300] = 0x97A0, [11301] = 0x97D3, [11302] = 0x9846, [11303] = 0x98B6, +- [11304] = 0x9935, [11305] = 0x9A01, [11310] = 0x99FF, [11311] = 0x9BAE, +- [11312] = 0x9BAB, [11313] = 0x9BAA, [11314] = 0x9BAD, [11315] = 0x9D3B, +- [11316] = 0x9D3F, [11317] = 0x9E8B, [11318] = 0x9ECF, [11319] = 0x9EDE, +- [11320] = 0x9EDC, [11321] = 0x9EDD, [11322] = 0x9EDB, [11323] = 0x9F3E, +- [11324] = 0x9F4B, [11325] = 0x53E2, [11326] = 0x5695, [11327] = 0x56AE, +- [11328] = 0x58D9, [11329] = 0x58D8, [11330] = 0x5B38, [11331] = 0x5F5D, +- [11332] = 0x61E3, [11333] = 0x6233, [11334] = 0x64F4, [11335] = 0x64F2, +- [11336] = 0x64FE, [11337] = 0x6506, [11338] = 0x64FA, [11339] = 0x64FB, +- [11340] = 0x64F7, [11341] = 0x65B7, [11342] = 0x66DC, [11343] = 0x6726, +- [11344] = 0x6AB3, [11345] = 0x6AAC, [11346] = 0x6AC3, [11347] = 0x6ABB, +- [11348] = 0x6AB8, [11349] = 0x6AC2, [11350] = 0x6AAE, [11351] = 0x6AAF, +- [11352] = 0x6B5F, [11353] = 0x6B78, [11354] = 0x6BAF, [11355] = 0x7009, +- [11356] = 0x700B, [11357] = 0x6FFE, [11358] = 0x7006, [11359] = 0x6FFA, +- [11360] = 0x7011, [11361] = 0x700F, [11362] = 0x71FB, [11363] = 0x71FC, +- [11364] = 0x71FE, [11365] = 0x71F8, [11366] = 0x7377, [11367] = 0x7375, +- [11368] = 0x74A7, [11369] = 0x74BF, [11370] = 0x7515, [11371] = 0x7656, +- [11372] = 0x7658, [11407] = 0x7652, [11408] = 0x77BD, [11409] = 0x77BF, +- [11410] = 0x77BB, [11411] = 0x77BC, [11412] = 0x790E, [11413] = 0x79AE, +- [11414] = 0x7A61, [11415] = 0x7A62, [11416] = 0x7A60, [11417] = 0x7AC4, +- [11418] = 0x7AC5, [11419] = 0x7C2B, [11420] = 0x7C27, [11421] = 0x7C2A, +- [11422] = 0x7C1E, [11423] = 0x7C23, [11424] = 0x7C21, [11425] = 0x7CE7, +- [11426] = 0x7E54, [11427] = 0x7E55, [11428] = 0x7E5E, [11429] = 0x7E5A, +- [11430] = 0x7E61, [11431] = 0x7E52, [11432] = 0x7E59, [11433] = 0x7F48, +- [11434] = 0x7FF9, [11435] = 0x7FFB, [11436] = 0x8077, [11437] = 0x8076, +- [11438] = 0x81CD, [11439] = 0x81CF, [11440] = 0x820A, [11441] = 0x85CF, +- [11442] = 0x85A9, [11443] = 0x85CD, [11444] = 0x85D0, [11445] = 0x85C9, +- [11446] = 0x85B0, [11447] = 0x85BA, [11448] = 0x85B9, [11449] = 0x85A6, +- [11450] = 0x87EF, [11451] = 0x87EC, [11452] = 0x87F2, [11453] = 0x87E0, +- [11454] = 0x8986, [11455] = 0x89B2, [11456] = 0x89F4, [11457] = 0x8B28, +- [11458] = 0x8B39, [11459] = 0x8B2C, [11460] = 0x8B2B, [11461] = 0x8C50, +- [11462] = 0x8D05, [11463] = 0x8E59, [11464] = 0x8E63, [11465] = 0x8E66, +- [11466] = 0x8E64, [11467] = 0x8E5F, [11468] = 0x8E55, [11469] = 0x8EC0, +- [11470] = 0x8F49, [11471] = 0x8F4D, [11472] = 0x9087, [11473] = 0x9083, +- [11474] = 0x9088, [11475] = 0x91AB, [11476] = 0x91AC, [11477] = 0x91D0, +- [11478] = 0x9394, [11479] = 0x938A, [11480] = 0x9396, [11481] = 0x93A2, +- [11482] = 0x93B3, [11483] = 0x93AE, [11484] = 0x93AC, [11485] = 0x93B0, +- [11486] = 0x9398, [11487] = 0x939A, [11488] = 0x9397, [11489] = 0x95D4, +- [11490] = 0x95D6, [11491] = 0x95D0, [11492] = 0x95D5, [11493] = 0x96E2, +- [11494] = 0x96DC, [11495] = 0x96D9, [11496] = 0x96DB, [11497] = 0x96DE, +- [11498] = 0x9724, [11499] = 0x97A3, [11500] = 0x97A6, [11505] = 0x97AD, +- [11506] = 0x97F9, [11507] = 0x984D, [11508] = 0x984F, [11509] = 0x984C, +- [11510] = 0x984E, [11511] = 0x9853, [11512] = 0x98BA, [11513] = 0x993E, +- [11514] = 0x993F, [11515] = 0x993D, [11516] = 0x992E, [11517] = 0x99A5, +- [11518] = 0x9A0E, [11519] = 0x9AC1, [11520] = 0x9B03, [11521] = 0x9B06, +- [11522] = 0x9B4F, [11523] = 0x9B4E, [11524] = 0x9B4D, [11525] = 0x9BCA, +- [11526] = 0x9BC9, [11527] = 0x9BFD, [11528] = 0x9BC8, [11529] = 0x9BC0, +- [11530] = 0x9D51, [11531] = 0x9D5D, [11532] = 0x9D60, [11533] = 0x9EE0, +- [11534] = 0x9F15, [11535] = 0x9F2C, [11536] = 0x5133, [11537] = 0x56A5, +- [11538] = 0x58DE, [11539] = 0x58DF, [11540] = 0x58E2, [11541] = 0x5BF5, +- [11542] = 0x9F90, [11543] = 0x5EEC, [11544] = 0x61F2, [11545] = 0x61F7, +- [11546] = 0x61F6, [11547] = 0x61F5, [11548] = 0x6500, [11549] = 0x650F, +- [11550] = 0x66E0, [11551] = 0x66DD, [11552] = 0x6AE5, [11553] = 0x6ADD, +- [11554] = 0x6ADA, [11555] = 0x6AD3, [11556] = 0x701B, [11557] = 0x701F, +- [11558] = 0x7028, [11559] = 0x701A, [11560] = 0x701D, [11561] = 0x7015, +- [11562] = 0x7018, [11563] = 0x7206, [11564] = 0x720D, [11565] = 0x7258, +- [11566] = 0x72A2, [11567] = 0x7378, [11602] = 0x737A, [11603] = 0x74BD, +- [11604] = 0x74CA, [11605] = 0x74E3, [11606] = 0x7587, [11607] = 0x7586, +- [11608] = 0x765F, [11609] = 0x7661, [11610] = 0x77C7, [11611] = 0x7919, +- [11612] = 0x79B1, [11613] = 0x7A6B, [11614] = 0x7A69, [11615] = 0x7C3E, +- [11616] = 0x7C3F, [11617] = 0x7C38, [11618] = 0x7C3D, [11619] = 0x7C37, +- [11620] = 0x7C40, [11621] = 0x7E6B, [11622] = 0x7E6D, [11623] = 0x7E79, +- [11624] = 0x7E69, [11625] = 0x7E6A, [11626] = 0x7F85, [11627] = 0x7E73, +- [11628] = 0x7FB6, [11629] = 0x7FB9, [11630] = 0x7FB8, [11631] = 0x81D8, +- [11632] = 0x85E9, [11633] = 0x85DD, [11634] = 0x85EA, [11635] = 0x85D5, +- [11636] = 0x85E4, [11637] = 0x85E5, [11638] = 0x85F7, [11639] = 0x87FB, +- [11640] = 0x8805, [11641] = 0x880D, [11642] = 0x87F9, [11643] = 0x87FE, +- [11644] = 0x8960, [11645] = 0x895F, [11646] = 0x8956, [11647] = 0x895E, +- [11648] = 0x8B41, [11649] = 0x8B5C, [11650] = 0x8B58, [11651] = 0x8B49, +- [11652] = 0x8B5A, [11653] = 0x8B4E, [11654] = 0x8B4F, [11655] = 0x8B46, +- [11656] = 0x8B59, [11657] = 0x8D08, [11658] = 0x8D0A, [11659] = 0x8E7C, +- [11660] = 0x8E72, [11661] = 0x8E87, [11662] = 0x8E76, [11663] = 0x8E6C, +- [11664] = 0x8E7A, [11665] = 0x8E74, [11666] = 0x8F54, [11667] = 0x8F4E, +- [11668] = 0x8FAD, [11669] = 0x908A, [11670] = 0x908B, [11671] = 0x91B1, +- [11672] = 0x91AE, [11673] = 0x93E1, [11674] = 0x93D1, [11675] = 0x93DF, +- [11676] = 0x93C3, [11677] = 0x93C8, [11678] = 0x93DC, [11679] = 0x93DD, +- [11680] = 0x93D6, [11681] = 0x93E2, [11682] = 0x93CD, [11683] = 0x93D8, +- [11684] = 0x93E4, [11685] = 0x93D7, [11686] = 0x93E8, [11687] = 0x95DC, +- [11688] = 0x96B4, [11689] = 0x96E3, [11690] = 0x972A, [11691] = 0x9727, +- [11692] = 0x9761, [11693] = 0x97DC, [11694] = 0x97FB, [11695] = 0x985E, +- [11700] = 0x9858, [11701] = 0x985B, [11702] = 0x98BC, [11703] = 0x9945, +- [11704] = 0x9949, [11705] = 0x9A16, [11706] = 0x9A19, [11707] = 0x9B0D, +- [11708] = 0x9BE8, [11709] = 0x9BE7, [11710] = 0x9BD6, [11711] = 0x9BDB, +- [11712] = 0x9D89, [11713] = 0x9D61, [11714] = 0x9D72, [11715] = 0x9D6A, +- [11716] = 0x9D6C, [11717] = 0x9E92, [11718] = 0x9E97, [11719] = 0x9E93, +- [11720] = 0x9EB4, [11721] = 0x52F8, [11722] = 0x56A8, [11723] = 0x56B7, +- [11724] = 0x56B6, [11725] = 0x56B4, [11726] = 0x56BC, [11727] = 0x58E4, +- [11728] = 0x5B40, [11729] = 0x5B43, [11730] = 0x5B7D, [11731] = 0x5BF6, +- [11732] = 0x5DC9, [11733] = 0x61F8, [11734] = 0x61FA, [11735] = 0x6518, +- [11736] = 0x6514, [11737] = 0x6519, [11738] = 0x66E6, [11739] = 0x6727, +- [11740] = 0x6AEC, [11741] = 0x703E, [11742] = 0x7030, [11743] = 0x7032, +- [11744] = 0x7210, [11745] = 0x737B, [11746] = 0x74CF, [11747] = 0x7662, +- [11748] = 0x7665, [11749] = 0x7926, [11750] = 0x792A, [11751] = 0x792C, +- [11752] = 0x792B, [11753] = 0x7AC7, [11754] = 0x7AF6, [11755] = 0x7C4C, +- [11756] = 0x7C43, [11757] = 0x7C4D, [11758] = 0x7CEF, [11759] = 0x7CF0, +- [11760] = 0x8FAE, [11761] = 0x7E7D, [11762] = 0x7E7C, [11797] = 0x7E82, +- [11798] = 0x7F4C, [11799] = 0x8000, [11800] = 0x81DA, [11801] = 0x8266, +- [11802] = 0x85FB, [11803] = 0x85F9, [11804] = 0x8611, [11805] = 0x85FA, +- [11806] = 0x8606, [11807] = 0x860B, [11808] = 0x8607, [11809] = 0x860A, +- [11810] = 0x8814, [11811] = 0x8815, [11812] = 0x8964, [11813] = 0x89BA, +- [11814] = 0x89F8, [11815] = 0x8B70, [11816] = 0x8B6C, [11817] = 0x8B66, +- [11818] = 0x8B6F, [11819] = 0x8B5F, [11820] = 0x8B6B, [11821] = 0x8D0F, +- [11822] = 0x8D0D, [11823] = 0x8E89, [11824] = 0x8E81, [11825] = 0x8E85, +- [11826] = 0x8E82, [11827] = 0x91B4, [11828] = 0x91CB, [11829] = 0x9418, +- [11830] = 0x9403, [11831] = 0x93FD, [11832] = 0x95E1, [11833] = 0x9730, +- [11834] = 0x98C4, [11835] = 0x9952, [11836] = 0x9951, [11837] = 0x99A8, +- [11838] = 0x9A2B, [11839] = 0x9A30, [11840] = 0x9A37, [11841] = 0x9A35, +- [11842] = 0x9C13, [11843] = 0x9C0D, [11844] = 0x9E79, [11845] = 0x9EB5, +- [11846] = 0x9EE8, [11847] = 0x9F2F, [11848] = 0x9F5F, [11849] = 0x9F63, +- [11850] = 0x9F61, [11851] = 0x5137, [11852] = 0x5138, [11853] = 0x56C1, +- [11854] = 0x56C0, [11855] = 0x56C2, [11856] = 0x5914, [11857] = 0x5C6C, +- [11858] = 0x5DCD, [11859] = 0x61FC, [11860] = 0x61FE, [11861] = 0x651D, +- [11862] = 0x651C, [11863] = 0x6595, [11864] = 0x66E9, [11865] = 0x6AFB, +- [11866] = 0x6B04, [11867] = 0x6AFA, [11868] = 0x6BB2, [11869] = 0x704C, +- [11870] = 0x721B, [11871] = 0x72A7, [11872] = 0x74D6, [11873] = 0x74D4, +- [11874] = 0x7669, [11875] = 0x77D3, [11876] = 0x7C50, [11877] = 0x7E8F, +- [11878] = 0x7E8C, [11879] = 0x7FBC, [11880] = 0x8617, [11881] = 0x862D, +- [11882] = 0x861A, [11883] = 0x8823, [11884] = 0x8822, [11885] = 0x8821, +- [11886] = 0x881F, [11887] = 0x896A, [11888] = 0x896C, [11889] = 0x89BD, +- [11890] = 0x8B74, [11895] = 0x8B77, [11896] = 0x8B7D, [11897] = 0x8D13, +- [11898] = 0x8E8A, [11899] = 0x8E8D, [11900] = 0x8E8B, [11901] = 0x8F5F, +- [11902] = 0x8FAF, [11903] = 0x91BA, [11904] = 0x942E, [11905] = 0x9433, +- [11906] = 0x9435, [11907] = 0x943A, [11908] = 0x9438, [11909] = 0x9432, +- [11910] = 0x942B, [11911] = 0x95E2, [11912] = 0x9738, [11913] = 0x9739, +- [11914] = 0x9732, [11915] = 0x97FF, [11916] = 0x9867, [11917] = 0x9865, +- [11918] = 0x9957, [11919] = 0x9A45, [11920] = 0x9A43, [11921] = 0x9A40, +- [11922] = 0x9A3E, [11923] = 0x9ACF, [11924] = 0x9B54, [11925] = 0x9B51, +- [11926] = 0x9C2D, [11927] = 0x9C25, [11928] = 0x9DAF, [11929] = 0x9DB4, +- [11930] = 0x9DC2, [11931] = 0x9DB8, [11932] = 0x9E9D, [11933] = 0x9EEF, +- [11934] = 0x9F19, [11935] = 0x9F5C, [11936] = 0x9F66, [11937] = 0x9F67, +- [11938] = 0x513C, [11939] = 0x513B, [11940] = 0x56C8, [11941] = 0x56CA, +- [11942] = 0x56C9, [11943] = 0x5B7F, [11944] = 0x5DD4, [11945] = 0x5DD2, +- [11946] = 0x5F4E, [11947] = 0x61FF, [11948] = 0x6524, [11949] = 0x6B0A, +- [11950] = 0x6B61, [11951] = 0x7051, [11952] = 0x7058, [11953] = 0x7380, +- [11954] = 0x74E4, [11955] = 0x758A, [11956] = 0x766E, [11957] = 0x766C, +- [11992] = 0x79B3, [11993] = 0x7C60, [11994] = 0x7C5F, [11995] = 0x807E, +- [11996] = 0x807D, [11997] = 0x81DF, [11998] = 0x8972, [11999] = 0x896F, +- [12000] = 0x89FC, [12001] = 0x8B80, [12002] = 0x8D16, [12003] = 0x8D17, +- [12004] = 0x8E91, [12005] = 0x8E93, [12006] = 0x8F61, [12007] = 0x9148, +- [12008] = 0x9444, [12009] = 0x9451, [12010] = 0x9452, [12011] = 0x973D, +- [12012] = 0x973E, [12013] = 0x97C3, [12014] = 0x97C1, [12015] = 0x986B, +- [12016] = 0x9955, [12017] = 0x9A55, [12018] = 0x9A4D, [12019] = 0x9AD2, +- [12020] = 0x9B1A, [12021] = 0x9C49, [12022] = 0x9C31, [12023] = 0x9C3E, +- [12024] = 0x9C3B, [12025] = 0x9DD3, [12026] = 0x9DD7, [12027] = 0x9F34, +- [12028] = 0x9F6C, [12029] = 0x9F6A, [12030] = 0x9F94, [12031] = 0x56CC, +- [12032] = 0x5DD6, [12033] = 0x6200, [12034] = 0x6523, [12035] = 0x652B, +- [12036] = 0x652A, [12037] = 0x66EC, [12038] = 0x6B10, [12039] = 0x74DA, +- [12040] = 0x7ACA, [12041] = 0x7C64, [12042] = 0x7C63, [12043] = 0x7C65, +- [12044] = 0x7E93, [12045] = 0x7E96, [12046] = 0x7E94, [12047] = 0x81E2, +- [12048] = 0x8638, [12049] = 0x863F, [12050] = 0x8831, [12051] = 0x8B8A, +- [12052] = 0x9090, [12053] = 0x908F, [12054] = 0x9463, [12055] = 0x9460, +- [12056] = 0x9464, [12057] = 0x9768, [12058] = 0x986F, [12059] = 0x995C, +- [12060] = 0x9A5A, [12061] = 0x9A5B, [12062] = 0x9A57, [12063] = 0x9AD3, +- [12064] = 0x9AD4, [12065] = 0x9AD1, [12066] = 0x9C54, [12067] = 0x9C57, +- [12068] = 0x9C56, [12069] = 0x9DE5, [12070] = 0x9E9F, [12071] = 0x9EF4, +- [12072] = 0x56D1, [12073] = 0x58E9, [12074] = 0x652C, [12075] = 0x705E, +- [12076] = 0x7671, [12077] = 0x7672, [12078] = 0x77D7, [12079] = 0x7F50, +- [12080] = 0x7F88, [12081] = 0x8836, [12082] = 0x8839, [12083] = 0x8862, +- [12084] = 0x8B93, [12085] = 0x8B92, [12090] = 0x8B96, [12091] = 0x8277, +- [12092] = 0x8D1B, [12093] = 0x91C0, [12094] = 0x946A, [12095] = 0x9742, +- [12096] = 0x9748, [12097] = 0x9744, [12098] = 0x97C6, [12099] = 0x9870, +- [12100] = 0x9A5F, [12101] = 0x9B22, [12102] = 0x9B58, [12103] = 0x9C5F, +- [12104] = 0x9DF9, [12105] = 0x9DFA, [12106] = 0x9E7C, [12107] = 0x9E7D, +- [12108] = 0x9F07, [12109] = 0x9F77, [12110] = 0x9F72, [12111] = 0x5EF3, +- [12112] = 0x6B16, [12113] = 0x7063, [12114] = 0x7C6C, [12115] = 0x7C6E, +- [12116] = 0x883B, [12117] = 0x89C0, [12118] = 0x8EA1, [12119] = 0x91C1, +- [12120] = 0x9472, [12121] = 0x9470, [12122] = 0x9871, [12123] = 0x995E, +- [12124] = 0x9AD6, [12125] = 0x9B23, [12126] = 0x9ECC, [12127] = 0x7064, +- [12128] = 0x77DA, [12129] = 0x8B9A, [12130] = 0x9477, [12131] = 0x97C9, +- [12132] = 0x9A62, [12133] = 0x9A65, [12134] = 0x7E9C, [12135] = 0x8B9C, +- [12136] = 0x8EAA, [12137] = 0x91C5, [12138] = 0x947D, [12139] = 0x947E, +- [12140] = 0x947C, [12141] = 0x9C77, [12142] = 0x9C78, [12143] = 0x9EF7, +- [12144] = 0x8C54, [12145] = 0x947F, [12146] = 0x9E1A, [12147] = 0x7228, +- [12148] = 0x9A6A, [12149] = 0x9B31, [12150] = 0x9E1B, [12151] = 0x9E1E, +- [12152] = 0x7C72, [12187] = 0x2460, [12188] = 0x2461, [12189] = 0x2462, +- [12190] = 0x2463, [12191] = 0x2464, [12192] = 0x2465, [12193] = 0x2466, +- [12194] = 0x2467, [12195] = 0x2468, [12196] = 0x2469, [12197] = 0x2474, +- [12198] = 0x2475, [12199] = 0x2476, [12200] = 0x2477, [12201] = 0x2478, +- [12202] = 0x2479, [12203] = 0x247A, [12204] = 0x247B, [12205] = 0x247C, +- [12206] = 0x247D, [12207] = 0x2170, [12208] = 0x2171, [12209] = 0x2172, +- [12210] = 0x2173, [12211] = 0x2174, [12212] = 0x2175, [12213] = 0x2176, +- [12214] = 0x2177, [12215] = 0x2178, [12216] = 0x2179, [12217] = 0x4E36, +- [12218] = 0x4E3F, [12219] = 0x4E85, [12220] = 0x4EA0, [12221] = 0x5182, +- [12222] = 0x5196, [12223] = 0x51AB, [12224] = 0x52F9, [12225] = 0x5338, +- [12226] = 0x5369, [12227] = 0x53B6, [12228] = 0x590A, [12229] = 0x5B80, +- [12230] = 0x5DDB, [12231] = 0x2F33, [12232] = 0x5E7F, [12234] = 0x5F50, +- [12235] = 0x5F61, [12236] = 0x6534, [12238] = 0x7592, [12240] = 0x8FB5, +- [12242] = 0x00A8, [12243] = 0x02C6, [12244] = 0x30FD, [12245] = 0x30FE, +- [12246] = 0x309D, [12247] = 0x309E, [12250] = 0x3005, [12251] = 0x3006, +- [12252] = 0x3007, [12253] = 0x30FC, [12254] = 0xFF3B, [12255] = 0xFF3D, +- [12256] = 0x273D, [12257] = 0x3041, [12258] = 0x3042, [12259] = 0x3043, +- [12260] = 0x3044, [12261] = 0x3045, [12262] = 0x3046, [12263] = 0x3047, +- [12264] = 0x3048, [12265] = 0x3049, [12266] = 0x304A, [12267] = 0x304B, +- [12268] = 0x304C, [12269] = 0x304D, [12270] = 0x304E, [12271] = 0x304F, +- [12272] = 0x3050, [12273] = 0x3051, [12274] = 0x3052, [12275] = 0x3053, +- [12276] = 0x3054, [12277] = 0x3055, [12278] = 0x3056, [12279] = 0x3057, +- [12280] = 0x3058, [12285] = 0x3059, [12286] = 0x305A, [12287] = 0x305B, +- [12288] = 0x305C, [12289] = 0x305D, [12290] = 0x305E, [12291] = 0x305F, +- [12292] = 0x3060, [12293] = 0x3061, [12294] = 0x3062, [12295] = 0x3063, +- [12296] = 0x3064, [12297] = 0x3065, [12298] = 0x3066, [12299] = 0x3067, +- [12300] = 0x3068, [12301] = 0x3069, [12302] = 0x306A, [12303] = 0x306B, +- [12304] = 0x306C, [12305] = 0x306D, [12306] = 0x306E, [12307] = 0x306F, +- [12308] = 0x3070, [12309] = 0x3071, [12310] = 0x3072, [12311] = 0x3073, +- [12312] = 0x3074, [12313] = 0x3075, [12314] = 0x3076, [12315] = 0x3077, +- [12316] = 0x3078, [12317] = 0x3079, [12318] = 0x307A, [12319] = 0x307B, +- [12320] = 0x307C, [12321] = 0x307D, [12322] = 0x307E, [12323] = 0x307F, +- [12324] = 0x3080, [12325] = 0x3081, [12326] = 0x3082, [12327] = 0x3083, +- [12328] = 0x3084, [12329] = 0x3085, [12330] = 0x3086, [12331] = 0x3087, +- [12332] = 0x3088, [12333] = 0x3089, [12334] = 0x308A, [12335] = 0x308B, +- [12336] = 0x308C, [12337] = 0x308D, [12338] = 0x308E, [12339] = 0x308F, +- [12340] = 0x3090, [12341] = 0x3091, [12342] = 0x3092, [12343] = 0x3093, +- [12344] = 0x30A1, [12345] = 0x30A2, [12346] = 0x30A3, [12347] = 0x30A4, +- [12382] = 0x30A5, [12383] = 0x30A6, [12384] = 0x30A7, [12385] = 0x30A8, +- [12386] = 0x30A9, [12387] = 0x30AA, [12388] = 0x30AB, [12389] = 0x30AC, +- [12390] = 0x30AD, [12391] = 0x30AE, [12392] = 0x30AF, [12393] = 0x30B0, +- [12394] = 0x30B1, [12395] = 0x30B2, [12396] = 0x30B3, [12397] = 0x30B4, +- [12398] = 0x30B5, [12399] = 0x30B6, [12400] = 0x30B7, [12401] = 0x30B8, +- [12402] = 0x30B9, [12403] = 0x30BA, [12404] = 0x30BB, [12405] = 0x30BC, +- [12406] = 0x30BD, [12407] = 0x30BE, [12408] = 0x30BF, [12409] = 0x30C0, +- [12410] = 0x30C1, [12411] = 0x30C2, [12412] = 0x30C3, [12413] = 0x30C4, +- [12414] = 0x30C5, [12415] = 0x30C6, [12416] = 0x30C7, [12417] = 0x30C8, +- [12418] = 0x30C9, [12419] = 0x30CA, [12420] = 0x30CB, [12421] = 0x30CC, +- [12422] = 0x30CD, [12423] = 0x30CE, [12424] = 0x30CF, [12425] = 0x30D0, +- [12426] = 0x30D1, [12427] = 0x30D2, [12428] = 0x30D3, [12429] = 0x30D4, +- [12430] = 0x30D5, [12431] = 0x30D6, [12432] = 0x30D7, [12433] = 0x30D8, +- [12434] = 0x30D9, [12435] = 0x30DA, [12436] = 0x30DB, [12437] = 0x30DC, +- [12438] = 0x30DD, [12439] = 0x30DE, [12440] = 0x30DF, [12441] = 0x30E0, +- [12442] = 0x30E1, [12443] = 0x30E2, [12444] = 0x30E3, [12445] = 0x30E4, +- [12446] = 0x30E5, [12447] = 0x30E6, [12448] = 0x30E7, [12449] = 0x30E8, +- [12450] = 0x30E9, [12451] = 0x30EA, [12452] = 0x30EB, [12453] = 0x30EC, +- [12454] = 0x30ED, [12455] = 0x30EE, [12456] = 0x30EF, [12457] = 0x30F0, +- [12458] = 0x30F1, [12459] = 0x30F2, [12460] = 0x30F3, [12461] = 0x30F4, +- [12462] = 0x30F5, [12463] = 0x30F6, [12464] = 0x0410, [12465] = 0x0411, +- [12466] = 0x0412, [12467] = 0x0413, [12468] = 0x0414, [12469] = 0x0415, +- [12470] = 0x0401, [12471] = 0x0416, [12472] = 0x0417, [12473] = 0x0418, +- [12474] = 0x0419, [12475] = 0x041A, [12480] = 0x041B, [12481] = 0x041C, +- [12482] = 0x041D, [12483] = 0x041E, [12484] = 0x041F, [12485] = 0x0420, +- [12486] = 0x0421, [12487] = 0x0422, [12488] = 0x0423, [12489] = 0x0424, +- [12490] = 0x0425, [12491] = 0x0426, [12492] = 0x0427, [12493] = 0x0428, +- [12494] = 0x0429, [12495] = 0x042A, [12496] = 0x042B, [12497] = 0x042C, +- [12498] = 0x042D, [12499] = 0x042E, [12500] = 0x042F, [12501] = 0x0430, +- [12502] = 0x0431, [12503] = 0x0432, [12504] = 0x0433, [12505] = 0x0434, +- [12506] = 0x0435, [12507] = 0x0451, [12508] = 0x0436, [12509] = 0x0437, +- [12510] = 0x0438, [12511] = 0x0439, [12512] = 0x043A, [12513] = 0x043B, +- [12514] = 0x043C, [12515] = 0x043D, [12516] = 0x043E, [12517] = 0x043F, +- [12518] = 0x0440, [12519] = 0x0441, [12520] = 0x0442, [12521] = 0x0443, +- [12522] = 0x0444, [12523] = 0x0445, [12524] = 0x0446, [12525] = 0x0447, +- [12526] = 0x0448, [12527] = 0x0449, [12528] = 0x044A, [12529] = 0x044B, +- [12530] = 0x044C, [12531] = 0x044D, [12532] = 0x044E, [12533] = 0x044F, +- [12534] = 0x21E7, [12535] = 0x21B8, [12536] = 0x21B9, [12537] = 0xF7E5, +- [12538] = 0xF7E6, [12539] = 0x4E5A, [12540] = 0xF7E8, [12541] = 0x5202, +- [12542] = 0xF7EA, [12577] = 0xF7EB, [12578] = 0x5188, [12579] = 0xF7ED, +- [12580] = 0xF7EE, [12621] = 0xFFE2, [12622] = 0xFFE4, [12623] = 0xFF07, +- [12624] = 0xFF02, [12625] = 0x3231, [12626] = 0x2116, [12627] = 0x2121, +- [12628] = 0x309B, [12629] = 0x309C, [12630] = 0x2E80, [12631] = 0x2E84, +- [12632] = 0x2E86, [12633] = 0x2E87, [12634] = 0x2E88, [12635] = 0x2E8A, +- [12636] = 0x2E8C, [12637] = 0x2E8D, [12638] = 0x2E95, [12639] = 0x2E9C, +- [12640] = 0x2E9D, [12641] = 0x2EA5, [12642] = 0x2EA7, [12643] = 0x2EAA, +- [12644] = 0x2EAC, [12645] = 0x2EAE, [12646] = 0x2EB6, [12647] = 0x2EBC, +- [12648] = 0x2EBE, [12649] = 0x2EC6, [12650] = 0x2ECA, [12651] = 0x2ECC, +- [12652] = 0x2ECD, [12653] = 0x2ECF, [12654] = 0x2ED6, [12655] = 0x2ED7, +- [12656] = 0x2EDE, [12657] = 0x2EE3, [12661] = 0x0283, [12662] = 0x0250, +- [12663] = 0x025B, [12664] = 0x0254, [12665] = 0x0275, [12666] = 0x0153, +- [12667] = 0x00F8, [12668] = 0x014B, [12669] = 0x028A, [12670] = 0x026A, +- [12675] = 0x4E42, [12676] = 0x4E5C, [12677] = 0x51F5, [12678] = 0x531A, +- [12679] = 0x5382, [12680] = 0x4E07, [12681] = 0x4E0C, [12682] = 0x4E47, +- [12683] = 0x4E8D, [12684] = 0x56D7, [12685] = 0xFA0C, [12686] = 0x5C6E, +- [12687] = 0x5F73, [12688] = 0x4E0F, [12689] = 0x5187, [12690] = 0x4E0E, +- [12691] = 0x4E2E, [12692] = 0x4E93, [12693] = 0x4EC2, [12694] = 0x4EC9, +- [12695] = 0x4EC8, [12696] = 0x5198, [12697] = 0x52FC, [12698] = 0x536C, +- [12699] = 0x53B9, [12700] = 0x5720, [12701] = 0x5903, [12702] = 0x592C, +- [12703] = 0x5C10, [12704] = 0x5DFF, [12705] = 0x65E1, [12706] = 0x6BB3, +- [12707] = 0x6BCC, [12708] = 0x6C14, [12709] = 0x723F, [12710] = 0x4E31, +- [12711] = 0x4E3C, [12712] = 0x4EE8, [12713] = 0x4EDC, [12714] = 0x4EE9, +- [12715] = 0x4EE1, [12716] = 0x4EDD, [12717] = 0x4EDA, [12718] = 0x520C, +- [12719] = 0x531C, [12720] = 0x534C, [12721] = 0x5722, [12722] = 0x5723, +- [12723] = 0x5917, [12724] = 0x592F, [12725] = 0x5B81, [12726] = 0x5B84, +- [12727] = 0x5C12, [12728] = 0x5C3B, [12729] = 0x5C74, [12730] = 0x5C73, +- [12731] = 0x5E04, [12732] = 0x5E80, [12733] = 0x5E82, [12734] = 0x5FC9, +- [12735] = 0x6209, [12736] = 0x6250, [12737] = 0x6C15, [12772] = 0x6C36, +- [12773] = 0x6C43, [12774] = 0x6C3F, [12775] = 0x6C3B, [12776] = 0x72AE, +- [12777] = 0x72B0, [12778] = 0x738A, [12779] = 0x79B8, [12780] = 0x808A, +- [12781] = 0x961E, [12782] = 0x4F0E, [12783] = 0x4F18, [12784] = 0x4F2C, +- [12785] = 0x4EF5, [12786] = 0x4F14, [12787] = 0x4EF1, [12788] = 0x4F00, +- [12789] = 0x4EF7, [12790] = 0x4F08, [12791] = 0x4F1D, [12792] = 0x4F02, +- [12793] = 0x4F05, [12794] = 0x4F22, [12795] = 0x4F13, [12796] = 0x4F04, +- [12797] = 0x4EF4, [12798] = 0x4F12, [12799] = 0x51B1, [12800] = 0x5213, +- [12801] = 0x5209, [12802] = 0x5210, [12803] = 0x52A6, [12804] = 0x5322, +- [12805] = 0x531F, [12806] = 0x534D, [12807] = 0x538A, [12808] = 0x5407, +- [12809] = 0x56E1, [12810] = 0x56DF, [12811] = 0x572E, [12812] = 0x572A, +- [12813] = 0x5734, [12814] = 0x593C, [12815] = 0x5980, [12816] = 0x597C, +- [12817] = 0x5985, [12818] = 0x597B, [12819] = 0x597E, [12820] = 0x5977, +- [12821] = 0x597F, [12822] = 0x5B56, [12823] = 0x5C15, [12824] = 0x5C25, +- [12825] = 0x5C7C, [12826] = 0x5C7A, [12827] = 0x5C7B, [12828] = 0x5C7E, +- [12829] = 0x5DDF, [12830] = 0x5E75, [12831] = 0x5E84, [12832] = 0x5F02, +- [12833] = 0x5F1A, [12834] = 0x5F74, [12835] = 0x5FD5, [12836] = 0x5FD4, +- [12837] = 0x5FCF, [12838] = 0x625C, [12839] = 0x625E, [12840] = 0x6264, +- [12841] = 0x6261, [12842] = 0x6266, [12843] = 0x6262, [12844] = 0x6259, +- [12845] = 0x6260, [12846] = 0x625A, [12847] = 0x6265, [12848] = 0x65EF, +- [12849] = 0x65EE, [12850] = 0x673E, [12851] = 0x6739, [12852] = 0x6738, +- [12853] = 0x673B, [12854] = 0x673A, [12855] = 0x673F, [12856] = 0x673C, +- [12857] = 0x6733, [12858] = 0x6C18, [12859] = 0x6C46, [12860] = 0x6C52, +- [12861] = 0x6C5C, [12862] = 0x6C4F, [12863] = 0x6C4A, [12864] = 0x6C54, +- [12865] = 0x6C4B, [12870] = 0x6C4C, [12871] = 0x7071, [12872] = 0x725E, +- [12873] = 0x72B4, [12874] = 0x72B5, [12875] = 0x738E, [12876] = 0x752A, +- [12877] = 0x767F, [12878] = 0x7A75, [12879] = 0x7F51, [12880] = 0x8278, +- [12881] = 0x827C, [12882] = 0x8280, [12883] = 0x827D, [12884] = 0x827F, +- [12885] = 0x864D, [12886] = 0x897E, [12887] = 0x9099, [12888] = 0x9097, +- [12889] = 0x9098, [12890] = 0x909B, [12891] = 0x9094, [12892] = 0x9622, +- [12893] = 0x9624, [12894] = 0x9620, [12895] = 0x9623, [12896] = 0x4F56, +- [12897] = 0x4F3B, [12898] = 0x4F62, [12899] = 0x4F49, [12900] = 0x4F53, +- [12901] = 0x4F64, [12902] = 0x4F3E, [12903] = 0x4F67, [12904] = 0x4F52, +- [12905] = 0x4F5F, [12906] = 0x4F41, [12907] = 0x4F58, [12908] = 0x4F2D, +- [12909] = 0x4F33, [12910] = 0x4F3F, [12911] = 0x4F61, [12912] = 0x518F, +- [12913] = 0x51B9, [12914] = 0x521C, [12915] = 0x521E, [12916] = 0x5221, +- [12917] = 0x52AD, [12918] = 0x52AE, [12919] = 0x5309, [12920] = 0x5363, +- [12921] = 0x5372, [12922] = 0x538E, [12923] = 0x538F, [12924] = 0x5430, +- [12925] = 0x5437, [12926] = 0x542A, [12927] = 0x5454, [12928] = 0x5445, +- [12929] = 0x5419, [12930] = 0x541C, [12931] = 0x5425, [12932] = 0x5418, +- [12967] = 0x543D, [12968] = 0x544F, [12969] = 0x5441, [12970] = 0x5428, +- [12971] = 0x5424, [12972] = 0x5447, [12973] = 0x56EE, [12974] = 0x56E7, +- [12975] = 0x56E5, [12976] = 0x5741, [12977] = 0x5745, [12978] = 0x574C, +- [12979] = 0x5749, [12980] = 0x574B, [12981] = 0x5752, [12982] = 0x5906, +- [12983] = 0x5940, [12984] = 0x59A6, [12985] = 0x5998, [12986] = 0x59A0, +- [12987] = 0x5997, [12988] = 0x598E, [12989] = 0x59A2, [12990] = 0x5990, +- [12991] = 0x598F, [12992] = 0x59A7, [12993] = 0x59A1, [12994] = 0x5B8E, +- [12995] = 0x5B92, [12996] = 0x5C28, [12997] = 0x5C2A, [12998] = 0x5C8D, +- [12999] = 0x5C8F, [13000] = 0x5C88, [13001] = 0x5C8B, [13002] = 0x5C89, +- [13003] = 0x5C92, [13004] = 0x5C8A, [13005] = 0x5C86, [13006] = 0x5C93, +- [13007] = 0x5C95, [13008] = 0x5DE0, [13009] = 0x5E0A, [13010] = 0x5E0E, +- [13011] = 0x5E8B, [13012] = 0x5E89, [13013] = 0x5E8C, [13014] = 0x5E88, +- [13015] = 0x5E8D, [13016] = 0x5F05, [13017] = 0x5F1D, [13018] = 0x5F78, +- [13019] = 0x5F76, [13020] = 0x5FD2, [13021] = 0x5FD1, [13022] = 0x5FD0, +- [13023] = 0x5FED, [13024] = 0x5FE8, [13025] = 0x5FEE, [13026] = 0x5FF3, +- [13027] = 0x5FE1, [13028] = 0x5FE4, [13029] = 0x5FE3, [13030] = 0x5FFA, +- [13031] = 0x5FEF, [13032] = 0x5FF7, [13033] = 0x5FFB, [13034] = 0x6000, +- [13035] = 0x5FF4, [13036] = 0x623A, [13037] = 0x6283, [13038] = 0x628C, +- [13039] = 0x628E, [13040] = 0x628F, [13041] = 0x6294, [13042] = 0x6287, +- [13043] = 0x6271, [13044] = 0x627B, [13045] = 0x627A, [13046] = 0x6270, +- [13047] = 0x6281, [13048] = 0x6288, [13049] = 0x6277, [13050] = 0x627D, +- [13051] = 0x6272, [13052] = 0x6274, [13053] = 0x6537, [13054] = 0x65F0, +- [13055] = 0x65F4, [13056] = 0x65F3, [13057] = 0x65F2, [13058] = 0x65F5, +- [13059] = 0x6745, [13060] = 0x6747, [13065] = 0x6759, [13066] = 0x6755, +- [13067] = 0x674C, [13068] = 0x6748, [13069] = 0x675D, [13070] = 0x674D, +- [13071] = 0x675A, [13072] = 0x674B, [13073] = 0x6BD0, [13074] = 0x6C19, +- [13075] = 0x6C1A, [13076] = 0x6C78, [13077] = 0x6C67, [13078] = 0x6C6B, +- [13079] = 0x6C84, [13080] = 0x6C8B, [13081] = 0x6C8F, [13082] = 0x6C71, +- [13083] = 0x6C6F, [13084] = 0x6C69, [13085] = 0x6C9A, [13086] = 0x6C6D, +- [13087] = 0x6C87, [13088] = 0x6C95, [13089] = 0x6C9C, [13090] = 0x6C66, +- [13091] = 0x6C73, [13092] = 0x6C65, [13093] = 0x6C7B, [13094] = 0x6C8E, +- [13095] = 0x7074, [13096] = 0x707A, [13097] = 0x7263, [13098] = 0x72BF, +- [13099] = 0x72BD, [13100] = 0x72C3, [13101] = 0x72C6, [13102] = 0x72C1, +- [13103] = 0x72BA, [13104] = 0x72C5, [13105] = 0x7395, [13106] = 0x7397, +- [13107] = 0x7393, [13108] = 0x7394, [13109] = 0x7392, [13110] = 0x753A, +- [13111] = 0x7539, [13112] = 0x7594, [13113] = 0x7595, [13114] = 0x7681, +- [13115] = 0x793D, [13116] = 0x8034, [13117] = 0x8095, [13118] = 0x8099, +- [13119] = 0x8090, [13120] = 0x8092, [13121] = 0x809C, [13122] = 0x8290, +- [13123] = 0x828F, [13124] = 0x8285, [13125] = 0x828E, [13126] = 0x8291, +- [13127] = 0x8293, [13162] = 0x828A, [13163] = 0x8283, [13164] = 0x8284, +- [13165] = 0x8C78, [13166] = 0x8FC9, [13167] = 0x8FBF, [13168] = 0x909F, +- [13169] = 0x90A1, [13170] = 0x90A5, [13171] = 0x909E, [13172] = 0x90A7, +- [13173] = 0x90A0, [13174] = 0x9630, [13175] = 0x9628, [13176] = 0x962F, +- [13177] = 0x962D, [13178] = 0x4E33, [13179] = 0x4F98, [13180] = 0x4F7C, +- [13181] = 0x4F85, [13182] = 0x4F7D, [13183] = 0x4F80, [13184] = 0x4F87, +- [13185] = 0x4F76, [13186] = 0x4F74, [13187] = 0x4F89, [13188] = 0x4F84, +- [13189] = 0x4F77, [13190] = 0x4F4C, [13191] = 0x4F97, [13192] = 0x4F6A, +- [13193] = 0x4F9A, [13194] = 0x4F79, [13195] = 0x4F81, [13196] = 0x4F78, +- [13197] = 0x4F90, [13198] = 0x4F9C, [13199] = 0x4F94, [13200] = 0x4F9E, +- [13201] = 0x4F92, [13202] = 0x4F82, [13203] = 0x4F95, [13204] = 0x4F6B, +- [13205] = 0x4F6E, [13206] = 0x519E, [13207] = 0x51BC, [13208] = 0x51BE, +- [13209] = 0x5235, [13210] = 0x5232, [13211] = 0x5233, [13212] = 0x5246, +- [13213] = 0x5231, [13214] = 0x52BC, [13215] = 0x530A, [13216] = 0x530B, +- [13217] = 0x533C, [13218] = 0x5392, [13219] = 0x5394, [13220] = 0x5487, +- [13221] = 0x547F, [13222] = 0x5481, [13223] = 0x5491, [13224] = 0x5482, +- [13225] = 0x5488, [13226] = 0x546B, [13227] = 0x547A, [13228] = 0x547E, +- [13229] = 0x5465, [13230] = 0x546C, [13231] = 0x5474, [13232] = 0x5466, +- [13233] = 0x548D, [13234] = 0x546F, [13235] = 0x5461, [13236] = 0x5460, +- [13237] = 0x5498, [13238] = 0x5463, [13239] = 0x5467, [13240] = 0x5464, +- [13241] = 0x56F7, [13242] = 0x56F9, [13243] = 0x576F, [13244] = 0x5772, +- [13245] = 0x576D, [13246] = 0x576B, [13247] = 0x5771, [13248] = 0x5770, +- [13249] = 0x5776, [13250] = 0x5780, [13251] = 0x5775, [13252] = 0x577B, +- [13253] = 0x5773, [13254] = 0x5774, [13255] = 0x5762, [13260] = 0x5768, +- [13261] = 0x577D, [13262] = 0x590C, [13263] = 0x5945, [13264] = 0x59B5, +- [13265] = 0x59BA, [13266] = 0x59CF, [13267] = 0x59CE, [13268] = 0x59B2, +- [13269] = 0x59CC, [13270] = 0x59C1, [13271] = 0x59B6, [13272] = 0x59BC, +- [13273] = 0x59C3, [13274] = 0x59D6, [13275] = 0x59B1, [13276] = 0x59BD, +- [13277] = 0x59C0, [13278] = 0x59C8, [13279] = 0x59B4, [13280] = 0x59C7, +- [13281] = 0x5B62, [13282] = 0x5B65, [13283] = 0x5B93, [13284] = 0x5B95, +- [13285] = 0x5C44, [13286] = 0x5C47, [13287] = 0x5CAE, [13288] = 0x5CA4, +- [13289] = 0x5CA0, [13290] = 0x5CB5, [13291] = 0x5CAF, [13292] = 0x5CA8, +- [13293] = 0x5CAC, [13294] = 0x5C9F, [13295] = 0x5CA3, [13296] = 0x5CAD, +- [13297] = 0x5CA2, [13298] = 0x5CAA, [13299] = 0x5CA7, [13300] = 0x5C9D, +- [13301] = 0x5CA5, [13302] = 0x5CB6, [13303] = 0x5CB0, [13304] = 0x5CA6, +- [13305] = 0x5E17, [13306] = 0x5E14, [13307] = 0x5E19, [13308] = 0x5F28, +- [13309] = 0x5F22, [13310] = 0x5F23, [13311] = 0x5F24, [13312] = 0x5F54, +- [13313] = 0x5F82, [13314] = 0x5F7E, [13315] = 0x5F7D, [13316] = 0x5FDE, +- [13317] = 0x5FE5, [13318] = 0x602D, [13319] = 0x6026, [13320] = 0x6019, +- [13321] = 0x6032, [13322] = 0x600B, [13357] = 0x6034, [13358] = 0x600A, +- [13359] = 0x6017, [13360] = 0x6033, [13361] = 0x601A, [13362] = 0x601E, +- [13363] = 0x602C, [13364] = 0x6022, [13365] = 0x600D, [13366] = 0x6010, +- [13367] = 0x602E, [13368] = 0x6013, [13369] = 0x6011, [13370] = 0x600C, +- [13371] = 0x6009, [13372] = 0x601C, [13373] = 0x6214, [13374] = 0x623D, +- [13375] = 0x62AD, [13376] = 0x62B4, [13377] = 0x62D1, [13378] = 0x62BE, +- [13379] = 0x62AA, [13380] = 0x62B6, [13381] = 0x62CA, [13382] = 0x62AE, +- [13383] = 0x62B3, [13384] = 0x62AF, [13385] = 0x62BB, [13386] = 0x62A9, +- [13387] = 0x62B0, [13388] = 0x62B8, [13389] = 0x653D, [13390] = 0x65A8, +- [13391] = 0x65BB, [13392] = 0x6609, [13393] = 0x65FC, [13394] = 0x6604, +- [13395] = 0x6612, [13396] = 0x6608, [13397] = 0x65FB, [13398] = 0x6603, +- [13399] = 0x660B, [13400] = 0x660D, [13401] = 0x6605, [13402] = 0x65FD, +- [13403] = 0x6611, [13404] = 0x6610, [13405] = 0x66F6, [13406] = 0x670A, +- [13407] = 0x6785, [13408] = 0x676C, [13409] = 0x678E, [13410] = 0x6792, +- [13411] = 0x6776, [13412] = 0x677B, [13413] = 0x6798, [13414] = 0x6786, +- [13415] = 0x6784, [13416] = 0x6774, [13417] = 0x678D, [13418] = 0x678C, +- [13419] = 0x677A, [13420] = 0x679F, [13421] = 0x6791, [13422] = 0x6799, +- [13423] = 0x6783, [13424] = 0x677D, [13425] = 0x6781, [13426] = 0x6778, +- [13427] = 0x6779, [13428] = 0x6794, [13429] = 0x6B25, [13430] = 0x6B80, +- [13431] = 0x6B7E, [13432] = 0x6BDE, [13433] = 0x6C1D, [13434] = 0x6C93, +- [13435] = 0x6CEC, [13436] = 0x6CEB, [13437] = 0x6CEE, [13438] = 0x6CD9, +- [13439] = 0x6CB6, [13440] = 0x6CD4, [13441] = 0x6CAD, [13442] = 0x6CE7, +- [13443] = 0x6CB7, [13444] = 0x6CD0, [13445] = 0x6CC2, [13446] = 0x6CBA, +- [13447] = 0x6CC3, [13448] = 0x6CC6, [13449] = 0x6CED, [13450] = 0x6CF2, +- [13455] = 0x6CD2, [13456] = 0x6CDD, [13457] = 0x6CB4, [13458] = 0x6C8A, +- [13459] = 0x6C9D, [13460] = 0x6C80, [13461] = 0x6CDE, [13462] = 0x6CC0, +- [13463] = 0x6D30, [13464] = 0x6CCD, [13465] = 0x6CC7, [13466] = 0x6CB0, +- [13467] = 0x6CF9, [13468] = 0x6CCF, [13469] = 0x6CE9, [13470] = 0x6CD1, +- [13471] = 0x7094, [13472] = 0x7098, [13473] = 0x7085, [13474] = 0x7093, +- [13475] = 0x7086, [13476] = 0x7084, [13477] = 0x7091, [13478] = 0x7096, +- [13479] = 0x7082, [13480] = 0x709A, [13481] = 0x7083, [13482] = 0x726A, +- [13483] = 0x72D6, [13484] = 0x72CB, [13485] = 0x72D8, [13486] = 0x72C9, +- [13487] = 0x72DC, [13488] = 0x72D2, [13489] = 0x72D4, [13490] = 0x72DA, +- [13491] = 0x72CC, [13492] = 0x72D1, [13493] = 0x73A4, [13494] = 0x73A1, +- [13495] = 0x73AD, [13496] = 0x73A6, [13497] = 0x73A2, [13498] = 0x73A0, +- [13499] = 0x73AC, [13500] = 0x739D, [13501] = 0x74DD, [13502] = 0x74E8, +- [13503] = 0x753F, [13504] = 0x7540, [13505] = 0x753E, [13506] = 0x758C, +- [13507] = 0x7598, [13508] = 0x76AF, [13509] = 0x76F3, [13510] = 0x76F1, +- [13511] = 0x76F0, [13512] = 0x76F5, [13513] = 0x77F8, [13514] = 0x77FC, +- [13515] = 0x77F9, [13516] = 0x77FB, [13517] = 0x77FA, [13552] = 0x77F7, +- [13553] = 0x7942, [13554] = 0x793F, [13555] = 0x79C5, [13556] = 0x7A78, +- [13557] = 0x7A7B, [13558] = 0x7AFB, [13559] = 0x7C75, [13560] = 0x7CFD, +- [13561] = 0x8035, [13562] = 0x808F, [13563] = 0x80AE, [13564] = 0x80A3, +- [13565] = 0x80B8, [13566] = 0x80B5, [13567] = 0x80AD, [13568] = 0x8220, +- [13569] = 0x82A0, [13570] = 0x82C0, [13571] = 0x82AB, [13572] = 0x829A, +- [13573] = 0x8298, [13574] = 0x829B, [13575] = 0x82B5, [13576] = 0x82A7, +- [13577] = 0x82AE, [13578] = 0x82BC, [13579] = 0x829E, [13580] = 0x82BA, +- [13581] = 0x82B4, [13582] = 0x82A8, [13583] = 0x82A1, [13584] = 0x82A9, +- [13585] = 0x82C2, [13586] = 0x82A4, [13587] = 0x82C3, [13588] = 0x82B6, +- [13589] = 0x82A2, [13590] = 0x8670, [13591] = 0x866F, [13592] = 0x866D, +- [13593] = 0x866E, [13594] = 0x8C56, [13595] = 0x8FD2, [13596] = 0x8FCB, +- [13597] = 0x8FD3, [13598] = 0x8FCD, [13599] = 0x8FD6, [13600] = 0x8FD5, +- [13601] = 0x8FD7, [13602] = 0x90B2, [13603] = 0x90B4, [13604] = 0x90AF, +- [13605] = 0x90B3, [13606] = 0x90B0, [13607] = 0x9639, [13608] = 0x963D, +- [13609] = 0x963C, [13610] = 0x963A, [13611] = 0x9643, [13612] = 0x4FCD, +- [13613] = 0x4FC5, [13614] = 0x4FD3, [13615] = 0x4FB2, [13616] = 0x4FC9, +- [13617] = 0x4FCB, [13618] = 0x4FC1, [13619] = 0x4FD4, [13620] = 0x4FDC, +- [13621] = 0x4FD9, [13622] = 0x4FBB, [13623] = 0x4FB3, [13624] = 0x4FDB, +- [13625] = 0x4FC7, [13626] = 0x4FD6, [13627] = 0x4FBA, [13628] = 0x4FC0, +- [13629] = 0x4FB9, [13630] = 0x4FEC, [13631] = 0x5244, [13632] = 0x5249, +- [13633] = 0x52C0, [13634] = 0x52C2, [13635] = 0x533D, [13636] = 0x537C, +- [13637] = 0x5397, [13638] = 0x5396, [13639] = 0x5399, [13640] = 0x5398, +- [13641] = 0x54BA, [13642] = 0x54A1, [13643] = 0x54AD, [13644] = 0x54A5, +- [13645] = 0x54CF, [13650] = 0x54C3, [13651] = 0x830D, [13652] = 0x54B7, +- [13653] = 0x54AE, [13654] = 0x54D6, [13655] = 0x54B6, [13656] = 0x54C5, +- [13657] = 0x54C6, [13658] = 0x54A0, [13659] = 0x5470, [13660] = 0x54BC, +- [13661] = 0x54A2, [13662] = 0x54BE, [13663] = 0x5472, [13664] = 0x54DE, +- [13665] = 0x54B0, [13666] = 0x57B5, [13667] = 0x579E, [13668] = 0x579F, +- [13669] = 0x57A4, [13670] = 0x578C, [13671] = 0x5797, [13672] = 0x579D, +- [13673] = 0x579B, [13674] = 0x5794, [13675] = 0x5798, [13676] = 0x578F, +- [13677] = 0x5799, [13678] = 0x57A5, [13679] = 0x579A, [13680] = 0x5795, +- [13681] = 0x58F4, [13682] = 0x590D, [13683] = 0x5953, [13684] = 0x59E1, +- [13685] = 0x59DE, [13686] = 0x59EE, [13687] = 0x5A00, [13688] = 0x59F1, +- [13689] = 0x59DD, [13690] = 0x59FA, [13691] = 0x59FD, [13692] = 0x59FC, +- [13693] = 0x59F6, [13694] = 0x59E4, [13695] = 0x59F2, [13696] = 0x59F7, +- [13697] = 0x59DB, [13698] = 0x59E9, [13699] = 0x59F3, [13700] = 0x59F5, +- [13701] = 0x59E0, [13702] = 0x59FE, [13703] = 0x59F4, [13704] = 0x59ED, +- [13705] = 0x5BA8, [13706] = 0x5C4C, [13707] = 0x5CD0, [13708] = 0x5CD8, +- [13709] = 0x5CCC, [13710] = 0x5CD7, [13711] = 0x5CCB, [13712] = 0x5CDB, +- [13747] = 0x5CDE, [13748] = 0x5CDA, [13749] = 0x5CC9, [13750] = 0x5CC7, +- [13751] = 0x5CCA, [13752] = 0x5CD6, [13753] = 0x5CD3, [13754] = 0x5CD4, +- [13755] = 0x5CCF, [13756] = 0x5CC8, [13757] = 0x5CC6, [13758] = 0x5CCE, +- [13759] = 0x5CDF, [13760] = 0x5CF8, [13761] = 0x5DF9, [13762] = 0x5E21, +- [13763] = 0x5E22, [13764] = 0x5E23, [13765] = 0x5E20, [13766] = 0x5E24, +- [13767] = 0x5EB0, [13768] = 0x5EA4, [13769] = 0x5EA2, [13770] = 0x5E9B, +- [13771] = 0x5EA3, [13772] = 0x5EA5, [13773] = 0x5F07, [13774] = 0x5F2E, +- [13775] = 0x5F56, [13776] = 0x5F86, [13777] = 0x6037, [13778] = 0x6039, +- [13779] = 0x6054, [13780] = 0x6072, [13781] = 0x605E, [13782] = 0x6045, +- [13783] = 0x6053, [13784] = 0x6047, [13785] = 0x6049, [13786] = 0x605B, +- [13787] = 0x604C, [13788] = 0x6040, [13789] = 0x6042, [13790] = 0x605F, +- [13791] = 0x6024, [13792] = 0x6044, [13793] = 0x6058, [13794] = 0x6066, +- [13795] = 0x606E, [13796] = 0x6242, [13797] = 0x6243, [13798] = 0x62CF, +- [13799] = 0x630D, [13800] = 0x630B, [13801] = 0x62F5, [13802] = 0x630E, +- [13803] = 0x6303, [13804] = 0x62EB, [13805] = 0x62F9, [13806] = 0x630F, +- [13807] = 0x630C, [13808] = 0x62F8, [13809] = 0x62F6, [13810] = 0x6300, +- [13811] = 0x6313, [13812] = 0x6314, [13813] = 0x62FA, [13814] = 0x6315, +- [13815] = 0x62FB, [13816] = 0x62F0, [13817] = 0x6541, [13818] = 0x6543, +- [13819] = 0x65AA, [13820] = 0x65BF, [13821] = 0x6636, [13822] = 0x6621, +- [13823] = 0x6632, [13824] = 0x6635, [13825] = 0x661C, [13826] = 0x6626, +- [13827] = 0x6622, [13828] = 0x6633, [13829] = 0x662B, [13830] = 0x663A, +- [13831] = 0x661D, [13832] = 0x6634, [13833] = 0x6639, [13834] = 0x662E, +- [13835] = 0x670F, [13836] = 0x6710, [13837] = 0x67C1, [13838] = 0x67F2, +- [13839] = 0x67C8, [13840] = 0x67BA, [13845] = 0x67DC, [13846] = 0x67BB, +- [13847] = 0x67F8, [13848] = 0x67D8, [13849] = 0x67C0, [13850] = 0x67B7, +- [13851] = 0x67C5, [13852] = 0x67EB, [13853] = 0x67E4, [13854] = 0x67DF, +- [13855] = 0x67B5, [13856] = 0x67CD, [13857] = 0x67B3, [13858] = 0x67F7, +- [13859] = 0x67F6, [13860] = 0x67EE, [13861] = 0x67E3, [13862] = 0x67C2, +- [13863] = 0x67B9, [13864] = 0x67CE, [13865] = 0x67E7, [13866] = 0x67F0, +- [13867] = 0x67B2, [13868] = 0x67FC, [13869] = 0x67C6, [13870] = 0x67ED, +- [13871] = 0x67CC, [13872] = 0x67AE, [13873] = 0x67E6, [13874] = 0x67DB, +- [13875] = 0x67FA, [13876] = 0x67C9, [13877] = 0x67CA, [13878] = 0x67C3, +- [13879] = 0x67EA, [13880] = 0x67CB, [13881] = 0x6B28, [13882] = 0x6B82, +- [13883] = 0x6B84, [13884] = 0x6BB6, [13885] = 0x6BD6, [13886] = 0x6BD8, +- [13887] = 0x6BE0, [13888] = 0x6C20, [13889] = 0x6C21, [13890] = 0x6D28, +- [13891] = 0x6D34, [13892] = 0x6D2D, [13893] = 0x6D1F, [13894] = 0x6D3C, +- [13895] = 0x6D3F, [13896] = 0x6D12, [13897] = 0x6D0A, [13898] = 0x6CDA, +- [13899] = 0x6D33, [13900] = 0x6D04, [13901] = 0x6D19, [13902] = 0x6D3A, +- [13903] = 0x6D1A, [13904] = 0x6D11, [13905] = 0x6D00, [13906] = 0x6D1D, +- [13907] = 0x6D42, [13942] = 0x6D01, [13943] = 0x6D18, [13944] = 0x6D37, +- [13945] = 0x6D03, [13946] = 0x6D0F, [13947] = 0x6D40, [13948] = 0x6D07, +- [13949] = 0x6D20, [13950] = 0x6D2C, [13951] = 0x6D08, [13952] = 0x6D22, +- [13953] = 0x6D09, [13954] = 0x6D10, [13955] = 0x70B7, [13956] = 0x709F, +- [13957] = 0x70BE, [13958] = 0x70B1, [13959] = 0x70B0, [13960] = 0x70A1, +- [13961] = 0x70B4, [13962] = 0x70B5, [13963] = 0x70A9, [13964] = 0x7241, +- [13965] = 0x7249, [13966] = 0x724A, [13967] = 0x726C, [13968] = 0x7270, +- [13969] = 0x7273, [13970] = 0x726E, [13971] = 0x72CA, [13972] = 0x72E4, +- [13973] = 0x72E8, [13974] = 0x72EB, [13975] = 0x72DF, [13976] = 0x72EA, +- [13977] = 0x72E6, [13978] = 0x72E3, [13979] = 0x7385, [13980] = 0x73CC, +- [13981] = 0x73C2, [13982] = 0x73C8, [13983] = 0x73C5, [13984] = 0x73B9, +- [13985] = 0x73B6, [13986] = 0x73B5, [13987] = 0x73B4, [13988] = 0x73EB, +- [13989] = 0x73BF, [13990] = 0x73C7, [13991] = 0x73BE, [13992] = 0x73C3, +- [13993] = 0x73C6, [13994] = 0x73B8, [13995] = 0x73CB, [13996] = 0x74EC, +- [13997] = 0x74EE, [13998] = 0x752E, [13999] = 0x7547, [14000] = 0x7548, +- [14001] = 0x75A7, [14002] = 0x75AA, [14003] = 0x7679, [14004] = 0x76C4, +- [14005] = 0x7708, [14006] = 0x7703, [14007] = 0x7704, [14008] = 0x7705, +- [14009] = 0x770A, [14010] = 0x76F7, [14011] = 0x76FB, [14012] = 0x76FA, +- [14013] = 0x77E7, [14014] = 0x77E8, [14015] = 0x7806, [14016] = 0x7811, +- [14017] = 0x7812, [14018] = 0x7805, [14019] = 0x7810, [14020] = 0x780F, +- [14021] = 0x780E, [14022] = 0x7809, [14023] = 0x7803, [14024] = 0x7813, +- [14025] = 0x794A, [14026] = 0x794C, [14027] = 0x794B, [14028] = 0x7945, +- [14029] = 0x7944, [14030] = 0x79D5, [14031] = 0x79CD, [14032] = 0x79CF, +- [14033] = 0x79D6, [14034] = 0x79CE, [14035] = 0x7A80, [14040] = 0x7A7E, +- [14041] = 0x7AD1, [14042] = 0x7B00, [14043] = 0x7B01, [14044] = 0x7C7A, +- [14045] = 0x7C78, [14046] = 0x7C79, [14047] = 0x7C7F, [14048] = 0x7C80, +- [14049] = 0x7C81, [14050] = 0x7D03, [14051] = 0x7D08, [14052] = 0x7D01, +- [14053] = 0x7F58, [14054] = 0x7F91, [14055] = 0x7F8D, [14056] = 0x7FBE, +- [14057] = 0x8007, [14058] = 0x800E, [14059] = 0x800F, [14060] = 0x8014, +- [14061] = 0x8037, [14062] = 0x80D8, [14063] = 0x80C7, [14064] = 0x80E0, +- [14065] = 0x80D1, [14066] = 0x80C8, [14067] = 0x80C2, [14068] = 0x80D0, +- [14069] = 0x80C5, [14070] = 0x80E3, [14071] = 0x80D9, [14072] = 0x80DC, +- [14073] = 0x80CA, [14074] = 0x80D5, [14075] = 0x80C9, [14076] = 0x80CF, +- [14077] = 0x80D7, [14078] = 0x80E6, [14079] = 0x80CD, [14080] = 0x81FF, +- [14081] = 0x8221, [14082] = 0x8294, [14083] = 0x82D9, [14084] = 0x82FE, +- [14085] = 0x82F9, [14086] = 0x8307, [14087] = 0x82E8, [14088] = 0x8300, +- [14089] = 0x82D5, [14090] = 0x833A, [14091] = 0x82EB, [14092] = 0x82D6, +- [14093] = 0x82F4, [14094] = 0x82EC, [14095] = 0x82E1, [14096] = 0x82F2, +- [14097] = 0x82F5, [14098] = 0x830C, [14099] = 0x82FB, [14100] = 0x82F6, +- [14101] = 0x82F0, [14102] = 0x82EA, [14137] = 0x82E4, [14138] = 0x82E0, +- [14139] = 0x82FA, [14140] = 0x82F3, [14141] = 0x82ED, [14142] = 0x8677, +- [14143] = 0x8674, [14144] = 0x867C, [14145] = 0x8673, [14146] = 0x8841, +- [14147] = 0x884E, [14148] = 0x8867, [14149] = 0x886A, [14150] = 0x8869, +- [14151] = 0x89D3, [14152] = 0x8A04, [14153] = 0x8A07, [14154] = 0x8D72, +- [14155] = 0x8FE3, [14156] = 0x8FE1, [14157] = 0x8FEE, [14158] = 0x8FE0, +- [14159] = 0x90F1, [14160] = 0x90BD, [14161] = 0x90BF, [14162] = 0x90D5, +- [14163] = 0x90C5, [14164] = 0x90BE, [14165] = 0x90C7, [14166] = 0x90CB, +- [14167] = 0x90C8, [14168] = 0x91D4, [14169] = 0x91D3, [14170] = 0x9654, +- [14171] = 0x964F, [14172] = 0x9651, [14173] = 0x9653, [14174] = 0x964A, +- [14175] = 0x964E, [14176] = 0x501E, [14177] = 0x5005, [14178] = 0x5007, +- [14179] = 0x5013, [14180] = 0x5022, [14181] = 0x5030, [14182] = 0x501B, +- [14183] = 0x4FF5, [14184] = 0x4FF4, [14185] = 0x5033, [14186] = 0x5037, +- [14187] = 0x502C, [14188] = 0x4FF6, [14189] = 0x4FF7, [14190] = 0x5017, +- [14191] = 0x501C, [14192] = 0x5020, [14193] = 0x5027, [14194] = 0x5035, +- [14195] = 0x502F, [14196] = 0x5031, [14197] = 0x500E, [14198] = 0x515A, +- [14199] = 0x5194, [14200] = 0x5193, [14201] = 0x51CA, [14202] = 0x51C4, +- [14203] = 0x51C5, [14204] = 0x51C8, [14205] = 0x51CE, [14206] = 0x5261, +- [14207] = 0x525A, [14208] = 0x5252, [14209] = 0x525E, [14210] = 0x525F, +- [14211] = 0x5255, [14212] = 0x5262, [14213] = 0x52CD, [14214] = 0x530E, +- [14215] = 0x539E, [14216] = 0x5526, [14217] = 0x54E2, [14218] = 0x5517, +- [14219] = 0x5512, [14220] = 0x54E7, [14221] = 0x54F3, [14222] = 0x54E4, +- [14223] = 0x551A, [14224] = 0x54FF, [14225] = 0x5504, [14226] = 0x5508, +- [14227] = 0x54EB, [14228] = 0x5511, [14229] = 0x5505, [14230] = 0x54F1, +- [14235] = 0x550A, [14236] = 0x54FB, [14237] = 0x54F7, [14238] = 0x54F8, +- [14239] = 0x54E0, [14240] = 0x550E, [14241] = 0x5503, [14242] = 0x550B, +- [14243] = 0x5701, [14244] = 0x5702, [14245] = 0x57CC, [14246] = 0x5832, +- [14247] = 0x57D5, [14248] = 0x57D2, [14249] = 0x57BA, [14250] = 0x57C6, +- [14251] = 0x57BD, [14252] = 0x57BC, [14253] = 0x57B8, [14254] = 0x57B6, +- [14255] = 0x57BF, [14256] = 0x57C7, [14257] = 0x57D0, [14258] = 0x57B9, +- [14259] = 0x57C1, [14260] = 0x590E, [14261] = 0x594A, [14262] = 0x5A19, +- [14263] = 0x5A16, [14264] = 0x5A2D, [14265] = 0x5A2E, [14266] = 0x5A15, +- [14267] = 0x5A0F, [14268] = 0x5A17, [14269] = 0x5A0A, [14270] = 0x5A1E, +- [14271] = 0x5A33, [14272] = 0x5B6C, [14273] = 0x5BA7, [14274] = 0x5BAD, +- [14275] = 0x5BAC, [14276] = 0x5C03, [14277] = 0x5C56, [14278] = 0x5C54, +- [14279] = 0x5CEC, [14280] = 0x5CFF, [14281] = 0x5CEE, [14282] = 0x5CF1, +- [14283] = 0x5CF7, [14284] = 0x5D00, [14285] = 0x5CF9, [14286] = 0x5E29, +- [14287] = 0x5E28, [14288] = 0x5EA8, [14289] = 0x5EAE, [14290] = 0x5EAA, +- [14291] = 0x5EAC, [14292] = 0x5F33, [14293] = 0x5F30, [14294] = 0x5F67, +- [14295] = 0x605D, [14296] = 0x605A, [14297] = 0x6067, [14332] = 0x6041, +- [14333] = 0x60A2, [14334] = 0x6088, [14335] = 0x6080, [14336] = 0x6092, +- [14337] = 0x6081, [14338] = 0x609D, [14339] = 0x6083, [14340] = 0x6095, +- [14341] = 0x609B, [14342] = 0x6097, [14343] = 0x6087, [14344] = 0x609C, +- [14345] = 0x608E, [14346] = 0x6219, [14347] = 0x6246, [14348] = 0x62F2, +- [14349] = 0x6310, [14350] = 0x6356, [14351] = 0x632C, [14352] = 0x6344, +- [14353] = 0x6345, [14354] = 0x6336, [14355] = 0x6343, [14356] = 0x63E4, +- [14357] = 0x6339, [14358] = 0x634B, [14359] = 0x634A, [14360] = 0x633C, +- [14361] = 0x6329, [14362] = 0x6341, [14363] = 0x6334, [14364] = 0x6358, +- [14365] = 0x6354, [14366] = 0x6359, [14367] = 0x632D, [14368] = 0x6347, +- [14369] = 0x6333, [14370] = 0x635A, [14371] = 0x6351, [14372] = 0x6338, +- [14373] = 0x6357, [14374] = 0x6340, [14375] = 0x6348, [14376] = 0x654A, +- [14377] = 0x6546, [14378] = 0x65C6, [14379] = 0x65C3, [14380] = 0x65C4, +- [14381] = 0x65C2, [14382] = 0x664A, [14383] = 0x665F, [14384] = 0x6647, +- [14385] = 0x6651, [14386] = 0x6712, [14387] = 0x6713, [14388] = 0x681F, +- [14389] = 0x681A, [14390] = 0x6849, [14391] = 0x6832, [14392] = 0x6833, +- [14393] = 0x683B, [14394] = 0x684B, [14395] = 0x684F, [14396] = 0x6816, +- [14397] = 0x6831, [14398] = 0x681C, [14399] = 0x6835, [14400] = 0x682B, +- [14401] = 0x682D, [14402] = 0x682F, [14403] = 0x684E, [14404] = 0x6844, +- [14405] = 0x6834, [14406] = 0x681D, [14407] = 0x6812, [14408] = 0x6814, +- [14409] = 0x6826, [14410] = 0x6828, [14411] = 0x682E, [14412] = 0x684D, +- [14413] = 0x683A, [14414] = 0x6825, [14415] = 0x6820, [14416] = 0x6B2C, +- [14417] = 0x6B2F, [14418] = 0x6B2D, [14419] = 0x6B31, [14420] = 0x6B34, +- [14421] = 0x6B6D, [14422] = 0x8082, [14423] = 0x6B88, [14424] = 0x6BE6, +- [14425] = 0x6BE4, [14430] = 0x6BE8, [14431] = 0x6BE3, [14432] = 0x6BE2, +- [14433] = 0x6BE7, [14434] = 0x6C25, [14435] = 0x6D7A, [14436] = 0x6D63, +- [14437] = 0x6D64, [14438] = 0x6D76, [14439] = 0x6D0D, [14440] = 0x6D61, +- [14441] = 0x6D92, [14442] = 0x6D58, [14443] = 0x6D62, [14444] = 0x6D6D, +- [14445] = 0x6D6F, [14446] = 0x6D91, [14447] = 0x6D8D, [14448] = 0x6DEF, +- [14449] = 0x6D7F, [14450] = 0x6D86, [14451] = 0x6D5E, [14452] = 0x6D67, +- [14453] = 0x6D60, [14454] = 0x6D97, [14455] = 0x6D70, [14456] = 0x6D7C, +- [14457] = 0x6D5F, [14458] = 0x6D82, [14459] = 0x6D98, [14460] = 0x6D2F, +- [14461] = 0x6D68, [14462] = 0x6D8B, [14463] = 0x6D7E, [14464] = 0x6D80, +- [14465] = 0x6D84, [14466] = 0x6D16, [14467] = 0x6D83, [14468] = 0x6D7B, +- [14469] = 0x6D7D, [14470] = 0x6D75, [14471] = 0x6D90, [14472] = 0x70DC, +- [14473] = 0x70D3, [14474] = 0x70D1, [14475] = 0x70DD, [14476] = 0x70CB, +- [14477] = 0x7F39, [14478] = 0x70E2, [14479] = 0x70D7, [14480] = 0x70D2, +- [14481] = 0x70DE, [14482] = 0x70E0, [14483] = 0x70D4, [14484] = 0x70CD, +- [14485] = 0x70C5, [14486] = 0x70C6, [14487] = 0x70C7, [14488] = 0x70DA, +- [14489] = 0x70CE, [14490] = 0x70E1, [14491] = 0x7242, [14492] = 0x7278, +- [14527] = 0x7277, [14528] = 0x7276, [14529] = 0x7300, [14530] = 0x72FA, +- [14531] = 0x72F4, [14532] = 0x72FE, [14533] = 0x72F6, [14534] = 0x72F3, +- [14535] = 0x72FB, [14536] = 0x7301, [14537] = 0x73D3, [14538] = 0x73D9, +- [14539] = 0x73E5, [14540] = 0x73D6, [14541] = 0x73BC, [14542] = 0x73E7, +- [14543] = 0x73E3, [14544] = 0x73E9, [14545] = 0x73DC, [14546] = 0x73D2, +- [14547] = 0x73DB, [14548] = 0x73D4, [14549] = 0x73DD, [14550] = 0x73DA, +- [14551] = 0x73D7, [14552] = 0x73D8, [14553] = 0x73E8, [14554] = 0x74DE, +- [14555] = 0x74DF, [14556] = 0x74F4, [14557] = 0x74F5, [14558] = 0x7521, +- [14559] = 0x755B, [14560] = 0x755F, [14561] = 0x75B0, [14562] = 0x75C1, +- [14563] = 0x75BB, [14564] = 0x75C4, [14565] = 0x75C0, [14566] = 0x75BF, +- [14567] = 0x75B6, [14568] = 0x75BA, [14569] = 0x768A, [14570] = 0x76C9, +- [14571] = 0x771D, [14572] = 0x771B, [14573] = 0x7710, [14574] = 0x7713, +- [14575] = 0x7712, [14576] = 0x7723, [14577] = 0x7711, [14578] = 0x7715, +- [14579] = 0x7719, [14580] = 0x771A, [14581] = 0x7722, [14582] = 0x7727, +- [14583] = 0x7823, [14584] = 0x782C, [14585] = 0x7822, [14586] = 0x7835, +- [14587] = 0x782F, [14588] = 0x7828, [14589] = 0x782E, [14590] = 0x782B, +- [14591] = 0x7821, [14592] = 0x7829, [14593] = 0x7833, [14594] = 0x782A, +- [14595] = 0x7831, [14596] = 0x7954, [14597] = 0x795B, [14598] = 0x794F, +- [14599] = 0x795C, [14600] = 0x7953, [14601] = 0x7952, [14602] = 0x7951, +- [14603] = 0x79EB, [14604] = 0x79EC, [14605] = 0x79E0, [14606] = 0x79EE, +- [14607] = 0x79ED, [14608] = 0x79EA, [14609] = 0x79DC, [14610] = 0x79DE, +- [14611] = 0x79DD, [14612] = 0x7A86, [14613] = 0x7A89, [14614] = 0x7A85, +- [14615] = 0x7A8B, [14616] = 0x7A8C, [14617] = 0x7A8A, [14618] = 0x7A87, +- [14619] = 0x7AD8, [14620] = 0x7B10, [14625] = 0x7B04, [14626] = 0x7B13, +- [14627] = 0x7B05, [14628] = 0x7B0F, [14629] = 0x7B08, [14630] = 0x7B0A, +- [14631] = 0x7B0E, [14632] = 0x7B09, [14633] = 0x7B12, [14634] = 0x7C84, +- [14635] = 0x7C91, [14636] = 0x7C8A, [14637] = 0x7C8C, [14638] = 0x7C88, +- [14639] = 0x7C8D, [14640] = 0x7C85, [14641] = 0x7D1E, [14642] = 0x7D1D, +- [14643] = 0x7D11, [14644] = 0x7D0E, [14645] = 0x7D18, [14646] = 0x7D16, +- [14647] = 0x7D13, [14648] = 0x7D1F, [14649] = 0x7D12, [14650] = 0x7D0F, +- [14651] = 0x7D0C, [14652] = 0x7F5C, [14653] = 0x7F61, [14654] = 0x7F5E, +- [14655] = 0x7F60, [14656] = 0x7F5D, [14657] = 0x7F5B, [14658] = 0x7F96, +- [14659] = 0x7F92, [14660] = 0x7FC3, [14661] = 0x7FC2, [14662] = 0x7FC0, +- [14663] = 0x8016, [14664] = 0x803E, [14665] = 0x8039, [14666] = 0x80FA, +- [14667] = 0x80F2, [14668] = 0x80F9, [14669] = 0x80F5, [14670] = 0x8101, +- [14671] = 0x80FB, [14672] = 0x8100, [14673] = 0x8201, [14674] = 0x822F, +- [14675] = 0x8225, [14676] = 0x8333, [14677] = 0x832D, [14678] = 0x8344, +- [14679] = 0x8319, [14680] = 0x8351, [14681] = 0x8325, [14682] = 0x8356, +- [14683] = 0x833F, [14684] = 0x8341, [14685] = 0x8326, [14686] = 0x831C, +- [14687] = 0x8322, [14722] = 0x8342, [14723] = 0x834E, [14724] = 0x831B, +- [14725] = 0x832A, [14726] = 0x8308, [14727] = 0x833C, [14728] = 0x834D, +- [14729] = 0x8316, [14730] = 0x8324, [14731] = 0x8320, [14732] = 0x8337, +- [14733] = 0x832F, [14734] = 0x8329, [14735] = 0x8347, [14736] = 0x8345, +- [14737] = 0x834C, [14738] = 0x8353, [14739] = 0x831E, [14740] = 0x832C, +- [14741] = 0x834B, [14742] = 0x8327, [14743] = 0x8348, [14744] = 0x8653, +- [14745] = 0x8652, [14746] = 0x86A2, [14747] = 0x86A8, [14748] = 0x8696, +- [14749] = 0x868D, [14750] = 0x8691, [14751] = 0x869E, [14752] = 0x8687, +- [14753] = 0x8697, [14754] = 0x8686, [14755] = 0x868B, [14756] = 0x869A, +- [14757] = 0x8685, [14758] = 0x86A5, [14759] = 0x8699, [14760] = 0x86A1, +- [14761] = 0x86A7, [14762] = 0x8695, [14763] = 0x8698, [14764] = 0x868E, +- [14765] = 0x869D, [14766] = 0x8690, [14767] = 0x8694, [14768] = 0x8843, +- [14769] = 0x8844, [14770] = 0x886D, [14771] = 0x8875, [14772] = 0x8876, +- [14773] = 0x8872, [14774] = 0x8880, [14775] = 0x8871, [14776] = 0x887F, +- [14777] = 0x886F, [14778] = 0x8883, [14779] = 0x887E, [14780] = 0x8874, +- [14781] = 0x887C, [14782] = 0x8A12, [14783] = 0x8C47, [14784] = 0x8C57, +- [14785] = 0x8C7B, [14786] = 0x8CA4, [14787] = 0x8CA3, [14788] = 0x8D76, +- [14789] = 0x8D78, [14790] = 0x8DB5, [14791] = 0x8DB7, [14792] = 0x8DB6, +- [14793] = 0x8ED1, [14794] = 0x8ED3, [14795] = 0x8FFE, [14796] = 0x8FF5, +- [14797] = 0x9002, [14798] = 0x8FFF, [14799] = 0x8FFB, [14800] = 0x9004, +- [14801] = 0x8FFC, [14802] = 0x8FF6, [14803] = 0x90D6, [14804] = 0x90E0, +- [14805] = 0x90D9, [14806] = 0x90DA, [14807] = 0x90E3, [14808] = 0x90DF, +- [14809] = 0x90E5, [14810] = 0x90D8, [14811] = 0x90DB, [14812] = 0x90D7, +- [14813] = 0x90DC, [14814] = 0x90E4, [14815] = 0x9150, [14820] = 0x914E, +- [14821] = 0x914F, [14822] = 0x91D5, [14823] = 0x91E2, [14824] = 0x91DA, +- [14825] = 0x965C, [14826] = 0x965F, [14827] = 0x96BC, [14828] = 0x98E3, +- [14829] = 0x9ADF, [14830] = 0x9B2F, [14831] = 0x4E7F, [14832] = 0x5070, +- [14833] = 0x506A, [14834] = 0x5061, [14835] = 0x505E, [14836] = 0x5060, +- [14837] = 0x5053, [14838] = 0x504B, [14839] = 0x505D, [14840] = 0x5072, +- [14841] = 0x5048, [14842] = 0x504D, [14843] = 0x5041, [14844] = 0x505B, +- [14845] = 0x504A, [14846] = 0x5062, [14847] = 0x5015, [14848] = 0x5045, +- [14849] = 0x505F, [14850] = 0x5069, [14851] = 0x506B, [14852] = 0x5063, +- [14853] = 0x5064, [14854] = 0x5046, [14855] = 0x5040, [14856] = 0x506E, +- [14857] = 0x5073, [14858] = 0x5057, [14859] = 0x5051, [14860] = 0x51D0, +- [14861] = 0x526B, [14862] = 0x526D, [14863] = 0x526C, [14864] = 0x526E, +- [14865] = 0x52D6, [14866] = 0x52D3, [14867] = 0x532D, [14868] = 0x539C, +- [14869] = 0x5575, [14870] = 0x5576, [14871] = 0x553C, [14872] = 0x554D, +- [14873] = 0x5550, [14874] = 0x5534, [14875] = 0x552A, [14876] = 0x5551, +- [14877] = 0x5562, [14878] = 0x5536, [14879] = 0x5535, [14880] = 0x5530, +- [14881] = 0x5552, [14882] = 0x5545, [14917] = 0x550C, [14918] = 0x5532, +- [14919] = 0x5565, [14920] = 0x554E, [14921] = 0x5539, [14922] = 0x5548, +- [14923] = 0x552D, [14924] = 0x553B, [14925] = 0x5540, [14926] = 0x554B, +- [14927] = 0x570A, [14928] = 0x5707, [14929] = 0x57FB, [14930] = 0x5814, +- [14931] = 0x57E2, [14932] = 0x57F6, [14933] = 0x57DC, [14934] = 0x57F4, +- [14935] = 0x5800, [14936] = 0x57ED, [14937] = 0x57FD, [14938] = 0x5808, +- [14939] = 0x57F8, [14940] = 0x580B, [14941] = 0x57F3, [14942] = 0x57CF, +- [14943] = 0x5807, [14944] = 0x57EE, [14945] = 0x57E3, [14946] = 0x57F2, +- [14947] = 0x57E5, [14948] = 0x57EC, [14949] = 0x57E1, [14950] = 0x580E, +- [14951] = 0x57FC, [14952] = 0x5810, [14953] = 0x57E7, [14954] = 0x5801, +- [14955] = 0x580C, [14956] = 0x57F1, [14957] = 0x57E9, [14958] = 0x57F0, +- [14959] = 0x580D, [14960] = 0x5804, [14961] = 0x595C, [14962] = 0x5A60, +- [14963] = 0x5A58, [14964] = 0x5A55, [14965] = 0x5A67, [14966] = 0x5A5E, +- [14967] = 0x5A38, [14968] = 0x5A35, [14969] = 0x5A6D, [14970] = 0x5A50, +- [14971] = 0x5A5F, [14972] = 0x5A65, [14973] = 0x5A6C, [14974] = 0x5A53, +- [14975] = 0x5A64, [14976] = 0x5A57, [14977] = 0x5A43, [14978] = 0x5A5D, +- [14979] = 0x5A52, [14980] = 0x5A44, [14981] = 0x5A5B, [14982] = 0x5A48, +- [14983] = 0x5A8E, [14984] = 0x5A3E, [14985] = 0x5A4D, [14986] = 0x5A39, +- [14987] = 0x5A4C, [14988] = 0x5A70, [14989] = 0x5A69, [14990] = 0x5A47, +- [14991] = 0x5A51, [14992] = 0x5A56, [14993] = 0x5A42, [14994] = 0x5A5C, +- [14995] = 0x5B72, [14996] = 0x5B6E, [14997] = 0x5BC1, [14998] = 0x5BC0, +- [14999] = 0x5C59, [15000] = 0x5D1E, [15001] = 0x5D0B, [15002] = 0x5D1D, +- [15003] = 0x5D1A, [15004] = 0x5D20, [15005] = 0x5D0C, [15006] = 0x5D28, +- [15007] = 0x5D0D, [15008] = 0x5D26, [15009] = 0x5D25, [15010] = 0x5D0F, +- [15015] = 0x5D30, [15016] = 0x5D12, [15017] = 0x5D23, [15018] = 0x5D1F, +- [15019] = 0x5D2E, [15020] = 0x5E3E, [15021] = 0x5E34, [15022] = 0x5EB1, +- [15023] = 0x5EB4, [15024] = 0x5EB9, [15025] = 0x5EB2, [15026] = 0x5EB3, +- [15027] = 0x5F36, [15028] = 0x5F38, [15029] = 0x5F9B, [15030] = 0x5F96, +- [15031] = 0x5F9F, [15032] = 0x608A, [15033] = 0x6090, [15034] = 0x6086, +- [15035] = 0x60BE, [15036] = 0x60B0, [15037] = 0x60BA, [15038] = 0x60D3, +- [15039] = 0x60D4, [15040] = 0x60CF, [15041] = 0x60E4, [15042] = 0x60D9, +- [15043] = 0x60DD, [15044] = 0x60C8, [15045] = 0x60B1, [15046] = 0x60DB, +- [15047] = 0x60B7, [15048] = 0x60CA, [15049] = 0x60BF, [15050] = 0x60C3, +- [15051] = 0x60CD, [15052] = 0x60C0, [15053] = 0x6332, [15054] = 0x6365, +- [15055] = 0x638A, [15056] = 0x6382, [15057] = 0x637D, [15058] = 0x63BD, +- [15059] = 0x639E, [15060] = 0x63AD, [15061] = 0x639D, [15062] = 0x6397, +- [15063] = 0x63AB, [15064] = 0x638E, [15065] = 0x636F, [15066] = 0x6387, +- [15067] = 0x6390, [15068] = 0x636E, [15069] = 0x63AF, [15070] = 0x6375, +- [15071] = 0x639C, [15072] = 0x636D, [15073] = 0x63AE, [15074] = 0x637C, +- [15075] = 0x63A4, [15076] = 0x633B, [15077] = 0x639F, [15112] = 0x6378, +- [15113] = 0x6385, [15114] = 0x6381, [15115] = 0x6391, [15116] = 0x638D, +- [15117] = 0x6370, [15118] = 0x6553, [15119] = 0x65CD, [15120] = 0x6665, +- [15121] = 0x6661, [15122] = 0x665B, [15123] = 0x6659, [15124] = 0x665C, +- [15125] = 0x6662, [15126] = 0x6718, [15127] = 0x6879, [15128] = 0x6887, +- [15129] = 0x6890, [15130] = 0x689C, [15131] = 0x686D, [15132] = 0x686E, +- [15133] = 0x68AE, [15134] = 0x68AB, [15135] = 0x6956, [15136] = 0x686F, +- [15137] = 0x68A3, [15138] = 0x68AC, [15139] = 0x68A9, [15140] = 0x6875, +- [15141] = 0x6874, [15142] = 0x68B2, [15143] = 0x688F, [15144] = 0x6877, +- [15145] = 0x6892, [15146] = 0x687C, [15147] = 0x686B, [15148] = 0x6872, +- [15149] = 0x68AA, [15150] = 0x6880, [15151] = 0x6871, [15152] = 0x687E, +- [15153] = 0x689B, [15154] = 0x6896, [15155] = 0x688B, [15156] = 0x68A0, +- [15157] = 0x6889, [15158] = 0x68A4, [15159] = 0x6878, [15160] = 0x687B, +- [15161] = 0x6891, [15162] = 0x688C, [15163] = 0x688A, [15164] = 0x687D, +- [15165] = 0x6B36, [15166] = 0x6B33, [15167] = 0x6B37, [15168] = 0x6B38, +- [15169] = 0x6B91, [15170] = 0x6B8F, [15171] = 0x6B8D, [15172] = 0x6B8E, +- [15173] = 0x6B8C, [15174] = 0x6C2A, [15175] = 0x6DC0, [15176] = 0x6DAB, +- [15177] = 0x6DB4, [15178] = 0x6DB3, [15179] = 0x6E74, [15180] = 0x6DAC, +- [15181] = 0x6DE9, [15182] = 0x6DE2, [15183] = 0x6DB7, [15184] = 0x6DF6, +- [15185] = 0x6DD4, [15186] = 0x6E00, [15187] = 0x6DC8, [15188] = 0x6DE0, +- [15189] = 0x6DDF, [15190] = 0x6DD6, [15191] = 0x6DBE, [15192] = 0x6DE5, +- [15193] = 0x6DDC, [15194] = 0x6DDD, [15195] = 0x6DDB, [15196] = 0x6DF4, +- [15197] = 0x6DCA, [15198] = 0x6DBD, [15199] = 0x6DED, [15200] = 0x6DF0, +- [15201] = 0x6DBA, [15202] = 0x6DD5, [15203] = 0x6DC2, [15204] = 0x6DCF, +- [15205] = 0x6DC9, [15210] = 0x6DD0, [15211] = 0x6DF2, [15212] = 0x6DD3, +- [15213] = 0x6DFD, [15214] = 0x6DD7, [15215] = 0x6DCD, [15216] = 0x6DE3, +- [15217] = 0x6DBB, [15218] = 0x70FA, [15219] = 0x710D, [15220] = 0x70F7, +- [15221] = 0x7117, [15222] = 0x70F4, [15223] = 0x710C, [15224] = 0x70F0, +- [15225] = 0x7104, [15226] = 0x70F3, [15227] = 0x7110, [15228] = 0x70FC, +- [15229] = 0x70FF, [15230] = 0x7106, [15231] = 0x7113, [15232] = 0x7100, +- [15233] = 0x70F8, [15234] = 0x70F6, [15235] = 0x710B, [15236] = 0x7102, +- [15237] = 0x710E, [15238] = 0x727E, [15239] = 0x727B, [15240] = 0x727C, +- [15241] = 0x727F, [15242] = 0x731D, [15243] = 0x7317, [15244] = 0x7307, +- [15245] = 0x7311, [15246] = 0x7318, [15247] = 0x730A, [15248] = 0x7308, +- [15249] = 0x72FF, [15250] = 0x730F, [15251] = 0x731E, [15252] = 0x7388, +- [15253] = 0x73F6, [15254] = 0x73F8, [15255] = 0x73F5, [15256] = 0x7404, +- [15257] = 0x7401, [15258] = 0x73FD, [15259] = 0x7407, [15260] = 0x7400, +- [15261] = 0x73FA, [15262] = 0x73FC, [15263] = 0x73FF, [15264] = 0x740C, +- [15265] = 0x740B, [15266] = 0x73F4, [15267] = 0x7408, [15268] = 0x7564, +- [15269] = 0x7563, [15270] = 0x75CE, [15271] = 0x75D2, [15272] = 0x75CF, +- [15307] = 0x75CB, [15308] = 0x75CC, [15309] = 0x75D1, [15310] = 0x75D0, +- [15311] = 0x768F, [15312] = 0x7689, [15313] = 0x76D3, [15314] = 0x7739, +- [15315] = 0x772F, [15316] = 0x772D, [15317] = 0x7731, [15318] = 0x7732, +- [15319] = 0x7734, [15320] = 0x7733, [15321] = 0x773D, [15322] = 0x7725, +- [15323] = 0x773B, [15324] = 0x7735, [15325] = 0x7848, [15326] = 0x7852, +- [15327] = 0x7849, [15328] = 0x784D, [15329] = 0x784A, [15330] = 0x784C, +- [15331] = 0x7826, [15332] = 0x7845, [15333] = 0x7850, [15334] = 0x7964, +- [15335] = 0x7967, [15336] = 0x7969, [15337] = 0x796A, [15338] = 0x7963, +- [15339] = 0x796B, [15340] = 0x7961, [15341] = 0x79BB, [15342] = 0x79FA, +- [15343] = 0x79F8, [15344] = 0x79F6, [15345] = 0x79F7, [15346] = 0x7A8F, +- [15347] = 0x7A94, [15348] = 0x7A90, [15349] = 0x7B35, [15350] = 0x7B47, +- [15351] = 0x7B34, [15352] = 0x7B25, [15353] = 0x7B30, [15354] = 0x7B22, +- [15355] = 0x7B24, [15356] = 0x7B33, [15357] = 0x7B18, [15358] = 0x7B2A, +- [15359] = 0x7B1D, [15360] = 0x7B31, [15361] = 0x7B2B, [15362] = 0x7B2D, +- [15363] = 0x7B2F, [15364] = 0x7B32, [15365] = 0x7B38, [15366] = 0x7B1A, +- [15367] = 0x7B23, [15368] = 0x7C94, [15369] = 0x7C98, [15370] = 0x7C96, +- [15371] = 0x7CA3, [15372] = 0x7D35, [15373] = 0x7D3D, [15374] = 0x7D38, +- [15375] = 0x7D36, [15376] = 0x7D3A, [15377] = 0x7D45, [15378] = 0x7D2C, +- [15379] = 0x7D29, [15380] = 0x7D41, [15381] = 0x7D47, [15382] = 0x7D3E, +- [15383] = 0x7D3F, [15384] = 0x7D4A, [15385] = 0x7D3B, [15386] = 0x7D28, +- [15387] = 0x7F63, [15388] = 0x7F95, [15389] = 0x7F9C, [15390] = 0x7F9D, +- [15391] = 0x7F9B, [15392] = 0x7FCA, [15393] = 0x7FCB, [15394] = 0x7FCD, +- [15395] = 0x7FD0, [15396] = 0x7FD1, [15397] = 0x7FC7, [15398] = 0x7FCF, +- [15399] = 0x7FC9, [15400] = 0x801F, [15405] = 0x801E, [15406] = 0x801B, +- [15407] = 0x8047, [15408] = 0x8043, [15409] = 0x8048, [15410] = 0x8118, +- [15411] = 0x8125, [15412] = 0x8119, [15413] = 0x811B, [15414] = 0x812D, +- [15415] = 0x811F, [15416] = 0x812C, [15417] = 0x811E, [15418] = 0x8121, +- [15419] = 0x8115, [15420] = 0x8127, [15421] = 0x811D, [15422] = 0x8122, +- [15423] = 0x8211, [15424] = 0x8238, [15425] = 0x8233, [15426] = 0x823A, +- [15427] = 0x8234, [15428] = 0x8232, [15429] = 0x8274, [15430] = 0x8390, +- [15431] = 0x83A3, [15432] = 0x83A8, [15433] = 0x838D, [15434] = 0x837A, +- [15435] = 0x8373, [15436] = 0x83A4, [15437] = 0x8374, [15438] = 0x838F, +- [15439] = 0x8381, [15440] = 0x8395, [15441] = 0x8399, [15442] = 0x8375, +- [15443] = 0x8394, [15444] = 0x83A9, [15445] = 0x837D, [15446] = 0x8383, +- [15447] = 0x838C, [15448] = 0x839D, [15449] = 0x839B, [15450] = 0x83AA, +- [15451] = 0x838B, [15452] = 0x837E, [15453] = 0x83A5, [15454] = 0x83AF, +- [15455] = 0x8388, [15456] = 0x8397, [15457] = 0x83B0, [15458] = 0x837F, +- [15459] = 0x83A6, [15460] = 0x8387, [15461] = 0x83AE, [15462] = 0x8376, +- [15463] = 0x839A, [15464] = 0x8659, [15465] = 0x8656, [15466] = 0x86BF, +- [15467] = 0x86B7, [15502] = 0x86C2, [15503] = 0x86C1, [15504] = 0x86C5, +- [15505] = 0x86BA, [15506] = 0x86B0, [15507] = 0x86C8, [15508] = 0x86B9, +- [15509] = 0x86B3, [15510] = 0x86B8, [15511] = 0x86CC, [15512] = 0x86B4, +- [15513] = 0x86BB, [15514] = 0x86BC, [15515] = 0x86C3, [15516] = 0x86BD, +- [15517] = 0x86BE, [15518] = 0x8852, [15519] = 0x8889, [15520] = 0x8895, +- [15521] = 0x88A8, [15522] = 0x88A2, [15523] = 0x88AA, [15524] = 0x889A, +- [15525] = 0x8891, [15526] = 0x88A1, [15527] = 0x889F, [15528] = 0x8898, +- [15529] = 0x88A7, [15530] = 0x8899, [15531] = 0x889B, [15532] = 0x8897, +- [15533] = 0x88A4, [15534] = 0x88AC, [15535] = 0x888C, [15536] = 0x8893, +- [15537] = 0x888E, [15538] = 0x8982, [15539] = 0x89D6, [15540] = 0x89D9, +- [15541] = 0x89D5, [15542] = 0x8A30, [15543] = 0x8A27, [15544] = 0x8A2C, +- [15545] = 0x8A1E, [15546] = 0x8C39, [15547] = 0x8C3B, [15548] = 0x8C5C, +- [15549] = 0x8C5D, [15550] = 0x8C7D, [15551] = 0x8CA5, [15552] = 0x8D7D, +- [15553] = 0x8D7B, [15554] = 0x8D79, [15555] = 0x8DBC, [15556] = 0x8DC2, +- [15557] = 0x8DB9, [15558] = 0x8DBF, [15559] = 0x8DC1, [15560] = 0x8ED8, +- [15561] = 0x8EDE, [15562] = 0x8EDD, [15563] = 0x8EDC, [15564] = 0x8ED7, +- [15565] = 0x8EE0, [15566] = 0x8EE1, [15567] = 0x9024, [15568] = 0x900B, +- [15569] = 0x9011, [15570] = 0x901C, [15571] = 0x900C, [15572] = 0x9021, +- [15573] = 0x90EF, [15574] = 0x90EA, [15575] = 0x90F0, [15576] = 0x90F4, +- [15577] = 0x90F2, [15578] = 0x90F3, [15579] = 0x90D4, [15580] = 0x90EB, +- [15581] = 0x90EC, [15582] = 0x90E9, [15583] = 0x9156, [15584] = 0x9158, +- [15585] = 0x915A, [15586] = 0x9153, [15587] = 0x9155, [15588] = 0x91EC, +- [15589] = 0x91F4, [15590] = 0x91F1, [15591] = 0x91F3, [15592] = 0x91F8, +- [15593] = 0x91E4, [15594] = 0x91F9, [15595] = 0x91EA, [15600] = 0x91EB, +- [15601] = 0x91F7, [15602] = 0x91E8, [15603] = 0x91EE, [15604] = 0x957A, +- [15605] = 0x9586, [15606] = 0x9588, [15607] = 0x967C, [15608] = 0x966D, +- [15609] = 0x966B, [15610] = 0x9671, [15611] = 0x966F, [15612] = 0x96BF, +- [15613] = 0x976A, [15614] = 0x9804, [15615] = 0x98E5, [15616] = 0x9997, +- [15617] = 0x509B, [15618] = 0x5095, [15619] = 0x5094, [15620] = 0x509E, +- [15621] = 0x508B, [15622] = 0x50A3, [15623] = 0x5083, [15624] = 0x508C, +- [15625] = 0x508E, [15626] = 0x509D, [15627] = 0x5068, [15628] = 0x509C, +- [15629] = 0x5092, [15630] = 0x5082, [15631] = 0x5087, [15632] = 0x515F, +- [15633] = 0x51D4, [15634] = 0x5312, [15635] = 0x5311, [15636] = 0x53A4, +- [15637] = 0x53A7, [15638] = 0x5591, [15639] = 0x55A8, [15640] = 0x55A5, +- [15641] = 0x55AD, [15642] = 0x5577, [15643] = 0x5645, [15644] = 0x55A2, +- [15645] = 0x5593, [15646] = 0x5588, [15647] = 0x558F, [15648] = 0x55B5, +- [15649] = 0x5581, [15650] = 0x55A3, [15651] = 0x5592, [15652] = 0x55A4, +- [15653] = 0x557D, [15654] = 0x558C, [15655] = 0x55A6, [15656] = 0x557F, +- [15657] = 0x5595, [15658] = 0x55A1, [15659] = 0x558E, [15660] = 0x570C, +- [15661] = 0x5829, [15662] = 0x5837, [15697] = 0x5819, [15698] = 0x581E, +- [15699] = 0x5827, [15700] = 0x5823, [15701] = 0x5828, [15702] = 0x57F5, +- [15703] = 0x5848, [15704] = 0x5825, [15705] = 0x581C, [15706] = 0x581B, +- [15707] = 0x5833, [15708] = 0x583F, [15709] = 0x5836, [15710] = 0x582E, +- [15711] = 0x5839, [15712] = 0x5838, [15713] = 0x582D, [15714] = 0x582C, +- [15715] = 0x583B, [15716] = 0x5961, [15717] = 0x5AAF, [15718] = 0x5A94, +- [15719] = 0x5A9F, [15720] = 0x5A7A, [15721] = 0x5AA2, [15722] = 0x5A9E, +- [15723] = 0x5A78, [15724] = 0x5AA6, [15725] = 0x5A7C, [15726] = 0x5AA5, +- [15727] = 0x5AAC, [15728] = 0x5A95, [15729] = 0x5AAE, [15730] = 0x5A37, +- [15731] = 0x5A84, [15732] = 0x5A8A, [15733] = 0x5A97, [15734] = 0x5A83, +- [15735] = 0x5A8B, [15736] = 0x5AA9, [15737] = 0x5A7B, [15738] = 0x5A7D, +- [15739] = 0x5A8C, [15740] = 0x5A9C, [15741] = 0x5A8F, [15742] = 0x5A93, +- [15743] = 0x5A9D, [15744] = 0x5BEA, [15745] = 0x5BCD, [15746] = 0x5BCB, +- [15747] = 0x5BD4, [15748] = 0x5BD1, [15749] = 0x5BCA, [15750] = 0x5BCE, +- [15751] = 0x5C0C, [15752] = 0x5C30, [15753] = 0x5D37, [15754] = 0x5D43, +- [15755] = 0x5D6B, [15756] = 0x5D41, [15757] = 0x5D4B, [15758] = 0x5D3F, +- [15759] = 0x5D35, [15760] = 0x5D51, [15761] = 0x5D4E, [15762] = 0x5D55, +- [15763] = 0x5D33, [15764] = 0x5D3A, [15765] = 0x5D52, [15766] = 0x5D3D, +- [15767] = 0x5D31, [15768] = 0x5D59, [15769] = 0x5D42, [15770] = 0x5D39, +- [15771] = 0x5D49, [15772] = 0x5D38, [15773] = 0x5D3C, [15774] = 0x5D32, +- [15775] = 0x5D36, [15776] = 0x5D40, [15777] = 0x5D45, [15778] = 0x5E44, +- [15779] = 0x5E41, [15780] = 0x5F58, [15781] = 0x5FA6, [15782] = 0x5FA5, +- [15783] = 0x5FAB, [15784] = 0x60C9, [15785] = 0x60B9, [15786] = 0x60CC, +- [15787] = 0x60E2, [15788] = 0x60CE, [15789] = 0x60C4, [15790] = 0x6114, +- [15795] = 0x60F2, [15796] = 0x610A, [15797] = 0x6116, [15798] = 0x6105, +- [15799] = 0x60F5, [15800] = 0x6113, [15801] = 0x60F8, [15802] = 0x60FC, +- [15803] = 0x60FE, [15804] = 0x60C1, [15805] = 0x6103, [15806] = 0x6118, +- [15807] = 0x611D, [15808] = 0x6110, [15809] = 0x60FF, [15810] = 0x6104, +- [15811] = 0x610B, [15812] = 0x624A, [15813] = 0x6394, [15814] = 0x63B1, +- [15815] = 0x63B0, [15816] = 0x63CE, [15817] = 0x63E5, [15818] = 0x63E8, +- [15819] = 0x63EF, [15820] = 0x63C3, [15821] = 0x649D, [15822] = 0x63F3, +- [15823] = 0x63CA, [15824] = 0x63E0, [15825] = 0x63F6, [15826] = 0x63D5, +- [15827] = 0x63F2, [15828] = 0x63F5, [15829] = 0x6461, [15830] = 0x63DF, +- [15831] = 0x63BE, [15832] = 0x63DD, [15833] = 0x63DC, [15834] = 0x63C4, +- [15835] = 0x63D8, [15836] = 0x63D3, [15837] = 0x63C2, [15838] = 0x63C7, +- [15839] = 0x63CC, [15840] = 0x63CB, [15841] = 0x63C8, [15842] = 0x63F0, +- [15843] = 0x63D7, [15844] = 0x63D9, [15845] = 0x6532, [15846] = 0x6567, +- [15847] = 0x656A, [15848] = 0x6564, [15849] = 0x655C, [15850] = 0x6568, +- [15851] = 0x6565, [15852] = 0x658C, [15853] = 0x659D, [15854] = 0x659E, +- [15855] = 0x65AE, [15856] = 0x65D0, [15857] = 0x65D2, [15892] = 0x667C, +- [15893] = 0x666C, [15894] = 0x667B, [15895] = 0x6680, [15896] = 0x6671, +- [15897] = 0x6679, [15898] = 0x666A, [15899] = 0x6672, [15900] = 0x6701, +- [15901] = 0x690C, [15902] = 0x68D3, [15903] = 0x6904, [15904] = 0x68DC, +- [15905] = 0x692A, [15906] = 0x68EC, [15907] = 0x68EA, [15908] = 0x68F1, +- [15909] = 0x690F, [15910] = 0x68D6, [15911] = 0x68F7, [15912] = 0x68EB, +- [15913] = 0x68E4, [15914] = 0x68F6, [15915] = 0x6913, [15916] = 0x6910, +- [15917] = 0x68F3, [15918] = 0x68E1, [15919] = 0x6907, [15920] = 0x68CC, +- [15921] = 0x6908, [15922] = 0x6970, [15923] = 0x68B4, [15924] = 0x6911, +- [15925] = 0x68EF, [15926] = 0x68C6, [15927] = 0x6914, [15928] = 0x68F8, +- [15929] = 0x68D0, [15930] = 0x68FD, [15931] = 0x68FC, [15932] = 0x68E8, +- [15933] = 0x690B, [15934] = 0x690A, [15935] = 0x6917, [15936] = 0x68CE, +- [15937] = 0x68C8, [15938] = 0x68DD, [15939] = 0x68DE, [15940] = 0x68E6, +- [15941] = 0x68F4, [15942] = 0x68D1, [15943] = 0x6906, [15944] = 0x68D4, +- [15945] = 0x68E9, [15946] = 0x6915, [15947] = 0x6925, [15948] = 0x68C7, +- [15949] = 0x6B39, [15950] = 0x6B3B, [15951] = 0x6B3F, [15952] = 0x6B3C, +- [15953] = 0x6B94, [15954] = 0x6B97, [15955] = 0x6B99, [15956] = 0x6B95, +- [15957] = 0x6BBD, [15958] = 0x6BF0, [15959] = 0x6BF2, [15960] = 0x6BF3, +- [15961] = 0x6C30, [15962] = 0x6DFC, [15963] = 0x6E46, [15964] = 0x6E47, +- [15965] = 0x6E1F, [15966] = 0x6E49, [15967] = 0x6E88, [15968] = 0x6E3C, +- [15969] = 0x6E3D, [15970] = 0x6E45, [15971] = 0x6E62, [15972] = 0x6E2B, +- [15973] = 0x6E3F, [15974] = 0x6E41, [15975] = 0x6E5D, [15976] = 0x6E73, +- [15977] = 0x6E1C, [15978] = 0x6E33, [15979] = 0x6E4B, [15980] = 0x6E40, +- [15981] = 0x6E51, [15982] = 0x6E3B, [15983] = 0x6E03, [15984] = 0x6E2E, +- [15985] = 0x6E5E, [15990] = 0x6E68, [15991] = 0x6E5C, [15992] = 0x6E61, +- [15993] = 0x6E31, [15994] = 0x6E28, [15995] = 0x6E60, [15996] = 0x6E71, +- [15997] = 0x6E6B, [15998] = 0x6E39, [15999] = 0x6E22, [16000] = 0x6E30, +- [16001] = 0x6E53, [16002] = 0x6E65, [16003] = 0x6E27, [16004] = 0x6E78, +- [16005] = 0x6E64, [16006] = 0x6E77, [16007] = 0x6E55, [16008] = 0x6E79, +- [16009] = 0x6E52, [16010] = 0x6E66, [16011] = 0x6E35, [16012] = 0x6E36, +- [16013] = 0x6E5A, [16014] = 0x7120, [16015] = 0x711E, [16016] = 0x712F, +- [16017] = 0x70FB, [16018] = 0x712E, [16019] = 0x7131, [16020] = 0x7123, +- [16021] = 0x7125, [16022] = 0x7122, [16023] = 0x7132, [16024] = 0x711F, +- [16025] = 0x7128, [16026] = 0x713A, [16027] = 0x711B, [16028] = 0x724B, +- [16029] = 0x725A, [16030] = 0x7288, [16031] = 0x7289, [16032] = 0x7286, +- [16033] = 0x7285, [16034] = 0x728B, [16035] = 0x7312, [16036] = 0x730B, +- [16037] = 0x7330, [16038] = 0x7322, [16039] = 0x7331, [16040] = 0x7333, +- [16041] = 0x7327, [16042] = 0x7332, [16043] = 0x732D, [16044] = 0x7326, +- [16045] = 0x7323, [16046] = 0x7335, [16047] = 0x730C, [16048] = 0x742E, +- [16049] = 0x742C, [16050] = 0x7430, [16051] = 0x742B, [16052] = 0x7416, +- [16087] = 0x741A, [16088] = 0x7421, [16089] = 0x742D, [16090] = 0x7431, +- [16091] = 0x7424, [16092] = 0x7423, [16093] = 0x741D, [16094] = 0x7429, +- [16095] = 0x7420, [16096] = 0x7432, [16097] = 0x74FB, [16098] = 0x752F, +- [16099] = 0x756F, [16100] = 0x756C, [16101] = 0x75E7, [16102] = 0x75DA, +- [16103] = 0x75E1, [16104] = 0x75E6, [16105] = 0x75DD, [16106] = 0x75DF, +- [16107] = 0x75E4, [16108] = 0x75D7, [16109] = 0x7695, [16110] = 0x7692, +- [16111] = 0x76DA, [16112] = 0x7746, [16113] = 0x7747, [16114] = 0x7744, +- [16115] = 0x774D, [16116] = 0x7745, [16117] = 0x774A, [16118] = 0x774E, +- [16119] = 0x774B, [16120] = 0x774C, [16121] = 0x77DE, [16122] = 0x77EC, +- [16123] = 0x7860, [16124] = 0x7864, [16125] = 0x7865, [16126] = 0x785C, +- [16127] = 0x786D, [16128] = 0x7871, [16129] = 0x786A, [16130] = 0x786E, +- [16131] = 0x7870, [16132] = 0x7869, [16133] = 0x7868, [16134] = 0x785E, +- [16135] = 0x7862, [16136] = 0x7974, [16137] = 0x7973, [16138] = 0x7972, +- [16139] = 0x7970, [16140] = 0x7A02, [16141] = 0x7A0A, [16142] = 0x7A03, +- [16143] = 0x7A0C, [16144] = 0x7A04, [16145] = 0x7A99, [16146] = 0x7AE6, +- [16147] = 0x7AE4, [16148] = 0x7B4A, [16149] = 0x7B3B, [16150] = 0x7B44, +- [16151] = 0x7B48, [16152] = 0x7B4C, [16153] = 0x7B4E, [16154] = 0x7B40, +- [16155] = 0x7B58, [16156] = 0x7B45, [16157] = 0x7CA2, [16158] = 0x7C9E, +- [16159] = 0x7CA8, [16160] = 0x7CA1, [16161] = 0x7D58, [16162] = 0x7D6F, +- [16163] = 0x7D63, [16164] = 0x7D53, [16165] = 0x7D56, [16166] = 0x7D67, +- [16167] = 0x7D6A, [16168] = 0x7D4F, [16169] = 0x7D6D, [16170] = 0x7D5C, +- [16171] = 0x7D6B, [16172] = 0x7D52, [16173] = 0x7D54, [16174] = 0x7D69, +- [16175] = 0x7D51, [16176] = 0x7D5F, [16177] = 0x7D4E, [16178] = 0x7F3E, +- [16179] = 0x7F3F, [16180] = 0x7F65, [16185] = 0x7F66, [16186] = 0x7FA2, +- [16187] = 0x7FA0, [16188] = 0x7FA1, [16189] = 0x7FD7, [16190] = 0x8051, +- [16191] = 0x804F, [16192] = 0x8050, [16193] = 0x80FE, [16194] = 0x80D4, +- [16195] = 0x8143, [16196] = 0x814A, [16197] = 0x8152, [16198] = 0x814F, +- [16199] = 0x8147, [16200] = 0x813D, [16201] = 0x814D, [16202] = 0x813A, +- [16203] = 0x81E6, [16204] = 0x81EE, [16205] = 0x81F7, [16206] = 0x81F8, +- [16207] = 0x81F9, [16208] = 0x8204, [16209] = 0x823C, [16210] = 0x823D, +- [16211] = 0x823F, [16212] = 0x8275, [16213] = 0x833B, [16214] = 0x83CF, +- [16215] = 0x83F9, [16216] = 0x8423, [16217] = 0x83C0, [16218] = 0x83E8, +- [16219] = 0x8412, [16220] = 0x83E7, [16221] = 0x83E4, [16222] = 0x83FC, +- [16223] = 0x83F6, [16224] = 0x8410, [16225] = 0x83C6, [16226] = 0x83C8, +- [16227] = 0x83EB, [16228] = 0x83E3, [16229] = 0x83BF, [16230] = 0x8401, +- [16231] = 0x83DD, [16232] = 0x83E5, [16233] = 0x83D8, [16234] = 0x83FF, +- [16235] = 0x83E1, [16236] = 0x83CB, [16237] = 0x83CE, [16238] = 0x83D6, +- [16239] = 0x83F5, [16240] = 0x83C9, [16241] = 0x8409, [16242] = 0x840F, +- [16243] = 0x83DE, [16244] = 0x8411, [16245] = 0x8406, [16246] = 0x83C2, +- [16247] = 0x83F3, [16282] = 0x83D5, [16283] = 0x83FA, [16284] = 0x83C7, +- [16285] = 0x83D1, [16286] = 0x83EA, [16287] = 0x8413, [16288] = 0x83C3, +- [16289] = 0x83EC, [16290] = 0x83EE, [16291] = 0x83C4, [16292] = 0x83FB, +- [16293] = 0x83D7, [16294] = 0x83E2, [16295] = 0x841B, [16296] = 0x83DB, +- [16297] = 0x83FE, [16298] = 0x86D8, [16299] = 0x86E2, [16300] = 0x86E6, +- [16301] = 0x86D3, [16302] = 0x86E3, [16303] = 0x86DA, [16304] = 0x86EA, +- [16305] = 0x86DD, [16306] = 0x86EB, [16307] = 0x86DC, [16308] = 0x86EC, +- [16309] = 0x86E9, [16310] = 0x86D7, [16311] = 0x86E8, [16312] = 0x86D1, +- [16313] = 0x8848, [16314] = 0x8856, [16315] = 0x8855, [16316] = 0x88BA, +- [16317] = 0x88D7, [16318] = 0x88B9, [16319] = 0x88B8, [16320] = 0x88C0, +- [16321] = 0x88BE, [16322] = 0x88B6, [16323] = 0x88BC, [16324] = 0x88B7, +- [16325] = 0x88BD, [16326] = 0x88B2, [16327] = 0x8901, [16328] = 0x88C9, +- [16329] = 0x8995, [16330] = 0x8998, [16331] = 0x8997, [16332] = 0x89DD, +- [16333] = 0x89DA, [16334] = 0x89DB, [16335] = 0x8A4E, [16336] = 0x8A4D, +- [16337] = 0x8A39, [16338] = 0x8A59, [16339] = 0x8A40, [16340] = 0x8A57, +- [16341] = 0x8A58, [16342] = 0x8A44, [16343] = 0x8A45, [16344] = 0x8A52, +- [16345] = 0x8A48, [16346] = 0x8A51, [16347] = 0x8A4A, [16348] = 0x8A4C, +- [16349] = 0x8A4F, [16350] = 0x8C5F, [16351] = 0x8C81, [16352] = 0x8C80, +- [16353] = 0x8CBA, [16354] = 0x8CBE, [16355] = 0x8CB0, [16356] = 0x8CB9, +- [16357] = 0x8CB5, [16358] = 0x8D84, [16359] = 0x8D80, [16360] = 0x8D89, +- [16361] = 0x8DD8, [16362] = 0x8DD3, [16363] = 0x8DCD, [16364] = 0x8DC7, +- [16365] = 0x8DD6, [16366] = 0x8DDC, [16367] = 0x8DCF, [16368] = 0x8DD5, +- [16369] = 0x8DD9, [16370] = 0x8DC8, [16371] = 0x8DD7, [16372] = 0x8DC5, +- [16373] = 0x8EEF, [16374] = 0x8EF7, [16375] = 0x8EFA, [16380] = 0x8EF9, +- [16381] = 0x8EE6, [16382] = 0x8EEE, [16383] = 0x8EE5, [16384] = 0x8EF5, +- [16385] = 0x8EE7, [16386] = 0x8EE8, [16387] = 0x8EF6, [16388] = 0x8EEB, +- [16389] = 0x8EF1, [16390] = 0x8EEC, [16391] = 0x8EF4, [16392] = 0x8EE9, +- [16393] = 0x902D, [16394] = 0x9034, [16395] = 0x902F, [16396] = 0x9106, +- [16397] = 0x912C, [16398] = 0x9104, [16399] = 0x90FF, [16400] = 0x90FC, +- [16401] = 0x9108, [16402] = 0x90F9, [16403] = 0x90FB, [16404] = 0x9101, +- [16405] = 0x9100, [16406] = 0x9107, [16407] = 0x9105, [16408] = 0x9103, +- [16409] = 0x9161, [16410] = 0x9164, [16411] = 0x915F, [16412] = 0x9162, +- [16413] = 0x9160, [16414] = 0x9201, [16415] = 0x920A, [16416] = 0x9225, +- [16417] = 0x9203, [16418] = 0x921A, [16419] = 0x9226, [16420] = 0x920F, +- [16421] = 0x920C, [16422] = 0x9200, [16423] = 0x9212, [16424] = 0x91FF, +- [16425] = 0x91FD, [16426] = 0x9206, [16427] = 0x9204, [16428] = 0x9227, +- [16429] = 0x9202, [16430] = 0x921C, [16431] = 0x9224, [16432] = 0x9219, +- [16433] = 0x9217, [16434] = 0x9205, [16435] = 0x9216, [16436] = 0x957B, +- [16437] = 0x958D, [16438] = 0x958C, [16439] = 0x9590, [16440] = 0x9687, +- [16441] = 0x967E, [16442] = 0x9688, [16477] = 0x9689, [16478] = 0x9683, +- [16479] = 0x9680, [16480] = 0x96C2, [16481] = 0x96C8, [16482] = 0x96C3, +- [16483] = 0x96F1, [16484] = 0x96F0, [16485] = 0x976C, [16486] = 0x9770, +- [16487] = 0x976E, [16488] = 0x9807, [16489] = 0x98A9, [16490] = 0x98EB, +- [16491] = 0x9CE6, [16492] = 0x9EF9, [16493] = 0x4E83, [16494] = 0x4E84, +- [16495] = 0x4EB6, [16496] = 0x50BD, [16497] = 0x50BF, [16498] = 0x50C6, +- [16499] = 0x50AE, [16500] = 0x50C4, [16501] = 0x50CA, [16502] = 0x50B4, +- [16503] = 0x50C8, [16504] = 0x50C2, [16505] = 0x50B0, [16506] = 0x50C1, +- [16507] = 0x50BA, [16508] = 0x50B1, [16509] = 0x50CB, [16510] = 0x50C9, +- [16511] = 0x50B6, [16512] = 0x50B8, [16513] = 0x51D7, [16514] = 0x527A, +- [16515] = 0x5278, [16516] = 0x527B, [16517] = 0x527C, [16518] = 0x55C3, +- [16519] = 0x55DB, [16520] = 0x55CC, [16521] = 0x55D0, [16522] = 0x55CB, +- [16523] = 0x55CA, [16524] = 0x55DD, [16525] = 0x55C0, [16526] = 0x55D4, +- [16527] = 0x55C4, [16528] = 0x55E9, [16529] = 0x55BF, [16530] = 0x55D2, +- [16531] = 0x558D, [16532] = 0x55CF, [16533] = 0x55D5, [16534] = 0x55E2, +- [16535] = 0x55D6, [16536] = 0x55C8, [16537] = 0x55F2, [16538] = 0x55CD, +- [16539] = 0x55D9, [16540] = 0x55C2, [16541] = 0x5714, [16542] = 0x5853, +- [16543] = 0x5868, [16544] = 0x5864, [16545] = 0x584F, [16546] = 0x584D, +- [16547] = 0x5849, [16548] = 0x586F, [16549] = 0x5855, [16550] = 0x584E, +- [16551] = 0x585D, [16552] = 0x5859, [16553] = 0x5865, [16554] = 0x585B, +- [16555] = 0x583D, [16556] = 0x5863, [16557] = 0x5871, [16558] = 0x58FC, +- [16559] = 0x5AC7, [16560] = 0x5AC4, [16561] = 0x5ACB, [16562] = 0x5ABA, +- [16563] = 0x5AB8, [16564] = 0x5AB1, [16565] = 0x5AB5, [16566] = 0x5AB0, +- [16567] = 0x5ABF, [16568] = 0x5AC8, [16569] = 0x5ABB, [16570] = 0x5AC6, +- [16575] = 0x5AB7, [16576] = 0x5AC0, [16577] = 0x5ACA, [16578] = 0x5AB4, +- [16579] = 0x5AB6, [16580] = 0x5ACD, [16581] = 0x5AB9, [16582] = 0x5A90, +- [16583] = 0x5BD6, [16584] = 0x5BD8, [16585] = 0x5BD9, [16586] = 0x5C1F, +- [16587] = 0x5C33, [16588] = 0x5D71, [16589] = 0x5D63, [16590] = 0x5D4A, +- [16591] = 0x5D65, [16592] = 0x5D72, [16593] = 0x5D6C, [16594] = 0x5D5E, +- [16595] = 0x5D68, [16596] = 0x5D67, [16597] = 0x5D62, [16598] = 0x5DF0, +- [16599] = 0x5E4F, [16600] = 0x5E4E, [16601] = 0x5E4A, [16602] = 0x5E4D, +- [16603] = 0x5E4B, [16604] = 0x5EC5, [16605] = 0x5ECC, [16606] = 0x5EC6, +- [16607] = 0x5ECB, [16608] = 0x5EC7, [16609] = 0x5F40, [16610] = 0x5FAF, +- [16611] = 0x5FAD, [16612] = 0x60F7, [16613] = 0x6149, [16614] = 0x614A, +- [16615] = 0x612B, [16616] = 0x6145, [16617] = 0x6136, [16618] = 0x6132, +- [16619] = 0x612E, [16620] = 0x6146, [16621] = 0x612F, [16622] = 0x614F, +- [16623] = 0x6129, [16624] = 0x6140, [16625] = 0x6220, [16626] = 0x9168, +- [16627] = 0x6223, [16628] = 0x6225, [16629] = 0x6224, [16630] = 0x63C5, +- [16631] = 0x63F1, [16632] = 0x63EB, [16633] = 0x6410, [16634] = 0x6412, +- [16635] = 0x6409, [16636] = 0x6420, [16637] = 0x6424, [16672] = 0x6433, +- [16673] = 0x6443, [16674] = 0x641F, [16675] = 0x6415, [16676] = 0x6418, +- [16677] = 0x6439, [16678] = 0x6437, [16679] = 0x6422, [16680] = 0x6423, +- [16681] = 0x640C, [16682] = 0x6426, [16683] = 0x6430, [16684] = 0x6428, +- [16685] = 0x6441, [16686] = 0x6435, [16687] = 0x642F, [16688] = 0x640A, +- [16689] = 0x641A, [16690] = 0x6440, [16691] = 0x6425, [16692] = 0x6427, +- [16693] = 0x640B, [16694] = 0x63E7, [16695] = 0x641B, [16696] = 0x642E, +- [16697] = 0x6421, [16698] = 0x640E, [16699] = 0x656F, [16700] = 0x6592, +- [16701] = 0x65D3, [16702] = 0x6686, [16703] = 0x668C, [16704] = 0x6695, +- [16705] = 0x6690, [16706] = 0x668B, [16707] = 0x668A, [16708] = 0x6699, +- [16709] = 0x6694, [16710] = 0x6678, [16711] = 0x6720, [16712] = 0x6966, +- [16713] = 0x695F, [16714] = 0x6938, [16715] = 0x694E, [16716] = 0x6962, +- [16717] = 0x6971, [16718] = 0x693F, [16719] = 0x6945, [16720] = 0x696A, +- [16721] = 0x6939, [16722] = 0x6942, [16723] = 0x6957, [16724] = 0x6959, +- [16725] = 0x697A, [16726] = 0x6948, [16727] = 0x6949, [16728] = 0x6935, +- [16729] = 0x696C, [16730] = 0x6933, [16731] = 0x693D, [16732] = 0x6965, +- [16733] = 0x68F0, [16734] = 0x6978, [16735] = 0x6934, [16736] = 0x6969, +- [16737] = 0x6940, [16738] = 0x696F, [16739] = 0x6944, [16740] = 0x6976, +- [16741] = 0x6958, [16742] = 0x6941, [16743] = 0x6974, [16744] = 0x694C, +- [16745] = 0x693B, [16746] = 0x694B, [16747] = 0x6937, [16748] = 0x695C, +- [16749] = 0x694F, [16750] = 0x6951, [16751] = 0x6932, [16752] = 0x6952, +- [16753] = 0x692F, [16754] = 0x697B, [16755] = 0x693C, [16756] = 0x6B46, +- [16757] = 0x6B45, [16758] = 0x6B43, [16759] = 0x6B42, [16760] = 0x6B48, +- [16761] = 0x6B41, [16762] = 0x6B9B, [16763] = 0xFA0D, [16764] = 0x6BFB, +- [16765] = 0x6BFC, [16770] = 0x6BF9, [16771] = 0x6BF7, [16772] = 0x6BF8, +- [16773] = 0x6E9B, [16774] = 0x6ED6, [16775] = 0x6EC8, [16776] = 0x6E8F, +- [16777] = 0x6EC0, [16778] = 0x6E9F, [16779] = 0x6E93, [16780] = 0x6E94, +- [16781] = 0x6EA0, [16782] = 0x6EB1, [16783] = 0x6EB9, [16784] = 0x6EC6, +- [16785] = 0x6ED2, [16786] = 0x6EBD, [16787] = 0x6EC1, [16788] = 0x6E9E, +- [16789] = 0x6EC9, [16790] = 0x6EB7, [16791] = 0x6EB0, [16792] = 0x6ECD, +- [16793] = 0x6EA6, [16794] = 0x6ECF, [16795] = 0x6EB2, [16796] = 0x6EBE, +- [16797] = 0x6EC3, [16798] = 0x6EDC, [16799] = 0x6ED8, [16800] = 0x6E99, +- [16801] = 0x6E92, [16802] = 0x6E8E, [16803] = 0x6E8D, [16804] = 0x6EA4, +- [16805] = 0x6EA1, [16806] = 0x6EBF, [16807] = 0x6EB3, [16808] = 0x6ED0, +- [16809] = 0x6ECA, [16810] = 0x6E97, [16811] = 0x6EAE, [16812] = 0x6EA3, +- [16813] = 0x7147, [16814] = 0x7154, [16815] = 0x7152, [16816] = 0x7163, +- [16817] = 0x7160, [16818] = 0x7141, [16819] = 0x715D, [16820] = 0x7162, +- [16821] = 0x7172, [16822] = 0x7178, [16823] = 0x716A, [16824] = 0x7161, +- [16825] = 0x7142, [16826] = 0x7158, [16827] = 0x7143, [16828] = 0x714B, +- [16829] = 0x7170, [16830] = 0x715F, [16831] = 0x7150, [16832] = 0x7153, +- [16867] = 0x7144, [16868] = 0x714D, [16869] = 0x715A, [16870] = 0x724F, +- [16871] = 0x728D, [16872] = 0x728C, [16873] = 0x7291, [16874] = 0x7290, +- [16875] = 0x728E, [16876] = 0x733C, [16877] = 0x7342, [16878] = 0x733B, +- [16879] = 0x733A, [16880] = 0x7340, [16881] = 0x734A, [16882] = 0x7349, +- [16883] = 0x7444, [16884] = 0x744A, [16885] = 0x744B, [16886] = 0x7452, +- [16887] = 0x7451, [16888] = 0x7457, [16889] = 0x7440, [16890] = 0x744F, +- [16891] = 0x7450, [16892] = 0x744E, [16893] = 0x7442, [16894] = 0x7446, +- [16895] = 0x744D, [16896] = 0x7454, [16897] = 0x74E1, [16898] = 0x74FF, +- [16899] = 0x74FE, [16900] = 0x74FD, [16901] = 0x751D, [16902] = 0x7579, +- [16903] = 0x7577, [16904] = 0x6983, [16905] = 0x75EF, [16906] = 0x760F, +- [16907] = 0x7603, [16908] = 0x75F7, [16909] = 0x75FE, [16910] = 0x75FC, +- [16911] = 0x75F9, [16912] = 0x75F8, [16913] = 0x7610, [16914] = 0x75FB, +- [16915] = 0x75F6, [16916] = 0x75ED, [16917] = 0x75F5, [16918] = 0x75FD, +- [16919] = 0x7699, [16920] = 0x76B5, [16921] = 0x76DD, [16922] = 0x7755, +- [16923] = 0x775F, [16924] = 0x7760, [16925] = 0x7752, [16926] = 0x7756, +- [16927] = 0x775A, [16928] = 0x7769, [16929] = 0x7767, [16930] = 0x7754, +- [16931] = 0x7759, [16932] = 0x776D, [16933] = 0x77E0, [16934] = 0x7887, +- [16935] = 0x789A, [16936] = 0x7894, [16937] = 0x788F, [16938] = 0x7884, +- [16939] = 0x7895, [16940] = 0x7885, [16941] = 0x7886, [16942] = 0x78A1, +- [16943] = 0x7883, [16944] = 0x7879, [16945] = 0x7899, [16946] = 0x7880, +- [16947] = 0x7896, [16948] = 0x787B, [16949] = 0x797C, [16950] = 0x7982, +- [16951] = 0x797D, [16952] = 0x7979, [16953] = 0x7A11, [16954] = 0x7A18, +- [16955] = 0x7A19, [16956] = 0x7A12, [16957] = 0x7A17, [16958] = 0x7A15, +- [16959] = 0x7A22, [16960] = 0x7A13, [16965] = 0x7A1B, [16966] = 0x7A10, +- [16967] = 0x7AA3, [16968] = 0x7AA2, [16969] = 0x7A9E, [16970] = 0x7AEB, +- [16971] = 0x7B66, [16972] = 0x7B64, [16973] = 0x7B6D, [16974] = 0x7B74, +- [16975] = 0x7B69, [16976] = 0x7B72, [16977] = 0x7B65, [16978] = 0x7B73, +- [16979] = 0x7B71, [16980] = 0x7B70, [16981] = 0x7B61, [16982] = 0x7B78, +- [16983] = 0x7B76, [16984] = 0x7B63, [16985] = 0x7CB2, [16986] = 0x7CB4, +- [16987] = 0x7CAF, [16988] = 0x7D88, [16989] = 0x7D86, [16990] = 0x7D80, +- [16991] = 0x7D8D, [16992] = 0x7D7F, [16993] = 0x7D85, [16994] = 0x7D7A, +- [16995] = 0x7D8E, [16996] = 0x7D7B, [16997] = 0x7D83, [16998] = 0x7D7C, +- [16999] = 0x7D8C, [17000] = 0x7D94, [17001] = 0x7D84, [17002] = 0x7D7D, +- [17003] = 0x7D92, [17004] = 0x7F6D, [17005] = 0x7F6B, [17006] = 0x7F67, +- [17007] = 0x7F68, [17008] = 0x7F6C, [17009] = 0x7FA6, [17010] = 0x7FA5, +- [17011] = 0x7FA7, [17012] = 0x7FDB, [17013] = 0x7FDC, [17014] = 0x8021, +- [17015] = 0x8164, [17016] = 0x8160, [17017] = 0x8177, [17018] = 0x815C, +- [17019] = 0x8169, [17020] = 0x815B, [17021] = 0x8162, [17022] = 0x8172, +- [17023] = 0x6721, [17024] = 0x815E, [17025] = 0x8176, [17026] = 0x8167, +- [17027] = 0x816F, [17062] = 0x8144, [17063] = 0x8161, [17064] = 0x821D, +- [17065] = 0x8249, [17066] = 0x8244, [17067] = 0x8240, [17068] = 0x8242, +- [17069] = 0x8245, [17070] = 0x84F1, [17071] = 0x843F, [17072] = 0x8456, +- [17073] = 0x8476, [17074] = 0x8479, [17075] = 0x848F, [17076] = 0x848D, +- [17077] = 0x8465, [17078] = 0x8451, [17079] = 0x8440, [17080] = 0x8486, +- [17081] = 0x8467, [17082] = 0x8430, [17083] = 0x844D, [17084] = 0x847D, +- [17085] = 0x845A, [17086] = 0x8459, [17087] = 0x8474, [17088] = 0x8473, +- [17089] = 0x845D, [17090] = 0x8507, [17091] = 0x845E, [17092] = 0x8437, +- [17093] = 0x843A, [17094] = 0x8434, [17095] = 0x847A, [17096] = 0x8443, +- [17097] = 0x8478, [17098] = 0x8432, [17099] = 0x8445, [17100] = 0x8429, +- [17101] = 0x83D9, [17102] = 0x844B, [17103] = 0x842F, [17104] = 0x8442, +- [17105] = 0x842D, [17106] = 0x845F, [17107] = 0x8470, [17108] = 0x8439, +- [17109] = 0x844E, [17110] = 0x844C, [17111] = 0x8452, [17112] = 0x846F, +- [17113] = 0x84C5, [17114] = 0x848E, [17115] = 0x843B, [17116] = 0x8447, +- [17117] = 0x8436, [17118] = 0x8433, [17119] = 0x8468, [17120] = 0x847E, +- [17121] = 0x8444, [17122] = 0x842B, [17123] = 0x8460, [17124] = 0x8454, +- [17125] = 0x846E, [17126] = 0x8450, [17127] = 0x870B, [17128] = 0x8704, +- [17129] = 0x86F7, [17130] = 0x870C, [17131] = 0x86FA, [17132] = 0x86D6, +- [17133] = 0x86F5, [17134] = 0x874D, [17135] = 0x86F8, [17136] = 0x870E, +- [17137] = 0x8709, [17138] = 0x8701, [17139] = 0x86F6, [17140] = 0x870D, +- [17141] = 0x8705, [17142] = 0x88D6, [17143] = 0x88CB, [17144] = 0x88CD, +- [17145] = 0x88CE, [17146] = 0x88DE, [17147] = 0x88DB, [17148] = 0x88DA, +- [17149] = 0x88CC, [17150] = 0x88D0, [17151] = 0x8985, [17152] = 0x899B, +- [17153] = 0x89DF, [17154] = 0x89E5, [17155] = 0x89E4, [17160] = 0x89E1, +- [17161] = 0x89E0, [17162] = 0x89E2, [17163] = 0x89DC, [17164] = 0x89E6, +- [17165] = 0x8A76, [17166] = 0x8A86, [17167] = 0x8A7F, [17168] = 0x8A61, +- [17169] = 0x8A3F, [17170] = 0x8A77, [17171] = 0x8A82, [17172] = 0x8A84, +- [17173] = 0x8A75, [17174] = 0x8A83, [17175] = 0x8A81, [17176] = 0x8A74, +- [17177] = 0x8A7A, [17178] = 0x8C3C, [17179] = 0x8C4B, [17180] = 0x8C4A, +- [17181] = 0x8C65, [17182] = 0x8C64, [17183] = 0x8C66, [17184] = 0x8C86, +- [17185] = 0x8C84, [17186] = 0x8C85, [17187] = 0x8CCC, [17188] = 0x8D68, +- [17189] = 0x8D69, [17190] = 0x8D91, [17191] = 0x8D8C, [17192] = 0x8D8E, +- [17193] = 0x8D8F, [17194] = 0x8D8D, [17195] = 0x8D93, [17196] = 0x8D94, +- [17197] = 0x8D90, [17198] = 0x8D92, [17199] = 0x8DF0, [17200] = 0x8DE0, +- [17201] = 0x8DEC, [17202] = 0x8DF1, [17203] = 0x8DEE, [17204] = 0x8DD0, +- [17205] = 0x8DE9, [17206] = 0x8DE3, [17207] = 0x8DE2, [17208] = 0x8DE7, +- [17209] = 0x8DF2, [17210] = 0x8DEB, [17211] = 0x8DF4, [17212] = 0x8F06, +- [17213] = 0x8EFF, [17214] = 0x8F01, [17215] = 0x8F00, [17216] = 0x8F05, +- [17217] = 0x8F07, [17218] = 0x8F08, [17219] = 0x8F02, [17220] = 0x8F0B, +- [17221] = 0x9052, [17222] = 0x903F, [17257] = 0x9044, [17258] = 0x9049, +- [17259] = 0x903D, [17260] = 0x9110, [17261] = 0x910D, [17262] = 0x910F, +- [17263] = 0x9111, [17264] = 0x9116, [17265] = 0x9114, [17266] = 0x910B, +- [17267] = 0x910E, [17268] = 0x916E, [17269] = 0x916F, [17270] = 0x9248, +- [17271] = 0x9252, [17272] = 0x9230, [17273] = 0x923A, [17274] = 0x9266, +- [17275] = 0x9233, [17276] = 0x9265, [17277] = 0x925E, [17278] = 0x9283, +- [17279] = 0x922E, [17280] = 0x924A, [17281] = 0x9246, [17282] = 0x926D, +- [17283] = 0x926C, [17284] = 0x924F, [17285] = 0x9260, [17286] = 0x9267, +- [17287] = 0x926F, [17288] = 0x9236, [17289] = 0x9261, [17290] = 0x9270, +- [17291] = 0x9231, [17292] = 0x9254, [17293] = 0x9263, [17294] = 0x9250, +- [17295] = 0x9272, [17296] = 0x924E, [17297] = 0x9253, [17298] = 0x924C, +- [17299] = 0x9256, [17300] = 0x9232, [17301] = 0x959F, [17302] = 0x959C, +- [17303] = 0x959E, [17304] = 0x959B, [17305] = 0x9692, [17306] = 0x9693, +- [17307] = 0x9691, [17308] = 0x9697, [17309] = 0x96CE, [17310] = 0x96FA, +- [17311] = 0x96FD, [17312] = 0x96F8, [17313] = 0x96F5, [17314] = 0x9773, +- [17315] = 0x9777, [17316] = 0x9778, [17317] = 0x9772, [17318] = 0x980F, +- [17319] = 0x980D, [17320] = 0x980E, [17321] = 0x98AC, [17322] = 0x98F6, +- [17323] = 0x98F9, [17324] = 0x99AF, [17325] = 0x99B2, [17326] = 0x99B0, +- [17327] = 0x99B5, [17328] = 0x9AAD, [17329] = 0x9AAB, [17330] = 0x9B5B, +- [17331] = 0x9CEA, [17332] = 0x9CED, [17333] = 0x9CE7, [17334] = 0x9E80, +- [17335] = 0x9EFD, [17336] = 0x50E6, [17337] = 0x50D4, [17338] = 0x50D7, +- [17339] = 0x50E8, [17340] = 0x50F3, [17341] = 0x50DB, [17342] = 0x50EA, +- [17343] = 0x50DD, [17344] = 0x50E4, [17345] = 0x50D3, [17346] = 0x50EC, +- [17347] = 0x50F0, [17348] = 0x50EF, [17349] = 0x50E3, [17350] = 0x50E0, +- [17355] = 0x51D8, [17356] = 0x5280, [17357] = 0x5281, [17358] = 0x52E9, +- [17359] = 0x52EB, [17360] = 0x5330, [17361] = 0x53AC, [17362] = 0x5627, +- [17363] = 0x5615, [17364] = 0x560C, [17365] = 0x5612, [17366] = 0x55FC, +- [17367] = 0x560F, [17368] = 0x561C, [17369] = 0x5601, [17370] = 0x5613, +- [17371] = 0x5602, [17372] = 0x55FA, [17373] = 0x561D, [17374] = 0x5604, +- [17375] = 0x55FF, [17376] = 0x55F9, [17377] = 0x5889, [17378] = 0x587C, +- [17379] = 0x5890, [17380] = 0x5898, [17381] = 0x5886, [17382] = 0x5881, +- [17383] = 0x587F, [17384] = 0x5874, [17385] = 0x588B, [17386] = 0x587A, +- [17387] = 0x5887, [17388] = 0x5891, [17389] = 0x588E, [17390] = 0x5876, +- [17391] = 0x5882, [17392] = 0x5888, [17393] = 0x587B, [17394] = 0x5894, +- [17395] = 0x588F, [17396] = 0x58FE, [17397] = 0x596B, [17398] = 0x5ADC, +- [17399] = 0x5AEE, [17400] = 0x5AE5, [17401] = 0x5AD5, [17402] = 0x5AEA, +- [17403] = 0x5ADA, [17404] = 0x5AED, [17405] = 0x5AEB, [17406] = 0x5AF3, +- [17407] = 0x5AE2, [17408] = 0x5AE0, [17409] = 0x5ADB, [17410] = 0x5AEC, +- [17411] = 0x5ADE, [17412] = 0x5ADD, [17413] = 0x5AD9, [17414] = 0x5AE8, +- [17415] = 0x5ADF, [17416] = 0x5B77, [17417] = 0x5BE0, [17452] = 0x5BE3, +- [17453] = 0x5C63, [17454] = 0x5D82, [17455] = 0x5D80, [17456] = 0x5D7D, +- [17457] = 0x5D86, [17458] = 0x5D7A, [17459] = 0x5D81, [17460] = 0x5D77, +- [17461] = 0x5D8A, [17462] = 0x5D89, [17463] = 0x5D88, [17464] = 0x5D7E, +- [17465] = 0x5D7C, [17466] = 0x5D8D, [17467] = 0x5D79, [17468] = 0x5D7F, +- [17469] = 0x5E58, [17470] = 0x5E59, [17471] = 0x5E53, [17472] = 0x5ED8, +- [17473] = 0x5ED1, [17474] = 0x5ED7, [17475] = 0x5ECE, [17476] = 0x5EDC, +- [17477] = 0x5ED5, [17478] = 0x5ED9, [17479] = 0x5ED2, [17480] = 0x5ED4, +- [17481] = 0x5F44, [17482] = 0x5F43, [17483] = 0x5F6F, [17484] = 0x5FB6, +- [17485] = 0x612C, [17486] = 0x6128, [17487] = 0x6141, [17488] = 0x615E, +- [17489] = 0x6171, [17490] = 0x6173, [17491] = 0x6152, [17492] = 0x6153, +- [17493] = 0x6172, [17494] = 0x616C, [17495] = 0x6180, [17496] = 0x6174, +- [17497] = 0x6154, [17498] = 0x617A, [17499] = 0x615B, [17500] = 0x6165, +- [17501] = 0x613B, [17502] = 0x616A, [17503] = 0x6161, [17504] = 0x6156, +- [17505] = 0x6229, [17506] = 0x6227, [17507] = 0x622B, [17508] = 0x642B, +- [17509] = 0x644D, [17510] = 0x645B, [17511] = 0x645D, [17512] = 0x6474, +- [17513] = 0x6476, [17514] = 0x6472, [17515] = 0x6473, [17516] = 0x647D, +- [17517] = 0x6475, [17518] = 0x6466, [17519] = 0x64A6, [17520] = 0x644E, +- [17521] = 0x6482, [17522] = 0x645E, [17523] = 0x645C, [17524] = 0x644B, +- [17525] = 0x6453, [17526] = 0x6460, [17527] = 0x6450, [17528] = 0x647F, +- [17529] = 0x643F, [17530] = 0x646C, [17531] = 0x646B, [17532] = 0x6459, +- [17533] = 0x6465, [17534] = 0x6477, [17535] = 0x6573, [17536] = 0x65A0, +- [17537] = 0x66A1, [17538] = 0x66A0, [17539] = 0x669F, [17540] = 0x6705, +- [17541] = 0x6704, [17542] = 0x6722, [17543] = 0x69B1, [17544] = 0x69B6, +- [17545] = 0x69C9, [17550] = 0x69A0, [17551] = 0x69CE, [17552] = 0x6996, +- [17553] = 0x69B0, [17554] = 0x69AC, [17555] = 0x69BC, [17556] = 0x6991, +- [17557] = 0x6999, [17558] = 0x698E, [17559] = 0x69A7, [17560] = 0x698D, +- [17561] = 0x69A9, [17562] = 0x69BE, [17563] = 0x69AF, [17564] = 0x69BF, +- [17565] = 0x69C4, [17566] = 0x69BD, [17567] = 0x69A4, [17568] = 0x69D4, +- [17569] = 0x69B9, [17570] = 0x69CA, [17571] = 0x699A, [17572] = 0x69CF, +- [17573] = 0x69B3, [17574] = 0x6993, [17575] = 0x69AA, [17576] = 0x69A1, +- [17577] = 0x699E, [17578] = 0x69D9, [17579] = 0x6997, [17580] = 0x6990, +- [17581] = 0x69C2, [17582] = 0x69B5, [17583] = 0x69A5, [17584] = 0x69C6, +- [17585] = 0x6B4A, [17586] = 0x6B4D, [17587] = 0x6B4B, [17588] = 0x6B9E, +- [17589] = 0x6B9F, [17590] = 0x6BA0, [17591] = 0x6BC3, [17592] = 0x6BC4, +- [17593] = 0x6BFE, [17594] = 0x6ECE, [17595] = 0x6EF5, [17596] = 0x6EF1, +- [17597] = 0x6F03, [17598] = 0x6F25, [17599] = 0x6EF8, [17600] = 0x6F37, +- [17601] = 0x6EFB, [17602] = 0x6F2E, [17603] = 0x6F09, [17604] = 0x6F4E, +- [17605] = 0x6F19, [17606] = 0x6F1A, [17607] = 0x6F27, [17608] = 0x6F18, +- [17609] = 0x6F3B, [17610] = 0x6F12, [17611] = 0x6EED, [17612] = 0x6F0A, +- [17647] = 0x6F36, [17648] = 0x6F73, [17649] = 0x6EF9, [17650] = 0x6EEE, +- [17651] = 0x6F2D, [17652] = 0x6F40, [17653] = 0x6F30, [17654] = 0x6F3C, +- [17655] = 0x6F35, [17656] = 0x6EEB, [17657] = 0x6F07, [17658] = 0x6F0E, +- [17659] = 0x6F43, [17660] = 0x6F05, [17661] = 0x6EFD, [17662] = 0x6EF6, +- [17663] = 0x6F39, [17664] = 0x6F1C, [17665] = 0x6EFC, [17666] = 0x6F3A, +- [17667] = 0x6F1F, [17668] = 0x6F0D, [17669] = 0x6F1E, [17670] = 0x6F08, +- [17671] = 0x6F21, [17672] = 0x7187, [17673] = 0x7190, [17674] = 0x7189, +- [17675] = 0x7180, [17676] = 0x7185, [17677] = 0x7182, [17678] = 0x718F, +- [17679] = 0x717B, [17680] = 0x7186, [17681] = 0x7181, [17682] = 0x7197, +- [17683] = 0x7244, [17684] = 0x7253, [17685] = 0x7297, [17686] = 0x7295, +- [17687] = 0x7293, [17688] = 0x7343, [17689] = 0x734D, [17690] = 0x7351, +- [17691] = 0x734C, [17692] = 0x7462, [17693] = 0x7473, [17694] = 0x7471, +- [17695] = 0x7475, [17696] = 0x7472, [17697] = 0x7467, [17698] = 0x746E, +- [17699] = 0x7500, [17700] = 0x7502, [17701] = 0x7503, [17702] = 0x757D, +- [17703] = 0x7590, [17704] = 0x7616, [17705] = 0x7608, [17706] = 0x760C, +- [17707] = 0x7615, [17708] = 0x7611, [17709] = 0x760A, [17710] = 0x7614, +- [17711] = 0x76B8, [17712] = 0x7781, [17713] = 0x777C, [17714] = 0x7785, +- [17715] = 0x7782, [17716] = 0x776E, [17717] = 0x7780, [17718] = 0x776F, +- [17719] = 0x777E, [17720] = 0x7783, [17721] = 0x78B2, [17722] = 0x78AA, +- [17723] = 0x78B4, [17724] = 0x78AD, [17725] = 0x78A8, [17726] = 0x787E, +- [17727] = 0x78AB, [17728] = 0x789E, [17729] = 0x78A5, [17730] = 0x78A0, +- [17731] = 0x78AC, [17732] = 0x78A2, [17733] = 0x78A4, [17734] = 0x7998, +- [17735] = 0x798A, [17736] = 0x798B, [17737] = 0x7996, [17738] = 0x7995, +- [17739] = 0x7994, [17740] = 0x7993, [17745] = 0x7997, [17746] = 0x7988, +- [17747] = 0x7992, [17748] = 0x7990, [17749] = 0x7A2B, [17750] = 0x7A4A, +- [17751] = 0x7A30, [17752] = 0x7A2F, [17753] = 0x7A28, [17754] = 0x7A26, +- [17755] = 0x7AA8, [17756] = 0x7AAB, [17757] = 0x7AAC, [17758] = 0x7AEE, +- [17759] = 0x7B88, [17760] = 0x7B9C, [17761] = 0x7B8A, [17762] = 0x7B91, +- [17763] = 0x7B90, [17764] = 0x7B96, [17765] = 0x7B8D, [17766] = 0x7B8C, +- [17767] = 0x7B9B, [17768] = 0x7B8E, [17769] = 0x7B85, [17770] = 0x7B98, +- [17771] = 0x5284, [17772] = 0x7B99, [17773] = 0x7BA4, [17774] = 0x7B82, +- [17775] = 0x7CBB, [17776] = 0x7CBF, [17777] = 0x7CBC, [17778] = 0x7CBA, +- [17779] = 0x7DA7, [17780] = 0x7DB7, [17781] = 0x7DC2, [17782] = 0x7DA3, +- [17783] = 0x7DAA, [17784] = 0x7DC1, [17785] = 0x7DC0, [17786] = 0x7DC5, +- [17787] = 0x7D9D, [17788] = 0x7DCE, [17789] = 0x7DC4, [17790] = 0x7DC6, +- [17791] = 0x7DCB, [17792] = 0x7DCC, [17793] = 0x7DAF, [17794] = 0x7DB9, +- [17795] = 0x7D96, [17796] = 0x7DBC, [17797] = 0x7D9F, [17798] = 0x7DA6, +- [17799] = 0x7DAE, [17800] = 0x7DA9, [17801] = 0x7DA1, [17802] = 0x7DC9, +- [17803] = 0x7F73, [17804] = 0x7FE2, [17805] = 0x7FE3, [17806] = 0x7FE5, +- [17807] = 0x7FDE, [17842] = 0x8024, [17843] = 0x805D, [17844] = 0x805C, +- [17845] = 0x8189, [17846] = 0x8186, [17847] = 0x8183, [17848] = 0x8187, +- [17849] = 0x818D, [17850] = 0x818C, [17851] = 0x818B, [17852] = 0x8215, +- [17853] = 0x8497, [17854] = 0x84A4, [17855] = 0x84A1, [17856] = 0x849F, +- [17857] = 0x84BA, [17858] = 0x84CE, [17859] = 0x84C2, [17860] = 0x84AC, +- [17861] = 0x84AE, [17862] = 0x84AB, [17863] = 0x84B9, [17864] = 0x84B4, +- [17865] = 0x84C1, [17866] = 0x84CD, [17867] = 0x84AA, [17868] = 0x849A, +- [17869] = 0x84B1, [17870] = 0x84D0, [17871] = 0x849D, [17872] = 0x84A7, +- [17873] = 0x84BB, [17874] = 0x84A2, [17875] = 0x8494, [17876] = 0x84C7, +- [17877] = 0x84CC, [17878] = 0x849B, [17879] = 0x84A9, [17880] = 0x84AF, +- [17881] = 0x84A8, [17882] = 0x84D6, [17883] = 0x8498, [17884] = 0x84B6, +- [17885] = 0x84CF, [17886] = 0x84A0, [17887] = 0x84D7, [17888] = 0x84D4, +- [17889] = 0x84D2, [17890] = 0x84DB, [17891] = 0x84B0, [17892] = 0x8491, +- [17893] = 0x8661, [17894] = 0x8733, [17895] = 0x8723, [17896] = 0x8728, +- [17897] = 0x876B, [17898] = 0x8740, [17899] = 0x872E, [17900] = 0x871E, +- [17901] = 0x8721, [17902] = 0x8719, [17903] = 0x871B, [17904] = 0x8743, +- [17905] = 0x872C, [17906] = 0x8741, [17907] = 0x873E, [17908] = 0x8746, +- [17909] = 0x8720, [17910] = 0x8732, [17911] = 0x872A, [17912] = 0x872D, +- [17913] = 0x873C, [17914] = 0x8712, [17915] = 0x873A, [17916] = 0x8731, +- [17917] = 0x8735, [17918] = 0x8742, [17919] = 0x8726, [17920] = 0x8727, +- [17921] = 0x8738, [17922] = 0x8724, [17923] = 0x871A, [17924] = 0x8730, +- [17925] = 0x8711, [17926] = 0x88F7, [17927] = 0x88E7, [17928] = 0x88F1, +- [17929] = 0x88F2, [17930] = 0x88FA, [17931] = 0x88FE, [17932] = 0x88EE, +- [17933] = 0x88FC, [17934] = 0x88F6, [17935] = 0x88FB, [17940] = 0x88F0, +- [17941] = 0x88EC, [17942] = 0x88EB, [17943] = 0x899D, [17944] = 0x89A1, +- [17945] = 0x899F, [17946] = 0x899E, [17947] = 0x89E9, [17948] = 0x89EB, +- [17949] = 0x89E8, [17950] = 0x8AAB, [17951] = 0x8A99, [17952] = 0x8A8B, +- [17953] = 0x8A92, [17954] = 0x8A8F, [17955] = 0x8A96, [17956] = 0x8C3D, +- [17957] = 0x8C68, [17958] = 0x8C69, [17959] = 0x8CD5, [17960] = 0x8CCF, +- [17961] = 0x8CD7, [17962] = 0x8D96, [17963] = 0x8E09, [17964] = 0x8E02, +- [17965] = 0x8DFF, [17966] = 0x8E0D, [17967] = 0x8DFD, [17968] = 0x8E0A, +- [17969] = 0x8E03, [17970] = 0x8E07, [17971] = 0x8E06, [17972] = 0x8E05, +- [17973] = 0x8DFE, [17974] = 0x8E00, [17975] = 0x8E04, [17976] = 0x8F10, +- [17977] = 0x8F11, [17978] = 0x8F0E, [17979] = 0x8F0D, [17980] = 0x9123, +- [17981] = 0x911C, [17982] = 0x9120, [17983] = 0x9122, [17984] = 0x911F, +- [17985] = 0x911D, [17986] = 0x911A, [17987] = 0x9124, [17988] = 0x9121, +- [17989] = 0x911B, [17990] = 0x917A, [17991] = 0x9172, [17992] = 0x9179, +- [17993] = 0x9173, [17994] = 0x92A5, [17995] = 0x92A4, [17996] = 0x9276, +- [17997] = 0x929B, [17998] = 0x927A, [17999] = 0x92A0, [18000] = 0x9294, +- [18001] = 0x92AA, [18002] = 0x928D, [18037] = 0x92A6, [18038] = 0x929A, +- [18039] = 0x92AB, [18040] = 0x9279, [18041] = 0x9297, [18042] = 0x927F, +- [18043] = 0x92A3, [18044] = 0x92EE, [18045] = 0x928E, [18046] = 0x9282, +- [18047] = 0x9295, [18048] = 0x92A2, [18049] = 0x927D, [18050] = 0x9288, +- [18051] = 0x92A1, [18052] = 0x928A, [18053] = 0x9286, [18054] = 0x928C, +- [18055] = 0x9299, [18056] = 0x92A7, [18057] = 0x927E, [18058] = 0x9287, +- [18059] = 0x92A9, [18060] = 0x929D, [18061] = 0x928B, [18062] = 0x922D, +- [18063] = 0x969E, [18064] = 0x96A1, [18065] = 0x96FF, [18066] = 0x9758, +- [18067] = 0x977D, [18068] = 0x977A, [18069] = 0x977E, [18070] = 0x9783, +- [18071] = 0x9780, [18072] = 0x9782, [18073] = 0x977B, [18074] = 0x9784, +- [18075] = 0x9781, [18076] = 0x977F, [18077] = 0x97CE, [18078] = 0x97CD, +- [18079] = 0x9816, [18080] = 0x98AD, [18081] = 0x98AE, [18082] = 0x9902, +- [18083] = 0x9900, [18084] = 0x9907, [18085] = 0x999D, [18086] = 0x999C, +- [18087] = 0x99C3, [18088] = 0x99B9, [18089] = 0x99BB, [18090] = 0x99BA, +- [18091] = 0x99C2, [18092] = 0x99BD, [18093] = 0x99C7, [18094] = 0x9AB1, +- [18095] = 0x9AE3, [18096] = 0x9AE7, [18097] = 0x9B3E, [18098] = 0x9B3F, +- [18099] = 0x9B60, [18100] = 0x9B61, [18101] = 0x9B5F, [18102] = 0x9CF1, +- [18103] = 0x9CF2, [18104] = 0x9CF5, [18105] = 0x9EA7, [18106] = 0x50FF, +- [18107] = 0x5103, [18108] = 0x5130, [18109] = 0x50F8, [18110] = 0x5106, +- [18111] = 0x5107, [18112] = 0x50F6, [18113] = 0x50FE, [18114] = 0x510B, +- [18115] = 0x510C, [18116] = 0x50FD, [18117] = 0x510A, [18118] = 0x528B, +- [18119] = 0x528C, [18120] = 0x52F1, [18121] = 0x52EF, [18122] = 0x5648, +- [18123] = 0x5642, [18124] = 0x564C, [18125] = 0x5635, [18126] = 0x5641, +- [18127] = 0x564A, [18128] = 0x5649, [18129] = 0x5646, [18130] = 0x5658, +- [18135] = 0x565A, [18136] = 0x5640, [18137] = 0x5633, [18138] = 0x563D, +- [18139] = 0x562C, [18140] = 0x563E, [18141] = 0x5638, [18142] = 0x562A, +- [18143] = 0x563A, [18144] = 0x571A, [18145] = 0x58AB, [18146] = 0x589D, +- [18147] = 0x58B1, [18148] = 0x58A0, [18149] = 0x58A3, [18150] = 0x58AF, +- [18151] = 0x58AC, [18152] = 0x58A5, [18153] = 0x58A1, [18154] = 0x58FF, +- [18155] = 0x5AFF, [18156] = 0x5AF4, [18157] = 0x5AFD, [18158] = 0x5AF7, +- [18159] = 0x5AF6, [18160] = 0x5B03, [18161] = 0x5AF8, [18162] = 0x5B02, +- [18163] = 0x5AF9, [18164] = 0x5B01, [18165] = 0x5B07, [18166] = 0x5B05, +- [18167] = 0x5B0F, [18168] = 0x5C67, [18169] = 0x5D99, [18170] = 0x5D97, +- [18171] = 0x5D9F, [18172] = 0x5D92, [18173] = 0x5DA2, [18174] = 0x5D93, +- [18175] = 0x5D95, [18176] = 0x5DA0, [18177] = 0x5D9C, [18178] = 0x5DA1, +- [18179] = 0x5D9A, [18180] = 0x5D9E, [18181] = 0x5E69, [18182] = 0x5E5D, +- [18183] = 0x5E60, [18184] = 0x5E5C, [18185] = 0x7DF3, [18186] = 0x5EDB, +- [18187] = 0x5EDE, [18188] = 0x5EE1, [18189] = 0x5F49, [18190] = 0x5FB2, +- [18191] = 0x618B, [18192] = 0x6183, [18193] = 0x6179, [18194] = 0x61B1, +- [18195] = 0x61B0, [18196] = 0x61A2, [18197] = 0x6189, [18232] = 0x619B, +- [18233] = 0x6193, [18234] = 0x61AF, [18235] = 0x61AD, [18236] = 0x619F, +- [18237] = 0x6192, [18238] = 0x61AA, [18239] = 0x61A1, [18240] = 0x618D, +- [18241] = 0x6166, [18242] = 0x61B3, [18243] = 0x622D, [18244] = 0x646E, +- [18245] = 0x6470, [18246] = 0x6496, [18247] = 0x64A0, [18248] = 0x6485, +- [18249] = 0x6497, [18250] = 0x649C, [18251] = 0x648F, [18252] = 0x648B, +- [18253] = 0x648A, [18254] = 0x648C, [18255] = 0x64A3, [18256] = 0x649F, +- [18257] = 0x6468, [18258] = 0x64B1, [18259] = 0x6498, [18260] = 0x6576, +- [18261] = 0x657A, [18262] = 0x6579, [18263] = 0x657B, [18264] = 0x65B2, +- [18265] = 0x65B3, [18266] = 0x66B5, [18267] = 0x66B0, [18268] = 0x66A9, +- [18269] = 0x66B2, [18270] = 0x66B7, [18271] = 0x66AA, [18272] = 0x66AF, +- [18273] = 0x6A00, [18274] = 0x6A06, [18275] = 0x6A17, [18276] = 0x69E5, +- [18277] = 0x69F8, [18278] = 0x6A15, [18279] = 0x69F1, [18280] = 0x69E4, +- [18281] = 0x6A20, [18282] = 0x69FF, [18283] = 0x69EC, [18284] = 0x69E2, +- [18285] = 0x6A1B, [18286] = 0x6A1D, [18287] = 0x69FE, [18288] = 0x6A27, +- [18289] = 0x69F2, [18290] = 0x69EE, [18291] = 0x6A14, [18292] = 0x69F7, +- [18293] = 0x69E7, [18294] = 0x6A40, [18295] = 0x6A08, [18296] = 0x69E6, +- [18297] = 0x69FB, [18298] = 0x6A0D, [18299] = 0x69FC, [18300] = 0x69EB, +- [18301] = 0x6A09, [18302] = 0x6A04, [18303] = 0x6A18, [18304] = 0x6A25, +- [18305] = 0x6A0F, [18306] = 0x69F6, [18307] = 0x6A26, [18308] = 0x6A07, +- [18309] = 0x69F4, [18310] = 0x6A16, [18311] = 0x6B51, [18312] = 0x6BA5, +- [18313] = 0x6BA3, [18314] = 0x6BA2, [18315] = 0x6BA6, [18316] = 0x6C01, +- [18317] = 0x6C00, [18318] = 0x6BFF, [18319] = 0x6C02, [18320] = 0x6F41, +- [18321] = 0x6F26, [18322] = 0x6F7E, [18323] = 0x6F87, [18324] = 0x6FC6, +- [18325] = 0x6F92, [18330] = 0x6F8D, [18331] = 0x6F89, [18332] = 0x6F8C, +- [18333] = 0x6F62, [18334] = 0x6F4F, [18335] = 0x6F85, [18336] = 0x6F5A, +- [18337] = 0x6F96, [18338] = 0x6F76, [18339] = 0x6F6C, [18340] = 0x6F82, +- [18341] = 0x6F55, [18342] = 0x6F72, [18343] = 0x6F52, [18344] = 0x6F50, +- [18345] = 0x6F57, [18346] = 0x6F94, [18347] = 0x6F93, [18348] = 0x6F5D, +- [18349] = 0x6F00, [18350] = 0x6F61, [18351] = 0x6F6B, [18352] = 0x6F7D, +- [18353] = 0x6F67, [18354] = 0x6F90, [18355] = 0x6F53, [18356] = 0x6F8B, +- [18357] = 0x6F69, [18358] = 0x6F7F, [18359] = 0x6F95, [18360] = 0x6F63, +- [18361] = 0x6F77, [18362] = 0x6F6A, [18363] = 0x6F7B, [18364] = 0x71B2, +- [18365] = 0x71AF, [18366] = 0x719B, [18367] = 0x71B0, [18368] = 0x71A0, +- [18369] = 0x719A, [18370] = 0x71A9, [18371] = 0x71B5, [18372] = 0x719D, +- [18373] = 0x71A5, [18374] = 0x719E, [18375] = 0x71A4, [18376] = 0x71A1, +- [18377] = 0x71AA, [18378] = 0x719C, [18379] = 0x71A7, [18380] = 0x71B3, +- [18381] = 0x7298, [18382] = 0x729A, [18383] = 0x7358, [18384] = 0x7352, +- [18385] = 0x735E, [18386] = 0x735F, [18387] = 0x7360, [18388] = 0x735D, +- [18389] = 0x735B, [18390] = 0x7361, [18391] = 0x735A, [18392] = 0x7359, +- [18427] = 0x7362, [18428] = 0x7487, [18429] = 0x7489, [18430] = 0x748A, +- [18431] = 0x7486, [18432] = 0x7481, [18433] = 0x747D, [18434] = 0x7485, +- [18435] = 0x7488, [18436] = 0x747C, [18437] = 0x7479, [18438] = 0x7508, +- [18439] = 0x7507, [18440] = 0x757E, [18441] = 0x7625, [18442] = 0x761E, +- [18443] = 0x7619, [18444] = 0x761D, [18445] = 0x761C, [18446] = 0x7623, +- [18447] = 0x761A, [18448] = 0x7628, [18449] = 0x761B, [18450] = 0x769C, +- [18451] = 0x769D, [18452] = 0x769E, [18453] = 0x769B, [18454] = 0x778D, +- [18455] = 0x778F, [18456] = 0x7789, [18457] = 0x7788, [18458] = 0x78CD, +- [18459] = 0x78BB, [18460] = 0x78CF, [18461] = 0x78CC, [18462] = 0x78D1, +- [18463] = 0x78CE, [18464] = 0x78D4, [18465] = 0x78C8, [18466] = 0x78C3, +- [18467] = 0x78C4, [18468] = 0x78C9, [18469] = 0x799A, [18470] = 0x79A1, +- [18471] = 0x79A0, [18472] = 0x799C, [18473] = 0x79A2, [18474] = 0x799B, +- [18475] = 0x6B76, [18476] = 0x7A39, [18477] = 0x7AB2, [18478] = 0x7AB4, +- [18479] = 0x7AB3, [18480] = 0x7BB7, [18481] = 0x7BCB, [18482] = 0x7BBE, +- [18483] = 0x7BAC, [18484] = 0x7BCE, [18485] = 0x7BAF, [18486] = 0x7BB9, +- [18487] = 0x7BCA, [18488] = 0x7BB5, [18489] = 0x7CC5, [18490] = 0x7CC8, +- [18491] = 0x7CCC, [18492] = 0x7CCB, [18493] = 0x7DF7, [18494] = 0x7DDB, +- [18495] = 0x7DEA, [18496] = 0x7DE7, [18497] = 0x7DD7, [18498] = 0x7DE1, +- [18499] = 0x7E03, [18500] = 0x7DFA, [18501] = 0x7DE6, [18502] = 0x7DF6, +- [18503] = 0x7DF1, [18504] = 0x7DF0, [18505] = 0x7DEE, [18506] = 0x7DDF, +- [18507] = 0x7F76, [18508] = 0x7FAC, [18509] = 0x7FB0, [18510] = 0x7FAD, +- [18511] = 0x7FED, [18512] = 0x7FEB, [18513] = 0x7FEA, [18514] = 0x7FEC, +- [18515] = 0x7FE6, [18516] = 0x7FE8, [18517] = 0x8064, [18518] = 0x8067, +- [18519] = 0x81A3, [18520] = 0x819F, [18525] = 0x819E, [18526] = 0x8195, +- [18527] = 0x81A2, [18528] = 0x8199, [18529] = 0x8197, [18530] = 0x8216, +- [18531] = 0x824F, [18532] = 0x8253, [18533] = 0x8252, [18534] = 0x8250, +- [18535] = 0x824E, [18536] = 0x8251, [18537] = 0x8524, [18538] = 0x853B, +- [18539] = 0x850F, [18540] = 0x8500, [18541] = 0x8529, [18542] = 0x850E, +- [18543] = 0x8509, [18544] = 0x850D, [18545] = 0x851F, [18546] = 0x850A, +- [18547] = 0x8527, [18548] = 0x851C, [18549] = 0x84FB, [18550] = 0x852B, +- [18551] = 0x84FA, [18552] = 0x8508, [18553] = 0x850C, [18554] = 0x84F4, +- [18555] = 0x852A, [18556] = 0x84F2, [18557] = 0x8515, [18558] = 0x84F7, +- [18559] = 0x84EB, [18560] = 0x84F3, [18561] = 0x84FC, [18562] = 0x8512, +- [18563] = 0x84EA, [18564] = 0x84E9, [18565] = 0x8516, [18566] = 0x84FE, +- [18567] = 0x8528, [18568] = 0x851D, [18569] = 0x852E, [18570] = 0x8502, +- [18571] = 0x84FD, [18572] = 0x851E, [18573] = 0x84F6, [18574] = 0x8531, +- [18575] = 0x8526, [18576] = 0x84E7, [18577] = 0x84E8, [18578] = 0x84F0, +- [18579] = 0x84EF, [18580] = 0x84F9, [18581] = 0x8518, [18582] = 0x8520, +- [18583] = 0x8530, [18584] = 0x850B, [18585] = 0x8519, [18586] = 0x852F, +- [18587] = 0x8662, [18622] = 0x8756, [18623] = 0x8763, [18624] = 0x8764, +- [18625] = 0x8777, [18626] = 0x87E1, [18627] = 0x8773, [18628] = 0x8758, +- [18629] = 0x8754, [18630] = 0x875B, [18631] = 0x8752, [18632] = 0x8761, +- [18633] = 0x875A, [18634] = 0x8751, [18635] = 0x875E, [18636] = 0x876D, +- [18637] = 0x876A, [18638] = 0x8750, [18639] = 0x874E, [18640] = 0x875F, +- [18641] = 0x875D, [18642] = 0x876F, [18643] = 0x876C, [18644] = 0x877A, +- [18645] = 0x876E, [18646] = 0x875C, [18647] = 0x8765, [18648] = 0x874F, +- [18649] = 0x877B, [18650] = 0x8775, [18651] = 0x8762, [18652] = 0x8767, +- [18653] = 0x8769, [18654] = 0x885A, [18655] = 0x8905, [18656] = 0x890C, +- [18657] = 0x8914, [18658] = 0x890B, [18659] = 0x8917, [18660] = 0x8918, +- [18661] = 0x8919, [18662] = 0x8906, [18663] = 0x8916, [18664] = 0x8911, +- [18665] = 0x890E, [18666] = 0x8909, [18667] = 0x89A2, [18668] = 0x89A4, +- [18669] = 0x89A3, [18670] = 0x89ED, [18671] = 0x89F0, [18672] = 0x89EC, +- [18673] = 0x8ACF, [18674] = 0x8AC6, [18675] = 0x8AB8, [18676] = 0x8AD3, +- [18677] = 0x8AD1, [18678] = 0x8AD4, [18679] = 0x8AD5, [18680] = 0x8ABB, +- [18681] = 0x8AD7, [18682] = 0x8ABE, [18683] = 0x8AC0, [18684] = 0x8AC5, +- [18685] = 0x8AD8, [18686] = 0x8AC3, [18687] = 0x8ABA, [18688] = 0x8ABD, +- [18689] = 0x8AD9, [18690] = 0x8C3E, [18691] = 0x8C4D, [18692] = 0x8C8F, +- [18693] = 0x8CE5, [18694] = 0x8CDF, [18695] = 0x8CD9, [18696] = 0x8CE8, +- [18697] = 0x8CDA, [18698] = 0x8CDD, [18699] = 0x8CE7, [18700] = 0x8DA0, +- [18701] = 0x8D9C, [18702] = 0x8DA1, [18703] = 0x8D9B, [18704] = 0x8E20, +- [18705] = 0x8E23, [18706] = 0x8E25, [18707] = 0x8E24, [18708] = 0x8E2E, +- [18709] = 0x8E15, [18710] = 0x8E1B, [18711] = 0x8E16, [18712] = 0x8E11, +- [18713] = 0x8E19, [18714] = 0x8E26, [18715] = 0x8E27, [18720] = 0x8E14, +- [18721] = 0x8E12, [18722] = 0x8E18, [18723] = 0x8E13, [18724] = 0x8E1C, +- [18725] = 0x8E17, [18726] = 0x8E1A, [18727] = 0x8F2C, [18728] = 0x8F24, +- [18729] = 0x8F18, [18730] = 0x8F1A, [18731] = 0x8F20, [18732] = 0x8F23, +- [18733] = 0x8F16, [18734] = 0x8F17, [18735] = 0x9073, [18736] = 0x9070, +- [18737] = 0x906F, [18738] = 0x9067, [18739] = 0x906B, [18740] = 0x912F, +- [18741] = 0x912B, [18742] = 0x9129, [18743] = 0x912A, [18744] = 0x9132, +- [18745] = 0x9126, [18746] = 0x912E, [18747] = 0x9185, [18748] = 0x9186, +- [18749] = 0x918A, [18750] = 0x9181, [18751] = 0x9182, [18752] = 0x9184, +- [18753] = 0x9180, [18754] = 0x92D0, [18755] = 0x92C3, [18756] = 0x92C4, +- [18757] = 0x92C0, [18758] = 0x92D9, [18759] = 0x92B6, [18760] = 0x92CF, +- [18761] = 0x92F1, [18762] = 0x92DF, [18763] = 0x92D8, [18764] = 0x92E9, +- [18765] = 0x92D7, [18766] = 0x92DD, [18767] = 0x92CC, [18768] = 0x92EF, +- [18769] = 0x92C2, [18770] = 0x92E8, [18771] = 0x92CA, [18772] = 0x92C8, +- [18773] = 0x92CE, [18774] = 0x92E6, [18775] = 0x92CD, [18776] = 0x92D5, +- [18777] = 0x92C9, [18778] = 0x92E0, [18779] = 0x92DE, [18780] = 0x92E7, +- [18781] = 0x92D1, [18782] = 0x92D3, [18817] = 0x92B5, [18818] = 0x92E1, +- [18819] = 0x92C6, [18820] = 0x92B4, [18821] = 0x957C, [18822] = 0x95AC, +- [18823] = 0x95AB, [18824] = 0x95AE, [18825] = 0x95B0, [18826] = 0x96A4, +- [18827] = 0x96A2, [18828] = 0x96D3, [18829] = 0x9705, [18830] = 0x9708, +- [18831] = 0x9702, [18832] = 0x975A, [18833] = 0x978A, [18834] = 0x978E, +- [18835] = 0x9788, [18836] = 0x97D0, [18837] = 0x97CF, [18838] = 0x981E, +- [18839] = 0x981D, [18840] = 0x9826, [18841] = 0x9829, [18842] = 0x9828, +- [18843] = 0x9820, [18844] = 0x981B, [18845] = 0x9827, [18846] = 0x98B2, +- [18847] = 0x9908, [18848] = 0x98FA, [18849] = 0x9911, [18850] = 0x9914, +- [18851] = 0x9916, [18852] = 0x9917, [18853] = 0x9915, [18854] = 0x99DC, +- [18855] = 0x99CD, [18856] = 0x99CF, [18857] = 0x99D3, [18858] = 0x99D4, +- [18859] = 0x99CE, [18860] = 0x99C9, [18861] = 0x99D6, [18862] = 0x99D8, +- [18863] = 0x99CB, [18864] = 0x99D7, [18865] = 0x99CC, [18866] = 0x9AB3, +- [18867] = 0x9AEC, [18868] = 0x9AEB, [18869] = 0x9AF3, [18870] = 0x9AF2, +- [18871] = 0x9AF1, [18872] = 0x9B46, [18873] = 0x9B43, [18874] = 0x9B67, +- [18875] = 0x9B74, [18876] = 0x9B71, [18877] = 0x9B66, [18878] = 0x9B76, +- [18879] = 0x9B75, [18880] = 0x9B70, [18881] = 0x9B68, [18882] = 0x9B64, +- [18883] = 0x9B6C, [18884] = 0x9CFC, [18885] = 0x9CFA, [18886] = 0x9CFD, +- [18887] = 0x9CFF, [18888] = 0x9CF7, [18889] = 0x9D07, [18890] = 0x9D00, +- [18891] = 0x9CF9, [18892] = 0x9CFB, [18893] = 0x9D08, [18894] = 0x9D05, +- [18895] = 0x9D04, [18896] = 0x9E83, [18897] = 0x9ED3, [18898] = 0x9F0F, +- [18899] = 0x9F10, [18900] = 0x511C, [18901] = 0x5113, [18902] = 0x5117, +- [18903] = 0x511A, [18904] = 0x5111, [18905] = 0x51DE, [18906] = 0x5334, +- [18907] = 0x53E1, [18908] = 0x5670, [18909] = 0x5660, [18910] = 0x566E, +- [18915] = 0x5673, [18916] = 0x5666, [18917] = 0x5663, [18918] = 0x566D, +- [18919] = 0x5672, [18920] = 0x565E, [18921] = 0x5677, [18922] = 0x571C, +- [18923] = 0x571B, [18924] = 0x58C8, [18925] = 0x58BD, [18926] = 0x58C9, +- [18927] = 0x58BF, [18928] = 0x58BA, [18929] = 0x58C2, [18930] = 0x58BC, +- [18931] = 0x58C6, [18932] = 0x5B17, [18933] = 0x5B19, [18934] = 0x5B1B, +- [18935] = 0x5B21, [18936] = 0x5B14, [18937] = 0x5B13, [18938] = 0x5B10, +- [18939] = 0x5B16, [18940] = 0x5B28, [18941] = 0x5B1A, [18942] = 0x5B20, +- [18943] = 0x5B1E, [18944] = 0x5BEF, [18945] = 0x5DAC, [18946] = 0x5DB1, +- [18947] = 0x5DA9, [18948] = 0x5DA7, [18949] = 0x5DB5, [18950] = 0x5DB0, +- [18951] = 0x5DAE, [18952] = 0x5DAA, [18953] = 0x5DA8, [18954] = 0x5DB2, +- [18955] = 0x5DAD, [18956] = 0x5DAF, [18957] = 0x5DB4, [18958] = 0x5E67, +- [18959] = 0x5E68, [18960] = 0x5E66, [18961] = 0x5E6F, [18962] = 0x5EE9, +- [18963] = 0x5EE7, [18964] = 0x5EE6, [18965] = 0x5EE8, [18966] = 0x5EE5, +- [18967] = 0x5F4B, [18968] = 0x5FBC, [18969] = 0x619D, [18970] = 0x61A8, +- [18971] = 0x6196, [18972] = 0x61C5, [18973] = 0x61B4, [18974] = 0x61C6, +- [18975] = 0x61C1, [18976] = 0x61CC, [18977] = 0x61BA, [19012] = 0x61BF, +- [19013] = 0x61B8, [19014] = 0x618C, [19015] = 0x64D7, [19016] = 0x64D6, +- [19017] = 0x64D0, [19018] = 0x64CF, [19019] = 0x64C9, [19020] = 0x64BD, +- [19021] = 0x6489, [19022] = 0x64C3, [19023] = 0x64DB, [19024] = 0x64F3, +- [19025] = 0x64D9, [19026] = 0x6533, [19027] = 0x657F, [19028] = 0x657C, +- [19029] = 0x65A2, [19030] = 0x66C8, [19031] = 0x66BE, [19032] = 0x66C0, +- [19033] = 0x66CA, [19034] = 0x66CB, [19035] = 0x66CF, [19036] = 0x66BD, +- [19037] = 0x66BB, [19038] = 0x66BA, [19039] = 0x66CC, [19040] = 0x6723, +- [19041] = 0x6A34, [19042] = 0x6A66, [19043] = 0x6A49, [19044] = 0x6A67, +- [19045] = 0x6A32, [19046] = 0x6A68, [19047] = 0x6A3E, [19048] = 0x6A5D, +- [19049] = 0x6A6D, [19050] = 0x6A76, [19051] = 0x6A5B, [19052] = 0x6A51, +- [19053] = 0x6A28, [19054] = 0x6A5A, [19055] = 0x6A3B, [19056] = 0x6A3F, +- [19057] = 0x6A41, [19058] = 0x6A6A, [19059] = 0x6A64, [19060] = 0x6A50, +- [19061] = 0x6A4F, [19062] = 0x6A54, [19063] = 0x6A6F, [19064] = 0x6A69, +- [19065] = 0x6A60, [19066] = 0x6A3C, [19067] = 0x6A5E, [19068] = 0x6A56, +- [19069] = 0x6A55, [19070] = 0x6A4D, [19071] = 0x6A4E, [19072] = 0x6A46, +- [19073] = 0x6B55, [19074] = 0x6B54, [19075] = 0x6B56, [19076] = 0x6BA7, +- [19077] = 0x6BAA, [19078] = 0x6BAB, [19079] = 0x6BC8, [19080] = 0x6BC7, +- [19081] = 0x6C04, [19082] = 0x6C03, [19083] = 0x6C06, [19084] = 0x6FAD, +- [19085] = 0x6FCB, [19086] = 0x6FA3, [19087] = 0x6FC7, [19088] = 0x6FBC, +- [19089] = 0x6FCE, [19090] = 0x6FC8, [19091] = 0x6F5E, [19092] = 0x6FC4, +- [19093] = 0x6FBD, [19094] = 0x6F9E, [19095] = 0x6FCA, [19096] = 0x6FA8, +- [19097] = 0x7004, [19098] = 0x6FA5, [19099] = 0x6FAE, [19100] = 0x6FBA, +- [19101] = 0x6FAC, [19102] = 0x6FAA, [19103] = 0x6FCF, [19104] = 0x6FBF, +- [19105] = 0x6FB8, [19110] = 0x6FA2, [19111] = 0x6FC9, [19112] = 0x6FAB, +- [19113] = 0x6FCD, [19114] = 0x6FAF, [19115] = 0x6FB2, [19116] = 0x6FB0, +- [19117] = 0x71C5, [19118] = 0x71C2, [19119] = 0x71BF, [19120] = 0x71B8, +- [19121] = 0x71D6, [19122] = 0x71C0, [19123] = 0x71C1, [19124] = 0x71CB, +- [19125] = 0x71D4, [19126] = 0x71CA, [19127] = 0x71C7, [19128] = 0x71CF, +- [19129] = 0x71BD, [19130] = 0x71D8, [19131] = 0x71BC, [19132] = 0x71C6, +- [19133] = 0x71DA, [19134] = 0x71DB, [19135] = 0x729D, [19136] = 0x729E, +- [19137] = 0x7369, [19138] = 0x7366, [19139] = 0x7367, [19140] = 0x736C, +- [19141] = 0x7365, [19142] = 0x736B, [19143] = 0x736A, [19144] = 0x747F, +- [19145] = 0x749A, [19146] = 0x74A0, [19147] = 0x7494, [19148] = 0x7492, +- [19149] = 0x7495, [19150] = 0x74A1, [19151] = 0x750B, [19152] = 0x7580, +- [19153] = 0x762F, [19154] = 0x762D, [19155] = 0x7631, [19156] = 0x763D, +- [19157] = 0x7633, [19158] = 0x763C, [19159] = 0x7635, [19160] = 0x7632, +- [19161] = 0x7630, [19162] = 0x76BB, [19163] = 0x76E6, [19164] = 0x779A, +- [19165] = 0x779D, [19166] = 0x77A1, [19167] = 0x779C, [19168] = 0x779B, +- [19169] = 0x77A2, [19170] = 0x77A3, [19171] = 0x7795, [19172] = 0x7799, +- [19207] = 0x7797, [19208] = 0x78DD, [19209] = 0x78E9, [19210] = 0x78E5, +- [19211] = 0x78EA, [19212] = 0x78DE, [19213] = 0x78E3, [19214] = 0x78DB, +- [19215] = 0x78E1, [19216] = 0x78E2, [19217] = 0x78ED, [19218] = 0x78DF, +- [19219] = 0x78E0, [19220] = 0x79A4, [19221] = 0x7A44, [19222] = 0x7A48, +- [19223] = 0x7A47, [19224] = 0x7AB6, [19225] = 0x7AB8, [19226] = 0x7AB5, +- [19227] = 0x7AB1, [19228] = 0x7AB7, [19229] = 0x7BDE, [19230] = 0x7BE3, +- [19231] = 0x7BE7, [19232] = 0x7BDD, [19233] = 0x7BD5, [19234] = 0x7BE5, +- [19235] = 0x7BDA, [19236] = 0x7BE8, [19237] = 0x7BF9, [19238] = 0x7BD4, +- [19239] = 0x7BEA, [19240] = 0x7BE2, [19241] = 0x7BDC, [19242] = 0x7BEB, +- [19243] = 0x7BD8, [19244] = 0x7BDF, [19245] = 0x7CD2, [19246] = 0x7CD4, +- [19247] = 0x7CD7, [19248] = 0x7CD0, [19249] = 0x7CD1, [19250] = 0x7E12, +- [19251] = 0x7E21, [19252] = 0x7E17, [19253] = 0x7E0C, [19254] = 0x7E1F, +- [19255] = 0x7E20, [19256] = 0x7E13, [19257] = 0x7E0E, [19258] = 0x7E1C, +- [19259] = 0x7E15, [19260] = 0x7E1A, [19261] = 0x7E22, [19262] = 0x7E0B, +- [19263] = 0x7E0F, [19264] = 0x7E16, [19265] = 0x7E0D, [19266] = 0x7E14, +- [19267] = 0x7E25, [19268] = 0x7E24, [19269] = 0x7F43, [19270] = 0x7F7B, +- [19271] = 0x7F7C, [19272] = 0x7F7A, [19273] = 0x7FB1, [19274] = 0x7FEF, +- [19275] = 0x802A, [19276] = 0x8029, [19277] = 0x806C, [19278] = 0x81B1, +- [19279] = 0x81A6, [19280] = 0x81AE, [19281] = 0x81B9, [19282] = 0x81B5, +- [19283] = 0x81AB, [19284] = 0x81B0, [19285] = 0x81AC, [19286] = 0x81B4, +- [19287] = 0x81B2, [19288] = 0x81B7, [19289] = 0x81A7, [19290] = 0x81F2, +- [19291] = 0x8255, [19292] = 0x8256, [19293] = 0x8257, [19294] = 0x8556, +- [19295] = 0x8545, [19296] = 0x856B, [19297] = 0x854D, [19298] = 0x8553, +- [19299] = 0x8561, [19300] = 0x8558, [19305] = 0x8540, [19306] = 0x8546, +- [19307] = 0x8564, [19308] = 0x8541, [19309] = 0x8562, [19310] = 0x8544, +- [19311] = 0x8551, [19312] = 0x8547, [19313] = 0x8563, [19314] = 0x853E, +- [19315] = 0x855B, [19316] = 0x8571, [19317] = 0x854E, [19318] = 0x856E, +- [19319] = 0x8575, [19320] = 0x8555, [19321] = 0x8567, [19322] = 0x8560, +- [19323] = 0x858C, [19324] = 0x8566, [19325] = 0x855D, [19326] = 0x8554, +- [19327] = 0x8565, [19328] = 0x856C, [19329] = 0x8663, [19330] = 0x8665, +- [19331] = 0x8664, [19332] = 0x879B, [19333] = 0x878F, [19334] = 0x8797, +- [19335] = 0x8793, [19336] = 0x8792, [19337] = 0x8788, [19338] = 0x8781, +- [19339] = 0x8796, [19340] = 0x8798, [19341] = 0x8779, [19342] = 0x8787, +- [19343] = 0x87A3, [19344] = 0x8785, [19345] = 0x8790, [19346] = 0x8791, +- [19347] = 0x879D, [19348] = 0x8784, [19349] = 0x8794, [19350] = 0x879C, +- [19351] = 0x879A, [19352] = 0x8789, [19353] = 0x891E, [19354] = 0x8926, +- [19355] = 0x8930, [19356] = 0x892D, [19357] = 0x892E, [19358] = 0x8927, +- [19359] = 0x8931, [19360] = 0x8922, [19361] = 0x8929, [19362] = 0x8923, +- [19363] = 0x892F, [19364] = 0x892C, [19365] = 0x891F, [19366] = 0x89F1, +- [19367] = 0x8AE0, [19402] = 0x8AE2, [19403] = 0x8AF2, [19404] = 0x8AF4, +- [19405] = 0x8AF5, [19406] = 0x8ADD, [19407] = 0x8B14, [19408] = 0x8AE4, +- [19409] = 0x8ADF, [19410] = 0x8AF0, [19411] = 0x8AC8, [19412] = 0x8ADE, +- [19413] = 0x8AE1, [19414] = 0x8AE8, [19415] = 0x8AFF, [19416] = 0x8AEF, +- [19417] = 0x8AFB, [19418] = 0x8C91, [19419] = 0x8C92, [19420] = 0x8C90, +- [19421] = 0x8CF5, [19422] = 0x8CEE, [19423] = 0x8CF1, [19424] = 0x8CF0, +- [19425] = 0x8CF3, [19426] = 0x8D6C, [19427] = 0x8D6E, [19428] = 0x8DA5, +- [19429] = 0x8DA7, [19430] = 0x8E33, [19431] = 0x8E3E, [19432] = 0x8E38, +- [19433] = 0x8E40, [19434] = 0x8E45, [19435] = 0x8E36, [19436] = 0x8E3C, +- [19437] = 0x8E3D, [19438] = 0x8E41, [19439] = 0x8E30, [19440] = 0x8E3F, +- [19441] = 0x8EBD, [19442] = 0x8F36, [19443] = 0x8F2E, [19444] = 0x8F35, +- [19445] = 0x8F32, [19446] = 0x8F39, [19447] = 0x8F37, [19448] = 0x8F34, +- [19449] = 0x9076, [19450] = 0x9079, [19451] = 0x907B, [19452] = 0x9086, +- [19453] = 0x90FA, [19454] = 0x9133, [19455] = 0x9135, [19456] = 0x9136, +- [19457] = 0x9193, [19458] = 0x9190, [19459] = 0x9191, [19460] = 0x918D, +- [19461] = 0x918F, [19462] = 0x9327, [19463] = 0x931E, [19464] = 0x9308, +- [19465] = 0x931F, [19466] = 0x9306, [19467] = 0x930F, [19468] = 0x937A, +- [19469] = 0x9338, [19470] = 0x933C, [19471] = 0x931B, [19472] = 0x9323, +- [19473] = 0x9312, [19474] = 0x9301, [19475] = 0x9346, [19476] = 0x932D, +- [19477] = 0x930E, [19478] = 0x930D, [19479] = 0x92CB, [19480] = 0x931D, +- [19481] = 0x92FA, [19482] = 0x9325, [19483] = 0x9313, [19484] = 0x92F9, +- [19485] = 0x92F7, [19486] = 0x9334, [19487] = 0x9302, [19488] = 0x9324, +- [19489] = 0x92FF, [19490] = 0x9329, [19491] = 0x9339, [19492] = 0x9335, +- [19493] = 0x932A, [19494] = 0x9314, [19495] = 0x930C, [19500] = 0x930B, +- [19501] = 0x92FE, [19502] = 0x9309, [19503] = 0x9300, [19504] = 0x92FB, +- [19505] = 0x9316, [19506] = 0x95BC, [19507] = 0x95CD, [19508] = 0x95BE, +- [19509] = 0x95B9, [19510] = 0x95BA, [19511] = 0x95B6, [19512] = 0x95BF, +- [19513] = 0x95B5, [19514] = 0x95BD, [19515] = 0x96A9, [19516] = 0x96D4, +- [19517] = 0x970B, [19518] = 0x9712, [19519] = 0x9710, [19520] = 0x9799, +- [19521] = 0x9797, [19522] = 0x9794, [19523] = 0x97F0, [19524] = 0x97F8, +- [19525] = 0x9835, [19526] = 0x982F, [19527] = 0x9832, [19528] = 0x9924, +- [19529] = 0x991F, [19530] = 0x9927, [19531] = 0x9929, [19532] = 0x999E, +- [19533] = 0x99EE, [19534] = 0x99EC, [19535] = 0x99E5, [19536] = 0x99E4, +- [19537] = 0x99F0, [19538] = 0x99E3, [19539] = 0x99EA, [19540] = 0x99E9, +- [19541] = 0x99E7, [19542] = 0x9AB9, [19543] = 0x9ABF, [19544] = 0x9AB4, +- [19545] = 0x9ABB, [19546] = 0x9AF6, [19547] = 0x9AFA, [19548] = 0x9AF9, +- [19549] = 0x9AF7, [19550] = 0x9B33, [19551] = 0x9B80, [19552] = 0x9B85, +- [19553] = 0x9B87, [19554] = 0x9B7C, [19555] = 0x9B7E, [19556] = 0x9B7B, +- [19557] = 0x9B82, [19558] = 0x9B93, [19559] = 0x9B92, [19560] = 0x9B90, +- [19561] = 0x9B7A, [19562] = 0x9B95, [19597] = 0x9B7D, [19598] = 0x9B88, +- [19599] = 0x9D25, [19600] = 0x9D17, [19601] = 0x9D20, [19602] = 0x9D1E, +- [19603] = 0x9D14, [19604] = 0x9D29, [19605] = 0x9D1D, [19606] = 0x9D18, +- [19607] = 0x9D22, [19608] = 0x9D10, [19609] = 0x9D19, [19610] = 0x9D1F, +- [19611] = 0x9E88, [19612] = 0x9E86, [19613] = 0x9E87, [19614] = 0x9EAE, +- [19615] = 0x9EAD, [19616] = 0x9ED5, [19617] = 0x9ED6, [19618] = 0x9EFA, +- [19619] = 0x9F12, [19620] = 0x9F3D, [19621] = 0x5126, [19622] = 0x5125, +- [19623] = 0x5122, [19624] = 0x5124, [19625] = 0x5120, [19626] = 0x5129, +- [19627] = 0x52F4, [19628] = 0x5693, [19629] = 0x568C, [19630] = 0x568D, +- [19631] = 0x5686, [19632] = 0x5684, [19633] = 0x5683, [19634] = 0x567E, +- [19635] = 0x5682, [19636] = 0x567F, [19637] = 0x5681, [19638] = 0x58D6, +- [19639] = 0x58D4, [19640] = 0x58CF, [19641] = 0x58D2, [19642] = 0x5B2D, +- [19643] = 0x5B25, [19644] = 0x5B32, [19645] = 0x5B23, [19646] = 0x5B2C, +- [19647] = 0x5B27, [19648] = 0x5B26, [19649] = 0x5B2F, [19650] = 0x5B2E, +- [19651] = 0x5B7B, [19652] = 0x5BF1, [19653] = 0x5BF2, [19654] = 0x5DB7, +- [19655] = 0x5E6C, [19656] = 0x5E6A, [19657] = 0x5FBE, [19658] = 0x5FBB, +- [19659] = 0x61C3, [19660] = 0x61B5, [19661] = 0x61BC, [19662] = 0x61E7, +- [19663] = 0x61E0, [19664] = 0x61E5, [19665] = 0x61E4, [19666] = 0x61E8, +- [19667] = 0x61DE, [19668] = 0x64EF, [19669] = 0x64E9, [19670] = 0x64E3, +- [19671] = 0x64EB, [19672] = 0x64E4, [19673] = 0x64E8, [19674] = 0x6581, +- [19675] = 0x6580, [19676] = 0x65B6, [19677] = 0x65DA, [19678] = 0x66D2, +- [19679] = 0x6A8D, [19680] = 0x6A96, [19681] = 0x6A81, [19682] = 0x6AA5, +- [19683] = 0x6A89, [19684] = 0x6A9F, [19685] = 0x6A9B, [19686] = 0x6AA1, +- [19687] = 0x6A9E, [19688] = 0x6A87, [19689] = 0x6A93, [19690] = 0x6A8E, +- [19695] = 0x6A95, [19696] = 0x6A83, [19697] = 0x6AA8, [19698] = 0x6AA4, +- [19699] = 0x6A91, [19700] = 0x6A7F, [19701] = 0x6AA6, [19702] = 0x6A9A, +- [19703] = 0x6A85, [19704] = 0x6A8C, [19705] = 0x6A92, [19706] = 0x6B5B, +- [19707] = 0x6BAD, [19708] = 0x6C09, [19709] = 0x6FCC, [19710] = 0x6FA9, +- [19711] = 0x6FF4, [19712] = 0x6FD4, [19713] = 0x6FE3, [19714] = 0x6FDC, +- [19715] = 0x6FED, [19716] = 0x6FE7, [19717] = 0x6FE6, [19718] = 0x6FDE, +- [19719] = 0x6FF2, [19720] = 0x6FDD, [19721] = 0x6FE2, [19722] = 0x6FE8, +- [19723] = 0x71E1, [19724] = 0x71F1, [19725] = 0x71E8, [19726] = 0x71F2, +- [19727] = 0x71E4, [19728] = 0x71F0, [19729] = 0x71E2, [19730] = 0x7373, +- [19731] = 0x736E, [19732] = 0x736F, [19733] = 0x7497, [19734] = 0x74B2, +- [19735] = 0x74AB, [19736] = 0x7490, [19737] = 0x74AA, [19738] = 0x74AD, +- [19739] = 0x74B1, [19740] = 0x74A5, [19741] = 0x74AF, [19742] = 0x7510, +- [19743] = 0x7511, [19744] = 0x7512, [19745] = 0x750F, [19746] = 0x7584, +- [19747] = 0x7643, [19748] = 0x7648, [19749] = 0x7649, [19750] = 0x7647, +- [19751] = 0x76A4, [19752] = 0x76E9, [19753] = 0x77B5, [19754] = 0x77AB, +- [19755] = 0x77B2, [19756] = 0x77B7, [19757] = 0x77B6, [19792] = 0x77B4, +- [19793] = 0x77B1, [19794] = 0x77A8, [19795] = 0x77F0, [19796] = 0x78F3, +- [19797] = 0x78FD, [19798] = 0x7902, [19799] = 0x78FB, [19800] = 0x78FC, +- [19801] = 0x78F2, [19802] = 0x7905, [19803] = 0x78F9, [19804] = 0x78FE, +- [19805] = 0x7904, [19806] = 0x79AB, [19807] = 0x79A8, [19808] = 0x7A5C, +- [19809] = 0x7A5B, [19810] = 0x7A56, [19811] = 0x7A58, [19812] = 0x7A54, +- [19813] = 0x7A5A, [19814] = 0x7ABE, [19815] = 0x7AC0, [19816] = 0x7AC1, +- [19817] = 0x7C05, [19818] = 0x7C0F, [19819] = 0x7BF2, [19820] = 0x7C00, +- [19821] = 0x7BFF, [19822] = 0x7BFB, [19823] = 0x7C0E, [19824] = 0x7BF4, +- [19825] = 0x7C0B, [19826] = 0x7BF3, [19827] = 0x7C02, [19828] = 0x7C09, +- [19829] = 0x7C03, [19830] = 0x7C01, [19831] = 0x7BF8, [19832] = 0x7BFD, +- [19833] = 0x7C06, [19834] = 0x7BF0, [19835] = 0x7BF1, [19836] = 0x7C10, +- [19837] = 0x7C0A, [19838] = 0x7CE8, [19839] = 0x7E2D, [19840] = 0x7E3C, +- [19841] = 0x7E42, [19842] = 0x7E33, [19843] = 0x9848, [19844] = 0x7E38, +- [19845] = 0x7E2A, [19846] = 0x7E49, [19847] = 0x7E40, [19848] = 0x7E47, +- [19849] = 0x7E29, [19850] = 0x7E4C, [19851] = 0x7E30, [19852] = 0x7E3B, +- [19853] = 0x7E36, [19854] = 0x7E44, [19855] = 0x7E3A, [19856] = 0x7F45, +- [19857] = 0x7F7F, [19858] = 0x7F7E, [19859] = 0x7F7D, [19860] = 0x7FF4, +- [19861] = 0x7FF2, [19862] = 0x802C, [19863] = 0x81BB, [19864] = 0x81C4, +- [19865] = 0x81CC, [19866] = 0x81CA, [19867] = 0x81C5, [19868] = 0x81C7, +- [19869] = 0x81BC, [19870] = 0x81E9, [19871] = 0x825B, [19872] = 0x825A, +- [19873] = 0x825C, [19874] = 0x8583, [19875] = 0x8580, [19876] = 0x858F, +- [19877] = 0x85A7, [19878] = 0x8595, [19879] = 0x85A0, [19880] = 0x858B, +- [19881] = 0x85A3, [19882] = 0x857B, [19883] = 0x85A4, [19884] = 0x859A, +- [19885] = 0x859E, [19890] = 0x8577, [19891] = 0x857C, [19892] = 0x8589, +- [19893] = 0x85A1, [19894] = 0x857A, [19895] = 0x8578, [19896] = 0x8557, +- [19897] = 0x858E, [19898] = 0x8596, [19899] = 0x8586, [19900] = 0x858D, +- [19901] = 0x8599, [19902] = 0x859D, [19903] = 0x8581, [19904] = 0x85A2, +- [19905] = 0x8582, [19906] = 0x8588, [19907] = 0x8585, [19908] = 0x8579, +- [19909] = 0x8576, [19910] = 0x8598, [19911] = 0x8590, [19912] = 0x859F, +- [19913] = 0x8668, [19914] = 0x87BE, [19915] = 0x87AA, [19916] = 0x87AD, +- [19917] = 0x87C5, [19918] = 0x87B0, [19919] = 0x87AC, [19920] = 0x87B9, +- [19921] = 0x87B5, [19922] = 0x87BC, [19923] = 0x87AE, [19924] = 0x87C9, +- [19925] = 0x87C3, [19926] = 0x87C2, [19927] = 0x87CC, [19928] = 0x87B7, +- [19929] = 0x87AF, [19930] = 0x87C4, [19931] = 0x87CA, [19932] = 0x87B4, +- [19933] = 0x87B6, [19934] = 0x87BF, [19935] = 0x87B8, [19936] = 0x87BD, +- [19937] = 0x87DE, [19938] = 0x87B2, [19939] = 0x8935, [19940] = 0x8933, +- [19941] = 0x893C, [19942] = 0x893E, [19943] = 0x8941, [19944] = 0x8952, +- [19945] = 0x8937, [19946] = 0x8942, [19947] = 0x89AD, [19948] = 0x89AF, +- [19949] = 0x89AE, [19950] = 0x89F2, [19951] = 0x89F3, [19952] = 0x8B1E, +- [19987] = 0x8B18, [19988] = 0x8B16, [19989] = 0x8B11, [19990] = 0x8B05, +- [19991] = 0x8B0B, [19992] = 0x8B22, [19993] = 0x8B0F, [19994] = 0x8B12, +- [19995] = 0x8B15, [19996] = 0x8B07, [19997] = 0x8B0D, [19998] = 0x8B08, +- [19999] = 0x8B06, [20000] = 0x8B1C, [20001] = 0x8B13, [20002] = 0x8B1A, +- [20003] = 0x8C4F, [20004] = 0x8C70, [20005] = 0x8C72, [20006] = 0x8C71, +- [20007] = 0x8C6F, [20008] = 0x8C95, [20009] = 0x8C94, [20010] = 0x8CF9, +- [20011] = 0x8D6F, [20012] = 0x8E4E, [20013] = 0x8E4D, [20014] = 0x8E53, +- [20015] = 0x8E50, [20016] = 0x8E4C, [20017] = 0x8E47, [20018] = 0x8F43, +- [20019] = 0x8F40, [20020] = 0x9085, [20021] = 0x907E, [20022] = 0x9138, +- [20023] = 0x919A, [20024] = 0x91A2, [20025] = 0x919B, [20026] = 0x9199, +- [20027] = 0x919F, [20028] = 0x91A1, [20029] = 0x919D, [20030] = 0x91A0, +- [20031] = 0x93A1, [20032] = 0x9383, [20033] = 0x93AF, [20034] = 0x9364, +- [20035] = 0x9356, [20036] = 0x9347, [20037] = 0x937C, [20038] = 0x9358, +- [20039] = 0x935C, [20040] = 0x9376, [20041] = 0x9349, [20042] = 0x9350, +- [20043] = 0x9351, [20044] = 0x9360, [20045] = 0x936D, [20046] = 0x938F, +- [20047] = 0x934C, [20048] = 0x936A, [20049] = 0x9379, [20050] = 0x9357, +- [20051] = 0x9355, [20052] = 0x9352, [20053] = 0x934F, [20054] = 0x9371, +- [20055] = 0x9377, [20056] = 0x937B, [20057] = 0x9361, [20058] = 0x935E, +- [20059] = 0x9363, [20060] = 0x9367, [20061] = 0x9380, [20062] = 0x934E, +- [20063] = 0x9359, [20064] = 0x95C7, [20065] = 0x95C0, [20066] = 0x95C9, +- [20067] = 0x95C3, [20068] = 0x95C5, [20069] = 0x95B7, [20070] = 0x96AE, +- [20071] = 0x96B0, [20072] = 0x96AC, [20073] = 0x9720, [20074] = 0x971F, +- [20075] = 0x9718, [20076] = 0x971D, [20077] = 0x9719, [20078] = 0x979A, +- [20079] = 0x97A1, [20080] = 0x979C, [20085] = 0x979E, [20086] = 0x979D, +- [20087] = 0x97D5, [20088] = 0x97D4, [20089] = 0x97F1, [20090] = 0x9841, +- [20091] = 0x9844, [20092] = 0x984A, [20093] = 0x9849, [20094] = 0x9845, +- [20095] = 0x9843, [20096] = 0x9925, [20097] = 0x992B, [20098] = 0x992C, +- [20099] = 0x992A, [20100] = 0x9933, [20101] = 0x9932, [20102] = 0x992F, +- [20103] = 0x992D, [20104] = 0x9931, [20105] = 0x9930, [20106] = 0x9998, +- [20107] = 0x99A3, [20108] = 0x99A1, [20109] = 0x9A02, [20110] = 0x99FA, +- [20111] = 0x99F4, [20112] = 0x99F7, [20113] = 0x99F9, [20114] = 0x99F8, +- [20115] = 0x99F6, [20116] = 0x99FB, [20117] = 0x99FD, [20118] = 0x99FE, +- [20119] = 0x99FC, [20120] = 0x9A03, [20121] = 0x9ABE, [20122] = 0x9AFE, +- [20123] = 0x9AFD, [20124] = 0x9B01, [20125] = 0x9AFC, [20126] = 0x9B48, +- [20127] = 0x9B9A, [20128] = 0x9BA8, [20129] = 0x9B9E, [20130] = 0x9B9B, +- [20131] = 0x9BA6, [20132] = 0x9BA1, [20133] = 0x9BA5, [20134] = 0x9BA4, +- [20135] = 0x9B86, [20136] = 0x9BA2, [20137] = 0x9BA0, [20138] = 0x9BAF, +- [20139] = 0x9D33, [20140] = 0x9D41, [20141] = 0x9D67, [20142] = 0x9D36, +- [20143] = 0x9D2E, [20144] = 0x9D2F, [20145] = 0x9D31, [20146] = 0x9D38, +- [20147] = 0x9D30, [20182] = 0x9D45, [20183] = 0x9D42, [20184] = 0x9D43, +- [20185] = 0x9D3E, [20186] = 0x9D37, [20187] = 0x9D40, [20188] = 0x9D3D, +- [20189] = 0x7FF5, [20190] = 0x9D2D, [20191] = 0x9E8A, [20192] = 0x9E89, +- [20193] = 0x9E8D, [20194] = 0x9EB0, [20195] = 0x9EC8, [20196] = 0x9EDA, +- [20197] = 0x9EFB, [20198] = 0x9EFF, [20199] = 0x9F24, [20200] = 0x9F23, +- [20201] = 0x9F22, [20202] = 0x9F54, [20203] = 0x9FA0, [20204] = 0x5131, +- [20205] = 0x512D, [20206] = 0x512E, [20207] = 0x5698, [20208] = 0x569C, +- [20209] = 0x5697, [20210] = 0x569A, [20211] = 0x569D, [20212] = 0x5699, +- [20213] = 0x5970, [20214] = 0x5B3C, [20215] = 0x5C69, [20216] = 0x5C6A, +- [20217] = 0x5DC0, [20218] = 0x5E6D, [20219] = 0x5E6E, [20220] = 0x61D8, +- [20221] = 0x61DF, [20222] = 0x61ED, [20223] = 0x61EE, [20224] = 0x61F1, +- [20225] = 0x61EA, [20226] = 0x61F0, [20227] = 0x61EB, [20228] = 0x61D6, +- [20229] = 0x61E9, [20230] = 0x64FF, [20231] = 0x6504, [20232] = 0x64FD, +- [20233] = 0x64F8, [20234] = 0x6501, [20235] = 0x6503, [20236] = 0x64FC, +- [20237] = 0x6594, [20238] = 0x65DB, [20239] = 0x66DA, [20240] = 0x66DB, +- [20241] = 0x66D8, [20242] = 0x6AC5, [20243] = 0x6AB9, [20244] = 0x6ABD, +- [20245] = 0x6AE1, [20246] = 0x6AC6, [20247] = 0x6ABA, [20248] = 0x6AB6, +- [20249] = 0x6AB7, [20250] = 0x6AC7, [20251] = 0x6AB4, [20252] = 0x6AAD, +- [20253] = 0x6B5E, [20254] = 0x6BC9, [20255] = 0x6C0B, [20256] = 0x7007, +- [20257] = 0x700C, [20258] = 0x700D, [20259] = 0x7001, [20260] = 0x7005, +- [20261] = 0x7014, [20262] = 0x700E, [20263] = 0x6FFF, [20264] = 0x7000, +- [20265] = 0x6FFB, [20266] = 0x7026, [20267] = 0x6FFC, [20268] = 0x6FF7, +- [20269] = 0x700A, [20270] = 0x7201, [20271] = 0x71FF, [20272] = 0x71F9, +- [20273] = 0x7203, [20274] = 0x71FD, [20275] = 0x7376, [20280] = 0x74B8, +- [20281] = 0x74C0, [20282] = 0x74B5, [20283] = 0x74C1, [20284] = 0x74BE, +- [20285] = 0x74B6, [20286] = 0x74BB, [20287] = 0x74C2, [20288] = 0x7514, +- [20289] = 0x7513, [20290] = 0x765C, [20291] = 0x7664, [20292] = 0x7659, +- [20293] = 0x7650, [20294] = 0x7653, [20295] = 0x7657, [20296] = 0x765A, +- [20297] = 0x76A6, [20298] = 0x76BD, [20299] = 0x76EC, [20300] = 0x77C2, +- [20301] = 0x77BA, [20302] = 0x78FF, [20303] = 0x790C, [20304] = 0x7913, +- [20305] = 0x7914, [20306] = 0x7909, [20307] = 0x7910, [20308] = 0x7912, +- [20309] = 0x7911, [20310] = 0x79AD, [20311] = 0x79AC, [20312] = 0x7A5F, +- [20313] = 0x7C1C, [20314] = 0x7C29, [20315] = 0x7C19, [20316] = 0x7C20, +- [20317] = 0x7C1F, [20318] = 0x7C2D, [20319] = 0x7C1D, [20320] = 0x7C26, +- [20321] = 0x7C28, [20322] = 0x7C22, [20323] = 0x7C25, [20324] = 0x7C30, +- [20325] = 0x7E5C, [20326] = 0x7E50, [20327] = 0x7E56, [20328] = 0x7E63, +- [20329] = 0x7E58, [20330] = 0x7E62, [20331] = 0x7E5F, [20332] = 0x7E51, +- [20333] = 0x7E60, [20334] = 0x7E57, [20335] = 0x7E53, [20336] = 0x7FB5, +- [20337] = 0x7FB3, [20338] = 0x7FF7, [20339] = 0x7FF8, [20340] = 0x8075, +- [20341] = 0x81D1, [20342] = 0x81D2, [20377] = 0x81D0, [20378] = 0x825F, +- [20379] = 0x825E, [20380] = 0x85B4, [20381] = 0x85C6, [20382] = 0x85C0, +- [20383] = 0x85C3, [20384] = 0x85C2, [20385] = 0x85B3, [20386] = 0x85B5, +- [20387] = 0x85BD, [20388] = 0x85C7, [20389] = 0x85C4, [20390] = 0x85BF, +- [20391] = 0x85CB, [20392] = 0x85CE, [20393] = 0x85C8, [20394] = 0x85C5, +- [20395] = 0x85B1, [20396] = 0x85B6, [20397] = 0x85D2, [20398] = 0x8624, +- [20399] = 0x85B8, [20400] = 0x85B7, [20401] = 0x85BE, [20402] = 0x8669, +- [20403] = 0x87E7, [20404] = 0x87E6, [20405] = 0x87E2, [20406] = 0x87DB, +- [20407] = 0x87EB, [20408] = 0x87EA, [20409] = 0x87E5, [20410] = 0x87DF, +- [20411] = 0x87F3, [20412] = 0x87E4, [20413] = 0x87D4, [20414] = 0x87DC, +- [20415] = 0x87D3, [20416] = 0x87ED, [20417] = 0x87D8, [20418] = 0x87E3, +- [20419] = 0x87A4, [20420] = 0x87D7, [20421] = 0x87D9, [20422] = 0x8801, +- [20423] = 0x87F4, [20424] = 0x87E8, [20425] = 0x87DD, [20426] = 0x8953, +- [20427] = 0x894B, [20428] = 0x894F, [20429] = 0x894C, [20430] = 0x8946, +- [20431] = 0x8950, [20432] = 0x8951, [20433] = 0x8949, [20434] = 0x8B2A, +- [20435] = 0x8B27, [20436] = 0x8B23, [20437] = 0x8B33, [20438] = 0x8B30, +- [20439] = 0x8B35, [20440] = 0x8B47, [20441] = 0x8B2F, [20442] = 0x8B3C, +- [20443] = 0x8B3E, [20444] = 0x8B31, [20445] = 0x8B25, [20446] = 0x8B37, +- [20447] = 0x8B26, [20448] = 0x8B36, [20449] = 0x8B2E, [20450] = 0x8B24, +- [20451] = 0x8B3B, [20452] = 0x8B3D, [20453] = 0x8B3A, [20454] = 0x8C42, +- [20455] = 0x8C75, [20456] = 0x8C99, [20457] = 0x8C98, [20458] = 0x8C97, +- [20459] = 0x8CFE, [20460] = 0x8D04, [20461] = 0x8D02, [20462] = 0x8D00, +- [20463] = 0x8E5C, [20464] = 0x8E62, [20465] = 0x8E60, [20466] = 0x8E57, +- [20467] = 0x8E56, [20468] = 0x8E5E, [20469] = 0x8E65, [20470] = 0x8E67, +- [20475] = 0x8E5B, [20476] = 0x8E5A, [20477] = 0x8E61, [20478] = 0x8E5D, +- [20479] = 0x8E69, [20480] = 0x8E54, [20481] = 0x8F46, [20482] = 0x8F47, +- [20483] = 0x8F48, [20484] = 0x8F4B, [20485] = 0x9128, [20486] = 0x913A, +- [20487] = 0x913B, [20488] = 0x913E, [20489] = 0x91A8, [20490] = 0x91A5, +- [20491] = 0x91A7, [20492] = 0x91AF, [20493] = 0x91AA, [20494] = 0x93B5, +- [20495] = 0x938C, [20496] = 0x9392, [20497] = 0x93B7, [20498] = 0x939B, +- [20499] = 0x939D, [20500] = 0x9389, [20501] = 0x93A7, [20502] = 0x938E, +- [20503] = 0x93AA, [20504] = 0x939E, [20505] = 0x93A6, [20506] = 0x9395, +- [20507] = 0x9388, [20508] = 0x9399, [20509] = 0x939F, [20510] = 0x938D, +- [20511] = 0x93B1, [20512] = 0x9391, [20513] = 0x93B2, [20514] = 0x93A4, +- [20515] = 0x93A8, [20516] = 0x93B4, [20517] = 0x93A3, [20518] = 0x93A5, +- [20519] = 0x95D2, [20520] = 0x95D3, [20521] = 0x95D1, [20522] = 0x96B3, +- [20523] = 0x96D7, [20524] = 0x96DA, [20525] = 0x5DC2, [20526] = 0x96DF, +- [20527] = 0x96D8, [20528] = 0x96DD, [20529] = 0x9723, [20530] = 0x9722, +- [20531] = 0x9725, [20532] = 0x97AC, [20533] = 0x97AE, [20534] = 0x97A8, +- [20535] = 0x97AB, [20536] = 0x97A4, [20537] = 0x97AA, [20572] = 0x97A2, +- [20573] = 0x97A5, [20574] = 0x97D7, [20575] = 0x97D9, [20576] = 0x97D6, +- [20577] = 0x97D8, [20578] = 0x97FA, [20579] = 0x9850, [20580] = 0x9851, +- [20581] = 0x9852, [20582] = 0x98B8, [20583] = 0x9941, [20584] = 0x993C, +- [20585] = 0x993A, [20586] = 0x9A0F, [20587] = 0x9A0B, [20588] = 0x9A09, +- [20589] = 0x9A0D, [20590] = 0x9A04, [20591] = 0x9A11, [20592] = 0x9A0A, +- [20593] = 0x9A05, [20594] = 0x9A07, [20595] = 0x9A06, [20596] = 0x9AC0, +- [20597] = 0x9ADC, [20598] = 0x9B08, [20599] = 0x9B04, [20600] = 0x9B05, +- [20601] = 0x9B29, [20602] = 0x9B35, [20603] = 0x9B4A, [20604] = 0x9B4C, +- [20605] = 0x9B4B, [20606] = 0x9BC7, [20607] = 0x9BC6, [20608] = 0x9BC3, +- [20609] = 0x9BBF, [20610] = 0x9BC1, [20611] = 0x9BB5, [20612] = 0x9BB8, +- [20613] = 0x9BD3, [20614] = 0x9BB6, [20615] = 0x9BC4, [20616] = 0x9BB9, +- [20617] = 0x9BBD, [20618] = 0x9D5C, [20619] = 0x9D53, [20620] = 0x9D4F, +- [20621] = 0x9D4A, [20622] = 0x9D5B, [20623] = 0x9D4B, [20624] = 0x9D59, +- [20625] = 0x9D56, [20626] = 0x9D4C, [20627] = 0x9D57, [20628] = 0x9D52, +- [20629] = 0x9D54, [20630] = 0x9D5F, [20631] = 0x9D58, [20632] = 0x9D5A, +- [20633] = 0x9E8E, [20634] = 0x9E8C, [20635] = 0x9EDF, [20636] = 0x9F01, +- [20637] = 0x9F00, [20638] = 0x9F16, [20639] = 0x9F25, [20640] = 0x9F2B, +- [20641] = 0x9F2A, [20642] = 0x9F29, [20643] = 0x9F28, [20644] = 0x9F4C, +- [20645] = 0x9F55, [20646] = 0x5134, [20647] = 0x5135, [20648] = 0x5296, +- [20649] = 0x52F7, [20650] = 0x53B4, [20651] = 0x56AB, [20652] = 0x56AD, +- [20653] = 0x56A6, [20654] = 0x56A7, [20655] = 0x56AA, [20656] = 0x56AC, +- [20657] = 0x58DA, [20658] = 0x58DD, [20659] = 0x58DB, [20660] = 0x5912, +- [20661] = 0x5B3D, [20662] = 0x5B3E, [20663] = 0x5B3F, [20664] = 0x5DC3, +- [20665] = 0x5E70, [20670] = 0x5FBF, [20671] = 0x61FB, [20672] = 0x6507, +- [20673] = 0x6510, [20674] = 0x650D, [20675] = 0x6509, [20676] = 0x650C, +- [20677] = 0x650E, [20678] = 0x6584, [20679] = 0x65DE, [20680] = 0x65DD, +- [20681] = 0x66DE, [20682] = 0x6AE7, [20683] = 0x6AE0, [20684] = 0x6ACC, +- [20685] = 0x6AD1, [20686] = 0x6AD9, [20687] = 0x6ACB, [20688] = 0x6ADF, +- [20689] = 0x6ADC, [20690] = 0x6AD0, [20691] = 0x6AEB, [20692] = 0x6ACF, +- [20693] = 0x6ACD, [20694] = 0x6ADE, [20695] = 0x6B60, [20696] = 0x6BB0, +- [20697] = 0x6C0C, [20698] = 0x7019, [20699] = 0x7027, [20700] = 0x7020, +- [20701] = 0x7016, [20702] = 0x702B, [20703] = 0x7021, [20704] = 0x7022, +- [20705] = 0x7023, [20706] = 0x7029, [20707] = 0x7017, [20708] = 0x7024, +- [20709] = 0x701C, [20710] = 0x702A, [20711] = 0x720C, [20712] = 0x720A, +- [20713] = 0x7207, [20714] = 0x7202, [20715] = 0x7205, [20716] = 0x72A5, +- [20717] = 0x72A6, [20718] = 0x72A4, [20719] = 0x72A3, [20720] = 0x72A1, +- [20721] = 0x74CB, [20722] = 0x74C5, [20723] = 0x74B7, [20724] = 0x74C3, +- [20725] = 0x7516, [20726] = 0x7660, [20727] = 0x77C9, [20728] = 0x77CA, +- [20729] = 0x77C4, [20730] = 0x77F1, [20731] = 0x791D, [20732] = 0x791B, +- [20767] = 0x7921, [20768] = 0x791C, [20769] = 0x7917, [20770] = 0x791E, +- [20771] = 0x79B0, [20772] = 0x7A67, [20773] = 0x7A68, [20774] = 0x7C33, +- [20775] = 0x7C3C, [20776] = 0x7C39, [20777] = 0x7C2C, [20778] = 0x7C3B, +- [20779] = 0x7CEC, [20780] = 0x7CEA, [20781] = 0x7E76, [20782] = 0x7E75, +- [20783] = 0x7E78, [20784] = 0x7E70, [20785] = 0x7E77, [20786] = 0x7E6F, +- [20787] = 0x7E7A, [20788] = 0x7E72, [20789] = 0x7E74, [20790] = 0x7E68, +- [20791] = 0x7F4B, [20792] = 0x7F4A, [20793] = 0x7F83, [20794] = 0x7F86, +- [20795] = 0x7FB7, [20796] = 0x7FFD, [20797] = 0x7FFE, [20798] = 0x8078, +- [20799] = 0x81D7, [20800] = 0x81D5, [20801] = 0x8264, [20802] = 0x8261, +- [20803] = 0x8263, [20804] = 0x85EB, [20805] = 0x85F1, [20806] = 0x85ED, +- [20807] = 0x85D9, [20808] = 0x85E1, [20809] = 0x85E8, [20810] = 0x85DA, +- [20811] = 0x85D7, [20812] = 0x85EC, [20813] = 0x85F2, [20814] = 0x85F8, +- [20815] = 0x85D8, [20816] = 0x85DF, [20817] = 0x85E3, [20818] = 0x85DC, +- [20819] = 0x85D1, [20820] = 0x85F0, [20821] = 0x85E6, [20822] = 0x85EF, +- [20823] = 0x85DE, [20824] = 0x85E2, [20825] = 0x8800, [20826] = 0x87FA, +- [20827] = 0x8803, [20828] = 0x87F6, [20829] = 0x87F7, [20830] = 0x8809, +- [20831] = 0x880C, [20832] = 0x880B, [20833] = 0x8806, [20834] = 0x87FC, +- [20835] = 0x8808, [20836] = 0x87FF, [20837] = 0x880A, [20838] = 0x8802, +- [20839] = 0x8962, [20840] = 0x895A, [20841] = 0x895B, [20842] = 0x8957, +- [20843] = 0x8961, [20844] = 0x895C, [20845] = 0x8958, [20846] = 0x895D, +- [20847] = 0x8959, [20848] = 0x8988, [20849] = 0x89B7, [20850] = 0x89B6, +- [20851] = 0x89F6, [20852] = 0x8B50, [20853] = 0x8B48, [20854] = 0x8B4A, +- [20855] = 0x8B40, [20856] = 0x8B53, [20857] = 0x8B56, [20858] = 0x8B54, +- [20859] = 0x8B4B, [20860] = 0x8B55, [20865] = 0x8B51, [20866] = 0x8B42, +- [20867] = 0x8B52, [20868] = 0x8B57, [20869] = 0x8C43, [20870] = 0x8C77, +- [20871] = 0x8C76, [20872] = 0x8C9A, [20873] = 0x8D06, [20874] = 0x8D07, +- [20875] = 0x8D09, [20876] = 0x8DAC, [20877] = 0x8DAA, [20878] = 0x8DAD, +- [20879] = 0x8DAB, [20880] = 0x8E6D, [20881] = 0x8E78, [20882] = 0x8E73, +- [20883] = 0x8E6A, [20884] = 0x8E6F, [20885] = 0x8E7B, [20886] = 0x8EC2, +- [20887] = 0x8F52, [20888] = 0x8F51, [20889] = 0x8F4F, [20890] = 0x8F50, +- [20891] = 0x8F53, [20892] = 0x8FB4, [20893] = 0x9140, [20894] = 0x913F, +- [20895] = 0x91B0, [20896] = 0x91AD, [20897] = 0x93DE, [20898] = 0x93C7, +- [20899] = 0x93CF, [20900] = 0x93C2, [20901] = 0x93DA, [20902] = 0x93D0, +- [20903] = 0x93F9, [20904] = 0x93EC, [20905] = 0x93CC, [20906] = 0x93D9, +- [20907] = 0x93A9, [20908] = 0x93E6, [20909] = 0x93CA, [20910] = 0x93D4, +- [20911] = 0x93EE, [20912] = 0x93E3, [20913] = 0x93D5, [20914] = 0x93C4, +- [20915] = 0x93CE, [20916] = 0x93C0, [20917] = 0x93D2, [20918] = 0x93E7, +- [20919] = 0x957D, [20920] = 0x95DA, [20921] = 0x95DB, [20922] = 0x96E1, +- [20923] = 0x9729, [20924] = 0x972B, [20925] = 0x972C, [20926] = 0x9728, +- [20927] = 0x9726, [20962] = 0x97B3, [20963] = 0x97B7, [20964] = 0x97B6, +- [20965] = 0x97DD, [20966] = 0x97DE, [20967] = 0x97DF, [20968] = 0x985C, +- [20969] = 0x9859, [20970] = 0x985D, [20971] = 0x9857, [20972] = 0x98BF, +- [20973] = 0x98BD, [20974] = 0x98BB, [20975] = 0x98BE, [20976] = 0x9948, +- [20977] = 0x9947, [20978] = 0x9943, [20979] = 0x99A6, [20980] = 0x99A7, +- [20981] = 0x9A1A, [20982] = 0x9A15, [20983] = 0x9A25, [20984] = 0x9A1D, +- [20985] = 0x9A24, [20986] = 0x9A1B, [20987] = 0x9A22, [20988] = 0x9A20, +- [20989] = 0x9A27, [20990] = 0x9A23, [20991] = 0x9A1E, [20992] = 0x9A1C, +- [20993] = 0x9A14, [20994] = 0x9AC2, [20995] = 0x9B0B, [20996] = 0x9B0A, +- [20997] = 0x9B0E, [20998] = 0x9B0C, [20999] = 0x9B37, [21000] = 0x9BEA, +- [21001] = 0x9BEB, [21002] = 0x9BE0, [21003] = 0x9BDE, [21004] = 0x9BE4, +- [21005] = 0x9BE6, [21006] = 0x9BE2, [21007] = 0x9BF0, [21008] = 0x9BD4, +- [21009] = 0x9BD7, [21010] = 0x9BEC, [21011] = 0x9BDC, [21012] = 0x9BD9, +- [21013] = 0x9BE5, [21014] = 0x9BD5, [21015] = 0x9BE1, [21016] = 0x9BDA, +- [21017] = 0x9D77, [21018] = 0x9D81, [21019] = 0x9D8A, [21020] = 0x9D84, +- [21021] = 0x9D88, [21022] = 0x9D71, [21023] = 0x9D80, [21024] = 0x9D78, +- [21025] = 0x9D86, [21026] = 0x9D8B, [21027] = 0x9D8C, [21028] = 0x9D7D, +- [21029] = 0x9D6B, [21030] = 0x9D74, [21031] = 0x9D75, [21032] = 0x9D70, +- [21033] = 0x9D69, [21034] = 0x9D85, [21035] = 0x9D73, [21036] = 0x9D7B, +- [21037] = 0x9D82, [21038] = 0x9D6F, [21039] = 0x9D79, [21040] = 0x9D7F, +- [21041] = 0x9D87, [21042] = 0x9D68, [21043] = 0x9E94, [21044] = 0x9E91, +- [21045] = 0x9EC0, [21046] = 0x9EFC, [21047] = 0x9F2D, [21048] = 0x9F40, +- [21049] = 0x9F41, [21050] = 0x9F4D, [21051] = 0x9F56, [21052] = 0x9F57, +- [21053] = 0x9F58, [21054] = 0x5337, [21055] = 0x56B2, [21060] = 0x56B5, +- [21061] = 0x56B3, [21062] = 0x58E3, [21063] = 0x5B45, [21064] = 0x5DC6, +- [21065] = 0x5DC7, [21066] = 0x5EEE, [21067] = 0x5EEF, [21068] = 0x5FC0, +- [21069] = 0x5FC1, [21070] = 0x61F9, [21071] = 0x6517, [21072] = 0x6516, +- [21073] = 0x6515, [21074] = 0x6513, [21075] = 0x65DF, [21076] = 0x66E8, +- [21077] = 0x66E3, [21078] = 0x66E4, [21079] = 0x6AF3, [21080] = 0x6AF0, +- [21081] = 0x6AEA, [21082] = 0x6AE8, [21083] = 0x6AF9, [21084] = 0x6AF1, +- [21085] = 0x6AEE, [21086] = 0x6AEF, [21087] = 0x703C, [21088] = 0x7035, +- [21089] = 0x702F, [21090] = 0x7037, [21091] = 0x7034, [21092] = 0x7031, +- [21093] = 0x7042, [21094] = 0x7038, [21095] = 0x703F, [21096] = 0x703A, +- [21097] = 0x7039, [21098] = 0x7040, [21099] = 0x703B, [21100] = 0x7033, +- [21101] = 0x7041, [21102] = 0x7213, [21103] = 0x7214, [21104] = 0x72A8, +- [21105] = 0x737D, [21106] = 0x737C, [21107] = 0x74BA, [21108] = 0x76AB, +- [21109] = 0x76AA, [21110] = 0x76BE, [21111] = 0x76ED, [21112] = 0x77CC, +- [21113] = 0x77CE, [21114] = 0x77CF, [21115] = 0x77CD, [21116] = 0x77F2, +- [21117] = 0x7925, [21118] = 0x7923, [21119] = 0x7927, [21120] = 0x7928, +- [21121] = 0x7924, [21122] = 0x7929, [21157] = 0x79B2, [21158] = 0x7A6E, +- [21159] = 0x7A6C, [21160] = 0x7A6D, [21161] = 0x7AF7, [21162] = 0x7C49, +- [21163] = 0x7C48, [21164] = 0x7C4A, [21165] = 0x7C47, [21166] = 0x7C45, +- [21167] = 0x7CEE, [21168] = 0x7E7B, [21169] = 0x7E7E, [21170] = 0x7E81, +- [21171] = 0x7E80, [21172] = 0x7FBA, [21173] = 0x7FFF, [21174] = 0x8079, +- [21175] = 0x81DB, [21176] = 0x81D9, [21177] = 0x820B, [21178] = 0x8268, +- [21179] = 0x8269, [21180] = 0x8622, [21181] = 0x85FF, [21182] = 0x8601, +- [21183] = 0x85FE, [21184] = 0x861B, [21185] = 0x8600, [21186] = 0x85F6, +- [21187] = 0x8604, [21188] = 0x8609, [21189] = 0x8605, [21190] = 0x860C, +- [21191] = 0x85FD, [21192] = 0x8819, [21193] = 0x8810, [21194] = 0x8811, +- [21195] = 0x8817, [21196] = 0x8813, [21197] = 0x8816, [21198] = 0x8963, +- [21199] = 0x8966, [21200] = 0x89B9, [21201] = 0x89F7, [21202] = 0x8B60, +- [21203] = 0x8B6A, [21204] = 0x8B5D, [21205] = 0x8B68, [21206] = 0x8B63, +- [21207] = 0x8B65, [21208] = 0x8B67, [21209] = 0x8B6D, [21210] = 0x8DAE, +- [21211] = 0x8E86, [21212] = 0x8E88, [21213] = 0x8E84, [21214] = 0x8F59, +- [21215] = 0x8F56, [21216] = 0x8F57, [21217] = 0x8F55, [21218] = 0x8F58, +- [21219] = 0x8F5A, [21220] = 0x908D, [21221] = 0x9143, [21222] = 0x9141, +- [21223] = 0x91B7, [21224] = 0x91B5, [21225] = 0x91B2, [21226] = 0x91B3, +- [21227] = 0x940B, [21228] = 0x9413, [21229] = 0x93FB, [21230] = 0x9420, +- [21231] = 0x940F, [21232] = 0x9414, [21233] = 0x93FE, [21234] = 0x9415, +- [21235] = 0x9410, [21236] = 0x9428, [21237] = 0x9419, [21238] = 0x940D, +- [21239] = 0x93F5, [21240] = 0x9400, [21241] = 0x93F7, [21242] = 0x9407, +- [21243] = 0x940E, [21244] = 0x9416, [21245] = 0x9412, [21246] = 0x93FA, +- [21247] = 0x9409, [21248] = 0x93F8, [21249] = 0x940A, [21250] = 0x93FF, +- [21255] = 0x93FC, [21256] = 0x940C, [21257] = 0x93F6, [21258] = 0x9411, +- [21259] = 0x9406, [21260] = 0x95DE, [21261] = 0x95E0, [21262] = 0x95DF, +- [21263] = 0x972E, [21264] = 0x972F, [21265] = 0x97B9, [21266] = 0x97BB, +- [21267] = 0x97FD, [21268] = 0x97FE, [21269] = 0x9860, [21270] = 0x9862, +- [21271] = 0x9863, [21272] = 0x985F, [21273] = 0x98C1, [21274] = 0x98C2, +- [21275] = 0x9950, [21276] = 0x994E, [21277] = 0x9959, [21278] = 0x994C, +- [21279] = 0x994B, [21280] = 0x9953, [21281] = 0x9A32, [21282] = 0x9A34, +- [21283] = 0x9A31, [21284] = 0x9A2C, [21285] = 0x9A2A, [21286] = 0x9A36, +- [21287] = 0x9A29, [21288] = 0x9A2E, [21289] = 0x9A38, [21290] = 0x9A2D, +- [21291] = 0x9AC7, [21292] = 0x9ACA, [21293] = 0x9AC6, [21294] = 0x9B10, +- [21295] = 0x9B12, [21296] = 0x9B11, [21297] = 0x9C0B, [21298] = 0x9C08, +- [21299] = 0x9BF7, [21300] = 0x9C05, [21301] = 0x9C12, [21302] = 0x9BF8, +- [21303] = 0x9C40, [21304] = 0x9C07, [21305] = 0x9C0E, [21306] = 0x9C06, +- [21307] = 0x9C17, [21308] = 0x9C14, [21309] = 0x9C09, [21310] = 0x9D9F, +- [21311] = 0x9D99, [21312] = 0x9DA4, [21313] = 0x9D9D, [21314] = 0x9D92, +- [21315] = 0x9D98, [21316] = 0x9D90, [21317] = 0x9D9B, [21352] = 0x9DA0, +- [21353] = 0x9D94, [21354] = 0x9D9C, [21355] = 0x9DAA, [21356] = 0x9D97, +- [21357] = 0x9DA1, [21358] = 0x9D9A, [21359] = 0x9DA2, [21360] = 0x9DA8, +- [21361] = 0x9D9E, [21362] = 0x9DA3, [21363] = 0x9DBF, [21364] = 0x9DA9, +- [21365] = 0x9D96, [21366] = 0x9DA6, [21367] = 0x9DA7, [21368] = 0x9E99, +- [21369] = 0x9E9B, [21370] = 0x9E9A, [21371] = 0x9EE5, [21372] = 0x9EE4, +- [21373] = 0x9EE7, [21374] = 0x9EE6, [21375] = 0x9F30, [21376] = 0x9F2E, +- [21377] = 0x9F5B, [21378] = 0x9F60, [21379] = 0x9F5E, [21380] = 0x9F5D, +- [21381] = 0x9F59, [21382] = 0x9F91, [21383] = 0x513A, [21384] = 0x5139, +- [21385] = 0x5298, [21386] = 0x5297, [21387] = 0x56C3, [21388] = 0x56BD, +- [21389] = 0x56BE, [21390] = 0x5B48, [21391] = 0x5B47, [21392] = 0x5DCB, +- [21393] = 0x5DCF, [21394] = 0x5EF1, [21395] = 0x61FD, [21396] = 0x651B, +- [21397] = 0x6B02, [21398] = 0x6AFC, [21399] = 0x6B03, [21400] = 0x6AF8, +- [21401] = 0x6B00, [21402] = 0x7043, [21403] = 0x7044, [21404] = 0x704A, +- [21405] = 0x7048, [21406] = 0x7049, [21407] = 0x7045, [21408] = 0x7046, +- [21409] = 0x721D, [21410] = 0x721A, [21411] = 0x7219, [21412] = 0x737E, +- [21413] = 0x7517, [21414] = 0x766A, [21415] = 0x77D0, [21416] = 0x792D, +- [21417] = 0x7931, [21418] = 0x792F, [21419] = 0x7C54, [21420] = 0x7C53, +- [21421] = 0x7CF2, [21422] = 0x7E8A, [21423] = 0x7E87, [21424] = 0x7E88, +- [21425] = 0x7E8B, [21426] = 0x7E86, [21427] = 0x7E8D, [21428] = 0x7F4D, +- [21429] = 0x7FBB, [21430] = 0x8030, [21431] = 0x81DD, [21432] = 0x8618, +- [21433] = 0x862A, [21434] = 0x8626, [21435] = 0x861F, [21436] = 0x8623, +- [21437] = 0x861C, [21438] = 0x8619, [21439] = 0x8627, [21440] = 0x862E, +- [21441] = 0x8621, [21442] = 0x8620, [21443] = 0x8629, [21444] = 0x861E, +- [21445] = 0x8625, [21450] = 0x8829, [21451] = 0x881D, [21452] = 0x881B, +- [21453] = 0x8820, [21454] = 0x8824, [21455] = 0x881C, [21456] = 0x882B, +- [21457] = 0x884A, [21458] = 0x896D, [21459] = 0x8969, [21460] = 0x896E, +- [21461] = 0x896B, [21462] = 0x89FA, [21463] = 0x8B79, [21464] = 0x8B78, +- [21465] = 0x8B45, [21466] = 0x8B7A, [21467] = 0x8B7B, [21468] = 0x8D10, +- [21469] = 0x8D14, [21470] = 0x8DAF, [21471] = 0x8E8E, [21472] = 0x8E8C, +- [21473] = 0x8F5E, [21474] = 0x8F5B, [21475] = 0x8F5D, [21476] = 0x9146, +- [21477] = 0x9144, [21478] = 0x9145, [21479] = 0x91B9, [21480] = 0x943F, +- [21481] = 0x943B, [21482] = 0x9436, [21483] = 0x9429, [21484] = 0x943D, +- [21485] = 0x943C, [21486] = 0x9430, [21487] = 0x9439, [21488] = 0x942A, +- [21489] = 0x9437, [21490] = 0x942C, [21491] = 0x9440, [21492] = 0x9431, +- [21493] = 0x95E5, [21494] = 0x95E4, [21495] = 0x95E3, [21496] = 0x9735, +- [21497] = 0x973A, [21498] = 0x97BF, [21499] = 0x97E1, [21500] = 0x9864, +- [21501] = 0x98C9, [21502] = 0x98C6, [21503] = 0x98C0, [21504] = 0x9958, +- [21505] = 0x9956, [21506] = 0x9A39, [21507] = 0x9A3D, [21508] = 0x9A46, +- [21509] = 0x9A44, [21510] = 0x9A42, [21511] = 0x9A41, [21512] = 0x9A3A, +- [21547] = 0x9A3F, [21548] = 0x9ACD, [21549] = 0x9B15, [21550] = 0x9B17, +- [21551] = 0x9B18, [21552] = 0x9B16, [21553] = 0x9B3A, [21554] = 0x9B52, +- [21555] = 0x9C2B, [21556] = 0x9C1D, [21557] = 0x9C1C, [21558] = 0x9C2C, +- [21559] = 0x9C23, [21560] = 0x9C28, [21561] = 0x9C29, [21562] = 0x9C24, +- [21563] = 0x9C21, [21564] = 0x9DB7, [21565] = 0x9DB6, [21566] = 0x9DBC, +- [21567] = 0x9DC1, [21568] = 0x9DC7, [21569] = 0x9DCA, [21570] = 0x9DCF, +- [21571] = 0x9DBE, [21572] = 0x9DC5, [21573] = 0x9DC3, [21574] = 0x9DBB, +- [21575] = 0x9DB5, [21576] = 0x9DCE, [21577] = 0x9DB9, [21578] = 0x9DBA, +- [21579] = 0x9DAC, [21580] = 0x9DC8, [21581] = 0x9DB1, [21582] = 0x9DAD, +- [21583] = 0x9DCC, [21584] = 0x9DB3, [21585] = 0x9DCD, [21586] = 0x9DB2, +- [21587] = 0x9E7A, [21588] = 0x9E9C, [21589] = 0x9EEB, [21590] = 0x9EEE, +- [21591] = 0x9EED, [21592] = 0x9F1B, [21593] = 0x9F18, [21594] = 0x9F1A, +- [21595] = 0x9F31, [21596] = 0x9F4E, [21597] = 0x9F65, [21598] = 0x9F64, +- [21599] = 0x9F92, [21600] = 0x4EB9, [21601] = 0x56C6, [21602] = 0x56C5, +- [21603] = 0x56CB, [21604] = 0x5971, [21605] = 0x5B4B, [21606] = 0x5B4C, +- [21607] = 0x5DD5, [21608] = 0x5DD1, [21609] = 0x5EF2, [21610] = 0x6521, +- [21611] = 0x6520, [21612] = 0x6526, [21613] = 0x6522, [21614] = 0x6B0B, +- [21615] = 0x6B08, [21616] = 0x6B09, [21617] = 0x6C0D, [21618] = 0x7055, +- [21619] = 0x7056, [21620] = 0x7057, [21621] = 0x7052, [21622] = 0x721E, +- [21623] = 0x721F, [21624] = 0x72A9, [21625] = 0x737F, [21626] = 0x74D8, +- [21627] = 0x74D5, [21628] = 0x74D9, [21629] = 0x74D7, [21630] = 0x766D, +- [21631] = 0x76AD, [21632] = 0x7935, [21633] = 0x79B4, [21634] = 0x7A70, +- [21635] = 0x7A71, [21636] = 0x7C57, [21637] = 0x7C5C, [21638] = 0x7C59, +- [21639] = 0x7C5B, [21640] = 0x7C5A, [21645] = 0x7CF4, [21646] = 0x7CF1, +- [21647] = 0x7E91, [21648] = 0x7F4F, [21649] = 0x7F87, [21650] = 0x81DE, +- [21651] = 0x826B, [21652] = 0x8634, [21653] = 0x8635, [21654] = 0x8633, +- [21655] = 0x862C, [21656] = 0x8632, [21657] = 0x8636, [21658] = 0x882C, +- [21659] = 0x8828, [21660] = 0x8826, [21661] = 0x882A, [21662] = 0x8825, +- [21663] = 0x8971, [21664] = 0x89BF, [21665] = 0x89BE, [21666] = 0x89FB, +- [21667] = 0x8B7E, [21668] = 0x8B84, [21669] = 0x8B82, [21670] = 0x8B86, +- [21671] = 0x8B85, [21672] = 0x8B7F, [21673] = 0x8D15, [21674] = 0x8E95, +- [21675] = 0x8E94, [21676] = 0x8E9A, [21677] = 0x8E92, [21678] = 0x8E90, +- [21679] = 0x8E96, [21680] = 0x8E97, [21681] = 0x8F60, [21682] = 0x8F62, +- [21683] = 0x9147, [21684] = 0x944C, [21685] = 0x9450, [21686] = 0x944A, +- [21687] = 0x944B, [21688] = 0x944F, [21689] = 0x9447, [21690] = 0x9445, +- [21691] = 0x9448, [21692] = 0x9449, [21693] = 0x9446, [21694] = 0x973F, +- [21695] = 0x97E3, [21696] = 0x986A, [21697] = 0x9869, [21698] = 0x98CB, +- [21699] = 0x9954, [21700] = 0x995B, [21701] = 0x9A4E, [21702] = 0x9A53, +- [21703] = 0x9A54, [21704] = 0x9A4C, [21705] = 0x9A4F, [21706] = 0x9A48, +- [21707] = 0x9A4A, [21742] = 0x9A49, [21743] = 0x9A52, [21744] = 0x9A50, +- [21745] = 0x9AD0, [21746] = 0x9B19, [21747] = 0x9B2B, [21748] = 0x9B3B, +- [21749] = 0x9B56, [21750] = 0x9B55, [21751] = 0x9C46, [21752] = 0x9C48, +- [21753] = 0x9C3F, [21754] = 0x9C44, [21755] = 0x9C39, [21756] = 0x9C33, +- [21757] = 0x9C41, [21758] = 0x9C3C, [21759] = 0x9C37, [21760] = 0x9C34, +- [21761] = 0x9C32, [21762] = 0x9C3D, [21763] = 0x9C36, [21764] = 0x9DDB, +- [21765] = 0x9DD2, [21766] = 0x9DDE, [21767] = 0x9DDA, [21768] = 0x9DCB, +- [21769] = 0x9DD0, [21770] = 0x9DDC, [21771] = 0x9DD1, [21772] = 0x9DDF, +- [21773] = 0x9DE9, [21774] = 0x9DD9, [21775] = 0x9DD8, [21776] = 0x9DD6, +- [21777] = 0x9DF5, [21778] = 0x9DD5, [21779] = 0x9DDD, [21780] = 0x9EB6, +- [21781] = 0x9EF0, [21782] = 0x9F35, [21783] = 0x9F33, [21784] = 0x9F32, +- [21785] = 0x9F42, [21786] = 0x9F6B, [21787] = 0x9F95, [21788] = 0x9FA2, +- [21789] = 0x513D, [21790] = 0x5299, [21791] = 0x58E8, [21792] = 0x58E7, +- [21793] = 0x5972, [21794] = 0x5B4D, [21795] = 0x5DD8, [21796] = 0x882F, +- [21797] = 0x5F4F, [21798] = 0x6201, [21799] = 0x6203, [21800] = 0x6204, +- [21801] = 0x6529, [21802] = 0x6525, [21803] = 0x6596, [21804] = 0x66EB, +- [21805] = 0x6B11, [21806] = 0x6B12, [21807] = 0x6B0F, [21808] = 0x6BCA, +- [21809] = 0x705B, [21810] = 0x705A, [21811] = 0x7222, [21812] = 0x7382, +- [21813] = 0x7381, [21814] = 0x7383, [21815] = 0x7670, [21816] = 0x77D4, +- [21817] = 0x7C67, [21818] = 0x7C66, [21819] = 0x7E95, [21820] = 0x826C, +- [21821] = 0x863A, [21822] = 0x8640, [21823] = 0x8639, [21824] = 0x863C, +- [21825] = 0x8631, [21826] = 0x863B, [21827] = 0x863E, [21828] = 0x8830, +- [21829] = 0x8832, [21830] = 0x882E, [21831] = 0x8833, [21832] = 0x8976, +- [21833] = 0x8974, [21834] = 0x8973, [21835] = 0x89FE, [21840] = 0x8B8C, +- [21841] = 0x8B8E, [21842] = 0x8B8B, [21843] = 0x8B88, [21844] = 0x8C45, +- [21845] = 0x8D19, [21846] = 0x8E98, [21847] = 0x8F64, [21848] = 0x8F63, +- [21849] = 0x91BC, [21850] = 0x9462, [21851] = 0x9455, [21852] = 0x945D, +- [21853] = 0x9457, [21854] = 0x945E, [21855] = 0x97C4, [21856] = 0x97C5, +- [21857] = 0x9800, [21858] = 0x9A56, [21859] = 0x9A59, [21860] = 0x9B1E, +- [21861] = 0x9B1F, [21862] = 0x9B20, [21863] = 0x9C52, [21864] = 0x9C58, +- [21865] = 0x9C50, [21866] = 0x9C4A, [21867] = 0x9C4D, [21868] = 0x9C4B, +- [21869] = 0x9C55, [21870] = 0x9C59, [21871] = 0x9C4C, [21872] = 0x9C4E, +- [21873] = 0x9DFB, [21874] = 0x9DF7, [21875] = 0x9DEF, [21876] = 0x9DE3, +- [21877] = 0x9DEB, [21878] = 0x9DF8, [21879] = 0x9DE4, [21880] = 0x9DF6, +- [21881] = 0x9DE1, [21882] = 0x9DEE, [21883] = 0x9DE6, [21884] = 0x9DF2, +- [21885] = 0x9DF0, [21886] = 0x9DE2, [21887] = 0x9DEC, [21888] = 0x9DF4, +- [21889] = 0x9DF3, [21890] = 0x9DE8, [21891] = 0x9DED, [21892] = 0x9EC2, +- [21893] = 0x9ED0, [21894] = 0x9EF2, [21895] = 0x9EF3, [21896] = 0x9F06, +- [21897] = 0x9F1C, [21898] = 0x9F38, [21899] = 0x9F37, [21900] = 0x9F36, +- [21901] = 0x9F43, [21902] = 0x9F4F, [21937] = 0x9F71, [21938] = 0x9F70, +- [21939] = 0x9F6E, [21940] = 0x9F6F, [21941] = 0x56D3, [21942] = 0x56CD, +- [21943] = 0x5B4E, [21944] = 0x5C6D, [21945] = 0x652D, [21946] = 0x66ED, +- [21947] = 0x66EE, [21948] = 0x6B13, [21949] = 0x705F, [21950] = 0x7061, +- [21951] = 0x705D, [21952] = 0x7060, [21953] = 0x7223, [21954] = 0x74DB, +- [21955] = 0x74E5, [21956] = 0x77D5, [21957] = 0x7938, [21958] = 0x79B7, +- [21959] = 0x79B6, [21960] = 0x7C6A, [21961] = 0x7E97, [21962] = 0x7F89, +- [21963] = 0x826D, [21964] = 0x8643, [21965] = 0x8838, [21966] = 0x8837, +- [21967] = 0x8835, [21968] = 0x884B, [21969] = 0x8B94, [21970] = 0x8B95, +- [21971] = 0x8E9E, [21972] = 0x8E9F, [21973] = 0x8EA0, [21974] = 0x8E9D, +- [21975] = 0x91BE, [21976] = 0x91BD, [21977] = 0x91C2, [21978] = 0x946B, +- [21979] = 0x9468, [21980] = 0x9469, [21981] = 0x96E5, [21982] = 0x9746, +- [21983] = 0x9743, [21984] = 0x9747, [21985] = 0x97C7, [21986] = 0x97E5, +- [21987] = 0x9A5E, [21988] = 0x9AD5, [21989] = 0x9B59, [21990] = 0x9C63, +- [21991] = 0x9C67, [21992] = 0x9C66, [21993] = 0x9C62, [21994] = 0x9C5E, +- [21995] = 0x9C60, [21996] = 0x9E02, [21997] = 0x9DFE, [21998] = 0x9E07, +- [21999] = 0x9E03, [22000] = 0x9E06, [22001] = 0x9E05, [22002] = 0x9E00, +- [22003] = 0x9E01, [22004] = 0x9E09, [22005] = 0x9DFF, [22006] = 0x9DFD, +- [22007] = 0x9E04, [22008] = 0x9EA0, [22009] = 0x9F1E, [22010] = 0x9F46, +- [22011] = 0x9F74, [22012] = 0x9F75, [22013] = 0x9F76, [22014] = 0x56D4, +- [22015] = 0x652E, [22016] = 0x65B8, [22017] = 0x6B18, [22018] = 0x6B19, +- [22019] = 0x6B17, [22020] = 0x6B1A, [22021] = 0x7062, [22022] = 0x7226, +- [22023] = 0x72AA, [22024] = 0x77D8, [22025] = 0x77D9, [22026] = 0x7939, +- [22027] = 0x7C69, [22028] = 0x7C6B, [22029] = 0x7CF6, [22030] = 0x7E9A, +- [22035] = 0x7E98, [22036] = 0x7E9B, [22037] = 0x7E99, [22038] = 0x81E0, +- [22039] = 0x81E1, [22040] = 0x8646, [22041] = 0x8647, [22042] = 0x8648, +- [22043] = 0x8979, [22044] = 0x897A, [22045] = 0x897C, [22046] = 0x897B, +- [22047] = 0x89FF, [22048] = 0x8B98, [22049] = 0x8B99, [22050] = 0x8EA5, +- [22051] = 0x8EA4, [22052] = 0x8EA3, [22053] = 0x946E, [22054] = 0x946D, +- [22055] = 0x946F, [22056] = 0x9471, [22057] = 0x9473, [22058] = 0x9749, +- [22059] = 0x9872, [22060] = 0x995F, [22061] = 0x9C68, [22062] = 0x9C6E, +- [22063] = 0x9C6D, [22064] = 0x9E0B, [22065] = 0x9E0D, [22066] = 0x9E10, +- [22067] = 0x9E0F, [22068] = 0x9E12, [22069] = 0x9E11, [22070] = 0x9EA1, +- [22071] = 0x9EF5, [22072] = 0x9F09, [22073] = 0x9F47, [22074] = 0x9F78, +- [22075] = 0x9F7B, [22076] = 0x9F7A, [22077] = 0x9F79, [22078] = 0x571E, +- [22079] = 0x7066, [22080] = 0x7C6F, [22081] = 0x883C, [22082] = 0x8DB2, +- [22083] = 0x8EA6, [22084] = 0x91C3, [22085] = 0x9474, [22086] = 0x9478, +- [22087] = 0x9476, [22088] = 0x9475, [22089] = 0x9A60, [22090] = 0x9C74, +- [22091] = 0x9C73, [22092] = 0x9C71, [22093] = 0x9C75, [22094] = 0x9E14, +- [22095] = 0x9E13, [22096] = 0x9EF6, [22097] = 0x9F0A, [22132] = 0x9FA4, +- [22133] = 0x7068, [22134] = 0x7065, [22135] = 0x7CF7, [22136] = 0x866A, +- [22137] = 0x883E, [22138] = 0x883D, [22139] = 0x883F, [22140] = 0x8B9E, +- [22141] = 0x8C9C, [22142] = 0x8EA9, [22143] = 0x8EC9, [22144] = 0x974B, +- [22145] = 0x9873, [22146] = 0x9874, [22147] = 0x98CC, [22148] = 0x9961, +- [22149] = 0x99AB, [22150] = 0x9A64, [22151] = 0x9A66, [22152] = 0x9A67, +- [22153] = 0x9B24, [22154] = 0x9E15, [22155] = 0x9E17, [22156] = 0x9F48, +- [22157] = 0x6207, [22158] = 0x6B1E, [22159] = 0x7227, [22160] = 0x864C, +- [22161] = 0x8EA8, [22162] = 0x9482, [22163] = 0x9480, [22164] = 0x9481, +- [22165] = 0x9A69, [22166] = 0x9A68, [22167] = 0x9B2E, [22168] = 0x9E19, +- [22169] = 0x7229, [22170] = 0x864B, [22171] = 0x8B9F, [22172] = 0x9483, +- [22173] = 0x9C79, [22174] = 0x9EB7, [22175] = 0x7675, [22176] = 0x9A6B, +- [22177] = 0x9C7A, [22178] = 0x9E1D, [22179] = 0x7069, [22180] = 0x706A, +- [22181] = 0x9EA4, [22182] = 0x9F7E, [22183] = 0x9F49, [22184] = 0x9F98, +- [22185] = 0x7881, [22186] = 0x92B9, [22187] = 0x88CF, [22188] = 0x58BB, +- [22189] = 0x6052, [22190] = 0x7CA7, [22191] = 0x5AFA, [22192] = 0x2554, +- [22193] = 0x2566, [22194] = 0x2557, [22195] = 0x2560, [22196] = 0x256C, +- [22197] = 0x2563, [22198] = 0x255A, [22199] = 0x2569, [22200] = 0x255D, +- [22201] = 0x2552, [22202] = 0x2564, [22203] = 0x2555, [22204] = 0x255E, +- [22205] = 0x256A, [22206] = 0x2561, [22207] = 0x2558, [22208] = 0x2567, +- [22209] = 0x255B, [22210] = 0x2553, [22211] = 0x2565, [22212] = 0x2556, +- [22213] = 0x255F, [22214] = 0x256B, [22215] = 0x2562, [22216] = 0x2559, +- [22217] = 0x2568, [22218] = 0x255C, [22219] = 0x2551, [22220] = 0x2550, +- [22221] = 0x256D, [22222] = 0x256E, [22223] = 0x2570, [22224] = 0x256F, +- [22225] = 0xFFED, [22230] = 0x20547, [22231] = 0x92DB, [22232] = 0x205DF, +- [22233] = 0xE003, [22234] = 0x854C, [22235] = 0x42B5, [22236] = 0x73EF, +- [22237] = 0x51B5, [22238] = 0x3649, [22239] = 0x24942, [22240] = 0x289E4, +- [22241] = 0x9344, [22242] = 0x219DB, [22243] = 0x82EE, [22244] = 0x23CC8, +- [22245] = 0x783C, [22246] = 0x6744, [22247] = 0x62DF, [22248] = 0x24933, +- [22249] = 0x289AA, [22250] = 0x202A0, [22251] = 0x26BB3, [22252] = 0x21305, +- [22253] = 0x4FAB, [22254] = 0xE018, [22255] = 0x5008, [22256] = 0x26D29, +- [22257] = 0xE01B, [22258] = 0x23600, [22259] = 0x24AB1, [22260] = 0x22513, +- [22262] = 0x2037E, [22263] = 0x5FA4, [22264] = 0x20380, [22265] = 0x20347, +- [22266] = 0x6EDB, [22267] = 0x2041F, [22269] = 0x5101, [22270] = 0x347A, +- [22271] = 0x510E, [22272] = 0x986C, [22273] = 0x3743, [22274] = 0x8416, +- [22275] = 0xE02D, [22276] = 0x20487, [22277] = 0x5160, [22278] = 0x233B4, +- [22279] = 0x516A, [22280] = 0x20BFF, [22281] = 0x220FC, [22282] = 0x202E5, +- [22283] = 0x22530, [22284] = 0x2058E, [22285] = 0x23233, [22286] = 0xE038, +- [22287] = 0x5B82, [22288] = 0x877D, [22289] = 0x205B3, [22290] = 0x23C99, +- [22291] = 0x51B2, [22292] = 0x51B8, [22327] = 0x9D34, [22328] = 0x51C9, +- [22329] = 0x51CF, [22330] = 0x51D1, [22331] = 0x3CDC, [22332] = 0x51D3, +- [22333] = 0x24AA6, [22334] = 0x51B3, [22335] = 0x51E2, [22336] = 0x5342, +- [22337] = 0x51ED, [22338] = 0x83CD, [22339] = 0x693E, [22340] = 0xE04C, +- [22341] = 0x5F7B, [22342] = 0x520B, [22343] = 0x5226, [22344] = 0x523C, +- [22345] = 0x52B5, [22346] = 0x5257, [22347] = 0x5294, [22348] = 0x52B9, +- [22349] = 0x52C5, [22350] = 0x7C15, [22351] = 0x8542, [22352] = 0x52E0, +- [22353] = 0x860D, [22354] = 0xE05A, [22356] = 0x28ADE, [22357] = 0x5549, +- [22358] = 0x6ED9, [22359] = 0x23F80, [22360] = 0x20954, [22361] = 0x23FEC, +- [22362] = 0x5333, [22364] = 0x20BE2, [22365] = 0x6CCB, [22366] = 0x21726, +- [22367] = 0x681B, [22368] = 0x73D5, [22369] = 0x604A, [22370] = 0x3EAA, +- [22371] = 0x38CC, [22372] = 0x216E8, [22373] = 0x71DD, [22374] = 0x44A2, +- [22375] = 0x536D, [22376] = 0x5374, [22377] = 0x286AB, [22378] = 0x537E, +- [22380] = 0x21596, [22381] = 0x21613, [22382] = 0x77E6, [22383] = 0x5393, +- [22384] = 0x28A9B, [22385] = 0x53A0, [22386] = 0x53AB, [22387] = 0x53AE, +- [22388] = 0x73A7, [22389] = 0x25772, [22390] = 0x3F59, [22391] = 0x739C, +- [22392] = 0x53C1, [22393] = 0x53C5, [22394] = 0x6C49, [22395] = 0x4E49, +- [22396] = 0x57FE, [22397] = 0x53D9, [22398] = 0x3AAB, [22399] = 0x20B8F, +- [22400] = 0x53E0, [22401] = 0x23FEB, [22402] = 0x22DA3, [22403] = 0x53F6, +- [22404] = 0x20C77, [22405] = 0x5413, [22406] = 0x7079, [22407] = 0x552B, +- [22408] = 0x6657, [22409] = 0x6D5B, [22410] = 0x546D, [22411] = 0x26B53, +- [22412] = 0xE094, [22413] = 0x555D, [22414] = 0x548F, [22415] = 0x54A4, +- [22416] = 0x47A6, [22417] = 0xE099, [22418] = 0xE09A, [22419] = 0x3DB4, +- [22420] = 0x20D4D, [22425] = 0x289BC, [22426] = 0x22698, [22427] = 0x5547, +- [22428] = 0x4CED, [22429] = 0x542F, [22430] = 0x7417, [22431] = 0x5586, +- [22432] = 0x55A9, [22434] = 0x218D7, [22435] = 0x2403A, [22436] = 0x4552, +- [22437] = 0x24435, [22438] = 0x66B3, [22439] = 0x210B4, [22440] = 0x5637, +- [22441] = 0x66CD, [22442] = 0x2328A, [22443] = 0x66A4, [22444] = 0x66AD, +- [22445] = 0x564D, [22446] = 0x564F, [22447] = 0x78F1, [22448] = 0x56F1, +- [22449] = 0x9787, [22450] = 0x53FE, [22451] = 0x5700, [22452] = 0x56EF, +- [22453] = 0x56ED, [22454] = 0x28B66, [22455] = 0x3623, [22456] = 0x2124F, +- [22457] = 0x5746, [22458] = 0x241A5, [22459] = 0x6C6E, [22460] = 0x708B, +- [22461] = 0x5742, [22462] = 0x36B1, [22463] = 0x26C7E, [22464] = 0x57E6, +- [22465] = 0xE0C5, [22466] = 0x5803, [22467] = 0x21454, [22468] = 0x24363, +- [22469] = 0x5826, [22470] = 0x24BF5, [22471] = 0x585C, [22472] = 0x58AA, +- [22473] = 0x3561, [22474] = 0x58E0, [22475] = 0x58DC, [22476] = 0xE0D0, +- [22477] = 0x58FB, [22478] = 0x5BFF, [22479] = 0x5743, [22480] = 0x2A150, +- [22481] = 0x24278, [22482] = 0x93D3, [22483] = 0x35A1, [22484] = 0x591F, +- [22485] = 0x68A6, [22486] = 0x36C3, [22487] = 0x6E59, [22522] = 0x2163E, +- [22523] = 0x5A24, [22524] = 0x5553, [22525] = 0x21692, [22526] = 0x8505, +- [22527] = 0x59C9, [22528] = 0x20D4E, [22529] = 0x26C81, [22530] = 0x26D2A, +- [22531] = 0x217DC, [22532] = 0x59D9, [22533] = 0x217FB, [22534] = 0x217B2, +- [22535] = 0x26DA6, [22536] = 0x6D71, [22537] = 0x21828, [22538] = 0x216D5, +- [22539] = 0x59F9, [22540] = 0x26E45, [22541] = 0x5AAB, [22542] = 0x5A63, +- [22543] = 0x36E6, [22544] = 0xE0F2, [22546] = 0x3708, [22547] = 0x5A96, +- [22548] = 0x7465, [22549] = 0x5AD3, [22550] = 0x26FA1, [22551] = 0xE0F9, +- [22552] = 0x3D85, [22553] = 0x21911, [22554] = 0x3732, [22555] = 0xE0FD, +- [22556] = 0x5E83, [22557] = 0x52D0, [22558] = 0x5B76, [22559] = 0x6588, +- [22560] = 0x5B7C, [22561] = 0x27A0E, [22562] = 0x4004, [22563] = 0x485D, +- [22564] = 0xE106, [22565] = 0x5BD5, [22566] = 0x6160, [22567] = 0xE109, +- [22568] = 0xE10A, [22569] = 0x205A5, [22570] = 0x5BF3, [22571] = 0x5B9D, +- [22572] = 0x4D10, [22573] = 0x5C05, [22574] = 0x21B44, [22575] = 0x5C13, +- [22576] = 0x73CE, [22577] = 0x5C14, [22578] = 0x21CA5, [22579] = 0x26B28, +- [22580] = 0x5C49, [22581] = 0x48DD, [22582] = 0x5C85, [22583] = 0x5CE9, +- [22584] = 0x5CEF, [22585] = 0x5D8B, [22586] = 0x21DF9, [22587] = 0x21E37, +- [22588] = 0x5D10, [22589] = 0x5D18, [22590] = 0x5D46, [22591] = 0x21EA4, +- [22592] = 0x5CBA, [22593] = 0x5DD7, [22594] = 0x82FC, [22595] = 0x382D, +- [22596] = 0x24901, [22597] = 0x22049, [22598] = 0x22173, [22599] = 0x8287, +- [22600] = 0x3836, [22601] = 0x3BC2, [22602] = 0x5E2E, [22603] = 0x6A8A, +- [22605] = 0x5E7A, [22606] = 0xE130, [22607] = 0x20CD3, [22608] = 0x53A6, +- [22609] = 0x4EB7, [22611] = 0x53A8, [22612] = 0x21771, [22613] = 0x5E09, +- [22614] = 0x5EF4, [22615] = 0x28482, [22620] = 0x5EF9, [22621] = 0x5EFB, +- [22622] = 0x38A0, [22623] = 0x5EFC, [22624] = 0x683E, [22625] = 0x941B, +- [22626] = 0x5F0D, [22627] = 0x201C1, [22628] = 0x2F894, [22629] = 0x3ADE, +- [22630] = 0x48AE, [22631] = 0x2133A, [22632] = 0x5F3A, [22633] = 0x26888, +- [22634] = 0x223D0, [22636] = 0x22471, [22637] = 0x5F63, [22638] = 0x97BD, +- [22639] = 0x26E6E, [22640] = 0x5F72, [22641] = 0x9340, [22642] = 0xE150, +- [22643] = 0x5FA7, [22644] = 0x5DB6, [22645] = 0x3D5F, [22646] = 0xE154, +- [22647] = 0x21F6A, [22648] = 0x270F8, [22649] = 0x22668, [22650] = 0x91D6, +- [22651] = 0x2029E, [22652] = 0x28A29, [22653] = 0x6031, [22654] = 0x6685, +- [22655] = 0xE15D, [22656] = 0x3963, [22657] = 0x3DC7, [22658] = 0x3639, +- [22659] = 0x5790, [22660] = 0x227B4, [22661] = 0x7971, [22662] = 0x3E40, +- [22663] = 0x609E, [22665] = 0x60B3, [22666] = 0xE168, [22667] = 0x2498F, +- [22668] = 0xE16A, [22669] = 0x74A4, [22670] = 0x50E1, [22671] = 0x5AA0, +- [22672] = 0x6164, [22673] = 0x8424, [22674] = 0x6142, [22675] = 0xE171, +- [22676] = 0x26ED2, [22677] = 0x6181, [22678] = 0x51F4, [22679] = 0xE175, +- [22680] = 0x6187, [22681] = 0x5BAA, [22682] = 0x23FB7, [22717] = 0x2285F, +- [22718] = 0x61D3, [22719] = 0x28B9D, [22720] = 0x2995D, [22721] = 0x61D0, +- [22722] = 0x3932, [22723] = 0x22980, [22724] = 0x228C1, [22725] = 0x6023, +- [22726] = 0x615C, [22727] = 0x651E, [22728] = 0x638B, [22729] = 0x20118, +- [22730] = 0x62C5, [22731] = 0x21770, [22732] = 0x62D5, [22733] = 0x22E0D, +- [22734] = 0x636C, [22735] = 0x249DF, [22736] = 0x3A17, [22737] = 0x6438, +- [22738] = 0x63F8, [22739] = 0xE18F, [22740] = 0x217FC, [22742] = 0x6F8A, +- [22743] = 0x22E36, [22744] = 0x9814, [22745] = 0x2408C, [22746] = 0x2571D, +- [22747] = 0x64E1, [22748] = 0x64E5, [22749] = 0x947B, [22750] = 0x3A66, +- [22751] = 0x643A, [22752] = 0x3A57, [22753] = 0x654D, [22754] = 0x6F16, +- [22755] = 0x24A28, [22756] = 0x24A23, [22757] = 0x6585, [22758] = 0x656D, +- [22759] = 0x655F, [22760] = 0x2307E, [22761] = 0x65B5, [22762] = 0x24940, +- [22763] = 0x4B37, [22764] = 0x65D1, [22765] = 0x40D8, [22766] = 0x21829, +- [22767] = 0x65E0, [22768] = 0x65E3, [22769] = 0x5FDF, [22770] = 0x23400, +- [22771] = 0x6618, [22772] = 0x231F7, [22773] = 0x231F8, [22774] = 0x6644, +- [22775] = 0x231A4, [22776] = 0x231A5, [22777] = 0x664B, [22778] = 0x20E75, +- [22779] = 0x6667, [22780] = 0x251E6, [22781] = 0x6673, [22783] = 0xE1BB, +- [22784] = 0x23231, [22785] = 0x285F4, [22786] = 0x231C8, [22787] = 0x25313, +- [22788] = 0x77C5, [22789] = 0x228F7, [22790] = 0x99A4, [22791] = 0x6702, +- [22792] = 0x2439C, [22793] = 0x24A21, [22794] = 0x3B2B, [22795] = 0x69FA, +- [22796] = 0x237C2, [22798] = 0x6767, [22799] = 0x6762, [22800] = 0xE1CC, +- [22801] = 0xE1CD, [22802] = 0x67D7, [22803] = 0x44E9, [22804] = 0x6822, +- [22805] = 0x6E50, [22806] = 0x923C, [22807] = 0x6801, [22808] = 0x233E6, +- [22809] = 0x26DA0, [22810] = 0x685D, [22815] = 0xE1D7, [22816] = 0x69E1, +- [22817] = 0x6A0B, [22818] = 0x28ADF, [22819] = 0x6973, [22820] = 0x68C3, +- [22821] = 0x235CD, [22822] = 0x6901, [22823] = 0x6900, [22824] = 0x3D32, +- [22825] = 0x3A01, [22826] = 0x2363C, [22827] = 0x3B80, [22828] = 0x67AC, +- [22829] = 0x6961, [22830] = 0x28A4A, [22831] = 0x42FC, [22832] = 0x6936, +- [22833] = 0x6998, [22834] = 0x3BA1, [22835] = 0x203C9, [22836] = 0x8363, +- [22837] = 0x5090, [22838] = 0x69F9, [22839] = 0xE1EF, [22840] = 0x2212A, +- [22841] = 0x6A45, [22842] = 0xE1F2, [22843] = 0x6A9D, [22844] = 0x3BF3, +- [22845] = 0x67B1, [22846] = 0x6AC8, [22847] = 0x2919C, [22848] = 0x3C0D, +- [22849] = 0x6B1D, [22850] = 0xE1FA, [22851] = 0x60DE, [22852] = 0x6B35, +- [22853] = 0x6B74, [22854] = 0xE1FE, [22855] = 0x6EB5, [22856] = 0x23ADB, +- [22857] = 0x203B5, [22858] = 0xE202, [22859] = 0x3740, [22860] = 0x5421, +- [22861] = 0x23B5A, [22862] = 0x6BE1, [22863] = 0x23EFC, [22864] = 0x6BDC, +- [22865] = 0x6C37, [22866] = 0x2248B, [22867] = 0xE20B, [22868] = 0x26B51, +- [22869] = 0x6C5A, [22870] = 0x8226, [22871] = 0x6C79, [22872] = 0x23DBC, +- [22873] = 0x44C5, [22874] = 0x23DBD, [22875] = 0x241A4, [22876] = 0x2490C, +- [22877] = 0x24900, [22912] = 0x23CC9, [22913] = 0x36E5, [22914] = 0x3CEB, +- [22915] = 0xE219, [22916] = 0x9B83, [22917] = 0x231F9, [22918] = 0xE21C, +- [22919] = 0x7F8F, [22920] = 0x6837, [22921] = 0x26D25, [22922] = 0x26DA1, +- [22923] = 0x26DEB, [22924] = 0x6D96, [22925] = 0x6D5C, [22926] = 0x6E7C, +- [22927] = 0x6F04, [22928] = 0x2497F, [22929] = 0xE227, [22930] = 0x26E72, +- [22931] = 0x8533, [22932] = 0x26F74, [22933] = 0x51C7, [22936] = 0x842E, +- [22937] = 0x28B21, [22939] = 0x23E2F, [22940] = 0x7453, [22941] = 0x23F82, +- [22942] = 0x79CC, [22943] = 0x6E4F, [22944] = 0x5A91, [22945] = 0x2304B, +- [22946] = 0x6FF8, [22947] = 0x370D, [22948] = 0x6F9D, [22949] = 0x23E30, +- [22950] = 0x6EFA, [22951] = 0x21497, [22952] = 0x2403D, [22953] = 0x4555, +- [22954] = 0x93F0, [22955] = 0x6F44, [22956] = 0x6F5C, [22957] = 0x3D4E, +- [22958] = 0x6F74, [22959] = 0xE245, [22960] = 0x3D3B, [22961] = 0x6F9F, +- [22962] = 0x24144, [22963] = 0x6FD3, [22964] = 0xE24A, [22965] = 0x24155, +- [22966] = 0x24039, [22967] = 0x25D20, [22968] = 0xE24E, [22969] = 0x2413F, +- [22970] = 0x51DF, [22971] = 0x24156, [22972] = 0x24157, [22973] = 0x24140, +- [22974] = 0x261DD, [22975] = 0x704B, [22976] = 0x707E, [22977] = 0x70A7, +- [22978] = 0x7081, [22979] = 0x70CC, [22980] = 0x70D5, [22981] = 0x70D6, +- [22982] = 0x70DF, [22983] = 0x4104, [22984] = 0x3DE8, [22985] = 0x71B4, +- [22986] = 0x7196, [22987] = 0x24277, [22988] = 0x712B, [22989] = 0x7145, +- [22990] = 0x5A88, [22991] = 0x714A, [22993] = 0x5C9C, [22994] = 0x24365, +- [22995] = 0x714F, [22996] = 0x9362, [22997] = 0xE26B, [22998] = 0x712C, +- [22999] = 0x2445A, [23000] = 0x24A27, [23001] = 0x24A22, [23002] = 0x71BA, +- [23003] = 0x28BE8, [23004] = 0x70BD, [23005] = 0x720E, [23010] = 0x9442, +- [23011] = 0x7215, [23012] = 0x5911, [23013] = 0x9443, [23014] = 0x7224, +- [23015] = 0x9341, [23016] = 0xE27A, [23017] = 0x722E, [23018] = 0x7240, +- [23019] = 0x24974, [23020] = 0x68BD, [23021] = 0x7255, [23022] = 0x7257, +- [23023] = 0x3E55, [23024] = 0xE282, [23025] = 0x680D, [23026] = 0x6F3D, +- [23027] = 0x7282, [23029] = 0x732B, [23030] = 0x24823, [23031] = 0x2882B, +- [23032] = 0x48ED, [23033] = 0x28804, [23034] = 0x7328, [23035] = 0x732E, +- [23036] = 0x73CF, [23037] = 0x73AA, [23038] = 0xE290, [23039] = 0x26A2E, +- [23040] = 0x73C9, [23041] = 0x7449, [23042] = 0x241E2, [23043] = 0x216E7, +- [23044] = 0x24A24, [23045] = 0x6623, [23046] = 0x36C5, [23047] = 0x249B7, +- [23048] = 0x2498D, [23049] = 0xE29B, [23050] = 0x73F7, [23051] = 0x7415, +- [23052] = 0x6903, [23053] = 0x24A26, [23054] = 0x7439, [23055] = 0xE2A1, +- [23056] = 0x3ED7, [23058] = 0x228AD, [23059] = 0x7460, [23060] = 0x28EB2, +- [23061] = 0x7447, [23062] = 0x73E4, [23063] = 0x7476, [23064] = 0x83B9, +- [23065] = 0x746C, [23066] = 0x3730, [23067] = 0x7474, [23068] = 0x93F1, +- [23069] = 0x6A2C, [23070] = 0x7482, [23071] = 0x4953, [23072] = 0xE2B2, +- [23107] = 0x2415F, [23108] = 0x24A79, [23109] = 0x28B8F, [23110] = 0x5B46, +- [23111] = 0xE2B7, [23112] = 0x2189E, [23113] = 0x74C8, [23114] = 0x21988, +- [23115] = 0x750E, [23117] = 0x751E, [23118] = 0x28ED9, [23119] = 0x21A4B, +- [23120] = 0x5BD7, [23121] = 0xE2C1, [23122] = 0x9385, [23123] = 0x754D, +- [23124] = 0x754A, [23125] = 0x7567, [23126] = 0x756E, [23127] = 0x24F82, +- [23128] = 0x3F04, [23129] = 0xE2C9, [23130] = 0x758E, [23131] = 0x745D, +- [23132] = 0x759E, [23133] = 0x75B4, [23134] = 0x7602, [23135] = 0x762C, +- [23136] = 0x7651, [23137] = 0x764F, [23138] = 0x766F, [23139] = 0x7676, +- [23140] = 0xE2D4, [23141] = 0x7690, [23142] = 0x81EF, [23143] = 0x37F8, +- [23144] = 0x26911, [23145] = 0x2690E, [23146] = 0x76A1, [23147] = 0x76A5, +- [23148] = 0x76B7, [23149] = 0x76CC, [23150] = 0x26F9F, [23151] = 0x8462, +- [23152] = 0x2509D, [23153] = 0x2517D, [23154] = 0xE2E2, [23155] = 0x771E, +- [23156] = 0x7726, [23157] = 0x7740, [23158] = 0x64AF, [23159] = 0x25220, +- [23160] = 0x7758, [23161] = 0x232AC, [23162] = 0x77AF, [23163] = 0xE2EB, +- [23164] = 0xE2EC, [23165] = 0x216C1, [23166] = 0x77F4, [23168] = 0xE2F0, +- [23169] = 0xE2F1, [23170] = 0x68CA, [23171] = 0x78AF, [23172] = 0x78C7, +- [23173] = 0x78D3, [23174] = 0x96A5, [23175] = 0x792E, [23176] = 0x255E0, +- [23177] = 0x78D7, [23178] = 0x7934, [23179] = 0x78B1, [23180] = 0x2760C, +- [23181] = 0x8FB8, [23182] = 0x8884, [23183] = 0x28B2B, [23184] = 0xE300, +- [23185] = 0x2261C, [23186] = 0x7986, [23187] = 0x8900, [23188] = 0x6902, +- [23189] = 0x7980, [23190] = 0x25857, [23191] = 0x799D, [23192] = 0x27B39, +- [23193] = 0x793C, [23194] = 0x79A9, [23195] = 0x6E2A, [23196] = 0x27126, +- [23197] = 0x3EA8, [23198] = 0x79C6, [23199] = 0x2910D, [23200] = 0x79D4 ++ [ 0] = 0x43F0, [ 1] = 0x4C32, [ 2] = 0x4603, [ 3] = 0x45A6, ++ [ 4] = 0x4578, [ 5] = 0x27267, [ 6] = 0x4D77, [ 7] = 0x45B3, ++ [ 8] = 0x27CB1, [ 9] = 0x4CE2, [ 10] = 0x27CC5, [ 11] = 0x3B95, ++ [ 12] = 0x4736, [ 13] = 0x4744, [ 14] = 0x4C47, [ 15] = 0x4C40, ++ [ 16] = 0x242BF, [ 17] = 0x23617, [ 18] = 0x27352, [ 19] = 0x26E8B, ++ [ 20] = 0x270D2, [ 21] = 0x4C57, [ 22] = 0x2A351, [ 23] = 0x474F, ++ [ 24] = 0x45DA, [ 25] = 0x4C85, [ 26] = 0x27C6C, [ 27] = 0x4D07, ++ [ 28] = 0x4AA4, [ 29] = 0x46A1, [ 30] = 0x26B23, [ 31] = 0x7225, ++ [ 32] = 0x25A54, [ 33] = 0x21A63, [ 34] = 0x23E06, [ 35] = 0x23F61, ++ [ 36] = 0x664D, [ 37] = 0x56FB, [ 39] = 0x7D95, [ 40] = 0x591D, ++ [ 41] = 0x28BB9, [ 42] = 0x3DF4, [ 43] = 0x9734, [ 44] = 0x27BEF, ++ [ 45] = 0x5BDB, [ 46] = 0x21D5E, [ 47] = 0x5AA4, [ 48] = 0x3625, ++ [ 49] = 0x29EB0, [ 50] = 0x5AD1, [ 51] = 0x5BB7, [ 52] = 0x5CFC, ++ [ 53] = 0x676E, [ 54] = 0x8593, [ 55] = 0x29945, [ 56] = 0x7461, ++ [ 57] = 0x749D, [ 58] = 0x3875, [ 59] = 0x21D53, [ 60] = 0x2369E, ++ [ 61] = 0x26021, [ 62] = 0x3EEC, [ 97] = 0x258DE, [ 98] = 0x3AF5, ++ [ 99] = 0x7AFC, [ 100] = 0x9F97, [ 101] = 0x24161, [ 102] = 0x2890D, ++ [ 103] = 0x231EA, [ 104] = 0x20A8A, [ 105] = 0x2325E, [ 106] = 0x430A, ++ [ 107] = 0x8484, [ 108] = 0x9F96, [ 109] = 0x942F, [ 110] = 0x4930, ++ [ 111] = 0x8613, [ 112] = 0x5896, [ 113] = 0x974A, [ 114] = 0x9218, ++ [ 115] = 0x79D0, [ 116] = 0x7A32, [ 117] = 0x6660, [ 118] = 0x6A29, ++ [ 119] = 0x889D, [ 120] = 0x744C, [ 121] = 0x7BC5, [ 122] = 0x6782, ++ [ 123] = 0x7A2C, [ 124] = 0x524F, [ 125] = 0x9046, [ 126] = 0x34E6, ++ [ 127] = 0x73C4, [ 128] = 0x25DB9, [ 129] = 0x74C6, [ 130] = 0x9FC7, ++ [ 131] = 0x57B3, [ 132] = 0x492F, [ 133] = 0x544C, [ 134] = 0x4131, ++ [ 135] = 0x2368E, [ 136] = 0x5818, [ 137] = 0x7A72, [ 138] = 0x27B65, ++ [ 139] = 0x8B8F, [ 140] = 0x46AE, [ 141] = 0x26E88, [ 142] = 0x4181, ++ [ 143] = 0x25D99, [ 144] = 0x7BAE, [ 145] = 0x224BC, [ 146] = 0x9FC8, ++ [ 147] = 0x224C1, [ 148] = 0x224C9, [ 149] = 0x224CC, [ 150] = 0x9FC9, ++ [ 151] = 0x8504, [ 152] = 0x235BB, [ 153] = 0x40B4, [ 154] = 0x9FCA, ++ [ 155] = 0x44E1, [ 156] = 0x2ADFF, [ 157] = 0x62C1, [ 158] = 0x706E, ++ [ 159] = 0x9FCB, [ 195] = 0x31C0, [ 196] = 0x31C1, [ 197] = 0x31C2, ++ [ 198] = 0x31C3, [ 199] = 0x31C4, [ 200] = 0x2010C, [ 201] = 0x31C5, ++ [ 202] = 0x200D1, [ 203] = 0x200CD, [ 204] = 0x31C6, [ 205] = 0x31C7, ++ [ 206] = 0x200CB, [ 207] = 0x21FE8, [ 208] = 0x31C8, [ 209] = 0x200CA, ++ [ 210] = 0x31C9, [ 211] = 0x31CA, [ 212] = 0x31CB, [ 213] = 0x31CC, ++ [ 214] = 0x2010E, [ 215] = 0x31CD, [ 216] = 0x31CE, [ 217] = 0x0100, ++ [ 218] = 0x00C1, [ 219] = 0x01CD, [ 220] = 0x00C0, [ 221] = 0x0112, ++ [ 222] = 0x00C9, [ 223] = 0x011A, [ 224] = 0x00C8, [ 225] = 0x014C, ++ [ 226] = 0x00D3, [ 227] = 0x01D1, [ 228] = 0x00D2, [ 230] = 0x1EBE, ++ [ 232] = 0x1EC0, [ 233] = 0x00CA, [ 234] = 0x0101, [ 235] = 0x00E1, ++ [ 236] = 0x01CE, [ 237] = 0x00E0, [ 238] = 0x0251, [ 239] = 0x0113, ++ [ 240] = 0x00E9, [ 241] = 0x011B, [ 242] = 0x00E8, [ 243] = 0x012B, ++ [ 244] = 0x00ED, [ 245] = 0x01D0, [ 246] = 0x00EC, [ 247] = 0x014D, ++ [ 248] = 0x00F3, [ 249] = 0x01D2, [ 250] = 0x00F2, [ 251] = 0x016B, ++ [ 252] = 0x00FA, [ 253] = 0x01D4, [ 254] = 0x00F9, [ 255] = 0x01D6, ++ [ 256] = 0x01D8, [ 257] = 0x01DA, [ 292] = 0x01DC, [ 293] = 0x00FC, ++ [ 295] = 0x1EBF, [ 297] = 0x1EC1, [ 298] = 0x00EA, [ 299] = 0x0261, ++ [ 300] = 0x23DA, [ 301] = 0x23DB, [ 390] = 0x2A3A9, [ 391] = 0x21145, ++ [ 393] = 0x650A, [ 396] = 0x4E3D, [ 397] = 0x6EDD, [ 398] = 0x9D4E, ++ [ 399] = 0x91DF, [ 402] = 0x27735, [ 403] = 0x6491, [ 404] = 0x4F1A, ++ [ 405] = 0x4F28, [ 406] = 0x4FA8, [ 407] = 0x5156, [ 408] = 0x5174, ++ [ 409] = 0x519C, [ 410] = 0x51E4, [ 411] = 0x52A1, [ 412] = 0x52A8, ++ [ 413] = 0x533B, [ 414] = 0x534E, [ 415] = 0x53D1, [ 416] = 0x53D8, ++ [ 417] = 0x56E2, [ 418] = 0x58F0, [ 419] = 0x5904, [ 420] = 0x5907, ++ [ 421] = 0x5932, [ 422] = 0x5934, [ 423] = 0x5B66, [ 424] = 0x5B9E, ++ [ 425] = 0x5B9F, [ 426] = 0x5C9A, [ 427] = 0x5E86, [ 428] = 0x603B, ++ [ 429] = 0x6589, [ 430] = 0x67FE, [ 431] = 0x6804, [ 432] = 0x6865, ++ [ 433] = 0x6D4E, [ 434] = 0x70BC, [ 435] = 0x7535, [ 436] = 0x7EA4, ++ [ 437] = 0x7EAC, [ 438] = 0x7EBA, [ 439] = 0x7EC7, [ 440] = 0x7ECF, ++ [ 441] = 0x7EDF, [ 442] = 0x7F06, [ 443] = 0x7F37, [ 444] = 0x827A, ++ [ 445] = 0x82CF, [ 446] = 0x836F, [ 447] = 0x89C6, [ 448] = 0x8BBE, ++ [ 449] = 0x8BE2, [ 450] = 0x8F66, [ 451] = 0x8F67, [ 452] = 0x8F6E, ++ [ 487] = 0x7411, [ 488] = 0x7CFC, [ 489] = 0x7DCD, [ 490] = 0x6946, ++ [ 491] = 0x7AC9, [ 492] = 0x5227, [ 497] = 0x918C, [ 498] = 0x78B8, ++ [ 499] = 0x915E, [ 500] = 0x80BC, [ 502] = 0x8D0B, [ 503] = 0x80F6, ++ [ 504] = 0x209E7, [ 507] = 0x809F, [ 508] = 0x9EC7, [ 509] = 0x4CCD, ++ [ 510] = 0x9DC9, [ 511] = 0x9E0C, [ 512] = 0x4C3E, [ 513] = 0x29DF6, ++ [ 514] = 0x2700E, [ 515] = 0x9E0A, [ 516] = 0x2A133, [ 517] = 0x35C1, ++ [ 519] = 0x6E9A, [ 520] = 0x823E, [ 521] = 0x7519, [ 523] = 0x4911, ++ [ 524] = 0x9A6C, [ 525] = 0x9A8F, [ 526] = 0x9F99, [ 527] = 0x7987, ++ [ 528] = 0x2846C, [ 529] = 0x21DCA, [ 530] = 0x205D0, [ 531] = 0x22AE6, ++ [ 532] = 0x4E24, [ 533] = 0x4E81, [ 534] = 0x4E80, [ 535] = 0x4E87, ++ [ 536] = 0x4EBF, [ 537] = 0x4EEB, [ 538] = 0x4F37, [ 539] = 0x344C, ++ [ 540] = 0x4FBD, [ 541] = 0x3E48, [ 542] = 0x5003, [ 543] = 0x5088, ++ [ 544] = 0x347D, [ 545] = 0x3493, [ 546] = 0x34A5, [ 547] = 0x5186, ++ [ 548] = 0x5905, [ 549] = 0x51DB, [ 550] = 0x51FC, [ 551] = 0x5205, ++ [ 552] = 0x4E89, [ 553] = 0x5279, [ 554] = 0x5290, [ 555] = 0x5327, ++ [ 556] = 0x35C7, [ 557] = 0x53A9, [ 558] = 0x3551, [ 559] = 0x53B0, ++ [ 560] = 0x3553, [ 561] = 0x53C2, [ 562] = 0x5423, [ 563] = 0x356D, ++ [ 564] = 0x3572, [ 565] = 0x3681, [ 566] = 0x5493, [ 567] = 0x54A3, ++ [ 568] = 0x54B4, [ 569] = 0x54B9, [ 570] = 0x54D0, [ 571] = 0x54EF, ++ [ 572] = 0x5518, [ 573] = 0x5523, [ 574] = 0x5528, [ 575] = 0x3598, ++ [ 576] = 0x553F, [ 577] = 0x35A5, [ 578] = 0x35BF, [ 579] = 0x55D7, ++ [ 580] = 0x35C5, [ 585] = 0x27D84, [ 586] = 0x5525, [ 588] = 0x20C42, ++ [ 589] = 0x20D15, [ 590] = 0x2512B, [ 591] = 0x5590, [ 592] = 0x22CC6, ++ [ 593] = 0x39EC, [ 594] = 0x20341, [ 595] = 0x8E46, [ 596] = 0x24DB8, ++ [ 597] = 0x294E5, [ 598] = 0x4053, [ 599] = 0x280BE, [ 600] = 0x777A, ++ [ 601] = 0x22C38, [ 602] = 0x3A34, [ 603] = 0x47D5, [ 604] = 0x2815D, ++ [ 605] = 0x269F2, [ 606] = 0x24DEA, [ 607] = 0x64DD, [ 608] = 0x20D7C, ++ [ 609] = 0x20FB4, [ 610] = 0x20CD5, [ 611] = 0x210F4, [ 612] = 0x648D, ++ [ 613] = 0x8E7E, [ 614] = 0x20E96, [ 615] = 0x20C0B, [ 616] = 0x20F64, ++ [ 617] = 0x22CA9, [ 618] = 0x28256, [ 619] = 0x244D3, [ 621] = 0x20D46, ++ [ 622] = 0x29A4D, [ 623] = 0x280E9, [ 624] = 0x47F4, [ 625] = 0x24EA7, ++ [ 626] = 0x22CC2, [ 627] = 0x9AB2, [ 628] = 0x3A67, [ 629] = 0x295F4, ++ [ 630] = 0x3FED, [ 631] = 0x3506, [ 632] = 0x252C7, [ 633] = 0x297D4, ++ [ 634] = 0x278C8, [ 635] = 0x22D44, [ 636] = 0x9D6E, [ 637] = 0x9815, ++ [ 639] = 0x43D9, [ 640] = 0x260A5, [ 641] = 0x64B4, [ 642] = 0x54E3, ++ [ 643] = 0x22D4C, [ 644] = 0x22BCA, [ 645] = 0x21077, [ 646] = 0x39FB, ++ [ 647] = 0x2106F, [ 682] = 0x266DA, [ 683] = 0x26716, [ 684] = 0x279A0, ++ [ 685] = 0x64EA, [ 686] = 0x25052, [ 687] = 0x20C43, [ 688] = 0x8E68, ++ [ 689] = 0x221A1, [ 690] = 0x28B4C, [ 691] = 0x20731, [ 693] = 0x480B, ++ [ 694] = 0x201A9, [ 695] = 0x3FFA, [ 696] = 0x5873, [ 697] = 0x22D8D, ++ [ 699] = 0x245C8, [ 700] = 0x204FC, [ 701] = 0x26097, [ 702] = 0x20F4C, ++ [ 703] = 0x20D96, [ 704] = 0x5579, [ 705] = 0x40BB, [ 706] = 0x43BA, ++ [ 708] = 0x4AB4, [ 709] = 0x22A66, [ 710] = 0x2109D, [ 711] = 0x81AA, ++ [ 712] = 0x98F5, [ 713] = 0x20D9C, [ 714] = 0x6379, [ 715] = 0x39FE, ++ [ 716] = 0x22775, [ 717] = 0x8DC0, [ 718] = 0x56A1, [ 719] = 0x647C, ++ [ 720] = 0x3E43, [ 722] = 0x2A601, [ 723] = 0x20E09, [ 724] = 0x22ACF, ++ [ 725] = 0x22CC9, [ 727] = 0x210C8, [ 728] = 0x239C2, [ 729] = 0x3992, ++ [ 730] = 0x3A06, [ 731] = 0x2829B, [ 732] = 0x3578, [ 733] = 0x25E49, ++ [ 734] = 0x220C7, [ 735] = 0x5652, [ 736] = 0x20F31, [ 737] = 0x22CB2, ++ [ 738] = 0x29720, [ 739] = 0x34BC, [ 740] = 0x6C3D, [ 741] = 0x24E3B, ++ [ 744] = 0x27574, [ 745] = 0x22E8B, [ 746] = 0x22208, [ 747] = 0x2A65B, ++ [ 748] = 0x28CCD, [ 749] = 0x20E7A, [ 750] = 0x20C34, [ 751] = 0x2681C, ++ [ 752] = 0x7F93, [ 753] = 0x210CF, [ 754] = 0x22803, [ 755] = 0x22939, ++ [ 756] = 0x35FB, [ 757] = 0x251E3, [ 758] = 0x20E8C, [ 759] = 0x20F8D, ++ [ 760] = 0x20EAA, [ 761] = 0x3F93, [ 762] = 0x20F30, [ 763] = 0x20D47, ++ [ 764] = 0x2114F, [ 765] = 0x20E4C, [ 767] = 0x20EAB, [ 768] = 0x20BA9, ++ [ 769] = 0x20D48, [ 770] = 0x210C0, [ 771] = 0x2113D, [ 772] = 0x3FF9, ++ [ 773] = 0x22696, [ 774] = 0x6432, [ 775] = 0x20FAD, [ 780] = 0x233F4, ++ [ 781] = 0x27639, [ 782] = 0x22BCE, [ 783] = 0x20D7E, [ 784] = 0x20D7F, ++ [ 785] = 0x22C51, [ 786] = 0x22C55, [ 787] = 0x3A18, [ 788] = 0x20E98, ++ [ 789] = 0x210C7, [ 790] = 0x20F2E, [ 791] = 0x2A632, [ 792] = 0x26B50, ++ [ 793] = 0x28CD2, [ 794] = 0x28D99, [ 795] = 0x28CCA, [ 796] = 0x95AA, ++ [ 797] = 0x54CC, [ 798] = 0x82C4, [ 799] = 0x55B9, [ 801] = 0x29EC3, ++ [ 802] = 0x9C26, [ 803] = 0x9AB6, [ 804] = 0x2775E, [ 805] = 0x22DEE, ++ [ 806] = 0x7140, [ 807] = 0x816D, [ 808] = 0x80EC, [ 809] = 0x5C1C, ++ [ 810] = 0x26572, [ 811] = 0x8134, [ 812] = 0x3797, [ 813] = 0x535F, ++ [ 814] = 0x280BD, [ 815] = 0x91B6, [ 816] = 0x20EFA, [ 817] = 0x20E0F, ++ [ 818] = 0x20E77, [ 819] = 0x20EFB, [ 820] = 0x35DD, [ 821] = 0x24DEB, ++ [ 822] = 0x3609, [ 823] = 0x20CD6, [ 824] = 0x56AF, [ 825] = 0x227B5, ++ [ 826] = 0x210C9, [ 827] = 0x20E10, [ 828] = 0x20E78, [ 829] = 0x21078, ++ [ 830] = 0x21148, [ 831] = 0x28207, [ 832] = 0x21455, [ 833] = 0x20E79, ++ [ 834] = 0x24E50, [ 835] = 0x22DA4, [ 836] = 0x5A54, [ 837] = 0x2101D, ++ [ 838] = 0x2101E, [ 839] = 0x210F5, [ 840] = 0x210F6, [ 841] = 0x579C, ++ [ 842] = 0x20E11, [ 877] = 0x27694, [ 878] = 0x282CD, [ 879] = 0x20FB5, ++ [ 880] = 0x20E7B, [ 881] = 0x2517E, [ 882] = 0x3703, [ 883] = 0x20FB6, ++ [ 884] = 0x21180, [ 885] = 0x252D8, [ 886] = 0x2A2BD, [ 887] = 0x249DA, ++ [ 888] = 0x2183A, [ 889] = 0x24177, [ 890] = 0x2827C, [ 891] = 0x5899, ++ [ 892] = 0x5268, [ 893] = 0x361A, [ 894] = 0x2573D, [ 895] = 0x7BB2, ++ [ 896] = 0x5B68, [ 897] = 0x4800, [ 898] = 0x4B2C, [ 899] = 0x9F27, ++ [ 900] = 0x49E7, [ 901] = 0x9C1F, [ 902] = 0x9B8D, [ 903] = 0x25B74, ++ [ 904] = 0x2313D, [ 905] = 0x55FB, [ 906] = 0x35F2, [ 907] = 0x5689, ++ [ 908] = 0x4E28, [ 909] = 0x5902, [ 910] = 0x21BC1, [ 911] = 0x2F878, ++ [ 912] = 0x9751, [ 913] = 0x20086, [ 914] = 0x4E5B, [ 915] = 0x4EBB, ++ [ 916] = 0x353E, [ 917] = 0x5C23, [ 918] = 0x5F51, [ 919] = 0x5FC4, ++ [ 920] = 0x38FA, [ 921] = 0x624C, [ 922] = 0x6535, [ 923] = 0x6B7A, ++ [ 924] = 0x6C35, [ 925] = 0x6C3A, [ 926] = 0x706C, [ 927] = 0x722B, ++ [ 928] = 0x4E2C, [ 929] = 0x72AD, [ 930] = 0x248E9, [ 931] = 0x7F52, ++ [ 932] = 0x793B, [ 933] = 0x7CF9, [ 934] = 0x7F53, [ 935] = 0x2626A, ++ [ 936] = 0x34C1, [ 938] = 0x2634B, [ 939] = 0x8002, [ 940] = 0x8080, ++ [ 941] = 0x26612, [ 942] = 0x26951, [ 943] = 0x535D, [ 944] = 0x8864, ++ [ 945] = 0x89C1, [ 946] = 0x278B2, [ 947] = 0x8BA0, [ 948] = 0x8D1D, ++ [ 949] = 0x9485, [ 950] = 0x9578, [ 951] = 0x957F, [ 952] = 0x95E8, ++ [ 953] = 0x28E0F, [ 954] = 0x97E6, [ 955] = 0x9875, [ 956] = 0x98CE, ++ [ 957] = 0x98DE, [ 958] = 0x9963, [ 959] = 0x29810, [ 960] = 0x9C7C, ++ [ 961] = 0x9E1F, [ 962] = 0x9EC4, [ 963] = 0x6B6F, [ 964] = 0xF907, ++ [ 965] = 0x4E37, [ 966] = 0x20087, [ 967] = 0x961D, [ 968] = 0x6237, ++ [ 969] = 0x94A2, [ 975] = 0x503B, [ 976] = 0x6DFE, [ 977] = 0x29C73, ++ [ 978] = 0x9FA6, [ 979] = 0x3DC9, [ 980] = 0x888F, [ 981] = 0x2414E, ++ [ 982] = 0x7077, [ 983] = 0x5CF5, [ 984] = 0x4B20, [ 985] = 0x251CD, ++ [ 986] = 0x3559, [ 987] = 0x25D30, [ 988] = 0x6122, [ 989] = 0x28A32, ++ [ 990] = 0x8FA7, [ 991] = 0x91F6, [ 992] = 0x7191, [ 993] = 0x6719, ++ [ 994] = 0x73BA, [ 995] = 0x23281, [ 996] = 0x2A107, [ 997] = 0x3C8B, ++ [ 998] = 0x21980, [ 999] = 0x4B10, [ 1000] = 0x78E4, [ 1001] = 0x7402, ++ [ 1002] = 0x51AE, [ 1003] = 0x2870F, [ 1004] = 0x4009, [ 1005] = 0x6A63, ++ [ 1006] = 0x2A2BA, [ 1007] = 0x4223, [ 1008] = 0x860F, [ 1009] = 0x20A6F, ++ [ 1010] = 0x7A2A, [ 1011] = 0x29947, [ 1012] = 0x28AEA, [ 1013] = 0x9755, ++ [ 1014] = 0x704D, [ 1015] = 0x5324, [ 1016] = 0x2207E, [ 1017] = 0x93F4, ++ [ 1018] = 0x76D9, [ 1019] = 0x289E3, [ 1020] = 0x9FA7, [ 1021] = 0x77DD, ++ [ 1022] = 0x4EA3, [ 1023] = 0x4FF0, [ 1024] = 0x50BC, [ 1025] = 0x4E2F, ++ [ 1026] = 0x4F17, [ 1027] = 0x9FA8, [ 1028] = 0x5434, [ 1029] = 0x7D8B, ++ [ 1030] = 0x5892, [ 1031] = 0x58D0, [ 1032] = 0x21DB6, [ 1033] = 0x5E92, ++ [ 1034] = 0x5E99, [ 1035] = 0x5FC2, [ 1036] = 0x22712, [ 1037] = 0x658B, ++ [ 1072] = 0x233F9, [ 1073] = 0x6919, [ 1074] = 0x6A43, [ 1075] = 0x23C63, ++ [ 1076] = 0x6CFF, [ 1078] = 0x7200, [ 1079] = 0x24505, [ 1080] = 0x738C, ++ [ 1081] = 0x3EDB, [ 1082] = 0x24A13, [ 1083] = 0x5B15, [ 1084] = 0x74B9, ++ [ 1085] = 0x8B83, [ 1086] = 0x25CA4, [ 1087] = 0x25695, [ 1088] = 0x7A93, ++ [ 1089] = 0x7BEC, [ 1090] = 0x7CC3, [ 1091] = 0x7E6C, [ 1092] = 0x82F8, ++ [ 1093] = 0x8597, [ 1094] = 0x9FA9, [ 1095] = 0x8890, [ 1096] = 0x9FAA, ++ [ 1097] = 0x8EB9, [ 1098] = 0x9FAB, [ 1099] = 0x8FCF, [ 1100] = 0x855F, ++ [ 1101] = 0x99E0, [ 1102] = 0x9221, [ 1103] = 0x9FAC, [ 1104] = 0x28DB9, ++ [ 1105] = 0x2143F, [ 1106] = 0x4071, [ 1107] = 0x42A2, [ 1108] = 0x5A1A, ++ [ 1112] = 0x9868, [ 1113] = 0x676B, [ 1114] = 0x4276, [ 1115] = 0x573D, ++ [ 1117] = 0x85D6, [ 1118] = 0x2497B, [ 1119] = 0x82BF, [ 1120] = 0x2710D, ++ [ 1121] = 0x4C81, [ 1122] = 0x26D74, [ 1123] = 0x5D7B, [ 1124] = 0x26B15, ++ [ 1125] = 0x26FBE, [ 1126] = 0x9FAD, [ 1127] = 0x9FAE, [ 1128] = 0x5B96, ++ [ 1129] = 0x9FAF, [ 1130] = 0x66E7, [ 1131] = 0x7E5B, [ 1132] = 0x6E57, ++ [ 1133] = 0x79CA, [ 1134] = 0x3D88, [ 1135] = 0x44C3, [ 1136] = 0x23256, ++ [ 1137] = 0x22796, [ 1138] = 0x439A, [ 1139] = 0x4536, [ 1141] = 0x5CD5, ++ [ 1142] = 0x23B1A, [ 1143] = 0x8AF9, [ 1144] = 0x5C78, [ 1145] = 0x3D12, ++ [ 1146] = 0x23551, [ 1147] = 0x5D78, [ 1148] = 0x9FB2, [ 1149] = 0x7157, ++ [ 1150] = 0x4558, [ 1151] = 0x240EC, [ 1152] = 0x21E23, [ 1153] = 0x4C77, ++ [ 1154] = 0x3978, [ 1155] = 0x344A, [ 1156] = 0x201A4, [ 1157] = 0x26C41, ++ [ 1158] = 0x8ACC, [ 1159] = 0x4FB4, [ 1160] = 0x20239, [ 1161] = 0x59BF, ++ [ 1162] = 0x816C, [ 1163] = 0x9856, [ 1164] = 0x298FA, [ 1165] = 0x5F3B, ++ [ 1170] = 0x20B9F, [ 1172] = 0x221C1, [ 1173] = 0x2896D, [ 1174] = 0x4102, ++ [ 1175] = 0x46BB, [ 1176] = 0x29079, [ 1177] = 0x3F07, [ 1178] = 0x9FB3, ++ [ 1179] = 0x2A1B5, [ 1180] = 0x40F8, [ 1181] = 0x37D6, [ 1182] = 0x46F7, ++ [ 1183] = 0x26C46, [ 1184] = 0x417C, [ 1185] = 0x286B2, [ 1186] = 0x273FF, ++ [ 1187] = 0x456D, [ 1188] = 0x38D4, [ 1189] = 0x2549A, [ 1190] = 0x4561, ++ [ 1191] = 0x451B, [ 1192] = 0x4D89, [ 1193] = 0x4C7B, [ 1194] = 0x4D76, ++ [ 1195] = 0x45EA, [ 1196] = 0x3FC8, [ 1197] = 0x24B0F, [ 1198] = 0x3661, ++ [ 1199] = 0x44DE, [ 1200] = 0x44BD, [ 1201] = 0x41ED, [ 1202] = 0x5D3E, ++ [ 1203] = 0x5D48, [ 1204] = 0x5D56, [ 1205] = 0x3DFC, [ 1206] = 0x380F, ++ [ 1207] = 0x5DA4, [ 1208] = 0x5DB9, [ 1209] = 0x3820, [ 1210] = 0x3838, ++ [ 1211] = 0x5E42, [ 1212] = 0x5EBD, [ 1213] = 0x5F25, [ 1214] = 0x5F83, ++ [ 1215] = 0x3908, [ 1216] = 0x3914, [ 1217] = 0x393F, [ 1218] = 0x394D, ++ [ 1219] = 0x60D7, [ 1220] = 0x613D, [ 1221] = 0x5CE5, [ 1222] = 0x3989, ++ [ 1223] = 0x61B7, [ 1224] = 0x61B9, [ 1225] = 0x61CF, [ 1226] = 0x39B8, ++ [ 1227] = 0x622C, [ 1228] = 0x6290, [ 1229] = 0x62E5, [ 1230] = 0x6318, ++ [ 1231] = 0x39F8, [ 1232] = 0x56B1, [ 1267] = 0x3A03, [ 1268] = 0x63E2, ++ [ 1269] = 0x63FB, [ 1270] = 0x6407, [ 1271] = 0x645A, [ 1272] = 0x3A4B, ++ [ 1273] = 0x64C0, [ 1274] = 0x5D15, [ 1275] = 0x5621, [ 1276] = 0x9F9F, ++ [ 1277] = 0x3A97, [ 1278] = 0x6586, [ 1279] = 0x3ABD, [ 1280] = 0x65FF, ++ [ 1281] = 0x6653, [ 1282] = 0x3AF2, [ 1283] = 0x6692, [ 1284] = 0x3B22, ++ [ 1285] = 0x6716, [ 1286] = 0x3B42, [ 1287] = 0x67A4, [ 1288] = 0x6800, ++ [ 1289] = 0x3B58, [ 1290] = 0x684A, [ 1291] = 0x6884, [ 1292] = 0x3B72, ++ [ 1293] = 0x3B71, [ 1294] = 0x3B7B, [ 1295] = 0x6909, [ 1296] = 0x6943, ++ [ 1297] = 0x725C, [ 1298] = 0x6964, [ 1299] = 0x699F, [ 1300] = 0x6985, ++ [ 1301] = 0x3BBC, [ 1302] = 0x69D6, [ 1303] = 0x3BDD, [ 1304] = 0x6A65, ++ [ 1305] = 0x6A74, [ 1306] = 0x6A71, [ 1307] = 0x6A82, [ 1308] = 0x3BEC, ++ [ 1309] = 0x6A99, [ 1310] = 0x3BF2, [ 1311] = 0x6AAB, [ 1312] = 0x6AB5, ++ [ 1313] = 0x6AD4, [ 1314] = 0x6AF6, [ 1315] = 0x6B81, [ 1316] = 0x6BC1, ++ [ 1317] = 0x6BEA, [ 1318] = 0x6C75, [ 1319] = 0x6CAA, [ 1320] = 0x3CCB, ++ [ 1321] = 0x6D02, [ 1322] = 0x6D06, [ 1323] = 0x6D26, [ 1324] = 0x6D81, ++ [ 1325] = 0x3CEF, [ 1326] = 0x6DA4, [ 1327] = 0x6DB1, [ 1328] = 0x6E15, ++ [ 1329] = 0x6E18, [ 1330] = 0x6E29, [ 1331] = 0x6E86, [ 1332] = 0x289C0, ++ [ 1333] = 0x6EBB, [ 1334] = 0x6EE2, [ 1335] = 0x6EDA, [ 1336] = 0x9F7F, ++ [ 1337] = 0x6EE8, [ 1338] = 0x6EE9, [ 1339] = 0x6F24, [ 1340] = 0x6F34, ++ [ 1341] = 0x3D46, [ 1342] = 0x23F41, [ 1343] = 0x6F81, [ 1344] = 0x6FBE, ++ [ 1345] = 0x3D6A, [ 1346] = 0x3D75, [ 1347] = 0x71B7, [ 1348] = 0x5C99, ++ [ 1349] = 0x3D8A, [ 1350] = 0x702C, [ 1351] = 0x3D91, [ 1352] = 0x7050, ++ [ 1353] = 0x7054, [ 1354] = 0x706F, [ 1355] = 0x707F, [ 1356] = 0x7089, ++ [ 1357] = 0x20325, [ 1358] = 0x43C1, [ 1359] = 0x35F1, [ 1360] = 0x20ED8, ++ [ 1365] = 0x23ED7, [ 1366] = 0x57BE, [ 1367] = 0x26ED3, [ 1368] = 0x713E, ++ [ 1369] = 0x257E0, [ 1370] = 0x364E, [ 1371] = 0x69A2, [ 1372] = 0x28BE9, ++ [ 1373] = 0x5B74, [ 1374] = 0x7A49, [ 1375] = 0x258E1, [ 1376] = 0x294D9, ++ [ 1377] = 0x7A65, [ 1378] = 0x7A7D, [ 1379] = 0x259AC, [ 1380] = 0x7ABB, ++ [ 1381] = 0x7AB0, [ 1382] = 0x7AC2, [ 1383] = 0x7AC3, [ 1384] = 0x71D1, ++ [ 1385] = 0x2648D, [ 1386] = 0x41CA, [ 1387] = 0x7ADA, [ 1388] = 0x7ADD, ++ [ 1389] = 0x7AEA, [ 1390] = 0x41EF, [ 1391] = 0x54B2, [ 1392] = 0x25C01, ++ [ 1393] = 0x7B0B, [ 1394] = 0x7B55, [ 1395] = 0x7B29, [ 1396] = 0x2530E, ++ [ 1397] = 0x25CFE, [ 1398] = 0x7BA2, [ 1399] = 0x7B6F, [ 1400] = 0x839C, ++ [ 1401] = 0x25BB4, [ 1402] = 0x26C7F, [ 1403] = 0x7BD0, [ 1404] = 0x8421, ++ [ 1405] = 0x7B92, [ 1407] = 0x25D20, [ 1408] = 0x3DAD, [ 1409] = 0x25C65, ++ [ 1410] = 0x8492, [ 1411] = 0x7BFA, [ 1413] = 0x7C35, [ 1414] = 0x25CC1, ++ [ 1415] = 0x7C44, [ 1416] = 0x7C83, [ 1417] = 0x24882, [ 1418] = 0x7CA6, ++ [ 1419] = 0x667D, [ 1420] = 0x24578, [ 1421] = 0x7CC9, [ 1422] = 0x7CC7, ++ [ 1423] = 0x7CE6, [ 1424] = 0x7C74, [ 1425] = 0x7CF3, [ 1426] = 0x7CF5, ++ [ 1462] = 0x7E67, [ 1463] = 0x451D, [ 1464] = 0x26E44, [ 1465] = 0x7D5D, ++ [ 1466] = 0x26ED6, [ 1467] = 0x748D, [ 1468] = 0x7D89, [ 1469] = 0x7DAB, ++ [ 1470] = 0x7135, [ 1471] = 0x7DB3, [ 1473] = 0x24057, [ 1474] = 0x26029, ++ [ 1475] = 0x7DE4, [ 1476] = 0x3D13, [ 1477] = 0x7DF5, [ 1478] = 0x217F9, ++ [ 1479] = 0x7DE5, [ 1480] = 0x2836D, [ 1482] = 0x26121, [ 1483] = 0x2615A, ++ [ 1484] = 0x7E6E, [ 1485] = 0x7E92, [ 1486] = 0x432B, [ 1487] = 0x946C, ++ [ 1488] = 0x7E27, [ 1489] = 0x7F40, [ 1490] = 0x7F41, [ 1491] = 0x7F47, ++ [ 1492] = 0x7936, [ 1493] = 0x262D0, [ 1494] = 0x99E1, [ 1495] = 0x7F97, ++ [ 1496] = 0x26351, [ 1497] = 0x7FA3, [ 1498] = 0x21661, [ 1499] = 0x20068, ++ [ 1500] = 0x455C, [ 1501] = 0x23766, [ 1502] = 0x4503, [ 1503] = 0x2833A, ++ [ 1504] = 0x7FFA, [ 1505] = 0x26489, [ 1507] = 0x8008, [ 1508] = 0x801D, ++ [ 1510] = 0x802F, [ 1511] = 0x2A087, [ 1512] = 0x26CC3, [ 1513] = 0x803B, ++ [ 1514] = 0x803C, [ 1515] = 0x8061, [ 1516] = 0x22714, [ 1517] = 0x4989, ++ [ 1518] = 0x26626, [ 1519] = 0x23DE3, [ 1520] = 0x266E8, [ 1521] = 0x6725, ++ [ 1522] = 0x80A7, [ 1523] = 0x28A48, [ 1524] = 0x8107, [ 1525] = 0x811A, ++ [ 1526] = 0x58B0, [ 1527] = 0x226F6, [ 1528] = 0x6C7F, [ 1529] = 0x26498, ++ [ 1530] = 0x24FB8, [ 1531] = 0x64E7, [ 1532] = 0x2148A, [ 1533] = 0x8218, ++ [ 1534] = 0x2185E, [ 1535] = 0x6A53, [ 1536] = 0x24A65, [ 1537] = 0x24A95, ++ [ 1538] = 0x447A, [ 1539] = 0x8229, [ 1540] = 0x20B0D, [ 1541] = 0x26A52, ++ [ 1542] = 0x23D7E, [ 1543] = 0x4FF9, [ 1544] = 0x214FD, [ 1545] = 0x84E2, ++ [ 1546] = 0x8362, [ 1547] = 0x26B0A, [ 1548] = 0x249A7, [ 1549] = 0x23530, ++ [ 1550] = 0x21773, [ 1551] = 0x23DF8, [ 1552] = 0x82AA, [ 1553] = 0x691B, ++ [ 1554] = 0x2F994, [ 1555] = 0x41DB, [ 1560] = 0x854B, [ 1561] = 0x82D0, ++ [ 1562] = 0x831A, [ 1563] = 0x20E16, [ 1564] = 0x217B4, [ 1565] = 0x36C1, ++ [ 1566] = 0x2317D, [ 1567] = 0x2355A, [ 1568] = 0x827B, [ 1569] = 0x82E2, ++ [ 1570] = 0x8318, [ 1571] = 0x23E8B, [ 1572] = 0x26DA3, [ 1573] = 0x26B05, ++ [ 1574] = 0x26B97, [ 1575] = 0x235CE, [ 1576] = 0x3DBF, [ 1577] = 0x831D, ++ [ 1578] = 0x55EC, [ 1579] = 0x8385, [ 1580] = 0x450B, [ 1581] = 0x26DA5, ++ [ 1582] = 0x83AC, [ 1584] = 0x83D3, [ 1585] = 0x347E, [ 1586] = 0x26ED4, ++ [ 1587] = 0x6A57, [ 1588] = 0x855A, [ 1589] = 0x3496, [ 1590] = 0x26E42, ++ [ 1591] = 0x22EEF, [ 1592] = 0x8458, [ 1593] = 0x25BE4, [ 1594] = 0x8471, ++ [ 1595] = 0x3DD3, [ 1596] = 0x44E4, [ 1597] = 0x6AA7, [ 1598] = 0x844A, ++ [ 1599] = 0x23CB5, [ 1600] = 0x7958, [ 1602] = 0x26B96, [ 1603] = 0x26E77, ++ [ 1604] = 0x26E43, [ 1605] = 0x84DE, [ 1607] = 0x8391, [ 1608] = 0x44A0, ++ [ 1609] = 0x8493, [ 1610] = 0x84E4, [ 1611] = 0x25C91, [ 1612] = 0x4240, ++ [ 1613] = 0x25CC0, [ 1614] = 0x4543, [ 1615] = 0x8534, [ 1616] = 0x5AF2, ++ [ 1617] = 0x26E99, [ 1618] = 0x4527, [ 1619] = 0x8573, [ 1620] = 0x4516, ++ [ 1621] = 0x67BF, [ 1622] = 0x8616, [ 1657] = 0x28625, [ 1658] = 0x2863B, ++ [ 1659] = 0x85C1, [ 1660] = 0x27088, [ 1661] = 0x8602, [ 1662] = 0x21582, ++ [ 1663] = 0x270CD, [ 1664] = 0x2F9B2, [ 1665] = 0x456A, [ 1666] = 0x8628, ++ [ 1667] = 0x3648, [ 1668] = 0x218A2, [ 1669] = 0x53F7, [ 1670] = 0x2739A, ++ [ 1671] = 0x867E, [ 1672] = 0x8771, [ 1673] = 0x2A0F8, [ 1674] = 0x87EE, ++ [ 1675] = 0x22C27, [ 1676] = 0x87B1, [ 1677] = 0x87DA, [ 1678] = 0x880F, ++ [ 1679] = 0x5661, [ 1680] = 0x866C, [ 1681] = 0x6856, [ 1682] = 0x460F, ++ [ 1683] = 0x8845, [ 1684] = 0x8846, [ 1685] = 0x275E0, [ 1686] = 0x23DB9, ++ [ 1687] = 0x275E4, [ 1688] = 0x885E, [ 1689] = 0x889C, [ 1690] = 0x465B, ++ [ 1691] = 0x88B4, [ 1692] = 0x88B5, [ 1693] = 0x63C1, [ 1694] = 0x88C5, ++ [ 1695] = 0x7777, [ 1696] = 0x2770F, [ 1697] = 0x8987, [ 1698] = 0x898A, ++ [ 1701] = 0x89A7, [ 1702] = 0x89BC, [ 1703] = 0x28A25, [ 1704] = 0x89E7, ++ [ 1705] = 0x27924, [ 1706] = 0x27ABD, [ 1707] = 0x8A9C, [ 1708] = 0x7793, ++ [ 1709] = 0x91FE, [ 1710] = 0x8A90, [ 1711] = 0x27A59, [ 1712] = 0x7AE9, ++ [ 1713] = 0x27B3A, [ 1714] = 0x23F8F, [ 1715] = 0x4713, [ 1716] = 0x27B38, ++ [ 1717] = 0x717C, [ 1718] = 0x8B0C, [ 1719] = 0x8B1F, [ 1720] = 0x25430, ++ [ 1721] = 0x25565, [ 1722] = 0x8B3F, [ 1723] = 0x8B4C, [ 1724] = 0x8B4D, ++ [ 1725] = 0x8AA9, [ 1726] = 0x24A7A, [ 1727] = 0x8B90, [ 1728] = 0x8B9B, ++ [ 1729] = 0x8AAF, [ 1730] = 0x216DF, [ 1731] = 0x4615, [ 1732] = 0x884F, ++ [ 1733] = 0x8C9B, [ 1734] = 0x27D54, [ 1735] = 0x27D8F, [ 1736] = 0x2F9D4, ++ [ 1737] = 0x3725, [ 1738] = 0x27D53, [ 1739] = 0x8CD6, [ 1740] = 0x27D98, ++ [ 1741] = 0x27DBD, [ 1742] = 0x8D12, [ 1743] = 0x8D03, [ 1744] = 0x21910, ++ [ 1745] = 0x8CDB, [ 1746] = 0x705C, [ 1747] = 0x8D11, [ 1748] = 0x24CC9, ++ [ 1749] = 0x3ED0, [ 1755] = 0x8DA9, [ 1756] = 0x28002, [ 1757] = 0x21014, ++ [ 1758] = 0x2498A, [ 1759] = 0x3B7C, [ 1760] = 0x281BC, [ 1761] = 0x2710C, ++ [ 1762] = 0x7AE7, [ 1763] = 0x8EAD, [ 1764] = 0x8EB6, [ 1765] = 0x8EC3, ++ [ 1766] = 0x92D4, [ 1767] = 0x8F19, [ 1768] = 0x8F2D, [ 1769] = 0x28365, ++ [ 1770] = 0x28412, [ 1771] = 0x8FA5, [ 1772] = 0x9303, [ 1773] = 0x2A29F, ++ [ 1774] = 0x20A50, [ 1775] = 0x8FB3, [ 1776] = 0x492A, [ 1777] = 0x289DE, ++ [ 1778] = 0x2853D, [ 1779] = 0x23DBB, [ 1780] = 0x5EF8, [ 1781] = 0x23262, ++ [ 1782] = 0x8FF9, [ 1783] = 0x2A014, [ 1784] = 0x286BC, [ 1785] = 0x28501, ++ [ 1786] = 0x22325, [ 1787] = 0x3980, [ 1788] = 0x26ED7, [ 1789] = 0x9037, ++ [ 1790] = 0x2853C, [ 1791] = 0x27ABE, [ 1792] = 0x9061, [ 1793] = 0x2856C, ++ [ 1794] = 0x2860B, [ 1795] = 0x90A8, [ 1796] = 0x28713, [ 1797] = 0x90C4, ++ [ 1798] = 0x286E6, [ 1799] = 0x90AE, [ 1801] = 0x9167, [ 1802] = 0x3AF0, ++ [ 1803] = 0x91A9, [ 1804] = 0x91C4, [ 1805] = 0x7CAC, [ 1806] = 0x28933, ++ [ 1807] = 0x21E89, [ 1808] = 0x920E, [ 1809] = 0x6C9F, [ 1810] = 0x9241, ++ [ 1811] = 0x9262, [ 1812] = 0x255B9, [ 1814] = 0x28AC6, [ 1815] = 0x23C9B, ++ [ 1816] = 0x28B0C, [ 1817] = 0x255DB, [ 1852] = 0x20D31, [ 1853] = 0x932C, ++ [ 1854] = 0x936B, [ 1855] = 0x28AE1, [ 1856] = 0x28BEB, [ 1857] = 0x708F, ++ [ 1858] = 0x5AC3, [ 1859] = 0x28AE2, [ 1860] = 0x28AE5, [ 1861] = 0x4965, ++ [ 1862] = 0x9244, [ 1863] = 0x28BEC, [ 1864] = 0x28C39, [ 1865] = 0x28BFF, ++ [ 1866] = 0x9373, [ 1867] = 0x945B, [ 1868] = 0x8EBC, [ 1869] = 0x9585, ++ [ 1870] = 0x95A6, [ 1871] = 0x9426, [ 1872] = 0x95A0, [ 1873] = 0x6FF6, ++ [ 1874] = 0x42B9, [ 1875] = 0x2267A, [ 1876] = 0x286D8, [ 1877] = 0x2127C, ++ [ 1878] = 0x23E2E, [ 1879] = 0x49DF, [ 1880] = 0x6C1C, [ 1881] = 0x967B, ++ [ 1882] = 0x9696, [ 1883] = 0x416C, [ 1884] = 0x96A3, [ 1885] = 0x26ED5, ++ [ 1886] = 0x61DA, [ 1887] = 0x96B6, [ 1888] = 0x78F5, [ 1889] = 0x28AE0, ++ [ 1890] = 0x96BD, [ 1891] = 0x53CC, [ 1892] = 0x49A1, [ 1893] = 0x26CB8, ++ [ 1894] = 0x20274, [ 1895] = 0x26410, [ 1896] = 0x290AF, [ 1897] = 0x290E5, ++ [ 1898] = 0x24AD1, [ 1899] = 0x21915, [ 1900] = 0x2330A, [ 1901] = 0x9731, ++ [ 1902] = 0x8642, [ 1903] = 0x9736, [ 1904] = 0x4A0F, [ 1905] = 0x453D, ++ [ 1906] = 0x4585, [ 1907] = 0x24AE9, [ 1908] = 0x7075, [ 1909] = 0x5B41, ++ [ 1910] = 0x971B, [ 1912] = 0x291D5, [ 1913] = 0x9757, [ 1914] = 0x5B4A, ++ [ 1915] = 0x291EB, [ 1916] = 0x975F, [ 1917] = 0x9425, [ 1918] = 0x50D0, ++ [ 1919] = 0x230B7, [ 1920] = 0x230BC, [ 1921] = 0x9789, [ 1922] = 0x979F, ++ [ 1923] = 0x97B1, [ 1924] = 0x97BE, [ 1925] = 0x97C0, [ 1926] = 0x97D2, ++ [ 1927] = 0x97E0, [ 1928] = 0x2546C, [ 1929] = 0x97EE, [ 1930] = 0x741C, ++ [ 1931] = 0x29433, [ 1933] = 0x97F5, [ 1934] = 0x2941D, [ 1935] = 0x2797A, ++ [ 1936] = 0x4AD1, [ 1937] = 0x9834, [ 1938] = 0x9833, [ 1939] = 0x984B, ++ [ 1940] = 0x9866, [ 1941] = 0x3B0E, [ 1942] = 0x27175, [ 1943] = 0x3D51, ++ [ 1944] = 0x20630, [ 1945] = 0x2415C, [ 1950] = 0x25706, [ 1951] = 0x98CA, ++ [ 1952] = 0x98B7, [ 1953] = 0x98C8, [ 1954] = 0x98C7, [ 1955] = 0x4AFF, ++ [ 1956] = 0x26D27, [ 1957] = 0x216D3, [ 1958] = 0x55B0, [ 1959] = 0x98E1, ++ [ 1960] = 0x98E6, [ 1961] = 0x98EC, [ 1962] = 0x9378, [ 1963] = 0x9939, ++ [ 1964] = 0x24A29, [ 1965] = 0x4B72, [ 1966] = 0x29857, [ 1967] = 0x29905, ++ [ 1968] = 0x99F5, [ 1969] = 0x9A0C, [ 1970] = 0x9A3B, [ 1971] = 0x9A10, ++ [ 1972] = 0x9A58, [ 1973] = 0x25725, [ 1974] = 0x36C4, [ 1975] = 0x290B1, ++ [ 1976] = 0x29BD5, [ 1977] = 0x9AE0, [ 1978] = 0x9AE2, [ 1979] = 0x29B05, ++ [ 1980] = 0x9AF4, [ 1981] = 0x4C0E, [ 1982] = 0x9B14, [ 1983] = 0x9B2D, ++ [ 1984] = 0x28600, [ 1985] = 0x5034, [ 1986] = 0x9B34, [ 1987] = 0x269A8, ++ [ 1988] = 0x38C3, [ 1989] = 0x2307D, [ 1990] = 0x9B50, [ 1991] = 0x9B40, ++ [ 1992] = 0x29D3E, [ 1993] = 0x5A45, [ 1994] = 0x21863, [ 1995] = 0x9B8E, ++ [ 1996] = 0x2424B, [ 1997] = 0x9C02, [ 1998] = 0x9BFF, [ 1999] = 0x9C0C, ++ [ 2000] = 0x29E68, [ 2001] = 0x9DD4, [ 2002] = 0x29FB7, [ 2003] = 0x2A192, ++ [ 2004] = 0x2A1AB, [ 2005] = 0x2A0E1, [ 2006] = 0x2A123, [ 2007] = 0x2A1DF, ++ [ 2008] = 0x9D7E, [ 2009] = 0x9D83, [ 2010] = 0x2A134, [ 2011] = 0x9E0E, ++ [ 2012] = 0x6888, [ 2047] = 0x9DC4, [ 2048] = 0x2215B, [ 2049] = 0x2A193, ++ [ 2050] = 0x2A220, [ 2051] = 0x2193B, [ 2052] = 0x2A233, [ 2053] = 0x9D39, ++ [ 2054] = 0x2A0B9, [ 2055] = 0x2A2B4, [ 2056] = 0x9E90, [ 2057] = 0x9E95, ++ [ 2058] = 0x9E9E, [ 2059] = 0x9EA2, [ 2060] = 0x4D34, [ 2061] = 0x9EAA, ++ [ 2062] = 0x9EAF, [ 2063] = 0x24364, [ 2064] = 0x9EC1, [ 2065] = 0x3B60, ++ [ 2066] = 0x39E5, [ 2067] = 0x3D1D, [ 2068] = 0x4F32, [ 2069] = 0x37BE, ++ [ 2070] = 0x28C2B, [ 2071] = 0x9F02, [ 2072] = 0x9F08, [ 2073] = 0x4B96, ++ [ 2074] = 0x9424, [ 2075] = 0x26DA2, [ 2076] = 0x9F17, [ 2078] = 0x9F39, ++ [ 2079] = 0x569F, [ 2080] = 0x568A, [ 2081] = 0x9F45, [ 2082] = 0x99B8, ++ [ 2083] = 0x2908B, [ 2084] = 0x97F2, [ 2085] = 0x847F, [ 2086] = 0x9F62, ++ [ 2087] = 0x9F69, [ 2088] = 0x7ADC, [ 2089] = 0x9F8E, [ 2090] = 0x7216, ++ [ 2091] = 0x4BBE, [ 2092] = 0x24975, [ 2093] = 0x249BB, [ 2094] = 0x7177, ++ [ 2095] = 0x249F8, [ 2096] = 0x24348, [ 2097] = 0x24A51, [ 2098] = 0x739E, ++ [ 2099] = 0x28BDA, [ 2100] = 0x218FA, [ 2101] = 0x799F, [ 2102] = 0x2897E, ++ [ 2103] = 0x28E36, [ 2104] = 0x9369, [ 2105] = 0x93F3, [ 2106] = 0x28A44, ++ [ 2107] = 0x92EC, [ 2108] = 0x9381, [ 2109] = 0x93CB, [ 2110] = 0x2896C, ++ [ 2111] = 0x244B9, [ 2112] = 0x7217, [ 2113] = 0x3EEB, [ 2114] = 0x7772, ++ [ 2115] = 0x7A43, [ 2116] = 0x70D0, [ 2117] = 0x24473, [ 2118] = 0x243F8, ++ [ 2119] = 0x717E, [ 2120] = 0x217EF, [ 2121] = 0x70A3, [ 2122] = 0x218BE, ++ [ 2123] = 0x23599, [ 2124] = 0x3EC7, [ 2125] = 0x21885, [ 2126] = 0x2542F, ++ [ 2127] = 0x217F8, [ 2128] = 0x3722, [ 2129] = 0x216FB, [ 2130] = 0x21839, ++ [ 2131] = 0x36E1, [ 2132] = 0x21774, [ 2133] = 0x218D1, [ 2134] = 0x25F4B, ++ [ 2135] = 0x3723, [ 2136] = 0x216C0, [ 2137] = 0x575B, [ 2138] = 0x24A25, ++ [ 2139] = 0x213FE, [ 2140] = 0x212A8, [ 2145] = 0x213C6, [ 2146] = 0x214B6, ++ [ 2147] = 0x8503, [ 2148] = 0x236A6, [ 2150] = 0x8455, [ 2151] = 0x24994, ++ [ 2152] = 0x27165, [ 2153] = 0x23E31, [ 2154] = 0x2555C, [ 2155] = 0x23EFB, ++ [ 2156] = 0x27052, [ 2157] = 0x44F4, [ 2158] = 0x236EE, [ 2159] = 0x2999D, ++ [ 2160] = 0x26F26, [ 2161] = 0x67F9, [ 2162] = 0x3733, [ 2163] = 0x3C15, ++ [ 2164] = 0x3DE7, [ 2165] = 0x586C, [ 2166] = 0x21922, [ 2167] = 0x6810, ++ [ 2168] = 0x4057, [ 2169] = 0x2373F, [ 2170] = 0x240E1, [ 2171] = 0x2408B, ++ [ 2172] = 0x2410F, [ 2173] = 0x26C21, [ 2174] = 0x54CB, [ 2175] = 0x569E, ++ [ 2176] = 0x266B1, [ 2177] = 0x5692, [ 2178] = 0x20FDF, [ 2179] = 0x20BA8, ++ [ 2180] = 0x20E0D, [ 2181] = 0x93C6, [ 2182] = 0x28B13, [ 2183] = 0x939C, ++ [ 2184] = 0x4EF8, [ 2185] = 0x512B, [ 2186] = 0x3819, [ 2187] = 0x24436, ++ [ 2188] = 0x4EBC, [ 2189] = 0x20465, [ 2190] = 0x2037F, [ 2191] = 0x4F4B, ++ [ 2192] = 0x4F8A, [ 2193] = 0x25651, [ 2194] = 0x5A68, [ 2195] = 0x201AB, ++ [ 2196] = 0x203CB, [ 2197] = 0x3999, [ 2198] = 0x2030A, [ 2199] = 0x20414, ++ [ 2200] = 0x3435, [ 2201] = 0x4F29, [ 2202] = 0x202C0, [ 2203] = 0x28EB3, ++ [ 2204] = 0x20275, [ 2205] = 0x8ADA, [ 2206] = 0x2020C, [ 2207] = 0x4E98, ++ [ 2242] = 0x50CD, [ 2243] = 0x510D, [ 2244] = 0x4FA2, [ 2245] = 0x4F03, ++ [ 2246] = 0x24A0E, [ 2247] = 0x23E8A, [ 2248] = 0x4F42, [ 2249] = 0x502E, ++ [ 2250] = 0x506C, [ 2251] = 0x5081, [ 2252] = 0x4FCC, [ 2253] = 0x4FE5, ++ [ 2254] = 0x5058, [ 2255] = 0x50FC, [ 2260] = 0x6E76, [ 2261] = 0x23595, ++ [ 2262] = 0x23E39, [ 2263] = 0x23EBF, [ 2264] = 0x6D72, [ 2265] = 0x21884, ++ [ 2266] = 0x23E89, [ 2267] = 0x51A8, [ 2268] = 0x51C3, [ 2269] = 0x205E0, ++ [ 2270] = 0x44DD, [ 2271] = 0x204A3, [ 2272] = 0x20492, [ 2273] = 0x20491, ++ [ 2274] = 0x8D7A, [ 2275] = 0x28A9C, [ 2276] = 0x2070E, [ 2277] = 0x5259, ++ [ 2278] = 0x52A4, [ 2279] = 0x20873, [ 2280] = 0x52E1, [ 2282] = 0x467A, ++ [ 2283] = 0x718C, [ 2284] = 0x2438C, [ 2285] = 0x20C20, [ 2286] = 0x249AC, ++ [ 2287] = 0x210E4, [ 2288] = 0x69D1, [ 2289] = 0x20E1D, [ 2291] = 0x3EDE, ++ [ 2292] = 0x7499, [ 2293] = 0x7414, [ 2294] = 0x7456, [ 2295] = 0x7398, ++ [ 2296] = 0x4B8E, [ 2297] = 0x24ABC, [ 2298] = 0x2408D, [ 2299] = 0x53D0, ++ [ 2300] = 0x3584, [ 2301] = 0x720F, [ 2302] = 0x240C9, [ 2303] = 0x55B4, ++ [ 2304] = 0x20345, [ 2305] = 0x54CD, [ 2306] = 0x20BC6, [ 2307] = 0x571D, ++ [ 2308] = 0x925D, [ 2309] = 0x96F4, [ 2310] = 0x9366, [ 2311] = 0x57DD, ++ [ 2312] = 0x578D, [ 2313] = 0x577F, [ 2314] = 0x363E, [ 2315] = 0x58CB, ++ [ 2316] = 0x5A99, [ 2317] = 0x28A46, [ 2318] = 0x216FA, [ 2319] = 0x2176F, ++ [ 2320] = 0x21710, [ 2321] = 0x5A2C, [ 2322] = 0x59B8, [ 2323] = 0x928F, ++ [ 2324] = 0x5A7E, [ 2325] = 0x5ACF, [ 2326] = 0x5A12, [ 2327] = 0x25946, ++ [ 2328] = 0x219F3, [ 2329] = 0x21861, [ 2330] = 0x24295, [ 2331] = 0x36F5, ++ [ 2332] = 0x6D05, [ 2333] = 0x7443, [ 2334] = 0x5A21, [ 2335] = 0x25E83, ++ [ 2340] = 0x5A81, [ 2341] = 0x28BD7, [ 2342] = 0x20413, [ 2343] = 0x93E0, ++ [ 2344] = 0x748C, [ 2345] = 0x21303, [ 2346] = 0x7105, [ 2347] = 0x4972, ++ [ 2348] = 0x9408, [ 2349] = 0x289FB, [ 2350] = 0x93BD, [ 2351] = 0x37A0, ++ [ 2352] = 0x5C1E, [ 2353] = 0x5C9E, [ 2354] = 0x5E5E, [ 2355] = 0x5E48, ++ [ 2356] = 0x21996, [ 2357] = 0x2197C, [ 2358] = 0x23AEE, [ 2359] = 0x5ECD, ++ [ 2360] = 0x5B4F, [ 2361] = 0x21903, [ 2362] = 0x21904, [ 2363] = 0x3701, ++ [ 2364] = 0x218A0, [ 2365] = 0x36DD, [ 2366] = 0x216FE, [ 2367] = 0x36D3, ++ [ 2368] = 0x812A, [ 2369] = 0x28A47, [ 2370] = 0x21DBA, [ 2371] = 0x23472, ++ [ 2372] = 0x289A8, [ 2373] = 0x5F0C, [ 2374] = 0x5F0E, [ 2375] = 0x21927, ++ [ 2376] = 0x217AB, [ 2377] = 0x5A6B, [ 2378] = 0x2173B, [ 2379] = 0x5B44, ++ [ 2380] = 0x8614, [ 2381] = 0x275FD, [ 2382] = 0x8860, [ 2383] = 0x607E, ++ [ 2384] = 0x22860, [ 2385] = 0x2262B, [ 2386] = 0x5FDB, [ 2387] = 0x3EB8, ++ [ 2388] = 0x225AF, [ 2389] = 0x225BE, [ 2390] = 0x29088, [ 2391] = 0x26F73, ++ [ 2392] = 0x61C0, [ 2393] = 0x2003E, [ 2394] = 0x20046, [ 2395] = 0x2261B, ++ [ 2396] = 0x6199, [ 2397] = 0x6198, [ 2398] = 0x6075, [ 2399] = 0x22C9B, ++ [ 2400] = 0x22D07, [ 2401] = 0x246D4, [ 2402] = 0x2914D, [ 2437] = 0x6471, ++ [ 2438] = 0x24665, [ 2439] = 0x22B6A, [ 2440] = 0x3A29, [ 2441] = 0x22B22, ++ [ 2442] = 0x23450, [ 2443] = 0x298EA, [ 2444] = 0x22E78, [ 2445] = 0x6337, ++ [ 2446] = 0x2A45B, [ 2447] = 0x64B6, [ 2448] = 0x6331, [ 2449] = 0x63D1, ++ [ 2450] = 0x249E3, [ 2451] = 0x22D67, [ 2452] = 0x62A4, [ 2453] = 0x22CA1, ++ [ 2454] = 0x643B, [ 2455] = 0x656B, [ 2456] = 0x6972, [ 2457] = 0x3BF4, ++ [ 2458] = 0x2308E, [ 2459] = 0x232AD, [ 2460] = 0x24989, [ 2461] = 0x232AB, ++ [ 2462] = 0x550D, [ 2463] = 0x232E0, [ 2464] = 0x218D9, [ 2465] = 0x2943F, ++ [ 2466] = 0x66CE, [ 2467] = 0x23289, [ 2468] = 0x231B3, [ 2469] = 0x3AE0, ++ [ 2470] = 0x4190, [ 2471] = 0x25584, [ 2472] = 0x28B22, [ 2473] = 0x2558F, ++ [ 2474] = 0x216FC, [ 2475] = 0x2555B, [ 2476] = 0x25425, [ 2477] = 0x78EE, ++ [ 2478] = 0x23103, [ 2479] = 0x2182A, [ 2480] = 0x23234, [ 2481] = 0x3464, ++ [ 2482] = 0x2320F, [ 2483] = 0x23182, [ 2484] = 0x242C9, [ 2485] = 0x668E, ++ [ 2486] = 0x26D24, [ 2487] = 0x666B, [ 2488] = 0x4B93, [ 2489] = 0x6630, ++ [ 2490] = 0x27870, [ 2491] = 0x21DEB, [ 2492] = 0x6663, [ 2493] = 0x232D2, ++ [ 2494] = 0x232E1, [ 2495] = 0x661E, [ 2496] = 0x25872, [ 2497] = 0x38D1, ++ [ 2498] = 0x2383A, [ 2499] = 0x237BC, [ 2500] = 0x3B99, [ 2501] = 0x237A2, ++ [ 2502] = 0x233FE, [ 2503] = 0x74D0, [ 2504] = 0x3B96, [ 2505] = 0x678F, ++ [ 2506] = 0x2462A, [ 2507] = 0x68B6, [ 2508] = 0x681E, [ 2509] = 0x3BC4, ++ [ 2510] = 0x6ABE, [ 2511] = 0x3863, [ 2512] = 0x237D5, [ 2513] = 0x24487, ++ [ 2514] = 0x6A33, [ 2515] = 0x6A52, [ 2516] = 0x6AC9, [ 2517] = 0x6B05, ++ [ 2518] = 0x21912, [ 2519] = 0x6511, [ 2520] = 0x6898, [ 2521] = 0x6A4C, ++ [ 2522] = 0x3BD7, [ 2523] = 0x6A7A, [ 2524] = 0x6B57, [ 2525] = 0x23FC0, ++ [ 2526] = 0x23C9A, [ 2527] = 0x93A0, [ 2528] = 0x92F2, [ 2529] = 0x28BEA, ++ [ 2530] = 0x28ACB, [ 2535] = 0x9289, [ 2536] = 0x2801E, [ 2537] = 0x289DC, ++ [ 2538] = 0x9467, [ 2539] = 0x6DA5, [ 2540] = 0x6F0B, [ 2541] = 0x249EC, ++ [ 2543] = 0x23F7F, [ 2544] = 0x3D8F, [ 2545] = 0x6E04, [ 2546] = 0x2403C, ++ [ 2547] = 0x5A3D, [ 2548] = 0x6E0A, [ 2549] = 0x5847, [ 2550] = 0x6D24, ++ [ 2551] = 0x7842, [ 2552] = 0x713B, [ 2553] = 0x2431A, [ 2554] = 0x24276, ++ [ 2555] = 0x70F1, [ 2556] = 0x7250, [ 2557] = 0x7287, [ 2558] = 0x7294, ++ [ 2559] = 0x2478F, [ 2560] = 0x24725, [ 2561] = 0x5179, [ 2562] = 0x24AA4, ++ [ 2563] = 0x205EB, [ 2564] = 0x747A, [ 2565] = 0x23EF8, [ 2566] = 0x2365F, ++ [ 2567] = 0x24A4A, [ 2568] = 0x24917, [ 2569] = 0x25FE1, [ 2570] = 0x3F06, ++ [ 2571] = 0x3EB1, [ 2572] = 0x24ADF, [ 2573] = 0x28C23, [ 2574] = 0x23F35, ++ [ 2575] = 0x60A7, [ 2576] = 0x3EF3, [ 2577] = 0x74CC, [ 2578] = 0x743C, ++ [ 2579] = 0x9387, [ 2580] = 0x7437, [ 2581] = 0x449F, [ 2582] = 0x26DEA, ++ [ 2583] = 0x4551, [ 2584] = 0x7583, [ 2585] = 0x3F63, [ 2586] = 0x24CD9, ++ [ 2587] = 0x24D06, [ 2588] = 0x3F58, [ 2589] = 0x7555, [ 2590] = 0x7673, ++ [ 2591] = 0x2A5C6, [ 2592] = 0x3B19, [ 2593] = 0x7468, [ 2594] = 0x28ACC, ++ [ 2595] = 0x249AB, [ 2596] = 0x2498E, [ 2597] = 0x3AFB, [ 2632] = 0x3DCD, ++ [ 2633] = 0x24A4E, [ 2634] = 0x3EFF, [ 2635] = 0x249C5, [ 2636] = 0x248F3, ++ [ 2637] = 0x91FA, [ 2638] = 0x5732, [ 2639] = 0x9342, [ 2640] = 0x28AE3, ++ [ 2641] = 0x21864, [ 2642] = 0x50DF, [ 2643] = 0x25221, [ 2644] = 0x251E7, ++ [ 2645] = 0x7778, [ 2646] = 0x23232, [ 2647] = 0x770E, [ 2648] = 0x770F, ++ [ 2649] = 0x777B, [ 2650] = 0x24697, [ 2651] = 0x23781, [ 2652] = 0x3A5E, ++ [ 2653] = 0x248F0, [ 2654] = 0x7438, [ 2655] = 0x749B, [ 2656] = 0x3EBF, ++ [ 2657] = 0x24ABA, [ 2658] = 0x24AC7, [ 2659] = 0x40C8, [ 2660] = 0x24A96, ++ [ 2661] = 0x261AE, [ 2662] = 0x9307, [ 2663] = 0x25581, [ 2664] = 0x781E, ++ [ 2665] = 0x788D, [ 2666] = 0x7888, [ 2667] = 0x78D2, [ 2668] = 0x73D0, ++ [ 2669] = 0x7959, [ 2670] = 0x27741, [ 2671] = 0x256E3, [ 2672] = 0x410E, ++ [ 2674] = 0x8496, [ 2675] = 0x79A5, [ 2676] = 0x6A2D, [ 2677] = 0x23EFA, ++ [ 2678] = 0x7A3A, [ 2679] = 0x79F4, [ 2680] = 0x416E, [ 2681] = 0x216E6, ++ [ 2682] = 0x4132, [ 2683] = 0x9235, [ 2684] = 0x79F1, [ 2685] = 0x20D4C, ++ [ 2686] = 0x2498C, [ 2687] = 0x20299, [ 2688] = 0x23DBA, [ 2689] = 0x2176E, ++ [ 2690] = 0x3597, [ 2691] = 0x556B, [ 2692] = 0x3570, [ 2693] = 0x36AA, ++ [ 2694] = 0x201D4, [ 2695] = 0x20C0D, [ 2696] = 0x7AE2, [ 2697] = 0x5A59, ++ [ 2698] = 0x226F5, [ 2699] = 0x25AAF, [ 2700] = 0x25A9C, [ 2701] = 0x5A0D, ++ [ 2702] = 0x2025B, [ 2703] = 0x78F0, [ 2704] = 0x5A2A, [ 2705] = 0x25BC6, ++ [ 2706] = 0x7AFE, [ 2707] = 0x41F9, [ 2708] = 0x7C5D, [ 2709] = 0x7C6D, ++ [ 2710] = 0x4211, [ 2711] = 0x25BB3, [ 2712] = 0x25EBC, [ 2713] = 0x25EA6, ++ [ 2714] = 0x7CCD, [ 2715] = 0x249F9, [ 2716] = 0x217B0, [ 2717] = 0x7C8E, ++ [ 2718] = 0x7C7C, [ 2719] = 0x7CAE, [ 2720] = 0x6AB2, [ 2721] = 0x7DDC, ++ [ 2722] = 0x7E07, [ 2723] = 0x7DD3, [ 2724] = 0x7F4E, [ 2725] = 0x26261, ++ [ 2730] = 0x2615C, [ 2731] = 0x27B48, [ 2732] = 0x7D97, [ 2733] = 0x25E82, ++ [ 2734] = 0x426A, [ 2735] = 0x26B75, [ 2736] = 0x20916, [ 2737] = 0x67D6, ++ [ 2738] = 0x2004E, [ 2739] = 0x235CF, [ 2740] = 0x57C4, [ 2741] = 0x26412, ++ [ 2742] = 0x263F8, [ 2743] = 0x24962, [ 2744] = 0x7FDD, [ 2745] = 0x7B27, ++ [ 2746] = 0x2082C, [ 2747] = 0x25AE9, [ 2748] = 0x25D43, [ 2749] = 0x7B0C, ++ [ 2750] = 0x25E0E, [ 2751] = 0x99E6, [ 2752] = 0x8645, [ 2753] = 0x9A63, ++ [ 2754] = 0x6A1C, [ 2755] = 0x2343F, [ 2756] = 0x39E2, [ 2757] = 0x249F7, ++ [ 2758] = 0x265AD, [ 2759] = 0x9A1F, [ 2760] = 0x265A0, [ 2761] = 0x8480, ++ [ 2762] = 0x27127, [ 2763] = 0x26CD1, [ 2764] = 0x44EA, [ 2765] = 0x8137, ++ [ 2766] = 0x4402, [ 2767] = 0x80C6, [ 2768] = 0x8109, [ 2769] = 0x8142, ++ [ 2770] = 0x267B4, [ 2771] = 0x98C3, [ 2772] = 0x26A42, [ 2773] = 0x8262, ++ [ 2774] = 0x8265, [ 2775] = 0x26A51, [ 2776] = 0x8453, [ 2777] = 0x26DA7, ++ [ 2778] = 0x8610, [ 2779] = 0x2721B, [ 2780] = 0x5A86, [ 2781] = 0x417F, ++ [ 2782] = 0x21840, [ 2783] = 0x5B2B, [ 2784] = 0x218A1, [ 2785] = 0x5AE4, ++ [ 2786] = 0x218D8, [ 2787] = 0x86A0, [ 2788] = 0x2F9BC, [ 2789] = 0x23D8F, ++ [ 2790] = 0x882D, [ 2791] = 0x27422, [ 2792] = 0x5A02, [ 2827] = 0x886E, ++ [ 2828] = 0x4F45, [ 2829] = 0x8887, [ 2830] = 0x88BF, [ 2831] = 0x88E6, ++ [ 2832] = 0x8965, [ 2833] = 0x894D, [ 2834] = 0x25683, [ 2835] = 0x8954, ++ [ 2836] = 0x27785, [ 2837] = 0x27784, [ 2838] = 0x28BF5, [ 2839] = 0x28BD9, ++ [ 2840] = 0x28B9C, [ 2841] = 0x289F9, [ 2842] = 0x3EAD, [ 2843] = 0x84A3, ++ [ 2844] = 0x46F5, [ 2845] = 0x46CF, [ 2846] = 0x37F2, [ 2847] = 0x8A3D, ++ [ 2848] = 0x8A1C, [ 2849] = 0x29448, [ 2850] = 0x5F4D, [ 2851] = 0x922B, ++ [ 2852] = 0x24284, [ 2853] = 0x65D4, [ 2854] = 0x7129, [ 2855] = 0x70C4, ++ [ 2856] = 0x21845, [ 2857] = 0x9D6D, [ 2858] = 0x8C9F, [ 2859] = 0x8CE9, ++ [ 2860] = 0x27DDC, [ 2861] = 0x599A, [ 2862] = 0x77C3, [ 2863] = 0x59F0, ++ [ 2864] = 0x436E, [ 2865] = 0x36D4, [ 2866] = 0x8E2A, [ 2867] = 0x8EA7, ++ [ 2868] = 0x24C09, [ 2869] = 0x8F30, [ 2870] = 0x8F4A, [ 2871] = 0x42F4, ++ [ 2872] = 0x6C58, [ 2873] = 0x6FBB, [ 2874] = 0x22321, [ 2875] = 0x489B, ++ [ 2876] = 0x6F79, [ 2877] = 0x6E8B, [ 2878] = 0x217DA, [ 2879] = 0x9BE9, ++ [ 2880] = 0x36B5, [ 2881] = 0x2492F, [ 2882] = 0x90BB, [ 2884] = 0x5571, ++ [ 2885] = 0x4906, [ 2886] = 0x91BB, [ 2887] = 0x9404, [ 2888] = 0x28A4B, ++ [ 2889] = 0x4062, [ 2890] = 0x28AFC, [ 2891] = 0x9427, [ 2892] = 0x28C1D, ++ [ 2893] = 0x28C3B, [ 2894] = 0x84E5, [ 2895] = 0x8A2B, [ 2896] = 0x9599, ++ [ 2897] = 0x95A7, [ 2898] = 0x9597, [ 2899] = 0x9596, [ 2900] = 0x28D34, ++ [ 2901] = 0x7445, [ 2902] = 0x3EC2, [ 2903] = 0x248FF, [ 2904] = 0x24A42, ++ [ 2905] = 0x243EA, [ 2906] = 0x3EE7, [ 2907] = 0x23225, [ 2908] = 0x968F, ++ [ 2909] = 0x28EE7, [ 2910] = 0x28E66, [ 2911] = 0x28E65, [ 2912] = 0x3ECC, ++ [ 2913] = 0x249ED, [ 2914] = 0x24A78, [ 2915] = 0x23FEE, [ 2916] = 0x7412, ++ [ 2917] = 0x746B, [ 2918] = 0x3EFC, [ 2919] = 0x9741, [ 2920] = 0x290B0, ++ [ 2925] = 0x6847, [ 2926] = 0x4A1D, [ 2927] = 0x29093, [ 2928] = 0x257DF, ++ [ 2930] = 0x9368, [ 2931] = 0x28989, [ 2932] = 0x28C26, [ 2933] = 0x28B2F, ++ [ 2934] = 0x263BE, [ 2935] = 0x92BA, [ 2936] = 0x5B11, [ 2937] = 0x8B69, ++ [ 2938] = 0x493C, [ 2939] = 0x73F9, [ 2940] = 0x2421B, [ 2941] = 0x979B, ++ [ 2942] = 0x9771, [ 2943] = 0x9938, [ 2944] = 0x20F26, [ 2945] = 0x5DC1, ++ [ 2946] = 0x28BC5, [ 2947] = 0x24AB2, [ 2948] = 0x981F, [ 2949] = 0x294DA, ++ [ 2950] = 0x92F6, [ 2951] = 0x295D7, [ 2952] = 0x91E5, [ 2953] = 0x44C0, ++ [ 2954] = 0x28B50, [ 2955] = 0x24A67, [ 2956] = 0x28B64, [ 2957] = 0x98DC, ++ [ 2958] = 0x28A45, [ 2959] = 0x3F00, [ 2960] = 0x922A, [ 2961] = 0x4925, ++ [ 2962] = 0x8414, [ 2963] = 0x993B, [ 2964] = 0x994D, [ 2965] = 0x27B06, ++ [ 2966] = 0x3DFD, [ 2967] = 0x999B, [ 2968] = 0x4B6F, [ 2969] = 0x99AA, ++ [ 2970] = 0x9A5C, [ 2971] = 0x28B65, [ 2972] = 0x258C8, [ 2973] = 0x6A8F, ++ [ 2974] = 0x9A21, [ 2975] = 0x5AFE, [ 2976] = 0x9A2F, [ 2977] = 0x298F1, ++ [ 2978] = 0x4B90, [ 2979] = 0x29948, [ 2980] = 0x99BC, [ 2981] = 0x4BBD, ++ [ 2982] = 0x4B97, [ 2983] = 0x937D, [ 2984] = 0x5872, [ 2985] = 0x21302, ++ [ 2986] = 0x5822, [ 2987] = 0x249B8, [ 3022] = 0x214E8, [ 3023] = 0x7844, ++ [ 3024] = 0x2271F, [ 3025] = 0x23DB8, [ 3026] = 0x68C5, [ 3027] = 0x3D7D, ++ [ 3028] = 0x9458, [ 3029] = 0x3927, [ 3030] = 0x6150, [ 3031] = 0x22781, ++ [ 3032] = 0x2296B, [ 3033] = 0x6107, [ 3034] = 0x9C4F, [ 3035] = 0x9C53, ++ [ 3036] = 0x9C7B, [ 3037] = 0x9C35, [ 3038] = 0x9C10, [ 3039] = 0x9B7F, ++ [ 3040] = 0x9BCF, [ 3041] = 0x29E2D, [ 3042] = 0x9B9F, [ 3043] = 0x2A1F5, ++ [ 3044] = 0x2A0FE, [ 3045] = 0x9D21, [ 3046] = 0x4CAE, [ 3047] = 0x24104, ++ [ 3048] = 0x9E18, [ 3049] = 0x4CB0, [ 3050] = 0x9D0C, [ 3051] = 0x2A1B4, ++ [ 3052] = 0x2A0ED, [ 3053] = 0x2A0F3, [ 3054] = 0x2992F, [ 3055] = 0x9DA5, ++ [ 3056] = 0x84BD, [ 3057] = 0x26E12, [ 3058] = 0x26FDF, [ 3059] = 0x26B82, ++ [ 3060] = 0x85FC, [ 3061] = 0x4533, [ 3062] = 0x26DA4, [ 3063] = 0x26E84, ++ [ 3064] = 0x26DF0, [ 3065] = 0x8420, [ 3066] = 0x85EE, [ 3067] = 0x26E00, ++ [ 3068] = 0x237D7, [ 3069] = 0x26064, [ 3070] = 0x79E2, [ 3071] = 0x2359C, ++ [ 3072] = 0x23640, [ 3073] = 0x492D, [ 3074] = 0x249DE, [ 3075] = 0x3D62, ++ [ 3076] = 0x93DB, [ 3077] = 0x92BE, [ 3078] = 0x9348, [ 3079] = 0x202BF, ++ [ 3080] = 0x78B9, [ 3081] = 0x9277, [ 3082] = 0x944D, [ 3083] = 0x4FE4, ++ [ 3084] = 0x3440, [ 3085] = 0x9064, [ 3086] = 0x2555D, [ 3087] = 0x783D, ++ [ 3088] = 0x7854, [ 3089] = 0x78B6, [ 3090] = 0x784B, [ 3091] = 0x21757, ++ [ 3092] = 0x231C9, [ 3093] = 0x24941, [ 3094] = 0x369A, [ 3095] = 0x4F72, ++ [ 3096] = 0x6FDA, [ 3097] = 0x6FD9, [ 3099] = 0x701E, [ 3100] = 0x5414, ++ [ 3101] = 0x241B5, [ 3102] = 0x57BB, [ 3103] = 0x58F3, [ 3104] = 0x578A, ++ [ 3105] = 0x9D16, [ 3106] = 0x57D7, [ 3107] = 0x7134, [ 3108] = 0x34AF, ++ [ 3109] = 0x241AC, [ 3110] = 0x71EB, [ 3111] = 0x26C40, [ 3112] = 0x24F97, ++ [ 3114] = 0x217B5, [ 3115] = 0x28A49, [ 3120] = 0x610C, [ 3121] = 0x5ACE, ++ [ 3122] = 0x5A0B, [ 3123] = 0x42BC, [ 3124] = 0x24488, [ 3125] = 0x372C, ++ [ 3126] = 0x4B7B, [ 3127] = 0x289FC, [ 3128] = 0x93BB, [ 3129] = 0x93B8, ++ [ 3130] = 0x218D6, [ 3131] = 0x20F1D, [ 3132] = 0x8472, [ 3133] = 0x26CC0, ++ [ 3134] = 0x21413, [ 3135] = 0x242FA, [ 3136] = 0x22C26, [ 3137] = 0x243C1, ++ [ 3138] = 0x5994, [ 3139] = 0x23DB7, [ 3140] = 0x26741, [ 3141] = 0x7DA8, ++ [ 3142] = 0x2615B, [ 3143] = 0x260A4, [ 3144] = 0x249B9, [ 3145] = 0x2498B, ++ [ 3146] = 0x289FA, [ 3147] = 0x92E5, [ 3148] = 0x73E2, [ 3149] = 0x3EE9, ++ [ 3150] = 0x74B4, [ 3151] = 0x28B63, [ 3152] = 0x2189F, [ 3153] = 0x3EE1, ++ [ 3154] = 0x24AB3, [ 3155] = 0x6AD8, [ 3156] = 0x73F3, [ 3157] = 0x73FB, ++ [ 3158] = 0x3ED6, [ 3159] = 0x24A3E, [ 3160] = 0x24A94, [ 3161] = 0x217D9, ++ [ 3162] = 0x24A66, [ 3163] = 0x203A7, [ 3164] = 0x21424, [ 3165] = 0x249E5, ++ [ 3166] = 0x7448, [ 3167] = 0x24916, [ 3168] = 0x70A5, [ 3169] = 0x24976, ++ [ 3170] = 0x9284, [ 3171] = 0x73E6, [ 3172] = 0x935F, [ 3173] = 0x204FE, ++ [ 3174] = 0x9331, [ 3175] = 0x28ACE, [ 3176] = 0x28A16, [ 3177] = 0x9386, ++ [ 3178] = 0x28BE7, [ 3179] = 0x255D5, [ 3180] = 0x4935, [ 3181] = 0x28A82, ++ [ 3182] = 0x716B, [ 3217] = 0x24943, [ 3218] = 0x20CFF, [ 3219] = 0x56A4, ++ [ 3220] = 0x2061A, [ 3221] = 0x20BEB, [ 3222] = 0x20CB8, [ 3223] = 0x5502, ++ [ 3224] = 0x79C4, [ 3225] = 0x217FA, [ 3226] = 0x7DFE, [ 3227] = 0x216C2, ++ [ 3228] = 0x24A50, [ 3229] = 0x21852, [ 3230] = 0x452E, [ 3231] = 0x9401, ++ [ 3232] = 0x370A, [ 3233] = 0x28AC0, [ 3234] = 0x249AD, [ 3235] = 0x59B0, ++ [ 3236] = 0x218BF, [ 3237] = 0x21883, [ 3238] = 0x27484, [ 3239] = 0x5AA1, ++ [ 3240] = 0x36E2, [ 3241] = 0x23D5B, [ 3242] = 0x36B0, [ 3243] = 0x925F, ++ [ 3244] = 0x5A79, [ 3245] = 0x28A81, [ 3246] = 0x21862, [ 3247] = 0x9374, ++ [ 3248] = 0x3CCD, [ 3249] = 0x20AB4, [ 3250] = 0x4A96, [ 3251] = 0x398A, ++ [ 3252] = 0x50F4, [ 3253] = 0x3D69, [ 3254] = 0x3D4C, [ 3255] = 0x2139C, ++ [ 3256] = 0x7175, [ 3257] = 0x42FB, [ 3258] = 0x28218, [ 3259] = 0x6E0F, ++ [ 3260] = 0x290E4, [ 3261] = 0x44EB, [ 3262] = 0x6D57, [ 3263] = 0x27E4F, ++ [ 3264] = 0x7067, [ 3265] = 0x6CAF, [ 3266] = 0x3CD6, [ 3267] = 0x23FED, ++ [ 3268] = 0x23E2D, [ 3269] = 0x6E02, [ 3270] = 0x6F0C, [ 3271] = 0x3D6F, ++ [ 3272] = 0x203F5, [ 3273] = 0x7551, [ 3274] = 0x36BC, [ 3275] = 0x34C8, ++ [ 3276] = 0x4680, [ 3277] = 0x3EDA, [ 3278] = 0x4871, [ 3279] = 0x59C4, ++ [ 3280] = 0x926E, [ 3281] = 0x493E, [ 3282] = 0x8F41, [ 3283] = 0x28C1C, ++ [ 3284] = 0x26BC0, [ 3285] = 0x5812, [ 3286] = 0x57C8, [ 3287] = 0x36D6, ++ [ 3288] = 0x21452, [ 3289] = 0x70FE, [ 3290] = 0x24362, [ 3291] = 0x24A71, ++ [ 3292] = 0x22FE3, [ 3293] = 0x212B0, [ 3294] = 0x223BD, [ 3295] = 0x68B9, ++ [ 3296] = 0x6967, [ 3297] = 0x21398, [ 3298] = 0x234E5, [ 3299] = 0x27BF4, ++ [ 3300] = 0x236DF, [ 3301] = 0x28A83, [ 3302] = 0x237D6, [ 3303] = 0x233FA, ++ [ 3304] = 0x24C9F, [ 3305] = 0x6A1A, [ 3306] = 0x236AD, [ 3307] = 0x26CB7, ++ [ 3308] = 0x843E, [ 3309] = 0x44DF, [ 3310] = 0x44CE, [ 3315] = 0x26D26, ++ [ 3316] = 0x26D51, [ 3317] = 0x26C82, [ 3318] = 0x26FDE, [ 3319] = 0x6F17, ++ [ 3320] = 0x27109, [ 3321] = 0x833D, [ 3322] = 0x2173A, [ 3323] = 0x83ED, ++ [ 3324] = 0x26C80, [ 3325] = 0x27053, [ 3326] = 0x217DB, [ 3327] = 0x5989, ++ [ 3328] = 0x5A82, [ 3329] = 0x217B3, [ 3330] = 0x5A61, [ 3331] = 0x5A71, ++ [ 3332] = 0x21905, [ 3333] = 0x241FC, [ 3334] = 0x372D, [ 3335] = 0x59EF, ++ [ 3336] = 0x2173C, [ 3337] = 0x36C7, [ 3338] = 0x718E, [ 3339] = 0x9390, ++ [ 3340] = 0x669A, [ 3341] = 0x242A5, [ 3342] = 0x5A6E, [ 3343] = 0x5A2B, ++ [ 3344] = 0x24293, [ 3345] = 0x6A2B, [ 3346] = 0x23EF9, [ 3347] = 0x27736, ++ [ 3348] = 0x2445B, [ 3349] = 0x242CA, [ 3350] = 0x711D, [ 3351] = 0x24259, ++ [ 3352] = 0x289E1, [ 3353] = 0x4FB0, [ 3354] = 0x26D28, [ 3355] = 0x5CC2, ++ [ 3356] = 0x244CE, [ 3357] = 0x27E4D, [ 3358] = 0x243BD, [ 3359] = 0x6A0C, ++ [ 3360] = 0x24256, [ 3361] = 0x21304, [ 3362] = 0x70A6, [ 3363] = 0x7133, ++ [ 3364] = 0x243E9, [ 3365] = 0x3DA5, [ 3366] = 0x6CDF, [ 3367] = 0x2F825, ++ [ 3368] = 0x24A4F, [ 3369] = 0x7E65, [ 3370] = 0x59EB, [ 3371] = 0x5D2F, ++ [ 3372] = 0x3DF3, [ 3373] = 0x5F5C, [ 3374] = 0x24A5D, [ 3375] = 0x217DF, ++ [ 3376] = 0x7DA4, [ 3377] = 0x8426, [ 3412] = 0x5485, [ 3413] = 0x23AFA, ++ [ 3414] = 0x23300, [ 3415] = 0x20214, [ 3416] = 0x577E, [ 3417] = 0x208D5, ++ [ 3418] = 0x20619, [ 3419] = 0x3FE5, [ 3420] = 0x21F9E, [ 3421] = 0x2A2B6, ++ [ 3422] = 0x7003, [ 3423] = 0x2915B, [ 3424] = 0x5D70, [ 3425] = 0x738F, ++ [ 3426] = 0x7CD3, [ 3427] = 0x28A59, [ 3428] = 0x29420, [ 3429] = 0x4FC8, ++ [ 3430] = 0x7FE7, [ 3431] = 0x72CD, [ 3432] = 0x7310, [ 3433] = 0x27AF4, ++ [ 3434] = 0x7338, [ 3435] = 0x7339, [ 3436] = 0x256F6, [ 3437] = 0x7341, ++ [ 3438] = 0x7348, [ 3439] = 0x3EA9, [ 3440] = 0x27B18, [ 3441] = 0x906C, ++ [ 3442] = 0x71F5, [ 3443] = 0x248F2, [ 3444] = 0x73E1, [ 3445] = 0x81F6, ++ [ 3446] = 0x3ECA, [ 3447] = 0x770C, [ 3448] = 0x3ED1, [ 3449] = 0x6CA2, ++ [ 3450] = 0x56FD, [ 3451] = 0x7419, [ 3452] = 0x741E, [ 3453] = 0x741F, ++ [ 3454] = 0x3EE2, [ 3455] = 0x3EF0, [ 3456] = 0x3EF4, [ 3457] = 0x3EFA, ++ [ 3458] = 0x74D3, [ 3459] = 0x3F0E, [ 3460] = 0x3F53, [ 3461] = 0x7542, ++ [ 3462] = 0x756D, [ 3463] = 0x7572, [ 3464] = 0x758D, [ 3465] = 0x3F7C, ++ [ 3466] = 0x75C8, [ 3467] = 0x75DC, [ 3468] = 0x3FC0, [ 3469] = 0x764D, ++ [ 3470] = 0x3FD7, [ 3471] = 0x7674, [ 3472] = 0x3FDC, [ 3473] = 0x767A, ++ [ 3474] = 0x24F5C, [ 3475] = 0x7188, [ 3476] = 0x5623, [ 3477] = 0x8980, ++ [ 3478] = 0x5869, [ 3479] = 0x401D, [ 3480] = 0x7743, [ 3481] = 0x4039, ++ [ 3482] = 0x6761, [ 3483] = 0x4045, [ 3484] = 0x35DB, [ 3485] = 0x7798, ++ [ 3486] = 0x406A, [ 3487] = 0x406F, [ 3488] = 0x5C5E, [ 3489] = 0x77BE, ++ [ 3490] = 0x77CB, [ 3491] = 0x58F2, [ 3492] = 0x7818, [ 3493] = 0x70B9, ++ [ 3494] = 0x781C, [ 3495] = 0x40A8, [ 3496] = 0x7839, [ 3497] = 0x7847, ++ [ 3498] = 0x7851, [ 3499] = 0x7866, [ 3500] = 0x8448, [ 3501] = 0x25535, ++ [ 3502] = 0x7933, [ 3503] = 0x6803, [ 3504] = 0x7932, [ 3505] = 0x4103, ++ [ 3510] = 0x4109, [ 3511] = 0x7991, [ 3512] = 0x7999, [ 3513] = 0x8FBB, ++ [ 3514] = 0x7A06, [ 3515] = 0x8FBC, [ 3516] = 0x4167, [ 3517] = 0x7A91, ++ [ 3518] = 0x41B2, [ 3519] = 0x7ABC, [ 3520] = 0x8279, [ 3521] = 0x41C4, ++ [ 3522] = 0x7ACF, [ 3523] = 0x7ADB, [ 3524] = 0x41CF, [ 3525] = 0x4E21, ++ [ 3526] = 0x7B62, [ 3527] = 0x7B6C, [ 3528] = 0x7B7B, [ 3529] = 0x7C12, ++ [ 3530] = 0x7C1B, [ 3531] = 0x4260, [ 3532] = 0x427A, [ 3533] = 0x7C7B, ++ [ 3534] = 0x7C9C, [ 3535] = 0x428C, [ 3536] = 0x7CB8, [ 3537] = 0x4294, ++ [ 3538] = 0x7CED, [ 3539] = 0x8F93, [ 3540] = 0x70C0, [ 3541] = 0x20CCF, ++ [ 3542] = 0x7DCF, [ 3543] = 0x7DD4, [ 3544] = 0x7DD0, [ 3545] = 0x7DFD, ++ [ 3546] = 0x7FAE, [ 3547] = 0x7FB4, [ 3548] = 0x729F, [ 3549] = 0x4397, ++ [ 3550] = 0x8020, [ 3551] = 0x8025, [ 3552] = 0x7B39, [ 3553] = 0x802E, ++ [ 3554] = 0x8031, [ 3555] = 0x8054, [ 3556] = 0x3DCC, [ 3557] = 0x57B4, ++ [ 3558] = 0x70A0, [ 3559] = 0x80B7, [ 3560] = 0x80E9, [ 3561] = 0x43ED, ++ [ 3562] = 0x810C, [ 3563] = 0x732A, [ 3564] = 0x810E, [ 3565] = 0x8112, ++ [ 3566] = 0x7560, [ 3567] = 0x8114, [ 3568] = 0x4401, [ 3569] = 0x3B39, ++ [ 3570] = 0x8156, [ 3571] = 0x8159, [ 3572] = 0x815A, [ 3607] = 0x4413, ++ [ 3608] = 0x583A, [ 3609] = 0x817C, [ 3610] = 0x8184, [ 3611] = 0x4425, ++ [ 3612] = 0x8193, [ 3613] = 0x442D, [ 3614] = 0x81A5, [ 3615] = 0x57EF, ++ [ 3616] = 0x81C1, [ 3617] = 0x81E4, [ 3618] = 0x8254, [ 3619] = 0x448F, ++ [ 3620] = 0x82A6, [ 3621] = 0x8276, [ 3622] = 0x82CA, [ 3623] = 0x82D8, ++ [ 3624] = 0x82FF, [ 3625] = 0x44B0, [ 3626] = 0x8357, [ 3627] = 0x9669, ++ [ 3628] = 0x698A, [ 3629] = 0x8405, [ 3630] = 0x70F5, [ 3631] = 0x8464, ++ [ 3632] = 0x60E3, [ 3633] = 0x8488, [ 3634] = 0x4504, [ 3635] = 0x84BE, ++ [ 3636] = 0x84E1, [ 3637] = 0x84F8, [ 3638] = 0x8510, [ 3639] = 0x8538, ++ [ 3640] = 0x8552, [ 3641] = 0x453B, [ 3642] = 0x856F, [ 3643] = 0x8570, ++ [ 3644] = 0x85E0, [ 3645] = 0x4577, [ 3646] = 0x8672, [ 3647] = 0x8692, ++ [ 3648] = 0x86B2, [ 3649] = 0x86EF, [ 3650] = 0x9645, [ 3651] = 0x878B, ++ [ 3652] = 0x4606, [ 3653] = 0x4617, [ 3654] = 0x88AE, [ 3655] = 0x88FF, ++ [ 3656] = 0x8924, [ 3657] = 0x8947, [ 3658] = 0x8991, [ 3659] = 0x27967, ++ [ 3660] = 0x8A29, [ 3661] = 0x8A38, [ 3662] = 0x8A94, [ 3663] = 0x8AB4, ++ [ 3664] = 0x8C51, [ 3665] = 0x8CD4, [ 3666] = 0x8CF2, [ 3667] = 0x8D1C, ++ [ 3668] = 0x4798, [ 3669] = 0x585F, [ 3670] = 0x8DC3, [ 3671] = 0x47ED, ++ [ 3672] = 0x4EEE, [ 3673] = 0x8E3A, [ 3674] = 0x55D8, [ 3675] = 0x5754, ++ [ 3676] = 0x8E71, [ 3677] = 0x55F5, [ 3678] = 0x8EB0, [ 3679] = 0x4837, ++ [ 3680] = 0x8ECE, [ 3681] = 0x8EE2, [ 3682] = 0x8EE4, [ 3683] = 0x8EED, ++ [ 3684] = 0x8EF2, [ 3685] = 0x8FB7, [ 3686] = 0x8FC1, [ 3687] = 0x8FCA, ++ [ 3688] = 0x8FCC, [ 3689] = 0x9033, [ 3690] = 0x99C4, [ 3691] = 0x48AD, ++ [ 3692] = 0x98E0, [ 3693] = 0x9213, [ 3694] = 0x491E, [ 3695] = 0x9228, ++ [ 3696] = 0x9258, [ 3697] = 0x926B, [ 3698] = 0x92B1, [ 3699] = 0x92AE, ++ [ 3700] = 0x92BF, [ 3705] = 0x92E3, [ 3706] = 0x92EB, [ 3707] = 0x92F3, ++ [ 3708] = 0x92F4, [ 3709] = 0x92FD, [ 3710] = 0x9343, [ 3711] = 0x9384, ++ [ 3712] = 0x93AD, [ 3713] = 0x4945, [ 3714] = 0x4951, [ 3715] = 0x9EBF, ++ [ 3716] = 0x9417, [ 3717] = 0x5301, [ 3718] = 0x941D, [ 3719] = 0x942D, ++ [ 3720] = 0x943E, [ 3721] = 0x496A, [ 3722] = 0x9454, [ 3723] = 0x9479, ++ [ 3724] = 0x952D, [ 3725] = 0x95A2, [ 3726] = 0x49A7, [ 3727] = 0x95F4, ++ [ 3728] = 0x9633, [ 3729] = 0x49E5, [ 3730] = 0x67A0, [ 3731] = 0x4A24, ++ [ 3732] = 0x9740, [ 3733] = 0x4A35, [ 3734] = 0x97B2, [ 3735] = 0x97C2, ++ [ 3736] = 0x5654, [ 3737] = 0x4AE4, [ 3738] = 0x60E8, [ 3739] = 0x98B9, ++ [ 3740] = 0x4B19, [ 3741] = 0x98F1, [ 3742] = 0x5844, [ 3743] = 0x990E, ++ [ 3744] = 0x9919, [ 3745] = 0x51B4, [ 3746] = 0x991C, [ 3747] = 0x9937, ++ [ 3748] = 0x9942, [ 3749] = 0x995D, [ 3750] = 0x9962, [ 3751] = 0x4B70, ++ [ 3752] = 0x99C5, [ 3753] = 0x4B9D, [ 3754] = 0x9A3C, [ 3755] = 0x9B0F, ++ [ 3756] = 0x7A83, [ 3757] = 0x9B69, [ 3758] = 0x9B81, [ 3759] = 0x9BDD, ++ [ 3760] = 0x9BF1, [ 3761] = 0x9BF4, [ 3762] = 0x4C6D, [ 3763] = 0x9C20, ++ [ 3764] = 0x376F, [ 3765] = 0x21BC2, [ 3766] = 0x9D49, [ 3767] = 0x9C3A, ++ [ 3802] = 0x9EFE, [ 3803] = 0x5650, [ 3804] = 0x9D93, [ 3805] = 0x9DBD, ++ [ 3806] = 0x9DC0, [ 3807] = 0x9DFC, [ 3808] = 0x94F6, [ 3809] = 0x8FB6, ++ [ 3810] = 0x9E7B, [ 3811] = 0x9EAC, [ 3812] = 0x9EB1, [ 3813] = 0x9EBD, ++ [ 3814] = 0x9EC6, [ 3815] = 0x94DC, [ 3816] = 0x9EE2, [ 3817] = 0x9EF1, ++ [ 3818] = 0x9EF8, [ 3819] = 0x7AC8, [ 3820] = 0x9F44, [ 3821] = 0x20094, ++ [ 3822] = 0x202B7, [ 3823] = 0x203A0, [ 3824] = 0x691A, [ 3825] = 0x94C3, ++ [ 3826] = 0x59AC, [ 3827] = 0x204D7, [ 3828] = 0x5840, [ 3829] = 0x94C1, ++ [ 3830] = 0x37B9, [ 3831] = 0x205D5, [ 3832] = 0x20615, [ 3833] = 0x20676, ++ [ 3834] = 0x216BA, [ 3835] = 0x5757, [ 3836] = 0x7173, [ 3837] = 0x20AC2, ++ [ 3838] = 0x20ACD, [ 3839] = 0x20BBF, [ 3840] = 0x546A, [ 3841] = 0x2F83B, ++ [ 3842] = 0x20BCB, [ 3843] = 0x549E, [ 3844] = 0x20BFB, [ 3845] = 0x20C3B, ++ [ 3846] = 0x20C53, [ 3847] = 0x20C65, [ 3848] = 0x20C7C, [ 3849] = 0x60E7, ++ [ 3850] = 0x20C8D, [ 3851] = 0x567A, [ 3852] = 0x20CB5, [ 3853] = 0x20CDD, ++ [ 3854] = 0x20CED, [ 3855] = 0x20D6F, [ 3856] = 0x20DB2, [ 3857] = 0x20DC8, ++ [ 3858] = 0x6955, [ 3859] = 0x9C2F, [ 3860] = 0x87A5, [ 3861] = 0x20E04, ++ [ 3862] = 0x20E0E, [ 3863] = 0x20ED7, [ 3864] = 0x20F90, [ 3865] = 0x20F2D, ++ [ 3866] = 0x20E73, [ 3867] = 0x5C20, [ 3868] = 0x20FBC, [ 3869] = 0x5E0B, ++ [ 3870] = 0x2105C, [ 3871] = 0x2104F, [ 3872] = 0x21076, [ 3873] = 0x671E, ++ [ 3874] = 0x2107B, [ 3875] = 0x21088, [ 3876] = 0x21096, [ 3877] = 0x3647, ++ [ 3878] = 0x210BF, [ 3879] = 0x210D3, [ 3880] = 0x2112F, [ 3881] = 0x2113B, ++ [ 3882] = 0x5364, [ 3883] = 0x84AD, [ 3884] = 0x212E3, [ 3885] = 0x21375, ++ [ 3886] = 0x21336, [ 3887] = 0x8B81, [ 3888] = 0x21577, [ 3889] = 0x21619, ++ [ 3890] = 0x217C3, [ 3891] = 0x217C7, [ 3892] = 0x4E78, [ 3893] = 0x70BB, ++ [ 3894] = 0x2182D, [ 3895] = 0x2196A, [ 3900] = 0x21A2D, [ 3901] = 0x21A45, ++ [ 3902] = 0x21C2A, [ 3903] = 0x21C70, [ 3904] = 0x21CAC, [ 3905] = 0x21EC8, ++ [ 3906] = 0x62C3, [ 3907] = 0x21ED5, [ 3908] = 0x21F15, [ 3909] = 0x7198, ++ [ 3910] = 0x6855, [ 3911] = 0x22045, [ 3912] = 0x69E9, [ 3913] = 0x36C8, ++ [ 3914] = 0x2227C, [ 3915] = 0x223D7, [ 3916] = 0x223FA, [ 3917] = 0x2272A, ++ [ 3918] = 0x22871, [ 3919] = 0x2294F, [ 3920] = 0x82FD, [ 3921] = 0x22967, ++ [ 3922] = 0x22993, [ 3923] = 0x22AD5, [ 3924] = 0x89A5, [ 3925] = 0x22AE8, ++ [ 3926] = 0x8FA0, [ 3927] = 0x22B0E, [ 3928] = 0x97B8, [ 3929] = 0x22B3F, ++ [ 3930] = 0x9847, [ 3931] = 0x9ABD, [ 3932] = 0x22C4C, [ 3934] = 0x22C88, ++ [ 3935] = 0x22CB7, [ 3936] = 0x25BE8, [ 3937] = 0x22D08, [ 3938] = 0x22D12, ++ [ 3939] = 0x22DB7, [ 3940] = 0x22D95, [ 3941] = 0x22E42, [ 3942] = 0x22F74, ++ [ 3943] = 0x22FCC, [ 3944] = 0x23033, [ 3945] = 0x23066, [ 3946] = 0x2331F, ++ [ 3947] = 0x233DE, [ 3948] = 0x5FB1, [ 3949] = 0x6648, [ 3950] = 0x66BF, ++ [ 3951] = 0x27A79, [ 3952] = 0x23567, [ 3953] = 0x235F3, [ 3955] = 0x249BA, ++ [ 3957] = 0x2361A, [ 3958] = 0x23716, [ 3960] = 0x20346, [ 3961] = 0x58B5, ++ [ 3962] = 0x670E, [ 3997] = 0x6918, [ 3998] = 0x23AA7, [ 3999] = 0x27657, ++ [ 4000] = 0x25FE2, [ 4001] = 0x23E11, [ 4002] = 0x23EB9, [ 4003] = 0x275FE, ++ [ 4004] = 0x2209A, [ 4005] = 0x48D0, [ 4006] = 0x4AB8, [ 4007] = 0x24119, ++ [ 4008] = 0x28A9A, [ 4009] = 0x242EE, [ 4010] = 0x2430D, [ 4011] = 0x2403B, ++ [ 4012] = 0x24334, [ 4013] = 0x24396, [ 4014] = 0x24A45, [ 4015] = 0x205CA, ++ [ 4016] = 0x51D2, [ 4017] = 0x20611, [ 4018] = 0x599F, [ 4019] = 0x21EA8, ++ [ 4020] = 0x3BBE, [ 4021] = 0x23CFF, [ 4022] = 0x24404, [ 4023] = 0x244D6, ++ [ 4024] = 0x5788, [ 4025] = 0x24674, [ 4026] = 0x399B, [ 4027] = 0x2472F, ++ [ 4028] = 0x285E8, [ 4029] = 0x299C9, [ 4030] = 0x3762, [ 4031] = 0x221C3, ++ [ 4032] = 0x8B5E, [ 4033] = 0x28B4E, [ 4035] = 0x24812, [ 4036] = 0x248FB, ++ [ 4037] = 0x24A15, [ 4038] = 0x7209, [ 4039] = 0x24AC0, [ 4040] = 0x20C78, ++ [ 4041] = 0x5965, [ 4042] = 0x24EA5, [ 4043] = 0x24F86, [ 4044] = 0x20779, ++ [ 4045] = 0x8EDA, [ 4046] = 0x2502C, [ 4047] = 0x528F, [ 4048] = 0x573F, ++ [ 4049] = 0x7171, [ 4050] = 0x25299, [ 4051] = 0x25419, [ 4052] = 0x23F4A, ++ [ 4053] = 0x24AA7, [ 4054] = 0x55BC, [ 4055] = 0x25446, [ 4056] = 0x2546E, ++ [ 4057] = 0x26B52, [ 4059] = 0x3473, [ 4060] = 0x2553F, [ 4061] = 0x27632, ++ [ 4062] = 0x2555E, [ 4063] = 0x4718, [ 4064] = 0x25562, [ 4065] = 0x25566, ++ [ 4066] = 0x257C7, [ 4067] = 0x2493F, [ 4068] = 0x2585D, [ 4069] = 0x5066, ++ [ 4070] = 0x34FB, [ 4071] = 0x233CC, [ 4073] = 0x25903, [ 4074] = 0x477C, ++ [ 4075] = 0x28948, [ 4076] = 0x25AAE, [ 4077] = 0x25B89, [ 4078] = 0x25C06, ++ [ 4079] = 0x21D90, [ 4080] = 0x57A1, [ 4081] = 0x7151, [ 4083] = 0x26102, ++ [ 4084] = 0x27C12, [ 4085] = 0x9056, [ 4086] = 0x261B2, [ 4087] = 0x24F9A, ++ [ 4088] = 0x8B62, [ 4089] = 0x26402, [ 4090] = 0x2644A, [ 4095] = 0x5D5B, ++ [ 4096] = 0x26BF7, [ 4098] = 0x26484, [ 4099] = 0x2191C, [ 4100] = 0x8AEA, ++ [ 4101] = 0x249F6, [ 4102] = 0x26488, [ 4103] = 0x23FEF, [ 4104] = 0x26512, ++ [ 4105] = 0x4BC0, [ 4106] = 0x265BF, [ 4107] = 0x266B5, [ 4108] = 0x2271B, ++ [ 4109] = 0x9465, [ 4110] = 0x257E1, [ 4111] = 0x6195, [ 4112] = 0x5A27, ++ [ 4113] = 0x2F8CD, [ 4115] = 0x56B9, [ 4116] = 0x24521, [ 4117] = 0x266FC, ++ [ 4118] = 0x4E6A, [ 4119] = 0x24934, [ 4120] = 0x9656, [ 4121] = 0x6D8F, ++ [ 4122] = 0x26CBD, [ 4123] = 0x3618, [ 4124] = 0x8977, [ 4125] = 0x26799, ++ [ 4126] = 0x2686E, [ 4127] = 0x26411, [ 4128] = 0x2685E, [ 4130] = 0x268C7, ++ [ 4131] = 0x7B42, [ 4132] = 0x290C0, [ 4133] = 0x20A11, [ 4134] = 0x26926, ++ [ 4136] = 0x26939, [ 4137] = 0x7A45, [ 4139] = 0x269FA, [ 4140] = 0x9A26, ++ [ 4141] = 0x26A2D, [ 4142] = 0x365F, [ 4143] = 0x26469, [ 4144] = 0x20021, ++ [ 4145] = 0x7983, [ 4146] = 0x26A34, [ 4147] = 0x26B5B, [ 4148] = 0x5D2C, ++ [ 4149] = 0x23519, [ 4151] = 0x26B9D, [ 4152] = 0x46D0, [ 4153] = 0x26CA4, ++ [ 4154] = 0x753B, [ 4155] = 0x8865, [ 4156] = 0x26DAE, [ 4157] = 0x58B6, ++ [ 4192] = 0x371C, [ 4193] = 0x2258D, [ 4194] = 0x2704B, [ 4195] = 0x271CD, ++ [ 4196] = 0x3C54, [ 4197] = 0x27280, [ 4198] = 0x27285, [ 4199] = 0x9281, ++ [ 4200] = 0x2217A, [ 4201] = 0x2728B, [ 4202] = 0x9330, [ 4203] = 0x272E6, ++ [ 4204] = 0x249D0, [ 4205] = 0x6C39, [ 4206] = 0x949F, [ 4207] = 0x27450, ++ [ 4208] = 0x20EF8, [ 4209] = 0x8827, [ 4210] = 0x88F5, [ 4211] = 0x22926, ++ [ 4212] = 0x28473, [ 4213] = 0x217B1, [ 4214] = 0x6EB8, [ 4215] = 0x24A2A, ++ [ 4216] = 0x21820, [ 4217] = 0x39A4, [ 4218] = 0x36B9, [ 4221] = 0x453F, ++ [ 4222] = 0x66B6, [ 4223] = 0x29CAD, [ 4224] = 0x298A4, [ 4225] = 0x8943, ++ [ 4226] = 0x277CC, [ 4227] = 0x27858, [ 4228] = 0x56D6, [ 4229] = 0x40DF, ++ [ 4230] = 0x2160A, [ 4231] = 0x39A1, [ 4232] = 0x2372F, [ 4233] = 0x280E8, ++ [ 4234] = 0x213C5, [ 4235] = 0x71AD, [ 4236] = 0x8366, [ 4237] = 0x279DD, ++ [ 4238] = 0x291A8, [ 4240] = 0x4CB7, [ 4241] = 0x270AF, [ 4242] = 0x289AB, ++ [ 4243] = 0x279FD, [ 4244] = 0x27A0A, [ 4245] = 0x27B0B, [ 4246] = 0x27D66, ++ [ 4247] = 0x2417A, [ 4248] = 0x7B43, [ 4249] = 0x797E, [ 4250] = 0x28009, ++ [ 4251] = 0x6FB5, [ 4252] = 0x2A2DF, [ 4253] = 0x6A03, [ 4254] = 0x28318, ++ [ 4255] = 0x53A2, [ 4256] = 0x26E07, [ 4257] = 0x93BF, [ 4258] = 0x6836, ++ [ 4259] = 0x975D, [ 4260] = 0x2816F, [ 4261] = 0x28023, [ 4262] = 0x269B5, ++ [ 4263] = 0x213ED, [ 4264] = 0x2322F, [ 4265] = 0x28048, [ 4266] = 0x5D85, ++ [ 4267] = 0x28C30, [ 4268] = 0x28083, [ 4269] = 0x5715, [ 4270] = 0x9823, ++ [ 4271] = 0x28949, [ 4272] = 0x5DAB, [ 4273] = 0x24988, [ 4274] = 0x65BE, ++ [ 4275] = 0x69D5, [ 4276] = 0x53D2, [ 4277] = 0x24AA5, [ 4278] = 0x23F81, ++ [ 4279] = 0x3C11, [ 4280] = 0x6736, [ 4281] = 0x28090, [ 4282] = 0x280F4, ++ [ 4283] = 0x2812E, [ 4284] = 0x21FA1, [ 4285] = 0x2814F, [ 4290] = 0x28189, ++ [ 4291] = 0x281AF, [ 4292] = 0x2821A, [ 4293] = 0x28306, [ 4294] = 0x2832F, ++ [ 4295] = 0x2838A, [ 4296] = 0x35CA, [ 4297] = 0x28468, [ 4298] = 0x286AA, ++ [ 4299] = 0x48FA, [ 4300] = 0x63E6, [ 4301] = 0x28956, [ 4302] = 0x7808, ++ [ 4303] = 0x9255, [ 4304] = 0x289B8, [ 4305] = 0x43F2, [ 4306] = 0x289E7, ++ [ 4307] = 0x43DF, [ 4308] = 0x289E8, [ 4309] = 0x28B46, [ 4310] = 0x28BD4, ++ [ 4311] = 0x59F8, [ 4312] = 0x28C09, [ 4314] = 0x28FC5, [ 4315] = 0x290EC, ++ [ 4317] = 0x29110, [ 4318] = 0x2913C, [ 4319] = 0x3DF7, [ 4320] = 0x2915E, ++ [ 4321] = 0x24ACA, [ 4322] = 0x8FD0, [ 4323] = 0x728F, [ 4324] = 0x568B, ++ [ 4325] = 0x294E7, [ 4326] = 0x295E9, [ 4327] = 0x295B0, [ 4328] = 0x295B8, ++ [ 4329] = 0x29732, [ 4330] = 0x298D1, [ 4331] = 0x29949, [ 4332] = 0x2996A, ++ [ 4333] = 0x299C3, [ 4334] = 0x29A28, [ 4335] = 0x29B0E, [ 4336] = 0x29D5A, ++ [ 4337] = 0x29D9B, [ 4338] = 0x7E9F, [ 4339] = 0x29EF8, [ 4340] = 0x29F23, ++ [ 4341] = 0x4CA4, [ 4342] = 0x9547, [ 4343] = 0x2A293, [ 4344] = 0x71A2, ++ [ 4345] = 0x2A2FF, [ 4346] = 0x4D91, [ 4347] = 0x9012, [ 4348] = 0x2A5CB, ++ [ 4349] = 0x4D9C, [ 4350] = 0x20C9C, [ 4351] = 0x8FBE, [ 4352] = 0x55C1, ++ [ 4387] = 0x8FBA, [ 4388] = 0x224B0, [ 4389] = 0x8FB9, [ 4390] = 0x24A93, ++ [ 4391] = 0x4509, [ 4392] = 0x7E7F, [ 4393] = 0x6F56, [ 4394] = 0x6AB1, ++ [ 4395] = 0x4EEA, [ 4396] = 0x34E4, [ 4397] = 0x28B2C, [ 4398] = 0x2789D, ++ [ 4399] = 0x373A, [ 4400] = 0x8E80, [ 4401] = 0x217F5, [ 4402] = 0x28024, ++ [ 4403] = 0x28B6C, [ 4404] = 0x28B99, [ 4405] = 0x27A3E, [ 4406] = 0x266AF, ++ [ 4407] = 0x3DEB, [ 4408] = 0x27655, [ 4409] = 0x23CB7, [ 4410] = 0x25635, ++ [ 4411] = 0x25956, [ 4412] = 0x4E9A, [ 4413] = 0x25E81, [ 4414] = 0x26258, ++ [ 4415] = 0x56BF, [ 4416] = 0x20E6D, [ 4417] = 0x8E0E, [ 4418] = 0x5B6D, ++ [ 4419] = 0x23E88, [ 4420] = 0x24C9E, [ 4421] = 0x63DE, [ 4423] = 0x217F6, ++ [ 4424] = 0x2187B, [ 4425] = 0x6530, [ 4426] = 0x562D, [ 4427] = 0x25C4A, ++ [ 4428] = 0x541A, [ 4429] = 0x25311, [ 4430] = 0x3DC6, [ 4431] = 0x29D98, ++ [ 4432] = 0x4C7D, [ 4433] = 0x5622, [ 4434] = 0x561E, [ 4435] = 0x7F49, ++ [ 4436] = 0x25ED8, [ 4437] = 0x5975, [ 4438] = 0x23D40, [ 4439] = 0x8770, ++ [ 4440] = 0x4E1C, [ 4441] = 0x20FEA, [ 4442] = 0x20D49, [ 4443] = 0x236BA, ++ [ 4444] = 0x8117, [ 4445] = 0x9D5E, [ 4446] = 0x8D18, [ 4447] = 0x763B, ++ [ 4448] = 0x9C45, [ 4449] = 0x764E, [ 4450] = 0x77B9, [ 4451] = 0x9345, ++ [ 4452] = 0x5432, [ 4453] = 0x8148, [ 4454] = 0x82F7, [ 4455] = 0x5625, ++ [ 4456] = 0x8132, [ 4457] = 0x8418, [ 4458] = 0x80BD, [ 4459] = 0x55EA, ++ [ 4460] = 0x7962, [ 4461] = 0x5643, [ 4462] = 0x5416, [ 4463] = 0x20E9D, ++ [ 4464] = 0x35CE, [ 4465] = 0x5605, [ 4466] = 0x55F1, [ 4467] = 0x66F1, ++ [ 4468] = 0x282E2, [ 4469] = 0x362D, [ 4470] = 0x7534, [ 4471] = 0x55F0, ++ [ 4472] = 0x55BA, [ 4473] = 0x5497, [ 4474] = 0x5572, [ 4475] = 0x20C41, ++ [ 4476] = 0x20C96, [ 4477] = 0x5ED0, [ 4478] = 0x25148, [ 4479] = 0x20E76, ++ [ 4480] = 0x22C62, [ 4485] = 0x20EA2, [ 4486] = 0x9EAB, [ 4487] = 0x7D5A, ++ [ 4488] = 0x55DE, [ 4489] = 0x21075, [ 4490] = 0x629D, [ 4491] = 0x976D, ++ [ 4492] = 0x5494, [ 4493] = 0x8CCD, [ 4494] = 0x71F6, [ 4495] = 0x9176, ++ [ 4496] = 0x63FC, [ 4497] = 0x63B9, [ 4498] = 0x63FE, [ 4499] = 0x5569, ++ [ 4500] = 0x22B43, [ 4501] = 0x9C72, [ 4502] = 0x22EB3, [ 4503] = 0x519A, ++ [ 4504] = 0x34DF, [ 4505] = 0x20DA7, [ 4506] = 0x51A7, [ 4507] = 0x544D, ++ [ 4508] = 0x551E, [ 4509] = 0x5513, [ 4510] = 0x7666, [ 4511] = 0x8E2D, ++ [ 4512] = 0x2688A, [ 4513] = 0x75B1, [ 4514] = 0x80B6, [ 4515] = 0x8804, ++ [ 4516] = 0x8786, [ 4517] = 0x88C7, [ 4518] = 0x81B6, [ 4519] = 0x841C, ++ [ 4520] = 0x210C1, [ 4521] = 0x44EC, [ 4522] = 0x7304, [ 4523] = 0x24706, ++ [ 4524] = 0x5B90, [ 4525] = 0x830B, [ 4526] = 0x26893, [ 4527] = 0x567B, ++ [ 4528] = 0x226F4, [ 4529] = 0x27D2F, [ 4530] = 0x241A3, [ 4531] = 0x27D73, ++ [ 4532] = 0x26ED0, [ 4533] = 0x272B6, [ 4534] = 0x9170, [ 4535] = 0x211D9, ++ [ 4536] = 0x9208, [ 4537] = 0x23CFC, [ 4538] = 0x2A6A9, [ 4539] = 0x20EAC, ++ [ 4540] = 0x20EF9, [ 4541] = 0x7266, [ 4542] = 0x21CA2, [ 4543] = 0x474E, ++ [ 4544] = 0x24FC2, [ 4545] = 0x27FF9, [ 4546] = 0x20FEB, [ 4547] = 0x40FA, ++ [ 4582] = 0x9C5D, [ 4583] = 0x651F, [ 4584] = 0x22DA0, [ 4585] = 0x48F3, ++ [ 4586] = 0x247E0, [ 4587] = 0x29D7C, [ 4588] = 0x20FEC, [ 4589] = 0x20E0A, ++ [ 4591] = 0x275A3, [ 4592] = 0x20FED, [ 4594] = 0x26048, [ 4595] = 0x21187, ++ [ 4596] = 0x71A3, [ 4597] = 0x7E8E, [ 4598] = 0x9D50, [ 4599] = 0x4E1A, ++ [ 4600] = 0x4E04, [ 4601] = 0x3577, [ 4602] = 0x5B0D, [ 4603] = 0x6CB2, ++ [ 4604] = 0x5367, [ 4605] = 0x36AC, [ 4606] = 0x39DC, [ 4607] = 0x537D, ++ [ 4608] = 0x36A5, [ 4609] = 0x24618, [ 4610] = 0x589A, [ 4611] = 0x24B6E, ++ [ 4612] = 0x822D, [ 4613] = 0x544B, [ 4614] = 0x57AA, [ 4615] = 0x25A95, ++ [ 4616] = 0x20979, [ 4618] = 0x3A52, [ 4619] = 0x22465, [ 4620] = 0x7374, ++ [ 4621] = 0x29EAC, [ 4622] = 0x4D09, [ 4623] = 0x9BED, [ 4624] = 0x23CFE, ++ [ 4625] = 0x29F30, [ 4626] = 0x4C5B, [ 4627] = 0x24FA9, [ 4628] = 0x2959E, ++ [ 4629] = 0x29FDE, [ 4630] = 0x845C, [ 4631] = 0x23DB6, [ 4632] = 0x272B2, ++ [ 4633] = 0x267B3, [ 4634] = 0x23720, [ 4635] = 0x632E, [ 4636] = 0x7D25, ++ [ 4637] = 0x23EF7, [ 4638] = 0x23E2C, [ 4639] = 0x3A2A, [ 4640] = 0x9008, ++ [ 4641] = 0x52CC, [ 4642] = 0x3E74, [ 4643] = 0x367A, [ 4644] = 0x45E9, ++ [ 4645] = 0x2048E, [ 4646] = 0x7640, [ 4647] = 0x5AF0, [ 4648] = 0x20EB6, ++ [ 4649] = 0x787A, [ 4650] = 0x27F2E, [ 4651] = 0x58A7, [ 4652] = 0x40BF, ++ [ 4653] = 0x567C, [ 4654] = 0x9B8B, [ 4655] = 0x5D74, [ 4656] = 0x7654, ++ [ 4657] = 0x2A434, [ 4658] = 0x9E85, [ 4659] = 0x4CE1, [ 4661] = 0x37FB, ++ [ 4662] = 0x6119, [ 4663] = 0x230DA, [ 4664] = 0x243F2, [ 4666] = 0x565D, ++ [ 4667] = 0x212A9, [ 4668] = 0x57A7, [ 4669] = 0x24963, [ 4670] = 0x29E06, ++ [ 4671] = 0x5234, [ 4672] = 0x270AE, [ 4673] = 0x35AD, [ 4675] = 0x9D7C, ++ [ 4680] = 0x7C56, [ 4681] = 0x9B39, [ 4682] = 0x57DE, [ 4683] = 0x2176C, ++ [ 4684] = 0x5C53, [ 4685] = 0x64D3, [ 4686] = 0x294D0, [ 4687] = 0x26335, ++ [ 4688] = 0x27164, [ 4689] = 0x86AD, [ 4690] = 0x20D28, [ 4691] = 0x26D22, ++ [ 4692] = 0x24AE2, [ 4693] = 0x20D71, [ 4695] = 0x51FE, [ 4696] = 0x21F0F, ++ [ 4697] = 0x5D8E, [ 4698] = 0x9703, [ 4699] = 0x21DD1, [ 4700] = 0x9E81, ++ [ 4701] = 0x904C, [ 4702] = 0x7B1F, [ 4703] = 0x9B02, [ 4704] = 0x5CD1, ++ [ 4705] = 0x7BA3, [ 4706] = 0x6268, [ 4707] = 0x6335, [ 4708] = 0x9AFF, ++ [ 4709] = 0x7BCF, [ 4710] = 0x9B2A, [ 4711] = 0x7C7E, [ 4713] = 0x7C42, ++ [ 4714] = 0x7C86, [ 4715] = 0x9C15, [ 4716] = 0x7BFC, [ 4717] = 0x9B09, ++ [ 4719] = 0x9C1B, [ 4720] = 0x2493E, [ 4721] = 0x9F5A, [ 4722] = 0x5573, ++ [ 4723] = 0x5BC3, [ 4724] = 0x4FFD, [ 4725] = 0x9E98, [ 4726] = 0x4FF2, ++ [ 4727] = 0x5260, [ 4728] = 0x3E06, [ 4729] = 0x52D1, [ 4730] = 0x5767, ++ [ 4731] = 0x5056, [ 4732] = 0x59B7, [ 4733] = 0x5E12, [ 4734] = 0x97C8, ++ [ 4735] = 0x9DAB, [ 4736] = 0x8F5C, [ 4737] = 0x5469, [ 4738] = 0x97B4, ++ [ 4739] = 0x9940, [ 4740] = 0x97BA, [ 4741] = 0x532C, [ 4742] = 0x6130, ++ [ 4777] = 0x692C, [ 4778] = 0x53DA, [ 4779] = 0x9C0A, [ 4780] = 0x9D02, ++ [ 4781] = 0x4C3B, [ 4782] = 0x9641, [ 4783] = 0x6980, [ 4784] = 0x50A6, ++ [ 4785] = 0x7546, [ 4786] = 0x2176D, [ 4787] = 0x99DA, [ 4788] = 0x5273, ++ [ 4790] = 0x9159, [ 4791] = 0x9681, [ 4792] = 0x915C, [ 4794] = 0x9151, ++ [ 4795] = 0x28E97, [ 4796] = 0x637F, [ 4797] = 0x26D23, [ 4798] = 0x6ACA, ++ [ 4799] = 0x5611, [ 4800] = 0x918E, [ 4801] = 0x757A, [ 4802] = 0x6285, ++ [ 4803] = 0x203FC, [ 4804] = 0x734F, [ 4805] = 0x7C70, [ 4806] = 0x25C21, ++ [ 4807] = 0x23CFD, [ 4809] = 0x24919, [ 4810] = 0x76D6, [ 4811] = 0x9B9D, ++ [ 4812] = 0x4E2A, [ 4813] = 0x20CD4, [ 4814] = 0x83BE, [ 4815] = 0x8842, ++ [ 4817] = 0x5C4A, [ 4818] = 0x69C0, [ 4820] = 0x577A, [ 4821] = 0x521F, ++ [ 4822] = 0x5DF5, [ 4823] = 0x4ECE, [ 4824] = 0x6C31, [ 4825] = 0x201F2, ++ [ 4826] = 0x4F39, [ 4827] = 0x549C, [ 4828] = 0x54DA, [ 4829] = 0x529A, ++ [ 4830] = 0x8D82, [ 4831] = 0x35FE, [ 4833] = 0x35F3, [ 4835] = 0x6B52, ++ [ 4836] = 0x917C, [ 4837] = 0x9FA5, [ 4838] = 0x9B97, [ 4839] = 0x982E, ++ [ 4840] = 0x98B4, [ 4841] = 0x9ABA, [ 4842] = 0x9EA8, [ 4843] = 0x9E84, ++ [ 4844] = 0x717A, [ 4845] = 0x7B14, [ 4847] = 0x6BFA, [ 4848] = 0x8818, ++ [ 4849] = 0x7F78, [ 4851] = 0x5620, [ 4852] = 0x2A64A, [ 4853] = 0x8E77, ++ [ 4854] = 0x9F53, [ 4856] = 0x8DD4, [ 4857] = 0x8E4F, [ 4858] = 0x9E1C, ++ [ 4859] = 0x8E01, [ 4860] = 0x6282, [ 4861] = 0x2837D, [ 4862] = 0x8E28, ++ [ 4863] = 0x8E75, [ 4864] = 0x7AD3, [ 4865] = 0x24A77, [ 4866] = 0x7A3E, ++ [ 4867] = 0x78D8, [ 4868] = 0x6CEA, [ 4869] = 0x8A67, [ 4870] = 0x7607, ++ [ 4875] = 0x28A5A, [ 4876] = 0x9F26, [ 4877] = 0x6CCE, [ 4878] = 0x87D6, ++ [ 4879] = 0x75C3, [ 4880] = 0x2A2B2, [ 4881] = 0x7853, [ 4882] = 0x2F840, ++ [ 4883] = 0x8D0C, [ 4884] = 0x72E2, [ 4885] = 0x7371, [ 4886] = 0x8B2D, ++ [ 4887] = 0x7302, [ 4888] = 0x74F1, [ 4889] = 0x8CEB, [ 4890] = 0x24ABB, ++ [ 4891] = 0x862F, [ 4892] = 0x5FBA, [ 4893] = 0x88A0, [ 4894] = 0x44B7, ++ [ 4896] = 0x2183B, [ 4897] = 0x26E05, [ 4899] = 0x8A7E, [ 4900] = 0x2251B, ++ [ 4902] = 0x60FD, [ 4903] = 0x7667, [ 4904] = 0x9AD7, [ 4905] = 0x9D44, ++ [ 4906] = 0x936E, [ 4907] = 0x9B8F, [ 4908] = 0x87F5, [ 4911] = 0x8CF7, ++ [ 4912] = 0x732C, [ 4913] = 0x9721, [ 4914] = 0x9BB0, [ 4915] = 0x35D6, ++ [ 4916] = 0x72B2, [ 4917] = 0x4C07, [ 4918] = 0x7C51, [ 4919] = 0x994A, ++ [ 4920] = 0x26159, [ 4921] = 0x6159, [ 4922] = 0x4C04, [ 4923] = 0x9E96, ++ [ 4924] = 0x617D, [ 4926] = 0x575F, [ 4927] = 0x616F, [ 4928] = 0x62A6, ++ [ 4929] = 0x6239, [ 4931] = 0x3A5C, [ 4932] = 0x61E2, [ 4933] = 0x53AA, ++ [ 4934] = 0x233F5, [ 4935] = 0x6364, [ 4936] = 0x6802, [ 4937] = 0x35D2, ++ [ 4972] = 0x5D57, [ 4973] = 0x28BC2, [ 4974] = 0x8FDA, [ 4975] = 0x28E39, ++ [ 4977] = 0x50D9, [ 4978] = 0x21D46, [ 4979] = 0x7906, [ 4980] = 0x5332, ++ [ 4981] = 0x9638, [ 4982] = 0x20F3B, [ 4983] = 0x4065, [ 4985] = 0x77FE, ++ [ 4987] = 0x7CC2, [ 4988] = 0x25F1A, [ 4989] = 0x7CDA, [ 4990] = 0x7A2D, ++ [ 4991] = 0x8066, [ 4992] = 0x8063, [ 4993] = 0x7D4D, [ 4994] = 0x7505, ++ [ 4995] = 0x74F2, [ 4996] = 0x8994, [ 4997] = 0x821A, [ 4998] = 0x670C, ++ [ 4999] = 0x8062, [ 5000] = 0x27486, [ 5001] = 0x805B, [ 5002] = 0x74F0, ++ [ 5003] = 0x8103, [ 5004] = 0x7724, [ 5005] = 0x8989, [ 5006] = 0x267CC, ++ [ 5007] = 0x7553, [ 5008] = 0x26ED1, [ 5009] = 0x87A9, [ 5010] = 0x87CE, ++ [ 5011] = 0x81C8, [ 5012] = 0x878C, [ 5013] = 0x8A49, [ 5014] = 0x8CAD, ++ [ 5015] = 0x8B43, [ 5016] = 0x772B, [ 5017] = 0x74F8, [ 5018] = 0x84DA, ++ [ 5019] = 0x3635, [ 5020] = 0x69B2, [ 5021] = 0x8DA6, [ 5023] = 0x89A9, ++ [ 5025] = 0x6DB9, [ 5026] = 0x87C1, [ 5027] = 0x24011, [ 5028] = 0x74E7, ++ [ 5029] = 0x3DDB, [ 5030] = 0x7176, [ 5031] = 0x60A4, [ 5032] = 0x619C, ++ [ 5033] = 0x3CD1, [ 5035] = 0x6077, [ 5037] = 0x7F71, [ 5038] = 0x28B2D, ++ [ 5040] = 0x60E9, [ 5041] = 0x4B7E, [ 5042] = 0x5220, [ 5043] = 0x3C18, ++ [ 5044] = 0x23CC7, [ 5045] = 0x25ED7, [ 5046] = 0x27656, [ 5047] = 0x25531, ++ [ 5048] = 0x21944, [ 5049] = 0x212FE, [ 5050] = 0x29903, [ 5051] = 0x26DDC, ++ [ 5052] = 0x270AD, [ 5053] = 0x5CC1, [ 5054] = 0x261AD, [ 5055] = 0x28A0F, ++ [ 5056] = 0x23677, [ 5057] = 0x200EE, [ 5058] = 0x26846, [ 5059] = 0x24F0E, ++ [ 5060] = 0x4562, [ 5061] = 0x5B1F, [ 5062] = 0x2634C, [ 5063] = 0x9F50, ++ [ 5064] = 0x9EA6, [ 5065] = 0x2626B, [ 5070] = 0x3000, [ 5071] = 0xFF0C, ++ [ 5072] = 0x3001, [ 5073] = 0x3002, [ 5074] = 0xFF0E, [ 5075] = 0x2022, ++ [ 5076] = 0xFF1B, [ 5077] = 0xFF1A, [ 5078] = 0xFF1F, [ 5079] = 0xFF01, ++ [ 5080] = 0xFE30, [ 5081] = 0x2026, [ 5082] = 0x2025, [ 5083] = 0xFE50, ++ [ 5084] = 0xFF64, [ 5085] = 0xFE52, [ 5086] = 0x00B7, [ 5087] = 0xFE54, ++ [ 5088] = 0xFE55, [ 5089] = 0xFE56, [ 5090] = 0xFE57, [ 5091] = 0xFF5C, ++ [ 5092] = 0x2013, [ 5093] = 0xFE31, [ 5094] = 0x2014, [ 5095] = 0xFE33, ++ [ 5097] = 0xFE34, [ 5098] = 0xFE4F, [ 5099] = 0xFF08, [ 5100] = 0xFF09, ++ [ 5101] = 0xFE35, [ 5102] = 0xFE36, [ 5103] = 0xFF5B, [ 5104] = 0xFF5D, ++ [ 5105] = 0xFE37, [ 5106] = 0xFE38, [ 5107] = 0x3014, [ 5108] = 0x3015, ++ [ 5109] = 0xFE39, [ 5110] = 0xFE3A, [ 5111] = 0x3010, [ 5112] = 0x3011, ++ [ 5113] = 0xFE3B, [ 5114] = 0xFE3C, [ 5115] = 0x300A, [ 5116] = 0x300B, ++ [ 5117] = 0xFE3D, [ 5118] = 0xFE3E, [ 5119] = 0x3008, [ 5120] = 0x3009, ++ [ 5121] = 0xFE3F, [ 5122] = 0xFE40, [ 5123] = 0x300C, [ 5124] = 0x300D, ++ [ 5125] = 0xFE41, [ 5126] = 0xFE42, [ 5127] = 0x300E, [ 5128] = 0x300F, ++ [ 5129] = 0xFE43, [ 5130] = 0xFE44, [ 5131] = 0xFE59, [ 5132] = 0xFE5A, ++ [ 5167] = 0xFE5B, [ 5168] = 0xFE5C, [ 5169] = 0xFE5D, [ 5170] = 0xFE5E, ++ [ 5171] = 0x2018, [ 5172] = 0x2019, [ 5173] = 0x201C, [ 5174] = 0x201D, ++ [ 5175] = 0x301D, [ 5176] = 0x301E, [ 5177] = 0x2035, [ 5178] = 0x2032, ++ [ 5179] = 0xFF03, [ 5180] = 0xFF06, [ 5181] = 0xFF0A, [ 5182] = 0x203B, ++ [ 5183] = 0x00A7, [ 5184] = 0x3003, [ 5185] = 0x25CB, [ 5186] = 0x25CF, ++ [ 5187] = 0x25B3, [ 5188] = 0x25B2, [ 5189] = 0x25CE, [ 5190] = 0x2606, ++ [ 5191] = 0x2605, [ 5192] = 0x25C7, [ 5193] = 0x25C6, [ 5194] = 0x25A1, ++ [ 5195] = 0x25A0, [ 5196] = 0x25BD, [ 5197] = 0x25BC, [ 5198] = 0x32A3, ++ [ 5199] = 0x2105, [ 5200] = 0x203E, [ 5202] = 0xFF3F, [ 5204] = 0xFE49, ++ [ 5205] = 0xFE4A, [ 5206] = 0xFE4D, [ 5207] = 0xFE4E, [ 5208] = 0xFE4B, ++ [ 5209] = 0xFE4C, [ 5210] = 0xFE5F, [ 5211] = 0xFE60, [ 5212] = 0xFE61, ++ [ 5213] = 0xFF0B, [ 5214] = 0xFF0D, [ 5215] = 0x00D7, [ 5216] = 0x00F7, ++ [ 5217] = 0x00B1, [ 5218] = 0x221A, [ 5219] = 0xFF1C, [ 5220] = 0xFF1E, ++ [ 5221] = 0xFF1D, [ 5222] = 0x2266, [ 5223] = 0x2267, [ 5224] = 0x2260, ++ [ 5225] = 0x221E, [ 5226] = 0x2252, [ 5227] = 0x2261, [ 5228] = 0xFE62, ++ [ 5229] = 0xFE63, [ 5230] = 0xFE64, [ 5231] = 0xFE65, [ 5232] = 0xFE66, ++ [ 5233] = 0x223C, [ 5234] = 0x2229, [ 5235] = 0x222A, [ 5236] = 0x22A5, ++ [ 5237] = 0x2220, [ 5238] = 0x221F, [ 5239] = 0x22BF, [ 5240] = 0x33D2, ++ [ 5241] = 0x33D1, [ 5242] = 0x222B, [ 5243] = 0x222E, [ 5244] = 0x2235, ++ [ 5245] = 0x2234, [ 5246] = 0x2640, [ 5247] = 0x2642, [ 5248] = 0x2641, ++ [ 5249] = 0x2609, [ 5250] = 0x2191, [ 5251] = 0x2193, [ 5252] = 0x2190, ++ [ 5253] = 0x2192, [ 5254] = 0x2196, [ 5255] = 0x2197, [ 5256] = 0x2199, ++ [ 5257] = 0x2198, [ 5258] = 0x2225, [ 5259] = 0x2223, [ 5266] = 0xFF0F, ++ [ 5267] = 0xFF3C, [ 5268] = 0xFF04, [ 5269] = 0x00A5, [ 5270] = 0x3012, ++ [ 5271] = 0x00A2, [ 5272] = 0x00A3, [ 5273] = 0xFF05, [ 5274] = 0xFF20, ++ [ 5275] = 0x2103, [ 5276] = 0x2109, [ 5277] = 0xFE69, [ 5278] = 0xFE6A, ++ [ 5279] = 0xFE6B, [ 5280] = 0x33D5, [ 5281] = 0x339C, [ 5282] = 0x339D, ++ [ 5283] = 0x339E, [ 5284] = 0x33CE, [ 5285] = 0x33A1, [ 5286] = 0x338E, ++ [ 5287] = 0x338F, [ 5288] = 0x33C4, [ 5289] = 0x00B0, [ 5290] = 0x5159, ++ [ 5291] = 0x515B, [ 5292] = 0x515E, [ 5293] = 0x515D, [ 5294] = 0x5161, ++ [ 5295] = 0x5163, [ 5296] = 0x55E7, [ 5297] = 0x74E9, [ 5298] = 0x7CCE, ++ [ 5299] = 0x2581, [ 5300] = 0x2582, [ 5301] = 0x2583, [ 5302] = 0x2584, ++ [ 5303] = 0x2585, [ 5304] = 0x2586, [ 5305] = 0x2587, [ 5306] = 0x2588, ++ [ 5307] = 0x258F, [ 5308] = 0x258E, [ 5309] = 0x258D, [ 5310] = 0x258C, ++ [ 5311] = 0x258B, [ 5312] = 0x258A, [ 5313] = 0x2589, [ 5314] = 0x253C, ++ [ 5315] = 0x2534, [ 5316] = 0x252C, [ 5317] = 0x2524, [ 5318] = 0x251C, ++ [ 5319] = 0x2594, [ 5320] = 0x2500, [ 5321] = 0x2502, [ 5322] = 0x2595, ++ [ 5323] = 0x250C, [ 5324] = 0x2510, [ 5325] = 0x2514, [ 5326] = 0x2518, ++ [ 5327] = 0x256D, [ 5362] = 0x256E, [ 5363] = 0x2570, [ 5364] = 0x256F, ++ [ 5365] = 0x2550, [ 5366] = 0x255E, [ 5367] = 0x256A, [ 5368] = 0x2561, ++ [ 5369] = 0x25E2, [ 5370] = 0x25E3, [ 5371] = 0x25E5, [ 5372] = 0x25E4, ++ [ 5373] = 0x2571, [ 5374] = 0x2572, [ 5375] = 0x2573, [ 5376] = 0xFF10, ++ [ 5377] = 0xFF11, [ 5378] = 0xFF12, [ 5379] = 0xFF13, [ 5380] = 0xFF14, ++ [ 5381] = 0xFF15, [ 5382] = 0xFF16, [ 5383] = 0xFF17, [ 5384] = 0xFF18, ++ [ 5385] = 0xFF19, [ 5386] = 0x2160, [ 5387] = 0x2161, [ 5388] = 0x2162, ++ [ 5389] = 0x2163, [ 5390] = 0x2164, [ 5391] = 0x2165, [ 5392] = 0x2166, ++ [ 5393] = 0x2167, [ 5394] = 0x2168, [ 5395] = 0x2169, [ 5396] = 0x3021, ++ [ 5397] = 0x3022, [ 5398] = 0x3023, [ 5399] = 0x3024, [ 5400] = 0x3025, ++ [ 5401] = 0x3026, [ 5402] = 0x3027, [ 5403] = 0x3028, [ 5404] = 0x3029, ++ [ 5406] = 0x5344, [ 5408] = 0xFF21, [ 5409] = 0xFF22, [ 5410] = 0xFF23, ++ [ 5411] = 0xFF24, [ 5412] = 0xFF25, [ 5413] = 0xFF26, [ 5414] = 0xFF27, ++ [ 5415] = 0xFF28, [ 5416] = 0xFF29, [ 5417] = 0xFF2A, [ 5418] = 0xFF2B, ++ [ 5419] = 0xFF2C, [ 5420] = 0xFF2D, [ 5421] = 0xFF2E, [ 5422] = 0xFF2F, ++ [ 5423] = 0xFF30, [ 5424] = 0xFF31, [ 5425] = 0xFF32, [ 5426] = 0xFF33, ++ [ 5427] = 0xFF34, [ 5428] = 0xFF35, [ 5429] = 0xFF36, [ 5430] = 0xFF37, ++ [ 5431] = 0xFF38, [ 5432] = 0xFF39, [ 5433] = 0xFF3A, [ 5434] = 0xFF41, ++ [ 5435] = 0xFF42, [ 5436] = 0xFF43, [ 5437] = 0xFF44, [ 5438] = 0xFF45, ++ [ 5439] = 0xFF46, [ 5440] = 0xFF47, [ 5441] = 0xFF48, [ 5442] = 0xFF49, ++ [ 5443] = 0xFF4A, [ 5444] = 0xFF4B, [ 5445] = 0xFF4C, [ 5446] = 0xFF4D, ++ [ 5447] = 0xFF4E, [ 5448] = 0xFF4F, [ 5449] = 0xFF50, [ 5450] = 0xFF51, ++ [ 5451] = 0xFF52, [ 5452] = 0xFF53, [ 5453] = 0xFF54, [ 5454] = 0xFF55, ++ [ 5455] = 0xFF56, [ 5460] = 0xFF57, [ 5461] = 0xFF58, [ 5462] = 0xFF59, ++ [ 5463] = 0xFF5A, [ 5464] = 0x0391, [ 5465] = 0x0392, [ 5466] = 0x0393, ++ [ 5467] = 0x0394, [ 5468] = 0x0395, [ 5469] = 0x0396, [ 5470] = 0x0397, ++ [ 5471] = 0x0398, [ 5472] = 0x0399, [ 5473] = 0x039A, [ 5474] = 0x039B, ++ [ 5475] = 0x039C, [ 5476] = 0x039D, [ 5477] = 0x039E, [ 5478] = 0x039F, ++ [ 5479] = 0x03A0, [ 5480] = 0x03A1, [ 5481] = 0x03A3, [ 5482] = 0x03A4, ++ [ 5483] = 0x03A5, [ 5484] = 0x03A6, [ 5485] = 0x03A7, [ 5486] = 0x03A8, ++ [ 5487] = 0x03A9, [ 5488] = 0x03B1, [ 5489] = 0x03B2, [ 5490] = 0x03B3, ++ [ 5491] = 0x03B4, [ 5492] = 0x03B5, [ 5493] = 0x03B6, [ 5494] = 0x03B7, ++ [ 5495] = 0x03B8, [ 5496] = 0x03B9, [ 5497] = 0x03BA, [ 5498] = 0x03BB, ++ [ 5499] = 0x03BC, [ 5500] = 0x03BD, [ 5501] = 0x03BE, [ 5502] = 0x03BF, ++ [ 5503] = 0x03C0, [ 5504] = 0x03C1, [ 5505] = 0x03C3, [ 5506] = 0x03C4, ++ [ 5507] = 0x03C5, [ 5508] = 0x03C6, [ 5509] = 0x03C7, [ 5510] = 0x03C8, ++ [ 5511] = 0x03C9, [ 5512] = 0x3105, [ 5513] = 0x3106, [ 5514] = 0x3107, ++ [ 5515] = 0x3108, [ 5516] = 0x3109, [ 5517] = 0x310A, [ 5518] = 0x310B, ++ [ 5519] = 0x310C, [ 5520] = 0x310D, [ 5521] = 0x310E, [ 5522] = 0x310F, ++ [ 5557] = 0x3110, [ 5558] = 0x3111, [ 5559] = 0x3112, [ 5560] = 0x3113, ++ [ 5561] = 0x3114, [ 5562] = 0x3115, [ 5563] = 0x3116, [ 5564] = 0x3117, ++ [ 5565] = 0x3118, [ 5566] = 0x3119, [ 5567] = 0x311A, [ 5568] = 0x311B, ++ [ 5569] = 0x311C, [ 5570] = 0x311D, [ 5571] = 0x311E, [ 5572] = 0x311F, ++ [ 5573] = 0x3120, [ 5574] = 0x3121, [ 5575] = 0x3122, [ 5576] = 0x3123, ++ [ 5577] = 0x3124, [ 5578] = 0x3125, [ 5579] = 0x3126, [ 5580] = 0x3127, ++ [ 5581] = 0x3128, [ 5582] = 0x3129, [ 5583] = 0x02D9, [ 5584] = 0x02C9, ++ [ 5585] = 0x02CA, [ 5586] = 0x02C7, [ 5587] = 0x02CB, [ 5655] = 0x4E00, ++ [ 5656] = 0x4E59, [ 5657] = 0x4E01, [ 5658] = 0x4E03, [ 5659] = 0x4E43, ++ [ 5660] = 0x4E5D, [ 5661] = 0x4E86, [ 5662] = 0x4E8C, [ 5663] = 0x4EBA, ++ [ 5664] = 0x513F, [ 5665] = 0x5165, [ 5666] = 0x516B, [ 5667] = 0x51E0, ++ [ 5668] = 0x5200, [ 5669] = 0x5201, [ 5670] = 0x529B, [ 5671] = 0x5315, ++ [ 5672] = 0x5341, [ 5673] = 0x535C, [ 5674] = 0x53C8, [ 5675] = 0x4E09, ++ [ 5676] = 0x4E0B, [ 5677] = 0x4E08, [ 5678] = 0x4E0A, [ 5679] = 0x4E2B, ++ [ 5680] = 0x4E38, [ 5681] = 0x51E1, [ 5682] = 0x4E45, [ 5683] = 0x4E48, ++ [ 5684] = 0x4E5F, [ 5685] = 0x4E5E, [ 5686] = 0x4E8E, [ 5687] = 0x4EA1, ++ [ 5688] = 0x5140, [ 5689] = 0x5203, [ 5690] = 0x52FA, [ 5691] = 0x5343, ++ [ 5692] = 0x53C9, [ 5693] = 0x53E3, [ 5694] = 0x571F, [ 5695] = 0x58EB, ++ [ 5696] = 0x5915, [ 5697] = 0x5927, [ 5698] = 0x5973, [ 5699] = 0x5B50, ++ [ 5700] = 0x5B51, [ 5701] = 0x5B53, [ 5702] = 0x5BF8, [ 5703] = 0x5C0F, ++ [ 5704] = 0x5C22, [ 5705] = 0x5C38, [ 5706] = 0x5C71, [ 5707] = 0x5DDD, ++ [ 5708] = 0x5DE5, [ 5709] = 0x5DF1, [ 5710] = 0x5DF2, [ 5711] = 0x5DF3, ++ [ 5712] = 0x5DFE, [ 5713] = 0x5E72, [ 5714] = 0x5EFE, [ 5715] = 0x5F0B, ++ [ 5716] = 0x5F13, [ 5717] = 0x624D, [ 5752] = 0x4E11, [ 5753] = 0x4E10, ++ [ 5754] = 0x4E0D, [ 5755] = 0x4E2D, [ 5756] = 0x4E30, [ 5757] = 0x4E39, ++ [ 5758] = 0x4E4B, [ 5759] = 0x5C39, [ 5760] = 0x4E88, [ 5761] = 0x4E91, ++ [ 5762] = 0x4E95, [ 5763] = 0x4E92, [ 5764] = 0x4E94, [ 5765] = 0x4EA2, ++ [ 5766] = 0x4EC1, [ 5767] = 0x4EC0, [ 5768] = 0x4EC3, [ 5769] = 0x4EC6, ++ [ 5770] = 0x4EC7, [ 5771] = 0x4ECD, [ 5772] = 0x4ECA, [ 5773] = 0x4ECB, ++ [ 5774] = 0x4EC4, [ 5775] = 0x5143, [ 5776] = 0x5141, [ 5777] = 0x5167, ++ [ 5778] = 0x516D, [ 5779] = 0x516E, [ 5780] = 0x516C, [ 5781] = 0x5197, ++ [ 5782] = 0x51F6, [ 5783] = 0x5206, [ 5784] = 0x5207, [ 5785] = 0x5208, ++ [ 5786] = 0x52FB, [ 5787] = 0x52FE, [ 5788] = 0x52FF, [ 5789] = 0x5316, ++ [ 5790] = 0x5339, [ 5791] = 0x5348, [ 5792] = 0x5347, [ 5793] = 0x5345, ++ [ 5794] = 0x535E, [ 5795] = 0x5384, [ 5796] = 0x53CB, [ 5797] = 0x53CA, ++ [ 5798] = 0x53CD, [ 5799] = 0x58EC, [ 5800] = 0x5929, [ 5801] = 0x592B, ++ [ 5802] = 0x592A, [ 5803] = 0x592D, [ 5804] = 0x5B54, [ 5805] = 0x5C11, ++ [ 5806] = 0x5C24, [ 5807] = 0x5C3A, [ 5808] = 0x5C6F, [ 5809] = 0x5DF4, ++ [ 5810] = 0x5E7B, [ 5811] = 0x5EFF, [ 5812] = 0x5F14, [ 5813] = 0x5F15, ++ [ 5814] = 0x5FC3, [ 5815] = 0x6208, [ 5816] = 0x6236, [ 5817] = 0x624B, ++ [ 5818] = 0x624E, [ 5819] = 0x652F, [ 5820] = 0x6587, [ 5821] = 0x6597, ++ [ 5822] = 0x65A4, [ 5823] = 0x65B9, [ 5824] = 0x65E5, [ 5825] = 0x66F0, ++ [ 5826] = 0x6708, [ 5827] = 0x6728, [ 5828] = 0x6B20, [ 5829] = 0x6B62, ++ [ 5830] = 0x6B79, [ 5831] = 0x6BCB, [ 5832] = 0x6BD4, [ 5833] = 0x6BDB, ++ [ 5834] = 0x6C0F, [ 5835] = 0x6C34, [ 5836] = 0x706B, [ 5837] = 0x722A, ++ [ 5838] = 0x7236, [ 5839] = 0x723B, [ 5840] = 0x7247, [ 5841] = 0x7259, ++ [ 5842] = 0x725B, [ 5843] = 0x72AC, [ 5844] = 0x738B, [ 5845] = 0x4E19, ++ [ 5850] = 0x4E16, [ 5851] = 0x4E15, [ 5852] = 0x4E14, [ 5853] = 0x4E18, ++ [ 5854] = 0x4E3B, [ 5855] = 0x4E4D, [ 5856] = 0x4E4F, [ 5857] = 0x4E4E, ++ [ 5858] = 0x4EE5, [ 5859] = 0x4ED8, [ 5860] = 0x4ED4, [ 5861] = 0x4ED5, ++ [ 5862] = 0x4ED6, [ 5863] = 0x4ED7, [ 5864] = 0x4EE3, [ 5865] = 0x4EE4, ++ [ 5866] = 0x4ED9, [ 5867] = 0x4EDE, [ 5868] = 0x5145, [ 5869] = 0x5144, ++ [ 5870] = 0x5189, [ 5871] = 0x518A, [ 5872] = 0x51AC, [ 5873] = 0x51F9, ++ [ 5874] = 0x51FA, [ 5875] = 0x51F8, [ 5876] = 0x520A, [ 5877] = 0x52A0, ++ [ 5878] = 0x529F, [ 5879] = 0x5305, [ 5880] = 0x5306, [ 5881] = 0x5317, ++ [ 5882] = 0x531D, [ 5883] = 0x4EDF, [ 5884] = 0x534A, [ 5885] = 0x5349, ++ [ 5886] = 0x5361, [ 5887] = 0x5360, [ 5888] = 0x536F, [ 5889] = 0x536E, ++ [ 5890] = 0x53BB, [ 5891] = 0x53EF, [ 5892] = 0x53E4, [ 5893] = 0x53F3, ++ [ 5894] = 0x53EC, [ 5895] = 0x53EE, [ 5896] = 0x53E9, [ 5897] = 0x53E8, ++ [ 5898] = 0x53FC, [ 5899] = 0x53F8, [ 5900] = 0x53F5, [ 5901] = 0x53EB, ++ [ 5902] = 0x53E6, [ 5903] = 0x53EA, [ 5904] = 0x53F2, [ 5905] = 0x53F1, ++ [ 5906] = 0x53F0, [ 5907] = 0x53E5, [ 5908] = 0x53ED, [ 5909] = 0x53FB, ++ [ 5910] = 0x56DB, [ 5911] = 0x56DA, [ 5912] = 0x5916, [ 5947] = 0x592E, ++ [ 5948] = 0x5931, [ 5949] = 0x5974, [ 5950] = 0x5976, [ 5951] = 0x5B55, ++ [ 5952] = 0x5B83, [ 5953] = 0x5C3C, [ 5954] = 0x5DE8, [ 5955] = 0x5DE7, ++ [ 5956] = 0x5DE6, [ 5957] = 0x5E02, [ 5958] = 0x5E03, [ 5959] = 0x5E73, ++ [ 5960] = 0x5E7C, [ 5961] = 0x5F01, [ 5962] = 0x5F18, [ 5963] = 0x5F17, ++ [ 5964] = 0x5FC5, [ 5965] = 0x620A, [ 5966] = 0x6253, [ 5967] = 0x6254, ++ [ 5968] = 0x6252, [ 5969] = 0x6251, [ 5970] = 0x65A5, [ 5971] = 0x65E6, ++ [ 5972] = 0x672E, [ 5973] = 0x672C, [ 5974] = 0x672A, [ 5975] = 0x672B, ++ [ 5976] = 0x672D, [ 5977] = 0x6B63, [ 5978] = 0x6BCD, [ 5979] = 0x6C11, ++ [ 5980] = 0x6C10, [ 5981] = 0x6C38, [ 5982] = 0x6C41, [ 5983] = 0x6C40, ++ [ 5984] = 0x6C3E, [ 5985] = 0x72AF, [ 5986] = 0x7384, [ 5987] = 0x7389, ++ [ 5988] = 0x74DC, [ 5989] = 0x74E6, [ 5990] = 0x7518, [ 5991] = 0x751F, ++ [ 5992] = 0x7528, [ 5993] = 0x7529, [ 5994] = 0x7530, [ 5995] = 0x7531, ++ [ 5996] = 0x7532, [ 5997] = 0x7533, [ 5998] = 0x758B, [ 5999] = 0x767D, ++ [ 6000] = 0x76AE, [ 6001] = 0x76BF, [ 6002] = 0x76EE, [ 6003] = 0x77DB, ++ [ 6004] = 0x77E2, [ 6005] = 0x77F3, [ 6006] = 0x793A, [ 6007] = 0x79BE, ++ [ 6008] = 0x7A74, [ 6009] = 0x7ACB, [ 6010] = 0x4E1E, [ 6011] = 0x4E1F, ++ [ 6012] = 0x4E52, [ 6013] = 0x4E53, [ 6014] = 0x4E69, [ 6015] = 0x4E99, ++ [ 6016] = 0x4EA4, [ 6017] = 0x4EA6, [ 6018] = 0x4EA5, [ 6019] = 0x4EFF, ++ [ 6020] = 0x4F09, [ 6021] = 0x4F19, [ 6022] = 0x4F0A, [ 6023] = 0x4F15, ++ [ 6024] = 0x4F0D, [ 6025] = 0x4F10, [ 6026] = 0x4F11, [ 6027] = 0x4F0F, ++ [ 6028] = 0x4EF2, [ 6029] = 0x4EF6, [ 6030] = 0x4EFB, [ 6031] = 0x4EF0, ++ [ 6032] = 0x4EF3, [ 6033] = 0x4EFD, [ 6034] = 0x4F01, [ 6035] = 0x4F0B, ++ [ 6036] = 0x5149, [ 6037] = 0x5147, [ 6038] = 0x5146, [ 6039] = 0x5148, ++ [ 6040] = 0x5168, [ 6045] = 0x5171, [ 6046] = 0x518D, [ 6047] = 0x51B0, ++ [ 6048] = 0x5217, [ 6049] = 0x5211, [ 6050] = 0x5212, [ 6051] = 0x520E, ++ [ 6052] = 0x5216, [ 6053] = 0x52A3, [ 6054] = 0x5308, [ 6055] = 0x5321, ++ [ 6056] = 0x5320, [ 6057] = 0x5370, [ 6058] = 0x5371, [ 6059] = 0x5409, ++ [ 6060] = 0x540F, [ 6061] = 0x540C, [ 6062] = 0x540A, [ 6063] = 0x5410, ++ [ 6064] = 0x5401, [ 6065] = 0x540B, [ 6066] = 0x5404, [ 6067] = 0x5411, ++ [ 6068] = 0x540D, [ 6069] = 0x5408, [ 6070] = 0x5403, [ 6071] = 0x540E, ++ [ 6072] = 0x5406, [ 6073] = 0x5412, [ 6074] = 0x56E0, [ 6075] = 0x56DE, ++ [ 6076] = 0x56DD, [ 6077] = 0x5733, [ 6078] = 0x5730, [ 6079] = 0x5728, ++ [ 6080] = 0x572D, [ 6081] = 0x572C, [ 6082] = 0x572F, [ 6083] = 0x5729, ++ [ 6084] = 0x5919, [ 6085] = 0x591A, [ 6086] = 0x5937, [ 6087] = 0x5938, ++ [ 6088] = 0x5984, [ 6089] = 0x5978, [ 6090] = 0x5983, [ 6091] = 0x597D, ++ [ 6092] = 0x5979, [ 6093] = 0x5982, [ 6094] = 0x5981, [ 6095] = 0x5B57, ++ [ 6096] = 0x5B58, [ 6097] = 0x5B87, [ 6098] = 0x5B88, [ 6099] = 0x5B85, ++ [ 6100] = 0x5B89, [ 6101] = 0x5BFA, [ 6102] = 0x5C16, [ 6103] = 0x5C79, ++ [ 6104] = 0x5DDE, [ 6105] = 0x5E06, [ 6106] = 0x5E76, [ 6107] = 0x5E74, ++ [ 6142] = 0x5F0F, [ 6143] = 0x5F1B, [ 6144] = 0x5FD9, [ 6145] = 0x5FD6, ++ [ 6146] = 0x620E, [ 6147] = 0x620C, [ 6148] = 0x620D, [ 6149] = 0x6210, ++ [ 6150] = 0x6263, [ 6151] = 0x625B, [ 6152] = 0x6258, [ 6153] = 0x6536, ++ [ 6154] = 0x65E9, [ 6155] = 0x65E8, [ 6156] = 0x65EC, [ 6157] = 0x65ED, ++ [ 6158] = 0x66F2, [ 6159] = 0x66F3, [ 6160] = 0x6709, [ 6161] = 0x673D, ++ [ 6162] = 0x6734, [ 6163] = 0x6731, [ 6164] = 0x6735, [ 6165] = 0x6B21, ++ [ 6166] = 0x6B64, [ 6167] = 0x6B7B, [ 6168] = 0x6C16, [ 6169] = 0x6C5D, ++ [ 6170] = 0x6C57, [ 6171] = 0x6C59, [ 6172] = 0x6C5F, [ 6173] = 0x6C60, ++ [ 6174] = 0x6C50, [ 6175] = 0x6C55, [ 6176] = 0x6C61, [ 6177] = 0x6C5B, ++ [ 6178] = 0x6C4D, [ 6179] = 0x6C4E, [ 6180] = 0x7070, [ 6181] = 0x725F, ++ [ 6182] = 0x725D, [ 6183] = 0x767E, [ 6184] = 0x7AF9, [ 6185] = 0x7C73, ++ [ 6186] = 0x7CF8, [ 6187] = 0x7F36, [ 6188] = 0x7F8A, [ 6189] = 0x7FBD, ++ [ 6190] = 0x8001, [ 6191] = 0x8003, [ 6192] = 0x800C, [ 6193] = 0x8012, ++ [ 6194] = 0x8033, [ 6195] = 0x807F, [ 6196] = 0x8089, [ 6197] = 0x808B, ++ [ 6198] = 0x808C, [ 6199] = 0x81E3, [ 6200] = 0x81EA, [ 6201] = 0x81F3, ++ [ 6202] = 0x81FC, [ 6203] = 0x820C, [ 6204] = 0x821B, [ 6205] = 0x821F, ++ [ 6206] = 0x826E, [ 6207] = 0x8272, [ 6208] = 0x827E, [ 6209] = 0x866B, ++ [ 6210] = 0x8840, [ 6211] = 0x884C, [ 6212] = 0x8863, [ 6213] = 0x897F, ++ [ 6214] = 0x9621, [ 6215] = 0x4E32, [ 6216] = 0x4EA8, [ 6217] = 0x4F4D, ++ [ 6218] = 0x4F4F, [ 6219] = 0x4F47, [ 6220] = 0x4F57, [ 6221] = 0x4F5E, ++ [ 6222] = 0x4F34, [ 6223] = 0x4F5B, [ 6224] = 0x4F55, [ 6225] = 0x4F30, ++ [ 6226] = 0x4F50, [ 6227] = 0x4F51, [ 6228] = 0x4F3D, [ 6229] = 0x4F3A, ++ [ 6230] = 0x4F38, [ 6231] = 0x4F43, [ 6232] = 0x4F54, [ 6233] = 0x4F3C, ++ [ 6234] = 0x4F46, [ 6235] = 0x4F63, [ 6240] = 0x4F5C, [ 6241] = 0x4F60, ++ [ 6242] = 0x4F2F, [ 6243] = 0x4F4E, [ 6244] = 0x4F36, [ 6245] = 0x4F59, ++ [ 6246] = 0x4F5D, [ 6247] = 0x4F48, [ 6248] = 0x4F5A, [ 6249] = 0x514C, ++ [ 6250] = 0x514B, [ 6251] = 0x514D, [ 6252] = 0x5175, [ 6253] = 0x51B6, ++ [ 6254] = 0x51B7, [ 6255] = 0x5225, [ 6256] = 0x5224, [ 6257] = 0x5229, ++ [ 6258] = 0x522A, [ 6259] = 0x5228, [ 6260] = 0x52AB, [ 6261] = 0x52A9, ++ [ 6262] = 0x52AA, [ 6263] = 0x52AC, [ 6264] = 0x5323, [ 6265] = 0x5373, ++ [ 6266] = 0x5375, [ 6267] = 0x541D, [ 6268] = 0x542D, [ 6269] = 0x541E, ++ [ 6270] = 0x543E, [ 6271] = 0x5426, [ 6272] = 0x544E, [ 6273] = 0x5427, ++ [ 6274] = 0x5446, [ 6275] = 0x5443, [ 6276] = 0x5433, [ 6277] = 0x5448, ++ [ 6278] = 0x5442, [ 6279] = 0x541B, [ 6280] = 0x5429, [ 6281] = 0x544A, ++ [ 6282] = 0x5439, [ 6283] = 0x543B, [ 6284] = 0x5438, [ 6285] = 0x542E, ++ [ 6286] = 0x5435, [ 6287] = 0x5436, [ 6288] = 0x5420, [ 6289] = 0x543C, ++ [ 6290] = 0x5440, [ 6291] = 0x5431, [ 6292] = 0x542B, [ 6293] = 0x541F, ++ [ 6294] = 0x542C, [ 6295] = 0x56EA, [ 6296] = 0x56F0, [ 6297] = 0x56E4, ++ [ 6298] = 0x56EB, [ 6299] = 0x574A, [ 6300] = 0x5751, [ 6301] = 0x5740, ++ [ 6302] = 0x574D, [ 6337] = 0x5747, [ 6338] = 0x574E, [ 6339] = 0x573E, ++ [ 6340] = 0x5750, [ 6341] = 0x574F, [ 6342] = 0x573B, [ 6343] = 0x58EF, ++ [ 6344] = 0x593E, [ 6345] = 0x599D, [ 6346] = 0x5992, [ 6347] = 0x59A8, ++ [ 6348] = 0x599E, [ 6349] = 0x59A3, [ 6350] = 0x5999, [ 6351] = 0x5996, ++ [ 6352] = 0x598D, [ 6353] = 0x59A4, [ 6354] = 0x5993, [ 6355] = 0x598A, ++ [ 6356] = 0x59A5, [ 6357] = 0x5B5D, [ 6358] = 0x5B5C, [ 6359] = 0x5B5A, ++ [ 6360] = 0x5B5B, [ 6361] = 0x5B8C, [ 6362] = 0x5B8B, [ 6363] = 0x5B8F, ++ [ 6364] = 0x5C2C, [ 6365] = 0x5C40, [ 6366] = 0x5C41, [ 6367] = 0x5C3F, ++ [ 6368] = 0x5C3E, [ 6369] = 0x5C90, [ 6370] = 0x5C91, [ 6371] = 0x5C94, ++ [ 6372] = 0x5C8C, [ 6373] = 0x5DEB, [ 6374] = 0x5E0C, [ 6375] = 0x5E8F, ++ [ 6376] = 0x5E87, [ 6377] = 0x5E8A, [ 6378] = 0x5EF7, [ 6379] = 0x5F04, ++ [ 6380] = 0x5F1F, [ 6381] = 0x5F64, [ 6382] = 0x5F62, [ 6383] = 0x5F77, ++ [ 6384] = 0x5F79, [ 6385] = 0x5FD8, [ 6386] = 0x5FCC, [ 6387] = 0x5FD7, ++ [ 6388] = 0x5FCD, [ 6389] = 0x5FF1, [ 6390] = 0x5FEB, [ 6391] = 0x5FF8, ++ [ 6392] = 0x5FEA, [ 6393] = 0x6212, [ 6394] = 0x6211, [ 6395] = 0x6284, ++ [ 6396] = 0x6297, [ 6397] = 0x6296, [ 6398] = 0x6280, [ 6399] = 0x6276, ++ [ 6400] = 0x6289, [ 6401] = 0x626D, [ 6402] = 0x628A, [ 6403] = 0x627C, ++ [ 6404] = 0x627E, [ 6405] = 0x6279, [ 6406] = 0x6273, [ 6407] = 0x6292, ++ [ 6408] = 0x626F, [ 6409] = 0x6298, [ 6410] = 0x626E, [ 6411] = 0x6295, ++ [ 6412] = 0x6293, [ 6413] = 0x6291, [ 6414] = 0x6286, [ 6415] = 0x6539, ++ [ 6416] = 0x653B, [ 6417] = 0x6538, [ 6418] = 0x65F1, [ 6419] = 0x66F4, ++ [ 6420] = 0x675F, [ 6421] = 0x674E, [ 6422] = 0x674F, [ 6423] = 0x6750, ++ [ 6424] = 0x6751, [ 6425] = 0x675C, [ 6426] = 0x6756, [ 6427] = 0x675E, ++ [ 6428] = 0x6749, [ 6429] = 0x6746, [ 6430] = 0x6760, [ 6435] = 0x6753, ++ [ 6436] = 0x6757, [ 6437] = 0x6B65, [ 6438] = 0x6BCF, [ 6439] = 0x6C42, ++ [ 6440] = 0x6C5E, [ 6441] = 0x6C99, [ 6442] = 0x6C81, [ 6443] = 0x6C88, ++ [ 6444] = 0x6C89, [ 6445] = 0x6C85, [ 6446] = 0x6C9B, [ 6447] = 0x6C6A, ++ [ 6448] = 0x6C7A, [ 6449] = 0x6C90, [ 6450] = 0x6C70, [ 6451] = 0x6C8C, ++ [ 6452] = 0x6C68, [ 6453] = 0x6C96, [ 6454] = 0x6C92, [ 6455] = 0x6C7D, ++ [ 6456] = 0x6C83, [ 6457] = 0x6C72, [ 6458] = 0x6C7E, [ 6459] = 0x6C74, ++ [ 6460] = 0x6C86, [ 6461] = 0x6C76, [ 6462] = 0x6C8D, [ 6463] = 0x6C94, ++ [ 6464] = 0x6C98, [ 6465] = 0x6C82, [ 6466] = 0x7076, [ 6467] = 0x707C, ++ [ 6468] = 0x707D, [ 6469] = 0x7078, [ 6470] = 0x7262, [ 6471] = 0x7261, ++ [ 6472] = 0x7260, [ 6473] = 0x72C4, [ 6474] = 0x72C2, [ 6475] = 0x7396, ++ [ 6476] = 0x752C, [ 6477] = 0x752B, [ 6478] = 0x7537, [ 6479] = 0x7538, ++ [ 6480] = 0x7682, [ 6481] = 0x76EF, [ 6482] = 0x77E3, [ 6483] = 0x79C1, ++ [ 6484] = 0x79C0, [ 6485] = 0x79BF, [ 6486] = 0x7A76, [ 6487] = 0x7CFB, ++ [ 6488] = 0x7F55, [ 6489] = 0x8096, [ 6490] = 0x8093, [ 6491] = 0x809D, ++ [ 6492] = 0x8098, [ 6493] = 0x809B, [ 6494] = 0x809A, [ 6495] = 0x80B2, ++ [ 6496] = 0x826F, [ 6497] = 0x8292, [ 6532] = 0x828B, [ 6533] = 0x828D, ++ [ 6534] = 0x898B, [ 6535] = 0x89D2, [ 6536] = 0x8A00, [ 6537] = 0x8C37, ++ [ 6538] = 0x8C46, [ 6539] = 0x8C55, [ 6540] = 0x8C9D, [ 6541] = 0x8D64, ++ [ 6542] = 0x8D70, [ 6543] = 0x8DB3, [ 6544] = 0x8EAB, [ 6545] = 0x8ECA, ++ [ 6546] = 0x8F9B, [ 6547] = 0x8FB0, [ 6548] = 0x8FC2, [ 6549] = 0x8FC6, ++ [ 6550] = 0x8FC5, [ 6551] = 0x8FC4, [ 6552] = 0x5DE1, [ 6553] = 0x9091, ++ [ 6554] = 0x90A2, [ 6555] = 0x90AA, [ 6556] = 0x90A6, [ 6557] = 0x90A3, ++ [ 6558] = 0x9149, [ 6559] = 0x91C6, [ 6560] = 0x91CC, [ 6561] = 0x9632, ++ [ 6562] = 0x962E, [ 6563] = 0x9631, [ 6564] = 0x962A, [ 6565] = 0x962C, ++ [ 6566] = 0x4E26, [ 6567] = 0x4E56, [ 6568] = 0x4E73, [ 6569] = 0x4E8B, ++ [ 6570] = 0x4E9B, [ 6571] = 0x4E9E, [ 6572] = 0x4EAB, [ 6573] = 0x4EAC, ++ [ 6574] = 0x4F6F, [ 6575] = 0x4F9D, [ 6576] = 0x4F8D, [ 6577] = 0x4F73, ++ [ 6578] = 0x4F7F, [ 6579] = 0x4F6C, [ 6580] = 0x4F9B, [ 6581] = 0x4F8B, ++ [ 6582] = 0x4F86, [ 6583] = 0x4F83, [ 6584] = 0x4F70, [ 6585] = 0x4F75, ++ [ 6586] = 0x4F88, [ 6587] = 0x4F69, [ 6588] = 0x4F7B, [ 6589] = 0x4F96, ++ [ 6590] = 0x4F7E, [ 6591] = 0x4F8F, [ 6592] = 0x4F91, [ 6593] = 0x4F7A, ++ [ 6594] = 0x5154, [ 6595] = 0x5152, [ 6596] = 0x5155, [ 6597] = 0x5169, ++ [ 6598] = 0x5177, [ 6599] = 0x5176, [ 6600] = 0x5178, [ 6601] = 0x51BD, ++ [ 6602] = 0x51FD, [ 6603] = 0x523B, [ 6604] = 0x5238, [ 6605] = 0x5237, ++ [ 6606] = 0x523A, [ 6607] = 0x5230, [ 6608] = 0x522E, [ 6609] = 0x5236, ++ [ 6610] = 0x5241, [ 6611] = 0x52BE, [ 6612] = 0x52BB, [ 6613] = 0x5352, ++ [ 6614] = 0x5354, [ 6615] = 0x5353, [ 6616] = 0x5351, [ 6617] = 0x5366, ++ [ 6618] = 0x5377, [ 6619] = 0x5378, [ 6620] = 0x5379, [ 6621] = 0x53D6, ++ [ 6622] = 0x53D4, [ 6623] = 0x53D7, [ 6624] = 0x5473, [ 6625] = 0x5475, ++ [ 6630] = 0x5496, [ 6631] = 0x5478, [ 6632] = 0x5495, [ 6633] = 0x5480, ++ [ 6634] = 0x547B, [ 6635] = 0x5477, [ 6636] = 0x5484, [ 6637] = 0x5492, ++ [ 6638] = 0x5486, [ 6639] = 0x547C, [ 6640] = 0x5490, [ 6641] = 0x5471, ++ [ 6642] = 0x5476, [ 6643] = 0x548C, [ 6644] = 0x549A, [ 6645] = 0x5462, ++ [ 6646] = 0x5468, [ 6647] = 0x548B, [ 6648] = 0x547D, [ 6649] = 0x548E, ++ [ 6650] = 0x56FA, [ 6651] = 0x5783, [ 6652] = 0x5777, [ 6653] = 0x576A, ++ [ 6654] = 0x5769, [ 6655] = 0x5761, [ 6656] = 0x5766, [ 6657] = 0x5764, ++ [ 6658] = 0x577C, [ 6659] = 0x591C, [ 6660] = 0x5949, [ 6661] = 0x5947, ++ [ 6662] = 0x5948, [ 6663] = 0x5944, [ 6664] = 0x5954, [ 6665] = 0x59BE, ++ [ 6666] = 0x59BB, [ 6667] = 0x59D4, [ 6668] = 0x59B9, [ 6669] = 0x59AE, ++ [ 6670] = 0x59D1, [ 6671] = 0x59C6, [ 6672] = 0x59D0, [ 6673] = 0x59CD, ++ [ 6674] = 0x59CB, [ 6675] = 0x59D3, [ 6676] = 0x59CA, [ 6677] = 0x59AF, ++ [ 6678] = 0x59B3, [ 6679] = 0x59D2, [ 6680] = 0x59C5, [ 6681] = 0x5B5F, ++ [ 6682] = 0x5B64, [ 6683] = 0x5B63, [ 6684] = 0x5B97, [ 6685] = 0x5B9A, ++ [ 6686] = 0x5B98, [ 6687] = 0x5B9C, [ 6688] = 0x5B99, [ 6689] = 0x5B9B, ++ [ 6690] = 0x5C1A, [ 6691] = 0x5C48, [ 6692] = 0x5C45, [ 6727] = 0x5C46, ++ [ 6728] = 0x5CB7, [ 6729] = 0x5CA1, [ 6730] = 0x5CB8, [ 6731] = 0x5CA9, ++ [ 6732] = 0x5CAB, [ 6733] = 0x5CB1, [ 6734] = 0x5CB3, [ 6735] = 0x5E18, ++ [ 6736] = 0x5E1A, [ 6737] = 0x5E16, [ 6738] = 0x5E15, [ 6739] = 0x5E1B, ++ [ 6740] = 0x5E11, [ 6741] = 0x5E78, [ 6742] = 0x5E9A, [ 6743] = 0x5E97, ++ [ 6744] = 0x5E9C, [ 6745] = 0x5E95, [ 6746] = 0x5E96, [ 6747] = 0x5EF6, ++ [ 6748] = 0x5F26, [ 6749] = 0x5F27, [ 6750] = 0x5F29, [ 6751] = 0x5F80, ++ [ 6752] = 0x5F81, [ 6753] = 0x5F7F, [ 6754] = 0x5F7C, [ 6755] = 0x5FDD, ++ [ 6756] = 0x5FE0, [ 6757] = 0x5FFD, [ 6758] = 0x5FF5, [ 6759] = 0x5FFF, ++ [ 6760] = 0x600F, [ 6761] = 0x6014, [ 6762] = 0x602F, [ 6763] = 0x6035, ++ [ 6764] = 0x6016, [ 6765] = 0x602A, [ 6766] = 0x6015, [ 6767] = 0x6021, ++ [ 6768] = 0x6027, [ 6769] = 0x6029, [ 6770] = 0x602B, [ 6771] = 0x601B, ++ [ 6772] = 0x6216, [ 6773] = 0x6215, [ 6774] = 0x623F, [ 6775] = 0x623E, ++ [ 6776] = 0x6240, [ 6777] = 0x627F, [ 6778] = 0x62C9, [ 6779] = 0x62CC, ++ [ 6780] = 0x62C4, [ 6781] = 0x62BF, [ 6782] = 0x62C2, [ 6783] = 0x62B9, ++ [ 6784] = 0x62D2, [ 6785] = 0x62DB, [ 6786] = 0x62AB, [ 6787] = 0x62D3, ++ [ 6788] = 0x62D4, [ 6789] = 0x62CB, [ 6790] = 0x62C8, [ 6791] = 0x62A8, ++ [ 6792] = 0x62BD, [ 6793] = 0x62BC, [ 6794] = 0x62D0, [ 6795] = 0x62D9, ++ [ 6796] = 0x62C7, [ 6797] = 0x62CD, [ 6798] = 0x62B5, [ 6799] = 0x62DA, ++ [ 6800] = 0x62B1, [ 6801] = 0x62D8, [ 6802] = 0x62D6, [ 6803] = 0x62D7, ++ [ 6804] = 0x62C6, [ 6805] = 0x62AC, [ 6806] = 0x62CE, [ 6807] = 0x653E, ++ [ 6808] = 0x65A7, [ 6809] = 0x65BC, [ 6810] = 0x65FA, [ 6811] = 0x6614, ++ [ 6812] = 0x6613, [ 6813] = 0x660C, [ 6814] = 0x6606, [ 6815] = 0x6602, ++ [ 6816] = 0x660E, [ 6817] = 0x6600, [ 6818] = 0x660F, [ 6819] = 0x6615, ++ [ 6820] = 0x660A, [ 6825] = 0x6607, [ 6826] = 0x670D, [ 6827] = 0x670B, ++ [ 6828] = 0x676D, [ 6829] = 0x678B, [ 6830] = 0x6795, [ 6831] = 0x6771, ++ [ 6832] = 0x679C, [ 6833] = 0x6773, [ 6834] = 0x6777, [ 6835] = 0x6787, ++ [ 6836] = 0x679D, [ 6837] = 0x6797, [ 6838] = 0x676F, [ 6839] = 0x6770, ++ [ 6840] = 0x677F, [ 6841] = 0x6789, [ 6842] = 0x677E, [ 6843] = 0x6790, ++ [ 6844] = 0x6775, [ 6845] = 0x679A, [ 6846] = 0x6793, [ 6847] = 0x677C, ++ [ 6848] = 0x676A, [ 6849] = 0x6772, [ 6850] = 0x6B23, [ 6851] = 0x6B66, ++ [ 6852] = 0x6B67, [ 6853] = 0x6B7F, [ 6854] = 0x6C13, [ 6855] = 0x6C1B, ++ [ 6856] = 0x6CE3, [ 6857] = 0x6CE8, [ 6858] = 0x6CF3, [ 6859] = 0x6CB1, ++ [ 6860] = 0x6CCC, [ 6861] = 0x6CE5, [ 6862] = 0x6CB3, [ 6863] = 0x6CBD, ++ [ 6864] = 0x6CBE, [ 6865] = 0x6CBC, [ 6866] = 0x6CE2, [ 6867] = 0x6CAB, ++ [ 6868] = 0x6CD5, [ 6869] = 0x6CD3, [ 6870] = 0x6CB8, [ 6871] = 0x6CC4, ++ [ 6872] = 0x6CB9, [ 6873] = 0x6CC1, [ 6874] = 0x6CAE, [ 6875] = 0x6CD7, ++ [ 6876] = 0x6CC5, [ 6877] = 0x6CF1, [ 6878] = 0x6CBF, [ 6879] = 0x6CBB, ++ [ 6880] = 0x6CE1, [ 6881] = 0x6CDB, [ 6882] = 0x6CCA, [ 6883] = 0x6CAC, ++ [ 6884] = 0x6CEF, [ 6885] = 0x6CDC, [ 6886] = 0x6CD6, [ 6887] = 0x6CE0, ++ [ 6922] = 0x7095, [ 6923] = 0x708E, [ 6924] = 0x7092, [ 6925] = 0x708A, ++ [ 6926] = 0x7099, [ 6927] = 0x722C, [ 6928] = 0x722D, [ 6929] = 0x7238, ++ [ 6930] = 0x7248, [ 6931] = 0x7267, [ 6932] = 0x7269, [ 6933] = 0x72C0, ++ [ 6934] = 0x72CE, [ 6935] = 0x72D9, [ 6936] = 0x72D7, [ 6937] = 0x72D0, ++ [ 6938] = 0x73A9, [ 6939] = 0x73A8, [ 6940] = 0x739F, [ 6941] = 0x73AB, ++ [ 6942] = 0x73A5, [ 6943] = 0x753D, [ 6944] = 0x759D, [ 6945] = 0x7599, ++ [ 6946] = 0x759A, [ 6947] = 0x7684, [ 6948] = 0x76C2, [ 6949] = 0x76F2, ++ [ 6950] = 0x76F4, [ 6951] = 0x77E5, [ 6952] = 0x77FD, [ 6953] = 0x793E, ++ [ 6954] = 0x7940, [ 6955] = 0x7941, [ 6956] = 0x79C9, [ 6957] = 0x79C8, ++ [ 6958] = 0x7A7A, [ 6959] = 0x7A79, [ 6960] = 0x7AFA, [ 6961] = 0x7CFE, ++ [ 6962] = 0x7F54, [ 6963] = 0x7F8C, [ 6964] = 0x7F8B, [ 6965] = 0x8005, ++ [ 6966] = 0x80BA, [ 6967] = 0x80A5, [ 6968] = 0x80A2, [ 6969] = 0x80B1, ++ [ 6970] = 0x80A1, [ 6971] = 0x80AB, [ 6972] = 0x80A9, [ 6973] = 0x80B4, ++ [ 6974] = 0x80AA, [ 6975] = 0x80AF, [ 6976] = 0x81E5, [ 6977] = 0x81FE, ++ [ 6978] = 0x820D, [ 6979] = 0x82B3, [ 6980] = 0x829D, [ 6981] = 0x8299, ++ [ 6982] = 0x82AD, [ 6983] = 0x82BD, [ 6984] = 0x829F, [ 6985] = 0x82B9, ++ [ 6986] = 0x82B1, [ 6987] = 0x82AC, [ 6988] = 0x82A5, [ 6989] = 0x82AF, ++ [ 6990] = 0x82B8, [ 6991] = 0x82A3, [ 6992] = 0x82B0, [ 6993] = 0x82BE, ++ [ 6994] = 0x82B7, [ 6995] = 0x864E, [ 6996] = 0x8671, [ 6997] = 0x521D, ++ [ 6998] = 0x8868, [ 6999] = 0x8ECB, [ 7000] = 0x8FCE, [ 7001] = 0x8FD4, ++ [ 7002] = 0x8FD1, [ 7003] = 0x90B5, [ 7004] = 0x90B8, [ 7005] = 0x90B1, ++ [ 7006] = 0x90B6, [ 7007] = 0x91C7, [ 7008] = 0x91D1, [ 7009] = 0x9577, ++ [ 7010] = 0x9580, [ 7011] = 0x961C, [ 7012] = 0x9640, [ 7013] = 0x963F, ++ [ 7014] = 0x963B, [ 7015] = 0x9644, [ 7020] = 0x9642, [ 7021] = 0x96B9, ++ [ 7022] = 0x96E8, [ 7023] = 0x9752, [ 7024] = 0x975E, [ 7025] = 0x4E9F, ++ [ 7026] = 0x4EAD, [ 7027] = 0x4EAE, [ 7028] = 0x4FE1, [ 7029] = 0x4FB5, ++ [ 7030] = 0x4FAF, [ 7031] = 0x4FBF, [ 7032] = 0x4FE0, [ 7033] = 0x4FD1, ++ [ 7034] = 0x4FCF, [ 7035] = 0x4FDD, [ 7036] = 0x4FC3, [ 7037] = 0x4FB6, ++ [ 7038] = 0x4FD8, [ 7039] = 0x4FDF, [ 7040] = 0x4FCA, [ 7041] = 0x4FD7, ++ [ 7042] = 0x4FAE, [ 7043] = 0x4FD0, [ 7044] = 0x4FC4, [ 7045] = 0x4FC2, ++ [ 7046] = 0x4FDA, [ 7047] = 0x4FCE, [ 7048] = 0x4FDE, [ 7049] = 0x4FB7, ++ [ 7050] = 0x5157, [ 7051] = 0x5192, [ 7052] = 0x5191, [ 7053] = 0x51A0, ++ [ 7054] = 0x524E, [ 7055] = 0x5243, [ 7056] = 0x524A, [ 7057] = 0x524D, ++ [ 7058] = 0x524C, [ 7059] = 0x524B, [ 7060] = 0x5247, [ 7061] = 0x52C7, ++ [ 7062] = 0x52C9, [ 7063] = 0x52C3, [ 7064] = 0x52C1, [ 7065] = 0x530D, ++ [ 7066] = 0x5357, [ 7067] = 0x537B, [ 7068] = 0x539A, [ 7069] = 0x53DB, ++ [ 7070] = 0x54AC, [ 7071] = 0x54C0, [ 7072] = 0x54A8, [ 7073] = 0x54CE, ++ [ 7074] = 0x54C9, [ 7075] = 0x54B8, [ 7076] = 0x54A6, [ 7077] = 0x54B3, ++ [ 7078] = 0x54C7, [ 7079] = 0x54C2, [ 7080] = 0x54BD, [ 7081] = 0x54AA, ++ [ 7082] = 0x54C1, [ 7117] = 0x54C4, [ 7118] = 0x54C8, [ 7119] = 0x54AF, ++ [ 7120] = 0x54AB, [ 7121] = 0x54B1, [ 7122] = 0x54BB, [ 7123] = 0x54A9, ++ [ 7124] = 0x54A7, [ 7125] = 0x54BF, [ 7126] = 0x56FF, [ 7127] = 0x5782, ++ [ 7128] = 0x578B, [ 7129] = 0x57A0, [ 7130] = 0x57A3, [ 7131] = 0x57A2, ++ [ 7132] = 0x57CE, [ 7133] = 0x57AE, [ 7134] = 0x5793, [ 7135] = 0x5955, ++ [ 7136] = 0x5951, [ 7137] = 0x594F, [ 7138] = 0x594E, [ 7139] = 0x5950, ++ [ 7140] = 0x59DC, [ 7141] = 0x59D8, [ 7142] = 0x59FF, [ 7143] = 0x59E3, ++ [ 7144] = 0x59E8, [ 7145] = 0x5A03, [ 7146] = 0x59E5, [ 7147] = 0x59EA, ++ [ 7148] = 0x59DA, [ 7149] = 0x59E6, [ 7150] = 0x5A01, [ 7151] = 0x59FB, ++ [ 7152] = 0x5B69, [ 7153] = 0x5BA3, [ 7154] = 0x5BA6, [ 7155] = 0x5BA4, ++ [ 7156] = 0x5BA2, [ 7157] = 0x5BA5, [ 7158] = 0x5C01, [ 7159] = 0x5C4E, ++ [ 7160] = 0x5C4F, [ 7161] = 0x5C4D, [ 7162] = 0x5C4B, [ 7163] = 0x5CD9, ++ [ 7164] = 0x5CD2, [ 7165] = 0x5DF7, [ 7166] = 0x5E1D, [ 7167] = 0x5E25, ++ [ 7168] = 0x5E1F, [ 7169] = 0x5E7D, [ 7170] = 0x5EA0, [ 7171] = 0x5EA6, ++ [ 7172] = 0x5EFA, [ 7173] = 0x5F08, [ 7174] = 0x5F2D, [ 7175] = 0x5F65, ++ [ 7176] = 0x5F88, [ 7177] = 0x5F85, [ 7178] = 0x5F8A, [ 7179] = 0x5F8B, ++ [ 7180] = 0x5F87, [ 7181] = 0x5F8C, [ 7182] = 0x5F89, [ 7183] = 0x6012, ++ [ 7184] = 0x601D, [ 7185] = 0x6020, [ 7186] = 0x6025, [ 7187] = 0x600E, ++ [ 7188] = 0x6028, [ 7189] = 0x604D, [ 7190] = 0x6070, [ 7191] = 0x6068, ++ [ 7192] = 0x6062, [ 7193] = 0x6046, [ 7194] = 0x6043, [ 7195] = 0x606C, ++ [ 7196] = 0x606B, [ 7197] = 0x606A, [ 7198] = 0x6064, [ 7199] = 0x6241, ++ [ 7200] = 0x62DC, [ 7201] = 0x6316, [ 7202] = 0x6309, [ 7203] = 0x62FC, ++ [ 7204] = 0x62ED, [ 7205] = 0x6301, [ 7206] = 0x62EE, [ 7207] = 0x62FD, ++ [ 7208] = 0x6307, [ 7209] = 0x62F1, [ 7210] = 0x62F7, [ 7215] = 0x62EF, ++ [ 7216] = 0x62EC, [ 7217] = 0x62FE, [ 7218] = 0x62F4, [ 7219] = 0x6311, ++ [ 7220] = 0x6302, [ 7221] = 0x653F, [ 7222] = 0x6545, [ 7223] = 0x65AB, ++ [ 7224] = 0x65BD, [ 7225] = 0x65E2, [ 7226] = 0x6625, [ 7227] = 0x662D, ++ [ 7228] = 0x6620, [ 7229] = 0x6627, [ 7230] = 0x662F, [ 7231] = 0x661F, ++ [ 7232] = 0x6628, [ 7233] = 0x6631, [ 7234] = 0x6624, [ 7235] = 0x66F7, ++ [ 7236] = 0x67FF, [ 7237] = 0x67D3, [ 7238] = 0x67F1, [ 7239] = 0x67D4, ++ [ 7240] = 0x67D0, [ 7241] = 0x67EC, [ 7242] = 0x67B6, [ 7243] = 0x67AF, ++ [ 7244] = 0x67F5, [ 7245] = 0x67E9, [ 7246] = 0x67EF, [ 7247] = 0x67C4, ++ [ 7248] = 0x67D1, [ 7249] = 0x67B4, [ 7250] = 0x67DA, [ 7251] = 0x67E5, ++ [ 7252] = 0x67B8, [ 7253] = 0x67CF, [ 7254] = 0x67DE, [ 7255] = 0x67F3, ++ [ 7256] = 0x67B0, [ 7257] = 0x67D9, [ 7258] = 0x67E2, [ 7259] = 0x67DD, ++ [ 7260] = 0x67D2, [ 7261] = 0x6B6A, [ 7262] = 0x6B83, [ 7263] = 0x6B86, ++ [ 7264] = 0x6BB5, [ 7265] = 0x6BD2, [ 7266] = 0x6BD7, [ 7267] = 0x6C1F, ++ [ 7268] = 0x6CC9, [ 7269] = 0x6D0B, [ 7270] = 0x6D32, [ 7271] = 0x6D2A, ++ [ 7272] = 0x6D41, [ 7273] = 0x6D25, [ 7274] = 0x6D0C, [ 7275] = 0x6D31, ++ [ 7276] = 0x6D1E, [ 7277] = 0x6D17, [ 7312] = 0x6D3B, [ 7313] = 0x6D3D, ++ [ 7314] = 0x6D3E, [ 7315] = 0x6D36, [ 7316] = 0x6D1B, [ 7317] = 0x6CF5, ++ [ 7318] = 0x6D39, [ 7319] = 0x6D27, [ 7320] = 0x6D38, [ 7321] = 0x6D29, ++ [ 7322] = 0x6D2E, [ 7323] = 0x6D35, [ 7324] = 0x6D0E, [ 7325] = 0x6D2B, ++ [ 7326] = 0x70AB, [ 7327] = 0x70BA, [ 7328] = 0x70B3, [ 7329] = 0x70AC, ++ [ 7330] = 0x70AF, [ 7331] = 0x70AD, [ 7332] = 0x70B8, [ 7333] = 0x70AE, ++ [ 7334] = 0x70A4, [ 7335] = 0x7230, [ 7336] = 0x7272, [ 7337] = 0x726F, ++ [ 7338] = 0x7274, [ 7339] = 0x72E9, [ 7340] = 0x72E0, [ 7341] = 0x72E1, ++ [ 7342] = 0x73B7, [ 7343] = 0x73CA, [ 7344] = 0x73BB, [ 7345] = 0x73B2, ++ [ 7346] = 0x73CD, [ 7347] = 0x73C0, [ 7348] = 0x73B3, [ 7349] = 0x751A, ++ [ 7350] = 0x752D, [ 7351] = 0x754F, [ 7352] = 0x754C, [ 7353] = 0x754E, ++ [ 7354] = 0x754B, [ 7355] = 0x75AB, [ 7356] = 0x75A4, [ 7357] = 0x75A5, ++ [ 7358] = 0x75A2, [ 7359] = 0x75A3, [ 7360] = 0x7678, [ 7361] = 0x7686, ++ [ 7362] = 0x7687, [ 7363] = 0x7688, [ 7364] = 0x76C8, [ 7365] = 0x76C6, ++ [ 7366] = 0x76C3, [ 7367] = 0x76C5, [ 7368] = 0x7701, [ 7369] = 0x76F9, ++ [ 7370] = 0x76F8, [ 7371] = 0x7709, [ 7372] = 0x770B, [ 7373] = 0x76FE, ++ [ 7374] = 0x76FC, [ 7375] = 0x7707, [ 7376] = 0x77DC, [ 7377] = 0x7802, ++ [ 7378] = 0x7814, [ 7379] = 0x780C, [ 7380] = 0x780D, [ 7381] = 0x7946, ++ [ 7382] = 0x7949, [ 7383] = 0x7948, [ 7384] = 0x7947, [ 7385] = 0x79B9, ++ [ 7386] = 0x79BA, [ 7387] = 0x79D1, [ 7388] = 0x79D2, [ 7389] = 0x79CB, ++ [ 7390] = 0x7A7F, [ 7391] = 0x7A81, [ 7392] = 0x7AFF, [ 7393] = 0x7AFD, ++ [ 7394] = 0x7C7D, [ 7395] = 0x7D02, [ 7396] = 0x7D05, [ 7397] = 0x7D00, ++ [ 7398] = 0x7D09, [ 7399] = 0x7D07, [ 7400] = 0x7D04, [ 7401] = 0x7D06, ++ [ 7402] = 0x7F38, [ 7403] = 0x7F8E, [ 7404] = 0x7FBF, [ 7405] = 0x8004, ++ [ 7410] = 0x8010, [ 7411] = 0x800D, [ 7412] = 0x8011, [ 7413] = 0x8036, ++ [ 7414] = 0x80D6, [ 7415] = 0x80E5, [ 7416] = 0x80DA, [ 7417] = 0x80C3, ++ [ 7418] = 0x80C4, [ 7419] = 0x80CC, [ 7420] = 0x80E1, [ 7421] = 0x80DB, ++ [ 7422] = 0x80CE, [ 7423] = 0x80DE, [ 7424] = 0x80E4, [ 7425] = 0x80DD, ++ [ 7426] = 0x81F4, [ 7427] = 0x8222, [ 7428] = 0x82E7, [ 7429] = 0x8303, ++ [ 7430] = 0x8305, [ 7431] = 0x82E3, [ 7432] = 0x82DB, [ 7433] = 0x82E6, ++ [ 7434] = 0x8304, [ 7435] = 0x82E5, [ 7436] = 0x8302, [ 7437] = 0x8309, ++ [ 7438] = 0x82D2, [ 7439] = 0x82D7, [ 7440] = 0x82F1, [ 7441] = 0x8301, ++ [ 7442] = 0x82DC, [ 7443] = 0x82D4, [ 7444] = 0x82D1, [ 7445] = 0x82DE, ++ [ 7446] = 0x82D3, [ 7447] = 0x82DF, [ 7448] = 0x82EF, [ 7449] = 0x8306, ++ [ 7450] = 0x8650, [ 7451] = 0x8679, [ 7452] = 0x867B, [ 7453] = 0x867A, ++ [ 7454] = 0x884D, [ 7455] = 0x886B, [ 7456] = 0x8981, [ 7457] = 0x89D4, ++ [ 7458] = 0x8A08, [ 7459] = 0x8A02, [ 7460] = 0x8A03, [ 7461] = 0x8C9E, ++ [ 7462] = 0x8CA0, [ 7463] = 0x8D74, [ 7464] = 0x8D73, [ 7465] = 0x8DB4, ++ [ 7466] = 0x8ECD, [ 7467] = 0x8ECC, [ 7468] = 0x8FF0, [ 7469] = 0x8FE6, ++ [ 7470] = 0x8FE2, [ 7471] = 0x8FEA, [ 7472] = 0x8FE5, [ 7507] = 0x8FED, ++ [ 7508] = 0x8FEB, [ 7509] = 0x8FE4, [ 7510] = 0x8FE8, [ 7511] = 0x90CA, ++ [ 7512] = 0x90CE, [ 7513] = 0x90C1, [ 7514] = 0x90C3, [ 7515] = 0x914B, ++ [ 7516] = 0x914A, [ 7517] = 0x91CD, [ 7518] = 0x9582, [ 7519] = 0x9650, ++ [ 7520] = 0x964B, [ 7521] = 0x964C, [ 7522] = 0x964D, [ 7523] = 0x9762, ++ [ 7524] = 0x9769, [ 7525] = 0x97CB, [ 7526] = 0x97ED, [ 7527] = 0x97F3, ++ [ 7528] = 0x9801, [ 7529] = 0x98A8, [ 7530] = 0x98DB, [ 7531] = 0x98DF, ++ [ 7532] = 0x9996, [ 7533] = 0x9999, [ 7534] = 0x4E58, [ 7535] = 0x4EB3, ++ [ 7536] = 0x500C, [ 7537] = 0x500D, [ 7538] = 0x5023, [ 7539] = 0x4FEF, ++ [ 7540] = 0x5026, [ 7541] = 0x5025, [ 7542] = 0x4FF8, [ 7543] = 0x5029, ++ [ 7544] = 0x5016, [ 7545] = 0x5006, [ 7546] = 0x503C, [ 7547] = 0x501F, ++ [ 7548] = 0x501A, [ 7549] = 0x5012, [ 7550] = 0x5011, [ 7551] = 0x4FFA, ++ [ 7552] = 0x5000, [ 7553] = 0x5014, [ 7554] = 0x5028, [ 7555] = 0x4FF1, ++ [ 7556] = 0x5021, [ 7557] = 0x500B, [ 7558] = 0x5019, [ 7559] = 0x5018, ++ [ 7560] = 0x4FF3, [ 7561] = 0x4FEE, [ 7562] = 0x502D, [ 7563] = 0x502A, ++ [ 7564] = 0x4FFE, [ 7565] = 0x502B, [ 7566] = 0x5009, [ 7567] = 0x517C, ++ [ 7568] = 0x51A4, [ 7569] = 0x51A5, [ 7570] = 0x51A2, [ 7571] = 0x51CD, ++ [ 7572] = 0x51CC, [ 7573] = 0x51C6, [ 7574] = 0x51CB, [ 7575] = 0x5256, ++ [ 7576] = 0x525C, [ 7577] = 0x5254, [ 7578] = 0x525B, [ 7579] = 0x525D, ++ [ 7580] = 0x532A, [ 7581] = 0x537F, [ 7582] = 0x539F, [ 7583] = 0x539D, ++ [ 7584] = 0x53DF, [ 7585] = 0x54E8, [ 7586] = 0x5510, [ 7587] = 0x5501, ++ [ 7588] = 0x5537, [ 7589] = 0x54FC, [ 7590] = 0x54E5, [ 7591] = 0x54F2, ++ [ 7592] = 0x5506, [ 7593] = 0x54FA, [ 7594] = 0x5514, [ 7595] = 0x54E9, ++ [ 7596] = 0x54ED, [ 7597] = 0x54E1, [ 7598] = 0x5509, [ 7599] = 0x54EE, ++ [ 7600] = 0x54EA, [ 7605] = 0x54E6, [ 7606] = 0x5527, [ 7607] = 0x5507, ++ [ 7608] = 0x54FD, [ 7609] = 0x550F, [ 7610] = 0x5703, [ 7611] = 0x5704, ++ [ 7612] = 0x57C2, [ 7613] = 0x57D4, [ 7614] = 0x57CB, [ 7615] = 0x57C3, ++ [ 7616] = 0x5809, [ 7617] = 0x590F, [ 7618] = 0x5957, [ 7619] = 0x5958, ++ [ 7620] = 0x595A, [ 7621] = 0x5A11, [ 7622] = 0x5A18, [ 7623] = 0x5A1C, ++ [ 7624] = 0x5A1F, [ 7625] = 0x5A1B, [ 7626] = 0x5A13, [ 7627] = 0x59EC, ++ [ 7628] = 0x5A20, [ 7629] = 0x5A23, [ 7630] = 0x5A29, [ 7631] = 0x5A25, ++ [ 7632] = 0x5A0C, [ 7633] = 0x5A09, [ 7634] = 0x5B6B, [ 7635] = 0x5C58, ++ [ 7636] = 0x5BB0, [ 7637] = 0x5BB3, [ 7638] = 0x5BB6, [ 7639] = 0x5BB4, ++ [ 7640] = 0x5BAE, [ 7641] = 0x5BB5, [ 7642] = 0x5BB9, [ 7643] = 0x5BB8, ++ [ 7644] = 0x5C04, [ 7645] = 0x5C51, [ 7646] = 0x5C55, [ 7647] = 0x5C50, ++ [ 7648] = 0x5CED, [ 7649] = 0x5CFD, [ 7650] = 0x5CFB, [ 7651] = 0x5CEA, ++ [ 7652] = 0x5CE8, [ 7653] = 0x5CF0, [ 7654] = 0x5CF6, [ 7655] = 0x5D01, ++ [ 7656] = 0x5CF4, [ 7657] = 0x5DEE, [ 7658] = 0x5E2D, [ 7659] = 0x5E2B, ++ [ 7660] = 0x5EAB, [ 7661] = 0x5EAD, [ 7662] = 0x5EA7, [ 7663] = 0x5F31, ++ [ 7664] = 0x5F92, [ 7665] = 0x5F91, [ 7666] = 0x5F90, [ 7667] = 0x6059, ++ [ 7702] = 0x6063, [ 7703] = 0x6065, [ 7704] = 0x6050, [ 7705] = 0x6055, ++ [ 7706] = 0x606D, [ 7707] = 0x6069, [ 7708] = 0x606F, [ 7709] = 0x6084, ++ [ 7710] = 0x609F, [ 7711] = 0x609A, [ 7712] = 0x608D, [ 7713] = 0x6094, ++ [ 7714] = 0x608C, [ 7715] = 0x6085, [ 7716] = 0x6096, [ 7717] = 0x6247, ++ [ 7718] = 0x62F3, [ 7719] = 0x6308, [ 7720] = 0x62FF, [ 7721] = 0x634E, ++ [ 7722] = 0x633E, [ 7723] = 0x632F, [ 7724] = 0x6355, [ 7725] = 0x6342, ++ [ 7726] = 0x6346, [ 7727] = 0x634F, [ 7728] = 0x6349, [ 7729] = 0x633A, ++ [ 7730] = 0x6350, [ 7731] = 0x633D, [ 7732] = 0x632A, [ 7733] = 0x632B, ++ [ 7734] = 0x6328, [ 7735] = 0x634D, [ 7736] = 0x634C, [ 7737] = 0x6548, ++ [ 7738] = 0x6549, [ 7739] = 0x6599, [ 7740] = 0x65C1, [ 7741] = 0x65C5, ++ [ 7742] = 0x6642, [ 7743] = 0x6649, [ 7744] = 0x664F, [ 7745] = 0x6643, ++ [ 7746] = 0x6652, [ 7747] = 0x664C, [ 7748] = 0x6645, [ 7749] = 0x6641, ++ [ 7750] = 0x66F8, [ 7751] = 0x6714, [ 7752] = 0x6715, [ 7753] = 0x6717, ++ [ 7754] = 0x6821, [ 7755] = 0x6838, [ 7756] = 0x6848, [ 7757] = 0x6846, ++ [ 7758] = 0x6853, [ 7759] = 0x6839, [ 7760] = 0x6842, [ 7761] = 0x6854, ++ [ 7762] = 0x6829, [ 7763] = 0x68B3, [ 7764] = 0x6817, [ 7765] = 0x684C, ++ [ 7766] = 0x6851, [ 7767] = 0x683D, [ 7768] = 0x67F4, [ 7769] = 0x6850, ++ [ 7770] = 0x6840, [ 7771] = 0x683C, [ 7772] = 0x6843, [ 7773] = 0x682A, ++ [ 7774] = 0x6845, [ 7775] = 0x6813, [ 7776] = 0x6818, [ 7777] = 0x6841, ++ [ 7778] = 0x6B8A, [ 7779] = 0x6B89, [ 7780] = 0x6BB7, [ 7781] = 0x6C23, ++ [ 7782] = 0x6C27, [ 7783] = 0x6C28, [ 7784] = 0x6C26, [ 7785] = 0x6C24, ++ [ 7786] = 0x6CF0, [ 7787] = 0x6D6A, [ 7788] = 0x6D95, [ 7789] = 0x6D88, ++ [ 7790] = 0x6D87, [ 7791] = 0x6D66, [ 7792] = 0x6D78, [ 7793] = 0x6D77, ++ [ 7794] = 0x6D59, [ 7795] = 0x6D93, [ 7800] = 0x6D6C, [ 7801] = 0x6D89, ++ [ 7802] = 0x6D6E, [ 7803] = 0x6D5A, [ 7804] = 0x6D74, [ 7805] = 0x6D69, ++ [ 7806] = 0x6D8C, [ 7807] = 0x6D8A, [ 7808] = 0x6D79, [ 7809] = 0x6D85, ++ [ 7810] = 0x6D65, [ 7811] = 0x6D94, [ 7812] = 0x70CA, [ 7813] = 0x70D8, ++ [ 7814] = 0x70E4, [ 7815] = 0x70D9, [ 7816] = 0x70C8, [ 7817] = 0x70CF, ++ [ 7818] = 0x7239, [ 7819] = 0x7279, [ 7820] = 0x72FC, [ 7821] = 0x72F9, ++ [ 7822] = 0x72FD, [ 7823] = 0x72F8, [ 7824] = 0x72F7, [ 7825] = 0x7386, ++ [ 7826] = 0x73ED, [ 7827] = 0x7409, [ 7828] = 0x73EE, [ 7829] = 0x73E0, ++ [ 7830] = 0x73EA, [ 7831] = 0x73DE, [ 7832] = 0x7554, [ 7833] = 0x755D, ++ [ 7834] = 0x755C, [ 7835] = 0x755A, [ 7836] = 0x7559, [ 7837] = 0x75BE, ++ [ 7838] = 0x75C5, [ 7839] = 0x75C7, [ 7840] = 0x75B2, [ 7841] = 0x75B3, ++ [ 7842] = 0x75BD, [ 7843] = 0x75BC, [ 7844] = 0x75B9, [ 7845] = 0x75C2, ++ [ 7846] = 0x75B8, [ 7847] = 0x768B, [ 7848] = 0x76B0, [ 7849] = 0x76CA, ++ [ 7850] = 0x76CD, [ 7851] = 0x76CE, [ 7852] = 0x7729, [ 7853] = 0x771F, ++ [ 7854] = 0x7720, [ 7855] = 0x7728, [ 7856] = 0x77E9, [ 7857] = 0x7830, ++ [ 7858] = 0x7827, [ 7859] = 0x7838, [ 7860] = 0x781D, [ 7861] = 0x7834, ++ [ 7862] = 0x7837, [ 7897] = 0x7825, [ 7898] = 0x782D, [ 7899] = 0x7820, ++ [ 7900] = 0x781F, [ 7901] = 0x7832, [ 7902] = 0x7955, [ 7903] = 0x7950, ++ [ 7904] = 0x7960, [ 7905] = 0x795F, [ 7906] = 0x7956, [ 7907] = 0x795E, ++ [ 7908] = 0x795D, [ 7909] = 0x7957, [ 7910] = 0x795A, [ 7911] = 0x79E4, ++ [ 7912] = 0x79E3, [ 7913] = 0x79E7, [ 7914] = 0x79DF, [ 7915] = 0x79E6, ++ [ 7916] = 0x79E9, [ 7917] = 0x79D8, [ 7918] = 0x7A84, [ 7919] = 0x7A88, ++ [ 7920] = 0x7AD9, [ 7921] = 0x7B06, [ 7922] = 0x7B11, [ 7923] = 0x7C89, ++ [ 7924] = 0x7D21, [ 7925] = 0x7D17, [ 7926] = 0x7D0B, [ 7927] = 0x7D0A, ++ [ 7928] = 0x7D20, [ 7929] = 0x7D22, [ 7930] = 0x7D14, [ 7931] = 0x7D10, ++ [ 7932] = 0x7D15, [ 7933] = 0x7D1A, [ 7934] = 0x7D1C, [ 7935] = 0x7D0D, ++ [ 7936] = 0x7D19, [ 7937] = 0x7D1B, [ 7938] = 0x7F3A, [ 7939] = 0x7F5F, ++ [ 7940] = 0x7F94, [ 7941] = 0x7FC5, [ 7942] = 0x7FC1, [ 7943] = 0x8006, ++ [ 7944] = 0x8018, [ 7945] = 0x8015, [ 7946] = 0x8019, [ 7947] = 0x8017, ++ [ 7948] = 0x803D, [ 7949] = 0x803F, [ 7950] = 0x80F1, [ 7951] = 0x8102, ++ [ 7952] = 0x80F0, [ 7953] = 0x8105, [ 7954] = 0x80ED, [ 7955] = 0x80F4, ++ [ 7956] = 0x8106, [ 7957] = 0x80F8, [ 7958] = 0x80F3, [ 7959] = 0x8108, ++ [ 7960] = 0x80FD, [ 7961] = 0x810A, [ 7962] = 0x80FC, [ 7963] = 0x80EF, ++ [ 7964] = 0x81ED, [ 7965] = 0x81EC, [ 7966] = 0x8200, [ 7967] = 0x8210, ++ [ 7968] = 0x822A, [ 7969] = 0x822B, [ 7970] = 0x8228, [ 7971] = 0x822C, ++ [ 7972] = 0x82BB, [ 7973] = 0x832B, [ 7974] = 0x8352, [ 7975] = 0x8354, ++ [ 7976] = 0x834A, [ 7977] = 0x8338, [ 7978] = 0x8350, [ 7979] = 0x8349, ++ [ 7980] = 0x8335, [ 7981] = 0x8334, [ 7982] = 0x834F, [ 7983] = 0x8332, ++ [ 7984] = 0x8339, [ 7985] = 0x8336, [ 7986] = 0x8317, [ 7987] = 0x8340, ++ [ 7988] = 0x8331, [ 7989] = 0x8328, [ 7990] = 0x8343, [ 7995] = 0x8654, ++ [ 7996] = 0x868A, [ 7997] = 0x86AA, [ 7998] = 0x8693, [ 7999] = 0x86A4, ++ [ 8000] = 0x86A9, [ 8001] = 0x868C, [ 8002] = 0x86A3, [ 8003] = 0x869C, ++ [ 8004] = 0x8870, [ 8005] = 0x8877, [ 8006] = 0x8881, [ 8007] = 0x8882, ++ [ 8008] = 0x887D, [ 8009] = 0x8879, [ 8010] = 0x8A18, [ 8011] = 0x8A10, ++ [ 8012] = 0x8A0E, [ 8013] = 0x8A0C, [ 8014] = 0x8A15, [ 8015] = 0x8A0A, ++ [ 8016] = 0x8A17, [ 8017] = 0x8A13, [ 8018] = 0x8A16, [ 8019] = 0x8A0F, ++ [ 8020] = 0x8A11, [ 8021] = 0x8C48, [ 8022] = 0x8C7A, [ 8023] = 0x8C79, ++ [ 8024] = 0x8CA1, [ 8025] = 0x8CA2, [ 8026] = 0x8D77, [ 8027] = 0x8EAC, ++ [ 8028] = 0x8ED2, [ 8029] = 0x8ED4, [ 8030] = 0x8ECF, [ 8031] = 0x8FB1, ++ [ 8032] = 0x9001, [ 8033] = 0x9006, [ 8034] = 0x8FF7, [ 8035] = 0x9000, ++ [ 8036] = 0x8FFA, [ 8037] = 0x8FF4, [ 8038] = 0x9003, [ 8039] = 0x8FFD, ++ [ 8040] = 0x9005, [ 8041] = 0x8FF8, [ 8042] = 0x9095, [ 8043] = 0x90E1, ++ [ 8044] = 0x90DD, [ 8045] = 0x90E2, [ 8046] = 0x9152, [ 8047] = 0x914D, ++ [ 8048] = 0x914C, [ 8049] = 0x91D8, [ 8050] = 0x91DD, [ 8051] = 0x91D7, ++ [ 8052] = 0x91DC, [ 8053] = 0x91D9, [ 8054] = 0x9583, [ 8055] = 0x9662, ++ [ 8056] = 0x9663, [ 8057] = 0x9661, [ 8092] = 0x965B, [ 8093] = 0x965D, ++ [ 8094] = 0x9664, [ 8095] = 0x9658, [ 8096] = 0x965E, [ 8097] = 0x96BB, ++ [ 8098] = 0x98E2, [ 8099] = 0x99AC, [ 8100] = 0x9AA8, [ 8101] = 0x9AD8, ++ [ 8102] = 0x9B25, [ 8103] = 0x9B32, [ 8104] = 0x9B3C, [ 8105] = 0x4E7E, ++ [ 8106] = 0x507A, [ 8107] = 0x507D, [ 8108] = 0x505C, [ 8109] = 0x5047, ++ [ 8110] = 0x5043, [ 8111] = 0x504C, [ 8112] = 0x505A, [ 8113] = 0x5049, ++ [ 8114] = 0x5065, [ 8115] = 0x5076, [ 8116] = 0x504E, [ 8117] = 0x5055, ++ [ 8118] = 0x5075, [ 8119] = 0x5074, [ 8120] = 0x5077, [ 8121] = 0x504F, ++ [ 8122] = 0x500F, [ 8123] = 0x506F, [ 8124] = 0x506D, [ 8125] = 0x515C, ++ [ 8126] = 0x5195, [ 8127] = 0x51F0, [ 8128] = 0x526A, [ 8129] = 0x526F, ++ [ 8130] = 0x52D2, [ 8131] = 0x52D9, [ 8132] = 0x52D8, [ 8133] = 0x52D5, ++ [ 8134] = 0x5310, [ 8135] = 0x530F, [ 8136] = 0x5319, [ 8137] = 0x533F, ++ [ 8138] = 0x5340, [ 8139] = 0x533E, [ 8140] = 0x53C3, [ 8141] = 0x66FC, ++ [ 8142] = 0x5546, [ 8143] = 0x556A, [ 8144] = 0x5566, [ 8145] = 0x5544, ++ [ 8146] = 0x555E, [ 8147] = 0x5561, [ 8148] = 0x5543, [ 8149] = 0x554A, ++ [ 8150] = 0x5531, [ 8151] = 0x5556, [ 8152] = 0x554F, [ 8153] = 0x5555, ++ [ 8154] = 0x552F, [ 8155] = 0x5564, [ 8156] = 0x5538, [ 8157] = 0x552E, ++ [ 8158] = 0x555C, [ 8159] = 0x552C, [ 8160] = 0x5563, [ 8161] = 0x5533, ++ [ 8162] = 0x5541, [ 8163] = 0x5557, [ 8164] = 0x5708, [ 8165] = 0x570B, ++ [ 8166] = 0x5709, [ 8167] = 0x57DF, [ 8168] = 0x5805, [ 8169] = 0x580A, ++ [ 8170] = 0x5806, [ 8171] = 0x57E0, [ 8172] = 0x57E4, [ 8173] = 0x57FA, ++ [ 8174] = 0x5802, [ 8175] = 0x5835, [ 8176] = 0x57F7, [ 8177] = 0x57F9, ++ [ 8178] = 0x5920, [ 8179] = 0x5962, [ 8180] = 0x5A36, [ 8181] = 0x5A41, ++ [ 8182] = 0x5A49, [ 8183] = 0x5A66, [ 8184] = 0x5A6A, [ 8185] = 0x5A40, ++ [ 8190] = 0x5A3C, [ 8191] = 0x5A62, [ 8192] = 0x5A5A, [ 8193] = 0x5A46, ++ [ 8194] = 0x5A4A, [ 8195] = 0x5B70, [ 8196] = 0x5BC7, [ 8197] = 0x5BC5, ++ [ 8198] = 0x5BC4, [ 8199] = 0x5BC2, [ 8200] = 0x5BBF, [ 8201] = 0x5BC6, ++ [ 8202] = 0x5C09, [ 8203] = 0x5C08, [ 8204] = 0x5C07, [ 8205] = 0x5C60, ++ [ 8206] = 0x5C5C, [ 8207] = 0x5C5D, [ 8208] = 0x5D07, [ 8209] = 0x5D06, ++ [ 8210] = 0x5D0E, [ 8211] = 0x5D1B, [ 8212] = 0x5D16, [ 8213] = 0x5D22, ++ [ 8214] = 0x5D11, [ 8215] = 0x5D29, [ 8216] = 0x5D14, [ 8217] = 0x5D19, ++ [ 8218] = 0x5D24, [ 8219] = 0x5D27, [ 8220] = 0x5D17, [ 8221] = 0x5DE2, ++ [ 8222] = 0x5E38, [ 8223] = 0x5E36, [ 8224] = 0x5E33, [ 8225] = 0x5E37, ++ [ 8226] = 0x5EB7, [ 8227] = 0x5EB8, [ 8228] = 0x5EB6, [ 8229] = 0x5EB5, ++ [ 8230] = 0x5EBE, [ 8231] = 0x5F35, [ 8232] = 0x5F37, [ 8233] = 0x5F57, ++ [ 8234] = 0x5F6C, [ 8235] = 0x5F69, [ 8236] = 0x5F6B, [ 8237] = 0x5F97, ++ [ 8238] = 0x5F99, [ 8239] = 0x5F9E, [ 8240] = 0x5F98, [ 8241] = 0x5FA1, ++ [ 8242] = 0x5FA0, [ 8243] = 0x5F9C, [ 8244] = 0x607F, [ 8245] = 0x60A3, ++ [ 8246] = 0x6089, [ 8247] = 0x60A0, [ 8248] = 0x60A8, [ 8249] = 0x60CB, ++ [ 8250] = 0x60B4, [ 8251] = 0x60E6, [ 8252] = 0x60BD, [ 8287] = 0x60C5, ++ [ 8288] = 0x60BB, [ 8289] = 0x60B5, [ 8290] = 0x60DC, [ 8291] = 0x60BC, ++ [ 8292] = 0x60D8, [ 8293] = 0x60D5, [ 8294] = 0x60C6, [ 8295] = 0x60DF, ++ [ 8296] = 0x60B8, [ 8297] = 0x60DA, [ 8298] = 0x60C7, [ 8299] = 0x621A, ++ [ 8300] = 0x621B, [ 8301] = 0x6248, [ 8302] = 0x63A0, [ 8303] = 0x63A7, ++ [ 8304] = 0x6372, [ 8305] = 0x6396, [ 8306] = 0x63A2, [ 8307] = 0x63A5, ++ [ 8308] = 0x6377, [ 8309] = 0x6367, [ 8310] = 0x6398, [ 8311] = 0x63AA, ++ [ 8312] = 0x6371, [ 8313] = 0x63A9, [ 8314] = 0x6389, [ 8315] = 0x6383, ++ [ 8316] = 0x639B, [ 8317] = 0x636B, [ 8318] = 0x63A8, [ 8319] = 0x6384, ++ [ 8320] = 0x6388, [ 8321] = 0x6399, [ 8322] = 0x63A1, [ 8323] = 0x63AC, ++ [ 8324] = 0x6392, [ 8325] = 0x638F, [ 8326] = 0x6380, [ 8327] = 0x637B, ++ [ 8328] = 0x6369, [ 8329] = 0x6368, [ 8330] = 0x637A, [ 8331] = 0x655D, ++ [ 8332] = 0x6556, [ 8333] = 0x6551, [ 8334] = 0x6559, [ 8335] = 0x6557, ++ [ 8336] = 0x555F, [ 8337] = 0x654F, [ 8338] = 0x6558, [ 8339] = 0x6555, ++ [ 8340] = 0x6554, [ 8341] = 0x659C, [ 8342] = 0x659B, [ 8343] = 0x65AC, ++ [ 8344] = 0x65CF, [ 8345] = 0x65CB, [ 8346] = 0x65CC, [ 8347] = 0x65CE, ++ [ 8348] = 0x665D, [ 8349] = 0x665A, [ 8350] = 0x6664, [ 8351] = 0x6668, ++ [ 8352] = 0x6666, [ 8353] = 0x665E, [ 8354] = 0x66F9, [ 8355] = 0x52D7, ++ [ 8356] = 0x671B, [ 8357] = 0x6881, [ 8358] = 0x68AF, [ 8359] = 0x68A2, ++ [ 8360] = 0x6893, [ 8361] = 0x68B5, [ 8362] = 0x687F, [ 8363] = 0x6876, ++ [ 8364] = 0x68B1, [ 8365] = 0x68A7, [ 8366] = 0x6897, [ 8367] = 0x68B0, ++ [ 8368] = 0x6883, [ 8369] = 0x68C4, [ 8370] = 0x68AD, [ 8371] = 0x6886, ++ [ 8372] = 0x6885, [ 8373] = 0x6894, [ 8374] = 0x689D, [ 8375] = 0x68A8, ++ [ 8376] = 0x689F, [ 8377] = 0x68A1, [ 8378] = 0x6882, [ 8379] = 0x6B32, ++ [ 8380] = 0x6BBA, [ 8385] = 0x6BEB, [ 8386] = 0x6BEC, [ 8387] = 0x6C2B, ++ [ 8388] = 0x6D8E, [ 8389] = 0x6DBC, [ 8390] = 0x6DF3, [ 8391] = 0x6DD9, ++ [ 8392] = 0x6DB2, [ 8393] = 0x6DE1, [ 8394] = 0x6DCC, [ 8395] = 0x6DE4, ++ [ 8396] = 0x6DFB, [ 8397] = 0x6DFA, [ 8398] = 0x6E05, [ 8399] = 0x6DC7, ++ [ 8400] = 0x6DCB, [ 8401] = 0x6DAF, [ 8402] = 0x6DD1, [ 8403] = 0x6DAE, ++ [ 8404] = 0x6DDE, [ 8405] = 0x6DF9, [ 8406] = 0x6DB8, [ 8407] = 0x6DF7, ++ [ 8408] = 0x6DF5, [ 8409] = 0x6DC5, [ 8410] = 0x6DD2, [ 8411] = 0x6E1A, ++ [ 8412] = 0x6DB5, [ 8413] = 0x6DDA, [ 8414] = 0x6DEB, [ 8415] = 0x6DD8, ++ [ 8416] = 0x6DEA, [ 8417] = 0x6DF1, [ 8418] = 0x6DEE, [ 8419] = 0x6DE8, ++ [ 8420] = 0x6DC6, [ 8421] = 0x6DC4, [ 8422] = 0x6DAA, [ 8423] = 0x6DEC, ++ [ 8424] = 0x6DBF, [ 8425] = 0x6DE6, [ 8426] = 0x70F9, [ 8427] = 0x7109, ++ [ 8428] = 0x710A, [ 8429] = 0x70FD, [ 8430] = 0x70EF, [ 8431] = 0x723D, ++ [ 8432] = 0x727D, [ 8433] = 0x7281, [ 8434] = 0x731C, [ 8435] = 0x731B, ++ [ 8436] = 0x7316, [ 8437] = 0x7313, [ 8438] = 0x7319, [ 8439] = 0x7387, ++ [ 8440] = 0x7405, [ 8441] = 0x740A, [ 8442] = 0x7403, [ 8443] = 0x7406, ++ [ 8444] = 0x73FE, [ 8445] = 0x740D, [ 8446] = 0x74E0, [ 8447] = 0x74F6, ++ [ 8482] = 0x74F7, [ 8483] = 0x751C, [ 8484] = 0x7522, [ 8485] = 0x7565, ++ [ 8486] = 0x7566, [ 8487] = 0x7562, [ 8488] = 0x7570, [ 8489] = 0x758F, ++ [ 8490] = 0x75D4, [ 8491] = 0x75D5, [ 8492] = 0x75B5, [ 8493] = 0x75CA, ++ [ 8494] = 0x75CD, [ 8495] = 0x768E, [ 8496] = 0x76D4, [ 8497] = 0x76D2, ++ [ 8498] = 0x76DB, [ 8499] = 0x7737, [ 8500] = 0x773E, [ 8501] = 0x773C, ++ [ 8502] = 0x7736, [ 8503] = 0x7738, [ 8504] = 0x773A, [ 8505] = 0x786B, ++ [ 8506] = 0x7843, [ 8507] = 0x784E, [ 8508] = 0x7965, [ 8509] = 0x7968, ++ [ 8510] = 0x796D, [ 8511] = 0x79FB, [ 8512] = 0x7A92, [ 8513] = 0x7A95, ++ [ 8514] = 0x7B20, [ 8515] = 0x7B28, [ 8516] = 0x7B1B, [ 8517] = 0x7B2C, ++ [ 8518] = 0x7B26, [ 8519] = 0x7B19, [ 8520] = 0x7B1E, [ 8521] = 0x7B2E, ++ [ 8522] = 0x7C92, [ 8523] = 0x7C97, [ 8524] = 0x7C95, [ 8525] = 0x7D46, ++ [ 8526] = 0x7D43, [ 8527] = 0x7D71, [ 8528] = 0x7D2E, [ 8529] = 0x7D39, ++ [ 8530] = 0x7D3C, [ 8531] = 0x7D40, [ 8532] = 0x7D30, [ 8533] = 0x7D33, ++ [ 8534] = 0x7D44, [ 8535] = 0x7D2F, [ 8536] = 0x7D42, [ 8537] = 0x7D32, ++ [ 8538] = 0x7D31, [ 8539] = 0x7F3D, [ 8540] = 0x7F9E, [ 8541] = 0x7F9A, ++ [ 8542] = 0x7FCC, [ 8543] = 0x7FCE, [ 8544] = 0x7FD2, [ 8545] = 0x801C, ++ [ 8546] = 0x804A, [ 8547] = 0x8046, [ 8548] = 0x812F, [ 8549] = 0x8116, ++ [ 8550] = 0x8123, [ 8551] = 0x812B, [ 8552] = 0x8129, [ 8553] = 0x8130, ++ [ 8554] = 0x8124, [ 8555] = 0x8202, [ 8556] = 0x8235, [ 8557] = 0x8237, ++ [ 8558] = 0x8236, [ 8559] = 0x8239, [ 8560] = 0x838E, [ 8561] = 0x839E, ++ [ 8562] = 0x8398, [ 8563] = 0x8378, [ 8564] = 0x83A2, [ 8565] = 0x8396, ++ [ 8566] = 0x83BD, [ 8567] = 0x83AB, [ 8568] = 0x8392, [ 8569] = 0x838A, ++ [ 8570] = 0x8393, [ 8571] = 0x8389, [ 8572] = 0x83A0, [ 8573] = 0x8377, ++ [ 8574] = 0x837B, [ 8575] = 0x837C, [ 8580] = 0x8386, [ 8581] = 0x83A7, ++ [ 8582] = 0x8655, [ 8583] = 0x5F6A, [ 8584] = 0x86C7, [ 8585] = 0x86C0, ++ [ 8586] = 0x86B6, [ 8587] = 0x86C4, [ 8588] = 0x86B5, [ 8589] = 0x86C6, ++ [ 8590] = 0x86CB, [ 8591] = 0x86B1, [ 8592] = 0x86AF, [ 8593] = 0x86C9, ++ [ 8594] = 0x8853, [ 8595] = 0x889E, [ 8596] = 0x8888, [ 8597] = 0x88AB, ++ [ 8598] = 0x8892, [ 8599] = 0x8896, [ 8600] = 0x888D, [ 8601] = 0x888B, ++ [ 8602] = 0x8993, [ 8603] = 0x898F, [ 8604] = 0x8A2A, [ 8605] = 0x8A1D, ++ [ 8606] = 0x8A23, [ 8607] = 0x8A25, [ 8608] = 0x8A31, [ 8609] = 0x8A2D, ++ [ 8610] = 0x8A1F, [ 8611] = 0x8A1B, [ 8612] = 0x8A22, [ 8613] = 0x8C49, ++ [ 8614] = 0x8C5A, [ 8615] = 0x8CA9, [ 8616] = 0x8CAC, [ 8617] = 0x8CAB, ++ [ 8618] = 0x8CA8, [ 8619] = 0x8CAA, [ 8620] = 0x8CA7, [ 8621] = 0x8D67, ++ [ 8622] = 0x8D66, [ 8623] = 0x8DBE, [ 8624] = 0x8DBA, [ 8625] = 0x8EDB, ++ [ 8626] = 0x8EDF, [ 8627] = 0x9019, [ 8628] = 0x900D, [ 8629] = 0x901A, ++ [ 8630] = 0x9017, [ 8631] = 0x9023, [ 8632] = 0x901F, [ 8633] = 0x901D, ++ [ 8634] = 0x9010, [ 8635] = 0x9015, [ 8636] = 0x901E, [ 8637] = 0x9020, ++ [ 8638] = 0x900F, [ 8639] = 0x9022, [ 8640] = 0x9016, [ 8641] = 0x901B, ++ [ 8642] = 0x9014, [ 8677] = 0x90E8, [ 8678] = 0x90ED, [ 8679] = 0x90FD, ++ [ 8680] = 0x9157, [ 8681] = 0x91CE, [ 8682] = 0x91F5, [ 8683] = 0x91E6, ++ [ 8684] = 0x91E3, [ 8685] = 0x91E7, [ 8686] = 0x91ED, [ 8687] = 0x91E9, ++ [ 8688] = 0x9589, [ 8689] = 0x966A, [ 8690] = 0x9675, [ 8691] = 0x9673, ++ [ 8692] = 0x9678, [ 8693] = 0x9670, [ 8694] = 0x9674, [ 8695] = 0x9676, ++ [ 8696] = 0x9677, [ 8697] = 0x966C, [ 8698] = 0x96C0, [ 8699] = 0x96EA, ++ [ 8700] = 0x96E9, [ 8701] = 0x7AE0, [ 8702] = 0x7ADF, [ 8703] = 0x9802, ++ [ 8704] = 0x9803, [ 8705] = 0x9B5A, [ 8706] = 0x9CE5, [ 8707] = 0x9E75, ++ [ 8708] = 0x9E7F, [ 8709] = 0x9EA5, [ 8710] = 0x9EBB, [ 8711] = 0x50A2, ++ [ 8712] = 0x508D, [ 8713] = 0x5085, [ 8714] = 0x5099, [ 8715] = 0x5091, ++ [ 8716] = 0x5080, [ 8717] = 0x5096, [ 8718] = 0x5098, [ 8719] = 0x509A, ++ [ 8720] = 0x6700, [ 8721] = 0x51F1, [ 8722] = 0x5272, [ 8723] = 0x5274, ++ [ 8724] = 0x5275, [ 8725] = 0x5269, [ 8726] = 0x52DE, [ 8727] = 0x52DD, ++ [ 8728] = 0x52DB, [ 8729] = 0x535A, [ 8730] = 0x53A5, [ 8731] = 0x557B, ++ [ 8732] = 0x5580, [ 8733] = 0x55A7, [ 8734] = 0x557C, [ 8735] = 0x558A, ++ [ 8736] = 0x559D, [ 8737] = 0x5598, [ 8738] = 0x5582, [ 8739] = 0x559C, ++ [ 8740] = 0x55AA, [ 8741] = 0x5594, [ 8742] = 0x5587, [ 8743] = 0x558B, ++ [ 8744] = 0x5583, [ 8745] = 0x55B3, [ 8746] = 0x55AE, [ 8747] = 0x559F, ++ [ 8748] = 0x553E, [ 8749] = 0x55B2, [ 8750] = 0x559A, [ 8751] = 0x55BB, ++ [ 8752] = 0x55AC, [ 8753] = 0x55B1, [ 8754] = 0x557E, [ 8755] = 0x5589, ++ [ 8756] = 0x55AB, [ 8757] = 0x5599, [ 8758] = 0x570D, [ 8759] = 0x582F, ++ [ 8760] = 0x582A, [ 8761] = 0x5834, [ 8762] = 0x5824, [ 8763] = 0x5830, ++ [ 8764] = 0x5831, [ 8765] = 0x5821, [ 8766] = 0x581D, [ 8767] = 0x5820, ++ [ 8768] = 0x58F9, [ 8769] = 0x58FA, [ 8770] = 0x5960, [ 8775] = 0x5A77, ++ [ 8776] = 0x5A9A, [ 8777] = 0x5A7F, [ 8778] = 0x5A92, [ 8779] = 0x5A9B, ++ [ 8780] = 0x5AA7, [ 8781] = 0x5B73, [ 8782] = 0x5B71, [ 8783] = 0x5BD2, ++ [ 8784] = 0x5BCC, [ 8785] = 0x5BD3, [ 8786] = 0x5BD0, [ 8787] = 0x5C0A, ++ [ 8788] = 0x5C0B, [ 8789] = 0x5C31, [ 8790] = 0x5D4C, [ 8791] = 0x5D50, ++ [ 8792] = 0x5D34, [ 8793] = 0x5D47, [ 8794] = 0x5DFD, [ 8795] = 0x5E45, ++ [ 8796] = 0x5E3D, [ 8797] = 0x5E40, [ 8798] = 0x5E43, [ 8799] = 0x5E7E, ++ [ 8800] = 0x5ECA, [ 8801] = 0x5EC1, [ 8802] = 0x5EC2, [ 8803] = 0x5EC4, ++ [ 8804] = 0x5F3C, [ 8805] = 0x5F6D, [ 8806] = 0x5FA9, [ 8807] = 0x5FAA, ++ [ 8808] = 0x5FA8, [ 8809] = 0x60D1, [ 8810] = 0x60E1, [ 8811] = 0x60B2, ++ [ 8812] = 0x60B6, [ 8813] = 0x60E0, [ 8814] = 0x611C, [ 8815] = 0x6123, ++ [ 8816] = 0x60FA, [ 8817] = 0x6115, [ 8818] = 0x60F0, [ 8819] = 0x60FB, ++ [ 8820] = 0x60F4, [ 8821] = 0x6168, [ 8822] = 0x60F1, [ 8823] = 0x610E, ++ [ 8824] = 0x60F6, [ 8825] = 0x6109, [ 8826] = 0x6100, [ 8827] = 0x6112, ++ [ 8828] = 0x621F, [ 8829] = 0x6249, [ 8830] = 0x63A3, [ 8831] = 0x638C, ++ [ 8832] = 0x63CF, [ 8833] = 0x63C0, [ 8834] = 0x63E9, [ 8835] = 0x63C9, ++ [ 8836] = 0x63C6, [ 8837] = 0x63CD, [ 8872] = 0x63D2, [ 8873] = 0x63E3, ++ [ 8874] = 0x63D0, [ 8875] = 0x63E1, [ 8876] = 0x63D6, [ 8877] = 0x63ED, ++ [ 8878] = 0x63EE, [ 8879] = 0x6376, [ 8880] = 0x63F4, [ 8881] = 0x63EA, ++ [ 8882] = 0x63DB, [ 8883] = 0x6452, [ 8884] = 0x63DA, [ 8885] = 0x63F9, ++ [ 8886] = 0x655E, [ 8887] = 0x6566, [ 8888] = 0x6562, [ 8889] = 0x6563, ++ [ 8890] = 0x6591, [ 8891] = 0x6590, [ 8892] = 0x65AF, [ 8893] = 0x666E, ++ [ 8894] = 0x6670, [ 8895] = 0x6674, [ 8896] = 0x6676, [ 8897] = 0x666F, ++ [ 8898] = 0x6691, [ 8899] = 0x667A, [ 8900] = 0x667E, [ 8901] = 0x6677, ++ [ 8902] = 0x66FE, [ 8903] = 0x66FF, [ 8904] = 0x671F, [ 8905] = 0x671D, ++ [ 8906] = 0x68FA, [ 8907] = 0x68D5, [ 8908] = 0x68E0, [ 8909] = 0x68D8, ++ [ 8910] = 0x68D7, [ 8911] = 0x6905, [ 8912] = 0x68DF, [ 8913] = 0x68F5, ++ [ 8914] = 0x68EE, [ 8915] = 0x68E7, [ 8916] = 0x68F9, [ 8917] = 0x68D2, ++ [ 8918] = 0x68F2, [ 8919] = 0x68E3, [ 8920] = 0x68CB, [ 8921] = 0x68CD, ++ [ 8922] = 0x690D, [ 8923] = 0x6912, [ 8924] = 0x690E, [ 8925] = 0x68C9, ++ [ 8926] = 0x68DA, [ 8927] = 0x696E, [ 8928] = 0x68FB, [ 8929] = 0x6B3E, ++ [ 8930] = 0x6B3A, [ 8931] = 0x6B3D, [ 8932] = 0x6B98, [ 8933] = 0x6B96, ++ [ 8934] = 0x6BBC, [ 8935] = 0x6BEF, [ 8936] = 0x6C2E, [ 8937] = 0x6C2F, ++ [ 8938] = 0x6C2C, [ 8939] = 0x6E2F, [ 8940] = 0x6E38, [ 8941] = 0x6E54, ++ [ 8942] = 0x6E21, [ 8943] = 0x6E32, [ 8944] = 0x6E67, [ 8945] = 0x6E4A, ++ [ 8946] = 0x6E20, [ 8947] = 0x6E25, [ 8948] = 0x6E23, [ 8949] = 0x6E1B, ++ [ 8950] = 0x6E5B, [ 8951] = 0x6E58, [ 8952] = 0x6E24, [ 8953] = 0x6E56, ++ [ 8954] = 0x6E6E, [ 8955] = 0x6E2D, [ 8956] = 0x6E26, [ 8957] = 0x6E6F, ++ [ 8958] = 0x6E34, [ 8959] = 0x6E4D, [ 8960] = 0x6E3A, [ 8961] = 0x6E2C, ++ [ 8962] = 0x6E43, [ 8963] = 0x6E1D, [ 8964] = 0x6E3E, [ 8965] = 0x6ECB, ++ [ 8970] = 0x6E89, [ 8971] = 0x6E19, [ 8972] = 0x6E4E, [ 8973] = 0x6E63, ++ [ 8974] = 0x6E44, [ 8975] = 0x6E72, [ 8976] = 0x6E69, [ 8977] = 0x6E5F, ++ [ 8978] = 0x7119, [ 8979] = 0x711A, [ 8980] = 0x7126, [ 8981] = 0x7130, ++ [ 8982] = 0x7121, [ 8983] = 0x7136, [ 8984] = 0x716E, [ 8985] = 0x711C, ++ [ 8986] = 0x724C, [ 8987] = 0x7284, [ 8988] = 0x7280, [ 8989] = 0x7336, ++ [ 8990] = 0x7325, [ 8991] = 0x7334, [ 8992] = 0x7329, [ 8993] = 0x743A, ++ [ 8994] = 0x742A, [ 8995] = 0x7433, [ 8996] = 0x7422, [ 8997] = 0x7425, ++ [ 8998] = 0x7435, [ 8999] = 0x7436, [ 9000] = 0x7434, [ 9001] = 0x742F, ++ [ 9002] = 0x741B, [ 9003] = 0x7426, [ 9004] = 0x7428, [ 9005] = 0x7525, ++ [ 9006] = 0x7526, [ 9007] = 0x756B, [ 9008] = 0x756A, [ 9009] = 0x75E2, ++ [ 9010] = 0x75DB, [ 9011] = 0x75E3, [ 9012] = 0x75D9, [ 9013] = 0x75D8, ++ [ 9014] = 0x75DE, [ 9015] = 0x75E0, [ 9016] = 0x767B, [ 9017] = 0x767C, ++ [ 9018] = 0x7696, [ 9019] = 0x7693, [ 9020] = 0x76B4, [ 9021] = 0x76DC, ++ [ 9022] = 0x774F, [ 9023] = 0x77ED, [ 9024] = 0x785D, [ 9025] = 0x786C, ++ [ 9026] = 0x786F, [ 9027] = 0x7A0D, [ 9028] = 0x7A08, [ 9029] = 0x7A0B, ++ [ 9030] = 0x7A05, [ 9031] = 0x7A00, [ 9032] = 0x7A98, [ 9067] = 0x7A97, ++ [ 9068] = 0x7A96, [ 9069] = 0x7AE5, [ 9070] = 0x7AE3, [ 9071] = 0x7B49, ++ [ 9072] = 0x7B56, [ 9073] = 0x7B46, [ 9074] = 0x7B50, [ 9075] = 0x7B52, ++ [ 9076] = 0x7B54, [ 9077] = 0x7B4D, [ 9078] = 0x7B4B, [ 9079] = 0x7B4F, ++ [ 9080] = 0x7B51, [ 9081] = 0x7C9F, [ 9082] = 0x7CA5, [ 9083] = 0x7D5E, ++ [ 9084] = 0x7D50, [ 9085] = 0x7D68, [ 9086] = 0x7D55, [ 9087] = 0x7D2B, ++ [ 9088] = 0x7D6E, [ 9089] = 0x7D72, [ 9090] = 0x7D61, [ 9091] = 0x7D66, ++ [ 9092] = 0x7D62, [ 9093] = 0x7D70, [ 9094] = 0x7D73, [ 9095] = 0x5584, ++ [ 9096] = 0x7FD4, [ 9097] = 0x7FD5, [ 9098] = 0x800B, [ 9099] = 0x8052, ++ [ 9100] = 0x8085, [ 9101] = 0x8155, [ 9102] = 0x8154, [ 9103] = 0x814B, ++ [ 9104] = 0x8151, [ 9105] = 0x814E, [ 9106] = 0x8139, [ 9107] = 0x8146, ++ [ 9108] = 0x813E, [ 9109] = 0x814C, [ 9110] = 0x8153, [ 9111] = 0x8174, ++ [ 9112] = 0x8212, [ 9113] = 0x821C, [ 9114] = 0x83E9, [ 9115] = 0x8403, ++ [ 9116] = 0x83F8, [ 9117] = 0x840D, [ 9118] = 0x83E0, [ 9119] = 0x83C5, ++ [ 9120] = 0x840B, [ 9121] = 0x83C1, [ 9122] = 0x83EF, [ 9123] = 0x83F1, ++ [ 9124] = 0x83F4, [ 9125] = 0x8457, [ 9126] = 0x840A, [ 9127] = 0x83F0, ++ [ 9128] = 0x840C, [ 9129] = 0x83CC, [ 9130] = 0x83FD, [ 9131] = 0x83F2, ++ [ 9132] = 0x83CA, [ 9133] = 0x8438, [ 9134] = 0x840E, [ 9135] = 0x8404, ++ [ 9136] = 0x83DC, [ 9137] = 0x8407, [ 9138] = 0x83D4, [ 9139] = 0x83DF, ++ [ 9140] = 0x865B, [ 9141] = 0x86DF, [ 9142] = 0x86D9, [ 9143] = 0x86ED, ++ [ 9144] = 0x86D4, [ 9145] = 0x86DB, [ 9146] = 0x86E4, [ 9147] = 0x86D0, ++ [ 9148] = 0x86DE, [ 9149] = 0x8857, [ 9150] = 0x88C1, [ 9151] = 0x88C2, ++ [ 9152] = 0x88B1, [ 9153] = 0x8983, [ 9154] = 0x8996, [ 9155] = 0x8A3B, ++ [ 9156] = 0x8A60, [ 9157] = 0x8A55, [ 9158] = 0x8A5E, [ 9159] = 0x8A3C, ++ [ 9160] = 0x8A41, [ 9165] = 0x8A54, [ 9166] = 0x8A5B, [ 9167] = 0x8A50, ++ [ 9168] = 0x8A46, [ 9169] = 0x8A34, [ 9170] = 0x8A3A, [ 9171] = 0x8A36, ++ [ 9172] = 0x8A56, [ 9173] = 0x8C61, [ 9174] = 0x8C82, [ 9175] = 0x8CAF, ++ [ 9176] = 0x8CBC, [ 9177] = 0x8CB3, [ 9178] = 0x8CBD, [ 9179] = 0x8CC1, ++ [ 9180] = 0x8CBB, [ 9181] = 0x8CC0, [ 9182] = 0x8CB4, [ 9183] = 0x8CB7, ++ [ 9184] = 0x8CB6, [ 9185] = 0x8CBF, [ 9186] = 0x8CB8, [ 9187] = 0x8D8A, ++ [ 9188] = 0x8D85, [ 9189] = 0x8D81, [ 9190] = 0x8DCE, [ 9191] = 0x8DDD, ++ [ 9192] = 0x8DCB, [ 9193] = 0x8DDA, [ 9194] = 0x8DD1, [ 9195] = 0x8DCC, ++ [ 9196] = 0x8DDB, [ 9197] = 0x8DC6, [ 9198] = 0x8EFB, [ 9199] = 0x8EF8, ++ [ 9200] = 0x8EFC, [ 9201] = 0x8F9C, [ 9202] = 0x902E, [ 9203] = 0x9035, ++ [ 9204] = 0x9031, [ 9205] = 0x9038, [ 9206] = 0x9032, [ 9207] = 0x9036, ++ [ 9208] = 0x9102, [ 9209] = 0x90F5, [ 9210] = 0x9109, [ 9211] = 0x90FE, ++ [ 9212] = 0x9163, [ 9213] = 0x9165, [ 9214] = 0x91CF, [ 9215] = 0x9214, ++ [ 9216] = 0x9215, [ 9217] = 0x9223, [ 9218] = 0x9209, [ 9219] = 0x921E, ++ [ 9220] = 0x920D, [ 9221] = 0x9210, [ 9222] = 0x9207, [ 9223] = 0x9211, ++ [ 9224] = 0x9594, [ 9225] = 0x958F, [ 9226] = 0x958B, [ 9227] = 0x9591, ++ [ 9262] = 0x9593, [ 9263] = 0x9592, [ 9264] = 0x958E, [ 9265] = 0x968A, ++ [ 9266] = 0x968E, [ 9267] = 0x968B, [ 9268] = 0x967D, [ 9269] = 0x9685, ++ [ 9270] = 0x9686, [ 9271] = 0x968D, [ 9272] = 0x9672, [ 9273] = 0x9684, ++ [ 9274] = 0x96C1, [ 9275] = 0x96C5, [ 9276] = 0x96C4, [ 9277] = 0x96C6, ++ [ 9278] = 0x96C7, [ 9279] = 0x96EF, [ 9280] = 0x96F2, [ 9281] = 0x97CC, ++ [ 9282] = 0x9805, [ 9283] = 0x9806, [ 9284] = 0x9808, [ 9285] = 0x98E7, ++ [ 9286] = 0x98EA, [ 9287] = 0x98EF, [ 9288] = 0x98E9, [ 9289] = 0x98F2, ++ [ 9290] = 0x98ED, [ 9291] = 0x99AE, [ 9292] = 0x99AD, [ 9293] = 0x9EC3, ++ [ 9294] = 0x9ECD, [ 9295] = 0x9ED1, [ 9296] = 0x4E82, [ 9297] = 0x50AD, ++ [ 9298] = 0x50B5, [ 9299] = 0x50B2, [ 9300] = 0x50B3, [ 9301] = 0x50C5, ++ [ 9302] = 0x50BE, [ 9303] = 0x50AC, [ 9304] = 0x50B7, [ 9305] = 0x50BB, ++ [ 9306] = 0x50AF, [ 9307] = 0x50C7, [ 9308] = 0x527F, [ 9309] = 0x5277, ++ [ 9310] = 0x527D, [ 9311] = 0x52DF, [ 9312] = 0x52E6, [ 9313] = 0x52E4, ++ [ 9314] = 0x52E2, [ 9315] = 0x52E3, [ 9316] = 0x532F, [ 9317] = 0x55DF, ++ [ 9318] = 0x55E8, [ 9319] = 0x55D3, [ 9320] = 0x55E6, [ 9321] = 0x55CE, ++ [ 9322] = 0x55DC, [ 9323] = 0x55C7, [ 9324] = 0x55D1, [ 9325] = 0x55E3, ++ [ 9326] = 0x55E4, [ 9327] = 0x55EF, [ 9328] = 0x55DA, [ 9329] = 0x55E1, ++ [ 9330] = 0x55C5, [ 9331] = 0x55C6, [ 9332] = 0x55E5, [ 9333] = 0x55C9, ++ [ 9334] = 0x5712, [ 9335] = 0x5713, [ 9336] = 0x585E, [ 9337] = 0x5851, ++ [ 9338] = 0x5858, [ 9339] = 0x5857, [ 9340] = 0x585A, [ 9341] = 0x5854, ++ [ 9342] = 0x586B, [ 9343] = 0x584C, [ 9344] = 0x586D, [ 9345] = 0x584A, ++ [ 9346] = 0x5862, [ 9347] = 0x5852, [ 9348] = 0x584B, [ 9349] = 0x5967, ++ [ 9350] = 0x5AC1, [ 9351] = 0x5AC9, [ 9352] = 0x5ACC, [ 9353] = 0x5ABE, ++ [ 9354] = 0x5ABD, [ 9355] = 0x5ABC, [ 9360] = 0x5AB3, [ 9361] = 0x5AC2, ++ [ 9362] = 0x5AB2, [ 9363] = 0x5D69, [ 9364] = 0x5D6F, [ 9365] = 0x5E4C, ++ [ 9366] = 0x5E79, [ 9367] = 0x5EC9, [ 9368] = 0x5EC8, [ 9369] = 0x5F12, ++ [ 9370] = 0x5F59, [ 9371] = 0x5FAC, [ 9372] = 0x5FAE, [ 9373] = 0x611A, ++ [ 9374] = 0x610F, [ 9375] = 0x6148, [ 9376] = 0x611F, [ 9377] = 0x60F3, ++ [ 9378] = 0x611B, [ 9379] = 0x60F9, [ 9380] = 0x6101, [ 9381] = 0x6108, ++ [ 9382] = 0x614E, [ 9383] = 0x614C, [ 9384] = 0x6144, [ 9385] = 0x614D, ++ [ 9386] = 0x613E, [ 9387] = 0x6134, [ 9388] = 0x6127, [ 9389] = 0x610D, ++ [ 9390] = 0x6106, [ 9391] = 0x6137, [ 9392] = 0x6221, [ 9393] = 0x6222, ++ [ 9394] = 0x6413, [ 9395] = 0x643E, [ 9396] = 0x641E, [ 9397] = 0x642A, ++ [ 9398] = 0x642D, [ 9399] = 0x643D, [ 9400] = 0x642C, [ 9401] = 0x640F, ++ [ 9402] = 0x641C, [ 9403] = 0x6414, [ 9404] = 0x640D, [ 9405] = 0x6436, ++ [ 9406] = 0x6416, [ 9407] = 0x6417, [ 9408] = 0x6406, [ 9409] = 0x656C, ++ [ 9410] = 0x659F, [ 9411] = 0x65B0, [ 9412] = 0x6697, [ 9413] = 0x6689, ++ [ 9414] = 0x6687, [ 9415] = 0x6688, [ 9416] = 0x6696, [ 9417] = 0x6684, ++ [ 9418] = 0x6698, [ 9419] = 0x668D, [ 9420] = 0x6703, [ 9421] = 0x6994, ++ [ 9422] = 0x696D, [ 9457] = 0x695A, [ 9458] = 0x6977, [ 9459] = 0x6960, ++ [ 9460] = 0x6954, [ 9461] = 0x6975, [ 9462] = 0x6930, [ 9463] = 0x6982, ++ [ 9464] = 0x694A, [ 9465] = 0x6968, [ 9466] = 0x696B, [ 9467] = 0x695E, ++ [ 9468] = 0x6953, [ 9469] = 0x6979, [ 9470] = 0x6986, [ 9471] = 0x695D, ++ [ 9472] = 0x6963, [ 9473] = 0x695B, [ 9474] = 0x6B47, [ 9475] = 0x6B72, ++ [ 9476] = 0x6BC0, [ 9477] = 0x6BBF, [ 9478] = 0x6BD3, [ 9479] = 0x6BFD, ++ [ 9480] = 0x6EA2, [ 9481] = 0x6EAF, [ 9482] = 0x6ED3, [ 9483] = 0x6EB6, ++ [ 9484] = 0x6EC2, [ 9485] = 0x6E90, [ 9486] = 0x6E9D, [ 9487] = 0x6EC7, ++ [ 9488] = 0x6EC5, [ 9489] = 0x6EA5, [ 9490] = 0x6E98, [ 9491] = 0x6EBC, ++ [ 9492] = 0x6EBA, [ 9493] = 0x6EAB, [ 9494] = 0x6ED1, [ 9495] = 0x6E96, ++ [ 9496] = 0x6E9C, [ 9497] = 0x6EC4, [ 9498] = 0x6ED4, [ 9499] = 0x6EAA, ++ [ 9500] = 0x6EA7, [ 9501] = 0x6EB4, [ 9502] = 0x714E, [ 9503] = 0x7159, ++ [ 9504] = 0x7169, [ 9505] = 0x7164, [ 9506] = 0x7149, [ 9507] = 0x7167, ++ [ 9508] = 0x715C, [ 9509] = 0x716C, [ 9510] = 0x7166, [ 9511] = 0x714C, ++ [ 9512] = 0x7165, [ 9513] = 0x715E, [ 9514] = 0x7146, [ 9515] = 0x7168, ++ [ 9516] = 0x7156, [ 9517] = 0x723A, [ 9518] = 0x7252, [ 9519] = 0x7337, ++ [ 9520] = 0x7345, [ 9521] = 0x733F, [ 9522] = 0x733E, [ 9523] = 0x746F, ++ [ 9524] = 0x745A, [ 9525] = 0x7455, [ 9526] = 0x745F, [ 9527] = 0x745E, ++ [ 9528] = 0x7441, [ 9529] = 0x743F, [ 9530] = 0x7459, [ 9531] = 0x745B, ++ [ 9532] = 0x745C, [ 9533] = 0x7576, [ 9534] = 0x7578, [ 9535] = 0x7600, ++ [ 9536] = 0x75F0, [ 9537] = 0x7601, [ 9538] = 0x75F2, [ 9539] = 0x75F1, ++ [ 9540] = 0x75FA, [ 9541] = 0x75FF, [ 9542] = 0x75F4, [ 9543] = 0x75F3, ++ [ 9544] = 0x76DE, [ 9545] = 0x76DF, [ 9546] = 0x775B, [ 9547] = 0x776B, ++ [ 9548] = 0x7766, [ 9549] = 0x775E, [ 9550] = 0x7763, [ 9555] = 0x7779, ++ [ 9556] = 0x776A, [ 9557] = 0x776C, [ 9558] = 0x775C, [ 9559] = 0x7765, ++ [ 9560] = 0x7768, [ 9561] = 0x7762, [ 9562] = 0x77EE, [ 9563] = 0x788E, ++ [ 9564] = 0x78B0, [ 9565] = 0x7897, [ 9566] = 0x7898, [ 9567] = 0x788C, ++ [ 9568] = 0x7889, [ 9569] = 0x787C, [ 9570] = 0x7891, [ 9571] = 0x7893, ++ [ 9572] = 0x787F, [ 9573] = 0x797A, [ 9574] = 0x797F, [ 9575] = 0x7981, ++ [ 9576] = 0x842C, [ 9577] = 0x79BD, [ 9578] = 0x7A1C, [ 9579] = 0x7A1A, ++ [ 9580] = 0x7A20, [ 9581] = 0x7A14, [ 9582] = 0x7A1F, [ 9583] = 0x7A1E, ++ [ 9584] = 0x7A9F, [ 9585] = 0x7AA0, [ 9586] = 0x7B77, [ 9587] = 0x7BC0, ++ [ 9588] = 0x7B60, [ 9589] = 0x7B6E, [ 9590] = 0x7B67, [ 9591] = 0x7CB1, ++ [ 9592] = 0x7CB3, [ 9593] = 0x7CB5, [ 9594] = 0x7D93, [ 9595] = 0x7D79, ++ [ 9596] = 0x7D91, [ 9597] = 0x7D81, [ 9598] = 0x7D8F, [ 9599] = 0x7D5B, ++ [ 9600] = 0x7F6E, [ 9601] = 0x7F69, [ 9602] = 0x7F6A, [ 9603] = 0x7F72, ++ [ 9604] = 0x7FA9, [ 9605] = 0x7FA8, [ 9606] = 0x7FA4, [ 9607] = 0x8056, ++ [ 9608] = 0x8058, [ 9609] = 0x8086, [ 9610] = 0x8084, [ 9611] = 0x8171, ++ [ 9612] = 0x8170, [ 9613] = 0x8178, [ 9614] = 0x8165, [ 9615] = 0x816E, ++ [ 9616] = 0x8173, [ 9617] = 0x816B, [ 9652] = 0x8179, [ 9653] = 0x817A, ++ [ 9654] = 0x8166, [ 9655] = 0x8205, [ 9656] = 0x8247, [ 9657] = 0x8482, ++ [ 9658] = 0x8477, [ 9659] = 0x843D, [ 9660] = 0x8431, [ 9661] = 0x8475, ++ [ 9662] = 0x8466, [ 9663] = 0x846B, [ 9664] = 0x8449, [ 9665] = 0x846C, ++ [ 9666] = 0x845B, [ 9667] = 0x843C, [ 9668] = 0x8435, [ 9669] = 0x8461, ++ [ 9670] = 0x8463, [ 9671] = 0x8469, [ 9672] = 0x846D, [ 9673] = 0x8446, ++ [ 9674] = 0x865E, [ 9675] = 0x865C, [ 9676] = 0x865F, [ 9677] = 0x86F9, ++ [ 9678] = 0x8713, [ 9679] = 0x8708, [ 9680] = 0x8707, [ 9681] = 0x8700, ++ [ 9682] = 0x86FE, [ 9683] = 0x86FB, [ 9684] = 0x8702, [ 9685] = 0x8703, ++ [ 9686] = 0x8706, [ 9687] = 0x870A, [ 9688] = 0x8859, [ 9689] = 0x88DF, ++ [ 9690] = 0x88D4, [ 9691] = 0x88D9, [ 9692] = 0x88DC, [ 9693] = 0x88D8, ++ [ 9694] = 0x88DD, [ 9695] = 0x88E1, [ 9696] = 0x88CA, [ 9697] = 0x88D5, ++ [ 9698] = 0x88D2, [ 9699] = 0x899C, [ 9700] = 0x89E3, [ 9701] = 0x8A6B, ++ [ 9702] = 0x8A72, [ 9703] = 0x8A73, [ 9704] = 0x8A66, [ 9705] = 0x8A69, ++ [ 9706] = 0x8A70, [ 9707] = 0x8A87, [ 9708] = 0x8A7C, [ 9709] = 0x8A63, ++ [ 9710] = 0x8AA0, [ 9711] = 0x8A71, [ 9712] = 0x8A85, [ 9713] = 0x8A6D, ++ [ 9714] = 0x8A62, [ 9715] = 0x8A6E, [ 9716] = 0x8A6C, [ 9717] = 0x8A79, ++ [ 9718] = 0x8A7B, [ 9719] = 0x8A3E, [ 9720] = 0x8A68, [ 9721] = 0x8C62, ++ [ 9722] = 0x8C8A, [ 9723] = 0x8C89, [ 9724] = 0x8CCA, [ 9725] = 0x8CC7, ++ [ 9726] = 0x8CC8, [ 9727] = 0x8CC4, [ 9728] = 0x8CB2, [ 9729] = 0x8CC3, ++ [ 9730] = 0x8CC2, [ 9731] = 0x8CC5, [ 9732] = 0x8DE1, [ 9733] = 0x8DDF, ++ [ 9734] = 0x8DE8, [ 9735] = 0x8DEF, [ 9736] = 0x8DF3, [ 9737] = 0x8DFA, ++ [ 9738] = 0x8DEA, [ 9739] = 0x8DE4, [ 9740] = 0x8DE6, [ 9741] = 0x8EB2, ++ [ 9742] = 0x8F03, [ 9743] = 0x8F09, [ 9744] = 0x8EFE, [ 9745] = 0x8F0A, ++ [ 9750] = 0x8F9F, [ 9751] = 0x8FB2, [ 9752] = 0x904B, [ 9753] = 0x904A, ++ [ 9754] = 0x9053, [ 9755] = 0x9042, [ 9756] = 0x9054, [ 9757] = 0x903C, ++ [ 9758] = 0x9055, [ 9759] = 0x9050, [ 9760] = 0x9047, [ 9761] = 0x904F, ++ [ 9762] = 0x904E, [ 9763] = 0x904D, [ 9764] = 0x9051, [ 9765] = 0x903E, ++ [ 9766] = 0x9041, [ 9767] = 0x9112, [ 9768] = 0x9117, [ 9769] = 0x916C, ++ [ 9770] = 0x916A, [ 9771] = 0x9169, [ 9772] = 0x91C9, [ 9773] = 0x9237, ++ [ 9774] = 0x9257, [ 9775] = 0x9238, [ 9776] = 0x923D, [ 9777] = 0x9240, ++ [ 9778] = 0x923E, [ 9779] = 0x925B, [ 9780] = 0x924B, [ 9781] = 0x9264, ++ [ 9782] = 0x9251, [ 9783] = 0x9234, [ 9784] = 0x9249, [ 9785] = 0x924D, ++ [ 9786] = 0x9245, [ 9787] = 0x9239, [ 9788] = 0x923F, [ 9789] = 0x925A, ++ [ 9790] = 0x9598, [ 9791] = 0x9698, [ 9792] = 0x9694, [ 9793] = 0x9695, ++ [ 9794] = 0x96CD, [ 9795] = 0x96CB, [ 9796] = 0x96C9, [ 9797] = 0x96CA, ++ [ 9798] = 0x96F7, [ 9799] = 0x96FB, [ 9800] = 0x96F9, [ 9801] = 0x96F6, ++ [ 9802] = 0x9756, [ 9803] = 0x9774, [ 9804] = 0x9776, [ 9805] = 0x9810, ++ [ 9806] = 0x9811, [ 9807] = 0x9813, [ 9808] = 0x980A, [ 9809] = 0x9812, ++ [ 9810] = 0x980C, [ 9811] = 0x98FC, [ 9812] = 0x98F4, [ 9847] = 0x98FD, ++ [ 9848] = 0x98FE, [ 9849] = 0x99B3, [ 9850] = 0x99B1, [ 9851] = 0x99B4, ++ [ 9852] = 0x9AE1, [ 9853] = 0x9CE9, [ 9854] = 0x9E82, [ 9855] = 0x9F0E, ++ [ 9856] = 0x9F13, [ 9857] = 0x9F20, [ 9858] = 0x50E7, [ 9859] = 0x50EE, ++ [ 9860] = 0x50E5, [ 9861] = 0x50D6, [ 9862] = 0x50ED, [ 9863] = 0x50DA, ++ [ 9864] = 0x50D5, [ 9865] = 0x50CF, [ 9866] = 0x50D1, [ 9867] = 0x50F1, ++ [ 9868] = 0x50CE, [ 9869] = 0x50E9, [ 9870] = 0x5162, [ 9871] = 0x51F3, ++ [ 9872] = 0x5283, [ 9873] = 0x5282, [ 9874] = 0x5331, [ 9875] = 0x53AD, ++ [ 9876] = 0x55FE, [ 9877] = 0x5600, [ 9878] = 0x561B, [ 9879] = 0x5617, ++ [ 9880] = 0x55FD, [ 9881] = 0x5614, [ 9882] = 0x5606, [ 9883] = 0x5609, ++ [ 9884] = 0x560D, [ 9885] = 0x560E, [ 9886] = 0x55F7, [ 9887] = 0x5616, ++ [ 9888] = 0x561F, [ 9889] = 0x5608, [ 9890] = 0x5610, [ 9891] = 0x55F6, ++ [ 9892] = 0x5718, [ 9893] = 0x5716, [ 9894] = 0x5875, [ 9895] = 0x587E, ++ [ 9896] = 0x5883, [ 9897] = 0x5893, [ 9898] = 0x588A, [ 9899] = 0x5879, ++ [ 9900] = 0x5885, [ 9901] = 0x587D, [ 9902] = 0x58FD, [ 9903] = 0x5925, ++ [ 9904] = 0x5922, [ 9905] = 0x5924, [ 9906] = 0x596A, [ 9907] = 0x5969, ++ [ 9908] = 0x5AE1, [ 9909] = 0x5AE6, [ 9910] = 0x5AE9, [ 9911] = 0x5AD7, ++ [ 9912] = 0x5AD6, [ 9913] = 0x5AD8, [ 9914] = 0x5AE3, [ 9915] = 0x5B75, ++ [ 9916] = 0x5BDE, [ 9917] = 0x5BE7, [ 9918] = 0x5BE1, [ 9919] = 0x5BE5, ++ [ 9920] = 0x5BE6, [ 9921] = 0x5BE8, [ 9922] = 0x5BE2, [ 9923] = 0x5BE4, ++ [ 9924] = 0x5BDF, [ 9925] = 0x5C0D, [ 9926] = 0x5C62, [ 9927] = 0x5D84, ++ [ 9928] = 0x5D87, [ 9929] = 0x5E5B, [ 9930] = 0x5E63, [ 9931] = 0x5E55, ++ [ 9932] = 0x5E57, [ 9933] = 0x5E54, [ 9934] = 0x5ED3, [ 9935] = 0x5ED6, ++ [ 9936] = 0x5F0A, [ 9937] = 0x5F46, [ 9938] = 0x5F70, [ 9939] = 0x5FB9, ++ [ 9940] = 0x6147, [ 9945] = 0x613F, [ 9946] = 0x614B, [ 9947] = 0x6177, ++ [ 9948] = 0x6162, [ 9949] = 0x6163, [ 9950] = 0x615F, [ 9951] = 0x615A, ++ [ 9952] = 0x6158, [ 9953] = 0x6175, [ 9954] = 0x622A, [ 9955] = 0x6487, ++ [ 9956] = 0x6458, [ 9957] = 0x6454, [ 9958] = 0x64A4, [ 9959] = 0x6478, ++ [ 9960] = 0x645F, [ 9961] = 0x647A, [ 9962] = 0x6451, [ 9963] = 0x6467, ++ [ 9964] = 0x6434, [ 9965] = 0x646D, [ 9966] = 0x647B, [ 9967] = 0x6572, ++ [ 9968] = 0x65A1, [ 9969] = 0x65D7, [ 9970] = 0x65D6, [ 9971] = 0x66A2, ++ [ 9972] = 0x66A8, [ 9973] = 0x669D, [ 9974] = 0x699C, [ 9975] = 0x69A8, ++ [ 9976] = 0x6995, [ 9977] = 0x69C1, [ 9978] = 0x69AE, [ 9979] = 0x69D3, ++ [ 9980] = 0x69CB, [ 9981] = 0x699B, [ 9982] = 0x69B7, [ 9983] = 0x69BB, ++ [ 9984] = 0x69AB, [ 9985] = 0x69B4, [ 9986] = 0x69D0, [ 9987] = 0x69CD, ++ [ 9988] = 0x69AD, [ 9989] = 0x69CC, [ 9990] = 0x69A6, [ 9991] = 0x69C3, ++ [ 9992] = 0x69A3, [ 9993] = 0x6B49, [ 9994] = 0x6B4C, [ 9995] = 0x6C33, ++ [ 9996] = 0x6F33, [ 9997] = 0x6F14, [ 9998] = 0x6EFE, [ 9999] = 0x6F13, ++ [10000] = 0x6EF4, [10001] = 0x6F29, [10002] = 0x6F3E, [10003] = 0x6F20, ++ [10004] = 0x6F2C, [10005] = 0x6F0F, [10006] = 0x6F02, [10007] = 0x6F22, ++ [10042] = 0x6EFF, [10043] = 0x6EEF, [10044] = 0x6F06, [10045] = 0x6F31, ++ [10046] = 0x6F38, [10047] = 0x6F32, [10048] = 0x6F23, [10049] = 0x6F15, ++ [10050] = 0x6F2B, [10051] = 0x6F2F, [10052] = 0x6F88, [10053] = 0x6F2A, ++ [10054] = 0x6EEC, [10055] = 0x6F01, [10056] = 0x6EF2, [10057] = 0x6ECC, ++ [10058] = 0x6EF7, [10059] = 0x7194, [10060] = 0x7199, [10061] = 0x717D, ++ [10062] = 0x718A, [10063] = 0x7184, [10064] = 0x7192, [10065] = 0x723E, ++ [10066] = 0x7292, [10067] = 0x7296, [10068] = 0x7344, [10069] = 0x7350, ++ [10070] = 0x7464, [10071] = 0x7463, [10072] = 0x746A, [10073] = 0x7470, ++ [10074] = 0x746D, [10075] = 0x7504, [10076] = 0x7591, [10077] = 0x7627, ++ [10078] = 0x760D, [10079] = 0x760B, [10080] = 0x7609, [10081] = 0x7613, ++ [10082] = 0x76E1, [10083] = 0x76E3, [10084] = 0x7784, [10085] = 0x777D, ++ [10086] = 0x777F, [10087] = 0x7761, [10088] = 0x78C1, [10089] = 0x789F, ++ [10090] = 0x78A7, [10091] = 0x78B3, [10092] = 0x78A9, [10093] = 0x78A3, ++ [10094] = 0x798E, [10095] = 0x798F, [10096] = 0x798D, [10097] = 0x7A2E, ++ [10098] = 0x7A31, [10099] = 0x7AAA, [10100] = 0x7AA9, [10101] = 0x7AED, ++ [10102] = 0x7AEF, [10103] = 0x7BA1, [10104] = 0x7B95, [10105] = 0x7B8B, ++ [10106] = 0x7B75, [10107] = 0x7B97, [10108] = 0x7B9D, [10109] = 0x7B94, ++ [10110] = 0x7B8F, [10111] = 0x7BB8, [10112] = 0x7B87, [10113] = 0x7B84, ++ [10114] = 0x7CB9, [10115] = 0x7CBD, [10116] = 0x7CBE, [10117] = 0x7DBB, ++ [10118] = 0x7DB0, [10119] = 0x7D9C, [10120] = 0x7DBD, [10121] = 0x7DBE, ++ [10122] = 0x7DA0, [10123] = 0x7DCA, [10124] = 0x7DB4, [10125] = 0x7DB2, ++ [10126] = 0x7DB1, [10127] = 0x7DBA, [10128] = 0x7DA2, [10129] = 0x7DBF, ++ [10130] = 0x7DB5, [10131] = 0x7DB8, [10132] = 0x7DAD, [10133] = 0x7DD2, ++ [10134] = 0x7DC7, [10135] = 0x7DAC, [10140] = 0x7F70, [10141] = 0x7FE0, ++ [10142] = 0x7FE1, [10143] = 0x7FDF, [10144] = 0x805E, [10145] = 0x805A, ++ [10146] = 0x8087, [10147] = 0x8150, [10148] = 0x8180, [10149] = 0x818F, ++ [10150] = 0x8188, [10151] = 0x818A, [10152] = 0x817F, [10153] = 0x8182, ++ [10154] = 0x81E7, [10155] = 0x81FA, [10156] = 0x8207, [10157] = 0x8214, ++ [10158] = 0x821E, [10159] = 0x824B, [10160] = 0x84C9, [10161] = 0x84BF, ++ [10162] = 0x84C6, [10163] = 0x84C4, [10164] = 0x8499, [10165] = 0x849E, ++ [10166] = 0x84B2, [10167] = 0x849C, [10168] = 0x84CB, [10169] = 0x84B8, ++ [10170] = 0x84C0, [10171] = 0x84D3, [10172] = 0x8490, [10173] = 0x84BC, ++ [10174] = 0x84D1, [10175] = 0x84CA, [10176] = 0x873F, [10177] = 0x871C, ++ [10178] = 0x873B, [10179] = 0x8722, [10180] = 0x8725, [10181] = 0x8734, ++ [10182] = 0x8718, [10183] = 0x8755, [10184] = 0x8737, [10185] = 0x8729, ++ [10186] = 0x88F3, [10187] = 0x8902, [10188] = 0x88F4, [10189] = 0x88F9, ++ [10190] = 0x88F8, [10191] = 0x88FD, [10192] = 0x88E8, [10193] = 0x891A, ++ [10194] = 0x88EF, [10195] = 0x8AA6, [10196] = 0x8A8C, [10197] = 0x8A9E, ++ [10198] = 0x8AA3, [10199] = 0x8A8D, [10200] = 0x8AA1, [10201] = 0x8A93, ++ [10202] = 0x8AA4, [10237] = 0x8AAA, [10238] = 0x8AA5, [10239] = 0x8AA8, ++ [10240] = 0x8A98, [10241] = 0x8A91, [10242] = 0x8A9A, [10243] = 0x8AA7, ++ [10244] = 0x8C6A, [10245] = 0x8C8D, [10246] = 0x8C8C, [10247] = 0x8CD3, ++ [10248] = 0x8CD1, [10249] = 0x8CD2, [10250] = 0x8D6B, [10251] = 0x8D99, ++ [10252] = 0x8D95, [10253] = 0x8DFC, [10254] = 0x8F14, [10255] = 0x8F12, ++ [10256] = 0x8F15, [10257] = 0x8F13, [10258] = 0x8FA3, [10259] = 0x9060, ++ [10260] = 0x9058, [10261] = 0x905C, [10262] = 0x9063, [10263] = 0x9059, ++ [10264] = 0x905E, [10265] = 0x9062, [10266] = 0x905D, [10267] = 0x905B, ++ [10268] = 0x9119, [10269] = 0x9118, [10270] = 0x911E, [10271] = 0x9175, ++ [10272] = 0x9178, [10273] = 0x9177, [10274] = 0x9174, [10275] = 0x9278, ++ [10276] = 0x9280, [10277] = 0x9285, [10278] = 0x9298, [10279] = 0x9296, ++ [10280] = 0x927B, [10281] = 0x9293, [10282] = 0x929C, [10283] = 0x92A8, ++ [10284] = 0x927C, [10285] = 0x9291, [10286] = 0x95A1, [10287] = 0x95A8, ++ [10288] = 0x95A9, [10289] = 0x95A3, [10290] = 0x95A5, [10291] = 0x95A4, ++ [10292] = 0x9699, [10293] = 0x969C, [10294] = 0x969B, [10295] = 0x96CC, ++ [10296] = 0x96D2, [10297] = 0x9700, [10298] = 0x977C, [10299] = 0x9785, ++ [10300] = 0x97F6, [10301] = 0x9817, [10302] = 0x9818, [10303] = 0x98AF, ++ [10304] = 0x98B1, [10305] = 0x9903, [10306] = 0x9905, [10307] = 0x990C, ++ [10308] = 0x9909, [10309] = 0x99C1, [10310] = 0x9AAF, [10311] = 0x9AB0, ++ [10312] = 0x9AE6, [10313] = 0x9B41, [10314] = 0x9B42, [10315] = 0x9CF4, ++ [10316] = 0x9CF6, [10317] = 0x9CF3, [10318] = 0x9EBC, [10319] = 0x9F3B, ++ [10320] = 0x9F4A, [10321] = 0x5104, [10322] = 0x5100, [10323] = 0x50FB, ++ [10324] = 0x50F5, [10325] = 0x50F9, [10326] = 0x5102, [10327] = 0x5108, ++ [10328] = 0x5109, [10329] = 0x5105, [10330] = 0x51DC, [10335] = 0x5287, ++ [10336] = 0x5288, [10337] = 0x5289, [10338] = 0x528D, [10339] = 0x528A, ++ [10340] = 0x52F0, [10341] = 0x53B2, [10342] = 0x562E, [10343] = 0x563B, ++ [10344] = 0x5639, [10345] = 0x5632, [10346] = 0x563F, [10347] = 0x5634, ++ [10348] = 0x5629, [10349] = 0x5653, [10350] = 0x564E, [10351] = 0x5657, ++ [10352] = 0x5674, [10353] = 0x5636, [10354] = 0x562F, [10355] = 0x5630, ++ [10356] = 0x5880, [10357] = 0x589F, [10358] = 0x589E, [10359] = 0x58B3, ++ [10360] = 0x589C, [10361] = 0x58AE, [10362] = 0x58A9, [10363] = 0x58A6, ++ [10364] = 0x596D, [10365] = 0x5B09, [10366] = 0x5AFB, [10367] = 0x5B0B, ++ [10368] = 0x5AF5, [10369] = 0x5B0C, [10370] = 0x5B08, [10371] = 0x5BEE, ++ [10372] = 0x5BEC, [10373] = 0x5BE9, [10374] = 0x5BEB, [10375] = 0x5C64, ++ [10376] = 0x5C65, [10377] = 0x5D9D, [10378] = 0x5D94, [10379] = 0x5E62, ++ [10380] = 0x5E5F, [10381] = 0x5E61, [10382] = 0x5EE2, [10383] = 0x5EDA, ++ [10384] = 0x5EDF, [10385] = 0x5EDD, [10386] = 0x5EE3, [10387] = 0x5EE0, ++ [10388] = 0x5F48, [10389] = 0x5F71, [10390] = 0x5FB7, [10391] = 0x5FB5, ++ [10392] = 0x6176, [10393] = 0x6167, [10394] = 0x616E, [10395] = 0x615D, ++ [10396] = 0x6155, [10397] = 0x6182, [10432] = 0x617C, [10433] = 0x6170, ++ [10434] = 0x616B, [10435] = 0x617E, [10436] = 0x61A7, [10437] = 0x6190, ++ [10438] = 0x61AB, [10439] = 0x618E, [10440] = 0x61AC, [10441] = 0x619A, ++ [10442] = 0x61A4, [10443] = 0x6194, [10444] = 0x61AE, [10445] = 0x622E, ++ [10446] = 0x6469, [10447] = 0x646F, [10448] = 0x6479, [10449] = 0x649E, ++ [10450] = 0x64B2, [10451] = 0x6488, [10452] = 0x6490, [10453] = 0x64B0, ++ [10454] = 0x64A5, [10455] = 0x6493, [10456] = 0x6495, [10457] = 0x64A9, ++ [10458] = 0x6492, [10459] = 0x64AE, [10460] = 0x64AD, [10461] = 0x64AB, ++ [10462] = 0x649A, [10463] = 0x64AC, [10464] = 0x6499, [10465] = 0x64A2, ++ [10466] = 0x64B3, [10467] = 0x6575, [10468] = 0x6577, [10469] = 0x6578, ++ [10470] = 0x66AE, [10471] = 0x66AB, [10472] = 0x66B4, [10473] = 0x66B1, ++ [10474] = 0x6A23, [10475] = 0x6A1F, [10476] = 0x69E8, [10477] = 0x6A01, ++ [10478] = 0x6A1E, [10479] = 0x6A19, [10480] = 0x69FD, [10481] = 0x6A21, ++ [10482] = 0x6A13, [10483] = 0x6A0A, [10484] = 0x69F3, [10485] = 0x6A02, ++ [10486] = 0x6A05, [10487] = 0x69ED, [10488] = 0x6A11, [10489] = 0x6B50, ++ [10490] = 0x6B4E, [10491] = 0x6BA4, [10492] = 0x6BC5, [10493] = 0x6BC6, ++ [10494] = 0x6F3F, [10495] = 0x6F7C, [10496] = 0x6F84, [10497] = 0x6F51, ++ [10498] = 0x6F66, [10499] = 0x6F54, [10500] = 0x6F86, [10501] = 0x6F6D, ++ [10502] = 0x6F5B, [10503] = 0x6F78, [10504] = 0x6F6E, [10505] = 0x6F8E, ++ [10506] = 0x6F7A, [10507] = 0x6F70, [10508] = 0x6F64, [10509] = 0x6F97, ++ [10510] = 0x6F58, [10511] = 0x6ED5, [10512] = 0x6F6F, [10513] = 0x6F60, ++ [10514] = 0x6F5F, [10515] = 0x719F, [10516] = 0x71AC, [10517] = 0x71B1, ++ [10518] = 0x71A8, [10519] = 0x7256, [10520] = 0x729B, [10521] = 0x734E, ++ [10522] = 0x7357, [10523] = 0x7469, [10524] = 0x748B, [10525] = 0x7483, ++ [10530] = 0x747E, [10531] = 0x7480, [10532] = 0x757F, [10533] = 0x7620, ++ [10534] = 0x7629, [10535] = 0x761F, [10536] = 0x7624, [10537] = 0x7626, ++ [10538] = 0x7621, [10539] = 0x7622, [10540] = 0x769A, [10541] = 0x76BA, ++ [10542] = 0x76E4, [10543] = 0x778E, [10544] = 0x7787, [10545] = 0x778C, ++ [10546] = 0x7791, [10547] = 0x778B, [10548] = 0x78CB, [10549] = 0x78C5, ++ [10550] = 0x78BA, [10551] = 0x78CA, [10552] = 0x78BE, [10553] = 0x78D5, ++ [10554] = 0x78BC, [10555] = 0x78D0, [10556] = 0x7A3F, [10557] = 0x7A3C, ++ [10558] = 0x7A40, [10559] = 0x7A3D, [10560] = 0x7A37, [10561] = 0x7A3B, ++ [10562] = 0x7AAF, [10563] = 0x7AAE, [10564] = 0x7BAD, [10565] = 0x7BB1, ++ [10566] = 0x7BC4, [10567] = 0x7BB4, [10568] = 0x7BC6, [10569] = 0x7BC7, ++ [10570] = 0x7BC1, [10571] = 0x7BA0, [10572] = 0x7BCC, [10573] = 0x7CCA, ++ [10574] = 0x7DE0, [10575] = 0x7DF4, [10576] = 0x7DEF, [10577] = 0x7DFB, ++ [10578] = 0x7DD8, [10579] = 0x7DEC, [10580] = 0x7DDD, [10581] = 0x7DE8, ++ [10582] = 0x7DE3, [10583] = 0x7DDA, [10584] = 0x7DDE, [10585] = 0x7DE9, ++ [10586] = 0x7D9E, [10587] = 0x7DD9, [10588] = 0x7DF2, [10589] = 0x7DF9, ++ [10590] = 0x7F75, [10591] = 0x7F77, [10592] = 0x7FAF, [10627] = 0x7FE9, ++ [10628] = 0x8026, [10629] = 0x819B, [10630] = 0x819C, [10631] = 0x819D, ++ [10632] = 0x81A0, [10633] = 0x819A, [10634] = 0x8198, [10635] = 0x8517, ++ [10636] = 0x853D, [10637] = 0x851A, [10638] = 0x84EE, [10639] = 0x852C, ++ [10640] = 0x852D, [10641] = 0x8513, [10642] = 0x8511, [10643] = 0x8523, ++ [10644] = 0x8521, [10645] = 0x8514, [10646] = 0x84EC, [10647] = 0x8525, ++ [10648] = 0x84FF, [10649] = 0x8506, [10650] = 0x8782, [10651] = 0x8774, ++ [10652] = 0x8776, [10653] = 0x8760, [10654] = 0x8766, [10655] = 0x8778, ++ [10656] = 0x8768, [10657] = 0x8759, [10658] = 0x8757, [10659] = 0x874C, ++ [10660] = 0x8753, [10661] = 0x885B, [10662] = 0x885D, [10663] = 0x8910, ++ [10664] = 0x8907, [10665] = 0x8912, [10666] = 0x8913, [10667] = 0x8915, ++ [10668] = 0x890A, [10669] = 0x8ABC, [10670] = 0x8AD2, [10671] = 0x8AC7, ++ [10672] = 0x8AC4, [10673] = 0x8A95, [10674] = 0x8ACB, [10675] = 0x8AF8, ++ [10676] = 0x8AB2, [10677] = 0x8AC9, [10678] = 0x8AC2, [10679] = 0x8ABF, ++ [10680] = 0x8AB0, [10681] = 0x8AD6, [10682] = 0x8ACD, [10683] = 0x8AB6, ++ [10684] = 0x8AB9, [10685] = 0x8ADB, [10686] = 0x8C4C, [10687] = 0x8C4E, ++ [10688] = 0x8C6C, [10689] = 0x8CE0, [10690] = 0x8CDE, [10691] = 0x8CE6, ++ [10692] = 0x8CE4, [10693] = 0x8CEC, [10694] = 0x8CED, [10695] = 0x8CE2, ++ [10696] = 0x8CE3, [10697] = 0x8CDC, [10698] = 0x8CEA, [10699] = 0x8CE1, ++ [10700] = 0x8D6D, [10701] = 0x8D9F, [10702] = 0x8DA3, [10703] = 0x8E2B, ++ [10704] = 0x8E10, [10705] = 0x8E1D, [10706] = 0x8E22, [10707] = 0x8E0F, ++ [10708] = 0x8E29, [10709] = 0x8E1F, [10710] = 0x8E21, [10711] = 0x8E1E, ++ [10712] = 0x8EBA, [10713] = 0x8F1D, [10714] = 0x8F1B, [10715] = 0x8F1F, ++ [10716] = 0x8F29, [10717] = 0x8F26, [10718] = 0x8F2A, [10719] = 0x8F1C, ++ [10720] = 0x8F1E, [10725] = 0x8F25, [10726] = 0x9069, [10727] = 0x906E, ++ [10728] = 0x9068, [10729] = 0x906D, [10730] = 0x9077, [10731] = 0x9130, ++ [10732] = 0x912D, [10733] = 0x9127, [10734] = 0x9131, [10735] = 0x9187, ++ [10736] = 0x9189, [10737] = 0x918B, [10738] = 0x9183, [10739] = 0x92C5, ++ [10740] = 0x92BB, [10741] = 0x92B7, [10742] = 0x92EA, [10743] = 0x92AC, ++ [10744] = 0x92E4, [10745] = 0x92C1, [10746] = 0x92B3, [10747] = 0x92BC, ++ [10748] = 0x92D2, [10749] = 0x92C7, [10750] = 0x92F0, [10751] = 0x92B2, ++ [10752] = 0x95AD, [10753] = 0x95B1, [10754] = 0x9704, [10755] = 0x9706, ++ [10756] = 0x9707, [10757] = 0x9709, [10758] = 0x9760, [10759] = 0x978D, ++ [10760] = 0x978B, [10761] = 0x978F, [10762] = 0x9821, [10763] = 0x982B, ++ [10764] = 0x981C, [10765] = 0x98B3, [10766] = 0x990A, [10767] = 0x9913, ++ [10768] = 0x9912, [10769] = 0x9918, [10770] = 0x99DD, [10771] = 0x99D0, ++ [10772] = 0x99DF, [10773] = 0x99DB, [10774] = 0x99D1, [10775] = 0x99D5, ++ [10776] = 0x99D2, [10777] = 0x99D9, [10778] = 0x9AB7, [10779] = 0x9AEE, ++ [10780] = 0x9AEF, [10781] = 0x9B27, [10782] = 0x9B45, [10783] = 0x9B44, ++ [10784] = 0x9B77, [10785] = 0x9B6F, [10786] = 0x9D06, [10787] = 0x9D09, ++ [10822] = 0x9D03, [10823] = 0x9EA9, [10824] = 0x9EBE, [10825] = 0x9ECE, ++ [10826] = 0x58A8, [10827] = 0x9F52, [10828] = 0x5112, [10829] = 0x5118, ++ [10830] = 0x5114, [10831] = 0x5110, [10832] = 0x5115, [10833] = 0x5180, ++ [10834] = 0x51AA, [10835] = 0x51DD, [10836] = 0x5291, [10837] = 0x5293, ++ [10838] = 0x52F3, [10839] = 0x5659, [10840] = 0x566B, [10841] = 0x5679, ++ [10842] = 0x5669, [10843] = 0x5664, [10844] = 0x5678, [10845] = 0x566A, ++ [10846] = 0x5668, [10847] = 0x5665, [10848] = 0x5671, [10849] = 0x566F, ++ [10850] = 0x566C, [10851] = 0x5662, [10852] = 0x5676, [10853] = 0x58C1, ++ [10854] = 0x58BE, [10855] = 0x58C7, [10856] = 0x58C5, [10857] = 0x596E, ++ [10858] = 0x5B1D, [10859] = 0x5B34, [10860] = 0x5B78, [10861] = 0x5BF0, ++ [10862] = 0x5C0E, [10863] = 0x5F4A, [10864] = 0x61B2, [10865] = 0x6191, ++ [10866] = 0x61A9, [10867] = 0x618A, [10868] = 0x61CD, [10869] = 0x61B6, ++ [10870] = 0x61BE, [10871] = 0x61CA, [10872] = 0x61C8, [10873] = 0x6230, ++ [10874] = 0x64C5, [10875] = 0x64C1, [10876] = 0x64CB, [10877] = 0x64BB, ++ [10878] = 0x64BC, [10879] = 0x64DA, [10880] = 0x64C4, [10881] = 0x64C7, ++ [10882] = 0x64C2, [10883] = 0x64CD, [10884] = 0x64BF, [10885] = 0x64D2, ++ [10886] = 0x64D4, [10887] = 0x64BE, [10888] = 0x6574, [10889] = 0x66C6, ++ [10890] = 0x66C9, [10891] = 0x66B9, [10892] = 0x66C4, [10893] = 0x66C7, ++ [10894] = 0x66B8, [10895] = 0x6A3D, [10896] = 0x6A38, [10897] = 0x6A3A, ++ [10898] = 0x6A59, [10899] = 0x6A6B, [10900] = 0x6A58, [10901] = 0x6A39, ++ [10902] = 0x6A44, [10903] = 0x6A62, [10904] = 0x6A61, [10905] = 0x6A4B, ++ [10906] = 0x6A47, [10907] = 0x6A35, [10908] = 0x6A5F, [10909] = 0x6A48, ++ [10910] = 0x6B59, [10911] = 0x6B77, [10912] = 0x6C05, [10913] = 0x6FC2, ++ [10914] = 0x6FB1, [10915] = 0x6FA1, [10920] = 0x6FC3, [10921] = 0x6FA4, ++ [10922] = 0x6FC1, [10923] = 0x6FA7, [10924] = 0x6FB3, [10925] = 0x6FC0, ++ [10926] = 0x6FB9, [10927] = 0x6FB6, [10928] = 0x6FA6, [10929] = 0x6FA0, ++ [10930] = 0x6FB4, [10931] = 0x71BE, [10932] = 0x71C9, [10933] = 0x71D0, ++ [10934] = 0x71D2, [10935] = 0x71C8, [10936] = 0x71D5, [10937] = 0x71B9, ++ [10938] = 0x71CE, [10939] = 0x71D9, [10940] = 0x71DC, [10941] = 0x71C3, ++ [10942] = 0x71C4, [10943] = 0x7368, [10944] = 0x749C, [10945] = 0x74A3, ++ [10946] = 0x7498, [10947] = 0x749F, [10948] = 0x749E, [10949] = 0x74E2, ++ [10950] = 0x750C, [10951] = 0x750D, [10952] = 0x7634, [10953] = 0x7638, ++ [10954] = 0x763A, [10955] = 0x76E7, [10956] = 0x76E5, [10957] = 0x77A0, ++ [10958] = 0x779E, [10959] = 0x779F, [10960] = 0x77A5, [10961] = 0x78E8, ++ [10962] = 0x78DA, [10963] = 0x78EC, [10964] = 0x78E7, [10965] = 0x79A6, ++ [10966] = 0x7A4D, [10967] = 0x7A4E, [10968] = 0x7A46, [10969] = 0x7A4C, ++ [10970] = 0x7A4B, [10971] = 0x7ABA, [10972] = 0x7BD9, [10973] = 0x7C11, ++ [10974] = 0x7BC9, [10975] = 0x7BE4, [10976] = 0x7BDB, [10977] = 0x7BE1, ++ [10978] = 0x7BE9, [10979] = 0x7BE6, [10980] = 0x7CD5, [10981] = 0x7CD6, ++ [10982] = 0x7E0A, [11017] = 0x7E11, [11018] = 0x7E08, [11019] = 0x7E1B, ++ [11020] = 0x7E23, [11021] = 0x7E1E, [11022] = 0x7E1D, [11023] = 0x7E09, ++ [11024] = 0x7E10, [11025] = 0x7F79, [11026] = 0x7FB2, [11027] = 0x7FF0, ++ [11028] = 0x7FF1, [11029] = 0x7FEE, [11030] = 0x8028, [11031] = 0x81B3, ++ [11032] = 0x81A9, [11033] = 0x81A8, [11034] = 0x81FB, [11035] = 0x8208, ++ [11036] = 0x8258, [11037] = 0x8259, [11038] = 0x854A, [11039] = 0x8559, ++ [11040] = 0x8548, [11041] = 0x8568, [11042] = 0x8569, [11043] = 0x8543, ++ [11044] = 0x8549, [11045] = 0x856D, [11046] = 0x856A, [11047] = 0x855E, ++ [11048] = 0x8783, [11049] = 0x879F, [11050] = 0x879E, [11051] = 0x87A2, ++ [11052] = 0x878D, [11053] = 0x8861, [11054] = 0x892A, [11055] = 0x8932, ++ [11056] = 0x8925, [11057] = 0x892B, [11058] = 0x8921, [11059] = 0x89AA, ++ [11060] = 0x89A6, [11061] = 0x8AE6, [11062] = 0x8AFA, [11063] = 0x8AEB, ++ [11064] = 0x8AF1, [11065] = 0x8B00, [11066] = 0x8ADC, [11067] = 0x8AE7, ++ [11068] = 0x8AEE, [11069] = 0x8AFE, [11070] = 0x8B01, [11071] = 0x8B02, ++ [11072] = 0x8AF7, [11073] = 0x8AED, [11074] = 0x8AF3, [11075] = 0x8AF6, ++ [11076] = 0x8AFC, [11077] = 0x8C6B, [11078] = 0x8C6D, [11079] = 0x8C93, ++ [11080] = 0x8CF4, [11081] = 0x8E44, [11082] = 0x8E31, [11083] = 0x8E34, ++ [11084] = 0x8E42, [11085] = 0x8E39, [11086] = 0x8E35, [11087] = 0x8F3B, ++ [11088] = 0x8F2F, [11089] = 0x8F38, [11090] = 0x8F33, [11091] = 0x8FA8, ++ [11092] = 0x8FA6, [11093] = 0x9075, [11094] = 0x9074, [11095] = 0x9078, ++ [11096] = 0x9072, [11097] = 0x907C, [11098] = 0x907A, [11099] = 0x9134, ++ [11100] = 0x9192, [11101] = 0x9320, [11102] = 0x9336, [11103] = 0x92F8, ++ [11104] = 0x9333, [11105] = 0x932F, [11106] = 0x9322, [11107] = 0x92FC, ++ [11108] = 0x932B, [11109] = 0x9304, [11110] = 0x931A, [11115] = 0x9310, ++ [11116] = 0x9326, [11117] = 0x9321, [11118] = 0x9315, [11119] = 0x932E, ++ [11120] = 0x9319, [11121] = 0x95BB, [11122] = 0x96A7, [11123] = 0x96A8, ++ [11124] = 0x96AA, [11125] = 0x96D5, [11126] = 0x970E, [11127] = 0x9711, ++ [11128] = 0x9716, [11129] = 0x970D, [11130] = 0x9713, [11131] = 0x970F, ++ [11132] = 0x975B, [11133] = 0x975C, [11134] = 0x9766, [11135] = 0x9798, ++ [11136] = 0x9830, [11137] = 0x9838, [11138] = 0x983B, [11139] = 0x9837, ++ [11140] = 0x982D, [11141] = 0x9839, [11142] = 0x9824, [11143] = 0x9910, ++ [11144] = 0x9928, [11145] = 0x991E, [11146] = 0x991B, [11147] = 0x9921, ++ [11148] = 0x991A, [11149] = 0x99ED, [11150] = 0x99E2, [11151] = 0x99F1, ++ [11152] = 0x9AB8, [11153] = 0x9ABC, [11154] = 0x9AFB, [11155] = 0x9AED, ++ [11156] = 0x9B28, [11157] = 0x9B91, [11158] = 0x9D15, [11159] = 0x9D23, ++ [11160] = 0x9D26, [11161] = 0x9D28, [11162] = 0x9D12, [11163] = 0x9D1B, ++ [11164] = 0x9ED8, [11165] = 0x9ED4, [11166] = 0x9F8D, [11167] = 0x9F9C, ++ [11168] = 0x512A, [11169] = 0x511F, [11170] = 0x5121, [11171] = 0x5132, ++ [11172] = 0x52F5, [11173] = 0x568E, [11174] = 0x5680, [11175] = 0x5690, ++ [11176] = 0x5685, [11177] = 0x5687, [11212] = 0x568F, [11213] = 0x58D5, ++ [11214] = 0x58D3, [11215] = 0x58D1, [11216] = 0x58CE, [11217] = 0x5B30, ++ [11218] = 0x5B2A, [11219] = 0x5B24, [11220] = 0x5B7A, [11221] = 0x5C37, ++ [11222] = 0x5C68, [11223] = 0x5DBC, [11224] = 0x5DBA, [11225] = 0x5DBD, ++ [11226] = 0x5DB8, [11227] = 0x5E6B, [11228] = 0x5F4C, [11229] = 0x5FBD, ++ [11230] = 0x61C9, [11231] = 0x61C2, [11232] = 0x61C7, [11233] = 0x61E6, ++ [11234] = 0x61CB, [11235] = 0x6232, [11236] = 0x6234, [11237] = 0x64CE, ++ [11238] = 0x64CA, [11239] = 0x64D8, [11240] = 0x64E0, [11241] = 0x64F0, ++ [11242] = 0x64E6, [11243] = 0x64EC, [11244] = 0x64F1, [11245] = 0x64E2, ++ [11246] = 0x64ED, [11247] = 0x6582, [11248] = 0x6583, [11249] = 0x66D9, ++ [11250] = 0x66D6, [11251] = 0x6A80, [11252] = 0x6A94, [11253] = 0x6A84, ++ [11254] = 0x6AA2, [11255] = 0x6A9C, [11256] = 0x6ADB, [11257] = 0x6AA3, ++ [11258] = 0x6A7E, [11259] = 0x6A97, [11260] = 0x6A90, [11261] = 0x6AA0, ++ [11262] = 0x6B5C, [11263] = 0x6BAE, [11264] = 0x6BDA, [11265] = 0x6C08, ++ [11266] = 0x6FD8, [11267] = 0x6FF1, [11268] = 0x6FDF, [11269] = 0x6FE0, ++ [11270] = 0x6FDB, [11271] = 0x6FE4, [11272] = 0x6FEB, [11273] = 0x6FEF, ++ [11274] = 0x6F80, [11275] = 0x6FEC, [11276] = 0x6FE1, [11277] = 0x6FE9, ++ [11278] = 0x6FD5, [11279] = 0x6FEE, [11280] = 0x6FF0, [11281] = 0x71E7, ++ [11282] = 0x71DF, [11283] = 0x71EE, [11284] = 0x71E6, [11285] = 0x71E5, ++ [11286] = 0x71ED, [11287] = 0x71EC, [11288] = 0x71F4, [11289] = 0x71E0, ++ [11290] = 0x7235, [11291] = 0x7246, [11292] = 0x7370, [11293] = 0x7372, ++ [11294] = 0x74A9, [11295] = 0x74B0, [11296] = 0x74A6, [11297] = 0x74A8, ++ [11298] = 0x7646, [11299] = 0x7642, [11300] = 0x764C, [11301] = 0x76EA, ++ [11302] = 0x77B3, [11303] = 0x77AA, [11304] = 0x77B0, [11305] = 0x77AC, ++ [11310] = 0x77A7, [11311] = 0x77AD, [11312] = 0x77EF, [11313] = 0x78F7, ++ [11314] = 0x78FA, [11315] = 0x78F4, [11316] = 0x78EF, [11317] = 0x7901, ++ [11318] = 0x79A7, [11319] = 0x79AA, [11320] = 0x7A57, [11321] = 0x7ABF, ++ [11322] = 0x7C07, [11323] = 0x7C0D, [11324] = 0x7BFE, [11325] = 0x7BF7, ++ [11326] = 0x7C0C, [11327] = 0x7BE0, [11328] = 0x7CE0, [11329] = 0x7CDC, ++ [11330] = 0x7CDE, [11331] = 0x7CE2, [11332] = 0x7CDF, [11333] = 0x7CD9, ++ [11334] = 0x7CDD, [11335] = 0x7E2E, [11336] = 0x7E3E, [11337] = 0x7E46, ++ [11338] = 0x7E37, [11339] = 0x7E32, [11340] = 0x7E43, [11341] = 0x7E2B, ++ [11342] = 0x7E3D, [11343] = 0x7E31, [11344] = 0x7E45, [11345] = 0x7E41, ++ [11346] = 0x7E34, [11347] = 0x7E39, [11348] = 0x7E48, [11349] = 0x7E35, ++ [11350] = 0x7E3F, [11351] = 0x7E2F, [11352] = 0x7F44, [11353] = 0x7FF3, ++ [11354] = 0x7FFC, [11355] = 0x8071, [11356] = 0x8072, [11357] = 0x8070, ++ [11358] = 0x806F, [11359] = 0x8073, [11360] = 0x81C6, [11361] = 0x81C3, ++ [11362] = 0x81BA, [11363] = 0x81C2, [11364] = 0x81C0, [11365] = 0x81BF, ++ [11366] = 0x81BD, [11367] = 0x81C9, [11368] = 0x81BE, [11369] = 0x81E8, ++ [11370] = 0x8209, [11371] = 0x8271, [11372] = 0x85AA, [11407] = 0x8584, ++ [11408] = 0x857E, [11409] = 0x859C, [11410] = 0x8591, [11411] = 0x8594, ++ [11412] = 0x85AF, [11413] = 0x859B, [11414] = 0x8587, [11415] = 0x85A8, ++ [11416] = 0x858A, [11417] = 0x8667, [11418] = 0x87C0, [11419] = 0x87D1, ++ [11420] = 0x87B3, [11421] = 0x87D2, [11422] = 0x87C6, [11423] = 0x87AB, ++ [11424] = 0x87BB, [11425] = 0x87BA, [11426] = 0x87C8, [11427] = 0x87CB, ++ [11428] = 0x893B, [11429] = 0x8936, [11430] = 0x8944, [11431] = 0x8938, ++ [11432] = 0x893D, [11433] = 0x89AC, [11434] = 0x8B0E, [11435] = 0x8B17, ++ [11436] = 0x8B19, [11437] = 0x8B1B, [11438] = 0x8B0A, [11439] = 0x8B20, ++ [11440] = 0x8B1D, [11441] = 0x8B04, [11442] = 0x8B10, [11443] = 0x8C41, ++ [11444] = 0x8C3F, [11445] = 0x8C73, [11446] = 0x8CFA, [11447] = 0x8CFD, ++ [11448] = 0x8CFC, [11449] = 0x8CF8, [11450] = 0x8CFB, [11451] = 0x8DA8, ++ [11452] = 0x8E49, [11453] = 0x8E4B, [11454] = 0x8E48, [11455] = 0x8E4A, ++ [11456] = 0x8F44, [11457] = 0x8F3E, [11458] = 0x8F42, [11459] = 0x8F45, ++ [11460] = 0x8F3F, [11461] = 0x907F, [11462] = 0x907D, [11463] = 0x9084, ++ [11464] = 0x9081, [11465] = 0x9082, [11466] = 0x9080, [11467] = 0x9139, ++ [11468] = 0x91A3, [11469] = 0x919E, [11470] = 0x919C, [11471] = 0x934D, ++ [11472] = 0x9382, [11473] = 0x9328, [11474] = 0x9375, [11475] = 0x934A, ++ [11476] = 0x9365, [11477] = 0x934B, [11478] = 0x9318, [11479] = 0x937E, ++ [11480] = 0x936C, [11481] = 0x935B, [11482] = 0x9370, [11483] = 0x935A, ++ [11484] = 0x9354, [11485] = 0x95CA, [11486] = 0x95CB, [11487] = 0x95CC, ++ [11488] = 0x95C8, [11489] = 0x95C6, [11490] = 0x96B1, [11491] = 0x96B8, ++ [11492] = 0x96D6, [11493] = 0x971C, [11494] = 0x971E, [11495] = 0x97A0, ++ [11496] = 0x97D3, [11497] = 0x9846, [11498] = 0x98B6, [11499] = 0x9935, ++ [11500] = 0x9A01, [11505] = 0x99FF, [11506] = 0x9BAE, [11507] = 0x9BAB, ++ [11508] = 0x9BAA, [11509] = 0x9BAD, [11510] = 0x9D3B, [11511] = 0x9D3F, ++ [11512] = 0x9E8B, [11513] = 0x9ECF, [11514] = 0x9EDE, [11515] = 0x9EDC, ++ [11516] = 0x9EDD, [11517] = 0x9EDB, [11518] = 0x9F3E, [11519] = 0x9F4B, ++ [11520] = 0x53E2, [11521] = 0x5695, [11522] = 0x56AE, [11523] = 0x58D9, ++ [11524] = 0x58D8, [11525] = 0x5B38, [11526] = 0x5F5D, [11527] = 0x61E3, ++ [11528] = 0x6233, [11529] = 0x64F4, [11530] = 0x64F2, [11531] = 0x64FE, ++ [11532] = 0x6506, [11533] = 0x64FA, [11534] = 0x64FB, [11535] = 0x64F7, ++ [11536] = 0x65B7, [11537] = 0x66DC, [11538] = 0x6726, [11539] = 0x6AB3, ++ [11540] = 0x6AAC, [11541] = 0x6AC3, [11542] = 0x6ABB, [11543] = 0x6AB8, ++ [11544] = 0x6AC2, [11545] = 0x6AAE, [11546] = 0x6AAF, [11547] = 0x6B5F, ++ [11548] = 0x6B78, [11549] = 0x6BAF, [11550] = 0x7009, [11551] = 0x700B, ++ [11552] = 0x6FFE, [11553] = 0x7006, [11554] = 0x6FFA, [11555] = 0x7011, ++ [11556] = 0x700F, [11557] = 0x71FB, [11558] = 0x71FC, [11559] = 0x71FE, ++ [11560] = 0x71F8, [11561] = 0x7377, [11562] = 0x7375, [11563] = 0x74A7, ++ [11564] = 0x74BF, [11565] = 0x7515, [11566] = 0x7656, [11567] = 0x7658, ++ [11602] = 0x7652, [11603] = 0x77BD, [11604] = 0x77BF, [11605] = 0x77BB, ++ [11606] = 0x77BC, [11607] = 0x790E, [11608] = 0x79AE, [11609] = 0x7A61, ++ [11610] = 0x7A62, [11611] = 0x7A60, [11612] = 0x7AC4, [11613] = 0x7AC5, ++ [11614] = 0x7C2B, [11615] = 0x7C27, [11616] = 0x7C2A, [11617] = 0x7C1E, ++ [11618] = 0x7C23, [11619] = 0x7C21, [11620] = 0x7CE7, [11621] = 0x7E54, ++ [11622] = 0x7E55, [11623] = 0x7E5E, [11624] = 0x7E5A, [11625] = 0x7E61, ++ [11626] = 0x7E52, [11627] = 0x7E59, [11628] = 0x7F48, [11629] = 0x7FF9, ++ [11630] = 0x7FFB, [11631] = 0x8077, [11632] = 0x8076, [11633] = 0x81CD, ++ [11634] = 0x81CF, [11635] = 0x820A, [11636] = 0x85CF, [11637] = 0x85A9, ++ [11638] = 0x85CD, [11639] = 0x85D0, [11640] = 0x85C9, [11641] = 0x85B0, ++ [11642] = 0x85BA, [11643] = 0x85B9, [11644] = 0x85A6, [11645] = 0x87EF, ++ [11646] = 0x87EC, [11647] = 0x87F2, [11648] = 0x87E0, [11649] = 0x8986, ++ [11650] = 0x89B2, [11651] = 0x89F4, [11652] = 0x8B28, [11653] = 0x8B39, ++ [11654] = 0x8B2C, [11655] = 0x8B2B, [11656] = 0x8C50, [11657] = 0x8D05, ++ [11658] = 0x8E59, [11659] = 0x8E63, [11660] = 0x8E66, [11661] = 0x8E64, ++ [11662] = 0x8E5F, [11663] = 0x8E55, [11664] = 0x8EC0, [11665] = 0x8F49, ++ [11666] = 0x8F4D, [11667] = 0x9087, [11668] = 0x9083, [11669] = 0x9088, ++ [11670] = 0x91AB, [11671] = 0x91AC, [11672] = 0x91D0, [11673] = 0x9394, ++ [11674] = 0x938A, [11675] = 0x9396, [11676] = 0x93A2, [11677] = 0x93B3, ++ [11678] = 0x93AE, [11679] = 0x93AC, [11680] = 0x93B0, [11681] = 0x9398, ++ [11682] = 0x939A, [11683] = 0x9397, [11684] = 0x95D4, [11685] = 0x95D6, ++ [11686] = 0x95D0, [11687] = 0x95D5, [11688] = 0x96E2, [11689] = 0x96DC, ++ [11690] = 0x96D9, [11691] = 0x96DB, [11692] = 0x96DE, [11693] = 0x9724, ++ [11694] = 0x97A3, [11695] = 0x97A6, [11700] = 0x97AD, [11701] = 0x97F9, ++ [11702] = 0x984D, [11703] = 0x984F, [11704] = 0x984C, [11705] = 0x984E, ++ [11706] = 0x9853, [11707] = 0x98BA, [11708] = 0x993E, [11709] = 0x993F, ++ [11710] = 0x993D, [11711] = 0x992E, [11712] = 0x99A5, [11713] = 0x9A0E, ++ [11714] = 0x9AC1, [11715] = 0x9B03, [11716] = 0x9B06, [11717] = 0x9B4F, ++ [11718] = 0x9B4E, [11719] = 0x9B4D, [11720] = 0x9BCA, [11721] = 0x9BC9, ++ [11722] = 0x9BFD, [11723] = 0x9BC8, [11724] = 0x9BC0, [11725] = 0x9D51, ++ [11726] = 0x9D5D, [11727] = 0x9D60, [11728] = 0x9EE0, [11729] = 0x9F15, ++ [11730] = 0x9F2C, [11731] = 0x5133, [11732] = 0x56A5, [11733] = 0x58DE, ++ [11734] = 0x58DF, [11735] = 0x58E2, [11736] = 0x5BF5, [11737] = 0x9F90, ++ [11738] = 0x5EEC, [11739] = 0x61F2, [11740] = 0x61F7, [11741] = 0x61F6, ++ [11742] = 0x61F5, [11743] = 0x6500, [11744] = 0x650F, [11745] = 0x66E0, ++ [11746] = 0x66DD, [11747] = 0x6AE5, [11748] = 0x6ADD, [11749] = 0x6ADA, ++ [11750] = 0x6AD3, [11751] = 0x701B, [11752] = 0x701F, [11753] = 0x7028, ++ [11754] = 0x701A, [11755] = 0x701D, [11756] = 0x7015, [11757] = 0x7018, ++ [11758] = 0x7206, [11759] = 0x720D, [11760] = 0x7258, [11761] = 0x72A2, ++ [11762] = 0x7378, [11797] = 0x737A, [11798] = 0x74BD, [11799] = 0x74CA, ++ [11800] = 0x74E3, [11801] = 0x7587, [11802] = 0x7586, [11803] = 0x765F, ++ [11804] = 0x7661, [11805] = 0x77C7, [11806] = 0x7919, [11807] = 0x79B1, ++ [11808] = 0x7A6B, [11809] = 0x7A69, [11810] = 0x7C3E, [11811] = 0x7C3F, ++ [11812] = 0x7C38, [11813] = 0x7C3D, [11814] = 0x7C37, [11815] = 0x7C40, ++ [11816] = 0x7E6B, [11817] = 0x7E6D, [11818] = 0x7E79, [11819] = 0x7E69, ++ [11820] = 0x7E6A, [11821] = 0x7F85, [11822] = 0x7E73, [11823] = 0x7FB6, ++ [11824] = 0x7FB9, [11825] = 0x7FB8, [11826] = 0x81D8, [11827] = 0x85E9, ++ [11828] = 0x85DD, [11829] = 0x85EA, [11830] = 0x85D5, [11831] = 0x85E4, ++ [11832] = 0x85E5, [11833] = 0x85F7, [11834] = 0x87FB, [11835] = 0x8805, ++ [11836] = 0x880D, [11837] = 0x87F9, [11838] = 0x87FE, [11839] = 0x8960, ++ [11840] = 0x895F, [11841] = 0x8956, [11842] = 0x895E, [11843] = 0x8B41, ++ [11844] = 0x8B5C, [11845] = 0x8B58, [11846] = 0x8B49, [11847] = 0x8B5A, ++ [11848] = 0x8B4E, [11849] = 0x8B4F, [11850] = 0x8B46, [11851] = 0x8B59, ++ [11852] = 0x8D08, [11853] = 0x8D0A, [11854] = 0x8E7C, [11855] = 0x8E72, ++ [11856] = 0x8E87, [11857] = 0x8E76, [11858] = 0x8E6C, [11859] = 0x8E7A, ++ [11860] = 0x8E74, [11861] = 0x8F54, [11862] = 0x8F4E, [11863] = 0x8FAD, ++ [11864] = 0x908A, [11865] = 0x908B, [11866] = 0x91B1, [11867] = 0x91AE, ++ [11868] = 0x93E1, [11869] = 0x93D1, [11870] = 0x93DF, [11871] = 0x93C3, ++ [11872] = 0x93C8, [11873] = 0x93DC, [11874] = 0x93DD, [11875] = 0x93D6, ++ [11876] = 0x93E2, [11877] = 0x93CD, [11878] = 0x93D8, [11879] = 0x93E4, ++ [11880] = 0x93D7, [11881] = 0x93E8, [11882] = 0x95DC, [11883] = 0x96B4, ++ [11884] = 0x96E3, [11885] = 0x972A, [11886] = 0x9727, [11887] = 0x9761, ++ [11888] = 0x97DC, [11889] = 0x97FB, [11890] = 0x985E, [11895] = 0x9858, ++ [11896] = 0x985B, [11897] = 0x98BC, [11898] = 0x9945, [11899] = 0x9949, ++ [11900] = 0x9A16, [11901] = 0x9A19, [11902] = 0x9B0D, [11903] = 0x9BE8, ++ [11904] = 0x9BE7, [11905] = 0x9BD6, [11906] = 0x9BDB, [11907] = 0x9D89, ++ [11908] = 0x9D61, [11909] = 0x9D72, [11910] = 0x9D6A, [11911] = 0x9D6C, ++ [11912] = 0x9E92, [11913] = 0x9E97, [11914] = 0x9E93, [11915] = 0x9EB4, ++ [11916] = 0x52F8, [11917] = 0x56A8, [11918] = 0x56B7, [11919] = 0x56B6, ++ [11920] = 0x56B4, [11921] = 0x56BC, [11922] = 0x58E4, [11923] = 0x5B40, ++ [11924] = 0x5B43, [11925] = 0x5B7D, [11926] = 0x5BF6, [11927] = 0x5DC9, ++ [11928] = 0x61F8, [11929] = 0x61FA, [11930] = 0x6518, [11931] = 0x6514, ++ [11932] = 0x6519, [11933] = 0x66E6, [11934] = 0x6727, [11935] = 0x6AEC, ++ [11936] = 0x703E, [11937] = 0x7030, [11938] = 0x7032, [11939] = 0x7210, ++ [11940] = 0x737B, [11941] = 0x74CF, [11942] = 0x7662, [11943] = 0x7665, ++ [11944] = 0x7926, [11945] = 0x792A, [11946] = 0x792C, [11947] = 0x792B, ++ [11948] = 0x7AC7, [11949] = 0x7AF6, [11950] = 0x7C4C, [11951] = 0x7C43, ++ [11952] = 0x7C4D, [11953] = 0x7CEF, [11954] = 0x7CF0, [11955] = 0x8FAE, ++ [11956] = 0x7E7D, [11957] = 0x7E7C, [11992] = 0x7E82, [11993] = 0x7F4C, ++ [11994] = 0x8000, [11995] = 0x81DA, [11996] = 0x8266, [11997] = 0x85FB, ++ [11998] = 0x85F9, [11999] = 0x8611, [12000] = 0x85FA, [12001] = 0x8606, ++ [12002] = 0x860B, [12003] = 0x8607, [12004] = 0x860A, [12005] = 0x8814, ++ [12006] = 0x8815, [12007] = 0x8964, [12008] = 0x89BA, [12009] = 0x89F8, ++ [12010] = 0x8B70, [12011] = 0x8B6C, [12012] = 0x8B66, [12013] = 0x8B6F, ++ [12014] = 0x8B5F, [12015] = 0x8B6B, [12016] = 0x8D0F, [12017] = 0x8D0D, ++ [12018] = 0x8E89, [12019] = 0x8E81, [12020] = 0x8E85, [12021] = 0x8E82, ++ [12022] = 0x91B4, [12023] = 0x91CB, [12024] = 0x9418, [12025] = 0x9403, ++ [12026] = 0x93FD, [12027] = 0x95E1, [12028] = 0x9730, [12029] = 0x98C4, ++ [12030] = 0x9952, [12031] = 0x9951, [12032] = 0x99A8, [12033] = 0x9A2B, ++ [12034] = 0x9A30, [12035] = 0x9A37, [12036] = 0x9A35, [12037] = 0x9C13, ++ [12038] = 0x9C0D, [12039] = 0x9E79, [12040] = 0x9EB5, [12041] = 0x9EE8, ++ [12042] = 0x9F2F, [12043] = 0x9F5F, [12044] = 0x9F63, [12045] = 0x9F61, ++ [12046] = 0x5137, [12047] = 0x5138, [12048] = 0x56C1, [12049] = 0x56C0, ++ [12050] = 0x56C2, [12051] = 0x5914, [12052] = 0x5C6C, [12053] = 0x5DCD, ++ [12054] = 0x61FC, [12055] = 0x61FE, [12056] = 0x651D, [12057] = 0x651C, ++ [12058] = 0x6595, [12059] = 0x66E9, [12060] = 0x6AFB, [12061] = 0x6B04, ++ [12062] = 0x6AFA, [12063] = 0x6BB2, [12064] = 0x704C, [12065] = 0x721B, ++ [12066] = 0x72A7, [12067] = 0x74D6, [12068] = 0x74D4, [12069] = 0x7669, ++ [12070] = 0x77D3, [12071] = 0x7C50, [12072] = 0x7E8F, [12073] = 0x7E8C, ++ [12074] = 0x7FBC, [12075] = 0x8617, [12076] = 0x862D, [12077] = 0x861A, ++ [12078] = 0x8823, [12079] = 0x8822, [12080] = 0x8821, [12081] = 0x881F, ++ [12082] = 0x896A, [12083] = 0x896C, [12084] = 0x89BD, [12085] = 0x8B74, ++ [12090] = 0x8B77, [12091] = 0x8B7D, [12092] = 0x8D13, [12093] = 0x8E8A, ++ [12094] = 0x8E8D, [12095] = 0x8E8B, [12096] = 0x8F5F, [12097] = 0x8FAF, ++ [12098] = 0x91BA, [12099] = 0x942E, [12100] = 0x9433, [12101] = 0x9435, ++ [12102] = 0x943A, [12103] = 0x9438, [12104] = 0x9432, [12105] = 0x942B, ++ [12106] = 0x95E2, [12107] = 0x9738, [12108] = 0x9739, [12109] = 0x9732, ++ [12110] = 0x97FF, [12111] = 0x9867, [12112] = 0x9865, [12113] = 0x9957, ++ [12114] = 0x9A45, [12115] = 0x9A43, [12116] = 0x9A40, [12117] = 0x9A3E, ++ [12118] = 0x9ACF, [12119] = 0x9B54, [12120] = 0x9B51, [12121] = 0x9C2D, ++ [12122] = 0x9C25, [12123] = 0x9DAF, [12124] = 0x9DB4, [12125] = 0x9DC2, ++ [12126] = 0x9DB8, [12127] = 0x9E9D, [12128] = 0x9EEF, [12129] = 0x9F19, ++ [12130] = 0x9F5C, [12131] = 0x9F66, [12132] = 0x9F67, [12133] = 0x513C, ++ [12134] = 0x513B, [12135] = 0x56C8, [12136] = 0x56CA, [12137] = 0x56C9, ++ [12138] = 0x5B7F, [12139] = 0x5DD4, [12140] = 0x5DD2, [12141] = 0x5F4E, ++ [12142] = 0x61FF, [12143] = 0x6524, [12144] = 0x6B0A, [12145] = 0x6B61, ++ [12146] = 0x7051, [12147] = 0x7058, [12148] = 0x7380, [12149] = 0x74E4, ++ [12150] = 0x758A, [12151] = 0x766E, [12152] = 0x766C, [12187] = 0x79B3, ++ [12188] = 0x7C60, [12189] = 0x7C5F, [12190] = 0x807E, [12191] = 0x807D, ++ [12192] = 0x81DF, [12193] = 0x8972, [12194] = 0x896F, [12195] = 0x89FC, ++ [12196] = 0x8B80, [12197] = 0x8D16, [12198] = 0x8D17, [12199] = 0x8E91, ++ [12200] = 0x8E93, [12201] = 0x8F61, [12202] = 0x9148, [12203] = 0x9444, ++ [12204] = 0x9451, [12205] = 0x9452, [12206] = 0x973D, [12207] = 0x973E, ++ [12208] = 0x97C3, [12209] = 0x97C1, [12210] = 0x986B, [12211] = 0x9955, ++ [12212] = 0x9A55, [12213] = 0x9A4D, [12214] = 0x9AD2, [12215] = 0x9B1A, ++ [12216] = 0x9C49, [12217] = 0x9C31, [12218] = 0x9C3E, [12219] = 0x9C3B, ++ [12220] = 0x9DD3, [12221] = 0x9DD7, [12222] = 0x9F34, [12223] = 0x9F6C, ++ [12224] = 0x9F6A, [12225] = 0x9F94, [12226] = 0x56CC, [12227] = 0x5DD6, ++ [12228] = 0x6200, [12229] = 0x6523, [12230] = 0x652B, [12231] = 0x652A, ++ [12232] = 0x66EC, [12233] = 0x6B10, [12234] = 0x74DA, [12235] = 0x7ACA, ++ [12236] = 0x7C64, [12237] = 0x7C63, [12238] = 0x7C65, [12239] = 0x7E93, ++ [12240] = 0x7E96, [12241] = 0x7E94, [12242] = 0x81E2, [12243] = 0x8638, ++ [12244] = 0x863F, [12245] = 0x8831, [12246] = 0x8B8A, [12247] = 0x9090, ++ [12248] = 0x908F, [12249] = 0x9463, [12250] = 0x9460, [12251] = 0x9464, ++ [12252] = 0x9768, [12253] = 0x986F, [12254] = 0x995C, [12255] = 0x9A5A, ++ [12256] = 0x9A5B, [12257] = 0x9A57, [12258] = 0x9AD3, [12259] = 0x9AD4, ++ [12260] = 0x9AD1, [12261] = 0x9C54, [12262] = 0x9C57, [12263] = 0x9C56, ++ [12264] = 0x9DE5, [12265] = 0x9E9F, [12266] = 0x9EF4, [12267] = 0x56D1, ++ [12268] = 0x58E9, [12269] = 0x652C, [12270] = 0x705E, [12271] = 0x7671, ++ [12272] = 0x7672, [12273] = 0x77D7, [12274] = 0x7F50, [12275] = 0x7F88, ++ [12276] = 0x8836, [12277] = 0x8839, [12278] = 0x8862, [12279] = 0x8B93, ++ [12280] = 0x8B92, [12285] = 0x8B96, [12286] = 0x8277, [12287] = 0x8D1B, ++ [12288] = 0x91C0, [12289] = 0x946A, [12290] = 0x9742, [12291] = 0x9748, ++ [12292] = 0x9744, [12293] = 0x97C6, [12294] = 0x9870, [12295] = 0x9A5F, ++ [12296] = 0x9B22, [12297] = 0x9B58, [12298] = 0x9C5F, [12299] = 0x9DF9, ++ [12300] = 0x9DFA, [12301] = 0x9E7C, [12302] = 0x9E7D, [12303] = 0x9F07, ++ [12304] = 0x9F77, [12305] = 0x9F72, [12306] = 0x5EF3, [12307] = 0x6B16, ++ [12308] = 0x7063, [12309] = 0x7C6C, [12310] = 0x7C6E, [12311] = 0x883B, ++ [12312] = 0x89C0, [12313] = 0x8EA1, [12314] = 0x91C1, [12315] = 0x9472, ++ [12316] = 0x9470, [12317] = 0x9871, [12318] = 0x995E, [12319] = 0x9AD6, ++ [12320] = 0x9B23, [12321] = 0x9ECC, [12322] = 0x7064, [12323] = 0x77DA, ++ [12324] = 0x8B9A, [12325] = 0x9477, [12326] = 0x97C9, [12327] = 0x9A62, ++ [12328] = 0x9A65, [12329] = 0x7E9C, [12330] = 0x8B9C, [12331] = 0x8EAA, ++ [12332] = 0x91C5, [12333] = 0x947D, [12334] = 0x947E, [12335] = 0x947C, ++ [12336] = 0x9C77, [12337] = 0x9C78, [12338] = 0x9EF7, [12339] = 0x8C54, ++ [12340] = 0x947F, [12341] = 0x9E1A, [12342] = 0x7228, [12343] = 0x9A6A, ++ [12344] = 0x9B31, [12345] = 0x9E1B, [12346] = 0x9E1E, [12347] = 0x7C72, ++ [12382] = 0x2460, [12383] = 0x2461, [12384] = 0x2462, [12385] = 0x2463, ++ [12386] = 0x2464, [12387] = 0x2465, [12388] = 0x2466, [12389] = 0x2467, ++ [12390] = 0x2468, [12391] = 0x2469, [12392] = 0x2474, [12393] = 0x2475, ++ [12394] = 0x2476, [12395] = 0x2477, [12396] = 0x2478, [12397] = 0x2479, ++ [12398] = 0x247A, [12399] = 0x247B, [12400] = 0x247C, [12401] = 0x247D, ++ [12402] = 0x2170, [12403] = 0x2171, [12404] = 0x2172, [12405] = 0x2173, ++ [12406] = 0x2174, [12407] = 0x2175, [12408] = 0x2176, [12409] = 0x2177, ++ [12410] = 0x2178, [12411] = 0x2179, [12412] = 0x4E36, [12413] = 0x4E3F, ++ [12414] = 0x4E85, [12415] = 0x4EA0, [12416] = 0x5182, [12417] = 0x5196, ++ [12418] = 0x51AB, [12419] = 0x52F9, [12420] = 0x5338, [12421] = 0x5369, ++ [12422] = 0x53B6, [12423] = 0x590A, [12424] = 0x5B80, [12425] = 0x5DDB, ++ [12426] = 0x2F33, [12427] = 0x5E7F, [12429] = 0x5F50, [12430] = 0x5F61, ++ [12431] = 0x6534, [12433] = 0x7592, [12435] = 0x8FB5, [12437] = 0x00A8, ++ [12438] = 0x02C6, [12439] = 0x30FD, [12440] = 0x30FE, [12441] = 0x309D, ++ [12442] = 0x309E, [12445] = 0x3005, [12446] = 0x3006, [12447] = 0x3007, ++ [12448] = 0x30FC, [12449] = 0xFF3B, [12450] = 0xFF3D, [12451] = 0x273D, ++ [12452] = 0x3041, [12453] = 0x3042, [12454] = 0x3043, [12455] = 0x3044, ++ [12456] = 0x3045, [12457] = 0x3046, [12458] = 0x3047, [12459] = 0x3048, ++ [12460] = 0x3049, [12461] = 0x304A, [12462] = 0x304B, [12463] = 0x304C, ++ [12464] = 0x304D, [12465] = 0x304E, [12466] = 0x304F, [12467] = 0x3050, ++ [12468] = 0x3051, [12469] = 0x3052, [12470] = 0x3053, [12471] = 0x3054, ++ [12472] = 0x3055, [12473] = 0x3056, [12474] = 0x3057, [12475] = 0x3058, ++ [12480] = 0x3059, [12481] = 0x305A, [12482] = 0x305B, [12483] = 0x305C, ++ [12484] = 0x305D, [12485] = 0x305E, [12486] = 0x305F, [12487] = 0x3060, ++ [12488] = 0x3061, [12489] = 0x3062, [12490] = 0x3063, [12491] = 0x3064, ++ [12492] = 0x3065, [12493] = 0x3066, [12494] = 0x3067, [12495] = 0x3068, ++ [12496] = 0x3069, [12497] = 0x306A, [12498] = 0x306B, [12499] = 0x306C, ++ [12500] = 0x306D, [12501] = 0x306E, [12502] = 0x306F, [12503] = 0x3070, ++ [12504] = 0x3071, [12505] = 0x3072, [12506] = 0x3073, [12507] = 0x3074, ++ [12508] = 0x3075, [12509] = 0x3076, [12510] = 0x3077, [12511] = 0x3078, ++ [12512] = 0x3079, [12513] = 0x307A, [12514] = 0x307B, [12515] = 0x307C, ++ [12516] = 0x307D, [12517] = 0x307E, [12518] = 0x307F, [12519] = 0x3080, ++ [12520] = 0x3081, [12521] = 0x3082, [12522] = 0x3083, [12523] = 0x3084, ++ [12524] = 0x3085, [12525] = 0x3086, [12526] = 0x3087, [12527] = 0x3088, ++ [12528] = 0x3089, [12529] = 0x308A, [12530] = 0x308B, [12531] = 0x308C, ++ [12532] = 0x308D, [12533] = 0x308E, [12534] = 0x308F, [12535] = 0x3090, ++ [12536] = 0x3091, [12537] = 0x3092, [12538] = 0x3093, [12539] = 0x30A1, ++ [12540] = 0x30A2, [12541] = 0x30A3, [12542] = 0x30A4, [12577] = 0x30A5, ++ [12578] = 0x30A6, [12579] = 0x30A7, [12580] = 0x30A8, [12581] = 0x30A9, ++ [12582] = 0x30AA, [12583] = 0x30AB, [12584] = 0x30AC, [12585] = 0x30AD, ++ [12586] = 0x30AE, [12587] = 0x30AF, [12588] = 0x30B0, [12589] = 0x30B1, ++ [12590] = 0x30B2, [12591] = 0x30B3, [12592] = 0x30B4, [12593] = 0x30B5, ++ [12594] = 0x30B6, [12595] = 0x30B7, [12596] = 0x30B8, [12597] = 0x30B9, ++ [12598] = 0x30BA, [12599] = 0x30BB, [12600] = 0x30BC, [12601] = 0x30BD, ++ [12602] = 0x30BE, [12603] = 0x30BF, [12604] = 0x30C0, [12605] = 0x30C1, ++ [12606] = 0x30C2, [12607] = 0x30C3, [12608] = 0x30C4, [12609] = 0x30C5, ++ [12610] = 0x30C6, [12611] = 0x30C7, [12612] = 0x30C8, [12613] = 0x30C9, ++ [12614] = 0x30CA, [12615] = 0x30CB, [12616] = 0x30CC, [12617] = 0x30CD, ++ [12618] = 0x30CE, [12619] = 0x30CF, [12620] = 0x30D0, [12621] = 0x30D1, ++ [12622] = 0x30D2, [12623] = 0x30D3, [12624] = 0x30D4, [12625] = 0x30D5, ++ [12626] = 0x30D6, [12627] = 0x30D7, [12628] = 0x30D8, [12629] = 0x30D9, ++ [12630] = 0x30DA, [12631] = 0x30DB, [12632] = 0x30DC, [12633] = 0x30DD, ++ [12634] = 0x30DE, [12635] = 0x30DF, [12636] = 0x30E0, [12637] = 0x30E1, ++ [12638] = 0x30E2, [12639] = 0x30E3, [12640] = 0x30E4, [12641] = 0x30E5, ++ [12642] = 0x30E6, [12643] = 0x30E7, [12644] = 0x30E8, [12645] = 0x30E9, ++ [12646] = 0x30EA, [12647] = 0x30EB, [12648] = 0x30EC, [12649] = 0x30ED, ++ [12650] = 0x30EE, [12651] = 0x30EF, [12652] = 0x30F0, [12653] = 0x30F1, ++ [12654] = 0x30F2, [12655] = 0x30F3, [12656] = 0x30F4, [12657] = 0x30F5, ++ [12658] = 0x30F6, [12659] = 0x0410, [12660] = 0x0411, [12661] = 0x0412, ++ [12662] = 0x0413, [12663] = 0x0414, [12664] = 0x0415, [12665] = 0x0401, ++ [12666] = 0x0416, [12667] = 0x0417, [12668] = 0x0418, [12669] = 0x0419, ++ [12670] = 0x041A, [12675] = 0x041B, [12676] = 0x041C, [12677] = 0x041D, ++ [12678] = 0x041E, [12679] = 0x041F, [12680] = 0x0420, [12681] = 0x0421, ++ [12682] = 0x0422, [12683] = 0x0423, [12684] = 0x0424, [12685] = 0x0425, ++ [12686] = 0x0426, [12687] = 0x0427, [12688] = 0x0428, [12689] = 0x0429, ++ [12690] = 0x042A, [12691] = 0x042B, [12692] = 0x042C, [12693] = 0x042D, ++ [12694] = 0x042E, [12695] = 0x042F, [12696] = 0x0430, [12697] = 0x0431, ++ [12698] = 0x0432, [12699] = 0x0433, [12700] = 0x0434, [12701] = 0x0435, ++ [12702] = 0x0451, [12703] = 0x0436, [12704] = 0x0437, [12705] = 0x0438, ++ [12706] = 0x0439, [12707] = 0x043A, [12708] = 0x043B, [12709] = 0x043C, ++ [12710] = 0x043D, [12711] = 0x043E, [12712] = 0x043F, [12713] = 0x0440, ++ [12714] = 0x0441, [12715] = 0x0442, [12716] = 0x0443, [12717] = 0x0444, ++ [12718] = 0x0445, [12719] = 0x0446, [12720] = 0x0447, [12721] = 0x0448, ++ [12722] = 0x0449, [12723] = 0x044A, [12724] = 0x044B, [12725] = 0x044C, ++ [12726] = 0x044D, [12727] = 0x044E, [12728] = 0x044F, [12729] = 0x21E7, ++ [12730] = 0x21B8, [12731] = 0x21B9, [12732] = 0x31CF, [12733] = 0x200CC, ++ [12734] = 0x4E5A, [12735] = 0x2008A, [12736] = 0x5202, [12737] = 0x4491, ++ [12772] = 0x9FB0, [12773] = 0x5188, [12774] = 0x9FB1, [12775] = 0x27607, ++ [12816] = 0xFFE2, [12817] = 0xFFE4, [12818] = 0xFF07, [12819] = 0xFF02, ++ [12820] = 0x3231, [12821] = 0x2116, [12822] = 0x2121, [12823] = 0x309B, ++ [12824] = 0x309C, [12825] = 0x2E80, [12826] = 0x2E84, [12827] = 0x2E86, ++ [12828] = 0x2E87, [12829] = 0x2E88, [12830] = 0x2E8A, [12831] = 0x2E8C, ++ [12832] = 0x2E8D, [12833] = 0x2E95, [12834] = 0x2E9C, [12835] = 0x2E9D, ++ [12836] = 0x2EA5, [12837] = 0x2EA7, [12838] = 0x2EAA, [12839] = 0x2EAC, ++ [12840] = 0x2EAE, [12841] = 0x2EB6, [12842] = 0x2EBC, [12843] = 0x2EBE, ++ [12844] = 0x2EC6, [12845] = 0x2ECA, [12846] = 0x2ECC, [12847] = 0x2ECD, ++ [12848] = 0x2ECF, [12849] = 0x2ED6, [12850] = 0x2ED7, [12851] = 0x2EDE, ++ [12852] = 0x2EE3, [12856] = 0x0283, [12857] = 0x0250, [12858] = 0x025B, ++ [12859] = 0x0254, [12860] = 0x0275, [12861] = 0x0153, [12862] = 0x00F8, ++ [12863] = 0x014B, [12864] = 0x028A, [12865] = 0x026A, [12870] = 0x4E42, ++ [12871] = 0x4E5C, [12872] = 0x51F5, [12873] = 0x531A, [12874] = 0x5382, ++ [12875] = 0x4E07, [12876] = 0x4E0C, [12877] = 0x4E47, [12878] = 0x4E8D, ++ [12879] = 0x56D7, [12880] = 0xFA0C, [12881] = 0x5C6E, [12882] = 0x5F73, ++ [12883] = 0x4E0F, [12884] = 0x5187, [12885] = 0x4E0E, [12886] = 0x4E2E, ++ [12887] = 0x4E93, [12888] = 0x4EC2, [12889] = 0x4EC9, [12890] = 0x4EC8, ++ [12891] = 0x5198, [12892] = 0x52FC, [12893] = 0x536C, [12894] = 0x53B9, ++ [12895] = 0x5720, [12896] = 0x5903, [12897] = 0x592C, [12898] = 0x5C10, ++ [12899] = 0x5DFF, [12900] = 0x65E1, [12901] = 0x6BB3, [12902] = 0x6BCC, ++ [12903] = 0x6C14, [12904] = 0x723F, [12905] = 0x4E31, [12906] = 0x4E3C, ++ [12907] = 0x4EE8, [12908] = 0x4EDC, [12909] = 0x4EE9, [12910] = 0x4EE1, ++ [12911] = 0x4EDD, [12912] = 0x4EDA, [12913] = 0x520C, [12914] = 0x531C, ++ [12915] = 0x534C, [12916] = 0x5722, [12917] = 0x5723, [12918] = 0x5917, ++ [12919] = 0x592F, [12920] = 0x5B81, [12921] = 0x5B84, [12922] = 0x5C12, ++ [12923] = 0x5C3B, [12924] = 0x5C74, [12925] = 0x5C73, [12926] = 0x5E04, ++ [12927] = 0x5E80, [12928] = 0x5E82, [12929] = 0x5FC9, [12930] = 0x6209, ++ [12931] = 0x6250, [12932] = 0x6C15, [12967] = 0x6C36, [12968] = 0x6C43, ++ [12969] = 0x6C3F, [12970] = 0x6C3B, [12971] = 0x72AE, [12972] = 0x72B0, ++ [12973] = 0x738A, [12974] = 0x79B8, [12975] = 0x808A, [12976] = 0x961E, ++ [12977] = 0x4F0E, [12978] = 0x4F18, [12979] = 0x4F2C, [12980] = 0x4EF5, ++ [12981] = 0x4F14, [12982] = 0x4EF1, [12983] = 0x4F00, [12984] = 0x4EF7, ++ [12985] = 0x4F08, [12986] = 0x4F1D, [12987] = 0x4F02, [12988] = 0x4F05, ++ [12989] = 0x4F22, [12990] = 0x4F13, [12991] = 0x4F04, [12992] = 0x4EF4, ++ [12993] = 0x4F12, [12994] = 0x51B1, [12995] = 0x5213, [12996] = 0x5209, ++ [12997] = 0x5210, [12998] = 0x52A6, [12999] = 0x5322, [13000] = 0x531F, ++ [13001] = 0x534D, [13002] = 0x538A, [13003] = 0x5407, [13004] = 0x56E1, ++ [13005] = 0x56DF, [13006] = 0x572E, [13007] = 0x572A, [13008] = 0x5734, ++ [13009] = 0x593C, [13010] = 0x5980, [13011] = 0x597C, [13012] = 0x5985, ++ [13013] = 0x597B, [13014] = 0x597E, [13015] = 0x5977, [13016] = 0x597F, ++ [13017] = 0x5B56, [13018] = 0x5C15, [13019] = 0x5C25, [13020] = 0x5C7C, ++ [13021] = 0x5C7A, [13022] = 0x5C7B, [13023] = 0x5C7E, [13024] = 0x5DDF, ++ [13025] = 0x5E75, [13026] = 0x5E84, [13027] = 0x5F02, [13028] = 0x5F1A, ++ [13029] = 0x5F74, [13030] = 0x5FD5, [13031] = 0x5FD4, [13032] = 0x5FCF, ++ [13033] = 0x625C, [13034] = 0x625E, [13035] = 0x6264, [13036] = 0x6261, ++ [13037] = 0x6266, [13038] = 0x6262, [13039] = 0x6259, [13040] = 0x6260, ++ [13041] = 0x625A, [13042] = 0x6265, [13043] = 0x65EF, [13044] = 0x65EE, ++ [13045] = 0x673E, [13046] = 0x6739, [13047] = 0x6738, [13048] = 0x673B, ++ [13049] = 0x673A, [13050] = 0x673F, [13051] = 0x673C, [13052] = 0x6733, ++ [13053] = 0x6C18, [13054] = 0x6C46, [13055] = 0x6C52, [13056] = 0x6C5C, ++ [13057] = 0x6C4F, [13058] = 0x6C4A, [13059] = 0x6C54, [13060] = 0x6C4B, ++ [13065] = 0x6C4C, [13066] = 0x7071, [13067] = 0x725E, [13068] = 0x72B4, ++ [13069] = 0x72B5, [13070] = 0x738E, [13071] = 0x752A, [13072] = 0x767F, ++ [13073] = 0x7A75, [13074] = 0x7F51, [13075] = 0x8278, [13076] = 0x827C, ++ [13077] = 0x8280, [13078] = 0x827D, [13079] = 0x827F, [13080] = 0x864D, ++ [13081] = 0x897E, [13082] = 0x9099, [13083] = 0x9097, [13084] = 0x9098, ++ [13085] = 0x909B, [13086] = 0x9094, [13087] = 0x9622, [13088] = 0x9624, ++ [13089] = 0x9620, [13090] = 0x9623, [13091] = 0x4F56, [13092] = 0x4F3B, ++ [13093] = 0x4F62, [13094] = 0x4F49, [13095] = 0x4F53, [13096] = 0x4F64, ++ [13097] = 0x4F3E, [13098] = 0x4F67, [13099] = 0x4F52, [13100] = 0x4F5F, ++ [13101] = 0x4F41, [13102] = 0x4F58, [13103] = 0x4F2D, [13104] = 0x4F33, ++ [13105] = 0x4F3F, [13106] = 0x4F61, [13107] = 0x518F, [13108] = 0x51B9, ++ [13109] = 0x521C, [13110] = 0x521E, [13111] = 0x5221, [13112] = 0x52AD, ++ [13113] = 0x52AE, [13114] = 0x5309, [13115] = 0x5363, [13116] = 0x5372, ++ [13117] = 0x538E, [13118] = 0x538F, [13119] = 0x5430, [13120] = 0x5437, ++ [13121] = 0x542A, [13122] = 0x5454, [13123] = 0x5445, [13124] = 0x5419, ++ [13125] = 0x541C, [13126] = 0x5425, [13127] = 0x5418, [13162] = 0x543D, ++ [13163] = 0x544F, [13164] = 0x5441, [13165] = 0x5428, [13166] = 0x5424, ++ [13167] = 0x5447, [13168] = 0x56EE, [13169] = 0x56E7, [13170] = 0x56E5, ++ [13171] = 0x5741, [13172] = 0x5745, [13173] = 0x574C, [13174] = 0x5749, ++ [13175] = 0x574B, [13176] = 0x5752, [13177] = 0x5906, [13178] = 0x5940, ++ [13179] = 0x59A6, [13180] = 0x5998, [13181] = 0x59A0, [13182] = 0x5997, ++ [13183] = 0x598E, [13184] = 0x59A2, [13185] = 0x5990, [13186] = 0x598F, ++ [13187] = 0x59A7, [13188] = 0x59A1, [13189] = 0x5B8E, [13190] = 0x5B92, ++ [13191] = 0x5C28, [13192] = 0x5C2A, [13193] = 0x5C8D, [13194] = 0x5C8F, ++ [13195] = 0x5C88, [13196] = 0x5C8B, [13197] = 0x5C89, [13198] = 0x5C92, ++ [13199] = 0x5C8A, [13200] = 0x5C86, [13201] = 0x5C93, [13202] = 0x5C95, ++ [13203] = 0x5DE0, [13204] = 0x5E0A, [13205] = 0x5E0E, [13206] = 0x5E8B, ++ [13207] = 0x5E89, [13208] = 0x5E8C, [13209] = 0x5E88, [13210] = 0x5E8D, ++ [13211] = 0x5F05, [13212] = 0x5F1D, [13213] = 0x5F78, [13214] = 0x5F76, ++ [13215] = 0x5FD2, [13216] = 0x5FD1, [13217] = 0x5FD0, [13218] = 0x5FED, ++ [13219] = 0x5FE8, [13220] = 0x5FEE, [13221] = 0x5FF3, [13222] = 0x5FE1, ++ [13223] = 0x5FE4, [13224] = 0x5FE3, [13225] = 0x5FFA, [13226] = 0x5FEF, ++ [13227] = 0x5FF7, [13228] = 0x5FFB, [13229] = 0x6000, [13230] = 0x5FF4, ++ [13231] = 0x623A, [13232] = 0x6283, [13233] = 0x628C, [13234] = 0x628E, ++ [13235] = 0x628F, [13236] = 0x6294, [13237] = 0x6287, [13238] = 0x6271, ++ [13239] = 0x627B, [13240] = 0x627A, [13241] = 0x6270, [13242] = 0x6281, ++ [13243] = 0x6288, [13244] = 0x6277, [13245] = 0x627D, [13246] = 0x6272, ++ [13247] = 0x6274, [13248] = 0x6537, [13249] = 0x65F0, [13250] = 0x65F4, ++ [13251] = 0x65F3, [13252] = 0x65F2, [13253] = 0x65F5, [13254] = 0x6745, ++ [13255] = 0x6747, [13260] = 0x6759, [13261] = 0x6755, [13262] = 0x674C, ++ [13263] = 0x6748, [13264] = 0x675D, [13265] = 0x674D, [13266] = 0x675A, ++ [13267] = 0x674B, [13268] = 0x6BD0, [13269] = 0x6C19, [13270] = 0x6C1A, ++ [13271] = 0x6C78, [13272] = 0x6C67, [13273] = 0x6C6B, [13274] = 0x6C84, ++ [13275] = 0x6C8B, [13276] = 0x6C8F, [13277] = 0x6C71, [13278] = 0x6C6F, ++ [13279] = 0x6C69, [13280] = 0x6C9A, [13281] = 0x6C6D, [13282] = 0x6C87, ++ [13283] = 0x6C95, [13284] = 0x6C9C, [13285] = 0x6C66, [13286] = 0x6C73, ++ [13287] = 0x6C65, [13288] = 0x6C7B, [13289] = 0x6C8E, [13290] = 0x7074, ++ [13291] = 0x707A, [13292] = 0x7263, [13293] = 0x72BF, [13294] = 0x72BD, ++ [13295] = 0x72C3, [13296] = 0x72C6, [13297] = 0x72C1, [13298] = 0x72BA, ++ [13299] = 0x72C5, [13300] = 0x7395, [13301] = 0x7397, [13302] = 0x7393, ++ [13303] = 0x7394, [13304] = 0x7392, [13305] = 0x753A, [13306] = 0x7539, ++ [13307] = 0x7594, [13308] = 0x7595, [13309] = 0x7681, [13310] = 0x793D, ++ [13311] = 0x8034, [13312] = 0x8095, [13313] = 0x8099, [13314] = 0x8090, ++ [13315] = 0x8092, [13316] = 0x809C, [13317] = 0x8290, [13318] = 0x828F, ++ [13319] = 0x8285, [13320] = 0x828E, [13321] = 0x8291, [13322] = 0x8293, ++ [13357] = 0x828A, [13358] = 0x8283, [13359] = 0x8284, [13360] = 0x8C78, ++ [13361] = 0x8FC9, [13362] = 0x8FBF, [13363] = 0x909F, [13364] = 0x90A1, ++ [13365] = 0x90A5, [13366] = 0x909E, [13367] = 0x90A7, [13368] = 0x90A0, ++ [13369] = 0x9630, [13370] = 0x9628, [13371] = 0x962F, [13372] = 0x962D, ++ [13373] = 0x4E33, [13374] = 0x4F98, [13375] = 0x4F7C, [13376] = 0x4F85, ++ [13377] = 0x4F7D, [13378] = 0x4F80, [13379] = 0x4F87, [13380] = 0x4F76, ++ [13381] = 0x4F74, [13382] = 0x4F89, [13383] = 0x4F84, [13384] = 0x4F77, ++ [13385] = 0x4F4C, [13386] = 0x4F97, [13387] = 0x4F6A, [13388] = 0x4F9A, ++ [13389] = 0x4F79, [13390] = 0x4F81, [13391] = 0x4F78, [13392] = 0x4F90, ++ [13393] = 0x4F9C, [13394] = 0x4F94, [13395] = 0x4F9E, [13396] = 0x4F92, ++ [13397] = 0x4F82, [13398] = 0x4F95, [13399] = 0x4F6B, [13400] = 0x4F6E, ++ [13401] = 0x519E, [13402] = 0x51BC, [13403] = 0x51BE, [13404] = 0x5235, ++ [13405] = 0x5232, [13406] = 0x5233, [13407] = 0x5246, [13408] = 0x5231, ++ [13409] = 0x52BC, [13410] = 0x530A, [13411] = 0x530B, [13412] = 0x533C, ++ [13413] = 0x5392, [13414] = 0x5394, [13415] = 0x5487, [13416] = 0x547F, ++ [13417] = 0x5481, [13418] = 0x5491, [13419] = 0x5482, [13420] = 0x5488, ++ [13421] = 0x546B, [13422] = 0x547A, [13423] = 0x547E, [13424] = 0x5465, ++ [13425] = 0x546C, [13426] = 0x5474, [13427] = 0x5466, [13428] = 0x548D, ++ [13429] = 0x546F, [13430] = 0x5461, [13431] = 0x5460, [13432] = 0x5498, ++ [13433] = 0x5463, [13434] = 0x5467, [13435] = 0x5464, [13436] = 0x56F7, ++ [13437] = 0x56F9, [13438] = 0x576F, [13439] = 0x5772, [13440] = 0x576D, ++ [13441] = 0x576B, [13442] = 0x5771, [13443] = 0x5770, [13444] = 0x5776, ++ [13445] = 0x5780, [13446] = 0x5775, [13447] = 0x577B, [13448] = 0x5773, ++ [13449] = 0x5774, [13450] = 0x5762, [13455] = 0x5768, [13456] = 0x577D, ++ [13457] = 0x590C, [13458] = 0x5945, [13459] = 0x59B5, [13460] = 0x59BA, ++ [13461] = 0x59CF, [13462] = 0x59CE, [13463] = 0x59B2, [13464] = 0x59CC, ++ [13465] = 0x59C1, [13466] = 0x59B6, [13467] = 0x59BC, [13468] = 0x59C3, ++ [13469] = 0x59D6, [13470] = 0x59B1, [13471] = 0x59BD, [13472] = 0x59C0, ++ [13473] = 0x59C8, [13474] = 0x59B4, [13475] = 0x59C7, [13476] = 0x5B62, ++ [13477] = 0x5B65, [13478] = 0x5B93, [13479] = 0x5B95, [13480] = 0x5C44, ++ [13481] = 0x5C47, [13482] = 0x5CAE, [13483] = 0x5CA4, [13484] = 0x5CA0, ++ [13485] = 0x5CB5, [13486] = 0x5CAF, [13487] = 0x5CA8, [13488] = 0x5CAC, ++ [13489] = 0x5C9F, [13490] = 0x5CA3, [13491] = 0x5CAD, [13492] = 0x5CA2, ++ [13493] = 0x5CAA, [13494] = 0x5CA7, [13495] = 0x5C9D, [13496] = 0x5CA5, ++ [13497] = 0x5CB6, [13498] = 0x5CB0, [13499] = 0x5CA6, [13500] = 0x5E17, ++ [13501] = 0x5E14, [13502] = 0x5E19, [13503] = 0x5F28, [13504] = 0x5F22, ++ [13505] = 0x5F23, [13506] = 0x5F24, [13507] = 0x5F54, [13508] = 0x5F82, ++ [13509] = 0x5F7E, [13510] = 0x5F7D, [13511] = 0x5FDE, [13512] = 0x5FE5, ++ [13513] = 0x602D, [13514] = 0x6026, [13515] = 0x6019, [13516] = 0x6032, ++ [13517] = 0x600B, [13552] = 0x6034, [13553] = 0x600A, [13554] = 0x6017, ++ [13555] = 0x6033, [13556] = 0x601A, [13557] = 0x601E, [13558] = 0x602C, ++ [13559] = 0x6022, [13560] = 0x600D, [13561] = 0x6010, [13562] = 0x602E, ++ [13563] = 0x6013, [13564] = 0x6011, [13565] = 0x600C, [13566] = 0x6009, ++ [13567] = 0x601C, [13568] = 0x6214, [13569] = 0x623D, [13570] = 0x62AD, ++ [13571] = 0x62B4, [13572] = 0x62D1, [13573] = 0x62BE, [13574] = 0x62AA, ++ [13575] = 0x62B6, [13576] = 0x62CA, [13577] = 0x62AE, [13578] = 0x62B3, ++ [13579] = 0x62AF, [13580] = 0x62BB, [13581] = 0x62A9, [13582] = 0x62B0, ++ [13583] = 0x62B8, [13584] = 0x653D, [13585] = 0x65A8, [13586] = 0x65BB, ++ [13587] = 0x6609, [13588] = 0x65FC, [13589] = 0x6604, [13590] = 0x6612, ++ [13591] = 0x6608, [13592] = 0x65FB, [13593] = 0x6603, [13594] = 0x660B, ++ [13595] = 0x660D, [13596] = 0x6605, [13597] = 0x65FD, [13598] = 0x6611, ++ [13599] = 0x6610, [13600] = 0x66F6, [13601] = 0x670A, [13602] = 0x6785, ++ [13603] = 0x676C, [13604] = 0x678E, [13605] = 0x6792, [13606] = 0x6776, ++ [13607] = 0x677B, [13608] = 0x6798, [13609] = 0x6786, [13610] = 0x6784, ++ [13611] = 0x6774, [13612] = 0x678D, [13613] = 0x678C, [13614] = 0x677A, ++ [13615] = 0x679F, [13616] = 0x6791, [13617] = 0x6799, [13618] = 0x6783, ++ [13619] = 0x677D, [13620] = 0x6781, [13621] = 0x6778, [13622] = 0x6779, ++ [13623] = 0x6794, [13624] = 0x6B25, [13625] = 0x6B80, [13626] = 0x6B7E, ++ [13627] = 0x6BDE, [13628] = 0x6C1D, [13629] = 0x6C93, [13630] = 0x6CEC, ++ [13631] = 0x6CEB, [13632] = 0x6CEE, [13633] = 0x6CD9, [13634] = 0x6CB6, ++ [13635] = 0x6CD4, [13636] = 0x6CAD, [13637] = 0x6CE7, [13638] = 0x6CB7, ++ [13639] = 0x6CD0, [13640] = 0x6CC2, [13641] = 0x6CBA, [13642] = 0x6CC3, ++ [13643] = 0x6CC6, [13644] = 0x6CED, [13645] = 0x6CF2, [13650] = 0x6CD2, ++ [13651] = 0x6CDD, [13652] = 0x6CB4, [13653] = 0x6C8A, [13654] = 0x6C9D, ++ [13655] = 0x6C80, [13656] = 0x6CDE, [13657] = 0x6CC0, [13658] = 0x6D30, ++ [13659] = 0x6CCD, [13660] = 0x6CC7, [13661] = 0x6CB0, [13662] = 0x6CF9, ++ [13663] = 0x6CCF, [13664] = 0x6CE9, [13665] = 0x6CD1, [13666] = 0x7094, ++ [13667] = 0x7098, [13668] = 0x7085, [13669] = 0x7093, [13670] = 0x7086, ++ [13671] = 0x7084, [13672] = 0x7091, [13673] = 0x7096, [13674] = 0x7082, ++ [13675] = 0x709A, [13676] = 0x7083, [13677] = 0x726A, [13678] = 0x72D6, ++ [13679] = 0x72CB, [13680] = 0x72D8, [13681] = 0x72C9, [13682] = 0x72DC, ++ [13683] = 0x72D2, [13684] = 0x72D4, [13685] = 0x72DA, [13686] = 0x72CC, ++ [13687] = 0x72D1, [13688] = 0x73A4, [13689] = 0x73A1, [13690] = 0x73AD, ++ [13691] = 0x73A6, [13692] = 0x73A2, [13693] = 0x73A0, [13694] = 0x73AC, ++ [13695] = 0x739D, [13696] = 0x74DD, [13697] = 0x74E8, [13698] = 0x753F, ++ [13699] = 0x7540, [13700] = 0x753E, [13701] = 0x758C, [13702] = 0x7598, ++ [13703] = 0x76AF, [13704] = 0x76F3, [13705] = 0x76F1, [13706] = 0x76F0, ++ [13707] = 0x76F5, [13708] = 0x77F8, [13709] = 0x77FC, [13710] = 0x77F9, ++ [13711] = 0x77FB, [13712] = 0x77FA, [13747] = 0x77F7, [13748] = 0x7942, ++ [13749] = 0x793F, [13750] = 0x79C5, [13751] = 0x7A78, [13752] = 0x7A7B, ++ [13753] = 0x7AFB, [13754] = 0x7C75, [13755] = 0x7CFD, [13756] = 0x8035, ++ [13757] = 0x808F, [13758] = 0x80AE, [13759] = 0x80A3, [13760] = 0x80B8, ++ [13761] = 0x80B5, [13762] = 0x80AD, [13763] = 0x8220, [13764] = 0x82A0, ++ [13765] = 0x82C0, [13766] = 0x82AB, [13767] = 0x829A, [13768] = 0x8298, ++ [13769] = 0x829B, [13770] = 0x82B5, [13771] = 0x82A7, [13772] = 0x82AE, ++ [13773] = 0x82BC, [13774] = 0x829E, [13775] = 0x82BA, [13776] = 0x82B4, ++ [13777] = 0x82A8, [13778] = 0x82A1, [13779] = 0x82A9, [13780] = 0x82C2, ++ [13781] = 0x82A4, [13782] = 0x82C3, [13783] = 0x82B6, [13784] = 0x82A2, ++ [13785] = 0x8670, [13786] = 0x866F, [13787] = 0x866D, [13788] = 0x866E, ++ [13789] = 0x8C56, [13790] = 0x8FD2, [13791] = 0x8FCB, [13792] = 0x8FD3, ++ [13793] = 0x8FCD, [13794] = 0x8FD6, [13795] = 0x8FD5, [13796] = 0x8FD7, ++ [13797] = 0x90B2, [13798] = 0x90B4, [13799] = 0x90AF, [13800] = 0x90B3, ++ [13801] = 0x90B0, [13802] = 0x9639, [13803] = 0x963D, [13804] = 0x963C, ++ [13805] = 0x963A, [13806] = 0x9643, [13807] = 0x4FCD, [13808] = 0x4FC5, ++ [13809] = 0x4FD3, [13810] = 0x4FB2, [13811] = 0x4FC9, [13812] = 0x4FCB, ++ [13813] = 0x4FC1, [13814] = 0x4FD4, [13815] = 0x4FDC, [13816] = 0x4FD9, ++ [13817] = 0x4FBB, [13818] = 0x4FB3, [13819] = 0x4FDB, [13820] = 0x4FC7, ++ [13821] = 0x4FD6, [13822] = 0x4FBA, [13823] = 0x4FC0, [13824] = 0x4FB9, ++ [13825] = 0x4FEC, [13826] = 0x5244, [13827] = 0x5249, [13828] = 0x52C0, ++ [13829] = 0x52C2, [13830] = 0x533D, [13831] = 0x537C, [13832] = 0x5397, ++ [13833] = 0x5396, [13834] = 0x5399, [13835] = 0x5398, [13836] = 0x54BA, ++ [13837] = 0x54A1, [13838] = 0x54AD, [13839] = 0x54A5, [13840] = 0x54CF, ++ [13845] = 0x54C3, [13846] = 0x830D, [13847] = 0x54B7, [13848] = 0x54AE, ++ [13849] = 0x54D6, [13850] = 0x54B6, [13851] = 0x54C5, [13852] = 0x54C6, ++ [13853] = 0x54A0, [13854] = 0x5470, [13855] = 0x54BC, [13856] = 0x54A2, ++ [13857] = 0x54BE, [13858] = 0x5472, [13859] = 0x54DE, [13860] = 0x54B0, ++ [13861] = 0x57B5, [13862] = 0x579E, [13863] = 0x579F, [13864] = 0x57A4, ++ [13865] = 0x578C, [13866] = 0x5797, [13867] = 0x579D, [13868] = 0x579B, ++ [13869] = 0x5794, [13870] = 0x5798, [13871] = 0x578F, [13872] = 0x5799, ++ [13873] = 0x57A5, [13874] = 0x579A, [13875] = 0x5795, [13876] = 0x58F4, ++ [13877] = 0x590D, [13878] = 0x5953, [13879] = 0x59E1, [13880] = 0x59DE, ++ [13881] = 0x59EE, [13882] = 0x5A00, [13883] = 0x59F1, [13884] = 0x59DD, ++ [13885] = 0x59FA, [13886] = 0x59FD, [13887] = 0x59FC, [13888] = 0x59F6, ++ [13889] = 0x59E4, [13890] = 0x59F2, [13891] = 0x59F7, [13892] = 0x59DB, ++ [13893] = 0x59E9, [13894] = 0x59F3, [13895] = 0x59F5, [13896] = 0x59E0, ++ [13897] = 0x59FE, [13898] = 0x59F4, [13899] = 0x59ED, [13900] = 0x5BA8, ++ [13901] = 0x5C4C, [13902] = 0x5CD0, [13903] = 0x5CD8, [13904] = 0x5CCC, ++ [13905] = 0x5CD7, [13906] = 0x5CCB, [13907] = 0x5CDB, [13942] = 0x5CDE, ++ [13943] = 0x5CDA, [13944] = 0x5CC9, [13945] = 0x5CC7, [13946] = 0x5CCA, ++ [13947] = 0x5CD6, [13948] = 0x5CD3, [13949] = 0x5CD4, [13950] = 0x5CCF, ++ [13951] = 0x5CC8, [13952] = 0x5CC6, [13953] = 0x5CCE, [13954] = 0x5CDF, ++ [13955] = 0x5CF8, [13956] = 0x5DF9, [13957] = 0x5E21, [13958] = 0x5E22, ++ [13959] = 0x5E23, [13960] = 0x5E20, [13961] = 0x5E24, [13962] = 0x5EB0, ++ [13963] = 0x5EA4, [13964] = 0x5EA2, [13965] = 0x5E9B, [13966] = 0x5EA3, ++ [13967] = 0x5EA5, [13968] = 0x5F07, [13969] = 0x5F2E, [13970] = 0x5F56, ++ [13971] = 0x5F86, [13972] = 0x6037, [13973] = 0x6039, [13974] = 0x6054, ++ [13975] = 0x6072, [13976] = 0x605E, [13977] = 0x6045, [13978] = 0x6053, ++ [13979] = 0x6047, [13980] = 0x6049, [13981] = 0x605B, [13982] = 0x604C, ++ [13983] = 0x6040, [13984] = 0x6042, [13985] = 0x605F, [13986] = 0x6024, ++ [13987] = 0x6044, [13988] = 0x6058, [13989] = 0x6066, [13990] = 0x606E, ++ [13991] = 0x6242, [13992] = 0x6243, [13993] = 0x62CF, [13994] = 0x630D, ++ [13995] = 0x630B, [13996] = 0x62F5, [13997] = 0x630E, [13998] = 0x6303, ++ [13999] = 0x62EB, [14000] = 0x62F9, [14001] = 0x630F, [14002] = 0x630C, ++ [14003] = 0x62F8, [14004] = 0x62F6, [14005] = 0x6300, [14006] = 0x6313, ++ [14007] = 0x6314, [14008] = 0x62FA, [14009] = 0x6315, [14010] = 0x62FB, ++ [14011] = 0x62F0, [14012] = 0x6541, [14013] = 0x6543, [14014] = 0x65AA, ++ [14015] = 0x65BF, [14016] = 0x6636, [14017] = 0x6621, [14018] = 0x6632, ++ [14019] = 0x6635, [14020] = 0x661C, [14021] = 0x6626, [14022] = 0x6622, ++ [14023] = 0x6633, [14024] = 0x662B, [14025] = 0x663A, [14026] = 0x661D, ++ [14027] = 0x6634, [14028] = 0x6639, [14029] = 0x662E, [14030] = 0x670F, ++ [14031] = 0x6710, [14032] = 0x67C1, [14033] = 0x67F2, [14034] = 0x67C8, ++ [14035] = 0x67BA, [14040] = 0x67DC, [14041] = 0x67BB, [14042] = 0x67F8, ++ [14043] = 0x67D8, [14044] = 0x67C0, [14045] = 0x67B7, [14046] = 0x67C5, ++ [14047] = 0x67EB, [14048] = 0x67E4, [14049] = 0x67DF, [14050] = 0x67B5, ++ [14051] = 0x67CD, [14052] = 0x67B3, [14053] = 0x67F7, [14054] = 0x67F6, ++ [14055] = 0x67EE, [14056] = 0x67E3, [14057] = 0x67C2, [14058] = 0x67B9, ++ [14059] = 0x67CE, [14060] = 0x67E7, [14061] = 0x67F0, [14062] = 0x67B2, ++ [14063] = 0x67FC, [14064] = 0x67C6, [14065] = 0x67ED, [14066] = 0x67CC, ++ [14067] = 0x67AE, [14068] = 0x67E6, [14069] = 0x67DB, [14070] = 0x67FA, ++ [14071] = 0x67C9, [14072] = 0x67CA, [14073] = 0x67C3, [14074] = 0x67EA, ++ [14075] = 0x67CB, [14076] = 0x6B28, [14077] = 0x6B82, [14078] = 0x6B84, ++ [14079] = 0x6BB6, [14080] = 0x6BD6, [14081] = 0x6BD8, [14082] = 0x6BE0, ++ [14083] = 0x6C20, [14084] = 0x6C21, [14085] = 0x6D28, [14086] = 0x6D34, ++ [14087] = 0x6D2D, [14088] = 0x6D1F, [14089] = 0x6D3C, [14090] = 0x6D3F, ++ [14091] = 0x6D12, [14092] = 0x6D0A, [14093] = 0x6CDA, [14094] = 0x6D33, ++ [14095] = 0x6D04, [14096] = 0x6D19, [14097] = 0x6D3A, [14098] = 0x6D1A, ++ [14099] = 0x6D11, [14100] = 0x6D00, [14101] = 0x6D1D, [14102] = 0x6D42, ++ [14137] = 0x6D01, [14138] = 0x6D18, [14139] = 0x6D37, [14140] = 0x6D03, ++ [14141] = 0x6D0F, [14142] = 0x6D40, [14143] = 0x6D07, [14144] = 0x6D20, ++ [14145] = 0x6D2C, [14146] = 0x6D08, [14147] = 0x6D22, [14148] = 0x6D09, ++ [14149] = 0x6D10, [14150] = 0x70B7, [14151] = 0x709F, [14152] = 0x70BE, ++ [14153] = 0x70B1, [14154] = 0x70B0, [14155] = 0x70A1, [14156] = 0x70B4, ++ [14157] = 0x70B5, [14158] = 0x70A9, [14159] = 0x7241, [14160] = 0x7249, ++ [14161] = 0x724A, [14162] = 0x726C, [14163] = 0x7270, [14164] = 0x7273, ++ [14165] = 0x726E, [14166] = 0x72CA, [14167] = 0x72E4, [14168] = 0x72E8, ++ [14169] = 0x72EB, [14170] = 0x72DF, [14171] = 0x72EA, [14172] = 0x72E6, ++ [14173] = 0x72E3, [14174] = 0x7385, [14175] = 0x73CC, [14176] = 0x73C2, ++ [14177] = 0x73C8, [14178] = 0x73C5, [14179] = 0x73B9, [14180] = 0x73B6, ++ [14181] = 0x73B5, [14182] = 0x73B4, [14183] = 0x73EB, [14184] = 0x73BF, ++ [14185] = 0x73C7, [14186] = 0x73BE, [14187] = 0x73C3, [14188] = 0x73C6, ++ [14189] = 0x73B8, [14190] = 0x73CB, [14191] = 0x74EC, [14192] = 0x74EE, ++ [14193] = 0x752E, [14194] = 0x7547, [14195] = 0x7548, [14196] = 0x75A7, ++ [14197] = 0x75AA, [14198] = 0x7679, [14199] = 0x76C4, [14200] = 0x7708, ++ [14201] = 0x7703, [14202] = 0x7704, [14203] = 0x7705, [14204] = 0x770A, ++ [14205] = 0x76F7, [14206] = 0x76FB, [14207] = 0x76FA, [14208] = 0x77E7, ++ [14209] = 0x77E8, [14210] = 0x7806, [14211] = 0x7811, [14212] = 0x7812, ++ [14213] = 0x7805, [14214] = 0x7810, [14215] = 0x780F, [14216] = 0x780E, ++ [14217] = 0x7809, [14218] = 0x7803, [14219] = 0x7813, [14220] = 0x794A, ++ [14221] = 0x794C, [14222] = 0x794B, [14223] = 0x7945, [14224] = 0x7944, ++ [14225] = 0x79D5, [14226] = 0x79CD, [14227] = 0x79CF, [14228] = 0x79D6, ++ [14229] = 0x79CE, [14230] = 0x7A80, [14235] = 0x7A7E, [14236] = 0x7AD1, ++ [14237] = 0x7B00, [14238] = 0x7B01, [14239] = 0x7C7A, [14240] = 0x7C78, ++ [14241] = 0x7C79, [14242] = 0x7C7F, [14243] = 0x7C80, [14244] = 0x7C81, ++ [14245] = 0x7D03, [14246] = 0x7D08, [14247] = 0x7D01, [14248] = 0x7F58, ++ [14249] = 0x7F91, [14250] = 0x7F8D, [14251] = 0x7FBE, [14252] = 0x8007, ++ [14253] = 0x800E, [14254] = 0x800F, [14255] = 0x8014, [14256] = 0x8037, ++ [14257] = 0x80D8, [14258] = 0x80C7, [14259] = 0x80E0, [14260] = 0x80D1, ++ [14261] = 0x80C8, [14262] = 0x80C2, [14263] = 0x80D0, [14264] = 0x80C5, ++ [14265] = 0x80E3, [14266] = 0x80D9, [14267] = 0x80DC, [14268] = 0x80CA, ++ [14269] = 0x80D5, [14270] = 0x80C9, [14271] = 0x80CF, [14272] = 0x80D7, ++ [14273] = 0x80E6, [14274] = 0x80CD, [14275] = 0x81FF, [14276] = 0x8221, ++ [14277] = 0x8294, [14278] = 0x82D9, [14279] = 0x82FE, [14280] = 0x82F9, ++ [14281] = 0x8307, [14282] = 0x82E8, [14283] = 0x8300, [14284] = 0x82D5, ++ [14285] = 0x833A, [14286] = 0x82EB, [14287] = 0x82D6, [14288] = 0x82F4, ++ [14289] = 0x82EC, [14290] = 0x82E1, [14291] = 0x82F2, [14292] = 0x82F5, ++ [14293] = 0x830C, [14294] = 0x82FB, [14295] = 0x82F6, [14296] = 0x82F0, ++ [14297] = 0x82EA, [14332] = 0x82E4, [14333] = 0x82E0, [14334] = 0x82FA, ++ [14335] = 0x82F3, [14336] = 0x82ED, [14337] = 0x8677, [14338] = 0x8674, ++ [14339] = 0x867C, [14340] = 0x8673, [14341] = 0x8841, [14342] = 0x884E, ++ [14343] = 0x8867, [14344] = 0x886A, [14345] = 0x8869, [14346] = 0x89D3, ++ [14347] = 0x8A04, [14348] = 0x8A07, [14349] = 0x8D72, [14350] = 0x8FE3, ++ [14351] = 0x8FE1, [14352] = 0x8FEE, [14353] = 0x8FE0, [14354] = 0x90F1, ++ [14355] = 0x90BD, [14356] = 0x90BF, [14357] = 0x90D5, [14358] = 0x90C5, ++ [14359] = 0x90BE, [14360] = 0x90C7, [14361] = 0x90CB, [14362] = 0x90C8, ++ [14363] = 0x91D4, [14364] = 0x91D3, [14365] = 0x9654, [14366] = 0x964F, ++ [14367] = 0x9651, [14368] = 0x9653, [14369] = 0x964A, [14370] = 0x964E, ++ [14371] = 0x501E, [14372] = 0x5005, [14373] = 0x5007, [14374] = 0x5013, ++ [14375] = 0x5022, [14376] = 0x5030, [14377] = 0x501B, [14378] = 0x4FF5, ++ [14379] = 0x4FF4, [14380] = 0x5033, [14381] = 0x5037, [14382] = 0x502C, ++ [14383] = 0x4FF6, [14384] = 0x4FF7, [14385] = 0x5017, [14386] = 0x501C, ++ [14387] = 0x5020, [14388] = 0x5027, [14389] = 0x5035, [14390] = 0x502F, ++ [14391] = 0x5031, [14392] = 0x500E, [14393] = 0x515A, [14394] = 0x5194, ++ [14395] = 0x5193, [14396] = 0x51CA, [14397] = 0x51C4, [14398] = 0x51C5, ++ [14399] = 0x51C8, [14400] = 0x51CE, [14401] = 0x5261, [14402] = 0x525A, ++ [14403] = 0x5252, [14404] = 0x525E, [14405] = 0x525F, [14406] = 0x5255, ++ [14407] = 0x5262, [14408] = 0x52CD, [14409] = 0x530E, [14410] = 0x539E, ++ [14411] = 0x5526, [14412] = 0x54E2, [14413] = 0x5517, [14414] = 0x5512, ++ [14415] = 0x54E7, [14416] = 0x54F3, [14417] = 0x54E4, [14418] = 0x551A, ++ [14419] = 0x54FF, [14420] = 0x5504, [14421] = 0x5508, [14422] = 0x54EB, ++ [14423] = 0x5511, [14424] = 0x5505, [14425] = 0x54F1, [14430] = 0x550A, ++ [14431] = 0x54FB, [14432] = 0x54F7, [14433] = 0x54F8, [14434] = 0x54E0, ++ [14435] = 0x550E, [14436] = 0x5503, [14437] = 0x550B, [14438] = 0x5701, ++ [14439] = 0x5702, [14440] = 0x57CC, [14441] = 0x5832, [14442] = 0x57D5, ++ [14443] = 0x57D2, [14444] = 0x57BA, [14445] = 0x57C6, [14446] = 0x57BD, ++ [14447] = 0x57BC, [14448] = 0x57B8, [14449] = 0x57B6, [14450] = 0x57BF, ++ [14451] = 0x57C7, [14452] = 0x57D0, [14453] = 0x57B9, [14454] = 0x57C1, ++ [14455] = 0x590E, [14456] = 0x594A, [14457] = 0x5A19, [14458] = 0x5A16, ++ [14459] = 0x5A2D, [14460] = 0x5A2E, [14461] = 0x5A15, [14462] = 0x5A0F, ++ [14463] = 0x5A17, [14464] = 0x5A0A, [14465] = 0x5A1E, [14466] = 0x5A33, ++ [14467] = 0x5B6C, [14468] = 0x5BA7, [14469] = 0x5BAD, [14470] = 0x5BAC, ++ [14471] = 0x5C03, [14472] = 0x5C56, [14473] = 0x5C54, [14474] = 0x5CEC, ++ [14475] = 0x5CFF, [14476] = 0x5CEE, [14477] = 0x5CF1, [14478] = 0x5CF7, ++ [14479] = 0x5D00, [14480] = 0x5CF9, [14481] = 0x5E29, [14482] = 0x5E28, ++ [14483] = 0x5EA8, [14484] = 0x5EAE, [14485] = 0x5EAA, [14486] = 0x5EAC, ++ [14487] = 0x5F33, [14488] = 0x5F30, [14489] = 0x5F67, [14490] = 0x605D, ++ [14491] = 0x605A, [14492] = 0x6067, [14527] = 0x6041, [14528] = 0x60A2, ++ [14529] = 0x6088, [14530] = 0x6080, [14531] = 0x6092, [14532] = 0x6081, ++ [14533] = 0x609D, [14534] = 0x6083, [14535] = 0x6095, [14536] = 0x609B, ++ [14537] = 0x6097, [14538] = 0x6087, [14539] = 0x609C, [14540] = 0x608E, ++ [14541] = 0x6219, [14542] = 0x6246, [14543] = 0x62F2, [14544] = 0x6310, ++ [14545] = 0x6356, [14546] = 0x632C, [14547] = 0x6344, [14548] = 0x6345, ++ [14549] = 0x6336, [14550] = 0x6343, [14551] = 0x63E4, [14552] = 0x6339, ++ [14553] = 0x634B, [14554] = 0x634A, [14555] = 0x633C, [14556] = 0x6329, ++ [14557] = 0x6341, [14558] = 0x6334, [14559] = 0x6358, [14560] = 0x6354, ++ [14561] = 0x6359, [14562] = 0x632D, [14563] = 0x6347, [14564] = 0x6333, ++ [14565] = 0x635A, [14566] = 0x6351, [14567] = 0x6338, [14568] = 0x6357, ++ [14569] = 0x6340, [14570] = 0x6348, [14571] = 0x654A, [14572] = 0x6546, ++ [14573] = 0x65C6, [14574] = 0x65C3, [14575] = 0x65C4, [14576] = 0x65C2, ++ [14577] = 0x664A, [14578] = 0x665F, [14579] = 0x6647, [14580] = 0x6651, ++ [14581] = 0x6712, [14582] = 0x6713, [14583] = 0x681F, [14584] = 0x681A, ++ [14585] = 0x6849, [14586] = 0x6832, [14587] = 0x6833, [14588] = 0x683B, ++ [14589] = 0x684B, [14590] = 0x684F, [14591] = 0x6816, [14592] = 0x6831, ++ [14593] = 0x681C, [14594] = 0x6835, [14595] = 0x682B, [14596] = 0x682D, ++ [14597] = 0x682F, [14598] = 0x684E, [14599] = 0x6844, [14600] = 0x6834, ++ [14601] = 0x681D, [14602] = 0x6812, [14603] = 0x6814, [14604] = 0x6826, ++ [14605] = 0x6828, [14606] = 0x682E, [14607] = 0x684D, [14608] = 0x683A, ++ [14609] = 0x6825, [14610] = 0x6820, [14611] = 0x6B2C, [14612] = 0x6B2F, ++ [14613] = 0x6B2D, [14614] = 0x6B31, [14615] = 0x6B34, [14616] = 0x6B6D, ++ [14617] = 0x8082, [14618] = 0x6B88, [14619] = 0x6BE6, [14620] = 0x6BE4, ++ [14625] = 0x6BE8, [14626] = 0x6BE3, [14627] = 0x6BE2, [14628] = 0x6BE7, ++ [14629] = 0x6C25, [14630] = 0x6D7A, [14631] = 0x6D63, [14632] = 0x6D64, ++ [14633] = 0x6D76, [14634] = 0x6D0D, [14635] = 0x6D61, [14636] = 0x6D92, ++ [14637] = 0x6D58, [14638] = 0x6D62, [14639] = 0x6D6D, [14640] = 0x6D6F, ++ [14641] = 0x6D91, [14642] = 0x6D8D, [14643] = 0x6DEF, [14644] = 0x6D7F, ++ [14645] = 0x6D86, [14646] = 0x6D5E, [14647] = 0x6D67, [14648] = 0x6D60, ++ [14649] = 0x6D97, [14650] = 0x6D70, [14651] = 0x6D7C, [14652] = 0x6D5F, ++ [14653] = 0x6D82, [14654] = 0x6D98, [14655] = 0x6D2F, [14656] = 0x6D68, ++ [14657] = 0x6D8B, [14658] = 0x6D7E, [14659] = 0x6D80, [14660] = 0x6D84, ++ [14661] = 0x6D16, [14662] = 0x6D83, [14663] = 0x6D7B, [14664] = 0x6D7D, ++ [14665] = 0x6D75, [14666] = 0x6D90, [14667] = 0x70DC, [14668] = 0x70D3, ++ [14669] = 0x70D1, [14670] = 0x70DD, [14671] = 0x70CB, [14672] = 0x7F39, ++ [14673] = 0x70E2, [14674] = 0x70D7, [14675] = 0x70D2, [14676] = 0x70DE, ++ [14677] = 0x70E0, [14678] = 0x70D4, [14679] = 0x70CD, [14680] = 0x70C5, ++ [14681] = 0x70C6, [14682] = 0x70C7, [14683] = 0x70DA, [14684] = 0x70CE, ++ [14685] = 0x70E1, [14686] = 0x7242, [14687] = 0x7278, [14722] = 0x7277, ++ [14723] = 0x7276, [14724] = 0x7300, [14725] = 0x72FA, [14726] = 0x72F4, ++ [14727] = 0x72FE, [14728] = 0x72F6, [14729] = 0x72F3, [14730] = 0x72FB, ++ [14731] = 0x7301, [14732] = 0x73D3, [14733] = 0x73D9, [14734] = 0x73E5, ++ [14735] = 0x73D6, [14736] = 0x73BC, [14737] = 0x73E7, [14738] = 0x73E3, ++ [14739] = 0x73E9, [14740] = 0x73DC, [14741] = 0x73D2, [14742] = 0x73DB, ++ [14743] = 0x73D4, [14744] = 0x73DD, [14745] = 0x73DA, [14746] = 0x73D7, ++ [14747] = 0x73D8, [14748] = 0x73E8, [14749] = 0x74DE, [14750] = 0x74DF, ++ [14751] = 0x74F4, [14752] = 0x74F5, [14753] = 0x7521, [14754] = 0x755B, ++ [14755] = 0x755F, [14756] = 0x75B0, [14757] = 0x75C1, [14758] = 0x75BB, ++ [14759] = 0x75C4, [14760] = 0x75C0, [14761] = 0x75BF, [14762] = 0x75B6, ++ [14763] = 0x75BA, [14764] = 0x768A, [14765] = 0x76C9, [14766] = 0x771D, ++ [14767] = 0x771B, [14768] = 0x7710, [14769] = 0x7713, [14770] = 0x7712, ++ [14771] = 0x7723, [14772] = 0x7711, [14773] = 0x7715, [14774] = 0x7719, ++ [14775] = 0x771A, [14776] = 0x7722, [14777] = 0x7727, [14778] = 0x7823, ++ [14779] = 0x782C, [14780] = 0x7822, [14781] = 0x7835, [14782] = 0x782F, ++ [14783] = 0x7828, [14784] = 0x782E, [14785] = 0x782B, [14786] = 0x7821, ++ [14787] = 0x7829, [14788] = 0x7833, [14789] = 0x782A, [14790] = 0x7831, ++ [14791] = 0x7954, [14792] = 0x795B, [14793] = 0x794F, [14794] = 0x795C, ++ [14795] = 0x7953, [14796] = 0x7952, [14797] = 0x7951, [14798] = 0x79EB, ++ [14799] = 0x79EC, [14800] = 0x79E0, [14801] = 0x79EE, [14802] = 0x79ED, ++ [14803] = 0x79EA, [14804] = 0x79DC, [14805] = 0x79DE, [14806] = 0x79DD, ++ [14807] = 0x7A86, [14808] = 0x7A89, [14809] = 0x7A85, [14810] = 0x7A8B, ++ [14811] = 0x7A8C, [14812] = 0x7A8A, [14813] = 0x7A87, [14814] = 0x7AD8, ++ [14815] = 0x7B10, [14820] = 0x7B04, [14821] = 0x7B13, [14822] = 0x7B05, ++ [14823] = 0x7B0F, [14824] = 0x7B08, [14825] = 0x7B0A, [14826] = 0x7B0E, ++ [14827] = 0x7B09, [14828] = 0x7B12, [14829] = 0x7C84, [14830] = 0x7C91, ++ [14831] = 0x7C8A, [14832] = 0x7C8C, [14833] = 0x7C88, [14834] = 0x7C8D, ++ [14835] = 0x7C85, [14836] = 0x7D1E, [14837] = 0x7D1D, [14838] = 0x7D11, ++ [14839] = 0x7D0E, [14840] = 0x7D18, [14841] = 0x7D16, [14842] = 0x7D13, ++ [14843] = 0x7D1F, [14844] = 0x7D12, [14845] = 0x7D0F, [14846] = 0x7D0C, ++ [14847] = 0x7F5C, [14848] = 0x7F61, [14849] = 0x7F5E, [14850] = 0x7F60, ++ [14851] = 0x7F5D, [14852] = 0x7F5B, [14853] = 0x7F96, [14854] = 0x7F92, ++ [14855] = 0x7FC3, [14856] = 0x7FC2, [14857] = 0x7FC0, [14858] = 0x8016, ++ [14859] = 0x803E, [14860] = 0x8039, [14861] = 0x80FA, [14862] = 0x80F2, ++ [14863] = 0x80F9, [14864] = 0x80F5, [14865] = 0x8101, [14866] = 0x80FB, ++ [14867] = 0x8100, [14868] = 0x8201, [14869] = 0x822F, [14870] = 0x8225, ++ [14871] = 0x8333, [14872] = 0x832D, [14873] = 0x8344, [14874] = 0x8319, ++ [14875] = 0x8351, [14876] = 0x8325, [14877] = 0x8356, [14878] = 0x833F, ++ [14879] = 0x8341, [14880] = 0x8326, [14881] = 0x831C, [14882] = 0x8322, ++ [14917] = 0x8342, [14918] = 0x834E, [14919] = 0x831B, [14920] = 0x832A, ++ [14921] = 0x8308, [14922] = 0x833C, [14923] = 0x834D, [14924] = 0x8316, ++ [14925] = 0x8324, [14926] = 0x8320, [14927] = 0x8337, [14928] = 0x832F, ++ [14929] = 0x8329, [14930] = 0x8347, [14931] = 0x8345, [14932] = 0x834C, ++ [14933] = 0x8353, [14934] = 0x831E, [14935] = 0x832C, [14936] = 0x834B, ++ [14937] = 0x8327, [14938] = 0x8348, [14939] = 0x8653, [14940] = 0x8652, ++ [14941] = 0x86A2, [14942] = 0x86A8, [14943] = 0x8696, [14944] = 0x868D, ++ [14945] = 0x8691, [14946] = 0x869E, [14947] = 0x8687, [14948] = 0x8697, ++ [14949] = 0x8686, [14950] = 0x868B, [14951] = 0x869A, [14952] = 0x8685, ++ [14953] = 0x86A5, [14954] = 0x8699, [14955] = 0x86A1, [14956] = 0x86A7, ++ [14957] = 0x8695, [14958] = 0x8698, [14959] = 0x868E, [14960] = 0x869D, ++ [14961] = 0x8690, [14962] = 0x8694, [14963] = 0x8843, [14964] = 0x8844, ++ [14965] = 0x886D, [14966] = 0x8875, [14967] = 0x8876, [14968] = 0x8872, ++ [14969] = 0x8880, [14970] = 0x8871, [14971] = 0x887F, [14972] = 0x886F, ++ [14973] = 0x8883, [14974] = 0x887E, [14975] = 0x8874, [14976] = 0x887C, ++ [14977] = 0x8A12, [14978] = 0x8C47, [14979] = 0x8C57, [14980] = 0x8C7B, ++ [14981] = 0x8CA4, [14982] = 0x8CA3, [14983] = 0x8D76, [14984] = 0x8D78, ++ [14985] = 0x8DB5, [14986] = 0x8DB7, [14987] = 0x8DB6, [14988] = 0x8ED1, ++ [14989] = 0x8ED3, [14990] = 0x8FFE, [14991] = 0x8FF5, [14992] = 0x9002, ++ [14993] = 0x8FFF, [14994] = 0x8FFB, [14995] = 0x9004, [14996] = 0x8FFC, ++ [14997] = 0x8FF6, [14998] = 0x90D6, [14999] = 0x90E0, [15000] = 0x90D9, ++ [15001] = 0x90DA, [15002] = 0x90E3, [15003] = 0x90DF, [15004] = 0x90E5, ++ [15005] = 0x90D8, [15006] = 0x90DB, [15007] = 0x90D7, [15008] = 0x90DC, ++ [15009] = 0x90E4, [15010] = 0x9150, [15015] = 0x914E, [15016] = 0x914F, ++ [15017] = 0x91D5, [15018] = 0x91E2, [15019] = 0x91DA, [15020] = 0x965C, ++ [15021] = 0x965F, [15022] = 0x96BC, [15023] = 0x98E3, [15024] = 0x9ADF, ++ [15025] = 0x9B2F, [15026] = 0x4E7F, [15027] = 0x5070, [15028] = 0x506A, ++ [15029] = 0x5061, [15030] = 0x505E, [15031] = 0x5060, [15032] = 0x5053, ++ [15033] = 0x504B, [15034] = 0x505D, [15035] = 0x5072, [15036] = 0x5048, ++ [15037] = 0x504D, [15038] = 0x5041, [15039] = 0x505B, [15040] = 0x504A, ++ [15041] = 0x5062, [15042] = 0x5015, [15043] = 0x5045, [15044] = 0x505F, ++ [15045] = 0x5069, [15046] = 0x506B, [15047] = 0x5063, [15048] = 0x5064, ++ [15049] = 0x5046, [15050] = 0x5040, [15051] = 0x506E, [15052] = 0x5073, ++ [15053] = 0x5057, [15054] = 0x5051, [15055] = 0x51D0, [15056] = 0x526B, ++ [15057] = 0x526D, [15058] = 0x526C, [15059] = 0x526E, [15060] = 0x52D6, ++ [15061] = 0x52D3, [15062] = 0x532D, [15063] = 0x539C, [15064] = 0x5575, ++ [15065] = 0x5576, [15066] = 0x553C, [15067] = 0x554D, [15068] = 0x5550, ++ [15069] = 0x5534, [15070] = 0x552A, [15071] = 0x5551, [15072] = 0x5562, ++ [15073] = 0x5536, [15074] = 0x5535, [15075] = 0x5530, [15076] = 0x5552, ++ [15077] = 0x5545, [15112] = 0x550C, [15113] = 0x5532, [15114] = 0x5565, ++ [15115] = 0x554E, [15116] = 0x5539, [15117] = 0x5548, [15118] = 0x552D, ++ [15119] = 0x553B, [15120] = 0x5540, [15121] = 0x554B, [15122] = 0x570A, ++ [15123] = 0x5707, [15124] = 0x57FB, [15125] = 0x5814, [15126] = 0x57E2, ++ [15127] = 0x57F6, [15128] = 0x57DC, [15129] = 0x57F4, [15130] = 0x5800, ++ [15131] = 0x57ED, [15132] = 0x57FD, [15133] = 0x5808, [15134] = 0x57F8, ++ [15135] = 0x580B, [15136] = 0x57F3, [15137] = 0x57CF, [15138] = 0x5807, ++ [15139] = 0x57EE, [15140] = 0x57E3, [15141] = 0x57F2, [15142] = 0x57E5, ++ [15143] = 0x57EC, [15144] = 0x57E1, [15145] = 0x580E, [15146] = 0x57FC, ++ [15147] = 0x5810, [15148] = 0x57E7, [15149] = 0x5801, [15150] = 0x580C, ++ [15151] = 0x57F1, [15152] = 0x57E9, [15153] = 0x57F0, [15154] = 0x580D, ++ [15155] = 0x5804, [15156] = 0x595C, [15157] = 0x5A60, [15158] = 0x5A58, ++ [15159] = 0x5A55, [15160] = 0x5A67, [15161] = 0x5A5E, [15162] = 0x5A38, ++ [15163] = 0x5A35, [15164] = 0x5A6D, [15165] = 0x5A50, [15166] = 0x5A5F, ++ [15167] = 0x5A65, [15168] = 0x5A6C, [15169] = 0x5A53, [15170] = 0x5A64, ++ [15171] = 0x5A57, [15172] = 0x5A43, [15173] = 0x5A5D, [15174] = 0x5A52, ++ [15175] = 0x5A44, [15176] = 0x5A5B, [15177] = 0x5A48, [15178] = 0x5A8E, ++ [15179] = 0x5A3E, [15180] = 0x5A4D, [15181] = 0x5A39, [15182] = 0x5A4C, ++ [15183] = 0x5A70, [15184] = 0x5A69, [15185] = 0x5A47, [15186] = 0x5A51, ++ [15187] = 0x5A56, [15188] = 0x5A42, [15189] = 0x5A5C, [15190] = 0x5B72, ++ [15191] = 0x5B6E, [15192] = 0x5BC1, [15193] = 0x5BC0, [15194] = 0x5C59, ++ [15195] = 0x5D1E, [15196] = 0x5D0B, [15197] = 0x5D1D, [15198] = 0x5D1A, ++ [15199] = 0x5D20, [15200] = 0x5D0C, [15201] = 0x5D28, [15202] = 0x5D0D, ++ [15203] = 0x5D26, [15204] = 0x5D25, [15205] = 0x5D0F, [15210] = 0x5D30, ++ [15211] = 0x5D12, [15212] = 0x5D23, [15213] = 0x5D1F, [15214] = 0x5D2E, ++ [15215] = 0x5E3E, [15216] = 0x5E34, [15217] = 0x5EB1, [15218] = 0x5EB4, ++ [15219] = 0x5EB9, [15220] = 0x5EB2, [15221] = 0x5EB3, [15222] = 0x5F36, ++ [15223] = 0x5F38, [15224] = 0x5F9B, [15225] = 0x5F96, [15226] = 0x5F9F, ++ [15227] = 0x608A, [15228] = 0x6090, [15229] = 0x6086, [15230] = 0x60BE, ++ [15231] = 0x60B0, [15232] = 0x60BA, [15233] = 0x60D3, [15234] = 0x60D4, ++ [15235] = 0x60CF, [15236] = 0x60E4, [15237] = 0x60D9, [15238] = 0x60DD, ++ [15239] = 0x60C8, [15240] = 0x60B1, [15241] = 0x60DB, [15242] = 0x60B7, ++ [15243] = 0x60CA, [15244] = 0x60BF, [15245] = 0x60C3, [15246] = 0x60CD, ++ [15247] = 0x60C0, [15248] = 0x6332, [15249] = 0x6365, [15250] = 0x638A, ++ [15251] = 0x6382, [15252] = 0x637D, [15253] = 0x63BD, [15254] = 0x639E, ++ [15255] = 0x63AD, [15256] = 0x639D, [15257] = 0x6397, [15258] = 0x63AB, ++ [15259] = 0x638E, [15260] = 0x636F, [15261] = 0x6387, [15262] = 0x6390, ++ [15263] = 0x636E, [15264] = 0x63AF, [15265] = 0x6375, [15266] = 0x639C, ++ [15267] = 0x636D, [15268] = 0x63AE, [15269] = 0x637C, [15270] = 0x63A4, ++ [15271] = 0x633B, [15272] = 0x639F, [15307] = 0x6378, [15308] = 0x6385, ++ [15309] = 0x6381, [15310] = 0x6391, [15311] = 0x638D, [15312] = 0x6370, ++ [15313] = 0x6553, [15314] = 0x65CD, [15315] = 0x6665, [15316] = 0x6661, ++ [15317] = 0x665B, [15318] = 0x6659, [15319] = 0x665C, [15320] = 0x6662, ++ [15321] = 0x6718, [15322] = 0x6879, [15323] = 0x6887, [15324] = 0x6890, ++ [15325] = 0x689C, [15326] = 0x686D, [15327] = 0x686E, [15328] = 0x68AE, ++ [15329] = 0x68AB, [15330] = 0x6956, [15331] = 0x686F, [15332] = 0x68A3, ++ [15333] = 0x68AC, [15334] = 0x68A9, [15335] = 0x6875, [15336] = 0x6874, ++ [15337] = 0x68B2, [15338] = 0x688F, [15339] = 0x6877, [15340] = 0x6892, ++ [15341] = 0x687C, [15342] = 0x686B, [15343] = 0x6872, [15344] = 0x68AA, ++ [15345] = 0x6880, [15346] = 0x6871, [15347] = 0x687E, [15348] = 0x689B, ++ [15349] = 0x6896, [15350] = 0x688B, [15351] = 0x68A0, [15352] = 0x6889, ++ [15353] = 0x68A4, [15354] = 0x6878, [15355] = 0x687B, [15356] = 0x6891, ++ [15357] = 0x688C, [15358] = 0x688A, [15359] = 0x687D, [15360] = 0x6B36, ++ [15361] = 0x6B33, [15362] = 0x6B37, [15363] = 0x6B38, [15364] = 0x6B91, ++ [15365] = 0x6B8F, [15366] = 0x6B8D, [15367] = 0x6B8E, [15368] = 0x6B8C, ++ [15369] = 0x6C2A, [15370] = 0x6DC0, [15371] = 0x6DAB, [15372] = 0x6DB4, ++ [15373] = 0x6DB3, [15374] = 0x6E74, [15375] = 0x6DAC, [15376] = 0x6DE9, ++ [15377] = 0x6DE2, [15378] = 0x6DB7, [15379] = 0x6DF6, [15380] = 0x6DD4, ++ [15381] = 0x6E00, [15382] = 0x6DC8, [15383] = 0x6DE0, [15384] = 0x6DDF, ++ [15385] = 0x6DD6, [15386] = 0x6DBE, [15387] = 0x6DE5, [15388] = 0x6DDC, ++ [15389] = 0x6DDD, [15390] = 0x6DDB, [15391] = 0x6DF4, [15392] = 0x6DCA, ++ [15393] = 0x6DBD, [15394] = 0x6DED, [15395] = 0x6DF0, [15396] = 0x6DBA, ++ [15397] = 0x6DD5, [15398] = 0x6DC2, [15399] = 0x6DCF, [15400] = 0x6DC9, ++ [15405] = 0x6DD0, [15406] = 0x6DF2, [15407] = 0x6DD3, [15408] = 0x6DFD, ++ [15409] = 0x6DD7, [15410] = 0x6DCD, [15411] = 0x6DE3, [15412] = 0x6DBB, ++ [15413] = 0x70FA, [15414] = 0x710D, [15415] = 0x70F7, [15416] = 0x7117, ++ [15417] = 0x70F4, [15418] = 0x710C, [15419] = 0x70F0, [15420] = 0x7104, ++ [15421] = 0x70F3, [15422] = 0x7110, [15423] = 0x70FC, [15424] = 0x70FF, ++ [15425] = 0x7106, [15426] = 0x7113, [15427] = 0x7100, [15428] = 0x70F8, ++ [15429] = 0x70F6, [15430] = 0x710B, [15431] = 0x7102, [15432] = 0x710E, ++ [15433] = 0x727E, [15434] = 0x727B, [15435] = 0x727C, [15436] = 0x727F, ++ [15437] = 0x731D, [15438] = 0x7317, [15439] = 0x7307, [15440] = 0x7311, ++ [15441] = 0x7318, [15442] = 0x730A, [15443] = 0x7308, [15444] = 0x72FF, ++ [15445] = 0x730F, [15446] = 0x731E, [15447] = 0x7388, [15448] = 0x73F6, ++ [15449] = 0x73F8, [15450] = 0x73F5, [15451] = 0x7404, [15452] = 0x7401, ++ [15453] = 0x73FD, [15454] = 0x7407, [15455] = 0x7400, [15456] = 0x73FA, ++ [15457] = 0x73FC, [15458] = 0x73FF, [15459] = 0x740C, [15460] = 0x740B, ++ [15461] = 0x73F4, [15462] = 0x7408, [15463] = 0x7564, [15464] = 0x7563, ++ [15465] = 0x75CE, [15466] = 0x75D2, [15467] = 0x75CF, [15502] = 0x75CB, ++ [15503] = 0x75CC, [15504] = 0x75D1, [15505] = 0x75D0, [15506] = 0x768F, ++ [15507] = 0x7689, [15508] = 0x76D3, [15509] = 0x7739, [15510] = 0x772F, ++ [15511] = 0x772D, [15512] = 0x7731, [15513] = 0x7732, [15514] = 0x7734, ++ [15515] = 0x7733, [15516] = 0x773D, [15517] = 0x7725, [15518] = 0x773B, ++ [15519] = 0x7735, [15520] = 0x7848, [15521] = 0x7852, [15522] = 0x7849, ++ [15523] = 0x784D, [15524] = 0x784A, [15525] = 0x784C, [15526] = 0x7826, ++ [15527] = 0x7845, [15528] = 0x7850, [15529] = 0x7964, [15530] = 0x7967, ++ [15531] = 0x7969, [15532] = 0x796A, [15533] = 0x7963, [15534] = 0x796B, ++ [15535] = 0x7961, [15536] = 0x79BB, [15537] = 0x79FA, [15538] = 0x79F8, ++ [15539] = 0x79F6, [15540] = 0x79F7, [15541] = 0x7A8F, [15542] = 0x7A94, ++ [15543] = 0x7A90, [15544] = 0x7B35, [15545] = 0x7B47, [15546] = 0x7B34, ++ [15547] = 0x7B25, [15548] = 0x7B30, [15549] = 0x7B22, [15550] = 0x7B24, ++ [15551] = 0x7B33, [15552] = 0x7B18, [15553] = 0x7B2A, [15554] = 0x7B1D, ++ [15555] = 0x7B31, [15556] = 0x7B2B, [15557] = 0x7B2D, [15558] = 0x7B2F, ++ [15559] = 0x7B32, [15560] = 0x7B38, [15561] = 0x7B1A, [15562] = 0x7B23, ++ [15563] = 0x7C94, [15564] = 0x7C98, [15565] = 0x7C96, [15566] = 0x7CA3, ++ [15567] = 0x7D35, [15568] = 0x7D3D, [15569] = 0x7D38, [15570] = 0x7D36, ++ [15571] = 0x7D3A, [15572] = 0x7D45, [15573] = 0x7D2C, [15574] = 0x7D29, ++ [15575] = 0x7D41, [15576] = 0x7D47, [15577] = 0x7D3E, [15578] = 0x7D3F, ++ [15579] = 0x7D4A, [15580] = 0x7D3B, [15581] = 0x7D28, [15582] = 0x7F63, ++ [15583] = 0x7F95, [15584] = 0x7F9C, [15585] = 0x7F9D, [15586] = 0x7F9B, ++ [15587] = 0x7FCA, [15588] = 0x7FCB, [15589] = 0x7FCD, [15590] = 0x7FD0, ++ [15591] = 0x7FD1, [15592] = 0x7FC7, [15593] = 0x7FCF, [15594] = 0x7FC9, ++ [15595] = 0x801F, [15600] = 0x801E, [15601] = 0x801B, [15602] = 0x8047, ++ [15603] = 0x8043, [15604] = 0x8048, [15605] = 0x8118, [15606] = 0x8125, ++ [15607] = 0x8119, [15608] = 0x811B, [15609] = 0x812D, [15610] = 0x811F, ++ [15611] = 0x812C, [15612] = 0x811E, [15613] = 0x8121, [15614] = 0x8115, ++ [15615] = 0x8127, [15616] = 0x811D, [15617] = 0x8122, [15618] = 0x8211, ++ [15619] = 0x8238, [15620] = 0x8233, [15621] = 0x823A, [15622] = 0x8234, ++ [15623] = 0x8232, [15624] = 0x8274, [15625] = 0x8390, [15626] = 0x83A3, ++ [15627] = 0x83A8, [15628] = 0x838D, [15629] = 0x837A, [15630] = 0x8373, ++ [15631] = 0x83A4, [15632] = 0x8374, [15633] = 0x838F, [15634] = 0x8381, ++ [15635] = 0x8395, [15636] = 0x8399, [15637] = 0x8375, [15638] = 0x8394, ++ [15639] = 0x83A9, [15640] = 0x837D, [15641] = 0x8383, [15642] = 0x838C, ++ [15643] = 0x839D, [15644] = 0x839B, [15645] = 0x83AA, [15646] = 0x838B, ++ [15647] = 0x837E, [15648] = 0x83A5, [15649] = 0x83AF, [15650] = 0x8388, ++ [15651] = 0x8397, [15652] = 0x83B0, [15653] = 0x837F, [15654] = 0x83A6, ++ [15655] = 0x8387, [15656] = 0x83AE, [15657] = 0x8376, [15658] = 0x839A, ++ [15659] = 0x8659, [15660] = 0x8656, [15661] = 0x86BF, [15662] = 0x86B7, ++ [15697] = 0x86C2, [15698] = 0x86C1, [15699] = 0x86C5, [15700] = 0x86BA, ++ [15701] = 0x86B0, [15702] = 0x86C8, [15703] = 0x86B9, [15704] = 0x86B3, ++ [15705] = 0x86B8, [15706] = 0x86CC, [15707] = 0x86B4, [15708] = 0x86BB, ++ [15709] = 0x86BC, [15710] = 0x86C3, [15711] = 0x86BD, [15712] = 0x86BE, ++ [15713] = 0x8852, [15714] = 0x8889, [15715] = 0x8895, [15716] = 0x88A8, ++ [15717] = 0x88A2, [15718] = 0x88AA, [15719] = 0x889A, [15720] = 0x8891, ++ [15721] = 0x88A1, [15722] = 0x889F, [15723] = 0x8898, [15724] = 0x88A7, ++ [15725] = 0x8899, [15726] = 0x889B, [15727] = 0x8897, [15728] = 0x88A4, ++ [15729] = 0x88AC, [15730] = 0x888C, [15731] = 0x8893, [15732] = 0x888E, ++ [15733] = 0x8982, [15734] = 0x89D6, [15735] = 0x89D9, [15736] = 0x89D5, ++ [15737] = 0x8A30, [15738] = 0x8A27, [15739] = 0x8A2C, [15740] = 0x8A1E, ++ [15741] = 0x8C39, [15742] = 0x8C3B, [15743] = 0x8C5C, [15744] = 0x8C5D, ++ [15745] = 0x8C7D, [15746] = 0x8CA5, [15747] = 0x8D7D, [15748] = 0x8D7B, ++ [15749] = 0x8D79, [15750] = 0x8DBC, [15751] = 0x8DC2, [15752] = 0x8DB9, ++ [15753] = 0x8DBF, [15754] = 0x8DC1, [15755] = 0x8ED8, [15756] = 0x8EDE, ++ [15757] = 0x8EDD, [15758] = 0x8EDC, [15759] = 0x8ED7, [15760] = 0x8EE0, ++ [15761] = 0x8EE1, [15762] = 0x9024, [15763] = 0x900B, [15764] = 0x9011, ++ [15765] = 0x901C, [15766] = 0x900C, [15767] = 0x9021, [15768] = 0x90EF, ++ [15769] = 0x90EA, [15770] = 0x90F0, [15771] = 0x90F4, [15772] = 0x90F2, ++ [15773] = 0x90F3, [15774] = 0x90D4, [15775] = 0x90EB, [15776] = 0x90EC, ++ [15777] = 0x90E9, [15778] = 0x9156, [15779] = 0x9158, [15780] = 0x915A, ++ [15781] = 0x9153, [15782] = 0x9155, [15783] = 0x91EC, [15784] = 0x91F4, ++ [15785] = 0x91F1, [15786] = 0x91F3, [15787] = 0x91F8, [15788] = 0x91E4, ++ [15789] = 0x91F9, [15790] = 0x91EA, [15795] = 0x91EB, [15796] = 0x91F7, ++ [15797] = 0x91E8, [15798] = 0x91EE, [15799] = 0x957A, [15800] = 0x9586, ++ [15801] = 0x9588, [15802] = 0x967C, [15803] = 0x966D, [15804] = 0x966B, ++ [15805] = 0x9671, [15806] = 0x966F, [15807] = 0x96BF, [15808] = 0x976A, ++ [15809] = 0x9804, [15810] = 0x98E5, [15811] = 0x9997, [15812] = 0x509B, ++ [15813] = 0x5095, [15814] = 0x5094, [15815] = 0x509E, [15816] = 0x508B, ++ [15817] = 0x50A3, [15818] = 0x5083, [15819] = 0x508C, [15820] = 0x508E, ++ [15821] = 0x509D, [15822] = 0x5068, [15823] = 0x509C, [15824] = 0x5092, ++ [15825] = 0x5082, [15826] = 0x5087, [15827] = 0x515F, [15828] = 0x51D4, ++ [15829] = 0x5312, [15830] = 0x5311, [15831] = 0x53A4, [15832] = 0x53A7, ++ [15833] = 0x5591, [15834] = 0x55A8, [15835] = 0x55A5, [15836] = 0x55AD, ++ [15837] = 0x5577, [15838] = 0x5645, [15839] = 0x55A2, [15840] = 0x5593, ++ [15841] = 0x5588, [15842] = 0x558F, [15843] = 0x55B5, [15844] = 0x5581, ++ [15845] = 0x55A3, [15846] = 0x5592, [15847] = 0x55A4, [15848] = 0x557D, ++ [15849] = 0x558C, [15850] = 0x55A6, [15851] = 0x557F, [15852] = 0x5595, ++ [15853] = 0x55A1, [15854] = 0x558E, [15855] = 0x570C, [15856] = 0x5829, ++ [15857] = 0x5837, [15892] = 0x5819, [15893] = 0x581E, [15894] = 0x5827, ++ [15895] = 0x5823, [15896] = 0x5828, [15897] = 0x57F5, [15898] = 0x5848, ++ [15899] = 0x5825, [15900] = 0x581C, [15901] = 0x581B, [15902] = 0x5833, ++ [15903] = 0x583F, [15904] = 0x5836, [15905] = 0x582E, [15906] = 0x5839, ++ [15907] = 0x5838, [15908] = 0x582D, [15909] = 0x582C, [15910] = 0x583B, ++ [15911] = 0x5961, [15912] = 0x5AAF, [15913] = 0x5A94, [15914] = 0x5A9F, ++ [15915] = 0x5A7A, [15916] = 0x5AA2, [15917] = 0x5A9E, [15918] = 0x5A78, ++ [15919] = 0x5AA6, [15920] = 0x5A7C, [15921] = 0x5AA5, [15922] = 0x5AAC, ++ [15923] = 0x5A95, [15924] = 0x5AAE, [15925] = 0x5A37, [15926] = 0x5A84, ++ [15927] = 0x5A8A, [15928] = 0x5A97, [15929] = 0x5A83, [15930] = 0x5A8B, ++ [15931] = 0x5AA9, [15932] = 0x5A7B, [15933] = 0x5A7D, [15934] = 0x5A8C, ++ [15935] = 0x5A9C, [15936] = 0x5A8F, [15937] = 0x5A93, [15938] = 0x5A9D, ++ [15939] = 0x5BEA, [15940] = 0x5BCD, [15941] = 0x5BCB, [15942] = 0x5BD4, ++ [15943] = 0x5BD1, [15944] = 0x5BCA, [15945] = 0x5BCE, [15946] = 0x5C0C, ++ [15947] = 0x5C30, [15948] = 0x5D37, [15949] = 0x5D43, [15950] = 0x5D6B, ++ [15951] = 0x5D41, [15952] = 0x5D4B, [15953] = 0x5D3F, [15954] = 0x5D35, ++ [15955] = 0x5D51, [15956] = 0x5D4E, [15957] = 0x5D55, [15958] = 0x5D33, ++ [15959] = 0x5D3A, [15960] = 0x5D52, [15961] = 0x5D3D, [15962] = 0x5D31, ++ [15963] = 0x5D59, [15964] = 0x5D42, [15965] = 0x5D39, [15966] = 0x5D49, ++ [15967] = 0x5D38, [15968] = 0x5D3C, [15969] = 0x5D32, [15970] = 0x5D36, ++ [15971] = 0x5D40, [15972] = 0x5D45, [15973] = 0x5E44, [15974] = 0x5E41, ++ [15975] = 0x5F58, [15976] = 0x5FA6, [15977] = 0x5FA5, [15978] = 0x5FAB, ++ [15979] = 0x60C9, [15980] = 0x60B9, [15981] = 0x60CC, [15982] = 0x60E2, ++ [15983] = 0x60CE, [15984] = 0x60C4, [15985] = 0x6114, [15990] = 0x60F2, ++ [15991] = 0x610A, [15992] = 0x6116, [15993] = 0x6105, [15994] = 0x60F5, ++ [15995] = 0x6113, [15996] = 0x60F8, [15997] = 0x60FC, [15998] = 0x60FE, ++ [15999] = 0x60C1, [16000] = 0x6103, [16001] = 0x6118, [16002] = 0x611D, ++ [16003] = 0x6110, [16004] = 0x60FF, [16005] = 0x6104, [16006] = 0x610B, ++ [16007] = 0x624A, [16008] = 0x6394, [16009] = 0x63B1, [16010] = 0x63B0, ++ [16011] = 0x63CE, [16012] = 0x63E5, [16013] = 0x63E8, [16014] = 0x63EF, ++ [16015] = 0x63C3, [16016] = 0x649D, [16017] = 0x63F3, [16018] = 0x63CA, ++ [16019] = 0x63E0, [16020] = 0x63F6, [16021] = 0x63D5, [16022] = 0x63F2, ++ [16023] = 0x63F5, [16024] = 0x6461, [16025] = 0x63DF, [16026] = 0x63BE, ++ [16027] = 0x63DD, [16028] = 0x63DC, [16029] = 0x63C4, [16030] = 0x63D8, ++ [16031] = 0x63D3, [16032] = 0x63C2, [16033] = 0x63C7, [16034] = 0x63CC, ++ [16035] = 0x63CB, [16036] = 0x63C8, [16037] = 0x63F0, [16038] = 0x63D7, ++ [16039] = 0x63D9, [16040] = 0x6532, [16041] = 0x6567, [16042] = 0x656A, ++ [16043] = 0x6564, [16044] = 0x655C, [16045] = 0x6568, [16046] = 0x6565, ++ [16047] = 0x658C, [16048] = 0x659D, [16049] = 0x659E, [16050] = 0x65AE, ++ [16051] = 0x65D0, [16052] = 0x65D2, [16087] = 0x667C, [16088] = 0x666C, ++ [16089] = 0x667B, [16090] = 0x6680, [16091] = 0x6671, [16092] = 0x6679, ++ [16093] = 0x666A, [16094] = 0x6672, [16095] = 0x6701, [16096] = 0x690C, ++ [16097] = 0x68D3, [16098] = 0x6904, [16099] = 0x68DC, [16100] = 0x692A, ++ [16101] = 0x68EC, [16102] = 0x68EA, [16103] = 0x68F1, [16104] = 0x690F, ++ [16105] = 0x68D6, [16106] = 0x68F7, [16107] = 0x68EB, [16108] = 0x68E4, ++ [16109] = 0x68F6, [16110] = 0x6913, [16111] = 0x6910, [16112] = 0x68F3, ++ [16113] = 0x68E1, [16114] = 0x6907, [16115] = 0x68CC, [16116] = 0x6908, ++ [16117] = 0x6970, [16118] = 0x68B4, [16119] = 0x6911, [16120] = 0x68EF, ++ [16121] = 0x68C6, [16122] = 0x6914, [16123] = 0x68F8, [16124] = 0x68D0, ++ [16125] = 0x68FD, [16126] = 0x68FC, [16127] = 0x68E8, [16128] = 0x690B, ++ [16129] = 0x690A, [16130] = 0x6917, [16131] = 0x68CE, [16132] = 0x68C8, ++ [16133] = 0x68DD, [16134] = 0x68DE, [16135] = 0x68E6, [16136] = 0x68F4, ++ [16137] = 0x68D1, [16138] = 0x6906, [16139] = 0x68D4, [16140] = 0x68E9, ++ [16141] = 0x6915, [16142] = 0x6925, [16143] = 0x68C7, [16144] = 0x6B39, ++ [16145] = 0x6B3B, [16146] = 0x6B3F, [16147] = 0x6B3C, [16148] = 0x6B94, ++ [16149] = 0x6B97, [16150] = 0x6B99, [16151] = 0x6B95, [16152] = 0x6BBD, ++ [16153] = 0x6BF0, [16154] = 0x6BF2, [16155] = 0x6BF3, [16156] = 0x6C30, ++ [16157] = 0x6DFC, [16158] = 0x6E46, [16159] = 0x6E47, [16160] = 0x6E1F, ++ [16161] = 0x6E49, [16162] = 0x6E88, [16163] = 0x6E3C, [16164] = 0x6E3D, ++ [16165] = 0x6E45, [16166] = 0x6E62, [16167] = 0x6E2B, [16168] = 0x6E3F, ++ [16169] = 0x6E41, [16170] = 0x6E5D, [16171] = 0x6E73, [16172] = 0x6E1C, ++ [16173] = 0x6E33, [16174] = 0x6E4B, [16175] = 0x6E40, [16176] = 0x6E51, ++ [16177] = 0x6E3B, [16178] = 0x6E03, [16179] = 0x6E2E, [16180] = 0x6E5E, ++ [16185] = 0x6E68, [16186] = 0x6E5C, [16187] = 0x6E61, [16188] = 0x6E31, ++ [16189] = 0x6E28, [16190] = 0x6E60, [16191] = 0x6E71, [16192] = 0x6E6B, ++ [16193] = 0x6E39, [16194] = 0x6E22, [16195] = 0x6E30, [16196] = 0x6E53, ++ [16197] = 0x6E65, [16198] = 0x6E27, [16199] = 0x6E78, [16200] = 0x6E64, ++ [16201] = 0x6E77, [16202] = 0x6E55, [16203] = 0x6E79, [16204] = 0x6E52, ++ [16205] = 0x6E66, [16206] = 0x6E35, [16207] = 0x6E36, [16208] = 0x6E5A, ++ [16209] = 0x7120, [16210] = 0x711E, [16211] = 0x712F, [16212] = 0x70FB, ++ [16213] = 0x712E, [16214] = 0x7131, [16215] = 0x7123, [16216] = 0x7125, ++ [16217] = 0x7122, [16218] = 0x7132, [16219] = 0x711F, [16220] = 0x7128, ++ [16221] = 0x713A, [16222] = 0x711B, [16223] = 0x724B, [16224] = 0x725A, ++ [16225] = 0x7288, [16226] = 0x7289, [16227] = 0x7286, [16228] = 0x7285, ++ [16229] = 0x728B, [16230] = 0x7312, [16231] = 0x730B, [16232] = 0x7330, ++ [16233] = 0x7322, [16234] = 0x7331, [16235] = 0x7333, [16236] = 0x7327, ++ [16237] = 0x7332, [16238] = 0x732D, [16239] = 0x7326, [16240] = 0x7323, ++ [16241] = 0x7335, [16242] = 0x730C, [16243] = 0x742E, [16244] = 0x742C, ++ [16245] = 0x7430, [16246] = 0x742B, [16247] = 0x7416, [16282] = 0x741A, ++ [16283] = 0x7421, [16284] = 0x742D, [16285] = 0x7431, [16286] = 0x7424, ++ [16287] = 0x7423, [16288] = 0x741D, [16289] = 0x7429, [16290] = 0x7420, ++ [16291] = 0x7432, [16292] = 0x74FB, [16293] = 0x752F, [16294] = 0x756F, ++ [16295] = 0x756C, [16296] = 0x75E7, [16297] = 0x75DA, [16298] = 0x75E1, ++ [16299] = 0x75E6, [16300] = 0x75DD, [16301] = 0x75DF, [16302] = 0x75E4, ++ [16303] = 0x75D7, [16304] = 0x7695, [16305] = 0x7692, [16306] = 0x76DA, ++ [16307] = 0x7746, [16308] = 0x7747, [16309] = 0x7744, [16310] = 0x774D, ++ [16311] = 0x7745, [16312] = 0x774A, [16313] = 0x774E, [16314] = 0x774B, ++ [16315] = 0x774C, [16316] = 0x77DE, [16317] = 0x77EC, [16318] = 0x7860, ++ [16319] = 0x7864, [16320] = 0x7865, [16321] = 0x785C, [16322] = 0x786D, ++ [16323] = 0x7871, [16324] = 0x786A, [16325] = 0x786E, [16326] = 0x7870, ++ [16327] = 0x7869, [16328] = 0x7868, [16329] = 0x785E, [16330] = 0x7862, ++ [16331] = 0x7974, [16332] = 0x7973, [16333] = 0x7972, [16334] = 0x7970, ++ [16335] = 0x7A02, [16336] = 0x7A0A, [16337] = 0x7A03, [16338] = 0x7A0C, ++ [16339] = 0x7A04, [16340] = 0x7A99, [16341] = 0x7AE6, [16342] = 0x7AE4, ++ [16343] = 0x7B4A, [16344] = 0x7B3B, [16345] = 0x7B44, [16346] = 0x7B48, ++ [16347] = 0x7B4C, [16348] = 0x7B4E, [16349] = 0x7B40, [16350] = 0x7B58, ++ [16351] = 0x7B45, [16352] = 0x7CA2, [16353] = 0x7C9E, [16354] = 0x7CA8, ++ [16355] = 0x7CA1, [16356] = 0x7D58, [16357] = 0x7D6F, [16358] = 0x7D63, ++ [16359] = 0x7D53, [16360] = 0x7D56, [16361] = 0x7D67, [16362] = 0x7D6A, ++ [16363] = 0x7D4F, [16364] = 0x7D6D, [16365] = 0x7D5C, [16366] = 0x7D6B, ++ [16367] = 0x7D52, [16368] = 0x7D54, [16369] = 0x7D69, [16370] = 0x7D51, ++ [16371] = 0x7D5F, [16372] = 0x7D4E, [16373] = 0x7F3E, [16374] = 0x7F3F, ++ [16375] = 0x7F65, [16380] = 0x7F66, [16381] = 0x7FA2, [16382] = 0x7FA0, ++ [16383] = 0x7FA1, [16384] = 0x7FD7, [16385] = 0x8051, [16386] = 0x804F, ++ [16387] = 0x8050, [16388] = 0x80FE, [16389] = 0x80D4, [16390] = 0x8143, ++ [16391] = 0x814A, [16392] = 0x8152, [16393] = 0x814F, [16394] = 0x8147, ++ [16395] = 0x813D, [16396] = 0x814D, [16397] = 0x813A, [16398] = 0x81E6, ++ [16399] = 0x81EE, [16400] = 0x81F7, [16401] = 0x81F8, [16402] = 0x81F9, ++ [16403] = 0x8204, [16404] = 0x823C, [16405] = 0x823D, [16406] = 0x823F, ++ [16407] = 0x8275, [16408] = 0x833B, [16409] = 0x83CF, [16410] = 0x83F9, ++ [16411] = 0x8423, [16412] = 0x83C0, [16413] = 0x83E8, [16414] = 0x8412, ++ [16415] = 0x83E7, [16416] = 0x83E4, [16417] = 0x83FC, [16418] = 0x83F6, ++ [16419] = 0x8410, [16420] = 0x83C6, [16421] = 0x83C8, [16422] = 0x83EB, ++ [16423] = 0x83E3, [16424] = 0x83BF, [16425] = 0x8401, [16426] = 0x83DD, ++ [16427] = 0x83E5, [16428] = 0x83D8, [16429] = 0x83FF, [16430] = 0x83E1, ++ [16431] = 0x83CB, [16432] = 0x83CE, [16433] = 0x83D6, [16434] = 0x83F5, ++ [16435] = 0x83C9, [16436] = 0x8409, [16437] = 0x840F, [16438] = 0x83DE, ++ [16439] = 0x8411, [16440] = 0x8406, [16441] = 0x83C2, [16442] = 0x83F3, ++ [16477] = 0x83D5, [16478] = 0x83FA, [16479] = 0x83C7, [16480] = 0x83D1, ++ [16481] = 0x83EA, [16482] = 0x8413, [16483] = 0x83C3, [16484] = 0x83EC, ++ [16485] = 0x83EE, [16486] = 0x83C4, [16487] = 0x83FB, [16488] = 0x83D7, ++ [16489] = 0x83E2, [16490] = 0x841B, [16491] = 0x83DB, [16492] = 0x83FE, ++ [16493] = 0x86D8, [16494] = 0x86E2, [16495] = 0x86E6, [16496] = 0x86D3, ++ [16497] = 0x86E3, [16498] = 0x86DA, [16499] = 0x86EA, [16500] = 0x86DD, ++ [16501] = 0x86EB, [16502] = 0x86DC, [16503] = 0x86EC, [16504] = 0x86E9, ++ [16505] = 0x86D7, [16506] = 0x86E8, [16507] = 0x86D1, [16508] = 0x8848, ++ [16509] = 0x8856, [16510] = 0x8855, [16511] = 0x88BA, [16512] = 0x88D7, ++ [16513] = 0x88B9, [16514] = 0x88B8, [16515] = 0x88C0, [16516] = 0x88BE, ++ [16517] = 0x88B6, [16518] = 0x88BC, [16519] = 0x88B7, [16520] = 0x88BD, ++ [16521] = 0x88B2, [16522] = 0x8901, [16523] = 0x88C9, [16524] = 0x8995, ++ [16525] = 0x8998, [16526] = 0x8997, [16527] = 0x89DD, [16528] = 0x89DA, ++ [16529] = 0x89DB, [16530] = 0x8A4E, [16531] = 0x8A4D, [16532] = 0x8A39, ++ [16533] = 0x8A59, [16534] = 0x8A40, [16535] = 0x8A57, [16536] = 0x8A58, ++ [16537] = 0x8A44, [16538] = 0x8A45, [16539] = 0x8A52, [16540] = 0x8A48, ++ [16541] = 0x8A51, [16542] = 0x8A4A, [16543] = 0x8A4C, [16544] = 0x8A4F, ++ [16545] = 0x8C5F, [16546] = 0x8C81, [16547] = 0x8C80, [16548] = 0x8CBA, ++ [16549] = 0x8CBE, [16550] = 0x8CB0, [16551] = 0x8CB9, [16552] = 0x8CB5, ++ [16553] = 0x8D84, [16554] = 0x8D80, [16555] = 0x8D89, [16556] = 0x8DD8, ++ [16557] = 0x8DD3, [16558] = 0x8DCD, [16559] = 0x8DC7, [16560] = 0x8DD6, ++ [16561] = 0x8DDC, [16562] = 0x8DCF, [16563] = 0x8DD5, [16564] = 0x8DD9, ++ [16565] = 0x8DC8, [16566] = 0x8DD7, [16567] = 0x8DC5, [16568] = 0x8EEF, ++ [16569] = 0x8EF7, [16570] = 0x8EFA, [16575] = 0x8EF9, [16576] = 0x8EE6, ++ [16577] = 0x8EEE, [16578] = 0x8EE5, [16579] = 0x8EF5, [16580] = 0x8EE7, ++ [16581] = 0x8EE8, [16582] = 0x8EF6, [16583] = 0x8EEB, [16584] = 0x8EF1, ++ [16585] = 0x8EEC, [16586] = 0x8EF4, [16587] = 0x8EE9, [16588] = 0x902D, ++ [16589] = 0x9034, [16590] = 0x902F, [16591] = 0x9106, [16592] = 0x912C, ++ [16593] = 0x9104, [16594] = 0x90FF, [16595] = 0x90FC, [16596] = 0x9108, ++ [16597] = 0x90F9, [16598] = 0x90FB, [16599] = 0x9101, [16600] = 0x9100, ++ [16601] = 0x9107, [16602] = 0x9105, [16603] = 0x9103, [16604] = 0x9161, ++ [16605] = 0x9164, [16606] = 0x915F, [16607] = 0x9162, [16608] = 0x9160, ++ [16609] = 0x9201, [16610] = 0x920A, [16611] = 0x9225, [16612] = 0x9203, ++ [16613] = 0x921A, [16614] = 0x9226, [16615] = 0x920F, [16616] = 0x920C, ++ [16617] = 0x9200, [16618] = 0x9212, [16619] = 0x91FF, [16620] = 0x91FD, ++ [16621] = 0x9206, [16622] = 0x9204, [16623] = 0x9227, [16624] = 0x9202, ++ [16625] = 0x921C, [16626] = 0x9224, [16627] = 0x9219, [16628] = 0x9217, ++ [16629] = 0x9205, [16630] = 0x9216, [16631] = 0x957B, [16632] = 0x958D, ++ [16633] = 0x958C, [16634] = 0x9590, [16635] = 0x9687, [16636] = 0x967E, ++ [16637] = 0x9688, [16672] = 0x9689, [16673] = 0x9683, [16674] = 0x9680, ++ [16675] = 0x96C2, [16676] = 0x96C8, [16677] = 0x96C3, [16678] = 0x96F1, ++ [16679] = 0x96F0, [16680] = 0x976C, [16681] = 0x9770, [16682] = 0x976E, ++ [16683] = 0x9807, [16684] = 0x98A9, [16685] = 0x98EB, [16686] = 0x9CE6, ++ [16687] = 0x9EF9, [16688] = 0x4E83, [16689] = 0x4E84, [16690] = 0x4EB6, ++ [16691] = 0x50BD, [16692] = 0x50BF, [16693] = 0x50C6, [16694] = 0x50AE, ++ [16695] = 0x50C4, [16696] = 0x50CA, [16697] = 0x50B4, [16698] = 0x50C8, ++ [16699] = 0x50C2, [16700] = 0x50B0, [16701] = 0x50C1, [16702] = 0x50BA, ++ [16703] = 0x50B1, [16704] = 0x50CB, [16705] = 0x50C9, [16706] = 0x50B6, ++ [16707] = 0x50B8, [16708] = 0x51D7, [16709] = 0x527A, [16710] = 0x5278, ++ [16711] = 0x527B, [16712] = 0x527C, [16713] = 0x55C3, [16714] = 0x55DB, ++ [16715] = 0x55CC, [16716] = 0x55D0, [16717] = 0x55CB, [16718] = 0x55CA, ++ [16719] = 0x55DD, [16720] = 0x55C0, [16721] = 0x55D4, [16722] = 0x55C4, ++ [16723] = 0x55E9, [16724] = 0x55BF, [16725] = 0x55D2, [16726] = 0x558D, ++ [16727] = 0x55CF, [16728] = 0x55D5, [16729] = 0x55E2, [16730] = 0x55D6, ++ [16731] = 0x55C8, [16732] = 0x55F2, [16733] = 0x55CD, [16734] = 0x55D9, ++ [16735] = 0x55C2, [16736] = 0x5714, [16737] = 0x5853, [16738] = 0x5868, ++ [16739] = 0x5864, [16740] = 0x584F, [16741] = 0x584D, [16742] = 0x5849, ++ [16743] = 0x586F, [16744] = 0x5855, [16745] = 0x584E, [16746] = 0x585D, ++ [16747] = 0x5859, [16748] = 0x5865, [16749] = 0x585B, [16750] = 0x583D, ++ [16751] = 0x5863, [16752] = 0x5871, [16753] = 0x58FC, [16754] = 0x5AC7, ++ [16755] = 0x5AC4, [16756] = 0x5ACB, [16757] = 0x5ABA, [16758] = 0x5AB8, ++ [16759] = 0x5AB1, [16760] = 0x5AB5, [16761] = 0x5AB0, [16762] = 0x5ABF, ++ [16763] = 0x5AC8, [16764] = 0x5ABB, [16765] = 0x5AC6, [16770] = 0x5AB7, ++ [16771] = 0x5AC0, [16772] = 0x5ACA, [16773] = 0x5AB4, [16774] = 0x5AB6, ++ [16775] = 0x5ACD, [16776] = 0x5AB9, [16777] = 0x5A90, [16778] = 0x5BD6, ++ [16779] = 0x5BD8, [16780] = 0x5BD9, [16781] = 0x5C1F, [16782] = 0x5C33, ++ [16783] = 0x5D71, [16784] = 0x5D63, [16785] = 0x5D4A, [16786] = 0x5D65, ++ [16787] = 0x5D72, [16788] = 0x5D6C, [16789] = 0x5D5E, [16790] = 0x5D68, ++ [16791] = 0x5D67, [16792] = 0x5D62, [16793] = 0x5DF0, [16794] = 0x5E4F, ++ [16795] = 0x5E4E, [16796] = 0x5E4A, [16797] = 0x5E4D, [16798] = 0x5E4B, ++ [16799] = 0x5EC5, [16800] = 0x5ECC, [16801] = 0x5EC6, [16802] = 0x5ECB, ++ [16803] = 0x5EC7, [16804] = 0x5F40, [16805] = 0x5FAF, [16806] = 0x5FAD, ++ [16807] = 0x60F7, [16808] = 0x6149, [16809] = 0x614A, [16810] = 0x612B, ++ [16811] = 0x6145, [16812] = 0x6136, [16813] = 0x6132, [16814] = 0x612E, ++ [16815] = 0x6146, [16816] = 0x612F, [16817] = 0x614F, [16818] = 0x6129, ++ [16819] = 0x6140, [16820] = 0x6220, [16821] = 0x9168, [16822] = 0x6223, ++ [16823] = 0x6225, [16824] = 0x6224, [16825] = 0x63C5, [16826] = 0x63F1, ++ [16827] = 0x63EB, [16828] = 0x6410, [16829] = 0x6412, [16830] = 0x6409, ++ [16831] = 0x6420, [16832] = 0x6424, [16867] = 0x6433, [16868] = 0x6443, ++ [16869] = 0x641F, [16870] = 0x6415, [16871] = 0x6418, [16872] = 0x6439, ++ [16873] = 0x6437, [16874] = 0x6422, [16875] = 0x6423, [16876] = 0x640C, ++ [16877] = 0x6426, [16878] = 0x6430, [16879] = 0x6428, [16880] = 0x6441, ++ [16881] = 0x6435, [16882] = 0x642F, [16883] = 0x640A, [16884] = 0x641A, ++ [16885] = 0x6440, [16886] = 0x6425, [16887] = 0x6427, [16888] = 0x640B, ++ [16889] = 0x63E7, [16890] = 0x641B, [16891] = 0x642E, [16892] = 0x6421, ++ [16893] = 0x640E, [16894] = 0x656F, [16895] = 0x6592, [16896] = 0x65D3, ++ [16897] = 0x6686, [16898] = 0x668C, [16899] = 0x6695, [16900] = 0x6690, ++ [16901] = 0x668B, [16902] = 0x668A, [16903] = 0x6699, [16904] = 0x6694, ++ [16905] = 0x6678, [16906] = 0x6720, [16907] = 0x6966, [16908] = 0x695F, ++ [16909] = 0x6938, [16910] = 0x694E, [16911] = 0x6962, [16912] = 0x6971, ++ [16913] = 0x693F, [16914] = 0x6945, [16915] = 0x696A, [16916] = 0x6939, ++ [16917] = 0x6942, [16918] = 0x6957, [16919] = 0x6959, [16920] = 0x697A, ++ [16921] = 0x6948, [16922] = 0x6949, [16923] = 0x6935, [16924] = 0x696C, ++ [16925] = 0x6933, [16926] = 0x693D, [16927] = 0x6965, [16928] = 0x68F0, ++ [16929] = 0x6978, [16930] = 0x6934, [16931] = 0x6969, [16932] = 0x6940, ++ [16933] = 0x696F, [16934] = 0x6944, [16935] = 0x6976, [16936] = 0x6958, ++ [16937] = 0x6941, [16938] = 0x6974, [16939] = 0x694C, [16940] = 0x693B, ++ [16941] = 0x694B, [16942] = 0x6937, [16943] = 0x695C, [16944] = 0x694F, ++ [16945] = 0x6951, [16946] = 0x6932, [16947] = 0x6952, [16948] = 0x692F, ++ [16949] = 0x697B, [16950] = 0x693C, [16951] = 0x6B46, [16952] = 0x6B45, ++ [16953] = 0x6B43, [16954] = 0x6B42, [16955] = 0x6B48, [16956] = 0x6B41, ++ [16957] = 0x6B9B, [16958] = 0xFA0D, [16959] = 0x6BFB, [16960] = 0x6BFC, ++ [16965] = 0x6BF9, [16966] = 0x6BF7, [16967] = 0x6BF8, [16968] = 0x6E9B, ++ [16969] = 0x6ED6, [16970] = 0x6EC8, [16971] = 0x6E8F, [16972] = 0x6EC0, ++ [16973] = 0x6E9F, [16974] = 0x6E93, [16975] = 0x6E94, [16976] = 0x6EA0, ++ [16977] = 0x6EB1, [16978] = 0x6EB9, [16979] = 0x6EC6, [16980] = 0x6ED2, ++ [16981] = 0x6EBD, [16982] = 0x6EC1, [16983] = 0x6E9E, [16984] = 0x6EC9, ++ [16985] = 0x6EB7, [16986] = 0x6EB0, [16987] = 0x6ECD, [16988] = 0x6EA6, ++ [16989] = 0x6ECF, [16990] = 0x6EB2, [16991] = 0x6EBE, [16992] = 0x6EC3, ++ [16993] = 0x6EDC, [16994] = 0x6ED8, [16995] = 0x6E99, [16996] = 0x6E92, ++ [16997] = 0x6E8E, [16998] = 0x6E8D, [16999] = 0x6EA4, [17000] = 0x6EA1, ++ [17001] = 0x6EBF, [17002] = 0x6EB3, [17003] = 0x6ED0, [17004] = 0x6ECA, ++ [17005] = 0x6E97, [17006] = 0x6EAE, [17007] = 0x6EA3, [17008] = 0x7147, ++ [17009] = 0x7154, [17010] = 0x7152, [17011] = 0x7163, [17012] = 0x7160, ++ [17013] = 0x7141, [17014] = 0x715D, [17015] = 0x7162, [17016] = 0x7172, ++ [17017] = 0x7178, [17018] = 0x716A, [17019] = 0x7161, [17020] = 0x7142, ++ [17021] = 0x7158, [17022] = 0x7143, [17023] = 0x714B, [17024] = 0x7170, ++ [17025] = 0x715F, [17026] = 0x7150, [17027] = 0x7153, [17062] = 0x7144, ++ [17063] = 0x714D, [17064] = 0x715A, [17065] = 0x724F, [17066] = 0x728D, ++ [17067] = 0x728C, [17068] = 0x7291, [17069] = 0x7290, [17070] = 0x728E, ++ [17071] = 0x733C, [17072] = 0x7342, [17073] = 0x733B, [17074] = 0x733A, ++ [17075] = 0x7340, [17076] = 0x734A, [17077] = 0x7349, [17078] = 0x7444, ++ [17079] = 0x744A, [17080] = 0x744B, [17081] = 0x7452, [17082] = 0x7451, ++ [17083] = 0x7457, [17084] = 0x7440, [17085] = 0x744F, [17086] = 0x7450, ++ [17087] = 0x744E, [17088] = 0x7442, [17089] = 0x7446, [17090] = 0x744D, ++ [17091] = 0x7454, [17092] = 0x74E1, [17093] = 0x74FF, [17094] = 0x74FE, ++ [17095] = 0x74FD, [17096] = 0x751D, [17097] = 0x7579, [17098] = 0x7577, ++ [17099] = 0x6983, [17100] = 0x75EF, [17101] = 0x760F, [17102] = 0x7603, ++ [17103] = 0x75F7, [17104] = 0x75FE, [17105] = 0x75FC, [17106] = 0x75F9, ++ [17107] = 0x75F8, [17108] = 0x7610, [17109] = 0x75FB, [17110] = 0x75F6, ++ [17111] = 0x75ED, [17112] = 0x75F5, [17113] = 0x75FD, [17114] = 0x7699, ++ [17115] = 0x76B5, [17116] = 0x76DD, [17117] = 0x7755, [17118] = 0x775F, ++ [17119] = 0x7760, [17120] = 0x7752, [17121] = 0x7756, [17122] = 0x775A, ++ [17123] = 0x7769, [17124] = 0x7767, [17125] = 0x7754, [17126] = 0x7759, ++ [17127] = 0x776D, [17128] = 0x77E0, [17129] = 0x7887, [17130] = 0x789A, ++ [17131] = 0x7894, [17132] = 0x788F, [17133] = 0x7884, [17134] = 0x7895, ++ [17135] = 0x7885, [17136] = 0x7886, [17137] = 0x78A1, [17138] = 0x7883, ++ [17139] = 0x7879, [17140] = 0x7899, [17141] = 0x7880, [17142] = 0x7896, ++ [17143] = 0x787B, [17144] = 0x797C, [17145] = 0x7982, [17146] = 0x797D, ++ [17147] = 0x7979, [17148] = 0x7A11, [17149] = 0x7A18, [17150] = 0x7A19, ++ [17151] = 0x7A12, [17152] = 0x7A17, [17153] = 0x7A15, [17154] = 0x7A22, ++ [17155] = 0x7A13, [17160] = 0x7A1B, [17161] = 0x7A10, [17162] = 0x7AA3, ++ [17163] = 0x7AA2, [17164] = 0x7A9E, [17165] = 0x7AEB, [17166] = 0x7B66, ++ [17167] = 0x7B64, [17168] = 0x7B6D, [17169] = 0x7B74, [17170] = 0x7B69, ++ [17171] = 0x7B72, [17172] = 0x7B65, [17173] = 0x7B73, [17174] = 0x7B71, ++ [17175] = 0x7B70, [17176] = 0x7B61, [17177] = 0x7B78, [17178] = 0x7B76, ++ [17179] = 0x7B63, [17180] = 0x7CB2, [17181] = 0x7CB4, [17182] = 0x7CAF, ++ [17183] = 0x7D88, [17184] = 0x7D86, [17185] = 0x7D80, [17186] = 0x7D8D, ++ [17187] = 0x7D7F, [17188] = 0x7D85, [17189] = 0x7D7A, [17190] = 0x7D8E, ++ [17191] = 0x7D7B, [17192] = 0x7D83, [17193] = 0x7D7C, [17194] = 0x7D8C, ++ [17195] = 0x7D94, [17196] = 0x7D84, [17197] = 0x7D7D, [17198] = 0x7D92, ++ [17199] = 0x7F6D, [17200] = 0x7F6B, [17201] = 0x7F67, [17202] = 0x7F68, ++ [17203] = 0x7F6C, [17204] = 0x7FA6, [17205] = 0x7FA5, [17206] = 0x7FA7, ++ [17207] = 0x7FDB, [17208] = 0x7FDC, [17209] = 0x8021, [17210] = 0x8164, ++ [17211] = 0x8160, [17212] = 0x8177, [17213] = 0x815C, [17214] = 0x8169, ++ [17215] = 0x815B, [17216] = 0x8162, [17217] = 0x8172, [17218] = 0x6721, ++ [17219] = 0x815E, [17220] = 0x8176, [17221] = 0x8167, [17222] = 0x816F, ++ [17257] = 0x8144, [17258] = 0x8161, [17259] = 0x821D, [17260] = 0x8249, ++ [17261] = 0x8244, [17262] = 0x8240, [17263] = 0x8242, [17264] = 0x8245, ++ [17265] = 0x84F1, [17266] = 0x843F, [17267] = 0x8456, [17268] = 0x8476, ++ [17269] = 0x8479, [17270] = 0x848F, [17271] = 0x848D, [17272] = 0x8465, ++ [17273] = 0x8451, [17274] = 0x8440, [17275] = 0x8486, [17276] = 0x8467, ++ [17277] = 0x8430, [17278] = 0x844D, [17279] = 0x847D, [17280] = 0x845A, ++ [17281] = 0x8459, [17282] = 0x8474, [17283] = 0x8473, [17284] = 0x845D, ++ [17285] = 0x8507, [17286] = 0x845E, [17287] = 0x8437, [17288] = 0x843A, ++ [17289] = 0x8434, [17290] = 0x847A, [17291] = 0x8443, [17292] = 0x8478, ++ [17293] = 0x8432, [17294] = 0x8445, [17295] = 0x8429, [17296] = 0x83D9, ++ [17297] = 0x844B, [17298] = 0x842F, [17299] = 0x8442, [17300] = 0x842D, ++ [17301] = 0x845F, [17302] = 0x8470, [17303] = 0x8439, [17304] = 0x844E, ++ [17305] = 0x844C, [17306] = 0x8452, [17307] = 0x846F, [17308] = 0x84C5, ++ [17309] = 0x848E, [17310] = 0x843B, [17311] = 0x8447, [17312] = 0x8436, ++ [17313] = 0x8433, [17314] = 0x8468, [17315] = 0x847E, [17316] = 0x8444, ++ [17317] = 0x842B, [17318] = 0x8460, [17319] = 0x8454, [17320] = 0x846E, ++ [17321] = 0x8450, [17322] = 0x870B, [17323] = 0x8704, [17324] = 0x86F7, ++ [17325] = 0x870C, [17326] = 0x86FA, [17327] = 0x86D6, [17328] = 0x86F5, ++ [17329] = 0x874D, [17330] = 0x86F8, [17331] = 0x870E, [17332] = 0x8709, ++ [17333] = 0x8701, [17334] = 0x86F6, [17335] = 0x870D, [17336] = 0x8705, ++ [17337] = 0x88D6, [17338] = 0x88CB, [17339] = 0x88CD, [17340] = 0x88CE, ++ [17341] = 0x88DE, [17342] = 0x88DB, [17343] = 0x88DA, [17344] = 0x88CC, ++ [17345] = 0x88D0, [17346] = 0x8985, [17347] = 0x899B, [17348] = 0x89DF, ++ [17349] = 0x89E5, [17350] = 0x89E4, [17355] = 0x89E1, [17356] = 0x89E0, ++ [17357] = 0x89E2, [17358] = 0x89DC, [17359] = 0x89E6, [17360] = 0x8A76, ++ [17361] = 0x8A86, [17362] = 0x8A7F, [17363] = 0x8A61, [17364] = 0x8A3F, ++ [17365] = 0x8A77, [17366] = 0x8A82, [17367] = 0x8A84, [17368] = 0x8A75, ++ [17369] = 0x8A83, [17370] = 0x8A81, [17371] = 0x8A74, [17372] = 0x8A7A, ++ [17373] = 0x8C3C, [17374] = 0x8C4B, [17375] = 0x8C4A, [17376] = 0x8C65, ++ [17377] = 0x8C64, [17378] = 0x8C66, [17379] = 0x8C86, [17380] = 0x8C84, ++ [17381] = 0x8C85, [17382] = 0x8CCC, [17383] = 0x8D68, [17384] = 0x8D69, ++ [17385] = 0x8D91, [17386] = 0x8D8C, [17387] = 0x8D8E, [17388] = 0x8D8F, ++ [17389] = 0x8D8D, [17390] = 0x8D93, [17391] = 0x8D94, [17392] = 0x8D90, ++ [17393] = 0x8D92, [17394] = 0x8DF0, [17395] = 0x8DE0, [17396] = 0x8DEC, ++ [17397] = 0x8DF1, [17398] = 0x8DEE, [17399] = 0x8DD0, [17400] = 0x8DE9, ++ [17401] = 0x8DE3, [17402] = 0x8DE2, [17403] = 0x8DE7, [17404] = 0x8DF2, ++ [17405] = 0x8DEB, [17406] = 0x8DF4, [17407] = 0x8F06, [17408] = 0x8EFF, ++ [17409] = 0x8F01, [17410] = 0x8F00, [17411] = 0x8F05, [17412] = 0x8F07, ++ [17413] = 0x8F08, [17414] = 0x8F02, [17415] = 0x8F0B, [17416] = 0x9052, ++ [17417] = 0x903F, [17452] = 0x9044, [17453] = 0x9049, [17454] = 0x903D, ++ [17455] = 0x9110, [17456] = 0x910D, [17457] = 0x910F, [17458] = 0x9111, ++ [17459] = 0x9116, [17460] = 0x9114, [17461] = 0x910B, [17462] = 0x910E, ++ [17463] = 0x916E, [17464] = 0x916F, [17465] = 0x9248, [17466] = 0x9252, ++ [17467] = 0x9230, [17468] = 0x923A, [17469] = 0x9266, [17470] = 0x9233, ++ [17471] = 0x9265, [17472] = 0x925E, [17473] = 0x9283, [17474] = 0x922E, ++ [17475] = 0x924A, [17476] = 0x9246, [17477] = 0x926D, [17478] = 0x926C, ++ [17479] = 0x924F, [17480] = 0x9260, [17481] = 0x9267, [17482] = 0x926F, ++ [17483] = 0x9236, [17484] = 0x9261, [17485] = 0x9270, [17486] = 0x9231, ++ [17487] = 0x9254, [17488] = 0x9263, [17489] = 0x9250, [17490] = 0x9272, ++ [17491] = 0x924E, [17492] = 0x9253, [17493] = 0x924C, [17494] = 0x9256, ++ [17495] = 0x9232, [17496] = 0x959F, [17497] = 0x959C, [17498] = 0x959E, ++ [17499] = 0x959B, [17500] = 0x9692, [17501] = 0x9693, [17502] = 0x9691, ++ [17503] = 0x9697, [17504] = 0x96CE, [17505] = 0x96FA, [17506] = 0x96FD, ++ [17507] = 0x96F8, [17508] = 0x96F5, [17509] = 0x9773, [17510] = 0x9777, ++ [17511] = 0x9778, [17512] = 0x9772, [17513] = 0x980F, [17514] = 0x980D, ++ [17515] = 0x980E, [17516] = 0x98AC, [17517] = 0x98F6, [17518] = 0x98F9, ++ [17519] = 0x99AF, [17520] = 0x99B2, [17521] = 0x99B0, [17522] = 0x99B5, ++ [17523] = 0x9AAD, [17524] = 0x9AAB, [17525] = 0x9B5B, [17526] = 0x9CEA, ++ [17527] = 0x9CED, [17528] = 0x9CE7, [17529] = 0x9E80, [17530] = 0x9EFD, ++ [17531] = 0x50E6, [17532] = 0x50D4, [17533] = 0x50D7, [17534] = 0x50E8, ++ [17535] = 0x50F3, [17536] = 0x50DB, [17537] = 0x50EA, [17538] = 0x50DD, ++ [17539] = 0x50E4, [17540] = 0x50D3, [17541] = 0x50EC, [17542] = 0x50F0, ++ [17543] = 0x50EF, [17544] = 0x50E3, [17545] = 0x50E0, [17550] = 0x51D8, ++ [17551] = 0x5280, [17552] = 0x5281, [17553] = 0x52E9, [17554] = 0x52EB, ++ [17555] = 0x5330, [17556] = 0x53AC, [17557] = 0x5627, [17558] = 0x5615, ++ [17559] = 0x560C, [17560] = 0x5612, [17561] = 0x55FC, [17562] = 0x560F, ++ [17563] = 0x561C, [17564] = 0x5601, [17565] = 0x5613, [17566] = 0x5602, ++ [17567] = 0x55FA, [17568] = 0x561D, [17569] = 0x5604, [17570] = 0x55FF, ++ [17571] = 0x55F9, [17572] = 0x5889, [17573] = 0x587C, [17574] = 0x5890, ++ [17575] = 0x5898, [17576] = 0x5886, [17577] = 0x5881, [17578] = 0x587F, ++ [17579] = 0x5874, [17580] = 0x588B, [17581] = 0x587A, [17582] = 0x5887, ++ [17583] = 0x5891, [17584] = 0x588E, [17585] = 0x5876, [17586] = 0x5882, ++ [17587] = 0x5888, [17588] = 0x587B, [17589] = 0x5894, [17590] = 0x588F, ++ [17591] = 0x58FE, [17592] = 0x596B, [17593] = 0x5ADC, [17594] = 0x5AEE, ++ [17595] = 0x5AE5, [17596] = 0x5AD5, [17597] = 0x5AEA, [17598] = 0x5ADA, ++ [17599] = 0x5AED, [17600] = 0x5AEB, [17601] = 0x5AF3, [17602] = 0x5AE2, ++ [17603] = 0x5AE0, [17604] = 0x5ADB, [17605] = 0x5AEC, [17606] = 0x5ADE, ++ [17607] = 0x5ADD, [17608] = 0x5AD9, [17609] = 0x5AE8, [17610] = 0x5ADF, ++ [17611] = 0x5B77, [17612] = 0x5BE0, [17647] = 0x5BE3, [17648] = 0x5C63, ++ [17649] = 0x5D82, [17650] = 0x5D80, [17651] = 0x5D7D, [17652] = 0x5D86, ++ [17653] = 0x5D7A, [17654] = 0x5D81, [17655] = 0x5D77, [17656] = 0x5D8A, ++ [17657] = 0x5D89, [17658] = 0x5D88, [17659] = 0x5D7E, [17660] = 0x5D7C, ++ [17661] = 0x5D8D, [17662] = 0x5D79, [17663] = 0x5D7F, [17664] = 0x5E58, ++ [17665] = 0x5E59, [17666] = 0x5E53, [17667] = 0x5ED8, [17668] = 0x5ED1, ++ [17669] = 0x5ED7, [17670] = 0x5ECE, [17671] = 0x5EDC, [17672] = 0x5ED5, ++ [17673] = 0x5ED9, [17674] = 0x5ED2, [17675] = 0x5ED4, [17676] = 0x5F44, ++ [17677] = 0x5F43, [17678] = 0x5F6F, [17679] = 0x5FB6, [17680] = 0x612C, ++ [17681] = 0x6128, [17682] = 0x6141, [17683] = 0x615E, [17684] = 0x6171, ++ [17685] = 0x6173, [17686] = 0x6152, [17687] = 0x6153, [17688] = 0x6172, ++ [17689] = 0x616C, [17690] = 0x6180, [17691] = 0x6174, [17692] = 0x6154, ++ [17693] = 0x617A, [17694] = 0x615B, [17695] = 0x6165, [17696] = 0x613B, ++ [17697] = 0x616A, [17698] = 0x6161, [17699] = 0x6156, [17700] = 0x6229, ++ [17701] = 0x6227, [17702] = 0x622B, [17703] = 0x642B, [17704] = 0x644D, ++ [17705] = 0x645B, [17706] = 0x645D, [17707] = 0x6474, [17708] = 0x6476, ++ [17709] = 0x6472, [17710] = 0x6473, [17711] = 0x647D, [17712] = 0x6475, ++ [17713] = 0x6466, [17714] = 0x64A6, [17715] = 0x644E, [17716] = 0x6482, ++ [17717] = 0x645E, [17718] = 0x645C, [17719] = 0x644B, [17720] = 0x6453, ++ [17721] = 0x6460, [17722] = 0x6450, [17723] = 0x647F, [17724] = 0x643F, ++ [17725] = 0x646C, [17726] = 0x646B, [17727] = 0x6459, [17728] = 0x6465, ++ [17729] = 0x6477, [17730] = 0x6573, [17731] = 0x65A0, [17732] = 0x66A1, ++ [17733] = 0x66A0, [17734] = 0x669F, [17735] = 0x6705, [17736] = 0x6704, ++ [17737] = 0x6722, [17738] = 0x69B1, [17739] = 0x69B6, [17740] = 0x69C9, ++ [17745] = 0x69A0, [17746] = 0x69CE, [17747] = 0x6996, [17748] = 0x69B0, ++ [17749] = 0x69AC, [17750] = 0x69BC, [17751] = 0x6991, [17752] = 0x6999, ++ [17753] = 0x698E, [17754] = 0x69A7, [17755] = 0x698D, [17756] = 0x69A9, ++ [17757] = 0x69BE, [17758] = 0x69AF, [17759] = 0x69BF, [17760] = 0x69C4, ++ [17761] = 0x69BD, [17762] = 0x69A4, [17763] = 0x69D4, [17764] = 0x69B9, ++ [17765] = 0x69CA, [17766] = 0x699A, [17767] = 0x69CF, [17768] = 0x69B3, ++ [17769] = 0x6993, [17770] = 0x69AA, [17771] = 0x69A1, [17772] = 0x699E, ++ [17773] = 0x69D9, [17774] = 0x6997, [17775] = 0x6990, [17776] = 0x69C2, ++ [17777] = 0x69B5, [17778] = 0x69A5, [17779] = 0x69C6, [17780] = 0x6B4A, ++ [17781] = 0x6B4D, [17782] = 0x6B4B, [17783] = 0x6B9E, [17784] = 0x6B9F, ++ [17785] = 0x6BA0, [17786] = 0x6BC3, [17787] = 0x6BC4, [17788] = 0x6BFE, ++ [17789] = 0x6ECE, [17790] = 0x6EF5, [17791] = 0x6EF1, [17792] = 0x6F03, ++ [17793] = 0x6F25, [17794] = 0x6EF8, [17795] = 0x6F37, [17796] = 0x6EFB, ++ [17797] = 0x6F2E, [17798] = 0x6F09, [17799] = 0x6F4E, [17800] = 0x6F19, ++ [17801] = 0x6F1A, [17802] = 0x6F27, [17803] = 0x6F18, [17804] = 0x6F3B, ++ [17805] = 0x6F12, [17806] = 0x6EED, [17807] = 0x6F0A, [17842] = 0x6F36, ++ [17843] = 0x6F73, [17844] = 0x6EF9, [17845] = 0x6EEE, [17846] = 0x6F2D, ++ [17847] = 0x6F40, [17848] = 0x6F30, [17849] = 0x6F3C, [17850] = 0x6F35, ++ [17851] = 0x6EEB, [17852] = 0x6F07, [17853] = 0x6F0E, [17854] = 0x6F43, ++ [17855] = 0x6F05, [17856] = 0x6EFD, [17857] = 0x6EF6, [17858] = 0x6F39, ++ [17859] = 0x6F1C, [17860] = 0x6EFC, [17861] = 0x6F3A, [17862] = 0x6F1F, ++ [17863] = 0x6F0D, [17864] = 0x6F1E, [17865] = 0x6F08, [17866] = 0x6F21, ++ [17867] = 0x7187, [17868] = 0x7190, [17869] = 0x7189, [17870] = 0x7180, ++ [17871] = 0x7185, [17872] = 0x7182, [17873] = 0x718F, [17874] = 0x717B, ++ [17875] = 0x7186, [17876] = 0x7181, [17877] = 0x7197, [17878] = 0x7244, ++ [17879] = 0x7253, [17880] = 0x7297, [17881] = 0x7295, [17882] = 0x7293, ++ [17883] = 0x7343, [17884] = 0x734D, [17885] = 0x7351, [17886] = 0x734C, ++ [17887] = 0x7462, [17888] = 0x7473, [17889] = 0x7471, [17890] = 0x7475, ++ [17891] = 0x7472, [17892] = 0x7467, [17893] = 0x746E, [17894] = 0x7500, ++ [17895] = 0x7502, [17896] = 0x7503, [17897] = 0x757D, [17898] = 0x7590, ++ [17899] = 0x7616, [17900] = 0x7608, [17901] = 0x760C, [17902] = 0x7615, ++ [17903] = 0x7611, [17904] = 0x760A, [17905] = 0x7614, [17906] = 0x76B8, ++ [17907] = 0x7781, [17908] = 0x777C, [17909] = 0x7785, [17910] = 0x7782, ++ [17911] = 0x776E, [17912] = 0x7780, [17913] = 0x776F, [17914] = 0x777E, ++ [17915] = 0x7783, [17916] = 0x78B2, [17917] = 0x78AA, [17918] = 0x78B4, ++ [17919] = 0x78AD, [17920] = 0x78A8, [17921] = 0x787E, [17922] = 0x78AB, ++ [17923] = 0x789E, [17924] = 0x78A5, [17925] = 0x78A0, [17926] = 0x78AC, ++ [17927] = 0x78A2, [17928] = 0x78A4, [17929] = 0x7998, [17930] = 0x798A, ++ [17931] = 0x798B, [17932] = 0x7996, [17933] = 0x7995, [17934] = 0x7994, ++ [17935] = 0x7993, [17940] = 0x7997, [17941] = 0x7988, [17942] = 0x7992, ++ [17943] = 0x7990, [17944] = 0x7A2B, [17945] = 0x7A4A, [17946] = 0x7A30, ++ [17947] = 0x7A2F, [17948] = 0x7A28, [17949] = 0x7A26, [17950] = 0x7AA8, ++ [17951] = 0x7AAB, [17952] = 0x7AAC, [17953] = 0x7AEE, [17954] = 0x7B88, ++ [17955] = 0x7B9C, [17956] = 0x7B8A, [17957] = 0x7B91, [17958] = 0x7B90, ++ [17959] = 0x7B96, [17960] = 0x7B8D, [17961] = 0x7B8C, [17962] = 0x7B9B, ++ [17963] = 0x7B8E, [17964] = 0x7B85, [17965] = 0x7B98, [17966] = 0x5284, ++ [17967] = 0x7B99, [17968] = 0x7BA4, [17969] = 0x7B82, [17970] = 0x7CBB, ++ [17971] = 0x7CBF, [17972] = 0x7CBC, [17973] = 0x7CBA, [17974] = 0x7DA7, ++ [17975] = 0x7DB7, [17976] = 0x7DC2, [17977] = 0x7DA3, [17978] = 0x7DAA, ++ [17979] = 0x7DC1, [17980] = 0x7DC0, [17981] = 0x7DC5, [17982] = 0x7D9D, ++ [17983] = 0x7DCE, [17984] = 0x7DC4, [17985] = 0x7DC6, [17986] = 0x7DCB, ++ [17987] = 0x7DCC, [17988] = 0x7DAF, [17989] = 0x7DB9, [17990] = 0x7D96, ++ [17991] = 0x7DBC, [17992] = 0x7D9F, [17993] = 0x7DA6, [17994] = 0x7DAE, ++ [17995] = 0x7DA9, [17996] = 0x7DA1, [17997] = 0x7DC9, [17998] = 0x7F73, ++ [17999] = 0x7FE2, [18000] = 0x7FE3, [18001] = 0x7FE5, [18002] = 0x7FDE, ++ [18037] = 0x8024, [18038] = 0x805D, [18039] = 0x805C, [18040] = 0x8189, ++ [18041] = 0x8186, [18042] = 0x8183, [18043] = 0x8187, [18044] = 0x818D, ++ [18045] = 0x818C, [18046] = 0x818B, [18047] = 0x8215, [18048] = 0x8497, ++ [18049] = 0x84A4, [18050] = 0x84A1, [18051] = 0x849F, [18052] = 0x84BA, ++ [18053] = 0x84CE, [18054] = 0x84C2, [18055] = 0x84AC, [18056] = 0x84AE, ++ [18057] = 0x84AB, [18058] = 0x84B9, [18059] = 0x84B4, [18060] = 0x84C1, ++ [18061] = 0x84CD, [18062] = 0x84AA, [18063] = 0x849A, [18064] = 0x84B1, ++ [18065] = 0x84D0, [18066] = 0x849D, [18067] = 0x84A7, [18068] = 0x84BB, ++ [18069] = 0x84A2, [18070] = 0x8494, [18071] = 0x84C7, [18072] = 0x84CC, ++ [18073] = 0x849B, [18074] = 0x84A9, [18075] = 0x84AF, [18076] = 0x84A8, ++ [18077] = 0x84D6, [18078] = 0x8498, [18079] = 0x84B6, [18080] = 0x84CF, ++ [18081] = 0x84A0, [18082] = 0x84D7, [18083] = 0x84D4, [18084] = 0x84D2, ++ [18085] = 0x84DB, [18086] = 0x84B0, [18087] = 0x8491, [18088] = 0x8661, ++ [18089] = 0x8733, [18090] = 0x8723, [18091] = 0x8728, [18092] = 0x876B, ++ [18093] = 0x8740, [18094] = 0x872E, [18095] = 0x871E, [18096] = 0x8721, ++ [18097] = 0x8719, [18098] = 0x871B, [18099] = 0x8743, [18100] = 0x872C, ++ [18101] = 0x8741, [18102] = 0x873E, [18103] = 0x8746, [18104] = 0x8720, ++ [18105] = 0x8732, [18106] = 0x872A, [18107] = 0x872D, [18108] = 0x873C, ++ [18109] = 0x8712, [18110] = 0x873A, [18111] = 0x8731, [18112] = 0x8735, ++ [18113] = 0x8742, [18114] = 0x8726, [18115] = 0x8727, [18116] = 0x8738, ++ [18117] = 0x8724, [18118] = 0x871A, [18119] = 0x8730, [18120] = 0x8711, ++ [18121] = 0x88F7, [18122] = 0x88E7, [18123] = 0x88F1, [18124] = 0x88F2, ++ [18125] = 0x88FA, [18126] = 0x88FE, [18127] = 0x88EE, [18128] = 0x88FC, ++ [18129] = 0x88F6, [18130] = 0x88FB, [18135] = 0x88F0, [18136] = 0x88EC, ++ [18137] = 0x88EB, [18138] = 0x899D, [18139] = 0x89A1, [18140] = 0x899F, ++ [18141] = 0x899E, [18142] = 0x89E9, [18143] = 0x89EB, [18144] = 0x89E8, ++ [18145] = 0x8AAB, [18146] = 0x8A99, [18147] = 0x8A8B, [18148] = 0x8A92, ++ [18149] = 0x8A8F, [18150] = 0x8A96, [18151] = 0x8C3D, [18152] = 0x8C68, ++ [18153] = 0x8C69, [18154] = 0x8CD5, [18155] = 0x8CCF, [18156] = 0x8CD7, ++ [18157] = 0x8D96, [18158] = 0x8E09, [18159] = 0x8E02, [18160] = 0x8DFF, ++ [18161] = 0x8E0D, [18162] = 0x8DFD, [18163] = 0x8E0A, [18164] = 0x8E03, ++ [18165] = 0x8E07, [18166] = 0x8E06, [18167] = 0x8E05, [18168] = 0x8DFE, ++ [18169] = 0x8E00, [18170] = 0x8E04, [18171] = 0x8F10, [18172] = 0x8F11, ++ [18173] = 0x8F0E, [18174] = 0x8F0D, [18175] = 0x9123, [18176] = 0x911C, ++ [18177] = 0x9120, [18178] = 0x9122, [18179] = 0x911F, [18180] = 0x911D, ++ [18181] = 0x911A, [18182] = 0x9124, [18183] = 0x9121, [18184] = 0x911B, ++ [18185] = 0x917A, [18186] = 0x9172, [18187] = 0x9179, [18188] = 0x9173, ++ [18189] = 0x92A5, [18190] = 0x92A4, [18191] = 0x9276, [18192] = 0x929B, ++ [18193] = 0x927A, [18194] = 0x92A0, [18195] = 0x9294, [18196] = 0x92AA, ++ [18197] = 0x928D, [18232] = 0x92A6, [18233] = 0x929A, [18234] = 0x92AB, ++ [18235] = 0x9279, [18236] = 0x9297, [18237] = 0x927F, [18238] = 0x92A3, ++ [18239] = 0x92EE, [18240] = 0x928E, [18241] = 0x9282, [18242] = 0x9295, ++ [18243] = 0x92A2, [18244] = 0x927D, [18245] = 0x9288, [18246] = 0x92A1, ++ [18247] = 0x928A, [18248] = 0x9286, [18249] = 0x928C, [18250] = 0x9299, ++ [18251] = 0x92A7, [18252] = 0x927E, [18253] = 0x9287, [18254] = 0x92A9, ++ [18255] = 0x929D, [18256] = 0x928B, [18257] = 0x922D, [18258] = 0x969E, ++ [18259] = 0x96A1, [18260] = 0x96FF, [18261] = 0x9758, [18262] = 0x977D, ++ [18263] = 0x977A, [18264] = 0x977E, [18265] = 0x9783, [18266] = 0x9780, ++ [18267] = 0x9782, [18268] = 0x977B, [18269] = 0x9784, [18270] = 0x9781, ++ [18271] = 0x977F, [18272] = 0x97CE, [18273] = 0x97CD, [18274] = 0x9816, ++ [18275] = 0x98AD, [18276] = 0x98AE, [18277] = 0x9902, [18278] = 0x9900, ++ [18279] = 0x9907, [18280] = 0x999D, [18281] = 0x999C, [18282] = 0x99C3, ++ [18283] = 0x99B9, [18284] = 0x99BB, [18285] = 0x99BA, [18286] = 0x99C2, ++ [18287] = 0x99BD, [18288] = 0x99C7, [18289] = 0x9AB1, [18290] = 0x9AE3, ++ [18291] = 0x9AE7, [18292] = 0x9B3E, [18293] = 0x9B3F, [18294] = 0x9B60, ++ [18295] = 0x9B61, [18296] = 0x9B5F, [18297] = 0x9CF1, [18298] = 0x9CF2, ++ [18299] = 0x9CF5, [18300] = 0x9EA7, [18301] = 0x50FF, [18302] = 0x5103, ++ [18303] = 0x5130, [18304] = 0x50F8, [18305] = 0x5106, [18306] = 0x5107, ++ [18307] = 0x50F6, [18308] = 0x50FE, [18309] = 0x510B, [18310] = 0x510C, ++ [18311] = 0x50FD, [18312] = 0x510A, [18313] = 0x528B, [18314] = 0x528C, ++ [18315] = 0x52F1, [18316] = 0x52EF, [18317] = 0x5648, [18318] = 0x5642, ++ [18319] = 0x564C, [18320] = 0x5635, [18321] = 0x5641, [18322] = 0x564A, ++ [18323] = 0x5649, [18324] = 0x5646, [18325] = 0x5658, [18330] = 0x565A, ++ [18331] = 0x5640, [18332] = 0x5633, [18333] = 0x563D, [18334] = 0x562C, ++ [18335] = 0x563E, [18336] = 0x5638, [18337] = 0x562A, [18338] = 0x563A, ++ [18339] = 0x571A, [18340] = 0x58AB, [18341] = 0x589D, [18342] = 0x58B1, ++ [18343] = 0x58A0, [18344] = 0x58A3, [18345] = 0x58AF, [18346] = 0x58AC, ++ [18347] = 0x58A5, [18348] = 0x58A1, [18349] = 0x58FF, [18350] = 0x5AFF, ++ [18351] = 0x5AF4, [18352] = 0x5AFD, [18353] = 0x5AF7, [18354] = 0x5AF6, ++ [18355] = 0x5B03, [18356] = 0x5AF8, [18357] = 0x5B02, [18358] = 0x5AF9, ++ [18359] = 0x5B01, [18360] = 0x5B07, [18361] = 0x5B05, [18362] = 0x5B0F, ++ [18363] = 0x5C67, [18364] = 0x5D99, [18365] = 0x5D97, [18366] = 0x5D9F, ++ [18367] = 0x5D92, [18368] = 0x5DA2, [18369] = 0x5D93, [18370] = 0x5D95, ++ [18371] = 0x5DA0, [18372] = 0x5D9C, [18373] = 0x5DA1, [18374] = 0x5D9A, ++ [18375] = 0x5D9E, [18376] = 0x5E69, [18377] = 0x5E5D, [18378] = 0x5E60, ++ [18379] = 0x5E5C, [18380] = 0x7DF3, [18381] = 0x5EDB, [18382] = 0x5EDE, ++ [18383] = 0x5EE1, [18384] = 0x5F49, [18385] = 0x5FB2, [18386] = 0x618B, ++ [18387] = 0x6183, [18388] = 0x6179, [18389] = 0x61B1, [18390] = 0x61B0, ++ [18391] = 0x61A2, [18392] = 0x6189, [18427] = 0x619B, [18428] = 0x6193, ++ [18429] = 0x61AF, [18430] = 0x61AD, [18431] = 0x619F, [18432] = 0x6192, ++ [18433] = 0x61AA, [18434] = 0x61A1, [18435] = 0x618D, [18436] = 0x6166, ++ [18437] = 0x61B3, [18438] = 0x622D, [18439] = 0x646E, [18440] = 0x6470, ++ [18441] = 0x6496, [18442] = 0x64A0, [18443] = 0x6485, [18444] = 0x6497, ++ [18445] = 0x649C, [18446] = 0x648F, [18447] = 0x648B, [18448] = 0x648A, ++ [18449] = 0x648C, [18450] = 0x64A3, [18451] = 0x649F, [18452] = 0x6468, ++ [18453] = 0x64B1, [18454] = 0x6498, [18455] = 0x6576, [18456] = 0x657A, ++ [18457] = 0x6579, [18458] = 0x657B, [18459] = 0x65B2, [18460] = 0x65B3, ++ [18461] = 0x66B5, [18462] = 0x66B0, [18463] = 0x66A9, [18464] = 0x66B2, ++ [18465] = 0x66B7, [18466] = 0x66AA, [18467] = 0x66AF, [18468] = 0x6A00, ++ [18469] = 0x6A06, [18470] = 0x6A17, [18471] = 0x69E5, [18472] = 0x69F8, ++ [18473] = 0x6A15, [18474] = 0x69F1, [18475] = 0x69E4, [18476] = 0x6A20, ++ [18477] = 0x69FF, [18478] = 0x69EC, [18479] = 0x69E2, [18480] = 0x6A1B, ++ [18481] = 0x6A1D, [18482] = 0x69FE, [18483] = 0x6A27, [18484] = 0x69F2, ++ [18485] = 0x69EE, [18486] = 0x6A14, [18487] = 0x69F7, [18488] = 0x69E7, ++ [18489] = 0x6A40, [18490] = 0x6A08, [18491] = 0x69E6, [18492] = 0x69FB, ++ [18493] = 0x6A0D, [18494] = 0x69FC, [18495] = 0x69EB, [18496] = 0x6A09, ++ [18497] = 0x6A04, [18498] = 0x6A18, [18499] = 0x6A25, [18500] = 0x6A0F, ++ [18501] = 0x69F6, [18502] = 0x6A26, [18503] = 0x6A07, [18504] = 0x69F4, ++ [18505] = 0x6A16, [18506] = 0x6B51, [18507] = 0x6BA5, [18508] = 0x6BA3, ++ [18509] = 0x6BA2, [18510] = 0x6BA6, [18511] = 0x6C01, [18512] = 0x6C00, ++ [18513] = 0x6BFF, [18514] = 0x6C02, [18515] = 0x6F41, [18516] = 0x6F26, ++ [18517] = 0x6F7E, [18518] = 0x6F87, [18519] = 0x6FC6, [18520] = 0x6F92, ++ [18525] = 0x6F8D, [18526] = 0x6F89, [18527] = 0x6F8C, [18528] = 0x6F62, ++ [18529] = 0x6F4F, [18530] = 0x6F85, [18531] = 0x6F5A, [18532] = 0x6F96, ++ [18533] = 0x6F76, [18534] = 0x6F6C, [18535] = 0x6F82, [18536] = 0x6F55, ++ [18537] = 0x6F72, [18538] = 0x6F52, [18539] = 0x6F50, [18540] = 0x6F57, ++ [18541] = 0x6F94, [18542] = 0x6F93, [18543] = 0x6F5D, [18544] = 0x6F00, ++ [18545] = 0x6F61, [18546] = 0x6F6B, [18547] = 0x6F7D, [18548] = 0x6F67, ++ [18549] = 0x6F90, [18550] = 0x6F53, [18551] = 0x6F8B, [18552] = 0x6F69, ++ [18553] = 0x6F7F, [18554] = 0x6F95, [18555] = 0x6F63, [18556] = 0x6F77, ++ [18557] = 0x6F6A, [18558] = 0x6F7B, [18559] = 0x71B2, [18560] = 0x71AF, ++ [18561] = 0x719B, [18562] = 0x71B0, [18563] = 0x71A0, [18564] = 0x719A, ++ [18565] = 0x71A9, [18566] = 0x71B5, [18567] = 0x719D, [18568] = 0x71A5, ++ [18569] = 0x719E, [18570] = 0x71A4, [18571] = 0x71A1, [18572] = 0x71AA, ++ [18573] = 0x719C, [18574] = 0x71A7, [18575] = 0x71B3, [18576] = 0x7298, ++ [18577] = 0x729A, [18578] = 0x7358, [18579] = 0x7352, [18580] = 0x735E, ++ [18581] = 0x735F, [18582] = 0x7360, [18583] = 0x735D, [18584] = 0x735B, ++ [18585] = 0x7361, [18586] = 0x735A, [18587] = 0x7359, [18622] = 0x7362, ++ [18623] = 0x7487, [18624] = 0x7489, [18625] = 0x748A, [18626] = 0x7486, ++ [18627] = 0x7481, [18628] = 0x747D, [18629] = 0x7485, [18630] = 0x7488, ++ [18631] = 0x747C, [18632] = 0x7479, [18633] = 0x7508, [18634] = 0x7507, ++ [18635] = 0x757E, [18636] = 0x7625, [18637] = 0x761E, [18638] = 0x7619, ++ [18639] = 0x761D, [18640] = 0x761C, [18641] = 0x7623, [18642] = 0x761A, ++ [18643] = 0x7628, [18644] = 0x761B, [18645] = 0x769C, [18646] = 0x769D, ++ [18647] = 0x769E, [18648] = 0x769B, [18649] = 0x778D, [18650] = 0x778F, ++ [18651] = 0x7789, [18652] = 0x7788, [18653] = 0x78CD, [18654] = 0x78BB, ++ [18655] = 0x78CF, [18656] = 0x78CC, [18657] = 0x78D1, [18658] = 0x78CE, ++ [18659] = 0x78D4, [18660] = 0x78C8, [18661] = 0x78C3, [18662] = 0x78C4, ++ [18663] = 0x78C9, [18664] = 0x799A, [18665] = 0x79A1, [18666] = 0x79A0, ++ [18667] = 0x799C, [18668] = 0x79A2, [18669] = 0x799B, [18670] = 0x6B76, ++ [18671] = 0x7A39, [18672] = 0x7AB2, [18673] = 0x7AB4, [18674] = 0x7AB3, ++ [18675] = 0x7BB7, [18676] = 0x7BCB, [18677] = 0x7BBE, [18678] = 0x7BAC, ++ [18679] = 0x7BCE, [18680] = 0x7BAF, [18681] = 0x7BB9, [18682] = 0x7BCA, ++ [18683] = 0x7BB5, [18684] = 0x7CC5, [18685] = 0x7CC8, [18686] = 0x7CCC, ++ [18687] = 0x7CCB, [18688] = 0x7DF7, [18689] = 0x7DDB, [18690] = 0x7DEA, ++ [18691] = 0x7DE7, [18692] = 0x7DD7, [18693] = 0x7DE1, [18694] = 0x7E03, ++ [18695] = 0x7DFA, [18696] = 0x7DE6, [18697] = 0x7DF6, [18698] = 0x7DF1, ++ [18699] = 0x7DF0, [18700] = 0x7DEE, [18701] = 0x7DDF, [18702] = 0x7F76, ++ [18703] = 0x7FAC, [18704] = 0x7FB0, [18705] = 0x7FAD, [18706] = 0x7FED, ++ [18707] = 0x7FEB, [18708] = 0x7FEA, [18709] = 0x7FEC, [18710] = 0x7FE6, ++ [18711] = 0x7FE8, [18712] = 0x8064, [18713] = 0x8067, [18714] = 0x81A3, ++ [18715] = 0x819F, [18720] = 0x819E, [18721] = 0x8195, [18722] = 0x81A2, ++ [18723] = 0x8199, [18724] = 0x8197, [18725] = 0x8216, [18726] = 0x824F, ++ [18727] = 0x8253, [18728] = 0x8252, [18729] = 0x8250, [18730] = 0x824E, ++ [18731] = 0x8251, [18732] = 0x8524, [18733] = 0x853B, [18734] = 0x850F, ++ [18735] = 0x8500, [18736] = 0x8529, [18737] = 0x850E, [18738] = 0x8509, ++ [18739] = 0x850D, [18740] = 0x851F, [18741] = 0x850A, [18742] = 0x8527, ++ [18743] = 0x851C, [18744] = 0x84FB, [18745] = 0x852B, [18746] = 0x84FA, ++ [18747] = 0x8508, [18748] = 0x850C, [18749] = 0x84F4, [18750] = 0x852A, ++ [18751] = 0x84F2, [18752] = 0x8515, [18753] = 0x84F7, [18754] = 0x84EB, ++ [18755] = 0x84F3, [18756] = 0x84FC, [18757] = 0x8512, [18758] = 0x84EA, ++ [18759] = 0x84E9, [18760] = 0x8516, [18761] = 0x84FE, [18762] = 0x8528, ++ [18763] = 0x851D, [18764] = 0x852E, [18765] = 0x8502, [18766] = 0x84FD, ++ [18767] = 0x851E, [18768] = 0x84F6, [18769] = 0x8531, [18770] = 0x8526, ++ [18771] = 0x84E7, [18772] = 0x84E8, [18773] = 0x84F0, [18774] = 0x84EF, ++ [18775] = 0x84F9, [18776] = 0x8518, [18777] = 0x8520, [18778] = 0x8530, ++ [18779] = 0x850B, [18780] = 0x8519, [18781] = 0x852F, [18782] = 0x8662, ++ [18817] = 0x8756, [18818] = 0x8763, [18819] = 0x8764, [18820] = 0x8777, ++ [18821] = 0x87E1, [18822] = 0x8773, [18823] = 0x8758, [18824] = 0x8754, ++ [18825] = 0x875B, [18826] = 0x8752, [18827] = 0x8761, [18828] = 0x875A, ++ [18829] = 0x8751, [18830] = 0x875E, [18831] = 0x876D, [18832] = 0x876A, ++ [18833] = 0x8750, [18834] = 0x874E, [18835] = 0x875F, [18836] = 0x875D, ++ [18837] = 0x876F, [18838] = 0x876C, [18839] = 0x877A, [18840] = 0x876E, ++ [18841] = 0x875C, [18842] = 0x8765, [18843] = 0x874F, [18844] = 0x877B, ++ [18845] = 0x8775, [18846] = 0x8762, [18847] = 0x8767, [18848] = 0x8769, ++ [18849] = 0x885A, [18850] = 0x8905, [18851] = 0x890C, [18852] = 0x8914, ++ [18853] = 0x890B, [18854] = 0x8917, [18855] = 0x8918, [18856] = 0x8919, ++ [18857] = 0x8906, [18858] = 0x8916, [18859] = 0x8911, [18860] = 0x890E, ++ [18861] = 0x8909, [18862] = 0x89A2, [18863] = 0x89A4, [18864] = 0x89A3, ++ [18865] = 0x89ED, [18866] = 0x89F0, [18867] = 0x89EC, [18868] = 0x8ACF, ++ [18869] = 0x8AC6, [18870] = 0x8AB8, [18871] = 0x8AD3, [18872] = 0x8AD1, ++ [18873] = 0x8AD4, [18874] = 0x8AD5, [18875] = 0x8ABB, [18876] = 0x8AD7, ++ [18877] = 0x8ABE, [18878] = 0x8AC0, [18879] = 0x8AC5, [18880] = 0x8AD8, ++ [18881] = 0x8AC3, [18882] = 0x8ABA, [18883] = 0x8ABD, [18884] = 0x8AD9, ++ [18885] = 0x8C3E, [18886] = 0x8C4D, [18887] = 0x8C8F, [18888] = 0x8CE5, ++ [18889] = 0x8CDF, [18890] = 0x8CD9, [18891] = 0x8CE8, [18892] = 0x8CDA, ++ [18893] = 0x8CDD, [18894] = 0x8CE7, [18895] = 0x8DA0, [18896] = 0x8D9C, ++ [18897] = 0x8DA1, [18898] = 0x8D9B, [18899] = 0x8E20, [18900] = 0x8E23, ++ [18901] = 0x8E25, [18902] = 0x8E24, [18903] = 0x8E2E, [18904] = 0x8E15, ++ [18905] = 0x8E1B, [18906] = 0x8E16, [18907] = 0x8E11, [18908] = 0x8E19, ++ [18909] = 0x8E26, [18910] = 0x8E27, [18915] = 0x8E14, [18916] = 0x8E12, ++ [18917] = 0x8E18, [18918] = 0x8E13, [18919] = 0x8E1C, [18920] = 0x8E17, ++ [18921] = 0x8E1A, [18922] = 0x8F2C, [18923] = 0x8F24, [18924] = 0x8F18, ++ [18925] = 0x8F1A, [18926] = 0x8F20, [18927] = 0x8F23, [18928] = 0x8F16, ++ [18929] = 0x8F17, [18930] = 0x9073, [18931] = 0x9070, [18932] = 0x906F, ++ [18933] = 0x9067, [18934] = 0x906B, [18935] = 0x912F, [18936] = 0x912B, ++ [18937] = 0x9129, [18938] = 0x912A, [18939] = 0x9132, [18940] = 0x9126, ++ [18941] = 0x912E, [18942] = 0x9185, [18943] = 0x9186, [18944] = 0x918A, ++ [18945] = 0x9181, [18946] = 0x9182, [18947] = 0x9184, [18948] = 0x9180, ++ [18949] = 0x92D0, [18950] = 0x92C3, [18951] = 0x92C4, [18952] = 0x92C0, ++ [18953] = 0x92D9, [18954] = 0x92B6, [18955] = 0x92CF, [18956] = 0x92F1, ++ [18957] = 0x92DF, [18958] = 0x92D8, [18959] = 0x92E9, [18960] = 0x92D7, ++ [18961] = 0x92DD, [18962] = 0x92CC, [18963] = 0x92EF, [18964] = 0x92C2, ++ [18965] = 0x92E8, [18966] = 0x92CA, [18967] = 0x92C8, [18968] = 0x92CE, ++ [18969] = 0x92E6, [18970] = 0x92CD, [18971] = 0x92D5, [18972] = 0x92C9, ++ [18973] = 0x92E0, [18974] = 0x92DE, [18975] = 0x92E7, [18976] = 0x92D1, ++ [18977] = 0x92D3, [19012] = 0x92B5, [19013] = 0x92E1, [19014] = 0x92C6, ++ [19015] = 0x92B4, [19016] = 0x957C, [19017] = 0x95AC, [19018] = 0x95AB, ++ [19019] = 0x95AE, [19020] = 0x95B0, [19021] = 0x96A4, [19022] = 0x96A2, ++ [19023] = 0x96D3, [19024] = 0x9705, [19025] = 0x9708, [19026] = 0x9702, ++ [19027] = 0x975A, [19028] = 0x978A, [19029] = 0x978E, [19030] = 0x9788, ++ [19031] = 0x97D0, [19032] = 0x97CF, [19033] = 0x981E, [19034] = 0x981D, ++ [19035] = 0x9826, [19036] = 0x9829, [19037] = 0x9828, [19038] = 0x9820, ++ [19039] = 0x981B, [19040] = 0x9827, [19041] = 0x98B2, [19042] = 0x9908, ++ [19043] = 0x98FA, [19044] = 0x9911, [19045] = 0x9914, [19046] = 0x9916, ++ [19047] = 0x9917, [19048] = 0x9915, [19049] = 0x99DC, [19050] = 0x99CD, ++ [19051] = 0x99CF, [19052] = 0x99D3, [19053] = 0x99D4, [19054] = 0x99CE, ++ [19055] = 0x99C9, [19056] = 0x99D6, [19057] = 0x99D8, [19058] = 0x99CB, ++ [19059] = 0x99D7, [19060] = 0x99CC, [19061] = 0x9AB3, [19062] = 0x9AEC, ++ [19063] = 0x9AEB, [19064] = 0x9AF3, [19065] = 0x9AF2, [19066] = 0x9AF1, ++ [19067] = 0x9B46, [19068] = 0x9B43, [19069] = 0x9B67, [19070] = 0x9B74, ++ [19071] = 0x9B71, [19072] = 0x9B66, [19073] = 0x9B76, [19074] = 0x9B75, ++ [19075] = 0x9B70, [19076] = 0x9B68, [19077] = 0x9B64, [19078] = 0x9B6C, ++ [19079] = 0x9CFC, [19080] = 0x9CFA, [19081] = 0x9CFD, [19082] = 0x9CFF, ++ [19083] = 0x9CF7, [19084] = 0x9D07, [19085] = 0x9D00, [19086] = 0x9CF9, ++ [19087] = 0x9CFB, [19088] = 0x9D08, [19089] = 0x9D05, [19090] = 0x9D04, ++ [19091] = 0x9E83, [19092] = 0x9ED3, [19093] = 0x9F0F, [19094] = 0x9F10, ++ [19095] = 0x511C, [19096] = 0x5113, [19097] = 0x5117, [19098] = 0x511A, ++ [19099] = 0x5111, [19100] = 0x51DE, [19101] = 0x5334, [19102] = 0x53E1, ++ [19103] = 0x5670, [19104] = 0x5660, [19105] = 0x566E, [19110] = 0x5673, ++ [19111] = 0x5666, [19112] = 0x5663, [19113] = 0x566D, [19114] = 0x5672, ++ [19115] = 0x565E, [19116] = 0x5677, [19117] = 0x571C, [19118] = 0x571B, ++ [19119] = 0x58C8, [19120] = 0x58BD, [19121] = 0x58C9, [19122] = 0x58BF, ++ [19123] = 0x58BA, [19124] = 0x58C2, [19125] = 0x58BC, [19126] = 0x58C6, ++ [19127] = 0x5B17, [19128] = 0x5B19, [19129] = 0x5B1B, [19130] = 0x5B21, ++ [19131] = 0x5B14, [19132] = 0x5B13, [19133] = 0x5B10, [19134] = 0x5B16, ++ [19135] = 0x5B28, [19136] = 0x5B1A, [19137] = 0x5B20, [19138] = 0x5B1E, ++ [19139] = 0x5BEF, [19140] = 0x5DAC, [19141] = 0x5DB1, [19142] = 0x5DA9, ++ [19143] = 0x5DA7, [19144] = 0x5DB5, [19145] = 0x5DB0, [19146] = 0x5DAE, ++ [19147] = 0x5DAA, [19148] = 0x5DA8, [19149] = 0x5DB2, [19150] = 0x5DAD, ++ [19151] = 0x5DAF, [19152] = 0x5DB4, [19153] = 0x5E67, [19154] = 0x5E68, ++ [19155] = 0x5E66, [19156] = 0x5E6F, [19157] = 0x5EE9, [19158] = 0x5EE7, ++ [19159] = 0x5EE6, [19160] = 0x5EE8, [19161] = 0x5EE5, [19162] = 0x5F4B, ++ [19163] = 0x5FBC, [19164] = 0x619D, [19165] = 0x61A8, [19166] = 0x6196, ++ [19167] = 0x61C5, [19168] = 0x61B4, [19169] = 0x61C6, [19170] = 0x61C1, ++ [19171] = 0x61CC, [19172] = 0x61BA, [19207] = 0x61BF, [19208] = 0x61B8, ++ [19209] = 0x618C, [19210] = 0x64D7, [19211] = 0x64D6, [19212] = 0x64D0, ++ [19213] = 0x64CF, [19214] = 0x64C9, [19215] = 0x64BD, [19216] = 0x6489, ++ [19217] = 0x64C3, [19218] = 0x64DB, [19219] = 0x64F3, [19220] = 0x64D9, ++ [19221] = 0x6533, [19222] = 0x657F, [19223] = 0x657C, [19224] = 0x65A2, ++ [19225] = 0x66C8, [19226] = 0x66BE, [19227] = 0x66C0, [19228] = 0x66CA, ++ [19229] = 0x66CB, [19230] = 0x66CF, [19231] = 0x66BD, [19232] = 0x66BB, ++ [19233] = 0x66BA, [19234] = 0x66CC, [19235] = 0x6723, [19236] = 0x6A34, ++ [19237] = 0x6A66, [19238] = 0x6A49, [19239] = 0x6A67, [19240] = 0x6A32, ++ [19241] = 0x6A68, [19242] = 0x6A3E, [19243] = 0x6A5D, [19244] = 0x6A6D, ++ [19245] = 0x6A76, [19246] = 0x6A5B, [19247] = 0x6A51, [19248] = 0x6A28, ++ [19249] = 0x6A5A, [19250] = 0x6A3B, [19251] = 0x6A3F, [19252] = 0x6A41, ++ [19253] = 0x6A6A, [19254] = 0x6A64, [19255] = 0x6A50, [19256] = 0x6A4F, ++ [19257] = 0x6A54, [19258] = 0x6A6F, [19259] = 0x6A69, [19260] = 0x6A60, ++ [19261] = 0x6A3C, [19262] = 0x6A5E, [19263] = 0x6A56, [19264] = 0x6A55, ++ [19265] = 0x6A4D, [19266] = 0x6A4E, [19267] = 0x6A46, [19268] = 0x6B55, ++ [19269] = 0x6B54, [19270] = 0x6B56, [19271] = 0x6BA7, [19272] = 0x6BAA, ++ [19273] = 0x6BAB, [19274] = 0x6BC8, [19275] = 0x6BC7, [19276] = 0x6C04, ++ [19277] = 0x6C03, [19278] = 0x6C06, [19279] = 0x6FAD, [19280] = 0x6FCB, ++ [19281] = 0x6FA3, [19282] = 0x6FC7, [19283] = 0x6FBC, [19284] = 0x6FCE, ++ [19285] = 0x6FC8, [19286] = 0x6F5E, [19287] = 0x6FC4, [19288] = 0x6FBD, ++ [19289] = 0x6F9E, [19290] = 0x6FCA, [19291] = 0x6FA8, [19292] = 0x7004, ++ [19293] = 0x6FA5, [19294] = 0x6FAE, [19295] = 0x6FBA, [19296] = 0x6FAC, ++ [19297] = 0x6FAA, [19298] = 0x6FCF, [19299] = 0x6FBF, [19300] = 0x6FB8, ++ [19305] = 0x6FA2, [19306] = 0x6FC9, [19307] = 0x6FAB, [19308] = 0x6FCD, ++ [19309] = 0x6FAF, [19310] = 0x6FB2, [19311] = 0x6FB0, [19312] = 0x71C5, ++ [19313] = 0x71C2, [19314] = 0x71BF, [19315] = 0x71B8, [19316] = 0x71D6, ++ [19317] = 0x71C0, [19318] = 0x71C1, [19319] = 0x71CB, [19320] = 0x71D4, ++ [19321] = 0x71CA, [19322] = 0x71C7, [19323] = 0x71CF, [19324] = 0x71BD, ++ [19325] = 0x71D8, [19326] = 0x71BC, [19327] = 0x71C6, [19328] = 0x71DA, ++ [19329] = 0x71DB, [19330] = 0x729D, [19331] = 0x729E, [19332] = 0x7369, ++ [19333] = 0x7366, [19334] = 0x7367, [19335] = 0x736C, [19336] = 0x7365, ++ [19337] = 0x736B, [19338] = 0x736A, [19339] = 0x747F, [19340] = 0x749A, ++ [19341] = 0x74A0, [19342] = 0x7494, [19343] = 0x7492, [19344] = 0x7495, ++ [19345] = 0x74A1, [19346] = 0x750B, [19347] = 0x7580, [19348] = 0x762F, ++ [19349] = 0x762D, [19350] = 0x7631, [19351] = 0x763D, [19352] = 0x7633, ++ [19353] = 0x763C, [19354] = 0x7635, [19355] = 0x7632, [19356] = 0x7630, ++ [19357] = 0x76BB, [19358] = 0x76E6, [19359] = 0x779A, [19360] = 0x779D, ++ [19361] = 0x77A1, [19362] = 0x779C, [19363] = 0x779B, [19364] = 0x77A2, ++ [19365] = 0x77A3, [19366] = 0x7795, [19367] = 0x7799, [19402] = 0x7797, ++ [19403] = 0x78DD, [19404] = 0x78E9, [19405] = 0x78E5, [19406] = 0x78EA, ++ [19407] = 0x78DE, [19408] = 0x78E3, [19409] = 0x78DB, [19410] = 0x78E1, ++ [19411] = 0x78E2, [19412] = 0x78ED, [19413] = 0x78DF, [19414] = 0x78E0, ++ [19415] = 0x79A4, [19416] = 0x7A44, [19417] = 0x7A48, [19418] = 0x7A47, ++ [19419] = 0x7AB6, [19420] = 0x7AB8, [19421] = 0x7AB5, [19422] = 0x7AB1, ++ [19423] = 0x7AB7, [19424] = 0x7BDE, [19425] = 0x7BE3, [19426] = 0x7BE7, ++ [19427] = 0x7BDD, [19428] = 0x7BD5, [19429] = 0x7BE5, [19430] = 0x7BDA, ++ [19431] = 0x7BE8, [19432] = 0x7BF9, [19433] = 0x7BD4, [19434] = 0x7BEA, ++ [19435] = 0x7BE2, [19436] = 0x7BDC, [19437] = 0x7BEB, [19438] = 0x7BD8, ++ [19439] = 0x7BDF, [19440] = 0x7CD2, [19441] = 0x7CD4, [19442] = 0x7CD7, ++ [19443] = 0x7CD0, [19444] = 0x7CD1, [19445] = 0x7E12, [19446] = 0x7E21, ++ [19447] = 0x7E17, [19448] = 0x7E0C, [19449] = 0x7E1F, [19450] = 0x7E20, ++ [19451] = 0x7E13, [19452] = 0x7E0E, [19453] = 0x7E1C, [19454] = 0x7E15, ++ [19455] = 0x7E1A, [19456] = 0x7E22, [19457] = 0x7E0B, [19458] = 0x7E0F, ++ [19459] = 0x7E16, [19460] = 0x7E0D, [19461] = 0x7E14, [19462] = 0x7E25, ++ [19463] = 0x7E24, [19464] = 0x7F43, [19465] = 0x7F7B, [19466] = 0x7F7C, ++ [19467] = 0x7F7A, [19468] = 0x7FB1, [19469] = 0x7FEF, [19470] = 0x802A, ++ [19471] = 0x8029, [19472] = 0x806C, [19473] = 0x81B1, [19474] = 0x81A6, ++ [19475] = 0x81AE, [19476] = 0x81B9, [19477] = 0x81B5, [19478] = 0x81AB, ++ [19479] = 0x81B0, [19480] = 0x81AC, [19481] = 0x81B4, [19482] = 0x81B2, ++ [19483] = 0x81B7, [19484] = 0x81A7, [19485] = 0x81F2, [19486] = 0x8255, ++ [19487] = 0x8256, [19488] = 0x8257, [19489] = 0x8556, [19490] = 0x8545, ++ [19491] = 0x856B, [19492] = 0x854D, [19493] = 0x8553, [19494] = 0x8561, ++ [19495] = 0x8558, [19500] = 0x8540, [19501] = 0x8546, [19502] = 0x8564, ++ [19503] = 0x8541, [19504] = 0x8562, [19505] = 0x8544, [19506] = 0x8551, ++ [19507] = 0x8547, [19508] = 0x8563, [19509] = 0x853E, [19510] = 0x855B, ++ [19511] = 0x8571, [19512] = 0x854E, [19513] = 0x856E, [19514] = 0x8575, ++ [19515] = 0x8555, [19516] = 0x8567, [19517] = 0x8560, [19518] = 0x858C, ++ [19519] = 0x8566, [19520] = 0x855D, [19521] = 0x8554, [19522] = 0x8565, ++ [19523] = 0x856C, [19524] = 0x8663, [19525] = 0x8665, [19526] = 0x8664, ++ [19527] = 0x879B, [19528] = 0x878F, [19529] = 0x8797, [19530] = 0x8793, ++ [19531] = 0x8792, [19532] = 0x8788, [19533] = 0x8781, [19534] = 0x8796, ++ [19535] = 0x8798, [19536] = 0x8779, [19537] = 0x8787, [19538] = 0x87A3, ++ [19539] = 0x8785, [19540] = 0x8790, [19541] = 0x8791, [19542] = 0x879D, ++ [19543] = 0x8784, [19544] = 0x8794, [19545] = 0x879C, [19546] = 0x879A, ++ [19547] = 0x8789, [19548] = 0x891E, [19549] = 0x8926, [19550] = 0x8930, ++ [19551] = 0x892D, [19552] = 0x892E, [19553] = 0x8927, [19554] = 0x8931, ++ [19555] = 0x8922, [19556] = 0x8929, [19557] = 0x8923, [19558] = 0x892F, ++ [19559] = 0x892C, [19560] = 0x891F, [19561] = 0x89F1, [19562] = 0x8AE0, ++ [19597] = 0x8AE2, [19598] = 0x8AF2, [19599] = 0x8AF4, [19600] = 0x8AF5, ++ [19601] = 0x8ADD, [19602] = 0x8B14, [19603] = 0x8AE4, [19604] = 0x8ADF, ++ [19605] = 0x8AF0, [19606] = 0x8AC8, [19607] = 0x8ADE, [19608] = 0x8AE1, ++ [19609] = 0x8AE8, [19610] = 0x8AFF, [19611] = 0x8AEF, [19612] = 0x8AFB, ++ [19613] = 0x8C91, [19614] = 0x8C92, [19615] = 0x8C90, [19616] = 0x8CF5, ++ [19617] = 0x8CEE, [19618] = 0x8CF1, [19619] = 0x8CF0, [19620] = 0x8CF3, ++ [19621] = 0x8D6C, [19622] = 0x8D6E, [19623] = 0x8DA5, [19624] = 0x8DA7, ++ [19625] = 0x8E33, [19626] = 0x8E3E, [19627] = 0x8E38, [19628] = 0x8E40, ++ [19629] = 0x8E45, [19630] = 0x8E36, [19631] = 0x8E3C, [19632] = 0x8E3D, ++ [19633] = 0x8E41, [19634] = 0x8E30, [19635] = 0x8E3F, [19636] = 0x8EBD, ++ [19637] = 0x8F36, [19638] = 0x8F2E, [19639] = 0x8F35, [19640] = 0x8F32, ++ [19641] = 0x8F39, [19642] = 0x8F37, [19643] = 0x8F34, [19644] = 0x9076, ++ [19645] = 0x9079, [19646] = 0x907B, [19647] = 0x9086, [19648] = 0x90FA, ++ [19649] = 0x9133, [19650] = 0x9135, [19651] = 0x9136, [19652] = 0x9193, ++ [19653] = 0x9190, [19654] = 0x9191, [19655] = 0x918D, [19656] = 0x918F, ++ [19657] = 0x9327, [19658] = 0x931E, [19659] = 0x9308, [19660] = 0x931F, ++ [19661] = 0x9306, [19662] = 0x930F, [19663] = 0x937A, [19664] = 0x9338, ++ [19665] = 0x933C, [19666] = 0x931B, [19667] = 0x9323, [19668] = 0x9312, ++ [19669] = 0x9301, [19670] = 0x9346, [19671] = 0x932D, [19672] = 0x930E, ++ [19673] = 0x930D, [19674] = 0x92CB, [19675] = 0x931D, [19676] = 0x92FA, ++ [19677] = 0x9325, [19678] = 0x9313, [19679] = 0x92F9, [19680] = 0x92F7, ++ [19681] = 0x9334, [19682] = 0x9302, [19683] = 0x9324, [19684] = 0x92FF, ++ [19685] = 0x9329, [19686] = 0x9339, [19687] = 0x9335, [19688] = 0x932A, ++ [19689] = 0x9314, [19690] = 0x930C, [19695] = 0x930B, [19696] = 0x92FE, ++ [19697] = 0x9309, [19698] = 0x9300, [19699] = 0x92FB, [19700] = 0x9316, ++ [19701] = 0x95BC, [19702] = 0x95CD, [19703] = 0x95BE, [19704] = 0x95B9, ++ [19705] = 0x95BA, [19706] = 0x95B6, [19707] = 0x95BF, [19708] = 0x95B5, ++ [19709] = 0x95BD, [19710] = 0x96A9, [19711] = 0x96D4, [19712] = 0x970B, ++ [19713] = 0x9712, [19714] = 0x9710, [19715] = 0x9799, [19716] = 0x9797, ++ [19717] = 0x9794, [19718] = 0x97F0, [19719] = 0x97F8, [19720] = 0x9835, ++ [19721] = 0x982F, [19722] = 0x9832, [19723] = 0x9924, [19724] = 0x991F, ++ [19725] = 0x9927, [19726] = 0x9929, [19727] = 0x999E, [19728] = 0x99EE, ++ [19729] = 0x99EC, [19730] = 0x99E5, [19731] = 0x99E4, [19732] = 0x99F0, ++ [19733] = 0x99E3, [19734] = 0x99EA, [19735] = 0x99E9, [19736] = 0x99E7, ++ [19737] = 0x9AB9, [19738] = 0x9ABF, [19739] = 0x9AB4, [19740] = 0x9ABB, ++ [19741] = 0x9AF6, [19742] = 0x9AFA, [19743] = 0x9AF9, [19744] = 0x9AF7, ++ [19745] = 0x9B33, [19746] = 0x9B80, [19747] = 0x9B85, [19748] = 0x9B87, ++ [19749] = 0x9B7C, [19750] = 0x9B7E, [19751] = 0x9B7B, [19752] = 0x9B82, ++ [19753] = 0x9B93, [19754] = 0x9B92, [19755] = 0x9B90, [19756] = 0x9B7A, ++ [19757] = 0x9B95, [19792] = 0x9B7D, [19793] = 0x9B88, [19794] = 0x9D25, ++ [19795] = 0x9D17, [19796] = 0x9D20, [19797] = 0x9D1E, [19798] = 0x9D14, ++ [19799] = 0x9D29, [19800] = 0x9D1D, [19801] = 0x9D18, [19802] = 0x9D22, ++ [19803] = 0x9D10, [19804] = 0x9D19, [19805] = 0x9D1F, [19806] = 0x9E88, ++ [19807] = 0x9E86, [19808] = 0x9E87, [19809] = 0x9EAE, [19810] = 0x9EAD, ++ [19811] = 0x9ED5, [19812] = 0x9ED6, [19813] = 0x9EFA, [19814] = 0x9F12, ++ [19815] = 0x9F3D, [19816] = 0x5126, [19817] = 0x5125, [19818] = 0x5122, ++ [19819] = 0x5124, [19820] = 0x5120, [19821] = 0x5129, [19822] = 0x52F4, ++ [19823] = 0x5693, [19824] = 0x568C, [19825] = 0x568D, [19826] = 0x5686, ++ [19827] = 0x5684, [19828] = 0x5683, [19829] = 0x567E, [19830] = 0x5682, ++ [19831] = 0x567F, [19832] = 0x5681, [19833] = 0x58D6, [19834] = 0x58D4, ++ [19835] = 0x58CF, [19836] = 0x58D2, [19837] = 0x5B2D, [19838] = 0x5B25, ++ [19839] = 0x5B32, [19840] = 0x5B23, [19841] = 0x5B2C, [19842] = 0x5B27, ++ [19843] = 0x5B26, [19844] = 0x5B2F, [19845] = 0x5B2E, [19846] = 0x5B7B, ++ [19847] = 0x5BF1, [19848] = 0x5BF2, [19849] = 0x5DB7, [19850] = 0x5E6C, ++ [19851] = 0x5E6A, [19852] = 0x5FBE, [19853] = 0x5FBB, [19854] = 0x61C3, ++ [19855] = 0x61B5, [19856] = 0x61BC, [19857] = 0x61E7, [19858] = 0x61E0, ++ [19859] = 0x61E5, [19860] = 0x61E4, [19861] = 0x61E8, [19862] = 0x61DE, ++ [19863] = 0x64EF, [19864] = 0x64E9, [19865] = 0x64E3, [19866] = 0x64EB, ++ [19867] = 0x64E4, [19868] = 0x64E8, [19869] = 0x6581, [19870] = 0x6580, ++ [19871] = 0x65B6, [19872] = 0x65DA, [19873] = 0x66D2, [19874] = 0x6A8D, ++ [19875] = 0x6A96, [19876] = 0x6A81, [19877] = 0x6AA5, [19878] = 0x6A89, ++ [19879] = 0x6A9F, [19880] = 0x6A9B, [19881] = 0x6AA1, [19882] = 0x6A9E, ++ [19883] = 0x6A87, [19884] = 0x6A93, [19885] = 0x6A8E, [19890] = 0x6A95, ++ [19891] = 0x6A83, [19892] = 0x6AA8, [19893] = 0x6AA4, [19894] = 0x6A91, ++ [19895] = 0x6A7F, [19896] = 0x6AA6, [19897] = 0x6A9A, [19898] = 0x6A85, ++ [19899] = 0x6A8C, [19900] = 0x6A92, [19901] = 0x6B5B, [19902] = 0x6BAD, ++ [19903] = 0x6C09, [19904] = 0x6FCC, [19905] = 0x6FA9, [19906] = 0x6FF4, ++ [19907] = 0x6FD4, [19908] = 0x6FE3, [19909] = 0x6FDC, [19910] = 0x6FED, ++ [19911] = 0x6FE7, [19912] = 0x6FE6, [19913] = 0x6FDE, [19914] = 0x6FF2, ++ [19915] = 0x6FDD, [19916] = 0x6FE2, [19917] = 0x6FE8, [19918] = 0x71E1, ++ [19919] = 0x71F1, [19920] = 0x71E8, [19921] = 0x71F2, [19922] = 0x71E4, ++ [19923] = 0x71F0, [19924] = 0x71E2, [19925] = 0x7373, [19926] = 0x736E, ++ [19927] = 0x736F, [19928] = 0x7497, [19929] = 0x74B2, [19930] = 0x74AB, ++ [19931] = 0x7490, [19932] = 0x74AA, [19933] = 0x74AD, [19934] = 0x74B1, ++ [19935] = 0x74A5, [19936] = 0x74AF, [19937] = 0x7510, [19938] = 0x7511, ++ [19939] = 0x7512, [19940] = 0x750F, [19941] = 0x7584, [19942] = 0x7643, ++ [19943] = 0x7648, [19944] = 0x7649, [19945] = 0x7647, [19946] = 0x76A4, ++ [19947] = 0x76E9, [19948] = 0x77B5, [19949] = 0x77AB, [19950] = 0x77B2, ++ [19951] = 0x77B7, [19952] = 0x77B6, [19987] = 0x77B4, [19988] = 0x77B1, ++ [19989] = 0x77A8, [19990] = 0x77F0, [19991] = 0x78F3, [19992] = 0x78FD, ++ [19993] = 0x7902, [19994] = 0x78FB, [19995] = 0x78FC, [19996] = 0x78F2, ++ [19997] = 0x7905, [19998] = 0x78F9, [19999] = 0x78FE, [20000] = 0x7904, ++ [20001] = 0x79AB, [20002] = 0x79A8, [20003] = 0x7A5C, [20004] = 0x7A5B, ++ [20005] = 0x7A56, [20006] = 0x7A58, [20007] = 0x7A54, [20008] = 0x7A5A, ++ [20009] = 0x7ABE, [20010] = 0x7AC0, [20011] = 0x7AC1, [20012] = 0x7C05, ++ [20013] = 0x7C0F, [20014] = 0x7BF2, [20015] = 0x7C00, [20016] = 0x7BFF, ++ [20017] = 0x7BFB, [20018] = 0x7C0E, [20019] = 0x7BF4, [20020] = 0x7C0B, ++ [20021] = 0x7BF3, [20022] = 0x7C02, [20023] = 0x7C09, [20024] = 0x7C03, ++ [20025] = 0x7C01, [20026] = 0x7BF8, [20027] = 0x7BFD, [20028] = 0x7C06, ++ [20029] = 0x7BF0, [20030] = 0x7BF1, [20031] = 0x7C10, [20032] = 0x7C0A, ++ [20033] = 0x7CE8, [20034] = 0x7E2D, [20035] = 0x7E3C, [20036] = 0x7E42, ++ [20037] = 0x7E33, [20038] = 0x9848, [20039] = 0x7E38, [20040] = 0x7E2A, ++ [20041] = 0x7E49, [20042] = 0x7E40, [20043] = 0x7E47, [20044] = 0x7E29, ++ [20045] = 0x7E4C, [20046] = 0x7E30, [20047] = 0x7E3B, [20048] = 0x7E36, ++ [20049] = 0x7E44, [20050] = 0x7E3A, [20051] = 0x7F45, [20052] = 0x7F7F, ++ [20053] = 0x7F7E, [20054] = 0x7F7D, [20055] = 0x7FF4, [20056] = 0x7FF2, ++ [20057] = 0x802C, [20058] = 0x81BB, [20059] = 0x81C4, [20060] = 0x81CC, ++ [20061] = 0x81CA, [20062] = 0x81C5, [20063] = 0x81C7, [20064] = 0x81BC, ++ [20065] = 0x81E9, [20066] = 0x825B, [20067] = 0x825A, [20068] = 0x825C, ++ [20069] = 0x8583, [20070] = 0x8580, [20071] = 0x858F, [20072] = 0x85A7, ++ [20073] = 0x8595, [20074] = 0x85A0, [20075] = 0x858B, [20076] = 0x85A3, ++ [20077] = 0x857B, [20078] = 0x85A4, [20079] = 0x859A, [20080] = 0x859E, ++ [20085] = 0x8577, [20086] = 0x857C, [20087] = 0x8589, [20088] = 0x85A1, ++ [20089] = 0x857A, [20090] = 0x8578, [20091] = 0x8557, [20092] = 0x858E, ++ [20093] = 0x8596, [20094] = 0x8586, [20095] = 0x858D, [20096] = 0x8599, ++ [20097] = 0x859D, [20098] = 0x8581, [20099] = 0x85A2, [20100] = 0x8582, ++ [20101] = 0x8588, [20102] = 0x8585, [20103] = 0x8579, [20104] = 0x8576, ++ [20105] = 0x8598, [20106] = 0x8590, [20107] = 0x859F, [20108] = 0x8668, ++ [20109] = 0x87BE, [20110] = 0x87AA, [20111] = 0x87AD, [20112] = 0x87C5, ++ [20113] = 0x87B0, [20114] = 0x87AC, [20115] = 0x87B9, [20116] = 0x87B5, ++ [20117] = 0x87BC, [20118] = 0x87AE, [20119] = 0x87C9, [20120] = 0x87C3, ++ [20121] = 0x87C2, [20122] = 0x87CC, [20123] = 0x87B7, [20124] = 0x87AF, ++ [20125] = 0x87C4, [20126] = 0x87CA, [20127] = 0x87B4, [20128] = 0x87B6, ++ [20129] = 0x87BF, [20130] = 0x87B8, [20131] = 0x87BD, [20132] = 0x87DE, ++ [20133] = 0x87B2, [20134] = 0x8935, [20135] = 0x8933, [20136] = 0x893C, ++ [20137] = 0x893E, [20138] = 0x8941, [20139] = 0x8952, [20140] = 0x8937, ++ [20141] = 0x8942, [20142] = 0x89AD, [20143] = 0x89AF, [20144] = 0x89AE, ++ [20145] = 0x89F2, [20146] = 0x89F3, [20147] = 0x8B1E, [20182] = 0x8B18, ++ [20183] = 0x8B16, [20184] = 0x8B11, [20185] = 0x8B05, [20186] = 0x8B0B, ++ [20187] = 0x8B22, [20188] = 0x8B0F, [20189] = 0x8B12, [20190] = 0x8B15, ++ [20191] = 0x8B07, [20192] = 0x8B0D, [20193] = 0x8B08, [20194] = 0x8B06, ++ [20195] = 0x8B1C, [20196] = 0x8B13, [20197] = 0x8B1A, [20198] = 0x8C4F, ++ [20199] = 0x8C70, [20200] = 0x8C72, [20201] = 0x8C71, [20202] = 0x8C6F, ++ [20203] = 0x8C95, [20204] = 0x8C94, [20205] = 0x8CF9, [20206] = 0x8D6F, ++ [20207] = 0x8E4E, [20208] = 0x8E4D, [20209] = 0x8E53, [20210] = 0x8E50, ++ [20211] = 0x8E4C, [20212] = 0x8E47, [20213] = 0x8F43, [20214] = 0x8F40, ++ [20215] = 0x9085, [20216] = 0x907E, [20217] = 0x9138, [20218] = 0x919A, ++ [20219] = 0x91A2, [20220] = 0x919B, [20221] = 0x9199, [20222] = 0x919F, ++ [20223] = 0x91A1, [20224] = 0x919D, [20225] = 0x91A0, [20226] = 0x93A1, ++ [20227] = 0x9383, [20228] = 0x93AF, [20229] = 0x9364, [20230] = 0x9356, ++ [20231] = 0x9347, [20232] = 0x937C, [20233] = 0x9358, [20234] = 0x935C, ++ [20235] = 0x9376, [20236] = 0x9349, [20237] = 0x9350, [20238] = 0x9351, ++ [20239] = 0x9360, [20240] = 0x936D, [20241] = 0x938F, [20242] = 0x934C, ++ [20243] = 0x936A, [20244] = 0x9379, [20245] = 0x9357, [20246] = 0x9355, ++ [20247] = 0x9352, [20248] = 0x934F, [20249] = 0x9371, [20250] = 0x9377, ++ [20251] = 0x937B, [20252] = 0x9361, [20253] = 0x935E, [20254] = 0x9363, ++ [20255] = 0x9367, [20256] = 0x9380, [20257] = 0x934E, [20258] = 0x9359, ++ [20259] = 0x95C7, [20260] = 0x95C0, [20261] = 0x95C9, [20262] = 0x95C3, ++ [20263] = 0x95C5, [20264] = 0x95B7, [20265] = 0x96AE, [20266] = 0x96B0, ++ [20267] = 0x96AC, [20268] = 0x9720, [20269] = 0x971F, [20270] = 0x9718, ++ [20271] = 0x971D, [20272] = 0x9719, [20273] = 0x979A, [20274] = 0x97A1, ++ [20275] = 0x979C, [20280] = 0x979E, [20281] = 0x979D, [20282] = 0x97D5, ++ [20283] = 0x97D4, [20284] = 0x97F1, [20285] = 0x9841, [20286] = 0x9844, ++ [20287] = 0x984A, [20288] = 0x9849, [20289] = 0x9845, [20290] = 0x9843, ++ [20291] = 0x9925, [20292] = 0x992B, [20293] = 0x992C, [20294] = 0x992A, ++ [20295] = 0x9933, [20296] = 0x9932, [20297] = 0x992F, [20298] = 0x992D, ++ [20299] = 0x9931, [20300] = 0x9930, [20301] = 0x9998, [20302] = 0x99A3, ++ [20303] = 0x99A1, [20304] = 0x9A02, [20305] = 0x99FA, [20306] = 0x99F4, ++ [20307] = 0x99F7, [20308] = 0x99F9, [20309] = 0x99F8, [20310] = 0x99F6, ++ [20311] = 0x99FB, [20312] = 0x99FD, [20313] = 0x99FE, [20314] = 0x99FC, ++ [20315] = 0x9A03, [20316] = 0x9ABE, [20317] = 0x9AFE, [20318] = 0x9AFD, ++ [20319] = 0x9B01, [20320] = 0x9AFC, [20321] = 0x9B48, [20322] = 0x9B9A, ++ [20323] = 0x9BA8, [20324] = 0x9B9E, [20325] = 0x9B9B, [20326] = 0x9BA6, ++ [20327] = 0x9BA1, [20328] = 0x9BA5, [20329] = 0x9BA4, [20330] = 0x9B86, ++ [20331] = 0x9BA2, [20332] = 0x9BA0, [20333] = 0x9BAF, [20334] = 0x9D33, ++ [20335] = 0x9D41, [20336] = 0x9D67, [20337] = 0x9D36, [20338] = 0x9D2E, ++ [20339] = 0x9D2F, [20340] = 0x9D31, [20341] = 0x9D38, [20342] = 0x9D30, ++ [20377] = 0x9D45, [20378] = 0x9D42, [20379] = 0x9D43, [20380] = 0x9D3E, ++ [20381] = 0x9D37, [20382] = 0x9D40, [20383] = 0x9D3D, [20384] = 0x7FF5, ++ [20385] = 0x9D2D, [20386] = 0x9E8A, [20387] = 0x9E89, [20388] = 0x9E8D, ++ [20389] = 0x9EB0, [20390] = 0x9EC8, [20391] = 0x9EDA, [20392] = 0x9EFB, ++ [20393] = 0x9EFF, [20394] = 0x9F24, [20395] = 0x9F23, [20396] = 0x9F22, ++ [20397] = 0x9F54, [20398] = 0x9FA0, [20399] = 0x5131, [20400] = 0x512D, ++ [20401] = 0x512E, [20402] = 0x5698, [20403] = 0x569C, [20404] = 0x5697, ++ [20405] = 0x569A, [20406] = 0x569D, [20407] = 0x5699, [20408] = 0x5970, ++ [20409] = 0x5B3C, [20410] = 0x5C69, [20411] = 0x5C6A, [20412] = 0x5DC0, ++ [20413] = 0x5E6D, [20414] = 0x5E6E, [20415] = 0x61D8, [20416] = 0x61DF, ++ [20417] = 0x61ED, [20418] = 0x61EE, [20419] = 0x61F1, [20420] = 0x61EA, ++ [20421] = 0x61F0, [20422] = 0x61EB, [20423] = 0x61D6, [20424] = 0x61E9, ++ [20425] = 0x64FF, [20426] = 0x6504, [20427] = 0x64FD, [20428] = 0x64F8, ++ [20429] = 0x6501, [20430] = 0x6503, [20431] = 0x64FC, [20432] = 0x6594, ++ [20433] = 0x65DB, [20434] = 0x66DA, [20435] = 0x66DB, [20436] = 0x66D8, ++ [20437] = 0x6AC5, [20438] = 0x6AB9, [20439] = 0x6ABD, [20440] = 0x6AE1, ++ [20441] = 0x6AC6, [20442] = 0x6ABA, [20443] = 0x6AB6, [20444] = 0x6AB7, ++ [20445] = 0x6AC7, [20446] = 0x6AB4, [20447] = 0x6AAD, [20448] = 0x6B5E, ++ [20449] = 0x6BC9, [20450] = 0x6C0B, [20451] = 0x7007, [20452] = 0x700C, ++ [20453] = 0x700D, [20454] = 0x7001, [20455] = 0x7005, [20456] = 0x7014, ++ [20457] = 0x700E, [20458] = 0x6FFF, [20459] = 0x7000, [20460] = 0x6FFB, ++ [20461] = 0x7026, [20462] = 0x6FFC, [20463] = 0x6FF7, [20464] = 0x700A, ++ [20465] = 0x7201, [20466] = 0x71FF, [20467] = 0x71F9, [20468] = 0x7203, ++ [20469] = 0x71FD, [20470] = 0x7376, [20475] = 0x74B8, [20476] = 0x74C0, ++ [20477] = 0x74B5, [20478] = 0x74C1, [20479] = 0x74BE, [20480] = 0x74B6, ++ [20481] = 0x74BB, [20482] = 0x74C2, [20483] = 0x7514, [20484] = 0x7513, ++ [20485] = 0x765C, [20486] = 0x7664, [20487] = 0x7659, [20488] = 0x7650, ++ [20489] = 0x7653, [20490] = 0x7657, [20491] = 0x765A, [20492] = 0x76A6, ++ [20493] = 0x76BD, [20494] = 0x76EC, [20495] = 0x77C2, [20496] = 0x77BA, ++ [20497] = 0x78FF, [20498] = 0x790C, [20499] = 0x7913, [20500] = 0x7914, ++ [20501] = 0x7909, [20502] = 0x7910, [20503] = 0x7912, [20504] = 0x7911, ++ [20505] = 0x79AD, [20506] = 0x79AC, [20507] = 0x7A5F, [20508] = 0x7C1C, ++ [20509] = 0x7C29, [20510] = 0x7C19, [20511] = 0x7C20, [20512] = 0x7C1F, ++ [20513] = 0x7C2D, [20514] = 0x7C1D, [20515] = 0x7C26, [20516] = 0x7C28, ++ [20517] = 0x7C22, [20518] = 0x7C25, [20519] = 0x7C30, [20520] = 0x7E5C, ++ [20521] = 0x7E50, [20522] = 0x7E56, [20523] = 0x7E63, [20524] = 0x7E58, ++ [20525] = 0x7E62, [20526] = 0x7E5F, [20527] = 0x7E51, [20528] = 0x7E60, ++ [20529] = 0x7E57, [20530] = 0x7E53, [20531] = 0x7FB5, [20532] = 0x7FB3, ++ [20533] = 0x7FF7, [20534] = 0x7FF8, [20535] = 0x8075, [20536] = 0x81D1, ++ [20537] = 0x81D2, [20572] = 0x81D0, [20573] = 0x825F, [20574] = 0x825E, ++ [20575] = 0x85B4, [20576] = 0x85C6, [20577] = 0x85C0, [20578] = 0x85C3, ++ [20579] = 0x85C2, [20580] = 0x85B3, [20581] = 0x85B5, [20582] = 0x85BD, ++ [20583] = 0x85C7, [20584] = 0x85C4, [20585] = 0x85BF, [20586] = 0x85CB, ++ [20587] = 0x85CE, [20588] = 0x85C8, [20589] = 0x85C5, [20590] = 0x85B1, ++ [20591] = 0x85B6, [20592] = 0x85D2, [20593] = 0x8624, [20594] = 0x85B8, ++ [20595] = 0x85B7, [20596] = 0x85BE, [20597] = 0x8669, [20598] = 0x87E7, ++ [20599] = 0x87E6, [20600] = 0x87E2, [20601] = 0x87DB, [20602] = 0x87EB, ++ [20603] = 0x87EA, [20604] = 0x87E5, [20605] = 0x87DF, [20606] = 0x87F3, ++ [20607] = 0x87E4, [20608] = 0x87D4, [20609] = 0x87DC, [20610] = 0x87D3, ++ [20611] = 0x87ED, [20612] = 0x87D8, [20613] = 0x87E3, [20614] = 0x87A4, ++ [20615] = 0x87D7, [20616] = 0x87D9, [20617] = 0x8801, [20618] = 0x87F4, ++ [20619] = 0x87E8, [20620] = 0x87DD, [20621] = 0x8953, [20622] = 0x894B, ++ [20623] = 0x894F, [20624] = 0x894C, [20625] = 0x8946, [20626] = 0x8950, ++ [20627] = 0x8951, [20628] = 0x8949, [20629] = 0x8B2A, [20630] = 0x8B27, ++ [20631] = 0x8B23, [20632] = 0x8B33, [20633] = 0x8B30, [20634] = 0x8B35, ++ [20635] = 0x8B47, [20636] = 0x8B2F, [20637] = 0x8B3C, [20638] = 0x8B3E, ++ [20639] = 0x8B31, [20640] = 0x8B25, [20641] = 0x8B37, [20642] = 0x8B26, ++ [20643] = 0x8B36, [20644] = 0x8B2E, [20645] = 0x8B24, [20646] = 0x8B3B, ++ [20647] = 0x8B3D, [20648] = 0x8B3A, [20649] = 0x8C42, [20650] = 0x8C75, ++ [20651] = 0x8C99, [20652] = 0x8C98, [20653] = 0x8C97, [20654] = 0x8CFE, ++ [20655] = 0x8D04, [20656] = 0x8D02, [20657] = 0x8D00, [20658] = 0x8E5C, ++ [20659] = 0x8E62, [20660] = 0x8E60, [20661] = 0x8E57, [20662] = 0x8E56, ++ [20663] = 0x8E5E, [20664] = 0x8E65, [20665] = 0x8E67, [20670] = 0x8E5B, ++ [20671] = 0x8E5A, [20672] = 0x8E61, [20673] = 0x8E5D, [20674] = 0x8E69, ++ [20675] = 0x8E54, [20676] = 0x8F46, [20677] = 0x8F47, [20678] = 0x8F48, ++ [20679] = 0x8F4B, [20680] = 0x9128, [20681] = 0x913A, [20682] = 0x913B, ++ [20683] = 0x913E, [20684] = 0x91A8, [20685] = 0x91A5, [20686] = 0x91A7, ++ [20687] = 0x91AF, [20688] = 0x91AA, [20689] = 0x93B5, [20690] = 0x938C, ++ [20691] = 0x9392, [20692] = 0x93B7, [20693] = 0x939B, [20694] = 0x939D, ++ [20695] = 0x9389, [20696] = 0x93A7, [20697] = 0x938E, [20698] = 0x93AA, ++ [20699] = 0x939E, [20700] = 0x93A6, [20701] = 0x9395, [20702] = 0x9388, ++ [20703] = 0x9399, [20704] = 0x939F, [20705] = 0x938D, [20706] = 0x93B1, ++ [20707] = 0x9391, [20708] = 0x93B2, [20709] = 0x93A4, [20710] = 0x93A8, ++ [20711] = 0x93B4, [20712] = 0x93A3, [20713] = 0x93A5, [20714] = 0x95D2, ++ [20715] = 0x95D3, [20716] = 0x95D1, [20717] = 0x96B3, [20718] = 0x96D7, ++ [20719] = 0x96DA, [20720] = 0x5DC2, [20721] = 0x96DF, [20722] = 0x96D8, ++ [20723] = 0x96DD, [20724] = 0x9723, [20725] = 0x9722, [20726] = 0x9725, ++ [20727] = 0x97AC, [20728] = 0x97AE, [20729] = 0x97A8, [20730] = 0x97AB, ++ [20731] = 0x97A4, [20732] = 0x97AA, [20767] = 0x97A2, [20768] = 0x97A5, ++ [20769] = 0x97D7, [20770] = 0x97D9, [20771] = 0x97D6, [20772] = 0x97D8, ++ [20773] = 0x97FA, [20774] = 0x9850, [20775] = 0x9851, [20776] = 0x9852, ++ [20777] = 0x98B8, [20778] = 0x9941, [20779] = 0x993C, [20780] = 0x993A, ++ [20781] = 0x9A0F, [20782] = 0x9A0B, [20783] = 0x9A09, [20784] = 0x9A0D, ++ [20785] = 0x9A04, [20786] = 0x9A11, [20787] = 0x9A0A, [20788] = 0x9A05, ++ [20789] = 0x9A07, [20790] = 0x9A06, [20791] = 0x9AC0, [20792] = 0x9ADC, ++ [20793] = 0x9B08, [20794] = 0x9B04, [20795] = 0x9B05, [20796] = 0x9B29, ++ [20797] = 0x9B35, [20798] = 0x9B4A, [20799] = 0x9B4C, [20800] = 0x9B4B, ++ [20801] = 0x9BC7, [20802] = 0x9BC6, [20803] = 0x9BC3, [20804] = 0x9BBF, ++ [20805] = 0x9BC1, [20806] = 0x9BB5, [20807] = 0x9BB8, [20808] = 0x9BD3, ++ [20809] = 0x9BB6, [20810] = 0x9BC4, [20811] = 0x9BB9, [20812] = 0x9BBD, ++ [20813] = 0x9D5C, [20814] = 0x9D53, [20815] = 0x9D4F, [20816] = 0x9D4A, ++ [20817] = 0x9D5B, [20818] = 0x9D4B, [20819] = 0x9D59, [20820] = 0x9D56, ++ [20821] = 0x9D4C, [20822] = 0x9D57, [20823] = 0x9D52, [20824] = 0x9D54, ++ [20825] = 0x9D5F, [20826] = 0x9D58, [20827] = 0x9D5A, [20828] = 0x9E8E, ++ [20829] = 0x9E8C, [20830] = 0x9EDF, [20831] = 0x9F01, [20832] = 0x9F00, ++ [20833] = 0x9F16, [20834] = 0x9F25, [20835] = 0x9F2B, [20836] = 0x9F2A, ++ [20837] = 0x9F29, [20838] = 0x9F28, [20839] = 0x9F4C, [20840] = 0x9F55, ++ [20841] = 0x5134, [20842] = 0x5135, [20843] = 0x5296, [20844] = 0x52F7, ++ [20845] = 0x53B4, [20846] = 0x56AB, [20847] = 0x56AD, [20848] = 0x56A6, ++ [20849] = 0x56A7, [20850] = 0x56AA, [20851] = 0x56AC, [20852] = 0x58DA, ++ [20853] = 0x58DD, [20854] = 0x58DB, [20855] = 0x5912, [20856] = 0x5B3D, ++ [20857] = 0x5B3E, [20858] = 0x5B3F, [20859] = 0x5DC3, [20860] = 0x5E70, ++ [20865] = 0x5FBF, [20866] = 0x61FB, [20867] = 0x6507, [20868] = 0x6510, ++ [20869] = 0x650D, [20870] = 0x6509, [20871] = 0x650C, [20872] = 0x650E, ++ [20873] = 0x6584, [20874] = 0x65DE, [20875] = 0x65DD, [20876] = 0x66DE, ++ [20877] = 0x6AE7, [20878] = 0x6AE0, [20879] = 0x6ACC, [20880] = 0x6AD1, ++ [20881] = 0x6AD9, [20882] = 0x6ACB, [20883] = 0x6ADF, [20884] = 0x6ADC, ++ [20885] = 0x6AD0, [20886] = 0x6AEB, [20887] = 0x6ACF, [20888] = 0x6ACD, ++ [20889] = 0x6ADE, [20890] = 0x6B60, [20891] = 0x6BB0, [20892] = 0x6C0C, ++ [20893] = 0x7019, [20894] = 0x7027, [20895] = 0x7020, [20896] = 0x7016, ++ [20897] = 0x702B, [20898] = 0x7021, [20899] = 0x7022, [20900] = 0x7023, ++ [20901] = 0x7029, [20902] = 0x7017, [20903] = 0x7024, [20904] = 0x701C, ++ [20905] = 0x702A, [20906] = 0x720C, [20907] = 0x720A, [20908] = 0x7207, ++ [20909] = 0x7202, [20910] = 0x7205, [20911] = 0x72A5, [20912] = 0x72A6, ++ [20913] = 0x72A4, [20914] = 0x72A3, [20915] = 0x72A1, [20916] = 0x74CB, ++ [20917] = 0x74C5, [20918] = 0x74B7, [20919] = 0x74C3, [20920] = 0x7516, ++ [20921] = 0x7660, [20922] = 0x77C9, [20923] = 0x77CA, [20924] = 0x77C4, ++ [20925] = 0x77F1, [20926] = 0x791D, [20927] = 0x791B, [20962] = 0x7921, ++ [20963] = 0x791C, [20964] = 0x7917, [20965] = 0x791E, [20966] = 0x79B0, ++ [20967] = 0x7A67, [20968] = 0x7A68, [20969] = 0x7C33, [20970] = 0x7C3C, ++ [20971] = 0x7C39, [20972] = 0x7C2C, [20973] = 0x7C3B, [20974] = 0x7CEC, ++ [20975] = 0x7CEA, [20976] = 0x7E76, [20977] = 0x7E75, [20978] = 0x7E78, ++ [20979] = 0x7E70, [20980] = 0x7E77, [20981] = 0x7E6F, [20982] = 0x7E7A, ++ [20983] = 0x7E72, [20984] = 0x7E74, [20985] = 0x7E68, [20986] = 0x7F4B, ++ [20987] = 0x7F4A, [20988] = 0x7F83, [20989] = 0x7F86, [20990] = 0x7FB7, ++ [20991] = 0x7FFD, [20992] = 0x7FFE, [20993] = 0x8078, [20994] = 0x81D7, ++ [20995] = 0x81D5, [20996] = 0x8264, [20997] = 0x8261, [20998] = 0x8263, ++ [20999] = 0x85EB, [21000] = 0x85F1, [21001] = 0x85ED, [21002] = 0x85D9, ++ [21003] = 0x85E1, [21004] = 0x85E8, [21005] = 0x85DA, [21006] = 0x85D7, ++ [21007] = 0x85EC, [21008] = 0x85F2, [21009] = 0x85F8, [21010] = 0x85D8, ++ [21011] = 0x85DF, [21012] = 0x85E3, [21013] = 0x85DC, [21014] = 0x85D1, ++ [21015] = 0x85F0, [21016] = 0x85E6, [21017] = 0x85EF, [21018] = 0x85DE, ++ [21019] = 0x85E2, [21020] = 0x8800, [21021] = 0x87FA, [21022] = 0x8803, ++ [21023] = 0x87F6, [21024] = 0x87F7, [21025] = 0x8809, [21026] = 0x880C, ++ [21027] = 0x880B, [21028] = 0x8806, [21029] = 0x87FC, [21030] = 0x8808, ++ [21031] = 0x87FF, [21032] = 0x880A, [21033] = 0x8802, [21034] = 0x8962, ++ [21035] = 0x895A, [21036] = 0x895B, [21037] = 0x8957, [21038] = 0x8961, ++ [21039] = 0x895C, [21040] = 0x8958, [21041] = 0x895D, [21042] = 0x8959, ++ [21043] = 0x8988, [21044] = 0x89B7, [21045] = 0x89B6, [21046] = 0x89F6, ++ [21047] = 0x8B50, [21048] = 0x8B48, [21049] = 0x8B4A, [21050] = 0x8B40, ++ [21051] = 0x8B53, [21052] = 0x8B56, [21053] = 0x8B54, [21054] = 0x8B4B, ++ [21055] = 0x8B55, [21060] = 0x8B51, [21061] = 0x8B42, [21062] = 0x8B52, ++ [21063] = 0x8B57, [21064] = 0x8C43, [21065] = 0x8C77, [21066] = 0x8C76, ++ [21067] = 0x8C9A, [21068] = 0x8D06, [21069] = 0x8D07, [21070] = 0x8D09, ++ [21071] = 0x8DAC, [21072] = 0x8DAA, [21073] = 0x8DAD, [21074] = 0x8DAB, ++ [21075] = 0x8E6D, [21076] = 0x8E78, [21077] = 0x8E73, [21078] = 0x8E6A, ++ [21079] = 0x8E6F, [21080] = 0x8E7B, [21081] = 0x8EC2, [21082] = 0x8F52, ++ [21083] = 0x8F51, [21084] = 0x8F4F, [21085] = 0x8F50, [21086] = 0x8F53, ++ [21087] = 0x8FB4, [21088] = 0x9140, [21089] = 0x913F, [21090] = 0x91B0, ++ [21091] = 0x91AD, [21092] = 0x93DE, [21093] = 0x93C7, [21094] = 0x93CF, ++ [21095] = 0x93C2, [21096] = 0x93DA, [21097] = 0x93D0, [21098] = 0x93F9, ++ [21099] = 0x93EC, [21100] = 0x93CC, [21101] = 0x93D9, [21102] = 0x93A9, ++ [21103] = 0x93E6, [21104] = 0x93CA, [21105] = 0x93D4, [21106] = 0x93EE, ++ [21107] = 0x93E3, [21108] = 0x93D5, [21109] = 0x93C4, [21110] = 0x93CE, ++ [21111] = 0x93C0, [21112] = 0x93D2, [21113] = 0x93E7, [21114] = 0x957D, ++ [21115] = 0x95DA, [21116] = 0x95DB, [21117] = 0x96E1, [21118] = 0x9729, ++ [21119] = 0x972B, [21120] = 0x972C, [21121] = 0x9728, [21122] = 0x9726, ++ [21157] = 0x97B3, [21158] = 0x97B7, [21159] = 0x97B6, [21160] = 0x97DD, ++ [21161] = 0x97DE, [21162] = 0x97DF, [21163] = 0x985C, [21164] = 0x9859, ++ [21165] = 0x985D, [21166] = 0x9857, [21167] = 0x98BF, [21168] = 0x98BD, ++ [21169] = 0x98BB, [21170] = 0x98BE, [21171] = 0x9948, [21172] = 0x9947, ++ [21173] = 0x9943, [21174] = 0x99A6, [21175] = 0x99A7, [21176] = 0x9A1A, ++ [21177] = 0x9A15, [21178] = 0x9A25, [21179] = 0x9A1D, [21180] = 0x9A24, ++ [21181] = 0x9A1B, [21182] = 0x9A22, [21183] = 0x9A20, [21184] = 0x9A27, ++ [21185] = 0x9A23, [21186] = 0x9A1E, [21187] = 0x9A1C, [21188] = 0x9A14, ++ [21189] = 0x9AC2, [21190] = 0x9B0B, [21191] = 0x9B0A, [21192] = 0x9B0E, ++ [21193] = 0x9B0C, [21194] = 0x9B37, [21195] = 0x9BEA, [21196] = 0x9BEB, ++ [21197] = 0x9BE0, [21198] = 0x9BDE, [21199] = 0x9BE4, [21200] = 0x9BE6, ++ [21201] = 0x9BE2, [21202] = 0x9BF0, [21203] = 0x9BD4, [21204] = 0x9BD7, ++ [21205] = 0x9BEC, [21206] = 0x9BDC, [21207] = 0x9BD9, [21208] = 0x9BE5, ++ [21209] = 0x9BD5, [21210] = 0x9BE1, [21211] = 0x9BDA, [21212] = 0x9D77, ++ [21213] = 0x9D81, [21214] = 0x9D8A, [21215] = 0x9D84, [21216] = 0x9D88, ++ [21217] = 0x9D71, [21218] = 0x9D80, [21219] = 0x9D78, [21220] = 0x9D86, ++ [21221] = 0x9D8B, [21222] = 0x9D8C, [21223] = 0x9D7D, [21224] = 0x9D6B, ++ [21225] = 0x9D74, [21226] = 0x9D75, [21227] = 0x9D70, [21228] = 0x9D69, ++ [21229] = 0x9D85, [21230] = 0x9D73, [21231] = 0x9D7B, [21232] = 0x9D82, ++ [21233] = 0x9D6F, [21234] = 0x9D79, [21235] = 0x9D7F, [21236] = 0x9D87, ++ [21237] = 0x9D68, [21238] = 0x9E94, [21239] = 0x9E91, [21240] = 0x9EC0, ++ [21241] = 0x9EFC, [21242] = 0x9F2D, [21243] = 0x9F40, [21244] = 0x9F41, ++ [21245] = 0x9F4D, [21246] = 0x9F56, [21247] = 0x9F57, [21248] = 0x9F58, ++ [21249] = 0x5337, [21250] = 0x56B2, [21255] = 0x56B5, [21256] = 0x56B3, ++ [21257] = 0x58E3, [21258] = 0x5B45, [21259] = 0x5DC6, [21260] = 0x5DC7, ++ [21261] = 0x5EEE, [21262] = 0x5EEF, [21263] = 0x5FC0, [21264] = 0x5FC1, ++ [21265] = 0x61F9, [21266] = 0x6517, [21267] = 0x6516, [21268] = 0x6515, ++ [21269] = 0x6513, [21270] = 0x65DF, [21271] = 0x66E8, [21272] = 0x66E3, ++ [21273] = 0x66E4, [21274] = 0x6AF3, [21275] = 0x6AF0, [21276] = 0x6AEA, ++ [21277] = 0x6AE8, [21278] = 0x6AF9, [21279] = 0x6AF1, [21280] = 0x6AEE, ++ [21281] = 0x6AEF, [21282] = 0x703C, [21283] = 0x7035, [21284] = 0x702F, ++ [21285] = 0x7037, [21286] = 0x7034, [21287] = 0x7031, [21288] = 0x7042, ++ [21289] = 0x7038, [21290] = 0x703F, [21291] = 0x703A, [21292] = 0x7039, ++ [21293] = 0x7040, [21294] = 0x703B, [21295] = 0x7033, [21296] = 0x7041, ++ [21297] = 0x7213, [21298] = 0x7214, [21299] = 0x72A8, [21300] = 0x737D, ++ [21301] = 0x737C, [21302] = 0x74BA, [21303] = 0x76AB, [21304] = 0x76AA, ++ [21305] = 0x76BE, [21306] = 0x76ED, [21307] = 0x77CC, [21308] = 0x77CE, ++ [21309] = 0x77CF, [21310] = 0x77CD, [21311] = 0x77F2, [21312] = 0x7925, ++ [21313] = 0x7923, [21314] = 0x7927, [21315] = 0x7928, [21316] = 0x7924, ++ [21317] = 0x7929, [21352] = 0x79B2, [21353] = 0x7A6E, [21354] = 0x7A6C, ++ [21355] = 0x7A6D, [21356] = 0x7AF7, [21357] = 0x7C49, [21358] = 0x7C48, ++ [21359] = 0x7C4A, [21360] = 0x7C47, [21361] = 0x7C45, [21362] = 0x7CEE, ++ [21363] = 0x7E7B, [21364] = 0x7E7E, [21365] = 0x7E81, [21366] = 0x7E80, ++ [21367] = 0x7FBA, [21368] = 0x7FFF, [21369] = 0x8079, [21370] = 0x81DB, ++ [21371] = 0x81D9, [21372] = 0x820B, [21373] = 0x8268, [21374] = 0x8269, ++ [21375] = 0x8622, [21376] = 0x85FF, [21377] = 0x8601, [21378] = 0x85FE, ++ [21379] = 0x861B, [21380] = 0x8600, [21381] = 0x85F6, [21382] = 0x8604, ++ [21383] = 0x8609, [21384] = 0x8605, [21385] = 0x860C, [21386] = 0x85FD, ++ [21387] = 0x8819, [21388] = 0x8810, [21389] = 0x8811, [21390] = 0x8817, ++ [21391] = 0x8813, [21392] = 0x8816, [21393] = 0x8963, [21394] = 0x8966, ++ [21395] = 0x89B9, [21396] = 0x89F7, [21397] = 0x8B60, [21398] = 0x8B6A, ++ [21399] = 0x8B5D, [21400] = 0x8B68, [21401] = 0x8B63, [21402] = 0x8B65, ++ [21403] = 0x8B67, [21404] = 0x8B6D, [21405] = 0x8DAE, [21406] = 0x8E86, ++ [21407] = 0x8E88, [21408] = 0x8E84, [21409] = 0x8F59, [21410] = 0x8F56, ++ [21411] = 0x8F57, [21412] = 0x8F55, [21413] = 0x8F58, [21414] = 0x8F5A, ++ [21415] = 0x908D, [21416] = 0x9143, [21417] = 0x9141, [21418] = 0x91B7, ++ [21419] = 0x91B5, [21420] = 0x91B2, [21421] = 0x91B3, [21422] = 0x940B, ++ [21423] = 0x9413, [21424] = 0x93FB, [21425] = 0x9420, [21426] = 0x940F, ++ [21427] = 0x9414, [21428] = 0x93FE, [21429] = 0x9415, [21430] = 0x9410, ++ [21431] = 0x9428, [21432] = 0x9419, [21433] = 0x940D, [21434] = 0x93F5, ++ [21435] = 0x9400, [21436] = 0x93F7, [21437] = 0x9407, [21438] = 0x940E, ++ [21439] = 0x9416, [21440] = 0x9412, [21441] = 0x93FA, [21442] = 0x9409, ++ [21443] = 0x93F8, [21444] = 0x940A, [21445] = 0x93FF, [21450] = 0x93FC, ++ [21451] = 0x940C, [21452] = 0x93F6, [21453] = 0x9411, [21454] = 0x9406, ++ [21455] = 0x95DE, [21456] = 0x95E0, [21457] = 0x95DF, [21458] = 0x972E, ++ [21459] = 0x972F, [21460] = 0x97B9, [21461] = 0x97BB, [21462] = 0x97FD, ++ [21463] = 0x97FE, [21464] = 0x9860, [21465] = 0x9862, [21466] = 0x9863, ++ [21467] = 0x985F, [21468] = 0x98C1, [21469] = 0x98C2, [21470] = 0x9950, ++ [21471] = 0x994E, [21472] = 0x9959, [21473] = 0x994C, [21474] = 0x994B, ++ [21475] = 0x9953, [21476] = 0x9A32, [21477] = 0x9A34, [21478] = 0x9A31, ++ [21479] = 0x9A2C, [21480] = 0x9A2A, [21481] = 0x9A36, [21482] = 0x9A29, ++ [21483] = 0x9A2E, [21484] = 0x9A38, [21485] = 0x9A2D, [21486] = 0x9AC7, ++ [21487] = 0x9ACA, [21488] = 0x9AC6, [21489] = 0x9B10, [21490] = 0x9B12, ++ [21491] = 0x9B11, [21492] = 0x9C0B, [21493] = 0x9C08, [21494] = 0x9BF7, ++ [21495] = 0x9C05, [21496] = 0x9C12, [21497] = 0x9BF8, [21498] = 0x9C40, ++ [21499] = 0x9C07, [21500] = 0x9C0E, [21501] = 0x9C06, [21502] = 0x9C17, ++ [21503] = 0x9C14, [21504] = 0x9C09, [21505] = 0x9D9F, [21506] = 0x9D99, ++ [21507] = 0x9DA4, [21508] = 0x9D9D, [21509] = 0x9D92, [21510] = 0x9D98, ++ [21511] = 0x9D90, [21512] = 0x9D9B, [21547] = 0x9DA0, [21548] = 0x9D94, ++ [21549] = 0x9D9C, [21550] = 0x9DAA, [21551] = 0x9D97, [21552] = 0x9DA1, ++ [21553] = 0x9D9A, [21554] = 0x9DA2, [21555] = 0x9DA8, [21556] = 0x9D9E, ++ [21557] = 0x9DA3, [21558] = 0x9DBF, [21559] = 0x9DA9, [21560] = 0x9D96, ++ [21561] = 0x9DA6, [21562] = 0x9DA7, [21563] = 0x9E99, [21564] = 0x9E9B, ++ [21565] = 0x9E9A, [21566] = 0x9EE5, [21567] = 0x9EE4, [21568] = 0x9EE7, ++ [21569] = 0x9EE6, [21570] = 0x9F30, [21571] = 0x9F2E, [21572] = 0x9F5B, ++ [21573] = 0x9F60, [21574] = 0x9F5E, [21575] = 0x9F5D, [21576] = 0x9F59, ++ [21577] = 0x9F91, [21578] = 0x513A, [21579] = 0x5139, [21580] = 0x5298, ++ [21581] = 0x5297, [21582] = 0x56C3, [21583] = 0x56BD, [21584] = 0x56BE, ++ [21585] = 0x5B48, [21586] = 0x5B47, [21587] = 0x5DCB, [21588] = 0x5DCF, ++ [21589] = 0x5EF1, [21590] = 0x61FD, [21591] = 0x651B, [21592] = 0x6B02, ++ [21593] = 0x6AFC, [21594] = 0x6B03, [21595] = 0x6AF8, [21596] = 0x6B00, ++ [21597] = 0x7043, [21598] = 0x7044, [21599] = 0x704A, [21600] = 0x7048, ++ [21601] = 0x7049, [21602] = 0x7045, [21603] = 0x7046, [21604] = 0x721D, ++ [21605] = 0x721A, [21606] = 0x7219, [21607] = 0x737E, [21608] = 0x7517, ++ [21609] = 0x766A, [21610] = 0x77D0, [21611] = 0x792D, [21612] = 0x7931, ++ [21613] = 0x792F, [21614] = 0x7C54, [21615] = 0x7C53, [21616] = 0x7CF2, ++ [21617] = 0x7E8A, [21618] = 0x7E87, [21619] = 0x7E88, [21620] = 0x7E8B, ++ [21621] = 0x7E86, [21622] = 0x7E8D, [21623] = 0x7F4D, [21624] = 0x7FBB, ++ [21625] = 0x8030, [21626] = 0x81DD, [21627] = 0x8618, [21628] = 0x862A, ++ [21629] = 0x8626, [21630] = 0x861F, [21631] = 0x8623, [21632] = 0x861C, ++ [21633] = 0x8619, [21634] = 0x8627, [21635] = 0x862E, [21636] = 0x8621, ++ [21637] = 0x8620, [21638] = 0x8629, [21639] = 0x861E, [21640] = 0x8625, ++ [21645] = 0x8829, [21646] = 0x881D, [21647] = 0x881B, [21648] = 0x8820, ++ [21649] = 0x8824, [21650] = 0x881C, [21651] = 0x882B, [21652] = 0x884A, ++ [21653] = 0x896D, [21654] = 0x8969, [21655] = 0x896E, [21656] = 0x896B, ++ [21657] = 0x89FA, [21658] = 0x8B79, [21659] = 0x8B78, [21660] = 0x8B45, ++ [21661] = 0x8B7A, [21662] = 0x8B7B, [21663] = 0x8D10, [21664] = 0x8D14, ++ [21665] = 0x8DAF, [21666] = 0x8E8E, [21667] = 0x8E8C, [21668] = 0x8F5E, ++ [21669] = 0x8F5B, [21670] = 0x8F5D, [21671] = 0x9146, [21672] = 0x9144, ++ [21673] = 0x9145, [21674] = 0x91B9, [21675] = 0x943F, [21676] = 0x943B, ++ [21677] = 0x9436, [21678] = 0x9429, [21679] = 0x943D, [21680] = 0x943C, ++ [21681] = 0x9430, [21682] = 0x9439, [21683] = 0x942A, [21684] = 0x9437, ++ [21685] = 0x942C, [21686] = 0x9440, [21687] = 0x9431, [21688] = 0x95E5, ++ [21689] = 0x95E4, [21690] = 0x95E3, [21691] = 0x9735, [21692] = 0x973A, ++ [21693] = 0x97BF, [21694] = 0x97E1, [21695] = 0x9864, [21696] = 0x98C9, ++ [21697] = 0x98C6, [21698] = 0x98C0, [21699] = 0x9958, [21700] = 0x9956, ++ [21701] = 0x9A39, [21702] = 0x9A3D, [21703] = 0x9A46, [21704] = 0x9A44, ++ [21705] = 0x9A42, [21706] = 0x9A41, [21707] = 0x9A3A, [21742] = 0x9A3F, ++ [21743] = 0x9ACD, [21744] = 0x9B15, [21745] = 0x9B17, [21746] = 0x9B18, ++ [21747] = 0x9B16, [21748] = 0x9B3A, [21749] = 0x9B52, [21750] = 0x9C2B, ++ [21751] = 0x9C1D, [21752] = 0x9C1C, [21753] = 0x9C2C, [21754] = 0x9C23, ++ [21755] = 0x9C28, [21756] = 0x9C29, [21757] = 0x9C24, [21758] = 0x9C21, ++ [21759] = 0x9DB7, [21760] = 0x9DB6, [21761] = 0x9DBC, [21762] = 0x9DC1, ++ [21763] = 0x9DC7, [21764] = 0x9DCA, [21765] = 0x9DCF, [21766] = 0x9DBE, ++ [21767] = 0x9DC5, [21768] = 0x9DC3, [21769] = 0x9DBB, [21770] = 0x9DB5, ++ [21771] = 0x9DCE, [21772] = 0x9DB9, [21773] = 0x9DBA, [21774] = 0x9DAC, ++ [21775] = 0x9DC8, [21776] = 0x9DB1, [21777] = 0x9DAD, [21778] = 0x9DCC, ++ [21779] = 0x9DB3, [21780] = 0x9DCD, [21781] = 0x9DB2, [21782] = 0x9E7A, ++ [21783] = 0x9E9C, [21784] = 0x9EEB, [21785] = 0x9EEE, [21786] = 0x9EED, ++ [21787] = 0x9F1B, [21788] = 0x9F18, [21789] = 0x9F1A, [21790] = 0x9F31, ++ [21791] = 0x9F4E, [21792] = 0x9F65, [21793] = 0x9F64, [21794] = 0x9F92, ++ [21795] = 0x4EB9, [21796] = 0x56C6, [21797] = 0x56C5, [21798] = 0x56CB, ++ [21799] = 0x5971, [21800] = 0x5B4B, [21801] = 0x5B4C, [21802] = 0x5DD5, ++ [21803] = 0x5DD1, [21804] = 0x5EF2, [21805] = 0x6521, [21806] = 0x6520, ++ [21807] = 0x6526, [21808] = 0x6522, [21809] = 0x6B0B, [21810] = 0x6B08, ++ [21811] = 0x6B09, [21812] = 0x6C0D, [21813] = 0x7055, [21814] = 0x7056, ++ [21815] = 0x7057, [21816] = 0x7052, [21817] = 0x721E, [21818] = 0x721F, ++ [21819] = 0x72A9, [21820] = 0x737F, [21821] = 0x74D8, [21822] = 0x74D5, ++ [21823] = 0x74D9, [21824] = 0x74D7, [21825] = 0x766D, [21826] = 0x76AD, ++ [21827] = 0x7935, [21828] = 0x79B4, [21829] = 0x7A70, [21830] = 0x7A71, ++ [21831] = 0x7C57, [21832] = 0x7C5C, [21833] = 0x7C59, [21834] = 0x7C5B, ++ [21835] = 0x7C5A, [21840] = 0x7CF4, [21841] = 0x7CF1, [21842] = 0x7E91, ++ [21843] = 0x7F4F, [21844] = 0x7F87, [21845] = 0x81DE, [21846] = 0x826B, ++ [21847] = 0x8634, [21848] = 0x8635, [21849] = 0x8633, [21850] = 0x862C, ++ [21851] = 0x8632, [21852] = 0x8636, [21853] = 0x882C, [21854] = 0x8828, ++ [21855] = 0x8826, [21856] = 0x882A, [21857] = 0x8825, [21858] = 0x8971, ++ [21859] = 0x89BF, [21860] = 0x89BE, [21861] = 0x89FB, [21862] = 0x8B7E, ++ [21863] = 0x8B84, [21864] = 0x8B82, [21865] = 0x8B86, [21866] = 0x8B85, ++ [21867] = 0x8B7F, [21868] = 0x8D15, [21869] = 0x8E95, [21870] = 0x8E94, ++ [21871] = 0x8E9A, [21872] = 0x8E92, [21873] = 0x8E90, [21874] = 0x8E96, ++ [21875] = 0x8E97, [21876] = 0x8F60, [21877] = 0x8F62, [21878] = 0x9147, ++ [21879] = 0x944C, [21880] = 0x9450, [21881] = 0x944A, [21882] = 0x944B, ++ [21883] = 0x944F, [21884] = 0x9447, [21885] = 0x9445, [21886] = 0x9448, ++ [21887] = 0x9449, [21888] = 0x9446, [21889] = 0x973F, [21890] = 0x97E3, ++ [21891] = 0x986A, [21892] = 0x9869, [21893] = 0x98CB, [21894] = 0x9954, ++ [21895] = 0x995B, [21896] = 0x9A4E, [21897] = 0x9A53, [21898] = 0x9A54, ++ [21899] = 0x9A4C, [21900] = 0x9A4F, [21901] = 0x9A48, [21902] = 0x9A4A, ++ [21937] = 0x9A49, [21938] = 0x9A52, [21939] = 0x9A50, [21940] = 0x9AD0, ++ [21941] = 0x9B19, [21942] = 0x9B2B, [21943] = 0x9B3B, [21944] = 0x9B56, ++ [21945] = 0x9B55, [21946] = 0x9C46, [21947] = 0x9C48, [21948] = 0x9C3F, ++ [21949] = 0x9C44, [21950] = 0x9C39, [21951] = 0x9C33, [21952] = 0x9C41, ++ [21953] = 0x9C3C, [21954] = 0x9C37, [21955] = 0x9C34, [21956] = 0x9C32, ++ [21957] = 0x9C3D, [21958] = 0x9C36, [21959] = 0x9DDB, [21960] = 0x9DD2, ++ [21961] = 0x9DDE, [21962] = 0x9DDA, [21963] = 0x9DCB, [21964] = 0x9DD0, ++ [21965] = 0x9DDC, [21966] = 0x9DD1, [21967] = 0x9DDF, [21968] = 0x9DE9, ++ [21969] = 0x9DD9, [21970] = 0x9DD8, [21971] = 0x9DD6, [21972] = 0x9DF5, ++ [21973] = 0x9DD5, [21974] = 0x9DDD, [21975] = 0x9EB6, [21976] = 0x9EF0, ++ [21977] = 0x9F35, [21978] = 0x9F33, [21979] = 0x9F32, [21980] = 0x9F42, ++ [21981] = 0x9F6B, [21982] = 0x9F95, [21983] = 0x9FA2, [21984] = 0x513D, ++ [21985] = 0x5299, [21986] = 0x58E8, [21987] = 0x58E7, [21988] = 0x5972, ++ [21989] = 0x5B4D, [21990] = 0x5DD8, [21991] = 0x882F, [21992] = 0x5F4F, ++ [21993] = 0x6201, [21994] = 0x6203, [21995] = 0x6204, [21996] = 0x6529, ++ [21997] = 0x6525, [21998] = 0x6596, [21999] = 0x66EB, [22000] = 0x6B11, ++ [22001] = 0x6B12, [22002] = 0x6B0F, [22003] = 0x6BCA, [22004] = 0x705B, ++ [22005] = 0x705A, [22006] = 0x7222, [22007] = 0x7382, [22008] = 0x7381, ++ [22009] = 0x7383, [22010] = 0x7670, [22011] = 0x77D4, [22012] = 0x7C67, ++ [22013] = 0x7C66, [22014] = 0x7E95, [22015] = 0x826C, [22016] = 0x863A, ++ [22017] = 0x8640, [22018] = 0x8639, [22019] = 0x863C, [22020] = 0x8631, ++ [22021] = 0x863B, [22022] = 0x863E, [22023] = 0x8830, [22024] = 0x8832, ++ [22025] = 0x882E, [22026] = 0x8833, [22027] = 0x8976, [22028] = 0x8974, ++ [22029] = 0x8973, [22030] = 0x89FE, [22035] = 0x8B8C, [22036] = 0x8B8E, ++ [22037] = 0x8B8B, [22038] = 0x8B88, [22039] = 0x8C45, [22040] = 0x8D19, ++ [22041] = 0x8E98, [22042] = 0x8F64, [22043] = 0x8F63, [22044] = 0x91BC, ++ [22045] = 0x9462, [22046] = 0x9455, [22047] = 0x945D, [22048] = 0x9457, ++ [22049] = 0x945E, [22050] = 0x97C4, [22051] = 0x97C5, [22052] = 0x9800, ++ [22053] = 0x9A56, [22054] = 0x9A59, [22055] = 0x9B1E, [22056] = 0x9B1F, ++ [22057] = 0x9B20, [22058] = 0x9C52, [22059] = 0x9C58, [22060] = 0x9C50, ++ [22061] = 0x9C4A, [22062] = 0x9C4D, [22063] = 0x9C4B, [22064] = 0x9C55, ++ [22065] = 0x9C59, [22066] = 0x9C4C, [22067] = 0x9C4E, [22068] = 0x9DFB, ++ [22069] = 0x9DF7, [22070] = 0x9DEF, [22071] = 0x9DE3, [22072] = 0x9DEB, ++ [22073] = 0x9DF8, [22074] = 0x9DE4, [22075] = 0x9DF6, [22076] = 0x9DE1, ++ [22077] = 0x9DEE, [22078] = 0x9DE6, [22079] = 0x9DF2, [22080] = 0x9DF0, ++ [22081] = 0x9DE2, [22082] = 0x9DEC, [22083] = 0x9DF4, [22084] = 0x9DF3, ++ [22085] = 0x9DE8, [22086] = 0x9DED, [22087] = 0x9EC2, [22088] = 0x9ED0, ++ [22089] = 0x9EF2, [22090] = 0x9EF3, [22091] = 0x9F06, [22092] = 0x9F1C, ++ [22093] = 0x9F38, [22094] = 0x9F37, [22095] = 0x9F36, [22096] = 0x9F43, ++ [22097] = 0x9F4F, [22132] = 0x9F71, [22133] = 0x9F70, [22134] = 0x9F6E, ++ [22135] = 0x9F6F, [22136] = 0x56D3, [22137] = 0x56CD, [22138] = 0x5B4E, ++ [22139] = 0x5C6D, [22140] = 0x652D, [22141] = 0x66ED, [22142] = 0x66EE, ++ [22143] = 0x6B13, [22144] = 0x705F, [22145] = 0x7061, [22146] = 0x705D, ++ [22147] = 0x7060, [22148] = 0x7223, [22149] = 0x74DB, [22150] = 0x74E5, ++ [22151] = 0x77D5, [22152] = 0x7938, [22153] = 0x79B7, [22154] = 0x79B6, ++ [22155] = 0x7C6A, [22156] = 0x7E97, [22157] = 0x7F89, [22158] = 0x826D, ++ [22159] = 0x8643, [22160] = 0x8838, [22161] = 0x8837, [22162] = 0x8835, ++ [22163] = 0x884B, [22164] = 0x8B94, [22165] = 0x8B95, [22166] = 0x8E9E, ++ [22167] = 0x8E9F, [22168] = 0x8EA0, [22169] = 0x8E9D, [22170] = 0x91BE, ++ [22171] = 0x91BD, [22172] = 0x91C2, [22173] = 0x946B, [22174] = 0x9468, ++ [22175] = 0x9469, [22176] = 0x96E5, [22177] = 0x9746, [22178] = 0x9743, ++ [22179] = 0x9747, [22180] = 0x97C7, [22181] = 0x97E5, [22182] = 0x9A5E, ++ [22183] = 0x9AD5, [22184] = 0x9B59, [22185] = 0x9C63, [22186] = 0x9C67, ++ [22187] = 0x9C66, [22188] = 0x9C62, [22189] = 0x9C5E, [22190] = 0x9C60, ++ [22191] = 0x9E02, [22192] = 0x9DFE, [22193] = 0x9E07, [22194] = 0x9E03, ++ [22195] = 0x9E06, [22196] = 0x9E05, [22197] = 0x9E00, [22198] = 0x9E01, ++ [22199] = 0x9E09, [22200] = 0x9DFF, [22201] = 0x9DFD, [22202] = 0x9E04, ++ [22203] = 0x9EA0, [22204] = 0x9F1E, [22205] = 0x9F46, [22206] = 0x9F74, ++ [22207] = 0x9F75, [22208] = 0x9F76, [22209] = 0x56D4, [22210] = 0x652E, ++ [22211] = 0x65B8, [22212] = 0x6B18, [22213] = 0x6B19, [22214] = 0x6B17, ++ [22215] = 0x6B1A, [22216] = 0x7062, [22217] = 0x7226, [22218] = 0x72AA, ++ [22219] = 0x77D8, [22220] = 0x77D9, [22221] = 0x7939, [22222] = 0x7C69, ++ [22223] = 0x7C6B, [22224] = 0x7CF6, [22225] = 0x7E9A, [22230] = 0x7E98, ++ [22231] = 0x7E9B, [22232] = 0x7E99, [22233] = 0x81E0, [22234] = 0x81E1, ++ [22235] = 0x8646, [22236] = 0x8647, [22237] = 0x8648, [22238] = 0x8979, ++ [22239] = 0x897A, [22240] = 0x897C, [22241] = 0x897B, [22242] = 0x89FF, ++ [22243] = 0x8B98, [22244] = 0x8B99, [22245] = 0x8EA5, [22246] = 0x8EA4, ++ [22247] = 0x8EA3, [22248] = 0x946E, [22249] = 0x946D, [22250] = 0x946F, ++ [22251] = 0x9471, [22252] = 0x9473, [22253] = 0x9749, [22254] = 0x9872, ++ [22255] = 0x995F, [22256] = 0x9C68, [22257] = 0x9C6E, [22258] = 0x9C6D, ++ [22259] = 0x9E0B, [22260] = 0x9E0D, [22261] = 0x9E10, [22262] = 0x9E0F, ++ [22263] = 0x9E12, [22264] = 0x9E11, [22265] = 0x9EA1, [22266] = 0x9EF5, ++ [22267] = 0x9F09, [22268] = 0x9F47, [22269] = 0x9F78, [22270] = 0x9F7B, ++ [22271] = 0x9F7A, [22272] = 0x9F79, [22273] = 0x571E, [22274] = 0x7066, ++ [22275] = 0x7C6F, [22276] = 0x883C, [22277] = 0x8DB2, [22278] = 0x8EA6, ++ [22279] = 0x91C3, [22280] = 0x9474, [22281] = 0x9478, [22282] = 0x9476, ++ [22283] = 0x9475, [22284] = 0x9A60, [22285] = 0x9C74, [22286] = 0x9C73, ++ [22287] = 0x9C71, [22288] = 0x9C75, [22289] = 0x9E14, [22290] = 0x9E13, ++ [22291] = 0x9EF6, [22292] = 0x9F0A, [22327] = 0x9FA4, [22328] = 0x7068, ++ [22329] = 0x7065, [22330] = 0x7CF7, [22331] = 0x866A, [22332] = 0x883E, ++ [22333] = 0x883D, [22334] = 0x883F, [22335] = 0x8B9E, [22336] = 0x8C9C, ++ [22337] = 0x8EA9, [22338] = 0x8EC9, [22339] = 0x974B, [22340] = 0x9873, ++ [22341] = 0x9874, [22342] = 0x98CC, [22343] = 0x9961, [22344] = 0x99AB, ++ [22345] = 0x9A64, [22346] = 0x9A66, [22347] = 0x9A67, [22348] = 0x9B24, ++ [22349] = 0x9E15, [22350] = 0x9E17, [22351] = 0x9F48, [22352] = 0x6207, ++ [22353] = 0x6B1E, [22354] = 0x7227, [22355] = 0x864C, [22356] = 0x8EA8, ++ [22357] = 0x9482, [22358] = 0x9480, [22359] = 0x9481, [22360] = 0x9A69, ++ [22361] = 0x9A68, [22362] = 0x9B2E, [22363] = 0x9E19, [22364] = 0x7229, ++ [22365] = 0x864B, [22366] = 0x8B9F, [22367] = 0x9483, [22368] = 0x9C79, ++ [22369] = 0x9EB7, [22370] = 0x7675, [22371] = 0x9A6B, [22372] = 0x9C7A, ++ [22373] = 0x9E1D, [22374] = 0x7069, [22375] = 0x706A, [22376] = 0x9EA4, ++ [22377] = 0x9F7E, [22378] = 0x9F49, [22379] = 0x9F98, [22380] = 0x7881, ++ [22381] = 0x92B9, [22382] = 0x88CF, [22383] = 0x58BB, [22384] = 0x6052, ++ [22385] = 0x7CA7, [22386] = 0x5AFA, [22387] = 0x2554, [22388] = 0x2566, ++ [22389] = 0x2557, [22390] = 0x2560, [22391] = 0x256C, [22392] = 0x2563, ++ [22393] = 0x255A, [22394] = 0x2569, [22395] = 0x255D, [22396] = 0x2552, ++ [22397] = 0x2564, [22398] = 0x2555, [22399] = 0x255E, [22400] = 0x256A, ++ [22401] = 0x2561, [22402] = 0x2558, [22403] = 0x2567, [22404] = 0x255B, ++ [22405] = 0x2553, [22406] = 0x2565, [22407] = 0x2556, [22408] = 0x255F, ++ [22409] = 0x256B, [22410] = 0x2562, [22411] = 0x2559, [22412] = 0x2568, ++ [22413] = 0x255C, [22414] = 0x2551, [22415] = 0x2550, [22416] = 0x256D, ++ [22417] = 0x256E, [22418] = 0x2570, [22419] = 0x256F, [22420] = 0xFFED, ++ [22425] = 0x20547, [22426] = 0x92DB, [22427] = 0x205DF, [22428] = 0x23FC5, ++ [22429] = 0x854C, [22430] = 0x42B5, [22431] = 0x73EF, [22432] = 0x51B5, ++ [22433] = 0x3649, [22434] = 0x24942, [22435] = 0x289E4, [22436] = 0x9344, ++ [22437] = 0x219DB, [22438] = 0x82EE, [22439] = 0x23CC8, [22440] = 0x783C, ++ [22441] = 0x6744, [22442] = 0x62DF, [22443] = 0x24933, [22444] = 0x289AA, ++ [22445] = 0x202A0, [22446] = 0x26BB3, [22447] = 0x21305, [22448] = 0x4FAB, ++ [22449] = 0x224ED, [22450] = 0x5008, [22451] = 0x26D29, [22452] = 0x27A84, ++ [22453] = 0x23600, [22454] = 0x24AB1, [22455] = 0x22513, [22457] = 0x2037E, ++ [22458] = 0x5FA4, [22459] = 0x20380, [22460] = 0x20347, [22461] = 0x6EDB, ++ [22462] = 0x2041F, [22464] = 0x5101, [22465] = 0x347A, [22466] = 0x510E, ++ [22467] = 0x986C, [22468] = 0x3743, [22469] = 0x8416, [22470] = 0x249A4, ++ [22471] = 0x20487, [22472] = 0x5160, [22473] = 0x233B4, [22474] = 0x516A, ++ [22475] = 0x20BFF, [22476] = 0x220FC, [22477] = 0x202E5, [22478] = 0x22530, ++ [22479] = 0x2058E, [22480] = 0x23233, [22481] = 0x21983, [22482] = 0x5B82, ++ [22483] = 0x877D, [22484] = 0x205B3, [22485] = 0x23C99, [22486] = 0x51B2, ++ [22487] = 0x51B8, [22522] = 0x9D34, [22523] = 0x51C9, [22524] = 0x51CF, ++ [22525] = 0x51D1, [22526] = 0x3CDC, [22527] = 0x51D3, [22528] = 0x24AA6, ++ [22529] = 0x51B3, [22530] = 0x51E2, [22531] = 0x5342, [22532] = 0x51ED, ++ [22533] = 0x83CD, [22534] = 0x693E, [22535] = 0x2372D, [22536] = 0x5F7B, ++ [22537] = 0x520B, [22538] = 0x5226, [22539] = 0x523C, [22540] = 0x52B5, ++ [22541] = 0x5257, [22542] = 0x5294, [22543] = 0x52B9, [22544] = 0x52C5, ++ [22545] = 0x7C15, [22546] = 0x8542, [22547] = 0x52E0, [22548] = 0x860D, ++ [22549] = 0x26B13, [22551] = 0x28ADE, [22552] = 0x5549, [22553] = 0x6ED9, ++ [22554] = 0x23F80, [22555] = 0x20954, [22556] = 0x23FEC, [22557] = 0x5333, ++ [22559] = 0x20BE2, [22560] = 0x6CCB, [22561] = 0x21726, [22562] = 0x681B, ++ [22563] = 0x73D5, [22564] = 0x604A, [22565] = 0x3EAA, [22566] = 0x38CC, ++ [22567] = 0x216E8, [22568] = 0x71DD, [22569] = 0x44A2, [22570] = 0x536D, ++ [22571] = 0x5374, [22572] = 0x286AB, [22573] = 0x537E, [22575] = 0x21596, ++ [22576] = 0x21613, [22577] = 0x77E6, [22578] = 0x5393, [22579] = 0x28A9B, ++ [22580] = 0x53A0, [22581] = 0x53AB, [22582] = 0x53AE, [22583] = 0x73A7, ++ [22584] = 0x25772, [22585] = 0x3F59, [22586] = 0x739C, [22587] = 0x53C1, ++ [22588] = 0x53C5, [22589] = 0x6C49, [22590] = 0x4E49, [22591] = 0x57FE, ++ [22592] = 0x53D9, [22593] = 0x3AAB, [22594] = 0x20B8F, [22595] = 0x53E0, ++ [22596] = 0x23FEB, [22597] = 0x22DA3, [22598] = 0x53F6, [22599] = 0x20C77, ++ [22600] = 0x5413, [22601] = 0x7079, [22602] = 0x552B, [22603] = 0x6657, ++ [22604] = 0x6D5B, [22605] = 0x546D, [22606] = 0x26B53, [22607] = 0x20D74, ++ [22608] = 0x555D, [22609] = 0x548F, [22610] = 0x54A4, [22611] = 0x47A6, ++ [22612] = 0x2170D, [22613] = 0x20EDD, [22614] = 0x3DB4, [22615] = 0x20D4D, ++ [22620] = 0x289BC, [22621] = 0x22698, [22622] = 0x5547, [22623] = 0x4CED, ++ [22624] = 0x542F, [22625] = 0x7417, [22626] = 0x5586, [22627] = 0x55A9, ++ [22629] = 0x218D7, [22630] = 0x2403A, [22631] = 0x4552, [22632] = 0x24435, ++ [22633] = 0x66B3, [22634] = 0x210B4, [22635] = 0x5637, [22636] = 0x66CD, ++ [22637] = 0x2328A, [22638] = 0x66A4, [22639] = 0x66AD, [22640] = 0x564D, ++ [22641] = 0x564F, [22642] = 0x78F1, [22643] = 0x56F1, [22644] = 0x9787, ++ [22645] = 0x53FE, [22646] = 0x5700, [22647] = 0x56EF, [22648] = 0x56ED, ++ [22649] = 0x28B66, [22650] = 0x3623, [22651] = 0x2124F, [22652] = 0x5746, ++ [22653] = 0x241A5, [22654] = 0x6C6E, [22655] = 0x708B, [22656] = 0x5742, ++ [22657] = 0x36B1, [22658] = 0x26C7E, [22659] = 0x57E6, [22660] = 0x21416, ++ [22661] = 0x5803, [22662] = 0x21454, [22663] = 0x24363, [22664] = 0x5826, ++ [22665] = 0x24BF5, [22666] = 0x585C, [22667] = 0x58AA, [22668] = 0x3561, ++ [22669] = 0x58E0, [22670] = 0x58DC, [22671] = 0x2123C, [22672] = 0x58FB, ++ [22673] = 0x5BFF, [22674] = 0x5743, [22675] = 0x2A150, [22676] = 0x24278, ++ [22677] = 0x93D3, [22678] = 0x35A1, [22679] = 0x591F, [22680] = 0x68A6, ++ [22681] = 0x36C3, [22682] = 0x6E59, [22717] = 0x2163E, [22718] = 0x5A24, ++ [22719] = 0x5553, [22720] = 0x21692, [22721] = 0x8505, [22722] = 0x59C9, ++ [22723] = 0x20D4E, [22724] = 0x26C81, [22725] = 0x26D2A, [22726] = 0x217DC, ++ [22727] = 0x59D9, [22728] = 0x217FB, [22729] = 0x217B2, [22730] = 0x26DA6, ++ [22731] = 0x6D71, [22732] = 0x21828, [22733] = 0x216D5, [22734] = 0x59F9, ++ [22735] = 0x26E45, [22736] = 0x5AAB, [22737] = 0x5A63, [22738] = 0x36E6, ++ [22739] = 0x249A9, [22741] = 0x3708, [22742] = 0x5A96, [22743] = 0x7465, ++ [22744] = 0x5AD3, [22745] = 0x26FA1, [22746] = 0x22554, [22747] = 0x3D85, ++ [22748] = 0x21911, [22749] = 0x3732, [22750] = 0x216B8, [22751] = 0x5E83, ++ [22752] = 0x52D0, [22753] = 0x5B76, [22754] = 0x6588, [22755] = 0x5B7C, ++ [22756] = 0x27A0E, [22757] = 0x4004, [22758] = 0x485D, [22759] = 0x20204, ++ [22760] = 0x5BD5, [22761] = 0x6160, [22762] = 0x21A34, [22763] = 0x259CC, ++ [22764] = 0x205A5, [22765] = 0x5BF3, [22766] = 0x5B9D, [22767] = 0x4D10, ++ [22768] = 0x5C05, [22769] = 0x21B44, [22770] = 0x5C13, [22771] = 0x73CE, ++ [22772] = 0x5C14, [22773] = 0x21CA5, [22774] = 0x26B28, [22775] = 0x5C49, ++ [22776] = 0x48DD, [22777] = 0x5C85, [22778] = 0x5CE9, [22779] = 0x5CEF, ++ [22780] = 0x5D8B, [22781] = 0x21DF9, [22782] = 0x21E37, [22783] = 0x5D10, ++ [22784] = 0x5D18, [22785] = 0x5D46, [22786] = 0x21EA4, [22787] = 0x5CBA, ++ [22788] = 0x5DD7, [22789] = 0x82FC, [22790] = 0x382D, [22791] = 0x24901, ++ [22792] = 0x22049, [22793] = 0x22173, [22794] = 0x8287, [22795] = 0x3836, ++ [22796] = 0x3BC2, [22797] = 0x5E2E, [22798] = 0x6A8A, [22800] = 0x5E7A, ++ [22801] = 0x244BC, [22802] = 0x20CD3, [22803] = 0x53A6, [22804] = 0x4EB7, ++ [22806] = 0x53A8, [22807] = 0x21771, [22808] = 0x5E09, [22809] = 0x5EF4, ++ [22810] = 0x28482, [22815] = 0x5EF9, [22816] = 0x5EFB, [22817] = 0x38A0, ++ [22818] = 0x5EFC, [22819] = 0x683E, [22820] = 0x941B, [22821] = 0x5F0D, ++ [22822] = 0x201C1, [22823] = 0x2F894, [22824] = 0x3ADE, [22825] = 0x48AE, ++ [22826] = 0x2133A, [22827] = 0x5F3A, [22828] = 0x26888, [22829] = 0x223D0, ++ [22831] = 0x22471, [22832] = 0x5F63, [22833] = 0x97BD, [22834] = 0x26E6E, ++ [22835] = 0x5F72, [22836] = 0x9340, [22837] = 0x28A36, [22838] = 0x5FA7, ++ [22839] = 0x5DB6, [22840] = 0x3D5F, [22841] = 0x25250, [22842] = 0x21F6A, ++ [22843] = 0x270F8, [22844] = 0x22668, [22845] = 0x91D6, [22846] = 0x2029E, ++ [22847] = 0x28A29, [22848] = 0x6031, [22849] = 0x6685, [22850] = 0x21877, ++ [22851] = 0x3963, [22852] = 0x3DC7, [22853] = 0x3639, [22854] = 0x5790, ++ [22855] = 0x227B4, [22856] = 0x7971, [22857] = 0x3E40, [22858] = 0x609E, ++ [22860] = 0x60B3, [22861] = 0x24982, [22862] = 0x2498F, [22863] = 0x27A53, ++ [22864] = 0x74A4, [22865] = 0x50E1, [22866] = 0x5AA0, [22867] = 0x6164, ++ [22868] = 0x8424, [22869] = 0x6142, [22870] = 0x2F8A6, [22871] = 0x26ED2, ++ [22872] = 0x6181, [22873] = 0x51F4, [22874] = 0x20656, [22875] = 0x6187, ++ [22876] = 0x5BAA, [22877] = 0x23FB7, [22912] = 0x2285F, [22913] = 0x61D3, ++ [22914] = 0x28B9D, [22915] = 0x2995D, [22916] = 0x61D0, [22917] = 0x3932, ++ [22918] = 0x22980, [22919] = 0x228C1, [22920] = 0x6023, [22921] = 0x615C, ++ [22922] = 0x651E, [22923] = 0x638B, [22924] = 0x20118, [22925] = 0x62C5, ++ [22926] = 0x21770, [22927] = 0x62D5, [22928] = 0x22E0D, [22929] = 0x636C, ++ [22930] = 0x249DF, [22931] = 0x3A17, [22932] = 0x6438, [22933] = 0x63F8, ++ [22934] = 0x2138E, [22935] = 0x217FC, [22937] = 0x6F8A, [22938] = 0x22E36, ++ [22939] = 0x9814, [22940] = 0x2408C, [22941] = 0x2571D, [22942] = 0x64E1, ++ [22943] = 0x64E5, [22944] = 0x947B, [22945] = 0x3A66, [22946] = 0x643A, ++ [22947] = 0x3A57, [22948] = 0x654D, [22949] = 0x6F16, [22950] = 0x24A28, ++ [22951] = 0x24A23, [22952] = 0x6585, [22953] = 0x656D, [22954] = 0x655F, ++ [22955] = 0x2307E, [22956] = 0x65B5, [22957] = 0x24940, [22958] = 0x4B37, ++ [22959] = 0x65D1, [22960] = 0x40D8, [22961] = 0x21829, [22962] = 0x65E0, ++ [22963] = 0x65E3, [22964] = 0x5FDF, [22965] = 0x23400, [22966] = 0x6618, ++ [22967] = 0x231F7, [22968] = 0x231F8, [22969] = 0x6644, [22970] = 0x231A4, ++ [22971] = 0x231A5, [22972] = 0x664B, [22973] = 0x20E75, [22974] = 0x6667, ++ [22975] = 0x251E6, [22976] = 0x6673, [22978] = 0x21E3D, [22979] = 0x23231, ++ [22980] = 0x285F4, [22981] = 0x231C8, [22982] = 0x25313, [22983] = 0x77C5, ++ [22984] = 0x228F7, [22985] = 0x99A4, [22986] = 0x6702, [22987] = 0x2439C, ++ [22988] = 0x24A21, [22989] = 0x3B2B, [22990] = 0x69FA, [22991] = 0x237C2, ++ [22993] = 0x6767, [22994] = 0x6762, [22995] = 0x241CD, [22996] = 0x290ED, ++ [22997] = 0x67D7, [22998] = 0x44E9, [22999] = 0x6822, [23000] = 0x6E50, ++ [23001] = 0x923C, [23002] = 0x6801, [23003] = 0x233E6, [23004] = 0x26DA0, ++ [23005] = 0x685D, [23010] = 0x2346F, [23011] = 0x69E1, [23012] = 0x6A0B, ++ [23013] = 0x28ADF, [23014] = 0x6973, [23015] = 0x68C3, [23016] = 0x235CD, ++ [23017] = 0x6901, [23018] = 0x6900, [23019] = 0x3D32, [23020] = 0x3A01, ++ [23021] = 0x2363C, [23022] = 0x3B80, [23023] = 0x67AC, [23024] = 0x6961, ++ [23025] = 0x28A4A, [23026] = 0x42FC, [23027] = 0x6936, [23028] = 0x6998, ++ [23029] = 0x3BA1, [23030] = 0x203C9, [23031] = 0x8363, [23032] = 0x5090, ++ [23033] = 0x69F9, [23034] = 0x23659, [23035] = 0x2212A, [23036] = 0x6A45, ++ [23037] = 0x23703, [23038] = 0x6A9D, [23039] = 0x3BF3, [23040] = 0x67B1, ++ [23041] = 0x6AC8, [23042] = 0x2919C, [23043] = 0x3C0D, [23044] = 0x6B1D, ++ [23045] = 0x20923, [23046] = 0x60DE, [23047] = 0x6B35, [23048] = 0x6B74, ++ [23049] = 0x227CD, [23050] = 0x6EB5, [23051] = 0x23ADB, [23052] = 0x203B5, ++ [23053] = 0x21958, [23054] = 0x3740, [23055] = 0x5421, [23056] = 0x23B5A, ++ [23057] = 0x6BE1, [23058] = 0x23EFC, [23059] = 0x6BDC, [23060] = 0x6C37, ++ [23061] = 0x2248B, [23062] = 0x248F1, [23063] = 0x26B51, [23064] = 0x6C5A, ++ [23065] = 0x8226, [23066] = 0x6C79, [23067] = 0x23DBC, [23068] = 0x44C5, ++ [23069] = 0x23DBD, [23070] = 0x241A4, [23071] = 0x2490C, [23072] = 0x24900, ++ [23107] = 0x23CC9, [23108] = 0x36E5, [23109] = 0x3CEB, [23110] = 0x20D32, ++ [23111] = 0x9B83, [23112] = 0x231F9, [23113] = 0x22491, [23114] = 0x7F8F, ++ [23115] = 0x6837, [23116] = 0x26D25, [23117] = 0x26DA1, [23118] = 0x26DEB, ++ [23119] = 0x6D96, [23120] = 0x6D5C, [23121] = 0x6E7C, [23122] = 0x6F04, ++ [23123] = 0x2497F, [23124] = 0x24085, [23125] = 0x26E72, [23126] = 0x8533, ++ [23127] = 0x26F74, [23128] = 0x51C7, [23131] = 0x842E, [23132] = 0x28B21, ++ [23134] = 0x23E2F, [23135] = 0x7453, [23136] = 0x23F82, [23137] = 0x79CC, ++ [23138] = 0x6E4F, [23139] = 0x5A91, [23140] = 0x2304B, [23141] = 0x6FF8, ++ [23142] = 0x370D, [23143] = 0x6F9D, [23144] = 0x23E30, [23145] = 0x6EFA, ++ [23146] = 0x21497, [23147] = 0x2403D, [23148] = 0x4555, [23149] = 0x93F0, ++ [23150] = 0x6F44, [23151] = 0x6F5C, [23152] = 0x3D4E, [23153] = 0x6F74, ++ [23154] = 0x29170, [23155] = 0x3D3B, [23156] = 0x6F9F, [23157] = 0x24144, ++ [23158] = 0x6FD3, [23159] = 0x24091, [23160] = 0x24155, [23161] = 0x24039, ++ [23162] = 0x23FF0, [23163] = 0x23FB4, [23164] = 0x2413F, [23165] = 0x51DF, ++ [23166] = 0x24156, [23167] = 0x24157, [23168] = 0x24140, [23169] = 0x261DD, ++ [23170] = 0x704B, [23171] = 0x707E, [23172] = 0x70A7, [23173] = 0x7081, ++ [23174] = 0x70CC, [23175] = 0x70D5, [23176] = 0x70D6, [23177] = 0x70DF, ++ [23178] = 0x4104, [23179] = 0x3DE8, [23180] = 0x71B4, [23181] = 0x7196, ++ [23182] = 0x24277, [23183] = 0x712B, [23184] = 0x7145, [23185] = 0x5A88, ++ [23186] = 0x714A, [23188] = 0x5C9C, [23189] = 0x24365, [23190] = 0x714F, ++ [23191] = 0x9362, [23192] = 0x242C1, [23193] = 0x712C, [23194] = 0x2445A, ++ [23195] = 0x24A27, [23196] = 0x24A22, [23197] = 0x71BA, [23198] = 0x28BE8, ++ [23199] = 0x70BD, [23200] = 0x720E, [23205] = 0x9442, [23206] = 0x7215, ++ [23207] = 0x5911, [23208] = 0x9443, [23209] = 0x7224, [23210] = 0x9341, ++ [23211] = 0x25605, [23212] = 0x722E, [23213] = 0x7240, [23214] = 0x24974, ++ [23215] = 0x68BD, [23216] = 0x7255, [23217] = 0x7257, [23218] = 0x3E55, ++ [23219] = 0x23044, [23220] = 0x680D, [23221] = 0x6F3D, [23222] = 0x7282, ++ [23224] = 0x732B, [23225] = 0x24823, [23226] = 0x2882B, [23227] = 0x48ED, ++ [23228] = 0x28804, [23229] = 0x7328, [23230] = 0x732E, [23231] = 0x73CF, ++ [23232] = 0x73AA, [23233] = 0x20C3A, [23234] = 0x26A2E, [23235] = 0x73C9, ++ [23236] = 0x7449, [23237] = 0x241E2, [23238] = 0x216E7, [23239] = 0x24A24, ++ [23240] = 0x6623, [23241] = 0x36C5, [23242] = 0x249B7, [23243] = 0x2498D, ++ [23244] = 0x249FB, [23245] = 0x73F7, [23246] = 0x7415, [23247] = 0x6903, ++ [23248] = 0x24A26, [23249] = 0x7439, [23250] = 0x205C3, [23251] = 0x3ED7, ++ [23253] = 0x228AD, [23254] = 0x7460, [23255] = 0x28EB2, [23256] = 0x7447, ++ [23257] = 0x73E4, [23258] = 0x7476, [23259] = 0x83B9, [23260] = 0x746C, ++ [23261] = 0x3730, [23262] = 0x7474, [23263] = 0x93F1, [23264] = 0x6A2C, ++ [23265] = 0x7482, [23266] = 0x4953, [23267] = 0x24A8C, [23302] = 0x2415F, ++ [23303] = 0x24A79, [23304] = 0x28B8F, [23305] = 0x5B46, [23306] = 0x28C03, ++ [23307] = 0x2189E, [23308] = 0x74C8, [23309] = 0x21988, [23310] = 0x750E, ++ [23312] = 0x751E, [23313] = 0x28ED9, [23314] = 0x21A4B, [23315] = 0x5BD7, ++ [23316] = 0x28EAC, [23317] = 0x9385, [23318] = 0x754D, [23319] = 0x754A, ++ [23320] = 0x7567, [23321] = 0x756E, [23322] = 0x24F82, [23323] = 0x3F04, ++ [23324] = 0x24D13, [23325] = 0x758E, [23326] = 0x745D, [23327] = 0x759E, ++ [23328] = 0x75B4, [23329] = 0x7602, [23330] = 0x762C, [23331] = 0x7651, ++ [23332] = 0x764F, [23333] = 0x766F, [23334] = 0x7676, [23335] = 0x263F5, ++ [23336] = 0x7690, [23337] = 0x81EF, [23338] = 0x37F8, [23339] = 0x26911, ++ [23340] = 0x2690E, [23341] = 0x76A1, [23342] = 0x76A5, [23343] = 0x76B7, ++ [23344] = 0x76CC, [23345] = 0x26F9F, [23346] = 0x8462, [23347] = 0x2509D, ++ [23348] = 0x2517D, [23349] = 0x21E1C, [23350] = 0x771E, [23351] = 0x7726, ++ [23352] = 0x7740, [23353] = 0x64AF, [23354] = 0x25220, [23355] = 0x7758, ++ [23356] = 0x232AC, [23357] = 0x77AF, [23358] = 0x28964, [23359] = 0x28968, ++ [23360] = 0x216C1, [23361] = 0x77F4, [23363] = 0x21376, [23364] = 0x24A12, ++ [23365] = 0x68CA, [23366] = 0x78AF, [23367] = 0x78C7, [23368] = 0x78D3, ++ [23369] = 0x96A5, [23370] = 0x792E, [23371] = 0x255E0, [23372] = 0x78D7, ++ [23373] = 0x7934, [23374] = 0x78B1, [23375] = 0x2760C, [23376] = 0x8FB8, ++ [23377] = 0x8884, [23378] = 0x28B2B, [23379] = 0x26083, [23380] = 0x2261C, ++ [23381] = 0x7986, [23382] = 0x8900, [23383] = 0x6902, [23384] = 0x7980, ++ [23385] = 0x25857, [23386] = 0x799D, [23387] = 0x27B39, [23388] = 0x793C, ++ [23389] = 0x79A9, [23390] = 0x6E2A, [23391] = 0x27126, [23392] = 0x3EA8, ++ [23393] = 0x79C6, [23394] = 0x2910D, [23395] = 0x79D4 + }; + + +@@ -4636,7 +4711,7 @@ static const uint32_t big5hkscs_to_ucs[] = + } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +-static const char from_ucs4[][2] = ++static const unsigned char from_ucs4[][2] = + { + /* 0x00a2 */ "\xa2\x46", "\xa2\x47", "\x00\x00", "\xa2\x44", "\x00\x00", + /* 0x00a7 */ "\xa1\xb1", "\xc6\xd8", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -4895,6 +4970,8 @@ static const char from_ucs4[][2] = + /* 0x22b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa1\xe9", + ++ /* 0x23da */ "\x88\xa9", "\x88\xaa", ++ + /* 0x2460 */ "\xc6\xa1", "\xc6\xa2", "\xc6\xa3", "\xc6\xa4", "\xc6\xa5", + /* 0x2465 */ "\xc6\xa6", "\xc6\xa7", "\xc6\xa8", "\xc6\xa9", "\xc6\xaa", + /* 0x2469 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5068,29 +5145,52 @@ static const char from_ucs4[][2] = + /* 0x3122 */ "\xa3\xb3", "\xa3\xb4", "\xa3\xb5", "\xa3\xb6", "\xa3\xb7", + /* 0x3127 */ "\xa3\xb8", "\xa3\xb9", "\xa3\xba", + +- /* 0x3231 */ "\xc8\xd1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3235 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x323a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x323f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3244 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3249 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x324e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3253 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3258 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x325d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3262 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3267 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x326c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3271 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3276 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x327b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3280 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3285 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x328a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x328f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3294 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3299 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x329e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa1\xc0", ++ /* 0x31c0 */ "\x88\x40", "\x88\x41", "\x88\x42", "\x88\x43", "\x88\x44", ++ /* 0x31c5 */ "\x88\x46", "\x88\x49", "\x88\x4a", "\x88\x4d", "\x88\x4f", ++ /* 0x31ca */ "\x88\x50", "\x88\x51", "\x88\x52", "\x88\x54", "\x88\x55", ++ /* 0x31cf */ "\xc8\x79", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x31fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3200 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3205 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x320a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x320f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3214 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3219 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x321e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3223 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3228 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x322d */ "\x00\x00", "\x00\x00", "\x00\x00", "\xc8\xd1", "\x00\x00", ++ /* 0x3232 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3237 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x323c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3241 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3246 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x324b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3250 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3255 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x325a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x325f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3264 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3269 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x326e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3273 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3278 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x327d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3282 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3287 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x328c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3291 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3296 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x329b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x32a0 */ "\x00\x00", "\x00\x00", "\xa1\xc0", + + /* 0x338e */ "\xa2\x55", "\xa2\x56", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3392 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5129,7 +5229,7 @@ static const char from_ucs4[][2] = + /* 0x3437 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x343c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xdf", "\x00\x00", + /* 0x3441 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3446 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3446 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xf4", "\x00\x00", + /* 0x344c */ "\x89\xd5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3450 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3455 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5160,7 +5260,7 @@ static const char from_ucs4[][2] = + /* 0x34d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x34d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x34dc */ "\x00\x00", "\x00\x00", "\x9e\x53", "\x00\x00", "\x00\x00", +- /* 0x34e1 */ "\x00\x00", "\x00\x00", "\x9d\xaa", "\x00\x00", "\x00\x00", ++ /* 0x34e1 */ "\x00\x00", "\x00\x00", "\x9d\xaa", "\x00\x00", "\x87\xbe", + /* 0x34e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x34eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x34f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5183,7 +5283,7 @@ static const char from_ucs4[][2] = + /* 0x3545 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x354a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x354f */ "\x00\x00", "\x89\xe8", "\x00\x00", "\x89\xea", "\x00\x00", +- /* 0x3554 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3554 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x4b", + /* 0x3559 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x355e */ "\x00\x00", "\x00\x00", "\xfb\x70", "\x00\x00", "\x00\x00", + /* 0x3563 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5224,7 +5324,7 @@ static const char from_ucs4[][2] = + /* 0x3612 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3618 */ "\x9c\x5c", "\x00\x00", "\x8b\xb1", "\x00\x00", "\x00\x00", + /* 0x361c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3621 */ "\x00\x00", "\xfb\x5e", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3621 */ "\x00\x00", "\xfb\x5e", "\x00\x00", "\x87\x70", "\x00\x00", + /* 0x3626 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x362b */ "\x00\x00", "\x9d\xf3", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3630 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xd0", +@@ -5236,7 +5336,7 @@ static const char from_ucs4[][2] = + /* 0x364e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3653 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3658 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x365d */ "\x00\x00", "\x9c\x6f", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x365d */ "\x00\x00", "\x9c\x6f", "\x00\x00", "\x8d\x5c", "\x00\x00", + /* 0x3662 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3667 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x366c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5311,7 +5411,7 @@ static const char from_ucs4[][2] = + /* 0x37c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x37ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x37cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x37d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x37d4 */ "\x00\x00", "\x8d\x4b", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x37d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x37de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x37e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5343,7 +5443,7 @@ static const char from_ucs4[][2] = + /* 0x3865 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x386a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x386f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3874 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3875 */ "\x87\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3879 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x387e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3883 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5362,7 +5462,7 @@ static const char from_ucs4[][2] = + /* 0x38c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x38c9 */ "\x00\x00", "\x00\x00", "\xfa\xcd", "\x00\x00", "\x00\x00", + /* 0x38ce */ "\x00\x00", "\x00\x00", "\x93\xdd", "\x00\x00", "\x00\x00", +- /* 0x38d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x38d4 */ "\x8d\x52", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x38d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x38dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x38e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5394,7 +5494,7 @@ static const char from_ucs4[][2] = + /* 0x3964 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3969 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x396e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3973 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3973 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xf3", + /* 0x3978 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x397d */ "\x00\x00", "\x00\x00", "\x90\x60", "\x00\x00", "\x00\x00", + /* 0x3982 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5471,7 +5571,7 @@ static const char from_ucs4[][2] = + /* 0x3ae5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3aea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3af0 */ "\x90\x6f", "\x00\x00", "\x8d\xb0", "\x00\x00", "\x00\x00", +- /* 0x3af4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3af5 */ "\x87\xa2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3af9 */ "\x00\x00", "\x94\x7e", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3afe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3b03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5503,7 +5603,7 @@ static const char from_ucs4[][2] = + /* 0x3b85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3b8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3b8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3b94 */ "\x00\x00", "\x93\xe4", "\x00\x00", "\x00\x00", "\x93\xe0", ++ /* 0x3b95 */ "\x87\x4b", "\x93\xe4", "\x00\x00", "\x00\x00", "\x93\xe0", + /* 0x3b99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3b9e */ "\x00\x00", "\x00\x00", "\xfd\x53", "\x00\x00", "\x00\x00", + /* 0x3ba3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5552,7 +5652,7 @@ static const char from_ucs4[][2] = + /* 0x3c7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3c7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3c84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3c89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3c89 */ "\x00\x00", "\x8c\x56", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3c8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3c93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3c98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5579,7 +5679,7 @@ static const char from_ucs4[][2] = + /* 0x3d01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3d06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3d0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3d10 */ "\x00\x00", "\x00\x00", "\x8e\xaf", "\x00\x00", "\x00\x00", ++ /* 0x3d10 */ "\x00\x00", "\x8c\xea", "\x8e\xaf", "\x00\x00", "\x00\x00", + /* 0x3d15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3d1a */ "\x00\x00", "\x00\x00", "\x91\xb5", "\x00\x00", "\x00\x00", + /* 0x3d1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5602,7 +5702,7 @@ static const char from_ucs4[][2] = + /* 0x3d75 */ "\x8d\xf0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3d79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xa6", "\x00\x00", + /* 0x3d7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3d83 */ "\x00\x00", "\xfb\xbf", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3d83 */ "\x00\x00", "\xfb\xbf", "\x00\x00", "\x00\x00", "\x8c\xdf", + /* 0x3d88 */ "\x00\x00", "\x8d\xf3", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3d8d */ "\x00\x00", "\x94\x49", "\x00\x00", "\x8d\xf5", "\x00\x00", + /* 0x3d92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5615,7 +5715,7 @@ static const char from_ucs4[][2] = + /* 0x3db5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3dba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\x50", + /* 0x3dbf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3dc4 */ "\x00\x00", "\x9d\xcc", "\xfc\x65", "\x00\x00", "\x00\x00", ++ /* 0x3dc4 */ "\x00\x00", "\x9d\xcc", "\xfc\x65", "\x00\x00", "\x8c\x44", + /* 0x3dc9 */ "\x00\x00", "\x00\x00", "\x99\x6e", "\x94\xa1", "\x00\x00", + /* 0x3dce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\x63", + /* 0x3dd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5624,7 +5724,7 @@ static const char from_ucs4[][2] = + /* 0x3de2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x53", + /* 0x3de8 */ "\xfd\xe9", "\x00\x00", "\x00\x00", "\x9d\xb5", "\x00\x00", + /* 0x3dec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3df1 */ "\x00\x00", "\x98\x79", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3df1 */ "\x00\x00", "\x98\x79", "\x87\x6a", "\x00\x00", "\x00\x00", + /* 0x3df7 */ "\x9d\x5d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3dfc */ "\x8d\x63", "\x96\x69", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3e00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5670,16 +5770,16 @@ static const char from_ucs4[][2] = + /* 0x3ec8 */ "\x00\x00", "\x98\xc3", "\x00\x00", "\x95\xf6", "\x00\x00", + /* 0x3ecd */ "\x00\x00", "\x00\x00", "\x8f\xfd", "\x98\xc5", "\x00\x00", + /* 0x3ed2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x66", "\xfe\x6e", +- /* 0x3ed7 */ "\x00\x00", "\x00\x00", "\x97\xdd", "\x00\x00", "\x00\x00", ++ /* 0x3ed7 */ "\x00\x00", "\x00\x00", "\x97\xdd", "\x8c\xaa", "\x00\x00", + /* 0x3edc */ "\x00\x00", "\x92\xd2", "\x00\x00", "\x00\x00", "\x97\x61", + /* 0x3ee2 */ "\x98\xcb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3ee7 */ "\x95\xf0", "\x00\x00", "\x97\x5d", "\x00\x00", "\x91\xe3", +- /* 0x3eeb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xcc", ++ /* 0x3eec */ "\x87\x7e", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xcc", + /* 0x3ef0 */ "\x00\x00", "\x00\x00", "\x94\x69", "\x98\xcd", "\x00\x00", + /* 0x3ef5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xce", + /* 0x3efa */ "\x00\x00", "\x95\xfc", "\x00\x00", "\x00\x00", "\x94\xa3", + /* 0x3f00 */ "\x96\x62", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xb6", +- /* 0x3f04 */ "\x00\x00", "\x94\x63", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3f04 */ "\x00\x00", "\x94\x63", "\x8d\x47", "\x00\x00", "\x00\x00", + /* 0x3f09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xd0", + /* 0x3f0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3f13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5718,7 +5818,7 @@ static const char from_ucs4[][2] = + /* 0x3fb8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3fbd */ "\x00\x00", "\x00\x00", "\x98\xd9", "\x00\x00", "\x00\x00", + /* 0x3fc2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x3fc7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x3fc8 */ "\x8d\x5a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3fcc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3fd1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3fd7 */ "\x98\xdb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5731,7 +5831,7 @@ static const char from_ucs4[][2] = + /* 0x3ffa */ "\x8a\xae", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x3ffe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4004 */ "\xfb\xc9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4008 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4009 */ "\x8c\x5d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x400d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4012 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4017 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5751,7 +5851,7 @@ static const char from_ucs4[][2] = + /* 0x405d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xdf", + /* 0x4062 */ "\x00\x00", "\x00\x00", "\xa0\xac", "\x00\x00", "\x00\x00", + /* 0x4067 */ "\x00\x00", "\x00\x00", "\x98\xeb", "\x00\x00", "\x00\x00", +- /* 0x406c */ "\x00\x00", "\x00\x00", "\x98\xec", "\x00\x00", "\x00\x00", ++ /* 0x406c */ "\x00\x00", "\x00\x00", "\x98\xec", "\x00\x00", "\x8c\xc3", + /* 0x4071 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4076 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x407b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5765,7 +5865,7 @@ static const char from_ucs4[][2] = + /* 0x40a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xf4", + /* 0x40a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x40ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x40b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x40b2 */ "\x00\x00", "\x87\xd9", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x40b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xb8", "\x00\x00", + /* 0x40bc */ "\x00\x00", "\x00\x00", "\x9e\xe7", "\x00\x00", "\x00\x00", + /* 0x40c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5778,9 +5878,9 @@ static const char from_ucs4[][2] = + /* 0x40e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x40e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x40ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x40f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x40f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x4a", + /* 0x40f8 */ "\x00\x00", "\x9e\x7e", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x40fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x40fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x44", + /* 0x4103 */ "\x98\xfe", "\xfd\xe8", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4107 */ "\x00\x00", "\x99\x40", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x410c */ "\x00\x00", "\x94\xc9", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5790,7 +5890,7 @@ static const char from_ucs4[][2] = + /* 0x4120 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4125 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x412a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x412f */ "\x00\x00", "\x00\x00", "\x94\xd3", "\x00\x00", "\x00\x00", ++ /* 0x412f */ "\x00\x00", "\x87\xc6", "\x94\xd3", "\x00\x00", "\x00\x00", + /* 0x4134 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4139 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x413e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5805,8 +5905,8 @@ static const char from_ucs4[][2] = + /* 0x416c */ "\x90\xc0", "\x00\x00", "\x94\xd1", "\x00\x00", "\x00\x00", + /* 0x4170 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4175 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x417a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x73", +- /* 0x417f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x417a */ "\x00\x00", "\x8d\x4e", "\x00\x00", "\x00\x00", "\x95\x73", ++ /* 0x417f */ "\x00\x00", "\x87\xce", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4184 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4189 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x418e */ "\x00\x00", "\x93\xc2", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5827,7 +5927,7 @@ static const char from_ucs4[][2] = + /* 0x41d9 */ "\x00\x00", "\x8e\xfe", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x41de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x41e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x41e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x41e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x5f", + /* 0x41ed */ "\x00\x00", "\x8e\x59", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x41f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x41f7 */ "\x00\x00", "\x94\xec", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5838,7 +5938,7 @@ static const char from_ucs4[][2] = + /* 0x4211 */ "\x94\xef", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4215 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x421a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x421f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x421f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x60", "\x00\x00", + /* 0x4224 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4229 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x422e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5855,7 +5955,7 @@ static const char from_ucs4[][2] = + /* 0x4265 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x44", + /* 0x426a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x426f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4274 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4274 */ "\x00\x00", "\x8c\xcb", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x427a */ "\x99\x56", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x427e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4283 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5864,7 +5964,7 @@ static const char from_ucs4[][2] = + /* 0x4292 */ "\x00\x00", "\x99\x5b", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4297 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x429c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x42a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x42a2 */ "\x8c\xc4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x42a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x42ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x42b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x45", +@@ -5884,7 +5984,7 @@ static const char from_ucs4[][2] = + /* 0x42f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xc9", + /* 0x42fc */ "\xfd\x50", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4300 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4305 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4305 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xaa", + /* 0x430a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x430f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4314 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5913,7 +6013,7 @@ static const char from_ucs4[][2] = + /* 0x4387 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x438c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4391 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4397 */ "\x99\x67", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4397 */ "\x99\x67", "\x00\x00", "\x00\x00", "\x8c\xe3", "\x00\x00", + /* 0x439b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x43a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x43a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5930,7 +6030,7 @@ static const char from_ucs4[][2] = + /* 0x43dc */ "\x00\x00", "\x00\x00", "\x9d\x51", "\x00\x00", "\x00\x00", + /* 0x43e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x43e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x43eb */ "\x00\x00", "\x99\x73", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x43eb */ "\x00\x00", "\x99\x73", "\x00\x00", "\x00\x00", "\x87\x40", + /* 0x43f0 */ "\x00\x00", "\x9d\x4f", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x43f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x43fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -5963,7 +6063,7 @@ static const char from_ucs4[][2] = + /* 0x4481 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4486 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x448b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x99\xad", "\x00\x00", +- /* 0x4490 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4491 */ "\xc8\x7e", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4495 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x449a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x6e", + /* 0x44a0 */ "\x8f\x70", "\x00\x00", "\xfa\xd0", "\x00\x00", "\x00\x00", +@@ -5971,15 +6071,15 @@ static const char from_ucs4[][2] = + /* 0x44a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x44ae */ "\x00\x00", "\x99\xb3", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x44b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\x53", "\x00\x00", +- /* 0x44b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x44b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x5e", + /* 0x44bd */ "\x00\x00", "\x00\x00", "\x96\x5c", "\x00\x00", "\x00\x00", +- /* 0x44c2 */ "\x00\x00", "\x00\x00", "\xfd\x7a", "\x00\x00", "\x00\x00", ++ /* 0x44c3 */ "\x8c\xe0", "\x00\x00", "\xfd\x7a", "\x00\x00", "\x00\x00", + /* 0x44c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x44cc */ "\x00\x00", "\x97\xfe", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x44d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x44d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x44db */ "\x00\x00", "\x92\xbd", "\x00\x00", "\x97\xfd", "\x00\x00", +- /* 0x44e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\x64", "\x00\x00", ++ /* 0x44db */ "\x00\x00", "\x92\xbd", "\x8d\x5d", "\x97\xfd", "\x00\x00", ++ /* 0x44e1 */ "\x87\xdb", "\x00\x00", "\x00\x00", "\x8f\x64", "\x00\x00", + /* 0x44e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xf7", "\x95\x62", + /* 0x44eb */ "\x97\xcd", "\x9e\x64", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x44ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x4c", +@@ -5990,26 +6090,26 @@ static const char from_ucs4[][2] = + /* 0x4509 */ "\x9d\xa5", "\x00\x00", "\x8f\x54", "\x00\x00", "\x00\x00", + /* 0x450d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4512 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\x7c", "\x00\x00", +- /* 0x4517 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4517 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x55", "\x00\x00", + /* 0x451d */ "\x8e\xa2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4521 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4527 */ "\x8f\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x452b */ "\x00\x00", "\x00\x00", "\x97\xae", "\x00\x00", "\x00\x00", + /* 0x4530 */ "\x00\x00", "\x00\x00", "\x96\xc8", "\x00\x00", "\x00\x00", +- /* 0x4535 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4536 */ "\x8c\xe4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x453b */ "\x99\xc3", "\x00\x00", "\x90\xd6", "\x00\x00", "\x9c\xbe", + /* 0x453f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\x76", "\x00\x00", + /* 0x4544 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4549 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x454e */ "\x00\x00", "\x00\x00", "\x94\x70", "\xfb\x4b", "\x00\x00", +- /* 0x4553 */ "\x00\x00", "\xfd\xca", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4553 */ "\x00\x00", "\xfd\xca", "\x00\x00", "\x00\x00", "\x8c\xef", + /* 0x4558 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xc7", "\x00\x00", +- /* 0x455d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xf9", ++ /* 0x455d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x54", "\xa0\xf9", + /* 0x4562 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4567 */ "\x00\x00", "\x00\x00", "\x8f\xa9", "\x00\x00", "\x00\x00", +- /* 0x456c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x456d */ "\x8d\x51", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4571 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4577 */ "\x99\xc7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4577 */ "\x99\xc7", "\x87\x44", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x457b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4580 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xd7", + /* 0x4585 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6018,26 +6118,26 @@ static const char from_ucs4[][2] = + /* 0x4594 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4599 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x459e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x45a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x45a3 */ "\x00\x00", "\x00\x00", "\x87\x43", "\x00\x00", "\x00\x00", + /* 0x45a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x45b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x45b3 */ "\x87\x47", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x45d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x45d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x58", + /* 0x45da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xdf", +- /* 0x45e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x45ea */ "\x8d\x59", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x45fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4602 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x99\xce", "\x00\x00", ++ /* 0x4603 */ "\x87\x42", "\x00\x00", "\x00\x00", "\x99\xce", "\x00\x00", + /* 0x4607 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x460c */ "\x00\x00", "\x00\x00", "\x8f\xba", "\x00\x00", "\x00\x00", + /* 0x4611 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xeb", "\x00\x00", +@@ -6068,12 +6168,12 @@ static const char from_ucs4[][2] = + /* 0x468e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4693 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4698 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x469d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x469d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x5d", "\x00\x00", + /* 0x46a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x46ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x46ac */ "\x00\x00", "\x87\xcc", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x46b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x46b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x45", + /* 0x46bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6085,7 +6185,7 @@ static const char from_ucs4[][2] = + /* 0x46e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x46f2 */ "\x00\x00", "\x00\x00", "\x95\xb2", "\x00\x00", "\x00\x00", ++ /* 0x46f2 */ "\x00\x00", "\x00\x00", "\x95\xb2", "\x00\x00", "\x8d\x4c", + /* 0x46f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x46fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4701 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6098,12 +6198,12 @@ static const char from_ucs4[][2] = + /* 0x4724 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4729 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x472e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4733 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4733 */ "\x00\x00", "\x00\x00", "\x87\x4c", "\x00\x00", "\x00\x00", + /* 0x4738 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x473d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4742 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4742 */ "\x00\x00", "\x87\x4d", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4747 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x474c */ "\x00\x00", "\x9e\x7a", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x474c */ "\x00\x00", "\x9e\x7a", "\x87\x57", "\x00\x00", "\x00\x00", + /* 0x4751 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4756 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x475b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6124,7 +6224,7 @@ static const char from_ucs4[][2] = + /* 0x47a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x47ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x47b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x47b6 */ "\x9e\xe5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x47b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x47ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x47bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x47c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6199,7 +6299,7 @@ static const char from_ucs4[][2] = + /* 0x491e */ "\x99\xf8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4922 */ "\x00\x00", "\x00\x00", "\x96\x64", "\x00\x00", "\x00\x00", + /* 0x4927 */ "\x00\x00", "\x00\x00", "\x90\x55", "\x00\x00", "\x00\x00", +- /* 0x492d */ "\x96\xd4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x492d */ "\x96\xd4", "\x00\x00", "\x87\xc4", "\x87\xae", "\x00\x00", + /* 0x4931 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x7c", "\x00\x00", + /* 0x4936 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x493c */ "\x96\x4d", "\x00\x00", "\x97\xe1", "\x00\x00", "\x00\x00", +@@ -6274,7 +6374,7 @@ static const char from_ucs4[][2] = + /* 0x4a94 */ "\x00\x00", "\x97\xc2", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4a99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4a9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4aa3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4aa4 */ "\x87\x5c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4aa8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4aad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4ab2 */ "\x00\x00", "\x8a\xbb", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6295,10 +6395,10 @@ static const char from_ucs4[][2] = + /* 0x4afd */ "\x00\x00", "\x91\x45", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4b02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4b07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4b0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4b0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x58", "\x00\x00", + /* 0x4b11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4b16 */ "\x00\x00", "\x00\x00", "\x9a\x63", "\x00\x00", "\x00\x00", +- /* 0x4b1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4b1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x49", + /* 0x4b20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4b25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4b2a */ "\x00\x00", "\x8b\xb6", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6353,24 +6453,24 @@ static const char from_ucs4[][2] = + /* 0x4c1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4c2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4c2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x41", "\x00\x00", + /* 0x4c33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c38 */ "\x00\x00", "\x00\x00", "\x9f\xa5", "\x00\x00", "\x00\x00", +- /* 0x4c3e */ "\x89\xba", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4c42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4c3e */ "\x89\xba", "\x00\x00", "\x87\x4f", "\x00\x00", "\x00\x00", ++ /* 0x4c42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x4e", + /* 0x4c47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4c56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xcd", ++ /* 0x4c57 */ "\x87\x55", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xcd", + /* 0x4c5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c6a */ "\x00\x00", "\x00\x00", "\x9a\x79", "\x00\x00", "\x00\x00", + /* 0x4c6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4c74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4c79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xce", "\x00\x00", +- /* 0x4c7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4c83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4c74 */ "\x00\x00", "\x00\x00", "\x8c\xf2", "\x00\x00", "\x00\x00", ++ /* 0x4c79 */ "\x00\x00", "\x8d\x57", "\x00\x00", "\x9d\xce", "\x00\x00", ++ /* 0x4c7e */ "\x00\x00", "\x00\x00", "\x8c\xd2", "\x00\x00", "\x00\x00", ++ /* 0x4c83 */ "\x00\x00", "\x87\x59", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4c92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6388,7 +6488,7 @@ static const char from_ucs4[][2] = + /* 0x4cce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4cd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4cd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4cdd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xee", "\x00\x00", ++ /* 0x4cdd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xee", "\x87\x49", + /* 0x4ce2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4ce7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4ced */ "\xfb\x43", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6396,7 +6496,7 @@ static const char from_ucs4[][2] = + /* 0x4cf6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4cfb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4d05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xc9", "\x00\x00", ++ /* 0x4d05 */ "\x00\x00", "\x87\x5b", "\x00\x00", "\x9e\xc9", "\x00\x00", + /* 0x4d0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d10 */ "\xfb\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6418,11 +6518,11 @@ static const char from_ucs4[][2] = + /* 0x4d64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4d73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4d73 */ "\x00\x00", "\x00\x00", "\x8d\x58", "\x87\x46", "\x00\x00", + /* 0x4d78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x4d87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x4d87 */ "\x00\x00", "\x8d\x56", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x78", + /* 0x4d91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4d96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6455,7 +6555,7 @@ static const char from_ucs4[][2] = + /* 0x4e1e */ "\xa5\xe0", "\xa5\xe1", "\x00\x00", "\x99\x4f", "\x00\x00", + /* 0x4e22 */ "\x00\x00", "\x89\xce", "\x00\x00", "\xa8\xc3", "\x00\x00", + /* 0x4e28 */ "\x8b\xc0", "\x00\x00", "\x9f\xc4", "\xa4\x58", "\x8b\xd4", +- /* 0x4e2d */ "\xa4\xa4", "\xc9\x50", "\x00\x00", "\xa4\xa5", "\xc9\x63", ++ /* 0x4e2d */ "\xa4\xa4", "\xc9\x50", "\x8c\x72", "\xa4\xa5", "\xc9\x63", + /* 0x4e32 */ "\xa6\xea", "\xcb\xb1", "\x00\x00", "\x00\x00", "\xc6\xbf", + /* 0x4e37 */ "\x8b\xf9", "\xa4\x59", "\xa4\xa6", "\x00\x00", "\xa5\x44", + /* 0x4e3c */ "\xc9\x64", "\x89\x46", "\x00\x00", "\xc6\xc0", "\x00\x00", +@@ -6478,7 +6578,7 @@ static const char from_ucs4[][2] = + /* 0x4e91 */ "\xa4\xaa", "\xa4\xac", "\xc9\x51", "\xa4\xad", "\xa4\xab", + /* 0x4e95 */ "\x00\x00", "\x00\x00", "\x92\x7e", "\xa5\xe5", "\x9d\xba", + /* 0x4e9b */ "\xa8\xc7", "\x00\x00", "\x00\x00", "\xa8\xc8", "\xab\x45", +- /* 0x4ea0 */ "\xc6\xc2", "\xa4\x60", "\xa4\xae", "\x00\x00", "\xa5\xe6", ++ /* 0x4ea0 */ "\xc6\xc2", "\xa4\x60", "\xa4\xae", "\x8c\x6f", "\xa5\xe6", + /* 0x4ea5 */ "\xa5\xe8", "\xa5\xe7", "\x00\x00", "\xa6\xeb", "\x00\x00", + /* 0x4ea9 */ "\x00\x00", "\xa8\xc9", "\xa8\xca", "\xab\x46", "\xab\x47", + /* 0x4eae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xad\xbd", +@@ -6501,7 +6601,7 @@ static const char from_ucs4[][2] = + /* 0x4f04 */ "\xc9\xb9", "\xc9\xb6", "\x00\x00", "\x00\x00", "\xc9\xb3", + /* 0x4f09 */ "\xa5\xea", "\xa5\xec", "\xa5\xf9", "\x00\x00", "\xa5\xee", + /* 0x4f0e */ "\xc9\xab", "\xa5\xf1", "\xa5\xef", "\xa5\xf0", "\xc9\xbb", +- /* 0x4f13 */ "\xc9\xb8", "\xc9\xaf", "\xa5\xed", "\x00\x00", "\x00\x00", ++ /* 0x4f13 */ "\xc9\xb8", "\xc9\xaf", "\xa5\xed", "\x00\x00", "\x8c\x73", + /* 0x4f18 */ "\xc9\xac", "\xa5\xeb", "\x89\x4e", "\x00\x00", "\x00\x00", + /* 0x4f1d */ "\xc9\xb4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4f22 */ "\xc9\xb7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6533,7 +6633,7 @@ static const char from_ucs4[][2] = + /* 0x4fa3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x89\x50", + /* 0x4fa8 */ "\x00\x00", "\x00\x00", "\xfa\x57", "\x00\x00", "\x00\x00", + /* 0x4fae */ "\xab\x56", "\xab\x4a", "\x98\x66", "\x00\x00", "\xcd\xe0", +- /* 0x4fb3 */ "\xcd\xe8", "\x00\x00", "\xab\x49", "\xab\x51", "\xab\x5d", ++ /* 0x4fb3 */ "\xcd\xe8", "\x8c\xf8", "\xab\x49", "\xab\x51", "\xab\x5d", + /* 0x4fb7 */ "\x00\x00", "\xcd\xee", "\xcd\xec", "\xcd\xe7", "\x00\x00", + /* 0x4fbd */ "\x89\xd6", "\x00\x00", "\xab\x4b", "\xcd\xed", "\xcd\xe3", + /* 0x4fc2 */ "\xab\x59", "\xab\x50", "\xab\x58", "\xcd\xde", "\x00\x00", +@@ -6545,7 +6645,7 @@ static const char from_ucs4[][2] = + /* 0x4fe0 */ "\xab\x4c", "\xab\x48", "\x00\x00", "\x00\x00", "\x96\xde", + /* 0x4fe5 */ "\x92\xac", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x4fe9 */ "\x00\x00", "\x00\x00", "\xcd\xef", "\x00\x00", "\xad\xd7", +- /* 0x4fef */ "\xad\xc1", "\x00\x00", "\xad\xd1", "\x9f\x6e", "\xad\xd6", ++ /* 0x4fef */ "\xad\xc1", "\x8c\x70", "\xad\xd1", "\x9f\x6e", "\xad\xd6", + /* 0x4ff4 */ "\xd0\xd0", "\xd0\xcf", "\xd0\xd4", "\xd0\xd5", "\xad\xc4", + /* 0x4ff9 */ "\x8e\xf2", "\xad\xcd", "\x00\x00", "\x00\x00", "\x9f\x6c", + /* 0x4ffe */ "\xad\xda", "\x00\x00", "\xad\xce", "\x00\x00", "\x00\x00", +@@ -6560,7 +6660,7 @@ static const char from_ucs4[][2] = + /* 0x502b */ "\xad\xdb", "\xd0\xd3", "\xad\xd8", "\x92\xa8", "\xd0\xdb", + /* 0x5030 */ "\xd0\xcd", "\xd0\xdc", "\x00\x00", "\xd0\xd1", "\x91\x63", + /* 0x5035 */ "\xd0\xda", "\x00\x00", "\xd0\xd2", "\x00\x00", "\x00\x00", +- /* 0x5039 */ "\x00\x00", "\x00\x00", "\xad\xc8", "\x00\x00", "\x00\x00", ++ /* 0x5039 */ "\x00\x00", "\x8c\x40", "\xad\xc8", "\x00\x00", "\x00\x00", + /* 0x503e */ "\x00\x00", "\xd4\x63", "\xd4\x57", "\x00\x00", "\xb0\xb3", + /* 0x5043 */ "\x00\x00", "\xd4\x5c", "\xd4\x62", "\xb0\xb2", "\xd4\x55", + /* 0x5049 */ "\xb0\xb6", "\xd4\x59", "\xd4\x52", "\xb0\xb4", "\xd4\x56", +@@ -6586,7 +6686,7 @@ static const char from_ucs4[][2] = + /* 0x50ad */ "\xb6\xc4", "\xdc\xb7", "\xb6\xcd", "\xdc\xbd", "\xdc\xc0", + /* 0x50b2 */ "\xb6\xc6", "\xb6\xc7", "\xdc\xba", "\xb6\xc5", "\xdc\xc3", + /* 0x50b7 */ "\xb6\xcb", "\xdc\xc4", "\x00\x00", "\xdc\xbf", "\xb6\xcc", +- /* 0x50bb */ "\x00\x00", "\xdc\xb4", "\xb6\xc9", "\xdc\xb5", "\x00\x00", ++ /* 0x50bc */ "\x8c\x71", "\xdc\xb4", "\xb6\xc9", "\xdc\xb5", "\x00\x00", + /* 0x50c1 */ "\xdc\xbe", "\xdc\xbc", "\x00\x00", "\xdc\xb8", "\xb6\xc8", + /* 0x50c6 */ "\xdc\xb6", "\xb6\xce", "\xdc\xbb", "\xdc\xc2", "\xdc\xb9", + /* 0x50cb */ "\xdc\xc1", "\x00\x00", "\x92\xa1", "\xb9\xb6", "\xb9\xb3", +@@ -6634,7 +6734,7 @@ static const char from_ucs4[][2] = + /* 0x519c */ "\x00\x00", "\xcb\xcd", "\x00\x00", "\xab\x61", "\x00\x00", + /* 0x51a2 */ "\xad\xe0", "\x00\x00", "\xad\xde", "\xad\xdf", "\x00\x00", + /* 0x51a7 */ "\x9e\x55", "\x92\xba", "\x00\x00", "\xbe\xad", "\xc6\xc5", +- /* 0x51ac */ "\xa5\x56", "\x00\x00", "\x00\x00", "\x00\x00", "\xa6\x42", ++ /* 0x51ac */ "\xa5\x56", "\x00\x00", "\x8c\x5b", "\x00\x00", "\xa6\x42", + /* 0x51b1 */ "\xc9\xbc", "\xfa\x7d", "\xfa\xa8", "\x9a\x68", "\xfa\x47", + /* 0x51b6 */ "\xa7\x4d", "\xa7\x4e", "\xfa\x7e", "\xca\x6b", "\x00\x00", + /* 0x51ba */ "\x00\x00", "\xcb\xce", "\xa8\xe6", "\xcb\xcf", "\x00\x00", +@@ -6666,7 +6766,7 @@ static const char from_ucs4[][2] = + /* 0x523c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa8\xef", + /* 0x5241 */ "\x00\x00", "\xab\x63", "\xcd\xf0", "\x00\x00", "\xcb\xd3", + /* 0x5247 */ "\xab\x68", "\x00\x00", "\xcd\xf1", "\xab\x64", "\xab\x67", +- /* 0x524c */ "\xab\x66", "\xab\x65", "\xab\x62", "\x00\x00", "\x00\x00", ++ /* 0x524c */ "\xab\x66", "\xab\x65", "\xab\x62", "\x87\xbc", "\x00\x00", + /* 0x5250 */ "\x00\x00", "\xd0\xe8", "\x00\x00", "\xad\xe7", "\xd0\xeb", + /* 0x5256 */ "\xad\xe5", "\xfa\xb4", "\x00\x00", "\x92\xc4", "\xd0\xe7", + /* 0x525b */ "\xad\xe8", "\xad\xe6", "\xad\xe9", "\xd0\xe9", "\xd0\xea", +@@ -6709,7 +6809,7 @@ static const char from_ucs4[][2] = + /* 0x5313 */ "\x00\x00", "\xa4\x50", "\xa4\xc6", "\xa5\x5f", "\x00\x00", + /* 0x5319 */ "\xb0\xcd", "\xc9\x43", "\x00\x00", "\xc9\x6c", "\xa5\x60", + /* 0x531d */ "\x00\x00", "\xc9\xc2", "\xa6\x4b", "\xa6\x4a", "\xc9\xc1", +- /* 0x5323 */ "\xa7\x58", "\x00\x00", "\x00\x00", "\x00\x00", "\x89\xe5", ++ /* 0x5323 */ "\xa7\x58", "\x8c\x68", "\x00\x00", "\x00\x00", "\x89\xe5", + /* 0x5327 */ "\x00\x00", "\x00\x00", "\xad\xea", "\x00\x00", "\x9f\x7d", + /* 0x532d */ "\xd4\x6f", "\x00\x00", "\xb6\xd7", "\xe1\x45", "\xb9\xbc", + /* 0x5332 */ "\xa0\xa9", "\xfa\xc4", "\xe8\xfa", "\x00\x00", "\x00\x00", +@@ -6763,12 +6863,12 @@ static const char from_ucs4[][2] = + /* 0x5421 */ "\x00\x00", "\x89\xec", "\xca\xa5", "\xca\x7d", "\xa7\x5f", + /* 0x5427 */ "\xa7\x61", "\xca\xa4", "\xa7\x68", "\xca\x78", "\xa7\x74", + /* 0x542c */ "\xa7\x76", "\xa7\x5c", "\xa7\x6d", "\xfb\x44", "\xca\x76", +- /* 0x5431 */ "\xa7\x73", "\x9d\xe2", "\xa7\x64", "\x00\x00", "\xa7\x6e", ++ /* 0x5431 */ "\xa7\x73", "\x9d\xe2", "\xa7\x64", "\x8c\x75", "\xa7\x6e", + /* 0x5436 */ "\xa7\x6f", "\xca\x77", "\xa7\x6c", "\xa7\x6a", "\x00\x00", + /* 0x543b */ "\xa7\x6b", "\xa7\x71", "\xca\xa1", "\xa7\x5e", "\x00\x00", + /* 0x5440 */ "\xa7\x72", "\xca\xa3", "\xa7\x66", "\xa7\x63", "\x00\x00", + /* 0x5445 */ "\xca\x7a", "\xa7\x62", "\xca\xa6", "\xa7\x65", "\x00\x00", +- /* 0x544a */ "\xa7\x69", "\x9e\xc0", "\x00\x00", "\x9e\x56", "\xa7\x60", ++ /* 0x544a */ "\xa7\x69", "\x9e\xc0", "\x87\xc5", "\x9e\x56", "\xa7\x60", + /* 0x544f */ "\xca\xa2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x5454 */ "\xca\x79", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x5458 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -6905,7 +7005,7 @@ static const char from_ucs4[][2] = + /* 0x56e7 */ "\x00\x00", "\x00\x00", "\xa7\x77", "\xa7\x7a", "\x00\x00", + /* 0x56ed */ "\xfb\x5c", "\xca\xa7", "\xfb\x5b", "\xa7\x78", "\xfb\x57", + /* 0x56f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x56f7 */ "\xcb\xf0", "\x00\x00", "\xcb\xf1", "\xa9\x54", "\x00\x00", ++ /* 0x56f7 */ "\xcb\xf0", "\x00\x00", "\xcb\xf1", "\xa9\x54", "\x87\x65", + /* 0x56fb */ "\x00\x00", "\x98\xc7", "\x00\x00", "\xab\xaa", "\xfb\x5a", + /* 0x5701 */ "\xd1\x48", "\xd1\x49", "\xae\x45", "\xae\x46", "\x00\x00", + /* 0x5705 */ "\x00\x00", "\xd4\xac", "\xb0\xe9", "\xb0\xeb", "\xd4\xab", +@@ -6919,7 +7019,7 @@ static const char from_ucs4[][2] = + /* 0x572e */ "\xc9\xc8", "\xa6\x65", "\xa6\x61", "\x00\x00", "\x94\xa7", + /* 0x5733 */ "\xa6\x60", "\xc9\xca", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x5737 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa7\xa6", "\x00\x00", +- /* 0x573c */ "\x00\x00", "\xa7\xa3", "\x9b\xd4", "\xa7\x7d", "\xca\xaa", ++ /* 0x573d */ "\x8c\xcc", "\xa7\xa3", "\x9b\xd4", "\xa7\x7d", "\xca\xaa", + /* 0x5742 */ "\xfb\x64", "\xfb\x76", "\x00\x00", "\xca\xab", "\xfb\x60", + /* 0x5747 */ "\xa7\xa1", "\x00\x00", "\xca\xad", "\xa7\x7b", "\xca\xae", + /* 0x574c */ "\xca\xac", "\xa7\x7e", "\xa7\xa2", "\xa7\xa5", "\xa7\xa4", +@@ -6942,7 +7042,7 @@ static const char from_ucs4[][2] = + /* 0x57a1 */ "\x9b\xf4", "\xab\xaf", "\xab\xae", "\xce\x53", "\xce\x5c", + /* 0x57a5 */ "\x00\x00", "\x9e\xf7", "\x00\x00", "\x00\x00", "\x9e\xc1", + /* 0x57aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\xab\xb1", "\x00\x00", +- /* 0x57af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x99\x6f", ++ /* 0x57af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xc3", "\x99\x6f", + /* 0x57b5 */ "\xce\x50", "\xd1\x53", "\x00\x00", "\xd1\x52", "\xd1\x57", + /* 0x57ba */ "\xd1\x4e", "\x96\xf1", "\xd1\x51", "\xd1\x50", "\x8e\x41", + /* 0x57bf */ "\xd1\x54", "\x00\x00", "\xd1\x58", "\xae\x47", "\xae\x4a", +@@ -6962,7 +7062,7 @@ static const char from_ucs4[][2] = + /* 0x5805 */ "\xb0\xed", "\xb0\xef", "\xd4\xbb", "\xd4\xb6", "\xae\x4b", + /* 0x580a */ "\xb0\xee", "\xd4\xb8", "\xd4\xc7", "\xd4\xcb", "\xd4\xc2", + /* 0x580e */ "\x00\x00", "\xd4\xc4", "\x00\x00", "\x97\xe5", "\x00\x00", +- /* 0x5814 */ "\xd4\xae", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x5814 */ "\xd4\xae", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xc8", + /* 0x5819 */ "\xd8\xa1", "\x00\x00", "\xd8\xaa", "\xd8\xa9", "\xb3\xfa", + /* 0x581e */ "\xd8\xa2", "\x00\x00", "\xb3\xfb", "\xb3\xf9", "\x96\x7d", + /* 0x5823 */ "\xd8\xa4", "\xb3\xf6", "\xd8\xa8", "\xfb\x6c", "\xd8\xa3", +@@ -6987,8 +7087,8 @@ static const char from_ucs4[][2] = + /* 0x5882 */ "\xe1\x64", "\xb9\xd2", "\x00\x00", "\xb9\xd6", "\xe1\x5a", + /* 0x5887 */ "\xe1\x60", "\xe1\x65", "\xe1\x56", "\xb9\xd4", "\xe1\x5e", + /* 0x588b */ "\x00\x00", "\x00\x00", "\xe1\x62", "\xe1\x68", "\xe1\x58", +- /* 0x5891 */ "\xe1\x61", "\x00\x00", "\xb9\xd3", "\xe1\x67", "\x00\x00", +- /* 0x5895 */ "\x00\x00", "\x00\x00", "\xe1\x59", "\x8b\xaf", "\x9e\xbd", ++ /* 0x5891 */ "\xe1\x61", "\x8c\x77", "\xb9\xd3", "\xe1\x67", "\x00\x00", ++ /* 0x5896 */ "\x87\xb0", "\x00\x00", "\xe1\x59", "\x8b\xaf", "\x9e\xbd", + /* 0x589a */ "\x00\x00", "\xbc\x59", "\xe5\x4b", "\xbc\x57", "\xbc\x56", + /* 0x58a0 */ "\xe5\x4d", "\xe5\x52", "\x00\x00", "\xe5\x4e", "\x00\x00", + /* 0x58a5 */ "\xe5\x51", "\xbc\x5c", "\x9e\xe6", "\xbe\xa5", "\xbc\x5b", +@@ -6999,7 +7099,7 @@ static const char from_ucs4[][2] = + /* 0x58be */ "\xbe\xc1", "\xe9\x4c", "\x00\x00", "\xbe\xc0", "\xe9\x4e", + /* 0x58c2 */ "\x00\x00", "\x00\x00", "\xbe\xc3", "\xe9\x50", "\xbe\xc2", + /* 0x58c8 */ "\xe9\x49", "\xe9\x4b", "\x00\x00", "\x92\xea", "\x00\x00", +- /* 0x58cc */ "\x00\x00", "\xc0\xa5", "\xec\xcc", "\x00\x00", "\xc0\xa4", ++ /* 0x58cc */ "\x00\x00", "\xc0\xa5", "\xec\xcc", "\x8c\x78", "\xc0\xa4", + /* 0x58d2 */ "\xec\xcd", "\xc0\xa3", "\xec\xcb", "\xc0\xa2", "\xec\xca", + /* 0x58d6 */ "\x00\x00", "\xc2\x53", "\xc2\x52", "\xf1\xf6", "\xf1\xf8", + /* 0x58dc */ "\xfb\x72", "\xf1\xf7", "\xc3\x61", "\xc3\x62", "\xfb\x71", +@@ -7015,7 +7115,7 @@ static const char from_ucs4[][2] = + /* 0x590e */ "\xd1\x59", "\xae\x4c", "\x00\x00", "\xfe\x42", "\xf1\xf9", + /* 0x5912 */ "\x00\x00", "\xc4\xdc", "\xa4\x69", "\xa5\x7e", "\xc9\x70", + /* 0x5917 */ "\x00\x00", "\xa6\x67", "\xa6\x68", "\x00\x00", "\xa9\x5d", +- /* 0x591c */ "\x00\x00", "\x00\x00", "\xfb\x7b", "\xb0\xf7", "\x00\x00", ++ /* 0x591d */ "\x87\x68", "\x00\x00", "\xfb\x7b", "\xb0\xf7", "\x00\x00", + /* 0x5922 */ "\xb9\xda", "\x00\x00", "\xb9\xdb", "\xb9\xd9", "\x00\x00", + /* 0x5927 */ "\xa4\x6a", "\x00\x00", "\xa4\xd1", "\xa4\xd3", "\xa4\xd2", + /* 0x592c */ "\xc9\x5b", "\xa4\xd4", "\xa5\xa1", "\xc9\x71", "\x00\x00", +@@ -7047,7 +7147,7 @@ static const char from_ucs4[][2] = + /* 0x59ae */ "\xa9\x67", "\xa9\x6f", "\x97\xb3", "\xcc\x4f", "\xcc\x48", + /* 0x59b3 */ "\xa9\x70", "\xcc\x53", "\xcc\x44", "\xcc\x4b", "\x9f\x74", + /* 0x59b8 */ "\x92\xf1", "\xa9\x66", "\xcc\x45", "\xa9\x64", "\xcc\x4c", +- /* 0x59bd */ "\xcc\x50", "\xa9\x63", "\x00\x00", "\xcc\x51", "\xcc\x4a", ++ /* 0x59bd */ "\xcc\x50", "\xa9\x63", "\x8c\xfa", "\xcc\x51", "\xcc\x4a", + /* 0x59c1 */ "\x00\x00", "\xcc\x4d", "\x97\xdf", "\xa9\x72", "\xa9\x69", + /* 0x59c7 */ "\xcc\x54", "\xcc\x52", "\xfb\xa6", "\xa9\x6e", "\xa9\x6c", + /* 0x59cc */ "\xcc\x49", "\xa9\x6b", "\xcc\x47", "\xcc\x46", "\xa9\x6a", +@@ -7065,7 +7165,7 @@ static const char from_ucs4[][2] = + /* 0x5a07 */ "\x00\x00", "\xae\x5c", "\xd1\x62", "\x97\x42", "\xae\x5b", + /* 0x5a0d */ "\x94\xe6", "\x00\x00", "\xd1\x60", "\x00\x00", "\xae\x50", + /* 0x5a12 */ "\x92\xf5", "\xae\x55", "\x00\x00", "\xd1\x5f", "\xd1\x5c", +- /* 0x5a17 */ "\xd1\x61", "\xae\x51", "\xd1\x5b", "\x00\x00", "\xae\x54", ++ /* 0x5a17 */ "\xd1\x61", "\xae\x51", "\xd1\x5b", "\x8c\xc5", "\xae\x54", + /* 0x5a1c */ "\xae\x52", "\x00\x00", "\xd1\x63", "\xae\x53", "\xae\x57", + /* 0x5a21 */ "\x92\xfd", "\x00\x00", "\xae\x58", "\xfb\xa2", "\xae\x5a", + /* 0x5a25 */ "\x00\x00", "\x9c\x51", "\x00\x00", "\xae\x59", "\x94\xe9", +@@ -7093,7 +7193,7 @@ static const char from_ucs4[][2] = + /* 0x5a94 */ "\xd8\xb6", "\xd8\xc0", "\xfb\xba", "\xd8\xc5", "\x00\x00", + /* 0x5a99 */ "\x92\xeb", "\xb4\x41", "\xb4\x44", "\xd8\xcc", "\xd8\xcf", + /* 0x5a9e */ "\xd8\xba", "\xd8\xb7", "\xfc\x73", "\x97\xb7", "\xd8\xb9", +- /* 0x5aa2 */ "\x00\x00", "\x00\x00", "\xd8\xbe", "\xd8\xbc", "\xb4\x45", ++ /* 0x5aa2 */ "\x00\x00", "\x87\x6f", "\xd8\xbe", "\xd8\xbc", "\xb4\x45", + /* 0x5aa7 */ "\x00\x00", "\xd8\xc8", "\x00\x00", "\xfb\xb4", "\xd8\xbf", + /* 0x5aac */ "\x00\x00", "\xd8\xc1", "\xd8\xb5", "\xdc\xfa", "\xdc\xf8", + /* 0x5ab2 */ "\xb7\x42", "\xb7\x40", "\xdd\x43", "\xdc\xf9", "\xdd\x44", +@@ -7102,7 +7202,7 @@ static const char from_ucs4[][2] = + /* 0x5ac1 */ "\xb6\xf9", "\xb7\x41", "\x90\xa7", "\xdc\xf4", "\x00\x00", + /* 0x5ac6 */ "\xdc\xfe", "\xdc\xf3", "\xdc\xfc", "\xb6\xfa", "\xdd\x42", + /* 0x5acb */ "\xdc\xf5", "\xb6\xfb", "\xdd\x45", "\x97\x41", "\x92\xf4", +- /* 0x5acf */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xbc", "\x00\x00", ++ /* 0x5acf */ "\x00\x00", "\x87\x72", "\x00\x00", "\xfb\xbc", "\x00\x00", + /* 0x5ad5 */ "\xe1\x6e", "\xb9\xe2", "\xb9\xe1", "\xb9\xe3", "\xe1\x7a", + /* 0x5ada */ "\xe1\x70", "\xe1\x76", "\xe1\x6b", "\xe1\x79", "\xe1\x78", + /* 0x5adf */ "\xe1\x7c", "\xe1\x75", "\xb9\xde", "\xe1\x74", "\xb9\xe4", +@@ -7115,7 +7215,7 @@ static const char from_ucs4[][2] = + /* 0x5b02 */ "\xe5\x5b", "\xe5\x59", "\x00\x00", "\xe5\x5f", "\x00\x00", + /* 0x5b07 */ "\xe5\x5e", "\xbc\x63", "\xbc\x5e", "\x00\x00", "\xbc\x60", + /* 0x5b0c */ "\xbc\x62", "\x9e\xb5", "\x00\x00", "\xe5\x60", "\xe9\x57", +- /* 0x5b11 */ "\x96\x4b", "\x00\x00", "\xe9\x56", "\xe9\x55", "\x00\x00", ++ /* 0x5b11 */ "\x96\x4b", "\x00\x00", "\xe9\x56", "\xe9\x55", "\x8c\xac", + /* 0x5b16 */ "\xe9\x58", "\xe9\x51", "\x00\x00", "\xe9\x52", "\xe9\x5a", + /* 0x5b1b */ "\xe9\x53", "\x00\x00", "\xbe\xc5", "\xe9\x5c", "\xa0\xfa", + /* 0x5b20 */ "\xe9\x5b", "\xe9\x54", "\x00\x00", "\xec\xd1", "\xc0\xa8", +@@ -7141,21 +7241,21 @@ static const char from_ucs4[][2] = + /* 0x5b84 */ "\xc9\x73", "\xa6\x76", "\x00\x00", "\xa6\x74", "\xa6\x75", + /* 0x5b89 */ "\xa6\x77", "\x00\x00", "\xa7\xba", "\xa7\xb9", "\x00\x00", + /* 0x5b8e */ "\xca\xbc", "\xa7\xbb", "\x9e\x67", "\x00\x00", "\xca\xbd", +- /* 0x5b93 */ "\xcc\x57", "\x00\x00", "\xcc\x58", "\x00\x00", "\xa9\x76", ++ /* 0x5b93 */ "\xcc\x57", "\x00\x00", "\xcc\x58", "\x8c\xd9", "\xa9\x76", + /* 0x5b98 */ "\xa9\x78", "\xa9\x7a", "\xa9\x77", "\xa9\x7b", "\xa9\x79", + /* 0x5b9d */ "\xfb\xd2", "\x89\x62", "\x89\x63", "\x00\x00", "\x00\x00", + /* 0x5ba2 */ "\xab\xc8", "\xab\xc5", "\xab\xc7", "\xab\xc9", "\xab\xc6", + /* 0x5ba7 */ "\xd1\x66", "\xce\x77", "\x00\x00", "\xfc\x7d", "\x00\x00", + /* 0x5bac */ "\xd1\x68", "\xd1\x67", "\xae\x63", "\x00\x00", "\xae\x5f", + /* 0x5bb0 */ "\x00\x00", "\x00\x00", "\xae\x60", "\xae\x62", "\xae\x64", +- /* 0x5bb6 */ "\xae\x61", "\x00\x00", "\xae\x66", "\xae\x65", "\x00\x00", ++ /* 0x5bb6 */ "\xae\x61", "\x87\x73", "\xae\x66", "\xae\x65", "\x00\x00", + /* 0x5bba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xb1\x4a", + /* 0x5bc0 */ "\xd4\xf2", "\xd4\xf1", "\xb1\x49", "\x9f\x6b", "\xb1\x48", + /* 0x5bc5 */ "\xb1\x47", "\xb1\x4b", "\xb1\x46", "\x00\x00", "\x00\x00", + /* 0x5bca */ "\xd8\xd5", "\xd8\xd2", "\xb4\x49", "\xd8\xd1", "\xd8\xd6", + /* 0x5bce */ "\x00\x00", "\xb4\x4b", "\xd8\xd4", "\xb4\x48", "\xb4\x4a", + /* 0x5bd4 */ "\xd8\xd3", "\xfb\xcc", "\xdd\x48", "\xfe\xae", "\xdd\x49", +- /* 0x5bd9 */ "\xdd\x4a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x5bd9 */ "\xdd\x4a", "\x00\x00", "\x87\x6d", "\x00\x00", "\x00\x00", + /* 0x5bde */ "\xb9\xe6", "\xb9\xee", "\xe1\x7e", "\xb9\xe8", "\xb9\xec", + /* 0x5be3 */ "\xe1\xa1", "\xb9\xed", "\xb9\xe9", "\xb9\xea", "\xb9\xe7", + /* 0x5be8 */ "\xb9\xeb", "\xbc\x66", "\xd8\xd0", "\xbc\x67", "\xbc\x65", +@@ -7186,7 +7286,7 @@ static const char from_ucs4[][2] = + /* 0x5c65 */ "\xbc\x69", "\x00\x00", "\xe5\x61", "\xc0\xab", "\xef\xc2", + /* 0x5c6a */ "\xef\xc3", "\x00\x00", "\xc4\xdd", "\xf8\xa8", "\xc9\x4b", + /* 0x5c6f */ "\xa4\xd9", "\x00\x00", "\xa4\x73", "\x00\x00", "\xc9\x77", +- /* 0x5c74 */ "\xc9\x76", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x5c74 */ "\xc9\x76", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xe9", + /* 0x5c79 */ "\xa6\x7a", "\xc9\xd7", "\xc9\xd8", "\xc9\xd6", "\x00\x00", + /* 0x5c7e */ "\xc9\xd9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x5c82 */ "\x00\x00", "\x00\x00", "\xfb\xdd", "\xca\xc7", "\x00\x00", +@@ -7205,15 +7305,15 @@ static const char from_ucs4[][2] = + /* 0x5cc3 */ "\x00\x00", "\x00\x00", "\xce\xab", "\xce\xa4", "\xce\xaa", + /* 0x5cc9 */ "\xce\xa3", "\xce\xa5", "\xce\x7d", "\xce\x7b", "\x00\x00", + /* 0x5cce */ "\xce\xac", "\xce\xa9", "\xce\x79", "\x9f\x58", "\xab\xd0", +- /* 0x5cd3 */ "\xce\xa7", "\xce\xa8", "\x00\x00", "\xce\xa6", "\xce\x7c", ++ /* 0x5cd3 */ "\xce\xa7", "\xce\xa8", "\x8c\xe6", "\xce\xa6", "\xce\x7c", + /* 0x5cd8 */ "\xce\x7a", "\xab\xcf", "\xce\xa2", "\xce\x7e", "\x00\x00", + /* 0x5cdc */ "\x00\x00", "\xce\xa1", "\xce\xad", "\x00\x00", "\x00\x00", + /* 0x5ce1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x73", "\x00\x00", + /* 0x5ce6 */ "\x00\x00", "\xae\x6f", "\xfb\xde", "\xae\x6e", "\x00\x00", + /* 0x5cec */ "\xd1\x6c", "\xae\x6b", "\xd1\x6e", "\xfb\xdf", "\xae\x70", +- /* 0x5cf1 */ "\xd1\x6f", "\x00\x00", "\x00\x00", "\xae\x73", "\x00\x00", ++ /* 0x5cf1 */ "\xd1\x6f", "\x00\x00", "\x00\x00", "\xae\x73", "\x8c\x48", + /* 0x5cf6 */ "\xae\x71", "\xd1\x70", "\xce\xae", "\xd1\x72", "\x00\x00", +- /* 0x5cfb */ "\xae\x6d", "\x00\x00", "\xae\x6c", "\x00\x00", "\xd1\x6d", ++ /* 0x5cfb */ "\xae\x6d", "\x87\x74", "\xae\x6c", "\x00\x00", "\xd1\x6d", + /* 0x5d00 */ "\xd1\x71", "\xae\x72", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x5d04 */ "\x00\x00", "\xb1\x53", "\xb1\x52", "\x00\x00", "\x00\x00", + /* 0x5d09 */ "\x00\x00", "\xd4\xf5", "\xd4\xf9", "\xd4\xfb", "\xb1\x54", +@@ -7238,7 +7338,7 @@ static const char from_ucs4[][2] = + /* 0x5d69 */ "\xb7\x43", "\x00\x00", "\xd8\xdb", "\xdd\x52", "\x00\x00", + /* 0x5d6d */ "\x00\x00", "\xb7\x44", "\x98\xad", "\xdd\x4d", "\xdd\x51", + /* 0x5d72 */ "\x00\x00", "\x9e\xea", "\x00\x00", "\x00\x00", "\xe1\xa9", +- /* 0x5d77 */ "\x00\x00", "\xe1\xb0", "\xe1\xa7", "\x00\x00", "\xe1\xae", ++ /* 0x5d78 */ "\x8c\xec", "\xe1\xb0", "\xe1\xa7", "\x8c\xd4", "\xe1\xae", + /* 0x5d7d */ "\xe1\xa5", "\xe1\xad", "\xe1\xb1", "\xe1\xa4", "\xe1\xa8", + /* 0x5d82 */ "\xe1\xa3", "\x00\x00", "\xb9\xf1", "\x9c\xeb", "\xe1\xa6", + /* 0x5d87 */ "\xb9\xf2", "\xe1\xac", "\xe1\xab", "\xe1\xaa", "\xfb\xe0", +@@ -7294,8 +7394,8 @@ static const char from_ucs4[][2] = + /* 0x5e80 */ "\x00\x00", "\xc9\x7a", "\xfb\xc3", "\xc9\xdc", "\x00\x00", + /* 0x5e86 */ "\x89\x65", "\xa7\xc8", "\xca\xd0", "\xca\xce", "\xa7\xc9", + /* 0x5e8b */ "\xca\xcd", "\xca\xcf", "\xca\xd1", "\x00\x00", "\xa7\xc7", +- /* 0x5e8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x5e95 */ "\xa9\xb3", "\xa9\xb4", "\xa9\xb1", "\x00\x00", "\x00\x00", ++ /* 0x5e8f */ "\x00\x00", "\x00\x00", "\x8c\x7a", "\x00\x00", "\x00\x00", ++ /* 0x5e95 */ "\xa9\xb3", "\xa9\xb4", "\xa9\xb1", "\x00\x00", "\x8c\x7b", + /* 0x5e9a */ "\xa9\xb0", "\xce\xb8", "\xa9\xb2", "\x00\x00", "\x00\x00", + /* 0x5e9e */ "\x00\x00", "\xab\xd6", "\x00\x00", "\xce\xb7", "\xce\xb9", + /* 0x5ea4 */ "\xce\xb6", "\xce\xba", "\xab\xd7", "\xae\x79", "\xd1\x75", +@@ -7328,7 +7428,7 @@ static const char from_ucs4[][2] = + /* 0x5f2a */ "\x00\x00", "\x00\x00", "\xab\xda", "\xce\xbc", "\x00\x00", + /* 0x5f30 */ "\xd1\x7a", "\xae\x7a", "\x00\x00", "\xd1\x79", "\x00\x00", + /* 0x5f35 */ "\xb1\x69", "\xd5\x4c", "\xb1\x6a", "\xd5\x4d", "\x00\x00", +- /* 0x5f3a */ "\xfc\x4c", "\x00\x00", "\xb4\x5d", "\x00\x00", "\x00\x00", ++ /* 0x5f3a */ "\xfc\x4c", "\x8c\xfe", "\xb4\x5d", "\x00\x00", "\x00\x00", + /* 0x5f3e */ "\x00\x00", "\xdd\x62", "\x00\x00", "\x00\x00", "\xe1\xbf", + /* 0x5f44 */ "\xe1\xbe", "\x00\x00", "\xb9\xfb", "\x00\x00", "\xbc\x75", + /* 0x5f49 */ "\xe5\x76", "\xbe\xca", "\xe9\x74", "\xc0\xb1", "\x95\xb8", +@@ -7355,7 +7455,7 @@ static const char from_ucs4[][2] = + /* 0x5fb2 */ "\xe5\x77", "\x00\x00", "\x00\x00", "\xbc\x78", "\xe1\xc1", + /* 0x5fb7 */ "\xbc\x77", "\x00\x00", "\xb9\xfd", "\xa0\x51", "\xec\xde", + /* 0x5fbc */ "\xe9\x75", "\xc0\xb2", "\xec\xdd", "\xf2\x40", "\xf4\x48", +- /* 0x5fc1 */ "\xf4\x49", "\x00\x00", "\xa4\xdf", "\x8b\xcb", "\xa5\xb2", ++ /* 0x5fc1 */ "\xf4\x49", "\x8c\x7c", "\xa4\xdf", "\x8b\xcb", "\xa5\xb2", + /* 0x5fc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xc9\x7b", "\x00\x00", + /* 0x5fca */ "\x00\x00", "\xa7\xd2", "\xa7\xd4", "\x00\x00", "\xc9\xe2", + /* 0x5fd0 */ "\xca\xd8", "\xca\xd7", "\xca\xd6", "\x00\x00", "\xc9\xe1", +@@ -7425,7 +7525,7 @@ static const char from_ucs4[][2] = + /* 0x6110 */ "\xd9\x4d", "\x00\x00", "\xb4\x74", "\xd9\x45", "\xd8\xfe", + /* 0x6115 */ "\xb4\x6a", "\xd9\x42", "\x00\x00", "\xd9\x4b", "\x9e\xf1", + /* 0x611a */ "\xb7\x4d", "\xb7\x52", "\xb4\x67", "\xd9\x4c", "\x00\x00", +- /* 0x611f */ "\xb7\x50", "\x00\x00", "\x00\x00", "\x00\x00", "\xb4\x68", ++ /* 0x611f */ "\xb7\x50", "\x00\x00", "\x00\x00", "\x8c\x4d", "\xb4\x68", + /* 0x6123 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xb7\x5c", "\xe1\xc3", + /* 0x6129 */ "\xdd\x70", "\x00\x00", "\xdd\x68", "\xe1\xc2", "\x00\x00", + /* 0x612e */ "\xdd\x6c", "\xdd\x6e", "\x9f\x7e", "\x00\x00", "\xdd\x6b", +@@ -7508,7 +7608,7 @@ static const char from_ucs4[][2] = + /* 0x62af */ "\xcc\xbc", "\xcc\xbf", "\xa9\xea", "\x00\x00", "\xcc\xbb", + /* 0x62b4 */ "\xcc\xb4", "\xa9\xe8", "\xcc\xb8", "\x00\x00", "\xcc\xc0", + /* 0x62b9 */ "\xa9\xd9", "\x00\x00", "\xcc\xbd", "\xa9\xe3", "\xa9\xe2", +- /* 0x62be */ "\xcc\xb6", "\xa9\xd7", "\x00\x00", "\x00\x00", "\xa9\xd8", ++ /* 0x62be */ "\xcc\xb6", "\xa9\xd7", "\x00\x00", "\x87\xdd", "\xa9\xd8", + /* 0x62c3 */ "\x9b\x46", "\xa9\xd6", "\xfc\xae", "\xa9\xee", "\xa9\xe6", + /* 0x62c8 */ "\xa9\xe0", "\xa9\xd4", "\xcc\xb9", "\xa9\xdf", "\xa9\xd5", + /* 0x62cd */ "\xa9\xe7", "\xa9\xf0", "\xce\xd4", "\xa9\xe4", "\xcc\xb5", +@@ -7651,7 +7751,7 @@ static const char from_ucs4[][2] = + /* 0x657a */ "\xe5\xbe", "\xe5\xc0", "\xe9\xb1", "\x00\x00", "\x00\x00", + /* 0x657f */ "\xe9\xb0", "\xec\xef", "\xec\xee", "\xc0\xc4", "\xc0\xc5", + /* 0x6584 */ "\xf2\x48", "\xfc\xc9", "\x8d\xac", "\xa4\xe5", "\xfb\xc6", +- /* 0x6589 */ "\x89\x67", "\x00\x00", "\x00\x00", "\xd9\x79", "\x00\x00", ++ /* 0x6589 */ "\x89\x67", "\x00\x00", "\x8c\x7e", "\xd9\x79", "\x00\x00", + /* 0x658d */ "\x00\x00", "\x00\x00", "\xb4\xb4", "\xb4\xb3", "\xdd\xbd", + /* 0x6592 */ "\x00\x00", "\xef\xd8", "\xc4\xe3", "\xf7\xde", "\xa4\xe6", + /* 0x6597 */ "\x00\x00", "\xae\xc6", "\x00\x00", "\xb1\xd8", "\xb1\xd7", +@@ -7690,11 +7790,11 @@ static const char from_ucs4[][2] = + /* 0x663c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xae\xd0", + /* 0x6642 */ "\xae\xc9", "\xae\xcc", "\xfc\xda", "\xae\xcf", "\x00\x00", + /* 0x6647 */ "\xd1\xd5", "\x9b\x71", "\xae\xca", "\xd1\xd3", "\xfc\xdd", +- /* 0x664c */ "\xae\xce", "\x00\x00", "\x00\x00", "\xae\xcb", "\x00\x00", ++ /* 0x664c */ "\xae\xce", "\x87\x64", "\x00\x00", "\xae\xcb", "\x00\x00", + /* 0x6651 */ "\xd1\xd6", "\xae\xcd", "\x8d\xaf", "\x00\x00", "\x00\x00", + /* 0x6655 */ "\x00\x00", "\xfa\xf2", "\x00\x00", "\xd5\xac", "\xb1\xdf", + /* 0x665b */ "\xd5\xab", "\xd5\xad", "\xb1\xde", "\xb1\xe3", "\xd1\xd4", +- /* 0x665f */ "\x00\x00", "\xd5\xaa", "\xd5\xae", "\x93\xd8", "\xb1\xe0", ++ /* 0x6660 */ "\x87\xb5", "\xd5\xaa", "\xd5\xae", "\x93\xd8", "\xb1\xe0", + /* 0x6665 */ "\xd5\xa9", "\xb1\xe2", "\xfc\xdf", "\xb1\xe1", "\x00\x00", + /* 0x666a */ "\xd9\xa7", "\x93\xd3", "\xd9\xa2", "\x00\x00", "\xb4\xb6", + /* 0x666f */ "\xb4\xba", "\xb4\xb7", "\xd9\xa5", "\xd9\xa8", "\xfc\xe1", +@@ -7721,7 +7821,7 @@ static const char from_ucs4[][2] = + /* 0x66d8 */ "\xef\xdc", "\xc0\xc6", "\xef\xda", "\xef\xdb", "\xc2\x60", + /* 0x66dd */ "\xc3\x6e", "\xf2\x4b", "\x00\x00", "\xc3\x6d", "\x00\x00", + /* 0x66e1 */ "\x00\x00", "\xf4\x51", "\xf4\x52", "\x00\x00", "\xc4\x66", +- /* 0x66e6 */ "\x00\x00", "\xf4\x50", "\xc4\xe4", "\x00\x00", "\xf7\xdf", ++ /* 0x66e7 */ "\x8c\xdb", "\xf4\x50", "\xc4\xe4", "\x00\x00", "\xf7\xdf", + /* 0x66ec */ "\xc5\xce", "\xf8\xaa", "\xf8\xab", "\x00\x00", "\xa4\xea", + /* 0x66f1 */ "\x9d\xf1", "\xa6\xb1", "\xa6\xb2", "\xa7\xf3", "\x00\x00", + /* 0x66f6 */ "\xcc\xd1", "\xac\x54", "\xae\xd1", "\xb1\xe4", "\x00\x00", +@@ -7731,7 +7831,7 @@ static const char from_ucs4[][2] = + /* 0x670a */ "\xcc\xd2", "\xaa\x42", "\xa0\xbb", "\xaa\x41", "\x9b\x7e", + /* 0x670f */ "\xce\xf9", "\xce\xfa", "\x00\x00", "\xd1\xd7", "\xd1\xd8", + /* 0x6714 */ "\xae\xd2", "\xae\xd3", "\x8d\xb3", "\xae\xd4", "\xd5\xaf", +- /* 0x6718 */ "\x00\x00", "\x00\x00", "\xb1\xe6", "\x00\x00", "\xb4\xc2", ++ /* 0x6719 */ "\x8c\x52", "\x00\x00", "\xb1\xe6", "\x00\x00", "\xb4\xc2", + /* 0x671e */ "\x9a\xe8", "\xb4\xc1", "\xdd\xc8", "\xdf\x7a", "\xe1\xfb", + /* 0x6723 */ "\xe9\xbd", "\x00\x00", "\x8e\xdc", "\xc2\x61", "\xc4\x67", + /* 0x6728 */ "\xa4\xec", "\x00\x00", "\xa5\xbc", "\xa5\xbd", "\xa5\xbb", +@@ -7747,12 +7847,12 @@ static const char from_ucs4[][2] = + /* 0x675a */ "\xcb\x46", "\x00\x00", "\xa7\xf9", "\xcb\x44", "\xa7\xfb", + /* 0x675f */ "\xa7\xf4", "\xa7\xfe", "\x98\xe7", "\xfc\xf3", "\x00\x00", + /* 0x6763 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xf2", "\x00\x00", +- /* 0x6768 */ "\x00\x00", "\xaa\x57", "\x00\x00", "\xcc\xd4", "\xaa\x43", +- /* 0x676d */ "\x00\x00", "\xaa\x4d", "\xaa\x4e", "\xaa\x46", "\xaa\x58", ++ /* 0x6768 */ "\x00\x00", "\xaa\x57", "\x8c\xca", "\xcc\xd4", "\xaa\x43", ++ /* 0x676e */ "\x87\x75", "\xaa\x4d", "\xaa\x4e", "\xaa\x46", "\xaa\x58", + /* 0x6773 */ "\xaa\x48", "\xcc\xdc", "\xaa\x53", "\xcc\xd7", "\xaa\x49", + /* 0x6778 */ "\xcc\xe6", "\xcc\xe7", "\xcc\xdf", "\xcc\xd8", "\xaa\x56", + /* 0x677d */ "\xcc\xe4", "\xaa\x51", "\xaa\x4f", "\x00\x00", "\xcc\xe5", +- /* 0x6781 */ "\x00\x00", "\xcc\xe3", "\xcc\xdb", "\xcc\xd3", "\xcc\xda", ++ /* 0x6782 */ "\x87\xba", "\xcc\xe3", "\xcc\xdb", "\xcc\xd3", "\xcc\xda", + /* 0x6787 */ "\xaa\x4a", "\x00\x00", "\xaa\x50", "\x00\x00", "\xaa\x44", + /* 0x678c */ "\xcc\xde", "\xcc\xdd", "\xcc\xd5", "\x93\xe5", "\xaa\x52", + /* 0x6791 */ "\xcc\xe1", "\xcc\xd6", "\xaa\x55", "\xcc\xe8", "\xaa\x45", +@@ -7833,7 +7933,7 @@ static const char from_ucs4[][2] = + /* 0x6908 */ "\xd9\xbe", "\x8d\xbd", "\xd9\xcb", "\xd9\xca", "\xd9\xaa", + /* 0x690d */ "\xb4\xd3", "\xb4\xd5", "\xd9\xb2", "\xd9\xb9", "\xd9\xc1", + /* 0x6912 */ "\xb4\xd4", "\xd9\xb8", "\xd9\xc4", "\xd9\xd7", "\x00\x00", +- /* 0x6917 */ "\xd9\xcc", "\x9b\xa1", "\x00\x00", "\x9a\xb7", "\x8e\xfc", ++ /* 0x6917 */ "\xd9\xcc", "\x9b\xa1", "\x8c\xa2", "\x9a\xb7", "\x8e\xfc", + /* 0x691b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x6920 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xd9\xd8", + /* 0x6925 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xd9\xae", +@@ -7887,19 +7987,19 @@ static const char from_ucs4[][2] = + /* 0x6a16 */ "\xe5\xef", "\xe5\xcc", "\xe5\xe8", "\xbc\xd0", "\x97\xf9", + /* 0x6a1b */ "\xe5\xd6", "\x95\x58", "\xe5\xd7", "\xbc\xcf", "\xbc\xcc", + /* 0x6a20 */ "\xe5\xd2", "\xbc\xd2", "\x00\x00", "\xbc\xcb", "\x00\x00", +- /* 0x6a25 */ "\xe5\xe9", "\xe5\xec", "\xe5\xd9", "\xe9\xca", "\x00\x00", ++ /* 0x6a25 */ "\xe5\xe9", "\xe5\xec", "\xe5\xd9", "\xe9\xca", "\x87\xb6", + /* 0x6a29 */ "\x00\x00", "\x98\x5e", "\xfe\x7b", "\x94\xcd", "\x00\x00", + /* 0x6a2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\xe9\xc2", "\x93\xee", + /* 0x6a34 */ "\xe9\xbe", "\xbe\xf6", "\x00\x00", "\x00\x00", "\xbe\xeb", + /* 0x6a39 */ "\xbe\xf0", "\xbe\xec", "\xe9\xcc", "\xe9\xd7", "\xbe\xea", + /* 0x6a3e */ "\xe9\xc4", "\xe9\xcd", "\xe5\xdf", "\xe9\xce", "\x00\x00", +- /* 0x6a42 */ "\x00\x00", "\xbe\xf1", "\xfd\x5a", "\xe9\xdd", "\xbe\xf5", ++ /* 0x6a43 */ "\x8c\xa3", "\xbe\xf1", "\xfd\x5a", "\xe9\xdd", "\xbe\xf5", + /* 0x6a48 */ "\xbe\xf8", "\xe9\xc0", "\x00\x00", "\xbe\xf4", "\x93\xf5", + /* 0x6a4d */ "\xe9\xdb", "\xe9\xdc", "\xe9\xd2", "\xe9\xd1", "\xe9\xc9", + /* 0x6a52 */ "\x93\xef", "\x8e\xea", "\xe9\xd3", "\xe9\xda", "\xe9\xd9", + /* 0x6a57 */ "\x8f\x5b", "\xbe\xef", "\xbe\xed", "\xe9\xcb", "\xe9\xc8", + /* 0x6a5b */ "\x00\x00", "\xe9\xc5", "\xe9\xd8", "\xbe\xf7", "\xe9\xd6", +- /* 0x6a61 */ "\xbe\xf3", "\xbe\xf2", "\x00\x00", "\xe9\xd0", "\x8d\xc6", ++ /* 0x6a61 */ "\xbe\xf3", "\xbe\xf2", "\x8c\x5e", "\xe9\xd0", "\x8d\xc6", + /* 0x6a66 */ "\xe9\xbf", "\xe9\xc1", "\xe9\xc3", "\xe9\xd5", "\xe9\xcf", + /* 0x6a6b */ "\xbe\xee", "\x00\x00", "\xe9\xc6", "\x00\x00", "\xe9\xd4", + /* 0x6a6f */ "\x00\x00", "\x8d\xc8", "\x00\x00", "\x00\x00", "\x8d\xc7", +@@ -8033,7 +8133,7 @@ static const char from_ucs4[][2] = + /* 0x6cf0 */ "\xae\xf5", "\xaa\x74", "\xcc\xfe", "\xaa\x61", "\x00\x00", + /* 0x6cf5 */ "\xac\xa6", "\x00\x00", "\x00\x00", "\x00\x00", "\xcd\x4c", + /* 0x6cf9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x6cfe */ "\x00\x00", "\xcf\x7c", "\xcf\xa1", "\x8d\xd7", "\xcf\xa4", ++ /* 0x6cff */ "\x8c\xa5", "\xcf\x7c", "\xcf\xa1", "\x8d\xd7", "\xcf\xa4", + /* 0x6d04 */ "\xcf\x77", "\x92\xfb", "\x8d\xd8", "\xcf\xa7", "\xcf\xaa", + /* 0x6d09 */ "\xcf\xac", "\xcf\x74", "\xac\x76", "\xac\x7b", "\xd2\x49", + /* 0x6d0e */ "\xac\xad", "\xcf\xa5", "\xcf\xad", "\xcf\x7b", "\xcf\x73", +@@ -8084,7 +8184,7 @@ static const char from_ucs4[][2] = + /* 0x6def */ "\xd2\x52", "\xd5\xf9", "\xb2\x60", "\xd6\x41", "\xb2\x45", + /* 0x6df4 */ "\xd5\xf5", "\xb2\x57", "\xd5\xe9", "\xb2\x56", "\x00\x00", + /* 0x6df9 */ "\xb2\x54", "\xb2\x4c", "\xb2\x4b", "\xd9\xe7", "\xd6\x43", +- /* 0x6dfd */ "\x00\x00", "\x00\x00", "\xd5\xeb", "\x00\x00", "\x97\xd5", ++ /* 0x6dfe */ "\x8c\x41", "\x00\x00", "\xd5\xeb", "\x00\x00", "\x97\xd5", + /* 0x6e03 */ "\xd9\xfc", "\x94\x4a", "\xb2\x4d", "\x00\x00", "\x00\x00", + /* 0x6e07 */ "\x00\x00", "\x00\x00", "\x94\x4d", "\x00\x00", "\x00\x00", + /* 0x6e0c */ "\x00\x00", "\x00\x00", "\x97\xcb", "\x00\x00", "\x00\x00", +@@ -8101,7 +8201,7 @@ static const char from_ucs4[][2] = + /* 0x6e44 */ "\xb5\x44", "\xd9\xef", "\xd9\xe8", "\xd9\xe9", "\x00\x00", + /* 0x6e49 */ "\xd9\xeb", "\xb4\xea", "\xd9\xf8", "\x00\x00", "\xb4\xf8", + /* 0x6e4e */ "\xb5\x42", "\xfd\xc0", "\xfc\xf9", "\xd9\xfa", "\xda\x53", +- /* 0x6e53 */ "\xda\x4b", "\xb4\xe6", "\xda\x51", "\xb4\xf2", "\x00\x00", ++ /* 0x6e53 */ "\xda\x4b", "\xb4\xe6", "\xda\x51", "\xb4\xf2", "\x8c\xdd", + /* 0x6e58 */ "\xb4\xf0", "\xfb\x7e", "\xda\x57", "\xb4\xef", "\xda\x41", + /* 0x6e5d */ "\xd9\xf4", "\xd9\xfe", "\xb5\x47", "\xda\x45", "\xda\x42", + /* 0x6e62 */ "\xd9\xf0", "\xb5\x43", "\xda\x4f", "\xda\x4c", "\xda\x54", +@@ -8202,15 +8302,15 @@ static const char from_ucs4[][2] = + /* 0x703c */ "\x00\x00", "\xc4\x69", "\xf4\x63", "\xf4\x66", "\xf4\x69", + /* 0x7042 */ "\xf4\x61", "\xf5\xd3", "\xf5\xd4", "\xf5\xd8", "\xf5\xd9", + /* 0x7046 */ "\x00\x00", "\xf5\xd6", "\xf5\xd7", "\xf5\xd5", "\xfd\xe0", +- /* 0x704c */ "\xc4\xe9", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\xf6", ++ /* 0x704c */ "\xc4\xe9", "\x8c\x67", "\x00\x00", "\x00\x00", "\x8d\xf6", + /* 0x7051 */ "\xc5\x78", "\xf6\xeb", "\x00\x00", "\x8d\xf7", "\xf6\xe8", + /* 0x7056 */ "\xf6\xe9", "\xf6\xea", "\xc5\x79", "\x00\x00", "\xf7\xe5", + /* 0x705b */ "\xf7\xe4", "\x8f\xfa", "\xf8\xaf", "\xc5\xf4", "\xf8\xad", + /* 0x7060 */ "\xf8\xb0", "\xf8\xae", "\xf8\xf5", "\xc6\x57", "\xc6\x65", + /* 0x7065 */ "\xf9\xa3", "\xf9\x6c", "\x97\xd0", "\xf9\xa2", "\xf9\xd0", +- /* 0x706a */ "\xf9\xd1", "\xa4\xf5", "\x8b\xd2", "\x00\x00", "\x00\x00", ++ /* 0x706a */ "\xf9\xd1", "\xa4\xf5", "\x8b\xd2", "\x00\x00", "\x87\xde", + /* 0x706f */ "\x8d\xf8", "\xa6\xc7", "\xca\x41", "\x00\x00", "\x00\x00", +- /* 0x7074 */ "\xcb\x5e", "\x90\xd9", "\xa8\x5f", "\x00\x00", "\xa8\x62", ++ /* 0x7074 */ "\xcb\x5e", "\x90\xd9", "\xa8\x5f", "\x8c\x47", "\xa8\x62", + /* 0x7079 */ "\xfa\xf0", "\xcb\x5f", "\x00\x00", "\xa8\x60", "\xa8\x61", + /* 0x707e */ "\xfd\xe1", "\x8d\xf9", "\x00\x00", "\xfd\xe3", "\xcd\x58", + /* 0x7083 */ "\xcd\x5a", "\xcd\x55", "\xcd\x52", "\xcd\x54", "\x00\x00", +@@ -8255,7 +8355,7 @@ static const char from_ucs4[][2] = + /* 0x7146 */ "\xb7\xda", "\xde\x6b", "\x00\x00", "\xb7\xd2", "\xfd\xf0", + /* 0x714b */ "\xde\x7a", "\xb7\xd7", "\xde\xa2", "\xb7\xce", "\xfd\xf4", + /* 0x7150 */ "\xde\x7d", "\x9b\xf5", "\xde\x6d", "\xde\x7e", "\xde\x6c", +- /* 0x7154 */ "\x00\x00", "\xb7\xdc", "\x00\x00", "\xde\x78", "\xb7\xcf", ++ /* 0x7154 */ "\x00\x00", "\xb7\xdc", "\x8c\xee", "\xde\x78", "\xb7\xcf", + /* 0x715a */ "\xde\xa3", "\x00\x00", "\xb7\xd4", "\xde\x71", "\xb7\xd9", + /* 0x715f */ "\xde\x7c", "\xde\x6f", "\xde\x76", "\xde\x72", "\xde\x6e", + /* 0x7164 */ "\xb7\xd1", "\xb7\xd8", "\xb7\xd6", "\xb7\xd3", "\xb7\xdb", +@@ -8267,7 +8367,7 @@ static const char from_ucs4[][2] = + /* 0x7182 */ "\xe2\xbf", "\x00\x00", "\xba\xb6", "\xe2\xbe", "\xe2\xc2", + /* 0x7187 */ "\xe2\xba", "\x98\xe0", "\xe2\xbc", "\xba\xb5", "\x00\x00", + /* 0x718c */ "\x92\xca", "\x00\x00", "\x98\x57", "\xe2\xc0", "\xe2\xbb", +- /* 0x7190 */ "\x00\x00", "\xba\xb7", "\x00\x00", "\xba\xb2", "\x00\x00", ++ /* 0x7191 */ "\x8c\x51", "\xba\xb7", "\x00\x00", "\xba\xb2", "\x00\x00", + /* 0x7196 */ "\xfd\xeb", "\xe2\xc4", "\x9b\x49", "\xba\xb3", "\xe6\x67", + /* 0x719b */ "\xe6\x64", "\xe6\x70", "\xe6\x6a", "\xe6\x6c", "\xbc\xf4", + /* 0x71a0 */ "\xe6\x66", "\xe6\x6e", "\x9d\x76", "\x9e\xaf", "\xe6\x6d", +@@ -8289,14 +8389,14 @@ static const char from_ucs4[][2] = + /* 0x71f0 */ "\xed\x61", "\xed\x5d", "\xed\x5f", "\x00\x00", "\xc0\xed", + /* 0x71f5 */ "\x98\xbf", "\x9e\x49", "\x00\x00", "\xc2\x77", "\xef\xfb", + /* 0x71f9 */ "\x00\x00", "\xc2\x74", "\xc2\x75", "\xef\xfd", "\xc2\x76", +- /* 0x71ff */ "\xef\xfa", "\x00\x00", "\xef\xf9", "\xf2\x6c", "\xef\xfc", ++ /* 0x71ff */ "\xef\xfa", "\x8c\xa7", "\xef\xf9", "\xf2\x6c", "\xef\xfc", + /* 0x7203 */ "\x00\x00", "\xf2\x6d", "\xc3\x7a", "\xf2\x6b", "\x00\x00", + /* 0x7209 */ "\x9b\xca", "\xf2\x6a", "\x00\x00", "\xf2\x69", "\xc3\x7b", + /* 0x720e */ "\xfd\xfe", "\x92\xdc", "\xc4\x6c", "\x00\x00", "\x00\x00", + /* 0x7213 */ "\xf4\x6a", "\xf4\x6b", "\xfe\x41", "\x91\xcc", "\x91\xe2", + /* 0x7217 */ "\x00\x00", "\xf5\xdc", "\xf5\xdb", "\xc4\xea", "\x00\x00", + /* 0x721d */ "\xf5\xda", "\xf6\xec", "\xf6\xed", "\x00\x00", "\x00\x00", +- /* 0x7222 */ "\xf7\xe6", "\xf8\xb1", "\xfe\x44", "\x00\x00", "\xf8\xf6", ++ /* 0x7222 */ "\xf7\xe6", "\xf8\xb1", "\xfe\x44", "\x87\x5f", "\xf8\xf6", + /* 0x7227 */ "\xf9\xbc", "\xc6\x79", "\xf9\xc6", "\xa4\xf6", "\x8b\xd3", + /* 0x722c */ "\xaa\xa6", "\xaa\xa7", "\xfe\x47", "\x00\x00", "\xac\xb8", + /* 0x7230 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xc0\xef", +@@ -8368,7 +8468,7 @@ static const char from_ucs4[][2] = + /* 0x737b */ "\xc4\x6d", "\xf4\x6e", "\xf4\x6d", "\xf5\xdd", "\xf6\xef", + /* 0x7380 */ "\xc5\x7a", "\xf7\xe8", "\xf7\xe7", "\xf7\xe9", "\xa5\xc8", + /* 0x7385 */ "\xcf\xc6", "\xaf\x59", "\xb2\x76", "\xd6\x6a", "\xa5\xc9", +- /* 0x738a */ "\xc9\xa7", "\xa4\xfd", "\x00\x00", "\x00\x00", "\xca\x45", ++ /* 0x738a */ "\xc9\xa7", "\xa4\xfd", "\x8c\xa9", "\x00\x00", "\xca\x45", + /* 0x738f */ "\x98\xae", "\x00\x00", "\x00\x00", "\xcb\x6c", "\xcb\x6a", + /* 0x7394 */ "\xcb\x6b", "\xcb\x68", "\xa8\x68", "\xcb\x69", "\x92\xd6", + /* 0x7398 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\xe1", "\xcd\x6d", +@@ -8377,9 +8477,9 @@ static const char from_ucs4[][2] = + /* 0x73a8 */ "\xaa\xb2", "\xaa\xb1", "\xfe\x5b", "\xaa\xb4", "\xcd\x6c", + /* 0x73ad */ "\xcd\x68", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x73b2 */ "\xac\xc2", "\xac\xc5", "\xcf\xce", "\xcf\xcd", "\xcf\xcc", +- /* 0x73b7 */ "\xac\xbf", "\xcf\xd5", "\xcf\xcb", "\x00\x00", "\xac\xc1", ++ /* 0x73b7 */ "\xac\xbf", "\xcf\xd5", "\xcf\xcb", "\x8c\x53", "\xac\xc1", + /* 0x73bc */ "\xd2\xaf", "\x00\x00", "\xcf\xd2", "\xcf\xd0", "\xac\xc4", +- /* 0x73c0 */ "\x00\x00", "\xcf\xc8", "\xcf\xd3", "\x00\x00", "\xcf\xca", ++ /* 0x73c0 */ "\x00\x00", "\xcf\xc8", "\xcf\xd3", "\x87\xbf", "\xcf\xca", + /* 0x73c6 */ "\xcf\xd4", "\xcf\xd1", "\xcf\xc9", "\xfe\x5e", "\xac\xc0", + /* 0x73cb */ "\xcf\xd6", "\xcf\xc7", "\xac\xc3", "\xfb\xd7", "\xfe\x5a", + /* 0x73d0 */ "\x94\xc5", "\x00\x00", "\xd2\xb4", "\xd2\xab", "\xd2\xb6", +@@ -8392,7 +8492,7 @@ static const char from_ucs4[][2] = + /* 0x73f3 */ "\x97\x64", "\xd6\x78", "\xd6\x6d", "\xd6\x6b", "\xfe\x68", + /* 0x73f8 */ "\xd6\x6c", "\x96\x4e", "\xd6\x73", "\x97\x65", "\xd6\x74", + /* 0x73fd */ "\xd6\x70", "\xb2\x7b", "\xd6\x75", "\xd6\x72", "\xd6\x6f", +- /* 0x7401 */ "\x00\x00", "\xb2\x79", "\xd6\x6e", "\xb2\x77", "\xb2\x7a", ++ /* 0x7402 */ "\x8c\x5a", "\xb2\x79", "\xd6\x6e", "\xb2\x77", "\xb2\x7a", + /* 0x7407 */ "\xd6\x71", "\xd6\x79", "\xaf\x5b", "\xb2\x78", "\xd6\x77", + /* 0x740c */ "\xd6\x76", "\xb2\x7c", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x7411 */ "\x89\xa1", "\x95\xfa", "\x00\x00", "\x92\xd4", "\xfe\x69", +@@ -8406,12 +8506,12 @@ static const char from_ucs4[][2] = + /* 0x7439 */ "\xfe\x6c", "\xb5\x57", "\x00\x00", "\x94\x6b", "\x00\x00", + /* 0x743d */ "\x00\x00", "\xb7\xe9", "\xde\xb7", "\xb7\xe8", "\xde\xbb", + /* 0x7443 */ "\x92\xfc", "\xde\xb1", "\x95\xeb", "\xde\xbc", "\xfe\x73", +- /* 0x7448 */ "\x97\x6e", "\xfe\x5f", "\xde\xb2", "\xde\xb3", "\x00\x00", ++ /* 0x7448 */ "\x97\x6e", "\xfe\x5f", "\xde\xb2", "\xde\xb3", "\x87\xb8", + /* 0x744d */ "\xde\xbd", "\xde\xba", "\xde\xb8", "\xde\xb9", "\xde\xb5", + /* 0x7452 */ "\xde\xb4", "\xfd\xbd", "\xde\xbe", "\xb7\xe5", "\x92\xd5", + /* 0x7457 */ "\xde\xb6", "\x00\x00", "\xb7\xea", "\xb7\xe4", "\xb7\xeb", + /* 0x745c */ "\xb7\xec", "\xfe\xb9", "\xb7\xe7", "\xb7\xe6", "\xfe\x71", +- /* 0x7460 */ "\x00\x00", "\xe2\xce", "\xba\xbe", "\xba\xbd", "\xfb\xbb", ++ /* 0x7461 */ "\x87\x78", "\xe2\xce", "\xba\xbe", "\xba\xbd", "\xfb\xbb", + /* 0x7465 */ "\x00\x00", "\xe2\xd3", "\x94\x7a", "\xbc\xfc", "\xba\xbf", + /* 0x746b */ "\x95\xfb", "\xfe\x77", "\xba\xc1", "\xe2\xd4", "\xb7\xe3", + /* 0x7470 */ "\xba\xc0", "\xe2\xd0", "\xe2\xd2", "\xe2\xcf", "\xfe\x79", +@@ -8423,15 +8523,15 @@ static const char from_ucs4[][2] = + /* 0x748d */ "\x00\x00", "\x00\x00", "\xed\x69", "\x00\x00", "\xea\x66", + /* 0x7492 */ "\x00\x00", "\xea\x65", "\xea\x67", "\x00\x00", "\xed\x66", + /* 0x7498 */ "\xbf\x5a", "\x92\xd3", "\xea\x63", "\x94\xb8", "\xbf\x58", +- /* 0x749c */ "\x00\x00", "\xbf\x5c", "\xbf\x5b", "\xea\x64", "\xea\x68", ++ /* 0x749d */ "\x87\x79", "\xbf\x5c", "\xbf\x5b", "\xea\x64", "\xea\x68", + /* 0x74a1 */ "\x00\x00", "\xbf\x59", "\xfc\x71", "\xed\x6d", "\xc0\xf5", + /* 0x74a7 */ "\xc2\x7a", "\xc0\xf6", "\xc0\xf3", "\xed\x6a", "\xed\x68", + /* 0x74ab */ "\x00\x00", "\xed\x6b", "\x00\x00", "\xed\x6e", "\xc0\xf4", + /* 0x74b1 */ "\xed\x6c", "\xed\x67", "\x00\x00", "\x97\x5e", "\xf0\x42", +- /* 0x74b6 */ "\xf0\x45", "\xf2\x75", "\xf0\x40", "\x00\x00", "\xf4\x6f", ++ /* 0x74b6 */ "\xf0\x45", "\xf2\x75", "\xf0\x40", "\x8c\xad", "\xf4\x6f", + /* 0x74bb */ "\xf0\x46", "\x00\x00", "\xc3\xa2", "\xf0\x44", "\xc2\x7b", + /* 0x74c0 */ "\xf0\x41", "\xf0\x43", "\xf0\x47", "\xf2\x76", "\x00\x00", +- /* 0x74c5 */ "\xf2\x74", "\x00\x00", "\x00\x00", "\xfe\xa7", "\x00\x00", ++ /* 0x74c5 */ "\xf2\x74", "\x87\xc1", "\x00\x00", "\xfe\xa7", "\x00\x00", + /* 0x74ca */ "\xc3\xa3", "\xf2\x73", "\x94\x6a", "\x00\x00", "\x00\x00", + /* 0x74cf */ "\xc4\x6e", "\x93\xe3", "\x00\x00", "\x00\x00", "\x98\xcf", + /* 0x74d4 */ "\xc4\xed", "\xf6\xf1", "\xc4\xec", "\xf6\xf3", "\xf6\xf0", +@@ -8537,7 +8637,7 @@ static const char from_ucs4[][2] = + /* 0x76c8 */ "\xac\xd5", "\xd2\xcc", "\xaf\x71", "\x00\x00", "\xfe\xcb", + /* 0x76cd */ "\xaf\x72", "\xaf\x73", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x76d2 */ "\xb2\xb0", "\xd6\xa7", "\xb2\xaf", "\x00\x00", "\x9f\xc2", +- /* 0x76d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xda\xb9", "\xb2\xb1", ++ /* 0x76d6 */ "\x00\x00", "\x00\x00", "\x8c\x6b", "\xda\xb9", "\xb2\xb1", + /* 0x76dc */ "\xb5\x73", "\xde\xd7", "\xb7\xf8", "\xb7\xf9", "\x00\x00", + /* 0x76e1 */ "\xba\xc9", "\x00\x00", "\xba\xca", "\xbd\x4c", "\xbf\x64", + /* 0x76e6 */ "\xea\x75", "\xbf\x63", "\x00\x00", "\xed\x79", "\xc0\xfa", +@@ -8589,7 +8689,7 @@ static const char from_ucs4[][2] = + /* 0x77cc */ "\xf4\x74", "\xf4\x77", "\xf4\x75", "\xf4\x76", "\xf5\xe0", + /* 0x77d0 */ "\x00\x00", "\x00\x00", "\xc4\xef", "\xf7\xeb", "\xf8\xb4", + /* 0x77d5 */ "\x00\x00", "\xc5\xf7", "\xf8\xf8", "\xf8\xf9", "\xc6\x66", +- /* 0x77db */ "\xa5\xd9", "\xac\xe1", "\x00\x00", "\xda\xc3", "\x00\x00", ++ /* 0x77db */ "\xa5\xd9", "\xac\xe1", "\x8c\x6e", "\xda\xc3", "\x00\x00", + /* 0x77e0 */ "\xde\xe3", "\x00\x00", "\xa5\xda", "\xa8\x6f", "\x00\x00", + /* 0x77e5 */ "\xaa\xbe", "\xfa\xd8", "\xcf\xe8", "\xcf\xe9", "\xaf\x78", + /* 0x77e9 */ "\x00\x00", "\x00\x00", "\xda\xc4", "\xb5\x75", "\xb8\x47", +@@ -8642,7 +8742,7 @@ static const char from_ucs4[][2] = + /* 0x78d5 */ "\xbd\x57", "\x00\x00", "\xfe\xe7", "\x9f\xfb", "\x00\x00", + /* 0x78da */ "\xbf\x6a", "\xea\xa8", "\x00\x00", "\xea\xa2", "\xea\xa6", + /* 0x78df */ "\xea\xac", "\xea\xad", "\xea\xa9", "\xea\xaa", "\xea\xa7", +- /* 0x78e3 */ "\x00\x00", "\xea\xa4", "\x00\x00", "\xbf\x6c", "\xbf\x69", ++ /* 0x78e4 */ "\x8c\x59", "\xea\xa4", "\x00\x00", "\xbf\x6c", "\xbf\x69", + /* 0x78e9 */ "\xea\xa3", "\xea\xa5", "\x00\x00", "\xbf\x6b", "\xea\xab", + /* 0x78ee */ "\x93\xc9", "\xc1\x46", "\x94\xe8", "\xfb\x56", "\xed\xaa", + /* 0x78f3 */ "\xed\xa5", "\xc1\x45", "\x90\xc5", "\x00\x00", "\xc1\x43", +@@ -8688,8 +8788,8 @@ static const char from_ucs4[][2] = + /* 0x79bb */ "\xd6\xc3", "\x00\x00", "\xb8\x56", "\xa5\xdd", "\xa8\x72", + /* 0x79c0 */ "\xa8\x71", "\xa8\x70", "\x00\x00", "\x00\x00", "\x97\xa8", + /* 0x79c5 */ "\xcd\xa4", "\xfe\xfc", "\x00\x00", "\xaa\xc4", "\xaa\xc3", +- /* 0x79c9 */ "\x00\x00", "\xac\xee", "\xfd\xbf", "\xcf\xfa", "\xcf\xfd", +- /* 0x79cf */ "\xcf\xfb", "\x00\x00", "\xac\xec", "\xac\xed", "\x00\x00", ++ /* 0x79ca */ "\x8c\xde", "\xac\xee", "\xfd\xbf", "\xcf\xfa", "\xcf\xfd", ++ /* 0x79cf */ "\xcf\xfb", "\x87\xb3", "\xac\xec", "\xac\xed", "\x00\x00", + /* 0x79d4 */ "\xfe\xfe", "\xcf\xf9", "\xcf\xfc", "\x00\x00", "\xaf\xb5", + /* 0x79d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xd2\xf3", "\xd2\xf5", + /* 0x79de */ "\xd2\xf4", "\xaf\xb2", "\xd2\xef", "\x00\x00", "\x96\xd1", +@@ -8707,8 +8807,8 @@ static const char from_ucs4[][2] = + /* 0x7a1a */ "\xb8\x58", "\xdf\x40", "\xb8\x57", "\x00\x00", "\xb8\x5c", + /* 0x7a1f */ "\xb8\x5b", "\xb8\x59", "\x00\x00", "\xde\xfd", "\x00\x00", + /* 0x7a23 */ "\x00\x00", "\x00\x00", "\xe3\x49", "\x00\x00", "\xe3\x48", +- /* 0x7a28 */ "\x00\x00", "\x00\x00", "\xe3\x44", "\x00\x00", "\xa0\xb3", +- /* 0x7a2e */ "\xba\xd8", "\xe3\x47", "\xe3\x46", "\xba\xd9", "\x00\x00", ++ /* 0x7a28 */ "\x00\x00", "\x8c\x63", "\xe3\x44", "\x87\xbb", "\xa0\xb3", ++ /* 0x7a2e */ "\xba\xd8", "\xe3\x47", "\xe3\x46", "\xba\xd9", "\x87\xb4", + /* 0x7a32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xbd\x5e", + /* 0x7a37 */ "\x00\x00", "\xe6\xd2", "\x94\xcf", "\xbd\x5f", "\xbd\x5b", + /* 0x7a3d */ "\xbd\x5d", "\x9f\xfa", "\xbd\x5a", "\xbd\x5c", "\x00\x00", +@@ -8721,14 +8821,14 @@ static const char from_ucs4[][2] = + /* 0x7a60 */ "\xc2\xaa", "\xc2\xa8", "\xc2\xa9", "\x00\x00", "\x00\x00", + /* 0x7a65 */ "\x8e\x4c", "\x00\x00", "\xf2\xa6", "\xf2\xa7", "\xc3\xad", + /* 0x7a69 */ "\x00\x00", "\xc3\xac", "\xf4\xa3", "\xf4\xa4", "\xf4\xa2", +- /* 0x7a6e */ "\x00\x00", "\xf6\xf8", "\xf6\xf9", "\x00\x00", "\x00\x00", ++ /* 0x7a6e */ "\x00\x00", "\xf6\xf8", "\xf6\xf9", "\x87\xc9", "\x00\x00", + /* 0x7a74 */ "\xa5\xde", "\xca\x48", "\xa8\x73", "\x00\x00", "\xcd\xa5", + /* 0x7a79 */ "\xaa\xc6", "\xaa\xc5", "\xcd\xa6", "\x00\x00", "\x8e\x4d", + /* 0x7a7e */ "\xd0\x40", "\xac\xef", "\xcf\xfe", "\xac\xf0", "\x00\x00", + /* 0x7a83 */ "\x9a\x73", "\xaf\xb6", "\xd2\xf8", "\xd2\xf6", "\xd2\xfc", + /* 0x7a88 */ "\xaf\xb7", "\xd2\xf7", "\xd2\xfb", "\xd2\xf9", "\xd2\xfa", + /* 0x7a8c */ "\x00\x00", "\x00\x00", "\xd6\xc8", "\xd6\xca", "\x99\x47", +- /* 0x7a92 */ "\xb2\xbf", "\x00\x00", "\xd6\xc9", "\xb2\xc0", "\xb5\xa2", ++ /* 0x7a92 */ "\xb2\xbf", "\x8c\xb1", "\xd6\xc9", "\xb2\xc0", "\xb5\xa2", + /* 0x7a97 */ "\xb5\xa1", "\xb5\x7e", "\xda\xdb", "\x00\x00", "\x00\x00", + /* 0x7a9b */ "\x00\x00", "\x00\x00", "\xdf\x44", "\xb8\x5d", "\xb8\x5e", + /* 0x7aa0 */ "\x00\x00", "\xdf\x43", "\xdf\x42", "\x00\x00", "\x00\x00", +@@ -8749,7 +8849,7 @@ static const char from_ucs4[][2] = + /* 0x7aeb */ "\x00\x00", "\xba\xdc", "\xe3\x4d", "\xba\xdd", "\x00\x00", + /* 0x7af0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x7af6 */ "\xc4\x76", "\xf4\xa5", "\x00\x00", "\xa6\xcb", "\xaa\xc7", +- /* 0x7afb */ "\xcd\xa7", "\x00\x00", "\xac\xf2", "\x94\xeb", "\xac\xf1", ++ /* 0x7afb */ "\xcd\xa7", "\x87\xa3", "\xac\xf2", "\x94\xeb", "\xac\xf1", + /* 0x7b00 */ "\xd0\x42", "\xd0\x43", "\x00\x00", "\x00\x00", "\xd3\x40", + /* 0x7b05 */ "\xd3\x42", "\xaf\xb9", "\x00\x00", "\xd3\x44", "\xd3\x47", + /* 0x7b0a */ "\xd3\x45", "\x8e\x5c", "\x95\x53", "\x00\x00", "\xd3\x46", +@@ -8784,12 +8884,12 @@ static const char from_ucs4[][2] = + /* 0x7b9b */ "\xe3\x56", "\xe3\x4f", "\xba\xe3", "\x00\x00", "\x00\x00", + /* 0x7ba0 */ "\xbd\x69", "\xba\xde", "\x8e\x61", "\x9f\x59", "\xe3\x5c", + /* 0x7ba4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x7ba9 */ "\x00\x00", "\x00\x00", "\xe6\xd9", "\xbd\x62", "\x00\x00", ++ /* 0x7ba9 */ "\x00\x00", "\x00\x00", "\xe6\xd9", "\xbd\x62", "\x87\xd0", + /* 0x7baf */ "\xe6\xdb", "\x00\x00", "\xbd\x63", "\x8b\xb3", "\x00\x00", + /* 0x7bb4 */ "\xbd\x65", "\xe6\xde", "\x00\x00", "\xe6\xd6", "\xba\xe6", + /* 0x7bb9 */ "\xe6\xdc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x7bbe */ "\xe6\xd8", "\x00\x00", "\xb8\x60", "\xbd\x68", "\x00\x00", +- /* 0x7bc2 */ "\x00\x00", "\xbd\x64", "\x00\x00", "\xbd\x66", "\xbd\x67", ++ /* 0x7bc2 */ "\x00\x00", "\xbd\x64", "\x87\xb9", "\xbd\x66", "\xbd\x67", + /* 0x7bc7 */ "\x00\x00", "\xbf\x76", "\xe6\xdd", "\xe6\xd7", "\xbd\x6a", + /* 0x7bcc */ "\x00\x00", "\xe6\xda", "\x9f\x5d", "\x8e\x66", "\x00\x00", + /* 0x7bd1 */ "\x00\x00", "\x00\x00", "\xea\xc0", "\xea\xbb", "\x00\x00", +@@ -8797,7 +8897,7 @@ static const char from_ucs4[][2] = + /* 0x7bdc */ "\xea\xc3", "\xea\xba", "\xea\xb7", "\xea\xc6", "\xc1\x51", + /* 0x7be1 */ "\xbf\x79", "\xea\xc2", "\xea\xb8", "\xbf\x77", "\xea\xbc", + /* 0x7be6 */ "\xbf\x7b", "\xea\xb9", "\xea\xbe", "\xbf\x7a", "\xea\xc1", +- /* 0x7beb */ "\xea\xc4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x7beb */ "\xea\xc4", "\x8c\xb2", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x7bf0 */ "\xed\xcb", "\xed\xcc", "\xed\xbc", "\xed\xc3", "\xed\xc1", + /* 0x7bf4 */ "\x00\x00", "\x00\x00", "\xc1\x4f", "\xed\xc8", "\xea\xbf", + /* 0x7bfa */ "\x8e\x6e", "\xed\xbf", "\x9f\x64", "\xed\xc9", "\xc1\x4e", +@@ -8840,7 +8940,7 @@ static const char from_ucs4[][2] = + /* 0x7cb3 */ "\xb8\x65", "\xdf\x55", "\xb8\x66", "\x00\x00", "\x00\x00", + /* 0x7cb8 */ "\x99\x5a", "\xba\xe9", "\xe3\x61", "\xe3\x5e", "\xe3\x60", + /* 0x7cbd */ "\xba\xea", "\xba\xeb", "\xe3\x5f", "\x00\x00", "\x00\x00", +- /* 0x7cc2 */ "\xa0\xb0", "\x00\x00", "\x00\x00", "\xe6\xdf", "\x00\x00", ++ /* 0x7cc2 */ "\xa0\xb0", "\x8c\xb3", "\x00\x00", "\xe6\xdf", "\x00\x00", + /* 0x7cc7 */ "\x8e\x79", "\xe6\xe0", "\x8e\x78", "\xbd\x6b", "\xe6\xe2", + /* 0x7ccc */ "\xe6\xe1", "\x94\xf3", "\xa2\x61", "\x00\x00", "\xea\xca", + /* 0x7cd1 */ "\xea\xcb", "\xea\xc7", "\x98\xaf", "\xea\xc8", "\xbf\x7c", +@@ -8880,9 +8980,9 @@ static const char from_ucs4[][2] = + /* 0x7d7b */ "\xdf\x5f", "\xdf\x61", "\xdf\x65", "\x00\x00", "\xdf\x5b", + /* 0x7d80 */ "\xdf\x59", "\xb8\x6a", "\x00\x00", "\xdf\x60", "\xdf\x64", + /* 0x7d85 */ "\xdf\x5c", "\xdf\x58", "\x00\x00", "\xdf\x57", "\x8e\xa7", +- /* 0x7d89 */ "\x00\x00", "\x00\x00", "\xdf\x62", "\xdf\x5a", "\xdf\x5e", ++ /* 0x7d89 */ "\x00\x00", "\x8c\x76", "\xdf\x62", "\xdf\x5a", "\xdf\x5e", + /* 0x7d8f */ "\xb8\x6b", "\x00\x00", "\xb8\x69", "\xdf\x66", "\xb8\x67", +- /* 0x7d94 */ "\xdf\x63", "\x00\x00", "\xe3\x72", "\x95\x42", "\x00\x00", ++ /* 0x7d94 */ "\xdf\x63", "\x87\x67", "\xe3\x72", "\x95\x42", "\x00\x00", + /* 0x7d98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xba\xee", "\xe3\x6a", + /* 0x7d9e */ "\xbd\x78", "\xe3\x74", "\xba\xf1", "\xe3\x78", "\xba\xf7", + /* 0x7da3 */ "\xe3\x65", "\x98\x7d", "\x00\x00", "\xe3\x75", "\xe3\x62", +@@ -8921,11 +9021,11 @@ static const char from_ucs4[][2] = + /* 0x7e48 */ "\xc1\x66", "\xed\xd7", "\x00\x00", "\x00\x00", "\xed\xdb", + /* 0x7e4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\xf0\x6e", "\xf0\x74", + /* 0x7e52 */ "\xc2\xb9", "\xf0\x77", "\xc2\xb4", "\xc2\xb5", "\xf0\x6f", +- /* 0x7e57 */ "\xf0\x76", "\xf0\x71", "\xc2\xba", "\xc2\xb7", "\x00\x00", ++ /* 0x7e57 */ "\xf0\x76", "\xf0\x71", "\xc2\xba", "\xc2\xb7", "\x8c\xdc", + /* 0x7e5c */ "\xf0\x6d", "\x00\x00", "\xc2\xb6", "\xf0\x73", "\xf0\x75", + /* 0x7e61 */ "\xc2\xb8", "\xf0\x72", "\xf0\x70", "\x00\x00", "\x98\x76", + /* 0x7e65 */ "\x00\x00", "\x8e\xa1", "\xf2\xb8", "\xc3\xb7", "\xc3\xb8", +- /* 0x7e6b */ "\xc3\xb4", "\x00\x00", "\xc3\xb5", "\x8e\xb7", "\xf2\xb4", ++ /* 0x7e6b */ "\xc3\xb4", "\x8c\xb4", "\xc3\xb5", "\x8e\xb7", "\xf2\xb4", + /* 0x7e70 */ "\xf2\xb2", "\x00\x00", "\xf2\xb6", "\xc3\xba", "\xf2\xb7", + /* 0x7e75 */ "\xf2\xb0", "\xf2\xaf", "\xf2\xb3", "\xf2\xb1", "\xc3\xb6", + /* 0x7e7a */ "\xf2\xb5", "\xf4\xac", "\xc4\x7e", "\xc4\x7d", "\xf4\xad", +@@ -9078,7 +9178,7 @@ static const char from_ucs4[][2] = + /* 0x8159 */ "\x99\x7d", "\x99\x7e", "\xdf\x77", "\xdf\x75", "\x00\x00", + /* 0x815e */ "\xdf\x7b", "\x00\x00", "\xdf\x73", "\xdf\xa2", "\xdf\x78", + /* 0x8162 */ "\x00\x00", "\xdf\x72", "\xb8\x7b", "\xb8\xa3", "\xdf\x7d", +- /* 0x8167 */ "\x00\x00", "\xdf\x76", "\x00\x00", "\xb8\x7e", "\x00\x00", ++ /* 0x8167 */ "\x00\x00", "\xdf\x76", "\x00\x00", "\xb8\x7e", "\x8c\xfb", + /* 0x816d */ "\x8b\x5b", "\xb8\x7c", "\xdf\x7e", "\xb8\x79", "\xb8\x78", + /* 0x8172 */ "\xdf\x79", "\xb8\x7d", "\xb5\xcd", "\x00\x00", "\xdf\x7c", + /* 0x8177 */ "\xdf\x74", "\xb8\x7a", "\xb8\xa1", "\xb8\xa2", "\x00\x00", +@@ -9146,7 +9246,7 @@ static const char from_ucs4[][2] = + /* 0x82ad */ "\xaa\xdd", "\xcd\xba", "\xaa\xe4", "\xaa\xe7", "\xaa\xe1", + /* 0x82b1 */ "\x00\x00", "\xaa\xda", "\xcd\xbe", "\xcd\xb8", "\xcd\xc5", + /* 0x82b7 */ "\xaa\xe9", "\xaa\xe5", "\xaa\xe0", "\xcd\xbd", "\xaf\xec", +- /* 0x82bc */ "\xcd\xbb", "\xaa\xde", "\xaa\xe8", "\x00\x00", "\xcd\xb3", ++ /* 0x82bc */ "\xcd\xbb", "\xaa\xde", "\xaa\xe8", "\x8c\xd0", "\xcd\xb3", + /* 0x82c0 */ "\x00\x00", "\xcd\xc2", "\xcd\xc4", "\x8b\x52", "\x00\x00", + /* 0x82c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x99\xb0", + /* 0x82ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x89\x77", +@@ -9158,7 +9258,7 @@ static const char from_ucs4[][2] = + /* 0x82e8 */ "\x00\x00", "\xd0\x7e", "\xd0\x73", "\xd0\x76", "\xd0\xa5", + /* 0x82ee */ "\xfa\x4d", "\xad\x66", "\xd0\x7d", "\xad\x5e", "\xd0\x78", + /* 0x82f3 */ "\xd0\xa4", "\xd0\x75", "\xd0\x79", "\xd0\x7c", "\x9d\xe4", +- /* 0x82f7 */ "\x00\x00", "\xd0\x6d", "\xd0\xa3", "\xd0\x7b", "\xfb\xe9", ++ /* 0x82f8 */ "\x8c\xb5", "\xd0\x6d", "\xd0\xa3", "\xd0\x7b", "\xfb\xe9", + /* 0x82fd */ "\x9b\x54", "\xd0\x6c", "\x99\xb2", "\xd0\x70", "\xad\x5f", + /* 0x8302 */ "\xad\x5a", "\xad\x53", "\xad\x58", "\xad\x54", "\xad\x67", + /* 0x8307 */ "\xd0\x6e", "\xd3\xa5", "\xad\x5b", "\x00\x00", "\x9e\x68", +@@ -9237,7 +9337,7 @@ static const char from_ucs4[][2] = + /* 0x8474 */ "\xdf\xba", "\xb8\xaa", "\xdf\xac", "\xb8\xa7", "\xdf\xc4", + /* 0x8479 */ "\xdf\xad", "\xdf\xc2", "\x00\x00", "\x00\x00", "\xdf\xb7", + /* 0x847e */ "\xdf\xdb", "\x91\xc7", "\x95\x5f", "\x00\x00", "\xb8\xa6", +- /* 0x8482 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xdf\xb3", "\x00\x00", ++ /* 0x8482 */ "\x00\x00", "\x87\xab", "\x00\x00", "\xdf\xb3", "\x00\x00", + /* 0x8488 */ "\x99\xbb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x848d */ "\xdf\xaf", "\xdf\xd5", "\xdf\xae", "\xbb\x60", "\xe3\xd3", + /* 0x8492 */ "\x8e\x6d", "\x8f\x71", "\xe3\xc2", "\x00\x00", "\x94\xcb", +@@ -9262,7 +9362,7 @@ static const char from_ucs4[][2] = + /* 0x84f1 */ "\xdf\xa9", "\xe7\x5f", "\xe7\x63", "\xe7\x5d", "\x00\x00", + /* 0x84f6 */ "\xe7\x70", "\xe7\x61", "\x99\xbf", "\xe7\x77", "\xe7\x5a", + /* 0x84fb */ "\xe7\x58", "\xe7\x64", "\xe7\x6e", "\xe7\x69", "\xbd\xb6", +- /* 0x8500 */ "\xe7\x4f", "\x00\x00", "\xe7\x6d", "\x92\x42", "\x00\x00", ++ /* 0x8500 */ "\xe7\x4f", "\x00\x00", "\xe7\x6d", "\x92\x42", "\x87\xd7", + /* 0x8505 */ "\xfb\xa5", "\xbd\xb7", "\xdf\xbd", "\xe7\x5b", "\xe7\x52", + /* 0x850a */ "\xe7\x55", "\xe7\x7b", "\xe7\x5c", "\xe7\x53", "\xe7\x51", + /* 0x850f */ "\xe7\x4e", "\x99\xc0", "\xbd\xb0", "\xe7\x65", "\xbd\xaf", +@@ -9281,7 +9381,7 @@ static const char from_ucs4[][2] = + /* 0x854f */ "\x00\x00", "\xeb\x46", "\x99\xc2", "\xea\xfc", "\xeb\x55", + /* 0x8555 */ "\xeb\x4f", "\xea\xf8", "\xee\x46", "\xea\xfe", "\xbf\xb7", + /* 0x855a */ "\x8f\x5c", "\xeb\x4a", "\x00\x00", "\xeb\x54", "\xbf\xbf", +- /* 0x855e */ "\x00\x00", "\xeb\x51", "\xea\xfd", "\xeb\x44", "\xeb\x48", ++ /* 0x855f */ "\x8c\xbd", "\xeb\x51", "\xea\xfd", "\xeb\x44", "\xeb\x48", + /* 0x8564 */ "\xeb\x42", "\xeb\x56", "\xeb\x53", "\xeb\x50", "\xbf\xb9", + /* 0x8569 */ "\xbf\xba", "\xbf\xbe", "\xea\xfa", "\xeb\x57", "\xbf\xbd", + /* 0x856e */ "\xeb\x4d", "\x99\xc4", "\x99\xc5", "\xeb\x4b", "\x00\x00", +@@ -9291,8 +9391,8 @@ static const char from_ucs4[][2] = + /* 0x8582 */ "\xee\x4f", "\xed\xf3", "\xc1\xa1", "\xee\x51", "\xee\x49", + /* 0x8587 */ "\xc1\xa8", "\xee\x50", "\xee\x42", "\xc1\xaa", "\xed\xf9", + /* 0x858c */ "\xeb\x52", "\xee\x4a", "\xee\x47", "\xed\xf5", "\xee\x55", +- /* 0x8591 */ "\xc1\xa4", "\x00\x00", "\x00\x00", "\xc1\xa5", "\xed\xf7", +- /* 0x8596 */ "\xee\x48", "\x00\x00", "\xee\x54", "\xee\x4b", "\xed\xfd", ++ /* 0x8591 */ "\xc1\xa4", "\x00\x00", "\x87\x76", "\xc1\xa5", "\xed\xf7", ++ /* 0x8596 */ "\xee\x48", "\x8c\xb6", "\xee\x54", "\xee\x4b", "\xed\xfd", + /* 0x859b */ "\xc1\xa7", "\xc1\xa3", "\xee\x4c", "\xed\xfe", "\xee\x56", + /* 0x85a0 */ "\xed\xf8", "\xee\x43", "\xee\x4e", "\xed\xfa", "\xed\xfc", + /* 0x85a4 */ "\x00\x00", "\xc2\xcb", "\xed\xf6", "\xc1\xa9", "\xc2\xc4", +@@ -9304,7 +9404,7 @@ static const char from_ucs4[][2] = + /* 0x85c3 */ "\xf0\xa7", "\xf0\xad", "\xf0\xb2", "\xf0\xa5", "\xf0\xac", + /* 0x85c8 */ "\xf0\xb1", "\xc2\xc7", "\x00\x00", "\xf0\xaf", "\x00\x00", + /* 0x85cd */ "\xc2\xc5", "\xf0\xb0", "\xc2\xc3", "\xc2\xc6", "\xf2\xd5", +- /* 0x85d2 */ "\xf0\xb5", "\x00\x00", "\x00\x00", "\xc3\xc2", "\x00\x00", ++ /* 0x85d2 */ "\xf0\xb5", "\x00\x00", "\x00\x00", "\xc3\xc2", "\x8c\xce", + /* 0x85d7 */ "\xf2\xcd", "\xf2\xd1", "\xf2\xc9", "\xf2\xcc", "\x00\x00", + /* 0x85dc */ "\xf2\xd4", "\xc3\xc0", "\xf2\xd9", "\xf2\xd2", "\x99\xc6", + /* 0x85e1 */ "\xf2\xca", "\xf2\xda", "\xf2\xd3", "\xc3\xc3", "\xc3\xc4", +@@ -9316,8 +9416,8 @@ static const char from_ucs4[][2] = + /* 0x85ff */ "\xf4\xb9", "\xf4\xbd", "\xf4\xba", "\x8f\xa5", "\x00\x00", + /* 0x8604 */ "\xf4\xbf", "\xf4\xc1", "\xc4\xaa", "\xc4\xac", "\x00\x00", + /* 0x8609 */ "\xf4\xc0", "\xc4\xad", "\xc4\xab", "\xf4\xc2", "\xfa\xbb", +- /* 0x860d */ "\x00\x00", "\x00\x00", "\x95\x70", "\xc4\xa8", "\x00\x00", +- /* 0x8612 */ "\x00\x00", "\x93\x68", "\x00\x00", "\x8f\x7e", "\xc4\xf4", ++ /* 0x860d */ "\x00\x00", "\x8c\x61", "\x95\x70", "\xc4\xa8", "\x00\x00", ++ /* 0x8613 */ "\x87\xaf", "\x93\x68", "\x00\x00", "\x8f\x7e", "\xc4\xf4", + /* 0x8618 */ "\xf5\xf1", "\xf5\xf7", "\xc4\xf6", "\xf4\xbc", "\xf5\xf6", + /* 0x861c */ "\x00\x00", "\xf5\xfd", "\xf5\xf4", "\xf5\xfb", "\xf5\xfa", + /* 0x8622 */ "\xf4\xb8", "\xf5\xf5", "\xf0\xb6", "\xf5\xfe", "\xf5\xf3", +@@ -9444,10 +9544,10 @@ static const char from_ucs4[][2] = + /* 0x887f */ "\xd3\xd7", "\xd3\xd5", "\xb0\x4b", "\xb0\x4c", "\xd3\xd9", + /* 0x8884 */ "\xfe\xec", "\x00\x00", "\x00\x00", "\x95\xa3", "\xb3\x50", + /* 0x8889 */ "\xd7\xb2", "\x00\x00", "\xb3\x55", "\xd7\xc2", "\xb3\x54", +- /* 0x888e */ "\xd7\xc4", "\x00\x00", "\x00\x00", "\xd7\xb8", "\xb3\x52", ++ /* 0x888e */ "\xd7\xc4", "\x8c\x45", "\x8c\xb8", "\xd7\xb8", "\xb3\x52", + /* 0x8893 */ "\xd7\xc3", "\x00\x00", "\xd7\xb3", "\xb3\x53", "\xd7\xbf", + /* 0x8898 */ "\xd7\xbb", "\xd7\xbd", "\xd7\xb7", "\xd7\xbe", "\x8f\xc1", +- /* 0x889c */ "\x00\x00", "\xb3\x4f", "\xd7\xba", "\xa0\x52", "\xd7\xb9", ++ /* 0x889d */ "\x87\xb7", "\xb3\x4f", "\xd7\xba", "\xa0\x52", "\xd7\xb9", + /* 0x88a2 */ "\xd7\xb5", "\x00\x00", "\xd7\xc0", "\x00\x00", "\x00\x00", + /* 0x88a7 */ "\xd7\xbc", "\xd7\xb4", "\x00\x00", "\xd7\xb6", "\xb3\x51", + /* 0x88ac */ "\xd7\xc1", "\x00\x00", "\x99\xd0", "\x00\x00", "\x00\x00", +@@ -9558,7 +9658,7 @@ static const char from_ucs4[][2] = + /* 0x8ab9 */ "\xbd\xda", "\xe7\xe2", "\xe7\xdb", "\xbd\xcb", "\xe7\xe3", + /* 0x8abe */ "\xe7\xdd", "\xbd\xd5", "\xe7\xde", "\x00\x00", "\xbd\xd4", + /* 0x8ac3 */ "\xe7\xe1", "\xbd\xce", "\xe7\xdf", "\xe7\xd5", "\xbd\xcd", +- /* 0x8ac8 */ "\xeb\xaa", "\xbd\xd3", "\x00\x00", "\xbd\xd0", "\x00\x00", ++ /* 0x8ac8 */ "\xeb\xaa", "\xbd\xd3", "\x00\x00", "\xbd\xd0", "\x8c\xf7", + /* 0x8acd */ "\xbd\xd8", "\x00\x00", "\xe7\xd4", "\x00\x00", "\xe7\xd8", + /* 0x8ad2 */ "\xbd\xcc", "\xe7\xd7", "\xe7\xd9", "\xe7\xda", "\xbd\xd7", + /* 0x8ad7 */ "\xe7\xdc", "\xe7\xe0", "\xe7\xe4", "\x92\x7c", "\xbd\xdb", +@@ -9567,7 +9667,7 @@ static const char from_ucs4[][2] = + /* 0x8ae6 */ "\xbf\xcd", "\xbf\xd3", "\xeb\xad", "\x00\x00", "\x9c\x45", + /* 0x8aeb */ "\xbf\xcf", "\x00\x00", "\xbf\xd9", "\xbf\xd4", "\xeb\xaf", + /* 0x8af0 */ "\xeb\xa9", "\xbf\xd0", "\xeb\xa2", "\xbf\xda", "\xeb\xa3", +- /* 0x8af5 */ "\xeb\xa4", "\xbf\xdb", "\xbf\xd8", "\xbd\xd1", "\x00\x00", ++ /* 0x8af5 */ "\xeb\xa4", "\xbf\xdb", "\xbf\xd8", "\xbd\xd1", "\x8c\xe8", + /* 0x8afa */ "\xbf\xce", "\xeb\xb0", "\xbf\xdc", "\x00\x00", "\xbf\xd5", + /* 0x8aff */ "\xeb\xae", "\xbf\xd1", "\xbf\xd6", "\xbf\xd7", "\x00\x00", + /* 0x8b04 */ "\xc1\xc3", "\xee\xa4", "\xee\xad", "\xee\xaa", "\xee\xac", +@@ -9595,9 +9695,9 @@ static const char from_ucs4[][2] = + /* 0x8b71 */ "\x00\x00", "\x00\x00", "\xc4\xfe", "\x00\x00", "\x00\x00", + /* 0x8b77 */ "\xc5\x40", "\xf6\x4e", "\xf6\x4d", "\xf6\x50", "\xf6\x51", + /* 0x8b7b */ "\x00\x00", "\xc5\x41", "\xf7\x56", "\xf7\x5b", "\xc5\xaa", +- /* 0x8b81 */ "\x9a\xf6", "\xf7\x58", "\x00\x00", "\xf7\x57", "\xf7\x5a", ++ /* 0x8b81 */ "\x9a\xf6", "\xf7\x58", "\x8c\xae", "\xf7\x57", "\xf7\x5a", + /* 0x8b86 */ "\xf7\x59", "\x00\x00", "\xf8\x43", "\x00\x00", "\xc5\xdc", +- /* 0x8b8b */ "\xf8\x42", "\xf8\x40", "\x00\x00", "\xf8\x41", "\x00\x00", ++ /* 0x8b8b */ "\xf8\x42", "\xf8\x40", "\x00\x00", "\xf8\x41", "\x87\xcb", + /* 0x8b90 */ "\x8f\xe7", "\x00\x00", "\xc5\xfe", "\xc5\xfd", "\xf8\xc1", + /* 0x8b95 */ "\xf8\xc2", "\xc6\x40", "\x00\x00", "\xf9\x4d", "\xf9\x4e", + /* 0x8b9a */ "\xc6\x67", "\x8f\xe8", "\xc6\x6d", "\x00\x00", "\xf9\xa9", +@@ -9759,7 +9859,7 @@ static const char from_ucs4[][2] = + /* 0x8ea6 */ "\xf9\x70", "\x95\xc9", "\xf9\xbe", "\xf9\xab", "\xc6\x6e", + /* 0x8eab */ "\xa8\xad", "\xb0\x60", "\x90\x48", "\x00\x00", "\x00\x00", + /* 0x8eb0 */ "\x99\xe8", "\x00\x00", "\xb8\xfa", "\x00\x00", "\x00\x00", +- /* 0x8eb4 */ "\x00\x00", "\x90\x49", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x8eb4 */ "\x00\x00", "\x90\x49", "\x00\x00", "\x00\x00", "\x8c\xba", + /* 0x8eba */ "\xbd\xf6", "\x00\x00", "\x90\xb1", "\xeb\xc8", "\x00\x00", + /* 0x8ebe */ "\x00\x00", "\xc2\xdf", "\x00\x00", "\xf3\x55", "\x90\x4a", + /* 0x8ec3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -9807,7 +9907,7 @@ static const char from_ucs4[][2] = + /* 0x8f95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x8f9b */ "\xa8\xaf", "\xb6\x64", "\x00\x00", "\x00\x00", "\xb9\x40", + /* 0x8fa0 */ "\x9b\x5a", "\x00\x00", "\x00\x00", "\xbb\xb6", "\x00\x00", +- /* 0x8fa5 */ "\x90\x50", "\xbf\xec", "\x00\x00", "\xbf\xeb", "\x00\x00", ++ /* 0x8fa5 */ "\x90\x50", "\xbf\xec", "\x8c\x4f", "\xbf\xeb", "\x00\x00", + /* 0x8fa9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xc3\xe3", "\xc4\x7c", + /* 0x8faf */ "\xc5\x47", "\xa8\xb0", "\xb0\x64", "\xb9\x41", "\x90\x54", + /* 0x8fb4 */ "\xf3\x5b", "\xc6\xd6", "\x9a\xa8", "\x99\xef", "\xfe\xeb", +@@ -9815,7 +9915,7 @@ static const char from_ucs4[][2] = + /* 0x8fbe */ "\x9d\x7d", "\xcb\xa6", "\x00\x00", "\x99\xf0", "\xa8\xb1", + /* 0x8fc2 */ "\x00\x00", "\xa8\xb4", "\xa8\xb3", "\xa8\xb2", "\x00\x00", + /* 0x8fc7 */ "\x00\x00", "\xcb\xa5", "\x99\xf1", "\xcd\xcd", "\x99\xf2", +- /* 0x8fcd */ "\xcd\xcf", "\xaa\xef", "\x00\x00", "\x9d\x60", "\xaa\xf1", ++ /* 0x8fcd */ "\xcd\xcf", "\xaa\xef", "\x8c\xbc", "\x9d\x60", "\xaa\xf1", + /* 0x8fd2 */ "\xcd\xcc", "\xcd\xce", "\xaa\xf0", "\xcd\xd1", "\xcd\xd0", + /* 0x8fd7 */ "\xcd\xd2", "\x00\x00", "\x00\x00", "\xa0\xa3", "\x00\x00", + /* 0x8fdb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xd0\xb6", +@@ -9839,7 +9939,7 @@ static const char from_ucs4[][2] = + /* 0x9036 */ "\xb6\x6a", "\x90\x62", "\xb6\x68", "\x00\x00", "\x00\x00", + /* 0x903a */ "\x00\x00", "\xb9\x47", "\xe0\xa3", "\xb9\x4f", "\xe0\x7e", + /* 0x903f */ "\x00\x00", "\xb9\x50", "\xb9\x45", "\x00\x00", "\xe0\xa1", +- /* 0x9044 */ "\x00\x00", "\x00\x00", "\xb9\x4a", "\x00\x00", "\xe0\xa2", ++ /* 0x9044 */ "\x00\x00", "\x87\xbd", "\xb9\x4a", "\x00\x00", "\xe0\xa2", + /* 0x904a */ "\xb9\x43", "\xb9\x42", "\x9f\x55", "\xb9\x4d", "\xb9\x4c", + /* 0x904f */ "\xb9\x4b", "\xb9\x49", "\xb9\x4e", "\xe0\x7d", "\xb9\x44", + /* 0x9054 */ "\xb9\x46", "\xb9\x48", "\x9b\xf9", "\x00\x00", "\xbb\xb8", +@@ -9925,16 +10025,16 @@ static const char from_ucs4[][2] = + /* 0x91e4 */ "\xd7\xfc", "\x96\x5b", "\xb3\xa7", "\xb3\xa9", "\xd8\x42", + /* 0x91e9 */ "\xb3\xab", "\xd7\xfe", "\xd8\x40", "\xd7\xf7", "\xb3\xaa", + /* 0x91ee */ "\xd8\x43", "\x00\x00", "\x00\x00", "\xd7\xf9", "\x00\x00", +- /* 0x91f3 */ "\xd7\xfa", "\xd7\xf8", "\xb3\xa6", "\x00\x00", "\xd8\x41", ++ /* 0x91f3 */ "\xd7\xfa", "\xd7\xf8", "\xb3\xa6", "\x8c\x50", "\xd8\x41", + /* 0x91f8 */ "\xd7\xfb", "\xd7\xfd", "\x94\xa6", "\x00\x00", "\x00\x00", + /* 0x91fd */ "\xdc\x6d", "\x8f\xd5", "\xdc\x6c", "\xdc\x6a", "\xdc\x62", + /* 0x9202 */ "\xdc\x71", "\xdc\x65", "\xdc\x6f", "\xdc\x76", "\xdc\x6e", + /* 0x9207 */ "\xb6\x79", "\x9e\x73", "\xb6\x75", "\xdc\x63", "\x00\x00", + /* 0x920c */ "\xdc\x69", "\xb6\x77", "\x90\x75", "\xdc\x68", "\xb6\x78", + /* 0x9211 */ "\xb6\x7a", "\xdc\x6b", "\x99\xf7", "\xb6\x72", "\xb6\x73", +- /* 0x9216 */ "\xdc\x77", "\xdc\x75", "\x00\x00", "\xdc\x74", "\xdc\x66", ++ /* 0x9216 */ "\xdc\x77", "\xdc\x75", "\x87\xb2", "\xdc\x74", "\xdc\x66", + /* 0x921a */ "\x00\x00", "\xdc\x72", "\x00\x00", "\xb6\x76", "\x00\x00", +- /* 0x921f */ "\x00\x00", "\x00\x00", "\x00\x00", "\xb6\x74", "\xdc\x73", ++ /* 0x921f */ "\x00\x00", "\x8c\xbf", "\x00\x00", "\xb6\x74", "\xdc\x73", + /* 0x9225 */ "\xdc\x64", "\xdc\x67", "\xdc\x70", "\x99\xf9", "\x00\x00", + /* 0x922a */ "\x96\x63", "\x95\xb9", "\x00\x00", "\xe4\xba", "\xe0\xb7", + /* 0x922e */ "\x00\x00", "\xe0\xb0", "\xe0\xc3", "\xe0\xcc", "\xe0\xb3", +@@ -10027,7 +10127,7 @@ static const char from_ucs4[][2] = + /* 0x93e2 */ "\xc3\xf0", "\xf3\x6f", "\xc3\xf3", "\x00\x00", "\xf3\x6b", + /* 0x93e7 */ "\xf3\x75", "\xc3\xf5", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x93ec */ "\xf3\x67", "\x00\x00", "\xf3\x6e", "\x00\x00", "\xfd\xcb", +- /* 0x93f1 */ "\xfe\x7a", "\x00\x00", "\x91\xdb", "\x00\x00", "\xf4\xf3", ++ /* 0x93f1 */ "\xfe\x7a", "\x00\x00", "\x91\xdb", "\x8c\x6a", "\xf4\xf3", + /* 0x93f6 */ "\xf5\x42", "\xf4\xf5", "\xf4\xfc", "\xf3\x66", "\xf4\xfa", + /* 0x93fb */ "\xf4\xe9", "\xf5\x40", "\xc4\xc3", "\xf4\xed", "\xf4\xfe", + /* 0x9400 */ "\xf4\xf4", "\x97\xaf", "\x00\x00", "\xc4\xc2", "\x95\xdd", +@@ -10039,7 +10139,7 @@ static const char from_ucs4[][2] = + /* 0x941d */ "\x00\x00", "\x00\x00", "\xf4\xea", "\x00\x00", "\x00\x00", + /* 0x9422 */ "\x00\x00", "\x91\xbc", "\x90\xe2", "\x90\xb4", "\x95\xe1", + /* 0x9428 */ "\xf4\xf0", "\xf6\x61", "\xf6\x66", "\xc5\x4f", "\xf6\x68", +- /* 0x942d */ "\x9a\x4e", "\xc5\x49", "\x00\x00", "\xf6\x64", "\xf6\x6a", ++ /* 0x942d */ "\x9a\x4e", "\xc5\x49", "\x87\xad", "\xf6\x64", "\xf6\x6a", + /* 0x9432 */ "\xc5\x4e", "\xc5\x4a", "\x00\x00", "\xc5\x4b", "\xf6\x60", + /* 0x9437 */ "\xf6\x67", "\xc5\x4d", "\xf6\x65", "\xc5\x4c", "\xf6\x5f", + /* 0x943c */ "\xf6\x63", "\xf6\x62", "\x9a\x4f", "\xf6\x5e", "\xf6\x69", +@@ -10194,13 +10294,13 @@ static const char from_ucs4[][2] = + /* 0x9725 */ "\xf1\x78", "\xf3\x7e", "\xc3\xfa", "\xf3\x7d", "\xf3\x7a", + /* 0x972a */ "\xc3\xf9", "\xf3\x7b", "\xf3\x7c", "\x00\x00", "\xf5\x48", + /* 0x972f */ "\xf5\x49", "\xc4\xc5", "\x90\xd2", "\xc5\x53", "\x00\x00", +- /* 0x9733 */ "\x00\x00", "\xf6\x6e", "\x90\xd4", "\x00\x00", "\xc5\x51", ++ /* 0x9734 */ "\x87\x6b", "\xf6\x6e", "\x90\xd4", "\x00\x00", "\xc5\x51", + /* 0x9739 */ "\xc5\x52", "\xf6\x6f", "\x00\x00", "\x00\x00", "\xc5\xb4", + /* 0x973e */ "\xc5\xb5", "\xf7\x71", "\x9a\x5b", "\x95\xfd", "\xc6\x45", + /* 0x9743 */ "\xf8\xcf", "\xc6\x47", "\x00\x00", "\xf8\xce", "\xf8\xd0", +- /* 0x9748 */ "\xc6\x46", "\xf9\x57", "\x00\x00", "\xf9\xad", "\x00\x00", ++ /* 0x9748 */ "\xc6\x46", "\xf9\x57", "\x87\xb1", "\xf9\xad", "\x00\x00", + /* 0x974c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xc4", +- /* 0x9752 */ "\xab\x43", "\x00\x00", "\x00\x00", "\x00\x00", "\xb9\x74", ++ /* 0x9752 */ "\xab\x43", "\x00\x00", "\x00\x00", "\x8c\x66", "\xb9\x74", + /* 0x9757 */ "\x90\xde", "\xe4\xbe", "\x00\x00", "\xe8\xb0", "\xc0\x51", + /* 0x975c */ "\xc0\x52", "\x9c\xe4", "\xab\x44", "\x90\xe1", "\xbe\x61", + /* 0x9761 */ "\xc3\xfb", "\xad\xb1", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -10252,10 +10352,10 @@ static const char from_ucs4[][2] = + /* 0x9847 */ "\x9b\x5e", "\xed\xd4", "\xef\x48", "\xef\x47", "\x90\xf8", + /* 0x984c */ "\xc3\x44", "\xc3\x42", "\xc3\x45", "\xc3\x43", "\xf1\xa8", + /* 0x9851 */ "\xf1\xa9", "\xf1\xaa", "\xc3\x46", "\x00\x00", "\x00\x00", +- /* 0x9855 */ "\x00\x00", "\xf3\xaa", "\xc4\x40", "\xf3\xa8", "\x00\x00", ++ /* 0x9856 */ "\x8c\xfc", "\xf3\xaa", "\xc4\x40", "\xf3\xa8", "\x00\x00", + /* 0x985b */ "\xc4\x41", "\xf3\xa7", "\xf3\xa9", "\xc3\xfe", "\xf5\x51", + /* 0x9860 */ "\xf5\x4e", "\x00\x00", "\xf5\x4f", "\xf5\x50", "\xf6\x72", +- /* 0x9865 */ "\xc5\x56", "\x90\xf9", "\xc5\x55", "\x00\x00", "\xf7\x74", ++ /* 0x9865 */ "\xc5\x56", "\x90\xf9", "\xc5\x55", "\x8c\xc9", "\xf7\x74", + /* 0x986a */ "\xf7\x73", "\xc5\xb8", "\xfa\x6a", "\x00\x00", "\x00\x00", + /* 0x986f */ "\xc5\xe3", "\xc6\x49", "\xc6\x60", "\xf9\x58", "\xf9\xae", + /* 0x9874 */ "\xf9\xaf", "\x8b\xef", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -10330,7 +10430,7 @@ static const char from_ucs4[][2] = + /* 0x99cd */ "\xe8\xc7", "\xe8\xcb", "\xe8\xc8", "\xbe\x6e", "\xbe\x71", + /* 0x99d2 */ "\xbe\x73", "\xe8\xc9", "\xe8\xca", "\xbe\x72", "\xe8\xcd", + /* 0x99d7 */ "\xe8\xd0", "\xe8\xce", "\xbe\x74", "\x9f\xab", "\xbe\x70", +- /* 0x99dc */ "\xe8\xc6", "\xbe\x6d", "\x00\x00", "\xbe\x6f", "\x00\x00", ++ /* 0x99dc */ "\xe8\xc6", "\xbe\x6d", "\x00\x00", "\xbe\x6f", "\x8c\xbe", + /* 0x99e1 */ "\x8e\xc1", "\xc0\x63", "\xec\x66", "\xec\x64", "\xec\x63", + /* 0x99e6 */ "\x95\x55", "\xec\x69", "\x00\x00", "\xec\x68", "\xec\x67", + /* 0x99ea */ "\x00\x00", "\xec\x62", "\xc0\x62", "\xec\x61", "\x00\x00", +@@ -10623,852 +10723,19 @@ static const char from_ucs4[][2] = + /* 0x9f85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x9f8a */ "\x00\x00", "\x00\x00", "\xc0\x73", "\x91\xcb", "\x00\x00", + /* 0x9f90 */ "\xc3\x65", "\xf5\xbf", "\xf6\xd5", "\x00\x00", "\xc5\xc7", +- /* 0x9f95 */ "\xf7\xce", "\x00\x00", "\x00\x00", "\xf9\xd5", "\x89\xc8", ++ /* 0x9f95 */ "\xf7\xce", "\x87\xac", "\x87\xa4", "\xf9\xd5", "\x89\xc8", + /* 0x9f99 */ "\x00\x00", "\x00\x00", "\xc0\x74", "\x00\x00", "\x00\x00", + /* 0x9f9f */ "\x8d\xaa", "\xef\xb6", "\x00\x00", "\xf7\xcf", "\x00\x00", +- /* 0x9fa4 */ "\xf9\xa1", "\x9f\xdd", +- +- /* 0xe003 */ "\xfa\x43", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe007 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe00c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe011 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe016 */ "\x00\x00", "\xfa\x58", "\x00\x00", "\x00\x00", "\xfa\x5b", +- /* 0xe01b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe020 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe025 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe02a */ "\x00\x00", "\x00\x00", "\xfa\x6d", "\x00\x00", "\x00\x00", +- /* 0xe02f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe034 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x78", "\x00\x00", +- /* 0xe039 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe03e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe043 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe048 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\xae", "\x00\x00", +- /* 0xe04d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe052 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe057 */ "\x00\x00", "\x00\x00", "\xfa\xbc", "\x00\x00", "\x00\x00", +- /* 0xe05c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe061 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe066 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe06b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe070 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe075 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe07a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe07f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe084 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe089 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe08e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe094 */ "\xfa\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe099 */ "\xfa\xfb", "\xfa\xfc", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe09d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\x68", +- /* 0xe0c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0d0 */ "\xfb\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xb7", +- /* 0xe0f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0f7 */ "\x00\x00", "\xfb\xbe", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe0fd */ "\xfb\xc2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe101 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xcb", +- /* 0xe106 */ "\x00\x00", "\x00\x00", "\xfb\xce", "\xfb\xcf", "\x00\x00", +- /* 0xe10b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe110 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe115 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe11a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe11f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe124 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe129 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe12e */ "\x00\x00", "\xfb\xf5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe133 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe138 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe13d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe142 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe147 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe14c */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x56", "\x00\x00", +- /* 0xe151 */ "\x00\x00", "\x00\x00", "\xfc\x5a", "\x00\x00", "\x00\x00", +- /* 0xe156 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe15b */ "\x00\x00", "\xfc\x63", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe160 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe165 */ "\x00\x00", "\x00\x00", "\xfc\x6e", "\x00\x00", "\xfc\x70", +- /* 0xe16a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe16f */ "\x00\x00", "\xfc\x77", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe175 */ "\xfc\x7b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe179 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe17e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe183 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe188 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe18d */ "\x00\x00", "\xfc\xb7", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe192 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe197 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe19c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1bb */ "\xfc\xe3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1c9 */ "\x00\x00", "\x00\x00", "\xfc\xf4", "\xfc\xf5", "\x00\x00", +- /* 0xe1ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x40", "\x00\x00", +- /* 0xe1d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1ec */ "\x00\x00", "\x00\x00", "\xfd\x58", "\x00\x00", "\x00\x00", +- /* 0xe1f2 */ "\xfd\x5b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe1f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x63", "\x00\x00", +- /* 0xe1fb */ "\x00\x00", "\x00\x00", "\xfd\x67", "\x00\x00", "\x00\x00", +- /* 0xe200 */ "\x00\x00", "\xfd\x6b", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe205 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe20b */ "\xfd\x74", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe20f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe214 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xa4", +- /* 0xe219 */ "\x00\x00", "\x00\x00", "\xfd\xa7", "\x00\x00", "\x00\x00", +- /* 0xe21e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe223 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xb2", "\x00\x00", +- /* 0xe228 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe22d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe232 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe237 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe23c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe241 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xd0", "\x00\x00", +- /* 0xe246 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xd5", "\x00\x00", +- /* 0xe24b */ "\x00\x00", "\x00\x00", "\xfd\xd9", "\x00\x00", "\x00\x00", +- /* 0xe250 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe255 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe25a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe25f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe264 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe269 */ "\x00\x00", "\xfd\xf6", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe26e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe273 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe278 */ "\x00\x00", "\xfe\x46", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe27d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x4e", +- /* 0xe282 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe287 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe28c */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x5c", "\x00\x00", +- /* 0xe291 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe296 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x67", +- /* 0xe29b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2a1 */ "\xfe\x6d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2af */ "\x00\x00", "\x00\x00", "\xfe\x7e", "\x00\x00", "\x00\x00", +- /* 0xe2b4 */ "\x00\x00", "\x00\x00", "\xfe\xa5", "\x00\x00", "\x00\x00", +- /* 0xe2b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2be */ "\x00\x00", "\x00\x00", "\xfe\xaf", "\x00\x00", "\x00\x00", +- /* 0xe2c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2c9 */ "\xfe\xb7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2d2 */ "\x00\x00", "\xfe\xc2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2e2 */ "\xfe\xd0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xd9", +- /* 0xe2ec */ "\xfe\xda", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xde", +- /* 0xe2f1 */ "\xfe\xdf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe2fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe300 */ "\xfe\xee", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe304 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe309 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe30e */ "\x00\x00", "\x00\x00", "\x8e\x40", "\x00\x00", "\x00\x00", +- /* 0xe313 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe318 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe31d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe322 */ "\x00\x00", "\x00\x00", "\x8e\x54", "\x00\x00", "\x00\x00", +- /* 0xe327 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe32c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x5f", "\x00\x00", +- /* 0xe331 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe336 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe33b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe340 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x74", +- /* 0xe345 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe34a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe34f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe354 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe359 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe35e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xb3", "\x00\x00", +- /* 0xe363 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe368 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe36d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe372 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe377 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe37c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xd2", +- /* 0xe382 */ "\x8e\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xd7", +- /* 0xe386 */ "\x00\x00", "\x00\x00", "\x8e\xda", "\x00\x00", "\x00\x00", +- /* 0xe38b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe390 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xe5", "\x00\x00", +- /* 0xe396 */ "\x8e\xe7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe39a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xef", "\x00\x00", +- /* 0xe3a0 */ "\x8e\xf1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3b4 */ "\x8f\x46", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3b8 */ "\x00\x00", "\x00\x00", "\x8f\x4d", "\x00\x00", "\x00\x00", +- /* 0xe3bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3cd */ "\x8f\x5f", "\x00\x00", "\x8f\x61", "\x00\x00", "\x00\x00", +- /* 0xe3d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\x67", "\x00\x00", +- /* 0xe3d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3e1 */ "\x8f\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3e5 */ "\x00\x00", "\x8f\x79", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3f0 */ "\x8f\xa4", "\x00\x00", "\x8f\xa6", "\x00\x00", "\x8f\xa8", +- /* 0xe3f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe3fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe403 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe408 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe40d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe412 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe417 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe41c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe421 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xda", +- /* 0xe426 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe42b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe430 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe436 */ "\x8f\xea", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe43a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe43f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe444 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xfc", "\x00\x00", +- /* 0xe449 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x42", "\x00\x00", +- /* 0xe44e */ "\x00\x00", "\x90\x45", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe453 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe458 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe45d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe462 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x5c", +- /* 0xe468 */ "\x90\x5d", "\x90\x5e", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe46c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe471 */ "\x00\x00", "\x00\x00", "\x90\x69", "\x00\x00", "\x00\x00", +- /* 0xe476 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe47b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe480 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe485 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xa1", +- /* 0xe48a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe48f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe494 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe499 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe49e */ "\x00\x00", "\x00\x00", "\x90\xb8", "\x00\x00", "\x00\x00", +- /* 0xe4a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xd8", +- /* 0xe4c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xdd", +- /* 0xe4c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4da */ "\x00\x00", "\x00\x00", "\x90\xf4", "\x00\x00", "\x00\x00", +- /* 0xe4df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe4fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe502 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe507 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe50c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe511 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe516 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe51b */ "\x00\x00", "\x00\x00", "\x91\x76", "\x00\x00", "\x00\x00", +- /* 0xe520 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x7c", "\x00\x00", +- /* 0xe525 */ "\x00\x00", "\x00\x00", "\x91\xa2", "\x00\x00", "\x00\x00", +- /* 0xe52a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xa8", "\x91\xa9", +- /* 0xe52f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe534 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe539 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe53e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe543 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe548 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe54d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe552 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe557 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe55c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe561 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe566 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe56b */ "\x00\x00", "\x91\xe7", "\x00\x00", "\x00\x00", "\x91\xea", +- /* 0xe570 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe575 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xf4", +- /* 0xe57a */ "\x00\x00", "\x00\x00", "\x91\xf7", "\x00\x00", "\x00\x00", +- /* 0xe57f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xfe", +- /* 0xe584 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe589 */ "\x00\x00", "\x92\x46", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe58e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe593 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe598 */ "\x00\x00", "\x92\x55", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe59e */ "\x92\x59", "\x00\x00", "\x92\x5b", "\x00\x00", "\x00\x00", +- /* 0xe5a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x61", "\x00\x00", +- /* 0xe5a7 */ "\x00\x00", "\x00\x00", "\x92\x65", "\x00\x00", "\x00\x00", +- /* 0xe5ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5c0 */ "\x00\x00", "\x92\x7d", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5c5 */ "\x00\x00", "\x00\x00", "\x92\xa5", "\x00\x00", "\x00\x00", +- /* 0xe5ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xb5", "\x00\x00", +- /* 0xe5d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xce", "\x00\x00", +- /* 0xe5f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe5fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe601 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe606 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe60b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe610 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe615 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xf6", "\x00\x00", +- /* 0xe61a */ "\x00\x00", "\x92\xf9", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe61f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe624 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe629 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe62e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe633 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe638 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe63d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe642 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x64", "\x00\x00", +- /* 0xe647 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe64c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe651 */ "\x00\x00", "\x00\x00", "\x93\x72", "\x00\x00", "\x00\x00", +- /* 0xe656 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe65b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x7e", +- /* 0xe660 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe665 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xaa", +- /* 0xe66a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe66f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe674 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe679 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xbd", "\x00\x00", +- /* 0xe67e */ "\x00\x00", "\x93\xc0", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe683 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe688 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe68e */ "\x93\xce", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe692 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xd7", +- /* 0xe697 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe69c */ "\x00\x00", "\x93\xde", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6c0 */ "\x94\x41", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6c5 */ "\x94\x46", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6de */ "\x94\x5f", "\x94\x60", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe6fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe701 */ "\x94\xa4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe705 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe70a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe70f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xb6", "\x00\x00", +- /* 0xe714 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe719 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe71e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe723 */ "\x00\x00", "\x94\xc8", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe728 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe72d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe732 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe737 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe73d */ "\x94\xe0", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xe4", +- /* 0xe741 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe746 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe74b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe750 */ "\x00\x00", "\x94\xf5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe755 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe75a */ "\x00\x00", "\x00\x00", "\x95\x41", "\x00\x00", "\x00\x00", +- /* 0xe75f */ "\x00\x00", "\x95\x45", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe764 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x4c", "\x00\x00", +- /* 0xe769 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe76e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe773 */ "\x00\x00", "\x95\x59", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe778 */ "\x00\x00", "\x95\x5e", "\x00\x00", "\x00\x00", "\x95\x61", +- /* 0xe77d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe782 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe787 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe78c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x74", "\x00\x00", +- /* 0xe791 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe797 */ "\x95\x7b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe79b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7a6 */ "\x95\xac", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xba", +- /* 0xe7b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7d7 */ "\x00\x00", "\x00\x00", "\x95\xe0", "\x00\x00", "\x00\x00", +- /* 0xe7dd */ "\x95\xe3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7e6 */ "\x00\x00", "\x95\xee", "\x95\xef", "\x00\x00", "\x00\x00", +- /* 0xe7eb */ "\x00\x00", "\x95\xf3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7f1 */ "\x95\xf7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe7fb */ "\x96\x42", "\x96\x43", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe800 */ "\x96\x47", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe804 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe809 */ "\x00\x00", "\x00\x00", "\x96\x53", "\x00\x00", "\x00\x00", +- /* 0xe80e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\x5a", +- /* 0xe813 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe818 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe81d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\x68", "\x00\x00", +- /* 0xe822 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe828 */ "\x96\x6f", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe82d */ "\x96\x74", "\x00\x00", "\x96\x76", "\x00\x00", "\x00\x00", +- /* 0xe831 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe836 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe83b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe840 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe845 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe84a */ "\x00\x00", "\x00\x00", "\x96\xb6", "\x00\x00", "\x00\x00", +- /* 0xe84f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe855 */ "\x96\xbe", "\x96\xbf", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe859 */ "\x00\x00", "\x96\xc4", "\x00\x00", "\x96\xc6", "\x00\x00", +- /* 0xe85e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe863 */ "\x00\x00", "\x96\xce", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe868 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe86d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe872 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe877 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe87c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe881 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe887 */ "\x96\xf0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe88b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xf8", "\x00\x00", +- /* 0xe891 */ "\x96\xfa", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe895 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe89a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe89f */ "\x00\x00", "\x97\x4b", "\x00\x00", "\x00\x00", "\x97\x4e", +- /* 0xe8a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x6c", +- /* 0xe8c3 */ "\x97\x6d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8cd */ "\x97\x77", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xa1", "\x97\xa2", +- /* 0xe8d6 */ "\x00\x00", "\x00\x00", "\x97\xa5", "\x97\xa6", "\x00\x00", +- /* 0xe8db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8e1 */ "\x97\xad", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xb1", +- /* 0xe8e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe8f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xca", +- /* 0xe8fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe903 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe908 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe90d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe912 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xe3", +- /* 0xe918 */ "\x97\xe4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe91c */ "\x00\x00", "\x00\x00", "\x97\xeb", "\x00\x00", "\x00\x00", +- /* 0xe921 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xf1", "\x00\x00", +- /* 0xe926 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xf7", +- /* 0xe92b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe930 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x41", "\x00\x00", +- /* 0xe935 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe93a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe93f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe944 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe949 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe94e */ "\x00\x00", "\x98\x5d", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe953 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe958 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe95d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe962 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x74", +- /* 0xe967 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe96c */ "\x00\x00", "\x98\x7b", "\x98\x7c", "\x00\x00", "\x00\x00", +- /* 0xe971 */ "\x00\x00", "\x98\xa2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe977 */ "\x98\xa6", "\x00\x00", "\x00\x00", "\x98\xa9", "\x98\xaa", +- /* 0xe97b */ "\x00\x00", "\x98\xac", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe980 */ "\x00\x00", "\x98\xb1", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe985 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe98a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe98f */ "\x00\x00", "\x98\xc0", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe994 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe999 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe99e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xe9c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xfa", +- +- /* 0xeaa9 */ "\x9a\x7c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeaad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeab2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeab7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeabc */ "\x00\x00", "\x00\x00", "\x9a\xb4", "\x9a\xb5", "\x9a\xb6", +- /* 0xeac1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xba", "\x00\x00", +- /* 0xeac6 */ "\x00\x00", "\x00\x00", "\x9a\xbe", "\x9a\xbf", "\x9a\xc0", +- /* 0xeacc */ "\x9a\xc1", "\x00\x00", "\x00\x00", "\x9a\xc4", "\x9a\xc5", +- /* 0xead1 */ "\x9a\xc6", "\x00\x00", "\x9a\xc8", "\x9a\xc9", "\x00\x00", +- /* 0xead6 */ "\x9a\xcb", "\x9a\xcc", "\x00\x00", "\x9a\xce", "\x9a\xcf", +- /* 0xeada */ "\x00\x00", "\x9a\xd1", "\x00\x00", "\x9a\xd3", "\x9a\xd4", +- /* 0xeae0 */ "\x9a\xd5", "\x9a\xd6", "\x9a\xd7", "\x9a\xd8", "\x00\x00", +- /* 0xeae4 */ "\x00\x00", "\x00\x00", "\x9a\xdc", "\x00\x00", "\x9a\xde", +- /* 0xeaea */ "\x9a\xdf", "\x00\x00", "\x9a\xe1", "\x00\x00", "\x9a\xe3", +- /* 0xeaee */ "\x00\x00", "\x9a\xe5", "\x9a\xe6", "\x00\x00", "\x00\x00", +- /* 0xeaf3 */ "\x00\x00", "\x9a\xea", "\x9a\xeb", "\x00\x00", "\x9a\xed", +- /* 0xeaf9 */ "\x9a\xee", "\x9a\xef", "\x9a\xf0", "\x00\x00", "\x00\x00", +- /* 0xeafd */ "\x00\x00", "\x9a\xf4", "\x9a\xf5", "\x00\x00", "\x9a\xf7", +- /* 0xeb03 */ "\x9a\xf8", "\x9a\xf9", "\x9a\xfa", "\x00\x00", "\x00\x00", +- /* 0xeb08 */ "\x9a\xfd", "\x9a\xfe", "\x9b\x40", "\x9b\x41", "\x9b\x42", +- /* 0xeb0d */ "\x9b\x43", "\x9b\x44", "\x9b\x45", "\x00\x00", "\x00\x00", +- /* 0xeb12 */ "\x9b\x48", "\x00\x00", "\x00\x00", "\x9b\x4b", "\x00\x00", +- /* 0xeb16 */ "\x00\x00", "\x00\x00", "\x9b\x4f", "\x9b\x50", "\x9b\x51", +- /* 0xeb1c */ "\x9b\x52", "\x9b\x53", "\x00\x00", "\x9b\x55", "\x9b\x56", +- /* 0xeb20 */ "\x00\x00", "\x00\x00", "\x9b\x59", "\x00\x00", "\x9b\x5b", +- /* 0xeb25 */ "\x00\x00", "\x9b\x5d", "\x00\x00", "\x00\x00", "\x9b\x60", +- /* 0xeb2a */ "\x00\x00", "\x9b\x62", "\x9b\x63", "\x9b\x64", "\x00\x00", +- /* 0xeb30 */ "\x9b\x66", "\x9b\x67", "\x9b\x68", "\x9b\x69", "\x9b\x6a", +- /* 0xeb35 */ "\x9b\x6b", "\x9b\x6c", "\x9b\x6d", "\x9b\x6e", "\x9b\x6f", +- /* 0xeb39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x73", "\x9b\x74", +- /* 0xeb3f */ "\x9b\x75", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x79", +- /* 0xeb44 */ "\x9b\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeb48 */ "\x00\x00", "\x9b\xa2", "\x00\x00", "\x00\x00", "\x9b\xa5", +- /* 0xeb4e */ "\x9b\xa6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeb53 */ "\x9b\xab", "\x00\x00", "\x9b\xad", "\x9b\xae", "\x00\x00", +- /* 0xeb58 */ "\x9b\xb0", "\x00\x00", "\x9b\xb2", "\x9b\xb3", "\x00\x00", +- /* 0xeb5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeb62 */ "\x9b\xba", "\x9b\xbb", "\x00\x00", "\x9b\xbd", "\x00\x00", +- /* 0xeb67 */ "\x9b\xbf", "\x9b\xc0", "\x9b\xc1", "\x00\x00", "\x00\x00", +- /* 0xeb6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xc7", "\x9b\xc8", +- /* 0xeb71 */ "\x9b\xc9", "\x00\x00", "\x9b\xcb", "\x00\x00", "\x00\x00", +- /* 0xeb76 */ "\x9b\xce", "\x9b\xcf", "\x00\x00", "\x00\x00", "\x9b\xd2", +- /* 0xeb7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xd6", "\x9b\xd7", +- /* 0xeb80 */ "\x9b\xd8", "\x00\x00", "\x00\x00", "\x9b\xdb", "\x00\x00", +- /* 0xeb84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xe0", "\x00\x00", +- /* 0xeb8a */ "\x9b\xe2", "\x00\x00", "\x9b\xe4", "\x00\x00", "\x00\x00", +- /* 0xeb8e */ "\x00\x00", "\x9b\xe8", "\x00\x00", "\x00\x00", "\x9b\xeb", +- /* 0xeb93 */ "\x00\x00", "\x9b\xed", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeb99 */ "\x9b\xf1", "\x00\x00", "\x9b\xf3", "\x00\x00", "\x00\x00", +- /* 0xeb9d */ "\x00\x00", "\x9b\xf7", "\x00\x00", "\x00\x00", "\x9b\xfa", +- /* 0xeba2 */ "\x00\x00", "\x00\x00", "\x9b\xfd", "\x9b\xfe", "\x00\x00", +- /* 0xeba7 */ "\x00\x00", "\x00\x00", "\x9c\x43", "\x9c\x44", "\x00\x00", +- /* 0xebac */ "\x00\x00", "\x9c\x47", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xebb2 */ "\x9c\x4b", "\x9c\x4c", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xebb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xebbb */ "\x00\x00", "\x9c\x56", "\x00\x00", "\x9c\x58", "\x00\x00", +- /* 0xebc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x5e", +- /* 0xebc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x63", +- /* 0xebca */ "\x00\x00", "\x9c\x65", "\x00\x00", "\x9c\x67", "\x00\x00", +- /* 0xebd0 */ "\x9c\x69", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xebd5 */ "\x9c\x6e", "\x00\x00", "\x9c\x70", "\x9c\x71", "\x00\x00", +- /* 0xebda */ "\x9c\x73", "\x9c\x74", "\x00\x00", "\x9c\x76", "\x00\x00", +- /* 0xebdf */ "\x9c\x78", "\x00\x00", "\x9c\x7a", "\x00\x00", "\x00\x00", +- /* 0xebe4 */ "\x9c\x7d", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xa3", +- /* 0xebe9 */ "\x9c\xa4", "\x00\x00", "\x9c\xa6", "\x9c\xa7", "\x00\x00", +- /* 0xebed */ "\x00\x00", "\x9c\xaa", "\x00\x00", "\x00\x00", "\x9c\xad", +- /* 0xebf2 */ "\x00\x00", "\x00\x00", "\x9c\xb0", "\x00\x00", "\x00\x00", +- /* 0xebf7 */ "\x00\x00", "\x9c\xb4", "\x9c\xb5", "\x00\x00", "\x00\x00", +- /* 0xebfc */ "\x00\x00", "\x9c\xb9", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec06 */ "\x00\x00", "\x9c\xc3", "\x9c\xc4", "\x00\x00", "\x00\x00", +- /* 0xec0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xca", "\x00\x00", +- /* 0xec10 */ "\x00\x00", "\x00\x00", "\x9c\xce", "\x00\x00", "\x00\x00", +- /* 0xec15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xd4", "\x9c\xd5", +- /* 0xec1b */ "\x9c\xd6", "\x9c\xd7", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xdf", +- /* 0xec24 */ "\x00\x00", "\x9c\xe1", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec29 */ "\x00\x00", "\x9c\xe6", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec2f */ "\x9c\xea", "\x00\x00", "\x00\x00", "\x9c\xed", "\x00\x00", +- /* 0xec33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec3d */ "\x00\x00", "\x9c\xfa", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec43 */ "\x9c\xfe", "\x9d\x40", "\x9d\x41", "\x9d\x42", "\x9d\x43", +- /* 0xec48 */ "\x9d\x44", "\x9d\x45", "\x00\x00", "\x9d\x47", "\x00\x00", +- /* 0xec4c */ "\x00\x00", "\x00\x00", "\x9d\x4b", "\x00\x00", "\x00\x00", +- /* 0xec52 */ "\x9d\x4e", "\x00\x00", "\x9d\x50", "\x00\x00", "\x9d\x52", +- /* 0xec57 */ "\x9d\x53", "\x9d\x54", "\x00\x00", "\x9d\x56", "\x00\x00", +- /* 0xec5c */ "\x9d\x58", "\x9d\x59", "\x00\x00", "\x00\x00", "\x9d\x5c", +- /* 0xec60 */ "\x00\x00", "\x9d\x5e", "\x9d\x5f", "\x00\x00", "\x00\x00", +- /* 0xec65 */ "\x00\x00", "\x9d\x63", "\x00\x00", "\x9d\x65", "\x9d\x66", +- /* 0xec6b */ "\x9d\x67", "\x9d\x68", "\x9d\x69", "\x00\x00", "\x9d\x6b", +- /* 0xec70 */ "\x9d\x6c", "\x00\x00", "\x9d\x6e", "\x9d\x6f", "\x00\x00", +- /* 0xec75 */ "\x9d\x71", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x75", +- /* 0xec79 */ "\x00\x00", "\x9d\x77", "\x00\x00", "\x00\x00", "\x9d\x7a", +- /* 0xec7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec84 */ "\x9d\xa2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec8e */ "\x9d\xac", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xb0", +- /* 0xec92 */ "\x00\x00", "\x00\x00", "\x9d\xb3", "\x00\x00", "\x00\x00", +- /* 0xec97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xec9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeca1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeca6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xcd", "\x00\x00", +- /* 0xecb0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecb6 */ "\x9d\xd4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecbf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecc4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecc9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeccf */ "\x9d\xed", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xfa", "\x00\x00", +- /* 0xecdd */ "\x00\x00", "\x00\x00", "\x9d\xfe", "\x9e\x40", "\x00\x00", +- /* 0xece2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xece7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x4f", "\x00\x00", +- /* 0xecf2 */ "\x9e\x51", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecf6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xecfc */ "\x9e\x5b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed0f */ "\x00\x00", "\x9e\x70", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x7c", "\x00\x00", +- /* 0xed1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed24 */ "\x9e\xa5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed29 */ "\x9e\xaa", "\x00\x00", "\x00\x00", "\x9e\xad", "\x00\x00", +- /* 0xed2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xbc", "\x00\x00", +- /* 0xed3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xc2", +- /* 0xed41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xd0", "\x00\x00", +- /* 0xed50 */ "\x00\x00", "\x9e\xd3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xe0", +- /* 0xed5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed69 */ "\x00\x00", "\x9e\xec", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xf9", +- /* 0xed78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed82 */ "\x00\x00", "\x9f\x46", "\x9f\x47", "\x00\x00", "\x00\x00", +- /* 0xed88 */ "\x9f\x4a", "\x00\x00", "\x00\x00", "\x9f\x4d", "\x00\x00", +- /* 0xed8c */ "\x00\x00", "\x9f\x50", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xed9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeda0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeda5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedaa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedaf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedb4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedcd */ "\x00\x00", "\x9f\xb3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedd7 */ "\x00\x00", "\x00\x00", "\x9f\xbe", "\x00\x00", "\x00\x00", +- /* 0xeddc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xede1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xede6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedeb */ "\x00\x00", "\x9f\xd1", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedf0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedf5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedfa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xedff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xec", "\x00\x00", +- /* 0xee09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xa4", "\x00\x00", +- /* 0xee5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee68 */ "\x00\x00", "\xa0\xb1", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xee9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeea5 */ "\xa0\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeea9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeeae */ "\x00\x00", "\xa0\xf7", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xeeb4 */ "\xa0\xfb", "\x00\x00", "\x00\x00", "\xa0\xfe", ++ /* 0x9fa4 */ "\xf9\xa1", "\x9f\xdd", "\x8c\x43", "\x8c\x6d", "\x8c\x74", ++ /* 0x9fa9 */ "\x8c\xb7", "\x8c\xb9", "\x8c\xbb", "\x8c\xc0", "\x8c\xd7", ++ /* 0x9fae */ "\x8c\xd8", "\x8c\xda", "\xc8\xa1", "\xc8\xa3", "\x8c\xed", ++ /* 0x9fb3 */ "\x8d\x48", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x9fb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x9fbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x9fc1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x9fc7 */ "\x87\xc2", "\x87\xd2", "\x87\xd6", "\x87\xda", "\x87\xdf", + +- /* 0xf303 */ "\x88\x40", "\x88\x41", "\x88\x42", "\x88\x43", "\x88\x44", +- /* 0xf308 */ "\x88\x45", "\x88\x46", "\x88\x47", "\x88\x48", "\x88\x49", +- /* 0xf30d */ "\x88\x4a", "\x88\x4b", "\x88\x4c", "\x88\x4d", "\x88\x4e", +- /* 0xf312 */ "\x88\x4f", "\x88\x50", "\x88\x51", "\x88\x52", "\x88\x53", +- /* 0xf317 */ "\x88\x54", "\x88\x55", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf31b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf320 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x88\x62", +- /* 0xf325 */ "\x00\x00", "\x88\x64", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf32a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf32f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf334 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf339 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf33e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf344 */ "\x88\xa3", "\x00\x00", "\x88\xa5", "\x00\x00", "\x00\x00", +- /* 0xf348 */ "\x00\x00", "\x88\xa9", "\x88\xaa", "\x00\x00", "\x00\x00", +- /* 0xf34d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf352 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf357 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf35c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf361 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf366 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf36b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf370 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf375 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf37a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf37f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf384 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf389 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf38e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf393 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf398 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf39d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x89\x41", "\x00\x00", +- /* 0xf3a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3ed */ "\x00\x00", "\x00\x00", "\x89\xb2", "\x00\x00", "\x00\x00", +- /* 0xf3f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf3f7 */ "\x00\x00", "\x89\xbb", "\x00\x00", "\x00\x00", "\x89\xbe", +- /* 0xf3fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf401 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf406 */ "\x00\x00", "\x89\xca", "\x00\x00", "\x00\x00", "\x89\xcd", +- /* 0xf40b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf410 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf415 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf41a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf41f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf424 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf429 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf42e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf433 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf438 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x40", +- /* 0xf43d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x44", "\x8a\x45", +- /* 0xf442 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf447 */ "\x00\x00", "\x8a\x4c", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf44d */ "\x8a\x50", "\x00\x00", "\x00\x00", "\x8a\x53", "\x00\x00", +- /* 0xf451 */ "\x00\x00", "\x00\x00", "\x8a\x57", "\x00\x00", "\x00\x00", +- /* 0xf456 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x5d", "\x8a\x5e", +- /* 0xf45c */ "\x8a\x5f", "\x8a\x60", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf460 */ "\x00\x00", "\x8a\x65", "\x00\x00", "\x00\x00", "\x8a\x68", +- /* 0xf466 */ "\x8a\x69", "\x00\x00", "\x00\x00", "\x8a\x6c", "\x00\x00", +- /* 0xf46a */ "\x00\x00", "\x00\x00", "\x8a\x70", "\x8a\x71", "\x8a\x72", +- /* 0xf46f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf474 */ "\x00\x00", "\x00\x00", "\x8a\x7a", "\x8a\x7b", "\x00\x00", +- /* 0xf479 */ "\x00\x00", "\x00\x00", "\x8a\xa1", "\x8a\xa2", "\x8a\xa3", +- /* 0xf47e */ "\x00\x00", "\x8a\xa5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf483 */ "\x00\x00", "\x8a\xaa", "\x00\x00", "\x00\x00", "\x8a\xad", +- /* 0xf488 */ "\x00\x00", "\x00\x00", "\x8a\xb0", "\x00\x00", "\x8a\xb2", +- /* 0xf48d */ "\x00\x00", "\x8a\xb4", "\x8a\xb5", "\x8a\xb6", "\x00\x00", +- /* 0xf492 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xbc", +- /* 0xf498 */ "\x8a\xbd", "\x00\x00", "\x00\x00", "\x8a\xc0", "\x00\x00", +- /* 0xf49c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4a1 */ "\x00\x00", "\x00\x00", "\x8a\xc9", "\x00\x00", "\x00\x00", +- /* 0xf4a7 */ "\x8a\xcc", "\x00\x00", "\x00\x00", "\x8a\xcf", "\x00\x00", +- /* 0xf4ab */ "\x00\x00", "\x8a\xd2", "\x00\x00", "\x8a\xd4", "\x00\x00", +- /* 0xf4b0 */ "\x00\x00", "\x00\x00", "\x8a\xd8", "\x8a\xd9", "\x00\x00", +- /* 0xf4b5 */ "\x00\x00", "\x8a\xdc", "\x00\x00", "\x00\x00", "\x8a\xdf", +- /* 0xf4bb */ "\x8a\xe0", "\x8a\xe1", "\x8a\xe2", "\x00\x00", "\x00\x00", +- /* 0xf4c0 */ "\x8a\xe5", "\x8a\xe6", "\x00\x00", "\x8a\xe8", "\x00\x00", +- /* 0xf4c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xed", "\x00\x00", +- /* 0xf4c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xf3", +- /* 0xf4cf */ "\x8a\xf4", "\x00\x00", "\x00\x00", "\x8a\xf7", "\x00\x00", +- /* 0xf4d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x48", +- /* 0xf4e2 */ "\x00\x00", "\x00\x00", "\x8b\x4b", "\x00\x00", "\x8b\x4d", +- /* 0xf4e8 */ "\x8b\x4e", "\x8b\x4f", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4f1 */ "\x00\x00", "\x8b\x59", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf4fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf500 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf505 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf50a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf50f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf514 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf519 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf51e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xaa", "\x8b\xab", +- /* 0xf523 */ "\x00\x00", "\x8b\xad", "\x8b\xae", "\x00\x00", "\x00\x00", +- /* 0xf528 */ "\x00\x00", "\x8b\xb2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf52d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf532 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf537 */ "\x00\x00", "\x00\x00", "\x8b\xc2", "\x8b\xc3", "\x00\x00", +- /* 0xf53d */ "\x8b\xc5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf541 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf546 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf54b */ "\x00\x00", "\x00\x00", "\x8b\xd6", "\x00\x00", "\x00\x00", +- /* 0xf550 */ "\x00\x00", "\x00\x00", "\x8b\xdb", "\x00\x00", "\x00\x00", +- /* 0xf556 */ "\x8b\xde", "\x00\x00", "\x00\x00", "\x8b\xe1", "\x8b\xe2", +- /* 0xf55a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xe6", "\x00\x00", +- /* 0xf55f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf565 */ "\x8b\xed", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf569 */ "\x00\x00", "\x8b\xf3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0xf56e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xfa", +- +- /* 0xf6b0 */ "\x8d\xfe", +- +- /* 0xf7e5 */ "\xc8\x79", "\xc8\x7a", "\x00\x00", "\xc8\x7c", "\x00\x00", +- /* 0xf7ea */ "\xc8\x7e", "\xc8\xa1", "\x00\x00", "\xc8\xa3", "\xc8\xa4", ++ /* 0xf907 */ "\x8b\xf8", + + /* 0xfa0c */ "\xc9\x4a", "\xdd\xfc", + +@@ -11534,258 +10801,304 @@ static const char from_ucs4[][2] = + /* 0xffe6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0xffeb */ "\x00\x00", "\xf9\xfe", + +- /* 0x2003e */ "\x93\x75", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20042 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x76", "\x00\x00", +- /* 0x20047 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2004c */ "\x00\x00", "\x95\x48", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20051 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20056 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2005b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20060 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20065 */ "\x00\x00", "\x00\x00", "\x8e\xc6", +- ++ /* 0x20021 */ "\x9c\x71", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20025 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2002a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2002f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20034 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20039 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x75", ++ /* 0x2003e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20043 */ "\x00\x00", "\x00\x00", "\x93\x76", "\x00\x00", "\x00\x00", ++ /* 0x20048 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2004e */ "\x95\x48", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20052 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20057 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2005c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20061 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20066 */ "\x00\x00", "\x8e\xc6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2006b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20070 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20075 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2007a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2007f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20084 */ "\x00\x00", "\x8b\xc5", "\x8b\xfa", "\x00\x00", "\x00\x00", ++ /* 0x2008a */ "\xc8\x7c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2008e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20094 */ "\x9a\xb4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20098 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2009d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x88\x4e", ++ /* 0x200cb */ "\x88\x4b", "\xc8\x7a", "\x88\x48", "\x00\x00", "\x00\x00", ++ /* 0x200cf */ "\x00\x00", "\x88\x47", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x200e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x200ee */ "\xa0\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x200f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x200f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x200fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20101 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20106 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2010b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2010c */ "\x88\x45", "\x00\x00", "\x88\x53", "\x00\x00", "\x00\x00", + /* 0x20110 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20115 */ "\x00\x00", "\x00\x00", "\xfc\xad", + +- /* 0x201ab */ "\x92\x72", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201be */ "\x00\x00", "\x00\x00", "\xfc\x47", "\x00\x00", "\x00\x00", +- /* 0x201c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201d2 */ "\x00\x00", "\x94\xdf", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x201ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20204 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20209 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2020e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20214 */ "\x98\xa4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20218 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2021d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20222 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20227 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2022c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20231 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20236 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2023b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20240 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20245 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2024a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2024f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20254 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20259 */ "\x00\x00", "\x94\xe7", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2025e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20263 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20268 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2026d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20272 */ "\x00\x00", "\x90\xcb", "\x92\x7b", "\x00\x00", "\x00\x00", +- /* 0x20277 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2027c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20281 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20286 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2028b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20290 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20295 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xd8", "\x00\x00", +- /* 0x2029a */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x5f", "\x00\x00", +- /* 0x202a0 */ "\xfa\x54", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202bd */ "\x00\x00", "\x96\xda", "\x92\x79", "\x00\x00", "\x00\x00", +- /* 0x202c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x74", +- /* 0x202e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x202fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20303 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20308 */ "\x00\x00", "\x92\x75", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2030d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20312 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20317 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2031c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20321 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\xfb", "\x00\x00", +- /* 0x20326 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2032b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20330 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20335 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2033a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2033f */ "\x00\x00", "\x8a\x49", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20345 */ "\x92\xdf", "\x9b\x7c", "\xfa\x63", "\x00\x00", "\x00\x00", +- /* 0x20349 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2034e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20353 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20358 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2035d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20362 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20367 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2036c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20371 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20376 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2037b */ "\x00\x00", "\x00\x00", "\xfa\x60", "\x92\x6d", "\xfa\x62", +- /* 0x20380 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20385 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2038a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2038f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20394 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20399 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2039e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x6b", "\x00\x00", +- /* 0x203a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203b2 */ "\x00\x00", "\x00\x00", "\xfd\x6a", "\x00\x00", "\x00\x00", +- /* 0x203b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203c6 */ "\x00\x00", "\x00\x00", "\xfd\x54", "\x00\x00", "\x92\x73", +- /* 0x203cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203f3 */ "\x00\x00", "\x97\xd8", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x203f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xbb", "\x00\x00", +- /* 0x203fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20402 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20407 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2040c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20411 */ "\x00\x00", "\x93\x42", "\x92\x76", "\x00\x00", "\x00\x00", +- /* 0x20416 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2041b */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x65", "\x00\x00", +- /* 0x20420 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20425 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2042a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2042f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20434 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20439 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2043e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20443 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20448 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2044d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20452 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20457 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2045c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20461 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x6c", "\x00\x00", +- /* 0x20466 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2046b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20470 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20475 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2047a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2047f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20484 */ "\x00\x00", "\x00\x00", "\xfa\x6e", "\x00\x00", "\x00\x00", +- /* 0x20489 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2048e */ "\x00\x00", "\x00\x00", "\x92\xc0", "\x92\xbf", "\x00\x00", +- /* 0x20493 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20498 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2049d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204a3 */ "\x92\xbe", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x204f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xb3", +- /* 0x204fc */ "\x00\x00", "\x97\x75", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20501 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20506 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2050b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20510 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20515 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2051a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2051f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20524 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20529 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2052e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20533 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20538 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2053d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20542 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x40", +- /* 0x20547 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2054c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20551 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20556 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2055b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20560 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20565 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2056a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2056f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20574 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20579 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2057e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20583 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20588 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2058e */ "\xfa\x76", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20592 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20597 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2059c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xd0", "\x00\x00", +- /* 0x205a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205b0 */ "\x00\x00", "\x00\x00", "\xfa\x7b", "\x00\x00", "\x00\x00", +- /* 0x205b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205ce */ "\x00\x00", "\x89\xcc", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205dd */ "\x00\x00", "\xfa\x42", "\x92\xbc", "\x00\x00", "\x00\x00", +- /* 0x205e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x5c", "\x00\x00", +- /* 0x205ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x205fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20600 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20605 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2060a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2060f */ "\x00\x00", "\x9b\xb5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20614 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xa7", +- /* 0x2061a */ "\x97\xa4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2061e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20623 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20628 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2062d */ "\x00\x00", "\x00\x00", "\x90\xfd", ++ /* 0x201a4 */ "\x8c\xf5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201a9 */ "\x8a\xad", "\x00\x00", "\x92\x72", "\x00\x00", "\x00\x00", ++ /* 0x201ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x47", ++ /* 0x201c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xdf", "\x00\x00", ++ /* 0x201d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xd1", "\x00\x00", ++ /* 0x201f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x201fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20202 */ "\x00\x00", "\xfb\xcb", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20207 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x7d", ++ /* 0x2020c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20211 */ "\x00\x00", "\x00\x00", "\x98\xa4", "\x00\x00", "\x00\x00", ++ /* 0x20216 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2021b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20220 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20225 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2022a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2022f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20234 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xf9", ++ /* 0x20239 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2023e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20243 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20248 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2024d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20252 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20257 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xe7", "\x00\x00", ++ /* 0x2025c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20261 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20266 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2026b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20270 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xcb", "\x92\x7b", ++ /* 0x20275 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2027a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2027f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20284 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20289 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2028e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20293 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20299 */ "\x94\xd8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2029e */ "\xfc\x5f", "\x00\x00", "\xfa\x54", "\x00\x00", "\x00\x00", ++ /* 0x202a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202b7 */ "\x9a\xb5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xda", "\x92\x79", ++ /* 0x202c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202e3 */ "\x00\x00", "\xfa\x74", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x202fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20301 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20306 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x75", "\x00\x00", ++ /* 0x2030b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20310 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20315 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2031a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2031f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20325 */ "\x8d\xfb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20329 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2032e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20333 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20338 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2033d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x49", "\x00\x00", ++ /* 0x20342 */ "\x00\x00", "\x00\x00", "\x92\xdf", "\x9b\x7c", "\xfa\x63", ++ /* 0x20347 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2034c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20351 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20356 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2035b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20360 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20365 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2036a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2036f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20374 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20379 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x60", ++ /* 0x2037f */ "\x92\x6d", "\xfa\x62", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20383 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20388 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2038d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20392 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20397 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2039c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xb6", "\x00\x00", ++ /* 0x203a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203a7 */ "\x97\x6b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x6a", ++ /* 0x203b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x54", ++ /* 0x203c9 */ "\x00\x00", "\x92\x73", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xd8", "\x00\x00", ++ /* 0x203f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x203fc */ "\x9f\xbb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20400 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20405 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2040a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2040f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x42", "\x92\x76", ++ /* 0x20414 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20419 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2041f */ "\xfa\x65", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20423 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20428 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2042d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20432 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20437 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2043c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20441 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20446 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2044b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20450 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20455 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2045a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2045f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20465 */ "\x92\x6c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20469 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2046e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20473 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20478 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2047d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20482 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x6e", ++ /* 0x20487 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2048c */ "\x00\x00", "\x9e\xe0", "\x00\x00", "\x00\x00", "\x92\xc0", ++ /* 0x20492 */ "\x92\xbf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20496 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2049b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204a0 */ "\x00\x00", "\x00\x00", "\x92\xbe", "\x00\x00", "\x00\x00", ++ /* 0x204a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xba", ++ /* 0x204d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x204fa */ "\x00\x00", "\x8a\xb3", "\x00\x00", "\x97\x75", "\x00\x00", ++ /* 0x204ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20504 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20509 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2050e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20513 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20518 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2051d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20522 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20527 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2052c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20531 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20536 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2053b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20540 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20545 */ "\x00\x00", "\xfa\x40", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2054a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2054f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20554 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20559 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2055e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20563 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20568 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2056d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20572 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20577 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2057c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20581 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20586 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2058b */ "\x00\x00", "\x00\x00", "\xfa\x76", "\x00\x00", "\x00\x00", ++ /* 0x20590 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20595 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2059a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2059f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205a5 */ "\xfb\xd0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x7b", ++ /* 0x205b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205c3 */ "\xfe\x6d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205c7 */ "\x00\x00", "\x00\x00", "\x9b\xb3", "\x00\x00", "\x00\x00", ++ /* 0x205cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x89\xcc", "\x00\x00", ++ /* 0x205d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xbe", "\x00\x00", ++ /* 0x205d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205db */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x42", "\x92\xbc", ++ /* 0x205e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205eb */ "\x94\x5c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x205fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20603 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20608 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2060d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xb5", "\x00\x00", ++ /* 0x20612 */ "\x00\x00", "\x00\x00", "\x9a\xbf", "\x00\x00", "\x00\x00", ++ /* 0x20617 */ "\x00\x00", "\x98\xa7", "\x97\xa4", "\x00\x00", "\x00\x00", ++ /* 0x2061c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20621 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20626 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2062b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xfd", ++ /* 0x20630 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20635 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2063a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2063f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20644 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20649 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2064e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20653 */ "\x00\x00", "\x00\x00", "\xfc\x7b", "\x00\x00", "\x00\x00", ++ /* 0x20658 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2065d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20662 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20667 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2066c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20671 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xc0", + + /* 0x2070e */ "\x92\xc3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20712 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11794,7 +11107,7 @@ static const char from_ucs4[][2] = + /* 0x20721 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20726 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2072b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20730 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20731 */ "\x8a\xaa", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20735 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2073a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2073f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11824,29 +11137,89 @@ static const char from_ucs4[][2] = + /* 0x20862 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20867 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2086c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20871 */ "\x00\x00", "\x92\xc6", +- +- /* 0x20916 */ "\x95\x46", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2091a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2091f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20924 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20929 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2092e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20933 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20938 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2093d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20942 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20947 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2094c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20951 */ "\x00\x00", "\x00\x00", "\xfa\xc2", "\x00\x00", "\x00\x00", +- /* 0x20956 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2095b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20960 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20965 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2096a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2096f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20974 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xc3", +- ++ /* 0x20871 */ "\x00\x00", "\x92\xc6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20876 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2087b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20880 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20885 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2088a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2088f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20894 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20899 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2089e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xa6", ++ /* 0x208d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x208fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20902 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20907 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2090c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20911 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x46", ++ /* 0x20916 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2091b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20920 */ "\x00\x00", "\x00\x00", "\xfd\x63", "\x00\x00", "\x00\x00", ++ /* 0x20925 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2092a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2092f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20934 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20939 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2093e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20943 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20948 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2094d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20952 */ "\x00\x00", "\xfa\xc2", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20957 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2095c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20961 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20966 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2096b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20970 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20975 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xc3", "\x00\x00", ++ /* 0x2097a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2097f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20984 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20989 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2098e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20993 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20998 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2099d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x89\xb2", "\x00\x00", ++ /* 0x209e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x209fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20a01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20a06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20a0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a11 */ "\x9c\x66", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11865,13 +11238,13 @@ static const char from_ucs4[][2] = + /* 0x20a5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20a6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20a6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x62", + /* 0x20a6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20a88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20a88 */ "\x00\x00", "\x87\xa8", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20a97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11879,34 +11252,52 @@ static const char from_ucs4[][2] = + /* 0x20aa1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20aa6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20aab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20ab0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xc1", ++ /* 0x20ab0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xc1", "\x00\x00", ++ /* 0x20ab5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20aba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20abf */ "\x00\x00", "\x00\x00", "\x9a\xc4", "\x00\x00", "\x00\x00", ++ /* 0x20ac4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ac9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xc5", "\x00\x00", ++ /* 0x20ace */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ad3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ad8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20add */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ae2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ae7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20aec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20af1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20af6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20afb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20b00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20b05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20b0a */ "\x00\x00", "\x00\x00", "\x8e\xef", + + /* 0x20b8f */ "\xfa\xe9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20b93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20b98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20b9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20b9d */ "\x00\x00", "\x8d\x40", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ba2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20ba8 */ "\x92\x62", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ba8 */ "\x92\x62", "\x8a\xf7", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20bbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20bbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xc6", "\x00\x00", + /* 0x20bc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bc6 */ "\x92\xe1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20bca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20bcb */ "\x9a\xc9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bcf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bde */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\xc6", "\x00\x00", + /* 0x20be3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20be8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20be8 */ "\x00\x00", "\x00\x00", "\x97\xa5", "\x00\x00", "\x00\x00", + /* 0x20bed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20bf2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20bf7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20bf7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xcb", "\x00\x00", + /* 0x20bfc */ "\x00\x00", "\x00\x00", "\xfa\x72", "\x00\x00", "\x00\x00", + /* 0x20c01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x5e", ++ /* 0x20c0b */ "\x00\x00", "\x94\xe0", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11914,8 +11305,8 @@ static const char from_ucs4[][2] = + /* 0x20c24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c34 */ "\x8a\xe5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c38 */ "\x00\x00", "\xfe\x5c", "\x9a\xcc", "\x00\x00", "\x00\x00", + /* 0x20c3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xf9", "\x8a\x43", + /* 0x20c43 */ "\x8a\xa6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11923,48 +11314,48 @@ static const char from_ucs4[][2] = + /* 0x20c51 */ "\x00\x00", "\x9a\xcd", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xce", + /* 0x20c65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c74 */ "\x00\x00", "\x00\x00", "\xfa\xee", "\x9b\xcc", "\x00\x00", +- /* 0x20c79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c79 */ "\x00\x00", "\x00\x00", "\x9a\xcf", "\x00\x00", "\x00\x00", + /* 0x20c7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20c83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xd1", + /* 0x20c8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20c92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20c92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xfa", "\x00\x00", + /* 0x20c97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x7c", + /* 0x20c9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ca1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ca6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20cab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20cb0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20cb5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20cb0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xd3", ++ /* 0x20cb5 */ "\x00\x00", "\x00\x00", "\x97\xa6", "\x00\x00", "\x00\x00", + /* 0x20cba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20cbf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20cc4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20cc9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ccf */ "\x99\x5f", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xf6", + /* 0x20cd4 */ "\x9f\xc5", "\x8a\x59", "\x8b\x6b", "\x00\x00", "\x00\x00", +- /* 0x20cd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20cd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xd4", + /* 0x20cdd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ce2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ce7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20cec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ced */ "\x9a\xd5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20cf1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20cf6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20cfb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20cfb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xa2", "\x00\x00", + /* 0x20d00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d15 */ "\x8a\x44", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\x4a", + /* 0x20d28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xa1", "\xfd\xa4", + /* 0x20d32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -11977,24 +11368,24 @@ static const char from_ucs4[][2] = + /* 0x20d5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d6f */ "\x9a\xd6", "\x00\x00", "\x9f\x4d", "\x00\x00", "\x00\x00", ++ /* 0x20d74 */ "\xfa\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x57", "\x00\x00", + /* 0x20d7e */ "\x8b\x43", "\x8b\x44", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20d8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xb6", + /* 0x20d96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20d9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20d9c */ "\x8a\xc0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20da0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20da5 */ "\x00\x00", "\x9e\x54", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20daa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20daf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20daf */ "\x00\x00", "\x00\x00", "\x9a\xd7", "\x00\x00", "\x00\x00", + /* 0x20db4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20db9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20dbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20dc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20dc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xd8", + /* 0x20dc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20dcd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20dd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12006,7 +11397,7 @@ static const char from_ucs4[][2] = + /* 0x20df0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20df5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20dfa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20dff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20dff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xdc", + /* 0x20e04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xca", + /* 0x20e0a */ "\x9e\xa8", "\x00\x00", "\x00\x00", "\x92\x63", "\x9a\xdd", + /* 0x20e0f */ "\x8b\x65", "\x8b\x6f", "\x8b\x7e", "\x00\x00", "\x00\x00", +@@ -12021,7 +11412,7 @@ static const char from_ucs4[][2] = + /* 0x20e3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20e4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20e4a */ "\x00\x00", "\x8a\xf4", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12029,16 +11420,16 @@ static const char from_ucs4[][2] = + /* 0x20e63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xbe", + /* 0x20e6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20e72 */ "\x00\x00", "\x00\x00", "\xfc\xde", "\x9d\xfd", "\x8b\x66", ++ /* 0x20e73 */ "\x9a\xe1", "\x00\x00", "\xfc\xde", "\x9d\xfd", "\x8b\x66", + /* 0x20e78 */ "\x8b\x70", "\x8b\x75", "\x8a\xe4", "\x8b\xa4", "\x00\x00", + /* 0x20e7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20e8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20e8c */ "\x8a\xed", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20e90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20e95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20e9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20e9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20e96 */ "\x8a\x5d", "\x00\x00", "\x8b\x48", "\x00\x00", "\x00\x00", ++ /* 0x20e9a */ "\x00\x00", "\x00\x00", "\x9d\xed", "\x00\x00", "\x00\x00", ++ /* 0x20e9f */ "\x00\x00", "\x00\x00", "\x9e\x40", "\x00\x00", "\x00\x00", + /* 0x20ea4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20eaa */ "\x8a\xef", "\x8a\xf6", "\x9e\x76", "\x00\x00", "\x00\x00", + /* 0x20eae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12049,8 +11440,8 @@ static const char from_ucs4[][2] = + /* 0x20ec7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ecc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ed1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20ed6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20edb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20ed7 */ "\x9a\xde", "\x8d\xfe", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20edb */ "\x00\x00", "\xfa\xfc", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ee0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20ee5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20eea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12063,8 +11454,8 @@ static const char from_ucs4[][2] = + /* 0x20f0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20f1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20f21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20f1d */ "\x97\x4b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20f21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\x53", + /* 0x20f26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f2b */ "\x00\x00", "\x9a\xe0", "\x8b\x4a", "\x00\x00", "\x8a\xf1", + /* 0x20f31 */ "\x8a\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12072,12 +11463,12 @@ static const char from_ucs4[][2] = + /* 0x20f3b */ "\xa0\xab", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20f49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20f49 */ "\x00\x00", "\x00\x00", "\x8a\xb5", "\x00\x00", "\x00\x00", + /* 0x20f4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20f62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20f62 */ "\x00\x00", "\x8a\x5f", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12086,7 +11477,7 @@ static const char from_ucs4[][2] = + /* 0x20f80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f8a */ "\x00\x00", "\x00\x00", "\x8a\xee", "\x00\x00", "\x00\x00", +- /* 0x20f8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20f90 */ "\x9a\xdf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20f9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12094,14 +11485,14 @@ static const char from_ucs4[][2] = + /* 0x20fa8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xfe", + /* 0x20fad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fb2 */ "\x00\x00", "\x8a\x58", "\x8b\xa3", "\x8b\xa7", "\x00\x00", +- /* 0x20fb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20fb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xe3", + /* 0x20fbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fc1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fc6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fcb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fd0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fd5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x20fda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x20fda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x61", + /* 0x20fdf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fe4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x20fea */ "\x9d\xd7", "\x9e\x7d", "\x9e\xa7", "\x9e\xab", "\x00\x00", +@@ -12112,7 +11503,7 @@ static const char from_ucs4[][2] = + /* 0x21002 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21007 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2100c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21011 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21011 */ "\x00\x00", "\x00\x00", "\x90\x42", "\x00\x00", "\x00\x00", + /* 0x21016 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2101b */ "\x00\x00", "\x8b\x79", "\x8b\x7a", "\x00\x00", "\x00\x00", + /* 0x21020 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12124,9 +11515,9 @@ static const char from_ucs4[][2] = + /* 0x2103e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21043 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21048 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2104d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2104d */ "\x00\x00", "\x9a\xe6", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21052 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21057 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21057 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xe5", + /* 0x2105c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21061 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21066 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12135,26 +11526,26 @@ static const char from_ucs4[][2] = + /* 0x21076 */ "\x9a\xe7", "\x8a\x7c", "\x8b\x71", "\x00\x00", "\x00\x00", + /* 0x2107b */ "\x9a\xe9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2107f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21084 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21084 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xea", "\x00\x00", + /* 0x21089 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2108e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21093 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21098 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21093 */ "\x00\x00", "\x00\x00", "\x9a\xeb", "\x00\x00", "\x00\x00", ++ /* 0x21098 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xbd", + /* 0x2109d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210b1 */ "\x00\x00", "\x00\x00", "\xfb\x4e", "\x00\x00", "\x00\x00", + /* 0x210b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x210bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xf9", ++ /* 0x210bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xed", "\x8a\xf9", + /* 0x210c1 */ "\x9e\x63", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210c5 */ "\x00\x00", "\x8b\x49", "\x8a\xce", "\x8b\x6e", "\x00\x00", +- /* 0x210ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x210cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x210ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xe8", ++ /* 0x210cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xee", "\x00\x00", + /* 0x210d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x210e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x210e4 */ "\x92\xce", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x210f2 */ "\x00\x00", "\x8a\x5a", "\x8b\x7b", "\x8b\x7c", "\x00\x00", +@@ -12169,13 +11560,13 @@ static const char from_ucs4[][2] = + /* 0x2111f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21124 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21129 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2112e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2112f */ "\x9a\xef", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21133 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21138 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xfa", ++ /* 0x21138 */ "\x00\x00", "\x00\x00", "\x9a\xf0", "\x00\x00", "\x8a\xfa", + /* 0x2113d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21142 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21142 */ "\x00\x00", "\x00\x00", "\x89\x41", "\x00\x00", "\x00\x00", + /* 0x21148 */ "\x8b\x72", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2114c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2114c */ "\x00\x00", "\x00\x00", "\x8a\xf3", "\x00\x00", "\x00\x00", + /* 0x21151 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21156 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2115b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12222,7 +11613,7 @@ static const char from_ucs4[][2] = + /* 0x21228 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2122d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21232 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21237 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21237 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\x73", + /* 0x2123c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21241 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21246 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12244,7 +11635,7 @@ static const char from_ucs4[][2] = + /* 0x21296 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2129b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x212a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x212a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xf6", "\x00\x00", ++ /* 0x212a5 */ "\x00\x00", "\x00\x00", "\x91\xfe", "\x9e\xf6", "\x00\x00", + /* 0x212aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x212b0 */ "\x97\xed", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x212b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12272,7 +11663,7 @@ static const char from_ucs4[][2] = + /* 0x21322 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21327 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2132c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21331 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21331 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xf5", + /* 0x21336 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x4b", "\x00\x00", + /* 0x2133b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21340 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12285,14 +11676,14 @@ static const char from_ucs4[][2] = + /* 0x21363 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21368 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2136d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21372 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21372 */ "\x00\x00", "\x00\x00", "\x9a\xf4", "\xfe\xde", "\x00\x00", + /* 0x21377 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2137c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21381 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21386 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2138b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2138b */ "\x00\x00", "\x00\x00", "\xfc\xb7", "\x00\x00", "\x00\x00", + /* 0x21390 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21395 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21395 */ "\x00\x00", "\x00\x00", "\x97\xf1", "\x00\x00", "\x00\x00", + /* 0x2139a */ "\x00\x00", "\x97\xc7", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2139f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x213a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12317,15 +11708,15 @@ static const char from_ucs4[][2] = + /* 0x21403 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21408 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2140d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21412 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21413 */ "\x97\x4e", "\x00\x00", "\x00\x00", "\xfb\x68", "\x00\x00", + /* 0x21417 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2141c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21421 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21421 */ "\x00\x00", "\x00\x00", "\x97\x6c", "\x00\x00", "\x00\x00", + /* 0x21426 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2142b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21430 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21435 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2143a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2143a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xc2", + /* 0x2143f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21444 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21449 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12340,7 +11731,7 @@ static const char from_ucs4[][2] = + /* 0x21476 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2147b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21480 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21485 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21485 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xe7", + /* 0x2148a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2148f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21494 */ "\x00\x00", "\x00\x00", "\xfd\xc8", "\x00\x00", "\x00\x00", +@@ -12364,259 +11755,363 @@ static const char from_ucs4[][2] = + /* 0x214ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x214f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x214f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xf3", ++ /* 0x214fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21502 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21507 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2150c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21511 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21516 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2151b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21520 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21525 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2152a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2152f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21534 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21539 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2153e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21543 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21548 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2154d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21552 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21557 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2155c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21561 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21566 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2156b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21570 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21575 */ "\x00\x00", "\x9a\xf7", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2157a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2157f */ "\x00\x00", "\x00\x00", "\x8f\xa6", "\x00\x00", "\x00\x00", ++ /* 0x21584 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21589 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2158e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21593 */ "\x00\x00", "\x00\x00", "\xfa\xd6", "\x00\x00", "\x00\x00", ++ /* 0x21598 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2159d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x215fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21601 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21606 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xc7", "\x00\x00", ++ /* 0x2160b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21610 */ "\x00\x00", "\x00\x00", "\xfa\xd7", "\x00\x00", "\x00\x00", ++ /* 0x21615 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xf8", "\x00\x00", ++ /* 0x2161a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2161f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21624 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21629 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2162e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21633 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21638 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2163e */ "\xfb\xa1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21642 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21647 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2164c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21651 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21656 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2165b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21661 */ "\x8e\xc5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21665 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2166a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2166f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21674 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21679 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2167e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21683 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21688 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2168d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xa4", ++ /* 0x21692 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21697 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2169c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216b5 */ "\x00\x00", "\x00\x00", "\xfb\xc2", "\x00\x00", "\x9a\xc1", ++ /* 0x216ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216c0 */ "\x91\xfa", "\xfe\xdb", "\x97\xab", "\x00\x00", "\x00\x00", ++ /* 0x216c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x47", ++ /* 0x216d3 */ "\x00\x00", "\xfb\xb1", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216dd */ "\x00\x00", "\x8f\xea", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xd2", "\xfe\x61", ++ /* 0x216e8 */ "\xfa\xce", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x216f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xed", "\x91\xf3", ++ /* 0x216fc */ "\x93\xc6", "\x00\x00", "\x93\x5a", "\x00\x00", "\x00\x00", ++ /* 0x21700 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21705 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2170a */ "\x00\x00", "\x00\x00", "\xfa\xfb", "\x00\x00", "\x00\x00", ++ /* 0x21710 */ "\x92\xef", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21714 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21719 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2171e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21723 */ "\x00\x00", "\x00\x00", "\xfa\xc8", "\x00\x00", "\x00\x00", ++ /* 0x21728 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2172d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21732 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21737 */ "\x00\x00", "\x00\x00", "\x98\x47", "\x93\x66", "\x98\x55", ++ /* 0x2173c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21741 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21746 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2174b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21750 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21755 */ "\x00\x00", "\x96\xe6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2175a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2175f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21764 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21769 */ "\x00\x00", "\x00\x00", "\x9f\x43", "\x9f\xaa", "\x94\xda", ++ /* 0x2176f */ "\x92\xee", "\xfc\xaf", "\xfb\xfb", "\x00\x00", "\x8e\xf9", ++ /* 0x21774 */ "\x91\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21778 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2177d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21782 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21787 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2178c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21791 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21796 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2179b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217ab */ "\x93\x64", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217b0 */ "\x94\xf5", "\x9c\xb6", "\xfb\xad", "\x98\x4e", "\x8f\x44", ++ /* 0x217b5 */ "\x96\xfd", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xf9", ++ /* 0x217c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9a\xfa", "\x00\x00", ++ /* 0x217c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217d7 */ "\x00\x00", "\x97\x69", "\x95\xd4", "\x98\x4b", "\xfb\xaa", ++ /* 0x217dc */ "\x00\x00", "\x00\x00", "\x98\x7c", "\x00\x00", "\x00\x00", ++ /* 0x217e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xea", "\x00\x00", ++ /* 0x217f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xaf", ++ /* 0x217f6 */ "\x9d\xc5", "\x00\x00", "\x91\xf1", "\x8e\xb1", "\x97\xa9", ++ /* 0x217fb */ "\xfb\xac", "\xfc\xb8", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x217ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21804 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21809 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2180e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21813 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21818 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2181d */ "\x00\x00", "\x00\x00", "\x9c\xb9", "\x00\x00", "\x00\x00", ++ /* 0x21822 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21828 */ "\xfb\xb0", "\xfc\xd2", "\x93\xcb", "\x00\x00", "\x00\x00", ++ /* 0x2182d */ "\x9a\xfd", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21831 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21836 */ "\x00\x00", "\x00\x00", "\x91\xf4", "\x8b\xac", "\xa0\x55", ++ /* 0x2183b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x74", ++ /* 0x21840 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xbe", ++ /* 0x21845 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2184a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2184f */ "\x00\x00", "\x00\x00", "\x97\xad", "\x00\x00", "\x00\x00", ++ /* 0x21854 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21859 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xe9", ++ /* 0x2185e */ "\x00\x00", "\x00\x00", "\x92\xf8", "\x97\xbe", "\x91\x6c", ++ /* 0x21864 */ "\x94\xaa", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21868 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2186d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21872 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x63", ++ /* 0x21877 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xc6", "\x00\x00", ++ /* 0x2187c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21881 */ "\x00\x00", "\x97\xb5", "\x92\xb8", "\x91\xef", "\x00\x00", ++ /* 0x21886 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2188b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21890 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21895 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2189a */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xa6", "\x97\x60", ++ /* 0x218a0 */ "\x93\x58", "\x95\x76", "\x8f\xac", "\x00\x00", "\x00\x00", ++ /* 0x218a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218be */ "\x91\xec", "\x97\xb4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xf7", ++ /* 0x218d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x4a", ++ /* 0x218d7 */ "\xfb\x49", "\x95\x78", "\x93\xbc", "\x00\x00", "\x00\x00", ++ /* 0x218db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218fa */ "\x91\xd6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x218fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x55", ++ /* 0x21904 */ "\x93\x56", "\x98\x51", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21908 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2190d */ "\x00\x00", "\x00\x00", "\x8f\xf8", "\xfb\xc0", "\x93\xf2", ++ /* 0x21912 */ "\x00\x00", "\x00\x00", "\x90\xd0", "\x00\x00", "\x00\x00", ++ /* 0x21917 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x44", ++ /* 0x2191c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21922 */ "\x92\x55", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21927 */ "\x93\x63", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2192b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21930 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21935 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2193b */ "\x91\xa5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2193f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xed", ++ /* 0x21944 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21949 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2194e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21953 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x6b", ++ /* 0x21958 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2195d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21962 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21967 */ "\x00\x00", "\x00\x00", "\x9a\xfe", "\x00\x00", "\x00\x00", ++ /* 0x2196c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21971 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21976 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2197c */ "\x93\x51", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x57", ++ /* 0x21980 */ "\x00\x00", "\x00\x00", "\xfa\x78", "\x00\x00", "\x00\x00", ++ /* 0x21985 */ "\x00\x00", "\x00\x00", "\xfe\xa8", "\x00\x00", "\x00\x00", ++ /* 0x2198a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2198f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21994 */ "\x00\x00", "\x93\x50", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21999 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2199e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219db */ "\xfa\x4c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xf7", ++ /* 0x219f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x219fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a2a */ "\x00\x00", "\x00\x00", "\x9b\x40", "\x00\x00", "\x00\x00", ++ /* 0x21a2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xce", ++ /* 0x21a34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a43 */ "\x00\x00", "\x9b\x41", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a48 */ "\x00\x00", "\x00\x00", "\xfe\xad", "\x00\x00", "\x00\x00", ++ /* 0x21a4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21a61 */ "\x00\x00", "\x87\x61", + +- /* 0x21596 */ "\xfa\xd6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2159a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2159f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x215fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21603 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21608 */ "\x00\x00", "\x9c\xc7", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2160d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21613 */ "\xfa\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21617 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2161c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21621 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21626 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2162b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21630 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21635 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2163a */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xa1", "\x00\x00", +- /* 0x2163f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21644 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21649 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2164e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21653 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21658 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2165d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xc5", "\x00\x00", +- /* 0x21662 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21667 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2166c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21671 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21676 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2167b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21680 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21685 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2168a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2168f */ "\x00\x00", "\x00\x00", "\xfb\xa4", "\x00\x00", "\x00\x00", +- /* 0x21694 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21699 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2169e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xfa", "\xfe\xdb", +- /* 0x216c2 */ "\x97\xab", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216d0 */ "\x00\x00", "\x00\x00", "\x91\x47", "\x00\x00", "\xfb\xb1", +- /* 0x216d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216e4 */ "\x00\x00", "\x94\xd2", "\xfe\x61", "\xfa\xce", "\x00\x00", +- /* 0x216e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x216f8 */ "\x00\x00", "\x92\xed", "\x91\xf3", "\x93\xc6", "\x00\x00", +- /* 0x216fe */ "\x93\x5a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21702 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21707 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2170c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xef", "\x00\x00", +- /* 0x21711 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21716 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2171b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21720 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21726 */ "\xfa\xc8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2172a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2172f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21734 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2173a */ "\x98\x47", "\x93\x66", "\x98\x55", "\x00\x00", "\x00\x00", +- /* 0x2173e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21743 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21748 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2174d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21752 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xe6", +- /* 0x21757 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2175c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21761 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21766 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2176c */ "\x9f\x43", "\x9f\xaa", "\x94\xda", "\x92\xee", "\xfc\xaf", +- /* 0x21771 */ "\xfb\xfb", "\x00\x00", "\x8e\xf9", "\x91\xf6", "\x00\x00", +- /* 0x21775 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2177a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2177f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21784 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21789 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2178e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21793 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21798 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2179d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xb6", +- /* 0x217b2 */ "\xfb\xad", "\x98\x4e", "\x8f\x44", "\x96\xfd", "\x00\x00", +- /* 0x217b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x69", +- /* 0x217da */ "\x95\xd4", "\x98\x4b", "\xfb\xaa", "\x00\x00", "\x00\x00", +- /* 0x217de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x217f2 */ "\x00\x00", "\x00\x00", "\x9d\xaf", "\x9d\xc5", "\x00\x00", +- /* 0x217f8 */ "\x91\xf1", "\x8e\xb1", "\x97\xa9", "\xfb\xac", "\xfc\xb8", +- /* 0x217fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21801 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21806 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2180b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21810 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21815 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2181a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2181f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21824 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xb0", "\xfc\xd2", +- /* 0x2182a */ "\x93\xcb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2182e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21833 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21838 */ "\x00\x00", "\x8b\xac", "\xa0\x55", "\x00\x00", "\x00\x00", +- /* 0x2183d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21842 */ "\x00\x00", "\x00\x00", "\x95\xbe", "\x00\x00", "\x00\x00", +- /* 0x21847 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2184c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21851 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21856 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2185b */ "\x00\x00", "\x00\x00", "\x8e\xe9", "\x00\x00", "\x00\x00", +- /* 0x21861 */ "\x92\xf8", "\x97\xbe", "\x91\x6c", "\x94\xaa", "\x00\x00", +- /* 0x21865 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2186a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2186f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21874 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21879 */ "\x00\x00", "\x9d\xc6", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2187e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xb5", +- /* 0x21884 */ "\x92\xb8", "\x91\xef", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21888 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2188d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21892 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21897 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2189c */ "\x00\x00", "\xfe\xa6", "\x97\x60", "\x93\x58", "\x95\x76", +- /* 0x218a2 */ "\x8f\xac", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xec", "\x97\xb4", +- /* 0x218bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218d3 */ "\x00\x00", "\x00\x00", "\x97\x4a", "\xfb\x49", "\x95\x78", +- /* 0x218d9 */ "\x93\xbc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x218f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xd6", "\x00\x00", +- /* 0x218fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21900 */ "\x00\x00", "\x00\x00", "\x93\x55", "\x93\x56", "\x98\x51", +- /* 0x21905 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2190a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21910 */ "\x8f\xf8", "\xfb\xc0", "\x93\xf2", "\x00\x00", "\x00\x00", +- /* 0x21915 */ "\x90\xd0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21919 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2191e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21923 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x63", "\x00\x00", +- /* 0x21928 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2192d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21932 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21937 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xa5", "\x00\x00", +- /* 0x2193c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21941 */ "\x00\x00", "\x00\x00", "\xa0\xed", "\x00\x00", "\x00\x00", +- /* 0x21946 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2194b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21950 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21955 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2195a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2195f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21964 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21969 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2196e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21973 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21978 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x51", "\x00\x00", +- /* 0x2197d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21982 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21988 */ "\xfe\xa8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2198c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21991 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x50", +- /* 0x21996 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2199b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x4c", "\x00\x00", +- /* 0x219dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219f0 */ "\x00\x00", "\x00\x00", "\x92\xf7", "\x00\x00", "\x00\x00", +- /* 0x219f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x219ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21a4b */ "\xfe\xad", +- +- /* 0x21b44 */ "\xfb\xd5", +- +- /* 0x21ca2 */ "\x9e\x79", "\x00\x00", "\x00\x00", "\xfb\xd9", ++ /* 0x21b44 */ "\xfb\xd5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21b9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ba2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ba7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bc1 */ "\x8b\xc2", "\x9a\x7c", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bcf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bde */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21be3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21be8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bf2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bf7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21bfc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c2a */ "\x9b\x42", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c70 */ "\x9b\x43", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21c9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ca2 */ "\x9e\x79", "\x00\x00", "\x00\x00", "\xfb\xd9", "\x00\x00", ++ /* 0x21ca6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21cac */ "\x9b\x44", + + /* 0x21d46 */ "\xa0\xa7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21d4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21d4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x7b", "\x00\x00", + /* 0x21d54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21d59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21d59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x6e", + /* 0x21d5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12626,7 +12121,7 @@ static const char from_ucs4[][2] = + /* 0x21d7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21d8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21d8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xf3", + /* 0x21d90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21d9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12634,7 +12129,7 @@ static const char from_ucs4[][2] = + /* 0x21da4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21da9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21dae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21db3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21db3 */ "\x00\x00", "\x00\x00", "\x8c\x79", "\x00\x00", "\x00\x00", + /* 0x21db8 */ "\x00\x00", "\x93\x5e", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21dbd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21dc2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12645,7 +12140,7 @@ static const char from_ucs4[][2] = + /* 0x21ddb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21de0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21de5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21dea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21deb */ "\x93\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21def */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21df4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xe1", + /* 0x21df9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12654,14 +12149,14 @@ static const char from_ucs4[][2] = + /* 0x21e08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21e17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21e17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xd0", + /* 0x21e1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21e21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21e21 */ "\x00\x00", "\x8c\xf1", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e35 */ "\x00\x00", "\xfb\xe2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21e3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21e3a */ "\x00\x00", "\x00\x00", "\xfc\xe3", "\x00\x00", "\x00\x00", + /* 0x21e3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21e49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -12689,101 +12184,196 @@ static const char from_ucs4[][2] = + /* 0x21eb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21ebc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21ec1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21ec6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ec6 */ "\x00\x00", "\x9b\x45", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21ecb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x21ed0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x47", +- +- /* 0x21f6a */ "\xfc\x5b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21f9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x21fa1 */ "\x9c\xfd", +- +- /* 0x22049 */ "\xfb\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2204d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22052 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22057 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2205c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22061 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22066 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2206b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22070 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22075 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2207a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2207f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22084 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22089 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2208e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22093 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22098 */ "\x00\x00", "\x9b\xa8", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2209d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220c5 */ "\x00\x00", "\x8a\xd5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x220f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x73", +- /* 0x220fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22101 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22106 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2210b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22110 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22115 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2211a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2211f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22124 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2212a */ "\xfd\x59", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2212e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22133 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22138 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2213d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22142 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22147 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2214c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22151 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22156 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2215b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22160 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22165 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2216a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2216f */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xed", "\x00\x00", +- /* 0x22174 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2217a */ "\x9c\xa9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2217e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22183 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22188 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2218d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22192 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22197 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2219c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xa8", +- /* 0x221a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x221a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x221ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x221b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x221b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x221ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x221bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xc3", +- +- /* 0x2227c */ "\x9b\x4e", ++ /* 0x21ed5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21eda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21edf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ee4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ee9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21eee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ef3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ef8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21efd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f0c */ "\x00\x00", "\x00\x00", "\x9f\x50", "\x00\x00", "\x00\x00", ++ /* 0x21f11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x48", "\x00\x00", ++ /* 0x21f16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x5b", "\x00\x00", ++ /* 0x21f6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21f9e */ "\x98\xa9", "\x00\x00", "\x00\x00", "\x9c\xfd", "\x00\x00", ++ /* 0x21fa2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fa7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fcf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fde */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fe3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x88\x4c", ++ /* 0x21fe8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21fed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ff2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ff7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x21ffc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22001 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22006 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2200b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22010 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22015 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2201a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2201f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22024 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22029 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2202e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22033 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22038 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2203d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22042 */ "\x00\x00", "\x00\x00", "\x9b\x4b", "\x00\x00", "\x00\x00", ++ /* 0x22047 */ "\x00\x00", "\xfb\xec", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2204c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22051 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22056 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2205b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22060 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22065 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2206a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2206f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22074 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22079 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x69", ++ /* 0x2207e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22083 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22088 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2208d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22092 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22097 */ "\x00\x00", "\x00\x00", "\x9b\xa8", "\x00\x00", "\x00\x00", ++ /* 0x2209c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220c4 */ "\x00\x00", "\x00\x00", "\x8a\xd5", "\x00\x00", "\x00\x00", ++ /* 0x220c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x220fc */ "\xfa\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22100 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22105 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2210a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2210f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22114 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22119 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2211e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22123 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22128 */ "\x00\x00", "\xfd\x59", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2212d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22132 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22137 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2213c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22141 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22146 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2214b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22150 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22155 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2215b */ "\x91\xa2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2215f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22164 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22169 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2216e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xed", ++ /* 0x22173 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22178 */ "\x00\x00", "\x9c\xa9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2217d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22182 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22187 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2218c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22191 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22196 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2219b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221a1 */ "\x8a\xa8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221be */ "\x00\x00", "\x00\x00", "\x8d\x42", "\x00\x00", "\x9b\xc3", ++ /* 0x221c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x221ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22204 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xe1", "\x00\x00", ++ /* 0x22209 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2220e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22213 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22218 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2221d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22222 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22227 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2222c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22231 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22236 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2223b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22240 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22245 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2224a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2224f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22254 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22259 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2225e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22263 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22268 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2226d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22272 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22277 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x4e", + + /* 0x22321 */ "\x95\xd0", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x5f", + +@@ -12791,257 +12381,336 @@ static const char from_ucs4[][2] = + /* 0x223c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x223c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x223cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x4e", ++ /* 0x223d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223d5 */ "\x00\x00", "\x9b\x4f", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223f8 */ "\x00\x00", "\x9b\x50", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x223fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22402 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22407 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2240c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22411 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22416 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2241b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22420 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22425 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2242a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2242f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22434 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22439 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2243e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22443 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22448 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2244d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22452 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22457 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2245c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22461 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xc6", "\x00\x00", ++ /* 0x22466 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2246b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22471 */ "\xfc\x50", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22475 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2247a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2247f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22484 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22489 */ "\x00\x00", "\xfd\x73", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2248e */ "\x00\x00", "\x00\x00", "\xfd\xa7", "\x00\x00", "\x00\x00", ++ /* 0x22493 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22498 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2249d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xa2", "\x00\x00", ++ /* 0x224b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224bc */ "\x87\xd1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224c1 */ "\x87\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xd4", "\x00\x00", ++ /* 0x224ca */ "\x00\x00", "\x87\xd5", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x58", ++ /* 0x224ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x224fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22501 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22506 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2250b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22510 */ "\x00\x00", "\x00\x00", "\xfa\x5e", "\x00\x00", "\x00\x00", ++ /* 0x22515 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2251b */ "\xa0\x59", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2251f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22524 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22529 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2252e */ "\x00\x00", "\xfa\x75", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22533 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22538 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2253d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22542 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22547 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2254c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22551 */ "\x00\x00", "\x00\x00", "\xfb\xbe", "\x00\x00", "\x00\x00", ++ /* 0x22556 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2255b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22560 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22565 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2256a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2256f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22574 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22579 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2257e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22583 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22588 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xa2", ++ /* 0x2258d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22592 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22597 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2259c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x70", "\x00\x00", ++ /* 0x225b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x71", "\x00\x00", ++ /* 0x225bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x225fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22600 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22605 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2260a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2260f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22614 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22619 */ "\x00\x00", "\x93\x77", "\xfe\xef", "\x00\x00", "\x00\x00", ++ /* 0x2261e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22623 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22628 */ "\x00\x00", "\x00\x00", "\x93\x6d", "\x00\x00", "\x00\x00", ++ /* 0x2262d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22632 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22637 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2263c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22641 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22646 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2264b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22650 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22655 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2265a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2265f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22664 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x5d", "\x00\x00", ++ /* 0x22669 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2266e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22673 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22678 */ "\x00\x00", "\x90\xb8", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2267d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22682 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22687 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2268c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22691 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xfc", ++ /* 0x22696 */ "\x00\x00", "\xfb\x41", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2269b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x6b", "\x94\xe3", ++ /* 0x226f6 */ "\x8e\xe2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x226ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22704 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22709 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2270e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x7d", "\x00\x00", ++ /* 0x22714 */ "\x8e\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22718 */ "\x00\x00", "\x00\x00", "\x9c\x4d", "\x00\x00", "\x00\x00", ++ /* 0x2271d */ "\x00\x00", "\x96\xa3", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22722 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22727 */ "\x00\x00", "\x00\x00", "\x9b\x51", "\x00\x00", "\x00\x00", ++ /* 0x2272c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22731 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22736 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2273b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22740 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22745 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2274a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2274f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22754 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22759 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2275e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22763 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22768 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2276d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22772 */ "\x00\x00", "\x00\x00", "\x8a\xc3", "\x00\x00", "\x00\x00", ++ /* 0x22777 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2277c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xaa", ++ /* 0x22781 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22786 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2278b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22790 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22796 */ "\x8c\xe2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2279a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2279f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227b4 */ "\xfc\x68", "\x8b\x6d", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227cd */ "\xfd\x67", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x227fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xe9", ++ /* 0x22803 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22808 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2280d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22812 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22817 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2281c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22821 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22826 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2282b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22830 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22835 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2283a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2283f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22844 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22849 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2284e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22853 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22858 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2285d */ "\x00\x00", "\xfc\xa1", "\x93\x6c", "\x00\x00", "\x00\x00", ++ /* 0x22862 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22867 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2286c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x52", ++ /* 0x22871 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22876 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2287b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22880 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22885 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2288a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2288f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22894 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22899 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2289e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x70", ++ /* 0x228ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xa8", ++ /* 0x228c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xe9", "\x00\x00", ++ /* 0x228f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x228fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22902 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22907 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2290c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22911 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22916 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2291b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22920 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22926 */ "\x9c\xb4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2292a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2292f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22934 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xea", ++ /* 0x22939 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2293e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22943 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22948 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2294d */ "\x00\x00", "\x9b\x53", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22952 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22957 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2295c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22961 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22967 */ "\x9b\x55", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xab", ++ /* 0x2296b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22970 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22975 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2297a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22980 */ "\xfc\xa7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22984 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22989 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2298e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x56", + +- /* 0x22465 */ "\x9e\xc6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22469 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2246e */ "\x00\x00", "\x00\x00", "\xfc\x50", "\x00\x00", "\x00\x00", +- /* 0x22473 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22478 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2247d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22482 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22487 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x73", +- +- /* 0x22513 */ "\xfa\x5e", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22517 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\x59", "\x00\x00", +- /* 0x2251c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22521 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22526 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2252b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x75", +- /* 0x22530 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22535 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2253a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2253f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22544 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22549 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2254e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22553 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22558 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2255d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22562 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22567 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2256c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22571 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22576 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2257b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22580 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22585 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2258a */ "\x00\x00", "\x00\x00", "\x9c\xa2", "\x00\x00", "\x00\x00", +- /* 0x2258f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22594 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22599 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2259e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225ad */ "\x00\x00", "\x93\x70", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225bc */ "\x00\x00", "\x93\x71", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x225fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22602 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22607 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2260c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22611 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22616 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x77", +- /* 0x2261c */ "\xfe\xef", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22620 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22625 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2262b */ "\x93\x6d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2262f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22634 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22639 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2263e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22643 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22648 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2264d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22652 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22657 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2265c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22661 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22666 */ "\x00\x00", "\xfc\x5d", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2266b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22670 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22675 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2267a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2267f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22684 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22689 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2268e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22693 */ "\x00\x00", "\x00\x00", "\x8a\xfc", "\x00\x00", "\xfb\x41", +- /* 0x22698 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2269d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226f2 */ "\x00\x00", "\x9e\x6b", "\x94\xe3", "\x8e\xe2", "\x00\x00", +- /* 0x226f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x226fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22701 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22706 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2270b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22710 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22715 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2271b */ "\x9c\x4d", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xa3", +- /* 0x2271f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22724 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22729 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2272e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22733 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22738 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2273d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22742 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22747 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2274c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22751 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22756 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2275b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22760 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22765 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2276a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2276f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22775 */ "\x8a\xc3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22779 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2277e */ "\x00\x00", "\x00\x00", "\x96\xaa", "\x00\x00", "\x00\x00", +- /* 0x22783 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22788 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2278d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22792 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22797 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2279c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x68", "\x8b\x6d", +- /* 0x227b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x227fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22800 */ "\x00\x00", "\x00\x00", "\x8a\xe9", "\x00\x00", "\x00\x00", +- /* 0x22805 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2280a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2280f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22814 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22819 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2281e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22823 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22828 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2282d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22832 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22837 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2283c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22841 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22846 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2284b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22850 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22855 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2285a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xa1", +- /* 0x22860 */ "\x93\x6c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22864 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22869 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2286e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22873 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22878 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2287d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22882 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22887 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2288c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22891 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22896 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2289b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228aa */ "\x00\x00", "\x00\x00", "\xfe\x70", "\x00\x00", "\x00\x00", +- /* 0x228af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228be */ "\x00\x00", "\x00\x00", "\xfc\xa8", "\x00\x00", "\x00\x00", +- /* 0x228c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228f5 */ "\x00\x00", "\xfc\xe9", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x228ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22904 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22909 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2290e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22913 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22918 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2291d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22922 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22927 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2292c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22931 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22936 */ "\x00\x00", "\x00\x00", "\x8a\xea", "\x00\x00", "\x00\x00", +- /* 0x2293b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22940 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22945 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2294a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2294f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22954 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22959 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2295e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22963 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22968 */ "\x00\x00", "\x00\x00", "\x96\xab", "\x00\x00", "\x00\x00", +- /* 0x2296d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22972 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22977 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2297c */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xa7", +- ++ /* 0x22a66 */ "\x8a\xbc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22a9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22aa1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22aa6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22aab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ab0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ab5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22aba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22abf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ac4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ac9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22acf */ "\x8a\xcb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22ad3 */ "\x00\x00", "\x9b\x57", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22ad8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22add */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22ae2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22ae7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ae2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x89\xcd", "\x00\x00", ++ /* 0x22ae8 */ "\x9b\x59", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22aec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22af1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22af6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22afb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22b0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22b0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x5b", "\x00\x00", + /* 0x22b0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13051,8 +12720,8 @@ static const char from_ucs4[][2] = + /* 0x22b2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22b3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22b41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22b3c */ "\x00\x00", "\x00\x00", "\x9b\x5d", "\x00\x00", "\x00\x00", ++ /* 0x22b41 */ "\x00\x00", "\x9e\x4f", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22b50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13079,7 +12748,7 @@ static const char from_ucs4[][2] = + /* 0x22bb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22bbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22bc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22bc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22bc8 */ "\x00\x00", "\x8a\x7b", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22bce */ "\x8b\x42", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22bd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22bd7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13101,15 +12770,15 @@ static const char from_ucs4[][2] = + /* 0x22c27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22c36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22c36 */ "\x00\x00", "\x8a\x50", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22c4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22c4a */ "\x00\x00", "\x9b\x60", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c4f */ "\x00\x00", "\x8b\x45", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c55 */ "\x8b\x46", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22c5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22c5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xfe", "\x00\x00", + /* 0x22c63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13117,20 +12786,20 @@ static const char from_ucs4[][2] = + /* 0x22c77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22c86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22c86 */ "\x00\x00", "\x9b\x62", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c9b */ "\x93\x7b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22c9f */ "\x00\x00", "\x93\xb1", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22ca4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ca4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x60", + /* 0x22ca9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22cae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22cb3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22cae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xd8", "\x00\x00", ++ /* 0x22cb3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x63", "\x00\x00", + /* 0x22cb8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22cbd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22cbd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x69", + /* 0x22cc2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x47", "\x00\x00", +- /* 0x22cc7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22cc7 */ "\x00\x00", "\x8a\xcc", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22ccc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22cd1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22cd6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13144,7 +12813,7 @@ static const char from_ucs4[][2] = + /* 0x22cfe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x7c", "\x9b\x65", + /* 0x22d08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22d0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22d0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x66", + /* 0x22d12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13154,9 +12823,9 @@ static const char from_ucs4[][2] = + /* 0x22d30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22d3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22d3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x72", + /* 0x22d44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22d49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22d49 */ "\x00\x00", "\x00\x00", "\x8a\x7a", "\x00\x00", "\x00\x00", + /* 0x22d4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13169,15 +12838,15 @@ static const char from_ucs4[][2] = + /* 0x22d7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22d8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22d8a */ "\x00\x00", "\x00\x00", "\x8a\xb0", "\x00\x00", "\x00\x00", + /* 0x22d8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22d94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22d95 */ "\x9b\x68", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22d9e */ "\x00\x00", "\x9e\xa3", "\x00\x00", "\x00\x00", "\xfa\xec", + /* 0x22da4 */ "\x8b\x77", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22da8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22dad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22db2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22db2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x67", + /* 0x22db7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22dbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22dc1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13188,7 +12857,7 @@ static const char from_ucs4[][2] = + /* 0x22dda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22ddf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22de4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22de9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22de9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x59", + /* 0x22dee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22df3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22df8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13205,7 +12874,7 @@ static const char from_ucs4[][2] = + /* 0x22e2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22e34 */ "\x00\x00", "\xfc\xbb", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22e39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22e3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x69", "\x00\x00", + /* 0x22e43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22e48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22e4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13216,186 +12885,236 @@ static const char from_ucs4[][2] = + /* 0x22e66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22e6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x22e70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22e75 */ "\x00\x00", "\x00\x00", "\x93\xa8", ++ /* 0x22e75 */ "\x00\x00", "\x00\x00", "\x93\xa8", "\x00\x00", "\x00\x00", ++ /* 0x22e7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e89 */ "\x00\x00", "\x8a\xe0", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22e9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ea2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ea7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22eac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22eb1 */ "\x00\x00", "\x9e\x51", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22eb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ebb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ec0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ec5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22eca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ecf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ed4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ed9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ede */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ee3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ee8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22eed */ "\x00\x00", "\x8f\x5f", + +- /* 0x22fe3 */ "\x97\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22fe7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22fec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22ff1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22ff6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x22ffb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23000 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23005 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2300a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2300f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23014 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23019 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2301e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23023 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23028 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2302d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23032 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23037 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2303c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23041 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23046 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xc2", +- /* 0x2304b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23050 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23055 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2305a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2305f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23064 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23069 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2306e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23073 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23078 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x67", +- /* 0x2307e */ "\xfc\xcc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23082 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23087 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2308c */ "\x00\x00", "\x93\xb6", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23091 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23096 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2309b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230b4 */ "\x00\x00", "\x00\x00", "\x90\xe4", "\x00\x00", "\x00\x00", +- /* 0x230b9 */ "\x00\x00", "\x00\x00", "\x90\xe5", "\x00\x00", "\x00\x00", +- /* 0x230be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230d7 */ "\x00\x00", "\x00\x00", "\x9e\xf2", "\x00\x00", "\x00\x00", +- /* 0x230dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x230ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xca", "\x00\x00", +- /* 0x23104 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23109 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2310e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23113 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23118 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2311d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23122 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23127 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2312c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23131 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23136 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2313b */ "\x00\x00", "\x8b\xbc", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23140 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23145 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2314a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2314f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23154 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23159 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2315e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23163 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23168 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2316d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23172 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23177 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2317c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23182 */ "\x93\xcf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23186 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2318b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23190 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23195 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2319a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2319f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xdb", +- /* 0x231a5 */ "\xfc\xdc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231c8 */ "\xfc\xe6", "\x96\xe7", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231f4 */ "\x00\x00", "\x00\x00", "\xfc\xd8", "\xfc\xd9", "\xfd\xa6", +- /* 0x231f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x231fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23203 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23208 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2320d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23212 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23217 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2321c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23221 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xf1", "\x00\x00", +- /* 0x23226 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2322b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xe9", "\x00\x00", +- /* 0x23231 */ "\xfc\xe4", "\x94\xaf", "\xfa\x77", "\x93\xcc", "\x00\x00", +- /* 0x23235 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2323a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2323f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23244 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23249 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2324e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23253 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23258 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2325d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x5a", +- /* 0x23262 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23267 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2326c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23271 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23276 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2327b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23280 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23285 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xbf", "\xfb\x51", +- /* 0x2328a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2328f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23294 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23299 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2329e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232a8 */ "\x00\x00", "\x00\x00", "\x93\xb9", "\xfe\xd7", "\x93\xb7", +- /* 0x232ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232d0 */ "\x00\x00", "\x93\xd9", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232e0 */ "\x93\xbb", "\x93\xda", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x232fd */ "\x00\x00", "\x00\x00", "\x98\xa3", "\x00\x00", "\x00\x00", +- /* 0x23302 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23307 */ "\x00\x00", "\x00\x00", "\x90\xd1", ++ /* 0x22f74 */ "\x9b\x6a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22f9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fa0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fa5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22faa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22faf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fb4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x6b", "\x00\x00", ++ /* 0x22fcd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fd7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fdc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fe1 */ "\x00\x00", "\x97\xec", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fe6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22feb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ff0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ff5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22ffa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x22fff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23004 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23009 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2300e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23013 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23018 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2301d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23022 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23027 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2302c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23031 */ "\x00\x00", "\x9b\x6c", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23036 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2303b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23040 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x4e", "\x00\x00", ++ /* 0x23045 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2304b */ "\xfd\xc2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2304f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23054 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23059 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2305e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23063 */ "\x00\x00", "\x00\x00", "\x9b\x6d", "\x00\x00", "\x00\x00", ++ /* 0x23068 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2306d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23072 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23077 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2307d */ "\x91\x67", "\xfc\xcc", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23081 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23086 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2308b */ "\x00\x00", "\x00\x00", "\x93\xb6", "\x00\x00", "\x00\x00", ++ /* 0x23090 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23095 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2309a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2309f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xe4", "\x00\x00", ++ /* 0x230b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xe5", "\x00\x00", ++ /* 0x230bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xf2", "\x00\x00", ++ /* 0x230db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x230fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xca", ++ /* 0x23103 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23108 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2310d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23112 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23117 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2311c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23121 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23126 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2312b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23130 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23135 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2313a */ "\x00\x00", "\x00\x00", "\x8b\xbc", "\x00\x00", "\x00\x00", ++ /* 0x2313f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23144 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23149 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2314e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23153 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23158 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2315d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23162 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23167 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2316c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23171 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23176 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2317b */ "\x00\x00", "\x8f\x46", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23180 */ "\x00\x00", "\x93\xcf", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23185 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2318a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2318f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23194 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23199 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2319e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231a4 */ "\xfc\xdb", "\xfc\xdc", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231b3 */ "\x93\xc0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231c6 */ "\x00\x00", "\xfc\xe6", "\x96\xe7", "\x00\x00", "\x00\x00", ++ /* 0x231cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231ea */ "\x87\xa7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xd8", "\xfc\xd9", ++ /* 0x231f9 */ "\xfd\xa6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x231fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23202 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23207 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2320c */ "\x00\x00", "\x00\x00", "\x93\xce", "\x00\x00", "\x00\x00", ++ /* 0x23211 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23216 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2321b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23220 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xf1", ++ /* 0x23225 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2322a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xe9", ++ /* 0x2322f */ "\x00\x00", "\xfc\xe4", "\x94\xaf", "\xfa\x77", "\x93\xcc", ++ /* 0x23234 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23239 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2323e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23243 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23248 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2324d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23252 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xe1", "\x00\x00", ++ /* 0x23257 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2325c */ "\x00\x00", "\x87\xa9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23262 */ "\x90\x5a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23266 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2326b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23270 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23275 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2327a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2327f */ "\x00\x00", "\x8c\x54", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23284 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xbf", ++ /* 0x2328a */ "\xfb\x51", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2328e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23293 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23298 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2329d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xb9", "\xfe\xd7", ++ /* 0x232ad */ "\x93\xb7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232cf */ "\x00\x00", "\x00\x00", "\x93\xd9", "\x00\x00", "\x00\x00", ++ /* 0x232d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232de */ "\x00\x00", "\x93\xbb", "\x93\xda", "\x00\x00", "\x00\x00", ++ /* 0x232e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x232fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xa3", "\x00\x00", ++ /* 0x23301 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23306 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xd1", "\x00\x00", ++ /* 0x2330b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23310 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23315 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2331a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\x6e", + + /* 0x233b4 */ "\xfa\x70", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x233c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x233c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xeb", + /* 0x233cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x233db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x233db */ "\x00\x00", "\x00\x00", "\x9b\x6f", "\x00\x00", "\x00\x00", + /* 0x233e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233e6 */ "\xfc\xfc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x233ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x40", +- /* 0x233f5 */ "\xa0\x7b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x233f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xe2", ++ /* 0x233f5 */ "\xa0\x7b", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xa1", ++ /* 0x233fa */ "\x97\xf7", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xe2", + /* 0x233fe */ "\x00\x00", "\xfc\xd6", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23403 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23408 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13408,7 +13127,7 @@ static const char from_ucs4[][2] = + /* 0x2342b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23430 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23435 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2343a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2343a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x59", + /* 0x2343f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23444 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23449 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13418,7 +13137,7 @@ static const char from_ucs4[][2] = + /* 0x2345d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23462 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23467 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2346c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2346c */ "\x00\x00", "\x00\x00", "\xfd\x40", "\x00\x00", "\x00\x00", + /* 0x23472 */ "\x93\x5f", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23476 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2347b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13452,7 +13171,7 @@ static const char from_ucs4[][2] = + /* 0x23507 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2350c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23511 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23516 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23516 */ "\x00\x00", "\x00\x00", "\x9c\x76", "\x00\x00", "\x00\x00", + /* 0x2351b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23520 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23525 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13463,12 +13182,12 @@ static const char from_ucs4[][2] = + /* 0x2353e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23543 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23548 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2354d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2354d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xeb", "\x00\x00", + /* 0x23552 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23557 */ "\x00\x00", "\x00\x00", "\x8f\x47", "\x00\x00", "\x00\x00", + /* 0x2355c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23561 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23566 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23567 */ "\x9b\x74", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2356b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23570 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23575 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13484,7 +13203,7 @@ static const char from_ucs4[][2] = + /* 0x235a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x235b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x235b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xd8", + /* 0x235bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13496,14 +13215,14 @@ static const char from_ucs4[][2] = + /* 0x235e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x235f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x235f3 */ "\x9b\x75", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x235fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x5c", "\x00\x00", + /* 0x23601 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23606 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2360b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23610 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23615 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23615 */ "\x00\x00", "\x87\x51", "\x00\x00", "\x00\x00", "\x9b\x79", + /* 0x2361a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2361f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23624 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13516,8 +13235,8 @@ static const char from_ucs4[][2] = + /* 0x23647 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2364c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23651 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23656 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2365b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23656 */ "\x00\x00", "\x00\x00", "\xfd\x58", "\x00\x00", "\x00\x00", ++ /* 0x2365b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x5f", "\x00\x00", + /* 0x23660 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23665 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2366a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13527,10 +13246,10 @@ static const char from_ucs4[][2] = + /* 0x2367e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23683 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23688 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2368d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2368e */ "\x87\xc7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23692 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23697 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2369c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2369c */ "\x00\x00", "\x87\x7c", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x236a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x43", + /* 0x236a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x236ab */ "\x00\x00", "\x97\xfa", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13550,15 +13269,15 @@ static const char from_ucs4[][2] = + /* 0x236f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x236f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x236fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23700 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23700 */ "\x00\x00", "\x00\x00", "\xfd\x5b", "\x00\x00", "\x00\x00", + /* 0x23705 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2370a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2370f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23714 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23714 */ "\x00\x00", "\x9b\x7a", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23719 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2371e */ "\x00\x00", "\x9e\xd5", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23723 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23728 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23728 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\xae", + /* 0x2372d */ "\x00\x00", "\x9c\xc9", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23732 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x23737 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -13593,667 +13312,837 @@ static const char from_ucs4[][2] = + /* 0x237c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x237cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x237d2 */ "\x00\x00", "\x00\x00", "\x93\xec", "\x97\xf6", "\x96\xcf", ++ /* 0x237d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x237ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23804 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23809 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2380e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23813 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23818 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2381d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23822 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23827 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2382c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23831 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23836 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xde", + +- /* 0x23adb */ "\xfd\x69", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23adf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ae4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ae9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x52", +- /* 0x23aee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23af3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23af8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23afd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23b57 */ "\x00\x00", "\x00\x00", "\xfd\x6e", +- +- /* 0x23c99 */ "\xfa\x7c", "\x93\xfa", "\x90\x7c", "\x00\x00", "\x00\x00", +- /* 0x23c9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ca2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ca7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cb7 */ "\x9d\xb7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cc5 */ "\x00\x00", "\xa0\xe9", "\xfa\x4e", "\xfd\xa1", "\x00\x00", +- /* 0x23cca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ccf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cde */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ce3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ce8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ced */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cf2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23cf7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x74", +- /* 0x23cfd */ "\x9f\xbf", "\x9e\xcb", "\x9b\xb9", "\x00\x00", "\x00\x00", +- /* 0x23d01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xb9", +- /* 0x23d5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23d9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23da1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23da6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23db0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23db6 */ "\x9e\xd2", "\x97\x53", "\x96\xa4", "\x8f\xbe", "\x94\xd9", +- /* 0x23dbb */ "\x90\x58", "\xfd\x79", "\xfd\x7b", "\x00\x00", "\x00\x00", +- /* 0x23dbf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dc4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dc9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ddd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23de2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23de7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23df1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23df6 */ "\x00\x00", "\x8e\xfa", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23dfb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xd9", "\x97\xd4", +- /* 0x23e2e */ "\x90\xbb", "\xfd\xbc", "\xfd\xc6", "\x92\x48", "\x00\x00", +- /* 0x23e32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e88 */ "\x9d\xc1", "\x92\xb9", "\x92\xa6", "\x8f\x4b", "\x00\x00", +- /* 0x23e8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23e9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ea0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ea5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23eaa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23eaf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23eb4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23eb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ebf */ "\x92\xb6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ec3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ec8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ecd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ed2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ed7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23edc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ee1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ee6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23eeb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ef0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ef5 */ "\x00\x00", "\x9e\xd8", "\x94\x5e", "\x98\x5f", "\x94\xce", +- /* 0x23efb */ "\x92\x4a", "\xfd\x70", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23eff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x67", "\x00\x00", +- /* 0x23f36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f41 */ "\x8d\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f7c */ "\x00\x00", "\x00\x00", "\x94\x48", "\xfa\xc1", "\x9c\xf7", +- /* 0x23f82 */ "\xfd\xbe", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23f9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fa4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fa9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fb3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x7e", "\x00\x00", +- /* 0x23fb8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fbd */ "\x00\x00", "\x00\x00", "\x93\xf9", "\x00\x00", "\x00\x00", +- /* 0x23fc2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fc7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fcc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fd1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fd6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fdb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fe0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23fe5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23feb */ "\xfa\xeb", "\xfa\xc3", "\x97\xd3", "\x95\xf9", "\x9c\x48", +- /* 0x23ff0 */ "\x8e\x6a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ff4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ff9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x23ffe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24003 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24008 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2400d */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xd8", "\x00\x00", +- /* 0x24012 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24017 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2401c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24021 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24026 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2402b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24030 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24035 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xd7", "\xfb\x4a", +- /* 0x2403b */ "\x9b\xaf", "\x94\x4b", "\xfd\xc9", "\x00\x00", "\x00\x00", +- /* 0x2403f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24044 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24049 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2404e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24053 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xac", "\x00\x00", +- /* 0x24058 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2405d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24062 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24067 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2406c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24071 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24076 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2407b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24080 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24085 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2408b */ "\x92\x5a", "\xfc\xbd", "\x92\xd9", "\x00\x00", "\x00\x00", +- /* 0x2408f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24094 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24099 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2409e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240c6 */ "\x00\x00", "\x00\x00", "\x92\xdd", "\x00\x00", "\x00\x00", +- /* 0x240cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x240fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24102 */ "\x00\x00", "\x96\xba", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24107 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2410c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24111 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24116 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2411b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24120 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24125 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2412a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2412f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24134 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24139 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2413f */ "\xfd\xda", "\xfd\xde", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24144 */ "\xfd\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24148 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2414d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24152 */ "\x00\x00", "\x00\x00", "\xfd\xd6", "\xfd\xdc", "\xfd\xdd", +- /* 0x24157 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xfe", +- /* 0x2415c */ "\x00\x00", "\x00\x00", "\xfe\xa1", "\x00\x00", "\x00\x00", +- /* 0x24161 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24166 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2416b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24170 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24175 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xd8", +- /* 0x2417a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2417f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24184 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24189 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2418e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24193 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24198 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2419d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241a3 */ "\x9e\x6d", "\xfd\x7c", "\xfb\x61", "\x00\x00", "\x00\x00", +- /* 0x241a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241de */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x60", "\x00\x00", +- /* 0x241e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x241f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x52", +- /* 0x241fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24201 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24206 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2420b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24210 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24215 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2421b */ "\x96\x4f", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2421f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24224 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24229 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2422e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24233 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24238 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2423d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24242 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24247 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x6e", "\x00\x00", +- /* 0x2424c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24251 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x6d", +- /* 0x24256 */ "\x00\x00", "\x00\x00", "\x98\x64", "\x00\x00", "\x00\x00", +- /* 0x2425b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24260 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24265 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2426a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2426f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24274 */ "\x00\x00", "\x94\x53", "\xfd\xec", "\xfb\x78", "\x00\x00", +- /* 0x24279 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2427e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24283 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24288 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2428d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24292 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24297 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2429c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x5a", "\x00\x00", +- /* 0x242a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xd0", +- /* 0x242ca */ "\x98\x62", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x242f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x4f", "\x00\x00", +- /* 0x242fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24300 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24305 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2430a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2430f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24314 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2431a */ "\x94\x52", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2431e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24323 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24328 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2432d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24332 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24337 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2433c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24341 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24346 */ "\x00\x00", "\x91\xd2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2434b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24350 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24355 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2435a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2435f */ "\x00\x00", "\x00\x00", "\x97\xea", "\xfb\x6b", "\x91\xb1", +- /* 0x24365 */ "\xfd\xf3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24369 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2436e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24373 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24378 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2437d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24382 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24387 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xcb", +- /* 0x2438c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24391 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xb1", +- /* 0x24396 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2439c */ "\xfc\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x6b", "\x00\x00", +- /* 0x243be */ "\x00\x00", "\x00\x00", "\x97\x51", "\x00\x00", "\x00\x00", +- /* 0x243c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243e6 */ "\x00\x00", "\x00\x00", "\x98\x71", "\x00\x00", "\x00\x00", +- /* 0x243eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243f0 */ "\x00\x00", "\x9e\xf3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243f5 */ "\x00\x00", "\x00\x00", "\x91\xe8", "\x00\x00", "\x00\x00", +- /* 0x243fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x243ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24404 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24409 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2440e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24413 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24418 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2441d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24422 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24427 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2442c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24431 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\x4c", "\x92\x6a", +- /* 0x24436 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2443b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24440 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24445 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2444a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2444f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24454 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2445a */ "\xfd\xf8", "\x98\x61", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2445e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24463 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24468 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2446d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24472 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24477 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2447c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24481 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24487 */ "\x93\xed", "\x97\x44", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2448b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24490 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24495 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2449a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2449f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244b9 */ "\x91\xe1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244cc */ "\x00\x00", "\x98\x69", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244d1 */ "\x00\x00", "\x8a\x62", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x244fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24503 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24508 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2450d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24512 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24517 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2451c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x55", +- /* 0x24521 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24526 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2452b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24530 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24535 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2453a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2453f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24544 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24549 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2454e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24553 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24558 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2455d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24562 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24567 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2456c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24571 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24576 */ "\x00\x00", "\x8e\x77", ++ /* 0x239c2 */ "\x8a\xcf", + +- /* 0x2462a */ "\x93\xe6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2462e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24633 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24638 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2463d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24642 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24647 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2464c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24651 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24656 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2465b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24660 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xa2", +- /* 0x24665 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2466a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2466f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24674 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24679 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2467e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24683 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24688 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2468d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24692 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xb3", +- /* 0x24697 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2469c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246d4 */ "\x93\x7d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x246fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24700 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24706 */ "\x9e\x66", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2470a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2470f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24714 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24719 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2471e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24723 */ "\x00\x00", "\x94\x59", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24728 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2472d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24732 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24737 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2473c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24741 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24746 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2474b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24750 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24755 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2475a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2475f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24764 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24769 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2476e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24773 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24778 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2477d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24782 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24787 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2478c */ "\x00\x00", "\x00\x00", "\x94\x58", ++ /* 0x23aa7 */ "\x9b\xa2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23aab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ab0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ab5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23aba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23abf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ac4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ac9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ace */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ad3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ad8 */ "\x00\x00", "\x00\x00", "\xfd\x69", "\x00\x00", "\x00\x00", ++ /* 0x23add */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ae2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ae7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23aec */ "\x00\x00", "\x93\x52", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23af1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23af6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xa2", "\x00\x00", ++ /* 0x23afb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b1a */ "\x8c\xe7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23b55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\x6e", + +- /* 0x24823 */ "\xfe\x54", +- +- /* 0x248f3 */ "\x94\xa5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x248f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x248fc */ "\x00\x00", "\x00\x00", "\x95\xed", "\xfd\x7e", "\xfb\xeb", +- /* 0x24901 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24906 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2490c */ "\xfd\x7d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24910 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24916 */ "\x97\x6f", "\x94\x61", "\x00\x00", "\x9f\xc1", "\x00\x00", +- /* 0x2491a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2491f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24924 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24929 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2492f */ "\x95\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x52", +- /* 0x24933 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24938 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2493e */ "\x9f\x68", "\x9b\xe7", "\xfc\xce", "\x96\xe8", "\xfa\x49", +- /* 0x24942 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24947 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2494c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24951 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24956 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2495b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24960 */ "\x00\x00", "\x95\x4d", "\x9e\xf8", "\x00\x00", "\x00\x00", +- /* 0x24965 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2496a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2496f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x49", +- /* 0x24975 */ "\x91\xce", "\x97\x71", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24979 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2497f */ "\xfd\xb1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24983 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xf2", +- /* 0x24989 */ "\x93\xb8", "\x90\x43", "\x97\x59", "\x94\xd7", "\xfe\x66", +- /* 0x2498e */ "\x94\x7d", "\xfc\x6f", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24992 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24997 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2499c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249a7 */ "\x8e\xf7", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x7c", +- /* 0x249ac */ "\x92\xcd", "\x97\xb2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249b5 */ "\x00\x00", "\xfe\x65", "\x96\x7e", "\x97\x58", "\x9b\x77", +- /* 0x249bb */ "\x91\xcf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249de */ "\x96\xd5", "\xfc\xb3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249e3 */ "\x93\xae", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x249f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x46", +- /* 0x249f7 */ "\x95\x5b", "\x91\xd1", "\x94\xf4", "\x00\x00", "\x00\x00", +- /* 0x249fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a1e */ "\x00\x00", "\x00\x00", "\xfc\xed", "\xfd\xfa", "\xfc\xc8", +- /* 0x24a24 */ "\xfe\x62", "\x91\xfc", "\xfe\x6b", "\xfd\xf9", "\xfc\xc7", +- /* 0x24a29 */ "\x91\x4e", "\x9c\xb8", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a3c */ "\x00\x00", "\x97\x67", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a4b */ "\x00\x00", "\x00\x00", "\x94\xa2", "\x98\x75", "\x97\xac", +- /* 0x24a51 */ "\x91\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a65 */ "\x8e\xeb", "\x97\x6a", "\x96\x5e", "\x00\x00", "\x00\x00", +- /* 0x24a69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xf9", "\x95\xf8", +- /* 0x24a79 */ "\xfe\xa2", "\x8f\xe6", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a91 */ "\x00\x00", "\x9d\xa4", "\x97\x68", "\x8e\xec", "\x94\xbd", +- /* 0x24a96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24a9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24aa0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x5b", "\x9c\xf6", +- /* 0x24aa6 */ "\xfa\xa7", "\x9b\xd9", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24aaa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24aaf */ "\x00\x00", "\xfa\x5d", "\x96\x56", "\x97\x62", "\x00\x00", +- /* 0x24ab4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24aba */ "\x94\xba", "\xa0\x4f", "\x92\xd8", "\x00\x00", "\x00\x00", +- /* 0x24abe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24ac3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xbb", "\x00\x00", +- /* 0x24ac8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24acd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xcf", "\x00\x00", +- /* 0x24ad2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24ad7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24adc */ "\x00\x00", "\x00\x00", "\x94\x65", "\x00\x00", "\x00\x00", +- /* 0x24ae2 */ "\x9f\x4c", +- +- /* 0x24b6e */ "\x9e\xbe", ++ /* 0x23c63 */ "\x8c\xa4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x7c", ++ /* 0x23c9a */ "\x93\xfa", "\x90\x7c", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23c9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ca3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ca8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cb2 */ "\x00\x00", "\x00\x00", "\x8f\x67", "\x00\x00", "\x9d\xb7", ++ /* 0x23cb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cc1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cc7 */ "\xa0\xe9", "\xfa\x4e", "\xfd\xa1", "\x00\x00", "\x00\x00", ++ /* 0x23ccb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cd0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cd5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cdf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ce4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ce9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cf3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23cf8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x74", "\x9f\xbf", ++ /* 0x23cfe */ "\x9e\xcb", "\x9b\xb9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d3e */ "\x00\x00", "\x9d\xd4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xb9", "\x00\x00", ++ /* 0x23d5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xf1", "\x00\x00", ++ /* 0x23d7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d8f */ "\x95\x7b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23d9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23da2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23da7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23db1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xd2", ++ /* 0x23db7 */ "\x97\x53", "\x96\xa4", "\x8f\xbe", "\x94\xd9", "\x90\x58", ++ /* 0x23dbc */ "\xfd\x79", "\xfd\x7b", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dcf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dde */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xda", ++ /* 0x23de3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23de8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ded */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23df2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23df8 */ "\x8e\xfa", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23dfc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x62", ++ /* 0x23e06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e11 */ "\x9b\xa5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e29 */ "\x00\x00", "\x00\x00", "\x9e\xd9", "\x97\xd4", "\x90\xbb", ++ /* 0x23e2f */ "\xfd\xbc", "\xfd\xc6", "\x92\x48", "\x00\x00", "\x00\x00", ++ /* 0x23e33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e39 */ "\x92\xb5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xc1", ++ /* 0x23e89 */ "\x92\xb9", "\x92\xa6", "\x8f\x4b", "\x00\x00", "\x00\x00", ++ /* 0x23e8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23e9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ea1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ea6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23eab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23eb0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23eb5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xa6", "\x00\x00", ++ /* 0x23eba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xb6", ++ /* 0x23ebf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ec4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ec9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ece */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ed3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x40", "\x00\x00", ++ /* 0x23ed8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23edd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ee2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ee7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23eec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ef1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ef7 */ "\x9e\xd8", "\x94\x5e", "\x98\x5f", "\x94\xce", "\x92\x4a", ++ /* 0x23efc */ "\xfd\x70", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f32 */ "\x00\x00", "\x00\x00", "\x94\x67", "\x00\x00", "\x00\x00", ++ /* 0x23f37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\xec", ++ /* 0x23f41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xd8", "\x00\x00", ++ /* 0x23f4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f5f */ "\x00\x00", "\x87\x63", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f7d */ "\x00\x00", "\x94\x48", "\xfa\xc1", "\x9c\xf7", "\xfd\xbe", ++ /* 0x23f82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f8c */ "\x00\x00", "\x00\x00", "\x8f\xda", "\x00\x00", "\x00\x00", ++ /* 0x23f91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23f9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fa0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fa5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23faa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23faf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xd9", ++ /* 0x23fb4 */ "\x00\x00", "\x00\x00", "\xfc\x7e", "\x00\x00", "\x00\x00", ++ /* 0x23fb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fbe */ "\x00\x00", "\x93\xf9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fc3 */ "\x00\x00", "\xfa\x43", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fcd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fd7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fdc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fe1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fe6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\xeb", ++ /* 0x23fec */ "\xfa\xc3", "\x97\xd3", "\x95\xf9", "\x9c\x48", "\xfd\xd8", ++ /* 0x23ff0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ff5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23ffa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x23fff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24004 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24009 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2400e */ "\x00\x00", "\x00\x00", "\xa0\xd8", "\x00\x00", "\x00\x00", ++ /* 0x24013 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24018 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2401d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24022 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24027 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2402c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24031 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24036 */ "\x00\x00", "\x00\x00", "\xfd\xd7", "\xfb\x4a", "\x9b\xaf", ++ /* 0x2403c */ "\x94\x4b", "\xfd\xc9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24040 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24045 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2404a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2404f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24054 */ "\x00\x00", "\x00\x00", "\x8e\xac", "\x00\x00", "\x00\x00", ++ /* 0x24059 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2405e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24063 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24068 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2406d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24072 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24077 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2407c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24081 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xb2", "\x00\x00", ++ /* 0x24086 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x5a", ++ /* 0x2408c */ "\xfc\xbd", "\x92\xd9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24091 */ "\xfd\xd5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24095 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2409a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2409f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240c7 */ "\x00\x00", "\x92\xdd", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240e1 */ "\x92\x59", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240ea */ "\x00\x00", "\x8c\xf0", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x240fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24104 */ "\x96\xba", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24108 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2410d */ "\x00\x00", "\x92\x5b", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24112 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24117 */ "\x00\x00", "\x9b\xab", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2411c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24121 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24126 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2412b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24130 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24135 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2413a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xda", ++ /* 0x24140 */ "\xfd\xde", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xd3", ++ /* 0x24144 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24149 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x46", ++ /* 0x2414e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24153 */ "\x00\x00", "\xfd\xd6", "\xfd\xdc", "\xfd\xdd", "\x00\x00", ++ /* 0x24158 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xfe", "\x00\x00", ++ /* 0x2415d */ "\x00\x00", "\xfe\xa1", "\x00\x00", "\x87\xa5", "\x00\x00", ++ /* 0x24162 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24167 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2416c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24171 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24177 */ "\x8b\xad", "\x00\x00", "\x00\x00", "\x9c\xd8", "\x00\x00", ++ /* 0x2417b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24180 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24185 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2418a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2418f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24194 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24199 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2419e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x6d", ++ /* 0x241a4 */ "\xfd\x7c", "\xfb\x61", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xf8", "\x00\x00", ++ /* 0x241ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241b2 */ "\x00\x00", "\x00\x00", "\x96\xf0", "\x00\x00", "\x00\x00", ++ /* 0x241b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241cb */ "\x00\x00", "\xfc\xf4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241df */ "\x00\x00", "\x00\x00", "\xfe\x60", "\x00\x00", "\x00\x00", ++ /* 0x241e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x241f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x52", "\x00\x00", ++ /* 0x241fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24202 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24207 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2420c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24211 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24216 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\x4f", ++ /* 0x2421b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24220 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24225 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2422a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2422f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24234 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24239 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2423e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24243 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24248 */ "\x00\x00", "\x00\x00", "\x91\x6e", "\x00\x00", "\x00\x00", ++ /* 0x2424d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24252 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x6d", "\x00\x00", ++ /* 0x24257 */ "\x00\x00", "\x98\x64", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2425c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24261 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24266 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2426b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24270 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24276 */ "\x94\x53", "\xfd\xec", "\xfb\x78", "\x00\x00", "\x00\x00", ++ /* 0x2427a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2427f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xba", ++ /* 0x24284 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24289 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2428e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x5d", ++ /* 0x24293 */ "\x00\x00", "\x92\xf9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24298 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2429d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242a2 */ "\x00\x00", "\x00\x00", "\x98\x5a", "\x00\x00", "\x00\x00", ++ /* 0x242a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x50", "\x00\x00", ++ /* 0x242c1 */ "\xfd\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xd0", "\x98\x62", ++ /* 0x242ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242ee */ "\x9b\xad", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x242f7 */ "\x00\x00", "\x00\x00", "\x97\x4f", "\x00\x00", "\x00\x00", ++ /* 0x242fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24301 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24306 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2430b */ "\x00\x00", "\x9b\xae", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24310 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24315 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x52", ++ /* 0x2431a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2431f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24324 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24329 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2432e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24334 */ "\x9b\xb0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24338 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2433d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24342 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24348 */ "\x91\xd2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2434c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24351 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24356 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2435b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24360 */ "\x00\x00", "\x97\xea", "\xfb\x6b", "\x91\xb1", "\xfd\xf3", ++ /* 0x24365 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2436a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2436f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24374 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24379 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2437e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24383 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24388 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xcb", "\x00\x00", ++ /* 0x2438d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24392 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xb1", "\x00\x00", ++ /* 0x24397 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xec", ++ /* 0x2439c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243ba */ "\x00\x00", "\x00\x00", "\x98\x6b", "\x00\x00", "\x00\x00", ++ /* 0x243bf */ "\x00\x00", "\x97\x51", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243e7 */ "\x00\x00", "\x98\x71", "\x95\xef", "\x00\x00", "\x00\x00", ++ /* 0x243ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243f2 */ "\x9e\xf3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243f6 */ "\x00\x00", "\x91\xe8", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x243fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24400 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xba", "\x00\x00", ++ /* 0x24405 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2440a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2440f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24414 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24419 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2441e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24423 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24428 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2442d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24432 */ "\x00\x00", "\x00\x00", "\xfb\x4c", "\x92\x6a", "\x00\x00", ++ /* 0x24437 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2443c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24441 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24446 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2444b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24450 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24455 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xf8", ++ /* 0x2445b */ "\x98\x61", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2445f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24464 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24469 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2446e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xe7", ++ /* 0x24473 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24478 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2447d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24482 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xed", ++ /* 0x24488 */ "\x97\x44", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2448c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24491 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24496 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2449b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xe1", ++ /* 0x244b9 */ "\x00\x00", "\x00\x00", "\xfb\xf5", "\x00\x00", "\x00\x00", ++ /* 0x244be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244ce */ "\x98\x69", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244d3 */ "\x8a\x62", "\x00\x00", "\x00\x00", "\x9b\xbb", "\x00\x00", ++ /* 0x244d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x244ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24505 */ "\x8c\xa8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24509 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2450e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24513 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24518 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2451d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x55", "\x00\x00", ++ /* 0x24522 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24527 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2452c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24531 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24536 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2453b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24540 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24545 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2454a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2454f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24554 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24559 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2455e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24563 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24568 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2456d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24572 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24578 */ "\x8e\x77", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2457c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24581 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24586 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2458b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24590 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24595 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2459a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2459f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245c8 */ "\x8a\xb2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x245fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24603 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24608 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2460d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24612 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24618 */ "\x9e\xbc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2461c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24621 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24626 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xe6", "\x00\x00", ++ /* 0x2462b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24630 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24635 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2463a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2463f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24644 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24649 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2464e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24653 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24658 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2465d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24662 */ "\x00\x00", "\x00\x00", "\x93\xa2", "\x00\x00", "\x00\x00", ++ /* 0x24667 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2466c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24671 */ "\x00\x00", "\x00\x00", "\x9b\xbd", "\x00\x00", "\x00\x00", ++ /* 0x24676 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2467b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24680 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24685 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2468a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2468f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24694 */ "\x00\x00", "\x00\x00", "\x94\xb3", "\x00\x00", "\x00\x00", ++ /* 0x24699 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2469e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x7d", "\x00\x00", ++ /* 0x246d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x246fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24702 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x66", "\x00\x00", ++ /* 0x24707 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2470c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24711 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24716 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2471b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24720 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x59", ++ /* 0x24725 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2472a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xbf", ++ /* 0x2472f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24734 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24739 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2473e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24743 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24748 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2474d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24752 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24757 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2475c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24761 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24766 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2476b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24770 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24775 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2477a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2477f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24784 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24789 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2478f */ "\x94\x58", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24793 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24798 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2479d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247de */ "\x00\x00", "\x9e\xa5", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x247fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24801 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24806 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2480b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24810 */ "\x00\x00", "\x9b\xc7", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24815 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2481a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2481f */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x54", "\x00\x00", ++ /* 0x24824 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24829 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2482e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24833 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24838 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2483d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24842 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24847 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2484c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24851 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24856 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2485b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24860 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24865 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2486a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2486f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24874 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24879 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2487e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x74", "\x00\x00", ++ /* 0x24883 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24888 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2488d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24892 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24897 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2489c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248e7 */ "\x00\x00", "\x8b\xd6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xb6", "\xfd\x74", ++ /* 0x248f2 */ "\x98\xc0", "\x94\xa5", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x248f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xc8", ++ /* 0x248fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xed", "\xfd\x7e", ++ /* 0x24901 */ "\xfb\xeb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24905 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2490a */ "\x00\x00", "\xfd\x7d", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2490f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24914 */ "\x00\x00", "\x97\x6f", "\x94\x61", "\x00\x00", "\x9f\xc1", ++ /* 0x24919 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2491e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24923 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24928 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2492d */ "\x00\x00", "\x95\xd7", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24933 */ "\xfa\x52", "\x9c\x58", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24937 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2493c */ "\x00\x00", "\x9f\x68", "\x9b\xe7", "\xfc\xce", "\x96\xe8", ++ /* 0x24942 */ "\xfa\x49", "\x97\xa1", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24946 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2494b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24950 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24955 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2495a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2495f */ "\x00\x00", "\x00\x00", "\x95\x4d", "\x9e\xf8", "\x00\x00", ++ /* 0x24964 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24969 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2496e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24974 */ "\xfe\x49", "\x91\xce", "\x97\x71", "\x00\x00", "\x00\x00", ++ /* 0x24978 */ "\x00\x00", "\x00\x00", "\x8c\xcf", "\x00\x00", "\x00\x00", ++ /* 0x2497d */ "\x00\x00", "\xfd\xb1", "\x00\x00", "\x00\x00", "\xfc\x6e", ++ /* 0x24982 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24988 */ "\x9c\xf2", "\x93\xb8", "\x90\x43", "\x97\x59", "\x94\xd7", ++ /* 0x2498d */ "\xfe\x66", "\x94\x7d", "\xfc\x6f", "\x00\x00", "\x00\x00", ++ /* 0x24991 */ "\x00\x00", "\x00\x00", "\x92\x46", "\x00\x00", "\x00\x00", ++ /* 0x24996 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2499b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x6d", "\x00\x00", ++ /* 0x249a5 */ "\x00\x00", "\x8e\xf7", "\x00\x00", "\xfb\xb7", "\x00\x00", ++ /* 0x249ab */ "\x94\x7c", "\x92\xcd", "\x97\xb2", "\x00\x00", "\x00\x00", ++ /* 0x249af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249b4 */ "\x00\x00", "\x00\x00", "\xfe\x65", "\x96\x7e", "\x97\x58", ++ /* 0x249ba */ "\x9b\x77", "\x91\xcf", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249c3 */ "\x00\x00", "\x94\xa4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249cd */ "\x00\x00", "\x00\x00", "\x9c\xad", "\x00\x00", "\x00\x00", ++ /* 0x249d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249d7 */ "\x00\x00", "\x00\x00", "\x8b\xab", "\x00\x00", "\x00\x00", ++ /* 0x249dc */ "\x00\x00", "\x96\xd5", "\xfc\xb3", "\x00\x00", "\x00\x00", ++ /* 0x249e1 */ "\x00\x00", "\x93\xae", "\x00\x00", "\x97\x6d", "\x00\x00", ++ /* 0x249e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249ec */ "\x94\x46", "\x95\xf7", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249f6 */ "\x9c\x46", "\x95\x5b", "\x91\xd1", "\x94\xf4", "\x00\x00", ++ /* 0x249fb */ "\xfe\x67", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x249ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x92\xa5", ++ /* 0x24a0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xdf", "\x8c\xab", ++ /* 0x24a13 */ "\x00\x00", "\x9b\xc9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xed", "\xfd\xfa", ++ /* 0x24a23 */ "\xfc\xc8", "\xfe\x62", "\x91\xfc", "\xfe\x6b", "\xfd\xf9", ++ /* 0x24a28 */ "\xfc\xc7", "\x91\x4e", "\x9c\xb8", "\x00\x00", "\x00\x00", ++ /* 0x24a2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a3b */ "\x00\x00", "\x00\x00", "\x97\x67", "\x00\x00", "\x00\x00", ++ /* 0x24a40 */ "\x00\x00", "\x95\xee", "\x00\x00", "\x00\x00", "\x9b\xb2", ++ /* 0x24a45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x60", ++ /* 0x24a4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xa2", "\x98\x75", ++ /* 0x24a50 */ "\x97\xac", "\x91\xd3", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x7b", "\x00\x00", ++ /* 0x24a5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a63 */ "\x00\x00", "\x8e\xeb", "\x97\x6a", "\x96\x5e", "\x00\x00", ++ /* 0x24a68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xeb", "\x00\x00", ++ /* 0x24a72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xf9", ++ /* 0x24a78 */ "\x95\xf8", "\xfe\xa2", "\x8f\xe6", "\x00\x00", "\x00\x00", ++ /* 0x24a7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a8c */ "\xfe\x7e", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a90 */ "\x00\x00", "\x00\x00", "\x9d\xa4", "\x97\x68", "\x8e\xec", ++ /* 0x24a96 */ "\x94\xbd", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24a9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x5b", ++ /* 0x24aa5 */ "\x9c\xf6", "\xfa\xa7", "\x9b\xd9", "\x00\x00", "\x00\x00", ++ /* 0x24aa9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24aae */ "\x00\x00", "\x00\x00", "\xfa\x5d", "\x96\x56", "\x97\x62", ++ /* 0x24ab3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ab8 */ "\x00\x00", "\x94\xba", "\xa0\x4f", "\x92\xd8", "\x00\x00", ++ /* 0x24abd */ "\x00\x00", "\x00\x00", "\x9b\xcb", "\x00\x00", "\x00\x00", ++ /* 0x24ac2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xbb", ++ /* 0x24ac7 */ "\x00\x00", "\x00\x00", "\x9d\x5f", "\x00\x00", "\x00\x00", ++ /* 0x24acc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xcf", ++ /* 0x24ad1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ad6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24adb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x65", "\x00\x00", ++ /* 0x24ae0 */ "\x00\x00", "\x9f\x4c", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ae5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xd8", "\x00\x00", ++ /* 0x24aea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24aef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24af4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24af9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24afe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b0d */ "\x00\x00", "\x8d\x5b", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24b6c */ "\x00\x00", "\x9e\xbe", + + /* 0x24bf5 */ "\xfb\x6d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24bf9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14269,7 +14158,7 @@ static const char from_ucs4[][2] = + /* 0x24cb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24cbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24cc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24cc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24cc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xfc", "\x00\x00", + /* 0x24cca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24ccf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24cd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x73", +@@ -14282,6 +14171,9 @@ static const char from_ucs4[][2] = + /* 0x24cf7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24cfc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24d01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x74", ++ /* 0x24d06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24d0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24d10 */ "\x00\x00", "\x00\x00", "\xfe\xb7", + + /* 0x24db8 */ "\x8a\x4b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24dbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14309,375 +14201,529 @@ static const char from_ucs4[][2] = + /* 0x24e2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24e2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24e34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24e39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e39 */ "\x00\x00", "\x8a\xdc", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24e3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24e43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x24e48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24e4d */ "\x00\x00", "\x00\x00", "\x8b\x76", +- +- /* 0x24f0e */ "\xa0\xf8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xdf", "\x00\x00", +- /* 0x24f5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f80 */ "\x00\x00", "\xfe\xb5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f94 */ "\x00\x00", "\x00\x00", "\x96\xfb", "\x00\x00", "\x00\x00", +- /* 0x24f9a */ "\x9b\xfb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24f9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fa3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fa9 */ "\x9e\xce", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fb2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x24fc2 */ "\x9e\x7b", +- +- /* 0x2509d */ "\xfe\xce", +- +- /* 0x25148 */ "\x9d\xfc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2514c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25151 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25156 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2515b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25160 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25165 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2516a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2516f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25174 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25179 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xcf", "\x8b\xa5", +- /* 0x2517e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25183 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25188 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2518d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25192 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25197 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2519c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251e3 */ "\x8a\xec", "\x00\x00", "\x00\x00", "\xfc\xe0", "\x94\xad", +- /* 0x251e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x251fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25200 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25205 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2520a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2520f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25214 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25219 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2521e */ "\x00\x00", "\xfe\xd5", "\x94\xac", ++ /* 0x24e4d */ "\x00\x00", "\x00\x00", "\x8b\x76", "\x00\x00", "\x00\x00", ++ /* 0x24e52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24e9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ea2 */ "\x00\x00", "\x00\x00", "\x9b\xce", "\x00\x00", "\x8a\x68", ++ /* 0x24ea7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24eac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24eb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24eb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ebb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ec0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ec5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24eca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ecf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ed4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ed9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ede */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ee3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ee8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24eed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ef2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ef7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24efc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f0b */ "\x00\x00", "\x00\x00", "\xa0\xf8", "\x00\x00", "\x00\x00", ++ /* 0x24f10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f5c */ "\x98\xdf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xb5", "\x00\x00", ++ /* 0x24f83 */ "\x00\x00", "\x00\x00", "\x9b\xcf", "\x00\x00", "\x00\x00", ++ /* 0x24f88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24f92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xfb", ++ /* 0x24f97 */ "\x00\x00", "\x00\x00", "\x9b\xfb", "\x00\x00", "\x00\x00", ++ /* 0x24f9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fa1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fa6 */ "\x00\x00", "\x00\x00", "\x9e\xce", "\x00\x00", "\x00\x00", ++ /* 0x24fab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fb0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fb5 */ "\x00\x00", "\x00\x00", "\x8e\xe5", "\x00\x00", "\x00\x00", ++ /* 0x24fba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fbf */ "\x00\x00", "\x00\x00", "\x9e\x7b", "\x00\x00", "\x00\x00", ++ /* 0x24fc4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fc9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fdd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fe2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fe7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24fec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ff1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ff6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x24ffb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25000 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25005 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2500a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2500f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25014 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25019 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2501e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25023 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25028 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xd2", "\x00\x00", ++ /* 0x2502d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25032 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25037 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2503c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25041 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25046 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2504b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25050 */ "\x00\x00", "\x8a\xa5", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25055 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2505a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2505f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25064 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25069 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2506e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25073 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25078 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2507d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25082 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25087 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2508c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25091 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25096 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2509b */ "\x00\x00", "\xfe\xce", + +- /* 0x252c7 */ "\x8a\x6f", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252d5 */ "\x00\x00", "\x00\x00", "\x8b\xa9", "\x00\x00", "\x00\x00", +- /* 0x252da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x252fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25302 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25307 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2530c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xcb", +- /* 0x25311 */ "\x00\x00", "\xfc\xe7", ++ /* 0x2512b */ "\x8a\x45", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2512f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25134 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25139 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2513e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25143 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xfc", ++ /* 0x25148 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2514d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25152 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25157 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2515c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25161 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25166 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2516b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25170 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25175 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2517a */ "\x00\x00", "\x00\x00", "\xfe\xcf", "\x8b\xa5", "\x00\x00", ++ /* 0x2517f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25184 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25189 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2518e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25193 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25198 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2519d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251ca */ "\x00\x00", "\x00\x00", "\x8c\x4a", "\x00\x00", "\x00\x00", ++ /* 0x251cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xec", ++ /* 0x251e3 */ "\x00\x00", "\x00\x00", "\xfc\xe0", "\x94\xad", "\x00\x00", ++ /* 0x251e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x251fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25201 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25206 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2520b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25210 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25215 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2521a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25220 */ "\xfe\xd5", "\x94\xac", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25224 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25229 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2522e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25233 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25238 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2523d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25242 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25247 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2524c */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x5a", "\x00\x00", ++ /* 0x25251 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25256 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2525b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25260 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25265 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2526a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2526f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25274 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25279 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2527e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25283 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25288 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2528d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25292 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25297 */ "\x00\x00", "\x9b\xd6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2529c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252c4 */ "\x00\x00", "\x00\x00", "\x8a\x6f", "\x00\x00", "\x00\x00", ++ /* 0x252c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xa9", ++ /* 0x252d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x252fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25300 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25305 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2530a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x5f", "\x00\x00", ++ /* 0x2530f */ "\x00\x00", "\x9d\xcb", "\x00\x00", "\xfc\xe7", + +- /* 0x25425 */ "\x93\xc8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25429 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2542f */ "\x91\xf0", "\x8f\xe0", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25433 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25438 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2543d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25442 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25447 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2544c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25451 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25456 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2545b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25460 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25465 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2546a */ "\x00\x00", "\x90\xed", "\x00\x00", "\x9b\xdc", ++ /* 0x25419 */ "\x9b\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2541d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25422 */ "\x00\x00", "\x00\x00", "\x93\xc8", "\x00\x00", "\x00\x00", ++ /* 0x25427 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2542c */ "\x00\x00", "\x00\x00", "\x91\xf0", "\x8f\xe0", "\x00\x00", ++ /* 0x25431 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25436 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2543b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25440 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25446 */ "\x9b\xdb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2544a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2544f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25454 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25459 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2545e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25463 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25468 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xed", "\x00\x00", ++ /* 0x2546e */ "\x9b\xdc", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25472 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25477 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2547c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25481 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25486 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2548b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25490 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25495 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x53", + +- /* 0x2555b */ "\x93\xc7", "\x92\x49", "\x96\xe1", "\x00\x00", "\x00\x00", +- /* 0x2555f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25565 */ "\x8f\xe1", "\x9b\xe5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25569 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2556e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25573 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25578 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2557d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xc0", "\x00\x00", +- /* 0x25582 */ "\x00\x00", "\x93\xc3", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25587 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2558c */ "\x00\x00", "\x00\x00", "\x93\xc5", "\x00\x00", "\x00\x00", +- /* 0x25591 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25596 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2559b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x79", +- /* 0x255b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255d2 */ "\x00\x00", "\x00\x00", "\x97\x7b", "\x00\x00", "\x00\x00", +- /* 0x255d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x7e", "\x00\x00", +- /* 0x255dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xe6", "\x00\x00", +- /* 0x255e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x255ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25604 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25609 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2560e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25613 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25618 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2561d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25622 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25627 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2562c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25631 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xb8", "\x00\x00", +- /* 0x25636 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2563b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25640 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25645 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2564a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2564f */ "\x00\x00", "\x92\x70", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25654 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25659 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2565e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25663 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25668 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2566d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25672 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25677 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2567c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25681 */ "\x00\x00", "\x95\xa8", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25686 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2568b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25690 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25695 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2569a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2569f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256f4 */ "\x00\x00", "\x98\xb9", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x256fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25703 */ "\x00\x00", "\x00\x00", "\x91\x40", "\x00\x00", "\x00\x00", +- /* 0x25708 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2570d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25712 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25717 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2571d */ "\xfc\xbe", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25721 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x57", "\x00\x00", +- /* 0x25726 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2572b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25730 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25735 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2573a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2573f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25744 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25749 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2574e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25753 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25758 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2575d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25762 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25767 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2576c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25772 */ "\xfa\xdf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25776 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2577b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25780 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25785 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2578a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2578f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25794 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25799 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2579e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257c7 */ "\x9b\xe6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257e0 */ "\x8e\x44", "\x9c\x4f", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x257fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25802 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25807 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2580c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25811 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25816 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2581b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25820 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25825 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2582a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2582f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25834 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25839 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2583e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25843 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25848 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2584d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25852 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xf4", +- /* 0x25857 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2585c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25861 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25866 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2586b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25870 */ "\x00\x00", "\x93\xdc", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25875 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2587a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2587f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25884 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25889 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2588e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25893 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25898 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2589d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258de */ "\x00\x00", "\x00\x00", "\x8e\x4a", "\x00\x00", "\x00\x00", +- /* 0x258e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x258fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25901 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25906 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2590b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25910 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25915 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2591a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2591f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25924 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25929 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2592e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25933 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25938 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2593d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25942 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25947 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2594c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25951 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xb9", +- /* 0x25956 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2595b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25960 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25965 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2596a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2596f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25974 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25979 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2597e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25983 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25988 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2598d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25992 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25997 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2599c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x259a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x259a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x259ac */ "\x8e\x4e", ++ /* 0x25531 */ "\xa0\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xfa", ++ /* 0x25535 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2553a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xe0", ++ /* 0x2553f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25544 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25549 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2554e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25553 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25558 */ "\x00\x00", "\x00\x00", "\x93\xc7", "\x92\x49", "\x96\xe1", ++ /* 0x2555e */ "\x9b\xe2", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xe4", ++ /* 0x25562 */ "\x00\x00", "\x00\x00", "\x8f\xe1", "\x9b\xe5", "\x00\x00", ++ /* 0x25567 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2556c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25571 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25576 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2557b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25581 */ "\x94\xc0", "\x00\x00", "\x00\x00", "\x93\xc3", "\x00\x00", ++ /* 0x25585 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2558a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xc5", ++ /* 0x2558f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25594 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25599 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2559e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255b7 */ "\x00\x00", "\x90\x79", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x7b", ++ /* 0x255d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255db */ "\x90\x7e", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255e0 */ "\xfe\xe6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x255fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25602 */ "\x00\x00", "\x00\x00", "\xfe\x46", "\x00\x00", "\x00\x00", ++ /* 0x25607 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2560c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25611 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25616 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2561b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25620 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25625 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2562a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2562f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25635 */ "\x9d\xb8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25639 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2563e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25643 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25648 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2564d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x70", "\x00\x00", ++ /* 0x25652 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25657 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2565c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25661 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25666 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2566b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25670 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25675 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2567a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2567f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xa8", "\x00\x00", ++ /* 0x25684 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25689 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2568e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25693 */ "\x00\x00", "\x8c\xb0", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25698 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2569d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xc8", ++ /* 0x256e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xb9", "\x00\x00", ++ /* 0x256f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x256fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25701 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x40", ++ /* 0x25706 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2570b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25710 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25715 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2571a */ "\x00\x00", "\x00\x00", "\xfc\xbe", "\x00\x00", "\x00\x00", ++ /* 0x2571f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25725 */ "\x91\x57", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25729 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2572e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25733 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25738 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xb2", ++ /* 0x2573d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25742 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25747 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2574c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25751 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25756 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2575b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25760 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25765 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2576a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2576f */ "\x00\x00", "\x00\x00", "\xfa\xdf", "\x00\x00", "\x00\x00", ++ /* 0x25774 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25779 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2577e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25783 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25788 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2578d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25792 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25797 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2579c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257c4 */ "\x00\x00", "\x00\x00", "\x9b\xe6", "\x00\x00", "\x00\x00", ++ /* 0x257c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257dd */ "\x00\x00", "\x96\x43", "\x8e\x44", "\x9c\x4f", "\x00\x00", ++ /* 0x257e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x257fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25800 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25805 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2580a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2580f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25814 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25819 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2581e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25823 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25828 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2582d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25832 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25837 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2583c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25841 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25846 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2584b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25850 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25855 */ "\x00\x00", "\xfe\xf4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2585a */ "\x00\x00", "\x00\x00", "\x9b\xe8", "\x00\x00", "\x00\x00", ++ /* 0x2585f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25864 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25869 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2586e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xdc", "\x00\x00", ++ /* 0x25873 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25878 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2587d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25882 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25887 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2588c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25891 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25896 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2589b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\x6f", ++ /* 0x258c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258dc */ "\x00\x00", "\x87\xa1", "\x00\x00", "\x00\x00", "\x8e\x4a", ++ /* 0x258e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x258ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xed", "\x00\x00", ++ /* 0x25904 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25909 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2590e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25913 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25918 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2591d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25922 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25927 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2592c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25931 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25936 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2593b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25940 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25946 */ "\x92\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2594a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2594f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25954 */ "\x00\x00", "\x9d\xb9", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25959 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2595e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25963 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25968 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2596d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25972 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25977 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2597c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25981 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25986 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2598b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25990 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25995 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2599a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2599f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259a9 */ "\x00\x00", "\x00\x00", "\x8e\x4e", "\x00\x00", "\x00\x00", ++ /* 0x259ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x259c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xcf", + +- /* 0x25a9c */ "\x94\xe5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25aa0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25aa5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25aaa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xf0", "\x00\x00", +- /* 0x25aaf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ab4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ab9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25abe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ac3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ac8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25acd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ad2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ad7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25adc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ae1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ae6 */ "\x00\x00", "\x00\x00", "\x95\x51", ++ /* 0x25a54 */ "\x87\x60", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a95 */ "\x9e\xc2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25a99 */ "\x00\x00", "\x00\x00", "\x94\xe5", "\x00\x00", "\x00\x00", ++ /* 0x25a9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25aa3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25aa8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25aae */ "\x9b\xf0", "\x94\xe4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ab2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ab7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25abc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ac1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ac6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25acb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ad0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ad5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ada */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25adf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ae4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x51", + + /* 0x25b74 */ "\x8b\xbb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25b78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25b7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25b82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25b87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25b87 */ "\x00\x00", "\x9b\xf1", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25b8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25b91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25b96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14695,8 +14741,8 @@ static const char from_ucs4[][2] = + /* 0x25bd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25bd7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25bdc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25be1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25be6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25be1 */ "\x00\x00", "\x00\x00", "\x8f\x61", "\x00\x00", "\x00\x00", ++ /* 0x25be6 */ "\x00\x00", "\x9b\x64", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25beb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25bf0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25bf5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14707,7 +14753,7 @@ static const char from_ucs4[][2] = + /* 0x25c0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25c1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25c1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xbe", "\x00\x00", + /* 0x25c22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14730,10 +14776,10 @@ static const char from_ucs4[][2] = + /* 0x25c81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25c90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25c91 */ "\x8f\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25c9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25c9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25c9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xaf", + /* 0x25ca4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25ca9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25cae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14758,79 +14804,118 @@ static const char from_ucs4[][2] = + /* 0x25d0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25d12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25d17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25d1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xd8", "\x00\x00", ++ /* 0x25d1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x6a", "\x00\x00", + /* 0x25d21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25d26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25d2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x4c", + /* 0x25d30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25d35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25d3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25d3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x52", +- +- /* 0x25e0e */ "\x95\x54", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e81 */ "\x9d\xbb", "\x95\x43", "\x92\xfe", "\x00\x00", "\x00\x00", +- /* 0x25e85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25e9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ea3 */ "\x00\x00", "\x00\x00", "\x94\xf2", "\x00\x00", "\x00\x00", +- /* 0x25ea8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ead */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25eb2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25eb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xf1", +- /* 0x25ebc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ec1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ec6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ecb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ed0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ed5 */ "\x00\x00", "\xa0\xea", "\x9d\xd2", "\x00\x00", "\x00\x00", +- /* 0x25eda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25edf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ee4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ee9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25eee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ef3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25ef8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25efd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x25f48 */ "\x00\x00", "\x00\x00", "\x91\xf8", ++ /* 0x25d3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x52", "\x00\x00", ++ /* 0x25d44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xcf", ++ /* 0x25d99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25d9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25da3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25da8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25db2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25db7 */ "\x00\x00", "\x87\xc0", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dc1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dc6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dcb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dd0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dd5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ddf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25de4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25de9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25df3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25df8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25dfd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e0c */ "\x00\x00", "\x95\x54", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e49 */ "\x8a\xd4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e7f */ "\x00\x00", "\x9d\xbb", "\x95\x43", "\x92\xfe", "\x00\x00", ++ /* 0x25e84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25e9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ea2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xf2", "\x00\x00", ++ /* 0x25ea7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25eac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25eb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25eb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ebc */ "\x94\xf1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ec0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ec5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25eca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ecf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ed4 */ "\x00\x00", "\x00\x00", "\xa0\xea", "\x9d\xd2", "\x00\x00", ++ /* 0x25ed9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ede */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ee3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ee8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25eed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ef2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25ef7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25efc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xb1", ++ /* 0x25f1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x25f47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xf8", + + /* 0x25fe1 */ "\x94\x62", "\x9b\xa4", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x25fe5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14844,7 +14929,7 @@ static const char from_ucs4[][2] = + /* 0x2600d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26012 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26017 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2601c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2601c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x7d", + /* 0x26021 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26026 */ "\x00\x00", "\x00\x00", "\x8e\xad", "\x00\x00", "\x00\x00", + /* 0x2602b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14852,7 +14937,7 @@ static const char from_ucs4[][2] = + /* 0x26035 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2603a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2603f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26044 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26044 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xad", "\x00\x00", + /* 0x26049 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2604e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26053 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14864,11 +14949,11 @@ static const char from_ucs4[][2] = + /* 0x26071 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26076 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2607b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26080 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26080 */ "\x00\x00", "\x00\x00", "\xfe\xee", "\x00\x00", "\x00\x00", + /* 0x26085 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2608a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2608f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26094 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26094 */ "\x00\x00", "\x00\x00", "\x8a\xb4", "\x00\x00", "\x00\x00", + /* 0x26099 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2609e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x260a4 */ "\x97\x57", "\x8a\x77", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14889,7 +14974,7 @@ static const char from_ucs4[][2] = + /* 0x260ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x260f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x260f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x260fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x260fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xf7", + /* 0x26102 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26107 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2610c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14925,7 +15010,7 @@ static const char from_ucs4[][2] = + /* 0x261a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x261a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x261ad */ "\xa0\xf3", "\x94\xbe", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x261b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x261b2 */ "\x9b\xfa", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x261b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x261bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x261c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14961,8 +15046,8 @@ static const char from_ucs4[][2] = + /* 0x26256 */ "\x00\x00", "\x9d\xbc", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2625b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26261 */ "\x94\xfe", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26265 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2626a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26265 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xdb", ++ /* 0x2626b */ "\xa0\xfe", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2626f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26274 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26279 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -14982,8 +15067,32 @@ static const char from_ucs4[][2] = + /* 0x262bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x262c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x262c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x262ce */ "\x00\x00", "\x8e\xc0", +- ++ /* 0x262ce */ "\x00\x00", "\x8e\xc0", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x262fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26300 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26305 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2630a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2630f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26314 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26319 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2631e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26323 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26328 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2632d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26332 */ "\x00\x00", "\x00\x00", "\x9f\x47", "\x00\x00", "\x00\x00", ++ /* 0x26337 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2633c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26341 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26346 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xde", ++ /* 0x2634c */ "\xa0\xfb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26351 */ "\x8e\xc3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26355 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2635a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15016,10 +15125,10 @@ static const char from_ucs4[][2] = + /* 0x263e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x263e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x263eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x263f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x263f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x263f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xc2", ++ /* 0x263f5 */ "\x00\x00", "\x00\x00", "\x95\x4c", "\x00\x00", "\x00\x00", + /* 0x263fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x263ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x263ff */ "\x00\x00", "\x00\x00", "\x9b\xfd", "\x00\x00", "\x00\x00", + /* 0x26404 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26409 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2640e */ "\x00\x00", "\x90\xcc", "\x9c\x60", "\x95\x4b", "\x00\x00", +@@ -15033,21 +15142,21 @@ static const char from_ucs4[][2] = + /* 0x26436 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2643b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26440 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26445 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26445 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xfe", + /* 0x2644a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2644f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26454 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26459 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2645e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26463 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26468 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26469 */ "\x9c\x70", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2646d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26472 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26477 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2647c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26481 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26486 */ "\x00\x00", "\x00\x00", "\x8e\xcc", "\x00\x00", "\x00\x00", +- /* 0x2648b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26481 */ "\x00\x00", "\x00\x00", "\x9c\x43", "\x00\x00", "\x00\x00", ++ /* 0x26486 */ "\x00\x00", "\x9c\x47", "\x8e\xcc", "\x00\x00", "\x00\x00", ++ /* 0x2648b */ "\x00\x00", "\x8e\x54", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26490 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26495 */ "\x00\x00", "\x00\x00", "\x8e\xe4", "\x00\x00", "\x00\x00", + /* 0x2649a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15102,13 +15211,13 @@ static const char from_ucs4[][2] = + /* 0x2658f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26594 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26599 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2659e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2659e */ "\x00\x00", "\x95\x5e", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x265a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x265a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x5c", + /* 0x265ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x265b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x265b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x265bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x265bc */ "\x00\x00", "\x00\x00", "\x9c\x4b", "\x00\x00", "\x00\x00", + /* 0x265c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x265c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x265cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15125,33 +15234,33 @@ static const char from_ucs4[][2] = + /* 0x26602 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26607 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2660c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26611 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26612 */ "\x8b\xe1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26616 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2661b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26620 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26626 */ "\x8e\xd9", + + /* 0x266af */ "\x9d\xb4", "\x00\x00", "\x92\x5f", "\x00\x00", "\x00\x00", +- /* 0x266b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x266b3 */ "\x00\x00", "\x9c\x4c", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x266d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x266d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xa1", "\x00\x00", + /* 0x266db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266e5 */ "\x00\x00", "\x00\x00", "\x8e\xdb", "\x00\x00", "\x00\x00", + /* 0x266ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x266f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x266f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x266f9 */ "\x00\x00", "\x00\x00", "\x9c\x56", "\x00\x00", "\x00\x00", + /* 0x266fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26703 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26708 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2670d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26712 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26712 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xa2", "\x00\x00", + /* 0x26717 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2671c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26721 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15177,7 +15286,7 @@ static const char from_ucs4[][2] = + /* 0x26785 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2678a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2678f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26794 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26794 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x5e", + /* 0x26799 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2679e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x267a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15188,87 +15297,144 @@ static const char from_ucs4[][2] = + /* 0x267bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x267c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x267c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x267cc */ "\xa0\xc3", +- +- /* 0x2685e */ "\x9c\x61", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26862 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26867 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2686c */ "\x00\x00", "\x9c\x5f", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26871 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26876 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2687b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26880 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26885 */ "\x00\x00", "\x00\x00", "\xfc\x4d", "\x00\x00", "\x00\x00", +- /* 0x2688a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2688f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x69", "\x00\x00", +- /* 0x26894 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26899 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2689e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x268fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26902 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26907 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2690c */ "\x00\x00", "\xfe\xc7", "\x00\x00", "\x00\x00", "\xfe\xc6", +- +- /* 0x269a8 */ "\x91\x65", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xe7", "\x00\x00", +- /* 0x269b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x54", +- /* 0x269f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x269f7 */ "\x00\x00", "\x00\x00", "\x9c\x6c", "\x00\x00", "\x00\x00", +- /* 0x269fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x5d", +- /* 0x26a2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x6a", +- /* 0x26a42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26a4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x6d", +- /* 0x26a52 */ "\x8e\xf0", ++ /* 0x267cc */ "\xa0\xc3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x267fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26802 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26807 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2680c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26811 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26816 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2681c */ "\x8a\xe6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26820 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26825 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2682a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2682f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26834 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26839 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2683e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26843 */ "\x00\x00", "\x00\x00", "\xa0\xf7", "\x00\x00", "\x00\x00", ++ /* 0x26848 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2684d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26852 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26857 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2685c */ "\x00\x00", "\x9c\x61", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26861 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26866 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2686b */ "\x00\x00", "\x00\x00", "\x9c\x5f", "\x00\x00", "\x00\x00", ++ /* 0x26870 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26875 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2687a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2687f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26884 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x4d", "\x00\x00", ++ /* 0x2688a */ "\x9e\x5b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2688e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x69", ++ /* 0x26893 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26898 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2689d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268c5 */ "\x00\x00", "\x9c\x63", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x268fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26901 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26906 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2690b */ "\x00\x00", "\x00\x00", "\xfe\xc7", "\x00\x00", "\x00\x00", ++ /* 0x26911 */ "\xfe\xc6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26915 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2691a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2691f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26924 */ "\x00\x00", "\x9c\x67", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26929 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2692e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26933 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26939 */ "\x9c\x69", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2693d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26942 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26947 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2694c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xe2", ++ /* 0x26951 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26956 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2695b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26960 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26965 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2696a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2696f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26974 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26979 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2697e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26983 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26988 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2698d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26992 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26997 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2699c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269a6 */ "\x00\x00", "\x91\x65", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xe7", ++ /* 0x269b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269f2 */ "\x8a\x54", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x269f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x6c", "\x00\x00", ++ /* 0x269fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x6e", ++ /* 0x26a2e */ "\xfe\x5d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a32 */ "\x00\x00", "\x9c\x73", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a42 */ "\x95\x6a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26a51 */ "\x95\x6d", "\x8e\xf0", + ++ /* 0x26b05 */ "\x8f\x4d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b0a */ "\x8e\xf6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26b0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\xbc", ++ /* 0x26b13 */ "\x00\x00", "\x8c\xd5", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26b23 */ "\x87\x5e", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b28 */ "\xfb\xda", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15279,27 +15445,27 @@ static const char from_ucs4[][2] = + /* 0x26b4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b50 */ "\x8b\x4c", "\xfd\x75", "\x9b\xdd", "\xfa\xf5", "\x00\x00", + /* 0x26b54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26b59 */ "\x00\x00", "\x9c\x74", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26b72 */ "\x00\x00", "\x00\x00", "\x95\x45", "\x00\x00", "\x00\x00", + /* 0x26b77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26b82 */ "\x96\xc6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26b96 */ "\x8f\x6a", "\x8f\x4e", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26b9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26b9a */ "\x00\x00", "\x00\x00", "\x9c\x78", "\x00\x00", "\x00\x00", + /* 0x26b9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26ba4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26ba9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26bae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfa\x55", + /* 0x26bb3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26bb8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26bbd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26bbd */ "\x00\x00", "\x00\x00", "\x97\xe4", "\x00\x00", "\x00\x00", + /* 0x26bc2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26bc7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26bcc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15325,8 +15491,8 @@ static const char from_ucs4[][2] = + /* 0x26c30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26c3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26c44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26c40 */ "\x96\xfa", "\x8c\xf6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26c44 */ "\x00\x00", "\x8d\x4d", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15345,16 +15511,16 @@ static const char from_ucs4[][2] = + /* 0x26c94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26c9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26ca3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26ca4 */ "\x9c\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26ca8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cb2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xfb", + /* 0x26cb8 */ "\x90\xca", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cbd */ "\x9c\x5b", "\x00\x00", "\x00\x00", "\x97\x4d", "\x00\x00", +- /* 0x26cc1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26cc1 */ "\x00\x00", "\x8e\xd3", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cc6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26ccb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26cd0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26cd1 */ "\x95\x61", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cd5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26cdf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15379,14 +15545,14 @@ static const char from_ucs4[][2] = + /* 0x26d3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26d4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26d4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\x41", "\x00\x00", + /* 0x26d52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d6b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26d70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26d70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xd3", "\x00\x00", + /* 0x26d75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26d7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15398,7 +15564,7 @@ static const char from_ucs4[][2] = + /* 0x26d9d */ "\x00\x00", "\x00\x00", "\xfc\xfd", "\xfd\xab", "\x91\xbd", + /* 0x26da3 */ "\x8f\x4c", "\x96\xc9", "\x8f\x55", "\xfb\xae", "\x95\x6f", + /* 0x26da7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26dac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26dac */ "\x00\x00", "\x9c\x7d", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26db1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26db6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26dbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15414,11 +15580,11 @@ static const char from_ucs4[][2] = + /* 0x26ded */ "\x00\x00", "\x00\x00", "\x96\xcb", "\x00\x00", "\x00\x00", + /* 0x26df2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26df7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26dfc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26dfc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xce", "\x00\x00", + /* 0x26e01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\x56", "\x00\x00", +- /* 0x26e06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26e07 */ "\x9c\xe1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26e10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26e10 */ "\x00\x00", "\x96\xc4", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15441,11 +15607,11 @@ static const char from_ucs4[][2] = + /* 0x26e74 */ "\x00\x00", "\x00\x00", "\x8f\x6b", "\x00\x00", "\x00\x00", + /* 0x26e79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26e84 */ "\x96\xca", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26e88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26e84 */ "\x96\xca", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\xcd", ++ /* 0x26e88 */ "\x00\x00", "\x00\x00", "\x87\x53", "\x00\x00", "\x00\x00", + /* 0x26e8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26e97 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26e97 */ "\x00\x00", "\x8f\x79", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26e9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26ea1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26ea6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15503,7 +15669,7 @@ static const char from_ucs4[][2] = + /* 0x26faa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26faf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26fb4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x26fb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x26fb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xd6", + /* 0x26fbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26fc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x26fc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15532,7 +15698,7 @@ static const char from_ucs4[][2] = + /* 0x2703b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27040 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27045 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2704a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2704b */ "\x9c\xa3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2704f */ "\x00\x00", "\x00\x00", "\x92\x4b", "\x98\x4a", "\x00\x00", + /* 0x27054 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27059 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15544,7 +15710,7 @@ static const char from_ucs4[][2] = + /* 0x27077 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2707c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27081 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27086 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27086 */ "\x00\x00", "\x8f\xa4", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2708b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27090 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27095 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15559,7 +15725,7 @@ static const char from_ucs4[][2] = + /* 0x270c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x270c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x270cd */ "\x8f\xa7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x270d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x270d2 */ "\x87\x54", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x270d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x270db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x270e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15570,7 +15736,7 @@ static const char from_ucs4[][2] = + /* 0x270f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x270fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27103 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27109 */ "\x98\x45", "\x00\x00", "\x00\x00", "\x90\x46", "\x00\x00", ++ /* 0x27109 */ "\x98\x45", "\x00\x00", "\x00\x00", "\x90\x46", "\x8c\xd1", + /* 0x2710d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27112 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27117 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15591,209 +15757,509 @@ static const char from_ucs4[][2] = + /* 0x27162 */ "\x00\x00", "\x9f\x48", "\x92\x47", "\x00\x00", "\x00\x00", + /* 0x27167 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2716c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27171 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xfb", +- +- /* 0x2721b */ "\x95\x71", +- +- /* 0x272e6 */ "\x9c\xac", ++ /* 0x27171 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xfb", "\x00\x00", ++ /* 0x27176 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2717b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27180 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27185 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2718a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2718f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27194 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27199 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2719e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271cb */ "\x00\x00", "\x9c\xa4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x271fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27202 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27207 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2720c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27211 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27216 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x71", ++ /* 0x2721b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27220 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27225 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2722a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2722f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27234 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27239 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2723e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27243 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27248 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2724d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27252 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27257 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2725c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27261 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27267 */ "\x87\x45", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2726b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27270 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27275 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2727a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27280 */ "\x9c\xa6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27285 */ "\x9c\xa7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27289 */ "\x00\x00", "\x9c\xaa", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2728e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27293 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27298 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2729d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272b2 */ "\x9e\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x70", ++ /* 0x272b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272e3 */ "\x00\x00", "\x00\x00", "\x9c\xac", "\x00\x00", "\x00\x00", ++ /* 0x272e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x272fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27301 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27306 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2730b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27310 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27315 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2731a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2731f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27324 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27329 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2732e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27333 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27338 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2733d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27342 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27347 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2734c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27352 */ "\x87\x52", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27356 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2735b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27360 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27365 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2736a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2736f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27374 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27379 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2737e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27383 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27388 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2738d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27392 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27397 */ "\x00\x00", "\x00\x00", "\x8f\xae", "\x00\x00", "\x00\x00", ++ /* 0x2739c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x273fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\x50", "\x00\x00", ++ /* 0x27400 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27405 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2740a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2740f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27414 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27419 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2741e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\x7d", "\x00\x00", ++ /* 0x27423 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27428 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2742d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27432 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27437 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2743c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27441 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27446 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2744b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xb0", ++ /* 0x27450 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27455 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2745a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2745f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27464 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27469 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2746e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27473 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27478 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2747d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27482 */ "\x00\x00", "\x97\xb6", "\x00\x00", "\xa0\xbd", + +- /* 0x2739a */ "\x8f\xae", ++ /* 0x27574 */ "\x8a\xdf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27578 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2757d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27582 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27587 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2758c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27591 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27596 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2759b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275a0 */ "\x00\x00", "\x00\x00", "\x9e\xaa", "\x00\x00", "\x00\x00", ++ /* 0x275a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xbd", "\x00\x00", ++ /* 0x275e1 */ "\x00\x00", "\x00\x00", "\x8f\xbf", "\x00\x00", "\x00\x00", ++ /* 0x275e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x275fa */ "\x00\x00", "\x00\x00", "\x93\x69", "\x9b\xa7", "\x00\x00", ++ /* 0x275ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27604 */ "\x00\x00", "\x00\x00", "\xc8\xa4", "\x00\x00", "\x00\x00", ++ /* 0x27609 */ "\x00\x00", "\x00\x00", "\xfe\xea", "\x00\x00", "\x00\x00", ++ /* 0x2760e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27613 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27618 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2761d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27622 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27627 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2762c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27632 */ "\x9b\xe1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27636 */ "\x00\x00", "\x00\x00", "\x8b\x41", "\x00\x00", "\x00\x00", ++ /* 0x2763b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27640 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27645 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2764a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2764f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27655 */ "\x9d\xb6", "\xa0\xeb", "\x9b\xa3", "\x00\x00", "\x00\x00", ++ /* 0x27659 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2765e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27663 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27668 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2766d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27672 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27677 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2767c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27681 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27686 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2768b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27690 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xa1", "\x00\x00", ++ /* 0x27695 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2769a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2769f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x276fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27703 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27708 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2770d */ "\x00\x00", "\x8f\xc8", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27712 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27717 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2771c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27721 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27726 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2772b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27730 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x89\x4c", ++ /* 0x27736 */ "\x98\x60", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2773a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2773f */ "\x00\x00", "\x94\xc7", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27744 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27749 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2774e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27753 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27758 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2775e */ "\x8b\x58", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27762 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27767 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2776c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27771 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27776 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2777b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27780 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xab", "\x95\xaa", ++ /* 0x27785 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2778a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2778f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27794 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27799 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2779e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x277cc */ "\x9c\xc3", + +- /* 0x27422 */ "\x95\x7d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27426 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2742b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27430 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27435 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2743a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2743f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27444 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27449 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2744e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27453 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27458 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2745d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27462 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27467 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2746c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27471 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27476 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2747b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27480 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xb6", "\x00\x00", +- /* 0x27486 */ "\xa0\xbd", +- +- /* 0x275e0 */ "\x8f\xbd", "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xbf", +- /* 0x275e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x275e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x275ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x275f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x275f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\x69", +- /* 0x275fe */ "\x9b\xa7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27602 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27607 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xea", +- /* 0x2760c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27611 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27616 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2761b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27620 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27625 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2762a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2762f */ "\x00\x00", "\x00\x00", "\x9b\xe1", "\x00\x00", "\x00\x00", +- /* 0x27634 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x41", +- /* 0x27639 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2763e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27643 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27648 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2764d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27652 */ "\x00\x00", "\x00\x00", "\x9d\xb6", "\xa0\xeb", "\x9b\xa3", +- /* 0x27657 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2765c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27661 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27666 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2766b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27670 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27675 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2767a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2767f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27684 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27689 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2768e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27694 */ "\x8b\xa1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27698 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2769d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x276fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27701 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27706 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2770b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xc8", "\x00\x00", +- /* 0x27710 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27715 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2771a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2771f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27724 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27729 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2772e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27733 */ "\x00\x00", "\x89\x4c", "\x98\x60", "\x00\x00", "\x00\x00", +- /* 0x27738 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2773d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x94\xc7", "\x00\x00", +- /* 0x27742 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27747 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2774c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27751 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27756 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2775b */ "\x00\x00", "\x00\x00", "\x8b\x58", "\x00\x00", "\x00\x00", +- /* 0x27760 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27765 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2776a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2776f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27774 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27779 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2777e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27784 */ "\x95\xab", "\x95\xaa", +- +- /* 0x27870 */ "\x93\xd6", +- +- /* 0x27924 */ "\x8f\xd1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27928 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2792d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27932 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27937 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2793c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27941 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27946 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2794b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27950 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27955 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2795a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2795f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27964 */ "\x00\x00", "\x00\x00", "\x99\xd5", +- +- /* 0x27a0e */ "\xfb\xc8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a59 */ "\x8f\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a62 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27a9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27aa3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27aa8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27aad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ab2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ab7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27abd */ "\x8f\xd2", "\x90\x64", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ac1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ac6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27acb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ad0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ad5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ada */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27adf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ae4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27ae9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27aee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27af4 */ "\x98\xb6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27af8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27afd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b16 */ "\x00\x00", "\x98\xbd", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27b34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xdc", "\xfe\xf6", +- /* 0x27b3a */ "\x8f\xd9", ++ /* 0x27858 */ "\x9c\xc4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2785c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27861 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27866 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2786b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xd6", ++ /* 0x27870 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27875 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2787a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2787f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27884 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27889 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2788e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27893 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27898 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xac", ++ /* 0x2789d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278b2 */ "\x8b\xe6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278c5 */ "\x00\x00", "\x00\x00", "\x8a\x71", "\x00\x00", "\x00\x00", ++ /* 0x278ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x278fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27901 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27906 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2790b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27910 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27915 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2791a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2791f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xd1", ++ /* 0x27924 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27929 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2792e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27933 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27938 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2793d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27942 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27947 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2794c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27951 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27956 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2795b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27960 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27965 */ "\x00\x00", "\x99\xd5", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2796a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2796f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27974 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2797a */ "\x90\xf4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2797e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27983 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27988 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2798d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27992 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27997 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2799c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xa3", "\x00\x00", ++ /* 0x279a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xce", ++ /* 0x279dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x279fb */ "\x00\x00", "\x9c\xd4", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xd5", ++ /* 0x27a0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\xc8", "\x00\x00", ++ /* 0x27a0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a3c */ "\x00\x00", "\x9d\xb3", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a50 */ "\x00\x00", "\x00\x00", "\xfc\x70", "\x00\x00", "\x00\x00", ++ /* 0x27a55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xd7", "\x00\x00", ++ /* 0x27a5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a79 */ "\x9b\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a82 */ "\x00\x00", "\xfa\x5b", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27a9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27aa0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27aa5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27aaa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27aaf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ab4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ab9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xd2", "\x90\x64", ++ /* 0x27abe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ac3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ac8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27acd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ad2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ad7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27adc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ae1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ae6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27aeb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27af0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xb6", "\x00\x00", ++ /* 0x27af5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27afa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27aff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b04 */ "\x00\x00", "\x96\x68", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b09 */ "\x00\x00", "\x9c\xd6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xbd", ++ /* 0x27b18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b36 */ "\x00\x00", "\x8f\xdc", "\xfe\xf6", "\x8f\xd9", "\x00\x00", ++ /* 0x27b3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b45 */ "\x00\x00", "\x00\x00", "\x95\x41", "\x00\x00", "\x00\x00", ++ /* 0x27b4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27b63 */ "\x00\x00", "\x87\xca", + ++ /* 0x27bef */ "\x87\x6c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27bf4 */ "\x97\xf3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27bf8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27bfd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27c02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27c07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27c0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27c12 */ "\x9b\xf8", +- ++ /* 0x27c12 */ "\x9b\xf8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c1b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c20 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c2a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c2f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c39 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c3e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c43 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c48 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c4d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c52 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c57 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c5c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c61 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c66 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c6c */ "\x87\x5a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c70 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c75 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c7a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c7f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c84 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c89 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c8e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c93 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c98 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27c9d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ca2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ca7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x48", ++ /* 0x27cb1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cb6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x4a", ++ /* 0x27cc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ccf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cde */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ce3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ce8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ced */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cf2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cf7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27cfc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d15 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d24 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d2f */ "\x9e\x6c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d33 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15805,13 +16271,13 @@ static const char from_ucs4[][2] = + /* 0x27d56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27d65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d66 */ "\x9c\xd7", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\x6e", "\x00\x00", + /* 0x27d74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x27d83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27d84 */ "\x8a\x40", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d8d */ "\x00\x00", "\x8f\xef", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27d92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15853,121 +16319,191 @@ static const char from_ucs4[][2] = + /* 0x27e46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x27e4b */ "\x00\x00", "\x98\x6a", "\x00\x00", "\x97\xcf", + +- /* 0x28002 */ "\x90\x41", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28006 */ "\x00\x00", "\x00\x00", "\x9c\xdb", ++ /* 0x27f2e */ "\x9e\xe5", + +- /* 0x280bd */ "\x8b\x62", "\x8a\x4e", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x66", +- /* 0x280e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280f4 */ "\x9c\xfb", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x280fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28102 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28107 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2810c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28111 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28116 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2811b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28120 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28125 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2812a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xfc", "\x00\x00", +- /* 0x2812f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28134 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28139 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2813e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28143 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28148 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2814d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28152 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28157 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2815c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28161 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28166 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2816b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xe5", +- +- /* 0x28207 */ "\x8b\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2820b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28210 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28215 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2821a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2821f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28224 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28229 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2822e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28233 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28238 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2823d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28242 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28247 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2824c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28251 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x61", +- /* 0x28256 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2825b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28260 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28265 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2826a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2826f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28274 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28279 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2827e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28283 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28288 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2828d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28292 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28297 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2829c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xa2", "\x00\x00", +- /* 0x282ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xf2", +- /* 0x282e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x282fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28300 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28305 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2830a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2830f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28314 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28319 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2831e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28323 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28328 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2832d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28332 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28337 */ "\x00\x00", "\x00\x00", "\x8e\xca", "\x00\x00", "\x00\x00", +- /* 0x2833c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28341 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28346 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2834b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28350 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28355 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2835a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2835f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28365 */ "\x90\x4e", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28369 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2836e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28373 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28378 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9f\xf5", ++ /* 0x27ff9 */ "\x9e\x7c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x27ffd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x41", ++ /* 0x28002 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28007 */ "\x00\x00", "\x9c\xdb", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2800c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28011 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28016 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2801b */ "\x00\x00", "\x00\x00", "\x94\x41", "\x00\x00", "\x00\x00", ++ /* 0x28020 */ "\x00\x00", "\x00\x00", "\x9c\xe6", "\x9d\xb0", "\x00\x00", ++ /* 0x28025 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2802a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2802f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28034 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28039 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2803e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28043 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xea", ++ /* 0x28048 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2804d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28052 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28057 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2805c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28061 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28066 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2806b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28070 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28075 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2807a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2807f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xed", "\x00\x00", ++ /* 0x28084 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28089 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2808e */ "\x00\x00", "\x9c\xfa", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28093 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28098 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2809d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280bb */ "\x00\x00", "\x8b\x62", "\x8a\x4e", "\x00\x00", "\x00\x00", ++ /* 0x280c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xca", ++ /* 0x280e9 */ "\x8a\x66", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280f2 */ "\x00\x00", "\x9c\xfb", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x280fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28101 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28106 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2810b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28110 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28115 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2811a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2811f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28124 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28129 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xfc", ++ /* 0x2812e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28133 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28138 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2813d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28142 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28147 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2814c */ "\x00\x00", "\x00\x00", "\x9c\xfe", "\x00\x00", "\x00\x00", ++ /* 0x28151 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28156 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2815b */ "\x00\x00", "\x8a\x53", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28160 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28165 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2816a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xe5", ++ /* 0x2816f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28174 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28179 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2817e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28183 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28189 */ "\x9d\x40", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2818d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28192 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28197 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2819c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x41", "\x00\x00", ++ /* 0x281b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281ba */ "\x00\x00", "\x90\x45", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x281fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28200 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28205 */ "\x00\x00", "\x8b\x73", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2820a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2820f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28214 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xca", "\x00\x00", ++ /* 0x2821a */ "\x9d\x42", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2821e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28223 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28228 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2822d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28232 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28237 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2823c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28241 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28246 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2824b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28250 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28256 */ "\x8a\x61", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2825a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2825f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28264 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28269 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2826e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28273 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28278 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xae", "\x00\x00", ++ /* 0x2827d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28282 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28287 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2828c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28291 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28296 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xd2", ++ /* 0x2829b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xa2", ++ /* 0x282cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282e2 */ "\x9d\xf2", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x282ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28304 */ "\x00\x00", "\x9d\x43", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28309 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2830e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28313 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xdf", ++ /* 0x28318 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2831d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28322 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28327 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2832c */ "\x00\x00", "\x00\x00", "\x9d\x44", "\x00\x00", "\x00\x00", ++ /* 0x28331 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28336 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xca", "\x00\x00", ++ /* 0x2833b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28340 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28345 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2834a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2834f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28354 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28359 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2835e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28363 */ "\x00\x00", "\x90\x4e", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28368 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xb3", ++ /* 0x2836d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28372 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28377 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2837d */ "\x9f\xf5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28381 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28386 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x45", + + /* 0x28412 */ "\x90\x4f", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x28416 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -15986,73 +16522,143 @@ static const char from_ucs4[][2] = + /* 0x28457 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2845c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x28461 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28466 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2846b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28470 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28466 */ "\x00\x00", "\x9d\x47", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2846c */ "\x89\xca", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28470 */ "\x00\x00", "\x00\x00", "\x9c\xb5", "\x00\x00", "\x00\x00", + /* 0x28475 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2847a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2847f */ "\x00\x00", "\x00\x00", "\xfb\xfe", +- +- /* 0x2853c */ "\x90\x63", "\x90\x57", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28540 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28545 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2854a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2854f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28554 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28559 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2855e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28563 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28568 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x66", +- +- /* 0x285f4 */ "\xfc\xe5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x285f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x285fd */ "\x00\x00", "\x00\x00", "\x91\x62", "\x00\x00", "\x00\x00", +- /* 0x28602 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28607 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x67", "\x00\x00", +- /* 0x2860c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28611 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28616 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2861b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28620 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xa1", +- /* 0x28625 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2862a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2862f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28634 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28639 */ "\x00\x00", "\x8f\xa2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2863e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28643 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28648 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2864d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28652 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28657 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2865c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28661 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28666 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2866b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28670 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28675 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2867a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2867f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28684 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28689 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2868e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28693 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28698 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2869d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286a7 */ "\x00\x00", "\x00\x00", "\x9d\x48", "\xfa\xd3", "\x00\x00", +- /* 0x286ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xb9", "\x00\x00", +- /* 0x286d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x286e3 */ "\x00\x00", "\x00\x00", "\x90\x6b", ++ /* 0x2847f */ "\x00\x00", "\x00\x00", "\xfb\xfe", "\x00\x00", "\x00\x00", ++ /* 0x28484 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28489 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2848e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28493 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28498 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2849d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x284fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x5e", ++ /* 0x28501 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28506 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2850b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28510 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28515 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2851a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2851f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28524 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28529 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2852e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28533 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28538 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x63", "\x90\x57", ++ /* 0x2853d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28542 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28547 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2854c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28551 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28556 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2855b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28560 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28565 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2856a */ "\x00\x00", "\x90\x66", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2856f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28574 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28579 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2857e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28583 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28588 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2858d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28592 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28597 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2859c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285e8 */ "\x9b\xc0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285f1 */ "\x00\x00", "\x00\x00", "\xfc\xe5", "\x00\x00", "\x00\x00", ++ /* 0x285f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x285fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x62", ++ /* 0x28600 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28605 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2860b */ "\x90\x67", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2860f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28614 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28619 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2861e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28623 */ "\x00\x00", "\x8f\xa1", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28628 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2862d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28632 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28637 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xa2", "\x00\x00", ++ /* 0x2863c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28641 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28646 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2864b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28650 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28655 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2865a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2865f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28664 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28669 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2866e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28673 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28678 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2867d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28682 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28687 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2868c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28691 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28696 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2869b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x48", ++ /* 0x286ab */ "\xfa\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286af */ "\x00\x00", "\x00\x00", "\x8d\x4f", "\x00\x00", "\x00\x00", ++ /* 0x286b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286b9 */ "\x00\x00", "\x00\x00", "\x90\x5d", "\x00\x00", "\x00\x00", ++ /* 0x286be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286d8 */ "\x90\xb9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x6b", ++ /* 0x286e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x286ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28704 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28709 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2870f */ "\x8c\x5c", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x69", + + /* 0x28804 */ "\xfe\x57", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x28808 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -16063,574 +16669,941 @@ static const char from_ucs4[][2] = + /* 0x28821 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x28826 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x55", + +- /* 0x28933 */ "\x90\x73", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28937 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2893c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28941 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28946 */ "\x00\x00", "\x9b\xef", "\x9c\xf0", "\x00\x00", "\x00\x00", +- /* 0x2894b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28950 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28955 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2895a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2895f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28964 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28969 */ "\x00\x00", "\x00\x00", "\x91\xe0", "\x00\x00", "\x00\x00", +- /* 0x2896e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28973 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28978 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2897e */ "\x91\xd8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28982 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28987 */ "\x00\x00", "\x96\x46", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2898c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28991 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28996 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2899b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289a5 */ "\x00\x00", "\x00\x00", "\x93\x60", "\x00\x00", "\xfa\x53", +- /* 0x289ab */ "\x9c\xd3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289b9 */ "\x00\x00", "\x00\x00", "\xfb\x40", "\x00\x00", "\x00\x00", +- /* 0x289be */ "\x00\x00", "\x8d\xe2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x94\x42", +- /* 0x289dc */ "\x00\x00", "\x90\x56", "\x00\x00", "\x00\x00", "\x98\x65", +- /* 0x289e1 */ "\x00\x00", "\x00\x00", "\xfa\x4a", "\x00\x00", "\x00\x00", +- /* 0x289e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xaf", "\x97\x5a", +- /* 0x289fb */ "\x93\x49", "\x97\x47", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x289ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a0f */ "\xa0\xf4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a13 */ "\x00\x00", "\x00\x00", "\x97\x78", "\x00\x00", "\x00\x00", +- /* 0x28a18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a22 */ "\x00\x00", "\x00\x00", "\x8f\xcf", "\x00\x00", "\x00\x00", +- /* 0x28a27 */ "\x00\x00", "\xfc\x60", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xdc", "\x96\x61", +- /* 0x28a46 */ "\x92\xec", "\x93\x5d", "\x8e\xde", "\x96\xfe", "\xfd\x4f", +- /* 0x28a4b */ "\x95\xde", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x98\xb0", +- /* 0x28a5a */ "\xa0\x40", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xbd", +- /* 0x28a82 */ "\x97\x7d", "\x97\xf5", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xac", +- /* 0x28a9b */ "\xfa\xda", "\x92\xc2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28a9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28aa4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28aa9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28aae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ab3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ab8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28abd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ac2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x7b", "\x00\x00", +- /* 0x28ac7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xfe", "\x94\x7b", +- /* 0x28acc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ad1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ad6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28adb */ "\x00\x00", "\x00\x00", "\xfa\xbe", "\xfd\x43", "\x90\xc6", +- /* 0x28ae1 */ "\x90\xa4", "\x90\xa8", "\x94\xa9", "\x00\x00", "\x90\xa9", +- /* 0x28ae5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28aea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28aef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28af4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28af9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28afe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x7d", "\x00\x00", +- /* 0x28b0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfd\xba", +- /* 0x28b22 */ "\x93\xc4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xed", +- /* 0x28b2c */ "\x9d\xab", "\xa0\xe3", "\x00\x00", "\x96\x48", "\x00\x00", +- /* 0x28b30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b49 */ "\x00\x00", "\x00\x00", "\x8a\xa9", "\x00\x00", "\x9b\xc5", +- /* 0x28b4e */ "\x00\x00", "\x96\x5d", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b63 */ "\x97\x5f", "\x96\x5f", "\x96\x6e", "\xfb\x5d", "\x00\x00", +- /* 0x28b67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xb1", +- /* 0x28b6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xa3", +- /* 0x28b8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28b94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\xb2", +- /* 0x28b99 */ "\x00\x00", "\x00\x00", "\x95\xae", "\xfc\xa3", "\x00\x00", +- /* 0x28b9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ba3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ba8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bb2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bbc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bc2 */ "\xa0\xa2", "\x00\x00", "\x00\x00", "\x96\x55", "\x00\x00", +- /* 0x28bc6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bcb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bd0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bd5 */ "\x00\x00", "\x93\x41", "\x00\x00", "\x95\xad", "\x91\xd5", +- /* 0x28bda */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bdf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28be4 */ "\x00\x00", "\x00\x00", "\x97\x7a", "\xfd\xfc", "\x8e\x47", +- /* 0x28bea */ "\x93\xfd", "\x90\xa5", "\x90\xac", "\x00\x00", "\x00\x00", +- /* 0x28bee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bf3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bf8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28bfd */ "\x00\x00", "\x90\xae", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c02 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c07 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c0c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c11 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c16 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c1b */ "\x00\x00", "\x95\xe2", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c20 */ "\x00\x00", "\x00\x00", "\x94\x66", "\x00\x00", "\x00\x00", +- /* 0x28c25 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c2b */ "\x91\xb8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c30 */ "\x9c\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28c34 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xad", ++ /* 0x2890d */ "\x87\xa6", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28911 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28916 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2891b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28920 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28925 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2892a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2892f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x73", "\x00\x00", ++ /* 0x28934 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28939 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2893e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28943 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9b\xef", ++ /* 0x28949 */ "\x9c\xf0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2894d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28952 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x4b", "\x00\x00", ++ /* 0x28957 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2895c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28961 */ "\x00\x00", "\x00\x00", "\xfe\xd9", "\x00\x00", "\x00\x00", ++ /* 0x28966 */ "\x00\x00", "\xfe\xda", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2896c */ "\x91\xe0", "\x8d\x43", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28970 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28975 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2897a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xd8", "\x00\x00", ++ /* 0x2897f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28984 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\x46", ++ /* 0x28989 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2898e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28993 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28998 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2899d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289a8 */ "\x93\x60", "\x00\x00", "\xfa\x53", "\x9c\xd3", "\x00\x00", ++ /* 0x289ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289b6 */ "\x00\x00", "\x9d\x4e", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289bc */ "\xfb\x40", "\x00\x00", "\x00\x00", "\x00\x00", "\x8d\xe2", ++ /* 0x289c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289d9 */ "\x00\x00", "\x00\x00", "\x94\x42", "\x00\x00", "\x90\x56", ++ /* 0x289de */ "\x00\x00", "\x00\x00", "\x98\x65", "\x00\x00", "\x8c\x6c", ++ /* 0x289e4 */ "\xfa\x4a", "\x00\x00", "\x00\x00", "\x9d\x50", "\x9d\x52", ++ /* 0x289e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x289f7 */ "\x00\x00", "\x95\xaf", "\x97\x5a", "\x93\x49", "\x97\x47", ++ /* 0x289fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a01 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a06 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a0b */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xf4", "\x00\x00", ++ /* 0x28a10 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a16 */ "\x97\x78", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a1a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a1f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a25 */ "\x8f\xcf", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x60", ++ /* 0x28a29 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a2e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\x4e", "\x00\x00", ++ /* 0x28a33 */ "\x00\x00", "\x00\x00", "\xfc\x56", "\x00\x00", "\x00\x00", ++ /* 0x28a38 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a3d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a42 */ "\x00\x00", "\x91\xdc", "\x96\x61", "\x92\xec", "\x93\x5d", ++ /* 0x28a48 */ "\x8e\xde", "\x96\xfe", "\xfd\x4f", "\x95\xde", "\x00\x00", ++ /* 0x28a4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a56 */ "\x00\x00", "\x00\x00", "\x98\xb0", "\xa0\x40", "\x00\x00", ++ /* 0x28a5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a79 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a7e */ "\x00\x00", "\x00\x00", "\x97\xbd", "\x97\x7d", "\x97\xf5", ++ /* 0x28a83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28a97 */ "\x00\x00", "\x00\x00", "\x9b\xac", "\xfa\xda", "\x92\xc2", ++ /* 0x28a9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28aa1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28aa6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28aab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ab0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ab5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28aba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ac0 */ "\x97\xb1", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ac4 */ "\x00\x00", "\x90\x7b", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ac9 */ "\x00\x00", "\x93\xfe", "\x94\x7b", "\x00\x00", "\x97\x77", ++ /* 0x28ace */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ad3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ad8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ade */ "\xfa\xbe", "\xfd\x43", "\x90\xc6", "\x90\xa4", "\x90\xa8", ++ /* 0x28ae3 */ "\x94\xa9", "\x00\x00", "\x90\xa9", "\x00\x00", "\x00\x00", ++ /* 0x28ae7 */ "\x00\x00", "\x00\x00", "\x8c\x65", "\x00\x00", "\x00\x00", ++ /* 0x28aec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28af1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28af6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28afc */ "\x95\xe0", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b0a */ "\x00\x00", "\x90\x7d", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x92\x65", "\x00\x00", ++ /* 0x28b14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b1e */ "\x00\x00", "\x00\x00", "\xfd\xba", "\x93\xc4", "\x00\x00", ++ /* 0x28b23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b28 */ "\x00\x00", "\x00\x00", "\xfe\xed", "\x9d\xab", "\xa0\xe3", ++ /* 0x28b2d */ "\x00\x00", "\x96\x48", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x53", ++ /* 0x28b46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b4c */ "\x8a\xa9", "\x00\x00", "\x9b\xc5", "\x00\x00", "\x96\x5d", ++ /* 0x28b50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\x5f", "\x96\x5f", ++ /* 0x28b65 */ "\x96\x6e", "\xfb\x5d", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b69 */ "\x00\x00", "\x00\x00", "\x9d\xb1", "\x00\x00", "\x00\x00", ++ /* 0x28b6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b8c */ "\x00\x00", "\x00\x00", "\xfe\xa3", "\x00\x00", "\x00\x00", ++ /* 0x28b91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28b96 */ "\x00\x00", "\x00\x00", "\x9d\xb2", "\x00\x00", "\x00\x00", ++ /* 0x28b9c */ "\x95\xae", "\xfc\xa3", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ba0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ba5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28baa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28baf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bb4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x69", ++ /* 0x28bb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xa2", "\x00\x00", ++ /* 0x28bc3 */ "\x00\x00", "\x96\x55", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bcd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bd2 */ "\x00\x00", "\x9d\x54", "\x00\x00", "\x00\x00", "\x93\x41", ++ /* 0x28bd7 */ "\x00\x00", "\x95\xad", "\x91\xd5", "\x00\x00", "\x00\x00", ++ /* 0x28bdc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28be1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28be7 */ "\x97\x7a", "\xfd\xfc", "\x8e\x47", "\x93\xfd", "\x90\xa5", ++ /* 0x28bec */ "\x90\xac", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bf0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xac", ++ /* 0x28bf5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28bfa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xae", ++ /* 0x28bff */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xa5", "\x00\x00", ++ /* 0x28c04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x56", ++ /* 0x28c09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28c0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28c13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28c18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xe3", "\x95\xe2", ++ /* 0x28c1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28c23 */ "\x94\x66", "\x00\x00", "\x00\x00", "\x96\x47", "\x00\x00", ++ /* 0x28c27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xb8", "\x00\x00", ++ /* 0x28c2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xec", "\x00\x00", ++ /* 0x28c31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28c36 */ "\x00\x00", "\x00\x00", "\x90\xad", "\x00\x00", "\x95\xe3", + +- /* 0x28ccd */ "\x8a\xe3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cd1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cd6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cdb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ce0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ce5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cf4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cf9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28cfe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28d30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xea", ++ /* 0x28cca */ "\x8b\x4f", "\x00\x00", "\x00\x00", "\x8a\xe3", "\x00\x00", ++ /* 0x28cce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x4d", "\x00\x00", ++ /* 0x28cd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28cd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28cdd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ce2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ce7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28cec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28cf1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28cf6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28cfb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d05 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d32 */ "\x00\x00", "\x95\xea", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28d96 */ "\x00\x00", "\x00\x00", "\x8b\x4e", "\x00\x00", "\x00\x00", ++ /* 0x28d9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28da0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28da5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28daa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28daf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28db4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xc1", ++ /* 0x28db9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dbe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dc3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dc8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dcd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dd2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dd7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ddc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28de1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28de6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28deb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28df0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28df5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dfa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28dff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e0f */ "\x8b\xed", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e22 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xd9", ++ /* 0x28e36 */ "\x00\x00", "\x00\x00", "\xa0\xa4", "\x00\x00", "\x00\x00", ++ /* 0x28e3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e63 */ "\x00\x00", "\x95\xf5", "\x95\xf4", "\x00\x00", "\x00\x00", ++ /* 0x28e68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e95 */ "\x00\x00", "\x9f\xb3", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28e9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ea4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ea9 */ "\x00\x00", "\x00\x00", "\xfe\xaf", "\x00\x00", "\x00\x00", ++ /* 0x28eae */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x72", "\x92\x7a", ++ /* 0x28eb3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28eb8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ebd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ec2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ec7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ecc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ed1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ed6 */ "\x00\x00", "\x00\x00", "\xfe\xac", "\x00\x00", "\x00\x00", ++ /* 0x28edb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ee0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x28ee5 */ "\x00\x00", "\x95\xf3", + +- /* 0x28e36 */ "\x91\xd9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e4e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e53 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e58 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e5d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e62 */ "\x00\x00", "\x00\x00", "\x95\xf5", "\x95\xf4", "\x00\x00", +- /* 0x28e67 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e6c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e71 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e76 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e7b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e80 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e85 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e8a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e8f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e94 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e99 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28e9e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ea3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ea8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ead */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\x72", +- /* 0x28eb3 */ "\x92\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28eb7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ebc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ec1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ec6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ecb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ed0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x28ed5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xac", ++ /* 0x28fc5 */ "\x9d\x58", + +- /* 0x2908b */ "\x91\xc5", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2908f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29094 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29099 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2909e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290ad */ "\x00\x00", "\x90\xcd", "\x95\xfe", "\x91\x59", "\x00\x00", +- /* 0x290b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x97\xcc", +- /* 0x290e5 */ "\x90\xce", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x290fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29102 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29107 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2910d */ "\xfe\xfd", "\x00\x00", "\x00\x00", "\x9d\x5b", ++ /* 0x29079 */ "\x8d\x46", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2907d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29082 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29088 */ "\x93\x72", "\x00\x00", "\x00\x00", "\x91\xc5", "\x00\x00", ++ /* 0x2908c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29091 */ "\x00\x00", "\x96\x42", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29096 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2909b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xcd", ++ /* 0x290b0 */ "\x95\xfe", "\x91\x59", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290be */ "\x00\x00", "\x9c\x65", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290e1 */ "\x00\x00", "\x00\x00", "\x97\xcc", "\x90\xce", "\x00\x00", ++ /* 0x290e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290ec */ "\x9d\x59", "\xfc\xf5", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x290ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29104 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29109 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfe\xfd", "\x00\x00", ++ /* 0x2910e */ "\x00\x00", "\x9d\x5b", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29113 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29118 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2911d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29122 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29127 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2912c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29131 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29136 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2913c */ "\x9d\x5c", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29140 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29145 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2914a */ "\x00\x00", "\x00\x00", "\x93\x7e", "\x00\x00", "\x00\x00", ++ /* 0x2914f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29154 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29159 */ "\x00\x00", "\x98\xac", "\x00\x00", "\x00\x00", "\x9d\x5e", ++ /* 0x2915e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29163 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29168 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2916d */ "\x00\x00", "\x00\x00", "\xfd\xd0", "\x00\x00", "\x00\x00", ++ /* 0x29172 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29177 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2917c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29181 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29186 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2918b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29190 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29195 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2919a */ "\x00\x00", "\xfd\x60", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2919f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xcf", "\x00\x00", ++ /* 0x291a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xdd", "\x00\x00", ++ /* 0x291d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x291eb */ "\x90\xe0", + +- /* 0x2919c */ "\xfd\x60", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291a5 */ "\x00\x00", "\x00\x00", "\x9c\xcf", "\x00\x00", "\x00\x00", +- /* 0x291aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x291e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\xe0", +- +- /* 0x2941d */ "\x90\xf3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2941d */ "\x90\xf3", "\x00\x00", "\x00\x00", "\x98\xb1", "\x00\x00", + /* 0x29421 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29426 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2942b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29430 */ "\x00\x00", "\x00\x00", "\x90\xf0", "\x00\x00", "\x00\x00", + /* 0x29435 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2943a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2943a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xbd", + /* 0x2943f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29444 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x95\xb7", + +- /* 0x294d9 */ "\x8e\x4b", "\x96\x58", ++ /* 0x294d0 */ "\x9f\x46", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x294d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\x4b", ++ /* 0x294da */ "\x96\x58", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x294de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x294e3 */ "\x00\x00", "\x8a\x4c", "\x00\x00", "\x9d\x63", + + /* 0x2959e */ "\x9e\xcf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x295ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x295ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x65", "\x00\x00", + /* 0x295b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x295b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x295b6 */ "\x00\x00", "\x9d\x66", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x295d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x295d4 */ "\x00\x00", "\x00\x00", "\x96\x5a", "\x00\x00", "\x00\x00", + /* 0x295d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x295e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x295e9 */ "\x9d\x64", ++ /* 0x295e9 */ "\x9d\x64", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x295ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x295f2 */ "\x00\x00", "\x8a\x6c", ++ ++ /* 0x29720 */ "\x8a\xd9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29724 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29729 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2972e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x67", + +- /* 0x29857 */ "\x91\x50", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2985b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29860 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29865 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2986a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2986f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29874 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29879 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2987e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29883 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29888 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2988d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29892 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29897 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2989c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298a1 */ "\x00\x00", "\x00\x00", "\x9c\xc1", "\x00\x00", "\x00\x00", +- /* 0x298a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298e7 */ "\x00\x00", "\x00\x00", "\x93\xa7", "\x00\x00", "\x00\x00", +- /* 0x298ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x298fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29900 */ "\x00\x00", "\x00\x00", "\xa0\xef", "\x00\x00", "\x91\x51", +- /* 0x29905 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2990a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2990f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29914 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29919 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2991e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29923 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29928 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2992d */ "\x00\x00", "\x96\xc1", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29932 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29937 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2993c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29941 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29946 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2994b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29950 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29955 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2995a */ "\x00\x00", "\x00\x00", "\xfc\xa4", "\x00\x00", "\x00\x00", +- /* 0x2995f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29964 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2996a */ "\x9d\x6a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2996e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29973 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29978 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2997d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29982 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29987 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2998c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29991 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29996 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2999b */ "\x00\x00", "\x92\x4e", ++ /* 0x297d4 */ "\x8a\x70", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297ec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297f1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297f6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x297fb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29800 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29805 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2980a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29810 */ "\x8b\xf3", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29814 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29819 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2981e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29823 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29828 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2982d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29832 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29837 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2983c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29841 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29846 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2984b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29850 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29855 */ "\x00\x00", "\x91\x50", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2985a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2985f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29864 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29869 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2986e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29873 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29878 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2987d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29882 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29887 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2988c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29891 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29896 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2989b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xc1", "\x00\x00", ++ /* 0x298a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298aa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298b4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x68", "\x00\x00", ++ /* 0x298d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298dc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xa7", "\x00\x00", ++ /* 0x298eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298f1 */ "\x96\x74", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8c\xfd", ++ /* 0x298fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x298ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\xef", "\x00\x00", ++ /* 0x29905 */ "\x91\x51", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29909 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2990e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29913 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29918 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2991d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29922 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29927 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2992c */ "\x00\x00", "\x00\x00", "\x96\xc1", "\x00\x00", "\x00\x00", ++ /* 0x29931 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29936 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2993b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29940 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x87\x77", ++ /* 0x29945 */ "\x00\x00", "\x8c\x64", "\x96\x76", "\x9d\x69", "\x00\x00", ++ /* 0x2994a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2994f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29954 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29959 */ "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\xa4", "\x00\x00", ++ /* 0x2995e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29963 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29968 */ "\x00\x00", "\x9d\x6a", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2996d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29972 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29977 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2997c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29981 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29986 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2998b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29990 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29995 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2999a */ "\x00\x00", "\x00\x00", "\x92\x4e", "\x00\x00", "\x00\x00", ++ /* 0x2999f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299b3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299b8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299c3 */ "\x9d\x6b", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299c7 */ "\x00\x00", "\x9b\xc1", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x299fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a21 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a26 */ "\x00\x00", "\x9d\x6c", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a30 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a35 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a3a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a3f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a44 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29a49 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\x65", + + /* 0x29b05 */ "\x91\x5d", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29b09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x6d", + + /* 0x29bd5 */ "\x91\x5a", + +- /* 0x29cad */ "\x9c\xc0", ++ /* 0x29c73 */ "\x8c\x42", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29c9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ca4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ca9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xc0", + + /* 0x29d3e */ "\x91\x6a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d42 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d47 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d4c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d51 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29d56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29d56 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9d\x6e", "\x00\x00", + /* 0x29d5b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d60 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d65 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d6a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d6f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x29d74 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29d79 */ "\x00\x00", "\x00\x00", "\x9e\xa6", +- +- /* 0x29e2d */ "\x96\xb4", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e31 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e36 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e3b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e40 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e45 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e4a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e4f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e54 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e59 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e5e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e63 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x72", +- /* 0x29e68 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e6d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e72 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e77 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e7c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e81 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e86 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e8b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e90 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e95 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e9a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29e9f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ea4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ea9 */ "\x00\x00", "\x00\x00", "\x9e\xc8", "\x00\x00", "\x00\x00", +- /* 0x29eae */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29eb3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29eb8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ebd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ec3 */ "\x8b\x55", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ec7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ecc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ed1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ed6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29edb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ee0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ee5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29eea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29eef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ef4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29ef9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29efe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f03 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f08 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f0d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f12 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f17 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f1c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f21 */ "\x00\x00", "\x9d\x72", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f26 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x29f2b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xcc", +- +- /* 0x29fb7 */ "\x91\x74", +- +- /* 0x2a0e1 */ "\x91\x77", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a0e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a0ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a0ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xc0", "\x00\x00", +- /* 0x2a0f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8f\xb1", "\x00\x00", +- /* 0x2a0f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xb7", +- /* 0x2a0fe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a103 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a108 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a10d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a112 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a117 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a11c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a121 */ "\x00\x00", "\x91\x78", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a126 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a12b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a130 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a135 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a13a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a13f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a144 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a149 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a14e */ "\x00\x00", "\xfb\x77", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a153 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a158 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a15d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a162 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a167 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a16c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a171 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a176 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a17b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a180 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a185 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a18a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a18f */ "\x00\x00", "\x00\x00", "\x91\x75", "\x91\xa3", "\x00\x00", +- /* 0x2a194 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a199 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a19e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1cb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1d0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1d5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1da */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x79", +- /* 0x2a1df */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1e4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1e9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1ee */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1f3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1f8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a1fd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a202 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a207 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a20c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a211 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a216 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a21b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xa4", +- /* 0x2a220 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a225 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a22a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a22f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xa6", "\x00\x00", +- /* 0x2a234 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a239 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a23e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a243 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a248 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a24d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a252 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a257 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a25c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a261 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a266 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a26b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a270 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a275 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a27a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a27f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a284 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a289 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a28e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a293 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a298 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a29d */ "\x00\x00", "\x90\x52", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2b2 */ "\xa0\x45", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2a2df */ "\x9c\xdd", ++ /* 0x29d79 */ "\x00\x00", "\x00\x00", "\x9e\xa6", "\x00\x00", "\x00\x00", ++ /* 0x29d7e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29d83 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29d88 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29d8d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29d92 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29d98 */ "\x9d\xcd", "\x00\x00", "\x00\x00", "\x9d\x6f", "\x00\x00", ++ /* 0x29d9c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29da1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29da6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29db0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29db5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dbf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dc4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dc9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dd3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dd8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ddd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29de2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29de7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dec */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29df1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x89\xbb", ++ /* 0x29df6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29dfb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e00 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e06 */ "\x9e\xf9", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e0a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e0f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e14 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e19 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e1e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e23 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e28 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xb4", ++ /* 0x29e2d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e32 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e37 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e3c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e41 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e46 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e4b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e50 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e55 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e5a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e5f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e64 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x72", "\x00\x00", ++ /* 0x29e69 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e6e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e73 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e78 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e7d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e82 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e87 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e8c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e91 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e96 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29e9b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ea0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ea5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29eaa */ "\x00\x00", "\x9e\xc8", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29eb0 */ "\x87\x71", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29eb4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29eb9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ebe */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x55", ++ /* 0x29ec3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ec8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ecd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ed2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ed7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29edc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ee1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ee6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29eeb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ef0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ef5 */ "\x00\x00", "\x00\x00", "\x9d\x71", "\x00\x00", "\x00\x00", ++ /* 0x29efa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29eff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f04 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f09 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f0e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f13 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f18 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f1d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f23 */ "\x9d\x72", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f27 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29f2c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xcc", + ++ /* 0x29fb7 */ "\x91\x74", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fbb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fc0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fc5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fcf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fd4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fd9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x9e\xd0", ++ /* 0x29fde */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fe3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fe8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29fed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ff2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ff7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x29ffc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a001 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a006 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a00b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a010 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x5c", "\x00\x00", ++ /* 0x2a015 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a01a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a01f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a024 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a029 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a02e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a033 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a038 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a03d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a042 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a047 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a04c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a051 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a056 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a05b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a060 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a065 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a06a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a06f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a074 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a079 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a07e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a083 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8e\xd2", "\x00\x00", ++ /* 0x2a088 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a08d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a092 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a097 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a09c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\xa8", "\x00\x00", ++ /* 0x2a0ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0ce */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0d3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0d8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0dd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x77", "\x00\x00", ++ /* 0x2a0e2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0e7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0ed */ "\x96\xbf", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0f1 */ "\x00\x00", "\x96\xc0", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0f6 */ "\x00\x00", "\x8f\xb1", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a0fb */ "\x00\x00", "\x00\x00", "\x96\xb7", "\x00\x00", "\x00\x00", ++ /* 0x2a100 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a105 */ "\x00\x00", "\x8c\x55", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a10a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a10f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a114 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a119 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a11e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x91\x78", ++ /* 0x2a123 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a128 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a12d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a133 */ "\x89\xbe", "\x91\x7c", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a137 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a13c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a141 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a146 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a14b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfb\x77", ++ /* 0x2a150 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a155 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a15a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a15f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a164 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a169 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a16e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a173 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a178 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a17d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a182 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a187 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a18c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a192 */ "\x91\x75", "\x91\xa3", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a196 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a19b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1a0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1a5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1ab */ "\x91\x76", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1af */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xbe", ++ /* 0x2a1b5 */ "\x8d\x49", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1b9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1be */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1c3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1c8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1cd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1d2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1d7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1dc */ "\x00\x00", "\x00\x00", "\x91\x79", "\x00\x00", "\x00\x00", ++ /* 0x2a1e1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1e6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1eb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1f0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x96\xb6", ++ /* 0x2a1f5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1fa */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a1ff */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a204 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a209 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a20e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a213 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a218 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a21d */ "\x00\x00", "\x00\x00", "\x91\xa4", "\x00\x00", "\x00\x00", ++ /* 0x2a222 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a227 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a22c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a231 */ "\x00\x00", "\x91\xa6", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a236 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a23b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a240 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a245 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a24a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a24f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a254 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a259 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a25e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a263 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a268 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a26d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a272 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a277 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a27c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a281 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a286 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a28b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a290 */ "\x00\x00", "\x00\x00", "\x9d\x75", "\x00\x00", "\x00\x00", ++ /* 0x2a295 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a29a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x90\x52", ++ /* 0x2a29f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2a4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2a9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2ae */ "\x00\x00", "\x00\x00", "\x00\x00", "\xa0\x45", "\x00\x00", ++ /* 0x2a2b4 */ "\x91\xa9", "\x00\x00", "\x98\xaa", "\x00\x00", "\x00\x00", ++ /* 0x2a2b8 */ "\x00\x00", "\x8c\x5f", "\x00\x00", "\x00\x00", "\x8b\xaa", ++ /* 0x2a2bd */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2c2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2c7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2cc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2d1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2d6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2db */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\xdd", "\x00\x00", ++ /* 0x2a2e0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2e5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2ea */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2ef */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2f4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2f9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a2ff */ "\x9d\x77", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a303 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a308 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a30d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a312 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a317 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a31c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a321 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a326 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a32b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a330 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a335 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a33a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a33f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a344 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a349 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a34e */ "\x00\x00", "\x00\x00", "\x87\x56", "\x00\x00", "\x00\x00", ++ /* 0x2a353 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a358 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a35d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a362 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a367 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a36c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a371 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a376 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a37b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a380 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a385 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a38a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a38f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a394 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a399 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a39e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a3a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2a3a9 */ "\x89\x40", + +- /* 0x2a5c6 */ "\x94\x78", ++ /* 0x2a434 */ "\x9e\xec", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a438 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a43d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a442 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a447 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a44c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a451 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a456 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x93\xaa", + +- /* 0x2a6a9 */ "\x9e\x75", ++ /* 0x2a5c6 */ "\x94\x78", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5cb */ "\x9d\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5cf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5d4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5d9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5de */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5e3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5e8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5ed */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5f2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5f7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a5fc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xc9", ++ /* 0x2a601 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a606 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a60b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a610 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a615 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a61a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a61f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a624 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a629 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a62e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\x4b", "\x00\x00", ++ /* 0x2a633 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a638 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a63d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a642 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a647 */ "\x00\x00", "\x00\x00", "\x9f\xec", "\x00\x00", "\x00\x00", ++ /* 0x2a64c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a651 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a656 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x8a\xe2", ++ /* 0x2a65b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a660 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a665 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a66a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a66f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a674 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a679 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a67e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a683 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a688 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a68d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a692 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a697 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a69c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a6a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2a6a6 */ "\x00\x00", "\x00\x00", "\x9e\x75", + +- /* 0x2f840 */ "\xa0\x47", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f844 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f849 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f84e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f853 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f858 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f85d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f862 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f867 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f86c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f871 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f876 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f87b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f880 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f885 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f88a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f88f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x48", +- /* 0x2f894 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f899 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f89e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8a3 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8a8 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8ad */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8b2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8b7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8bc */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8c1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8c6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f8cb */ "\x00\x00", "\x9c\x52", ++ /* 0x2adff */ "\x87\xdc", ++ ++ /* 0x2f825 */ "\x98\x74", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f829 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f82e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f833 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f838 */ "\x00\x00", "\x00\x00", "\x9a\xc8", "\x00\x00", "\x00\x00", ++ /* 0x2f83d */ "\x00\x00", "\x00\x00", "\xa0\x47", "\x00\x00", "\x00\x00", ++ /* 0x2f842 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f847 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f84c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f851 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f856 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f85b */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f860 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f865 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f86a */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f86f */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f874 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x8b\xc3", "\x00\x00", ++ /* 0x2f879 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f87e */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f883 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f888 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f88d */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f892 */ "\x00\x00", "\xfc\x48", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f897 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f89c */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8a1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\xfc\x77", ++ /* 0x2f8a6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8ab */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8b0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8b5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8ba */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8bf */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8c4 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f8c9 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x9c\x52", + + /* 0x2f994 */ "\x8e\xfd", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f998 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -16638,9 +17611,9 @@ static const char from_ucs4[][2] = + /* 0x2f9a2 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f9a7 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f9ac */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f9b1 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f9b2 */ "\x8f\xa8", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f9b6 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +- /* 0x2f9bb */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", ++ /* 0x2f9bc */ "\x95\x7a", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f9c0 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f9c5 */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", + /* 0x2f9ca */ "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", "\x00\x00", +@@ -16693,105 +17666,70 @@ static struct + { 0x1ebe, 0x1ec1, 761 }, + { 0x2013, 0x203e, 765 }, + { 0x2103, 0x22bf, 809 }, +- { 0x2460, 0x247d, 1254 }, +- { 0x2500, 0x2642, 1284 }, +- { 0x273d, 0x273d, 1607 }, +- { 0x2e80, 0x2f33, 1608 }, +- { 0x3000, 0x3129, 1788 }, +- { 0x3231, 0x32a3, 2086 }, +- { 0x338e, 0x9fa5, 2201 }, +- { 0xe003, 0xe9cb, 29873 }, +- { 0xeaa9, 0xeeb7, 32378 }, +- { 0xf303, 0xf572, 33417 }, +- { 0xf6b0, 0xf6b0, 34041 }, +- { 0xf7e5, 0xf7ee, 34042 }, +- { 0xfa0c, 0xfa0d, 34052 }, +- { 0xfe30, 0xfe6b, 34054 }, +- { 0xff01, 0xffed, 34114 }, +- { 0x2003e, 0x20068, 34351 }, +- { 0x200ee, 0x20118, 34394 }, +- { 0x201ab, 0x20630, 34437 }, +- { 0x2070e, 0x20779, 35595 }, +- { 0x2082c, 0x20873, 35703 }, +- { 0x20916, 0x20979, 35775 }, +- { 0x20a11, 0x20ab4, 35875 }, +- { 0x20b8f, 0x214fd, 36039 }, +- { 0x21596, 0x21a4b, 38454 }, +- { 0x21b44, 0x21b44, 39660 }, +- { 0x21ca2, 0x21ca5, 39661 }, +- { 0x21d46, 0x21ed5, 39665 }, +- { 0x21f6a, 0x21fa1, 40065 }, +- { 0x22049, 0x221c3, 40121 }, +- { 0x2227c, 0x2227c, 40500 }, +- { 0x22321, 0x22325, 40501 }, +- { 0x223bd, 0x223d0, 40506 }, +- { 0x22465, 0x2248b, 40526 }, +- { 0x22513, 0x22980, 40565 }, +- { 0x22acf, 0x22e78, 41699 }, +- { 0x22fe3, 0x2330a, 42637 }, +- { 0x233b4, 0x237d7, 43445 }, +- { 0x23adb, 0x23b5a, 44505 }, +- { 0x23c99, 0x24578, 44633 }, +- { 0x2462a, 0x2478f, 46905 }, +- { 0x24823, 0x24823, 47263 }, +- { 0x248f3, 0x24ae2, 47264 }, +- { 0x24b6e, 0x24b6e, 47760 }, +- { 0x24bf5, 0x24c09, 47761 }, +- { 0x24c9e, 0x24d06, 47782 }, +- { 0x24db8, 0x24e50, 47887 }, +- { 0x24f0e, 0x24fc2, 48040 }, +- { 0x2509d, 0x2509d, 48221 }, +- { 0x25148, 0x25221, 48222 }, +- { 0x252c7, 0x25313, 48440 }, +- { 0x25425, 0x2546e, 48517 }, +- { 0x2555b, 0x259ac, 48591 }, +- { 0x25a9c, 0x25ae9, 49697 }, +- { 0x25b74, 0x25d43, 49775 }, +- { 0x25e0e, 0x25f4b, 50239 }, +- { 0x25fe1, 0x262d0, 50557 }, +- { 0x26351, 0x26626, 51309 }, +- { 0x266af, 0x267cc, 52035 }, +- { 0x2685e, 0x26911, 52321 }, +- { 0x269a8, 0x26a52, 52501 }, +- { 0x26b0a, 0x27175, 52672 }, +- { 0x2721b, 0x2721b, 54316 }, +- { 0x272e6, 0x272e6, 54317 }, +- { 0x2739a, 0x2739a, 54318 }, +- { 0x27422, 0x27486, 54319 }, +- { 0x275e0, 0x27785, 54420 }, +- { 0x27870, 0x27870, 54842 }, +- { 0x27924, 0x27967, 54843 }, +- { 0x27a0e, 0x27b3a, 54911 }, +- { 0x27bf4, 0x27c12, 55212 }, +- { 0x27d2f, 0x27e4f, 55243 }, +- { 0x28002, 0x28009, 55532 }, +- { 0x280bd, 0x2816f, 55540 }, +- { 0x28207, 0x2837d, 55719 }, +- { 0x28412, 0x28482, 56094 }, +- { 0x2853c, 0x2856c, 56207 }, +- { 0x285f4, 0x286e6, 56256 }, +- { 0x28804, 0x2882b, 56499 }, +- { 0x28933, 0x28c39, 56539 }, +- { 0x28ccd, 0x28d34, 57314 }, +- { 0x28e36, 0x28ed9, 57418 }, +- { 0x2908b, 0x29110, 57582 }, +- { 0x2919c, 0x291eb, 57716 }, +- { 0x2941d, 0x29448, 57796 }, +- { 0x294d9, 0x294da, 57840 }, +- { 0x2959e, 0x295e9, 57842 }, +- { 0x29857, 0x2999d, 57918 }, +- { 0x29b05, 0x29b0e, 58245 }, +- { 0x29bd5, 0x29bd5, 58255 }, +- { 0x29cad, 0x29cad, 58256 }, +- { 0x29d3e, 0x29d7c, 58257 }, +- { 0x29e2d, 0x29f30, 58320 }, +- { 0x29fb7, 0x29fb7, 58580 }, +- { 0x2a0e1, 0x2a2df, 58581 }, +- { 0x2a3a9, 0x2a3a9, 59092 }, +- { 0x2a5c6, 0x2a5c6, 59093 }, +- { 0x2a6a9, 0x2a6a9, 59094 }, +- { 0x2f840, 0x2f8cd, 59095 }, +- { 0x2f994, 0x2f9d4, 59237 } ++ { 0x23da, 0x23db, 1254 }, ++ { 0x2460, 0x247d, 1256 }, ++ { 0x2500, 0x2642, 1286 }, ++ { 0x273d, 0x273d, 1609 }, ++ { 0x2e80, 0x2f33, 1610 }, ++ { 0x3000, 0x3129, 1790 }, ++ { 0x31c0, 0x32a3, 2088 }, ++ { 0x338e, 0x9fcb, 2316 }, ++ { 0xf907, 0xf907, 30026 }, ++ { 0xfa0c, 0xfa0d, 30027 }, ++ { 0xfe30, 0xfe6b, 30029 }, ++ { 0xff01, 0xffed, 30089 }, ++ { 0x20021, 0x20118, 30326 }, ++ { 0x201a4, 0x20676, 30574 }, ++ { 0x2070e, 0x20779, 31809 }, ++ { 0x2082c, 0x20b0d, 31917 }, ++ { 0x20b8f, 0x21a63, 32655 }, ++ { 0x21b44, 0x21cac, 36452 }, ++ { 0x21d46, 0x2227c, 36813 }, ++ { 0x22321, 0x22325, 38148 }, ++ { 0x223bd, 0x22993, 38153 }, ++ { 0x22a66, 0x22eef, 39648 }, ++ { 0x22f74, 0x2331f, 40810 }, ++ { 0x233b4, 0x2383a, 41750 }, ++ { 0x239c2, 0x239c2, 42909 }, ++ { 0x23aa7, 0x23b5a, 42910 }, ++ { 0x23c63, 0x24b6e, 43090 }, ++ { 0x24bf5, 0x24c09, 46942 }, ++ { 0x24c9e, 0x24d13, 46963 }, ++ { 0x24db8, 0x2509d, 47081 }, ++ { 0x2512b, 0x25313, 47823 }, ++ { 0x25419, 0x2549a, 48312 }, ++ { 0x25531, 0x259cc, 48442 }, ++ { 0x25a54, 0x25ae9, 49622 }, ++ { 0x25b74, 0x25f4b, 49772 }, ++ { 0x25fe1, 0x26626, 50756 }, ++ { 0x266af, 0x26a52, 52362 }, ++ { 0x26b05, 0x27486, 53294 }, ++ { 0x27574, 0x277cc, 55728 }, ++ { 0x27858, 0x27b65, 56329 }, ++ { 0x27bef, 0x27e4f, 57111 }, ++ { 0x27f2e, 0x27f2e, 57720 }, ++ { 0x27ff9, 0x2838a, 57721 }, ++ { 0x28412, 0x28713, 58635 }, ++ { 0x28804, 0x2882b, 59405 }, ++ { 0x2890d, 0x28c3b, 59445 }, ++ { 0x28cca, 0x28ee7, 60260 }, ++ { 0x28fc5, 0x28fc5, 60802 }, ++ { 0x29079, 0x291eb, 60803 }, ++ { 0x2941d, 0x29448, 61174 }, ++ { 0x294d0, 0x294e7, 61218 }, ++ { 0x2959e, 0x295f4, 61242 }, ++ { 0x29720, 0x29732, 61329 }, ++ { 0x297d4, 0x29a4d, 61348 }, ++ { 0x29b05, 0x29b0e, 61982 }, ++ { 0x29bd5, 0x29bd5, 61992 }, ++ { 0x29c73, 0x29cad, 61993 }, ++ { 0x29d3e, 0x29f30, 62052 }, ++ { 0x29fb7, 0x2a3a9, 62551 }, ++ { 0x2a434, 0x2a45b, 63562 }, ++ { 0x2a5c6, 0x2a6a9, 63602 }, ++ { 0x2adff, 0x2adff, 63830 }, ++ { 0x2f825, 0x2f8cd, 63831 }, ++ { 0x2f994, 0x2f9d4, 64000 } + }; + + /* Definitions used in the body of the `gconv' function. */ +@@ -16800,57 +17738,168 @@ static struct + #define TO_LOOP to_big5hkscs + #define DEFINE_INIT 1 + #define DEFINE_FINI 1 +-#define MIN_NEEDED_FROM 1 +-#define MAX_NEEDED_FROM 2 +-#define MIN_NEEDED_TO 4 ++#define FROM_LOOP_MIN_NEEDED_FROM 1 ++#define FROM_LOOP_MAX_NEEDED_FROM 2 ++#define FROM_LOOP_MIN_NEEDED_TO 4 ++#define FROM_LOOP_MAX_NEEDED_TO 8 ++#define TO_LOOP_MIN_NEEDED_FROM 4 ++#define TO_LOOP_MAX_NEEDED_FROM 4 ++#define TO_LOOP_MIN_NEEDED_TO 1 ++#define TO_LOOP_MAX_NEEDED_TO 2 ++#define PREPARE_LOOP \ ++ int saved_state; \ ++ int *statep = &data->__statep->__count; ++#define EXTRA_LOOP_ARGS , statep ++ ++ ++/* Since we might have to reset input pointer we must be able to save ++ and restore the state. */ ++#define SAVE_RESET_STATE(Save) \ ++ if (Save) \ ++ saved_state = *statep; \ ++ else \ ++ *statep = saved_state ++ ++ ++/* During BIG5-HKSCS to UCS-4 conversion, the COUNT element of the state ++ contains the last UCS-4 character, shifted by 3 bits. ++ During UCS-4 to BIG5-HKSCS conversion, the COUNT element of the state ++ contains the last two bytes to be output, shifted by 3 bits. */ ++ ++/* Since this is a stateful encoding we have to provide code which resets ++ the output state to the initial state. This has to be done during the ++ flushing. */ ++#define EMIT_SHIFT_TO_INIT \ ++ if (data->__statep->__count != 0) \ ++ { \ ++ if (FROM_DIRECTION) \ ++ { \ ++ if (__builtin_expect (outbuf + 4 <= outend, 1)) \ ++ { \ ++ /* Write out the last character. */ \ ++ *((uint32_t *) outbuf) = data->__statep->__count >> 3; \ ++ outbuf += sizeof (uint32_t); \ ++ data->__statep->__count = 0; \ ++ } \ ++ else \ ++ /* We don't have enough room in the output buffer. */ \ ++ status = __GCONV_FULL_OUTPUT; \ ++ } \ ++ else \ ++ { \ ++ if (__builtin_expect (outbuf + 2 <= outend, 1)) \ ++ { \ ++ /* Write out the last character. */ \ ++ uint32_t lasttwo = data->__statep->__count >> 3; \ ++ *outbuf++ = (lasttwo >> 8) & 0xff; \ ++ *outbuf++ = lasttwo & 0xff; \ ++ data->__statep->__count = 0; \ ++ } \ ++ else \ ++ /* We don't have enough room in the output buffer. */ \ ++ status = __GCONV_FULL_OUTPUT; \ ++ } \ ++ } + + + /* First define the conversion function from Big5 to UCS4. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define MIN_NEEDED_INPUT FROM_LOOP_MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT FROM_LOOP_MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT FROM_LOOP_MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT FROM_LOOP_MAX_NEEDED_TO + #define LOOPFCT FROM_LOOP + #define BODY \ + { \ +- uint32_t ch = *inptr; \ ++ uint32_t ch; \ + \ +- if (ch >= 0x81 && ch <= 0xfe) \ ++ /* Determine whether there is a buffered character pending. */ \ ++ ch = *statep >> 3; \ ++ if (__builtin_expect (ch == 0, 1)) \ + { \ +- /* Two-byte character. First test whether the next byte \ +- is also available. */ \ +- uint32_t ch2; \ +- int idx; \ ++ /* No - so look at the next input byte. */ \ ++ ch = *inptr; \ + \ +- if (__builtin_expect (inptr + 1 >= inend, 0)) \ ++ if (ch >= 0x81 && ch <= 0xfe) \ + { \ +- /* The second character is not available. */ \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ ++ /* Two-byte character. First test whether the next byte \ ++ is also available. */ \ ++ uint32_t ch2; \ ++ int idx; \ + \ +- ch2 = inptr[1]; \ +- /* See whether the second byte is in the correct range. */ \ +- if (ch < 0x88 || ch2 < 0x40 || ch2 > 0xfe \ +- || (idx = (ch - 0x88) * 195 + ch2 - 0x40, \ +- (ch = big5hkscs_to_ucs[idx]) == 0)) \ ++ if (__builtin_expect (inptr + 1 >= inend, 0)) \ ++ { \ ++ /* The second character is not available. */ \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ ch2 = inptr[1]; \ ++ idx = (ch - 0x87) * 195 + ch2 - 0x40; \ ++ /* See whether the second byte is in the correct range. */ \ ++ if (ch < 0x87 || ch2 < 0x40 || ch2 > 0xfe \ ++ || (ch = big5hkscs_to_ucs[idx]) == 0) \ ++ { \ ++ /* Check for special cases: combining characters. */ \ ++ if (idx == 195 + 0x22 /* 8862 */) \ ++ { \ ++ ch = 0xca; \ ++ ch2 = 0x304; \ ++ } \ ++ else if (idx == 195 + 0x24 /* 8864 */) \ ++ { \ ++ ch = 0xca; \ ++ ch2 = 0x30c; \ ++ } \ ++ else if (idx == 195 + 0x63 /* 88a3 */) \ ++ { \ ++ ch = 0xea; \ ++ ch2 = 0x304; \ ++ } \ ++ else if (idx == 195 + 0x65 /* 88a5 */) \ ++ { \ ++ ch = 0xea; \ ++ ch2 = 0x30c; \ ++ } \ ++ else \ ++ /* This is illegal. */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (1); \ ++ \ ++ inptr += 2; \ ++ \ ++ put32 (outptr, ch); \ ++ outptr += 4; \ ++ \ ++ /* See whether we have room for two characters. */ \ ++ if (outptr + 4 <= outend) \ ++ { \ ++ put32 (outptr, ch2); \ ++ outptr += 4; \ ++ continue; \ ++ } \ ++ \ ++ /* Otherwise store only the first character now, and \ ++ put the second one into the queue. */ \ ++ *statep = ch2 << 3; \ ++ /* Tell the caller why we terminate the loop. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ ++ inptr += 2; \ ++ } \ ++ else if (__builtin_expect (ch == 0xff, 0)) \ + { \ +- /* This is illegal. */ \ + STANDARD_FROM_LOOP_ERR_HANDLER (1); \ + } \ +- \ +- inptr += 2; \ +- } \ +- else if (__builtin_expect (ch == 0xff, 0)) \ +- { \ +- STANDARD_FROM_LOOP_ERR_HANDLER (1); \ ++ else \ ++ ++inptr; \ + } \ +- else \ +- ++inptr; \ + \ + put32 (outptr, ch); \ + outptr += 4; \ + } + #define LOOP_NEED_FLAGS ++#define EXTRA_LOOP_DECLS , int *statep + #define ONEBYTE_BODY \ + { \ + if (c <= 0x80) \ +@@ -16862,19 +17911,61 @@ static struct + + + /* Next, define the other direction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_INPUT TO_LOOP_MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT TO_LOOP_MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT TO_LOOP_MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT TO_LOOP_MAX_NEEDED_TO + #define LOOPFCT TO_LOOP + #define BODY \ + { \ + uint32_t ch = get32 (inptr); \ + \ ++ if ((*statep >> 3) != 0) \ ++ { \ ++ /* Attempt to combine the last character with this one. */ \ ++ uint16_t lasttwo = *statep >> 3; \ ++ \ ++ if (ch == 0x304 && lasttwo == 0x8866) \ ++ ch = 0x8862; \ ++ else if (ch == 0x30c && lasttwo == 0x8866) \ ++ ch = 0x8864; \ ++ else if (ch == 0x304 && lasttwo == 0x88a7) \ ++ ch = 0x88a3; \ ++ else if (ch == 0x30c && lasttwo == 0x88a7) \ ++ ch = 0x88a5; \ ++ else \ ++ goto not_combining; \ ++ \ ++ /* Output the combined character. */ \ ++ if (__builtin_expect (outptr + 1 >= outend, 0)) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ *outptr++ = (ch >> 8) & 0xff; \ ++ *outptr++ = ch & 0xff; \ ++ *statep = 0; \ ++ inptr += 4; \ ++ continue; \ ++ \ ++ not_combining: \ ++ /* Output the buffered character. */ \ ++ if (__builtin_expect (outptr + 1 >= outend, 0)) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ *outptr++ = (lasttwo >> 8) & 0xff; \ ++ *outptr++ = lasttwo & 0xff; \ ++ *statep = 0; \ ++ continue; \ ++ } \ ++ \ + if (ch <= 0x0080) \ + *outptr++ = ch; \ + else \ + { \ +- const char *cp = ""; \ ++ const unsigned char *cp = (const unsigned char *) ""; \ + size_t i; \ + \ + for (i = 0; \ +@@ -16900,6 +17991,14 @@ static struct + } \ + else \ + { \ ++ /* Check for possible combining character. */ \ ++ if (__builtin_expect (ch == 0xca || ch == 0xea, 0)) \ ++ { \ ++ *statep = ((cp[0] << 8) | cp[1]) << 3; \ ++ inptr += 4; \ ++ continue; \ ++ } \ ++ \ + /* See whether there is enough room to write the second byte. */ \ + if (__builtin_expect (cp[1] != '\0', 1) \ + && __builtin_expect (outptr + 1 >= outend, 0)) \ +@@ -16918,6 +18017,7 @@ static struct + inptr += 4; \ + } + #define LOOP_NEED_FLAGS ++#define EXTRA_LOOP_DECLS , int *statep + #include + + +diff --git a/iconvdata/testdata/BIG5HKSCS b/iconvdata/testdata/BIG5HKSCS +index 827e20b..ac76f6e 100644 +--- a/iconvdata/testdata/BIG5HKSCS ++++ b/iconvdata/testdata/BIG5HKSCS +@@ -1,1135 +1,1154 @@ +- ˆ@ ˆ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 ˆ[ ˆ\ ˆ] ˆ^ ˆ_ +- ˆ` ˆ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 ˆ{ ˆ| ˆ} ˆ~ ˆ¡ +- ˆ¢ ˆ£ ˆ¤ ˆ¥ ˆ¦ ˆ§ ˆ¨ ˆ© ˆª ‰@ ‰A ‰C ‰F ‰G ‰H ‰I +- ‰L ‰M ‰N ‰O ‰P ‰Q ‰R ‰S ‰T ‰U ‰V ‰W ‰X ‰Y ‰Z ‰[ +- ‰\ ‰] ‰^ ‰_ ‰` ‰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 ‰{ +- ‰| ‰} ‰~ ‰¡ ‰¢ ‰£ ‰¤ ‰¥ ‰¦ ‰« ‰¬ ‰­ ‰® ‰° ‰± ‰² +- ‰µ ‰¶ ‰· ‰¸ ‰¹ ‰º ‰» ‰¼ ‰½ ‰¾ ‰¿ ‰Á ‰Â ‰Ã ‰Å ‰Æ +- ‰Ç ‰È ‰É ‰Ê ‰Ë ‰Ì ‰Í ‰Î ‰Ï ‰Ð ‰Ñ ‰Ò ‰Ó ‰Ô ‰Õ ‰Ö +- ‰× ‰Ø ‰Ù ‰Ú ‰Û ‰Ü ‰Ý ‰Þ ‰ß ‰à ‰á ‰â ‰ã ‰ä ‰å ‰æ +- ‰ç ‰è ‰é ‰ê ‰ë ‰ì ‰í ‰î ‰ï ‰ð ‰ñ ‰ò ‰ó ‰ô ‰õ ‰ö +- ‰÷ ‰ø ‰ù ‰ú ‰û ‰ü ‰ý ‰þ Š@ ŠA ŠC ŠD ŠE ŠF ŠG ŠH +- ŠI ŠJ ŠK ŠL ŠM ŠN ŠO ŠP ŠQ ŠR ŠS ŠT ŠU ŠV ŠW ŠX +- ŠY ŠZ Š[ Š\ Š] Š^ Š_ Š` Ša Šb Šd Še Šf Šg Šh Ši +- Šj Šk Šl Šm Šn Šo Šp Šq Šr Šs Št Šv Šw Šx Šy Šz +- Š{ Š| Š} Š~ Š¡ Š¢ Š£ Š¤ Š¥ Š¦ Š§ Š¨ Š© Šª Š¬ Š­ +- Š® Š¯ Š° Š² Š³ Š´ Šµ Š¶ Š· Š¸ Š¹ Š» Š¼ Š½ Š¾ Š¿ +- ŠÀ ŠÁ ŠÂ ŠÃ ŠÄ ŠÅ ŠÆ ŠÇ ŠÉ ŠÊ ŠË ŠÌ ŠÎ ŠÏ ŠÐ ŠÑ +- ŠÒ ŠÓ ŠÔ ŠÕ ŠÖ Š× ŠØ ŠÙ ŠÚ ŠÛ ŠÜ Šß Šà Šá Šâ Šã +- Šä Šå Šæ Šç Šè Šé Šê Šë Šì Ší Šî Šï Šð Šñ Šò Šó +- Šô Šö Š÷ Šø Šù Šú Šû Šü Šý Šþ ‹@ ‹A ‹B ‹C ‹D ‹E +- ‹F ‹G ‹H ‹I ‹J ‹K ‹L ‹M ‹N ‹O ‹P ‹Q ‹R ‹S ‹U ‹V +- ‹W ‹X ‹Y ‹Z ‹[ ‹\ ‹] ‹^ ‹_ ‹` ‹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 ‹{ ‹| ‹} ‹~ ‹¡ ‹¢ ‹£ ‹¤ ‹¥ ‹¦ ‹§ ‹¨ +- ‹© ‹ª ‹« ‹¬ ‹­ ‹® ‹¯ ‹° ‹± ‹² ‹³ ‹´ ‹µ ‹¶ ‹· ‹¸ +- ‹¹ ‹º ‹» ‹¼ ‹½ ‹¾ ‹¿ ‹À ‹Á ‹Â ‹Ã ‹Ä ‹Å ‹Æ ‹Ç ‹È +- ‹É ‹Ê ‹Ë ‹Ì ‹Í ‹Î ‹Ï ‹Ð ‹Ñ ‹Ò ‹Ó ‹Ô ‹Õ ‹Ö ‹× ‹Ø +- ‹Ù ‹Ú ‹Û ‹Ü ‹Þ ‹ß ‹à ‹á ‹â ‹ã ‹ä ‹å ‹æ ‹ç ‹è ‹é +- ‹ê ‹ë ‹ì ‹í ‹î ‹ï ‹ð ‹ñ ‹ò ‹ó ‹ô ‹õ ‹ö ‹÷ ‹ù ‹ú +- ‹û ‹ü ‹ý ` 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 { | +- } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® +- ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ +- ¿ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î +- Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ +- ß à á â ã ä å æ ç è é ê ë ì í î +- ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ +- Ž@ Ž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 Ž[ Ž\ Ž] Ž^ Ž_ +- Ž` Ža Žb Žc Žd Že Žf Žg Žh Žj Žk Žl Žm Žn Žp Žq +- Žr Žs Žt Žu Žv Žw Žx Žy Žz Ž{ Ž| Ž} Ž¡ Ž¢ Ž£ Ž¤ +- Ž¥ Ž¦ Ž§ Ž¨ Ž© Žª Ž¬ Ž­ Ž® Ž¯ Ž° Ž± Ž² Ž³ Žµ Ž¶ +- Ž· Ž¸ Ž¹ Žº Ž» Ž¼ Ž½ Ž¾ Ž¿ ŽÀ ŽÁ ŽÂ ŽÃ ŽÄ ŽÅ ŽÆ +- ŽÇ ŽÈ ŽÉ ŽÊ ŽË ŽÌ ŽÎ ŽÏ ŽÑ ŽÒ ŽÓ ŽÔ ŽÕ ŽÖ Ž× ŽØ +- ŽÙ ŽÚ ŽÛ ŽÜ ŽÝ ŽÞ Žß Žà Žá Žâ Žã Žä Žå Žæ Žç Žè +- Žé Žê Žë Žì Ží Žî Žï Žð Žñ Žò Žó Žô Žõ Žö Ž÷ Žø +- Žù Žú Žû Žü Žý Žþ @ A B C D E F G H I +- J K L M N O P Q R S T U V X Y Z +- [ \ ] ^ _ ` a b c d e f g h j k +- l m o p q r s t u v w x y z { | +- } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® +- ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ +- ¿ À Á Â Ã Ä Å Æ Ç È É Ê Í Î Ï Ð +- Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à +- á â ã ä å æ ç è é ê ë ì í î ï ð +- ñ ò ó ô õ ö ÷ ø ù ú û ü ý @ 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 [ \ ] ^ _ ` a b +- c d e f g h i j k l n o p q r s +- t u v w x y { | } ~ ¡ ¢ £ ¤ ¥ ¦ +- § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ +- · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ +- Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö +- × Ø Ù Ú Û Ý Þ ß à á â ã ä å æ ç +- è é ê ë ì í î ï ð ò ó ô õ ö ÷ ø +- ù ú û ü ý þ ‘@ ‘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 ‘[ ‘\ ‘] ‘^ ‘_ ‘` ‘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 ‘{ ‘| ‘} ‘~ ‘¡ ‘¢ ‘£ ‘¤ ‘¥ ‘¦ ‘§ ‘¨ ‘© ‘ª ‘« +- ‘¬ ‘­ ‘® ‘¯ ‘° ‘± ‘² ‘³ ‘´ ‘µ ‘¶ ‘· ‘¸ ‘¹ ‘º ‘» +- ‘¼ ‘½ ‘¾ ‘À ‘Á ‘ ‘à ‘Ä ‘Å ‘Æ ‘Ç ‘È ‘É ‘Ê ‘Ë ‘Ì +- ‘Í ‘Î ‘Ï ‘Ð ‘Ñ ‘Ò ‘Ó ‘Ô ‘Õ ‘Ö ‘× ‘Ø ‘Ù ‘Ú ‘Û ‘Ü +- ‘Ý ‘Þ ‘ß ‘à ‘á ‘â ‘ã ‘ä ‘å ‘æ ‘ç ‘è ‘é ‘ê ‘ë ‘ì +- ‘í ‘î ‘ï ‘ð ‘ñ ‘ò ‘ó ‘ô ‘õ ‘ö ‘÷ ‘ø ‘ù ‘ú ‘û ‘ü +- ‘ý ‘þ ’@ ’A ’B ’C ’E ’F ’G ’H ’I ’J ’K ’L ’M ’N +- ’O ’P ’Q ’R ’S ’T ’U ’V ’W ’X ’Y ’Z ’[ ’\ ’] ’^ +- ’_ ’` ’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 ’{ ’| ’} ’~ +- ’¡ ’¢ ’£ ’¤ ’¥ ’¦ ’§ ’¨ ’© ’ª ’« ’¬ ’­ ’® ’³ ’´ +- ’µ ’¶ ’· ’¸ ’¹ ’º ’» ’¼ ’½ ’¾ ’¿ ’À ’Á ’ ’à ’Ä +- ’Å ’Æ ’Ç ’É ’Ê ’Ë ’Ì ’Í ’Î ’Ï ’Ð ’Ò ’Ó ’Ô ’Õ ’Ö +- ’× ’Ø ’Ù ’Ú ’Û ’Ü ’Ý ’Þ ’ß ’à ’á ’â ’ã ’ä ’å ’æ +- ’ç ’è ’é ’ê ’ë ’ì ’í ’î ’ï ’ð ’ñ ’ò ’ó ’ô ’õ ’ö +- ’÷ ’ø ’ù ’ú ’û ’ü ’ý ’þ “@ “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 “[ “\ “] “^ “_ “` “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 “{ “| “} “~ “¡ “¢ “£ “¤ “¥ “¦ “§ “¨ “© +- “ª “« “¬ “­ “® “¯ “° “± “² “³ “´ “µ “¶ “· “¸ “¹ +- “º “» “¼ “½ “¾ “¿ “À “Á “ “à “Ä “Å “Æ “Ç “È “É +- “Ê “Ë “Ì “Í “Î “Ï “Ð “Ñ “Ò “Ó “Ô “Õ “Ö “× “Ø “Ù +- “Ú “Û “Ü “Ý “Þ “ß “à “á “â “ã “ä “å “æ “ç “è “é +- “ê “ë “ì “í “î “ï “ð “ñ “ò “ó “ô “õ “ö “÷ “ø “ù +- “ú “û “ü “ý “þ ”@ ”A ”B ”C ”D ”E ”F ”H ”I ”J ”K +- ”L ”M ”N ”O ”P ”Q ”R ”S ”T ”U ”V ”W ”X ”Y ”Z ”[ +- ”\ ”] ”^ ”_ ”` ”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 ”{ +- ”| ”} ”~ ”¡ ”¢ ”£ ”¤ ”¥ ”¦ ”§ ”¨ ”© ”ª ”« ”¬ ”­ +- ”® ”¯ ”° ”± ”² ”³ ”´ ”µ ”¶ ”· ”¸ ”¹ ”º ”» ”¼ ”½ +- ”¾ ”¿ ”À ”Á ” ”à ”Ä ”Å ”Æ ”Ç ”È ”É ”Ë ”Ì ”Í ”Î +- ”Ï ”Ð ”Ñ ”Ò ”Ó ”Ô ”Õ ”Ö ”× ”Ø ”Ù ”Ú ”Û ”Ü ”Ý ”Þ +- ”ß ”à ”á ”â ”ã ”ä ”å ”æ ”ç ”è ”é ”ê ”ë ”ì ”í ”î +- ”ï ”ð ”ñ ”ò ”ó ”ô ”õ ”ö ”÷ ”ø ”ù ”ú ”û ”ü ”ý ”þ +- •@ •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 •[ •\ •] •^ •_ +- •` •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 •{ •| •} •~ •¡ +- •¢ •£ •¤ •¥ •¦ •§ •¨ •© •ª •« •¬ •­ •® •¯ •° •± +- •² •³ •´ •µ •¶ •· •¸ •¹ •º •» •¼ •½ •¾ •¿ •À •Á +- •Â •Ã •Ä •Å •Æ •Ç •È •É •Ê •Ë •Ì •Í •Î •Ï •Ð •Ñ +- •Ò •Ó •Ô •Õ •Ö •× •Ø •Ú •Û •Ü •Ý •Þ •ß •à •á •â +- •ã •ä •å •æ •ç •è •é •ê •ë •ì •í •î •ï •ð •ñ •ò +- •ó •ô •õ •ö •÷ •ø •ù •ú •û •ü •ý •þ –@ –A –B –C +- –E –F –G –H –I –J –K –L –M –N –O –P –Q –R –S –T +- –U –V –W –X –Y –Z –[ –\ –] –^ –_ –` –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 –{ –| –} –~ –¡ –¢ –£ –¤ –¥ –¦ +- –§ –¨ –© –ª –« –¬ –­ –® –¯ –° –± –² –³ –´ –µ –¶ +- –· –¸ –¹ –º –» –¼ –½ –¾ –¿ –À –Á – –à –Ä –Å –Æ +- –Ç –È –É –Ê –Ë –Ì –Í –Î –Ï –Ð –Ñ –Ò –Ó –Ô –Õ –Ö +- –× –Ø –Ù –Ú –Û –Ü –Ý –Þ –ß –à –á –â –ã –ä –å –æ +- –ç –è –é –ê –ë –ì –î –ï –ð –ñ –ò –ó –ô –õ –ö –÷ +- –ø –ù –ú –û –ý –þ —@ —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 —[ —\ —] —^ —_ —` —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 —{ —| —} —~ —¡ —¢ —£ —¤ —¥ —¦ —§ —¨ —© —ª —« +- —¬ —­ —® —¯ —° —± —² —³ —´ —µ —¶ —· —¸ —¹ —º —» +- —¼ —½ —¾ —¿ —À —Á — —à —Ä —Å —Æ —Ç —È —É —Ê —Ë +- —Ì —Í —Î —Ï —Ð —Ñ —Ò —Ó —Ô —Õ —Ö —× —Ø —Ù —Ú —Û +- —Ü —Ý —Þ —ß —à —á —â —ã —ä —å —æ —ç —è —é —ê —ë +- —ì —í —î —ï —ð —ñ —ò —ó —ô —õ —ö —÷ —ø —ù —ú —û +- —ü —ý —þ ˜@ ˜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 ˜[ ˜\ +- ˜] ˜^ ˜_ ˜` ˜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 ˜{ ˜| +- ˜} ˜~ ˜¡ ˜¢ ˜£ ˜¤ ˜¥ ˜¦ ˜§ ˜¨ ˜© ˜ª ˜« ˜¬ ˜­ ˜® +- ˜¯ ˜° ˜± ˜² ˜³ ˜´ ˜µ ˜¶ ˜· ˜¸ ˜¹ ˜º ˜» ˜¼ ˜½ ˜¾ +- ˜¿ ˜À ˜Á ˜Â ˜Ã ˜Ä ˜Å ˜Æ ˜Ç ˜È ˜É ˜Ê ˜Ë ˜Ì ˜Í ˜Î +- ˜Ï ˜Ð ˜Ñ ˜Ò ˜Ó ˜Ô ˜Õ ˜Ö ˜× ˜Ø ˜Ù ˜Ú ˜Û ˜Ü ˜Ý ˜Þ +- ˜ß ˜à ˜á ˜â ˜ã ˜ä ˜å ˜æ ˜ç ˜è ˜é ˜ê ˜ë ˜ì ˜í ˜î +- ˜ï ˜ð ˜ñ ˜ò ˜ó ˜ô ˜õ ˜ö ˜÷ ˜ø ˜ù ˜ú ˜û ˜ü ˜ý ˜þ +- ™@ ™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 ™[ ™\ ™] ™^ ™_ +- ™` ™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 ™{ ™| ™} ™~ ™¡ +- ™¢ ™£ ™¤ ™¥ ™¦ ™§ ™¨ ™© ™ª ™« ™¬ ™­ ™® ™¯ ™° ™± +- ™² ™³ ™´ ™µ ™¶ ™· ™¸ ™¹ ™º ™» ™¼ ™½ ™¾ ™¿ ™À ™Á +- ™Â ™Ã ™Ä ™Å ™Æ ™Ç ™È ™É ™Ê ™Ë ™Ì ™Í ™Î ™Ï ™Ð ™Ñ +- ™Ò ™Ó ™Ô ™Õ ™Ö ™× ™Ø ™Ù ™Ú ™Û ™Ü ™Ý ™Þ ™ß ™à ™á +- ™â ™ã ™ä ™å ™æ ™ç ™è ™é ™ê ™ë ™ì ™í ™î ™ï ™ð ™ñ +- ™ò ™ó ™ô ™õ ™ö ™÷ ™ø ™ù ™ú ™û ™ü ™ý ™þ š@ š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 š[ š\ š] š^ š_ š` š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 š{ š| š} š~ š¡ š¢ š£ š¤ +- š¥ š¦ š§ š¨ š© šª š« š¬ š­ š® š¯ š° š± š² š³ š´ +- šµ š¶ š· š¸ š¹ šº š» š¼ š½ š¾ š¿ šÀ šÁ šÂ šÃ šÄ +- šÅ šÆ šÇ šÈ šÉ šÊ šË šÌ šÍ šÎ šÏ šÐ šÑ šÒ šÓ šÔ +- šÕ šÖ š× šØ šÙ šÚ šÛ šÜ šÝ šÞ šß šà šá šâ šã šä +- šå šæ šç šè šé šê šë šì ší šî šï šð šñ šò šó šô +- šõ šö š÷ šø šù šú šû šü šý šþ ›@ ›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 ›[ ›\ ›] ›^ ›_ ›` ›b ›c ›d ›e ›f +- ›g ›h ›i ›j ›k ›l ›m ›n ›o ›p ›q ›r ›s ›t ›u ›w +- ›y ›z ›| ›} ›~ ›¡ ›¢ ›£ ›¤ ›¥ ›¦ ›§ ›¨ ›© ›ª ›« +- ›¬ ›­ ›® ›¯ ›° ›± ›² ›³ ›´ ›µ ›¶ ›· ›¸ ›¹ ›º ›» +- ›¼ ›½ ›¾ ›¿ ›À ›Á ›Â ›Ã ›Ä ›Å ›Ç ›È ›É ›Ê ›Ë ›Ì +- ›Í ›Î ›Ï ›Ð ›Ñ ›Ò ›Ó ›Ô ›Õ ›Ö ›× ›Ø ›Ù ›Ú ›Û ›Ü +- ›Ý ›ß ›à ›á ›â ›ã ›ä ›å ›æ ›ç ›è ›é ›ê ›ë ›í ›î +- ›ï ›ð ›ñ ›ò ›ó ›ô ›õ ›÷ ›ø ›ù ›ú ›û ›ü ›ý ›þ œ@ +- œA œC œD œE œF œG œH œI œJ œK œL œM œN œO œP œQ +- œR œT œU œV œW œX œY œZ œ[ œ\ œ] œ^ œ_ œ` œa œc +- œd œe œf œg œi œj œl œm œn œo œp œq œr œs œt œu +- œv œx œy œz œ{ œ| œ} œ~ œ¡ œ¢ œ£ œ¤ œ¥ œ¦ œ§ œ¨ +- œ© œª œ« œ¬ œ­ œ® œ¯ œ° œ± œ² œ³ œ´ œµ œ¶ œ· œ¸ +- œ¹ œº œ» œ¾ œ¿ œÀ œÁ œÂ œÃ œÄ œÅ œÆ œÇ œÈ œÉ œÊ +- œË œÌ œÍ œÎ œÏ œÑ œÒ œÓ œÔ œÕ œÖ œ× œØ œÙ œÚ œÛ +- œÜ œÝ œÞ œß œà œá œâ œã œä œå œæ œç œè œé œê œë +- œì œí œî œï œð œñ œò œó œô œõ œö œ÷ œø œù œú œû +- œü œý œþ @ A B C D E F G H I J K L +- M N O P Q R S T U V X Y [ \ ] ^ +- _ ` 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 { | } ~ +- ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° +- ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À +- Á Â Ã Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ +- Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á +- â ã ä å æ ç è é ê ë ì í î ï ð ñ +- ò ó ô õ ö ÷ ø ù ú û ü ý þ ž@ ž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 ž[ ž\ ž] ž^ ž_ ž` ž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 ž{ ž| ž} ž~ ž¡ ž¢ ž£ ž¤ +- ž¥ ž¦ ž§ ž¨ žª ž« ž­ ž® ž¯ ž° ž± ž² ž³ ž´ žµ ž¶ +- ž· ž¸ ž¹ žº ž» ž¼ ž½ ž¾ ž¿ žÀ žÁ žÂ žÃ žÅ žÆ žÇ +- žÈ žÉ žÊ žË žÌ žÍ žÎ žÏ žÐ žÑ žÒ žÓ žÔ žÕ žÖ ž× +- žØ žÙ žÚ žÛ žÜ žÝ žÞ žß žà žá žâ žã žä žå žæ žç +- žè žé žê žë žì ží žî žð žñ žò žó žõ žö ž÷ žø žù +- žú žû žü žþ Ÿ@ ŸA ŸB ŸC ŸD ŸE ŸF ŸG ŸH ŸI ŸJ ŸK +- ŸL ŸM ŸO ŸP ŸQ ŸR ŸS ŸT ŸU ŸV ŸW ŸX ŸY ŸZ Ÿ[ Ÿ\ +- Ÿ] Ÿ^ Ÿ_ Ÿa Ÿb Ÿc Ÿd Ÿe Ÿg Ÿh Ÿi Ÿj Ÿk Ÿl Ÿm Ÿn +- Ÿo Ÿp Ÿq Ÿr Ÿs Ÿt Ÿu Ÿv Ÿw Ÿx Ÿy Ÿz Ÿ{ Ÿ| Ÿ} Ÿ~ +- Ÿ¡ Ÿ¢ Ÿ£ Ÿ¤ Ÿ¥ Ÿ¦ Ÿ§ Ÿ¨ Ÿ© Ÿª Ÿ« Ÿ¬ Ÿ® Ÿ¯ Ÿ° Ÿ² +- Ÿ³ Ÿ´ Ÿµ Ÿ¶ Ÿ· Ÿ¸ Ÿ¹ Ÿº Ÿ» Ÿ¼ Ÿ½ Ÿ¾ Ÿ¿ ŸÁ ŸÂ ŸÃ +- ŸÄ ŸÅ ŸÆ ŸÇ ŸÉ ŸÊ ŸÌ ŸÍ ŸÎ ŸÏ ŸÐ ŸÑ ŸÒ ŸÓ ŸÔ ŸÕ +- ŸÖ Ÿ× ŸÙ ŸÛ ŸÜ ŸÝ ŸÞ Ÿß Ÿà Ÿá Ÿâ Ÿã Ÿä Ÿå Ÿç Ÿè +- Ÿé Ÿë Ÿì Ÿí Ÿî Ÿð Ÿñ Ÿò Ÿó Ÿô Ÿõ Ÿö Ÿ÷ Ÿø Ÿù Ÿú +- Ÿû Ÿü Ÿý Ÿþ  @  A  B  C  D  E  F  G  H  I  J  K +-  L  M  N  O  P  Q  R  S  U  V  X  Y  [  \  ]  ^ +-  _  `  a  d  e  f  g  h  i  j  k  l  m  n  o  p +-  q  s  t  u  v  x  y  z  {  |  }  ~  ¡  ¢  £  ¤ +-  ¦  §  ¨  ©  ª  «  ¬  ®  °  ±  ²  ³  ´  µ  ¶  · +-  ¸  ¹  º  »  ¼  ½  ¾  ¿  À  Á  Â  Ã  Ä  Å  Æ  Ç +-  È  É  Ê  Ë  Ì  Í  Î  Ï  Ð  Ñ  Ò  Ô  Ö  ×  Ø  Ù +-  Ú  Û  Ü  Ý  Þ  à  â  ã  å  æ  ç  è  é  ê  ë  ì +-  í  î  ï  ð  ñ  ò  ó  ô  õ  ö  ÷  ø  ù  ú  û  ü +-  ý  þ ¡@ ¡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 ¡[ ¡\ ¡] ¡^ +- ¡_ ¡` ¡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 ¡{ ¡| ¡} ¡~ +- ¡¡ ¡¢ ¡£ ¡¤ ¡¥ ¡¦ ¡§ ¡¨ ¡© ¡ª ¡« ¡¬ ¡­ ¡® ¡¯ ¡° +- ¡± ¡² ¡³ ¡´ ¡µ ¡¶ ¡· ¡¸ ¡¹ ¡º ¡» ¡¼ ¡½ ¡¾ ¡¿ ¡À +- ¡Á ¡Â ¡Ä ¡Æ ¡Ç ¡È ¡É ¡Ê ¡Ë ¡Ì ¡Í ¡Î ¡Ï ¡Ð ¡Ñ ¡Ò +- ¡Ó ¡Ô ¡Õ ¡Ö ¡× ¡Ø ¡Ù ¡Ú ¡Û ¡Ü ¡Ý ¡Þ ¡ß ¡à ¡á ¡â +- ¡ã ¡ä ¡å ¡æ ¡ç ¡è ¡é ¡ê ¡ë ¡ì ¡í ¡î ¡ï ¡ð ¡ñ ¡ò +- ¡ó ¡ô ¡õ ¡ö ¡÷ ¡ø ¡ù ¡ú ¡û ¡ü ¡ý ¢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 ¢[ ¢\ ¢] ¢^ ¢_ ¢` ¢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 ¢{ ¢| ¢} ¢¨ ¢© ¢ª ¢« ¢¬ ¢­ ¢® ¢¯ +- ¢° ¢± ¢² ¢³ ¢´ ¢µ ¢¶ ¢· ¢¸ ¢¹ ¢º ¢» ¢¼ ¢½ ¢¾ ¢¿ +- ¢À ¢Á ¢Â ¢Ã ¢Ä ¢Å ¢Æ ¢Ç ¢È ¢É ¢Ê ¢Ë ¢Í ¢Ï ¢Ð ¢Ñ +- ¢Ò ¢Ó ¢Ô ¢Õ ¢Ö ¢× ¢Ø ¢Ù ¢Ú ¢Û ¢Ü ¢Ý ¢Þ ¢ß ¢à ¢á +- ¢â ¢ã ¢ä ¢å ¢æ ¢ç ¢è ¢é ¢ê ¢ë ¢ì ¢í ¢î ¢ï ¢ð ¢ñ +- ¢ò ¢ó ¢ô ¢õ ¢ö ¢÷ ¢ø ¢ù ¢ú ¢û ¢ü ¢ý ¢þ £@ £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 £[ £\ £] £^ £_ £` £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 £{ £| £} £~ £¡ £¢ ££ £¤ +- £¥ £¦ £§ £¨ £© £ª £« £¬ £­ £® £¯ £° £± £² £³ £´ +- £µ £¶ £· £¸ £¹ £º £» £¼ £½ £¾ £¿ ¤@ ¤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 ¤[ ¤\ ¤] ¤^ ¤_ ¤` ¤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 ¤{ ¤| ¤} ¤~ ¤¡ ¤¢ ¤£ ¤¤ ¤¥ ¤¦ +- ¤§ ¤¨ ¤© ¤ª ¤« ¤¬ ¤­ ¤® ¤¯ ¤° ¤± ¤² ¤³ ¤´ ¤µ ¤¶ +- ¤· ¤¸ ¤¹ ¤º ¤» ¤¼ ¤½ ¤¾ ¤¿ ¤À ¤Á ¤Â ¤Ã ¤Ä ¤Å ¤Æ +- ¤Ç ¤È ¤É ¤Ê ¤Ë ¤Ì ¤Í ¤Î ¤Ï ¤Ð ¤Ñ ¤Ò ¤Ó ¤Ô ¤Õ ¤Ö +- ¤× ¤Ø ¤Ù ¤Ú ¤Û ¤Ü ¤Ý ¤Þ ¤ß ¤à ¤á ¤â ¤ã ¤ä ¤å ¤æ +- ¤ç ¤è ¤é ¤ê ¤ë ¤ì ¤í ¤î ¤ï ¤ð ¤ñ ¤ò ¤ó ¤ô ¤õ ¤ö +- ¤÷ ¤ø ¤ù ¤ú ¤û ¤ü ¤ý ¤þ ¥@ ¥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 ¥[ ¥\ ¥] ¥^ ¥_ ¥` ¥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 ¥{ ¥| ¥} ¥~ ¥¡ ¥¢ ¥£ ¥¤ ¥¥ ¥¦ ¥§ ¥¨ ¥© +- ¥ª ¥« ¥¬ ¥­ ¥® ¥¯ ¥° ¥± ¥² ¥³ ¥´ ¥µ ¥¶ ¥· ¥¸ ¥¹ +- ¥º ¥» ¥¼ ¥½ ¥¾ ¥¿ ¥À ¥Á ¥Â ¥Ã ¥Ä ¥Å ¥Æ ¥Ç ¥È ¥É +- ¥Ê ¥Ë ¥Ì ¥Í ¥Î ¥Ï ¥Ð ¥Ñ ¥Ò ¥Ó ¥Ô ¥Õ ¥Ö ¥× ¥Ø ¥Ù +- ¥Ú ¥Û ¥Ü ¥Ý ¥Þ ¥ß ¥à ¥á ¥â ¥ã ¥ä ¥å ¥æ ¥ç ¥è ¥é +- ¥ê ¥ë ¥ì ¥í ¥î ¥ï ¥ð ¥ñ ¥ò ¥ó ¥ô ¥õ ¥ö ¥÷ ¥ø ¥ù +- ¥ú ¥û ¥ü ¥ý ¥þ ¦@ ¦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 +- ¦[ ¦\ ¦] ¦^ ¦_ ¦` ¦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 +- ¦{ ¦| ¦} ¦~ ¦¡ ¦¢ ¦£ ¦¤ ¦¥ ¦¦ ¦§ ¦¨ ¦© ¦ª ¦« ¦¬ +- ¦­ ¦® ¦¯ ¦° ¦± ¦² ¦³ ¦´ ¦µ ¦¶ ¦· ¦¸ ¦¹ ¦º ¦» ¦¼ +- ¦½ ¦¾ ¦¿ ¦À ¦Á ¦Â ¦Ã ¦Ä ¦Å ¦Æ ¦Ç ¦È ¦É ¦Ê ¦Ë ¦Ì +- ¦Í ¦Î ¦Ï ¦Ð ¦Ñ ¦Ò ¦Ó ¦Ô ¦Õ ¦Ö ¦× ¦Ø ¦Ù ¦Ú ¦Û ¦Ü +- ¦Ý ¦Þ ¦ß ¦à ¦á ¦â ¦ã ¦ä ¦å ¦æ ¦ç ¦è ¦é ¦ê ¦ë ¦ì +- ¦í ¦î ¦ï ¦ð ¦ñ ¦ò ¦ó ¦ô ¦õ ¦ö ¦÷ ¦ø ¦ù ¦ú ¦û ¦ü +- ¦ý ¦þ §@ §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 §[ §\ §] +- §^ §_ §` §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 §{ §| §} +- §~ §¡ §¢ §£ §¤ §¥ §¦ §§ §¨ §© §ª §« §¬ §­ §® §¯ +- §° §± §² §³ §´ §µ §¶ §· §¸ §¹ §º §» §¼ §½ §¾ §¿ +- §À §Á §Â §Ã §Ä §Å §Æ §Ç §È §É §Ê §Ë §Ì §Í §Î §Ï +- §Ð §Ñ §Ò §Ó §Ô §Õ §Ö §× §Ø §Ù §Ú §Û §Ü §Ý §Þ §ß +- §à §á §â §ã §ä §å §æ §ç §è §é §ê §ë §ì §í §î §ï +- §ð §ñ §ò §ó §ô §õ §ö §÷ §ø §ù §ú §û §ü §ý §þ ¨@ +- ¨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 ¨[ ¨\ ¨] ¨^ ¨_ ¨` +- ¨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 ¨{ ¨| ¨} ¨~ ¨¡ ¨¢ +- ¨£ ¨¤ ¨¥ ¨¦ ¨§ ¨¨ ¨© ¨ª ¨« ¨¬ ¨­ ¨® ¨¯ ¨° ¨± ¨² +- ¨³ ¨´ ¨µ ¨¶ ¨· ¨¸ ¨¹ ¨º ¨» ¨¼ ¨½ ¨¾ ¨¿ ¨À ¨Á ¨Â +- ¨Ã ¨Ä ¨Å ¨Æ ¨Ç ¨È ¨É ¨Ê ¨Ë ¨Ì ¨Í ¨Î ¨Ï ¨Ð ¨Ñ ¨Ò +- ¨Ó ¨Ô ¨Õ ¨Ö ¨× ¨Ø ¨Ù ¨Ú ¨Û ¨Ü ¨Ý ¨Þ ¨ß ¨à ¨á ¨â +- ¨ã ¨ä ¨å ¨æ ¨ç ¨è ¨é ¨ê ¨ë ¨ì ¨í ¨î ¨ï ¨ð ¨ñ ¨ò +- ¨ó ¨ô ¨õ ¨ö ¨÷ ¨ø ¨ù ¨ú ¨û ¨ü ¨ý ¨þ ©@ ©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 ©[ ©\ ©] ©^ ©_ ©` ©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 ©{ ©| ©} ©~ ©¡ ©¢ ©£ ©¤ ©¥ +- ©¦ ©§ ©¨ ©© ©ª ©« ©¬ ©­ ©® ©¯ ©° ©± ©² ©³ ©´ ©µ +- ©¶ ©· ©¸ ©¹ ©º ©» ©¼ ©½ ©¾ ©¿ ©À ©Á ©Â ©Ã ©Ä ©Å +- ©Æ ©Ç ©È ©É ©Ê ©Ë ©Ì ©Í ©Î ©Ï ©Ð ©Ñ ©Ò ©Ó ©Ô ©Õ +- ©Ö ©× ©Ø ©Ù ©Ú ©Û ©Ü ©Ý ©Þ ©ß ©à ©á ©â ©ã ©ä ©å +- ©æ ©ç ©è ©é ©ê ©ë ©ì ©í ©î ©ï ©ð ©ñ ©ò ©ó ©ô ©õ +- ©ö ©÷ ©ø ©ù ©ú ©û ©ü ©ý ©þ ª@ ª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 ª[ ª\ ª] ª^ ª_ ª` ª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 ª{ ª| ª} ª~ ª¡ ª¢ ª£ ª¤ ª¥ ª¦ ª§ ª¨ +- ª© ªª ª« ª¬ ª­ ª® ª¯ ª° ª± ª² ª³ ª´ ªµ ª¶ ª· ª¸ +- ª¹ ªº ª» ª¼ ª½ ª¾ ª¿ ªÀ ªÁ ªÂ ªÃ ªÄ ªÅ ªÆ ªÇ ªÈ +- ªÉ ªÊ ªË ªÌ ªÍ ªÎ ªÏ ªÐ ªÑ ªÒ ªÓ ªÔ ªÕ ªÖ ª× ªØ +- ªÙ ªÚ ªÛ ªÜ ªÝ ªÞ ªß ªà ªá ªâ ªã ªä ªå ªæ ªç ªè +- ªé ªê ªë ªì ªí ªî ªï ªð ªñ ªò ªó ªô ªõ ªö ª÷ ªø +- ªù ªú ªû ªü ªý ªþ «@ «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 «[ «\ «] «^ «_ «` «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 «{ «| «} «~ «¡ «¢ «£ «¤ «¥ «¦ «§ «¨ «© «ª «« +- «¬ «­ «® «¯ «° «± «² «³ «´ «µ «¶ «· «¸ «¹ «º «» +- «¼ «½ «¾ «¿ «À «Á «Â «Ã «Ä «Å «Æ «Ç «È «É «Ê «Ë +- «Ì «Í «Î «Ï «Ð «Ñ «Ò «Ó «Ô «Õ «Ö «× «Ø «Ù «Ú «Û +- «Ü «Ý «Þ «ß «à «á «â «ã «ä «å «æ «ç «è «é «ê «ë +- «ì «í «î «ï «ð «ñ «ò «ó «ô «õ «ö «÷ «ø «ù «ú «û +- «ü «ý «þ ¬@ ¬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 ¬[ ¬\ +- ¬] ¬^ ¬_ ¬` ¬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 ¬{ ¬| +- ¬} ¬~ ¬¡ ¬¢ ¬£ ¬¤ ¬¥ ¬¦ ¬§ ¬¨ ¬© ¬ª ¬« ¬¬ ¬­ ¬® +- ¬¯ ¬° ¬± ¬² ¬³ ¬´ ¬µ ¬¶ ¬· ¬¸ ¬¹ ¬º ¬» ¬¼ ¬½ ¬¾ +- ¬¿ ¬À ¬Á ¬Â ¬Ã ¬Ä ¬Å ¬Æ ¬Ç ¬È ¬É ¬Ê ¬Ë ¬Ì ¬Í ¬Î +- ¬Ï ¬Ð ¬Ñ ¬Ò ¬Ó ¬Ô ¬Õ ¬Ö ¬× ¬Ø ¬Ù ¬Ú ¬Û ¬Ü ¬Ý ¬Þ +- ¬ß ¬à ¬á ¬â ¬ã ¬ä ¬å ¬æ ¬ç ¬è ¬é ¬ê ¬ë ¬ì ¬í ¬î +- ¬ï ¬ð ¬ñ ¬ò ¬ó ¬ô ¬õ ¬ö ¬÷ ¬ø ¬ù ¬ú ¬û ¬ü ¬ý ¬þ +- ­@ ­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 ­[ ­\ ­] ­^ ­_ +- ­` ­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 ­{ ­| ­} ­~ ­¡ +- ­¢ ­£ ­¤ ­¥ ­¦ ­§ ­¨ ­© ­ª ­« ­¬ ­­ ­® ­¯ ­° ­± +- ­² ­³ ­´ ­µ ­¶ ­· ­¸ ­¹ ­º ­» ­¼ ­½ ­¾ ­¿ ­À ­Á +- ­Â ­Ã ­Ä ­Å ­Æ ­Ç ­È ­É ­Ê ­Ë ­Ì ­Í ­Î ­Ï ­Ð ­Ñ +- ­Ò ­Ó ­Ô ­Õ ­Ö ­× ­Ø ­Ù ­Ú ­Û ­Ü ­Ý ­Þ ­ß ­à ­á +- ­â ­ã ­ä ­å ­æ ­ç ­è ­é ­ê ­ë ­ì ­í ­î ­ï ­ð ­ñ +- ­ò ­ó ­ô ­õ ­ö ­÷ ­ø ­ù ­ú ­û ­ü ­ý ­þ ®@ ®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 ®[ ®\ ®] ®^ ®_ ®` ®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 ®{ ®| ®} ®~ ®¡ ®¢ ®£ ®¤ +- ®¥ ®¦ ®§ ®¨ ®© ®ª ®« ®¬ ®­ ®® ®¯ ®° ®± ®² ®³ ®´ +- ®µ ®¶ ®· ®¸ ®¹ ®º ®» ®¼ ®½ ®¾ ®¿ ®À ®Á ®Â ®Ã ®Ä +- ®Å ®Æ ®Ç ®È ®É ®Ê ®Ë ®Ì ®Í ®Î ®Ï ®Ð ®Ñ ®Ò ®Ó ®Ô +- ®Õ ®Ö ®× ®Ø ®Ù ®Ú ®Û ®Ü ®Ý ®Þ ®ß ®à ®á ®â ®ã ®ä +- ®å ®æ ®ç ®è ®é ®ê ®ë ®ì ®í ®î ®ï ®ð ®ñ ®ò ®ó ®ô +- ®õ ®ö ®÷ ®ø ®ù ®ú ®û ®ü ®ý ®þ ¯@ ¯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 ¯[ ¯\ ¯] ¯^ ¯_ ¯` ¯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 ¯{ ¯| ¯} ¯~ ¯¡ ¯¢ ¯£ ¯¤ ¯¥ ¯¦ ¯§ +- ¯¨ ¯© ¯ª ¯« ¯¬ ¯­ ¯® ¯¯ ¯° ¯± ¯² ¯³ ¯´ ¯µ ¯¶ ¯· +- ¯¸ ¯¹ ¯º ¯» ¯¼ ¯½ ¯¾ ¯¿ ¯À ¯Á ¯Â ¯Ã ¯Ä ¯Å ¯Æ ¯Ç +- ¯È ¯É ¯Ê ¯Ë ¯Ì ¯Í ¯Î ¯Ï ¯Ð ¯Ñ ¯Ò ¯Ó ¯Ô ¯Õ ¯Ö ¯× +- ¯Ø ¯Ù ¯Ú ¯Û ¯Ü ¯Ý ¯Þ ¯ß ¯à ¯á ¯â ¯ã ¯ä ¯å ¯æ ¯ç +- ¯è ¯é ¯ê ¯ë ¯ì ¯í ¯î ¯ï ¯ð ¯ñ ¯ò ¯ó ¯ô ¯õ ¯ö ¯÷ +- ¯ø ¯ù ¯ú ¯û ¯ü ¯ý ¯þ °@ °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 °[ °\ °] °^ °_ °` °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 °{ °| °} °~ °¡ °¢ °£ °¤ °¥ °¦ °§ °¨ °© °ª +- °« °¬ °­ °® °¯ °° °± °² °³ °´ °µ °¶ °· °¸ °¹ °º +- °» °¼ °½ °¾ °¿ °À °Á °Â °Ã °Ä °Å °Æ °Ç °È °É °Ê +- °Ë °Ì °Í °Î °Ï °Ð °Ñ °Ò °Ó °Ô °Õ °Ö °× °Ø °Ù °Ú +- °Û °Ü °Ý °Þ °ß °à °á °â °ã °ä °å °æ °ç °è °é °ê +- °ë °ì °í °î °ï °ð °ñ °ò °ó °ô °õ °ö °÷ °ø °ù °ú +- °û °ü °ý °þ ±@ ±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 ±[ +- ±\ ±] ±^ ±_ ±` ±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 ±{ +- ±| ±} ±~ ±¡ ±¢ ±£ ±¤ ±¥ ±¦ ±§ ±¨ ±© ±ª ±« ±¬ ±­ +- ±® ±¯ ±° ±± ±² ±³ ±´ ±µ ±¶ ±· ±¸ ±¹ ±º ±» ±¼ ±½ +- ±¾ ±¿ ±À ±Á ±Â ±Ã ±Ä ±Å ±Æ ±Ç ±È ±É ±Ê ±Ë ±Ì ±Í +- ±Î ±Ï ±Ð ±Ñ ±Ò ±Ó ±Ô ±Õ ±Ö ±× ±Ø ±Ù ±Ú ±Û ±Ü ±Ý +- ±Þ ±ß ±à ±á ±â ±ã ±ä ±å ±æ ±ç ±è ±é ±ê ±ë ±ì ±í +- ±î ±ï ±ð ±ñ ±ò ±ó ±ô ±õ ±ö ±÷ ±ø ±ù ±ú ±û ±ü ±ý +- ±þ ²@ ²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 ²[ ²\ ²] ²^ +- ²_ ²` ²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 ²{ ²| ²} ²~ +- ²¡ ²¢ ²£ ²¤ ²¥ ²¦ ²§ ²¨ ²© ²ª ²« ²¬ ²­ ²® ²¯ ²° +- ²± ²² ²³ ²´ ²µ ²¶ ²· ²¸ ²¹ ²º ²» ²¼ ²½ ²¾ ²¿ ²À +- ²Á ²Â ²Ã ²Ä ²Å ²Æ ²Ç ²È ²É ²Ê ²Ë ²Ì ²Í ²Î ²Ï ²Ð +- ²Ñ ²Ò ²Ó ²Ô ²Õ ²Ö ²× ²Ø ²Ù ²Ú ²Û ²Ü ²Ý ²Þ ²ß ²à +- ²á ²â ²ã ²ä ²å ²æ ²ç ²è ²é ²ê ²ë ²ì ²í ²î ²ï ²ð +- ²ñ ²ò ²ó ²ô ²õ ²ö ²÷ ²ø ²ù ²ú ²û ²ü ²ý ²þ ³@ ³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 ³[ ³\ ³] ³^ ³_ ³` ³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 ³{ ³| ³} ³~ ³¡ ³¢ ³£ +- ³¤ ³¥ ³¦ ³§ ³¨ ³© ³ª ³« ³¬ ³­ ³® ³¯ ³° ³± ³² ³³ +- ³´ ³µ ³¶ ³· ³¸ ³¹ ³º ³» ³¼ ³½ ³¾ ³¿ ³À ³Á ³Â ³Ã +- ³Ä ³Å ³Æ ³Ç ³È ³É ³Ê ³Ë ³Ì ³Í ³Î ³Ï ³Ð ³Ñ ³Ò ³Ó +- ³Ô ³Õ ³Ö ³× ³Ø ³Ù ³Ú ³Û ³Ü ³Ý ³Þ ³ß ³à ³á ³â ³ã +- ³ä ³å ³æ ³ç ³è ³é ³ê ³ë ³ì ³í ³î ³ï ³ð ³ñ ³ò ³ó +- ³ô ³õ ³ö ³÷ ³ø ³ù ³ú ³û ³ü ³ý ³þ ´@ ´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 ´[ ´\ ´] ´^ ´_ ´` ´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 ´{ ´| ´} ´~ ´¡ ´¢ ´£ ´¤ ´¥ ´¦ +- ´§ ´¨ ´© ´ª ´« ´¬ ´­ ´® ´¯ ´° ´± ´² ´³ ´´ ´µ ´¶ +- ´· ´¸ ´¹ ´º ´» ´¼ ´½ ´¾ ´¿ ´À ´Á ´Â ´Ã ´Ä ´Å ´Æ +- ´Ç ´È ´É ´Ê ´Ë ´Ì ´Í ´Î ´Ï ´Ð ´Ñ ´Ò ´Ó ´Ô ´Õ ´Ö +- ´× ´Ø ´Ù ´Ú ´Û ´Ü ´Ý ´Þ ´ß ´à ´á ´â ´ã ´ä ´å ´æ +- ´ç ´è ´é ´ê ´ë ´ì ´í ´î ´ï ´ð ´ñ ´ò ´ó ´ô ´õ ´ö +- ´÷ ´ø ´ù ´ú ´û ´ü ´ý ´þ µ@ µ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 µ[ µ\ µ] µ^ µ_ µ` µ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 µ{ µ| µ} µ~ µ¡ µ¢ µ£ µ¤ µ¥ µ¦ µ§ µ¨ µ© +- µª µ« µ¬ µ­ µ® µ¯ µ° µ± µ² µ³ µ´ µµ µ¶ µ· µ¸ µ¹ +- µº µ» µ¼ µ½ µ¾ µ¿ µÀ µÁ µÂ µÃ µÄ µÅ µÆ µÇ µÈ µÉ +- µÊ µË µÌ µÍ µÎ µÏ µÐ µÑ µÒ µÓ µÔ µÕ µÖ µ× µØ µÙ +- µÚ µÛ µÜ µÝ µÞ µß µà µá µâ µã µä µå µæ µç µè µé +- µê µë µì µí µî µï µð µñ µò µó µô µõ µö µ÷ µø µù +- µú µû µü µý µþ ¶@ ¶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 +- ¶[ ¶\ ¶] ¶^ ¶_ ¶` ¶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 +- ¶{ ¶| ¶} ¶~ ¶¡ ¶¢ ¶£ ¶¤ ¶¥ ¶¦ ¶§ ¶¨ ¶© ¶ª ¶« ¶¬ +- ¶­ ¶® ¶¯ ¶° ¶± ¶² ¶³ ¶´ ¶µ ¶¶ ¶· ¶¸ ¶¹ ¶º ¶» ¶¼ +- ¶½ ¶¾ ¶¿ ¶À ¶Á ¶Â ¶Ã ¶Ä ¶Å ¶Æ ¶Ç ¶È ¶É ¶Ê ¶Ë ¶Ì +- ¶Í ¶Î ¶Ï ¶Ð ¶Ñ ¶Ò ¶Ó ¶Ô ¶Õ ¶Ö ¶× ¶Ø ¶Ù ¶Ú ¶Û ¶Ü +- ¶Ý ¶Þ ¶ß ¶à ¶á ¶â ¶ã ¶ä ¶å ¶æ ¶ç ¶è ¶é ¶ê ¶ë ¶ì +- ¶í ¶î ¶ï ¶ð ¶ñ ¶ò ¶ó ¶ô ¶õ ¶ö ¶÷ ¶ø ¶ù ¶ú ¶û ¶ü +- ¶ý ¶þ ·@ ·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 ·[ ·\ ·] +- ·^ ·_ ·` ·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 ·{ ·| ·} +- ·~ ·¡ ·¢ ·£ ·¤ ·¥ ·¦ ·§ ·¨ ·© ·ª ·« ·¬ ·­ ·® ·¯ +- ·° ·± ·² ·³ ·´ ·µ ·¶ ·· ·¸ ·¹ ·º ·» ·¼ ·½ ·¾ ·¿ +- ·À ·Á ·Â ·Ã ·Ä ·Å ·Æ ·Ç ·È ·É ·Ê ·Ë ·Ì ·Í ·Î ·Ï +- ·Ð ·Ñ ·Ò ·Ó ·Ô ·Õ ·Ö ·× ·Ø ·Ù ·Ú ·Û ·Ü ·Ý ·Þ ·ß +- ·à ·á ·â ·ã ·ä ·å ·æ ·ç ·è ·é ·ê ·ë ·ì ·í ·î ·ï +- ·ð ·ñ ·ò ·ó ·ô ·õ ·ö ·÷ ·ø ·ù ·ú ·û ·ü ·ý ·þ ¸@ +- ¸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 ¸[ ¸\ ¸] ¸^ ¸_ ¸` +- ¸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 ¸{ ¸| ¸} ¸~ ¸¡ ¸¢ +- ¸£ ¸¤ ¸¥ ¸¦ ¸§ ¸¨ ¸© ¸ª ¸« ¸¬ ¸­ ¸® ¸¯ ¸° ¸± ¸² +- ¸³ ¸´ ¸µ ¸¶ ¸· ¸¸ ¸¹ ¸º ¸» ¸¼ ¸½ ¸¾ ¸¿ ¸À ¸Á ¸Â +- ¸Ã ¸Ä ¸Å ¸Æ ¸Ç ¸È ¸É ¸Ê ¸Ë ¸Ì ¸Í ¸Î ¸Ï ¸Ð ¸Ñ ¸Ò +- ¸Ó ¸Ô ¸Õ ¸Ö ¸× ¸Ø ¸Ù ¸Ú ¸Û ¸Ü ¸Ý ¸Þ ¸ß ¸à ¸á ¸â +- ¸ã ¸ä ¸å ¸æ ¸ç ¸è ¸é ¸ê ¸ë ¸ì ¸í ¸î ¸ï ¸ð ¸ñ ¸ò +- ¸ó ¸ô ¸õ ¸ö ¸÷ ¸ø ¸ù ¸ú ¸û ¸ü ¸ý ¸þ ¹@ ¹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 ¹[ ¹\ ¹] ¹^ ¹_ ¹` ¹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 ¹{ ¹| ¹} ¹~ ¹¡ ¹¢ ¹£ ¹¤ ¹¥ +- ¹¦ ¹§ ¹¨ ¹© ¹ª ¹« ¹¬ ¹­ ¹® ¹¯ ¹° ¹± ¹² ¹³ ¹´ ¹µ +- ¹¶ ¹· ¹¸ ¹¹ ¹º ¹» ¹¼ ¹½ ¹¾ ¹¿ ¹À ¹Á ¹Â ¹Ã ¹Ä ¹Å +- ¹Æ ¹Ç ¹È ¹É ¹Ê ¹Ë ¹Ì ¹Í ¹Î ¹Ï ¹Ð ¹Ñ ¹Ò ¹Ó ¹Ô ¹Õ +- ¹Ö ¹× ¹Ø ¹Ù ¹Ú ¹Û ¹Ü ¹Ý ¹Þ ¹ß ¹à ¹á ¹â ¹ã ¹ä ¹å +- ¹æ ¹ç ¹è ¹é ¹ê ¹ë ¹ì ¹í ¹î ¹ï ¹ð ¹ñ ¹ò ¹ó ¹ô ¹õ +- ¹ö ¹÷ ¹ø ¹ù ¹ú ¹û ¹ü ¹ý ¹þ º@ º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 º[ º\ º] º^ º_ º` º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 º{ º| º} º~ º¡ º¢ º£ º¤ º¥ º¦ º§ º¨ +- º© ºª º« º¬ º­ º® º¯ º° º± º² º³ º´ ºµ º¶ º· º¸ +- º¹ ºº º» º¼ º½ º¾ º¿ ºÀ ºÁ ºÂ ºÃ ºÄ ºÅ ºÆ ºÇ ºÈ +- ºÉ ºÊ ºË ºÌ ºÍ ºÎ ºÏ ºÐ ºÑ ºÒ ºÓ ºÔ ºÕ ºÖ º× ºØ +- ºÙ ºÚ ºÛ ºÜ ºÝ ºÞ ºß ºà ºá ºâ ºã ºä ºå ºæ ºç ºè +- ºé ºê ºë ºì ºí ºî ºï ºð ºñ ºò ºó ºô ºõ ºö º÷ ºø +- ºù ºú ºû ºü ºý ºþ »@ »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 »[ »\ »] »^ »_ »` »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 »{ »| »} »~ »¡ »¢ »£ »¤ »¥ »¦ »§ »¨ »© »ª »« +- »¬ »­ »® »¯ »° »± »² »³ »´ »µ »¶ »· »¸ »¹ »º »» +- »¼ »½ »¾ »¿ »À »Á »Â »Ã »Ä »Å »Æ »Ç »È »É »Ê »Ë +- »Ì »Í »Î »Ï »Ð »Ñ »Ò »Ó »Ô »Õ »Ö »× »Ø »Ù »Ú »Û +- »Ü »Ý »Þ »ß »à »á »â »ã »ä »å »æ »ç »è »é »ê »ë +- »ì »í »î »ï »ð »ñ »ò »ó »ô »õ »ö »÷ »ø »ù »ú »û +- »ü »ý »þ ¼@ ¼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 ¼[ ¼\ +- ¼] ¼^ ¼_ ¼` ¼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 ¼{ ¼| +- ¼} ¼~ ¼¡ ¼¢ ¼£ ¼¤ ¼¥ ¼¦ ¼§ ¼¨ ¼© ¼ª ¼« ¼¬ ¼­ ¼® +- ¼¯ ¼° ¼± ¼² ¼³ ¼´ ¼µ ¼¶ ¼· ¼¸ ¼¹ ¼º ¼» ¼¼ ¼½ ¼¾ +- ¼¿ ¼À ¼Á ¼Â ¼Ã ¼Ä ¼Å ¼Æ ¼Ç ¼È ¼É ¼Ê ¼Ë ¼Ì ¼Í ¼Î +- ¼Ï ¼Ð ¼Ñ ¼Ò ¼Ó ¼Ô ¼Õ ¼Ö ¼× ¼Ø ¼Ù ¼Ú ¼Û ¼Ü ¼Ý ¼Þ +- ¼ß ¼à ¼á ¼â ¼ã ¼ä ¼å ¼æ ¼ç ¼è ¼é ¼ê ¼ë ¼ì ¼í ¼î +- ¼ï ¼ð ¼ñ ¼ò ¼ó ¼ô ¼õ ¼ö ¼÷ ¼ø ¼ù ¼ú ¼û ¼ü ¼ý ¼þ +- ½@ ½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 ½[ ½\ ½] ½^ ½_ +- ½` ½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 ½{ ½| ½} ½~ ½¡ +- ½¢ ½£ ½¤ ½¥ ½¦ ½§ ½¨ ½© ½ª ½« ½¬ ½­ ½® ½¯ ½° ½± +- ½² ½³ ½´ ½µ ½¶ ½· ½¸ ½¹ ½º ½» ½¼ ½½ ½¾ ½¿ ½À ½Á +- ½Â ½Ã ½Ä ½Å ½Æ ½Ç ½È ½É ½Ê ½Ë ½Ì ½Í ½Î ½Ï ½Ð ½Ñ +- ½Ò ½Ó ½Ô ½Õ ½Ö ½× ½Ø ½Ù ½Ú ½Û ½Ü ½Ý ½Þ ½ß ½à ½á +- ½â ½ã ½ä ½å ½æ ½ç ½è ½é ½ê ½ë ½ì ½í ½î ½ï ½ð ½ñ +- ½ò ½ó ½ô ½õ ½ö ½÷ ½ø ½ù ½ú ½û ½ü ½ý ½þ ¾@ ¾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 ¾[ ¾\ ¾] ¾^ ¾_ ¾` ¾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 ¾{ ¾| ¾} ¾~ ¾¡ ¾¢ ¾£ ¾¤ +- ¾¥ ¾¦ ¾§ ¾¨ ¾© ¾ª ¾« ¾¬ ¾­ ¾® ¾¯ ¾° ¾± ¾² ¾³ ¾´ +- ¾µ ¾¶ ¾· ¾¸ ¾¹ ¾º ¾» ¾¼ ¾½ ¾¾ ¾¿ ¾À ¾Á ¾Â ¾Ã ¾Ä +- ¾Å ¾Æ ¾Ç ¾È ¾É ¾Ê ¾Ë ¾Ì ¾Í ¾Î ¾Ï ¾Ð ¾Ñ ¾Ò ¾Ó ¾Ô +- ¾Õ ¾Ö ¾× ¾Ø ¾Ù ¾Ú ¾Û ¾Ü ¾Ý ¾Þ ¾ß ¾à ¾á ¾â ¾ã ¾ä +- ¾å ¾æ ¾ç ¾è ¾é ¾ê ¾ë ¾ì ¾í ¾î ¾ï ¾ð ¾ñ ¾ò ¾ó ¾ô +- ¾õ ¾ö ¾÷ ¾ø ¾ù ¾ú ¾û ¾ü ¾ý ¾þ ¿@ ¿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 ¿[ ¿\ ¿] ¿^ ¿_ ¿` ¿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 ¿{ ¿| ¿} ¿~ ¿¡ ¿¢ ¿£ ¿¤ ¿¥ ¿¦ ¿§ +- ¿¨ ¿© ¿ª ¿« ¿¬ ¿­ ¿® ¿¯ ¿° ¿± ¿² ¿³ ¿´ ¿µ ¿¶ ¿· +- ¿¸ ¿¹ ¿º ¿» ¿¼ ¿½ ¿¾ ¿¿ ¿À ¿Á ¿Â ¿Ã ¿Ä ¿Å ¿Æ ¿Ç +- ¿È ¿É ¿Ê ¿Ë ¿Ì ¿Í ¿Î ¿Ï ¿Ð ¿Ñ ¿Ò ¿Ó ¿Ô ¿Õ ¿Ö ¿× +- ¿Ø ¿Ù ¿Ú ¿Û ¿Ü ¿Ý ¿Þ ¿ß ¿à ¿á ¿â ¿ã ¿ä ¿å ¿æ ¿ç +- ¿è ¿é ¿ê ¿ë ¿ì ¿í ¿î ¿ï ¿ð ¿ñ ¿ò ¿ó ¿ô ¿õ ¿ö ¿÷ +- ¿ø ¿ù ¿ú ¿û ¿ü ¿ý ¿þ À@ À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 À[ À\ À] À^ À_ À` À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 À{ À| À} À~ À¡ À¢ À£ À¤ À¥ À¦ À§ À¨ À© Àª +- À« À¬ À­ À® À¯ À° À± À² À³ À´ Àµ À¶ À· À¸ À¹ Àº +- À» À¼ À½ À¾ À¿ ÀÀ ÀÁ À Àà ÀÄ ÀÅ ÀÆ ÀÇ ÀÈ ÀÉ ÀÊ +- ÀË ÀÌ ÀÍ ÀÎ ÀÏ ÀÐ ÀÑ ÀÒ ÀÓ ÀÔ ÀÕ ÀÖ À× ÀØ ÀÙ ÀÚ +- ÀÛ ÀÜ ÀÝ ÀÞ Àß Àà Àá Àâ Àã Àä Àå Àæ Àç Àè Àé Àê +- Àë Àì Àí Àî Àï Àð Àñ Àò Àó Àô Àõ Àö À÷ Àø Àù Àú +- Àû Àü Àý Àþ Á@ Á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 Á[ +- Á\ Á] Á^ Á_ Á` Á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 Á{ +- Á| Á} Á~ Á¡ Á¢ Á£ Á¤ Á¥ Á¦ Á§ Á¨ Á© Áª Á« Á¬ Á­ +- Á® Á¯ Á° Á± Á² Á³ Á´ Áµ Á¶ Á· Á¸ Á¹ Áº Á» Á¼ Á½ +- Á¾ Á¿ ÁÀ ÁÁ Á Áà ÁÄ ÁÅ ÁÆ ÁÇ ÁÈ ÁÉ ÁÊ ÁË ÁÌ ÁÍ +- ÁÎ ÁÏ ÁÐ ÁÑ ÁÒ ÁÓ ÁÔ ÁÕ ÁÖ Á× ÁØ ÁÙ ÁÚ ÁÛ ÁÜ ÁÝ +- ÁÞ Áß Áà Áá Áâ Áã Áä Áå Áæ Áç Áè Áé Áê Áë Áì Áí +- Áî Áï Áð Áñ Áò Áó Áô Áõ Áö Á÷ Áø Áù Áú Áû Áü Áý +- Áþ Â@ Â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 Â[ Â\ Â] Â^ +- Â_ Â` Â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 Â{ Â| Â} Â~ +- ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° +- ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ ÂÀ +- ÂÁ  Âà ÂÄ ÂÅ ÂÆ ÂÇ ÂÈ ÂÉ ÂÊ ÂË ÂÌ ÂÍ ÂÎ ÂÏ ÂÐ +- ÂÑ ÂÒ ÂÓ ÂÔ ÂÕ ÂÖ Â× ÂØ ÂÙ ÂÚ ÂÛ ÂÜ ÂÝ ÂÞ Âß Âà +- Âá Ââ Âã Âä Âå Âæ Âç Âè Âé Âê Âë Âì Âí Âî Âï Âð +- Âñ Âò Âó Âô Âõ Âö Â÷ Âø Âù Âú Âû Âü Âý Âþ Ã@ Ã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 Ã[ Ã\ Ã] Ã^ Ã_ Ã` Ã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 Ã{ Ã| Ã} Ã~ á â ã +- ä Ã¥ æ ç è é ê ë ì í î ï ð ñ ò ó +- ô õ ö ÷ ø ù ú û ü ý þ ÿ ÃÀ ÃÁ àÃà +- ÃÄ ÃÅ ÃÆ ÃÇ ÃÈ ÃÉ ÃÊ ÃË ÃÌ ÃÍ ÃÎ ÃÏ ÃÐ ÃÑ ÃÒ ÃÓ +- ÃÔ ÃÕ ÃÖ Ã× ÃØ ÃÙ ÃÚ ÃÛ ÃÜ ÃÝ ÃÞ Ãß Ãà Ãá Ãâ Ãã +- Ãä Ãå Ãæ Ãç Ãè Ãé Ãê Ãë Ãì Ãí Ãî Ãï Ãð Ãñ Ãò Ãó +- Ãô Ãõ Ãö Ã÷ Ãø Ãù Ãú Ãû Ãü Ãý Ãþ Ä@ Ä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 Ä[ Ä\ Ä] Ä^ Ä_ Ä` Ä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 Ä{ Ä| Ä} Ä~ Ä¡ Ä¢ Ä£ Ĥ Ä¥ Ħ +- ħ Ĩ Ä© Ī Ä« Ĭ Ä­ Ä® į Ä° ı IJ ij Ä´ ĵ Ķ +- Ä· ĸ Ĺ ĺ Ä» ļ Ľ ľ Ä¿ ÄÀ ÄÁ Ä Äà ÄÄ ÄÅ ÄÆ +- ÄÇ ÄÈ ÄÉ ÄÊ ÄË ÄÌ ÄÍ ÄÎ ÄÏ ÄÐ ÄÑ ÄÒ ÄÓ ÄÔ ÄÕ ÄÖ +- Ä× ÄØ ÄÙ ÄÚ ÄÛ ÄÜ ÄÝ ÄÞ Äß Äà Äá Äâ Äã Ää Äå Äæ +- Äç Äè Äé Äê Äë Äì Äí Äî Äï Äð Äñ Äò Äó Äô Äõ Äö +- Ä÷ Äø Äù Äú Äû Äü Äý Äþ Å@ Å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 Å[ Å\ Å] Å^ Å_ Å` Å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 Å{ Å| Å} Å~ Å¡ Å¢ Å£ Ť Å¥ Ŧ ŧ Ũ Å© +- Ū Å« Ŭ Å­ Å® ů Å° ű Ų ų Å´ ŵ Ŷ Å· Ÿ Ź +- ź Å» ż Ž ž Å¿ ÅÀ ÅÁ Å Åà ÅÄ ÅÅ ÅÆ ÅÇ ÅÈ ÅÉ +- ÅÊ ÅË ÅÌ ÅÍ ÅÎ ÅÏ ÅÐ ÅÑ ÅÒ ÅÓ ÅÔ ÅÕ ÅÖ Å× ÅØ ÅÙ +- ÅÚ ÅÛ ÅÜ ÅÝ ÅÞ Åß Åà Åá Åâ Åã Åä Åå Åæ Åç Åè Åé +- Åê Åë Åì Åí Åî Åï Åð Åñ Åò Åó Åô Åõ Åö Å÷ Åø Åù +- Åú Åû Åü Åý Åþ Æ@ Æ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 +- Æ[ Æ\ Æ] Æ^ Æ_ Æ` Æ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 +- Æ{ Æ| Æ} Æ~ Æ¡ Æ¢ Æ£ Ƥ Æ¥ Ʀ Ƨ ƨ Æ© ƪ Æ« Ƭ +- Æ­ Æ® Ư Æ° Ʊ Ʋ Ƴ Æ´ Ƶ ƶ Æ· Ƹ ƹ ƺ Æ» Ƽ +- ƽ ƾ Æ¿ ÆÀ ÆÁ Æ Æà ÆÄ ÆÅ ÆÆ ÆÇ ÆÈ ÆÉ ÆÊ ÆË ÆÌ +- ÆÍ ÆÎ ÆÐ ÆÑ ÆÒ ÆÔ ÆÖ ÆØ ÆÙ ÆÚ ÆÛ ÆÜ ÆÝ Æà Æá Æâ +- Æã Æä Æå Ææ Æç Æè Æé Æê Æë Æì Æí Æî Æï Æð Æñ Æò +- Æó Æô Æõ Æö Æ÷ Æø Æù Æú Æû Æü Æý Æþ Ç@ Ç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 Ç[ Ç\ Ç] Ç^ Ç_ Ç` Ç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 Ç{ Ç| Ç} Ç~ Ç¡ Ç¢ Ç£ Ǥ Ç¥ +- Ǧ ǧ Ǩ Ç© Ǫ Ç« Ǭ Ç­ Ç® ǯ Ç° DZ Dz dz Ç´ ǵ +- Ƕ Ç· Ǹ ǹ Ǻ Ç» Ǽ ǽ Ǿ Ç¿ ÇÀ ÇÁ Ç Çà ÇÄ ÇÅ +- ÇÆ ÇÇ ÇÈ ÇÉ ÇÊ ÇË ÇÌ ÇÍ ÇÎ ÇÏ ÇÐ ÇÑ ÇÒ ÇÓ ÇÔ ÇÕ +- ÇÖ Ç× ÇØ ÇÙ ÇÚ ÇÛ ÇÜ ÇÝ ÇÞ Çß Çà Çá Çâ Çã Çä Çå +- Çæ Çç Çè Çé Çê Çë Çì Çí Çî Çï Çð Çñ Çò Çó Çô Çõ +- Çö Ç÷ Çø Çù Çú Çû Çü Çý Çþ È@ È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 È[ È\ È] È^ È_ È` È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 È{ È| È} È~ È¡ È¢ È£ Ȥ ÈÍ ÈÎ ÈÏ ÈÐ +- ÈÑ ÈÒ ÈÓ ÈÔ ÈÕ ÈÖ È× ÈØ ÈÙ ÈÚ ÈÛ ÈÜ ÈÝ ÈÞ Èß Èà +- Èá Èâ Èã Èä Èå Èæ Èç Èè Èé Èê Èë Èì Èí Èî Èï Èð +- Èñ Èõ Èö È÷ Èø Èù Èú Èû Èü Èý Èþ É@ É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 É[ É\ É] É^ É_ É` É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 É{ É| É} É~ É¡ É¢ É£ ɤ É¥ ɦ +- ɧ ɨ É© ɪ É« ɬ É­ É® ɯ É° ɱ ɲ ɳ É´ ɵ ɶ +- É· ɸ ɹ ɺ É» ɼ ɽ ɾ É¿ ÉÀ ÉÁ É Éà ÉÄ ÉÅ ÉÆ +- ÉÇ ÉÈ ÉÉ ÉÊ ÉË ÉÌ ÉÍ ÉÎ ÉÏ ÉÐ ÉÑ ÉÒ ÉÓ ÉÔ ÉÕ ÉÖ +- É× ÉØ ÉÙ ÉÚ ÉÛ ÉÜ ÉÝ ÉÞ Éß Éà Éá Éâ Éã Éä Éå Éæ +- Éç Éè Éé Éê Éë Éì Éí Éî Éï Éð Éñ Éò Éó Éô Éõ Éö +- É÷ Éø Éù Éú Éû Éü Éý Éþ Ê@ Ê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 Ê[ Ê\ Ê] Ê^ Ê_ Ê` Ê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 Ê{ Ê| Ê} Ê~ Ê¡ Ê¢ Ê£ ʤ Ê¥ ʦ ʧ ʨ Ê© +- ʪ Ê« ʬ Ê­ Ê® ʯ Ê° ʱ ʲ ʳ Ê´ ʵ ʶ Ê· ʸ ʹ +- ʺ Ê» ʼ ʽ ʾ Ê¿ ÊÀ ÊÁ Ê Êà ÊÄ ÊÅ ÊÆ ÊÇ ÊÈ ÊÉ +- ÊÊ ÊË ÊÌ ÊÍ ÊÎ ÊÏ ÊÐ ÊÑ ÊÒ ÊÓ ÊÔ ÊÕ ÊÖ Ê× ÊØ ÊÙ +- ÊÚ ÊÛ ÊÜ ÊÝ ÊÞ Êß Êà Êá Êâ Êã Êä Êå Êæ Êç Êè Êé +- Êê Êë Êì Êí Êî Êï Êð Êñ Êò Êó Êô Êõ Êö Ê÷ Êø Êù +- Êú Êû Êü Êý Êþ Ë@ Ë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 +- Ë[ Ë\ Ë] Ë^ Ë_ Ë` Ë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 +- Ë{ Ë| Ë} Ë~ Ë¡ Ë¢ Ë£ ˤ Ë¥ ˦ ˧ ˨ Ë© ˪ Ë« ˬ +- Ë­ Ë® ˯ Ë° ˱ ˲ ˳ Ë´ ˵ ˶ Ë· ˸ ˹ ˺ Ë» ˼ +- ˽ ˾ Ë¿ ËÀ ËÁ Ë Ëà ËÄ ËÅ ËÆ ËÇ ËÈ ËÉ ËÊ ËË ËÌ +- ËÍ ËÎ ËÏ ËÐ ËÑ ËÒ ËÓ ËÔ ËÕ ËÖ Ë× ËØ ËÙ ËÚ ËÛ ËÜ +- ËÝ ËÞ Ëß Ëà Ëá Ëâ Ëã Ëä Ëå Ëæ Ëç Ëè Ëé Ëê Ëë Ëì +- Ëí Ëî Ëï Ëð Ëñ Ëò Ëó Ëô Ëõ Ëö Ë÷ Ëø Ëù Ëú Ëû Ëü +- Ëý Ëþ Ì@ Ì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 Ì[ Ì\ Ì] +- Ì^ Ì_ Ì` Ì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 Ì{ Ì| Ì} +- Ì~ Ì¡ Ì¢ Ì£ ̤ Ì¥ ̦ ̧ ̨ Ì© ̪ Ì« ̬ Ì­ Ì® ̯ +- Ì° ̱ ̲ ̳ Ì´ ̵ ̶ Ì· ̸ ̹ ̺ Ì» ̼ ̽ ̾ Ì¿ +- ÌÀ ÌÁ Ì Ìà ÌÄ ÌÅ ÌÆ ÌÇ ÌÈ ÌÉ ÌÊ ÌË ÌÌ ÌÍ ÌÎ ÌÏ +- ÌÐ ÌÑ ÌÒ ÌÓ ÌÔ ÌÕ ÌÖ Ì× ÌØ ÌÙ ÌÚ ÌÛ ÌÜ ÌÝ ÌÞ Ìß +- Ìà Ìá Ìâ Ìã Ìä Ìå Ìæ Ìç Ìè Ìé Ìê Ìë Ìì Ìí Ìî Ìï +- Ìð Ìñ Ìò Ìó Ìô Ìõ Ìö Ì÷ Ìø Ìù Ìú Ìû Ìü Ìý Ìþ Í@ +- Í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 Í[ Í\ Í] Í^ Í_ Í` +- Í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 Í{ Í| Í} Í~ Í¡ Í¢ +- Í£ ͤ Í¥ ͦ ͧ ͨ Í© ͪ Í« ͬ Í­ Í® ͯ Í° ͱ Ͳ +- ͳ Í´ ͵ Ͷ Í· ͸ ͹ ͺ Í» ͼ ͽ ; Í¿ ÍÀ ÍÁ Í +- Íà ÍÄ ÍÅ ÍÆ ÍÇ ÍÈ ÍÉ ÍÊ ÍË ÍÌ ÍÍ ÍÎ ÍÏ ÍÐ ÍÑ ÍÒ +- ÍÓ ÍÔ ÍÕ ÍÖ Í× ÍØ ÍÙ ÍÚ ÍÛ ÍÜ ÍÝ ÍÞ Íß Íà Íá Íâ +- Íã Íä Íå Íæ Íç Íè Íé Íê Íë Íì Íí Íî Íï Íð Íñ Íò +- Íó Íô Íõ Íö Í÷ Íø Íù Íú Íû Íü Íý Íþ Î@ Î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 Î[ Î\ Î] Î^ Î_ Î` Î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 Î{ Î| Î} Î~ Ρ ΢ Σ Τ Î¥ +- Φ Χ Ψ Ω Ϊ Ϋ ά έ ή ί ΰ α β γ δ ε +- ζ η θ ι κ λ μ ν ξ ο ÎÀ ÎÁ ΠÎà ÎÄ ÎÅ +- ÎÆ ÎÇ ÎÈ ÎÉ ÎÊ ÎË ÎÌ ÎÍ ÎÎ ÎÏ ÎÐ ÎÑ ÎÒ ÎÓ ÎÔ ÎÕ +- ÎÖ Î× ÎØ ÎÙ ÎÚ ÎÛ ÎÜ ÎÝ ÎÞ Îß Îà Îá Îâ Îã Îä Îå +- Îæ Îç Îè Îé Îê Îë Îì Îí Îî Îï Îð Îñ Îò Îó Îô Îõ +- Îö Î÷ Îø Îù Îú Îû Îü Îý Îþ Ï@ Ï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 Ï[ Ï\ Ï] Ï^ Ï_ Ï` Ï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 Ï{ Ï| Ï} Ï~ Ï¡ Ï¢ Ï£ Ϥ Ï¥ Ϧ ϧ Ϩ +- Ï© Ϫ Ï« Ϭ Ï­ Ï® ϯ Ï° ϱ ϲ ϳ Ï´ ϵ ϶ Ï· ϸ +- Ϲ Ϻ Ï» ϼ Ͻ Ͼ Ï¿ ÏÀ ÏÁ Ï Ïà ÏÄ ÏÅ ÏÆ ÏÇ ÏÈ +- ÏÉ ÏÊ ÏË ÏÌ ÏÍ ÏÎ ÏÏ ÏÐ ÏÑ ÏÒ ÏÓ ÏÔ ÏÕ ÏÖ Ï× ÏØ +- ÏÙ ÏÚ ÏÛ ÏÜ ÏÝ ÏÞ Ïß Ïà Ïá Ïâ Ïã Ïä Ïå Ïæ Ïç Ïè +- Ïé Ïê Ïë Ïì Ïí Ïî Ïï Ïð Ïñ Ïò Ïó Ïô Ïõ Ïö Ï÷ Ïø +- Ïù Ïú Ïû Ïü Ïý Ïþ Ð@ Ð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 Ð[ Ð\ Ð] Ð^ Ð_ Ð` Ð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 Ð{ Ð| Ð} Ð~ С Т У Ф Ð¥ Ц Ч Ш Щ Ъ Ы +- Ь Э Ю Я а б в г д е ж з и й к л +- м н о п ÐÀ ÐÁ РÐà ÐÄ ÐÅ ÐÆ ÐÇ ÐÈ ÐÉ ÐÊ ÐË +- ÐÌ ÐÍ ÐÎ ÐÏ ÐÐ ÐÑ ÐÒ ÐÓ ÐÔ ÐÕ ÐÖ Ð× ÐØ ÐÙ ÐÚ ÐÛ +- ÐÜ ÐÝ ÐÞ Ðß Ðà Ðá Ðâ Ðã Ðä Ðå Ðæ Ðç Ðè Ðé Ðê Ðë +- Ðì Ðí Ðî Ðï Ðð Ðñ Ðò Ðó Ðô Ðõ Ðö Ð÷ Ðø Ðù Ðú Ðû +- Ðü Ðý Ðþ Ñ@ Ñ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 Ñ[ Ñ\ +- Ñ] Ñ^ Ñ_ Ñ` Ñ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 Ñ{ Ñ| +- Ñ} Ñ~ Ñ¡ Ñ¢ Ñ£ Ѥ Ñ¥ Ѧ ѧ Ѩ Ñ© Ѫ Ñ« Ѭ Ñ­ Ñ® +- ѯ Ñ° ѱ Ѳ ѳ Ñ´ ѵ Ѷ Ñ· Ѹ ѹ Ѻ Ñ» Ѽ ѽ Ѿ +- Ñ¿ ÑÀ ÑÁ Ñ Ñà ÑÄ ÑÅ ÑÆ ÑÇ ÑÈ ÑÉ ÑÊ ÑË ÑÌ ÑÍ ÑÎ +- ÑÏ ÑÐ ÑÑ ÑÒ ÑÓ ÑÔ ÑÕ ÑÖ Ñ× ÑØ ÑÙ ÑÚ ÑÛ ÑÜ ÑÝ ÑÞ +- Ñß Ñà Ñá Ñâ Ñã Ñä Ñå Ñæ Ñç Ñè Ñé Ñê Ñë Ñì Ñí Ñî +- Ñï Ñð Ññ Ñò Ñó Ñô Ñõ Ñö Ñ÷ Ñø Ñù Ñú Ñû Ñü Ñý Ñþ +- Ò@ Ò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 Ò[ Ò\ Ò] Ò^ Ò_ +- Ò` Ò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 Ò{ Ò| Ò} Ò~ Ò¡ +- Ò¢ Ò£ Ò¤ Ò¥ Ò¦ Ò§ Ò¨ Ò© Òª Ò« Ò¬ Ò­ Ò® Ò¯ Ò° Ò± +- Ò² Ò³ Ò´ Òµ Ò¶ Ò· Ò¸ Ò¹ Òº Ò» Ò¼ Ò½ Ò¾ Ò¿ ÒÀ ÒÁ +- Ò Òà ÒÄ ÒÅ ÒÆ ÒÇ ÒÈ ÒÉ ÒÊ ÒË ÒÌ ÒÍ ÒÎ ÒÏ ÒÐ ÒÑ +- ÒÒ ÒÓ ÒÔ ÒÕ ÒÖ Ò× ÒØ ÒÙ ÒÚ ÒÛ ÒÜ ÒÝ ÒÞ Òß Òà Òá +- Òâ Òã Òä Òå Òæ Òç Òè Òé Òê Òë Òì Òí Òî Òï Òð Òñ +- Òò Òó Òô Òõ Òö Ò÷ Òø Òù Òú Òû Òü Òý Òþ Ó@ Ó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 Ó[ Ó\ Ó] Ó^ Ó_ Ó` Ó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 Ó{ Ó| Ó} Ó~ Ó¡ Ó¢ Ó£ Ó¤ +- Ó¥ Ó¦ Ó§ Ó¨ Ó© Óª Ó« Ó¬ Ó­ Ó® Ó¯ Ó° Ó± Ó² Ó³ Ó´ +- Óµ Ó¶ Ó· Ó¸ Ó¹ Óº Ó» Ó¼ Ó½ Ó¾ Ó¿ ÓÀ ÓÁ Ó Óà ÓÄ +- ÓÅ ÓÆ ÓÇ ÓÈ ÓÉ ÓÊ ÓË ÓÌ ÓÍ ÓÎ ÓÏ ÓÐ ÓÑ ÓÒ ÓÓ ÓÔ +- ÓÕ ÓÖ Ó× ÓØ ÓÙ ÓÚ ÓÛ ÓÜ ÓÝ ÓÞ Óß Óà Óá Óâ Óã Óä +- Óå Óæ Óç Óè Óé Óê Óë Óì Óí Óî Óï Óð Óñ Óò Óó Óô +- Óõ Óö Ó÷ Óø Óù Óú Óû Óü Óý Óþ Ô@ Ô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 Ô[ Ô\ Ô] Ô^ Ô_ Ô` Ô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 Ô{ Ô| Ô} Ô~ Ô¡ Ô¢ Ô£ Ô¤ Ô¥ Ô¦ Ô§ +- Ô¨ Ô© Ôª Ô« Ô¬ Ô­ Ô® Ô¯ Ô° Ô± Ô² Ô³ Ô´ Ôµ Ô¶ Ô· +- Ô¸ Ô¹ Ôº Ô» Ô¼ Ô½ Ô¾ Ô¿ ÔÀ ÔÁ Ô Ôà ÔÄ ÔÅ ÔÆ ÔÇ +- ÔÈ ÔÉ ÔÊ ÔË ÔÌ ÔÍ ÔÎ ÔÏ ÔÐ ÔÑ ÔÒ ÔÓ ÔÔ ÔÕ ÔÖ Ô× +- ÔØ ÔÙ ÔÚ ÔÛ ÔÜ ÔÝ ÔÞ Ôß Ôà Ôá Ôâ Ôã Ôä Ôå Ôæ Ôç +- Ôè Ôé Ôê Ôë Ôì Ôí Ôî Ôï Ôð Ôñ Ôò Ôó Ôô Ôõ Ôö Ô÷ +- Ôø Ôù Ôú Ôû Ôü Ôý Ôþ Õ@ Õ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 Õ[ Õ\ Õ] Õ^ Õ_ Õ` Õ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 Õ{ Õ| Õ} Õ~ Õ¡ Õ¢ Õ£ Õ¤ Õ¥ Õ¦ Õ§ Õ¨ Õ© Õª +- Õ« Õ¬ Õ­ Õ® Õ¯ Õ° Õ± Õ² Õ³ Õ´ Õµ Õ¶ Õ· Õ¸ Õ¹ Õº +- Õ» Õ¼ Õ½ Õ¾ Õ¿ ÕÀ ÕÁ Õ Õà ÕÄ ÕÅ ÕÆ ÕÇ ÕÈ ÕÉ ÕÊ +- ÕË ÕÌ ÕÍ ÕÎ ÕÏ ÕÐ ÕÑ ÕÒ ÕÓ ÕÔ ÕÕ ÕÖ Õ× ÕØ ÕÙ ÕÚ +- ÕÛ ÕÜ ÕÝ ÕÞ Õß Õà Õá Õâ Õã Õä Õå Õæ Õç Õè Õé Õê +- Õë Õì Õí Õî Õï Õð Õñ Õò Õó Õô Õõ Õö Õ÷ Õø Õù Õú +- Õû Õü Õý Õþ Ö@ Ö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 Ö[ +- Ö\ Ö] Ö^ Ö_ Ö` Ö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 Ö{ +- Ö| Ö} Ö~ Ö¡ Ö¢ Ö£ Ö¤ Ö¥ Ö¦ Ö§ Ö¨ Ö© Öª Ö« Ö¬ Ö­ +- Ö® Ö¯ Ö° Ö± Ö² Ö³ Ö´ Öµ Ö¶ Ö· Ö¸ Ö¹ Öº Ö» Ö¼ Ö½ +- Ö¾ Ö¿ ÖÀ ÖÁ Ö Öà ÖÄ ÖÅ ÖÆ ÖÇ ÖÈ ÖÉ ÖÊ ÖË ÖÌ ÖÍ +- ÖÎ ÖÏ ÖÐ ÖÑ ÖÒ ÖÓ ÖÔ ÖÕ ÖÖ Ö× ÖØ ÖÙ ÖÚ ÖÛ ÖÜ ÖÝ +- ÖÞ Öß Öà Öá Öâ Öã Öä Öå Öæ Öç Öè Öé Öê Öë Öì Öí +- Öî Öï Öð Öñ Öò Öó Öô Öõ Öö Ö÷ Öø Öù Öú Öû Öü Öý +- Öþ ×@ ×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 ×[ ×\ ×] ×^ +- ×_ ×` ×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 ×{ ×| ×} ×~ +- ס ×¢ ×£ פ ×¥ צ ק ר ש ת ׫ ׬ ×­ ×® ׯ ×° +- ×± ײ ׳ ×´ ×µ ׶ ×· ׸ ×¹ ׺ ×» ×¼ ×½ ×¾ ׿ ×À +- ×Á × ×à ×Ä ×Å ×Æ ×Ç ×È ×É ×Ê ×Ë ×Ì ×Í ×Î ×Ï ×Ð +- ×Ñ ×Ò ×Ó ×Ô ×Õ ×Ö ×× ×Ø ×Ù ×Ú ×Û ×Ü ×Ý ×Þ ×ß ×à +- ×á ×â ×ã ×ä ×å ×æ ×ç ×è ×é ×ê ×ë ×ì ×í ×î ×ï ×ð +- ×ñ ×ò ×ó ×ô ×õ ×ö ×÷ ×ø ×ù ×ú ×û ×ü ×ý ×þ Ø@ Ø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 Ø[ Ø\ Ø] Ø^ Ø_ Ø` Ø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 Ø{ Ø| Ø} Ø~ Ø¡ Ø¢ Ø£ +- ؤ Ø¥ ئ ا ب Ø© ت Ø« ج Ø­ Ø® د Ø° ر ز س +- Ø´ ص ض Ø· ظ ع غ Ø» ؼ ؽ ؾ Ø¿ ØÀ ØÁ Ø Øà +- ØÄ ØÅ ØÆ ØÇ ØÈ ØÉ ØÊ ØË ØÌ ØÍ ØÎ ØÏ ØÐ ØÑ ØÒ ØÓ +- ØÔ ØÕ ØÖ Ø× ØØ ØÙ ØÚ ØÛ ØÜ ØÝ ØÞ Øß Øà Øá Øâ Øã +- Øä Øå Øæ Øç Øè Øé Øê Øë Øì Øí Øî Øï Øð Øñ Øò Øó +- Øô Øõ Øö Ø÷ Øø Øù Øú Øû Øü Øý Øþ Ù@ Ù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 Ù[ Ù\ Ù] Ù^ Ù_ Ù` Ù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 Ù{ Ù| Ù} Ù~ Ù¡ Ù¢ Ù£ Ù¤ Ù¥ Ù¦ +- Ù§ Ù¨ Ù© Ùª Ù« Ù¬ Ù­ Ù® Ù¯ Ù° Ù± Ù² Ù³ Ù´ Ùµ Ù¶ +- Ù· Ù¸ Ù¹ Ùº Ù» Ù¼ Ù½ Ù¾ Ù¿ ÙÀ ÙÁ Ù Ùà ÙÄ ÙÅ ÙÆ +- ÙÇ ÙÈ ÙÉ ÙÊ ÙË ÙÌ ÙÍ ÙÎ ÙÏ ÙÐ ÙÑ ÙÒ ÙÓ ÙÔ ÙÕ ÙÖ +- Ù× ÙØ ÙÙ ÙÚ ÙÛ ÙÜ ÙÝ ÙÞ Ùß Ùà Ùá Ùâ Ùã Ùä Ùå Ùæ +- Ùç Ùè Ùé Ùê Ùë Ùì Ùí Ùî Ùï Ùð Ùñ Ùò Ùó Ùô Ùõ Ùö +- Ù÷ Ùø Ùù Ùú Ùû Ùü Ùý Ùþ Ú@ Ú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 Ú[ Ú\ Ú] Ú^ Ú_ Ú` Ú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 Ú{ Ú| Ú} Ú~ Ú¡ Ú¢ Ú£ Ú¤ Ú¥ Ú¦ Ú§ Ú¨ Ú© +- Úª Ú« Ú¬ Ú­ Ú® Ú¯ Ú° Ú± Ú² Ú³ Ú´ Úµ Ú¶ Ú· Ú¸ Ú¹ +- Úº Ú» Ú¼ Ú½ Ú¾ Ú¿ ÚÀ ÚÁ Ú Úà ÚÄ ÚÅ ÚÆ ÚÇ ÚÈ ÚÉ +- ÚÊ ÚË ÚÌ ÚÍ ÚÎ ÚÏ ÚÐ ÚÑ ÚÒ ÚÓ ÚÔ ÚÕ ÚÖ Ú× ÚØ ÚÙ +- ÚÚ ÚÛ ÚÜ ÚÝ ÚÞ Úß Úà Úá Úâ Úã Úä Úå Úæ Úç Úè Úé +- Úê Úë Úì Úí Úî Úï Úð Úñ Úò Úó Úô Úõ Úö Ú÷ Úø Úù +- Úú Úû Úü Úý Úþ Û@ Û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 +- Û[ Û\ Û] Û^ Û_ Û` Û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 +- Û{ Û| Û} Û~ Û¡ Û¢ Û£ Û¤ Û¥ Û¦ Û§ Û¨ Û© Ûª Û« Û¬ +- Û­ Û® Û¯ Û° Û± Û² Û³ Û´ Ûµ Û¶ Û· Û¸ Û¹ Ûº Û» Û¼ +- Û½ Û¾ Û¿ ÛÀ ÛÁ Û Ûà ÛÄ ÛÅ ÛÆ ÛÇ ÛÈ ÛÉ ÛÊ ÛË ÛÌ +- ÛÍ ÛÎ ÛÏ ÛÐ ÛÑ ÛÒ ÛÓ ÛÔ ÛÕ ÛÖ Û× ÛØ ÛÙ ÛÚ ÛÛ ÛÜ +- ÛÝ ÛÞ Ûß Ûà Ûá Ûâ Ûã Ûä Ûå Ûæ Ûç Ûè Ûé Ûê Ûë Ûì +- Ûí Ûî Ûï Ûð Ûñ Ûò Ûó Ûô Ûõ Ûö Û÷ Ûø Ûù Ûú Ûû Ûü +- Ûý Ûþ Ü@ Ü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 Ü[ Ü\ Ü] +- Ü^ Ü_ Ü` Ü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 Ü{ Ü| Ü} +- Ü~ Ü¡ Ü¢ Ü£ ܤ Ü¥ ܦ ܧ ܨ Ü© ܪ Ü« ܬ Ü­ Ü® ܯ +- Ü° ܱ ܲ ܳ Ü´ ܵ ܶ Ü· ܸ ܹ ܺ Ü» ܼ ܽ ܾ Ü¿ +- ÜÀ ÜÁ Ü Üà ÜÄ ÜÅ ÜÆ ÜÇ ÜÈ ÜÉ ÜÊ ÜË ÜÌ ÜÍ ÜÎ ÜÏ +- ÜÐ ÜÑ ÜÒ ÜÓ ÜÔ ÜÕ ÜÖ Ü× ÜØ ÜÙ ÜÚ ÜÛ ÜÜ ÜÝ ÜÞ Üß +- Üà Üá Üâ Üã Üä Üå Üæ Üç Üè Üé Üê Üë Üì Üí Üî Üï +- Üð Üñ Üò Üó Üô Üõ Üö Ü÷ Üø Üù Üú Üû Üü Üý Üþ Ý@ +- Ý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 Ý[ Ý\ Ý] Ý^ Ý_ Ý` +- Ý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 Ý{ Ý| Ý} Ý~ Ý¡ Ý¢ +- Ý£ ݤ Ý¥ ݦ ݧ ݨ Ý© ݪ Ý« ݬ Ý­ Ý® ݯ Ý° ݱ ݲ +- ݳ Ý´ ݵ ݶ Ý· ݸ ݹ ݺ Ý» ݼ ݽ ݾ Ý¿ ÝÀ ÝÁ Ý +- Ýà ÝÄ ÝÅ ÝÆ ÝÇ ÝÈ ÝÉ ÝÊ ÝË ÝÌ ÝÍ ÝÎ ÝÏ ÝÐ ÝÑ ÝÒ +- ÝÓ ÝÔ ÝÕ ÝÖ Ý× ÝØ ÝÙ ÝÚ ÝÛ ÝÜ ÝÝ ÝÞ Ýß Ýà Ýá Ýâ +- Ýã Ýä Ýå Ýæ Ýç Ýè Ýé Ýê Ýë Ýì Ýí Ýî Ýï Ýð Ýñ Ýò +- Ýó Ýô Ýõ Ýö Ý÷ Ýø Ýù Ýú Ýû Ýü Ýý Ýþ Þ@ Þ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 Þ[ Þ\ Þ] Þ^ Þ_ Þ` Þ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 Þ{ Þ| Þ} Þ~ Þ¡ Þ¢ Þ£ Þ¤ Þ¥ +- Þ¦ Þ§ Þ¨ Þ© Þª Þ« Þ¬ Þ­ Þ® Þ¯ Þ° Þ± Þ² Þ³ Þ´ Þµ +- Þ¶ Þ· Þ¸ Þ¹ Þº Þ» Þ¼ Þ½ Þ¾ Þ¿ ÞÀ ÞÁ Þ Þà ÞÄ ÞÅ +- ÞÆ ÞÇ ÞÈ ÞÉ ÞÊ ÞË ÞÌ ÞÍ ÞÎ ÞÏ ÞÐ ÞÑ ÞÒ ÞÓ ÞÔ ÞÕ +- ÞÖ Þ× ÞØ ÞÙ ÞÚ ÞÛ ÞÜ ÞÝ ÞÞ Þß Þà Þá Þâ Þã Þä Þå +- Þæ Þç Þè Þé Þê Þë Þì Þí Þî Þï Þð Þñ Þò Þó Þô Þõ +- Þö Þ÷ Þø Þù Þú Þû Þü Þý Þþ ß@ ß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 ß[ ß\ ß] ß^ ß_ ß` ß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 ß{ ß| ß} ß~ ß¡ ߢ ߣ ߤ ߥ ߦ ߧ ߨ +- ß© ߪ ß« ߬ ß­ ß® ߯ ß° ß± ß² ß³ ß´ ßµ ߶ ß· ߸ +- ß¹ ߺ ß» ß¼ ß½ ß¾ ß¿ ßÀ ßÁ ß ßà ßÄ ßÅ ßÆ ßÇ ßÈ +- ßÉ ßÊ ßË ßÌ ßÍ ßÎ ßÏ ßÐ ßÑ ßÒ ßÓ ßÔ ßÕ ßÖ ß× ßØ +- ßÙ ßÚ ßÛ ßÜ ßÝ ßÞ ßß ßà ßá ßâ ßã ßä ßå ßæ ßç ßè +- ßé ßê ßë ßì ßí ßî ßï ßð ßñ ßò ßó ßô ßõ ßö ß÷ ßø +- ßù ßú ßû ßü ßý ßþ à@ à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 à[ à\ à] à^ à_ à` à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 à{ à| à} à~ ࡠࢠ࣠ठॠঠৠਠ੠ઠૠ+- ଠୠ஠௠ఠౠಠೠഠൠච෠ภ๠ຠ໠+- ༠འྠ࿠àÀ àÁ à àà àÄ àÅ àÆ àÇ àÈ àÉ àÊ àË +- àÌ àÍ àÎ àÏ àÐ àÑ àÒ àÓ àÔ àÕ àÖ à× àØ àÙ àÚ àÛ +- àÜ àÝ àÞ àß àà àá àâ àã àä àå àæ àç àè àé àê àë +- àì àí àî àï àð àñ àò àó àô àõ àö à÷ àø àù àú àû +- àü àý àþ á@ á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 á[ á\ +- á] á^ á_ á` á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 á{ á| +- á} á~ ᡠᢠᣠᤠᥠᦠ᧠ᨠ᩠᪠᫠ᬠ᭠ᮠ+- ᯠᰠᱠᲠ᳠ᴠᵠᶠᷠḠṠẠỠἠὠᾠ+- á¿ áÀ áÁ á áà áÄ áÅ áÆ áÇ áÈ áÉ áÊ áË áÌ áÍ áÎ +- áÏ áÐ áÑ áÒ áÓ áÔ áÕ áÖ á× áØ áÙ áÚ áÛ áÜ áÝ áÞ +- áß áà áá áâ áã áä áå áæ áç áè áé áê áë áì áí áî +- áï áð áñ áò áó áô áõ áö á÷ áø áù áú áû áü áý áþ +- â@ â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 â[ â\ â] â^ â_ +- â` â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 â{ â| â} â~ â¡ +- ⢠⣠⤠⥠⦠⧠⨠⩠⪠⫠⬠⭠⮠⯠ⰠⱠ+- ⲠⳠⴠⵠⶠⷠ⸠⹠⺠⻠⼠⽠⾠⿠âÀ âÁ +- â âà âÄ âÅ âÆ âÇ âÈ âÉ âÊ âË âÌ âÍ âÎ âÏ âÐ âÑ +- âÒ âÓ âÔ âÕ âÖ â× âØ âÙ âÚ âÛ âÜ âÝ âÞ âß âà âá +- ââ âã âä âå âæ âç âè âé âê âë âì âí âî âï âð âñ +- âò âó âô âõ âö â÷ âø âù âú âû âü âý âþ ã@ ã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 ã[ ã\ ã] ã^ ã_ ã` ã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 ã{ ã| ã} ã~ 㡠㢠㣠㤠+- 㥠㦠㧠㨠㩠㪠㫠㬠㭠㮠㯠㰠㱠㲠㳠㴠+- 㵠㶠㷠㸠㹠㺠㻠㼠㽠㾠㿠ãÀ ãÁ ã ãà ãÄ +- ãÅ ãÆ ãÇ ãÈ ãÉ ãÊ ãË ãÌ ãÍ ãÎ ãÏ ãÐ ãÑ ãÒ ãÓ ãÔ +- ãÕ ãÖ ã× ãØ ãÙ ãÚ ãÛ ãÜ ãÝ ãÞ ãß ãà ãá ãâ ãã ãä +- ãå ãæ ãç ãè ãé ãê ãë ãì ãí ãî ãï ãð ãñ ãò ãó ãô +- ãõ ãö ã÷ ãø ãù ãú ãû ãü ãý ãþ ä@ ä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 ä[ ä\ ä] ä^ ä_ ä` ä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 ä{ ä| ä} ä~ ä¡ ä¢ ä£ ä¤ ä¥ ä¦ ä§ +- ä¨ ä© äª ä« ä¬ ä­ ä® ä¯ ä° ä± ä² ä³ ä´ äµ ä¶ ä· +- ä¸ ä¹ äº ä» ä¼ ä½ ä¾ ä¿ äÀ äÁ ä äà äÄ äÅ äÆ äÇ +- äÈ äÉ äÊ äË äÌ äÍ äÎ äÏ äÐ äÑ äÒ äÓ äÔ äÕ äÖ ä× +- äØ äÙ äÚ äÛ äÜ äÝ äÞ äß äà äá äâ äã ää äå äæ äç +- äè äé äê äë äì äí äî äï äð äñ äò äó äô äõ äö ä÷ +- äø äù äú äû äü äý äþ å@ å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 å[ å\ å] å^ å_ å` å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 å{ å| å} å~ å¡ å¢ å£ å¤ å¥ å¦ å§ å¨ å© åª +- å« å¬ å­ å® å¯ å° å± å² å³ å´ åµ å¶ å· å¸ å¹ åº +- å» å¼ å½ å¾ å¿ åÀ åÁ å åà åÄ åÅ åÆ åÇ åÈ åÉ åÊ +- åË åÌ åÍ åÎ åÏ åÐ åÑ åÒ åÓ åÔ åÕ åÖ å× åØ åÙ åÚ +- åÛ åÜ åÝ åÞ åß åà åá åâ åã åä åå åæ åç åè åé åê +- åë åì åí åî åï åð åñ åò åó åô åõ åö å÷ åø åù åú +- åû åü åý åþ æ@ æ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 æ[ +- æ\ æ] æ^ æ_ æ` æ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 æ{ +- æ| æ} æ~ æ¡ æ¢ æ£ æ¤ æ¥ æ¦ æ§ æ¨ æ© æª æ« æ¬ æ­ +- æ® æ¯ æ° æ± æ² æ³ æ´ æµ æ¶ æ· æ¸ æ¹ æº æ» æ¼ æ½ +- æ¾ æ¿ æÀ æÁ æ æà æÄ æÅ æÆ æÇ æÈ æÉ æÊ æË æÌ æÍ +- æÎ æÏ æÐ æÑ æÒ æÓ æÔ æÕ æÖ æ× æØ æÙ æÚ æÛ æÜ æÝ +- æÞ æß æà æá æâ æã æä æå ææ æç æè æé æê æë æì æí +- æî æï æð æñ æò æó æô æõ æö æ÷ æø æù æú æû æü æý +- æþ ç@ ç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 ç[ ç\ ç] ç^ +- ç_ ç` ç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 ç{ ç| ç} ç~ +- ç¡ ç¢ ç£ ç¤ ç¥ ç¦ ç§ ç¨ ç© çª ç« ç¬ ç­ ç® ç¯ ç° +- ç± ç² ç³ ç´ çµ ç¶ ç· ç¸ ç¹ çº ç» ç¼ ç½ ç¾ ç¿ çÀ +- çÁ ç çà çÄ çÅ çÆ çÇ çÈ çÉ çÊ çË çÌ çÍ çÎ çÏ çÐ +- çÑ çÒ çÓ çÔ çÕ çÖ ç× çØ çÙ çÚ çÛ çÜ çÝ çÞ çß çà +- çá çâ çã çä çå çæ çç çè çé çê çë çì çí çî çï çð +- çñ çò çó çô çõ çö ç÷ çø çù çú çû çü çý çþ è@ è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 è[ è\ è] è^ è_ è` è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 è{ è| è} è~ è¡ è¢ è£ +- è¤ è¥ è¦ è§ è¨ è© èª è« è¬ è­ è® è¯ è° è± è² è³ +- è´ èµ è¶ è· è¸ è¹ èº è» è¼ è½ è¾ è¿ èÀ èÁ è èà +- èÄ èÅ èÆ èÇ èÈ èÉ èÊ èË èÌ èÍ èÎ èÏ èÐ èÑ èÒ èÓ +- èÔ èÕ èÖ è× èØ èÙ èÚ èÛ èÜ èÝ èÞ èß èà èá èâ èã +- èä èå èæ èç èè èé èê èë èì èí èî èï èð èñ èò èó +- èô èõ èö è÷ èø èù èú èû èü èý èþ é@ é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 é[ é\ é] é^ é_ é` é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 é{ é| é} é~ é¡ é¢ é£ é¤ é¥ é¦ +- é§ é¨ é© éª é« é¬ é­ é® é¯ é° é± é² é³ é´ éµ é¶ +- é· é¸ é¹ éº é» é¼ é½ é¾ é¿ éÀ éÁ é éà éÄ éÅ éÆ +- éÇ éÈ éÉ éÊ éË éÌ éÍ éÎ éÏ éÐ éÑ éÒ éÓ éÔ éÕ éÖ +- é× éØ éÙ éÚ éÛ éÜ éÝ éÞ éß éà éá éâ éã éä éå éæ +- éç éè éé éê éë éì éí éî éï éð éñ éò éó éô éõ éö +- é÷ éø éù éú éû éü éý éþ ê@ ê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 ê[ ê\ ê] ê^ ê_ ê` ê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 ê{ ê| ê} ê~ ê¡ ê¢ ê£ ê¤ ê¥ ê¦ ê§ ê¨ ê© +- êª ê« ê¬ ê­ ê® ê¯ ê° ê± ê² ê³ ê´ êµ ê¶ ê· ê¸ ê¹ +- êº ê» ê¼ ê½ ê¾ ê¿ êÀ êÁ ê êà êÄ êÅ êÆ êÇ êÈ êÉ +- êÊ êË êÌ êÍ êÎ êÏ êÐ êÑ êÒ êÓ êÔ êÕ êÖ ê× êØ êÙ +- êÚ êÛ êÜ êÝ êÞ êß êà êá êâ êã êä êå êæ êç êè êé +- êê êë êì êí êî êï êð êñ êò êó êô êõ êö ê÷ êø êù +- êú êû êü êý êþ ë@ ë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 +- ë[ ë\ ë] ë^ ë_ ë` ë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 +- ë{ ë| ë} ë~ ë¡ ë¢ ë£ ë¤ ë¥ ë¦ ë§ ë¨ ë© ëª ë« ë¬ +- ë­ ë® ë¯ ë° ë± ë² ë³ ë´ ëµ ë¶ ë· ë¸ ë¹ ëº ë» ë¼ +- ë½ ë¾ ë¿ ëÀ ëÁ ë ëà ëÄ ëÅ ëÆ ëÇ ëÈ ëÉ ëÊ ëË ëÌ +- ëÍ ëÎ ëÏ ëÐ ëÑ ëÒ ëÓ ëÔ ëÕ ëÖ ë× ëØ ëÙ ëÚ ëÛ ëÜ +- ëÝ ëÞ ëß ëà ëá ëâ ëã ëä ëå ëæ ëç ëè ëé ëê ëë ëì +- ëí ëî ëï ëð ëñ ëò ëó ëô ëõ ëö ë÷ ëø ëù ëú ëû ëü +- ëý ëþ ì@ ì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 ì[ ì\ ì] +- ì^ ì_ ì` ì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 ì{ ì| ì} +- ì~ ì¡ ì¢ ì£ ì¤ ì¥ ì¦ ì§ ì¨ ì© ìª ì« ì¬ ì­ ì® ì¯ +- ì° ì± ì² ì³ ì´ ìµ ì¶ ì· ì¸ ì¹ ìº ì» ì¼ ì½ ì¾ ì¿ +- ìÀ ìÁ ì ìà ìÄ ìÅ ìÆ ìÇ ìÈ ìÉ ìÊ ìË ìÌ ìÍ ìÎ ìÏ +- ìÐ ìÑ ìÒ ìÓ ìÔ ìÕ ìÖ ì× ìØ ìÙ ìÚ ìÛ ìÜ ìÝ ìÞ ìß +- ìà ìá ìâ ìã ìä ìå ìæ ìç ìè ìé ìê ìë ìì ìí ìî ìï +- ìð ìñ ìò ìó ìô ìõ ìö ì÷ ìø ìù ìú ìû ìü ìý ìþ í@ +- í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 í[ í\ í] í^ í_ í` +- í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 í{ í| í} í~ í¡ í¢ +- í£ í¤ í¥ í¦ í§ í¨ í© íª í« í¬ í­ í® í¯ í° í± í² +- í³ í´ íµ í¶ í· í¸ í¹ íº í» í¼ í½ í¾ í¿ íÀ íÁ í +- íà íÄ íÅ íÆ íÇ íÈ íÉ íÊ íË íÌ íÍ íÎ íÏ íÐ íÑ íÒ +- íÓ íÔ íÕ íÖ í× íØ íÙ íÚ íÛ íÜ íÝ íÞ íß íà íá íâ +- íã íä íå íæ íç íè íé íê íë íì íí íî íï íð íñ íò +- íó íô íõ íö í÷ íø íù íú íû íü íý íþ î@ î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 î[ î\ î] î^ î_ î` î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 î{ î| î} î~ î¡ î¢ î£ î¤ î¥ +- î¦ î§ î¨ î© îª î« î¬ î­ î® î¯ î° î± î² î³ î´ îµ +- î¶ î· î¸ î¹ îº î» î¼ î½ î¾ î¿ îÀ îÁ î îà îÄ îÅ +- îÆ îÇ îÈ îÉ îÊ îË îÌ îÍ îÎ îÏ îÐ îÑ îÒ îÓ îÔ îÕ +- îÖ î× îØ îÙ îÚ îÛ îÜ îÝ îÞ îß îà îá îâ îã îä îå +- îæ îç îè îé îê îë îì îí îî îï îð îñ îò îó îô îõ +- îö î÷ îø îù îú îû îü îý îþ ï@ ï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 ï[ ï\ ï] ï^ ï_ ï` ï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 ï{ ï| ï} ï~ ï¡ ï¢ ï£ ï¤ ï¥ ï¦ ï§ ï¨ +- ï© ïª ï« ï¬ ï­ ï® ï¯ ï° ï± ï² ï³ ï´ ïµ ï¶ ï· ï¸ +- ï¹ ïº ï» ï¼ ï½ ï¾ ï¿ ïÀ ïÁ ï ïà ïÄ ïÅ ïÆ ïÇ ïÈ +- ïÉ ïÊ ïË ïÌ ïÍ ïÎ ïÏ ïÐ ïÑ ïÒ ïÓ ïÔ ïÕ ïÖ ï× ïØ +- ïÙ ïÚ ïÛ ïÜ ïÝ ïÞ ïß ïà ïá ïâ ïã ïä ïå ïæ ïç ïè +- ïé ïê ïë ïì ïí ïî ïï ïð ïñ ïò ïó ïô ïõ ïö ï÷ ïø +- ïù ïú ïû ïü ïý ïþ ð@ ð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 ð[ ð\ ð] ð^ ð_ ð` ð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 ð{ ð| ð} ð~ ð¡ ð¢ ð£ ð¤ ð¥ ð¦ ð§ ð¨ ð© ðª ð« +- ð¬ ð­ ð® ð¯ ð° ð± ð² ð³ ð´ ðµ ð¶ ð· ð¸ ð¹ ðº ð» +- ð¼ ð½ ð¾ ð¿ ðÀ ðÁ ð ðà ðÄ ðÅ ðÆ ðÇ ðÈ ðÉ ðÊ ðË +- ðÌ ðÍ ðÎ ðÏ ðÐ ðÑ ðÒ ðÓ ðÔ ðÕ ðÖ ð× ðØ ðÙ ðÚ ðÛ +- ðÜ ðÝ ðÞ ðß ðà ðá ðâ ðã ðä ðå ðæ ðç ðè ðé ðê ðë +- ðì ðí ðî ðï ðð ðñ ðò ðó ðô ðõ ðö ð÷ ðø ðù ðú ðû +- ðü ðý ðþ ñ@ ñ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 ñ[ ñ\ +- ñ] ñ^ ñ_ ñ` ñ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 ñ{ ñ| +- ñ} ñ~ ñ¡ ñ¢ ñ£ ñ¤ ñ¥ ñ¦ ñ§ ñ¨ ñ© ñª ñ« ñ¬ ñ­ ñ® +- ñ¯ ñ° ñ± ñ² ñ³ ñ´ ñµ ñ¶ ñ· ñ¸ ñ¹ ñº ñ» ñ¼ ñ½ ñ¾ +- ñ¿ ñÀ ñÁ ñ ñà ñÄ ñÅ ñÆ ñÇ ñÈ ñÉ ñÊ ñË ñÌ ñÍ ñÎ +- ñÏ ñÐ ñÑ ñÒ ñÓ ñÔ ñÕ ñÖ ñ× ñØ ñÙ ñÚ ñÛ ñÜ ñÝ ñÞ +- ñß ñà ñá ñâ ñã ñä ñå ñæ ñç ñè ñé ñê ñë ñì ñí ñî +- ñï ñð ññ ñò ñó ñô ñõ ñö ñ÷ ñø ñù ñú ñû ñü ñý ñþ +- ò@ ò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 ò[ ò\ ò] ò^ ò_ +- ò` ò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 ò{ ò| ò} ò~ ò¡ +- ò¢ ò£ ò¤ ò¥ ò¦ ò§ ò¨ ò© òª ò« ò¬ ò­ ò® ò¯ ò° ò± +- ò² ò³ ò´ òµ ò¶ ò· ò¸ ò¹ òº ò» ò¼ ò½ ò¾ ò¿ òÀ òÁ +- ò òà òÄ òÅ òÆ òÇ òÈ òÉ òÊ òË òÌ òÍ òÎ òÏ òÐ òÑ +- òÒ òÓ òÔ òÕ òÖ ò× òØ òÙ òÚ òÛ òÜ òÝ òÞ òß òà òá +- òâ òã òä òå òæ òç òè òé òê òë òì òí òî òï òð òñ +- òò òó òô òõ òö ò÷ òø òù òú òû òü òý òþ ó@ ó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 ó[ ó\ ó] ó^ ó_ ó` ó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 ó{ ó| ó} ó~ ó¡ ó¢ ó£ ó¤ +- ó¥ ó¦ ó§ ó¨ ó© óª ó« ó¬ ó­ ó® ó¯ ó° ó± ó² ó³ ó´ +- óµ ó¶ ó· ó¸ ó¹ óº ó» ó¼ ó½ ó¾ ó¿ óÀ óÁ ó óà óÄ +- óÅ óÆ óÇ óÈ óÉ óÊ óË óÌ óÍ óÎ óÏ óÐ óÑ óÒ óÓ óÔ +- óÕ óÖ ó× óØ óÙ óÚ óÛ óÜ óÝ óÞ óß óà óá óâ óã óä +- óå óæ óç óè óé óê óë óì óí óî óï óð óñ óò óó óô +- óõ óö ó÷ óø óù óú óû óü óý óþ ô@ ô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 ô[ ô\ ô] ô^ ô_ ô` ô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 ô{ ô| ô} ô~ ô¡ ô¢ ô£ ô¤ ô¥ ô¦ ô§ +- ô¨ ô© ôª ô« ô¬ ô­ ô® ô¯ ô° ô± ô² ô³ ô´ ôµ ô¶ ô· +- ô¸ ô¹ ôº ô» ô¼ ô½ ô¾ ô¿ ôÀ ôÁ ô ôà ôÄ ôÅ ôÆ ôÇ +- ôÈ ôÉ ôÊ ôË ôÌ ôÍ ôÎ ôÏ ôÐ ôÑ ôÒ ôÓ ôÔ ôÕ ôÖ ô× +- ôØ ôÙ ôÚ ôÛ ôÜ ôÝ ôÞ ôß ôà ôá ôâ ôã ôä ôå ôæ ôç +- ôè ôé ôê ôë ôì ôí ôî ôï ôð ôñ ôò ôó ôô ôõ ôö ô÷ +- ôø ôù ôú ôû ôü ôý ôþ õ@ õ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 õ[ õ\ õ] õ^ õ_ õ` õ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 õ{ õ| õ} õ~ õ¡ õ¢ õ£ õ¤ õ¥ õ¦ õ§ õ¨ õ© õª +- õ« õ¬ õ­ õ® õ¯ õ° õ± õ² õ³ õ´ õµ õ¶ õ· õ¸ õ¹ õº +- õ» õ¼ õ½ õ¾ õ¿ õÀ õÁ õ õà õÄ õÅ õÆ õÇ õÈ õÉ õÊ +- õË õÌ õÍ õÎ õÏ õÐ õÑ õÒ õÓ õÔ õÕ õÖ õ× õØ õÙ õÚ +- õÛ õÜ õÝ õÞ õß õà õá õâ õã õä õå õæ õç õè õé õê +- õë õì õí õî õï õð õñ õò õó õô õõ õö õ÷ õø õù õú +- õû õü õý õþ ö@ ö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 ö[ +- ö\ ö] ö^ ö_ ö` ö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 ö{ +- ö| ö} ö~ ö¡ ö¢ ö£ ö¤ ö¥ ö¦ ö§ ö¨ ö© öª ö« ö¬ ö­ +- ö® ö¯ ö° ö± ö² ö³ ö´ öµ ö¶ ö· ö¸ ö¹ öº ö» ö¼ ö½ +- ö¾ ö¿ öÀ öÁ ö öà öÄ öÅ öÆ öÇ öÈ öÉ öÊ öË öÌ öÍ +- öÎ öÏ öÐ öÑ öÒ öÓ öÔ öÕ öÖ ö× öØ öÙ öÚ öÛ öÜ öÝ +- öÞ öß öà öá öâ öã öä öå öæ öç öè öé öê öë öì öí +- öî öï öð öñ öò öó öô öõ öö ö÷ öø öù öú öû öü öý +- öþ ÷@ ÷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 ÷[ ÷\ ÷] ÷^ +- ÷_ ÷` ÷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 ÷{ ÷| ÷} ÷~ +- ÷¡ ÷¢ ÷£ ÷¤ ÷¥ ÷¦ ÷§ ÷¨ ÷© ÷ª ÷« ÷¬ ÷­ ÷® ÷¯ ÷° +- ÷± ÷² ÷³ ÷´ ÷µ ÷¶ ÷· ÷¸ ÷¹ ÷º ÷» ÷¼ ÷½ ÷¾ ÷¿ ÷À +- ÷Á ÷ ÷à ÷Ä ÷Å ÷Æ ÷Ç ÷È ÷É ÷Ê ÷Ë ÷Ì ÷Í ÷Î ÷Ï ÷Ð +- ÷Ñ ÷Ò ÷Ó ÷Ô ÷Õ ÷Ö ÷× ÷Ø ÷Ù ÷Ú ÷Û ÷Ü ÷Ý ÷Þ ÷ß ÷à +- ÷á ÷â ÷ã ÷ä ÷å ÷æ ÷ç ÷è ÷é ÷ê ÷ë ÷ì ÷í ÷î ÷ï ÷ð +- ÷ñ ÷ò ÷ó ÷ô ÷õ ÷ö ÷÷ ÷ø ÷ù ÷ú ÷û ÷ü ÷ý ÷þ ø@ ø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 ø[ ø\ ø] ø^ ø_ ø` ø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 ø{ ø| ø} ø~ ø¡ ø¢ ø£ +- ø¤ ø¥ ø¦ ø§ ø¨ ø© øª ø« ø¬ ø­ ø® ø¯ ø° ø± ø² ø³ +- ø´ øµ ø¶ ø· ø¸ ø¹ øº ø» ø¼ ø½ ø¾ ø¿ øÀ øÁ ø øà +- øÄ øÅ øÆ øÇ øÈ øÉ øÊ øË øÌ øÍ øÎ øÏ øÐ øÑ øÒ øÓ +- øÔ øÕ øÖ ø× øØ øÙ øÚ øÛ øÜ øÝ øÞ øß øà øá øâ øã +- øä øå øæ øç øè øé øê øë øì øí øî øï øð øñ øò øó +- øô øõ øö ø÷ øø øù øú øû øü øý øþ ù@ ù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 ù[ ù\ ù] ù^ ù_ ù` ù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 ù{ ù| ù} ù~ ù¡ ù¢ ù£ ù¤ ù¥ ù¦ +- ù§ ù¨ ù© ùª ù« ù¬ ù­ ù® ù¯ ù° ù± ù² ù³ ù´ ùµ ù¶ +- ù· ù¸ ù¹ ùº ù» ù¼ ù½ ù¾ ù¿ ùÀ ùÁ ù ùà ùÄ ùÅ ùÆ +- ùÇ ùÈ ùÉ ùÊ ùË ùÌ ùÍ ùÎ ùÏ ùÐ ùÑ ùÒ ùÓ ùÔ ùÕ ùÖ +- ù× ùØ ùÙ ùÚ ùÛ ùÜ ùÝ ùÞ ùß ùà ùá ùâ ùã ùä ùå ùæ +- ùç ùè ùé ùê ùë ùì ùí ùî ùï ùð ùñ ùò ùó ùô ùõ ùö +- ù÷ ùø ùù ùú ùû ùü ùý ùþ ú@ ú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 ú[ ú\ ú] ú^ ú` úa úb úc úd úe úg úh úi +- új úk úl úm ún úo úp úq úr ús út úu úv úw úx úy +- úz ú{ ú| ú} ú~ ú¡ ú¢ ú£ ú¤ ú¥ ú¦ ú§ ú¨ ú© úª ú« +- ú¬ ú­ ú® ú¯ ú° ú± ú² ú³ ú´ úµ ú¶ ú· ú¸ ú¹ úº ú» +- ú¼ ú¾ ú¿ úÀ úÁ ú úà úÄ úÆ úÇ úÈ úÉ úÊ úË úÌ úÍ +- úÎ úÏ úÐ úÑ úÒ úÓ úÔ úÖ ú× úØ úÙ úÚ úÛ úÜ úÝ úÞ +- úß úà úá úâ úã úä úå úæ úç úè úé úê úë úì úí úî +- úï úð úñ úò úó úô úõ úö ú÷ úø úù úú úû úü úý úþ +- û@ ûA ûB ûC ûD ûE ûF ûG ûI ûJ ûK ûL ûM ûN ûO ûP +- ûQ ûR ûS ûT ûU ûV ûW ûX ûY ûZ û[ û\ û] û^ û_ û` +- û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 û{ û| û} û~ û¡ û¢ +- û£ û¤ û¥ û¦ û§ û¨ û© ûª û« û¬ û­ û® û¯ û° û± û² +- û³ û´ ûµ û¶ û· û¹ ûº û» û¼ û½ û¾ û¿ ûÀ ûÁ û ûà +- ûÄ ûÅ ûÆ ûÇ ûÈ ûÉ ûÊ ûË ûÌ ûÍ ûÎ ûÏ ûÐ ûÑ ûÒ ûÓ +- ûÔ ûÕ ûÖ û× ûØ ûÙ ûÚ ûÛ ûÜ ûÝ ûÞ ûß ûà ûá ûâ ûã +- ûä ûå ûæ ûç ûè ûé ûê ûë ûì ûí ûî ûï ûð ûñ ûò ûô +- ûõ ûö û÷ ûø ûú ûû ûü ûý ûþ ü@ üA üB üC üD üE üF +- üG üH üI üJ üK üL üM üN üP üQ üR üS üT üU üV üW +- üX üY üZ ü[ ü\ ü] ü^ ü_ ü` üa üb üc üd üe üf üg +- üh üi üj ük üm ün üo üp üq ür üs üt üu üv üw üx +- üy üz ü{ ü| ü} ü~ ü¡ ü¢ ü£ ü¤ ü¥ ü¦ ü§ ü¨ ü© üª +- ü« ü¬ ü­ ü® ü¯ ü° ü± ü² ü³ ü´ üµ ü¶ ü· ü¸ üº ü» +- ü¼ ü½ ü¾ ü¿ üÀ üÁ ü üà üÄ üÅ üÆ üÇ üÈ üÉ üÊ üË +- üÌ üÍ üÎ üÏ üÐ üÑ üÒ üÓ üÔ üÕ üÖ ü× üØ üÙ üÚ üÛ +- üÜ üÝ üÞ üß üà üá üã üä üå üæ üç üè üé üê üë üì +- üí üî üï üð üò üó üô üõ üö ü÷ üø üù üú üû üü üý +- üþ ý@ ý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 ý[ ý\ ý] ý^ +- ý_ ý` ý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 ý{ ý| ý} ý~ +- ý¡ ý¢ ý£ ý¤ ý¥ ý¦ ý§ ý¨ ý© ýª ý« ý¬ ý­ ý® ý¯ ý° +- ý± ý² ý³ ý´ ýµ ý¶ ý¹ ýº ý¼ ý½ ý¾ ý¿ ýÀ ýÁ ý ýà +- ýÄ ýÅ ýÆ ýÇ ýÈ ýÉ ýÊ ýË ýÌ ýÍ ýÎ ýÏ ýÐ ýÑ ýÒ ýÓ +- ýÔ ýÕ ýÖ ý× ýØ ýÙ ýÚ ýÛ ýÜ ýÝ ýÞ ýß ýà ýá ýâ ýã +- ýä ýå ýæ ýç ýè ýé ýê ýë ýì ýí ýî ýï ýð ýò ýó ýô +- ýõ ýö ý÷ ýø ýù ýú ýû ýü ýý ýþ þ@ þA þB þC þD þE +- þF þG þH þI þJ þK þL þM þN þO þP þQ þS þT þU þV +- þW þX þY þZ þ[ þ\ þ] þ^ þ_ þ` þa þb þc þd þe þf +- þg þh þi þj þk þl þm þn þp þq þr þs þt þu þv þw +- þx þy þz þ{ þ| þ} þ~ þ¡ þ¢ þ£ þ¤ þ¥ þ¦ þ§ þ¨ þ© +- þ« þ¬ þ­ þ® þ¯ þ° þ± þ² þ³ þ´ þµ þ¶ þ· þ¸ þ¹ þº +- þ» þ¼ þ½ þ¾ þ¿ þÀ þÁ þ þà þÄ þÅ þÆ þÇ þÈ þÉ þÊ +- þË þÌ þÍ þÎ þÏ þÐ þÑ þÒ þÓ þÔ þÕ þÖ þ× þØ þÙ þÚ +- þÛ þÜ þÞ þß þà þá þâ þã þä þå þæ þç þè þé þê þë +- þì þí þî þï þð þñ þò þó þô þõ þö þ÷ þø þù þú þû +- þü þý þþ ++ ‡@ ‡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 ‡[ ‡\ ‡] ‡^ ‡_ ++ ‡` ‡a ‡b ‡c ‡d ‡e ‡g ‡h ‡i ‡j ‡k ‡l ‡m ‡n ‡o ‡p ++ ‡q ‡r ‡s ‡t ‡u ‡v ‡w ‡x ‡y ‡z ‡{ ‡| ‡} ‡~ ‡¡ ‡¢ ++ ‡£ ‡¤ ‡¥ ‡¦ ‡§ ‡¨ ‡© ‡ª ‡« ‡¬ ‡­ ‡® ‡¯ ‡° ‡± ‡² ++ ‡³ ‡´ ‡µ ‡¶ ‡· ‡¸ ‡¹ ‡º ‡» ‡¼ ‡½ ‡¾ ‡¿ ‡À ‡Á ‡Â ++ ‡Ã ‡Ä ‡Å ‡Æ ‡Ç ‡È ‡É ‡Ê ‡Ë ‡Ì ‡Í ‡Î ‡Ï ‡Ð ‡Ñ ‡Ò ++ ‡Ó ‡Ô ‡Õ ‡Ö ‡× ‡Ø ‡Ù ‡Ú ‡Û ‡Ü ‡Ý ‡Þ ‡ß ˆ@ ˆ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 ˆ[ ˆ\ ˆ] ˆ^ ˆ_ ˆ` ˆ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 ˆ{ ˆ| ˆ} ˆ~ ˆ¡ ˆ¢ ˆ£ ˆ¤ ++ ˆ¥ ˆ¦ ˆ§ ˆ¨ ˆ© ˆª ‰@ ‰A ‰C ‰F ‰G ‰H ‰I ‰L ‰M ‰N ++ ‰O ‰P ‰Q ‰R ‰S ‰T ‰U ‰V ‰W ‰X ‰Y ‰Z ‰[ ‰\ ‰] ‰^ ++ ‰_ ‰` ‰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 ‰{ ‰| ‰} ‰~ ++ ‰¡ ‰¢ ‰£ ‰¤ ‰¥ ‰¦ ‰« ‰¬ ‰­ ‰® ‰° ‰± ‰² ‰µ ‰¶ ‰· ++ ‰¸ ‰¹ ‰º ‰» ‰¼ ‰½ ‰¾ ‰¿ ‰Á ‰Â ‰Ã ‰Å ‰Æ ‰Ç ‰È ‰É ++ ‰Ê ‰Ë ‰Ì ‰Í ‰Î ‰Ï ‰Ð ‰Ñ ‰Ò ‰Ó ‰Ô ‰Õ ‰Ö ‰× ‰Ø ‰Ù ++ ‰Ú ‰Û ‰Ü ‰Ý ‰Þ ‰ß ‰à ‰á ‰â ‰ã ‰ä ‰å ‰æ ‰ç ‰è ‰é ++ ‰ê ‰ë ‰ì ‰í ‰î ‰ï ‰ð ‰ñ ‰ò ‰ó ‰ô ‰õ ‰ö ‰÷ ‰ø ‰ù ++ ‰ú ‰û ‰ü ‰ý ‰þ Š@ ŠA ŠC ŠD ŠE ŠF ŠG ŠH ŠI ŠJ ŠK ++ ŠL ŠM ŠN ŠO ŠP ŠQ ŠR ŠS ŠT ŠU ŠV ŠW ŠX ŠY ŠZ Š[ ++ Š\ Š] Š^ Š_ Š` Ša Šb Šd Še Šf Šg Šh Ši Šj Šk Šl ++ Šm Šn Šo Šp Šq Šr Šs Št Šv Šw Šx Šy Šz Š{ Š| Š} ++ Š~ Š¡ Š¢ Š£ Š¤ Š¥ Š¦ Š§ Š¨ Š© Šª Š¬ Š­ Š® Š¯ Š° ++ Š² Š³ Š´ Šµ Š¶ Š· Š¸ Š¹ Š» Š¼ Š½ Š¾ Š¿ ŠÀ ŠÁ ŠÂ ++ ŠÃ ŠÄ ŠÅ ŠÆ ŠÇ ŠÉ ŠÊ ŠË ŠÌ ŠÎ ŠÏ ŠÐ ŠÑ ŠÒ ŠÓ ŠÔ ++ ŠÕ ŠÖ Š× ŠØ ŠÙ ŠÚ ŠÛ ŠÜ Šß Šà Šá Šâ Šã Šä Šå Šæ ++ Šç Šè Šé Šê Šë Šì Ší Šî Šï Šð Šñ Šò Šó Šô Šö Š÷ ++ Šø Šù Šú Šû Šü Šý Šþ ‹@ ‹A ‹B ‹C ‹D ‹E ‹F ‹G ‹H ++ ‹I ‹J ‹K ‹L ‹M ‹N ‹O ‹P ‹Q ‹R ‹S ‹U ‹V ‹W ‹X ‹Y ++ ‹Z ‹[ ‹\ ‹] ‹^ ‹_ ‹` ‹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 ‹{ ‹| ‹} ‹~ ‹¡ ‹¢ ‹£ ‹¤ ‹¥ ‹¦ ‹§ ‹¨ ‹© ‹ª ‹« ++ ‹¬ ‹­ ‹® ‹¯ ‹° ‹± ‹² ‹³ ‹´ ‹µ ‹¶ ‹· ‹¸ ‹¹ ‹º ‹» ++ ‹¼ ‹½ ‹¾ ‹¿ ‹À ‹Á ‹Â ‹Ã ‹Ä ‹Å ‹Æ ‹Ç ‹È ‹É ‹Ê ‹Ë ++ ‹Ì ‹Í ‹Î ‹Ï ‹Ð ‹Ñ ‹Ò ‹Ó ‹Ô ‹Õ ‹Ö ‹× ‹Ø ‹Ù ‹Ú ‹Û ++ ‹Ü ‹Þ ‹ß ‹à ‹á ‹â ‹ã ‹ä ‹å ‹æ ‹ç ‹è ‹é ‹ê ‹ë ‹ì ++ ‹í ‹î ‹ï ‹ð ‹ñ ‹ò ‹ó ‹ô ‹õ ‹ö ‹÷ ‹ø ‹ù ‹ú ‹û ‹ü ++ ‹ý Œ@ Œ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 Œ[ Œ\ Œ] Œ^ ++ Œ_ Œ` Œ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 Œ{ Œ| Œ} Œ~ ++ Œ¡ Œ¢ Œ£ Œ¤ Œ¥ Œ§ Œ¨ Œ© Œª Œ« Œ¬ Œ­ Œ® Œ¯ Œ° Œ± ++ Œ² Œ³ Œ´ Œµ Œ¶ Œ· Œ¸ Œ¹ Œº Œ» Œ¼ Œ½ Œ¾ Œ¿ ŒÀ ŒÁ ++ ŒÂ ŒÃ ŒÄ ŒÅ ŒÉ ŒÊ ŒË ŒÌ ŒÎ ŒÏ ŒÐ ŒÑ ŒÒ ŒÓ ŒÔ ŒÕ ++ ŒÖ Œ× ŒØ ŒÙ ŒÚ ŒÛ ŒÜ ŒÝ ŒÞ Œß Œà Œá Œâ Œã Œä Œæ ++ Œç Œè Œé Œê Œë Œì Œí Œî Œï Œð Œñ Œò Œó Œô Œõ Œö ++ Œ÷ Œø Œù Œú Œû Œü Œý Œþ @ 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 [ \ ] ^ _ ` 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 { | } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª ++ « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º ++ » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê ++ Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú ++ Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ++ ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú ++ û ü ý þ Ž@ Ž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 Ž[ ++ Ž\ Ž] Ž^ Ž_ Ž` Ža Žb Žc Žd Že Žf Žg Žh Žj Žk Žl ++ Žm Žn Žp Žq Žr Žs Žt Žu Žv Žw Žx Žy Žz Ž{ Ž| Ž} ++ Ž¡ Ž¢ Ž£ Ž¤ Ž¥ Ž¦ Ž§ Ž¨ Ž© Žª Ž¬ Ž­ Ž® Ž¯ Ž° Ž± ++ Ž² Ž³ Žµ Ž¶ Ž· Ž¸ Ž¹ Žº Ž» Ž¼ Ž½ Ž¾ Ž¿ ŽÀ ŽÁ ŽÂ ++ ŽÃ ŽÄ ŽÅ ŽÆ ŽÇ ŽÈ ŽÉ ŽÊ ŽË ŽÌ ŽÎ ŽÏ ŽÑ ŽÒ ŽÓ ŽÔ ++ ŽÕ ŽÖ Ž× ŽØ ŽÙ ŽÚ ŽÛ ŽÜ ŽÝ ŽÞ Žß Žà Žá Žâ Žã Žä ++ Žå Žæ Žç Žè Žé Žê Žë Žì Ží Žî Žï Žð Žñ Žò Žó Žô ++ Žõ Žö Ž÷ Žø Žù Žú Žû Žü Žý Žþ @ A B C D E ++ F G H I J K L M N O P Q R S T U ++ V X Y Z [ \ ] ^ _ ` a b c d e f ++ g h j k l m o p q r s t u v w x ++ y z { | } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª ++ « ¬ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º ++ » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ Ç È É Ê ++ Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü ++ Ý Þ ß à á â ã ä å æ ç è é ê ë ì ++ í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ++ ý @ 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 [ \ ] ^ ++ _ ` a b c d e f g h i j k l n o ++ p q r s t u v w x y { | } ~ ¡ ¢ ++ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ++ ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á  ++ Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò ++ Ó Ô Õ Ö × Ø Ù Ú Û Ý Þ ß à á â ã ++ ä å æ ç è é ê ë ì í î ï ð ò ó ô ++ õ ö ÷ ø ù ú û ü ý þ ‘@ ‘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 ‘[ ‘\ ‘] ‘^ ‘_ ‘` ‘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 ‘{ ‘| ‘} ‘~ ‘¡ ‘¢ ‘£ ‘¤ ‘¥ ‘¦ ‘§ ++ ‘¨ ‘© ‘ª ‘« ‘¬ ‘­ ‘® ‘¯ ‘° ‘± ‘² ‘³ ‘´ ‘µ ‘¶ ‘· ++ ‘¸ ‘¹ ‘º ‘» ‘¼ ‘½ ‘¾ ‘À ‘Á ‘ ‘à ‘Ä ‘Å ‘Æ ‘Ç ‘È ++ ‘É ‘Ê ‘Ë ‘Ì ‘Í ‘Î ‘Ï ‘Ð ‘Ñ ‘Ò ‘Ó ‘Ô ‘Õ ‘Ö ‘× ‘Ø ++ ‘Ù ‘Ú ‘Û ‘Ü ‘Ý ‘Þ ‘ß ‘à ‘á ‘â ‘ã ‘ä ‘å ‘æ ‘ç ‘è ++ ‘é ‘ê ‘ë ‘ì ‘í ‘î ‘ï ‘ð ‘ñ ‘ò ‘ó ‘ô ‘õ ‘ö ‘÷ ‘ø ++ ‘ù ‘ú ‘û ‘ü ‘ý ‘þ ’@ ’A ’B ’C ’E ’F ’G ’H ’I ’J ++ ’K ’L ’M ’N ’O ’P ’Q ’R ’S ’T ’U ’V ’W ’X ’Y ’Z ++ ’[ ’\ ’] ’^ ’_ ’` ’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 ++ ’{ ’| ’} ’~ ’¡ ’¢ ’£ ’¤ ’¥ ’¦ ’§ ’¨ ’© ’ª ’« ’¬ ++ ’­ ’® ’³ ’´ ’µ ’¶ ’· ’¸ ’¹ ’º ’» ’¼ ’½ ’¾ ’¿ ’À ++ ’Á ’ ’à ’Ä ’Å ’Æ ’Ç ’É ’Ê ’Ë ’Ì ’Í ’Î ’Ï ’Ð ’Ò ++ ’Ó ’Ô ’Õ ’Ö ’× ’Ø ’Ù ’Ú ’Û ’Ü ’Ý ’Þ ’ß ’à ’á ’â ++ ’ã ’ä ’å ’æ ’ç ’è ’é ’ê ’ë ’ì ’í ’î ’ï ’ð ’ñ ’ò ++ ’ó ’ô ’õ ’ö ’÷ ’ø ’ù ’ú ’û ’ü ’ý ’þ “@ “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 “[ “\ “] “^ “_ “` “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 “{ “| “} “~ “¡ “¢ “£ “¤ “¥ ++ “¦ “§ “¨ “© “ª “« “¬ “­ “® “¯ “° “± “² “³ “´ “µ ++ “¶ “· “¸ “¹ “º “» “¼ “½ “¾ “¿ “À “Á “ “à “Ä “Å ++ “Æ “Ç “È “É “Ê “Ë “Ì “Í “Î “Ï “Ð “Ñ “Ò “Ó “Ô “Õ ++ “Ö “× “Ø “Ù “Ú “Û “Ü “Ý “Þ “ß “à “á “â “ã “ä “å ++ “æ “ç “è “é “ê “ë “ì “í “î “ï “ð “ñ “ò “ó “ô “õ ++ “ö “÷ “ø “ù “ú “û “ü “ý “þ ”@ ”A ”B ”C ”D ”E ”F ++ ”H ”I ”J ”K ”L ”M ”N ”O ”P ”Q ”R ”S ”T ”U ”V ”W ++ ”X ”Y ”Z ”[ ”\ ”] ”^ ”_ ”` ”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 ”{ ”| ”} ”~ ”¡ ”¢ ”£ ”¤ ”¥ ”¦ ”§ ”¨ ”© ++ ”ª ”« ”¬ ”­ ”® ”¯ ”° ”± ”² ”³ ”´ ”µ ”¶ ”· ”¸ ”¹ ++ ”º ”» ”¼ ”½ ”¾ ”¿ ”À ”Á ” ”à ”Ä ”Å ”Æ ”Ç ”È ”É ++ ”Ë ”Ì ”Í ”Î ”Ï ”Ð ”Ñ ”Ò ”Ó ”Ô ”Õ ”Ö ”× ”Ø ”Ù ”Ú ++ ”Û ”Ü ”Ý ”Þ ”ß ”à ”á ”â ”ã ”ä ”å ”æ ”ç ”è ”é ”ê ++ ”ë ”ì ”í ”î ”ï ”ð ”ñ ”ò ”ó ”ô ”õ ”ö ”÷ ”ø ”ù ”ú ++ ”û ”ü ”ý ”þ •@ •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 •[ ++ •\ •] •^ •_ •` •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 •{ ++ •| •} •~ •¡ •¢ •£ •¤ •¥ •¦ •§ •¨ •© •ª •« •¬ •­ ++ •® •¯ •° •± •² •³ •´ •µ •¶ •· •¸ •¹ •º •» •¼ •½ ++ •¾ •¿ •À •Á •Â •Ã •Ä •Å •Æ •Ç •È •É •Ê •Ë •Ì •Í ++ •Î •Ï •Ð •Ñ •Ò •Ó •Ô •Õ •Ö •× •Ø •Ú •Û •Ü •Ý •Þ ++ •ß •à •á •â •ã •ä •å •æ •ç •è •é •ê •ë •ì •í •î ++ •ï •ð •ñ •ò •ó •ô •õ •ö •÷ •ø •ù •ú •û •ü •ý •þ ++ –@ –A –B –C –E –F –G –H –I –J –K –L –M –N –O –P ++ –Q –R –S –T –U –V –W –X –Y –Z –[ –\ –] –^ –_ –` ++ –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 –{ –| –} –~ –¡ –¢ ++ –£ –¤ –¥ –¦ –§ –¨ –© –ª –« –¬ –­ –® –¯ –° –± –² ++ –³ –´ –µ –¶ –· –¸ –¹ –º –» –¼ –½ –¾ –¿ –À –Á – ++ –à –Ä –Å –Æ –Ç –È –É –Ê –Ë –Ì –Í –Î –Ï –Ð –Ñ –Ò ++ –Ó –Ô –Õ –Ö –× –Ø –Ù –Ú –Û –Ü –Ý –Þ –ß –à –á –â ++ –ã –ä –å –æ –ç –è –é –ê –ë –ì –î –ï –ð –ñ –ò –ó ++ –ô –õ –ö –÷ –ø –ù –ú –û –ý –þ —@ —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 —[ —\ —] —^ —_ —` —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 —{ —| —} —~ —¡ —¢ —£ —¤ —¥ —¦ —§ ++ —¨ —© —ª —« —¬ —­ —® —¯ —° —± —² —³ —´ —µ —¶ —· ++ —¸ —¹ —º —» —¼ —½ —¾ —¿ —À —Á — —à —Ä —Å —Æ —Ç ++ —È —É —Ê —Ë —Ì —Í —Î —Ï —Ð —Ñ —Ò —Ó —Ô —Õ —Ö —× ++ —Ø —Ù —Ú —Û —Ü —Ý —Þ —ß —à —á —â —ã —ä —å —æ —ç ++ —è —é —ê —ë —ì —í —î —ï —ð —ñ —ò —ó —ô —õ —ö —÷ ++ —ø —ù —ú —û —ü —ý —þ ˜@ ˜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 ˜[ ˜\ ˜] ˜^ ˜_ ˜` ˜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 ˜{ ˜| ˜} ˜~ ˜¡ ˜¢ ˜£ ˜¤ ˜¥ ˜¦ ˜§ ˜¨ ˜© ˜ª ++ ˜« ˜¬ ˜­ ˜® ˜¯ ˜° ˜± ˜² ˜³ ˜´ ˜µ ˜¶ ˜· ˜¸ ˜¹ ˜º ++ ˜» ˜¼ ˜½ ˜¾ ˜¿ ˜À ˜Á ˜Â ˜Ã ˜Ä ˜Å ˜Æ ˜Ç ˜È ˜É ˜Ê ++ ˜Ë ˜Ì ˜Í ˜Î ˜Ï ˜Ð ˜Ñ ˜Ò ˜Ó ˜Ô ˜Õ ˜Ö ˜× ˜Ø ˜Ù ˜Ú ++ ˜Û ˜Ü ˜Ý ˜Þ ˜ß ˜à ˜á ˜â ˜ã ˜ä ˜å ˜æ ˜ç ˜è ˜é ˜ê ++ ˜ë ˜ì ˜í ˜î ˜ï ˜ð ˜ñ ˜ò ˜ó ˜ô ˜õ ˜ö ˜÷ ˜ø ˜ù ˜ú ++ ˜û ˜ü ˜ý ˜þ ™@ ™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 ™[ ++ ™\ ™] ™^ ™_ ™` ™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 ™{ ++ ™| ™} ™~ ™¡ ™¢ ™£ ™¤ ™¥ ™¦ ™§ ™¨ ™© ™ª ™« ™¬ ™­ ++ ™® ™¯ ™° ™± ™² ™³ ™´ ™µ ™¶ ™· ™¸ ™¹ ™º ™» ™¼ ™½ ++ ™¾ ™¿ ™À ™Á ™Â ™Ã ™Ä ™Å ™Æ ™Ç ™È ™É ™Ê ™Ë ™Ì ™Í ++ ™Î ™Ï ™Ð ™Ñ ™Ò ™Ó ™Ô ™Õ ™Ö ™× ™Ø ™Ù ™Ú ™Û ™Ü ™Ý ++ ™Þ ™ß ™à ™á ™â ™ã ™ä ™å ™æ ™ç ™è ™é ™ê ™ë ™ì ™í ++ ™î ™ï ™ð ™ñ ™ò ™ó ™ô ™õ ™ö ™÷ ™ø ™ù ™ú ™û ™ü ™ý ++ ™þ š@ š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 š[ š\ š] š^ ++ š_ š` š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 š{ š| š} š~ ++ š¡ š¢ š£ š¤ š¥ š¦ š§ š¨ š© šª š« š¬ š­ š® š¯ š° ++ š± š² š³ š´ šµ š¶ š· š¸ š¹ šº š» š¼ š½ š¾ š¿ šÀ ++ šÁ šÂ šÃ šÄ šÅ šÆ šÇ šÈ šÉ šÊ šË šÌ šÍ šÎ šÏ šÐ ++ šÑ šÒ šÓ šÔ šÕ šÖ š× šØ šÙ šÚ šÛ šÜ šÝ šÞ šß šà ++ šá šâ šã šä šå šæ šç šè šé šê šë šì ší šî šï šð ++ šñ šò šó šô šõ šö š÷ šø šù šú šû šü šý šþ ›@ ›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 ›[ ›\ ›] ›^ ›_ ›` ›b ++ ›c ›d ›e ›f ›g ›h ›i ›j ›k ›l ›m ›n ›o ›p ›q ›r ++ ›s ›t ›u ›w ›y ›z ›| ›} ›~ ›¡ ›¢ ›£ ›¤ ›¥ ›¦ ›§ ++ ›¨ ›© ›ª ›« ›¬ ›­ ›® ›¯ ›° ›± ›² ›³ ›´ ›µ ›¶ ›· ++ ›¸ ›¹ ›º ›» ›¼ ›½ ›¾ ›¿ ›À ›Á ›Â ›Ã ›Ä ›Å ›Ç ›È ++ ›É ›Ê ›Ë ›Ì ›Í ›Î ›Ï ›Ð ›Ñ ›Ò ›Ó ›Ô ›Õ ›Ö ›× ›Ø ++ ›Ù ›Ú ›Û ›Ü ›Ý ›ß ›à ›á ›â ›ã ›ä ›å ›æ ›ç ›è ›é ++ ›ê ›ë ›í ›î ›ï ›ð ›ñ ›ò ›ó ›ô ›õ ›÷ ›ø ›ù ›ú ›û ++ ›ü ›ý ›þ œ@ œA œC œD œE œF œG œH œI œJ œK œL œM ++ œN œO œP œQ œR œT œU œV œW œX œY œZ œ[ œ\ œ] œ^ ++ œ_ œ` œa œc œd œe œf œg œi œj œl œm œn œo œp œq ++ œr œs œt œu œv œx œy œz œ{ œ| œ} œ~ œ¡ œ¢ œ£ œ¤ ++ œ¥ œ¦ œ§ œ¨ œ© œª œ« œ¬ œ­ œ® œ¯ œ° œ± œ² œ³ œ´ ++ œµ œ¶ œ· œ¸ œ¹ œº œ» œ¾ œ¿ œÀ œÁ œÂ œÃ œÄ œÅ œÆ ++ œÇ œÈ œÉ œÊ œË œÌ œÍ œÎ œÏ œÑ œÒ œÓ œÔ œÕ œÖ œ× ++ œØ œÙ œÚ œÛ œÜ œÝ œÞ œß œà œá œâ œã œä œå œæ œç ++ œè œé œê œë œì œí œî œï œð œñ œò œó œô œõ œö œ÷ ++ œø œù œú œû œü œý œþ @ A B C D E F G H ++ I J K L M N O P Q R S T U V X Y ++ [ \ ] ^ _ ` 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 ++ { | } ~ ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ++ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ++ ½ ¾ ¿ À Á Â Ã Å Æ Ç È É Ê Ë Ì Í ++ Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý ++ Þ ß à á â ã ä å æ ç è é ê ë ì í ++ î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý ++ þ ž@ ž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 ž[ ž\ ž] ž^ ++ ž_ ž` ž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 ž{ ž| ž} ž~ ++ ž¡ ž¢ ž£ ž¤ ž¥ ž¦ ž§ ž¨ žª ž« ž­ ž® ž¯ ž° ž± ž² ++ ž³ ž´ žµ ž¶ ž· ž¸ ž¹ žº ž» ž¼ ž½ ž¾ ž¿ žÀ žÁ žÂ ++ žÃ žÅ žÆ žÇ žÈ žÉ žÊ žË žÌ žÍ žÎ žÏ žÐ žÑ žÒ žÓ ++ žÔ žÕ žÖ ž× žØ žÙ žÚ žÛ žÜ žÝ žÞ žß žà žá žâ žã ++ žä žå žæ žç žè žé žê žë žì ží žî žð žñ žò žó žõ ++ žö ž÷ žø žù žú žû žü žþ Ÿ@ ŸA ŸB ŸC ŸD ŸE ŸF ŸG ++ ŸH ŸI ŸJ ŸK ŸL ŸM ŸO ŸP ŸQ ŸR ŸS ŸT ŸU ŸV ŸW ŸX ++ ŸY ŸZ Ÿ[ Ÿ\ Ÿ] Ÿ^ Ÿ_ Ÿa Ÿb Ÿc Ÿd Ÿe Ÿg Ÿh Ÿi Ÿj ++ Ÿk Ÿl Ÿm Ÿn Ÿo Ÿp Ÿq Ÿr Ÿs Ÿt Ÿu Ÿv Ÿw Ÿx Ÿy Ÿz ++ Ÿ{ Ÿ| Ÿ} Ÿ~ Ÿ¡ Ÿ¢ Ÿ£ Ÿ¤ Ÿ¥ Ÿ¦ Ÿ§ Ÿ¨ Ÿ© Ÿª Ÿ« Ÿ¬ ++ Ÿ® Ÿ¯ Ÿ° Ÿ² Ÿ³ Ÿ´ Ÿµ Ÿ¶ Ÿ· Ÿ¸ Ÿ¹ Ÿº Ÿ» Ÿ¼ Ÿ½ Ÿ¾ ++ Ÿ¿ ŸÁ ŸÂ ŸÃ ŸÄ ŸÅ ŸÆ ŸÇ ŸÉ ŸÊ ŸÌ ŸÍ ŸÎ ŸÏ ŸÐ ŸÑ ++ ŸÒ ŸÓ ŸÔ ŸÕ ŸÖ Ÿ× ŸÙ ŸÛ ŸÜ ŸÝ ŸÞ Ÿß Ÿà Ÿá Ÿâ Ÿã ++ Ÿä Ÿå Ÿç Ÿè Ÿé Ÿë Ÿì Ÿí Ÿî Ÿð Ÿñ Ÿò Ÿó Ÿô Ÿõ Ÿö ++ Ÿ÷ Ÿø Ÿù Ÿú Ÿû Ÿü Ÿý Ÿþ  @  A  B  C  D  E  F  G ++  H  I  J  K  L  M  N  O  P  Q  R  S  U  V  X  Y ++  [  \  ]  ^  _  `  a  d  e  f  g  h  i  j  k  l ++  m  n  o  p  q  s  t  u  v  x  y  z  {  |  }  ~ ++  ¡  ¢  £  ¤  ¦  §  ¨  ©  ª  «  ¬  ®  °  ±  ²  ³ ++  ´  µ  ¶  ·  ¸  ¹  º  »  ¼  ½  ¾  ¿  À  Á  Â  Ã ++  Ä  Å  Æ  Ç  È  É  Ê  Ë  Ì  Í  Î  Ï  Ð  Ñ  Ò  Ô ++  Ö  ×  Ø  Ù  Ú  Û  Ü  Ý  Þ  à  â  ã  å  æ  ç  è ++  é  ê  ë  ì  í  î  ï  ð  ñ  ò  ó  ô  õ  ö  ÷  ø ++  ù  ú  û  ü  ý  þ ¡@ ¡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 ++ ¡[ ¡\ ¡] ¡^ ¡_ ¡` ¡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 ++ ¡{ ¡| ¡} ¡~ ¡¡ ¡¢ ¡£ ¡¤ ¡¥ ¡¦ ¡§ ¡¨ ¡© ¡ª ¡« ¡¬ ++ ¡­ ¡® ¡¯ ¡° ¡± ¡² ¡³ ¡´ ¡µ ¡¶ ¡· ¡¸ ¡¹ ¡º ¡» ¡¼ ++ ¡½ ¡¾ ¡¿ ¡À ¡Á ¡Â ¡Ä ¡Æ ¡Ç ¡È ¡É ¡Ê ¡Ë ¡Ì ¡Í ¡Î ++ ¡Ï ¡Ð ¡Ñ ¡Ò ¡Ó ¡Ô ¡Õ ¡Ö ¡× ¡Ø ¡Ù ¡Ú ¡Û ¡Ü ¡Ý ¡Þ ++ ¡ß ¡à ¡á ¡â ¡ã ¡ä ¡å ¡æ ¡ç ¡è ¡é ¡ê ¡ë ¡ì ¡í ¡î ++ ¡ï ¡ð ¡ñ ¡ò ¡ó ¡ô ¡õ ¡ö ¡÷ ¡ø ¡ù ¡ú ¡û ¡ü ¡ý ¢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 ¢[ ¢\ ¢] ¢^ ¢_ ¢` ¢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 ¢{ ¢| ¢} ¢¨ ¢© ¢ª ¢« ++ ¢¬ ¢­ ¢® ¢¯ ¢° ¢± ¢² ¢³ ¢´ ¢µ ¢¶ ¢· ¢¸ ¢¹ ¢º ¢» ++ ¢¼ ¢½ ¢¾ ¢¿ ¢À ¢Á ¢Â ¢Ã ¢Ä ¢Å ¢Æ ¢Ç ¢È ¢É ¢Ê ¢Ë ++ ¢Í ¢Ï ¢Ð ¢Ñ ¢Ò ¢Ó ¢Ô ¢Õ ¢Ö ¢× ¢Ø ¢Ù ¢Ú ¢Û ¢Ü ¢Ý ++ ¢Þ ¢ß ¢à ¢á ¢â ¢ã ¢ä ¢å ¢æ ¢ç ¢è ¢é ¢ê ¢ë ¢ì ¢í ++ ¢î ¢ï ¢ð ¢ñ ¢ò ¢ó ¢ô ¢õ ¢ö ¢÷ ¢ø ¢ù ¢ú ¢û ¢ü ¢ý ++ ¢þ £@ £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 £[ £\ £] £^ ++ £_ £` £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 £{ £| £} £~ ++ £¡ £¢ ££ £¤ £¥ £¦ £§ £¨ £© £ª £« £¬ £­ £® £¯ £° ++ £± £² £³ £´ £µ £¶ £· £¸ £¹ £º £» £¼ £½ £¾ £¿ ¤@ ++ ¤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 ¤[ ¤\ ¤] ¤^ ¤_ ¤` ++ ¤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 ¤{ ¤| ¤} ¤~ ¤¡ ¤¢ ++ ¤£ ¤¤ ¤¥ ¤¦ ¤§ ¤¨ ¤© ¤ª ¤« ¤¬ ¤­ ¤® ¤¯ ¤° ¤± ¤² ++ ¤³ ¤´ ¤µ ¤¶ ¤· ¤¸ ¤¹ ¤º ¤» ¤¼ ¤½ ¤¾ ¤¿ ¤À ¤Á ¤Â ++ ¤Ã ¤Ä ¤Å ¤Æ ¤Ç ¤È ¤É ¤Ê ¤Ë ¤Ì ¤Í ¤Î ¤Ï ¤Ð ¤Ñ ¤Ò ++ ¤Ó ¤Ô ¤Õ ¤Ö ¤× ¤Ø ¤Ù ¤Ú ¤Û ¤Ü ¤Ý ¤Þ ¤ß ¤à ¤á ¤â ++ ¤ã ¤ä ¤å ¤æ ¤ç ¤è ¤é ¤ê ¤ë ¤ì ¤í ¤î ¤ï ¤ð ¤ñ ¤ò ++ ¤ó ¤ô ¤õ ¤ö ¤÷ ¤ø ¤ù ¤ú ¤û ¤ü ¤ý ¤þ ¥@ ¥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 ¥[ ¥\ ¥] ¥^ ¥_ ¥` ¥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 ¥{ ¥| ¥} ¥~ ¥¡ ¥¢ ¥£ ¥¤ ¥¥ ++ ¥¦ ¥§ ¥¨ ¥© ¥ª ¥« ¥¬ ¥­ ¥® ¥¯ ¥° ¥± ¥² ¥³ ¥´ ¥µ ++ ¥¶ ¥· ¥¸ ¥¹ ¥º ¥» ¥¼ ¥½ ¥¾ ¥¿ ¥À ¥Á ¥Â ¥Ã ¥Ä ¥Å ++ ¥Æ ¥Ç ¥È ¥É ¥Ê ¥Ë ¥Ì ¥Í ¥Î ¥Ï ¥Ð ¥Ñ ¥Ò ¥Ó ¥Ô ¥Õ ++ ¥Ö ¥× ¥Ø ¥Ù ¥Ú ¥Û ¥Ü ¥Ý ¥Þ ¥ß ¥à ¥á ¥â ¥ã ¥ä ¥å ++ ¥æ ¥ç ¥è ¥é ¥ê ¥ë ¥ì ¥í ¥î ¥ï ¥ð ¥ñ ¥ò ¥ó ¥ô ¥õ ++ ¥ö ¥÷ ¥ø ¥ù ¥ú ¥û ¥ü ¥ý ¥þ ¦@ ¦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 ¦[ ¦\ ¦] ¦^ ¦_ ¦` ¦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 ¦{ ¦| ¦} ¦~ ¦¡ ¦¢ ¦£ ¦¤ ¦¥ ¦¦ ¦§ ¦¨ ++ ¦© ¦ª ¦« ¦¬ ¦­ ¦® ¦¯ ¦° ¦± ¦² ¦³ ¦´ ¦µ ¦¶ ¦· ¦¸ ++ ¦¹ ¦º ¦» ¦¼ ¦½ ¦¾ ¦¿ ¦À ¦Á ¦Â ¦Ã ¦Ä ¦Å ¦Æ ¦Ç ¦È ++ ¦É ¦Ê ¦Ë ¦Ì ¦Í ¦Î ¦Ï ¦Ð ¦Ñ ¦Ò ¦Ó ¦Ô ¦Õ ¦Ö ¦× ¦Ø ++ ¦Ù ¦Ú ¦Û ¦Ü ¦Ý ¦Þ ¦ß ¦à ¦á ¦â ¦ã ¦ä ¦å ¦æ ¦ç ¦è ++ ¦é ¦ê ¦ë ¦ì ¦í ¦î ¦ï ¦ð ¦ñ ¦ò ¦ó ¦ô ¦õ ¦ö ¦÷ ¦ø ++ ¦ù ¦ú ¦û ¦ü ¦ý ¦þ §@ §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 §[ §\ §] §^ §_ §` §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 §{ §| §} §~ §¡ §¢ §£ §¤ §¥ §¦ §§ §¨ §© §ª §« ++ §¬ §­ §® §¯ §° §± §² §³ §´ §µ §¶ §· §¸ §¹ §º §» ++ §¼ §½ §¾ §¿ §À §Á §Â §Ã §Ä §Å §Æ §Ç §È §É §Ê §Ë ++ §Ì §Í §Î §Ï §Ð §Ñ §Ò §Ó §Ô §Õ §Ö §× §Ø §Ù §Ú §Û ++ §Ü §Ý §Þ §ß §à §á §â §ã §ä §å §æ §ç §è §é §ê §ë ++ §ì §í §î §ï §ð §ñ §ò §ó §ô §õ §ö §÷ §ø §ù §ú §û ++ §ü §ý §þ ¨@ ¨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 ¨[ ¨\ ++ ¨] ¨^ ¨_ ¨` ¨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 ¨{ ¨| ++ ¨} ¨~ ¨¡ ¨¢ ¨£ ¨¤ ¨¥ ¨¦ ¨§ ¨¨ ¨© ¨ª ¨« ¨¬ ¨­ ¨® ++ ¨¯ ¨° ¨± ¨² ¨³ ¨´ ¨µ ¨¶ ¨· ¨¸ ¨¹ ¨º ¨» ¨¼ ¨½ ¨¾ ++ ¨¿ ¨À ¨Á ¨Â ¨Ã ¨Ä ¨Å ¨Æ ¨Ç ¨È ¨É ¨Ê ¨Ë ¨Ì ¨Í ¨Î ++ ¨Ï ¨Ð ¨Ñ ¨Ò ¨Ó ¨Ô ¨Õ ¨Ö ¨× ¨Ø ¨Ù ¨Ú ¨Û ¨Ü ¨Ý ¨Þ ++ ¨ß ¨à ¨á ¨â ¨ã ¨ä ¨å ¨æ ¨ç ¨è ¨é ¨ê ¨ë ¨ì ¨í ¨î ++ ¨ï ¨ð ¨ñ ¨ò ¨ó ¨ô ¨õ ¨ö ¨÷ ¨ø ¨ù ¨ú ¨û ¨ü ¨ý ¨þ ++ ©@ ©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 ©[ ©\ ©] ©^ ©_ ++ ©` ©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 ©{ ©| ©} ©~ ©¡ ++ ©¢ ©£ ©¤ ©¥ ©¦ ©§ ©¨ ©© ©ª ©« ©¬ ©­ ©® ©¯ ©° ©± ++ ©² ©³ ©´ ©µ ©¶ ©· ©¸ ©¹ ©º ©» ©¼ ©½ ©¾ ©¿ ©À ©Á ++ ©Â ©Ã ©Ä ©Å ©Æ ©Ç ©È ©É ©Ê ©Ë ©Ì ©Í ©Î ©Ï ©Ð ©Ñ ++ ©Ò ©Ó ©Ô ©Õ ©Ö ©× ©Ø ©Ù ©Ú ©Û ©Ü ©Ý ©Þ ©ß ©à ©á ++ ©â ©ã ©ä ©å ©æ ©ç ©è ©é ©ê ©ë ©ì ©í ©î ©ï ©ð ©ñ ++ ©ò ©ó ©ô ©õ ©ö ©÷ ©ø ©ù ©ú ©û ©ü ©ý ©þ ª@ ª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 ª[ ª\ ª] ª^ ª_ ª` ª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 ª{ ª| ª} ª~ ª¡ ª¢ ª£ ª¤ ++ ª¥ ª¦ ª§ ª¨ ª© ªª ª« ª¬ ª­ ª® ª¯ ª° ª± ª² ª³ ª´ ++ ªµ ª¶ ª· ª¸ ª¹ ªº ª» ª¼ ª½ ª¾ ª¿ ªÀ ªÁ ªÂ ªÃ ªÄ ++ ªÅ ªÆ ªÇ ªÈ ªÉ ªÊ ªË ªÌ ªÍ ªÎ ªÏ ªÐ ªÑ ªÒ ªÓ ªÔ ++ ªÕ ªÖ ª× ªØ ªÙ ªÚ ªÛ ªÜ ªÝ ªÞ ªß ªà ªá ªâ ªã ªä ++ ªå ªæ ªç ªè ªé ªê ªë ªì ªí ªî ªï ªð ªñ ªò ªó ªô ++ ªõ ªö ª÷ ªø ªù ªú ªû ªü ªý ªþ «@ «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 «[ «\ «] «^ «_ «` «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 «{ «| «} «~ «¡ «¢ «£ «¤ «¥ «¦ «§ ++ «¨ «© «ª «« «¬ «­ «® «¯ «° «± «² «³ «´ «µ «¶ «· ++ «¸ «¹ «º «» «¼ «½ «¾ «¿ «À «Á «Â «Ã «Ä «Å «Æ «Ç ++ «È «É «Ê «Ë «Ì «Í «Î «Ï «Ð «Ñ «Ò «Ó «Ô «Õ «Ö «× ++ «Ø «Ù «Ú «Û «Ü «Ý «Þ «ß «à «á «â «ã «ä «å «æ «ç ++ «è «é «ê «ë «ì «í «î «ï «ð «ñ «ò «ó «ô «õ «ö «÷ ++ «ø «ù «ú «û «ü «ý «þ ¬@ ¬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 ¬[ ¬\ ¬] ¬^ ¬_ ¬` ¬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 ¬{ ¬| ¬} ¬~ ¬¡ ¬¢ ¬£ ¬¤ ¬¥ ¬¦ ¬§ ¬¨ ¬© ¬ª ++ ¬« ¬¬ ¬­ ¬® ¬¯ ¬° ¬± ¬² ¬³ ¬´ ¬µ ¬¶ ¬· ¬¸ ¬¹ ¬º ++ ¬» ¬¼ ¬½ ¬¾ ¬¿ ¬À ¬Á ¬Â ¬Ã ¬Ä ¬Å ¬Æ ¬Ç ¬È ¬É ¬Ê ++ ¬Ë ¬Ì ¬Í ¬Î ¬Ï ¬Ð ¬Ñ ¬Ò ¬Ó ¬Ô ¬Õ ¬Ö ¬× ¬Ø ¬Ù ¬Ú ++ ¬Û ¬Ü ¬Ý ¬Þ ¬ß ¬à ¬á ¬â ¬ã ¬ä ¬å ¬æ ¬ç ¬è ¬é ¬ê ++ ¬ë ¬ì ¬í ¬î ¬ï ¬ð ¬ñ ¬ò ¬ó ¬ô ¬õ ¬ö ¬÷ ¬ø ¬ù ¬ú ++ ¬û ¬ü ¬ý ¬þ ­@ ­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 ­[ ++ ­\ ­] ­^ ­_ ­` ­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 ­{ ++ ­| ­} ­~ ­¡ ­¢ ­£ ­¤ ­¥ ­¦ ­§ ­¨ ­© ­ª ­« ­¬ ­­ ++ ­® ­¯ ­° ­± ­² ­³ ­´ ­µ ­¶ ­· ­¸ ­¹ ­º ­» ­¼ ­½ ++ ­¾ ­¿ ­À ­Á ­Â ­Ã ­Ä ­Å ­Æ ­Ç ­È ­É ­Ê ­Ë ­Ì ­Í ++ ­Î ­Ï ­Ð ­Ñ ­Ò ­Ó ­Ô ­Õ ­Ö ­× ­Ø ­Ù ­Ú ­Û ­Ü ­Ý ++ ­Þ ­ß ­à ­á ­â ­ã ­ä ­å ­æ ­ç ­è ­é ­ê ­ë ­ì ­í ++ ­î ­ï ­ð ­ñ ­ò ­ó ­ô ­õ ­ö ­÷ ­ø ­ù ­ú ­û ­ü ­ý ++ ­þ ®@ ®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 ®[ ®\ ®] ®^ ++ ®_ ®` ®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 ®{ ®| ®} ®~ ++ ®¡ ®¢ ®£ ®¤ ®¥ ®¦ ®§ ®¨ ®© ®ª ®« ®¬ ®­ ®® ®¯ ®° ++ ®± ®² ®³ ®´ ®µ ®¶ ®· ®¸ ®¹ ®º ®» ®¼ ®½ ®¾ ®¿ ®À ++ ®Á ®Â ®Ã ®Ä ®Å ®Æ ®Ç ®È ®É ®Ê ®Ë ®Ì ®Í ®Î ®Ï ®Ð ++ ®Ñ ®Ò ®Ó ®Ô ®Õ ®Ö ®× ®Ø ®Ù ®Ú ®Û ®Ü ®Ý ®Þ ®ß ®à ++ ®á ®â ®ã ®ä ®å ®æ ®ç ®è ®é ®ê ®ë ®ì ®í ®î ®ï ®ð ++ ®ñ ®ò ®ó ®ô ®õ ®ö ®÷ ®ø ®ù ®ú ®û ®ü ®ý ®þ ¯@ ¯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 ¯[ ¯\ ¯] ¯^ ¯_ ¯` ¯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 ¯{ ¯| ¯} ¯~ ¯¡ ¯¢ ¯£ ++ ¯¤ ¯¥ ¯¦ ¯§ ¯¨ ¯© ¯ª ¯« ¯¬ ¯­ ¯® ¯¯ ¯° ¯± ¯² ¯³ ++ ¯´ ¯µ ¯¶ ¯· ¯¸ ¯¹ ¯º ¯» ¯¼ ¯½ ¯¾ ¯¿ ¯À ¯Á ¯Â ¯Ã ++ ¯Ä ¯Å ¯Æ ¯Ç ¯È ¯É ¯Ê ¯Ë ¯Ì ¯Í ¯Î ¯Ï ¯Ð ¯Ñ ¯Ò ¯Ó ++ ¯Ô ¯Õ ¯Ö ¯× ¯Ø ¯Ù ¯Ú ¯Û ¯Ü ¯Ý ¯Þ ¯ß ¯à ¯á ¯â ¯ã ++ ¯ä ¯å ¯æ ¯ç ¯è ¯é ¯ê ¯ë ¯ì ¯í ¯î ¯ï ¯ð ¯ñ ¯ò ¯ó ++ ¯ô ¯õ ¯ö ¯÷ ¯ø ¯ù ¯ú ¯û ¯ü ¯ý ¯þ °@ °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 °[ °\ °] °^ °_ °` °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 °{ °| °} °~ °¡ °¢ °£ °¤ °¥ °¦ ++ °§ °¨ °© °ª °« °¬ °­ °® °¯ °° °± °² °³ °´ °µ °¶ ++ °· °¸ °¹ °º °» °¼ °½ °¾ °¿ °À °Á °Â °Ã °Ä °Å °Æ ++ °Ç °È °É °Ê °Ë °Ì °Í °Î °Ï °Ð °Ñ °Ò °Ó °Ô °Õ °Ö ++ °× °Ø °Ù °Ú °Û °Ü °Ý °Þ °ß °à °á °â °ã °ä °å °æ ++ °ç °è °é °ê °ë °ì °í °î °ï °ð °ñ °ò °ó °ô °õ °ö ++ °÷ °ø °ù °ú °û °ü °ý °þ ±@ ±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 ±[ ±\ ±] ±^ ±_ ±` ±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 ±{ ±| ±} ±~ ±¡ ±¢ ±£ ±¤ ±¥ ±¦ ±§ ±¨ ±© ++ ±ª ±« ±¬ ±­ ±® ±¯ ±° ±± ±² ±³ ±´ ±µ ±¶ ±· ±¸ ±¹ ++ ±º ±» ±¼ ±½ ±¾ ±¿ ±À ±Á ±Â ±Ã ±Ä ±Å ±Æ ±Ç ±È ±É ++ ±Ê ±Ë ±Ì ±Í ±Î ±Ï ±Ð ±Ñ ±Ò ±Ó ±Ô ±Õ ±Ö ±× ±Ø ±Ù ++ ±Ú ±Û ±Ü ±Ý ±Þ ±ß ±à ±á ±â ±ã ±ä ±å ±æ ±ç ±è ±é ++ ±ê ±ë ±ì ±í ±î ±ï ±ð ±ñ ±ò ±ó ±ô ±õ ±ö ±÷ ±ø ±ù ++ ±ú ±û ±ü ±ý ±þ ²@ ²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 ++ ²[ ²\ ²] ²^ ²_ ²` ²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 ++ ²{ ²| ²} ²~ ²¡ ²¢ ²£ ²¤ ²¥ ²¦ ²§ ²¨ ²© ²ª ²« ²¬ ++ ²­ ²® ²¯ ²° ²± ²² ²³ ²´ ²µ ²¶ ²· ²¸ ²¹ ²º ²» ²¼ ++ ²½ ²¾ ²¿ ²À ²Á ²Â ²Ã ²Ä ²Å ²Æ ²Ç ²È ²É ²Ê ²Ë ²Ì ++ ²Í ²Î ²Ï ²Ð ²Ñ ²Ò ²Ó ²Ô ²Õ ²Ö ²× ²Ø ²Ù ²Ú ²Û ²Ü ++ ²Ý ²Þ ²ß ²à ²á ²â ²ã ²ä ²å ²æ ²ç ²è ²é ²ê ²ë ²ì ++ ²í ²î ²ï ²ð ²ñ ²ò ²ó ²ô ²õ ²ö ²÷ ²ø ²ù ²ú ²û ²ü ++ ²ý ²þ ³@ ³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 ³[ ³\ ³] ++ ³^ ³_ ³` ³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 ³{ ³| ³} ++ ³~ ³¡ ³¢ ³£ ³¤ ³¥ ³¦ ³§ ³¨ ³© ³ª ³« ³¬ ³­ ³® ³¯ ++ ³° ³± ³² ³³ ³´ ³µ ³¶ ³· ³¸ ³¹ ³º ³» ³¼ ³½ ³¾ ³¿ ++ ³À ³Á ³Â ³Ã ³Ä ³Å ³Æ ³Ç ³È ³É ³Ê ³Ë ³Ì ³Í ³Î ³Ï ++ ³Ð ³Ñ ³Ò ³Ó ³Ô ³Õ ³Ö ³× ³Ø ³Ù ³Ú ³Û ³Ü ³Ý ³Þ ³ß ++ ³à ³á ³â ³ã ³ä ³å ³æ ³ç ³è ³é ³ê ³ë ³ì ³í ³î ³ï ++ ³ð ³ñ ³ò ³ó ³ô ³õ ³ö ³÷ ³ø ³ù ³ú ³û ³ü ³ý ³þ ´@ ++ ´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 ´[ ´\ ´] ´^ ´_ ´` ++ ´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 ´{ ´| ´} ´~ ´¡ ´¢ ++ ´£ ´¤ ´¥ ´¦ ´§ ´¨ ´© ´ª ´« ´¬ ´­ ´® ´¯ ´° ´± ´² ++ ´³ ´´ ´µ ´¶ ´· ´¸ ´¹ ´º ´» ´¼ ´½ ´¾ ´¿ ´À ´Á ´Â ++ ´Ã ´Ä ´Å ´Æ ´Ç ´È ´É ´Ê ´Ë ´Ì ´Í ´Î ´Ï ´Ð ´Ñ ´Ò ++ ´Ó ´Ô ´Õ ´Ö ´× ´Ø ´Ù ´Ú ´Û ´Ü ´Ý ´Þ ´ß ´à ´á ´â ++ ´ã ´ä ´å ´æ ´ç ´è ´é ´ê ´ë ´ì ´í ´î ´ï ´ð ´ñ ´ò ++ ´ó ´ô ´õ ´ö ´÷ ´ø ´ù ´ú ´û ´ü ´ý ´þ µ@ µ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 µ[ µ\ µ] µ^ µ_ µ` µ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 µ{ µ| µ} µ~ µ¡ µ¢ µ£ µ¤ µ¥ ++ µ¦ µ§ µ¨ µ© µª µ« µ¬ µ­ µ® µ¯ µ° µ± µ² µ³ µ´ µµ ++ µ¶ µ· µ¸ µ¹ µº µ» µ¼ µ½ µ¾ µ¿ µÀ µÁ µÂ µÃ µÄ µÅ ++ µÆ µÇ µÈ µÉ µÊ µË µÌ µÍ µÎ µÏ µÐ µÑ µÒ µÓ µÔ µÕ ++ µÖ µ× µØ µÙ µÚ µÛ µÜ µÝ µÞ µß µà µá µâ µã µä µå ++ µæ µç µè µé µê µë µì µí µî µï µð µñ µò µó µô µõ ++ µö µ÷ µø µù µú µû µü µý µþ ¶@ ¶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 ¶[ ¶\ ¶] ¶^ ¶_ ¶` ¶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 ¶{ ¶| ¶} ¶~ ¶¡ ¶¢ ¶£ ¶¤ ¶¥ ¶¦ ¶§ ¶¨ ++ ¶© ¶ª ¶« ¶¬ ¶­ ¶® ¶¯ ¶° ¶± ¶² ¶³ ¶´ ¶µ ¶¶ ¶· ¶¸ ++ ¶¹ ¶º ¶» ¶¼ ¶½ ¶¾ ¶¿ ¶À ¶Á ¶Â ¶Ã ¶Ä ¶Å ¶Æ ¶Ç ¶È ++ ¶É ¶Ê ¶Ë ¶Ì ¶Í ¶Î ¶Ï ¶Ð ¶Ñ ¶Ò ¶Ó ¶Ô ¶Õ ¶Ö ¶× ¶Ø ++ ¶Ù ¶Ú ¶Û ¶Ü ¶Ý ¶Þ ¶ß ¶à ¶á ¶â ¶ã ¶ä ¶å ¶æ ¶ç ¶è ++ ¶é ¶ê ¶ë ¶ì ¶í ¶î ¶ï ¶ð ¶ñ ¶ò ¶ó ¶ô ¶õ ¶ö ¶÷ ¶ø ++ ¶ù ¶ú ¶û ¶ü ¶ý ¶þ ·@ ·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 ·[ ·\ ·] ·^ ·_ ·` ·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 ·{ ·| ·} ·~ ·¡ ·¢ ·£ ·¤ ·¥ ·¦ ·§ ·¨ ·© ·ª ·« ++ ·¬ ·­ ·® ·¯ ·° ·± ·² ·³ ·´ ·µ ·¶ ·· ·¸ ·¹ ·º ·» ++ ·¼ ·½ ·¾ ·¿ ·À ·Á ·Â ·Ã ·Ä ·Å ·Æ ·Ç ·È ·É ·Ê ·Ë ++ ·Ì ·Í ·Î ·Ï ·Ð ·Ñ ·Ò ·Ó ·Ô ·Õ ·Ö ·× ·Ø ·Ù ·Ú ·Û ++ ·Ü ·Ý ·Þ ·ß ·à ·á ·â ·ã ·ä ·å ·æ ·ç ·è ·é ·ê ·ë ++ ·ì ·í ·î ·ï ·ð ·ñ ·ò ·ó ·ô ·õ ·ö ·÷ ·ø ·ù ·ú ·û ++ ·ü ·ý ·þ ¸@ ¸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 ¸[ ¸\ ++ ¸] ¸^ ¸_ ¸` ¸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 ¸{ ¸| ++ ¸} ¸~ ¸¡ ¸¢ ¸£ ¸¤ ¸¥ ¸¦ ¸§ ¸¨ ¸© ¸ª ¸« ¸¬ ¸­ ¸® ++ ¸¯ ¸° ¸± ¸² ¸³ ¸´ ¸µ ¸¶ ¸· ¸¸ ¸¹ ¸º ¸» ¸¼ ¸½ ¸¾ ++ ¸¿ ¸À ¸Á ¸Â ¸Ã ¸Ä ¸Å ¸Æ ¸Ç ¸È ¸É ¸Ê ¸Ë ¸Ì ¸Í ¸Î ++ ¸Ï ¸Ð ¸Ñ ¸Ò ¸Ó ¸Ô ¸Õ ¸Ö ¸× ¸Ø ¸Ù ¸Ú ¸Û ¸Ü ¸Ý ¸Þ ++ ¸ß ¸à ¸á ¸â ¸ã ¸ä ¸å ¸æ ¸ç ¸è ¸é ¸ê ¸ë ¸ì ¸í ¸î ++ ¸ï ¸ð ¸ñ ¸ò ¸ó ¸ô ¸õ ¸ö ¸÷ ¸ø ¸ù ¸ú ¸û ¸ü ¸ý ¸þ ++ ¹@ ¹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 ¹[ ¹\ ¹] ¹^ ¹_ ++ ¹` ¹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 ¹{ ¹| ¹} ¹~ ¹¡ ++ ¹¢ ¹£ ¹¤ ¹¥ ¹¦ ¹§ ¹¨ ¹© ¹ª ¹« ¹¬ ¹­ ¹® ¹¯ ¹° ¹± ++ ¹² ¹³ ¹´ ¹µ ¹¶ ¹· ¹¸ ¹¹ ¹º ¹» ¹¼ ¹½ ¹¾ ¹¿ ¹À ¹Á ++ ¹Â ¹Ã ¹Ä ¹Å ¹Æ ¹Ç ¹È ¹É ¹Ê ¹Ë ¹Ì ¹Í ¹Î ¹Ï ¹Ð ¹Ñ ++ ¹Ò ¹Ó ¹Ô ¹Õ ¹Ö ¹× ¹Ø ¹Ù ¹Ú ¹Û ¹Ü ¹Ý ¹Þ ¹ß ¹à ¹á ++ ¹â ¹ã ¹ä ¹å ¹æ ¹ç ¹è ¹é ¹ê ¹ë ¹ì ¹í ¹î ¹ï ¹ð ¹ñ ++ ¹ò ¹ó ¹ô ¹õ ¹ö ¹÷ ¹ø ¹ù ¹ú ¹û ¹ü ¹ý ¹þ º@ º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 º[ º\ º] º^ º_ º` º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 º{ º| º} º~ º¡ º¢ º£ º¤ ++ º¥ º¦ º§ º¨ º© ºª º« º¬ º­ º® º¯ º° º± º² º³ º´ ++ ºµ º¶ º· º¸ º¹ ºº º» º¼ º½ º¾ º¿ ºÀ ºÁ ºÂ ºÃ ºÄ ++ ºÅ ºÆ ºÇ ºÈ ºÉ ºÊ ºË ºÌ ºÍ ºÎ ºÏ ºÐ ºÑ ºÒ ºÓ ºÔ ++ ºÕ ºÖ º× ºØ ºÙ ºÚ ºÛ ºÜ ºÝ ºÞ ºß ºà ºá ºâ ºã ºä ++ ºå ºæ ºç ºè ºé ºê ºë ºì ºí ºî ºï ºð ºñ ºò ºó ºô ++ ºõ ºö º÷ ºø ºù ºú ºû ºü ºý ºþ »@ »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 »[ »\ »] »^ »_ »` »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 »{ »| »} »~ »¡ »¢ »£ »¤ »¥ »¦ »§ ++ »¨ »© »ª »« »¬ »­ »® »¯ »° »± »² »³ »´ »µ »¶ »· ++ »¸ »¹ »º »» »¼ »½ »¾ »¿ »À »Á »Â »Ã »Ä »Å »Æ »Ç ++ »È »É »Ê »Ë »Ì »Í »Î »Ï »Ð »Ñ »Ò »Ó »Ô »Õ »Ö »× ++ »Ø »Ù »Ú »Û »Ü »Ý »Þ »ß »à »á »â »ã »ä »å »æ »ç ++ »è »é »ê »ë »ì »í »î »ï »ð »ñ »ò »ó »ô »õ »ö »÷ ++ »ø »ù »ú »û »ü »ý »þ ¼@ ¼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 ¼[ ¼\ ¼] ¼^ ¼_ ¼` ¼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 ¼{ ¼| ¼} ¼~ ¼¡ ¼¢ ¼£ ¼¤ ¼¥ ¼¦ ¼§ ¼¨ ¼© ¼ª ++ ¼« ¼¬ ¼­ ¼® ¼¯ ¼° ¼± ¼² ¼³ ¼´ ¼µ ¼¶ ¼· ¼¸ ¼¹ ¼º ++ ¼» ¼¼ ¼½ ¼¾ ¼¿ ¼À ¼Á ¼Â ¼Ã ¼Ä ¼Å ¼Æ ¼Ç ¼È ¼É ¼Ê ++ ¼Ë ¼Ì ¼Í ¼Î ¼Ï ¼Ð ¼Ñ ¼Ò ¼Ó ¼Ô ¼Õ ¼Ö ¼× ¼Ø ¼Ù ¼Ú ++ ¼Û ¼Ü ¼Ý ¼Þ ¼ß ¼à ¼á ¼â ¼ã ¼ä ¼å ¼æ ¼ç ¼è ¼é ¼ê ++ ¼ë ¼ì ¼í ¼î ¼ï ¼ð ¼ñ ¼ò ¼ó ¼ô ¼õ ¼ö ¼÷ ¼ø ¼ù ¼ú ++ ¼û ¼ü ¼ý ¼þ ½@ ½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 ½[ ++ ½\ ½] ½^ ½_ ½` ½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 ½{ ++ ½| ½} ½~ ½¡ ½¢ ½£ ½¤ ½¥ ½¦ ½§ ½¨ ½© ½ª ½« ½¬ ½­ ++ ½® ½¯ ½° ½± ½² ½³ ½´ ½µ ½¶ ½· ½¸ ½¹ ½º ½» ½¼ ½½ ++ ½¾ ½¿ ½À ½Á ½Â ½Ã ½Ä ½Å ½Æ ½Ç ½È ½É ½Ê ½Ë ½Ì ½Í ++ ½Î ½Ï ½Ð ½Ñ ½Ò ½Ó ½Ô ½Õ ½Ö ½× ½Ø ½Ù ½Ú ½Û ½Ü ½Ý ++ ½Þ ½ß ½à ½á ½â ½ã ½ä ½å ½æ ½ç ½è ½é ½ê ½ë ½ì ½í ++ ½î ½ï ½ð ½ñ ½ò ½ó ½ô ½õ ½ö ½÷ ½ø ½ù ½ú ½û ½ü ½ý ++ ½þ ¾@ ¾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 ¾[ ¾\ ¾] ¾^ ++ ¾_ ¾` ¾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 ¾{ ¾| ¾} ¾~ ++ ¾¡ ¾¢ ¾£ ¾¤ ¾¥ ¾¦ ¾§ ¾¨ ¾© ¾ª ¾« ¾¬ ¾­ ¾® ¾¯ ¾° ++ ¾± ¾² ¾³ ¾´ ¾µ ¾¶ ¾· ¾¸ ¾¹ ¾º ¾» ¾¼ ¾½ ¾¾ ¾¿ ¾À ++ ¾Á ¾Â ¾Ã ¾Ä ¾Å ¾Æ ¾Ç ¾È ¾É ¾Ê ¾Ë ¾Ì ¾Í ¾Î ¾Ï ¾Ð ++ ¾Ñ ¾Ò ¾Ó ¾Ô ¾Õ ¾Ö ¾× ¾Ø ¾Ù ¾Ú ¾Û ¾Ü ¾Ý ¾Þ ¾ß ¾à ++ ¾á ¾â ¾ã ¾ä ¾å ¾æ ¾ç ¾è ¾é ¾ê ¾ë ¾ì ¾í ¾î ¾ï ¾ð ++ ¾ñ ¾ò ¾ó ¾ô ¾õ ¾ö ¾÷ ¾ø ¾ù ¾ú ¾û ¾ü ¾ý ¾þ ¿@ ¿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 ¿[ ¿\ ¿] ¿^ ¿_ ¿` ¿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 ¿{ ¿| ¿} ¿~ ¿¡ ¿¢ ¿£ ++ ¿¤ ¿¥ ¿¦ ¿§ ¿¨ ¿© ¿ª ¿« ¿¬ ¿­ ¿® ¿¯ ¿° ¿± ¿² ¿³ ++ ¿´ ¿µ ¿¶ ¿· ¿¸ ¿¹ ¿º ¿» ¿¼ ¿½ ¿¾ ¿¿ ¿À ¿Á ¿Â ¿Ã ++ ¿Ä ¿Å ¿Æ ¿Ç ¿È ¿É ¿Ê ¿Ë ¿Ì ¿Í ¿Î ¿Ï ¿Ð ¿Ñ ¿Ò ¿Ó ++ ¿Ô ¿Õ ¿Ö ¿× ¿Ø ¿Ù ¿Ú ¿Û ¿Ü ¿Ý ¿Þ ¿ß ¿à ¿á ¿â ¿ã ++ ¿ä ¿å ¿æ ¿ç ¿è ¿é ¿ê ¿ë ¿ì ¿í ¿î ¿ï ¿ð ¿ñ ¿ò ¿ó ++ ¿ô ¿õ ¿ö ¿÷ ¿ø ¿ù ¿ú ¿û ¿ü ¿ý ¿þ À@ À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 À[ À\ À] À^ À_ À` À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 À{ À| À} À~ À¡ À¢ À£ À¤ À¥ À¦ ++ À§ À¨ À© Àª À« À¬ À­ À® À¯ À° À± À² À³ À´ Àµ À¶ ++ À· À¸ À¹ Àº À» À¼ À½ À¾ À¿ ÀÀ ÀÁ À Àà ÀÄ ÀÅ ÀÆ ++ ÀÇ ÀÈ ÀÉ ÀÊ ÀË ÀÌ ÀÍ ÀÎ ÀÏ ÀÐ ÀÑ ÀÒ ÀÓ ÀÔ ÀÕ ÀÖ ++ À× ÀØ ÀÙ ÀÚ ÀÛ ÀÜ ÀÝ ÀÞ Àß Àà Àá Àâ Àã Àä Àå Àæ ++ Àç Àè Àé Àê Àë Àì Àí Àî Àï Àð Àñ Àò Àó Àô Àõ Àö ++ À÷ Àø Àù Àú Àû Àü Àý Àþ Á@ Á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 Á[ Á\ Á] Á^ Á_ Á` Á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 Á{ Á| Á} Á~ Á¡ Á¢ Á£ Á¤ Á¥ Á¦ Á§ Á¨ Á© ++ Áª Á« Á¬ Á­ Á® Á¯ Á° Á± Á² Á³ Á´ Áµ Á¶ Á· Á¸ Á¹ ++ Áº Á» Á¼ Á½ Á¾ Á¿ ÁÀ ÁÁ Á Áà ÁÄ ÁÅ ÁÆ ÁÇ ÁÈ ÁÉ ++ ÁÊ ÁË ÁÌ ÁÍ ÁÎ ÁÏ ÁÐ ÁÑ ÁÒ ÁÓ ÁÔ ÁÕ ÁÖ Á× ÁØ ÁÙ ++ ÁÚ ÁÛ ÁÜ ÁÝ ÁÞ Áß Áà Áá Áâ Áã Áä Áå Áæ Áç Áè Áé ++ Áê Áë Áì Áí Áî Áï Áð Áñ Áò Áó Áô Áõ Áö Á÷ Áø Áù ++ Áú Áû Áü Áý Áþ Â@ Â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 ++ Â[ Â\ Â] Â^ Â_ Â` Â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 ++ Â{ Â| Â} Â~ ¡ ¢ £ ¤ Â¥ ¦ § ¨ © ª « ¬ ++ ­ ® ¯ ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ++ ½ ¾ ¿ ÂÀ ÂÁ  Âà ÂÄ ÂÅ ÂÆ ÂÇ ÂÈ ÂÉ ÂÊ ÂË ÂÌ ++ ÂÍ ÂÎ ÂÏ ÂÐ ÂÑ ÂÒ ÂÓ ÂÔ ÂÕ ÂÖ Â× ÂØ ÂÙ ÂÚ ÂÛ ÂÜ ++ ÂÝ ÂÞ Âß Âà Âá Ââ Âã Âä Âå Âæ Âç Âè Âé Âê Âë Âì ++ Âí Âî Âï Âð Âñ Âò Âó Âô Âõ Âö Â÷ Âø Âù Âú Âû Âü ++ Âý Âþ Ã@ Ã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 Ã[ Ã\ Ã] ++ Ã^ Ã_ Ã` Ã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 Ã{ Ã| Ã} ++ Ã~ á â ã ä Ã¥ æ ç è é ê ë ì í î ï ++ ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ ++ ÃÀ ÃÁ àÃà ÃÄ ÃÅ ÃÆ ÃÇ ÃÈ ÃÉ ÃÊ ÃË ÃÌ ÃÍ ÃÎ ÃÏ ++ ÃÐ ÃÑ ÃÒ ÃÓ ÃÔ ÃÕ ÃÖ Ã× ÃØ ÃÙ ÃÚ ÃÛ ÃÜ ÃÝ ÃÞ Ãß ++ Ãà Ãá Ãâ Ãã Ãä Ãå Ãæ Ãç Ãè Ãé Ãê Ãë Ãì Ãí Ãî Ãï ++ Ãð Ãñ Ãò Ãó Ãô Ãõ Ãö Ã÷ Ãø Ãù Ãú Ãû Ãü Ãý Ãþ Ä@ ++ Ä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 Ä[ Ä\ Ä] Ä^ Ä_ Ä` ++ Ä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 Ä{ Ä| Ä} Ä~ Ä¡ Ä¢ ++ Ä£ Ĥ Ä¥ Ħ ħ Ĩ Ä© Ī Ä« Ĭ Ä­ Ä® į Ä° ı IJ ++ ij Ä´ ĵ Ķ Ä· ĸ Ĺ ĺ Ä» ļ Ľ ľ Ä¿ ÄÀ ÄÁ Ä ++ Äà ÄÄ ÄÅ ÄÆ ÄÇ ÄÈ ÄÉ ÄÊ ÄË ÄÌ ÄÍ ÄÎ ÄÏ ÄÐ ÄÑ ÄÒ ++ ÄÓ ÄÔ ÄÕ ÄÖ Ä× ÄØ ÄÙ ÄÚ ÄÛ ÄÜ ÄÝ ÄÞ Äß Äà Äá Äâ ++ Äã Ää Äå Äæ Äç Äè Äé Äê Äë Äì Äí Äî Äï Äð Äñ Äò ++ Äó Äô Äõ Äö Ä÷ Äø Äù Äú Äû Äü Äý Äþ Å@ Å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 Å[ Å\ Å] Å^ Å_ Å` Å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 Å{ Å| Å} Å~ Å¡ Å¢ Å£ Ť Å¥ ++ Ŧ ŧ Ũ Å© Ū Å« Ŭ Å­ Å® ů Å° ű Ų ų Å´ ŵ ++ Ŷ Å· Ÿ Ź ź Å» ż Ž ž Å¿ ÅÀ ÅÁ Å Åà ÅÄ ÅÅ ++ ÅÆ ÅÇ ÅÈ ÅÉ ÅÊ ÅË ÅÌ ÅÍ ÅÎ ÅÏ ÅÐ ÅÑ ÅÒ ÅÓ ÅÔ ÅÕ ++ ÅÖ Å× ÅØ ÅÙ ÅÚ ÅÛ ÅÜ ÅÝ ÅÞ Åß Åà Åá Åâ Åã Åä Åå ++ Åæ Åç Åè Åé Åê Åë Åì Åí Åî Åï Åð Åñ Åò Åó Åô Åõ ++ Åö Å÷ Åø Åù Åú Åû Åü Åý Åþ Æ@ Æ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 Æ[ Æ\ Æ] Æ^ Æ_ Æ` Æ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 Æ{ Æ| Æ} Æ~ Æ¡ Æ¢ Æ£ Ƥ Æ¥ Ʀ Ƨ ƨ ++ Æ© ƪ Æ« Ƭ Æ­ Æ® Ư Æ° Ʊ Ʋ Ƴ Æ´ Ƶ ƶ Æ· Ƹ ++ ƹ ƺ Æ» Ƽ ƽ ƾ Æ¿ ÆÀ ÆÁ Æ Æà ÆÄ ÆÅ ÆÆ ÆÇ ÆÈ ++ ÆÉ ÆÊ ÆË ÆÌ ÆÍ ÆÎ ÆÐ ÆÑ ÆÒ ÆÔ ÆÖ ÆØ ÆÙ ÆÚ ÆÛ ÆÜ ++ ÆÝ Æà Æá Æâ Æã Æä Æå Ææ Æç Æè Æé Æê Æë Æì Æí Æî ++ Æï Æð Æñ Æò Æó Æô Æõ Æö Æ÷ Æø Æù Æú Æû Æü Æý Æþ ++ Ç@ Ç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 Ç[ Ç\ Ç] Ç^ Ç_ ++ Ç` Ç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 Ç{ Ç| Ç} Ç~ Ç¡ ++ Ç¢ Ç£ Ǥ Ç¥ Ǧ ǧ Ǩ Ç© Ǫ Ç« Ǭ Ç­ Ç® ǯ Ç° DZ ++ Dz dz Ç´ ǵ Ƕ Ç· Ǹ ǹ Ǻ Ç» Ǽ ǽ Ǿ Ç¿ ÇÀ ÇÁ ++ Ç Çà ÇÄ ÇÅ ÇÆ ÇÇ ÇÈ ÇÉ ÇÊ ÇË ÇÌ ÇÍ ÇÎ ÇÏ ÇÐ ÇÑ ++ ÇÒ ÇÓ ÇÔ ÇÕ ÇÖ Ç× ÇØ ÇÙ ÇÚ ÇÛ ÇÜ ÇÝ ÇÞ Çß Çà Çá ++ Çâ Çã Çä Çå Çæ Çç Çè Çé Çê Çë Çì Çí Çî Çï Çð Çñ ++ Çò Çó Çô Çõ Çö Ç÷ Çø Çù Çú Çû Çü Çý Çþ È@ È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 È[ È\ È] È^ È_ È` È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 È{ È| È} È~ È¡ È¢ È£ Ȥ ++ ÈÍ ÈÎ ÈÏ ÈÐ ÈÑ ÈÒ ÈÓ ÈÔ ÈÕ ÈÖ È× ÈØ ÈÙ ÈÚ ÈÛ ÈÜ ++ ÈÝ ÈÞ Èß Èà Èá Èâ Èã Èä Èå Èæ Èç Èè Èé Èê Èë Èì ++ Èí Èî Èï Èð Èñ Èõ Èö È÷ Èø Èù Èú Èû Èü Èý Èþ É@ ++ É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 É[ É\ É] É^ É_ É` ++ É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 É{ É| É} É~ É¡ É¢ ++ É£ ɤ É¥ ɦ ɧ ɨ É© ɪ É« ɬ É­ É® ɯ É° ɱ ɲ ++ ɳ É´ ɵ ɶ É· ɸ ɹ ɺ É» ɼ ɽ ɾ É¿ ÉÀ ÉÁ É ++ Éà ÉÄ ÉÅ ÉÆ ÉÇ ÉÈ ÉÉ ÉÊ ÉË ÉÌ ÉÍ ÉÎ ÉÏ ÉÐ ÉÑ ÉÒ ++ ÉÓ ÉÔ ÉÕ ÉÖ É× ÉØ ÉÙ ÉÚ ÉÛ ÉÜ ÉÝ ÉÞ Éß Éà Éá Éâ ++ Éã Éä Éå Éæ Éç Éè Éé Éê Éë Éì Éí Éî Éï Éð Éñ Éò ++ Éó Éô Éõ Éö É÷ Éø Éù Éú Éû Éü Éý Éþ Ê@ Ê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 Ê[ Ê\ Ê] Ê^ Ê_ Ê` Ê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 Ê{ Ê| Ê} Ê~ Ê¡ Ê¢ Ê£ ʤ Ê¥ ++ ʦ ʧ ʨ Ê© ʪ Ê« ʬ Ê­ Ê® ʯ Ê° ʱ ʲ ʳ Ê´ ʵ ++ ʶ Ê· ʸ ʹ ʺ Ê» ʼ ʽ ʾ Ê¿ ÊÀ ÊÁ Ê Êà ÊÄ ÊÅ ++ ÊÆ ÊÇ ÊÈ ÊÉ ÊÊ ÊË ÊÌ ÊÍ ÊÎ ÊÏ ÊÐ ÊÑ ÊÒ ÊÓ ÊÔ ÊÕ ++ ÊÖ Ê× ÊØ ÊÙ ÊÚ ÊÛ ÊÜ ÊÝ ÊÞ Êß Êà Êá Êâ Êã Êä Êå ++ Êæ Êç Êè Êé Êê Êë Êì Êí Êî Êï Êð Êñ Êò Êó Êô Êõ ++ Êö Ê÷ Êø Êù Êú Êû Êü Êý Êþ Ë@ Ë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 Ë[ Ë\ Ë] Ë^ Ë_ Ë` Ë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 Ë{ Ë| Ë} Ë~ Ë¡ Ë¢ Ë£ ˤ Ë¥ ˦ ˧ ˨ ++ Ë© ˪ Ë« ˬ Ë­ Ë® ˯ Ë° ˱ ˲ ˳ Ë´ ˵ ˶ Ë· ˸ ++ ˹ ˺ Ë» ˼ ˽ ˾ Ë¿ ËÀ ËÁ Ë Ëà ËÄ ËÅ ËÆ ËÇ ËÈ ++ ËÉ ËÊ ËË ËÌ ËÍ ËÎ ËÏ ËÐ ËÑ ËÒ ËÓ ËÔ ËÕ ËÖ Ë× ËØ ++ ËÙ ËÚ ËÛ ËÜ ËÝ ËÞ Ëß Ëà Ëá Ëâ Ëã Ëä Ëå Ëæ Ëç Ëè ++ Ëé Ëê Ëë Ëì Ëí Ëî Ëï Ëð Ëñ Ëò Ëó Ëô Ëõ Ëö Ë÷ Ëø ++ Ëù Ëú Ëû Ëü Ëý Ëþ Ì@ Ì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 Ì[ Ì\ Ì] Ì^ Ì_ Ì` Ì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 Ì{ Ì| Ì} Ì~ Ì¡ Ì¢ Ì£ ̤ Ì¥ ̦ ̧ ̨ Ì© ̪ Ì« ++ ̬ Ì­ Ì® ̯ Ì° ̱ ̲ ̳ Ì´ ̵ ̶ Ì· ̸ ̹ ̺ Ì» ++ ̼ ̽ ̾ Ì¿ ÌÀ ÌÁ Ì Ìà ÌÄ ÌÅ ÌÆ ÌÇ ÌÈ ÌÉ ÌÊ ÌË ++ ÌÌ ÌÍ ÌÎ ÌÏ ÌÐ ÌÑ ÌÒ ÌÓ ÌÔ ÌÕ ÌÖ Ì× ÌØ ÌÙ ÌÚ ÌÛ ++ ÌÜ ÌÝ ÌÞ Ìß Ìà Ìá Ìâ Ìã Ìä Ìå Ìæ Ìç Ìè Ìé Ìê Ìë ++ Ìì Ìí Ìî Ìï Ìð Ìñ Ìò Ìó Ìô Ìõ Ìö Ì÷ Ìø Ìù Ìú Ìû ++ Ìü Ìý Ìþ Í@ Í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 Í[ Í\ ++ Í] Í^ Í_ Í` Í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 Í{ Í| ++ Í} Í~ Í¡ Í¢ Í£ ͤ Í¥ ͦ ͧ ͨ Í© ͪ Í« ͬ Í­ Í® ++ ͯ Í° ͱ Ͳ ͳ Í´ ͵ Ͷ Í· ͸ ͹ ͺ Í» ͼ ͽ ; ++ Í¿ ÍÀ ÍÁ Í Íà ÍÄ ÍÅ ÍÆ ÍÇ ÍÈ ÍÉ ÍÊ ÍË ÍÌ ÍÍ ÍÎ ++ ÍÏ ÍÐ ÍÑ ÍÒ ÍÓ ÍÔ ÍÕ ÍÖ Í× ÍØ ÍÙ ÍÚ ÍÛ ÍÜ ÍÝ ÍÞ ++ Íß Íà Íá Íâ Íã Íä Íå Íæ Íç Íè Íé Íê Íë Íì Íí Íî ++ Íï Íð Íñ Íò Íó Íô Íõ Íö Í÷ Íø Íù Íú Íû Íü Íý Íþ ++ Î@ Î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 Î[ Î\ Î] Î^ Î_ ++ Î` Î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 Î{ Î| Î} Î~ Ρ ++ ΢ Σ Τ Î¥ Φ Χ Ψ Ω Ϊ Ϋ ά έ ή ί ΰ α ++ β γ δ ε ζ η θ ι κ λ μ ν ξ ο ÎÀ ÎÁ ++ ΠÎà ÎÄ ÎÅ ÎÆ ÎÇ ÎÈ ÎÉ ÎÊ ÎË ÎÌ ÎÍ ÎÎ ÎÏ ÎÐ ÎÑ ++ ÎÒ ÎÓ ÎÔ ÎÕ ÎÖ Î× ÎØ ÎÙ ÎÚ ÎÛ ÎÜ ÎÝ ÎÞ Îß Îà Îá ++ Îâ Îã Îä Îå Îæ Îç Îè Îé Îê Îë Îì Îí Îî Îï Îð Îñ ++ Îò Îó Îô Îõ Îö Î÷ Îø Îù Îú Îû Îü Îý Îþ Ï@ Ï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 Ï[ Ï\ Ï] Ï^ Ï_ Ï` Ï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 Ï{ Ï| Ï} Ï~ Ï¡ Ï¢ Ï£ Ϥ ++ Ï¥ Ϧ ϧ Ϩ Ï© Ϫ Ï« Ϭ Ï­ Ï® ϯ Ï° ϱ ϲ ϳ Ï´ ++ ϵ ϶ Ï· ϸ Ϲ Ϻ Ï» ϼ Ͻ Ͼ Ï¿ ÏÀ ÏÁ Ï Ïà ÏÄ ++ ÏÅ ÏÆ ÏÇ ÏÈ ÏÉ ÏÊ ÏË ÏÌ ÏÍ ÏÎ ÏÏ ÏÐ ÏÑ ÏÒ ÏÓ ÏÔ ++ ÏÕ ÏÖ Ï× ÏØ ÏÙ ÏÚ ÏÛ ÏÜ ÏÝ ÏÞ Ïß Ïà Ïá Ïâ Ïã Ïä ++ Ïå Ïæ Ïç Ïè Ïé Ïê Ïë Ïì Ïí Ïî Ïï Ïð Ïñ Ïò Ïó Ïô ++ Ïõ Ïö Ï÷ Ïø Ïù Ïú Ïû Ïü Ïý Ïþ Ð@ Ð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 Ð[ Ð\ Ð] Ð^ Ð_ Ð` Ð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 Ð{ Ð| Ð} Ð~ С Т У Ф Ð¥ Ц Ч ++ Ш Щ Ъ Ы Ь Э Ю Я а б в г д е ж з ++ и й к л м н о п ÐÀ ÐÁ РÐà ÐÄ ÐÅ ÐÆ ÐÇ ++ ÐÈ ÐÉ ÐÊ ÐË ÐÌ ÐÍ ÐÎ ÐÏ ÐÐ ÐÑ ÐÒ ÐÓ ÐÔ ÐÕ ÐÖ Ð× ++ ÐØ ÐÙ ÐÚ ÐÛ ÐÜ ÐÝ ÐÞ Ðß Ðà Ðá Ðâ Ðã Ðä Ðå Ðæ Ðç ++ Ðè Ðé Ðê Ðë Ðì Ðí Ðî Ðï Ðð Ðñ Ðò Ðó Ðô Ðõ Ðö Ð÷ ++ Ðø Ðù Ðú Ðû Ðü Ðý Ðþ Ñ@ Ñ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 Ñ[ Ñ\ Ñ] Ñ^ Ñ_ Ñ` Ñ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 Ñ{ Ñ| Ñ} Ñ~ Ñ¡ Ñ¢ Ñ£ Ѥ Ñ¥ Ѧ ѧ Ѩ Ñ© Ѫ ++ Ñ« Ѭ Ñ­ Ñ® ѯ Ñ° ѱ Ѳ ѳ Ñ´ ѵ Ѷ Ñ· Ѹ ѹ Ѻ ++ Ñ» Ѽ ѽ Ѿ Ñ¿ ÑÀ ÑÁ Ñ Ñà ÑÄ ÑÅ ÑÆ ÑÇ ÑÈ ÑÉ ÑÊ ++ ÑË ÑÌ ÑÍ ÑÎ ÑÏ ÑÐ ÑÑ ÑÒ ÑÓ ÑÔ ÑÕ ÑÖ Ñ× ÑØ ÑÙ ÑÚ ++ ÑÛ ÑÜ ÑÝ ÑÞ Ñß Ñà Ñá Ñâ Ñã Ñä Ñå Ñæ Ñç Ñè Ñé Ñê ++ Ñë Ñì Ñí Ñî Ñï Ñð Ññ Ñò Ñó Ñô Ñõ Ñö Ñ÷ Ñø Ñù Ñú ++ Ñû Ñü Ñý Ñþ Ò@ Ò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 Ò[ ++ Ò\ Ò] Ò^ Ò_ Ò` Ò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 Ò{ ++ Ò| Ò} Ò~ Ò¡ Ò¢ Ò£ Ò¤ Ò¥ Ò¦ Ò§ Ò¨ Ò© Òª Ò« Ò¬ Ò­ ++ Ò® Ò¯ Ò° Ò± Ò² Ò³ Ò´ Òµ Ò¶ Ò· Ò¸ Ò¹ Òº Ò» Ò¼ Ò½ ++ Ò¾ Ò¿ ÒÀ ÒÁ Ò Òà ÒÄ ÒÅ ÒÆ ÒÇ ÒÈ ÒÉ ÒÊ ÒË ÒÌ ÒÍ ++ ÒÎ ÒÏ ÒÐ ÒÑ ÒÒ ÒÓ ÒÔ ÒÕ ÒÖ Ò× ÒØ ÒÙ ÒÚ ÒÛ ÒÜ ÒÝ ++ ÒÞ Òß Òà Òá Òâ Òã Òä Òå Òæ Òç Òè Òé Òê Òë Òì Òí ++ Òî Òï Òð Òñ Òò Òó Òô Òõ Òö Ò÷ Òø Òù Òú Òû Òü Òý ++ Òþ Ó@ Ó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 Ó[ Ó\ Ó] Ó^ ++ Ó_ Ó` Ó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 Ó{ Ó| Ó} Ó~ ++ Ó¡ Ó¢ Ó£ Ó¤ Ó¥ Ó¦ Ó§ Ó¨ Ó© Óª Ó« Ó¬ Ó­ Ó® Ó¯ Ó° ++ Ó± Ó² Ó³ Ó´ Óµ Ó¶ Ó· Ó¸ Ó¹ Óº Ó» Ó¼ Ó½ Ó¾ Ó¿ ÓÀ ++ ÓÁ Ó Óà ÓÄ ÓÅ ÓÆ ÓÇ ÓÈ ÓÉ ÓÊ ÓË ÓÌ ÓÍ ÓÎ ÓÏ ÓÐ ++ ÓÑ ÓÒ ÓÓ ÓÔ ÓÕ ÓÖ Ó× ÓØ ÓÙ ÓÚ ÓÛ ÓÜ ÓÝ ÓÞ Óß Óà ++ Óá Óâ Óã Óä Óå Óæ Óç Óè Óé Óê Óë Óì Óí Óî Óï Óð ++ Óñ Óò Óó Óô Óõ Óö Ó÷ Óø Óù Óú Óû Óü Óý Óþ Ô@ Ô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 Ô[ Ô\ Ô] Ô^ Ô_ Ô` Ô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 Ô{ Ô| Ô} Ô~ Ô¡ Ô¢ Ô£ ++ Ô¤ Ô¥ Ô¦ Ô§ Ô¨ Ô© Ôª Ô« Ô¬ Ô­ Ô® Ô¯ Ô° Ô± Ô² Ô³ ++ Ô´ Ôµ Ô¶ Ô· Ô¸ Ô¹ Ôº Ô» Ô¼ Ô½ Ô¾ Ô¿ ÔÀ ÔÁ Ô Ôà ++ ÔÄ ÔÅ ÔÆ ÔÇ ÔÈ ÔÉ ÔÊ ÔË ÔÌ ÔÍ ÔÎ ÔÏ ÔÐ ÔÑ ÔÒ ÔÓ ++ ÔÔ ÔÕ ÔÖ Ô× ÔØ ÔÙ ÔÚ ÔÛ ÔÜ ÔÝ ÔÞ Ôß Ôà Ôá Ôâ Ôã ++ Ôä Ôå Ôæ Ôç Ôè Ôé Ôê Ôë Ôì Ôí Ôî Ôï Ôð Ôñ Ôò Ôó ++ Ôô Ôõ Ôö Ô÷ Ôø Ôù Ôú Ôû Ôü Ôý Ôþ Õ@ Õ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 Õ[ Õ\ Õ] Õ^ Õ_ Õ` Õ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 Õ{ Õ| Õ} Õ~ Õ¡ Õ¢ Õ£ Õ¤ Õ¥ Õ¦ ++ Õ§ Õ¨ Õ© Õª Õ« Õ¬ Õ­ Õ® Õ¯ Õ° Õ± Õ² Õ³ Õ´ Õµ Õ¶ ++ Õ· Õ¸ Õ¹ Õº Õ» Õ¼ Õ½ Õ¾ Õ¿ ÕÀ ÕÁ Õ Õà ÕÄ ÕÅ ÕÆ ++ ÕÇ ÕÈ ÕÉ ÕÊ ÕË ÕÌ ÕÍ ÕÎ ÕÏ ÕÐ ÕÑ ÕÒ ÕÓ ÕÔ ÕÕ ÕÖ ++ Õ× ÕØ ÕÙ ÕÚ ÕÛ ÕÜ ÕÝ ÕÞ Õß Õà Õá Õâ Õã Õä Õå Õæ ++ Õç Õè Õé Õê Õë Õì Õí Õî Õï Õð Õñ Õò Õó Õô Õõ Õö ++ Õ÷ Õø Õù Õú Õû Õü Õý Õþ Ö@ Ö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 Ö[ Ö\ Ö] Ö^ Ö_ Ö` Ö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 Ö{ Ö| Ö} Ö~ Ö¡ Ö¢ Ö£ Ö¤ Ö¥ Ö¦ Ö§ Ö¨ Ö© ++ Öª Ö« Ö¬ Ö­ Ö® Ö¯ Ö° Ö± Ö² Ö³ Ö´ Öµ Ö¶ Ö· Ö¸ Ö¹ ++ Öº Ö» Ö¼ Ö½ Ö¾ Ö¿ ÖÀ ÖÁ Ö Öà ÖÄ ÖÅ ÖÆ ÖÇ ÖÈ ÖÉ ++ ÖÊ ÖË ÖÌ ÖÍ ÖÎ ÖÏ ÖÐ ÖÑ ÖÒ ÖÓ ÖÔ ÖÕ ÖÖ Ö× ÖØ ÖÙ ++ ÖÚ ÖÛ ÖÜ ÖÝ ÖÞ Öß Öà Öá Öâ Öã Öä Öå Öæ Öç Öè Öé ++ Öê Öë Öì Öí Öî Öï Öð Öñ Öò Öó Öô Öõ Öö Ö÷ Öø Öù ++ Öú Öû Öü Öý Öþ ×@ ×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 ++ ×[ ×\ ×] ×^ ×_ ×` ×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 ++ ×{ ×| ×} ×~ ס ×¢ ×£ פ ×¥ צ ק ר ש ת ׫ ׬ ++ ×­ ×® ׯ ×° ×± ײ ׳ ×´ ×µ ׶ ×· ׸ ×¹ ׺ ×» ×¼ ++ ×½ ×¾ ׿ ×À ×Á × ×à ×Ä ×Å ×Æ ×Ç ×È ×É ×Ê ×Ë ×Ì ++ ×Í ×Î ×Ï ×Ð ×Ñ ×Ò ×Ó ×Ô ×Õ ×Ö ×× ×Ø ×Ù ×Ú ×Û ×Ü ++ ×Ý ×Þ ×ß ×à ×á ×â ×ã ×ä ×å ×æ ×ç ×è ×é ×ê ×ë ×ì ++ ×í ×î ×ï ×ð ×ñ ×ò ×ó ×ô ×õ ×ö ×÷ ×ø ×ù ×ú ×û ×ü ++ ×ý ×þ Ø@ Ø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 Ø[ Ø\ Ø] ++ Ø^ Ø_ Ø` Ø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 Ø{ Ø| Ø} ++ Ø~ Ø¡ Ø¢ Ø£ ؤ Ø¥ ئ ا ب Ø© ت Ø« ج Ø­ Ø® د ++ Ø° ر ز س Ø´ ص ض Ø· ظ ع غ Ø» ؼ ؽ ؾ Ø¿ ++ ØÀ ØÁ Ø Øà ØÄ ØÅ ØÆ ØÇ ØÈ ØÉ ØÊ ØË ØÌ ØÍ ØÎ ØÏ ++ ØÐ ØÑ ØÒ ØÓ ØÔ ØÕ ØÖ Ø× ØØ ØÙ ØÚ ØÛ ØÜ ØÝ ØÞ Øß ++ Øà Øá Øâ Øã Øä Øå Øæ Øç Øè Øé Øê Øë Øì Øí Øî Øï ++ Øð Øñ Øò Øó Øô Øõ Øö Ø÷ Øø Øù Øú Øû Øü Øý Øþ Ù@ ++ Ù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 Ù[ Ù\ Ù] Ù^ Ù_ Ù` ++ Ù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 Ù{ Ù| Ù} Ù~ Ù¡ Ù¢ ++ Ù£ Ù¤ Ù¥ Ù¦ Ù§ Ù¨ Ù© Ùª Ù« Ù¬ Ù­ Ù® Ù¯ Ù° Ù± Ù² ++ Ù³ Ù´ Ùµ Ù¶ Ù· Ù¸ Ù¹ Ùº Ù» Ù¼ Ù½ Ù¾ Ù¿ ÙÀ ÙÁ Ù ++ Ùà ÙÄ ÙÅ ÙÆ ÙÇ ÙÈ ÙÉ ÙÊ ÙË ÙÌ ÙÍ ÙÎ ÙÏ ÙÐ ÙÑ ÙÒ ++ ÙÓ ÙÔ ÙÕ ÙÖ Ù× ÙØ ÙÙ ÙÚ ÙÛ ÙÜ ÙÝ ÙÞ Ùß Ùà Ùá Ùâ ++ Ùã Ùä Ùå Ùæ Ùç Ùè Ùé Ùê Ùë Ùì Ùí Ùî Ùï Ùð Ùñ Ùò ++ Ùó Ùô Ùõ Ùö Ù÷ Ùø Ùù Ùú Ùû Ùü Ùý Ùþ Ú@ Ú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 Ú[ Ú\ Ú] Ú^ Ú_ Ú` Ú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 Ú{ Ú| Ú} Ú~ Ú¡ Ú¢ Ú£ Ú¤ Ú¥ ++ Ú¦ Ú§ Ú¨ Ú© Úª Ú« Ú¬ Ú­ Ú® Ú¯ Ú° Ú± Ú² Ú³ Ú´ Úµ ++ Ú¶ Ú· Ú¸ Ú¹ Úº Ú» Ú¼ Ú½ Ú¾ Ú¿ ÚÀ ÚÁ Ú Úà ÚÄ ÚÅ ++ ÚÆ ÚÇ ÚÈ ÚÉ ÚÊ ÚË ÚÌ ÚÍ ÚÎ ÚÏ ÚÐ ÚÑ ÚÒ ÚÓ ÚÔ ÚÕ ++ ÚÖ Ú× ÚØ ÚÙ ÚÚ ÚÛ ÚÜ ÚÝ ÚÞ Úß Úà Úá Úâ Úã Úä Úå ++ Úæ Úç Úè Úé Úê Úë Úì Úí Úî Úï Úð Úñ Úò Úó Úô Úõ ++ Úö Ú÷ Úø Úù Úú Úû Úü Úý Úþ Û@ Û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 Û[ Û\ Û] Û^ Û_ Û` Û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 Û{ Û| Û} Û~ Û¡ Û¢ Û£ Û¤ Û¥ Û¦ Û§ Û¨ ++ Û© Ûª Û« Û¬ Û­ Û® Û¯ Û° Û± Û² Û³ Û´ Ûµ Û¶ Û· Û¸ ++ Û¹ Ûº Û» Û¼ Û½ Û¾ Û¿ ÛÀ ÛÁ Û Ûà ÛÄ ÛÅ ÛÆ ÛÇ ÛÈ ++ ÛÉ ÛÊ ÛË ÛÌ ÛÍ ÛÎ ÛÏ ÛÐ ÛÑ ÛÒ ÛÓ ÛÔ ÛÕ ÛÖ Û× ÛØ ++ ÛÙ ÛÚ ÛÛ ÛÜ ÛÝ ÛÞ Ûß Ûà Ûá Ûâ Ûã Ûä Ûå Ûæ Ûç Ûè ++ Ûé Ûê Ûë Ûì Ûí Ûî Ûï Ûð Ûñ Ûò Ûó Ûô Ûõ Ûö Û÷ Ûø ++ Ûù Ûú Ûû Ûü Ûý Ûþ Ü@ Ü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 Ü[ Ü\ Ü] Ü^ Ü_ Ü` Ü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 Ü{ Ü| Ü} Ü~ Ü¡ Ü¢ Ü£ ܤ Ü¥ ܦ ܧ ܨ Ü© ܪ Ü« ++ ܬ Ü­ Ü® ܯ Ü° ܱ ܲ ܳ Ü´ ܵ ܶ Ü· ܸ ܹ ܺ Ü» ++ ܼ ܽ ܾ Ü¿ ÜÀ ÜÁ Ü Üà ÜÄ ÜÅ ÜÆ ÜÇ ÜÈ ÜÉ ÜÊ ÜË ++ ÜÌ ÜÍ ÜÎ ÜÏ ÜÐ ÜÑ ÜÒ ÜÓ ÜÔ ÜÕ ÜÖ Ü× ÜØ ÜÙ ÜÚ ÜÛ ++ ÜÜ ÜÝ ÜÞ Üß Üà Üá Üâ Üã Üä Üå Üæ Üç Üè Üé Üê Üë ++ Üì Üí Üî Üï Üð Üñ Üò Üó Üô Üõ Üö Ü÷ Üø Üù Üú Üû ++ Üü Üý Üþ Ý@ Ý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 Ý[ Ý\ ++ Ý] Ý^ Ý_ Ý` Ý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 Ý{ Ý| ++ Ý} Ý~ Ý¡ Ý¢ Ý£ ݤ Ý¥ ݦ ݧ ݨ Ý© ݪ Ý« ݬ Ý­ Ý® ++ ݯ Ý° ݱ ݲ ݳ Ý´ ݵ ݶ Ý· ݸ ݹ ݺ Ý» ݼ ݽ ݾ ++ Ý¿ ÝÀ ÝÁ Ý Ýà ÝÄ ÝÅ ÝÆ ÝÇ ÝÈ ÝÉ ÝÊ ÝË ÝÌ ÝÍ ÝÎ ++ ÝÏ ÝÐ ÝÑ ÝÒ ÝÓ ÝÔ ÝÕ ÝÖ Ý× ÝØ ÝÙ ÝÚ ÝÛ ÝÜ ÝÝ ÝÞ ++ Ýß Ýà Ýá Ýâ Ýã Ýä Ýå Ýæ Ýç Ýè Ýé Ýê Ýë Ýì Ýí Ýî ++ Ýï Ýð Ýñ Ýò Ýó Ýô Ýõ Ýö Ý÷ Ýø Ýù Ýú Ýû Ýü Ýý Ýþ ++ Þ@ Þ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 Þ[ Þ\ Þ] Þ^ Þ_ ++ Þ` Þ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 Þ{ Þ| Þ} Þ~ Þ¡ ++ Þ¢ Þ£ Þ¤ Þ¥ Þ¦ Þ§ Þ¨ Þ© Þª Þ« Þ¬ Þ­ Þ® Þ¯ Þ° Þ± ++ Þ² Þ³ Þ´ Þµ Þ¶ Þ· Þ¸ Þ¹ Þº Þ» Þ¼ Þ½ Þ¾ Þ¿ ÞÀ ÞÁ ++ Þ Þà ÞÄ ÞÅ ÞÆ ÞÇ ÞÈ ÞÉ ÞÊ ÞË ÞÌ ÞÍ ÞÎ ÞÏ ÞÐ ÞÑ ++ ÞÒ ÞÓ ÞÔ ÞÕ ÞÖ Þ× ÞØ ÞÙ ÞÚ ÞÛ ÞÜ ÞÝ ÞÞ Þß Þà Þá ++ Þâ Þã Þä Þå Þæ Þç Þè Þé Þê Þë Þì Þí Þî Þï Þð Þñ ++ Þò Þó Þô Þõ Þö Þ÷ Þø Þù Þú Þû Þü Þý Þþ ß@ ß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 ß[ ß\ ß] ß^ ß_ ß` ß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 ß{ ß| ß} ß~ ß¡ ߢ ߣ ߤ ++ ߥ ߦ ߧ ߨ ß© ߪ ß« ߬ ß­ ß® ߯ ß° ß± ß² ß³ ß´ ++ ßµ ߶ ß· ߸ ß¹ ߺ ß» ß¼ ß½ ß¾ ß¿ ßÀ ßÁ ß ßà ßÄ ++ ßÅ ßÆ ßÇ ßÈ ßÉ ßÊ ßË ßÌ ßÍ ßÎ ßÏ ßÐ ßÑ ßÒ ßÓ ßÔ ++ ßÕ ßÖ ß× ßØ ßÙ ßÚ ßÛ ßÜ ßÝ ßÞ ßß ßà ßá ßâ ßã ßä ++ ßå ßæ ßç ßè ßé ßê ßë ßì ßí ßî ßï ßð ßñ ßò ßó ßô ++ ßõ ßö ß÷ ßø ßù ßú ßû ßü ßý ßþ à@ à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 à[ à\ à] à^ à_ à` à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 à{ à| à} à~ ࡠࢠ࣠ठॠঠৠ++ ਠ੠ઠૠଠୠ஠௠ఠౠಠೠഠൠච෠++ ภ๠ຠ໠༠འྠ࿠àÀ àÁ à àà àÄ àÅ àÆ àÇ ++ àÈ àÉ àÊ àË àÌ àÍ àÎ àÏ àÐ àÑ àÒ àÓ àÔ àÕ àÖ à× ++ àØ àÙ àÚ àÛ àÜ àÝ àÞ àß àà àá àâ àã àä àå àæ àç ++ àè àé àê àë àì àí àî àï àð àñ àò àó àô àõ àö à÷ ++ àø àù àú àû àü àý àþ á@ á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 á[ á\ á] á^ á_ á` á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 á{ á| á} á~ ᡠᢠᣠᤠᥠᦠ᧠ᨠ᩠᪠++ ᫠ᬠ᭠ᮠᯠᰠᱠᲠ᳠ᴠᵠᶠᷠḠṠẠ++ á» á¼ á½ á¾ á¿ áÀ áÁ á áà áÄ áÅ áÆ áÇ áÈ áÉ áÊ ++ áË áÌ áÍ áÎ áÏ áÐ áÑ áÒ áÓ áÔ áÕ áÖ á× áØ áÙ áÚ ++ áÛ áÜ áÝ áÞ áß áà áá áâ áã áä áå áæ áç áè áé áê ++ áë áì áí áî áï áð áñ áò áó áô áõ áö á÷ áø áù áú ++ áû áü áý áþ â@ â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 â[ ++ â\ â] â^ â_ â` â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 â{ ++ â| â} â~ ⡠⢠⣠⤠⥠⦠⧠⨠⩠⪠⫠⬠⭠++ ⮠⯠ⰠⱠⲠⳠⴠⵠⶠⷠ⸠⹠⺠⻠⼠⽠++ â¾ â¿ âÀ âÁ â âà âÄ âÅ âÆ âÇ âÈ âÉ âÊ âË âÌ âÍ ++ âÎ âÏ âÐ âÑ âÒ âÓ âÔ âÕ âÖ â× âØ âÙ âÚ âÛ âÜ âÝ ++ âÞ âß âà âá ââ âã âä âå âæ âç âè âé âê âë âì âí ++ âî âï âð âñ âò âó âô âõ âö â÷ âø âù âú âû âü âý ++ âþ ã@ ã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 ã[ ã\ ã] ã^ ++ ã_ ã` ã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 ã{ ã| ã} ã~ ++ 㡠㢠㣠㤠㥠㦠㧠㨠㩠㪠㫠㬠㭠㮠㯠㰠++ 㱠㲠㳠㴠㵠㶠㷠㸠㹠㺠㻠㼠㽠㾠㿠ãÀ ++ ãÁ ã ãà ãÄ ãÅ ãÆ ãÇ ãÈ ãÉ ãÊ ãË ãÌ ãÍ ãÎ ãÏ ãÐ ++ ãÑ ãÒ ãÓ ãÔ ãÕ ãÖ ã× ãØ ãÙ ãÚ ãÛ ãÜ ãÝ ãÞ ãß ãà ++ ãá ãâ ãã ãä ãå ãæ ãç ãè ãé ãê ãë ãì ãí ãî ãï ãð ++ ãñ ãò ãó ãô ãõ ãö ã÷ ãø ãù ãú ãû ãü ãý ãþ ä@ ä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 ä[ ä\ ä] ä^ ä_ ä` ä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 ä{ ä| ä} ä~ ä¡ ä¢ ä£ ++ ä¤ ä¥ ä¦ ä§ ä¨ ä© äª ä« ä¬ ä­ ä® ä¯ ä° ä± ä² ä³ ++ ä´ äµ ä¶ ä· ä¸ ä¹ äº ä» ä¼ ä½ ä¾ ä¿ äÀ äÁ ä äà ++ äÄ äÅ äÆ äÇ äÈ äÉ äÊ äË äÌ äÍ äÎ äÏ äÐ äÑ äÒ äÓ ++ äÔ äÕ äÖ ä× äØ äÙ äÚ äÛ äÜ äÝ äÞ äß äà äá äâ äã ++ ää äå äæ äç äè äé äê äë äì äí äî äï äð äñ äò äó ++ äô äõ äö ä÷ äø äù äú äû äü äý äþ å@ å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 å[ å\ å] å^ å_ å` å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 å{ å| å} å~ å¡ å¢ å£ å¤ å¥ å¦ ++ å§ å¨ å© åª å« å¬ å­ å® å¯ å° å± å² å³ å´ åµ å¶ ++ å· å¸ å¹ åº å» å¼ å½ å¾ å¿ åÀ åÁ å åà åÄ åÅ åÆ ++ åÇ åÈ åÉ åÊ åË åÌ åÍ åÎ åÏ åÐ åÑ åÒ åÓ åÔ åÕ åÖ ++ å× åØ åÙ åÚ åÛ åÜ åÝ åÞ åß åà åá åâ åã åä åå åæ ++ åç åè åé åê åë åì åí åî åï åð åñ åò åó åô åõ åö ++ å÷ åø åù åú åû åü åý åþ æ@ æ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 æ[ æ\ æ] æ^ æ_ æ` æ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 æ{ æ| æ} æ~ æ¡ æ¢ æ£ æ¤ æ¥ æ¦ æ§ æ¨ æ© ++ æª æ« æ¬ æ­ æ® æ¯ æ° æ± æ² æ³ æ´ æµ æ¶ æ· æ¸ æ¹ ++ æº æ» æ¼ æ½ æ¾ æ¿ æÀ æÁ æ æà æÄ æÅ æÆ æÇ æÈ æÉ ++ æÊ æË æÌ æÍ æÎ æÏ æÐ æÑ æÒ æÓ æÔ æÕ æÖ æ× æØ æÙ ++ æÚ æÛ æÜ æÝ æÞ æß æà æá æâ æã æä æå ææ æç æè æé ++ æê æë æì æí æî æï æð æñ æò æó æô æõ æö æ÷ æø æù ++ æú æû æü æý æþ ç@ ç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 ++ ç[ ç\ ç] ç^ ç_ ç` ç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 ++ ç{ ç| ç} ç~ ç¡ ç¢ ç£ ç¤ ç¥ ç¦ ç§ ç¨ ç© çª ç« ç¬ ++ ç­ ç® ç¯ ç° ç± ç² ç³ ç´ çµ ç¶ ç· ç¸ ç¹ çº ç» ç¼ ++ ç½ ç¾ ç¿ çÀ çÁ ç çà çÄ çÅ çÆ çÇ çÈ çÉ çÊ çË çÌ ++ çÍ çÎ çÏ çÐ çÑ çÒ çÓ çÔ çÕ çÖ ç× çØ çÙ çÚ çÛ çÜ ++ çÝ çÞ çß çà çá çâ çã çä çå çæ çç çè çé çê çë çì ++ çí çî çï çð çñ çò çó çô çõ çö ç÷ çø çù çú çû çü ++ çý çþ è@ è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 è[ è\ è] ++ è^ è_ è` è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 è{ è| è} ++ è~ è¡ è¢ è£ è¤ è¥ è¦ è§ è¨ è© èª è« è¬ è­ è® è¯ ++ è° è± è² è³ è´ èµ è¶ è· è¸ è¹ èº è» è¼ è½ è¾ è¿ ++ èÀ èÁ è èà èÄ èÅ èÆ èÇ èÈ èÉ èÊ èË èÌ èÍ èÎ èÏ ++ èÐ èÑ èÒ èÓ èÔ èÕ èÖ è× èØ èÙ èÚ èÛ èÜ èÝ èÞ èß ++ èà èá èâ èã èä èå èæ èç èè èé èê èë èì èí èî èï ++ èð èñ èò èó èô èõ èö è÷ èø èù èú èû èü èý èþ é@ ++ é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 é[ é\ é] é^ é_ é` ++ é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 é{ é| é} é~ é¡ é¢ ++ é£ é¤ é¥ é¦ é§ é¨ é© éª é« é¬ é­ é® é¯ é° é± é² ++ é³ é´ éµ é¶ é· é¸ é¹ éº é» é¼ é½ é¾ é¿ éÀ éÁ é ++ éà éÄ éÅ éÆ éÇ éÈ éÉ éÊ éË éÌ éÍ éÎ éÏ éÐ éÑ éÒ ++ éÓ éÔ éÕ éÖ é× éØ éÙ éÚ éÛ éÜ éÝ éÞ éß éà éá éâ ++ éã éä éå éæ éç éè éé éê éë éì éí éî éï éð éñ éò ++ éó éô éõ éö é÷ éø éù éú éû éü éý éþ ê@ ê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 ê[ ê\ ê] ê^ ê_ ê` ê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 ê{ ê| ê} ê~ ê¡ ê¢ ê£ ê¤ ê¥ ++ ê¦ ê§ ê¨ ê© êª ê« ê¬ ê­ ê® ê¯ ê° ê± ê² ê³ ê´ êµ ++ ê¶ ê· ê¸ ê¹ êº ê» ê¼ ê½ ê¾ ê¿ êÀ êÁ ê êà êÄ êÅ ++ êÆ êÇ êÈ êÉ êÊ êË êÌ êÍ êÎ êÏ êÐ êÑ êÒ êÓ êÔ êÕ ++ êÖ ê× êØ êÙ êÚ êÛ êÜ êÝ êÞ êß êà êá êâ êã êä êå ++ êæ êç êè êé êê êë êì êí êî êï êð êñ êò êó êô êõ ++ êö ê÷ êø êù êú êû êü êý êþ ë@ ë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 ë[ ë\ ë] ë^ ë_ ë` ë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 ë{ ë| ë} ë~ ë¡ ë¢ ë£ ë¤ ë¥ ë¦ ë§ ë¨ ++ ë© ëª ë« ë¬ ë­ ë® ë¯ ë° ë± ë² ë³ ë´ ëµ ë¶ ë· ë¸ ++ ë¹ ëº ë» ë¼ ë½ ë¾ ë¿ ëÀ ëÁ ë ëà ëÄ ëÅ ëÆ ëÇ ëÈ ++ ëÉ ëÊ ëË ëÌ ëÍ ëÎ ëÏ ëÐ ëÑ ëÒ ëÓ ëÔ ëÕ ëÖ ë× ëØ ++ ëÙ ëÚ ëÛ ëÜ ëÝ ëÞ ëß ëà ëá ëâ ëã ëä ëå ëæ ëç ëè ++ ëé ëê ëë ëì ëí ëî ëï ëð ëñ ëò ëó ëô ëõ ëö ë÷ ëø ++ ëù ëú ëû ëü ëý ëþ ì@ ì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 ì[ ì\ ì] ì^ ì_ ì` ì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 ì{ ì| ì} ì~ ì¡ ì¢ ì£ ì¤ ì¥ ì¦ ì§ ì¨ ì© ìª ì« ++ ì¬ ì­ ì® ì¯ ì° ì± ì² ì³ ì´ ìµ ì¶ ì· ì¸ ì¹ ìº ì» ++ ì¼ ì½ ì¾ ì¿ ìÀ ìÁ ì ìà ìÄ ìÅ ìÆ ìÇ ìÈ ìÉ ìÊ ìË ++ ìÌ ìÍ ìÎ ìÏ ìÐ ìÑ ìÒ ìÓ ìÔ ìÕ ìÖ ì× ìØ ìÙ ìÚ ìÛ ++ ìÜ ìÝ ìÞ ìß ìà ìá ìâ ìã ìä ìå ìæ ìç ìè ìé ìê ìë ++ ìì ìí ìî ìï ìð ìñ ìò ìó ìô ìõ ìö ì÷ ìø ìù ìú ìû ++ ìü ìý ìþ í@ í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 í[ í\ ++ í] í^ í_ í` í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 í{ í| ++ í} í~ í¡ í¢ í£ í¤ í¥ í¦ í§ í¨ í© íª í« í¬ í­ í® ++ í¯ í° í± í² í³ í´ íµ í¶ í· í¸ í¹ íº í» í¼ í½ í¾ ++ í¿ íÀ íÁ í íà íÄ íÅ íÆ íÇ íÈ íÉ íÊ íË íÌ íÍ íÎ ++ íÏ íÐ íÑ íÒ íÓ íÔ íÕ íÖ í× íØ íÙ íÚ íÛ íÜ íÝ íÞ ++ íß íà íá íâ íã íä íå íæ íç íè íé íê íë íì íí íî ++ íï íð íñ íò íó íô íõ íö í÷ íø íù íú íû íü íý íþ ++ î@ î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 î[ î\ î] î^ î_ ++ î` î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 î{ î| î} î~ î¡ ++ î¢ î£ î¤ î¥ î¦ î§ î¨ î© îª î« î¬ î­ î® î¯ î° î± ++ î² î³ î´ îµ î¶ î· î¸ î¹ îº î» î¼ î½ î¾ î¿ îÀ îÁ ++ î îà îÄ îÅ îÆ îÇ îÈ îÉ îÊ îË îÌ îÍ îÎ îÏ îÐ îÑ ++ îÒ îÓ îÔ îÕ îÖ î× îØ îÙ îÚ îÛ îÜ îÝ îÞ îß îà îá ++ îâ îã îä îå îæ îç îè îé îê îë îì îí îî îï îð îñ ++ îò îó îô îõ îö î÷ îø îù îú îû îü îý îþ ï@ ï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 ï[ ï\ ï] ï^ ï_ ï` ï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 ï{ ï| ï} ï~ ï¡ ï¢ ï£ ï¤ ++ ï¥ ï¦ ï§ ï¨ ï© ïª ï« ï¬ ï­ ï® ï¯ ï° ï± ï² ï³ ï´ ++ ïµ ï¶ ï· ï¸ ï¹ ïº ï» ï¼ ï½ ï¾ ï¿ ïÀ ïÁ ï ïà ïÄ ++ ïÅ ïÆ ïÇ ïÈ ïÉ ïÊ ïË ïÌ ïÍ ïÎ ïÏ ïÐ ïÑ ïÒ ïÓ ïÔ ++ ïÕ ïÖ ï× ïØ ïÙ ïÚ ïÛ ïÜ ïÝ ïÞ ïß ïà ïá ïâ ïã ïä ++ ïå ïæ ïç ïè ïé ïê ïë ïì ïí ïî ïï ïð ïñ ïò ïó ïô ++ ïõ ïö ï÷ ïø ïù ïú ïû ïü ïý ïþ ð@ ð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 ð[ ð\ ð] ð^ ð_ ð` ð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 ð{ ð| ð} ð~ ð¡ ð¢ ð£ ð¤ ð¥ ð¦ ð§ ++ ð¨ ð© ðª ð« ð¬ ð­ ð® ð¯ ð° ð± ð² ð³ ð´ ðµ ð¶ ð· ++ ð¸ ð¹ ðº ð» ð¼ ð½ ð¾ ð¿ ðÀ ðÁ ð ðà ðÄ ðÅ ðÆ ðÇ ++ ðÈ ðÉ ðÊ ðË ðÌ ðÍ ðÎ ðÏ ðÐ ðÑ ðÒ ðÓ ðÔ ðÕ ðÖ ð× ++ ðØ ðÙ ðÚ ðÛ ðÜ ðÝ ðÞ ðß ðà ðá ðâ ðã ðä ðå ðæ ðç ++ ðè ðé ðê ðë ðì ðí ðî ðï ðð ðñ ðò ðó ðô ðõ ðö ð÷ ++ ðø ðù ðú ðû ðü ðý ðþ ñ@ ñ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 ñ[ ñ\ ñ] ñ^ ñ_ ñ` ñ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 ñ{ ñ| ñ} ñ~ ñ¡ ñ¢ ñ£ ñ¤ ñ¥ ñ¦ ñ§ ñ¨ ñ© ñª ++ ñ« ñ¬ ñ­ ñ® ñ¯ ñ° ñ± ñ² ñ³ ñ´ ñµ ñ¶ ñ· ñ¸ ñ¹ ñº ++ ñ» ñ¼ ñ½ ñ¾ ñ¿ ñÀ ñÁ ñ ñà ñÄ ñÅ ñÆ ñÇ ñÈ ñÉ ñÊ ++ ñË ñÌ ñÍ ñÎ ñÏ ñÐ ñÑ ñÒ ñÓ ñÔ ñÕ ñÖ ñ× ñØ ñÙ ñÚ ++ ñÛ ñÜ ñÝ ñÞ ñß ñà ñá ñâ ñã ñä ñå ñæ ñç ñè ñé ñê ++ ñë ñì ñí ñî ñï ñð ññ ñò ñó ñô ñõ ñö ñ÷ ñø ñù ñú ++ ñû ñü ñý ñþ ò@ ò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 ò[ ++ ò\ ò] ò^ ò_ ò` ò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 ò{ ++ ò| ò} ò~ ò¡ ò¢ ò£ ò¤ ò¥ ò¦ ò§ ò¨ ò© òª ò« ò¬ ò­ ++ ò® ò¯ ò° ò± ò² ò³ ò´ òµ ò¶ ò· ò¸ ò¹ òº ò» ò¼ ò½ ++ ò¾ ò¿ òÀ òÁ ò òà òÄ òÅ òÆ òÇ òÈ òÉ òÊ òË òÌ òÍ ++ òÎ òÏ òÐ òÑ òÒ òÓ òÔ òÕ òÖ ò× òØ òÙ òÚ òÛ òÜ òÝ ++ òÞ òß òà òá òâ òã òä òå òæ òç òè òé òê òë òì òí ++ òî òï òð òñ òò òó òô òõ òö ò÷ òø òù òú òû òü òý ++ òþ ó@ ó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 ó[ ó\ ó] ó^ ++ ó_ ó` ó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 ó{ ó| ó} ó~ ++ ó¡ ó¢ ó£ ó¤ ó¥ ó¦ ó§ ó¨ ó© óª ó« ó¬ ó­ ó® ó¯ ó° ++ ó± ó² ó³ ó´ óµ ó¶ ó· ó¸ ó¹ óº ó» ó¼ ó½ ó¾ ó¿ óÀ ++ óÁ ó óà óÄ óÅ óÆ óÇ óÈ óÉ óÊ óË óÌ óÍ óÎ óÏ óÐ ++ óÑ óÒ óÓ óÔ óÕ óÖ ó× óØ óÙ óÚ óÛ óÜ óÝ óÞ óß óà ++ óá óâ óã óä óå óæ óç óè óé óê óë óì óí óî óï óð ++ óñ óò óó óô óõ óö ó÷ óø óù óú óû óü óý óþ ô@ ô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 ô[ ô\ ô] ô^ ô_ ô` ô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 ô{ ô| ô} ô~ ô¡ ô¢ ô£ ++ ô¤ ô¥ ô¦ ô§ ô¨ ô© ôª ô« ô¬ ô­ ô® ô¯ ô° ô± ô² ô³ ++ ô´ ôµ ô¶ ô· ô¸ ô¹ ôº ô» ô¼ ô½ ô¾ ô¿ ôÀ ôÁ ô ôà ++ ôÄ ôÅ ôÆ ôÇ ôÈ ôÉ ôÊ ôË ôÌ ôÍ ôÎ ôÏ ôÐ ôÑ ôÒ ôÓ ++ ôÔ ôÕ ôÖ ô× ôØ ôÙ ôÚ ôÛ ôÜ ôÝ ôÞ ôß ôà ôá ôâ ôã ++ ôä ôå ôæ ôç ôè ôé ôê ôë ôì ôí ôî ôï ôð ôñ ôò ôó ++ ôô ôõ ôö ô÷ ôø ôù ôú ôû ôü ôý ôþ õ@ õ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 õ[ õ\ õ] õ^ õ_ õ` õ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 õ{ õ| õ} õ~ õ¡ õ¢ õ£ õ¤ õ¥ õ¦ ++ õ§ õ¨ õ© õª õ« õ¬ õ­ õ® õ¯ õ° õ± õ² õ³ õ´ õµ õ¶ ++ õ· õ¸ õ¹ õº õ» õ¼ õ½ õ¾ õ¿ õÀ õÁ õ õà õÄ õÅ õÆ ++ õÇ õÈ õÉ õÊ õË õÌ õÍ õÎ õÏ õÐ õÑ õÒ õÓ õÔ õÕ õÖ ++ õ× õØ õÙ õÚ õÛ õÜ õÝ õÞ õß õà õá õâ õã õä õå õæ ++ õç õè õé õê õë õì õí õî õï õð õñ õò õó õô õõ õö ++ õ÷ õø õù õú õû õü õý õþ ö@ ö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 ö[ ö\ ö] ö^ ö_ ö` ö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 ö{ ö| ö} ö~ ö¡ ö¢ ö£ ö¤ ö¥ ö¦ ö§ ö¨ ö© ++ öª ö« ö¬ ö­ ö® ö¯ ö° ö± ö² ö³ ö´ öµ ö¶ ö· ö¸ ö¹ ++ öº ö» ö¼ ö½ ö¾ ö¿ öÀ öÁ ö öà öÄ öÅ öÆ öÇ öÈ öÉ ++ öÊ öË öÌ öÍ öÎ öÏ öÐ öÑ öÒ öÓ öÔ öÕ öÖ ö× öØ öÙ ++ öÚ öÛ öÜ öÝ öÞ öß öà öá öâ öã öä öå öæ öç öè öé ++ öê öë öì öí öî öï öð öñ öò öó öô öõ öö ö÷ öø öù ++ öú öû öü öý öþ ÷@ ÷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 ++ ÷[ ÷\ ÷] ÷^ ÷_ ÷` ÷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 ++ ÷{ ÷| ÷} ÷~ ÷¡ ÷¢ ÷£ ÷¤ ÷¥ ÷¦ ÷§ ÷¨ ÷© ÷ª ÷« ÷¬ ++ ÷­ ÷® ÷¯ ÷° ÷± ÷² ÷³ ÷´ ÷µ ÷¶ ÷· ÷¸ ÷¹ ÷º ÷» ÷¼ ++ ÷½ ÷¾ ÷¿ ÷À ÷Á ÷ ÷à ÷Ä ÷Å ÷Æ ÷Ç ÷È ÷É ÷Ê ÷Ë ÷Ì ++ ÷Í ÷Î ÷Ï ÷Ð ÷Ñ ÷Ò ÷Ó ÷Ô ÷Õ ÷Ö ÷× ÷Ø ÷Ù ÷Ú ÷Û ÷Ü ++ ÷Ý ÷Þ ÷ß ÷à ÷á ÷â ÷ã ÷ä ÷å ÷æ ÷ç ÷è ÷é ÷ê ÷ë ÷ì ++ ÷í ÷î ÷ï ÷ð ÷ñ ÷ò ÷ó ÷ô ÷õ ÷ö ÷÷ ÷ø ÷ù ÷ú ÷û ÷ü ++ ÷ý ÷þ ø@ ø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 ø[ ø\ ø] ++ ø^ ø_ ø` ø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 ø{ ø| ø} ++ ø~ ø¡ ø¢ ø£ ø¤ ø¥ ø¦ ø§ ø¨ ø© øª ø« ø¬ ø­ ø® ø¯ ++ ø° ø± ø² ø³ ø´ øµ ø¶ ø· ø¸ ø¹ øº ø» ø¼ ø½ ø¾ ø¿ ++ øÀ øÁ ø øà øÄ øÅ øÆ øÇ øÈ øÉ øÊ øË øÌ øÍ øÎ øÏ ++ øÐ øÑ øÒ øÓ øÔ øÕ øÖ ø× øØ øÙ øÚ øÛ øÜ øÝ øÞ øß ++ øà øá øâ øã øä øå øæ øç øè øé øê øë øì øí øî øï ++ øð øñ øò øó øô øõ øö ø÷ øø øù øú øû øü øý øþ ù@ ++ ù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 ù[ ù\ ù] ù^ ù_ ù` ++ ù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 ù{ ù| ù} ù~ ù¡ ù¢ ++ ù£ ù¤ ù¥ ù¦ ù§ ù¨ ù© ùª ù« ù¬ ù­ ù® ù¯ ù° ù± ù² ++ ù³ ù´ ùµ ù¶ ù· ù¸ ù¹ ùº ù» ù¼ ù½ ù¾ ù¿ ùÀ ùÁ ù ++ ùà ùÄ ùÅ ùÆ ùÇ ùÈ ùÉ ùÊ ùË ùÌ ùÍ ùÎ ùÏ ùÐ ùÑ ùÒ ++ ùÓ ùÔ ùÕ ùÖ ù× ùØ ùÙ ùÚ ùÛ ùÜ ùÝ ùÞ ùß ùà ùá ùâ ++ ùã ùä ùå ùæ ùç ùè ùé ùê ùë ùì ùí ùî ùï ùð ùñ ùò ++ ùó ùô ùõ ùö ù÷ ùø ùù ùú ùû ùü ùý ùþ ú@ ú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 ú[ ú\ ú] ú^ ú` úa úb úc úd ++ úe úg úh úi új úk úl úm ún úo úp úq úr ús út úu ++ úv úw úx úy úz ú{ ú| ú} ú~ ú¡ ú¢ ú£ ú¤ ú¥ ú¦ ú§ ++ ú¨ ú© úª ú« ú¬ ú­ ú® ú¯ ú° ú± ú² ú³ ú´ úµ ú¶ ú· ++ ú¸ ú¹ úº ú» ú¼ ú¾ ú¿ úÀ úÁ ú úà úÄ úÆ úÇ úÈ úÉ ++ úÊ úË úÌ úÍ úÎ úÏ úÐ úÑ úÒ úÓ úÔ úÖ ú× úØ úÙ úÚ ++ úÛ úÜ úÝ úÞ úß úà úá úâ úã úä úå úæ úç úè úé úê ++ úë úì úí úî úï úð úñ úò úó úô úõ úö ú÷ úø úù úú ++ úû úü úý úþ û@ ûA ûB ûC ûD ûE ûF ûG ûI ûJ ûK ûL ++ ûM ûN ûO ûP ûQ ûR ûS ûT ûU ûV ûW ûX ûY ûZ û[ û\ ++ û] û^ û_ û` û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 û{ û| ++ û} û~ û¡ û¢ û£ û¤ û¥ û¦ û§ û¨ û© ûª û« û¬ û­ û® ++ û¯ û° û± û² û³ û´ ûµ û¶ û· û¹ ûº û» û¼ û½ û¾ û¿ ++ ûÀ ûÁ û ûà ûÄ ûÅ ûÆ ûÇ ûÈ ûÉ ûÊ ûË ûÌ ûÍ ûÎ ûÏ ++ ûÐ ûÑ ûÒ ûÓ ûÔ ûÕ ûÖ û× ûØ ûÙ ûÚ ûÛ ûÜ ûÝ ûÞ ûß ++ ûà ûá ûâ ûã ûä ûå ûæ ûç ûè ûé ûê ûë ûì ûí ûî ûï ++ ûð ûñ ûò ûô ûõ ûö û÷ ûø ûú ûû ûü ûý ûþ ü@ üA üB ++ üC üD üE üF üG üH üI üJ üK üL üM üN üP üQ üR üS ++ üT üU üV üW üX üY üZ ü[ ü\ ü] ü^ ü_ ü` üa üb üc ++ üd üe üf üg üh üi üj ük üm ün üo üp üq ür üs üt ++ üu üv üw üx üy üz ü{ ü| ü} ü~ ü¡ ü¢ ü£ ü¤ ü¥ ü¦ ++ ü§ ü¨ ü© üª ü« ü¬ ü­ ü® ü¯ ü° ü± ü² ü³ ü´ üµ ü¶ ++ ü· ü¸ üº ü» ü¼ ü½ ü¾ ü¿ üÀ üÁ ü üà üÄ üÅ üÆ üÇ ++ üÈ üÉ üÊ üË üÌ üÍ üÎ üÏ üÐ üÑ üÒ üÓ üÔ üÕ üÖ ü× ++ üØ üÙ üÚ üÛ üÜ üÝ üÞ üß üà üá üã üä üå üæ üç üè ++ üé üê üë üì üí üî üï üð üò üó üô üõ üö ü÷ üø üù ++ üú üû üü üý üþ ý@ ý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 ++ ý[ ý\ ý] ý^ ý_ ý` ý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 ++ ý{ ý| ý} ý~ ý¡ ý¢ ý£ ý¤ ý¥ ý¦ ý§ ý¨ ý© ýª ý« ý¬ ++ ý­ ý® ý¯ ý° ý± ý² ý³ ý´ ýµ ý¶ ý¹ ýº ý¼ ý½ ý¾ ý¿ ++ ýÀ ýÁ ý ýà ýÄ ýÅ ýÆ ýÇ ýÈ ýÉ ýÊ ýË ýÌ ýÍ ýÎ ýÏ ++ ýÐ ýÑ ýÒ ýÓ ýÔ ýÕ ýÖ ý× ýØ ýÙ ýÚ ýÛ ýÜ ýÝ ýÞ ýß ++ ýà ýá ýâ ýã ýä ýå ýæ ýç ýè ýé ýê ýë ýì ýí ýî ýï ++ ýð ýò ýó ýô ýõ ýö ý÷ ýø ýù ýú ýû ýü ýý ýþ þ@ þA ++ þB þC þD þE þF þG þH þI þJ þK þL þM þN þO þP þQ ++ þS þT þU þV þW þX þY þZ þ[ þ\ þ] þ^ þ_ þ` þa þb ++ þc þd þe þf þg þh þi þj þk þl þm þn þp þq þr þs ++ þt þu þv þw þx þy þz þ{ þ| þ} þ~ þ¡ þ¢ þ£ þ¤ þ¥ ++ þ¦ þ§ þ¨ þ© þ« þ¬ þ­ þ® þ¯ þ° þ± þ² þ³ þ´ þµ þ¶ ++ þ· þ¸ þ¹ þº þ» þ¼ þ½ þ¾ þ¿ þÀ þÁ þ þà þÄ þÅ þÆ ++ þÇ þÈ þÉ þÊ þË þÌ þÍ þÎ þÏ þÐ þÑ þÒ þÓ þÔ þÕ þÖ ++ þ× þØ þÙ þÚ þÛ þÜ þÞ þß þà þá þâ þã þä þå þæ þç ++ þè þé þê þë þì þí þî þï þð þñ þò þó þô þõ þö þ÷ ++ þø þù þú þû þü þý þþ +diff --git a/iconvdata/testdata/BIG5HKSCS..UTF8 b/iconvdata/testdata/BIG5HKSCS..UTF8 +index a3b5254..5fbde06 100644 +--- a/iconvdata/testdata/BIG5HKSCS..UTF8 ++++ b/iconvdata/testdata/BIG5HKSCS..UTF8 +@@ -1,1135 +1,1154 @@ +-           ïŒ ïŒŽ ïŒ ïŒ ïŒ‘  +-       Ä€ Ã Ç Ã€ Ä’ É Äš È ÅŒ Ó +- Ç‘ Ã’  Ế  Ề Ê Ä Ã¡ ÇŽ à É‘ Ä“ é Ä› è +- Ä« í Ç Ã¬ Šó Ç’ ò Å« ú Ç” ù Ç– ǘ Çš Çœ +- ü ï„ áº¿ ï† á» Ãª É¡ ïŠ ï‹ ðªŽ©  攊 丽 æ» éµŽ 釟 +- 𧜵 æ’‘ 会 伨 侨 å…– å…´ 农 凤 务 动 医 åŽ å‘ å˜ å›¢ +- 声 处 备 夲 头 å­¦ 实 実 岚 庆 总 æ–‰ 柾 æ „ æ¡¥ 济 +- 炼 电 纤 纬 纺 织 ç» ç»Ÿ 缆 ç¼· 艺 è‹ è¯ è§† 设 询 +- 车 轧 è½® ç‘ ç³¼ ç· æ¥† 竉 刧 醌 碸 é…ž 肼 è´‹ 胶 ï° +- è‚Ÿ 黇 ä³ é·‰ 鸌 ä°¾ ï¹ ð§€Ž 鸊 ï¼ ã— æºš 舾 ç”™ 䤑 马 +- éª é¾™ 禇 ïˆ ð¡·Š ð — ï‹ ä¸¤ äº äº€ 亇 亿 仫 ä¼· ã‘Œ ä¾½ +- 㹈 倃 傈 㑽 ã’“ ã’¥ 円 夅 凛 凼 刅 争 剹 åŠ åŒ§ ã—‡ +- 厩 ã•‘ 厰 ã•“ å‚ å£ ã•­ 㕲 ãš å’“ å’£ å’´ å’¹ å“ å“¯ 唘 +- 唣 唨 ã–˜ 唿 ã–¥ ã–¿ å—— ã—… ï½ å”¥ 𠱂 ï‘ ï‘‚ å– ð¢³† 㧬 +- ð  蹆 𤶸  ä“ ð¨‚¾ çº ï‘ ã¨´ 䟕 ï‘ ð¦§² 𤷪 æ“ ï‘” ð ¾´ +- 𠳕 𡃴 æ’ è¹¾ ï‘š ï‘› ï‘œ ï‘ ð¨‰– 𤓓 𠵆 ï‘¢ 𨃩 䟴 ï‘¥  +- 骲 㩧 ï‘© ã¿­ 㔆 𥋇 ï‘­ ï‘®  éµ® é • ä™ ð¦‚¥ æ’´ å“£ ï‘· +-  𡷠㧻 𡯠   擪 ï’€ 𠱃 蹨 𢆡 𨭌 ï’… ä ‹ ï’ˆ +- 㿺 塳 ï’‹ ï’ ð “¼ ï’ ï’ ï’‘ 啹 ä‚» 䎺 䪴 ï’— ï’˜ 膪 飵 +- ï’› æ¹ ã§¾ 𢵠跀 åš¡ 摼 㹃 ï’¤ 𠸉 𢫠 𡃈 ï’ª 㦒 㨆 +- ï’­ 㕸 ï’¯ 𢃇 å™’ ð ¼± ï’³ ï’´ ã’¼ æ°½ ï’· ï’º ï’» ï’¼ ï’½ 𨳠+- 𠹺 ï“€ ï“ ç¾“  𢠃 𢤹 ã—» 𥇣  𠾠𠺪 㾓 ð ¼° 𠵇 ï“Ž +- ï“ ð º« ï“’ 𠵈 𡃀 ð¡„½ 㿹 𢚖 æ² ð ¾­ 𣴠𧘹 𢯎 ð µ¾ 𠵿 𢱑 +- 𢱕 㨘 ï“¢ 𡃇 ð ¼® ï“¥ 𦭠  ï“© é–ª å“Œ è‹„ å–¹ 𩻃 é°¦ +- 骶 𧞠 ç…€ è…­ 胬 å°œ 𦕲 è„´ ãž— åŸ ð¨‚½ 醶 𠻺 ð ¸ ð ¹· +- ð »» 㗠𤷫 㘉 ð ³– 嚯 𢞵 𡃉 𠸠𠹸 𡸠𡅈 𨈇 ð¡‘• ð ¹¹ 𤹠+- 𢶤 å©” 𡀠𡀞 𡃵 𡃶 åžœ 𠸑 𧚔 𨋠𠾵 ð ¹» 𥅾 㜃 𠾶 𡆀 +- 𥋘   ð¡ º   墙 剨 㘚  箲 å­¨ ä € 䬬 鼧 䧧 +- é°Ÿ é® ð¥­´ 𣄽 å—» ã—² 嚉 丨 夂  ï”» é‘ ï”½ ä¹› 亻 㔾 +- å°£ 彑 å¿„ 㣺 扌 攵 æ­º æ°µ æ°º ç¬ çˆ« 丬 犭 ï•Ž ç½’ 礻 +- ç³¹ 罓 ï•“ ã“ ï•– 耂 è‚€ ï•™ ï•š å 衤 è§ ï•ž è®  è´ é’… +- 镸 é•¿ é—¨ ï•¥ 韦 页 风 飞 饣 ï•« é±¼ 鸟 黄 æ­¯ 丷  +- é˜ æˆ· é’¢ å´¾ 嵈 åµ– ã·¼ ã  å¶¤ 嶹 ã   ã ¸ 幂 庽 å¼¥ 徃 +- 㤈 㤔 㤿 㥠惗 愽 å³¥ 㦉 憷 憹 æ‡ ã¦¸ 戬 æŠ æ‹¥ 挘 +- 㧸 åš± 㨃 æ¢ æ» æ‡ æ‘š ã©‹ æ“€ å´• 嘡 龟 㪗 æ–† 㪽 æ—¿ +- 晓 㫲 æš’ 㬢 朖 ã­‚ 枤 æ € ã­˜ æ¡Š 梄 ã­² ã­± ã­» 椉 楃 +- 牜 楤 榟 榅 㮼 槖 㯠橥 æ©´ 橱 檂 㯬 檙 㯲 檫 檵 +- æ«” 櫶 æ® æ¯ æ¯ª æ±µ 沪 㳋 æ´‚ æ´† æ´¦ æ¶ ã³¯ 涤 涱 渕 +- 渘 温 溆 𨧀 溻 滢 滚 齿 滨 滩 漤 æ¼´ 㵆 ð£½ æ¾ æ¾¾ +- 㵪 ãµµ 熷 å²™ 㶊 瀬 㶑 ç ç” ç¯ ç¿ ç‚‰ 𠌥 ä ã—± ïš° +-  åž¾ 𦻓 焾 𥟠 㙎 榢 𨯩 å­´ 穉 𥣡 ð©“™ ç©¥ 穽 𥦬 窻 +- 窰 ç«‚ 竃 燑  䇊 ç«š ç« ç«ª 䇯 å’² 𥰠笋 ç­• 笩  +- 𥳾 箢 ç­¯ 莜 𥮴 𦱿 ç¯ è¡ ç®’ 𣿰 㶭 𥱥 è’’ 篺 ç°µ 𥳠+- 籄 粃 î… ç²¦ 晽 𤕸 糉 糇 糦 ç±´ ç³³ ç³µ 繧 ä” ð¦¹„ çµ +- 𦻖 ç’ ç¶‰ 綫 焵 綳 𤗠𦀩 ç·¤ ã´“ ç·µ 𡟹 ç·¥ î¢ ð¦„¡ 𦅚 +- ç¹® 纒 䌫 鑬 縧 ç½€ ç½ ç½‡ 礶 𦋠駡 ç¾— 𦑠羣 ð¡™¡ ð ¨ +- ä•œ 𣦠䔃 𨌺 翺 𦒉 耈 è€ è€¯ îŽ îŽ‚ 耻 耼 è¡ îŽ† 䦉 +- 𦘦  𦛨 朥 肧 𨩈 脇 è„š 墰 𢛶 汿 𦒘  擧  舘 +- ð¡¡ž æ©“ 𤩥 𤪕 䑺 舩  𦩒  俹 ð¡“½ è“¢ è¢ ð¦¬Š 𤦧 𣔰 +- 𡳠𣷸 芪 椛 芳 䇛 è•‹ è‹ èŒš ð ¸– ð¡ž´ 㛠 𣕚 艻 è‹¢ +- 茘 𣺋 𦶣  𦮗 𣗎 㶿 èŒ å—¬ 莅 䔋 𦶥 莬 è“ ã‘¾ 𦻔 +- æ©— è•š ã’– 𦹂 î 葘 î 葱 ã·“ 䓤 檧 è‘Š î• ç¥˜ 𦮖 𦹷 +- 𦹃 è“ž 莑 ä’  è’“ 蓤 î¡ ä‰€ 𥳀 䕃 è”´ 嫲 î§ ä”§ 蕳 ä”– +- æž¿ 蘖 𨘥 𨘻 è— î° è˜‚ î² ð§ƒ î´ ä•ª 蘨 㙈 ð¡¢¢ å· ð§Žš +- 虾 è± ðªƒ¸ 蟮 𢰧 èž± 蟚 è  å™¡ 虬 æ¡– ä˜ è¡… 衆 𧗠 𣶹 +- 𧗤 è¡ž 袜 ä™› 袴 袵 æ 装 ç· ð§œ è¦‡ 覊 覧 覼 𨨥 觧 +- 𧤤 𧪽 誜 çž“ 釾 èª ð§©™ ç«© 𧬺 î¦ äœ“ 𧬸 ç…¼ 謌 謟 𥰠+- 𥕥 謿 è­Œ è­ èª© 𤩺 è® è®› 誯 î¶ ä˜• è¡ è²› 𧵔 𧶠貫 +- 㜥 𧵓 è³– 𧶘 𧶽 è´’ è´ƒ 𡤠賛 çœ è´‘  㻠趩 𨀂 î‘ +- 𤦊 ã­¼ î‘ ð§„Œ 竧 躭 躶 軃 é‹” è¼™ è¼­ 𨥠𨒠辥 錃 𪊟 +- ð © è¾³ 䤪 𨧞 𨔽 𣶻 廸 𣉢 迹   î‘© 𢌥 㦀 𦻗 逷 +- 𨔼 𧪾 é¡ ð¨•¬ 𨘋 邨 î‘´ 郄 𨛦 é‚® é…§ ã«° 醩 釄 粬 𨤳 +- 𡺉 鈎 沟 é‰ é‰¢ 𥖹 𨫆 𣲛 𨬌 𥗛 î’Š 錬 é« ð¨«¡ 𨯫 ç‚ +- 嫃 𨫢 𨫥 䥥 鉄 𨯬 𨰹 𨯿 é³ é‘› 躼 é–… é–¦ é¦ é–  濶 +- 䊹 î’¡ 𨛘 𡉼 𣸮 䧟 æ°œ é™» éš– ä…¬ 隣 𦻕 懚 隶 磵 𨫠 +- éš½ åŒ ä¦¡ 𦲸 ð ‰´ ð¦ 𩂯 𩃥 𤫑 𡤕 𣌊 霱 虂 霶 ä¨ ä”½ +- ä–… î“ çµ å­ éœ›  é— å­Š 𩇫 éŸ é¥ åƒ ð£‚· 𣂼 鞉 鞟 +- éž± éž¾ 韀 韒 韠 𥑬 韮 çœ ð©³ éŸµ ð© î“ ä«‘ é ´ é ³ é¡‹ +- 顦 㬎 𧅵 㵑 ð ˜° 𤅜 𥜆 飊 颷 飈 飇 ä«¿ 𦴧 ð¡›“ å–° 飡 +- 飦 飬 é¸ é¤¹ 𤨩 ä­² ð©¡— 𩤅 駵 騌 騻 é¨ é©˜ 𥜥 㛄 ð©‚± +- 𩯕 é«  é«¢ 𩬅 é«´ ä°Ž 鬔 鬭 𨘀 倴 鬴 𦦨 㣃 ð£½ é­ é­€ +- ð©´¾ å©… ð¡¡£ 鮎 𤉋 é°‚ 鯿 é°Œ 𩹨 é·” 𩾷 𪆒  𪃡 𪄣 𪇟 +- éµ¾ 鶃  鸎 梈 é·„  𪆓 𪈠 𡤻 𪈳 é´¹ î”®  éº éº• +- 麞 麢 ä´´ 麪 麯 ð¤¤ é» ã­  㧥 ã´ ä¼² ãž¾ 𨰫 鼂 鼈 ä®– +- é¤ ð¦¶¢ é¼— é¼¹ 嚟 嚊 é½… 馸 ð©‚‹ 韲 è‘¿ é½¢ 齩 ç«œ 龎 爖 +- 䮾 𤥵 𤦻 ç…· 𤧸 𤈠𤩑 玞 𨯚 𡣺 禟 𨥾 𨸶 é© é³ ð¨©„ +- 鋬 éŽ é‹ ð¨¥¬ 𤒹 爗 㻫 ç² ç©ƒ çƒ î•­ 𤸠煾 î•° ç‚£ ð¡¢¾ +- 𣖙 㻇 ð¡¢… 𥯠𡟸 㜢 ð¡›»  㛡 𡴠 𥽋 㜣 𡛀 å› ð¤¨¥ +- 𡾠 𡆠𡒶 蔃 𣚦 è‘• î–‹ 𧅥 𣸱 𥕜 𣻻 𧒠䓴 𣛮 𩦠+- 𦼦 柹 㜳 ã°• ã·§ 塬 î–š æ  ä— ð£œ¿ î–ž 𤂋 î–  𦰡 å“‹ åšž +- 𦚱 åš’ î–¦ 𠮨 ð ¸ é† î–ª 鎜 仸 å„« ã ™ 𤶠亼 ð ‘¥ 𠿠佋 +- 侊 𥙑 婨 𠆫 𠋠㦙 𠌊 𠔠㵠伩 ð ‹€ 𨺳 𠉵 è«š î—‚ 亘 +- åƒ å„ ä¾¢ 伃 î—ˆ 𣺊 佂 倮 å¬ å‚ ä¿Œ ä¿¥ å˜ åƒ¼ 湶 𣖕 +- î—˜ 𣺿 æµ² 𡢄 𣺉 冨 凃 ð —  ä“ ð ’£ ð ’’ ð ’‘ 赺 𨪜 𠜎 剙 +- 劤 ð ¡³ å‹¡ 䙺 熌 𤎌 ð °  𤦬 î—± 槑 𠸠㻞 ç’™ ç” ç‘– 玘 +- 䮎 𤪼 𤂠å ã–„ çˆ ð¤ƒ‰ å–´ ð … å“ ð ¯† åœ é‰ é›´ é¦ åŸ +- åž å¿ ã˜¾ 壋 媙 𨩆 𡛺 𡯠𡜠娬 妸 éŠ å©¾ å« å¨’  +- 𡧳 ð¡¡¡  㛵 æ´… 瑃 娡 𥺃 åª ð¨¯— ð “ é  ç’Œ 𡌃 ç„… 䥲 +- éˆ ð¨§» 鎽 ãž  å°ž 岞 幞 幈 𡦖 ð¡¥¼ 𣫮 å» å­ ð¡¤ƒ 𡤄 㜠+- ð¡¢  ã› ð¡›¾ 㛓 脪 𨩇 𡶺 𣑲 𨦨 弌 弎 𡤧  å©« 𡜻 å­„ +- 蘔 𧗽 è¡  æ¾ ð¢¡  𢘫 å¿› 㺸 𢖯 𢖾 î™” 𦽳 懀 ð €¾ 𠆠𢘛 +- 憙 憘 æµ ð¢²› 𢴇 𤛔 î™  摱 𤙥 𢭪 㨩 𢬢 𣑠𩣪 𢹸 挷 +-  æ’¶ 挱 æ‘ ð¤§£ 𢵧 护 𢲡 æ» æ•« 楲 㯴 𣂎 𣊭 𤦉 𣊫 +- å” ð£‹  ð¡£™  曎 𣊉  ã«  ä† ð¥–„ 𨬢 𥖠𡛼 𥕛 𥥠磮 +- 𣄃 ð¡ ª 𣈴 㑤  𣆂 𤋉 暎 𦴤 晫 䮓 昰 𧡰 îš— 晣 𣋒 +- 𣋡 昞 𥡲 㣑 îšž 𣞼 ã®™ 𣞢 ð£¾ ç“ ã®– æž ð¤˜ª 梶 æ ž 㯄 +- 檾 ã¡£ 𣟕 𤒇 樳 æ©’ 櫉 欅 𡤒 攑 梘 æ©Œ 㯗 橺 æ­— 𣿀 +- 𣲚 鎠 鋲 𨯪 𨫋 銉  𨧜 鑧 涥 漋 î›… 𣽿 㶠渄 𤀼 +- 娽 渊 塇 æ´¤ ç¡‚ ç„» 𤌚 𤉶 烱 ç‰ çŠ‡ 犔 𤞠𤜥 å…¹ 𤪤 +- ð —« 瑺 𣻸   𤤗 𥿡 㼆 㺱 𤫟 𨰣 𣼵 悧 㻳 ç“Œ ç¼ +- 鎇 ç· ä’Ÿ 𦷪 ä•‘ ç–ƒ ã½£ 𤳙 𤴆 㽘 ç•• 癳 𪗆 㬙 瑨 𨫌 +- 𤦫 𤦎 ã«» 㷠𤩎 㻿 îœ ð¤£³ 釺 圲 é‚ ð¨«£ 𡡤 僟 𥈡 𥇧 +- ç¸ ð£ˆ² 眎 çœ ç» ð¤š— 𣞠㩞  ç¸ ç’› 㺿 𤪺 𤫇 䃈 𤪖 +- 𦆮 錇 𥖠砞 ç¢ ç¢ˆ 磒 ç 祙 ð§  ä„Ž è’– 禥 樭 𣻺 +- 稺 秴 ä…® 𡛦 䄲 鈵 秱 𠵌 𤦌 ð Š™ 𣶺 ð¡® ã–— å•« ã•° 㚪 +- 𠇔  ç«¢ å©™ 𢛵 î 𥪜 å¨ ð ‰› 磰 娪 𥯆 竾 䇹 ç± ç±­ +- 䈑 𥮳 𥺼 𥺦 ç³ ð¤§¹ î’ ç²Ž ç±¼ ç²® 檲 ç·œ 縇 ç·“ 罎 𦉡 +- 𦅜 î 綗 𥺂 䉪 î¡ ð ¤– 柖 𠎠𣗠埄 ð¦’ î¨ ð¤¥¢ ç¿ ç¬§ +- ð  ¬ 𥫩 𥵃 笌 𥸎 駦 è™… é©£ 樜 îµ ã§¢ 𤧷 𦖭 騟 îº è’€ +- 𧄧 î½ ä“ª è„· ä‚ èƒ† 脉 è…‚ 𦞴 飃 𦩂 艢 艥 𦩑 è‘“ 𦶧 +- è˜ ð§ˆ› 媆 ä…¿ îž å¬« 𡢡 嫤 𡣘 èš  îž— è ­ 𧢠娂 è¡® +- ä½… 袇 袿 裦 襥 è¥ ð¥šƒ 襔 𧞅 𧞄  𨯙 𨮜 𨧹 㺭 è’£ +- 䛵 ä› ãŸ² 訽 訜 𩑈 å½ éˆ« îž´ æ—” ç„© 烄 ð¡¡… éµ­ 貟 賩 +- 𧷜 妚 矃 姰 ä® ã›” 踪 躧 𤰉 è¼° 轊 ä‹´ 汘 æ¾» 𢌡 䢛 +- æ½¹ 溋 ð¡Ÿš 鯩 ãšµ 𤤯 é‚» 啱 䤆 醻 é„ ð¨©‹ ä¢ îŸš é§ ð¨° +- îŸ è“¥ 訫 é–™ é–§ é–— é–– 𨴴 ç‘… 㻂 𤣿   㻧 𣈥 éš +-  𨹦 𨹥 㻌  𤩸 𣿮 ç’ ç‘« 㻼 é ð©‚° 桇 ä¨ îŸ»  +- é¨ ð¨¦‰ î € 𨬯 𦎾 銺 嬑 è­© 䤼 ç¹ ð¤ˆ› éž› é± é¤¸ î Œ å· +- 𨯅 𤪲 é Ÿ ð©“š 鋶 î “ 釥 ä“€ 𨭠𤩧 𨭤 飜 𨩅 ã¼€ 鈪 䤥 +- è” é¤» é¥ î ¡ ã·½ 馛 ä­¯ 馪 é©œ 𨭥 î ¨ æª é¨¡ 嫾 騯 î ­ +- ä® î ¯ 馼 䮽 ä®— é½ å¡² 𡌂 å ¢ 𤦸 𡓨 ç¡„ 𢜟 𣶸 棅 ãµ½ +- 鑘 㤧 æ… ð¢ž ð¢¥« 愇 é± é±“ é±» é°µ é° é­¿ é¯ ð©¸­ 鮟 î¡ +- 𪃾 é´¡ ä²® 𤄄 鸘 ä²° é´Œ î¡• î¡– 𪃳 𩤯 鶥 è’½ î¡› 𦿟 î¡ +- è—¼ 䔳 𦶤 𦺄 𦷰 è  è—® î¡¥ 𣟗 𦤠秢 𣖜 𣙀 䤭 𤧞 ãµ¢ +- é› éŠ¾ éˆ ð Š¿ 碹 鉷 é‘ ä¿¤ ã‘€ é¤ ð¥• ç ½ ç¡” 碶 ç¡‹ ð¡— +- 𣇉 𤥠㚚 ä½² æ¿š æ¿™ 瀞 å” î¢‡ åž» 壳 垊 é´– 埗 ç„´ ã’¯ +- î¢ ç‡«  𤾗 ð¡žµ 𨩉 æ„Œ å«Ž 娋 䊼 𤒈 㜬 ä­» 𨧼 鎻 鎸 +- ð¡£–  葲 𦳀  𤋺 𢰦 ð¤ 妔 𣶷 ð¦ 綨 𦅛 𦂤 𤦹 𤦋 +- 𨧺 é‹¥ ç¢ ã»© ç’´ 𨭣 𡢟 㻡 𤪳 櫘 ç³ ç» ã»– 𤨾 𤪔 ð¡Ÿ™ +- 𤩦 𠎧   瑈 𤤖 ç‚¥ 𤥶 銄 ç¦ éŸ ð “¾ 錱 î£ ð¨¨– 鎆 +- 𨯧 𥗕 䤵 𨪂 ç…«   嚤 𠘚   唂 秄 𡟺 ç·¾ ð¡›‚ +- 𤩠 ä”® é 㜊  𤦭 妰 𡢿 𡢃 𧒄 媡 㛢 𣵛 ãš° 鉟 +- 婹 𨪠𡡢 é´ ã³ ð ª´ 䪖 㦊 僴 㵩 㵌 ð¡Žœ ç…µ ä‹»  æ¸ +- 𩃤 ä“« æµ— ð§¹ ç§ æ²¯ ã³– 𣿭 𣸭 渂 漌 㵯 ð µ ç•‘ ãš¼ 㓈 +- 䚀 㻚 䡱 姄 鉮 䤾 è½ î¤—  å ’ 埈 ã›– ð¡‘’ 烾 𤢠 +- 𢿣 ð¡Š° 𢎽 梹 楧  𣓥 𧯴 𣛟 𨪃 𣟖  𤲟 樚 𣚭 𦲷 +- è¾ ä“Ÿ ä“Ž 𦴦  𦲂 𦿞 æ¼— 𧄉 茽 𡜺 è­ ð¦²€ 𧓠𡟛 妉 +- 媂 ð¡ž³ å©¡ 婱 𡤅 𤇼 㜭 姯 𡜼 㛇 熎 éŽ æšš 𤊥 å©® 娫 +- î¥ æ¨« 𣻹 𧜶 𤑛 𤋊 ç„ ð¤‰™ 𨧡 ä¾° 𦴨 峂 𤓎 𧹠𤎽 樌 +- 𤉖 𡌄 炦 焳 𤩠㶥 泟  𤩠繥 姫 å´¯ ã·³ 彜   +- 綤 è¦ å’…  𣌀 𠈔 å¾ î¥· 𠘙 ã¿¥   瀃  åµ° çŽ +- 糓 𨩙  俈 翧 ç‹ çŒ ð§«´ 猸 猹 𥛶 ç çˆ ãº© 𧬘 é¬ +- 燵  ç¡ è‡¶ 㻊 県 㻑 æ²¢ 国 ç™ çž çŸ ã»¢ ã»° ã»´ 㻺 +- ç““ 㼎 㽓 ç•‚ ç•­ 畲 ç– ã½¼ ç—ˆ ç—œ ã¿€ ç™ ã¿— ç™´ ã¿œ 発 +- 𤽜 熈 嘣 覀 å¡© ä€ çƒ ä€¹ æ¡ ä… ã—› 瞘 äª ä¯ å±ž çž¾ +- 矋 売 ç ˜ 点 ç œ 䂨 ç ¹ 硇 ç¡‘ 硦 葈  礳 æ ƒ 礲 䄃 +- 䄉 禑 禙 è¾» 稆 è¾¼ ä…§ 窑 䆲 窼 艹 䇄 ç« ç«› ä‡ ä¸¡ +- ç­¢ ç­¬ ç­» ç°’ ç°› 䉠 䉺 ç±» 粜 䊌 粸 䊔 ç³­ 输 烀 ð ³ +- ç· ç·” ç· ç·½ ç¾® ç¾´ 犟 䎗 耠 耥 笹 耮 耱 è” ã·Œ åž´ +- ç‚  è‚· 胩 ä­ è„Œ 猪 è„Ž è„’ ç•  è„” ä 㬹 è…– è…™ è…š ä“ +- å º è…¼ 膄 ä¥ è†“ ä­ è†¥ 埯 è‡ è‡¤ 艔 ä’ èŠ¦ 艶 è‹Š 苘 +- è‹¿ ä’° è— é™© 榊 è… çƒµ 葤 惣 è’ˆ 䔄 è’¾ è“¡ 蓸 è” è”¸ +- è•’ ä”» 蕯 è•° è—  ä•· 虲 èš’ èš² 蛯 é™… èž‹ 䘆 䘗 袮 裿 +- 褤 襇 覑 𧥧 訩 訸 誔 誴 豑 è³” è³² è´œ 䞘 å¡Ÿ è·ƒ 䟭 +- ä»® 踺 å—˜ å” è¹± å—µ 躰 ä · 軎 転 軤 è»­ 軲 è¾· è¿ è¿Š +- è¿Œ 逳 駄 䢭 飠 鈓 䤞 鈨 鉘 鉫 銱 銮 銿 é‹£ é‹« 鋳 +- é‹´ 鋽 éƒ éŽ„ 鎭 䥅 䥑 麿 é— åŒ é é­ é¾ ä¥ª é‘” 鑹 +- é”­ é–¢ 䦧 é—´ 阳 䧥 æž  䨤 é€ ä¨µ éž² 韂 å™” 䫤 惨 颹 +- 䬙 飱 å¡„ 餎 餙 冴 餜 餷 饂 é¥ é¥¢ ä­° 駅 ä® é¨¼ é¬ +- 窃 é­© é® é¯ é¯± 鯴 ä±­ é°  㯠 鵉 é°º 黾 å™ é¶“ 鶽 +- é·€ é·¼ 银 辶 é¹» 麬 麱 麽 黆 é“œ 黢 é»± 黸 竈 齄  +- î«€ î« æ¤š 铃 妬 î«… å¡€ é“ ãž¹  î«Š î«‹ î«Œ å— ç…³ î« +- î« î«‘ 呪 î«“ î«” å’ž î«– î«— 𠱓 î«™ î«š 惧 î«œ 噺 î«ž î«Ÿ +- î«  î«¡ î«¢ î«£ 楕 é°¯ 螥  𠸎 î«©  ð ¼­  å°  î«® 帋 +- î«°  𡶠朞 𡻠  㙇    î«» å¤ è’­ ð¡‹£ î«¿ +-  è® î¬‚    乸 ç‚»      î¬ î¬Ž î¬ +- 拃 ð¡»•  熘 æ¡•  槩 㛈 𢉼     î¬ è‹½  +-  𢫕 覥  è¾   鞸  顇 骽     𢴈  +-          å¾± 晈 æš¿    𤦺 +- î­ƒ î­„ 𠆠墵 朎 椘 î­Š 𧙗 𥿢 î­ î­Ž 𧗾 𢂚 ä£ äª¸ î­“ +- 𨪚 î­• î­– 𤀻 î­˜ 𤎖 î­š î­› 凒 𠘑 妟 𡺨 㮾 𣳿 î­¢ î­£ +- 垈 î­¥ 㦛 î­§ î­¨ î­© 㢠𢇃 è­ž 𨭎 î­¯ î­° î­± 爉 î­³ 𠱸 +- 奥 î­¶ î­· 𠹠軚 î­º åŠ åœ¿ ç…± î­¾ î­¿  𤪧 å–¼  𥑮 +- 𦭒 㑳  𧘲  䜘  𥕦 𥟇 𤤿 î® å¦ ã“»   ä¼ +- 𨥈 𥪮 î®™ 𥰆 î®› åž¡ ç…‘  𧰒 é– î®¢ 𤾚 è­¢   åµ› +- 𦯷   諪 𤧶 î®® 𣿯 𦔒 䯀   𢜛 é‘¥ 𥟡 憕 娧 +- 枅嚹 𤔡  乪  é™– æ¶ ð¦²½ 㘘 襷  𦡮 𦑠𦡞  +- ç­‚  𠨑  î¯ ç©… 𦧺 騦  㙟   禃   å´¬ +- î¯ î¯Ÿ ä› î¯¡ ç”» è¡¥  墶 㜜 𢖠  ã±”   éŠ +- 𢅺  錰 𧋦  æ°¹ é’Ÿ  𠻸 è § 裵   ð¡ž± 溸 𤨪 +-  㦤 ãš¹ 䔿 暶 𩲭 𩢤 襃 î°ˆ î°‰ å›– 䃟 𡘊 㦡 𣜯 î° +- 𡅠熭 è¦ î°“ 𩆨 ä²· 𧂯 𨦫 î°™ î°š î°› î°œ 𤅺 ç­ƒ 祾 𨀉 +- æ¾µ 𪋟 樃 î°¤ 厢 î°¦ 鎿 æ ¶ é 𨅯 î°« 𦦵 𡭠𣈯 î°¯ 嶅 +- 𨰰 î°² 圕 é £ 𨥉 嶫 𤦈 æ–¾ 槕 å’ ð¤ª¥ 𣾠㰑 朶 î°¿ 𨃴 +- 𨄮 𡾡   î±…     ã—Š  𨚪 䣺 æ¦ î± ç ˆ +- 鉕 î±’ ä² î±” äŸ î±– î±—  姸   î± ð©„ î±  ã·· î±¢ +- î±£ è¿ çŠ åš‹  ð©—©     î±­ 𩥪  î±° 𩬎 î±² +- î±³ 纟 î±µ 𩼣 䲤 镇 î±¹ 熢 î±» 䶑 递 î±¾ 䶜 𠲜 è¾¾ å— +- 辺  è¾¹ 𤪓 䔉 繿 æ½– 檱 仪 㓤 𨬬  㜺 躀 𡟵 î²’ +- 𨭬 𨮙  𦚯 ã·« 𧙕 𣲷 𥘵 𥥖 亚 𥺠𦉘 åš¿ ð ¹­ 踎 å­­ +- 𣺈 𤲞 æž ð¡Ÿ¶ ð¡¡» æ”° 嘭 𥱊 åš ð¥Œ‘ ã·†  ä±½ 嘢 嘞 罉 +- 𥻘 奵  è° ä¸œ 𠿪 𠵉 𣚺 è„— 鵞 è´˜ 瘻 é±… 癎 çž¹ é… +- å² è…ˆ è‹· 嘥 脲 è˜ è‚½ å—ª 祢 噃 å– î³ ã—Ž 嘅 å—± æ›± +- 𨋢 㘭 ç”´ å—° å–º å’— 啲 𠱠 å» ð¥…ˆ 𠹶 î³   麫 絚 +- å—ž ð¡µ æŠ é­ å’” è³ ç‡¶ é…¶ æ¼ æŽ¹ æ¾ å•© î³° é±² î³² 冚 +- ã“Ÿ 𠶧 冧 å‘ å”ž 唓 癦 踭 î³¼ ç–± 肶 è „ 螆 裇 膶 èœ +- 𡃠䓬 猄 𤜆 å® èŒ‹ 𦢓 å™» 𢛴 𧴯 𤆣 𧵳 𦻠 é…° 𡇙 +- 鈈 𣳼 𪚩 𠺬 ð »¹ 牦 𡲢 äŽ ð¤¿‚ î´ ð ¿« 䃺 é± æ”Ÿ 𢶠 䣳 +- î´¤ 𩵼 𠿬 𠸊 î´© ð ¿­ î´¬ 𡆇 熣 纎 éµ ä¸š 丄 ã•· å¬ æ²² +- å§ ãš¬ 㧜 å½ ãš¥ î´» 墚 𤭮 舭 å‘‹ 垪 îµ ð ¥¹ ã©’ 𢑥 ç´ +- 𩺬 ä´‰ 鯭 𣳾 𩼰 ä±› 𤾩 ð©–ž îµ è‘œ 𣶶 îµ’ 𦞳 𣜠 挮 ç´¥ +- 𣻷 𣸬 㨪 逈 å‹Œ ã¹´ 㙺 ä—©  癀 å«° 𠺶 硺 䞶 墧 ä‚¿ +- 噼 鮋 åµ´ ç™”  麅 䳡 㟻 æ„™ 𣃚 ð¤² å™ ð¡Š© 垧 𤥣  +- 刴 𧂮 ã–­ éµ¼ ç±– 鬹 埞 𡬠屓 æ““   𧅤 èš­  𦴢 +- 𤫢  凾  嶎 霃 ð¡·‘ éº éŒ ç¬Ÿ 鬂 峑 箣 扨 挵 é«¿ +- ç¯ é¬ª ç±¾ 籂 粆 é°• 篼 鬉 é°› 𤤾 齚 啳 寃 俽 麘 俲 +- 剠 㸆 å‹‘ å§ å– å¦· 帒 韈 鶫 轜 å‘© éž´ 饀 鞺 匬 æ„° +- 椬 åš é°Š é´‚ ä°» é™ æ¦€ 傦 畆 𡭠駚 剳 é…™ éš é…œ é…‘ +- î· æ¿ ð¦´£ æ«Š 嘑 醎 畺 抅 ð ¼ ç ç±° î·š 𣳽 𤤙 ç›– é® +- 个 ð ³” 莾 è¡‚ 届 槀 åº åˆŸ å·µ 从 æ°± î·­ ä¼¹ å’œ å“š 劚 +- 趂 ã—¾ ã—³ æ­’ é…¼ é¾¥ é®— é ® 颴 骺 麨 麄 ç…º 笔 毺 è ˜ +- 罸 嘠  è¹· 齓 è·” è¹ é¸œ è¸ æŠ‚ 𨽠踨 è¹µ ç«“ 𤩷 稾 +- 磘 泪 詧 瘇 𨩚 鼦 泎 蟖 ç—ƒ 𪊲 ç¡“ 咢 è´Œ ç‹¢ ç± è¬­ +- 猂 瓱 賫 𤪻 蘯 徺 袠 ä’· ð¡ » 𦸅 詾 𢔛 惽 癧 é«— 鵄 +- é® é® èŸµ è³· 猬 霡 é®° ã—– 犲 ä°‡ 籑 饊 𦅙 æ…™ ä°„ 麖 +- æ…½ åŸ æ…¯ 抦 戹 ã©œ 懢 厪 ð£µ æ¤ æ ‚ ã—’ åµ— 𨯂 è¿š î¹ +- 僙 𡵆 礆 匲 阸 ð ¼» ä¥ çŸ¾ 糂  糚 稭 è¦ è£ çµ ç”… +- 瓲 覔 舚 朌 è¢ ð§’† è› ç“° 脃 眤 覉 𦟌 ç•“ 𦻑 èž© 蟎 +- 臈 螌 詉 è²­ è­ƒ 眫 瓸 è“š 㘵 榲 趦 覩 涹 èŸ ð¤€‘ 瓧 +- ã·› ç…¶ 悤 憜 㳑 æ· ç½± 𨬭 惩 ä­¾ 删 ã°˜ 𣳇 𥻗 𧙖  +- 𡥄 ð¡‹¾ 𩤃 𦷜 𧂭 å³ ð¦†­ 𨨠𣙷 𠃮  𤼎 ä•¢ 嬟  é½ +- 麦    , 〠。 . • ï¼› : ? ï¼ ï¸° … ‥ ï¹ +- 、 ï¹’ · ï¹” ﹕ ï¹– ï¹— | – ︱ — ︳ ︴ ï¹ ï¼ˆ ) +- ︵ ︶ ï½› ï½ ï¸· ︸ 〔 〕 ︹ ︺ 〠】 ︻ ︼ 《 》 +- ︽ ︾ 〈 〉 ︿ ï¹€ 「 ã€ ï¹ ï¹‚ 『 〠﹃ ﹄ ï¹™ ﹚ +- ï¹› ﹜ ï¹ ï¹ž ‘ ’ “ †〠〞 ‵ ′ # & * ※ +- § 〃 â—‹ â— â–³ â–² â—Ž ☆ ★ â—‡ â—† â–¡ â–  â–½ â–¼ ㊣ +- â„… ‾ _ ﹉ ﹊ ï¹ ï¹Ž ﹋ ﹌ ﹟ ï¹  ﹡ + ï¼ Ã— ÷ +- ± √ < > ï¼ â‰¦ ≧ ≠ ∞ ≒ ≡ ï¹¢ ï¹£ ﹤ ï¹¥ ﹦ +- ∼ ∩ ∪ ⊥ ∠ ∟ ⊿ 㒠㑠∫ ∮ ∵ ∴ ♀ ♂ â™ +- ☉ ↑ ↓ ↠→ ↖ ↗ ↙ ↘ ∥ ∣ ï¼ ï¼¼ $ Â¥ 〒 +- ¢ £ ï¼… ï¼  ℃ ℉ ﹩ ﹪ ﹫ 㕠㎜ ㎠㎞ ㎠㎡ ㎎ +- ㎠ㄠ° å…™ å…› å…ž å… å…¡ å…£ å—§ ç“© 糎 â– â–‚ â–ƒ â–„ +- â–… â–† â–‡ â–ˆ â– â–Ž â– â–Œ â–‹ â–Š â–‰ ┼ â”´ ┬ ┤ ├ +- â–” ─ │ â–• ┌ â” â”” ┘ â—¢ â—£ â—¥ â—¤ ╱ ╲ ╳ ï¼ +- 1 ï¼’ 3 ï¼” 5 ï¼– ï¼— 8 ï¼™ â…  â…¡ â…¢ â…£ â…¤ â…¥ â…¦ +- â…§ â…¨ â…© 〡 〢 〣 〤 〥 〦 〧 〨 〩 å„ ï¼¡ ï¼¢ ï¼£ +- D ï¼¥ F G H I J K L ï¼­ ï¼® O ï¼° ï¼± ï¼² ï¼³ +- ï¼´ ï¼µ V ï¼· X ï¼¹ Z ï½ ï½‚ c d ï½… f g h i +- j k l ï½ ï½Ž ï½ ï½ ï½‘ ï½’ s ï½” u ï½– ï½— x ï½™ +- z Α Î’ Γ Δ Ε Ζ Η Θ Ι Κ Λ Îœ ΠΞ Ο +- Π Ρ Σ Τ Î¥ Φ Χ Ψ Ω α β γ δ ε ζ η +- θ ι κ λ μ ν ξ ο Ï€ Ï Ïƒ Ï„ Ï… φ χ ψ +- ω ã„… ㄆ ㄇ ㄈ ㄉ ã„Š ã„‹ ã„Œ ã„ ã„Ž ã„ ã„ ã„‘ ã„’ ã„“ +- ã„” ã„• ã„– ã„— ㄘ ã„™ ã„š ã„› ã„œ ã„ ã„ž ã„Ÿ ã„  ã„¡ ã„¢ ã„£ +- ㄤ ã„¥ ㄦ ㄧ ㄨ ã„© Ë™ ˉ ËŠ ˇ Ë‹ 一 ä¹™ ä¸ ä¸ƒ 乃 +- ä¹ äº† 二 人 å„¿ å…¥ å…« 几 刀 åˆ åŠ› 匕 å åœ åˆ ä¸‰ +- 下 丈 上 丫 丸 凡 ä¹… 么 也 乞 于 亡 å…€ 刃 勺 åƒ +- å‰ å£ åœŸ 士 夕 大 女 å­ å­‘ å­“ 寸 å° å°¢ å°¸ å±± å· +- å·¥ å·± å·² å·³ å·¾ å¹² 廾 弋 弓 æ‰ ä¸‘ ä¸ ä¸ ä¸­ 丰 丹 +- 之 å°¹ 予 云 井 互 五 亢 ä» ä»€ 仃 仆 仇 ä» ä»Š 介 +- 仄 å…ƒ å… å…§ å…­ å…® å…¬ 冗 凶 分 切 刈 å‹» 勾 å‹¿ 化 +- 匹 åˆ å‡ å… åž åŽ„ å‹ åŠ å 壬 天 夫 太 夭 å­” å°‘ +- å°¤ å°º 屯 å·´ å¹» 廿 å¼” 引 心 戈 戶 手 扎 支 æ–‡ æ–— +- æ–¤ æ–¹ æ—¥ æ›° 月 木 欠 æ­¢ æ­¹ 毋 比 毛 æ° æ°´ ç« çˆª +- 父 爻 片 牙 牛 犬 王 丙 世 丕 且 丘 主 ä¹ ä¹ ä¹Ž +- 以 付 ä»” 仕 ä»– ä»— 代 令 ä»™ 仞 å…… å…„ 冉 冊 冬 凹 +- 出 凸 刊 加 功 包 匆 北 åŒ ä»Ÿ åŠ å‰ å¡ å  å¯ å® +- 去 å¯ å¤ å³ å¬ å® å© å¨ å¼ å¸ åµ å« å¦ åª å² å± +- å° å¥ å­ å» å›› 囚 外 央 失 奴 奶 å­• 它 å°¼ å·¨ å·§ +- å·¦ 市 布 å¹³ å¹¼ å¼ å¼˜ å¼— å¿… 戊 打 扔 扒 扑 æ–¥ æ—¦ +- 朮 本 未 末 札 æ­£ æ¯ æ°‘ æ° æ°¸ æ± æ±€ æ°¾ 犯 玄 玉 +- ç“œ 瓦 甘 生 用 甩 ç”° ç”± 甲 申 ç–‹ 白 çš® çš¿ ç›® 矛 +- 矢 石 示 禾 ç©´ ç«‹ 丞 丟 ä¹’ 乓 乩 亙 交 亦 亥 仿 +- 伉 ä¼™ 伊 伕 ä¼ ä¼ ä¼‘ ä¼ ä»² 件 ä»» ä»° 仳 份 ä¼ ä¼‹ +- å…‰ å…‡ å…† å…ˆ å…¨ å…± å† å†° 列 刑 划 刎 刖 劣 匈 匡 +- 匠 å° å± å‰ å åŒ åŠ å å å‹ å„ å‘ å åˆ åƒ åŽ +- å† å’ å›  回 å› åœ³ 地 在 圭 圬 圯 圩 夙 多 夷 夸 +- 妄 奸 妃 好 她 如 å¦ å­— å­˜ 宇 守 å®… 安 寺 å°– å±¹ +- å·ž 帆 并 å¹´ å¼ å¼› å¿™ å¿– 戎 戌 æˆ æˆ æ‰£ 扛 托 收 +- æ—© æ—¨ æ—¬ æ—­ 曲 曳 有 朽 朴 朱 朵 次 æ­¤ æ­» æ°– æ± +- æ±— æ±™ 江 æ±  æ± æ±• 污 æ±› æ± æ±Ž ç° ç‰Ÿ ç‰ ç™¾ 竹 ç±³ +- 糸 缶 羊 ç¾½ è€ è€ƒ 而 耒 耳 è¿ è‚‰ è‚‹ è‚Œ 臣 自 至 +- 臼 舌 舛 舟 艮 色 艾 虫 è¡€ è¡Œ è¡£ 西 阡 串 亨 ä½ +- ä½ ä½‡ ä½— 佞 ä¼´ ä½› 何 ä¼° ä½ ä½‘ ä¼½ 伺 伸 佃 ä½” ä¼¼ +- 但 ä½£ 作 ä½  伯 低 伶 ä½™ ä½ ä½ˆ 佚 å…Œ å…‹ å… å…µ 冶 +- 冷 別 判 利 刪 刨 劫 助 努 劬 匣 å³ åµ å å­ åž +- å¾ å¦ å‘Ž å§ å‘† 呃 å³ å‘ˆ å‘‚ å› å© å‘Š å¹ å» å¸ å® +- åµ å¶ å  å¼ å‘€ å± å« åŸ å¬ å›ª å›° 囤 囫 åŠ å‘ å€ +- å å‡ åŽ åœ¾ å å 圻 壯 夾 å¦ å¦’ 妨 妞 妣 妙 妖 +- å¦ å¦¤ 妓 妊 妥 å­ å­œ å­š å­› 完 宋 å® å°¬ å±€ å± å°¿ +- å°¾ å² å²‘ å²” 岌 å·« 希 åº åº‡ 床 å»· 弄 弟 彤 å½¢ å½· +- å½¹ 忘 å¿Œ å¿— å¿ å¿± å¿« 忸 忪 戒 我 抄 抗 抖 技 扶 +- 抉 扭 把 扼 找 批 扳 抒 扯 折 扮 投 抓 抑 抆 改 +- æ”» 攸 æ—± æ›´ æŸ æŽ æ æ æ‘ æœ æ– æž æ‰ æ† æ  æ“ +- æ— æ­¥ æ¯ æ±‚ 汞 æ²™ æ² æ²ˆ 沉 æ²… æ²› 汪 決 æ² æ±° 沌 +- 汨 æ²– æ²’ æ±½ 沃 æ±² æ±¾ æ±´ 沆 汶 æ² æ²” 沘 沂 ç¶ ç¼ +- ç½ ç¸ ç‰¢ 牡 牠 ç‹„ ç‹‚ 玖 甬 甫 ç”· 甸 çš‚ 盯 矣 ç§ +- 秀 禿 究 ç³» 罕 è‚– è‚“ è‚ è‚˜ è‚› è‚š 育 良 芒 芋 èŠ +- 見 角 言 è°· 豆 豕 è² èµ¤ èµ° 足 身 車 è¾› è¾° è¿‚ 迆 +- è¿… è¿„ å·¡ é‚‘ é‚¢ 邪 邦 é‚£ é…‰ 釆 里 防 阮 阱 阪 阬 +- 並 ä¹– ä¹³ 事 些 亞 享 京 佯 ä¾ ä¾ ä½³ 使 佬 ä¾› 例 +- 來 侃 ä½° ä½µ 侈 佩 ä½» ä¾– ä½¾ ä¾ ä¾‘ 佺 å…” å…’ å…• å…© +- å…· å…¶ å…¸ 冽 函 刻 券 刷 刺 到 刮 制 å‰ åŠ¾ 劻 å’ +- å” å“ å‘ å¦ å· å¸ å¹ å– å” å— å‘³ 呵 å’– 呸 å’• å’€ +- å‘» å‘· å’„ å’’ å’† 呼 å’ å‘± 呶 å’Œ å’š å‘¢ 周 å’‹ 命 å’Ž +- 固 垃 å· åª å© å¡ å¦ å¤ å¼ å¤œ 奉 奇 奈 奄 奔 妾 +- 妻 委 妹 妮 姑 姆 å§ å§ å§‹ 姓 姊 妯 妳 姒 姅 å­Ÿ +- å­¤ å­£ å®— 定 官 宜 å®™ å®› å°š 屈 å±… 屆 å²· 岡 岸 岩 +- 岫 å²± å²³ 帘 帚 帖 帕 帛 帑 幸 庚 店 府 底 庖 延 +- 弦 弧 弩 å¾€ å¾ å½¿ å½¼ å¿ å¿  忽 念 å¿¿ æ€ æ€” 怯 怵 +- 怖 怪 怕 怡 性 怩 怫 怛 或 戕 房 戾 所 承 拉 æ‹Œ +- æ‹„ 抿 æ‹‚ 抹 æ‹’ æ‹› 披 æ‹“ æ‹” æ‹‹ 拈 抨 抽 押 æ‹ æ‹™ +- 拇 æ‹ æŠµ æ‹š 抱 拘 æ‹– æ‹— 拆 抬 æ‹Ž 放 æ–§ æ–¼ æ—º 昔 +- 易 昌 昆 昂 明 昀 æ˜ æ˜• 昊 昇 æœ æœ‹ æ­ æž‹ æž• æ± +- æžœ æ³ æ· æž‡ æž æž— æ¯ æ° æ¿ æž‰ æ¾ æž æµ æžš æž“ æ¼ +- æª æ² æ¬£ æ­¦ æ­§ æ­¿ æ°“ æ°› æ³£ 注 æ³³ æ²± 泌 æ³¥ æ²³ æ²½ +- æ²¾ æ²¼ æ³¢ 沫 法 泓 沸 泄 æ²¹ æ³ æ²® æ³— æ³… æ³± 沿 æ²» +- 泡 æ³› 泊 沬 泯 泜 æ³– æ³  ç‚• ç‚Ž ç‚’ ç‚Š ç‚™ 爬 爭 爸 +- 版 牧 物 ç‹€ ç‹Ž ç‹™ ç‹— ç‹ çŽ© 玨 玟 玫 玥 甽 ç– ç–™ +- ç–š çš„ 盂 盲 ç›´ 知 矽 社 祀 ç¥ ç§‰ 秈 空 穹 竺 ç³¾ +- ç½” 羌 羋 者 肺 è‚¥ è‚¢ 肱 è‚¡ è‚« è‚© è‚´ 肪 肯 臥 臾 +- èˆ èŠ³ èŠ èŠ™ 芭 芽 芟 芹 花 芬 芥 芯 芸 芣 芰 芾 +- 芷 虎 è™± åˆ è¡¨ 軋 è¿Ž è¿” è¿‘ 邵 邸 邱 邶 采 金 é•· +- é–€ 阜 陀 阿 阻 附 陂 éš¹ 雨 é’ éž äºŸ 亭 亮 ä¿¡ ä¾µ +- 侯 便 ä¿  ä¿‘ ä¿ ä¿ ä¿ƒ 侶 俘 ä¿Ÿ ä¿Š ä¿— ä¾® ä¿ ä¿„ ä¿‚ +- ä¿š ä¿Ž ä¿ž ä¾· å…— 冒 冑 冠 剎 剃 削 å‰ å‰Œ 剋 則 勇 +- 勉 勃 å‹ åŒ å— å» åŽš å› å’¬ å“€ å’¨ å“Ž 哉 å’¸ å’¦ å’³ +- 哇 å“‚ å’½ å’ª å“ å“„ 哈 å’¯ å’« å’± å’» å’© å’§ å’¿ 囿 åž‚ +- åž‹ åž  垣 垢 城 åž® åž“ 奕 契 å¥ å¥Ž å¥ å§œ 姘 姿 姣 +- 姨 娃 姥 姪 姚 姦 å¨ å§» å­© 宣 宦 室 客 宥 å° å±Ž +- å± å± å±‹ å³™ å³’ å·· å¸ å¸¥ 帟 å¹½ 庠 度 建 弈 å¼­ å½¥ +- 很 å¾… 徊 律 徇 後 徉 怒 æ€ æ€  急 怎 怨 æ æ° æ¨ +- æ¢ æ† æƒ æ¬ æ« æª æ¤ æ‰ æ‹œ 挖 按 拼 æ‹­ æŒ æ‹® 拽 +- 指 拱 æ‹· 拯 括 拾 æ‹´ 挑 挂 政 æ•… æ–« æ–½ æ—¢ 春 昭 +- 映 昧 是 星 昨 昱 昤 æ›· 柿 染 柱 柔 æŸ æŸ¬ 架 枯 +- 柵 柩 柯 柄 柑 æž´ 柚 查 枸 æŸ æŸž 柳 æž° 柙 柢 æŸ +- 柒 æ­ª 殃 殆 段 毒 毗 æ°Ÿ 泉 æ´‹ æ´² æ´ª æµ æ´¥ æ´Œ æ´± +- æ´ž æ´— æ´» æ´½ æ´¾ æ´¶ æ´› æ³µ æ´¹ æ´§ æ´¸ æ´© æ´® æ´µ æ´Ž æ´« +- ç‚« 為 炳 炬 炯 ç‚­ 炸 ç‚® 炤 爰 牲 牯 牴 ç‹© ç‹  ç‹¡ +- 玷 çŠ çŽ» 玲 ç ç€ çŽ³ 甚 ç”­ ç• ç•Œ ç•Ž ç•‹ ç–« ç–¤ ç–¥ +- ç–¢ ç–£ 癸 皆 皇 皈 盈 盆 盃 ç›… çœ ç›¹ 相 眉 看 盾 +- 盼 眇 矜 ç ‚ ç ” ç Œ ç  ç¥† 祉 祈 祇 禹 禺 科 秒 秋 +- ç©¿ çª ç«¿ 竽 ç±½ ç´‚ ç´… ç´€ ç´‰ ç´‡ ç´„ ç´† 缸 美 羿 耄 +- è€ è€ è€‘ 耶 胖 胥 胚 胃 胄 背 胡 胛 胎 胞 胤 èƒ +- 致 舢 苧 范 茅 è‹£ è‹› 苦 茄 è‹¥ 茂 茉 è‹’ è‹— 英 èŒ +- è‹œ è‹” è‹‘ è‹ž è‹“ è‹Ÿ 苯 茆 è™ è™¹ è™» 虺 è¡ è¡« è¦ è§” +- 計 訂 訃 貞 è²  èµ´ èµ³ 趴 è» è»Œ è¿° 迦 è¿¢ 迪 è¿¥ è¿­ +- è¿« 迤 迨 郊 郎 éƒ éƒƒ é…‹ é…Š é‡ é–‚ é™ é™‹ 陌 é™ é¢ +- é© éŸ‹ 韭 音 é  é¢¨ 飛 食 首 香 乘 亳 倌 å€ å€£ 俯 +- 倦 倥 俸 倩 倖 倆 值 借 倚 倒 們 俺 倀 倔 倨 俱 +- 倡 個 候 倘 俳 ä¿® 倭 倪 俾 倫 倉 å…¼ 冤 冥 冢 å‡ +- 凌 准 凋 剖 剜 剔 剛 å‰ åŒª å¿ åŽŸ åŽ åŸ å“¨ å” å” +- å”· 哼 å“¥ 哲 唆 哺 å”” å“© å“­ å“¡ 唉 å“® 哪 哦 唧 唇 +- 哽 å” åœƒ 圄 埂 埔 埋 埃 å ‰ å¤ å¥— 奘 奚 娑 娘 娜 +- 娟 娛 娓 姬 娠 娣 娩 娥 娌 娉 å­« 屘 å®° 害 家 å®´ +- å®® 宵 容 宸 å°„ 屑 展 å± å³­ å³½ å³» 峪 峨 å³° 島 å´ +- å³´ å·® 席 師 庫 庭 座 å¼± å¾’ 徑 å¾ æ™ æ£ æ¥ æ æ• +- æ­ æ© æ¯ æ‚„ æ‚Ÿ æ‚š æ‚ æ‚” æ‚Œ æ‚… æ‚– 扇 拳 挈 æ‹¿ æŽ +- 挾 振 æ• æ‚ æ† æ æ‰ æŒº æ 挽 挪 挫 挨 æ æŒ æ•ˆ +- 敉 æ–™ æ— æ—… 時 晉 æ™ æ™ƒ æ™’ 晌 æ™… æ™ æ›¸ 朔 朕 朗 +- æ ¡ æ ¸ 案 框 æ¡“ æ ¹ æ¡‚ æ¡” æ © 梳 æ — æ¡Œ æ¡‘ æ ½ 柴 æ¡ +- æ¡€ æ ¼ 桃 æ ª æ¡… æ “ æ ˜ æ¡ æ®Š 殉 æ®· æ°£ æ°§ æ°¨ æ°¦ æ°¤ +- æ³° 浪 涕 消 涇 浦 浸 æµ· æµ™ 涓 浬 涉 æµ® 浚 æµ´ 浩 +- 涌 涊 æµ¹ 涅 æµ¥ 涔 烊 烘 烤 烙 烈 çƒ çˆ¹ 特 狼 狹 +- 狽 狸 ç‹· 玆 ç­ ç‰ ç® ç  çª çž ç•” ç• ç•œ ç•š ç•™ ç–¾ +- ç—… ç—‡ ç–² ç–³ ç–½ ç–¼ ç–¹ ç—‚ ç–¸ çš‹ çš° 益 ç› ç›Ž 眩 真 +- 眠 眨 矩 ç ° ç § ç ¸ ç  ç ´ ç · ç ¥ ç ­ ç   ç Ÿ ç ² 祕 ç¥ +- 祠 祟 祖 神 ç¥ ç¥— 祚 秤 秣 秧 租 秦 秩 秘 窄 窈 +- ç«™ 笆 笑 粉 ç´¡ ç´— ç´‹ ç´Š ç´  ç´¢ ç´” ç´ ç´• ç´š ç´œ ç´ +- ç´™ ç´› 缺 罟 ç¾” ç¿… ç¿ è€† 耘 耕 耙 耗 耽 耿 胱 è„‚ +- 胰 è„… 胭 胴 脆 胸 胳 脈 能 è„Š 胼 胯 臭 臬 舀 èˆ +- 航 舫 舨 般 芻 茫 è’ è” èŠ èŒ¸ è è‰ èŒµ 茴 è 茲 +- 茹 茶 茗 è€ èŒ± 茨 èƒ è™” 蚊 蚪 èš“ 蚤 èš© 蚌 蚣 èšœ +- è¡° è¡· è¢ è¢‚ 衽 衹 記 è¨ è¨Ž 訌 訕 訊 託 訓 訖 è¨ +- 訑 豈 豺 è±¹ 財 è²¢ èµ· 躬 è»’ è»” è» è¾± é€ é€† è¿· 退 +- 迺 è¿´ 逃 追 逅 迸 é‚• 郡 éƒ éƒ¢ é…’ é… é…Œ 釘 é‡ é‡— +- 釜 釙 é–ƒ 院 陣 陡 é™› é™ é™¤ 陘 陞 éš» 飢 馬 骨 高 +- 鬥 鬲 鬼 ä¹¾ åº å½ åœ å‡ åƒ åŒ åš å‰ å¥ å¶ åŽ å• +- åµ å´ å· å å€ å¯ å­ å…œ 冕 凰 剪 副 å‹’ å‹™ 勘 å‹• +- åŒ åŒ åŒ™ 匿 å€ åŒ¾ åƒ æ›¼ 商 啪 啦 å•„ å•ž å•¡ 啃 å•Š +- å”± å•– å• å•• 唯 啤 唸 å”® å•œ 唬 å•£ 唳 å• å•— 圈 國 +- 圉 域 å … å Š å † 埠 埤 基 å ‚ å µ 執 培 夠 奢 娶 å© +- 婉 婦 婪 å©€ 娼 å©¢ å©š 婆 å©Š å­° 寇 寅 寄 寂 宿 密 +- å°‰ å°ˆ å°‡ å±  屜 å± å´‡ å´† å´Ž å´› å´– å´¢ å´‘ å´© å´” å´™ +- å´¤ å´§ å´— å·¢ 常 帶 帳 帷 康 庸 庶 庵 庾 å¼µ å¼· å½— +- 彬 彩 彫 å¾— å¾™ 從 徘 御 å¾  徜 æ¿ æ‚£ 悉 æ‚  您 惋 +- æ‚´ 惦 悽 情 æ‚» 悵 惜 悼 惘 惕 惆 惟 悸 惚 惇 戚 +- 戛 扈 掠 控 æ² æŽ– 探 接 æ· æ§ æŽ˜ 措 æ± æŽ© 掉 掃 +- 掛 æ« æŽ¨ 掄 授 掙 採 掬 排 æŽ æŽ€ æ» æ© æ¨ æº æ• +- æ•– æ•‘ æ•™ æ•— å•Ÿ æ• æ•˜ æ•• æ•” æ–œ æ–› æ–¬ æ— æ—‹ æ—Œ æ—Ž +- æ™ æ™š 晤 晨 晦 晞 曹 å‹— 望 æ¢ æ¢¯ 梢 梓 梵 æ¡¿ 桶 +- 梱 梧 梗 械 梃 棄 梭 梆 梅 梔 æ¢ æ¢¨ 梟 梡 梂 欲 +- 殺 毫 毬 æ°« 涎 涼 æ·³ æ·™ 液 æ·¡ æ·Œ æ·¤ æ·» æ·º 清 æ·‡ +- æ·‹ 涯 æ·‘ 涮 æ·ž æ·¹ 涸 æ·· æ·µ æ·… æ·’ 渚 涵 æ·š æ·« æ·˜ +- æ·ª æ·± æ·® æ·¨ æ·† æ·„ 涪 æ·¬ 涿 æ·¦ 烹 焉 ç„Š 烽 烯 爽 +- 牽 çŠ çŒœ 猛 猖 猓 猙 率 ç… çŠ çƒ ç† ç¾ ç ç“  瓶 +- ç“· 甜 產 ç•¥ 畦 ç•¢ ç•° ç– ç—” ç—• ç–µ ç—Š ç— çšŽ ç›” ç›’ +- ç›› 眷 眾 眼 眶 眸 眺 ç¡« 硃 ç¡Ž 祥 票 祭 移 窒 窕 +- 笠 笨 笛 第 符 笙 笞 笮 ç²’ ç²— 粕 絆 絃 çµ± ç´® ç´¹ +- ç´¼ çµ€ ç´° ç´³ 組 ç´¯ 終 ç´² ç´± ç¼½ 羞 羚 ç¿Œ ç¿Ž ç¿’ 耜 +- èŠ è† è„¯ è„– è„£ è„« è„© è„° 脤 舂 舵 舷 舶 船 莎 莞 +- 莘 è¸ èŽ¢ 莖 莽 莫 莒 莊 莓 莉 莠 è· è» è¼ èŽ† 莧 +- 處 彪 蛇 蛀 蚶 蛄 èšµ 蛆 蛋 èš± 蚯 蛉 è¡“ 袞 袈 被 +- 袒 袖 è¢ è¢‹ 覓 è¦ è¨ª è¨ è¨£ 訥 許 設 訟 訛 訢 豉 +- 豚 販 責 貫 貨 貪 貧 赧 赦 趾 趺 è»› 軟 這 é€ é€š +- 逗 連 速 é€ é€ é€• 逞 造 é€ é€¢ 逖 逛 途 部 郭 都 +- é…— 野 釵 釦 釣 釧 釭 釩 é–‰ 陪 陵 陳 陸 é™° é™´ 陶 +- é™· 陬 雀 雪 雩 ç«  ç«Ÿ é ‚ é ƒ é­š é³¥ é¹µ 鹿 麥 麻 å‚¢ +- å‚ å‚… å‚™ å‚‘ å‚€ å‚– 傘 å‚š 最 凱 割 剴 創 剩 å‹ž å‹ +- å‹› åš åŽ¥ å•» å–€ å–§ 啼 å–Š å– å–˜ å–‚ å–œ å–ª å–” å–‡ å–‹ +- å–ƒ å–³ å–® å–Ÿ 唾 å–² å–š å–» å–¬ å–± 啾 å–‰ å–« å–™ åœ å ¯ +- å ª å ´ å ¤ å ° å ± å ¡ å  å   壹 壺 奠 å©· 媚 å©¿ 媒 媛 +- 媧 å­³ å­± 寒 富 寓 å¯ å°Š å°‹ å°± 嵌 åµ å´´ 嵇 å·½ å¹… +- 帽 å¹€ 幃 å¹¾ 廊 å» å»‚ 廄 å¼¼ å½­ 復 循 徨 惑 惡 悲 +- 悶 惠 æ„œ æ„£ 惺 æ„• 惰 惻 惴 æ…¨ 惱 æ„Ž 惶 愉 æ„€ æ„’ +- 戟 扉 掣 掌 æ æ€ æ© æ‰ æ† æ æ’ æ£ æ æ¡ æ– æ­ +- æ® æ¶ æ´ æª æ› æ‘’ æš æ¹ æ•ž 敦 æ•¢ æ•£ æ–‘ æ– æ–¯ æ™® +- æ™° æ™´ 晶 景 æš‘ 智 晾 æ™· 曾 替 期 æœ æ£º 棕 棠 棘 +- 棗 椅 棟 棵 森 棧 棹 棒 棲 棣 棋 æ£ æ¤ æ¤’ 椎 棉 +- 棚 楮 棻 款 欺 欽 殘 æ®– 殼 毯 æ°® æ°¯ æ°¬ 港 游 æ¹” +- 渡 渲 湧 湊 渠 渥 渣 減 æ¹› 湘 渤 æ¹– æ¹® 渭 渦 湯 +- 渴 æ¹ æ¸º 測 湃 æ¸ æ¸¾ 滋 溉 渙 湎 æ¹£ 湄 æ¹² 湩 湟 +- ç„™ ç„š 焦 ç„° ç„¡ 然 ç…® ç„œ 牌 犄 犀 猶 猥 猴 猩 çº +- çª ç³ ç¢ ç¥ çµ ç¶ ç´ ç¯ ç› ç¦ ç¨ ç”¥ 甦 ç•« 番 ç—¢ +- ç—› ç—£ ç—™ ç—˜ ç—ž ç—  ç™» 發 çš– çš“ çš´ 盜 ç 短 ç¡ ç¡¬ +- 硯 ç¨ ç¨ˆ 程 稅 稀 窘 窗 窖 ç«¥ ç«£ ç­‰ ç­– ç­† ç­ ç­’ +- ç­” ç­ ç­‹ ç­ ç­‘ 粟 ç²¥ 絞 çµ çµ¨ 絕 ç´« çµ® çµ² 絡 給 +- çµ¢ çµ° çµ³ å–„ ç¿” ç¿• 耋 è’ è‚… è…• è…” è…‹ è…‘ è…Ž 脹 è…† +- 脾 è…Œ è…“ è…´ 舒 舜 è© èƒ è¸ è è  è… è‹ è è¯ è± +- è´ è‘— èŠ è° èŒ èŒ è½ è² èŠ è¸ èŽ è„ èœ è‡ è” èŸ +- è™› 蛟 è›™ è›­ è›” è›› 蛤 è› è›ž è¡— è£ è£‚ 袱 覃 視 註 +- è©  è©• è©ž 証 è© è©” è©› è© è©† 訴 診 訶 è©– 象 貂 貯 +- è²¼ è²³ è²½ è³ è²» è³€ è²´ è²· 貶 貿 貸 越 超 è¶ è·Ž è· +- è·‹ è·š è·‘ è·Œ è·› è·† è»» 軸 軼 辜 逮 逵 週 逸 進 逶 +- é„‚ 郵 鄉 郾 é…£ é…¥ é‡ éˆ” 鈕 鈣 鈉 鈞 éˆ éˆ éˆ‡ 鈑 +- é–” é– é–‹ é–‘ é–“ é–’ é–Ž 隊 階 éš‹ 陽 éš… 隆 éš é™² éš„ +- é› é›… 雄 集 雇 雯 雲 韌 é … é † é ˆ 飧 飪 飯 飩 飲 +- 飭 馮 馭 黃 é» é»‘ 亂 å‚­ 債 傲 傳 僅 傾 催 å‚· å‚» +- 傯 僇 剿 剷 剽 å‹Ÿ 勦 勤 å‹¢ å‹£ 匯 å—Ÿ å—¨ å—“ å—¦ å—Ž +- å—œ å—‡ å—‘ å—£ å—¤ å—¯ å—š å—¡ å—… å—† å—¥ å—‰ 園 圓 å¡ž å¡‘ +- 塘 å¡— å¡š å¡” å¡« å¡Œ å¡­ å¡Š å¡¢ å¡’ å¡‹ 奧 å« å«‰ å«Œ 媾 +- 媽 媼 媳 å«‚ 媲 嵩 嵯 幌 å¹¹ 廉 廈 å¼’ å½™ 徬 å¾® æ„š +- æ„ æ…ˆ æ„Ÿ 想 æ„› 惹 æ„ æ„ˆ æ…Ž æ…Œ æ…„ æ… æ„¾ æ„´ 愧 æ„ +- 愆 æ„· 戡 戢 æ“ æ¾ æž æª æ­ æ½ æ¬ æ æœ æ” æ æ¶ +- æ– æ— æ† æ•¬ æ–Ÿ æ–° æš— 暉 暇 暈 æš– æš„ 暘 æš æœƒ 榔 +- 業 楚 楷 楠 楔 極 椰 概 楊 楨 楫 楞 楓 楹 榆 æ¥ +- 楣 楛 æ­‡ æ­² 毀 殿 毓 毽 溢 溯 滓 溶 滂 æº æº æ»‡ +- æ»… 溥 溘 溼 溺 溫 滑 準 溜 滄 æ»” 溪 溧 溴 ç…Ž ç…™ +- ç…© ç…¤ ç…‰ ç…§ ç…œ ç…¬ ç…¦ ç…Œ ç…¥ ç…ž ç…† ç…¨ ç…– 爺 牒 猷 +- ç… çŒ¿ 猾 瑯 ç‘š ç‘• ç‘Ÿ ç‘ž ç‘ ç¿ ç‘™ ç‘› ç‘œ 當 畸 瘀 +- ç—° ç˜ ç—² ç—± ç—º ç—¿ ç—´ ç—³ 盞 盟 ç› ç« ç¦ çž ç£ ç¹ +- çª ç¬ çœ ç¥ ç¨ ç¢ çŸ® 碎 碰 碗 碘 碌 碉 硼 碑 碓 +- ç¡¿ 祺 祿 ç¦ è¬ ç¦½ 稜 稚 稠 稔 稟 稞 窟 窠 ç­· 節 +- ç­  ç­® ç­§ ç²± ç²³ ç²µ 經 çµ¹ 綑 ç¶ ç¶ çµ› ç½® 罩 罪 ç½² +- 義 羨 群 è– è˜ è‚† è‚„ è…± è…° è…¸ è…¥ è…® è…³ è…« è…¹ è…º +- è…¦ 舅 艇 è’‚ è‘· è½ è± è‘µ 葦 è‘« 葉 葬 è‘› è¼ èµ è‘¡ +- è‘£ è‘© è‘­ 葆 虞 虜 號 蛹 蜓 蜈 蜇 蜀 蛾 è›» 蜂 蜃 +- 蜆 蜊 è¡™ 裟 裔 裙 補 裘 è£ è£¡ 裊 裕 裒 覜 解 è©« +- 該 詳 試 è©© è©° 誇 詼 è©£ 誠 話 誅 è©­ è©¢ è©® 詬 詹 +- è©» 訾 詨 è±¢ 貊 貉 賊 資 賈 賄 è²² 賃 賂 è³… è·¡ è·Ÿ +- è·¨ è·¯ è·³ è·º è·ª è·¤ è·¦ 躲 較 載 軾 輊 辟 è¾² é‹ éŠ +- é“ é‚ é” é€¼ é• é é‡ é éŽ é é‘ é€¾ é é„’ é„— é…¬ +- é…ª é…© 釉 鈷 鉗 鈸 鈽 鉀 鈾 鉛 鉋 鉤 鉑 鈴 鉉 é‰ +- 鉅 鈹 鈿 鉚 é–˜ 隘 éš” éš• é› é›‹ 雉 雊 é›· é›» 雹 零 +- é– é´ é¶ é  é ‘ é “ é Š é ’ é Œ 飼 飴 飽 飾 馳 馱 馴 +- é«¡ 鳩 麂 鼎 鼓 é¼  僧 僮 僥 僖 僭 僚 僕 åƒ åƒ‘ 僱 +- 僎 僩 å…¢ 凳 劃 劂 匱 厭 å—¾ 嘀 嘛 嘗 å—½ 嘔 嘆 嘉 +- å˜ å˜Ž å—· 嘖 嘟 嘈 å˜ å—¶ 團 圖 塵 塾 境 墓 墊 塹 +- 墅 塽 壽 夥 夢 夤 奪 奩 å«¡ 嫦 å«© å«— å«– 嫘 å«£ å­µ +- 寞 寧 寡 寥 實 寨 寢 寤 察 å° å±¢ 嶄 嶇 å¹› å¹£ 幕 +- å¹— å¹” 廓 å»– 弊 彆 å½° å¾¹ æ…‡ æ„¿ æ…‹ æ…· æ…¢ æ…£ æ…Ÿ æ…š +- æ…˜ æ…µ 截 æ’‡ 摘 æ‘” æ’¤ 摸 æ‘Ÿ 摺 æ‘‘ 摧 æ´ æ‘­ æ‘» 敲 +- æ–¡ æ—— æ—– 暢 暨 æš æ¦œ 榨 榕 æ§ æ¦® 槓 構 榛 榷 榻 +- 榫 榴 æ§ æ§ æ¦­ 槌 榦 槃 榣 æ­‰ æ­Œ æ°³ æ¼³ æ¼” 滾 漓 +- æ»´ 漩 æ¼¾ æ¼  漬 æ¼ æ¼‚ æ¼¢ 滿 滯 漆 æ¼± 漸 æ¼² æ¼£ 漕 +- 漫 漯 澈 漪 滬 æ¼ æ»² 滌 æ»· 熔 熙 ç…½ 熊 熄 熒 爾 +- 犒 犖 ç„ ç 瑤 ç‘£ 瑪 ç‘° ç‘­ 甄 ç–‘ 瘧 ç˜ ç˜‹ 瘉 瘓 +- 盡 監 çž„ ç½ ç¿ ç¡ ç£ ç¢Ÿ 碧 碳 碩 碣 禎 ç¦ ç¦ ç¨® +- 稱 窪 窩 ç«­ 端 管 箕 箋 ç­µ ç®— ç® ç®” ç® ç®¸ 箇 箄 +- ç²¹ ç²½ ç²¾ 綻 綰 綜 綽 綾 綠 ç·Š 綴 網 綱 綺 綢 綿 +- 綵 綸 維 ç·’ ç·‡ 綬 ç½° ç¿  ç¿¡ ç¿Ÿ èž èš è‚‡ è… è†€ è† +- 膈 膊 è…¿ 膂 臧 臺 與 舔 舞 艋 蓉 è’¿ 蓆 è“„ è’™ è’ž +- è’² è’œ è“‹ è’¸ è“€ è““ è’ è’¼ è“‘ è“Š 蜿 蜜 蜻 蜢 蜥 蜴 +- 蜘 è• èœ· 蜩 裳 褂 裴 裹 裸 製 裨 褚 裯 誦 誌 語 +- 誣 èª èª¡ 誓 誤 說 誥 誨 誘 誑 誚 誧 豪 è² è²Œ 賓 +- 賑 è³’ 赫 趙 趕 è·¼ è¼” è¼’ 輕 輓 è¾£ é  é˜ éœ é£ é™ +- éž é¢ é é› é„™ 鄘 é„ž é…µ é…¸ é…· é…´ 鉸 銀 銅 銘 銖 +- 鉻 銓 銜 銨 鉼 銑 é–¡ é–¨ é–© é–£ é–¥ é–¤ éš™ éšœ éš› 雌 +- é›’ 需 é¼ éž… 韶 é — é ˜ 颯 颱 餃 餅 餌 餉 é§ éª¯ 骰 +- 髦 é­ é­‚ é³´ 鳶 é³³ 麼 é¼» 齊 å„„ å„€ 僻 僵 價 å„‚ 儈 +- 儉 å„… 凜 劇 劈 劉 åŠ åŠŠ å‹° 厲 嘮 嘻 嘹 嘲 嘿 嘴 +- 嘩 噓 噎 å™— å™´ 嘶 嘯 嘰 墀 墟 增 墳 墜 墮 墩 墦 +- 奭 嬉 å«» 嬋 嫵 嬌 嬈 寮 寬 審 寫 層 å±¥ å¶ å¶” å¹¢ +- 幟 幡 廢 廚 廟 å» å»£ å»  彈 å½± å¾· å¾µ æ…¶ æ…§ æ…® æ… +- æ…• 憂 æ…¼ æ…° æ…« æ…¾ 憧 æ† æ†« 憎 憬 憚 憤 憔 憮 戮 +- æ‘© 摯 摹 æ’ž æ’² æ’ˆ æ’ æ’° æ’¥ æ’“ æ’• æ’© æ’’ æ’® æ’­ æ’« +- æ’š æ’¬ æ’™ æ’¢ æ’³ 敵 æ•· 數 æš® æš« æš´ æš± 樣 樟 槨 æ¨ +- 樞 標 槽 模 樓 樊 槳 樂 樅 槭 樑 æ­ æ­Ž 殤 毅 毆 +- 漿 æ½¼ 澄 潑 潦 æ½” 澆 æ½­ æ½› 潸 æ½® 澎 潺 æ½° 潤 æ¾— +- 潘 滕 潯 æ½  潟 熟 熬 熱 熨 牖 犛 çŽ ç— ç‘© ç’‹ ç’ƒ +- 瑾 ç’€ ç•¿ 瘠 瘩 瘟 瘤 瘦 瘡 瘢 çšš 皺 盤 瞎 瞇 瞌 +- çž‘ çž‹ 磋 磅 確 磊 碾 磕 碼 ç£ ç¨¿ 稼 ç©€ 稽 稷 稻 +- 窯 窮 ç®­ ç®± 範 ç®´ 篆 篇 ç¯ ç®  篌 糊 ç·  ç·´ ç·¯ ç·» +- ç·˜ ç·¬ ç· ç·¨ ç·£ ç·š ç·ž ç·© 綞 ç·™ ç·² ç·¹ ç½µ ç½· 羯 ç¿© +- 耦 膛 膜 è† è†  膚 膘 è”— 蔽 蔚 è“® 蔬 è”­ 蔓 蔑 蔣 +- 蔡 è”” 蓬 蔥 è“¿ 蔆 èž‚ è´ è¶ è  è¦ è¸ è¨ è™ è— èŒ +- è“ è¡› è¡ è¤ è¤‡ 褒 褓 褕 褊 誼 è«’ 談 è«„ 誕 è«‹ 諸 +- 課 諉 è«‚ 調 誰 è«– è« èª¶ 誹 è«› 豌 豎 豬 è³  賞 賦 +- 賤 賬 è³­ è³¢ è³£ 賜 質 賡 èµ­ 趟 趣 踫 è¸ è¸ è¸¢ è¸ +- 踩 踟 踡 踞 躺 è¼ è¼› 輟 輩 輦 輪 輜 輞 è¼¥ é© é® +- é¨ é­ é· é„° é„­ 鄧 鄱 醇 醉 醋 醃 é‹… 銻 銷 鋪 銬 +- 鋤 é‹ éŠ³ 銼 é‹’ 鋇 é‹° 銲 é–­ é–± 霄 霆 震 霉 é  éž +- éž‹ éž é ¡ é « é œ 颳 養 餓 餒 餘 é§ é§ é§Ÿ 駛 駑 駕 +- 駒 駙 骷 é«® 髯 鬧 é­… é­„ é­· é­¯ é´† é´‰ é´ƒ 麩 麾 黎 +- 墨 é½’ å„’ 儘 å„” å„ å„• 冀 冪 å‡ åŠ‘ 劓 勳 å™™ 噫 噹 +- 噩 噤 噸 噪 器 噥 å™± 噯 噬 噢 噶 å£ å¢¾ 壇 壅 奮 +- å¬ å¬´ å­¸ 寰 å°Ž 彊 憲 憑 憩 憊 æ‡ æ†¶ 憾 懊 懈 戰 +- æ“… æ“ æ“‹ æ’» æ’¼ æ“š æ“„ 擇 æ“‚ æ“ æ’¿ æ“’ æ“” æ’¾ æ•´ 曆 +- 曉 æš¹ 曄 曇 暸 樽 樸 樺 æ©™ æ©« 橘 樹 æ©„ æ©¢ æ©¡ æ©‹ +- 橇 樵 æ©Ÿ 橈 æ­™ æ­· æ°… æ¿‚ æ¾± 澡 濃 澤 æ¿ æ¾§ æ¾³ æ¿€ +- æ¾¹ 澶 澦 æ¾  æ¾´ 熾 燉 ç‡ ç‡’ 燈 燕 熹 燎 燙 燜 燃 +- 燄 ç¨ ç’œ ç’£ ç’˜ ç’Ÿ ç’ž ç“¢ 甌 ç” ç˜´ 瘸 瘺 盧 盥 çž  +- çžž 瞟 瞥 磨 磚 磬 磧 禦 ç© ç©Ž 穆 ç©Œ ç©‹ 窺 篙 ç°‘ +- 築 篤 篛 篡 篩 篦 糕 ç³– 縊 縑 縈 縛 縣 縞 ç¸ ç¸‰ +- ç¸ ç½¹ ç¾² ç¿° 翱 ç¿® 耨 膳 膩 膨 臻 興 艘 艙 è•Š è•™ +- 蕈 蕨 è•© 蕃 蕉 è•­ 蕪 è•ž 螃 螟 èžž 螢 èž è¡¡ 褪 褲 +- 褥 褫 褡 親 覦 諦 諺 è«« 諱 謀 è«œ 諧 è«® 諾 è¬ è¬‚ +- è«· è«­ 諳 諶 諼 豫 è±­ 貓 è³´ 蹄 踱 踴 蹂 踹 踵 è¼» +- 輯 輸 è¼³ 辨 辦 éµ é´ é¸ é² é¼ éº é„´ 醒 錠 錶 鋸 +- 錳 錯 錢 鋼 錫 錄 錚 éŒ éŒ¦ 錡 錕 錮 錙 é–» 隧 隨 +- 險 雕 霎 霑 霖 éœ éœ“ éœ é› éœ é¦ éž˜ é ° é ¸ é » é · +- é ­ é ¹ é ¤ é¤ é¤¨ 餞 餛 餡 餚 駭 駢 駱 骸 骼 é«» é«­ +- 鬨 鮑 é´• é´£ é´¦ é´¨ é´’ é´› 默 é»” é¾ é¾œ 優 å„Ÿ å„¡ 儲 +- 勵 嚎 嚀 åš åš… 嚇 åš å£• 壓 壑 壎 嬰 嬪 嬤 å­º å°· +- 屨 嶼 嶺 嶽 嶸 幫 彌 å¾½ 應 懂 懇 懦 懋 戲 戴 æ“Ž +- æ“Š 擘 æ“  æ“° 擦 擬 擱 æ“¢ æ“­ æ–‚ æ–ƒ æ›™ æ›– 檀 檔 檄 +- 檢 檜 æ«› 檣 橾 檗 æª æª  æ­œ æ®® 毚 æ°ˆ 濘 濱 æ¿Ÿ æ¿  +- æ¿› 濤 æ¿« 濯 æ¾€ 濬 æ¿¡ æ¿© æ¿• æ¿® æ¿° 燧 營 燮 燦 燥 +- 燭 燬 燴 燠 爵 牆 ç° ç² ç’© ç’° ç’¦ ç’¨ 癆 療 癌 盪 +- çž³ 瞪 çž° 瞬 瞧 çž­ 矯 磷 磺 磴 磯 ç¤ ç¦§ 禪 ç©— 窿 +- ç°‡ ç° ç¯¾ 篷 ç°Œ 篠 ç³  糜 糞 ç³¢ 糟 ç³™ ç³ ç¸® 績 繆 +- 縷 縲 繃 縫 總 縱 ç¹… ç¹ ç¸´ 縹 繈 縵 縿 縯 罄 翳 +- 翼 è± è² è° è¯ è³ è‡† 臃 膺 臂 臀 膿 膽 臉 膾 臨 +- 舉 艱 è–ª è–„ 蕾 è–œ è–‘ è–” è–¯ è–› è–‡ è–¨ è–Š 虧 蟀 蟑 +- èž³ 蟒 蟆 èž« èž» 螺 蟈 蟋 褻 褶 襄 褸 褽 覬 謎 謗 +- 謙 講 謊 謠 è¬ è¬„ è¬ è± è°¿ è±³ 賺 è³½ è³¼ 賸 è³» 趨 +- 蹉 蹋 蹈 蹊 轄 è¼¾ 轂 è½… 輿 é¿ é½ é‚„ é‚ é‚‚ é‚€ 鄹 +- 醣 醞 醜 é 鎂 錨 éµ éŠ é¥ é‹ éŒ˜ é¾ é¬ é› é° éš +- é” é—Š é—‹ é—Œ é—ˆ é—† éš± 隸 é›– 霜 霞 éž  韓 顆 颶 餵 +- é¨ é§¿ é®® 鮫 鮪 é®­ é´» é´¿ 麋 é» é»ž 黜 é» é»› é¼¾ 齋 +- å¢ åš• åš® 壙 壘 嬸 å½ æ‡£ 戳 æ“´ 擲 擾 攆 擺 æ“» æ“· +- æ–· 曜 朦 檳 檬 櫃 檻 檸 æ«‚ 檮 檯 æ­Ÿ æ­¸ 殯 瀉 瀋 +- 濾 瀆 濺 瀑 ç€ ç‡» 燼 燾 燸 ç· çµ ç’§ ç’¿ 甕 ç™– 癘 +- ç™’ çž½ çž¿ çž» çž¼ 礎 禮 ç©¡ ç©¢ ç©  ç«„ ç«… ç°« ç°§ ç°ª ç°ž +- ç°£ ç°¡ 糧 ç¹” 繕 繞 繚 繡 ç¹’ ç¹™ 罈 翹 ç¿» è· è¶ è‡ +- è‡ èˆŠ è— è–© è— è— è—‰ è–° è–º è–¹ è–¦ 蟯 蟬 蟲 蟠 覆 +- 覲 觴 謨 謹 謬 謫 è± è´… è¹™ è¹£ 蹦 蹤 蹟 蹕 軀 轉 +- è½ é‚‡ 邃 邈 醫 醬 é‡ éŽ” 鎊 鎖 鎢 鎳 鎮 鎬 鎰 鎘 +- 鎚 鎗 é—” é—– é— é—• 離 雜 é›™ é›› 雞 霤 鞣 鞦 éž­ 韹 +- é¡ é¡ é¡Œ é¡Ž é¡“ 颺 餾 餿 餽 餮 馥 騎 é« é¬ƒ 鬆 é­ +- é­Ž é­ é¯Š 鯉 鯽 鯈 鯀 鵑 éµ éµ  é»  鼕 鼬 儳 嚥 壞 +- 壟 壢 寵 é¾ å»¬ 懲 懷 懶 懵 攀 æ” æ›  æ› æ«¥ æ« æ«š +- æ«“ 瀛 瀟 瀨 瀚 ç€ ç€• 瀘 爆 çˆ ç‰˜ 犢 ç¸ çº ç’½ ç“Š +- ç“£ ç–‡ ç–† 癟 癡 矇 礙 禱 ç©« ç©© ç°¾ ç°¿ ç°¸ ç°½ ç°· ç±€ +- 繫 ç¹­ ç¹¹ 繩 繪 ç¾… ç¹³ 羶 ç¾¹ 羸 臘 è—© è— è—ª è—• è—¤ +- è—¥ è—· 蟻 è … è  èŸ¹ 蟾 襠 襟 襖 襞 è­ è­œ è­˜ è­‰ è­š +- è­Ž è­ è­† è­™ è´ˆ è´Š è¹¼ è¹² 躇 蹶 蹬 蹺 è¹´ è½” 轎 è¾­ +- é‚Š é‚‹ 醱 醮 é¡ é‘ éŸ éƒ éˆ éœ é é– é¢ é é˜ é¤ +- é— é¨ é—œ éš´ 難 霪 霧 é¡ éŸœ 韻 é¡ž 願 é¡› 颼 饅 饉 +- 騖 騙 é¬ é¯¨ 鯧 鯖 鯛 鶉 鵡 éµ² 鵪 鵬 麒 麗 麓 麴 +- 勸 嚨 åš· 嚶 åš´ åš¼ 壤 å­€ å­ƒ å­½ 寶 å·‰ 懸 懺 攘 æ”” +- æ”™ 曦 朧 櫬 瀾 瀰 瀲 çˆ ç» ç“ ç™¢ 癥 礦 礪 礬 礫 +- 竇 競 籌 籃 ç± ç³¯ ç³° è¾® ç¹½ ç¹¼ 纂 罌 耀 臚 艦 è—» +- è—¹ 蘑 è—º 蘆 蘋 蘇 蘊 è ” è • 襤 覺 觸 è­° è­¬ è­¦ è­¯ +- è­Ÿ è­« è´ è´ èº‰ èº èº… 躂 醴 釋 é˜ éƒ é½ é—¡ 霰 飄 +- 饒 饑 馨 騫 騰 騷 騵 é°“ é° é¹¹ 麵 黨 鼯 齟 é½£ 齡 +- å„· 儸 å› å›€ 囂 夔 屬 å· æ‡¼ 懾 æ” æ”œ æ–• 曩 æ«» 欄 +- 櫺 殲 çŒ çˆ› 犧 ç“– ç“” 癩 矓 ç± çº çºŒ ç¾¼ 蘗 蘭 蘚 +- è £ è ¢ è ¡ è Ÿ 襪 襬 覽 è­´ è­· è­½ è´“ 躊 èº èº‹ 轟 辯 +- 醺 é® é³ éµ éº é¸ é² é« é—¢ 霸 霹 露 響 顧 é¡¥ 饗 +- é©… 驃 é©€ 騾 é« é­” é­‘ é°­ é°¥ 鶯 鶴 é·‚ 鶸 éº é»¯ é¼™ +- 齜 齦 齧 儼 å„» 囈 囊 囉 å­¿ å·” å·’ 彎 懿 攤 權 æ­¡ +- ç‘ ç˜ çŽ€ 瓤 ç–Š ç™® 癬 禳 ç±  籟 è¾ è½ è‡Ÿ 襲 襯 觼 +- 讀 è´– è´— 躑 躓 轡 é…ˆ é‘„ é‘‘ é‘’ 霽 霾 韃 éŸ é¡« 饕 +- é©• é© é«’ 鬚 鱉 é°± é°¾ é°» é·“ é·— é¼´ 齬 齪 é¾” 囌 å·– +- 戀 攣 攫 攪 曬 æ¬ ç“š ç«Š 籤 ç±£ ç±¥ 纓 纖 纔 臢 蘸 +- 蘿 è ± 變 é‚ é‚ é‘£ é‘  鑤 é¨ é¡¯ 饜 é©š é©› é©— é«“ é«” +- é«‘ é±” é±— é±– é·¥ 麟 é»´ 囑 壩 攬 çž ç™± 癲 矗 ç½ ç¾ˆ +- è ¶ è ¹ è¡¢ 讓 è®’ è®– 艷 è´› 釀 鑪 é‚ éˆ é„ éŸ† é¡° é©Ÿ +- 鬢 é­˜ 鱟 é·¹ é·º é¹¼ é¹½ 鼇 é½· é½² 廳 欖 ç£ ç±¬ ç±® è » +- 觀 躡 é‡ é‘² é‘° 顱 饞 é«– 鬣 黌 ç¤ çŸš 讚 é‘· 韉 é©¢ +- é©¥ 纜 讜 躪 釅 鑽 鑾 鑼 é±· 鱸 é»· è±” é‘¿ 鸚 爨 驪 +- 鬱 鸛 鸞 ç±² â‘  â‘¡ â‘¢ â‘£ ⑤ â‘¥ ⑦ ⑧ ⑨ â‘© â‘´ ⑵ +- ⑶ â‘· ⑸ ⑹ ⑺ â‘» ⑼ ⑽ â…° â…± â…² â…³ â…´ â…µ â…¶ â…· +- â…¸ â…¹ 丶 丿 亅 亠 冂 冖 冫 勹 匸 å© åŽ¶ 夊 宀 å·› +- â¼³ 广 å½ å½¡ æ”´ ç–’ è¾µ ¨ ˆ ヽ ヾ ã‚ ã‚ž 々 〆 〇 +- ー ï¼» ï¼½ ✽ ã ã‚ ãƒ ã„ ã… ã† ã‡ ãˆ ã‰ ãŠ ã‹ ãŒ +- ã ㎠ã ã 㑠㒠㓠㔠㕠㖠㗠㘠㙠㚠㛠㜠+- ã ãž ãŸ ã  ã¡ ã¢ ã£ ã¤ ã¥ ã¦ ã§ ã¨ ã© ãª ã« ã¬ +- 㭠㮠㯠㰠㱠㲠㳠㴠㵠㶠㷠㸠㹠㺠㻠㼠+- ã½ ã¾ ã¿ ã‚€ ã‚ ã‚‚ ゃ ã‚„ ã‚… ゆ ょ よ ら ã‚Š ã‚‹ ã‚Œ +- ã‚ ã‚Ž ã‚ ã‚ ã‚‘ ã‚’ ã‚“ ã‚¡ ã‚¢ ã‚£ イ ã‚¥ ウ ェ エ ã‚© +- オ ã‚« ガ ã‚­ ã‚® ク ã‚° ケ ゲ コ ã‚´ サ ザ ã‚· ジ ス +- ズ ã‚» ゼ ソ ゾ ã‚¿ ダ ムヂ ッ ツ ヅ テ デ ト ド +- ナ ニ ヌ ムノ ムムパ ヒ ビ ピ フ ブ プ ヘ ベ +- ペ ホ ボ ムマ ミ ム メ モ ャ ヤ ュ ユ ョ ヨ ラ +- リ ル レ ロ ヮ ワ ヰ ヱ ヲ ン ヴ ヵ ヶ РБ Ð’ +- Г Д Е РЖ З И Й К Л Ðœ РО П Р С +- Т У Ф Ð¥ Ц Ч Ш Щ Ъ Ы Ь Э Ю Я а б +- в г д е Ñ‘ ж з и й к л м н о п Ñ€ +- Ñ Ñ‚ у Ñ„ Ñ… ц ч ш щ ÑŠ Ñ‹ ÑŒ Ñ ÑŽ Ñ â‡§ +- ↸ ↹   乚  刂   冈   ï¿¢ ¦ ' " +- ㈱ â„– â„¡ ã‚› ã‚œ ⺀ ⺄ ⺆ ⺇ ⺈ ⺊ ⺌ ⺠⺕ ⺜ ⺠+- ⺥ ⺧ ⺪ ⺬ ⺮ ⺶ ⺼ ⺾ ⻆ ⻊ ⻌ â» â» â»– â»— ⻞ +- ⻣ ʃ É É› É” ɵ Å“ ø Å‹ ÊŠ ɪ 乂 乜 凵 匚 厂 +- 万 丌 乇 äº å›— 兀 å±® å½³ ä¸ å†‡ 与 丮 亓 仂 仉 仈 +- 冘 勼 å¬ åŽ¹ 圠 夃 夬 å° å·¿ æ—¡ 殳 毌 æ°” 爿 丱 丼 +- 仨 仜 仩 仡 ä» ä»š 刌 匜 åŒ åœ¢ 圣 夗 夯 å® å®„ å°’ +- å°» å±´ å±³ 帄 庀 庂 忉 戉 æ‰ æ°• æ°¶ 汃 æ°¿ æ°» 犮 犰 +- 玊 禸 è‚Š 阞 伎 优 伬 仵 ä¼” ä»± ä¼€ ä»· 伈 ä¼ ä¼‚ ä¼… +- ä¼¢ 伓 伄 ä»´ ä¼’ 冱 刓 刉 åˆ åŠ¦ 匢 匟 å 厊 å‡ å›¡ +- 囟 圮 圪 圴 夼 妀 奼 妅 奻 奾 奷 奿 å­– å°• å°¥ å±¼ +- 屺 å±» å±¾ å·Ÿ å¹µ 庄 异 弚 å½´ å¿• å¿” å¿ æ‰œ 扞 扤 扡 +- 扦 扢 扙 扠 扚 扥 æ—¯ æ—® 朾 朹 朸 朻 机 朿 朼 朳 +- æ°˜ 汆 æ±’ 汜 æ± æ±Š æ±” 汋 汌 ç± ç‰ž 犴 犵 玎 甪 癿 +- 穵 网 艸 艼 芀 艽 艿 è™ è¥¾ é‚™ é‚— 邘 é‚› é‚” 阢 阤 +- 阠 阣 ä½– ä¼» ä½¢ 佉 体 佤 ä¼¾ 佧 ä½’ 佟 ä½ ä½˜ ä¼­ ä¼³ +- 伿 佡 å† å†¹ 刜 刞 刡 劭 劮 匉 å£ å² åŽŽ åŽ å° å· +- åª å‘” å‘… å™ åœ å¥ å˜ å½ å‘ å‘ å¨ å¤ å‘‡ å›® 囧 囥 +- å å… åŒ å‰ å‹ å’ å¤† 奀 妦 妘 妠 妗 妎 妢 å¦ å¦ +- 妧 妡 宎 å®’ å°¨ å°ª å² å² å²ˆ 岋 岉 å²’ 岊 岆 岓 岕 +- å·  帊 帎 庋 庉 庌 庈 åº å¼… å¼ å½¸ 彶 å¿’ å¿‘ å¿ å¿­ +- 忨 å¿® 忳 å¿¡ 忤 å¿£ 忺 忯 å¿· å¿» 怀 å¿´ 戺 抃 抌 抎 +- æŠ æŠ” 抇 扱 扻 扺 扰 æŠ æŠˆ 扷 扽 扲 扴 æ”· æ—° æ—´ +- æ—³ æ—² æ—µ æ… æ‡ æ™ æ• æŒ æˆ æ æ æš æ‹ æ¯ æ°™ æ°š +- 汸 汧 汫 沄 沋 æ² æ±± 汯 汩 沚 æ±­ 沇 沕 沜 汦 æ±³ +- æ±¥ æ±» 沎 ç´ çº ç‰£ 犿 犽 狃 狆 ç‹ çŠº ç‹… 玕 玗 玓 +- 玔 玒 町 甹 ç–” ç–• çš ç¤½ 耴 è‚• è‚™ è‚ è‚’ è‚œ èŠ èŠ +- 芅 芎 芑 芓 芊 芃 芄 豸 迉 辿 é‚Ÿ é‚¡ é‚¥ é‚ž 邧 é‚  +- 阰 阨 阯 阭 丳 侘 ä½¼ ä¾… ä½½ ä¾€ 侇 佶 ä½´ 侉 侄 ä½· +- 佌 ä¾— 佪 侚 ä½¹ ä¾ ä½¸ ä¾ ä¾œ ä¾” 侞 ä¾’ 侂 侕 佫 ä½® +- 冞 冼 冾 刵 刲 刳 剆 刱 劼 匊 匋 匼 厒 厔 å’‡ å‘¿ +- å’ å’‘ å’‚ å’ˆ å‘« 呺 呾 å‘¥ 呬 å‘´ 呦 å’ å‘¯ å‘¡ å‘  å’˜ +- å‘£ 呧 呤 å›· 囹 å¯ å² å­ å« å± å° å¶ åž€ åµ å» å³ +- å´ å¢ å¨ å½ å¤Œ 奅 妵 妺 å§ å§Ž 妲 姌 å§ å¦¶ 妼 姃 +- 姖 妱 妽 姀 姈 妴 姇 å­¢ å­¥ 宓 宕 屄 屇 å²® 岤 å²  +- å²µ 岯 岨 岬 岟 å²£ å²­ å²¢ 岪 岧 å² å²¥ 岶 å²° 岦 帗 +- 帔 帙 弨 å¼¢ å¼£ 弤 å½” 徂 å½¾ å½½ å¿ž å¿¥ 怭 怦 怙 怲 +- 怋 怴 怊 怗 怳 怚 怞 怬 怢 æ€ æ€ æ€® 怓 怑 怌 怉 +- 怜 戔 戽 抭 抴 æ‹‘ 抾 抪 抶 æ‹Š 抮 抳 抯 抻 抩 抰 +- 抸 攽 æ–¨ æ–» 昉 æ—¼ 昄 昒 昈 æ—» 昃 昋 æ˜ æ˜… æ—½ 昑 +- æ˜ æ›¶ 朊 æž… æ¬ æžŽ æž’ æ¶ æ» æž˜ 枆 æž„ æ´ æž æžŒ æº +- 枟 æž‘ æž™ 枃 æ½ æž æ¸ æ¹ æž” 欥 殀 æ­¾ 毞 æ° æ²“ 泬 +- 泫 æ³® æ³™ 沶 æ³” æ²­ 泧 æ²· æ³ æ³‚ 沺 泃 泆 æ³­ æ³² æ³’ +- æ³ æ²´ 沊 æ² æ²€ 泞 æ³€ æ´° æ³ æ³‡ æ²° æ³¹ æ³ æ³© 泑 ç‚” +- 炘 ç‚… ç‚“ 炆 ç‚„ ç‚‘ ç‚– ç‚‚ ç‚š 炃 牪 ç‹– ç‹‹ 狘 狉 ç‹œ +- ç‹’ ç‹” ç‹š ç‹Œ ç‹‘ 玤 玡 玭 玦 玢 玠 玬 çŽ ç“ ç“¨ 甿 +- ç•€ 甾 ç–Œ ç–˜ 皯 盳 ç›± ç›° 盵 矸 矼 矹 矻 矺 矷 祂 +- 礿 秅 穸 ç©» ç«» ç±µ ç³½ 耵 è‚ è‚® è‚£ 肸 肵 è‚­ 舠 芠 +- è‹€ 芫 芚 芘 芛 芵 芧 芮 芼 芞 芺 芴 芨 芡 芩 è‹‚ +- 芤 苃 芶 芢 è™° 虯 è™­ è™® è±– è¿’ è¿‹ è¿“ è¿ è¿– è¿• è¿— +- 邲 é‚´ 邯 邳 é‚° 阹 阽 阼 阺 陃 ä¿ ä¿… ä¿“ ä¾² 俉 ä¿‹ +- ä¿ ä¿” ä¿œ ä¿™ ä¾» ä¾³ ä¿› 俇 ä¿– 侺 ä¿€ ä¾¹ 俬 剄 剉 å‹€ +- å‹‚ 匽 å¼ åŽ— 厖 厙 厘 å’º å’¡ å’­ å’¥ å“ å“ƒ èŒ å’· å’® +- å“– å’¶ å“… 哆 å’  å‘° å’¼ å’¢ å’¾ 呲 å“ž å’° åžµ åžž 垟 垤 +- 垌 åž— åž åž› åž” 垘 åž åž™ 垥 åžš åž• 壴 å¤ å¥“ 姡 姞 +- 姮 娀 姱 å§ å§º 姽 姼 姶 姤 姲 姷 姛 姩 姳 姵 姠 +- 姾 姴 姭 宨 屌 å³ å³˜ 峌 å³— 峋 å³› 峞 峚 峉 峇 峊 +- å³– 峓 å³” å³ å³ˆ 峆 峎 峟 峸 å·¹ 帡 帢 帣 帠 帤 庰 +- 庤 庢 庛 庣 庥 弇 å¼® å½– 徆 怷 怹 æ” æ² æž æ… æ“ +- æ‡ æ‰ æ› æŒ æ€ æ‚ æŸ æ€¤ æ„ æ˜ æ¦ æ® æ‰‚ 扃 æ‹ æŒ +- 挋 拵 挎 挃 æ‹« 拹 æŒ æŒŒ 拸 拶 挀 挓 挔 拺 挕 æ‹» +- æ‹° æ• æ•ƒ æ–ª æ–¿ 昶 昡 昲 昵 昜 昦 昢 昳 昫 昺 æ˜ +- 昴 昹 昮 æœ æœ æŸ æŸ² 柈 枺 柜 æž» 柸 柘 柀 æž· 柅 +- 柫 柤 柟 æžµ æŸ æž³ 柷 柶 柮 柣 柂 æž¹ 柎 柧 柰 æž² +- 柼 柆 柭 柌 æž® 柦 柛 柺 柉 柊 柃 柪 柋 欨 殂 殄 +- 殶 毖 毘 毠 æ°  æ°¡ æ´¨ æ´´ æ´­ æ´Ÿ æ´¼ æ´¿ æ´’ æ´Š 泚 æ´³ +- æ´„ æ´™ æ´º æ´š æ´‘ æ´€ æ´ æµ‚ æ´ æ´˜ æ´· æ´ƒ æ´ æµ€ æ´‡ æ´  +- æ´¬ æ´ˆ æ´¢ æ´‰ æ´ ç‚· ç‚Ÿ 炾 炱 ç‚° ç‚¡ ç‚´ 炵 ç‚© ç‰ ç‰‰ +- 牊 牬 牰 牳 牮 ç‹Š 狤 狨 ç‹« ç‹Ÿ 狪 狦 ç‹£ 玅 çŒ ç‚ +- çˆ ç… çŽ¹ 玶 玵 玴 ç« çŽ¿ ç‡ çŽ¾ çƒ ç† çŽ¸ ç‹ ç“¬ ç“® +- ç”® 畇 畈 ç–§ ç–ª 癹 盄 眈 眃 眄 眅 眊 ç›· ç›» 盺 矧 +- 矨 ç † ç ‘ ç ’ ç … ç  ç  ç Ž ç ‰ ç ƒ ç “ 祊 祌 祋 祅 祄 +- 秕 ç§ ç§ ç§– 秎 窀 穾 ç«‘ 笀 ç¬ ç±º 籸 ç±¹ 籿 ç²€ ç² +- ç´ƒ ç´ˆ ç´ ç½˜ 羑 ç¾ ç¾¾ 耇 耎 è€ è€” 耷 胘 胇 胠 胑 +- 胈 胂 èƒ èƒ… 胣 胙 胜 胊 胕 胉 èƒ èƒ— 胦 èƒ è‡¿ 舡 +- 芔 è‹™ 苾 苹 茇 苨 茀 è‹• 茺 è‹« è‹– è‹´ 苬 è‹¡ 苲 苵 +- 茌 è‹» 苶 è‹° 苪 苤 è‹  苺 苳 è‹­ è™· è™´ 虼 虳 è¡ è¡Ž +- 衧 衪 è¡© 觓 訄 訇 èµ² è¿£ è¿¡ è¿® è¿  郱 邽 é‚¿ 郕 郅 +- 邾 郇 郋 郈 釔 釓 é™” é™ é™‘ 陓 陊 陎 倞 倅 倇 倓 +- 倢 倰 倛 俵 ä¿´ 倳 倷 倬 俶 ä¿· 倗 倜 倠 倧 倵 倯 +- 倱 倎 å…š 冔 冓 凊 凄 凅 凈 凎 剡 剚 剒 剞 剟 剕 +- 剢 å‹ åŒŽ 厞 唦 å“¢ å”— å”’ 哧 哳 哤 唚 å“¿ 唄 唈 å“« +- 唑 å”… 哱 唊 å“» å“· 哸 å“  唎 唃 唋 åœ åœ‚ 埌 å ² 埕 +- 埒 垺 埆 åž½ åž¼ 垸 垶 åž¿ 埇 åŸ åž¹ åŸ å¤Ž 奊 娙 娖 +- 娭 娮 娕 å¨ å¨— 娊 娞 娳 å­¬ 宧 å®­ 宬 å°ƒ å±– å±” 峬 +- 峿 å³® å³± å³· å´€ å³¹ 帩 帨 庨 庮 庪 庬 å¼³ å¼° 彧 æ +- æš æ§ æ æ‚¢ 悈 æ‚€ æ‚’ æ‚ æ‚ æ‚ƒ æ‚• æ‚› æ‚— 悇 æ‚œ æ‚Ž +- 戙 扆 拲 æŒ æ– æŒ¬ æ„ æ… æŒ¶ æƒ æ¤ æŒ¹ æ‹ æŠ æŒ¼ 挩 +- æ 挴 æ˜ æ” æ™ æŒ­ æ‡ æŒ³ æš æ‘ æŒ¸ æ— æ€ æˆ æ•Š 敆 +- æ—† æ—ƒ æ—„ æ—‚ 晊 晟 晇 晑 朒 朓 æ Ÿ æ š 桉 æ ² æ ³ æ » +- æ¡‹ æ¡ æ – æ ± æ œ æ µ æ « æ ­ æ ¯ æ¡Ž æ¡„ æ ´ æ  æ ’ æ ” æ ¦ +- æ ¨ æ ® æ¡ æ º æ ¥ æ   欬 欯 欭 欱 欴 æ­­ è‚‚ 殈 毦 毤 +- 毨 毣 毢 毧 æ°¥ 浺 æµ£ 浤 浶 æ´ æµ¡ 涒 浘 æµ¢ æµ­ 浯 +- 涑 æ¶ æ·¯ 浿 涆 浞 浧 æµ  涗 æµ° æµ¼ 浟 涂 涘 æ´¯ 浨 +- 涋 æµ¾ 涀 涄 æ´– 涃 æµ» æµ½ æµµ æ¶ çƒœ 烓 烑 çƒ çƒ‹ ç¼¹ +- 烢 烗 烒 烞 烠 烔 çƒ çƒ… 烆 烇 烚 烎 烡 牂 牸 牷 +- 牶 猀 狺 ç‹´ 狾 狶 狳 ç‹» çŒ ç“ ç™ ç¥ ç– çŽ¼ ç§ ç£ +- ç© çœ ç’ ç› ç” ç çš ç— ç˜ ç¨ ç“ž ç“Ÿ ç“´ 瓵 甡 ç•› +- ç•Ÿ ç–° ç— ç–» ç—„ ç—€ ç–¿ ç–¶ ç–º 皊 盉 çœ çœ› çœ çœ“ 眒 +- 眣 眑 眕 眙 眚 眢 眧 ç £ ç ¬ ç ¢ ç µ ç ¯ ç ¨ ç ® ç « ç ¡ +- ç © ç ³ ç ª ç ± 祔 祛 ç¥ ç¥œ 祓 祒 祑 秫 秬 秠 秮 秭 +- 秪 秜 秞 ç§ çª† 窉 窅 窋 窌 窊 窇 竘 ç¬ ç¬„ 笓 笅 +- ç¬ ç¬ˆ 笊 笎 笉 笒 粄 粑 粊 粌 粈 ç² ç²… ç´ž ç´ ç´‘ +- ç´Ž ç´˜ ç´– ç´“ ç´Ÿ ç´’ ç´ ç´Œ 罜 罡 罞 ç½  ç½ ç½› ç¾– ç¾’ +- 翃 ç¿‚ ç¿€ 耖 耾 耹 胺 胲 胹 胵 è„ èƒ» è„€ èˆ èˆ¯ 舥 +- 茳 茭 è„ èŒ™ è‘ èŒ¥ è– èŒ¿ è 茦 茜 茢 è‚ èŽ èŒ› 茪 +- 茈 茼 è 茖 茤 茠 茷 茯 茩 è‡ è… èŒ è“ èŒž 茬 è‹ +- 茧 èˆ è™“ è™’ 蚢 蚨 èš– èš èš‘ èšž 蚇 èš— 蚆 èš‹ èšš èš… +- 蚥 èš™ èš¡ 蚧 èš• 蚘 蚎 èš èš èš” 衃 è¡„ è¡­ 衵 衶 衲 +- 袀 衱 è¡¿ 衯 袃 衾 è¡´ 衼 訒 豇 è±— è±» 貤 è²£ 赶 赸 +- 趵 趷 趶 軑 軓 迾 迵 适 è¿¿ è¿» 逄 迼 迶 郖 郠 郙 +- 郚 郣 郟 郥 郘 郛 郗 郜 郤 é… é…Ž é… é‡• 釢 釚 陜 +- 陟 éš¼ 飣 é«Ÿ 鬯 乿 å° åª å¡ åž å  å“ å‹ å å² åˆ +- å å å› åŠ å¢ å€• å… åŸ å© å« å£ å¤ å† å€ å® å³ +- å— å‘ å‡ å‰« 剭 剬 剮 å‹– å‹“ 匭 厜 啵 啶 唼 å• å• +- å”´ 唪 å•‘ å•¢ 唶 唵 å”° å•’ å•… 唌 唲 å•¥ å•Ž 唹 啈 å”­ +- å”» å•€ å•‹ 圊 圇 埻 å ” 埢 埶 埜 埴 å € 埭 埽 å ˆ 埸 +- å ‹ 埳 åŸ å ‡ 埮 埣 埲 埥 埬 埡 å Ž 埼 å  åŸ§ å  å Œ +- 埱 埩 埰 å  å „ 奜 å©  婘 å©• 婧 å©ž 娸 娵 å©­ å© å©Ÿ +- å©¥ 婬 å©“ 婤 å©— 婃 å© å©’ å©„ å©› 婈 媎 娾 å© å¨¹ å©Œ +- å©° å©© 婇 å©‘ å©– å©‚ å©œ å­² å­® å¯ å¯€ å±™ å´ž å´‹ å´ å´š +- å´  å´Œ å´¨ å´ å´¦ å´¥ å´ å´° å´’ å´£ å´Ÿ å´® 帾 帴 庱 庴 +- 庹 庲 庳 弶 弸 å¾› å¾– 徟 æ‚Š æ‚ æ‚† 悾 æ‚° 悺 惓 惔 +- æƒ æƒ¤ 惙 æƒ æƒˆ 悱 惛 æ‚· 惊 æ‚¿ 惃 æƒ æƒ€ 挲 æ¥ æŽŠ +- 掂 æ½ æŽ½ 掞 掭 æŽ æŽ— 掫 掎 æ¯ æŽ‡ æŽ æ® æŽ¯ æµ æŽœ +- æ­ æŽ® æ¼ æŽ¤ 挻 掟 æ¸ æŽ… æŽ æŽ‘ æŽ æ° æ•“ æ— æ™¥ 晡 +- æ™› æ™™ 晜 晢 朘 桹 梇 æ¢ æ¢œ æ¡­ æ¡® 梮 梫 楖 桯 梣 +- 梬 梩 桵 æ¡´ 梲 æ¢ æ¡· 梒 桼 æ¡« 桲 梪 梀 桱 桾 梛 +- 梖 梋 梠 梉 梤 桸 æ¡» 梑 梌 梊 桽 欶 欳 欷 欸 殑 +- æ® æ® æ®Ž 殌 æ°ª æ·€ 涫 涴 涳 æ¹´ 涬 æ·© æ·¢ 涷 æ·¶ æ·” +- 渀 æ·ˆ æ·  æ·Ÿ æ·– 涾 æ·¥ æ·œ æ· æ·› æ·´ æ·Š 涽 æ·­ æ·° 涺 +- æ·• æ·‚ æ· æ·‰ æ· æ·² æ·“ æ·½ æ·— æ· æ·£ 涻 烺 ç„ çƒ· ç„— +- 烴 ç„Œ 烰 ç„„ 烳 ç„ çƒ¼ 烿 焆 ç„“ ç„€ 烸 烶 ç„‹ ç„‚ ç„Ž +- 牾 牻 牼 牿 çŒ çŒ— 猇 猑 猘 猊 猈 ç‹¿ çŒ çŒž 玈 ç¶ +- ç¸ çµ ç„ ç ç½ ç‡ ç€ çº ç¼ ç¿ çŒ ç‹ ç´ çˆ ç•¤ ç•£ +- ç—Ž ç—’ ç— ç—‹ ç—Œ ç—‘ ç— çš çš‰ 盓 眹 眯 眭 眱 眲 眴 +- 眳 眽 眥 眻 眵 硈 ç¡’ 硉 ç¡ ç¡Š ç¡Œ ç ¦ ç¡… ç¡ ç¥¤ 祧 +- 祩 祪 祣 祫 祡 离 秺 秸 秶 秷 çª çª” çª ç¬µ ç­‡ 笴 +- 笥 笰 笢 笤 笳 笘 笪 ç¬ ç¬± 笫 笭 笯 笲 笸 笚 笣 +- ç²” 粘 ç²– ç²£ ç´µ ç´½ ç´¸ ç´¶ ç´º çµ… ç´¬ ç´© çµ çµ‡ ç´¾ ç´¿ +- 絊 ç´» ç´¨ ç½£ 羕 羜 ç¾ ç¾› ç¿Š ç¿‹ ç¿ ç¿ ç¿‘ 翇 ç¿ ç¿‰ +- 耟 耞 耛 è‡ èƒ èˆ è„˜ è„¥ è„™ è„› è„­ è„Ÿ 脬 è„ž è„¡ è„• +- 脧 è„ è„¢ 舑 舸 舳 舺 舴 舲 艴 èŽ èŽ£ 莨 èŽ èº è³ +- 莤 è´ èŽ èŽ èŽ• 莙 èµ èŽ” 莩 è½ èŽƒ 莌 èŽ èŽ› 莪 莋 +- è¾ èŽ¥ 莯 莈 莗 莰 è¿ èŽ¦ 莇 莮 è¶ èŽš è™™ è™– èš¿ èš· +- 蛂 è› è›… 蚺 èš° 蛈 èš¹ èš³ 蚸 蛌 èš´ èš» èš¼ 蛃 èš½ èš¾ +- è¡’ 袉 袕 袨 袢 袪 袚 袑 袡 袟 袘 袧 袙 袛 袗 袤 +- 袬 袌 袓 袎 覂 觖 觙 觕 訰 訧 訬 訞 è°¹ è°» 豜 è± +- è±½ è²¥ èµ½ èµ» èµ¹ 趼 è·‚ 趹 趿 è· è»˜ 軞 è» è»œ è»— è»  +- 軡 逤 逋 逑 逜 逌 逡 郯 郪 郰 郴 郲 郳 郔 郫 郬 +- 郩 é…– é…˜ é…š é…“ é…• 釬 釴 釱 釳 釸 釤 釹 釪 釫 釷 +- 釨 釮 镺 é–† é–ˆ 陼 é™­ 陫 é™± 陯 éš¿ éª é „ 飥 馗 å‚› +- å‚• å‚” å‚ž å‚‹ å‚£ 傃 å‚Œ å‚Ž å‚ å¨ å‚œ å‚’ å‚‚ 傇 å…Ÿ 凔 +- 匒 匑 厤 厧 å–‘ å–¨ å–¥ å–­ å•· å™… å–¢ å–“ å–ˆ å– å–µ å– +- å–£ å–’ å–¤ 啽 å–Œ å–¦ å•¿ å–• å–¡ å–Ž 圌 å © å · å ™ å ž å § +- å £ å ¨ 埵 塈 å ¥ å œ å › å ³ å ¿ å ¶ å ® å ¹ å ¸ å ­ å ¬ å » +- 奡 媯 媔 媟 婺 媢 媞 婸 媦 婼 媥 媬 媕 媮 娷 媄 +- 媊 媗 媃 媋 媩 å©» 婽 媌 媜 åª åª“ åª å¯ª å¯ å¯‹ 寔 +- 寑 寊 寎 å°Œ å°° å´· 嵃 嵫 åµ åµ‹ å´¿ å´µ 嵑 嵎 嵕 å´³ +- å´º åµ’ å´½ å´± åµ™ 嵂 å´¹ 嵉 å´¸ å´¼ å´² å´¶ åµ€ åµ… 幄 å¹ +- 彘 徦 å¾¥ 徫 惉 悹 惌 惢 惎 惄 æ„” 惲 æ„Š æ„– æ„… 惵 +- æ„“ 惸 惼 惾 æƒ æ„ƒ 愘 æ„ æ„ æƒ¿ æ„„ æ„‹ 扊 掔 掱 掰 +- æŽ æ¥ æ¨ æ¯ æƒ æ’ æ³ æŠ æ  æ¶ æ• æ² æµ æ‘¡ æŸ æŽ¾ +- æ æœ æ„ æ˜ æ“ æ‚ æ‡ æŒ æ‹ æˆ æ° æ— æ™ æ”² 敧 敪 +- 敤 æ•œ 敨 æ•¥ æ–Œ æ– æ–ž æ–® æ— æ—’ 晼 晬 æ™» 暀 æ™± 晹 +- 晪 晲 æœ æ¤Œ 棓 椄 棜 椪 棬 棪 棱 æ¤ æ£– 棷 棫 棤 +- 棶 椓 æ¤ æ£³ 棡 椇 棌 椈 楰 梴 椑 棯 棆 椔 棸 æ£ +- 棽 棼 棨 椋 椊 椗 棎 棈 æ£ æ£ž 棦 棴 棑 椆 棔 棩 +- 椕 椥 棇 欹 欻 欿 欼 æ®” æ®— æ®™ 殕 殽 毰 毲 毳 æ°° +- æ·¼ 湆 湇 渟 湉 溈 渼 渽 æ¹… æ¹¢ 渫 渿 æ¹ æ¹ æ¹³ 渜 +- 渳 湋 æ¹€ 湑 渻 渃 渮 湞 湨 湜 湡 渱 渨 æ¹  æ¹± 湫 +- 渹 渢 渰 湓 æ¹¥ 渧 湸 湤 æ¹· 湕 æ¹¹ æ¹’ 湦 渵 渶 湚 +- ç„  ç„ž 焯 烻 ç„® 焱 ç„£ ç„¥ ç„¢ 焲 ç„Ÿ 焨 焺 ç„› 牋 牚 +- 犈 犉 犆 犅 犋 猒 猋 猰 猢 猱 猳 猧 猲 猭 猦 猣 +- 猵 猌 ç® ç¬ ç° ç« ç– çš ç¡ ç­ ç± ç¤ ç£ ç ç© ç  +- ç² ç“» 甯 畯 畬 ç—§ ç—š ç—¡ ç—¦ ç— ç—Ÿ ç—¤ ç—— çš• çš’ 盚 +- ç† ç‡ ç„ ç ç… çŠ çŽ ç‹ çŒ çŸž 矬 ç¡  硤 ç¡¥ ç¡œ ç¡­ +- 硱 硪 ç¡® ç¡° ç¡© 硨 ç¡ž ç¡¢ 祴 祳 祲 祰 稂 稊 稃 稌 +- 稄 窙 竦 竤 ç­Š 笻 ç­„ ç­ˆ ç­Œ ç­Ž ç­€ ç­˜ ç­… ç²¢ 粞 粨 +- 粡 絘 絯 çµ£ 絓 çµ– 絧 絪 çµ çµ­ 絜 絫 çµ’ çµ” 絩 絑 +- 絟 絎 ç¼¾ 缿 ç½¥ 罦 ç¾¢ ç¾  羡 ç¿— è‘ è è 胾 胔 è…ƒ +- è…Š è…’ è… è…‡ 脽 è… è„º 臦 臮 臷 臸 臹 舄 舼 舽 舿 +- 艵 茻 è è¹ è£ è€ è¨ è’ è§ è¤ è¼ è¶ è è† èˆ è« +- è£ èŽ¿ è è è¥ è˜ è¿ è¡ è‹ èŽ è– èµ è‰ è‰ è èž +- è‘ è† è‚ è³ è• èº è‡ è‘ èª è“ èƒ è¬ è® è„ è» è— +- è¢ è› è› è¾ è›˜ 蛢 蛦 蛓 蛣 蛚 蛪 è› è›« 蛜 蛬 蛩 +- è›— 蛨 蛑 衈 è¡– è¡• 袺 裗 袹 袸 裀 袾 袶 袼 袷 袽 +- 袲 è¤ è£‰ 覕 覘 覗 è§ è§š 觛 è©Ž è© è¨¹ è©™ è©€ è©— 詘 +- è©„ è©… è©’ 詈 è©‘ è©Š è©Œ è© è±Ÿ è² è²€ 貺 è²¾ è²° è²¹ è²µ +- 趄 趀 趉 è·˜ è·“ è· è·‡ è·– è·œ è· è·• è·™ è·ˆ è·— è·… 軯 +- è»· 軺 軹 軦 è»® 軥 軵 軧 軨 軶 軫 è»± 軬 è»´ 軩 逭 +- 逴 逯 鄆 鄬 é„„ 郿 郼 鄈 郹 郻 é„ é„€ 鄇 é„… 鄃 é…¡ +- é…¤ é…Ÿ é…¢ é…  éˆ éˆŠ 鈥 鈃 鈚 鈦 éˆ éˆŒ 鈀 鈒 釿 釽 +- 鈆 鈄 鈧 鈂 鈜 鈤 鈙 鈗 鈅 鈖 é•» é– é–Œ é– éš‡ 陾 +- 隈 隉 隃 隀 雂 雈 雃 é›± é›° é¬ é° é® é ‡ 颩 飫 鳦 +- 黹 亃 亄 亶 傽 å‚¿ 僆 å‚® 僄 僊 å‚´ 僈 僂 å‚° åƒ å‚º +- 傱 僋 僉 傶 傸 凗 剺 剸 剻 剼 å—ƒ å—› å—Œ å— å—‹ å—Š +- å— å—€ å—” å—„ å—© å–¿ å—’ å– å— å—• å—¢ å—– å—ˆ å—² å— å—™ +- å—‚ 圔 å¡“ 塨 塤 å¡ å¡ å¡‰ 塯 å¡• å¡Ž å¡ å¡™ å¡¥ å¡› å ½ +- å¡£ 塱 壼 嫇 å«„ å«‹ 媺 媸 媱 媵 媰 媿 嫈 媻 嫆 媷 +- å«€ å«Š 媴 媶 å« åª¹ åª å¯– 寘 寙 å°Ÿ å°³ åµ± åµ£ 嵊 åµ¥ +- åµ² 嵬 嵞 嵨 嵧 åµ¢ å·° å¹ å¹Ž 幊 å¹ å¹‹ å»… 廌 廆 廋 +- 廇 å½€ 徯 å¾­ 惷 æ…‰ æ…Š æ„« æ…… 愶 愲 æ„® æ…† 愯 æ… æ„© +- æ…€ 戠 é…¨ 戣 戥 戤 æ… æ± æ« æ æ’ æ‰ æ  æ¤ æ³ æ‘ƒ +- æŸ æ• æ˜ æ¹ æ· æ¢ æ£ æŒ æ¦ æ° æ¨ æ‘ æµ æ¯ æŠ æš +- æ‘€ æ¥ æ§ æ‹ æ§ æ› æ® æ¡ æŽ æ•¯ æ–’ æ—“ 暆 暌 æš• æš +- æš‹ 暊 æš™ æš” 晸 朠 楦 楟 椸 楎 楢 楱 椿 楅 楪 椹 +- 楂 楗 楙 楺 楈 楉 椵 楬 椳 椽 楥 棰 楸 椴 楩 楀 +- 楯 楄 楶 楘 æ¥ æ¥´ 楌 椻 楋 椷 楜 æ¥ æ¥‘ 椲 楒 椯 +- 楻 椼 æ­† æ­… æ­ƒ æ­‚ æ­ˆ æ­ æ®› ï¨ æ¯» 毼 毹 毷 毸 溛 +- æ»– 滈 æº æ»€ 溟 溓 溔 溠 溱 溹 滆 æ»’ 溽 æ» æºž 滉 +- 溷 溰 æ» æº¦ æ» æº² 溾 滃 滜 滘 溙 溒 溎 æº æº¤ 溡 +- 溿 溳 æ» æ»Š 溗 溮 溣 ç…‡ ç…” ç…’ ç…£ ç…  ç… ç… ç…¢ ç…² +- ç…¸ ç…ª ç…¡ ç…‚ ç…˜ ç…ƒ ç…‹ ç…° ç…Ÿ ç… ç…“ ç…„ ç… ç…š ç‰ çŠ +- 犌 犑 çŠ çŠŽ 猼 ç‚ çŒ» 猺 ç€ çŠ ç‰ ç‘„ ç‘Š ç‘‹ ç‘’ ç‘‘ +- ç‘— ç‘€ ç‘ ç‘ ç‘Ž ç‘‚ 瑆 ç‘ ç‘” ç“¡ ç“¿ 瓾 瓽 ç” ç•¹ ç•· +- 榃 ç—¯ ç˜ ç˜ƒ ç—· ç—¾ ç—¼ ç—¹ ç—¸ ç˜ ç—» ç—¶ ç—­ ç—µ ç—½ çš™ +- çšµ ç› ç• çŸ ç  ç’ ç– çš ç© ç§ ç” ç™ ç­ çŸ  碇 碚 +- 碔 ç¢ ç¢„ 碕 碅 碆 碡 碃 硹 碙 碀 碖 ç¡» 祼 禂 祽 +- 祹 稑 稘 稙 稒 稗 稕 稢 稓 稛 ç¨ çª£ 窢 窞 ç«« ç­¦ +- ç­¤ ç­­ ç­´ ç­© ç­² ç­¥ ç­³ ç­± ç­° ç­¡ ç­¸ ç­¶ ç­£ ç²² ç²´ 粯 +- 綈 綆 綀 ç¶ çµ¿ 綅 絺 綎 çµ» 綃 çµ¼ 綌 綔 綄 çµ½ 綒 +- ç½­ 罫 罧 罨 罬 羦 ç¾¥ 羧 ç¿› ç¿œ 耡 è…¤ è…  è…· è…œ è…© +- è…› è…¢ è…² 朡 è…ž è…¶ è…§ è…¯ è…„ è…¡ èˆ è‰‰ 艄 艀 艂 艅 +- 蓱 è¿ è‘– 葶 葹 è’ è’ è‘¥ è‘‘ è‘€ è’† 葧 è° è‘ è‘½ è‘š +- è‘™ è‘´ 葳 è‘ è”‡ è‘ž è· èº è´ è‘º 葃 葸 è² è‘… è© è™ +- è‘‹ è¯ è‘‚ è­ è‘Ÿ è‘° è¹ è‘Ž è‘Œ è‘’ 葯 è“… è’Ž è» è‘‡ è¶ +- è³ è‘¨ 葾 è‘„ è« è‘  è‘” è‘® è‘ èœ‹ 蜄 è›· 蜌 蛺 è›– 蛵 +- è 蛸 蜎 蜉 èœ è›¶ èœ èœ… 裖 裋 è£ è£Ž 裞 裛 裚 裌 +- è£ è¦… 覛 觟 觥 觤 觡 觠 觢 觜 触 詶 誆 è©¿ è©¡ 訿 +- è©· 誂 誄 詵 誃 èª è©´ 詺 è°¼ 豋 豊 è±¥ 豤 豦 貆 貄 +- è²… 賌 赨 赩 趑 趌 趎 è¶ è¶ è¶“ 趔 è¶ è¶’ è·° è·  è·¬ +- è·± è·® è· è·© è·£ è·¢ è·§ è·² è·« è·´ 輆 軿 è¼ è¼€ è¼… 輇 +- 輈 輂 輋 é’ é€¿ é„ é‰ é€½ é„ é„ é„ é„‘ é„– é„” é„‹ é„Ž +- é…® é…¯ 鉈 鉒 鈰 鈺 鉦 鈳 鉥 鉞 銃 鈮 鉊 鉆 鉭 鉬 +- é‰ é‰  鉧 鉯 鈶 鉡 鉰 鈱 鉔 鉣 é‰ é‰² 鉎 鉓 鉌 鉖 +- 鈲 é–Ÿ é–œ é–ž é–› éš’ éš“ éš‘ éš— 雎 雺 雽 雸 雵 é³ é· +- é¸ é² é  é  é Ž 颬 飶 飹 馯 馲 馰 馵 骭 骫 é­› 鳪 +- é³­ 鳧 麀 黽 僦 僔 僗 僨 僳 僛 僪 åƒ åƒ¤ 僓 僬 僰 +- 僯 僣 僠 凘 劀 åŠ å‹© å‹« 匰 厬 嘧 嘕 嘌 嘒 å—¼ å˜ +- 嘜 å˜ å˜“ 嘂 å—º å˜ å˜„ å—¿ å—¹ 墉 塼 å¢ å¢˜ 墆 å¢ å¡¿ +- å¡´ 墋 塺 墇 墑 墎 塶 墂 墈 å¡» 墔 å¢ å£¾ 奫 å«œ å«® +- å«¥ å«• 嫪 å«š å«­ å«« 嫳 å«¢ å«  å«› 嫬 å«ž å« å«™ 嫨 å«Ÿ +- å­· 寠 寣 å±£ 嶂 嶀 åµ½ 嶆 嵺 å¶ åµ· 嶊 嶉 嶈 åµ¾ åµ¼ +- å¶ åµ¹ 嵿 幘 å¹™ 幓 廘 廑 å»— 廎 廜 廕 å»™ å»’ å»” 彄 +- 彃 彯 徶 愬 愨 æ… æ…ž æ…± æ…³ æ…’ æ…“ æ…² æ…¬ 憀 æ…´ æ…” +- æ…º æ…› æ…¥ æ„» æ…ª æ…¡ æ…– 戩 戧 戫 æ« æ‘ æ‘› æ‘ æ‘´ 摶 +- 摲 摳 摽 摵 摦 æ’¦ æ‘Ž æ’‚ æ‘ž æ‘œ æ‘‹ æ‘“ æ‘  æ‘ æ‘¿ æ¿ +- 摬 æ‘« æ‘™ æ‘¥ æ‘· 敳 æ–  æš¡ æš  暟 朅 朄 朢 榱 榶 槉 +- 榠 槎 榖 榰 榬 榼 榑 榙 榎 榧 æ¦ æ¦© 榾 榯 榿 槄 +- 榽 榤 槔 榹 槊 榚 æ§ æ¦³ 榓 榪 榡 榞 槙 榗 æ¦ æ§‚ +- 榵 榥 槆 æ­Š æ­ æ­‹ 殞 殟 æ®  毃 毄 毾 滎 滵 æ»± 漃 +- æ¼¥ 滸 æ¼· æ»» æ¼® 漉 潎 æ¼™ 漚 漧 漘 æ¼» æ¼’ æ»­ 漊 漶 +- æ½³ 滹 æ»® æ¼­ æ½€ æ¼° æ¼¼ æ¼µ 滫 漇 漎 潃 æ¼… 滽 滶 æ¼¹ +- 漜 滼 漺 漟 æ¼ æ¼ž 漈 漡 熇 ç† ç†‰ 熀 熅 熂 ç† ç…» +- 熆 ç† ç†— 牄 牓 犗 犕 犓 çƒ ç ç‘ çŒ ç‘¢ 瑳 瑱 瑵 +- 瑲 瑧 ç‘® 甀 甂 甃 畽 ç– ç˜– 瘈 瘌 瘕 瘑 瘊 瘔 皸 +- çž ç¼ çž… çž‚ ç® çž€ ç¯ ç¾ çžƒ 碲 碪 碴 碭 碨 硾 碫 +- 碞 碥 碠 碬 碢 碤 禘 禊 禋 禖 禕 禔 禓 禗 禈 禒 +- ç¦ ç¨« ç©Š 稰 稯 稨 稦 窨 窫 窬 ç«® 箈 箜 箊 箑 ç® +- ç®– ç® ç®Œ ç®› 箎 ç®… 箘 劄 ç®™ 箤 箂 ç²» 粿 ç²¼ 粺 綧 +- 綷 ç·‚ 綣 綪 ç· ç·€ ç·… ç¶ ç·Ž ç·„ ç·† ç·‹ ç·Œ 綯 綹 綖 +- 綼 綟 綦 綮 綩 綡 ç·‰ ç½³ ç¿¢ ç¿£ ç¿¥ ç¿ž 耤 è èœ è†‰ +- 膆 膃 膇 è† è†Œ 膋 舕 è’— è’¤ è’¡ è’Ÿ è’º è“Ž è“‚ è’¬ è’® +- è’« è’¹ è’´ è“ è“ è’ª è’š è’± è“ è’ è’§ è’» è’¢ è’” 蓇 è“Œ +- è’› è’© è’¯ è’¨ è“– è’˜ è’¶ è“ è’  è“— è“” è“’ è“› è’° è’‘ 虡 +- 蜳 蜣 蜨 è« è€ èœ® 蜞 蜡 蜙 蜛 èƒ èœ¬ è 蜾 è† èœ  +- 蜲 蜪 蜭 蜼 蜒 蜺 蜱 蜵 è‚ èœ¦ 蜧 蜸 蜤 蜚 蜰 蜑 +- 裷 裧 裱 裲 裺 裾 裮 裼 裶 裻 裰 裬 裫 è¦ è¦¡ 覟 +- 覞 觩 觫 觨 誫 誙 誋 誒 èª èª– è°½ 豨 豩 賕 è³ è³— +- 趖 踉 踂 è·¿ è¸ è·½ 踊 踃 踇 踆 踅 è·¾ 踀 踄 è¼ è¼‘ +- 輎 è¼ é„£ é„œ é„  é„¢ é„Ÿ é„ é„š 鄤 é„¡ é„› é…º é…² é…¹ é…³ +- 銥 銤 鉶 銛 鉺 銠 銔 銪 éŠ éŠ¦ 銚 銫 鉹 銗 鉿 銣 +- é‹® 銎 銂 銕 銢 鉽 銈 銡 銊 銆 銌 銙 銧 鉾 銇 銩 +- éŠ éŠ‹ 鈭 éšž éš¡ 雿 é˜ é½ éº é¾ éžƒ 鞀 éž‚ é» éž„ éž +- é¿ éŸŽ éŸ é – 颭 颮 餂 餀 餇 é¦ é¦œ 駃 馹 馻 馺 駂 +- 馽 駇 骱 é«£ 髧 鬾 鬿 é­  é­¡ é­Ÿ é³± é³² é³µ 麧 僿 儃 +- å„° 僸 儆 儇 僶 僾 å„‹ å„Œ 僽 å„Š 劋 劌 勱 勯 噈 噂 +- 噌 嘵 å™ å™Š 噉 噆 噘 噚 噀 嘳 嘽 嘬 嘾 嘸 嘪 嘺 +- 圚 墫 å¢ å¢± 墠 墣 墯 墬 墥 墡 壿 å«¿ å«´ 嫽 å«· 嫶 +- 嬃 嫸 嬂 嫹 å¬ å¬‡ 嬅 å¬ å±§ 嶙 嶗 嶟 嶒 嶢 嶓 嶕 +- 嶠 嶜 嶡 嶚 嶞 幩 å¹ å¹  幜 ç·³ å»› 廞 廡 彉 å¾² 憋 +- 憃 æ…¹ 憱 憰 憢 憉 憛 憓 憯 憭 憟 憒 憪 憡 æ† æ…¦ +- 憳 戭 æ‘® æ‘° æ’– æ’  æ’… æ’— æ’œ æ’ æ’‹ æ’Š æ’Œ æ’£ æ’Ÿ 摨 +- æ’± æ’˜ 敶 敺 敹 æ•» æ–² æ–³ æšµ æš° æš© æš² æš· 暪 暯 樀 +- 樆 樗 槥 槸 樕 槱 槤 樠 槿 槬 槢 樛 æ¨ æ§¾ 樧 槲 +- 槮 樔 槷 槧 æ©€ 樈 槦 槻 æ¨ æ§¼ 槫 樉 樄 樘 樥 æ¨ +- 槶 樦 樇 槴 樖 æ­‘ 殥 殣 殢 殦 æ° æ°€ 毿 æ°‚ æ½ æ¼¦ +- æ½¾ 澇 濆 æ¾’ æ¾ æ¾‰ 澌 æ½¢ æ½ æ¾… 潚 æ¾– 潶 潬 澂 潕 +- æ½² æ½’ æ½ æ½— æ¾” 澓 æ½ æ¼€ 潡 潫 æ½½ 潧 æ¾ æ½“ 澋 潩 +- 潿 澕 æ½£ æ½· 潪 æ½» 熲 熯 熛 熰 熠 熚 熩 熵 ç† ç†¥ +- 熞 熤 熡 熪 熜 熧 熳 犘 犚 ç˜ ç’ çž çŸ ç  ç ç› +- ç¡ çš ç™ ç¢ ç’‡ ç’‰ ç’Š ç’† ç’ ç‘½ ç’… ç’ˆ 瑼 瑹 甈 甇 +- 畾 瘥 瘞 瘙 ç˜ ç˜œ 瘣 瘚 瘨 瘛 çšœ çš çšž çš› çž çž +- 瞉 瞈 ç£ ç¢» ç£ ç£Œ 磑 磎 磔 磈 磃 磄 磉 禚 禡 禠 +- 禜 禢 禛 æ­¶ 稹 窲 窴 窳 ç®· 篋 箾 箬 篎 箯 箹 篊 +- 箵 ç³… 糈 糌 糋 ç·· ç·› ç·ª ç·§ ç·— ç·¡ 縃 ç·º ç·¦ ç·¶ ç·± +- ç·° ç·® ç·Ÿ 罶 羬 ç¾° ç¾­ ç¿­ ç¿« 翪 翬 翦 翨 è¤ è§ è†£ +- 膟 膞 膕 膢 膙 膗 舖 è‰ è‰“ 艒 è‰ è‰Ž 艑 蔤 è”» è” +- 蔀 蔩 蔎 蔉 è” è”Ÿ 蔊 蔧 蔜 è“» 蔫 蓺 蔈 蔌 è“´ 蔪 +- 蓲 蔕 è“· è“« 蓳 蓼 è”’ 蓪 è“© è”– 蓾 蔨 è” è”® 蔂 蓽 +- 蔞 蓶 è”± 蔦 蓧 蓨 è“° 蓯 蓹 蔘 è”  è”° 蔋 è”™ 蔯 虢 +- è– è£ è¤ è· èŸ¡ è³ è˜ è” è› è’ è¡ èš è‘ èž è­ èª +- è èŽ èŸ è è¯ è¬ èº è® èœ è¥ è è» èµ è¢ è§ è© +- è¡š 褅 褌 褔 褋 褗 褘 褙 褆 褖 褑 褎 褉 覢 覤 覣 +- 觭 觰 觬 è« è«† 誸 è«“ è«‘ è«” è«• 誻 è«— 誾 è«€ è«… 諘 +- 諃 誺 誽 è«™ è°¾ è± è² è³¥ 賟 è³™ 賨 賚 è³ è³§ 趠 趜 +- 趡 趛 踠 踣 踥 踤 踮 踕 踛 踖 踑 踙 踦 踧 踔 踒 +- 踘 踓 踜 踗 踚 輬 輤 輘 輚 è¼  è¼£ è¼– è¼— é³ é° é¯ +- é§ é« é„¯ é„« é„© 鄪 鄲 鄦 é„® 醅 醆 醊 é† é†‚ 醄 醀 +- é‹ é‹ƒ é‹„ é‹€ é‹™ 銶 é‹ é‹± é‹Ÿ 鋘 é‹© é‹— é‹ é‹Œ 鋯 é‹‚ +- 鋨 é‹Š 鋈 é‹Ž 鋦 é‹ é‹• 鋉 é‹  é‹ž 鋧 é‹‘ é‹“ 銵 é‹¡ 鋆 +- 銴 镼 é–¬ é–« é–® é–° 隤 隢 雓 霅 霈 霂 éš éžŠ 鞎 鞈 +- éŸ éŸ é ž é  é ¦ é © é ¨ é   é › é § 颲 餈 飺 餑 餔 餖 +- 餗 餕 駜 é§ é§ é§“ 駔 駎 駉 駖 駘 駋 駗 駌 骳 髬 +- é«« 髳 髲 髱 é­† é­ƒ é­§ é­´ é­± é­¦ é­¶ é­µ é­° é­¨ é­¤ é­¬ +- é³¼ 鳺 é³½ 鳿 é³· é´‡ é´€ é³¹ é³» é´ˆ é´… é´„ 麃 黓 é¼ é¼ +- å„œ å„“ å„— å„š å„‘ 凞 匴 å¡ å™° å™  å™® 噳 噦 噣 å™­ 噲 +- 噞 å™· 圜 圛 壈 墽 壉 墿 墺 壂 墼 壆 嬗 嬙 嬛 嬡 +- 嬔 嬓 å¬ å¬– 嬨 嬚 嬠 嬞 寯 嶬 嶱 嶩 嶧 嶵 嶰 嶮 +- 嶪 嶨 嶲 嶭 嶯 嶴 幧 幨 幦 幯 廩 廧 廦 廨 廥 彋 +- å¾¼ æ† æ†¨ 憖 懅 憴 懆 æ‡ æ‡Œ 憺 憿 憸 憌 æ“— æ“– æ“ +- æ“ æ“‰ æ’½ æ’‰ 擃 æ“› 擳 æ“™ 攳 æ•¿ 敼 æ–¢ 曈 æš¾ 曀 曊 +- 曋 æ› æš½ æš» 暺 曌 朣 樴 橦 橉 橧 樲 橨 樾 æ© æ©­ +- 橶 æ©› æ©‘ 樨 æ©š 樻 樿 æ© æ©ª 橤 æ© æ© æ©” 橯 æ©© æ©  +- 樼 æ©ž æ©– æ©• æ© æ©Ž 橆 æ­• æ­” æ­– 殧 殪 殫 毈 毇 æ°„ +- æ°ƒ æ°† æ¾­ æ¿‹ æ¾£ 濇 æ¾¼ æ¿Ž 濈 潞 æ¿„ æ¾½ 澞 æ¿Š 澨 瀄 +- æ¾¥ æ¾® 澺 澬 澪 æ¿ æ¾¿ 澸 æ¾¢ 濉 澫 æ¿ æ¾¯ æ¾² æ¾° 燅 +- 燂 熿 熸 燖 燀 ç‡ ç‡‹ 燔 燊 燇 ç‡ ç†½ 燘 熼 燆 燚 +- 燛 çŠ çŠž ç© ç¦ ç§ ç¬ ç¥ ç« çª ç‘¿ ç’š ç’  ç’” ç’’ ç’• +- ç’¡ 甋 ç–€ 瘯 瘭 瘱 瘽 瘳 瘼 瘵 瘲 瘰 çš» 盦 çžš çž +- çž¡ çžœ çž› 瞢 瞣 çž• çž™ çž— ç£ ç£© 磥 磪 磞 磣 磛 磡 +- 磢 磭 磟 磠 禤 ç©„ 穈 穇 窶 窸 窵 窱 窷 篞 篣 篧 +- ç¯ ç¯• 篥 篚 篨 篹 篔 篪 篢 篜 篫 篘 篟 ç³’ ç³” ç³— +- ç³ ç³‘ 縒 縡 縗 縌 縟 縠 縓 縎 縜 縕 縚 縢 縋 ç¸ +- 縖 ç¸ ç¸” 縥 縤 罃 ç½» ç½¼ 罺 ç¾± 翯 耪 耩 è¬ è†± 膦 +- 膮 膹 膵 膫 膰 膬 膴 膲 膷 膧 臲 艕 艖 艗 è•– è•… +- è•« è• è•“ è•¡ 蕘 è•€ 蕆 蕤 è• è•¢ è•„ è•‘ 蕇 è•£ 蔾 è•› +- 蕱 è•Ž è•® 蕵 è•• 蕧 è•  è–Œ 蕦 è• è•” è•¥ 蕬 虣 虥 虤 +- èž› èž èž— èž“ èž’ 螈 èž èž– 螘 è¹ èž‡ 螣 èž… èž èž‘ èž +- èž„ èž” èžœ èžš 螉 褞 褦 褰 褭 褮 褧 褱 褢 褩 褣 褯 +- 褬 褟 觱 è«  è«¢ 諲 è«´ 諵 è« è¬” 諤 è«Ÿ è«° 諈 è«ž è«¡ +- 諨 è«¿ 諯 è«» 貑 è²’ è² è³µ è³® è³± è³° è³³ 赬 èµ® 趥 趧 +- 踳 踾 踸 è¹€ è¹… 踶 踼 踽 è¹ è¸° 踿 躽 輶 è¼® è¼µ è¼² +- è¼¹ è¼· è¼´ é¶ é¹ é» é‚† 郺 鄳 鄵 鄶 醓 é† é†‘ é† é† +- 錧 錞 錈 錟 錆 éŒ éº éŒ¸ 錼 錛 錣 錒 éŒ é† éŒ­ 錎 +- éŒ é‹‹ éŒ é‹º 錥 錓 鋹 é‹· 錴 錂 錤 é‹¿ 錩 錹 錵 錪 +- 錔 錌 錋 鋾 錉 錀 é‹» 錖 é–¼ é— é–¾ é–¹ é–º é–¶ é–¿ é–µ +- é–½ éš© é›” 霋 霒 éœ éž™ éž— éž” 韰 韸 é µ é ¯ é ² 餤 餟 +- 餧 餩 馞 駮 駬 駥 駤 駰 駣 駪 駩 駧 骹 骿 骴 骻 +- 髶 髺 髹 é«· 鬳 鮀 é®… 鮇 é­¼ é­¾ é­» 鮂 鮓 é®’ é® é­º +- 鮕 é­½ 鮈 é´¥ é´— é´  é´ž é´” é´© é´ é´˜ é´¢ é´ é´™ é´Ÿ 麈 +- 麆 麇 麮 麭 黕 é»– 黺 é¼’ é¼½ 儦 å„¥ å„¢ 儤 å„  å„© å‹´ +- åš“ 嚌 åš åš† åš„ 嚃 噾 åš‚ 噿 åš å£– 壔 å£ å£’ 嬭 嬥 +- 嬲 嬣 嬬 嬧 嬦 嬯 嬮 å­» 寱 寲 嶷 幬 幪 å¾¾ å¾» 懃 +- 憵 憼 懧 懠 懥 懤 懨 懞 擯 æ“© æ“£ æ“« 擤 擨 æ– æ–€ +- æ–¶ æ—š æ›’ æª æª– æª æª¥ 檉 檟 檛 檡 檞 檇 檓 檎 檕 +- 檃 檨 檤 檑 æ©¿ 檦 檚 檅 檌 檒 æ­› æ®­ æ°‰ æ¿Œ 澩 æ¿´ +- æ¿” æ¿£ æ¿œ æ¿­ 濧 濦 æ¿ž 濲 æ¿ æ¿¢ 濨 燡 燱 燨 燲 燤 +- 燰 燢 ç³ ç® ç¯ ç’— ç’² ç’« ç’ ç’ª ç’­ ç’± ç’¥ ç’¯ ç” ç”‘ +- ç”’ ç” ç–„ 癃 癈 癉 癇 皤 盩 çžµ çž« çž² çž· 瞶 çž´ çž± +- 瞨 矰 磳 磽 礂 磻 磼 磲 礅 磹 磾 礄 禫 禨 ç©œ ç©› +- ç©– 穘 ç©” ç©š 窾 ç«€ ç« ç°… ç° ç¯² ç°€ 篿 篻 ç°Ž 篴 ç°‹ +- 篳 ç°‚ ç°‰ ç°ƒ ç° ç¯¸ 篽 ç°† 篰 篱 ç° ç°Š 糨 縭 縼 繂 +- 縳 顈 縸 縪 繉 ç¹€ 繇 縩 繌 縰 縻 縶 繄 縺 ç½… 罿 +- ç½¾ ç½½ ç¿´ 翲 耬 膻 臄 臌 臊 臅 臇 膼 臩 艛 艚 艜 +- è–ƒ è–€ è– è–§ è–• è–  è–‹ è–£ è•» è–¤ è–š è–ž è•· 蕼 è–‰ è–¡ +- 蕺 蕸 è•— è–Ž è–– è–† è– è–™ è– è– è–¢ è–‚ è–ˆ è–… 蕹 蕶 +- è–˜ è– è–Ÿ 虨 èž¾ 螪 èž­ 蟅 èž° 螬 èž¹ èžµ èž¼ èž® 蟉 蟃 +- 蟂 蟌 èž· 螯 蟄 蟊 èž´ 螶 èž¿ 螸 èž½ 蟞 èž² 褵 褳 褼 +- 褾 è¥ è¥’ 褷 襂 覭 覯 覮 觲 觳 謞 謘 謖 謑 謅 謋 +- 謢 è¬ è¬’ 謕 謇 è¬ è¬ˆ 謆 謜 謓 謚 è± è±° è±² è±± 豯 +- 貕 è²” è³¹ 赯 蹎 è¹ è¹“ è¹ è¹Œ 蹇 轃 è½€ é‚… é¾ é„¸ 醚 +- 醢 醛 醙 醟 醡 é† é†  鎡 鎃 鎯 é¤ é– é‡ é¼ é˜ éœ +- é¶ é‰ é é‘ é  é­ éŽ éŒ éª é¹ é— é• é’ é é± é· +- é» é¡ éž é£ é§ éŽ€ éŽ é™ é—‡ é—€ é—‰ é—ƒ é—… é–· éš® éš° +- 隬 霠 霟 霘 éœ éœ™ éžš éž¡ éžœ éžž éž éŸ• 韔 韱 é¡ é¡„ +- é¡Š 顉 é¡… 顃 餥 餫 餬 餪 餳 餲 餯 餭 餱 餰 馘 馣 +- 馡 騂 駺 駴 駷 駹 駸 駶 駻 駽 駾 駼 騃 骾 髾 髽 +- é¬ é«¼ é­ˆ 鮚 鮨 鮞 é®› 鮦 鮡 鮥 鮤 鮆 鮢 é®  鮯 é´³ +- éµ éµ§ é´¶ é´® é´¯ é´± é´¸ é´° éµ… 鵂 鵃 é´¾ é´· éµ€ é´½ 翵 +- é´­ 麊 麉 éº éº° 黈 黚 é»» 黿 鼤 é¼£ é¼¢ é½” é¾  儱 å„­ +- å„® 嚘 åšœ åš— åšš åš åš™ 奰 嬼 屩 屪 å·€ å¹­ å¹® 懘 懟 +- 懭 懮 懱 懪 懰 懫 懖 懩 æ“¿ 攄 擽 擸 æ” æ”ƒ 擼 æ–” +- æ—› 曚 æ›› 曘 æ«… 檹 檽 æ«¡ 櫆 檺 檶 檷 櫇 檴 檭 æ­ž +- 毉 æ°‹ 瀇 瀌 ç€ ç€ ç€… 瀔 瀎 æ¿¿ 瀀 æ¿» 瀦 濼 æ¿· 瀊 +- çˆ ç‡¿ 燹 爃 燽 ç¶ ç’¸ ç“€ ç’µ ç“ ç’¾ ç’¶ ç’» ç“‚ ç”” 甓 +- 癜 癤 ç™™ ç™ ç™“ ç™— 癚 皦 çš½ 盬 矂 瞺 磿 礌 礓 礔 +- 礉 ç¤ ç¤’ 礑 禭 禬 ç©Ÿ ç°œ ç°© ç°™ ç°  ç°Ÿ ç°­ ç° ç°¦ ç°¨ +- ç°¢ ç°¥ ç°° 繜 ç¹ ç¹– ç¹£ 繘 ç¹¢ 繟 繑 ç¹  ç¹— 繓 ç¾µ ç¾³ +- ç¿· 翸 èµ è‡‘ 臒 è‡ è‰Ÿ 艞 è–´ è—† è—€ è—ƒ è—‚ è–³ è–µ è–½ +- è—‡ è—„ è–¿ è—‹ è—Ž è—ˆ è—… è–± è–¶ è—’ 蘤 è–¸ è–· è–¾ 虩 蟧 +- 蟦 蟢 蟛 蟫 蟪 蟥 蟟 蟳 蟤 蟔 蟜 蟓 蟭 蟘 蟣 螤 +- 蟗 蟙 è  èŸ´ 蟨 èŸ è¥“ 襋 è¥ è¥Œ 襆 è¥ è¥‘ 襉 謪 謧 +- 謣 謳 謰 謵 è­‡ 謯 謼 謾 謱 謥 謷 謦 謶 謮 謤 謻 +- 謽 謺 豂 è±µ è²™ 貘 è²— è³¾ è´„ è´‚ è´€ 蹜 è¹¢ è¹  è¹— è¹– +- 蹞 è¹¥ 蹧 è¹› 蹚 蹡 è¹ è¹© è¹” 轆 轇 轈 轋 鄨 鄺 é„» +- 鄾 醨 醥 醧 醯 醪 鎵 鎌 鎒 鎷 鎛 éŽ éŽ‰ 鎧 鎎 鎪 +- 鎞 鎦 鎕 鎈 鎙 鎟 éŽ éŽ± 鎑 鎲 鎤 鎨 鎴 鎣 鎥 é—’ +- é—“ é—‘ éš³ é›— 雚 å·‚ 雟 雘 é› éœ£ 霢 霥 鞬 éž® 鞨 éž« +- 鞤 鞪 鞢 鞥 韗 韙 韖 韘 韺 é¡ é¡‘ é¡’ 颸 é¥ é¤¼ 餺 +- é¨ é¨‹ 騉 é¨ é¨„ 騑 騊 騅 騇 騆 é«€ é«œ 鬈 鬄 鬅 鬩 +- 鬵 é­Š é­Œ é­‹ 鯇 鯆 鯃 鮿 é¯ é®µ 鮸 鯓 鮶 鯄 鮹 鮽 +- 鵜 鵓 éµ éµŠ éµ› 鵋 éµ™ éµ– 鵌 éµ— éµ’ éµ” 鵟 鵘 鵚 麎 +- 麌 黟 é¼ é¼€ é¼– é¼¥ 鼫 鼪 鼩 鼨 齌 齕 å„´ 儵 劖 å‹· +- 厴 åš« åš­ 嚦 嚧 嚪 嚬 壚 å£ å£› 夒 嬽 嬾 嬿 å·ƒ å¹° +- 徿 懻 攇 æ” æ” æ”‰ 攌 攎 æ–„ æ—ž æ— æ›ž 櫧 æ«  æ«Œ æ«‘ +- æ«™ æ«‹ æ«Ÿ æ«œ æ« æ«« æ« æ« æ«ž æ­  æ®° æ°Œ 瀙 瀧 瀠 瀖 +- 瀫 瀡 瀢 瀣 瀩 瀗 瀤 瀜 瀪 爌 爊 爇 爂 爅 犥 犦 +- 犤 犣 犡 ç“‹ ç“… ç’· 瓃 ç”– ç™  矉 矊 矄 矱 ç¤ ç¤› 礡 +- 礜 礗 礞 禰 穧 穨 ç°³ ç°¼ ç°¹ ç°¬ ç°» 糬 糪 繶 ç¹µ 繸 +- ç¹° ç¹· 繯 繺 ç¹² ç¹´ 繨 罋 罊 羃 羆 ç¾· 翽 翾 è¸ è‡— +- 臕 艤 艡 艣 è—« è—± è—­ è—™ è—¡ è—¨ è—š è—— è—¬ è—² è—¸ è—˜ +- è—Ÿ è—£ è—œ è—‘ è—° è—¦ è—¯ è—ž è—¢ è € 蟺 è ƒ 蟶 蟷 è ‰ è Œ +- è ‹ è † 蟼 è ˆ 蟿 è Š è ‚ 襢 襚 襛 襗 襡 襜 襘 è¥ è¥™ +- 覈 覷 覶 觶 è­ è­ˆ è­Š è­€ è­“ è­– è­” è­‹ è­• è­‘ è­‚ è­’ +- è­— 豃 è±· 豶 貚 è´† è´‡ è´‰ 趬 趪 趭 趫 è¹­ 蹸 è¹³ 蹪 +- 蹯 è¹» 軂 è½’ 轑 è½ è½ è½“ è¾´ é…€ é„¿ 醰 醭 éž é‡ é +- é‚ éš é é¹ é¬ éŒ é™ éŽ© é¦ éŠ é” é® é£ é• é„ éŽ +- é€ é’ é§ é•½ é—š é—› 雡 霩 霫 霬 霨 霦 éž³ éž· 鞶 éŸ +- 韞 韟 é¡œ é¡™ é¡ é¡— 颿 颽 颻 颾 饈 饇 饃 馦 馧 騚 +- 騕 騥 é¨ é¨¤ 騛 騢 騠 騧 騣 騞 騜 騔 é«‚ 鬋 鬊 鬎 +- 鬌 鬷 鯪 鯫 鯠 鯞 鯤 鯦 鯢 鯰 鯔 鯗 鯬 鯜 鯙 鯥 +- 鯕 鯡 鯚 éµ· é¶ é¶Š 鶄 鶈 éµ± 鶀 鵸 鶆 鶋 鶌 éµ½ 鵫 +- éµ´ éµµ éµ° 鵩 鶅 éµ³ éµ» 鶂 鵯 éµ¹ 鵿 鶇 鵨 麔 麑 黀 +- 黼 é¼­ é½€ é½ é½ é½– é½— 齘 匷 åš² åšµ åš³ 壣 å­… å·† å·‡ +- å»® 廯 å¿€ å¿ æ‡¹ æ”— æ”– 攕 攓 æ—Ÿ 曨 曣 曤 櫳 æ«° 櫪 +- 櫨 櫹 櫱 æ«® 櫯 瀼 瀵 瀯 瀷 瀴 瀱 ç‚ ç€¸ 瀿 瀺 瀹 +- ç€ ç€» 瀳 ç 爓 爔 犨 ç½ ç¼ ç’º çš« 皪 çš¾ ç›­ 矌 矎 +- çŸ çŸ çŸ² 礥 礣 礧 礨 礤 礩 禲 ç©® 穬 ç©­ ç«· 籉 籈 +- 籊 籇 ç±… ç³® ç¹» ç¹¾ çº çº€ 羺 ç¿¿ è¹ è‡› 臙 舋 艨 艩 +- 蘢 è—¿ è˜ è—¾ 蘛 蘀 è—¶ 蘄 蘉 蘅 蘌 è—½ è ™ è  è ‘ è — +- è “ è – 襣 襦 覹 觷 è­  è­ª è­ è­¨ è­£ è­¥ è­§ è­­ 趮 躆 +- 躈 躄 è½™ è½– è½— 轕 轘 轚 é‚ é…ƒ é… é†· 醵 醲 醳 é‹ +- é“ é» é  é é” é¾ é• é é¨ é™ é éµ é€ é· é‡ éŽ +- é– é’ éº é‰ é¸ éŠ é¿ é¼ éŒ é¶ é‘ é† é—ž é—  é—Ÿ 霮 +- 霯 éž¹ éž» 韽 韾 é¡  é¡¢ é¡£ é¡Ÿ é£ é£‚ é¥ é¥Ž 饙 饌 饋 +- 饓 騲 騴 騱 騬 騪 騶 騩 騮 騸 騭 髇 é«Š 髆 é¬ é¬’ +- 鬑 é°‹ é°ˆ 鯷 é°… é°’ 鯸 é±€ é°‡ é°Ž é°† é°— é°” é°‰ 鶟 鶙 +- 鶤 é¶ é¶’ 鶘 é¶ é¶› 鶠 鶔 鶜 鶪 鶗 鶡 鶚 鶢 鶨 鶞 +- 鶣 鶿 鶩 鶖 鶦 鶧 麙 麛 麚 黥 黤 黧 黦 é¼° é¼® é½› +- é½  齞 é½ é½™ 龑 儺 儹 劘 劗 囃 åš½ åš¾ å­ˆ å­‡ å·‹ å· +- å»± 懽 æ”› 欂 櫼 欃 櫸 欀 çƒ ç„ çŠ çˆ ç‰ ç… ç† çˆ +- 爚 爙 ç¾ ç”— 癪 çŸ ç¤­ 礱 礯 ç±” 籓 ç³² 纊 纇 纈 纋 +- 纆 çº ç½ ç¾» 耰 è‡ è˜˜ 蘪 蘦 蘟 蘣 蘜 蘙 蘧 蘮 蘡 +- 蘠 蘩 蘞 蘥 è © è  è › è   è ¤ è œ è « è¡Š 襭 襩 襮 襫 +- 觺 è­¹ è­¸ è­… è­º è­» è´ è´” 趯 躎 躌 轞 è½› è½ é…† é…„ +- é…… 醹 é¿ é» é¶ é© é½ é¼ é° é¹ éª é· é¬ é‘€ é± é—¥ +- é—¤ é—£ 霵 霺 éž¿ 韡 顤 飉 飆 飀 饘 饖 騹 騽 驆 é©„ +- é©‚ é© é¨º 騿 é« é¬• 鬗 鬘 鬖 鬺 é­’ é°« é° é°œ é°¬ é°£ +- é°¨ é°© é°¤ é°¡ 鶷 鶶 鶼 é· é·‡ é·Š é· é¶¾ é·… é·ƒ 鶻 鶵 +- é·Ž 鶹 鶺 鶬 é·ˆ 鶱 鶭 é·Œ 鶳 é· é¶² 鹺 麜 黫 é»® é»­ +- é¼› 鼘 鼚 é¼± 齎 é½¥ 齤 é¾’ 亹 囆 å›… 囋 奱 å­‹ å­Œ å·• +- å·‘ 廲 攡 æ”  攦 攢 欋 欈 欉 æ° ç• ç– ç— ç’ çˆž 爟 +- 犩 ç¿ ç“˜ ç“• ç“™ ç“— ç™­ çš­ 礵 禴 ç©° 穱 ç±— 籜 ç±™ ç±› +- 籚 ç³´ ç³± 纑 ç½ ç¾‡ 臞 艫 蘴 蘵 蘳 蘬 蘲 蘶 è ¬ è ¨ +- è ¦ è ª è ¥ 襱 覿 覾 觻 è­¾ 讄 讂 讆 è®… è­¿ è´• 躕 躔 +- 躚 躒 èº èº– 躗 è½  è½¢ é…‡ é‘Œ é‘ é‘Š é‘‹ é‘ é‘‡ é‘… 鑈 +- 鑉 鑆 霿 韣 顪 é¡© 飋 饔 饛 é©Ž é©“ é©” é©Œ é© é©ˆ é©Š +- 驉 é©’ é© é« é¬™ 鬫 鬻 é­– é­• 鱆 鱈 é°¿ 鱄 é°¹ é°³ é± +- é°¼ é°· é°´ é°² é°½ é°¶ é·› é·’ é·ž é·š é·‹ é· é·œ é·‘ é·Ÿ é·© +- é·™ é·˜ é·– é·µ é·• é· éº¶ é»° é¼µ é¼³ é¼² 齂 齫 龕 é¾¢ 儽 +- 劙 壨 壧 奲 å­ å·˜ è ¯ å½ æˆ æˆƒ 戄 攩 攥 æ–– 曫 欑 +- 欒 æ¬ æ¯Š ç› çš çˆ¢ 玂 çŽ çŽƒ ç™° 矔 籧 籦 纕 艬 蘺 +- 虀 蘹 蘼 蘱 蘻 蘾 è ° è ² è ® è ³ 襶 襴 襳 觾 讌 讎 +- 讋 讈 è±… è´™ 躘 轤 è½£ 醼 é‘¢ é‘• é‘ é‘— é‘ž 韄 韅 é € +- é©– é©™ 鬞 鬟 鬠 é±’ 鱘 é± é±Š é± é±‹ 鱕 é±™ 鱌 鱎 é·» +- é·· é·¯ é·£ é·« é·¸ é·¤ é·¶ é·¡ é·® é·¦ é·² é·° é·¢ é·¬ é·´ é·³ +- é·¨ é·­ 黂 é» é»² 黳 鼆 鼜 鼸 é¼· 鼶 齃 é½ é½± é½° é½® +- 齯 囓 å› å­Ž å±­ æ”­ æ›­ æ›® 欓 çŸ ç¡ ç ç  çˆ£ ç“› ç“¥ +- 矕 礸 禷 禶 籪 纗 羉 艭 虃 è ¸ è · è µ è¡‹ è®” 讕 躞 +- 躟 躠 èº é†¾ 醽 釂 é‘« 鑨 é‘© 雥 é† éƒ é‡ éŸ‡ 韥 é©ž +- é«• é­™ é±£ 鱧 鱦 é±¢ 鱞 é±  鸂 é·¾ 鸇 鸃 鸆 鸅 鸀 é¸ +- 鸉 é·¿ é·½ 鸄 麠 鼞 齆 é½´ é½µ 齶 å›” æ”® æ–¸ 欘 欙 欗 +- 欚 ç¢ çˆ¦ 犪 矘 矙 礹 籩 籫 糶 纚 纘 纛 纙 臠 臡 +- 虆 虇 虈 襹 襺 襼 襻 觿 讘 è®™ 躥 躤 躣 é‘® é‘­ 鑯 +- 鑱 鑳 é‰ é¡² 饟 鱨 é±® é±­ 鸋 é¸ é¸ é¸ é¸’ 鸑 麡 黵 +- 鼉 齇 齸 é½» 齺 é½¹ 圞 ç¦ ç±¯ è ¼ 趲 躦 釃 é‘´ 鑸 鑶 +- 鑵 é©  é±´ é±³ é±± é±µ 鸔 鸓 黶 鼊 龤 ç¨ ç¥ ç³· 虪 è ¾ +- è ½ è ¿ 讞 貜 躩 軉 é‹ é¡³ é¡´ 飌 饡 馫 驤 驦 驧 鬤 +- 鸕 鸗 齈 戇 欞 爧 虌 躨 é’‚ é’€ é’ é©© 驨 鬮 鸙 爩 +- 虋 讟 é’ƒ é±¹ 麷 癵 é©« 鱺 é¸ ç© çª éº¤ é½¾ 齉 龘 ç¢ +- 銹 è£ å¢» æ’ ç²§ 嫺 â•” ╦ â•— â•  ╬ â•£ â•š â•© â• â•’ +- ╤ â•• â•ž ╪ â•¡ ╘ ╧ â•› â•“ â•¥ â•– â•Ÿ â•« â•¢ â•™ ╨ +- â•œ â•‘ â• â•­ â•® â•° ╯ ï¿­ 𠕇 é‹› ð —Ÿ  è•Œ 䊵 ç¯ å†µ +- 㙉 𤥂 𨧤 é„ ð¡§› è‹® 𣳈 ç ¼ æ„ æ‹Ÿ 𤤳 𨦪 ð Š  𦮳 𡌅 侫 +-  倈 𦴩  𣘀 𤪱 𢔓 𠾠徤 𠎀 ð ‡ æ»› ð Ÿ å„ ã‘º å„Ž +- 顬 ãƒ è– î€­ ð ’‡ å…  𣎴 å…ª 𠯿 𢃼 ð ‹¥ 𢔰 ð –Ž 𣈳  宂 +- è½ ð –³ 𣲙 冲 冸 é´´ 凉 å‡ å‡‘ 㳜 凓 𤪦 决 凢 å‚ å‡­ +- è 椾 îŒ å½» 刋 刦 刼 劵 剗 劔 効 å‹… ç°• è•‚ å‹  è˜ +- îš ð¨«ž 啉 æ»™ 𣾀 ð ¥” 𣿬 匳 𠯢 泋 𡜦 æ › ç• æŠ ãºª 㣌 +- 𡛨 ç‡ ä’¢ å­ å´ ð¨š« å¾ ð¡–– 𡘓 矦 厓 𨪛 厠 厫 厮 玧 +- 𥲠㽙 玜 å å… æ±‰ 义 埾 å™ ãª« ð ® å  ð£¿« 𢶣 å¶ ð ±· +- å“ ç¹ å”« æ™— æµ› å‘­ 𦭓 î‚” å• å’ å’¤ 䞦 î‚™ î‚š 㶴 ð µ +- 𨦼 𢚘 啇 ä³­ å¯ ç— å–† å–© ð¡£— 𤀺 ä•’ 𤵠暳 ð¡‚´ 嘷 æ› +- 𣊊 暤 æš­ å™ å™ ç£± å›± 鞇 å¾ åœ€ 囯 å›­ 𨭦 㘣 ð¡‰ å† +- 𤆥 æ±® ç‚‹ å‚ ãš± 𦱾 埦  å ƒ ð¡‘” 𤣠堦 𤯵 å¡œ 墪 ã•¡ +- 壠 壜 îƒ å£» 寿 åƒ ðª… ð¤‰¸ é“ ã–¡ 够 梦 㛃 æ¹™ 𡘾 娤 +- å•“ ð¡š’ è”… 姉 𠵎 𦲠𦴪 ð¡Ÿœ 姙 ð¡Ÿ» ð¡ž² 𦶦 æµ± ð¡ ¨ ð¡›• 姹 +- 𦹅 媫 å©£ 㛦  㜈 媖 ç‘¥ å«“ 𦾡  㶅 𡤑 㜲  広 +- å‹ å­¶ æ–ˆ å­¼ 𧨎 䀄 ä¡ î„† 寕 æ…   î„Š ð –¥ 寳 å® ä´ +- å°… ð¡­„ å°“ çŽ å°” 𡲥 𦬨 屉 ä£ å²… 峩 峯 嶋 ð¡·¹ 𡸷 å´ +- å´˜ 嵆 𡺤 岺 å·— 苼 ã ­ 𤤠𢉠𢅳 芇 ã ¶ 㯂 帮 檊 幺 +- î„° 𠳓 厦 亷 厨 𡱠帉 å»´ 𨒂 廹 å»» 㢠 廼 æ ¾ é› å¼ +- 𠇠弢 ã«ž 䢮 𡌺 强 𦢈 ð¢ 𢑱 å½£ éž½ 𦹮 å½² é€ î… å¾§ +- 嶶 㵟 î…” 𡽪 𧃸 𢙨 釖 ð Šž 𨨩 怱 æš… î… ã¥£ ã·‡ 㘹 åž +- 𢞴 祱 ã¹€ æ‚ž 悳 î…¨ 𤦠 ç’¤ 僡 媠 æ…¤ è¤ æ…‚ î…± 𦻒 +- æ† å‡´ î…µ 憇 宪 𣾷 𢡟 懓 ð¨® ð©¥ æ‡ ã¤² 𢦀 𢣠怣 æ…œ +- 攞 掋 𠄘 æ‹… ð¡° æ‹• ð¢¸ æ¬ ð¤§Ÿ 㨗 æ¸ æ¸ î† ð¡Ÿ¼ 澊 𢸶 +- é ” 𤂌 𥜠擡 æ“¥ é‘» 㩦 æº ã©— æ• æ¼– 𤨨 𤨣 æ–… æ•­ æ•Ÿ +- 𣾠斵 𤥀 䬷 æ—‘ 䃘 ð¡ © æ—  æ—£ å¿Ÿ 𣀠昘 𣇷 𣇸 晄 𣆤 +- 𣆥 晋 ð ¹µ 晧 𥇦 晳  𣈱 𨗴 𣇈 𥌓 矅 𢣷 馤 朂 𤎜 +- 𤨡 㬫 槺 𣟂 æ§ æ¢ î‡Œ î‡ æŸ— ä“© æ ¢ æ¹ éˆ¼ æ  ð£¦ ð¦¶  +- æ¡ î‡— 槡 樋 𨫟 楳 棃 ð£— æ¤ æ¤€ ã´² 㨠𣘼 㮀 枬 楡 +- 𨩊 䋼 椶 榘 㮡 ð ‰ è£ å‚ æ§¹  𢄪 æ©…  æª ã¯³ æž± +- 櫈 𩆜 ã° æ¬ î‡º 惞 欵 æ­´  溵 𣫛 𠎵  ã€ å¡ ð£­š +- 毡 𣻼 毜 æ°· 𢒋  𦭑 汚 舦 æ±¹ 𣶼 ä“… 𣶽 𤆤 𤤌 𤤀 +- 𣳉 㛥 㳫  鮃 𣇹  ç¾ æ · 𦴥 𦶡 𦷫 涖 浜 æ¹¼ 漄 +- 𤥿  𦹲 蔳 𦽴 凇 è® ð¨¬¡ 𣸯 ç‘“ 𣾂 秌 æ¹ åª‘ 𣋠濸 +- ãœ æ¾ ð£¸° 滺 ð¡’— 𤀽 ä•• é° æ½„ 潜 㵎 æ½´  ã´» 澟 𤅄 +- æ¿“  𤅕 𤀹 𥴠  𤄿 凟 𤅖 𤅗 𤅀 ð¦‡ ç‹ ç¾ ç‚§ ç‚ +- 烌 烕 烖 烟 ä„„ ã·¨ 熴 熖 𤉷 ç„« ç…… 媈 ç…Š 岜 ð¤¥ ç… +- é¢ î‰« 焬 𤑚 𤨧 𤨢 熺 𨯨 炽 爎 é‘‚ 爕 夑 鑃 爤 é +-  爮 牀 𤥴 梽 牕 牗 㹕  æ  æ¼½ 犂 猫 𤠣 𨠫 䣭 +- 𨠄 猨 献 ç 玪 îŠ ð¦¨® ç‰ ç‘‰ 𤇢 𡛧 𤨤 昣 ã›… 𤦷 𤦠+-  ç· ç• æ¤ƒ 𤨦 ç¹ îŠ¡ ã»— 𢢭 ç‘  𨺲 瑇 ç¤ ç‘¶ 莹 瑬 +- 㜰 ç‘´ é± æ¨¬ ç’‚ 䥓  𤅟 𤩹 𨮠孆  𡢞 瓈 𡦈 甎 +- 甞 𨻙 ð¡©‹ 寗 î‹ éŽ… ç• ç•Š 畧 ç•® 𤾂 㼄  ç–Ž ç‘ ç–ž +- ç–´ 瘂 瘬 癑 ç™ ç™¯ 癶 î‹” çš è‡¯ 㟸 𦤑 𦤎 çš¡ 皥 çš· +- 盌 𦾟 è‘¢ 𥂠𥅽 î‹¢ 眞 眦 ç€ æ’¯ 𥈠 ç˜ ð£Š¬ 瞯 î‹«  +- 𡛠矴 î‹°  棊 碯 磇 磓 隥 礮 𥗠 磗 礴 碱 𧘌 辸 +- 袄 𨬫  𢘜 禆 褀 椂 禀 𥡗 ç¦ ð§¬¹ 礼 禩 渪 𧄦 㺨 +- 秆 𩄠秔 ++ ä° ä°² 䘃 ä–¦ 䕸 𧉧 äµ· ä–³ 𧲱 ä³¢ 𧳅 㮕 䜶 ä„ ä±‡ ä±€ ++ 𤊿 𣘗 𧒠𦺋 𧃒 ä±— 𪑠ä ä—š ä²… 𧱬 ä´‡ 䪤 äš¡ 𦬣 爥 ++ 𥩔 ð¡©£ 𣸆 𣽡 æ™ å›» 綕 å¤ ð¨®¹ ã·´ 霴 𧯯 寛 𡵞 媤 㘥 ++ 𩺰 å«‘ å®· å³¼ æ® è–“ ð©¥… ç‘¡ ç’ ã¡µ 𡵓 𣚞 𦀡 㻬 𥣞 㫵 ++ 竼 é¾— 𤅡 𨤠𣇪 𠪊 𣉞 䌊 è’„ é¾– é¯ ä¤° 蘓 墖 éŠ éˆ˜ ++ ç§ ç¨² æ™  権 è¢ ç‘Œ 篅 æž‚ 稬 å‰ é† ã“¦ ç„ ð¥¶¹ 瓆 鿇 ++ åž³ 䤯 å‘Œ 䄱 𣚎 å ˜ 穲 𧭥 è® äš® 𦺈 ä† ð¥¶™ ç®® 𢒼 鿈 ++ 𢓠𢓉 𢓌 鿉 蔄 𣖻 ä‚´ é¿Š ä“¡ 𪷿 æ‹ ç® é¿‹ ㇀ ㇠㇂ ++ ㇃ ㇄ ð „Œ ㇅ 𠃑 𠃠㇆ ㇇ 𠃋 𡿨 ㇈ 𠃊 ㇉ ㇊ ㇋ ㇌ ++ ð „Ž ㇠㇎ Ä€ Ã Ç Ã€ Ä’ É Äš È ÅŒ Ó Ç‘ Ã’ Ê̄ ++ Ế Ê̌ Ề Ê Ä Ã¡ ÇŽ à É‘ Ä“ é Ä› è Ä« í Ç ++ ì Šó Ç’ ò Å« ú Ç” ù Ç– ǘ Çš Çœ ü ê̄ ế ++ ê̌ Ỡê É¡ ⚠⛠𪎩 ð¡…… 攊 丽 æ» éµŽ 釟 𧜵 æ’‘ 会 ++ 伨 侨 å…– å…´ 农 凤 务 动 医 åŽ å‘ å˜ å›¢ 声 处 备 ++ 夲 头 å­¦ 实 実 岚 庆 总 æ–‰ 柾 æ „ æ¡¥ 济 炼 电 纤 ++ 纬 纺 织 ç» ç»Ÿ 缆 ç¼· 艺 è‹ è¯ è§† 设 询 车 轧 è½® ++ ç‘ ç³¼ ç· æ¥† 竉 刧 醌 碸 é…ž 肼 è´‹ 胶 𠧧 è‚Ÿ 黇 ä³ ++ é·‰ 鸌 ä°¾ ð©·¶ 𧀎 鸊 𪄳 㗠溚 舾 ç”™ 䤑 马 éª é¾™ 禇 ++ 𨑬 ð¡·Š 𠗠𢫦 两 äº äº€ 亇 亿 仫 ä¼· ã‘Œ ä¾½ 㹈 倃 傈 ++ 㑽 ã’“ ã’¥ 円 夅 凛 凼 刅 争 剹 åŠ åŒ§ ã—‡ 厩 ã•‘ 厰 ++ ã•“ å‚ å£ ã•­ 㕲 ãš å’“ å’£ å’´ å’¹ å“ å“¯ 唘 唣 唨 ã–˜ ++ 唿 ã–¥ ã–¿ å—— ã—… 𧶄 唥 𠱂 ð ´• 𥄫 å– ð¢³† 㧬 ð  蹆 𤶸 ++ ð©“¥ ä“ ð¨‚¾ çº ð¢°¸ 㨴 䟕 𨅠𦧲 𤷪 æ“ ð µ¼ ð ¾´ 𠳕 𡃴 æ’ ++ è¹¾ ð º– ð °‹ 𠽤 𢲩 𨉖 𤓓 𠵆 𩩠𨃩 䟴 𤺧 𢳂 骲 㩧 ð©—´ ++ ã¿­ 㔆 𥋇 ð©Ÿ” 𧣈 𢵄 éµ® é • ä™ ð¦‚¥ æ’´ å“£ 𢵌 𢯊 𡷠㧻 ++ 𡯠𦛚 𦜖 𧦠 擪 𥒠𠱃 蹨 𢆡 𨭌 𠜱 ä ‹ 𠆩 㿺 塳 𢶠++ 𤗈 ð “¼ 𦂗 𠽌 ð ¶– 啹 ä‚» 䎺 䪴 𢩦 𡂠膪 飵 𠶜 æ¹ ã§¾ ++ 𢵠跀 åš¡ 摼 㹃 𪘠𠸉 𢫠𢳉 𡃈 𣧂 㦒 㨆 𨊛 㕸 𥹉 ++ 𢃇 å™’ ð ¼± 𢲲 𩜠 ã’¼ æ°½ 𤸻 𧕴 𢺋 𢈈 𪙛 𨳠𠹺 ð °´ 𦠜 ++ 羓 𡃠𢠃 𢤹 ã—» 𥇣 𠺌 𠾠𠺪 㾓 ð ¼° 𠵇 𡅠𠹌 𠺫 ð ®© ++ 𠵈 𡃀 ð¡„½ 㿹 𢚖 æ² ð ¾­ 𣴠𧘹 𢯎 ð µ¾ 𠵿 𢱑 𢱕 㨘 𠺘 ++ 𡃇 ð ¼® 𪘲 𦭠𨳒 𨶙 𨳊 é–ª å“Œ è‹„ å–¹ 𩻃 é°¦ 骶 𧞠𢷮 ++ ç…€ è…­ 胬 å°œ 𦕲 è„´ ãž— åŸ ð¨‚½ 醶 𠻺 ð ¸ ð ¹· ð »» 㗠𤷫 ++ 㘉 ð ³– 嚯 𢞵 𡃉 𠸠𠹸 𡸠𡅈 𨈇 ð¡‘• ð ¹¹ 𤹠𢶤 å©” ð¡€ ++ 𡀞 𡃵 𡃶 åžœ 𠸑 𧚔 𨋠𠾵 ð ¹» 𥅾 㜃 𠾶 𡆀 𥋘 𪊽 𤧚 ++ ð¡ º 𤅷 𨉼 墙 剨 㘚 𥜽 箲 å­¨ ä € 䬬 鼧 䧧 é°Ÿ é® ð¥­´ ++ 𣄽 å—» ã—² 嚉 丨 夂 𡯠屮 é‘ ð ‚† ä¹› 亻 㔾 å°£ 彑 å¿„ ++ 㣺 扌 攵 æ­º æ°µ æ°º ç¬ çˆ« 丬 犭 𤣩 ç½’ 礻 ç³¹ 罓 𦉪 ++ 㓠𦋠耂 è‚€ 𦘒 𦥑 å 衤 è§ ð§¢² è®  è´ é’… 镸 é•¿ é—¨ ++ 𨸠韦 页 风 飞 饣 ð©  é±¼ 鸟 黄 æ­¯ 龜 丷 𠂇 é˜ æˆ· ++ é’¢ 倻 æ·¾ 𩱳 龦 ã·‰ è¢ ð¤…Ž ç· å³µ 䬠 𥇠㕙 𥴰 æ„¢ 𨨲 ++ 辧 釶 熑 朙 玺 𣊠𪄇 㲋 𡦀 ä¬ ç£¤ ç‚ å†® 𨜠䀉 æ©£ ++ 𪊺 䈣 è˜ ð ©¯ 稪 𩥇 𨫪 é• ç 匤 ð¢¾ é´ ç›™ 𨧣 龧 çŸ ++ 亣 ä¿° 傼 丯 ä¼— 龨 å´ ç¶‹ 墒 å£ ð¡¶¶ 庒 庙 å¿‚ 𢜒 æ–‹ ++ 𣹠椙 橃 𣱣 泿 爀 𤔅 玌 ã»› 𤨓 嬕 ç’¹ 讃 𥲤 𥚕 窓 ++ 篬 糃 繬 苸 è–— 龩 è¢ é¾ª 躹 龫 è¿ è•Ÿ 駠 鈡 龬 𨶹 ++ ð¡¿ ä± äŠ¢ 娚 顨 æ« ä‰¶ 圽 è—– 𤥻 芿 ð§„ ä² ð¦µ´ åµ» 𦬕 ++ 𦾾 é¾­ é¾® å®– 龯 曧 ç¹› æ¹— 秊 㶈 䓃 𣉖 𢞖 䎚 䔶 峕 ++ 𣬚 諹 屸 ã´’ 𣕑 嵸 é¾² ç…— 䕘 𤃬 𡸣 ä±· 㥸 ã‘Š 𠆤 𦱠++ è«Œ ä¾´ 𠈹 妿 è…¬ é¡– 𩣺 å¼» 𠮟 𢇠𨥭 ä„‚ äš» 𩹠㼇 é¾³ ++ 𪆵 䃸 㟖 ä›· 𦱆 ä…¼ 𨚲 𧿠䕭 㣔 𥒚 ä•¡ ä”› 䶉 ä±» 䵶 ++ ä—ª 㿈 𤬠㙡 ä“ž ä’½ 䇭 å´¾ 嵈 åµ– ã·¼ ã  å¶¤ 嶹 ã   ã ¸ ++ 幂 庽 å¼¥ 徃 㤈 㤔 㤿 㥠惗 愽 å³¥ 㦉 憷 憹 æ‡ ã¦¸ ++ 戬 æŠ æ‹¥ 挘 㧸 åš± 㨃 æ¢ æ» æ‡ æ‘š ã©‹ æ“€ å´• 嘡 龟 ++ 㪗 æ–† 㪽 æ—¿ 晓 㫲 æš’ 㬢 朖 ã­‚ 枤 æ € ã­˜ æ¡Š 梄 ã­² ++ ã­± ã­» 椉 楃 牜 楤 榟 榅 㮼 槖 㯠橥 æ©´ 橱 檂 㯬 ++ 檙 㯲 檫 檵 æ«” 櫶 æ® æ¯ æ¯ª æ±µ 沪 㳋 æ´‚ æ´† æ´¦ æ¶ ++ 㳯 涤 涱 渕 渘 温 溆 𨧀 溻 滢 滚 齿 滨 滩 漤 æ¼´ ++ 㵆 ð£½ æ¾ æ¾¾ 㵪 ãµµ 熷 å²™ 㶊 瀬 㶑 ç ç” ç¯ ç¿ ç‚‰ ++ 𠌥 ä ã—± 𠻘 𣻗 åž¾ 𦻓 焾 𥟠 㙎 榢 𨯩 å­´ 穉 𥣡 ð©“™ ++ ç©¥ 穽 𥦬 窻 窰 ç«‚ 竃 燑 𦒠䇊 ç«š ç« ç«ª 䇯 å’² 𥰠++ 笋 ç­• 笩 𥌎 𥳾 箢 ç­¯ 莜 𥮴 𦱿 ç¯ è¡ ç®’ 𥴠 㶭 𥱥 ++ è’’ 篺 ç°µ 𥳠籄 粃 𤢂 粦 晽 𤕸 糉 糇 糦 ç±´ ç³³ ç³µ ++ 繧 ä” ð¦¹„ çµ ð¦»– ç’ ç¶‰ 綫 焵 綳 𤗠𦀩 ç·¤ ã´“ ç·µ 𡟹 ++ ç·¥ 𨭠𦄡 𦅚 ç¹® 纒 䌫 鑬 縧 ç½€ ç½ ç½‡ 礶 𦋠駡 ç¾— ++ 𦑠羣 ð¡™¡ ð ¨ ä•œ 𣦠䔃 𨌺 翺 𦒉 耈 è€ è€¯ 𪂇 𦳃 耻 ++ 耼 è¡ ð¢œ” 䦉 𦘦 𣷣 𦛨 朥 肧 𨩈 脇 è„š 墰 𢛶 汿 𦒘 ++ 𤾸 擧 ð¡’Š 舘 ð¡¡ž æ©“ 𤩥 𤪕 䑺 舩 𠬠𦩒 𣵾 俹 ð¡“½ è“¢ ++ è¢ ð¦¬Š 𤦧 𣔰 𡳠𣷸 芪 椛 芳 䇛 è•‹ è‹ èŒš ð ¸– ð¡ž´ ã› ++ 𣅽 𣕚 艻 è‹¢ 茘 𣺋 𦶣 𦬅 𦮗 𣗎 㶿 èŒ å—¬ 莅 䔋 𦶥 ++ 莬 è“ ã‘¾ 𦻔 æ©— è•š ã’– 𦹂 𢻯 葘 𥯤 葱 ã·“ 䓤 檧 è‘Š ++ 𣲵 祘 𦮖 𦹷 𦹃 è“ž 莑 ä’  è’“ 蓤 𥲑 䉀 𥳀 䕃 è”´ 嫲 ++ 𦺙 䔧 蕳 ä”– æž¿ 蘖 𨘥 𨘻 è— ð§‚ˆ 蘂 ð¡–‚ 𧃠䕫 䕪 蘨 ++ 㙈 ð¡¢¢ å· ð§Žš 虾 è± ðªƒ¸ 蟮 𢰧 èž± 蟚 è  å™¡ 虬 æ¡– ä˜ ++ è¡… 衆 𧗠 𣶹 𧗤 è¡ž 袜 ä™› 袴 袵 æ 装 ç· ð§œ è¦‡ 覊 ++ 覧 覼 𨨥 觧 𧤤 𧪽 誜 çž“ 釾 èª ð§©™ ç«© 𧬺 𣾠䜓 𧬸 ++ ç…¼ 謌 謟 𥰠𥕥 謿 è­Œ è­ èª© 𤩺 è® è®› 誯 𡛟 䘕 è¡ ++ è²› 𧵔 𧶠貫 㜥 𧵓 è³– 𧶘 𧶽 è´’ è´ƒ 𡤠賛 çœ è´‘ 𤳉 ++ 㻠趩 𨀂 ð¡€” 𤦊 ã­¼ 𨆼 𧄌 竧 躭 躶 軃 é‹” è¼™ è¼­ 𨥠++ 𨒠辥 錃 𪊟 ð © è¾³ 䤪 𨧞 𨔽 𣶻 廸 𣉢 迹 𪀔 𨚼 𨔠++ 𢌥 㦀 𦻗 逷 𨔼 𧪾 é¡ ð¨•¬ 𨘋 邨 𨜓 郄 𨛦 é‚® é…§ ã«° ++ 醩 釄 粬 𨤳 𡺉 鈎 沟 é‰ é‰¢ 𥖹 𨫆 𣲛 𨬌 𥗛 ð ´± 錬 ++ é« ð¨«¡ 𨯫 ç‚ å«ƒ 𨫢 𨫥 䥥 鉄 𨯬 𨰹 𨯿 é³ é‘› 躼 é–… ++ é–¦ é¦ é–  濶 䊹 𢙺 𨛘 𡉼 𣸮 䧟 æ°œ é™» éš– ä…¬ 隣 𦻕 ++ 懚 隶 磵 𨫠 éš½ åŒ ä¦¡ 𦲸 ð ‰´ ð¦ 𩂯 𩃥 𤫑 𡤕 𣌊 霱 ++ 虂 霶 ä¨ ä”½ ä–… 𤫩 çµ å­ éœ› 𩇕 é— å­Š 𩇫 éŸ é¥ åƒ ++ 𣂷 𣂼 鞉 鞟 éž± éž¾ 韀 韒 韠 𥑬 韮 çœ ð©³ éŸµ ð© 𧥺 ++ ä«‘ é ´ é ³ é¡‹ 顦 㬎 𧅵 㵑 ð ˜° 𤅜 𥜆 飊 颷 飈 飇 ä«¿ ++ 𦴧 ð¡›“ å–° 飡 飦 飬 é¸ é¤¹ 𤨩 ä­² ð©¡— 𩤅 駵 騌 騻 é¨ ++ 驘 𥜥 㛄 ð©‚± 𩯕 é«  é«¢ 𩬅 é«´ ä°Ž 鬔 鬭 𨘀 倴 鬴 𦦨 ++ 㣃 ð£½ é­ é­€ ð©´¾ å©… ð¡¡£ 鮎 𤉋 é°‚ 鯿 é°Œ 𩹨 é·” 𩾷 𪆒 ++ 𪆫 𪃡 𪄣 𪇟 éµ¾ 鶃 𪄴 鸎 梈 é·„ 𢅛 𪆓 𪈠 𡤻 𪈳 é´¹ ++ 𪂹 𪊴 éº éº• 麞 麢 ä´´ 麪 麯 ð¤¤ é» ã­  㧥 ã´ ä¼² ãž¾ ++ 𨰫 鼂 鼈 ä®– é¤ ð¦¶¢ é¼— é¼¹ 嚟 嚊 é½… 馸 ð©‚‹ 韲 è‘¿ é½¢ ++ 齩 ç«œ 龎 爖 䮾 𤥵 𤦻 ç…· 𤧸 𤈠𤩑 玞 𨯚 𡣺 禟 𨥾 ++ 𨸶 é© é³ ð¨©„ 鋬 éŽ é‹ ð¨¥¬ 𤒹 爗 㻫 ç² ç©ƒ çƒ ð¤‘³ 𤸠++ ç…¾ 𡟯 ç‚£ ð¡¢¾ 𣖙 㻇 ð¡¢… 𥯠𡟸 㜢 ð¡›» ð¡ ¹ 㛡 𡴠𡣑 𥽋 ++ 㜣 𡛀 å› ð¤¨¥ 𡾠𡊨 𡆠𡒶 蔃 𣚦 è‘• 𤦔 𧅥 𣸱 𥕜 𣻻 ++ 𧒠䓴 𣛮 𩦠𦼦 柹 㜳 ã°• ã·§ 塬 𡤢 æ  ä— ð£œ¿ 𤃡 𤂋 ++ 𤄠𦰡 å“‹ åšž 𦚱 åš’ ð ¿Ÿ 𠮨 ð ¸ é† ð¨¬“ 鎜 仸 å„« ã ™ 𤶠++ 亼 ð ‘¥ 𠿠佋 侊 𥙑 婨 𠆫 𠋠㦙 𠌊 𠔠㵠伩 ð ‹€ 𨺳 ++ 𠉵 è«š 𠈌 亘 åƒ å„ ä¾¢ 伃 𤨎 𣺊 佂 倮 å¬ å‚ ä¿Œ ä¿¥ ++ å˜ åƒ¼ 湶 𣖕 𣸹 𣺿 æµ² 𡢄 𣺉 冨 凃 ð —  ä“ ð ’£ ð ’’ ð ’‘ ++ 赺 𨪜 𠜎 剙 劤 ð ¡³ å‹¡ 䙺 熌 𤎌 ð °  𤦬 𡃤 槑 𠸠㻞 ++ ç’™ ç” ç‘– 玘 䮎 𤪼 𤂠å ã–„ çˆ ð¤ƒ‰ å–´ ð … å“ ð ¯† åœ ++ é‰ é›´ é¦ åŸ åž å¿ ã˜¾ 壋 媙 𨩆 𡛺 𡯠𡜠娬 妸 éŠ ++ 婾 å« å¨’ 𥥆 𡧳 ð¡¡¡ 𤊕 㛵 æ´… 瑃 娡 𥺃 åª ð¨¯— ð “ é  ++ ç’Œ 𡌃 ç„… 䥲 éˆ ð¨§» 鎽 ãž  å°ž 岞 幞 幈 𡦖 ð¡¥¼ 𣫮 å» ++ å­ ð¡¤ƒ 𡤄 㜠𡢠 ã› ð¡›¾ 㛓 脪 𨩇 𡶺 𣑲 𨦨 弌 弎 𡤧 ++ ð¡ž« å©« 𡜻 å­„ 蘔 𧗽 è¡  æ¾ ð¢¡  𢘫 å¿› 㺸 𢖯 𢖾 𩂈 𦽳 ++ 懀 ð €¾ 𠆠𢘛 憙 憘 æµ ð¢²› 𢴇 𤛔 𩅠摱 𤙥 𢭪 㨩 𢬢 ++ 𣑠𩣪 𢹸 挷 𪑛 æ’¶ 挱 æ‘ ð¤§£ 𢵧 护 𢲡 æ» æ•« 楲 㯴 ++ 𣂎 𣊭 𤦉 𣊫 å” ð£‹  ð¡£™ 𩿠曎 𣊉 𣆳 ã«  ä† ð¥–„ 𨬢 𥖠++ ð¡›¼ 𥕛 𥥠磮 𣄃 ð¡ ª 𣈴 㑤 𣈠𣆂 𤋉 暎 𦴤 晫 䮓 昰 ++ 𧡰 ð¡·« 晣 𣋒 𣋡 昞 𥡲 㣑 𣠺 𣞼 ã®™ 𣞢 ð£¾ ç“ ã®– æž ++ 𤘪 梶 æ ž 㯄 檾 ã¡£ 𣟕 𤒇 樳 æ©’ 櫉 欅 𡤒 攑 梘 æ©Œ ++ 㯗 橺 æ­— 𣿀 𣲚 鎠 鋲 𨯪 𨫋 銉 𨀞 𨧜 鑧 涥 漋 𤧬 ++ 𣽿 㶠渄 𤀼 娽 渊 塇 æ´¤ ç¡‚ ç„» 𤌚 𤉶 烱 ç‰ çŠ‡ 犔 ++ 𤞠𤜥 å…¹ 𤪤 ð —« 瑺 𣻸 𣙟 𤩊 𤤗 𥿡 㼆 㺱 𤫟 𨰣 𣼵 ++ 悧 㻳 ç“Œ ç¼ éŽ‡ ç· ä’Ÿ 𦷪 ä•‘ ç–ƒ ã½£ 𤳙 𤴆 㽘 ç•• 癳 ++ 𪗆 㬙 瑨 𨫌 𤦫 𤦎 ã«» 㷠𤩎 㻿 𤧅 𤣳 釺 圲 é‚ ð¨«£ ++ 𡡤 僟 𥈡 𥇧 ç¸ ð£ˆ² 眎 çœ ç» ð¤š— 𣞠㩞 𤣰 ç¸ ç’› 㺿 ++ 𤪺 𤫇 䃈 𤪖 𦆮 錇 𥖠砞 ç¢ ç¢ˆ 磒 ç 祙 ð§ 𥛣 ä„Ž ++ è’– 禥 樭 𣻺 稺 秴 ä…® 𡛦 䄲 鈵 秱 𠵌 𤦌 ð Š™ 𣶺 ð¡® ++ ã–— å•« ã•° 㚪 𠇔 ð ° ç«¢ å©™ 𢛵 𥪯 𥪜 å¨ ð ‰› 磰 娪 𥯆 ++ 竾 䇹 ç± ç±­ 䈑 𥮳 𥺼 𥺦 ç³ ð¤§¹ ð¡ž° 粎 ç±¼ ç²® 檲 ç·œ ++ 縇 ç·“ 罎 𦉡 𦅜 𧭈 綗 𥺂 䉪 𦭵 ð ¤– 柖 𠎠𣗠埄 𦒠++ 𦸠𤥢 ç¿ ç¬§ ð  ¬ 𥫩 𥵃 笌 𥸎 駦 è™… é©£ 樜 𣿠㧢 𤧷 ++ 𦖭 騟 𦖠 è’€ 𧄧 𦳑 䓪 è„· ä‚ èƒ† 脉 è…‚ 𦞴 飃 𦩂 艢 ++ 艥 𦩑 è‘“ 𦶧 è˜ ð§ˆ› 媆 ä…¿ ð¡¡€ 嬫 𡢡 嫤 𡣘 èš  蜨 𣶠++ è ­ 𧢠娂 è¡® ä½… 袇 袿 裦 襥 è¥ ð¥šƒ 襔 𧞅 𧞄 𨯵 𨯙 ++ 𨮜 𨧹 㺭 è’£ 䛵 ä› ãŸ² 訽 訜 𩑈 å½ éˆ« 𤊄 æ—” ç„© 烄 ++ ð¡¡… éµ­ 貟 賩 𧷜 妚 矃 姰 ä® ã›” 踪 躧 𤰉 è¼° 轊 ä‹´ ++ 汘 æ¾» 𢌡 䢛 æ½¹ 溋 ð¡Ÿš 鯩 ãšµ 𤤯 é‚» 啱 䤆 醻 é„ ð¨©‹ ++ ä¢ ð¨«¼ é§ ð¨° ð¨°» è“¥ 訫 é–™ é–§ é–— é–– 𨴴 ç‘… 㻂 𤣿 𤩂 ++ 𤪠㻧 𣈥 éš ð¨»§ 𨹦 𨹥 㻌 𤧭 𤩸 𣿮 ç’ ç‘« 㻼 é ð©‚° ++ 桇 ä¨ ð©‚“ 𥟟 é¨ ð¨¦‰ 𨰦 𨬯 𦎾 銺 嬑 è­© 䤼 ç¹ ð¤ˆ› éž› ++ é± é¤¸ 𠼦 å· ð¨¯… 𤪲 é Ÿ ð©“š 鋶 ð©—— 釥 ä“€ 𨭠𤩧 𨭤 飜 ++ 𨩅 ã¼€ 鈪 䤥 è” é¤» é¥ ð§¬† ã·½ 馛 ä­¯ 馪 é©œ 𨭥 𥣈 æª ++ 騡 嫾 騯 ð©£± ä® ð©¥ˆ 馼 䮽 ä®— é½ å¡² 𡌂 å ¢ 𤦸 𡓨 ç¡„ ++ 𢜟 𣶸 棅 ãµ½ 鑘 㤧 æ… ð¢ž ð¢¥« 愇 é± é±“ é±» é°µ é° é­¿ ++ é¯ ð©¸­ 鮟 𪇵 𪃾 é´¡ ä²® 𤄄 鸘 ä²° é´Œ 𪆴 𪃭 𪃳 𩤯 鶥 ++ è’½ 𦸒 𦿟 𦮂 è—¼ 䔳 𦶤 𦺄 𦷰 è  è—® 𦸀 𣟗 𦤠秢 𣖜 ++ 𣙀 䤭 𤧞 ãµ¢ é› éŠ¾ éˆ ð Š¿ 碹 鉷 é‘ ä¿¤ ã‘€ é¤ ð¥• ç ½ ++ ç¡” 碶 ç¡‹ 𡗠𣇉 𤥠㚚 ä½² æ¿š æ¿™ 瀞 å” ð¤†µ åž» 壳 垊 ++ é´– 埗 ç„´ ã’¯ 𤆬 燫 𦱀 𤾗 ð¡žµ 𨩉 æ„Œ å«Ž 娋 䊼 𤒈 㜬 ++ ä­» 𨧼 鎻 鎸 ð¡£– 𠼠葲 𦳀 𡓠𤋺 𢰦 ð¤ 妔 𣶷 ð¦ 綨 ++ 𦅛 𦂤 𤦹 𤦋 𨧺 é‹¥ ç¢ ã»© ç’´ 𨭣 𡢟 㻡 𤪳 櫘 ç³ ç» ++ ã»– 𤨾 𤪔 ð¡Ÿ™ 𤩦 𠎧 𡤠𤧥 瑈 𤤖 ç‚¥ 𤥶 銄 ç¦ éŸ ð “¾ ++ 錱 𨫎 𨨖 鎆 𨯧 𥗕 䤵 𨪂 ç…« 𤥃 𠳿 嚤 𠘚 𠯫 𠲸 唂 ++ 秄 𡟺 ç·¾ ð¡›‚ 𤩠𡡒 ä”® é 㜊 𨫀 𤦭 妰 𡢿 𡢃 𧒄 媡 ++ 㛢 𣵛 ãš° 鉟 婹 𨪠𡡢 é´ ã³ ð ª´ 䪖 㦊 僴 㵩 㵌 ð¡Žœ ++ ç…µ ä‹» 𨈘 æ¸ ð©ƒ¤ ä“« æµ— ð§¹ ç§ æ²¯ ã³– 𣿭 𣸭 渂 漌 㵯 ++ ð µ ç•‘ ãš¼ 㓈 䚀 㻚 䡱 姄 鉮 䤾 è½ ð¨°œ 𦯀 å ’ 埈 ã›– ++ ð¡‘’ 烾 𤢠𤩱 𢿣 ð¡Š° 𢎽 梹 楧 𡎘 𣓥 𧯴 𣛟 𨪃 𣟖 𣺠++ 𤲟 樚 𣚭 𦲷 è¾ ä“Ÿ ä“Ž 𦴦 𦵑 𦲂 𦿞 æ¼— 𧄉 茽 𡜺 è­ ++ 𦲀 𧓠𡟛 妉 媂 ð¡ž³ å©¡ 婱 𡤅 𤇼 㜭 姯 𡜼 㛇 熎 éŽ ++ æšš 𤊥 å©® 娫 𤊓 樫 𣻹 𧜶 𤑛 𤋊 ç„ ð¤‰™ 𨧡 ä¾° 𦴨 峂 ++ 𤓎 𧹠𤎽 樌 𤉖 𡌄 炦 焳 𤩠㶥 泟 勇 𤩠繥 姫 å´¯ ++ ã·³ 彜 𤩠𡟟 綤 è¦ å’… 𣫺 𣌀 𠈔 å¾ ð £• 𠘙 ã¿¥ 𡾞 𪊶 ++ 瀃 ð©…› åµ° çŽ ç³“ 𨩙 𩠠俈 翧 ç‹ çŒ ð§«´ 猸 猹 𥛶 ç ++ çˆ ãº© 𧬘 é¬ ç‡µ 𤣲 ç¡ è‡¶ 㻊 県 㻑 æ²¢ 国 ç™ çž çŸ ++ 㻢 ã»° ã»´ 㻺 ç““ 㼎 㽓 ç•‚ ç•­ 畲 ç– ã½¼ ç—ˆ ç—œ ã¿€ ç™ ++ ã¿— ç™´ ã¿œ 発 𤽜 熈 嘣 覀 å¡© ä€ çƒ ä€¹ æ¡ ä… ã—› 瞘 ++ äª ä¯ å±ž çž¾ 矋 売 ç ˜ 点 ç œ 䂨 ç ¹ 硇 ç¡‘ 硦 葈 𥔵 ++ 礳 æ ƒ 礲 䄃 䄉 禑 禙 è¾» 稆 è¾¼ ä…§ 窑 䆲 窼 艹 䇄 ++ ç« ç«› ä‡ ä¸¡ ç­¢ ç­¬ ç­» ç°’ ç°› 䉠 䉺 ç±» 粜 䊌 粸 䊔 ++ ç³­ 输 烀 ð ³ ç· ç·” ç· ç·½ ç¾® ç¾´ 犟 䎗 耠 耥 笹 耮 ++ 耱 è” ã·Œ åž´ ç‚  è‚· 胩 ä­ è„Œ 猪 è„Ž è„’ ç•  è„” ä 㬹 ++ è…– è…™ è…š ä“ å º è…¼ 膄 ä¥ è†“ ä­ è†¥ 埯 è‡ è‡¤ 艔 ä’ ++ 芦 艶 è‹Š 苘 è‹¿ ä’° è— é™© 榊 è… çƒµ 葤 惣 è’ˆ 䔄 è’¾ ++ è“¡ 蓸 è” è”¸ è•’ ä”» 蕯 è•° è—  ä•· 虲 èš’ èš² 蛯 é™… èž‹ ++ 䘆 䘗 袮 裿 褤 襇 覑 𧥧 訩 訸 誔 誴 豑 è³” è³² è´œ ++ 䞘 å¡Ÿ è·ƒ 䟭 ä»® 踺 å—˜ å” è¹± å—µ 躰 ä · 軎 転 軤 è»­ ++ 軲 è¾· è¿ è¿Š è¿Œ 逳 駄 䢭 飠 鈓 䤞 鈨 鉘 鉫 銱 銮 ++ 銿 é‹£ é‹« 鋳 é‹´ 鋽 éƒ éŽ„ 鎭 䥅 䥑 麿 é— åŒ é é­ ++ é¾ ä¥ª é‘” 鑹 é”­ é–¢ 䦧 é—´ 阳 䧥 æž  䨤 é€ ä¨µ éž² 韂 ++ å™” 䫤 惨 颹 䬙 飱 å¡„ 餎 餙 冴 餜 餷 饂 é¥ é¥¢ ä­° ++ 駅 ä® é¨¼ é¬ çªƒ é­© é® é¯ é¯± 鯴 ä±­ é°  㯠𡯂 鵉 é°º ++ 黾 å™ é¶“ 鶽 é·€ é·¼ 银 辶 é¹» 麬 麱 麽 黆 é“œ 黢 é»± ++ 黸 竈 齄 ð ‚” ð Š· ð Ž  椚 铃 妬 ð “— å¡€ é“ ãž¹ ð —• 𠘕 𠙶 ++ 𡚺 å— ç…³ ð «‚ ð « ð ®¿ 呪 吆 𠯋 å’ž 𠯻 ð °» 𠱓 ð ±¥ ð ±¼ 惧 ++ 𠲠噺 ð ²µ ð ³ ð ³­ 𠵯 𠶲 ð ·ˆ 楕 é°¯ 螥 𠸄 𠸎 ð »— ð ¾ ð ¼­ ++ ð ¹³ å°  ð ¾¼ 帋 𡜠ð¡ 𡶠朞 𡻠𡂈 ð¡‚– 㙇 ð¡‚¿ 𡃓 𡄯 ð¡„» ++ å¤ è’­ ð¡‹£ 𡵠𡌶 è® ð¡•· 𡘙 𡟃 𡟇 乸 ç‚» ð¡ ­ 𡥪 𡨭 ð¡©… ++ ð¡°ª 𡱰 𡲬 𡻈 拃 ð¡»• 𡼕 熘 æ¡• 𢅠槩 㛈 𢉼 𢗠𢺠𢜪 ++ 𢡱 𢥠苽 𢥧 𢦓 𢫕 覥 𢫨 è¾  𢬎 鞸 𢬿 顇 骽 𢱌 𢲈 ++ 𢲷 𥯨 𢴈 𢴒 𢶷 𢶕 𢹂 𢽴 𢿌 𣀳 𣦠𣌟 𣞠徱 晈 æš¿ ++ 𧩹 𣕧 𣗳 𤦺 𣘚 𣜖 𠆠墵 朎 椘 𣪧 𧙗 𥿢 𣸑 𣺹 𧗾 ++ 𢂚 ä£ äª¸ 𤄙 𨪚 𤋮 𤌠𤀻 𤌴 𤎖 𤩅 ð —Š 凒 𠘑 妟 𡺨 ++ 㮾 𣳿 𤄠𤓖 垈 𤙴 㦛 𤜯 𨗨 𩧉 㢠𢇃 è­ž 𨭎 𤠒 𤣻 ++ 𤨕 爉 𤫀 𠱸 奥 𤺥 𤾆 𠹠軚 𥀬 åŠ åœ¿ ç…± 𥊙 𥙠𣽊 ++ 𤪧 å–¼ 𥑆 𥑮 𦭒 㑳 𥔿 𧘲 𥕞 䜘 𥕢 𥕦 𥟇 𤤿 ð¥¡ å¦ ++ ã“» 𣌠𥤃 ä¼ ð¨¥ˆ 𥪮 𥮉 𥰆 𡶠垡 ç…‘ 𦄂 𧰒 é– ð¦†² 𤾚 ++ è­¢ 𦂠𦑊 åµ› 𦯷 𦒄 𡤜 諪 𤧶 𦒈 𣿯 𦔒 䯀 𦖿 𦚵 𢜛 ++ é‘¥ 𥟡 憕 娧 枅嚹 𤔡 𦛼 乪 𤤴 é™– æ¶ ð¦²½ 㘘 襷 𦞙 ++ 𦡮 𦑠𦡞 𦣇 ç­‚ 𩃀 𠨑 𦤦 𦤹 ç©… 𦧺 騦 𦨭 㙟 𦑩 𠀡 ++ 禃 𦨴 𦭛 å´¬ 𣔙 ð¦® ä› ð¦²¤ ç”» è¡¥ 𦶮 墶 㜜 𢖠𧋠𧇠++ ã±” 𧊀 𧊅 éŠ ð¢…º 𧊋 錰 𧋦 𤧠氹 é’Ÿ 𧑠𠻸 è § 裵 𢤦 ++ 𨑳 ð¡ž± 溸 𤨪 ð¡   㦤 ãš¹ 䔿 暶 𩲭 𩢤 襃 𧟌 𧡘 å›– 䃟 ++ 𡘊 㦡 𣜯 𨃨 𡅠熭 è¦ ð§§ ð©†¨ ä²· 𧂯 𨦫 𧧽 𧨊 𧬋 𧵦 ++ 𤅺 ç­ƒ 祾 𨀉 æ¾µ 𪋟 樃 𨌘 厢 𦸇 鎿 æ ¶ é 𨅯 𨀣 𦦵 ++ 𡭠𣈯 𨈠嶅 𨰰 𨂃 圕 é £ 𨥉 嶫 𤦈 æ–¾ 槕 å’ ð¤ª¥ 𣾠++ ã°‘ 朶 𨂠𨃴 𨄮 𡾡 𨅠𨆉 𨆯 𨈚 𨌆 𨌯 𨎊 ã—Š 𨑨 𨚪 ++ 䣺 æ¦ ð¨¥– ç ˆ 鉕 𨦸 ä² ð¨§§ äŸ ð¨§¨ 𨭆 𨯔 姸 𨰉 𨿅 𩃬 ++ ð©„ ð©„¼ ã·· ð©…ž 𤫊 è¿ çŠ åš‹ 𩓧 ð©—© ð©–° ð©–¸ 𩜲 𩣑 𩥉 𩥪 ++ 𩧃 𩨨 𩬎 𩵚 𩶛 纟 𩻸 𩼣 䲤 镇 𪊓 熢 𪋿 䶑 递 𪗋 ++ 䶜 𠲜 è¾¾ å— è¾º 𢒰 è¾¹ 𤪓 䔉 繿 æ½– 檱 仪 㓤 𨬬 𧢠++ 㜺 躀 𡟵 𨀤 𨭬 𨮙 𧨾 𦚯 ã·« 𧙕 𣲷 𥘵 𥥖 亚 𥺠𦉘 ++ åš¿ ð ¹­ 踎 å­­ 𣺈 𤲞 æž ð¡Ÿ¶ ð¡¡» æ”° 嘭 𥱊 åš ð¥Œ‘ ã·† 𩶘 ++ ä±½ 嘢 嘞 罉 𥻘 奵 𣵀 è° ä¸œ 𠿪 𠵉 𣚺 è„— 鵞 è´˜ 瘻 ++ é±… 癎 çž¹ é… å² è…ˆ è‹· 嘥 脲 è˜ è‚½ å—ª 祢 噃 å– ð º ++ ã—Ž 嘅 å—± æ›± 𨋢 㘭 ç”´ å—° å–º å’— 啲 ð ± ð ²– å» ð¥…ˆ 𠹶 ++ 𢱢 𠺢 麫 絚 å—ž ð¡µ æŠ é­ å’” è³ ç‡¶ é…¶ æ¼ æŽ¹ æ¾ å•© ++ 𢭃 é±² 𢺳 冚 ã“Ÿ 𠶧 冧 å‘ å”ž 唓 癦 踭 𦢊 ç–± 肶 è „ ++ 螆 裇 膶 èœ ð¡ƒ ä“¬ 猄 𤜆 å® èŒ‹ 𦢓 å™» 𢛴 𧴯 𤆣 𧵳 ++ 𦻠𧊶 é…° 𡇙 鈈 𣳼 𪚩 𠺬 ð »¹ 牦 𡲢 äŽ ð¤¿‚ 𧿹 ð ¿« 䃺 ++ é± æ”Ÿ 𢶠 䣳 𤟠 𩵼 𠿬 𠸊 𧖣 ð ¿­ 𦈠𡆇 熣 纎 éµ ä¸š ++ 丄 ã•· å¬ æ²² å§ ãš¬ 㧜 å½ ãš¥ 𤘘 墚 𤭮 舭 å‘‹ 垪 𥪕 ++ ð ¥¹ ã©’ 𢑥 ç´ ð©º¬ ä´‰ 鯭 𣳾 𩼰 ä±› 𤾩 ð©–ž ð©¿ž è‘œ 𣶶 𧊲 ++ 𦞳 𣜠 挮 ç´¥ 𣻷 𣸬 㨪 逈 å‹Œ ã¹´ 㙺 ä—© ð ’Ž 癀 å«° 𠺶 ++ 硺 𧼮 墧 ä‚¿ 噼 鮋 åµ´ ç™” 𪴠麅 䳡 㟻 æ„™ 𣃚 ð¤² å™ ++ ð¡Š© 垧 𤥣 𩸆 刴 𧂮 ã–­ éµ¼ ç±– 鬹 埞 𡬠屓 æ““ 𩓠𦌵 ++ 𧅤 èš­ ð ´¨ 𦴢 𤫢 ð µ± 凾 𡼠嶎 霃 ð¡·‘ éº éŒ ç¬Ÿ 鬂 峑 ++ 箣 扨 挵 é«¿ ç¯ é¬ª ç±¾ 籂 粆 é°• 篼 鬉 é°› 𤤾 齚 啳 ++ 寃 俽 麘 俲 剠 㸆 å‹‘ å§ å– å¦· 帒 韈 鶫 轜 å‘© éž´ ++ 饀 鞺 匬 æ„° 椬 åš é°Š é´‚ ä°» é™ æ¦€ 傦 畆 𡭠駚 剳 ++ é…™ éš é…œ é…‘ 𨺗 æ¿ ð¦´£ æ«Š 嘑 醎 畺 抅 ð ¼ ç ç±° 𥰡 ++ 𣳽 𤤙 ç›– é® ä¸ª ð ³” 莾 è¡‚ 届 槀 åº åˆŸ å·µ 从 æ°± 𠇲 ++ ä¼¹ å’œ å“š 劚 趂 ã—¾ ã—³ æ­’ é…¼ é¾¥ é®— é ® 颴 骺 麨 麄 ++ ç…º 笔 毺 è ˜ 罸 嘠 𪙊 è¹· 齓 è·” è¹ é¸œ è¸ æŠ‚ 𨽠踨 ++ è¹µ ç«“ 𤩷 稾 磘 泪 詧 瘇 𨩚 鼦 泎 蟖 ç—ƒ 𪊲 ç¡“ 咢 ++ è´Œ ç‹¢ ç± è¬­ 猂 瓱 賫 𤪻 蘯 徺 袠 ä’· ð¡ » 𦸅 詾 𢔛 ++ 惽 癧 é«— 鵄 é® é® èŸµ è³· 猬 霡 é®° ã—– 犲 ä°‡ 籑 饊 ++ 𦅙 æ…™ ä°„ 麖 æ…½ åŸ æ…¯ 抦 戹 ã©œ 懢 厪 ð£µ æ¤ æ ‚ ã—’ ++ åµ— 𨯂 è¿š 𨸹 僙 𡵆 礆 匲 阸 ð ¼» ä¥ çŸ¾ 糂 𥼚 糚 稭 ++ è¦ è£ çµ ç”… 瓲 覔 舚 朌 è¢ ð§’† è› ç“° 脃 眤 覉 𦟌 ++ ç•“ 𦻑 èž© 蟎 臈 螌 詉 è²­ è­ƒ 眫 瓸 è“š 㘵 榲 趦 覩 ++ 涹 èŸ ð¤€‘ 瓧 ã·› ç…¶ 悤 憜 㳑 æ· ç½± 𨬭 惩 ä­¾ 删 ã°˜ ++ 𣳇 𥻗 𧙖 𥔱 𡥄 ð¡‹¾ 𩤃 𦷜 𧂭 å³ ð¦†­ 𨨠𣙷 𠃮 𦡆 𤼎 ++ ä•¢ 嬟 ð¦Œ é½ éº¦ 𦉫   , 〠。 . • ï¼› : ? ï¼ ++ ︰ … ‥ ï¹ ï½¤ ï¹’ · ï¹” ﹕ ï¹– ï¹— | – ︱ — ︳ ++ ︴ ï¹ ï¼ˆ ) ︵ ︶ ï½› ï½ ï¸· ︸ 〔 〕 ︹ ︺ 〠】 ++ ︻ ︼ 《 》 ︽ ︾ 〈 〉 ︿ ï¹€ 「 ã€ ï¹ ï¹‚ 『 〠++ ﹃ ﹄ ï¹™ ﹚ ï¹› ﹜ ï¹ ï¹ž ‘ ’ “ †〠〞 ‵ ′ ++ # & * ※ § 〃 â—‹ â— â–³ â–² â—Ž ☆ ★ â—‡ â—† â–¡ ++ â–  â–½ â–¼ ㊣ â„… ‾ _ ﹉ ﹊ ï¹ ï¹Ž ﹋ ﹌ ﹟ ï¹  ﹡ ++ + ï¼ Ã— ÷ ± √ < > ï¼ â‰¦ ≧ ≠ ∞ ≒ ≡ ï¹¢ ++ ï¹£ ﹤ ï¹¥ ﹦ ∼ ∩ ∪ ⊥ ∠ ∟ ⊿ 㒠㑠∫ ∮ ∵ ++ ∴ ♀ ♂ ♠☉ ↑ ↓ ↠→ ↖ ↗ ↙ ↘ ∥ ∣ ï¼ ++ ï¼¼ $ Â¥ 〒 ¢ £ ï¼… ï¼  ℃ ℉ ﹩ ﹪ ﹫ 㕠㎜ ㎠++ ㎞ ㎠㎡ ㎎ ㎠ㄠ° å…™ å…› å…ž å… å…¡ å…£ å—§ ç“© 糎 ++ â– â–‚ â–ƒ â–„ â–… â–† â–‡ â–ˆ â– â–Ž â– â–Œ â–‹ â–Š â–‰ ┼ ++ â”´ ┬ ┤ ├ â–” ─ │ â–• ┌ â” â”” ┘ â—¢ â—£ â—¥ â—¤ ++ ╱ ╲ ╳ ï¼ ï¼‘ ï¼’ 3 ï¼” 5 ï¼– ï¼— 8 ï¼™ â…  â…¡ â…¢ ++ â…£ â…¤ â…¥ â…¦ â…§ â…¨ â…© 〡 〢 〣 〤 〥 〦 〧 〨 〩 ++ å„ ï¼¡ ï¼¢ ï¼£ D ï¼¥ F G H I J K L ï¼­ ï¼® O ++ ï¼° ï¼± ï¼² ï¼³ ï¼´ ï¼µ V ï¼· X ï¼¹ Z ï½ ï½‚ c d ï½… ++ f g h i j k l ï½ ï½Ž ï½ ï½ ï½‘ ï½’ s ï½” u ++ ï½– ï½— x ï½™ z Α Î’ Γ Δ Ε Ζ Η Θ Ι Κ Λ ++ Îœ ΠΞ Ο Π Ρ Σ Τ Î¥ Φ Χ Ψ Ω α β γ ++ δ ε ζ η θ ι κ λ μ ν ξ ο Ï€ Ï Ïƒ Ï„ ++ Ï… φ χ ψ ω ã„… ㄆ ㄇ ㄈ ㄉ ã„Š ã„‹ ã„Œ ã„ ã„Ž ã„ ++ ã„ ã„‘ ã„’ ã„“ ã„” ã„• ã„– ã„— ㄘ ã„™ ã„š ã„› ã„œ ã„ ã„ž ã„Ÿ ++ ã„  ã„¡ ã„¢ ã„£ ㄤ ã„¥ ㄦ ㄧ ㄨ ã„© Ë™ ˉ ËŠ ˇ Ë‹ 一 ++ ä¹™ ä¸ ä¸ƒ 乃 ä¹ äº† 二 人 å„¿ å…¥ å…« 几 刀 åˆ åŠ› 匕 ++ å åœ åˆ ä¸‰ 下 丈 上 丫 丸 凡 ä¹… 么 也 乞 于 亡 ++ å…€ 刃 勺 åƒ å‰ å£ åœŸ 士 夕 大 女 å­ å­‘ å­“ 寸 å° ++ å°¢ å°¸ å±± å· å·¥ å·± å·² å·³ å·¾ å¹² 廾 弋 弓 æ‰ ä¸‘ ä¸ ++ ä¸ ä¸­ 丰 丹 之 å°¹ 予 云 井 互 五 亢 ä» ä»€ 仃 仆 ++ 仇 ä» ä»Š 介 仄 å…ƒ å… å…§ å…­ å…® å…¬ 冗 凶 分 切 刈 ++ å‹» 勾 å‹¿ 化 匹 åˆ å‡ å… åž åŽ„ å‹ åŠ å 壬 天 夫 ++ 太 夭 å­” å°‘ å°¤ å°º 屯 å·´ å¹» 廿 å¼” 引 心 戈 戶 手 ++ 扎 支 æ–‡ æ–— æ–¤ æ–¹ æ—¥ æ›° 月 木 欠 æ­¢ æ­¹ 毋 比 毛 ++ æ° æ°´ ç« çˆª 父 爻 片 牙 牛 犬 王 丙 世 丕 且 丘 ++ 主 ä¹ ä¹ ä¹Ž 以 付 ä»” 仕 ä»– ä»— 代 令 ä»™ 仞 å…… å…„ ++ 冉 冊 冬 凹 出 凸 刊 加 功 包 匆 北 åŒ ä»Ÿ åŠ å‰ ++ å¡ å  å¯ å® åŽ» å¯ å¤ å³ å¬ å® å© å¨ å¼ å¸ åµ å« ++ å¦ åª å² å± å° å¥ å­ å» å›› 囚 外 央 失 奴 奶 å­• ++ 它 å°¼ å·¨ å·§ å·¦ 市 布 å¹³ å¹¼ å¼ å¼˜ å¼— å¿… 戊 打 扔 ++ 扒 扑 æ–¥ æ—¦ 朮 本 未 末 札 æ­£ æ¯ æ°‘ æ° æ°¸ æ± æ±€ ++ æ°¾ 犯 玄 玉 ç“œ 瓦 甘 生 用 甩 ç”° ç”± 甲 申 ç–‹ 白 ++ çš® çš¿ ç›® 矛 矢 石 示 禾 ç©´ ç«‹ 丞 丟 ä¹’ 乓 乩 亙 ++ 交 亦 亥 仿 伉 ä¼™ 伊 伕 ä¼ ä¼ ä¼‘ ä¼ ä»² 件 ä»» ä»° ++ 仳 份 ä¼ ä¼‹ å…‰ å…‡ å…† å…ˆ å…¨ å…± å† å†° 列 刑 划 刎 ++ 刖 劣 匈 匡 匠 å° å± å‰ å åŒ åŠ å å å‹ å„ å‘ ++ å åˆ åƒ åŽ å† å’ å›  回 å› åœ³ 地 在 圭 圬 圯 圩 ++ 夙 多 夷 夸 妄 奸 妃 好 她 如 å¦ å­— å­˜ 宇 守 å®… ++ 安 寺 å°– å±¹ å·ž 帆 并 å¹´ å¼ å¼› å¿™ å¿– 戎 戌 æˆ æˆ ++ 扣 扛 托 收 æ—© æ—¨ æ—¬ æ—­ 曲 曳 有 朽 朴 朱 朵 次 ++ æ­¤ æ­» æ°– æ± æ±— æ±™ 江 æ±  æ± æ±• 污 æ±› æ± æ±Ž ç° ç‰Ÿ ++ ç‰ ç™¾ 竹 ç±³ 糸 缶 羊 ç¾½ è€ è€ƒ 而 耒 耳 è¿ è‚‰ è‚‹ ++ è‚Œ 臣 自 至 臼 舌 舛 舟 艮 色 艾 虫 è¡€ è¡Œ è¡£ 西 ++ 阡 串 亨 ä½ ä½ ä½‡ ä½— 佞 ä¼´ ä½› 何 ä¼° ä½ ä½‘ ä¼½ 伺 ++ 伸 佃 ä½” ä¼¼ 但 ä½£ 作 ä½  伯 低 伶 ä½™ ä½ ä½ˆ 佚 å…Œ ++ å…‹ å… å…µ 冶 冷 別 判 利 刪 刨 劫 助 努 劬 匣 å³ ++ åµ å å­ åž å¾ å¦ å‘Ž å§ å‘† 呃 å³ å‘ˆ å‘‚ å› å© å‘Š ++ å¹ å» å¸ å® åµ å¶ å  å¼ å‘€ å± å« åŸ å¬ å›ª å›° 囤 ++ 囫 åŠ å‘ å€ å å‡ åŽ åœ¾ å å 圻 壯 夾 å¦ å¦’ 妨 ++ 妞 妣 妙 妖 å¦ å¦¤ 妓 妊 妥 å­ å­œ å­š å­› 完 宋 å® ++ å°¬ å±€ å± å°¿ å°¾ å² å²‘ å²” 岌 å·« 希 åº åº‡ 床 å»· 弄 ++ 弟 彤 å½¢ å½· å½¹ 忘 å¿Œ å¿— å¿ å¿± å¿« 忸 忪 戒 我 抄 ++ 抗 抖 技 扶 抉 扭 把 扼 找 批 扳 抒 扯 折 扮 投 ++ 抓 抑 抆 改 æ”» 攸 æ—± æ›´ æŸ æŽ æ æ æ‘ æœ æ– æž ++ æ‰ æ† æ  æ“ æ— æ­¥ æ¯ æ±‚ 汞 æ²™ æ² æ²ˆ 沉 æ²… æ²› 汪 ++ 決 æ² æ±° 沌 汨 æ²– æ²’ æ±½ 沃 æ±² æ±¾ æ±´ 沆 汶 æ² æ²” ++ 沘 沂 ç¶ ç¼ ç½ ç¸ ç‰¢ 牡 牠 ç‹„ ç‹‚ 玖 甬 甫 ç”· 甸 ++ çš‚ 盯 矣 ç§ ç§€ 禿 究 ç³» 罕 è‚– è‚“ è‚ è‚˜ è‚› è‚š 育 ++ 良 芒 芋 èŠ è¦‹ 角 言 è°· 豆 豕 è² èµ¤ èµ° 足 身 車 ++ è¾› è¾° è¿‚ 迆 è¿… è¿„ å·¡ é‚‘ é‚¢ 邪 邦 é‚£ é…‰ 釆 里 防 ++ 阮 阱 阪 阬 並 ä¹– ä¹³ 事 些 亞 享 京 佯 ä¾ ä¾ ä½³ ++ 使 佬 ä¾› 例 來 侃 ä½° ä½µ 侈 佩 ä½» ä¾– ä½¾ ä¾ ä¾‘ 佺 ++ å…” å…’ å…• å…© å…· å…¶ å…¸ 冽 函 刻 券 刷 刺 到 刮 制 ++ å‰ åŠ¾ 劻 å’ å” å“ å‘ å¦ å· å¸ å¹ å– å” å— å‘³ 呵 ++ å’– 呸 å’• å’€ å‘» å‘· å’„ å’’ å’† 呼 å’ å‘± 呶 å’Œ å’š å‘¢ ++ 周 å’‹ 命 å’Ž 固 垃 å· åª å© å¡ å¦ å¤ å¼ å¤œ 奉 奇 ++ 奈 奄 奔 妾 妻 委 妹 妮 姑 姆 å§ å§ å§‹ 姓 姊 妯 ++ 妳 姒 姅 å­Ÿ å­¤ å­£ å®— 定 官 宜 å®™ å®› å°š 屈 å±… 屆 ++ å²· 岡 岸 岩 岫 å²± å²³ 帘 帚 帖 帕 帛 帑 幸 庚 店 ++ 府 底 庖 延 弦 弧 弩 å¾€ å¾ å½¿ å½¼ å¿ å¿  忽 念 å¿¿ ++ æ€ æ€” 怯 怵 怖 怪 怕 怡 性 怩 怫 怛 或 戕 房 戾 ++ 所 承 拉 æ‹Œ æ‹„ 抿 æ‹‚ 抹 æ‹’ æ‹› 披 æ‹“ æ‹” æ‹‹ 拈 抨 ++ 抽 押 æ‹ æ‹™ 拇 æ‹ æŠµ æ‹š 抱 拘 æ‹– æ‹— 拆 抬 æ‹Ž 放 ++ æ–§ æ–¼ æ—º 昔 易 昌 昆 昂 明 昀 æ˜ æ˜• 昊 昇 æœ æœ‹ ++ æ­ æž‹ æž• æ± æžœ æ³ æ· æž‡ æž æž— æ¯ æ° æ¿ æž‰ æ¾ æž ++ æµ æžš æž“ æ¼ æª æ² æ¬£ æ­¦ æ­§ æ­¿ æ°“ æ°› æ³£ 注 æ³³ æ²± ++ 泌 æ³¥ æ²³ æ²½ æ²¾ æ²¼ æ³¢ 沫 法 泓 沸 泄 æ²¹ æ³ æ²® æ³— ++ æ³… æ³± 沿 æ²» 泡 æ³› 泊 沬 泯 泜 æ³– æ³  ç‚• ç‚Ž ç‚’ ç‚Š ++ ç‚™ 爬 爭 爸 版 牧 物 ç‹€ ç‹Ž ç‹™ ç‹— ç‹ çŽ© 玨 玟 玫 ++ 玥 甽 ç– ç–™ ç–š çš„ 盂 盲 ç›´ 知 矽 社 祀 ç¥ ç§‰ 秈 ++ 空 穹 竺 ç³¾ ç½” 羌 羋 者 肺 è‚¥ è‚¢ 肱 è‚¡ è‚« è‚© è‚´ ++ 肪 肯 臥 臾 èˆ èŠ³ èŠ èŠ™ 芭 芽 芟 芹 花 芬 芥 芯 ++ 芸 芣 芰 芾 芷 虎 è™± åˆ è¡¨ 軋 è¿Ž è¿” è¿‘ 邵 邸 邱 ++ 邶 采 金 é•· é–€ 阜 陀 阿 阻 附 陂 éš¹ 雨 é’ éž äºŸ ++ 亭 亮 ä¿¡ ä¾µ 侯 便 ä¿  ä¿‘ ä¿ ä¿ ä¿ƒ 侶 俘 ä¿Ÿ ä¿Š ä¿— ++ ä¾® ä¿ ä¿„ ä¿‚ ä¿š ä¿Ž ä¿ž ä¾· å…— 冒 冑 冠 剎 剃 削 å‰ ++ 剌 剋 則 勇 勉 勃 å‹ åŒ å— å» åŽš å› å’¬ å“€ å’¨ å“Ž ++ 哉 å’¸ å’¦ å’³ 哇 å“‚ å’½ å’ª å“ å“„ 哈 å’¯ å’« å’± å’» å’© ++ å’§ å’¿ 囿 åž‚ åž‹ åž  垣 垢 城 åž® åž“ 奕 契 å¥ å¥Ž å¥ ++ 姜 姘 姿 姣 姨 娃 姥 姪 姚 姦 å¨ å§» å­© 宣 宦 室 ++ 客 宥 å° å±Ž å± å± å±‹ å³™ å³’ å·· å¸ å¸¥ 帟 å¹½ 庠 度 ++ 建 弈 å¼­ å½¥ 很 å¾… 徊 律 徇 後 徉 怒 æ€ æ€  急 怎 ++ 怨 æ æ° æ¨ æ¢ æ† æƒ æ¬ æ« æª æ¤ æ‰ æ‹œ 挖 按 拼 ++ æ‹­ æŒ æ‹® 拽 指 拱 æ‹· 拯 括 拾 æ‹´ 挑 挂 政 æ•… æ–« ++ æ–½ æ—¢ 春 昭 映 昧 是 星 昨 昱 昤 æ›· 柿 染 柱 柔 ++ æŸ æŸ¬ 架 枯 柵 柩 柯 柄 柑 æž´ 柚 查 枸 æŸ æŸž 柳 ++ æž° 柙 柢 æŸ æŸ’ æ­ª 殃 殆 段 毒 毗 æ°Ÿ 泉 æ´‹ æ´² æ´ª ++ æµ æ´¥ æ´Œ æ´± æ´ž æ´— æ´» æ´½ æ´¾ æ´¶ æ´› æ³µ æ´¹ æ´§ æ´¸ æ´© ++ æ´® æ´µ æ´Ž æ´« ç‚« 為 炳 炬 炯 ç‚­ 炸 ç‚® 炤 爰 牲 牯 ++ 牴 ç‹© ç‹  ç‹¡ 玷 çŠ çŽ» 玲 ç ç€ çŽ³ 甚 ç”­ ç• ç•Œ ç•Ž ++ ç•‹ ç–« ç–¤ ç–¥ ç–¢ ç–£ 癸 皆 皇 皈 盈 盆 盃 ç›… çœ ç›¹ ++ 相 眉 看 盾 盼 眇 矜 ç ‚ ç ” ç Œ ç  ç¥† 祉 祈 祇 禹 ++ 禺 科 秒 秋 ç©¿ çª ç«¿ 竽 ç±½ ç´‚ ç´… ç´€ ç´‰ ç´‡ ç´„ ç´† ++ 缸 美 羿 耄 è€ è€ è€‘ 耶 胖 胥 胚 胃 胄 背 胡 胛 ++ 胎 胞 胤 èƒ è‡´ 舢 苧 范 茅 è‹£ è‹› 苦 茄 è‹¥ 茂 茉 ++ è‹’ è‹— 英 èŒ è‹œ è‹” è‹‘ è‹ž è‹“ è‹Ÿ 苯 茆 è™ è™¹ è™» 虺 ++ è¡ è¡« è¦ è§” 計 訂 訃 貞 è²  èµ´ èµ³ 趴 è» è»Œ è¿° 迦 ++ è¿¢ 迪 è¿¥ è¿­ è¿« 迤 迨 郊 郎 éƒ éƒƒ é…‹ é…Š é‡ é–‚ é™ ++ 陋 陌 é™ é¢ é© éŸ‹ 韭 音 é  é¢¨ 飛 食 首 香 乘 亳 ++ 倌 å€ å€£ 俯 倦 倥 俸 倩 倖 倆 值 借 倚 倒 們 俺 ++ 倀 倔 倨 俱 倡 個 候 倘 俳 ä¿® 倭 倪 俾 倫 倉 å…¼ ++ 冤 冥 冢 å‡ å‡Œ 准 凋 剖 剜 剔 剛 å‰ åŒª å¿ åŽŸ åŽ ++ åŸ å“¨ å” å” å”· 哼 å“¥ 哲 唆 哺 å”” å“© å“­ å“¡ 唉 å“® ++ 哪 哦 唧 唇 哽 å” åœƒ 圄 埂 埔 埋 埃 å ‰ å¤ å¥— 奘 ++ 奚 娑 娘 娜 娟 娛 娓 姬 娠 娣 娩 娥 娌 娉 å­« 屘 ++ å®° 害 家 å®´ å®® 宵 容 宸 å°„ 屑 展 å± å³­ å³½ å³» 峪 ++ 峨 å³° 島 å´ å³´ å·® 席 師 庫 庭 座 å¼± å¾’ 徑 å¾ æ™ ++ æ£ æ¥ æ æ• æ­ æ© æ¯ æ‚„ æ‚Ÿ æ‚š æ‚ æ‚” æ‚Œ æ‚… æ‚– 扇 ++ 拳 挈 æ‹¿ æŽ æŒ¾ 振 æ• æ‚ æ† æ æ‰ æŒº æ 挽 挪 挫 ++ 挨 æ æŒ æ•ˆ 敉 æ–™ æ— æ—… 時 晉 æ™ æ™ƒ æ™’ 晌 æ™… æ™ ++ 書 朔 朕 朗 æ ¡ æ ¸ 案 框 æ¡“ æ ¹ æ¡‚ æ¡” æ © 梳 æ — æ¡Œ ++ æ¡‘ æ ½ 柴 æ¡ æ¡€ æ ¼ 桃 æ ª æ¡… æ “ æ ˜ æ¡ æ®Š 殉 æ®· æ°£ ++ æ°§ æ°¨ æ°¦ æ°¤ æ³° 浪 涕 消 涇 浦 浸 æµ· æµ™ 涓 浬 涉 ++ æµ® 浚 æµ´ 浩 涌 涊 æµ¹ 涅 æµ¥ 涔 烊 烘 烤 烙 烈 çƒ ++ 爹 特 狼 狹 狽 狸 ç‹· 玆 ç­ ç‰ ç® ç  çª çž ç•” ç• ++ ç•œ ç•š ç•™ ç–¾ ç—… ç—‡ ç–² ç–³ ç–½ ç–¼ ç–¹ ç—‚ ç–¸ çš‹ çš° 益 ++ ç› ç›Ž 眩 真 眠 眨 矩 ç ° ç § ç ¸ ç  ç ´ ç · ç ¥ ç ­ ç   ++ ç Ÿ ç ² 祕 ç¥ ç¥  祟 祖 神 ç¥ ç¥— 祚 秤 秣 秧 租 秦 ++ 秩 秘 窄 窈 ç«™ 笆 笑 粉 ç´¡ ç´— ç´‹ ç´Š ç´  ç´¢ ç´” ç´ ++ ç´• ç´š ç´œ ç´ ç´™ ç´› 缺 罟 ç¾” ç¿… ç¿ è€† 耘 耕 耙 耗 ++ 耽 耿 胱 è„‚ 胰 è„… 胭 胴 脆 胸 胳 脈 能 è„Š 胼 胯 ++ 臭 臬 舀 èˆ èˆª 舫 舨 般 芻 茫 è’ è” èŠ èŒ¸ è è‰ ++ 茵 茴 è 茲 茹 茶 茗 è€ èŒ± 茨 èƒ è™” 蚊 蚪 èš“ 蚤 ++ èš© 蚌 蚣 èšœ è¡° è¡· è¢ è¢‚ 衽 衹 記 è¨ è¨Ž 訌 訕 訊 ++ 託 訓 訖 è¨ è¨‘ 豈 豺 è±¹ 財 è²¢ èµ· 躬 è»’ è»” è» è¾± ++ é€ é€† è¿· 退 迺 è¿´ 逃 追 逅 迸 é‚• 郡 éƒ éƒ¢ é…’ é… ++ é…Œ 釘 é‡ é‡— 釜 釙 é–ƒ 院 陣 陡 é™› é™ é™¤ 陘 陞 éš» ++ 飢 馬 骨 高 鬥 鬲 鬼 ä¹¾ åº å½ åœ å‡ åƒ åŒ åš å‰ ++ å¥ å¶ åŽ å• åµ å´ å· å å€ å¯ å­ å…œ 冕 凰 剪 副 ++ å‹’ å‹™ 勘 å‹• åŒ åŒ åŒ™ 匿 å€ åŒ¾ åƒ æ›¼ 商 啪 啦 å•„ ++ å•ž å•¡ 啃 å•Š å”± å•– å• å•• 唯 啤 唸 å”® å•œ 唬 å•£ 唳 ++ å• å•— 圈 國 圉 域 å … å Š å † 埠 埤 基 å ‚ å µ 執 培 ++ 夠 奢 娶 å© å©‰ 婦 婪 å©€ 娼 å©¢ å©š 婆 å©Š å­° 寇 寅 ++ 寄 寂 宿 密 å°‰ å°ˆ å°‡ å±  屜 å± å´‡ å´† å´Ž å´› å´– å´¢ ++ å´‘ å´© å´” å´™ å´¤ å´§ å´— å·¢ 常 帶 帳 帷 康 庸 庶 庵 ++ 庾 å¼µ å¼· å½— 彬 彩 彫 å¾— å¾™ 從 徘 御 å¾  徜 æ¿ æ‚£ ++ 悉 æ‚  您 惋 æ‚´ 惦 悽 情 æ‚» 悵 惜 悼 惘 惕 惆 惟 ++ 悸 惚 惇 戚 戛 扈 掠 控 æ² æŽ– 探 接 æ· æ§ æŽ˜ 措 ++ æ± æŽ© 掉 掃 掛 æ« æŽ¨ 掄 授 掙 採 掬 排 æŽ æŽ€ æ» ++ æ© æ¨ æº æ• æ•– æ•‘ æ•™ æ•— å•Ÿ æ• æ•˜ æ•• æ•” æ–œ æ–› æ–¬ ++ æ— æ—‹ æ—Œ æ—Ž æ™ æ™š 晤 晨 晦 晞 曹 å‹— 望 æ¢ æ¢¯ 梢 ++ 梓 梵 æ¡¿ 桶 梱 梧 梗 械 梃 棄 梭 梆 梅 梔 æ¢ æ¢¨ ++ 梟 梡 梂 欲 殺 毫 毬 æ°« 涎 涼 æ·³ æ·™ 液 æ·¡ æ·Œ æ·¤ ++ æ·» æ·º 清 æ·‡ æ·‹ 涯 æ·‘ 涮 æ·ž æ·¹ 涸 æ·· æ·µ æ·… æ·’ 渚 ++ 涵 æ·š æ·« æ·˜ æ·ª æ·± æ·® æ·¨ æ·† æ·„ 涪 æ·¬ 涿 æ·¦ 烹 焉 ++ ç„Š 烽 烯 爽 牽 çŠ çŒœ 猛 猖 猓 猙 率 ç… çŠ çƒ ç† ++ ç¾ ç ç“  瓶 ç“· 甜 產 ç•¥ 畦 ç•¢ ç•° ç– ç—” ç—• ç–µ ç—Š ++ ç— çšŽ ç›” ç›’ ç›› 眷 眾 眼 眶 眸 眺 ç¡« 硃 ç¡Ž 祥 票 ++ 祭 移 窒 窕 笠 笨 笛 第 符 笙 笞 笮 ç²’ ç²— 粕 絆 ++ 絃 çµ± ç´® ç´¹ ç´¼ çµ€ ç´° ç´³ 組 ç´¯ 終 ç´² ç´± ç¼½ 羞 羚 ++ ç¿Œ ç¿Ž ç¿’ 耜 èŠ è† è„¯ è„– è„£ è„« è„© è„° 脤 舂 舵 舷 ++ 舶 船 莎 莞 莘 è¸ èŽ¢ 莖 莽 莫 莒 莊 莓 莉 莠 è· ++ è» è¼ èŽ† 莧 處 彪 蛇 蛀 蚶 蛄 èšµ 蛆 蛋 èš± 蚯 蛉 ++ è¡“ 袞 袈 被 袒 袖 è¢ è¢‹ 覓 è¦ è¨ª è¨ è¨£ 訥 許 設 ++ 訟 訛 訢 豉 豚 販 責 貫 貨 貪 貧 赧 赦 趾 趺 è»› ++ 軟 這 é€ é€š 逗 連 速 é€ é€ é€• 逞 造 é€ é€¢ 逖 逛 ++ 途 部 郭 都 é…— 野 釵 釦 釣 釧 釭 釩 é–‰ 陪 陵 陳 ++ 陸 é™° é™´ 陶 é™· 陬 雀 雪 雩 ç«  ç«Ÿ é ‚ é ƒ é­š é³¥ é¹µ ++ 鹿 麥 麻 å‚¢ å‚ å‚… å‚™ å‚‘ å‚€ å‚– 傘 å‚š 最 凱 割 剴 ++ 創 剩 å‹ž å‹ å‹› åš åŽ¥ å•» å–€ å–§ 啼 å–Š å– å–˜ å–‚ å–œ ++ å–ª å–” å–‡ å–‹ å–ƒ å–³ å–® å–Ÿ 唾 å–² å–š å–» å–¬ å–± 啾 å–‰ ++ å–« å–™ åœ å ¯ å ª å ´ å ¤ å ° å ± å ¡ å  å   壹 壺 奠 å©· ++ 媚 å©¿ 媒 媛 媧 å­³ å­± 寒 富 寓 å¯ å°Š å°‹ å°± 嵌 åµ ++ å´´ 嵇 å·½ å¹… 帽 å¹€ 幃 å¹¾ 廊 å» å»‚ 廄 å¼¼ å½­ 復 循 ++ 徨 惑 惡 悲 悶 惠 æ„œ æ„£ 惺 æ„• 惰 惻 惴 æ…¨ 惱 æ„Ž ++ 惶 愉 æ„€ æ„’ 戟 扉 掣 掌 æ æ€ æ© æ‰ æ† æ æ’ æ£ ++ æ æ¡ æ– æ­ æ® æ¶ æ´ æª æ› æ‘’ æš æ¹ æ•ž 敦 æ•¢ æ•£ ++ æ–‘ æ– æ–¯ æ™® æ™° æ™´ 晶 景 æš‘ 智 晾 æ™· 曾 替 期 æœ ++ 棺 棕 棠 棘 棗 椅 棟 棵 森 棧 棹 棒 棲 棣 棋 æ£ ++ æ¤ æ¤’ 椎 棉 棚 楮 棻 款 欺 欽 殘 æ®– 殼 毯 æ°® æ°¯ ++ æ°¬ 港 游 æ¹” 渡 渲 湧 湊 渠 渥 渣 減 æ¹› 湘 渤 æ¹– ++ æ¹® 渭 渦 湯 渴 æ¹ æ¸º 測 湃 æ¸ æ¸¾ 滋 溉 渙 湎 æ¹£ ++ 湄 æ¹² 湩 湟 ç„™ ç„š 焦 ç„° ç„¡ 然 ç…® ç„œ 牌 犄 犀 猶 ++ 猥 猴 猩 çº çª ç³ ç¢ ç¥ çµ ç¶ ç´ ç¯ ç› ç¦ ç¨ ç”¥ ++ 甦 ç•« 番 ç—¢ ç—› ç—£ ç—™ ç—˜ ç—ž ç—  ç™» 發 çš– çš“ çš´ 盜 ++ ç 短 ç¡ ç¡¬ 硯 ç¨ ç¨ˆ 程 稅 稀 窘 窗 窖 ç«¥ ç«£ ç­‰ ++ ç­– ç­† ç­ ç­’ ç­” ç­ ç­‹ ç­ ç­‘ 粟 ç²¥ 絞 çµ çµ¨ 絕 ç´« ++ çµ® çµ² 絡 給 çµ¢ çµ° çµ³ å–„ ç¿” ç¿• 耋 è’ è‚… è…• è…” è…‹ ++ è…‘ è…Ž 脹 è…† 脾 è…Œ è…“ è…´ 舒 舜 è© èƒ è¸ è è  è… ++ è‹ è è¯ è± è´ è‘— èŠ è° èŒ èŒ è½ è² èŠ è¸ èŽ è„ ++ èœ è‡ è” èŸ è™› 蛟 è›™ è›­ è›” è›› 蛤 è› è›ž è¡— è£ è£‚ ++ 袱 覃 視 註 è©  è©• è©ž 証 è© è©” è©› è© è©† 訴 診 訶 ++ è©– 象 貂 貯 è²¼ è²³ è²½ è³ è²» è³€ è²´ è²· 貶 貿 貸 越 ++ 超 è¶ è·Ž è· è·‹ è·š è·‘ è·Œ è·› è·† è»» 軸 軼 辜 逮 逵 ++ 週 逸 進 逶 é„‚ 郵 鄉 郾 é…£ é…¥ é‡ éˆ” 鈕 鈣 鈉 鈞 ++ éˆ éˆ éˆ‡ 鈑 é–” é– é–‹ é–‘ é–“ é–’ é–Ž 隊 階 éš‹ 陽 éš… ++ 隆 éš é™² éš„ é› é›… 雄 集 雇 雯 雲 韌 é … é † é ˆ 飧 ++ 飪 飯 飩 飲 飭 馮 馭 黃 é» é»‘ 亂 å‚­ 債 傲 傳 僅 ++ 傾 催 å‚· å‚» 傯 僇 剿 剷 剽 å‹Ÿ 勦 勤 å‹¢ å‹£ 匯 å—Ÿ ++ å—¨ å—“ å—¦ å—Ž å—œ å—‡ å—‘ å—£ å—¤ å—¯ å—š å—¡ å—… å—† å—¥ å—‰ ++ 園 圓 å¡ž å¡‘ 塘 å¡— å¡š å¡” å¡« å¡Œ å¡­ å¡Š å¡¢ å¡’ å¡‹ 奧 ++ å« å«‰ å«Œ 媾 媽 媼 媳 å«‚ 媲 嵩 嵯 幌 å¹¹ 廉 廈 å¼’ ++ å½™ 徬 å¾® æ„š æ„ æ…ˆ æ„Ÿ 想 æ„› 惹 æ„ æ„ˆ æ…Ž æ…Œ æ…„ æ… ++ 愾 æ„´ 愧 æ„ æ„† æ„· 戡 戢 æ“ æ¾ æž æª æ­ æ½ æ¬ æ ++ æœ æ” æ æ¶ æ– æ— æ† æ•¬ æ–Ÿ æ–° æš— 暉 暇 暈 æš– æš„ ++ 暘 æš æœƒ 榔 業 楚 楷 楠 楔 極 椰 概 楊 楨 楫 楞 ++ 楓 楹 榆 æ¥ æ¥£ 楛 æ­‡ æ­² 毀 殿 毓 毽 溢 溯 滓 溶 ++ 滂 æº æº æ»‡ æ»… 溥 溘 溼 溺 溫 滑 準 溜 滄 æ»” 溪 ++ 溧 溴 ç…Ž ç…™ ç…© ç…¤ ç…‰ ç…§ ç…œ ç…¬ ç…¦ ç…Œ ç…¥ ç…ž ç…† ç…¨ ++ ç…– 爺 牒 猷 ç… çŒ¿ 猾 瑯 ç‘š ç‘• ç‘Ÿ ç‘ž ç‘ ç¿ ç‘™ ç‘› ++ ç‘œ 當 畸 瘀 ç—° ç˜ ç—² ç—± ç—º ç—¿ ç—´ ç—³ 盞 盟 ç› ç« ++ ç¦ çž ç£ ç¹ çª ç¬ çœ ç¥ ç¨ ç¢ çŸ® 碎 碰 碗 碘 碌 ++ 碉 硼 碑 碓 ç¡¿ 祺 祿 ç¦ è¬ ç¦½ 稜 稚 稠 稔 稟 稞 ++ 窟 窠 ç­· 節 ç­  ç­® ç­§ ç²± ç²³ ç²µ 經 çµ¹ 綑 ç¶ ç¶ çµ› ++ ç½® 罩 罪 ç½² 義 羨 群 è– è˜ è‚† è‚„ è…± è…° è…¸ è…¥ è…® ++ è…³ è…« è…¹ è…º è…¦ 舅 艇 è’‚ è‘· è½ è± è‘µ 葦 è‘« 葉 葬 ++ è‘› è¼ èµ è‘¡ è‘£ è‘© è‘­ 葆 虞 虜 號 蛹 蜓 蜈 蜇 蜀 ++ 蛾 è›» 蜂 蜃 蜆 蜊 è¡™ 裟 裔 裙 補 裘 è£ è£¡ 裊 裕 ++ 裒 覜 解 è©« 該 詳 試 è©© è©° 誇 詼 è©£ 誠 話 誅 è©­ ++ è©¢ è©® 詬 詹 è©» 訾 詨 è±¢ 貊 貉 賊 資 賈 賄 è²² 賃 ++ 賂 è³… è·¡ è·Ÿ è·¨ è·¯ è·³ è·º è·ª è·¤ è·¦ 躲 較 載 軾 輊 ++ 辟 è¾² é‹ éŠ é“ é‚ é” é€¼ é• é é‡ é éŽ é é‘ é€¾ ++ é é„’ é„— é…¬ é…ª é…© 釉 鈷 鉗 鈸 鈽 鉀 鈾 鉛 鉋 鉤 ++ 鉑 鈴 鉉 é‰ é‰… 鈹 鈿 鉚 é–˜ 隘 éš” éš• é› é›‹ 雉 雊 ++ é›· é›» 雹 零 é– é´ é¶ é  é ‘ é “ é Š é ’ é Œ 飼 飴 飽 ++ 飾 馳 馱 馴 é«¡ 鳩 麂 鼎 鼓 é¼  僧 僮 僥 僖 僭 僚 ++ 僕 åƒ åƒ‘ 僱 僎 僩 å…¢ 凳 劃 劂 匱 厭 å—¾ 嘀 嘛 嘗 ++ å—½ 嘔 嘆 嘉 å˜ å˜Ž å—· 嘖 嘟 嘈 å˜ å—¶ 團 圖 塵 塾 ++ 境 墓 墊 塹 墅 塽 壽 夥 夢 夤 奪 奩 å«¡ 嫦 å«© å«— ++ å«– 嫘 å«£ å­µ 寞 寧 寡 寥 實 寨 寢 寤 察 å° å±¢ 嶄 ++ 嶇 å¹› å¹£ 幕 å¹— å¹” 廓 å»– 弊 彆 å½° å¾¹ æ…‡ æ„¿ æ…‹ æ…· ++ æ…¢ æ…£ æ…Ÿ æ…š æ…˜ æ…µ 截 æ’‡ 摘 æ‘” æ’¤ 摸 æ‘Ÿ 摺 æ‘‘ 摧 ++ æ´ æ‘­ æ‘» 敲 æ–¡ æ—— æ—– 暢 暨 æš æ¦œ 榨 榕 æ§ æ¦® 槓 ++ 構 榛 榷 榻 榫 榴 æ§ æ§ æ¦­ 槌 榦 槃 榣 æ­‰ æ­Œ æ°³ ++ æ¼³ æ¼” 滾 漓 æ»´ 漩 æ¼¾ æ¼  漬 æ¼ æ¼‚ æ¼¢ 滿 滯 漆 æ¼± ++ 漸 æ¼² æ¼£ 漕 漫 漯 澈 漪 滬 æ¼ æ»² 滌 æ»· 熔 熙 ç…½ ++ 熊 熄 熒 爾 犒 犖 ç„ ç 瑤 ç‘£ 瑪 ç‘° ç‘­ 甄 ç–‘ 瘧 ++ ç˜ ç˜‹ 瘉 瘓 盡 監 çž„ ç½ ç¿ ç¡ ç£ ç¢Ÿ 碧 碳 碩 碣 ++ 禎 ç¦ ç¦ ç¨® 稱 窪 窩 ç«­ 端 管 箕 箋 ç­µ ç®— ç® ç®” ++ ç® ç®¸ 箇 箄 ç²¹ ç²½ ç²¾ 綻 綰 綜 綽 綾 綠 ç·Š 綴 網 ++ 綱 綺 綢 綿 綵 綸 維 ç·’ ç·‡ 綬 ç½° ç¿  ç¿¡ ç¿Ÿ èž èš ++ 肇 è… è†€ è† è†ˆ 膊 è…¿ 膂 臧 臺 與 舔 舞 艋 蓉 è’¿ ++ 蓆 è“„ è’™ è’ž è’² è’œ è“‹ è’¸ è“€ è““ è’ è’¼ è“‘ è“Š 蜿 蜜 ++ 蜻 蜢 蜥 蜴 蜘 è• èœ· 蜩 裳 褂 裴 裹 裸 製 裨 褚 ++ 裯 誦 誌 語 誣 èª èª¡ 誓 誤 說 誥 誨 誘 誑 誚 誧 ++ 豪 è² è²Œ 賓 賑 è³’ 赫 趙 趕 è·¼ è¼” è¼’ 輕 輓 è¾£ é  ++ é˜ éœ é£ é™ éž é¢ é é› é„™ 鄘 é„ž é…µ é…¸ é…· é…´ 鉸 ++ 銀 銅 銘 銖 鉻 銓 銜 銨 鉼 銑 é–¡ é–¨ é–© é–£ é–¥ é–¤ ++ éš™ éšœ éš› 雌 é›’ 需 é¼ éž… 韶 é — é ˜ 颯 颱 餃 餅 餌 ++ 餉 é§ éª¯ 骰 髦 é­ é­‚ é³´ 鳶 é³³ 麼 é¼» 齊 å„„ å„€ 僻 ++ 僵 價 å„‚ 儈 儉 å„… 凜 劇 劈 劉 åŠ åŠŠ å‹° 厲 嘮 嘻 ++ 嘹 嘲 嘿 嘴 嘩 噓 噎 å™— å™´ 嘶 嘯 嘰 墀 墟 增 墳 ++ 墜 墮 墩 墦 奭 嬉 å«» 嬋 嫵 嬌 嬈 寮 寬 審 寫 層 ++ å±¥ å¶ å¶” å¹¢ 幟 幡 廢 廚 廟 å» å»£ å»  彈 å½± å¾· å¾µ ++ æ…¶ æ…§ æ…® æ… æ…• 憂 æ…¼ æ…° æ…« æ…¾ 憧 æ† æ†« 憎 憬 憚 ++ 憤 憔 憮 戮 æ‘© 摯 摹 æ’ž æ’² æ’ˆ æ’ æ’° æ’¥ æ’“ æ’• æ’© ++ æ’’ æ’® æ’­ æ’« æ’š æ’¬ æ’™ æ’¢ æ’³ 敵 æ•· 數 æš® æš« æš´ æš± ++ 樣 樟 槨 æ¨ æ¨ž 標 槽 模 樓 樊 槳 樂 樅 槭 樑 æ­ ++ æ­Ž 殤 毅 毆 漿 æ½¼ 澄 潑 潦 æ½” 澆 æ½­ æ½› 潸 æ½® 澎 ++ 潺 æ½° 潤 æ¾— 潘 滕 潯 æ½  潟 熟 熬 熱 熨 牖 犛 çŽ ++ ç— ç‘© ç’‹ ç’ƒ 瑾 ç’€ ç•¿ 瘠 瘩 瘟 瘤 瘦 瘡 瘢 çšš 皺 ++ 盤 瞎 瞇 瞌 çž‘ çž‹ 磋 磅 確 磊 碾 磕 碼 ç£ ç¨¿ 稼 ++ ç©€ 稽 稷 稻 窯 窮 ç®­ ç®± 範 ç®´ 篆 篇 ç¯ ç®  篌 糊 ++ ç·  ç·´ ç·¯ ç·» ç·˜ ç·¬ ç· ç·¨ ç·£ ç·š ç·ž ç·© 綞 ç·™ ç·² ç·¹ ++ ç½µ ç½· 羯 ç¿© 耦 膛 膜 è† è†  膚 膘 è”— 蔽 蔚 è“® 蔬 ++ è”­ 蔓 蔑 蔣 蔡 è”” 蓬 蔥 è“¿ 蔆 èž‚ è´ è¶ è  è¦ è¸ ++ è¨ è™ è— èŒ è“ è¡› è¡ è¤ è¤‡ 褒 褓 褕 褊 誼 è«’ 談 ++ è«„ 誕 è«‹ 諸 課 諉 è«‚ 調 誰 è«– è« èª¶ 誹 è«› 豌 豎 ++ 豬 è³  賞 賦 賤 賬 è³­ è³¢ è³£ 賜 質 賡 èµ­ 趟 趣 踫 ++ è¸ è¸ è¸¢ è¸ è¸© 踟 踡 踞 躺 è¼ è¼› 輟 輩 輦 輪 輜 ++ 輞 è¼¥ é© é® é¨ é­ é· é„° é„­ 鄧 鄱 醇 醉 醋 醃 é‹… ++ 銻 銷 鋪 銬 鋤 é‹ éŠ³ 銼 é‹’ 鋇 é‹° 銲 é–­ é–± 霄 霆 ++ 震 霉 é  éž éž‹ éž é ¡ é « é œ 颳 養 餓 餒 餘 é§ é§ ++ 駟 駛 駑 駕 駒 駙 骷 é«® 髯 鬧 é­… é­„ é­· é­¯ é´† é´‰ ++ é´ƒ 麩 麾 黎 墨 é½’ å„’ 儘 å„” å„ å„• 冀 冪 å‡ åŠ‘ 劓 ++ 勳 å™™ 噫 噹 噩 噤 噸 噪 器 噥 å™± 噯 噬 噢 噶 å£ ++ 墾 壇 壅 奮 å¬ å¬´ å­¸ 寰 å°Ž 彊 憲 憑 憩 憊 æ‡ æ†¶ ++ 憾 懊 懈 戰 æ“… æ“ æ“‹ æ’» æ’¼ æ“š æ“„ 擇 æ“‚ æ“ æ’¿ æ“’ ++ æ“” æ’¾ æ•´ 曆 曉 æš¹ 曄 曇 暸 樽 樸 樺 æ©™ æ©« 橘 樹 ++ æ©„ æ©¢ æ©¡ æ©‹ 橇 樵 æ©Ÿ 橈 æ­™ æ­· æ°… æ¿‚ æ¾± 澡 濃 澤 ++ æ¿ æ¾§ æ¾³ æ¿€ æ¾¹ 澶 澦 æ¾  æ¾´ 熾 燉 ç‡ ç‡’ 燈 燕 熹 ++ 燎 燙 燜 燃 燄 ç¨ ç’œ ç’£ ç’˜ ç’Ÿ ç’ž ç“¢ 甌 ç” ç˜´ 瘸 ++ 瘺 盧 盥 çž  çžž 瞟 瞥 磨 磚 磬 磧 禦 ç© ç©Ž 穆 ç©Œ ++ ç©‹ 窺 篙 ç°‘ 築 篤 篛 篡 篩 篦 糕 ç³– 縊 縑 縈 縛 ++ 縣 縞 ç¸ ç¸‰ ç¸ ç½¹ ç¾² ç¿° 翱 ç¿® 耨 膳 膩 膨 臻 興 ++ 艘 艙 è•Š è•™ 蕈 蕨 è•© 蕃 蕉 è•­ 蕪 è•ž 螃 螟 èžž 螢 ++ èž è¡¡ 褪 褲 褥 褫 褡 親 覦 諦 諺 è«« 諱 謀 è«œ 諧 ++ è«® 諾 è¬ è¬‚ è«· è«­ 諳 諶 諼 豫 è±­ 貓 è³´ 蹄 踱 踴 ++ 蹂 踹 踵 è¼» 輯 輸 è¼³ 辨 辦 éµ é´ é¸ é² é¼ éº é„´ ++ 醒 錠 錶 鋸 錳 錯 錢 鋼 錫 錄 錚 éŒ éŒ¦ 錡 錕 錮 ++ 錙 é–» 隧 隨 險 雕 霎 霑 霖 éœ éœ“ éœ é› éœ é¦ éž˜ ++ é ° é ¸ é » é · é ­ é ¹ é ¤ é¤ é¤¨ 餞 餛 餡 餚 駭 駢 駱 ++ 骸 骼 é«» é«­ 鬨 鮑 é´• é´£ é´¦ é´¨ é´’ é´› 默 é»” é¾ é¾œ ++ 優 å„Ÿ å„¡ 儲 勵 嚎 嚀 åš åš… 嚇 åš å£• 壓 壑 壎 嬰 ++ 嬪 嬤 å­º å°· 屨 嶼 嶺 嶽 嶸 幫 彌 å¾½ 應 懂 懇 懦 ++ 懋 戲 戴 æ“Ž æ“Š 擘 æ“  æ“° 擦 擬 擱 æ“¢ æ“­ æ–‚ æ–ƒ æ›™ ++ æ›– 檀 檔 檄 檢 檜 æ«› 檣 橾 檗 æª æª  æ­œ æ®® 毚 æ°ˆ ++ 濘 濱 æ¿Ÿ æ¿  æ¿› 濤 æ¿« 濯 æ¾€ 濬 æ¿¡ æ¿© æ¿• æ¿® æ¿° 燧 ++ 營 燮 燦 燥 燭 燬 燴 燠 爵 牆 ç° ç² ç’© ç’° ç’¦ ç’¨ ++ 癆 療 癌 盪 çž³ 瞪 çž° 瞬 瞧 çž­ 矯 磷 磺 磴 磯 ç¤ ++ 禧 禪 ç©— 窿 ç°‡ ç° ç¯¾ 篷 ç°Œ 篠 ç³  糜 糞 ç³¢ 糟 ç³™ ++ ç³ ç¸® 績 繆 縷 縲 繃 縫 總 縱 ç¹… ç¹ ç¸´ 縹 繈 縵 ++ 縿 縯 罄 翳 翼 è± è² è° è¯ è³ è‡† 臃 膺 臂 臀 膿 ++ 膽 臉 膾 臨 舉 艱 è–ª è–„ 蕾 è–œ è–‘ è–” è–¯ è–› è–‡ è–¨ ++ è–Š 虧 蟀 蟑 èž³ 蟒 蟆 èž« èž» 螺 蟈 蟋 褻 褶 襄 褸 ++ 褽 覬 謎 謗 謙 講 謊 謠 è¬ è¬„ è¬ è± è°¿ è±³ 賺 è³½ ++ è³¼ 賸 è³» 趨 蹉 蹋 蹈 蹊 轄 è¼¾ 轂 è½… 輿 é¿ é½ é‚„ ++ é‚ é‚‚ é‚€ 鄹 醣 醞 醜 é 鎂 錨 éµ éŠ é¥ é‹ éŒ˜ é¾ ++ é¬ é› é° éš é” é—Š é—‹ é—Œ é—ˆ é—† éš± 隸 é›– 霜 霞 éž  ++ 韓 顆 颶 餵 é¨ é§¿ é®® 鮫 鮪 é®­ é´» é´¿ 麋 é» é»ž 黜 ++ é» é»› é¼¾ 齋 å¢ åš• åš® 壙 壘 嬸 å½ æ‡£ 戳 æ“´ 擲 擾 ++ 攆 擺 æ“» æ“· æ–· 曜 朦 檳 檬 櫃 檻 檸 æ«‚ 檮 檯 æ­Ÿ ++ æ­¸ 殯 瀉 瀋 濾 瀆 濺 瀑 ç€ ç‡» 燼 燾 燸 ç· çµ ç’§ ++ ç’¿ 甕 ç™– 癘 ç™’ çž½ çž¿ çž» çž¼ 礎 禮 ç©¡ ç©¢ ç©  ç«„ ç«… ++ ç°« ç°§ ç°ª ç°ž ç°£ ç°¡ 糧 ç¹” 繕 繞 繚 繡 ç¹’ ç¹™ 罈 翹 ++ ç¿» è· è¶ è‡ è‡ èˆŠ è— è–© è— è— è—‰ è–° è–º è–¹ è–¦ 蟯 ++ 蟬 蟲 蟠 覆 覲 觴 謨 謹 謬 謫 è± è´… è¹™ è¹£ 蹦 蹤 ++ 蹟 蹕 軀 轉 è½ é‚‡ 邃 邈 醫 醬 é‡ éŽ” 鎊 鎖 鎢 鎳 ++ 鎮 鎬 鎰 鎘 鎚 鎗 é—” é—– é— é—• 離 雜 é›™ é›› 雞 霤 ++ 鞣 鞦 éž­ 韹 é¡ é¡ é¡Œ é¡Ž é¡“ 颺 餾 餿 餽 餮 馥 騎 ++ é« é¬ƒ 鬆 é­ é­Ž é­ é¯Š 鯉 鯽 鯈 鯀 鵑 éµ éµ  é»  鼕 ++ 鼬 儳 嚥 壞 壟 壢 寵 é¾ å»¬ 懲 懷 懶 懵 攀 æ” æ›  ++ æ› æ«¥ æ« æ«š æ«“ 瀛 瀟 瀨 瀚 ç€ ç€• 瀘 爆 çˆ ç‰˜ 犢 ++ ç¸ çº ç’½ ç“Š ç“£ ç–‡ ç–† 癟 癡 矇 礙 禱 ç©« ç©© ç°¾ ç°¿ ++ ç°¸ ç°½ ç°· ç±€ 繫 ç¹­ ç¹¹ 繩 繪 ç¾… ç¹³ 羶 ç¾¹ 羸 臘 è—© ++ è— è—ª è—• è—¤ è—¥ è—· 蟻 è … è  èŸ¹ 蟾 襠 襟 襖 襞 è­ ++ è­œ è­˜ è­‰ è­š è­Ž è­ è­† è­™ è´ˆ è´Š è¹¼ è¹² 躇 蹶 蹬 蹺 ++ è¹´ è½” 轎 è¾­ é‚Š é‚‹ 醱 醮 é¡ é‘ éŸ éƒ éˆ éœ é é– ++ é¢ é é˜ é¤ é— é¨ é—œ éš´ 難 霪 霧 é¡ éŸœ 韻 é¡ž 願 ++ é¡› 颼 饅 饉 騖 騙 é¬ é¯¨ 鯧 鯖 鯛 鶉 鵡 éµ² 鵪 鵬 ++ 麒 麗 麓 麴 勸 嚨 åš· 嚶 åš´ åš¼ 壤 å­€ å­ƒ å­½ 寶 å·‰ ++ 懸 懺 攘 æ”” æ”™ 曦 朧 櫬 瀾 瀰 瀲 çˆ ç» ç“ ç™¢ 癥 ++ 礦 礪 礬 礫 竇 競 籌 籃 ç± ç³¯ ç³° è¾® ç¹½ ç¹¼ 纂 罌 ++ 耀 臚 艦 è—» è—¹ 蘑 è—º 蘆 蘋 蘇 蘊 è ” è • 襤 覺 觸 ++ è­° è­¬ è­¦ è­¯ è­Ÿ è­« è´ è´ èº‰ èº èº… 躂 醴 釋 é˜ éƒ ++ é½ é—¡ 霰 飄 饒 饑 馨 騫 騰 騷 騵 é°“ é° é¹¹ 麵 黨 ++ 鼯 齟 é½£ 齡 å„· 儸 å› å›€ 囂 夔 屬 å· æ‡¼ 懾 æ” æ”œ ++ æ–• 曩 æ«» 欄 櫺 殲 çŒ çˆ› 犧 ç“– ç“” 癩 矓 ç± çº çºŒ ++ ç¾¼ 蘗 蘭 蘚 è £ è ¢ è ¡ è Ÿ 襪 襬 覽 è­´ è­· è­½ è´“ 躊 ++ èº èº‹ 轟 辯 醺 é® é³ éµ éº é¸ é² é« é—¢ 霸 霹 露 ++ 響 顧 é¡¥ 饗 é©… 驃 é©€ 騾 é« é­” é­‘ é°­ é°¥ 鶯 鶴 é·‚ ++ 鶸 éº é»¯ é¼™ 齜 齦 齧 儼 å„» 囈 囊 囉 å­¿ å·” å·’ 彎 ++ 懿 攤 權 æ­¡ ç‘ ç˜ çŽ€ 瓤 ç–Š ç™® 癬 禳 ç±  籟 è¾ è½ ++ 臟 襲 襯 觼 讀 è´– è´— 躑 躓 轡 é…ˆ é‘„ é‘‘ é‘’ 霽 霾 ++ 韃 éŸ é¡« 饕 é©• é© é«’ 鬚 鱉 é°± é°¾ é°» é·“ é·— é¼´ 齬 ++ 齪 é¾” 囌 å·– 戀 攣 攫 攪 曬 æ¬ ç“š ç«Š 籤 ç±£ ç±¥ 纓 ++ 纖 纔 臢 蘸 蘿 è ± 變 é‚ é‚ é‘£ é‘  鑤 é¨ é¡¯ 饜 é©š ++ é©› é©— é«“ é«” é«‘ é±” é±— é±– é·¥ 麟 é»´ 囑 壩 攬 çž ç™± ++ 癲 矗 ç½ ç¾ˆ è ¶ è ¹ è¡¢ 讓 è®’ è®– 艷 è´› 釀 鑪 é‚ éˆ ++ é„ éŸ† é¡° é©Ÿ 鬢 é­˜ 鱟 é·¹ é·º é¹¼ é¹½ 鼇 é½· é½² 廳 欖 ++ ç£ ç±¬ ç±® è » 觀 躡 é‡ é‘² é‘° 顱 饞 é«– 鬣 黌 ç¤ çŸš ++ 讚 é‘· 韉 é©¢ é©¥ 纜 讜 躪 釅 鑽 鑾 鑼 é±· 鱸 é»· è±” ++ é‘¿ 鸚 爨 驪 鬱 鸛 鸞 ç±² â‘  â‘¡ â‘¢ â‘£ ⑤ â‘¥ ⑦ ⑧ ++ ⑨ â‘© â‘´ ⑵ ⑶ â‘· ⑸ ⑹ ⑺ â‘» ⑼ ⑽ â…° â…± â…² â…³ ++ â…´ â…µ â…¶ â…· â…¸ â…¹ 丶 丿 亅 亠 冂 冖 冫 勹 匸 å© ++ 厶 夊 宀 å·› â¼³ 广 å½ å½¡ æ”´ ç–’ è¾µ ¨ ˆ ヽ ヾ ã‚ ++ ã‚ž 々 〆 〇 ー ï¼» ï¼½ ✽ ã ã‚ ãƒ ã„ ã… ã† ã‡ ãˆ ++ ㉠㊠㋠㌠ã ㎠ã ã 㑠㒠㓠㔠㕠㖠㗠㘠++ 㙠㚠㛠㜠ã ãž ãŸ ã  ã¡ ã¢ ã£ ã¤ ã¥ ã¦ ã§ ã¨ ++ 㩠㪠㫠㬠㭠㮠㯠㰠㱠㲠㳠㴠㵠㶠㷠㸠++ 㹠㺠㻠㼠㽠㾠㿠む ã‚ ã‚‚ ゃ ã‚„ ã‚… ゆ ょ よ ++ ら ã‚Š ã‚‹ ã‚Œ ã‚ ã‚Ž ã‚ ã‚ ã‚‘ ã‚’ ã‚“ ã‚¡ ã‚¢ ã‚£ イ ã‚¥ ++ ウ ェ エ ã‚© オ ã‚« ガ ã‚­ ã‚® ク ã‚° ケ ゲ コ ã‚´ サ ++ ザ ã‚· ジ ス ズ ã‚» ゼ ソ ゾ ã‚¿ ダ ムヂ ッ ツ ヅ ++ テ デ ト ド ナ ニ ヌ ムノ ムムパ ヒ ビ ピ フ ++ ブ プ ヘ ベ ペ ホ ボ ムマ ミ ム メ モ ャ ヤ ュ ++ ユ ョ ヨ ラ リ ル レ ロ ヮ ワ ヰ ヱ ヲ ン ヴ ヵ ++ ヶ РБ Ð’ Г Д Е РЖ З И Й К Л Ðœ Ð ++ О П Р С Т У Ф Ð¥ Ц Ч Ш Щ Ъ Ы Ь Э ++ Ю Я а б в г д е Ñ‘ ж з и й к л м ++ н о п Ñ€ Ñ Ñ‚ у Ñ„ Ñ… ц ч ш щ ÑŠ Ñ‹ ÑŒ ++ Ñ ÑŽ Ñ â‡§ ↸ ↹ ㇠𠃌 乚 ð ‚Š 刂 ä’‘ é¾° 冈 é¾± 𧘇 ++ ï¿¢ ¦ ' " ㈱ â„– â„¡ ã‚› ã‚œ ⺀ ⺄ ⺆ ⺇ ⺈ ⺊ ⺌ ++ ⺠⺕ ⺜ ⺠⺥ ⺧ ⺪ ⺬ ⺮ ⺶ ⺼ ⺾ ⻆ ⻊ ⻌ â» ++ â» â»– â»— ⻞ ⻣ ʃ É É› É” ɵ Å“ ø Å‹ ÊŠ ɪ 乂 ++ 乜 凵 匚 厂 万 丌 乇 äº å›— 兀 å±® å½³ ä¸ å†‡ 与 丮 ++ 亓 仂 仉 仈 冘 勼 å¬ åŽ¹ 圠 夃 夬 å° å·¿ æ—¡ 殳 毌 ++ æ°” 爿 丱 丼 仨 仜 仩 仡 ä» ä»š 刌 匜 åŒ åœ¢ 圣 夗 ++ 夯 å® å®„ å°’ å°» å±´ å±³ 帄 庀 庂 忉 戉 æ‰ æ°• æ°¶ 汃 ++ æ°¿ æ°» 犮 犰 玊 禸 è‚Š 阞 伎 优 伬 仵 ä¼” ä»± ä¼€ ä»· ++ 伈 ä¼ ä¼‚ ä¼… ä¼¢ 伓 伄 ä»´ ä¼’ 冱 刓 刉 åˆ åŠ¦ 匢 匟 ++ å 厊 å‡ å›¡ 囟 圮 圪 圴 夼 妀 奼 妅 奻 奾 奷 奿 ++ å­– å°• å°¥ å±¼ 屺 å±» å±¾ å·Ÿ å¹µ 庄 异 弚 å½´ å¿• å¿” å¿ ++ 扜 扞 扤 扡 扦 扢 扙 扠 扚 扥 æ—¯ æ—® 朾 朹 朸 朻 ++ 机 朿 朼 朳 æ°˜ 汆 æ±’ 汜 æ± æ±Š æ±” 汋 汌 ç± ç‰ž 犴 ++ 犵 玎 甪 癿 穵 网 艸 艼 芀 艽 艿 è™ è¥¾ é‚™ é‚— 邘 ++ é‚› é‚” 阢 阤 阠 阣 ä½– ä¼» ä½¢ 佉 体 佤 ä¼¾ 佧 ä½’ 佟 ++ ä½ ä½˜ ä¼­ ä¼³ 伿 佡 å† å†¹ 刜 刞 刡 劭 劮 匉 å£ å² ++ 厎 åŽ å° å· åª å‘” å‘… å™ åœ å¥ å˜ å½ å‘ å‘ å¨ å¤ ++ 呇 å›® 囧 囥 å å… åŒ å‰ å‹ å’ å¤† 奀 妦 妘 妠 妗 ++ 妎 妢 å¦ å¦ å¦§ 妡 宎 å®’ å°¨ å°ª å² å² å²ˆ 岋 岉 å²’ ++ 岊 岆 岓 岕 å·  帊 帎 庋 庉 庌 庈 åº å¼… å¼ å½¸ 彶 ++ å¿’ å¿‘ å¿ å¿­ 忨 å¿® 忳 å¿¡ 忤 å¿£ 忺 忯 å¿· å¿» 怀 å¿´ ++ 戺 抃 抌 抎 æŠ æŠ” 抇 扱 扻 扺 扰 æŠ æŠˆ 扷 扽 扲 ++ 扴 æ”· æ—° æ—´ æ—³ æ—² æ—µ æ… æ‡ æ™ æ• æŒ æˆ æ æ æš ++ æ‹ æ¯ æ°™ æ°š 汸 汧 汫 沄 沋 æ² æ±± 汯 汩 沚 æ±­ 沇 ++ 沕 沜 汦 æ±³ æ±¥ æ±» 沎 ç´ çº ç‰£ 犿 犽 狃 狆 ç‹ çŠº ++ ç‹… 玕 玗 玓 玔 玒 町 甹 ç–” ç–• çš ç¤½ 耴 è‚• è‚™ è‚ ++ è‚’ è‚œ èŠ èŠ èŠ… 芎 芑 芓 芊 芃 芄 豸 迉 辿 é‚Ÿ é‚¡ ++ é‚¥ é‚ž 邧 é‚  阰 阨 阯 阭 丳 侘 ä½¼ ä¾… ä½½ ä¾€ 侇 佶 ++ ä½´ 侉 侄 ä½· 佌 ä¾— 佪 侚 ä½¹ ä¾ ä½¸ ä¾ ä¾œ ä¾” 侞 ä¾’ ++ 侂 侕 佫 ä½® 冞 冼 冾 刵 刲 刳 剆 刱 劼 匊 匋 匼 ++ 厒 厔 å’‡ å‘¿ å’ å’‘ å’‚ å’ˆ å‘« 呺 呾 å‘¥ 呬 å‘´ 呦 å’ ++ 呯 å‘¡ å‘  å’˜ å‘£ 呧 呤 å›· 囹 å¯ å² å­ å« å± å° å¶ ++ 垀 åµ å» å³ å´ å¢ å¨ å½ å¤Œ 奅 妵 妺 å§ å§Ž 妲 姌 ++ å§ å¦¶ 妼 姃 姖 妱 妽 姀 姈 妴 姇 å­¢ å­¥ 宓 宕 屄 ++ 屇 å²® 岤 å²  å²µ 岯 岨 岬 岟 å²£ å²­ å²¢ 岪 岧 å² å²¥ ++ 岶 å²° 岦 帗 帔 帙 弨 å¼¢ å¼£ 弤 å½” 徂 å½¾ å½½ å¿ž å¿¥ ++ 怭 怦 怙 怲 怋 怴 怊 怗 怳 怚 怞 怬 怢 æ€ æ€ æ€® ++ 怓 怑 怌 怉 怜 戔 戽 抭 抴 æ‹‘ 抾 抪 抶 æ‹Š 抮 抳 ++ 抯 抻 抩 抰 抸 攽 æ–¨ æ–» 昉 æ—¼ 昄 昒 昈 æ—» 昃 昋 ++ æ˜ æ˜… æ—½ 昑 æ˜ æ›¶ 朊 æž… æ¬ æžŽ æž’ æ¶ æ» æž˜ 枆 æž„ ++ æ´ æž æžŒ æº æžŸ æž‘ æž™ 枃 æ½ æž æ¸ æ¹ æž” 欥 殀 æ­¾ ++ 毞 æ° æ²“ 泬 泫 æ³® æ³™ 沶 æ³” æ²­ 泧 æ²· æ³ æ³‚ 沺 泃 ++ 泆 æ³­ æ³² æ³’ æ³ æ²´ 沊 æ² æ²€ 泞 æ³€ æ´° æ³ æ³‡ æ²° æ³¹ ++ æ³ æ³© 泑 ç‚” 炘 ç‚… ç‚“ 炆 ç‚„ ç‚‘ ç‚– ç‚‚ ç‚š 炃 牪 ç‹– ++ ç‹‹ 狘 狉 ç‹œ ç‹’ ç‹” ç‹š ç‹Œ ç‹‘ 玤 玡 玭 玦 玢 玠 玬 ++ çŽ ç“ ç“¨ 甿 ç•€ 甾 ç–Œ ç–˜ 皯 盳 ç›± ç›° 盵 矸 矼 矹 ++ 矻 矺 矷 祂 礿 秅 穸 ç©» ç«» ç±µ ç³½ 耵 è‚ è‚® è‚£ 肸 ++ 肵 è‚­ 舠 芠 è‹€ 芫 芚 芘 芛 芵 芧 芮 芼 芞 芺 芴 ++ 芨 芡 芩 è‹‚ 芤 苃 芶 芢 è™° 虯 è™­ è™® è±– è¿’ è¿‹ è¿“ ++ è¿ è¿– è¿• è¿— 邲 é‚´ 邯 邳 é‚° 阹 阽 阼 阺 陃 ä¿ ä¿… ++ ä¿“ ä¾² 俉 ä¿‹ ä¿ ä¿” ä¿œ ä¿™ ä¾» ä¾³ ä¿› 俇 ä¿– 侺 ä¿€ ä¾¹ ++ 俬 剄 剉 å‹€ å‹‚ 匽 å¼ åŽ— 厖 厙 厘 å’º å’¡ å’­ å’¥ å“ ++ 哃 èŒ å’· å’® å“– å’¶ å“… 哆 å’  å‘° å’¼ å’¢ å’¾ 呲 å“ž å’° ++ åžµ åžž 垟 垤 垌 åž— åž åž› åž” 垘 åž åž™ 垥 åžš åž• 壴 ++ å¤ å¥“ 姡 姞 姮 娀 姱 å§ å§º 姽 姼 姶 姤 姲 姷 姛 ++ 姩 姳 姵 姠 姾 姴 姭 宨 屌 å³ å³˜ 峌 å³— 峋 å³› 峞 ++ 峚 峉 峇 峊 å³– 峓 å³” å³ å³ˆ 峆 峎 峟 峸 å·¹ 帡 帢 ++ 帣 帠 帤 庰 庤 庢 庛 庣 庥 弇 å¼® å½– 徆 怷 怹 æ” ++ æ² æž æ… æ“ æ‡ æ‰ æ› æŒ æ€ æ‚ æŸ æ€¤ æ„ æ˜ æ¦ æ® ++ 扂 扃 æ‹ æŒ æŒ‹ 拵 挎 挃 æ‹« 拹 æŒ æŒŒ 拸 拶 挀 挓 ++ 挔 拺 挕 æ‹» æ‹° æ• æ•ƒ æ–ª æ–¿ 昶 昡 昲 昵 昜 昦 昢 ++ 昳 昫 昺 æ˜ æ˜´ 昹 昮 æœ æœ æŸ æŸ² 柈 枺 柜 æž» 柸 ++ 柘 柀 æž· 柅 柫 柤 柟 æžµ æŸ æž³ 柷 柶 柮 柣 柂 æž¹ ++ 柎 柧 柰 æž² 柼 柆 柭 柌 æž® 柦 柛 柺 柉 柊 柃 柪 ++ 柋 欨 殂 殄 殶 毖 毘 毠 æ°  æ°¡ æ´¨ æ´´ æ´­ æ´Ÿ æ´¼ æ´¿ ++ æ´’ æ´Š 泚 æ´³ æ´„ æ´™ æ´º æ´š æ´‘ æ´€ æ´ æµ‚ æ´ æ´˜ æ´· æ´ƒ ++ æ´ æµ€ æ´‡ æ´  æ´¬ æ´ˆ æ´¢ æ´‰ æ´ ç‚· ç‚Ÿ 炾 炱 ç‚° ç‚¡ ç‚´ ++ 炵 ç‚© ç‰ ç‰‰ 牊 牬 牰 牳 牮 ç‹Š 狤 狨 ç‹« ç‹Ÿ 狪 狦 ++ ç‹£ 玅 çŒ ç‚ çˆ ç… çŽ¹ 玶 玵 玴 ç« çŽ¿ ç‡ çŽ¾ çƒ ç† ++ 玸 ç‹ ç“¬ ç“® ç”® 畇 畈 ç–§ ç–ª 癹 盄 眈 眃 眄 眅 眊 ++ ç›· ç›» 盺 矧 矨 ç † ç ‘ ç ’ ç … ç  ç  ç Ž ç ‰ ç ƒ ç “ 祊 ++ 祌 祋 祅 祄 秕 ç§ ç§ ç§– 秎 窀 穾 ç«‘ 笀 ç¬ ç±º 籸 ++ ç±¹ 籿 ç²€ ç² ç´ƒ ç´ˆ ç´ ç½˜ 羑 ç¾ ç¾¾ 耇 耎 è€ è€” 耷 ++ 胘 胇 胠 胑 胈 胂 èƒ èƒ… 胣 胙 胜 胊 胕 胉 èƒ èƒ— ++ 胦 èƒ è‡¿ 舡 芔 è‹™ 苾 苹 茇 苨 茀 è‹• 茺 è‹« è‹– è‹´ ++ 苬 è‹¡ 苲 苵 茌 è‹» 苶 è‹° 苪 苤 è‹  苺 苳 è‹­ è™· è™´ ++ 虼 虳 è¡ è¡Ž 衧 衪 è¡© 觓 訄 訇 èµ² è¿£ è¿¡ è¿® è¿  郱 ++ 邽 é‚¿ 郕 郅 邾 郇 郋 郈 釔 釓 é™” é™ é™‘ 陓 陊 陎 ++ 倞 倅 倇 倓 倢 倰 倛 俵 ä¿´ 倳 倷 倬 俶 ä¿· 倗 倜 ++ 倠 倧 倵 倯 倱 倎 å…š 冔 冓 凊 凄 凅 凈 凎 剡 剚 ++ 剒 剞 剟 剕 剢 å‹ åŒŽ 厞 唦 å“¢ å”— å”’ 哧 哳 哤 唚 ++ å“¿ 唄 唈 å“« 唑 å”… 哱 唊 å“» å“· 哸 å“  唎 唃 唋 åœ ++ 圂 埌 å ² 埕 埒 垺 埆 åž½ åž¼ 垸 垶 åž¿ 埇 åŸ åž¹ åŸ ++ 夎 奊 娙 娖 娭 娮 娕 å¨ å¨— 娊 娞 娳 å­¬ 宧 å®­ 宬 ++ å°ƒ å±– å±” 峬 峿 å³® å³± å³· å´€ å³¹ 帩 帨 庨 庮 庪 庬 ++ å¼³ å¼° 彧 æ æš æ§ æ æ‚¢ 悈 æ‚€ æ‚’ æ‚ æ‚ æ‚ƒ æ‚• æ‚› ++ æ‚— 悇 æ‚œ æ‚Ž 戙 扆 拲 æŒ æ– æŒ¬ æ„ æ… æŒ¶ æƒ æ¤ æŒ¹ ++ æ‹ æŠ æŒ¼ 挩 æ 挴 æ˜ æ” æ™ æŒ­ æ‡ æŒ³ æš æ‘ æŒ¸ æ— ++ æ€ æˆ æ•Š 敆 æ—† æ—ƒ æ—„ æ—‚ 晊 晟 晇 晑 朒 朓 æ Ÿ æ š ++ 桉 æ ² æ ³ æ » æ¡‹ æ¡ æ – æ ± æ œ æ µ æ « æ ­ æ ¯ æ¡Ž æ¡„ æ ´ ++ æ  æ ’ æ ” æ ¦ æ ¨ æ ® æ¡ æ º æ ¥ æ   欬 欯 欭 欱 欴 æ­­ ++ è‚‚ 殈 毦 毤 毨 毣 毢 毧 æ°¥ 浺 æµ£ 浤 浶 æ´ æµ¡ 涒 ++ 浘 æµ¢ æµ­ 浯 涑 æ¶ æ·¯ 浿 涆 浞 浧 æµ  涗 æµ° æµ¼ 浟 ++ 涂 涘 æ´¯ 浨 涋 æµ¾ 涀 涄 æ´– 涃 æµ» æµ½ æµµ æ¶ çƒœ 烓 ++ 烑 çƒ çƒ‹ ç¼¹ 烢 烗 烒 烞 烠 烔 çƒ çƒ… 烆 烇 烚 烎 ++ 烡 牂 牸 牷 牶 猀 狺 ç‹´ 狾 狶 狳 ç‹» çŒ ç“ ç™ ç¥ ++ ç– çŽ¼ ç§ ç£ ç© çœ ç’ ç› ç” ç çš ç— ç˜ ç¨ ç“ž ç“Ÿ ++ ç“´ 瓵 甡 ç•› ç•Ÿ ç–° ç— ç–» ç—„ ç—€ ç–¿ ç–¶ ç–º 皊 盉 çœ ++ 眛 çœ çœ“ 眒 眣 眑 眕 眙 眚 眢 眧 ç £ ç ¬ ç ¢ ç µ ç ¯ ++ ç ¨ ç ® ç « ç ¡ ç © ç ³ ç ª ç ± 祔 祛 ç¥ ç¥œ 祓 祒 祑 秫 ++ 秬 秠 秮 秭 秪 秜 秞 ç§ çª† 窉 窅 窋 窌 窊 窇 竘 ++ ç¬ ç¬„ 笓 笅 ç¬ ç¬ˆ 笊 笎 笉 笒 粄 粑 粊 粌 粈 ç² ++ ç²… ç´ž ç´ ç´‘ ç´Ž ç´˜ ç´– ç´“ ç´Ÿ ç´’ ç´ ç´Œ 罜 罡 罞 ç½  ++ ç½ ç½› ç¾– ç¾’ 翃 ç¿‚ ç¿€ 耖 耾 耹 胺 胲 胹 胵 è„ èƒ» ++ è„€ èˆ èˆ¯ 舥 茳 茭 è„ èŒ™ è‘ èŒ¥ è– èŒ¿ è 茦 茜 茢 ++ è‚ èŽ èŒ› 茪 茈 茼 è 茖 茤 茠 茷 茯 茩 è‡ è… èŒ ++ è“ èŒž 茬 è‹ èŒ§ èˆ è™“ è™’ 蚢 蚨 èš– èš èš‘ èšž 蚇 èš— ++ 蚆 èš‹ èšš èš… 蚥 èš™ èš¡ 蚧 èš• 蚘 蚎 èš èš èš” 衃 è¡„ ++ è¡­ 衵 衶 衲 袀 衱 è¡¿ 衯 袃 衾 è¡´ 衼 訒 豇 è±— è±» ++ 貤 è²£ 赶 赸 趵 趷 趶 軑 軓 迾 迵 适 è¿¿ è¿» 逄 迼 ++ 迶 郖 郠 郙 郚 郣 郟 郥 郘 郛 郗 郜 郤 é… é…Ž é… ++ 釕 釢 釚 陜 陟 éš¼ 飣 é«Ÿ 鬯 乿 å° åª å¡ åž å  å“ ++ å‹ å å² åˆ å å å› åŠ å¢ å€• å… åŸ å© å« å£ å¤ ++ å† å€ å® å³ å— å‘ å‡ å‰« 剭 剬 剮 å‹– å‹“ 匭 厜 啵 ++ 啶 唼 å• å• å”´ 唪 å•‘ å•¢ 唶 唵 å”° å•’ å•… 唌 唲 å•¥ ++ å•Ž 唹 啈 å”­ å”» å•€ å•‹ 圊 圇 埻 å ” 埢 埶 埜 埴 å € ++ 埭 埽 å ˆ 埸 å ‹ 埳 åŸ å ‡ 埮 埣 埲 埥 埬 埡 å Ž 埼 ++ å  åŸ§ å  å Œ 埱 埩 埰 å  å „ 奜 å©  婘 å©• 婧 å©ž 娸 ++ 娵 å©­ å© å©Ÿ å©¥ 婬 å©“ 婤 å©— 婃 å© å©’ å©„ å©› 婈 媎 ++ 娾 å© å¨¹ å©Œ å©° å©© 婇 å©‘ å©– å©‚ å©œ å­² å­® å¯ å¯€ å±™ ++ å´ž å´‹ å´ å´š å´  å´Œ å´¨ å´ å´¦ å´¥ å´ å´° å´’ å´£ å´Ÿ å´® ++ 帾 帴 庱 庴 庹 庲 庳 弶 弸 å¾› å¾– 徟 æ‚Š æ‚ æ‚† 悾 ++ æ‚° 悺 惓 惔 æƒ æƒ¤ 惙 æƒ æƒˆ 悱 惛 æ‚· 惊 æ‚¿ 惃 æƒ ++ 惀 挲 æ¥ æŽŠ 掂 æ½ æŽ½ 掞 掭 æŽ æŽ— 掫 掎 æ¯ æŽ‡ æŽ ++ æ® æŽ¯ æµ æŽœ æ­ æŽ® æ¼ æŽ¤ 挻 掟 æ¸ æŽ… æŽ æŽ‘ æŽ æ° ++ æ•“ æ— æ™¥ 晡 æ™› æ™™ 晜 晢 朘 桹 梇 æ¢ æ¢œ æ¡­ æ¡® 梮 ++ 梫 楖 桯 梣 梬 梩 桵 æ¡´ 梲 æ¢ æ¡· 梒 桼 æ¡« 桲 梪 ++ 梀 桱 桾 梛 梖 梋 梠 梉 梤 桸 æ¡» 梑 梌 梊 桽 欶 ++ 欳 欷 欸 殑 æ® æ® æ®Ž 殌 æ°ª æ·€ 涫 涴 涳 æ¹´ 涬 æ·© ++ æ·¢ 涷 æ·¶ æ·” 渀 æ·ˆ æ·  æ·Ÿ æ·– 涾 æ·¥ æ·œ æ· æ·› æ·´ æ·Š ++ 涽 æ·­ æ·° 涺 æ·• æ·‚ æ· æ·‰ æ· æ·² æ·“ æ·½ æ·— æ· æ·£ 涻 ++ 烺 ç„ çƒ· ç„— 烴 ç„Œ 烰 ç„„ 烳 ç„ çƒ¼ 烿 焆 ç„“ ç„€ 烸 ++ 烶 ç„‹ ç„‚ ç„Ž 牾 牻 牼 牿 çŒ çŒ— 猇 猑 猘 猊 猈 ç‹¿ ++ çŒ çŒž 玈 ç¶ ç¸ çµ ç„ ç ç½ ç‡ ç€ çº ç¼ ç¿ çŒ ç‹ ++ ç´ çˆ ç•¤ ç•£ ç—Ž ç—’ ç— ç—‹ ç—Œ ç—‘ ç— çš çš‰ 盓 眹 眯 ++ 眭 眱 眲 眴 眳 眽 眥 眻 眵 硈 ç¡’ 硉 ç¡ ç¡Š ç¡Œ ç ¦ ++ ç¡… ç¡ ç¥¤ 祧 祩 祪 祣 祫 祡 离 秺 秸 秶 秷 çª çª” ++ çª ç¬µ ç­‡ 笴 笥 笰 笢 笤 笳 笘 笪 ç¬ ç¬± 笫 笭 笯 ++ 笲 笸 笚 笣 ç²” 粘 ç²– ç²£ ç´µ ç´½ ç´¸ ç´¶ ç´º çµ… ç´¬ ç´© ++ çµ çµ‡ ç´¾ ç´¿ 絊 ç´» ç´¨ ç½£ 羕 羜 ç¾ ç¾› ç¿Š ç¿‹ ç¿ ç¿ ++ ç¿‘ 翇 ç¿ ç¿‰ 耟 耞 耛 è‡ èƒ èˆ è„˜ è„¥ è„™ è„› è„­ è„Ÿ ++ 脬 è„ž è„¡ è„• 脧 è„ è„¢ 舑 舸 舳 舺 舴 舲 艴 èŽ èŽ£ ++ 莨 èŽ èº è³ èŽ¤ è´ èŽ èŽ èŽ• 莙 èµ èŽ” 莩 è½ èŽƒ 莌 ++ èŽ èŽ› 莪 莋 è¾ èŽ¥ 莯 莈 莗 莰 è¿ èŽ¦ 莇 莮 è¶ èŽš ++ è™™ è™– èš¿ èš· 蛂 è› è›… 蚺 èš° 蛈 èš¹ èš³ 蚸 蛌 èš´ èš» ++ èš¼ 蛃 èš½ èš¾ è¡’ 袉 袕 袨 袢 袪 袚 袑 袡 袟 袘 袧 ++ 袙 袛 袗 袤 袬 袌 袓 袎 覂 觖 觙 觕 訰 訧 訬 訞 ++ è°¹ è°» 豜 è± è±½ è²¥ èµ½ èµ» èµ¹ 趼 è·‚ 趹 趿 è· è»˜ 軞 ++ è» è»œ è»— è»  軡 逤 逋 逑 逜 逌 逡 郯 郪 郰 郴 郲 ++ 郳 郔 郫 郬 郩 é…– é…˜ é…š é…“ é…• 釬 釴 釱 釳 釸 釤 ++ 釹 釪 釫 釷 釨 釮 镺 é–† é–ˆ 陼 é™­ 陫 é™± 陯 éš¿ éª ++ é „ 飥 馗 å‚› å‚• å‚” å‚ž å‚‹ å‚£ 傃 å‚Œ å‚Ž å‚ å¨ å‚œ å‚’ ++ å‚‚ 傇 å…Ÿ 凔 匒 匑 厤 厧 å–‘ å–¨ å–¥ å–­ å•· å™… å–¢ å–“ ++ å–ˆ å– å–µ å– å–£ å–’ å–¤ 啽 å–Œ å–¦ å•¿ å–• å–¡ å–Ž 圌 å © ++ å · å ™ å ž å § å £ å ¨ 埵 塈 å ¥ å œ å › å ³ å ¿ å ¶ å ® å ¹ ++ å ¸ å ­ å ¬ å » 奡 媯 媔 媟 婺 媢 媞 婸 媦 婼 媥 媬 ++ 媕 媮 娷 媄 媊 媗 媃 媋 媩 å©» 婽 媌 媜 åª åª“ åª ++ 寪 å¯ å¯‹ 寔 寑 寊 寎 å°Œ å°° å´· 嵃 嵫 åµ åµ‹ å´¿ å´µ ++ 嵑 嵎 嵕 å´³ å´º åµ’ å´½ å´± åµ™ 嵂 å´¹ 嵉 å´¸ å´¼ å´² å´¶ ++ åµ€ åµ… 幄 å¹ å½˜ 徦 å¾¥ 徫 惉 悹 惌 惢 惎 惄 æ„” 惲 ++ æ„Š æ„– æ„… 惵 æ„“ 惸 惼 惾 æƒ æ„ƒ 愘 æ„ æ„ æƒ¿ æ„„ æ„‹ ++ 扊 掔 掱 掰 æŽ æ¥ æ¨ æ¯ æƒ æ’ æ³ æŠ æ  æ¶ æ• æ² ++ æµ æ‘¡ æŸ æŽ¾ æ æœ æ„ æ˜ æ“ æ‚ æ‡ æŒ æ‹ æˆ æ° æ— ++ æ™ æ”² 敧 敪 敤 æ•œ 敨 æ•¥ æ–Œ æ– æ–ž æ–® æ— æ—’ 晼 晬 ++ æ™» 暀 æ™± 晹 晪 晲 æœ æ¤Œ 棓 椄 棜 椪 棬 棪 棱 æ¤ ++ 棖 棷 棫 棤 棶 椓 æ¤ æ£³ 棡 椇 棌 椈 楰 梴 椑 棯 ++ 棆 椔 棸 æ£ æ£½ 棼 棨 椋 椊 椗 棎 棈 æ£ æ£ž 棦 棴 ++ 棑 椆 棔 棩 椕 椥 棇 欹 欻 欿 欼 æ®” æ®— æ®™ 殕 殽 ++ 毰 毲 毳 æ°° æ·¼ 湆 湇 渟 湉 溈 渼 渽 æ¹… æ¹¢ 渫 渿 ++ æ¹ æ¹ æ¹³ 渜 渳 湋 æ¹€ 湑 渻 渃 渮 湞 湨 湜 湡 渱 ++ 渨 æ¹  æ¹± 湫 渹 渢 渰 湓 æ¹¥ 渧 湸 湤 æ¹· 湕 æ¹¹ æ¹’ ++ 湦 渵 渶 湚 ç„  ç„ž 焯 烻 ç„® 焱 ç„£ ç„¥ ç„¢ 焲 ç„Ÿ 焨 ++ 焺 ç„› 牋 牚 犈 犉 犆 犅 犋 猒 猋 猰 猢 猱 猳 猧 ++ 猲 猭 猦 猣 猵 猌 ç® ç¬ ç° ç« ç– çš ç¡ ç­ ç± ç¤ ++ ç£ ç ç© ç  ç² ç“» 甯 畯 畬 ç—§ ç—š ç—¡ ç—¦ ç— ç—Ÿ ç—¤ ++ ç—— çš• çš’ 盚 ç† ç‡ ç„ ç ç… çŠ çŽ ç‹ çŒ çŸž 矬 ç¡  ++ 硤 ç¡¥ ç¡œ ç¡­ 硱 硪 ç¡® ç¡° ç¡© 硨 ç¡ž ç¡¢ 祴 祳 祲 祰 ++ 稂 稊 稃 稌 稄 窙 竦 竤 ç­Š 笻 ç­„ ç­ˆ ç­Œ ç­Ž ç­€ ç­˜ ++ ç­… ç²¢ 粞 粨 粡 絘 絯 çµ£ 絓 çµ– 絧 絪 çµ çµ­ 絜 絫 ++ çµ’ çµ” 絩 絑 絟 絎 ç¼¾ 缿 ç½¥ 罦 ç¾¢ ç¾  羡 ç¿— è‘ è ++ è 胾 胔 è…ƒ è…Š è…’ è… è…‡ 脽 è… è„º 臦 臮 臷 臸 臹 ++ 舄 舼 舽 舿 艵 茻 è è¹ è£ è€ è¨ è’ è§ è¤ è¼ è¶ ++ è è† èˆ è« è£ èŽ¿ è è è¥ è˜ è¿ è¡ è‹ èŽ è– èµ ++ è‰ è‰ è èž è‘ è† è‚ è³ è• èº è‡ è‘ èª è“ èƒ è¬ ++ è® è„ è» è— è¢ è› è› è¾ è›˜ 蛢 蛦 蛓 蛣 蛚 蛪 è› ++ 蛫 蛜 蛬 蛩 è›— 蛨 蛑 衈 è¡– è¡• 袺 裗 袹 袸 裀 袾 ++ 袶 袼 袷 袽 袲 è¤ è£‰ 覕 覘 覗 è§ è§š 觛 è©Ž è© è¨¹ ++ è©™ è©€ è©— 詘 è©„ è©… è©’ 詈 è©‘ è©Š è©Œ è© è±Ÿ è² è²€ 貺 ++ è²¾ è²° è²¹ è²µ 趄 趀 趉 è·˜ è·“ è· è·‡ è·– è·œ è· è·• è·™ ++ è·ˆ è·— è·… 軯 è»· 軺 軹 軦 è»® 軥 軵 軧 軨 軶 軫 è»± ++ 軬 è»´ 軩 逭 逴 逯 鄆 鄬 é„„ 郿 郼 鄈 郹 郻 é„ é„€ ++ 鄇 é„… 鄃 é…¡ é…¤ é…Ÿ é…¢ é…  éˆ éˆŠ 鈥 鈃 鈚 鈦 éˆ éˆŒ ++ 鈀 鈒 釿 釽 鈆 鈄 鈧 鈂 鈜 鈤 鈙 鈗 鈅 鈖 é•» é– ++ é–Œ é– éš‡ 陾 隈 隉 隃 隀 雂 雈 雃 é›± é›° é¬ é° é® ++ é ‡ 颩 飫 鳦 黹 亃 亄 亶 傽 å‚¿ 僆 å‚® 僄 僊 å‚´ 僈 ++ 僂 å‚° åƒ å‚º 傱 僋 僉 傶 傸 凗 剺 剸 剻 剼 å—ƒ å—› ++ å—Œ å— å—‹ å—Š å— å—€ å—” å—„ å—© å–¿ å—’ å– å— å—• å—¢ å—– ++ å—ˆ å—² å— å—™ å—‚ 圔 å¡“ 塨 塤 å¡ å¡ å¡‰ 塯 å¡• å¡Ž å¡ ++ å¡™ å¡¥ å¡› å ½ å¡£ 塱 壼 嫇 å«„ å«‹ 媺 媸 媱 媵 媰 媿 ++ 嫈 媻 嫆 媷 å«€ å«Š 媴 媶 å« åª¹ åª å¯– 寘 寙 å°Ÿ å°³ ++ åµ± åµ£ 嵊 åµ¥ åµ² 嵬 嵞 嵨 嵧 åµ¢ å·° å¹ å¹Ž 幊 å¹ å¹‹ ++ å»… 廌 廆 廋 廇 å½€ 徯 å¾­ 惷 æ…‰ æ…Š æ„« æ…… 愶 愲 æ„® ++ æ…† 愯 æ… æ„© æ…€ 戠 é…¨ 戣 戥 戤 æ… æ± æ« æ æ’ æ‰ ++ æ  æ¤ æ³ æ‘ƒ æŸ æ• æ˜ æ¹ æ· æ¢ æ£ æŒ æ¦ æ° æ¨ æ‘ ++ æµ æ¯ æŠ æš æ‘€ æ¥ æ§ æ‹ æ§ æ› æ® æ¡ æŽ æ•¯ æ–’ æ—“ ++ 暆 暌 æš• æš æš‹ 暊 æš™ æš” 晸 朠 楦 楟 椸 楎 楢 楱 ++ 椿 楅 楪 椹 楂 楗 楙 楺 楈 楉 椵 楬 椳 椽 楥 棰 ++ 楸 椴 楩 楀 楯 楄 楶 楘 æ¥ æ¥´ 楌 椻 楋 椷 楜 æ¥ ++ 楑 椲 楒 椯 楻 椼 æ­† æ­… æ­ƒ æ­‚ æ­ˆ æ­ æ®› ï¨ æ¯» 毼 ++ 毹 毷 毸 溛 æ»– 滈 æº æ»€ 溟 溓 溔 溠 溱 溹 滆 æ»’ ++ 溽 æ» æºž 滉 溷 溰 æ» æº¦ æ» æº² 溾 滃 滜 滘 溙 溒 ++ 溎 æº æº¤ 溡 溿 溳 æ» æ»Š 溗 溮 溣 ç…‡ ç…” ç…’ ç…£ ç…  ++ ç… ç… ç…¢ ç…² ç…¸ ç…ª ç…¡ ç…‚ ç…˜ ç…ƒ ç…‹ ç…° ç…Ÿ ç… ç…“ ç…„ ++ ç… ç…š ç‰ çŠ çŠŒ 犑 çŠ çŠŽ 猼 ç‚ çŒ» 猺 ç€ çŠ ç‰ ç‘„ ++ ç‘Š ç‘‹ ç‘’ ç‘‘ ç‘— ç‘€ ç‘ ç‘ ç‘Ž ç‘‚ 瑆 ç‘ ç‘” ç“¡ ç“¿ 瓾 ++ 瓽 ç” ç•¹ ç•· 榃 ç—¯ ç˜ ç˜ƒ ç—· ç—¾ ç—¼ ç—¹ ç—¸ ç˜ ç—» ç—¶ ++ ç—­ ç—µ ç—½ çš™ çšµ ç› ç• çŸ ç  ç’ ç– çš ç© ç§ ç” ç™ ++ ç­ çŸ  碇 碚 碔 ç¢ ç¢„ 碕 碅 碆 碡 碃 硹 碙 碀 碖 ++ ç¡» 祼 禂 祽 祹 稑 稘 稙 稒 稗 稕 稢 稓 稛 ç¨ çª£ ++ 窢 窞 ç«« ç­¦ ç­¤ ç­­ ç­´ ç­© ç­² ç­¥ ç­³ ç­± ç­° ç­¡ ç­¸ ç­¶ ++ ç­£ ç²² ç²´ 粯 綈 綆 綀 ç¶ çµ¿ 綅 絺 綎 çµ» 綃 çµ¼ 綌 ++ 綔 綄 çµ½ 綒 ç½­ 罫 罧 罨 罬 羦 ç¾¥ 羧 ç¿› ç¿œ 耡 è…¤ ++ è…  è…· è…œ è…© è…› è…¢ è…² 朡 è…ž è…¶ è…§ è…¯ è…„ è…¡ èˆ è‰‰ ++ 艄 艀 艂 艅 蓱 è¿ è‘– 葶 葹 è’ è’ è‘¥ è‘‘ è‘€ è’† 葧 ++ è° è‘ è‘½ è‘š è‘™ è‘´ 葳 è‘ è”‡ è‘ž è· èº è´ è‘º 葃 葸 ++ è² è‘… è© è™ è‘‹ è¯ è‘‚ è­ è‘Ÿ è‘° è¹ è‘Ž è‘Œ è‘’ 葯 è“… ++ è’Ž è» è‘‡ è¶ è³ è‘¨ 葾 è‘„ è« è‘  è‘” è‘® è‘ èœ‹ 蜄 è›· ++ 蜌 蛺 è›– 蛵 è 蛸 蜎 蜉 èœ è›¶ èœ èœ… 裖 裋 è£ è£Ž ++ 裞 裛 裚 裌 è£ è¦… 覛 觟 觥 觤 觡 觠 觢 觜 触 詶 ++ 誆 è©¿ è©¡ 訿 è©· 誂 誄 詵 誃 èª è©´ 詺 è°¼ 豋 豊 è±¥ ++ 豤 豦 貆 貄 è²… 賌 赨 赩 趑 趌 趎 è¶ è¶ è¶“ 趔 è¶ ++ 趒 è·° è·  è·¬ è·± è·® è· è·© è·£ è·¢ è·§ è·² è·« è·´ 輆 軿 ++ è¼ è¼€ è¼… 輇 輈 輂 輋 é’ é€¿ é„ é‰ é€½ é„ é„ é„ é„‘ ++ é„– é„” é„‹ é„Ž é…® é…¯ 鉈 鉒 鈰 鈺 鉦 鈳 鉥 鉞 銃 鈮 ++ 鉊 鉆 鉭 鉬 é‰ é‰  鉧 鉯 鈶 鉡 鉰 鈱 鉔 鉣 é‰ é‰² ++ 鉎 鉓 鉌 鉖 鈲 é–Ÿ é–œ é–ž é–› éš’ éš“ éš‘ éš— 雎 雺 雽 ++ 雸 雵 é³ é· é¸ é² é  é  é Ž 颬 飶 飹 馯 馲 馰 馵 ++ 骭 骫 é­› 鳪 é³­ 鳧 麀 黽 僦 僔 僗 僨 僳 僛 僪 åƒ ++ 僤 僓 僬 僰 僯 僣 僠 凘 劀 åŠ å‹© å‹« 匰 厬 嘧 嘕 ++ 嘌 嘒 å—¼ å˜ å˜œ å˜ å˜“ 嘂 å—º å˜ å˜„ å—¿ å—¹ 墉 塼 å¢ ++ 墘 墆 å¢ å¡¿ å¡´ 墋 塺 墇 墑 墎 塶 墂 墈 å¡» 墔 å¢ ++ 壾 奫 å«œ å«® å«¥ å«• 嫪 å«š å«­ å«« 嫳 å«¢ å«  å«› 嫬 å«ž ++ å« å«™ 嫨 å«Ÿ å­· 寠 寣 å±£ 嶂 嶀 åµ½ 嶆 嵺 å¶ åµ· 嶊 ++ 嶉 嶈 åµ¾ åµ¼ å¶ åµ¹ 嵿 幘 å¹™ 幓 廘 廑 å»— 廎 廜 廕 ++ å»™ å»’ å»” 彄 彃 彯 徶 愬 愨 æ… æ…ž æ…± æ…³ æ…’ æ…“ æ…² ++ æ…¬ 憀 æ…´ æ…” æ…º æ…› æ…¥ æ„» æ…ª æ…¡ æ…– 戩 戧 戫 æ« æ‘ ++ æ‘› æ‘ æ‘´ 摶 摲 摳 摽 摵 摦 æ’¦ æ‘Ž æ’‚ æ‘ž æ‘œ æ‘‹ æ‘“ ++ æ‘  æ‘ æ‘¿ æ¿ æ‘¬ æ‘« æ‘™ æ‘¥ æ‘· 敳 æ–  æš¡ æš  暟 朅 朄 ++ 朢 榱 榶 槉 榠 槎 榖 榰 榬 榼 榑 榙 榎 榧 æ¦ æ¦© ++ 榾 榯 榿 槄 榽 榤 槔 榹 槊 榚 æ§ æ¦³ 榓 榪 榡 榞 ++ 槙 榗 æ¦ æ§‚ 榵 榥 槆 æ­Š æ­ æ­‹ 殞 殟 æ®  毃 毄 毾 ++ 滎 滵 æ»± 漃 æ¼¥ 滸 æ¼· æ»» æ¼® 漉 潎 æ¼™ 漚 漧 漘 æ¼» ++ æ¼’ æ»­ 漊 漶 æ½³ 滹 æ»® æ¼­ æ½€ æ¼° æ¼¼ æ¼µ 滫 漇 漎 潃 ++ æ¼… 滽 滶 æ¼¹ 漜 滼 漺 漟 æ¼ æ¼ž 漈 漡 熇 ç† ç†‰ 熀 ++ 熅 熂 ç† ç…» 熆 ç† ç†— 牄 牓 犗 犕 犓 çƒ ç ç‘ çŒ ++ ç‘¢ 瑳 瑱 瑵 瑲 瑧 ç‘® 甀 甂 甃 畽 ç– ç˜– 瘈 瘌 瘕 ++ 瘑 瘊 瘔 皸 çž ç¼ çž… çž‚ ç® çž€ ç¯ ç¾ çžƒ 碲 碪 碴 ++ 碭 碨 硾 碫 碞 碥 碠 碬 碢 碤 禘 禊 禋 禖 禕 禔 ++ 禓 禗 禈 禒 ç¦ ç¨« ç©Š 稰 稯 稨 稦 窨 窫 窬 ç«® 箈 ++ 箜 箊 箑 ç® ç®– ç® ç®Œ ç®› 箎 ç®… 箘 劄 ç®™ 箤 箂 ç²» ++ 粿 ç²¼ 粺 綧 綷 ç·‚ 綣 綪 ç· ç·€ ç·… ç¶ ç·Ž ç·„ ç·† ç·‹ ++ ç·Œ 綯 綹 綖 綼 綟 綦 綮 綩 綡 ç·‰ ç½³ ç¿¢ ç¿£ ç¿¥ ç¿ž ++ 耤 è èœ è†‰ 膆 膃 膇 è† è†Œ 膋 舕 è’— è’¤ è’¡ è’Ÿ è’º ++ è“Ž è“‚ è’¬ è’® è’« è’¹ è’´ è“ è“ è’ª è’š è’± è“ è’ è’§ è’» ++ è’¢ è’” 蓇 è“Œ è’› è’© è’¯ è’¨ è“– è’˜ è’¶ è“ è’  è“— è“” è“’ ++ è“› è’° è’‘ 虡 蜳 蜣 蜨 è« è€ èœ® 蜞 蜡 蜙 蜛 èƒ èœ¬ ++ è 蜾 è† èœ  蜲 蜪 蜭 蜼 蜒 蜺 蜱 蜵 è‚ èœ¦ 蜧 蜸 ++ 蜤 蜚 蜰 蜑 裷 裧 裱 裲 裺 裾 裮 裼 裶 裻 裰 裬 ++ 裫 è¦ è¦¡ 覟 覞 觩 觫 觨 誫 誙 誋 誒 èª èª– è°½ 豨 ++ 豩 賕 è³ è³— 趖 踉 踂 è·¿ è¸ è·½ 踊 踃 踇 踆 踅 è·¾ ++ 踀 踄 è¼ è¼‘ 輎 è¼ é„£ é„œ é„  é„¢ é„Ÿ é„ é„š 鄤 é„¡ é„› ++ é…º é…² é…¹ é…³ 銥 銤 鉶 銛 鉺 銠 銔 銪 éŠ éŠ¦ 銚 銫 ++ 鉹 銗 鉿 銣 é‹® 銎 銂 銕 銢 鉽 銈 銡 銊 銆 銌 銙 ++ 銧 鉾 銇 銩 éŠ éŠ‹ 鈭 éšž éš¡ 雿 é˜ é½ éº é¾ éžƒ 鞀 ++ éž‚ é» éž„ éž é¿ éŸŽ éŸ é – 颭 颮 餂 餀 餇 é¦ é¦œ 駃 ++ 馹 馻 馺 駂 馽 駇 骱 é«£ 髧 鬾 鬿 é­  é­¡ é­Ÿ é³± é³² ++ é³µ 麧 僿 儃 å„° 僸 儆 儇 僶 僾 å„‹ å„Œ 僽 å„Š 劋 劌 ++ 勱 勯 噈 噂 噌 嘵 å™ å™Š 噉 噆 噘 噚 噀 嘳 嘽 嘬 ++ 嘾 嘸 嘪 嘺 圚 墫 å¢ å¢± 墠 墣 墯 墬 墥 墡 壿 å«¿ ++ å«´ 嫽 å«· 嫶 嬃 嫸 嬂 嫹 å¬ å¬‡ 嬅 å¬ å±§ 嶙 嶗 嶟 ++ 嶒 嶢 嶓 嶕 嶠 嶜 嶡 嶚 嶞 幩 å¹ å¹  幜 ç·³ å»› 廞 ++ 廡 彉 å¾² 憋 憃 æ…¹ 憱 憰 憢 憉 憛 憓 憯 憭 憟 憒 ++ 憪 憡 æ† æ…¦ 憳 戭 æ‘® æ‘° æ’– æ’  æ’… æ’— æ’œ æ’ æ’‹ æ’Š ++ æ’Œ æ’£ æ’Ÿ 摨 æ’± æ’˜ 敶 敺 敹 æ•» æ–² æ–³ æšµ æš° æš© æš² ++ æš· 暪 暯 樀 樆 樗 槥 槸 樕 槱 槤 樠 槿 槬 槢 樛 ++ æ¨ æ§¾ 樧 槲 槮 樔 槷 槧 æ©€ 樈 槦 槻 æ¨ æ§¼ 槫 樉 ++ 樄 樘 樥 æ¨ æ§¶ 樦 樇 槴 樖 æ­‘ 殥 殣 殢 殦 æ° æ°€ ++ 毿 æ°‚ æ½ æ¼¦ æ½¾ 澇 濆 æ¾’ æ¾ æ¾‰ 澌 æ½¢ æ½ æ¾… 潚 æ¾– ++ 潶 潬 澂 潕 æ½² æ½’ æ½ æ½— æ¾” 澓 æ½ æ¼€ 潡 潫 æ½½ 潧 ++ æ¾ æ½“ 澋 潩 潿 澕 æ½£ æ½· 潪 æ½» 熲 熯 熛 熰 熠 熚 ++ 熩 熵 ç† ç†¥ 熞 熤 熡 熪 熜 熧 熳 犘 犚 ç˜ ç’ çž ++ çŸ ç  ç ç› ç¡ çš ç™ ç¢ ç’‡ ç’‰ ç’Š ç’† ç’ ç‘½ ç’… ç’ˆ ++ 瑼 瑹 甈 甇 畾 瘥 瘞 瘙 ç˜ ç˜œ 瘣 瘚 瘨 瘛 çšœ çš ++ çšž çš› çž çž çž‰ 瞈 ç£ ç¢» ç£ ç£Œ 磑 磎 磔 磈 磃 磄 ++ 磉 禚 禡 禠 禜 禢 禛 æ­¶ 稹 窲 窴 窳 ç®· 篋 箾 箬 ++ 篎 箯 箹 篊 箵 ç³… 糈 糌 糋 ç·· ç·› ç·ª ç·§ ç·— ç·¡ 縃 ++ ç·º ç·¦ ç·¶ ç·± ç·° ç·® ç·Ÿ 罶 羬 ç¾° ç¾­ ç¿­ ç¿« 翪 翬 翦 ++ 翨 è¤ è§ è†£ 膟 膞 膕 膢 膙 膗 舖 è‰ è‰“ 艒 è‰ è‰Ž ++ 艑 蔤 è”» è” è”€ 蔩 蔎 蔉 è” è”Ÿ 蔊 蔧 蔜 è“» 蔫 蓺 ++ 蔈 蔌 è“´ 蔪 蓲 蔕 è“· è“« 蓳 蓼 è”’ 蓪 è“© è”– 蓾 蔨 ++ è” è”® 蔂 蓽 蔞 蓶 è”± 蔦 蓧 蓨 è“° 蓯 蓹 蔘 è”  è”° ++ 蔋 è”™ 蔯 虢 è– è£ è¤ è· èŸ¡ è³ è˜ è” è› è’ è¡ èš ++ è‘ èž è­ èª è èŽ èŸ è è¯ è¬ èº è® èœ è¥ è è» ++ èµ è¢ è§ è© è¡š 褅 褌 褔 褋 褗 褘 褙 褆 褖 褑 褎 ++ 褉 覢 覤 覣 觭 觰 觬 è« è«† 誸 è«“ è«‘ è«” è«• 誻 è«— ++ 誾 è«€ è«… 諘 諃 誺 誽 è«™ è°¾ è± è² è³¥ 賟 è³™ 賨 賚 ++ è³ è³§ 趠 趜 趡 趛 踠 踣 踥 踤 踮 踕 踛 踖 踑 踙 ++ 踦 踧 踔 踒 踘 踓 踜 踗 踚 輬 輤 輘 輚 è¼  è¼£ è¼– ++ è¼— é³ é° é¯ é§ é« é„¯ é„« é„© 鄪 鄲 鄦 é„® 醅 醆 醊 ++ é† é†‚ 醄 醀 é‹ é‹ƒ é‹„ é‹€ é‹™ 銶 é‹ é‹± é‹Ÿ 鋘 é‹© é‹— ++ é‹ é‹Œ 鋯 é‹‚ 鋨 é‹Š 鋈 é‹Ž 鋦 é‹ é‹• 鋉 é‹  é‹ž 鋧 é‹‘ ++ é‹“ 銵 é‹¡ 鋆 銴 镼 é–¬ é–« é–® é–° 隤 隢 雓 霅 霈 霂 ++ éš éžŠ 鞎 鞈 éŸ éŸ é ž é  é ¦ é © é ¨ é   é › é § 颲 餈 ++ 飺 餑 餔 餖 餗 餕 駜 é§ é§ é§“ 駔 駎 駉 駖 駘 駋 ++ 駗 駌 骳 髬 é«« 髳 髲 髱 é­† é­ƒ é­§ é­´ é­± é­¦ é­¶ é­µ ++ é­° é­¨ é­¤ é­¬ é³¼ 鳺 é³½ 鳿 é³· é´‡ é´€ é³¹ é³» é´ˆ é´… é´„ ++ 麃 黓 é¼ é¼ å„œ å„“ å„— å„š å„‘ 凞 匴 å¡ å™° å™  å™® 噳 ++ 噦 噣 å™­ 噲 噞 å™· 圜 圛 壈 墽 壉 墿 墺 壂 墼 壆 ++ 嬗 嬙 嬛 嬡 嬔 嬓 å¬ å¬– 嬨 嬚 嬠 嬞 寯 嶬 嶱 嶩 ++ 嶧 嶵 嶰 嶮 嶪 嶨 嶲 嶭 嶯 嶴 幧 幨 幦 幯 廩 廧 ++ 廦 廨 廥 彋 å¾¼ æ† æ†¨ 憖 懅 憴 懆 æ‡ æ‡Œ 憺 憿 憸 ++ 憌 æ“— æ“– æ“ æ“ æ“‰ æ’½ æ’‰ 擃 æ“› 擳 æ“™ 攳 æ•¿ 敼 æ–¢ ++ 曈 æš¾ 曀 曊 曋 æ› æš½ æš» 暺 曌 朣 樴 橦 橉 橧 樲 ++ 橨 樾 æ© æ©­ 橶 æ©› æ©‘ 樨 æ©š 樻 樿 æ© æ©ª 橤 æ© æ© ++ æ©” 橯 æ©© æ©  樼 æ©ž æ©– æ©• æ© æ©Ž 橆 æ­• æ­” æ­– 殧 殪 ++ 殫 毈 毇 æ°„ æ°ƒ æ°† æ¾­ æ¿‹ æ¾£ 濇 æ¾¼ æ¿Ž 濈 潞 æ¿„ æ¾½ ++ 澞 æ¿Š 澨 瀄 æ¾¥ æ¾® 澺 澬 澪 æ¿ æ¾¿ 澸 æ¾¢ 濉 澫 æ¿ ++ 澯 æ¾² æ¾° 燅 燂 熿 熸 燖 燀 ç‡ ç‡‹ 燔 燊 燇 ç‡ ç†½ ++ 燘 熼 燆 燚 燛 çŠ çŠž ç© ç¦ ç§ ç¬ ç¥ ç« çª ç‘¿ ç’š ++ ç’  ç’” ç’’ ç’• ç’¡ 甋 ç–€ 瘯 瘭 瘱 瘽 瘳 瘼 瘵 瘲 瘰 ++ çš» 盦 çžš çž çž¡ çžœ çž› 瞢 瞣 çž• çž™ çž— ç£ ç£© 磥 磪 ++ 磞 磣 磛 磡 磢 磭 磟 磠 禤 ç©„ 穈 穇 窶 窸 窵 窱 ++ 窷 篞 篣 篧 ç¯ ç¯• 篥 篚 篨 篹 篔 篪 篢 篜 篫 篘 ++ 篟 ç³’ ç³” ç³— ç³ ç³‘ 縒 縡 縗 縌 縟 縠 縓 縎 縜 縕 ++ 縚 縢 縋 ç¸ ç¸– ç¸ ç¸” 縥 縤 罃 ç½» ç½¼ 罺 ç¾± 翯 耪 ++ 耩 è¬ è†± 膦 膮 膹 膵 膫 膰 膬 膴 膲 膷 膧 臲 艕 ++ 艖 艗 è•– è•… è•« è• è•“ è•¡ 蕘 è•€ 蕆 蕤 è• è•¢ è•„ è•‘ ++ 蕇 è•£ 蔾 è•› 蕱 è•Ž è•® 蕵 è•• 蕧 è•  è–Œ 蕦 è• è•” è•¥ ++ 蕬 虣 虥 虤 èž› èž èž— èž“ èž’ 螈 èž èž– 螘 è¹ èž‡ 螣 ++ èž… èž èž‘ èž èž„ èž” èžœ èžš 螉 褞 褦 褰 褭 褮 褧 褱 ++ 褢 褩 褣 褯 褬 褟 觱 è«  è«¢ 諲 è«´ 諵 è« è¬” 諤 è«Ÿ ++ è«° 諈 è«ž è«¡ 諨 è«¿ 諯 è«» 貑 è²’ è² è³µ è³® è³± è³° è³³ ++ 赬 èµ® 趥 趧 踳 踾 踸 è¹€ è¹… 踶 踼 踽 è¹ è¸° 踿 躽 ++ 輶 è¼® è¼µ è¼² è¼¹ è¼· è¼´ é¶ é¹ é» é‚† 郺 鄳 鄵 鄶 醓 ++ é† é†‘ é† é† éŒ§ 錞 錈 錟 錆 éŒ éº éŒ¸ 錼 錛 錣 錒 ++ éŒ é† éŒ­ 錎 éŒ é‹‹ éŒ é‹º 錥 錓 鋹 é‹· 錴 錂 錤 é‹¿ ++ 錩 錹 錵 錪 錔 錌 錋 鋾 錉 錀 é‹» 錖 é–¼ é— é–¾ é–¹ ++ é–º é–¶ é–¿ é–µ é–½ éš© é›” 霋 霒 éœ éž™ éž— éž” 韰 韸 é µ ++ é ¯ é ² 餤 餟 餧 餩 馞 駮 駬 駥 駤 駰 駣 駪 駩 駧 ++ 骹 骿 骴 骻 髶 髺 髹 é«· 鬳 鮀 é®… 鮇 é­¼ é­¾ é­» 鮂 ++ 鮓 é®’ é® é­º 鮕 é­½ 鮈 é´¥ é´— é´  é´ž é´” é´© é´ é´˜ é´¢ ++ é´ é´™ é´Ÿ 麈 麆 麇 麮 麭 黕 é»– 黺 é¼’ é¼½ 儦 å„¥ å„¢ ++ 儤 å„  å„© å‹´ åš“ 嚌 åš åš† åš„ 嚃 噾 åš‚ 噿 åš å£– 壔 ++ å£ å£’ 嬭 嬥 嬲 嬣 嬬 嬧 嬦 嬯 嬮 å­» 寱 寲 嶷 幬 ++ 幪 å¾¾ å¾» 懃 憵 憼 懧 懠 懥 懤 懨 懞 擯 æ“© æ“£ æ“« ++ 擤 擨 æ– æ–€ æ–¶ æ—š æ›’ æª æª– æª æª¥ 檉 檟 檛 檡 檞 ++ 檇 檓 檎 檕 檃 檨 檤 檑 æ©¿ 檦 檚 檅 檌 檒 æ­› æ®­ ++ æ°‰ æ¿Œ 澩 æ¿´ æ¿” æ¿£ æ¿œ æ¿­ 濧 濦 æ¿ž 濲 æ¿ æ¿¢ 濨 燡 ++ 燱 燨 燲 燤 燰 燢 ç³ ç® ç¯ ç’— ç’² ç’« ç’ ç’ª ç’­ ç’± ++ ç’¥ ç’¯ ç” ç”‘ ç”’ ç” ç–„ 癃 癈 癉 癇 皤 盩 çžµ çž« çž² ++ çž· 瞶 çž´ çž± 瞨 矰 磳 磽 礂 磻 磼 磲 礅 磹 磾 礄 ++ 禫 禨 ç©œ ç©› ç©– 穘 ç©” ç©š 窾 ç«€ ç« ç°… ç° ç¯² ç°€ 篿 ++ 篻 ç°Ž 篴 ç°‹ 篳 ç°‚ ç°‰ ç°ƒ ç° ç¯¸ 篽 ç°† 篰 篱 ç° ç°Š ++ 糨 縭 縼 繂 縳 顈 縸 縪 繉 ç¹€ 繇 縩 繌 縰 縻 縶 ++ 繄 縺 ç½… 罿 ç½¾ ç½½ ç¿´ 翲 耬 膻 臄 臌 臊 臅 臇 膼 ++ 臩 艛 艚 艜 è–ƒ è–€ è– è–§ è–• è–  è–‹ è–£ è•» è–¤ è–š è–ž ++ è•· 蕼 è–‰ è–¡ 蕺 蕸 è•— è–Ž è–– è–† è– è–™ è– è– è–¢ è–‚ ++ è–ˆ è–… 蕹 蕶 è–˜ è– è–Ÿ 虨 èž¾ 螪 èž­ 蟅 èž° 螬 èž¹ èžµ ++ èž¼ èž® 蟉 蟃 蟂 蟌 èž· 螯 蟄 蟊 èž´ 螶 èž¿ 螸 èž½ 蟞 ++ èž² 褵 褳 褼 褾 è¥ è¥’ 褷 襂 覭 覯 覮 觲 觳 謞 謘 ++ 謖 謑 謅 謋 謢 è¬ è¬’ 謕 謇 è¬ è¬ˆ 謆 謜 謓 謚 è± ++ è±° è±² è±± 豯 貕 è²” è³¹ 赯 蹎 è¹ è¹“ è¹ è¹Œ 蹇 轃 è½€ ++ é‚… é¾ é„¸ 醚 醢 醛 醙 醟 醡 é† é†  鎡 鎃 鎯 é¤ é– ++ é‡ é¼ é˜ éœ é¶ é‰ é é‘ é  é­ éŽ éŒ éª é¹ é— é• ++ é’ é é± é· é» é¡ éž é£ é§ éŽ€ éŽ é™ é—‡ é—€ é—‰ é—ƒ ++ é—… é–· éš® éš° 隬 霠 霟 霘 éœ éœ™ éžš éž¡ éžœ éžž éž éŸ• ++ 韔 韱 é¡ é¡„ é¡Š 顉 é¡… 顃 餥 餫 餬 餪 餳 餲 餯 餭 ++ 餱 餰 馘 馣 馡 騂 駺 駴 駷 駹 駸 駶 駻 駽 駾 駼 ++ 騃 骾 髾 髽 é¬ é«¼ é­ˆ 鮚 鮨 鮞 é®› 鮦 鮡 鮥 鮤 鮆 ++ 鮢 é®  鮯 é´³ éµ éµ§ é´¶ é´® é´¯ é´± é´¸ é´° éµ… 鵂 鵃 é´¾ ++ é´· éµ€ é´½ 翵 é´­ 麊 麉 éº éº° 黈 黚 é»» 黿 鼤 é¼£ é¼¢ ++ é½” é¾  儱 å„­ å„® 嚘 åšœ åš— åšš åš åš™ 奰 嬼 屩 屪 å·€ ++ å¹­ å¹® 懘 懟 懭 懮 懱 懪 懰 懫 懖 懩 æ“¿ 攄 擽 擸 ++ æ” æ”ƒ 擼 æ–” æ—› 曚 æ›› 曘 æ«… 檹 檽 æ«¡ 櫆 檺 檶 檷 ++ 櫇 檴 檭 æ­ž 毉 æ°‹ 瀇 瀌 ç€ ç€ ç€… 瀔 瀎 æ¿¿ 瀀 æ¿» ++ 瀦 濼 æ¿· 瀊 çˆ ç‡¿ 燹 爃 燽 ç¶ ç’¸ ç“€ ç’µ ç“ ç’¾ ç’¶ ++ ç’» ç“‚ ç”” 甓 癜 癤 ç™™ ç™ ç™“ ç™— 癚 皦 çš½ 盬 矂 瞺 ++ 磿 礌 礓 礔 礉 ç¤ ç¤’ 礑 禭 禬 ç©Ÿ ç°œ ç°© ç°™ ç°  ç°Ÿ ++ ç°­ ç° ç°¦ ç°¨ ç°¢ ç°¥ ç°° 繜 ç¹ ç¹– ç¹£ 繘 ç¹¢ 繟 繑 ç¹  ++ ç¹— 繓 ç¾µ ç¾³ ç¿· 翸 èµ è‡‘ 臒 è‡ è‰Ÿ 艞 è–´ è—† è—€ è—ƒ ++ è—‚ è–³ è–µ è–½ è—‡ è—„ è–¿ è—‹ è—Ž è—ˆ è—… è–± è–¶ è—’ 蘤 è–¸ ++ è–· è–¾ 虩 蟧 蟦 蟢 蟛 蟫 蟪 蟥 蟟 蟳 蟤 蟔 蟜 蟓 ++ 蟭 蟘 蟣 螤 蟗 蟙 è  èŸ´ 蟨 èŸ è¥“ 襋 è¥ è¥Œ 襆 è¥ ++ 襑 襉 謪 謧 謣 謳 謰 謵 è­‡ 謯 謼 謾 謱 謥 謷 謦 ++ 謶 謮 謤 謻 謽 謺 豂 è±µ è²™ 貘 è²— è³¾ è´„ è´‚ è´€ 蹜 ++ è¹¢ è¹  è¹— è¹– 蹞 è¹¥ 蹧 è¹› 蹚 蹡 è¹ è¹© è¹” 轆 轇 轈 ++ 轋 鄨 鄺 é„» 鄾 醨 醥 醧 醯 醪 鎵 鎌 鎒 鎷 鎛 éŽ ++ 鎉 鎧 鎎 鎪 鎞 鎦 鎕 鎈 鎙 鎟 éŽ éŽ± 鎑 鎲 鎤 鎨 ++ 鎴 鎣 鎥 é—’ é—“ é—‘ éš³ é›— 雚 å·‚ 雟 雘 é› éœ£ 霢 霥 ++ 鞬 éž® 鞨 éž« 鞤 鞪 鞢 鞥 韗 韙 韖 韘 韺 é¡ é¡‘ é¡’ ++ 颸 é¥ é¤¼ 餺 é¨ é¨‹ 騉 é¨ é¨„ 騑 騊 騅 騇 騆 é«€ é«œ ++ 鬈 鬄 鬅 鬩 鬵 é­Š é­Œ é­‹ 鯇 鯆 鯃 鮿 é¯ é®µ 鮸 鯓 ++ 鮶 鯄 鮹 鮽 鵜 鵓 éµ éµŠ éµ› 鵋 éµ™ éµ– 鵌 éµ— éµ’ éµ” ++ 鵟 鵘 鵚 麎 麌 黟 é¼ é¼€ é¼– é¼¥ 鼫 鼪 鼩 鼨 齌 齕 ++ å„´ 儵 劖 å‹· 厴 åš« åš­ 嚦 嚧 嚪 嚬 壚 å£ å£› 夒 嬽 ++ 嬾 嬿 å·ƒ å¹° 徿 懻 攇 æ” æ” æ”‰ 攌 攎 æ–„ æ—ž æ— æ›ž ++ 櫧 æ«  æ«Œ æ«‘ æ«™ æ«‹ æ«Ÿ æ«œ æ« æ«« æ« æ« æ«ž æ­  æ®° æ°Œ ++ 瀙 瀧 瀠 瀖 瀫 瀡 瀢 瀣 瀩 瀗 瀤 瀜 瀪 爌 爊 爇 ++ 爂 爅 犥 犦 犤 犣 犡 ç“‹ ç“… ç’· 瓃 ç”– ç™  矉 矊 矄 ++ 矱 ç¤ ç¤› 礡 礜 礗 礞 禰 穧 穨 ç°³ ç°¼ ç°¹ ç°¬ ç°» 糬 ++ 糪 繶 ç¹µ 繸 ç¹° ç¹· 繯 繺 ç¹² ç¹´ 繨 罋 罊 羃 羆 ç¾· ++ 翽 翾 è¸ è‡— 臕 艤 艡 艣 è—« è—± è—­ è—™ è—¡ è—¨ è—š è—— ++ è—¬ è—² è—¸ è—˜ è—Ÿ è—£ è—œ è—‘ è—° è—¦ è—¯ è—ž è—¢ è € 蟺 è ƒ ++ 蟶 蟷 è ‰ è Œ è ‹ è † 蟼 è ˆ 蟿 è Š è ‚ 襢 襚 襛 襗 襡 ++ 襜 襘 è¥ è¥™ 覈 覷 覶 觶 è­ è­ˆ è­Š è­€ è­“ è­– è­” è­‹ ++ è­• è­‘ è­‚ è­’ è­— 豃 è±· 豶 貚 è´† è´‡ è´‰ 趬 趪 趭 趫 ++ è¹­ 蹸 è¹³ 蹪 蹯 è¹» 軂 è½’ 轑 è½ è½ è½“ è¾´ é…€ é„¿ 醰 ++ 醭 éž é‡ é é‚ éš é é¹ é¬ éŒ é™ éŽ© é¦ éŠ é” é® ++ é£ é• é„ éŽ é€ é’ é§ é•½ é—š é—› 雡 霩 霫 霬 霨 霦 ++ éž³ éž· 鞶 éŸ éŸž 韟 é¡œ é¡™ é¡ é¡— 颿 颽 颻 颾 饈 饇 ++ 饃 馦 馧 騚 騕 騥 é¨ é¨¤ 騛 騢 騠 騧 騣 騞 騜 騔 ++ é«‚ 鬋 鬊 鬎 鬌 鬷 鯪 鯫 鯠 鯞 鯤 鯦 鯢 鯰 鯔 鯗 ++ 鯬 鯜 鯙 鯥 鯕 鯡 鯚 éµ· é¶ é¶Š 鶄 鶈 éµ± 鶀 鵸 鶆 ++ 鶋 鶌 éµ½ 鵫 éµ´ éµµ éµ° 鵩 鶅 éµ³ éµ» 鶂 鵯 éµ¹ 鵿 鶇 ++ 鵨 麔 麑 黀 黼 é¼­ é½€ é½ é½ é½– é½— 齘 匷 åš² åšµ åš³ ++ 壣 å­… å·† å·‡ å»® 廯 å¿€ å¿ æ‡¹ æ”— æ”– 攕 攓 æ—Ÿ 曨 曣 ++ 曤 櫳 æ«° 櫪 櫨 櫹 櫱 æ«® 櫯 瀼 瀵 瀯 瀷 瀴 瀱 ç‚ ++ 瀸 瀿 瀺 瀹 ç€ ç€» 瀳 ç 爓 爔 犨 ç½ ç¼ ç’º çš« 皪 ++ çš¾ ç›­ 矌 矎 çŸ çŸ çŸ² 礥 礣 礧 礨 礤 礩 禲 ç©® 穬 ++ ç©­ ç«· 籉 籈 籊 籇 ç±… ç³® ç¹» ç¹¾ çº çº€ 羺 ç¿¿ è¹ è‡› ++ 臙 舋 艨 艩 蘢 è—¿ è˜ è—¾ 蘛 蘀 è—¶ 蘄 蘉 蘅 蘌 è—½ ++ è ™ è  è ‘ è — è “ è – 襣 襦 覹 觷 è­  è­ª è­ è­¨ è­£ è­¥ ++ è­§ è­­ 趮 躆 躈 躄 è½™ è½– è½— 轕 轘 轚 é‚ é…ƒ é… é†· ++ 醵 醲 醳 é‹ é“ é» é  é é” é¾ é• é é¨ é™ é éµ ++ é€ é· é‡ éŽ é– é’ éº é‰ é¸ éŠ é¿ é¼ éŒ é¶ é‘ é† ++ é—ž é—  é—Ÿ 霮 霯 éž¹ éž» 韽 韾 é¡  é¡¢ é¡£ é¡Ÿ é£ é£‚ é¥ ++ 饎 饙 饌 饋 饓 騲 騴 騱 騬 騪 騶 騩 騮 騸 騭 髇 ++ é«Š 髆 é¬ é¬’ 鬑 é°‹ é°ˆ 鯷 é°… é°’ 鯸 é±€ é°‡ é°Ž é°† é°— ++ é°” é°‰ 鶟 鶙 鶤 é¶ é¶’ 鶘 é¶ é¶› 鶠 鶔 鶜 鶪 鶗 鶡 ++ 鶚 鶢 鶨 鶞 鶣 鶿 鶩 鶖 鶦 鶧 麙 麛 麚 黥 黤 黧 ++ 黦 é¼° é¼® é½› é½  齞 é½ é½™ 龑 儺 儹 劘 劗 囃 åš½ åš¾ ++ å­ˆ å­‡ å·‹ å· å»± 懽 æ”› 欂 櫼 欃 櫸 欀 çƒ ç„ çŠ çˆ ++ ç‰ ç… ç† çˆ çˆš 爙 ç¾ ç”— 癪 çŸ ç¤­ 礱 礯 ç±” 籓 ç³² ++ 纊 纇 纈 纋 纆 çº ç½ ç¾» 耰 è‡ è˜˜ 蘪 蘦 蘟 蘣 蘜 ++ 蘙 蘧 蘮 蘡 蘠 蘩 蘞 蘥 è © è  è › è   è ¤ è œ è « è¡Š ++ 襭 襩 襮 襫 觺 è­¹ è­¸ è­… è­º è­» è´ è´” 趯 躎 躌 轞 ++ è½› è½ é…† é…„ é…… 醹 é¿ é» é¶ é© é½ é¼ é° é¹ éª é· ++ é¬ é‘€ é± é—¥ é—¤ é—£ 霵 霺 éž¿ 韡 顤 飉 飆 飀 饘 饖 ++ 騹 騽 驆 é©„ é©‚ é© é¨º 騿 é« é¬• 鬗 鬘 鬖 鬺 é­’ é°« ++ é° é°œ é°¬ é°£ é°¨ é°© é°¤ é°¡ 鶷 鶶 鶼 é· é·‡ é·Š é· é¶¾ ++ é·… é·ƒ 鶻 鶵 é·Ž 鶹 鶺 鶬 é·ˆ 鶱 鶭 é·Œ 鶳 é· é¶² 鹺 ++ 麜 黫 é»® é»­ é¼› 鼘 鼚 é¼± 齎 é½¥ 齤 é¾’ 亹 囆 å›… 囋 ++ 奱 å­‹ å­Œ å·• å·‘ 廲 攡 æ”  攦 攢 欋 欈 欉 æ° ç• ç– ++ ç— ç’ çˆž 爟 犩 ç¿ ç“˜ ç“• ç“™ ç“— ç™­ çš­ 礵 禴 ç©° 穱 ++ ç±— 籜 ç±™ ç±› 籚 ç³´ ç³± 纑 ç½ ç¾‡ 臞 艫 蘴 蘵 蘳 蘬 ++ 蘲 蘶 è ¬ è ¨ è ¦ è ª è ¥ 襱 覿 覾 觻 è­¾ 讄 讂 讆 è®… ++ è­¿ è´• 躕 躔 躚 躒 èº èº– 躗 è½  è½¢ é…‡ é‘Œ é‘ é‘Š é‘‹ ++ é‘ é‘‡ é‘… 鑈 鑉 鑆 霿 韣 顪 é¡© 飋 饔 饛 é©Ž é©“ é©” ++ é©Œ é© é©ˆ é©Š 驉 é©’ é© é« é¬™ 鬫 鬻 é­– é­• 鱆 鱈 é°¿ ++ 鱄 é°¹ é°³ é± é°¼ é°· é°´ é°² é°½ é°¶ é·› é·’ é·ž é·š é·‹ é· ++ é·œ é·‘ é·Ÿ é·© é·™ é·˜ é·– é·µ é·• é· éº¶ é»° é¼µ é¼³ é¼² 齂 ++ 齫 龕 é¾¢ 儽 劙 壨 壧 奲 å­ å·˜ è ¯ å½ æˆ æˆƒ 戄 攩 ++ 攥 æ–– 曫 欑 欒 æ¬ æ¯Š ç› çš çˆ¢ 玂 çŽ çŽƒ ç™° 矔 籧 ++ 籦 纕 艬 蘺 虀 蘹 蘼 蘱 蘻 蘾 è ° è ² è ® è ³ 襶 襴 ++ 襳 觾 讌 讎 讋 讈 è±… è´™ 躘 轤 è½£ 醼 é‘¢ é‘• é‘ é‘— ++ é‘ž 韄 韅 é € é©– é©™ 鬞 鬟 鬠 é±’ 鱘 é± é±Š é± é±‹ 鱕 ++ é±™ 鱌 鱎 é·» é·· é·¯ é·£ é·« é·¸ é·¤ é·¶ é·¡ é·® é·¦ é·² é·° ++ é·¢ é·¬ é·´ é·³ é·¨ é·­ 黂 é» é»² 黳 鼆 鼜 鼸 é¼· 鼶 齃 ++ é½ é½± é½° é½® 齯 囓 å› å­Ž å±­ æ”­ æ›­ æ›® 欓 çŸ ç¡ ç ++ ç  çˆ£ ç“› ç“¥ 矕 礸 禷 禶 籪 纗 羉 艭 虃 è ¸ è · è µ ++ è¡‹ è®” 讕 躞 躟 躠 èº é†¾ 醽 釂 é‘« 鑨 é‘© 雥 é† éƒ ++ é‡ éŸ‡ 韥 é©ž é«• é­™ é±£ 鱧 鱦 é±¢ 鱞 é±  鸂 é·¾ 鸇 鸃 ++ 鸆 鸅 鸀 é¸ é¸‰ é·¿ é·½ 鸄 麠 鼞 齆 é½´ é½µ 齶 å›” æ”® ++ æ–¸ 欘 欙 欗 欚 ç¢ çˆ¦ 犪 矘 矙 礹 籩 籫 糶 纚 纘 ++ 纛 纙 臠 臡 虆 虇 虈 襹 襺 襼 襻 觿 讘 è®™ 躥 躤 ++ 躣 é‘® é‘­ 鑯 鑱 鑳 é‰ é¡² 饟 鱨 é±® é±­ 鸋 é¸ é¸ é¸ ++ 鸒 鸑 麡 黵 鼉 齇 齸 é½» 齺 é½¹ 圞 ç¦ ç±¯ è ¼ 趲 躦 ++ 釃 é‘´ 鑸 鑶 鑵 é©  é±´ é±³ é±± é±µ 鸔 鸓 黶 鼊 龤 ç¨ ++ ç¥ ç³· 虪 è ¾ è ½ è ¿ 讞 貜 躩 軉 é‹ é¡³ é¡´ 飌 饡 馫 ++ 驤 驦 驧 鬤 鸕 鸗 齈 戇 欞 爧 虌 躨 é’‚ é’€ é’ é©© ++ 驨 鬮 鸙 爩 虋 讟 é’ƒ é±¹ 麷 癵 é©« 鱺 é¸ ç© çª éº¤ ++ é½¾ 齉 龘 ç¢ éŠ¹ è£ å¢» æ’ ç²§ 嫺 â•” ╦ â•— â•  ╬ â•£ ++ â•š â•© â• â•’ ╤ â•• â•ž ╪ â•¡ ╘ ╧ â•› â•“ â•¥ â•– â•Ÿ ++ â•« â•¢ â•™ ╨ â•œ â•‘ â• â•­ â•® â•° ╯ ï¿­ 𠕇 é‹› ð —Ÿ 𣿅 ++ è•Œ 䊵 ç¯ å†µ 㙉 𤥂 𨧤 é„ ð¡§› è‹® 𣳈 ç ¼ æ„ æ‹Ÿ 𤤳 𨦪 ++ ð Š  𦮳 𡌅 侫 𢓭 倈 𦴩 𧪄 𣘀 𤪱 𢔓 𠾠徤 𠎀 ð ‡ æ»› ++ ð Ÿ å„ ã‘º å„Ž 顬 ãƒ è– ð¤¦¤ ð ’‡ å…  𣎴 å…ª 𠯿 𢃼 ð ‹¥ 𢔰 ++ ð –Ž 𣈳 𡦃 宂 è½ ð –³ 𣲙 冲 冸 é´´ 凉 å‡ å‡‘ 㳜 凓 𤪦 ++ 决 凢 å‚ å‡­ è 椾 𣜭 å½» 刋 刦 刼 劵 剗 劔 効 å‹… ++ ç°• è•‚ å‹  è˜ ð¦¬“ 𨫞 啉 æ»™ 𣾀 ð ¥” 𣿬 匳 𠯢 泋 𡜦 æ › ++ ç• æŠ ãºª 㣌 𡛨 ç‡ ä’¢ å­ å´ ð¨š« å¾ ð¡–– 𡘓 矦 厓 𨪛 ++ 厠 厫 厮 玧 𥲠㽙 玜 å å… æ±‰ 义 埾 å™ ãª« ð ® å  ++ 𣿫 𢶣 å¶ ð ±· å“ ç¹ å”« æ™— æµ› å‘­ 𦭓 ð µ´ å• å’ å’¤ 䞦 ++ 𡜠𠻠㶴 𠵠𨦼 𢚘 啇 ä³­ å¯ ç— å–† å–© ð¡£— 𤀺 ä•’ 𤵠++ æš³ ð¡‚´ 嘷 æ› ð£ŠŠ 暤 æš­ å™ å™ ç£± å›± 鞇 å¾ åœ€ 囯 å›­ ++ 𨭦 㘣 ð¡‰ å† ð¤†¥ æ±® ç‚‹ å‚ ãš± 𦱾 埦 ð¡– å ƒ ð¡‘” 𤣠堦 ++ 𤯵 å¡œ 墪 ã•¡ 壠 壜 𡈼 壻 寿 åƒ ðª… ð¤‰¸ é“ ã–¡ 够 梦 ++ 㛃 æ¹™ 𡘾 娤 å•“ ð¡š’ è”… 姉 𠵎 𦲠𦴪 ð¡Ÿœ 姙 ð¡Ÿ» ð¡ž² 𦶦 ++ æµ± ð¡ ¨ ð¡›• 姹 𦹅 媫 å©£ 㛦 𤦩 㜈 媖 ç‘¥ å«“ 𦾡 𢕔 㶅 ++ 𡤑 㜲 𡚸 広 å‹ å­¶ æ–ˆ å­¼ 𧨎 䀄 ä¡ ð ˆ„ 寕 æ…  𡨴 𥧌 ++ ð –¥ 寳 å® ä´ å°… ð¡­„ å°“ çŽ å°” 𡲥 𦬨 屉 ä£ å²… 峩 峯 ++ 嶋 ð¡·¹ 𡸷 å´ å´˜ 嵆 𡺤 岺 å·— 苼 ã ­ 𤤠𢉠𢅳 芇 ã ¶ ++ 㯂 帮 檊 幺 𤒼 𠳓 厦 亷 厨 𡱠帉 å»´ 𨒂 廹 å»» 㢠 ++ 廼 æ ¾ é› å¼ ð ‡ ð¯¢” ã«ž 䢮 𡌺 强 𦢈 ð¢ 𢑱 å½£ éž½ 𦹮 ++ å½² é€ ð¨¨¶ 徧 嶶 㵟 𥉠𡽪 𧃸 𢙨 釖 ð Šž 𨨩 怱 æš… ð¡¡· ++ 㥣 ã·‡ 㘹 åž ð¢ž´ 祱 ã¹€ æ‚ž 悳 𤦂 𤦠𧩓 ç’¤ 僡 媠 æ…¤ ++ è¤ æ…‚ 慈 𦻒 æ† å‡´ ð ™– 憇 宪 𣾷 𢡟 懓 ð¨® ð©¥ æ‡ ã¤² ++ 𢦀 𢣠怣 æ…œ 攞 掋 𠄘 æ‹… ð¡° æ‹• ð¢¸ æ¬ ð¤§Ÿ 㨗 æ¸ æ¸ ++ ð¡ŽŽ 𡟼 澊 𢸶 é ” 𤂌 𥜠擡 æ“¥ é‘» 㩦 æº ã©— æ• æ¼– 𤨨 ++ 𤨣 æ–… æ•­ æ•Ÿ 𣾠斵 𤥀 䬷 æ—‘ 䃘 ð¡ © æ—  æ—£ å¿Ÿ 𣀠昘 ++ 𣇷 𣇸 晄 𣆤 𣆥 晋 ð ¹µ 晧 𥇦 晳 𡸽 𣈱 𨗴 𣇈 𥌓 矅 ++ 𢣷 馤 朂 𤎜 𤨡 㬫 槺 𣟂 æ§ æ¢ ð¤‡ ð©ƒ­ 柗 ä“© æ ¢ æ¹ ++ 鈼 æ  ð£¦ ð¦¶  æ¡ ð£‘¯ 槡 樋 𨫟 楳 棃 ð£— æ¤ æ¤€ ã´² 㨠++ 𣘼 㮀 枬 楡 𨩊 䋼 椶 榘 㮡 ð ‰ è£ å‚ æ§¹ 𣙙 𢄪 æ©… ++ 𣜃 æª ã¯³ æž± 櫈 𩆜 ã° æ¬ ð ¤£ 惞 欵 æ­´ 𢟠溵 𣫛 𠎵 ++ 𡥘 ã€ å¡ ð£­š 毡 𣻼 毜 æ°· 𢒋 𤣱 𦭑 汚 舦 æ±¹ 𣶼 ä“… ++ 𣶽 𤆤 𤤌 𤤀 𣳉 㛥 㳫 ð ´² 鮃 𣇹 𢒑 ç¾ æ · 𦴥 𦶡 𦷫 ++ 涖 浜 æ¹¼ 漄 𤥿 𤂅 𦹲 蔳 𦽴 凇 è® ð¨¬¡ 𣸯 ç‘“ 𣾂 秌 ++ æ¹ åª‘ 𣋠濸 ãœ æ¾ ð£¸° 滺 ð¡’— 𤀽 ä•• é° æ½„ 潜 㵎 æ½´ ++ ð©…° ã´» 澟 𤅄 æ¿“ 𤂑 𤅕 𤀹 𣿰 𣾴 𤄿 凟 𤅖 𤅗 𤅀 𦇠++ ç‹ ç¾ ç‚§ ç‚ çƒŒ 烕 烖 烟 ä„„ ã·¨ 熴 熖 𤉷 ç„« ç…… 媈 ++ ç…Š 岜 ð¤¥ ç… é¢ ð¤‹ ç„¬ 𤑚 𤨧 𤨢 熺 𨯨 炽 爎 é‘‚ 爕 ++ 夑 鑃 爤 é 𥘅 爮 牀 𤥴 梽 牕 牗 㹕 ð£„ æ  æ¼½ 犂 ++ 猫 𤠣 𨠫 䣭 𨠄 猨 献 ç 玪 ð °º 𦨮 ç‰ ç‘‰ 𤇢 𡛧 𤨤 ++ 昣 ã›… 𤦷 𤦠𤧻 ç· ç• æ¤ƒ 𤨦 ç¹ ð —ƒ ã»— 𢢭 ç‘  𨺲 瑇 ++ ç¤ ç‘¶ 莹 瑬 㜰 ç‘´ é± æ¨¬ ç’‚ 䥓 𤪌 𤅟 𤩹 𨮠孆 𨰃 ++ 𡢞 瓈 𡦈 甎 甞 𨻙 ð¡©‹ 寗 𨺬 鎅 ç• ç•Š 畧 ç•® 𤾂 㼄 ++ 𤴓 ç–Ž ç‘ ç–ž ç–´ 瘂 瘬 癑 ç™ ç™¯ 癶 ð¦µ çš è‡¯ 㟸 𦤑 ++ 𦤎 çš¡ 皥 çš· 盌 𦾟 è‘¢ 𥂠𥅽 𡸜 眞 眦 ç€ æ’¯ 𥈠 ç˜ ++ 𣊬 瞯 𨥤 𨥨 𡛠矴 𡶠𤨒 棊 碯 磇 磓 隥 礮 𥗠 磗 ++ 礴 碱 𧘌 辸 袄 𨬫 𦂃 𢘜 禆 褀 椂 禀 𥡗 ç¦ ð§¬¹ 礼 ++ 禩 渪 𧄦 㺨 秆 𩄠秔 +diff --git a/localedata/charmaps/BIG5-HKSCS b/localedata/charmaps/BIG5-HKSCS +index b6f55b4..0735efc 100644 +--- a/localedata/charmaps/BIG5-HKSCS ++++ b/localedata/charmaps/BIG5-HKSCS +@@ -7,7 +7,8 @@ + % alias BIG5HKSCS + + % +-% Generated from the big5hkscs.c iconv module. ++% Last updated from the HKSCS-2008 standard ++% http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/e_hkscs_2008.pdf + % + + CHARMAP +@@ -140,28 +141,153 @@ CHARMAP + /x7e TILDE + /x7f DELETE + /x80 PADDING CHARACTER (PAD) +- /x88/x40 +- /x88/x41 +- /x88/x42 +- /x88/x43 +- /x88/x44 +- /x88/x45 +- /x88/x46 +- /x88/x47 +- /x88/x48 +- /x88/x49 +- /x88/x4a +- /x88/x4b +- /x88/x4c +- /x88/x4d +- /x88/x4e +- /x88/x4f +- /x88/x50 +- /x88/x51 +- /x88/x52 +- /x88/x53 +- /x88/x54 +- /x88/x55 ++ /x87/x40 ++ /x87/x41 ++ /x87/x42 ++ /x87/x43 ++ /x87/x44 ++ /x87/x45 ++ /x87/x46 ++ /x87/x47 ++ /x87/x48 ++ /x87/x49 ++ /x87/x4a ++ /x87/x4b ++ /x87/x4c ++ /x87/x4d ++ /x87/x4e ++ /x87/x4f ++ /x87/x50 ++ /x87/x51 ++ /x87/x52 ++ /x87/x53 ++ /x87/x54 ++ /x87/x55 ++ /x87/x56 ++ /x87/x57 ++ /x87/x58 ++ /x87/x59 ++ /x87/x5a ++ /x87/x5b ++ /x87/x5c ++ /x87/x5d ++ /x87/x5e ++ /x87/x5f ++ /x87/x60 ++ /x87/x61 ++ /x87/x62 ++ /x87/x63 ++ /x87/x64 ++ /x87/x65 ++ /x87/x67 ++ /x87/x68 ++ /x87/x69 ++ /x87/x6a ++ /x87/x6b ++ /x87/x6c ++ /x87/x6d ++ /x87/x6e ++ /x87/x6f ++ /x87/x70 ++ /x87/x71 ++ /x87/x72 ++ /x87/x73 ++ /x87/x74 ++ /x87/x75 ++ /x87/x76 ++ /x87/x77 ++ /x87/x78 ++ /x87/x79 ++ /x87/x7a ++ /x87/x7b ++ /x87/x7c ++ /x87/x7d ++ /x87/x7e ++ /x87/xa1 ++ /x87/xa2 ++ /x87/xa3 ++ /x87/xa4 ++ /x87/xa5 ++ /x87/xa6 ++ /x87/xa7 ++ /x87/xa8 ++ /x87/xa9 ++ /x87/xaa ++ /x87/xab ++ /x87/xac ++ /x87/xad ++ /x87/xae ++ /x87/xaf ++ /x87/xb0 ++ /x87/xb1 ++ /x87/xb2 ++ /x87/xb3 ++ /x87/xb4 ++ /x87/xb5 ++ /x87/xb6 ++ /x87/xb7 ++ /x87/xb8 ++ /x87/xb9 ++ /x87/xba ++ /x87/xbb ++ /x87/xbc ++ /x87/xbd ++ /x87/xbe ++ /x87/xbf ++ /x87/xc0 ++ /x87/xc1 ++ /x87/xc2 ++ /x87/xc3 ++ /x87/xc4 ++ /x87/xc5 ++ /x87/xc6 ++ /x87/xc7 ++ /x87/xc8 ++ /x87/xc9 ++ /x87/xca ++ /x87/xcb ++ /x87/xcc ++ /x87/xcd ++ /x87/xce ++ /x87/xcf ++ /x87/xd0 ++ /x87/xd1 ++ /x87/xd2 ++ /x87/xd3 ++ /x87/xd4 ++ /x87/xd5 ++ /x87/xd6 ++ /x87/xd7 ++ /x87/xd8 ++ /x87/xd9 ++ /x87/xda ++ /x87/xdb ++ /x87/xdc ++ /x87/xdd ++ /x87/xde ++ /x87/xdf ++ /x88/x40 ++ /x88/x41 ++ /x88/x42 ++ /x88/x43 ++ /x88/x44 ++ /x88/x45 ++ /x88/x46 ++ /x88/x47 ++ /x88/x48 ++ /x88/x49 ++ /x88/x4a ++ /x88/x4b ++ /x88/x4c ++ /x88/x4d ++ /x88/x4e ++ /x88/x4f ++ /x88/x50 ++ /x88/x51 ++ /x88/x52 ++ /x88/x53 ++ /x88/x54 ++ /x88/x55 + /x88/x56 LATIN CAPITAL LETTER A WITH MACRON + /x88/x57 LATIN CAPITAL LETTER A WITH ACUTE + /x88/x58 LATIN CAPITAL LETTER A WITH CARON +@@ -174,9 +300,9 @@ CHARMAP + /x88/x5f LATIN CAPITAL LETTER O WITH ACUTE + /x88/x60 LATIN CAPITAL LETTER O WITH CARON + /x88/x61 LATIN CAPITAL LETTER O WITH GRAVE +- /x88/x62 ++% /x88/x62 + /x88/x63 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +- /x88/x64 ++% /x88/x64 + /x88/x65 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE + /x88/x66 LATIN CAPITAL LETTER E WITH CIRCUMFLEX + /x88/x67 LATIN SMALL LETTER A WITH MACRON +@@ -205,16 +331,16 @@ CHARMAP + /x88/x7e LATIN SMALL LETTER U WITH DIAERESIS AND CARON + /x88/xa1 LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE + /x88/xa2 LATIN SMALL LETTER U WITH DIAERESIS +- /x88/xa3 ++% /x88/xa3 + /x88/xa4 LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +- /x88/xa5 ++% /x88/xa5 + /x88/xa6 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE + /x88/xa7 LATIN SMALL LETTER E WITH CIRCUMFLEX + /x88/xa8 LATIN SMALL LETTER SCRIPT G +- /x88/xa9 +- /x88/xaa ++ /x88/xa9 EARTH GROUND ++ /x88/xaa FUSE + /x89/x40 +- /x89/x41 ++ /x89/x41 + /x89/x43 + /x89/x46 + /x89/x47 +@@ -283,17 +409,17 @@ CHARMAP + /x89/xae + /x89/xb0 + /x89/xb1 +- /x89/xb2 ++ /x89/xb2 + /x89/xb5 + /x89/xb6 + /x89/xb7 + /x89/xb8 + /x89/xb9 + /x89/xba +- /x89/xbb ++ /x89/xbb + /x89/xbc + /x89/xbd +- /x89/xbe ++ /x89/xbe + /x89/xbf + /x89/xc1 + /x89/xc2 +@@ -303,10 +429,10 @@ CHARMAP + /x89/xc7 + /x89/xc8 + /x89/xc9 +- /x89/xca ++ /x89/xca + /x89/xcb + /x89/xcc +- /x89/xcd ++ /x89/xcd + /x89/xce + /x89/xcf + /x89/xd0 +@@ -356,95 +482,95 @@ CHARMAP + /x89/xfc + /x89/xfd + /x89/xfe +- /x8a/x40 ++ /x8a/x40 + /x8a/x41 + /x8a/x43 +- /x8a/x44 +- /x8a/x45 ++ /x8a/x44 ++ /x8a/x45 + /x8a/x46 + /x8a/x47 + /x8a/x48 + /x8a/x49 + /x8a/x4a + /x8a/x4b +- /x8a/x4c ++ /x8a/x4c + /x8a/x4d + /x8a/x4e + /x8a/x4f +- /x8a/x50 ++ /x8a/x50 + /x8a/x51 + /x8a/x52 +- /x8a/x53 ++ /x8a/x53 + /x8a/x54 + /x8a/x55 + /x8a/x56 +- /x8a/x57 ++ /x8a/x57 + /x8a/x58 + /x8a/x59 + /x8a/x5a + /x8a/x5b + /x8a/x5c +- /x8a/x5d +- /x8a/x5e +- /x8a/x5f +- /x8a/x60 ++ /x8a/x5d ++ /x8a/x5e ++ /x8a/x5f ++ /x8a/x60 + /x8a/x61 + /x8a/x62 + /x8a/x64 +- /x8a/x65 ++ /x8a/x65 + /x8a/x66 + /x8a/x67 +- /x8a/x68 +- /x8a/x69 ++ /x8a/x68 ++ /x8a/x69 + /x8a/x6a + /x8a/x6b +- /x8a/x6c ++ /x8a/x6c + /x8a/x6d + /x8a/x6e + /x8a/x6f +- /x8a/x70 +- /x8a/x71 +- /x8a/x72 ++ /x8a/x70 ++ /x8a/x71 ++ /x8a/x72 + /x8a/x73 + /x8a/x74 + /x8a/x76 + /x8a/x77 + /x8a/x78 + /x8a/x79 +- /x8a/x7a +- /x8a/x7b ++ /x8a/x7a ++ /x8a/x7b + /x8a/x7c + /x8a/x7d + /x8a/x7e +- /x8a/xa1 +- /x8a/xa2 +- /x8a/xa3 ++ /x8a/xa1 ++ /x8a/xa2 ++ /x8a/xa3 + /x8a/xa4 +- /x8a/xa5 ++ /x8a/xa5 + /x8a/xa6 + /x8a/xa7 + /x8a/xa8 + /x8a/xa9 +- /x8a/xaa ++ /x8a/xaa + /x8a/xac +- /x8a/xad ++ /x8a/xad + /x8a/xae + /x8a/xaf +- /x8a/xb0 +- /x8a/xb2 ++ /x8a/xb0 ++ /x8a/xb2 + /x8a/xb3 +- /x8a/xb4 +- /x8a/xb5 +- /x8a/xb6 ++ /x8a/xb4 ++ /x8a/xb5 ++ /x8a/xb6 + /x8a/xb7 + /x8a/xb8 + /x8a/xb9 + /x8a/xbb +- /x8a/xbc +- /x8a/xbd ++ /x8a/xbc ++ /x8a/xbd + /x8a/xbe + /x8a/xbf +- /x8a/xc0 ++ /x8a/xc0 + /x8a/xc1 + /x8a/xc2 + /x8a/xc3 +@@ -452,49 +578,49 @@ CHARMAP + /x8a/xc5 + /x8a/xc6 + /x8a/xc7 +- /x8a/xc9 ++ /x8a/xc9 + /x8a/xca + /x8a/xcb +- /x8a/xcc ++ /x8a/xcc + /x8a/xce +- /x8a/xcf ++ /x8a/xcf + /x8a/xd0 + /x8a/xd1 +- /x8a/xd2 ++ /x8a/xd2 + /x8a/xd3 +- /x8a/xd4 ++ /x8a/xd4 + /x8a/xd5 + /x8a/xd6 + /x8a/xd7 +- /x8a/xd8 +- /x8a/xd9 ++ /x8a/xd8 ++ /x8a/xd9 + /x8a/xda + /x8a/xdb +- /x8a/xdc +- /x8a/xdf +- /x8a/xe0 +- /x8a/xe1 +- /x8a/xe2 ++ /x8a/xdc ++ /x8a/xdf ++ /x8a/xe0 ++ /x8a/xe1 ++ /x8a/xe2 + /x8a/xe3 + /x8a/xe4 +- /x8a/xe5 +- /x8a/xe6 ++ /x8a/xe5 ++ /x8a/xe6 + /x8a/xe7 +- /x8a/xe8 ++ /x8a/xe8 + /x8a/xe9 + /x8a/xea + /x8a/xeb + /x8a/xec +- /x8a/xed ++ /x8a/xed + /x8a/xee + /x8a/xef + /x8a/xf0 + /x8a/xf1 + /x8a/xf2 +- /x8a/xf3 +- /x8a/xf4 ++ /x8a/xf3 ++ /x8a/xf4 + /x8a/xf6 +- /x8a/xf7 ++ /x8a/xf7 + /x8a/xf8 + /x8a/xf9 + /x8a/xfa +@@ -510,14 +636,14 @@ CHARMAP + /x8b/x45 + /x8b/x46 + /x8b/x47 +- /x8b/x48 ++ /x8b/x48 + /x8b/x49 + /x8b/x4a +- /x8b/x4b ++ /x8b/x4b + /x8b/x4c +- /x8b/x4d +- /x8b/x4e +- /x8b/x4f ++ /x8b/x4d ++ /x8b/x4e ++ /x8b/x4f + /x8b/x50 + /x8b/x51 + /x8b/x52 +@@ -526,7 +652,7 @@ CHARMAP + /x8b/x56 + /x8b/x57 + /x8b/x58 +- /x8b/x59 ++ /x8b/x59 + /x8b/x5a + /x8b/x5b + /x8b/x5c +@@ -573,15 +699,15 @@ CHARMAP + /x8b/xa7 + /x8b/xa8 + /x8b/xa9 +- /x8b/xaa +- /x8b/xab ++ /x8b/xaa ++ /x8b/xab + /x8b/xac +- /x8b/xad +- /x8b/xae ++ /x8b/xad ++ /x8b/xae + /x8b/xaf + /x8b/xb0 + /x8b/xb1 +- /x8b/xb2 ++ /x8b/xb2 + /x8b/xb3 + /x8b/xb4 + /x8b/xb5 +@@ -597,10 +723,10 @@ CHARMAP + /x8b/xbf + /x8b/xc0 + /x8b/xc1 +- /x8b/xc2 +- /x8b/xc3 ++ /x8b/xc2 ++ /x8b/xc3 + /x8b/xc4 +- /x8b/xc5 ++ /x8b/xc5 + /x8b/xc6 + /x8b/xc7 + /x8b/xc8 +@@ -617,45 +743,227 @@ CHARMAP + /x8b/xd3 + /x8b/xd4 + /x8b/xd5 +- /x8b/xd6 ++ /x8b/xd6 + /x8b/xd7 + /x8b/xd8 + /x8b/xd9 + /x8b/xda +- /x8b/xdb ++ /x8b/xdb + /x8b/xdc +- /x8b/xde ++ /x8b/xde + /x8b/xdf + /x8b/xe0 +- /x8b/xe1 +- /x8b/xe2 ++ /x8b/xe1 ++ /x8b/xe2 + /x8b/xe3 + /x8b/xe4 + /x8b/xe5 +- /x8b/xe6 ++ /x8b/xe6 + /x8b/xe7 + /x8b/xe8 + /x8b/xe9 + /x8b/xea + /x8b/xeb + /x8b/xec +- /x8b/xed ++ /x8b/xed + /x8b/xee + /x8b/xef + /x8b/xf0 + /x8b/xf1 + /x8b/xf2 +- /x8b/xf3 ++ /x8b/xf3 + /x8b/xf4 + /x8b/xf5 + /x8b/xf6 + /x8b/xf7 +-%IRREVERSIBLE% /x8b/xf8 ++ /x8b/xf8 + /x8b/xf9 +- /x8b/xfa ++ /x8b/xfa + /x8b/xfb + /x8b/xfc + /x8b/xfd ++ /x8c/x40 ++ /x8c/x41 ++ /x8c/x42 ++ /x8c/x43 ++ /x8c/x44 ++ /x8c/x45 ++ /x8c/x46 ++ /x8c/x47 ++ /x8c/x48 ++ /x8c/x49 ++ /x8c/x4a ++ /x8c/x4b ++ /x8c/x4c ++ /x8c/x4d ++ /x8c/x4e ++ /x8c/x4f ++ /x8c/x50 ++ /x8c/x51 ++ /x8c/x52 ++ /x8c/x53 ++ /x8c/x54 ++ /x8c/x55 ++ /x8c/x56 ++ /x8c/x57 ++ /x8c/x58 ++ /x8c/x59 ++ /x8c/x5a ++ /x8c/x5b ++ /x8c/x5c ++ /x8c/x5d ++ /x8c/x5e ++ /x8c/x5f ++ /x8c/x60 ++ /x8c/x61 ++ /x8c/x62 ++ /x8c/x63 ++ /x8c/x64 ++ /x8c/x65 ++ /x8c/x66 ++ /x8c/x67 ++ /x8c/x68 ++ /x8c/x69 ++ /x8c/x6a ++ /x8c/x6b ++ /x8c/x6c ++ /x8c/x6d ++ /x8c/x6e ++ /x8c/x6f ++ /x8c/x70 ++ /x8c/x71 ++ /x8c/x72 ++ /x8c/x73 ++ /x8c/x74 ++ /x8c/x75 ++ /x8c/x76 ++ /x8c/x77 ++ /x8c/x78 ++ /x8c/x79 ++ /x8c/x7a ++ /x8c/x7b ++ /x8c/x7c ++ /x8c/x7d ++ /x8c/x7e ++ /x8c/xa1 ++ /x8c/xa2 ++ /x8c/xa3 ++ /x8c/xa4 ++ /x8c/xa5 ++ /x8c/xa7 ++ /x8c/xa8 ++ /x8c/xa9 ++ /x8c/xaa ++ /x8c/xab ++ /x8c/xac ++ /x8c/xad ++ /x8c/xae ++ /x8c/xaf ++ /x8c/xb0 ++ /x8c/xb1 ++ /x8c/xb2 ++ /x8c/xb3 ++ /x8c/xb4 ++ /x8c/xb5 ++ /x8c/xb6 ++ /x8c/xb7 ++ /x8c/xb8 ++ /x8c/xb9 ++ /x8c/xba ++ /x8c/xbb ++ /x8c/xbc ++ /x8c/xbd ++ /x8c/xbe ++ /x8c/xbf ++ /x8c/xc0 ++ /x8c/xc1 ++ /x8c/xc2 ++ /x8c/xc3 ++ /x8c/xc4 ++ /x8c/xc5 ++ /x8c/xc9 ++ /x8c/xca ++ /x8c/xcb ++ /x8c/xcc ++ /x8c/xce ++ /x8c/xcf ++ /x8c/xd0 ++ /x8c/xd1 ++ /x8c/xd2 ++ /x8c/xd3 ++ /x8c/xd4 ++ /x8c/xd5 ++ /x8c/xd6 ++ /x8c/xd7 ++ /x8c/xd8 ++ /x8c/xd9 ++ /x8c/xda ++ /x8c/xdb ++ /x8c/xdc ++ /x8c/xdd ++ /x8c/xde ++ /x8c/xdf ++ /x8c/xe0 ++ /x8c/xe1 ++ /x8c/xe2 ++ /x8c/xe3 ++ /x8c/xe4 ++ /x8c/xe6 ++ /x8c/xe7 ++ /x8c/xe8 ++ /x8c/xe9 ++ /x8c/xea ++ /x8c/xeb ++ /x8c/xec ++ /x8c/xed ++ /x8c/xee ++ /x8c/xef ++ /x8c/xf0 ++ /x8c/xf1 ++ /x8c/xf2 ++ /x8c/xf3 ++ /x8c/xf4 ++ /x8c/xf5 ++ /x8c/xf6 ++ /x8c/xf7 ++ /x8c/xf8 ++ /x8c/xf9 ++ /x8c/xfa ++ /x8c/xfb ++ /x8c/xfc ++ /x8c/xfd ++ /x8c/xfe ++ /x8d/x40 ++ /x8d/x42 ++ /x8d/x43 ++ /x8d/x44 ++ /x8d/x45 ++ /x8d/x46 ++ /x8d/x47 ++ /x8d/x48 ++ /x8d/x49 ++ /x8d/x4a ++ /x8d/x4b ++ /x8d/x4c ++ /x8d/x4d ++ /x8d/x4e ++ /x8d/x4f ++ /x8d/x50 ++ /x8d/x51 ++ /x8d/x52 ++ /x8d/x53 ++ /x8d/x54 ++ /x8d/x55 ++ /x8d/x56 ++ /x8d/x57 ++ /x8d/x58 ++ /x8d/x59 ++ /x8d/x5a ++ /x8d/x5b ++ /x8d/x5c ++ /x8d/x5d ++ /x8d/x5e ++ /x8d/x5f + /x8d/x60 + /x8d/x61 + /x8d/x62 +@@ -780,8 +1088,8 @@ CHARMAP + /x8d/xfb + /x8d/xfc + /x8d/xfd +- /x8d/xfe +- /x8e/x40 ++ /x8d/xfe ++ /x8e/x40 + /x8e/x41 + /x8e/x42 + /x8e/x43 +@@ -801,7 +1109,7 @@ CHARMAP + /x8e/x51 + /x8e/x52 + /x8e/x53 +- /x8e/x54 ++ /x8e/x54 + /x8e/x55 + /x8e/x56 + /x8e/x57 +@@ -812,7 +1120,7 @@ CHARMAP + /x8e/x5c + /x8e/x5d + /x8e/x5e +- /x8e/x5f ++ /x8e/x5f + /x8e/x60 + /x8e/x61 + /x8e/x62 +@@ -822,7 +1130,7 @@ CHARMAP + /x8e/x66 + /x8e/x67 + /x8e/x68 +- /x8e/x6a ++ /x8e/x6a + /x8e/x6b + /x8e/x6c + /x8e/x6d +@@ -831,7 +1139,7 @@ CHARMAP + /x8e/x71 + /x8e/x72 + /x8e/x73 +- /x8e/x74 ++ /x8e/x74 + /x8e/x75 + /x8e/x76 + /x8e/x77 +@@ -858,7 +1166,7 @@ CHARMAP + /x8e/xb0 + /x8e/xb1 + /x8e/xb2 +- /x8e/xb3 ++ /x8e/xb3 + /x8e/xb5 + /x8e/xb6 + /x8e/xb7 +@@ -886,15 +1194,15 @@ CHARMAP + /x8e/xce + /x8e/xcf + /x8e/xd1 +- /x8e/xd2 +- /x8e/xd3 ++ /x8e/xd2 ++ /x8e/xd3 + /x8e/xd4 + /x8e/xd5 + /x8e/xd6 +- /x8e/xd7 ++ /x8e/xd7 + /x8e/xd8 + /x8e/xd9 +- /x8e/xda ++ /x8e/xda + /x8e/xdb + /x8e/xdc + /x8e/xdd +@@ -905,9 +1213,9 @@ CHARMAP + /x8e/xe2 + /x8e/xe3 + /x8e/xe4 +- /x8e/xe5 ++ /x8e/xe5 + /x8e/xe6 +- /x8e/xe7 ++ /x8e/xe7 + /x8e/xe8 + /x8e/xe9 + /x8e/xea +@@ -915,9 +1223,9 @@ CHARMAP + /x8e/xec + /x8e/xed + /x8e/xee +- /x8e/xef ++ /x8e/xef + /x8e/xf0 +- /x8e/xf1 ++ /x8e/xf1 + /x8e/xf2 + /x8e/xf3 + /x8e/xf4 +@@ -937,14 +1245,14 @@ CHARMAP + /x8f/x43 + /x8f/x44 + /x8f/x45 +- /x8f/x46 ++ /x8f/x46 + /x8f/x47 + /x8f/x48 + /x8f/x49 + /x8f/x4a + /x8f/x4b + /x8f/x4c +- /x8f/x4d ++ /x8f/x4d + /x8f/x4e + /x8f/x4f + /x8f/x50 +@@ -961,15 +1269,15 @@ CHARMAP + /x8f/x5c + /x8f/x5d + /x8f/x5e +- /x8f/x5f ++ /x8f/x5f + /x8f/x60 +- /x8f/x61 ++ /x8f/x61 + /x8f/x62 + /x8f/x63 + /x8f/x64 + /x8f/x65 + /x8f/x66 +- /x8f/x67 ++ /x8f/x67 + /x8f/x68 + /x8f/x6a + /x8f/x6b +@@ -979,13 +1287,13 @@ CHARMAP + /x8f/x70 + /x8f/x71 + /x8f/x72 +- /x8f/x73 ++ /x8f/x73 + /x8f/x74 + /x8f/x75 + /x8f/x76 + /x8f/x77 + /x8f/x78 +- /x8f/x79 ++ /x8f/x79 + /x8f/x7a + /x8f/x7b + /x8f/x7c +@@ -994,11 +1302,11 @@ CHARMAP + /x8f/xa1 + /x8f/xa2 + /x8f/xa3 +- /x8f/xa4 ++ /x8f/xa4 + /x8f/xa5 +- /x8f/xa6 ++ /x8f/xa6 + /x8f/xa7 +- /x8f/xa8 ++ /x8f/xa8 + /x8f/xa9 + /x8f/xaa + /x8f/xab +@@ -1046,7 +1354,7 @@ CHARMAP + /x8f/xd7 + /x8f/xd8 + /x8f/xd9 +- /x8f/xda ++ /x8f/xda + /x8f/xdb + /x8f/xdc + /x8f/xdd +@@ -1062,7 +1370,7 @@ CHARMAP + /x8f/xe7 + /x8f/xe8 + /x8f/xe9 +- /x8f/xea ++ /x8f/xea + /x8f/xeb + /x8f/xec + /x8f/xed +@@ -1080,14 +1388,14 @@ CHARMAP + /x8f/xf9 + /x8f/xfa + /x8f/xfb +- /x8f/xfc ++ /x8f/xfc + /x8f/xfd + /x90/x40 + /x90/x41 +- /x90/x42 ++ /x90/x42 + /x90/x43 + /x90/x44 +- /x90/x45 ++ /x90/x45 + /x90/x46 + /x90/x47 + /x90/x48 +@@ -1110,9 +1418,9 @@ CHARMAP + /x90/x59 + /x90/x5a + /x90/x5b +- /x90/x5c +- /x90/x5d +- /x90/x5e ++ /x90/x5c ++ /x90/x5d ++ /x90/x5e + /x90/x5f + /x90/x60 + /x90/x61 +@@ -1123,7 +1431,7 @@ CHARMAP + /x90/x66 + /x90/x67 + /x90/x68 +- /x90/x69 ++ /x90/x69 + /x90/x6a + /x90/x6b + /x90/x6c +@@ -1143,7 +1451,7 @@ CHARMAP + /x90/x7c + /x90/x7d + /x90/x7e +- /x90/xa1 ++ /x90/xa1 + /x90/xa2 + /x90/xa3 + /x90/xa4 +@@ -1166,7 +1474,7 @@ CHARMAP + /x90/xb5 + /x90/xb6 + /x90/xb7 +- /x90/xb8 ++ /x90/xb8 + /x90/xb9 + /x90/xba + /x90/xbb +@@ -1198,11 +1506,11 @@ CHARMAP + /x90/xd5 + /x90/xd6 + /x90/xd7 +- /x90/xd8 ++ /x90/xd8 + /x90/xd9 + /x90/xda + /x90/xdb +- /x90/xdd ++ /x90/xdd + /x90/xde + /x90/xdf + /x90/xe0 +@@ -1224,7 +1532,7 @@ CHARMAP + /x90/xf0 + /x90/xf2 + /x90/xf3 +- /x90/xf4 ++ /x90/xf4 + /x90/xf5 + /x90/xf6 + /x90/xf7 +@@ -1289,24 +1597,24 @@ CHARMAP + /x91/x73 + /x91/x74 + /x91/x75 +- /x91/x76 ++ /x91/x76 + /x91/x77 + /x91/x78 + /x91/x79 + /x91/x7a + /x91/x7b +- /x91/x7c ++ /x91/x7c + /x91/x7d + /x91/x7e + /x91/xa1 +- /x91/xa2 ++ /x91/xa2 + /x91/xa3 + /x91/xa4 + /x91/xa5 + /x91/xa6 + /x91/xa7 +- /x91/xa8 +- /x91/xa9 ++ /x91/xa8 ++ /x91/xa9 + /x91/xaa + /x91/xab + /x91/xac +@@ -1367,10 +1675,10 @@ CHARMAP + /x91/xe4 + /x91/xe5 + /x91/xe6 +- /x91/xe7 ++ /x91/xe7 + /x91/xe8 + /x91/xe9 +- /x91/xea ++ /x91/xea + /x91/xeb + /x91/xec + /x91/xed +@@ -1380,23 +1688,23 @@ CHARMAP + /x91/xf1 + /x91/xf2 + /x91/xf3 +- /x91/xf4 ++ /x91/xf4 + /x91/xf5 + /x91/xf6 +- /x91/xf7 ++ /x91/xf7 + /x91/xf8 + /x91/xf9 + /x91/xfa + /x91/xfb + /x91/xfc + /x91/xfd +- /x91/xfe ++ /x91/xfe + /x92/x40 + /x92/x41 + /x92/x42 + /x92/x43 + /x92/x45 +- /x92/x46 ++ /x92/x46 + /x92/x47 + /x92/x48 + /x92/x49 +@@ -1411,23 +1719,23 @@ CHARMAP + /x92/x52 + /x92/x53 + /x92/x54 +- /x92/x55 ++ /x92/x55 + /x92/x56 + /x92/x57 + /x92/x58 +- /x92/x59 ++ /x92/x59 + /x92/x5a +- /x92/x5b ++ /x92/x5b + /x92/x5c + /x92/x5d + /x92/x5e + /x92/x5f + /x92/x60 +- /x92/x61 ++ /x92/x61 + /x92/x62 + /x92/x63 + /x92/x64 +- /x92/x65 ++ /x92/x65 + /x92/x66 + /x92/x67 + /x92/x68 +@@ -1451,13 +1759,13 @@ CHARMAP + /x92/x7a + /x92/x7b + /x92/x7c +- /x92/x7d ++ /x92/x7d + /x92/x7e + /x92/xa1 + /x92/xa2 + /x92/xa3 + /x92/xa4 +- /x92/xa5 ++ /x92/xa5 + /x92/xa6 + /x92/xa7 + /x92/xa8 +@@ -1469,7 +1777,7 @@ CHARMAP + /x92/xae + /x92/xb3 + /x92/xb4 +- /x92/xb5 ++ /x92/xb5 + /x92/xb6 + /x92/xb7 + /x92/xb8 +@@ -1493,7 +1801,7 @@ CHARMAP + /x92/xcb + /x92/xcc + /x92/xcd +- /x92/xce ++ /x92/xce + /x92/xcf + /x92/xd0 + /x92/xd2 +@@ -1532,10 +1840,10 @@ CHARMAP + /x92/xf3 + /x92/xf4 + /x92/xf5 +- /x92/xf6 ++ /x92/xf6 + /x92/xf7 + /x92/xf8 +- /x92/xf9 ++ /x92/xf9 + /x92/xfa + /x92/xfb + /x92/xfc +@@ -1577,7 +1885,7 @@ CHARMAP + /x93/x61 + /x93/x62 + /x93/x63 +- /x93/x64 ++ /x93/x64 + /x93/x65 + /x93/x66 + /x93/x67 +@@ -1591,7 +1899,7 @@ CHARMAP + /x93/x6f + /x93/x70 + /x93/x71 +- /x93/x72 ++ /x93/x72 + /x93/x73 + /x93/x74 + /x93/x75 +@@ -1603,7 +1911,7 @@ CHARMAP + /x93/x7b + /x93/x7c + /x93/x7d +- /x93/x7e ++ /x93/x7e + /x93/xa1 + /x93/xa2 + /x93/xa3 +@@ -1613,7 +1921,7 @@ CHARMAP + /x93/xa7 + /x93/xa8 + /x93/xa9 +- /x93/xaa ++ /x93/xaa + /x93/xab + /x93/xac + /x93/xad +@@ -1632,10 +1940,10 @@ CHARMAP + /x93/xba + /x93/xbb + /x93/xbc +- /x93/xbd ++ /x93/xbd + /x93/xbe + /x93/xbf +- /x93/xc0 ++ /x93/xc0 + /x93/xc1 + /x93/xc2 + /x93/xc3 +@@ -1649,7 +1957,7 @@ CHARMAP + /x93/xcb + /x93/xcc + /x93/xcd +- /x93/xce ++ /x93/xce + /x93/xcf + /x93/xd0 + /x93/xd1 +@@ -1658,14 +1966,14 @@ CHARMAP + /x93/xd4 + /x93/xd5 + /x93/xd6 +- /x93/xd7 ++ /x93/xd7 + /x93/xd8 + /x93/xd9 + /x93/xda + /x93/xdb + /x93/xdc + /x93/xdd +- /x93/xde ++ /x93/xde + /x93/xdf + /x93/xe0 + /x93/xe1 +@@ -1699,12 +2007,12 @@ CHARMAP + /x93/xfd + /x93/xfe + /x94/x40 +- /x94/x41 ++ /x94/x41 + /x94/x42 + /x94/x43 + /x94/x44 + /x94/x45 +- /x94/x46 ++ /x94/x46 + /x94/x48 + /x94/x49 + /x94/x4a +@@ -1728,8 +2036,8 @@ CHARMAP + /x94/x5c + /x94/x5d + /x94/x5e +- /x94/x5f +- /x94/x60 ++ /x94/x5f ++ /x94/x60 + /x94/x61 + /x94/x62 + /x94/x63 +@@ -1763,7 +2071,7 @@ CHARMAP + /x94/xa1 + /x94/xa2 + /x94/xa3 +- /x94/xa4 ++ /x94/xa4 + /x94/xa5 + /x94/xa6 + /x94/xa7 +@@ -1781,7 +2089,7 @@ CHARMAP + /x94/xb3 + /x94/xb4 + /x94/xb5 +- /x94/xb6 ++ /x94/xb6 + /x94/xb7 + /x94/xb8 + /x94/xb9 +@@ -1799,7 +2107,7 @@ CHARMAP + /x94/xc5 + /x94/xc6 + /x94/xc7 +- /x94/xc8 ++ /x94/xc8 + /x94/xc9 + /x94/xcb + /x94/xcc +@@ -1822,11 +2130,11 @@ CHARMAP + /x94/xdd + /x94/xde + /x94/xdf +- /x94/xe0 ++ /x94/xe0 + /x94/xe1 + /x94/xe2 + /x94/xe3 +- /x94/xe4 ++ /x94/xe4 + /x94/xe5 + /x94/xe6 + /x94/xe7 +@@ -1843,7 +2151,7 @@ CHARMAP + /x94/xf2 + /x94/xf3 + /x94/xf4 +- /x94/xf5 ++ /x94/xf5 + /x94/xf6 + /x94/xf7 + /x94/xf8 +@@ -1854,18 +2162,18 @@ CHARMAP + /x94/xfd + /x94/xfe + /x95/x40 +- /x95/x41 ++ /x95/x41 + /x95/x42 + /x95/x43 + /x95/x44 +- /x95/x45 ++ /x95/x45 + /x95/x46 + /x95/x47 + /x95/x48 + /x95/x49 + /x95/x4a + /x95/x4b +- /x95/x4c ++ /x95/x4c + /x95/x4d + /x95/x4e + /x95/x4f +@@ -1878,15 +2186,15 @@ CHARMAP + /x95/x56 + /x95/x57 + /x95/x58 +- /x95/x59 ++ /x95/x59 + /x95/x5a + /x95/x5b + /x95/x5c + /x95/x5d +- /x95/x5e ++ /x95/x5e + /x95/x5f + /x95/x60 +- /x95/x61 ++ /x95/x61 + /x95/x62 + /x95/x63 + /x95/x64 +@@ -1905,14 +2213,14 @@ CHARMAP + /x95/x71 + /x95/x72 + /x95/x73 +- /x95/x74 ++ /x95/x74 + /x95/x75 + /x95/x76 + /x95/x77 + /x95/x78 + /x95/x79 +-%IRREVERSIBLE% /x95/x7a +- /x95/x7b ++ /x95/x7a ++ /x95/x7b + /x95/x7c + /x95/x7d + /x95/x7e +@@ -1927,7 +2235,7 @@ CHARMAP + /x95/xa9 + /x95/xaa + /x95/xab +- /x95/xac ++ /x95/xac + /x95/xad + /x95/xae + /x95/xaf +@@ -1941,7 +2249,7 @@ CHARMAP + /x95/xb7 + /x95/xb8 + /x95/xb9 +- /x95/xba ++ /x95/xba + /x95/xbb + /x95/xbc + /x95/xbd +@@ -1978,10 +2286,10 @@ CHARMAP + /x95/xdd + /x95/xde + /x95/xdf +- /x95/xe0 ++ /x95/xe0 + /x95/xe1 + /x95/xe2 +- /x95/xe3 ++ /x95/xe3 + /x95/xe4 + /x95/xe5 + /x95/xe6 +@@ -1992,16 +2300,16 @@ CHARMAP + /x95/xeb + /x95/xec + /x95/xed +- /x95/xee +- /x95/xef ++ /x95/xee ++ /x95/xef + /x95/xf0 + /x95/xf1 + /x95/xf2 +- /x95/xf3 ++ /x95/xf3 + /x95/xf4 + /x95/xf5 + /x95/xf6 +- /x95/xf7 ++ /x95/xf7 + /x95/xf8 + /x95/xf9 + /x95/xfa +@@ -2011,11 +2319,11 @@ CHARMAP + /x95/xfe + /x96/x40 + /x96/x41 +- /x96/x42 +- /x96/x43 ++ /x96/x42 ++ /x96/x43 + /x96/x45 + /x96/x46 +- /x96/x47 ++ /x96/x47 + /x96/x48 + /x96/x49 + /x96/x4a +@@ -2027,14 +2335,14 @@ CHARMAP + /x96/x50 + /x96/x51 + /x96/x52 +- /x96/x53 ++ /x96/x53 + /x96/x54 + /x96/x55 + /x96/x56 + /x96/x57 + /x96/x58 + /x96/x59 +- /x96/x5a ++ /x96/x5a + /x96/x5b + /x96/x5c + /x96/x5d +@@ -2048,21 +2356,21 @@ CHARMAP + /x96/x65 + /x96/x66 + /x96/x67 +- /x96/x68 ++ /x96/x68 + /x96/x69 + /x96/x6a + /x96/x6b + /x96/x6c + /x96/x6d + /x96/x6e +- /x96/x6f ++ /x96/x6f + /x96/x70 + /x96/x71 + /x96/x72 + /x96/x73 +- /x96/x74 ++ /x96/x74 + /x96/x75 +- /x96/x76 ++ /x96/x76 + /x96/x77 + /x96/x78 + /x96/x79 +@@ -2092,7 +2400,7 @@ CHARMAP + /x96/xb3 + /x96/xb4 + /x96/xb5 +- /x96/xb6 ++ /x96/xb6 + /x96/xb7 + /x96/xb8 + /x96/xb9 +@@ -2100,15 +2408,15 @@ CHARMAP + /x96/xbb + /x96/xbc + /x96/xbd +- /x96/xbe +- /x96/xbf ++ /x96/xbe ++ /x96/xbf + /x96/xc0 + /x96/xc1 + /x96/xc2 + /x96/xc3 +- /x96/xc4 ++ /x96/xc4 + /x96/xc5 +- /x96/xc6 ++ /x96/xc6 + /x96/xc7 + /x96/xc8 + /x96/xc9 +@@ -2116,7 +2424,7 @@ CHARMAP + /x96/xcb + /x96/xcc + /x96/xcd +- /x96/xce ++ /x96/xce + /x96/xcf + /x96/xd0 + /x96/xd1 +@@ -2149,7 +2457,7 @@ CHARMAP + /x96/xec + /x96/xee + /x96/xef +- /x96/xf0 ++ /x96/xf0 + /x96/xf1 + /x96/xf2 + /x96/xf3 +@@ -2157,9 +2465,9 @@ CHARMAP + /x96/xf5 + /x96/xf6 + /x96/xf7 +- /x96/xf8 ++ /x96/xf8 + /x96/xf9 +- /x96/xfa ++ /x96/xfa + /x96/xfb + /x96/xfd + /x96/xfe +@@ -2174,10 +2482,10 @@ CHARMAP + /x97/x48 + /x97/x49 + /x97/x4a +- /x97/x4b ++ /x97/x4b + /x97/x4c + /x97/x4d +- /x97/x4e ++ /x97/x4e + /x97/x4f + /x97/x50 + /x97/x51 +@@ -2207,8 +2515,8 @@ CHARMAP + /x97/x69 + /x97/x6a + /x97/x6b +- /x97/x6c +- /x97/x6d ++ /x97/x6c ++ /x97/x6d + /x97/x6e + /x97/x6f + /x97/x70 +@@ -2218,7 +2526,7 @@ CHARMAP + /x97/x74 + /x97/x75 + /x97/x76 +- /x97/x77 ++ /x97/x77 + /x97/x78 + /x97/x79 + /x97/x7a +@@ -2226,23 +2534,23 @@ CHARMAP + /x97/x7c + /x97/x7d + /x97/x7e +- /x97/xa1 +- /x97/xa2 ++ /x97/xa1 ++ /x97/xa2 + /x97/xa3 + /x97/xa4 +- /x97/xa5 +- /x97/xa6 ++ /x97/xa5 ++ /x97/xa6 + /x97/xa7 + /x97/xa8 + /x97/xa9 + /x97/xaa + /x97/xab + /x97/xac +- /x97/xad ++ /x97/xad + /x97/xae + /x97/xaf + /x97/xb0 +- /x97/xb1 ++ /x97/xb1 + /x97/xb2 + /x97/xb3 + /x97/xb4 +@@ -2267,7 +2575,7 @@ CHARMAP + /x97/xc7 + /x97/xc8 + /x97/xc9 +- /x97/xca ++ /x97/xca + /x97/xcb + /x97/xcc + /x97/xcd +@@ -2292,27 +2600,27 @@ CHARMAP + /x97/xe0 + /x97/xe1 + /x97/xe2 +- /x97/xe3 +- /x97/xe4 ++ /x97/xe3 ++ /x97/xe4 + /x97/xe5 + /x97/xe6 + /x97/xe7 + /x97/xe8 + /x97/xe9 + /x97/xea +- /x97/xeb ++ /x97/xeb + /x97/xec + /x97/xed + /x97/xee + /x97/xef + /x97/xf0 +- /x97/xf1 ++ /x97/xf1 + /x97/xf2 + /x97/xf3 + /x97/xf4 + /x97/xf5 + /x97/xf6 +- /x97/xf7 ++ /x97/xf7 + /x97/xf8 + /x97/xf9 + /x97/xfa +@@ -2321,7 +2629,7 @@ CHARMAP + /x97/xfd + /x97/xfe + /x98/x40 +- /x98/x41 ++ /x98/x41 + /x98/x42 + /x98/x43 + /x98/x44 +@@ -2349,7 +2657,7 @@ CHARMAP + /x98/x5a + /x98/x5b + /x98/x5c +- /x98/x5d ++ /x98/x5d + /x98/x5e + /x98/x5f + /x98/x60 +@@ -2372,34 +2680,34 @@ CHARMAP + /x98/x71 + /x98/x72 + /x98/x73 +- /x98/x74 ++ /x98/x74 + /x98/x75 + /x98/x76 + /x98/x77 + /x98/x78 + /x98/x79 + /x98/x7a +- /x98/x7b +- /x98/x7c ++ /x98/x7b ++ /x98/x7c + /x98/x7d + /x98/x7e + /x98/xa1 +- /x98/xa2 ++ /x98/xa2 + /x98/xa3 + /x98/xa4 + /x98/xa5 +- /x98/xa6 ++ /x98/xa6 + /x98/xa7 + /x98/xa8 +- /x98/xa9 +- /x98/xaa ++ /x98/xa9 ++ /x98/xaa + /x98/xab +- /x98/xac ++ /x98/xac + /x98/xad + /x98/xae + /x98/xaf + /x98/xb0 +- /x98/xb1 ++ /x98/xb1 + /x98/xb2 + /x98/xb3 + /x98/xb4 +@@ -2414,7 +2722,7 @@ CHARMAP + /x98/xbd + /x98/xbe + /x98/xbf +- /x98/xc0 ++ /x98/xc0 + /x98/xc1 + /x98/xc2 + /x98/xc3 +@@ -2472,7 +2780,7 @@ CHARMAP + /x98/xf7 + /x98/xf8 + /x98/xf9 +- /x98/xfa ++ /x98/xfa + /x98/xfb + /x98/xfc + /x98/xfd +@@ -2694,7 +3002,7 @@ CHARMAP + /x9a/x79 + /x9a/x7a + /x9a/x7b +- /x9a/x7c ++ /x9a/x7c + /x9a/x7d + /x9a/x7e + /x9a/xa1 +@@ -2716,242 +3024,242 @@ CHARMAP + /x9a/xb1 + /x9a/xb2 + /x9a/xb3 +- /x9a/xb4 +- /x9a/xb5 +- /x9a/xb6 ++ /x9a/xb4 ++ /x9a/xb5 ++ /x9a/xb6 + /x9a/xb7 + /x9a/xb8 + /x9a/xb9 +- /x9a/xba ++ /x9a/xba + /x9a/xbb + /x9a/xbc + /x9a/xbd +- /x9a/xbe +- /x9a/xbf +- /x9a/xc0 +- /x9a/xc1 ++ /x9a/xbe ++ /x9a/xbf ++ /x9a/xc0 ++ /x9a/xc1 + /x9a/xc2 + /x9a/xc3 +- /x9a/xc4 +- /x9a/xc5 +- /x9a/xc6 ++ /x9a/xc4 ++ /x9a/xc5 ++ /x9a/xc6 + /x9a/xc7 +- /x9a/xc8 +- /x9a/xc9 ++ /x9a/xc8 ++ /x9a/xc9 + /x9a/xca +- /x9a/xcb +- /x9a/xcc ++ /x9a/xcb ++ /x9a/xcc + /x9a/xcd +- /x9a/xce +- /x9a/xcf ++ /x9a/xce ++ /x9a/xcf + /x9a/xd0 +- /x9a/xd1 ++ /x9a/xd1 + /x9a/xd2 +- /x9a/xd3 +- /x9a/xd4 +- /x9a/xd5 +- /x9a/xd6 +- /x9a/xd7 +- /x9a/xd8 ++ /x9a/xd3 ++ /x9a/xd4 ++ /x9a/xd5 ++ /x9a/xd6 ++ /x9a/xd7 ++ /x9a/xd8 + /x9a/xd9 + /x9a/xda + /x9a/xdb +- /x9a/xdc ++ /x9a/xdc + /x9a/xdd +- /x9a/xde +- /x9a/xdf ++ /x9a/xde ++ /x9a/xdf + /x9a/xe0 +- /x9a/xe1 ++ /x9a/xe1 + /x9a/xe2 +- /x9a/xe3 ++ /x9a/xe3 + /x9a/xe4 +- /x9a/xe5 +- /x9a/xe6 ++ /x9a/xe5 ++ /x9a/xe6 + /x9a/xe7 + /x9a/xe8 + /x9a/xe9 +- /x9a/xea +- /x9a/xeb ++ /x9a/xea ++ /x9a/xeb + /x9a/xec +- /x9a/xed +- /x9a/xee +- /x9a/xef +- /x9a/xf0 ++ /x9a/xed ++ /x9a/xee ++ /x9a/xef ++ /x9a/xf0 + /x9a/xf1 + /x9a/xf2 + /x9a/xf3 +- /x9a/xf4 +- /x9a/xf5 ++ /x9a/xf4 ++ /x9a/xf5 + /x9a/xf6 +- /x9a/xf7 +- /x9a/xf8 +- /x9a/xf9 +- /x9a/xfa ++ /x9a/xf7 ++ /x9a/xf8 ++ /x9a/xf9 ++ /x9a/xfa + /x9a/xfb + /x9a/xfc +- /x9a/xfd +- /x9a/xfe +- /x9b/x40 +- /x9b/x41 +- /x9b/x42 +- /x9b/x43 +- /x9b/x44 +- /x9b/x45 ++ /x9a/xfd ++ /x9a/xfe ++ /x9b/x40 ++ /x9b/x41 ++ /x9b/x42 ++ /x9b/x43 ++ /x9b/x44 ++ /x9b/x45 + /x9b/x46 + /x9b/x47 +- /x9b/x48 ++ /x9b/x48 + /x9b/x49 + /x9b/x4a +- /x9b/x4b ++ /x9b/x4b + /x9b/x4c + /x9b/x4d + /x9b/x4e +- /x9b/x4f +- /x9b/x50 +- /x9b/x51 +- /x9b/x52 +- /x9b/x53 ++ /x9b/x4f ++ /x9b/x50 ++ /x9b/x51 ++ /x9b/x52 ++ /x9b/x53 + /x9b/x54 +- /x9b/x55 +- /x9b/x56 ++ /x9b/x55 ++ /x9b/x56 + /x9b/x57 + /x9b/x58 +- /x9b/x59 ++ /x9b/x59 + /x9b/x5a +- /x9b/x5b ++ /x9b/x5b + /x9b/x5c +- /x9b/x5d ++ /x9b/x5d + /x9b/x5e + /x9b/x5f +- /x9b/x60 +- /x9b/x62 +- /x9b/x63 +- /x9b/x64 ++ /x9b/x60 ++ /x9b/x62 ++ /x9b/x63 ++ /x9b/x64 + /x9b/x65 +- /x9b/x66 +- /x9b/x67 +- /x9b/x68 +- /x9b/x69 +- /x9b/x6a +- /x9b/x6b +- /x9b/x6c +- /x9b/x6d +- /x9b/x6e +- /x9b/x6f ++ /x9b/x66 ++ /x9b/x67 ++ /x9b/x68 ++ /x9b/x69 ++ /x9b/x6a ++ /x9b/x6b ++ /x9b/x6c ++ /x9b/x6d ++ /x9b/x6e ++ /x9b/x6f + /x9b/x70 + /x9b/x71 + /x9b/x72 +- /x9b/x73 +- /x9b/x74 +- /x9b/x75 ++ /x9b/x73 ++ /x9b/x74 ++ /x9b/x75 + /x9b/x77 +- /x9b/x79 +- /x9b/x7a ++ /x9b/x79 ++ /x9b/x7a + /x9b/x7c + /x9b/x7d + /x9b/x7e + /x9b/xa1 +- /x9b/xa2 ++ /x9b/xa2 + /x9b/xa3 + /x9b/xa4 +- /x9b/xa5 +- /x9b/xa6 ++ /x9b/xa5 ++ /x9b/xa6 + /x9b/xa7 + /x9b/xa8 + /x9b/xa9 + /x9b/xaa +- /x9b/xab ++ /x9b/xab + /x9b/xac +- /x9b/xad +- /x9b/xae ++ /x9b/xad ++ /x9b/xae + /x9b/xaf +- /x9b/xb0 ++ /x9b/xb0 + /x9b/xb1 +- /x9b/xb2 +- /x9b/xb3 ++ /x9b/xb2 ++ /x9b/xb3 + /x9b/xb4 + /x9b/xb5 + /x9b/xb6 + /x9b/xb7 + /x9b/xb8 + /x9b/xb9 +- /x9b/xba +- /x9b/xbb ++ /x9b/xba ++ /x9b/xbb + /x9b/xbc +- /x9b/xbd ++ /x9b/xbd + /x9b/xbe +- /x9b/xbf +- /x9b/xc0 +- /x9b/xc1 ++ /x9b/xbf ++ /x9b/xc0 ++ /x9b/xc1 + /x9b/xc2 + /x9b/xc3 + /x9b/xc4 + /x9b/xc5 +- /x9b/xc7 +- /x9b/xc8 +- /x9b/xc9 ++ /x9b/xc7 ++ /x9b/xc8 ++ /x9b/xc9 + /x9b/xca +- /x9b/xcb ++ /x9b/xcb + /x9b/xcc + /x9b/xcd +- /x9b/xce +- /x9b/xcf ++ /x9b/xce ++ /x9b/xcf + /x9b/xd0 + /x9b/xd1 +- /x9b/xd2 ++ /x9b/xd2 + /x9b/xd3 + /x9b/xd4 + /x9b/xd5 +- /x9b/xd6 +- /x9b/xd7 +- /x9b/xd8 ++ /x9b/xd6 ++ /x9b/xd7 ++ /x9b/xd8 + /x9b/xd9 + /x9b/xda +- /x9b/xdb ++ /x9b/xdb + /x9b/xdc + /x9b/xdd + /x9b/xdf +- /x9b/xe0 ++ /x9b/xe0 + /x9b/xe1 +- /x9b/xe2 ++ /x9b/xe2 + /x9b/xe3 +- /x9b/xe4 ++ /x9b/xe4 + /x9b/xe5 + /x9b/xe6 + /x9b/xe7 +- /x9b/xe8 ++ /x9b/xe8 + /x9b/xe9 + /x9b/xea +- /x9b/xeb +- /x9b/xed ++ /x9b/xeb ++ /x9b/xed + /x9b/xee + /x9b/xef + /x9b/xf0 +- /x9b/xf1 ++ /x9b/xf1 + /x9b/xf2 +- /x9b/xf3 ++ /x9b/xf3 + /x9b/xf4 + /x9b/xf5 +- /x9b/xf7 ++ /x9b/xf7 + /x9b/xf8 + /x9b/xf9 +- /x9b/xfa ++ /x9b/xfa + /x9b/xfb + /x9b/xfc +- /x9b/xfd +- /x9b/xfe ++ /x9b/xfd ++ /x9b/xfe + /x9c/x40 + /x9c/x41 +- /x9c/x43 +- /x9c/x44 ++ /x9c/x43 ++ /x9c/x44 + /x9c/x45 + /x9c/x46 +- /x9c/x47 ++ /x9c/x47 + /x9c/x48 + /x9c/x49 + /x9c/x4a +- /x9c/x4b +- /x9c/x4c ++ /x9c/x4b ++ /x9c/x4c + /x9c/x4d + /x9c/x4e + /x9c/x4f +@@ -2960,68 +3268,68 @@ CHARMAP + /x9c/x52 + /x9c/x54 + /x9c/x55 +- /x9c/x56 ++ /x9c/x56 + /x9c/x57 +- /x9c/x58 ++ /x9c/x58 + /x9c/x59 + /x9c/x5a + /x9c/x5b + /x9c/x5c + /x9c/x5d +- /x9c/x5e ++ /x9c/x5e + /x9c/x5f + /x9c/x60 + /x9c/x61 +- /x9c/x63 ++ /x9c/x63 + /x9c/x64 +- /x9c/x65 ++ /x9c/x65 + /x9c/x66 +- /x9c/x67 +- /x9c/x69 ++ /x9c/x67 ++ /x9c/x69 + /x9c/x6a + /x9c/x6c + /x9c/x6d +- /x9c/x6e ++ /x9c/x6e + /x9c/x6f +- /x9c/x70 +- /x9c/x71 ++ /x9c/x70 ++ /x9c/x71 + /x9c/x72 +- /x9c/x73 +- /x9c/x74 ++ /x9c/x73 ++ /x9c/x74 + /x9c/x75 +- /x9c/x76 +- /x9c/x78 ++ /x9c/x76 ++ /x9c/x78 + /x9c/x79 +- /x9c/x7a ++ /x9c/x7a + /x9c/x7b + /x9c/x7c +- /x9c/x7d ++ /x9c/x7d + /x9c/x7e + /x9c/xa1 + /x9c/xa2 +- /x9c/xa3 +- /x9c/xa4 ++ /x9c/xa3 ++ /x9c/xa4 + /x9c/xa5 +- /x9c/xa6 +- /x9c/xa7 ++ /x9c/xa6 ++ /x9c/xa7 + /x9c/xa8 + /x9c/xa9 +- /x9c/xaa ++ /x9c/xaa + /x9c/xab + /x9c/xac +- /x9c/xad ++ /x9c/xad + /x9c/xae + /x9c/xaf +- /x9c/xb0 ++ /x9c/xb0 + /x9c/xb1 + /x9c/xb2 + /x9c/xb3 +- /x9c/xb4 +- /x9c/xb5 ++ /x9c/xb4 ++ /x9c/xb5 + /x9c/xb6 + /x9c/xb7 + /x9c/xb8 +- /x9c/xb9 ++ /x9c/xb9 + /x9c/xba + /x9c/xbb + /x9c/xbe +@@ -3029,26 +3337,26 @@ CHARMAP + /x9c/xc0 + /x9c/xc1 + /x9c/xc2 +- /x9c/xc3 +- /x9c/xc4 ++ /x9c/xc3 ++ /x9c/xc4 + /x9c/xc5 + /x9c/xc6 + /x9c/xc7 + /x9c/xc8 + /x9c/xc9 +- /x9c/xca ++ /x9c/xca + /x9c/xcb + /x9c/xcc + /x9c/xcd +- /x9c/xce ++ /x9c/xce + /x9c/xcf + /x9c/xd1 + /x9c/xd2 + /x9c/xd3 +- /x9c/xd4 +- /x9c/xd5 +- /x9c/xd6 +- /x9c/xd7 ++ /x9c/xd4 ++ /x9c/xd5 ++ /x9c/xd6 ++ /x9c/xd7 + /x9c/xd8 + /x9c/xd9 + /x9c/xda +@@ -3056,21 +3364,21 @@ CHARMAP + /x9c/xdc + /x9c/xdd + /x9c/xde +- /x9c/xdf ++ /x9c/xdf + /x9c/xe0 +- /x9c/xe1 ++ /x9c/xe1 + /x9c/xe2 + /x9c/xe3 + /x9c/xe4 + /x9c/xe5 +- /x9c/xe6 ++ /x9c/xe6 + /x9c/xe7 + /x9c/xe8 + /x9c/xe9 +- /x9c/xea ++ /x9c/xea + /x9c/xeb + /x9c/xec +- /x9c/xed ++ /x9c/xed + /x9c/xee + /x9c/xef + /x9c/xf0 +@@ -3083,74 +3391,74 @@ CHARMAP + /x9c/xf7 + /x9c/xf8 + /x9c/xf9 +- /x9c/xfa ++ /x9c/xfa + /x9c/xfb + /x9c/xfc + /x9c/xfd +- /x9c/xfe +- /x9d/x40 +- /x9d/x41 +- /x9d/x42 +- /x9d/x43 +- /x9d/x44 +- /x9d/x45 ++ /x9c/xfe ++ /x9d/x40 ++ /x9d/x41 ++ /x9d/x42 ++ /x9d/x43 ++ /x9d/x44 ++ /x9d/x45 + /x9d/x46 +- /x9d/x47 ++ /x9d/x47 + /x9d/x48 + /x9d/x49 + /x9d/x4a +- /x9d/x4b ++ /x9d/x4b + /x9d/x4c + /x9d/x4d +- /x9d/x4e ++ /x9d/x4e + /x9d/x4f +- /x9d/x50 ++ /x9d/x50 + /x9d/x51 +- /x9d/x52 +- /x9d/x53 +- /x9d/x54 ++ /x9d/x52 ++ /x9d/x53 ++ /x9d/x54 + /x9d/x55 +- /x9d/x56 +- /x9d/x58 +- /x9d/x59 ++ /x9d/x56 ++ /x9d/x58 ++ /x9d/x59 + /x9d/x5b +- /x9d/x5c ++ /x9d/x5c + /x9d/x5d +- /x9d/x5e +- /x9d/x5f ++ /x9d/x5e ++ /x9d/x5f + /x9d/x60 + /x9d/x61 + /x9d/x62 +- /x9d/x63 ++ /x9d/x63 + /x9d/x64 +- /x9d/x65 +- /x9d/x66 +- /x9d/x67 +- /x9d/x68 +- /x9d/x69 ++ /x9d/x65 ++ /x9d/x66 ++ /x9d/x67 ++ /x9d/x68 ++ /x9d/x69 + /x9d/x6a +- /x9d/x6b +- /x9d/x6c ++ /x9d/x6b ++ /x9d/x6c + /x9d/x6d +- /x9d/x6e +- /x9d/x6f ++ /x9d/x6e ++ /x9d/x6f + /x9d/x70 +- /x9d/x71 ++ /x9d/x71 + /x9d/x72 + /x9d/x73 + /x9d/x74 +- /x9d/x75 ++ /x9d/x75 + /x9d/x76 +- /x9d/x77 ++ /x9d/x77 + /x9d/x78 + /x9d/x79 +- /x9d/x7a ++ /x9d/x7a + /x9d/x7b + /x9d/x7c + /x9d/x7d + /x9d/x7e + /x9d/xa1 +- /x9d/xa2 ++ /x9d/xa2 + /x9d/xa3 + /x9d/xa4 + /x9d/xa5 +@@ -3160,14 +3468,14 @@ CHARMAP + /x9d/xa9 + /x9d/xaa + /x9d/xab +- /x9d/xac ++ /x9d/xac + /x9d/xad + /x9d/xae + /x9d/xaf +- /x9d/xb0 ++ /x9d/xb0 + /x9d/xb1 + /x9d/xb2 +- /x9d/xb3 ++ /x9d/xb3 + /x9d/xb4 + /x9d/xb5 + /x9d/xb6 +@@ -3192,14 +3500,14 @@ CHARMAP + /x9d/xca + /x9d/xcb + /x9d/xcc +- /x9d/xcd ++ /x9d/xcd + /x9d/xce + /x9d/xcf + /x9d/xd0 + /x9d/xd1 + /x9d/xd2 + /x9d/xd3 +- /x9d/xd4 ++ /x9d/xd4 + /x9d/xd5 + /x9d/xd6 + /x9d/xd7 +@@ -3224,7 +3532,7 @@ CHARMAP + /x9d/xea + /x9d/xeb + /x9d/xec +- /x9d/xed ++ /x9d/xed + /x9d/xee + /x9d/xef + /x9d/xf0 +@@ -3237,12 +3545,12 @@ CHARMAP + /x9d/xf7 + /x9d/xf8 + /x9d/xf9 +- /x9d/xfa ++ /x9d/xfa + /x9d/xfb + /x9d/xfc + /x9d/xfd +- /x9d/xfe +- /x9e/x40 ++ /x9d/xfe ++ /x9e/x40 + /x9e/x41 + /x9e/x42 + /x9e/x43 +@@ -3257,9 +3565,9 @@ CHARMAP + /x9e/x4c + /x9e/x4d + /x9e/x4e +- /x9e/x4f ++ /x9e/x4f + /x9e/x50 +- /x9e/x51 ++ /x9e/x51 + /x9e/x52 + /x9e/x53 + /x9e/x54 +@@ -3269,7 +3577,7 @@ CHARMAP + /x9e/x58 + /x9e/x59 + /x9e/x5a +- /x9e/x5b ++ /x9e/x5b + /x9e/x5c + /x9e/x5d + /x9e/x5e +@@ -3290,7 +3598,7 @@ CHARMAP + /x9e/x6d + /x9e/x6e + /x9e/x6f +- /x9e/x70 ++ /x9e/x70 + /x9e/x71 + /x9e/x72 + /x9e/x73 +@@ -3302,20 +3610,20 @@ CHARMAP + /x9e/x79 + /x9e/x7a + /x9e/x7b +- /x9e/x7c ++ /x9e/x7c + /x9e/x7d + /x9e/x7e + /x9e/xa1 + /x9e/xa2 + /x9e/xa3 + /x9e/xa4 +- /x9e/xa5 ++ /x9e/xa5 + /x9e/xa6 + /x9e/xa7 + /x9e/xa8 +- /x9e/xaa ++ /x9e/xaa + /x9e/xab +- /x9e/xad ++ /x9e/xad + /x9e/xae + /x9e/xaf + /x9e/xb0 +@@ -3330,13 +3638,13 @@ CHARMAP + /x9e/xb9 + /x9e/xba + /x9e/xbb +- /x9e/xbc ++ /x9e/xbc + /x9e/xbd + /x9e/xbe + /x9e/xbf + /x9e/xc0 + /x9e/xc1 +- /x9e/xc2 ++ /x9e/xc2 + /x9e/xc3 + /x9e/xc5 + /x9e/xc6 +@@ -3349,10 +3657,10 @@ CHARMAP + /x9e/xcd + /x9e/xce + /x9e/xcf +- /x9e/xd0 ++ /x9e/xd0 + /x9e/xd1 + /x9e/xd2 +- /x9e/xd3 ++ /x9e/xd3 + /x9e/xd4 + /x9e/xd5 + /x9e/xd6 +@@ -3365,19 +3673,19 @@ CHARMAP + /x9e/xdd + /x9e/xde + /x9e/xdf +- /x9e/xe0 ++ /x9e/xe0 + /x9e/xe1 + /x9e/xe2 + /x9e/xe3 + /x9e/xe4 +- /x9e/xe5 ++ /x9e/xe5 + /x9e/xe6 + /x9e/xe7 + /x9e/xe8 + /x9e/xe9 + /x9e/xea + /x9e/xeb +- /x9e/xec ++ /x9e/xec + /x9e/xed + /x9e/xee + /x9e/xf0 +@@ -3388,7 +3696,7 @@ CHARMAP + /x9e/xf6 + /x9e/xf7 + /x9e/xf8 +- /x9e/xf9 ++ /x9e/xf9 + /x9e/xfa + /x9e/xfb + /x9e/xfc +@@ -3399,16 +3707,16 @@ CHARMAP + /x9f/x43 + /x9f/x44 + /x9f/x45 +- /x9f/x46 +- /x9f/x47 ++ /x9f/x46 ++ /x9f/x47 + /x9f/x48 + /x9f/x49 +- /x9f/x4a ++ /x9f/x4a + /x9f/x4b + /x9f/x4c +- /x9f/x4d ++ /x9f/x4d + /x9f/x4f +- /x9f/x50 ++ /x9f/x50 + /x9f/x51 + /x9f/x52 + /x9f/x53 +@@ -3469,7 +3777,7 @@ CHARMAP + /x9f/xaf + /x9f/xb0 + /x9f/xb2 +- /x9f/xb3 ++ /x9f/xb3 + /x9f/xb4 + /x9f/xb5 + /x9f/xb6 +@@ -3480,7 +3788,7 @@ CHARMAP + /x9f/xbb + /x9f/xbc + /x9f/xbd +- /x9f/xbe ++ /x9f/xbe + /x9f/xbf + /x9f/xc1 + /x9f/xc2 +@@ -3496,7 +3804,7 @@ CHARMAP + /x9f/xce + /x9f/xcf + /x9f/xd0 +- /x9f/xd1 ++ /x9f/xd1 + /x9f/xd2 + /x9f/xd3 + /x9f/xd4 +@@ -3519,7 +3827,7 @@ CHARMAP + /x9f/xe8 + /x9f/xe9 + /x9f/xeb +- /x9f/xec ++ /x9f/xec + /x9f/xed + /x9f/xee + /x9f/xf0 +@@ -3596,7 +3904,7 @@ CHARMAP + /xa0/xa1 + /xa0/xa2 + /xa0/xa3 +- /xa0/xa4 ++ /xa0/xa4 + /xa0/xa6 + /xa0/xa7 + /xa0/xa8 +@@ -3606,7 +3914,7 @@ CHARMAP + /xa0/xac + /xa0/xae + /xa0/xb0 +- /xa0/xb1 ++ /xa0/xb1 + /xa0/xb2 + /xa0/xb3 + /xa0/xb4 +@@ -3660,7 +3968,7 @@ CHARMAP + /xa0/xe9 + /xa0/xea + /xa0/xeb +- /xa0/xec ++ /xa0/xec + /xa0/xed + /xa0/xee + /xa0/xef +@@ -3671,14 +3979,14 @@ CHARMAP + /xa0/xf4 + /xa0/xf5 + /xa0/xf6 +- /xa0/xf7 ++ /xa0/xf7 + /xa0/xf8 + /xa0/xf9 + /xa0/xfa +- /xa0/xfb ++ /xa0/xfb + /xa0/xfc + /xa0/xfd +- /xa0/xfe ++ /xa0/xfe + /xa1/x40 IDEOGRAPHIC SPACE + /xa1/x41 FULLWIDTH COMMA + /xa1/x42 IDEOGRAPHIC COMMA +@@ -9783,16 +10091,16 @@ CHARMAP + /xc8/x76 UPWARDS WHITE ARROW + /xc8/x77 NORTH WEST ARROW TO LONG BAR + /xc8/x78 LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR +- /xc8/x79 +- /xc8/x7a ++ /xc8/x79 ++ /xc8/x7a + /xc8/x7b +- /xc8/x7c ++ /xc8/x7c + /xc8/x7d +- /xc8/x7e +- /xc8/xa1 ++ /xc8/x7e ++ /xc8/xa1 + /xc8/xa2 +- /xc8/xa3 +- /xc8/xa4 ++ /xc8/xa3 ++ /xc8/xa4 + /xc8/xcd FULLWIDTH NOT SIGN + /xc8/xce FULLWIDTH BROKEN BAR + /xc8/xcf FULLWIDTH APOSTROPHE +@@ -17536,7 +17844,7 @@ CHARMAP + /xfa/x40 + /xfa/x41 + /xfa/x42 +- /xfa/x43 ++ /xfa/x43 + /xfa/x44 + /xfa/x45 + /xfa/x46 +@@ -17557,10 +17865,10 @@ CHARMAP + /xfa/x55 + /xfa/x56 + /xfa/x57 +- /xfa/x58 ++ /xfa/x58 + /xfa/x59 + /xfa/x5a +- /xfa/x5b ++ /xfa/x5b + /xfa/x5c + /xfa/x5d + /xfa/x5e +@@ -17576,7 +17884,7 @@ CHARMAP + /xfa/x6a + /xfa/x6b + /xfa/x6c +- /xfa/x6d ++ /xfa/x6d + /xfa/x6e + /xfa/x6f + /xfa/x70 +@@ -17587,7 +17895,7 @@ CHARMAP + /xfa/x75 + /xfa/x76 + /xfa/x77 +- /xfa/x78 ++ /xfa/x78 + /xfa/x79 + /xfa/x7a + /xfa/x7b +@@ -17607,7 +17915,7 @@ CHARMAP + /xfa/xab + /xfa/xac + /xfa/xad +- /xfa/xae ++ /xfa/xae + /xfa/xaf + /xfa/xb0 + /xfa/xb1 +@@ -17621,7 +17929,7 @@ CHARMAP + /xfa/xb9 + /xfa/xba + /xfa/xbb +- /xfa/xbc ++ /xfa/xbc + /xfa/xbe + /xfa/xbf + /xfa/xc0 +@@ -17676,13 +17984,13 @@ CHARMAP + /xfa/xf3 + /xfa/xf4 + /xfa/xf5 +- /xfa/xf6 ++ /xfa/xf6 + /xfa/xf7 + /xfa/xf8 + /xfa/xf9 + /xfa/xfa +- /xfa/xfb +- /xfa/xfc ++ /xfa/xfb ++ /xfa/xfc + /xfa/xfd + /xfa/xfe + /xfb/x40 +@@ -17724,7 +18032,7 @@ CHARMAP + /xfb/x65 + /xfb/x66 + /xfb/x67 +- /xfb/x68 ++ /xfb/x68 + /xfb/x69 + /xfb/x6a + /xfb/x6b +@@ -17735,7 +18043,7 @@ CHARMAP + /xfb/x70 + /xfb/x71 + /xfb/x72 +- /xfb/x73 ++ /xfb/x73 + /xfb/x74 + /xfb/x75 + /xfb/x76 +@@ -17769,17 +18077,17 @@ CHARMAP + /xfb/xb4 + /xfb/xb5 + /xfb/xb6 +- /xfb/xb7 ++ /xfb/xb7 + /xfb/xb9 + /xfb/xba + /xfb/xbb + /xfb/xbc + /xfb/xbd +- /xfb/xbe ++ /xfb/xbe + /xfb/xbf + /xfb/xc0 + /xfb/xc1 +- /xfb/xc2 ++ /xfb/xc2 + /xfb/xc3 + /xfb/xc4 + /xfb/xc5 +@@ -17788,11 +18096,11 @@ CHARMAP + /xfb/xc8 + /xfb/xc9 + /xfb/xca +- /xfb/xcb ++ /xfb/xcb + /xfb/xcc + /xfb/xcd +- /xfb/xce +- /xfb/xcf ++ /xfb/xce ++ /xfb/xcf + /xfb/xd0 + /xfb/xd1 + /xfb/xd2 +@@ -17829,7 +18137,7 @@ CHARMAP + /xfb/xf1 + /xfb/xf2 + /xfb/xf4 +- /xfb/xf5 ++ /xfb/xf5 + /xfb/xf6 + /xfb/xf7 + /xfb/xf8 +@@ -17859,11 +18167,11 @@ CHARMAP + /xfc/x53 + /xfc/x54 + /xfc/x55 +- /xfc/x56 ++ /xfc/x56 + /xfc/x57 + /xfc/x58 + /xfc/x59 +- /xfc/x5a ++ /xfc/x5a + /xfc/x5b + /xfc/x5c + /xfc/x5d +@@ -17872,7 +18180,7 @@ CHARMAP + /xfc/x60 + /xfc/x61 + /xfc/x62 +- /xfc/x63 ++ /xfc/x63 + /xfc/x64 + /xfc/x65 + /xfc/x66 +@@ -17882,20 +18190,20 @@ CHARMAP + /xfc/x6a + /xfc/x6b + /xfc/x6d +- /xfc/x6e ++ /xfc/x6e + /xfc/x6f +- /xfc/x70 ++ /xfc/x70 + /xfc/x71 + /xfc/x72 + /xfc/x73 + /xfc/x74 + /xfc/x75 + /xfc/x76 +- /xfc/x77 ++ /xfc/x77 + /xfc/x78 + /xfc/x79 + /xfc/x7a +- /xfc/x7b ++ /xfc/x7b + /xfc/x7c + /xfc/x7d + /xfc/x7e +@@ -17921,7 +18229,7 @@ CHARMAP + /xfc/xb4 + /xfc/xb5 + /xfc/xb6 +- /xfc/xb7 ++ /xfc/xb7 + /xfc/xb8 + /xfc/xba + /xfc/xbb +@@ -17963,7 +18271,7 @@ CHARMAP + /xfc/xdf + /xfc/xe0 + /xfc/xe1 +- /xfc/xe3 ++ /xfc/xe3 + /xfc/xe4 + /xfc/xe5 + /xfc/xe6 +@@ -17979,8 +18287,8 @@ CHARMAP + /xfc/xf0 + /xfc/xf2 + /xfc/xf3 +- /xfc/xf4 +- /xfc/xf5 ++ /xfc/xf4 ++ /xfc/xf5 + /xfc/xf6 + /xfc/xf7 + /xfc/xf8 +@@ -17990,7 +18298,7 @@ CHARMAP + /xfc/xfc + /xfc/xfd + /xfc/xfe +- /xfd/x40 ++ /xfd/x40 + /xfd/x41 + /xfd/x42 + /xfd/x43 +@@ -18014,10 +18322,10 @@ CHARMAP + /xfd/x55 + /xfd/x56 + /xfd/x57 +- /xfd/x58 ++ /xfd/x58 + /xfd/x59 + /xfd/x5a +- /xfd/x5b ++ /xfd/x5b + /xfd/x5c + /xfd/x5d + /xfd/x5e +@@ -18025,15 +18333,15 @@ CHARMAP + /xfd/x60 + /xfd/x61 + /xfd/x62 +- /xfd/x63 ++ /xfd/x63 + /xfd/x64 + /xfd/x65 + /xfd/x66 +- /xfd/x67 ++ /xfd/x67 + /xfd/x68 + /xfd/x69 + /xfd/x6a +- /xfd/x6b ++ /xfd/x6b + /xfd/x6c + /xfd/x6d + /xfd/x6e +@@ -18042,7 +18350,7 @@ CHARMAP + /xfd/x71 + /xfd/x72 + /xfd/x73 +- /xfd/x74 ++ /xfd/x74 + /xfd/x75 + /xfd/x76 + /xfd/x77 +@@ -18056,10 +18364,10 @@ CHARMAP + /xfd/xa1 + /xfd/xa2 + /xfd/xa3 +- /xfd/xa4 ++ /xfd/xa4 + /xfd/xa5 + /xfd/xa6 +- /xfd/xa7 ++ /xfd/xa7 + /xfd/xa8 + /xfd/xa9 + /xfd/xaa +@@ -18070,7 +18378,7 @@ CHARMAP + /xfd/xaf + /xfd/xb0 + /xfd/xb1 +- /xfd/xb2 ++ /xfd/xb2 + /xfd/xb3 + /xfd/xb4 + /xfd/xb5 +@@ -18097,16 +18405,16 @@ CHARMAP + /xfd/xcd + /xfd/xce + /xfd/xcf +- /xfd/xd0 ++ /xfd/xd0 + /xfd/xd1 + /xfd/xd2 + /xfd/xd3 + /xfd/xd4 +- /xfd/xd5 ++ /xfd/xd5 + /xfd/xd6 + /xfd/xd7 +- /xfd/xd8 +- /xfd/xd9 ++ /xfd/xd8 ++ /xfd/xd9 + /xfd/xda + /xfd/xdb + /xfd/xdc +@@ -18134,7 +18442,7 @@ CHARMAP + /xfd/xf3 + /xfd/xf4 + /xfd/xf5 +- /xfd/xf6 ++ /xfd/xf6 + /xfd/xf7 + /xfd/xf8 + /xfd/xf9 +@@ -18149,7 +18457,7 @@ CHARMAP + /xfe/x43 + /xfe/x44 + /xfe/x45 +- /xfe/x46 ++ /xfe/x46 + /xfe/x47 + /xfe/x48 + /xfe/x49 +@@ -18157,7 +18465,7 @@ CHARMAP + /xfe/x4b + /xfe/x4c + /xfe/x4d +- /xfe/x4e ++ /xfe/x4e + /xfe/x4f + /xfe/x50 + /xfe/x51 +@@ -18170,7 +18478,7 @@ CHARMAP + /xfe/x59 + /xfe/x5a + /xfe/x5b +- /xfe/x5c ++ /xfe/x5c + /xfe/x5d + /xfe/x5e + /xfe/x5f +@@ -18181,13 +18489,13 @@ CHARMAP + /xfe/x64 + /xfe/x65 + /xfe/x66 +- /xfe/x67 ++ /xfe/x67 + /xfe/x68 + /xfe/x69 + /xfe/x6a + /xfe/x6b + /xfe/x6c +- /xfe/x6d ++ /xfe/x6d + /xfe/x6e + /xfe/x70 + /xfe/x71 +@@ -18203,12 +18511,12 @@ CHARMAP + /xfe/x7b + /xfe/x7c + /xfe/x7d +- /xfe/x7e ++ /xfe/x7e + /xfe/xa1 + /xfe/xa2 + /xfe/xa3 + /xfe/xa4 +- /xfe/xa5 ++ /xfe/xa5 + /xfe/xa6 + /xfe/xa7 + /xfe/xa8 +@@ -18217,7 +18525,7 @@ CHARMAP + /xfe/xac + /xfe/xad + /xfe/xae +- /xfe/xaf ++ /xfe/xaf + /xfe/xb0 + /xfe/xb1 + /xfe/xb2 +@@ -18225,7 +18533,7 @@ CHARMAP + /xfe/xb4 + /xfe/xb5 + /xfe/xb6 +- /xfe/xb7 ++ /xfe/xb7 + /xfe/xb8 + /xfe/xb9 + /xfe/xba +@@ -18236,7 +18544,7 @@ CHARMAP + /xfe/xbf + /xfe/xc0 + /xfe/xc1 +- /xfe/xc2 ++ /xfe/xc2 + /xfe/xc3 + /xfe/xc4 + /xfe/xc5 +@@ -18250,7 +18558,7 @@ CHARMAP + /xfe/xcd + /xfe/xce + /xfe/xcf +- /xfe/xd0 ++ /xfe/xd0 + /xfe/xd1 + /xfe/xd2 + /xfe/xd3 +@@ -18259,12 +18567,12 @@ CHARMAP + /xfe/xd6 + /xfe/xd7 + /xfe/xd8 +- /xfe/xd9 +- /xfe/xda ++ /xfe/xd9 ++ /xfe/xda + /xfe/xdb + /xfe/xdc +- /xfe/xde +- /xfe/xdf ++ /xfe/xde ++ /xfe/xdf + /xfe/xe0 + /xfe/xe1 + /xfe/xe2 +@@ -18279,7 +18587,7 @@ CHARMAP + /xfe/xeb + /xfe/xec + /xfe/xed +- /xfe/xee ++ /xfe/xee + /xfe/xef + /xfe/xf0 + /xfe/xf1 +@@ -18299,15 +18607,11 @@ CHARMAP + END CHARMAP + + WIDTH +-... 2 +- 2 +- 2 +- 2 +- 2 +-... 2 ++... 2 ++... 2 + ... 2 + ... 2 +-... 2 ++... 2 + ... 2 +-... 2 ++... 2 + END WIDTH diff --git a/SOURCES/glibc-rh1213603.patch b/SOURCES/glibc-rh1213603.patch new file mode 100644 index 00000000..0ffad671 --- /dev/null +++ b/SOURCES/glibc-rh1213603.patch @@ -0,0 +1,41 @@ +commit 31d0a4fa646db8b8c97ce24e0ec0a7b73de4fca1 +Author: Florian Weimer +Date: Sat Jun 11 12:12:56 2016 +0200 + + nss_db: Fix initialization of iteration position [BZ #20237] + + When get*ent is called without a preceding set*ent, we need + to set the initial iteration position in get*ent. + + Reproducer: Add “services: db files†to /etc/nsswitch.conf, then run + “perl -e getserventâ€. It will segfault before this change, and exit + silently after it. + +Index: b/nss/nss_db/db-XXX.c +=================================================================== +--- a/nss/nss_db/db-XXX.c ++++ b/nss/nss_db/db-XXX.c +@@ -76,7 +76,7 @@ CONCAT(_nss_db_set,ENTNAME) (int stayope + keep_db |= stayopen; + + /* Reset the sequential index. */ +- entidx = (const char *) state.header + state.header->valstroffset; ++ entidx = NULL; + } + + __libc_lock_unlock (lock); +@@ -249,8 +249,14 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct ST + H_ERRNO_SET (NETDB_INTERNAL); + goto out; + } ++ entidx = NULL; + } + ++ /* Start from the beginning if freshly initialized or reset ++ requested by set*ent. */ ++ if (entidx == NULL) ++ entidx = (const char *) state.header + state.header->valstroffset; ++ + status = NSS_STATUS_UNAVAIL; + if (state.header != MAP_FAILED) + { diff --git a/SOURCES/glibc-rh1216246.patch b/SOURCES/glibc-rh1216246.patch new file mode 100644 index 00000000..0df56f33 --- /dev/null +++ b/SOURCES/glibc-rh1216246.patch @@ -0,0 +1,69 @@ +commit 8b59c73386ddb64331ee03c29925a18dae547733 +Author: Carlos O'Donell +Date: Wed Jul 8 02:42:11 2015 -0400 + + Fix ruserok scalability with large ~/.rhosts file. + + Fixes bug 18557. + +diff --git glibc-2.17-c758a686/inet/rcmd.c glibc-2.17-c758a686/inet/rcmd.c +index 98b3735..91623b0 100644 +--- glibc-2.17-c758a686/inet/rcmd.c ++++ glibc-2.17-c758a686/inet/rcmd.c +@@ -809,29 +809,38 @@ __validuser2_sa(hostf, ra, ralen, luser, ruser, rhost) + *p = '\0'; /* terminate username (+host?) */ + + /* buf -> host(?) ; user -> username(?) */ ++ if (*buf == '\0') ++ break; ++ if (*user == '\0') ++ user = luser; ++ ++ /* First check the user part. This is an optimization, since ++ one should always check the host first in order to detect ++ negative host checks (which we check for later). */ ++ ucheck = __icheckuser (user, ruser); ++ ++ /* Either we found the user, or we didn't and this is a ++ negative host check. We must do the negative host lookup ++ in order to preserve the semantics of stopping on this line ++ before processing others. */ ++ if (ucheck != 0 || *buf == '-') { ++ ++ /* Next check host part */ ++ hcheck = __checkhost_sa (ra, ralen, buf, rhost); ++ ++ /* Negative '-host user(?)' match? */ ++ if (hcheck < 0) ++ break; + +- /* First check host part */ +- hcheck = __checkhost_sa (ra, ralen, buf, rhost); +- +- if (hcheck < 0) +- break; +- +- if (hcheck) { +- /* Then check user part */ +- if (! (*user)) +- user = luser; +- +- ucheck = __icheckuser (user, ruser); +- +- /* Positive 'host user' match? */ +- if (ucheck > 0) { ++ /* Positive 'host user' match? */ ++ if (hcheck > 0 && ucheck > 0) { + retval = 0; + break; + } + +- /* Negative 'host -user' match? */ +- if (ucheck < 0) +- break; ++ /* Negative 'host -user' match? */ ++ if (hcheck > 0 && ucheck < 0) ++ break; + + /* Neither, go on looking for match */ + } diff --git a/SOURCES/glibc-rh1219891.patch b/SOURCES/glibc-rh1219891.patch new file mode 100644 index 00000000..73a5bb84 --- /dev/null +++ b/SOURCES/glibc-rh1219891.patch @@ -0,0 +1,117 @@ +commit e83d72988d89378e7c70a1b7ba0b450a699ea70a +Author: David S. Miller +Date: Wed Jan 9 23:04:32 2013 -0800 + + Sync netinet/tcp.h with upstream Linux kernel. + + [BZ# 15003] + * sysdeps/gnu/netinet/tcp.h (TCP_COOKIE_TRANSACTIONS, + TCP_THIN_LINEAR_TIMEOUTS, TCP_THIN_DUPACK, TCP_USER_TIMEOUT, + TCP_REPAIR, TCP_REPAIR_QUEUE, TCP_QUEUE_SEQ, TCP_REPAIR_OPTIONS, + TCP_FASTOPEN): Define. + (tcp_repair_opt): New structure. + (TCP_NO_QUEUE, TCP_RECV_QUEUE, TCP_SEND_QUEUE, TCP_QUEUES_NR): New + enum values. + (TCP_COOKIE_MIN, TCP_COOKIE_MAX, TCP_COOKIE_PAIR_SIZE, + TCP_COOKIE_IN_ALWAYS, TCP_COOKIE_OUT_NEVER, TCP_S_DATA_IN, + TCP_S_DATA_OUT, TCP_MSS_DEFAULT, TCP_MSS_DESIRED): Define. + (tcp_cookie_transactions): New structure. + +diff --git glibc-2.17-c758a686/sysdeps/gnu/netinet/tcp.h glibc-2.17-c758a686/sysdeps/gnu/netinet/tcp.h +index 278fc9d..b62a696 100644 +--- glibc-2.17-c758a686/sysdeps/gnu/netinet/tcp.h ++++ glibc-2.17-c758a686/sysdeps/gnu/netinet/tcp.h +@@ -37,20 +37,29 @@ + /* + * User-settable options (used with setsockopt). + */ +-#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */ +-#define TCP_MAXSEG 2 /* Set maximum segment size */ +-#define TCP_CORK 3 /* Control sending of partial frames */ +-#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ +-#define TCP_KEEPINTVL 5 /* Interval between keepalives */ +-#define TCP_KEEPCNT 6 /* Number of keepalives before death */ +-#define TCP_SYNCNT 7 /* Number of SYN retransmits */ +-#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ +-#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ +-#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ +-#define TCP_INFO 11 /* Information about this connection. */ +-#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */ +-#define TCP_CONGESTION 13 /* Congestion control algorithm. */ +-#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ ++#define TCP_NODELAY 1 /* Don't delay send to coalesce packets */ ++#define TCP_MAXSEG 2 /* Set maximum segment size */ ++#define TCP_CORK 3 /* Control sending of partial frames */ ++#define TCP_KEEPIDLE 4 /* Start keeplives after this period */ ++#define TCP_KEEPINTVL 5 /* Interval between keepalives */ ++#define TCP_KEEPCNT 6 /* Number of keepalives before death */ ++#define TCP_SYNCNT 7 /* Number of SYN retransmits */ ++#define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */ ++#define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */ ++#define TCP_WINDOW_CLAMP 10 /* Bound advertised window */ ++#define TCP_INFO 11 /* Information about this connection. */ ++#define TCP_QUICKACK 12 /* Bock/reenable quick ACKs. */ ++#define TCP_CONGESTION 13 /* Congestion control algorithm. */ ++#define TCP_MD5SIG 14 /* TCP MD5 Signature (RFC2385) */ ++#define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ ++#define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ ++#define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ ++#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */ ++#define TCP_REPAIR 19 /* TCP sock is under repair right now */ ++#define TCP_REPAIR_QUEUE 20 /* Set TCP queue to repair */ ++#define TCP_QUEUE_SEQ 21 /* Set sequence number of repaired queue. */ ++#define TCP_REPAIR_OPTIONS 22 /* Repair TCP connection options */ ++#define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ + + #ifdef __USE_MISC + # include +@@ -243,6 +252,49 @@ struct tcp_md5sig + u_int8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* Key (binary). */ + }; + ++/* For socket repair options. */ ++struct tcp_repair_opt ++{ ++ u_int32_t opt_code; ++ u_int32_t opt_val; ++}; ++ ++/* Queue to repair, for TCP_REPAIR_QUEUE. */ ++enum ++{ ++ TCP_NO_QUEUE, ++ TCP_RECV_QUEUE, ++ TCP_SEND_QUEUE, ++ TCP_QUEUES_NR, ++}; ++ ++/* For cookie transactions socket options. */ ++#define TCP_COOKIE_MIN 8 /* 64-bits */ ++#define TCP_COOKIE_MAX 16 /* 128-bits */ ++#define TCP_COOKIE_PAIR_SIZE (2*TCP_COOKIE_MAX) ++ ++/* Flags for both getsockopt and setsockopt */ ++#define TCP_COOKIE_IN_ALWAYS (1 << 0) /* Discard SYN without cookie */ ++#define TCP_COOKIE_OUT_NEVER (1 << 1) /* Prohibit outgoing cookies, ++ * supercedes everything. */ ++ ++/* Flags for getsockopt */ ++#define TCP_S_DATA_IN (1 << 2) /* Was data received? */ ++#define TCP_S_DATA_OUT (1 << 3) /* Was data sent? */ ++ ++#define TCP_MSS_DEFAULT 536U /* IPv4 (RFC1122, RFC2581) */ ++#define TCP_MSS_DESIRED 1220U /* IPv6 (tunneled), EDNS0 (RFC3226) */ ++ ++struct tcp_cookie_transactions ++{ ++ u_int16_t tcpct_flags; ++ u_int8_t __tcpct_pad1; ++ u_int8_t tcpct_cookie_desired; ++ u_int16_t tcpct_s_data_desired; ++ u_int16_t tcpct_used; ++ u_int8_t tcpct_value[TCP_MSS_DEFAULT]; ++}; ++ + #endif /* Misc. */ + + #endif /* netinet/tcp.h */ diff --git a/SOURCES/glibc-rh1221046.patch b/SOURCES/glibc-rh1221046.patch new file mode 100644 index 00000000..38a3d59e --- /dev/null +++ b/SOURCES/glibc-rh1221046.patch @@ -0,0 +1,52 @@ +Superseded by this upstream patch: + +commit a06b40cdf5ba0d2ab4f9b4c77d21e45ff284fac7 +Author: Szabolcs Nagy +Date: Tue May 26 22:27:23 2015 +0530 + + struct stat is not posix conform + +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/generic/bits/stat.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/generic/bits/stat.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/generic/bits/stat.h +@@ -66,7 +66,7 @@ struct stat + __blksize_t st_blksize; /* Optimal block size for I/O. */ + int __pad2; + __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ +-#ifdef __USE_MISC ++#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -107,7 +107,7 @@ struct stat64 + __blksize_t st_blksize; /* Optimal block size for I/O. */ + int __pad2; + __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ +-#ifdef __USE_MISC ++#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/bits/stat.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/bits/stat.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/bits/stat.h +@@ -41,7 +41,7 @@ struct stat + int pad0; + __dev_t st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ +-#ifdef __USE_MISC ++#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -80,7 +80,7 @@ struct stat64 + int pad0; + __dev_t st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ +-#ifdef __USE_MISC ++#if defined __USE_MISC || defined __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the diff --git a/SOURCES/glibc-rh1227699.patch b/SOURCES/glibc-rh1227699.patch new file mode 100644 index 00000000..242cafed --- /dev/null +++ b/SOURCES/glibc-rh1227699.patch @@ -0,0 +1,33 @@ +# +# This is the original fix for bug 1124987 in Fedora. +# This patch should never go upstream. We are applying it +# in rhel-7.2 as a workaround. +# +# Upstream commit f8aeae347377f3dfa8cbadde057adf1827fb1d44 fixes +# this issue correctly, but reveals other bugs, therefore for now +# this patch is a workaround. +# +diff -urN glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +--- glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2014-08-21 01:00:55.000000000 -0400 ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2014-09-04 19:29:42.929692810 -0400 +@@ -388,8 +388,18 @@ + have to iterate beyond the first element in the slotinfo list. */ + #define TLS_SLOTINFO_SURPLUS (62) + +-/* Number of additional slots in the dtv allocated. */ +-#define DTV_SURPLUS (14) ++/* Number of additional allocated dtv slots. This was initially ++ 14, but problems with python, MESA, and X11's uses of static TLS meant ++ that most distributions were very close to this limit when they loaded ++ dynamically interpreted languages that used graphics. The simplest ++ solution was to roughly double the number of slots. The actual static ++ image space usage was relatively small, for example in MESA you ++ had only two dispatch pointers for a total of 16 bytes. If we hit up ++ against this limit again we should start a campaign with the ++ distributions to coordinate the usage of static TLS. Any user of this ++ resource is effectively coordinating a global resource since this ++ surplus is allocated for each thread at startup. */ ++#define DTV_SURPLUS (32) + + /* Initial dtv of the main thread, not allocated with normal malloc. */ + EXTERN void *_dl_initial_dtv; diff --git a/SOURCES/glibc-rh1228114-1.patch b/SOURCES/glibc-rh1228114-1.patch new file mode 100644 index 00000000..1e3df67a --- /dev/null +++ b/SOURCES/glibc-rh1228114-1.patch @@ -0,0 +1,234 @@ +commit 89fb6835583088059b8d8987c86caac33e37e5ea +Author: Siddhesh Poyarekar +Date: Tue Jun 11 11:11:11 2013 +0530 + + Fix symbol definitions for __clock_* functions + + __clock_gettime and other __clock_* functions could result in an extra + PLT reference within libc.so if it actually gets used. None of the + code currently uses them, which is why this probably went unnoticed. + +Index: b/include/time.h +=================================================================== +--- a/include/time.h ++++ b/include/time.h +@@ -21,6 +21,7 @@ libc_hidden_proto (strptime) + + extern __typeof (clock_getres) __clock_getres; + extern __typeof (clock_gettime) __clock_gettime; ++libc_hidden_proto (__clock_gettime) + extern __typeof (clock_settime) __clock_settime; + extern __typeof (clock_nanosleep) __clock_nanosleep; + extern __typeof (clock_getcpuclockid) __clock_getcpuclockid; +Index: b/rt/clock_getcpuclockid.c +=================================================================== +--- a/rt/clock_getcpuclockid.c ++++ b/rt/clock_getcpuclockid.c +@@ -21,7 +21,7 @@ + #include + + int +-clock_getcpuclockid (pid_t pid, clockid_t *clock_id) ++__clock_getcpuclockid (pid_t pid, clockid_t *clock_id) + { + /* We don't allow any process ID but our own. */ + if (pid != 0 && pid != getpid ()) +@@ -37,4 +37,4 @@ clock_getcpuclockid (pid_t pid, clockid_ + return ENOENT; + #endif + } +-strong_alias (clock_getcpuclockid, __clock_getcpuclockid) ++weak_alias (__clock_getcpuclockid, clock_getcpuclockid) +Index: b/rt/clock_getres.c +=================================================================== +--- a/rt/clock_getres.c ++++ b/rt/clock_getres.c +@@ -21,10 +21,10 @@ + + /* Get resolution of clock. */ + int +-clock_getres (clockid_t clock_id, struct timespec *res) ++__clock_getres (clockid_t clock_id, struct timespec *res) + { + __set_errno (ENOSYS); + return -1; + } +-strong_alias (clock_getres, __clock_getres) ++weak_alias (__clock_getres, clock_getres) + stub_warning (clock_getres) +Index: b/rt/clock_gettime.c +=================================================================== +--- a/rt/clock_gettime.c ++++ b/rt/clock_gettime.c +@@ -21,10 +21,11 @@ + + /* Get current value of CLOCK and store it in TP. */ + int +-clock_gettime (clockid_t clock_id, struct timespec *tp) ++__clock_gettime (clockid_t clock_id, struct timespec *tp) + { + __set_errno (ENOSYS); + return -1; + } +-strong_alias (clock_gettime, __clock_gettime) ++weak_alias (__clock_gettime, clock_gettime) ++libc_hidden_def (__clock_gettime) + stub_warning (clock_gettime) +Index: b/rt/clock_nanosleep.c +=================================================================== +--- a/rt/clock_nanosleep.c ++++ b/rt/clock_nanosleep.c +@@ -20,8 +20,8 @@ + #include + + int +-clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, +- struct timespec *rem) ++__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, ++ struct timespec *rem) + { + if (__builtin_expect (req->tv_nsec, 0) < 0 + || __builtin_expect (req->tv_nsec, 0) >= 1000000000) +@@ -33,5 +33,5 @@ clock_nanosleep (clockid_t clock_id, int + /* Not implemented. */ + return ENOSYS; + } +-strong_alias (clock_nanosleep, __clock_nanosleep) ++weak_alias (__clock_nanosleep, clock_nanosleep) + stub_warning (clock_nanosleep) +Index: b/rt/clock_settime.c +=================================================================== +--- a/rt/clock_settime.c ++++ b/rt/clock_settime.c +@@ -21,10 +21,10 @@ + + /* Set CLOCK to value TP. */ + int +-clock_settime (clockid_t clock_id, const struct timespec *tp) ++__clock_settime (clockid_t clock_id, const struct timespec *tp) + { + __set_errno (ENOSYS); + return -1; + } +-strong_alias (clock_settime, __clock_settime) ++weak_alias (__clock_settime, clock_settime) + stub_warning (clock_settime) +Index: b/sysdeps/posix/clock_getres.c +=================================================================== +--- a/sysdeps/posix/clock_getres.c ++++ b/sysdeps/posix/clock_getres.c +@@ -76,7 +76,7 @@ realtime_getres (struct timespec *res) + + /* Get resolution of clock. */ + int +-clock_getres (clockid_t clock_id, struct timespec *res) ++__clock_getres (clockid_t clock_id, struct timespec *res) + { + int retval = -1; + +@@ -115,4 +115,4 @@ clock_getres (clockid_t clock_id, struct + + return retval; + } +-strong_alias (clock_getres, __clock_getres) ++weak_alias (__clock_getres, clock_getres) +Index: b/sysdeps/unix/clock_gettime.c +=================================================================== +--- a/sysdeps/unix/clock_gettime.c ++++ b/sysdeps/unix/clock_gettime.c +@@ -89,7 +89,7 @@ realtime_gettime (struct timespec *tp) + + /* Get current value of CLOCK and store it in TP. */ + int +-clock_gettime (clockid_t clock_id, struct timespec *tp) ++__clock_gettime (clockid_t clock_id, struct timespec *tp) + { + int retval = -1; + +@@ -132,4 +132,5 @@ clock_gettime (clockid_t clock_id, struc + + return retval; + } +-strong_alias (clock_gettime, __clock_gettime) ++weak_alias (__clock_gettime, clock_gettime) ++libc_hidden_def (__clock_gettime) +Index: b/sysdeps/unix/clock_nanosleep.c +=================================================================== +--- a/sysdeps/unix/clock_nanosleep.c ++++ b/sysdeps/unix/clock_nanosleep.c +@@ -39,8 +39,8 @@ + /* This implementation assumes that these is only a `nanosleep' system + call. So we have to remap all other activities. */ + int +-clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, +- struct timespec *rem) ++__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, ++ struct timespec *rem) + { + struct timespec now; + +@@ -98,4 +98,4 @@ clock_nanosleep (clockid_t clock_id, int + + return __builtin_expect (nanosleep (req, rem), 0) ? errno : 0; + } +-strong_alias (clock_nanosleep, __clock_nanosleep) ++weak_alias (__clock_nanosleep, clock_nanosleep) +Index: b/sysdeps/unix/clock_settime.c +=================================================================== +--- a/sysdeps/unix/clock_settime.c ++++ b/sysdeps/unix/clock_settime.c +@@ -72,7 +72,7 @@ hp_timing_settime (clockid_t clock_id, c + + /* Set CLOCK to value TP. */ + int +-clock_settime (clockid_t clock_id, const struct timespec *tp) ++__clock_settime (clockid_t clock_id, const struct timespec *tp) + { + int retval; + +@@ -124,4 +124,4 @@ clock_settime (clockid_t clock_id, const + + return retval; + } +-strong_alias (clock_settime, __clock_settime) ++weak_alias (__clock_settime, clock_settime) +Index: b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/clock_getcpuclockid.c ++++ b/sysdeps/unix/sysv/linux/clock_getcpuclockid.c +@@ -23,7 +23,7 @@ + #include "kernel-posix-cpu-timers.h" + + int +-clock_getcpuclockid (pid_t pid, clockid_t *clock_id) ++__clock_getcpuclockid (pid_t pid, clockid_t *clock_id) + { + /* The clockid_t value is a simple computation from the PID. + But we do a clock_getres call to validate it. */ +@@ -46,4 +46,4 @@ clock_getcpuclockid (pid_t pid, clockid_ + else + return INTERNAL_SYSCALL_ERRNO (r, err); + } +-strong_alias (clock_getcpuclockid, __clock_getcpuclockid) ++weak_alias (__clock_getcpuclockid, clock_getcpuclockid) +Index: b/sysdeps/unix/sysv/linux/clock_nanosleep.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/clock_nanosleep.c ++++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c +@@ -26,8 +26,8 @@ + /* We can simply use the syscall. The CPU clocks are not supported + with this function. */ + int +-clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, +- struct timespec *rem) ++__clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, ++ struct timespec *rem) + { + INTERNAL_SYSCALL_DECL (err); + int r; +@@ -52,4 +52,4 @@ clock_nanosleep (clockid_t clock_id, int + return (INTERNAL_SYSCALL_ERROR_P (r, err) + ? INTERNAL_SYSCALL_ERRNO (r, err) : 0); + } +-strong_alias (clock_nanosleep, __clock_nanosleep) ++weak_alias (__clock_nanosleep, clock_nanosleep) diff --git a/SOURCES/glibc-rh1228114-2.patch b/SOURCES/glibc-rh1228114-2.patch new file mode 100644 index 00000000..af0ec9c9 --- /dev/null +++ b/SOURCES/glibc-rh1228114-2.patch @@ -0,0 +1,1551 @@ +commit cf0bd2f73bd65beab613865bba567d7787836888 +Author: Florian Weimer +Date: Tue Feb 28 15:28:45 2017 +0100 + + sunrpc: Improvements for UDP client timeout handling [BZ #20257] + + This commit fixes various aspects in the UDP client timeout handling. + Timeouts are now applied in a more consistent fashion. Discarded UDP + packets no longer prevent the timeout from happening at all. + +Index: b/inet/deadline.c +=================================================================== +--- /dev/null ++++ b/inet/deadline.c +@@ -0,0 +1,122 @@ ++/* Computing deadlines for timeouts. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct deadline_current_time internal_function ++__deadline_current_time (void) ++{ ++ struct deadline_current_time result; ++ if (__clock_gettime (CLOCK_MONOTONIC, &result.current) != 0) ++ { ++ struct timeval current_tv; ++ if (__gettimeofday (¤t_tv, NULL) == 0) ++ __libc_fatal ("Fatal error: gettimeofday system call failed\n"); ++ result.current.tv_sec = current_tv.tv_sec; ++ result.current.tv_nsec = current_tv.tv_usec * 1000; ++ } ++ assert (result.current.tv_sec >= 0); ++ return result; ++} ++ ++/* A special deadline value for which __deadline_is_infinite is ++ true. */ ++static inline struct deadline ++infinite_deadline (void) ++{ ++ return (struct deadline) { { -1, -1 } }; ++} ++ ++struct deadline internal_function ++__deadline_from_timeval (struct deadline_current_time current, ++ struct timeval tv) ++{ ++ assert (__is_timeval_valid_timeout (tv)); ++ ++ /* Compute second-based deadline. Perform the addition in ++ uintmax_t, which is unsigned, to simply overflow detection. */ ++ uintmax_t sec = current.current.tv_sec; ++ sec += tv.tv_sec; ++ if (sec < (uintmax_t) tv.tv_sec) ++ return infinite_deadline (); ++ ++ /* Compute nanosecond deadline. */ ++ int nsec = current.current.tv_nsec + tv.tv_usec * 1000; ++ if (nsec >= 1000 * 1000 * 1000) ++ { ++ /* Carry nanosecond overflow to seconds. */ ++ nsec -= 1000 * 1000 * 1000; ++ if (sec + 1 < sec) ++ return infinite_deadline (); ++ ++sec; ++ } ++ /* This uses a GCC extension, otherwise these casts for detecting ++ overflow would not be defined. */ ++ if ((time_t) sec < 0 || sec != (uintmax_t) (time_t) sec) ++ return infinite_deadline (); ++ ++ return (struct deadline) { { sec, nsec } }; ++} ++ ++int internal_function ++__deadline_to_ms (struct deadline_current_time current, ++ struct deadline deadline) ++{ ++ if (__deadline_is_infinite (deadline)) ++ return INT_MAX; ++ ++ if (current.current.tv_sec > deadline.absolute.tv_sec ++ || (current.current.tv_sec == deadline.absolute.tv_sec ++ && current.current.tv_nsec >= deadline.absolute.tv_nsec)) ++ return 0; ++ time_t sec = deadline.absolute.tv_sec - current.current.tv_sec; ++ if (sec >= INT_MAX) ++ /* This value will overflow below. */ ++ return INT_MAX; ++ int nsec = deadline.absolute.tv_nsec - current.current.tv_nsec; ++ if (nsec < 0) ++ { ++ /* Borrow from the seconds field. */ ++ assert (sec > 0); ++ --sec; ++ nsec += 1000 * 1000 * 1000; ++ } ++ ++ /* Prepare for rounding up to milliseconds. */ ++ nsec += 999999; ++ if (nsec > 1000 * 1000 * 1000) ++ { ++ assert (sec < INT_MAX); ++ ++sec; ++ nsec -= 1000 * 1000 * 1000; ++ } ++ ++ unsigned int msec = nsec / (1000 * 1000); ++ if (sec > INT_MAX / 1000) ++ return INT_MAX; ++ msec += sec * 1000; ++ if (msec > INT_MAX) ++ return INT_MAX; ++ return msec; ++} +Index: b/inet/tst-deadline.c +=================================================================== +--- /dev/null ++++ b/inet/tst-deadline.c +@@ -0,0 +1,188 @@ ++/* Tests for computing deadlines for timeouts. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Find the maximum value which can be represented in a time_t. */ ++static time_t ++time_t_max (void) ++{ ++ _Static_assert (0 > (time_t) -1, "time_t is signed"); ++ uintmax_t current = 1; ++ while (true) ++ { ++ uintmax_t next = current * 2; ++ /* This cannot happen because time_t is signed. */ ++ TEST_VERIFY_EXIT (next > current); ++ ++next; ++ if ((time_t) next < 0 || next != (uintmax_t) (time_t) next) ++ /* Value cannot be represented in time_t. Return the previous ++ value. */ ++ return current; ++ current = next; ++ } ++} ++ ++static int ++do_test (void) ++{ ++ { ++ struct deadline_current_time current_time = __deadline_current_time (); ++ TEST_VERIFY (current_time.current.tv_sec >= 0); ++ current_time = __deadline_current_time (); ++ /* Due to CLOCK_MONOTONIC, either seconds or nanoseconds are ++ greater than zero. This is also true for the gettimeofday ++ fallback. */ ++ TEST_VERIFY (current_time.current.tv_sec >= 0); ++ TEST_VERIFY (current_time.current.tv_sec > 0 ++ || current_time.current.tv_nsec > 0); ++ } ++ ++ /* Check basic computations of deadlines. */ ++ struct deadline_current_time current_time = { { 1, 123456789 } }; ++ struct deadline deadline = __deadline_from_timeval ++ (current_time, (struct timeval) { 0, 1 }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 123457789); ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1); ++ ++ deadline = __deadline_from_timeval ++ (current_time, ((struct timeval) { 0, 2 })); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 123458789); ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1); ++ ++ deadline = __deadline_from_timeval ++ (current_time, ((struct timeval) { 1, 0 })); ++ TEST_VERIFY (deadline.absolute.tv_sec == 2); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 123456789); ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); ++ ++ /* Check if timeouts are correctly rounded up to the next ++ millisecond. */ ++ for (int i = 0; i < 999999; ++i) ++ { ++ ++current_time.current.tv_nsec; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); ++ } ++ ++ /* A full millisecond has elapsed, so the time to the deadline is ++ now less than 1000. */ ++ ++current_time.current.tv_nsec; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999); ++ ++ /* Check __deadline_to_ms carry-over. */ ++ current_time = (struct deadline_current_time) { { 9, 123456789 } }; ++ deadline = (struct deadline) { { 10, 122456789 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999); ++ deadline = (struct deadline) { { 10, 122456790 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); ++ deadline = (struct deadline) { { 10, 123456788 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); ++ deadline = (struct deadline) { { 10, 123456789 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); ++ ++ /* Check __deadline_to_ms overflow. */ ++ deadline = (struct deadline) { { INT_MAX - 1, 1 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == INT_MAX); ++ ++ /* Check __deadline_to_ms for elapsed deadlines. */ ++ current_time = (struct deadline_current_time) { { 9, 123456789 } }; ++ deadline.absolute = current_time.current; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); ++ current_time = (struct deadline_current_time) { { 9, 123456790 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); ++ current_time = (struct deadline_current_time) { { 10, 0 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); ++ current_time = (struct deadline_current_time) { { 10, 123456788 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); ++ current_time = (struct deadline_current_time) { { 10, 123456789 } }; ++ TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); ++ ++ /* Check carry-over in __deadline_from_timeval. */ ++ current_time = (struct deadline_current_time) { { 9, 998000001 } }; ++ for (int i = 0; i < 2000; ++i) ++ { ++ deadline = __deadline_from_timeval ++ (current_time, (struct timeval) { 1, i }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 10); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 998000001 + i * 1000); ++ } ++ for (int i = 2000; i < 3000; ++i) ++ { ++ deadline = __deadline_from_timeval ++ (current_time, (struct timeval) { 2, i }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 12); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 1 + (i - 2000) * 1000); ++ } ++ ++ /* Check infinite deadlines. */ ++ deadline = __deadline_from_timeval ++ ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1000 } }, ++ (struct timeval) { time_t_max (), 1 }); ++ TEST_VERIFY (__deadline_is_infinite (deadline)); ++ deadline = __deadline_from_timeval ++ ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1001 } }, ++ (struct timeval) { time_t_max (), 1 }); ++ TEST_VERIFY (!__deadline_is_infinite (deadline)); ++ deadline = __deadline_from_timeval ++ ((struct deadline_current_time) ++ { { time_t_max (), 1000 * 1000 * 1000 - 1000 } }, ++ (struct timeval) { 0, 1 }); ++ TEST_VERIFY (__deadline_is_infinite (deadline)); ++ deadline = __deadline_from_timeval ++ ((struct deadline_current_time) ++ { { time_t_max () / 2 + 1, 0 } }, ++ (struct timeval) { time_t_max () / 2 + 1, 0 }); ++ TEST_VERIFY (__deadline_is_infinite (deadline)); ++ ++ /* Check __deadline_first behavior. */ ++ deadline = __deadline_first ++ ((struct deadline) { { 1, 2 } }, ++ (struct deadline) { { 1, 3 } }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 2); ++ deadline = __deadline_first ++ ((struct deadline) { { 1, 3 } }, ++ (struct deadline) { { 1, 2 } }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 2); ++ deadline = __deadline_first ++ ((struct deadline) { { 1, 2 } }, ++ (struct deadline) { { 2, 1 } }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 2); ++ deadline = __deadline_first ++ ((struct deadline) { { 1, 2 } }, ++ (struct deadline) { { 2, 4 } }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 2); ++ deadline = __deadline_first ++ ((struct deadline) { { 2, 4 } }, ++ (struct deadline) { { 1, 2 } }); ++ TEST_VERIFY (deadline.absolute.tv_sec == 1); ++ TEST_VERIFY (deadline.absolute.tv_nsec == 2); ++ ++ return 0; ++} ++ ++#include +Index: b/sunrpc/Makefile +=================================================================== +--- a/sunrpc/Makefile ++++ b/sunrpc/Makefile +@@ -96,11 +96,13 @@ others += rpcgen + + all: # Make this the default target; it will be defined in Rules. + +-tests = tst-xdrmem tst-xdrmem2 ++tests = tst-xdrmem tst-xdrmem2 tst-udp-timeout \ ++ tst-udp-nonblocking + xtests := tst-getmyaddr + + ifeq ($(have-thread-library),yes) + xtests += thrsvc ++tests += tst-udp-garbage + endif + + headers += $(rpcsvc:%.x=rpcsvc/%.h) +@@ -225,3 +227,8 @@ endif + endif + + $(objpfx)thrsvc: $(common-objpfx)linkobj/libc.so $(shared-thread-library) ++ ++$(objpfx)tst-udp-timeout: $(common-objpfx)linkobj/libc.so ++$(objpfx)tst-udp-nonblocking: $(common-objpfx)linkobj/libc.so ++$(objpfx)tst-udp-garbage: \ ++ $(common-objpfx)linkobj/libc.so $(shared-thread-library) +Index: b/sunrpc/clnt_udp.c +=================================================================== +--- a/sunrpc/clnt_udp.c ++++ b/sunrpc/clnt_udp.c +@@ -54,6 +54,7 @@ + #endif + + #include ++#include + + extern u_long _create_xid (void); + +@@ -79,7 +80,9 @@ static const struct clnt_ops udp_ops = + }; + + /* +- * Private data kept per client handle ++ * Private data kept per client handle. This private struct is ++ * unfortunately part of the ABI; ypbind contains a copy of it and ++ * accesses it through CLIENT::cl_private field. + */ + struct cu_data + { +@@ -309,28 +312,38 @@ clntudp_call (cl, proc, xargs, argsp, xr + int inlen; + socklen_t fromlen; + struct pollfd fd; +- int milliseconds = (cu->cu_wait.tv_sec * 1000) + +- (cu->cu_wait.tv_usec / 1000); + struct sockaddr_in from; + struct rpc_msg reply_msg; + XDR reply_xdrs; +- struct timeval time_waited; + bool_t ok; + int nrefreshes = 2; /* number of times to refresh cred */ +- struct timeval timeout; + int anyup; /* any network interface up */ + +- if (cu->cu_total.tv_usec == -1) +- { +- timeout = utimeout; /* use supplied timeout */ +- } +- else +- { +- timeout = cu->cu_total; /* use default timeout */ +- } ++ struct deadline_current_time current_time = __deadline_current_time (); ++ struct deadline total_deadline; /* Determined once by overall timeout. */ ++ struct deadline response_deadline; /* Determined anew for each query. */ ++ ++ /* Choose the timeout value. For non-sending usage (xargs == NULL), ++ the total deadline does not matter, only cu->cu_wait is used ++ below. */ ++ if (xargs != NULL) ++ { ++ struct timeval tv; ++ if (cu->cu_total.tv_usec == -1) ++ /* Use supplied timeout. */ ++ tv = utimeout; ++ else ++ /* Use default timeout. */ ++ tv = cu->cu_total; ++ if (!__is_timeval_valid_timeout (tv)) ++ return (cu->cu_error.re_status = RPC_TIMEDOUT); ++ total_deadline = __deadline_from_timeval (current_time, tv); ++ } ++ ++ /* Guard against bad timeout specification. */ ++ if (!__is_timeval_valid_timeout (cu->cu_wait)) ++ return (cu->cu_error.re_status = RPC_TIMEDOUT); + +- time_waited.tv_sec = 0; +- time_waited.tv_usec = 0; + call_again: + xdrs = &(cu->cu_outxdrs); + if (xargs == NULL) +@@ -356,27 +369,46 @@ send_again: + return (cu->cu_error.re_status = RPC_CANTSEND); + } + +- /* +- * Hack to provide rpc-based message passing +- */ +- if (timeout.tv_sec == 0 && timeout.tv_usec == 0) +- { +- return (cu->cu_error.re_status = RPC_TIMEDOUT); +- } ++ /* sendto may have blocked, so recompute the current time. */ ++ current_time = __deadline_current_time (); + get_reply: +- /* +- * sub-optimal code appears here because we have +- * some clock time to spare while the packets are in flight. +- * (We assume that this is actually only executed once.) +- */ ++ response_deadline = __deadline_from_timeval (current_time, cu->cu_wait); ++ + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = resultsp; + reply_msg.acpted_rply.ar_results.proc = xresults; + fd.fd = cu->cu_sock; + fd.events = POLLIN; + anyup = 0; ++ ++ /* Per-response retry loop. current_time must be up-to-date at the ++ top of the loop. */ + for (;;) + { ++ int milliseconds; ++ if (xargs != NULL) ++ { ++ if (__deadline_elapsed (current_time, total_deadline)) ++ /* Overall timeout expired. */ ++ return (cu->cu_error.re_status = RPC_TIMEDOUT); ++ milliseconds = __deadline_to_ms ++ (current_time, __deadline_first (total_deadline, ++ response_deadline)); ++ if (milliseconds == 0) ++ /* Per-query timeout expired. */ ++ goto send_again; ++ } ++ else ++ { ++ /* xatgs == NULL. Collect a response without sending a ++ query. In this mode, we need to ignore the total ++ deadline. */ ++ milliseconds = __deadline_to_ms (current_time, response_deadline); ++ if (milliseconds == 0) ++ /* Cannot send again, so bail out. */ ++ return (cu->cu_error.re_status = RPC_CANTSEND); ++ } ++ + switch (__poll (&fd, 1, milliseconds)) + { + +@@ -387,27 +419,10 @@ send_again: + if (!anyup) + return (cu->cu_error.re_status = RPC_CANTRECV); + } +- +- time_waited.tv_sec += cu->cu_wait.tv_sec; +- time_waited.tv_usec += cu->cu_wait.tv_usec; +- while (time_waited.tv_usec >= 1000000) +- { +- time_waited.tv_sec++; +- time_waited.tv_usec -= 1000000; +- } +- if ((time_waited.tv_sec < timeout.tv_sec) || +- ((time_waited.tv_sec == timeout.tv_sec) && +- (time_waited.tv_usec < timeout.tv_usec))) +- goto send_again; +- return (cu->cu_error.re_status = RPC_TIMEDOUT); +- +- /* +- * buggy in other cases because time_waited is not being +- * updated. +- */ ++ goto next_response; + case -1: + if (errno == EINTR) +- continue; ++ goto next_response; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } +@@ -463,20 +478,22 @@ send_again: + if (inlen < 0) + { + if (errno == EWOULDBLOCK) +- continue; ++ goto next_response; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } +- if (inlen < 4) +- continue; ++ /* Accept the response if the packet is sufficiently long and ++ the transaction ID matches the query (if available). */ ++ if (inlen >= 4 ++ && (xargs == NULL ++ || memcmp (cu->cu_inbuf, cu->cu_outbuf, ++ sizeof (u_int32_t)) == 0)) ++ break; + +- /* see if reply transaction id matches sent id. +- Don't do this if we only wait for a replay */ +- if (xargs != NULL +- && memcmp (cu->cu_inbuf, cu->cu_outbuf, sizeof (u_int32_t)) != 0) +- continue; +- /* we now assume we have the proper reply */ +- break; ++ next_response: ++ /* Update the current time because poll and recvmsg waited for ++ an unknown time. */ ++ current_time = __deadline_current_time (); + } + + /* +Index: b/sunrpc/tst-udp-garbage.c +=================================================================== +--- /dev/null ++++ b/sunrpc/tst-udp-garbage.c +@@ -0,0 +1,104 @@ ++/* Test that garbage packets do not affect timeout handling. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Descriptor for the server UDP socket. */ ++static int server_fd; ++ ++static void * ++garbage_sender_thread (void *unused) ++{ ++ while (true) ++ { ++ struct sockaddr_storage sa; ++ socklen_t salen = sizeof (sa); ++ char buf[1]; ++ if (recvfrom (server_fd, buf, sizeof (buf), 0, ++ (struct sockaddr *) &sa, &salen) < 0) ++ FAIL_EXIT1 ("recvfrom: %m"); ++ ++ /* Send garbage packets indefinitely. */ ++ buf[0] = 0; ++ while (true) ++ { ++ /* sendto can fail if the client closed the socket. */ ++ if (sendto (server_fd, buf, sizeof (buf), 0, ++ (struct sockaddr *) &sa, salen) < 0) ++ break; ++ ++ /* Wait a bit, to avoid burning too many CPU cycles in a ++ tight loop. The wait period must be much shorter than ++ the client timeouts configured below. */ ++ usleep (50 * 1000); ++ } ++ } ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ support_enter_network_namespace (); ++ ++ server_fd = xsocket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); ++ struct sockaddr_in server_address = ++ { ++ .sin_family = AF_INET, ++ .sin_addr.s_addr = htonl (INADDR_LOOPBACK), ++ }; ++ xbind (server_fd, ++ (struct sockaddr *) &server_address, sizeof (server_address)); ++ { ++ socklen_t sinlen = sizeof (server_address); ++ xgetsockname (server_fd, (struct sockaddr *) &server_address, &sinlen); ++ TEST_VERIFY (sizeof (server_address) == sinlen); ++ } ++ ++ /* Garbage packet source. */ ++ xpthread_detach (xpthread_create (NULL, garbage_sender_thread, NULL)); ++ ++ /* Test client. Use an arbitrary timeout of one second, which is ++ much longer than the garbage packet interval, but still ++ reasonably short, so that the test completes quickly. */ ++ int client_fd = RPC_ANYSOCK; ++ CLIENT *clnt = clntudp_create (&server_address, ++ 1, 2, /* Arbitrary RPC endpoint numbers. */ ++ (struct timeval) { 1, 0 }, ++ &client_fd); ++ if (clnt == NULL) ++ FAIL_EXIT1 ("clntudp_create: %m"); ++ ++ TEST_VERIFY (clnt_call (clnt, 3, /* Arbitrary RPC procedure number. */ ++ (xdrproc_t) xdr_void, NULL, ++ (xdrproc_t) xdr_void, NULL, ++ ((struct timeval) { 1, 0 }))); ++ ++ return 0; ++} ++ ++#include +Index: b/sunrpc/tst-udp-nonblocking.c +=================================================================== +--- /dev/null ++++ b/sunrpc/tst-udp-nonblocking.c +@@ -0,0 +1,333 @@ ++/* Test non-blocking use of the UDP client. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Test data serialization and deserialization. */ ++ ++struct test_query ++{ ++ uint32_t a; ++ uint32_t b; ++ uint32_t timeout_ms; ++}; ++ ++static bool_t ++xdr_test_query (XDR *xdrs, void *data, ...) ++{ ++ struct test_query *p = data; ++ return xdr_uint32_t (xdrs, &p->a) ++ && xdr_uint32_t (xdrs, &p->b) ++ && xdr_uint32_t (xdrs, &p->timeout_ms); ++} ++ ++struct test_response ++{ ++ uint32_t server_id; ++ uint32_t seq; ++ uint32_t sum; ++}; ++ ++static bool_t ++xdr_test_response (XDR *xdrs, void *data, ...) ++{ ++ struct test_response *p = data; ++ return xdr_uint32_t (xdrs, &p->server_id) ++ && xdr_uint32_t (xdrs, &p->seq) ++ && xdr_uint32_t (xdrs, &p->sum); ++} ++ ++/* Implementation of the test server. */ ++ ++enum ++ { ++ /* Number of test servers to run. */ ++ SERVER_COUNT = 3, ++ ++ /* RPC parameters, chosen at random. */ ++ PROGNUM = 8242, ++ VERSNUM = 19654, ++ ++ /* Main RPC operation. */ ++ PROC_ADD = 1, ++ ++ /* Request process termination. */ ++ PROC_EXIT, ++ ++ /* Special exit status to mark successful processing. */ ++ EXIT_MARKER = 55, ++ }; ++ ++/* Set by the parent process to tell test servers apart. */ ++static int server_id; ++ ++/* Implementation of the test server. */ ++static void ++server_dispatch (struct svc_req *request, SVCXPRT *transport) ++{ ++ /* Query sequence number. */ ++ static uint32_t seq = 0; ++ ++seq; ++ static bool proc_add_seen; ++ ++ if (test_verbose) ++ printf ("info: server_dispatch server_id=%d seq=%u rq_proc=%lu\n", ++ server_id, seq, request->rq_proc); ++ ++ switch (request->rq_proc) ++ { ++ case PROC_ADD: ++ { ++ struct test_query query; ++ memset (&query, 0xc0, sizeof (query)); ++ TEST_VERIFY_EXIT ++ (svc_getargs (transport, xdr_test_query, ++ (void *) &query)); ++ ++ if (test_verbose) ++ printf (" a=%u b=%u timeout_ms=%u\n", ++ query.a, query.b, query.timeout_ms); ++ ++ usleep (query.timeout_ms * 1000); ++ ++ struct test_response response = ++ { ++ .server_id = server_id, ++ .seq = seq, ++ .sum = query.a + query.b, ++ }; ++ TEST_VERIFY (svc_sendreply (transport, xdr_test_response, ++ (void *) &response)); ++ if (test_verbose) ++ printf (" server id %d response seq=%u sent\n", server_id, seq); ++ proc_add_seen = true; ++ } ++ break; ++ ++ case PROC_EXIT: ++ TEST_VERIFY (proc_add_seen); ++ TEST_VERIFY (svc_sendreply (transport, (xdrproc_t) xdr_void, NULL)); ++ _exit (EXIT_MARKER); ++ break; ++ ++ default: ++ FAIL_EXIT1 ("invalid rq_proc value: %lu", request->rq_proc); ++ break; ++ } ++} ++ ++/* Return the number seconds since an arbitrary point in time. */ ++static double ++get_ticks (void) ++{ ++ { ++ struct timespec ts; ++ if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0) ++ return ts.tv_sec + ts.tv_nsec * 1e-9; ++ } ++ { ++ struct timeval tv; ++ TEST_VERIFY_EXIT (gettimeofday (&tv, NULL) == 0); ++ return tv.tv_sec + tv.tv_usec * 1e-6; ++ } ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ support_enter_network_namespace (); ++ ++ /* Information about the test servers. */ ++ struct ++ { ++ SVCXPRT *transport; ++ struct sockaddr_in address; ++ pid_t pid; ++ uint32_t xid; ++ } servers[SERVER_COUNT]; ++ ++ /* Spawn the test servers. */ ++ for (int i = 0; i < SERVER_COUNT; ++i) ++ { ++ servers[i].transport = svcudp_create (RPC_ANYSOCK); ++ TEST_VERIFY_EXIT (servers[i].transport != NULL); ++ servers[i].address = (struct sockaddr_in) ++ { ++ .sin_family = AF_INET, ++ .sin_addr.s_addr = htonl (INADDR_LOOPBACK), ++ .sin_port = htons (servers[i].transport->xp_port), ++ }; ++ servers[i].xid = 0xabcd0101 + i; ++ if (test_verbose) ++ printf ("info: setting up server %d xid=%x on port %d\n", ++ i, servers[i].xid, servers[i].transport->xp_port); ++ ++ server_id = i; ++ servers[i].pid = xfork (); ++ if (servers[i].pid == 0) ++ { ++ TEST_VERIFY (svc_register (servers[i].transport, ++ PROGNUM, VERSNUM, server_dispatch, 0)); ++ svc_run (); ++ FAIL_EXIT1 ("supposed to be unreachable"); ++ } ++ /* We need to close the socket so that we do not accidentally ++ consume the request. */ ++ TEST_VERIFY (close (servers[i].transport->xp_sock) == 0); ++ } ++ ++ ++ /* The following code mirrors what ypbind does. */ ++ ++ /* Copied from clnt_udp.c (like ypbind). */ ++ struct cu_data ++ { ++ int cu_sock; ++ bool_t cu_closeit; ++ struct sockaddr_in cu_raddr; ++ int cu_rlen; ++ struct timeval cu_wait; ++ struct timeval cu_total; ++ struct rpc_err cu_error; ++ XDR cu_outxdrs; ++ u_int cu_xdrpos; ++ u_int cu_sendsz; ++ char *cu_outbuf; ++ u_int cu_recvsz; ++ char cu_inbuf[1]; ++ }; ++ ++ int client_socket = xsocket (AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0); ++ CLIENT *clnt = clntudp_create (&servers[0].address, PROGNUM, VERSNUM, ++ /* 5 seconds per-response timeout. */ ++ ((struct timeval) { 5, 0 }), ++ &client_socket); ++ TEST_VERIFY (clnt != NULL); ++ clnt->cl_auth = authunix_create_default (); ++ { ++ struct timeval zero = { 0, 0 }; ++ TEST_VERIFY (clnt_control (clnt, CLSET_TIMEOUT, (void *) &zero)); ++ } ++ ++ /* Poke at internal data structures (like ypbind). */ ++ struct cu_data *cu = (struct cu_data *) clnt->cl_private; ++ ++ /* Send a ping to each server. */ ++ double before_pings = get_ticks (); ++ for (int i = 0; i < SERVER_COUNT; ++i) ++ { ++ if (test_verbose) ++ printf ("info: sending server %d ping\n", i); ++ /* Reset the xid because it is changed by each invocation of ++ clnt_call. Subtract one to compensate for the xid update ++ during the call. */ ++ *((u_int32_t *) (cu->cu_outbuf)) = servers[i].xid - 1; ++ cu->cu_raddr = servers[i].address; ++ ++ struct test_query query = { .a = 100, .b = i + 1 }; ++ if (i == 1) ++ /* Shorter timeout to prefer this server. These timeouts must ++ be much shorter than the 5-second per-response timeout ++ configured with clntudp_create. */ ++ query.timeout_ms = 700; ++ else ++ query.timeout_ms = 1400; ++ struct test_response response = { 0 }; ++ /* NB: Do not check the return value. The server reply will ++ prove that the call worked. */ ++ double before_one_ping = get_ticks (); ++ clnt_call (clnt, PROC_ADD, ++ xdr_test_query, (void *) &query, ++ xdr_test_response, (void *) &response, ++ ((struct timeval) { 0, 0 })); ++ double after_one_ping = get_ticks (); ++ if (test_verbose) ++ printf ("info: non-blocking send took %f seconds\n", ++ after_one_ping - before_one_ping); ++ /* clnt_call should return immediately. Accept some delay in ++ case the process is descheduled. */ ++ TEST_VERIFY (after_one_ping - before_one_ping < 0.3); ++ } ++ ++ /* Collect the non-blocking response. */ ++ if (test_verbose) ++ printf ("info: collecting response\n"); ++ struct test_response response = { 0 }; ++ TEST_VERIFY ++ (clnt_call (clnt, PROC_ADD, NULL, NULL, ++ xdr_test_response, (void *) &response, ++ ((struct timeval) { 0, 0 })) == RPC_SUCCESS); ++ double after_pings = get_ticks (); ++ if (test_verbose) ++ printf ("info: send/receive took %f seconds\n", ++ after_pings - before_pings); ++ /* Expected timeout is 0.7 seconds. */ ++ TEST_VERIFY (0.7 <= after_pings - before_pings); ++ TEST_VERIFY (after_pings - before_pings < 1.2); ++ ++ uint32_t xid; ++ memcpy (&xid, &cu->cu_inbuf, sizeof (xid)); ++ if (test_verbose) ++ printf ("info: non-blocking response: xid=%x server_id=%u seq=%u sum=%u\n", ++ xid, response.server_id, response.seq, response.sum); ++ /* Check that the reply from the preferred server was used. */ ++ TEST_VERIFY (servers[1].xid == xid); ++ TEST_VERIFY (response.server_id == 1); ++ TEST_VERIFY (response.seq == 1); ++ TEST_VERIFY (response.sum == 102); ++ ++ auth_destroy (clnt->cl_auth); ++ clnt_destroy (clnt); ++ ++ for (int i = 0; i < SERVER_COUNT; ++i) ++ { ++ if (test_verbose) ++ printf ("info: requesting server %d termination\n", i); ++ client_socket = RPC_ANYSOCK; ++ clnt = clntudp_create (&servers[i].address, PROGNUM, VERSNUM, ++ ((struct timeval) { 5, 0 }), ++ &client_socket); ++ TEST_VERIFY_EXIT (clnt != NULL); ++ TEST_VERIFY (clnt_call (clnt, PROC_EXIT, ++ (xdrproc_t) xdr_void, NULL, ++ (xdrproc_t) xdr_void, NULL, ++ ((struct timeval) { 3, 0 })) == RPC_SUCCESS); ++ clnt_destroy (clnt); ++ ++ int status; ++ xwaitpid (servers[i].pid, &status, 0); ++ TEST_VERIFY (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_MARKER); ++ } ++ ++ return 0; ++} ++ ++#include +Index: b/sunrpc/tst-udp-timeout.c +=================================================================== +--- /dev/null ++++ b/sunrpc/tst-udp-timeout.c +@@ -0,0 +1,402 @@ ++/* Test timeout handling in the UDP client. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Test data serialization and deserialization. */ ++ ++struct test_query ++{ ++ uint32_t a; ++ uint32_t b; ++ uint32_t timeout_ms; ++ uint32_t wait_for_seq; ++ uint32_t garbage_packets; ++}; ++ ++static bool_t ++xdr_test_query (XDR *xdrs, void *data, ...) ++{ ++ struct test_query *p = data; ++ return xdr_uint32_t (xdrs, &p->a) ++ && xdr_uint32_t (xdrs, &p->b) ++ && xdr_uint32_t (xdrs, &p->timeout_ms) ++ && xdr_uint32_t (xdrs, &p->wait_for_seq) ++ && xdr_uint32_t (xdrs, &p->garbage_packets); ++} ++ ++struct test_response ++{ ++ uint32_t seq; ++ uint32_t sum; ++}; ++ ++static bool_t ++xdr_test_response (XDR *xdrs, void *data, ...) ++{ ++ struct test_response *p = data; ++ return xdr_uint32_t (xdrs, &p->seq) ++ && xdr_uint32_t (xdrs, &p->sum); ++} ++ ++/* Implementation of the test server. */ ++ ++enum ++ { ++ /* RPC parameters, chosen at random. */ ++ PROGNUM = 15717, ++ VERSNUM = 13689, ++ ++ /* Main RPC operation. */ ++ PROC_ADD = 1, ++ ++ /* Reset the sequence number. */ ++ PROC_RESET_SEQ, ++ ++ /* Request process termination. */ ++ PROC_EXIT, ++ ++ /* Special exit status to mark successful processing. */ ++ EXIT_MARKER = 55, ++ }; ++ ++static void ++server_dispatch (struct svc_req *request, SVCXPRT *transport) ++{ ++ /* Query sequence number. */ ++ static uint32_t seq = 0; ++ ++seq; ++ ++ if (test_verbose) ++ printf ("info: server_dispatch seq=%u rq_proc=%lu\n", ++ seq, request->rq_proc); ++ ++ switch (request->rq_proc) ++ { ++ case PROC_ADD: ++ { ++ struct test_query query; ++ memset (&query, 0xc0, sizeof (query)); ++ TEST_VERIFY_EXIT ++ (svc_getargs (transport, xdr_test_query, ++ (void *) &query)); ++ ++ if (test_verbose) ++ printf (" a=%u b=%u timeout_ms=%u wait_for_seq=%u" ++ " garbage_packets=%u\n", ++ query.a, query.b, query.timeout_ms, query.wait_for_seq, ++ query.garbage_packets); ++ ++ if (seq < query.wait_for_seq) ++ { ++ /* No response at this point. */ ++ if (test_verbose) ++ printf (" skipped response\n"); ++ break; ++ } ++ ++ if (query.garbage_packets > 0) ++ { ++ int per_packet_timeout; ++ if (query.timeout_ms > 0) ++ per_packet_timeout ++ = query.timeout_ms * 1000 / query.garbage_packets; ++ else ++ per_packet_timeout = 0; ++ ++ char buf[20]; ++ memset (&buf, 0xc0, sizeof (buf)); ++ for (int i = 0; i < query.garbage_packets; ++i) ++ { ++ /* 13 is relatively prime to 20 = sizeof (buf) + 1, so ++ the len variable will cover the entire interval ++ [0, 20] if query.garbage_packets is sufficiently ++ large. */ ++ size_t len = (i * 13 + 1) % (sizeof (buf) + 1); ++ TEST_VERIFY (sendto (transport->xp_sock, ++ buf, len, MSG_NOSIGNAL, ++ (struct sockaddr *) &transport->xp_raddr, ++ transport->xp_addrlen) == len); ++ if (per_packet_timeout > 0) ++ usleep (per_packet_timeout); ++ } ++ } ++ else if (query.timeout_ms > 0) ++ usleep (query.timeout_ms * 1000); ++ ++ struct test_response response = ++ { ++ .seq = seq, ++ .sum = query.a + query.b, ++ }; ++ TEST_VERIFY (svc_sendreply (transport, xdr_test_response, ++ (void *) &response)); ++ } ++ break; ++ ++ case PROC_RESET_SEQ: ++ seq = 0; ++ TEST_VERIFY (svc_sendreply (transport, (xdrproc_t) xdr_void, NULL)); ++ break; ++ ++ case PROC_EXIT: ++ TEST_VERIFY (svc_sendreply (transport, (xdrproc_t) xdr_void, NULL)); ++ _exit (EXIT_MARKER); ++ break; ++ ++ default: ++ FAIL_EXIT1 ("invalid rq_proc value: %lu", request->rq_proc); ++ break; ++ } ++} ++ ++/* Implementation of the test client. */ ++ ++static struct test_response ++test_call (CLIENT *clnt, int proc, struct test_query query, ++ struct timeval timeout) ++{ ++ if (test_verbose) ++ printf ("info: test_call proc=%d timeout=%lu.%06lu\n", ++ proc, (unsigned long) timeout.tv_sec, ++ (unsigned long) timeout.tv_usec); ++ struct test_response response; ++ TEST_VERIFY_EXIT (clnt_call (clnt, proc, ++ xdr_test_query, (void *) &query, ++ xdr_test_response, (void *) &response, ++ timeout) ++ == RPC_SUCCESS); ++ return response; ++} ++ ++static void ++test_call_timeout (CLIENT *clnt, int proc, struct test_query query, ++ struct timeval timeout) ++{ ++ struct test_response response; ++ TEST_VERIFY (clnt_call (clnt, proc, ++ xdr_test_query, (void *) &query, ++ xdr_test_response, (void *) &response, ++ timeout) ++ == RPC_TIMEDOUT); ++} ++ ++/* Complete one regular RPC call to drain the server socket ++ buffer. Resets the sequence number. */ ++static void ++test_call_flush (CLIENT *clnt) ++{ ++ /* This needs a longer timeout to flush out all pending requests. ++ The choice of 5 seconds is larger than the per-response timeouts ++ requested via the timeout_ms field. */ ++ if (test_verbose) ++ printf ("info: flushing pending queries\n"); ++ TEST_VERIFY_EXIT (clnt_call (clnt, PROC_RESET_SEQ, ++ (xdrproc_t) xdr_void, NULL, ++ (xdrproc_t) xdr_void, NULL, ++ ((struct timeval) { 5, 0 })) ++ == RPC_SUCCESS); ++} ++ ++/* Return the number seconds since an arbitrary point in time. */ ++static double ++get_ticks (void) ++{ ++ { ++ struct timespec ts; ++ if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0) ++ return ts.tv_sec + ts.tv_nsec * 1e-9; ++ } ++ { ++ struct timeval tv; ++ TEST_VERIFY_EXIT (gettimeofday (&tv, NULL) == 0); ++ return tv.tv_sec + tv.tv_usec * 1e-6; ++ } ++} ++ ++static void ++test_udp_server (int port) ++{ ++ struct sockaddr_in sin = ++ { ++ .sin_family = AF_INET, ++ .sin_addr.s_addr = htonl (INADDR_LOOPBACK), ++ .sin_port = htons (port) ++ }; ++ int sock = RPC_ANYSOCK; ++ ++ /* The client uses a 1.5 second timeout for retries. The timeouts ++ are arbitrary, but chosen so that there is a substantial gap ++ between them, but the total time spent waiting is not too ++ large. */ ++ CLIENT *clnt = clntudp_create (&sin, PROGNUM, VERSNUM, ++ (struct timeval) { 1, 500 * 1000 }, ++ &sock); ++ TEST_VERIFY_EXIT (clnt != NULL); ++ ++ /* Basic call/response test. */ ++ struct test_response response = test_call ++ (clnt, PROC_ADD, ++ (struct test_query) { .a = 17, .b = 4 }, ++ (struct timeval) { 3, 0 }); ++ TEST_VERIFY (response.sum == 21); ++ TEST_VERIFY (response.seq == 1); ++ ++ /* Check that garbage packets do not interfere with timeout ++ processing. */ ++ double before = get_ticks (); ++ response = test_call ++ (clnt, PROC_ADD, ++ (struct test_query) { ++ .a = 19, .b = 4, .timeout_ms = 500, .garbage_packets = 21, ++ }, ++ (struct timeval) { 3, 0 }); ++ TEST_VERIFY (response.sum == 23); ++ TEST_VERIFY (response.seq == 2); ++ double after = get_ticks (); ++ if (test_verbose) ++ printf ("info: 21 garbage packets took %f seconds\n", after - before); ++ /* Expected timeout is 0.5 seconds. Add some slack in case process ++ scheduling delays processing the query or response, but do not ++ accept a retry (which would happen at 1.5 seconds). */ ++ TEST_VERIFY (0.5 <= after - before); ++ TEST_VERIFY (after - before < 1.2); ++ test_call_flush (clnt); ++ ++ /* Check that missing a response introduces a 1.5 second timeout, as ++ requested when calling clntudp_create. */ ++ before = get_ticks (); ++ response = test_call ++ (clnt, PROC_ADD, ++ (struct test_query) { .a = 170, .b = 40, .wait_for_seq = 2 }, ++ (struct timeval) { 3, 0 }); ++ TEST_VERIFY (response.sum == 210); ++ TEST_VERIFY (response.seq == 2); ++ after = get_ticks (); ++ if (test_verbose) ++ printf ("info: skipping one response took %f seconds\n", ++ after - before); ++ /* Expected timeout is 1.5 seconds. Do not accept a second retry ++ (which would happen at 3 seconds). */ ++ TEST_VERIFY (1.5 <= after - before); ++ TEST_VERIFY (after - before < 2.9); ++ test_call_flush (clnt); ++ ++ /* Check that the overall timeout wins against the per-query ++ timeout. */ ++ before = get_ticks (); ++ test_call_timeout ++ (clnt, PROC_ADD, ++ (struct test_query) { .a = 170, .b = 41, .wait_for_seq = 2 }, ++ (struct timeval) { 0, 750 * 1000 }); ++ after = get_ticks (); ++ if (test_verbose) ++ printf ("info: 0.75 second timeout took %f seconds\n", ++ after - before); ++ TEST_VERIFY (0.75 <= after - before); ++ TEST_VERIFY (after - before < 1.4); ++ test_call_flush (clnt); ++ ++ for (int with_garbage = 0; with_garbage < 2; ++with_garbage) ++ { ++ /* Check that no response at all causes the client to bail out. */ ++ before = get_ticks (); ++ test_call_timeout ++ (clnt, PROC_ADD, ++ (struct test_query) { ++ .a = 170, .b = 40, .timeout_ms = 1200, ++ .garbage_packets = with_garbage * 21 ++ }, ++ (struct timeval) { 0, 750 * 1000 }); ++ after = get_ticks (); ++ if (test_verbose) ++ printf ("info: test_udp_server: 0.75 second timeout took %f seconds" ++ " (garbage %d)\n", ++ after - before, with_garbage); ++ TEST_VERIFY (0.75 <= after - before); ++ TEST_VERIFY (after - before < 1.4); ++ test_call_flush (clnt); ++ ++ /* As above, but check the total timeout. */ ++ before = get_ticks (); ++ test_call_timeout ++ (clnt, PROC_ADD, ++ (struct test_query) { ++ .a = 170, .b = 40, .timeout_ms = 3000, ++ .garbage_packets = with_garbage * 30 ++ }, ++ (struct timeval) { 2, 300 * 1000 }); ++ after = get_ticks (); ++ if (test_verbose) ++ printf ("info: test_udp_server: 2.3 second timeout took %f seconds" ++ " (garbage %d)\n", ++ after - before, with_garbage); ++ TEST_VERIFY (2.3 <= after - before); ++ TEST_VERIFY (after - before < 3.0); ++ test_call_flush (clnt); ++ } ++ ++ TEST_VERIFY_EXIT (clnt_call (clnt, PROC_EXIT, ++ (xdrproc_t) xdr_void, NULL, ++ (xdrproc_t) xdr_void, NULL, ++ ((struct timeval) { 5, 0 })) ++ == RPC_SUCCESS); ++ clnt_destroy (clnt); ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ support_enter_network_namespace (); ++ ++ SVCXPRT *transport = svcudp_create (RPC_ANYSOCK); ++ TEST_VERIFY_EXIT (transport != NULL); ++ TEST_VERIFY (svc_register (transport, PROGNUM, VERSNUM, server_dispatch, 0)); ++ ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ svc_run (); ++ FAIL_EXIT1 ("supposed to be unreachable"); ++ } ++ test_udp_server (transport->xp_port); ++ ++ int status; ++ xwaitpid (pid, &status, 0); ++ TEST_VERIFY (WIFEXITED (status) && WEXITSTATUS (status) == EXIT_MARKER); ++ ++ SVC_DESTROY (transport); ++ return 0; ++} ++ ++/* The minimum run time is around 17 seconds. */ ++#define TIMEOUT 25 ++#include +Index: b/inet/net-internal.h +=================================================================== +--- /dev/null ++++ b/inet/net-internal.h +@@ -0,0 +1,112 @@ ++/* Network-related functions for internal library use. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _NET_INTERNAL_H ++#define _NET_INTERNAL_H 1 ++ ++#include ++#include ++#include ++ ++/* Deadline handling for enforcing timeouts. ++ ++ Code should call __deadline_current_time to obtain the current time ++ and cache it locally. The cache needs updating after every ++ long-running or potentially blocking operation. Deadlines relative ++ to the current time can be computed using __deadline_from_timeval. ++ The deadlines may have to be recomputed in response to certain ++ events (such as an incoming packet), but they are absolute (not ++ relative to the current time). A timeout suitable for use with the ++ poll function can be computed from such a deadline using ++ __deadline_to_ms. ++ ++ The fields in the structs defined belowed should only be used ++ within the implementation. */ ++ ++/* Cache of the current time. Used to compute deadlines from relative ++ timeouts and vice versa. */ ++struct deadline_current_time ++{ ++ struct timespec current; ++}; ++ ++/* Return the current time. Terminates the process if the current ++ time is not available. */ ++struct deadline_current_time __deadline_current_time (void) ++ internal_function attribute_hidden; ++ ++/* Computed absolute deadline. */ ++struct deadline ++{ ++ struct timespec absolute; ++}; ++ ++ ++/* For internal use only. */ ++static inline bool ++__deadline_is_infinite (struct deadline deadline) ++{ ++ return deadline.absolute.tv_nsec < 0; ++} ++ ++/* Return true if the current time is at the deadline or past it. */ ++static inline bool ++__deadline_elapsed (struct deadline_current_time current, ++ struct deadline deadline) ++{ ++ return !__deadline_is_infinite (deadline) ++ && (current.current.tv_sec > deadline.absolute.tv_sec ++ || (current.current.tv_sec == deadline.absolute.tv_sec ++ && current.current.tv_nsec >= deadline.absolute.tv_nsec)); ++} ++ ++/* Return the deadline which occurs first. */ ++static inline struct deadline ++__deadline_first (struct deadline left, struct deadline right) ++{ ++ if (__deadline_is_infinite (right) ++ || left.absolute.tv_sec < right.absolute.tv_sec ++ || (left.absolute.tv_sec == right.absolute.tv_sec ++ && left.absolute.tv_nsec < right.absolute.tv_nsec)) ++ return left; ++ else ++ return right; ++} ++ ++/* Add TV to the current time and return it. Returns a special ++ infinite absolute deadline on overflow. */ ++struct deadline __deadline_from_timeval (struct deadline_current_time, ++ struct timeval tv) ++ internal_function attribute_hidden; ++ ++/* Compute the number of milliseconds until the specified deadline, ++ from the current time in the argument. The result is mainly for ++ use with poll. If the deadline has already passed, return 0. If ++ the result would overflow an int, return INT_MAX. */ ++int __deadline_to_ms (struct deadline_current_time, struct deadline) ++ internal_function attribute_hidden; ++ ++/* Return true if TV.tv_sec is non-negative and TV.tv_usec is in the ++ interval [0, 999999]. */ ++static inline bool ++__is_timeval_valid_timeout (struct timeval tv) ++{ ++ return tv.tv_sec >= 0 && tv.tv_usec >= 0 && tv.tv_usec < 1000 * 1000; ++} ++ ++#endif /* _NET_INTERNAL_H */ +Index: b/inet/Makefile +=================================================================== +--- a/inet/Makefile ++++ b/inet/Makefile +@@ -44,13 +44,18 @@ routines := htonl htons \ + getaliasent_r getaliasent getaliasname getaliasname_r \ + in6_addr getnameinfo if_index ifaddrs inet6_option \ + getipv4sourcefilter setipv4sourcefilter \ +- getsourcefilter setsourcefilter inet6_opt inet6_rth ++ getsourcefilter setsourcefilter inet6_opt inet6_rth \ ++ deadline + + aux := check_pf check_native ifreq + + tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ + tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ +- tst-getni1 tst-getni2 tst-inet6_rth tst-checks ++ tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-deadline ++ ++# tst-deadline must be linked statically so that we can access ++# internal functions. ++tests-static += tst-deadline + + include ../Rules diff --git a/SOURCES/glibc-rh1234449-1.patch b/SOURCES/glibc-rh1234449-1.patch new file mode 100644 index 00000000..cf2348ec --- /dev/null +++ b/SOURCES/glibc-rh1234449-1.patch @@ -0,0 +1,73 @@ +commit 45c30c61c9001867c1891f5862764f084e53f348 +Author: OndÅ™ej Bílka +Date: Sun Oct 20 08:25:25 2013 +0200 + + Replace alloca in __tzfile_read by malloc. Fixes bug 15670 + +diff --git a/time/tzfile.c b/time/tzfile.c +index 9dd5130..3ea3051 100644 +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -114,6 +114,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + int was_using_tzfile = __use_tzfile; + int trans_width = 4; + size_t tzspec_len; ++ char *new = NULL; + + if (sizeof (time_t) != 4 && sizeof (time_t) != 8) + abort (); +@@ -145,22 +146,12 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + if (*file != '/') + { + const char *tzdir; +- unsigned int len, tzdir_len; +- char *new, *tmp; + + tzdir = getenv ("TZDIR"); + if (tzdir == NULL || *tzdir == '\0') +- { +- tzdir = default_tzdir; +- tzdir_len = sizeof (default_tzdir) - 1; +- } +- else +- tzdir_len = strlen (tzdir); +- len = strlen (file) + 1; +- new = (char *) __alloca (tzdir_len + 1 + len); +- tmp = __mempcpy (new, tzdir, tzdir_len); +- *tmp++ = '/'; +- memcpy (tmp, file, len); ++ tzdir = default_tzdir; ++ if (__asprintf (&new, "%s/%s", tzdir, file) == -1) ++ goto ret_free_transitions; + file = new; + } + +@@ -170,11 +161,7 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + && stat64 (file, &st) == 0 + && tzfile_ino == st.st_ino && tzfile_dev == st.st_dev + && tzfile_mtime == st.st_mtime) +- { +- /* Nothing to do. */ +- __use_tzfile = 1; +- return; +- } ++ goto done; /* Nothing to do. */ + + /* Note the file is opened with cancellation in the I/O functions + disabled and if available FD_CLOEXEC set. */ +@@ -527,12 +514,15 @@ __tzfile_read (const char *file, size_t extra, char **extrap) + __daylight = rule_stdoff != rule_dstoff; + __timezone = -rule_stdoff; + ++ done: + __use_tzfile = 1; ++ free (new); + return; + + lose: + fclose (f); + ret_free_transitions: ++ free (new); + free ((void *) transitions); + transitions = NULL; + } diff --git a/SOURCES/glibc-rh1234449-2.patch b/SOURCES/glibc-rh1234449-2.patch new file mode 100644 index 00000000..97415815 --- /dev/null +++ b/SOURCES/glibc-rh1234449-2.patch @@ -0,0 +1,940 @@ +commit 42261ad731991df345880b0b509d83b0b9a9b9d8 +Author: Florian Weimer +Date: Fri Apr 24 17:34:47 2015 +0200 + + Make time zone file parser more robust [BZ #17715] + +commit 6807b1db8233ed84671f061b5d825622233df303 +Author: Kevin Easton +Date: Tue Feb 24 23:57:07 2015 -0500 + + Reduce lock contention in __tz_convert() [BZ #16145] (partial fix) + +commit 9d46370ca338054cb6ea7ebeddcf06c7ac7ad1a9 +Author: Joseph Myers +Date: Fri Oct 16 20:21:49 2015 +0000 + + Convert 703 function definitions to prototype style. + (A subset of these changes (tzset.c) were applied as part of this patch.) + +commit 0748546f660d27a2ad29fa6174d456e2f6490758 +Author: Paul Eggert +Date: Wed Sep 18 13:15:12 2013 -0700 + + Support TZ transition times < 00:00:00. + + This is needed for version-3 tz-format files; it supports time + stamps past 2037 for America/Godthab (the only entry in the tz + database for which this change is relevant). + * manual/time.texi (TZ Variable): Document transition times + from -167:59:59 through -00:00:01. + * time/tzset.c (tz_rule): Time of day is now signed. + (__tzset_parse_tz): Parse negative time of day. + (A subset of these changes were applied as part of this patch.) + +commit 3cc652e951c71785032019fec82e3b8543d85305 +Author: Mike Frysinger +Date: Fri Sep 18 13:49:08 2015 -0400 + + timezone: fix parallel check failures + + The XT testdata install rules expect the testdata dir to already exist in + the build tree, but it doesn't actually create it. Instead, it relies on + the build-testdata define happening to be executed before it (which runs + zic which creates the dir). When we run in parallel though, it's easy to + hit a failure: + $ cd timezone + $ rm -rf $objdir/timezone/testdata + $ make check -j + ... + cp testdata/XT1 .../timezone/testdata/XT1 + cp: cannot create regular file '.../timezone/testdata/XT1': No such file or directory + Makefile:116: recipe for target '.../timezone/testdata/XT1' failed + make: *** [.../timezone/testdata/XT1] Error 1 + make: *** Waiting for unfinished jobs.... + +diff --git a/time/tzfile.c b/time/tzfile.c +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -213,6 +213,9 @@ + num_isstd = (size_t) decode (tzhead.tzh_ttisstdcnt); + num_isgmt = (size_t) decode (tzhead.tzh_ttisgmtcnt); + ++ if (__glibc_unlikely (num_isstd > num_types || num_isgmt > num_types)) ++ goto lose; ++ + /* For platforms with 64-bit time_t we use the new format if available. */ + if (sizeof (time_t) == 8 && trans_width == 4 + && tzhead.tzh_version[0] != '\0') +@@ -445,12 +448,20 @@ + goto lose; + + tzspec_len = st.st_size - off - 1; +- char *tzstr = alloca (tzspec_len); ++ if (tzspec_len == 0) ++ goto lose; ++ char *tzstr = malloc (tzspec_len); ++ if (tzstr == NULL) ++ goto lose; + if (getc_unlocked (f) != '\n' + || (fread_unlocked (tzstr, 1, tzspec_len - 1, f) != tzspec_len - 1)) +- goto lose; ++ { ++ free (tzstr); ++ goto lose; ++ } + tzstr[tzspec_len - 1] = '\0'; + tzspec = __tzstring (tzstr); ++ free (tzstr); + } + + /* Don't use an empty TZ string. */ + +diff --git a/time/tzset.c b/time/tzset.c +--- a/time/tzset.c ++++ b/time/tzset.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1991-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1991-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -54,7 +55,7 @@ + /* When to change. */ + enum { J0, J1, M } type; /* Interpretation of: */ + unsigned short int m, n, d; /* Month, week, day. */ +- unsigned int secs; /* Time of day. */ ++ int secs; /* Time of day. */ + + long int offset; /* Seconds east of GMT (west if < 0). */ + +@@ -82,15 +83,14 @@ + + static struct tzstring_l *tzstring_list; + +-/* Allocate a permanent home for S. It will never be moved or deallocated, +- but may share space with other strings. +- Don't modify the returned string. */ +-char * +-__tzstring (const char *s) ++/* Allocate a permanent home for the first LEN characters of S. It ++ will never be moved or deallocated, but may share space with other ++ strings. Don't modify the returned string. */ ++static char * ++__tzstring_len (const char *s, size_t len) + { + char *p; + struct tzstring_l *t, *u, *new; +- size_t len = strlen (s); + + /* Walk the list and look for a match. If this string is the same + as the end of an already-allocated string, it can share space. */ +@@ -98,7 +98,7 @@ + if (len <= t->len) + { + p = &t->data[t->len - len]; +- if (strcmp (s, p) == 0) ++ if (memcmp (s, p, len) == 0) + return p; + } + +@@ -109,7 +109,8 @@ + + new->next = NULL; + new->len = len; +- strcpy (new->data, s); ++ memcpy (new->data, s, len); ++ new->data[len] = '\0'; + + if (u) + u->next = new; +@@ -118,6 +119,15 @@ + + return new->data; + } ++ ++/* Allocate a permanent home for S. It will never be moved or ++ deallocated, but may share space with other strings. Don't modify ++ the returned string. */ ++char * ++__tzstring (const char *s) ++{ ++ return __tzstring_len (s, strlen (s)); ++} + + /* Maximum length of a timezone name. tzset_internal keeps this up to date + (never decreasing it) when ! __use_tzfile. +@@ -125,7 +135,7 @@ + size_t __tzname_cur_max; + + long int +-__tzname_max () ++__tzname_max (void) + { + __libc_lock_lock (tzset_lock); + +@@ -164,243 +174,227 @@ + return min (ss, 59) + min (mm, 59) * 60 + min (hh, 24) * 60 * 60; + } + +- +-/* Parse the POSIX TZ-style string. */ +-void +-__tzset_parse_tz (tz) +- const char *tz; +-{ +- unsigned short int hh, mm, ss; +- +- /* Clear out old state and reset to unnamed UTC. */ +- memset (tz_rules, '\0', sizeof tz_rules); +- tz_rules[0].name = tz_rules[1].name = ""; +- +- /* Get the standard timezone name. */ +- char *tzbuf = strdupa (tz); +- +- int consumed; +- if (sscanf (tz, "%[A-Za-z]%n", tzbuf, &consumed) != 1) +- { +- /* Check for the quoted version. */ +- char *wp = tzbuf; +- if (__builtin_expect (*tz++ != '<', 0)) +- goto out; +- +- while (isalnum (*tz) || *tz == '+' || *tz == '-') +- *wp++ = *tz++; +- if (__builtin_expect (*tz++ != '>' || wp - tzbuf < 3, 0)) +- goto out; +- *wp = '\0'; ++/* Parses the time zone name at *TZP, and writes a pointer to an ++ interned string to tz_rules[WHICHRULE].name. On success, advances ++ *TZP, and returns true. Returns false otherwise. */ ++static bool ++parse_tzname (const char **tzp, int whichrule) ++{ ++ const char *start = *tzp; ++ const char *p = start; ++ while (('a' <= *p && *p <= 'z') ++ || ('A' <= *p && *p <= 'Z')) ++ ++p; ++ size_t len = p - start; ++ if (len < 3) ++ { ++ p = *tzp; ++ if (__glibc_unlikely (*p++ != '<')) ++ return false; ++ start = p; ++ while (('a' <= *p && *p <= 'z') ++ || ('A' <= *p && *p <= 'Z') ++ || ('0' <= *p && *p <= '9') ++ || *p == '+' || *p == '-') ++ ++p; ++ len = p - start; ++ if (*p++ != '>' || len < 3) ++ return false; + } +- else if (__builtin_expect (consumed < 3, 0)) +- goto out; +- else +- tz += consumed; + +- tz_rules[0].name = __tzstring (tzbuf); ++ tz_rules[whichrule].name = __tzstring_len (start, len); ++ ++ *tzp = p; ++ return true; ++} + +- /* Figure out the standard offset from UTC. */ +- if (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit (*tz))) +- goto out; ++/* Parses the time zone offset at *TZP, and writes it to ++ tz_rules[WHICHRULE].offset. Returns true if the parse was ++ successful. */ ++static bool ++parse_offset (const char **tzp, int whichrule) ++{ ++ const char *tz = *tzp; ++ if (whichrule == 0 ++ && (*tz == '\0' || (*tz != '+' && *tz != '-' && !isdigit (*tz)))) ++ return false; + ++ long sign; + if (*tz == '-' || *tz == '+') +- tz_rules[0].offset = *tz++ == '-' ? 1L : -1L; ++ sign = *tz++ == '-' ? 1L : -1L; + else +- tz_rules[0].offset = -1L; +- switch (sscanf (tz, "%hu%n:%hu%n:%hu%n", +- &hh, &consumed, &mm, &consumed, &ss, &consumed)) +- { +- default: +- tz_rules[0].offset = 0; +- goto out; +- case 1: +- mm = 0; +- case 2: +- ss = 0; +- case 3: +- break; +- } +- tz_rules[0].offset *= compute_offset (ss, mm, hh); +- tz += consumed; +- +- /* Get the DST timezone name (if any). */ +- if (*tz != '\0') +- { +- if (sscanf (tz, "%[A-Za-z]%n", tzbuf, &consumed) != 1) +- { +- /* Check for the quoted version. */ +- char *wp = tzbuf; +- const char *rp = tz; +- if (__builtin_expect (*rp++ != '<', 0)) +- /* Punt on name, set up the offsets. */ +- goto done_names; +- +- while (isalnum (*rp) || *rp == '+' || *rp == '-') +- *wp++ = *rp++; +- if (__builtin_expect (*rp++ != '>' || wp - tzbuf < 3, 0)) +- /* Punt on name, set up the offsets. */ +- goto done_names; +- *wp = '\0'; +- tz = rp; +- } +- else if (__builtin_expect (consumed < 3, 0)) +- /* Punt on name, set up the offsets. */ +- goto done_names; +- else +- tz += consumed; ++ sign = -1L; ++ *tzp = tz; + +- tz_rules[1].name = __tzstring (tzbuf); +- +- /* Figure out the DST offset from GMT. */ +- if (*tz == '-' || *tz == '+') +- tz_rules[1].offset = *tz++ == '-' ? 1L : -1L; ++ unsigned short int hh; ++ unsigned short mm = 0; ++ unsigned short ss = 0; ++ int consumed = 0; ++ if (sscanf (tz, "%hu%n:%hu%n:%hu%n", ++ &hh, &consumed, &mm, &consumed, &ss, &consumed) > 0) ++ tz_rules[whichrule].offset = sign * compute_offset (ss, mm, hh); ++ else ++ /* Nothing could be parsed. */ ++ if (whichrule == 0) ++ { ++ /* Standard time defaults to offset zero. */ ++ tz_rules[0].offset = 0; ++ return false; ++ } + else +- tz_rules[1].offset = -1L; ++ /* DST defaults to one hour later than standard time. */ ++ tz_rules[1].offset = tz_rules[0].offset + (60 * 60); ++ *tzp = tz + consumed; ++ return true; ++} + +- switch (sscanf (tz, "%hu%n:%hu%n:%hu%n", +- &hh, &consumed, &mm, &consumed, &ss, &consumed)) ++/* Parses the standard <-> DST rules at *TZP. Updates ++ tz_rule[WHICHRULE]. On success, advances *TZP and returns true. ++ Otherwise, returns false. */ ++static bool ++parse_rule (const char **tzp, int whichrule) ++{ ++ const char *tz = *tzp; ++ tz_rule *tzr = &tz_rules[whichrule]; ++ ++ /* Ignore comma to support string following the incorrect ++ specification in early POSIX.1 printings. */ ++ tz += *tz == ','; ++ ++ /* Get the date of the change. */ ++ if (*tz == 'J' || isdigit (*tz)) ++ { ++ char *end; ++ tzr->type = *tz == 'J' ? J1 : J0; ++ if (tzr->type == J1 && !isdigit (*++tz)) ++ return false; ++ unsigned long int d = strtoul (tz, &end, 10); ++ if (end == tz || d > 365) ++ return false; ++ if (tzr->type == J1 && d == 0) ++ return false; ++ tzr->d = d; ++ tz = end; ++ } ++ else if (*tz == 'M') ++ { ++ tzr->type = M; ++ int consumed; ++ if (sscanf (tz, "M%hu.%hu.%hu%n", ++ &tzr->m, &tzr->n, &tzr->d, &consumed) != 3 ++ || tzr->m < 1 || tzr->m > 12 ++ || tzr->n < 1 || tzr->n > 5 || tzr->d > 6) ++ return false; ++ tz += consumed; ++ } ++ else if (*tz == '\0') ++ { ++ /* Daylight time rules in the U.S. are defined in the U.S. Code, ++ Title 15, Chapter 6, Subchapter IX - Standard Time. These ++ dates were established by Congress in the Energy Policy Act ++ of 2005 [Pub. L. no. 109-58, 119 Stat 594 (2005)]. ++ Below is the equivalent of "M3.2.0,M11.1.0" [/2 not needed ++ since 2:00AM is the default]. */ ++ tzr->type = M; ++ if (tzr == &tz_rules[0]) + { +- default: +- /* Default to one hour later than standard time. */ +- tz_rules[1].offset = tz_rules[0].offset + (60 * 60); +- break; +- +- case 1: +- mm = 0; +- case 2: +- ss = 0; +- case 3: +- tz_rules[1].offset *= compute_offset (ss, mm, hh); +- tz += consumed; +- break; ++ tzr->m = 3; ++ tzr->n = 2; ++ tzr->d = 0; + } +- if (*tz == '\0' || (tz[0] == ',' && tz[1] == '\0')) ++ else + { +- /* There is no rule. See if there is a default rule file. */ +- __tzfile_default (tz_rules[0].name, tz_rules[1].name, +- tz_rules[0].offset, tz_rules[1].offset); +- if (__use_tzfile) +- { +- free (old_tz); +- old_tz = NULL; +- return; +- } ++ tzr->m = 11; ++ tzr->n = 1; ++ tzr->d = 0; + } + } + else +- { +- /* There is no DST. */ +- tz_rules[1].name = tz_rules[0].name; +- tz_rules[1].offset = tz_rules[0].offset; +- goto out; ++ return false; ++ ++ if (*tz != '\0' && *tz != '/' && *tz != ',') ++ return false; ++ else if (*tz == '/') ++ { ++ /* Get the time of day of the change. */ ++ int negative; ++ ++tz; ++ if (*tz == '\0') ++ return false; ++ negative = *tz == '-'; ++ tz += negative; ++ /* Default to 2:00 AM. */ ++ unsigned short hh = 2; ++ unsigned short mm = 0; ++ unsigned short ss = 0; ++ int consumed = 0; ++ sscanf (tz, "%hu%n:%hu%n:%hu%n", ++ &hh, &consumed, &mm, &consumed, &ss, &consumed);; ++ tz += consumed; ++ tzr->secs = (negative ? -1 : 1) * ((hh * 60 * 60) + (mm * 60) + ss); + } ++ else ++ /* Default to 2:00 AM. */ ++ tzr->secs = 2 * 60 * 60; + +- done_names: +- /* Figure out the standard <-> DST rules. */ +- for (unsigned int whichrule = 0; whichrule < 2; ++whichrule) +- { +- register tz_rule *tzr = &tz_rules[whichrule]; ++ tzr->computed_for = -1; ++ *tzp = tz; ++ return true; ++} + +- /* Ignore comma to support string following the incorrect +- specification in early POSIX.1 printings. */ +- tz += *tz == ','; ++/* Parse the POSIX TZ-style string. */ ++void ++__tzset_parse_tz (const char *tz) ++{ ++ /* Clear out old state and reset to unnamed UTC. */ ++ memset (tz_rules, '\0', sizeof tz_rules); ++ tz_rules[0].name = tz_rules[1].name = ""; + +- /* Get the date of the change. */ +- if (*tz == 'J' || isdigit (*tz)) +- { +- char *end; +- tzr->type = *tz == 'J' ? J1 : J0; +- if (tzr->type == J1 && !isdigit (*++tz)) +- goto out; +- unsigned long int d = strtoul (tz, &end, 10); +- if (end == tz || d > 365) +- goto out; +- if (tzr->type == J1 && d == 0) +- goto out; +- tzr->d = d; +- tz = end; +- } +- else if (*tz == 'M') +- { +- tzr->type = M; +- if (sscanf (tz, "M%hu.%hu.%hu%n", +- &tzr->m, &tzr->n, &tzr->d, &consumed) != 3 +- || tzr->m < 1 || tzr->m > 12 +- || tzr->n < 1 || tzr->n > 5 || tzr->d > 6) +- goto out; +- tz += consumed; +- } +- else if (*tz == '\0') ++ /* Get the standard timezone name. */ ++ if (parse_tzname (&tz, 0) && parse_offset (&tz, 0)) ++ { ++ /* Get the DST timezone name (if any). */ ++ if (*tz != '\0') + { +- /* Daylight time rules in the U.S. are defined in the +- U.S. Code, Title 15, Chapter 6, Subchapter IX - Standard +- Time. These dates were established by Congress in the +- Energy Policy Act of 2005 [Pub. L. no. 109-58, 119 Stat 594 +- (2005)]. +- Below is the equivalent of "M3.2.0,M11.1.0" [/2 not needed +- since 2:00AM is the default]. */ +- tzr->type = M; +- if (tzr == &tz_rules[0]) ++ if (parse_tzname (&tz, 1)) + { +- tzr->m = 3; +- tzr->n = 2; +- tzr->d = 0; +- } +- else +- { +- tzr->m = 11; +- tzr->n = 1; +- tzr->d = 0; ++ parse_offset (&tz, 1); ++ if (*tz == '\0' || (tz[0] == ',' && tz[1] == '\0')) ++ { ++ /* There is no rule. See if there is a default rule ++ file. */ ++ __tzfile_default (tz_rules[0].name, tz_rules[1].name, ++ tz_rules[0].offset, tz_rules[1].offset); ++ if (__use_tzfile) ++ { ++ free (old_tz); ++ old_tz = NULL; ++ return; ++ } ++ } + } ++ /* Figure out the standard <-> DST rules. */ ++ if (parse_rule (&tz, 0)) ++ parse_rule (&tz, 1); + } + else +- goto out; +- +- if (*tz != '\0' && *tz != '/' && *tz != ',') +- goto out; +- else if (*tz == '/') + { +- /* Get the time of day of the change. */ +- ++tz; +- if (*tz == '\0') +- goto out; +- consumed = 0; +- switch (sscanf (tz, "%hu%n:%hu%n:%hu%n", +- &hh, &consumed, &mm, &consumed, &ss, &consumed)) +- { +- default: +- hh = 2; /* Default to 2:00 AM. */ +- case 1: +- mm = 0; +- case 2: +- ss = 0; +- case 3: +- break; +- } +- tz += consumed; +- tzr->secs = (hh * 60 * 60) + (mm * 60) + ss; ++ /* There is no DST. */ ++ tz_rules[1].name = tz_rules[0].name; ++ tz_rules[1].offset = tz_rules[0].offset; + } +- else +- /* Default to 2:00 AM. */ +- tzr->secs = 2 * 60 * 60; +- +- tzr->computed_for = -1; + } + +- out: + update_vars (); + } + + /* Interpret the TZ envariable. */ + static void + internal_function +-tzset_internal (always, explicit) +- int always; +- int explicit; ++tzset_internal (int always, int explicit) + { + static int is_initialized; +- register const char *tz; ++ const char *tz; + + if (is_initialized && !always) + return; +@@ -467,11 +461,9 @@ + put it in RULE->change, saving YEAR in RULE->computed_for. */ + static void + internal_function +-compute_change (rule, year) +- tz_rule *rule; +- int year; ++compute_change (tz_rule *rule, int year) + { +- register time_t t; ++ time_t t; + + if (year != -1 && rule->computed_for == year) + /* Operations on times in 2 BC will be slower. Oh well. */ +@@ -558,10 +550,7 @@ + `__timezone', and `__daylight' accordingly. */ + void + internal_function +-__tz_compute (timer, tm, use_localtime) +- time_t timer; +- struct tm *tm; +- int use_localtime; ++__tz_compute (time_t timer, struct tm *tm, int use_localtime) + { + compute_change (&tz_rules[0], 1900 + tm->tm_year); + compute_change (&tz_rules[1], 1900 + tm->tm_year); +@@ -641,6 +630,8 @@ + leap_extra_secs = 0; + } + ++ __libc_lock_unlock (tzset_lock); ++ + if (tp) + { + if (! use_localtime) +@@ -656,8 +647,6 @@ + tp = NULL; + } + +- __libc_lock_unlock (tzset_lock); +- + return tp; + } + +diff --git a/timezone/Makefile b/timezone/Makefile +index 17424b8..5f18545 100644 +--- a/timezone/Makefile ++++ b/timezone/Makefile +@@ -23,7 +23,7 @@ + extra-objs := scheck.o ialloc.o + + others := zdump zic +-tests := test-tz tst-timezone ++tests := test-tz tst-timezone tst-tzset + + # pacificnew doesn't compile; if it is to be used, it should be included in + # northamerica. +@@ -87,9 +87,11 @@ + Australia/Melbourne \ + America/Sao_Paulo Asia/Tokyo \ + Europe/London) ++$(objpfx)tst-tzset.out: $(addprefix $(testdata)/XT, 1 2 3 4) + + test-tz-ENV = TZDIR=$(testdata) + tst-timezone-ENV = TZDIR=$(testdata) ++tst-tzset-ENV = TZDIR=$(testdata) + + # Note this must come second in the deps list for $(built-program-cmd) to work. + zic-deps = $(objpfx)zic $(leapseconds) yearistype +@@ -111,6 +113,8 @@ + $(testdata)/Asia/Tokyo: asia $(zic-deps) + $(build-testdata) + ++$(testdata)/XT%: testdata/XT% ++ cp $< $@ + + $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make + sed -e 's|/bin/bash|$(KSH)|g' \ +diff --git a/timezone/README b/timezone/README +index 7a5e31c..2268f8e 100644 +--- a/timezone/README ++++ b/timezone/README +@@ -15,3 +15,6 @@ version of the tzcode and tzdata packages. + + These packages may be found at ftp://ftp.iana.org/tz/releases/. Commentary + should be addressed to tz@iana.org. ++ ++The subdirectory testdata contains manually edited data files for ++regression testing purposes. +--- /dev/null ++++ b/timezone/tst-tzset.c +@@ -0,0 +1,200 @@ ++/* tzset tests with crafted time zone data. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define _GNU_SOURCE 1 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int do_test (void); ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++/* Returns the name of a large TZ file. */ ++static char * ++create_tz_file (off64_t size) ++{ ++ char *path; ++ int fd = create_temp_file ("tst-tzset-", &path); ++ if (fd < 0) ++ exit (1); ++ ++ // Reopen for large-file support. ++ close (fd); ++ fd = open64 (path, O_WRONLY); ++ if (fd < 0) ++ { ++ printf ("open64 (%s) failed: %m\n", path); ++ exit (1); ++ } ++ ++ static const char data[] = { ++ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x58, 0x54, 0x47, 0x00, 0x00, 0x00, ++ 0x54, 0x5a, 0x69, 0x66, 0x32, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0x00, 0x04, 0xf8, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x58, 0x54, 0x47, 0x00, 0x00, ++ 0x00, 0x0a, 0x58, 0x54, 0x47, 0x30, 0x0a ++ }; ++ ssize_t ret = write (fd, data, sizeof (data)); ++ if (ret < 0) ++ { ++ printf ("write failed: %m\n"); ++ exit (1); ++ } ++ if ((size_t) ret != sizeof (data)) ++ { ++ printf ("Short write\n"); ++ exit (1); ++ } ++ if (lseek64 (fd, size, SEEK_CUR) < 0) ++ { ++ printf ("lseek failed: %m\n"); ++ close (fd); ++ return NULL; ++ } ++ if (write (fd, "", 1) != 1) ++ { ++ printf ("Single-byte write failed\n"); ++ close (fd); ++ return NULL; ++ } ++ if (close (fd) != 0) ++ { ++ printf ("close failed: %m\n"); ++ exit (1); ++ } ++ return path; ++} ++ ++static void ++test_tz_file (off64_t size) ++{ ++ char *path = create_tz_file (size); ++ if (setenv ("TZ", path, 1) < 0) ++ { ++ printf ("setenv failed: %m\n"); ++ exit (1); ++ } ++ tzset (); ++ free (path); ++} ++ ++static int ++do_test (void) ++{ ++ /* Limit the size of the process. Otherwise, some of the tests will ++ consume a lot of resources. */ ++ { ++ struct rlimit limit; ++ if (getrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("getrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ long target = 512 * 1024 * 1024; ++ if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target) ++ { ++ limit.rlim_cur = 512 * 1024 * 1024; ++ if (setrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("setrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ } ++ } ++ ++ int errors = 0; ++ for (int i = 1; i <= 4; ++i) ++ { ++ char tz[16]; ++ snprintf (tz, sizeof (tz), "XT%d", i); ++ if (setenv ("TZ", tz, 1) < 0) ++ { ++ printf ("setenv failed: %m\n"); ++ return 1; ++ } ++ tzset (); ++ if (strcmp (tzname[0], tz) == 0) ++ { ++ printf ("Unexpected success for %s\n", tz); ++ ++errors; ++ } ++ } ++ ++ /* Large TZ files. */ ++ ++ /* This will succeed on 64-bit architectures, and fail on 32-bit ++ architectures. It used to crash on 32-bit. */ ++ test_tz_file (64 * 1024 * 1024); ++ ++ /* This will fail on 64-bit and 32-bit architectures. It used to ++ cause a test timeout on 64-bit and crash on 32-bit if the TZ file ++ open succeeded for some reason (it does not use O_LARGEFILE in ++ regular builds). */ ++ test_tz_file (4LL * 1024 * 1024 * 1024 - 6); ++ ++ /* Large TZ variables. */ ++ { ++ size_t length = 64 * 1024 * 1024; ++ char *value = malloc (length + 1); ++ if (value == NULL) ++ { ++ puts ("malloc failed: %m"); ++ return 1; ++ } ++ value[length] = '\0'; ++ ++ memset (value, ' ', length); ++ value[0] = 'U'; ++ value[1] = 'T'; ++ value[2] = 'C'; ++ if (setenv ("TZ", value, 1) < 0) ++ { ++ printf ("setenv failed: %m\n"); ++ return 1; ++ } ++ tzset (); ++ ++ memset (value, '0', length); ++ value[0] = '<'; ++ value[length - 1] = '>'; ++ if (setenv ("TZ", value, 1) < 0) ++ { ++ printf ("setenv failed: %m\n"); ++ return 1; ++ } ++ tzset (); ++ } ++ ++ return errors > 0; ++} +diff --git a/timezone/Makefile b/timezone/Makefile +index 81d4a3e..bfb3463 100644 +--- a/timezone/Makefile ++++ b/timezone/Makefile +@@ -113,6 +113,7 @@ $(testdata)/Asia/Tokyo: asia $(zic-deps) + $(build-testdata) + + $(testdata)/XT%: testdata/XT% ++ $(make-target-directory) + cp $< $@ + + $(objpfx)tzselect: tzselect.ksh $(common-objpfx)config.make +diff -Nrup -a a/timezone/testdata/XT1 b/timezone/testdata/XT1 +--- a/timezone/testdata/XT1 1969-12-31 19:00:00.000000000 -0500 ++++ b/timezone/testdata/XT1 2017-09-14 10:19:11.382923956 -0400 +@@ -0,0 +1,2 @@ ++TZif2ÿÿÿÿXT1TZif2ÿÿÿÿøXT1 ++XT10 +diff -Nrup -a a/timezone/testdata/XT2 b/timezone/testdata/XT2 +--- a/timezone/testdata/XT2 1969-12-31 19:00:00.000000000 -0500 ++++ b/timezone/testdata/XT2 2017-09-14 10:19:11.382923956 -0400 +@@ -0,0 +1,2 @@ ++TZif2ÿÿÿÿXT2TZif2ÿÿÿÿøXT2 ++XT20 +diff -Nrup -a a/timezone/testdata/XT3 b/timezone/testdata/XT3 +--- a/timezone/testdata/XT3 1969-12-31 19:00:00.000000000 -0500 ++++ b/timezone/testdata/XT3 2017-09-14 10:19:11.382923956 -0400 +@@ -0,0 +1,2 @@ ++TZif2XT3TZif2øXT3 ++XT30 +diff -Nrup -a a/timezone/testdata/XT4 b/timezone/testdata/XT4 +--- a/timezone/testdata/XT4 1969-12-31 19:00:00.000000000 -0500 ++++ b/timezone/testdata/XT4 2017-09-14 10:19:11.383923953 -0400 +@@ -0,0 +1,2 @@ ++TZif2XT4TZif2øXT4 ++XT40 diff --git a/SOURCES/glibc-rh1234449-3.patch b/SOURCES/glibc-rh1234449-3.patch new file mode 100644 index 00000000..2a9ebd14 --- /dev/null +++ b/SOURCES/glibc-rh1234449-3.patch @@ -0,0 +1,93 @@ +commit cc8dcf96e71dd643f929e32150904cd6ad69efa8 +Author: Florian Weimer +Date: Mon Apr 27 15:41:03 2015 +0200 + + test-skeleton: Support temporary files without memory leaks [BZ#18333] + + add_temp_file now makes a copy which is freed by delete_temp_files. + Callers to create_temp_file can now free the returned file name to + avoid the memory leak. These changes do not affect the leak behavior + of existing code. + + Also address a NULL pointer derefence in tzset after a memory allocation + failure, found during testing. + +diff --git a/test-skeleton.c b/test-skeleton.c +index 7a8ddfa..43fc236 100644 +--- a/test-skeleton.c ++++ b/test-skeleton.c +@@ -73,7 +73,7 @@ static const char *test_dir; + struct temp_name_list + { + struct qelem q; +- const char *name; ++ char *name; + } *temp_name_list; + + /* Add temporary files in list. */ +@@ -83,14 +83,17 @@ add_temp_file (const char *name) + { + struct temp_name_list *newp + = (struct temp_name_list *) calloc (sizeof (*newp), 1); +- if (newp != NULL) ++ char *newname = strdup (name); ++ if (newp != NULL && newname != NULL) + { +- newp->name = name; ++ newp->name = newname; + if (temp_name_list == NULL) + temp_name_list = (struct temp_name_list *) &newp->q; + else + insque (newp, temp_name_list); + } ++ else ++ free (newp); + } + + /* Delete all temporary files. */ +@@ -100,11 +103,19 @@ delete_temp_files (void) + while (temp_name_list != NULL) + { + remove (temp_name_list->name); +- temp_name_list = (struct temp_name_list *) temp_name_list->q.q_forw; ++ free (temp_name_list->name); ++ ++ struct temp_name_list *next ++ = (struct temp_name_list *) temp_name_list->q.q_forw; ++ free (temp_name_list); ++ temp_name_list = next; + } + } + +-/* Create a temporary file. */ ++/* Create a temporary file. Return the opened file descriptor on ++ success, or -1 on failure. Write the file name to *FILENAME if ++ FILENAME is not NULL. In this case, the caller is expected to free ++ *FILENAME. */ + static int + __attribute__ ((unused)) + create_temp_file (const char *base, char **filename) +@@ -132,6 +143,8 @@ create_temp_file (const char *base, char **filename) + add_temp_file (fname); + if (filename != NULL) + *filename = fname; ++ else ++ free (fname); + + return fd; + } +diff --git a/time/tzset.c b/time/tzset.c +--- a/time/tzset.c ++++ b/time/tzset.c +@@ -202,7 +202,10 @@ + return false; + } + +- tz_rules[whichrule].name = __tzstring_len (start, len); ++ const char *name = __tzstring_len (start, len); ++ if (name == NULL) ++ return false; ++ tz_rules[whichrule].name = name; + + *tzp = p; + return true; diff --git a/SOURCES/glibc-rh1234449-4.patch b/SOURCES/glibc-rh1234449-4.patch new file mode 100644 index 00000000..dcdc511e --- /dev/null +++ b/SOURCES/glibc-rh1234449-4.patch @@ -0,0 +1,21 @@ +commit 5cffc05ed5c7fea312f2822d388afc025d03c08a +Author: H.J. Lu +Date: Mon Apr 27 09:57:51 2015 -0700 + + Check tzspec_len == 0 in __tzfile_read + + [BZ#18333] + * time/tzset.c (__tzfile_read): Check tzspec_len == 0. + +--- a/time/tzfile.c ++++ b/time/tzfile.c +@@ -283,7 +283,8 @@ + if (__builtin_expect (tzspec_len == 0 || tzspec_len - 1 < num_isgmt, 0)) + goto lose; + tzspec_len -= num_isgmt + 1; +- if (__builtin_expect (SIZE_MAX - total_size < tzspec_len, 0)) ++ if (__builtin_expect (tzspec_len == 0 ++ || SIZE_MAX - total_size < tzspec_len, 0)) + goto lose; + } + if (__builtin_expect (SIZE_MAX - total_size - tzspec_len < extra, 0)) diff --git a/SOURCES/glibc-rh1234622.patch b/SOURCES/glibc-rh1234622.patch new file mode 100644 index 00000000..1935f41e --- /dev/null +++ b/SOURCES/glibc-rh1234622.patch @@ -0,0 +1,12 @@ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist +=================================================================== +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/libpthread.abilist +@@ -73,7 +73,6 @@ GLIBC_2.17 + pause F + pread F + pread64 F +- pthread_atfork F + pthread_attr_destroy F + pthread_attr_getaffinity_np F + pthread_attr_getdetachstate F diff --git a/SOURCES/glibc-rh1240351-1.patch b/SOURCES/glibc-rh1240351-1.patch new file mode 100644 index 00000000..f5091c03 --- /dev/null +++ b/SOURCES/glibc-rh1240351-1.patch @@ -0,0 +1,19 @@ + Removed file as a prerequisite for bug 1213267 - [7.3 FEAT] Configure + glibc with --with-cpu=power8 --with-tune=power8 for RHEL7.3 ppc64le. + +Part of this upstream commit: + +commit 5e6a4d4b9eb579c5ca606c0eed1f2f40e405a5f1 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:29:27 2013 -0500 + + PowerPC: Adjust multiarch Implies for PowerPC64 + +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies b/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies +deleted file mode 100644 +index fad2505..0000000 +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power8/fpu +-powerpc/powerpc64/power8 diff --git a/SOURCES/glibc-rh1240351-10.patch b/SOURCES/glibc-rh1240351-10.patch new file mode 100644 index 00000000..8003c582 --- /dev/null +++ b/SOURCES/glibc-rh1240351-10.patch @@ -0,0 +1,253 @@ + Backport of + commit 72607db038df1a1a7987af814aad8d2ed466c45c + Author: Rajalakshmi Srinivasaraghavan + Date: Fri Jan 9 11:56:35 2015 -0500 + + powerpc: Optimize POWER7 strcmp trailing checks + + This patch optimized the POWER7 trailing check by avoiding using byte + read operations and instead use the doubleword already readed with + bitwise operations. + + ChangeLog: + 2015-01-13 Rajalakshmi Srinivasaraghavan + Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/power7/strcmp.S (strcmp): Optimize + trailing byte check. + +diff --git a/sysdeps/powerpc/powerpc64/power7/strcmp.S b/sysdeps/powerpc/powerpc64/power7/strcmp.S +index f16a9d8..ade2811 100644 +--- a/sysdeps/powerpc/powerpc64/power7/strcmp.S ++++ b/sysdeps/powerpc/powerpc64/power7/strcmp.S +@@ -25,122 +25,96 @@ + + /* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) */ + ++ .machine power7 + EALIGN (strcmp, 4, 0) + CALL_MCOUNT 2 + + or r9, r3, r4 + rldicl. r10, r9, 0, 61 /* are s1 and s2 8 byte aligned..? */ + bne cr0, L(process_unaligned_bytes) ++ li r5, 0 + ++ .align 4 + /* process input parameters on double word aligned boundary */ +- ld r9, 0(r4) /* load s2 at offset=0 */ +- li r10, 0 /* load mask=0 */ +- cmpb r10, r9, r10 /* compare bytes at s2 with mask */ +- cmpdi cr7, r10, 0 /* is NULL found ..? is end of string HIT */ +- bne cr7, L(process_unaligned_bytes) /* process byte by byte */ +- +- ld r10, 0(r3) /* load s1 at offset=0 */ +- li r8, 0 /* load mask=0 */ +- cmpb r8, r10, r8 /* compare bytes at s1 with mask */ +- cmpdi cr7, r8, 0 /* is NULL found ..? is end of string HIT */ +- bne cr7, L(process_unaligned_bytes) /* process byte by byte */ +- +-/*s1 and s2 does not contain NULL now , so compare all 8 bytes in a GO */ +- cmpb r9, r10, r9 /* compare s1 and s2 */ +- cmpdi cr7, r9, -1 /* compare result with 0xFFFFFFFFFFFFFFFF */ +- bne cr7, L(process_unaligned_bytes) /* s1,s2 mismatch found */ +- +- addi r5, r3, 8 /* save next offset of s2 */ +- addi r11, r4, 8 /* save next offset of s1 */ +- ld r8, 8(r4) /* load s2 at offset=8 */ +- li r9, 0 /* load mask=0 */ +- cmpb r9, r8, r9 /* compare bytes at s2 with mask */ +- cmpdi cr7, r9, 0 /* NULL found ..? */ +- bne cr7, L(processBytes)/* update input and process bytes one by one */ +- +- mr r9, r4 /* save s2 */ +- li r10, 0 /* load mask=0 */ +- +- ld r7, 8(r3) /* load s1 at offset=8 */ +- cmpb r6, r7, r10 /* compare bytes at s1 with mask */ +- cmpdi cr7, r6, 0 /* is NULL found */ +- bne cr7, L(processBytes)/* mismatch, so process one by one */ +- + L(unrollDword): +- cmpb r8, r7, r8 /* compare s1 and s2 */ +- cmpdi cr7, r8, -1 /* compare result with 0xFFFFFFFFFFFFFFFF */ +- bne cr7, L(processBytes)/* mismatch with s1 and s2 */ +- +- addi r5, r3, 16 /* save offset=16 of s1 */ +- addi r4, r9, 16 /* save offset=16 of s2 */ +- ld r8, 16(r9) /* load s2 at offset=16 */ +- cmpb r7, r8, r10 /* compare bytes at s2 with mask */ +- cmpdi cr7, r7, 0 /* NULL found ..? */ +- bne cr7, L(update2processBytes) +- +- ld r7, 16(r3) /* load s1 at offset=16 */ +- cmpb r6, r7, r10 /* check s1 for end of string */ +- cmpdi cr7, r6, 0 /* end of s1 ?,then handle byte by byte */ +- bne 7,L(update2processBytes) +- +- cmpb r8, r7, r8 /* compare s1 and s2 double words */ +- cmpdi cr7, r8, -1 /* compare results with 0xFFFFFFFFFFFFFFFF */ +- bne cr7,L(update2processBytes) +- +- addi r5, r3, 24 /* update s1 to offset=24 */ +- addi r4, r9, 24 /* update s2 to offset=24 */ +- +- ld r8, 24(r9) /* load s2 */ +- cmpb r7, r8, r10 /* compare s2 for NULL */ +- cmpdi cr7, r7, 0 /* verify if s2 is ending now */ +- bne cr7,L(update2processBytes) +- +- ld r7, 24(r3) /* load s1 at offset=24 */ +- cmpb r6, r7, r10 /* verify for NULL */ +- cmpdi cr7, r6, 0 /* is NULL found */ +- bne cr7, L(update2processBytes) +- +- cmpb r8, r7, r8 /* compare s1 and s2 */ +- cmpdi cr7, r8, -1 /* are s1 and s2 same ..? */ +- bne cr7, L(update2processBytes) +- +- addi r7, r9, 32 /* update s2 to next double word */ +- addi r3, r3, 32 /* update s1 to next double word */ +- +- ld r8, 32(r9) /* load s2 */ +- mr r4, r7 /* save s2 */ +- cmpb r6, r8, r10 /* compare s2 with NULL */ +- cmpdi cr7, r6, 0 /* end of s2 ..? */ +- bne cr7, L(process_unaligned_bytes) +- +- ld r6, 0(r3) /* load and compare s1 for NULL */ +- cmpb r5, r6, r10 +- cmpdi cr7, r5, 0 +- bne cr7, L(process_unaligned_bytes) +- +- cmpb r8, r6, r8 /* compare s1 and s2 */ +- cmpdi cr7, r8, -1 +- bne cr7, L(process_unaligned_bytes) +- +- addi r5, r3, 8 /* increment s1 and d2 here */ +- addi r11, r9, 40 +- +- ld r8, 40(r9) /* process s2 now */ +- cmpb r9, r8, r10 +- cmpdi cr7, r9, 0 +- bne cr7, L(processBytes) +- +- mr r9, r7 +- ld r7, 8(r3) /* process s1 now */ +- cmpb r6, r7, r10 +- cmpdi cr7, r6, 0 +- beq cr7, L(unrollDword) /* unroll to compare s1 and s2 */ +- +-L(processBytes): +- mr r4, r11 /* update input params */ +- mr r3, r5 +- +- .p2align 4 ++ ld r8,0(r3) ++ ld r10,0(r4) ++ cmpb r7,r8,r5 ++ cmpdi cr7,r7,0 ++ mr r9,r7 ++ bne cr7,L(null_found) ++ cmpld cr7,r8,r10 ++ bne cr7,L(different) ++ ++ ld r8,8(r3) ++ ld r10,8(r4) ++ cmpb r7,r8,r5 ++ cmpdi cr7,r7,0 ++ mr r9,r7 ++ bne cr7,L(null_found) ++ cmpld cr7,r8,r10 ++ bne cr7,L(different) ++ ++ ld r8,16(r3) ++ ld r10,16(r4) ++ cmpb r7,r8,r5 ++ cmpdi cr7,r7,0 ++ mr r9,r7 ++ bne cr7,L(null_found) ++ cmpld cr7,r8,r10 ++ bne cr7,L(different) ++ ++ ld r8,24(r3) ++ ld r10,24(r4) ++ cmpb r7,r8,r5 ++ cmpdi cr7,r7,0 ++ mr r9,r7 ++ bne cr7,L(null_found) ++ cmpld cr7,r8,r10 ++ bne cr7,L(different) ++ ++ addi r3, r3, 32 ++ addi r4, r4, 32 ++ beq cr7, L(unrollDword) ++ ++ .align 4 ++L(null_found): ++#ifdef __LITTLE_ENDIAN__ ++ neg r7,r9 ++ and r9,r9,r7 ++ li r7,-1 ++ cntlzd r9,r9 ++ subfic r9,r9,71 ++ sld r9,r7,r9 ++#else ++ cntlzd r9,r9 ++ li r7,-1 ++ addi r9,r9,8 ++ srd r9,r7,r9 ++#endif ++ or r8,r8,r9 ++ or r10,r10,r9 ++ ++L(different): ++ cmpb r9,r8,r10 ++#ifdef __LITTLE_ENDIAN__ ++ addi r7,r9,1 ++ andc r9,r7,r9 ++ cntlzd r9,r9 ++ subfic r9,r9,63 ++#else ++ not r9,r9 ++ cntlzd r9,r9 ++ subfic r9,r9,56 ++#endif ++ srd r3,r8,r9 ++ srd r10,r10,r9 ++ rldicl r10,r10,0,56 ++ rldicl r3,r3,0,56 ++ subf r3,r10,r3 ++ blr ++ ++ .align 4 + L(process_unaligned_bytes): + lbz r9, 0(r3) /* load byte from s1 */ + lbz r10, 0(r4) /* load byte from s2 */ +@@ -172,24 +146,19 @@ L(process_unaligned_bytes): + addi r4, r4, 4 /* increment s2 by unroll factor */ + beq cr6, L(process_unaligned_bytes) /* unroll byte processing */ + +- .p2align 4 ++ .align 4 + L(ComputeDiff): + extsw r9, r9 + subf r10, r10, r9 /* compute s1 - s2 */ + extsw r3, r10 + blr /* return */ + +- .p2align 4 ++ .align 4 + L(diffOfNULL): + li r9, 0 + subf r10, r10, r9 /* compute s1 - s2 */ + extsw r3, r10 /* sign extend result */ + blr /* return */ + +- .p2align 4 +-L(update2processBytes): +- mr r3, r5 /* update and proceed */ +- b L(process_unaligned_bytes) +- + END (strcmp) + libc_hidden_builtin_def (strcmp) diff --git a/SOURCES/glibc-rh1240351-11.patch b/SOURCES/glibc-rh1240351-11.patch new file mode 100644 index 00000000..079685cb --- /dev/null +++ b/SOURCES/glibc-rh1240351-11.patch @@ -0,0 +1,450 @@ + Backport of + commit d3b00f468bec441596877a685a19f43dee88657f + Author: Adhemerval Zanella + Date: Fri Jan 9 16:04:26 2015 -0500 + + powerpc: Optimized strncmp for POWER8/PPC64 + + This patch adds an optimized POWER8 strncmp. The implementation focus + on speeding up unaligned cases follwing the ideas of power8 strcmp. + + The algorithm first check the initial 16 bytes, then align the first + function source and uses unaligned loads on second argument only. + Aditional checks for page boundaries are done for unaligned cases + (where sources alignment are different). + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/strncmp-power8.S: New file. + * sysdeps/powerpc/powerpc64/power8/strncmp.S: New file. + * sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]: Add + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 27c8b65..677d8ce 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -14,8 +14,9 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncat-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ +- strncase-power7 strncase_l-power7 strncmp-power7 \ +- strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \ ++ strncase-power7 strncase_l-power7 \ ++ strncmp-power8 strncmp-power7 strncmp-power4 strncmp-ppc64 \ ++ strchr-power7 strchr-ppc64 \ + strchrnul-power7 strchrnul-ppc64 wcschr-power7 \ + wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \ + wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 2b38c71..a540abf 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -100,6 +100,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */ + IFUNC_IMPL (i, name, strncmp, ++ IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strncmp_power8) + IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_HAS_VSX, + __strncmp_power7) + IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_POWER4, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power8.S +new file mode 100644 +index 0000000..8d7223d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power8.S +@@ -0,0 +1,40 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name,alignt,words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncmp_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncmp_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strncmp_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncmp_power8) \ ++ END_2(__strncmp_power8) ++ ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +index 9829d69..5e76783 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +@@ -25,13 +25,16 @@ + extern __typeof (strncmp) __strncmp_ppc attribute_hidden; + extern __typeof (strncmp) __strncmp_power4 attribute_hidden; + extern __typeof (strncmp) __strncmp_power7 attribute_hidden; ++extern __typeof (strncmp) __strncmp_power8 attribute_hidden; + + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (strncmp, +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __strncmp_power7 : +- (hwcap & PPC_FEATURE_POWER4) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strncmp_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strncmp_power7 : ++ (hwcap & PPC_FEATURE_POWER4) + ? __strncmp_power4 + : __strncmp_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/power8/strncmp.S b/sysdeps/powerpc/powerpc64/power8/strncmp.S +new file mode 100644 +index 0000000..56c814b +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strncmp.S +@@ -0,0 +1,323 @@ ++/* Optimized strncmp implementation for PowerPC64/POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Implements the function ++ ++ int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t [r5] n) ++ ++ The implementation uses unaligned doubleword access to avoid specialized ++ code paths depending of data alignment. Although recent powerpc64 uses ++ 64K as default, the page cross handling assumes minimum page size of ++ 4k. */ ++ ++ .machine power7 ++EALIGN (strncmp, 4, 0) ++ /* Check if size is 0. */ ++ mr. r10,r5 ++ beq cr0,L(ret0) ++ ++ /* Check if [s1]+16 or [s2]+16 will cross a 4K page boundary using ++ the code: ++ ++ (((size_t) s1) % PAGE_SIZE > (PAGE_SIZE - ITER_SIZE)) ++ ++ with PAGE_SIZE being 4096 and ITER_SIZE begin 16. */ ++ rldicl r8,r3,0,52 ++ cmpldi cr7,r8,4096-16 ++ bgt cr7,L(pagecross) ++ rldicl r9,r4,0,52 ++ cmpldi cr7,r9,4096-16 ++ bgt cr7,L(pagecross) ++ ++ /* For short string up to 16 bytes, load both s1 and s2 using ++ unaligned dwords and compare. */ ++ ld r7,0(r3) ++ ld r9,0(r4) ++ li r8,0 ++ cmpb r8,r7,r8 ++ cmpb r6,r7,r9 ++ orc. r8,r8,r6 ++ bne cr0,L(different1) ++ ++ /* If the string compared are equal, but size is less or equal ++ to 8, return 0. */ ++ cmpldi cr7,r10,8 ++ li r9,0 ++ ble cr7,L(ret1) ++ addi r5,r10,-8 ++ ++ ld r7,8(r3) ++ ld r9,8(r4) ++ cmpb r8,r7,r8 ++ cmpb r6,r7,r9 ++ orc. r8,r8,r6 ++ bne cr0,L(different0) ++ ++ cmpldi cr7,r5,8 ++ mr r9,r8 ++ ble cr7,L(ret1) ++ ++ /* Update pointers and size. */ ++ addi r10,r10,-16 ++ addi r3,r3,16 ++ addi r4,r4,16 ++ ++ /* Now it has checked for first 16 bytes, align source1 to doubleword ++ and adjust source2 address. */ ++L(align_8b): ++ rldicl r5,r3,0,61 ++ rldicr r3,r3,0,60 ++ subf r4,r5,r4 ++ add r10,r10,r5 ++ ++ /* At this point, source1 alignment is 0 and source2 alignment is ++ between 0 and 7. Check is source2 alignment is 0, meaning both ++ sources have the same alignment. */ ++ andi. r8,r4,0x7 ++ beq cr0,L(loop_eq_align_0) ++ ++ li r5,0 ++ b L(loop_ne_align_1) ++ ++ /* If source2 is unaligned to doubleword, the code needs to check ++ on each interation if the unaligned doubleword access will cross ++ a 4k page boundary. */ ++ .align 4 ++L(loop_ne_align_0): ++ ld r7,0(r3) ++ ld r9,0(r4) ++ cmpb r8,r7,r5 ++ cmpb r6,r7,r9 ++ orc. r8,r8,r6 ++ bne cr0,L(different1) ++ ++ cmpldi cr7,r10,8 ++ ble cr7,L(ret0) ++ addi r10,r10,-8 ++ addi r3,r3,8 ++ addi r4,r4,8 ++L(loop_ne_align_1): ++ rldicl r9,r4,0,52 ++ cmpldi r7,r9,4088 ++ ble cr7,L(loop_ne_align_0) ++ cmpdi cr7,r10,0 ++ beq cr7,L(ret0) ++ ++ lbz r9,0(r3) ++ lbz r8,0(r4) ++ cmplw cr7,r9,r8 ++ bne cr7,L(byte_ne_4) ++ cmpdi cr7,r9,0 ++ beq cr7,L(size_reached_0) ++ ++ li r9,r7 ++ addi r8,r3,1 ++ mtctr r9 ++ addi r4,r4,1 ++ addi r10,r10,-1 ++ addi r3,r3,8 ++ ++ /* The unaligned read of source2 will cross a 4K page boundary, ++ and the different byte or NULL maybe be in the remaining page ++ bytes. Since it can not use the unaligned load the algorithm ++ reads and compares 8 bytes to keep source1 doubleword aligned. */ ++ .align 4 ++L(loop_ne_align_byte): ++ cmpdi cr7,r10,0 ++ addi r10,r10,-1 ++ beq cr7,L(ret0) ++ lbz r9,0(r8) ++ lbz r7,0(r4) ++ addi r8,r8,1 ++ addi r4,r4,1 ++ cmplw cr7,r9,r7 ++ cmpdi cr5,r9,0 ++ bne cr7,L(size_reached_2) ++ beq cr5,L(size_reached_0) ++ bdnz L(loop_ne_align_byte) ++ ++ cmpdi cr7,r10,0 ++ bne+ cr7,L(loop_ne_align_0) ++ ++ .align 4 ++L(ret0): ++ li r9,0 ++L(ret1): ++ mr r3,r9 ++ blr ++ ++ /* The code now check if r8 and r10 are different by issuing a ++ cmpb and shift the result based on its output: ++ ++ #ifdef __LITTLE_ENDIAN__ ++ leadzero = (__builtin_ffsl (z1) - 1); ++ leadzero = leadzero > (n-1)*8 ? (n-1)*8 : leadzero; ++ r1 = (r1 >> leadzero) & 0xFFUL; ++ r2 = (r2 >> leadzero) & 0xFFUL; ++ #else ++ leadzero = __builtin_clzl (z1); ++ leadzero = leadzero > (n-1)*8 ? (n-1)*8 : leadzero; ++ r1 = (r1 >> (56 - leadzero)) & 0xFFUL; ++ r2 = (r2 >> (56 - leadzero)) & 0xFFUL; ++ #endif ++ return r1 - r2; */ ++ ++ .align 4 ++L(different0): ++ mr r10,r5 ++#ifdef __LITTLE_ENDIAN__ ++L(different1): ++ neg r11,r8 ++ sldi r10,r10,3 ++ and r8,r11,r8 ++ addi r10,r10,-8 ++ cntlzd r8,r8 ++ subfic r8,r8,63 ++ extsw r8,r8 ++ cmpld cr7,r8,r10 ++ ble cr7,L(different2) ++ mr r8,r10 ++L(different2): ++ extsw r8,r8 ++#else ++L(different1): ++ addi r10,r10,-1 ++ cntlzd r8,r8 ++ sldi r10,r10,3 ++ cmpld cr7,r8,r10 ++ blt cr7,L(different2) ++ mr r8,r10 ++L(different2): ++ subfic r8,r8,56 ++#endif ++ srd r7,r7,r8 ++ srd r9,r9,r8 ++ rldicl r3,r7,0,56 ++ rldicl r9,r9,0,56 ++ subf r9,r9,3 ++ extsw r9,r9 ++ mr r3,r9 ++ blr ++ ++ /* If unaligned 16 bytes reads across a 4K page boundary, it uses ++ a simple byte a byte comparison until the page alignment for s1 ++ is reached. */ ++ .align 4 ++L(pagecross): ++ lbz r7,0(r3) ++ lbz r9,0(r4) ++ subfic r8,r8,4095 ++ cmplw cr7,r9,r7 ++ bne cr7,L(byte_ne_3) ++ cmpdi cr7,r9,0 ++ beq cr7,L(byte_ne_0) ++ addi r10,r10,-1 ++ subf r7,r8,r10 ++ subf r9,r7,r10 ++ addi r9,r9,1 ++ mtctr r9 ++ b L(pagecross_loop1) ++ ++ .align 4 ++L(pagecross_loop0): ++ beq cr7,L(ret0) ++ lbz r9,0(r3) ++ lbz r8,0(r4) ++ addi r10,r10,-1 ++ cmplw cr7,r9,r8 ++ cmpdi cr5,r9,0 ++ bne r7,L(byte_ne_2) ++ beq r5,L(byte_ne_0) ++L(pagecross_loop1): ++ cmpdi cr7,r10,0 ++ addi r3,r3,1 ++ addi r4,r4,1 ++ bdnz L(pagecross_loop0) ++ cmpdi cr7,r7,0 ++ li r9,0 ++ bne+ cr7,L(align_8b) ++ b L(ret1) ++ ++ /* If both source1 and source2 are doubleword aligned, there is no ++ need for page boundary cross checks. */ ++ .align 4 ++L(loop_eq_align_0): ++ ld r7,0(r3) ++ ld r9,0(r4) ++ cmpb r8,r7,r8 ++ cmpb r6,r7,r9 ++ orc. r8,r8,r6 ++ bne cr0,L(different1) ++ ++ cmpldi cr7,r10,8 ++ ble cr7,L(ret0) ++ addi r9,r10,-9 ++ ++ li r5,0 ++ srdi r9,r9,3 ++ addi r9,r9,1 ++ mtctr r9 ++ b L(loop_eq_align_2) ++ ++ .align 4 ++L(loop_eq_align_1): ++ bdz L(ret0) ++L(loop_eq_align_2): ++ ldu r7,8(r3) ++ addi r10,r10,-8 ++ ldu r9,8(r4) ++ cmpb r8,r7,r5 ++ cmpb r6,r7,r9 ++ orc. r8,r8,r6 ++ beq cr0,L(loop_eq_align_1) ++ b L(different1) ++ ++ .align 4 ++L(byte_ne_0): ++ li r7,0 ++L(byte_ne_1): ++ subf r9,r9,r7 ++ extsw r9,r9 ++ b L(ret1) ++ ++ .align 4 ++L(byte_ne_2): ++ extsw r7,r9 ++ mr r9,r8 ++ b L(byte_ne_1) ++L(size_reached_0): ++ li r10,0 ++L(size_reached_1): ++ subf r9,r9,r10 ++ extsw r9,r9 ++ b L(ret1) ++L(size_reached_2): ++ extsw r10,r9 ++ mr r9,r7 ++ b L(size_reached_1) ++L(byte_ne_3): ++ extsw r7,r7 ++ b L(byte_ne_1) ++L(byte_ne_4): ++ extsw r10,r9 ++ mr r9,r8 ++ b L(size_reached_1) ++END(strncmp) ++libc_hidden_builtin_def(strncmp) diff --git a/SOURCES/glibc-rh1240351-12.patch b/SOURCES/glibc-rh1240351-12.patch new file mode 100644 index 00000000..76df8711 --- /dev/null +++ b/SOURCES/glibc-rh1240351-12.patch @@ -0,0 +1,1374 @@ + Backport of + commit ce6615c9c686acd34672a9f4eba9bcf5553496f6 + Author: Adhemerval Zanella + Date: Sun Jan 11 19:33:17 2015 -0600 + + powerpc: Fix POWER7/PPC64 performance regression on LE + + This patch fixes a performance regression on the POWER7/PPC64 memcmp + porting for Little Endian. The LE code uses 'ldbrx' instruction to read + the memory on byte reversed form, however ISA 2.06 just provide the indexed + form which uses a register value as additional index, instead of a fixed value + enconded in the instruction. + + And the port strategy for LE uses r0 index value and update the address + value on each compare loop interation. For large compare size values, + it adds 8 more instructions plus some more depending of trailing + size. This patch fixes it by adding pre-calculate indexes to remove the + address update on loops and tailing sizes. + + For large sizes it shows a considerable gain, with double performance + pairing with BE. + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/power7/memcmp.S (memcmp): Fix performance + regression on LE. + +diff --git a/sysdeps/powerpc/powerpc64/power7/memcmp.S b/sysdeps/powerpc/powerpc64/power7/memcmp.S +index 09bff69..98b9e54 100644 +--- a/sysdeps/powerpc/powerpc64/power7/memcmp.S ++++ b/sysdeps/powerpc/powerpc64/power7/memcmp.S +@@ -26,18 +26,48 @@ + EALIGN (memcmp, 4, 0) + CALL_MCOUNT 3 + +-#define rRTN r3 +-#define rSTR1 r3 /* first string arg */ +-#define rSTR2 r4 /* second string arg */ +-#define rN r5 /* max string length */ +-#define rWORD1 r6 /* current word in s1 */ +-#define rWORD2 r7 /* current word in s2 */ +-#define rWORD3 r8 /* next word in s1 */ +-#define rWORD4 r9 /* next word in s2 */ +-#define rWORD5 r10 /* next word in s1 */ +-#define rWORD6 r11 /* next word in s2 */ +-#define rWORD7 r30 /* next word in s1 */ +-#define rWORD8 r31 /* next word in s2 */ ++#define rRTN r3 ++#define rSTR1 r3 /* first string arg */ ++#define rSTR2 r4 /* second string arg */ ++#define rN r5 /* max string length */ ++#define rWORD1 r6 /* current word in s1 */ ++#define rWORD2 r7 /* current word in s2 */ ++#define rWORD3 r8 /* next word in s1 */ ++#define rWORD4 r9 /* next word in s2 */ ++#define rWORD5 r10 /* next word in s1 */ ++#define rWORD6 r11 /* next word in s2 */ ++ ++#define rOFF8 r20 /* 8 bytes offset. */ ++#define rOFF16 r21 /* 16 bytes offset. */ ++#define rOFF24 r22 /* 24 bytes offset. */ ++#define rOFF32 r23 /* 24 bytes offset. */ ++#define rWORD6_SHIFT r24 /* Left rotation temp for rWORD8. */ ++#define rWORD4_SHIFT r25 /* Left rotation temp for rWORD6. */ ++#define rWORD2_SHIFT r26 /* Left rotation temp for rWORD4. */ ++#define rWORD8_SHIFT r27 /* Left rotation temp for rWORD2. */ ++#define rSHR r28 /* Unaligned shift right count. */ ++#define rSHL r29 /* Unaligned shift left count. */ ++#define rWORD7 r30 /* next word in s1 */ ++#define rWORD8 r31 /* next word in s2 */ ++ ++#define rWORD8SAVE (-8) ++#define rWORD7SAVE (-16) ++#define rOFF8SAVE (-24) ++#define rOFF16SAVE (-32) ++#define rOFF24SAVE (-40) ++#define rOFF32SAVE (-48) ++#define rSHRSAVE (-56) ++#define rSHLSAVE (-64) ++#define rWORD8SHIFTSAVE (-72) ++#define rWORD2SHIFTSAVE (-80) ++#define rWORD4SHIFTSAVE (-88) ++#define rWORD6SHIFTSAVE (-96) ++ ++#ifdef __LITTLE_ENDIAN__ ++# define LD ldbrx ++#else ++# define LD ldx ++#endif + + xor r0, rSTR2, rSTR1 + cmpldi cr6, rN, 0 +@@ -51,10 +81,24 @@ EALIGN (memcmp, 4, 0) + /* If less than 8 bytes or not aligned, use the unaligned + byte loop. */ + blt cr1, L(bytealigned) +- std rWORD8, -8(r1) +- cfi_offset(rWORD8, -8) +- std rWORD7, -16(r1) +- cfi_offset(rWORD7, -16) ++ std rWORD8, rWORD8SAVE(r1) ++ cfi_offset(rWORD8, rWORD8SAVE) ++ std rWORD7, rWORD7SAVE(r1) ++ cfi_offset(rWORD7, rWORD7SAVE) ++ std rOFF8, rOFF8SAVE(r1) ++ cfi_offset(rWORD7, rOFF8SAVE) ++ std rOFF16, rOFF16SAVE(r1) ++ cfi_offset(rWORD7, rOFF16SAVE) ++ std rOFF24, rOFF24SAVE(r1) ++ cfi_offset(rWORD7, rOFF24SAVE) ++ std rOFF32, rOFF32SAVE(r1) ++ cfi_offset(rWORD7, rOFF32SAVE) ++ ++ li rOFF8,8 ++ li rOFF16,16 ++ li rOFF24,24 ++ li rOFF32,32 ++ + bne L(unaligned) + /* At this point we know both strings have the same alignment and the + compare length is at least 8 bytes. r12 contains the low order +@@ -79,15 +123,8 @@ L(samealignment): + sldi rWORD6, r12, 3 + srdi r0, rN, 5 /* Divide by 32 */ + andi. r12, rN, 24 /* Get the DW remainder */ +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 0(rSTR1) +- ld rWORD2, 0(rSTR2) +-#endif ++ LD rWORD1, 0, rSTR1 ++ LD rWORD2, 0, rSTR2 + cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 + clrldi rN, rN, 61 +@@ -104,15 +141,8 @@ L(dsP1): + cmpld cr5, rWORD5, rWORD6 + blt cr7, L(dP1x) + /* Do something useful in this cycle since we have to branch anyway. */ +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD1, rOFF8, rSTR1 ++ LD rWORD2, rOFF8, rSTR2 + cmpld cr7, rWORD1, rWORD2 + b L(dP1e) + /* Remainder is 16 */ +@@ -123,15 +153,8 @@ L(dPs2): + cmpld cr6, rWORD5, rWORD6 + blt cr7, L(dP2x) + /* Do something useful in this cycle since we have to branch anyway. */ +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD7, 8(rSTR1) +- ld rWORD8, 8(rSTR2) +-#endif ++ LD rWORD7, rOFF8, rSTR1 ++ LD rWORD8, rOFF8, rSTR2 + cmpld cr5, rWORD7, rWORD8 + b L(dP2e) + /* Remainder is 24 */ +@@ -173,72 +196,43 @@ L(dP1): + change any on the early exit path. The key here is the non-early + exit path only cares about the condition code (cr5), not about which + register pair was used. */ +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 0(rSTR1) +- ld rWORD6, 0(rSTR2) +-#endif ++ LD rWORD5, 0, rSTR1 ++ LD rWORD6, 0, rSTR2 + cmpld cr5, rWORD5, rWORD6 + blt cr7, L(dP1x) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD1, rOFF8, rSTR1 ++ LD rWORD2, rOFF8, rSTR2 + cmpld cr7, rWORD1, rWORD2 + L(dP1e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 16(rSTR1) +- ld rWORD4, 16(rSTR2) +-#endif ++ LD rWORD3, rOFF16, rSTR1 ++ LD rWORD4, rOFF16, rSTR2 + cmpld cr1, rWORD3, rWORD4 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 24(rSTR1) +- ld rWORD6, 24(rSTR2) +-#endif ++ LD rWORD5, rOFF24, rSTR1 ++ LD rWORD6, rOFF24, rSTR2 + cmpld cr6, rWORD5, rWORD6 + bne cr5, L(dLcr5x) + bne cr7, L(dLcr7x) + +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ldu rWORD7, 32(rSTR1) +- ldu rWORD8, 32(rSTR2) +-#endif ++ LD rWORD7, rOFF32, rSTR1 ++ LD rWORD8, rOFF32, rSTR2 ++ addi rSTR1, rSTR1, 32 ++ addi rSTR2, rSTR2, 32 + bne cr1, L(dLcr1) + cmpld cr5, rWORD7, rWORD8 + bdnz L(dLoop) + bne cr6, L(dLcr6) +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + .align 3 + L(dP1x): + sldi. r12, rN, 3 + bne cr5, L(dLcr5x) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne L(d00) ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 0 + blr + +@@ -246,79 +240,41 @@ L(dP1x): + .align 4 + L(dP2): + mtctr r0 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 0(rSTR1) +- ld rWORD6, 0(rSTR2) +-#endif ++ LD rWORD5, 0, rSTR1 ++ LD rWORD6, 0, rSTR2 + cmpld cr6, rWORD5, rWORD6 + blt cr7, L(dP2x) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD7, 8(rSTR1) +- ld rWORD8, 8(rSTR2) +-#endif ++ LD rWORD7, rOFF8, rSTR1 ++ LD rWORD8, rOFF8, rSTR2 + cmpld cr5, rWORD7, rWORD8 + L(dP2e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 16(rSTR1) +- ld rWORD2, 16(rSTR2) +-#endif ++ LD rWORD1, rOFF16, rSTR1 ++ LD rWORD2, rOFF16, rSTR2 + cmpld cr7, rWORD1, rWORD2 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 24(rSTR1) +- ld rWORD4, 24(rSTR2) +-#endif ++ LD rWORD3, rOFF24, rSTR1 ++ LD rWORD4, rOFF24, rSTR2 + cmpld cr1, rWORD3, rWORD4 +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +-#endif + bne cr6, L(dLcr6) + bne cr5, L(dLcr5) + b L(dLoop2) +-/* Again we are on a early exit path (16-23 byte compare), we want to +- only use volatile registers and avoid restoring non-volatile +- registers. */ + .align 4 + L(dP2x): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 8(rSTR1) +- ld rWORD4, 8(rSTR2) +-#endif ++ LD rWORD3, rOFF8, rSTR1 ++ LD rWORD4, rOFF8, rSTR2 + cmpld cr1, rWORD3, rWORD4 + sldi. r12, rN, 3 + bne cr6, L(dLcr6x) +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +-#endif + bne cr1, L(dLcr1x) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne L(d00) ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 0 + blr + +@@ -326,52 +282,22 @@ L(dP2x): + .align 4 + L(dP3): + mtctr r0 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 0(rSTR1) +- ld rWORD4, 0(rSTR2) +-#endif ++ LD rWORD3, 0, rSTR1 ++ LD rWORD4, 0, rSTR2 + cmpld cr1, rWORD3, rWORD4 + L(dP3e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 8(rSTR1) +- ld rWORD6, 8(rSTR2) +-#endif ++ LD rWORD5, rOFF8, rSTR1 ++ LD rWORD6, rOFF8, rSTR2 + cmpld cr6, rWORD5, rWORD6 + blt cr7, L(dP3x) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD7, 16(rSTR1) +- ld rWORD8, 16(rSTR2) +-#endif ++ LD rWORD7, rOFF16, rSTR1 ++ LD rWORD8, rOFF16, rSTR2 + cmpld cr5, rWORD7, rWORD8 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 24(rSTR1) +- ld rWORD2, 24(rSTR2) +-#endif ++ LD rWORD1, rOFF24, rSTR1 ++ LD rWORD2, rOFF24, rSTR2 + cmpld cr7, rWORD1, rWORD2 +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 +-#endif + bne cr1, L(dLcr1) + bne cr6, L(dLcr6) + b L(dLoop1) +@@ -380,26 +306,21 @@ L(dP3e): + registers. */ + .align 4 + L(dP3x): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 16(rSTR1) +- ld rWORD2, 16(rSTR2) +-#endif ++ LD rWORD1, rOFF16, rSTR1 ++ LD rWORD2, rOFF16, rSTR2 + cmpld cr7, rWORD1, rWORD2 + sldi. r12, rN, 3 + bne cr1, L(dLcr1x) +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 +-#endif + bne cr6, L(dLcr6x) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ + bne cr7, L(dLcr7x) + bne L(d00) ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 0 + blr + +@@ -407,46 +328,20 @@ L(dP3x): + .align 4 + L(dP4): + mtctr r0 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 0(rSTR1) +- ld rWORD2, 0(rSTR2) +-#endif ++ LD rWORD1, 0, rSTR1 ++ LD rWORD2, 0, rSTR2 + cmpld cr7, rWORD1, rWORD2 + L(dP4e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 8(rSTR1) +- ld rWORD4, 8(rSTR2) +-#endif ++ LD rWORD3, rOFF8, rSTR1 ++ LD rWORD4, rOFF8, rSTR2 + cmpld cr1, rWORD3, rWORD4 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 16(rSTR1) +- ld rWORD6, 16(rSTR2) +-#endif ++ LD rWORD5, rOFF16, rSTR1 ++ LD rWORD6, rOFF16, rSTR2 + cmpld cr6, rWORD5, rWORD6 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ldu rWORD7, 24(rSTR1) +- ldu rWORD8, 24(rSTR2) +-#endif ++ LD rWORD7, rOFF24, rSTR1 ++ LD rWORD8, rOFF24, rSTR2 ++ addi rSTR1, rSTR1, 24 ++ addi rSTR2, rSTR2, 24 + cmpld cr5, rWORD7, rWORD8 + bne cr7, L(dLcr7) + bne cr1, L(dLcr1) +@@ -454,51 +349,25 @@ L(dP4e): + /* This is the primary loop */ + .align 4 + L(dLoop): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD1, rOFF8, rSTR1 ++ LD rWORD2, rOFF8, rSTR2 + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(dLcr6) + L(dLoop1): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 16(rSTR1) +- ld rWORD4, 16(rSTR2) +-#endif ++ LD rWORD3, rOFF16, rSTR1 ++ LD rWORD4, rOFF16, rSTR2 + cmpld cr6, rWORD5, rWORD6 + bne cr5, L(dLcr5) + L(dLoop2): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 24(rSTR1) +- ld rWORD6, 24(rSTR2) +-#endif ++ LD rWORD5, rOFF24, rSTR1 ++ LD rWORD6, rOFF24, rSTR2 + cmpld cr5, rWORD7, rWORD8 + bne cr7, L(dLcr7) + L(dLoop3): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ldu rWORD7, 32(rSTR1) +- ldu rWORD8, 32(rSTR2) +-#endif ++ LD rWORD7, rOFF32, rSTR1 ++ LD rWORD8, rOFF32, rSTR2 ++ addi rSTR1, rSTR1, 32 ++ addi rSTR2, rSTR2, 32 + bne cr1, L(dLcr1) + cmpld cr7, rWORD1, rWORD2 + bdnz L(dLoop) +@@ -519,62 +388,75 @@ L(d14): + sldi. r12, rN, 3 + bne cr5, L(dLcr5) + L(d04): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + subfic rN, r12, 64 /* Shift count is 64 - (rN * 8). */ +- beq L(zeroLength) ++ beq L(duzeroLength) + /* At this point we have a remainder of 1 to 7 bytes to compare. Since + we are aligned it is safe to load the whole double word, and use + shift right double to eliminate bits beyond the compare length. */ + L(d00): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD1, rOFF8, rSTR1 ++ LD rWORD2, rOFF8, rSTR2 + srd rWORD1, rWORD1, rN + srd rWORD2, rWORD2, rN + cmpld cr7, rWORD1, rWORD2 + bne cr7, L(dLcr7x) ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 0 + blr + + .align 4 + L(dLcr7): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + L(dLcr7x): ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 1 + bgtlr cr7 + li rRTN, -1 + blr + .align 4 + L(dLcr1): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + L(dLcr1x): ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 1 + bgtlr cr1 + li rRTN, -1 + blr + .align 4 + L(dLcr6): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + L(dLcr6x): ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 1 + bgtlr cr6 + li rRTN, -1 + blr + .align 4 + L(dLcr5): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + L(dLcr5x): ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 1 + bgtlr cr5 + li rRTN, -1 +@@ -583,10 +465,6 @@ L(dLcr5x): + .align 4 + L(bytealigned): + mtctr rN +-#if 0 +-/* Huh? We've already branched on cr6! */ +- beq cr6, L(zeroLength) +-#endif + + /* We need to prime this loop. This loop is swing modulo scheduled + to avoid pipe delays. The dependent instruction latencies (load to +@@ -685,6 +563,7 @@ L(b11): + L(bx12): + sub rRTN, rWORD1, rWORD2 + blr ++ + .align 4 + L(zeroLength): + li rRTN, 0 +@@ -705,42 +584,36 @@ L(zeroLength): + we need to adjust the length (rN) and special case the loop + versioning for the first DW. This ensures that the loop count is + correct and the first DW (shifted) is in the expected resister pair. */ +-#define rSHL r29 /* Unaligned shift left count. */ +-#define rSHR r28 /* Unaligned shift right count. */ +-#define rWORD8_SHIFT r27 /* Left rotation temp for rWORD2. */ +-#define rWORD2_SHIFT r26 /* Left rotation temp for rWORD4. */ +-#define rWORD4_SHIFT r25 /* Left rotation temp for rWORD6. */ +-#define rWORD6_SHIFT r24 /* Left rotation temp for rWORD8. */ + L(unaligned): +- std rSHL, -24(r1) +- cfi_offset(rSHL, -24) ++ std rSHL, rSHLSAVE(r1) ++ cfi_offset(rSHL, rSHLSAVE) + clrldi rSHL, rSTR2, 61 + beq cr6, L(duzeroLength) +- std rSHR, -32(r1) +- cfi_offset(rSHR, -32) ++ std rSHR, rSHRSAVE(r1) ++ cfi_offset(rSHR, rSHRSAVE) + beq cr5, L(DWunaligned) +- std rWORD8_SHIFT, -40(r1) +- cfi_offset(rWORD8_SHIFT, -40) ++ std rWORD8_SHIFT, rWORD8SHIFTSAVE(r1) ++ cfi_offset(rWORD8_SHIFT, rWORD8SHIFTSAVE) + /* Adjust the logical start of rSTR2 to compensate for the extra bits + in the 1st rSTR1 DW. */ + sub rWORD8_SHIFT, rSTR2, r12 + /* But do not attempt to address the DW before that DW that contains + the actual start of rSTR2. */ + clrrdi rSTR2, rSTR2, 3 +- std rWORD2_SHIFT, -48(r1) +- cfi_offset(rWORD2_SHIFT, -48) ++ std rWORD2_SHIFT, rWORD2SHIFTSAVE(r1) ++ cfi_offset(rWORD2_SHIFT, rWORD2SHIFTSAVE) + /* Compute the left/right shift counts for the unaligned rSTR2, + compensating for the logical (DW aligned) start of rSTR1. */ + clrldi rSHL, rWORD8_SHIFT, 61 + clrrdi rSTR1, rSTR1, 3 +- std rWORD4_SHIFT, -56(r1) +- cfi_offset(rWORD4_SHIFT, -56) ++ std rWORD4_SHIFT, rWORD4SHIFTSAVE(r1) ++ cfi_offset(rWORD4_SHIFT, rWORD4SHIFTSAVE) + sldi rSHL, rSHL, 3 + cmpld cr5, rWORD8_SHIFT, rSTR2 + add rN, rN, r12 + sldi rWORD6, r12, 3 +- std rWORD6_SHIFT, -64(r1) +- cfi_offset(rWORD6_SHIFT, -64) ++ std rWORD6_SHIFT, rWORD6SHIFTSAVE(r1) ++ cfi_offset(rWORD6_SHIFT, rWORD6SHIFTSAVE) + subfic rSHR, rSHL, 64 + srdi r0, rN, 5 /* Divide by 32 */ + andi. r12, rN, 24 /* Get the DW remainder */ +@@ -750,25 +623,13 @@ L(unaligned): + this may cross a page boundary and cause a page fault. */ + li rWORD8, 0 + blt cr5, L(dus0) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD8, 0, rSTR2 ++ LD rWORD8, 0, rSTR2 + addi rSTR2, rSTR2, 8 +-#else +- ld rWORD8, 0(rSTR2) +- addi rSTR2, rSTR2, 8 +-#endif + sld rWORD8, rWORD8, rSHL + + L(dus0): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 0(rSTR1) +- ld rWORD2, 0(rSTR2) +-#endif ++ LD rWORD1, 0, rSTR1 ++ LD rWORD2, 0, rSTR2 + cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 + srd r12, rWORD2, rSHR +@@ -796,12 +657,7 @@ L(dusP1): + beq L(duZeroReturn) + li r0, 0 + ble cr7, L(dutrim) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD2, rOFF8, rSTR2 + srd r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 16 */ +@@ -832,27 +688,21 @@ L(duPs4): + compare length is at least 8 bytes. */ + .align 4 + L(DWunaligned): +- std rWORD8_SHIFT, -40(r1) +- cfi_offset(rWORD8_SHIFT, -40) ++ std rWORD8_SHIFT, rWORD8SHIFTSAVE(r1) ++ cfi_offset(rWORD8_SHIFT, rWORD8SHIFTSAVE) + clrrdi rSTR2, rSTR2, 3 +- std rWORD2_SHIFT, -48(r1) +- cfi_offset(rWORD2_SHIFT, -48) ++ std rWORD2_SHIFT, rWORD2SHIFTSAVE(r1) ++ cfi_offset(rWORD2_SHIFT, rWORD2SHIFTSAVE) + srdi r0, rN, 5 /* Divide by 32 */ +- std rWORD4_SHIFT, -56(r1) +- cfi_offset(rWORD4_SHIFT, -56) ++ std rWORD4_SHIFT, rWORD4SHIFTSAVE(r1) ++ cfi_offset(rWORD4_SHIFT, rWORD4SHIFTSAVE) + andi. r12, rN, 24 /* Get the DW remainder */ +- std rWORD6_SHIFT, -64(r1) +- cfi_offset(rWORD6_SHIFT, -64) ++ std rWORD6_SHIFT, rWORD6SHIFTSAVE(r1) ++ cfi_offset(rWORD6_SHIFT, rWORD6SHIFTSAVE) + sldi rSHL, rSHL, 3 +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD6, 0, rSTR2 ++ LD rWORD6, 0, rSTR2 ++ LD rWORD8, rOFF8, rSTR2 + addi rSTR2, rSTR2, 8 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD6, 0(rSTR2) +- ldu rWORD8, 8(rSTR2) +-#endif + cmpldi cr1, r12, 16 + cmpldi cr7, rN, 32 + clrldi rN, rN, 61 +@@ -867,52 +717,26 @@ L(DWunaligned): + .align 4 + L(duP1): + srd r12, rWORD8, rSHR +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- addi rSTR1, rSTR1, 8 +-#else +- ld rWORD7, 0(rSTR1) +-#endif ++ LD rWORD7, 0, rSTR1 + sld rWORD8_SHIFT, rWORD8, rSHL + or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP1x) + L(duP1e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD1, rOFF8, rSTR1 ++ LD rWORD2, rOFF8, rSTR2 + cmpld cr5, rWORD7, rWORD8 + srd r0, rWORD2, rSHR + sld rWORD2_SHIFT, rWORD2, rSHL + or rWORD2, r0, rWORD8_SHIFT +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 16(rSTR1) +- ld rWORD4, 16(rSTR2) +-#endif ++ LD rWORD3, rOFF16, rSTR1 ++ LD rWORD4, rOFF16, rSTR2 + cmpld cr7, rWORD1, rWORD2 + srd r12, rWORD4, rSHR + sld rWORD4_SHIFT, rWORD4, rSHL + bne cr5, L(duLcr5) + or rWORD4, r12, rWORD2_SHIFT +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 24(rSTR1) +- ld rWORD6, 24(rSTR2) +-#endif ++ LD rWORD5, rOFF24, rSTR1 ++ LD rWORD6, rOFF24, rSTR2 + cmpld cr1, rWORD3, rWORD4 + srd r0, rWORD6, rSHR + sld rWORD6_SHIFT, rWORD6, rSHL +@@ -932,82 +756,47 @@ L(duP1x): + beq L(duZeroReturn) + li r0, 0 + ble cr7, L(dutrim) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD2, rOFF8, rSTR2 + srd r0, rWORD2, rSHR + b L(dutrim) + /* Remainder is 16 */ + .align 4 + L(duP2): + srd r0, rWORD8, rSHR +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- addi rSTR1, rSTR1, 8 +-#else +- ld rWORD5, 0(rSTR1) +-#endif ++ LD rWORD5, 0, rSTR1 + or rWORD6, r0, rWORD6_SHIFT + sld rWORD6_SHIFT, rWORD8, rSHL + L(duP2e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD7, 8(rSTR1) +- ld rWORD8, 8(rSTR2) +-#endif ++ LD rWORD7, rOFF8, rSTR1 ++ LD rWORD8, rOFF8, rSTR2 + cmpld cr6, rWORD5, rWORD6 + srd r12, rWORD8, rSHR + sld rWORD8_SHIFT, rWORD8, rSHL + or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP2x) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 16(rSTR1) +- ld rWORD2, 16(rSTR2) +-#endif ++ LD rWORD1, rOFF16, rSTR1 ++ LD rWORD2, rOFF16, rSTR2 + cmpld cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) + srd r0, rWORD2, rSHR + sld rWORD2_SHIFT, rWORD2, rSHL + or rWORD2, r0, rWORD8_SHIFT +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 24(rSTR1) +- ld rWORD4, 24(rSTR2) +-#endif ++ LD rWORD3, rOFF24, rSTR1 ++ LD rWORD4, rOFF24, rSTR2 + cmpld cr7, rWORD1, rWORD2 + bne cr5, L(duLcr5) + srd r12, rWORD4, rSHR + sld rWORD4_SHIFT, rWORD4, rSHL + or rWORD4, r12, rWORD2_SHIFT +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +-#endif + cmpld cr1, rWORD3, rWORD4 + b L(duLoop2) + .align 4 + L(duP2x): + cmpld cr5, rWORD7, rWORD8 +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 8 + addi rSTR2, rSTR2, 8 +-#endif + bne cr6, L(duLcr6) + sldi. rN, rN, 3 + bne cr5, L(duLcr5) +@@ -1015,12 +804,7 @@ L(duP2x): + beq L(duZeroReturn) + li r0, 0 + ble cr7, L(dutrim) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD2, rOFF8, rSTR2 + srd r0, rWORD2, rSHR + b L(dutrim) + +@@ -1028,73 +812,39 @@ L(duP2x): + .align 4 + L(duP3): + srd r12, rWORD8, rSHR +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- addi rSTR1, rSTR1, 8 +-#else +- ld rWORD3, 0(rSTR1) +-#endif ++ LD rWORD3, 0, rSTR1 + sld rWORD4_SHIFT, rWORD8, rSHL + or rWORD4, r12, rWORD6_SHIFT + L(duP3e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 8(rSTR1) +- ld rWORD6, 8(rSTR2) +-#endif ++ LD rWORD5, rOFF8, rSTR1 ++ LD rWORD6, rOFF8, rSTR2 + cmpld cr1, rWORD3, rWORD4 + srd r0, rWORD6, rSHR + sld rWORD6_SHIFT, rWORD6, rSHL + or rWORD6, r0, rWORD4_SHIFT +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD7, 16(rSTR1) +- ld rWORD8, 16(rSTR2) +-#endif ++ LD rWORD7, rOFF16, rSTR1 ++ LD rWORD8, rOFF16, rSTR2 + cmpld cr6, rWORD5, rWORD6 + bne cr1, L(duLcr1) + srd r12, rWORD8, rSHR + sld rWORD8_SHIFT, rWORD8, rSHL + or rWORD8, r12, rWORD6_SHIFT + blt cr7, L(duP3x) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 24(rSTR1) +- ld rWORD2, 24(rSTR2) +-#endif ++ LD rWORD1, rOFF24, rSTR1 ++ LD rWORD2, rOFF24, rSTR2 + cmpld cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) + srd r0, rWORD2, rSHR + sld rWORD2_SHIFT, rWORD2, rSHL + or rWORD2, r0, rWORD8_SHIFT +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 +-#endif + cmpld cr7, rWORD1, rWORD2 + b L(duLoop1) + .align 4 + L(duP3x): +-#ifndef __LITTLE_ENDIAN__ + addi rSTR1, rSTR1, 16 + addi rSTR2, rSTR2, 16 +-#endif +-#if 0 +-/* Huh? We've already branched on cr1! */ +- bne cr1, L(duLcr1) +-#endif + cmpld cr5, rWORD7, rWORD8 + bne cr6, L(duLcr6) + sldi. rN, rN, 3 +@@ -1103,12 +853,7 @@ L(duP3x): + beq L(duZeroReturn) + li r0, 0 + ble cr7, L(dutrim) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD2, rOFF8, rSTR2 + srd r0, rWORD2, rSHR + b L(dutrim) + +@@ -1117,51 +862,27 @@ L(duP3x): + L(duP4): + mtctr r0 + srd r0, rWORD8, rSHR +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- addi rSTR1, rSTR1, 8 +-#else +- ld rWORD1, 0(rSTR1) +-#endif ++ LD rWORD1, 0, rSTR1 + sld rWORD2_SHIFT, rWORD8, rSHL + or rWORD2, r0, rWORD6_SHIFT + L(duP4e): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 8(rSTR1) +- ld rWORD4, 8(rSTR2) +-#endif ++ LD rWORD3, rOFF8, rSTR1 ++ LD rWORD4, rOFF8, rSTR2 + cmpld cr7, rWORD1, rWORD2 + srd r12, rWORD4, rSHR + sld rWORD4_SHIFT, rWORD4, rSHL + or rWORD4, r12, rWORD2_SHIFT +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 16(rSTR1) +- ld rWORD6, 16(rSTR2) +-#endif ++ LD rWORD5, rOFF16, rSTR1 ++ LD rWORD6, rOFF16, rSTR2 + cmpld cr1, rWORD3, rWORD4 + bne cr7, L(duLcr7) + srd r0, rWORD6, rSHR + sld rWORD6_SHIFT, rWORD6, rSHL + or rWORD6, r0, rWORD4_SHIFT +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ldu rWORD7, 24(rSTR1) +- ldu rWORD8, 24(rSTR2) +-#endif ++ LD rWORD7, rOFF24, rSTR1 ++ LD rWORD8, rOFF24, rSTR2 ++ addi rSTR1, rSTR1, 24 ++ addi rSTR2, rSTR2, 24 + cmpld cr6, rWORD5, rWORD6 + bne cr1, L(duLcr1) + srd r12, rWORD8, rSHR +@@ -1172,60 +893,34 @@ L(duP4e): + /* This is the primary loop */ + .align 4 + L(duLoop): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD1, 8(rSTR1) +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD1, rOFF8, rSTR1 ++ LD rWORD2, rOFF8, rSTR2 + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(duLcr6) + srd r0, rWORD2, rSHR + sld rWORD2_SHIFT, rWORD2, rSHL + or rWORD2, r0, rWORD8_SHIFT + L(duLoop1): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD3, 0, rSTR1 +- ldbrx rWORD4, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD3, 16(rSTR1) +- ld rWORD4, 16(rSTR2) +-#endif ++ LD rWORD3, rOFF16, rSTR1 ++ LD rWORD4, rOFF16, rSTR2 + cmpld cr6, rWORD5, rWORD6 + bne cr5, L(duLcr5) + srd r12, rWORD4, rSHR + sld rWORD4_SHIFT, rWORD4, rSHL + or rWORD4, r12, rWORD2_SHIFT + L(duLoop2): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD5, 0, rSTR1 +- ldbrx rWORD6, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD5, 24(rSTR1) +- ld rWORD6, 24(rSTR2) +-#endif ++ LD rWORD5, rOFF24, rSTR1 ++ LD rWORD6, rOFF24, rSTR2 + cmpld cr5, rWORD7, rWORD8 + bne cr7, L(duLcr7) + srd r0, rWORD6, rSHR + sld rWORD6_SHIFT, rWORD6, rSHL + or rWORD6, r0, rWORD4_SHIFT + L(duLoop3): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD7, 0, rSTR1 +- ldbrx rWORD8, 0, rSTR2 +- addi rSTR1, rSTR1, 8 +- addi rSTR2, rSTR2, 8 +-#else +- ldu rWORD7, 32(rSTR1) +- ldu rWORD8, 32(rSTR2) +-#endif ++ LD rWORD7, rOFF32, rSTR1 ++ LD rWORD8, rOFF32, rSTR2 ++ addi rSTR1, rSTR1, 32 ++ addi rSTR2, rSTR2, 32 + cmpld cr7, rWORD1, rWORD2 + bne cr1, L(duLcr1) + srd r12, rWORD8, rSHR +@@ -1234,10 +929,6 @@ L(duLoop3): + bdnz L(duLoop) + + L(duL4): +-#if 0 +-/* Huh? We've already branched on cr1! */ +- bne cr1, L(duLcr1) +-#endif + cmpld cr1, rWORD3, rWORD4 + bne cr6, L(duLcr6) + cmpld cr6, rWORD5, rWORD6 +@@ -1264,99 +955,102 @@ L(du14): + beq L(duZeroReturn) + li r0, 0 + ble cr7, L(dutrim) +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD2, 0, rSTR2 +- addi rSTR2, rSTR2, 8 +-#else +- ld rWORD2, 8(rSTR2) +-#endif ++ LD rWORD2, rOFF8, rSTR2 + srd r0, rWORD2, rSHR + .align 4 + L(dutrim): +-#ifdef __LITTLE_ENDIAN__ +- ldbrx rWORD1, 0, rSTR1 +-#else +- ld rWORD1, 8(rSTR1) +-#endif ++ LD rWORD1, rOFF8, rSTR1 + ld rWORD8, -8(r1) + subfic rN, rN, 64 /* Shift count is 64 - (rN * 8). */ + or rWORD2, r0, rWORD8_SHIFT +- ld rWORD7, -16(r1) +- ld rSHL, -24(r1) ++ ld rWORD7, rWORD7SAVE(r1) ++ ld rSHL, rSHLSAVE(r1) + srd rWORD1, rWORD1, rN + srd rWORD2, rWORD2, rN +- ld rSHR, -32(r1) +- ld rWORD8_SHIFT, -40(r1) ++ ld rSHR, rSHRSAVE(r1) ++ ld rWORD8_SHIFT, rWORD8SHIFTSAVE(r1) + li rRTN, 0 + cmpld cr7, rWORD1, rWORD2 +- ld rWORD2_SHIFT, -48(r1) +- ld rWORD4_SHIFT, -56(r1) ++ ld rWORD2_SHIFT, rWORD2SHIFTSAVE(r1) ++ ld rWORD4_SHIFT, rWORD4SHIFTSAVE(r1) + beq cr7, L(dureturn24) + li rRTN, 1 +- ld rWORD6_SHIFT, -64(r1) ++ ld rWORD6_SHIFT, rWORD6SHIFTSAVE(r1) ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + bgtlr cr7 + li rRTN, -1 + blr + .align 4 + L(duLcr7): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + li rRTN, 1 + bgt cr7, L(dureturn29) +- ld rSHL, -24(r1) +- ld rSHR, -32(r1) ++ ld rSHL, rSHLSAVE(r1) ++ ld rSHR, rSHRSAVE(r1) + li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr1): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + li rRTN, 1 + bgt cr1, L(dureturn29) +- ld rSHL, -24(r1) +- ld rSHR, -32(r1) ++ ld rSHL, rSHLSAVE(r1) ++ ld rSHR, rSHRSAVE(r1) + li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr6): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + li rRTN, 1 + bgt cr6, L(dureturn29) +- ld rSHL, -24(r1) +- ld rSHR, -32(r1) ++ ld rSHL, rSHLSAVE(r1) ++ ld rSHR, rSHRSAVE(r1) + li rRTN, -1 + b L(dureturn27) + .align 4 + L(duLcr5): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + li rRTN, 1 + bgt cr5, L(dureturn29) +- ld rSHL, -24(r1) +- ld rSHR, -32(r1) ++ ld rSHL, rSHLSAVE(r1) ++ ld rSHR, rSHRSAVE(r1) + li rRTN, -1 + b L(dureturn27) ++ + .align 3 + L(duZeroReturn): + li rRTN, 0 + .align 4 + L(dureturn): +- ld rWORD8, -8(r1) +- ld rWORD7, -16(r1) ++ ld rWORD8, rWORD8SAVE(r1) ++ ld rWORD7, rWORD7SAVE(r1) + L(dureturn29): +- ld rSHL, -24(r1) +- ld rSHR, -32(r1) ++ ld rSHL, rSHLSAVE(r1) ++ ld rSHR, rSHRSAVE(r1) + L(dureturn27): +- ld rWORD8_SHIFT, -40(r1) +-L(dureturn26): +- ld rWORD2_SHIFT, -48(r1) +-L(dureturn25): +- ld rWORD4_SHIFT, -56(r1) ++ ld rWORD8_SHIFT, rWORD8SHIFTSAVE(r1) ++ ld rWORD2_SHIFT, rWORD2SHIFTSAVE(r1) ++ ld rWORD4_SHIFT, rWORD4SHIFTSAVE(r1) + L(dureturn24): +- ld rWORD6_SHIFT, -64(r1) ++ ld rWORD6_SHIFT, rWORD6SHIFTSAVE(r1) ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + blr ++ + L(duzeroLength): ++ ld rOFF8, rOFF8SAVE(r1) ++ ld rOFF16, rOFF16SAVE(r1) ++ ld rOFF24, rOFF24SAVE(r1) ++ ld rOFF32, rOFF32SAVE(r1) + li rRTN, 0 + blr diff --git a/SOURCES/glibc-rh1240351-2.patch b/SOURCES/glibc-rh1240351-2.patch new file mode 100644 index 00000000..b557f23f --- /dev/null +++ b/SOURCES/glibc-rh1240351-2.patch @@ -0,0 +1,231 @@ + Backport of: + commit 487972aea52004f604c2878c8c9d3e77670f2c32 + Author: Adhemerval Zanella + Date: Thu Feb 27 09:43:51 2014 -0600 + + PowerPC: Optimized isnan/isnanf for POWER8 + + This patch add a optimized isnan/isnanf implementation for POWER8 + using the new Move From VSR Doubleword instruction to gains some + cycles from FP to GRP register move. + + ChangeLog: + 2014-02-27 Adhemerval Zanella + + * sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h (INIT_ARCH): + Add hwcap2 initialization. + * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add isnan power8 + implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S: New file: + POWER8 isnan ifunc implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c (__isnan): Add + POWER8 implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c (__isnanf): + Likewise. + * sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S: New file: + POWER8 isnan implementation. + * sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S: New file. + +diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +index 51a34f2..72d720d 100644 +--- a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h ++++ b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +@@ -36,6 +36,7 @@ + and fills the previous ones. */ + #define INIT_ARCH() \ + unsigned long int hwcap = __GLRO(dl_hwcap); \ ++ unsigned long int __attribute__((unused)) hwcap2 = __GLRO(dl_hwcap2); \ + if (hwcap & PPC_FEATURE_ARCH_2_06) \ + hwcap |= PPC_FEATURE_ARCH_2_05 | \ + PPC_FEATURE_POWER5_PLUS | \ +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 1e04f21..4cd1c5d 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -4,7 +4,7 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \ + s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ + s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \ +- s_modff-power5+ s_modff-ppc64 ++ s_modff-power5+ s_modff-ppc64 s_isnan-power8 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +@@ -21,7 +21,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \ + s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \ + s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \ +- e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 ++ e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \ ++ s_isnan-power8 + + CFLAGS-s_logbf-power7.c = -mcpu=power7 + CFLAGS-s_logbl-power7.c = -mcpu=power7 +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S +new file mode 100644 +index 0000000..c176d5a +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER7 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __isnan __isnan_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c +index 0de833e..65a5ca0 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c +@@ -26,16 +26,19 @@ extern __typeof (__isnan) __isnan_power5 attribute_hidden; + extern __typeof (__isnan) __isnan_power6 attribute_hidden; + extern __typeof (__isnan) __isnan_power6x attribute_hidden; + extern __typeof (__isnan) __isnan_power7 attribute_hidden; ++extern __typeof (__isnan) __isnan_power8 attribute_hidden; + + libc_ifunc (__isnan, +- (hwcap & PPC_FEATURE_ARCH_2_06) +- ? __isnan_power7 : +- (hwcap & PPC_FEATURE_POWER6_EXT) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __isnan_power8 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isnan_power7 : ++ (hwcap & PPC_FEATURE_POWER6_EXT) + ? __isnan_power6x : +- (hwcap & PPC_FEATURE_ARCH_2_05) +- ? __isnan_power6 : +- (hwcap & PPC_FEATURE_POWER5) +- ? __isnan_power5 ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __isnan_power6 : ++ (hwcap & PPC_FEATURE_POWER5) ++ ? __isnan_power5 + : __isnan_ppc64); + + weak_alias (__isnan, isnan) +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c +index b237455..eb68a50 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c +@@ -25,16 +25,19 @@ extern __typeof (__isnanf) __isnan_power5 attribute_hidden; + extern __typeof (__isnanf) __isnan_power6 attribute_hidden; + extern __typeof (__isnanf) __isnan_power6x attribute_hidden; + extern __typeof (__isnanf) __isnan_power7 attribute_hidden; ++extern __typeof (__isnanf) __isnan_power8 attribute_hidden; + + libc_ifunc (__isnanf, +- (hwcap & PPC_FEATURE_ARCH_2_06) +- ? __isnan_power7 : +- (hwcap & PPC_FEATURE_POWER6_EXT) +- ? __isnan_power6x : +- (hwcap & PPC_FEATURE_ARCH_2_05) +- ? __isnan_power6 : +- (hwcap & PPC_FEATURE_POWER5) +- ? __isnan_power5 ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __isnan_power8 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isnan_power7 : ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __isnan_power6x : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __isnan_power6 : ++ (hwcap & PPC_FEATURE_POWER5) ++ ? __isnan_power5 + : __isnan_ppc64); + + weak_alias (__isnanf, isnanf) +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S +new file mode 100644 +index 0000000..c1ca9a5 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S +@@ -0,0 +1,53 @@ ++/* isnan(). PowerPC64/POWER8 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define MFVSRD_R3_V1 .byte 0x7c,0x23,0x00,0x66 /* mfvsrd r3,vs1 */ ++ ++/* int [r3] __isnan([f1] x) */ ++ ++EALIGN (__isnan, 4, 0) ++ CALL_MCOUNT 0 ++ MFVSRD_R3_V1 ++ lis r9,0x7ff0 ++ clrldi r3,r3,1 /* r3 = r3 & 0x8000000000000000 */ ++ rldicr r9,r9,32,31 /* r9 = (r9 << 32) & 0xffffffff */ ++ subf r3,r3,r9 ++ rldicl r3,r3,1,63 ++ blr ++END (__isnan) ++ ++/* It turns out that the 'double' version will also always work for ++ single-precision. */ ++strong_alias (__isnan, __isnanf) ++hidden_def (__isnanf) ++weak_alias (__isnanf, isnanf) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__isnan, __isnanl) ++weak_alias (__isnan, isnanl) ++#endif ++ ++#ifndef IS_IN_libm ++# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) ++compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); ++compat_symbol (libc, isnan, isnanl, GLIBC_2_0); ++# endif ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S +new file mode 100644 +index 0000000..b48c85e +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S +@@ -0,0 +1 @@ ++/* This function uses the same code as s_isnan.S. */ diff --git a/SOURCES/glibc-rh1240351-3.patch b/SOURCES/glibc-rh1240351-3.patch new file mode 100644 index 00000000..0fb35148 --- /dev/null +++ b/SOURCES/glibc-rh1240351-3.patch @@ -0,0 +1,667 @@ + Backport of the following patches: + + commit 4393fc119c34e97519b9b7a4fc94066b283be452 + Author: Adhemerval Zanella + Date: Thu Feb 27 09:45:41 2014 -0600 + + PowerPC: Optimized isinf/isinff for POWER8 + + This patch add a optimized isinf/isinff implementation for POWER8 + using the new Move From VSR Doubleword instruction to gains some + cycles from FP to GRP register move. + + ChangeLog: + 2014-02-27 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add isinf power8 + implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S: New file: + POWER8 isinf ifunc implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c (__isinf): Add + POWER8 implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c (__isinff): + Likewise. + * sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S: New file: + POWER8 isinf implementation. + * sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S: New file. + + commit cac626d60a863e48ab75417064984769e58c5719 + Author: Adhemerval Zanella + Date: Thu Feb 27 09:46:46 2014 -0600 + + PowerPC: Optimized finite/finitef for POWER8 + + This patch add a optimized finite/finitef implementation for POWER8 + using the new Move From VSR Doubleword instruction to gains some + cycles from FP to GRP register move. + + ChangeLog: + 2014-02-27 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add finite power8 + implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S: New file: + POWER8 finite ifunc implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c (__finite): Add + POWER8 implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c (__finitef): + Likewise. + * sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S: New file: + POWER8 finite implementation. + * sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S: New file. + + commit 1ad8950a3ea4056ed343d681b5146f4b4aa27e10 + Author: Adhemerval Zanella + Date: Tue Feb 18 09:29:29 2014 -0500 + + PowerPC: llrint/llrintf POWER8 optimization + + This patch add a optimized llrint/llrintf implementation for POWER8 + using the new Move From VSR Doubleword instruction to gains some + cycles from FP to GRP register move. + + ChangeLog: + 2014-02-27 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add llrint power8 + implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S: New file: + POWER8 llrint ifunc implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c (__lllrint): Add + POWER8 implementation. + * sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S: New file: + POWER8 llrint implementation. + + commit fe13a20c37578f08ce393ccaeb45caeb48815ca5 + Author: Adhemerval Zanella + Date: Mon Feb 17 10:44:08 2014 -0600 + + PowerPC: llround/llroundf POWER8 optimization + + This patch add a optimized llround/llroundf implementation for POWER8 + using the new Move From VSR Doubleword instruction to gains some + cycles from FP to GRP register move. + + ChangeLog: + 2014-02-27 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add llround power8 + implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S: New file: + POWER8 llround ifunc implementation. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c (__lllround): Add + POWER8 implementation. + * sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S: New file: + POWER8 llround implementation. + + commit 757d9dd5c3efa56fac75965abc014faaae7b7895 + Author: Adhemerval Zanella + Date: Mon Mar 31 08:00:38 2014 -0500 + + PowerPC: Fix little endian enconding for mfvsrd + + This patch fixes the MFVSRD_R3_V1 macro that encodes 'mfvsrd r3,vs1' + (to support old binutils) for little endian. + +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 4cd1c5d..3e2127b 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -4,7 +4,8 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \ + s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ + s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \ +- s_modff-power5+ s_modff-ppc64 s_isnan-power8 ++ s_modff-power5+ s_modff-ppc64 s_isnan-power8 \ ++ s_isinf-power8 s_finite-power8 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +@@ -22,7 +23,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \ + s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \ + e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \ +- s_isnan-power8 ++ s_isnan-power8 s_isinf-power8 s_finite-power8 \ ++ s_llrint-power8 s_llround-power8 + + CFLAGS-s_logbf-power7.c = -mcpu=power7 + CFLAGS-s_logbl-power7.c = -mcpu=power7 +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S +new file mode 100644 +index 0000000..3b9071f +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER7 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __finite __finite_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c +index f79a93e..b9e908d 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c +@@ -23,10 +23,13 @@ + + extern __typeof (__finite) __finite_ppc64 attribute_hidden; + extern __typeof (__finite) __finite_power7 attribute_hidden; ++extern __typeof (__finite) __finite_power8 attribute_hidden; + + libc_ifunc (__finite, +- (hwcap & PPC_FEATURE_ARCH_2_06) +- ? __finite_power7 ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __finite_power8 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __finite_power7 + : __finite_ppc64); + + weak_alias (__finite, finite) +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c +index a7243b5..30b34bc 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c +@@ -23,10 +23,13 @@ + extern __typeof (__finitef) __finitef_ppc64 attribute_hidden; + /* The double-precision version also works for single-precision. */ + extern __typeof (__finitef) __finite_power7 attribute_hidden; ++extern __typeof (__finitef) __finite_power8 attribute_hidden; + + libc_ifunc (__finitef, +- (hwcap & PPC_FEATURE_ARCH_2_06) +- ? __finite_power7 ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __finite_power8 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __finite_power7 + : __finitef_ppc64); + + weak_alias (__finitef, finitef) +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S +new file mode 100644 +index 0000000..979816e +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S +@@ -0,0 +1,33 @@ ++/* isinf(). PowerPC64/POWER8 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, alias, ver) ++ ++#define __isinf __isinf_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c +index 1ee230b..e349a06 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c +@@ -23,10 +23,13 @@ + + extern __typeof (__isinf) __isinf_ppc64 attribute_hidden; + extern __typeof (__isinf) __isinf_power7 attribute_hidden; ++extern __typeof (__isinf) __isinf_power8 attribute_hidden; + + libc_ifunc (__isinf, +- (hwcap & PPC_FEATURE_ARCH_2_06) +- ? __isinf_power7 ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __isinf_power8 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isinf_power7 + : __isinf_ppc64); + + weak_alias (__isinf, isinf) +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c +index 1336feb..71da7a3 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c +@@ -24,10 +24,13 @@ + extern __typeof (__isinff) __isinff_ppc64 attribute_hidden; + /* The double-precision version also works for single-precision. */ + extern __typeof (__isinff) __isinf_power7 attribute_hidden; ++extern __typeof (__isinff) __isinf_power8 attribute_hidden; + + libc_ifunc (__isinff, +- (hwcap & PPC_FEATURE_ARCH_2_06) +- ? __isinf_power7 ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __isinf_power8 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isinf_power7 + : __isinff_ppc64); + + weak_alias (__isinff, isinff) +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S +new file mode 100644 +index 0000000..3962b7d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S +@@ -0,0 +1,31 @@ ++/* Round double to long int. PowerPC64/POWER6X default version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __llrint __llrint_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c +index 5818b53..cf1b2e4 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c +@@ -30,10 +30,13 @@ + + extern __typeof (__llrint) __llrint_ppc64 attribute_hidden; + extern __typeof (__llrint) __llrint_power6x attribute_hidden; ++extern __typeof (__llrint) __llrint_power8 attribute_hidden; + + libc_ifunc (__llrint, +- (hwcap & PPC_FEATURE_POWER6_EXT) +- ? __llrint_power6x ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __llrint_power8 : ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __llrint_power6x + : __llrint_ppc64); + + weak_alias (__llrint, llrint) +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S +new file mode 100644 +index 0000000..41c61a1 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S +@@ -0,0 +1,31 @@ ++/* llround(). PowerPC64 default version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, alias, ver) ++ ++#define __llround __llround_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c +index a4d1bf3..7dba17e 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c +@@ -27,12 +27,15 @@ + extern __typeof (__llround) __llround_ppc64 attribute_hidden; + extern __typeof (__llround) __llround_power5plus attribute_hidden; + extern __typeof (__llround) __llround_power6x attribute_hidden; ++extern __typeof (__llround) __llround_power8 attribute_hidden; + + libc_ifunc (__llround, +- (hwcap & PPC_FEATURE_POWER6_EXT) +- ? __llround_power6x : +- (hwcap & PPC_FEATURE_POWER5_PLUS) +- ? __llround_power5plus ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __llround_power8 : ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __llround_power6x : ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __llround_power5plus + : __llround_ppc64); + + weak_alias (__llround, llround) +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S +new file mode 100644 +index 0000000..3e98126 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S +@@ -0,0 +1,56 @@ ++/* isfinite(). PowerPC64/POWER8 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define MFVSRD_R3_V1 .long 0x7c230066 /* mfvsrd r3,vs1 */ ++ ++/* int [r3] __finite ([fp1] x) */ ++ ++EALIGN (__finite, 4, 0) ++ CALL_MCOUNT 0 ++ MFVSRD_R3_V1 ++ lis r9,0x8010 ++ clrldi r3,r3,1 /* r3 = r3 & 0x8000000000000000 */ ++ rldicr r9,r9,32,31 /* r9 = (r9 << 32) & 0xffffffff */ ++ add r3,r3,r9 ++ rldicl r3,r3,1,63 ++ blr ++END (__finite) ++ ++hidden_def (__finite) ++weak_alias (__finite, finite) ++ ++/* It turns out that the 'double' version will also always work for ++ single-precision. */ ++strong_alias (__finite, __finitef) ++hidden_def (__finitef) ++weak_alias (__finitef, finitef) ++ ++#ifdef IS_IN_libm ++# if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) ++compat_symbol (libm, __finite, __finitel, GLIBC_2_0) ++compat_symbol (libm, finite, finitel, GLIBC_2_0) ++# endif ++#else ++# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0) ++compat_symbol (libc, __finite, __finitel, GLIBC_2_0); ++compat_symbol (libc, finite, finitel, GLIBC_2_0); ++# endif ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S +new file mode 100644 +index 0000000..54bd941 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S +@@ -0,0 +1 @@ ++/* This function uses the same code as s_finite.S. */ +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S +new file mode 100644 +index 0000000..125de39 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S +@@ -0,0 +1,61 @@ ++/* isinf(). PowerPC64/POWER8 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define MFVSRD_R3_V1 .long 0x7c230066 /* mfvsrd r3,vs1 */ ++ ++/* int [r3] __isinf([fp1] x) */ ++ ++EALIGN (__isinf, 4, 0) ++ CALL_MCOUNT 0 ++ MFVSRD_R3_V1 ++ lis r9,0x7ff0 /* r9 = 0x7ff0 */ ++ rldicl r10,r3,0,1 /* r10 = r3 & (0x8000000000000000) */ ++ sldi r9,r9,32 /* r9 = r9 << 52 */ ++ cmpd cr7,r10,r9 /* fp1 & 0x7ff0000000000000 ? */ ++ beq cr7,L(inf) ++ li r3,0 /* Not inf */ ++ blr ++L(inf): ++ sradi r3,r3,63 /* r3 = r3 >> 63 */ ++ ori r3,r3,1 /* r3 = r3 | 0x1 */ ++ blr ++END (__isinf) ++ ++hidden_def (__isinf) ++weak_alias (__isinf, isinf) ++ ++/* It turns out that the 'double' version will also always work for ++ single-precision. */ ++strong_alias (__isinf, __isinff) ++hidden_def (__isinff) ++weak_alias (__isinff, isinff) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__isinf, __isinfl) ++weak_alias (__isinf, isinfl) ++#endif ++ ++#ifndef IS_IN_libm ++# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) ++compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); ++compat_symbol (libc, isinf, isinfl, GLIBC_2_0); ++# endif ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S +new file mode 100644 +index 0000000..be759e0 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S +@@ -0,0 +1 @@ ++/* This function uses the same code as s_isinf.S. */ +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S +index c1ca9a5..cb96d03 100644 +--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S +@@ -19,8 +19,8 @@ + #include + #include + +-#define MFVSRD_R3_V1 .byte 0x7c,0x23,0x00,0x66 /* mfvsrd r3,vs1 */ +- ++#define MFVSRD_R3_V1 .long 0x7c230066 /* mfvsrd r3,vs1 */ ++ + /* int [r3] __isnan([f1] x) */ + + EALIGN (__isnan, 4, 0) +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S +new file mode 100644 +index 0000000..ce48d4e +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S +@@ -0,0 +1,45 @@ ++/* Round double to long int. POWER8 PowerPC64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define MFVSRD_R3_V1 .long 0x7c230066 /* mfvsrd r3,vs1 */ ++ ++/* long long int[r3] __llrint (double x[fp1]) */ ++ENTRY (__llrint) ++ CALL_MCOUNT 0 ++ fctid fp1,fp1 ++ MFVSRD_R3_V1 ++ blr ++END (__llrint) ++ ++strong_alias (__llrint, __lrint) ++weak_alias (__llrint, llrint) ++weak_alias (__lrint, lrint) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__llrint, __llrintl) ++weak_alias (__llrint, llrintl) ++strong_alias (__lrint, __lrintl) ++weak_alias (__lrint, lrintl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) ++compat_symbol (libm, __llrint, llrintl, GLIBC_2_1) ++compat_symbol (libm, __lrint, lrintl, GLIBC_2_1) ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S +new file mode 100644 +index 0000000..2aea234 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S +@@ -0,0 +1,47 @@ ++/* llround function. POWER8 PowerPC64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define MFVSRD_R3_V1 .long 0x7c230066 /* mfvsrd r3,vs1 */ ++ ++/* long long [r3] llround (float x [fp1]) */ ++ ++ENTRY (__llround) ++ CALL_MCOUNT 0 ++ frin fp1,fp1 /* Round to nearest +-0.5. */ ++ fctidz fp1,fp1 /* Convert To Integer DW round toward 0. */ ++ MFVSRD_R3_V1 ++ blr ++END (__llround) ++ ++strong_alias (__llround, __lround) ++weak_alias (__llround, llround) ++weak_alias (__lround, lround) ++ ++#ifdef NO_LONG_DOUBLE ++weak_alias (__llround, llroundl) ++strong_alias (__llround, __llroundl) ++weak_alias (__lround, lroundl) ++strong_alias (__lround, __lroundl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) ++compat_symbol (libm, __llround, llroundl, GLIBC_2_1) ++compat_symbol (libm, __lround, lroundl, GLIBC_2_1) ++#endif diff --git a/SOURCES/glibc-rh1240351-4.patch b/SOURCES/glibc-rh1240351-4.patch new file mode 100644 index 00000000..e49b53ed --- /dev/null +++ b/SOURCES/glibc-rh1240351-4.patch @@ -0,0 +1,741 @@ + Backport of the following patch as a prerequistite for + 96d6fd6c4060d739abb1822e7ad633af749532b2: + commit 69f13dbf06c6195de0ada8632271d58ca3cf55da + Author: Adhemerval Zanella + Date: Thu Sep 26 09:29:19 2013 -0500 + + PowerPC: strcpy/stpcpy optimization for PPC64/POWER7 + + This patch intends to unify both strcpy and stpcpy implementationsi + for PPC64 and PPC64/POWER7. The idead default powerpc64 implementation + is to provide both doubleword and word aligned memory access. + + For PPC64/POWER7 is also provide doubleword and word memory access, + remove the branch hints, use the cmpb instruction for compare + doubleword/words, and add an optimization for inputs of same alignment. + + ChangeLog: + + 2013-10-04 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/strcpy.S (strcpy): Add word load/store + to provide a boost for large inputs with word alignment. + * sysdeps/powerpc/powerpc64/stpcpy.S (__stpcpy): Rewrite + implementation based on optimized PPC64 strcpy. + * sysdeps/powerpc/powerpc64/power7/strcpy.S: New file: optimized + strcpy for PPC64/POWER7 based on both doubleword and word load/store. + * sysdeps/powerpc/powerpc64/power7/stpcpy.S: New file: optimized + stpcpy for PPC64/POWER7 based on PPC64/POWER7 strcpy. + +diff --git a/sysdeps/powerpc/powerpc64/power7/stpcpy.S b/sysdeps/powerpc/powerpc64/power7/stpcpy.S +new file mode 100644 +index 0000000..727dd06 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/stpcpy.S +@@ -0,0 +1,24 @@ ++/* Optimized stpcpy implementation for PowerPC64/POWER7. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_STPCPY ++#include ++ ++weak_alias (__stpcpy, stpcpy) ++libc_hidden_def (__stpcpy) ++libc_hidden_builtin_def (stpcpy) +diff --git a/sysdeps/powerpc/powerpc64/power7/strcpy.S b/sysdeps/powerpc/powerpc64/power7/strcpy.S +new file mode 100644 +index 0000000..5c341a1 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/strcpy.S +@@ -0,0 +1,274 @@ ++/* Optimized strcpy/stpcpy implementation for PowerPC64/POWER7. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Implements the function ++ ++ char * [r3] strcpy (char *dest [r3], const char *src [r4]) ++ ++ or ++ ++ char * [r3] strcpy (char *dest [r3], const char *src [r4]) ++ ++ if USE_AS_STPCPY is defined. It tries to use aligned memory accesses ++ when possible using the following algorithm: ++ ++ if (((((uintptr_t)dst & 0x7UL) == 0) && ((uintptr_t)src & 0x7UL) == 0)) ++ goto aligned_doubleword_copy; ++ if (((((uintptr_t)dst & 0x3UL) == 0) && ((uintptr_t)src & 0x3UL) == 0)) ++ goto aligned_word_copy; ++ if (((uintptr_t)dst & 0x7UL) == ((uintptr_t)src & 0x7UL)) ++ goto same_alignment; ++ goto unaligned; ++ ++ The aligned comparison are made using cmpb instructions. */ ++ ++#ifdef USE_AS_STPCPY ++# define FUNC_NAME __stpcpy ++#else ++# define FUNC_NAME strcpy ++#endif ++ ++ .machine power7 ++EALIGN (FUNC_NAME, 4, 0) ++ CALL_MCOUNT 2 ++ ++#define rTMP r0 ++#ifdef USE_AS_STPCPY ++#define rRTN r3 /* pointer to previous word/doubleword in dest */ ++#else ++#define rRTN r12 /* pointer to previous word/doubleword in dest */ ++#endif ++#define rSRC r4 /* pointer to previous word/doubleword in src */ ++#define rMASK r5 /* mask 0xffffffff | 0xffffffffffffffff */ ++#define rWORD r6 /* current word from src */ ++#define rALT r7 /* alternate word from src */ ++#define rRTNAL r8 /* alignment of return pointer */ ++#define rSRCAL r9 /* alignment of source pointer */ ++#define rALCNT r10 /* bytes to read to reach 8 bytes alignment */ ++#define rSUBAL r11 /* doubleword minus unaligned displacement */ ++ ++#ifndef USE_AS_STPCPY ++/* Save the dst pointer to use as return value. */ ++ mr rRTN, r3 ++#endif ++ or rTMP, rSRC, rRTN ++ clrldi. rTMP, rTMP, 61 ++ bne L(check_word_alignment) ++ b L(aligned_doubleword_copy) ++ ++L(same_alignment): ++/* Src and dst with same alignment: align both to doubleword. */ ++ mr rALCNT, rRTN ++ lbz rWORD, 0(rSRC) ++ subfic rSUBAL, rRTNAL, 8 ++ addi rRTN, rRTN, 1 ++ addi rSRC, rSRC, 1 ++ cmpdi cr7, rWORD, 0 ++ stb rWORD, 0(rALCNT) ++ beq cr7, L(s2) ++ ++ add rALCNT, rALCNT, rSUBAL ++ subf rALCNT, rRTN, rALCNT ++ addi rALCNT, rALCNT, 1 ++ mtctr rALCNT ++ b L(s1) ++ ++ .align 4 ++L(s0): ++ addi rSRC, rSRC, 1 ++ lbz rWORD, -1(rSRC) ++ cmpdi cr7, rWORD, 0 ++ stb rWORD, -1(rALCNT) ++ beqlr cr7 ++ mr rRTN, rALCNT ++L(s1): ++ addi rALCNT, rRTN,1 ++ bdnz L(s0) ++ b L(aligned_doubleword_copy) ++ .align 4 ++L(s2): ++ mr rRTN, rALCNT ++ blr ++ ++/* For doubleword aligned memory, operate using doubleword load and stores. */ ++ .align 4 ++L(aligned_doubleword_copy): ++ li rMASK, 0 ++ addi rRTN, rRTN, -8 ++ ld rWORD, 0(rSRC) ++ b L(g2) ++ ++ .align 4 ++L(g0): ldu rALT, 8(rSRC) ++ stdu rWORD, 8(rRTN) ++ cmpb rTMP, rALT, rMASK ++ cmpdi rTMP, 0 ++ bne L(g1) ++ ldu rWORD, 8(rSRC) ++ stdu rALT, 8(rRTN) ++L(g2): cmpb rTMP, rWORD, rMASK ++ cmpdi rTMP, 0 /* If rTMP is 0, no null's have been found. */ ++ beq L(g0) ++ ++ mr rALT, rWORD ++/* We've hit the end of the string. Do the rest byte-by-byte. */ ++L(g1): ++#ifdef __LITTLE_ENDIAN__ ++ extrdi. rTMP, rALT, 8, 56 ++ stbu rALT, 8(rRTN) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 48 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 40 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 32 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 24 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 16 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ extrdi. rTMP, rALT, 8, 8 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ extrdi rTMP, rALT, 8, 0 ++ stbu rTMP, 1(rRTN) ++#else ++ extrdi. rTMP, rALT, 8, 0 ++ stbu rTMP, 8(rRTN) ++ beqlr ++ extrdi. rTMP, rALT, 8, 8 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ extrdi. rTMP, rALT, 8, 16 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ extrdi. rTMP, rALT, 8, 24 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ extrdi. rTMP, rALT, 8, 32 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ extrdi. rTMP, rALT, 8, 40 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ extrdi. rTMP, rALT, 8, 48 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ stbu rALT, 1(rRTN) ++#endif ++ blr ++ ++L(check_word_alignment): ++ clrldi. rTMP, rTMP, 62 ++ beq L(aligned_word_copy) ++ rldicl rRTNAL, rRTN, 0, 61 ++ rldicl rSRCAL, rSRC, 0, 61 ++ cmpld cr7, rSRCAL, rRTNAL ++ beq cr7, L(same_alignment) ++ b L(unaligned) ++ ++/* For word aligned memory, operate using word load and stores. */ ++ .align 4 ++L(aligned_word_copy): ++ li rMASK, 0 ++ addi rRTN, rRTN, -4 ++ lwz rWORD, 0(rSRC) ++ b L(g5) ++ ++ .align 4 ++L(g3): lwzu rALT, 4(rSRC) ++ stwu rWORD, 4(rRTN) ++ cmpb rTMP, rALT, rMASK ++ cmpwi rTMP, 0 ++ bne L(g4) ++ lwzu rWORD, 4(rSRC) ++ stwu rALT, 4(rRTN) ++L(g5): cmpb rTMP, rWORD, rMASK ++ cmpwi rTMP, 0 /* If rTMP is 0, no null in word. */ ++ beq L(g3) ++ ++ mr rALT, rWORD ++/* We've hit the end of the string. Do the rest byte-by-byte. */ ++L(g4): ++#ifdef __LITTLE_ENDIAN__ ++ rlwinm. rTMP, rALT, 0, 24, 31 ++ stbu rALT, 4(rRTN) ++ beqlr- ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ rlwinm rTMP, rALT, 8, 24, 31 ++ stbu rTMP, 1(rRTN) ++#else ++ rlwinm. rTMP, rALT, 8, 24, 31 ++ stbu rTMP, 4(rRTN) ++ beqlr ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr ++ stbu rALT, 1(rRTN) ++#endif ++ blr ++ ++/* Oh well. In this case, we just do a byte-by-byte copy. */ ++ .align 4 ++L(unaligned): ++ lbz rWORD, 0(rSRC) ++ addi rRTN, rRTN, -1 ++ cmpdi rWORD, 0 ++ beq L(u2) ++ ++ .align 5 ++L(u0): lbzu rALT, 1(rSRC) ++ stbu rWORD, 1(rRTN) ++ cmpdi rALT, 0 ++ beq L(u1) ++ lbzu rWORD, 1(rSRC) ++ stbu rALT, 1(rRTN) ++ cmpdi rWORD, 0 ++ beq L(u2) ++ lbzu rALT, 1(rSRC) ++ stbu rWORD, 1(rRTN) ++ cmpdi rALT, 0 ++ beq L(u1) ++ lbzu rWORD, 1(rSRC) ++ stbu rALT, 1(rRTN) ++ cmpdi rWORD, 0 ++ bne L(u0) ++L(u2): stbu rWORD, 1(rRTN) ++ blr ++L(u1): stbu rALT, 1(rRTN) ++ blr ++END (FUNC_NAME) ++ ++#ifndef USE_AS_STPCPY ++libc_hidden_builtin_def (strcpy) ++#endif +diff --git a/sysdeps/powerpc/powerpc64/stpcpy.S b/sysdeps/powerpc/powerpc64/stpcpy.S +index d795b61..09aa3be 100644 +--- a/sysdeps/powerpc/powerpc64/stpcpy.S ++++ b/sysdeps/powerpc/powerpc64/stpcpy.S +@@ -1,5 +1,5 @@ + /* Optimized stpcpy implementation for PowerPC64. +- Copyright (C) 1997, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. ++ Copyright (C) 1997-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,123 +16,9 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +-#include ++#define USE_AS_STPCPY ++#include + +-/* See strlen.s for comments on how the end-of-string testing works. */ +- +-/* char * [r3] stpcpy (char *dest [r3], const char *src [r4]) */ +- +-EALIGN (BP_SYM (__stpcpy), 4, 0) +- CALL_MCOUNT 2 +- +-#define rTMP r0 +-#define rRTN r3 +-#if __BOUNDED_POINTERS__ +-# define rDEST r4 /* pointer to previous word in dest */ +-# define rSRC r5 /* pointer to previous word in src */ +-# define rLOW r11 +-# define rHIGH r12 +-#else +-# define rDEST r3 /* pointer to previous word in dest */ +-# define rSRC r4 /* pointer to previous word in src */ +-#endif +-#define rWORD r6 /* current word from src */ +-#define rFEFE r7 /* 0xfefefeff */ +-#define r7F7F r8 /* 0x7f7f7f7f */ +-#define rNEG r9 /* ~(word in src | 0x7f7f7f7f) */ +-#define rALT r10 /* alternate word from src */ +- +- CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH) +- CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH) +- STORE_RETURN_BOUNDS (rLOW, rHIGH) +- +- or rTMP, rSRC, rDEST +- clrldi. rTMP, rTMP, 62 +- addi rDEST, rDEST, -4 +- bne L(unaligned) +- +- lis rFEFE, -0x101 +- lis r7F7F, 0x7f7f +- lwz rWORD, 0(rSRC) +- addi rFEFE, rFEFE, -0x101 +- addi r7F7F, r7F7F, 0x7f7f +- b L(g2) +- +-L(g0): lwzu rALT, 4(rSRC) +- stwu rWORD, 4(rDEST) +- add rTMP, rFEFE, rALT +- nor rNEG, r7F7F, rALT +- and. rTMP, rTMP, rNEG +- bne- L(g1) +- lwzu rWORD, 4(rSRC) +- stwu rALT, 4(rDEST) +-L(g2): add rTMP, rFEFE, rWORD +- nor rNEG, r7F7F, rWORD +- and. rTMP, rTMP, rNEG +- beq+ L(g0) +- +- mr rALT, rWORD +-/* We've hit the end of the string. Do the rest byte-by-byte. */ +-L(g1): +-#ifdef __LITTLE_ENDIAN__ +- rlwinm. rTMP, rALT, 0, 24, 31 +- stbu rALT, 4(rDEST) +- beqlr- +- rlwinm. rTMP, rALT, 24, 24, 31 +- stbu rTMP, 1(rDEST) +- beqlr- +- rlwinm. rTMP, rALT, 16, 24, 31 +- stbu rTMP, 1(rDEST) +- beqlr- +- rlwinm rTMP, rALT, 8, 24, 31 +- stbu rTMP, 1(rDEST) +- blr +-#else +- rlwinm. rTMP, rALT, 8, 24, 31 +- stbu rTMP, 4(rDEST) +- beqlr- +- rlwinm. rTMP, rALT, 16, 24, 31 +- stbu rTMP, 1(rDEST) +- beqlr- +- rlwinm. rTMP, rALT, 24, 24, 31 +- stbu rTMP, 1(rDEST) +- beqlr- +- stbu rALT, 1(rDEST) +- CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt) +- STORE_RETURN_VALUE (rDEST) +- blr +-#endif +- +-/* Oh well. In this case, we just do a byte-by-byte copy. */ +- .align 4 +- nop +-L(unaligned): +- lbz rWORD, 0(rSRC) +- addi rDEST, rDEST, 3 +- cmpwi rWORD, 0 +- beq- L(u2) +- +-L(u0): lbzu rALT, 1(rSRC) +- stbu rWORD, 1(rDEST) +- cmpwi rALT, 0 +- beq- L(u1) +- nop /* Let 601 load start of loop. */ +- lbzu rWORD, 1(rSRC) +- stbu rALT, 1(rDEST) +- cmpwi rWORD, 0 +- bne+ L(u0) +-L(u2): stbu rWORD, 1(rDEST) +- CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt) +- STORE_RETURN_VALUE (rDEST) +- blr +-L(u1): stbu rALT, 1(rDEST) +- CHECK_BOUNDS_HIGH (rDEST, rHIGH, twlgt) +- STORE_RETURN_VALUE (rDEST) +- blr +-END (BP_SYM (__stpcpy)) +- +-weak_alias (BP_SYM (__stpcpy), BP_SYM (stpcpy)) ++weak_alias (__stpcpy, stpcpy) + libc_hidden_def (__stpcpy) + libc_hidden_builtin_def (stpcpy) +diff --git a/sysdeps/powerpc/powerpc64/strcpy.S b/sysdeps/powerpc/powerpc64/strcpy.S +index 9434c27..793325d 100644 +--- a/sysdeps/powerpc/powerpc64/strcpy.S ++++ b/sysdeps/powerpc/powerpc64/strcpy.S +@@ -1,5 +1,5 @@ + /* Optimized strcpy implementation for PowerPC64. +- Copyright (C) 1997, 1999, 2000, 2002, 2003, 2011 Free Software Foundation, Inc. ++ Copyright (C) 1997-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,52 +17,43 @@ + . */ + + #include +-#include +-#include + + /* See strlen.s for comments on how the end-of-string testing works. */ + + /* char * [r3] strcpy (char *dest [r3], const char *src [r4]) */ + +-EALIGN (BP_SYM (strcpy), 4, 0) ++#ifdef USE_AS_STPCPY ++# define FUNC_NAME __stpcpy ++#else ++# define FUNC_NAME strcpy ++#endif ++ ++EALIGN (FUNC_NAME, 4, 0) + CALL_MCOUNT 2 + + #define rTMP r0 +-#define rRTN r3 /* incoming DEST arg preserved as result */ +-/* Note. The Bounded pointer support in this code is broken. This code +- was inherited from PPC32 and that support was never completed. +- Current PPC gcc does not support -fbounds-check or -fbounded-pointers. +- These artifacts are left in the code as a reminder in case we need +- bounded pointer support in the future. */ +-#if __BOUNDED_POINTERS__ +-# define rDEST r4 /* pointer to previous word in dest */ +-# define rSRC r5 /* pointer to previous word in src */ +-# define rLOW r11 +-# define rHIGH r12 ++#ifdef USE_AS_STPCPY ++#define rRTN r3 /* pointer to previous word/doubleword in dest */ + #else +-# define rSRC r4 /* pointer to previous word in src */ +-# define rDEST r5 /* pointer to previous word in dest */ ++#define rRTN r12 /* pointer to previous word/doubleword in dest */ + #endif ++#define rSRC r4 /* pointer to previous word/doubleword in src */ + #define rWORD r6 /* current word from src */ +-#define rFEFE r7 /* constant 0xfefefefefefefeff (-0x0101010101010101) */ +-#define r7F7F r8 /* constant 0x7f7f7f7f7f7f7f7f */ +-#define rNEG r9 /* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */ ++#define rFEFE r7 /* constant 0xfefefeff | 0xfefefefefefefeff */ ++#define r7F7F r8 /* constant 0x7f7f7f7f | 0x7f7f7f7f7f7f7f7f */ ++#define rNEG r9 /* ~(word in s1 | r7F7F) */ + #define rALT r10 /* alternate word from src */ + +- CHECK_BOUNDS_LOW (rSRC, rLOW, rHIGH) +- CHECK_BOUNDS_LOW (rDEST, rLOW, rHIGH) +- STORE_RETURN_BOUNDS (rLOW, rHIGH) +- +- dcbt 0,rSRC ++#ifndef USE_AS_STPCPY ++/* Save the dst pointer to use as return value. */ ++ mr rRTN, r3 ++#endif + or rTMP, rSRC, rRTN + clrldi. rTMP, rTMP, 61 +-#if __BOUNDED_POINTERS__ +- addi rDEST, rDEST, -8 +-#else +- addi rDEST, rRTN, -8 +-#endif +- dcbtst 0,rRTN +- bne L(unaligned) ++ bne L(check_word_alignment) ++ ++/* For doubleword aligned memory, operate using doubleword load and stores. */ ++ addi rRTN, rRTN, -8 + + lis rFEFE, -0x101 + lis r7F7F, 0x7f7f +@@ -75,13 +66,13 @@ EALIGN (BP_SYM (strcpy), 4, 0) + b L(g2) + + L(g0): ldu rALT, 8(rSRC) +- stdu rWORD, 8(rDEST) ++ stdu rWORD, 8(rRTN) + add rTMP, rFEFE, rALT + nor rNEG, r7F7F, rALT + and. rTMP, rTMP, rNEG + bne- L(g1) + ldu rWORD, 8(rSRC) +- stdu rALT, 8(rDEST) ++ stdu rALT, 8(rRTN) + L(g2): add rTMP, rFEFE, rWORD + nor rNEG, r7F7F, rWORD + and. rTMP, rTMP, rNEG +@@ -92,80 +83,134 @@ L(g2): add rTMP, rFEFE, rWORD + L(g1): + #ifdef __LITTLE_ENDIAN__ + extrdi. rTMP, rALT, 8, 56 +- stb rALT, 8(rDEST) ++ stbu rALT, 8(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 48 +- stb rTMP, 9(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 40 +- stb rTMP, 10(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 32 +- stb rTMP, 11(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 24 +- stb rTMP, 12(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 16 +- stb rTMP, 13(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 8 +- stb rTMP, 14(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi rTMP, rALT, 8, 0 +- stb rTMP, 15(rDEST) +- blr ++ stbu rTMP, 1(rRTN) + #else + extrdi. rTMP, rALT, 8, 0 +- stb rTMP, 8(rDEST) ++ stbu rTMP, 8(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 8 +- stb rTMP, 9(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 16 +- stb rTMP, 10(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 24 +- stb rTMP, 11(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 32 +- stb rTMP, 12(rDEST) +- beqlr- ++ stbu rTMP, 1(rRTN) ++ beqlr + extrdi. rTMP, rALT, 8, 40 +- stb rTMP, 13(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- + extrdi. rTMP, rALT, 8, 48 +- stb rTMP, 14(rDEST) ++ stbu rTMP, 1(rRTN) + beqlr- +- stb rALT, 15(rDEST) +- /* GKM FIXME: check high bound. */ ++ stbu rALT, 1(rRTN) ++#endif + blr ++ ++L(check_word_alignment): ++ clrldi. rTMP, rTMP, 62 ++ bne L(unaligned) ++ ++/* For word aligned memory, operate using word load and stores. */ ++ addi rRTN, rRTN, -4 ++ ++ lis rFEFE, -0x101 ++ lis r7F7F, 0x7f7f ++ lwz rWORD, 0(rSRC) ++ addi rFEFE, rFEFE, -0x101 ++ addi r7F7F, r7F7F, 0x7f7f ++ b L(g5) ++ ++L(g3): lwzu rALT, 4(rSRC) ++ stwu rWORD, 4(rRTN) ++ add rTMP, rFEFE, rALT ++ nor rNEG, r7F7F, rALT ++ and. rTMP, rTMP, rNEG ++ bne- L(g4) ++ lwzu rWORD, 4(rSRC) ++ stwu rALT, 4(rRTN) ++L(g5): add rTMP, rFEFE, rWORD ++ nor rNEG, r7F7F, rWORD ++ and. rTMP, rTMP, rNEG ++ beq+ L(g3) ++ ++ mr rALT, rWORD ++/* We've hit the end of the string. Do the rest byte-by-byte. */ ++L(g4): ++#ifdef __LITTLE_ENDIAN__ ++ rlwinm. rTMP, rALT, 0, 24, 31 ++ stbu rALT, 4(rRTN) ++ beqlr- ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ rlwinm rTMP, rALT, 8, 24, 31 ++ stbu rTMP, 1(rRTN) ++#else ++ rlwinm. rTMP, rALT, 8, 24, 31 ++ stbu rTMP, 4(rRTN) ++ beqlr- ++ rlwinm. rTMP, rALT, 16, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ rlwinm. rTMP, rALT, 24, 24, 31 ++ stbu rTMP, 1(rRTN) ++ beqlr- ++ stbu rALT, 1(rRTN) + #endif ++ blr + + /* Oh well. In this case, we just do a byte-by-byte copy. */ + .align 4 + nop + L(unaligned): + lbz rWORD, 0(rSRC) +- addi rDEST, rRTN, -1 ++ addi rRTN, rRTN, -1 + cmpwi rWORD, 0 + beq- L(u2) + + L(u0): lbzu rALT, 1(rSRC) +- stbu rWORD, 1(rDEST) ++ stbu rWORD, 1(rRTN) + cmpwi rALT, 0 + beq- L(u1) + nop /* Let 601 load start of loop. */ + lbzu rWORD, 1(rSRC) +- stbu rALT, 1(rDEST) ++ stbu rALT, 1(rRTN) + cmpwi rWORD, 0 + bne+ L(u0) +-L(u2): stb rWORD, 1(rDEST) +- /* GKM FIXME: check high bound. */ ++L(u2): stbu rWORD, 1(rRTN) + blr +-L(u1): stb rALT, 1(rDEST) +- /* GKM FIXME: check high bound. */ ++L(u1): stbu rALT, 1(rRTN) + blr ++END (FUNC_NAME) + +-END (BP_SYM (strcpy)) ++#ifndef USE_AS_STPCPY + libc_hidden_builtin_def (strcpy) ++#endif diff --git a/SOURCES/glibc-rh1240351-5.patch b/SOURCES/glibc-rh1240351-5.patch new file mode 100644 index 00000000..6d8d9f69 --- /dev/null +++ b/SOURCES/glibc-rh1240351-5.patch @@ -0,0 +1,793 @@ + Backport of the following commit: + + commit 96d6fd6c4060d739abb1822e7ad633af749532b2 + Author: Adhemerval Zanella + Date: Tue Dec 23 05:59:44 2014 -0600 + + powerpc: Optimized st{r,p}cpy for POWER8/PPC64 + + This patch adds an optimized POWER8 strcpy using unaligned accesses. + For strings up to 16 bytes the implementation first calculate the + string size, like strlen, and issues a memcpy. For larger strings, + source is first aligned to 16 bytes and then tested over a loop that + reads 16 bytes am combine the cmpb results for speedup. Special case is + added for page cross reads. + + It shows 30%-60% improvement over the optimized POWER7 one that uses + only aligned accesses. + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]: Add + strcpy-power8 and stpcpy-power8 objects. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add __strcpy_power8 and __stpcpy_power8 + implementations. + * sysdeps/powerpc/powerpc64/multiarch/stpcpy-power8.S: New file: + multiarch stpcpy implementation for POWER8. + * sysdeps/powerpc/powerpc64/multiarch/strcpy-power8.S: New file; + multiarch strcpy implementation for POWER8. + * sysdeps/powerpc/powerpc64/multiarch/strcpy.c (strcpy): Add + __strcpy_power8 function. + * sysdeps/powerpc/powerpc64/power8/stpcpy.S: New file: optimized + stpcpy for POWER8. + * sysdeps/powerpc/powerpc64/power8/strcpy.S: New file: optimized + strcpy for POWER8. + * NEWS: Update. + + and the commits it depends on: + + commit a52374e82b90a6039c720f7b9b7dfa9db24ff4f0 + Author: Adhemerval Zanella + Date: Fri Dec 13 14:55:22 2013 -0500 + + PowerPC: multiarch stpcpy for PowerPC64 + + ChangeLog: + 2013-12-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add stpcpy + multiarch implementations. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Likewise. + * sysdeps/powerpc/powerpc64/multiarch/stpcpy-power7.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/stpcpy.c : New file: + multiarch stpcpy for PPC64. + + commit 7f5ec11336e46d0449a6b5a8e5a0604c3c78ecbf + Author: Adhemerval Zanella + Date: Fri Dec 13 14:54:41 2013 -0500 + + PowerPC: multiarch strcpy for PowerPC64 + + ChangeLog: + 2013-12-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcpy + multiarch implementations. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcpy-power7.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/strcpy.c : New file: + multiarch strcpy for PPC64. + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 8dceb09..1cdd5d6 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -5,6 +5,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ ++ stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ ++ strcpy-power8 strcpy-power7 strcpy-ppc64 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 strncmp-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 2d21ce1..e89fd3e 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -34,6 +34,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + size_t i = 0; + + unsigned long int hwcap = GLRO(dl_hwcap); ++ unsigned long int hwcap2 = GLRO(dl_hwcap2); ++ + /* hwcap contains only the latest supported ISA, the code checks which is + and fills the previous supported ones. */ + if (hwcap & PPC_FEATURE_ARCH_2_06) +@@ -71,6 +73,24 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __memset_power4) + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcpy.c. */ ++ IFUNC_IMPL (i, name, strcpy, ++ IFUNC_IMPL_ADD (array, i, strcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strcpy_power8) ++ IFUNC_IMPL_ADD (array, i, strcpy, hwcap & PPC_FEATURE_HAS_VSX, ++ __strcpy_power7) ++ IFUNC_IMPL_ADD (array, i, strcpy, 1, ++ __strcpy_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/stpcpy.c. */ ++ IFUNC_IMPL (i, name, stpcpy, ++ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __stpcpy_power8) ++ IFUNC_IMPL_ADD (array, i, stpcpy, hwcap & PPC_FEATURE_HAS_VSX, ++ __stpcpy_power7) ++ IFUNC_IMPL_ADD (array, i, stpcpy, 1, ++ __stpcpy_ppc)) ++ + /* Support sysdeps/powerpc/powerpc64/multiarch/strlen.c. */ + IFUNC_IMPL (i, name, strlen, + IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_HAS_VSX, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/stpcpy-power7.S +new file mode 100644 +index 0000000..0943611 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized stpcpy implementation for POWER7. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__stpcpy_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__stpcpy_power7): \ ++ cfi_startproc; \ ++ LOCALENTRY(__stpcpy_power7) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__stpcpy_power7) \ ++ END_2(__stpcpy_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy-power8.S b/sysdeps/powerpc/powerpc64/multiarch/stpcpy-power8.S +new file mode 100644 +index 0000000..66e6f70 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy-power8.S +@@ -0,0 +1,40 @@ ++/* Optimized stpcpy implementation for POWER8/PPC64. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__stpcpy_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__stpcpy_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__stpcpy_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__stpcpy_power8) \ ++ END_2(__stpcpy_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S +new file mode 100644 +index 0000000..ac70c1b +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S +@@ -0,0 +1,48 @@ ++/* Default stpcpy implementation for PowerPC64. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined SHARED && !defined NOT_IN_libc ++# undef EALIGN ++# define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__stpcpy_ppc) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__stpcpy_ppc): \ ++ cfi_startproc; \ ++ LOCALENTRY(__stpcpy_ppc) ++ ++# undef END ++# define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__stpcpy_ppc) \ ++ END_2(__stpcpy_ppc) ++ ++# undef weak_alias ++# define weak_alias(name, alias) ++# undef libc_hidden_def ++# define libc_hidden_def(name) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ .globl __GI___stpcpy; __GI___stpcpy = __stpcpy_ppc ++#endif ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c +new file mode 100644 +index 0000000..2ab62bf +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c +@@ -0,0 +1,35 @@ ++/* Multiple versions of stpcpy. PowerPC64 version. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined SHARED && !defined NOT_IN_libc ++# define NO_MEMPCPY_STPCPY_REDIRECT ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__stpcpy) __stpcpy_ppc attribute_hidden; ++extern __typeof (__stpcpy) __stpcpy_power7 attribute_hidden; ++ ++libc_ifunc (__stpcpy, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __stpcpy_power7 ++ : __stpcpy_ppc); ++ ++weak_alias (__stpcpy, stpcpy) ++libc_hidden_def (stpcpy) ++#endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcpy-power7.S +new file mode 100644 +index 0000000..69851bb +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized strcpy implementation for POWER7. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcpy_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcpy_power7): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcpy_power7) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcpy_power7) \ ++ END_2(__strcpy_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strcpy-power8.S +new file mode 100644 +index 0000000..64cbc16 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy-power8.S +@@ -0,0 +1,40 @@ ++/* Optimized strcpy implementation for POWER8/PPC64. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcpy_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcpy_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcpy_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcpy_power8) \ ++ END_2(__strcpy_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S +new file mode 100644 +index 0000000..e5452b1 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S +@@ -0,0 +1,43 @@ ++/* Default strcpy implementation for PowerPC64. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined SHARED && !defined NOT_IN_libc ++# undef EALIGN ++# define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcpy_ppc) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcpy_ppc): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcpy_ppc) ++ ++# undef END ++# define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcpy_ppc) \ ++ END_2(__strcpy_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ .globl __GI_strcpy; __GI_strcpy = __strcpy_ppc ++#endif ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c +new file mode 100644 +index 0000000..5a86f26 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c +@@ -0,0 +1,34 @@ ++/* Multiple versions of strcpy. PowerPC64 version. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined SHARED && !defined NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strcpy) __strcpy_ppc attribute_hidden; ++extern __typeof (strcpy) __strcpy_power7 attribute_hidden; ++extern __typeof (strcpy) __strcpy_power8 attribute_hidden; ++ ++libc_ifunc (strcpy, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strcpy_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcpy_power7 ++ : __strcpy_ppc); ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/stpcpy.S b/sysdeps/powerpc/powerpc64/power8/stpcpy.S +new file mode 100644 +index 0000000..bf72065 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/stpcpy.S +@@ -0,0 +1,24 @@ ++/* Optimized stpcpy implementation for PowerPC64/POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_STPCPY ++#include ++ ++weak_alias (__stpcpy, stpcpy) ++libc_hidden_def (__stpcpy) ++libc_hidden_builtin_def (stpcpy) +diff --git a/sysdeps/powerpc/powerpc64/power8/strcpy.S b/sysdeps/powerpc/powerpc64/power8/strcpy.S +new file mode 100644 +index 0000000..d3e9a10 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strcpy.S +@@ -0,0 +1,262 @@ ++/* Optimized strcpy/stpcpy implementation for PowerPC64/POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifdef USE_AS_STPCPY ++# define FUNC_NAME __stpcpy ++#else ++# define FUNC_NAME strcpy ++#endif ++ ++/* Implements the function ++ ++ char * [r3] strcpy (char *dest [r3], const char *src [r4]) ++ ++ or ++ ++ char * [r3] stpcpy (char *dest [r3], const char *src [r4]) ++ ++ if USE_AS_STPCPY is defined. ++ ++ The implementation uses unaligned doubleword access to avoid specialized ++ code paths depending of data alignment. Although recent powerpc64 uses ++ 64K as default, the page cross handling assumes minimum page size of ++ 4k. */ ++ ++ .machine power7 ++EALIGN (FUNC_NAME, 4, 0) ++ li r0,0 /* Doubleword with null chars to use ++ with cmpb. */ ++ ++ /* Check if the [src]+15 will cross a 4K page by checking if the bit ++ indicating the page size changes. Basically: ++ ++ uint64_t srcin = (uint64_t)src; ++ uint64_t ob = srcin & 4096UL; ++ uint64_t nb = (srcin+15UL) & 4096UL; ++ if (ob ^ nb) ++ goto pagecross; */ ++ ++ addi r9,r4,15 ++ xor r9,r9,r4 ++ rlwinm. r9,r9,0,19,19 ++ bne L(pagecross) ++ ++ /* For short string (less than 16 bytes), just calculate its size as ++ strlen and issues a memcpy if null is found. */ ++ mr r7,r4 ++ ld r12,0(r7) /* Load doubleword from memory. */ ++ cmpb r10,r12,r0 /* Check for null bytes in DWORD1. */ ++ cmpdi cr7,r10,0 /* If r10 == 0, no null's have been found. */ ++ bne cr7,L(done) ++ ++ ldu r8,8(r7) ++ cmpb r10,r8,r0 ++ cmpdi cr7,r10,0 ++ bne cr7,L(done) ++ ++ b L(loop_before) ++ ++ .align 4 ++L(pagecross): ++ clrrdi r7,r4,3 /* Align the address to doubleword boundary. */ ++ rlwinm r6,r4,3,26,28 /* Calculate padding. */ ++ li r5,-1 /* MASK = 0xffffffffffffffff. */ ++ ld r12,0(r7) /* Load doubleword from memory. */ ++#ifdef __LITTLE_ENDIAN__ ++ sld r5,r5,r6 ++#else ++ srd r5,r5,r6 /* MASK = MASK >> padding. */ ++#endif ++ orc r9,r12,r5 /* Mask bits that are not part of the string. */ ++ cmpb r10,r9,r0 /* Check for null bytes in DWORD1. */ ++ cmpdi cr7,r10,0 /* If r10 == 0, no null's have been found. */ ++ bne cr7,L(done) ++ ++ ldu r6,8(r7) ++ cmpb r10,r6,r0 ++ cmpdi cr7,r10,0 ++ bne cr7,L(done) ++ ++ ld r12,0(r7) ++ cmpb r10,r12,r0 ++ cmpdi cr7,r10,0 ++ bne cr7,L(done) ++ ++ ldu r6,8(r7) ++ cmpb r10,r6,r0 ++ cmpdi cr7,r10,0 ++ bne cr7,L(done) ++ ++ /* We checked for 24 - x bytes, with x being the source alignment ++ (0 <= x <= 16), and no zero has been found. Start the loop ++ copy with doubleword aligned address. */ ++ mr r7,r4 ++ ld r12, 0(r7) ++ ldu r8, 8(r7) ++ ++L(loop_before): ++ /* Save the two doublewords readed from source and align the source ++ to 16 bytes for the loop. */ ++ mr r11,r3 ++ std r12,0(r11) ++ std r8,8(r11) ++ addi r11,r11,16 ++ rldicl r9,r4,0,60 ++ subf r7,r9,r7 ++ subf r11,r9,r11 ++ b L(loop_start) ++ ++ .align 5 ++L(loop): ++ std r12, 0(r11) ++ std r6, 8(r11) ++ addi r11,r11,16 ++L(loop_start): ++ /* Load two doublewords, compare and merge in a ++ single register for speed. This is an attempt ++ to speed up the null-checking process for bigger strings. */ ++ ++ ld r12, 8(r7) ++ ldu r6, 16(r7) ++ cmpb r10,r12,r0 ++ cmpb r9,r6,r0 ++ or r8,r9,r10 /* Merge everything in one doubleword. */ ++ cmpdi cr7,r8,0 ++ beq cr7,L(loop) ++ ++ ++ /* OK, one (or both) of the doublewords contains a null byte. Check ++ the first doubleword and decrement the address in case the first ++ doubleword really contains a null byte. */ ++ ++ addi r4,r7,-8 ++ cmpdi cr6,r10,0 ++ addi r7,r7,-8 ++ bne cr6,L(done2) ++ ++ /* The null byte must be in the second doubleword. Adjust the address ++ again and move the result of cmpb to r10 so we can calculate the ++ length. */ ++ ++ mr r10,r9 ++ addi r7,r7,8 ++ b L(done2) ++ ++ /* r10 has the output of the cmpb instruction, that is, it contains ++ 0xff in the same position as the null byte in the original ++ doubleword from the string. Use that to calculate the length. */ ++L(done): ++ mr r11,r3 ++L(done2): ++#ifdef __LITTLE_ENDIAN__ ++ addi r9, r10, -1 /* Form a mask from trailing zeros. */ ++ andc r9, r9, r10 ++ popcntd r6, r9 /* Count the bits in the mask. */ ++#else ++ cntlzd r6,r10 /* Count leading zeros before the match. */ ++#endif ++ subf r5,r4,r7 ++ srdi r6,r6,3 /* Convert leading/trailing zeros to bytes. */ ++ add r8,r5,r6 /* Compute final length. */ ++#ifdef USE_AS_STPCPY ++ /* stpcpy returns the dest address plus the size not counting the ++ final '\0'. */ ++ add r3,r11,r8 ++#endif ++ addi r8,r8,1 /* Final '/0'. */ ++ ++ cmpldi cr6,r8,8 ++ mtocrf 0x01,r8 ++ ble cr6,L(copy_LE_8) ++ ++ cmpldi cr1,r8,16 ++ blt cr1,8f ++ ++ /* Handle copies of 0~31 bytes. */ ++ .align 4 ++L(copy_LT_32): ++ /* At least 6 bytes to go. */ ++ blt cr1,8f ++ ++ /* Copy 16 bytes. */ ++ ld r6,0(r4) ++ ld r8,8(r4) ++ addi r4,r4,16 ++ std r6,0(r11) ++ std r8,8(r11) ++ addi r11,r11,16 ++8: /* Copy 8 bytes. */ ++ bf 28,L(tail4) ++ ld r6,0(r4) ++ addi r4,r4,8 ++ std r6,0(r11) ++ addi r11,r11,8 ++ ++ .align 4 ++/* Copies 4~7 bytes. */ ++L(tail4): ++ bf 29,L(tail2) ++ lwz r6,0(r4) ++ stw r6,0(r11) ++ bf 30,L(tail5) ++ lhz r7,4(r4) ++ sth r7,4(r11) ++ bflr 31 ++ lbz r8,6(r4) ++ stb r8,6(r11) ++ blr ++ ++ .align 4 ++/* Copies 2~3 bytes. */ ++L(tail2): ++ bf 30,1f ++ lhz r6,0(r4) ++ sth r6,0(r11) ++ bflr 31 ++ lbz r7,2(r4) ++ stb r7,2(r11) ++ blr ++ ++ .align 4 ++L(tail5): ++ bf 31,1f ++ lbz r6,4(r4) ++ stb r6,4(r11) ++ blr ++ ++ .align 4 ++1: ++ bflr 31 ++ lbz r6,0(r4) ++ stb r6,0(r11) ++ blr ++ ++/* Handles copies of 0~8 bytes. */ ++ .align 4 ++L(copy_LE_8): ++ bne cr6,L(tail4) ++ ld r6,0(r4) ++ std r6,0(r11) ++ blr ++END (FUNC_NAME) ++ ++#ifndef USE_AS_STPCPY ++libc_hidden_builtin_def (strcpy) ++#endif diff --git a/SOURCES/glibc-rh1240351-6.patch b/SOURCES/glibc-rh1240351-6.patch new file mode 100644 index 00000000..f5c8dd6f --- /dev/null +++ b/SOURCES/glibc-rh1240351-6.patch @@ -0,0 +1,252 @@ + Backport of: + commit 94c9680945369d63ef9ed266a29f28ebaaaeb5ce + Author: Adhemerval Zanella + Date: Tue Dec 23 13:36:34 2014 -0500 + + powerpc: Optimized strcat for POWER8/PPC64 + + With new optimized strcpy for POWER8, this patch adds an optimized + strcat which uses it along with default implementation at strings/. + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]: Add + strncat-power8 object. + * sysdeps/powerpc/powerpc64/multiarch/strcat.c (strcat): Add + __strcat_power8 implementation. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add __strcat_power8 implementation. + * sysdeps/powerpc/powerpc64/multiarch/strcat-power8.c: New file: + optimized strcat for power8. + + and its dependency: + + commit bc8ea38590070604006399e42469087e943fc8ec + Author: Vidya Ranganathan + Date: Wed Jun 11 22:21:20 2014 -0500 + + PowerPC: strcat optimization for PPC64/POWER7 + + This patch adds an ifunc power7 strcat symbol that uses the logic on + sysdeps/powerpc/strcat.c but call power7 strlen/strcpy symbols instead + of default ones. + + ChangeLog: + + 2014-07-02 Vidya Ranganathan + Adhemerval Zanella + + * sysdeps/powerpc/strcat.c: Using macro to redefine symbol name. + * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcat multiarch + optimizations. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c: + (__libc_ifunc_impl_list): Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcat.c: New file: + multiarch strcat for PPC64. + * sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c: New file/ + * sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c: New file. + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 1cdd5d6..7ebfc7e 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -6,6 +6,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ ++ strcat-power8 strcat-power7 strcat-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index e89fd3e..4e5bb17 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -211,6 +211,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, + __strncasecmp_l_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcat.c. */ ++ IFUNC_IMPL (i, name, strcat, ++ IFUNC_IMPL_ADD (array, i, strcat, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strcat_power8) ++ IFUNC_IMPL_ADD (array, i, strcat, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strcat_power7) ++ IFUNC_IMPL_ADD (array, i, strcat, 1, ++ __strcat_ppc)) ++ + /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c. */ + IFUNC_IMPL (i, name, wcschr, + IFUNC_IMPL_ADD (array, i, wcschr, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c b/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c +new file mode 100644 +index 0000000..291a720 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRCAT __strcat_power7 ++ ++#undef libc_hidden_def ++#define libc_hidden_def(name) ++ ++extern typeof (strcpy) __strcpy_power7; ++extern typeof (strlen) __strlen_power7; ++ ++#define strcpy __strcpy_power7 ++#define strlen __strlen_power7 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat-power8.c b/sysdeps/powerpc/powerpc64/multiarch/strcat-power8.c +new file mode 100644 +index 0000000..6c7544c +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcat-power8.c +@@ -0,0 +1,30 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRCAT __strcat_power8 ++ ++#undef libc_hidden_def ++#define libc_hidden_def(name) ++ ++extern typeof (strcpy) __strcpy_power8; ++extern typeof (strlen) __strlen_power7; ++ ++#define strcpy __strcpy_power8 ++#define strlen __strlen_power7 ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c +new file mode 100644 +index 0000000..1245764 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c +@@ -0,0 +1,29 @@ ++/* Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRCAT __strcat_ppc ++#ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcat_ppc, __GI_strcat, __strcat_ppc); ++#endif ++ ++extern __typeof (strcat) __strcat_ppc attribute_hidden; ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c +new file mode 100644 +index 0000000..847a62d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcat.c +@@ -0,0 +1,31 @@ ++/* Multiple versions of strcat. PowerPC64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strcat) __strcat_ppc attribute_hidden; ++extern __typeof (strcat) __strcat_power7 attribute_hidden; ++ ++libc_ifunc (strcat, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcat_power7 ++ : __strcat_ppc); ++#endif +diff --git a/sysdeps/powerpc/strcat.c b/sysdeps/powerpc/strcat.c +index 28575d0..393bee6 100644 +--- a/sysdeps/powerpc/strcat.c ++++ b/sysdeps/powerpc/strcat.c +@@ -18,13 +18,16 @@ + + #include + +-#undef strcat ++#ifndef STRCAT ++# undef strcat ++# define STRCAT strcat ++#endif + + /* Append SRC on the end of DEST. */ + char * +-strcat (char *dest, const char *src) ++STRCAT(char *dest, const char *src) + { + strcpy (dest + strlen (dest), src); + return dest; + } +-libc_hidden_builtin_def (strcat) ++libc_hidden_builtin_def (STRCAT) diff --git a/SOURCES/glibc-rh1240351-7.patch b/SOURCES/glibc-rh1240351-7.patch new file mode 100644 index 00000000..9d3e288d --- /dev/null +++ b/SOURCES/glibc-rh1240351-7.patch @@ -0,0 +1,78 @@ + Backport of the addition of + sysdeps/powerpc/powerpc64/multiarch/strncat-power7.c + from the following: + + commit 9f2f36e5a91c2ce6edba5415e176155eb1008ae1 + Author: Adhemerval Zanella + Date: Tue Dec 23 13:39:23 2014 -0500 + + powerpc: Optimized strncat for POWER7/PPC64 + + With 3eb38795dbbbd816 (Simplify strncat) the generic algorithms uses + strlen, strnlen, and memcpy. This is faster than POWER7 current + implementation, especially for unaligned strings (where POWER7 code + uses byte-byte operations). + + This patch removes the assembly implementation and uses a multiarch + specialization based on default algorithm calling optimized POWER7 + symbols. + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/strncat-power7.c: New file. + * sysdeps/powerpc/powerpc64/multiarch/strncat-power7.S: Remove file. + * sysdeps/powerpc/powerpc64/power7/strncat.S: Likewise. + + plus the addition of strncat-power7 to + sysdeps/powerpc/powerpc64/multiarch/Makefile + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 7ebfc7e..74ae710 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -8,6 +8,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ + strcat-power8 strcat-power7 strcat-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ ++ strncat-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 strncmp-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncat-power7.c b/sysdeps/powerpc/powerpc64/multiarch/strncat-power7.c +new file mode 100644 +index 0000000..39b1aeb +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncat-power7.c +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRNCAT __strncat_power7 ++ ++extern __typeof (strncat) __strncat_power7 attribute_hidden; ++extern __typeof (strlen) __strlen_power7 attribute_hidden; ++extern __typeof (strnlen) __strnlen_power7 attribute_hidden; ++extern __typeof (memcpy) __memcpy_power7 attribute_hidden; ++ ++#define strlen __strlen_power7 ++#define __strnlen __strnlen_power7 ++#define memcpy __memcpy_power7 ++ ++#include diff --git a/SOURCES/glibc-rh1240351-8.patch b/SOURCES/glibc-rh1240351-8.patch new file mode 100644 index 00000000..d0826eda --- /dev/null +++ b/SOURCES/glibc-rh1240351-8.patch @@ -0,0 +1,1272 @@ + Backport of: + + commit f06a4faf8a2b4d046eb40e94b47948cc47d79902 + Author: Adhemerval Zanella + Date: Wed Dec 31 11:47:41 2014 -0500 + + powerpc: Optimized st{r,p}ncpy for POWER8/PPC64 + + This patch adds an optimized POWER8 st{r,p}ncpy using unaligned accesses. + It shows 10%-80% improvement over the optimized POWER7 one that uses + only aligned accesses, specially on unaligned inputs. + + The algorithm first read and check 16 bytes (if inputs do not cross a 4K + page size). The it realign source to 16-bytes and issue a 16 bytes read + and compare loop to speedup null byte checks for large strings. Also, + different from POWER7 optimization, the null pad is done inline in the + implementation using possible unaligned accesses, instead of realying on + a memset call. Special case is added for page cross reads. + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]: + Add strncpy-power8 and stpncpy-power8 objects. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add __strncpy_power8 and stpncpy_power8 + implementations. + * sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S: New file. + * sysdeps/powerpc/powerpc64/multiarch/stpncpy.c (__stpncpy): Add + __stpncpy_power8 implementation. + * sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S: New file. + * sysdeps/powerpc/powerpc64/multiarch/strncpy.c (strncpy): Add + __strncpy_power8 implementation. + * sysdeps/powerpc/powerpc64/power8/stpncpy.S: New file. + * sysdeps/powerpc/powerpc64/power8/strncpy.S: New file. + * NEWS: Update. + + and its dependency: + + commit f360f94a05570045be615649e9a411cefba2e210 + Author: Vidya Ranganathan + Date: Mon May 5 19:10:45 2014 -0500 + + PowerPC: strncpy/stpncpy optimization for PPC64/POWER7 + + The optimization is achieved by following techniques: + > data alignment [gain from aligned memory access on read/write] + > POWER7 gains performance with loop unrolling/unwinding + [gain by reduction of branch penalty]. + > zero padding done by calling optimized memset + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 74ae710..ef39917 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -8,6 +8,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ + strcat-power8 strcat-power7 strcat-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ ++ stpncpy-power8 stpncpy-power7 stpncpy-ppc64 \ ++ strncpy-power8 strncpy-power7 strncpy-ppc64 + strncat-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 4e5bb17..23bf5dc 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -255,5 +255,27 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, wcscpy, 1, + __wcscpy_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strncpy.c. */ ++ IFUNC_IMPL (i, name, strncpy, ++ IFUNC_IMPL_ADD (array, i, strncpy, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strncpy_power8) ++ IFUNC_IMPL_ADD (array, i, strncpy, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strncpy_power7) ++ IFUNC_IMPL_ADD (array, i, strncpy, 1, ++ __strncpy_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/stpncpy.c. */ ++ IFUNC_IMPL (i, name, stpncpy, ++ IFUNC_IMPL_ADD (array, i, stpncpy, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __stpncpy_power8) ++ IFUNC_IMPL_ADD (array, i, stpncpy, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __stpncpy_power7) ++ IFUNC_IMPL_ADD (array, i, stpncpy, 1, ++ __stpncpy_ppc)) ++ + return i; + } +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S +new file mode 100644 +index 0000000..e29674f +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S +@@ -0,0 +1,44 @@ ++/* Optimized stpncpy implementation for POWER7. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define USE_AS_STPNCPY ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__stpncpy_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__stpncpy_power7): \ ++ cfi_startproc; \ ++ LOCALENTRY(__stpncpy_power7) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__stpncpy_power7) \ ++ END_2(__stpncpy_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define MEMSET __memset_power7 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S +new file mode 100644 +index 0000000..d5d835d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S +@@ -0,0 +1,39 @@ ++/* Optimized stpncpy implementation for POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define USE_AS_STPNCPY ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__stpncpy_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__stpncpy_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__stpncpy_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__stpncpy_power8) \ ++ END_2(__stpncpy_power8) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c +new file mode 100644 +index 0000000..74f47a7 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c +@@ -0,0 +1,26 @@ ++/* Default stpncpy implementation for PowerPC64. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STPNCPY __stpncpy_ppc ++#ifdef SHARED ++#undef libc_hidden_def ++#define libc_hidden_def(name) \ ++ __hidden_ver1 (__stpncpy_ppc, __GI___stpncpy, __stpncpy_ppc); ++#endif ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c +new file mode 100644 +index 0000000..3ee50e5 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c +@@ -0,0 +1,36 @@ ++/* Multiple versions of stpncpy. PowerPC64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden; ++extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden; ++extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden; ++ ++libc_ifunc (__stpncpy, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __stpncpy_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __stpncpy_power7 ++ : __stpncpy_ppc); ++ ++weak_alias (__stpncpy, stpncpy) ++#endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S +new file mode 100644 +index 0000000..be349f9 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S +@@ -0,0 +1,42 @@ ++/* Optimized strncpy implementation for POWER7. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncpy_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncpy_power7): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strncpy_power7) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncpy_power7) \ ++ END_2(__strncpy_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define MEMSET __memset_power7 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S +new file mode 100644 +index 0000000..ed906a4 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S +@@ -0,0 +1,40 @@ ++/* Optimized strncpy implementation for POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncpy_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncpy_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strncpy_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncpy_power8) \ ++ END_2(__strncpy_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c +new file mode 100644 +index 0000000..e3111d2 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRNCPY __strncpy_ppc ++#undef weak_alias ++#define weak_alias(name, aliasname) \ ++ extern __typeof (__strncpy_ppc) aliasname \ ++ __attribute__ ((weak, alias ("__strncpy_ppc"))); ++#if !defined(NOT_IN_libc) && defined(SHARED) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1(__strncpy_ppc, __GI_strncpy, __strncpy_ppc); ++#endif ++ ++extern __typeof (strncpy) __strncpy_ppc attribute_hidden; ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c +new file mode 100644 +index 0000000..19927bc +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c +@@ -0,0 +1,38 @@ ++/* Multiple versions of strncpy. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strncpy) __strncpy_ppc attribute_hidden; ++extern __typeof (strncpy) __strncpy_power7 attribute_hidden; ++extern __typeof (strncpy) __strncpy_power8 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (strncpy, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strncpy_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strncpy_power7 ++ : __strncpy_ppc); ++ ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power7/stpncpy.S b/sysdeps/powerpc/powerpc64/power7/stpncpy.S +new file mode 100644 +index 0000000..a539093 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/stpncpy.S +@@ -0,0 +1,24 @@ ++/* Optimized stpncpy implementation for PowerPC64/POWER7. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_STPNCPY ++#include ++ ++weak_alias (__stpncpy, stpncpy) ++libc_hidden_def (__stpncpy) ++libc_hidden_builtin_def (stpncpy) +diff --git a/sysdeps/powerpc/powerpc64/power7/strncpy.S b/sysdeps/powerpc/powerpc64/power7/strncpy.S +new file mode 100644 +index 0000000..51860df +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/strncpy.S +@@ -0,0 +1,338 @@ ++/* Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Implements the functions ++ ++ char * [r3] strncpy (char *dst [r3], const char *src [r4], size_t n [r5]) ++ ++ AND ++ ++ char * [r3] stpncpy (char *dst [r3], const char *src [r4], size_t n [r5]) ++ ++ The algorithm is as follows: ++ > if src and dest are 8 byte aligned, perform double word copy ++ else ++ > copy byte by byte on unaligned addresses. ++ ++ The aligned comparison are made using cmpb instructions. */ ++ ++/* The focus on optimization for performance improvements are as follows: ++ 1. data alignment [gain from aligned memory access on read/write] ++ 2. POWER7 gains performance with loop unrolling/unwinding ++ [gain by reduction of branch penalty]. ++ 3. The final pad with null bytes is done by calling an optimized ++ memset. */ ++ ++#ifdef USE_AS_STPNCPY ++# define FUNC_NAME __stpncpy ++#else ++# define FUNC_NAME strncpy ++#endif ++ ++#define FRAMESIZE (FRAME_MIN_SIZE+32) ++ ++#ifndef MEMSET ++/* For builds with no IFUNC support, local calls should be made to internal ++ GLIBC symbol (created by libc_hidden_builtin_def). */ ++# ifdef SHARED ++# define MEMSET __GI_memset ++# else ++# define MEMSET memset ++# endif ++#endif ++ ++ .machine power7 ++EALIGN(FUNC_NAME, 4, 0) ++ CALL_MCOUNT 3 ++ ++ mflr r0 /* load link register LR to r0 */ ++ or r10, r3, r4 /* to verify source and destination */ ++ rldicl. r8, r10, 0, 61 /* is double word aligned .. ? */ ++ ++ std r19, -8(r1) /* save callers register , r19 */ ++ std r18, -16(r1) /* save callers register , r18 */ ++ std r0, 16(r1) /* store the link register */ ++ stdu r1, -FRAMESIZE(r1) /* create the stack frame */ ++ ++ mr r9, r3 /* save r3 into r9 for use */ ++ mr r18, r3 /* save r3 for retCode of strncpy */ ++ bne 0, L(byte_by_byte) ++ ++ ++ srdi r11, r5, 3 /* compute count for CTR ; count = n/8 */ ++ cmpldi cr7, r11, 3 /* if count > 4 ; perform unrolling 4 times */ ++ ble 7, L(update1) ++ ++ ld r10, 0(r4) /* load doubleWord from src */ ++ cmpb r8, r10, r8 /* compare src with NULL ,we read just now */ ++ cmpdi cr7, r8, 0 /* if cmpb returned NULL ; we continue */ ++ bne cr7, L(update3) ++ ++ std r10, 0(r3) /* copy doubleword at offset=0 */ ++ ld r10, 8(r4) /* load next doubleword from offset=8 */ ++ cmpb r8, r10, r8 /* compare src with NULL , we read just now */ ++ cmpdi cr7, r8, 0 /* if cmpb returned NULL ; we continue */ ++ bne 7,L(HopBy8) ++ ++ addi r8, r11, -4 ++ mr r7, r3 ++ srdi r8, r8, 2 ++ mr r6, r4 ++ addi r8, r8, 1 ++ li r12, 0 ++ mtctr r8 ++ b L(dwordCopy) ++ ++ .p2align 4 ++L(dWordUnroll): ++ std r8, 16(r9) ++ ld r8, 24(r4) /* load dword,perform loop unrolling again */ ++ cmpb r10, r8, r10 ++ cmpdi cr7, r10, 0 ++ bne cr7, L(HopBy24) ++ ++ std r8, 24(r7) /* copy dword at offset=24 */ ++ addi r9, r9, 32 ++ addi r4, r4, 32 ++ bdz L(leftDwords) /* continue with loop on counter */ ++ ++ ld r3, 32(r6) ++ cmpb r8, r3, r10 ++ cmpdi cr7, r8, 0 ++ bne cr7, L(update2) ++ ++ std r3, 32(r7) ++ ld r10, 40(r6) ++ cmpb r8, r10, r8 ++ cmpdi cr7, r8, 0 ++ bne cr7, L(HopBy40) ++ ++ mr r6, r4 /* update values */ ++ mr r7, r9 ++ mr r11, r0 ++ mr r5, r19 ++ ++L(dwordCopy): ++ std r10, 8(r9) /* copy dword at offset=8 */ ++ addi r19, r5, -32 ++ addi r0, r11, -4 ++ ld r8, 16(r4) ++ cmpb r10, r8, r12 ++ cmpdi cr7, r10, 0 ++ beq cr7, L(dWordUnroll) ++ ++ addi r9, r9, 16 /* increment dst by 16 */ ++ addi r4, r4, 16 /* increment src by 16 */ ++ addi r5, r5, -16 /* decrement length 'n' by 16 */ ++ addi r0, r11, -2 /* decrement loop counter */ ++ ++L(dWordUnrollOFF): ++ ld r10, 0(r4) /* load first dword */ ++ li r8, 0 /* load mask */ ++ cmpb r8, r10, r8 ++ cmpdi cr7, r8, 0 ++ bne cr7, L(byte_by_byte) ++ mtctr r0 ++ li r7, 0 ++ b L(CopyDword) ++ ++ .p2align 4 ++L(loadDWordandCompare): ++ ld r10, 0(r4) ++ cmpb r8, r10, r7 ++ cmpdi cr7, r8, 0 ++ bne cr7, L(byte_by_byte) ++ ++L(CopyDword): ++ addi r9, r9, 8 ++ std r10, -8(r9) ++ addi r4, r4, 8 ++ addi r5, r5, -8 ++ bdnz L(loadDWordandCompare) ++ ++L(byte_by_byte): ++ cmpldi cr7, r5, 3 ++ ble cr7, L(verifyByte) ++ srdi r10, r5, 2 ++ mr r19, r9 ++ mtctr r10 ++ b L(firstByteUnroll) ++ ++ .p2align 4 ++L(bytes_unroll): ++ lbz r10, 1(r4) /* load byte from src */ ++ cmpdi cr7, r10, 0 /* compare for NULL */ ++ stb r10, 1(r19) /* store byte to dst */ ++ beq cr7, L(updtDestComputeN2ndByte) ++ ++ addi r4, r4, 4 /* advance src */ ++ ++ lbz r10, -2(r4) /* perform loop unrolling for byte r/w */ ++ cmpdi cr7, r10, 0 ++ stb r10, 2(r19) ++ beq cr7, L(updtDestComputeN3rdByte) ++ ++ lbz r10, -1(r4) /* perform loop unrolling for byte r/w */ ++ addi r19, r19, 4 ++ cmpdi cr7, r10, 0 ++ stb r10, -1(r19) ++ beq cr7, L(ComputeNByte) ++ ++ bdz L(update0) ++ ++L(firstByteUnroll): ++ lbz r10, 0(r4) /* perform loop unrolling for byte r/w */ ++ cmpdi cr7, 10, 0 ++ stb r10, 0(r19) ++ bne cr7, L(bytes_unroll) ++ addi r19, r19, 1 ++ ++L(ComputeNByte): ++ subf r9, r19, r9 /* compute 'n'n bytes to fill */ ++ add r8, r9, r5 ++ ++L(zeroFill): ++ cmpdi cr7, r8, 0 /* compare if length is zero */ ++ beq cr7, L(update3return) ++ ++ mr r3, r19 /* fill buffer with */ ++ li r4, 0 /* zero fill buffer */ ++ mr r5, r8 /* how many bytes to fill buffer with */ ++ bl MEMSET /* call optimized memset */ ++ nop ++ ++L(update3return): ++#ifdef USE_AS_STPNCPY ++ addi r3, r19, -1 /* update return value */ ++#endif ++ ++L(hop2return): ++#ifndef USE_AS_STPNCPY ++ mr r3, r18 /* set return value */ ++#endif ++ addi r1, r1, FRAMESIZE /* restore stack pointer */ ++ ld r0, 16(r1) /* read the saved link register */ ++ ld r18, -16(r1) /* restore callers save register, r18 */ ++ ld r19, -8(r1) /* restore callers save register, r19 */ ++ mtlr r0 /* branch to link register */ ++ blr /* return */ ++ ++ .p2align 4 ++L(update0): ++ mr r9, r19 ++ ++ .p2align 4 ++L(verifyByte): ++ rldicl. r8, r5, 0, 62 ++#ifdef USE_AS_STPNCPY ++ mr r3, r9 ++#endif ++ beq cr0, L(hop2return) ++ mtctr r8 ++ addi r4, r4, -1 ++ mr r19, r9 ++ b L(oneBYone) ++ ++ .p2align 4 ++L(proceed): ++ bdz L(done) ++ ++L(oneBYone): ++ lbzu r10, 1(r4) /* copy byte */ ++ addi r19, r19, 1 ++ addi r8, r8, -1 ++ cmpdi cr7, r10, 0 ++ stb r10, -1(r19) ++ bne cr7, L(proceed) ++ b L(zeroFill) ++ ++ .p2align 4 ++L(done): ++ addi r1, r1, FRAMESIZE /* restore stack pointer */ ++#ifdef USE_AS_STPNCPY ++ mr r3, r19 /* set the return value */ ++#else ++ mr r3, r18 /* set the return value */ ++#endif ++ ld r0, 16(r1) /* read the saved link register */ ++ ld r18, -16(r1) /* restore callers save register, r18 */ ++ ld r19, -8(r1) /* restore callers save register, r19 */ ++ mtlr r0 /* branch to link register */ ++ blr /* return */ ++ ++L(update1): ++ mr r0, r11 ++ mr r19, r5 ++ ++ .p2align 4 ++L(leftDwords): ++ cmpdi cr7, r0, 0 ++ mr r5, r19 ++ bne cr7, L(dWordUnrollOFF) ++ b L(byte_by_byte) ++ ++ .p2align 4 ++L(updtDestComputeN2ndByte): ++ addi r19, r19, 2 /* update dst by 2 */ ++ subf r9, r19, r9 /* compute distance covered */ ++ add r8, r9, r5 ++ b L(zeroFill) ++ ++ .p2align 4 ++L(updtDestComputeN3rdByte): ++ addi r19, r19, 3 /* update dst by 3 */ ++ subf r9, r19, r9 /* compute distance covered */ ++ add r8, r9, r5 ++ b L(zeroFill) ++ ++ .p2align 4 ++L(HopBy24): ++ addi r9, r9, 24 /* increment dst by 24 */ ++ addi r4, r4, 24 /* increment src by 24 */ ++ addi r5, r5, -24 /* decrement length 'n' by 24 */ ++ addi r0, r11, -3 /* decrement loop counter */ ++ b L(dWordUnrollOFF) ++ ++ .p2align 4 ++L(update2): ++ mr r5, r19 ++ b L(dWordUnrollOFF) ++ ++ .p2align 4 ++L(HopBy40): ++ addi r9, r7, 40 /* increment dst by 40 */ ++ addi r4, r6, 40 /* increment src by 40 */ ++ addi r5, r5, -40 /* decrement length 'n' by 40 */ ++ addi r0, r11, -5 /* decrement loop counter */ ++ b L(dWordUnrollOFF) ++ ++L(update3): ++ mr r0, r11 ++ b L(dWordUnrollOFF) ++ ++L(HopBy8): ++ addi r9, r3, 8 /* increment dst by 8 */ ++ addi r4, r4, 8 /* increment src by 8 */ ++ addi r5, r5, -8 /* decrement length 'n' by 8 */ ++ addi r0, r11, -1 /* decrement loop counter */ ++ b L(dWordUnrollOFF) ++END(FUNC_NAME) ++#ifndef USE_AS_STPNCPY ++libc_hidden_builtin_def (strncpy) ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/stpncpy.S b/sysdeps/powerpc/powerpc64/power8/stpncpy.S +new file mode 100644 +index 0000000..76a1466 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/stpncpy.S +@@ -0,0 +1,20 @@ ++/* Optimized stpncpy implementation for PowerPC64/POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_STPNCPY ++#include +diff --git a/sysdeps/powerpc/powerpc64/power8/strncpy.S b/sysdeps/powerpc/powerpc64/power8/strncpy.S +new file mode 100644 +index 0000000..5fda953 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strncpy.S +@@ -0,0 +1,424 @@ ++/* Optimized strncpy/stpncpy implementation for PowerPC64/POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifdef USE_AS_STPNCPY ++# define FUNC_NAME __stpncpy ++#else ++# define FUNC_NAME strncpy ++#endif ++ ++/* Implements the function ++ ++ char * [r3] strncpy (char *dest [r3], const char *src [r4], size_t n [r5]) ++ ++ or ++ ++ char * [r3] stpncpy (char *dest [r3], const char *src [r4], size_t n [r5]) ++ ++ if USE_AS_STPCPY is defined. ++ ++ The implementation uses unaligned doubleword access to avoid specialized ++ code paths depending of data alignment. Although recent powerpc64 uses ++ 64K as default, the page cross handling assumes minimum page size of ++ 4k. */ ++ ++ .machine power7 ++EALIGN (FUNC_NAME, 4, 0) ++ ++ /* Check if the [src]+15 will cross a 4K page by checking if the bit ++ indicating the page size changes. Basically: ++ ++ uint64_t srcin = (uint64_t)src; ++ uint64_t ob = srcin & 4096UL; ++ uint64_t nb = (srcin+15UL) & 4096UL; ++ if (ob ^ nb) ++ goto pagecross; */ ++ ++ addi r10,r4,16 ++ rlwinm r9,r4,0,19,19 ++ ++ /* Since it is a leaf function, save some non-volatile registers on the ++ protected/red zone. */ ++ std r26,-48(r1) ++ std r27,-40(r1) ++ ++ rlwinm r8,r10,0,19,19 ++ ++ std r28,-32(r1) ++ std r29,-24(r1) ++ ++ cmpld r7,r9,r8 ++ ++ std r30,-16(r1) ++ std r31,-8(r1) ++ ++ beq cr7,L(unaligned_lt_16) ++ rldicl r9,r4,0,61 ++ subfic r8,r9,8 ++ cmpld cr7,r5,r8 ++ bgt cr7,L(pagecross) ++ ++ /* At this points there is 1 to 15 bytes to check and write. Since it could ++ be either from first unaligned 16 bytes access or from bulk copy, the code ++ uses an unrolled byte read/write instead of trying to analyze the cmpb ++ results. */ ++L(short_path): ++ mr r9,r3 ++L(short_path_1): ++ cmpdi cr7,r5,0 ++ beq cr7,L(short_path_loop_end_1) ++L(short_path_2): ++ lbz r10,0(r4) ++ cmpdi cr7,r10,0 ++ stb r10,0(r9) ++ beq cr7,L(zero_pad_start_1) ++ cmpdi cr0,r5,1 ++ addi r8,r9,1 ++ addi r6,r5,-1 ++ beq cr0,L(short_path_loop_end_0) ++ lbz r10,1(r4) ++ cmpdi cr7,r10,0 ++ stb r10,1(r9) ++ beq cr7,L(zero_pad_start_prepare_1) ++ addi r10,r5,-3 ++ b L(short_path_loop_1) ++ ++ .align 4 ++L(short_path_loop): ++ lbz r8,0(r4) ++ addi r7,r10,-2 ++ cmpdi cr5,r8,0 ++ stb r8,0(r9) ++ beq cr5,L(zero_pad_start_1) ++ beq r7,L(short_path_loop_end_0) ++ lbz r8,1(r4) ++ cmpdi cr7,r8,0 ++ stb r8,1(r9) ++ beq cr7,L(zero_pad_start) ++ mr r10,r7 ++L(short_path_loop_1): ++ addic. r5,r5,-2 ++ addi r9,r9,2 ++ cmpdi cr7,r10,0 ++ addi r4,r4,2 ++ addi r6,r9,1 ++ bne cr0,L(short_path_loop) ++#ifdef USE_AS_STPNCPY ++ mr r3,r9 ++ b L(short_path_loop_end) ++#endif ++ ++L(short_path_loop_end_0): ++#ifdef USE_AS_STPNCPY ++ addi r3,r9,1 ++ b L(short_path_loop_end) ++#endif ++L(short_path_loop_end_1): ++#ifdef USE_AS_STPNCPY ++ mr r3,r9 ++#endif ++L(short_path_loop_end): ++ /* Restore non-volatile registers. */ ++ ld r26,-48(r1) ++ ld r27,-40(r1) ++ ld r28,-32(r1) ++ ld r29,-24(r1) ++ ld r30,-16(r1) ++ ld r31,-8(r1) ++ blr ++ ++ /* This code pads the remainder dest with NULL bytes. The algorithm ++ calculate the remanining size and issues a doubleword unrolled ++ loops followed by a byte a byte set. */ ++ .align 4 ++L(zero_pad_start): ++ mr r5,r10 ++ mr r9,r6 ++L(zero_pad_start_1): ++ srdi. r8,r5,r3 ++ mr r10,r9 ++#ifdef USE_AS_STPNCPY ++ mr r3,r9 ++#endif ++ beq- cr0,L(zero_pad_loop_b_start) ++ cmpldi cr7,r8,1 ++ li cr7,0 ++ std r7,0(r9) ++ beq cr7,L(zero_pad_loop_b_prepare) ++ addic. r8,r8,-2 ++ addi r10,r9,r16 ++ std r7,8(r9) ++ beq cr0,L(zero_pad_loop_dw_2) ++ std r7,16(r9) ++ li r9,0 ++ b L(zero_pad_loop_dw_1) ++ ++ .align 4 ++L(zero_pad_loop_dw): ++ addi r10,r10,16 ++ std r9,-8(r10) ++ beq cr0,L(zero_pad_loop_dw_2) ++ std r9,0(r10) ++L(zero_pad_loop_dw_1): ++ cmpldi cr7,r8,1 ++ std r9,0(r10) ++ addic. r8,r8,-2 ++ bne cr7,L(zero_pad_loop_dw) ++ addi r10,r10,8 ++L(zero_pad_loop_dw_2): ++ rldicl r5,r5,0,61 ++L(zero_pad_loop_b_start): ++ cmpdi cr7,r5,0 ++ addi r5,r5,-1 ++ addi r9,r10,-1 ++ add r10,r10,5 ++ subf r10,r9,r10 ++ li r8,0 ++ beq- cr7,L(short_path_loop_end) ++ ++ /* Write remaining 1-8 bytes. */ ++ .align 4 ++ addi r9,r9,1 ++ mtocrf 0x1,r10 ++ bf 29,4f ++ stw r8,0(r9) ++ addi r9,r9,4 ++ ++ .align 4 ++4: bf 30,2f ++ sth r8,0(r9) ++ addi r9,r9,2 ++ ++ .align 4 ++2: bf 31,1f ++ stb r8,0(r9) ++ ++ /* Restore non-volatile registers. */ ++1: ld r26,-48(r1) ++ ld r27,-40(r1) ++ ld r28,-32(r1) ++ ld r29,-24(r1) ++ ld r30,-16(r1) ++ ld r31,-8(r1) ++ blr ++ ++ /* The common case where [src]+16 will not cross a 4K page boundary. ++ In this case the code fast check the first 16 bytes by using doubleword ++ read/compares and update destiny if neither total size or null byte ++ is found in destiny. */ ++ .align 4 ++L(unaligned_lt_16): ++ cmpldi cr7,r5,7 ++ ble cr7,L(short_path) ++ ld r7,0(r4) ++ li r8,0 ++ cmpb r8,r7,r8 ++ cmpdi cr7,r8,0 ++ bne cr7,L(short_path_prepare_2) ++ addi r6,r5,-8 ++ std r7,0(r3) ++ addi r9,r3,r8 ++ cmpldi cr7,r6,7 ++ addi r7,r4,8 ++ ble cr7,L(short_path_prepare_1_1) ++ ld r4,8(r4) ++ cmpb r8,r4,r8 ++ cmpdi cr7,r8,0 ++ bne cr7,L(short_path_prepare_2_1) ++ std r4,8(r3) ++ addi r29,r3,16 ++ addi r5,r5,-16 ++ /* Neither the null byte was found or total length was reached, ++ align to 16 bytes and issue a bulk copy/compare. */ ++ b L(align_to_16b) ++ ++ /* In the case of 4k page boundary cross, the algorithm first align ++ the address to a doubleword, calculate a mask based on alignment ++ to ignore the bytes and continue using doubleword. */ ++ .align 4 ++L(pagecross): ++ rldicr r11,r4,0,59 /* Align the address to 8 bytes boundary. */ ++ li r6,-1 /* MASK = 0xffffffffffffffffUL. */ ++ sldi r9,r9,3 /* Calculate padding. */ ++ ld r7,0(r11) /* Load doubleword from memory. */ ++#ifdef __LITTLE_ENDIAN__ ++ sld r9,r6,r9 /* MASK = MASK << padding. */ ++#else ++ srd r9,r6,r9 /* MASK = MASK >> padding. */ ++#endif ++ orc r9,r7,r9 /* Mask bits that are not part of the ++ string. */ ++ li cr7,0 ++ cmpb r9,r9,r7 /* Check for null bytes in DWORD1. */ ++ cmpdi cr7,r9,0 ++ bne cr7,L(short_path_prepare_2) ++ subf r8,r8,r5 /* Adjust total length. */ ++ cmpldi cr7,r8,8 /* Check if length was reached. */ ++ ble cr7,L(short_path_prepare_2) ++ ++ /* For next checks we have aligned address, so we check for more ++ three doublewords to make sure we can read 16 unaligned bytes ++ to start the bulk copy with 16 aligned addresses. */ ++ ld cr7,8(r11) ++ cmpb r9,r7,r9 ++ cmpdi cr7,r9,0 ++ bne cr7,L(short_path_prepare_2) ++ addi cr7,r8,-8 ++ cmpldi cr7,r7,8 ++ ble cr7,L(short_path_prepare_2) ++ ld cr7,16(r11) ++ cmpb r9,r7,r9 ++ cmpdi cr7,r9,0 ++ bne cr7,L(short_path_prepare_2) ++ addi r8,r8,-16 ++ cmpldi r7,r8,8 ++ ble cr7,L(short_path_prepare_2) ++ ld r8,24(r11) ++ cmpb r9,r8,r9 ++ cmpdi r7,r9,0 ++ bne cr7,L(short_path_prepare_2) ++ ++ /* No null byte found in the 32 bytes readed and length not reached, ++ read source again using unaligned loads and store them. */ ++ ld r9,0(r4) ++ addi r29,r3,16 ++ addi r5,r5,-16 ++ std r9,0(r3) ++ ld r9,8(r4) ++ std r9,8(r3) ++ ++ /* Align source to 16 bytes and adjust destiny and size. */ ++L(align_to_16b): ++ rldicl r9,r10,0,60 ++ rldicr r28,r10,0,59 ++ add r12,r5,r9 ++ subf r29,r9,r29 ++ ++ /* The bulk read/compare/copy loads two doublewords, compare and merge ++ in a single register for speed. This is an attempt to speed up the ++ null-checking process for bigger strings. */ ++ ++ cmpldi cr7,r12,15 ++ ble cr7,L(short_path_prepare_1_2) ++ ++ /* Main loop for large sizes, unrolled 2 times to get better use of ++ pipeline. */ ++ ld r8,0(28) ++ ld r10,8(28) ++ li r9,0 ++ cmpb r7,r8,r9 ++ cmpb r9,r10,r9 ++ or. r6,r9,r7 ++ bne cr0,L(short_path_prepare_2_3) ++ addi r5,r12,-16 ++ addi r4,r28,16 ++ std r8,0(r29) ++ std r10,8(r29) ++ cmpldi cr7,r5,15 ++ addi r9,r29,16 ++ ble cr7,L(short_path_1) ++ mr r11,r28 ++ mr r6,r29 ++ li r30,0 ++ subfic r26,r4,48 ++ subfic r27,r9,48 ++ ++ b L(loop_16b) ++ ++ .align 4 ++L(loop_start): ++ ld r31,0(r11) ++ ld r10,8(r11) ++ cmpb r0,r31,r7 ++ cmpb r8,r10,r7 ++ or. r7,r0,r8 ++ addi r5,r5,-32 ++ cmpldi cr7,r5,15 ++ add r4,r4,r26 ++ add r9,r9,r27 ++ bne cr0,L(short_path_prepare_2_2) ++ add r4,r28,r4 ++ std r31,0(r6) ++ add r9,r29,r9 ++ std r10,8(r6) ++ ble cr7,L(short_path_1) ++ ++L(loop_16b): ++ ld r10,16(r11) ++ ld r0,24(r11) ++ cmpb r8,r10,r30 ++ cmpb r7,r0,r30 ++ or. r7,r8,r7 ++ addi r12,r12,-32 ++ cmpldi r7,r12,15 ++ addi r11,r11,32 ++ bne cr0,L(short_path_2) ++ std r10,16(r6) ++ addi r6,r6,32 ++ std r0,-8(r6) ++ bgt cr7,L(loop_start) ++ ++ mr r5,r12 ++ mr r4,r11 ++ mr r9,r6 ++ b L(short_path_1) ++ ++ .align 4 ++L(short_path_prepare_1_1): ++ mr r5,r6 ++ mr r4,r7 ++ b L(short_path_1) ++L(short_path_prepare_1_2): ++ mr r5,r12 ++ mr r4,r28 ++ mr r9,r29 ++ b L(short_path_1) ++L(short_path_prepare_2): ++ mr r9,r3 ++ b L(short_path_2) ++L(short_path_prepare_2_1): ++ mr r5,r6 ++ mr r4,r7 ++ b L(short_path_2) ++L(short_path_prepare_2_2): ++ mr r5,r12 ++ mr r4,r11 ++ mr r9,r6 ++ b L(short_path_2) ++L(short_path_prepare_2_3): ++ mr r5,r12 ++ mr r4,r28 ++ mr r9,r29 ++ b L(short_path_2) ++L(zero_pad_loop_b_prepare): ++ addi r10,r9,8 ++ rldicl r5,r5,0,61 ++ b L(zero_pad_loop_b_start) ++L(zero_pad_start_prepare_1): ++ mr r5,r6 ++ mr r9,r8 ++ b L(zero_pad_start_1) ++END (FUNC_NAME) ++ ++#ifdef USE_AS_STPNCPY ++libc_hidden_def (__stpncpy) ++#else ++libc_hidden_builtin_def (strncpy) ++#endif diff --git a/SOURCES/glibc-rh1240351-9.patch b/SOURCES/glibc-rh1240351-9.patch new file mode 100644 index 00000000..99ece3e9 --- /dev/null +++ b/SOURCES/glibc-rh1240351-9.patch @@ -0,0 +1,730 @@ + Backport of + commit 8bedcb5f03c62bf6001396dafdd82fbd4da7c2db + Author: Adhemerval Zanella + Date: Wed Jan 7 07:18:30 2015 -0500 + + powerpc: Optimized strcmp for POWER8/PPC64 + + This patch adds an optimized POWER8 strcmp using unaligned accesses. + The algorithm first check the initial 16 bytes, then align the first + function source and uses unaligned loads on second argument only. + Aditional checks for page boundaries are done for unaligned cases + + ChangeLog: + 2015-01-13 Adhemerval Zanella + + * sysdeps/powerpc/powerpc64/multiarch/Makefile [sysdep_routines]: + Add strcmp-power8 object. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add __strcmp_power8 implementation. + * sysdeps/powerpc/powerpc64/multiarch/strcmp-power8.S: New file. + * sysdeps/powerpc/powerpc64/multiarch/strcmp.c (strcmp): Add + __strcmp_power8 implementation. + * sysdeps/powerpc/powerpc64/power8/strcmp.S: New file. + * NEWS: Update. + + and its dependency: + commit e23d3d2690bf63207b1a47e83a94693daebbbfe5 + Author: Vidya Ranganathan + Date: Fri Jun 6 07:56:07 2014 -0500 + + PowerPC: Optimized strcmp for PPC64/POWER7 + + Optimization is achieved on 8 byte aligned strings with double word + comparison using cmpb instruction. On unaligned strings loop unrolling + is applied for Power7 gain. + + ChangeLog: + 2014-06-11 Vidya Ranganathan + + * sysdeps/powerpc/powerpc64/power7/strcmp.S: New file: Optimization. + * sysdeps/powerpc/powerpc64/multiarch/strcmp.c: New file: + multiarch strcmp for PPC64. + * sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S: New file. + * sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S: New file. + * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcmp + multiarch optimizations. + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c: + (__libc_ifunc_impl_list): Likewise. + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index ef39917..27c8b65 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -7,9 +7,10 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ + strcat-power8 strcat-power7 strcat-ppc64 \ ++ strcmp-power8 strcmp-power7 strcmp-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ + stpncpy-power8 stpncpy-power7 stpncpy-ppc64 \ +- strncpy-power8 strncpy-power7 strncpy-ppc64 ++ strncpy-power8 strncpy-power7 strncpy-ppc64 \ + strncat-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 23bf5dc..2b38c71 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -277,5 +277,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, stpncpy, 1, + __stpncpy_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcmp.c. */ ++ IFUNC_IMPL (i, name, strcmp, ++ IFUNC_IMPL_ADD (array, i, strcmp, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strcmp_power8) ++ IFUNC_IMPL_ADD (array, i, strcmp, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strcmp_power7) ++ IFUNC_IMPL_ADD (array, i, strcmp, 1, ++ __strcmp_ppc)) + return i; + } +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S +new file mode 100644 +index 0000000..790ce8d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized strcmp implementation for POWER7. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcmp_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcmp_power7): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcmp_power7) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcmp_power7) \ ++ END_2(__strcmp_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power8.S +new file mode 100644 +index 0000000..dc4bfac +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power8.S +@@ -0,0 +1,40 @@ ++/* Optimized strcmp implementation for POWER8/PPC64. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcmp_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcmp_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcmp_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcmp_power8) \ ++ END_2(__strcmp_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S +new file mode 100644 +index 0000000..93d1277 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S +@@ -0,0 +1,43 @@ ++/* Default strcmp implementation for PowerPC64. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined SHARED && !defined NOT_IN_libc ++# undef EALIGN ++# define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcmp_ppc) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcmp_ppc): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcmp_ppc) ++ ++# undef END ++# define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcmp_ppc) \ ++ END_2(__strcmp_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ .globl __GI_strcmp; __GI_strcmp = __strcmp_ppc ++#endif ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +new file mode 100644 +index 0000000..c711969 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +@@ -0,0 +1,34 @@ ++/* Multiple versions of strcmp. PowerPC64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined SHARED && !defined NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strcmp) __strcmp_ppc attribute_hidden; ++extern __typeof (strcmp) __strcmp_power7 attribute_hidden; ++extern __typeof (strcmp) __strcmp_power8 attribute_hidden; ++ ++libc_ifunc (strcmp, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strcmp_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcmp_power7 ++ : __strcmp_ppc); ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power7/strcmp.S b/sysdeps/powerpc/powerpc64/power7/strcmp.S +new file mode 100644 +index 0000000..f16a9d8 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/strcmp.S +@@ -0,0 +1,195 @@ ++/* Optimized strcmp implementation for Power7 using 'cmpb' instruction ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* The optimization is achieved here through cmpb instruction. ++ 8byte aligned strings are processed with double word comparision ++ and unaligned strings are handled effectively with loop unrolling ++ technique */ ++ ++#include ++ ++/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) */ ++ ++EALIGN (strcmp, 4, 0) ++ CALL_MCOUNT 2 ++ ++ or r9, r3, r4 ++ rldicl. r10, r9, 0, 61 /* are s1 and s2 8 byte aligned..? */ ++ bne cr0, L(process_unaligned_bytes) ++ ++/* process input parameters on double word aligned boundary */ ++ ld r9, 0(r4) /* load s2 at offset=0 */ ++ li r10, 0 /* load mask=0 */ ++ cmpb r10, r9, r10 /* compare bytes at s2 with mask */ ++ cmpdi cr7, r10, 0 /* is NULL found ..? is end of string HIT */ ++ bne cr7, L(process_unaligned_bytes) /* process byte by byte */ ++ ++ ld r10, 0(r3) /* load s1 at offset=0 */ ++ li r8, 0 /* load mask=0 */ ++ cmpb r8, r10, r8 /* compare bytes at s1 with mask */ ++ cmpdi cr7, r8, 0 /* is NULL found ..? is end of string HIT */ ++ bne cr7, L(process_unaligned_bytes) /* process byte by byte */ ++ ++/*s1 and s2 does not contain NULL now , so compare all 8 bytes in a GO */ ++ cmpb r9, r10, r9 /* compare s1 and s2 */ ++ cmpdi cr7, r9, -1 /* compare result with 0xFFFFFFFFFFFFFFFF */ ++ bne cr7, L(process_unaligned_bytes) /* s1,s2 mismatch found */ ++ ++ addi r5, r3, 8 /* save next offset of s2 */ ++ addi r11, r4, 8 /* save next offset of s1 */ ++ ld r8, 8(r4) /* load s2 at offset=8 */ ++ li r9, 0 /* load mask=0 */ ++ cmpb r9, r8, r9 /* compare bytes at s2 with mask */ ++ cmpdi cr7, r9, 0 /* NULL found ..? */ ++ bne cr7, L(processBytes)/* update input and process bytes one by one */ ++ ++ mr r9, r4 /* save s2 */ ++ li r10, 0 /* load mask=0 */ ++ ++ ld r7, 8(r3) /* load s1 at offset=8 */ ++ cmpb r6, r7, r10 /* compare bytes at s1 with mask */ ++ cmpdi cr7, r6, 0 /* is NULL found */ ++ bne cr7, L(processBytes)/* mismatch, so process one by one */ ++ ++L(unrollDword): ++ cmpb r8, r7, r8 /* compare s1 and s2 */ ++ cmpdi cr7, r8, -1 /* compare result with 0xFFFFFFFFFFFFFFFF */ ++ bne cr7, L(processBytes)/* mismatch with s1 and s2 */ ++ ++ addi r5, r3, 16 /* save offset=16 of s1 */ ++ addi r4, r9, 16 /* save offset=16 of s2 */ ++ ld r8, 16(r9) /* load s2 at offset=16 */ ++ cmpb r7, r8, r10 /* compare bytes at s2 with mask */ ++ cmpdi cr7, r7, 0 /* NULL found ..? */ ++ bne cr7, L(update2processBytes) ++ ++ ld r7, 16(r3) /* load s1 at offset=16 */ ++ cmpb r6, r7, r10 /* check s1 for end of string */ ++ cmpdi cr7, r6, 0 /* end of s1 ?,then handle byte by byte */ ++ bne 7,L(update2processBytes) ++ ++ cmpb r8, r7, r8 /* compare s1 and s2 double words */ ++ cmpdi cr7, r8, -1 /* compare results with 0xFFFFFFFFFFFFFFFF */ ++ bne cr7,L(update2processBytes) ++ ++ addi r5, r3, 24 /* update s1 to offset=24 */ ++ addi r4, r9, 24 /* update s2 to offset=24 */ ++ ++ ld r8, 24(r9) /* load s2 */ ++ cmpb r7, r8, r10 /* compare s2 for NULL */ ++ cmpdi cr7, r7, 0 /* verify if s2 is ending now */ ++ bne cr7,L(update2processBytes) ++ ++ ld r7, 24(r3) /* load s1 at offset=24 */ ++ cmpb r6, r7, r10 /* verify for NULL */ ++ cmpdi cr7, r6, 0 /* is NULL found */ ++ bne cr7, L(update2processBytes) ++ ++ cmpb r8, r7, r8 /* compare s1 and s2 */ ++ cmpdi cr7, r8, -1 /* are s1 and s2 same ..? */ ++ bne cr7, L(update2processBytes) ++ ++ addi r7, r9, 32 /* update s2 to next double word */ ++ addi r3, r3, 32 /* update s1 to next double word */ ++ ++ ld r8, 32(r9) /* load s2 */ ++ mr r4, r7 /* save s2 */ ++ cmpb r6, r8, r10 /* compare s2 with NULL */ ++ cmpdi cr7, r6, 0 /* end of s2 ..? */ ++ bne cr7, L(process_unaligned_bytes) ++ ++ ld r6, 0(r3) /* load and compare s1 for NULL */ ++ cmpb r5, r6, r10 ++ cmpdi cr7, r5, 0 ++ bne cr7, L(process_unaligned_bytes) ++ ++ cmpb r8, r6, r8 /* compare s1 and s2 */ ++ cmpdi cr7, r8, -1 ++ bne cr7, L(process_unaligned_bytes) ++ ++ addi r5, r3, 8 /* increment s1 and d2 here */ ++ addi r11, r9, 40 ++ ++ ld r8, 40(r9) /* process s2 now */ ++ cmpb r9, r8, r10 ++ cmpdi cr7, r9, 0 ++ bne cr7, L(processBytes) ++ ++ mr r9, r7 ++ ld r7, 8(r3) /* process s1 now */ ++ cmpb r6, r7, r10 ++ cmpdi cr7, r6, 0 ++ beq cr7, L(unrollDword) /* unroll to compare s1 and s2 */ ++ ++L(processBytes): ++ mr r4, r11 /* update input params */ ++ mr r3, r5 ++ ++ .p2align 4 ++L(process_unaligned_bytes): ++ lbz r9, 0(r3) /* load byte from s1 */ ++ lbz r10, 0(r4) /* load byte from s2 */ ++ cmpdi cr7, r9, 0 /* compare *s1 with NULL */ ++ beq cr7, L(diffOfNULL) /* if *s1 is NULL , return *s1 - *s2 */ ++ cmplw cr7, r9, r10 /* compare *s1 and *s2 */ ++ bne cr7, L(ComputeDiff) /* branch to compute difference and return */ ++ ++ lbz r9, 1(r3) /* load next byte from s1 */ ++ lbz r10, 1(r4) /* load next byte from s2 */ ++ cmpdi cr7, r9, 0 /* compare *s1 with NULL */ ++ beq cr7, L(diffOfNULL) /* if *s1 is NULL , return *s1 - *s2 */ ++ cmplw cr7, r9, r10 /* compare *s1 and *s2 */ ++ bne cr7, L(ComputeDiff) /* branch to compute difference and return */ ++ ++ lbz r9, 2(r3) /* unroll 3rd byte here */ ++ lbz r10, 2(r4) ++ cmpdi cr7, r9, 0 ++ beq cr7, L(diffOfNULL) ++ cmplw cr7, r9, r10 ++ bne 7, L(ComputeDiff) ++ ++ lbz r9, 3(r3) /* unroll 4th byte now */ ++ lbz r10, 3(r4) ++ addi r3, r3, 4 /* increment s1 by unroll factor */ ++ cmpdi cr7, r9, 0 ++ cmplw cr6, 9, r10 ++ beq cr7, L(diffOfNULL) ++ addi r4, r4, 4 /* increment s2 by unroll factor */ ++ beq cr6, L(process_unaligned_bytes) /* unroll byte processing */ ++ ++ .p2align 4 ++L(ComputeDiff): ++ extsw r9, r9 ++ subf r10, r10, r9 /* compute s1 - s2 */ ++ extsw r3, r10 ++ blr /* return */ ++ ++ .p2align 4 ++L(diffOfNULL): ++ li r9, 0 ++ subf r10, r10, r9 /* compute s1 - s2 */ ++ extsw r3, r10 /* sign extend result */ ++ blr /* return */ ++ ++ .p2align 4 ++L(update2processBytes): ++ mr r3, r5 /* update and proceed */ ++ b L(process_unaligned_bytes) ++ ++END (strcmp) ++libc_hidden_builtin_def (strcmp) +diff --git a/sysdeps/powerpc/powerpc64/power8/strcmp.S b/sysdeps/powerpc/powerpc64/power8/strcmp.S +new file mode 100644 +index 0000000..223d891 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strcmp.S +@@ -0,0 +1,257 @@ ++/* Optimized strcmp implementation for PowerPC64/POWER8. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Implements the function ++ ++ size_t [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) ++ ++ The implementation uses unaligned doubleword access to avoid specialized ++ code paths depending of data alignment. Although recent powerpc64 uses ++ 64K as default, the page cross handling assumes minimum page size of ++ 4k. */ ++ ++EALIGN (strcmp, 4, 0) ++ li r0,0 ++ ++ /* Check if [s1]+32 or [s2]+32 will cross a 4K page boundary using ++ the code: ++ ++ (((size_t) s1) % PAGE_SIZE > (PAGE_SIZE - ITER_SIZE)) ++ ++ with PAGE_SIZE being 4096 and ITER_SIZE begin 32. */ ++ ++ rldicl r7,r3,0,52 ++ rldicl r9,r4,0,52 ++ cmpldi cr7,r7,4096-32 ++ bgt cr7,L(pagecross_check) ++ cmpldi cr5,r9,4096-32 ++ bgt cr5,L(pagecross_check) ++ ++ /* For short string up to 32 bytes, load both s1 and s2 using ++ unaligned dwords and compare. */ ++ ld r8,0(r3) ++ ld r10,0(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ ld r8,8(r3) ++ ld r10,8(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ ld r8,16(r3) ++ ld r10,16(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ ld r8,24(r3) ++ ld r10,24(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ addi r7,r3,32 ++ addi r4,r4,32 ++ ++L(align_8b): ++ /* Now it has checked for first 32 bytes, align source1 to doubleword ++ and adjust source2 address. */ ++ rldicl r9,r7,0,61 /* source1 alignment to doubleword */ ++ subf r4,r9,r4 /* Adjust source2 address based on source1 ++ alignment. */ ++ rldicr r7,r7,0,60 /* Align source1 to doubleword. */ ++ ++ /* At this point, source1 alignment is 0 and source2 alignment is ++ between 0 and 7. Check is source2 alignment is 0, meaning both ++ sources have the same alignment. */ ++ andi. r9,r4,0x7 ++ bne cr0,L(loop_diff_align) ++ ++ /* If both source1 and source2 are doubleword aligned, there is no ++ need for page boundary cross checks. */ ++ ++ ld r8,0(r7) ++ ld r10,0(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ .align 4 ++L(loop_equal_align): ++ ld r8,8(r7) ++ ld r10,8(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ ld r8,16(r7) ++ ld r10,16(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ ldu r8,24(r7) ++ ldu r10,24(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ ++ b L(loop_equal_align) ++ ++ /* A zero byte was found in r8 (s1 dword), r9 contains the cmpb ++ result and r10 the dword from s2. To code isolate the byte ++ up to end (including the '\0'), masking with 0xFF the remaining ++ ones: ++ ++ #if __LITTLE_ENDIAN__ ++ (__builtin_ffsl (x) - 1) = counting trailing zero bits ++ r9 = (__builtin_ffsl (r9) - 1) + 8; ++ r9 = -1UL << r9 ++ #else ++ r9 = __builtin_clzl (r9) + 8; ++ r9 = -1UL >> r9 ++ #endif ++ r8 = r8 | r9 ++ r10 = r10 | r9 */ ++ ++#ifdef __LITTLE_ENDIAN__ ++ nor r9,r9,r9 ++L(different_nocmpb): ++ neg r3,r9 ++ and r9,r9,r3 ++ cntlzd r9,r9 ++ subfic r9,r9,63 ++#else ++ not r9,r9 ++L(different_nocmpb): ++ cntlzd r9,r9 ++ subfic r9,r9,56 ++#endif ++ srd r3,r8,r9 ++ srd r10,r10,r9 ++ rldicl r10,r10,0,56 ++ rldicl r3,r3,0,56 ++ subf r3,r10,r3 ++ extsw r3,r3 ++ blr ++ ++ .align 4 ++L(pagecross_check): ++ subfic r9,r9,4096 ++ subfic r7,r7,4096 ++ cmpld cr7,r7,r9 ++ bge cr7,L(pagecross) ++ mr r7,r9 ++ ++ /* If unaligned 16 bytes reads across a 4K page boundary, it uses ++ a simple byte a byte comparison until the page alignment for s1 ++ is reached. */ ++L(pagecross): ++ add r7,r3,r7 ++ subf r9,r3,r7 ++ mtctr r9 ++ ++ .align 4 ++L(pagecross_loop): ++ /* Loads a byte from s1 and s2, compare if *s1 is equal to *s2 ++ and if *s1 is '\0'. */ ++ lbz r9,0(r3) ++ lbz r10,0(r4) ++ addi r3,r3,1 ++ addi r4,r4,1 ++ cmplw cr7,r9,r10 ++ cmpdi cr5,r9,r0 ++ bne cr7,L(pagecross_ne) ++ beq cr5,L(pagecross_nullfound) ++ bdnz L(pagecross_loop) ++ b L(align_8b) ++ ++ .align 4 ++ /* The unaligned read of source2 will cross a 4K page boundary, ++ and the different byte or NULL maybe be in the remaining page ++ bytes. Since it can not use the unaligned load, the algorithm ++ reads and compares 8 bytes to keep source1 doubleword aligned. */ ++L(check_source2_byte): ++ li r9,8 ++ mtctr r9 ++ ++ .align 4 ++L(check_source2_byte_loop): ++ lbz r9,0(r7) ++ lbz r10,0(r4) ++ addi r7,r7,1 ++ addi r4,r4,1 ++ cmplw cr7,r9,10 ++ cmpdi r5,r9,0 ++ bne cr7,L(pagecross_ne) ++ beq cr5,L(pagecross_nullfound) ++ bdnz L(check_source2_byte_loop) ++ ++ /* If source2 is unaligned to doubleword, the code needs to check ++ on each interation if the unaligned doubleword access will cross ++ a 4k page boundary. */ ++ .align 5 ++L(loop_unaligned): ++ ld r8,0(r7) ++ ld r10,0(r4) ++ cmpb r12,r8,r0 ++ cmpb r11,r8,r10 ++ orc. r9,r12,r11 ++ bne cr0,L(different_nocmpb) ++ addi r7,r7,8 ++ addi r4,r4,8 ++ ++L(loop_diff_align): ++ /* Check if [src2]+8 cross a 4k page boundary: ++ ++ srcin2 % PAGE_SIZE > (PAGE_SIZE - 8) ++ ++ with PAGE_SIZE being 4096. */ ++ rldicl r9,r4,0,52 ++ cmpldi cr7,r9,4088 ++ ble cr7,L(loop_unaligned) ++ b L(check_source2_byte) ++ ++ .align 4 ++L(pagecross_ne): ++ extsw r3,r9 ++ mr r9,r10 ++L(pagecross_retdiff): ++ subf r9,r9,r3 ++ extsw r3,r9 ++ blr ++ ++ .align 4 ++L(pagecross_nullfound): ++ li r3,0 ++ b L(pagecross_retdiff) ++END (strcmp) ++libc_hidden_builtin_def (strcmp) diff --git a/SOURCES/glibc-rh1240796.patch b/SOURCES/glibc-rh1240796.patch new file mode 100644 index 00000000..0ee4fca1 --- /dev/null +++ b/SOURCES/glibc-rh1240796.patch @@ -0,0 +1,112 @@ +commit d298c41635ce7f2dc7c3eccc842fe3aa754c0c8e +Author: Adhemerval Zanella +Date: Thu May 22 14:48:38 2014 -0500 + + PowerPC: Remove 64 bits instructions in PPC32 code + + This patch replaces the insrdi by insrwi in powerpc32 assembly. + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/memset.S +@@ -52,7 +52,7 @@ L(_memset): + + /* Align to word boundary. */ + cmplwi cr5, rLEN, 31 +- insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ ++ insrwi rCHR, rCHR, 8, 16 /* Replicate byte to halfword. */ + beq+ L(aligned) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 4 +@@ -67,7 +67,7 @@ L(g0): + /* Handle the case of size < 31. */ + L(aligned): + mtcrf 0x01, rLEN +- insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ ++ insrwi rCHR, rCHR, 16, 0 /* Replicate halfword to word. */ + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x1C +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S +@@ -50,7 +50,7 @@ L(_memset): + ble- cr1, L(small) + /* Align to word boundary. */ + cmplwi cr5, rLEN, 31 +- insrdi rCHR, rCHR, 8, 48 /* Replicate byte to halfword. */ ++ insrwi rCHR, rCHR, 8, 16 /* Replicate byte to halfword. */ + beq+ L(aligned) + mtcrf 0x01, rMEMP0 + subfic rALIGN, rALIGN, 4 +@@ -66,7 +66,7 @@ L(g0): + /* Handle the case of size < 31. */ + L(aligned): + mtcrf 0x01, rLEN +- insrdi rCHR, rCHR, 16, 32 /* Replicate halfword to word. */ ++ insrwi rCHR, rCHR, 16, 0 /* Replicate halfword to word. */ + ble cr5, L(medium) + /* Align to 32-byte boundary. */ + andi. rALIGN, rMEMP, 0x1C +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/memset.S +@@ -37,8 +37,8 @@ L(_memset): + cfi_offset(31,-8) + + /* Replicate byte to word. */ +- insrdi 4,4,8,48 +- insrdi 4,4,16,32 ++ insrwi 4,4,8,16 ++ insrwi 4,4,16,0 + + ble cr6,L(small) /* If length <= 8, use short copy code. */ + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/rawmemchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/rawmemchr.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/rawmemchr.S +@@ -29,8 +29,8 @@ ENTRY (BP_SYM(__rawmemchr)) + clrrwi r8,r3,2 /* Align the address to word boundary. */ + + /* Replicate byte to word. */ +- rldimi r4,r4,8,48 +- rldimi r4,r4,16,32 ++ insrwi r4,r4,8,16 ++ insrwi r4,r4,16,0 + + /* Now r4 has a word of c bytes. */ + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strchr.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchr.S +@@ -37,8 +37,8 @@ ENTRY (BP_SYM(strchr)) + beq cr7,L(null_match) + + /* Replicate byte to word. */ +- insrdi r4,r4,8,48 +- insrdi r4,r4,16,32 ++ insrwi r4,r4,8,16 ++ insrwi r4,r4,16,0 + + /* Now r4 has a word of c bytes and r0 has + a word of null bytes. */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/strchrnul.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/strchrnul.S +@@ -29,8 +29,8 @@ ENTRY (BP_SYM(__strchrnul)) + clrrwi r8,r3,2 /* Align the address to word boundary. */ + + /* Replicate byte to word. */ +- insrdi r4,r4,8,48 +- insrdi r4,r4,16,32 ++ insrwi r4,r4,8,16 ++ insrwi r4,r4,16,0 + + rlwinm r6,r3,3,27,28 /* Calculate padding. */ + lwz r12,0(r8) /* Load word from memory. */ diff --git a/SOURCES/glibc-rh1248208-2.patch b/SOURCES/glibc-rh1248208-2.patch new file mode 100644 index 00000000..da621da0 --- /dev/null +++ b/SOURCES/glibc-rh1248208-2.patch @@ -0,0 +1,36 @@ +diff -pruN glibc-2.17-c758a686/nptl/tst-join7mod.c glibc-2.17-c758a686.new/nptl/tst-join7mod.c +--- glibc-2.17-c758a686/nptl/tst-join7mod.c 2015-08-13 17:06:56.505685552 +0530 ++++ glibc-2.17-c758a686.new/nptl/tst-join7mod.c 2015-08-14 12:42:10.446315345 +0530 +@@ -18,6 +18,7 @@ + . */ + + #include ++#include + #include + #include + +@@ -27,7 +28,14 @@ static int running = 1; + static void * + test_run (void *p) + { +- while (atomic_load_relaxed (&running)) ++ /* Spin on the value of RUNNING till it is 1. The RHEL-7 version of atomic.h ++ does not yet have an atomic_load. We don't need an acquire/release ++ barrier either since there is no ordering to worry about, but again, ++ atomic.h does not have relaxed atomic operations. */ ++ int oldval; ++ do ++ oldval = atomic_compare_and_exchange_val_acq (&running, 0, 0); ++ while (oldval == 1); + printf ("Test running\n"); + printf ("Test finished\n"); + return NULL; +@@ -48,7 +56,7 @@ do_init (void) + static void __attribute__ ((destructor)) + do_end (void) + { +- atomic_store_relaxed (&running, 0); ++ atomic_exchange_rel (&running, 0); + int ret = pthread_join (th, NULL); + + if (ret != 0) diff --git a/SOURCES/glibc-rh1248208.patch b/SOURCES/glibc-rh1248208.patch new file mode 100644 index 00000000..756323fe --- /dev/null +++ b/SOURCES/glibc-rh1248208.patch @@ -0,0 +1,224 @@ +commit e400f3ccd36fe91d432cc7d45b4ccc799dece763 +Author: Siddhesh Poyarekar +Date: Fri Jul 24 19:13:38 2015 +0530 + + Use IE model for static variables in libc.so, libpthread.so and rtld + + The recently introduced TLS variables in the thread-local destructor + implementation (__cxa_thread_atexit_impl) used the default GD access + model, resulting in a call to __tls_get_addr. This causes a deadlock + with recent changes to the way TLS is initialized because DTV + allocations are delayed and hence despite knowing the offset to the + variable inside its TLS block, the thread has to take the global rtld + lock to safely update the TLS offset. + + This causes deadlocks when a thread is instantiated and joined inside + a destructor of a dlopen'd DSO. The correct long term fix is to + somehow not take the lock, but that will need a lot deeper change set + to alter the way in which the big rtld lock is used. + + Instead, this patch just eliminates the call to __tls_get_addr for the + thread-local variables inside libc.so, libpthread.so and rtld by + building all of their units with -mtls-model=initial-exec. + + There were concerns that the static storage for TLS is limited and + hence we should not be using it. Additionally, dynamically loaded + modules may result in libc.so looking for this static storage pretty + late in static binaries. Both concerns are valid when using TLSDESC + since that is where one may attempt to allocate a TLS block from + static storage for even those variables that are not IE. They're not + very strong arguments for the traditional TLS model though, since it + assumes that the static storage would be used sparingly and definitely + not by default. Hence, for now this would only theoretically affect + ARM architectures. + + The impact is hence limited to statically linked binaries that dlopen + modules that in turn load libc.so, all that on arm hardware. It seems + like a small enough impact to justify fixing the larger problem that + currently affects everything everywhere. + + This still does not solve the original problem completely. That is, + it is still possible to deadlock on the big rtld lock with a small + tweak to the test case attached to this patch. That problem is + however not a regression in 2.22 and hence could be tackled as a + separate project. The test case is picked up as is from Alex's patch. + + This change has been tested to verify that it does not cause any + issues on x86_64. + + ChangeLog: + + [BZ #18457] + * nptl/Makefile (tests): New test case tst-join7. + (modules-names): New test case module tst-join7mod. + * nptl/tst-join7.c: New file. + * nptl/tst-join7mod.c: New file. + * Makeconfig (tls-model): Pass -ftls-model=initial-exec for + all translation units in libc.so, libpthread.so and rtld. + +diff --git a/nptl/Makefile b/nptl/Makefile +index 140f063..aaca0a4 100644 +--- a/nptl/Makefile ++++ b/nptl/Makefile +@@ -245,7 +245,7 @@ tests = tst-typesizes \ + tst-basic7 \ + tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \ + tst-raise1 \ +- tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 \ ++ tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 tst-join7 \ + tst-detach1 \ + tst-eintr1 tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \ + tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \ +@@ -327,7 +327,8 @@ endif + modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \ + tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ + tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ +- tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod ++ tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \ ++ tst-join7mod + extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) tst-cleanup4aux.o + test-extras += $(modules-names) tst-cleanup4aux + test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names))) +@@ -532,6 +533,11 @@ $(objpfx)tst-tls6.out: tst-tls6.sh $(objpfx)tst-tls5 \ + $(rtld-installed-name) '$(test-wrapper-env)' + endif + ++$(objpfx)tst-join7: $(libdl) $(shared-thread-library) ++$(objpfx)tst-join7.out: $(objpfx)tst-join7mod.so ++$(objpfx)tst-join7mod.so: $(shared-thread-library) ++LDFLAGS-tst-join7mod.so = -Wl,-soname,tst-join7mod.so ++ + $(objpfx)tst-dlsym1: $(libdl) $(shared-thread-library) + + $(objpfx)tst-fini1: $(shared-thread-library) $(objpfx)tst-fini1mod.so +diff --git a/nptl/tst-join7.c b/nptl/tst-join7.c +new file mode 100644 +index 0000000..439d0fc +--- /dev/null ++++ b/nptl/tst-join7.c +@@ -0,0 +1,46 @@ ++/* Verify that TLS access in separate thread in a dlopened library does not ++ deadlock. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* When one dynamically loads a module, which spawns a thread to perform some ++ activities, it could be possible that TLS storage is accessed for the first ++ time in that thread. This results in an allocation request within the ++ thread, which could result in an attempt to take the rtld load_lock. This ++ is a problem because it would then deadlock with the dlopen (which owns the ++ lock), if the main thread is waiting for the spawned thread to exit. We can ++ at least ensure that this problem does not occur due to accesses within ++ libc.so, by marking TLS variables within libc.so as IE. The problem of an ++ arbitrary variable being accessed and constructed within such a thread still ++ exists but this test case does not verify that. */ ++ ++int ++do_test (void) ++{ ++ void *f = dlopen ("tst-join7mod.so", RTLD_NOW | RTLD_GLOBAL); ++ if (f) ++ dlclose (f); ++ else ++ return 1; ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/nptl/tst-join7mod.c b/nptl/tst-join7mod.c +new file mode 100644 +index 0000000..92bb381 +--- /dev/null ++++ b/nptl/tst-join7mod.c +@@ -0,0 +1,61 @@ ++/* Verify that TLS access in separate thread in a dlopened library does not ++ deadlock - the module. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static pthread_t th; ++static int running = 1; ++ ++static void * ++test_run (void *p) ++{ ++ while (atomic_load_relaxed (&running)) ++ printf ("Test running\n"); ++ printf ("Test finished\n"); ++ return NULL; ++} ++ ++static void __attribute__ ((constructor)) ++do_init (void) ++{ ++ int ret = pthread_create (&th, NULL, test_run, NULL); ++ ++ if (ret != 0) ++ { ++ printf ("failed to create thread: %s (%d)\n", strerror (ret), ret); ++ exit (1); ++ } ++} ++ ++static void __attribute__ ((destructor)) ++do_end (void) ++{ ++ atomic_store_relaxed (&running, 0); ++ int ret = pthread_join (th, NULL); ++ ++ if (ret != 0) ++ { ++ printf ("pthread_join: %s(%d)\n", strerror (ret), ret); ++ exit (1); ++ } ++ ++ printf ("Thread joined\n"); ++} +diff -pruN a/string/strerror_l.c b/string/strerror_l.c +--- a/string/strerror_l.c ++++ b/string/strerror_l.c +@@ -23,7 +23,7 @@ + #include + + +-static __thread char *last_value; ++static __thread char *last_value attribute_tls_model_ie; + + + static const char * diff --git a/SOURCES/glibc-rh1249102.patch b/SOURCES/glibc-rh1249102.patch new file mode 100644 index 00000000..f26a6a18 --- /dev/null +++ b/SOURCES/glibc-rh1249102.patch @@ -0,0 +1,25 @@ +commit a53fbd8e6cd2f69bdfa3431d616a5f332aea6664 +Author: Adhemerval Zanella +Date: Tue Jul 29 13:56:44 2014 -0500 + + PowerPC: Fix gprof entry point for LE + + This patch fixes the ELFv2 gprof entry point since the ABI + does not define function descriptors. It fixes BZ#17213. +diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h +index 76ead1d..30553c1 100644 +--- a/sysdeps/powerpc/powerpc64/entry.h ++++ b/sysdeps/powerpc/powerpc64/entry.h +@@ -23,6 +23,7 @@ extern void _start (void); + + #define ENTRY_POINT _start + ++#if _CALL_ELF != 2 + /* We have to provide a special declaration. */ + #define ENTRY_POINT_DECL(class) class void _start (void); + +@@ -33,3 +34,4 @@ extern void _start (void); + #define TEXT_START \ + ({ extern unsigned long int _start_as_data[] asm ("_start"); \ + _start_as_data[0]; }) ++#endif diff --git a/SOURCES/glibc-rh1249114.patch b/SOURCES/glibc-rh1249114.patch new file mode 100644 index 00000000..d9b7e9ac --- /dev/null +++ b/SOURCES/glibc-rh1249114.patch @@ -0,0 +1,376 @@ +commit 2e807f29595eb5b1e5d0decc6e356a3562ecc58e +Author: Stefan Liebler +Date: Thu Mar 12 11:08:11 2015 +0100 + + S/390: Fix setcontext/swapcontext which are not restoring sigmask. + + [BZ #18080] + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 5e99d7f..8f22c8d 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -64,10 +64,10 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \ + test-canon test-canon2 tst-strtoll tst-environ \ + tst-xpg-basename tst-random tst-random2 tst-bsearch \ + tst-limits tst-rand48 bug-strtod tst-setcontext \ +- test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ +- tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ +- tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \ +- tst-makecontext2 tst-strtod6 tst-unsetenv1 \ ++ tst-setcontext2 test-a64l tst-qsort tst-system testmb2 \ ++ bug-strtod2 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 \ ++ tst-rand48-2 tst-makecontext tst-strtod4 tst-strtod5 \ ++ tst-qsort2 tst-makecontext2 tst-strtod6 tst-unsetenv1 \ + tst-makecontext3 bug-getcontext bug-fmtmsg1 \ + tst-secure-getenv tst-strtod-overflow tst-strtod-round \ + tst-tininess tst-strtod-underflow +diff --git a/stdlib/tst-setcontext2.c b/stdlib/tst-setcontext2.c +new file mode 100644 +index 0000000..8582cc0 +--- /dev/null ++++ b/stdlib/tst-setcontext2.c +@@ -0,0 +1,230 @@ ++/* Testcase checks, if setcontext(), swapcontext() restores signal-mask ++ and if pending signals are delivered after those calls. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++volatile int global; ++volatile sig_atomic_t handlerCalled; ++ ++static void ++check (const char *funcName) ++{ ++ sigset_t set; ++ ++ /* check if SIGUSR2 is unblocked after setcontext-call. */ ++ sigprocmask (SIG_BLOCK, NULL, &set); ++ ++ if (sigismember (&set, SIGUSR2) != 0) ++ { ++ printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName); ++ exit (1); ++ } ++ ++ if (sigismember (&set, SIGUSR1) != 1) ++ { ++ printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName); ++ exit (1); ++ } ++} ++ ++static void ++signalmask (int how, int signum) ++{ ++ sigset_t set; ++ sigemptyset (&set); ++ sigaddset (&set, signum); ++ if (sigprocmask (how, &set, NULL) != 0) ++ { ++ printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum); ++ exit (1); ++ } ++} ++ ++static void ++signalpending (int signum, const char *msg) ++{ ++ sigset_t set; ++ sigemptyset (&set); ++ if (sigpending (&set) != 0) ++ { ++ printf ("FAIL: sigpending: %m\n"); ++ exit (1); ++ } ++ if (sigismember (&set, SIGUSR2) != 1) ++ { ++ printf ("FAIL: Signal %d is not pending %s\n", signum, msg); ++ exit (1); ++ } ++} ++ ++static void ++handler (int __attribute__ ((unused)) signum) ++{ ++ handlerCalled ++; ++} ++ ++static int ++do_test (void) ++{ ++ ucontext_t ctx, oldctx; ++ struct sigaction action; ++ pid_t pid; ++ ++ pid = getpid (); ++ ++ /* unblock SIGUSR2 */ ++ signalmask (SIG_UNBLOCK, SIGUSR2); ++ ++ /* block SIGUSR1 */ ++ signalmask (SIG_BLOCK, SIGUSR1); ++ ++ /* register handler for SIGUSR2 */ ++ action.sa_flags = 0; ++ action.sa_handler = handler; ++ sigemptyset (&action.sa_mask); ++ sigaction (SIGUSR2, &action, NULL); ++ ++ if (getcontext (&ctx) != 0) ++ { ++ printf ("FAIL: getcontext: %m\n"); ++ exit (1); ++ } ++ ++ global++; ++ ++ if (global == 1) ++ { ++ puts ("after getcontext"); ++ ++ /* block SIGUSR2 */ ++ signalmask (SIG_BLOCK, SIGUSR2); ++ ++ /* send SIGUSR2 to me */ ++ handlerCalled = 0; ++ kill (pid, SIGUSR2); ++ ++ /* was SIGUSR2 handler called? */ ++ if (handlerCalled != 0) ++ { ++ puts ("FAIL: signal handler was called, but signal was blocked."); ++ exit (1); ++ } ++ ++ /* is SIGUSR2 pending? */ ++ signalpending (SIGUSR2, "before setcontext"); ++ ++ /* SIGUSR2 will be unblocked by setcontext-call. */ ++ if (setcontext (&ctx) != 0) ++ { ++ printf ("FAIL: setcontext: %m\n"); ++ exit (1); ++ } ++ } ++ else if (global == 2) ++ { ++ puts ("after setcontext"); ++ ++ /* check SIGUSR1/2 */ ++ check ("setcontext"); ++ ++ /* was SIGUSR2 handler called? */ ++ if (handlerCalled != 1) ++ { ++ puts ("FAIL: signal handler was not called after setcontext."); ++ exit (1); ++ } ++ ++ /* block SIGUSR2 */ ++ signalmask (SIG_BLOCK, SIGUSR2); ++ ++ /* send SIGUSR2 to me */ ++ handlerCalled = 0; ++ kill (pid, SIGUSR2); ++ ++ /* was SIGUSR2 handler called? */ ++ if (handlerCalled != 0) ++ { ++ puts ("FAIL: signal handler was called, but signal was blocked."); ++ exit (1); ++ } ++ ++ /* is SIGUSR2 pending? */ ++ signalpending (SIGUSR2, "before swapcontext"); ++ ++ if (swapcontext (&oldctx, &ctx) != 0) ++ { ++ printf ("FAIL: swapcontext: %m\n"); ++ exit (1); ++ } ++ ++ puts ("after returned from swapcontext"); ++ ++ if (global != 3) ++ { ++ puts ("FAIL: returned from swapcontext without ctx-context called."); ++ exit (1); ++ } ++ ++ puts ("test succeeded"); ++ return 0; ++ } ++ else if ( global != 3 ) ++ { ++ puts ("FAIL: 'global' not incremented three times"); ++ exit (1); ++ } ++ ++ puts ("after swapcontext"); ++ /* check SIGUSR1/2 */ ++ check ("swapcontext"); ++ ++ /* was SIGUSR2 handler called? */ ++ if (handlerCalled != 1) ++ { ++ puts ("FAIL: signal handler was not called after swapcontext."); ++ exit (1); ++ } ++ ++ /* check sigmask in old context of swapcontext-call */ ++ if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1) ++ { ++ puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask."); ++ exit (1); ++ } ++ ++ if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1) ++ { ++ puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks."); ++ exit (1); ++ } ++ ++ /* change to old context, which was gathered by swapcontext() call. */ ++ setcontext (&oldctx); ++ ++ puts ("FAIL: returned from setcontext (&oldctx)"); ++ exit (1); ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S +index b19fd8d..5f60f49 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S +@@ -34,7 +34,7 @@ ENTRY(__setcontext) + lr %r1,%r2 + + /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ +- la %r2,SIG_BLOCK ++ la %r2,SIG_SETMASK + la %r3,SC_MASK(%r1) + slr %r4,%r4 + lhi %r5,_NSIG8 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +index 092f2bc..dc21b44 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +@@ -24,7 +24,7 @@ + /* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) + + Saves the machine context in oucp such that when it is activated, +- it appears as if __swapcontextt() returned again, restores the ++ it appears as if __swapcontext() returned again, restores the + machine context in ucp and thereby resumes execution in that + context. + +@@ -36,13 +36,6 @@ ENTRY(__swapcontext) + lr %r1,%r2 + lr %r0,%r3 + +- /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ +- la %r2,SIG_BLOCK +- slr %r3,%r3 +- la %r4,SC_MASK(%r1) +- lhi %r5,_NSIG8 +- svc SYS_ify(rt_sigprocmask) +- + /* Store fpu context. */ + stfpc SC_FPC(%r1) + std %f0,SC_FPRS(%r1) +@@ -71,11 +64,12 @@ ENTRY(__swapcontext) + /* Store general purpose registers. */ + stm %r0,%r15,SC_GPRS(%r1) + +- /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ +- la %r2,SIG_BLOCK ++ /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, ++ sigsetsize). */ ++ la %r2,SIG_SETMASK + lr %r5,%r0 + la %r3,SC_MASK(%r5) +- slr %r4,%r4 ++ la %r4,SC_MASK(%r1) + lhi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S +index b9a55ed..004eafc 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S +@@ -34,7 +34,7 @@ ENTRY(__setcontext) + lgr %r1,%r2 + + /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ +- la %r2,SIG_BLOCK ++ la %r2,SIG_SETMASK + la %r3,SC_MASK(%r1) + slgr %r4,%r4 + lghi %r5,_NSIG8 +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S +index 6e2630c..2688762 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S +@@ -24,7 +24,7 @@ + /* __swapcontext (ucontext_t *oucp, const ucontext_t *ucp) + + Saves the machine context in oucp such that when it is activated, +- it appears as if __swapcontextt() returned again, restores the ++ it appears as if __swapcontext() returned again, restores the + machine context in ucp and thereby resumes execution in that + context. + +@@ -36,13 +36,6 @@ ENTRY(__swapcontext) + lgr %r1,%r2 + lgr %r0,%r3 + +- /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ +- la %r2,SIG_BLOCK +- slgr %r3,%r3 +- la %r4,SC_MASK(%r1) +- lghi %r5,_NSIG8 +- svc SYS_ify(rt_sigprocmask) +- + /* Store fpu context. */ + stfpc SC_FPC(%r1) + std %f0,SC_FPRS(%r1) +@@ -71,12 +64,13 @@ ENTRY(__swapcontext) + /* Store general purpose registers. */ + stmg %r0,%r15,SC_GPRS(%r1) + +- /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ +- la %r2,SIG_BLOCK ++ /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask, ++ sigsetsize). */ ++ la %r2,SIG_SETMASK + lgr %r5,%r0 + la %r3,SC_MASK(%r5) ++ la %r4,SC_MASK(%r1) + lghi %r5,_NSIG8 +- slgr %r4,%r4 + svc SYS_ify(rt_sigprocmask) + + /* Load fpu context. */ diff --git a/SOURCES/glibc-rh1249115.patch b/SOURCES/glibc-rh1249115.patch new file mode 100644 index 00000000..ef2c83bb --- /dev/null +++ b/SOURCES/glibc-rh1249115.patch @@ -0,0 +1,121 @@ +commit 890b7a4b33d482b5c768ab47d70758b80227e9bc +Author: Stefan Liebler +Date: Tue Jul 7 16:11:14 2015 +0200 + + S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()" [BZ #18508]. + +diff --git a/stdlib/Makefile b/stdlib/Makefile +index 8f22c8d..c1e80d7 100644 +--- a/stdlib/Makefile ++++ b/stdlib/Makefile +@@ -154,3 +154,4 @@ $(objpfx)bug-getcontext: $(link-libm) + $(objpfx)tst-strtod-round: $(link-libm) + $(objpfx)tst-tininess: $(link-libm) + $(objpfx)tst-strtod-underflow: $(link-libm) ++$(objpfx)tst-makecontext: $(libdl) +diff --git a/stdlib/tst-makecontext.c b/stdlib/tst-makecontext.c +index eb6e89b..1420857 100644 +--- a/stdlib/tst-makecontext.c ++++ b/stdlib/tst-makecontext.c +@@ -19,23 +19,62 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + + ucontext_t ucp; +-char st1[8192]; ++char st1[16384]; + __thread int thr; + + int somevar = -76; + long othervar = -78L; + ++struct trace_arg ++{ ++ int cnt, size; ++}; ++ ++static _Unwind_Reason_Code ++backtrace_helper (struct _Unwind_Context *ctx, void *a) ++{ ++ struct trace_arg *arg = a; ++ if (++arg->cnt == arg->size) ++ return _URC_END_OF_STACK; ++ return _URC_NO_REASON; ++} ++ + void + cf (int i) + { ++ struct trace_arg arg = { .size = 100, .cnt = -1 }; ++ void *handle; ++ _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); ++ + if (i != othervar || thr != 94) + { + printf ("i %d thr %d\n", i, thr); + exit (1); + } + ++ /* Test if callback function of _Unwind_Backtrace is not called infinitely ++ times. See Bug 18508 or gcc bug "Bug 66303 - runtime.Caller() returns ++ infinitely deep stack frames on s390x.". ++ The go runtime calls backtrace_full() in ++ /libbacktrace/backtrace.c, which uses _Unwind_Backtrace(). */ ++ handle = dlopen (LIBGCC_S_SO, RTLD_LAZY); ++ if (handle != NULL) ++ { ++ unwind_backtrace = dlsym (handle, "_Unwind_Backtrace"); ++ if (unwind_backtrace != NULL) ++ { ++ unwind_backtrace (backtrace_helper, &arg); ++ assert (arg.cnt != -1 && arg.cnt < 100); ++ } ++ dlclose (handle); ++ } ++ + /* Since uc_link below has been set to NULL, setcontext is supposed to + terminate the process normally after this function returns. */ + } +diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S +index ab172bb..365c2b0 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S +@@ -17,6 +17,14 @@ + + #include + ++/* We do not want .eh_frame info so that __makecontext_ret stops unwinding ++ if backtrace was called within a context created by makecontext. (There ++ is also no .eh_frame info for _start or thread_start.) */ ++#undef cfi_startproc ++#define cfi_startproc ++#undef cfi_endproc ++#define cfi_endproc ++ + ENTRY(__makecontext_ret) + basr %r14,%r7 + ltr %r8,%r8 /* Check whether uc_link is 0. */ +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S +index cbd88e1..c4a43bd 100644 +--- a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S +@@ -17,6 +17,14 @@ + + #include + ++/* We do not want .eh_frame info so that __makecontext_ret stops unwinding ++ if backtrace was called within a context created by makecontext. (There ++ is also no .eh_frame info for _start or thread_start.) */ ++#undef cfi_startproc ++#define cfi_startproc ++#undef cfi_endproc ++#define cfi_endproc ++ + ENTRY(__makecontext_ret) + basr %r14,%r7 + ltgr %r8,%r8 /* Check whether uc_link is 0. */ diff --git a/SOURCES/glibc-rh1255822.patch b/SOURCES/glibc-rh1255822.patch new file mode 100644 index 00000000..59541c76 --- /dev/null +++ b/SOURCES/glibc-rh1255822.patch @@ -0,0 +1,34 @@ +commit a3b473373ee43a292f5ec68a7fda6b9cfb26a9b0 +Author: Florian Weimer +Date: Tue Jun 21 21:29:21 2016 +0200 + + malloc: Avoid premature fallback to mmap [BZ #20284] + + Before this change, the while loop in reused_arena which avoids + returning a corrupt arena would never execute its body if the selected + arena were not corrupt. As a result, result == begin after the loop, + and the function returns NULL, triggering fallback to mmap. + +Index: glibc-2.17-c758a686/malloc/arena.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/arena.c ++++ glibc-2.17-c758a686/malloc/arena.c +@@ -907,14 +907,12 @@ reused_arena (mstate avoid_arena) + { + result = result->next; + if (result == begin) +- break; ++ /* We looped around the arena list. We could not find any ++ arena that was either not corrupted or not the one we ++ wanted to avoid. */ ++ return NULL; + } + +- /* We could not find any arena that was either not corrupted or not the one +- we wanted to avoid. */ +- if (result == begin || result == avoid_arena) +- return NULL; +- + /* No arena available without contention. Wait for the next in line. */ + LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena); + (void)mutex_lock(&result->mutex); diff --git a/SOURCES/glibc-rh1256317-0.patch b/SOURCES/glibc-rh1256317-0.patch new file mode 100644 index 00000000..04f2d691 --- /dev/null +++ b/SOURCES/glibc-rh1256317-0.patch @@ -0,0 +1,162 @@ +commit ac63a0783cdee8454c84fc45f37330d98b6039e7 +Author: Dmitry V. Levin +Date: Fri Jun 5 22:20:13 2015 +0000 + + Prepare for restoration of .interp section in libpthread.so + + Make runtime-linker.h available outside $(elf-objpfx) by moving + the file to $(common-objpfx) and the rules for it to Makerules. + + Tested for x86_64 and x86 (testsuite, and that no compiled code + changed by the patch). + + * Makeconfig (+interp): Remove unused variable. + * elf/Makefile ($(objpfx)interp.os): Define for [$(build-shared) = yes] + only. Depend on $(common-objpfx)runtime-linker.h instead of + $(elf-objpfx)runtime-linker.h. + ($(elf-objpfx)runtime-linker.h): Rename to + $(common-objpfx)runtime-linker.h and move ... + * Makerules [$(build-shared) = yes]: ... here. + * elf/interp.c: Include instead of + . + +commit 78ad175b3060aae058ed5d05ced2bc58714901cd +Author: Gleb Fotengauer-Malinovskiy +Date: Tue Jun 2 21:04:06 2015 +0300 + + nptl: restore .interp section in libpthread.so + + In commit 02657da2cf4457804ed938ee08b8316249126444, .interp section + was removed from libpthread.so. This led to an error: + + $ /lib64/libpthread.so.0 + Native POSIX Threads Library by Ulrich Drepper et al + Copyright (C) 2015 Free Software Foundation, Inc. + This is free software; see the source for copying conditions. + There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. + Forced unwind support included. + Segmentation fault + + (gdb) bt + #0 0x00000000000055a6 in _exit@plt () + + Unfortunately, there is no way to add a regression test for the bug + because .interp specifies the path to dynamic linker of the target + system. + + [BZ #18479] + * nptl/pt-interp.c: New file. + * nptl/Makefile (libpthread-routines, libpthread-shared-only-routines): + Add pt-interp. + [$(build-shared) = yes] ($(objpfx)pt-interp.os): Depend on + $(common-objpfx)runtime-linker.h. + +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -30,7 +30,7 @@ routines = alloca_cutoff forward libc-lo + libc-cleanup + shared-only-routines = forward + +-libpthread-routines = nptl-init vars events version \ ++libpthread-routines = nptl-init vars events version pt-interp \ + pthread_create pthread_exit pthread_detach \ + pthread_join pthread_tryjoin pthread_timedjoin \ + pthread_self pthread_equal pthread_yield \ +@@ -131,7 +131,8 @@ libpthread-routines = nptl-init vars eve + # pthread_setgid pthread_setegid pthread_setregid \ + # pthread_setresgid + +-libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind ++libpthread-shared-only-routines = version pt-interp pt-allocrtsig \ ++ unwind-forcedunwind + libpthread-static-only-routines = pthread_atfork + + # Since cancellation handling is in large parts handled using exceptions +@@ -591,6 +592,8 @@ $(objpfx)banner.h: Banner + generated += banner.h + # Give libpthread.so an entry point and make it directly runnable itself. + LDFLAGS-pthread.so += -e __nptl_main ++# pt-interp.c exists just to get the runtime linker path into libpthread.so. ++$(objpfx)pt-interp.os: $(common-objpfx)runtime-linker.h + endif + + ifeq ($(run-built-tests),yes) +Index: glibc-2.17-c758a686/nptl/pt-interp.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/pt-interp.c +@@ -0,0 +1 @@ ++#include +Index: glibc-2.17-c758a686/Makeconfig +=================================================================== +--- glibc-2.17-c758a686.orig/Makeconfig ++++ glibc-2.17-c758a686/Makeconfig +@@ -566,7 +566,6 @@ endif + # Variants of the two previous definitions for statically linking programs. + +prectorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtbeginT.o` + +postctorT = `$(CC) $(sysdep-LDFLAGS) --print-file-name=crtend.o` +-+interp = $(addprefix $(elf-objpfx),interp.os) + csu-objpfx = $(common-objpfx)csu/ + elf-objpfx = $(common-objpfx)elf/ + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -344,16 +344,10 @@ $(objpfx)ld.so: $(objpfx)librtld.os $(ld + $(READELF) -s $@ \ + | $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }' + ++ifeq (yes,$(build-shared)) + # interp.c exists just to get the runtime linker path into libc.so. +-$(objpfx)interp.os: $(elf-objpfx)runtime-linker.h +- +-$(elf-objpfx)runtime-linker.h: $(elf-objpfx)runtime-linker.st; @: +-$(elf-objpfx)runtime-linker.st: $(common-objpfx)config.make +- $(name-target-directory) +- echo '#define RUNTIME_LINKER "$(rtlddir)/$(rtld-installed-name)"' \ +- > ${@:st=T} +- $(move-if-change) ${@:st=T} ${@:st=h} +- touch $@ ++$(objpfx)interp.os: $(common-objpfx)runtime-linker.h ++endif + + ifneq (ld.so,$(rtld-installed-name)) + # Make sure ld.so.1 exists in the build directory so we can link +Index: glibc-2.17-c758a686/elf/interp.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/interp.c ++++ glibc-2.17-c758a686/elf/interp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include + + const char __invoke_dynamic_linker__[] __attribute__ ((section (".interp"))) + = RUNTIME_LINKER; +Index: glibc-2.17-c758a686/Makerules +=================================================================== +--- glibc-2.17-c758a686.orig/Makerules ++++ glibc-2.17-c758a686/Makerules +@@ -123,6 +123,16 @@ $(common-objpfx)libc-abis.stamp: $(..)sc + common-generated += $(common-objpfx)libc-abis.h + endif # avoid-generated + ++ifeq (yes,$(build-shared)) ++$(common-objpfx)runtime-linker.h: $(common-objpfx)runtime-linker.stamp; @: ++$(common-objpfx)runtime-linker.stamp: $(common-objpfx)config.make ++ $(make-target-directory) ++ echo '#define RUNTIME_LINKER "$(rtlddir)/$(rtld-installed-name)"' \ ++ > ${@:stamp=T} ++ $(move-if-change) ${@:stamp=T} ${@:stamp=h} ++ touch $@ ++endif ++ + # Make sure the subdirectory for object files gets created. + ifdef objpfx + ifeq (,$(wildcard $(objpfx).)) diff --git a/SOURCES/glibc-rh1256317-1.patch b/SOURCES/glibc-rh1256317-1.patch new file mode 100644 index 00000000..4de81e4f --- /dev/null +++ b/SOURCES/glibc-rh1256317-1.patch @@ -0,0 +1,46 @@ +commit 7a9ebfa159f392fcf1c3aa172fc5bd6bd1eeea63 +Author: Siddhesh Poyarekar +Date: Mon Nov 24 15:24:34 2014 +0530 + + Use IS_IN internally only + + This change is only useful for the conformance tests since the headers + changed are not installed. The conformance tests fail due to IS_IN + not being defined, so wrap it with a check to make sure that _ISOMAC + is defined. + + * include/bits/stdlib-float.h: Use IS_IN only if _ISOMAC is + defined. + * include/mqueue.h: Likewise. + * include/stdlib.h: Likewise. + +Index: glibc-2.17-c758a686/include/bits/stdlib-float.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/bits/stdlib-float.h ++++ glibc-2.17-c758a686/include/bits/stdlib-float.h +@@ -1,4 +1,8 @@ +-/* No floating-point inline functions in rtld. */ +-#if !IS_IN (rtld) ++/* No floating-point inline functions in rtld and for the conform tests. */ ++#ifdef _ISOMAC + # include ++#else ++# if !IS_IN (rtld) ++# include ++# endif + #endif +Index: glibc-2.17-c758a686/include/mqueue.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/mqueue.h ++++ glibc-2.17-c758a686/include/mqueue.h +@@ -1,7 +1,9 @@ + #include + +-#if IS_IN (librt) ++#ifndef _ISOMAC ++# if IS_IN (librt) + hidden_proto (mq_timedsend) + hidden_proto (mq_timedreceive) + hidden_proto (mq_setattr) ++# endif + #endif diff --git a/SOURCES/glibc-rh1256317-10.patch b/SOURCES/glibc-rh1256317-10.patch new file mode 100644 index 00000000..5e414b86 --- /dev/null +++ b/SOURCES/glibc-rh1256317-10.patch @@ -0,0 +1,46 @@ +commit fb6784e3068a747ead34e6dee6a9a1978668a955 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 12:33:44 2014 +0530 + + Remove IS_IN_ldconfig + + Replace with IS_IN (ldconfig). No change in generated code. + + * elf/Makefile (CFLAGS-ldconfig.c): Remove definition of + IS_IN_ldconfig. + * sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c: Use IS_IN. + * sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h: Likewise. + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -437,7 +437,7 @@ $(objpfx)pldd: $(pldd-modules:%=$(objpfx + + SYSCONF-FLAGS := -D'SYSCONFDIR="$(sysconfdir)"' + CFLAGS-ldconfig.c = $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \ +- -D'SLIBDIR="$(slibdir)"' -DIS_IN_ldconfig=1 -DNOT_IN_libc=1 ++ -D'SLIBDIR="$(slibdir)"' -DNOT_IN_libc + libof-ldconfig = ldconfig + CFLAGS-dl-cache.c = $(SYSCONF-FLAGS) + CFLAGS-cache.c = $(SYSCONF-FLAGS) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c +@@ -1,4 +1,4 @@ +-#ifdef IS_IN_ldconfig ++#if IS_IN (ldconfig) + # include + #else + # include +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h +@@ -1,4 +1,4 @@ +-#ifdef IS_IN_ldconfig ++#if IS_IN (ldconfig) + # include + #else + # include diff --git a/SOURCES/glibc-rh1256317-11.patch b/SOURCES/glibc-rh1256317-11.patch new file mode 100644 index 00000000..5d258267 --- /dev/null +++ b/SOURCES/glibc-rh1256317-11.patch @@ -0,0 +1,41 @@ +commit 2886d2d14dd7de6339b04505c5d2f9fc5c844751 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 12:21:01 2014 +0530 + + Remove IS_IN_libc + + Replace it with IS_IN (libc) and remove the one place that it + is defined in. The generated code remains unchanged on x86_64. + + * include/shlib-compat.h [!NOT_IN_libc]: Remove. + * nss/nss_files/files-parse.c (IS_IN_libc): Replace with + IS_IN (libc). + +Index: glibc-2.17-c758a686/include/shlib-compat.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/shlib-compat.h ++++ glibc-2.17-c758a686/include/shlib-compat.h +@@ -49,10 +49,6 @@ + && (!(ABI_##lib##_##obsoleted - 0) \ + || ((ABI_##lib##_##introduced - 0) < (ABI_##lib##_##obsoleted - 0)))) + +-# ifndef NOT_IN_libc +-# define IS_IN_libc 1 +-# endif +- + /* That header also defines symbols like `VERSION_libm_GLIBC_2_1' to + the version set name to use for e.g. symbols first introduced into + libm in the GLIBC_2.1 version. Definitions of symbols with explicit +Index: glibc-2.17-c758a686/nss/nss_files/files-parse.c +=================================================================== +--- glibc-2.17-c758a686.orig/nss/nss_files/files-parse.c ++++ glibc-2.17-c758a686/nss/nss_files/files-parse.c +@@ -72,7 +72,7 @@ struct parser_data + /* Export the line parser function so it can be used in nss_db. */ + # define parser_stclass /* Global */ + # define parse_line CONCAT(_nss_files_parse_,ENTNAME) +-# ifdef IS_IN_libc ++# if IS_IN (libc) + /* We are defining one of the functions that actually lives in libc + because it is used to implement fget*ent and suchlike. */ + # define nss_files_parse_hidden_def(name) libc_hidden_def (name) diff --git a/SOURCES/glibc-rh1256317-12.patch b/SOURCES/glibc-rh1256317-12.patch new file mode 100644 index 00000000..393d48c9 --- /dev/null +++ b/SOURCES/glibc-rh1256317-12.patch @@ -0,0 +1,25 @@ +commit 9a4848572bec992781311995e9e5e46eb226ce97 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 12:04:26 2014 +0530 + + Define IN_MODULE for translation units that define NOT_IN_libc + + Make sure that all instances where NOT_IN_libc is defined also defines + IN_MODULE to facilitate removal NOT_IN_libc in future passes. + + Verified that the generated code is unchanged on x86_64. + + * elf/Makefile (libof-sotruss-lib): Set as extramodules. + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -98,6 +98,7 @@ extra-objs += sotruss-lib.os sotruss-lib + install-others += $(inst_auditdir)/sotruss-lib.so + install-bin-script += sotruss + generated += sotruss ++libof-sotruss-lib = extramodules + CPPFLAGS-sotruss-lib = -DNOT_IN_libc + $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os + $(build-module-asneeded) diff --git a/SOURCES/glibc-rh1256317-13.patch b/SOURCES/glibc-rh1256317-13.patch new file mode 100644 index 00000000..e4a1fc83 --- /dev/null +++ b/SOURCES/glibc-rh1256317-13.patch @@ -0,0 +1,153 @@ +commit a10178bda190a62e7e3f56773f55f23cf06848a7 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 12:03:11 2014 +0530 + + Remove IN_LIB + + Replace with IS_IN and IS_IN_LIB macros instead. This change results + in a change in generated code, because it fixes a subtle bug. The bug + was introduced when systemtap probes were added to lowlevellock.h, + which resulted in stap-probe.h being included in a number of places. + stap-probe.h always defines IN_LIB, which breaks a check in errno.h + and netdb.h since they rely on that macro to decide whether to + implement an internal version of a declaration or an external one. + + The components that see a code change due to this are: + + iconv_prog + libmemusage.so + libpcprofile.so + libSegFault.so + libutil.so.1 + locale + localedef + nscd + + All other built components (i.e. libc, libpthread, etc.) remain + unchanged by this on x86_64. + + * elf/Makefile (CPPFLAGS-.os): Remove IN_LIB. + * elf/rtld-Rules (rtld-CPPFLAGS): Likewise. + * extra-lib.mk (CPPFLAGS-$(lib)): Likewise. + * include/libc-symbols.h (IS_IN_LIB): New macro. + * include/errno.h: Use IS_IN_LIB instead of IN_LIB. + * include/netdb.h: Likewise. + * include/stap-probe.h: Remove all uses of IN_LIB. + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -443,7 +443,7 @@ CFLAGS-cache.c = $(SYSCONF-FLAGS) + CFLAGS-rtld.c = $(SYSCONF-FLAGS) + + CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\ +- -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld) ++ -DNOT_IN_libc=1 -DIS_IN_rtld=1) + + # Disable any optimization which might result in function calls during early + # dynamic loader startup. We disable -ftree-loop-distribute-patterns which +Index: glibc-2.17-c758a686/elf/rtld-Rules +=================================================================== +--- glibc-2.17-c758a686.orig/elf/rtld-Rules ++++ glibc-2.17-c758a686/elf/rtld-Rules +@@ -134,6 +134,6 @@ lib := rtld + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + + # This here is the whole point of all the shenanigans. +-rtld-CPPFLAGS := -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld ++rtld-CPPFLAGS := -DNOT_IN_libc=1 -DIS_IN_rtld=1 + + endif +Index: glibc-2.17-c758a686/extra-lib.mk +=================================================================== +--- glibc-2.17-c758a686.orig/extra-lib.mk ++++ glibc-2.17-c758a686/extra-lib.mk +@@ -101,4 +101,4 @@ ifneq (,$(cpp-srcs-left)) + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + endif + +-CPPFLAGS-$(lib) := -DNOT_IN_libc=1 -DIS_IN_$(lib)=1 -DIN_LIB=$(lib) ++CPPFLAGS-$(lib) := -DNOT_IN_libc=1 -DIS_IN_$(lib)=1 +Index: glibc-2.17-c758a686/include/errno.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/errno.h ++++ glibc-2.17-c758a686/include/errno.h +@@ -17,7 +17,7 @@ + # define errno rtld_errno + extern int rtld_errno attribute_hidden; + +-# elif !defined NOT_IN_libc || defined IN_LIB ++# elif !defined NOT_IN_libc || IS_IN_LIB + + # include + +@@ -29,7 +29,7 @@ extern int rtld_errno attribute_hidden; + # endif + extern __thread int errno attribute_tls_model_ie; + +-# endif /* !NOT_IN_libc || IN_LIB */ ++# endif /* !NOT_IN_libc || IS_IN_LIB */ + + # define __set_errno(val) (errno = (val)) + +Index: glibc-2.17-c758a686/include/libc-symbols.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/libc-symbols.h ++++ glibc-2.17-c758a686/include/libc-symbols.h +@@ -23,6 +23,11 @@ + #define IN_MODULE PASTE_NAME (MODULE_, MODULE_NAME) + #define IS_IN(lib) (IN_MODULE == MODULE_##lib) + ++/* Returns true if the current module is a versioned library. Versioned ++ library names culled from shlib-versions files are assigned a MODULE_* ++ value lower than MODULE_LIBS_BEGIN. */ ++#define IS_IN_LIB (IN_MODULE > MODULE_LIBS_BEGIN) ++ + #define PASTE_NAME(a,b) PASTE_NAME1 (a,b) + #define PASTE_NAME1(a,b) a##b + +Index: glibc-2.17-c758a686/include/netdb.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/netdb.h ++++ glibc-2.17-c758a686/include/netdb.h +@@ -3,7 +3,7 @@ + + #ifndef _ISOMAC + /* Macros for accessing h_errno from inside libc. */ +-# if !defined NOT_IN_libc || defined IN_LIB ++# if !defined NOT_IN_libc || IS_IN_LIB + # undef h_errno + # ifdef _LIBC_REENTRANT + # include +@@ -16,7 +16,7 @@ extern __thread int h_errno attribute_tl + # else + extern int h_errno; + # endif /* _LIBC_REENTRANT */ +-# endif /* !NOT_IN_libc || IN_LIB */ ++# endif /* !NOT_IN_libc || IS_IN_LIB */ + # define __set_h_errno(x) (h_errno = (x)) + + libc_hidden_proto (hstrerror) +Index: glibc-2.17-c758a686/include/stap-probe.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/stap-probe.h ++++ glibc-2.17-c758a686/include/stap-probe.h +@@ -32,18 +32,6 @@ + STAP_PROBEn (provider, name, arg1, ..., argn). For "provider" we paste + in MODULE_NAME (libc, libpthread, etc.) automagically. */ + +-# ifndef NOT_IN_libc +-# define IN_LIB libc +-# elif !defined IN_LIB +-/* This is intentionally defined with extra unquoted commas in it so +- that macro substitution will bomb out when it is used. We don't +- just use #error here, so that this header can be included by +- other headers that use LIBC_PROBE inside their own macros. We +- only want such headers to fail to compile if those macros are +- actually used in a context where IN_LIB has not been defined. */ +-# define IN_LIB ,,,missing -DIN_LIB=... -- not extra-lib.mk?,,, +-# endif +- + # define LIBC_PROBE(name, n, ...) \ + LIBC_PROBE_1 (MODULE_NAME, name, n, ## __VA_ARGS__) diff --git a/SOURCES/glibc-rh1256317-14.patch b/SOURCES/glibc-rh1256317-14.patch new file mode 100644 index 00000000..b9d038f6 --- /dev/null +++ b/SOURCES/glibc-rh1256317-14.patch @@ -0,0 +1,105 @@ +Again we have to fix librtkaio to use MODULE_NAME definitions to +work around the changes we are making and preserve ABI/API. + +commit 279bc5b3c384c09746fbadb2b68c6db9e833c064 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 11:42:00 2014 +0530 + + Use MODULE_NAME in stap-probe instead of IN_LIB + + Define MODULE_NAME in the build command and define IN_MODULE using + MODULE_NAME. Verified that the generated code is unchanged on x86_64. + + * Makeconfig (module-cppflags-real): Define MODULE_NAME + instead of IN_MODULE. + * include/libc-symbols.h (IN_MODULE): Define using + MODULE_NAME. + (PASTE_NAME, PASTE_NAME1): New macros. + * include/stap-probe.h (LIBC_PROBE_1): Use MODULE_NAME instead + of IN_LIB. + (STAP_PROBE_ASM): Likewise. + +Index: glibc-2.17-c758a686/Makeconfig +=================================================================== +--- glibc-2.17-c758a686.orig/Makeconfig ++++ glibc-2.17-c758a686/Makeconfig +@@ -741,7 +741,7 @@ in-module = $(subst -,_,$(firstword $(li + libc)) + + module-cppflags-real = -include $(common-objpfx)libc-modules.h \ +- -DIN_MODULE=MODULE_$(in-module) ++ -DMODULE_NAME=$(in-module) + + # We don't need libc-modules.h and the MODULE_NAME definition for .v.i + # files. These targets don't (and will likely never need to) use the IS_IN +@@ -940,7 +940,7 @@ postclean-generated += soversions.mk sov + before-compile += $(common-objpfx)libc-modules.h + ifeq ($(soversions.mk-done),t) + # Generate a header with macro definitions for use with the IS_IN macro. +-# These are the possible values for the IN_MODULE macro defined when building ++# These are the possible values for the MODULE_NAME macro defined when building + # sources, to identify which module the translation unit is going to be built + # into. + $(common-objpfx)libc-modules.h: $(common-objpfx)libc-modules.stmp; @: +Index: glibc-2.17-c758a686/include/libc-symbols.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/libc-symbols.h ++++ glibc-2.17-c758a686/include/libc-symbols.h +@@ -20,8 +20,12 @@ + #ifndef _LIBC_SYMBOLS_H + #define _LIBC_SYMBOLS_H 1 + ++#define IN_MODULE PASTE_NAME (MODULE_, MODULE_NAME) + #define IS_IN(lib) (IN_MODULE == MODULE_##lib) + ++#define PASTE_NAME(a,b) PASTE_NAME1 (a,b) ++#define PASTE_NAME1(a,b) a##b ++ + /* This file's macros are included implicitly in the compilation of every + file in the C library by -imacros. + +Index: glibc-2.17-c758a686/include/stap-probe.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/stap-probe.h ++++ glibc-2.17-c758a686/include/stap-probe.h +@@ -30,7 +30,7 @@ + + Systemtap's header defines the macros STAP_PROBE (provider, name) and + STAP_PROBEn (provider, name, arg1, ..., argn). For "provider" we paste +- in the IN_LIB name (libc, libpthread, etc.) automagically. */ ++ in MODULE_NAME (libc, libpthread, etc.) automagically. */ + + # ifndef NOT_IN_libc + # define IN_LIB libc +@@ -45,7 +45,7 @@ + # endif + + # define LIBC_PROBE(name, n, ...) \ +- LIBC_PROBE_1 (IN_LIB, name, n, ## __VA_ARGS__) ++ LIBC_PROBE_1 (MODULE_NAME, name, n, ## __VA_ARGS__) + + # define LIBC_PROBE_1(lib, name, n, ...) \ + STAP_PROBE##n (lib, name, ## __VA_ARGS__) +@@ -53,7 +53,7 @@ + # define STAP_PROBE0 STAP_PROBE + + # define LIBC_PROBE_ASM(name, template) \ +- STAP_PROBE_ASM (IN_LIB, name, template) ++ STAP_PROBE_ASM (MODULE_NAME, name, template) + + # define LIBC_PROBE_ASM_OPERANDS STAP_PROBE_ASM_OPERANDS + +Index: glibc-2.17-c758a686/rtkaio/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/rtkaio/Makefile ++++ glibc-2.17-c758a686/rtkaio/Makefile +@@ -70,7 +70,9 @@ CFLAGS-kaio_librt-cancellation.c = -fasy + LDFLAGS-rtkaio.so = -Wl,-soname=lib$(libprefix)rt.so$(librt.so-version) \ + -Wl,--enable-new-dtags,-z,nodelete + CPPFLAGS-librtkaio += -UIN_MODULE -DIN_MODULE=MODULE_librt \ +- -UIS_IN_librt -DIS_IN_librt=1 -I$(..)rt ++ -UMODULE_NAME -DMODULE_NAME=librt \ ++ -UIS_IN_librt -DIS_IN_librt=1 \ ++ -I$(..)rt + + rpath-dirs := $(patsubst rt,rtkaio,$(rpath-dirs)) diff --git a/SOURCES/glibc-rh1256317-15.patch b/SOURCES/glibc-rh1256317-15.patch new file mode 100644 index 00000000..4379bd5b --- /dev/null +++ b/SOURCES/glibc-rh1256317-15.patch @@ -0,0 +1,220 @@ +commit 130ac68ca25c9aa65e027e3e37337bc048205c69 +Author: Siddhesh Poyarekar +Date: Wed Nov 19 12:16:00 2014 +0530 + + Auto-generate libc-modules.h + + Remove libc-modules.h from the tree and auto-generate it from + soversions.i and the list of modules in the built-modules variable + defined in Makeconfig. Macros generated have increasing numbered + values, with built-modules having lower values starting from 1, + following which a separator value LIBS_BEGIN is added and then finally + the library names from soversions.i are appended to the list. This + allows us to conveniently differentiate between the versioned + libraries and other built modules, which is needed in errno.h and + netdb.h to decide whether to use an internal symbol or an external + one. + + Verified that generated code remains unchanged on x86_64. + + * Makeconfig (built-modules): List non-library modules to be + built. + (module-cppflags): Include libc-modules.h for + everything except shlib-versions.v.i. + (CPPFLAGS): Use it. + (before-compile): Add libc-modules.h. + ($(common-objpfx)libc-modules.h, + $(common-objpfx)libc-modules.stmp): New targets. + (common-generated): Add libc-modules.h and libc-modules.stmp. + ($(common-objpfx)Versions.v.i): Depend on libc-modules.h. + * include/libc-symbols.h: Don't include libc-modules.h. + * include/libc-modules.h: Remove file. + * scripts/gen-libc-modules.awk: New script to generate + libc-modules.h. + * sysdeps/unix/Makefile ($(common-objpfx)sysd-syscalls): + Depend on libc-modules.stmp. + +commit 8a257e2cb50cd8e8e3e2368d80bf325ea4086cf9 +Author: Roland McGrath +Date: Thu Apr 9 14:42:29 2015 -0700 + + Omit libc-modules.h for all .v.i files. + +Index: glibc-2.17-c758a686/Makeconfig +=================================================================== +--- glibc-2.17-c758a686.orig/Makeconfig ++++ glibc-2.17-c758a686/Makeconfig +@@ -730,19 +730,34 @@ endif # $(+cflags) == "" + # of many little headers in the include directory. + libio-include = -I$(..)libio + ++# List of non-library modules that we build. ++built-modules = iconvprogs iconvdata ldconfig lddlibc4 libmemusage \ ++ libSegFault libpcprofile librpcsvc locale-programs \ ++ memusagestat nonlib nscd extramodules libnldbl ++ + in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \ + $(libof-$( ${@:stmp=T} ++ $(move-if-change) ${@:stmp=T} ${@:stmp=h} ++ touch $@ ++ ++endif ++ ++common-generated += libc-modules.h libc-modules.stmp ++ + # Generate the header containing the names of all shared libraries. + # We use a stamp file to avoid unnecessary recompilations. + before-compile += $(common-objpfx)gnu/lib-names.h +Index: glibc-2.17-c758a686/include/libc-modules.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/libc-modules.h ++++ /dev/null +@@ -1,41 +0,0 @@ +-/* Valid values for the IN_MODULE macro, which is defined for each source file +- during compilation to indicate which module it is to be built into. +- +- TODO: This file should eventually be auto-generated. */ +-#define MODULE_libc 1 +-#define MODULE_libpthread 2 +-#define MODULE_rtld 3 +-#define MODULE_libdl 4 +-#define MODULE_libm 5 +-#define MODULE_iconvprogs 6 +-#define MODULE_iconvdata 7 +-#define MODULE_lddlibc4 8 +-#define MODULE_locale_programs 9 +-#define MODULE_memusagestat 10 +-#define MODULE_libutil 12 +-#define MODULE_libBrokenLocale 13 +-#define MODULE_libmemusage 15 +-#define MODULE_libresolv 16 +-#define MODULE_libnss_db 17 +-#define MODULE_libnss_files 18 +-#define MODULE_libnss_dns 19 +-#define MODULE_libnss_compat 20 +-#define MODULE_libnss_hesiod 21 +-#define MODULE_libnss_nis 22 +-#define MODULE_libnss_nisplus 23 +-#define MODULE_libanl 24 +-#define MODULE_librt 25 +-#define MODULE_libSegFault 26 +-#define MODULE_libthread_db 27 +-#define MODULE_libcidn 28 +-#define MODULE_libcrypt 29 +-#define MODULE_libnsl 30 +-#define MODULE_libpcprofile 31 +-#define MODULE_librpcsvc 32 +-#define MODULE_nscd 33 +-#define MODULE_ldconfig 34 +-#define MODULE_libnldbl 35 +- +-/* Catch-all for test modules and other binaries. */ +-#define MODULE_nonlib 98 +-#define MODULE_extramodules 99 +Index: glibc-2.17-c758a686/include/libc-symbols.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/libc-symbols.h ++++ glibc-2.17-c758a686/include/libc-symbols.h +@@ -20,9 +20,6 @@ + #ifndef _LIBC_SYMBOLS_H + #define _LIBC_SYMBOLS_H 1 + +-/* Pull in definitions for the MODULE_* macros. */ +-#include +- + #define IS_IN(lib) (IN_MODULE == MODULE_##lib) + + /* This file's macros are included implicitly in the compilation of every +Index: glibc-2.17-c758a686/scripts/gen-libc-modules.awk +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/scripts/gen-libc-modules.awk +@@ -0,0 +1,34 @@ ++# Generate a header file that defines the MODULE_* macros for each library and ++# module we build in glibc. The library names are pulled in from soversions.i ++# and the additional modules are passed in the BUILDLIST variable. ++BEGIN { ++ # BUILDLIST is set from the build-list variable in Makeconfig and is a space ++ # separated list of non-library modules that we build in glibc. ++ num = split (buildlist, libs, " ") ++ # Separate the built modules from the libraries. ++ libs[++num] = "LIBS_BEGIN" ++} ++ ++# Skip over comments. ++$1 == "#" { ++ next ++} ++ ++# We have only one special case in soversions.i parsing, which is to replace ld ++# with rtld since that's what we call it throughout the sources. ++match (FILENAME, ".*soversions.i") { ++ name = $2 ++ if (name == "ld") ++ name = "rtld" ++ ++ # Library names are not duplicated in soversions.i. ++ libs[++num] = name ++} ++ ++# Finally, print out the header file. ++END { ++ printf ("/* AUTOGENERATED BY gen-libc-modules.awk, DO NOT EDIT. */\n\n") ++ for (l in libs) { ++ printf ("#define MODULE_%s %d\n", libs[l], l) ++ } ++} +Index: glibc-2.17-c758a686/sysdeps/unix/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/Makefile ++++ glibc-2.17-c758a686/sysdeps/unix/Makefile +@@ -77,7 +77,8 @@ compile-syscall = $(COMPILE.S) -o $@ -x + + ifndef avoid-generated + $(common-objpfx)sysd-syscalls: $(..)sysdeps/unix/make-syscalls.sh \ +- $(wildcard $(+sysdep_dirs:%=%/syscalls.list)) ++ $(wildcard $(+sysdep_dirs:%=%/syscalls.list)) \ ++ $(common-objpfx)libc-modules.stmp + for dir in $(+sysdep_dirs); do \ + test -f $$dir/syscalls.list && \ + { sysdirs='$(sysdirs)' \ diff --git a/SOURCES/glibc-rh1256317-16.patch b/SOURCES/glibc-rh1256317-16.patch new file mode 100644 index 00000000..c376344c --- /dev/null +++ b/SOURCES/glibc-rh1256317-16.patch @@ -0,0 +1,42 @@ +In order to ensure ABI compatibility between staged builds it was +required that rtkaio/Makefile define both IN_MODULE=MODULE_librt +and IS_IN_librt in order to get both the right set of versioned +symbols and enable cancellation correctly. The changes to rtkaio/Makefile +are Red Hat internal changes. + +commit 286663c34b006c1409df4a71f89d6d4d5d01df09 +Author: Siddhesh Poyarekar +Date: Wed Nov 19 12:15:01 2014 +0530 + + Fix -Wundef warning in SHLIB_COMPAT + + Replace the IS_IN_##lib with IS_IN(lib). Verified that the generated + code remains the same. + + * include/shlib-compat.h (_SHLIB_COMPAT): Use IS_IN. +Index: glibc-2.17-c758a686/include/shlib-compat.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/shlib-compat.h ++++ glibc-2.17-c758a686/include/shlib-compat.h +@@ -45,7 +45,7 @@ + # define SHLIB_COMPAT(lib, introduced, obsoleted) \ + _SHLIB_COMPAT (lib, introduced, obsoleted) + # define _SHLIB_COMPAT(lib, introduced, obsoleted) \ +- ((IS_IN_##lib - 0) \ ++ (IS_IN (lib) \ + && (!(ABI_##lib##_##obsoleted - 0) \ + || ((ABI_##lib##_##introduced - 0) < (ABI_##lib##_##obsoleted - 0)))) + +Index: glibc-2.17-c758a686/rtkaio/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/rtkaio/Makefile ++++ glibc-2.17-c758a686/rtkaio/Makefile +@@ -69,7 +69,8 @@ CFLAGS-kaio_librt-cancellation.c = -fasy + + LDFLAGS-rtkaio.so = -Wl,-soname=lib$(libprefix)rt.so$(librt.so-version) \ + -Wl,--enable-new-dtags,-z,nodelete +-CPPFLAGS-librtkaio += -DIS_IN_librt=1 -I$(..)rt ++CPPFLAGS-librtkaio += -UIN_MODULE -DIN_MODULE=MODULE_librt \ ++ -UIS_IN_librt -DIS_IN_librt=1 -I$(..)rt + + rpath-dirs := $(patsubst rt,rtkaio,$(rpath-dirs)) diff --git a/SOURCES/glibc-rh1256317-17.patch b/SOURCES/glibc-rh1256317-17.patch new file mode 100644 index 00000000..162ddc86 --- /dev/null +++ b/SOURCES/glibc-rh1256317-17.patch @@ -0,0 +1,466 @@ +commit 9cd4747089e6b0d6ed6b2b6c75798912489c7bab +Author: Siddhesh Poyarekar +Date: Wed Nov 19 12:13:54 2014 +0530 + + Add new macro IN_MODULE to identify module in which source is built + + The current scheme to identify which module a translation unit is + built in depends on defining multiple macros IS_IN_* and also defining + NOT_IN_libc if we're building a non-libc module. In addition, there + is an IN_LIB macro that does effectively the same thing, but for + different modules (notably the systemtap probes). This macro scheme + unifies both ideas to use just one macro IN_MODULE and assign it a + value depending on the module it is being built into. If the module + is not defined, it defaults to MODULE_libc. + + Patches that follow will replace uses of IS_IN_* variables with the + IS_IN() macro. libc-symbols.h has been converted already to give an + example of how such a transition will look. + + Verified that there are no relevant binary changes. One source change + that will crop up repeatedly is that of nscd_stat, since it uses the + build timestamp as a constant in its logic. + + * Makeconfig (in-module): Get value of libof set for the + translation unit. + (CPPFLAGS): Use $(in-module). + * Makerules: Don't suffix routine names for nonlib. + * include/libc-modules.h: New file. + * include/libc-symbols.h: Include libc-modules.h + (IS_IN): New macro to replace IS_IN_* macros. + * elf/Makefile: Set libof-* for each routine. + * elf/rtld-Rules: Likewise. + * extra-modules.mk: Likewise. + * iconv/Makefile: Likewise. + * iconvdata/Makefile: Likewise. + * locale/Makefile: Likewise. + * malloc/Makefile: Likewise. + * nss/Makefile: Likewise. + * sysdeps/gnu/Makefile: Likewise. + * sysdeps/ieee754/ldbl-opt/Makefile: Likewise. + * sysdeps/unix/sysv/linux/Makefile: Likewise. + * sysdeps/s390/s390-64/Makefile: Likewise. + * nscd/Makefile: Set libof-* for each routine. Set CFLAGS and + CPPFLAGS for nscd instead of nonlib. + +Index: glibc-2.17-c758a686/Makeconfig +=================================================================== +--- glibc-2.17-c758a686.orig/Makeconfig ++++ glibc-2.17-c758a686/Makeconfig +@@ -730,6 +730,11 @@ endif # $(+cflags) == "" + # of many little headers in the include directory. + libio-include = -I$(..)libio + ++in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \ ++ $(libof-$( ++ ++#define IS_IN(lib) (IN_MODULE == MODULE_##lib) ++ + /* This file's macros are included implicitly in the compilation of every + file in the C library by -imacros. + +@@ -450,7 +455,7 @@ for linking") + If the function should be internal to multiple objects, say ld.so and + libc.so, the best way is to use: + +- #if !defined NOT_IN_libc || defined IS_IN_rtld ++ #if IS_IN (libc) || IS_IN (rtld) + hidden_proto (foo) + #endif + +@@ -561,7 +566,7 @@ for linking") + # define libc_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # define rtld_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define rtld_hidden_def(name) hidden_def (name) + # define rtld_hidden_weak(name) hidden_weak (name) +@@ -579,7 +584,7 @@ for linking") + # define rtld_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # define libm_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libm_hidden_def(name) hidden_def (name) + # define libm_hidden_weak(name) hidden_weak (name) +@@ -597,7 +602,7 @@ for linking") + # define libm_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_libresolv ++#if IS_IN (libresolv) + # define libresolv_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libresolv_hidden_def(name) hidden_def (name) + # define libresolv_hidden_weak(name) hidden_weak (name) +@@ -615,7 +620,7 @@ for linking") + # define libresolv_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_librt ++#if IS_IN (librt) + # define librt_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define librt_hidden_def(name) hidden_def (name) + # define librt_hidden_weak(name) hidden_weak (name) +@@ -633,7 +638,7 @@ for linking") + # define librt_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_libdl ++#if IS_IN (libdl) + # define libdl_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libdl_hidden_def(name) hidden_def (name) + # define libdl_hidden_weak(name) hidden_weak (name) +@@ -651,7 +656,7 @@ for linking") + # define libdl_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_libnss_files ++#if IS_IN (libnss_files) + # define libnss_files_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libnss_files_hidden_def(name) hidden_def (name) + # define libnss_files_hidden_weak(name) hidden_weak (name) +@@ -669,7 +674,7 @@ for linking") + # define libnss_files_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_libnsl ++#if IS_IN (libnsl) + # define libnsl_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libnsl_hidden_def(name) hidden_def (name) + # define libnsl_hidden_weak(name) hidden_weak (name) +@@ -687,7 +692,7 @@ for linking") + # define libnsl_hidden_data_ver(local, name) + #endif + +-#ifdef IS_IN_libnss_nisplus ++#if IS_IN (libnss_nisplus) + # define libnss_nisplus_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libnss_nisplus_hidden_def(name) hidden_def (name) + # define libnss_nisplus_hidden_weak(name) hidden_weak (name) +@@ -713,7 +718,7 @@ for linking") + # define HIDDEN_BUILTIN_JUMPTARGET(name) HIDDEN_JUMPTARGET(name) + #endif + +-#ifdef IS_IN_libutil ++#if IS_IN (libutil) + # define libutil_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libutil_hidden_def(name) hidden_def (name) + # define libutil_hidden_weak(name) hidden_weak (name) +Index: glibc-2.17-c758a686/locale/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/locale/Makefile ++++ glibc-2.17-c758a686/locale/Makefile +@@ -95,8 +95,8 @@ CFLAGS-locfile.c = -Wno-write-strings -W + CFLAGS-charmap-dir.c = -Wno-write-strings + + # This makes sure -DNOT_IN_libc et al are passed for all these modules. +-cpp-srcs-left := $(addsuffix .c,$(localedef-modules) $(localedef-aux) \ +- $(locale-modules) $(lib-modules)) ++cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \ ++ $(lib-modules) + lib := locale-programs + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + +Index: glibc-2.17-c758a686/malloc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/Makefile ++++ glibc-2.17-c758a686/malloc/Makefile +@@ -97,6 +97,11 @@ endif + do-memusagestat: $(objpfx)memusagestat + + memusagestat-modules = memusagestat ++ ++cpp-srcs-left := $(memusagestat-modules) ++lib := memusagestat ++include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) ++ + $(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o) + $(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm + +Index: glibc-2.17-c758a686/nscd/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nscd/Makefile ++++ glibc-2.17-c758a686/nscd/Makefile +@@ -79,26 +79,25 @@ CFLAGS-nscd_gethst_r.c = -fexceptions + CFLAGS-nscd_getai.c = -fexceptions + CFLAGS-nscd_initgroups.c = -fexceptions + +-CPPFLAGS-nonlib += -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2 ++CPPFLAGS-nscd += -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2 -DNOT_IN_libc=1 + + ifeq (yesyes,$(have-fpie)$(build-shared)) +-CFLAGS-nonlib += $(pie-ccflag) ++CFLAGS-nscd += $(pie-ccflag) + endif + ifeq (yes,$(have-ssp)) +-CFLAGS-nonlib += -fstack-protector ++CFLAGS-nscd += -fstack-protector + endif + ifeq (yes,$(have-ssp-strong)) +-CFLAGS-nonlib += -fstack-protector-strong ++CFLAGS-nscd += -fstack-protector-strong + endif + + ifeq (yesyes,$(have-fpie)$(build-shared)) + LDFLAGS-nscd = -Wl,-z,now + endif + +-# This makes sure CPPFLAGS-nonlib and CFLAGS-nonlib are passed +-# for all these modules. +-cpp-srcs-left := $(nscd-modules:=.c) +-lib := nonlib ++# Set libof-nscd. ++cpp-srcs-left := $(nscd-modules) ++lib := nscd + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + + $(objpfx)nscd: $(nscd-modules:%=$(objpfx)%.o) +Index: glibc-2.17-c758a686/nss/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nss/Makefile ++++ glibc-2.17-c758a686/nss/Makefile +@@ -108,7 +108,8 @@ $(objpfx)makedb: $(makedb-modules:%=$(ob + $(inst_vardbdir)/Makefile: db-Makefile $(+force) + $(do-install) + +-CFLAGS-nss_test1.c = -DNOT_IN_libc=1 ++libof-nss_test1 = extramodules ++CPPFLAGS-nss_test1 = -DNOT_IN_libc=1 + $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(common-objpfx)libc.so \ + $(common-objpfx)libc_nonshared.a + $(build-module) +Index: glibc-2.17-c758a686/stdlib/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/stdlib/Makefile ++++ glibc-2.17-c758a686/stdlib/Makefile +@@ -138,6 +138,7 @@ LDFLAGS-tst-putenv = $(no-as-needed) + + $(objpfx)tst-putenvmod.so: $(objpfx)tst-putenvmod.os + $(build-module) ++libof-tst-putenvmod = extramodules + CFLAGS-tst-putenvmod.c = -DNOT_IN_libc=1 + + ifeq ($(build-shared),yes) +Index: glibc-2.17-c758a686/sysdeps/gnu/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/gnu/Makefile ++++ glibc-2.17-c758a686/sysdeps/gnu/Makefile +@@ -30,6 +30,8 @@ ifeq ($(subdir),stdio-common) + + errlist-c = $(firstword $(wildcard $(addsuffix /errlist.c,$(sysdirs) .))) + ++libof-errlist-compat = extramodules ++ + ifeq ($(versioning),yes) + $(objpfx)errlist-compat.c: $(errlist-c) $(..)sysdeps/gnu/errlist-compat.awk \ + $(common-objpfx)Versions.v.i $(before-compile) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/Makefile ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/Makefile +@@ -28,6 +28,10 @@ s390x-iconv-modules = ISO-8859-1_CP037_Z + extra-modules-left += $(s390x-iconv-modules) + include extra-module.mk + ++cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) ++lib := iconvdata ++include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) ++ + extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) + install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) + +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/Makefile ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/Makefile +@@ -159,6 +159,7 @@ ifeq ($(subdir),elf) + sysdep-rtld-routines += dl-brk dl-sbrk dl-getcwd dl-openat64 dl-opendir \ + dl-fxstatat64 + ++libof-lddlibc4 = lddlibc4 + CPPFLAGS-lddlibc4 += -DNOT_IN_libc + endif diff --git a/SOURCES/glibc-rh1256317-18.patch b/SOURCES/glibc-rh1256317-18.patch new file mode 100644 index 00000000..2cf0a89a --- /dev/null +++ b/SOURCES/glibc-rh1256317-18.patch @@ -0,0 +1,51 @@ +commit d330b980e9ee2349492087a279a9c7bf294f6b47 +Author: Siddhesh Poyarekar +Date: Tue Sep 16 22:20:45 2014 +0530 + + Remove CFLAGS for interp.c + + Replace it with including an auto-generated linker-runtime.h. + Build-tested on x86_64 and found that there was no change in the + generated code. + + * elf/Makefile (CFLAGS-interp.c): Remove. + ($(elf-objpfx)runtime-linker.h): Generate header with linker + path string. + * elf/interp.c: Include generated runtime-linker.h + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -344,9 +344,16 @@ $(objpfx)ld.so: $(objpfx)librtld.os $(ld + $(READELF) -s $@ \ + | $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }' + +-# interp.c exists just to get this string into the libraries. +-CFLAGS-interp.c = -D'RUNTIME_LINKER="$(rtlddir)/$(rtld-installed-name)"' +-$(objpfx)interp.os: $(common-objpfx)config.make ++# interp.c exists just to get the runtime linker path into libc.so. ++$(objpfx)interp.os: $(elf-objpfx)runtime-linker.h ++ ++$(elf-objpfx)runtime-linker.h: $(elf-objpfx)runtime-linker.st; @: ++$(elf-objpfx)runtime-linker.st: $(common-objpfx)config.make ++ $(name-target-directory) ++ echo '#define RUNTIME_LINKER "$(rtlddir)/$(rtld-installed-name)"' \ ++ > ${@:st=T} ++ $(move-if-change) ${@:st=T} ${@:st=h} ++ touch $@ + + ifneq (ld.so,$(rtld-installed-name)) + # Make sure ld.so.1 exists in the build directory so we can link +Index: glibc-2.17-c758a686/elf/interp.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/interp.c ++++ glibc-2.17-c758a686/elf/interp.c +@@ -16,5 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + ++#include ++ + const char __invoke_dynamic_linker__[] __attribute__ ((section (".interp"))) + = RUNTIME_LINKER; diff --git a/SOURCES/glibc-rh1256317-19.patch b/SOURCES/glibc-rh1256317-19.patch new file mode 100644 index 00000000..cecedd96 --- /dev/null +++ b/SOURCES/glibc-rh1256317-19.patch @@ -0,0 +1,254 @@ +commit 02657da2cf4457804ed938ee08b8316249126444 +Author: Siddhesh Poyarekar +Date: Tue Sep 16 22:19:22 2014 +0530 + + Include .interp section only for libc.so + + Barring libc.so and libdl.so, none of the libraries have any entry + points, so it is pointless to add a .interp section for them. The + libdl.so entry point (in dlfcn/eval.c) is also defunct, so remove that + file as well. + + Build tested for x86_64, ppc64 and s390x. I have not moved + CFLAGS-interp.c to CPPFLAGS-interp.c isnce I'll be removing it + completely in a follow-up patch. + + Siddhesh + + * Makerules (lib%.so): Don't include $(+interp) in + prerequisites. + * elf/Makefile (CFLAGS-interp.c): Don't define NOT_IN_libc. + * dlfcn/eval.c: Remove file. + +Index: glibc-2.17-c758a686/Makerules +=================================================================== +--- glibc-2.17-c758a686.orig/Makerules ++++ glibc-2.17-c758a686/Makerules +@@ -461,7 +461,7 @@ link-libc-deps = $(common-objpfx)libc.so + # build shared libraries in place from the installed *_pic.a files. + # $(LDLIBS-%.so) may contain -l switches to generate run-time dependencies + # on other shared objects. +-lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(+interp) ++lib%.so: lib%_pic.a $(+preinit) $(+postinit) + $(build-shlib) + + define build-shlib-helper +Index: glibc-2.17-c758a686/dlfcn/eval.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/eval.c ++++ /dev/null +@@ -1,200 +0,0 @@ +-/* You don't really want to know what this hack is for. +- Copyright (C) 1996, 1997, 2000, 2001 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-static void *funcall (char **stringp) __attribute_noinline__; +-static void *eval (char **stringp); +- +- +-long int weak_function +-__strtol_internal (const char *nptr, char **endptr, int base, int group) +-{ +- unsigned long int result = 0; +- long int sign = 1; +- +- while (*nptr == ' ' || *nptr == '\t') +- ++nptr; +- +- if (*nptr == '-') +- { +- sign = -1; +- ++nptr; +- } +- else if (*nptr == '+') +- ++nptr; +- +- if (*nptr < '0' || *nptr > '9') +- { +- if (endptr != NULL) +- *endptr = (char *) nptr; +- return 0L; +- } +- +- assert (base == 0); +- base = 10; +- if (*nptr == '0') +- { +- if (nptr[1] == 'x' || nptr[1] == 'X') +- { +- base = 16; +- nptr += 2; +- } +- else +- base = 8; +- } +- +- while (*nptr >= '0' && *nptr <= '9') +- { +- unsigned long int digval = *nptr - '0'; +- if (result > LONG_MAX / 10 +- || (sign > 0 ? result == LONG_MAX / 10 && digval > LONG_MAX % 10 +- : (result == ((unsigned long int) LONG_MAX + 1) / 10 +- && digval > ((unsigned long int) LONG_MAX + 1) % 10))) +- { +- errno = ERANGE; +- return sign > 0 ? LONG_MAX : LONG_MIN; +- } +- result *= base; +- result += digval; +- ++nptr; +- } +- +- return (long int) result * sign; +-} +- +- +-static void * +-funcall (char **stringp) +-{ +- void *args[strlen (*stringp)], **ap = args; +- void *argcookie = &args[1]; +- +- do +- { +- /* Evaluate the next token. */ +- *ap++ = eval (stringp); +- +- /* Whitespace is irrelevant. */ +- while (isspace (**stringp)) +- ++*stringp; +- +- /* Terminate at closing paren or end of line. */ +- } while (**stringp != '\0' && **stringp != ')'); +- if (**stringp != '\0') +- /* Swallow closing paren. */ +- ++*stringp; +- +- if (args[0] == NULL) +- { +- static const char unknown[] = "Unknown function\n"; +- write (1, unknown, sizeof unknown - 1); +- return NULL; +- } +- +- /* Do it to it. */ +- __builtin_return (__builtin_apply (args[0], +- &argcookie, +- (char *) ap - (char *) &args[1])); +-} +- +-static void * +-eval (char **stringp) +-{ +- void *value; +- char *p = *stringp, c; +- +- /* Whitespace is irrelevant. */ +- while (isspace (*p)) +- ++p; +- +- switch (*p) +- { +- case '"': +- /* String constant. */ +- value = ++p; +- do +- if (*p == '\\') +- { +- switch (*strcpy (p, p + 1)) +- { +- case 't': +- *p = '\t'; +- break; +- case 'n': +- *p = '\n'; +- break; +- } +- ++p; +- } +- while (*p != '\0' && *p++ != '"'); +- if (p[-1] == '"') +- p[-1] = '\0'; +- break; +- +- case '(': +- *stringp = ++p; +- return funcall (stringp); +- +- default: +- /* Try to parse it as a number. */ +- value = (void *) __strtol_internal (p, stringp, 0, 0); +- if (*stringp != p) +- return value; +- +- /* Anything else is a symbol that produces its address. */ +- value = p; +- do +- ++p; +- while (*p != '\0' && !isspace (*p) && (!ispunct (*p) || *p == '_')); +- c = *p; +- *p = '\0'; +- value = dlsym (NULL, value); +- *p = c; +- break; +- } +- +- *stringp = p; +- return value; +-} +- +- +-extern void _start (void) __attribute__ ((noreturn)); +-void +-__attribute__ ((noreturn)) +-_start (void) +-{ +- char *buf = NULL; +- size_t bufsz = 0; +- +- while (__getdelim (&buf, &bufsz, '\n', stdin) > 0) +- { +- char *p = buf; +- eval (&p); +- } +- +- exit (0); +-} +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -345,8 +345,7 @@ $(objpfx)ld.so: $(objpfx)librtld.os $(ld + | $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }' + + # interp.c exists just to get this string into the libraries. +-CFLAGS-interp.c = -D'RUNTIME_LINKER="$(rtlddir)/$(rtld-installed-name)"' \ +- -DNOT_IN_libc=1 ++CFLAGS-interp.c = -D'RUNTIME_LINKER="$(rtlddir)/$(rtld-installed-name)"' + $(objpfx)interp.os: $(common-objpfx)config.make + + ifneq (ld.so,$(rtld-installed-name)) diff --git a/SOURCES/glibc-rh1256317-2.patch b/SOURCES/glibc-rh1256317-2.patch new file mode 100644 index 00000000..cb2a9b85 --- /dev/null +++ b/SOURCES/glibc-rh1256317-2.patch @@ -0,0 +1,7228 @@ +commit 4f41c682f3f0a0ad69eeac38a6b270f4362c3a02 +Author: Siddhesh Poyarekar +Date: Mon Nov 24 15:03:45 2014 +0530 + + Remove NOT_IN_libc + + Replace with !IS_IN (libc). This completes the transition from + the IS_IN/NOT_IN macros to the IN_MODULE macro set. + + The generated code is unchanged on x86_64. + + * stdlib/isomac.c (fmt): Replace NOT_IN_libc with IN_MODULE. + (get_null_defines): Adjust. + * sunrpc/Makefile: Adjust comment. + * Makerules (CPPFLAGS-nonlib): Remove NOT_IN_libc. + * elf/Makefile (CPPFLAGS-sotruss-lib): Likewise. + (CFLAGS-interp.c): Likewise. + (CFLAGS-ldconfig.c): Likewise. + (CPPFLAGS-.os): Likewise. + * elf/rtld-Rules (rtld-CPPFLAGS): Likewise. + * extra-lib.mk (CPPFLAGS-$(lib)): Likewise. + * extra-modules.mk (extra-modules.mk): Likewise. + * iconv/Makefile (CPPFLAGS-iconvprogs): Likewise. + * locale/Makefile (CPPFLAGS-locale_programs): Likewise. + * malloc/Makefile (CPPFLAGS-memusagestat): Likewise. + * nscd/Makefile (CPPFLAGS-nscd): Likewise. + * nss/Makefile (CPPFLAGS-nss_test1): Likewise. + * stdlib/Makefile (CFLAGS-tst-putenvmod.c): Likewise. + * sysdeps/gnu/Makefile ($(objpfx)errlist-compat.c): Likewise. + * sysdeps/unix/sysv/linux/Makefile (CPPFLAGS-lddlibc4): Likewise. + * iconvdata/Makefile (CPPFLAGS): Likewise. + (cpp-srcs-left): Add libof for all iconvdata routines. + * bits/stdio-lock.h: Replace NOT_IN_libc with IS_IN. + * include/assert.h: Likewise. + * include/ctype.h: Likewise. + * include/errno.h: Likewise. + * include/libc-symbols.h: Likewise. + * include/math.h: Likewise. + * include/netdb.h: Likewise. + * include/resolv.h: Likewise. + * include/stdio.h: Likewise. + * include/stdlib.h: Likewise. + * include/string.h: Likewise. + * include/sys/stat.h: Likewise. + * include/wctype.h: Likewise. + * intl/l10nflist.c: Likewise. + * libidn/idn-stub.c: Likewise. + * libio/libioP.h: Likewise. + * nptl/libc_multiple_threads.c: Likewise. + * nptl/pthreadP.h: Likewise. + * posix/regex_internal.h: Likewise. + * resolv/res_hconf.c: Likewise. + * sysdeps/arm/armv7/multiarch/memcpy.S: Likewise. + * sysdeps/arm/memmove.S: Likewise. + * sysdeps/arm/sysdep.h: Likewise. + * sysdeps/generic/_itoa.h: Likewise. + * sysdeps/generic/symbol-hacks.h: Likewise. + * sysdeps/gnu/errlist.awk: Likewise. + * sysdeps/gnu/errlist.c: Likewise. + * sysdeps/i386/i586/memcpy.S: Likewise. + * sysdeps/i386/i586/memset.S: Likewise. + * sysdeps/i386/i686/memcpy.S: Likewise. + * sysdeps/i386/i686/memmove.S: Likewise. + * sysdeps/i386/i686/mempcpy.S: Likewise. + * sysdeps/i386/i686/memset.S: Likewise. + * sysdeps/i386/i686/multiarch/bcopy.S: Likewise. + * sysdeps/i386/i686/multiarch/bzero.S: Likewise. + * sysdeps/i386/i686/multiarch/memchr-sse2-bsf.S: Likewise. + * sysdeps/i386/i686/multiarch/memchr-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/memchr.S: Likewise. + * sysdeps/i386/i686/multiarch/memcmp-sse4.S: Likewise. + * sysdeps/i386/i686/multiarch/memcmp-ssse3.S: Likewise. + * sysdeps/i386/i686/multiarch/memcmp.S: Likewise. + * sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S: Likewise. + * sysdeps/i386/i686/multiarch/memcpy-ssse3.S: Likewise. + * sysdeps/i386/i686/multiarch/memcpy.S: Likewise. + * sysdeps/i386/i686/multiarch/memcpy_chk.S: Likewise. + * sysdeps/i386/i686/multiarch/memmove.S: Likewise. + * sysdeps/i386/i686/multiarch/memmove_chk.S: Likewise. + * sysdeps/i386/i686/multiarch/mempcpy.S: Likewise. + * sysdeps/i386/i686/multiarch/mempcpy_chk.S: Likewise. + * sysdeps/i386/i686/multiarch/memrchr-c.c: Likewise. + * sysdeps/i386/i686/multiarch/memrchr-sse2-bsf.S: Likewise. + * sysdeps/i386/i686/multiarch/memrchr-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/memrchr.S: Likewise. + * sysdeps/i386/i686/multiarch/memset-sse2-rep.S: Likewise. + * sysdeps/i386/i686/multiarch/memset-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/memset.S: Likewise. + * sysdeps/i386/i686/multiarch/memset_chk.S: Likewise. + * sysdeps/i386/i686/multiarch/rawmemchr.S: Likewise. + * sysdeps/i386/i686/multiarch/strcat-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/strcat-ssse3.S: Likewise. + * sysdeps/i386/i686/multiarch/strcat.S: Likewise. + * sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S: Likewise. + * sysdeps/i386/i686/multiarch/strchr-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/strchr.S: Likewise. + * sysdeps/i386/i686/multiarch/strcmp-sse4.S: Likewise. + * sysdeps/i386/i686/multiarch/strcmp-ssse3.S: Likewise. + * sysdeps/i386/i686/multiarch/strcmp.S: Likewise. + * sysdeps/i386/i686/multiarch/strcpy-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/strcpy-ssse3.S: Likewise. + * sysdeps/i386/i686/multiarch/strcpy.S: Likewise. + * sysdeps/i386/i686/multiarch/strcspn.S: Likewise. + * sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S: Likewise. + * sysdeps/i386/i686/multiarch/strlen-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/strlen.S: Likewise. + * sysdeps/i386/i686/multiarch/strnlen.S: Likewise. + * sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S: Likewise. + * sysdeps/i386/i686/multiarch/strrchr-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/strrchr.S: Likewise. + * sysdeps/i386/i686/multiarch/strspn.S: Likewise. + * sysdeps/i386/i686/multiarch/wcschr-c.c: Likewise. + * sysdeps/i386/i686/multiarch/wcschr-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/wcschr.S: Likewise. + * sysdeps/i386/i686/multiarch/wcscmp-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/wcscmp.S: Likewise. + * sysdeps/i386/i686/multiarch/wcscpy-c.c: Likewise. + * sysdeps/i386/i686/multiarch/wcscpy-ssse3.S: Likewise. + * sysdeps/i386/i686/multiarch/wcscpy.S: Likewise. + * sysdeps/i386/i686/multiarch/wcslen-c.c: Likewise. + * sysdeps/i386/i686/multiarch/wcslen-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/wcslen.S: Likewise. + * sysdeps/i386/i686/multiarch/wcsrchr-c.c: Likewise. + * sysdeps/i386/i686/multiarch/wcsrchr-sse2.S: Likewise. + * sysdeps/i386/i686/multiarch/wcsrchr.S: Likewise. + * sysdeps/i386/i686/multiarch/wmemcmp-c.c: Likewise. + * sysdeps/i386/i686/multiarch/wmemcmp.S: Likewise. + * sysdeps/ia64/fpu/libm-symbols.h: Likewise. + * sysdeps/nptl/bits/libc-lock.h: Likewise. + * sysdeps/nptl/bits/libc-lockP.h: Likewise. + * sysdeps/nptl/bits/stdio-lock.h: Likewise. + * sysdeps/posix/closedir.c: Likewise. + * sysdeps/posix/opendir.c: Likewise. + * sysdeps/posix/readdir.c: Likewise. + * sysdeps/posix/rewinddir.c: Likewise. + * sysdeps/powerpc/novmx-sigjmp.c: Likewise. + * sysdeps/powerpc/powerpc32/__longjmp.S: Likewise. + * sysdeps/powerpc/powerpc32/bsd-_setjmp.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/__longjmp.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/setjmp.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/bzero.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memcmp-ppc32.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memcpy-ppc32.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memrchr.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memset-ppc32.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/memset.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strlen-ppc32.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strncase.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strncase_l.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strncmp-ppc32.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wcschr.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy.c: Likewise. + * sysdeps/powerpc/powerpc32/power6/memset.S: Likewise. + * sysdeps/powerpc/powerpc32/setjmp.S: Likewise. + * sysdeps/powerpc/powerpc64/__longjmp.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/bzero.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memchr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memcmp.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memcpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memmove.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/mempcpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memrchr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/memset.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/stpcpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/stpncpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcat.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strchr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strchrnul.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcmp.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strcspn.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strlen.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncase.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncase_l.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncat.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncmp.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strncpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strnlen.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strpbrk.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strrchr-ppc64.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strrchr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/strspn.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/wcschr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/wcscpy.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c: Likewise. + * sysdeps/powerpc/powerpc64/multiarch/wordcopy.c: Likewise. + * sysdeps/powerpc/powerpc64/setjmp.S: Likewise. + * sysdeps/s390/s390-32/multiarch/ifunc-resolve.c: Likewise. + * sysdeps/s390/s390-32/multiarch/memcmp.S: Likewise. + * sysdeps/s390/s390-32/multiarch/memcpy.S: Likewise. + * sysdeps/s390/s390-32/multiarch/memset.S: Likewise. + * sysdeps/s390/s390-64/multiarch/ifunc-resolve.c: Likewise. + * sysdeps/s390/s390-64/multiarch/memcmp.S: Likewise. + * sysdeps/s390/s390-64/multiarch/memcpy.S: Likewise. + * sysdeps/s390/s390-64/multiarch/memset.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy-niagara1.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memset-niagara1.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memset-niagara4.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memset.S: Likewise. + * sysdeps/unix/alpha/sysdep.S: Likewise. + * sysdeps/unix/alpha/sysdep.h: Likewise. + * sysdeps/unix/make-syscalls.sh: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/alpha/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/arm/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/getpid.c: Likewise. + * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S: Likewise. + * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep.S: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/lowlevellock-futex.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/microblaze/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/mips/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/not-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/longjmp_chk.c: Likewise. + * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/sh/lowlevellock.S: Likewise. + * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sh/vfork.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/brk.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/tile/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/tile/waitpid.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. + * sysdeps/wordsize-32/symbol-hacks.h: Likewise. + * sysdeps/x86_64/memcpy.S: Likewise. + * sysdeps/x86_64/memmove.c: Likewise. + * sysdeps/x86_64/memset.S: Likewise. + * sysdeps/x86_64/multiarch/init-arch.h: Likewise. + * sysdeps/x86_64/multiarch/memcmp-sse4.S: Likewise. + * sysdeps/x86_64/multiarch/memcmp-ssse3.S: Likewise. + * sysdeps/x86_64/multiarch/memcmp.S: Likewise. + * sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S: Likewise. + * sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: Likewise. + * sysdeps/x86_64/multiarch/memcpy-ssse3.S: Likewise. + * sysdeps/x86_64/multiarch/memcpy.S: Likewise. + * sysdeps/x86_64/multiarch/memcpy_chk.S: Likewise. + * sysdeps/x86_64/multiarch/memmove.c: Likewise. + * sysdeps/x86_64/multiarch/mempcpy.S: Likewise. + * sysdeps/x86_64/multiarch/mempcpy_chk.S: Likewise. + * sysdeps/x86_64/multiarch/memset-avx2.S: Likewise. + * sysdeps/x86_64/multiarch/memset.S: Likewise. + * sysdeps/x86_64/multiarch/memset_chk.S: Likewise. + * sysdeps/x86_64/multiarch/strcat-sse2-unaligned.S: Likewise. + * sysdeps/x86_64/multiarch/strcat-ssse3.S: Likewise. + * sysdeps/x86_64/multiarch/strcat.S: Likewise. + * sysdeps/x86_64/multiarch/strchr-sse2-no-bsf.S: Likewise. + * sysdeps/x86_64/multiarch/strchr.S: Likewise. + * sysdeps/x86_64/multiarch/strcmp-ssse3.S: Likewise. + * sysdeps/x86_64/multiarch/strcmp.S: Likewise. + * sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: Likewise. + * sysdeps/x86_64/multiarch/strcpy-ssse3.S: Likewise. + * sysdeps/x86_64/multiarch/strcpy.S: Likewise. + * sysdeps/x86_64/multiarch/strcspn.S: Likewise. + * sysdeps/x86_64/multiarch/strspn.S: Likewise. + * sysdeps/x86_64/multiarch/wcscpy-c.c: Likewise. + * sysdeps/x86_64/multiarch/wcscpy-ssse3.S: Likewise. + * sysdeps/x86_64/multiarch/wcscpy.S: Likewise. + * sysdeps/x86_64/multiarch/wmemcmp-c.c: Likewise. + * sysdeps/x86_64/multiarch/wmemcmp.S: Likewise. + * sysdeps/x86_64/strcmp.S: Likewise. + +Index: glibc-2.17-c758a686/bits/stdio-lock.h +=================================================================== +--- glibc-2.17-c758a686.orig/bits/stdio-lock.h ++++ glibc-2.17-c758a686/bits/stdio-lock.h +@@ -44,7 +44,7 @@ __libc_lock_define_recursive (typedef, _ + #define _IO_cleanup_region_end(_doit) \ + __libc_cleanup_region_end (_doit) + +-#if defined _LIBC && !defined NOT_IN_libc ++#if defined _LIBC && IS_IN (libc) + # define _IO_acquire_lock(_fp) \ + _IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, (_fp)); \ + _IO_flockfile (_fp) +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -99,7 +99,6 @@ install-others += $(inst_auditdir)/sotru + install-bin-script += sotruss + generated += sotruss + libof-sotruss-lib = extramodules +-CPPFLAGS-sotruss-lib = -DNOT_IN_libc + $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os + $(build-module-asneeded) + $(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \ +@@ -437,15 +436,12 @@ $(objpfx)pldd: $(pldd-modules:%=$(objpfx + + SYSCONF-FLAGS := -D'SYSCONFDIR="$(sysconfdir)"' + CFLAGS-ldconfig.c = $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \ +- -D'SLIBDIR="$(slibdir)"' -DNOT_IN_libc ++ -D'SLIBDIR="$(slibdir)"' + libof-ldconfig = ldconfig + CFLAGS-dl-cache.c = $(SYSCONF-FLAGS) + CFLAGS-cache.c = $(SYSCONF-FLAGS) + CFLAGS-rtld.c = $(SYSCONF-FLAGS) + +-CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\ +- -DNOT_IN_libc=1) +- + # Disable any optimization which might result in function calls during early + # dynamic loader startup. We disable -ftree-loop-distribute-patterns which + # might convert code into calls to functions like memcpy or memset when the PLT +Index: glibc-2.17-c758a686/elf/rtld-Rules +=================================================================== +--- glibc-2.17-c758a686.orig/elf/rtld-Rules ++++ glibc-2.17-c758a686/elf/rtld-Rules +@@ -128,12 +128,10 @@ ifdef rtld-depfiles + -include $(rtld-depfiles) + endif + ++# This here is the whole point of all the shenanigans. + # Set libof-* for each routine. + cpp-srcs-left := $(rtld-modules:%.os=%) + lib := rtld + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + +-# This here is the whole point of all the shenanigans. +-rtld-CPPFLAGS := -DNOT_IN_libc=1 +- + endif +Index: glibc-2.17-c758a686/extra-lib.mk +=================================================================== +--- glibc-2.17-c758a686.orig/extra-lib.mk ++++ glibc-2.17-c758a686/extra-lib.mk +@@ -100,5 +100,3 @@ cpp-srcs-left := $($(lib)-routines) $($( + ifneq (,$(cpp-srcs-left)) + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + endif +- +-CPPFLAGS-$(lib) := -DNOT_IN_libc=1 +Index: glibc-2.17-c758a686/extra-modules.mk +=================================================================== +--- glibc-2.17-c758a686.orig/extra-modules.mk ++++ glibc-2.17-c758a686/extra-modules.mk +@@ -7,4 +7,3 @@ module := $(firstword $(extra-modules-le + extra-modules-left := $(filter-out $(module),$(extra-modules-left)) + + libof-$(notdir $(module)) := extramodules +-CPPFLAGS-$(module).c += -DNOT_IN_libc +Index: glibc-2.17-c758a686/iconv/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/iconv/Makefile ++++ glibc-2.17-c758a686/iconv/Makefile +@@ -53,8 +53,6 @@ CFLAGS-gconv_cache.c += -DGCONV_DIR='"$( + CFLAGS-gconv_conf.c = -DGCONV_PATH='"$(gconvdir)"' + CFLAGS-iconvconfig.c = -DGCONV_PATH='"$(gconvdir)"' -DGCONV_DIR='"$(gconvdir)"' + +-CPPFLAGS-iconvprogs = -DNOT_IN_libc +- + # Set libof-* for each routine. + cpp-srcs-left := $(iconv_prog-modules) $(iconvconfig-modules) + lib := iconvprogs +Index: glibc-2.17-c758a686/iconvdata/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/iconvdata/Makefile ++++ glibc-2.17-c758a686/iconvdata/Makefile +@@ -76,9 +76,6 @@ endif + test-srcs := tst-table-from tst-table-to + endif + +-# No code here is in libc.so. +-CPPFLAGS += -DNOT_IN_libc +- + libJIS-routines := jis0201 jis0208 jis0212 + libKSC-routines := ksc5601 + libGB-routines := gb2312 +@@ -267,7 +264,9 @@ endif # build-shared = yes + include ../Rules + + # Set libof-* for each routine. +-cpp-srcs-left := $(modules) $(generated-modules) ++cpp-srcs-left := $(modules) $(generated-modules) $(libJIS-routines) \ ++ $(libKSC-routines) $(libGB-routines) $(libCNS-routines) \ ++ $(libISOIR165-routines) $(libJISX0213-routines) + lib := iconvdata + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + +Index: glibc-2.17-c758a686/include/assert.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/assert.h ++++ glibc-2.17-c758a686/include/assert.h +@@ -20,7 +20,7 @@ extern void __assert_fail_base (const ch + const char *function) + __THROW __attribute__ ((__noreturn__)); + +-# if !defined NOT_IN_libc || IS_IN (rtld) ++# if IS_IN (libc) || IS_IN (rtld) + hidden_proto (__assert_fail) + hidden_proto (__assert_perror_fail) + # endif +Index: glibc-2.17-c758a686/include/errno.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/errno.h ++++ glibc-2.17-c758a686/include/errno.h +@@ -17,19 +17,19 @@ + # define errno rtld_errno + extern int rtld_errno attribute_hidden; + +-# elif !defined NOT_IN_libc || IS_IN_LIB ++# elif IS_IN_LIB + + # include + + # undef errno +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define errno __libc_errno + # else + # define errno errno /* For #ifndef errno tests. */ + # endif + extern __thread int errno attribute_tls_model_ie; + +-# endif /* !NOT_IN_libc || IS_IN_LIB */ ++# endif /* IS_IN_LIB */ + + # define __set_errno(val) (errno = (val)) + +Index: glibc-2.17-c758a686/include/math.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/math.h ++++ glibc-2.17-c758a686/include/math.h +@@ -6,7 +6,7 @@ + /* Now define the internal interfaces. */ + extern int __matherr (struct exception *__exc); + +-# if !defined NOT_IN_libc || IS_IN (libm) ++# if IS_IN (libc) || IS_IN (libm) + hidden_proto (__finite) + hidden_proto (__isinf) + hidden_proto (__isnan) +Index: glibc-2.17-c758a686/include/stdio.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/stdio.h ++++ glibc-2.17-c758a686/include/stdio.h +@@ -117,7 +117,7 @@ extern const char *const _sys_errlist_in + extern int _sys_nerr_internal attribute_hidden; + + libc_hidden_proto (__asprintf) +-# if !defined NOT_IN_libc ++# if IS_IN (libc) + extern _IO_FILE *_IO_new_fopen (const char*, const char*); + # define fopen(fname, mode) _IO_new_fopen (fname, mode) + extern _IO_FILE *_IO_new_fdopen (int, const char*); +Index: glibc-2.17-c758a686/include/string.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/string.h ++++ glibc-2.17-c758a686/include/string.h +@@ -57,7 +57,7 @@ extern __typeof (strcasecmp_l) __strcase + extern __typeof (strncasecmp_l) __strncasecmp_l; + + /* Alternative version which doesn't pollute glibc's namespace. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # undef strndupa + # define strndupa(s, n) \ + (__extension__ \ +Index: glibc-2.17-c758a686/include/sys/stat.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/sys/stat.h ++++ glibc-2.17-c758a686/include/sys/stat.h +@@ -12,7 +12,7 @@ extern __mode_t __umask (__mode_t __mask + extern int __mkdir (const char *__path, __mode_t __mode); + extern int __mknod (const char *__path, + __mode_t __mode, __dev_t __dev); +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + hidden_proto (__fxstat) + hidden_proto (__fxstat64) + hidden_proto (__lxstat) +Index: glibc-2.17-c758a686/include/wctype.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/wctype.h ++++ glibc-2.17-c758a686/include/wctype.h +@@ -89,7 +89,7 @@ libc_hidden_proto (__towupper_l) + + /* The spec says that isdigit must only match the decimal digits. We + can check this without a memory access. */ +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # undef iswdigit + # define iswdigit(c) ({ wint_t __c = (c); __c >= L'0' && __c <= L'9'; }) + # undef iswdigit_l +Index: glibc-2.17-c758a686/intl/l10nflist.c +=================================================================== +--- glibc-2.17-c758a686.orig/intl/l10nflist.c ++++ glibc-2.17-c758a686/intl/l10nflist.c +@@ -324,7 +324,7 @@ _nl_normalize_codeset (codeset, name_len + char *retval; + char *wp; + size_t cnt; +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + locale_t locale = newlocale (0, "C", NULL); + #else + # define locale _nl_C_locobj_ptr +Index: glibc-2.17-c758a686/libidn/idn-stub.c +=================================================================== +--- glibc-2.17-c758a686.orig/libidn/idn-stub.c ++++ glibc-2.17-c758a686/libidn/idn-stub.c +@@ -130,7 +130,7 @@ __idna_to_ascii_lz (const char *input, c + } + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + libc_freeres_fn (unload_libidn) + { + if (h != NULL && h != (void *) 1l) +Index: glibc-2.17-c758a686/libio/libioP.h +=================================================================== +--- glibc-2.17-c758a686.orig/libio/libioP.h ++++ glibc-2.17-c758a686/libio/libioP.h +@@ -900,7 +900,7 @@ _IO_acquire_lock_clear_flags2_fct (_IO_F + _IO_funlockfile (fp); + } + +-#if !defined _IO_MTSAFE_IO && !defined NOT_IN_libc ++#if !defined _IO_MTSAFE_IO && IS_IN (libc) + # define _IO_acquire_lock(_fp) \ + do { \ + _IO_FILE *_IO_acquire_lock_file = NULL +Index: glibc-2.17-c758a686/malloc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/Makefile ++++ glibc-2.17-c758a686/malloc/Makefile +@@ -56,8 +56,6 @@ extra-objs = mcheck-init.o libmcheck.a + # Include the cleanup handler. + aux := set-freeres thread-freeres + +-CPPFLAGS-memusagestat = -DNOT_IN_libc +- + # The Perl script to analyze the output of the mtrace functions. + ifneq ($(PERL),no) + install-bin-script = mtrace +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c +@@ -18,7 +18,7 @@ + + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifndef TLS_MULTIPLE_THREADS_IN_TCB + /* Variable set to a nonzero value either if more than one thread runs or ran, + or if a single-threaded process is trying to cancel itself. See +Index: glibc-2.17-c758a686/nptl/pthreadP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthreadP.h ++++ glibc-2.17-c758a686/nptl/pthreadP.h +@@ -273,7 +273,7 @@ __do_cancel (void) + #define CANCEL_RESET(oldtype) \ + __pthread_disable_asynccancel (oldtype) + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + /* Same as CANCEL_ASYNC, but for use in libc.so. */ + # define LIBC_CANCEL_ASYNC() \ + __libc_enable_asynccancel () +Index: glibc-2.17-c758a686/nscd/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nscd/Makefile ++++ glibc-2.17-c758a686/nscd/Makefile +@@ -79,7 +79,7 @@ CFLAGS-nscd_gethst_r.c = -fexceptions + CFLAGS-nscd_getai.c = -fexceptions + CFLAGS-nscd_initgroups.c = -fexceptions + +-CPPFLAGS-nscd += -D_FORTIFY_SOURCE=2 -DNOT_IN_libc ++CPPFLAGS-nscd += -D_FORTIFY_SOURCE=2 + + ifeq (yesyes,$(have-fpie)$(build-shared)) + CFLAGS-nscd += $(pie-ccflag) +Index: glibc-2.17-c758a686/posix/regex_internal.h +=================================================================== +--- glibc-2.17-c758a686.orig/posix/regex_internal.h ++++ glibc-2.17-c758a686/posix/regex_internal.h +@@ -385,7 +385,7 @@ typedef struct re_dfa_t re_dfa_t; + # endif + #endif + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, + int new_buf_len) + internal_function; +@@ -735,7 +735,7 @@ re_string_wchar_at (const re_string_t *p + return (wint_t) pstr->wcs[idx]; + } + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + static int + internal_function __attribute ((pure)) + re_string_elem_size_at (const re_string_t *pstr, int idx) +Index: glibc-2.17-c758a686/stdlib/isomac.c +=================================================================== +--- glibc-2.17-c758a686.orig/stdlib/isomac.c ++++ glibc-2.17-c758a686/stdlib/isomac.c +@@ -176,7 +176,8 @@ static char *macros[] = + /* Format string to build command to invoke compiler. */ + static const char fmt[] = "\ + echo \"#include <%s>\" |\ +-%s -E -dM -ansi -pedantic %s -D_LIBC -D_ISOMAC -DNOT_IN_libc -I. \ ++%s -E -dM -ansi -pedantic %s -D_LIBC -D_ISOMAC \ ++-DIN_MODULE=MODULE_extramodules -I. \ + -isystem `%s --print-prog-name=include` - 2> /dev/null > %s"; + + +@@ -304,7 +305,7 @@ get_null_defines (void) + ; + result[result_len] = xstrndup (start, end - start); + +- if (strcmp (result[result_len], "NOT_IN_libc") != 0) ++ if (strcmp (result[result_len], "IN_MODULE") != 0) + { + if (first) + { +Index: glibc-2.17-c758a686/sunrpc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sunrpc/Makefile ++++ glibc-2.17-c758a686/sunrpc/Makefile +@@ -168,7 +168,7 @@ $(cross-rpcgen-objs): $(objpfx)cross-%.o + $(objpfx)cross-rpcgen: $(cross-rpcgen-objs) + $(BUILD_CC) $^ $(BUILD_LDFLAGS) -o $@ + +-# This makes sure -DNOT_IN_libc is passed for all these modules. ++# This makes sure -DIN_MODULE is passed for all these modules. + cpp-srcs-left := $(rpcgen-objs:.o=.c) + lib := nonlib + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) +Index: glibc-2.17-c758a686/ports/sysdeps/arm/memmove.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/memmove.S ++++ glibc-2.17-c758a686/ports/sysdeps/arm/memmove.S +@@ -65,7 +65,7 @@ ENTRY(memmove) + + subs ip, r0, r1 + cmphi r2, ip +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + bls memcpy + #else + bls HIDDEN_JUMPTARGET(memcpy) +Index: glibc-2.17-c758a686/sysdeps/generic/_itoa.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/generic/_itoa.h ++++ glibc-2.17-c758a686/sysdeps/generic/_itoa.h +@@ -46,12 +46,12 @@ extern char *_itoa (unsigned long long i + + extern const char _itoa_upper_digits[]; + extern const char _itoa_lower_digits[]; +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + hidden_proto (_itoa_upper_digits) + hidden_proto (_itoa_lower_digits) + #endif + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + extern char *_itoa_word (_ITOA_WORD_TYPE value, char *buflim, + unsigned int base, int upper_case); + #else +Index: glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/generic/symbol-hacks.h ++++ glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h +@@ -1,6 +1,6 @@ + /* Some compiler optimizations may transform loops into memset/memmove + calls and without proper declaration it may generate PLT calls. */ +-#if !defined __ASSEMBLER__ && !defined NOT_IN_libc && defined SHARED ++#if !defined __ASSEMBLER__ && IS_IN (libc) && defined SHARED + asm ("memmove = __GI_memmove"); + asm ("memset = __GI_memset"); + asm ("memcpy = __GI_memcpy"); +Index: glibc-2.17-c758a686/sysdeps/gnu/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/gnu/Makefile ++++ glibc-2.17-c758a686/sysdeps/gnu/Makefile +@@ -41,7 +41,7 @@ $(objpfx)errlist-compat.c: $(errlist-c) + endif + $(make-target-directory) + $(AWK) -v maxerr=`\ +- $(CC) -S $(CPPFLAGS) $(CFLAGS) -DNOT_IN_libc -DEMIT_ERR_MAX $< -o - \ ++ $(CC) -S $(CPPFLAGS) $(CFLAGS) -DEMIT_ERR_MAX $< -o - \ + | sed -n 's/^.*@@@[^0-9]*\([0-9]*\)[^0-9]*@@@.*$$/\1/p'` \ + -f $(..)sysdeps/gnu/errlist-compat.awk \ + $(wildcard $(sysdirs:=/Versions)) > $@T +Index: glibc-2.17-c758a686/sysdeps/i386/i586/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i586/memset.S ++++ glibc-2.17-c758a686/sysdeps/i386/i586/memset.S +@@ -37,7 +37,7 @@ + #endif + + .text +-#if defined PIC && !defined NOT_IN_libc && !BZERO_P ++#if defined PIC && IS_IN (libc) && !BZERO_P + ENTRY (__memset_chk) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/memset.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/memset.S +@@ -38,7 +38,7 @@ + #endif + + .text +-#if defined PIC && !defined NOT_IN_libc && !BZERO_P ++#if defined PIC && IS_IN (libc) && !BZERO_P + ENTRY_CHK (__memset_chk) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +@@ -105,7 +105,7 @@ ENTRY (BP_SYM (memset)) + END (BP_SYM (memset)) + libc_hidden_builtin_def (memset) + +-#if defined PIC && !defined NOT_IN_libc && !BZERO_P ++#if defined PIC && IS_IN (libc) && !BZERO_P + strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bcopy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/bcopy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bcopy.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(bcopy) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bzero.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/bzero.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bzero.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__bzero) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr-sse2-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memchr-sse2-bsf.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr-sse2-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memchr-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define CFI_POP(REG) \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (REG) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp-sse4.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcmp-sse4.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp-sse4.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcmp-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(memcmp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S +@@ -19,7 +19,7 @@ + + #include + +-#if !defined NOT_IN_libc \ ++#if IS_IN (libc) \ + && (defined SHARED \ + || defined USE_AS_MEMMOVE \ + || !defined USE_MULTIARCH) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcpy-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if !defined NOT_IN_libc \ ++#if IS_IN (libc) \ + && (defined SHARED \ + || defined USE_AS_MEMMOVE \ + || !defined USE_MULTIARCH) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. In static binaries we need memcpy before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + .text + ENTRY(memcpy) + .type memcpy, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy_chk.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. There are no multiarch memcpy functions for static binaries. + */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__memcpy_chk) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memmove.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(memmove) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memmove_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove_chk.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__memmove_chk) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/mempcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. In static binaries we need mempcpy before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + .text + ENTRY(__mempcpy) + .type __mempcpy, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/mempcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy_chk.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. There are no multiarch mempcpy functions for static binaries. + */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__mempcpy_chk) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memrchr-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr-c.c +@@ -1,4 +1,4 @@ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define MEMRCHR __memrchr_ia32 + # include + extern void *__memrchr_ia32 (const void *, int, size_t); +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr-sse2-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memrchr-sse2-bsf.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr-sse2-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memrchr-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + # define CFI_PUSH(REG) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memrchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define CFI_POP(REG) \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (REG) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset-sse2-rep.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memset-sse2-rep.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset-sse2-rep.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + #include + #include "asm-syntax.h" +@@ -79,7 +79,7 @@ + #endif + + .section .text.sse2,"ax",@progbits +-#if defined SHARED && !defined NOT_IN_libc && !defined USE_AS_BZERO ++#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO + ENTRY (__memset_chk_sse2_rep) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memset-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + #include + #include "asm-syntax.h" +@@ -79,7 +79,7 @@ + #endif + + .section .text.sse2,"ax",@progbits +-#if defined SHARED && !defined NOT_IN_libc && !defined USE_AS_BZERO ++#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO + ENTRY (__memset_chk_sse2) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memset.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(memset) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memset_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset_chk.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__memset_chk) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/rawmemchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/rawmemchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/rawmemchr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define CFI_POP(REG) \ + cfi_adjust_cfa_offset (-4); \ + cfi_restore (REG) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcat-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat-sse2.S +@@ -18,7 +18,7 @@ + . */ + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcat-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat-ssse3.S +@@ -18,7 +18,7 @@ + . */ + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcat.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat.S +@@ -43,7 +43,7 @@ + /* Define multiple versions only for the definition in libc. Don't + define multiple versions for strncat in static library since we + need strncat before the initialization happened. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # ifdef SHARED + .text +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strchr-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(strchr) + .type strchr, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp-sse4.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcmp-sse4.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp-sse4.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + #include + #include "asm-syntax.h" +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcmp-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + #include + #include "asm-syntax.h" +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp.S +@@ -50,7 +50,7 @@ + /* Define multiple versions only for the definition in libc. Don't + define multiple versions for strncmp in static library since we + need strncmp before the initialization happened. */ +-#if (defined SHARED || !defined USE_AS_STRNCMP) && !defined NOT_IN_libc ++#if (defined SHARED || !defined USE_AS_STRNCMP) && IS_IN (libc) + # ifdef SHARED + .text + ENTRY(STRCMP) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcpy-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy-sse2.S +@@ -18,7 +18,7 @@ + . */ + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcpy-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy-ssse3.S +@@ -18,7 +18,7 @@ + . */ + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # ifndef USE_AS_STRCAT + # include +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy.S +@@ -59,7 +59,7 @@ + /* Define multiple versions only for the definition in libc. Don't + define multiple versions for strncpy in static library since we + need strncpy before the initialization happened. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # ifdef SHARED + .text +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcspn.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcspn.S +@@ -41,7 +41,7 @@ + /* Define multiple versions only for the definition in libc. Don't + define multiple versions for strpbrk in static library since we + need strpbrk before the initialization happened. */ +-#if (defined SHARED || !defined USE_AS_STRPBRK) && !defined NOT_IN_libc ++#if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc) + # ifdef SHARED + .text + ENTRY(STRCSPN) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + + #include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strlen-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen-sse2.S +@@ -19,7 +19,7 @@ + + /* for strlen only SHARED version is optimized, for strcat, strncat, strnlen both STATIC and SHARED are optimized */ + +-#if (defined USE_AS_STRNLEN || defined USE_AS_STRCAT || defined SHARED) && !defined NOT_IN_libc ++#if (defined USE_AS_STRNLEN || defined USE_AS_STRCAT || defined SHARED) && IS_IN (libc) + + # ifndef USE_AS_STRCAT + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strlen.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in libc and for the + DSO. In static binaries, we need strlen before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + .text + ENTRY(strlen) + .type strlen, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strnlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strnlen.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strnlen.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(__strnlen) + .type __strnlen, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strrchr-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strrchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(strrchr) + .type strrchr, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strspn.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strspn.S +@@ -26,7 +26,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(strspn) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcschr-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr-c.c +@@ -1,6 +1,6 @@ + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + # undef libc_hidden_def + # define libc_hidden_def(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcschr-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + # define CFI_PUSH(REG) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcschr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(wcschr) + .type wcschr, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscmp-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscmp-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscmp-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscmp.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in libc and for the + DSO. In static binaries, we need wcscmp before the initialization + happened. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(wcscmp) + .type wcscmp, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscpy-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy-c.c +@@ -1,4 +1,4 @@ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define wcscpy __wcscpy_ia32 + #endif + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscpy-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + # define CFI_PUSH(REG) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(wcscpy) + .type wcscpy, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcslen-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen-c.c +@@ -1,6 +1,6 @@ + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define WCSLEN __wcslen_ia32 + #endif + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcslen-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # define STR 4 + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcslen.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(__wcslen) + .type __wcslen, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcsrchr-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr-c.c +@@ -1,4 +1,4 @@ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define wcsrchr __wcsrchr_ia32 + #endif + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr-sse2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcsrchr-sse2.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr-sse2.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # define CFI_PUSH(REG) \ + cfi_adjust_cfa_offset (4); \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcsrchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr.S +@@ -21,7 +21,7 @@ + #include + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(wcsrchr) + .type wcsrchr, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wmemcmp-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wmemcmp-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wmemcmp-c.c +@@ -1,6 +1,6 @@ + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define WMEMCMP __wmemcmp_ia32 + #endif + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wmemcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wmemcmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wmemcmp.S +@@ -23,7 +23,7 @@ + + /* Define multiple versions only for the definition in libc. */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(wmemcmp) + .type wmemcmp, @gnu_indirect_function +Index: glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/libm-symbols.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/ia64/fpu/libm-symbols.h ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/fpu/libm-symbols.h +@@ -53,6 +53,6 @@ + ASM_SIZE_DIRECTIVE(__ieee754_##name); \ + .type __ieee754_##name, @function + +-#if defined ASSEMBLER && !defined NOT_IN_libc ++#if defined ASSEMBLER && IS_IN (libc) + # define __libm_error_support HIDDEN_JUMPTARGET(__libm_error_support) + #endif +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/bits/libc-lock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lock.h +@@ -26,7 +26,7 @@ + + /* Mutex type. */ + #if defined _LIBC || defined _IO_MTSAFE_IO +-# if (defined NOT_IN_libc && !IS_IN (libpthread)) || !defined _LIBC ++# if (!IS_IN (libc) && !IS_IN (libpthread)) || !defined _LIBC + typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t; + # else + typedef struct { int lock; int cnt; void *owner; } __libc_lock_recursive_t; +@@ -47,7 +47,7 @@ typedef struct __libc_lock_recursive_opa + + /* Define an initialized recursive lock variable NAME with storage + class CLASS. */ +-#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) ++#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) + # if LLL_LOCK_INITIALIZER == 0 + # define __libc_lock_define_initialized_recursive(CLASS,NAME) \ + CLASS __libc_lock_recursive_t NAME; +@@ -65,7 +65,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Initialize a recursive mutex. */ +-#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) ++#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) + # define __libc_lock_init_recursive(NAME) \ + ((NAME) = (__libc_lock_recursive_t) _LIBC_LOCK_RECURSIVE_INITIALIZER, 0) + #else +@@ -83,7 +83,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Finalize recursive named lock. */ +-#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) ++#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) + # define __libc_lock_fini_recursive(NAME) ((void) 0) + #else + # define __libc_lock_fini_recursive(NAME) \ +@@ -91,7 +91,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Lock the recursive named lock variable. */ +-#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) ++#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) + # define __libc_lock_lock_recursive(NAME) \ + do { \ + void *self = THREAD_SELF; \ +@@ -108,7 +108,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Try to lock the recursive named lock variable. */ +-#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) ++#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) + # define __libc_lock_trylock_recursive(NAME) \ + ({ \ + int result = 0; \ +@@ -133,7 +133,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Unlock the recursive named lock variable. */ +-#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) ++#if defined _LIBC && (IS_IN (libc) || IS_IN (libpthread)) + /* We do no error checking here. */ + # define __libc_lock_unlock_recursive(NAME) \ + do { \ +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lockP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/bits/libc-lockP.h ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lockP.h +@@ -35,7 +35,7 @@ + #include + + /* Mutex type. */ +-#if defined NOT_IN_libc && !IS_IN (libpthread) ++#if !IS_IN (libc) && !IS_IN (libpthread) + typedef pthread_mutex_t __libc_lock_t; + #else + typedef int __libc_lock_t; +@@ -69,7 +69,7 @@ typedef pthread_key_t __libc_key_t; + initialized locks must be set to one due to the lack of normal + atomic operations.) */ + +-#if !defined NOT_IN_libc || IS_IN (libpthread) ++#if IS_IN (libc) || IS_IN (libpthread) + # if LLL_LOCK_INITIALIZER == 0 + # define __libc_lock_define_initialized(CLASS,NAME) \ + CLASS __libc_lock_t NAME; +@@ -113,7 +113,7 @@ typedef pthread_key_t __libc_key_t; + #endif + + /* Call thread functions through the function pointer table. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # define PTFAVAIL(NAME) __libc_pthread_functions_init + # define __libc_ptf_call(FUNC, ARGS, ELSE) \ + (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE) +@@ -130,13 +130,13 @@ typedef pthread_key_t __libc_key_t; + + /* Initialize the named lock variable, leaving it in a consistent, unlocked + state. */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) ++#if IS_IN (libc) || IS_IN (libpthread) + # define __libc_lock_init(NAME) ((NAME) = LLL_LOCK_INITIALIZER, 0) + #else + # define __libc_lock_init(NAME) \ + __libc_maybe_call (__pthread_mutex_init, (&(NAME), NULL), 0) + #endif +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + /* ((NAME) = (__libc_rwlock_t) PTHREAD_RWLOCK_INITIALIZER, 0) is + inefficient. */ + # define __libc_rwlock_init(NAME) \ +@@ -149,13 +149,13 @@ typedef pthread_key_t __libc_key_t; + /* Finalize the named lock variable, which must be locked. It cannot be + used again until __libc_lock_init is called again on it. This must be + called on a lock variable before the containing storage is reused. */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) ++#if IS_IN (libc) || IS_IN (libpthread) + # define __libc_lock_fini(NAME) ((void) 0) + #else + # define __libc_lock_fini(NAME) \ + __libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0) + #endif +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # define __libc_rwlock_fini(NAME) ((void) 0) + #else + # define __libc_rwlock_fini(NAME) \ +@@ -163,7 +163,7 @@ typedef pthread_key_t __libc_key_t; + #endif + + /* Lock the named lock variable. */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) ++#if IS_IN (libc) || IS_IN (libpthread) + # ifndef __libc_lock_lock + # define __libc_lock_lock(NAME) \ + ({ lll_lock (NAME, LLL_PRIVATE); 0; }) +@@ -179,7 +179,7 @@ typedef pthread_key_t __libc_key_t; + __libc_ptf_call (__pthread_rwlock_wrlock, (&(NAME)), 0) + + /* Try to lock the named lock variable. */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) ++#if IS_IN (libc) || IS_IN (libpthread) + # ifndef __libc_lock_trylock + # define __libc_lock_trylock(NAME) \ + lll_trylock (NAME) +@@ -198,7 +198,7 @@ typedef pthread_key_t __libc_key_t; + __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0) + + /* Unlock the named lock variable. */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) ++#if IS_IN (libc) || IS_IN (libpthread) + # define __libc_lock_unlock(NAME) \ + lll_unlock (NAME, LLL_PRIVATE) + #else +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/stdio-lock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/bits/stdio-lock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/stdio-lock.h +@@ -84,7 +84,7 @@ typedef struct { int lock; int cnt; void + #define _IO_cleanup_region_end(_doit) \ + __libc_cleanup_region_end (_doit) + +-#if defined _LIBC && !defined NOT_IN_libc ++#if defined _LIBC && IS_IN (libc) + + # ifdef __EXCEPTIONS + # define _IO_acquire_lock(_fp) \ +Index: glibc-2.17-c758a686/sysdeps/posix/closedir.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/closedir.c ++++ glibc-2.17-c758a686/sysdeps/posix/closedir.c +@@ -44,7 +44,7 @@ __closedir (DIR *dirp) + + fd = dirp->fd; + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + __libc_lock_fini (dirp->lock); + #endif + +Index: glibc-2.17-c758a686/sysdeps/posix/opendir.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/opendir.c ++++ glibc-2.17-c758a686/sysdeps/posix/opendir.c +@@ -223,7 +223,7 @@ __alloc_dir (int fd, bool close_fd, int + } + + dirp->fd = fd; +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + __libc_lock_init (dirp->lock); + #endif + dirp->allocation = allocation; +Index: glibc-2.17-c758a686/sysdeps/posix/readdir.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/readdir.c ++++ glibc-2.17-c758a686/sysdeps/posix/readdir.c +@@ -40,7 +40,7 @@ __READDIR (DIR *dirp) + DIRENT_TYPE *dp; + int saved_errno = errno; + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + __libc_lock_lock (dirp->lock); + #endif + +@@ -110,7 +110,7 @@ __READDIR (DIR *dirp) + /* Skip deleted files. */ + } while (dp->d_ino == 0); + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + __libc_lock_unlock (dirp->lock); + #endif + +Index: glibc-2.17-c758a686/sysdeps/posix/rewinddir.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/rewinddir.c ++++ glibc-2.17-c758a686/sysdeps/posix/rewinddir.c +@@ -26,7 +26,7 @@ void + rewinddir (dirp) + DIR *dirp; + { +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + __libc_lock_lock (dirp->lock); + #endif + (void) __lseek (dirp->fd, (off_t) 0, SEEK_SET); +@@ -34,7 +34,7 @@ rewinddir (dirp) + dirp->offset = 0; + dirp->size = 0; + dirp->errcode = 0; +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + __libc_lock_unlock (dirp->lock); + #endif + } +Index: glibc-2.17-c758a686/sysdeps/powerpc/novmx-sigjmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/novmx-sigjmp.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/novmx-sigjmp.c +@@ -20,7 +20,7 @@ + + #include + #include +-#if !defined NOT_IN_libc && defined SHARED ++#if IS_IN (libc) && defined SHARED + # if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) + # include + # include +@@ -41,4 +41,4 @@ __novmx__sigjmp_save (__novmx__sigjmp_bu + } + + # endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */ +-#endif /* !NOT_IN_libc && SHARED */ ++#endif /* IS_IN (libc) && SHARED */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/__longjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/__longjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/__longjmp.S +@@ -19,11 +19,11 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + # include "__longjmp-common.S" + +-#else /* !NOT_IN_libc */ ++#else /* !IS_IN (libc) */ + strong_alias (__vmx__longjmp, __longjmp); + # define __longjmp __vmx__longjmp + # include "__longjmp-common.S" +@@ -35,4 +35,4 @@ strong_alias (__vmx__longjmp, __longjmp) + # define __longjmp __novmx__longjmp + # include "__longjmp-common.S" + # endif +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/bsd-_setjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/bsd-_setjmp.S +@@ -21,7 +21,7 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + ENTRY (BP_SYM (_setjmp)) + li r4,0 /* Set second argument to 0. */ +@@ -55,4 +55,4 @@ ENTRY (BP_SYM (__vmx_setjmp)) + b BP_SYM (__vmx__sigsetjmp@local) + END (BP_SYM (__vmx_setjmp)) + libc_hidden_def (__vmx_setjmp) +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/__longjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp.S +@@ -20,11 +20,11 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + # include "__longjmp-common.S" + +-#else /* !NOT_IN_libc */ ++#else /* !IS_IN (libc) */ + /* Build a versioned object for libc. */ + versioned_symbol (libc, __vmx__longjmp, __longjmp, GLIBC_2_3_4); + # define __longjmp __vmx__longjmp +@@ -38,4 +38,4 @@ compat_symbol (libc, __novmx__longjmp, _ + # define __longjmp __novmx__longjmp + # include "__longjmp-common.S" + # endif +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp.S +@@ -20,11 +20,11 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + # include "setjmp-common.S" + +-#else /* !NOT_IN_libc */ ++#else /* !IS_IN (libc) */ + /* Build a versioned object for libc. */ + versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) + # define __sigsetjmp __vmx__sigsetjmp +@@ -41,4 +41,4 @@ compat_symbol (libc, __novmx__sigsetjmp, + # define __sigjmp_save __novmx__sigjmp_save + # include "setjmp-common.S" + # endif +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/memset.S +@@ -230,7 +230,7 @@ L(nzCacheAligned128): + ori r1,r1,0 + stw rCHR,60(rMEMP3) + blt cr6,L(cacheAligned1) +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + lfd 0,-128(rMEMP) + #endif + b L(nzCacheAligned256) +@@ -238,7 +238,7 @@ L(nzCacheAligned128): + L(nzCacheAligned256): + cmplwi cr1,rLEN,256 + addi rMEMP3,rMEMP,64 +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + /* When we are not in libc we should use only GPRs to avoid the FPU lock + interrupt. */ + stw rCHR,0(rMEMP) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp.S +@@ -19,11 +19,11 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + # include "setjmp-common.S" + +-#else /* !NOT_IN_libc */ ++#else /* !IS_IN (libc) */ + /* Build a versioned object for libc. */ + versioned_symbol (libc, __vmx__sigsetjmp, __sigsetjmp, GLIBC_2_3_4) + # define __sigsetjmp __vmx__sigsetjmp +@@ -40,4 +40,4 @@ compat_symbol (libc, __novmx__sigsetjmp, + # define __sigjmp_save __novmx__sigjmp_save + # include "setjmp-common.S" + # endif +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/__longjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp.S +@@ -20,11 +20,11 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + # include "__longjmp-common.S" + +-#else /* !NOT_IN_libc */ ++#else /* IS_IN (libc) */ + strong_alias (__vmx__longjmp, __longjmp) + # define __longjmp __vmx__longjmp + # include "__longjmp-common.S" +@@ -36,4 +36,4 @@ strong_alias (__vmx__longjmp, __longjmp) + # define __longjmp __novmx__longjmp + # include "__longjmp-common.S" + # endif +-#endif /* !NOT_IN_libc */ ++#endif /* IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/bzero.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero.c +@@ -17,7 +17,7 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memchr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c +@@ -22,7 +22,7 @@ + #define weak_alias(name, aliasname) \ + extern __typeof (__memcmp_ppc) aliasname \ + __attribute__ ((weak, alias ("__memcmp_ppc"))); +-#if !defined(NOT_IN_libc) && defined(SHARED) ++#if IS_IN (libc) && defined(SHARED) + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) \ + __hidden_ver1(__memcmp_ppc, __GI_memcmp, __memcmp_ppc); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memcmp.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +@@ -17,7 +17,7 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S +@@ -18,7 +18,7 @@ + + #include + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # undef EALIGN + # define EALIGN(name, alignt, words) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memcpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy.c +@@ -19,7 +19,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. In static binaries we need memcpy before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + /* Redefine memcpy so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ + # undef memcpy +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memrchr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S +@@ -29,7 +29,7 @@ ENTRY (__bzero_ppc) + END_GEN_TB (__bzero_ppc,TB_TOCLESS) + + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # undef EALIGN + # define EALIGN(name, alignt, words) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/memset.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset.c +@@ -17,7 +17,7 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + /* Redefine memset so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ + # undef memset +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/stpcpy-ppc64.S +@@ -18,7 +18,7 @@ + + #include + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # undef EALIGN + # define EALIGN(name, alignt, words) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # define NO_MEMPCPY_STPCPY_REDIRECT + # include + # include +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # define strcasecmp __strcasecmp_ppc + extern __typeof (__strcasecmp) __strcasecmp_ppc attribute_hidden; +@@ -26,7 +26,7 @@ extern __typeof (__strcasecmp) __strcase + #include + #undef strcasecmp + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include "init-arch.h" + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # define strcasecmp_l __strcasecmp_l_ppc + extern __typeof (__strcasecmp_l) __strcasecmp_l_ppc attribute_hidden; +@@ -26,7 +26,7 @@ extern __typeof (__strcasecmp_l) __strca + #include + #undef strcasecmp_l + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include "init-arch.h" + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcat.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcat.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcat.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strchr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr.c +@@ -17,7 +17,7 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S +@@ -18,7 +18,7 @@ + + #include + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # undef EALIGN + # define EALIGN(name, alignt, words) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcmp.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcpy-ppc64.S +@@ -18,7 +18,7 @@ + + #include + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # undef EALIGN + # define EALIGN(name, alignt, words) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strcpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S +@@ -18,7 +18,7 @@ + + #include + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # undef ENTRY + # define ENTRY(name) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strlen.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + /* Redefine strlen so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ + # undef strlen +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strncase.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # define strncasecmp __strncasecmp_ppc + extern __typeof (__strncasecmp) __strncasecmp_ppc attribute_hidden; +@@ -26,7 +26,7 @@ extern __typeof (__strncasecmp) __strnca + #include + #undef strncasecmp + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include "init-arch.h" + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # define strncasecmp_l __strncasecmp_l_ppc + extern __typeof (__strncasecmp_l) __strncasecmp_l_ppc attribute_hidden; +@@ -26,7 +26,7 @@ extern __typeof (__strncasecmp_l) __strn + #include + #undef strncasecmp_l + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include "init-arch.h" + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S +@@ -17,7 +17,7 @@ + + #include + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + #undef EALIGN + #define EALIGN(name,alignt,words) \ + .section ".text"; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strncmp.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +@@ -17,7 +17,7 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c +@@ -22,7 +22,7 @@ + #define weak_alias(name, aliasname) \ + extern __typeof (__strncpy_ppc) aliasname \ + __attribute__ ((weak, alias ("__strncpy_ppc"))); +-#if !defined(NOT_IN_libc) && defined(SHARED) ++#if IS_IN (libc) && defined(SHARED) + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) \ + __hidden_ver1(__strncpy_ppc, __GI_strncpy, __strncpy_ppc); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strncpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncpy.c +@@ -17,7 +17,7 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strnlen.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/wcschr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include "init-arch.h" +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include + # include +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp.S +@@ -20,11 +20,11 @@ + #include + #include + +-#if defined NOT_IN_libc ++#if !IS_IN (libc) + /* Build a non-versioned object for rtld-*. */ + # include "setjmp-common.S" + +-#else /* !NOT_IN_libc */ ++#else /* !IS_IN (libc) */ + /* Build a versioned object for libc. */ + versioned_symbol (libc, __vmxsetjmp, setjmp, GLIBC_2_3_4) + versioned_symbol (libc, __vmx_setjmp, _setjmp, GLIBC_2_3_4) +@@ -54,4 +54,4 @@ compat_symbol (libc, __novmx__sigsetjmp, + # include "setjmp-common.S" + strong_alias (__novmxsetjmp, __novmx__setjmp) + # endif +-#endif /* !NOT_IN_libc */ ++#endif /* IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-niagara1.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memcpy-niagara1.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-niagara1.S +@@ -35,7 +35,7 @@ + #define XCC xcc + #endif + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + + .register %g2,#scratch + .register %g3,#scratch +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-niagara2.S +@@ -137,7 +137,7 @@ + LOAD(ldd, base + 0x28, %x5); \ + LOAD(ldd, base + 0x30, %x6); + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + + .register %g2,#scratch + .register %g3,#scratch +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-niagara4.S +@@ -46,7 +46,7 @@ + #define STORE(type,src,addr) type src, [addr] + #define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + + .register %g2,#scratch + .register %g3,#scratch +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S +@@ -30,7 +30,7 @@ + #define XCC xcc + #endif + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + + .register %g2,#scratch + .register %g3,#scratch +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memcpy.S +@@ -20,7 +20,7 @@ + + #include + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(memcpy) + .type memcpy, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memset-niagara1.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memset-niagara1.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memset-niagara1.S +@@ -28,7 +28,7 @@ + #define XCC xcc + #endif + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + + .register %g2,#scratch + +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memset-niagara4.S +@@ -21,7 +21,7 @@ + + #define ASI_BLK_INIT_QUAD_LDD_P 0xe2 + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + + .register %g2, #scratch + .register %g3, #scratch +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc64/multiarch/memset.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc64/multiarch/memset.S +@@ -20,7 +20,7 @@ + + #include + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(memset) + .type memset, @gnu_indirect_function +Index: glibc-2.17-c758a686/ports/sysdeps/unix/alpha/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/alpha/sysdep.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/alpha/sysdep.S +@@ -29,7 +29,7 @@ + .text + #endif + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + #else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/sysdeps/unix/make-syscalls.sh +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/make-syscalls.sh ++++ glibc-2.17-c758a686/sysdeps/unix/make-syscalls.sh +@@ -100,7 +100,7 @@ emit_weak_aliases() + *@@*) + base=`echo $name | sed 's/@@.*//'` + ver=`echo $name | sed 's/.*@@//;s/\./_/g'` +- echo " echo '#ifndef NOT_IN_libc'; \\" ++ echo " echo '#if IS_IN (libc)'; \\" + if test -z "$vcount" ; then + source=$strong + vcount=1 +@@ -117,7 +117,7 @@ emit_weak_aliases() + *@*) + base=`echo $name | sed 's/@.*//'` + ver=`echo $name | sed 's/.*@//;s/\./_/g'` +- echo " echo '#ifndef NOT_IN_libc'; \\" ++ echo " echo '#if IS_IN (libc)'; \\" + if test -z "$vcount" ; then + source=$strong + vcount=1 +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/Makefile ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/Makefile +@@ -160,7 +160,6 @@ sysdep-rtld-routines += dl-brk dl-sbrk d + dl-fxstatat64 + + libof-lddlibc4 = lddlibc4 +-CPPFLAGS-lddlibc4 += -DNOT_IN_libc + endif + + ifeq ($(subdir),rt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -85,7 +85,7 @@ ENTRY (name); \ + # define CENABLE bl __pthread_enable_asynccancel + # define CDISABLE bl __pthread_disable_asynccancel + # define __local_multiple_threads __pthread_multiple_threads +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE bl __libc_enable_asynccancel + # define CDISABLE bl __libc_disable_asynccancel + # define __local_multiple_threads __libc_multiple_threads +@@ -96,7 +96,7 @@ ENTRY (name); \ + # error Unsupported library + # endif + +-# if IS_IN (libpthread) || !defined NOT_IN_libc ++# if IS_IN (libpthread) || IS_IN (libc) + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -93,7 +93,7 @@ + # define ret_ERRVAL ret + + # define SYSCALL_ERROR .Lsyscall_error +-# if NOT_IN_libc ++# if !IS_IN (libc) + # if RTLD_PRIVATE_ERRNO + # define SYSCALL_ERROR_HANDLER \ + .Lsyscall_error: \ +@@ -325,7 +325,7 @@ + + /* Pointer mangling is supported for AArch64. */ + #if (IS_IN (rtld)) || \ +- (!defined SHARED && (!defined NOT_IN_libc \ ++ (!defined SHARED && (IS_IN (libc) \ + || IS_IN (libpthread))) + # ifdef __ASSEMBLER__ + # define PTR_MANGLE(dst, src, guard, tmp) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END + besides "ret". */ +@@ -109,7 +109,7 @@ __LABEL($multi_error) \ + # define __local_enable_asynccancel __pthread_enable_asynccancel + # define __local_disable_asynccancel __pthread_disable_asynccancel + # define __local_multiple_threads __pthread_multiple_threads +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define __local_enable_asynccancel __libc_enable_asynccancel + # define __local_disable_asynccancel __libc_disable_asynccancel + # define __local_multiple_threads __libc_multiple_threads +@@ -128,7 +128,7 @@ __LABEL($multi_error) \ + # define CDISABLE jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp) + # endif + +-# if IS_IN (libpthread) || !defined NOT_IN_libc ++# if IS_IN (libpthread) || IS_IN (libc) + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + /* NOTE: We do mark syscalls with unwind annotations, for the benefit of + cancellation; but they're really only accurate at the point of the +@@ -190,7 +190,7 @@ + # define CENABLE bl PLTJMP(__pthread_enable_asynccancel) + # define CDISABLE bl PLTJMP(__pthread_disable_asynccancel) + # define __local_multiple_threads __pthread_multiple_threads +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE bl PLTJMP(__libc_enable_asynccancel) + # define CDISABLE bl PLTJMP(__libc_disable_asynccancel) + # define __local_multiple_threads __libc_multiple_threads +@@ -201,7 +201,7 @@ + # error Unsupported library + # endif + +-# if IS_IN (libpthread) || !defined NOT_IN_libc ++# if IS_IN (libpthread) || IS_IN (libc) + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/sysdep.h +@@ -104,7 +104,7 @@ + + #define ret_ERRVAL PSEUDO_RET_NOERRNO + +-#if NOT_IN_libc ++#if !IS_IN (libc) + # define SYSCALL_ERROR __local_syscall_error + # if RTLD_PRIVATE_ERRNO + # define SYSCALL_ERROR_HANDLER \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/getpid.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/getpid.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/getpid.c +@@ -21,7 +21,7 @@ + #include + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + static inline __attribute__((always_inline)) pid_t really_getpid (pid_t oldval); + + static inline __attribute__((always_inline)) pid_t +@@ -48,7 +48,7 @@ really_getpid (pid_t oldval) + pid_t + __getpid (void) + { +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + INTERNAL_SYSCALL_DECL (err); + pid_t result = INTERNAL_SYSCALL (getpid, err, 0); + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h +@@ -56,7 +56,7 @@ + /* Initialize locks to zero. */ + #define LLL_MUTEX_LOCK_INITIALIZER (0) + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # ifndef NO_ERROR + # define NO_ERROR -0x1000 +@@ -216,7 +216,7 @@ L(pre_end): ASM_LINE_SEP \ + # define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \ + bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP + # endif +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # ifdef PIC + # define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \ + bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP +@@ -246,7 +246,7 @@ L(pre_end): ASM_LINE_SEP \ + + # if IS_IN (libpthread) + # define __local_multiple_threads __pthread_multiple_threads +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define __local_multiple_threads __libc_multiple_threads + # elif IS_IN (librt) + # define __local_multiple_threads __librt_multiple_threads +@@ -271,7 +271,7 @@ L(pre_end): ASM_LINE_SEP \ + # define NO_CANCELLATION 1 + + #endif +-/* !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) */ ++/* IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) */ + + #ifndef __ASSEMBLER__ + # define RTLD_SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S +@@ -115,7 +115,7 @@ __lll_lock_wait_private: + cfi_endproc + .size __lll_lock_wait_private,.-__lll_lock_wait_private + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl __lll_lock_wait + .type __lll_lock_wait,@function + .hidden __lll_lock_wait +@@ -361,7 +361,7 @@ __lll_unlock_wake_private: + cfi_endproc + .size __lll_unlock_wake_private,.-__lll_unlock_wake_private + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl __lll_unlock_wake + .type __lll_unlock_wake,@function + .hidden __lll_unlock_wake +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +@@ -71,7 +71,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +@@ -245,7 +245,7 @@ LLL_STUB_UNWIND_INFO_END + value is zero. In case the operation failed, the cmpxchg instruction + has loaded the current value of the memory work which is guaranteed + to be nonzero. */ +-#if defined NOT_IN_libc || defined UP ++#if !IS_IN (libc) || defined UP + # define __lll_trylock_asm LOCK_INSTR "cmpxchgl %2, %1" + #else + # define __lll_trylock_asm "cmpl $0, %%gs:%P5\n\t" \ +@@ -283,7 +283,7 @@ LLL_STUB_UNWIND_INFO_END + : "memory"); \ + ret; }) + +-#if defined NOT_IN_libc || defined UP ++#if !IS_IN (libc) || defined UP + # define __lll_lock_asm_start LOCK_INSTR "cmpxchgl %1, %2\n\t" + #else + # define __lll_lock_asm_start "cmpl $0, %%gs:%P6\n\t" \ +@@ -452,7 +452,7 @@ LLL_STUB_UNWIND_INFO_END + : "memory"); \ + result; }) + +-#if defined NOT_IN_libc || defined UP ++#if !IS_IN (libc) || defined UP + # define __lll_unlock_asm LOCK_INSTR "subl $1, %0\n\t" + #else + # define __lll_unlock_asm "cmpl $0, %%gs:%P3\n\t" \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -111,7 +111,7 @@ + # if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel; + # define CDISABLE call __pthread_disable_asynccancel +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE call __libc_enable_asynccancel; + # define CDISABLE call __libc_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -36,7 +36,7 @@ + #define SYS_ify(syscall_name) __NR_##syscall_name + + #if defined USE_DL_SYSINFO \ +- && (!defined NOT_IN_libc || IS_IN (libpthread)) ++ && (IS_IN (libc) || IS_IN (libpthread)) + # define I386_USE_SYSENTER 1 + #else + # undef I386_USE_SYSENTER +@@ -117,7 +117,7 @@ + + # elif defined _LIBC_REENTRANT + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h +@@ -22,11 +22,11 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSDEP_CANCEL_ERRNO __libc_errno + # else + # define SYSDEP_CANCEL_ERRNO errno +@@ -163,7 +163,7 @@ __GC_##name: \ + # if IS_IN (libpthread) + # define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel + # define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel + # define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/sysdep.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.S +@@ -34,7 +34,7 @@ ENTRY(__syscall_error) + st4 [r2]=r8 + mov r8=-1 + #else +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +@@ -61,7 +61,7 @@ + #endif + + #if defined USE_DL_SYSINFO \ +- && (!defined NOT_IN_libc \ ++ && (IS_IN (libc) \ + || IS_IN (libpthread) || IS_IN (librt)) + # define IA64_USE_NEW_STUB + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h +@@ -35,7 +35,7 @@ + + /* We define __rtld_* copies for rtld. + We need them visible in libc to initialize. */ +-# if IS_IN (rtld) || !defined NOT_IN_libc ++# if IS_IN (rtld) || IS_IN (libc) + extern void *__rtld___vdso_read_tp; + extern void *__rtld___vdso_atomic_cmpxchg_32; + extern void *__rtld___vdso_atomic_barrier; +@@ -44,7 +44,7 @@ extern void *__rtld___vdso_atomic_barrie + extern void __vdso_read_tp_stub (void); + extern void __vdso_atomic_cmpxchg_32_stub (void); + extern void __vdso_atomic_barrier_stub (void); +-# endif /* IS_IN (rtld) || !NOT_IN_libc */ ++# endif /* IS_IN (rtld) || IS_IN (libc) */ + + /* RTLD should only use its own copies. */ + # if !IS_IN (rtld) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -103,7 +103,7 @@ + # if IS_IN (libpthread) + # define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel) +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE PSEUDO_JMP (__libc_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel) + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/sysdep.h +@@ -102,7 +102,7 @@ SYSCALL_ERROR_LABEL: \ + move.l %d0, %a0; \ + rts; + # elif defined _LIBC_REENTRANT +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h +@@ -27,7 +27,7 @@ + happen before any instructions. So we use cfi_same_value instead of + cfi_restore. */ + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + #ifdef __PIC__ + # undef PSEUDO +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # ifdef __PIC__ + # define PSEUDO_CPLOAD .cpload t9; +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/not-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/not-cancel.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/not-cancel.h +@@ -27,7 +27,7 @@ + INLINE_SYSCALL (open, 2, (const char *) (name), (flags)) + + /* Uncancelable openat. */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + extern int __openat_nocancel (int fd, const char *fname, int oflag, + mode_t mode) attribute_hidden; + extern int __openat64_nocancel (int fd, const char *fname, int oflag, +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -84,7 +84,7 @@ + # if IS_IN (libpthread) + # define CENABLE bl __pthread_enable_asynccancel@local + # define CDISABLE bl __pthread_disable_asynccancel@local +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE bl __libc_enable_asynccancel@local + # define CDISABLE bl __libc_disable_asynccancel@local + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # ifdef HAVE_ASM_GLOBAL_DOT_NAME + # define DASHDASHPFX(str) .__##str +@@ -107,7 +107,7 @@ + # define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel); nop + # define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel); nop + # endif +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # ifdef SHARED + # define CENABLE bl JUMPTARGET(__libc_enable_asynccancel) + # define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +@@ -51,7 +51,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -78,7 +78,7 @@ L(pseudo_end): + # if IS_IN (libpthread) + # define CENABLE __pthread_enable_asynccancel + # define CDISABLE __pthread_disable_asynccancel +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE __libc_enable_asynccancel + # define CDISABLE __libc_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.S +@@ -31,7 +31,7 @@ + .text + ENTRY(__syscall_error) + #ifndef PIC +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +@@ -54,7 +54,7 @@ ENTRY(__syscall_error) + br %r14 + 1: .long rtld_errno - 0b + # else +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +@@ -106,7 +106,7 @@ + br %r14; \ + 2: .long rtld_errno-1b + # elif defined _LIBC_REENTRANT +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -73,7 +73,7 @@ L(pseudo_end): + # define CENABLE __pthread_enable_asynccancel + # define CDISABLE __pthread_disable_asynccancel + # define __local_multiple_threads __pthread_multiple_threads +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE __libc_enable_asynccancel + # define CDISABLE __libc_disable_asynccancel + # define __local_multiple_threads __libc_multiple_threads +@@ -111,7 +111,7 @@ L(pseudo_end): + #define LR7_6 lg %r7,56+160(%r15); \ + cfi_restore (%r7); + +-# if IS_IN (libpthread) || !defined NOT_IN_libc ++# if IS_IN (libpthread) || IS_IN (libc) + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.S +@@ -32,7 +32,7 @@ + .text + ENTRY(__syscall_error) + #ifndef PIC +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +@@ -55,7 +55,7 @@ ENTRY(__syscall_error) + lghi %r2,-1 + br %r14 + # else +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +@@ -114,7 +114,7 @@ + lghi %r2,-1; \ + br %r14 + # elif defined _LIBC_REENTRANT +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.S +@@ -172,7 +172,7 @@ __lll_lock_wait_private: + cfi_endproc + .size __lll_lock_wait_private,.-__lll_lock_wait_private + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl __lll_lock_wait + .type __lll_lock_wait,@function + .hidden __lll_lock_wait +@@ -454,7 +454,7 @@ __lll_unlock_wake_private: + cfi_endproc + .size __lll_unlock_wake_private,.-__lll_unlock_wake_private + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl __lll_unlock_wake + .type __lll_unlock_wake,@function + .hidden __lll_unlock_wake +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # define _IMM12 #-12 + # define _IMM16 #-16 +@@ -108,7 +108,7 @@ + # if IS_IN (libpthread) + # define __local_enable_asynccancel __pthread_enable_asynccancel + # define __local_disable_asynccancel __pthread_disable_asynccancel +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define __local_enable_asynccancel __libc_enable_asynccancel + # define __local_disable_asynccancel __libc_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sh/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sh/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sh/sysdep.h +@@ -116,7 +116,7 @@ + + # elif defined _LIBC_REENTRANT + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +@@ -56,7 +56,7 @@ extern void __cpu_relax (void); + #define BUSY_WAIT_NOP __cpu_relax () + #endif + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -71,7 +71,7 @@ __##syscall_name##_nocancel: \ + # if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel + # define CDISABLE call __pthread_disable_asynccancel +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE call __libc_enable_asynccancel + # define CDISABLE call __libc_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +@@ -80,7 +80,7 @@ ENTRY(name); \ + mov -1, %o0; + # elif defined _LIBC_REENTRANT + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S +@@ -89,7 +89,7 @@ ENTRY (__brk) + #endif + st %o0, [%g1] + #else +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + call HIDDEN_JUMPTARGET(__errno_location) + #else + call __errno_location +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -69,7 +69,7 @@ __##syscall_name##_nocancel: \ + # if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel + # define CDISABLE call __pthread_disable_asynccancel +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE call __libc_enable_asynccancel + # define CDISABLE call __libc_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +@@ -90,7 +90,7 @@ ENTRY(name); \ + mov -1, %o0; + # elif defined _LIBC_REENTRANT + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + /* Allow hacking in some extra code if desired. */ + #ifndef PSEUDO_EXTRA +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/sysdep.h +@@ -45,7 +45,7 @@ + #ifndef PIC + /* For static code, on error jump to __syscall_error directly. */ + # define SYSCALL_ERROR_NAME __syscall_error +-#elif !defined NOT_IN_libc || IS_IN (libpthread) ++#elif IS_IN (libc) || IS_IN (libpthread) + /* Use the internal name for libc/libpthread shared objects. */ + # define SYSCALL_ERROR_NAME __GI___syscall_error + #else +@@ -205,7 +205,7 @@ + #endif /* not __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && IS_IN (rtld) ++#if !IS_IN (libc) && IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S +@@ -1,7 +1,7 @@ + /* + extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden; + */ +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + /* Call __NR_wait4, providing fourth argument (struct rusage *) as NULL. */ + #define PSEUDO_EXTRA move r3, zero; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +@@ -108,7 +108,7 @@ __lll_lock_wait_private: + cfi_endproc + .size __lll_lock_wait_private,.-__lll_lock_wait_private + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl __lll_lock_wait + .type __lll_lock_wait,@function + .hidden __lll_lock_wait +@@ -348,7 +348,7 @@ __lll_unlock_wake_private: + cfi_endproc + .size __lll_unlock_wake_private,.-__lll_unlock_wake_private + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl __lll_unlock_wake + .type __lll_unlock_wake,@function + .hidden __lll_unlock_wake +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +@@ -72,7 +72,7 @@ + + #ifndef __ASSEMBLER__ + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +@@ -243,7 +243,7 @@ LLL_STUB_UNWIND_INFO_END + value is zero. In case the operation failed, the cmpxchg instruction + has loaded the current value of the memory work which is guaranteed + to be nonzero. */ +-#if defined NOT_IN_libc || defined UP ++#if !IS_IN (libc) || defined UP + # define __lll_trylock_asm LOCK_INSTR "cmpxchgl %2, %1" + #else + # define __lll_trylock_asm "cmpl $0, __libc_multiple_threads(%%rip)\n\t" \ +@@ -280,7 +280,7 @@ LLL_STUB_UNWIND_INFO_END + : "memory"); \ + ret; }) + +-#if defined NOT_IN_libc || defined UP ++#if !IS_IN (libc) || defined UP + # define __lll_lock_asm_start LOCK_INSTR "cmpxchgl %4, %2\n\t" \ + "jnz 1f\n\t" + #else +@@ -450,7 +450,7 @@ LLL_STUB_UNWIND_INFO_END + : "memory", "cx", "cc", "r10", "r11"); \ + result; }) + +-#if defined NOT_IN_libc || defined UP ++#if !IS_IN (libc) || defined UP + # define __lll_unlock_asm_start LOCK_INSTR "decl %0\n\t" \ + "jne 1f\n\t" + #else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + /* The code to disable cancellation depends on the fact that the called + functions are special. They don't modify registers other than %rax +@@ -63,7 +63,7 @@ + # define CENABLE call __pthread_enable_asynccancel; + # define CDISABLE call __pthread_disable_asynccancel; + # define __local_multiple_threads __pthread_multiple_threads +-# elif !defined NOT_IN_libc ++# elif IS_IN (libc) + # define CENABLE call __libc_enable_asynccancel; + # define CDISABLE call __libc_disable_asynccancel; + # define __local_multiple_threads __libc_multiple_threads +@@ -74,7 +74,7 @@ + # error Unsupported library + # endif + +-# if IS_IN (libpthread) || !defined NOT_IN_libc ++# if IS_IN (libpthread) || IS_IN (libc) + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/x86_64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/sysdep.h +@@ -117,7 +117,7 @@ + neg %eax; \ + movl %eax, (%rcx) + # else +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define SYSCALL_ERROR_ERRNO __libc_errno + # else + # define SYSCALL_ERROR_ERRNO errno +Index: glibc-2.17-c758a686/sysdeps/wordsize-32/symbol-hacks.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/wordsize-32/symbol-hacks.h ++++ glibc-2.17-c758a686/sysdeps/wordsize-32/symbol-hacks.h +@@ -23,7 +23,7 @@ + therefore we get PLTs. Unnecessarily so. Changing gcc is a big + task which might not be worth it so we play tricks with the + assembler. */ +-#if !defined __ASSEMBLER__ && !defined in_divdi3_c && !defined NOT_IN_libc && defined SHARED ++#if !defined __ASSEMBLER__ && !defined in_divdi3_c && IS_IN (libc) && defined SHARED + asm ("__divdi3 = __divdi3_internal"); + asm ("__udivdi3 = __udivdi3_internal"); + asm ("__moddi3 = __moddi3_internal"); +Index: glibc-2.17-c758a686/sysdeps/x86_64/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/memcpy.S +@@ -30,7 +30,7 @@ + # define RETVAL (0) + #else + # define RETVAL (-8) +-# if defined SHARED && !defined USE_MULTIARCH && !defined NOT_IN_libc ++# if defined SHARED && !defined USE_MULTIARCH && IS_IN (libc) + # define memcpy __memcpy + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) \ +@@ -44,7 +44,7 @@ + + .text + +-#if defined PIC && !defined NOT_IN_libc ++#if defined PIC && IS_IN (libc) + ENTRY_CHK (__memcpy_chk) + + cmpq %rdx, %rcx +@@ -253,14 +253,14 @@ L(32after): + /* Handle blocks smaller than 1/2 L1. */ + + L(fasttry): /* first 1/2 L1 */ +-#ifndef NOT_IN_libc /* only up to this algorithm outside of libc.so */ ++#if IS_IN (libc) /* only up to this algorithm outside of libc.so */ + mov __x86_64_data_cache_size_half(%rip), %R11_LP + cmpq %rdx, %r11 /* calculate the smaller of */ + cmovaq %rdx, %r11 /* remaining bytes and 1/2 L1 */ + #endif + + L(fast): /* good ol' MOVS */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + movq %r11, %rcx + andq $-8, %r11 + #else +@@ -275,7 +275,7 @@ L(fast): /* good ol' MOVS */ + .p2align 4,, 4 + + L(fastskip): +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + subq %r11, %rdx /* check for more */ + testq $-8, %rdx + jnz L(fastafter) +@@ -294,7 +294,7 @@ L(fastskip): + #endif + retq /* exit */ + +-#ifndef NOT_IN_libc /* none of the algorithms below for RTLD */ ++#if IS_IN (libc) /* none of the algorithms below for RTLD */ + + .p2align 4 + +@@ -570,13 +570,13 @@ L(NTskip): + #endif + retq /* exit */ + +-#endif /* !NOT_IN_libc */ ++#endif /* IS_IN (libc) */ + + END(memcpy) + + #ifndef USE_AS_MEMPCPY + libc_hidden_builtin_def (memcpy) +-# if defined SHARED && !defined USE_MULTIARCH && !defined NOT_IN_libc ++# if defined SHARED && !defined USE_MULTIARCH && IS_IN (libc) + # undef memcpy + # include + versioned_symbol (libc, __memcpy, memcpy, GLIBC_2_14); +Index: glibc-2.17-c758a686/sysdeps/x86_64/memmove.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/memmove.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/memmove.c +@@ -17,7 +17,7 @@ + + #include "string/memmove.c" + +-#if !defined memmove && !defined NOT_IN_libc ++#if !defined memmove && IS_IN (libc) + #include + + #if SHLIB_COMPAT (libc, GLIBC_2_2_5, GLIBC_2_14) +Index: glibc-2.17-c758a686/sysdeps/x86_64/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/memset.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/memset.S +@@ -23,7 +23,7 @@ + #define __STOS_UPPER_BOUNDARY $65536 + + .text +-#if !defined NOT_IN_libc && !defined USE_MULTIARCH ++#if IS_IN (libc) && !defined USE_MULTIARCH + ENTRY(__bzero) + mov %rsi,%rdx /* Adjust parameter. */ + xorl %esi,%esi /* Fill with 0s. */ +@@ -32,7 +32,7 @@ END(__bzero) + weak_alias (__bzero, bzero) + #endif + +-#if defined PIC && !defined NOT_IN_libc ++#if defined PIC && IS_IN (libc) + ENTRY_CHK (__memset_chk) + cmpq %rdx, %rcx + jb HIDDEN_JUMPTARGET (__chk_fail) +@@ -1354,7 +1354,7 @@ L(8byte_nt_move_skip): + END (memset) + libc_hidden_builtin_def (memset) + +-#if defined PIC && !defined NOT_IN_libc && !defined USE_MULTIARCH ++#if defined PIC && IS_IN (libc) && !defined USE_MULTIARCH + strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/init-arch.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.h +@@ -141,7 +141,7 @@ extern void __init_cpu_features (void) a + extern const struct cpu_features *__get_cpu_features (void) + __attribute__ ((const)); + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define __get_cpu_features() (&__cpu_features) + # endif + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp-sse4.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcmp-sse4.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp-sse4.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcmp-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(memcmp) + .type memcmp, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy-ssse3-back.S +@@ -19,7 +19,7 @@ + + #include + +-#if !defined NOT_IN_libc \ ++#if IS_IN (libc) \ + && (defined SHARED \ + || defined USE_AS_MEMMOVE \ + || !defined USE_MULTIARCH) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy-ssse3.S +@@ -19,7 +19,7 @@ + + #include + +-#if !defined NOT_IN_libc \ ++#if IS_IN (libc) \ + && (defined SHARED \ + || defined USE_AS_MEMMOVE \ + || !defined USE_MULTIARCH) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy.S +@@ -25,7 +25,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. In static binaries we need memcpy before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + .text + ENTRY(__new_memcpy) + .type __new_memcpy, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. There are no multiarch memcpy functions for static binaries. + */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__memcpy_chk) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memmove.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove.c +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define MEMMOVE __memmove_sse2 + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -39,7 +39,7 @@ extern __typeof (__redirect_memmove) __m + + #include "string/memmove.c" + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + # include "init-arch.h" + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/mempcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. In static binaries we need mempcpy before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + ENTRY(__mempcpy) + .type __mempcpy, @gnu_indirect_function + cmpl $0, KIND_OFFSET+__cpu_features(%rip) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/mempcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy_chk.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in lib and for + DSO. There are no multiarch mempcpy functions for static binaries. + */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + .text + ENTRY(__mempcpy_chk) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset.S +@@ -21,7 +21,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + ENTRY(memset) + .type memset, @gnu_indirect_function + cmpl $0, __cpu_features+KIND_OFFSET(%rip) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset_chk.S +@@ -21,7 +21,7 @@ + #include + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + ENTRY(__memset_chk) + .type __memset_chk, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat-sse2-unaligned.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcat-sse2-unaligned.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat-sse2-unaligned.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcat-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcat.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat.S +@@ -43,7 +43,7 @@ + + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(STRCAT) + .type STRCAT, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strchr-sse2-no-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strchr-sse2-no-bsf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strchr-sse2-no-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # include + # include "asm-syntax.h" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strchr.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strchr.S +@@ -21,7 +21,7 @@ + + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(strchr) + .type strchr, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcmp-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcmp-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcmp-ssse3.S +@@ -1,4 +1,4 @@ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define USE_SSSE3 1 + # define STRCMP __strcmp_ssse3 + # include "../strcmp.S" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcmp.S +@@ -79,7 +79,7 @@ + /* Define multiple versions only for the definition in libc. Don't + define multiple versions for strncmp in static library since we + need strncmp before the initialization happened. */ +-#if (defined SHARED || !defined USE_AS_STRNCMP) && !defined NOT_IN_libc ++#if (defined SHARED || !defined USE_AS_STRNCMP) && IS_IN (libc) + .text + ENTRY(STRCMP) + .type STRCMP, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # ifndef USE_AS_STRCAT + # include +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcpy-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + # ifndef USE_AS_STRCAT + # include +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy.S +@@ -57,7 +57,7 @@ + + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(STRCPY) + .type STRCPY, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcspn.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcspn.S +@@ -41,7 +41,7 @@ + /* Define multiple versions only for the definition in libc. Don't + define multiple versions for strpbrk in static library since we + need strpbrk before the initialization happened. */ +-#if (defined SHARED || !defined USE_AS_STRPBRK) && !defined NOT_IN_libc ++#if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc) + .text + ENTRY(STRCSPN) + .type STRCSPN, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strspn.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strspn.S +@@ -26,7 +26,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(strspn) + .type strspn, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wcscpy-c.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy-c.c +@@ -1,4 +1,4 @@ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define wcscpy __wcscpy_sse2 + #endif + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy-ssse3.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wcscpy-ssse3.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy-ssse3.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + .section .text.ssse3,"ax",@progbits +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wcscpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + .text + ENTRY(wcscpy) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wmemcmp-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wmemcmp-c.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wmemcmp-c.c +@@ -1,4 +1,4 @@ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + # define WMEMCMP __wmemcmp_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wmemcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wmemcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wmemcmp.S +@@ -22,7 +22,7 @@ + #include + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(wmemcmp) + .type wmemcmp, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/strcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/strcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/strcmp.S +@@ -129,7 +129,7 @@ libc_hidden_def (__strncasecmp) + #endif + + ENTRY (BP_SYM (STRCMP)) +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + /* Simple version since we can't use SSE registers in ld.so. */ + L(oop): movb (%rdi), %al + cmpb (%rsi), %al +@@ -147,7 +147,7 @@ L(neq): movl $1, %eax + cmovbl %ecx, %eax + ret + END (BP_SYM (STRCMP)) +-#else /* NOT_IN_libc */ ++#else /* !IS_IN (libc) */ + # ifdef USE_AS_STRCASECMP_L + /* We have to fall back on the C implementation for locales + with encodings not matching ASCII for single bytes. */ +@@ -2303,5 +2303,5 @@ LABEL(unaligned_table): + .int LABEL(ashr_14) - LABEL(unaligned_table) + .int LABEL(ashr_15) - LABEL(unaligned_table) + .int LABEL(ashr_0) - LABEL(unaligned_table) +-#endif /* NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ + libc_hidden_builtin_def (STRCMP) +Index: glibc-2.17-c758a686/ChangeLog +=================================================================== +--- glibc-2.17-c758a686.orig/ChangeLog ++++ glibc-2.17-c758a686/ChangeLog +@@ -4849,7 +4849,7 @@ + + * libio/genops.c (_IO_unbuffer_write): Conditionalize locking code on + [_IO_MTSAFE_IO]. +- * libio/libioP.h [!_IO_MTSAFE_IO && !NOT_IN_libc] ++ * libio/libioP.h [!_IO_MTSAFE_IO && !IS_IN (libc)] + (_IO_acquire_lock, _IO_acquire_lock_clear_flags2, _IO_release_lock): + New macros. + +@@ -5014,7 +5014,7 @@ + including . + + * sysdeps/x86_64/multiarch/memmove.c: Don't include . +- [!NOT_IN_libc]: Move #define and #undef of memmove to just before ++ [!IS_IN (libc)]: Move #define and #undef of memmove to just before + and after including . Move declarations of + __memmove_sse2, __memmove_ssse3, and __memmove_ssse3_back + to before #include "string/memmove.c". +@@ -7322,7 +7322,7 @@ + 2012-05-30 Richard Henderson + + * sysdeps/unix/make-syscalls.sh: Protect symbol_version output +- with #ifndef NOT_IN_libc. ++ with #if IS_IN (libc). + + * scripts/abilist.awk: Accept 8 fields. Handle Alpha functions + marked to avoid plt entry. +Index: glibc-2.17-c758a686/ChangeLog.13 +=================================================================== +--- glibc-2.17-c758a686.orig/ChangeLog.13 ++++ glibc-2.17-c758a686/ChangeLog.13 +@@ -2465,7 +2465,7 @@ + ($(objpfx)errlist.d): Depend on $(..)sysdeps/gnu/errlist-compat.c. + * sysdeps/gnu/errlist.awk: Make output define _sys_errlist_internal + and _sys_nerr_internal instead of anything else. Make it include +- "errlist-compat.c" if [!NOT_IN_libc && !ERRLIST_NO_COMPAT]. ++ "errlist-compat.c" if [!IS_IN (libc) && !ERRLIST_NO_COMPAT]. + Make it emit some asm magic if [EMIT_ERR_MAX]. + * sysdeps/gnu/errlist.c: Regenerated. + * sysdeps/gnu/errlist-compat.awk: New file. +Index: glibc-2.17-c758a686/ChangeLog.14 +=================================================================== +--- glibc-2.17-c758a686.orig/ChangeLog.14 ++++ glibc-2.17-c758a686/ChangeLog.14 +@@ -2058,13 +2058,13 @@ + * sysdeps/powerpc/powerpc64/__longjmp-common.S: New file. + * sysdeps/powerpc/powerpc64/__longjmp.S [NOT_IN_libc](__longjmp): + Non-versioned __longjmp for rtld-__longjmp. +- [!NOT_IN_libc](__vmx__longjmp): Add VMX reg support and define as ++ [!IS_IN (libc)](__vmx__longjmp): Add VMX reg support and define as + default version of __longjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)] + (__novmx__longjmp): Original version of __longjmp. + * sysdeps/powerpc/powerpc64/bsd-_setjmp.S [NOT_IN_libc](_setjmp): + Non-versioned _setjmp for rtld-_setjmp. +- [!NOT_IN_libc](__vmx_setjmp): Branch to __vmx__sigsetjmp and define ++ [!IS_IN (libc)](__vmx_setjmp): Branch to __vmx__sigsetjmp and define + as default version of _setjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)] + (__novmx_setjmp): Original version of _setjmp. +@@ -2075,7 +2075,7 @@ + * sysdeps/powerpc/powerpc64/setjmp-common.S: New file. + * sysdeps/powerpc/powerpc64/setjmp.S [NOT_IN_libc](__setjmp): + Non-versioned __sigsetjmp for rtld-setjmp. +- [!NOT_IN_libc](__vmx__sigsetjmp): Add VMX reg support and define ++ [!IS_IN (libc)](__vmx__sigsetjmp): Add VMX reg support and define + as default version of __sigsetjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)] + (__novmx__sigsetjmp): Original version of __sigsetjmp. +@@ -2083,13 +2083,13 @@ + * sysdeps/powerpc/powerpc32/__longjmp-common.S: New File + * sysdeps/powerpc/powerpc32/__longjmp.S [NOT_IN_libc](__longjmp): + Non-versioned __longjmp for rtld-__longjmp. +- [!NOT_IN_libc](__vmx__longjmp): Add VMX reg support and define as ++ [!IS_IN (libc)](__vmx__longjmp): Add VMX reg support and define as + default version of __longjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)] + (__novmx__longjmp): Original version of __longjmp. + * sysdeps/powerpc/powerpc32/bsd-_setjmp.S [NOT_IN_libc](_setjmp): + Non-versioned _setjmp for rtld-_setjmp. +- [!NOT_IN_libc](__vmx_setjmp): Branch to __vmx__sigsetjmp and define ++ [!IS_IN (libc)](__vmx_setjmp): Branch to __vmx__sigsetjmp and define + as default version of _setjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)] + (__novmx_setjmp): Original version of _setjmp. +@@ -2100,21 +2100,21 @@ + * sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S: New file. + * sysdeps/powerpc/powerpc32/fpu/__longjmp.S [NOT_IN_libc](__longjmp): + Non-versioned __longjmp for rtld-__longjmp. +- [!NOT_IN_libc](__vmx__longjmp): Add VMX reg support and define as ++ [!IS_IN (libc)](__vmx__longjmp): Add VMX reg support and define as + default version of __longjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)] + (__novmx__longjmp): Original version of __longjmp. + * sysdeps/powerpc/powerpc32/fpu/setjmp-common.S: New file. + * sysdeps/powerpc/powerpc32/fpu/setjmp.S [NOT_IN_libc](__setjmp): + Non-versioned __sigsetjmp for rtld-setjmp. +- [!NOT_IN_libc](__vmx__sigsetjmp): Add VMX reg support and define ++ [!IS_IN (libc)](__vmx__sigsetjmp): Add VMX reg support and define + as default version of __sigsetjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)] + (__novmx__sigsetjmp): Original version of __sigsetjmp. + * sysdeps/powerpc/powerpc32/setjmp-common.S: New file. + * sysdeps/powerpc/powerpc32/setjmp.S [NOT_IN_libc](__setjmp): + Non-versioned __sigsetjmp for rtld-setjmp. +- [!NOT_IN_libc](__vmx__sigsetjmp): Add VMX reg support and define ++ [!IS_IN (libc)](__vmx__sigsetjmp): Add VMX reg support and define + as default version of __sigsetjmp. + [SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)] + (__novmx__sigsetjmp): Original version of __sigsetjmp. +Index: glibc-2.17-c758a686/csu/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/csu/Makefile ++++ glibc-2.17-c758a686/csu/Makefile +@@ -146,13 +146,13 @@ $(objpfx)version-info.h: $(common-objpfx + linux*) version=`(printf '%s\n%s\n' \ + '#include ' \ + UTS_RELEASE \ +- | $(CC) $(CPPFLAGS) -O -E -P - -DNOT_IN_libc=1 | \ ++ | $(CC) $(CPPFLAGS) -O -E -P - | \ + sed -e 's/"\([^"]*\)".*/\1/p' -e d) 2>/dev/null`;\ + if [ -z "$$version" ]; then \ + version=`(printf '%s\n%s\n' \ + '#include ' \ + LINUX_VERSION_CODE \ +- | $(CC) $(CPPFLAGS) -O -E -P - -DNOT_IN_libc=1 \ ++ | $(CC) $(CPPFLAGS) -O -E -P - \ + | sed -n -e '/^[123456789].*/p' \ + | awk '{v=$$1; \ + printf("%d.%d.%d\n", \ +Index: glibc-2.17-c758a686/nptl/ChangeLog +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/ChangeLog ++++ glibc-2.17-c758a686/nptl/ChangeLog +@@ -11683,7 +11683,7 @@ + 2002-12-16 Jakub Jelinek + + * libc-cancellation.c: Guard both function with +- #if !defined NOT_IN_libc. ++ #if IS_IN (libc). + * Makefile (libpthread-routines): Use ptw-, not pt- prefix for the + automatically provided pthread wrappers. + * pthreadP.h (LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): Define to +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -134,8 +134,6 @@ libpthread-routines = nptl-init vars eve + libpthread-shared-only-routines = version pt-allocrtsig unwind-forcedunwind + libpthread-static-only-routines = pthread_atfork + +-CFLAGS-pthread_atfork.c = -DNOT_IN_libc +- + # Since cancellation handling is in large parts handled using exceptions + # we have to compile some files with exception handling enabled, some + # even with asynchronous unwind tables. +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +@@ -19,7 +19,7 @@ + + #include + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + extern int __open_nocancel (const char *, int, ...) attribute_hidden; + extern int __close_nocancel (int) attribute_hidden; + extern int __read_nocancel (int, void *, size_t) attribute_hidden; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +@@ -52,7 +52,7 @@ + #define LLL_PRIVATE 0 + #define LLL_SHARED FUTEX_PRIVATE_FLAG + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/lowlevellock.h +@@ -49,7 +49,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) ++#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -103,7 +103,7 @@ + # define CDISABLE call +__libc_disable_asynccancel,[],0; + # endif + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + # define __local_multiple_threads __libc_multiple_threads + #elif IS_IN (libpthread) + # define __local_multiple_threads __pthread_multiple_threads +@@ -118,7 +118,7 @@ + p_header.data.multiple_threads) == 0, 1) + # else + extern int __local_multiple_threads +-# if !defined NOT_IN_libc || IS_IN (libpthread) ++# if IS_IN (libc) || IS_IN (libpthread) + attribute_hidden; + # else + ; +@@ -130,7 +130,7 @@ extern int __local_multiple_threads + # define SINGLE_THREAD_P \ + mov (+__local_multiple_threads),d0; \ + cmp 0,d0 +-# elif !defined NOT_IN_libc || IS_IN (libpthread) ++# elif IS_IN (libc) || IS_IN (libpthread) + # define SINGLE_THREAD_P \ + movm [a2],(sp); \ + 1: mov pc,a2; \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h +@@ -48,7 +48,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h +@@ -48,7 +48,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || IS_IN (rtld) ++#if IS_IN (libc) || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define MEMRCHR __memrchr_ppc + # include + extern void *__memrchr_ppc (const void *, int, size_t); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c +@@ -17,7 +17,7 @@ + + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # ifdef SHARED + # undef libc_hidden_def + # define libc_hidden_def(name) \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c +@@ -17,7 +17,7 @@ + + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define WCSCPY __wcscpy_ppc + #endif + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c +@@ -17,7 +17,7 @@ + + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # define WCSRCHR __wcsrchr_ppc + #endif + +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memccpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memccpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memccpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define MEMCCPY __memccpy_c + # undef weak_alias + # define weak_alias(a, b) +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memccpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memccpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memccpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -153,4 +153,4 @@ ENTRY(__memccpy_vx) + lghi %r2,0 /* Return null. */ + br %r14 + END(__memccpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memccpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memccpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memccpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__memccpy, memccpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -154,6 +154,6 @@ END(__memchr_vx) + # define memchr __memchr_c + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) strong_alias(__memchr_c, __GI_memchr) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ + + #include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memrchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memrchr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memrchr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define MEMRCHR __memrchr_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memrchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memrchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memrchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -157,4 +157,4 @@ ENTRY(__memrchr_vx) + clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ + j .Llt64 + END(__memrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/memrchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/memrchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/memrchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__memrchr, memrchr) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/rawmemchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/rawmemchr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/rawmemchr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + + # define RAWMEMCHR __rawmemchr_c +@@ -31,4 +31,4 @@ + extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden; + + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/rawmemchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/rawmemchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/rawmemchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -89,4 +89,4 @@ ENTRY(__rawmemchr_vx) + la %r2,0(%r5,%r2) /* Return pointer to character. */ + br %r14 + END(__rawmemchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/rawmemchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/rawmemchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/rawmemchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__rawmemchr, rawmemchr) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT &&!defined NOT_IN_libc ) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT &&IS_IN (libc) ) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/stpcpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/stpcpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/stpcpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STPCPY __stpcpy_c + # undef libc_hidden_def + # undef weak_alias +@@ -31,4 +31,4 @@ + + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/stpcpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/stpcpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/stpcpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -101,4 +101,4 @@ ENTRY(__stpcpy_vx) + la %r2,0(%r5,%r2) /* Return pointer to zero. */ + br %r14 + END(__stpcpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/stpcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/stpcpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/stpcpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -26,4 +26,4 @@ libc_hidden_builtin_def (stpcpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/stpncpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/stpncpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/stpncpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STPNCPY __stpncpy_c + # ifdef SHARED + # undef libc_hidden_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/stpncpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/stpncpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/stpncpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -197,4 +197,4 @@ ENTRY(__stpncpy_vx) + vl %v16,0(%r5,%r3) /* Load s. */ + j .Llt64 + END(__stpncpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/stpncpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/stpncpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/stpncpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__stpncpy, stpncpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcat-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcat-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcat-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRCAT __strcat_c + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcat-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcat-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcat-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -158,4 +158,4 @@ ENTRY(__strcat_vx) + lgr %r2,%r0 /* Load saved dest-ptr. */ + br %r14 + END(__strcat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcat.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcat.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcat.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__strcat, strcat) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strchr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strchr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRCHR __strchr_c + # undef weak_alias + # ifdef SHARED +@@ -26,4 +26,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -97,4 +97,4 @@ ENTRY(__strchr_vx) + lghi %r2,0 /* Return null if character not found. */ + br %r14 + END(__strchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (strchr, index) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strchrnul-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strchrnul-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strchrnul-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRCHRNUL __strchrnul_c + # define __strchrnul STRCHRNUL + # undef weak_alias +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strchrnul-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strchrnul-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strchrnul-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -90,4 +90,4 @@ ENTRY(__strchrnul_vx) + .Lend: + br %r14 + END(__strchrnul_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strchrnul.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strchrnul.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strchrnul.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__strchrnul, strchrnul) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcmp-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcmp-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcmp-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -111,6 +111,6 @@ END(__strcmp_vx) + # define strcmp __strcmp_c + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ + + #include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -103,7 +103,7 @@ END(__strcpy_vx) + # define strcpy __strcpy_c + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ + + /* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory. */ + #include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcspn-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcspn-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcspn-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRCSPN __strcspn_c + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcspn-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcspn-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcspn-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -278,4 +278,4 @@ ENTRY(__strcspn_vx) + vlgvg %r9,%v31,1 + br %r14 + END(__strcspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strcspn.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strcspn.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strcspn.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__strcspn, strcspn) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strlen-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strlen-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strlen-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRLEN __strlen_c + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strlen-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strlen-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strlen-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -81,4 +81,4 @@ ENTRY(__strlen_vx) + algr %r2,%r5 + br %r14 + END(__strlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strlen.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strlen.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strlen.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__strlen, strlen) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncat-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncat-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncat-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRNCAT __strncat_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncat-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncat-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncat-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -236,4 +236,4 @@ ENTRY(__strncat_vx) + vl %v16,0(%r5,%r3) /* Load s. */ + j .Lcpy_lt64 + END(__strncat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncat.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncat.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncat.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__strncat, strncat) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncmp-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncmp-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncmp-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRNCMP __strncmp_c + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncmp-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncmp-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncmp-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -134,4 +134,4 @@ ENTRY(__strncmp_vx) + lghi %r2,0 + br %r14 + END(__strncmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -27,4 +27,4 @@ s390_vx_libc_ifunc2 (__strncmp, strncmp) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -201,7 +201,7 @@ END(__strncpy_vx) + # define strncpy __strncpy_c + # undef libc_hidden_builtin_def + # define libc_hidden_builtin_def(name) strong_alias(__strncpy_c, __GI_strncpy) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ + + /* Include strncpy-implementation in s390-32/s390-64 subdirectory. */ + #include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strncpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strncpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strncpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strnlen-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strnlen-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strnlen-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRNLEN __strnlen_c + # ifdef SHARED + # undef libc_hidden_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strnlen-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strnlen-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strnlen-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -131,4 +131,4 @@ ENTRY(__strnlen_vx) + + j .Llt64 + END(__strnlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strnlen.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strnlen.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strnlen.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -26,4 +26,4 @@ libc_hidden_def (strnlen) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strpbrk-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strpbrk-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strpbrk-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRPBRK __strpbrk_c + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strpbrk-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strpbrk-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strpbrk-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -299,4 +299,4 @@ ENTRY(__strpbrk_vx) + lgr %r2,%r1 + br %r14 + END(__strpbrk_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strpbrk.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strpbrk.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strpbrk.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__strpbrk, strpbrk) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strrchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strrchr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strrchr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRRCHR __strrchr_c + # undef weak_alias + # ifdef SHARED +@@ -26,4 +26,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strrchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strrchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strrchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -177,4 +177,4 @@ ENTRY(__strrchr_vx) + .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 + .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 + END(__strrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strrchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strrchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strrchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (strrchr, rindex) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strspn-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strspn-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strspn-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define STRSPN __strspn_c + # ifdef SHARED + # undef libc_hidden_builtin_def +@@ -25,4 +25,4 @@ + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strspn-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strspn-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strspn-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -253,4 +253,4 @@ ENTRY(__strspn_vx) + j .Lslow_next_acc_notonbb /* ... and search for zero in + fully loaded vreg again. */ + END(__strspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/strspn.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/strspn.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/strspn.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__strspn, strspn) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpcpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcpcpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpcpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCPCPY __wcpcpy_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpcpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcpcpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpcpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -111,4 +111,4 @@ ENTRY(__wcpcpy_vx) + .Lfallback: + jg __wcpcpy_c + END(__wcpcpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcpcpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpcpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcpcpy, wcpcpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpncpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcpncpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpncpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCPNCPY __wcpncpy_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpncpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcpncpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpncpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -219,4 +219,4 @@ ENTRY(__wcpncpy_vx) + .Lfallback: + jg __wcpncpy_c + END(__wcpncpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpncpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcpncpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcpncpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcpncpy, wcpncpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscat-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscat-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscat-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSCAT __wcscat_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscat-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscat-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscat-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -172,4 +172,4 @@ ENTRY(__wcscat_vx) + .Lfallback: + jg __wcscat_c + END(__wcscat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscat.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscat.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscat.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcscat, wcscat) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcschr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSCHR __wcschr_c + + # include +@@ -28,4 +28,4 @@ extern __typeof (wcschr) __wcschr_c; + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcschr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -100,4 +100,4 @@ ENTRY(__wcschr_vx) + .Lfallback: + jg __wcschr_c + END(__wcschr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcschr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcschr, wcschr) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschrnul-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcschrnul-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschrnul-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSCHRNUL __wcschrnul_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschrnul-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcschrnul-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschrnul-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -94,4 +94,4 @@ ENTRY(__wcschrnul_vx) + .Lfallback: + jg __wcschrnul_c + END(__wcschrnul_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschrnul.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcschrnul.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcschrnul.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcschrnul, wcschrnul) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscmp-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscmp-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscmp-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSCMP __wcscmp_c + + # include +@@ -27,4 +27,4 @@ extern __typeof (wcscmp) __wcscmp_c; + __hidden_ver1 (__wcscmp_c, __GI_wcscmp, __wcscmp_c); + # endif /* SHARED */ + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscmp-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscmp-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscmp-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -128,4 +128,4 @@ ENTRY(__wcscmp_vx) + lghi %r2,0 + br %r14 + END(__wcscmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcscmp, wcscmp) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSCPY __wcscpy_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -108,4 +108,4 @@ ENTRY(__wcscpy_vx) + .Lfallback: + jg __wcscpy_c + END(__wcscpy_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcscpy, wcscpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscspn-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscspn-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscspn-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSCSPN __wcscspn_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscspn-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscspn-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscspn-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -290,4 +290,4 @@ ENTRY(__wcscspn_vx) + .Lfallback: + jg __wcscspn_c + END(__wcscspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscspn.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcscspn.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcscspn.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcscspn, wcscspn) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcslen-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcslen-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcslen-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSLEN __wcslen_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcslen-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcslen-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcslen-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -88,4 +88,4 @@ ENTRY(__wcslen_vx) + .Lfallback: + jg __wcslen_c + END(__wcslen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcslen.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcslen.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcslen.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcslen, wcslen) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncat-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncat-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncat-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSNCAT __wcsncat_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncat-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncat-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncat-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -262,4 +262,4 @@ ENTRY(__wcsncat_vx) + .Lfallback: + jg __wcsncat_c + END(__wcsncat_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncat.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncat.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncat.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcsncat, wcsncat) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncmp-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncmp-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncmp-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSNCMP __wcsncmp_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncmp-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncmp-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncmp-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -174,4 +174,4 @@ ENTRY(__wcsncmp_vx) + locgrl %r2,%r1 + br %r14 + END(__wcsncmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncpy-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncpy-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncpy-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSNCPY __wcsncpy_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncpy-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncpy-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncpy-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -220,4 +220,4 @@ ENTRY(__wcsncpy_vx) + jg __wcsncpy_c + END(__wcsncpy_vx) + +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsncpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsncpy.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcsncpy, wcsncpy) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsnlen-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsnlen-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsnlen-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSNLEN __wcsnlen_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsnlen-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsnlen-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsnlen-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -148,4 +148,4 @@ ENTRY(__wcsnlen_vx) + .Lfallback: + jg __wcsnlen_c + END(__wcsnlen_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsnlen.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsnlen.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsnlen.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -25,4 +25,4 @@ weak_alias (__wcsnlen, wcsnlen) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcspbrk-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcspbrk-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcspbrk-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSPBRK __wcspbrk_c + + # include +@@ -28,4 +28,4 @@ extern __typeof (wcspbrk) __wcspbrk_c; + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcspbrk-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcspbrk-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcspbrk-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -312,4 +312,4 @@ ENTRY(__wcspbrk_vx) + .Lfallback: + jg __wcspbrk_c + END(__wcspbrk_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcspbrk.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcspbrk.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcspbrk.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcspbrk, wcspbrk) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsrchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsrchr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsrchr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSRCHR __wcsrchr_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsrchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsrchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsrchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -187,4 +187,4 @@ ENTRY(__wcsrchr_vx) + .Lfallback: + jg __wcsrchr_c + END(__wcsrchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsrchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsrchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsrchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsspn-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsspn-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsspn-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WCSSPN __wcsspn_c + + # include +@@ -28,4 +28,4 @@ extern __typeof (wcsspn) __wcsspn_c; + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsspn-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsspn-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsspn-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -267,4 +267,4 @@ ENTRY(__wcsspn_vx) + .Lfallback: + jg __wcsspn_c + END(__wcsspn_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsspn.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wcsspn.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wcsspn.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wcsspn, wcsspn) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemchr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemchr-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemchr-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WMEMCHR __wmemchr_c + + # include +@@ -28,4 +28,4 @@ extern __typeof (wmemchr) __wmemchr_c; + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemchr-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemchr-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemchr-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -163,4 +163,4 @@ ENTRY(__wmemchr_vx) + .Lfallback: + jg __wmemchr_c + END(__wmemchr_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemchr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemchr.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemchr.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wmemchr, wmemchr) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemcmp-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemcmp-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemcmp-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WMEMCMP __wmemcmp_c + + # include +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemcmp-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemcmp-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemcmp-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -146,4 +146,4 @@ ENTRY(__wmemcmp_vx) + la %r3,0(%r5,%r3) + j .Lremaining + END(__wmemcmp_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemcmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemcmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemcmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemset-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemset-c.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemset-c.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # define WMEMSET __wmemset_c + + # include +@@ -28,4 +28,4 @@ extern __typeof (wmemset) __wmemset_c; + # endif /* SHARED */ + + # include +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemset-vx.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemset-vx.S ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemset-vx.S +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + + # include "sysdep.h" + # include "asm-syntax.h" +@@ -139,4 +139,4 @@ ENTRY(__wmemset_vx) + srlg %r4,%r4,2 /* Convert byte-count to character-count. */ + jg __wmemset_c + END(__wmemset_vx) +-#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */ +Index: glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemset.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/multiarch/wmemset.c ++++ glibc-2.17-c758a686/sysdeps/s390/multiarch/wmemset.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) + # include + # include + +@@ -24,4 +24,4 @@ s390_vx_libc_ifunc2 (__wmemset, wmemset) + + #else + # include +-#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */ +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/multiarch/memcmp-s390.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +@@ -27,7 +27,7 @@ + + .text + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + ENTRY(__memcmp_z196) + .machine "z196" +@@ -92,11 +92,11 @@ ENTRY(__memcmp_z10) + clc 0(1,%r3),0(%r2) + END(__memcmp_z10) + +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ + + #include "../memcmp.S" + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl memcmp + .set memcmp,__memcmp_default + .weak bcmp +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/multiarch/memcmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + s390_libc_ifunc (memcmp) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/multiarch/memcpy-s390.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +@@ -27,7 +27,7 @@ + + .text + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + + ENTRY(__memcpy_z196) + .machine "z196" +@@ -88,11 +88,11 @@ ENTRY(__memcpy_z10) + mvc 0(1,%r1),0(%r3) + END(__memcpy_z10) + +-#endif /* SHARED && !defined NOT_IN_libc */ ++#endif /* SHARED && IS_IN (libc) */ + + #include "../memcpy.S" + +-#if !defined SHARED || defined NOT_IN_libc ++#if !defined SHARED || !IS_IN (libc) + .globl memcpy + .set memcpy,__memcpy_default + #endif +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/multiarch/memcpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memcpy.c +@@ -17,7 +17,7 @@ + . */ + + /* In the static lib memcpy is needed before the reloc is resolved. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # include + + s390_libc_ifunc (memcpy) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memset-s390.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/multiarch/memset-s390.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memset-s390.S +@@ -27,7 +27,7 @@ + + .text + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + ENTRY(__memset_z196) + .machine "z196" +@@ -103,11 +103,11 @@ ENTRY(__memset_mvcle) + br %r14 + END(__memset_mvcle) + +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ + + #include "../memset.S" + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl memset + .set memset,__memset_default + #endif +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memset.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/multiarch/memset.c ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/multiarch/memset.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + s390_libc_ifunc (memset) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +@@ -27,7 +27,7 @@ + + .text + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + ENTRY(__memcmp_z196) + .machine "z196" +@@ -89,11 +89,11 @@ ENTRY(__memcmp_z10) + clc 0(1,%r3),0(%r2) + END(__memcmp_z10) + +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ + + #include "../memcmp.S" + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl memcmp + .set memcmp,__memcmp_default + .weak bcmp +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/multiarch/memcmp.c ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcmp.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + s390_libc_ifunc (memcmp) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +@@ -27,7 +27,7 @@ + + .text + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + + ENTRY(__memcpy_z196) + .machine "z196" +@@ -84,11 +84,11 @@ ENTRY(__memcpy_z10) + mvc 0(1,%r1),0(%r3) + END(__memcpy_z10) + +-#endif /* SHARED && !defined NOT_IN_libc */ ++#endif /* SHARED && IS_IN (libc) */ + + #include "../memcpy.S" + +-#if !defined SHARED || defined NOT_IN_libc ++#if !defined SHARED || !IS_IN (libc) + .globl memcpy + .set memcpy,__memcpy_default + #endif +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcpy.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/multiarch/memcpy.c ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memcpy.c +@@ -17,7 +17,7 @@ + . */ + + /* In the static lib memcpy is needed before the reloc is resolved. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + # include + + s390_libc_ifunc (memcpy) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memset-s390x.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/multiarch/memset-s390x.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memset-s390x.S +@@ -27,7 +27,7 @@ + + .text + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + ENTRY(__memset_z196) + .machine "z196" +@@ -99,11 +99,11 @@ ENTRY(__memset_mvcle) + br %r14 + END(__memset_mvcle) + +-#endif /* !NOT_IN_libc */ ++#endif /* !IS_IN (libc) */ + + #include "../memset.S" + +-#ifdef NOT_IN_libc ++#if !IS_IN (libc) + .globl memset + .set memset,__memset_default + #endif +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memset.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/multiarch/memset.c ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/multiarch/memset.c +@@ -16,7 +16,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # include + + s390_libc_ifunc (memset) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset-x86-64.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset-x86-64.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset-x86-64.S +@@ -1,6 +1,6 @@ + #include + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + # undef ENTRY_CHK + # define ENTRY_CHK(name) \ + .type __memset_chk_x86_64, @function; \ +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rawmemchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/rawmemchr.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rawmemchr.S +@@ -23,7 +23,7 @@ + + + /* Define multiple versions only for the definition in lib. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + .text + ENTRY(rawmemchr) + .type rawmemchr, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen-sse2-no-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strlen-sse2-no-bsf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen-sse2-no-bsf.S +@@ -19,7 +19,7 @@ + + /* only for strlen case we don't use optimized version for STATIC build just for SHARED */ + +-#if (defined SHARED || defined USE_AS_STRCAT || defined USE_AS_STRNLEN) && !defined NOT_IN_libc ++#if (defined SHARED || defined USE_AS_STRCAT || defined USE_AS_STRNLEN) && IS_IN (libc) + + # ifndef USE_AS_STRCAT + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen-sse2-pminub.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strlen-sse2-pminub.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen-sse2-pminub.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if !defined NOT_IN_libc && (defined SHARED || defined USE_AS_STRCAT) ++#if IS_IN (libc) && (defined SHARED || defined USE_AS_STRCAT) + + # ifndef USE_AS_STRCAT + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen-sse4.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strlen-sse4.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen-sse4.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + + #include + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strlen.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen.S +@@ -25,7 +25,7 @@ + /* Define multiple versions only for the definition in libc and for + the DSO. In static binaries we need strlen before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + .text + ENTRY(strlen) + .type strlen, @gnu_indirect_function +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strnlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strnlen.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strnlen.S +@@ -22,7 +22,7 @@ + + + /* Define multiple versions only for the definition in libc. */ +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + + .text + ENTRY(__strnlen) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strrchr-sse2-no-bsf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strrchr-sse2-no-bsf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strrchr-sse2-no-bsf.S +@@ -17,7 +17,7 @@ + License along with the GNU C Library; if not, see + . */ + +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + + # include + # include "asm-syntax.h" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strrchr.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strrchr.S +@@ -24,7 +24,7 @@ + /* Define multiple versions only for the definition in libc and for + the DSO. In static binaries we need strrchr before the initialization + happened. */ +-#if defined SHARED && !defined NOT_IN_libc ++#if defined SHARED && IS_IN (libc) + .text + ENTRY(strrchr) + .type strrchr, @gnu_indirect_function +Index: glibc-2.17-c758a686/Makerules +=================================================================== +--- glibc-2.17-c758a686.orig/Makerules ++++ glibc-2.17-c758a686/Makerules +@@ -1156,9 +1156,6 @@ lib := nonlib + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + endif + +-# The include magic above causes those files to use this variable for flags. +-CPPFLAGS-nonlib = -DNOT_IN_libc=1 +- + + ifeq ($(versioning),yes) + # Generate normalized lists of symbols, versions, and data sizes. +Index: glibc-2.17-c758a686/include/ctype.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/ctype.h ++++ glibc-2.17-c758a686/include/ctype.h +@@ -7,7 +7,7 @@ libc_hidden_proto (__ctype_init) + + extern int __isctype (int __c, int __mask); + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + + /* These accessors are used by the optimized macros to find the + thread-local cache of ctype information from the current thread's +@@ -46,13 +46,13 @@ __ctype_tolower_loc (void) + return __libc_tsd_address (const int32_t *, CTYPE_TOLOWER); + } + +-# endif /* Not NOT_IN_libc. */ ++# endif /* IS_IN (libc) */ + #endif + + #include + + #ifndef _ISOMAC +-# if !defined __NO_CTYPE && !defined NOT_IN_libc ++# if !defined __NO_CTYPE && IS_IN (libc) + /* The spec says that isdigit must only match the decimal digits. We + can check this without a memory access. */ + # undef isdigit +Index: glibc-2.17-c758a686/include/libc-symbols.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/libc-symbols.h ++++ glibc-2.17-c758a686/include/libc-symbols.h +@@ -548,7 +548,7 @@ for linking") + # define hidden_nolink(name, lib, version) + #endif + +-#if !defined NOT_IN_libc ++#if IS_IN (libc) + # define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libc_hidden_def(name) hidden_def (name) + # define libc_hidden_weak(name) hidden_weak (name) +Index: glibc-2.17-c758a686/include/netdb.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/netdb.h ++++ glibc-2.17-c758a686/include/netdb.h +@@ -3,11 +3,11 @@ + + #ifndef _ISOMAC + /* Macros for accessing h_errno from inside libc. */ +-# if !defined NOT_IN_libc || IS_IN_LIB ++# if IS_IN_LIB + # undef h_errno + # ifdef _LIBC_REENTRANT + # include +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define h_errno __libc_h_errno + # else + # define h_errno h_errno /* For #ifndef h_errno tests. */ +@@ -16,7 +16,7 @@ extern __thread int h_errno attribute_tl + # else + extern int h_errno; + # endif /* _LIBC_REENTRANT */ +-# endif /* !NOT_IN_libc || IS_IN_LIB */ ++# endif /* IS_IN_LIB */ + # define __set_h_errno(x) (h_errno = (x)) + + libc_hidden_proto (hstrerror) +Index: glibc-2.17-c758a686/include/resolv.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/resolv.h ++++ glibc-2.17-c758a686/include/resolv.h +@@ -16,7 +16,7 @@ + # ifdef _LIBC_REENTRANT + # include + # undef _res +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # define __resp __libc_resp + # endif + # define _res (*__resp) +Index: glibc-2.17-c758a686/include/stdlib.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/stdlib.h ++++ glibc-2.17-c758a686/include/stdlib.h +@@ -216,7 +216,7 @@ extern int __qfcvt_r (long double __valu + int *__restrict __decpt, int *__restrict __sign, + char *__restrict __buf, size_t __len); + +-# ifndef NOT_IN_libc ++# if IS_IN (libc) + # undef MB_CUR_MAX + # define MB_CUR_MAX (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MB_CUR_MAX)) + +Index: glibc-2.17-c758a686/locale/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/locale/Makefile ++++ glibc-2.17-c758a686/locale/Makefile +@@ -88,13 +88,13 @@ CPPFLAGS-locale-programs = -DLOCALE_PATH + -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \ + -DREPERTOIREMAP_PATH='"$(i18ndir)/repertoiremaps"' \ + -DLOCSRCDIR='"$(i18ndir)/locales"' \ +- -DHAVE_CONFIG_H -DNOT_IN_libc ++ -DHAVE_CONFIG_H + + CFLAGS-charmap.c = -Wno-write-strings -Wno-char-subscripts + CFLAGS-locfile.c = -Wno-write-strings -Wno-char-subscripts + CFLAGS-charmap-dir.c = -Wno-write-strings + +-# This makes sure -DNOT_IN_libc et al are passed for all these modules. ++# Set libof-* for each routine. + cpp-srcs-left := $(localedef-modules) $(localedef-aux) $(locale-modules) \ + $(lib-modules) + lib := locale-programs +Index: glibc-2.17-c758a686/nss/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nss/Makefile ++++ glibc-2.17-c758a686/nss/Makefile +@@ -109,7 +109,6 @@ $(inst_vardbdir)/Makefile: db-Makefile $ + $(do-install) + + libof-nss_test1 = extramodules +-CPPFLAGS-nss_test1 = -DNOT_IN_libc=1 + $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(common-objpfx)libc.so \ + $(common-objpfx)libc_nonshared.a + $(build-module) +Index: glibc-2.17-c758a686/resolv/res_hconf.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/res_hconf.c ++++ glibc-2.17-c758a686/resolv/res_hconf.c +@@ -359,7 +359,7 @@ _res_hconf_init (void) + } + + +-#ifndef NOT_IN_libc ++#if IS_IN (libc) + /* List of known interfaces. */ + libc_freeres_ptr ( + static struct netaddr +Index: glibc-2.17-c758a686/stdlib/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/stdlib/Makefile ++++ glibc-2.17-c758a686/stdlib/Makefile +@@ -139,7 +139,6 @@ LDFLAGS-tst-putenv = $(no-as-needed) + $(objpfx)tst-putenvmod.so: $(objpfx)tst-putenvmod.os + $(build-module) + libof-tst-putenvmod = extramodules +-CFLAGS-tst-putenvmod.c = -DNOT_IN_libc=1 + + ifeq ($(build-shared),yes) + link-libm = $(common-objpfx)math/libm.so +Index: glibc-2.17-c758a686/sysdeps/gnu/errlist.awk +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/gnu/errlist.awk ++++ glibc-2.17-c758a686/sysdeps/gnu/errlist.awk +@@ -109,7 +109,7 @@ END { + print " (sizeof _sys_errlist_internal / sizeof _sys_errlist_internal [0])"; + print "const int _sys_nerr_internal = NERR;" + print ""; +- print "#if !defined NOT_IN_libc && !ERRLIST_NO_COMPAT"; ++ print "#if IS_IN (libc) && !ERRLIST_NO_COMPAT"; + print "# include "; + print "#endif"; + print ""; +Index: glibc-2.17-c758a686/sysdeps/gnu/errlist.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/gnu/errlist.c ++++ glibc-2.17-c758a686/sysdeps/gnu/errlist.c +@@ -1479,7 +1479,7 @@ TRANS error; @pxref{Cancel AIO Operation + (sizeof _sys_errlist_internal / sizeof _sys_errlist_internal [0]) + const int _sys_nerr_internal = NERR; + +-#if !defined NOT_IN_libc && !ERRLIST_NO_COMPAT ++#if IS_IN (libc) && !ERRLIST_NO_COMPAT + # include + #endif + +Index: glibc-2.17-c758a686/sysdeps/i386/i586/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i586/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i586/memcpy.S +@@ -34,7 +34,7 @@ + #define LEN SRC+PTR_SIZE + + .text +-#if defined PIC && !defined NOT_IN_libc ++#if defined PIC && IS_IN (libc) + ENTRY (__memcpy_chk) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/memcpy.S +@@ -30,7 +30,7 @@ + #define LEN SRC+PTR_SIZE + + .text +-#if defined PIC && !defined NOT_IN_libc ++#if defined PIC && IS_IN (libc) + ENTRY_CHK (__memcpy_chk) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/memmove.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/memmove.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/memmove.S +@@ -37,7 +37,7 @@ + # define SRC DEST+PTR_SIZE + # define LEN SRC+PTR_SIZE + +-# if defined PIC && !defined NOT_IN_libc ++# if defined PIC && IS_IN (libc) + ENTRY_CHK (__memmove_chk) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/mempcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/mempcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/mempcpy.S +@@ -30,7 +30,7 @@ + #define LEN SRC+PTR_SIZE + + .text +-#if defined PIC && !defined NOT_IN_libc ++#if defined PIC && IS_IN (libc) + ENTRY_CHK (__mempcpy_chk) + movl 12(%esp), %eax + cmpl %eax, 16(%esp) diff --git a/SOURCES/glibc-rh1256317-20.patch b/SOURCES/glibc-rh1256317-20.patch new file mode 100644 index 00000000..2a621dcf --- /dev/null +++ b/SOURCES/glibc-rh1256317-20.patch @@ -0,0 +1,54 @@ +commit 318c7a5846bbfaab567c92b37941000dfc0c00c0 +Author: Siddhesh Poyarekar +Date: Thu Aug 21 10:27:13 2014 +0530 + + Remove redundant CPPFLAGS for some programs + + These programs get the NOT_IN_libc twice, once through the 'other' + target and another explicitly. Remove the explicitly added CPFLAG. + + * catgets/Makefile (CPPFLAGS-gencat): Remove. + * iconv/Makefile (CPPFLAGS-iconv_prog): Likewise. + (CPPFLAGS-iconvconfig): Likewise. + * timezone/Makefile (CPPFLAGS-zic): Likewise. + +Index: glibc-2.17-c758a686/catgets/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/catgets/Makefile ++++ glibc-2.17-c758a686/catgets/Makefile +@@ -42,8 +42,6 @@ $(objpfx)gencat: $(gencat-modules:%=$(ob + catgets-CPPFLAGS := -DNLSPATH='"$(msgcatdir)/%L/%N:$(msgcatdir)/%L/LC_MESSAGES/%N:$(msgcatdir)/%l/%N:$(msgcatdir)/%l/LC_MESSAGES/%N:"' \ + -DHAVE_CONFIG_H + +-CPPFLAGS-gencat = -DNOT_IN_libc +- + generated = de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \ + test-gencat.h + generated-dirs = de +Index: glibc-2.17-c758a686/iconv/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/iconv/Makefile ++++ glibc-2.17-c758a686/iconv/Makefile +@@ -53,9 +53,7 @@ CFLAGS-gconv_cache.c += -DGCONV_DIR='"$( + CFLAGS-gconv_conf.c = -DGCONV_PATH='"$(gconvdir)"' + CFLAGS-iconvconfig.c = -DGCONV_PATH='"$(gconvdir)"' -DGCONV_DIR='"$(gconvdir)"' + +-CPPFLAGS-iconv_prog = -DNOT_IN_libc + CPPFLAGS-iconv_charmap = -DNOT_IN_libc +-CPPFLAGS-iconvconfig = -DNOT_IN_libc + CPPFLAGS-linereader = -DNOT_IN_libc + CPPFLAGS-strtab = -DNOT_IN_libc + CPPFLAGS-charmap = -DNOT_IN_libc +Index: glibc-2.17-c758a686/timezone/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/timezone/Makefile ++++ glibc-2.17-c758a686/timezone/Makefile +@@ -42,8 +42,6 @@ all: # Make this the default target; it + + include ../Makeconfig # Get objpfx defined so we can use it below. + +-CPPFLAGS-zic = -DNOT_IN_libc +- + ifeq ($(have-ksh),yes) + install-bin-script = tzselect + generated += tzselect diff --git a/SOURCES/glibc-rh1256317-21.patch b/SOURCES/glibc-rh1256317-21.patch new file mode 100644 index 00000000..17b45fe6 --- /dev/null +++ b/SOURCES/glibc-rh1256317-21.patch @@ -0,0 +1,509 @@ +commit eb72478a286e0104f5636d21d86407b4c0e89fa1 +Author: Siddhesh Poyarekar +Date: Thu Aug 21 10:26:46 2014 +0530 + + Remove unnecessary uses of NOT_IN_libc + + If a IS_IN_* macro is defined, then NOT_IN_libc is always defined, + except obviously for IS_IN_libc. There's no need to check for both. + Verified on x86_64 and i686 that the source is unchanged. + + * include/libc-symbols.h: Remove unnecessary check for + NOT_IN_libc. + * nptl/pthreadP.h: Likewise. + * sysdeps/aarch64/setjmp.S: Likewise. + * sysdeps/alpha/setjmp.S: Likewise. + * sysdeps/arm/sysdep.h: Likewise. + * sysdeps/i386/setjmp.S: Likewise. + * sysdeps/m68k/setjmp.c: Likewise. + * sysdeps/posix/getcwd.c: Likewise. + * sysdeps/powerpc/powerpc32/setjmp-common.S: Likewise. + * sysdeps/powerpc/powerpc64/setjmp-common.S: Likewise. + * sysdeps/s390/s390-32/setjmp.S: Likewise. + * sysdeps/s390/s390-64/setjmp.S: Likewise. + * sysdeps/sh/sh3/setjmp.S: Likewise. + * sysdeps/sh/sh4/setjmp.S: Likewise. + * sysdeps/unix/alpha/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/setjmp.S: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. + * sysdeps/x86_64/setjmp.S: Likewise. +Index: glibc-2.17-c758a686/include/libc-symbols.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/libc-symbols.h ++++ glibc-2.17-c758a686/include/libc-symbols.h +@@ -561,7 +561,7 @@ for linking") + # define libc_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + # define rtld_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define rtld_hidden_def(name) hidden_def (name) + # define rtld_hidden_weak(name) hidden_weak (name) +@@ -579,7 +579,7 @@ for linking") + # define rtld_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libm ++#ifdef IS_IN_libm + # define libm_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libm_hidden_def(name) hidden_def (name) + # define libm_hidden_weak(name) hidden_weak (name) +@@ -597,7 +597,7 @@ for linking") + # define libm_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libresolv ++#ifdef IS_IN_libresolv + # define libresolv_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libresolv_hidden_def(name) hidden_def (name) + # define libresolv_hidden_weak(name) hidden_weak (name) +@@ -615,7 +615,7 @@ for linking") + # define libresolv_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_librt ++#ifdef IS_IN_librt + # define librt_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define librt_hidden_def(name) hidden_def (name) + # define librt_hidden_weak(name) hidden_weak (name) +@@ -633,7 +633,7 @@ for linking") + # define librt_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libdl ++#ifdef IS_IN_libdl + # define libdl_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libdl_hidden_def(name) hidden_def (name) + # define libdl_hidden_weak(name) hidden_weak (name) +@@ -651,7 +651,7 @@ for linking") + # define libdl_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libnss_files ++#ifdef IS_IN_libnss_files + # define libnss_files_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libnss_files_hidden_def(name) hidden_def (name) + # define libnss_files_hidden_weak(name) hidden_weak (name) +@@ -669,7 +669,7 @@ for linking") + # define libnss_files_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libnsl ++#ifdef IS_IN_libnsl + # define libnsl_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libnsl_hidden_def(name) hidden_def (name) + # define libnsl_hidden_weak(name) hidden_weak (name) +@@ -687,7 +687,7 @@ for linking") + # define libnsl_hidden_data_ver(local, name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libnss_nisplus ++#ifdef IS_IN_libnss_nisplus + # define libnss_nisplus_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libnss_nisplus_hidden_def(name) hidden_def (name) + # define libnss_nisplus_hidden_weak(name) hidden_weak (name) +@@ -713,7 +713,7 @@ for linking") + # define HIDDEN_BUILTIN_JUMPTARGET(name) HIDDEN_JUMPTARGET(name) + #endif + +-#if defined NOT_IN_libc && defined IS_IN_libutil ++#ifdef IS_IN_libutil + # define libutil_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) + # define libutil_hidden_def(name) hidden_def (name) + # define libutil_hidden_weak(name) hidden_weak (name) +Index: glibc-2.17-c758a686/nptl/pthreadP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthreadP.h ++++ glibc-2.17-c758a686/nptl/pthreadP.h +@@ -239,7 +239,7 @@ extern void __pthread_register_cancel (_ + __cleanup_fct_attribute; + extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf) + __cleanup_fct_attribute; +-#if defined NOT_IN_libc && defined IS_IN_libpthread ++#ifdef IS_IN_libpthread + hidden_proto (__pthread_unwind) + hidden_proto (__pthread_unwind_next) + hidden_proto (__pthread_register_cancel) +@@ -283,13 +283,13 @@ __do_cancel (void) + # define LIBC_CANCEL_HANDLED() \ + __asm (".globl " __SYMBOL_PREFIX "__libc_enable_asynccancel"); \ + __asm (".globl " __SYMBOL_PREFIX "__libc_disable_asynccancel") +-#elif defined NOT_IN_libc && defined IS_IN_libpthread ++#elif defined IS_IN_libpthread + # define LIBC_CANCEL_ASYNC() CANCEL_ASYNC () + # define LIBC_CANCEL_RESET(val) CANCEL_RESET (val) + # define LIBC_CANCEL_HANDLED() \ + __asm (".globl " __SYMBOL_PREFIX "__pthread_enable_asynccancel"); \ + __asm (".globl " __SYMBOL_PREFIX "__pthread_disable_asynccancel") +-#elif defined NOT_IN_libc && defined IS_IN_librt ++#elif defined IS_IN_librt + # define LIBC_CANCEL_ASYNC() \ + __librt_enable_asynccancel () + # define LIBC_CANCEL_RESET(val) \ +@@ -344,7 +344,7 @@ extern int __make_stacks_executable (voi + + /* longjmp handling. */ + extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe); +-#if defined NOT_IN_libc && defined IS_IN_libpthread ++#ifdef IS_IN_libpthread + hidden_proto (__pthread_cleanup_upto) + #endif + +@@ -489,7 +489,7 @@ extern int __pthread_enable_asynccancel + extern void __pthread_disable_asynccancel (int oldtype) + internal_function attribute_hidden; + +-#if defined NOT_IN_libc && defined IS_IN_libpthread ++#ifdef IS_IN_libpthread + hidden_proto (__pthread_mutex_init) + hidden_proto (__pthread_mutex_destroy) + hidden_proto (__pthread_mutex_lock) +Index: glibc-2.17-c758a686/sysdeps/posix/getcwd.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/getcwd.c ++++ glibc-2.17-c758a686/sysdeps/posix/getcwd.c +@@ -206,7 +206,7 @@ extern char *alloca (); + + #ifdef __ASSUME_ATFCTS + # define __have_atfcts 1 +-#elif defined NOT_IN_libc && defined IS_IN_rtld ++#elif defined IS_IN_rtld + static int __rtld_have_atfcts; + # define __have_atfcts __rtld_have_atfcts + #endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +@@ -212,7 +212,7 @@ L(no_vmx): + #else + li r6,0 + #endif +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + li r3,0 + blr + #elif defined SHARED +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/setjmp.S +@@ -57,7 +57,7 @@ ENTRY(__sigsetjmp) + #endif + std %f4,40(%r2) + std %f6,48(%r2) +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + lhi %r2,0 + br %r14 +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S +@@ -63,7 +63,7 @@ ENTRY(__sigsetjmp) + std %f13,120(%r2) + std %f14,128(%r2) + std %f15,136(%r2) +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + lghi %r2,0 + br %r14 +Index: glibc-2.17-c758a686/sysdeps/sh/sh3/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sh/sh3/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/sh/sh3/setjmp.S +@@ -46,7 +46,7 @@ ENTRY (__sigsetjmp) + mov.l r9, @-r4 + mov.l r8, @-r4 + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + rts + mov #0, r0 +Index: glibc-2.17-c758a686/sysdeps/sh/sh4/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sh/sh4/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/sh/sh4/setjmp.S +@@ -55,7 +55,7 @@ ENTRY (__sigsetjmp) + mov.l r9, @-r4 + mov.l r8, @-r4 + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + rts + mov #0, r0 +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -521,7 +521,7 @@ asm (".L__X'%ebx = 1\n\t" + + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. Using a global variable + is too complicated here since we have no PC-relative addressing mode. */ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +@@ -272,7 +272,7 @@ + + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +@@ -282,7 +282,7 @@ + + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +@@ -367,7 +367,7 @@ + _ret; }) + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +@@ -373,7 +373,7 @@ + _ret; }) + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sh/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sh/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sh/sysdep.h +@@ -338,7 +338,7 @@ + #endif /* __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. Using a global variable + is too complicated here since we have no PC-relative addressing mode. */ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +@@ -126,7 +126,7 @@ ENTRY(name); \ + #endif /* __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +@@ -141,7 +141,7 @@ ENTRY(name); \ + #define STACK_BIAS 2047 + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/x86_64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/sysdep.h +@@ -395,7 +395,7 @@ + + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + # ifdef __ASSEMBLER__ +Index: glibc-2.17-c758a686/sysdeps/x86_64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/setjmp.S +@@ -54,7 +54,7 @@ ENTRY (__sigsetjmp) + #endif + movq %rax, (JB_PC*8)(%rdi) + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + xorl %eax, %eax + retq +Index: glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/aarch64/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +@@ -58,7 +58,7 @@ ENTRY (__sigsetjmp) + mov x2, sp + str x2, [x0, #JB_SP<<3] + #endif +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask */ + mov w0, #0 + RET +Index: glibc-2.17-c758a686/ports/sysdeps/alpha/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/alpha/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/alpha/setjmp.S +@@ -86,7 +86,7 @@ $sigsetjmp_local: + ldq ra, 0(sp) + addq sp, 16, sp + ret +-#elif defined NOT_IN_libc && defined IS_IN_rtld ++#elif defined IS_IN_rtld + /* In ld.so we never save the signal mask. */ + mov 0, v0 + ret +Index: glibc-2.17-c758a686/ports/sysdeps/m68k/setjmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/m68k/setjmp.c ++++ glibc-2.17-c758a686/ports/sysdeps/m68k/setjmp.c +@@ -57,7 +57,7 @@ __sigsetjmp (jmp_buf env, int savemask) + : : "m" (env[0].__jmpbuf[0].__fpregs[0])); + #endif + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + return 0; + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/alpha/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/alpha/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/alpha/sysdep.h +@@ -346,7 +346,7 @@ __LABEL(name) \ + + #include + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + # ifdef __ASSEMBLER__ + # define PTR_MANGLE(dst, src, tmp) \ + ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \ +Index: glibc-2.17-c758a686/sysdeps/i386/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/setjmp.S +@@ -51,7 +51,7 @@ ENTRY (BP_SYM (__sigsetjmp)) + LEAVE /* pop frame pointer to prepare for tail-call. */ + movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */ + +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + xorl %eax, %eax + ret +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/setjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp-common.S +@@ -64,7 +64,7 @@ ENTRY (BP_SYM (__sigsetjmp)) + stw r29,((JB_GPRS+15)*4)(3) + stw r30,((JB_GPRS+16)*4)(3) + stw r31,((JB_GPRS+17)*4)(3) +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + li r3,0 + blr + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -324,8 +324,9 @@ + #endif /* __ASSEMBLER__ */ + + /* Pointer mangling is supported for AArch64. */ +-#if (defined NOT_IN_libc && defined IS_IN_rtld) || \ +- (!defined SHARED && (!defined NOT_IN_libc || defined IS_IN_libpthread)) ++#if (defined IS_IN_rtld) || \ ++ (!defined SHARED && (!defined NOT_IN_libc \ ++ || defined IS_IN_libpthread)) + # ifdef __ASSEMBLER__ + # define PTR_MANGLE(dst, src, guard, tmp) \ + LDST_PCREL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/setjmp.S +@@ -179,7 +179,7 @@ ENTRY(__sigsetjmp) + ;; + st8.nta [r2]=r25 // ar.unat + st8.nta [r3]=in0 // &__jmp_buf +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* In ld.so we never save the signal mask. */ + ;; + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +@@ -62,7 +62,7 @@ + + #if defined USE_DL_SYSINFO \ + && (!defined NOT_IN_libc \ +- || defined IS_IN_libpthread || defined IS_IN_librt) ++ || IS_IN (libpthread) || defined IS_IN_librt) + # define IA64_USE_NEW_STUB + #else + # undef IA64_USE_NEW_STUB +@@ -361,7 +361,7 @@ + #endif /* not __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#ifdef IS_IN_rtld + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else diff --git a/SOURCES/glibc-rh1256317-3.patch b/SOURCES/glibc-rh1256317-3.patch new file mode 100644 index 00000000..640bcbbb --- /dev/null +++ b/SOURCES/glibc-rh1256317-3.patch @@ -0,0 +1,24 @@ +commit 76ca86a506a81d8a08655fb331162926569a47d6 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 21:24:22 2014 +0530 + + Remove last place for definition of IS_IN_* macros + + Ignoring IS_IN_build, which has a different purpose altogether, this + patch removes the last bit of IS_IN_* macro definitions. Now barring + NOT_IN_libc, all cases use the IN_MODULE scheme. + + Generated code unchanged on x86_64. + + * extra-lib.mk (CPPFLAGS-$(lib)): Remove IS_IN_$(lib). + +Index: glibc-2.17-c758a686/extra-lib.mk +=================================================================== +--- glibc-2.17-c758a686.orig/extra-lib.mk ++++ glibc-2.17-c758a686/extra-lib.mk +@@ -101,4 +101,4 @@ ifneq (,$(cpp-srcs-left)) + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + endif + +-CPPFLAGS-$(lib) := -DNOT_IN_libc=1 -DIS_IN_$(lib)=1 ++CPPFLAGS-$(lib) := -DNOT_IN_libc=1 diff --git a/SOURCES/glibc-rh1256317-4.patch b/SOURCES/glibc-rh1256317-4.patch new file mode 100644 index 00000000..eab03528 --- /dev/null +++ b/SOURCES/glibc-rh1256317-4.patch @@ -0,0 +1,1239 @@ +commit a38484851aa244e1d5c48405f0e26fe93fa8d3b5 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 21:09:43 2014 +0530 + + Remove IS_IN_rtld + + Replace with IS_IN (rtld). Generated code is unchanged on + x86_64. + + * elf/Makefile (CPPFLAGS-.os): Remove IS_IN_rtld. + * elf/dl-open.c: Use IS_IN (rtld) instead if IS_IN_rtld. + * elf/rtld-Rules: Likewise. + * elf/setup-vdso.h: Likewise. + * include/assert.h: Likewise. + * include/bits/stdlib-float.h: Likewise. + * include/errno.h: Likewise. + * include/sys/stat.h: Likewise. + * include/unistd.h: Likewise. + * sysdeps/aarch64/setjmp.S: Likewise. + * sysdeps/alpha/setjmp.S: Likewise. + * sysdeps/arm/__longjmp.S: Likewise. + * sysdeps/arm/aeabi_unwind_cpp_pr1.c: Likewise. + * sysdeps/arm/setjmp.S: Likewise. + * sysdeps/arm/sysdep.h: Likewise. + * sysdeps/generic/_itoa.h: Likewise. + * sysdeps/generic/dl-sysdep.h: Likewise. + * sysdeps/generic/ldsodefs.h: Likewise. + * sysdeps/i386/dl-tls.h: Likewise. + * sysdeps/i386/setjmp.S: Likewise. + * sysdeps/m68k/setjmp.c: Likewise. + * sysdeps/mach/hurd/dl-execstack.c: Likewise. + * sysdeps/mach/hurd/opendir.c: Likewise. + * sysdeps/posix/getcwd.c: Likewise. + * sysdeps/posix/opendir.c: Likewise. + * sysdeps/posix/profil.c: Likewise. + * sysdeps/powerpc/dl-procinfo.h: Likewise. + * sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/setjmp-common.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h: Likewise. + * sysdeps/powerpc/powerpc32/setjmp-common.S: Likewise. + * sysdeps/powerpc/powerpc64/__longjmp-common.S: Likewise. + * sysdeps/powerpc/powerpc64/setjmp-common.S: Likewise. + * sysdeps/s390/dl-tls.h: Likewise. + * sysdeps/s390/s390-32/setjmp.S: Likewise. + * sysdeps/s390/s390-64/setjmp.S: Likewise. + * sysdeps/sh/sh3/setjmp.S: Likewise. + * sysdeps/sh/sh4/setjmp.S: Likewise. + * sysdeps/unix/alpha/sysdep.h: Likewise. + * sysdeps/unix/arm/sysdep.S: Likewise. + * sysdeps/unix/i386/sysdep.S: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/getcwd.c: Likewise. + * sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/setjmp.S: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/lowlevellock-futex.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/m68k-helpers.S: Likewise. + * sysdeps/unix/sysv/linux/microblaze/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/tile/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Likewise. + * sysdeps/unix/x86_64/sysdep.S: Likewise. + * sysdeps/x86_64/setjmp.S: Likewise. + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -444,7 +444,7 @@ CFLAGS-cache.c = $(SYSCONF-FLAGS) + CFLAGS-rtld.c = $(SYSCONF-FLAGS) + + CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\ +- -DNOT_IN_libc=1 -DIS_IN_rtld=1) ++ -DNOT_IN_libc=1) + + # Disable any optimization which might result in function calls during early + # dynamic loader startup. We disable -ftree-loop-distribute-patterns which +Index: glibc-2.17-c758a686/elf/dl-open.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/dl-open.c ++++ glibc-2.17-c758a686/elf/dl-open.c +@@ -741,7 +741,7 @@ _dl_show_scope (struct link_map *l, int + _dl_debug_printf ("\n"); + } + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* Return non-zero if ADDR lies within one of L's segments. */ + int + internal_function +Index: glibc-2.17-c758a686/elf/rtld-Rules +=================================================================== +--- glibc-2.17-c758a686.orig/elf/rtld-Rules ++++ glibc-2.17-c758a686/elf/rtld-Rules +@@ -134,6 +134,6 @@ lib := rtld + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) + + # This here is the whole point of all the shenanigans. +-rtld-CPPFLAGS := -DNOT_IN_libc=1 -DIS_IN_rtld=1 ++rtld-CPPFLAGS := -DNOT_IN_libc=1 + + endif +Index: glibc-2.17-c758a686/elf/setup-vdso.h +=================================================================== +--- glibc-2.17-c758a686.orig/elf/setup-vdso.h ++++ glibc-2.17-c758a686/elf/setup-vdso.h +@@ -101,7 +101,7 @@ setup_vdso (struct link_map *main_map __ + /* Add the vDSO to the object list. */ + _dl_add_to_namespace_list (l, LM_ID_BASE); + +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* Rearrange the list so this DSO appears after rtld_map. */ + assert (l->l_next == NULL); + assert (l->l_prev == main_map); +Index: glibc-2.17-c758a686/include/assert.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/assert.h ++++ glibc-2.17-c758a686/include/assert.h +@@ -20,7 +20,7 @@ extern void __assert_fail_base (const ch + const char *function) + __THROW __attribute__ ((__noreturn__)); + +-# if !defined NOT_IN_libc || defined IS_IN_rtld ++# if !defined NOT_IN_libc || IS_IN (rtld) + hidden_proto (__assert_fail) + hidden_proto (__assert_perror_fail) + # endif +Index: glibc-2.17-c758a686/include/bits/stdlib-float.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/bits/stdlib-float.h ++++ glibc-2.17-c758a686/include/bits/stdlib-float.h +@@ -1,4 +1,4 @@ + /* No floating-point inline functions in rtld. */ +-#ifndef IS_IN_rtld ++#if !IS_IN (rtld) + # include + #endif +Index: glibc-2.17-c758a686/include/errno.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/errno.h ++++ glibc-2.17-c758a686/include/errno.h +@@ -4,7 +4,7 @@ + + #if defined _ERRNO_H && !defined _ISOMAC && !defined __cplusplus + +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + # include + # endif + +Index: glibc-2.17-c758a686/include/sys/stat.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/sys/stat.h ++++ glibc-2.17-c758a686/include/sys/stat.h +@@ -12,7 +12,7 @@ extern __mode_t __umask (__mode_t __mask + extern int __mkdir (const char *__path, __mode_t __mode); + extern int __mknod (const char *__path, + __mode_t __mode, __dev_t __dev); +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + hidden_proto (__fxstat) + hidden_proto (__fxstat64) + hidden_proto (__lxstat) +Index: glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/aarch64/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/setjmp.S +@@ -58,7 +58,7 @@ ENTRY (__sigsetjmp) + mov x2, sp + str x2, [x0, #JB_SP<<3] + #endif +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask */ + mov w0, #0 + RET +Index: glibc-2.17-c758a686/ports/sysdeps/alpha/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/alpha/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/alpha/setjmp.S +@@ -86,7 +86,7 @@ $sigsetjmp_local: + ldq ra, 0(sp) + addq sp, 16, sp + ret +-#elif defined IS_IN_rtld ++#elif IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + mov 0, v0 + ret +Index: glibc-2.17-c758a686/ports/sysdeps/arm/__longjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/__longjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/arm/__longjmp.S +@@ -52,7 +52,7 @@ ENTRY (__longjmp) + #endif + + #ifdef NEED_HWCAP +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + ldr a2, 1f + ldr a3, .Lrtld_local_ro + 0: add a2, pc, a2 +@@ -104,7 +104,7 @@ ENTRY (__longjmp) + DO_RET(lr) + + #ifdef NEED_HWCAP +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 + .Lrtld_local_ro: + .long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF) +Index: glibc-2.17-c758a686/ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c ++++ glibc-2.17-c758a686/ports/sysdeps/arm/aeabi_unwind_cpp_pr1.c +@@ -27,7 +27,7 @@ attribute_hidden + void + __aeabi_unwind_cpp_pr0 (void) + { +-#ifndef IS_IN_rtld ++#if !IS_IN (rtld) + abort (); + #endif + } +@@ -36,7 +36,7 @@ attribute_hidden + void + __aeabi_unwind_cpp_pr1 (void) + { +-#ifndef IS_IN_rtld ++#if !IS_IN (rtld) + abort (); + #endif + } +@@ -45,7 +45,7 @@ attribute_hidden + void + __aeabi_unwind_cpp_pr2 (void) + { +-#ifndef IS_IN_rtld ++#if !IS_IN (rtld) + abort (); + #endif + } +Index: glibc-2.17-c758a686/ports/sysdeps/arm/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/arm/setjmp.S +@@ -35,7 +35,7 @@ ENTRY (__sigsetjmp) + + #ifdef NEED_HWCAP + /* Check if we have a VFP unit. */ +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + ldr a3, 1f + ldr a4, .Lrtld_local_ro + 0: add a3, pc, a3 +@@ -90,7 +90,7 @@ ENTRY (__sigsetjmp) + B PLTJMP(C_SYMBOL_NAME(__sigjmp_save)) + + #ifdef NEED_HWCAP +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 + .Lrtld_local_ro: + .long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF) +Index: glibc-2.17-c758a686/sysdeps/generic/_itoa.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/generic/_itoa.h ++++ glibc-2.17-c758a686/sysdeps/generic/_itoa.h +@@ -46,7 +46,7 @@ extern char *_itoa (unsigned long long i + + extern const char _itoa_upper_digits[]; + extern const char _itoa_lower_digits[]; +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + hidden_proto (_itoa_upper_digits) + hidden_proto (_itoa_lower_digits) + #endif +Index: glibc-2.17-c758a686/sysdeps/generic/dl-sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/generic/dl-sysdep.h ++++ glibc-2.17-c758a686/sysdeps/generic/dl-sysdep.h +@@ -27,7 +27,7 @@ + all the libc functions that ld.so uses are called without PLT and always + get the versions linked into ld.so rather than the libc ones. */ + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # define RTLD_PRIVATE_ERRNO 1 + #else + # define RTLD_PRIVATE_ERRNO 0 +Index: glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/generic/ldsodefs.h ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +@@ -246,7 +246,7 @@ typedef void (*receiver_fct) (int, const + # define GL(name) _##name + #else + # define EXTERN +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + # define GL(name) _rtld_local._##name + # else + # define GL(name) _rtld_global._##name +@@ -415,7 +415,7 @@ struct rtld_global + #ifdef SHARED + }; + # define __rtld_global_attribute__ +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + # ifdef HAVE_SDATA_SECTION + # define __rtld_local_attribute__ \ + __attribute__ ((visibility ("hidden"), section (".sdata"))) +@@ -434,7 +434,7 @@ extern struct rtld_global _rtld_global _ + #ifndef SHARED + # define GLRO(name) _##name + #else +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + # define GLRO(name) _rtld_local_ro._##name + # else + # define GLRO(name) _rtld_global_ro._##name +@@ -593,7 +593,7 @@ struct rtld_global_ro + EXTERN int _dl_pointer_guard; + }; + # define __rtld_global_attribute__ +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + # define __rtld_local_attribute__ __attribute__ ((visibility ("hidden"))) + extern struct rtld_global_ro _rtld_local_ro + attribute_relro __rtld_local_attribute__; +@@ -610,7 +610,7 @@ extern const struct rtld_global_ro _rtld + #endif + #undef EXTERN + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* This is the initial value of GL(dl_error_catch_tsd). + A non-TLS libpthread will change it. */ + extern void **_dl_initial_error_catch_tsd (void) __attribute__ ((const)) +@@ -641,7 +641,7 @@ extern char **_dl_argv + attribute_relro + #endif + ; +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + extern char **_dl_argv_internal attribute_hidden + # ifndef DL_ARGV_NOT_RELRO + attribute_relro +@@ -655,7 +655,7 @@ extern char **_dl_argv_internal attribut + /* Flag set at startup and cleared when the last initializer has run. */ + extern int _dl_starting_up; + weak_extern (_dl_starting_up) +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + extern int _dl_starting_up_internal attribute_hidden; + #endif + +Index: glibc-2.17-c758a686/sysdeps/i386/dl-tls.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/dl-tls.h ++++ glibc-2.17-c758a686/sysdeps/i386/dl-tls.h +@@ -32,7 +32,7 @@ extern void *___tls_get_addr (tls_index + extern void *___tls_get_addr_internal (tls_index *ti) + __attribute__ ((__regparm__ (1))) attribute_hidden; + +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* The special thing about the x86 TLS ABI is that we have two + variants of the __tls_get_addr function with different calling + conventions. The GNU version, which we are mostly concerned here, +Index: glibc-2.17-c758a686/sysdeps/i386/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/setjmp.S +@@ -51,7 +51,7 @@ ENTRY (BP_SYM (__sigsetjmp)) + LEAVE /* pop frame pointer to prepare for tail-call. */ + movl %ebp, (JB_BP*4)(%eax) /* Save caller's frame pointer. */ + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + xorl %eax, %eax + ret +Index: glibc-2.17-c758a686/ports/sysdeps/m68k/setjmp.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/m68k/setjmp.c ++++ glibc-2.17-c758a686/ports/sysdeps/m68k/setjmp.c +@@ -57,7 +57,7 @@ __sigsetjmp (jmp_buf env, int savemask) + : : "m" (env[0].__jmpbuf[0].__fpregs[0])); + #endif + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + return 0; + #else +Index: glibc-2.17-c758a686/sysdeps/mach/hurd/dl-execstack.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/mach/hurd/dl-execstack.c ++++ glibc-2.17-c758a686/sysdeps/mach/hurd/dl-execstack.c +@@ -34,7 +34,7 @@ _dl_make_stack_executable (void **stack_ + return EPERM; + *stack_endp = NULL; + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + if (__mprotect ((void *)_dl_hurd_data->stack_base, _dl_hurd_data->stack_size, + PROT_READ|PROT_WRITE|PROT_EXEC) != 0) + return errno; +Index: glibc-2.17-c758a686/sysdeps/mach/hurd/opendir.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/mach/hurd/opendir.c ++++ glibc-2.17-c758a686/sysdeps/mach/hurd/opendir.c +@@ -82,7 +82,7 @@ __opendirat (int dfd, const char *name) + + int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC; + int fd; +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + assert (dfd == AT_FDCWD); + fd = open_not_cancel_2 (name, flags); + #else +Index: glibc-2.17-c758a686/sysdeps/posix/getcwd.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/getcwd.c ++++ glibc-2.17-c758a686/sysdeps/posix/getcwd.c +@@ -206,7 +206,7 @@ extern char *alloca (); + + #ifdef __ASSUME_ATFCTS + # define __have_atfcts 1 +-#elif defined IS_IN_rtld ++#elif IS_IN (rtld) + static int __rtld_have_atfcts; + # define __have_atfcts __rtld_have_atfcts + #endif +Index: glibc-2.17-c758a686/sysdeps/posix/opendir.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/opendir.c ++++ glibc-2.17-c758a686/sysdeps/posix/opendir.c +@@ -121,7 +121,7 @@ __opendirat (int dfd, const char *name) + flags |= O_CLOEXEC; + #endif + int fd; +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + assert (dfd == AT_FDCWD); + fd = open_not_cancel_2 (name, flags); + #else +Index: glibc-2.17-c758a686/sysdeps/posix/profil.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/posix/profil.c ++++ glibc-2.17-c758a686/sysdeps/posix/profil.c +@@ -65,7 +65,7 @@ __profil (u_short *sample_buffer, size_t + { + struct sigaction act; + struct itimerval timer; +-#ifndef IS_IN_rtld ++#if !IS_IN (rtld) + static struct sigaction oact; + static struct itimerval otimer; + # define oact_ptr &oact +Index: glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +@@ -166,7 +166,7 @@ _dl_string_platform (const char *str) + return -1; + } + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + static inline int + __attribute__ ((unused)) + _dl_procinfo (unsigned int type, unsigned long int word) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S +@@ -37,7 +37,7 @@ ENTRY (BP_SYM (__longjmp)) + addis r5,r5,_GLOBAL_OFFSET_TABLE_-got_label@ha + addi r5,r5,_GLOBAL_OFFSET_TABLE_-got_label@l + # ifdef SHARED +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* Inside ld.so we use the local alias to avoid runtime GOT + relocations. */ + lwz r5,_rtld_local_ro@got(r5) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S +@@ -90,7 +90,7 @@ ENTRY (BP_SYM (__sigsetjmp)) + mtlr r6 + cfi_same_value (lr) + # ifdef SHARED +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* Inside ld.so we use the local alias to avoid runtime GOT + relocations. */ + lwz r5,_rtld_local_ro@got(r5) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +@@ -21,7 +21,7 @@ + the dl_hwcap field. The assembly is to make the compiler not optimize the + test (&_rtld_global_ro != NULL), which is always true in ISO C (but not + in that case since _rtld_global_ro might not been realocated yet). */ +-#if defined(SHARED) && !defined(IS_IN_rtld) ++#if defined(SHARED) && !IS_IN (rtld) + # define __GLRO(value) \ + ({ volatile void **__p = (volatile void**)(&_rtld_global_ro); \ + unsigned long int __ret; \ +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/setjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/setjmp-common.S +@@ -64,7 +64,7 @@ ENTRY (BP_SYM (__sigsetjmp)) + stw r29,((JB_GPRS+15)*4)(3) + stw r30,((JB_GPRS+16)*4)(3) + stw r31,((JB_GPRS+17)*4)(3) +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + li r3,0 + blr + #else +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/__longjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/__longjmp-common.S +@@ -31,7 +31,7 @@ + .section ".toc","aw" + .LC__dl_hwcap: + # ifdef SHARED +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* Inside ld.so we use the local alias to avoid runtime GOT + relocations. */ + .tc _rtld_local_ro[TC],_rtld_local_ro +@@ -132,7 +132,7 @@ L(no_vmx): + ld r0,(JB_LR*8)(r3) + ld r14,((JB_GPRS+0)*8)(r3) + lfd fp14,((JB_FPRS+0)*8)(r3) +-#if defined SHARED && !defined IS_IN_rtld ++#if defined SHARED && !IS_IN (rtld) + std r2,FRAME_TOC_SAVE(r1) /* Restore the callers TOC save area. */ + #endif + ld r15,((JB_GPRS+1)*8)(r3) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/setjmp-common.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/setjmp-common.S +@@ -30,7 +30,7 @@ + .section ".toc","aw" + .LC__dl_hwcap: + # ifdef SHARED +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* Inside ld.so we use the local alias to avoid runtime GOT + relocations. */ + .tc _rtld_local_ro[TC],_rtld_local_ro +@@ -50,7 +50,7 @@ ENTRY (setjmp) + b JUMPTARGET (GLUE(__sigsetjmp,_ent)) + END (setjmp) + +-#if defined SHARED && !defined IS_IN_rtld && !defined __NO_VMX__ ++#if defined SHARED && !IS_IN (rtld) && !defined __NO_VMX__ + /* When called from within libc we need a special version of _setjmp + that saves r2 since the call won't go via a plt call stub. See + bugz #269. __GI__setjmp is used in csu/libc-start.c when +@@ -82,7 +82,7 @@ JUMPTARGET(GLUE(__sigsetjmp,_ent)): + std r1,(JB_GPR1*8)(3) + #endif + mflr r0 +-#if defined SHARED && !defined IS_IN_rtld ++#if defined SHARED && !IS_IN (rtld) + ld r5,FRAME_TOC_SAVE(r1) /* Retrieve the callers TOC. */ + std r5,(JB_GPR2*8)(3) + #else +@@ -212,7 +212,7 @@ L(no_vmx): + #else + li r6,0 + #endif +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + li r3,0 + blr + #elif defined SHARED +Index: glibc-2.17-c758a686/sysdeps/s390/dl-tls.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/dl-tls.h ++++ glibc-2.17-c758a686/sysdeps/s390/dl-tls.h +@@ -29,7 +29,7 @@ typedef struct + + extern unsigned long __tls_get_offset (unsigned long got_offset); + +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + + # include + +@@ -78,9 +78,9 @@ __tls_get_offset:\n\ + 1: .long __tls_get_addr - 0b\n\ + "); + # endif +-# else /* IS_IN_rtld */ ++# else /* IS_IN (rtld) */ + extern void *__tls_get_addr_internal (tls_index *ti); +-# endif /* !IS_IN_rtld */ ++# endif /* !IS_IN (rtld) */ + + # define GET_ADDR_OFFSET \ + (ti->ti_offset - (unsigned long) __builtin_thread_pointer ()) +Index: glibc-2.17-c758a686/sysdeps/s390/s390-32/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-32/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/setjmp.S +@@ -57,7 +57,7 @@ ENTRY(__sigsetjmp) + #endif + std %f4,40(%r2) + std %f6,48(%r2) +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + lhi %r2,0 + br %r14 +Index: glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/s390/s390-64/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S +@@ -63,7 +63,7 @@ ENTRY(__sigsetjmp) + std %f13,120(%r2) + std %f14,128(%r2) + std %f15,136(%r2) +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + lghi %r2,0 + br %r14 +Index: glibc-2.17-c758a686/sysdeps/sh/sh3/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sh/sh3/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/sh/sh3/setjmp.S +@@ -46,7 +46,7 @@ ENTRY (__sigsetjmp) + mov.l r9, @-r4 + mov.l r8, @-r4 + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + rts + mov #0, r0 +Index: glibc-2.17-c758a686/sysdeps/sh/sh4/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sh/sh4/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/sh/sh4/setjmp.S +@@ -55,7 +55,7 @@ ENTRY (__sigsetjmp) + mov.l r9, @-r4 + mov.l r8, @-r4 + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + rts + mov #0, r0 +Index: glibc-2.17-c758a686/ports/sysdeps/unix/alpha/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/alpha/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/alpha/sysdep.h +@@ -26,7 +26,7 @@ + # include + #endif + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + +@@ -346,7 +346,7 @@ __LABEL(name) \ + + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # ifdef __ASSEMBLER__ + # define PTR_MANGLE(dst, src, tmp) \ + ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/arm/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/arm/sysdep.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/arm/sysdep.S +@@ -21,7 +21,7 @@ + #define _ERRNO_H + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + +Index: glibc-2.17-c758a686/sysdeps/unix/i386/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/i386/sysdep.S ++++ glibc-2.17-c758a686/sysdeps/unix/i386/sysdep.S +@@ -22,7 +22,7 @@ + #include + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -324,7 +324,7 @@ + #endif /* __ASSEMBLER__ */ + + /* Pointer mangling is supported for AArch64. */ +-#if (defined IS_IN_rtld) || \ ++#if (IS_IN (rtld)) || \ + (!defined SHARED && (!defined NOT_IN_libc \ + || IS_IN (libpthread))) + # ifdef __ASSEMBLER__ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/getcwd.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/getcwd.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/getcwd.c +@@ -33,7 +33,7 @@ + + /* If we compile the file for use in ld.so we don't need the feature + that getcwd() allocates the buffers itself. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # define NO_ALLOCATION 1 + #endif + +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.h +@@ -56,7 +56,7 @@ + /* Initialize locks to zero. */ + #define LLL_MUTEX_LOCK_INITIALIZER (0) + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +@@ -71,7 +71,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -521,7 +521,7 @@ asm (".L__X'%ebx = 1\n\t" + + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. Using a global variable + is too complicated here since we have no PC-relative addressing mode. */ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/setjmp.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/setjmp.S +@@ -179,7 +179,7 @@ ENTRY(__sigsetjmp) + ;; + st8.nta [r2]=r25 // ar.unat + st8.nta [r3]=in0 // &__jmp_buf +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + ;; + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +@@ -361,7 +361,7 @@ + #endif /* not __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/bits/m68k-vdso.h +@@ -23,7 +23,7 @@ + + #ifdef SHARED + +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + # define M68K_VDSO_SYMBOL(name) __rtld_##name + # define STR_M68K_VDSO_SYMBOL(name) "__rtld_" #name + # else +@@ -35,7 +35,7 @@ + + /* We define __rtld_* copies for rtld. + We need them visible in libc to initialize. */ +-# if defined IS_IN_rtld || !defined NOT_IN_libc ++# if IS_IN (rtld) || !defined NOT_IN_libc + extern void *__rtld___vdso_read_tp; + extern void *__rtld___vdso_atomic_cmpxchg_32; + extern void *__rtld___vdso_atomic_barrier; +@@ -44,14 +44,14 @@ extern void *__rtld___vdso_atomic_barrie + extern void __vdso_read_tp_stub (void); + extern void __vdso_atomic_cmpxchg_32_stub (void); + extern void __vdso_atomic_barrier_stub (void); +-# endif /* IS_IN_rtld || !NOT_IN_libc */ ++# endif /* IS_IN (rtld) || !NOT_IN_libc */ + + /* RTLD should only use its own copies. */ +-# ifndef IS_IN_rtld ++# if !IS_IN (rtld) + extern void *__vdso_read_tp; + extern void *__vdso_atomic_cmpxchg_32; + extern void *__vdso_atomic_barrier; +-# endif /* !IS_IN_rtld */ ++# endif /* !IS_IN (rtld) */ + + # endif /* !__ASSEMBLER__ */ + +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/m68k-helpers.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/m68k-helpers.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/m68k-helpers.S +@@ -51,7 +51,7 @@ END (__vdso_read_tp_stub) + equivalent helper function (which clobbers fewer registers than + a normal function call) in a vdso; tail call to the + helper. */ +-# ifdef IS_IN_rtld ++# if IS_IN (rtld) + /* rtld gets a hidden copy of __m68k_read_tp. */ + .hidden __m68k_read_tp + # endif +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +@@ -272,7 +272,7 @@ + + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +@@ -282,7 +282,7 @@ + + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +@@ -51,7 +51,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h +@@ -367,7 +367,7 @@ + _ret; }) + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h +@@ -373,7 +373,7 @@ + _ret; }) + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sh/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sh/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sh/sysdep.h +@@ -338,7 +338,7 @@ + #endif /* __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. Using a global variable + is too complicated here since we have no PC-relative addressing mode. */ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +@@ -56,7 +56,7 @@ extern void __cpu_relax (void); + #define BUSY_WAIT_NOP __cpu_relax () + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +@@ -22,7 +22,7 @@ + + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + #include +@@ -126,7 +126,7 @@ ENTRY(name); \ + #endif /* __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +@@ -22,7 +22,7 @@ + + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + #include +@@ -141,7 +141,7 @@ ENTRY(name); \ + #define STACK_BIAS 2047 + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/sysdep.h +@@ -205,7 +205,7 @@ + #endif /* not __ASSEMBLER__ */ + + /* Pointer mangling support. */ +-#if defined NOT_IN_libc && defined IS_IN_rtld ++#if defined NOT_IN_libc && IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + #else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +@@ -72,7 +72,7 @@ + + #ifndef __ASSEMBLER__ + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/x86_64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/sysdep.h +@@ -24,7 +24,7 @@ + #include + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + +@@ -395,7 +395,7 @@ + + + /* Pointer mangling support. */ +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ + # ifdef __ASSEMBLER__ +Index: glibc-2.17-c758a686/sysdeps/unix/x86_64/sysdep.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/x86_64/sysdep.S ++++ glibc-2.17-c758a686/sysdeps/unix/x86_64/sysdep.S +@@ -22,7 +22,7 @@ + #include + #include + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # include /* Defines RTLD_PRIVATE_ERRNO. */ + #endif + +Index: glibc-2.17-c758a686/sysdeps/x86_64/setjmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/setjmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/setjmp.S +@@ -54,7 +54,7 @@ ENTRY (__sigsetjmp) + #endif + movq %rax, (JB_PC*8)(%rdi) + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + xorl %eax, %eax + retq +Index: glibc-2.17-c758a686/include/unistd.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/unistd.h ++++ glibc-2.17-c758a686/include/unistd.h +@@ -151,7 +151,7 @@ libc_hidden_proto (__sbrk) + environment variables that normally affect them. */ + extern int __libc_enable_secure attribute_relro; + extern int __libc_enable_secure_decided; +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + /* XXX The #ifdef should go. */ + extern int __libc_enable_secure_internal attribute_relro attribute_hidden; + #endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h +@@ -27,7 +27,7 @@ + all the libc functions that ld.so uses are called without PLT and always + get the versions linked into ld.so rather than the libc ones. */ + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # define RTLD_PRIVATE_ERRNO 1 + #else + # define RTLD_PRIVATE_ERRNO 0 +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +@@ -52,7 +52,7 @@ + #define LLL_PRIVATE 0 + #define LLL_SHARED FUTEX_PRIVATE_FLAG + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/lowlevellock.h +@@ -49,7 +49,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h +@@ -48,7 +48,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/dl-sysdep.h +@@ -27,7 +27,7 @@ + all the libc functions that ld.so uses are called without PLT and always + get the versions linked into ld.so rather than the libc ones. */ + +-#ifdef IS_IN_rtld ++#if IS_IN (rtld) + # define RTLD_PRIVATE_ERRNO 1 + #else + # define RTLD_PRIVATE_ERRNO 0 +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/lowlevellock.h +@@ -48,7 +48,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/lowlevellock.h +@@ -50,7 +50,7 @@ + #define LLL_SHARED FUTEX_PRIVATE_FLAG + + +-#if !defined NOT_IN_libc || defined IS_IN_rtld ++#if !defined NOT_IN_libc || IS_IN (rtld) + /* In libc.so or ld.so all futexes are private. */ + # ifdef __ASSUME_PRIVATE_FUTEX + # define __lll_private_flag(fl, private) \ diff --git a/SOURCES/glibc-rh1256317-5.patch b/SOURCES/glibc-rh1256317-5.patch new file mode 100644 index 00000000..75f27120 --- /dev/null +++ b/SOURCES/glibc-rh1256317-5.patch @@ -0,0 +1,861 @@ +commit a109996ef96b065c8374c486e80ee3bf23c69edd +Author: Siddhesh Poyarekar +Date: Thu Nov 20 21:04:47 2014 +0530 + + Remove IS_IN_libm + + Replace with IS_IN (libm). Generated code unchanged on x86_64. + + * include/math.h: Use IS_IN instead of IS_IN_libm. + * sysdeps/alpha/fpu/s_copysign.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_copysignl.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_finitel.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_fmal.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_frexpl.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_isinfl.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_isnanl.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_modfl.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c: Likewise. + * sysdeps/ieee754/ldbl-128ibm/s_signbitl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_copysignl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_finitel.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_frexpl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_isinfl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_isnanl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_modfl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_scalbnl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/s_signbitl.c: Likewise. + * sysdeps/ieee754/ldbl-64-128/w_scalblnl.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_copysign.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_finite.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_frexp.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_isinf.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_isnan.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_ldexp.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_ldexpl.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_modf.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_scalbln.c: Likewise. + * sysdeps/ieee754/ldbl-opt/s_scalbn.c: Likewise. + * sysdeps/powerpc/power5+/fpu/s_modf.c: Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_copysign.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_copysignl.S: Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_copysign.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c: Likewise. + * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf.c: Likewise. + * sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc32/power6/fpu/s_copysign.S: Likewise. + * sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S: Likewise. + * sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S: Likewise. + * sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c: Likewise. + * sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c: Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_copysignl.S: Likewise. + * sysdeps/powerpc/powerpc64/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/power6/fpu/s_copysign.S: Likewise. + * sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S: Likewise. + * sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S: Likewise. + * sysdeps/powerpc/powerpc64/power7/fpu/s_isnan.S: Likewise. + * sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S: Likewise. + * sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S: Likewise. + * sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S: Likewise. + * sysdeps/sparc/sparc32/fpu/s_signbitl.S: Likewise. + * sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S: Likewise. + * sysdeps/unix/sysv/linux/alpha/fraiseexcpt.S: Likewise. + +Index: glibc-2.17-c758a686/include/math.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/math.h ++++ glibc-2.17-c758a686/include/math.h +@@ -6,7 +6,7 @@ + /* Now define the internal interfaces. */ + extern int __matherr (struct exception *__exc); + +-# if !defined NOT_IN_libc || defined IS_IN_libm ++# if !defined NOT_IN_libc || IS_IN (libm) + hidden_proto (__finite) + hidden_proto (__isinf) + hidden_proto (__isnan) +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_copysignl.c +@@ -34,7 +34,7 @@ long double __copysignl(long double x, l + return x; + } + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __copysignl, copysignl); + #else + long_double_symbol (libc, __copysignl, copysignl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_finitel.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_finitel.c +@@ -40,7 +40,7 @@ ___finitel (long double x) + } + hidden_ver (___finitel, __finitel) + weak_alias (___finitel, ____finitel) +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, ____finitel, finitel); + long_double_symbol (libm, ___finitel, __finitel); + #else +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fmal.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_fmal.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_fmal.c +@@ -37,7 +37,7 @@ __fmal (long double x, long double y, lo + + return (x * y) + z; + } +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __fmal, fmal); + #else + long_double_symbol (libc, __fmal, fmal); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c +@@ -141,7 +141,7 @@ long double __frexpl(long double x, int + *eptr = expon; + return x; + } +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __frexpl, frexpl); + #else + long_double_symbol (libc, __frexpl, frexpl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isinfl.c +@@ -33,7 +33,7 @@ ___isinfl (long double x) + return ~mask & (hx >> 62); + } + hidden_ver (___isinfl, __isinfl) +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + weak_alias (___isinfl, ____isinfl) + long_double_symbol (libc, ___isinfl, isinfl); + long_double_symbol (libc, ____isinfl, __isinfl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_isnanl.c +@@ -39,7 +39,7 @@ ___isnanl (long double x) + return (int) (hx >> 63); + } + hidden_ver (___isnanl, __isnanl) +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + weak_alias (___isnanl, ____isnanl) + long_double_symbol (libc, ___isnanl, isnanl); + long_double_symbol (libc, ____isnanl, __isnanl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_modfl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_modfl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_modfl.c +@@ -89,7 +89,7 @@ long double __modfl(long double x, long + } + } + } +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __modfl, modfl); + #else + long_double_symbol (libc, __modfl, modfl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_scalbnl.c +@@ -102,7 +102,7 @@ long double __scalbnl (long double x, in + x = ldbl_pack (xhi, xlo); + return x*twolm54; + } +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __scalbnl, scalbnl); + #else + long_double_symbol (libc, __scalbnl, scalbnl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_signbitl.c +@@ -31,7 +31,7 @@ ___signbitl (long double x) + EXTRACT_WORDS64 (e, xhi); + return e < 0; + } +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, ___signbitl, __signbitl); + #else + long_double_symbol (libc, ___signbitl, __signbitl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_copysignl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_copysignl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_copysignl.c +@@ -2,7 +2,7 @@ + #undef weak_alias + #define weak_alias(n,a) + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __copysignl, copysignl); + #else + long_double_symbol (libc, __copysignl, copysignl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_finitel.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_finitel.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_finitel.c +@@ -8,7 +8,7 @@ + #undef __finitel + hidden_ver (___finitel, __finitel) + _weak_alias (___finitel, ____finitel) +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, ____finitel, finitel); + long_double_symbol (libm, ___finitel, __finitel); + #else +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_frexpl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_frexpl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_frexpl.c +@@ -2,7 +2,7 @@ + #undef weak_alias + #define weak_alias(n,a) + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __frexpl, frexpl); + #else + long_double_symbol (libc, __frexpl, frexpl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_isinfl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_isinfl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_isinfl.c +@@ -1,5 +1,5 @@ + #include +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # undef weak_alias + # define weak_alias(n,a) + # undef hidden_def +@@ -7,7 +7,7 @@ + # define __isinfl(arg) ___isinfl(arg) + #endif + #include +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # undef __isinfl + hidden_ver (___isinfl, __isinfl) + _weak_alias (___isinfl, ____isinfl) +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_isnanl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_isnanl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_isnanl.c +@@ -1,5 +1,5 @@ + #include +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # undef weak_alias + # define weak_alias(n,a) + # undef hidden_def +@@ -7,7 +7,7 @@ + # define __isnanl(arg) ___isnanl(arg) + #endif + #include +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # undef __isnanl + hidden_ver (___isnanl, __isnanl) + _weak_alias (___isnanl, ____isnanl) +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_modfl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_modfl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_modfl.c +@@ -2,7 +2,7 @@ + #undef weak_alias + #define weak_alias(n,a) + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __modfl, modfl); + #else + long_double_symbol (libc, __modfl, modfl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_scalbnl.c +@@ -2,7 +2,7 @@ + #undef weak_alias + #define weak_alias(n,a) + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __scalbnl, scalbnl); + #else + long_double_symbol (libc, __scalbnl, scalbnl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_signbitl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_signbitl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_signbitl.c +@@ -4,7 +4,7 @@ + #define __signbitl(arg) ___signbitl(arg) + #include + #undef __signbitl +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, ___signbitl, __signbitl); + #else + long_double_symbol (libc, ___signbitl, __signbitl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_copysign.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_copysign.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_copysign.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __copysign, copysignl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_finite.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_finite.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_finite.c +@@ -1,7 +1,7 @@ + #include + #include + weak_alias (__finite, ___finite) +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) + compat_symbol (libm, __finite, __finitel, GLIBC_2_1); + # endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_frexp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_frexp.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_frexp.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __frexp, frexpl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_isinf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_isinf.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_isinf.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); + compat_symbol (libc, isinf, isinfl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_isnan.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_isnan.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_isnan.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_ldexp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_ldexp.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_ldexp.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __ldexp, ldexpl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_ldexpl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_ldexpl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_ldexpl.c +@@ -2,7 +2,7 @@ + #undef weak_alias + #define weak_alias(n,a) + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __ldexpl, ldexpl); + #else + long_double_symbol (libc, __ldexpl, ldexpl); +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_modf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_modf.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_modf.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __modf, modfl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_scalbln.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_scalbln.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_scalbln.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + #if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) + compat_symbol (libm, __scalbln, scalblnl, GLIBC_2_1); + #endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_scalbn.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-opt/s_scalbn.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-opt/s_scalbn.c +@@ -1,6 +1,6 @@ + #include + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __scalbn, scalbnl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/power5+/fpu/s_modf.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modf.c +@@ -49,7 +49,7 @@ weak_alias (__modf, modf) + strong_alias (__modf, __modfl) + weak_alias (__modf, modfl) + #endif +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __modf, modfl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_copysign.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysign.S +@@ -50,7 +50,7 @@ strong_alias(__copysign,__copysignf) + weak_alias (__copysign,copysignl) + strong_alias(__copysign,__copysignl) + #endif +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __copysign, copysignl, GLIBC_2_0) + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S +@@ -42,7 +42,7 @@ L(0): bgelr cr6 + blr + END (__copysignl) + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __copysignl, copysignl) + #else + long_double_symbol (libc, __copysignl, copysignl) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_isnan.S +@@ -48,7 +48,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S +@@ -52,7 +52,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_copysign.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_copysign.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_copysign.S +@@ -47,7 +47,7 @@ strong_alias (__copysign, __copysignl) + weak_alias (__copysign, copysignl) + #endif + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) + compat_symbol (libm, copysign, copysignl, GLIBC_2_0) + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S +@@ -52,7 +52,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_finite.S +@@ -78,7 +78,7 @@ strong_alias (__finite, __finitel) + weak_alias (__finite, finitel) + #endif + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) + compat_symbol (libm, finite, finitel, GLIBC_2_0) + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isinf.S +@@ -77,7 +77,7 @@ strong_alias (__isinf, __isinfl) + weak_alias (__isinf, isinfl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); + compat_symbol (libc, isinf, isinfl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power7/fpu/s_isnan.S +@@ -82,7 +82,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c +@@ -42,7 +42,7 @@ weak_alias (__copysign, copysign) + weak_alias (__copysign,copysignl) + strong_alias(__copysign,__copysignl) + #endif +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __copysign, copysignl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c +@@ -39,7 +39,7 @@ strong_alias (__finite, __finitel) + weak_alias (__finite, finitel) + #endif + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) + compat_symbol (libm, finite, finitel, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c +@@ -39,7 +39,7 @@ strong_alias (__isinf, __isinfl) + weak_alias (__isinf, isinfl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0) + compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); + compat_symbol (libc, isinf, isinfl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c +@@ -48,7 +48,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c +@@ -35,7 +35,7 @@ weak_alias (__modf, modf) + strong_alias (__modf, __modfl) + weak_alias (__modf, modfl) + #endif +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __modf, modfl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_copysign.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysign.S +@@ -50,7 +50,7 @@ strong_alias(__copysign,__copysignf) + weak_alias (__copysign,copysignl) + strong_alias(__copysign,__copysignl) + #endif +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __copysign, copysignl, GLIBC_2_0) + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_copysignl.S +@@ -43,7 +43,7 @@ L(0): + blr + END (__copysignl) + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __copysignl, copysignl) + #else + long_double_symbol (libc, __copysignl, copysignl) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_isnan.S +@@ -47,7 +47,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S +@@ -51,7 +51,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/s_copysign.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6/fpu/s_copysign.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/s_copysign.S +@@ -47,7 +47,7 @@ strong_alias (__copysign, __copysignl) + weak_alias (__copysign, copysignl) + #endif + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) + compat_symbol (libm, copysign, copysignl, GLIBC_2_0) + # endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S +@@ -50,7 +50,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S +@@ -49,7 +49,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S +@@ -57,7 +57,7 @@ strong_alias (__finite, __finitef) + hidden_def (__finitef) + weak_alias (__finitef, finitef) + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) + compat_symbol (libm, __finite, __finitel, GLIBC_2_0) + compat_symbol (libm, finite, finitel, GLIBC_2_0) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S +@@ -61,7 +61,7 @@ strong_alias (__isinf, __isinfl) + weak_alias (__isinf, isinfl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); + compat_symbol (libc, isinf, isinfl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power7/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/s_isnan.S +@@ -60,7 +60,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S +@@ -43,7 +43,7 @@ strong_alias (__finite, __finitef) + hidden_def (__finitef) + weak_alias (__finitef, finitef) + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) + compat_symbol (libm, __finite, __finitel, GLIBC_2_0) + compat_symbol (libm, finite, finitel, GLIBC_2_0) +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S +@@ -53,7 +53,7 @@ strong_alias (__isinf, __isinfl) + weak_alias (__isinf, isinfl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); + compat_symbol (libc, isinf, isinfl, GLIBC_2_0); +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S +@@ -45,7 +45,7 @@ strong_alias (__isnan, __isnanl) + weak_alias (__isnan, isnanl) + #endif + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); +Index: glibc-2.17-c758a686/ports/sysdeps/alpha/fpu/s_copysign.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/alpha/fpu/s_copysign.c ++++ glibc-2.17-c758a686/ports/sysdeps/alpha/fpu/s_copysign.c +@@ -30,7 +30,7 @@ weak_alias (__copysign, copysign) + strong_alias (__copysign, __copysignl) + weak_alias (__copysign, copysignl) + #endif +-#ifdef IS_IN_libm ++#if IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) + compat_symbol (libm, __copysign, copysignl, GLIBC_2_0); + # endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-64-128/s_scalblnl.c +@@ -2,7 +2,7 @@ + #undef weak_alias + #define weak_alias(n,a) + #include +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, __scalblnl, scalblnl); + #else + long_double_symbol (libc, __scalblnl, scalblnl); +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc32/fpu/s_signbitl.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc32/fpu/s_signbitl.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/fpu/s_signbitl.S +@@ -25,7 +25,7 @@ ENTRY (___signbitl) + srl %o1, 31, %o0 + END (___signbitl) + +-#ifdef IS_IN_libm ++#if IS_IN (libm) + long_double_symbol (libm, ___signbitl, __signbitl); + #else + long_double_symbol (libc, ___signbitl, __signbitl); +Index: glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/sparc/sparc32/sparcv9/fpu/s_isnan.S +@@ -32,7 +32,7 @@ END (__isnan) + hidden_def (__isnan) + weak_alias (__isnan, isnan) + +-#ifndef IS_IN_libm ++#if !IS_IN (libm) + # if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) + compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); + compat_symbol (libc, isnan, isnanl, GLIBC_2_0); diff --git a/SOURCES/glibc-rh1256317-6.patch b/SOURCES/glibc-rh1256317-6.patch new file mode 100644 index 00000000..e11fbc29 --- /dev/null +++ b/SOURCES/glibc-rh1256317-6.patch @@ -0,0 +1,914 @@ +commit ce9f10f7f0cc83df3e307a18e480587c3b404321 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 14:22:40 2014 +0530 + + Remove IS_IN_libpthread + + Replace with IS_IN (libpthread). Generated code unchanged on + x86_64. + + * nptl/lowlevellock.c: Use IS_IN instead of IS_IN_libpthread. + * nptl/pthreadP.h: Likewise. + * nptl_db/structs.def: Likewise. + * sysdeps/arm/sysdep.h: Likewise. + * sysdeps/nptl/bits/libc-lock.h: Likewise. + * sysdeps/nptl/bits/libc-lockP.h: Likewise. + * sysdeps/sparc/sparc32/lowlevellock.c: Likewise. + * sysdeps/unix/alpha/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/mips/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/not-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/tile/waitpid.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/cancellation.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise. + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/lowlevellock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +@@ -37,7 +37,7 @@ __lll_lock_wait_private (int *futex) + + + /* These functions don't get included in libc.so */ +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + void + __lll_lock_wait (int *futex, int private) + { +Index: glibc-2.17-c758a686/nptl/pthreadP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthreadP.h ++++ glibc-2.17-c758a686/nptl/pthreadP.h +@@ -225,7 +225,7 @@ extern int __pthread_debug attribute_hid + + extern void __pthread_unwind (__pthread_unwind_buf_t *__buf) + __cleanup_fct_attribute __attribute ((__noreturn__)) +-#if !defined SHARED && !defined IS_IN_libpthread ++#if !defined SHARED && !IS_IN (libpthread) + weak_function + #endif + ; +@@ -239,7 +239,7 @@ extern void __pthread_register_cancel (_ + __cleanup_fct_attribute; + extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf) + __cleanup_fct_attribute; +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + hidden_proto (__pthread_unwind) + hidden_proto (__pthread_unwind_next) + hidden_proto (__pthread_register_cancel) +@@ -283,7 +283,7 @@ __do_cancel (void) + # define LIBC_CANCEL_HANDLED() \ + __asm (".globl " __SYMBOL_PREFIX "__libc_enable_asynccancel"); \ + __asm (".globl " __SYMBOL_PREFIX "__libc_disable_asynccancel") +-#elif defined IS_IN_libpthread ++#elif IS_IN (libpthread) + # define LIBC_CANCEL_ASYNC() CANCEL_ASYNC () + # define LIBC_CANCEL_RESET(val) CANCEL_RESET (val) + # define LIBC_CANCEL_HANDLED() \ +@@ -344,7 +344,7 @@ extern int __make_stacks_executable (voi + + /* longjmp handling. */ + extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe); +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + hidden_proto (__pthread_cleanup_upto) + #endif + +@@ -489,7 +489,7 @@ extern int __pthread_enable_asynccancel + extern void __pthread_disable_asynccancel (int oldtype) + internal_function attribute_hidden; + +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + hidden_proto (__pthread_mutex_init) + hidden_proto (__pthread_mutex_destroy) + hidden_proto (__pthread_mutex_lock) +@@ -528,7 +528,7 @@ extern int __librt_enable_asynccancel (v + extern void __librt_disable_asynccancel (int oldtype) + internal_function attribute_hidden; + +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + /* Special versions which use non-exported functions. */ + extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer, + void (*routine) (void *), void *arg) +Index: glibc-2.17-c758a686/nptl_db/structs.def +=================================================================== +--- glibc-2.17-c758a686.orig/nptl_db/structs.def ++++ glibc-2.17-c758a686/nptl_db/structs.def +@@ -31,7 +31,7 @@ + #endif + + #ifndef DB_RTLD_GLOBAL_FIELD +-# if !defined IS_IN_libpthread ++# if !IS_IN (libpthread) + # define DB_RTLD_GLOBAL_FIELD(field) \ + DB_STRUCT_FIELD (rtld_global, _##field) \ + DB_MAIN_VARIABLE (_##field) +@@ -98,11 +98,11 @@ DB_STRUCT_ARRAY_FIELD (dtv, dtv) + #define pointer_val pointer.val /* Field of anonymous struct in dtv_t. */ + DB_STRUCT_FIELD (dtv_t, pointer_val) + DB_STRUCT_FIELD (dtv_t, counter) +-#if !defined IS_IN_libpthread || TLS_TCB_AT_TP ++#if !IS_IN (libpthread) || TLS_TCB_AT_TP + DB_STRUCT_FIELD (pthread, dtvp) + #endif + +-#if !(defined IS_IN_libpthread && !defined SHARED) ++#if !(IS_IN (libpthread) && !defined SHARED) + DB_STRUCT (rtld_global) + DB_RTLD_VARIABLE (_rtld_global) + #endif +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/bits/libc-lock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lock.h +@@ -26,7 +26,7 @@ + + /* Mutex type. */ + #if defined _LIBC || defined _IO_MTSAFE_IO +-# if (defined NOT_IN_libc && !defined IS_IN_libpthread) || !defined _LIBC ++# if (defined NOT_IN_libc && !IS_IN (libpthread)) || !defined _LIBC + typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t; + # else + typedef struct { int lock; int cnt; void *owner; } __libc_lock_recursive_t; +@@ -47,7 +47,7 @@ typedef struct __libc_lock_recursive_opa + + /* Define an initialized recursive lock variable NAME with storage + class CLASS. */ +-#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) + # if LLL_LOCK_INITIALIZER == 0 + # define __libc_lock_define_initialized_recursive(CLASS,NAME) \ + CLASS __libc_lock_recursive_t NAME; +@@ -65,7 +65,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Initialize a recursive mutex. */ +-#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) + # define __libc_lock_init_recursive(NAME) \ + ((NAME) = (__libc_lock_recursive_t) _LIBC_LOCK_RECURSIVE_INITIALIZER, 0) + #else +@@ -83,7 +83,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Finalize recursive named lock. */ +-#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) + # define __libc_lock_fini_recursive(NAME) ((void) 0) + #else + # define __libc_lock_fini_recursive(NAME) \ +@@ -91,7 +91,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Lock the recursive named lock variable. */ +-#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) + # define __libc_lock_lock_recursive(NAME) \ + do { \ + void *self = THREAD_SELF; \ +@@ -108,7 +108,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Try to lock the recursive named lock variable. */ +-#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) + # define __libc_lock_trylock_recursive(NAME) \ + ({ \ + int result = 0; \ +@@ -133,7 +133,7 @@ typedef struct __libc_lock_recursive_opa + #endif + + /* Unlock the recursive named lock variable. */ +-#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++#if defined _LIBC && (!defined NOT_IN_libc || IS_IN (libpthread)) + /* We do no error checking here. */ + # define __libc_lock_unlock_recursive(NAME) \ + do { \ +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lockP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/bits/libc-lockP.h ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/bits/libc-lockP.h +@@ -35,7 +35,7 @@ + #include + + /* Mutex type. */ +-#if defined NOT_IN_libc && !defined IS_IN_libpthread ++#if defined NOT_IN_libc && !IS_IN (libpthread) + typedef pthread_mutex_t __libc_lock_t; + #else + typedef int __libc_lock_t; +@@ -69,7 +69,7 @@ typedef pthread_key_t __libc_key_t; + initialized locks must be set to one due to the lack of normal + atomic operations.) */ + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread ++#if !defined NOT_IN_libc || IS_IN (libpthread) + # if LLL_LOCK_INITIALIZER == 0 + # define __libc_lock_define_initialized(CLASS,NAME) \ + CLASS __libc_lock_t NAME; +@@ -130,7 +130,7 @@ typedef pthread_key_t __libc_key_t; + + /* Initialize the named lock variable, leaving it in a consistent, unlocked + state. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread ++#if !defined NOT_IN_libc || IS_IN (libpthread) + # define __libc_lock_init(NAME) ((NAME) = LLL_LOCK_INITIALIZER, 0) + #else + # define __libc_lock_init(NAME) \ +@@ -149,7 +149,7 @@ typedef pthread_key_t __libc_key_t; + /* Finalize the named lock variable, which must be locked. It cannot be + used again until __libc_lock_init is called again on it. This must be + called on a lock variable before the containing storage is reused. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread ++#if !defined NOT_IN_libc || IS_IN (libpthread) + # define __libc_lock_fini(NAME) ((void) 0) + #else + # define __libc_lock_fini(NAME) \ +@@ -163,7 +163,7 @@ typedef pthread_key_t __libc_key_t; + #endif + + /* Lock the named lock variable. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread ++#if !defined NOT_IN_libc || IS_IN (libpthread) + # ifndef __libc_lock_lock + # define __libc_lock_lock(NAME) \ + ({ lll_lock (NAME, LLL_PRIVATE); 0; }) +@@ -179,7 +179,7 @@ typedef pthread_key_t __libc_key_t; + __libc_ptf_call (__pthread_rwlock_wrlock, (&(NAME)), 0) + + /* Try to lock the named lock variable. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread ++#if !defined NOT_IN_libc || IS_IN (libpthread) + # ifndef __libc_lock_trylock + # define __libc_lock_trylock(NAME) \ + lll_trylock (NAME) +@@ -198,7 +198,7 @@ typedef pthread_key_t __libc_key_t; + __libc_maybe_call (__pthread_mutex_trylock, (&(NAME).mutex), 0) + + /* Unlock the named lock variable. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread ++#if !defined NOT_IN_libc || IS_IN (libpthread) + # define __libc_lock_unlock(NAME) \ + lll_unlock (NAME, LLL_PRIVATE) + #else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -81,7 +81,7 @@ ENTRY (name); \ + # define UNDOCARGS_5 UNDOCARGS_3; ldp x3, x4, [sp, 32] + # define UNDOCARGS_6 UNDOCARGS_4; ldp x4, x5, [sp, 40] + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE bl __pthread_enable_asynccancel + # define CDISABLE bl __pthread_disable_asynccancel + # define __local_multiple_threads __pthread_multiple_threads +@@ -96,7 +96,7 @@ ENTRY (name); \ + # error Unsupported library + # endif + +-# if defined IS_IN_libpthread || !defined NOT_IN_libc ++# if IS_IN (libpthread) || !defined NOT_IN_libc + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +@@ -326,7 +326,7 @@ + /* Pointer mangling is supported for AArch64. */ + #if (defined IS_IN_rtld) || \ + (!defined SHARED && (!defined NOT_IN_libc \ +- || defined IS_IN_libpthread)) ++ || IS_IN (libpthread))) + # ifdef __ASSEMBLER__ + # define PTR_MANGLE(dst, src, guard, tmp) \ + LDST_PCREL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + /* NOTE: We do mark syscalls with unwind annotations, for the benefit of + cancellation; but they're really only accurate at the point of the +@@ -186,7 +186,7 @@ + # define RESTORE_LR_6 \ + RESTORE_LR_0 + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE bl PLTJMP(__pthread_enable_asynccancel) + # define CDISABLE bl PLTJMP(__pthread_disable_asynccancel) + # define __local_multiple_threads __pthread_multiple_threads +@@ -201,7 +201,7 @@ + # error Unsupported library + # endif + +-# if defined IS_IN_libpthread || !defined NOT_IN_libc ++# if IS_IN (libpthread) || !defined NOT_IN_libc + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -108,7 +108,7 @@ + # define _POPCARGS_6 _POPCARGS_5; popl %ebp; \ + cfi_adjust_cfa_offset (-4); cfi_restore (ebp); + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel; + # define CDISABLE call __pthread_disable_asynccancel + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/i386/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/sysdep.h +@@ -36,7 +36,7 @@ + #define SYS_ify(syscall_name) __NR_##syscall_name + + #if defined USE_DL_SYSINFO \ +- && (!defined NOT_IN_libc || defined IS_IN_libpthread) ++ && (!defined NOT_IN_libc || IS_IN (libpthread)) + # define I386_USE_SYSENTER 1 + #else + # undef I386_USE_SYSENTER +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/not-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/not-cancel.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/not-cancel.h +@@ -27,7 +27,7 @@ + INLINE_SYSCALL (open, 2, (const char *) (name), (flags)) + + /* Uncancelable openat. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + extern int __openat_nocancel (int fd, const char *fname, int oflag, + mode_t mode) attribute_hidden; + extern int __openat64_nocancel (int fd, const char *fname, int oflag, +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -81,7 +81,7 @@ + # define DOCARGS_6 stw 8,40(1); DOCARGS_5 + # define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5 + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE bl __pthread_enable_asynccancel@local + # define CDISABLE bl __pthread_disable_asynccancel@local + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # ifdef HAVE_ASM_GLOBAL_DOT_NAME + # define DASHDASHPFX(str) .__##str +@@ -99,7 +99,7 @@ + # define DOCARGS_6 std 8,CANCEL_PARM_SAVE+40(1); DOCARGS_5 + # define UNDOCARGS_6 ld 8,CANCEL_PARM_SAVE+40(1); UNDOCARGS_5 + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # ifdef SHARED + # define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel) + # define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -75,7 +75,7 @@ L(pseudo_check): \ + .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ + L(pseudo_end): + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE __pthread_enable_asynccancel + # define CDISABLE __pthread_disable_asynccancel + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -69,7 +69,7 @@ L(pseudo_check): \ + .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \ + L(pseudo_end): + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE __pthread_enable_asynccancel + # define CDISABLE __pthread_disable_asynccancel + # define __local_multiple_threads __pthread_multiple_threads +@@ -111,7 +111,7 @@ L(pseudo_end): + #define LR7_6 lg %r7,56+160(%r15); \ + cfi_restore (%r7); + +-# if defined IS_IN_libpthread || !defined NOT_IN_libc ++# if IS_IN (libpthread) || !defined NOT_IN_libc + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S +@@ -21,7 +21,7 @@ + #include + #include "lowlevellock.h" + +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + # ifdef SHARED + # define __pthread_unwind __GI___pthread_unwind + # endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + /* The code to disable cancellation depends on the fact that the called + functions are special. They don't modify registers other than %rax +@@ -59,7 +59,7 @@ + jae SYSCALL_ERROR_LABEL + + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel; + # define CDISABLE call __pthread_disable_asynccancel; + # define __local_multiple_threads __pthread_multiple_threads +@@ -74,7 +74,7 @@ + # error Unsupported library + # endif + +-# if defined IS_IN_libpthread || !defined NOT_IN_libc ++# if IS_IN (libpthread) || !defined NOT_IN_libc + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +@@ -19,7 +19,7 @@ + + #include + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + extern int __open_nocancel (const char *, int, ...) attribute_hidden; + extern int __close_nocancel (int) attribute_hidden; + extern int __read_nocancel (int, void *, size_t) attribute_hidden; +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c +@@ -35,7 +35,7 @@ __lll_lock_wait_private (int *futex) + + + /* These functions don't get included in libc.so */ +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + void + __lll_lock_wait (int *futex, int private) + { +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # define _IMM12 #-12 + # define _IMM16 #-16 +@@ -105,7 +105,7 @@ + # define LOAD_ARGS_5 LOAD_ARGS_4 + # define LOAD_ARGS_6 LOAD_ARGS_5 + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define __local_enable_asynccancel __pthread_enable_asynccancel + # define __local_disable_asynccancel __pthread_disable_asynccancel + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/lowlevellock.c +@@ -37,7 +37,7 @@ __lll_lock_wait_private (int *futex) + + + /* These functions don't get included in libc.so */ +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + void + __lll_lock_wait (int *futex, int private) + { +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -68,7 +68,7 @@ __##syscall_name##_nocancel: \ + restore %g0, %l1, %o0; + + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel + # define CDISABLE call __pthread_disable_asynccancel + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -66,7 +66,7 @@ __##syscall_name##_nocancel: \ + 2: jmpl %i7 + 8, %g0; \ + restore %g0, %l1, %o0; + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel + # define CDISABLE call __pthread_disable_asynccancel + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END + besides "ret". */ +@@ -105,7 +105,7 @@ __LABEL($multi_error) \ + # define LOAD_ARGS_5 LOAD_ARGS_4; ldq a4, 40(sp) + # define LOAD_ARGS_6 LOAD_ARGS_5; ldq a5, 48(sp) + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define __local_enable_asynccancel __pthread_enable_asynccancel + # define __local_disable_asynccancel __pthread_disable_asynccancel + # define __local_multiple_threads __pthread_multiple_threads +@@ -128,7 +128,7 @@ __LABEL($multi_error) \ + # define CDISABLE jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp) + # endif + +-# if defined IS_IN_libpthread || !defined NOT_IN_libc ++# if IS_IN (libpthread) || !defined NOT_IN_libc + # ifndef __ASSEMBLER__ + extern int __local_multiple_threads attribute_hidden; + # define SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -79,7 +79,7 @@ + # define LOAD_ARGS_5 LOAD_ARGS_4 + # define LOAD_ARGS_6 LOAD_ARGS_5 + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE call __pthread_enable_asynccancel,[],0; + # define CDISABLE call __pthread_disable_asynccancel,[],0; + # elif IS_IN (librt) +@@ -105,7 +105,7 @@ + + #if !defined NOT_IN_libc + # define __local_multiple_threads __libc_multiple_threads +-#elif defined IS_IN_libpthread ++#elif IS_IN (libpthread) + # define __local_multiple_threads __pthread_multiple_threads + #else + # define __local_multiple_threads __librt_multiple_threads +@@ -118,7 +118,7 @@ + p_header.data.multiple_threads) == 0, 1) + # else + extern int __local_multiple_threads +-# if !defined NOT_IN_libc || defined IS_IN_libpthread ++# if !defined NOT_IN_libc || IS_IN (libpthread) + attribute_hidden; + # else + ; +@@ -130,7 +130,7 @@ extern int __local_multiple_threads + # define SINGLE_THREAD_P \ + mov (+__local_multiple_threads),d0; \ + cmp 0,d0 +-# elif !defined NOT_IN_libc || defined IS_IN_libpthread ++# elif !defined NOT_IN_libc || IS_IN (libpthread) + # define SINGLE_THREAD_P \ + movm [a2],(sp); \ + 1: mov pc,a2; \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/lowlevellock.c +@@ -85,7 +85,7 @@ __lll_timedlock_wait (lll_lock_t *futex, + + + /* These don't get included in libc.so */ +-#ifdef IS_IN_libpthread ++#if IS_IN (libpthread) + int + lll_unlock_wake_cb (lll_lock_t *futex) + { +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # ifndef NO_ERROR + # define NO_ERROR -0x1000 +@@ -204,7 +204,7 @@ L(pre_end): ASM_LINE_SEP \ + # define POPARGS_6 POPARGS_5 ldw -56(%sr0,%sp), %r21 ASM_LINE_SEP \ + .cfi_restore 21 ASM_LINE_SEP + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # ifdef PIC + # define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \ + bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP +@@ -244,7 +244,7 @@ L(pre_end): ASM_LINE_SEP \ + # error Unsupported library + # endif + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define __local_multiple_threads __pthread_multiple_threads + # elif !defined NOT_IN_libc + # define __local_multiple_threads __libc_multiple_threads +@@ -271,7 +271,7 @@ L(pre_end): ASM_LINE_SEP \ + # define NO_CANCELLATION 1 + + #endif +-/* !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) */ ++/* !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) */ + + #ifndef __ASSEMBLER__ + # define RTLD_SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + +@@ -160,7 +160,7 @@ __GC_##name: \ + # undef PSEUDO_END + # define PSEUDO_END(name) .endp + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel + # define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -100,7 +100,7 @@ + # define PSEUDO_JMP(sym) jbsr sym + # endif + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel) + # elif !defined NOT_IN_libc +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h +@@ -27,7 +27,7 @@ + happen before any instructions. So we use cfi_same_value instead of + cfi_restore. */ + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + #ifdef __PIC__ + # undef PSEUDO +@@ -146,7 +146,7 @@ + # define SAVESTK PTR_SUBU sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE) + # define RESTORESTK PTR_ADDU sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE) + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE PTR_LA t9, __pthread_enable_asynccancel; jalr t9 + # define CDISABLE PTR_LA t9, __pthread_disable_asynccancel; jalr t9 + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + # ifdef __PIC__ + # define PSEUDO_CPLOAD .cpload t9; +@@ -152,7 +152,7 @@ + # define PSEUDO_JMP(sym) jal sym; + # endif + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel) + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + /* Allow hacking in some extra code if desired. */ + #ifndef PSEUDO_EXTRA +@@ -117,7 +117,7 @@ + + # define STKSPACE (13 * REGSIZE) + +-# ifdef IS_IN_libpthread ++# if IS_IN (libpthread) + # define CENABLE jal __pthread_enable_asynccancel + # define CDISABLE jal __pthread_disable_asynccancel + # elif IS_IN (librt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S +@@ -1,7 +1,7 @@ + /* + extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden; + */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) ++#if !defined NOT_IN_libc || IS_IN (libpthread) || IS_IN (librt) + + /* Call __NR_wait4, providing fourth argument (struct rusage *) as NULL. */ + #define PSEUDO_EXTRA move r3, zero; +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/sysdep.h +@@ -45,7 +45,7 @@ + #ifndef PIC + /* For static code, on error jump to __syscall_error directly. */ + # define SYSCALL_ERROR_NAME __syscall_error +-#elif !defined NOT_IN_libc || defined IS_IN_libpthread ++#elif !defined NOT_IN_libc || IS_IN (libpthread) + /* Use the internal name for libc/libpthread shared objects. */ + # define SYSCALL_ERROR_NAME __GI___syscall_error + #else diff --git a/SOURCES/glibc-rh1256317-7.patch b/SOURCES/glibc-rh1256317-7.patch new file mode 100644 index 00000000..c2896d21 --- /dev/null +++ b/SOURCES/glibc-rh1256317-7.patch @@ -0,0 +1,546 @@ +commit 016afc75cd45dfaf49c0aa7a9befda77ab933846 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 13:26:25 2014 +0530 + + Remove IS_IN_librt + + Replace with IS_IN (librt). Generated code unchanged on x86_64 + + * include/mqueue.h: Use IS_IN instead of IS_IN_librt. + * nptl/pthreadP.h: Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/ia64/sysdep.h: Likewise. + * sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/mips/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/not-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/tile/sysdep-cancel.h: Likewise. + * sysdeps/unix/sysv/linux/tile/waitpid.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: Likewise. + +Index: glibc-2.17-c758a686/include/mqueue.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/mqueue.h ++++ glibc-2.17-c758a686/include/mqueue.h +@@ -1,6 +1,6 @@ + #include + +-#ifdef IS_IN_librt ++#if IS_IN (librt) + hidden_proto (mq_timedsend) + hidden_proto (mq_timedreceive) + hidden_proto (mq_setattr) +Index: glibc-2.17-c758a686/nptl/pthreadP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthreadP.h ++++ glibc-2.17-c758a686/nptl/pthreadP.h +@@ -289,7 +289,7 @@ __do_cancel (void) + # define LIBC_CANCEL_HANDLED() \ + __asm (".globl " __SYMBOL_PREFIX "__pthread_enable_asynccancel"); \ + __asm (".globl " __SYMBOL_PREFIX "__pthread_disable_asynccancel") +-#elif defined IS_IN_librt ++#elif IS_IN (librt) + # define LIBC_CANCEL_ASYNC() \ + __librt_enable_asynccancel () + # define LIBC_CANCEL_RESET(val) \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -89,7 +89,7 @@ ENTRY (name); \ + # define CENABLE bl __libc_enable_asynccancel + # define CDISABLE bl __libc_disable_asynccancel + # define __local_multiple_threads __libc_multiple_threads +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE bl __librt_enable_asynccancel + # define CDISABLE bl __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + /* NOTE: We do mark syscalls with unwind annotations, for the benefit of + cancellation; but they're really only accurate at the point of the +@@ -194,7 +194,7 @@ + # define CENABLE bl PLTJMP(__libc_enable_asynccancel) + # define CDISABLE bl PLTJMP(__libc_disable_asynccancel) + # define __local_multiple_threads __libc_multiple_threads +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE bl PLTJMP(__librt_enable_asynccancel) + # define CDISABLE bl PLTJMP(__librt_disable_asynccancel) + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -114,7 +114,7 @@ + # elif !defined NOT_IN_libc + # define CENABLE call __libc_enable_asynccancel; + # define CDISABLE call __libc_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE call __librt_enable_asynccancel; + # define CDISABLE call __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/not-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/not-cancel.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/not-cancel.h +@@ -27,7 +27,7 @@ + INLINE_SYSCALL (open, 2, (const char *) (name), (flags)) + + /* Uncancelable openat. */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + extern int __openat_nocancel (int fd, const char *fname, int oflag, + mode_t mode) attribute_hidden; + extern int __openat64_nocancel (int fd, const char *fname, int oflag, +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -87,7 +87,7 @@ + # elif !defined NOT_IN_libc + # define CENABLE bl __libc_enable_asynccancel@local + # define CDISABLE bl __libc_disable_asynccancel@local +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE bl __librt_enable_asynccancel@local + # define CDISABLE bl __librt_disable_asynccancel@local + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # ifdef HAVE_ASM_GLOBAL_DOT_NAME + # define DASHDASHPFX(str) .__##str +@@ -115,7 +115,7 @@ + # define CENABLE bl JUMPTARGET(__libc_enable_asynccancel); nop + # define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel); nop + # endif +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # ifdef SHARED + # define CENABLE bl JUMPTARGET(__librt_enable_asynccancel) + # define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -81,7 +81,7 @@ L(pseudo_end): + # elif !defined NOT_IN_libc + # define CENABLE __libc_enable_asynccancel + # define CDISABLE __libc_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE __librt_enable_asynccancel + # define CDISABLE __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -77,7 +77,7 @@ L(pseudo_end): + # define CENABLE __libc_enable_asynccancel + # define CDISABLE __libc_disable_asynccancel + # define __local_multiple_threads __libc_multiple_threads +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE __librt_enable_asynccancel + # define CDISABLE __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + /* The code to disable cancellation depends on the fact that the called + functions are special. They don't modify registers other than %rax +@@ -67,7 +67,7 @@ + # define CENABLE call __libc_enable_asynccancel; + # define CDISABLE call __libc_disable_asynccancel; + # define __local_multiple_threads __libc_multiple_threads +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE call __librt_enable_asynccancel; + # define CDISABLE call __librt_disable_asynccancel; + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/not-cancel.h +@@ -19,7 +19,7 @@ + + #include + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + extern int __open_nocancel (const char *, int, ...) attribute_hidden; + extern int __close_nocancel (int) attribute_hidden; + extern int __read_nocancel (int, void *, size_t) attribute_hidden; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # define _IMM12 #-12 + # define _IMM16 #-16 +@@ -111,7 +111,7 @@ + # elif !defined NOT_IN_libc + # define __local_enable_asynccancel __libc_enable_asynccancel + # define __local_disable_asynccancel __libc_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define __local_enable_asynccancel __librt_enable_asynccancel + # define __local_disable_asynccancel __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -74,7 +74,7 @@ __##syscall_name##_nocancel: \ + # elif !defined NOT_IN_libc + # define CENABLE call __libc_enable_asynccancel + # define CDISABLE call __libc_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE call __librt_enable_asynccancel + # define CDISABLE call __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -72,7 +72,7 @@ __##syscall_name##_nocancel: \ + # elif !defined NOT_IN_libc + # define CENABLE call __libc_enable_asynccancel + # define CDISABLE call __libc_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE call __librt_enable_asynccancel + # define CDISABLE call __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/alpha/nptl/sysdep-cancel.h +@@ -21,7 +21,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + /* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END + besides "ret". */ +@@ -113,7 +113,7 @@ __LABEL($multi_error) \ + # define __local_enable_asynccancel __libc_enable_asynccancel + # define __local_disable_asynccancel __libc_disable_asynccancel + # define __local_multiple_threads __libc_multiple_threads +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define __local_enable_asynccancel __librt_enable_asynccancel + # define __local_disable_asynccancel __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/am33/linuxthreads/sysdep-cancel.h +@@ -23,7 +23,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -82,7 +82,7 @@ + # ifdef IS_IN_libpthread + # define CENABLE call __pthread_enable_asynccancel,[],0; + # define CDISABLE call __pthread_disable_asynccancel,[],0; +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # ifdef PIC + # define CENABLE movm [a2],(sp); \ + 1: mov pc,a2; \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/hppa/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # ifndef NO_ERROR + # define NO_ERROR -0x1000 +@@ -228,7 +228,7 @@ L(pre_end): ASM_LINE_SEP \ + # define CDISABLE .import __libc_disable_asynccancel,code ASM_LINE_SEP \ + bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP + # endif +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # ifdef PIC + # define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \ + bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP +@@ -248,7 +248,7 @@ L(pre_end): ASM_LINE_SEP \ + # define __local_multiple_threads __pthread_multiple_threads + # elif !defined NOT_IN_libc + # define __local_multiple_threads __libc_multiple_threads +-# elif IS_IN_librt ++# elif IS_IN (librt) + # define __local_multiple_threads __librt_multiple_threads + # else + # error Unsupported library +@@ -271,7 +271,7 @@ L(pre_end): ASM_LINE_SEP \ + # define NO_CANCELLATION 1 + + #endif +-/* !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt */ ++/* !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) */ + + #ifndef __ASSEMBLER__ + # define RTLD_SINGLE_THREAD_P \ +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + +@@ -166,7 +166,7 @@ __GC_##name: \ + # elif !defined NOT_IN_libc + # define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel + # define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE br.call.sptk.many b0 = __librt_enable_asynccancel + # define CDISABLE br.call.sptk.many b0 = __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/sysdep.h +@@ -62,7 +62,7 @@ + + #if defined USE_DL_SYSINFO \ + && (!defined NOT_IN_libc \ +- || IS_IN (libpthread) || defined IS_IN_librt) ++ || IS_IN (libpthread) || IS_IN (librt)) + # define IA64_USE_NEW_STUB + #else + # undef IA64_USE_NEW_STUB +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/m68k/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # undef PSEUDO + # define PSEUDO(name, syscall_name, args) \ +@@ -106,7 +106,7 @@ + # elif !defined NOT_IN_libc + # define CENABLE PSEUDO_JMP (__libc_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel) +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE PSEUDO_JMP (__librt_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel) + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h +@@ -27,7 +27,7 @@ + happen before any instructions. So we use cfi_same_value instead of + cfi_restore. */ + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + #ifdef __PIC__ + # undef PSEUDO +@@ -149,7 +149,7 @@ + # ifdef IS_IN_libpthread + # define CENABLE PTR_LA t9, __pthread_enable_asynccancel; jalr t9 + # define CDISABLE PTR_LA t9, __pthread_disable_asynccancel; jalr t9 +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE PTR_LA t9, __librt_enable_asynccancel; jalr t9 + # define CDISABLE PTR_LA t9, __librt_disable_asynccancel; jalr t9 + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + # ifdef __PIC__ + # define PSEUDO_CPLOAD .cpload t9; +@@ -155,7 +155,7 @@ + # ifdef IS_IN_libpthread + # define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel) +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE PSEUDO_JMP (__librt_enable_asynccancel) + # define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel) + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/sysdep-cancel.h +@@ -22,7 +22,7 @@ + # include + #endif + +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + /* Allow hacking in some extra code if desired. */ + #ifndef PSEUDO_EXTRA +@@ -120,7 +120,7 @@ + # ifdef IS_IN_libpthread + # define CENABLE jal __pthread_enable_asynccancel + # define CDISABLE jal __pthread_disable_asynccancel +-# elif defined IS_IN_librt ++# elif IS_IN (librt) + # define CENABLE jal __librt_enable_asynccancel + # define CDISABLE jal __librt_disable_asynccancel + # else +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/tile/nptl/waitpid.S +@@ -1,7 +1,7 @@ + /* + extern pid_t __waitpid_nocancel (pid_t, int *, int) attribute_hidden; + */ +-#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt ++#if !defined NOT_IN_libc || defined IS_IN_libpthread || IS_IN (librt) + + /* Call __NR_wait4, providing fourth argument (struct rusage *) as NULL. */ + #define PSEUDO_EXTRA move r3, zero; diff --git a/SOURCES/glibc-rh1256317-8.patch b/SOURCES/glibc-rh1256317-8.patch new file mode 100644 index 00000000..f6ba1f82 --- /dev/null +++ b/SOURCES/glibc-rh1256317-8.patch @@ -0,0 +1,135 @@ +commit 9b42a0b3a3cc037e6bdd62869d91cb19c80aa0e5 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 13:17:21 2014 +0530 + + Remove IS_IN_libdl + + Replace with IS_IN (libdl). No changes to generated code on x86_64. + + * dlfcn/dladdr.c: Use IS_IN. + * dlfcn/dladdr1.c: Likewise. + * dlfcn/dlclose.c: Likewise. + * dlfcn/dlerror.c: Likewise. + * dlfcn/dlinfo.c: Likewise. + * dlfcn/dlmopen.c: Likewise. + * dlfcn/dlopen.c: Likewise. + * dlfcn/dlsym.c: Likewise. + * dlfcn/dlvsym.c: Likewise. + +Index: glibc-2.17-c758a686/dlfcn/dladdr.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dladdr.c ++++ glibc-2.17-c758a686/dlfcn/dladdr.c +@@ -19,7 +19,7 @@ + + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + int + dladdr (const void *address, Dl_info *info) +Index: glibc-2.17-c758a686/dlfcn/dladdr1.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dladdr1.c ++++ glibc-2.17-c758a686/dlfcn/dladdr1.c +@@ -18,7 +18,7 @@ + + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + int + dladdr1 (const void *address, Dl_info *info, void **extra, int flags) +Index: glibc-2.17-c758a686/dlfcn/dlclose.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlclose.c ++++ glibc-2.17-c758a686/dlfcn/dlclose.c +@@ -20,7 +20,7 @@ + #include + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + int + dlclose (void *handle) +Index: glibc-2.17-c758a686/dlfcn/dlerror.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlerror.c ++++ glibc-2.17-c758a686/dlfcn/dlerror.c +@@ -25,7 +25,7 @@ + #include + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + char * + dlerror (void) +Index: glibc-2.17-c758a686/dlfcn/dlinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlinfo.c ++++ glibc-2.17-c758a686/dlfcn/dlinfo.c +@@ -21,7 +21,7 @@ + #include + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + int + dlinfo (void *handle, int request, void *arg) +Index: glibc-2.17-c758a686/dlfcn/dlmopen.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlmopen.c ++++ glibc-2.17-c758a686/dlfcn/dlmopen.c +@@ -23,7 +23,7 @@ + #include + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + void * + dlmopen (Lmid_t nsid, const char *file, int mode) +Index: glibc-2.17-c758a686/dlfcn/dlopen.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlopen.c ++++ glibc-2.17-c758a686/dlfcn/dlopen.c +@@ -22,7 +22,7 @@ + #include + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + void * + dlopen (const char *file, int mode) +Index: glibc-2.17-c758a686/dlfcn/dlsym.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlsym.c ++++ glibc-2.17-c758a686/dlfcn/dlsym.c +@@ -21,7 +21,7 @@ + + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + void * + dlsym (void *handle, const char *name) +Index: glibc-2.17-c758a686/dlfcn/dlvsym.c +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/dlvsym.c ++++ glibc-2.17-c758a686/dlfcn/dlvsym.c +@@ -21,7 +21,7 @@ + + #include + +-#if !defined SHARED && defined IS_IN_libdl ++#if !defined SHARED && IS_IN (libdl) + + void * + weak_function diff --git a/SOURCES/glibc-rh1256317-9.patch b/SOURCES/glibc-rh1256317-9.patch new file mode 100644 index 00000000..79b181c5 --- /dev/null +++ b/SOURCES/glibc-rh1256317-9.patch @@ -0,0 +1,74 @@ +commit 85f36372aa9b7c4f8e1ebb6a3bf2c0785a019612 +Author: Siddhesh Poyarekar +Date: Thu Nov 20 13:12:02 2014 +0530 + + Remove IS_IN_nscd + + Replace with IS_IN (nscd). Generated code unchanged on x86_64. + + * include/ifaddrs.h: Use IS_IN. + * inet/check_pf.c: Likewise. + * sysdeps/unix/sysv/linux/check_pf.c: Likewise. + * nscd/Makefile (CPPFLAGS-nscd): Remove IS_IN_nscd. + +Index: glibc-2.17-c758a686/include/ifaddrs.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/ifaddrs.h ++++ glibc-2.17-c758a686/include/ifaddrs.h +@@ -26,7 +26,7 @@ extern void __check_native (uint32_t a1_ + uint32_t a2_index, int *a2_native) + attribute_hidden; + +-#ifdef IS_IN_nscd ++#if IS_IN (nscd) + extern uint32_t __bump_nl_timestamp (void) attribute_hidden; + #endif + +Index: glibc-2.17-c758a686/inet/check_pf.c +=================================================================== +--- glibc-2.17-c758a686.orig/inet/check_pf.c ++++ glibc-2.17-c758a686/inet/check_pf.c +@@ -62,7 +62,7 @@ __free_in6ai (struct in6addrinfo *in6ai) + } + + +-#ifdef IS_IN_nscd ++#if IS_IN (nscd) + uint32_t + __bump_nl_timestamp (void) + { +Index: glibc-2.17-c758a686/nscd/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nscd/Makefile ++++ glibc-2.17-c758a686/nscd/Makefile +@@ -79,7 +79,7 @@ CFLAGS-nscd_gethst_r.c = -fexceptions + CFLAGS-nscd_getai.c = -fexceptions + CFLAGS-nscd_initgroups.c = -fexceptions + +-CPPFLAGS-nscd += -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2 -DNOT_IN_libc=1 ++CPPFLAGS-nscd += -D_FORTIFY_SOURCE=2 -DNOT_IN_libc + + ifeq (yesyes,$(have-fpie)$(build-shared)) + CFLAGS-nscd += $(pie-ccflag) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/check_pf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/check_pf.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/check_pf.c +@@ -65,7 +65,7 @@ libc_freeres_ptr (static struct cached_d + __libc_lock_define_initialized (static, lock); + + +-#ifdef IS_IN_nscd ++#if IS_IN (nscd) + static uint32_t nl_timestamp; + + uint32_t +@@ -81,7 +81,7 @@ __bump_nl_timestamp (void) + static inline uint32_t + get_nl_timestamp (void) + { +-#ifdef IS_IN_nscd ++#if IS_IN (nscd) + return nl_timestamp; + #elif defined USE_NSCD + return __nscd_get_nl_timestamp (); diff --git a/SOURCES/glibc-rh1268008-1.patch b/SOURCES/glibc-rh1268008-1.patch new file mode 100644 index 00000000..04023c3a --- /dev/null +++ b/SOURCES/glibc-rh1268008-1.patch @@ -0,0 +1,97 @@ +From c58ed232c3d94c9ad7b4acddb8593ae0b1f9db10 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:16:32 +0200 +Subject: [PATCH 01/30] S/390: Unify 31 and 64 bit configure.in + +upstream-commit-id: 579db35a068e70a4f3112000778138ede6994ac0 + +This patch is needed to prepare for the optimized string function patchset. +The configure fragments for s390-32/64 are identical and thus unified to one +configure file. + +--- + sysdeps/s390/configure | 5 +++++ + sysdeps/s390/configure.in | 6 ++++++ + sysdeps/s390/s390-32/configure | 5 ----- + sysdeps/s390/s390-32/configure.in | 6 ------ + sysdeps/s390/s390-64/configure | 5 ----- + sysdeps/s390/s390-64/configure.in | 6 ------ + 6 files changed, 11 insertions(+), 22 deletions(-) + create mode 100644 sysdeps/s390/configure + create mode 100644 sysdeps/s390/configure.in + delete mode 100644 sysdeps/s390/s390-32/configure + delete mode 100644 sysdeps/s390/s390-32/configure.in + delete mode 100644 sysdeps/s390/s390-64/configure + delete mode 100644 sysdeps/s390/s390-64/configure.in + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +new file mode 100644 +index 0000000..669bb9b +--- /dev/null ++++ b/sysdeps/s390/configure +@@ -0,0 +1,5 @@ ++# This file is generated from configure.in by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/s390. ++ ++$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h ++ +diff --git a/sysdeps/s390/configure.in b/sysdeps/s390/configure.in +new file mode 100644 +index 0000000..b5af4e1 +--- /dev/null ++++ b/sysdeps/s390/configure.in +@@ -0,0 +1,6 @@ ++GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. ++# Local configure fragment for sysdeps/s390. ++ ++dnl It is always possible to access static and hidden symbols in an ++dnl position independent way. ++AC_DEFINE(PI_STATIC_AND_HIDDEN) +diff --git a/sysdeps/s390/s390-32/configure b/sysdeps/s390/s390-32/configure +deleted file mode 100644 +index 669bb9b..0000000 +--- a/sysdeps/s390/s390-32/configure ++++ /dev/null +@@ -1,5 +0,0 @@ +-# This file is generated from configure.in by Autoconf. DO NOT EDIT! +- # Local configure fragment for sysdeps/s390. +- +-$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h +- +diff --git a/sysdeps/s390/s390-32/configure.in b/sysdeps/s390/s390-32/configure.in +deleted file mode 100644 +index b5af4e1..0000000 +--- a/sysdeps/s390/s390-32/configure.in ++++ /dev/null +@@ -1,6 +0,0 @@ +-GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +-# Local configure fragment for sysdeps/s390. +- +-dnl It is always possible to access static and hidden symbols in an +-dnl position independent way. +-AC_DEFINE(PI_STATIC_AND_HIDDEN) +diff --git a/sysdeps/s390/s390-64/configure b/sysdeps/s390/s390-64/configure +deleted file mode 100644 +index 669bb9b..0000000 +--- a/sysdeps/s390/s390-64/configure ++++ /dev/null +@@ -1,5 +0,0 @@ +-# This file is generated from configure.in by Autoconf. DO NOT EDIT! +- # Local configure fragment for sysdeps/s390. +- +-$as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h +- +diff --git a/sysdeps/s390/s390-64/configure.in b/sysdeps/s390/s390-64/configure.in +deleted file mode 100644 +index b5af4e1..0000000 +--- a/sysdeps/s390/s390-64/configure.in ++++ /dev/null +@@ -1,6 +0,0 @@ +-GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +-# Local configure fragment for sysdeps/s390. +- +-dnl It is always possible to access static and hidden symbols in an +-dnl position independent way. +-AC_DEFINE(PI_STATIC_AND_HIDDEN) +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-10.patch b/SOURCES/glibc-rh1268008-10.patch new file mode 100644 index 00000000..7f7458e2 --- /dev/null +++ b/SOURCES/glibc-rh1268008-10.patch @@ -0,0 +1,478 @@ +From cca51a74315c37614042113b004505b150d305d7 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:54:21 +0200 +Subject: [PATCH 10/30] S390: Optimize strlen and wcslen. + +upstream-commit-id: 9472f35a0a6dbbda82ce103aaf0f5013f5d46e34 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00089.html + +This patch provides optimized versions of strlen and wcslen with the z13 vector +instructions. +The helper macro IFUNC_VX_IMPL is introduced and is used to register all +___c() and ___vx() functions within __libc_ifunc_impl_list() +to the ifunc test framework. + +ChangeLog: + + * sysdeps/s390/multiarch/Makefile: New File. + * sysdeps/s390/multiarch/strlen-c.c: Likewise. + * sysdeps/s390/multiarch/strlen-vx.S: Likewise. + * sysdeps/s390/multiarch/strlen.c: Likewise. + * sysdeps/s390/multiarch/wcslen-c.c: Likewise. + * sysdeps/s390/multiarch/wcslen-vx.S: Likewise. + * sysdeps/s390/multiarch/wcslen.c: Likewise. + * string/strlen.c (STRLEN): Define and use macro. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (IFUNC_VX_IMPL): New macro function. + (__libc_ifunc_impl_list): Add ifunc test for strlen, wcslen. + * benchtests/Makefile (wcsmbs-bench): New variable. + (string-bench-all): Added wcsmbs-bench. + * benchtests/bench-wcslen.c: New File. +--- + benchtests/Makefile | 3 +- + benchtests/bench-wcslen.c | 20 +++++++ + string/strlen.c | 7 ++- + sysdeps/s390/multiarch/Makefile | 7 +++ + sysdeps/s390/multiarch/ifunc-impl-list.c | 14 +++++ + sysdeps/s390/multiarch/strlen-c.c | 28 ++++++++++ + sysdeps/s390/multiarch/strlen-vx.S | 84 +++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strlen.c | 27 ++++++++++ + sysdeps/s390/multiarch/wcslen-c.c | 25 +++++++++ + sysdeps/s390/multiarch/wcslen-vx.S | 91 ++++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcslen.c | 28 ++++++++++ + 11 files changed, 331 insertions(+), 3 deletions(-) + create mode 100644 benchtests/bench-wcslen.c + create mode 100644 sysdeps/s390/multiarch/Makefile + create mode 100644 sysdeps/s390/multiarch/strlen-c.c + create mode 100644 sysdeps/s390/multiarch/strlen-vx.S + create mode 100644 sysdeps/s390/multiarch/strlen.c + create mode 100644 sysdeps/s390/multiarch/wcslen-c.c + create mode 100644 sysdeps/s390/multiarch/wcslen-vx.S + create mode 100644 sysdeps/s390/multiarch/wcslen.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 9b02bc7..09ab87f 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,8 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-string-bench-all := $(string-bench) ++wcsmbs-bench := wcslen ++string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod + +diff --git a/benchtests/bench-wcslen.c b/benchtests/bench-wcslen.c +new file mode 100644 +index 0000000..4e9d085 +--- /dev/null ++++ b/benchtests/bench-wcslen.c +@@ -0,0 +1,20 @@ ++/* Measure wcslen functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strlen.c" +diff --git a/string/strlen.c b/string/strlen.c +index 5c1efda..d682693 100644 +--- a/string/strlen.c ++++ b/string/strlen.c +@@ -23,11 +23,14 @@ + + #undef strlen + ++#ifndef STRLEN ++# define STRLEN strlen ++#endif ++ + /* Return the length of the null-terminated string STR. Scan for + the null terminator quickly by testing four bytes at a time. */ + size_t +-strlen (str) +- const char *str; ++STRLEN (const char *str) + { + const char *char_ptr; + const unsigned long int *longword_ptr; +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +new file mode 100644 +index 0000000..3a98098 +--- /dev/null ++++ b/sysdeps/s390/multiarch/Makefile +@@ -0,0 +1,7 @@ ++ifeq ($(subdir),string) ++sysdep_routines += strlen strlen-vx strlen-c ++endif ++ ++ifeq ($(subdir),wcsmbs) ++sysdep_routines += wcslen wcslen-vx wcslen-c ++endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c330904..e9639ef 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + #include + #include + +@@ -70,5 +71,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + #endif /* SHARED */ + ++#ifdef HAVE_S390_VX_ASM_SUPPORT ++ ++# define IFUNC_VX_IMPL(FUNC) \ ++ IFUNC_IMPL (i, name, FUNC, \ ++ IFUNC_IMPL_ADD (array, i, FUNC, dl_hwcap & HWCAP_S390_VX, \ ++ __##FUNC##_vx) \ ++ IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) ++ ++ IFUNC_VX_IMPL (strlen); ++ IFUNC_VX_IMPL (wcslen); ++ ++#endif /* HAVE_S390_VX_ASM_SUPPORT */ ++ + return i; + } +diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/multiarch/strlen-c.c +new file mode 100644 +index 0000000..1cbe959 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strlen-c.c +@@ -0,0 +1,28 @@ ++/* Default strlen implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRLEN __strlen_c ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/multiarch/strlen-vx.S +new file mode 100644 +index 0000000..1a5cb23 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strlen-vx.S +@@ -0,0 +1,84 @@ ++/* Vector optimized 32/64 bit S/390 version of strlen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t strlen (const char *s) ++ Returns length of string s. ++ ++ Register usage: ++ -r1=bytes to 4k-byte boundary ++ -r2=s ++ -r3=tmp ++ -r4=tmp ++ -r5=current_len and return_value ++ -v16=part of s ++*/ ++ENTRY(__strlen_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */ ++ clr %r4,%r1 /* If found zero within loaded bytes? */ ++ locgrl %r2,%r4 /* Then copy return value. */ ++ blr %r14 /* And return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r3 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find zero in 16 byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No zero found -> loop. */ ++ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r2,%v16,7 /* Load byte index of zero. */ ++ algr %r2,%r5 ++ br %r14 ++END(__strlen_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c +new file mode 100644 +index 0000000..ba5863f +--- /dev/null ++++ b/sysdeps/s390/multiarch/strlen.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of strlen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strlen, strlen) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcslen-c.c b/sysdeps/s390/multiarch/wcslen-c.c +new file mode 100644 +index 0000000..6dd011e +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcslen-c.c +@@ -0,0 +1,25 @@ ++/* Default wcslen implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSLEN __wcslen_c ++ ++# include ++extern __typeof (__wcslen) __wcslen_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcslen-vx.S b/sysdeps/s390/multiarch/wcslen-vx.S +new file mode 100644 +index 0000000..579e66b +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcslen-vx.S +@@ -0,0 +1,91 @@ ++/* Vector optimized 32/64 bit S/390 version of wcslen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t wcslen (const wchar_t *s) ++ Returns length of string s. ++ ++ Register usage: ++ -r1=bytes to 4k-byte boundary ++ -r2=s ++ -r3=tmp ++ -r4=tmp ++ -r5=current_len and return_value ++ -v16=part of s ++*/ ++ENTRY(__wcslen_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r4,%v16,7 /* Load zero index or 16 if not found. */ ++ clr %r4,%r1 /* If found zero within loaded bytes? */ ++ locgrl %r2,%r4 /* Then copy return value. */ ++ jl .Lend /* And return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r3,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r3 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No zero found -> loop. */ ++ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r2,%v16,7 /* Load byte index of zero. */ ++ algr %r2,%r5 ++.Lend: ++ srlg %r2,%r2,2 /* Convert byte-count to character-count. */ ++ br %r14 ++.Lfallback: ++ jg __wcslen_c ++END(__wcslen_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcslen.c b/sysdeps/s390/multiarch/wcslen.c +new file mode 100644 +index 0000000..a7be73e +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcslen.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcslen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcslen) ++weak_alias (__wcslen, wcslen) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-11.patch b/SOURCES/glibc-rh1268008-11.patch new file mode 100644 index 00000000..a07939f8 --- /dev/null +++ b/SOURCES/glibc-rh1268008-11.patch @@ -0,0 +1,961 @@ +From 1a569200bc2875ffc474587fb6ec599aac4bad9b Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:56:59 +0200 +Subject: [PATCH 11/30] S390: Optimize strnlen and wcsnlen. + +upstream-commit-id: fcf40ebe2682fd65d64f94d69a3df798960cf1b7 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00082.html + +This patch provides optimized versions of strnlen and wcsnlen with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strnlen-c.c: New File. + * sysdeps/s390/multiarch/strnlen-vx.S: Likewise. + * sysdeps/s390/multiarch/strnlen.c: Likewise. + * sysdeps/s390/multiarch/wcsnlen-c.c: Likewise. + * sysdeps/s390/multiarch/wcsnlen-vx.S: Likewise. + * sysdeps/s390/multiarch/wcsnlen.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strnlen and + wcsnlen functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strnlen, wcsnlen. + * wcsmbs/wcsnlen.c: Use WCSNLEN if defined. + * string/test-strnlen.c: Add wcsnlen support. + * wcsmbs/test-wcsnlen.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcsnlen. + * benchtests/bench-strnlen.c: Add wcsnlen support. + * benchtests/bench-wcsnlen.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcsnlen. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strnlen.c | 73 +++++++++------ + benchtests/bench-wcsnlen.c | 20 ++++ + string/test-strnlen.c | 87 +++++++++++------- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strnlen-c.c | 28 ++++++ + sysdeps/s390/multiarch/strnlen-vx.S | 134 +++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strnlen.c | 29 ++++++ + sysdeps/s390/multiarch/wcsnlen-c.c | 25 +++++ + sysdeps/s390/multiarch/wcsnlen-vx.S | 151 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcsnlen.c | 28 ++++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcsnlen-ifunc.c | 20 ++++ + wcsmbs/test-wcsnlen.c | 20 ++++ + wcsmbs/wcsnlen.c | 7 +- + 16 files changed, 571 insertions(+), 64 deletions(-) + create mode 100644 benchtests/bench-wcsnlen.c + create mode 100644 sysdeps/s390/multiarch/strnlen-c.c + create mode 100644 sysdeps/s390/multiarch/strnlen-vx.S + create mode 100644 sysdeps/s390/multiarch/strnlen.c + create mode 100644 sysdeps/s390/multiarch/wcsnlen-c.c + create mode 100644 sysdeps/s390/multiarch/wcsnlen-vx.S + create mode 100644 sysdeps/s390/multiarch/wcsnlen.c + create mode 100644 wcsmbs/test-wcsnlen-ifunc.c + create mode 100644 wcsmbs/test-wcsnlen.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 09ab87f..7bb2eef 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen ++wcsmbs-bench := wcslen wcsnlen + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strnlen.c b/benchtests/bench-strnlen.c +index 793f9be..cbdce75 100644 +--- a/benchtests/bench-strnlen.c ++++ b/benchtests/bench-strnlen.c +@@ -1,5 +1,5 @@ + /* Measure strlen functions. +- Copyright (C) 2013 Free Software Foundation, Inc. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,17 +17,36 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strnlen" ++#ifndef WIDE ++# define TEST_NAME "strnlen" ++#else ++# define TEST_NAME "wcsnlen" ++#endif /* WIDE */ + #include "bench-string.h" + +-typedef size_t (*proto_t) (const char *, size_t); +-size_t simple_strnlen (const char *, size_t); +- +-IMPL (simple_strnlen, 0) +-IMPL (strnlen, 1) ++#ifndef WIDE ++# define STRNLEN strnlen ++# define CHAR char ++# define BIG_CHAR CHAR_MAX ++# define MIDDLE_CHAR 127 ++# define SIMPLE_STRNLEN simple_strnlen ++#else ++# include ++# define STRNLEN wcsnlen ++# define CHAR wchar_t ++# define BIG_CHAR WCHAR_MAX ++# define MIDDLE_CHAR 1121 ++# define SIMPLE_STRNLEN simple_wcsnlen ++#endif /* WIDE */ ++ ++typedef size_t (*proto_t) (const CHAR *, size_t); ++size_t SIMPLE_STRNLEN (const CHAR *, size_t); ++ ++IMPL (SIMPLE_STRNLEN, 0) ++IMPL (STRNLEN, 1) + + size_t +-simple_strnlen (const char *s, size_t maxlen) ++SIMPLE_STRNLEN (const CHAR *s, size_t maxlen) + { + size_t i; + +@@ -36,7 +55,7 @@ simple_strnlen (const char *s, size_t maxlen) + } + + static void +-do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len) ++do_one_test (impl_t *impl, const CHAR *s, size_t maxlen, size_t exp_len) + { + size_t len = CALL (impl, s, maxlen), i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; +@@ -66,18 +85,20 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char) + { + size_t i; + +- align &= 7; +- if (align + len >= page_size) ++ align &= 63; ++ if ((align + len) * sizeof (CHAR) >= page_size) + return; + ++ CHAR *buf = (CHAR *) (buf1); ++ + for (i = 0; i < len; ++i) +- buf1[align + i] = 1 + 7 * i % max_char; +- buf1[align + len] = 0; ++ buf[align + i] = 1 + 7 * i % max_char; ++ buf[align + len] = 0; + + printf ("Length %4zd, alignment %2zd:", len, align); + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen)); ++ do_one_test (impl, (CHAR *) (buf + align), maxlen, MIN (len, maxlen)); + + putchar ('\n'); + } +@@ -96,34 +117,34 @@ test_main (void) + + for (i = 1; i < 8; ++i) + { +- do_test (0, i, i - 1, 127); +- do_test (0, i, i, 127); +- do_test (0, i, i + 1, 127); ++ do_test (0, i, i - 1, MIDDLE_CHAR); ++ do_test (0, i, i, MIDDLE_CHAR); ++ do_test (0, i, i + 1, MIDDLE_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (i, i, i - 1, 127); +- do_test (i, i, i, 127); +- do_test (i, i, i + 1, 127); ++ do_test (i, i, i - 1, MIDDLE_CHAR); ++ do_test (i, i, i, MIDDLE_CHAR); ++ do_test (i, i, i + 1, MIDDLE_CHAR); + } + + for (i = 2; i <= 10; ++i) + { +- do_test (0, 1 << i, 5000, 127); +- do_test (1, 1 << i, 5000, 127); ++ do_test (0, 1 << i, 5000, MIDDLE_CHAR); ++ do_test (1, 1 << i, 5000, MIDDLE_CHAR); + } + + for (i = 1; i < 8; ++i) +- do_test (0, i, 5000, 255); ++ do_test (0, i, 5000, BIG_CHAR); + + for (i = 1; i < 8; ++i) +- do_test (i, i, 5000, 255); ++ do_test (i, i, 5000, BIG_CHAR); + + for (i = 2; i <= 10; ++i) + { +- do_test (0, 1 << i, 5000, 255); +- do_test (1, 1 << i, 5000, 255); ++ do_test (0, 1 << i, 5000, BIG_CHAR); ++ do_test (1, 1 << i, 5000, BIG_CHAR); + } + + return ret; +diff --git a/benchtests/bench-wcsnlen.c b/benchtests/bench-wcsnlen.c +new file mode 100644 +index 0000000..2b5a51c +--- /dev/null ++++ b/benchtests/bench-wcsnlen.c +@@ -0,0 +1,20 @@ ++/* Measure wcsnlen functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strnlen.c" +diff --git a/string/test-strnlen.c b/string/test-strnlen.c +index ae959bf..43db896 100644 +--- a/string/test-strnlen.c ++++ b/string/test-strnlen.c +@@ -1,5 +1,5 @@ + /* Test and measure strlen functions. +- Copyright (C) 1999-2012 Free Software Foundation, Inc. ++ Copyright (C) 1999-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Jakub Jelinek , 1999. + +@@ -18,17 +18,36 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strnlen" ++#ifndef WIDE ++# define TEST_NAME "strnlen" ++#else ++# define TEST_NAME "wcsnlen" ++#endif /* !WIDE */ + #include "test-string.h" + +-typedef size_t (*proto_t) (const char *, size_t); +-size_t simple_strnlen (const char *, size_t); +- +-IMPL (simple_strnlen, 0) +-IMPL (strnlen, 1) ++#ifndef WIDE ++# define STRNLEN strnlen ++# define CHAR char ++# define BIG_CHAR CHAR_MAX ++# define MIDDLE_CHAR 127 ++# define SIMPLE_STRNLEN simple_strnlen ++#else ++# include ++# define STRNLEN wcsnlen ++# define CHAR wchar_t ++# define BIG_CHAR WCHAR_MAX ++# define MIDDLE_CHAR 1121 ++# define SIMPLE_STRNLEN simple_wcsnlen ++#endif /* !WIDE */ ++ ++typedef size_t (*proto_t) (const CHAR *, size_t); ++size_t SIMPLE_STRNLEN (const CHAR *, size_t); ++ ++IMPL (SIMPLE_STRNLEN, 0) ++IMPL (STRNLEN, 1) + + size_t +-simple_strnlen (const char *s, size_t maxlen) ++SIMPLE_STRNLEN (const CHAR *s, size_t maxlen) + { + size_t i; + +@@ -37,7 +56,7 @@ simple_strnlen (const char *s, size_t maxlen) + } + + static void +-do_one_test (impl_t *impl, const char *s, size_t maxlen, size_t exp_len) ++do_one_test (impl_t *impl, const CHAR *s, size_t maxlen, size_t exp_len) + { + size_t len = CALL (impl, s, maxlen); + if (len != exp_len) +@@ -54,23 +73,25 @@ do_test (size_t align, size_t len, size_t maxlen, int max_char) + { + size_t i; + +- align &= 7; +- if (align + len >= page_size) ++ align &= 63; ++ if ((align + len) * sizeof (CHAR) >= page_size) + return; + ++ CHAR *buf = (CHAR *) (buf1); ++ + for (i = 0; i < len; ++i) +- buf1[align + i] = 1 + 7 * i % max_char; +- buf1[align + len] = 0; ++ buf[align + i] = 1 + 7 * i % max_char; ++ buf[align + len] = 0; + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char *) (buf1 + align), maxlen, MIN (len, maxlen)); ++ do_one_test (impl, (CHAR *) (buf + align), maxlen, MIN (len, maxlen)); + } + + static void + do_random_tests (void) + { + size_t i, j, n, align, len; +- unsigned char *p = buf1 + page_size - 512; ++ CHAR *p = (CHAR *) (buf1 + page_size - 512 * sizeof (CHAR)); + + for (n = 0; n < ITERATIONS; n++) + { +@@ -97,25 +118,25 @@ do_random_tests (void) + FOR_EACH_IMPL (impl, 1) + { + if (len > 0 +- && CALL (impl, (char *) (p + align), len - 1) != len - 1) ++ && CALL (impl, (CHAR *) (p + align), len - 1) != len - 1) + { + error (0, 0, "Iteration %zd (limited) - wrong result in function %s (%zd) %zd != %zd, p %p", + n, impl->name, align, +- CALL (impl, (char *) (p + align), len - 1), len - 1, p); ++ CALL (impl, (CHAR *) (p + align), len - 1), len - 1, p); + ret = 1; + } +- if (CALL (impl, (char *) (p + align), len) != len) ++ if (CALL (impl, (CHAR *) (p + align), len) != len) + { + error (0, 0, "Iteration %zd (exact) - wrong result in function %s (%zd) %zd != %zd, p %p", + n, impl->name, align, +- CALL (impl, (char *) (p + align), len), len, p); ++ CALL (impl, (CHAR *) (p + align), len), len, p); + ret = 1; + } +- if (CALL (impl, (char *) (p + align), len + 1) != len) ++ if (CALL (impl, (CHAR *) (p + align), len + 1) != len) + { + error (0, 0, "Iteration %zd (long) - wrong result in function %s (%zd) %zd != %zd, p %p", + n, impl->name, align, +- CALL (impl, (char *) (p + align), len + 1), len, p); ++ CALL (impl, (CHAR *) (p + align), len + 1), len, p); + ret = 1; + } + } +@@ -136,34 +157,34 @@ test_main (void) + + for (i = 1; i < 8; ++i) + { +- do_test (0, i, i - 1, 127); +- do_test (0, i, i, 127); +- do_test (0, i, i + 1, 127); ++ do_test (0, i, i - 1, MIDDLE_CHAR); ++ do_test (0, i, i, MIDDLE_CHAR); ++ do_test (0, i, i + 1, MIDDLE_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (i, i, i - 1, 127); +- do_test (i, i, i, 127); +- do_test (i, i, i + 1, 127); ++ do_test (i, i, i - 1, MIDDLE_CHAR); ++ do_test (i, i, i, MIDDLE_CHAR); ++ do_test (i, i, i + 1, MIDDLE_CHAR); + } + + for (i = 2; i <= 10; ++i) + { +- do_test (0, 1 << i, 5000, 127); +- do_test (1, 1 << i, 5000, 127); ++ do_test (0, 1 << i, 5000, MIDDLE_CHAR); ++ do_test (1, 1 << i, 5000, MIDDLE_CHAR); + } + + for (i = 1; i < 8; ++i) +- do_test (0, i, 5000, 255); ++ do_test (0, i, 5000, BIG_CHAR); + + for (i = 1; i < 8; ++i) +- do_test (i, i, 5000, 255); ++ do_test (i, i, 5000, BIG_CHAR); + + for (i = 2; i <= 10; ++i) + { +- do_test (0, 1 << i, 5000, 255); +- do_test (1, 1 << i, 5000, 255); ++ do_test (0, 1 << i, 5000, BIG_CHAR); ++ do_test (1, 1 << i, 5000, BIG_CHAR); + } + + do_random_tests (); +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3a98098..3397f24 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,7 +1,9 @@ + ifeq ($(subdir),string) +-sysdep_routines += strlen strlen-vx strlen-c ++sysdep_routines += strlen strlen-vx strlen-c \ ++ strnlen strnlen-vx strnlen-c + endif + + ifeq ($(subdir),wcsmbs) +-sysdep_routines += wcslen wcslen-vx wcslen-c ++sysdep_routines += wcslen wcslen-vx wcslen-c \ ++ wcsnlen wcsnlen-vx wcsnlen-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index e9639ef..bc17c59 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -82,6 +82,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strlen); + IFUNC_VX_IMPL (wcslen); + ++ IFUNC_VX_IMPL (strnlen); ++ IFUNC_VX_IMPL (wcsnlen); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/multiarch/strnlen-c.c +new file mode 100644 +index 0000000..50fc688 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strnlen-c.c +@@ -0,0 +1,28 @@ ++/* Default strnlen implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRNLEN __strnlen_c ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__strnlen_c, __GI_strnlen, __strnlen_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/multiarch/strnlen-vx.S +new file mode 100644 +index 0000000..8c15621 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strnlen-vx.S +@@ -0,0 +1,134 @@ ++/* Vector optimized 32/64 bit S/390 version of strnlen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t strnlen (const char *s, size_t maxlen) ++ Returns the number of characters in s or at most maxlen. ++ ++ Register usage: ++ -r1=tmp ++ -r2=address of string ++ -r3=maxlen (number of characters to be read) ++ -r4=tmp ++ -r5=current_len and return_value ++ -v16=part of s ++*/ ++ENTRY(__strnlen_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r3,%r3 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r3,0 /* if maxlen == 0, return 0. */ ++ locgre %r2,%r3 ++ ber %r14 ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r1,%r1 /* Convert 32bit to 64bit. */ ++ ++ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ clgr %r1,%r3 ++ locgrh %r1,%r3 /* loaded_byte_count ++ = min (loaded_byte_count, maxlen) */ ++ ++ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ ++ clr %r5,%r1 /* If found zero within loaded bytes? */ ++ locgrl %r2,%r5 /* Then copy return value. */ ++ blr %r14 /* And return. */ ++ ++ clgr %r1,%r3 /* If loaded_byte_count == maxlen? */ ++ locgre %r2,%r3 /* Then copy return value. */ ++ ber %r14 /* And return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r3,.Lloop64 ++ ++ /* Find zero in max 64byte with aligned s. */ ++.Llt64: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound /* Jump away if zero was found. */ ++ aghi %r5,16 ++ clgrjhe %r5,%r3,.Lfound /* current_len >= maxlen -> end. */ ++ vl %v16,0(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound ++ aghi %r5,16 ++ clgrjhe %r5,%r3,.Lfound ++ vl %v16,0(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound ++ aghi %r5,16 ++ clgrjhe %r5,%r3,.Lfound ++ vl %v16,0(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ j .Lfound ++ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */ ++ algr %r5,%r4 ++ ++ clgr %r5,%r3 ++ locgrh %r5,%r3 /* Return min (current_len, maxlen). */ ++ lgr %r2,%r5 ++ br %r14 ++ ++ /* Find zero in 16 byte aligned loop. */ ++.Lloop64: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Lfound48 ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r3,.Lloop64 ++ ++ j .Llt64 ++END(__strnlen_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c +new file mode 100644 +index 0000000..f036fcd +--- /dev/null ++++ b/sysdeps/s390/multiarch/strnlen.c +@@ -0,0 +1,29 @@ ++/* Multiple versions of strnlen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__strnlen) ++weak_alias (__strnlen, strnlen) ++libc_hidden_def (strnlen) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/multiarch/wcsnlen-c.c +new file mode 100644 +index 0000000..6d8b537 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsnlen-c.c +@@ -0,0 +1,25 @@ ++/* Default wcsnlen implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSNLEN __wcsnlen_c ++ ++# include ++extern __typeof (__wcsnlen) __wcsnlen_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcsnlen-vx.S b/sysdeps/s390/multiarch/wcsnlen-vx.S +new file mode 100644 +index 0000000..8c21630 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsnlen-vx.S +@@ -0,0 +1,151 @@ ++/* Vector optimized 32/64 bit S/390 version of wcsnlen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t wcsnlen (const wchar_t *s, size_t maxlen) ++ Returns the number of characters in s or at most maxlen. ++ ++ Register usage: ++ -r1=tmp ++ -r2=address of string ++ -r3=maxlen (number of characters to be read) ++ -r4=tmp ++ -r5=current_len and return_value ++ -v16=part of s ++*/ ++ENTRY(__wcsnlen_vx) ++ ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r3,%r3 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r3,0 /* if maxlen == 0, return 0. */ ++ locgre %r2,%r3 ++ ber %r14 ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r1,%r1 /* Convert 32bit to 64bit. */ ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r3,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r4,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r3,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r4,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r3,%r3,2 /* Convert character-count to byte-count. */ ++ locgrne %r3,%r4 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ clgr %r1,%r3 ++ locgrh %r1,%r3 /* loaded_byte_count ++ = min (loaded_byte_count, maxlen) */ ++ ++ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lend /* Found zero within loaded bytes -> return. */ ++ ++ clgr %r1,%r3 /* If loaded_byte_count == maxlen -> end. */ ++ locgre %r5,%r3 ++ je .Lend ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r3,.Lloop64 ++ ++ /* Find zero in max 64byte with aligned s. */ ++.Llt64: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound /* Jump away if zero was found. */ ++ aghi %r5,16 ++ clgrjhe %r5,%r3,.Lfound /* If current_len >= maxlen -> end. */ ++ vl %v16,0(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound ++ aghi %r5,16 ++ clgrjhe %r5,%r3,.Lfound ++ vl %v16,0(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound ++ aghi %r5,16 ++ clgrjhe %r5,%r3,.Lfound ++ vl %v16,0(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ j .Lfound ++ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r4,%v16,7 /* Load byte index of zero or 16 if no zero. */ ++ algr %r5,%r4 ++ ++ clgr %r5,%r3 ++ locgrh %r5,%r3 /* Return min (current_len, maxlen). */ ++.Lend: ++ srlg %r2,%r5,2 /* Convert byte-count to character-count. */ ++ br %r14 ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop64: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Lfound48 ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r3,.Lloop64 ++ ++ j .Llt64 ++ ++.Lfallback: ++ jg __wcsnlen_c ++END(__wcsnlen_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/multiarch/wcsnlen.c +new file mode 100644 +index 0000000..fbb0cab +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsnlen.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcsnlen. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcsnlen) ++weak_alias (__wcsnlen, wcsnlen) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 54994e2..ec0b050 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -41,7 +41,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + isoc99_swscanf isoc99_vswscanf \ + mbrtoc16 c16rtomb + +-strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy ++strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcsnlen-ifunc.c b/wcsmbs/test-wcsnlen-ifunc.c +new file mode 100644 +index 0000000..8aa528e +--- /dev/null ++++ b/wcsmbs/test-wcsnlen-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcsnlen function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcsnlen.c" +diff --git a/wcsmbs/test-wcsnlen.c b/wcsmbs/test-wcsnlen.c +new file mode 100644 +index 0000000..262ab30 +--- /dev/null ++++ b/wcsmbs/test-wcsnlen.c +@@ -0,0 +1,20 @@ ++/* Test wcsnlen function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strnlen.c" +diff --git a/wcsmbs/wcsnlen.c b/wcsmbs/wcsnlen.c +index dff1b45..e803920 100644 +--- a/wcsmbs/wcsnlen.c ++++ b/wcsmbs/wcsnlen.c +@@ -18,8 +18,11 @@ + + #include + ++#ifdef WCSNLEN ++# define __wcsnlen WCSNLEN ++#endif + +-/* Copy SRC to DEST. */ ++/* Return length of string S at most maxlen. */ + size_t + __wcsnlen (s, maxlen) + const wchar_t *s; +@@ -44,4 +47,6 @@ __wcsnlen (s, maxlen) + + return len; + } ++#ifndef WCSNLEN + weak_alias (__wcsnlen, wcsnlen) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-12.patch b/SOURCES/glibc-rh1268008-12.patch new file mode 100644 index 00000000..e33973ef --- /dev/null +++ b/SOURCES/glibc-rh1268008-12.patch @@ -0,0 +1,501 @@ +From 4c98816d5248bed13b1d8388efc0c47fe869300f Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:02:10 +0200 +Subject: [PATCH 12/30] S390: Optimize strcpy and wcscpy. + +upstream-commit-id: 680df122ab8a07806cb38d044292896334f76c01 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00157.html + +This patch provides optimized versions of strcpy and wcscpy with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strcpy-vx.S: New File. + * sysdeps/s390/multiarch/strcpy.c: Likewise. + * sysdeps/s390/multiarch/wcscpy-c.c: Likewise. + * sysdeps/s390/multiarch/wcscpy-vx.S: Likewise. + * sysdeps/s390/multiarch/wcscpy.c: Likewise. + * sysdeps/s390/s390-32/multiarch/strcpy.c: Likewise. + * sysdeps/s390/s390-64/multiarch/strcpy.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strcpy and + wcscpy functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strcpy, wcscpy. + * benchtests/bench-wcscpy.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcscpy. +--- + benchtests/Makefile | 2 +- + benchtests/bench-wcscpy.c | 20 ++++++ + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strcpy-vx.S | 109 ++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strcpy.c | 24 +++++++ + sysdeps/s390/multiarch/wcscpy-c.c | 25 +++++++ + sysdeps/s390/multiarch/wcscpy-vx.S | 111 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcscpy.c | 27 ++++++++ + sysdeps/s390/s390-32/multiarch/strcpy.c | 21 ++++++ + sysdeps/s390/s390-64/multiarch/strcpy.c | 21 ++++++ + 11 files changed, 366 insertions(+), 3 deletions(-) + create mode 100644 benchtests/bench-wcscpy.c + create mode 100644 sysdeps/s390/multiarch/strcpy-vx.S + create mode 100644 sysdeps/s390/multiarch/strcpy.c + create mode 100644 sysdeps/s390/multiarch/wcscpy-c.c + create mode 100644 sysdeps/s390/multiarch/wcscpy-vx.S + create mode 100644 sysdeps/s390/multiarch/wcscpy.c + create mode 100644 sysdeps/s390/s390-32/multiarch/strcpy.c + create mode 100644 sysdeps/s390/s390-64/multiarch/strcpy.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 7bb2eef..1dda844 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen ++wcsmbs-bench := wcslen wcsnlen wcscpy + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-wcscpy.c b/benchtests/bench-wcscpy.c +new file mode 100644 +index 0000000..62c5825 +--- /dev/null ++++ b/benchtests/bench-wcscpy.c +@@ -0,0 +1,20 @@ ++/* Measure wcscpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strcpy.c" +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 3397f24..e2202b7 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,9 +1,11 @@ + ifeq ($(subdir),string) + sysdep_routines += strlen strlen-vx strlen-c \ +- strnlen strnlen-vx strnlen-c ++ strnlen strnlen-vx strnlen-c \ ++ strcpy strcpy-vx + endif + + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ +- wcsnlen wcsnlen-vx wcsnlen-c ++ wcsnlen wcsnlen-vx wcsnlen-c \ ++ wcscpy wcscpy-vx wcscpy-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index bc17c59..c9228d6 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -85,6 +85,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strnlen); + IFUNC_VX_IMPL (wcsnlen); + ++ IFUNC_VX_IMPL (strcpy); ++ IFUNC_VX_IMPL (wcscpy); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/multiarch/strcpy-vx.S +new file mode 100644 +index 0000000..a8243b0 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcpy-vx.S +@@ -0,0 +1,109 @@ ++/* Vector optimized 32/64 bit S/390 version of strcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * strcpy (const char *dest, const char *src) ++ Copy string src to dest. ++ ++ Register usage: ++ -r1=tmp ++ -r2=dest and return_value ++ -r3=src ++ -r4=tmp ++ -r5=current_len ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++*/ ++ENTRY(__strcpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, ++ copy bytes before and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r4 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16_0 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3)/* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezbs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ j .Lloop /* No zero found -> loop. */ ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++.Lfound_v16_0: ++ la %r3,0(%r5,%r2) ++ vlgvb %r4,%v17,7 /* Load byte index of zero. */ ++ vstl %v16,%r4,0(%r3) /* Store characters including zero. */ ++ br %r14 ++ ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ la %r3,16(%r5,%r2) ++ vlgvb %r4,%v17,7 /* Load byte index of zero. */ ++ vstl %v18,%r4,0(%r3) /* Store characters including zero. */ ++ br %r14 ++ ++.Lfound_align: ++ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ ++ br %r14 ++END(__strcpy_vx) ++ ++/* Use mvst-strcpy-implementation as default implementation. */ ++# define strcpy __strcpy_c ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++ ++/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory. */ ++#include +diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/multiarch/strcpy.c +new file mode 100644 +index 0000000..2e00ddf +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcpy.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of strcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strcpy, strcpy) ++#endif +diff --git a/sysdeps/s390/multiarch/wcscpy-c.c b/sysdeps/s390/multiarch/wcscpy-c.c +new file mode 100644 +index 0000000..ca219dd +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscpy-c.c +@@ -0,0 +1,25 @@ ++/* Default wcscpy implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSCPY __wcscpy_c ++ ++# include ++extern __typeof (wcscpy) __wcscpy_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcscpy-vx.S b/sysdeps/s390/multiarch/wcscpy-vx.S +new file mode 100644 +index 0000000..6ec10bf +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscpy-vx.S +@@ -0,0 +1,111 @@ ++/* Vector optimized 32/64 bit S/390 version of wcscpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * wcscpy (const wchar_t *dest, const wchar_t *src) ++ Copy string src to dest. ++ ++ Register usage: ++ -r0=border-len for switching to vector-instructions ++ -r1=tmp ++ -r2=dest and return value ++ -r3=src ++ -r4=tmp ++ -r5=current_len ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++*/ ++ENTRY(__wcscpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ tmll %r3,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, ++ copy bytes before and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r4 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16_0 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezfs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ j .Lloop /* No zero found -> loop. */ ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++.Lfound_v16_0: ++ la %r3,0(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ ++ br %r14 ++ ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ la %r3,16(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ ++ br %r14 ++ ++.Lfound_align: ++ aghi %r5,3 /* Also copy remaining bytes of zero. */ ++ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ ++ br %r14 ++ ++.Lfallback: ++ jg __wcscpy_c ++END(__wcscpy_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcscpy.c b/sysdeps/s390/multiarch/wcscpy.c +new file mode 100644 +index 0000000..b3a057a +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscpy.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcscpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcscpy, wcscpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c +new file mode 100644 +index 0000000..b02c392 +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/strcpy.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of strcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ ++#include +diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c +new file mode 100644 +index 0000000..b02c392 +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/strcpy.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of strcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ ++#include +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-13.patch b/SOURCES/glibc-rh1268008-13.patch new file mode 100644 index 00000000..5e7b4784 --- /dev/null +++ b/SOURCES/glibc-rh1268008-13.patch @@ -0,0 +1,706 @@ +From 9912e5a176f76caf6db58f9f2e9793b08ce3c957 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:04:59 +0200 +Subject: [PATCH 13/30] S390: Optimize stpcpy and wcpcpy. + +upstream-commit-id: 8ade3db78db17e0112648d302f98eda115949cd5 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00154.html + +This patch provides optimized versions of stpcpy and wcpcpy with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/stpcpy-c.c: New File. + * sysdeps/s390/multiarch/stpcpy-vx.S: Likewise. + * sysdeps/s390/multiarch/stpcpy.c: Likewise. + * sysdeps/s390/multiarch/wcpcpy-c.c: Likewise. + * sysdeps/s390/multiarch/wcpcpy-vx.S: Likewise. + * sysdeps/s390/multiarch/wcpcpy.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add stpcpy and + wcpcpy functions. + * string/stpcpy.c: Use STPCPY if defined. + * wcsmbs/wcpcpy.c: Use WCPCPY if defined. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for stpcpy, wcpcpy. + * string/test-stpcpy.c: Add wcpcpy support. + * wcsmbs/test-wcpcpy.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcpcpy. + * benchtests/bench-stpcpy.c: Add wcpcpy support. + * benchtests/bench-wcpcpy.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcpcpy. +--- + benchtests/Makefile | 2 +- + benchtests/bench-stpcpy.c | 33 ++++++--- + benchtests/bench-wcpcpy.c | 20 ++++++ + string/stpcpy.c | 6 ++ + string/test-stpcpy.c | 33 ++++++--- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/stpcpy-c.c | 34 +++++++++ + sysdeps/s390/multiarch/stpcpy-vx.S | 104 ++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/stpcpy.c | 29 ++++++++ + sysdeps/s390/multiarch/wcpcpy-c.c | 25 +++++++ + sysdeps/s390/multiarch/wcpcpy-vx.S | 114 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcpcpy.c | 28 ++++++++ + wcsmbs/Makefile | 3 +- + wcsmbs/test-wcpcpy-ifunc.c | 20 ++++++ + wcsmbs/test-wcpcpy.c | 20 ++++++ + wcsmbs/wcpcpy.c | 6 +- + 17 files changed, 463 insertions(+), 23 deletions(-) + create mode 100644 benchtests/bench-wcpcpy.c + create mode 100644 sysdeps/s390/multiarch/stpcpy-c.c + create mode 100644 sysdeps/s390/multiarch/stpcpy-vx.S + create mode 100644 sysdeps/s390/multiarch/stpcpy.c + create mode 100644 sysdeps/s390/multiarch/wcpcpy-c.c + create mode 100644 sysdeps/s390/multiarch/wcpcpy-vx.S + create mode 100644 sysdeps/s390/multiarch/wcpcpy.c + create mode 100644 wcsmbs/test-wcpcpy-ifunc.c + create mode 100644 wcsmbs/test-wcpcpy.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 1dda844..1b491c6 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen wcscpy ++wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-stpcpy.c b/benchtests/bench-stpcpy.c +index 0645298..f950c92 100644 +--- a/benchtests/bench-stpcpy.c ++++ b/benchtests/bench-stpcpy.c +@@ -18,19 +18,34 @@ + + #define STRCPY_RESULT(dst, len) ((dst) + (len)) + #define TEST_MAIN +-#define TEST_NAME "stpcpy" ++#ifndef WIDE ++# define TEST_NAME "stpcpy" ++#else ++# define TEST_NAME "wcpcpy" ++#endif /* WIDE */ + #include "bench-string.h" +- +-char *simple_stpcpy (char *, const char *); +- +-IMPL (simple_stpcpy, 0) +-IMPL (stpcpy, 1) +- +-char * +-simple_stpcpy (char *dst, const char *src) ++#ifndef WIDE ++# define CHAR char ++# define SIMPLE_STPCPY simple_stpcpy ++# define STPCPY stpcpy ++#else ++# include ++# define CHAR wchar_t ++# define SIMPLE_STPCPY simple_wcpcpy ++# define STPCPY wcpcpy ++#endif /* WIDE */ ++ ++CHAR *SIMPLE_STPCPY (CHAR *, const CHAR *); ++ ++IMPL (SIMPLE_STPCPY, 0) ++IMPL (STPCPY, 1) ++ ++CHAR * ++SIMPLE_STPCPY (CHAR *dst, const CHAR *src) + { + while ((*dst++ = *src++) != '\0'); + return dst - 1; + } + ++#undef CHAR + #include "bench-strcpy.c" +diff --git a/benchtests/bench-wcpcpy.c b/benchtests/bench-wcpcpy.c +new file mode 100644 +index 0000000..cfbfccf +--- /dev/null ++++ b/benchtests/bench-wcpcpy.c +@@ -0,0 +1,20 @@ ++/* Measure wcpcpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-stpcpy.c" +diff --git a/string/stpcpy.c b/string/stpcpy.c +index b0a83ba..69d150f 100644 +--- a/string/stpcpy.c ++++ b/string/stpcpy.c +@@ -28,6 +28,12 @@ + # define __stpcpy stpcpy + #endif + ++#ifdef STPCPY ++extern __typeof (__stpcpy) STPCPY; ++# undef __stpcpy ++# define __stpcpy STPCPY ++#endif ++ + /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ + char * + __stpcpy (dest, src) +diff --git a/string/test-stpcpy.c b/string/test-stpcpy.c +index 6a7af0c..962e5d6 100644 +--- a/string/test-stpcpy.c ++++ b/string/test-stpcpy.c +@@ -19,19 +19,34 @@ + + #define STRCPY_RESULT(dst, len) ((dst) + (len)) + #define TEST_MAIN +-#define TEST_NAME "stpcpy" ++#ifndef WIDE ++# define TEST_NAME "stpcpy" ++#else ++# define TEST_NAME "wcpcpy" ++#endif /* !WIDE */ + #include "test-string.h" +- +-char *simple_stpcpy (char *, const char *); +- +-IMPL (simple_stpcpy, 0) +-IMPL (stpcpy, 1) +- +-char * +-simple_stpcpy (char *dst, const char *src) ++#ifndef WIDE ++# define CHAR char ++# define SIMPLE_STPCPY simple_stpcpy ++# define STPCPY stpcpy ++#else ++# include ++# define CHAR wchar_t ++# define SIMPLE_STPCPY simple_wcpcpy ++# define STPCPY wcpcpy ++#endif /* !WIDE */ ++ ++CHAR *SIMPLE_STPCPY (CHAR *, const CHAR *); ++ ++IMPL (SIMPLE_STPCPY, 0) ++IMPL (STPCPY, 1) ++ ++CHAR * ++SIMPLE_STPCPY (CHAR *dst, const CHAR *src) + { + while ((*dst++ = *src++) != '\0'); + return dst - 1; + } + ++#undef CHAR + #include "test-strcpy.c" +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index e2202b7..5b57342 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -1,11 +1,13 @@ + ifeq ($(subdir),string) + sysdep_routines += strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ +- strcpy strcpy-vx ++ strcpy strcpy-vx \ ++ stpcpy stpcpy-vx stpcpy-c + endif + + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ +- wcscpy wcscpy-vx wcscpy-c ++ wcscpy wcscpy-vx wcscpy-c \ ++ wcpcpy wcpcpy-vx wcpcpy-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c9228d6..a402301 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -88,6 +88,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strcpy); + IFUNC_VX_IMPL (wcscpy); + ++ IFUNC_VX_IMPL (stpcpy); ++ IFUNC_VX_IMPL (wcpcpy); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/multiarch/stpcpy-c.c +new file mode 100644 +index 0000000..4679ec6 +--- /dev/null ++++ b/sysdeps/s390/multiarch/stpcpy-c.c +@@ -0,0 +1,34 @@ ++/* Default stpcpy implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STPCPY __stpcpy_c ++# undef libc_hidden_def ++# undef weak_alias ++# undef libc_hidden_builtin_def ++# ifdef SHARED ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c); ++# define libc_hidden_builtin_def(name) \ ++ strong_alias (__stpcpy_c, __stpcpy_c_1); \ ++ __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1); ++# endif /* SHARED */ ++ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/multiarch/stpcpy-vx.S +new file mode 100644 +index 0000000..661ad15 +--- /dev/null ++++ b/sysdeps/s390/multiarch/stpcpy-vx.S +@@ -0,0 +1,104 @@ ++/* Vector optimized 32/64 bit S/390 version of stpcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * stpcpy (const char *dest, const char *src) ++ Copy string src to dest returning a pointer to its end. ++ ++ Register usage: ++ -r1=tmp ++ -r2=dest and return value ++ -r3=src ++ -r4=tmp ++ -r5=current_len ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++*/ ++ENTRY(__stpcpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, ++ copy bytes before and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r4 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16_0 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezbs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ j .Lloop /* No zero found -> loop. */ ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++.Lfound_v16_0: ++ la %r3,0(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ ++ la %r2,0(%r1,%r3) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ la %r3,16(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ ++ la %r2,0(%r1,%r3) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lfound_align: ++ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ ++ la %r2,0(%r5,%r2) /* Return pointer to zero. */ ++ br %r14 ++END(__stpcpy_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c +new file mode 100644 +index 0000000..7dc85a0 +--- /dev/null ++++ b/sysdeps/s390/multiarch/stpcpy.c +@@ -0,0 +1,29 @@ ++/* Multiple versions of stpcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__stpcpy) ++weak_alias (__stpcpy, stpcpy) ++libc_hidden_builtin_def (stpcpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcpcpy-c.c b/sysdeps/s390/multiarch/wcpcpy-c.c +new file mode 100644 +index 0000000..7349f34 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcpcpy-c.c +@@ -0,0 +1,25 @@ ++/* Default wcslen implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCPCPY __wcpcpy_c ++ ++# include ++extern __typeof (__wcpcpy) __wcpcpy_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcpcpy-vx.S b/sysdeps/s390/multiarch/wcpcpy-vx.S +new file mode 100644 +index 0000000..195b836 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcpcpy-vx.S +@@ -0,0 +1,114 @@ ++/* Vector optimized 32/64 bit S/390 version of wcpcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t * wcpcpy (const wchar_t *dest, const wchar_t *src) ++ Copy string src to dest returning a pointer to its end. ++ ++ Register usage: ++ -r0=border-len for switching to vector-instructions ++ -r1=tmp ++ -r2=dest and return value ++ -r3=src ++ -r4=tmp ++ -r5=current_len ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++*/ ++ENTRY(__wcpcpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ tmll %r3,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lfound_align /* If found zero within loaded bytes, ++ copy bytes before and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r4 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16_0 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezfs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ j .Lloop /* No zero found -> loop. */ ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++.Lfound_v16_0: ++ la %r3,0(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v16,%r1,0(%r3) /* Copy characters including zero. */ ++ lay %r2,-3(%r1,%r3) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ la %r3,16(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v18,%r1,0(%r3) /* Copy characters including zero. */ ++ lay %r2,-3(%r1,%r3) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lfound_align: ++ aghi %r5,3 /* Also copy remaining bytes of zero. */ ++ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ ++ lay %r2,-3(%r5,%r2) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lfallback: ++ jg __wcpcpy_c ++END(__wcpcpy_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcpcpy.c b/sysdeps/s390/multiarch/wcpcpy.c +new file mode 100644 +index 0000000..46bf8e8 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcpcpy.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcpcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcpcpy) ++weak_alias (__wcpcpy, wcpcpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index ec0b050..3b91b6d 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -41,7 +41,8 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + isoc99_swscanf isoc99_vswscanf \ + mbrtoc16 c16rtomb + +-strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen ++strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ ++ wcpcpy + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcpcpy-ifunc.c b/wcsmbs/test-wcpcpy-ifunc.c +new file mode 100644 +index 0000000..aa39062 +--- /dev/null ++++ b/wcsmbs/test-wcpcpy-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcpcpy function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcpcpy.c" +diff --git a/wcsmbs/test-wcpcpy.c b/wcsmbs/test-wcpcpy.c +new file mode 100644 +index 0000000..2cf91a1 +--- /dev/null ++++ b/wcsmbs/test-wcpcpy.c +@@ -0,0 +1,20 @@ ++/* Test wcspcpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-stpcpy.c" +diff --git a/wcsmbs/wcpcpy.c b/wcsmbs/wcpcpy.c +index eaaab2c..f67ba62 100644 +--- a/wcsmbs/wcpcpy.c ++++ b/wcsmbs/wcpcpy.c +@@ -21,7 +21,9 @@ + #define __need_ptrdiff_t + #include + +- ++#ifdef WCPCPY ++# define __wcpcpy WCPCPY ++#endif + /* Copy SRC to DEST, returning the address of the terminating L'\0' in + DEST. */ + wchar_t * +@@ -43,4 +45,6 @@ __wcpcpy (dest, src) + return wcp; + } + ++#ifndef WCPCPY + weak_alias (__wcpcpy, wcpcpy) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-14.patch b/SOURCES/glibc-rh1268008-14.patch new file mode 100644 index 00000000..2bdc1995 --- /dev/null +++ b/SOURCES/glibc-rh1268008-14.patch @@ -0,0 +1,1237 @@ +From 74fa8494fa732a0bd63b14b60ea0f1e542e0cee6 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:09:04 +0200 +Subject: [PATCH 14/30] S390: Optimize strncpy and wcsncpy. + +upstream-commit-id: d183b96ee6dc694e95f212c9272a178163351b19 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00160.html + +This patch provides optimized versions of strncpy and wcsncpy with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strncpy-vx.S: New File. + * sysdeps/s390/multiarch/strncpy.c: Likewise. + * sysdeps/s390/multiarch/wcsncpy-c.c: Likewise. + * sysdeps/s390/multiarch/wcsncpy-vx.S: Likewise. + * sysdeps/s390/multiarch/wcsncpy.c: Likewise. + * sysdeps/s390/s390-32/multiarch/strncpy.c: Likewise. + * sysdeps/s390/s390-64/multiarch/strncpy.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strncpy and + wcsncpy functions. + * wcsmbs/wcsncpy.c: Use WCSNCPY if defined. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strncpy, wcsncpy. + * string/test-strncpy.c: Add wcsncpy support. + * wcsmbs/test-wcsncpy.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcsncpy. + * benchtests/bench-strncpy.c: Add wcsncpy support. + * benchtests/bench-wcsncpy.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcsncpy +--- + benchtests/Makefile | 2 +- + benchtests/bench-strncpy.c | 108 ++++++++++----- + benchtests/bench-wcsncpy.c | 20 +++ + string/test-strncpy.c | 129 +++++++++++------- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strncpy-vx.S | 207 ++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strncpy.c | 24 ++++ + sysdeps/s390/multiarch/wcsncpy-c.c | 25 ++++ + sysdeps/s390/multiarch/wcsncpy-vx.S | 223 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcsncpy.c | 28 ++++ + sysdeps/s390/s390-32/multiarch/strncpy.c | 21 +++ + sysdeps/s390/s390-64/multiarch/strncpy.c | 21 +++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcsncpy-ifunc.c | 20 +++ + wcsmbs/test-wcsncpy.c | 20 +++ + wcsmbs/wcsncpy.c | 5 + + 17 files changed, 778 insertions(+), 86 deletions(-) + create mode 100644 benchtests/bench-wcsncpy.c + create mode 100644 sysdeps/s390/multiarch/strncpy-vx.S + create mode 100644 sysdeps/s390/multiarch/strncpy.c + create mode 100644 sysdeps/s390/multiarch/wcsncpy-c.c + create mode 100644 sysdeps/s390/multiarch/wcsncpy-vx.S + create mode 100644 sysdeps/s390/multiarch/wcsncpy.c + create mode 100644 sysdeps/s390/s390-32/multiarch/strncpy.c + create mode 100644 sysdeps/s390/s390-64/multiarch/strncpy.c + create mode 100644 wcsmbs/test-wcsncpy-ifunc.c + create mode 100644 wcsmbs/test-wcsncpy.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 1b491c6..f898258 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy ++wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strncpy.c b/benchtests/bench-strncpy.c +index 645925b..2cfd56a 100644 +--- a/benchtests/bench-strncpy.c ++++ b/benchtests/bench-strncpy.c +@@ -1,5 +1,5 @@ + /* Measure strncpy functions. +- Copyright (C) 2013 Free Software Foundation, Inc. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,23 +16,56 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifdef WIDE ++# include ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++# define MEMCMP wmemcmp ++# define MEMSET wmemset ++# define STRNLEN wcsnlen ++#else ++# define CHAR char ++# define UCHAR unsigned char ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++# define MEMCMP memcmp ++# define MEMSET memset ++# define STRNLEN strnlen ++#endif /* !WIDE */ ++ + #ifndef STRNCPY_RESULT + # define STRNCPY_RESULT(dst, len, n) dst + # define TEST_MAIN +-# define TEST_NAME "strncpy" ++# ifndef WIDE ++# define TEST_NAME "strncpy" ++# else ++# define TEST_NAME "wcsncpy" ++# endif /* WIDE */ + # include "bench-string.h" + +-char *simple_strncpy (char *, const char *, size_t); +-char *stupid_strncpy (char *, const char *, size_t); +- +-IMPL (stupid_strncpy, 0) +-IMPL (simple_strncpy, 0) +-IMPL (strncpy, 1) +- +-char * +-simple_strncpy (char *dst, const char *src, size_t n) ++# ifndef WIDE ++# define SIMPLE_STRNCPY simple_strncpy ++# define STUPID_STRNCPY stupid_strncpy ++# define STRNCPY strncpy ++# else ++# define SIMPLE_STRNCPY simple_wcsncpy ++# define STUPID_STRNCPY stupid_wcsncpy ++# define STRNCPY wcsncpy ++# endif /* WIDE */ ++ ++CHAR *SIMPLE_STRNCPY (CHAR *, const CHAR *, size_t); ++CHAR *STUPID_STRNCPY (CHAR *, const CHAR *, size_t); ++ ++IMPL (STUPID_STRNCPY, 0) ++IMPL (SIMPLE_STRNCPY, 0) ++IMPL (STRNCPY, 1) ++ ++CHAR * ++SIMPLE_STRNCPY (CHAR *dst, const CHAR *src, size_t n) + { +- char *ret = dst; ++ CHAR *ret = dst; + while (n--) + if ((*dst++ = *src++) == '\0') + { +@@ -43,10 +76,10 @@ simple_strncpy (char *dst, const char *src, size_t n) + return ret; + } + +-char * +-stupid_strncpy (char *dst, const char *src, size_t n) ++CHAR * ++STUPID_STRNCPY (CHAR *dst, const CHAR *src, size_t n) + { +- size_t nc = strnlen (src, n); ++ size_t nc = STRNLEN (src, n); + size_t i; + + for (i = 0; i < nc; ++i) +@@ -55,12 +88,12 @@ stupid_strncpy (char *dst, const char *src, size_t n) + dst[i] = '\0'; + return dst; + } +-#endif ++#endif /* !STRNCPY_RESULT */ + +-typedef char *(*proto_t) (char *, const char *, size_t); ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); + + static void +-do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n) ++do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t len, size_t n) + { + size_t i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; +@@ -73,7 +106,7 @@ do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n) + return; + } + +- if (memcmp (dst, src, len > n ? n : len) != 0) ++ if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) != 0) + { + error (0, 0, "Wrong result in function %s", impl->name); + ret = 1; +@@ -109,23 +142,24 @@ static void + do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + align1 &= 7; +- if (align1 + len >= page_size) ++ if ((align1 + len) * sizeof (CHAR) >= page_size) + return; + + align2 &= 7; +- if (align2 + len >= page_size) ++ if ((align2 + len) * sizeof (CHAR) >= page_size) + return; + +- s1 = (char *) (buf1 + align1); +- s2 = (char *) (buf2 + align2); ++ s1 = (CHAR *) (buf1 + align1); ++ s2 = (CHAR *) (buf2 + align2); + + for (i = 0; i < len; ++i) + s1[i] = 32 + 23 * i % (max_char - 32); + s1[len] = 0; +- for (i = len + 1; i + align1 < page_size && i < len + 64; ++i) ++ for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64; ++ ++i) + s1[i] = 32 + 32 * i % (max_char - 32); + + printf ("Length %4zd, n %4zd, alignment %2zd/%2zd:", len, n, align1, align2); +@@ -150,22 +184,22 @@ test_main (void) + + for (i = 1; i < 8; ++i) + { +- do_test (i, i, 16, 16, 127); +- do_test (i, i, 16, 16, 255); +- do_test (i, 2 * i, 16, 16, 127); +- do_test (2 * i, i, 16, 16, 255); +- do_test (8 - i, 2 * i, 1 << i, 2 << i, 127); +- do_test (2 * i, 8 - i, 2 << i, 1 << i, 127); +- do_test (8 - i, 2 * i, 1 << i, 2 << i, 255); +- do_test (2 * i, 8 - i, 2 << i, 1 << i, 255); ++ do_test (i, i, 16, 16, SMALL_CHAR); ++ do_test (i, i, 16, 16, BIG_CHAR); ++ do_test (i, 2 * i, 16, 16, SMALL_CHAR); ++ do_test (2 * i, i, 16, 16, BIG_CHAR); ++ do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR); ++ do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR); ++ do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (0, 0, 4 << i, 8 << i, 127); +- do_test (0, 0, 16 << i, 8 << i, 127); +- do_test (8 - i, 2 * i, 4 << i, 8 << i, 127); +- do_test (8 - i, 2 * i, 16 << i, 8 << i, 127); ++ do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR); ++ do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR); + } + + return ret; +diff --git a/benchtests/bench-wcsncpy.c b/benchtests/bench-wcsncpy.c +new file mode 100644 +index 0000000..d6f63c9 +--- /dev/null ++++ b/benchtests/bench-wcsncpy.c +@@ -0,0 +1,20 @@ ++/* Measure wcsncpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strncpy.c" +diff --git a/string/test-strncpy.c b/string/test-strncpy.c +index a623093..bdccc98 100644 +--- a/string/test-strncpy.c ++++ b/string/test-strncpy.c +@@ -17,23 +17,56 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifdef WIDE ++# include ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++# define MEMCMP wmemcmp ++# define MEMSET wmemset ++# define STRNLEN wcsnlen ++#else ++# define CHAR char ++# define UCHAR unsigned char ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++# define MEMCMP memcmp ++# define MEMSET memset ++# define STRNLEN strnlen ++#endif /* !WIDE */ ++ ++ + #ifndef STRNCPY_RESULT + # define STRNCPY_RESULT(dst, len, n) dst + # define TEST_MAIN +-# define TEST_NAME "strncpy" ++# ifndef WIDE ++# define TEST_NAME "strncpy" ++# else ++# define TEST_NAME "wcsncpy" ++# endif /* WIDE */ + # include "test-string.h" ++# ifndef WIDE ++# define SIMPLE_STRNCPY simple_strncpy ++# define STUPID_STRNCPY stupid_strncpy ++# define STRNCPY strncpy ++# else ++# define SIMPLE_STRNCPY simple_wcsncpy ++# define STUPID_STRNCPY stupid_wcsncpy ++# define STRNCPY wcsncpy ++# endif /* WIDE */ + +-char *simple_strncpy (char *, const char *, size_t); +-char *stupid_strncpy (char *, const char *, size_t); ++CHAR *SIMPLE_STRNCPY (CHAR *, const CHAR *, size_t); ++CHAR *STUPID_STRNCPY (CHAR *, const CHAR *, size_t); + +-IMPL (stupid_strncpy, 0) +-IMPL (simple_strncpy, 0) +-IMPL (strncpy, 1) ++IMPL (STUPID_STRNCPY, 0) ++IMPL (SIMPLE_STRNCPY, 0) ++IMPL (STRNCPY, 1) + +-char * +-simple_strncpy (char *dst, const char *src, size_t n) ++CHAR * ++SIMPLE_STRNCPY (CHAR *dst, const CHAR *src, size_t n) + { +- char *ret = dst; ++ CHAR *ret = dst; + while (n--) + if ((*dst++ = *src++) == '\0') + { +@@ -44,10 +77,10 @@ simple_strncpy (char *dst, const char *src, size_t n) + return ret; + } + +-char * +-stupid_strncpy (char *dst, const char *src, size_t n) ++CHAR * ++STUPID_STRNCPY (CHAR *dst, const CHAR *src, size_t n) + { +- size_t nc = strnlen (src, n); ++ size_t nc = STRNLEN (src, n); + size_t i; + + for (i = 0; i < nc; ++i) +@@ -56,12 +89,12 @@ stupid_strncpy (char *dst, const char *src, size_t n) + dst[i] = '\0'; + return dst; + } +-#endif ++#endif /* !STRNCPY_RESULT */ + +-typedef char *(*proto_t) (char *, const char *, size_t); ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); + + static void +-do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n) ++do_one_test (impl_t *impl, CHAR *dst, const char *src, size_t len, size_t n) + { + if (CALL (impl, dst, src, n) != STRNCPY_RESULT (dst, len, n)) + { +@@ -71,7 +104,7 @@ do_one_test (impl_t *impl, char *dst, const char *src, size_t len, size_t n) + return; + } + +- if (memcmp (dst, src, len > n ? n : len) != 0) ++ if (memcmp (dst, src, (len > n ? n : len) * sizeof (CHAR)) != 0) + { + error (0, 0, "Wrong result in function %s", impl->name); + ret = 1; +@@ -96,23 +129,26 @@ static void + do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + ++/* For wcsncpy: align1 and align2 here mean alignment not in bytes, ++ but in wchar_ts, in bytes it will equal to align * (sizeof (wchar_t)). */ + align1 &= 7; +- if (align1 + len >= page_size) ++ if ((align1 + len) * sizeof (CHAR) >= page_size) + return; + + align2 &= 7; +- if (align2 + len >= page_size) ++ if ((align2 + len) * sizeof (CHAR) >= page_size) + return; + +- s1 = (char *) (buf1 + align1); +- s2 = (char *) (buf2 + align2); ++ s1 = (CHAR *) (buf1) + align1; ++ s2 = (CHAR *) (buf2) + align2; + + for (i = 0; i < len; ++i) + s1[i] = 32 + 23 * i % (max_char - 32); + s1[len] = 0; +- for (i = len + 1; i + align1 < page_size && i < len + 64; ++i) ++ for (i = len + 1; (i + align1) * sizeof (CHAR) < page_size && i < len + 64; ++ ++i) + s1[i] = 32 + 32 * i % (max_char - 32); + + FOR_EACH_IMPL (impl, 0) +@@ -123,12 +159,16 @@ static void + do_random_tests (void) + { + size_t i, j, n, align1, align2, len, size, mode; +- unsigned char *p1 = buf1 + page_size - 512; +- unsigned char *p2 = buf2 + page_size - 512; +- unsigned char *res; ++ UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512; ++ UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512; ++ UCHAR *res; + + for (n = 0; n < ITERATIONS; n++) + { ++ /* For wcsncpy: align1 and align2 here mean align not in bytes, ++ but in wchar_ts, in bytes it will equal to align * (sizeof ++ (wchar_t)). */ ++ + mode = random (); + if (mode & 1) + { +@@ -166,7 +206,7 @@ do_random_tests (void) + { + size = random () & 511; + if (size + j > 512) +- size = 512 - j - (random() & 31); ++ size = 512 - j - (random () & 31); + } + else + size = 512 - j; +@@ -182,18 +222,17 @@ do_random_tests (void) + p1[i] = 0; + else + { +- p1[i] = random () & 255; ++ p1[i] = random () & BIG_CHAR; + if (i >= align1 && i < len + align1 && !p1[i]) +- p1[i] = (random () & 127) + 3; ++ p1[i] = (random () & SMALL_CHAR) + 3; + } + } + + FOR_EACH_IMPL (impl, 1) + { +- memset (p2 - 64, '\1', 512 + 64); +- res = (unsigned char *) CALL (impl, +- (char *) (p2 + align2), +- (char *) (p1 + align1), size); ++ MEMSET (p2 - 64, '\1', 512 + 64); ++ res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2), ++ (CHAR *) (p1 + align1), size); + if (res != STRNCPY_RESULT (p2 + align2, len, size)) + { + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p", +@@ -235,7 +274,7 @@ do_random_tests (void) + j = len + 1; + if (size < j) + j = size; +- if (memcmp (p1 + align1, p2 + align2, j)) ++ if (MEMCMP (p1 + align1, p2 + align2, j)) + { + error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd)", + n, impl->name, align1, align2, len); +@@ -259,22 +298,22 @@ test_main (void) + + for (i = 1; i < 8; ++i) + { +- do_test (i, i, 16, 16, 127); +- do_test (i, i, 16, 16, 255); +- do_test (i, 2 * i, 16, 16, 127); +- do_test (2 * i, i, 16, 16, 255); +- do_test (8 - i, 2 * i, 1 << i, 2 << i, 127); +- do_test (2 * i, 8 - i, 2 << i, 1 << i, 127); +- do_test (8 - i, 2 * i, 1 << i, 2 << i, 255); +- do_test (2 * i, 8 - i, 2 << i, 1 << i, 255); ++ do_test (i, i, 16, 16, SMALL_CHAR); ++ do_test (i, i, 16, 16, BIG_CHAR); ++ do_test (i, 2 * i, 16, 16, SMALL_CHAR); ++ do_test (2 * i, i, 16, 16, BIG_CHAR); ++ do_test (8 - i, 2 * i, 1 << i, 2 << i, SMALL_CHAR); ++ do_test (2 * i, 8 - i, 2 << i, 1 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 1 << i, 2 << i, BIG_CHAR); ++ do_test (2 * i, 8 - i, 2 << i, 1 << i, BIG_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (0, 0, 4 << i, 8 << i, 127); +- do_test (0, 0, 16 << i, 8 << i, 127); +- do_test (8 - i, 2 * i, 4 << i, 8 << i, 127); +- do_test (8 - i, 2 * i, 16 << i, 8 << i, 127); ++ do_test (0, 0, 4 << i, 8 << i, SMALL_CHAR); ++ do_test (0, 0, 16 << i, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 4 << i, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 16 << i, 8 << i, SMALL_CHAR); + } + + do_random_tests (); +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 5b57342..0dff2dc 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -2,12 +2,14 @@ ifeq ($(subdir),string) + sysdep_routines += strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx \ +- stpcpy stpcpy-vx stpcpy-c ++ stpcpy stpcpy-vx stpcpy-c \ ++ strncpy strncpy-vx + endif + + ifeq ($(subdir),wcsmbs) + sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ +- wcpcpy wcpcpy-vx wcpcpy-c ++ wcpcpy wcpcpy-vx wcpcpy-c \ ++ wcsncpy wcsncpy-vx wcsncpy-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index a402301..940421d 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -91,6 +91,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (stpcpy); + IFUNC_VX_IMPL (wcpcpy); + ++ IFUNC_VX_IMPL (strncpy); ++ IFUNC_VX_IMPL (wcsncpy); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strncpy-vx.S b/sysdeps/s390/multiarch/strncpy-vx.S +new file mode 100644 +index 0000000..c18b9b7 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncpy-vx.S +@@ -0,0 +1,207 @@ ++/* Vector optimized 32/64 bit S/390 version of strncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * strncpy (const char *dest, const char *src, size_t n) ++ Copy at most n characters of string src to dest. ++ ++ Register usage: ++ -r0=dest pointer for return ++ -r1=tmp, zero byte index ++ -r2=dest ++ -r3=src ++ -r4=n ++ -r5=current_len ++ -r6=tmp, loaded bytes ++ -r7=tmp, border ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++ -v31=register save area for r6, r7 ++*/ ++ENTRY(__strncpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r4,0 ++ ber %r14 /* Nothing to do, if n == 0. */ ++ lgr %r0,%r2 /* Save destination pointer for return. */ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r6,%r6 /* Convert 32bit to 64bit. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes ++ -> process remaining. */ ++ ++ /* n > loaded-byte-count. */ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, ++ copy and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r7 /* Compute highest index to 16byte boundary. */ ++ ++ /* Zero not found and n > loaded-byte-count. */ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Now we are 16byte aligned, so we can load ++ a full vreg without page fault. */ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining ++ bytes. */ ++.Llt64: ++ lgr %r7,%r4 ++ slgfi %r7,16 /* border_len = n - 16. */ ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border ++ then process remaining bytes. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v18 ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18 ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 ++ vfenezbs %v17,%v16,%v16 ++ je .Lfound_v16 ++ vl %v18,16(%r5,%r3) ++ vst %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lremaining_v18: ++ vlr %v16,%v18 ++.Lremaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Store remaining bytes and append string-termination. */ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ la %r2,0(%r5,%r2) /* vstl has no index register. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ /* Zero in remaining bytes? -> jump away (zero-index < max-index) ++ Do not jump away if zero-index == max-index, ++ but simply copy zero with vstl below. */ ++ clrjl %r1,%r7,.Lfound_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null ++ termination!. */ ++.Lend: ++ /* Restore saved registers. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++ j .Lfound_v16 ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ aghi %r5,16 ++.Lfound_v18: ++ vlr %v16,%v18 ++.Lfound_v16: ++ /* v16 contains a zero. Store remaining bytes to zero. current_len ++ has not reached border, thus checking for n is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ ++.Lfound_v16_store: ++ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ ++ /* Fill remaining bytes with zero - remaining count always > 0. */ ++ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ ++ slgr %r4,%r5 /* = n - (current_len + zero_index + 1). */ ++ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ ++ aghi %r4,-2 /* mvc with exrl needs count - 1. ++ (additional -1, see remaining bytes above) */ ++ srlg %r6,%r4,8 /* Split into 256 byte blocks. */ ++ ltgr %r6,%r6 ++ je .Lzero_lt256 ++.Lzero_loop256: ++ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ ++ la %r2,256(%r2) ++ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ ++.Lzero_lt256: ++ exrl %r4,.Lmvc_lt256 ++ j .Lend ++.Lmvc_lt256: ++ mvc 1(1,%r2),0(%r2) ++ ++.Lloop64: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezbs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ j .Llt64 ++END(__strncpy_vx) ++ ++# define strncpy __strncpy_c ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) strong_alias(__strncpy_c, __GI_strncpy) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++ ++/* Include strncpy-implementation in s390-32/s390-64 subdirectory. */ ++#include +diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c +new file mode 100644 +index 0000000..0b0c308 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncpy.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of strncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strncpy, strncpy) ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/multiarch/wcsncpy-c.c +new file mode 100644 +index 0000000..a46e4ac +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncpy-c.c +@@ -0,0 +1,25 @@ ++/* Default wcsncpy implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSNCPY __wcsncpy_c ++ ++# include ++extern __typeof (__wcsncpy) __wcsncpy_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncpy-vx.S b/sysdeps/s390/multiarch/wcsncpy-vx.S +new file mode 100644 +index 0000000..072a2d4 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncpy-vx.S +@@ -0,0 +1,223 @@ ++/* Vector optimized 32/64 bit S/390 version of wcsncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t *wcsncpy (const wchar_t *dest, const wchar_t *src, size_t n) ++ Copy at most n characters of string src to dest. ++ ++ Register usage: ++ -r0=dest pointer for return ++ -r1=tmp, zero byte index ++ -r2=dest ++ -r3=src ++ -r4=n ++ -r5=current_len ++ -r6=tmp, loaded bytes ++ -r7=tmp, border ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++ -v31=register save area for r6, r7 ++*/ ++ENTRY(__wcsncpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r4,0 ++ ber %r14 /* Nothing to do, if n == 0. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ ++ tmll %r3,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ lgr %r0,%r2 /* Save destination pointer for return. */ ++ ++ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r6,%r6 /* Convert 32bit to 64bit. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of n. */ ++ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of n. */ ++ llilf %r1,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes ++ -> process remaining. */ ++ ++ /* n > loaded-byte-count. */ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, ++ copy and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r7 /* Compute highest index to 16byte boundary. */ ++ ++ /* Zero not found and n > loaded-byte-count. */ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Now we are 16byte aligned, so we can load ++ a full vreg without page fault. */ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ clgijl %r4,17,.Lremaining_v16 /* If n <=16, process remaining ++ bytes. */ ++.Llt64: ++ lgr %r7,%r4 ++ slgfi %r7,16 /* border_len = maxlen - 16. */ ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border ++ then process remaining bytes. */ ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v18 ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18 ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 ++ vfenezfs %v17,%v16,%v16 ++ je .Lfound_v16 ++ vl %v18,16(%r5,%r3) ++ vst %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lremaining_v18: ++ vlr %v16,%v18 ++.Lremaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Store remaining bytes and append string-termination. */ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ la %r2,0(%r5,%r2) /* vstl has no index register. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ /* Zero in remaining bytes? -> jump away (zero-index < max-index) ++ Do not jump away if zero-index == max-index, ++ but simply copy zero with vstl below. */ ++ clrjl %r1,%r7,.Lfound_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null ++ termination!. */ ++.Lend: ++ /* Restore saved registers. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++ j .Lfound_v16 ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ aghi %r5,16 ++.Lfound_v18: ++ vlr %v16,%v18 ++.Lfound_v16: ++ /* v16 contains a zero. Store remaining bytes to zero. current_len ++ has not reached border, thus checking for n is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++.Lfound_v16_store: ++ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ ++ /* Fill remaining bytes with zero - remaining count always > 0. */ ++ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ ++ slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1). */ ++ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ ++ aghi %r4,-2 /* mvc with exrl needs count - 1. ++ (additional -1, see remaining bytes above) */ ++ srlg %r6,%r4,8 /* Split into 256 byte blocks. */ ++ ltgr %r6,%r6 ++ je .Lzero_lt256 ++.Lzero_loop256: ++ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ ++ la %r2,256(%r2) ++ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ ++.Lzero_lt256: ++ exrl %r4,.Lmvc_lt256 ++ j .Lend ++.Lmvc_lt256: ++ mvc 1(1,%r2),0(%r2) ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop64: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezfs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ j .Llt64 ++ ++.Lfallback: ++ jg __wcsncpy_c ++END(__wcsncpy_vx) ++ ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/multiarch/wcsncpy.c +new file mode 100644 +index 0000000..99aa344 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncpy.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcsncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcsncpy) ++weak_alias (__wcsncpy, wcsncpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/s390-32/multiarch/strncpy.c b/sysdeps/s390/s390-32/multiarch/strncpy.c +new file mode 100644 +index 0000000..bc9c336 +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/strncpy.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of strncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ ++#include +diff --git a/sysdeps/s390/s390-64/multiarch/strncpy.c b/sysdeps/s390/s390-64/multiarch/strncpy.c +new file mode 100644 +index 0000000..bc9c336 +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/strncpy.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of strncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ ++#include +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 3b91b6d..c26ab0c 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy ++ wcpcpy wcsncpy + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcsncpy-ifunc.c b/wcsmbs/test-wcsncpy-ifunc.c +new file mode 100644 +index 0000000..0141b38 +--- /dev/null ++++ b/wcsmbs/test-wcsncpy-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcsncpy function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcsncpy.c" +diff --git a/wcsmbs/test-wcsncpy.c b/wcsmbs/test-wcsncpy.c +new file mode 100644 +index 0000000..27de6f8 +--- /dev/null ++++ b/wcsmbs/test-wcsncpy.c +@@ -0,0 +1,20 @@ ++/* Test wcsncpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strncpy.c" +diff --git a/wcsmbs/wcsncpy.c b/wcsmbs/wcsncpy.c +index f134c36..2e3cebe 100644 +--- a/wcsmbs/wcsncpy.c ++++ b/wcsmbs/wcsncpy.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WCSNCPY ++# define __wcsncpy WCSNCPY ++#endif + + /* Copy no more than N wide-characters of SRC to DEST. */ + wchar_t * +@@ -83,4 +86,6 @@ __wcsncpy (dest, src, n) + + return s; + } ++#ifndef WCSNCPY + weak_alias (__wcsncpy, wcsncpy) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-15.patch b/SOURCES/glibc-rh1268008-15.patch new file mode 100644 index 00000000..dadd5835 --- /dev/null +++ b/SOURCES/glibc-rh1268008-15.patch @@ -0,0 +1,914 @@ +From b403bd489e63561185fda4d7d1de2b1f627608d9 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:10:59 +0200 +Subject: [PATCH 15/30] S390: Optimize stpncpy and wcpncpy. + +upstream-commit-id: b3a0c176d1185621c4dd2bb3a51ec961bdb29123 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00158.html + +This patch provides optimized versions of stpncpy and wcpncpy with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/stpncpy-c.c: New File. + * sysdeps/s390/multiarch/stpncpy-vx.S: Likewise. + * sysdeps/s390/multiarch/stpncpy.c: Likewise. + * sysdeps/s390/multiarch/wcpncpy-c.c: Likewise. + * sysdeps/s390/multiarch/wcpncpy-vx.S: Likewise. + * sysdeps/s390/multiarch/wcpncpy.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add stpncpy and + wcpncpy functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for stpncpy, wcpncpy. + * wcsmbs/wcpncpy.c: Use WCPNCPY if defined. + * string/test-stpncpy.c: Add wcpncpy support. + * wcsmbs/test-wcpncpy.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcpncpy. + * benchtests/bench-stpncpy.c: Add wcpncpy support. + * benchtests/bench-wcpncpy.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcpncpy. +--- + benchtests/Makefile | 2 +- + benchtests/bench-stpncpy.c | 40 ++++-- + benchtests/bench-wcpncpy.c | 20 +++ + string/test-stpncpy.c | 40 ++++-- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/stpncpy-c.c | 28 ++++ + sysdeps/s390/multiarch/stpncpy-vx.S | 200 ++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/stpncpy.c | 28 ++++ + sysdeps/s390/multiarch/wcpncpy-c.c | 25 ++++ + sysdeps/s390/multiarch/wcpncpy-vx.S | 222 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcpncpy.c | 28 ++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcpncpy-ifunc.c | 20 +++ + wcsmbs/test-wcpncpy.c | 20 +++ + wcsmbs/wcpncpy.c | 5 + + 16 files changed, 663 insertions(+), 26 deletions(-) + create mode 100644 benchtests/bench-wcpncpy.c + create mode 100644 sysdeps/s390/multiarch/stpncpy-c.c + create mode 100644 sysdeps/s390/multiarch/stpncpy-vx.S + create mode 100644 sysdeps/s390/multiarch/stpncpy.c + create mode 100644 sysdeps/s390/multiarch/wcpncpy-c.c + create mode 100644 sysdeps/s390/multiarch/wcpncpy-vx.S + create mode 100644 sysdeps/s390/multiarch/wcpncpy.c + create mode 100644 wcsmbs/test-wcpncpy-ifunc.c + create mode 100644 wcsmbs/test-wcpncpy.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index f898258..dfab95f 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy ++wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-stpncpy.c b/benchtests/bench-stpncpy.c +index 65ed800..e428102 100644 +--- a/benchtests/bench-stpncpy.c ++++ b/benchtests/bench-stpncpy.c +@@ -18,18 +18,36 @@ + + #define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len))) + #define TEST_MAIN +-#define TEST_NAME "stpncpy" ++#ifndef WIDE ++# define TEST_NAME "stpncpy" ++#else ++# define TEST_NAME "wcpncpy" ++#endif /* WIDE */ + #include "bench-string.h" ++#ifndef WIDE ++# define CHAR char ++# define SIMPLE_STPNCPY simple_stpncpy ++# define STUPID_STPNCPY stupid_stpncpy ++# define STPNCPY stpncpy ++# define STRNLEN strnlen ++#else ++# include ++# define CHAR wchar_t ++# define SIMPLE_STPNCPY simple_wcpncpy ++# define STUPID_STPNCPY stupid_wcpncpy ++# define STPNCPY wcpncpy ++# define STRNLEN wcsnlen ++#endif /* WIDE */ + +-char *simple_stpncpy (char *, const char *, size_t); +-char *stupid_stpncpy (char *, const char *, size_t); ++CHAR *SIMPLE_STPNCPY (CHAR *, const CHAR *, size_t); ++CHAR *STUPID_STPNCPY (CHAR *, const CHAR *, size_t); + +-IMPL (stupid_stpncpy, 0) +-IMPL (simple_stpncpy, 0) +-IMPL (stpncpy, 1) ++IMPL (STUPID_STPNCPY, 0) ++IMPL (SIMPLE_STPNCPY, 0) ++IMPL (STPNCPY, 1) + +-char * +-simple_stpncpy (char *dst, const char *src, size_t n) ++CHAR * ++SIMPLE_STPNCPY (CHAR *dst, const CHAR *src, size_t n) + { + while (n--) + if ((*dst++ = *src++) == '\0') +@@ -43,10 +61,10 @@ simple_stpncpy (char *dst, const char *src, size_t n) + return dst; + } + +-char * +-stupid_stpncpy (char *dst, const char *src, size_t n) ++CHAR * ++STUPID_STPNCPY (CHAR *dst, const CHAR *src, size_t n) + { +- size_t nc = strnlen (src, n); ++ size_t nc = STRNLEN (src, n); + size_t i; + + for (i = 0; i < nc; ++i) +diff --git a/benchtests/bench-wcpncpy.c b/benchtests/bench-wcpncpy.c +new file mode 100644 +index 0000000..8aa529e +--- /dev/null ++++ b/benchtests/bench-wcpncpy.c +@@ -0,0 +1,20 @@ ++/* Measure wcpncpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-stpncpy.c" +diff --git a/string/test-stpncpy.c b/string/test-stpncpy.c +index 8647299..69c8181 100644 +--- a/string/test-stpncpy.c ++++ b/string/test-stpncpy.c +@@ -19,18 +19,36 @@ + + #define STRNCPY_RESULT(dst, len, n) ((dst) + ((len) > (n) ? (n) : (len))) + #define TEST_MAIN +-#define TEST_NAME "stpncpy" ++#ifndef WIDE ++# define TEST_NAME "stpncpy" ++#else ++# define TEST_NAME "wcpncpy" ++#endif /* WIDE */ + #include "test-string.h" ++#ifndef WIDE ++# define CHAR char ++# define SIMPLE_STPNCPY simple_stpncpy ++# define STUPID_STPNCPY stupid_stpncpy ++# define STPNCPY stpncpy ++# define STRNLEN strnlen ++#else ++# include ++# define CHAR wchar_t ++# define SIMPLE_STPNCPY simple_wcpncpy ++# define STUPID_STPNCPY stupid_wcpncpy ++# define STPNCPY wcpncpy ++# define STRNLEN wcsnlen ++#endif /* WIDE */ + +-char *simple_stpncpy (char *, const char *, size_t); +-char *stupid_stpncpy (char *, const char *, size_t); ++CHAR *SIMPLE_STPNCPY (CHAR *, const CHAR *, size_t); ++CHAR *STUPID_STPNCPY (CHAR *, const CHAR *, size_t); + +-IMPL (stupid_stpncpy, 0) +-IMPL (simple_stpncpy, 0) +-IMPL (stpncpy, 1) ++IMPL (STUPID_STPNCPY, 0) ++IMPL (SIMPLE_STPNCPY, 0) ++IMPL (STPNCPY, 1) + +-char * +-simple_stpncpy (char *dst, const char *src, size_t n) ++CHAR * ++SIMPLE_STPNCPY (CHAR *dst, const CHAR *src, size_t n) + { + while (n--) + if ((*dst++ = *src++) == '\0') +@@ -44,10 +62,10 @@ simple_stpncpy (char *dst, const char *src, size_t n) + return dst; + } + +-char * +-stupid_stpncpy (char *dst, const char *src, size_t n) ++CHAR * ++STUPID_STPNCPY (CHAR *dst, const CHAR *src, size_t n) + { +- size_t nc = strnlen (src, n); ++ size_t nc = STRNLEN (src, n); + size_t i; + + for (i = 0; i < nc; ++i) +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 0dff2dc..98b588f 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -3,7 +3,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strnlen strnlen-vx strnlen-c \ + strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ +- strncpy strncpy-vx ++ strncpy strncpy-vx \ ++ stpncpy stpncpy-vx stpncpy-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -11,5 +12,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsnlen wcsnlen-vx wcsnlen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ +- wcsncpy wcsncpy-vx wcsncpy-c ++ wcsncpy wcsncpy-vx wcsncpy-c \ ++ wcpncpy wcpncpy-vx wcpncpy-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 940421d..ca69983 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -94,6 +94,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strncpy); + IFUNC_VX_IMPL (wcsncpy); + ++ IFUNC_VX_IMPL (stpncpy); ++ IFUNC_VX_IMPL (wcpncpy); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/stpncpy-c.c b/sysdeps/s390/multiarch/stpncpy-c.c +new file mode 100644 +index 0000000..40dd8bd +--- /dev/null ++++ b/sysdeps/s390/multiarch/stpncpy-c.c +@@ -0,0 +1,28 @@ ++/* Default stpncpy implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STPNCPY __stpncpy_c ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__stpncpy_c, __GI___stpncpy, __stpncpy_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/stpncpy-vx.S b/sysdeps/s390/multiarch/stpncpy-vx.S +new file mode 100644 +index 0000000..36f6b93 +--- /dev/null ++++ b/sysdeps/s390/multiarch/stpncpy-vx.S +@@ -0,0 +1,200 @@ ++/* Vector optimized 32/64 bit S/390 version of stpncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * stpncpy (char *dest, const char *src, size_t n) ++ Copies at most n characters of string src to dest ++ returning a pointer to its end or dest+n ++ if src is smaller than n. ++ ++ Register usage: ++ -%r0 = return value ++ -%r1 = zero byte index ++ -%r2 = curr dst pointer ++ -%r3 = curr src pointer ++ -%r4 = n ++ -%r5 = current_len ++ -%r6 = loaded bytes ++ -%r7 = border, tmp ++*/ ++ENTRY(__stpncpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r4,0 ++ ber %r14 /* Nothing to do, if n == 0. */ ++ ++ la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r6,%r6 /* Convert 32bit to 64bit. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes ++ -> process remaining. */ ++ ++ /* n > loaded-byte-count */ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, ++ copy and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r7 /* Compute highest index to 16byte boundary. */ ++ ++ /* Zero not found and n > loaded-byte-count. */ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Now we are 16byte aligned, so we can load a full vreg ++ without page fault. */ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ clgijl %r4,17,.Lremaining_v16 /* If n <= 16, process remaining ++ bytes. */ ++.Llt64: ++ lgr %r7,%r4 ++ slgfi %r7,16 /* border_len = n - 16. */ ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border ++ then process remaining bytes. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v18 ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18 ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 ++ vfenezbs %v17,%v16,%v16 ++ je .Lfound_v16 ++ vl %v18,16(%r5,%r3) ++ vst %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lremaining_v18: ++ vlr %v16,%v18 ++.Lremaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Store remaining bytes and append string-termination. */ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ la %r2,0(%r5,%r2) /* vstl has no index register. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */ ++ clrjle %r1,%r7,.Lfound_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null ++ termination! */ ++.Lend: ++ /* Restore saved registers. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++ j .Lfound_v16 ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ aghi %r5,16 ++.Lfound_v18: ++ vlr %v16,%v18 ++.Lfound_v16: ++ /* v16 contains a zero. Store remaining bytes to zero. current_len ++ has not reached border, thus checking for n is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ ++.Lfound_v16_store: ++ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ ++ /* Fill remaining bytes with zero - remaining count always > 0. */ ++ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ ++ slgr %r4,%r5 /* = maxlen - (currlen + zero_index + 1) */ ++ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ ++ lgr %r0,%r2 /* Save return-pointer to found zero. */ ++ clgije %r4,1,.Lend /* Skip zero-filling, if found zero is last ++ possible character. ++ (1 is substracted from r4 below!). */ ++ aghi %r4,-2 /* mvc with exrl needs count - 1. ++ (additional -1, see remaining bytes above) */ ++ srlg %r6,%r4,8 /* Split into 256 byte blocks. */ ++ ltgr %r6,%r6 ++ je .Lzero_lt256 ++.Lzero_loop256: ++ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ ++ la %r2,256(%r2) ++ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ ++.Lzero_lt256: ++ exrl %r4,.Lmvc_lt256 ++ j .Lend ++.Lmvc_lt256: ++ mvc 1(1,%r2),0(%r2) ++ ++.Lloop64: ++ vl %v16,0(%r5,%r3) ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezbs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezbs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ j .Llt64 ++END(__stpncpy_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c +new file mode 100644 +index 0000000..894a33b +--- /dev/null ++++ b/sysdeps/s390/multiarch/stpncpy.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of stpncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__stpncpy) ++weak_alias (__stpncpy, stpncpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/multiarch/wcpncpy-c.c +new file mode 100644 +index 0000000..e49b2ef +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcpncpy-c.c +@@ -0,0 +1,25 @@ ++/* Default wcsncpy implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCPNCPY __wcpncpy_c ++ ++# include ++extern __typeof (__wcpncpy) __wcpncpy_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcpncpy-vx.S b/sysdeps/s390/multiarch/wcpncpy-vx.S +new file mode 100644 +index 0000000..335ea58 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcpncpy-vx.S +@@ -0,0 +1,222 @@ ++/* Vector optimized 32/64 bit S/390 version of wcpncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t * wcpncpy (wchar_t *dest, const wchar_t *src, size_t n) ++ Copies at most n characters of string src to dest ++ returning a pointer to its end or dest+n ++ if src is smaller than n. ++ ++ Register usage: ++ -%r0 = return value ++ -%r1 = zero byte index ++ -%r2 = curr dst pointer ++ -%r3 = curr src pointer ++ -%r4 = n ++ -%r5 = current_len ++ -%r6 = loaded bytes ++ -%r7 = border, tmp ++*/ ++ENTRY(__wcpncpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r4,0 ++ ber %r14 /* Nothing to do, if n == 0. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ ++ tmll %r3,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r6,%r6 /* Convert 32bit to 64bit. */ ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r1,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ la %r0,0(%r4,%r2) /* Save destination pointer + n for return. */ ++ ++ clgrjle %r4,%r6,.Lremaining_v16 /* If n <= loaded-bytes ++ -> process remaining. */ ++ ++ /* n > loaded-byte-count */ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ clrjl %r1,%r6,.Lfound_v16_store /* Found zero within loaded bytes, ++ copy and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r7 /* Compute highest index to 16byte boundary. */ ++ ++ /* Zero not found and n > loaded-byte-count. */ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Now we are 16byte aligned, so we can load a full vreg ++ without page fault. */ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ clgijl %r4,17,.Lremaining_v16 /* If n <=16, ++ process remaining bytes. */ ++.Llt64: ++ lgr %r7,%r4 ++ slgfi %r7,16 /* border_len = n - 16. */ ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 /* If current_len >= border ++ then process remaining bytes. */ ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v18 ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18 ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lremaining_v16 ++ vfenezfs %v17,%v16,%v16 ++ je .Lfound_v16 ++ vl %v18,16(%r5,%r3) ++ vst %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lremaining_v18: ++ vlr %v16,%v18 ++.Lremaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Store remaining bytes and append string-termination. */ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ la %r2,0(%r5,%r2) /* vstl has no index register. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ /* Zero in remaining bytes? -> jump away (zero-index <= max-index). */ ++ clrjle %r1,%r7,.Lfound_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes without null ++ termination! */ ++.Lend: ++ /* Restore saved registers. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lfound_v16_32: ++ aghi %r5,32 ++ j .Lfound_v16 ++.Lfound_v18_48: ++ aghi %r5,32 ++.Lfound_v18_16: ++ aghi %r5,16 ++.Lfound_v18: ++ vlr %v16,%v18 ++.Lfound_v16: ++ /* v16 contains a zero. Store remaining bytes to zero. current_len ++ has not reached border, thus checking for n is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ la %r2,0(%r5,%r2) /* vstl has no support for index-register. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++.Lfound_v16_store: ++ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ ++ /* Fill remaining bytes with zero - remaining byte count always > 0. */ ++ algr %r5,%r1 /* Remaining bytes (=%r4) = ... */ ++ slgr %r4,%r5 /* = n - (currlen + zero_index + 1) */ ++ la %r2,0(%r1,%r2) /* Pointer to zero. start filling beyond. */ ++ lay %r0,-3(%r2) /* Save return-pointer to found zero. */ ++ clgije %r4,1,.Lend /* Skip zero-filling, if found-zero is last ++ possible character. ++ (1 is substracted from r4 below!). */ ++ aghi %r4,-2 /* mvc with exrl needs count - 1. ++ (additional -1, see remaining bytes above) */ ++ srlg %r6,%r4,8 /* Split into 256 byte blocks. */ ++ ltgr %r6,%r6 ++ je .Lzero_lt256 ++.Lzero_loop256: ++ mvc 1(256,%r2),0(%r2) /* Fill 256 zeros at once. */ ++ la %r2,256(%r2) ++ brctg %r6,.Lzero_loop256 /* Loop until all blocks are processed. */ ++.Lzero_lt256: ++ exrl %r4,.Lmvc_lt256 ++ j .Lend ++.Lmvc_lt256: ++ mvc 1(1,%r2),0(%r2) ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lloop64: ++ vl %v16,0(%r5,%r3) ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lfound_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezfs %v17,%v16,%v16 ++ je .Lfound_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezfs %v17,%v18,%v18 ++ je .Lfound_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lloop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ j .Llt64 ++ ++.Lfallback: ++ jg __wcpncpy_c ++END(__wcpncpy_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/multiarch/wcpncpy.c +new file mode 100644 +index 0000000..3db7b8b +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcpncpy.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcpncpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcpncpy) ++weak_alias (__wcpncpy, wcpncpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index c26ab0c..89b5b3b 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy ++ wcpcpy wcsncpy wcpncpy + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcpncpy-ifunc.c b/wcsmbs/test-wcpncpy-ifunc.c +new file mode 100644 +index 0000000..0685487 +--- /dev/null ++++ b/wcsmbs/test-wcpncpy-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcpncpy function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcpncpy.c" +diff --git a/wcsmbs/test-wcpncpy.c b/wcsmbs/test-wcpncpy.c +new file mode 100644 +index 0000000..de302b4 +--- /dev/null ++++ b/wcsmbs/test-wcpncpy.c +@@ -0,0 +1,20 @@ ++/* Test wcpncpy functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-stpncpy.c" +diff --git a/wcsmbs/wcpncpy.c b/wcsmbs/wcpncpy.c +index 2fab857..6337a87 100644 +--- a/wcsmbs/wcpncpy.c ++++ b/wcsmbs/wcpncpy.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WCPNCPY ++# define __wcpncpy WCPNCPY ++#endif + + /* Copy no more than N wide-characters of SRC to DEST, returning the + address of the last character written into DEST. */ +@@ -82,4 +85,6 @@ __wcpncpy (dest, src, n) + return dest - 1; + } + ++#ifndef WCPNCPY + weak_alias (__wcpncpy, wcpncpy) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-16.patch b/SOURCES/glibc-rh1268008-16.patch new file mode 100644 index 00000000..51de403c --- /dev/null +++ b/SOURCES/glibc-rh1268008-16.patch @@ -0,0 +1,1100 @@ +From 43b14a5489db870aeeda0766bde25e29747f6864 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:13:14 +0200 +Subject: [PATCH 16/30] S390: Optimize strcat and wcscat. + +upstream-commit-id: d626a24f235dbd4c446b241211a9a264a1eedb9e +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00155.html + +This patch provides optimized versions of strcat and wcscat with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strcat-c.c: New File. + * sysdeps/s390/multiarch/strcat-vx.S: Likewise. + * sysdeps/s390/multiarch/strcat.c: Likewise. + * sysdeps/s390/multiarch/wcscat-c.c: Likewise. + * sysdeps/s390/multiarch/wcscat-vx.S: Likewise. + * sysdeps/s390/multiarch/wcscat.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strcat and + wcscat functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strcat, wcscat. + * string/strcat.c (STRCAT): Define and use macro. + * wcsmbs/wcscat.c: Use WCSCAT if defined. + * string/test-strcat.c: Add wcscat support. + * wcsmbs/test-wcscat.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcscat. + * benchtests/bench-strcat.c: Add wcscat support. + * benchtests/bench-wcscat.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcscat. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strcat.c | 90 ++++++++++------ + benchtests/bench-wcscat.c | 20 ++++ + string/strcat.c | 8 +- + string/test-strcat.c | 124 ++++++++++++++-------- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strcat-c.c | 28 +++++ + sysdeps/s390/multiarch/strcat-vx.S | 161 ++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strcat.c | 27 +++++ + sysdeps/s390/multiarch/wcscat-c.c | 25 +++++ + sysdeps/s390/multiarch/wcscat-vx.S | 175 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcscat.c | 28 +++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcscat-ifunc.c | 20 ++++ + wcsmbs/test-wcscat.c | 20 ++++ + wcsmbs/wcscat.c | 5 + + 17 files changed, 660 insertions(+), 84 deletions(-) + create mode 100644 benchtests/bench-wcscat.c + create mode 100644 sysdeps/s390/multiarch/strcat-c.c + create mode 100644 sysdeps/s390/multiarch/strcat-vx.S + create mode 100644 sysdeps/s390/multiarch/strcat.c + create mode 100644 sysdeps/s390/multiarch/wcscat-c.c + create mode 100644 sysdeps/s390/multiarch/wcscat-vx.S + create mode 100644 sysdeps/s390/multiarch/wcscat.c + create mode 100644 wcsmbs/test-wcscat-ifunc.c + create mode 100644 wcsmbs/test-wcscat.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index dfab95f..91db23c 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy ++wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strcat.c b/benchtests/bench-strcat.c +index 6602009..1abf6d3 100644 +--- a/benchtests/bench-strcat.c ++++ b/benchtests/bench-strcat.c +@@ -1,5 +1,5 @@ + /* Measure strcat functions. +- Copyright (C) 2013 Free Software Foundation, Inc. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,19 +17,45 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strcat" ++#ifndef WIDE ++# define TEST_NAME "strcat" ++#else ++# define TEST_NAME "wcscat" ++#endif /* WIDE */ + #include "bench-string.h" + +-typedef char *(*proto_t) (char *, const char *); +-char *simple_strcat (char *, const char *); +- +-IMPL (simple_strcat, 0) +-IMPL (strcat, 1) +- +-char * +-simple_strcat (char *dst, const char *src) ++#ifndef WIDE ++# define STRCAT strcat ++# define CHAR char ++# define sfmt "s" ++# define SIMPLE_STRCAT simple_strcat ++# define STRLEN strlen ++# define STRCMP strcmp ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define STRCAT wcscat ++# define CHAR wchar_t ++# define sfmt "ls" ++# define SIMPLE_STRCAT simple_wcscat ++# define STRLEN wcslen ++# define STRCMP wcscmp ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ ++ ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *); ++CHAR *SIMPLE_STRCAT (CHAR *, const CHAR *); ++ ++IMPL (SIMPLE_STRCAT, 0) ++IMPL (STRCAT, 1) ++ ++CHAR * ++SIMPLE_STRCAT (CHAR *dst, const CHAR *src) + { +- char *ret = dst; ++ CHAR *ret = dst; + while (*dst++ != '\0'); + --dst; + while ((*dst++ = *src++) != '\0'); +@@ -37,9 +63,9 @@ simple_strcat (char *dst, const char *src) + } + + static void +-do_one_test (impl_t *impl, char *dst, const char *src) ++do_one_test (impl_t *impl, CHAR *dst, const CHAR *src) + { +- size_t k = strlen (dst), i, iters = INNER_LOOP_ITERS; ++ size_t k = STRLEN (dst), i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; + + if (CALL (impl, dst, src) != dst) +@@ -50,9 +76,9 @@ do_one_test (impl_t *impl, char *dst, const char *src) + return; + } + +- if (strcmp (dst + k, src) != 0) ++ if (STRCMP (dst + k, src) != 0) + { +- error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", ++ error (0, 0, "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"", + impl->name, dst, src); + ret = 1; + return; +@@ -75,18 +101,18 @@ static void + do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + align1 &= 7; +- if (align1 + len1 >= page_size) ++ if ((align1 + len1) * sizeof (CHAR) >= page_size) + return; + + align2 &= 7; +- if (align2 + len1 + len2 >= page_size) ++ if ((align2 + len1 + len2) * sizeof (CHAR) >= page_size) + return; + +- s1 = (char *) (buf1 + align1); +- s2 = (char *) (buf2 + align2); ++ s1 = (CHAR *) (buf1) + align1; ++ s2 = (CHAR *) (buf2) + align2; + + for (i = 0; i < len1; ++i) + s1[i] = 32 + 23 * i % (max_char - 32); +@@ -120,26 +146,26 @@ test_main (void) + + for (i = 0; i < 16; ++i) + { +- do_test (0, 0, i, i, 127); +- do_test (0, 0, i, i, 255); +- do_test (0, i, i, i, 127); +- do_test (i, 0, i, i, 255); ++ do_test (0, 0, i, i, SMALL_CHAR); ++ do_test (0, 0, i, i, BIG_CHAR); ++ do_test (0, i, i, i, SMALL_CHAR); ++ do_test (i, 0, i, i, BIG_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (0, 0, 8 << i, 8 << i, 127); +- do_test (8 - i, 2 * i, 8 << i, 8 << i, 127); +- do_test (0, 0, 8 << i, 2 << i, 127); +- do_test (8 - i, 2 * i, 8 << i, 2 << i, 127); ++ do_test (0, 0, 8 << i, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 8 << i, SMALL_CHAR); ++ do_test (0, 0, 8 << i, 2 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 2 << i, SMALL_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (i, 2 * i, 8 << i, 1, 127); +- do_test (2 * i, i, 8 << i, 1, 255); +- do_test (i, i, 8 << i, 10, 127); +- do_test (i, i, 8 << i, 10, 255); ++ do_test (i, 2 * i, 8 << i, 1, SMALL_CHAR); ++ do_test (2 * i, i, 8 << i, 1, BIG_CHAR); ++ do_test (i, i, 8 << i, 10, SMALL_CHAR); ++ do_test (i, i, 8 << i, 10, BIG_CHAR); + } + + return ret; +diff --git a/benchtests/bench-wcscat.c b/benchtests/bench-wcscat.c +new file mode 100644 +index 0000000..cd0dbc0 +--- /dev/null ++++ b/benchtests/bench-wcscat.c +@@ -0,0 +1,20 @@ ++/* Measure wcscat functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strcat.c" +diff --git a/string/strcat.c b/string/strcat.c +index f9e4bc6..017bb41 100644 +--- a/string/strcat.c ++++ b/string/strcat.c +@@ -20,11 +20,13 @@ + + #undef strcat + ++#ifndef STRCAT ++# define STRCAT strcat ++#endif ++ + /* Append SRC on the end of DEST. */ + char * +-strcat (dest, src) +- char *dest; +- const char *src; ++STRCAT (char *dest, const char *src) + { + char *s1 = dest; + const char *s2 = src; +diff --git a/string/test-strcat.c b/string/test-strcat.c +index 2dc189a..a822733 100644 +--- a/string/test-strcat.c ++++ b/string/test-strcat.c +@@ -18,19 +18,52 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strcat" ++#ifndef WIDE ++# define TEST_NAME "strcat" ++#else ++# define TEST_NAME "wcscat" ++#endif /* WIDE */ + #include "test-string.h" + +-typedef char *(*proto_t) (char *, const char *); +-char *simple_strcat (char *, const char *); ++#ifndef WIDE ++# define STRCAT strcat ++# define CHAR char ++# define UCHAR unsigned char ++# define sfmt "s" ++# define SIMPLE_STRCAT simple_strcat ++# define STRLEN strlen ++# define STRCMP strcmp ++# define MEMSET memset ++# define MEMCPY memcpy ++# define MEMCMP memcmp ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define STRCAT wcscat ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define sfmt "ls" ++# define SIMPLE_STRCAT simple_wcscat ++# define STRLEN wcslen ++# define STRCMP wcscmp ++# define MEMSET wmemset ++# define MEMCPY wmemcpy ++# define MEMCMP wmemcmp ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ + +-IMPL (simple_strcat, 0) +-IMPL (strcat, 1) ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *); ++CHAR *SIMPLE_STRCAT (CHAR *, const CHAR *); + +-char * +-simple_strcat (char *dst, const char *src) ++IMPL (SIMPLE_STRCAT, 0) ++IMPL (STRCAT, 1) ++ ++CHAR * ++SIMPLE_STRCAT (CHAR *dst, const CHAR *src) + { +- char *ret = dst; ++ CHAR *ret = dst; + while (*dst++ != '\0'); + --dst; + while ((*dst++ = *src++) != '\0'); +@@ -38,9 +71,9 @@ simple_strcat (char *dst, const char *src) + } + + static void +-do_one_test (impl_t *impl, char *dst, const char *src) ++do_one_test (impl_t *impl, CHAR *dst, const char *src) + { +- size_t k = strlen (dst); ++ size_t k = STRLEN (dst); + if (CALL (impl, dst, src) != dst) + { + error (0, 0, "Wrong result in function %s %p %p", impl->name, +@@ -49,9 +82,9 @@ do_one_test (impl_t *impl, char *dst, const char *src) + return; + } + +- if (strcmp (dst + k, src) != 0) ++ if (STRCMP (dst + k, src) != 0) + { +- error (0, 0, "Wrong result in function %s dst \"%s\" src \"%s\"", ++ error (0, 0, "Wrong result in function %s dst \"%" sfmt "\" src \"%" sfmt "\"", + impl->name, dst, src); + ret = 1; + return; +@@ -62,18 +95,18 @@ static void + do_test (size_t align1, size_t align2, size_t len1, size_t len2, int max_char) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + align1 &= 7; +- if (align1 + len1 >= page_size) ++ if ((align1 + len1) * sizeof (CHAR) >= page_size) + return; + + align2 &= 7; +- if (align2 + len1 + len2 >= page_size) ++ if ((align2 + len1 + len2) * sizeof (CHAR) >= page_size) + return; + +- s1 = (char *) (buf1 + align1); +- s2 = (char *) (buf2 + align2); ++ s1 = (CHAR *) (buf1) + align1; ++ s2 = (CHAR *) (buf2) + align2; + + for (i = 0; i < len1; ++i) + s1[i] = 32 + 23 * i % (max_char - 32); +@@ -93,9 +126,10 @@ static void + do_random_tests (void) + { + size_t i, j, n, align1, align2, len1, len2; +- unsigned char *p1 = buf1 + page_size - 512; +- unsigned char *p2 = buf2 + page_size - 512; +- unsigned char *res; ++ UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512; ++ UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512; ++ UCHAR *p3 = (UCHAR *) buf1; ++ UCHAR *res; + + for (n = 0; n < ITERATIONS; n++) + { +@@ -132,26 +166,26 @@ do_random_tests (void) + p1[i] = 0; + else + { +- p1[i] = random () & 255; ++ p1[i] = random () & BIG_CHAR; + if (i >= align1 && i < len1 + align1 && !p1[i]) +- p1[i] = (random () & 127) + 3; ++ p1[i] = (random () & SMALL_CHAR) + 3; + } + } + for (i = 0; i < len2; i++) + { +- buf1[i] = random () & 255; +- if (!buf1[i]) +- buf1[i] = (random () & 127) + 3; ++ p3[i] = random () & BIG_CHAR; ++ if (!p3[i]) ++ p3[i] = (random () & SMALL_CHAR) + 3; + } +- buf1[len2] = 0; ++ p3[len2] = 0; + + FOR_EACH_IMPL (impl, 1) + { +- memset (p2 - 64, '\1', align2 + 64); +- memset (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1); +- memcpy (p2 + align2, buf1, len2 + 1); +- res = (unsigned char *) CALL (impl, (char *) (p2 + align2), +- (char *) (p1 + align1)); ++ MEMSET (p2 - 64, '\1', align2 + 64); ++ MEMSET (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1); ++ MEMCPY (p2 + align2, p3, len2 + 1); ++ res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2), ++ (CHAR *) (p1 + align1)); + if (res != p2 + align2) + { + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd %zd) %p != %p", +@@ -169,7 +203,7 @@ do_random_tests (void) + break; + } + } +- if (memcmp (p2 + align2, buf1, len2)) ++ if (MEMCMP (p2 + align2, p3, len2)) + { + error (0, 0, "Iteration %zd - garbage in string before, %s (%zd, %zd, %zd, %zd)", + n, impl->name, align1, align2, len1, len2); +@@ -185,7 +219,7 @@ do_random_tests (void) + break; + } + } +- if (memcmp (p1 + align1, p2 + align2 + len2, len1 + 1)) ++ if (MEMCMP (p1 + align1, p2 + align2 + len2, len1 + 1)) + { + error (0, 0, "Iteration %zd - different strings, %s (%zd, %zd, %zd, %zd)", + n, impl->name, align1, align2, len1, len2); +@@ -209,26 +243,26 @@ test_main (void) + + for (i = 0; i < 16; ++i) + { +- do_test (0, 0, i, i, 127); +- do_test (0, 0, i, i, 255); +- do_test (0, i, i, i, 127); +- do_test (i, 0, i, i, 255); ++ do_test (0, 0, i, i, SMALL_CHAR); ++ do_test (0, 0, i, i, BIG_CHAR); ++ do_test (0, i, i, i, SMALL_CHAR); ++ do_test (i, 0, i, i, BIG_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (0, 0, 8 << i, 8 << i, 127); +- do_test (8 - i, 2 * i, 8 << i, 8 << i, 127); +- do_test (0, 0, 8 << i, 2 << i, 127); +- do_test (8 - i, 2 * i, 8 << i, 2 << i, 127); ++ do_test (0, 0, 8 << i, 8 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 8 << i, SMALL_CHAR); ++ do_test (0, 0, 8 << i, 2 << i, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 2 << i, SMALL_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (i, 2 * i, 8 << i, 1, 127); +- do_test (2 * i, i, 8 << i, 1, 255); +- do_test (i, i, 8 << i, 10, 127); +- do_test (i, i, 8 << i, 10, 255); ++ do_test (i, 2 * i, 8 << i, 1, SMALL_CHAR); ++ do_test (2 * i, i, 8 << i, 1, BIG_CHAR); ++ do_test (i, i, 8 << i, 10, SMALL_CHAR); ++ do_test (i, i, 8 << i, 10, BIG_CHAR); + } + + do_random_tests (); +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 98b588f..6283999 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -4,7 +4,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strcpy strcpy-vx \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ +- stpncpy stpncpy-vx stpncpy-c ++ stpncpy stpncpy-vx stpncpy-c \ ++ strcat strcat-vx strcat-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -13,5 +14,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscpy wcscpy-vx wcscpy-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ +- wcpncpy wcpncpy-vx wcpncpy-c ++ wcpncpy wcpncpy-vx wcpncpy-c \ ++ wcscat wcscat-vx wcscat-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ca69983..ccf4dea 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -97,6 +97,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (stpncpy); + IFUNC_VX_IMPL (wcpncpy); + ++ IFUNC_VX_IMPL (strcat); ++ IFUNC_VX_IMPL (wcscat); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strcat-c.c b/sysdeps/s390/multiarch/strcat-c.c +new file mode 100644 +index 0000000..da4fad8 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcat-c.c +@@ -0,0 +1,28 @@ ++/* Default strcat implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRCAT __strcat_c ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcat_c, __GI_strcat, __strcat_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strcat-vx.S b/sysdeps/s390/multiarch/strcat-vx.S +new file mode 100644 +index 0000000..3915097 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcat-vx.S +@@ -0,0 +1,161 @@ ++/* Vector optimized 32/64 bit S/390 version of strcat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * strcat (const char *dest, const char *src) ++ Concatenate two strings. ++ ++ Register usage: ++ -r0=saved dest pointer for return ++ -r1=tmp ++ -r2=dest ++ -r3=src ++ -r4=tmp ++ -r5=current_len ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++*/ ++ENTRY(__strcat_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ lgr %r0,%r2 /* Save destination pointer for return. */ ++ ++ /* STRLEN ++ r1 = loaded bytes (tmp) ++ r4 = zero byte index (tmp) ++ r2 = dst ++ */ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Llen_loop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Llen_found /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Llen_found16 ++ vl %v16,32(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Llen_found32 ++ vl %v16,48(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Llen_found48 ++ ++ aghi %r5,64 ++ j .Llen_loop /* No zero -> loop. */ ++ ++.Llen_found48: ++ aghi %r5,16 ++.Llen_found32: ++ aghi %r5,16 ++.Llen_found16: ++ aghi %r5,16 ++.Llen_found: ++ vlgvb %r4,%v16,7 /* Load byte index of zero. */ ++ algr %r5,%r4 ++ ++.Llen_end: ++ /* STRCPY ++ %r1 = loaded bytes (tmp) ++ %r4 = zero byte index (tmp) ++ %r3 = curr src pointer ++ %r2 = curr dst pointer ++ */ ++ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes, ++ copy bytes before and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r4 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lcpy_loop: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lcpy_found_v16_0 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3)/* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezbs %v17,%v18,%v18 ++ je .Lcpy_found_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezbs %v17,%v16,%v16 ++ je .Lcpy_found_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezbs %v17,%v18,%v18 ++ je .Lcpy_found_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ j .Lcpy_loop /* No zero -> loop. */ ++ ++.Lcpy_found_v16_32: ++ aghi %r5,32 ++.Lcpy_found_v16_0: ++ la %r4,0(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ vstl %v16,%r1,0(%r4) /* Copy characters including zero. */ ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lcpy_found_v18_48: ++ aghi %r5,32 ++.Lcpy_found_v18_16: ++ la %r4,16(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ vstl %v18,%r1,0(%r4) /* Copy characters including zero. */ ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lcpy_found_align: ++ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++END(__strcat_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c +new file mode 100644 +index 0000000..8b5c47e +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcat.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of strcat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strcat, strcat) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/multiarch/wcscat-c.c +new file mode 100644 +index 0000000..49fb64b +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscat-c.c +@@ -0,0 +1,25 @@ ++/* Default wcscat implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSCAT __wcscat_c ++ ++# include ++extern __typeof (__wcscat) __wcscat_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcscat-vx.S b/sysdeps/s390/multiarch/wcscat-vx.S +new file mode 100644 +index 0000000..7ee185f +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscat-vx.S +@@ -0,0 +1,175 @@ ++/* Vector optimized 32/64 bit S/390 version of wcscat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t * wcscat (wchar_t *dest, const wchar_t *src) ++ Concatenate two strings. ++ ++ Register usage: ++ -r0=saved dest pointer for return ++ -r1=tmp ++ -r2=dest ++ -r3=src ++ -r4=tmp ++ -r5=current_len ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++*/ ++ENTRY(__wcscat_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ /* __wcslen_c can handle non 4byte aligned pointers, ++ but __wcscpy_c not. Thus if either src or dest is ++ not 4byte aligned, use __wcscat_c. */ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ tmll %r3,3 /* Test if src is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ lgr %r0,%r2 /* Save destination pointer for return. */ ++ ++ /* WCSLEN ++ r1 = loaded bytes (tmp) ++ r4 = zero byte index (tmp) ++ r2 = dst ++ */ ++ ++ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Llen_loop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Llen_found /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Llen_found16 ++ vl %v16,32(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Llen_found32 ++ vl %v16,48(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Llen_found48 ++ ++ aghi %r5,64 ++ j .Llen_loop /* No zero -> loop. */ ++ ++.Llen_found48: ++ aghi %r5,16 ++.Llen_found32: ++ aghi %r5,16 ++.Llen_found16: ++ aghi %r5,16 ++.Llen_found: ++ vlgvb %r4,%v16,7 /* Load byte index of zero. */ ++ algr %r5,%r4 ++ ++.Llen_end: ++ /* WCSCPY ++ %r1 = loaded bytes (tmp) ++ %r4 = zero byte index (tmp) ++ %r3 = curr src pointer ++ %r2 = curr dst pointer ++ */ ++ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Lcpy_found_align /* If found zero within loaded bytes, ++ copy bytes before and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r4 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lcpy_loop: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lcpy_found_v16_0 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ ++ vfenezfs %v17,%v18,%v18 ++ je .Lcpy_found_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezfs %v17,%v16,%v16 ++ je .Lcpy_found_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezfs %v17,%v18,%v18 ++ je .Lcpy_found_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ j .Lcpy_loop /* No zero -> loop. */ ++ ++.Lcpy_found_v16_32: ++ aghi %r5,32 ++.Lcpy_found_v16_0: ++ la %r4,0(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v16,%r1,0(%r4) /* Copy characters including zero. */ ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lcpy_found_v18_48: ++ aghi %r5,32 ++.Lcpy_found_v18_16: ++ la %r4,16(%r5,%r2) ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v18,%r1,0(%r4) /* Copy characters including zero. */ ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lcpy_found_align: ++ aghi %r5,3 /* Also copy remaining bytes of found zero. */ ++ vstl %v16,%r5,0(%r2) /* Copy characters including zero. */ ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++.Lfallback: ++ jg __wcscat_c ++END(__wcscat_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/multiarch/wcscat.c +new file mode 100644 +index 0000000..c6fdaa7 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscat.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcscat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcscat) ++weak_alias (__wcscat, wcscat) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 89b5b3b..9bfc78c 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy wcpncpy ++ wcpcpy wcsncpy wcpncpy wcscat + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcscat-ifunc.c b/wcsmbs/test-wcscat-ifunc.c +new file mode 100644 +index 0000000..53305c6 +--- /dev/null ++++ b/wcsmbs/test-wcscat-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcscat function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcscat.c" +diff --git a/wcsmbs/test-wcscat.c b/wcsmbs/test-wcscat.c +new file mode 100644 +index 0000000..9bab33b +--- /dev/null ++++ b/wcsmbs/test-wcscat.c +@@ -0,0 +1,20 @@ ++/* Test wcscat functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strcat.c" +diff --git a/wcsmbs/wcscat.c b/wcsmbs/wcscat.c +index 0d34d76..4eb2d93 100644 +--- a/wcsmbs/wcscat.c ++++ b/wcsmbs/wcscat.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WCSCAT ++# define __wcscat WCSCAT ++#endif + + /* Append SRC on the end of DEST. */ + wchar_t * +@@ -47,4 +50,6 @@ __wcscat (dest, src) + + return dest; + } ++#ifndef WCSCAT + weak_alias (__wcscat, wcscat) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-17.patch b/SOURCES/glibc-rh1268008-17.patch new file mode 100644 index 00000000..6e11297c --- /dev/null +++ b/SOURCES/glibc-rh1268008-17.patch @@ -0,0 +1,1256 @@ +From 712d46fa89e1341b3bffc27ca2ab5d892e4b14e1 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:16:05 +0200 +Subject: [PATCH 17/30] S390: Optimize strncat wcsncat. + +upstream-commit-id: e1fe91180e4e29549f35f8ecd705b0bb4f208606 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00162.html + +This patch provides optimized versions of strncat and wcsncat with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strncat-c.c: New File. + * sysdeps/s390/multiarch/strncat-vx.S: Likewise. + * sysdeps/s390/multiarch/strncat.c: Likewise. + * sysdeps/s390/multiarch/wcsncat-c.c: Likewise. + * sysdeps/s390/multiarch/wcsncat-vx.S: Likewise. + * sysdeps/s390/multiarch/wcsncat.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strncat and + wcsncat functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strncat, wcsncat. + * wcsmbs/wcsncat.c (WCSNCAT): Define and use macro. + * string/test-strncat.c: Add wcsncat support. + * wcsmbs/test-wcsncat.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcsncat. + * benchtests/bench-strncat.c: Add wcsncat support. + * benchtests/bench-wcsncat.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcsncat. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strncat.c | 99 +++++++----- + benchtests/bench-wcsncat.c | 20 +++ + string/test-strncat.c | 132 +++++++++------ + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strncat-c.c | 23 +++ + sysdeps/s390/multiarch/strncat-vx.S | 239 ++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strncat.c | 27 ++++ + sysdeps/s390/multiarch/wcsncat-c.c | 25 +++ + sysdeps/s390/multiarch/wcsncat-vx.S | 265 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcsncat.c | 27 ++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcsncat-ifunc.c | 20 +++ + wcsmbs/test-wcsncat.c | 20 +++ + wcsmbs/wcsncat.c | 5 +- + 16 files changed, 823 insertions(+), 92 deletions(-) + create mode 100644 benchtests/bench-wcsncat.c + create mode 100644 sysdeps/s390/multiarch/strncat-c.c + create mode 100644 sysdeps/s390/multiarch/strncat-vx.S + create mode 100644 sysdeps/s390/multiarch/strncat.c + create mode 100644 sysdeps/s390/multiarch/wcsncat-c.c + create mode 100644 sysdeps/s390/multiarch/wcsncat-vx.S + create mode 100644 sysdeps/s390/multiarch/wcsncat.c + create mode 100644 wcsmbs/test-wcsncat-ifunc.c + create mode 100644 wcsmbs/test-wcsncat.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 91db23c..fd8b7ee 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat ++wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strncat.c b/benchtests/bench-strncat.c +index 2a17817..8f3339d 100644 +--- a/benchtests/bench-strncat.c ++++ b/benchtests/bench-strncat.c +@@ -1,5 +1,5 @@ + /* Measure strncat functions. +- Copyright (C) 2013 Free Software Foundation, Inc. ++ Copyright (C) 2013-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,33 +17,58 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strncat" ++#ifndef WIDE ++# define TEST_NAME "strncat" ++#else ++# define TEST_NAME "wcsncat" ++#endif /* WIDE */ + #include "bench-string.h" + +-typedef char *(*proto_t) (char *, const char *, size_t); +-char *stupid_strncat (char *, const char *, size_t); +-char *simple_strncat (char *, const char *, size_t); +- +-IMPL (stupid_strncat, 0) +-IMPL (strncat, 2) +- +-char * +-stupid_strncat (char *dst, const char *src, size_t n) ++#ifndef WIDE ++# define STRNCAT strncat ++# define CHAR char ++# define SIMPLE_STRNCAT simple_strncat ++# define STUPID_STRNCAT stupid_strncat ++# define STRLEN strlen ++# define MEMCMP memcmp ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define STRNCAT wcsncat ++# define CHAR wchar_t ++# define SIMPLE_STRNCAT simple_wcsncat ++# define STUPID_STRNCAT stupid_wcsncat ++# define STRLEN wcslen ++# define MEMCMP wmemcmp ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); ++CHAR *STUPID_STRNCAT (CHAR *, const CHAR *, size_t); ++CHAR *SIMPLE_STRNCAT (CHAR *, const CHAR *, size_t); ++ ++IMPL (STUPID_STRNCAT, 0) ++IMPL (STRNCAT, 2) ++ ++CHAR * ++STUPID_STRNCAT (CHAR *dst, const CHAR *src, size_t n) + { +- char *ret = dst; ++ CHAR *ret = dst; + while (*dst++ != '\0'); + --dst; + while (n--) +- if ( (*dst++ = *src++) == '\0') ++ if ((*dst++ = *src++) == '\0') + return ret; + *dst = '\0'; + return ret; + } + + static void +-do_one_test (impl_t *impl, char *dst, const char *src, size_t n) ++do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t n) + { +- size_t k = strlen (dst), i, iters = INNER_LOOP_ITERS; ++ size_t k = STRLEN (dst), i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; + + if (CALL (impl, dst, src, n) != dst) +@@ -54,10 +79,10 @@ do_one_test (impl_t *impl, char *dst, const char *src, size_t n) + return; + } + +- size_t len = strlen (src); +- if (memcmp (dst + k, src, len + 1 > n ? n : len + 1) != 0) ++ size_t len = STRLEN (src); ++ if (MEMCMP (dst + k, src, len + 1 > n ? n : len + 1) != 0) + { +- error (0, 0, "Incorrect cancatination in function %s", ++ error (0, 0, "Incorrect concatenation in function %s", + impl->name); + ret = 1; + return; +@@ -88,20 +113,20 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2, + size_t n, int max_char) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + align1 &= 7; +- if (align1 + len1 >= page_size) ++ if ((align1 + len1) * sizeof (CHAR) >= page_size) + return; +- if (align1 + n > page_size) ++ if ((align1 + n) * sizeof (CHAR) > page_size) + return; + align2 &= 7; +- if (align2 + len1 + len2 >= page_size) ++ if ((align2 + len1 + len2) * sizeof (CHAR) >= page_size) + return; +- if (align2 + len1 + n > page_size) ++ if ((align2 + len1 + n) * sizeof (CHAR) > page_size) + return; +- s1 = (char *) (buf1 + align1); +- s2 = (char *) (buf2 + align2); ++ s1 = (CHAR *) (buf1) + align1; ++ s2 = (CHAR *) (buf2) + align2; + + for (i = 0; i < len1; ++i) + s1[i] = 32 + 23 * i % (max_char - 32); +@@ -136,25 +161,25 @@ main (void) + + for (n = 2; n <= 2048; n*=4) + { +- do_test (0, 2, 2, 2, n, 127); +- do_test (0, 0, 4, 4, n, 127); +- do_test (4, 0, 4, 4, n, 255); +- do_test (0, 0, 8, 8, n, 127); +- do_test (0, 8, 8, 8, n, 127); ++ do_test (0, 2, 2, 2, n, SMALL_CHAR); ++ do_test (0, 0, 4, 4, n, SMALL_CHAR); ++ do_test (4, 0, 4, 4, n, BIG_CHAR); ++ do_test (0, 0, 8, 8, n, SMALL_CHAR); ++ do_test (0, 8, 8, 8, n, SMALL_CHAR); + + for (i = 1; i < 8; ++i) + { +- do_test (0, 0, 8 << i, 8 << i, n, 127); +- do_test (8 - i, 2 * i, 8 << i, 8 << i, n, 127); +- do_test (0, 0, 8 << i, 2 << i, n, 127); +- do_test (8 - i, 2 * i, 8 << i, 2 << i, n, 127); ++ do_test (0, 0, 8 << i, 8 << i, n, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 8 << i, n, SMALL_CHAR); ++ do_test (0, 0, 8 << i, 2 << i, n, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 2 << i, n, SMALL_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (i, 2 * i, 8 << i, 1, n, 127); +- do_test (2 * i, i, 8 << i, 1, n, 255); +- do_test (i, i, 8 << i, 10, n, 127); ++ do_test (i, 2 * i, 8 << i, 1, n, SMALL_CHAR); ++ do_test (2 * i, i, 8 << i, 1, n, BIG_CHAR); ++ do_test (i, i, 8 << i, 10, n, SMALL_CHAR); + } + } + +diff --git a/benchtests/bench-wcsncat.c b/benchtests/bench-wcsncat.c +new file mode 100644 +index 0000000..b9d7c3f +--- /dev/null ++++ b/benchtests/bench-wcsncat.c +@@ -0,0 +1,20 @@ ++/* Measure wcsncat functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strncat.c" +diff --git a/string/test-strncat.c b/string/test-strncat.c +index 2bfe25f..790d8aa 100644 +--- a/string/test-strncat.c ++++ b/string/test-strncat.c +@@ -17,33 +17,64 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strncat" ++#ifndef WIDE ++# define TEST_NAME "strncat" ++#else ++# define TEST_NAME "wcsncat" ++#endif /* WIDE */ + #include "test-string.h" + +-typedef char *(*proto_t) (char *, const char *, size_t); +-char *stupid_strncat (char *, const char *, size_t); +-char *simple_strncat (char *, const char *, size_t); ++#ifndef WIDE ++# define STRNCAT strncat ++# define CHAR char ++# define UCHAR unsigned char ++# define SIMPLE_STRNCAT simple_strncat ++# define STUPID_STRNCAT stupid_strncat ++# define STRLEN strlen ++# define MEMSET memset ++# define MEMCPY memcpy ++# define MEMCMP memcmp ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define STRNCAT wcsncat ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define SIMPLE_STRNCAT simple_wcsncat ++# define STUPID_STRNCAT stupid_wcsncat ++# define STRLEN wcslen ++# define MEMSET wmemset ++# define MEMCPY wmemcpy ++# define MEMCMP wmemcmp ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ + +-IMPL (stupid_strncat, 0) +-IMPL (strncat, 2) ++typedef CHAR *(*proto_t) (CHAR *, const CHAR *, size_t); ++CHAR *STUPID_STRNCAT (CHAR *, const CHAR *, size_t); ++CHAR *SIMPLE_STRNCAT (CHAR *, const CHAR *, size_t); + +-char * +-stupid_strncat (char *dst, const char *src, size_t n) ++IMPL (STUPID_STRNCAT, 0) ++IMPL (STRNCAT, 2) ++ ++CHAR * ++STUPID_STRNCAT (CHAR *dst, const CHAR *src, size_t n) + { +- char *ret = dst; ++ CHAR *ret = dst; + while (*dst++ != '\0'); + --dst; + while (n--) +- if ( (*dst++ = *src++) == '\0') ++ if ((*dst++ = *src++) == '\0') + return ret; + *dst = '\0'; + return ret; + } + + static void +-do_one_test (impl_t *impl, char *dst, const char *src, size_t n) ++do_one_test (impl_t *impl, CHAR *dst, const CHAR *src, size_t n) + { +- size_t k = strlen (dst); ++ size_t k = STRLEN (dst); + if (CALL (impl, dst, src, n) != dst) + { + error (0, 0, "Wrong result in function %s %p != %p", impl->name, +@@ -52,10 +83,10 @@ do_one_test (impl_t *impl, char *dst, const char *src, size_t n) + return; + } + +- size_t len = strlen (src); +- if (memcmp (dst + k, src, len + 1 > n ? n : len + 1) != 0) ++ size_t len = STRLEN (src); ++ if (MEMCMP (dst + k, src, len + 1 > n ? n : len + 1) != 0) + { +- error (0, 0, "Incorrect cancatination in function %s", ++ error (0, 0, "Incorrect concatenation in function %s", + impl->name); + ret = 1; + return; +@@ -74,20 +105,20 @@ do_test (size_t align1, size_t align2, size_t len1, size_t len2, + size_t n, int max_char) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + align1 &= 7; +- if (align1 + len1 >= page_size) ++ if ((align1 + len1) * sizeof (CHAR) >= page_size) + return; +- if (align1 + n > page_size) ++ if ((align1 + n) * sizeof (CHAR) > page_size) + return; + align2 &= 7; +- if (align2 + len1 + len2 >= page_size) ++ if ((align2 + len1 + len2) * sizeof (CHAR) >= page_size) + return; +- if (align2 + len1 + n > page_size) ++ if ((align2 + len1 + n) * sizeof (CHAR) > page_size) + return; +- s1 = (char *) (buf1 + align1); +- s2 = (char *) (buf2 + align2); ++ s1 = (CHAR *) (buf1) + align1; ++ s2 = (CHAR *) (buf2) + align2; + + for (i = 0; i < len1; ++i) + s1[i] = 32 + 23 * i % (max_char - 32); +@@ -107,9 +138,10 @@ static void + do_random_tests (void) + { + size_t i, j, n, align1, align2, len1, len2, N; +- unsigned char *p1 = buf1 + page_size - 512; +- unsigned char *p2 = buf2 + page_size - 512; +- unsigned char *res; ++ UCHAR *p1 = (UCHAR *) (buf1 + page_size) - 512; ++ UCHAR *p2 = (UCHAR *) (buf2 + page_size) - 512; ++ UCHAR *p3 = (UCHAR *) buf1; ++ UCHAR *res; + fprintf (stdout, "Number of iterations in random test = %zd\n", + ITERATIONS); + for (n = 0; n < ITERATIONS; n++) +@@ -148,26 +180,26 @@ do_random_tests (void) + p1[i] = 0; + else + { +- p1[i] = random () & 255; ++ p1[i] = random () & BIG_CHAR; + if (i >= align1 && i < len1 + align1 && !p1[i]) +- p1[i] = (random () & 127) + 3; ++ p1[i] = (random () & SMALL_CHAR) + 3; + } + } + for (i = 0; i < len2; i++) + { +- buf1[i] = random () & 255; +- if (!buf1[i]) +- buf1[i] = (random () & 127) + 3; ++ p3[i] = random () & BIG_CHAR; ++ if (!p3[i]) ++ p3[i] = (random () & SMALL_CHAR) + 3; + } +- buf1[len2] = 0; ++ p3[len2] = 0; + + FOR_EACH_IMPL (impl, 1) + { +- memset (p2 - 64, '\1', align2 + 64); +- memset (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1); +- memcpy (p2 + align2, buf1, len2 + 1); +- res = (unsigned char *) CALL (impl, (char *) (p2 + align2), +- (char *) (p1 + align1), N); ++ MEMSET (p2 - 64, '\1', align2 + 64); ++ MEMSET (p2 + align2 + len2 + 1, '\1', 512 - align2 - len2 - 1); ++ MEMCPY (p2 + align2, p3, len2 + 1); ++ res = (UCHAR *) CALL (impl, (CHAR *) (p2 + align2), ++ (CHAR *) (p1 + align1), N); + if (res != p2 + align2) + { + error (0, 0, "Iteration %zd - wrong result in function %s " +@@ -187,7 +219,7 @@ do_random_tests (void) + break; + } + } +- if (memcmp (p2 + align2, buf1, len2)) ++ if (MEMCMP (p2 + align2, p3, len2)) + { + error (0, 0, "Iteration %zd - garbage in string before, %s " + "(%zd, %zd, %zd, %zd, %zd)", +@@ -220,7 +252,7 @@ do_random_tests (void) + ret = 1; + } + } +- if (memcmp (p1 + align1, p2 + align2 + len2, ++ if (MEMCMP (p1 + align1, p2 + align2 + len2, + (len1 + 1) > N ? N : len1 + 1)) + { + error (0, 0, "Iteration %zd - different strings, %s " +@@ -246,25 +278,25 @@ main (void) + + for (n = 2; n <= 2048; n*=4) + { +- do_test (0, 2, 2, 2, n, 127); +- do_test (0, 0, 4, 4, n, 127); +- do_test (4, 0, 4, 4, n, 255); +- do_test (0, 0, 8, 8, n, 127); +- do_test (0, 8, 8, 8, n, 127); ++ do_test (0, 2, 2, 2, n, SMALL_CHAR); ++ do_test (0, 0, 4, 4, n, SMALL_CHAR); ++ do_test (4, 0, 4, 4, n, BIG_CHAR); ++ do_test (0, 0, 8, 8, n, SMALL_CHAR); ++ do_test (0, 8, 8, 8, n, SMALL_CHAR); + + for (i = 1; i < 8; ++i) + { +- do_test (0, 0, 8 << i, 8 << i, n, 127); +- do_test (8 - i, 2 * i, 8 << i, 8 << i, n, 127); +- do_test (0, 0, 8 << i, 2 << i, n, 127); +- do_test (8 - i, 2 * i, 8 << i, 2 << i, n, 127); ++ do_test (0, 0, 8 << i, 8 << i, n, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 8 << i, n, SMALL_CHAR); ++ do_test (0, 0, 8 << i, 2 << i, n, SMALL_CHAR); ++ do_test (8 - i, 2 * i, 8 << i, 2 << i, n, SMALL_CHAR); + } + + for (i = 1; i < 8; ++i) + { +- do_test (i, 2 * i, 8 << i, 1, n, 127); +- do_test (2 * i, i, 8 << i, 1, n, 255); +- do_test (i, i, 8 << i, 10, n, 127); ++ do_test (i, 2 * i, 8 << i, 1, n, SMALL_CHAR); ++ do_test (2 * i, i, 8 << i, 1, n, BIG_CHAR); ++ do_test (i, i, 8 << i, 10, n, SMALL_CHAR); + } + } + +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 6283999..33c1398 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -5,7 +5,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + stpcpy stpcpy-vx stpcpy-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ +- strcat strcat-vx strcat-c ++ strcat strcat-vx strcat-c \ ++ strncat strncat-vx strncat-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -15,5 +16,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcpcpy wcpcpy-vx wcpcpy-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ +- wcscat wcscat-vx wcscat-c ++ wcscat wcscat-vx wcscat-c \ ++ wcsncat wcsncat-vx wcsncat-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ccf4dea..1e57c0e 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -100,6 +100,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strcat); + IFUNC_VX_IMPL (wcscat); + ++ IFUNC_VX_IMPL (strncat); ++ IFUNC_VX_IMPL (wcsncat); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strncat-c.c b/sysdeps/s390/multiarch/strncat-c.c +new file mode 100644 +index 0000000..f90f0e0 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncat-c.c +@@ -0,0 +1,23 @@ ++/* Default strncat implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRNCAT __strncat_c ++ ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/strncat-vx.S b/sysdeps/s390/multiarch/strncat-vx.S +new file mode 100644 +index 0000000..7f35696 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncat-vx.S +@@ -0,0 +1,239 @@ ++/* Vector optimized 32/64 bit S/390 version of strncat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char * strncat (const char *dest, const char *src, size_t n) ++ Concatenate two strings - at most n characters of src. ++ ++ Register usage: ++ -r0=saved dest pointer for return ++ -r1=tmp ++ -r2=dest ++ -r3=src ++ -r4=n ++ -r5=current_len ++ -r6=tmp ++ -r7=tmp ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++ -v31=register save area for r6, r7 ++*/ ++ENTRY(__strncat_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r4,0 ++ ber %r14 /* Nothing to do, if n == 0. */ ++ lgr %r0,%r2 /* Save destination pointer for return. */ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ ++ /* STRLEN ++ %r1 = loaded bytes (tmp) ++ %r6 = zero byte index (tmp) ++ %r2 = dst ++ */ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfenezb %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Llen_loop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezbs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Llen_found /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Llen_found16 ++ vl %v16,32(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Llen_found32 ++ vl %v16,48(%r5,%r2) ++ vfenezbs %v16,%v16,%v16 ++ je .Llen_found48 ++ ++ aghi %r5,64 ++ j .Llen_loop /* No zero -> loop. */ ++ ++.Llen_found48: ++ aghi %r5,16 ++.Llen_found32: ++ aghi %r5,16 ++.Llen_found16: ++ aghi %r5,16 ++.Llen_found: ++ vlgvb %r1,%v16,7 /* Load byte index of zero. */ ++ algr %r5,%r1 ++ ++.Llen_end: ++ /* STRCPY ++ %r1 = zero byte index (tmp) ++ %r6 = loaded bytes (tmp) ++ %r3 = curr src pointer ++ %r2 = curr dst pointer ++ %r7 = border, tmp ++ */ ++ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r6,%r6 /* Convert 32bit to 64bit. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes ++ -> process remaining. */ ++ ++ /* n > loaded-byte-count. */ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded ++ bytes, copy and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r7,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r7 /* Compute highest index to 16byte boundary. */ ++ ++ /* Zero not found and n > loaded-byte-count. */ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* ++ Now we are 16byte aligned, so we can load a full vreg ++ without page fault. ++ */ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lcpy_loop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16, ++ process remaining bytes. */ ++.Lcpy_lt64: ++ lgr %r7,%r4 ++ slgfi %r7,16 /* border_len = n - 16. */ ++ ++ /* If current_len >= border then process remaining bytes. */ ++ clgrjhe %r5,%r7,.Lcpy_remaining_v16 ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lcpy_found_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lcpy_remaining_v18 ++ vfenezbs %v17,%v18,%v18 ++ je .Lcpy_found_v18 ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lcpy_remaining_v16 ++ vfenezbs %v17,%v16,%v16 ++ je .Lcpy_found_v16 ++ vl %v18,16(%r5,%r3) ++ vst %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lcpy_remaining_v18: ++ vlr %v16,%v18 ++.Lcpy_remaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Store remaining bytes and append string-termination. */ ++ vfenezb %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ la %r2,0(%r5,%r2) /* vstl has no index register. */ ++ /* Zero-index within remaining-bytes, store up to zero and end. */ ++ clgrjle %r1,%r7,.Lcpy_found_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ ++ lghi %r1,0 ++ stc %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */ ++.Lcpy_end: ++ /* Restore saved registers. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lcpy_found_v16_32: ++ aghi %r5,32 ++ j .Lcpy_found_v16 ++.Lcpy_found_v18_48: ++ aghi %r5,32 ++.Lcpy_found_v18_16: ++ aghi %r5,16 ++.Lcpy_found_v18: ++ vlr %v16,%v18 ++.Lcpy_found_v16: ++ /* v16 contains a zero. Store remaining bytes to zero. current_len ++ has not reached border, thus checking for n is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ la %r2,0(%r5,%r2) ++.Lcpy_found_v16_store: ++ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ ++ j .Lcpy_end ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lcpy_loop64: ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ vfenezbs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lcpy_found_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Store previous part without zero to dst. */ ++ vfenezbs %v17,%v18,%v18 ++ je .Lcpy_found_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezbs %v17,%v16,%v16 ++ je .Lcpy_found_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezbs %v17,%v18,%v18 ++ je .Lcpy_found_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lcpy_loop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ j .Lcpy_lt64 ++END(__strncat_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strncat.c b/sysdeps/s390/multiarch/strncat.c +new file mode 100644 +index 0000000..82e87ad +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncat.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of strncat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strncat, strncat) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcsncat-c.c b/sysdeps/s390/multiarch/wcsncat-c.c +new file mode 100644 +index 0000000..4938ef2 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncat-c.c +@@ -0,0 +1,25 @@ ++/* Default wcsncat implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSNCAT __wcsncat_c ++ ++# include ++extern __typeof (wcsncat) __wcsncat_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncat-vx.S b/sysdeps/s390/multiarch/wcsncat-vx.S +new file mode 100644 +index 0000000..7e0653e +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncat-vx.S +@@ -0,0 +1,265 @@ ++/* Vector optimized 32/64 bit S/390 version of wcsncat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t * wcsncat (wchar_t *dest, const wchar_t *src, size_t n) ++ Concatenate two strings - at most n characters of src. ++ ++ Register usage: ++ -r0=saved dest pointer for return ++ -r1=tmp ++ -r2=dest ++ -r3=src ++ -r4=n ++ -r5=current_len ++ -r6=tmp ++ -r7=tmp ++ -v16=part of src ++ -v17=index of zero ++ -v18=part of src ++ -v31=register save area for r6, r7 ++*/ ++ENTRY(__wcsncat_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgfi %r4,0 ++ ber %r14 /* Nothing to do, if n == 0. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ /* If either src or dest is not 4byte aligned, use __wcsncat_c. */ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ tmll %r3,3 /* Test if src is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ lgr %r0,%r2 /* Save destination pointer for return. */ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ ++ /* WCSLEN ++ %r1 = loaded bytes (tmp) ++ %r6 = zero byte index (tmp) ++ %r2 = dst ++ */ ++ vfenezf %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r5,%v16,7 /* Load zero index or 16 if not found. */ ++ clrjl %r5,%r1,.Llen_end /* Found zero within loaded bytes, end. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find zero in 16byte aligned loop. */ ++.Llen_loop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfenezfs %v16,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Llen_found /* Jump away if zero was found. */ ++ vl %v16,16(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Llen_found16 ++ vl %v16,32(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Llen_found32 ++ vl %v16,48(%r5,%r2) ++ vfenezfs %v16,%v16,%v16 ++ je .Llen_found48 ++ ++ aghi %r5,64 ++ j .Llen_loop /* No zero -> loop. */ ++ ++.Llen_found48: ++ aghi %r5,16 ++.Llen_found32: ++ aghi %r5,16 ++.Llen_found16: ++ aghi %r5,16 ++.Llen_found: ++ vlgvb %r1,%v16,7 /* Load byte index of zero. */ ++ algr %r5,%r1 ++ ++.Llen_end: ++ /* WCSNCPY ++ %r1 = zero byte index (tmp) ++ %r6 = loaded bytes (tmp) ++ %r3 = curr src pointer ++ %r2 = curr dst pointer ++ %r7 = border, tmp ++ */ ++ la %r2,0(%r5,%r2) /* strcpy at end of dst-string. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r6,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r6,%r6 /* Convert 32bit to 64bit. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r1,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ clgrjle %r4,%r6,.Lcpy_remaining_v16 /* If n <= loaded-bytes ++ -> process remaining. */ ++ ++ /* n > loaded-byte-count. */ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ clrjl %r1,%r6,.Lcpy_found_v16_store /* Found zero within loaded bytes, ++ copy and return. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,15 /* current_len = 15. */ ++ slr %r5,%r1 /* Compute highest index to 16byte boundary. * ++ ++ /* Zero not found and maxlen > loaded-byte-count. */ ++ vstl %v16,%r5,0(%r2) /* Copy loaded characters - no zero. */ ++ ahi %r5,1 /* Start loop at next character. */ ++ ++ /* ++ Now we are 16byte aligned, so we can load a full vreg ++ without page fault. ++ */ ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lcpy_loop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ clgijl %r4,17,.Lcpy_remaining_v16 /* If n <=16, ++ process remaining bytes. */ ++.Lcpy_lt64: ++ lgr %r7,%r4 ++ slgfi %r7,16 /* border_len = n - 16. */ ++ ++ clgrjhe %r5,%r7,.Lcpy_remaining_v16 ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lcpy_found_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lcpy_remaining_v18 ++ vfenezfs %v17,%v18,%v18 ++ je .Lcpy_found_v18 ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++ clgrjhe %r5,%r7,.Lcpy_remaining_v16 ++ vfenezfs %v17,%v16,%v16 ++ je .Lcpy_found_v16 ++ vl %v18,16(%r5,%r3) ++ vst %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lcpy_remaining_v18: ++ vlr %v16,%v18 ++.Lcpy_remaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Store remaining bytes and append string-termination. */ ++ vfenezf %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ slgrk %r7,%r4,%r5 /* Remaining bytes = maxlen - current_len. */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ vlgvb %r1,%v17,7 /* Load zero index or 16 if not found. */ ++ la %r2,0(%r5,%r2) /* vstl has no index register. */ ++ /* Zero-index within remaining-bytes, store up to zero and end. */ ++ clgrjle %r1,%r7,.Lcpy_found_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ ++ lghi %r1,0 ++ st %r1,1(%r7,%r2) /* Store string-null-termination beyond n. */ ++.Lcpy_end: ++ /* Restore saved registers. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lgr %r2,%r0 /* Load saved dest-ptr. */ ++ br %r14 ++ ++.Lcpy_found_v16_32: ++ aghi %r5,32 ++ j .Lcpy_found_v16 ++.Lcpy_found_v18_48: ++ aghi %r5,32 ++.Lcpy_found_v18_16: ++ aghi %r5,16 ++.Lcpy_found_v18: ++ vlr %v16,%v18 ++.Lcpy_found_v16: ++ /* v16 contains a zero. Store remaining bytes to zero. current_len ++ has not reached border, thus checking for n is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of zero. */ ++ la %r2,0(%r5,%r2) ++.Lcpy_found_v16_store: ++ aghi %r1,3 /* Also copy remaining bytes of zero. */ ++ vstl %v16,%r1,0(%r2) /* Copy characters including zero. */ ++ j .Lcpy_end ++ ++ /* Find zero in 16byte aligned loop. */ ++.Lcpy_loop2: ++ vl %v16,16(%r5,%r3) ++ vst %v18,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Lcpy_loop64: ++ vl %v16,0(%r5,%r3) ++ vfenezfs %v17,%v16,%v16 /* Find element not equal with zero search. */ ++ je .Lcpy_found_v16 /* Jump away if zero was found. */ ++ vl %v18,16(%r5,%r3) /* Load next part of s. */ ++ vst %v16,0(%r5,%r2) /* Save previous part without zero to dst. */ ++ vfenezfs %v17,%v18,%v18 ++ je .Lcpy_found_v18_16 ++ vl %v16,32(%r5,%r3) ++ vst %v18,16(%r5,%r2) ++ vfenezfs %v17,%v16,%v16 ++ je .Lcpy_found_v16_32 ++ vl %v18,48(%r5,%r3) ++ vst %v16,32(%r5,%r2) ++ vfenezfs %v17,%v18,%v18 ++ je .Lcpy_found_v18_48 ++ vst %v18,48(%r5,%r2) ++ ++ aghi %r5,64 ++ lgr %r1,%r5 /* If %r5 + 64 < maxlen? -> loop64. */ ++ aghi %r1,64 ++ clgrjl %r1,%r4,.Lcpy_loop64 ++ ++ vl %v16,0(%r5,%r3) /* Load s. */ ++ j .Lcpy_lt64 ++ ++.Lfallback: ++ jg __wcsncat_c ++END(__wcsncat_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsncat.c b/sysdeps/s390/multiarch/wcsncat.c +new file mode 100644 +index 0000000..621444d +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncat.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcsncat. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcsncat, wcsncat) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 9bfc78c..44b1502 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy wcpncpy wcscat ++ wcpcpy wcsncpy wcpncpy wcscat wcsncat + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcsncat-ifunc.c b/wcsmbs/test-wcsncat-ifunc.c +new file mode 100644 +index 0000000..5497f7d +--- /dev/null ++++ b/wcsmbs/test-wcsncat-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcsncat function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcsncat.c" +diff --git a/wcsmbs/test-wcsncat.c b/wcsmbs/test-wcsncat.c +new file mode 100644 +index 0000000..8b91a18 +--- /dev/null ++++ b/wcsmbs/test-wcsncat.c +@@ -0,0 +1,20 @@ ++/* Test wcsncat functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strncat.c" +diff --git a/wcsmbs/wcsncat.c b/wcsmbs/wcsncat.c +index 2131466..21a3a1e 100644 +--- a/wcsmbs/wcsncat.c ++++ b/wcsmbs/wcsncat.c +@@ -18,10 +18,13 @@ + + #include + ++#ifndef WCSNCAT ++# define WCSNCAT wcsncat ++#endif + + /* Append no more than N wide-character of SRC onto DEST. */ + wchar_t * +-wcsncat (dest, src, n) ++WCSNCAT (dest, src, n) + wchar_t *dest; + const wchar_t *src; + size_t n; +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-18.patch b/SOURCES/glibc-rh1268008-18.patch new file mode 100644 index 00000000..60cae143 --- /dev/null +++ b/SOURCES/glibc-rh1268008-18.patch @@ -0,0 +1,585 @@ +From 111012ea9031349ebbd7cc992b71662bdd10397c Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:18:25 +0200 +Subject: [PATCH 18/30] S390: Optimize strcmp and wcscmp. + +upstream-commit-id: 63724a6db60f98e91da474d11d83a19aa10fc54e +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00084.html + +This patch provides optimized versions of strcmp and wcscmp with the z13 +vector instructions. + +The architecture specific string.h had a typo, which leads to ommiting the +inline version in this file if __USE_STRING_INLINES is defined. +Tested this inline version by tweaking test-strcmp.c. + +ChangeLog: + + * sysdeps/s390/multiarch/strcmp-vx.S: New File. + * sysdeps/s390/multiarch/strcmp.c: Likewise. + * sysdeps/s390/multiarch/wcscmp-c.c: Likewise. + * sysdeps/s390/multiarch/wcscmp-vx.S: Likewise. + * sysdeps/s390/multiarch/wcscmp.c: Likewise. + * sysdeps/s390/s390-32/multiarch/strcmp.c: Likewise. + * sysdeps/s390/s390-64/multiarch/strcmp.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strcmp and + wcscmp functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strcmp, wcscmp. + * string/strcmp.c (STRCMP): Define and use macro. + * benchtests/bench-wcscmp.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcscmp. + * sysdeps/s390/bits/string.h: Fix typo: _HAVE_STRING_ARCH_strcmp + instead of _HAVE_STRING_ARCH_memchr. +--- + benchtests/Makefile | 3 +- + benchtests/bench-wcscmp.c | 20 +++++ + string/strcmp.c | 6 +- + sysdeps/s390/bits/string.h | 4 +- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strcmp-vx.S | 116 +++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strcmp.c | 26 ++++++ + sysdeps/s390/multiarch/wcscmp-c.c | 30 +++++++ + sysdeps/s390/multiarch/wcscmp-vx.S | 131 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcscmp.c | 27 +++++++ + sysdeps/s390/s390-32/multiarch/strcmp.c | 21 +++++ + sysdeps/s390/s390-64/multiarch/strcmp.c | 21 +++++ + 13 files changed, 408 insertions(+), 6 deletions(-) + create mode 100644 benchtests/bench-wcscmp.c + create mode 100644 sysdeps/s390/multiarch/strcmp-vx.S + create mode 100644 sysdeps/s390/multiarch/strcmp.c + create mode 100644 sysdeps/s390/multiarch/wcscmp-c.c + create mode 100644 sysdeps/s390/multiarch/wcscmp-vx.S + create mode 100644 sysdeps/s390/multiarch/wcscmp.c + create mode 100644 sysdeps/s390/s390-32/multiarch/strcmp.c + create mode 100644 sysdeps/s390/s390-64/multiarch/strcmp.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index fd8b7ee..f6333eb 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -38,7 +38,8 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strcat strchr strchrnul strcmp strcpy strcspn strlen \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok +-wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat ++wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ ++ wcsncmp + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-wcscmp.c b/benchtests/bench-wcscmp.c +new file mode 100644 +index 0000000..bd483a2 +--- /dev/null ++++ b/benchtests/bench-wcscmp.c +@@ -0,0 +1,20 @@ ++/* Measure wcscmp functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strcmp.c" +diff --git a/string/strcmp.c b/string/strcmp.c +index 8229d7c..5384db9 100644 +--- a/string/strcmp.c ++++ b/string/strcmp.c +@@ -20,11 +20,15 @@ + + #undef strcmp + ++#ifndef STRCMP ++# define STRCMP strcmp ++#endif ++ + /* Compare S1 and S2, returning less than, equal to or + greater than zero if S1 is lexicographically less than, + equal to or greater than S2. */ + int +-strcmp (p1, p2) ++STRCMP (p1, p2) + const char *p1; + const char *p2; + { +diff --git a/sysdeps/s390/bits/string.h b/sysdeps/s390/bits/string.h +index f3070f1..037aa71 100644 +--- a/sysdeps/s390/bits/string.h ++++ b/sysdeps/s390/bits/string.h +@@ -226,8 +226,8 @@ memchr (const void *__str, int __c, size_t __n) + } + #endif + +-/* Search N bytes of S for C. */ +-#define _HAVE_STRING_ARCH_memchr 1 ++/* Compare S1 and S2. */ ++#define _HAVE_STRING_ARCH_strchr 1 + #ifndef _FORCE_INLINES + __STRING_INLINE int + strcmp (const char *__s1, const char *__s2) +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 33c1398..d8fbd55 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -6,7 +6,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strncpy strncpy-vx \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ +- strncat strncat-vx strncat-c ++ strncat strncat-vx strncat-c \ ++ strcmp strcmp-vx + endif + + ifeq ($(subdir),wcsmbs) +@@ -17,5 +18,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncpy wcsncpy-vx wcsncpy-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ +- wcsncat wcsncat-vx wcsncat-c ++ wcsncat wcsncat-vx wcsncat-c \ ++ wcscmp wcscmp-vx wcscmp-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 1e57c0e..196d3ec 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -103,6 +103,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strncat); + IFUNC_VX_IMPL (wcsncat); + ++ IFUNC_VX_IMPL (strcmp); ++ IFUNC_VX_IMPL (wcscmp); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strcmp-vx.S b/sysdeps/s390/multiarch/strcmp-vx.S +new file mode 100644 +index 0000000..57fce75 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcmp-vx.S +@@ -0,0 +1,116 @@ ++/* Vector optimized 32/64 bit S/390 version of strcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* int strcmp (const char *s1, const char *s2) ++ Compare two strings ++ ++ Register usage: ++ -r1=loaded byte count s1 ++ -r2=s1 ++ -r3=s2 ++ -r4=loaded byte coutn s2, tmp ++ -r5=current_len ++ -v16=part of s1 ++ -v17=part of s2 ++ -v18=index of unequal ++*/ ++ENTRY(__strcmp_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++.Lloop: ++ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ ++ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ ++ lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */ ++ jo .Llt16_1 /* Jump away if vr is not fully loaded. */ ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 /* Jump away if vr is not fully loaded. */ ++ /* Both vrs are fully loaded. */ ++ aghi %r5,16 ++ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r1,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezbs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r1,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezbs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r1,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezbs %v18,%v16,%v17 ++ jno .Lfound ++ j .Lloop ++ ++.Llt16_1: ++ lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */ ++.Llt16_2: ++ clr %r1,%r4 ++ locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */ ++ algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */ ++ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ ++ clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded ++ bytes. */ ++ j .Lloop ++ ++.Lfound: ++ je .Lend_equal ++ lghi %r2,1 ++ lghi %r1,-1 ++ locgrl %r2,%r1 ++ br %r14 ++.Lend_equal: ++ lghi %r2,0 ++ br %r14 ++END(__strcmp_vx) ++ ++# define strcmp __strcmp_c ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++ ++#include +diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c +new file mode 100644 +index 0000000..dd462a2 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcmp.c +@@ -0,0 +1,26 @@ ++/* Multiple versions of strcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++ ++# undef strcmp ++s390_vx_libc_ifunc2 (__strcmp, strcmp) ++#endif +diff --git a/sysdeps/s390/multiarch/wcscmp-c.c b/sysdeps/s390/multiarch/wcscmp-c.c +new file mode 100644 +index 0000000..8358e1f +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscmp-c.c +@@ -0,0 +1,30 @@ ++/* Default wcscmp implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSCMP __wcscmp_c ++ ++# include ++extern __typeof (wcscmp) __wcscmp_c; ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcscmp_c, __GI_wcscmp, __wcscmp_c); ++# endif /* SHARED */ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcscmp-vx.S b/sysdeps/s390/multiarch/wcscmp-vx.S +new file mode 100644 +index 0000000..2c9e610 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscmp-vx.S +@@ -0,0 +1,131 @@ ++/* Vector optimized 32/64 bit S/390 version of wcscmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* int wcscmp (const wchar_t *s1, const wchar_t *s2) ++ Compare two strings ++ ++ Register usage: ++ -r1=loaded byte count s1 ++ -r2=s1 ++ -r3=s2 ++ -r4=loaded byte coutn s2, tmp ++ -r5=current_len ++ -v16=part of s1 ++ -v17=part of s2 ++ -v18=index of unequal ++*/ ++ENTRY(__wcscmp_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++.Lloop: ++ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ ++ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ ++ lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */ ++ jo .Llt16_1 /* Jump away if vr is not fully loaded. */ ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 /* Jump away if vr is not fully loaded. */ ++ /* Both vrs are fully loaded. */ ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r1,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r1,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r1,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r4,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 ++ jno .Lfound ++ j .Lloop ++ ++.Lcmp_one_char: ++ /* At least one of both strings is not 4-byte aligned ++ and there is no full character before next block-boundary. ++ Compare one character to get over the boundary and ++ proceed with normal loop! */ ++ vlef %v16,0(%r5,%r2),0 /* Load one character. */ ++ vlef %v17,0(%r5,%r3),0 ++ lghi %r1,4 /* Loaded byte count is 4. */ ++ j .Llt_cmp /* Proceed with comparision. */ ++ ++.Llt16_1: ++ lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */ ++.Llt16_2: ++ clr %r1,%r4 ++ locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */ ++ nill %r1,65532 /* Align bytes loaded to full characters. */ ++ jz .Lcmp_one_char /* Jump away if no full char is available. */ ++.Llt_cmp: ++ algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */ ++ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ ++ clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded ++ bytes. */ ++ j .Lloop ++ ++.Lfound: ++ /* vfenezf found an unequal element or zero. ++ This instruction compares unsigned words, but wchar_t is signed. ++ Thus we have to compare the found element again. */ ++ vlgvb %r4,%v18,7 /* Extract not equal byte-index, */ ++ srl %r4,2 /* Convert it to character-index. */ ++ vlgvf %r3,%v16,0(%r4) /* Load character-values. */ ++ vlgvf %r4,%v17,0(%r4) ++ cr %r3,%r4 ++ je .Lend_equal ++ lghi %r2,1 ++ lghi %r1,-1 ++ locgrl %r2,%r1 ++ br %r14 ++.Lend_equal: ++ lghi %r2,0 ++ br %r14 ++END(__wcscmp_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c +new file mode 100644 +index 0000000..99bae4f +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscmp.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcscmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcscmp, wcscmp) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/s390-32/multiarch/strcmp.c b/sysdeps/s390/s390-32/multiarch/strcmp.c +new file mode 100644 +index 0000000..1598bbc +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/strcmp.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of strcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ ++#include +diff --git a/sysdeps/s390/s390-64/multiarch/strcmp.c b/sysdeps/s390/s390-64/multiarch/strcmp.c +new file mode 100644 +index 0000000..1598bbc +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/strcmp.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of strcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ ++#include +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-19.patch b/SOURCES/glibc-rh1268008-19.patch new file mode 100644 index 00000000..bcf6c7fd --- /dev/null +++ b/SOURCES/glibc-rh1268008-19.patch @@ -0,0 +1,1313 @@ +From 1026f1e15a84134fd19f58c98af85ec9474f7722 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:21:50 +0200 +Subject: [PATCH 19/30] S390: Optimize strncmp and wcsncmp. (AND COMMON-CODE + WCSNCMP - picked form upstream) + +upstream-commit-id: cee82e70ccb7b2f054cd781b0a603ae244523e72 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00087.html + +common-code wcsncmp: +upstream-commit-id: 920a0395ba9fa5949ec87aaf5daa0259da16749d +https://www.sourceware.org/ml/libc-alpha/2015-04/msg00098.html + +This patch provides optimized versions of strncmp and wcsncmp with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strncmp-c.c: New File. + * sysdeps/s390/multiarch/strncmp-vx.S: Likewise. + * sysdeps/s390/multiarch/strncmp.c: Likewise. + * sysdeps/s390/multiarch/wcsncmp-c.c: Likewise. + * sysdeps/s390/multiarch/wcsncmp-vx.S: Likewise. + * sysdeps/s390/multiarch/wcsncmp.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strncmp and + wcsncmp functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strncmp, wcsncmp. + * wcsmbs/wcsncmp.c (WCSNCMP): Define and use macro. + * benchtests/bench-strncmp.c: Add wcsncmp support. + * benchtests/bench-wcsncmp.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcsncmp. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strncmp.c | 104 +++++++++++++----- + benchtests/bench-wcsncmp.c | 20 ++++ + localedata/tests-mbwc/dat_wcsncmp.c | 18 ++-- + localedata/tests-mbwc/tst_wcsncmp.c | 2 + + string/strncmp.c | 2 +- + string/test-strncmp.c | 175 +++++++++++++++++++++--------- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strncmp-c.c | 28 +++++ + sysdeps/s390/multiarch/strncmp-vx.S | 137 ++++++++++++++++++++++++ + sysdeps/s390/multiarch/strncmp.c | 30 ++++++ + sysdeps/s390/multiarch/wcsncmp-c.c | 25 +++++ + sysdeps/s390/multiarch/wcsncmp-vx.S | 177 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcsncmp.c | 27 +++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcsncmp-ifunc.c | 20 ++++ + wcsmbs/test-wcsncmp.c | 2 + + wcsmbs/wcsncmp.c | 41 +++---- + 19 files changed, 716 insertions(+), 105 deletions(-) + create mode 100644 benchtests/bench-wcsncmp.c + create mode 100644 sysdeps/s390/multiarch/strncmp-c.c + create mode 100644 sysdeps/s390/multiarch/strncmp-vx.S + create mode 100644 sysdeps/s390/multiarch/strncmp.c + create mode 100644 sysdeps/s390/multiarch/wcsncmp-c.c + create mode 100644 sysdeps/s390/multiarch/wcsncmp-vx.S + create mode 100644 sysdeps/s390/multiarch/wcsncmp.c + create mode 100644 wcsmbs/test-wcsncmp-ifunc.c + create mode 100644 wcsmbs/test-wcsncmp.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index f6333eb..f6342da 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp ++ wcsncmp wcsncmp + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strncmp.c b/benchtests/bench-strncmp.c +index 25df3db..496ed68 100644 +--- a/benchtests/bench-strncmp.c ++++ b/benchtests/bench-strncmp.c +@@ -17,17 +17,66 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strncmp" ++#ifdef WIDE ++# define TEST_NAME "wcsncmp" ++#else ++# define TEST_NAME "strncmp" ++#endif /* !WIDE */ + #include "bench-string.h" + +-typedef int (*proto_t) (const char *, const char *, size_t); +-int simple_strncmp (const char *, const char *, size_t); +-int stupid_strncmp (const char *, const char *, size_t); ++#ifdef WIDE ++# include ++ ++# define L(str) L##str ++# define STRNCMP wcsncmp ++# define SIMPLE_STRNCMP simple_wcsncmp ++# define STUPID_STRNCMP stupid_wcsncmp ++# define CHAR wchar_t ++# define CHARBYTES 4 ++/* Wcsncmp uses signed semantics for comparison, not unsigned. ++ Avoid using substraction since possible overflow. */ ++int ++simple_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ while (n--) ++ { ++ c1 = *s1++; ++ c2 = *s2++; ++ if (c1 == L ('\0') || c1 != c2) ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); ++ } ++ return 0; ++} + +-IMPL (stupid_strncmp, 0) +-IMPL (simple_strncmp, 0) +-IMPL (strncmp, 1) ++int ++stupid_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ size_t ns1 = wcsnlen (s1, n) + 1, ns2 = wcsnlen (s2, n) + 1; ++ ++ n = ns1 < n ? ns1 : n; ++ n = ns2 < n ? ns2 : n; + ++ while (n--) ++ { ++ c1 = *s1++; ++ c2 = *s2++; ++ if (c1 != c2) ++ return c1 > c2 ? 1 : -1; ++ } ++ return 0; ++} ++ ++#else ++# define L(str) str ++# define STRNCMP strncmp ++# define SIMPLE_STRNCMP simple_strncmp ++# define STUPID_STRNCMP stupid_strncmp ++# define CHAR char ++# define CHARBYTES 1 ++ ++/* Strncmp uses unsigned semantics for comparison. */ + int + simple_strncmp (const char *s1, const char *s2, size_t n) + { +@@ -49,9 +98,16 @@ stupid_strncmp (const char *s1, const char *s2, size_t n) + while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0); + return ret; + } ++#endif /* !WIDE */ ++ ++typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); ++ ++IMPL (STUPID_STRNCMP, 0) ++IMPL (SIMPLE_STRNCMP, 0) ++IMPL (STRNCMP, 1) + + static void +-do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, ++do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n, + int exp_result) + { + size_t i, iters = INNER_LOOP_ITERS; +@@ -74,12 +130,12 @@ do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, + int exp_result) + { + size_t i, align_n; +- char *s1, *s2; ++ CHAR *s1, *s2; + + if (n == 0) + { +- s1 = (char*)(buf1 + page_size); +- s2 = (char*)(buf2 + page_size); ++ s1 = (CHAR*)(buf1 + page_size); ++ s2 = (CHAR*)(buf2 + page_size); + printf ("Length %4zd/%4zd:", len, n); + + FOR_EACH_IMPL (impl, 0) +@@ -92,16 +148,16 @@ do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, + + align1 &= 15; + align2 &= 15; +- align_n = (page_size - n) & 15; ++ align_n = (page_size - n * CHARBYTES) & 15; + +- s1 = (char*)(buf1 + page_size - n); +- s2 = (char*)(buf2 + page_size - n); ++ s1 = (CHAR*)(buf1 + page_size - n * CHARBYTES); ++ s2 = (CHAR*)(buf2 + page_size - n * CHARBYTES); + + if (align1 < align_n) +- s1 -= (align_n - align1); ++ s1 = (CHAR *) ((char *) s1 - (align_n - align1)); + + if (align2 < align_n) +- s2 -= (align_n - align2); ++ s2 = (CHAR *) ((char *) s2 - (align_n - align2)); + + for (i = 0; i < n; i++) + s1[i] = s2[i] = 1 + 23 * i % max_char; +@@ -129,24 +185,24 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, + int exp_result) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + if (n == 0) + return; + +- align1 &= 7; +- if (align1 + n + 1 >= page_size) ++ align1 &= 63; ++ if (align1 + (n + 1) * CHARBYTES >= page_size) + return; + + align2 &= 7; +- if (align2 + n + 1 >= page_size) ++ if (align2 + (n + 1) * CHARBYTES >= page_size) + return; + +- s1 = (char*)(buf1 + align1); +- s2 = (char*)(buf2 + align2); ++ s1 = (CHAR*)(buf1 + align1); ++ s2 = (CHAR*)(buf2 + align2); + + for (i = 0; i < n; i++) +- s1[i] = s2[i] = 1 + 23 * i % max_char; ++ s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char; + + s1[n] = 24 + exp_result; + s2[n] = 23; +@@ -162,7 +218,7 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, + printf ("Length %4zd/%4zd, alignment %2zd/%2zd:", len, n, align1, align2); + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); ++ do_one_test (impl, s1, s2, n, exp_result); + + putchar ('\n'); + } +diff --git a/benchtests/bench-wcsncmp.c b/benchtests/bench-wcsncmp.c +new file mode 100644 +index 0000000..8720060 +--- /dev/null ++++ b/benchtests/bench-wcsncmp.c +@@ -0,0 +1,20 @@ ++/* Measure wcsncmp functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strncmp.c" +diff --git a/localedata/tests-mbwc/dat_wcsncmp.c b/localedata/tests-mbwc/dat_wcsncmp.c +index 167ce48..f468a8b 100644 +--- a/localedata/tests-mbwc/dat_wcsncmp.c ++++ b/localedata/tests-mbwc/dat_wcsncmp.c +@@ -33,7 +33,7 @@ TST_WCSNCMP tst_wcsncmp_loc [] = { + }, + { /*input.*/ { { 0x00D1,0x00D2,0x00D3,0x0000 }, + { 0x0000,0x00D2,0x00D3,0x0000 }, 3 }, /* #06 */ +- /*expect*/ { 0,1,0x00D1, }, ++ /*expect*/ { 0,1,1, }, + }, + { /*input.*/ { { 0x00D1,0x00D2,0x00D3,0x0000 }, + { 0x00D1,0x00D2,0x00D9,0x0000 }, 2 }, /* #07 */ +@@ -41,11 +41,11 @@ TST_WCSNCMP tst_wcsncmp_loc [] = { + }, + { /*input.*/ { { 0x00D1,0x00D2,0x00D3,0x0000 }, + { 0x00D1,0x00D2,0x00D9,0x0000 }, 3 }, /* #08 */ +- /*expect*/ { 0,1,-0x0006, }, ++ /*expect*/ { 0,1,-1, }, + }, + { /*input.*/ { { 0x00D1,0x00D2,0x00D3,0x0000 }, + { 0x00D1,0x00D2,0x0000 }, 4 }, /* #09 */ +- /*expect*/ { 0,1,0x00D3, }, ++ /*expect*/ { 0,1,1, }, + }, + { .is_last = 1 } + } +@@ -75,7 +75,7 @@ TST_WCSNCMP tst_wcsncmp_loc [] = { + }, + { /*input.*/ { { 0x0041,0x0042,0x0043,0x0000 }, + { 0x0000,0x0042,0x0043,0x0000 }, 3 }, /* #06 */ +- /*expect*/ { 0,1,0x0041, }, ++ /*expect*/ { 0,1,1, }, + }, + { /*input.*/ { { 0x0041,0x0042,0x0043,0x0000 }, + { 0x0041,0x0042,0x0049,0x0000 }, 2 }, /* #07 */ +@@ -83,11 +83,11 @@ TST_WCSNCMP tst_wcsncmp_loc [] = { + }, + { /*input.*/ { { 0x0041,0x0042,0x0043,0x0000 }, + { 0x0041,0x0042,0x0049,0x0000 }, 3 }, /* #08 */ +- /*expect*/ { 0,1,-0x0006, }, ++ /*expect*/ { 0,1,-1, }, + }, + { /*input.*/ { { 0x0041,0x0042,0x0043,0x0000 }, + { 0x0041,0x0042,0x0000 }, 4 }, /* #09 */ +- /*expect*/ { 0,1,0x0043, }, ++ /*expect*/ { 0,1,1, }, + }, + { .is_last = 1 } + } +@@ -117,7 +117,7 @@ TST_WCSNCMP tst_wcsncmp_loc [] = { + }, + { /*input.*/ { { 0x3041,0x3042,0x3043,0x0000 }, + { 0x0000,0x3042,0x3043,0x0000 }, 3 }, /* #06 */ +- /*expect*/ { 0,1,0x3041, }, ++ /*expect*/ { 0,1,1, }, + }, + { /*input.*/ { { 0x3041,0x3042,0x3043,0x0000 }, + { 0x3041,0x3042,0x3049,0x0000 }, 2 }, /* #07 */ +@@ -125,11 +125,11 @@ TST_WCSNCMP tst_wcsncmp_loc [] = { + }, + { /*input.*/ { { 0x3041,0x3042,0x3043,0x0000 }, + { 0x3041,0x3042,0x3049,0x0000 }, 3 }, /* #08 */ +- /*expect*/ { 0,1,-0x0006, }, ++ /*expect*/ { 0,1,-1, }, + }, + { /*input.*/ { { 0x3041,0x3042,0x3043,0x0000 }, + { 0x3041,0x3042,0x0000 }, 4 }, /* #09 */ +- /*expect*/ { 0,1,0x3043, }, ++ /*expect*/ { 0,1,1, }, + }, + { .is_last = 1 } + } +diff --git a/localedata/tests-mbwc/tst_wcsncmp.c b/localedata/tests-mbwc/tst_wcsncmp.c +index d046ecd..e378efb 100644 +--- a/localedata/tests-mbwc/tst_wcsncmp.c ++++ b/localedata/tests-mbwc/tst_wcsncmp.c +@@ -24,6 +24,8 @@ tst_wcsncmp (FILE * fp, int debug_flg) + ws2 = TST_INPUT (wcsncmp).ws2; + n = TST_INPUT (wcsncmp).n; + ret = wcsncmp (ws1, ws2, n); ++ ret = (ret > 0 ? 1 : ret < 0 ? -1 : 0); ++ + + if (debug_flg) + { +diff --git a/string/strncmp.c b/string/strncmp.c +index d79305a..bd52138 100644 +--- a/string/strncmp.c ++++ b/string/strncmp.c +@@ -21,7 +21,7 @@ + #undef strncmp + + #ifndef STRNCMP +-#define STRNCMP strncmp ++# define STRNCMP strncmp + #endif + + /* Compare no more than N characters of S1 and S2, +diff --git a/string/test-strncmp.c b/string/test-strncmp.c +index 7169593..950bf24 100644 +--- a/string/test-strncmp.c ++++ b/string/test-strncmp.c +@@ -1,5 +1,5 @@ + /* Test and measure strncmp functions. +- Copyright (C) 1999-2012 Free Software Foundation, Inc. ++ Copyright (C) 1999-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Jakub Jelinek , 1999. + +@@ -18,18 +18,82 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strncmp" ++#ifdef WIDE ++# define TEST_NAME "wcsncmp" ++#else ++# define TEST_NAME "strncmp" ++#endif + #include "test-string.h" + +-typedef int (*proto_t) (const char *, const char *, size_t); +-int simple_strncmp (const char *, const char *, size_t); +-int stupid_strncmp (const char *, const char *, size_t); ++#ifdef WIDE ++# include ++ ++# define L(str) L##str ++# define STRNCMP wcsncmp ++# define STRCPY wcscpy ++# define STRDUP wcsdup ++# define MEMCPY wmemcpy ++# define SIMPLE_STRNCMP simple_wcsncmp ++# define STUPID_STRNCMP stupid_wcsncmp ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define CHARBYTES 4 ++# define CHAR__MAX WCHAR_MAX ++# define CHAR__MIN WCHAR_MIN ++ ++/* Wcsncmp uses signed semantics for comparison, not unsigned. ++ Avoid using substraction since possible overflow */ ++int ++simple_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ ++ while (n--) ++ { ++ c1 = *s1++; ++ c2 = *s2++; ++ if (c1 == L('\0') || c1 != c2) ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); ++ } ++ return 0; ++} + +-IMPL (stupid_strncmp, 0) +-IMPL (simple_strncmp, 0) +-IMPL (strncmp, 1) + + int ++stupid_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n) ++{ ++ wchar_t c1, c2; ++ size_t ns1 = wcsnlen (s1, n) + 1, ns2 = wcsnlen (s2, n) + 1; ++ ++ n = ns1 < n ? ns1 : n; ++ n = ns2 < n ? ns2 : n; ++ ++ while (n--) ++ { ++ c1 = *s1++; ++ c2 = *s2++; ++ if (c1 != c2) ++ return c1 > c2 ? 1 : -1; ++ } ++ return 0; ++} ++ ++#else ++# define L(str) str ++# define STRNCMP strncmp ++# define STRCPY strcpy ++# define STRDUP strdup ++# define MEMCPY memcpy ++# define SIMPLE_STRNCMP simple_strncmp ++# define STUPID_STRNCMP stupid_strncmp ++# define CHAR char ++# define UCHAR unsigned char ++# define CHARBYTES 1 ++# define CHAR__MAX CHAR_MAX ++# define CHAR__MIN CHAR_MIN ++ ++/* Strncmp uses unsigned semantics for comparison. */ ++int + simple_strncmp (const char *s1, const char *s2, size_t n) + { + int ret = 0; +@@ -50,9 +114,16 @@ stupid_strncmp (const char *s1, const char *s2, size_t n) + while (n-- && (ret = *(unsigned char *) s1++ - * (unsigned char *) s2++) == 0); + return ret; + } ++#endif ++ ++typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); ++ ++IMPL (STUPID_STRNCMP, 0) ++IMPL (SIMPLE_STRNCMP, 0) ++IMPL (STRNCMP, 1) + + static int +-check_result (impl_t *impl, const char *s1, const char *s2, size_t n, ++check_result (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n, + int exp_result) + { + int result = CALL (impl, s1, s2, n); +@@ -70,7 +141,7 @@ check_result (impl_t *impl, const char *s1, const char *s2, size_t n, + } + + static void +-do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n, ++do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n, + int exp_result) + { + if (check_result (impl, s1, s2, n, exp_result) < 0) +@@ -82,12 +153,12 @@ do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, + int exp_result) + { + size_t i, align_n; +- char *s1, *s2; ++ CHAR *s1, *s2; + + if (n == 0) + { +- s1 = (char*)(buf1 + page_size); +- s2 = (char*)(buf2 + page_size); ++ s1 = (CHAR*) (buf1 + page_size); ++ s2 = (CHAR*) (buf2 + page_size); + + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, s1, s2, n, 0); +@@ -97,16 +168,16 @@ do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, + + align1 &= 15; + align2 &= 15; +- align_n = (page_size - n) & 15; ++ align_n = (page_size - n * CHARBYTES) & 15; + +- s1 = (char*)(buf1 + page_size - n); +- s2 = (char*)(buf2 + page_size - n); ++ s1 = (CHAR*) (buf1 + page_size - n * CHARBYTES); ++ s2 = (CHAR*) (buf2 + page_size - n * CHARBYTES); + + if (align1 < align_n) +- s1 -= (align_n - align1); ++ s1 = (CHAR *) ((char *) s1 - (align_n - align1)); + + if (align2 < align_n) +- s2 -= (align_n - align2); ++ s2 = (CHAR *) ((char *) s2 - (align_n - align2)); + + for (i = 0; i < n; i++) + s1[i] = s2[i] = 1 + 23 * i % max_char; +@@ -130,24 +201,24 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, + int exp_result) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + + if (n == 0) + return; + +- align1 &= 7; +- if (align1 + n + 1 >= page_size) ++ align1 &= 63; ++ if (align1 + (n + 1) * CHARBYTES >= page_size) + return; + + align2 &= 7; +- if (align2 + n + 1 >= page_size) ++ if (align2 + (n + 1) * CHARBYTES >= page_size) + return; + +- s1 = (char*)(buf1 + align1); +- s2 = (char*)(buf2 + align2); ++ s1 = (CHAR*) (buf1 + align1); ++ s2 = (CHAR*) (buf2 + align2); + + for (i = 0; i < n; i++) +- s1[i] = s2[i] = 1 + 23 * i % max_char; ++ s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char; + + s1[n] = 24 + exp_result; + s2[n] = 23; +@@ -161,19 +232,20 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, + s2[n - 1] -= exp_result; + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char*)s1, (char*)s2, n, exp_result); ++ do_one_test (impl, s1, s2, n, exp_result); + } + + static void +-do_page_test (size_t offset1, size_t offset2, char *s2) ++do_page_test (size_t offset1, size_t offset2, CHAR *s2) + { +- char *s1; ++ CHAR *s1; + int exp_result; + +- if (offset1 >= page_size || offset2 >= page_size) ++ if (offset1 * CHARBYTES >= page_size || offset2 * CHARBYTES >= page_size) + return; + +- s1 = (char *) (buf1 + offset1); ++ s1 = (CHAR *) buf1; ++ s1 += offset1; + s2 += offset2; + + exp_result= *s1; +@@ -191,8 +263,8 @@ do_random_tests (void) + size_t i, j, n, align1, align2, pos, len1, len2, size; + int result; + long r; +- unsigned char *p1 = buf1 + page_size - 512; +- unsigned char *p2 = buf2 + page_size - 512; ++ UCHAR *p1 = (UCHAR *) (buf1 + page_size - 512 * CHARBYTES); ++ UCHAR *p2 = (UCHAR *) (buf2 + page_size - 512 * CHARBYTES); + + for (n = 0; n < ITERATIONS; n++) + { +@@ -240,7 +312,7 @@ do_random_tests (void) + } + + result = 0; +- memcpy (p2 + align2, p1 + align1, pos); ++ MEMCPY (p2 + align2, p1 + align1, pos); + if (pos < len1) + { + if (p2[align2 + pos] == p1[align1 + pos]) +@@ -263,7 +335,7 @@ do_random_tests (void) + + FOR_EACH_IMPL (impl, 1) + { +- r = CALL (impl, (char*)(p1 + align1), (char*)(p2 + align2), size); ++ r = CALL (impl, (CHAR *)(p1 + align1), (CHAR *)(p2 + align2), size); + /* Test whether on 64-bit architectures where ABI requires + callee to promote has the promotion been done. */ + asm ("" : "=g" (r) : "0" (r)); +@@ -282,19 +354,26 @@ do_random_tests (void) + static void + check1 (void) + { +- char *s1 = (char *)(buf1 + 0xb2c); +- char *s2 = (char *)(buf1 + 0xfd8); +- size_t i; ++ CHAR *s1 = (CHAR *)(buf1 + 0xb2c); ++ CHAR *s2 = (CHAR *)(buf1 + 0xfd8); ++ size_t i, offset; + int exp_result; + +- strcpy(s1, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs"); +- strcpy(s2, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV"); ++ strcpy(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs")); ++ strcpy(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV")); ++ ++ /* Check possible overflow bug for wcsncmp */ ++ s1[4] = CHAR__MAX; ++ s2[4] = CHAR__MIN; + +- for (i = 0; i < 80; i++) ++ for (offset = 0; offset < 6; offset++) + { +- exp_result = simple_strncmp (s1, s2, i); +- FOR_EACH_IMPL (impl, 0) +- check_result (impl, s1, s2, i, exp_result); ++ for (i = 0; i < 80; i++) ++ { ++ exp_result = SIMPLE_STRNCMP (s1 + offset, s2 + offset, i); ++ FOR_EACH_IMPL (impl, 0) ++ check_result (impl, s1 + offset, s2 + offset, i, exp_result); ++ } + } + } + +@@ -302,17 +381,17 @@ static void + check2 (void) + { + size_t i; +- char *s1, *s2; ++ CHAR *s1, *s2; + +- s1 = (char *) buf1; +- for (i = 0; i < page_size - 1; i++) ++ s1 = (CHAR *) buf1; ++ for (i = 0; i < (page_size / CHARBYTES) - 1; i++) + s1[i] = 23; + s1[i] = 0; + +- s2 = strdup (s1); ++ s2 = STRDUP (s1); + + for (i = 0; i < 64; ++i) +- do_page_test (3990 + i, 2635, s2); ++ do_page_test ((3988 / CHARBYTES) + i, (2636 / CHARBYTES), s2); + + free (s2); + } +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index d8fbd55..d77bee5 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -7,7 +7,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + stpncpy stpncpy-vx stpncpy-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ +- strcmp strcmp-vx ++ strcmp strcmp-vx \ ++ strncmp strncmp-vx strncmp-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -19,5 +20,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcpncpy wcpncpy-vx wcpncpy-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ +- wcscmp wcscmp-vx wcscmp-c ++ wcscmp wcscmp-vx wcscmp-c \ ++ wcsncmp wcsncmp-vx wcsncmp-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 196d3ec..5bfc493 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -106,6 +106,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strcmp); + IFUNC_VX_IMPL (wcscmp); + ++ IFUNC_VX_IMPL (strncmp); ++ IFUNC_VX_IMPL (wcsncmp); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strncmp-c.c b/sysdeps/s390/multiarch/strncmp-c.c +new file mode 100644 +index 0000000..75da859 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncmp-c.c +@@ -0,0 +1,28 @@ ++/* Default strncmp implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRNCMP __strncmp_c ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strncmp_c, __GI_strncmp, __strncmp_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strncmp-vx.S b/sysdeps/s390/multiarch/strncmp-vx.S +new file mode 100644 +index 0000000..36e99b8 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncmp-vx.S +@@ -0,0 +1,137 @@ ++/* Vector optimized 32/64 bit S/390 version of strncmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* int strncmp (const char *s1, const char *s2, size_t n) ++ Compare at most n characters of two strings. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=s1 ++ -r3=s2 ++ -r4=n ++ -r5=current_len ++ -v16=part of s1 ++ -v17=part of s2 ++ -v18=index of unequal ++*/ ++ENTRY(__strncmp_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgije %r4,0,.Lend_equal /* Nothing to do if n == 0, */ ++ lghi %r5,0 /* current_len = 0. */ ++ ++.Lloop: ++ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ ++ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ ++ lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */ ++ jo .Llt16_1 /* Jump away if vr is not fully loaded. */ ++ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ ++ jo .Llt16_2 /* Jump away if vr is not fully loaded. */ ++ aghi %r5,16 /* Both vrs are fully loaded. */ ++ clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */ ++ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r0,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r1,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfenezbs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r0,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r1,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfenezbs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vlbb %v16,0(%r5,%r2),6 ++ vlbb %v17,0(%r5,%r3),6 ++ lcbb %r0,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r1,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfenezbs %v18,%v16,%v17 ++ jno .Lfound ++ j .Lloop ++ ++.Llt16_1: ++ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count ofs2. */ ++.Llt16_2: ++ clr %r0,%r1 /* Compare logical. */ ++ locrh %r0,%r1 /* Compute minimum of bytes loaded. */ ++ algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */ ++ clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n ->last compare. */ ++ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ ++ clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within ++ loaded bytes (index < loaded-bytes) */ ++ j .Lloop ++ ++.Llastcmp: ++ /* Use comparision result only if located within first n characters. ++ %r0: loaded byte count in vreg; ++ %r5: current_len; ++ %r4: n; ++ (current_len - n): [0...16[ ++ First ignored match index: loaded bytes - (current_len-n): ]0...16] ++ */ ++ slgr %r5,%r4 /* %r5 = current_len - n. */ ++ slr %r0,%r5 /* %r0 = first ignored match index. */ ++ vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ ++ clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within ++ loaded bytes and below n bytes. */ ++ j .Lend_equal /* Miscompare after n-bytes -> end equal. */ ++ ++.Lfound: ++ /* Difference or end of string. */ ++ je .Lend_equal ++ lghi %r2,1 ++ lghi %r1,-1 ++ locgrl %r2,%r1 ++ br %r14 ++.Lend_equal: ++ lghi %r2,0 ++ br %r14 ++END(__strncmp_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c +new file mode 100644 +index 0000000..1e1e05a +--- /dev/null ++++ b/sysdeps/s390/multiarch/strncmp.c +@@ -0,0 +1,30 @@ ++/* Multiple versions of strncmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++ ++# undef strcmp ++extern __typeof (strncmp) __strncmp; ++s390_vx_libc_ifunc2 (__strncmp, strncmp) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcsncmp-c.c b/sysdeps/s390/multiarch/wcsncmp-c.c +new file mode 100644 +index 0000000..058cd0c +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncmp-c.c +@@ -0,0 +1,25 @@ ++/* Default wcsncmp implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSNCMP __wcsncmp_c ++ ++# include ++extern __typeof (wcsncmp) __wcsncmp_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcsncmp-vx.S b/sysdeps/s390/multiarch/wcsncmp-vx.S +new file mode 100644 +index 0000000..9a44424 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncmp-vx.S +@@ -0,0 +1,177 @@ ++/* Vector optimized 32/64 bit S/390 version of wcsncmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* int wcsncmp (const wchar_t *s1, const wchar_t *s2, size_t n) ++ Compare at most n characters of two strings. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=s1 ++ -r3=s2 ++ -r4=n ++ -r5=current_len ++ -v16=part of s1 ++ -v17=part of s2 ++ -v18=index of unequal ++*/ ++ENTRY(__wcsncmp_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */ ++ ++ /* Check range of n and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r1,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ /* Check first character without vector load. */ ++ lghi %r5,4 /* current_len = 4 bytes. */ ++ /* Check s1/2[0]. */ ++ lt %r0,0(%r2) ++ l %r1,0(%r3) ++ je .Lend_cmp_one_char ++ crjne %r0,%r1,.Lend_cmp_one_char ++ ++.Lloop: ++ vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */ ++ vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */ ++ lcbb %r0,0(%r5,%r2),6 /* Get loaded byte count of s1. */ ++ jo .Llt16_1 /* Jump away if vector not fully loaded. */ ++ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ ++ jo .Llt16_2 /* Jump away if vector not fully loaded. */ ++ aghi %r5,16 /* Both vectors are fully loaded. */ ++ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ clgrjhe %r5,%r4,.Llastcmp /* If current_len >= n ->last compare. */ ++ jno .Lfound ++ ++ vlbb %v17,0(%r5,%r3),6 ++ vlbb %v16,0(%r5,%r2),6 ++ lcbb %r0,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r1,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 ++ clgrjhe %r5,%r4,.Llastcmp ++ jno .Lfound ++ ++ vlbb %v17,0(%r5,%r3),6 ++ vlbb %v16,0(%r5,%r2),6 ++ lcbb %r0,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r1,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 ++ clgrjhe %r5,%r4,.Llastcmp ++ jno .Lfound ++ ++ vlbb %v17,0(%r5,%r3),6 ++ vlbb %v16,0(%r5,%r2),6 ++ lcbb %r0,0(%r5,%r2),6 ++ jo .Llt16_1 ++ lcbb %r1,0(%r5,%r3),6 ++ jo .Llt16_2 ++ aghi %r5,16 ++ vfenezfs %v18,%v16,%v17 ++ clgrjhe %r5,%r4,.Llastcmp ++ jno .Lfound ++ ++ j .Lloop ++ ++.Llt16_1: ++ lcbb %r1,0(%r5,%r3),6 /* Get loaded byte count of s2. */ ++.Llt16_2: ++ clr %r0,%r1 /* Compare logical. */ ++ locrh %r0,%r1 /* Compute minimum of bytes loaded. */ ++ nill %r0,65532 /* Align bytes loaded to full characters. */ ++ jz .Lcmp_one_char /* Jump away if no full char is available. */ ++.Llt_cmp: ++ algfr %r5,%r0 /* Add smallest loaded bytes to current_len. */ ++ vfenezfs %v18,%v16,%v17 /* Compare not equal with zero search. */ ++ clgrj %r5,%r4,10,.Llastcmp /* If current_len >= n -> last compare */ ++ vlgvb %r1,%v18,7 /* Get not equal index or 16 if all equal. */ ++ clrjl %r1,%r0,.Lfound /* Jump away if miscompare is within ++ loaded bytes; (index < loaded-bytes) */ ++ j .Lloop ++ ++.Lcmp_one_char: ++ /* At least one of both strings is not 4-byte aligned ++ and there is no full character before next block-boundary. ++ Compare one character to get over the boundary and ++ proceed with normal loop! */ ++ vlef %v16,0(%r5,%r2),0 /* Load one character. */ ++ lghi %r0,4 /* Loaded byte count is 4. */ ++ vlef %v17,0(%r5,%r3),0 ++ j .Llt_cmp /* Proceed with comparision. */ ++ ++.Llastcmp: ++ /* Use comparision result only if located within first n characters. ++ %r0: loaded byte count in vreg; ++ %r5: current_len; ++ %r4: n; ++ (current_len - n): [0...16[ ++ First ignored match index: loaded bytes - (current_len-n): ]0...16] ++ */ ++ slgr %r5,%r4 /* %r5 = current_len - n. */ ++ slr %r0,%r5 /* %r0 = first ignored match index. */ ++ vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */ ++ clrjl %r4,%r0,.Lfound2 /* Jump away if miscompare is within ++ loaded bytes and below n bytes. */ ++.Lend_equal: ++ lghi %r2,0 ++ br %r14 ++ ++.Lfound: ++ /* Difference or end of string. */ ++ /* vfenezf found an unequal element or zero. ++ This instruction compares unsigned words, but wchar_t is signed. ++ Thus we have to compare the found element again. */ ++ vlgvb %r4,%v18,7 /* Extract not equal byte-index. */ ++.Lfound2: ++ srl %r4,2 /* And convert it to character-index. */ ++ vlgvf %r0,%v16,0(%r4) /* Load character-values. */ ++ vlgvf %r1,%v17,0(%r4) ++.Lend_cmp_one_char: ++ cr %r0,%r1 ++ je .Lend_equal ++ lghi %r2,1 ++ lghi %r1,-1 ++ locgrl %r2,%r1 ++ br %r14 ++END(__wcsncmp_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsncmp.c b/sysdeps/s390/multiarch/wcsncmp.c +new file mode 100644 +index 0000000..0d79661 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsncmp.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcsncmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcsncmp, wcsncmp) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 44b1502..611b2c9 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -41,7 +41,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + isoc99_swscanf isoc99_vswscanf \ + mbrtoc16 c16rtomb + +-strop-tests := wcscmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ ++strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ + wcpcpy wcsncpy wcpncpy wcscat wcsncat + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ +diff --git a/wcsmbs/test-wcsncmp-ifunc.c b/wcsmbs/test-wcsncmp-ifunc.c +new file mode 100644 +index 0000000..35176f0 +--- /dev/null ++++ b/wcsmbs/test-wcsncmp-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcsncmp function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcsncmp.c" +diff --git a/wcsmbs/test-wcsncmp.c b/wcsmbs/test-wcsncmp.c +new file mode 100644 +index 0000000..07757d8 +--- /dev/null ++++ b/wcsmbs/test-wcsncmp.c +@@ -0,0 +1,2 @@ ++#define WIDE 1 ++#include "../string/test-strncmp.c" +diff --git a/wcsmbs/wcsncmp.c b/wcsmbs/wcsncmp.c +index 7f1704f..1522b6f 100644 +--- a/wcsmbs/wcsncmp.c ++++ b/wcsmbs/wcsncmp.c +@@ -18,53 +18,56 @@ + + #include + ++#ifndef WCSNCMP ++# define WCSNCMP wcsncmp ++#endif + + /* Compare no more than N characters of S1 and S2, + returning less than, equal to or greater than zero + if S1 is lexicographically less than, equal to or + greater than S2. */ + int +-wcsncmp (s1, s2, n) ++WCSNCMP (s1, s2, n) + const wchar_t *s1; + const wchar_t *s2; + size_t n; + { +- wint_t c1 = L'\0'; +- wint_t c2 = L'\0'; ++ wchar_t c1 = L'\0'; ++ wchar_t c2 = L'\0'; + + if (n >= 4) + { + size_t n4 = n >> 2; + do + { +- c1 = (wint_t) *s1++; +- c2 = (wint_t) *s2++; ++ c1 = *s1++; ++ c2 = *s2++; + if (c1 == L'\0' || c1 != c2) +- return c1 - c2; +- c1 = (wint_t) *s1++; +- c2 = (wint_t) *s2++; ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); ++ c1 = *s1++; ++ c2 = *s2++; + if (c1 == L'\0' || c1 != c2) +- return c1 - c2; +- c1 = (wint_t) *s1++; +- c2 = (wint_t) *s2++; ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); ++ c1 = *s1++; ++ c2 = *s2++; + if (c1 == L'\0' || c1 != c2) +- return c1 - c2; +- c1 = (wint_t) *s1++; +- c2 = (wint_t) *s2++; ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); ++ c1 = *s1++; ++ c2 = *s2++; + if (c1 == L'\0' || c1 != c2) +- return c1 - c2; ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); + } while (--n4 > 0); + n &= 3; + } + + while (n > 0) + { +- c1 = (wint_t) *s1++; +- c2 = (wint_t) *s2++; ++ c1 = *s1++; ++ c2 = *s2++; + if (c1 == L'\0' || c1 != c2) +- return c1 - c2; ++ return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); + n--; + } + +- return c1 - c2; ++ return 0; + } +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-2.patch b/SOURCES/glibc-rh1268008-2.patch new file mode 100644 index 00000000..5e61cf73 --- /dev/null +++ b/SOURCES/glibc-rh1268008-2.patch @@ -0,0 +1,52 @@ +From 0d53b09f7052ae07d4e1dd96908a406d7841eab2 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:28:40 +0200 +Subject: [PATCH 02/30] S/390: Use attribute_hidden in ifunc-resolve.c + +upstream-commit-id: 5f67c04f5e076d3cfc4d810e7f5d65ce1788b749 +https://sourceware.org/ml/libc-alpha/2013-03/msg00085.html + +This patch is needed to prepare for the optimized string function patchset. +Make the declarations of the optimized functions hidden in order to prevent +GOT slots being generated for them. +--- + sysdeps/s390/s390-32/multiarch/ifunc-resolve.c | 6 +++--- + sysdeps/s390/s390-64/multiarch/ifunc-resolve.c | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c b/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c +index f1bf8a3..42ca8da 100644 +--- a/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c ++++ b/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c +@@ -34,9 +34,9 @@ + \ + /* Make the declarations of the optimized functions hidden in order + to prevent GOT slots being generated for them. */ \ +- extern __attribute__((visibility("hidden"))) void *FUNC##_z196; \ +- extern __attribute__((visibility("hidden"))) void *FUNC##_z10; \ +- extern __attribute__((visibility("hidden"))) void *FUNC##_g5; \ ++ extern void *FUNC##_z196 attribute_hidden; \ ++ extern void *FUNC##_z10 attribute_hidden; \ ++ extern void *FUNC##_g5 attribute_hidden; \ + \ + void *resolve_##FUNC (unsigned long int dl_hwcap) \ + { \ +diff --git a/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c b/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c +index 5f56764..8db2c38 100644 +--- a/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c ++++ b/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c +@@ -34,9 +34,9 @@ + \ + /* Make the declarations of the optimized functions hidden in order + to prevent GOT slots being generated for them. */ \ +- extern __attribute__((visibility("hidden"))) void *FUNC##_z196; \ +- extern __attribute__((visibility("hidden"))) void *FUNC##_z10; \ +- extern __attribute__((visibility("hidden"))) void *FUNC##_z900; \ ++ extern void *FUNC##_z196 attribute_hidden; \ ++ extern void *FUNC##_z10 attribute_hidden; \ ++ extern void *FUNC##_z900 attribute_hidden; \ + \ + void *resolve_##FUNC (unsigned long int dl_hwcap) \ + { \ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-20.patch b/SOURCES/glibc-rh1268008-20.patch new file mode 100644 index 00000000..e6b37b7a --- /dev/null +++ b/SOURCES/glibc-rh1268008-20.patch @@ -0,0 +1,499 @@ +From 0b3ff29b298c488ab995d4224da2cc36fb56ddce Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 11:25:00 +0200 +Subject: [PATCH 20/30] S390: Optimize strchr and wcschr. + +upstream-commit-id: cf150d45a97c6bb8410d6d3acf6e1560e8fe96cc +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00094.html + +This patch provides optimized versions of strchr and wcschr with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strchr-c.c: New File. + * sysdeps/s390/multiarch/strchr-vx.S: Likewise. + * sysdeps/s390/multiarch/strchr.c: Likewise. + * sysdeps/s390/multiarch/wcschr-c.c: Likewise. + * sysdeps/s390/multiarch/wcschr-vx.S: Likewise. + * sysdeps/s390/multiarch/wcschr.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strchr and + wcschr functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strchr, wcschr. + * string/strchr.c (STRCHR): Define and use macro. + * benchtests/bench-wcschr.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcschr. +--- + benchtests/Makefile | 2 +- + benchtests/bench-wcschr.c | 20 ++++++ + string/strchr.c | 8 ++- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strchr-c.c | 29 +++++++++ + sysdeps/s390/multiarch/strchr-vx.S | 100 ++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strchr.c | 28 +++++++++ + sysdeps/s390/multiarch/wcschr-c.c | 31 ++++++++++ + sysdeps/s390/multiarch/wcschr-vx.S | 103 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcschr.c | 27 ++++++++ + 11 files changed, 351 insertions(+), 6 deletions(-) + create mode 100644 benchtests/bench-wcschr.c + create mode 100644 sysdeps/s390/multiarch/strchr-c.c + create mode 100644 sysdeps/s390/multiarch/strchr-vx.S + create mode 100644 sysdeps/s390/multiarch/strchr.c + create mode 100644 sysdeps/s390/multiarch/wcschr-c.c + create mode 100644 sysdeps/s390/multiarch/wcschr-vx.S + create mode 100644 sysdeps/s390/multiarch/wcschr.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index f6342da..bcb0288 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp ++ wcsncmp wcsncmp wcschr + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-wcschr.c b/benchtests/bench-wcschr.c +new file mode 100644 +index 0000000..4287724 +--- /dev/null ++++ b/benchtests/bench-wcschr.c +@@ -0,0 +1,20 @@ ++/* Measure wcschr functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strchr.c" +diff --git a/string/strchr.c b/string/strchr.c +index 9d18b7e..69a9cd9 100644 +--- a/string/strchr.c ++++ b/string/strchr.c +@@ -27,11 +27,13 @@ + + #undef strchr + ++#ifndef STRCHR ++# define STRCHR strchr ++#endif ++ + /* Find the first occurrence of C in S. */ + char * +-strchr (s, c_in) +- const char *s; +- int c_in; ++STRCHR (const char *s, int c_in) + { + const unsigned char *char_ptr; + const unsigned long int *longword_ptr; +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index d77bee5..1a3673b 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -8,7 +8,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strcat strcat-vx strcat-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ +- strncmp strncmp-vx strncmp-c ++ strncmp strncmp-vx strncmp-c \ ++ strchr strchr-vx strchr-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -21,5 +22,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscat wcscat-vx wcscat-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ +- wcsncmp wcsncmp-vx wcsncmp-c ++ wcsncmp wcsncmp-vx wcsncmp-c \ ++ wcschr wcschr-vx wcschr-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 5bfc493..b0782ff 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -109,6 +109,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strncmp); + IFUNC_VX_IMPL (wcsncmp); + ++ IFUNC_VX_IMPL (strchr); ++ IFUNC_VX_IMPL (wcschr); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strchr-c.c b/sysdeps/s390/multiarch/strchr-c.c +new file mode 100644 +index 0000000..4384e6b +--- /dev/null ++++ b/sysdeps/s390/multiarch/strchr-c.c +@@ -0,0 +1,29 @@ ++/* Default strchr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRCHR __strchr_c ++# undef weak_alias ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strchr_c, __GI_strchr, __strchr_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strchr-vx.S b/sysdeps/s390/multiarch/strchr-vx.S +new file mode 100644 +index 0000000..26180df +--- /dev/null ++++ b/sysdeps/s390/multiarch/strchr-vx.S +@@ -0,0 +1,100 @@ ++/* Vector optimized 32/64 bit S/390 version of strchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char *strchr (const char *s, int c) ++ Locate character in string. ++ ++ Register usage: ++ -r1=tmp ++ -r2=s ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v17=index of unequal ++ -v18=replicated c ++*/ ++ENTRY(__strchr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ vlvgb %v18,%r3,0 /* Generate vector which elements are all c. ++ If c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ ++ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ ++ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find c/zero in 16 byte aligned loop */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ jno .Lfound /* Found c/zero (cc=0|1|2). */ ++ vl %v16,16(%r5,%r2) ++ vfeezbs %v16,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeezbs %v16,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeezbs %v16,%v16,%v18 ++ jno .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character and no zero -> loop. */ ++ ++.Lfound48: ++ la %r5,16(%r5) /* Use la since aghi would clobber cc. */ ++.Lfound32: ++ la %r5,16(%r5) ++.Lfound16: ++ la %r5,16(%r5) ++.Lfound: ++ je .Lzero /* Found zero, but no c before that zero. */ ++ ++.Lcharacter: ++ vlgvb %r4,%v16,7 /* Load byte index of character. */ ++ algr %r5,%r4 ++ la %r2,0(%r5,%r2) /* Return pointer to character. */ ++ br %r14 ++ ++.Lzero: ++ llgcr %r3,%r3 /* char c_char = (char) c. */ ++ clije %r3,0,.Lcharacter /* Found zero and c is zero. */ ++ lghi %r2,0 /* Return null if character not found. */ ++ br %r14 ++END(__strchr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c +new file mode 100644 +index 0000000..e2a310f +--- /dev/null ++++ b/sysdeps/s390/multiarch/strchr.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of strchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strchr, strchr) ++weak_alias (strchr, index) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcschr-c.c b/sysdeps/s390/multiarch/wcschr-c.c +new file mode 100644 +index 0000000..ad7415e +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcschr-c.c +@@ -0,0 +1,31 @@ ++/* Default wcschr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSCHR __wcschr_c ++ ++# include ++extern __typeof (wcschr) __wcschr_c; ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcschr_c, __GI_wcschr, __wcschr_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcschr-vx.S b/sysdeps/s390/multiarch/wcschr-vx.S +new file mode 100644 +index 0000000..c1b3f6b +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcschr-vx.S +@@ -0,0 +1,103 @@ ++/* Vector optimized 32/64 bit S/390 version of wcschr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t *wcschr (const wchar_t *s, wchar_t c) ++ Locate character in string. ++ ++ Register usage: ++ -r1=tmp ++ -r2=s ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v17=index of unequal ++ -v18=replicated c ++*/ ++ENTRY(__wcschr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ ++ vrepf %v18,%v18,0 ++ ++ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ ++ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find c/zero in 16byte aligned loop */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ jno .Lfound /* Found c/zero (cc=0|1|2). */ ++ vl %v16,16(%r5,%r2) ++ vfeezfs %v16,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeezfs %v16,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeezfs %v16,%v16,%v18 ++ jno .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character and no zero -> loop. */ ++ ++.Lfound48: ++ la %r5,16(%r5) /* Use la since aghi would clobber cc. */ ++.Lfound32: ++ la %r5,16(%r5) ++.Lfound16: ++ la %r5,16(%r5) ++.Lfound: ++ je .Lzero /* Found zero, but no c before that zero. */ ++ ++.Lcharacter: ++ vlgvb %r4,%v16,7 /* Load byte index of character. */ ++ algr %r5,%r4 ++ la %r2,0(%r5,%r2) /* Return pointer to character. */ ++ br %r14 ++ ++.Lzero: ++ clije %r3,0,.Lcharacter /* Found zero and c is zero. */ ++ lghi %r2,0 /* Return null if character not found. */ ++ br %r14 ++.Lfallback: ++ jg __wcschr_c ++END(__wcschr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c +new file mode 100644 +index 0000000..9c8c097 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcschr.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcschr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcschr, wcschr) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-21.patch b/SOURCES/glibc-rh1268008-21.patch new file mode 100644 index 00000000..41a0fb92 --- /dev/null +++ b/SOURCES/glibc-rh1268008-21.patch @@ -0,0 +1,663 @@ +From 24020ef9258267c5d65ab37dbf118bf52e4995d2 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 12:40:02 +0200 +Subject: [PATCH 21/30] S390: Optimize strchrnul and wcschrnul. + +upstream-commit-id: d23d4ef19f1f5463745f2af205acb8c4975fd680 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00098.html + +This patch provides optimized versions of strchrnul and wcschrnul with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strchrnul-c.c: New File. + * sysdeps/s390/multiarch/strchrnul-vx.S: Likewise. + * sysdeps/s390/multiarch/strchrnul.c: Likewise. + * sysdeps/s390/multiarch/wcschrnul-c.c: Likewise. + * sysdeps/s390/multiarch/wcschrnul-vx.S: Likewise. + * sysdeps/s390/multiarch/wcschrnul.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strchrnul and + wcschrnul functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strchrnul, wcschrnul. + * wcsmbs/wcschrnul.c: Use WCSCHRNUL if defined. + * string/test-strchr.c: Add wcschrnul support. + * wcsmbs/test-wcschrnul.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcschrnul. + * benchtests/bench-strchr.c: Add wcschrnul support. + * benchtests/bench-wcschrnul.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcschrnul. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strchr.c | 22 ++++++-- + benchtests/bench-wcschrnul.c | 20 +++++++ + string/test-strchr.c | 24 ++++++-- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strchrnul-c.c | 26 +++++++++ + sysdeps/s390/multiarch/strchrnul-vx.S | 93 ++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strchrnul.c | 28 +++++++++ + sysdeps/s390/multiarch/wcschrnul-c.c | 25 ++++++++ + sysdeps/s390/multiarch/wcschrnul-vx.S | 97 ++++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcschrnul.c | 28 +++++++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcschrnul-ifunc.c | 20 +++++++ + wcsmbs/test-wcschrnul.c | 20 +++++++ + wcsmbs/wcschrnul.c | 5 ++ + 16 files changed, 405 insertions(+), 16 deletions(-) + create mode 100644 benchtests/bench-wcschrnul.c + create mode 100644 sysdeps/s390/multiarch/strchrnul-c.c + create mode 100644 sysdeps/s390/multiarch/strchrnul-vx.S + create mode 100644 sysdeps/s390/multiarch/strchrnul.c + create mode 100644 sysdeps/s390/multiarch/wcschrnul-c.c + create mode 100644 sysdeps/s390/multiarch/wcschrnul-vx.S + create mode 100644 sysdeps/s390/multiarch/wcschrnul.c + create mode 100644 wcsmbs/test-wcschrnul-ifunc.c + create mode 100644 wcsmbs/test-wcschrnul.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index bcb0288..d34bb3d 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp wcschr ++ wcsncmp wcsncmp wcschr wcschrnul + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strchr.c b/benchtests/bench-strchr.c +index d432ba5..9b1aaf9 100644 +--- a/benchtests/bench-strchr.c ++++ b/benchtests/bench-strchr.c +@@ -22,10 +22,14 @@ + # define TEST_NAME "strchrnul" + # else + # define TEST_NAME "strchr" +-# endif ++# endif /* !USE_FOR_STRCHRNUL */ + #else +-# define TEST_NAME "wcschr" +-#endif ++# ifdef USE_FOR_STRCHRNUL ++# define TEST_NAME "wcschrnul" ++# else ++# define TEST_NAME "wcschr" ++# endif /* !USE_FOR_STRCHRNUL */ ++#endif /* WIDE */ + #include "bench-string.h" + + #ifndef WIDE +@@ -44,20 +48,26 @@ + # define UCHAR unsigned char + #else + # include +-# define STRCHR wcschr ++# ifdef USE_FOR_STRCHRNUL ++# define STRCHR wcschrnul ++# define stupid_STRCHR stupid_WCSCHRNUL ++# define simple_STRCHR simple_WCSCHRNUL ++# else ++# define STRCHR wcschr ++# endif /* !USE_FOR_STRCHRNUL */ + # define STRLEN wcslen + # define CHAR wchar_t + # define BIG_CHAR WCHAR_MAX + # define MIDDLE_CHAR 1121 + # define SMALL_CHAR 851 + # define UCHAR wchar_t +-#endif ++#endif /* WIDE */ + + #ifdef USE_FOR_STRCHRNUL + # define NULLRET(endptr) endptr + #else + # define NULLRET(endptr) NULL +-#endif ++#endif /* !USE_FOR_STRCHRNUL */ + + + typedef CHAR *(*proto_t) (const CHAR *, int); +diff --git a/benchtests/bench-wcschrnul.c b/benchtests/bench-wcschrnul.c +new file mode 100644 +index 0000000..124b602 +--- /dev/null ++++ b/benchtests/bench-wcschrnul.c +@@ -0,0 +1,20 @@ ++/* Measure wcschrnul functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strchrnul.c" +diff --git a/string/test-strchr.c b/string/test-strchr.c +index b84e138..1cd14d7 100644 +--- a/string/test-strchr.c ++++ b/string/test-strchr.c +@@ -26,8 +26,12 @@ + # define TEST_NAME "strchr" + # endif + #else +-# define TEST_NAME "wcschr" +-#endif ++# ifdef USE_FOR_STRCHRNUL ++# define TEST_NAME "wcschrnul" ++# else ++# define TEST_NAME "wcschr" ++# endif /* !USE_FOR_STRCHRNUL */ ++#endif /* WIDE */ + #include "test-string.h" + + #ifndef WIDE +@@ -44,15 +48,23 @@ + # define MIDDLE_CHAR 127 + # define SMALL_CHAR 23 + # define UCHAR unsigned char ++# define L(s) s + #else + # include +-# define STRCHR wcschr ++# ifdef USE_FOR_STRCHRNUL ++# define STRCHR wcschrnul ++# define stupid_STRCHR stupid_WCSCHRNUL ++# define simple_STRCHR simple_WCSCHRNUL ++# else ++# define STRCHR wcschr ++# endif /* !USE_FOR_STRCHRNUL */ + # define STRLEN wcslen + # define CHAR wchar_t + # define BIG_CHAR WCHAR_MAX + # define MIDDLE_CHAR 1121 + # define SMALL_CHAR 851 + # define UCHAR wchar_t ++# define L(s) L ## s + #endif + + #ifdef USE_FOR_STRCHRNUL +@@ -219,9 +231,9 @@ do_random_tests (void) + static void + check1 (void) + { +- char s[] __attribute__((aligned(16))) = "\xff"; +- char c = '\xfe'; +- char *exp_result = stupid_STRCHR (s, c); ++ CHAR s[] __attribute__((aligned(16))) = L ("\xff"); ++ CHAR c = L ('\xfe'); ++ CHAR *exp_result = stupid_STRCHR (s, c); + + FOR_EACH_IMPL (impl, 0) + check_result (impl, s, c, exp_result); +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 1a3673b..b6b64c9 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -9,7 +9,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strncat strncat-vx strncat-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ +- strchr strchr-vx strchr-c ++ strchr strchr-vx strchr-c \ ++ strchrnul strchrnul-vx strchrnul-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -23,5 +24,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncat wcsncat-vx wcsncat-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ +- wcschr wcschr-vx wcschr-c ++ wcschr wcschr-vx wcschr-c \ ++ wcschrnul wcschrnul-vx wcschrnul-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b0782ff..ea474a8 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -112,6 +112,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strchr); + IFUNC_VX_IMPL (wcschr); + ++ IFUNC_VX_IMPL (strchrnul); ++ IFUNC_VX_IMPL (wcschrnul); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strchrnul-c.c b/sysdeps/s390/multiarch/strchrnul-c.c +new file mode 100644 +index 0000000..7615217 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strchrnul-c.c +@@ -0,0 +1,26 @@ ++/* Default strchrnul implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRCHRNUL __strchrnul_c ++# define __strchrnul STRCHRNUL ++# undef weak_alias ++# define weak_alias(name, alias) ++ ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/strchrnul-vx.S b/sysdeps/s390/multiarch/strchrnul-vx.S +new file mode 100644 +index 0000000..2c5f167 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strchrnul-vx.S +@@ -0,0 +1,93 @@ ++/* Vector optimized 32/64 bit S/390 version of strchrnul. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char *strchrnul (const char *s, int c) ++ Returns pointer to first c or to \0 if c not found. ++ ++ Register usage: ++ -r1=tmp ++ -r2=s and return pointer ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v18=vector with c replicated in every byte ++*/ ++ENTRY(__strchrnul_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ vlvgb %v18,%r3,0 /* Generate vector which elements are all c. ++ If c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ ++ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ ++ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find c/zero in 16byte aligned loop */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s */ ++ vfeezbs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ jno .Lfound /* Found c/zero (cc=0|1|2). */ ++ vl %v16,16(%r5,%r2) ++ vfeezbs %v16,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeezbs %v16,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeezbs %v16,%v16,%v18 ++ jno .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character and no zero -> loop. */ ++ ++ /* Found character or zero */ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r1,%v16,7 /* Load byte index of character. */ ++ algr %r5,%r1 ++ la %r2,0(%r5,%r2) /* Return pointer to character. */ ++ ++.Lend: ++ br %r14 ++END(__strchrnul_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strchrnul.c b/sysdeps/s390/multiarch/strchrnul.c +new file mode 100644 +index 0000000..73fcf19 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strchrnul.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of strchrnul. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__strchrnul) ++weak_alias (__strchrnul, strchrnul) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/multiarch/wcschrnul-c.c +new file mode 100644 +index 0000000..31fa416 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcschrnul-c.c +@@ -0,0 +1,25 @@ ++/* Default wcschrnul implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSCHRNUL __wcschrnul_c ++ ++# include ++extern __typeof (__wcschrnul) __wcschrnul_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcschrnul-vx.S b/sysdeps/s390/multiarch/wcschrnul-vx.S +new file mode 100644 +index 0000000..a89aee0 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcschrnul-vx.S +@@ -0,0 +1,97 @@ ++/* Vector optimized 32/64 bit S/390 version of wcschrnul. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t* wcschrnul (const wchar_t *s, wchar_t c) ++ Returns pointer to first c or to \0 if c not found. ++ ++ Register usage: ++ -r1=tmp ++ -r2=s and return pointer ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v18=vector with c replicated in every byte ++*/ ++ENTRY(__wcschrnul_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ ++ vrepf %v18,%v18,0 ++ ++ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ vlgvb %r4,%v16,7 /* Load byte index of character or zero. */ ++ clrjl %r4,%r1,.Lfound /* Return if c/zero is in loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find c/zero in 16byte aligned loop */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfeezfs %v16,%v16,%v18 /* Find element equal with zero search. */ ++ jno .Lfound /* Found c/zero (cc=0|1|2). */ ++ vl %v16,16(%r5,%r2) ++ vfeezfs %v16,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeezfs %v16,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeezfs %v16,%v16,%v18 ++ jno .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character and no zero -> loop. */ ++ ++ /* Found character or zero */ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r1,%v16,7 /* Load byte index of character. */ ++ algr %r5,%r1 ++ la %r2,0(%r5,%r2) /* Return pointer to character. */ ++ ++.Lend: ++ br %r14 ++.Lfallback: ++ jg __wcschrnul_c ++END(__wcschrnul_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/multiarch/wcschrnul.c +new file mode 100644 +index 0000000..644258b +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcschrnul.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of wcschrnul. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__wcschrnul) ++weak_alias (__wcschrnul, wcschrnul) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 611b2c9..de3635d 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy wcpncpy wcscat wcsncat ++ wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcschrnul-ifunc.c b/wcsmbs/test-wcschrnul-ifunc.c +new file mode 100644 +index 0000000..e64a1e4 +--- /dev/null ++++ b/wcsmbs/test-wcschrnul-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcschrnul function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcschrnul.c" +diff --git a/wcsmbs/test-wcschrnul.c b/wcsmbs/test-wcschrnul.c +new file mode 100644 +index 0000000..baea763 +--- /dev/null ++++ b/wcsmbs/test-wcschrnul.c +@@ -0,0 +1,20 @@ ++/* Test wcschrnul functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strchrnul.c" +diff --git a/wcsmbs/wcschrnul.c b/wcsmbs/wcschrnul.c +index 04db8f1..1e4c44f 100644 +--- a/wcsmbs/wcschrnul.c ++++ b/wcsmbs/wcschrnul.c +@@ -17,6 +17,9 @@ + + #include + ++#ifdef WCSCHRNUL ++# define __wcschrnul WCSCHRNUL ++#endif + + /* Find the first occurrence of WC in WCS. */ + wchar_t * +@@ -32,4 +35,6 @@ __wcschrnul (wcs, wc) + + return (wchar_t *) wcs; + } ++#ifndef WCSCHRNUL + weak_alias (__wcschrnul, wcschrnul) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-22.patch b/SOURCES/glibc-rh1268008-22.patch new file mode 100644 index 00000000..dea8911e --- /dev/null +++ b/SOURCES/glibc-rh1268008-22.patch @@ -0,0 +1,657 @@ +From cb5e8d0ec1a4c4eb09da45015755e3d18b3a086b Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 12:43:56 +0200 +Subject: [PATCH 22/30] S390: Optimize strrchr and wcsrchr. + +upstream-commit-id: f40132d4bda984479bac89dfcd6968e9ff56e088 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00101.html + +This patch provides optimized versions of strrchr and wcsrchr with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strrchr-c.c: New File. + * sysdeps/s390/multiarch/strrchr-vx.S: Likewise. + * sysdeps/s390/multiarch/strrchr.c: Likewise. + * sysdeps/s390/multiarch/wcsrchr-c.c: Likewise. + * sysdeps/s390/multiarch/wcsrchr-vx.S: Likewise. + * sysdeps/s390/multiarch/wcsrchr.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strrchr and + wcsrchr functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strrchr, wcsrchr. + * benchtests/bench-wcsrchr.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcsrchr. +--- + benchtests/Makefile | 2 +- + benchtests/bench-wcsrchr.c | 20 ++++ + string/strrchr.c | 6 +- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strrchr-c.c | 29 +++++ + sysdeps/s390/multiarch/strrchr-vx.S | 180 +++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strrchr.c | 28 +++++ + sysdeps/s390/multiarch/wcsrchr-c.c | 25 ++++ + sysdeps/s390/multiarch/wcsrchr-vx.S | 190 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcsrchr.c | 27 +++++ + 11 files changed, 512 insertions(+), 4 deletions(-) + create mode 100644 benchtests/bench-wcsrchr.c + create mode 100644 sysdeps/s390/multiarch/strrchr-c.c + create mode 100644 sysdeps/s390/multiarch/strrchr-vx.S + create mode 100644 sysdeps/s390/multiarch/strrchr.c + create mode 100644 sysdeps/s390/multiarch/wcsrchr-c.c + create mode 100644 sysdeps/s390/multiarch/wcsrchr-vx.S + create mode 100644 sysdeps/s390/multiarch/wcsrchr.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index d34bb3d..6444394 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp wcschr wcschrnul ++ wcsncmp wcsncmp wcschr wcschrnul wcsrchr + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-wcsrchr.c b/benchtests/bench-wcsrchr.c +new file mode 100644 +index 0000000..0d3923f +--- /dev/null ++++ b/benchtests/bench-wcsrchr.c +@@ -0,0 +1,20 @@ ++/* Measure wcsrchr functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strrchr.c" +diff --git a/string/strrchr.c b/string/strrchr.c +index a986ff9..03f3957 100644 +--- a/string/strrchr.c ++++ b/string/strrchr.c +@@ -19,9 +19,13 @@ + + #undef strrchr + ++#ifndef STRRCHR ++# define STRRCHR strrchr ++#endif ++ + /* Find the last occurrence of C in S. */ + char * +-strrchr (const char *s, int c) ++STRRCHR (const char *s, int c) + { + register const char *found, *p; + +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index b6b64c9..b8b141e 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -10,7 +10,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strcmp strcmp-vx \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ +- strchrnul strchrnul-vx strchrnul-c ++ strchrnul strchrnul-vx strchrnul-c \ ++ strrchr strrchr-vx strrchr-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -25,5 +26,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcscmp wcscmp-vx wcscmp-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ +- wcschrnul wcschrnul-vx wcschrnul-c ++ wcschrnul wcschrnul-vx wcschrnul-c \ ++ wcsrchr wcsrchr-vx wcsrchr-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ea474a8..ee84d80 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -115,6 +115,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strchrnul); + IFUNC_VX_IMPL (wcschrnul); + ++ IFUNC_VX_IMPL (strrchr); ++ IFUNC_VX_IMPL (wcsrchr); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strrchr-c.c b/sysdeps/s390/multiarch/strrchr-c.c +new file mode 100644 +index 0000000..b035cdc +--- /dev/null ++++ b/sysdeps/s390/multiarch/strrchr-c.c +@@ -0,0 +1,29 @@ ++/* Default strrchr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRRCHR __strrchr_c ++# undef weak_alias ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strrchr_c, __GI_strrchr, __strrchr_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strrchr-vx.S b/sysdeps/s390/multiarch/strrchr-vx.S +new file mode 100644 +index 0000000..dbc183b +--- /dev/null ++++ b/sysdeps/s390/multiarch/strrchr-vx.S +@@ -0,0 +1,180 @@ ++/* Vector optimized 32/64 bit S/390 version of strrchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char *strrchr (const char *s, int c) ++ Locate the last character c in string. ++ ++ Register usage: ++ -r0=loaded bytes in first part of s. ++ -r1=pointer to last occurence of c or NULL if not found. ++ -r2=s ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v17=index of found element ++ -v18=replicated c ++ -v19=part of s with last occurence of c. ++ -v20=permute pattern ++*/ ++ENTRY(__strrchr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vlvgb %v18,%r3,0 /* Generate vector which elements are all c. ++ if c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ ++ lghi %r1,-1 /* Currently no c found. */ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ vfeezbs %v17,%v16,%v18 /* Find element equal or zero. */ ++ vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */ ++ clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */ ++.Lalign: ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfeezbs %v17,%v16,%v18 /* Find element equal with zero search. */ ++ jno .Lfound /* Found c/zero (cc=0|1|2). */ ++ vl %v16,16(%r5,%r2) ++ vfeezbs %v17,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeezbs %v17,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeezbs %v17,%v16,%v18 ++ jno .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character and no zero -> loop. */ ++ ++.Lfound48: ++ la %r5,16(%r5) /* Use la since aghi would clobber cc. */ ++.Lfound32: ++ la %r5,16(%r5) ++.Lfound16: ++ la %r5,16(%r5) ++.Lfound: ++ je .Lzero /* Found zero, but no c before that zero. */ ++ /* Save this part of s to check for further matches after reaching ++ the end of the complete string. */ ++ vlr %v19,%v16 ++ lgr %r1,%r5 ++ ++ jh .Lzero /* Found a zero after the found c. */ ++ aghi %r5,16 /* Start search of next part of s. */ ++ j .Lloop ++ ++.Lfound_first_part: ++ /* This code is only executed if the found c/zero is whithin loaded ++ bytes. If no c/zero was found (cc==3) the found index = 16, thus ++ this code is not called. ++ Resulting condition code of vector find element equal: ++ cc==0: no c, found zero ++ cc==1: c found, no zero ++ cc==2: c found, found zero after c ++ cc==3: no c, no zero (this case can be ignored). */ ++ je .Lzero /* Found zero, but no c before that zero. */ ++ ++ locgrne %r1,%r5 /* Mark c as found in first part of s. */ ++ vlr %v19,%v16 ++ ++ jl .Lalign /* No zero (e.g. if vr was fully loaded) ++ -> Align and loop afterwards. */ ++ ++ /* Found a zero in vr. If vr was not fully loaded due to block ++ boundary, the remaining bytes are filled with zero and we can't ++ rely on zero indication of condition code here! */ ++ ++ vfenezb %v17,%v16,%v16 /* Find zero. */ ++ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ ++ clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */ ++ j .Lalign /* Align and loop afterwards. */ ++ ++.Lend_searched_zero: ++ vlgvb %r4,%v17,7 /* Load byte index of zero. */ ++ algr %r5,%r4 ++ la %r2,0(%r5,%r2) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lzero: ++ /* Reached end of string. Check if one c was found before. */ ++ clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */ ++ ++ cgfi %r1,-1 /* No c found -> return NULL. */ ++ locghie %r2,0 ++ ber %r14 ++ ++ larl %r3,.Lpermute_mask /* Load permute mask. */ ++ vl %v20,0(%r3) ++ ++ /* c was found and is part of v19. */ ++ vfenezb %v17,%v19,%v19 /* Find zero. */ ++ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ ++ ++ clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */ ++ lochine %r0,16 /* ... if v19 is not the first part of s. */ ++ ahi %r0,-1 /* Convert byte count to highest index. */ ++ ++ clr %r0,%r4 ++ locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */ ++ ++ /* Right-shift of v19 to mask bytes after zero. */ ++ clije %r4,15,.Lzero_permute /* No shift is needed if highest index ++ in vr is 15. */ ++ lhi %r0,15 ++ slr %r0,%r4 /* Compute byte count for vector shift right. */ ++ sll %r0,3 /* Convert to bit count. */ ++ vlvgb %v17,%r0,7 ++ vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes ++ specified in bits 1-4 of byte 7 in v17. */ ++ ++ /* Reverse bytes in v19. */ ++.Lzero_permute: ++ vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */ ++ ++ /* Find c in reversed v19. */ ++ vfeeb %v19,%v19,%v18 /* Find c. */ ++ la %r2,0(%r1,%r2) ++ vlgvb %r3,%v19,7 /* Load byte index of c. */ ++ ++ /* Compute index in real s and return. */ ++ slgr %r4,%r3 ++ la %r2,0(%r4,%r2) /* Return pointer to zero. */ ++ br %r14 ++.Lpermute_mask: ++ .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 ++ .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 ++END(__strrchr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c +new file mode 100644 +index 0000000..dc4efd3 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strrchr.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of strrchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strrchr, strrchr) ++weak_alias (strrchr, rindex) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcsrchr-c.c b/sysdeps/s390/multiarch/wcsrchr-c.c +new file mode 100644 +index 0000000..8f66600 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsrchr-c.c +@@ -0,0 +1,25 @@ ++/* Default wcsrchr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSRCHR __wcsrchr_c ++ ++# include ++extern __typeof (wcsrchr) __wcsrchr_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcsrchr-vx.S b/sysdeps/s390/multiarch/wcsrchr-vx.S +new file mode 100644 +index 0000000..efb7701 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsrchr-vx.S +@@ -0,0 +1,190 @@ ++/* Vector optimized 32/64 bit S/390 version of wcsrchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t *wcsrchr (const wchar_t *s, wchar_t c) ++ Locate the last character c in string. ++ ++ Register usage: ++ -r0=loaded bytes in first part of s. ++ -r1=pointer to last occurence of c or NULL if not found. ++ -r2=s ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v17=index of found element ++ -v18=replicated c ++ -v19=part of s with last occurence of c. ++ -v20=permute pattern ++*/ ++ENTRY(__wcsrchr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ ++ vrepf %v18,%v18,0 ++ ++ lghi %r1,-1 /* Currently no c found. */ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ vfeezfs %v17,%v16,%v18 /* Find element equal or zero. */ ++ vlgvb %r4,%v17,7 /* Load byte index of c/zero or 16. */ ++ clrjl %r4,%r0,.Lfound_first_part /* Found c/zero in loaded bytes. */ ++.Lalign: ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 /* current_len = 16. */ ++ slr %r5,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfeezfs %v17,%v16,%v18 /* Find element equal with zero search. */ ++ jno .Lfound /* Found c/zero (cc=0|1|2). */ ++ vl %v16,16(%r5,%r2) ++ vfeezfs %v17,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeezfs %v17,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeezfs %v17,%v16,%v18 ++ jno .Lfound48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character and no zero -> loop. */ ++ ++.Lfound48: ++ la %r5,16(%r5) /* Use la since aghi would clobber cc. */ ++.Lfound32: ++ la %r5,16(%r5) ++.Lfound16: ++ la %r5,16(%r5) ++.Lfound: ++ je .Lzero /* Found zero, but no c before that zero. */ ++ /* Save this part of s to check for further matches after reaching ++ the end of the complete string. */ ++ vlr %v19,%v16 ++ lgr %r1,%r5 ++ ++ jh .Lzero /* Found a zero after the found c. */ ++ aghi %r5,16 /* Start search of next part of s. */ ++ j .Lloop ++ ++.Lfound_first_part: ++ /* This code is only executed if the found c/zero is whithin loaded ++ bytes. If no c/zero was found (cc==3) the found index = 16, thus ++ this code is not called. ++ Resulting condition code of vector find element equal: ++ cc==0: no c, found zero ++ cc==1: c found, no zero ++ cc==2: c found, found zero after c ++ cc==3: no c, no zero (this case can be ignored). */ ++ je .Lzero /* Found zero, but no c before that zero. */ ++ ++ locgrne %r1,%r5 /* Mark c as found in first part of s. */ ++ vlr %v19,%v16 ++ ++ jl .Lalign /* No zero (e.g. if vr was fully loaded) ++ -> Align and loop afterwards. */ ++ ++ /* Found a zero in vr. If vr was not fully loaded due to block ++ boundary, the remaining bytes are filled with zero and we can't ++ rely on zero indication of condition code here! */ ++ ++ vfenezf %v17,%v16,%v16 ++ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ ++ clrjl %r4,%r0,.Lzero /* Zero within loaded bytes -> end. */ ++ j .Lalign /* Align and loop afterwards. */ ++ ++.Lend_searched_zero: ++ vlgvb %r4,%v17,7 /* Load byte index of zero. */ ++ algr %r5,%r4 ++ la %r2,0(%r5,%r2) /* Return pointer to zero. */ ++ br %r14 ++ ++.Lzero: ++ /* Reached end of string. Check if one c was found before. */ ++ clije %r3,0,.Lend_searched_zero /* Found zero and c is zero. */ ++ ++ cgfi %r1,-1 /* No c found -> return NULL. */ ++ locghie %r2,0 ++ ber %r14 ++ ++ larl %r3,.Lpermute_mask /* Load permute mask. */ ++ vl %v20,0(%r3) ++ ++ /* c was found and is part of v19. */ ++ vfenezf %v17,%v19,%v19 /* Find zero. */ ++ vlgvb %r4,%v17,7 /* Load byte index of zero or 16. */ ++ ahi %r4,3 /* Found zero index is first byte, ++ thus highest byte index is last byte of ++ wchar_t zero. */ ++ ++ clgfi %r5,0 /* Loaded byte count in v19 is 16, ... */ ++ lochine %r0,16 /* ... if v19 is not the first part of s. */ ++ ahi %r0,-1 /* Convert byte count to highest index. */ ++ ++ clr %r0,%r4 ++ locrl %r4,%r0 /* r4 = min (zero-index, highest-index). */ ++ ++ /* Right-shift of v19 to mask bytes after zero. */ ++ clije %r4,15,.Lzero_permute /* No shift is needed if highest index ++ in vr is 15. */ ++ lhi %r0,15 ++ slr %r0,%r4 /* Compute byte count for vector shift left. */ ++ sll %r0,3 /* Convert to bit count. */ ++ vlvgb %v17,%r0,7 ++ vsrlb %v19,%v19,%v17 /* Vector shift right by byte by number of bytes ++ specified in bits 1-4 of byte 7 in v17. */ ++ ++ /* Reverse bytes in v19. */ ++.Lzero_permute: ++ vperm %v19,%v19,%v19,%v20 /* Permute v19 to reversed order. */ ++ ++ /* Find c in reversed v19. */ ++ vfeef %v19,%v19,%v18 /* Find c. */ ++ la %r2,0(%r1,%r2) ++ vlgvb %r3,%v19,7 /* Load byte index of c. */ ++ ++ /* Compute index in real s and return. */ ++ slgr %r4,%r3 ++ lay %r2,-3(%r4,%r2) /* Return pointer to zero. -3 is needed, ++ because the found byte index is reversed in ++ vector-register. Thus point to first byte of ++ wchar_t. */ ++ br %r14 ++.Lpermute_mask: ++ .byte 0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B ++ .byte 0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03 ++.Lfallback: ++ jg __wcsrchr_c ++END(__wcsrchr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsrchr.c b/sysdeps/s390/multiarch/wcsrchr.c +new file mode 100644 +index 0000000..db3f467 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsrchr.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcsrchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcsrchr, wcsrchr) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-23.patch b/SOURCES/glibc-rh1268008-23.patch new file mode 100644 index 00000000..4f7a35b3 --- /dev/null +++ b/SOURCES/glibc-rh1268008-23.patch @@ -0,0 +1,1235 @@ +From 67611d45bb5e464f2e80782ec37ce3548459cf57 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 12:56:03 +0200 +Subject: [PATCH 23/30] S390: Optimize strspn and wcsspn. + +upstream-commit-id: f1ffad98be7ec4111fbd1cd1f58f3e3343257519 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00095.html + +This patch provides optimized versions of strspn and wcsspn with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strspn-c.c: New File. + * sysdeps/s390/multiarch/strspn-vx.S: Likewise. + * sysdeps/s390/multiarch/strspn.c: Likewise. + * sysdeps/s390/multiarch/wcsspn-c.c: Likewise. + * sysdeps/s390/multiarch/wcsspn-vx.S: Likewise. + * sysdeps/s390/multiarch/wcsspn.c: Likewise. + * wcsmbs/wcsspn.c: Use WCSSPN if defined. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strspn and + wcsspn functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strspn, wcsspn. + * string/test-strspn.c: Add wcsspn support. + * wcsmbs/test-wcsspn.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcsspn. + * benchtests/bench-strspn.c: Add wcsspn support. + * benchtests/bench-wcsspn.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcsspn. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strspn.c | 71 +++++--- + benchtests/bench-wcsspn.c | 20 +++ + string/strspn.c | 7 +- + string/test-strspn.c | 100 +++++++----- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strspn-c.c | 28 ++++ + sysdeps/s390/multiarch/strspn-vx.S | 256 +++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strspn.c | 27 ++++ + sysdeps/s390/multiarch/wcsspn-c.c | 31 ++++ + sysdeps/s390/multiarch/wcsspn-vx.S | 270 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcsspn.c | 27 ++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcsspn-ifunc.c | 20 +++ + wcsmbs/test-wcsspn.c | 20 +++ + wcsmbs/wcsspn.c | 3 + + 17 files changed, 827 insertions(+), 66 deletions(-) + create mode 100644 benchtests/bench-wcsspn.c + create mode 100644 sysdeps/s390/multiarch/strspn-c.c + create mode 100644 sysdeps/s390/multiarch/strspn-vx.S + create mode 100644 sysdeps/s390/multiarch/strspn.c + create mode 100644 sysdeps/s390/multiarch/wcsspn-c.c + create mode 100644 sysdeps/s390/multiarch/wcsspn-vx.S + create mode 100644 sysdeps/s390/multiarch/wcsspn.c + create mode 100644 wcsmbs/test-wcsspn-ifunc.c + create mode 100644 wcsmbs/test-wcsspn.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 6444394..337b2a1 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp wcschr wcschrnul wcsrchr ++ wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strspn.c b/benchtests/bench-strspn.c +index 634bca1..e1f2272 100644 +--- a/benchtests/bench-strspn.c ++++ b/benchtests/bench-strspn.c +@@ -17,22 +17,47 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strspn" ++#ifndef WIDE ++# define TEST_NAME "strspn" ++#else ++# define TEST_NAME "wcsspn" ++#endif /* WIDE */ + #include "bench-string.h" + +-typedef size_t (*proto_t) (const char *, const char *); +-size_t simple_strspn (const char *, const char *); +-size_t stupid_strspn (const char *, const char *); +- +-IMPL (stupid_strspn, 0) +-IMPL (simple_strspn, 0) +-IMPL (strspn, 1) ++#ifndef WIDE ++# define STRSPN strspn ++# define CHAR char ++# define SIMPLE_STRSPN simple_strspn ++# define STUPID_STRSPN stupid_strspn ++# define STRLEN strlen ++# define STRCHR strchr ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define STRSPN wcsspn ++# define CHAR wchar_t ++# define SIMPLE_STRSPN simple_wcsspn ++# define STUPID_STRSPN stupid_wcsspn ++# define STRLEN wcslen ++# define STRCHR wcschr ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ ++typedef size_t (*proto_t) (const CHAR *, const CHAR *); ++size_t SIMPLE_STRSPN (const CHAR *, const CHAR *); ++size_t STUPID_STRSPN (const CHAR *, const CHAR *); ++ ++IMPL (STUPID_STRSPN, 0) ++IMPL (SIMPLE_STRSPN, 0) ++IMPL (STRSPN, 1) + + size_t +-simple_strspn (const char *s, const char *acc) ++SIMPLE_STRSPN (const CHAR *s, const CHAR *acc) + { +- const char *r, *str = s; +- char c; ++ const CHAR *r, *str = s; ++ CHAR c; + + while ((c = *s++) != '\0') + { +@@ -46,9 +71,9 @@ simple_strspn (const char *s, const char *acc) + } + + size_t +-stupid_strspn (const char *s, const char *acc) ++STUPID_STRSPN (const CHAR *s, const CHAR *acc) + { +- size_t ns = strlen (s), nacc = strlen (acc); ++ size_t ns = STRLEN (s), nacc = STRLEN (acc); + size_t i, j; + + for (i = 0; i < ns; ++i) +@@ -63,7 +88,7 @@ stupid_strspn (const char *s, const char *acc) + } + + static void +-do_one_test (impl_t *impl, const char *s, const char *acc, size_t exp_res) ++do_one_test (impl_t *impl, const CHAR *s, const CHAR *acc, size_t exp_res) + { + size_t res = CALL (impl, s, acc), i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; +@@ -92,34 +117,34 @@ static void + do_test (size_t align, size_t pos, size_t len) + { + size_t i; +- char *acc, *s; ++ CHAR *acc, *s; + + align &= 7; +- if (align + pos + 10 >= page_size || len > 240 || ! len) ++ if ((align + pos + 10) * sizeof (CHAR) >= page_size || len > 240 || ! len) + return; + +- acc = (char *) (buf2 + (random () & 255)); +- s = (char *) (buf1 + align); ++ acc = (CHAR *) (buf2) + (random () & BIG_CHAR); ++ s = (CHAR *) (buf1) + align; + + for (i = 0; i < len; ++i) + { +- acc[i] = random () & 255; ++ acc[i] = random () & BIG_CHAR; + if (!acc[i]) +- acc[i] = random () & 255; ++ acc[i] = random () & BIG_CHAR; + if (!acc[i]) +- acc[i] = 1 + (random () & 127); ++ acc[i] = 1 + (random () & SMALL_CHAR); + } + acc[len] = '\0'; + + for (i = 0; i < pos; ++i) + s[i] = acc[random () % len]; +- s[pos] = random () & 255; ++ s[pos] = random () & BIG_CHAR; + if (strchr (acc, s[pos])) + s[pos] = '\0'; + else + { + for (i = pos + 1; i < pos + 10; ++i) +- s[i] = random () & 255; ++ s[i] = random () & BIG_CHAR; + s[i] = '\0'; + } + +diff --git a/benchtests/bench-wcsspn.c b/benchtests/bench-wcsspn.c +new file mode 100644 +index 0000000..7bdef50 +--- /dev/null ++++ b/benchtests/bench-wcsspn.c +@@ -0,0 +1,20 @@ ++/* Measure wcsspn functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strspn.c" +diff --git a/string/strspn.c b/string/strspn.c +index 48624aa..f0ac9db 100644 +--- a/string/strspn.c ++++ b/string/strspn.c +@@ -18,13 +18,14 @@ + #include + + #undef strspn ++#ifndef STRSPN ++#define STRSPN strspn ++#endif + + /* Return the length of the maximum initial segment + of S which contains only characters in ACCEPT. */ + size_t +-strspn (s, accept) +- const char *s; +- const char *accept; ++STRSPN (const char *s, const char *accept) + { + const char *p; + const char *a; +diff --git a/string/test-strspn.c b/string/test-strspn.c +index 0d6cd19..306958e 100644 +--- a/string/test-strspn.c ++++ b/string/test-strspn.c +@@ -18,22 +18,49 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "strspn" ++#ifndef WIDE ++# define TEST_NAME "strspn" ++#else ++# define TEST_NAME "wcsspn" ++#endif /* WIDE */ + #include "test-string.h" + +-typedef size_t (*proto_t) (const char *, const char *); +-size_t simple_strspn (const char *, const char *); +-size_t stupid_strspn (const char *, const char *); +- +-IMPL (stupid_strspn, 0) +-IMPL (simple_strspn, 0) +-IMPL (strspn, 1) ++#ifndef WIDE ++# define STRSPN strspn ++# define CHAR char ++# define UCHAR unsigned char ++# define SIMPLE_STRSPN simple_strspn ++# define STUPID_STRSPN stupid_strspn ++# define STRLEN strlen ++# define STRCHR strchr ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define STRSPN wcsspn ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define SIMPLE_STRSPN simple_wcsspn ++# define STUPID_STRSPN stupid_wcsspn ++# define STRLEN wcslen ++# define STRCHR wcschr ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ ++typedef size_t (*proto_t) (const CHAR *, const CHAR *); ++size_t SIMPLE_STRSPN (const CHAR *, const CHAR *); ++size_t STUPID_STRSPN (const CHAR *, const CHAR *); ++ ++IMPL (STUPID_STRSPN, 0) ++IMPL (SIMPLE_STRSPN, 0) ++IMPL (STRSPN, 1) + + size_t +-simple_strspn (const char *s, const char *acc) ++SIMPLE_STRSPN (const CHAR *s, const CHAR *acc) + { +- const char *r, *str = s; +- char c; ++ const CHAR *r, *str = s; ++ CHAR c; + + while ((c = *s++) != '\0') + { +@@ -47,9 +74,9 @@ simple_strspn (const char *s, const char *acc) + } + + size_t +-stupid_strspn (const char *s, const char *acc) ++STUPID_STRSPN (const CHAR *s, const CHAR *acc) + { +- size_t ns = strlen (s), nacc = strlen (acc); ++ size_t ns = STRLEN (s), nacc = STRLEN (acc); + size_t i, j; + + for (i = 0; i < ns; ++i) +@@ -64,7 +91,7 @@ stupid_strspn (const char *s, const char *acc) + } + + static void +-do_one_test (impl_t *impl, const char *s, const char *acc, size_t exp_res) ++do_one_test (impl_t *impl, const CHAR *s, const CHAR *acc, size_t exp_res) + { + size_t res = CALL (impl, s, acc); + if (res != exp_res) +@@ -80,34 +107,34 @@ static void + do_test (size_t align, size_t pos, size_t len) + { + size_t i; +- char *acc, *s; ++ CHAR *acc, *s; + + align &= 7; +- if (align + pos + 10 >= page_size || len > 240 || ! len) ++ if ((align + pos + 10) * sizeof (CHAR) >= page_size || len > 240 || ! len) + return; + +- acc = (char *) (buf2 + (random () & 255)); +- s = (char *) (buf1 + align); ++ acc = (CHAR *) (buf2) + (random () & 255); ++ s = (CHAR *) (buf1) + align; + + for (i = 0; i < len; ++i) + { +- acc[i] = random () & 255; ++ acc[i] = random () & BIG_CHAR; + if (!acc[i]) +- acc[i] = random () & 255; ++ acc[i] = random () & BIG_CHAR; + if (!acc[i]) +- acc[i] = 1 + (random () & 127); ++ acc[i] = 1 + (random () & SMALL_CHAR); + } + acc[len] = '\0'; + + for (i = 0; i < pos; ++i) + s[i] = acc[random () % len]; +- s[pos] = random () & 255; +- if (strchr (acc, s[pos])) ++ s[pos] = random () & BIG_CHAR; ++ if (STRCHR (acc, s[pos])) + s[pos] = '\0'; + else + { + for (i = pos + 1; i < pos + 10; ++i) +- s[i] = random () & 255; ++ s[i] = random () & BIG_CHAR; + s[i] = '\0'; + } + +@@ -119,8 +146,8 @@ static void + do_random_tests (void) + { + size_t i, j, n, align, pos, alen, len; +- unsigned char *p = buf1 + page_size - 512; +- unsigned char *acc; ++ UCHAR *p = (UCHAR *) (buf1 + page_size) - 512; ++ UCHAR *acc; + + for (n = 0; n < ITERATIONS; n++) + { +@@ -138,14 +165,14 @@ do_random_tests (void) + len = random () & 511; + if (len + align >= 512) + len = 511 - align - (random () & 7); +- acc = buf2 + page_size - alen - 1 - (random () & 7); ++ acc = (UCHAR *) (buf2 + page_size) - alen - 1 - (random () & 7); + for (i = 0; i < alen; ++i) + { +- acc[i] = random () & 255; ++ acc[i] = random () & BIG_CHAR; + if (!acc[i]) +- acc[i] = random () & 255; ++ acc[i] = random () & BIG_CHAR; + if (!acc[i]) +- acc[i] = 1 + (random () & 127); ++ acc[i] = 1 + (random () & SMALL_CHAR); + } + acc[i] = '\0'; + j = (pos > len ? pos : len) + align + 64; +@@ -158,26 +185,27 @@ do_random_tests (void) + p[i] = '\0'; + else if (i == pos + align) + { +- p[i] = random () & 255; +- if (strchr ((char *) acc, p[i])) ++ p[i] = random () & BIG_CHAR; ++ if (STRCHR ((CHAR *) acc, p[i])) + p[i] = '\0'; + } + else if (i < align || i > pos + align) +- p[i] = random () & 255; ++ p[i] = random () & BIG_CHAR; + else + p[i] = acc [random () % alen]; + } + + FOR_EACH_IMPL (impl, 1) +- if (CALL (impl, (char *) (p + align), +- (char *) acc) != (pos < len ? pos : len)) ++ if (CALL (impl, (CHAR *) (p + align), ++ (CHAR *) acc) != (pos < len ? pos : len)) + { + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %p, %zd, %zd, %zd) %zd != %zd", + n, impl->name, align, acc, alen, pos, len, +- CALL (impl, (char *) (p + align), (char *) acc), ++ CALL (impl, (CHAR *) (p + align), (CHAR *) acc), + (pos < len ? pos : len)); + ret = 1; + } ++ + } + } + +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index b8b141e..9403169 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -11,7 +11,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strncmp strncmp-vx strncmp-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ +- strrchr strrchr-vx strrchr-c ++ strrchr strrchr-vx strrchr-c \ ++ strspn strspn-vx strspn-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -27,5 +28,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsncmp wcsncmp-vx wcsncmp-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ +- wcsrchr wcsrchr-vx wcsrchr-c ++ wcsrchr wcsrchr-vx wcsrchr-c \ ++ wcsspn wcsspn-vx wcsspn-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index ee84d80..cbedf64 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -118,6 +118,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strrchr); + IFUNC_VX_IMPL (wcsrchr); + ++ IFUNC_VX_IMPL (strspn); ++ IFUNC_VX_IMPL (wcsspn); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strspn-c.c b/sysdeps/s390/multiarch/strspn-c.c +new file mode 100644 +index 0000000..8a7d342 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strspn-c.c +@@ -0,0 +1,28 @@ ++/* Default strspn implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRSPN __strspn_c ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strspn_c, __GI_strspn, __strspn_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strspn-vx.S b/sysdeps/s390/multiarch/strspn-vx.S +new file mode 100644 +index 0000000..df22347 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strspn-vx.S +@@ -0,0 +1,256 @@ ++/* Vector optimized 32/64 bit S/390 version of strspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t strspn (const char *s, const char * accept) ++ The strspn() function calculates the length of the initial segment ++ of s which consists entirely of characters in accept. ++ ++ This method checks the length of accept string. If it fits entirely ++ in one vector register, a fast algorithm is used, which does not need ++ to check multiple parts of accept-string. Otherwise a slower full ++ check of accept-string is used. ++ ++ register overview: ++ r3: pointer to start of accept-string ++ r2: pointer to start of search-string ++ r4: loaded byte count of vl search-string ++ r0: found byte index ++ r1: current return len of s ++ v16: search-string ++ v17: accept-string ++ v18: temp-vreg ++ ++ ONLY FOR SLOW: ++ v19: first accept-string ++ v20: zero for preparing acc-vector ++ v21: global mask; 1 indicates a match between ++ search-string-vreg and any accept-character ++ v22: current mask; 1 indicates a match between ++ search-string-vreg and any accept-character in current acc-vreg ++ v30, v31: for re-/storing registers r6, r8, r9 ++ r5: current len of accept-string ++ r6: zero-index in search-string or 16 if no zero ++ or min(zero-index, loaded byte count) ++ r8: >0, if former accept-string-part contains a zero, ++ otherwise =0; ++ r9: loaded byte count of vlbb accept-string ++*/ ++ENTRY(__strspn_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ /* ++ Check if accept-string fits in one vreg: ++ ---------------------------------------- ++ */ ++ vlbb %v17,0(%r3),6 /* Load accept. */ ++ lcbb %r4,0(%r3),6 ++ jo .Lcheck_onbb /* Special case if accept lays ++ on block-boundary. */ ++.Lcheck_notonbb: ++ vistrbs %v17,%v17 /* Fill with zeros after first zero. */ ++ je .Lfast /* Zero found -> accept fits in one vreg. */ ++ j .Lslow /* No zero -> accept exceeds one vreg. */ ++ ++.Lcheck_onbb: ++ /* Accept lays on block-boundary. */ ++ vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ ++ vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */ ++ clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count -> ++ Accept fits in one vreg; ++ Fill with zeros and proceed ++ with FAST. */ ++ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ ++ j .Lcheck_notonbb /* Check if accept fits in one vreg. */ ++ ++ ++ /* ++ Search s for accept in one vreg ++ ------------------------------- ++ */ ++.Lfast: ++ /* Complete accept-string is in v17 and remaining bytes are zero. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfaezbs %v16,%v16,%v17,8 /* Find first element in v16 ++ unequal to any in v17 ++ or first zero element. */ ++ vlgvb %r0,%v16,7 /* Load byte index of found element. */ ++ /* If found index is within loaded bytes (%r0 < %r1), ++ return with found element index (=equal count). */ ++ clr %r0,%r1 ++ locgrl %r2,%r0 ++ blr %r14 ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r1,16 /* current_len = 16. */ ++ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++.Lfast_loop: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ vfaezbs %v16,%v16,%v17,8 /* Find first element in v16 ++ unequal to any in v17 ++ or first zero element. */ ++ jno .Lfast_loop_found ++ vl %v16,16(%r1,%r2) ++ vfaezbs %v16,%v16,%v17,8 ++ jno .Lfast_loop_found16 ++ vl %v16,32(%r1,%r2) ++ vfaezbs %v16,%v16,%v17,8 ++ jno .Lfast_loop_found32 ++ vl %v16,48(%r1,%r2) ++ vfaezbs %v16,%v16,%v17,8 ++ jno .Lfast_loop_found48 ++ ++ aghi %r1,64 ++ j .Lfast_loop /* Loop if no element was unequal to accept ++ and not zero. */ ++ ++ /* Found unequal or zero element. */ ++.Lfast_loop_found48: ++ aghi %r1,16 ++.Lfast_loop_found32: ++ aghi %r1,16 ++.Lfast_loop_found16: ++ aghi %r1,16 ++.Lfast_loop_found: ++ vlgvb %r0,%v16,7 /* Load byte index of found element. */ ++ algrk %r2,%r1,%r0 /* And add it to current len. */ ++ br %r14 ++ ++ ++ /* ++ Search s for accept in multiple vregs ++ ------------------------------------- ++ */ ++.Lslow: ++ /* Save registers. */ ++ vlvgg %v30,%r6,0 ++ vlvgp %v31,%r8,%r9 ++ lghi %r1,0 /* current_len = 0. */ ++ ++ /* Accept in v17 without zero. */ ++ vlr %v19,%v17 /* Save first acc-part for a fast reload. */ ++ vzero %v20 /* Zero for preparing acc-vector. */ ++ ++ /* Align s to 16 byte. */ ++ risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and ++ %r0 = bits 60-63 'and' 15 */ ++ je .Lslow_loop_str /* If s is aligned, loop aligned */ ++ lghi %r4,15 ++ slr %r4,%r0 /* Compute highest index to load (15-x). */ ++ vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs ++ highest index, left bytes are 0). */ ++ ahi %r4,1 /* Work with loaded byte count. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept-string to zero. */ ++ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 ++ if there is no zero. */ ++ clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */ ++ locrl %r6,%r4 /* Load on cc==1. */ ++ j .Lslow_loop_acc ++ ++ /* Process s in 16byte aligned loop. */ ++.Lslow_next_str: ++ vlr %v17,%v19 /* Load first part of accept (no zero). */ ++ algfr %r1,%r4 /* Add loaded byte count to current len. */ ++.Lslow_loop_str: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ lghi %r4,16 /* Loaded byte count is 16. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept-string to zero. */ ++ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ ++.Lslow_loop_acc: ++ vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> ++ character matches any accepted character in ++ this accept-string-part) IN=0, RT=1. */ ++ vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */ ++ vfenezb %v18,%v21,%v21 /* Find first zero in global-mask. */ ++ vlgvb %r0,%v18,7 /* Get first found zero-index ++ (= first mismatch). */ ++ clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index) ++ -> Process this string-part ++ with next acc-part. */ ++ clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count ++ -> All loaded bytes are matching ++ any accept-character ++ and are not zero. */ ++ /* All bytes are matching any characters in accept-string ++ and search-string is fully processed (found-index == zero-index) */ ++.Lslow_add_lbc_end: ++ algrk %r2,%r1,%r0 /* Add matching characters to current_len. */ ++ /* Restore registers. */ ++ vlgvg %r6,%v30,0 ++ vlgvg %r8,%v31,0 ++ vlgvg %r9,%v31,1 ++ br %r14 ++ ++ ++ ++.Lslow_next_acc: ++ clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part ++ -> Add found index to current len ++ and end. */ ++ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ ++ aghi %r5,16 /* Add current_len of accept-string. */ ++ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ ++ jo .Lslow_next_acc_onbb /* Jump away if accept-string is ++ on block-boundary. */ ++.Lslow_next_acc_notonbb: ++ vistrbs %v17,%v17 /* Fill with zeros after first zero. */ ++ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ ++ ++.Lslow_next_acc_prepare_zero: ++ /* Zero in accept-part: fill zeros with first-accept-character. */ ++ vlgvb %r8,%v17,0 /* Load first element of acc-part. */ ++ clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character ++ in this part of accept-string. */ ++ /* r8>0 -> zero found in this acc-part. */ ++ vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ ++ vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars ++ by comparing with 0 (v20). */ ++ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ ++ j .Lslow_loop_acc /* Accept part is prepared -> process. */ ++ ++.Lslow_next_acc_onbb: ++ vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ ++ vlgvb %r8,%v18,7 /* Load byte index of zero. */ ++ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes ++ -> Prepare vr. */ ++ vl %v17,0(%r5,%r3) /* Load over boundary ... */ ++ lghi %r8,0 /* r8=0 -> no zero in this part of acc, ++ Check for zero is in jump-target. */ ++ j .Lslow_next_acc_notonbb /* ... and search for zero in ++ fully loaded vreg again. */ ++END(__strspn_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c +new file mode 100644 +index 0000000..48dd77b +--- /dev/null ++++ b/sysdeps/s390/multiarch/strspn.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of strspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strspn, strspn) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcsspn-c.c b/sysdeps/s390/multiarch/wcsspn-c.c +new file mode 100644 +index 0000000..93af16c +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsspn-c.c +@@ -0,0 +1,31 @@ ++/* Default wcsspn implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSSPN __wcsspn_c ++ ++# include ++extern __typeof (wcsspn) __wcsspn_c; ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcsspn_c, __GI_wcsspn, __wcsspn_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsspn-vx.S b/sysdeps/s390/multiarch/wcsspn-vx.S +new file mode 100644 +index 0000000..4ed8e84 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsspn-vx.S +@@ -0,0 +1,270 @@ ++/* Vector optimized 32/64 bit S/390 version of wcsspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t wcsspn (const wchar_t *s, const wchar_t * accept) ++ The wcsspn() function calculates the length of the initial segment ++ of s which consists entirely of characters in accept. ++ ++ This method checks the length of accept string. If it fits entirely ++ in one vector register, a fast algorithm is used, which does not need ++ to check multiple parts of accept-string. Otherwise a slower full ++ check of accept-string is used. ++ ++ register overview: ++ r3: pointer to start of accept-string ++ r2: pointer to start of search-string ++ r4: loaded byte count of vl search-string ++ r0: found byte index ++ r1: current return len of s ++ v16: search-string ++ v17: accept-string ++ v18: temp-vreg ++ ++ ONLY FOR SLOW: ++ v19: first accept-string ++ v20: zero for preparing acc-vector ++ v21: global mask; 1 indicates a match between ++ search-string-vreg and any accept-character ++ v22: current mask; 1 indicates a match between ++ search-string-vreg and any accept-character in current acc-vreg ++ v30, v31: for re-/storing registers r6, r8, r9 ++ r5: current len of accept-string ++ r6: zero-index in search-string or 16 if no zero ++ or min(zero-index, loaded byte count) ++ r8: >0, if former accept-string-part contains a zero, ++ otherwise =0; ++ r9: loaded byte count of vlbb accept-string ++*/ ++ENTRY(__wcsspn_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ /* ++ Check if accept-string fits in one vreg: ++ ---------------------------------------- ++ */ ++ vlbb %v17,0(%r3),6 /* Load accept. */ ++ lcbb %r4,0(%r3),6 ++ jo .Lcheck_onbb /* Special case if accept lays ++ on block-boundary. */ ++.Lcheck_notonbb: ++ vistrfs %v17,%v17 /* Fill with zeros after first zero. */ ++ je .Lfast /* Zero found -> accept fits in one vreg. */ ++ j .Lslow /* No zero -> accept exceeds one vreg. */ ++ ++.Lcheck_onbb: ++ /* Accept lays on block-boundary. */ ++ nill %r4,65532 /* Recognize only fully loaded characters. */ ++ je .Lcheck_onbb2 /* Reload vr if no full wchar_t. */ ++ vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ ++ vlgvb %r0,%v18,7 /* Get index of zero or 16 if not found. */ ++ clrjl %r0,%r4,.Lcheck_notonbb /* Zero index < loaded bytes count -> ++ Accept fits in one vreg; ++ Fill with zeros and proceed ++ with FAST. */ ++.Lcheck_onbb2: ++ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ ++ j .Lcheck_notonbb /* Check if accept fits in one vreg. */ ++ ++ ++ /* ++ Search s for accept in one vreg ++ ------------------------------- ++ */ ++.Lfast: ++ /* Complete accept-string in v17 and remaining bytes are zero. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfaezfs %v16,%v16,%v17,8 /* Find first element in v16 ++ unequal to any in v17 ++ or first zero element. */ ++ ++ vlgvb %r0,%v16,7 /* Load byte index of found element. */ ++ /* If found index is within loaded bytes (%r0 < %r1), ++ return with found element index (=equal count). */ ++ clr %r0,%r1 ++ srlg %r0,%r0,2 /* Convert byte-count to character-count. */ ++ locgrl %r2,%r0 ++ blr %r14 ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r1,16 /* current_len = 16. */ ++ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++.Lfast_loop: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ vfaezfs %v16,%v16,%v17,8 /* Find first element in v16 ++ unequal to any in v17 ++ or first zero element. */ ++ jno .Lfast_loop_found ++ vl %v16,16(%r1,%r2) ++ vfaezfs %v16,%v16,%v17,8 ++ jno .Lfast_loop_found16 ++ vl %v16,32(%r1,%r2) ++ vfaezfs %v16,%v16,%v17,8 ++ jno .Lfast_loop_found32 ++ vl %v16,48(%r1,%r2) ++ vfaezfs %v16,%v16,%v17,8 ++ jno .Lfast_loop_found48 ++ ++ aghi %r1,64 ++ j .Lfast_loop /* Loop if no element was unequal to accept ++ and not zero. */ ++ ++ /* Found unequal or zero element. */ ++.Lfast_loop_found48: ++ aghi %r1,16 ++.Lfast_loop_found32: ++ aghi %r1,16 ++.Lfast_loop_found16: ++ aghi %r1,16 ++.Lfast_loop_found: ++ vlgvb %r0,%v16,7 /* Load byte index of found element. */ ++ algrk %r2,%r1,%r0 /* And add it to current len. */ ++ srlg %r2,%r2,2 /* Convert byte-count to character-count. */ ++ br %r14 ++ ++ ++ /* ++ Search s for accept in multiple vregs ++ ------------------------------------- ++ */ ++.Lslow: ++ /* Save registers. */ ++ vlvgg %v30,%r6,0 ++ vlvgp %v31,%r8,%r9 ++ lghi %r1,0 /* Zero out current len. */ ++ ++ /* accept in v17 without zero. */ ++ vlr %v19,%v17 /* Save first acc-part for a fast reload. */ ++ vzero %v20 /* Zero for preparing acc-vector. */ ++ ++ /* Align s to 16 byte. */ ++ risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and ++ %r0 = bits 60-63 'and' 15. */ ++ je .Lslow_loop_str /* If s is aligned, loop aligned */ ++ lghi %r4,15 ++ slr %r4,%r0 /* Compute highest index to load (15-x). */ ++ vll %v16,%r4,0(%r2) /* Load up to 16byte boundary (vll needs ++ highest index, remaining bytes are 0). */ ++ aghi %r4,1 /* Work with loaded byte count. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept-string to zero. */ ++ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 ++ if there is no zero. */ ++ clr %r4,%r6 /* cc==1 if loaded byte count < zero-index. */ ++ locrl %r6,%r4 /* Load on cc==1. */ ++ j .Lslow_loop_acc ++ ++ /* Process s in 16byte aligned loop. */ ++.Lslow_next_str: ++ vlr %v17,%v19 /* Load first part of accept (no zero). */ ++ algfr %r1,%r4 /* Add loaded byte count to current len. */ ++.Lslow_loop_str: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ lghi %r4,16 /* Loaded byte count is 16. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept-string to zero. */ ++ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ ++.Lslow_loop_acc: ++ vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> ++ character matches any accepted character in ++ this accept-string-part) IN=0, RT=1. */ ++ vo %v21,%v21,%v22 /* global-mask = global- | matching-mask. */ ++ vfenezf %v18,%v21,%v21 /* Find first zero in global-mask. */ ++ vlgvb %r0,%v18,7 /* Get first found zero-index ++ (= first mismatch). */ ++ clrjl %r0,%r6,.Lslow_next_acc /* Mismatch-index < min(lbc,zero-index) ++ -> Process this string-part ++ with next acc-part. */ ++ clrjhe %r0,%r4,.Lslow_next_str /* Found-index >= loaded byte count ++ -> All loaded bytes are matching ++ any accept-character ++ and are not zero. */ ++ /* All bytes are matching any characters in accept-string ++ and search-string is fully processed (found-index == zero-index). */ ++.Lslow_add_lbc_end: ++ algrk %r2,%r1,%r0 /* Add matching characters to current len. */ ++ srlg %r2,%r2,2 /* Convert byte-count to character-count. */ ++ /* Restore registers. */ ++ vlgvg %r6,%v30,0 ++ vlgvg %r8,%v31,0 ++ vlgvg %r9,%v31,1 ++ br %r14 ++ ++.Lslow_next_acc: ++ clijh %r8,0,.Lslow_add_lbc_end /* There was a zero in last acc-part ++ -> Add found index to current len ++ and end. */ ++ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ ++ aghi %r5,16 /* Increment current len of accept-string. */ ++ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ ++ jo .Lslow_next_acc_onbb /* Jump away if accept-string is ++ on block-boundary. */ ++.Lslow_next_acc_notonbb: ++ vistrfs %v17,%v17 /* Fill with zeros after first zero. */ ++ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ ++ ++.Lslow_next_acc_prepare_zero: ++ /* Zero in accept-part: fill zeros with first-accept-character. */ ++ vlgvf %r8,%v17,0 /* Load first element of acc-part. */ ++ clije %r8,0,.Lslow_add_lbc_end /* End if zero is first character ++ in this part of accept-string. */ ++ /* r8>0 -> zero found in this acc-part. */ ++ vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ ++ vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars ++ by comparing with 0 (v20). */ ++ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ ++ j .Lslow_loop_acc /* Accept part is prepared -> process. */ ++ ++.Lslow_next_acc_onbb: ++ nill %r9,65532 /* Recognize only fully loaded characters. */ ++ je .Lslow_next_acc_onbb2 /* Reload vr, if we loaded no full ++ wchar_t. */ ++ vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ ++ vlgvb %r8,%v18,7 /* Load byte index of zero. */ ++ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes ++ -> Prepare vreg. */ ++.Lslow_next_acc_onbb2: ++ vl %v17,0(%r5,%r3) /* Load over boundary ... */ ++ lghi %r8,0 /* r8=0 -> no zero in this part of acc, ++ check for zero is in jump-target. */ ++ j .Lslow_next_acc_notonbb /* ... and search for zero in ++ fully loaded vreg again. */ ++.Lfallback: ++ jg __wcsspn_c ++END(__wcsspn_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c +new file mode 100644 +index 0000000..3b3041c +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcsspn.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcsspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcsspn, wcsspn) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index de3635d..843a23c 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul ++ wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcsspn-ifunc.c b/wcsmbs/test-wcsspn-ifunc.c +new file mode 100644 +index 0000000..73f288f +--- /dev/null ++++ b/wcsmbs/test-wcsspn-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcsspn function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcsspn.c" +diff --git a/wcsmbs/test-wcsspn.c b/wcsmbs/test-wcsspn.c +new file mode 100644 +index 0000000..171043c +--- /dev/null ++++ b/wcsmbs/test-wcsspn.c +@@ -0,0 +1,20 @@ ++/* Test wcsspn functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strspn.c" +diff --git a/wcsmbs/wcsspn.c b/wcsmbs/wcsspn.c +index dad72b4..3e84726 100644 +--- a/wcsmbs/wcsspn.c ++++ b/wcsmbs/wcsspn.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WCSSPN ++# define wcsspn WCSSPN ++#endif + + /* Return the length of the maximum initial segment + of WCS which contains only wide-characters in ACCEPT. */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-24.patch b/SOURCES/glibc-rh1268008-24.patch new file mode 100644 index 00000000..09998458 --- /dev/null +++ b/SOURCES/glibc-rh1268008-24.patch @@ -0,0 +1,1402 @@ +From 685417419834a85cd5d59787c25e487cd7129890 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 12:58:39 +0200 +Subject: [PATCH 24/30] S390: Optimize strpbrk and wcspbrk. + +upstream-commit-id: f0ba659847446eec3b2477d60c97c77ef4680e81 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00091.html + +This patch provides optimized versions of strpbrk and wcspbrk with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strpbrk-c.c: New File. + * sysdeps/s390/multiarch/strpbrk-vx.S: Likewise. + * sysdeps/s390/multiarch/strpbrk.c: Likewise. + * sysdeps/s390/multiarch/wcspbrk-c.c: Likewise. + * sysdeps/s390/multiarch/wcspbrk-vx.S: Likewise. + * sysdeps/s390/multiarch/wcspbrk.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strpbrk and + wcspbrk functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strpbrk, wcspbrk. + * wcsmbs/wcspbrk.c: Use WCSPBRK if defined. + * string/test-strpbrk.c: Add wcspbrk support. + * wcsmbs/test-wcspbrk.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcspbrk. + * benchtests/bench-strpbrk.c: Add wcspbrk support. + * benchtests/bench-wcspbrk.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcspbrk. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strpbrk.c | 100 ++++++---- + benchtests/bench-wcspbrk.c | 20 ++ + string/strpbrk.c | 8 +- + string/test-strpbrk.c | 130 ++++++++----- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strpbrk-c.c | 28 +++ + sysdeps/s390/multiarch/strpbrk-vx.S | 302 +++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strpbrk.c | 27 +++ + sysdeps/s390/multiarch/wcspbrk-c.c | 31 +++ + sysdeps/s390/multiarch/wcspbrk-vx.S | 315 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcspbrk.c | 27 +++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wcspbrk-ifunc.c | 20 ++ + wcsmbs/test-wcspbrk.c | 20 ++ + wcsmbs/wcspbrk.c | 3 + + 17 files changed, 953 insertions(+), 91 deletions(-) + create mode 100644 benchtests/bench-wcspbrk.c + create mode 100644 sysdeps/s390/multiarch/strpbrk-c.c + create mode 100644 sysdeps/s390/multiarch/strpbrk-vx.S + create mode 100644 sysdeps/s390/multiarch/strpbrk.c + create mode 100644 sysdeps/s390/multiarch/wcspbrk-c.c + create mode 100644 sysdeps/s390/multiarch/wcspbrk-vx.S + create mode 100644 sysdeps/s390/multiarch/wcspbrk.c + create mode 100644 wcsmbs/test-wcspbrk-ifunc.c + create mode 100644 wcsmbs/test-wcspbrk.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 337b2a1..015b5d6 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn ++ wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strpbrk.c b/benchtests/bench-strpbrk.c +index fe966be..f2db902 100644 +--- a/benchtests/bench-strpbrk.c ++++ b/benchtests/bench-strpbrk.c +@@ -16,50 +16,80 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifndef WIDE ++# define CHAR char ++# define STRLEN strlen ++# define STRCHR strchr ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define CHAR wchar_t ++# define STRLEN wcslen ++# define STRCHR wcschr ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ + #ifndef STRPBRK_RESULT + # define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL) +-# define RES_TYPE char * ++# define RES_TYPE CHAR * + # define TEST_MAIN +-# define TEST_NAME "strpbrk" ++# ifndef WIDE ++# define TEST_NAME "strpbrk" ++# else ++# define TEST_NAME "wcspbrk" ++# endif /* WIDE */ + # include "bench-string.h" + +-typedef char *(*proto_t) (const char *, const char *); +-char *simple_strpbrk (const char *, const char *); +-char *stupid_strpbrk (const char *, const char *); +- +-IMPL (stupid_strpbrk, 0) +-IMPL (simple_strpbrk, 0) +-IMPL (strpbrk, 1) +- +-char * +-simple_strpbrk (const char *s, const char *rej) ++# ifndef WIDE ++# define STRPBRK strpbrk ++# define SIMPLE_STRPBRK simple_strpbrk ++# define STUPID_STRPBRK stupid_strpbrk ++# else ++# include ++# define STRPBRK wcspbrk ++# define SIMPLE_STRPBRK simple_wcspbrk ++# define STUPID_STRPBRK stupid_wcspbrk ++# endif /* WIDE */ ++ ++typedef CHAR *(*proto_t) (const CHAR *, const CHAR *); ++CHAR *SIMPLE_STRPBRK (const CHAR *, const CHAR *); ++CHAR *STUPID_STRPBRK (const CHAR *, const CHAR *); ++ ++IMPL (STUPID_STRPBRK, 0) ++IMPL (SIMPLE_STRPBRK, 0) ++IMPL (STRPBRK, 1) ++ ++CHAR * ++SIMPLE_STRPBRK (const CHAR *s, const CHAR *rej) + { +- const char *r; +- char c; ++ const CHAR *r; ++ CHAR c; + + while ((c = *s++) != '\0') + for (r = rej; *r != '\0'; ++r) + if (*r == c) +- return (char *) s - 1; ++ return (CHAR *) s - 1; + return NULL; + } + +-char * +-stupid_strpbrk (const char *s, const char *rej) ++CHAR * ++STUPID_STRPBRK (const CHAR *s, const CHAR *rej) + { +- size_t ns = strlen (s), nrej = strlen (rej); ++ size_t ns = STRLEN (s), nrej = STRLEN (rej); + size_t i, j; + + for (i = 0; i < ns; ++i) + for (j = 0; j < nrej; ++j) + if (s[i] == rej[j]) +- return (char *) s + i; ++ return (CHAR *) s + i; + return NULL; + } +-#endif ++#endif /* !STRPBRK_RESULT */ + + static void +-do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res) ++do_one_test (impl_t *impl, const CHAR *s, const CHAR *rej, RES_TYPE exp_res) + { + RES_TYPE res = CALL (impl, s, rej); + size_t i, iters = INNER_LOOP_ITERS; +@@ -91,35 +121,35 @@ do_test (size_t align, size_t pos, size_t len) + size_t i; + int c; + RES_TYPE result; +- char *rej, *s; ++ CHAR *rej, *s; + + align &= 7; +- if (align + pos + 10 >= page_size || len > 240) ++ if ((align + pos + 10) * sizeof (CHAR) >= page_size || len > 240) + return; + +- rej = (char *) (buf2 + (random () & 255)); +- s = (char *) (buf1 + align); ++ rej = (CHAR *) (buf2) + (random () & BIG_CHAR); ++ s = (CHAR *) (buf1) + align; + + for (i = 0; i < len; ++i) + { +- rej[i] = random () & 255; ++ rej[i] = random () & BIG_CHAR; + if (!rej[i]) +- rej[i] = random () & 255; ++ rej[i] = random () & BIG_CHAR; + if (!rej[i]) +- rej[i] = 1 + (random () & 127); ++ rej[i] = 1 + (random () & SMALL_CHAR); + } + rej[len] = '\0'; +- for (c = 1; c <= 255; ++c) +- if (strchr (rej, c) == NULL) ++ for (c = 1; c <= BIG_CHAR; ++c) ++ if (STRCHR (rej, c) == NULL) + break; + + for (i = 0; i < pos; ++i) + { +- s[i] = random () & 255; +- if (strchr (rej, s[i])) ++ s[i] = random () & BIG_CHAR; ++ if (STRCHR (rej, s[i])) + { +- s[i] = random () & 255; +- if (strchr (rej, s[i])) ++ s[i] = random () & BIG_CHAR; ++ if (STRCHR (rej, s[i])) + s[i] = c; + } + } +@@ -127,7 +157,7 @@ do_test (size_t align, size_t pos, size_t len) + if (s[pos]) + { + for (i = pos + 1; i < pos + 10; ++i) +- s[i] = random () & 255; ++ s[i] = random () & BIG_CHAR; + s[i] = '\0'; + } + result = STRPBRK_RESULT (s, pos); +diff --git a/benchtests/bench-wcspbrk.c b/benchtests/bench-wcspbrk.c +new file mode 100644 +index 0000000..3d9f00f +--- /dev/null ++++ b/benchtests/bench-wcspbrk.c +@@ -0,0 +1,20 @@ ++/* Measure wcspbrk functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strpbrk.c" +diff --git a/string/strpbrk.c b/string/strpbrk.c +index 7f45fdf..c153d8e 100644 +--- a/string/strpbrk.c ++++ b/string/strpbrk.c +@@ -25,11 +25,13 @@ + + #undef strpbrk + ++#ifndef STRPBRK ++# define STRPBRK strpbrk ++#endif ++ + /* Find the first occurrence in S of any character in ACCEPT. */ + char * +-strpbrk (s, accept) +- const char *s; +- const char *accept; ++STRPBRK (const char *s, const char *accept) + { + while (*s != '\0') + { +diff --git a/string/test-strpbrk.c b/string/test-strpbrk.c +index 72eaaa1..c36c5b5 100644 +--- a/string/test-strpbrk.c ++++ b/string/test-strpbrk.c +@@ -17,50 +17,82 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifndef WIDE ++# define CHAR char ++# define UCHAR unsigned char ++# define STRLEN strlen ++# define STRCHR strchr ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define STRLEN wcslen ++# define STRCHR wcschr ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ + #ifndef STRPBRK_RESULT + # define STRPBRK_RESULT(s, pos) ((s)[(pos)] ? (s) + (pos) : NULL) +-# define RES_TYPE char * ++# define RES_TYPE CHAR * + # define TEST_MAIN +-# define TEST_NAME "strpbrk" ++# ifndef WIDE ++# define TEST_NAME "strpbrk" ++# else ++# define TEST_NAME "wcspbrk" ++# endif /* WIDE */ + # include "test-string.h" + +-typedef char *(*proto_t) (const char *, const char *); +-char *simple_strpbrk (const char *, const char *); +-char *stupid_strpbrk (const char *, const char *); ++# ifndef WIDE ++# define STRPBRK strpbrk ++# define SIMPLE_STRPBRK simple_strpbrk ++# define STUPID_STRPBRK stupid_strpbrk ++# else ++# include ++# define STRPBRK wcspbrk ++# define SIMPLE_STRPBRK simple_wcspbrk ++# define STUPID_STRPBRK stupid_wcspbrk ++# endif /* WIDE */ ++ ++typedef CHAR *(*proto_t) (const CHAR *, const CHAR *); ++CHAR *SIMPLE_STRPBRK (const CHAR *, const CHAR *); ++CHAR *STUPID_STRPBRK (const CHAR *, const CHAR *); + +-IMPL (stupid_strpbrk, 0) +-IMPL (simple_strpbrk, 0) +-IMPL (strpbrk, 1) ++IMPL (STUPID_STRPBRK, 0) ++IMPL (SIMPLE_STRPBRK, 0) ++IMPL (STRPBRK, 1) + +-char * +-simple_strpbrk (const char *s, const char *rej) ++CHAR * ++SIMPLE_STRPBRK (const CHAR *s, const CHAR *rej) + { +- const char *r; +- char c; ++ const CHAR *r; ++ CHAR c; + + while ((c = *s++) != '\0') + for (r = rej; *r != '\0'; ++r) + if (*r == c) +- return (char *) s - 1; ++ return (CHAR *) s - 1; + return NULL; + } + +-char * +-stupid_strpbrk (const char *s, const char *rej) ++CHAR * ++STUPID_STRPBRK (const CHAR *s, const CHAR *rej) + { +- size_t ns = strlen (s), nrej = strlen (rej); ++ size_t ns = STRLEN (s), nrej = STRLEN (rej); + size_t i, j; + + for (i = 0; i < ns; ++i) + for (j = 0; j < nrej; ++j) + if (s[i] == rej[j]) +- return (char *) s + i; ++ return (CHAR *) s + i; + return NULL; + } +-#endif ++#endif /* !STRPBRK_RESULT */ + + static void +-do_one_test (impl_t *impl, const char *s, const char *rej, RES_TYPE exp_res) ++do_one_test (impl_t *impl, const CHAR *s, const CHAR *rej, RES_TYPE exp_res) + { + RES_TYPE res = CALL (impl, s, rej); + if (res != exp_res) +@@ -78,35 +110,35 @@ do_test (size_t align, size_t pos, size_t len) + size_t i; + int c; + RES_TYPE result; +- char *rej, *s; ++ CHAR *rej, *s; + + align &= 7; +- if (align + pos + 10 >= page_size || len > 240) ++ if ((align + pos + 10) * sizeof (CHAR) >= page_size || len > 240) + return; + +- rej = (char *) (buf2 + (random () & 255)); +- s = (char *) (buf1 + align); ++ rej = (CHAR *) (buf2) + (random () & 255); ++ s = (CHAR *) (buf1) + align; + + for (i = 0; i < len; ++i) + { +- rej[i] = random () & 255; ++ rej[i] = random () & BIG_CHAR; + if (!rej[i]) +- rej[i] = random () & 255; ++ rej[i] = random () & BIG_CHAR; + if (!rej[i]) +- rej[i] = 1 + (random () & 127); ++ rej[i] = 1 + (random () & SMALL_CHAR); + } + rej[len] = '\0'; +- for (c = 1; c <= 255; ++c) +- if (strchr (rej, c) == NULL) ++ for (c = 1; c <= BIG_CHAR; ++c) ++ if (STRCHR (rej, c) == NULL) + break; + + for (i = 0; i < pos; ++i) + { +- s[i] = random () & 255; +- if (strchr (rej, s[i])) ++ s[i] = random () & BIG_CHAR; ++ if (STRCHR (rej, s[i])) + { +- s[i] = random () & 255; +- if (strchr (rej, s[i])) ++ s[i] = random () & BIG_CHAR; ++ if (STRCHR (rej, s[i])) + s[i] = c; + } + } +@@ -114,7 +146,7 @@ do_test (size_t align, size_t pos, size_t len) + if (s[pos]) + { + for (i = pos + 1; i < pos + 10; ++i) +- s[i] = random () & 255; ++ s[i] = random () & BIG_CHAR; + s[i] = '\0'; + } + result = STRPBRK_RESULT (s, pos); +@@ -129,8 +161,8 @@ do_random_tests (void) + size_t i, j, n, align, pos, len, rlen; + RES_TYPE result; + int c; +- unsigned char *p = buf1 + page_size - 512; +- unsigned char *rej; ++ UCHAR *p = (UCHAR *) (buf1 + page_size) - 512; ++ UCHAR *rej; + + for (n = 0; n < ITERATIONS; n++) + { +@@ -147,18 +179,18 @@ do_random_tests (void) + rlen = random () & 63; + else + rlen = random () & 15; +- rej = buf2 + page_size - rlen - 1 - (random () & 7); ++ rej = (UCHAR *) (buf2 + page_size) - rlen - 1 - (random () & 7); + for (i = 0; i < rlen; ++i) + { +- rej[i] = random () & 255; ++ rej[i] = random () & BIG_CHAR; + if (!rej[i]) +- rej[i] = random () & 255; ++ rej[i] = random () & BIG_CHAR; + if (!rej[i]) +- rej[i] = 1 + (random () & 127); ++ rej[i] = 1 + (random () & SMALL_CHAR); + } + rej[i] = '\0'; +- for (c = 1; c <= 255; ++c) +- if (strchr ((char *) rej, c) == NULL) ++ for (c = 1; c <= BIG_CHAR; ++c) ++ if (STRCHR ((CHAR *) rej, c) == NULL) + break; + j = (pos > len ? pos : len) + align + 64; + if (j > 512) +@@ -171,27 +203,27 @@ do_random_tests (void) + else if (i == pos + align) + p[i] = rej[random () % (rlen + 1)]; + else if (i < align || i > pos + align) +- p[i] = random () & 255; ++ p[i] = random () & BIG_CHAR; + else + { +- p[i] = random () & 255; +- if (strchr ((char *) rej, p[i])) ++ p[i] = random () & BIG_CHAR; ++ if (STRCHR ((CHAR *) rej, p[i])) + { +- p[i] = random () & 255; +- if (strchr ((char *) rej, p[i])) ++ p[i] = random () & BIG_CHAR; ++ if (STRCHR ((CHAR *) rej, p[i])) + p[i] = c; + } + } + } + +- result = STRPBRK_RESULT ((char *) (p + align), pos < len ? pos : len); ++ result = STRPBRK_RESULT ((CHAR *) (p + align), pos < len ? pos : len); + + FOR_EACH_IMPL (impl, 1) +- if (CALL (impl, (char *) (p + align), (char *) rej) != result) ++ if (CALL (impl, (CHAR *) (p + align), (CHAR *) rej) != result) + { + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %p, %zd, %zd, %zd) %p != %p", + n, impl->name, align, rej, rlen, pos, len, +- (void *) CALL (impl, (char *) (p + align), (char *) rej), ++ (void *) CALL (impl, (CHAR *) (p + align), (CHAR *) rej), + (void *) result); + ret = 1; + } +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 9403169..5765a8c 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -12,7 +12,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strchr strchr-vx strchr-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ +- strspn strspn-vx strspn-c ++ strspn strspn-vx strspn-c \ ++ strpbrk strpbrk-vx strpbrk-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -29,5 +30,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcschr wcschr-vx wcschr-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ +- wcsspn wcsspn-vx wcsspn-c ++ wcsspn wcsspn-vx wcsspn-c \ ++ wcspbrk wcspbrk-vx wcspbrk-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index cbedf64..b39a5c5 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -121,6 +121,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strspn); + IFUNC_VX_IMPL (wcsspn); + ++ IFUNC_VX_IMPL (strpbrk); ++ IFUNC_VX_IMPL (wcspbrk); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strpbrk-c.c b/sysdeps/s390/multiarch/strpbrk-c.c +new file mode 100644 +index 0000000..1c8bf49 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strpbrk-c.c +@@ -0,0 +1,28 @@ ++/* Default strpbrk implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRPBRK __strpbrk_c ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strpbrk_c, __GI_strpbrk, __strpbrk_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strpbrk-vx.S b/sysdeps/s390/multiarch/strpbrk-vx.S +new file mode 100644 +index 0000000..c6ad3ef +--- /dev/null ++++ b/sysdeps/s390/multiarch/strpbrk-vx.S +@@ -0,0 +1,302 @@ ++/* Vector optimized 32/64 bit S/390 version of strpbrk. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* char *strpbrk (const char *s, const char * accept) ++ The strpbrk() function locates the first occurrence in the string s ++ of any of the characters in the string accept and returns a pointer ++ to that character or NULL if not found. ++ ++ This method checks the length of accept string. If it fits entirely ++ in one vector register, a fast algorithm is used, which does not need ++ to check multiple parts of accept-string. Otherwise a slower full ++ check of accept-string is used. ++ ++ register overview: ++ r3: pointer to start of accept-string ++ r2: pointer to start of search-string ++ r0: loaded byte count of vlbb search-string (32bit unsigned) ++ r4: found byte index (32bit unsigned) ++ r1: current return len (64bit unsigned) ++ v16: search-string ++ v17: accept-string ++ v18: temp-vreg ++ ++ ONLY FOR SLOW: ++ v19: first accept-string ++ v20: zero for preparing acc-vector ++ v21: global mask; 1 indicates a match between ++ search-string-vreg and any accept-character ++ v22: current mask; 1 indicates a match between ++ search-string-vreg and any accept-character in current acc-vreg ++ v24: one for result-checking of former string-part ++ v30, v31: for re-/storing registers r6, r8, r9 ++ r5: current len of accept-string ++ r6: zero-index in search-string or 16 if no zero ++ or min(zero-index, loaded byte count) ++ r8: >0, if former accept-string-part contains a zero, ++ otherwise =0; ++ r9: loaded byte count of vlbb accept-string ++*/ ++ENTRY(__strpbrk_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ /* ++ Check if accept-string fits in one vreg: ++ ---------------------------------------- ++ */ ++ vlbb %v17,0(%r3),6 /* Load accept. */ ++ lghi %r1,0 /* Zero out current len. */ ++ vlgvb %r0,%v17,0 /* Get first element. */ ++ clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */ ++ lcbb %r0,0(%r3),6 ++ jo .Lcheck_onbb /* Special case if accept lays ++ on block-boundary. */ ++.Lcheck_notonbb: ++ vistrbs %v17,%v17 /* Fill with zeros after first zero. */ ++ je .Lfast /* Zero found -> accept fits in one vreg. */ ++ j .Lslow /* No zero -> accept exceeds one vreg */ ++ ++ ++.Lcheck_onbb: ++ /* Accept lays on block-boundary. */ ++ vfenezb %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ ++ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ ++ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> ++ Accept fits in one vreg; ++ Fill with zeros and proceed ++ with FAST. */ ++ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ ++ j .Lcheck_notonbb /* Check if accept fits in one vreg. */ ++ ++ ++ /* ++ Search s for accept in one vreg ++ ------------------------------- ++ */ ++.Lfast: ++ /* Complete accept-string in v17 and remaining bytes are zero. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any ++ in v17 or first zero element. */ ++ ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++ /* If found index is within loaded bytes, return with found ++ element index (=equal count). */ ++ clrjl %r4,%r0,.Lfast_loop_found2 ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r1,16 /* current_len = 16. */ ++ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lfast_loop: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any ++ in v17 or first zero element. */ ++ jno .Lfast_loop_found ++ ++ vl %v16,16(%r1,%r2) ++ vfaezbs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found16 ++ ++ vl %v16,32(%r1,%r2) ++ vfaezbs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found32 ++ ++ vl %v16,48(%r1,%r2) ++ vfaezbs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found48 ++ ++ aghi %r1,64 ++ j .Lfast_loop /* Loop if no element was unequal to accept ++ and not zero. */ ++ ++ /* Found equal or zero element. */ ++.Lfast_loop_found48: ++ aghi %r1,16 ++.Lfast_loop_found32: ++ aghi %r1,16 ++.Lfast_loop_found16: ++ aghi %r1,16 ++.Lfast_loop_found: ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++.Lfast_loop_found2: ++ vlgvb %r0,%v16,0(%r4) /* Get found element. */ ++ clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */ ++ algfr %r1,%r4 /* Add found index of char to current len. */ ++ la %r2,0(%r1,%r2) /* And return pointer to first equal char. */ ++ br %r14 ++ ++.Lfast_end_null: ++ lghi %r2,0 /* Return null if no character is equal. */ ++ br %r14 ++ ++ ++ ++ ++ /* ++ Search s for accept in multiple vregs ++ ------------------------------------- ++ */ ++.Lslow: ++ /* Save registers. */ ++ vlvgg %v30,%r6,0 ++ vlvgp %v31,%r8,%r9 ++ ++ /* accept in v17 without zero. */ ++ vlr %v19,%v17 /* Save first acc-part for a fast reload. */ ++ vzero %v20 /* Zero for preparing acc-vector. */ ++ vone %v24 /* One for checking result of former string. */ ++ ++ /* Align s to 16 byte. */ ++ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and ++ %r4 = bits 60-63 'and' 15. */ ++ je .Lslow_loop_str /* If s is aligned, loop aligned. */ ++ lghi %r0,15 ++ slr %r0,%r4 /* Compute highest index to load (15-x). */ ++ vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs ++ highest index, remaining bytes are 0). */ ++ ahi %r0,1 /* Work with loaded byte count. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept-string to zero. */ ++ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end_null /* If first element is zero ++ (end of string) -> return null */ ++ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ ++ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ ++ j .Lslow_loop_acc ++ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lslow_next_str: ++ /* Check results of former processed str-part. */ ++ vfeeb %v18,%v21,%v24 /* Find first equal match in global mask ++ (ones in element). */ ++ vlgvb %r4,%v18,7 /* Get index of first one (=equal) ++ or 16 if no match. */ ++ /* Equal-index < min(zero-index, loaded byte count) ++ -> return pointer to equal element. */ ++ clrjl %r4,%r6,.Lslow_index_found ++ /* Zero-index < loaded byte count ++ -> former str-part was last str-part ++ -> return null */ ++ clrjl %r6,%r0,.Lslow_end_null ++ /* All elements are zero (=no match) -> proceed with next str-part. */ ++ ++ vlr %v17,%v19 /* Load first part of accept (no zero). */ ++ algfr %r1,%r0 /* Add loaded byte count to current len. */ ++ ++.Lslow_loop_str: ++ vl %v16,0(%r1,%r2) /* Load search-string */ ++ lghi %r0,16 /* Loaded byte count is 16. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept to zero. */ ++ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end_null /* If first element is zero ++ (end of string) -> return null. */ ++ ++.Lslow_loop_acc: ++ vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> ++ Character matches any accepted character in ++ this accept-string-part) IN=0, RT=1. */ ++ vlgvb %r4,%v22,0 /* Get result of first element. */ ++ /* First element is equal to any accepted characters ++ (all other parts of accept cannot lead to a match before this one) ++ -> current len is pointing to first element ++ -> return found */ ++ clijh %r4,0,.Lslow_end_found ++ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ ++ /* Proceed with next acc until end of acc is reached. */ ++ ++ ++.Lslow_next_acc: ++ clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part ++ -> add index to current_len and ++ end. */ ++ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ ++ aghi %r5,16 /* Increment current len of accept-string. */ ++ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ ++ jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is ++ on block-boundary. */ ++.Lslow_next_acc_notonbb: ++ vistrbs %v17,%v17 /* Fill with zeros after first zero. */ ++ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ ++ ++.Lslow_next_acc_prepare_zero: ++ /* Zero in accept-part: fill zeros with first-accept-character. */ ++ vlgvb %r8,%v17,0 /* Load first element of acc-part. */ ++ clije %r8,0,.Lslow_next_str /* Proceed with next string-part, ++ if first char in this part of accept ++ is a zero. */ ++ /* r8>0 -> zero found in this acc-part. */ ++ vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ ++ vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars ++ by comparing with 0 (v20). */ ++ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ ++ j .Lslow_loop_acc /* Accept part is prepared -> process. */ ++ ++.Lslow_next_acc_onbb: ++ vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ ++ vlgvb %r8,%v18,7 /* Load byte index of zero. */ ++ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes ++ -> Prepare vreg. */ ++ vl %v17,0(%r5,%r3) /* Load over boundary ... */ ++ lghi %r8,0 /* r8=0 -> no zero in this part of acc, ++ check for zero is in jump-target. */ ++ j .Lslow_next_acc_notonbb /* ... and search for zero in ++ fully loaded vreg again. */ ++ ++.Lslow_end_null: ++ lghi %r1,0 /* Return null if no character is equal. */ ++ j .Lslow_end ++ ++.Lslow_loop_found: ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++ vlgvb %r0,%v16,0(%r4) /* Get found element. */ ++ clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */ ++ ++.Lslow_index_found: ++ algfr %r1,%r4 /* Add found index of char to current len. */ ++.Lslow_end_found: ++ la %r1,0(%r1,%r2) /* And return pointer to first equal char. */ ++ ++.Lslow_end: ++ /* Restore registers. */ ++ vlgvg %r6,%v30,0 ++ vlgvg %r8,%v31,0 ++ vlgvg %r9,%v31,1 ++ lgr %r2,%r1 ++ br %r14 ++END(__strpbrk_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c +new file mode 100644 +index 0000000..afcb633 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strpbrk.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of strpbrk. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strpbrk, strpbrk) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcspbrk-c.c b/sysdeps/s390/multiarch/wcspbrk-c.c +new file mode 100644 +index 0000000..3a27e60 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcspbrk-c.c +@@ -0,0 +1,31 @@ ++/* Default wcspbrk implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSPBRK __wcspbrk_c ++ ++# include ++extern __typeof (wcspbrk) __wcspbrk_c; ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcspbrk_c, __GI_wcspbrk, __wcspbrk_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcspbrk-vx.S b/sysdeps/s390/multiarch/wcspbrk-vx.S +new file mode 100644 +index 0000000..e6eaf95 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcspbrk-vx.S +@@ -0,0 +1,315 @@ ++/* Vector optimized 32/64 bit S/390 version of wcspbrk. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t *wcspbrk (const wchar_t *s, const wchar_t * accept) ++ The wcspbrk() function locates the first occurrence in the string s ++ of any of the characters in the string accept and returns a pointer ++ to that character or NULL if not found. ++ ++ This method checks the length of accept string. If it fits entirely ++ in one vector register, a fast algorithm is used, which does not need ++ to check multiple parts of accept-string. Otherwise a slower full ++ check of accept-string is used. ++ ++ register overview: ++ r3: pointer to start of accept-string ++ r2: pointer to start of search-string ++ r0: loaded byte count of vlbb search-string (32bit unsigned) ++ r4: found byte index (32bit unsigned) ++ r1: current return len (64bit unsigned) ++ v16: search-string ++ v17: accept-string ++ v18: temp-vreg ++ ++ ONLY FOR SLOW: ++ v19: first accept-string ++ v20: zero for preparing acc-vector ++ v21: global mask; 1 indicates a match between ++ search-string-vreg and any accept-character ++ v22: current mask; 1 indicates a match between ++ search-string-vreg and any accept-character in current acc-vreg ++ v24: one for result-checking of former string-part ++ v30, v31: for re-/storing registers r6, r8, r9 ++ r5: current len of accept-string ++ r6: zero-index in search-string or 16 if no zero ++ or min(zero-index, loaded byte count) ++ r8: >0, if former accept-string-part contains a zero, ++ otherwise =0; ++ r9: loaded byte count of vlbb accept-string ++*/ ++ENTRY(__wcspbrk_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ /* ++ Check if accept-string fits in one vreg: ++ ---------------------------------------- ++ */ ++ vlbb %v17,0(%r3),6 /* Load accept. */ ++ lcbb %r0,0(%r3),6 ++ jo .Lcheck_onbb /* Special case if accept lays ++ on block-boundary. */ ++ ++.Lcheck_notonbb: ++ lghi %r1,0 /* Zero out current len. */ ++ vlgvf %r0,%v17,0 /* Get first element. */ ++ clije %r0,0,.Lfast_end_null /* Return null if accept is empty. */ ++ ++ vistrfs %v17,%v17 /* Fill with zeros after first zero. */ ++ je .Lfast /* Zero found -> accept fits in one vreg. */ ++ j .Lslow /* No zero -> accept exceeds one vreg */ ++ ++ ++.Lcheck_onbb: ++ /* Accept lays on block-boundary. */ ++ nill %r0,65532 /* Recognize only fully loaded characters. */ ++ je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */ ++ vfenezf %v18,%v17,%v17 /* Search zero in loaded accept bytes. */ ++ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ ++ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> ++ accept fits in one vreg; ++ Fill with zeros and proceed ++ with FAST. */ ++.Lcheck_onbb2: ++ vl %v17,0(%r3) /* Load accept, which exceeds loaded bytes. */ ++ j .Lcheck_notonbb /* Check if accept fits in one vreg. */ ++ ++ ++ /* ++ Search s for accept in one vreg ++ ------------------------------- ++ */ ++.Lfast: ++ /* Complete accept-string in v17 and remaining bytes are zero. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 unequal to any ++ in v17 or first zero element. */ ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++ /* If found index is within loaded bytes, return with found ++ element index (=equal count). */ ++ clrjl %r4,%r0,.Lfast_loop_found2 ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r1,16 /* current_len = 16. */ ++ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++.Lfast_loop: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any ++ in v17 or first zero element. */ ++ jno .Lfast_loop_found ++ ++ vl %v16,16(%r1,%r2) ++ vfaezfs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found16 ++ ++ vl %v16,32(%r1,%r2) ++ vfaezfs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found32 ++ ++ vl %v16,48(%r1,%r2) ++ vfaezfs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found48 ++ ++ aghi %r1,64 ++ j .Lfast_loop /* Loop if no element was unequal to accept ++ and not zero. */ ++ ++ /* Found equal or zero element. */ ++.Lfast_loop_found48: ++ aghi %r1,16 ++.Lfast_loop_found32: ++ aghi %r1,16 ++.Lfast_loop_found16: ++ aghi %r1,16 ++.Lfast_loop_found: ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++.Lfast_loop_found2: ++ srlg %r5,%r4,2 /* Convert byte-index to character-index. */ ++ vlgvf %r0,%v16,0(%r5) /* Get found element. */ ++ clije %r0,0,.Lfast_end_null /* Return null if no accept-char found */ ++ algfr %r1,%r4 /* Add found index of char to current len. */ ++ la %r2,0(%r1,%r2) /* And return pointer to first equal char. */ ++ br %r14 ++ ++.Lfast_end_null: ++ lghi %r2,0 /* Return null if no character is equal. */ ++ br %r14 ++ ++ ++ ++ ++ /* ++ Search s for accept in multiple vregs ++ ------------------------------------- ++ */ ++.Lslow: ++ /* Save registers. */ ++ vlvgg %v30,%r6,0 ++ vlvgp %v31,%r8,%r9 ++ ++ /* Accept in v17 without zero */ ++ vlr %v19,%v17 /* Save first acc-part for a fast reload. */ ++ vzero %v20 /* Zero for preparing acc-vector. */ ++ vone %v24 /* One for checking result of former string. */ ++ ++ /* Align s to 16 byte. */ ++ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and ++ %r4 = bits 60-63 'and' 15. */ ++ je .Lslow_loop_str /* If s is aligned, loop aligned. */ ++ lghi %r0,15 ++ slr %r0,%r4 /* Compute highest index to load (15-x). */ ++ vll %v16,%r0,0(%r2) /* Load up to 16byte boundary; ++ needs highest index, left bytes are 0. */ ++ ahi %r0,1 /* Work with loaded byte count. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept-string to zero. */ ++ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end_null /* If first element is zero ++ (end of string) -> return null */ ++ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ ++ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ ++ j .Lslow_loop_acc ++ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lslow_next_str: ++ /* Check results of former processed str-part. */ ++ vfeef %v18,%v21,%v24 /* Find first equal match in global mask ++ (ones in element). */ ++ vlgvb %r4,%v18,7 /* Get index of first one (=equal) ++ or 16 if no match. */ ++ /* Equal-index < min(zero-index, loaded byte count) ++ -> return pointer to equal element. */ ++ clrjl %r4,%r6,.Lslow_index_found ++ /* Zero-index < loaded byte count ++ -> former str-part was last str-part ++ -> return null */ ++ clrjl %r6,%r0,.Lslow_end_null ++ /* All elements are zero (=no match) -> proceed with next str-part. */ ++ ++ vlr %v17,%v19 /* Load first part of accept (no zero). */ ++ algfr %r1,%r0 /* Add loaded byte count to current len. */ ++ ++.Lslow_loop_str: ++ vl %v16,0(%r1,%r2) /* Load search-string */ ++ lghi %r0,16 /* Loaded byte count is 16. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of accept to zero. */ ++ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first accept-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end_null /* If first element is zero ++ (end of string) -> return null. */ ++ ++.Lslow_loop_acc: ++ vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> ++ Character matches any accepted character in ++ this accept-string-part) IN=0, RT=1. */ ++ vlgvf %r4,%v22,0 /* Get result of first element. */ ++ /* First element is equal to any accepted characters ++ (all other parts of accept cannot lead to a match before this one) ++ -> current len is pointing to first element ++ -> return found */ ++ clijh %r4,0,.Lslow_end_found ++ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ ++ /* Proceed with next acc until end of acc is reached. */ ++ ++ ++.Lslow_next_acc: ++ clijh %r8,0,.Lslow_next_str /* There was a zero in the last acc-part ++ -> add index to current len and ++ end. */ ++ vlbb %v17,16(%r5,%r3),6 /* Load next accept part. */ ++ aghi %r5,16 /* Increment current len of accept-string. */ ++ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of accept-string. */ ++ jo .Lslow_next_acc_onbb /* Jump away ifaccept-string is ++ on block-boundary. */ ++.Lslow_next_acc_notonbb: ++ vistrfs %v17,%v17 /* Fill with zeros after first zero. */ ++ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ ++ ++.Lslow_next_acc_prepare_zero: ++ /* Zero in accept-part: fill zeros with first-accept-character. */ ++ vlgvf %r8,%v17,0 /* Load first element of acc-part. */ ++ clije %r8,0,.Lslow_next_str /* Proceed with next string-part, ++ If first char in this part of accept ++ is a zero. */ ++ /* r8>0 -> zero found in this acc-part. */ ++ vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ ++ vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars ++ by comparing with 0 (v20). */ ++ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ ++ j .Lslow_loop_acc /* Accept part is prepared -> process. */ ++ ++.Lslow_next_acc_onbb: ++ nill %r9,65532 /* Recognize only fully loaded characters. */ ++ je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t. */ ++ vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of accept part. */ ++ vlgvb %r8,%v18,7 /* Load byte index of zero. */ ++ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes ++ -> Prepare vreg. */ ++.Lslow_next_acc_onbb2: ++ vl %v17,0(%r5,%r3) /* Load over boundary ... */ ++ lghi %r8,0 /* r8=0 -> no zero in this part of acc, ++ check for zero is in jump-target. */ ++ j .Lslow_next_acc_notonbb /* ... and search for zero in ++ fully loaded vreg again. */ ++ ++.Lslow_end_null: ++ lghi %r1,0 /* Return null if no character is equal. */ ++ j .Lslow_end ++ ++.Lslow_loop_found: ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++ srlg %r5,%r4,2 /* Convert byte-index to character-index. */ ++ vlgvf %r0,%v16,0(%r5) /* Get found element. */ ++ clije %r0,0,.Lslow_end_null /* Return null if no acc-char found. */ ++ ++.Lslow_index_found: ++ algfr %r1,%r4 /* Add found index of char to current len. */ ++.Lslow_end_found: ++ la %r1,0(%r1,%r2) /* And return pointer to first equal char. */ ++ ++.Lslow_end: ++ /* Restore registers. */ ++ vlgvg %r6,%v30,0 ++ vlgvg %r8,%v31,0 ++ vlgvg %r9,%v31,1 ++ lgr %r2,%r1 ++ br %r14 ++.Lfallback: ++ jg __wcspbrk_c ++END(__wcspbrk_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c +new file mode 100644 +index 0000000..1a0ef9c +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcspbrk.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcspbrk. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcspbrk, wcspbrk) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 843a23c..7ecff8b 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn ++ wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcspbrk-ifunc.c b/wcsmbs/test-wcspbrk-ifunc.c +new file mode 100644 +index 0000000..af389b6 +--- /dev/null ++++ b/wcsmbs/test-wcspbrk-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcspbrk function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcspbrk.c" +diff --git a/wcsmbs/test-wcspbrk.c b/wcsmbs/test-wcspbrk.c +new file mode 100644 +index 0000000..98e44e5 +--- /dev/null ++++ b/wcsmbs/test-wcspbrk.c +@@ -0,0 +1,20 @@ ++/* Test wcspbrk functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strpbrk.c" +diff --git a/wcsmbs/wcspbrk.c b/wcsmbs/wcspbrk.c +index a39f148..b769a38 100644 +--- a/wcsmbs/wcspbrk.c ++++ b/wcsmbs/wcspbrk.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WCSPBRK ++# define wcspbrk WCSPBRK ++#endif + + /* Find the first occurrence in WCS of any wide-character in ACCEPT. */ + wchar_t * +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-25.patch b/SOURCES/glibc-rh1268008-25.patch new file mode 100644 index 00000000..7f1f48a5 --- /dev/null +++ b/SOURCES/glibc-rh1268008-25.patch @@ -0,0 +1,1106 @@ +From 6be435ec4f615266351487da396333f3ff026c03 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 13:02:41 +0200 +Subject: [PATCH 25/30] S390: Optimize strcspn and wcscspn. + +upstream-commit-id: b4c21601b147efc3c2b0e679e4ffc554b3987f0b +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00099.html + +This patch provides optimized versions of strcspn and wcscspn with the z13 +vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/strcspn-c.c: New File. + * sysdeps/s390/multiarch/strcspn-vx.S: Likewise. + * sysdeps/s390/multiarch/strcspn.c: Likewise. + * sysdeps/s390/multiarch/wcscspn-c.c: Likewise. + * sysdeps/s390/multiarch/wcscspn-vx.S: Likewise. + * sysdeps/s390/multiarch/wcscspn.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strcspn and + wcscspn functions. + * sysdeps/s390/multiarch/ifunc-impl-list.c + (__libc_ifunc_impl_list): Add ifunc test for strcspn, wcscspn. + * wcsmbs/wcscspn.c: Use WCSCSPN if defined. + * string/test-strcspn.c: Add wcscspn support. + * wcsmbs/test-wcscspn.c: New File. + * wcsmbs/Makefile (strop-tests): Add wcscspn. + * benchtests/bench-strcspn.c: Add wcscspn support. + * benchtests/bench-wcscspn.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wcscspn. +--- + benchtests/Makefile | 2 +- + benchtests/bench-strcspn.c | 45 +++-- + benchtests/bench-wcscspn.c | 20 +++ + string/strcspn.c | 8 +- + string/test-strcspn.c | 45 +++-- + sysdeps/s390/multiarch/Makefile | 6 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 3 + + sysdeps/s390/multiarch/strcspn-c.c | 28 +++ + sysdeps/s390/multiarch/strcspn-vx.S | 281 +++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/strcspn.c | 27 +++ + sysdeps/s390/multiarch/wcscspn-c.c | 26 +++ + sysdeps/s390/multiarch/wcscspn-vx.S | 293 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wcscspn.c | 27 +++ + wcsmbs/Makefile | 3 +- + wcsmbs/test-wcscspn-ifunc.c | 20 +++ + wcsmbs/test-wcscspn.c | 20 +++ + wcsmbs/wcscspn.c | 3 + + 17 files changed, 826 insertions(+), 31 deletions(-) + create mode 100644 benchtests/bench-wcscspn.c + create mode 100644 sysdeps/s390/multiarch/strcspn-c.c + create mode 100644 sysdeps/s390/multiarch/strcspn-vx.S + create mode 100644 sysdeps/s390/multiarch/strcspn.c + create mode 100644 sysdeps/s390/multiarch/wcscspn-c.c + create mode 100644 sysdeps/s390/multiarch/wcscspn-vx.S + create mode 100644 sysdeps/s390/multiarch/wcscspn.c + create mode 100644 wcsmbs/test-wcscspn-ifunc.c + create mode 100644 wcsmbs/test-wcscspn.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 015b5d6..4e811a9 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk ++ wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-strcspn.c b/benchtests/bench-strcspn.c +index 22b3b84..25de640 100644 +--- a/benchtests/bench-strcspn.c ++++ b/benchtests/bench-strcspn.c +@@ -19,22 +19,41 @@ + #define STRPBRK_RESULT(s, pos) (pos) + #define RES_TYPE size_t + #define TEST_MAIN +-#define TEST_NAME "strcspn" ++#ifndef WIDE ++# define TEST_NAME "strcspn" ++#else ++# define TEST_NAME "wcscspn" ++#endif /* WIDE */ + #include "bench-string.h" + +-typedef size_t (*proto_t) (const char *, const char *); +-size_t simple_strcspn (const char *, const char *); +-size_t stupid_strcspn (const char *, const char *); ++#ifndef WIDE ++# define STRCSPN strcspn ++# define CHAR char ++# define SIMPLE_STRCSPN simple_strcspn ++# define STUPID_STRCSPN stupid_strcspn ++# define STRLEN strlen ++#else ++# include ++# define STRCSPN wcscspn ++# define CHAR wchar_t ++# define SIMPLE_STRCSPN simple_wcscspn ++# define STUPID_STRCSPN stupid_wcscspn ++# define STRLEN wcslen ++#endif /* WIDE */ + +-IMPL (stupid_strcspn, 0) +-IMPL (simple_strcspn, 0) +-IMPL (strcspn, 1) ++typedef size_t (*proto_t) (const CHAR *, const CHAR *); ++size_t SIMPLE_STRCSPN (const CHAR *, const CHAR *); ++size_t STUPID_STRCSPN (const CHAR *, const CHAR *); ++ ++IMPL (STUPID_STRCSPN, 0) ++IMPL (SIMPLE_STRCSPN, 0) ++IMPL (STRCSPN, 1) + + size_t +-simple_strcspn (const char *s, const char *rej) ++SIMPLE_STRCSPN (const CHAR *s, const CHAR *rej) + { +- const char *r, *str = s; +- char c; ++ const CHAR *r, *str = s; ++ CHAR c; + + while ((c = *s++) != '\0') + for (r = rej; *r != '\0'; ++r) +@@ -44,9 +63,9 @@ simple_strcspn (const char *s, const char *rej) + } + + size_t +-stupid_strcspn (const char *s, const char *rej) ++STUPID_STRCSPN (const CHAR *s, const CHAR *rej) + { +- size_t ns = strlen (s), nrej = strlen (rej); ++ size_t ns = STRLEN (s), nrej = STRLEN (rej); + size_t i, j; + + for (i = 0; i < ns; ++i) +@@ -56,4 +75,6 @@ stupid_strcspn (const char *s, const char *rej) + return i; + } + ++#undef CHAR ++#undef STRLEN + #include "bench-strpbrk.c" +diff --git a/benchtests/bench-wcscspn.c b/benchtests/bench-wcscspn.c +new file mode 100644 +index 0000000..3991951 +--- /dev/null ++++ b/benchtests/bench-wcscspn.c +@@ -0,0 +1,20 @@ ++/* Measure wcscspn functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-strcspn.c" +diff --git a/string/strcspn.c b/string/strcspn.c +index 6290429..0c750a8 100644 +--- a/string/strcspn.c ++++ b/string/strcspn.c +@@ -30,12 +30,14 @@ + + #undef strcspn + ++#ifndef STRCSPN ++# define STRCSPN strcspn ++#endif ++ + /* Return the length of the maximum initial segment of S + which contains no characters from REJECT. */ + size_t +-strcspn (s, reject) +- const char *s; +- const char *reject; ++STRCSPN (const char *s, const char *reject) + { + size_t count = 0; + +diff --git a/string/test-strcspn.c b/string/test-strcspn.c +index e2863c7..3443425 100644 +--- a/string/test-strcspn.c ++++ b/string/test-strcspn.c +@@ -20,22 +20,41 @@ + #define STRPBRK_RESULT(s, pos) (pos) + #define RES_TYPE size_t + #define TEST_MAIN +-#define TEST_NAME "strcspn" ++#ifndef WIDE ++# define TEST_NAME "strcspn" ++#else ++# define TEST_NAME "wcscspn" ++#endif /* WIDE */ + #include "test-string.h" + +-typedef size_t (*proto_t) (const char *, const char *); +-size_t simple_strcspn (const char *, const char *); +-size_t stupid_strcspn (const char *, const char *); ++#ifndef WIDE ++# define STRCSPN strcspn ++# define CHAR char ++# define SIMPLE_STRCSPN simple_strcspn ++# define STUPID_STRCSPN stupid_strcspn ++# define STRLEN strlen ++#else ++# include ++# define STRCSPN wcscspn ++# define CHAR wchar_t ++# define SIMPLE_STRCSPN simple_wcscspn ++# define STUPID_STRCSPN stupid_wcscspn ++# define STRLEN wcslen ++#endif /* WIDE */ + +-IMPL (stupid_strcspn, 0) +-IMPL (simple_strcspn, 0) +-IMPL (strcspn, 1) ++typedef size_t (*proto_t) (const CHAR *, const CHAR *); ++size_t SIMPLE_STRCSPN (const CHAR *, const CHAR *); ++size_t STUPID_STRCSPN (const CHAR *, const CHAR *); ++ ++IMPL (STUPID_STRCSPN, 0) ++IMPL (SIMPLE_STRCSPN, 0) ++IMPL (STRCSPN, 1) + + size_t +-simple_strcspn (const char *s, const char *rej) ++SIMPLE_STRCSPN (const CHAR *s, const CHAR *rej) + { +- const char *r, *str = s; +- char c; ++ const CHAR *r, *str = s; ++ CHAR c; + + while ((c = *s++) != '\0') + for (r = rej; *r != '\0'; ++r) +@@ -45,9 +64,9 @@ simple_strcspn (const char *s, const char *rej) + } + + size_t +-stupid_strcspn (const char *s, const char *rej) ++STUPID_STRCSPN (const CHAR *s, const CHAR *rej) + { +- size_t ns = strlen (s), nrej = strlen (rej); ++ size_t ns = STRLEN (s), nrej = STRLEN (rej); + size_t i, j; + + for (i = 0; i < ns; ++i) +@@ -57,4 +76,6 @@ stupid_strcspn (const char *s, const char *rej) + return i; + } + ++#undef CHAR ++#undef STRLEN + #include "test-strpbrk.c" +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 5765a8c..2c1fce0 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -13,7 +13,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strchrnul strchrnul-vx strchrnul-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ +- strpbrk strpbrk-vx strpbrk-c ++ strpbrk strpbrk-vx strpbrk-c \ ++ strcspn strcspn-vx strcspn-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -31,5 +32,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcschrnul wcschrnul-vx wcschrnul-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ +- wcspbrk wcspbrk-vx wcspbrk-c ++ wcspbrk wcspbrk-vx wcspbrk-c \ ++ wcscspn wcscspn-vx wcscspn-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index b39a5c5..7f62e49 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -124,6 +124,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strpbrk); + IFUNC_VX_IMPL (wcspbrk); + ++ IFUNC_VX_IMPL (strcspn); ++ IFUNC_VX_IMPL (wcscspn); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/strcspn-c.c b/sysdeps/s390/multiarch/strcspn-c.c +new file mode 100644 +index 0000000..af04b4e +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcspn-c.c +@@ -0,0 +1,28 @@ ++/* Default strcspn implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define STRCSPN __strcspn_c ++# ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__strcspn_c, __GI_strcspn, __strcspn_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strcspn-vx.S b/sysdeps/s390/multiarch/strcspn-vx.S +new file mode 100644 +index 0000000..c7113c4 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcspn-vx.S +@@ -0,0 +1,281 @@ ++/* Vector optimized 32/64 bit S/390 version of strcspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t strcspn (const char *s, const char * reject) ++ The strcspn() function calculates the length of the initial segment ++ of s which consists entirely of characters not in reject. ++ ++ This method checks the length of reject string. If it fits entirely ++ in one vector register, a fast algorithm is used, which does not need ++ to check multiple parts of accept-string. Otherwise a slower full ++ check of accept-string is used. ++ ++ register overview: ++ r3: pointer to start of reject-string ++ r2: pointer to start of search-string ++ r0: loaded byte count of vlbb search-string ++ r4: found byte index ++ r1: current return len ++ v16: search-string ++ v17: reject-string ++ v18: temp-vreg ++ ++ ONLY FOR SLOW: ++ v19: first reject-string ++ v20: zero for preparing acc-vector ++ v21: global mask; 1 indicates a match between ++ search-string-vreg and any reject-character ++ v22: current mask; 1 indicates a match between ++ search-string-vreg and any reject-character in current acc-vreg ++ v24: one for result-checking of former string-part ++ v30, v31: for re-/storing registers r6, r8, r9 ++ r5: current len of reject-string ++ r6: zero-index in search-string or 16 if no zero ++ or min(zero-index, loaded byte count) ++ r8: >0, if former reject-string-part contains a zero, ++ otherwise =0; ++ r9: loaded byte count of vlbb reject-string ++*/ ++ENTRY(__strcspn_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ /* ++ Check if reject-string fits in one vreg: ++ ---------------------------------------- ++ */ ++ vlbb %v17,0(%r3),6 /* Load reject. */ ++ lghi %r1,0 /* Zero out current len. */ ++ lcbb %r0,0(%r3),6 ++ jo .Lcheck_onbb /* Special case if reject ++ lays on block-boundary. */ ++.Lcheck_notonbb: ++ vistrbs %v17,%v17 /* Fill with zeros after first zero. */ ++ je .Lfast /* Zero found -> reject fits in one vreg. */ ++ j .Lslow /* No zero -> reject exceeds one vreg. */ ++ ++ ++.Lcheck_onbb: ++ /* Reject lays on block-boundary. */ ++ vfenezb %v18,%v17,%v17 /* Search zero in loaded reject bytes. */ ++ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ ++ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> ++ Reject fits in one vreg; ++ Fill with zeros and proceed ++ with FAST. */ ++ vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */ ++ j .Lcheck_notonbb /* Check if reject fits in one vreg. */ ++ ++ ++ /* ++ Search s for reject in one vreg ++ ------------------------------- ++ */ ++.Lfast: ++ /* Complete reject-string in v17 and remaining bytes are zero. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 ++ unequal to any in v17 ++ or first zero element. */ ++ ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++ clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded ++ bytes, return with found element ++ index (=equal count). */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r1,16 /* current_len = 16. */ ++ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lfast_loop: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ vfaezbs %v18,%v16,%v17,0 /* Find first element in v16 equal to any ++ in v17 or first zero element. */ ++ jno .Lfast_loop_found ++ ++ vl %v16,16(%r1,%r2) ++ vfaezbs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found16 ++ ++ vl %v16,32(%r1,%r2) ++ vfaezbs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found32 ++ ++ vl %v16,48(%r1,%r2) ++ vfaezbs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found48 ++ ++ aghi %r1,64 ++ j .Lfast_loop /* Loop if no element was unequal to reject ++ and not zero. */ ++ ++ /* Found equal or zero element. */ ++.Lfast_loop_found48: ++ aghi %r1,16 ++.Lfast_loop_found32: ++ aghi %r1,16 ++.Lfast_loop_found16: ++ aghi %r1,16 ++.Lfast_loop_found: ++ vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */ ++.Lfast_loop_found2: ++ algrk %r2,%r1,%r4 /* Add found index to current len. */ ++ br %r14 ++ ++ ++ ++ /* ++ Search s for reject in multiple vregs ++ ------------------------------------- ++ */ ++.Lslow: ++ /* Save registers. */ ++ vlvgg %v30,%r6,0 ++ vlvgp %v31,%r8,%r9 ++ ++ /* Reject in v17 without zero. */ ++ vlr %v19,%v17 /* Save first acc-part for a fast reload. */ ++ vzero %v20 /* Zero for preparing acc-vector. */ ++ vone %v24 /* One for checking result of former ++ string-part. */ ++ ++ /* Align s to 16 byte. */ ++ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and ++ %r4 = bits 60-63 'and' 15. */ ++ je .Lslow_loop_str /* If s is aligned, loop aligned. */ ++ lghi %r0,15 ++ slr %r0,%r4 /* Compute highest index to load (15-x). */ ++ vll %v16,%r0,0(%r2) /* Load up to 16 byte boundary (vll needs ++ highest index, remaining bytes are 0). */ ++ ahi %r0,1 /* Work with loaded byte count. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of reject-string to zero. */ ++ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first reject-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */ ++ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ ++ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ ++ j .Lslow_loop_acc ++ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lslow_next_str: ++ /* Check results of former processed str-part. */ ++ vfeeb %v18,%v21,%v24 /* Find first equal match in global mask ++ (ones in element). */ ++ vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */ ++ /* Equal-index < min(zero-index, loaded byte count) ++ -> Return pointer to equal element. */ ++ clrjl %r4,%r6,.Lslow_index_found ++ /* Zero-index < loaded byte count ++ -> Former str-part was last str-part ++ -> Return null */ ++ clrjl %r6,%r0,.Lslow_end_not_found ++ ++ /* All elements are zero (=no match) -> Proceed with next str-part. */ ++ vlr %v17,%v19 /* Load first part of reject (no zero). */ ++ algfr %r1,%r0 /* Add loaded byte count to current len. */ ++ ++.Lslow_loop_str: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ lghi %r0,16 /* Loaded byte count is 16. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of reject to zero. */ ++ vfenezb %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first reject-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end /* If first element is zero (end of string) ++ -> Return current length. */ ++ ++.Lslow_loop_acc: ++ vfaeb %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> ++ Character matches any rejected character in ++ this reject-string-part) IN=0, RT=1. */ ++ vlgvb %r4,%v22,0 /* Get result of first element. */ ++ /* First element is equal to any rejected characters? ++ (all other parts of reject cannot lead to a match before this one) ++ -> Return current len, which is pointing to this element. */ ++ clijh %r4,0,.Lslow_end ++ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ ++ /* Proceed with next acc until end of acc is reached. */ ++ ++ ++.Lslow_next_acc: ++ clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part ++ -> Add found index to current len ++ and end. */ ++ vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */ ++ aghi %r5,16 /* Increment current len of reject-string. */ ++ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */ ++ jo .Lslow_next_acc_onbb /* Jump away if reject-string is ++ on block-boundary. */ ++.Lslow_next_acc_notonbb: ++ vistrbs %v17,%v17 /* Fill with zeros after first zero. */ ++ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ ++ ++.Lslow_next_acc_prepare_zero: ++ /* Zero in reject-part: fill zeros with first-reject-character. */ ++ vlgvb %r8,%v17,0 /* Load first element of reject-part. */ ++ clije %r8,0,.Lslow_next_str /* Process next str-part if first ++ character in this part of reject ++ is a zero. */ ++ /* r8>0 -> zero found in this acc-part. */ ++ vrepb %v18,%v17,0 /* Replicate first char accross all chars. */ ++ vceqb %v22,%v20,%v17 /* Create a mask (v22) of null chars ++ by comparing with 0 (v20). */ ++ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ ++ j .Lslow_loop_acc /* Reject-string part is prepared. */ ++ ++.Lslow_next_acc_onbb: ++ vfenezb %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */ ++ vlgvb %r8,%v18,7 /* Load byte index of zero. */ ++ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes ++ -> Prepare vreg. */ ++ vl %v17,0(%r5,%r3) /* Load over boundary ... */ ++ lghi %r8,0 /* r8=0 -> no zero in this part of acc, ++ check for zero is in jump-target. */ ++ j .Lslow_next_acc_notonbb /* ... and search for zero in ++ fully loaded vreg again. */ ++ ++.Lslow_end_not_found: ++ algfr %r1,%r6 /* Add zero-index to current len. */ ++ j .Lslow_end ++.Lslow_index_found: ++ algfr %r1,%r4 /* Add found index of char to current len. */ ++.Lslow_end: ++ lgr %r2,%r1 ++ /* Restore registers. */ ++ vlgvg %r6,%v30,0 ++ vlgvg %r8,%v31,0 ++ vlgvg %r9,%v31,1 ++ br %r14 ++END(__strcspn_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c +new file mode 100644 +index 0000000..32b46c4 +--- /dev/null ++++ b/sysdeps/s390/multiarch/strcspn.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of strcspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__strcspn, strcspn) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/wcscspn-c.c b/sysdeps/s390/multiarch/wcscspn-c.c +new file mode 100644 +index 0000000..95e76ae +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscspn-c.c +@@ -0,0 +1,26 @@ ++/* Default wcscscpn implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WCSCSPN __wcscspn_c ++ ++# include ++extern __typeof (wcscspn) __wcscspn_c; ++ ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wcscspn-vx.S b/sysdeps/s390/multiarch/wcscspn-vx.S +new file mode 100644 +index 0000000..aa581ce +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscspn-vx.S +@@ -0,0 +1,293 @@ ++/* Vector optimized 32/64 bit S/390 version of wcscspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* size_t wcscspn (const wchar_t *s, const wchar_t * reject) ++ The wcscspn() function calculates the length of the initial segment ++ of s which consists entirely of characters not in reject. ++ ++ This method checks the length of reject string. If it fits entirely ++ in one vector register, a fast algorithm is used, which does not need ++ to check multiple parts of accept-string. Otherwise a slower full ++ check of accept-string is used. ++ ++ register overview: ++ r3: pointer to start of reject-string ++ r2: pointer to start of search-string ++ r0: loaded byte count of vlbb search-string ++ r4: found byte index ++ r1: current return len ++ v16: search-string ++ v17: reject-string ++ v18: temp-vreg ++ ++ ONLY FOR SLOW: ++ v19: first reject-string ++ v20: zero for preparing acc-vector ++ v21: global mask; 1 indicates a match between ++ search-string-vreg and any reject-character ++ v22: current mask; 1 indicates a match between ++ search-string-vreg and any reject-character in current acc-vreg ++ v30, v31: for re-/storing registers r6, r8, r9 ++ r5: current len of reject-string ++ r6: zero-index in search-string or 16 if no zero ++ or min(zero-index, loaded byte count) ++ r8: >0, if former reject-string-part contains a zero, ++ otherwise =0; ++ r9: loaded byte count of vlbb reject-string ++*/ ++ENTRY(__wcscspn_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ /* ++ Check if reject-string fits in one vreg: ++ ---------------------------------------- ++ */ ++ vlbb %v17,0(%r3),0 /* Load reject. */ ++ lcbb %r0,0(%r3),0 ++ jo .Lcheck_onbb /* Special case if reject ++ lays on block-boundary. */ ++ ++.Lcheck_notonbb: ++ lghi %r1,0 /* Zero out current len. */ ++ vistrfs %v17,%v17 /* Fill with zeros after first zero. */ ++ je .Lfast /* Zero found -> reject fits in one vreg. */ ++ j .Lslow /* No zero -> reject exceeds one vreg. */ ++ ++ ++.Lcheck_onbb: ++ /* Reject lays on block-boundary. */ ++ nill %r0,65532 /* Recognize only fully loaded characters. */ ++ je .Lcheck_onbb2 /* Reload vr, if we loaded no full wchar_t. */ ++ vfenezf %v18,%v17,%v17 /* Search zero in loaded reject bytes. */ ++ vlgvb %r4,%v18,7 /* Get index of zero or 16 if not found. */ ++ clrjl %r4,%r0,.Lcheck_notonbb /* Zero index < loaded bytes count -> ++ Reject fits in one vreg; ++ Fill with zeros and proceed ++ with FAST. */ ++.Lcheck_onbb2: ++ vl %v17,0(%r3) /* Load reject, which exceeds loaded bytes. */ ++ j .Lcheck_notonbb /* Check if reject fits in one vreg. */ ++ ++ ++ /* ++ Search s for reject in one vreg ++ ------------------------------- ++ */ ++.Lfast: ++ /* Complete reject-string in v17 and remaining bytes are zero. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 ++ unequal to any in v17 ++ or first zero element. */ ++ vlgvb %r4,%v18,7 /* Load byte index of found element. */ ++ clrjl %r4,%r0,.Lfast_loop_found2 /* If found index is within loaded ++ bytes, return with found element ++ index (=equal count). */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r4,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r1,16 /* current_len = 16. */ ++ slr %r1,%r4 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lfast_loop: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ vfaezfs %v18,%v16,%v17,0 /* Find first element in v16 equal to any ++ in v17 or first zero element. */ ++ jno .Lfast_loop_found ++ ++ vl %v16,16(%r1,%r2) ++ vfaezfs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found16 ++ ++ vl %v16,32(%r1,%r2) ++ vfaezfs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found32 ++ ++ vl %v16,48(%r1,%r2) ++ vfaezfs %v18,%v16,%v17,0 ++ jno .Lfast_loop_found48 ++ ++ aghi %r1,64 ++ j .Lfast_loop /* Loop if no element was unequal to reject ++ and not zero. */ ++ ++ /* Found equal or zero element. */ ++.Lfast_loop_found48: ++ aghi %r1,16 ++.Lfast_loop_found32: ++ aghi %r1,16 ++.Lfast_loop_found16: ++ aghi %r1,16 ++.Lfast_loop_found: ++ vlgvb %r4,%v18,7 /* Load byte index of found element or zero. */ ++.Lfast_loop_found2: ++ algrk %r2,%r1,%r4 /* Add found index to current len. */ ++ srlg %r2,%r2,2 /* Convert byte-count to character-count. */ ++ br %r14 ++ ++ ++ ++ /* ++ Search s for reject in multiple vregs ++ ------------------------------------- ++ */ ++.Lslow: ++ /* Save registers. */ ++ vlvgg %v30,%r6,0 ++ vlvgp %v31,%r8,%r9 ++ ++ /* Reject in v17 without zero. */ ++ vlr %v19,%v17 /* Save first acc-part for a fast reload. */ ++ vzero %v20 /* Zero for preparing acc-vector. */ ++ vone %v24 /* One for checking result of former ++ string-part. */ ++ ++ /* Align s to 16 byte. */ ++ risbg %r4,%r2,60,128+63,0 /* Test if s is aligned and ++ %r4 = bits 60-63 'and' 15. */ ++ je .Lslow_loop_str /* If s is aligned, loop aligned. */ ++ lghi %r0,15 ++ slr %r0,%r4 /* Compute highest index to load (15-x). */ ++ vll %v16,%r0,0(%r2) /* Load up to 16byte boundary (vll needs ++ highest index, remaining bytes are 0). */ ++ ahi %r0,1 /* Work with loaded byte count. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of reject-string to zero. */ ++ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first reject-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end /* If first element is zero -> return 0. */ ++ clr %r0,%r6 /* cc==1 if loaded byte count < zero-index. */ ++ locrl %r6,%r0 /* Load on cc==1; zero-index = lbc. */ ++ j .Lslow_loop_acc ++ ++ ++ /* Process s in 16byte aligned loop. */ ++.Lslow_next_str: ++ /* Check results of former processed str-part. */ ++ vfeef %v18,%v21,%v24 /* Find first equal match in global mask ++ (ones in element). */ ++ vlgvb %r4,%v18,7 /* Get index of first one (=equal) or 16. */ ++ /* Equal-index < min(zero-index, loaded byte count) ++ -> Return pointer to equal element. */ ++ clrjl %r4,%r6,.Lslow_index_found ++ /* Zero-index < loaded byte count ++ -> Former str-part was last str-part ++ -> Return null */ ++ clrjl %r6,%r0,.Lslow_end_not_found ++ ++ /* All elements are zero (=no match) -> proceed with next str-part. */ ++ vlr %v17,%v19 /* Load first part of reject (no zero). */ ++ algfr %r1,%r0 /* Add loaded byte count to current len. */ ++ ++.Lslow_loop_str: ++ vl %v16,0(%r1,%r2) /* Load search-string. */ ++ lghi %r0,16 /* Loaded byte count is 16. */ ++ vzero %v21 /* Zero out global mask. */ ++ lghi %r5,0 /* Set current len of reject to zero. */ ++ vfenezf %v18,%v16,%v16 /* Find zero in current string-part. */ ++ lghi %r8,0 /* There is no zero in first reject-part. */ ++ vlgvb %r6,%v18,7 /* Load byte index of zero or 16 if no zero. */ ++ clije %r6,0,.Lslow_end /* If first element is zero (end of string) ++ -> Return current length. */ ++ ++.Lslow_loop_acc: ++ vfaef %v22,%v16,%v17,4 /* Create matching-mask (1 in mask -> ++ Character matches any rejected character in ++ this reject-string-part) IN=0, RT=1. */ ++ vlgvf %r4,%v22,0 /* Get result of first element. */ ++ /* First element is equal to any rejected characters? ++ (All other parts of reject cannot lead to a match before this one) ++ -> Return current len, which is pointing to this element. */ ++ clijh %r4,0,.Lslow_end ++ vo %v21,%v21,%v22 /* Global-mask = global-|matching-mask. */ ++ /* Proceed with next acc until end of acc is reached. */ ++ ++ ++.Lslow_next_acc: ++ clijh %r8,0,.Lslow_next_str /* There was a zero in last reject-part ++ -> Add found index to current len ++ and end. */ ++ vlbb %v17,16(%r5,%r3),6 /* Load next reject part. */ ++ aghi %r5,16 /* Increment current len of reject-string. */ ++ lcbb %r9,0(%r5,%r3),6 /* Get loaded byte count of reject-string. */ ++ jo .Lslow_next_acc_onbb /* Jump away if reject-string is ++ on block-boundary. */ ++.Lslow_next_acc_notonbb: ++ vistrfs %v17,%v17 /* Fill with zeros after first zero. */ ++ jo .Lslow_loop_acc /* No zero found -> no preparation needed. */ ++ ++.Lslow_next_acc_prepare_zero: ++ /* Zero in reject-part: fill zeros with first-reject-character. */ ++ vlgvf %r8,%v17,0 /* Load first element of reject-part. */ ++ clije %r8,0,.Lslow_next_str /* Process next str-part if first ++ character in this part of reject ++ is a zero. */ ++ /* r8>0 -> zero found in this acc-part. */ ++ vrepf %v18,%v17,0 /* Replicate first char accross all chars. */ ++ vceqf %v22,%v20,%v17 /* Create a mask (v22) of null chars ++ by comparing with 0 (v20). */ ++ vsel %v17,%v18,%v17,%v22 /* Replace null chars with first char. */ ++ j .Lslow_loop_acc /* Reject-string part is prepared. */ ++ ++.Lslow_next_acc_onbb: ++ nill %r9,65532 /* Recognize only fully loaded characters. */ ++ je .Lslow_next_acc_onbb2 /* Reload vr, if no full wchar_t ++ loaded. */ ++ vfenezf %v18,%v17,%v17 /* Find zero in loaded bytes of reject part. */ ++ vlgvb %r8,%v18,7 /* Load byte index of zero. */ ++ clrjl %r8,%r9,.Lslow_next_acc_notonbb /* Found a zero in loaded bytes ++ -> Prepare vreg. */ ++.Lslow_next_acc_onbb2: ++ vl %v17,0(%r5,%r3) /* Load over boundary ... */ ++ lghi %r8,0 /* r8=0 -> no zero in this part of acc, ++ check for zero is in jump-target. */ ++ j .Lslow_next_acc_notonbb /* ... and search for zero in ++ fully loaded vreg again. */ ++ ++.Lslow_end_not_found: ++ algfr %r1,%r6 /* Add zero-index to current len. */ ++ j .Lslow_end ++.Lslow_index_found: ++ algfr %r1,%r4 /* Add found index of char to current len. */ ++.Lslow_end: ++ srlg %r2,%r1,2 /* Convert byte-count to character-count. */ ++ /* Restore registers. */ ++ vlgvg %r6,%v30,0 ++ vlgvg %r8,%v31,0 ++ vlgvg %r9,%v31,1 ++ br %r14 ++.Lfallback: ++ jg __wcscspn_c ++END(__wcscspn_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wcscspn.c b/sysdeps/s390/multiarch/wcscspn.c +new file mode 100644 +index 0000000..3cb4516 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wcscspn.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wcscspn. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wcscspn, wcscspn) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 7ecff8b..9730b00 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -42,7 +42,8 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + mbrtoc16 c16rtomb + + strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ +- wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk ++ wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \ ++ wcscspn + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wcscspn-ifunc.c b/wcsmbs/test-wcscspn-ifunc.c +new file mode 100644 +index 0000000..e5dcdaf +--- /dev/null ++++ b/wcsmbs/test-wcscspn-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wcscspn function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wcscspn.c" +diff --git a/wcsmbs/test-wcscspn.c b/wcsmbs/test-wcscspn.c +new file mode 100644 +index 0000000..d09cd3d +--- /dev/null ++++ b/wcsmbs/test-wcscspn.c +@@ -0,0 +1,20 @@ ++/* Test wcscspn functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-strcspn.c" +diff --git a/wcsmbs/wcscspn.c b/wcsmbs/wcscspn.c +index 5d38d07..9e84226 100644 +--- a/wcsmbs/wcscspn.c ++++ b/wcsmbs/wcscspn.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WCSCSPN ++# define wcscspn WCSCSPN ++#endif + + /* Return the length of the maximum initial segment + of WCS which contains only wide-characters not in REJECT. */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-26.patch b/SOURCES/glibc-rh1268008-26.patch new file mode 100644 index 00000000..ac0c371c --- /dev/null +++ b/SOURCES/glibc-rh1268008-26.patch @@ -0,0 +1,1183 @@ +From 6bad9c03df10e4bca1840eff95ef9036e5261436 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 13:20:09 +0200 +Subject: [PATCH 26/30] S390: Optimize memchr, rawmemchr and wmemchr. + +upstream-commit-id: 88eefd344b3cf4a41284a1dfdaca61667e3a1b4b +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00093.html + +This patch provides optimized versions of memchr, rawmemchr and wmemchr with the +z13 vector instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/memchr-vx.S: New File. + * sysdeps/s390/multiarch/memchr.c: Likewise. + * sysdeps/s390/multiarch/rawmemchr-c.c: Likewise. + * sysdeps/s390/multiarch/rawmemchr-vx.S: Likewise. + * sysdeps/s390/multiarch/rawmemchr.c: Likewise. + * sysdeps/s390/multiarch/wmemchr-c.c: Likewise. + * sysdeps/s390/multiarch/wmemchr-vx.S: Likewise. + * sysdeps/s390/multiarch/wmemchr.c: Likewise. + * sysdeps/s390/s390-32/multiarch/memchr.c: Likewise. + * sysdeps/s390/s390-64/multiarch/memchr.c: Likewise. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add memchr, wmemchr + and rawmemchr functions. + * sysdeps/s390/multiarch/ifunc-impl-list-common.c + (__libc_ifunc_impl_list_common): Add ifunc test for memchr, rawmemchr + and wmemchr. + * wcsmbs/wmemchr.c: Use WMEMCHR if defined. + * string/test-memchr.c: Add wmemchr support. + * wcsmbs/test-wmemchr.c: New File. + * wcsmbs/Makefile (strop-tests): Add wmemchr. + * benchtests/bench-memchr.c: Add wmemchr support. + * benchtests/bench-wmemchr.c: New File. + * benchtests/Makefile (wcsmbs-bench): wmemchr. +--- + benchtests/Makefile | 3 +- + benchtests/bench-memchr.c | 68 ++++++++----- + benchtests/bench-wmemchr.c | 20 ++++ + string/test-memchr.c | 89 +++++++++++------ + sysdeps/s390/multiarch/Makefile | 7 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 4 + + sysdeps/s390/multiarch/memchr-vx.S | 159 +++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/memchr.c | 24 +++++ + sysdeps/s390/multiarch/rawmemchr-c.c | 34 +++++++ + sysdeps/s390/multiarch/rawmemchr-vx.S | 92 +++++++++++++++++ + sysdeps/s390/multiarch/rawmemchr.c | 28 ++++++ + sysdeps/s390/multiarch/wmemchr-c.c | 31 ++++++ + sysdeps/s390/multiarch/wmemchr-vx.S | 166 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wmemchr.c | 27 +++++ + sysdeps/s390/s390-32/multiarch/memchr.c | 21 ++++ + sysdeps/s390/s390-64/multiarch/memchr.c | 21 ++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wmemchr-ifunc.c | 20 ++++ + wcsmbs/test-wmemchr.c | 20 ++++ + wcsmbs/wmemchr.c | 4 + + 20 files changed, 780 insertions(+), 60 deletions(-) + create mode 100644 benchtests/bench-wmemchr.c + create mode 100644 sysdeps/s390/multiarch/memchr-vx.S + create mode 100644 sysdeps/s390/multiarch/memchr.c + create mode 100644 sysdeps/s390/multiarch/rawmemchr-c.c + create mode 100644 sysdeps/s390/multiarch/rawmemchr-vx.S + create mode 100644 sysdeps/s390/multiarch/rawmemchr.c + create mode 100644 sysdeps/s390/multiarch/wmemchr-c.c + create mode 100644 sysdeps/s390/multiarch/wmemchr-vx.S + create mode 100644 sysdeps/s390/multiarch/wmemchr.c + create mode 100644 sysdeps/s390/s390-32/multiarch/memchr.c + create mode 100644 sysdeps/s390/s390-64/multiarch/memchr.c + create mode 100644 wcsmbs/test-wmemchr-ifunc.c + create mode 100644 wcsmbs/test-wmemchr.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index 4e811a9..b4b3127 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -39,7 +39,8 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ +- wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn ++ wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn \ ++ wmemchr + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-memchr.c b/benchtests/bench-memchr.c +index 30c472c..84a90b4 100644 +--- a/benchtests/bench-memchr.c ++++ b/benchtests/bench-memchr.c +@@ -16,31 +16,51 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifndef WIDE ++# define CHAR char ++# define SMALL_CHAR 127 ++#else ++# include ++# define CHAR wchar_t ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ + #ifndef USE_AS_MEMRCHR + # define TEST_MAIN +-# define TEST_NAME "memchr" ++# ifndef WIDE ++# define TEST_NAME "memchr" ++# else ++# define TEST_NAME "wmemchr" ++# endif /* WIDE */ + # include "bench-string.h" + +-typedef char *(*proto_t) (const char *, int, size_t); +-char *simple_memchr (const char *, int, size_t); ++# ifndef WIDE ++# define MEMCHR memchr ++# define SIMPLE_MEMCHR simple_memchr ++# else ++# define MEMCHR wmemchr ++# define SIMPLE_MEMCHR simple_wmemchr ++# endif /* WIDE */ + +-IMPL (simple_memchr, 0) +-IMPL (memchr, 1) ++typedef CHAR *(*proto_t) (const CHAR *, int, size_t); ++CHAR *SIMPLE_MEMCHR (const CHAR *, int, size_t); + +-char * +-simple_memchr (const char *s, int c, size_t n) ++IMPL (SIMPLE_MEMCHR, 0) ++IMPL (MEMCHR, 1) ++ ++CHAR * ++SIMPLE_MEMCHR (const CHAR *s, int c, size_t n) + { + while (n--) +- if (*s++ == (char) c) +- return (char *) s - 1; ++ if (*s++ == (CHAR) c) ++ return (CHAR *) s - 1; + return NULL; + } +-#endif ++#endif /* !USE_AS_MEMRCHR */ + + static void +-do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res) ++do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res) + { +- char *res = CALL (impl, s, c, n); ++ CHAR *res = CALL (impl, s, c, n); + size_t i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; + +@@ -68,36 +88,38 @@ static void + do_test (size_t align, size_t pos, size_t len, int seek_char) + { + size_t i; +- char *result; ++ CHAR *result; + + align &= 7; +- if (align + len >= page_size) ++ if ((align + len) * sizeof (CHAR) >= page_size) + return; + ++ CHAR *buf = (CHAR *) (buf1); ++ + for (i = 0; i < len; ++i) + { +- buf1[align + i] = 1 + 23 * i % 127; +- if (buf1[align + i] == seek_char) +- buf1[align + i] = seek_char + 1; ++ buf[align + i] = 1 + 23 * i % SMALL_CHAR; ++ if (buf[align + i] == seek_char) ++ buf[align + i] = seek_char + 1; + } +- buf1[align + len] = 0; ++ buf[align + len] = 0; + + if (pos < len) + { +- buf1[align + pos] = seek_char; +- buf1[align + len] = -seek_char; +- result = (char *) (buf1 + align + pos); ++ buf[align + pos] = seek_char; ++ buf[align + len] = -seek_char; ++ result = (CHAR *) (buf1 + align + pos); + } + else + { + result = NULL; +- buf1[align + len] = seek_char; ++ buf[align + len] = seek_char; + } + + printf ("Length %4zd, alignment %2zd:", pos, align); + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); ++ do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result); + + putchar ('\n'); + } +diff --git a/benchtests/bench-wmemchr.c b/benchtests/bench-wmemchr.c +new file mode 100644 +index 0000000..d796a69 +--- /dev/null ++++ b/benchtests/bench-wmemchr.c +@@ -0,0 +1,20 @@ ++/* Measure wmemchr functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-memchr.c" +diff --git a/string/test-memchr.c b/string/test-memchr.c +index cdcceeb..058a837 100644 +--- a/string/test-memchr.c ++++ b/string/test-memchr.c +@@ -18,28 +18,49 @@ + . */ + + #define TEST_MAIN +-#define TEST_NAME "memchr" ++#ifndef WIDE ++# define TEST_NAME "memchr" ++#else ++# define TEST_NAME "wmemchr" ++#endif /* WIDE */ + #include "test-string.h" + +-typedef char *(*proto_t) (const char *, int, size_t); +-char *simple_memchr (const char *, int, size_t); +- +-IMPL (simple_memchr, 0) +-IMPL (memchr, 1) +- +-char * +-simple_memchr (const char *s, int c, size_t n) ++#ifndef WIDE ++# define MEMCHR memchr ++# define CHAR char ++# define UCHAR unsigned char ++# define SIMPLE_MEMCHR simple_memchr ++# define BIG_CHAR CHAR_MAX ++# define SMALL_CHAR 127 ++#else ++# include ++# define MEMCHR wmemchr ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define SIMPLE_MEMCHR simple_wmemchr ++# define BIG_CHAR WCHAR_MAX ++# define SMALL_CHAR 1273 ++#endif /* WIDE */ ++ ++typedef CHAR *(*proto_t) (const CHAR *, int, size_t); ++CHAR *SIMPLE_MEMCHR (const CHAR *, int, size_t); ++ ++IMPL (SIMPLE_MEMCHR, 0) ++IMPL (MEMCHR, 1) ++ ++CHAR * ++SIMPLE_MEMCHR (const CHAR *s, int c, size_t n) + { + while (n--) +- if (*s++ == (char) c) +- return (char *) s - 1; ++ if (*s++ == (CHAR) c) ++ return (CHAR *) s - 1; + return NULL; + } + + static void +-do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res) ++do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res) + { +- char *res = CALL (impl, s, c, n); ++ CHAR *res = CALL (impl, s, c, n); + if (res != exp_res) + { + error (0, 0, "Wrong result in function %s %p %p", impl->name, +@@ -53,34 +74,36 @@ static void + do_test (size_t align, size_t pos, size_t len, int seek_char) + { + size_t i; +- char *result; ++ CHAR *result; + + align &= 7; +- if (align + len >= page_size) ++ if ((align + len) * sizeof (CHAR) >= page_size) + return; + ++ CHAR *buf = (CHAR *) (buf1); ++ + for (i = 0; i < len; ++i) + { +- buf1[align + i] = 1 + 23 * i % 127; +- if (buf1[align + i] == seek_char) +- buf1[align + i] = seek_char + 1; ++ buf[align + i] = 1 + 23 * i % SMALL_CHAR; ++ if (buf[align + i] == seek_char) ++ buf[align + i] = seek_char + 1; + } +- buf1[align + len] = 0; ++ buf[align + len] = 0; + + if (pos < len) + { +- buf1[align + pos] = seek_char; +- buf1[align + len] = -seek_char; +- result = (char *) (buf1 + align + pos); ++ buf[align + pos] = seek_char; ++ buf[align + len] = -seek_char; ++ result = (CHAR *) (buf + align + pos); + } + else + { + result = NULL; +- buf1[align + len] = seek_char; ++ buf[align + len] = seek_char; + } + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char *) (buf1 + align), seek_char, len, result); ++ do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result); + } + + static void +@@ -88,8 +111,8 @@ do_random_tests (void) + { + size_t i, j, n, align, pos, len; + int seek_char; +- char *result; +- unsigned char *p = buf1 + page_size - 512; ++ CHAR *result; ++ UCHAR *p = (UCHAR *) (buf1 + page_size) - 512; + + for (n = 0; n < ITERATIONS; n++) + { +@@ -101,11 +124,11 @@ do_random_tests (void) + if (pos >= len) + len = pos + (random () & 7); + if (len + align >= 512) +- len = 512 - align - (random () & 7); +- seek_char = random () & 255; ++ len = 512 - align - (random () & 7); ++ seek_char = random () & BIG_CHAR; + j = len + align + 64; + if (j > 512) +- j = 512; ++ j = 512; + + for (i = 0; i < j; i++) + { +@@ -113,7 +136,7 @@ do_random_tests (void) + p[i] = seek_char; + else + { +- p[i] = random () & 255; ++ p[i] = random () & BIG_CHAR; + if (i < pos + align && p[i] == seek_char) + p[i] = seek_char + 13; + } +@@ -124,17 +147,17 @@ do_random_tests (void) + size_t r = random (); + if ((r & 31) == 0) + len = ~(uintptr_t) (p + align) - ((r >> 5) & 31); +- result = (char *) (p + pos + align); ++ result = (CHAR *) (p + pos + align); + } + else + result = NULL; + + FOR_EACH_IMPL (impl, 1) +- if (CALL (impl, (char *) (p + align), seek_char, len) != result) ++ if (CALL (impl, (CHAR *) (p + align), seek_char, len) != result) + { + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd, %zd) %p != %p, p %p", + n, impl->name, align, seek_char, len, pos, +- CALL (impl, (char *) (p + align), seek_char, len), ++ CALL (impl, (CHAR *) (p + align), seek_char, len), + result, p); + ret = 1; + } +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 2c1fce0..4a04c34 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -14,7 +14,9 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strrchr strrchr-vx strrchr-c \ + strspn strspn-vx strspn-c \ + strpbrk strpbrk-vx strpbrk-c \ +- strcspn strcspn-vx strcspn-c ++ strcspn strcspn-vx strcspn-c \ ++ memchr memchr-vx \ ++ rawmemchr rawmemchr-vx rawmemchr-c + endif + + ifeq ($(subdir),wcsmbs) +@@ -33,5 +35,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsrchr wcsrchr-vx wcsrchr-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ +- wcscspn wcscspn-vx wcscspn-c ++ wcscspn wcscspn-vx wcscspn-c \ ++ wmemchr wmemchr-vx wmemchr-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 7f62e49..d4c7c0d 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -127,6 +127,10 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (strcspn); + IFUNC_VX_IMPL (wcscspn); + ++ IFUNC_VX_IMPL (memchr); ++ IFUNC_VX_IMPL (wmemchr); ++ IFUNC_VX_IMPL (rawmemchr); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/memchr-vx.S b/sysdeps/s390/multiarch/memchr-vx.S +new file mode 100644 +index 0000000..5c98fd9 +--- /dev/null ++++ b/sysdeps/s390/multiarch/memchr-vx.S +@@ -0,0 +1,159 @@ ++/* Vector optimized 32/64 bit S/390 version of memchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* void *memchr (const void *s, int c, size_t n) ++ Scans memory for character c ++ and returns pointer to first c. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=s ++ -r3=c ++ -r4=n ++ -r5=current_len ++ -v16=part of s ++ -v17=index of found c ++ -v18=c replicated ++*/ ++ENTRY(__memchr_vx) ++ ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgije %r4,0,.Lnf_end /* If len == 0 then exit. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r0,%r0 /* Convert 32bit to 64bit. */ ++ ++ vlvgb %v18,%r3,0 /* Generate vector which elements are all c. ++ if c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ lghi %r5,16 /* current_len = 16. */ ++ ++ clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n, ++ jump to lastcmp. */ ++ ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ vlgvb %r1,%v17,7 /* Load byte index of c. */ ++ clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ ++ aghi %r0,64 ++ clgrjl %r0,%r4,.Lloop64 ++.Llt64: ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */ ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ jl .Lfound /* Jump away if c was found. */ ++ ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfeebs %v17,%v16,%v18 ++ jl .Lfound ++ ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfeebs %v17,%v16,%v18 ++ jl .Lfound ++ ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Llastcmp: ++ /* Use comparision result only if located within first n characters. ++ %r5: current_len; ++ %r4: n; ++ (current_len - n): [0...16[ ++ first ignored match index: vr-width - (current_len - n) ]0...16] ++ */ ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */ ++ lghi %r0,16 /* Register width = 16. */ ++ vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */ ++ slr %r0,%r4 /* %r0 = first ignored match index. */ ++ clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */ ++ /* c not found within n-bytes. */ ++.Lnf_end: ++ lghi %r2,0 /* Return null. */ ++ br %r14 ++ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound0: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r1,%v17,7 /* Load byte index of c. */ ++.Lfound2: ++ slgfi %r5,16 /* current_len -=16 */ ++ algr %r5,%r1 /* Zero byte index is added to current len. */ ++ la %r2,0(%r5,%r2) /* Return pointer to c. */ ++ br %r14 ++ ++ ++.Lloop64: ++ vl %v16,0(%r5,%r2) ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ jl .Lfound0 /* Jump away if c was found. */ ++ vl %v16,16(%r5,%r2) ++ vfeebs %v17,%v16,%v18 ++ jl .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeebs %v17,%v16,%v18 ++ jl .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeebs %v17,%v16,%v18 ++ jl .Lfound48 ++ ++ aghi %r5,64 ++ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ ++ aghi %r0,64 ++ clgrjl %r0,%r4,.Lloop64 ++ ++ j .Llt64 ++END(__memchr_vx) ++ ++# define memchr __memchr_c ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) strong_alias(__memchr_c, __GI_memchr) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ ++ ++#include +diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/multiarch/memchr.c +new file mode 100644 +index 0000000..6624765 +--- /dev/null ++++ b/sysdeps/s390/multiarch/memchr.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of memchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__memchr, memchr) ++#endif +diff --git a/sysdeps/s390/multiarch/rawmemchr-c.c b/sysdeps/s390/multiarch/rawmemchr-c.c +new file mode 100644 +index 0000000..f652133 +--- /dev/null ++++ b/sysdeps/s390/multiarch/rawmemchr-c.c +@@ -0,0 +1,34 @@ ++/* Default rawmemchr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++ ++# define RAWMEMCHR __rawmemchr_c ++# undef weak_alias ++# define weak_alias(a, b) ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__rawmemchr_c, __GI___rawmemchr, __rawmemchr_c); ++# endif /* SHARED */ ++ ++extern __typeof (rawmemchr) __rawmemchr_c attribute_hidden; ++ ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/multiarch/rawmemchr-vx.S b/sysdeps/s390/multiarch/rawmemchr-vx.S +new file mode 100644 +index 0000000..2af4570 +--- /dev/null ++++ b/sysdeps/s390/multiarch/rawmemchr-vx.S +@@ -0,0 +1,92 @@ ++/* Vector optimized 32/64 bit S/390 version of rawmemchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* void *rawmemchr (const void *s, int c) ++ Scans memory for character c ++ and returns pointer to first c. ++ ++ Register usage: ++ -r1=tmp ++ -r2=s ++ -r3=c ++ -r4=tmp ++ -r5=current_len ++ -v16=part of s ++ -v17=index of unequal ++ -v18=c replicated ++*/ ++ENTRY(__rawmemchr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r1,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ ++ vlvgb %v18,%r3,0 /* Generate vector which elements are all c. ++ If c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ ++ vfeeb %v17,%v16,%v18 /* Vector find element equal. */ ++ vlgvb %r5,%v17,7 /* Load byte index of character or zero. */ ++ clrjl %r5,%r1,.Lend_found /* If found c is in loaded bytes, end. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r5,16 ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ /* Find c in a 16byte aligned loop. */ ++.Lloop: ++ vl %v16,0(%r5,%r2) /* Load s. */ ++ vfeebs %v17,%v16,%v18 /* Vector find element equal. */ ++ jno .Lcharacter /* Jump away if element found. */ ++ vl %v16,16(%r5,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lcharacter16 ++ vl %v16,32(%r5,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lcharacter32 ++ vl %v16,48(%r5,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lcharacter48 ++ ++ aghi %r5,64 ++ j .Lloop /* No character found -> loop. */ ++ ++ /* Found character. */ ++.Lcharacter48: ++ aghi %r5,16 ++.Lcharacter32: ++ aghi %r5,16 ++.Lcharacter16: ++ aghi %r5,16 ++.Lcharacter: ++ vlgvb %r1,%v17,7 /* Load byte index of character. */ ++ algr %r5,%r1 ++.Lend_found: ++ la %r2,0(%r5,%r2) /* Return pointer to character. */ ++ br %r14 ++END(__rawmemchr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c +new file mode 100644 +index 0000000..2335289 +--- /dev/null ++++ b/sysdeps/s390/multiarch/rawmemchr.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of rawmemchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__rawmemchr) ++weak_alias (__rawmemchr, rawmemchr) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT &&!defined NOT_IN_libc ) */ +diff --git a/sysdeps/s390/multiarch/wmemchr-c.c b/sysdeps/s390/multiarch/wmemchr-c.c +new file mode 100644 +index 0000000..d4abeb4 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemchr-c.c +@@ -0,0 +1,31 @@ ++/* Default wmemchr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WMEMCHR __wmemchr_c ++ ++# include ++extern __typeof (wmemchr) __wmemchr_c; ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wmemchr_c, __GI_wmemchr, __wmemchr_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wmemchr-vx.S b/sysdeps/s390/multiarch/wmemchr-vx.S +new file mode 100644 +index 0000000..4df08d2 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemchr-vx.S +@@ -0,0 +1,166 @@ ++/* Vector optimized 32/64 bit S/390 version of wmemchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t *wmemchr (const wchar_t *s, wchar_t c, size_t n) ++ Scans memory for character c ++ and returns pointer to first c. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=s ++ -r3=c ++ -r4=n ++ -r5=current_len ++ -v16=part of s ++ -v17=index of found c ++ -v18=c replicated ++*/ ++ENTRY(__wmemchr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ clgije %r4,0,.Lnf_end /* If len == 0 then exit. */ ++ ++ vlbb %v16,0(%r2),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r2),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r0,%r0 /* Convert 32bit to 64bit. */ ++ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ ++ vlvgf %v18,%r3,0 /* Generate vector which elements are all c. */ ++ vrepf %v18,%v18,0 ++ lghi %r5,16 /* current_len = 16. */ ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r1,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ clgrjhe %r0,%r4,.Llastcmp /* If (bytes to boundary) >= n, ++ jump to lastcmp. */ ++ ++ vfeefs %v17,%v16,%v18 /* Find c. */ ++ vlgvb %r1,%v17,7 /* Load byte index of c. */ ++ clgrjl %r1,%r0,.Lfound2 /* Found c is within loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r2,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ slr %r5,%r1 /* Compute bytes to 16bytes boundary. */ ++ ++ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ ++ aghi %r0,64 ++ clgrjl %r0,%r4,.Lloop64 ++.Llt64: ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp /* Do last compare if curr-len >= n. */ ++ vfeefs %v17,%v16,%v18 /* Find c. */ ++ jl .Lfound /* Jump away if c was found. */ ++ ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfeefs %v17,%v16,%v18 ++ jl .Lfound ++ ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ clgrjhe %r5,%r4,.Llastcmp ++ vfeefs %v17,%v16,%v18 ++ jl .Lfound ++ ++ vl %v16,0(%r5,%r2) ++ aghi %r5,16 ++ ++.Llastcmp: ++ /* Use comparision result only if located within first n characters. ++ %r5: current_len; ++ %r4: n; ++ (current_len - n): [0...16[ ++ first ignored match index = vr-width - (current_len - n) ]0...16] ++ */ ++ vfeefs %v17,%v16,%v18 /* Find c. */ ++ slgrk %r4,%r5,%r4 /* %r5 = current_len - n. */ ++ lghi %r0,16 /* Register width = 16. */ ++ vlgvb %r1,%v17,7 /* Extract found index or 16 if all equal. */ ++ slr %r0,%r4 /* %r0 = first ignored match index. */ ++ clrjl %r1,%r0,.Lfound2 /* Go away if miscompare is below n bytes. */ ++ /* c not found within n-bytes. */ ++.Lnf_end: ++ lghi %r2,0 /* Return null. */ ++ br %r14 ++ ++.Lfound48: ++ aghi %r5,16 ++.Lfound32: ++ aghi %r5,16 ++.Lfound16: ++ aghi %r5,16 ++.Lfound0: ++ aghi %r5,16 ++.Lfound: ++ vlgvb %r1,%v17,7 /* Load byte index of c. */ ++.Lfound2: ++ slgfi %r5,16 /* current_len -=16 */ ++ algr %r5,%r1 /* Zero byte index is added to current len. */ ++ la %r2,0(%r5,%r2) /* Return pointer to c. */ ++ br %r14 ++ ++.Lloop64: ++ vl %v16,0(%r5,%r2) ++ vfeefs %v17,%v16,%v18 /* Find c. */ ++ jl .Lfound0 /* Jump away if c was found. */ ++ vl %v16,16(%r5,%r2) ++ vfeefs %v17,%v16,%v18 ++ jl .Lfound16 ++ vl %v16,32(%r5,%r2) ++ vfeefs %v17,%v16,%v18 ++ jl .Lfound32 ++ vl %v16,48(%r5,%r2) ++ vfeefs %v17,%v16,%v18 ++ jl .Lfound48 ++ ++ aghi %r5,64 ++ lgr %r0,%r5 /* If %r5 + 64 < n? -> loop64. */ ++ aghi %r0,64 ++ clgrjl %r0,%r4,.Lloop64 ++ ++ j .Llt64 ++.Lfallback: ++ jg __wmemchr_c ++END(__wmemchr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c +new file mode 100644 +index 0000000..b8b0e83 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemchr.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wmemchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wmemchr, wmemchr) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/sysdeps/s390/s390-32/multiarch/memchr.c b/sysdeps/s390/s390-32/multiarch/memchr.c +new file mode 100644 +index 0000000..00958cd +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memchr.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of memchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/memchr.S will be used. */ ++#include +diff --git a/sysdeps/s390/s390-64/multiarch/memchr.c b/sysdeps/s390/s390-64/multiarch/memchr.c +new file mode 100644 +index 0000000..00958cd +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memchr.c +@@ -0,0 +1,21 @@ ++/* Multiple versions of memchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This wrapper-file is needed, because otherwise file ++ sysdeps/s390/s390-[32|64]/memchr.S will be used. */ ++#include +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index 9730b00..f8bc401 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -43,7 +43,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + + strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ + wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \ +- wcscspn ++ wcscspn wmemchr + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wmemchr-ifunc.c b/wcsmbs/test-wmemchr-ifunc.c +new file mode 100644 +index 0000000..4b40871 +--- /dev/null ++++ b/wcsmbs/test-wmemchr-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wmemchr function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wmemchr.c" +diff --git a/wcsmbs/test-wmemchr.c b/wcsmbs/test-wmemchr.c +new file mode 100644 +index 0000000..90c7f68 +--- /dev/null ++++ b/wcsmbs/test-wmemchr.c +@@ -0,0 +1,20 @@ ++/* Test wmemchr functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-memchr.c" +diff --git a/wcsmbs/wmemchr.c b/wcsmbs/wmemchr.c +index 99ebed4..905a321 100644 +--- a/wcsmbs/wmemchr.c ++++ b/wcsmbs/wmemchr.c +@@ -18,6 +18,10 @@ + + #include + ++#ifdef WMEMCHR ++# define wmemchr WMEMCHR ++#endif ++ + wchar_t * + wmemchr (s, c, n) + register const wchar_t *s; +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-27.patch b/SOURCES/glibc-rh1268008-27.patch new file mode 100644 index 00000000..3d62e8e2 --- /dev/null +++ b/SOURCES/glibc-rh1268008-27.patch @@ -0,0 +1,306 @@ +From 130a0ae7cad6bc7a2d102624027a1d8de19cc3b3 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 13:21:11 +0200 +Subject: [PATCH 27/30] S390: Optimize memccpy. + +upstream-commit-id: 9b593dc3055d44a4179c03050be58a437ae385a1 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00100.html + +This patch provides optimized versions of memccpy with the z13 vector +instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/memccpy-c.c: New File. + * sysdeps/s390/multiarch/memccpy-vx.S: Likewise. + * sysdeps/s390/multiarch/memccpy.c: Likewise. + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Add memccpy functions. + * sysdeps/s390/multiarch/ifunc-impl-list-common.c + (__libc_ifunc_impl_list_common): Add ifunc test for memccpy. + * string/memccpy.c: Use MEMCCPY if defined. +--- + string/memccpy.c | 4 + + sysdeps/s390/multiarch/Makefile | 3 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 2 + + sysdeps/s390/multiarch/memccpy-c.c | 27 ++++++ + sysdeps/s390/multiarch/memccpy-vx.S | 156 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/memccpy.c | 28 ++++++ + 6 files changed, 219 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/s390/multiarch/memccpy-c.c + create mode 100644 sysdeps/s390/multiarch/memccpy-vx.S + create mode 100644 sysdeps/s390/multiarch/memccpy.c + +diff --git a/string/memccpy.c b/string/memccpy.c +index a8649ff..78c13b6 100644 +--- a/string/memccpy.c ++++ b/string/memccpy.c +@@ -20,6 +20,10 @@ + #undef __memccpy + #undef memccpy + ++#ifdef MEMCCPY ++# define __memccpy MEMCCPY ++#endif ++ + /* Copy no more than N bytes of SRC to DEST, stopping when C is found. + Return the position in DEST one byte past where C was copied, or + NULL if C was not found in the first N bytes of SRC. */ +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 4a04c34..87dff0f 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -16,7 +16,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strpbrk strpbrk-vx strpbrk-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ +- rawmemchr rawmemchr-vx rawmemchr-c ++ rawmemchr rawmemchr-vx rawmemchr-c \ ++ memccpy memccpy-vx memccpy-c + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index d4c7c0d..c90fb6b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -131,6 +131,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_VX_IMPL (wmemchr); + IFUNC_VX_IMPL (rawmemchr); + ++ IFUNC_VX_IMPL (memccpy); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/memccpy-c.c b/sysdeps/s390/multiarch/memccpy-c.c +new file mode 100644 +index 0000000..4d07b63 +--- /dev/null ++++ b/sysdeps/s390/multiarch/memccpy-c.c +@@ -0,0 +1,27 @@ ++/* Default memccpy implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define MEMCCPY __memccpy_c ++# undef weak_alias ++# define weak_alias(a, b) ++ ++# include ++extern __typeof (__memccpy) __memccpy_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/memccpy-vx.S b/sysdeps/s390/multiarch/memccpy-vx.S +new file mode 100644 +index 0000000..b1dc69c +--- /dev/null ++++ b/sysdeps/s390/multiarch/memccpy-vx.S +@@ -0,0 +1,156 @@ ++/* Vector optimized 32/64 bit S/390 version of memccpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* void *memccpy (void * dest, const void *src, int c, size_t n) ++ Copies no more than n bytes from src to dest, ++ stopping when the character c is found ++ and returns pointer next to c in dest or null if c not found. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=dest ++ -r3=src ++ -r4=c ++ -r5=n ++ -r6=current_len ++ -v16=part of s ++ -v17=index of found c ++ -v18=c replicated ++ -v19=part #2 of s ++ -v31=save area for r6 ++*/ ++ENTRY(__memccpy_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r5,%r5 ++# endif /* !defined __s390x__ */ ++ ++ vlvgp %v31,%r6,%r7 /* Save registers. */ ++ clgije %r5,0,.Lnf_end /* If len == 0 then exit. */ ++ ++ vlbb %v16,0(%r3),6 /* Load s until next 4k-byte boundary. */ ++ lcbb %r0,0(%r3),6 /* Get bytes to 4k-byte boundary or 16. */ ++ llgfr %r0,%r0 /* Convert 32bit to 64bit. */ ++ ++ vlvgb %v18,%r4,0 /* Generate vector which elements are all c. ++ if c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ lghi %r6,0 /* current_len = 0. */ ++ ++ clgrjle %r5,%r0,.Lremaining_v16 /* If maxlen <= loaded-bytes ++ -> Process remaining. */ ++ ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ vlgvb %r1,%v17,7 /* Load byte index of c. */ ++ clgrjl %r1,%r0,.Lfound_v16 /* Found c is within loaded bytes. */ ++ ++ /* Align s to 16 byte. */ ++ risbgn %r1,%r3,60,128+63,0 /* %r3 = bits 60-63 of %r2 'and' 15. */ ++ lghi %r6,15 /* current_len = 15. */ ++ slr %r6,%r1 /* Compute highest index to 16byte boundary. */ ++ ++ vstl %v16,%r6,0(%r2) /* Store prcessed bytes */ ++ ahi %r6,1 ++ ++.Lpreloop1: ++ /* Now we are 16byte aligned, so we can load ++ a full vreg without page fault. */ ++ vl %v16,0(%r6,%r3) /* Load s. */ ++ clgijl %r5,17,.Lremaining_v16 /* If n <= 16, ++ process remaining bytes. */ ++ lgr %r7,%r5 ++ slgfi %r7,16 /* border_len = n - 16. */ ++ j .Lloop1 ++ ++.Lloop2: ++ vl %v16,16(%r6,%r3) ++ vst %v19,0(%r6,%r2) ++ aghi %r6,16 ++ ++.Lloop1: ++ clgrjhe %r6,%r7,.Lremaining_v16 /* If current_len >= border ++ then process remaining bytes. */ ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ jl .Lfound_v16 /* Jump away if c was found. */ ++ vl %v19,16(%r6,%r3) /* Load next s part. */ ++ vst %v16,0(%r6,%r2) /* Store previous part without c. */ ++ aghi %r6,16 ++ ++ clgrjhe %r6,%r7,.Lremaining_v19 ++ vfeebs %v17,%v19,%v18 ++ jl .Lfound_v19 ++ vl %v16,16(%r6,%r3) ++ vst %v19,0(%r6,%r2) ++ aghi %r6,16 ++ ++ clgrjhe %r6,%r7,.Lremaining_v16 ++ vfeebs %v17,%v16,%v18 ++ jl .Lfound_v16 ++ vl %v19,16(%r6,%r3) ++ vst %v16,0(%r6,%r2) ++ aghi %r6,16 ++ ++ clgrjhe %r6,%r7,.Lremaining_v19 ++ vfeebs %v17,%v19,%v18 ++ jo .Lloop2 ++ ++.Lfound_v19: ++ vlr %v16,%v19 ++.Lfound_v16: ++ /* v16 contains c. Store remaining bytes to c. currlen hasn´t ++ reached border, thus checking for maxlen is not needed! */ ++ vlgvb %r1,%v17,7 /* Load byte index of c. */ ++ la %r2,0(%r6,%r2) /* vstl has no support for index-register. */ ++.Lfound_v16_store: ++ vstl %v16,%r1,0(%r2) /* Copy bytes including c. */ ++ la %r2,1(%r1,%r2) /* Return pointer next to c in dest. */ ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ br %r14 ++ ++.Lremaining_v19: ++ vlr %v16,%v19 ++.Lremaining_v16: ++ /* v16 contains the remaining bytes [1...16]. ++ Check and store remaining bytes. */ ++ vfeebs %v17,%v16,%v18 ++ slgrk %r7,%r5,%r6 /* Remaining bytes = maxlen - current_len. */ ++ aghi %r7,-1 /* vstl needs highest index. */ ++ la %r2,0(%r6,%r2) /* vstl has no index register. */ ++ vlgvb %r1,%v17,7 /* Load index of c or 16 if not found. */ ++ /* c in remaining bytes? -> Jump away (c-index <= max-index) */ ++ clrjle %r1,%r7,.Lfound_v16_store ++ vstl %v16,%r7,0(%r2) /* Store remaining bytes. */ ++ ++.Lnf_end: ++ vlgvg %r6,%v31,0 ++ vlgvg %r7,%v31,1 ++ lghi %r2,0 /* Return null. */ ++ br %r14 ++END(__memccpy_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/memccpy.c b/sysdeps/s390/multiarch/memccpy.c +new file mode 100644 +index 0000000..746bc25 +--- /dev/null ++++ b/sysdeps/s390/multiarch/memccpy.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of memccpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__memccpy) ++weak_alias (__memccpy, memccpy) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-28.patch b/SOURCES/glibc-rh1268008-28.patch new file mode 100644 index 00000000..c37faf60 --- /dev/null +++ b/SOURCES/glibc-rh1268008-28.patch @@ -0,0 +1,737 @@ +From f0954299ecdccf6a70cf904b8f499d15a5af3928 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 13:22:47 +0200 +Subject: [PATCH 28/30] S390: Optimize wmemset. + +upstream-commit-id: 2e9e166761fed5dfaa53480412bef0656f1b5306 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00078.html + +This patch provides optimized version of wmemset with the z13 vector +instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/wmemset-c.c: New File. + * sysdeps/s390/multiarch/wmemset-vx.S: Likewise. + * sysdeps/s390/multiarch/wmemset.c: Likewise. + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Add wmemset functions. + * sysdeps/s390/multiarch/ifunc-impl-list-common.c + (__libc_ifunc_impl_list_common): Add ifunc test for wmemset. + * wcsmbs/wmemset.c: Use WMEMSET if defined. + * string/test-memset.c: Add wmemset support. + * wcsmbs/test-wmemset.c: New File. + * wcsmbs/Makefile (strop-tests): Add wmemset. + * benchtests/bench-memset.c: Add wmemset support. + * benchtests/bench-wmemset.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wmemset. +--- + benchtests/Makefile | 2 +- + benchtests/bench-memset.c | 63 +++++++++----- + benchtests/bench-wmemset.c | 20 +++++ + string/test-memset.c | 88 ++++++++++++------- + sysdeps/s390/multiarch/Makefile | 3 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 2 + + sysdeps/s390/multiarch/wmemset-c.c | 31 +++++++ + sysdeps/s390/multiarch/wmemset-vx.S | 142 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wmemset.c | 27 ++++++ + wcsmbs/Makefile | 2 +- + wcsmbs/test-wmemset-ifunc.c | 20 +++++ + wcsmbs/test-wmemset.c | 20 +++++ + wcsmbs/wmemset.c | 3 + + 13 files changed, 368 insertions(+), 55 deletions(-) + create mode 100644 benchtests/bench-wmemset.c + create mode 100644 sysdeps/s390/multiarch/wmemset-c.c + create mode 100644 sysdeps/s390/multiarch/wmemset-vx.S + create mode 100644 sysdeps/s390/multiarch/wmemset.c + create mode 100644 wcsmbs/test-wmemset-ifunc.c + create mode 100644 wcsmbs/test-wmemset.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index b4b3127..b5edfdd 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -40,7 +40,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ + wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn \ +- wmemchr ++ wmemchr wmemset + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-memset.c b/benchtests/bench-memset.c +index 9786ce7..66c3c45 100644 +--- a/benchtests/bench-memset.c ++++ b/benchtests/bench-memset.c +@@ -20,12 +20,29 @@ + #ifdef TEST_BZERO + # define TEST_NAME "bzero" + #else +-# define TEST_NAME "memset" +-#endif ++# ifndef WIDE ++# define TEST_NAME "memset" ++# else ++# define TEST_NAME "wmemset" ++# endif /* WIDE */ ++#endif /* !TEST_BZERO */ + #define MIN_PAGE_SIZE 131072 + #include "bench-string.h" + +-char *simple_memset (char *, int, size_t); ++#ifndef WIDE ++# define MEMSET memset ++# define CHAR char ++# define SIMPLE_MEMSET simple_memset ++# define MEMCMP memcmp ++#else ++# include ++# define MEMSET wmemset ++# define CHAR wchar_t ++# define SIMPLE_MEMSET simple_wmemset ++# define MEMCMP wmemcmp ++#endif /* WIDE */ ++ ++CHAR *SIMPLE_MEMSET (CHAR *, int, size_t); + + #ifdef TEST_BZERO + typedef void (*proto_t) (char *, size_t); +@@ -39,7 +56,7 @@ IMPL (bzero, 1) + void + simple_bzero (char *s, size_t n) + { +- simple_memset (s, 0, n); ++ SIMPLE_MEMSET (s, 0, n); + } + + void +@@ -48,46 +65,50 @@ builtin_bzero (char *s, size_t n) + __builtin_bzero (s, n); + } + #else +-typedef char *(*proto_t) (char *, int, size_t); +-char *builtin_memset (char *, int, size_t); ++typedef CHAR *(*proto_t) (CHAR *, int, size_t); + +-IMPL (simple_memset, 0) ++IMPL (SIMPLE_MEMSET, 0) ++# ifndef WIDE ++char *builtin_memset (char *, int, size_t); + IMPL (builtin_memset, 0) +-IMPL (memset, 1) ++# endif /* !WIDE */ ++IMPL (MEMSET, 1) + ++# ifndef WIDE + char * + builtin_memset (char *s, int c, size_t n) + { + return __builtin_memset (s, c, n); + } +-#endif ++# endif /* !WIDE */ ++#endif /* !TEST_BZERO */ + +-char * ++CHAR * + inhibit_loop_to_libcall +-simple_memset (char *s, int c, size_t n) ++SIMPLE_MEMSET (CHAR *s, int c, size_t n) + { +- char *r = s, *end = s + n; ++ CHAR *r = s, *end = s + n; + while (r < end) + *r++ = c; + return s; + } + + static void +-do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n) ++do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n) + { + size_t i, iters = INNER_LOOP_ITERS; + timing_t start, stop, cur; +- char tstbuf[n]; ++ CHAR tstbuf[n]; + #ifdef TEST_BZERO + simple_bzero (tstbuf, n); + CALL (impl, s, n); + if (memcmp (s, tstbuf, n) != 0) + #else +- char *res = CALL (impl, s, c, n); ++ CHAR *res = CALL (impl, s, c, n); + if (res != s +- || simple_memset (tstbuf, c, n) != tstbuf +- || memcmp (s, tstbuf, n) != 0) +-#endif ++ || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf ++ || MEMCMP (s, tstbuf, n) != 0) ++#endif /* !TEST_BZERO */ + { + error (0, 0, "Wrong result in function %s", impl->name); + ret = 1; +@@ -101,7 +122,7 @@ do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n) + CALL (impl, s, n); + #else + CALL (impl, s, c, n); +-#endif ++#endif /* !TEST_BZERO */ + } + TIMING_NOW (stop); + +@@ -114,13 +135,13 @@ static void + do_test (size_t align, int c, size_t len) + { + align &= 7; +- if (align + len > page_size) ++ if ((align + len) * sizeof (CHAR) > page_size) + return; + + printf ("Length %4zd, alignment %2zd, c %2d:", len, align, c); + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char *) buf1 + align, c, len); ++ do_one_test (impl, (CHAR *) (buf1) + align, c, len); + + putchar ('\n'); + } +diff --git a/benchtests/bench-wmemset.c b/benchtests/bench-wmemset.c +new file mode 100644 +index 0000000..540829c +--- /dev/null ++++ b/benchtests/bench-wmemset.c +@@ -0,0 +1,20 @@ ++/* Measure wmemset functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-memset.c" +diff --git a/string/test-memset.c b/string/test-memset.c +index e556a88..99fc282 100644 +--- a/string/test-memset.c ++++ b/string/test-memset.c +@@ -21,12 +21,33 @@ + #ifdef TEST_BZERO + # define TEST_NAME "bzero" + #else +-# define TEST_NAME "memset" +-#endif ++# ifndef WIDE ++# define TEST_NAME "memset" ++# else ++# define TEST_NAME "wmemset" ++# endif /* WIDE */ ++#endif /* !TEST_BZERO */ + #define MIN_PAGE_SIZE 131072 + #include "test-string.h" + +-char *simple_memset (char *, int, size_t); ++#ifndef WIDE ++# define MEMSET memset ++# define CHAR char ++# define UCHAR unsigned char ++# define SIMPLE_MEMSET simple_memset ++# define MEMCMP memcmp ++# define BIG_CHAR CHAR_MAX ++#else ++# include ++# define MEMSET wmemset ++# define CHAR wchar_t ++# define UCHAR wchar_t ++# define SIMPLE_MEMSET simple_wmemset ++# define MEMCMP wmemcmp ++# define BIG_CHAR WCHAR_MAX ++#endif /* WIDE */ ++ ++CHAR *SIMPLE_MEMSET (CHAR *, int, size_t); + + #ifdef TEST_BZERO + typedef void (*proto_t) (char *, size_t); +@@ -40,7 +61,7 @@ IMPL (bzero, 1) + void + simple_bzero (char *s, size_t n) + { +- simple_memset (s, 0, n); ++ SIMPLE_MEMSET (s, 0, n); + } + + void +@@ -49,44 +70,48 @@ builtin_bzero (char *s, size_t n) + __builtin_bzero (s, n); + } + #else +-typedef char *(*proto_t) (char *, int, size_t); +-char *builtin_memset (char *, int, size_t); ++typedef CHAR *(*proto_t) (CHAR *, int, size_t); + +-IMPL (simple_memset, 0) ++IMPL (SIMPLE_MEMSET, 0) ++# ifndef WIDE ++char *builtin_memset (char *, int, size_t); + IMPL (builtin_memset, 0) +-IMPL (memset, 1) ++# endif /* !WIDE */ ++IMPL (MEMSET, 1) + ++# ifndef WIDE + char * + builtin_memset (char *s, int c, size_t n) + { + return __builtin_memset (s, c, n); + } +-#endif ++# endif /* !WIDE */ ++#endif /* !TEST_BZERO */ + +-char * ++CHAR * + inhibit_loop_to_libcall +-simple_memset (char *s, int c, size_t n) ++SIMPLE_MEMSET (CHAR *s, int c, size_t n) + { +- char *r = s, *end = s + n; ++ CHAR *r = s, *end = s + n; + while (r < end) + *r++ = c; + return s; + } + + static void +-do_one_test (impl_t *impl, char *s, int c __attribute ((unused)), size_t n) ++do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n) + { +- char tstbuf[n]; ++ CHAR tstbuf[n]; + #ifdef TEST_BZERO + simple_bzero (tstbuf, n); + CALL (impl, s, n); + if (memcmp (s, tstbuf, n) != 0) + #else +- char *res = CALL (impl, s, c, n); ++ CHAR *res = CALL (impl, s, c, n); + if (res != s +- || simple_memset (tstbuf, c, n) != tstbuf +- || memcmp (s, tstbuf, n) != 0) +-#endif ++ || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf ++ || MEMCMP (s, tstbuf, n) != 0) ++#endif /* !TEST_BZERO */ + { + error (0, 0, "Wrong result in function %s", impl->name); + ret = 1; +@@ -98,11 +123,11 @@ static void + do_test (size_t align, int c, size_t len) + { + align &= 7; +- if (align + len > page_size) ++ if ((align + len) * sizeof (CHAR) > page_size) + return; + + FOR_EACH_IMPL (impl, 0) +- do_one_test (impl, (char *) buf1 + align, c, len); ++ do_one_test (impl, (CHAR *) (buf1) + align, c, len); + } + + #ifndef TEST_BZERO +@@ -111,18 +136,19 @@ do_random_tests (void) + { + size_t i, j, k, n, align, len, size; + int c, o; +- unsigned char *p, *res; ++ UCHAR *p, *res; ++ UCHAR *p2 = (UCHAR *) buf2; + +- for (i = 0; i < 65536; ++i) +- buf2[i] = random () & 255; ++ for (i = 0; i < 65536 / sizeof (CHAR); ++i) ++ p2[i] = random () & BIG_CHAR; + + for (n = 0; n < ITERATIONS; n++) + { + if ((random () & 31) == 0) +- size = 65536; ++ size = 65536 / sizeof (CHAR); + else + size = 512; +- p = buf1 + page_size - size; ++ p = (UCHAR *) (buf1 + page_size) - size; + len = random () & (size - 1); + align = size - len - (random () & 31); + if (align > size) +@@ -132,10 +158,10 @@ do_random_tests (void) + if ((random () & 7) == 0) + c = 0; + else +- c = random () & 255; +- o = random () & 255; ++ c = random () & BIG_CHAR; ++ o = random () & BIG_CHAR; + if (o == c) +- o = (c + 1) & 255; ++ o = (c + 1) & BIG_CHAR; + j = len + align + 128; + if (j > size) + j = size; +@@ -152,11 +178,11 @@ do_random_tests (void) + { + for (i = 0; i < len; ++i) + { +- p[i + align] = buf2[i]; ++ p[i + align] = p2[i]; + if (p[i + align] == c) + p[i + align] = o; + } +- res = (unsigned char *) CALL (impl, (char *) p + align, c, len); ++ res = (UCHAR *) CALL (impl, (CHAR *) p + align, c, len); + if (res != p + align) + { + error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd) %p != %p", +@@ -190,7 +216,7 @@ do_random_tests (void) + } + } + } +-#endif ++#endif /* !TEST_BZERO */ + + int + test_main (void) +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 87dff0f..eac88e0 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -37,5 +37,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcsspn wcsspn-vx wcsspn-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ +- wmemchr wmemchr-vx wmemchr-c ++ wmemchr wmemchr-vx wmemchr-c \ ++ wmemset wmemset-vx wmemset-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index c90fb6b..44d534b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -133,6 +133,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (memccpy); + ++ IFUNC_VX_IMPL (wmemset); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/wmemset-c.c b/sysdeps/s390/multiarch/wmemset-c.c +new file mode 100644 +index 0000000..59c9a7e +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemset-c.c +@@ -0,0 +1,31 @@ ++/* Default wmemset implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WMEMSET __wmemset_c ++ ++# include ++extern __typeof (wmemset) __wmemset_c; ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wmemset_c, __GI_wmemset, __wmemset_c); ++# endif /* SHARED */ ++ ++# include ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wmemset-vx.S b/sysdeps/s390/multiarch/wmemset-vx.S +new file mode 100644 +index 0000000..dae2c29 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemset-vx.S +@@ -0,0 +1,142 @@ ++/* Vector Optimized 32/64 bit S/390 version of wmemset. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* wchar_t *wmemset(wchar_t *dest, wchar_t wc, size_t n) ++ Fill an array of wide-characters with a constant wide character ++ and returns dest. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=dest or current-pointer ++ -r3=wc ++ -r4=n ++ -r5=tmp ++ -v16=replicated wc ++ -v17,v18,v19=copy of v16 for vstm ++ -v31=saved dest for return ++*/ ++ENTRY(__wmemset_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ ++ vlvgg %v31,%r2,0 /* Save destination pointer for return. */ ++ clgije %r4,0,.Lend ++ ++ vlvgf %v16,%r3,0 /* Generate vector with wchar_t wc. */ ++ vrepf %v16,%v16,0 ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r5,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r5,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r5 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ /* Align dest to 16 byte. */ ++ risbg %r0,%r2,60,128+63,0 /* Test if s is aligned and ++ %r3 = bits 60-63 'and' 15. */ ++ je .Lpreloop /* If s is aligned, loop aligned. */ ++ tmll %r2,3 /* Test if s is 4-byte aligned? */ ++ jne .Lfallback /* And use common-code variant if not. */ ++ lghi %r1,16 ++ slr %r1,%r0 /* Compute byte count to load (16-x). */ ++ clgr %r1,%r4 ++ locgrh %r1,%r4 /* min (byte count, n) */ ++ aghik %r5,%r1,-1 /* vstl needs highest index. */ ++ vstl %v16,%r5,0(%r2) /* Store remaining bytes. */ ++ clgrje %r1,%r4,.Lend /* Return if n bytes where set. */ ++ slgr %r4,%r1 /* Compute remaining byte count. */ ++ la %r2,0(%r1,%r2) ++ ++.Lpreloop: ++ /* Now we are 16-byte aligned. */ ++ clgijl %r4,17,.Lremaining ++ srlg %r1,%r4,8 /* Split into 256byte blocks */ ++ clgije %r1,0,.Lpreloop64 ++ vlr %v17,%v16 ++ vlr %v18,%v16 ++ vlr %v19,%v16 ++ ++.Lloop256: ++ vstm %v16,%v19,0(%r2) ++ vstm %v16,%v19,64(%r2) ++ vstm %v16,%v19,128(%r2) ++ vstm %v16,%v19,192(%r2) ++ la %r2,256(%r2) ++ brctg %r1,.Lloop256 /* Loop until all blocks are processed. */ ++ ++ llgfr %r4,%r4 ++ nilf %r4,255 /* Get remaining bytes */ ++ je .Lend /* Skip store remaining bytes if zero. */ ++ ++.Lpreloop64: ++ clgijl %r4,17,.Lremaining ++ clgijl %r4,33,.Lpreloop16 ++ srlg %r1,%r4,5 /* Split into 32byte blocks */ ++ ++.Lloop32: ++ vst %v16,0(%r2) ++ vst %v16,16(%r2) ++ la %r2,32(%r2) ++ brctg %r1,.Lloop32 /* Loop until all blocks are processed. */ ++ ++ llgfr %r4,%r4 ++ nilf %r4,31 /* Get remaining bytes */ ++ je .Lend /* Skip store remaining bytes if zero. */ ++ ++.Lpreloop16: ++ clgijl %r4,17,.Lremaining ++ srlg %r1,%r4,4 /* Split into 16byte blocks */ ++ ++.Lloop16: ++ vst %v16,0(%r2) ++ la %r2,16(%r2) ++ brctg %r1,.Lloop16 /* Loop until all blocks are processed. */ ++ ++ llgfr %r4,%r4 ++ nilf %r4,15 /* Get remaining bytes */ ++ je .Lend /* Skip store remaining bytes if zero. */ ++ ++.Lremaining: ++ aghi %r4,-1 /* vstl needs highest index. */ ++ vstl %v16,%r4,0(%r2) ++ ++.Lend: ++ vlgvg %r2,%v31,0 /* Load saved dest for return value. */ ++ br %r14 ++.Lfallback: ++ srlg %r4,%r4,2 /* Convert byte-count to character-count. */ ++ jg __wmemset_c ++END(__wmemset_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c +new file mode 100644 +index 0000000..1225fc1 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemset.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wmemset. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wmemset, wmemset) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile +index f8bc401..1ca3ace 100644 +--- a/wcsmbs/Makefile ++++ b/wcsmbs/Makefile +@@ -43,7 +43,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \ + + strop-tests := wcscmp wcsncmp wmemcmp wcslen wcschr wcsrchr wcscpy wcsnlen \ + wcpcpy wcsncpy wcpncpy wcscat wcsncat wcschrnul wcsspn wcspbrk \ +- wcscspn wmemchr ++ wcscspn wmemchr wmemset + tests := tst-wcstof wcsmbs-tst1 tst-wcsnlen tst-btowc tst-mbrtowc \ + tst-wcrtomb tst-wcpncpy tst-mbsrtowcs tst-wchar-h tst-mbrtowc2 \ + tst-c16c32-1 wcsatcliff $(addprefix test-,$(strop-tests)) +diff --git a/wcsmbs/test-wmemset-ifunc.c b/wcsmbs/test-wmemset-ifunc.c +new file mode 100644 +index 0000000..b58b6bd +--- /dev/null ++++ b/wcsmbs/test-wmemset-ifunc.c +@@ -0,0 +1,20 @@ ++/* Test and measure IFUNC implementations of wmemset function. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_IFUNC 1 ++#include "test-wmemset.c" +diff --git a/wcsmbs/test-wmemset.c b/wcsmbs/test-wmemset.c +new file mode 100644 +index 0000000..c03c759 +--- /dev/null ++++ b/wcsmbs/test-wmemset.c +@@ -0,0 +1,20 @@ ++/* Test wmemset functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "../string/test-memset.c" +diff --git a/wcsmbs/wmemset.c b/wcsmbs/wmemset.c +index cc9a725..8049bb8 100644 +--- a/wcsmbs/wmemset.c ++++ b/wcsmbs/wmemset.c +@@ -18,6 +18,9 @@ + + #include + ++#ifdef WMEMSET ++# define wmemset WMEMSET ++#endif + + wchar_t * + wmemset (s, c, n) +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-29.patch b/SOURCES/glibc-rh1268008-29.patch new file mode 100644 index 00000000..1e6318c0 --- /dev/null +++ b/SOURCES/glibc-rh1268008-29.patch @@ -0,0 +1,322 @@ +From f34499b3a506359f84fcb63a125e44d4a8e4ee68 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 13:23:50 +0200 +Subject: [PATCH 29/30] S390: Optimize wmemcmp. + +upstream-commit-id: f21216015b7395c535abc01b9585a1ae3ceaa132 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00086.html + +This patch provides optimized version of wmemcmp with the z13 vector +instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/wmemcmp-c.c: New File. + * sysdeps/s390/multiarch/wmemcmp-vx.S: Likewise. + * sysdeps/s390/multiarch/wmemcmp.c: Likewise. + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Add wmemcmp functions. + * sysdeps/s390/multiarch/ifunc-impl-list-common.c + (__libc_ifunc_impl_list_common): Add ifunc test for wmemcmp. + * benchtests/bench-wmemcmp.c: New File. + * benchtests/Makefile (wcsmbs-bench): Add wmemcmp. +--- + benchtests/Makefile | 2 +- + benchtests/bench-wmemcmp.c | 20 +++++ + sysdeps/s390/multiarch/Makefile | 3 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 2 + + sysdeps/s390/multiarch/wmemcmp-c.c | 26 ++++++ + sysdeps/s390/multiarch/wmemcmp-vx.S | 149 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/wmemcmp.c | 27 ++++++ + 7 files changed, 227 insertions(+), 2 deletions(-) + create mode 100644 benchtests/bench-wmemcmp.c + create mode 100644 sysdeps/s390/multiarch/wmemcmp-c.c + create mode 100644 sysdeps/s390/multiarch/wmemcmp-vx.S + create mode 100644 sysdeps/s390/multiarch/wmemcmp.c + +diff --git a/benchtests/Makefile b/benchtests/Makefile +index b5edfdd..911b6df 100644 +--- a/benchtests/Makefile ++++ b/benchtests/Makefile +@@ -40,7 +40,7 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \ + strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok + wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \ + wcsncmp wcsncmp wcschr wcschrnul wcsrchr wcsspn wcspbrk wcscspn \ +- wmemchr wmemset ++ wmemchr wmemset wmemcmp + string-bench-all := $(string-bench) ${wcsmbs-bench} + + stdlib-bench := strtod +diff --git a/benchtests/bench-wmemcmp.c b/benchtests/bench-wmemcmp.c +new file mode 100644 +index 0000000..8b33f89 +--- /dev/null ++++ b/benchtests/bench-wmemcmp.c +@@ -0,0 +1,20 @@ ++/* Measure wmemcmp functions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WIDE 1 ++#include "bench-memcmp.c" +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index eac88e0..929a545 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -38,5 +38,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wcspbrk wcspbrk-vx wcspbrk-c \ + wcscspn wcscspn-vx wcscspn-c \ + wmemchr wmemchr-vx wmemchr-c \ +- wmemset wmemset-vx wmemset-c ++ wmemset wmemset-vx wmemset-c \ ++ wmemcmp wmemcmp-vx wmemcmp-c + endif +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 44d534b..5ea258b 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -135,6 +135,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wmemset); + ++ IFUNC_VX_IMPL (wmemcmp); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/wmemcmp-c.c b/sysdeps/s390/multiarch/wmemcmp-c.c +new file mode 100644 +index 0000000..b43e5d4 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemcmp-c.c +@@ -0,0 +1,26 @@ ++/* Default wmemcmp implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define WMEMCMP __wmemcmp_c ++ ++# include ++extern __typeof (wmemcmp) __wmemcmp_c; ++ ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/wmemcmp-vx.S b/sysdeps/s390/multiarch/wmemcmp-vx.S +new file mode 100644 +index 0000000..b509bef +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemcmp-vx.S +@@ -0,0 +1,149 @@ ++/* Vector Optimized 32/64 bit S/390 version of wmemcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* int wmemcmp (const wchar_t *s1, const wchar_t *s2, size_t n) ++ Compare at most n characters of two wchar_t-arrays. ++ ++ Register usage: ++ -r0=tmp ++ -r1=number of blocks ++ -r2=s1 ++ -r3=s2 ++ -r4=n ++ -r5=current_len ++ -v16=part of s1 ++ -v17=part of s2 ++ -v18=index of unequal ++*/ ++ENTRY(__wmemcmp_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ clgije %r4,0,.Lend_equal /* Nothing to do if n == 0. */ ++ ++ /* Check range of maxlen and convert to byte-count. */ ++# ifdef __s390x__ ++ tmhh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ lghi %r1,-4 /* Max byte-count is 18446744073709551612. */ ++# else ++ tmlh %r4,49152 /* Test bit 0 or 1 of maxlen. */ ++ llilf %r1,4294967292 /* Max byte-count is 4294967292. */ ++# endif /* !__s390x__ */ ++ sllg %r4,%r4,2 /* Convert character-count to byte-count. */ ++ locgrne %r4,%r1 /* Use max byte-count, if bit 0/1 was one. */ ++ ++ lghi %r5,0 /* current_len = 0. */ ++ ++ clgijh %r4,16,.Lgt16 ++ ++.Lremaining: ++ aghi %r4,-1 /* vstl needs highest index. */ ++ vll %v16,%r4,0(%r2) ++ vll %v17,%r4,0(%r3) ++ vfenef %v18,%v16,%v17 /* Compare not equal. */ ++ vlgvb %r1,%v18,7 /* Load unequal index or 16 if not found. */ ++ clrj %r1,%r4,12,.Lfound2 /* r1 <= r4 -> unequal within loaded ++ bytes. */ ++ ++.Lend_equal: ++ lghi %r2,0 ++ br %r14 ++ ++.Lfound: ++ /* vfenezf found an unequal element or zero. ++ This instruction compares unsigned words, but wchar_t is signed. ++ Thus we have to compare the found element again. */ ++ vlgvb %r1,%v18,7 /* Extract not equal byte-index. */ ++.Lfound2: ++ srl %r1,2 /* And convert it to character-index. */ ++ vlgvf %r0,%v16,0(%r1) /* Load character-values. */ ++ vlgvf %r1,%v17,0(%r1) ++ cr %r0,%r1 ++ je .Lend_equal ++ lghi %r2,1 ++ lghi %r1,-1 ++ locgrl %r2,%r1 ++ br %r14 ++ ++.Lgt16: ++ clgijh %r4,64,.Lpreloop64 ++ ++.Lpreloop16: ++ srlg %r1,%r4,4 /* Split into 16byte blocks */ ++.Lloop16: ++ vl %v16,0(%r5,%r2) ++ vl %v17,0(%r5,%r3) ++ aghi %r5,16 ++ vfenefs %v18,%v16,%v17 /* Compare not equal. */ ++ jno .Lfound ++ brctg %r1,.Lloop16 /* Loop until all blocks are processed. */ ++ ++ llgfr %r4,%r4 ++ nilf %r4,15 /* Get remaining bytes */ ++ locgre %r2,%r4 ++ ber %r14 ++ la %r2,0(%r5,%r2) ++ la %r3,0(%r5,%r3) ++ j .Lremaining ++ ++.Lpreloop64: ++ srlg %r1,%r4,6 /* Split into 64byte blocks */ ++.Lloop64: ++ vl %v16,0(%r5,%r2) ++ vl %v17,0(%r5,%r3) ++ vfenefs %v18,%v16,%v17 /* Compare not equal. */ ++ jno .Lfound ++ ++ vl %v16,16(%r5,%r2) ++ vl %v17,16(%r5,%r3) ++ vfenefs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vl %v16,32(%r5,%r2) ++ vl %v17,32(%r5,%r3) ++ vfenefs %v18,%v16,%v17 ++ jno .Lfound ++ ++ vl %v16,48(%r5,%r2) ++ vl %v17,48(%r5,%r3) ++ aghi %r5,64 ++ vfenefs %v18,%v16,%v17 ++ jno .Lfound ++ ++ brctg %r1,.Lloop64 /* Loop until all blocks are processed. */ ++ ++ llgfr %r4,%r4 ++ nilf %r4,63 /* Get remaining bytes */ ++ locgre %r2,%r4 ++ ber %r14 ++ clgijh %r4,16,.Lpreloop16 ++ la %r2,0(%r5,%r2) ++ la %r3,0(%r5,%r3) ++ j .Lremaining ++END(__wmemcmp_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/wmemcmp.c b/sysdeps/s390/multiarch/wmemcmp.c +new file mode 100644 +index 0000000..24a57e9 +--- /dev/null ++++ b/sysdeps/s390/multiarch/wmemcmp.c +@@ -0,0 +1,27 @@ ++/* Multiple versions of wmemcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc2 (__wmemcmp, wmemcmp) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-3.patch b/SOURCES/glibc-rh1268008-3.patch new file mode 100644 index 00000000..77266749 --- /dev/null +++ b/SOURCES/glibc-rh1268008-3.patch @@ -0,0 +1,643 @@ +From 6b9ad27fafd9c09aee186f2630b1c54348335040 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:29:17 +0200 +Subject: [PATCH 03/30] S390: Get rid of linknamespace failures for string + functions. + +upstream-commit-id: 1d53248326dbd3c620a2bca16d35eff3019d900a +https://www.sourceware.org/ml/libc-alpha/2015-01/msg00310.html + +This patch is needed to prepare for the optimized string function patchset. +This patch prefixes the ifunc-resolvers, the specific functions +and helper functions with '__' on s390-32/s390-64. +--- + sysdeps/s390/s390-32/memcmp.S | 4 ++-- + sysdeps/s390/s390-32/memcpy.S | 10 +++++----- + sysdeps/s390/s390-32/memset.S | 4 ++-- + sysdeps/s390/s390-32/multiarch/ifunc-resolve.c | 16 ++++++++-------- + sysdeps/s390/s390-32/multiarch/memcmp.S | 12 ++++++------ + sysdeps/s390/s390-32/multiarch/memcpy.S | 14 +++++++------- + sysdeps/s390/s390-32/multiarch/memset.S | 18 +++++++++--------- + sysdeps/s390/s390-64/memcmp.S | 4 ++-- + sysdeps/s390/s390-64/memcpy.S | 10 +++++----- + sysdeps/s390/s390-64/memset.S | 4 ++-- + sysdeps/s390/s390-64/multiarch/ifunc-resolve.c | 18 +++++++++--------- + sysdeps/s390/s390-64/multiarch/memcmp.S | 12 ++++++------ + sysdeps/s390/s390-64/multiarch/memcpy.S | 14 +++++++------- + sysdeps/s390/s390-64/multiarch/memset.S | 18 +++++++++--------- + 14 files changed, 79 insertions(+), 79 deletions(-) + +diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S +index 9ff84a3..b6eabe5 100644 +--- a/sysdeps/s390/s390-32/memcmp.S ++++ b/sysdeps/s390/s390-32/memcmp.S +@@ -27,7 +27,7 @@ + + .text + #ifdef USE_MULTIARCH +-ENTRY(memcmp_g5) ++ENTRY(__memcmp_g5) + #else + ENTRY(memcmp) + #endif +@@ -58,7 +58,7 @@ ENTRY(memcmp) + .L_G5_17: + clc 0(1,%r3),0(%r2) + #ifdef USE_MULTIARCH +-END(memcmp_g5) ++END(__memcmp_g5) + #else + END(memcmp) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S +index 90cc4cb..a3b1ace 100644 +--- a/sysdeps/s390/s390-32/memcpy.S ++++ b/sysdeps/s390/s390-32/memcpy.S +@@ -26,7 +26,7 @@ + %r4 = number of bytes to copy. */ + + #ifdef USE_MULTIARCH +-ENTRY(memcpy_g5) ++ENTRY(__memcpy_g5) + #else + ENTRY(memcpy) + #endif +@@ -49,7 +49,7 @@ ENTRY(memcpy) + br %r14 + .L_G5_13: + chi %r5,4096 # Switch to mvcle for copies >1MB +- jh memcpy_mvcle ++ jh __memcpy_mvcle + .L_G5_12: + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) +@@ -60,13 +60,13 @@ ENTRY(memcpy) + .L_G5_17: + mvc 0(1,%r1),0(%r3) + #ifdef USE_MULTIARCH +-END(memcpy_g5) ++END(__memcpy_g5) + #else + END(memcpy) + libc_hidden_builtin_def (memcpy) + #endif + +-ENTRY(memcpy_mvcle) ++ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. +@@ -79,4 +79,4 @@ ENTRY(memcpy_mvcle) + jo .L_MVCLE_1 + lr %r2,%r1 # return destination address + br %r14 +-END(memcpy_mvcle) ++END(__memcpy_mvcle) +diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S +index 31a70f0..a73dc6c 100644 +--- a/sysdeps/s390/s390-32/memset.S ++++ b/sysdeps/s390/s390-32/memset.S +@@ -28,7 +28,7 @@ + .text + + #ifdef USE_MULTIARCH +-ENTRY(memset_g5) ++ENTRY(__memset_g5) + #else + ENTRY(memset) + #endif +@@ -58,7 +58,7 @@ ENTRY(memset) + .L_G5_20: + mvc 1(1,%r1),0(%r1) + #ifdef USE_MULTIARCH +-END(memset_g5) ++END(__memset_g5) + #else + END(memset) + libc_hidden_builtin_def (memset) +diff --git a/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c b/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c +index 42ca8da..522c63c 100644 +--- a/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c ++++ b/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c +@@ -28,17 +28,17 @@ + #define IFUNC_RESOLVE(FUNC) \ + asm (".globl " #FUNC "\n\t" \ + ".type " #FUNC ",@gnu_indirect_function\n\t" \ +- ".set " #FUNC ",resolve_" #FUNC "\n\t" \ ++ ".set " #FUNC ",__resolve_" #FUNC "\n\t" \ + ".globl __GI_" #FUNC "\n\t" \ + ".set __GI_" #FUNC "," #FUNC "\n"); \ + \ + /* Make the declarations of the optimized functions hidden in order + to prevent GOT slots being generated for them. */ \ +- extern void *FUNC##_z196 attribute_hidden; \ +- extern void *FUNC##_z10 attribute_hidden; \ +- extern void *FUNC##_g5 attribute_hidden; \ ++ extern void *__##FUNC##_z196 attribute_hidden; \ ++ extern void *__##FUNC##_z10 attribute_hidden; \ ++ extern void *__##FUNC##_g5 attribute_hidden; \ + \ +- void *resolve_##FUNC (unsigned long int dl_hwcap) \ ++ void *__resolve_##FUNC (unsigned long int dl_hwcap) \ + { \ + if ((dl_hwcap & HWCAP_S390_STFLE) \ + && (dl_hwcap & HWCAP_S390_ZARCH) \ +@@ -53,11 +53,11 @@ + : : "cc"); \ + \ + if ((stfle_bits & (1ULL << (63 - STFLE_BITS_Z196))) != 0) \ +- return &FUNC##_z196; \ ++ return &__##FUNC##_z196; \ + else if ((stfle_bits & (1ULL << (63 - STFLE_BITS_Z10))) != 0) \ +- return &FUNC##_z10; \ ++ return &__##FUNC##_z10; \ + } \ +- return &FUNC##_g5; \ ++ return &__##FUNC##_g5; \ + } + + IFUNC_RESOLVE(memset) +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.S b/sysdeps/s390/s390-32/multiarch/memcmp.S +index 9ca8891..c654d19 100644 +--- a/sysdeps/s390/s390-32/multiarch/memcmp.S ++++ b/sysdeps/s390/s390-32/multiarch/memcmp.S +@@ -29,7 +29,7 @@ + + #ifndef NOT_IN_libc + +-ENTRY(memcmp_z196) ++ENTRY(__memcmp_z196) + .machine "z196" + .machinemode "zarch_nohighgprs" + ltr %r4,%r4 +@@ -61,9 +61,9 @@ ENTRY(memcmp_z196) + br %r14 + .L_Z196_14: + clc 0(1,%r3),0(%r2) +-END(memcmp_z196) ++END(__memcmp_z196) + +-ENTRY(memcmp_z10) ++ENTRY(__memcmp_z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + ltr %r4,%r4 +@@ -90,7 +90,7 @@ ENTRY(memcmp_z10) + j .L_Z10_3 + .L_Z10_15: + clc 0(1,%r3),0(%r2) +-END(memcmp_z10) ++END(__memcmp_z10) + + #endif + +@@ -98,7 +98,7 @@ END(memcmp_z10) + + #ifdef NOT_IN_libc + .globl memcmp +-.set memcmp,memcmp_g5 ++.set memcmp,__memcmp_g5 + .weak bcmp +-.set bcmp,memcmp_g5 ++.set bcmp,__memcmp_g5 + #endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.S b/sysdeps/s390/s390-32/multiarch/memcpy.S +index 7b85602..5c2113f 100644 +--- a/sysdeps/s390/s390-32/multiarch/memcpy.S ++++ b/sysdeps/s390/s390-32/multiarch/memcpy.S +@@ -29,7 +29,7 @@ + + #if defined SHARED && !defined NOT_IN_libc + +-ENTRY(memcpy_z196) ++ENTRY(__memcpy_z196) + .machine "z196" + .machinemode "zarch_nohighgprs" + llgfr %r4,%r4 +@@ -46,7 +46,7 @@ ENTRY(memcpy_z196) + br %r14 + .L_Z196_5: + cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh memcpy_mvcle ++ jh __memcpy_mvcle + .L_Z196_2: + pfd 1,768(%r3) + pfd 2,768(%r1) +@@ -58,9 +58,9 @@ ENTRY(memcpy_z196) + j .L_Z196_3 + .L_Z196_14: + mvc 0(1,%r1),0(%r3) +-END(memcpy_z196) ++END(__memcpy_z196) + +-ENTRY(memcpy_z10) ++ENTRY(__memcpy_z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + llgfr %r4,%r4 +@@ -75,7 +75,7 @@ ENTRY(memcpy_z10) + br %r14 + .L_Z10_13: + cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh memcpy_mvcle ++ jh __memcpy_mvcle + .L_Z10_12: + pfd 1,768(%r3) + pfd 2,768(%r1) +@@ -86,7 +86,7 @@ ENTRY(memcpy_z10) + j .L_Z10_3 + .L_Z10_15: + mvc 0(1,%r1),0(%r3) +-END(memcpy_z10) ++END(__memcpy_z10) + + #endif + +@@ -94,5 +94,5 @@ END(memcpy_z10) + + #if !defined SHARED || defined NOT_IN_libc + .globl memcpy +-.set memcpy,memcpy_g5 ++.set memcpy,__memcpy_g5 + #endif +diff --git a/sysdeps/s390/s390-32/multiarch/memset.S b/sysdeps/s390/s390-32/multiarch/memset.S +index ba43d67..54aa028 100644 +--- a/sysdeps/s390/s390-32/multiarch/memset.S ++++ b/sysdeps/s390/s390-32/multiarch/memset.S +@@ -29,7 +29,7 @@ + + #ifndef NOT_IN_libc + +-ENTRY(memset_z196) ++ENTRY(__memset_z196) + .machine "z196" + .machinemode "zarch_nohighgprs" + llgfr %r4,%r4 +@@ -49,7 +49,7 @@ ENTRY(memset_z196) + br %r14 + .L_Z196_1: + cgfi %r5,1048576 +- jh memset_mvcle # Switch to mvcle for >256MB ++ jh __memset_mvcle # Switch to mvcle for >256MB + .L_Z196_2: + pfd 2,1024(%r1) + mvc 1(256,%r1),0(%r1) +@@ -59,9 +59,9 @@ ENTRY(memset_z196) + j .L_Z196_3 + .L_Z196_17: + mvc 1(1,%r1),0(%r1) +-END(memset_z196) ++END(__memset_z196) + +-ENTRY(memset_z10) ++ENTRY(__memset_z10) + .machine "z10" + .machinemode "zarch_nohighgprs" + llgfr %r4,%r4 +@@ -78,7 +78,7 @@ ENTRY(memset_z10) + br %r14 + .L_Z10_15: + cgfi %r5,163840 # Switch to mvcle for >40MB +- jh memset_mvcle ++ jh __memset_mvcle + .L_Z10_14: + pfd 2,1024(%r1) + mvc 1(256,%r1),0(%r1) +@@ -87,9 +87,9 @@ ENTRY(memset_z10) + j .L_Z10_3 + .L_Z10_18: + mvc 1(1,%r1),0(%r1) +-END(memset_z10) ++END(__memset_z10) + +-ENTRY(memset_mvcle) ++ENTRY(__memset_mvcle) + ahi %r4,2 # take back the change done by the caller + lr %r0,%r2 # save source address + lr %r1,%r3 # move pad byte to R1 +@@ -101,7 +101,7 @@ ENTRY(memset_mvcle) + lr %r2,%r0 # return value is source address + .L1: + br %r14 +-END(memset_mvcle) ++END(__memset_mvcle) + + #endif + +@@ -109,5 +109,5 @@ END(memset_mvcle) + + #ifdef NOT_IN_libc + .globl memset +-.set memset,memset_g5 ++.set memset,__memset_g5 + #endif +diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/s390-64/memcmp.S +index 1b43440..eb5370f 100644 +--- a/sysdeps/s390/s390-64/memcmp.S ++++ b/sysdeps/s390/s390-64/memcmp.S +@@ -27,7 +27,7 @@ + + .text + #ifdef USE_MULTIARCH +-ENTRY(memcmp_z900) ++ENTRY(__memcmp_z900) + #else + ENTRY(memcmp) + #endif +@@ -56,7 +56,7 @@ ENTRY(memcmp) + .L_Z900_15: + clc 0(1,%r3),0(%r2) + #ifdef USE_MULTIARCH +-END(memcmp_z900) ++END(__memcmp_z900) + #else + END(memcmp) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/s390-64/memcpy.S +index bae8836..61fca0b 100644 +--- a/sysdeps/s390/s390-64/memcpy.S ++++ b/sysdeps/s390/s390-64/memcpy.S +@@ -29,7 +29,7 @@ + .text + + #ifdef USE_MULTIARCH +-ENTRY(memcpy_z900) ++ENTRY(__memcpy_z900) + #else + ENTRY(memcpy) + #endif +@@ -48,7 +48,7 @@ ENTRY(memcpy) + br %r14 + .L_Z900_13: + chi %r5,4096 # Switch to mvcle for copies >1MB +- jh memcpy_mvcle ++ jh __memcpy_mvcle + .L_Z900_12: + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) +@@ -59,13 +59,13 @@ ENTRY(memcpy) + mvc 0(1,%r1),0(%r3) + + #ifdef USE_MULTIARCH +-END(memcpy_z900) ++END(__memcpy_z900) + #else + END(memcpy) + libc_hidden_builtin_def (memcpy) + #endif + +-ENTRY(memcpy_mvcle) ++ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. +@@ -78,4 +78,4 @@ ENTRY(memcpy_mvcle) + jo .L_MVCLE_1 + lgr %r2,%r1 # return destination address + br %r14 +-END(memcpy_mvcle) ++END(__memcpy_mvcle) +diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/s390-64/memset.S +index 4edfb4e..8185e94 100644 +--- a/sysdeps/s390/s390-64/memset.S ++++ b/sysdeps/s390/s390-64/memset.S +@@ -29,7 +29,7 @@ + .text + + #ifdef USE_MULTIARCH +-ENTRY(memset_z900) ++ENTRY(__memset_z900) + #else + ENTRY(memset) + #endif +@@ -57,7 +57,7 @@ ENTRY(memset) + .L_Z900_18: + mvc 1(1,%r1),0(%r1) + #ifdef USE_MULTIARCH +-END(memset_z900) ++END(__memset_z900) + #else + END(memset) + libc_hidden_builtin_def (memset) +diff --git a/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c b/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c +index 8db2c38..b6be970 100644 +--- a/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c ++++ b/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c +@@ -28,17 +28,17 @@ + #define IFUNC_RESOLVE(FUNC) \ + asm (".globl " #FUNC "\n\t" \ + ".type " #FUNC ",@gnu_indirect_function\n\t" \ +- ".set " #FUNC ",resolve_" #FUNC "\n\t" \ ++ ".set " #FUNC ",__resolve_" #FUNC "\n\t" \ + ".globl __GI_" #FUNC "\n\t" \ + ".set __GI_" #FUNC "," #FUNC "\n"); \ + \ + /* Make the declarations of the optimized functions hidden in order + to prevent GOT slots being generated for them. */ \ +- extern void *FUNC##_z196 attribute_hidden; \ +- extern void *FUNC##_z10 attribute_hidden; \ +- extern void *FUNC##_z900 attribute_hidden; \ ++ extern void *__##FUNC##_z196 attribute_hidden; \ ++ extern void *__##FUNC##_z10 attribute_hidden; \ ++ extern void *__##FUNC##_z900 attribute_hidden; \ + \ +- void *resolve_##FUNC (unsigned long int dl_hwcap) \ ++ void *__resolve_##FUNC (unsigned long int dl_hwcap) \ + { \ + if (dl_hwcap & HWCAP_S390_STFLE) \ + { \ +@@ -54,14 +54,14 @@ + : : "cc"); \ + \ + if ((stfle_bits & (1UL << (63 - STFLE_BITS_Z196))) != 0) \ +- return &FUNC##_z196; \ ++ return &__##FUNC##_z196; \ + else if ((stfle_bits & (1UL << (63 - STFLE_BITS_Z10))) != 0) \ +- return &FUNC##_z10; \ ++ return &__##FUNC##_z10; \ + else \ +- return &FUNC##_z900; \ ++ return &__##FUNC##_z900; \ + } \ + else \ +- return &FUNC##_z900; \ ++ return &__##FUNC##_z900; \ + } + + IFUNC_RESOLVE(memset) +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.S b/sysdeps/s390/s390-64/multiarch/memcmp.S +index f40a3c1..9a8cba8 100644 +--- a/sysdeps/s390/s390-64/multiarch/memcmp.S ++++ b/sysdeps/s390/s390-64/multiarch/memcmp.S +@@ -29,7 +29,7 @@ + + #ifndef NOT_IN_libc + +-ENTRY(memcmp_z196) ++ENTRY(__memcmp_z196) + .machine "z196" + ltgr %r4,%r4 + je .L_Z196_4 +@@ -60,9 +60,9 @@ ENTRY(memcmp_z196) + br %r14 + .L_Z196_14: + clc 0(1,%r3),0(%r2) +-END(memcmp_z196) ++END(__memcmp_z196) + +-ENTRY(memcmp_z10) ++ENTRY(__memcmp_z10) + .machine "z10" + ltgr %r4,%r4 + je .L_Z10_4 +@@ -87,7 +87,7 @@ ENTRY(memcmp_z10) + j .L_Z10_3 + .L_Z10_15: + clc 0(1,%r3),0(%r2) +-END(memcmp_z10) ++END(__memcmp_z10) + + #endif + +@@ -95,7 +95,7 @@ END(memcmp_z10) + + #ifdef NOT_IN_libc + .globl memcmp +-.set memcmp,memcmp_z900 ++.set memcmp,__memcmp_z900 + .weak bcmp +-.set bcmp,memcmp_z900 ++.set bcmp,__memcmp_z900 + #endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.S b/sysdeps/s390/s390-64/multiarch/memcpy.S +index b00ffc1..525588f 100644 +--- a/sysdeps/s390/s390-64/multiarch/memcpy.S ++++ b/sysdeps/s390/s390-64/multiarch/memcpy.S +@@ -29,7 +29,7 @@ + + #if defined SHARED && !defined NOT_IN_libc + +-ENTRY(memcpy_z196) ++ENTRY(__memcpy_z196) + .machine "z196" + ltgr %r4,%r4 + je .L_Z196_4 +@@ -44,7 +44,7 @@ ENTRY(memcpy_z196) + br %r14 + .L_Z196_5: + cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh memcpy_mvcle ++ jh __memcpy_mvcle + .L_Z196_2: + pfd 1,768(%r3) + pfd 2,768(%r1) +@@ -56,9 +56,9 @@ ENTRY(memcpy_z196) + j .L_Z196_3 + .L_Z196_14: + mvc 0(1,%r1),0(%r3) +-END(memcpy_z196) ++END(__memcpy_z196) + +-ENTRY(memcpy_z10) ++ENTRY(__memcpy_z10) + .machine "z10" + cgije %r4,0,.L_Z10_4 + aghi %r4,-1 +@@ -71,7 +71,7 @@ ENTRY(memcpy_z10) + br %r14 + .L_Z10_13: + cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh memcpy_mvcle ++ jh __memcpy_mvcle + .L_Z10_12: + pfd 1,768(%r3) + pfd 2,768(%r1) +@@ -82,7 +82,7 @@ ENTRY(memcpy_z10) + j .L_Z10_3 + .L_Z10_15: + mvc 0(1,%r1),0(%r3) +-END(memcpy_z10) ++END(__memcpy_z10) + + #endif + +@@ -90,5 +90,5 @@ END(memcpy_z10) + + #if !defined SHARED || defined NOT_IN_libc + .globl memcpy +-.set memcpy,memcpy_z900 ++.set memcpy,__memcpy_z900 + #endif +diff --git a/sysdeps/s390/s390-64/multiarch/memset.S b/sysdeps/s390/s390-64/multiarch/memset.S +index 1f9064d..8dbb3cb 100644 +--- a/sysdeps/s390/s390-64/multiarch/memset.S ++++ b/sysdeps/s390/s390-64/multiarch/memset.S +@@ -29,7 +29,7 @@ + + #ifndef NOT_IN_libc + +-ENTRY(memset_z196) ++ENTRY(__memset_z196) + .machine "z196" + ltgr %r4,%r4 + je .L_Z196_4 +@@ -47,7 +47,7 @@ ENTRY(memset_z196) + br %r14 + .L_Z196_1: + cgfi %r5,1048576 +- jh memset_mvcle # Switch to mvcle for >256MB ++ jh __memset_mvcle # Switch to mvcle for >256MB + .L_Z196_2: + pfd 2,1024(%r1) + mvc 1(256,%r1),0(%r1) +@@ -57,9 +57,9 @@ ENTRY(memset_z196) + j .L_Z196_3 + .L_Z196_17: + mvc 1(1,%r1),0(%r1) +-END(memset_z196) ++END(__memset_z196) + +-ENTRY(memset_z10) ++ENTRY(__memset_z10) + .machine "z10" + cgije %r4,0,.L_Z10_4 + stc %r3,0(%r2) +@@ -74,7 +74,7 @@ ENTRY(memset_z10) + br %r14 + .L_Z10_15: + cgfi %r5,163840 # Switch to mvcle for >40MB +- jh memset_mvcle ++ jh __memset_mvcle + .L_Z10_14: + pfd 2,1024(%r1) + mvc 1(256,%r1),0(%r1) +@@ -83,9 +83,9 @@ ENTRY(memset_z10) + j .L_Z10_3 + .L_Z10_18: + mvc 1(1,%r1),0(%r1) +-END(memset_z10) ++END(__memset_z10) + +-ENTRY(memset_mvcle) ++ENTRY(__memset_mvcle) + aghi %r4,2 # take back the change done by the caller + lgr %r0,%r2 # save source address + lgr %r1,%r3 # move pad byte to R1 +@@ -97,7 +97,7 @@ ENTRY(memset_mvcle) + lgr %r2,%r0 # return value is source address + .L1: + br %r14 +-END(memset_mvcle) ++END(__memset_mvcle) + + #endif + +@@ -105,5 +105,5 @@ END(memset_mvcle) + + #ifdef NOT_IN_libc + .globl memset +-.set memset,memset_z900 ++.set memset,__memset_z900 + #endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-30.patch b/SOURCES/glibc-rh1268008-30.patch new file mode 100644 index 00000000..2ebe297d --- /dev/null +++ b/SOURCES/glibc-rh1268008-30.patch @@ -0,0 +1,291 @@ +From 250962053fadd0911accad515802d9b957c9d019 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 13:24:58 +0200 +Subject: [PATCH 30/30] S390: Optimize memrchr. + +upstream-commit-id: 798f5b4b5d24e5687dd55acc535954ed1d59c10c +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00092.html + +This patch provides optimized version of memrchr with the z13 vector +instructions. + +ChangeLog: + + * sysdeps/s390/multiarch/memrchr-c.c: New File. + * sysdeps/s390/multiarch/memrchr-vx.S: Likewise. + * sysdeps/s390/multiarch/memrchr.c: Likewise. + * sysdeps/s390/multiarch/Makefile + (sysdep_routines): Add memrchr functions. + * sysdeps/s390/multiarch/ifunc-impl-list-common.c + (__libc_ifunc_impl_list_common): Add ifunc test for memrchr. +--- + sysdeps/s390/multiarch/Makefile | 3 +- + sysdeps/s390/multiarch/ifunc-impl-list.c | 2 + + sysdeps/s390/multiarch/memrchr-c.c | 25 +++++ + sysdeps/s390/multiarch/memrchr-vx.S | 160 +++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/memrchr.c | 28 ++++++ + 5 files changed, 217 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/s390/multiarch/memrchr-c.c + create mode 100644 sysdeps/s390/multiarch/memrchr-vx.S + create mode 100644 sysdeps/s390/multiarch/memrchr.c + +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 929a545..0805b07 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -17,7 +17,8 @@ sysdep_routines += strlen strlen-vx strlen-c \ + strcspn strcspn-vx strcspn-c \ + memchr memchr-vx \ + rawmemchr rawmemchr-vx rawmemchr-c \ +- memccpy memccpy-vx memccpy-c ++ memccpy memccpy-vx memccpy-c \ ++ memrchr memrchr-vx memrchr-c + endif + + ifeq ($(subdir),wcsmbs) +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +index 5ea258b..c235bdc 100644 +--- a/sysdeps/s390/multiarch/ifunc-impl-list.c ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -137,6 +137,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + IFUNC_VX_IMPL (wmemcmp); + ++ IFUNC_VX_IMPL (memrchr); ++ + #endif /* HAVE_S390_VX_ASM_SUPPORT */ + + return i; +diff --git a/sysdeps/s390/multiarch/memrchr-c.c b/sysdeps/s390/multiarch/memrchr-c.c +new file mode 100644 +index 0000000..6a32861 +--- /dev/null ++++ b/sysdeps/s390/multiarch/memrchr-c.c +@@ -0,0 +1,25 @@ ++/* Default memrchr implementation for S/390. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# define MEMRCHR __memrchr_c ++ ++# include ++extern __typeof (__memrchr) __memrchr_c; ++# include ++#endif +diff --git a/sysdeps/s390/multiarch/memrchr-vx.S b/sysdeps/s390/multiarch/memrchr-vx.S +new file mode 100644 +index 0000000..da6dbdf +--- /dev/null ++++ b/sysdeps/s390/multiarch/memrchr-vx.S +@@ -0,0 +1,160 @@ ++/* Vector optimized 32/64 bit S/390 version of memrchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++ ++# include "sysdep.h" ++# include "asm-syntax.h" ++ ++ .text ++ ++/* void *memrchr (const void *s, int c, size_t n) ++ Scans memory for character c backwards ++ and returns pointer to first c. ++ ++ Register usage: ++ -r0=tmp ++ -r1=tmp ++ -r2=s ++ -r3=c ++ -r4=n ++ -r5=s in loop ++ ++ -v16=part of s ++ -v17=index of found c ++ -v18=c replicated ++ -v20=permute pattern ++*/ ++ENTRY(__memrchr_vx) ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ ++# if !defined __s390x__ ++ llgfr %r4,%r4 ++# endif /* !defined __s390x__ */ ++ clgije %r4,0,.Lnot_found ++ ++ vlvgb %v18,%r3,0 /* Generate vector which elements are all c. ++ If c > 255, c will be truncated. */ ++ vrepb %v18,%v18,0 ++ ++ llcr %r3,%r3 /* char c_char = (char) c. */ ++ ++ /* check byte n - 1. */ ++ llc %r0,-1(%r4,%r2) ++ slgfi %r4,1 ++ clrje %r0,%r3,.Lfound_end ++ jh .Lnot_found /* Return NULL if n is now 0. */ ++ ++ larl %r1,.Lpermute_mask /* Load permute mask. */ ++ vl %v20,0(%r1) ++ ++ /* check byte n - 2. */ ++ llc %r0,-1(%r4,%r2) ++ slgfi %r4,1 ++ clrje %r0,%r3,.Lfound_end ++ jh .Lnot_found /* Return NULL if n is now 0. */ ++ ++ clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ ++ ++.Llt64: ++ /* Process n < 64 bytes. */ ++ clgijl %r4,16,.Llt16 /* Jump away if n < 16. */ ++ aghi %r4,-16 ++ vl %v16,0(%r4,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lfound0 ++ clgijl %r4,16,.Llt16 ++ aghi %r4,-16 ++ vl %v16,0(%r4,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lfound0 ++ clgijl %r4,16,.Llt16 ++ aghi %r4,-16 ++ vl %v16,0(%r4,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lfound0 ++.Llt16: ++ clgfi %r4,0 /* if remaining bytes == 0, return NULL. */ ++ locghie %r2,0 ++ ber %r14 ++ ++ aghi %r4,-1 /* vll needs highest index. */ ++ vll %v16,%r4,0(%r2) /* Load remaining bytes. */ ++ ++ /* Right-shift of v16 to mask bytes after highest index. */ ++ lhi %r0,15 ++ slr %r0,%r4 /* Compute byte count for vector shift right. */ ++ sll %r0,3 /* Convert to bit count. */ ++ vlvgb %v17,%r0,7 ++ vsrlb %v16,%v16,%v17 /* Vector shift right by byte by number of bytes ++ specified in bits 1-4 of byte 7 in v17. */ ++ j .Lfound_permute ++ ++.Lfound48: ++ aghi %r4,16 ++.Lfound32: ++ aghi %r4,16 ++.Lfound16: ++ aghi %r4,16 ++.Lfound0: ++ la %r2,0(%r4,%r2) /* Set pointer to start of v16. */ ++ lghi %r4,15 /* Set highest index in v16 to last index. */ ++.Lfound_permute: ++ /* Search for a c in v16 in reversed byte order. v16 contains %r4 + 1 ++ bytes. If v16 was not fully loaded, the bytes are already ++ right shifted, so that the bytes in v16 can simply be reversed. */ ++ vperm %v16,%v16,%v16,%v20 /* Permute v16 to reversed order. */ ++ vfeeb %v16,%v16,%v18 /* Find c in reversed v16. */ ++ vlgvb %r1,%v16,7 /* Index of c or 16 if not found. */ ++ ++ /* Return NULL if there is no c in loaded bytes. */ ++ clrjh %r1,%r4,.Lnot_found ++ ++ slgr %r4,%r1 ++.Lfound_end: ++ la %r2,0(%r4,%r2) /* Return pointer to c. */ ++ br %r14 ++ ++.Lnot_found: ++ lghi %r2,0 ++ br %r14 ++ ++.Lpermute_mask: ++ .byte 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08 ++ .byte 0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 ++ ++.Lloop64: ++ aghi %r4,-64 ++ vl %v16,48(%r4,%r2) /* Load 16bytes of memory area. */ ++ vfeebs %v17,%v16,%v18 /* Find c. */ ++ jno .Lfound48 /* Jump away if c was found. */ ++ vl %v16,32(%r4,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lfound32 ++ vl %v16,16(%r4,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lfound16 ++ vl %v16,0(%r4,%r2) ++ vfeebs %v17,%v16,%v18 ++ jno .Lfound0 ++ ++ clgijhe %r4,64,.Lloop64 /* If n >= 64 -> loop64. */ ++ j .Llt64 ++END(__memrchr_vx) ++#endif /* HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc */ +diff --git a/sysdeps/s390/multiarch/memrchr.c b/sysdeps/s390/multiarch/memrchr.c +new file mode 100644 +index 0000000..6596067 +--- /dev/null ++++ b/sysdeps/s390/multiarch/memrchr.c +@@ -0,0 +1,28 @@ ++/* Multiple versions of memrchr. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc ++# include ++# include ++ ++s390_vx_libc_ifunc (__memrchr) ++weak_alias (__memrchr, memrchr) ++ ++#else ++# include ++#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && !defined NOT_IN_libc) */ +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-4.patch b/SOURCES/glibc-rh1268008-4.patch new file mode 100644 index 00000000..fce14582 --- /dev/null +++ b/SOURCES/glibc-rh1268008-4.patch @@ -0,0 +1,206 @@ +From aea6303d6c5fa276ea10887dab968ee0f3c79328 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:30:00 +0200 +Subject: [PATCH 04/30] S390: Fix handling of DXC-byte in FPC-register. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +upstream-commit-id: 5d96fe8c0dc3450bafe6c2aae2dabc76819df3e0 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00074.html + +On s390, the DXC(data-exception-code)-byte in FPC(floating-point-control)- +register contains a code of the last occured exception. +If bits 6 and 7 of DXC-byte are zero, the bits 0-5 correspond to the +ieee-exception flag bits. +The current implementation always uses these bits as ieee-exception flag bits. +fetestexcept() reports any exception after the first usage of a +vector-instruction in a process, because it raises an "vector instruction +exception" with DXC-code 0xFE. +This patch fixes the handling of the DXC-byte. The DXC-Byte is only handled +if bits 6 and 7 are zero. + +The #define _FPU_RESERVED is extended by the DXC-Byte. +Otherwise the tests math/test-fpucw-static and math/test-fpucw-ieee-static +fails, because DXC-Byte contains the vector instruction exception when reaching +main(). This exception was triggered by strrchr() call in __init_misc(). +__init_misc() is called after __setfpucw () in __libc_init_first(). + +The field __ieee_instruction_pointer in struct fenv_t is renamed to __unused +because it is a relict from commit "Remove PTRACE_PEEKUSER" +(87b9b50f0d4b92248905e95a06a13c513dc45e59) and isn´t used anymore. + +ChangeLog: + + [BZ #18610] + * sysdeps/s390/fpu/bits/fenv.h (fenv_t): Rename + __ieee_instruction_pointer to __unused. + * sysdeps/s390/fpu/fesetenv.c (__fesetenv): Remove usage of + __ieee_instruction_pointer. + * sysdeps/s390/fpu/fclrexcpt.c (feclearexcept): Fix dxc-field handling. + * sysdeps/s390/fpu/fgetexcptflg.c (fegetexceptflag): Likewise. + * sysdeps/s390/fpu/fsetexcptflg.c (fesetexceptflag): Likewise. + * sysdeps/s390/fpu/ftestexcept.c (fetestexcept): Likewise. + * sysdeps/s390/fpu/fpu_control.h (_FPU_RESERVED): + Mark dxc-field as reserved. +--- + sysdeps/s390/fpu/bits/fenv.h | 6 ++++-- + sysdeps/s390/fpu/fclrexcpt.c | 7 ++++++- + sysdeps/s390/fpu/fesetenv.c | 2 -- + sysdeps/s390/fpu/fgetexcptflg.c | 8 +++++++- + sysdeps/s390/fpu/fpu_control.h | 6 +++--- + sysdeps/s390/fpu/fsetexcptflg.c | 15 ++++++++++++--- + sysdeps/s390/fpu/ftestexcept.c | 12 +++++++++--- + 7 files changed, 41 insertions(+), 15 deletions(-) + +diff --git a/sysdeps/s390/fpu/bits/fenv.h b/sysdeps/s390/fpu/bits/fenv.h +index 88c6f7a..93177dc 100644 +--- a/sysdeps/s390/fpu/bits/fenv.h ++++ b/sysdeps/s390/fpu/bits/fenv.h +@@ -77,8 +77,10 @@ typedef unsigned int fexcept_t; /* size of fpc */ + typedef struct + { + fexcept_t __fpc; +- void *__ieee_instruction_pointer; +- /* failing instruction for ieee exceptions */ ++ void *__unused; ++ /* The field __unused (formerly __ieee_instruction_pointer) is a relict from ++ commit "Remove PTRACE_PEEKUSER" (87b9b50f0d4b92248905e95a06a13c513dc45e59) ++ and isn´t used anymore. */ + } fenv_t; + + /* If the default argument is used we use this value. */ +diff --git a/sysdeps/s390/fpu/fclrexcpt.c b/sysdeps/s390/fpu/fclrexcpt.c +index 3e8d9bb..c2647ba 100644 +--- a/sysdeps/s390/fpu/fclrexcpt.c ++++ b/sysdeps/s390/fpu/fclrexcpt.c +@@ -29,7 +29,12 @@ feclearexcept (int excepts) + + _FPU_GETCW (temp); + /* Clear the relevant bits. */ +- temp &= ~((excepts << FPC_DXC_SHIFT)|(excepts << FPC_FLAGS_SHIFT)); ++ temp &= ~(excepts << FPC_FLAGS_SHIFT); ++ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) ++ /* Bits 6, 7 of dxc-byte are zero, ++ thus bits 0-5 of dxc-byte correspond to the flag-bits. ++ Clear the relevant bits in flags and dxc-field. */ ++ temp &= ~(excepts << FPC_DXC_SHIFT); + + /* Put the new data in effect. */ + _FPU_SETCW (temp); +diff --git a/sysdeps/s390/fpu/fesetenv.c b/sysdeps/s390/fpu/fesetenv.c +index b534205..a4a0bb5 100644 +--- a/sysdeps/s390/fpu/fesetenv.c ++++ b/sysdeps/s390/fpu/fesetenv.c +@@ -32,12 +32,10 @@ fesetenv (const fenv_t *envp) + if (envp == FE_DFL_ENV) + { + env.__fpc = _FPU_DEFAULT; +- env.__ieee_instruction_pointer = 0; + } + else if (envp == FE_NOMASK_ENV) + { + env.__fpc = FPC_EXCEPTION_MASK; +- env.__ieee_instruction_pointer = 0; + } + else + env = (*envp); +diff --git a/sysdeps/s390/fpu/fgetexcptflg.c b/sysdeps/s390/fpu/fgetexcptflg.c +index 7457678..7941904 100644 +--- a/sysdeps/s390/fpu/fgetexcptflg.c ++++ b/sysdeps/s390/fpu/fgetexcptflg.c +@@ -27,7 +27,13 @@ fegetexceptflag (fexcept_t *flagp, int excepts) + + /* Get the current exceptions. */ + _FPU_GETCW (temp); +- newexcepts = (excepts << FPC_DXC_SHIFT) | (excepts << FPC_FLAGS_SHIFT); ++ newexcepts = excepts << FPC_FLAGS_SHIFT; ++ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) ++ /* Bits 6, 7 of dxc-byte are zero, ++ thus bits 0-5 of dxc-byte correspond to the flag-bits. ++ Evaluate flags and last dxc-exception-code. */ ++ newexcepts |= excepts << FPC_DXC_SHIFT; ++ + *flagp = temp & newexcepts; + + /* Success. */ +diff --git a/sysdeps/s390/fpu/fpu_control.h b/sysdeps/s390/fpu/fpu_control.h +index af81bc2..dba904d 100644 +--- a/sysdeps/s390/fpu/fpu_control.h ++++ b/sysdeps/s390/fpu/fpu_control.h +@@ -19,12 +19,12 @@ + . */ + + #ifndef _FPU_CONTROL_H +-# define _FPU_CONTROL_H ++#define _FPU_CONTROL_H + +-# include ++#include + + /* These bits are reserved are not changed. */ +-# define _FPU_RESERVED 0x070700FC ++#define _FPU_RESERVED 0x0707FFFC + + /* The fdlibm code requires no interrupts for exceptions. Don't + change the rounding mode, it would break long double I/O! */ +diff --git a/sysdeps/s390/fpu/fsetexcptflg.c b/sysdeps/s390/fpu/fsetexcptflg.c +index aada675..85c68e8 100644 +--- a/sysdeps/s390/fpu/fsetexcptflg.c ++++ b/sysdeps/s390/fpu/fsetexcptflg.c +@@ -24,16 +24,25 @@ + int + fesetexceptflag (const fexcept_t *flagp, int excepts) + { +- fexcept_t temp,newexcepts; ++ fexcept_t temp, newexcepts; + + /* Get the current environment. We have to do this since we cannot + separately set the status word. */ + _FPU_GETCW (temp); + /* Install the new exception bits in the Accrued Exception Byte. */ + excepts = excepts & FE_ALL_EXCEPT; +- newexcepts = (excepts << FPC_DXC_SHIFT) | (excepts << FPC_FLAGS_SHIFT); ++ newexcepts = excepts << FPC_FLAGS_SHIFT; + temp &= ~newexcepts; +- temp |= *flagp & newexcepts; ++ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) ++ /* Bits 6, 7 of dxc-byte are zero, ++ thus bits 0-5 of dxc-byte correspond to the flag-bits. ++ Clear given exceptions in dxc-field. */ ++ temp &= ~(excepts << FPC_DXC_SHIFT); ++ ++ /* Integrate dxc-byte of flagp into flags. The dxc-byte of flagp contains ++ either an ieee-exception or 0 (see fegetexceptflag). */ ++ temp |= (*flagp | ((*flagp >> FPC_DXC_SHIFT) << FPC_FLAGS_SHIFT)) ++ & newexcepts; + + /* Store the new status word (along with the rest of the environment. + Possibly new exceptions are set but they won't get executed unless +diff --git a/sysdeps/s390/fpu/ftestexcept.c b/sysdeps/s390/fpu/ftestexcept.c +index 5594994..c36aefd 100644 +--- a/sysdeps/s390/fpu/ftestexcept.c ++++ b/sysdeps/s390/fpu/ftestexcept.c +@@ -23,11 +23,17 @@ + int + fetestexcept (int excepts) + { +- fexcept_t temp; ++ fexcept_t temp, res; + + /* Get current exceptions. */ + _FPU_GETCW (temp); +- temp = (temp >> FPC_DXC_SHIFT) | (temp >> FPC_FLAGS_SHIFT); +- return temp & excepts & FE_ALL_EXCEPT; ++ res = temp >> FPC_FLAGS_SHIFT; ++ if ((temp & FPC_NOT_FPU_EXCEPTION) == 0) ++ /* Bits 6, 7 of dxc-byte are zero, ++ thus bits 0-5 of dxc-byte correspond to the flag-bits. ++ Evaluate flags and last dxc-exception-code. */ ++ res |= temp >> FPC_DXC_SHIFT; ++ ++ return res & excepts & FE_ALL_EXCEPT; + } + libm_hidden_def (fetestexcept) +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-5.patch b/SOURCES/glibc-rh1268008-5.patch new file mode 100644 index 00000000..c82603a6 --- /dev/null +++ b/SOURCES/glibc-rh1268008-5.patch @@ -0,0 +1,2341 @@ +From 6db8663b21a826cbf689a297a898675078256166 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:44:39 +0200 +Subject: [PATCH 05/30] S390: Refactor ifunc implementations and enable + ifunc-test-framework. + +upstream-commit-id: 31556246c3ac168a2dfec8f9036d913765bbb73d +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00088.html + +On s390 all ifunc resolvers were implemented in multiarch/ifunc-resolve.c. +The resulting single object files has undefined references to all ifunc-functions. +This patch introduces one multiarch/.c file for each of memcpy, memcmp +and memset with the function specific ifunc resolver. The different function +implementations are now implemented in multiarch/-s390x.S +(moved from multiarch/.S). + +The new multiarch/ifunc-resolve.h file contains the ifunc-resolver macro +and other helper-macros. They are merged and are now used in common for +32/64bit. Therefore the ___g5/___z900 functions were renamed to +___default. + +This patch also enables testing the ifunc implementations by implementing +the function __libc_ifunc_impl_list. It uses the helper-macros of ifunc-resolve.h. + +ChangeLog: + + * sysdeps/s390/s390-32/multiarch/Makefile (sysdep_routines): + Remove ifunc-resolve, add memset-s390, memcpy-s390, memcmp-s390. + * sysdeps/s390/s390-32/multiarch/ifunc-resolve.c: Delete File. + * sysdeps/s390/s390-32/multiarch/memcmp.S: Move to ... + * sysdeps/s390/s390-32/multiarch/memcmp-s390.S: ... here. + (memcmp, bcmp): Use __memcmp_default as alias source. + * sysdeps/s390/s390-32/multiarch/memcmp.c: New File. + * sysdeps/s390/s390-32/memcmp.S (__memcmp_g5): + Rename to __memcmp_default. + * sysdeps/s390/s390-32/multiarch/memcpy.S: Move to ... + * sysdeps/s390/s390-32/multiarch/memcpy-s390.S: ... here. + (memcpy): Use __memcpy_default as alias source. + * sysdeps/s390/s390-32/multiarch/memcpy.c: New File. + * sysdeps/s390/s390-32/memcpy.S (__memcpy_g5): + Rename to __memcpy_default. + * sysdeps/s390/s390-32/multiarch/memset.S: Move to ... + * sysdeps/s390/s390-32/multiarch/memset-s390.S: ... here. + (memset): Use __memset_default as alias source. + * sysdeps/s390/s390-32/multiarch/memset.c: New File. + * sysdeps/s390/s390-32/memset.S (__memset_g5): + Rename to __memset_default. + * sysdeps/s390/s390-64/multiarch/Makefile (sysdep_routines): + Remove ifunc-resolve, add memset-s390x, memcpy-s390x, memcmp-s390x. + * sysdeps/s390/s390-64/multiarch/ifunc-resolve.c: Delete File. + * sysdeps/s390/s390-64/multiarch/memcmp.S: Move to ... + * sysdeps/s390/s390-64/multiarch/memcmp-s390x.S: ... here. + (memcmp, bcmp): Use __memcmp_default as alias source. + * sysdeps/s390/s390-64/multiarch/memcmp.c: New File. + * sysdeps/s390/s390-64/memcmp.S (__memcmp_z900): + Rename to __memcmp_default. + * sysdeps/s390/s390-64/multiarch/memcpy.S: Move to ... + * sysdeps/s390/s390-64/multiarch/memcpy-s390x.S: ... here. + (memcpy): Use __memcpy_default as alias source. + * sysdeps/s390/s390-64/multiarch/memcpy.c: New File. + * sysdeps/s390/s390-64/memcpy.S (__memcpy_z900): + Rename to __memcpy_default. + * sysdeps/s390/s390-64/multiarch/memset.S: Move to ... + * sysdeps/s390/s390-64/multiarch/memset-s390x.S: ... here. + (memset): Use __memset_default as alias source. + * sysdeps/s390/s390-64/multiarch/memset.c: New File. + * sysdeps/s390/s390-64/memset.S (__memset_z900): + Rename to __memset_default. + * sysdeps/s390/multiarch/ifunc-resolve.h: New File. + * sysdeps/s390/multiarch/ifunc-impl-list.c: New File. +--- + sysdeps/s390/multiarch/ifunc-impl-list.c | 74 ++++++++++++++++ + sysdeps/s390/multiarch/ifunc-resolve.h | 75 ++++++++++++++++ + sysdeps/s390/s390-32/memcmp.S | 46 +++++----- + sysdeps/s390/s390-32/memcpy.S | 50 +++++------ + sysdeps/s390/s390-32/memset.S | 44 +++++----- + sysdeps/s390/s390-32/multiarch/Makefile | 3 +- + sysdeps/s390/s390-32/multiarch/ifunc-resolve.c | 72 ---------------- + sysdeps/s390/s390-32/multiarch/memcmp-s390.S | 104 +++++++++++++++++++++++ + sysdeps/s390/s390-32/multiarch/memcmp.S | 104 ----------------------- + sysdeps/s390/s390-32/multiarch/memcmp.c | 24 ++++++ + sysdeps/s390/s390-32/multiarch/memcpy-s390.S | 98 +++++++++++++++++++++ + sysdeps/s390/s390-32/multiarch/memcpy.S | 98 --------------------- + sysdeps/s390/s390-32/multiarch/memcpy.c | 24 ++++++ + sysdeps/s390/s390-32/multiarch/memset-s390.S | 113 +++++++++++++++++++++++++ + sysdeps/s390/s390-32/multiarch/memset.S | 113 ------------------------- + sysdeps/s390/s390-32/multiarch/memset.c | 23 +++++ + sysdeps/s390/s390-64/memcmp.S | 42 ++++----- + sysdeps/s390/s390-64/memcpy.S | 40 ++++----- + sysdeps/s390/s390-64/memset.S | 40 ++++----- + sysdeps/s390/s390-64/multiarch/Makefile | 3 +- + sysdeps/s390/s390-64/multiarch/ifunc-resolve.c | 76 ----------------- + sysdeps/s390/s390-64/multiarch/memcmp-s390x.S | 101 ++++++++++++++++++++++ + sysdeps/s390/s390-64/multiarch/memcmp.S | 101 ---------------------- + sysdeps/s390/s390-64/multiarch/memcmp.c | 24 ++++++ + sysdeps/s390/s390-64/multiarch/memcpy-s390x.S | 94 ++++++++++++++++++++ + sysdeps/s390/s390-64/multiarch/memcpy.S | 94 -------------------- + sysdeps/s390/s390-64/multiarch/memcpy.c | 24 ++++++ + sysdeps/s390/s390-64/multiarch/memset-s390x.S | 109 ++++++++++++++++++++++++ + sysdeps/s390/s390-64/multiarch/memset.S | 109 ------------------------ + sysdeps/s390/s390-64/multiarch/memset.c | 23 +++++ + 30 files changed, 1045 insertions(+), 900 deletions(-) + create mode 100644 sysdeps/s390/multiarch/ifunc-impl-list.c + create mode 100644 sysdeps/s390/multiarch/ifunc-resolve.h + delete mode 100644 sysdeps/s390/s390-32/multiarch/ifunc-resolve.c + create mode 100644 sysdeps/s390/s390-32/multiarch/memcmp-s390.S + delete mode 100644 sysdeps/s390/s390-32/multiarch/memcmp.S + create mode 100644 sysdeps/s390/s390-32/multiarch/memcmp.c + create mode 100644 sysdeps/s390/s390-32/multiarch/memcpy-s390.S + delete mode 100644 sysdeps/s390/s390-32/multiarch/memcpy.S + create mode 100644 sysdeps/s390/s390-32/multiarch/memcpy.c + create mode 100644 sysdeps/s390/s390-32/multiarch/memset-s390.S + delete mode 100644 sysdeps/s390/s390-32/multiarch/memset.S + create mode 100644 sysdeps/s390/s390-32/multiarch/memset.c + delete mode 100644 sysdeps/s390/s390-64/multiarch/ifunc-resolve.c + create mode 100644 sysdeps/s390/s390-64/multiarch/memcmp-s390x.S + delete mode 100644 sysdeps/s390/s390-64/multiarch/memcmp.S + create mode 100644 sysdeps/s390/s390-64/multiarch/memcmp.c + create mode 100644 sysdeps/s390/s390-64/multiarch/memcpy-s390x.S + delete mode 100644 sysdeps/s390/s390-64/multiarch/memcpy.S + create mode 100644 sysdeps/s390/s390-64/multiarch/memcpy.c + create mode 100644 sysdeps/s390/s390-64/multiarch/memset-s390x.S + delete mode 100644 sysdeps/s390/s390-64/multiarch/memset.S + create mode 100644 sysdeps/s390/s390-64/multiarch/memset.c + +diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c +new file mode 100644 +index 0000000..c330904 +--- /dev/null ++++ b/sysdeps/s390/multiarch/ifunc-impl-list.c +@@ -0,0 +1,74 @@ ++/* Enumerate available IFUNC implementations of a function. s390/s390x version. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* Maximum number of IFUNC implementations. */ ++#define MAX_IFUNC 3 ++ ++/* Fill ARRAY of MAX elements with IFUNC implementations for function ++ NAME supported on target machine and return the number of valid ++ entries. */ ++size_t ++__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, ++ size_t max) ++{ ++ assert (max >= MAX_IFUNC); ++ ++ size_t i = 0; ++ ++ /* Get hardware information. */ ++ unsigned long int dl_hwcap = GLRO (dl_hwcap); ++ unsigned long long stfle_bits = 0ULL; ++ if ((dl_hwcap & HWCAP_S390_STFLE) ++ && (dl_hwcap & HWCAP_S390_ZARCH) ++ && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) ++ { ++ S390_STORE_STFLE (stfle_bits); ++ } ++ ++ IFUNC_IMPL (i, name, memset, ++ IFUNC_IMPL_ADD (array, i, memset, ++ S390_IS_Z196 (stfle_bits), __memset_z196) ++ IFUNC_IMPL_ADD (array, i, memset, ++ S390_IS_Z10 (stfle_bits), __memset_z10) ++ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_default)) ++ ++ IFUNC_IMPL (i, name, memcmp, ++ IFUNC_IMPL_ADD (array, i, memcmp, ++ S390_IS_Z196 (stfle_bits), __memcmp_z196) ++ IFUNC_IMPL_ADD (array, i, memcmp, ++ S390_IS_Z10 (stfle_bits), __memcmp_z10) ++ IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_default)) ++ ++#ifdef SHARED ++ ++ IFUNC_IMPL (i, name, memcpy, ++ IFUNC_IMPL_ADD (array, i, memcpy, ++ S390_IS_Z196 (stfle_bits), __memcpy_z196) ++ IFUNC_IMPL_ADD (array, i, memcpy, ++ S390_IS_Z10 (stfle_bits), __memcpy_z10) ++ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default)) ++ ++#endif /* SHARED */ ++ ++ return i; ++} +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +new file mode 100644 +index 0000000..491df68 +--- /dev/null ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -0,0 +1,75 @@ ++/* IFUNC resolver function for CPU specific functions. ++ 32/64 bit S/390 version. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define S390_STFLE_BITS_Z10 34 /* General instructions extension */ ++#define S390_STFLE_BITS_Z196 45 /* Distinct operands, pop ... */ ++ ++#define S390_IS_Z196(STFLE_BITS) \ ++ ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z196))) != 0) ++ ++#define S390_IS_Z10(STFLE_BITS) \ ++ ((STFLE_BITS & (1ULL << (63 - S390_STFLE_BITS_Z10))) != 0) ++ ++#define S390_STORE_STFLE(STFLE_BITS) \ ++ /* We want just 1 double word to be returned. */ \ ++ register unsigned long reg0 asm("0") = 0; \ ++ \ ++ asm volatile(".machine push" "\n\t" \ ++ ".machine \"z9-109\"" "\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ "stfle %0" "\n\t" \ ++ ".machine pop" "\n" \ ++ : "=QS" (STFLE_BITS), "+d" (reg0) \ ++ : : "cc"); ++ ++#define s390_libc_ifunc(FUNC) \ ++ asm (".globl " #FUNC "\n\t" \ ++ ".type " #FUNC ",@gnu_indirect_function\n\t" \ ++ ".set " #FUNC ",__resolve_" #FUNC "\n\t" \ ++ ".globl __GI_" #FUNC "\n\t" \ ++ ".set __GI_" #FUNC "," #FUNC "\n"); \ ++ \ ++ /* Make the declarations of the optimized functions hidden in order ++ to prevent GOT slots being generated for them. */ \ ++ extern void *__##FUNC##_z196 attribute_hidden; \ ++ extern void *__##FUNC##_z10 attribute_hidden; \ ++ extern void *__##FUNC##_default attribute_hidden; \ ++ \ ++ void *__resolve_##FUNC (unsigned long int dl_hwcap) \ ++ { \ ++ if ((dl_hwcap & HWCAP_S390_STFLE) \ ++ && (dl_hwcap & HWCAP_S390_ZARCH) \ ++ && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) \ ++ { \ ++ unsigned long long stfle_bits; \ ++ S390_STORE_STFLE (stfle_bits); \ ++ \ ++ if (S390_IS_Z196 (stfle_bits)) \ ++ return &__##FUNC##_z196; \ ++ else if (S390_IS_Z10 (stfle_bits)) \ ++ return &__##FUNC##_z10; \ ++ else \ ++ return &__##FUNC##_default; \ ++ } \ ++ else \ ++ return &__##FUNC##_default; \ ++ } +diff --git a/sysdeps/s390/s390-32/memcmp.S b/sysdeps/s390/s390-32/memcmp.S +index b6eabe5..104e280 100644 +--- a/sysdeps/s390/s390-32/memcmp.S ++++ b/sysdeps/s390/s390-32/memcmp.S +@@ -27,38 +27,38 @@ + + .text + #ifdef USE_MULTIARCH +-ENTRY(__memcmp_g5) ++ENTRY(__memcmp_default) + #else + ENTRY(memcmp) + #endif + .machine "g5" +- basr %r5,0 ++ basr %r5,0 + .L_G5_16: +- ltr %r4,%r4 +- je .L_G5_4 +- ahi %r4,-1 +- lr %r1,%r4 +- srl %r1,8 +- ltr %r1,%r1 +- jne .L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r5) ++ ltr %r4,%r4 ++ je .L_G5_4 ++ ahi %r4,-1 ++ lr %r1,%r4 ++ srl %r1,8 ++ ltr %r1,%r1 ++ jne .L_G5_12 ++ ex %r4,.L_G5_17-.L_G5_16(%r5) + .L_G5_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 ++ ipm %r2 ++ sll %r2,2 ++ sra %r2,30 ++ br %r14 + .L_G5_12: +- clc 0(256,%r3),0(%r2) +- jne .L_G5_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brct %r1,.L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r5) +- j .L_G5_4 ++ clc 0(256,%r3),0(%r2) ++ jne .L_G5_4 ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ brct %r1,.L_G5_12 ++ ex %r4,.L_G5_17-.L_G5_16(%r5) ++ j .L_G5_4 + .L_G5_17: +- clc 0(1,%r3),0(%r2) ++ clc 0(1,%r3),0(%r2) + #ifdef USE_MULTIARCH +-END(__memcmp_g5) ++END(__memcmp_default) + #else + END(memcmp) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/s390/s390-32/memcpy.S b/sysdeps/s390/s390-32/memcpy.S +index a3b1ace..6a2cf68 100644 +--- a/sysdeps/s390/s390-32/memcpy.S ++++ b/sysdeps/s390/s390-32/memcpy.S +@@ -26,41 +26,41 @@ + %r4 = number of bytes to copy. */ + + #ifdef USE_MULTIARCH +-ENTRY(__memcpy_g5) ++ENTRY(__memcpy_default) + #else + ENTRY(memcpy) + #endif + .machine "g5" +- st %r13,52(%r15) +- .cfi_offset 13, -44 +- basr %r13,0 ++ st %r13,52(%r15) ++ .cfi_offset 13, -44 ++ basr %r13,0 + .L_G5_16: +- ltr %r4,%r4 +- je .L_G5_4 +- ahi %r4,-1 +- lr %r5,%r4 +- srl %r5,8 +- ltr %r5,%r5 +- lr %r1,%r2 +- jne .L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r13) ++ ltr %r4,%r4 ++ je .L_G5_4 ++ ahi %r4,-1 ++ lr %r5,%r4 ++ srl %r5,8 ++ ltr %r5,%r5 ++ lr %r1,%r2 ++ jne .L_G5_12 ++ ex %r4,.L_G5_17-.L_G5_16(%r13) + .L_G5_4: +- l %r13,52(%r15) +- br %r14 ++ l %r13,52(%r15) ++ br %r14 + .L_G5_13: +- chi %r5,4096 # Switch to mvcle for copies >1MB +- jh __memcpy_mvcle ++ chi %r5,4096 # Switch to mvcle for copies >1MB ++ jh __memcpy_mvcle + .L_G5_12: +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brct %r5,.L_G5_12 +- ex %r4,.L_G5_17-.L_G5_16(%r13) +- j .L_G5_4 ++ mvc 0(256,%r1),0(%r3) ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ brct %r5,.L_G5_12 ++ ex %r4,.L_G5_17-.L_G5_16(%r13) ++ j .L_G5_4 + .L_G5_17: +- mvc 0(1,%r1),0(%r3) ++ mvc 0(1,%r1),0(%r3) + #ifdef USE_MULTIARCH +-END(__memcpy_g5) ++END(__memcpy_default) + #else + END(memcpy) + libc_hidden_builtin_def (memcpy) +diff --git a/sysdeps/s390/s390-32/memset.S b/sysdeps/s390/s390-32/memset.S +index a73dc6c..d363cf1 100644 +--- a/sysdeps/s390/s390-32/memset.S ++++ b/sysdeps/s390/s390-32/memset.S +@@ -28,37 +28,37 @@ + .text + + #ifdef USE_MULTIARCH +-ENTRY(__memset_g5) ++ENTRY(__memset_default) + #else + ENTRY(memset) + #endif + .machine "g5" +- basr %r5,0 ++ basr %r5,0 + .L_G5_19: +- ltr %r4,%r4 +- je .L_G5_4 +- stc %r3,0(%r2) +- chi %r4,1 +- lr %r1,%r2 +- je .L_G5_4 +- ahi %r4,-2 +- lr %r3,%r4 +- srl %r3,8 +- ltr %r3,%r3 +- jne .L_G5_14 +- ex %r4,.L_G5_20-.L_G5_19(%r5) ++ ltr %r4,%r4 ++ je .L_G5_4 ++ stc %r3,0(%r2) ++ chi %r4,1 ++ lr %r1,%r2 ++ je .L_G5_4 ++ ahi %r4,-2 ++ lr %r3,%r4 ++ srl %r3,8 ++ ltr %r3,%r3 ++ jne .L_G5_14 ++ ex %r4,.L_G5_20-.L_G5_19(%r5) + .L_G5_4: +- br %r14 ++ br %r14 + .L_G5_14: +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brct %r3,.L_G5_14 +- ex %r4,.L_G5_20-.L_G5_19(%r5) +- j .L_G5_4 ++ mvc 1(256,%r1),0(%r1) ++ la %r1,256(%r1) ++ brct %r3,.L_G5_14 ++ ex %r4,.L_G5_20-.L_G5_19(%r5) ++ j .L_G5_4 + .L_G5_20: +- mvc 1(1,%r1),0(%r1) ++ mvc 1(1,%r1),0(%r1) + #ifdef USE_MULTIARCH +-END(__memset_g5) ++END(__memset_default) + #else + END(memset) + libc_hidden_builtin_def (memset) +diff --git a/sysdeps/s390/s390-32/multiarch/Makefile b/sysdeps/s390/s390-32/multiarch/Makefile +index 9baeecd..f8aee14 100644 +--- a/sysdeps/s390/s390-32/multiarch/Makefile ++++ b/sysdeps/s390/s390-32/multiarch/Makefile +@@ -1,3 +1,4 @@ + ifeq ($(subdir),string) +-sysdep_routines += ifunc-resolve memset memcpy memcmp ++sysdep_routines += memset memset-s390 memcpy memcpy-s390 \ ++ memcmp memcmp-s390 + endif +diff --git a/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c b/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c +deleted file mode 100644 +index 522c63c..0000000 +--- a/sysdeps/s390/s390-32/multiarch/ifunc-resolve.c ++++ /dev/null +@@ -1,72 +0,0 @@ +-/* IFUNC resolver function for CPU specific functions. +- 32 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-#define STFLE_BITS_Z10 34 /* General instructions extension */ +-#define STFLE_BITS_Z196 45 /* Distinct operands, pop ... */ +- +-#ifndef NOT_IN_libc +- +-#define IFUNC_RESOLVE(FUNC) \ +- asm (".globl " #FUNC "\n\t" \ +- ".type " #FUNC ",@gnu_indirect_function\n\t" \ +- ".set " #FUNC ",__resolve_" #FUNC "\n\t" \ +- ".globl __GI_" #FUNC "\n\t" \ +- ".set __GI_" #FUNC "," #FUNC "\n"); \ +- \ +- /* Make the declarations of the optimized functions hidden in order +- to prevent GOT slots being generated for them. */ \ +- extern void *__##FUNC##_z196 attribute_hidden; \ +- extern void *__##FUNC##_z10 attribute_hidden; \ +- extern void *__##FUNC##_g5 attribute_hidden; \ +- \ +- void *__resolve_##FUNC (unsigned long int dl_hwcap) \ +- { \ +- if ((dl_hwcap & HWCAP_S390_STFLE) \ +- && (dl_hwcap & HWCAP_S390_ZARCH) \ +- && (dl_hwcap & HWCAP_S390_HIGH_GPRS)) \ +- { \ +- /* We want just 1 double word to be returned. */ \ +- register unsigned long reg0 asm("0") = 0; \ +- unsigned long long stfle_bits; \ +- \ +- asm volatile(".insn s,0xb2b00000,%0" "\n\t" /* stfle */ \ +- : "=QS" (stfle_bits), "+d" (reg0) \ +- : : "cc"); \ +- \ +- if ((stfle_bits & (1ULL << (63 - STFLE_BITS_Z196))) != 0) \ +- return &__##FUNC##_z196; \ +- else if ((stfle_bits & (1ULL << (63 - STFLE_BITS_Z10))) != 0) \ +- return &__##FUNC##_z10; \ +- } \ +- return &__##FUNC##_g5; \ +- } +- +-IFUNC_RESOLVE(memset) +-IFUNC_RESOLVE(memcmp) +-asm(".weak bcmp ; bcmp = memcmp"); +- +-/* In the static lib memcpy is needed before the reloc is resolved. */ +-#ifdef SHARED +-IFUNC_RESOLVE(memcpy) +-#endif +- +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp-s390.S b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +new file mode 100644 +index 0000000..b339aac +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memcmp-s390.S +@@ -0,0 +1,104 @@ ++/* CPU specific memcmp implementations. 32 bit S/390 version. ++ Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* INPUT PARAMETERS ++ %r2 = address of first memory area ++ %r3 = address of second memory area ++ %r4 = number of bytes to compare. */ ++ ++ .text ++ ++#ifndef NOT_IN_libc ++ ++ENTRY(__memcmp_z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ ltr %r4,%r4 ++ je .L_Z196_4 ++ ahi %r4,-1 ++ srlk %r1,%r4,8 ++ ltr %r1,%r1 ++ jne .L_Z196_2 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ ipm %r2 ++ sll %r2,2 ++ sra %r2,30 ++ br %r14 ++.L_Z196_17: ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ ahi %r1,-1 ++ je .L_Z196_3 ++.L_Z196_2: ++ pfd 1,512(%r3) ++ pfd 1,512(%r2) ++ clc 0(256,%r3),0(%r2) ++ je .L_Z196_17 ++ ipm %r2 ++ sll %r2,2 ++ sra %r2,30 ++ br %r14 ++.L_Z196_14: ++ clc 0(1,%r3),0(%r2) ++END(__memcmp_z196) ++ ++ENTRY(__memcmp_z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ ltr %r4,%r4 ++ je .L_Z10_4 ++ ahi %r4,-1 ++ lr %r1,%r4 ++ srl %r1,8 ++ cijlh %r1,0,.L_Z10_12 ++.L_Z10_3: ++ exrl %r4,.L_Z10_15 ++.L_Z10_4: ++ ipm %r2 ++ sll %r2,2 ++ sra %r2,30 ++ br %r14 ++.L_Z10_12: ++ pfd 1,512(%r3) ++ pfd 1,512(%r2) ++ clc 0(256,%r3),0(%r2) ++ jne .L_Z10_4 ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ brct %r1,.L_Z10_12 ++ j .L_Z10_3 ++.L_Z10_15: ++ clc 0(1,%r3),0(%r2) ++END(__memcmp_z10) ++ ++#endif /* !NOT_IN_libc */ ++ ++#include "../memcmp.S" ++ ++#ifdef NOT_IN_libc ++.globl memcmp ++.set memcmp,__memcmp_default ++.weak bcmp ++.set bcmp,__memcmp_default ++#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.S b/sysdeps/s390/s390-32/multiarch/memcmp.S +deleted file mode 100644 +index c654d19..0000000 +--- a/sysdeps/s390/s390-32/multiarch/memcmp.S ++++ /dev/null +@@ -1,104 +0,0 @@ +-/* CPU specific memcmp implementations. 32 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +- +-#ifndef NOT_IN_libc +- +-ENTRY(__memcmp_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- ltr %r4,%r4 +- je .L_Z196_4 +- ahi %r4,-1 +- srlk %r1,%r4,8 +- ltr %r1,%r1 +- jne .L_Z196_2 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z196_17: +- la %r3,256(%r3) +- la %r2,256(%r2) +- ahi %r1,-1 +- je .L_Z196_3 +-.L_Z196_2: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- je .L_Z196_17 +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z196_14: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z196) +- +-ENTRY(__memcmp_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- ltr %r4,%r4 +- je .L_Z10_4 +- ahi %r4,-1 +- lr %r1,%r4 +- srl %r1,8 +- cijlh %r1,0,.L_Z10_12 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- ipm %r2 +- sll %r2,2 +- sra %r2,30 +- br %r14 +-.L_Z10_12: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- jne .L_Z10_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brct %r1,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z10) +- +-#endif +- +-#include "../memcmp.S" +- +-#ifdef NOT_IN_libc +-.globl memcmp +-.set memcmp,__memcmp_g5 +-.weak bcmp +-.set bcmp,__memcmp_g5 +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/s390-32/multiarch/memcmp.c +new file mode 100644 +index 0000000..7089d56 +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memcmp.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of memcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++ ++s390_libc_ifunc (memcmp) ++asm(".weak bcmp ; bcmp = memcmp"); ++#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy-s390.S b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +new file mode 100644 +index 0000000..f6e0fea +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memcpy-s390.S +@@ -0,0 +1,98 @@ ++/* CPU specific memcpy implementations. 32 bit S/390 version. ++ Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* INPUT PARAMETERS ++ %r2 = target operands address ++ %r3 = source operands address ++ %r4 = number of bytes to copy. */ ++ ++ .text ++ ++#if defined SHARED && !defined NOT_IN_libc ++ ++ENTRY(__memcpy_z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ llgfr %r4,%r4 ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ lr %r1,%r2 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_5 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ br %r14 ++.L_Z196_5: ++ cgfi %r5,262144 # Switch to mvcle for copies >64MB ++ jh __memcpy_mvcle ++.L_Z196_2: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_14: ++ mvc 0(1,%r1),0(%r3) ++END(__memcpy_z196) ++ ++ENTRY(__memcpy_z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ llgfr %r4,%r4 ++ cgije %r4,0,.L_Z10_4 ++ aghi %r4,-1 ++ lr %r1,%r2 ++ srlg %r5,%r4,8 ++ cgijlh %r5,0,.L_Z10_13 ++.L_Z10_3: ++ exrl %r4,.L_Z10_15 ++.L_Z10_4: ++ br %r14 ++.L_Z10_13: ++ cgfi %r5,65535 # Switch to mvcle for copies >16MB ++ jh __memcpy_mvcle ++.L_Z10_12: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ brctg %r5,.L_Z10_12 ++ j .L_Z10_3 ++.L_Z10_15: ++ mvc 0(1,%r1),0(%r3) ++END(__memcpy_z10) ++ ++#endif /* SHARED && !defined NOT_IN_libc */ ++ ++#include "../memcpy.S" ++ ++#if !defined SHARED || defined NOT_IN_libc ++.globl memcpy ++.set memcpy,__memcpy_default ++#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.S b/sysdeps/s390/s390-32/multiarch/memcpy.S +deleted file mode 100644 +index 5c2113f..0000000 +--- a/sysdeps/s390/s390-32/multiarch/memcpy.S ++++ /dev/null +@@ -1,98 +0,0 @@ +-/* CPU specific memcpy implementations. 32 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = target operands address +- %r3 = source operands address +- %r4 = number of bytes to copy. */ +- +- .text +- +-#if defined SHARED && !defined NOT_IN_libc +- +-ENTRY(__memcpy_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- lr %r1,%r2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_5 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- br %r14 +-.L_Z196_5: +- cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh __memcpy_mvcle +-.L_Z196_2: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- aghi %r5,-1 +- la %r1,256(%r1) +- la %r3,256(%r3) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_14: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z196) +- +-ENTRY(__memcpy_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- cgije %r4,0,.L_Z10_4 +- aghi %r4,-1 +- lr %r1,%r2 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_13 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- br %r14 +-.L_Z10_13: +- cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh __memcpy_mvcle +-.L_Z10_12: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z10) +- +-#endif +- +-#include "../memcpy.S" +- +-#if !defined SHARED || defined NOT_IN_libc +-.globl memcpy +-.set memcpy,__memcpy_g5 +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c +new file mode 100644 +index 0000000..1ff31bb +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memcpy.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of memcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* In the static lib memcpy is needed before the reloc is resolved. */ ++#if defined SHARED && !defined NOT_IN_libc ++# include ++ ++s390_libc_ifunc (memcpy) ++#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memset-s390.S b/sysdeps/s390/s390-32/multiarch/memset-s390.S +new file mode 100644 +index 0000000..f6df2fa +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memset-s390.S +@@ -0,0 +1,113 @@ ++/* Set a block of memory to some byte value. 32 bit S/390 version. ++ Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* INPUT PARAMETERS ++ %r2 = address of memory area ++ %r3 = byte to fill memory with ++ %r4 = number of bytes to fill. */ ++ ++ .text ++ ++#ifndef NOT_IN_libc ++ ++ENTRY(__memset_z196) ++ .machine "z196" ++ .machinemode "zarch_nohighgprs" ++ llgfr %r4,%r4 ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ stc %r3,0(%r2) ++ lr %r1,%r2 ++ cghi %r4,1 ++ je .L_Z196_4 ++ aghi %r4,-2 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_1 ++.L_Z196_3: ++ exrl %r4,.L_Z196_17 ++.L_Z196_4: ++ br %r14 ++.L_Z196_1: ++ cgfi %r5,1048576 ++ jh __memset_mvcle # Switch to mvcle for >256MB ++.L_Z196_2: ++ pfd 2,1024(%r1) ++ mvc 1(256,%r1),0(%r1) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_17: ++ mvc 1(1,%r1),0(%r1) ++END(__memset_z196) ++ ++ENTRY(__memset_z10) ++ .machine "z10" ++ .machinemode "zarch_nohighgprs" ++ llgfr %r4,%r4 ++ cgije %r4,0,.L_Z10_4 ++ stc %r3,0(%r2) ++ lr %r1,%r2 ++ cgije %r4,1,.L_Z10_4 ++ aghi %r4,-2 ++ srlg %r5,%r4,8 ++ cgijlh %r5,0,.L_Z10_15 ++.L_Z10_3: ++ exrl %r4,.L_Z10_18 ++.L_Z10_4: ++ br %r14 ++.L_Z10_15: ++ cgfi %r5,163840 # Switch to mvcle for >40MB ++ jh __memset_mvcle ++.L_Z10_14: ++ pfd 2,1024(%r1) ++ mvc 1(256,%r1),0(%r1) ++ la %r1,256(%r1) ++ brctg %r5,.L_Z10_14 ++ j .L_Z10_3 ++.L_Z10_18: ++ mvc 1(1,%r1),0(%r1) ++END(__memset_z10) ++ ++ENTRY(__memset_mvcle) ++ ahi %r4,2 # take back the change done by the caller ++ lr %r0,%r2 # save source address ++ lr %r1,%r3 # move pad byte to R1 ++ lr %r3,%r4 ++ sr %r4,%r4 # no source for MVCLE, only a pad byte ++ sr %r5,%r5 ++.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend ++ jo .L0 ++ lr %r2,%r0 # return value is source address ++.L1: ++ br %r14 ++END(__memset_mvcle) ++ ++#endif /* !NOT_IN_libc */ ++ ++#include "../memset.S" ++ ++#ifdef NOT_IN_libc ++.globl memset ++.set memset,__memset_default ++#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memset.S b/sysdeps/s390/s390-32/multiarch/memset.S +deleted file mode 100644 +index 54aa028..0000000 +--- a/sysdeps/s390/s390-32/multiarch/memset.S ++++ /dev/null +@@ -1,113 +0,0 @@ +-/* Set a block of memory to some byte value. 32 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#ifndef NOT_IN_libc +- +-ENTRY(__memset_z196) +- .machine "z196" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- ltgr %r4,%r4 +- je .L_Z196_4 +- stc %r3,0(%r2) +- lr %r1,%r2 +- cghi %r4,1 +- je .L_Z196_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_1 +-.L_Z196_3: +- exrl %r4,.L_Z196_17 +-.L_Z196_4: +- br %r14 +-.L_Z196_1: +- cgfi %r5,1048576 +- jh __memset_mvcle # Switch to mvcle for >256MB +-.L_Z196_2: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- aghi %r5,-1 +- la %r1,256(%r1) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_17: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z196) +- +-ENTRY(__memset_z10) +- .machine "z10" +- .machinemode "zarch_nohighgprs" +- llgfr %r4,%r4 +- cgije %r4,0,.L_Z10_4 +- stc %r3,0(%r2) +- lr %r1,%r2 +- cgije %r4,1,.L_Z10_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_15 +-.L_Z10_3: +- exrl %r4,.L_Z10_18 +-.L_Z10_4: +- br %r14 +-.L_Z10_15: +- cgfi %r5,163840 # Switch to mvcle for >40MB +- jh __memset_mvcle +-.L_Z10_14: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brctg %r5,.L_Z10_14 +- j .L_Z10_3 +-.L_Z10_18: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z10) +- +-ENTRY(__memset_mvcle) +- ahi %r4,2 # take back the change done by the caller +- lr %r0,%r2 # save source address +- lr %r1,%r3 # move pad byte to R1 +- lr %r3,%r4 +- sr %r4,%r4 # no source for MVCLE, only a pad byte +- sr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +- lr %r2,%r0 # return value is source address +-.L1: +- br %r14 +-END(__memset_mvcle) +- +-#endif +- +-#include "../memset.S" +- +-#ifdef NOT_IN_libc +-.globl memset +-.set memset,__memset_g5 +-#endif +diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c +new file mode 100644 +index 0000000..3b15446 +--- /dev/null ++++ b/sysdeps/s390/s390-32/multiarch/memset.c +@@ -0,0 +1,23 @@ ++/* Multiple versions of memset. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++ ++s390_libc_ifunc (memset) ++#endif +diff --git a/sysdeps/s390/s390-64/memcmp.S b/sysdeps/s390/s390-64/memcmp.S +index eb5370f..1d7e788 100644 +--- a/sysdeps/s390/s390-64/memcmp.S ++++ b/sysdeps/s390/s390-64/memcmp.S +@@ -27,36 +27,36 @@ + + .text + #ifdef USE_MULTIARCH +-ENTRY(__memcmp_z900) ++ENTRY(__memcmp_default) + #else + ENTRY(memcmp) + #endif + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 +- aghi %r4,-1 +- srlg %r1,%r4,8 +- ltgr %r1,%r1 +- jne .L_Z900_12 ++ ltgr %r4,%r4 ++ je .L_Z900_4 ++ aghi %r4,-1 ++ srlg %r1,%r4,8 ++ ltgr %r1,%r1 ++ jne .L_Z900_12 + .L_Z900_3: +- larl %r1,.L_Z900_15 +- ex %r4,0(%r1) ++ larl %r1,.L_Z900_15 ++ ex %r4,0(%r1) + .L_Z900_4: +- ipm %r2 +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +- br %r14 ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 + .L_Z900_12: +- clc 0(256,%r3),0(%r2) +- jne .L_Z900_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brctg %r1,.L_Z900_12 +- j .L_Z900_3 ++ clc 0(256,%r3),0(%r2) ++ jne .L_Z900_4 ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ brctg %r1,.L_Z900_12 ++ j .L_Z900_3 + .L_Z900_15: +- clc 0(1,%r3),0(%r2) ++ clc 0(1,%r3),0(%r2) + #ifdef USE_MULTIARCH +-END(__memcmp_z900) ++END(__memcmp_default) + #else + END(memcmp) + libc_hidden_builtin_def (memcmp) +diff --git a/sysdeps/s390/s390-64/memcpy.S b/sysdeps/s390/s390-64/memcpy.S +index 61fca0b..6827a0e 100644 +--- a/sysdeps/s390/s390-64/memcpy.S ++++ b/sysdeps/s390/s390-64/memcpy.S +@@ -29,37 +29,37 @@ + .text + + #ifdef USE_MULTIARCH +-ENTRY(__memcpy_z900) ++ENTRY(__memcpy_default) + #else + ENTRY(memcpy) + #endif + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 +- aghi %r4,-1 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- lgr %r1,%r2 +- jne .L_Z900_13 ++ ltgr %r4,%r4 ++ je .L_Z900_4 ++ aghi %r4,-1 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ lgr %r1,%r2 ++ jne .L_Z900_13 + .L_Z900_3: +- larl %r5,.L_Z900_15 +- ex %r4,0(%r5) ++ larl %r5,.L_Z900_15 ++ ex %r4,0(%r5) + .L_Z900_4: +- br %r14 ++ br %r14 + .L_Z900_13: +- chi %r5,4096 # Switch to mvcle for copies >1MB +- jh __memcpy_mvcle ++ chi %r5,4096 # Switch to mvcle for copies >1MB ++ jh __memcpy_mvcle + .L_Z900_12: +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z900_12 +- j .L_Z900_3 ++ mvc 0(256,%r1),0(%r3) ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ brctg %r5,.L_Z900_12 ++ j .L_Z900_3 + .L_Z900_15: +- mvc 0(1,%r1),0(%r3) ++ mvc 0(1,%r1),0(%r3) + + #ifdef USE_MULTIARCH +-END(__memcpy_z900) ++END(__memcpy_default) + #else + END(memcpy) + libc_hidden_builtin_def (memcpy) +diff --git a/sysdeps/s390/s390-64/memset.S b/sysdeps/s390/s390-64/memset.S +index 8185e94..b1ba9e2 100644 +--- a/sysdeps/s390/s390-64/memset.S ++++ b/sysdeps/s390/s390-64/memset.S +@@ -29,35 +29,35 @@ + .text + + #ifdef USE_MULTIARCH +-ENTRY(__memset_z900) ++ENTRY(__memset_default) + #else + ENTRY(memset) + #endif + .machine "z900" +- ltgr %r4,%r4 +- je .L_Z900_4 +- stc %r3,0(%r2) +- cghi %r4,1 +- lgr %r1,%r2 +- je .L_Z900_4 +- aghi %r4,-2 +- srlg %r3,%r4,8 +- ltgr %r3,%r3 +- jne .L_Z900_14 ++ ltgr %r4,%r4 ++ je .L_Z900_4 ++ stc %r3,0(%r2) ++ cghi %r4,1 ++ lgr %r1,%r2 ++ je .L_Z900_4 ++ aghi %r4,-2 ++ srlg %r3,%r4,8 ++ ltgr %r3,%r3 ++ jne .L_Z900_14 + .L_Z900_3: +- larl %r3,.L_Z900_18 +- ex %r4,0(%r3) ++ larl %r3,.L_Z900_18 ++ ex %r4,0(%r3) + .L_Z900_4: +- br %r14 ++ br %r14 + .L_Z900_14: +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brctg %r3,.L_Z900_14 +- j .L_Z900_3 ++ mvc 1(256,%r1),0(%r1) ++ la %r1,256(%r1) ++ brctg %r3,.L_Z900_14 ++ j .L_Z900_3 + .L_Z900_18: +- mvc 1(1,%r1),0(%r1) ++ mvc 1(1,%r1),0(%r1) + #ifdef USE_MULTIARCH +-END(__memset_z900) ++END(__memset_default) + #else + END(memset) + libc_hidden_builtin_def (memset) +diff --git a/sysdeps/s390/s390-64/multiarch/Makefile b/sysdeps/s390/s390-64/multiarch/Makefile +index 9baeecd..91053b5 100644 +--- a/sysdeps/s390/s390-64/multiarch/Makefile ++++ b/sysdeps/s390/s390-64/multiarch/Makefile +@@ -1,3 +1,4 @@ + ifeq ($(subdir),string) +-sysdep_routines += ifunc-resolve memset memcpy memcmp ++sysdep_routines += memset memset-s390x memcpy memcpy-s390x \ ++ memcmp memcmp-s390x + endif +diff --git a/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c b/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c +deleted file mode 100644 +index b6be970..0000000 +--- a/sysdeps/s390/s390-64/multiarch/ifunc-resolve.c ++++ /dev/null +@@ -1,76 +0,0 @@ +-/* IFUNC resolver function for CPU specific functions. +- 64 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-#define STFLE_BITS_Z10 34 /* General instructions extension */ +-#define STFLE_BITS_Z196 45 /* Distinct operands, pop ... */ +- +-#ifndef NOT_IN_libc +- +-#define IFUNC_RESOLVE(FUNC) \ +- asm (".globl " #FUNC "\n\t" \ +- ".type " #FUNC ",@gnu_indirect_function\n\t" \ +- ".set " #FUNC ",__resolve_" #FUNC "\n\t" \ +- ".globl __GI_" #FUNC "\n\t" \ +- ".set __GI_" #FUNC "," #FUNC "\n"); \ +- \ +- /* Make the declarations of the optimized functions hidden in order +- to prevent GOT slots being generated for them. */ \ +- extern void *__##FUNC##_z196 attribute_hidden; \ +- extern void *__##FUNC##_z10 attribute_hidden; \ +- extern void *__##FUNC##_z900 attribute_hidden; \ +- \ +- void *__resolve_##FUNC (unsigned long int dl_hwcap) \ +- { \ +- if (dl_hwcap & HWCAP_S390_STFLE) \ +- { \ +- /* We want just 1 double word to be returned. */ \ +- register unsigned long reg0 asm("0") = 0; \ +- unsigned long stfle_bits; \ +- \ +- asm volatile(".machine push" "\n\t" \ +- ".machine \"z9-109\"" "\n\t" \ +- "stfle %0" "\n\t" \ +- ".machine pop" "\n" \ +- : "=QS" (stfle_bits), "+d" (reg0) \ +- : : "cc"); \ +- \ +- if ((stfle_bits & (1UL << (63 - STFLE_BITS_Z196))) != 0) \ +- return &__##FUNC##_z196; \ +- else if ((stfle_bits & (1UL << (63 - STFLE_BITS_Z10))) != 0) \ +- return &__##FUNC##_z10; \ +- else \ +- return &__##FUNC##_z900; \ +- } \ +- else \ +- return &__##FUNC##_z900; \ +- } +- +-IFUNC_RESOLVE(memset) +-IFUNC_RESOLVE(memcmp) +-asm(".weak bcmp ; bcmp = memcmp"); +- +-/* In the static lib memcpy is needed before the reloc is resolved. */ +-#ifdef SHARED +-IFUNC_RESOLVE(memcpy) +-#endif +- +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +new file mode 100644 +index 0000000..6d55b0b +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S +@@ -0,0 +1,101 @@ ++/* CPU specific memcmp implementations. 64 bit S/390 version. ++ Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* INPUT PARAMETERS ++ %r2 = address of first memory area ++ %r3 = address of second memory area ++ %r4 = number of bytes to compare. */ ++ ++ .text ++ ++#ifndef NOT_IN_libc ++ ++ENTRY(__memcmp_z196) ++ .machine "z196" ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ srlg %r1,%r4,8 ++ ltgr %r1,%r1 ++ jne .L_Z196_2 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z196_17: ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ aghi %r1,-1 ++ je .L_Z196_3 ++.L_Z196_2: ++ pfd 1,512(%r3) ++ pfd 1,512(%r2) ++ clc 0(256,%r3),0(%r2) ++ je .L_Z196_17 ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z196_14: ++ clc 0(1,%r3),0(%r2) ++END(__memcmp_z196) ++ ++ENTRY(__memcmp_z10) ++ .machine "z10" ++ ltgr %r4,%r4 ++ je .L_Z10_4 ++ aghi %r4,-1 ++ srlg %r1,%r4,8 ++ cgijlh %r1,0,.L_Z10_12 ++.L_Z10_3: ++ exrl %r4,.L_Z10_15 ++.L_Z10_4: ++ ipm %r2 ++ sllg %r2,%r2,34 ++ srag %r2,%r2,62 ++ br %r14 ++.L_Z10_12: ++ pfd 1,512(%r3) ++ pfd 1,512(%r2) ++ clc 0(256,%r3),0(%r2) ++ jne .L_Z10_4 ++ la %r3,256(%r3) ++ la %r2,256(%r2) ++ brctg %r1,.L_Z10_12 ++ j .L_Z10_3 ++.L_Z10_15: ++ clc 0(1,%r3),0(%r2) ++END(__memcmp_z10) ++ ++#endif /* !NOT_IN_libc */ ++ ++#include "../memcmp.S" ++ ++#ifdef NOT_IN_libc ++.globl memcmp ++.set memcmp,__memcmp_default ++.weak bcmp ++.set bcmp,__memcmp_default ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.S b/sysdeps/s390/s390-64/multiarch/memcmp.S +deleted file mode 100644 +index 9a8cba8..0000000 +--- a/sysdeps/s390/s390-64/multiarch/memcmp.S ++++ /dev/null +@@ -1,101 +0,0 @@ +-/* CPU specific memcmp implementations. 64 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of first memory area +- %r3 = address of second memory area +- %r4 = number of bytes to compare. */ +- +- .text +- +-#ifndef NOT_IN_libc +- +-ENTRY(__memcmp_z196) +- .machine "z196" +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- srlg %r1,%r4,8 +- ltgr %r1,%r1 +- jne .L_Z196_2 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- ipm %r2 +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +- br %r14 +-.L_Z196_17: +- la %r3,256(%r3) +- la %r2,256(%r2) +- aghi %r1,-1 +- je .L_Z196_3 +-.L_Z196_2: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- je .L_Z196_17 +- ipm %r2 +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +- br %r14 +-.L_Z196_14: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z196) +- +-ENTRY(__memcmp_z10) +- .machine "z10" +- ltgr %r4,%r4 +- je .L_Z10_4 +- aghi %r4,-1 +- srlg %r1,%r4,8 +- cgijlh %r1,0,.L_Z10_12 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- ipm %r2 +- sllg %r2,%r2,34 +- srag %r2,%r2,62 +- br %r14 +-.L_Z10_12: +- pfd 1,512(%r3) +- pfd 1,512(%r2) +- clc 0(256,%r3),0(%r2) +- jne .L_Z10_4 +- la %r3,256(%r3) +- la %r2,256(%r2) +- brctg %r1,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- clc 0(1,%r3),0(%r2) +-END(__memcmp_z10) +- +-#endif +- +-#include "../memcmp.S" +- +-#ifdef NOT_IN_libc +-.globl memcmp +-.set memcmp,__memcmp_z900 +-.weak bcmp +-.set bcmp,__memcmp_z900 +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c +new file mode 100644 +index 0000000..7089d56 +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memcmp.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of memcmp. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++ ++s390_libc_ifunc (memcmp) ++asm(".weak bcmp ; bcmp = memcmp"); ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +new file mode 100644 +index 0000000..cdb34f1 +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S +@@ -0,0 +1,94 @@ ++/* CPU specific memcpy implementations. 64 bit S/390 version. ++ Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* INPUT PARAMETERS ++ %r2 = target operands address ++ %r3 = source operands address ++ %r4 = number of bytes to copy. */ ++ ++ .text ++ ++#if defined SHARED && !defined NOT_IN_libc ++ ++ENTRY(__memcpy_z196) ++ .machine "z196" ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ aghi %r4,-1 ++ lgr %r1,%r2 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_5 ++.L_Z196_3: ++ exrl %r4,.L_Z196_14 ++.L_Z196_4: ++ br %r14 ++.L_Z196_5: ++ cgfi %r5,262144 # Switch to mvcle for copies >64MB ++ jh __memcpy_mvcle ++.L_Z196_2: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_14: ++ mvc 0(1,%r1),0(%r3) ++END(__memcpy_z196) ++ ++ENTRY(__memcpy_z10) ++ .machine "z10" ++ cgije %r4,0,.L_Z10_4 ++ aghi %r4,-1 ++ lgr %r1,%r2 ++ srlg %r5,%r4,8 ++ cgijlh %r5,0,.L_Z10_13 ++.L_Z10_3: ++ exrl %r4,.L_Z10_15 ++.L_Z10_4: ++ br %r14 ++.L_Z10_13: ++ cgfi %r5,65535 # Switch to mvcle for copies >16MB ++ jh __memcpy_mvcle ++.L_Z10_12: ++ pfd 1,768(%r3) ++ pfd 2,768(%r1) ++ mvc 0(256,%r1),0(%r3) ++ la %r1,256(%r1) ++ la %r3,256(%r3) ++ brctg %r5,.L_Z10_12 ++ j .L_Z10_3 ++.L_Z10_15: ++ mvc 0(1,%r1),0(%r3) ++END(__memcpy_z10) ++ ++#endif /* SHARED && !defined NOT_IN_libc */ ++ ++#include "../memcpy.S" ++ ++#if !defined SHARED || defined NOT_IN_libc ++.globl memcpy ++.set memcpy,__memcpy_default ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.S b/sysdeps/s390/s390-64/multiarch/memcpy.S +deleted file mode 100644 +index 525588f..0000000 +--- a/sysdeps/s390/s390-64/multiarch/memcpy.S ++++ /dev/null +@@ -1,94 +0,0 @@ +-/* CPU specific memcpy implementations. 64 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = target operands address +- %r3 = source operands address +- %r4 = number of bytes to copy. */ +- +- .text +- +-#if defined SHARED && !defined NOT_IN_libc +- +-ENTRY(__memcpy_z196) +- .machine "z196" +- ltgr %r4,%r4 +- je .L_Z196_4 +- aghi %r4,-1 +- lgr %r1,%r2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_5 +-.L_Z196_3: +- exrl %r4,.L_Z196_14 +-.L_Z196_4: +- br %r14 +-.L_Z196_5: +- cgfi %r5,262144 # Switch to mvcle for copies >64MB +- jh __memcpy_mvcle +-.L_Z196_2: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- aghi %r5,-1 +- la %r1,256(%r1) +- la %r3,256(%r3) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_14: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z196) +- +-ENTRY(__memcpy_z10) +- .machine "z10" +- cgije %r4,0,.L_Z10_4 +- aghi %r4,-1 +- lgr %r1,%r2 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_13 +-.L_Z10_3: +- exrl %r4,.L_Z10_15 +-.L_Z10_4: +- br %r14 +-.L_Z10_13: +- cgfi %r5,65535 # Switch to mvcle for copies >16MB +- jh __memcpy_mvcle +-.L_Z10_12: +- pfd 1,768(%r3) +- pfd 2,768(%r1) +- mvc 0(256,%r1),0(%r3) +- la %r1,256(%r1) +- la %r3,256(%r3) +- brctg %r5,.L_Z10_12 +- j .L_Z10_3 +-.L_Z10_15: +- mvc 0(1,%r1),0(%r3) +-END(__memcpy_z10) +- +-#endif +- +-#include "../memcpy.S" +- +-#if !defined SHARED || defined NOT_IN_libc +-.globl memcpy +-.set memcpy,__memcpy_z900 +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c +new file mode 100644 +index 0000000..1ff31bb +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memcpy.c +@@ -0,0 +1,24 @@ ++/* Multiple versions of memcpy. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* In the static lib memcpy is needed before the reloc is resolved. */ ++#if defined SHARED && !defined NOT_IN_libc ++# include ++ ++s390_libc_ifunc (memcpy) ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/sysdeps/s390/s390-64/multiarch/memset-s390x.S +new file mode 100644 +index 0000000..0037bdf +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memset-s390x.S +@@ -0,0 +1,109 @@ ++/* Set a block of memory to some byte value. 64 bit S/390 version. ++ Copyright (C) 2012-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include "sysdep.h" ++#include "asm-syntax.h" ++ ++/* INPUT PARAMETERS ++ %r2 = address of memory area ++ %r3 = byte to fill memory with ++ %r4 = number of bytes to fill. */ ++ ++ .text ++ ++#ifndef NOT_IN_libc ++ ++ENTRY(__memset_z196) ++ .machine "z196" ++ ltgr %r4,%r4 ++ je .L_Z196_4 ++ stc %r3,0(%r2) ++ lgr %r1,%r2 ++ cghi %r4,1 ++ je .L_Z196_4 ++ aghi %r4,-2 ++ srlg %r5,%r4,8 ++ ltgr %r5,%r5 ++ jne .L_Z196_1 ++.L_Z196_3: ++ exrl %r4,.L_Z196_17 ++.L_Z196_4: ++ br %r14 ++.L_Z196_1: ++ cgfi %r5,1048576 ++ jh __memset_mvcle # Switch to mvcle for >256MB ++.L_Z196_2: ++ pfd 2,1024(%r1) ++ mvc 1(256,%r1),0(%r1) ++ aghi %r5,-1 ++ la %r1,256(%r1) ++ jne .L_Z196_2 ++ j .L_Z196_3 ++.L_Z196_17: ++ mvc 1(1,%r1),0(%r1) ++END(__memset_z196) ++ ++ENTRY(__memset_z10) ++ .machine "z10" ++ cgije %r4,0,.L_Z10_4 ++ stc %r3,0(%r2) ++ lgr %r1,%r2 ++ cgije %r4,1,.L_Z10_4 ++ aghi %r4,-2 ++ srlg %r5,%r4,8 ++ cgijlh %r5,0,.L_Z10_15 ++.L_Z10_3: ++ exrl %r4,.L_Z10_18 ++.L_Z10_4: ++ br %r14 ++.L_Z10_15: ++ cgfi %r5,163840 # Switch to mvcle for >40MB ++ jh __memset_mvcle ++.L_Z10_14: ++ pfd 2,1024(%r1) ++ mvc 1(256,%r1),0(%r1) ++ la %r1,256(%r1) ++ brctg %r5,.L_Z10_14 ++ j .L_Z10_3 ++.L_Z10_18: ++ mvc 1(1,%r1),0(%r1) ++END(__memset_z10) ++ ++ENTRY(__memset_mvcle) ++ aghi %r4,2 # take back the change done by the caller ++ lgr %r0,%r2 # save source address ++ lgr %r1,%r3 # move pad byte to R1 ++ lgr %r3,%r4 # move length to r3 ++ sgr %r4,%r4 # no source for MVCLE, only a pad byte ++ sgr %r5,%r5 ++.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend ++ jo .L0 ++ lgr %r2,%r0 # return value is source address ++.L1: ++ br %r14 ++END(__memset_mvcle) ++ ++#endif /* !NOT_IN_libc */ ++ ++#include "../memset.S" ++ ++#ifdef NOT_IN_libc ++.globl memset ++.set memset,__memset_default ++#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memset.S b/sysdeps/s390/s390-64/multiarch/memset.S +deleted file mode 100644 +index 8dbb3cb..0000000 +--- a/sysdeps/s390/s390-64/multiarch/memset.S ++++ /dev/null +@@ -1,109 +0,0 @@ +-/* Set a block of memory to some byte value. 64 bit S/390 version. +- Copyright (C) 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +- +-#include "sysdep.h" +-#include "asm-syntax.h" +- +-/* INPUT PARAMETERS +- %r2 = address of memory area +- %r3 = byte to fill memory with +- %r4 = number of bytes to fill. */ +- +- .text +- +-#ifndef NOT_IN_libc +- +-ENTRY(__memset_z196) +- .machine "z196" +- ltgr %r4,%r4 +- je .L_Z196_4 +- stc %r3,0(%r2) +- lgr %r1,%r2 +- cghi %r4,1 +- je .L_Z196_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- ltgr %r5,%r5 +- jne .L_Z196_1 +-.L_Z196_3: +- exrl %r4,.L_Z196_17 +-.L_Z196_4: +- br %r14 +-.L_Z196_1: +- cgfi %r5,1048576 +- jh __memset_mvcle # Switch to mvcle for >256MB +-.L_Z196_2: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- aghi %r5,-1 +- la %r1,256(%r1) +- jne .L_Z196_2 +- j .L_Z196_3 +-.L_Z196_17: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z196) +- +-ENTRY(__memset_z10) +- .machine "z10" +- cgije %r4,0,.L_Z10_4 +- stc %r3,0(%r2) +- lgr %r1,%r2 +- cgije %r4,1,.L_Z10_4 +- aghi %r4,-2 +- srlg %r5,%r4,8 +- cgijlh %r5,0,.L_Z10_15 +-.L_Z10_3: +- exrl %r4,.L_Z10_18 +-.L_Z10_4: +- br %r14 +-.L_Z10_15: +- cgfi %r5,163840 # Switch to mvcle for >40MB +- jh __memset_mvcle +-.L_Z10_14: +- pfd 2,1024(%r1) +- mvc 1(256,%r1),0(%r1) +- la %r1,256(%r1) +- brctg %r5,.L_Z10_14 +- j .L_Z10_3 +-.L_Z10_18: +- mvc 1(1,%r1),0(%r1) +-END(__memset_z10) +- +-ENTRY(__memset_mvcle) +- aghi %r4,2 # take back the change done by the caller +- lgr %r0,%r2 # save source address +- lgr %r1,%r3 # move pad byte to R1 +- lgr %r3,%r4 # move length to r3 +- sgr %r4,%r4 # no source for MVCLE, only a pad byte +- sgr %r5,%r5 +-.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend +- jo .L0 +- lgr %r2,%r0 # return value is source address +-.L1: +- br %r14 +-END(__memset_mvcle) +- +-#endif +- +-#include "../memset.S" +- +-#ifdef NOT_IN_libc +-.globl memset +-.set memset,__memset_z900 +-#endif +diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c +new file mode 100644 +index 0000000..3b15446 +--- /dev/null ++++ b/sysdeps/s390/s390-64/multiarch/memset.c +@@ -0,0 +1,23 @@ ++/* Multiple versions of memset. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++ ++s390_libc_ifunc (memset) ++#endif +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-6.patch b/SOURCES/glibc-rh1268008-6.patch new file mode 100644 index 00000000..c6d4715d --- /dev/null +++ b/SOURCES/glibc-rh1268008-6.patch @@ -0,0 +1,76 @@ +From 571d49008b0c44b4aabb66b2ac3ce690fd802466 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:45:29 +0200 +Subject: [PATCH 06/30] S390: Add hwcaps value for vector facility. + +upstream-commit-id: 4e28fa80886c71e6aaf85016b82ce981c0f12e6d +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00075.html + +The HWCAP_S390_VX flag in hwcap field of auxiliary vector indicates +if the vector facility is available and the kernel is aware of it. +This can be tested with LD_SHOW_AUXV=1 . +Currently it does not show te, because it was not incremented +by commit "S/390: Add hwcap value for transactional execution.". +Thus _DL_HWCAP_COUNT is incremented by two. + +ChangeLog: + + * sysdeps/s390/dl-procinfo.c (_dl_s390_platforms): Add vector flag. + * sysdeps/s390/dl-procinfo.h: Add vector capability. + * sysdeps/unix/sysv/linux/s390/bits/hwcap.h (HWCAP_S390_VX): Define. +--- + sysdeps/s390/dl-procinfo.c | 4 ++-- + sysdeps/s390/dl-procinfo.h | 3 ++- + sysdeps/unix/sysv/linux/s390/bits/hwcap.h | 1 + + 3 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index 9590146..96d438a 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -46,11 +46,11 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_cap_flags + #else +-PROCINFO_CLASS const char _dl_s390_cap_flags[11][9] ++PROCINFO_CLASS const char _dl_s390_cap_flags[12][9] + #endif + #ifndef PROCINFO_DECL + = { +- "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te" ++ "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te", "vx" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index 26de043..89766e0 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -21,7 +21,7 @@ + #define _DL_PROCINFO_H 1 + #include + +-#define _DL_HWCAP_COUNT 10 ++#define _DL_HWCAP_COUNT 12 + + #define _DL_PLATFORMS_COUNT 5 + +@@ -50,6 +50,7 @@ enum + HWCAP_S390_ETF3EH = 1 << 8, + HWCAP_S390_HIGH_GPRS = 1 << 9, + HWCAP_S390_TE = 1 << 10, ++ HWCAP_S390_VX = 1 << 11, + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ +diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +index 59d68b0..bd2ce3a 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +@@ -35,3 +35,4 @@ + #define HWCAP_S390_ETF3EH 256 + #define HWCAP_S390_HIGH_GPRS 512 + #define HWCAP_S390_TE 1024 ++#define HWCAP_S390_VX 2048 +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-7.patch b/SOURCES/glibc-rh1268008-7.patch new file mode 100644 index 00000000..89ab7e71 --- /dev/null +++ b/SOURCES/glibc-rh1268008-7.patch @@ -0,0 +1,55 @@ +From 9bcfc74b3097eb84973b7b91fd676f116e206938 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:45:58 +0200 +Subject: [PATCH 07/30] S390: Add new s390 platform. + +upstream-commit-id: a1b0488fc9df3d895a2e5eefbcd348d3f7fe0e52 +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00081.html + +The new IBM z13 is added to platform string array. +The macro _DL_PLATFORMS_COUNT is incremented to 8, +because it was not incremented by commit +"S/390: Sync AUXV capabilities and archs with kernel". + +ChangeLog: + + * sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags): Add z13. + * sysdeps/s390/dl-procinfo.h (_DL_PLATFORMS_COUNT): Increased. +--- + sysdeps/s390/dl-procinfo.c | 4 ++-- + sysdeps/s390/dl-procinfo.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index 96d438a..f353528 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -62,11 +62,11 @@ PROCINFO_CLASS const char _dl_s390_cap_flags[12][9] + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_platforms + #else +-PROCINFO_CLASS const char _dl_s390_platforms[7][7] ++PROCINFO_CLASS const char _dl_s390_platforms[8][7] + #endif + #ifndef PROCINFO_DECL + = { +- "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12" ++ "g5", "z900", "z990", "z9-109", "z10", "z196", "zEC12", "z13" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index 89766e0..80747f0 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -23,7 +23,7 @@ + + #define _DL_HWCAP_COUNT 12 + +-#define _DL_PLATFORMS_COUNT 5 ++#define _DL_PLATFORMS_COUNT 8 + + /* The kernel provides up to 32 capability bits with elf_hwcap. */ + #define _DL_FIRST_PLATFORM 32 +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-8.patch b/SOURCES/glibc-rh1268008-8.patch new file mode 100644 index 00000000..f4a616ae --- /dev/null +++ b/SOURCES/glibc-rh1268008-8.patch @@ -0,0 +1,132 @@ +From 2d04109858181ed8c7dc3e4ae42923a26c1d3591 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:47:37 +0200 +Subject: [PATCH 08/30] S390: configure check for vector instruction support in + assembler. + +upstream-commit-id: 4f0a1cea34c05fb2acc16f1a2d291f53230eb4fb +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00153.html + +The S390 specific test checks if the assembler has support for the new z13 +vector instructions by compiling a vector instruction. The .machine and +.machinemode directives are needed to compile the vector instruction without +-march=z13 option on 31/64 bit. +On success the macro HAVE_S390_VX_ASM_SUPPORT is defined. This macro is used +to determine if the optimized functions can be build without compile errors. +If the used assembler lacks vector support, then a warning is dumped while +configuring and only the common code functions are build. + +The z13 instruction support was introduced in +"[Committed] S/390: Add support for IBM z13." +(https://sourceware.org/ml/binutils/2015-01/msg00197.html) + +ChangeLog: + + * config.h.in (HAVE_S390_VX_ASM_SUPPORT): New macro undefine. + * sysdeps/s390/configure.ac: Add test for S390 vector instruction + assembler support. + * sysdeps/s390/configure: Regenerated. +--- + config.h.in | 3 +++ + sysdeps/s390/configure | 39 +++++++++++++++++++++++++++++++++++++++ + sysdeps/s390/configure.in | 27 +++++++++++++++++++++++++++ + 3 files changed, 69 insertions(+) + +diff --git a/config.h.in b/config.h.in +index 68321d4..f7f2388 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -110,6 +110,9 @@ + /* Define if assembler supports Intel MPX. */ + #undef HAVE_MPX_SUPPORT + ++/* Define if assembler supports vector instructions on S390. */ ++#undef HAVE_S390_VX_ASM_SUPPORT ++ + /* Define if gcc supports FMA4. */ + #undef HAVE_FMA4_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index 669bb9b..cc4c1e0 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -3,3 +3,42 @@ + + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 vector instruction support" >&5 ++$as_echo_n "checking for S390 vector instruction support... " >&6; } ++if ${libc_cv_asm_s390_vx+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testvecinsn () ++{ ++ __asm__ (".machine \"z13\" \n\t" ++ ".machinemode \"zarch_nohighgprs\" \n\t" ++ "vistrbs %%v16,%%v17 \n\t" ++ "locghie %%r1,0" : :); ++} ++EOF ++if { ac_try='${CC-cc} --shared conftest.c -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_vx=yes ++else ++ libc_cv_asm_s390_vx=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_vx" >&5 ++$as_echo "$libc_cv_asm_s390_vx" >&6; } ++ ++if test "$libc_cv_asm_s390_vx" = yes ; ++then ++ $as_echo "#define HAVE_S390_VX_ASM_SUPPORT 1" >>confdefs.h ++ ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Use binutils with vector-support in order to use optimized implementations." >&5 ++$as_echo "$as_me: WARNING: Use binutils with vector-support in order to use optimized implementations." >&2;} ++fi +diff --git a/sysdeps/s390/configure.in b/sysdeps/s390/configure.in +index b5af4e1..733e356 100644 +--- a/sysdeps/s390/configure.in ++++ b/sysdeps/s390/configure.in +@@ -4,3 +4,30 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + dnl It is always possible to access static and hidden symbols in an + dnl position independent way. + AC_DEFINE(PI_STATIC_AND_HIDDEN) ++ ++AC_CACHE_CHECK(for S390 vector instruction support, libc_cv_asm_s390_vx, [dnl ++cat > conftest.c <<\EOF ++void testvecinsn () ++{ ++ __asm__ (".machine \"z13\" \n\t" ++ ".machinemode \"zarch_nohighgprs\" \n\t" ++ "vistrbs %%v16,%%v17 \n\t" ++ "locghie %%r1,0" : :); ++} ++EOF ++dnl ++dnl test, if assembler supports S390 vector instructions ++if AC_TRY_COMMAND([${CC-cc} --shared conftest.c -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_vx=yes ++else ++ libc_cv_asm_s390_vx=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_asm_s390_vx" = yes ; ++then ++ AC_DEFINE(HAVE_S390_VX_ASM_SUPPORT) ++else ++ AC_MSG_WARN([Use binutils with vector-support in order to use optimized implementations.]) ++fi +-- +2.3.0 diff --git a/SOURCES/glibc-rh1268008-9.patch b/SOURCES/glibc-rh1268008-9.patch new file mode 100644 index 00000000..2c1da5be --- /dev/null +++ b/SOURCES/glibc-rh1268008-9.patch @@ -0,0 +1,49 @@ +From b13a91507798183556d7e1891fe3d4cd3a947aa6 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 8 Oct 2015 10:48:13 +0200 +Subject: [PATCH 09/30] S390: Ifunc resolver macro for vector instructions. + +upstream-commit-id: fd484e057dd4d2813182df08584a4c48d6f1dd7a +https://www.sourceware.org/ml/libc-alpha/2015-07/msg00076.html + +This patch introduces a s390 specific ifunc resolver macro for 32/64bit, +which chooses _vx with vector instructions if HWCAP_S390_VX flag +in hwcaps is set or _c if not. + +ChangeLog: + + * sysdeps/s390/multiarch/ifunc-resolve.h (s390_vx_libc_ifunc, + s390_vx_libc_ifunc2): New macro function. +--- + sysdeps/s390/multiarch/ifunc-resolve.h | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index 491df68..e9fd90e 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -73,3 +73,22 @@ + else \ + return &__##FUNC##_default; \ + } ++ ++#define s390_vx_libc_ifunc(FUNC) \ ++ s390_vx_libc_ifunc2(FUNC, FUNC) ++ ++#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \ ++ /* Make the declarations of the optimized functions hidden in order ++ to prevent GOT slots being generated for them. */ \ ++ extern __typeof (FUNC) RESOLVERFUNC##_vx attribute_hidden; \ ++ extern __typeof (FUNC) RESOLVERFUNC##_c attribute_hidden; \ ++ extern void *__resolve_##RESOLVERFUNC (unsigned long int) __asm__ (#FUNC); \ ++ \ ++ void *__resolve_##RESOLVERFUNC (unsigned long int dl_hwcap) \ ++ { \ ++ if (dl_hwcap & HWCAP_S390_VX) \ ++ return &RESOLVERFUNC##_vx; \ ++ else \ ++ return &RESOLVERFUNC##_c; \ ++ } \ ++ __asm__ (".type " #FUNC ", %gnu_indirect_function"); +-- +2.3.0 diff --git a/SOURCES/glibc-rh1276753-0.patch b/SOURCES/glibc-rh1276753-0.patch new file mode 100644 index 00000000..a7ac1a61 --- /dev/null +++ b/SOURCES/glibc-rh1276753-0.patch @@ -0,0 +1,310 @@ +commit 5782a80f9f8ca86899b30161166f044b0b6b8590 +Author: Ondřej Bílka +Date: Tue Dec 10 17:56:59 2013 +0100 + + Drop PER_THREAD conditionals from malloc. + +Index: glibc-2.17-c758a686/malloc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/Makefile ++++ glibc-2.17-c758a686/malloc/Makefile +@@ -121,7 +121,6 @@ endif + tst-mcheck-ENV = MALLOC_CHECK_=3 + tst-malloc-usable-ENV = MALLOC_CHECK_=3 + +-CPPFLAGS-malloc.c += -DPER_THREAD + # Uncomment this for test releases. For public releases it is too expensive. + #CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1 + +Index: glibc-2.17-c758a686/malloc/arena.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/arena.c ++++ glibc-2.17-c758a686/malloc/arena.c +@@ -78,10 +78,8 @@ extern int sanity_check_heap_info_alignm + + static tsd_key_t arena_key; + static mutex_t list_lock = MUTEX_INITIALIZER; +-#ifdef PER_THREAD + static size_t narenas = 1; + static mstate free_list; +-#endif + + #if THREAD_STATS + static int stat_n_heaps; +@@ -117,21 +115,12 @@ int __malloc_initialized = -1; + ptr = (mstate)tsd_getspecific(arena_key, vptr); \ + } while(0) + +-#ifdef PER_THREAD + # define arena_lock(ptr, size) do { \ + if(ptr && !arena_is_corrupt (ptr)) \ + (void)mutex_lock(&ptr->mutex); \ + else \ + ptr = arena_get2(ptr, (size), NULL); \ + } while(0) +-#else +-# define arena_lock(ptr, size) do { \ +- if(ptr && !mutex_trylock(&ptr->mutex)) { \ +- THREAD_STAT(++(ptr->stat_lock_direct)); \ +- } else \ +- ptr = arena_get2(ptr, (size), NULL); \ +-} while(0) +-#endif + + /* find the heap and corresponding arena for a given ptr */ + +@@ -297,17 +286,13 @@ ptmalloc_unlock_all2 (void) + tsd_setspecific(arena_key, save_arena); + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; +-#ifdef PER_THREAD + free_list = NULL; +-#endif + for(ar_ptr = &main_arena;;) { + mutex_init(&ar_ptr->mutex); +-#ifdef PER_THREAD + if (ar_ptr != save_arena) { + ar_ptr->next_free = free_list; + free_list = ar_ptr; + } +-#endif + ar_ptr = ar_ptr->next; + if(ar_ptr == &main_arena) break; + } +@@ -428,13 +413,10 @@ ptmalloc_init (void) + { + if (memcmp (envline, "MMAP_MAX_", 9) == 0) + __libc_mallopt(M_MMAP_MAX, atoi(&envline[10])); +-#ifdef PER_THREAD + else if (memcmp (envline, "ARENA_MAX", 9) == 0) + __libc_mallopt(M_ARENA_MAX, atoi(&envline[10])); +-#endif + } + break; +-#ifdef PER_THREAD + case 10: + if (! __builtin_expect (__libc_enable_secure, 0)) + { +@@ -442,7 +424,6 @@ ptmalloc_init (void) + __libc_mallopt(M_ARENA_TEST, atoi(&envline[11])); + } + break; +-#endif + case 15: + if (! __builtin_expect (__libc_enable_secure, 0)) + { +@@ -750,18 +731,14 @@ _int_new_arena(size_t size) + mutex_init(&a->mutex); + (void)mutex_lock(&a->mutex); + +-#ifdef PER_THREAD + (void)mutex_lock(&list_lock); +-#endif + + /* Add the new arena to the global list. */ + a->next = main_arena.next; + atomic_write_barrier (); + main_arena.next = a; + +-#ifdef PER_THREAD + (void)mutex_unlock(&list_lock); +-#endif + + THREAD_STAT(++(a->stat_lock_loop)); + +@@ -769,7 +746,6 @@ _int_new_arena(size_t size) + } + + +-#ifdef PER_THREAD + static mstate + get_free_list (void) + { +@@ -846,7 +822,6 @@ reused_arena (mstate avoid_arena) + + return result; + } +-#endif + + static mstate + internal_function +@@ -854,7 +829,6 @@ arena_get2(mstate a_tsd, size_t size, ms + { + mstate a; + +-#ifdef PER_THREAD + static size_t narenas_limit; + + a = get_free_list (); +@@ -897,54 +871,6 @@ arena_get2(mstate a_tsd, size_t size, ms + else + a = reused_arena (avoid_arena); + } +-#else +- if(!a_tsd) +- a = a_tsd = &main_arena; +- else { +- a = a_tsd->next; +- if(!a) { +- /* This can only happen while initializing the new arena. */ +- (void)mutex_lock(&main_arena.mutex); +- THREAD_STAT(++(main_arena.stat_lock_wait)); +- return &main_arena; +- } +- } +- +- /* Check the global, circularly linked list for available arenas. */ +- bool retried = false; +- repeat: +- do { +- if(!mutex_trylock(&a->mutex)) { +- if (retried) +- (void)mutex_unlock(&list_lock); +- THREAD_STAT(++(a->stat_lock_loop)); +- LIBC_PROBE (memory_arena_reuse, 2, a, a_tsd); +- tsd_setspecific(arena_key, (void *)a); +- return a; +- } +- a = a->next; +- } while(a != a_tsd); +- +- /* If not even the list_lock can be obtained, try again. This can +- happen during `atfork', or for example on systems where thread +- creation makes it temporarily impossible to obtain _any_ +- locks. */ +- if(!retried && mutex_trylock(&list_lock)) { +- /* We will block to not run in a busy loop. */ +- LIBC_PROBE (memory_arena_reuse_wait, 3, &list_lock, NULL, a_tsd); +- (void)mutex_lock(&list_lock); +- +- /* Since we blocked there might be an arena available now. */ +- retried = true; +- a = a_tsd; +- goto repeat; +- } +- +- /* Nothing immediately available, so generate a new arena. */ +- a = _int_new_arena(size); +- (void)mutex_unlock(&list_lock); +-#endif +- + return a; + } + +@@ -970,7 +896,6 @@ arena_get_retry (mstate ar_ptr, size_t b + return ar_ptr; + } + +-#ifdef PER_THREAD + static void __attribute__ ((section ("__libc_thread_freeres_fn"))) + arena_thread_freeres (void) + { +@@ -987,7 +912,6 @@ arena_thread_freeres (void) + } + } + text_set_element (__libc_thread_subfreeres, arena_thread_freeres); +-#endif + + /* + * Local variables: +Index: glibc-2.17-c758a686/malloc/hooks.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/hooks.c ++++ glibc-2.17-c758a686/malloc/hooks.c +@@ -464,11 +464,9 @@ __malloc_get_state(void) + ms->max_mmapped_mem = mp_.max_mmapped_mem; + ms->using_malloc_checking = using_malloc_checking; + ms->max_fast = get_max_fast(); +-#ifdef PER_THREAD + ms->arena_test = mp_.arena_test; + ms->arena_max = mp_.arena_max; + ms->narenas = narenas; +-#endif + (void)mutex_unlock(&main_arena.mutex); + return (void*)ms; + } +@@ -565,11 +563,9 @@ __malloc_set_state(void* msptr) + } + } + if (ms->version >= 4) { +-#ifdef PER_THREAD + mp_.arena_test = ms->arena_test; + mp_.arena_max = ms->arena_max; + narenas = ms->narenas; +-#endif + } + check_malloc_state(&main_arena); + +Index: glibc-2.17-c758a686/malloc/malloc.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/malloc.c ++++ glibc-2.17-c758a686/malloc/malloc.c +@@ -1727,10 +1727,8 @@ struct malloc_state { + /* Linked list */ + struct malloc_state *next; + +-#ifdef PER_THREAD + /* Linked list for free arenas. */ + struct malloc_state *next_free; +-#endif + + /* Memory allocated from the system in this arena. */ + INTERNAL_SIZE_T system_mem; +@@ -1742,10 +1740,8 @@ struct malloc_par { + unsigned long trim_threshold; + INTERNAL_SIZE_T top_pad; + INTERNAL_SIZE_T mmap_threshold; +-#ifdef PER_THREAD + INTERNAL_SIZE_T arena_test; + INTERNAL_SIZE_T arena_max; +-#endif + + /* Memory map support */ + int n_mmaps; +@@ -1787,18 +1783,14 @@ static struct malloc_par mp_ = + .n_mmaps_max = DEFAULT_MMAP_MAX, + .mmap_threshold = DEFAULT_MMAP_THRESHOLD, + .trim_threshold = DEFAULT_TRIM_THRESHOLD, +-#ifdef PER_THREAD + # define NARENAS_FROM_NCORES(n) ((n) * (sizeof(long) == 4 ? 2 : 8)) + .arena_test = NARENAS_FROM_NCORES (1) +-#endif + }; + + +-#ifdef PER_THREAD + /* Non public mallopt parameters. */ + #define M_ARENA_TEST -7 + #define M_ARENA_MAX -8 +-#endif + + + /* Maximum size of memory handled in fastbins. */ +@@ -3008,11 +3000,6 @@ __libc_realloc(void* oldmem, size_t byte + (void)mutex_lock(&ar_ptr->mutex); + #endif + +-#if !defined PER_THREAD +- LIBC_PROBE (memory_arena_reuse_realloc, 1, ar_ptr); +- /* As in malloc(), remember this arena for the next allocation. */ +- tsd_setspecific(arena_key, (void *)ar_ptr); +-#endif + + newp = _int_realloc(ar_ptr, oldp, oldsize, nb); + +@@ -4823,7 +4810,6 @@ int __libc_mallopt(int param_number, int + perturb_byte = value; + break; + +-#ifdef PER_THREAD + case M_ARENA_TEST: + if (value > 0) + { +@@ -4839,7 +4825,6 @@ int __libc_mallopt(int param_number, int + mp_.arena_max = value; + } + break; +-#endif + } + (void)mutex_unlock(&av->mutex); + return res; diff --git a/SOURCES/glibc-rh1276753.patch b/SOURCES/glibc-rh1276753.patch new file mode 100644 index 00000000..32ea4245 --- /dev/null +++ b/SOURCES/glibc-rh1276753.patch @@ -0,0 +1,654 @@ +Upstream commits: + +commit a62719ba90e2fa1728890ae7dc8df9e32a622e7b +Author: Florian Weimer +Date: Wed Oct 28 19:32:46 2015 +0100 + + malloc: Prevent arena free_list from turning cyclic [BZ #19048] + +commit 3da825ce483903e3a881a016113b3e59fd4041de +Author: Florian Weimer +Date: Wed Dec 16 12:39:48 2015 +0100 + + malloc: Fix attached thread reference count handling [BZ #19243] + +commit 90c400bd4904b0240a148f0b357a5cbc36179239 +Author: Florian Weimer +Date: Mon Dec 21 16:42:46 2015 +0100 + + malloc: Fix list_lock/arena lock deadlock [BZ #19182] + +commit 7962541a32eff5597bc4207e781cfac8d1bb0d87 +Author: Florian Weimer +Date: Wed Dec 23 17:23:33 2015 +0100 + + malloc: Update comment for list_lock + +commit 2a38688932243b5b16fb12d84c7ac1138ce50363 +Author: Florian Weimer +Date: Fri Feb 19 14:11:32 2016 +0100 + + tst-malloc-thread-exit: Use fewer system resources + +Also included is the following change, which has not yet been +committed upstream: + + malloc: Preserve arena free list/thread count invariant [BZ #20370] + + It is necessary to preserve the invariant that if an arena is + on the free list, it has thread attach count zero. Otherwise, + when arena_thread_freeres sees the zero attach count, it will + add it, and without the invariant, an arena could get pushed + to the list twice, resulting in a cycle. + + One possible execution trace looks like this: + + Thread 1 examines free list and observes it as empty. + Thread 2 exits and adds its arena to the free list, + with attached_threads == 0). + Thread 1 selects this arena in reused_arena (not from the free list). + Thread 1 increments attached_threads and attaches itself. + (The arena remains on the free list.) + Thread 1 exits, decrements attached_threads, + and adds the arena to the free list. + + The final step creates a cycle in the usual way (by overwriting the + next_free member with the former list head, while there is another + list item pointing to the arena structure). + + tst-malloc-thread-exit exhibits this issue, but it was only visible + with a debugger because the incorrect fix in bug 19243 removed + the assert from get_free_list. + + +Index: b/malloc/arena.c +=================================================================== +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -77,10 +77,30 @@ extern int sanity_check_heap_info_alignm + /* Thread specific data */ + + static tsd_key_t arena_key; +-static mutex_t list_lock = MUTEX_INITIALIZER; ++ ++/* Arena free list. free_list_lock synchronizes access to the ++ free_list variable below, and the next_free and attached_threads ++ members of struct malloc_state objects. No other locks must be ++ acquired after free_list_lock has been acquired. */ ++ ++static mutex_t free_list_lock = MUTEX_INITIALIZER; + static size_t narenas = 1; + static mstate free_list; + ++/* list_lock prevents concurrent writes to the next member of struct ++ malloc_state objects. ++ ++ Read access to the next member is supposed to synchronize with the ++ atomic_write_barrier and the write to the next member in ++ _int_new_arena. This suffers from data races; see the FIXME ++ comments in _int_new_arena and reused_arena. ++ ++ list_lock also prevents concurrent forks. At the time list_lock is ++ acquired, no arena lock must have been acquired, but it is ++ permitted to acquire arena locks subsequently, while list_lock is ++ acquired. */ ++static mutex_t list_lock = MUTEX_INITIALIZER; ++ + #if THREAD_STATS + static int stat_n_heaps; + #define THREAD_STAT(x) x +@@ -221,6 +241,10 @@ ptmalloc_lock_all (void) + + if(__malloc_initialized < 1) + return; ++ ++ /* We do not acquire free_list_lock here because we completely ++ reconstruct free_list in ptmalloc_unlock_all2. */ ++ + if (mutex_trylock(&list_lock)) + { + void *my_arena; +@@ -242,7 +266,10 @@ ptmalloc_lock_all (void) + save_free_hook = __free_hook; + __malloc_hook = malloc_atfork; + __free_hook = free_atfork; +- /* Only the current thread may perform malloc/free calls now. */ ++ /* Only the current thread may perform malloc/free calls now. ++ save_arena will be reattached to the current thread, in ++ ptmalloc_lock_all, so save_arena->attached_threads is not ++ updated. */ + tsd_getspecific(arena_key, save_arena); + tsd_setspecific(arena_key, ATFORK_ARENA_PTR); + out: +@@ -258,6 +285,9 @@ ptmalloc_unlock_all (void) + return; + if (--atfork_recursive_cntr != 0) + return; ++ /* Replace ATFORK_ARENA_PTR with save_arena. ++ save_arena->attached_threads was not changed in ptmalloc_lock_all ++ and is still correct. */ + tsd_setspecific(arena_key, save_arena); + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; +@@ -286,16 +316,24 @@ ptmalloc_unlock_all2 (void) + tsd_setspecific(arena_key, save_arena); + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; ++ /* Push all arenas to the free list, except save_arena, which is ++ attached to the current thread. */ ++ mutex_init (&free_list_lock); ++ if (save_arena != NULL) ++ ((mstate) save_arena)->attached_threads = 1; + free_list = NULL; + for(ar_ptr = &main_arena;;) { + mutex_init(&ar_ptr->mutex); + if (ar_ptr != save_arena) { ++ /* This arena is no longer attached to any thread. */ ++ ar_ptr->attached_threads = 0; + ar_ptr->next_free = free_list; + free_list = ar_ptr; + } + ar_ptr = ar_ptr->next; + if(ar_ptr == &main_arena) break; + } ++ + mutex_init(&list_lock); + atfork_recursive_cntr = 0; + } +@@ -692,8 +730,25 @@ heap_trim(heap_info *heap, size_t pad) + return 1; + } + +-/* Create a new arena with initial size "size". */ + ++/* If REPLACED_ARENA is not NULL, detach it from this thread. Must be ++ called while free_list_lock is held. */ ++static void ++detach_arena (mstate replaced_arena) ++{ ++ if (replaced_arena != NULL) ++ { ++ assert (replaced_arena->attached_threads > 0); ++ /* The current implementation only detaches from main_arena in ++ case of allocation failure. This means that it is likely not ++ beneficial to put the arena on free_list even if the ++ reference count reaches zero. */ ++ --replaced_arena->attached_threads; ++ } ++} ++ ++ ++/* Create a new arena with initial size "size". */ + static mstate + _int_new_arena(size_t size) + { +@@ -714,6 +769,7 @@ _int_new_arena(size_t size) + } + a = h->ar_ptr = (mstate)(h+1); + malloc_init_state(a); ++ a->attached_threads = 1; + /*a->next = NULL;*/ + a->system_mem = a->max_system_mem = h->size; + arena_mem += h->size; +@@ -727,36 +783,68 @@ _int_new_arena(size_t size) + set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE); + + LIBC_PROBE (memory_arena_new, 2, a, size); ++ mstate replaced_arena; ++ { ++ void *vptr = NULL; ++ replaced_arena = tsd_getspecific (arena_key, vptr); ++ } + tsd_setspecific(arena_key, (void *)a); + mutex_init(&a->mutex); +- (void)mutex_lock(&a->mutex); + + (void)mutex_lock(&list_lock); + + /* Add the new arena to the global list. */ + a->next = main_arena.next; ++ /* FIXME: The barrier is an attempt to synchronize with read access ++ in reused_arena, which does not acquire list_lock while ++ traversing the list. */ + atomic_write_barrier (); + main_arena.next = a; + + (void)mutex_unlock(&list_lock); + ++ (void) mutex_lock (&free_list_lock); ++ detach_arena (replaced_arena); ++ (void) mutex_unlock (&free_list_lock); ++ ++ /* Lock this arena. NB: Another thread may have been attached to ++ this arena because the arena is now accessible from the ++ main_arena.next list and could have been picked by reused_arena. ++ This can only happen for the last arena created (before the arena ++ limit is reached). At this point, some arena has to be attached ++ to two threads. We could acquire the arena lock before list_lock ++ to make it less likely that reused_arena picks this new arena, ++ but this could result in a deadlock with ptmalloc_lock_all. */ ++ ++ (void) mutex_lock (&a->mutex); ++ + THREAD_STAT(++(a->stat_lock_loop)); + + return a; + } + +- ++/* Remove an arena from free_list. */ + static mstate + get_free_list (void) + { ++ void *vptr = NULL; ++ mstate replaced_arena = tsd_getspecific (arena_key, vptr); + mstate result = free_list; + if (result != NULL) + { +- (void)mutex_lock(&list_lock); ++ (void)mutex_lock(&free_list_lock); + result = free_list; + if (result != NULL) +- free_list = result->next_free; +- (void)mutex_unlock(&list_lock); ++ { ++ free_list = result->next_free; ++ ++ /* The arena will be attached to this thread. */ ++ assert (result->attached_threads == 0); ++ result->attached_threads = 1; ++ ++ detach_arena (replaced_arena); ++ } ++ (void)mutex_unlock(&free_list_lock); + + if (result != NULL) + { +@@ -770,6 +858,26 @@ get_free_list (void) + return result; + } + ++/* Remove the arena from the free list (if it is present). ++ free_list_lock must have been acquired by the caller. */ ++static void ++remove_from_free_list (mstate arena) ++{ ++ mstate *previous = &free_list; ++ for (mstate p = free_list; p != NULL; p = p->next_free) ++ { ++ assert (p->attached_threads == 0); ++ if (p == arena) ++ { ++ /* Remove the requested arena from the list. */ ++ *previous = p->next_free; ++ break; ++ } ++ else ++ previous = &p->next_free; ++ } ++} ++ + /* Lock and return an arena that can be reused for memory allocation. + Avoid AVOID_ARENA as we have already failed to allocate memory in + it and it is currently locked. */ +@@ -777,16 +885,20 @@ static mstate + reused_arena (mstate avoid_arena) + { + mstate result; ++ /* FIXME: Access to next_to_use suffers from data races. */ + static mstate next_to_use; + if (next_to_use == NULL) + next_to_use = &main_arena; + ++ /* Iterate over all arenas (including those linked from ++ free_list). */ + result = next_to_use; + do + { + if (!arena_is_corrupt (result) && !mutex_trylock(&result->mutex)) + goto out; + ++ /* FIXME: This is a data race, see _int_new_arena. */ + result = result->next; + } + while (result != next_to_use); +@@ -815,6 +927,27 @@ reused_arena (mstate avoid_arena) + (void)mutex_lock(&result->mutex); + + out: ++ /* Attach the arena to the current thread. */ ++ { ++ /* Update the arena thread attachment counters. */ ++ void *vptr = NULL; ++ mstate replaced_arena = tsd_getspecific (arena_key, vptr); ++ (void) mutex_lock (&free_list_lock); ++ detach_arena (replaced_arena); ++ ++ /* We may have picked up an arena on the free list. We need to ++ preserve the invariant that no arena on the free list has a ++ positive attached_threads counter (otherwise, ++ arena_thread_freeres cannot use the counter to determine if the ++ arena needs to be put on the free list). We unconditionally ++ remove the selected arena from the free list. The caller of ++ reused_arena checked the free list and observed it to be empty, ++ so the list is very short. */ ++ remove_from_free_list (result); ++ ++ ++result->attached_threads; ++ (void) mutex_unlock (&free_list_lock); ++ } + LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena); + tsd_setspecific(arena_key, (void *)result); + THREAD_STAT(++(result->stat_lock_loop)); +@@ -905,10 +1038,16 @@ arena_thread_freeres (void) + + if (a != NULL) + { +- (void)mutex_lock(&list_lock); +- a->next_free = free_list; +- free_list = a; +- (void)mutex_unlock(&list_lock); ++ (void)mutex_lock(&free_list_lock); ++ /* If this was the last attached thread for this arena, put the ++ arena on the free list. */ ++ assert (a->attached_threads > 0); ++ if (--a->attached_threads == 0) ++ { ++ a->next_free = free_list; ++ free_list = a; ++ } ++ (void)mutex_unlock(&free_list_lock); + } + } + text_set_element (__libc_thread_subfreeres, arena_thread_freeres); +Index: b/malloc/malloc.c +=================================================================== +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1727,8 +1727,13 @@ struct malloc_state { + /* Linked list */ + struct malloc_state *next; + +- /* Linked list for free arenas. */ ++ /* Linked list for free arenas. Access to this field is serialized ++ by free_list_lock in arena.c. */ + struct malloc_state *next_free; ++ /* Number of threads attached to this arena. 0 if the arena is on ++ the free list. Access to this field is serialized by ++ free_list_lock in arena.c. */ ++ INTERNAL_SIZE_T attached_threads; + + /* Memory allocated from the system in this arena. */ + INTERNAL_SIZE_T system_mem; +@@ -1772,7 +1777,8 @@ struct malloc_par { + static struct malloc_state main_arena = + { + .mutex = MUTEX_INITIALIZER, +- .next = &main_arena ++ .next = &main_arena, ++ .attached_threads = 1, + }; + + /* There is only one instance of the malloc parameters. */ +Index: b/malloc/Makefile +=================================================================== +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -20,13 +20,14 @@ + # + subdir := malloc + +-all: ++include ../Makeconfig + + dist-headers := malloc.h + headers := $(dist-headers) obstack.h mcheck.h + tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \ +- tst-malloc-usable tst-malloc-backtrace ++ tst-malloc-usable \ ++ tst-malloc-backtrace tst-malloc-thread-exit + test-srcs = tst-mtrace + + routines = malloc morecore mcheck mtrace obstack +@@ -43,6 +44,8 @@ libmemusage-inhibit-o = $(filter-out .os + + $(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \ + $(common-objpfx)nptl/libpthread_nonshared.a ++$(objpfx)tst-malloc-thread-exit: $(common-objpfx)nptl/libpthread.so \ ++ $(common-objpfx)nptl/libpthread_nonshared.a + + # These should be removed by `make clean'. + extra-objs = mcheck-init.o libmcheck.a +@@ -50,8 +53,6 @@ extra-objs = mcheck-init.o libmcheck.a + # Include the cleanup handler. + aux := set-freeres thread-freeres + +-include ../Makeconfig +- + CPPFLAGS-memusagestat = -DNOT_IN_libc + + # The Perl script to analyze the output of the mtrace functions. +Index: b/malloc/tst-malloc-thread-exit.c +=================================================================== +--- /dev/null ++++ b/malloc/tst-malloc-thread-exit.c +@@ -0,0 +1,218 @@ ++/* Test malloc with concurrent thread termination. ++ Copyright (C) 2015-2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This thread spawns a number of outer threads, equal to the arena ++ limit. The outer threads run a loop which start and join two ++ different kinds of threads: the first kind allocates (attaching an ++ arena to the thread; malloc_first_thread) and waits, the second ++ kind waits and allocates (wait_first_threads). Both kinds of ++ threads exit immediately after waiting. The hope is that this will ++ exhibit races in thread termination and arena management, ++ particularly related to the arena free list. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int do_test (void); ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++static bool termination_requested; ++static int inner_thread_count = 4; ++static size_t malloc_size = 32; ++ ++static void ++__attribute__ ((noinline, noclone)) ++unoptimized_free (void *ptr) ++{ ++ free (ptr); ++} ++ ++static void * ++malloc_first_thread (void * closure) ++{ ++ pthread_barrier_t *barrier = closure; ++ void *ptr = malloc (malloc_size); ++ if (ptr == NULL) ++ { ++ printf ("error: malloc: %m\n"); ++ abort (); ++ } ++ int ret = pthread_barrier_wait (barrier); ++ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_wait: %m\n"); ++ abort (); ++ } ++ unoptimized_free (ptr); ++ return NULL; ++} ++ ++static void * ++wait_first_thread (void * closure) ++{ ++ pthread_barrier_t *barrier = closure; ++ int ret = pthread_barrier_wait (barrier); ++ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_wait: %m\n"); ++ abort (); ++ } ++ void *ptr = malloc (malloc_size); ++ if (ptr == NULL) ++ { ++ printf ("error: malloc: %m\n"); ++ abort (); ++ } ++ unoptimized_free (ptr); ++ return NULL; ++} ++ ++static void * ++outer_thread (void *closure) ++{ ++ pthread_t *threads = calloc (sizeof (*threads), inner_thread_count); ++ if (threads == NULL) ++ { ++ printf ("error: calloc: %m\n"); ++ abort (); ++ } ++ ++ while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED)) ++ { ++ pthread_barrier_t barrier; ++ int ret = pthread_barrier_init (&barrier, NULL, inner_thread_count + 1); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("pthread_barrier_init: %m\n"); ++ abort (); ++ } ++ for (int i = 0; i < inner_thread_count; ++i) ++ { ++ void *(*func) (void *); ++ if ((i % 2) == 0) ++ func = malloc_first_thread; ++ else ++ func = wait_first_thread; ++ ret = pthread_create (threads + i, NULL, func, &barrier); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_create: %m\n"); ++ abort (); ++ } ++ } ++ ret = pthread_barrier_wait (&barrier); ++ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) ++ { ++ errno = ret; ++ printf ("pthread_wait: %m\n"); ++ abort (); ++ } ++ for (int i = 0; i < inner_thread_count; ++i) ++ { ++ ret = pthread_join (threads[i], NULL); ++ if (ret != 0) ++ { ++ ret = errno; ++ printf ("error: pthread_join: %m\n"); ++ abort (); ++ } ++ } ++ ret = pthread_barrier_destroy (&barrier); ++ if (ret != 0) ++ { ++ ret = errno; ++ printf ("pthread_barrier_destroy: %m\n"); ++ abort (); ++ } ++ } ++ ++ free (threads); ++ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ /* The number of threads should be smaller than the number of ++ arenas, so that there will be some free arenas to add to the ++ arena free list. */ ++ enum { outer_thread_count = 2 }; ++ if (mallopt (M_ARENA_MAX, 8) == 0) ++ { ++ printf ("error: mallopt (M_ARENA_MAX) failed\n"); ++ return 1; ++ } ++ ++ /* Leave some room for shutting down all threads gracefully. */ ++ int timeout = 3; ++ if (timeout > TIMEOUT) ++ timeout = TIMEOUT - 1; ++ ++ pthread_t *threads = calloc (sizeof (*threads), outer_thread_count); ++ if (threads == NULL) ++ { ++ printf ("error: calloc: %m\n"); ++ abort (); ++ } ++ ++ for (long i = 0; i < outer_thread_count; ++i) ++ { ++ int ret = pthread_create (threads + i, NULL, outer_thread, NULL); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_create: %m\n"); ++ abort (); ++ } ++ } ++ ++ struct timespec ts = {timeout, 0}; ++ if (nanosleep (&ts, NULL)) ++ { ++ printf ("error: error: nanosleep: %m\n"); ++ abort (); ++ } ++ ++ __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED); ++ ++ for (long i = 0; i < outer_thread_count; ++i) ++ { ++ int ret = pthread_join (threads[i], NULL); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_join: %m\n"); ++ abort (); ++ } ++ } ++ free (threads); ++ ++ return 0; ++} diff --git a/SOURCES/glibc-rh1284959-1.patch b/SOURCES/glibc-rh1284959-1.patch new file mode 100644 index 00000000..70b8aecf --- /dev/null +++ b/SOURCES/glibc-rh1284959-1.patch @@ -0,0 +1,238 @@ +Description: Makes trimming work consistently across arenas. +Author: Mel Gorman +Origin: git://sourceware.org/git/glibc.git +Bug-RHEL: N/A +Bug-Fedora: N/A +Bug-Upstream: #17195 +Upstream status: committed + +Part of commit 8a35c3fe122d49ba76dff815b3537affb5a50b45 is also included +to allow the use of ALIGN_UP within malloc/arena.c. + +commit c26efef9798914e208329c0e8c3c73bb1135d9e3 +Author: Mel Gorman +Date: Thu Apr 2 12:14:14 2015 +0530 + + malloc: Consistently apply trim_threshold to all heaps [BZ #17195] + + Trimming heaps is a balance between saving memory and the system overhead + required to update page tables and discard allocated pages. The malloc + option M_TRIM_THRESHOLD is a tunable that users are meant to use to decide + where this balance point is but it is only applied to the main arena. + + For scalability reasons, glibc malloc has per-thread heaps but these are + shrunk with madvise() if there is one page free at the top of the heap. + In some circumstances this can lead to high system overhead if a thread + has a control flow like + + while (data_to_process) { + buf = malloc(large_size); + do_stuff(); + free(buf); + } + + For a large size, the free() will call madvise (pagetable teardown, page + free and TLB flush) every time followed immediately by a malloc (fault, + kernel page alloc, zeroing and charge accounting). The kernel overhead + can dominate such a workload. + + This patch allows the user to tune when madvise gets called by applying + the trim threshold to the per-thread heaps and using similar logic to the + main arena when deciding whether to shrink. Alternatively if the dynamic + brk/mmap threshold gets adjusted then the new values will be obeyed by + the per-thread heaps. + + Bug 17195 was a test case motivated by a problem encountered in scientific + applications written in python that performance badly due to high page fault + overhead. The basic operation of such a program was posted by Julian Taylor + https://sourceware.org/ml/libc-alpha/2015-02/msg00373.html + + With this patch applied, the overhead is eliminated. All numbers in this + report are in seconds and were recorded by running Julian's program 30 + times. + + pyarray + glibc madvise + 2.21 v2 + System min 1.81 ( 0.00%) 0.00 (100.00%) + System mean 1.93 ( 0.00%) 0.02 ( 99.20%) + System stddev 0.06 ( 0.00%) 0.01 ( 88.99%) + System max 2.06 ( 0.00%) 0.03 ( 98.54%) + Elapsed min 3.26 ( 0.00%) 2.37 ( 27.30%) + Elapsed mean 3.39 ( 0.00%) 2.41 ( 28.84%) + Elapsed stddev 0.14 ( 0.00%) 0.02 ( 82.73%) + Elapsed max 4.05 ( 0.00%) 2.47 ( 39.01%) + + glibc madvise + 2.21 v2 + User 141.86 142.28 + System 57.94 0.60 + Elapsed 102.02 72.66 + + Note that almost a minutes worth of system time is eliminted and the + program completes 28% faster on average. + + To illustrate the problem without python this is a basic test-case for + the worst case scenario where every free is a madvise followed by a an alloc + + /* gcc bench-free.c -lpthread -o bench-free */ + static int num = 1024; + + void __attribute__((noinline,noclone)) dostuff (void *p) + { + } + + void *worker (void *data) + { + int i; + + for (i = num; i--;) + { + void *m = malloc (48*4096); + dostuff (m); + free (m); + } + + return NULL; + } + + int main() + { + int i; + pthread_t t; + void *ret; + if (pthread_create (&t, NULL, worker, NULL)) + exit (2); + if (pthread_join (t, &ret)) + exit (3); + return 0; + } + + Before the patch, this resulted in 1024 calls to madvise. With the patch applied, + madvise is called twice because the default trim threshold is high enough to avoid + this. + + This a more complex case where there is a mix of frees. It's simply a different worker + function for the test case above + + void *worker (void *data) + { + int i; + int j = 0; + void *free_index[num]; + + for (i = num; i--;) + { + void *m = malloc ((i % 58) *4096); + dostuff (m); + if (i % 2 == 0) { + free (m); + } else { + free_index[j++] = m; + } + } + for (; j >= 0; j--) + { + free(free_index[j]); + } + + return NULL; + } + + glibc 2.21 calls malloc 90305 times but with the patch applied, it's + called 13438. Increasing the trim threshold will decrease the number of + times it's called with the option of eliminating the overhead. + + ebizzy is meant to generate a workload resembling common web application + server workloads. It is threaded with a large working set that at its core + has an allocation, do_stuff, free loop that also hits this case. The primary + metric of the benchmark is records processed per second. This is running on + my desktop which is a single socket machine with an I7-4770 and 8 cores. + Each thread count was run for 30 seconds. It was only run once as the + performance difference is so high that the variation is insignificant. + + glibc 2.21 patch + threads 1 10230 44114 + threads 2 19153 84925 + threads 4 34295 134569 + threads 8 51007 183387 + + Note that the saving happens to be a concidence as the size allocated + by ebizzy was less than the default threshold. If a different number of + chunks were specified then it may also be necessary to tune the threshold + to compensate + + This is roughly quadrupling the performance of this benchmark. The difference in + system CPU usage illustrates why. + + ebizzy running 1 thread with glibc 2.21 + 10230 records/s 306904 + real 30.00 s + user 7.47 s + sys 22.49 s + + 22.49 seconds was spent in the kernel for a workload runinng 30 seconds. With the + patch applied + + ebizzy running 1 thread with patch applied + 44126 records/s 1323792 + real 30.00 s + user 29.97 s + sys 0.00 s + + system CPU usage was zero with the patch applied. strace shows that glibc + running this workload calls madvise approximately 9000 times a second. With + the patch applied madvise was called twice during the workload (or 0.06 + times per second). + + 2015-02-10 Mel Gorman + + [BZ #17195] + * malloc/arena.c (free): Apply trim threshold to per-thread heaps + as well as the main arena. + +Index: glibc-2.17-c758a686/malloc/arena.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/arena.c ++++ glibc-2.17-c758a686/malloc/arena.c +@@ -661,7 +661,7 @@ heap_trim(heap_info *heap, size_t pad) + unsigned long pagesz = GLRO(dl_pagesize); + mchunkptr top_chunk = top(ar_ptr), p, bck, fwd; + heap_info *prev_heap; +- long new_size, top_size, extra, prev_size, misalign; ++ long new_size, top_size, top_area, extra, prev_size, misalign; + + /* Can this heap go away completely? */ + while(top_chunk == chunk_at_offset(heap, sizeof(*heap))) { +@@ -695,9 +695,16 @@ heap_trim(heap_info *heap, size_t pad) + set_head(top_chunk, new_size | PREV_INUSE); + /*check_chunk(ar_ptr, top_chunk);*/ + } ++ ++ /* Uses similar logic for per-thread arenas as the main arena with systrim ++ by preserving the top pad and at least a page. */ + top_size = chunksize(top_chunk); +- extra = (top_size - pad - MINSIZE - 1) & ~(pagesz - 1); +- if(extra < (long)pagesz) ++ top_area = top_size - MINSIZE - 1; ++ if (top_area <= pad) ++ return 0; ++ ++ extra = ALIGN_DOWN(top_area - pad, pagesz); ++ if ((unsigned long) extra < mp_.trim_threshold) + return 0; + /* Try to shrink. */ + if(shrink_heap(heap, extra) != 0) +Index: glibc-2.17-c758a686/malloc/malloc.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/malloc.c ++++ glibc-2.17-c758a686/malloc/malloc.c +@@ -236,6 +236,8 @@ + /* For va_arg, va_start, va_end. */ + #include + ++/* For ALIGN_UP. */ ++#include + + /* + Debugging: diff --git a/SOURCES/glibc-rh1284959-2.patch b/SOURCES/glibc-rh1284959-2.patch new file mode 100644 index 00000000..f66e6a68 --- /dev/null +++ b/SOURCES/glibc-rh1284959-2.patch @@ -0,0 +1,63 @@ +Description: Make trimming logic consistent. +Author: Carlos O'Donell +Origin: git://sourceware.org/git/glibc.git +Bug-RHEL: N/A +Bug-Fedora: N/A +Bug-Upstream: #17195 +Upstream status: committed + +commit e4bc326dbbf7328775fe7dd39de1178821363e0a +Author: Carlos O'Donell +Date: Wed Oct 7 22:21:36 2015 -0400 + + malloc: Consistently apply trim_threshold to all heaps (Bug 17195) + + In the per-thread arenas we apply trim_threshold-based checks + to the extra space between the pad and the top_area. This isn't + quite accurate and instead we should be harmonizing with the way + in which trim_treshold is applied everywhere else like sysrtim + and _int_free. The trimming check should be based on the size of + the top chunk and only the size of the top chunk. The following + patch harmonizes the trimming and make it consistent for the main + arena and thread arenas. + + In the old code a large padding request might have meant that + trimming was not triggered. Now trimming is considered first based + on the chunk, then the pad is subtracted, and the remainder trimmed. + This is how all the other trimmings operate. I didn't measure the + performance difference of this change because it corrects what I + consider to be a behavioural anomaly. We'll need some profile driven + optimization to make this code better, and even there Ondrej and + others have better ideas on how to speedup malloc. + + Tested on x86_64 with no regressions. Already reviewed by Siddhesh + Poyarekar and Mel Gorman here and discussed here: + https://sourceware.org/ml/libc-alpha/2015-05/msg00002.html + +Index: glibc-2.17-c758a686/malloc/arena.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/arena.c ++++ glibc-2.17-c758a686/malloc/arena.c +@@ -697,14 +697,20 @@ heap_trim(heap_info *heap, size_t pad) + } + + /* Uses similar logic for per-thread arenas as the main arena with systrim +- by preserving the top pad and at least a page. */ ++ and _int_free by preserving the top pad and rounding down to the nearest ++ page. */ + top_size = chunksize(top_chunk); ++ if ((unsigned long)(top_size) < ++ (unsigned long)(mp_.trim_threshold)) ++ return 0; ++ + top_area = top_size - MINSIZE - 1; + if (top_area <= pad) + return 0; + ++ /* Release in pagesize units and round down to the nearest page. */ + extra = ALIGN_DOWN(top_area - pad, pagesz); +- if ((unsigned long) extra < mp_.trim_threshold) ++ if (extra == 0) + return 0; + /* Try to shrink. */ + if(shrink_heap(heap, extra) != 0) diff --git a/SOURCES/glibc-rh1284959-3.patch b/SOURCES/glibc-rh1284959-3.patch new file mode 100644 index 00000000..8a479d0a --- /dev/null +++ b/SOURCES/glibc-rh1284959-3.patch @@ -0,0 +1,52 @@ +Short description: Don't corrupt heap if top chunk is MINSIZE. +Author(s): Mel Gorman +Origin: git://sourceware.org/git/glibc.git +Bug-RHEL: N/A +Bug-Fedora: N/A +Bug-Upstream: #18502 +Upstream status: committed + +commit f8ef472c0ff4644445ec716036d31430b4fa4bab +Author: Mel Gorman +Date: Mon Jun 8 13:36:13 2015 +0100 + + malloc: Do not corrupt the top of a threaded heap if top chunk is MINSIZE [BZ #18502] + + mksquashfs was reported in openSUSE to be causing segmentation faults when + creating installation images. Testing showed that mksquashfs sometimes + failed and could be reproduced within 10 attempts. The core dump looked + like the heap top was corrupted and was pointing to an unmapped area. In + other cases, this has been due to an application corrupting glibc structures + but mksquashfs appears to be fine in this regard. + + The problem is that heap_trim is "growing" the top into unmapped space. + If the top chunk == MINSIZE then top_area is -1 and this check does not + behave as expected due to a signed/unsigned comparison + + if (top_area <= pad) + return 0; + + The next calculation extra = ALIGN_DOWN(top_area - pad, pagesz) calculates + extra as a negative number which also is unnoticed due to a signed/unsigned + comparison. We then call shrink_heap(heap, negative_number) which crashes + later. This patch adds a simple check against MINSIZE to make sure extra + does not become negative. It adds a cast to hint to the reader that this + is a signed vs unsigned issue. + + Without the patch, mksquash fails within 10 attempts. With it applied, it + completed 1000 times without error. The standard test suite "make check" + showed no changes in the summary of test results. + +Index: glibc-2.17-c758a686/malloc/arena.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/arena.c ++++ glibc-2.17-c758a686/malloc/arena.c +@@ -705,7 +705,7 @@ heap_trim(heap_info *heap, size_t pad) + return 0; + + top_area = top_size - MINSIZE - 1; +- if (top_area <= pad) ++ if (top_area < 0 || (size_t) top_area <= pad) + return 0; + + /* Release in pagesize units and round down to the nearest page. */ diff --git a/SOURCES/glibc-rh1288613.patch b/SOURCES/glibc-rh1288613.patch new file mode 100644 index 00000000..5d1ec4f9 --- /dev/null +++ b/SOURCES/glibc-rh1288613.patch @@ -0,0 +1,183 @@ +commit b57525f1a376149840f740a31535681c07152ba4 +Author: Dmitry V. Levin +Date: Thu Jun 18 21:40:46 2015 +0000 + + Fix potential hanging of gethostbyaddr_r/gethostbyname_r + + When "reorder" resolver option is enabled, threads of a multi-threaded + process could hang in gethostbyaddr_r, gethostbyname_r, or + gethostbyname2_r. + + Due to a trivial bug in _res_hconf_reorder_addrs, simultaneous + invocations of this function in a multi-threaded process could result to + _res_hconf_reorder_addrs returning without releasing the lock it holds, + causing other threads to block indefinitely while waiting for the lock + that is not going to be released. + + [BZ #17977] + * resolv/res_hconf.c (_res_hconf_reorder_addrs): Fix unlocking + when initializing interface list, based on the bug analysis + and the patch proposed by Eric Newton. + * resolv/tst-res_hconf_reorder.c: New test. + * resolv/Makefile [$(have-thread-library) = yes] (tests): Add + tst-res_hconf_reorder. + ($(objpfx)tst-res_hconf_reorder): Depend on $(libdl) + and $(shared-thread-library). + (tst-res_hconf_reorder-ENV): New variable. + +Index: glibc-2.17-c758a686/resolv/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/Makefile ++++ glibc-2.17-c758a686/resolv/Makefile +@@ -40,6 +40,7 @@ extra-libs := libresolv libnss_dns + ifeq ($(have-thread-library),yes) + extra-libs += libanl + routines += gai_sigqueue ++tests += tst-res_hconf_reorder + endif + extra-libs-others = $(extra-libs) + libresolv-routines := gethnamaddr res_comp res_debug \ +@@ -108,6 +108,9 @@ $(objpfx)libanl.so: $(common-objpfx)libc + + $(objpfx)ga_test: $(objpfx)libanl.so $(shared-thread-library) + ++$(objpfx)tst-res_hconf_reorder: $(libdl) $(shared-thread-library) ++tst-res_hconf_reorder-ENV = RESOLV_REORDER=on ++ + $(objpfx)tst-leaks: $(objpfx)libresolv.so + tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace + $(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out +Index: glibc-2.17-c758a686/resolv/res_hconf.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/res_hconf.c ++++ glibc-2.17-c758a686/resolv/res_hconf.c +@@ -462,10 +462,10 @@ _res_hconf_reorder_addrs (struct hostent + errno = save; + + num_ifs = new_num_ifs; +- +- __libc_lock_unlock (lock); + } + ++ __libc_lock_unlock (lock); ++ + __close (sd); + } + +Index: glibc-2.17-c758a686/resolv/tst-res_hconf_reorder.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/resolv/tst-res_hconf_reorder.c +@@ -0,0 +1,112 @@ ++/* BZ #17977 _res_hconf_reorder_addrs test. ++ ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct timespec ts; ++ ++/* The first thread that gets a lock in _res_hconf_reorder_addrs() ++ should hold the lock long enough to make two other threads blocked. ++ This is achieved by slowing down realloc(3) that is called several times ++ by _res_hconf_reorder_addrs(). */ ++ ++void * ++realloc (void *ptr, size_t len) ++{ ++ static void *(*fun) (void *, size_t); ++ ++ if (!fun) ++ fun = dlsym (RTLD_NEXT, "realloc"); ++ ++ if (ts.tv_nsec) ++ nanosleep (&ts, NULL); ++ ++ return (*fun) (ptr, len); ++} ++ ++static void * ++resolve (void *arg) ++{ ++ struct in_addr addr; ++ struct hostent ent; ++ struct hostent *result; ++ int err; ++ char buf[1024]; ++ ++ addr.s_addr = htonl (INADDR_LOOPBACK); ++ (void) gethostbyaddr_r ((void *) &addr, sizeof (addr), AF_INET, ++ &ent, buf, sizeof (buf), &result, &err); ++ return arg; ++} ++ ++static int ++do_test (void) ++{ ++ #define N 3 ++ pthread_t thr[N]; ++ unsigned int i; ++ int result = 0; ++ ++ /* turn on realloc slowdown */ ++ ts.tv_nsec = 100000000; ++ ++ for (i = 0; i < N; ++i) ++ { ++ int rc = pthread_create (&thr[i], NULL, resolve, NULL); ++ ++ if (rc) ++ { ++ printf ("pthread_create: %s\n", strerror(rc)); ++ exit (1); ++ } ++ } ++ ++ for (i = 0; i < N; ++i) ++ { ++ void *retval; ++ int rc = pthread_join (thr[i], &retval); ++ ++ if (rc) ++ { ++ printf ("pthread_join: %s\n", strerror(rc)); ++ exit (1); ++ } ++ if (retval) ++ { ++ printf ("thread %u exit status %p\n", i, retval); ++ result = 1; ++ } ++ } ++ ++ /* turn off realloc slowdown, no longer needed */ ++ ts.tv_nsec = 0; ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh1292018-0.patch b/SOURCES/glibc-rh1292018-0.patch new file mode 100644 index 00000000..29f5a9d7 --- /dev/null +++ b/SOURCES/glibc-rh1292018-0.patch @@ -0,0 +1,55 @@ +commit a3d9ab5070b56b49aa91be2887fa5b118012b2cd +Author: H.J. Lu +Date: Tue Mar 31 13:17:51 2015 -0700 + + Limit threads sharing L2 cache to 2 for SLM/KNL + + Silvermont and Knights Landing have a modular system design with two cores + sharing an L2 cache. If more than 2 cores are detected to shared L2 cache, + it should be adjusted for Silvermont and Knights Landing. + + [BZ #18185] + * sysdeps/x86_64/cacheinfo.c (init_cacheinfo): Limit threads + sharing L2 cache to 2 for Silvermont/Knights Landing. + +diff --git a/sysdeps/x86_64/cacheinfo.c b/sysdeps/x86_64/cacheinfo.c +index f1cbf50..b99fb9a 100644 +--- a/sysdeps/x86_64/cacheinfo.c ++++ b/sysdeps/x86_64/cacheinfo.c +@@ -585,6 +585,10 @@ init_cacheinfo (void) + __cpuid (1, eax, ebx_1, ecx, edx); + #endif + ++ unsigned int family = (eax >> 8) & 0x0f; ++ unsigned int model = (eax >> 4) & 0x0f; ++ unsigned int extended_model = (eax >> 12) & 0xf0; ++ + #ifndef DISABLE_PREFERRED_MEMORY_INSTRUCTION + /* Intel prefers SSSE3 instructions for memory/string routines + if they are available. */ +@@ -647,6 +651,25 @@ init_cacheinfo (void) + } + } + threads += 1; ++ if (threads > 2 && level == 2 && family == 6) ++ { ++ model += extended_model; ++ switch (model) ++ { ++ case 0x57: ++ /* Knights Landing has L2 cache shared by 2 cores. */ ++ case 0x37: ++ case 0x4a: ++ case 0x4d: ++ case 0x5a: ++ case 0x5d: ++ /* Silvermont has L2 cache shared by 2 cores. */ ++ threads = 2; ++ break; ++ default: ++ break; ++ } ++ } + } + else + { diff --git a/SOURCES/glibc-rh1292018-0a.patch b/SOURCES/glibc-rh1292018-0a.patch new file mode 100644 index 00000000..635ba3dd --- /dev/null +++ b/SOURCES/glibc-rh1292018-0a.patch @@ -0,0 +1,423 @@ +Required to get access to _rtld_global_ro@@GLIBC_PRIVATE +since it's only available from ld.so. + +commit fab7ce3f5b4060bf62659e8b58529de4156b5a2f +Author: Joseph Myers +Date: Fri May 31 16:16:33 2013 +0000 + + Link extra-libs consistently with libc and ld.so. + +Index: glibc-2.17-c758a686/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/Makefile ++++ glibc-2.17-c758a686/Makefile +@@ -127,6 +127,9 @@ lib: $(common-objpfx)libc.so + + lib: $(common-objpfx)linkobj/libc.so + ++# Do not filter ld.so out of libc.so link. ++$(common-objpfx)linkobj/libc.so: link-libc-deps = # empty ++ + $(common-objpfx)linkobj/libc.so: $(elfobjdir)/soinit.os \ + $(common-objpfx)linkobj/libc_pic.a \ + $(elfobjdir)/sofini.os \ +Index: glibc-2.17-c758a686/Makerules +=================================================================== +--- glibc-2.17-c758a686.orig/Makerules ++++ glibc-2.17-c758a686/Makerules +@@ -470,9 +470,10 @@ link-libc-deps = $(common-objpfx)libc.so + # This must come after the installation rules so Make doesn't try to + # build shared libraries in place from the installed *_pic.a files. + # $(LDLIBS-%.so) may contain -l switches to generate run-time dependencies +-# on other shared objects. +-lib%.so: lib%_pic.a $(+preinit) $(+postinit) +- $(build-shlib) ++# on other shared objects. The linking with libc and ld.so is intended ++# to be as similar as possible to a default link with an installed libc. ++lib%.so: lib%_pic.a $(+preinit) $(+postinit) $(+interp) $(link-libc-deps) ++ $(build-shlib) $(link-libc-args) + + define build-shlib-helper + $(LINK.o) -shared $(static-libgcc) -Wl,-O1 $(sysdep-LDFLAGS) \ +@@ -558,7 +559,8 @@ endef + + build-module-helper-objlist = \ + $(patsubst %_pic.a,$(whole-archive) %_pic.a $(no-whole-archive),\ +- $(filter-out %.lds $(map-file) $(+preinit) $(+postinit),$^)) ++ $(filter-out %.lds $(map-file) $(+preinit) $(+postinit) \ ++ $(link-libc-deps),$^)) + + build-module-objlist = $(build-module-helper-objlist) $(LDLIBS-$(@F:%.so=%).so) + build-shlib-objlist = $(build-module-helper-objlist) \ +@@ -601,6 +603,9 @@ generated += libc_pic.opts libc_pic.os.c + libc_pic_clean := .clean + endif + ++# Do not filter ld.so out of libc.so link. ++$(common-objpfx)libc.so: link-libc-deps = # empty ++ + # Use our own special initializer and finalizer files for libc.so. + $(common-objpfx)libc.so: $(elfobjdir)/soinit.os \ + $(common-objpfx)libc_pic.os$(libc_pic_clean) \ +@@ -660,8 +665,7 @@ include $(patsubst %,$(..)extra-modules. + + extra-modules-build := $(filter-out $(modules-names-nobuild),$(modules-names)) + $(extra-modules-build:%=$(objpfx)%.so): $(objpfx)%.so: \ +- $(objpfx)%.os $(shlib-lds) \ +- $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a ++ $(objpfx)%.os $(shlib-lds) $(link-libs-deps) + $(build-module) + endif + +Index: glibc-2.17-c758a686/crypt/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/crypt/Makefile ++++ glibc-2.17-c758a686/crypt/Makefile +@@ -72,8 +72,3 @@ endif + ifeq (yes,$(build-bounded)) + $(tests:%=$(objpfx)%-bp): $(objpfx)libcrypt_b.a + endif +- +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libcrypt.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a +Index: glibc-2.17-c758a686/debug/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/debug/Makefile ++++ glibc-2.17-c758a686/debug/Makefile +@@ -159,13 +159,3 @@ $(objpfx)xtrace: xtrace.sh + -e 's|@PKGVERSION@|$(PKGVERSION)|' \ + -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|' $^ > $@.new \ + && rm -f $@ && mv $@.new $@ && chmod +x $@ +- +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libSegFault.so: $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a \ +- $(elf-objpfx)$(rtld-installed-name) +-$(objpfx)libpcprofile.so: $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a \ +- $(elf-objpfx)$(rtld-installed-name) +Index: glibc-2.17-c758a686/dlfcn/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/dlfcn/Makefile ++++ glibc-2.17-c758a686/dlfcn/Makefile +@@ -117,16 +117,9 @@ $(objpfx)bug-atexit1.out: $(objpfx)bug-a + $(objpfx)bug-atexit2: $(libdl) + $(objpfx)bug-atexit2.out: $(objpfx)bug-atexit2-lib.so + +-LDLIBS-bug-atexit3-lib.so = -lstdc++ -lgcc_eh $(elfobjdir)/ld.so \ +- $(common-objpfx)libc_nonshared.a ++LDLIBS-bug-atexit3-lib.so = -lstdc++ -lgcc_eh + $(objpfx)bug-atexit3: $(libdl) + $(objpfx)bug-atexit3.out: $(objpfx)bug-atexit3-lib.so + + $(objpfx)tst-rec-dlopen: $(libdl) + $(objpfx)tst-rec-dlopen.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so +- +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libdl.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a \ +- $(elfobjdir)/ld.so +Index: glibc-2.17-c758a686/hesiod/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/hesiod/Makefile ++++ glibc-2.17-c758a686/hesiod/Makefile +@@ -33,12 +33,7 @@ libnss_hesiod-inhibit-o = $(filter-out . + + include ../Rules + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-# The Hesiod NSS modules also needs the resolver and some help from ++# The Hesiod NSS module also needs the resolver and some help from + # the file service. + $(objpfx)libnss_hesiod.so: $(common-objpfx)resolv/libresolv.so \ +- $(common-objpfx)nss/libnss_files.so \ +- $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a ++ $(common-objpfx)nss/libnss_files.so +Index: glibc-2.17-c758a686/iconvdata/extra-module.mk +=================================================================== +--- glibc-2.17-c758a686.orig/iconvdata/extra-module.mk ++++ glibc-2.17-c758a686/iconvdata/extra-module.mk +@@ -4,16 +4,9 @@ extra-modules-left := $(strip $(filter-o + extra-objs := $(extra-objs) $(patsubst %,%.os,$($(mod)-routines)) + + $(objpfx)$(mod).so: $(addprefix $(objpfx),$(addsuffix .os,$($(mod)-routines)))\ +- $(shlib-lds) ++ $(shlib-lds) $(link-libc-deps) + $(build-module-asneeded) + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)$(mod).so: $(common-objpfx)libc.so \ +- $(common-objpfx)/elf/ld.so \ +- $(common-objpfx)libc_nonshared.a +- + ifneq (,$(extra-modules-left)) + include extra-module.mk + endif +Index: glibc-2.17-c758a686/libidn/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/libidn/Makefile ++++ glibc-2.17-c758a686/libidn/Makefile +@@ -33,5 +33,3 @@ include $(..)Makeconfig + libcidn-inhibit-o = $(filter-out .os,$(object-suffixes)) + + include $(..)Rules +- +-$(objpfx)libcidn.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a +Index: glibc-2.17-c758a686/locale/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/locale/Makefile ++++ glibc-2.17-c758a686/locale/Makefile +@@ -99,9 +99,3 @@ cpp-srcs-left := $(localedef-modules) $( + $(lib-modules) + lib := locale-programs + include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) +- +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libBrokenLocale.so: $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a +Index: glibc-2.17-c758a686/login/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/login/Makefile ++++ glibc-2.17-c758a686/login/Makefile +@@ -76,8 +76,3 @@ endif + $(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force) + $(make-target-directory) + -$(INSTALL_PROGRAM) -m 4755 -o root $< $@ +- +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libutil.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a +Index: glibc-2.17-c758a686/malloc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/Makefile ++++ glibc-2.17-c758a686/malloc/Makefile +@@ -151,7 +151,7 @@ $(objpfx)memusage: memusage.sh + + + # The implementation uses `dlsym' +-$(objpfx)libmemusage.so: $(common-objpfx)dlfcn/libdl.so $(elfobjdir)/ld.so ++$(objpfx)libmemusage.so: $(common-objpfx)dlfcn/libdl.so + + # Extra dependencies + $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c +Index: glibc-2.17-c758a686/math/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/math/Makefile ++++ glibc-2.17-c758a686/math/Makefile +@@ -203,8 +203,3 @@ gmp-objs = $(patsubst %,$(common-objpfx) + $(objpfx)atest-exp: $(gmp-objs) + $(objpfx)atest-sincos: $(gmp-objs) + $(objpfx)atest-exp2: $(gmp-objs) +- +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libm.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a +Index: glibc-2.17-c758a686/nis/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nis/Makefile ++++ glibc-2.17-c758a686/nis/Makefile +@@ -77,12 +77,12 @@ $(objpfx)libnss_nis.so: $(objpfx)libnsl. + $(common-objpfx)nss/libnss_files.so + $(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version) + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. + libnsl-libc = $(common-objpfx)linkobj/libc.so +-$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: $(libnsl-libc) \ +- $(common-objpfx)libc_nonshared.a ++# Target-specific variable setting to link objects using deprecated ++# RPC interfaces with the version of libc.so that makes them available ++# for new links: ++$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \ ++ libc-for-link = $(libnsl-libc) + + + ifeq ($(build-shared),yes) +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -530,14 +530,6 @@ $(objpfx)libpthread.so: $(addprefix $(ob + $(objpfx)libpthread.so: +preinit += $(addprefix $(objpfx),$(crti-objs)) + $(objpfx)libpthread.so: +postinit += $(addprefix $(objpfx),$(crtn-objs)) + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-# Depend on ld.so too to get proper versions of ld.so symbols. +-$(objpfx)libpthread.so: $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a \ +- $(elfobjdir)/ld.so +- + # Make sure we link with the thread library. + ifeq ($(build-shared),yes) + $(addprefix $(objpfx), \ +Index: glibc-2.17-c758a686/nptl_db/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl_db/Makefile ++++ glibc-2.17-c758a686/nptl_db/Makefile +@@ -51,12 +51,6 @@ libthread_db.so-no-z-defs = yes + + include ../Rules + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libthread_db.so: $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a +- + tests: $(objpfx)db-symbols.out + $(objpfx)db-symbols.out: $(objpfx)db-symbols.v.i \ + $(common-objpfx)nptl/libpthread.so +Index: glibc-2.17-c758a686/nss/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nss/Makefile ++++ glibc-2.17-c758a686/nss/Makefile +@@ -86,12 +86,11 @@ ifeq (yes,$(have-selinux)) + LDLIBS-makedb := -lselinux + endif + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. + libnss-libc = $(common-objpfx)linkobj/libc.so +-$(services:%=$(objpfx)libnss_%.so): $(libnss-libc) \ +- $(common-objpfx)libc_nonshared.a ++# Target-specific variable setting to link objects using deprecated ++# RPC interfaces with the version of libc.so that makes them available ++# for new links: ++$(services:%=$(objpfx)libnss_%.so): libc-for-link = $(libnss-libc) + + $(objpfx)libnss_db.so: $(objpfx)libnss_files.so + +@@ -109,8 +108,7 @@ $(inst_vardbdir)/Makefile: db-Makefile $ + $(do-install) + + libof-nss_test1 = extramodules +-$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a ++$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) + ifdef libnss_test1.so-version + $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so +Index: glibc-2.17-c758a686/ports/sysdeps/arm/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/arm/Makefile +@@ -25,11 +25,6 @@ sysdep_routines += $(aeabi_constants) $( + static-only-routines += $(aeabi_constants) + endif + +-# to pull in __aeabi_read_tp, needed for tls +-ifeq ($(subdir),malloc) +-$(objpfx)libmemusage.so: $(common-objpfx)libc_nonshared.a +-endif +- + ifeq ($(subdir),gmon) + sysdep_routines += arm-mcount + endif +@@ -37,7 +32,3 @@ endif + ifeq ($(subdir),debug) + CFLAGS-backtrace.c += -funwind-tables + endif +- +-ifeq ($(subdir),math) +-$(objpfx)libm.so: $(elfobjdir)/ld.so +-endif +Index: glibc-2.17-c758a686/resolv/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/Makefile ++++ glibc-2.17-c758a686/resolv/Makefile +@@ -88,23 +88,11 @@ CFLAGS-res_hconf.c = -fexceptions + # The BIND code elicits some harmless warnings. + +cflags += -Wno-strict-prototypes -Wno-write-strings + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)libresolv.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a +-# Some hosts need '__stack_chk_guard', so pull in the definition from +-# ld.so if required. +-ifeq (yes,$(have-ssp)) +-LDLIBS-resolv.so += $(as-needed) $(elfobjdir)/ld.so $(no-as-needed) +-endif +- + # The DNS NSS modules needs the resolver. +-$(objpfx)libnss_dns.so: $(objpfx)libresolv.so $(common-objpfx)libc.so \ +- $(common-objpfx)libc_nonshared.a ++$(objpfx)libnss_dns.so: $(objpfx)libresolv.so + + # The asynchronous name lookup code needs the thread library. +-$(objpfx)libanl.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a \ +- $(shared-thread-library) ++$(objpfx)libanl.so: $(shared-thread-library) + + $(objpfx)ga_test: $(objpfx)libanl.so $(shared-thread-library) + +Index: glibc-2.17-c758a686/rt/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/rt/Makefile ++++ glibc-2.17-c758a686/rt/Makefile +@@ -64,12 +64,7 @@ CFLAGS-librt-cancellation.c = -fasynchro + + LDFLAGS-rt.so = -Wl,--enable-new-dtags,-z,nodelete + +-# Depend on libc.so so a DT_NEEDED is generated in the shared objects. +-# This ensures they will load libc.so for needed symbols if loaded by +-# a statically-linked program that hasn't already loaded it. +-$(objpfx)librt.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a \ +- $(shared-thread-library) \ +- $(elfobjdir)/ld.so ++$(objpfx)librt.so: $(shared-thread-library) + + ifeq (yes,$(build-shared)) + $(addprefix $(objpfx),$(tests)): $(objpfx)librt.so $(shared-thread-library) +Index: glibc-2.17-c758a686/stdlib/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/stdlib/Makefile ++++ glibc-2.17-c758a686/stdlib/Makefile +@@ -136,7 +136,7 @@ $(objpfx)tst-fmtmsg.out: tst-fmtmsg.sh $ + $(objpfx)tst-putenv: $(objpfx)tst-putenvmod.so + LDFLAGS-tst-putenv = $(no-as-needed) + +-$(objpfx)tst-putenvmod.so: $(objpfx)tst-putenvmod.os ++$(objpfx)tst-putenvmod.so: $(objpfx)tst-putenvmod.os $(link-libc-deps) + $(build-module) + libof-tst-putenvmod = extramodules + +Index: glibc-2.17-c758a686/sysdeps/i386/fpu/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/fpu/Makefile ++++ /dev/null +@@ -1,3 +0,0 @@ +-ifeq ($(subdir),math) +-$(objpfx)libm.so: $(elfobjdir)/ld.so +-endif +Index: glibc-2.17-c758a686/sysdeps/powerpc/fpu/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/fpu/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/Makefile +@@ -2,8 +2,6 @@ ifeq ($(subdir),math) + libm-support += fenv_const fe_nomask fe_mask t_sqrt + libm-tests += test-powerpc-snan + +-# libm needs ld.so to access dl_hwcap +-$(objpfx)libm.so: $(elfobjdir)/ld.so + endif + + ifeq ($(subdir),stdlib) diff --git a/SOURCES/glibc-rh1292018-0b.patch b/SOURCES/glibc-rh1292018-0b.patch new file mode 100644 index 00000000..a0a28d2f --- /dev/null +++ b/SOURCES/glibc-rh1292018-0b.patch @@ -0,0 +1,148 @@ +Needed to get future uses of all-dl-routines to include +__get_cpu_features into the right shared object routines. + +commit ac9e0e5e401fa634667a8284a0db0ca886bf816b +Author: Roland McGrath +Date: Fri Feb 6 10:42:08 2015 -0800 + + Clean up sysdep-dl-routines variable. + +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -22,7 +22,7 @@ subdir := elf + include ../Makeconfig + + headers = elf.h bits/elfclass.h link.h bits/link.h +-routines = $(dl-routines) dl-support dl-iteratephdr \ ++routines = $(all-dl-routines) dl-support dl-iteratephdr \ + dl-addr enbl-secure dl-profstub \ + dl-origin dl-libc dl-sym dl-tsd dl-sysdep + +@@ -43,7 +43,7 @@ shared-only-routines += dl-caller + + # ld.so uses those routines, plus some special stuff for being the program + # interpreter and operating independent of libc. +-rtld-routines := rtld $(dl-routines) dl-sysdep dl-environ dl-minimal ++rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal + all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines) + + CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables +Index: glibc-2.17-c758a686/ports/sysdeps/aarch64/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/aarch64/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/aarch64/Makefile +@@ -2,8 +2,6 @@ long-double-fcts = yes + + ifeq ($(subdir),elf) + sysdep-dl-routines += tlsdesc dl-tlsdesc +-sysdep_routines += tlsdesc dl-tlsdesc +-sysdep-rtld-routines += tlsdesc dl-tlsdesc + gen-as-const-headers += dl-link.sym + endif + +Index: glibc-2.17-c758a686/ports/sysdeps/arm/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/arm/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/arm/Makefile +@@ -3,8 +3,8 @@ static-gnulib-arch = $(elfobjdir)/libgcc + + ifeq ($(subdir),elf) + sysdep-dl-routines += tlsdesc dl-tlsdesc +-sysdep_routines += aeabi_unwind_cpp_pr1 find_exidx tlsdesc dl-tlsdesc +-sysdep-rtld-routines += aeabi_unwind_cpp_pr1 tlsdesc dl-tlsdesc ++sysdep_routines += aeabi_unwind_cpp_pr1 find_exidx ++sysdep-rtld-routines += aeabi_unwind_cpp_pr1 + shared-only-routines += aeabi_unwind_cpp_pr1 + + $(objpfx)libgcc-stubs.a: $(objpfx)aeabi_unwind_cpp_pr1.os +Index: glibc-2.17-c758a686/ports/sysdeps/hppa/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/hppa/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/hppa/Makefile +@@ -24,8 +24,6 @@ LDFLAGS-c_pic.os += -Wl,--unique=.text* + ifeq ($(subdir),elf) + CFLAGS-rtld.c += -mdisable-fpregs + sysdep-dl-routines += dl-symaddr dl-fptr +-sysdep_routines += $(sysdep-dl-routines) +-sysdep-rtld-routines += $(sysdep-dl-routines) + endif + + ifeq ($(subdir),csu) +Index: glibc-2.17-c758a686/sysdeps/i386/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/Makefile ++++ glibc-2.17-c758a686/sysdeps/i386/Makefile +@@ -74,8 +74,6 @@ endif + + ifeq ($(subdir),elf) + sysdep-dl-routines += tlsdesc dl-tlsdesc +-sysdep_routines += tlsdesc dl-tlsdesc +-sysdep-rtld-routines += tlsdesc dl-tlsdesc + endif + + ifeq ($(subdir),csu) +Index: glibc-2.17-c758a686/ports/sysdeps/ia64/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/ia64/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/ia64/Makefile +@@ -17,6 +17,4 @@ endif + + ifeq ($(subdir),elf) + sysdep-dl-routines += dl-symaddr dl-fptr +-sysdep_routines += $(sysdep-dl-routines) +-sysdep-rtld-routines += $(sysdep-dl-routines) + endif +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/ia64/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/ia64/Makefile +@@ -14,8 +14,6 @@ endif + + ifeq ($(subdir),elf) + sysdep-dl-routines += dl-static +-sysdep_routines += $(sysdep-dl-routines) +-sysdep-rtld-routines += $(sysdep-dl-routines) + endif + + ifeq ($(subdir),rt) +Index: glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/ports/sysdeps/unix/sysv/linux/mips/Makefile ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/mips/Makefile +@@ -49,8 +49,6 @@ ifeq ($(subdir),elf) + ifeq ($(build-shared),yes) + # This is needed for DSO loading from static binaries. + sysdep-dl-routines += dl-static +-sysdep_routines += dl-static +-sysdep-rtld-routines += dl-static + endif + endif + +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/Makefile ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile +@@ -21,8 +21,6 @@ sysdep_routines += dl-vdso + ifeq ($(build-shared),yes) + # This is needed for DSO loading from static binaries. + sysdep-dl-routines += dl-static +-sysdep_routines += dl-static +-sysdep-rtld-routines += dl-static + endif + endif + +Index: glibc-2.17-c758a686/sysdeps/x86_64/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/Makefile ++++ glibc-2.17-c758a686/sysdeps/x86_64/Makefile +@@ -20,8 +20,6 @@ endif + + ifeq ($(subdir),elf) + sysdep-dl-routines += tlsdesc dl-tlsdesc +-sysdep_routines += tlsdesc dl-tlsdesc +-sysdep-rtld-routines += tlsdesc dl-tlsdesc + + tests += tst-quad1 tst-quad2 + modules-names += tst-quadmod1 tst-quadmod2 diff --git a/SOURCES/glibc-rh1292018-1.patch b/SOURCES/glibc-rh1292018-1.patch new file mode 100644 index 00000000..861759e1 --- /dev/null +++ b/SOURCES/glibc-rh1292018-1.patch @@ -0,0 +1,1522 @@ +We add back Prefer_SSE_for_memop since we still need it for all of the +existing era implementations for RHEL 7.3. To remove it would require +a more wholesale backport of optmized routines. + +commit e2e4f56056adddc3c1efe676b40a4b4f2453103b +Author: H.J. Lu +Date: Thu Aug 13 03:37:47 2015 -0700 + + Add _dl_x86_cpu_features to rtld_global + + This patch adds _dl_x86_cpu_features to rtld_global in x86 ld.so + and initializes it early before __libc_start_main is called so that + cpu_features is always available when it is used and we can avoid + calling __init_cpu_features in IFUNC selectors. + +Index: glibc-2.17-c758a686/sysdeps/i386/dl-machine.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/dl-machine.h ++++ glibc-2.17-c758a686/sysdeps/i386/dl-machine.h +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -266,6 +267,8 @@ dl_platform_init (void) + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') + /* Avoid an empty string which would disturb us. */ + GLRO(dl_platform) = NULL; ++ ++ init_cpu_features (&GLRO(dl_x86_cpu_features)); + } + + static inline Elf32_Addr +Index: glibc-2.17-c758a686/sysdeps/i386/dl-procinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/dl-procinfo.c ++++ glibc-2.17-c758a686/sysdeps/i386/dl-procinfo.c +@@ -43,6 +43,22 @@ + # define PROCINFO_CLASS + #endif + ++#if !IS_IN (ldconfig) ++# if !defined PROCINFO_DECL && defined SHARED ++ ._dl_x86_cpu_features ++# else ++PROCINFO_CLASS struct cpu_features _dl_x86_cpu_features ++# endif ++# ifndef PROCINFO_DECL ++= { } ++# endif ++# if !defined SHARED || defined PROCINFO_DECL ++; ++# else ++, ++# endif ++#endif ++ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_x86_cap_flags + #else +Index: glibc-2.17-c758a686/sysdeps/i386/i686/cacheinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/cacheinfo.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/cacheinfo.c +@@ -8,6 +8,5 @@ + #define __x86_64_raw_shared_cache_size_half __x86_raw_shared_cache_size_half + + #define DISABLE_PREFETCHW +-#define DISABLE_PREFERRED_MEMORY_INSTRUCTION + + #include +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Makefile +@@ -1,5 +1,4 @@ + ifeq ($(subdir),csu) +-aux += init-arch + tests += test-multiarch + gen-as-const-headers += ifunc-defines.sym + endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/Versions +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/Versions ++++ /dev/null +@@ -1,5 +0,0 @@ +-libc { +- GLIBC_PRIVATE { +- __get_cpu_features; +- } +-} +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-defines.sym +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/ifunc-defines.sym ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-defines.sym +@@ -4,7 +4,6 @@ + -- + + CPU_FEATURES_SIZE sizeof (struct cpu_features) +-KIND_OFFSET offsetof (struct cpu_features, kind) + CPUID_OFFSET offsetof (struct cpu_features, cpuid) + CPUID_SIZE sizeof (struct cpuid_registers) + CPUID_EAX_OFFSET offsetof (struct cpuid_registers, eax) +Index: glibc-2.17-c758a686/sysdeps/i386/ldsodefs.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/ldsodefs.h ++++ glibc-2.17-c758a686/sysdeps/i386/ldsodefs.h +@@ -20,6 +20,7 @@ + #define _I386_LDSODEFS_H 1 + + #include ++#include + + struct La_i86_regs; + struct La_i86_retval; +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c +@@ -1,5 +1,5 @@ + #if IS_IN (ldconfig) + # include + #else +-# include ++# include + #endif +Index: glibc-2.17-c758a686/sysdeps/x86/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/Makefile ++++ glibc-2.17-c758a686/sysdeps/x86/Makefile +@@ -7,3 +7,14 @@ $(objpfx)tst-xmmymmzmm.out: ../sysdeps/x + @echo "Checking ld.so for SSE register use. This will take a few seconds..." + $(SHELL) $< $(objpfx) '$(NM)' '$(OBJDUMP)' '$(READELF)' > $@ + endif ++ ++ifeq ($(subdir),csu) ++gen-as-const-headers += cpu-features-offsets.sym rtld-global-offsets.sym ++endif ++ ++ifeq ($(subdir),elf) ++sysdep-dl-routines += dl-get-cpu-features ++ ++tests += tst-get-cpu-features ++tests-static += tst-get-cpu-features-static ++endif +Index: glibc-2.17-c758a686/sysdeps/x86/Versions +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/Versions +@@ -0,0 +1,5 @@ ++ld { ++ GLIBC_PRIVATE { ++ __get_cpu_features; ++ } ++} +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features-offsets.sym +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features-offsets.sym +@@ -0,0 +1,7 @@ ++#define SHARED 1 ++ ++#include ++ ++#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) ++ ++RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET rtld_global_ro_offsetof (_dl_x86_cpu_features) +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +@@ -0,0 +1,213 @@ ++/* Initialize CPU feature data. ++ This file is part of the GNU C Library. ++ Copyright (C) 2008-2015 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static inline void ++get_common_indeces (struct cpu_features *cpu_features, ++ unsigned int *family, unsigned int *model) ++{ ++ unsigned int eax; ++ __cpuid (1, eax, cpu_features->cpuid[COMMON_CPUID_INDEX_1].ebx, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_1].edx); ++ GLRO(dl_x86_cpu_features).cpuid[COMMON_CPUID_INDEX_1].eax = eax; ++ *family = (eax >> 8) & 0x0f; ++ *model = (eax >> 4) & 0x0f; ++} ++ ++static inline void ++init_cpu_features (struct cpu_features *cpu_features) ++{ ++ unsigned int ebx, ecx, edx; ++ unsigned int family = 0; ++ unsigned int model = 0; ++ enum cpu_features_kind kind; ++ ++ __cpuid (0, cpu_features->max_cpuid, ebx, ecx, edx); ++ ++ /* This spells out "GenuineIntel". */ ++ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) ++ { ++ kind = arch_kind_intel; ++ ++ get_common_indeces (cpu_features, &family, &model); ++ ++ /* Intel processors prefer SSE instruction for memory/string ++ routines if they are available. */ ++ cpu_features->feature[index_Prefer_SSE_for_memop] ++ |= bit_Prefer_SSE_for_memop; ++ ++ unsigned int eax = cpu_features->cpuid[COMMON_CPUID_INDEX_1].eax; ++ unsigned int extended_family = (eax >> 20) & 0xff; ++ unsigned int extended_model = (eax >> 12) & 0xf0; ++ if (family == 0x0f) ++ { ++ family += extended_family; ++ model += extended_model; ++ } ++ else if (family == 0x06) ++ { ++ ecx = cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx; ++ model += extended_model; ++ switch (model) ++ { ++ case 0x1c: ++ case 0x26: ++ /* BSF is slow on Atom. */ ++ cpu_features->feature[index_Slow_BSF] |= bit_Slow_BSF; ++ break; ++ ++ case 0x37: ++ case 0x4a: ++ case 0x4d: ++ case 0x5a: ++ case 0x5d: ++ /* Unaligned load versions are faster than SSSE3 ++ on Silvermont. */ ++#if index_Fast_Unaligned_Load != index_Prefer_PMINUB_for_stringop ++# error index_Fast_Unaligned_Load != index_Prefer_PMINUB_for_stringop ++#endif ++#if index_Fast_Unaligned_Load != index_Slow_SSE4_2 ++# error index_Fast_Unaligned_Load != index_Slow_SSE4_2 ++#endif ++ cpu_features->feature[index_Fast_Unaligned_Load] ++ |= (bit_Fast_Unaligned_Load ++ | bit_Prefer_PMINUB_for_stringop ++ | bit_Slow_SSE4_2); ++ break; ++ ++ default: ++ /* Unknown family 0x06 processors. Assuming this is one ++ of Core i3/i5/i7 processors if AVX is available. */ ++ if ((ecx & bit_AVX) == 0) ++ break; ++ ++ case 0x1a: ++ case 0x1e: ++ case 0x1f: ++ case 0x25: ++ case 0x2c: ++ case 0x2e: ++ case 0x2f: ++ /* Rep string instructions, copy backward, unaligned loads ++ and pminub are fast on Intel Core i3, i5 and i7. */ ++#if index_Fast_Rep_String != index_Fast_Copy_Backward ++# error index_Fast_Rep_String != index_Fast_Copy_Backward ++#endif ++#if index_Fast_Rep_String != index_Fast_Unaligned_Load ++# error index_Fast_Rep_String != index_Fast_Unaligned_Load ++#endif ++#if index_Fast_Rep_String != index_Prefer_PMINUB_for_stringop ++# error index_Fast_Rep_String != index_Prefer_PMINUB_for_stringop ++#endif ++ cpu_features->feature[index_Fast_Rep_String] ++ |= (bit_Fast_Rep_String ++ | bit_Fast_Copy_Backward ++ | bit_Fast_Unaligned_Load ++ | bit_Prefer_PMINUB_for_stringop); ++ break; ++ } ++ } ++ } ++ /* This spells out "AuthenticAMD". */ ++ else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) ++ { ++ kind = arch_kind_amd; ++ ++ get_common_indeces (cpu_features, &family, &model); ++ ++ ecx = cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx; ++ ++ /* AMD processors prefer SSE instructions for memory/string routines ++ if they are available, otherwise they prefer integer instructions. */ ++ if ((ecx & 0x200)) ++ cpu_features->feature[index_Prefer_SSE_for_memop] ++ |= bit_Prefer_SSE_for_memop; ++ ++ unsigned int eax; ++ __cpuid (0x80000000, eax, ebx, ecx, edx); ++ if (eax >= 0x80000001) ++ __cpuid (0x80000001, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].eax, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].ebx, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].ecx, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_80000001].edx); ++ } ++ else ++ kind = arch_kind_other; ++ ++ if (cpu_features->max_cpuid >= 7) ++ __cpuid_count (7, 0, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_7].eax, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_7].ecx, ++ cpu_features->cpuid[COMMON_CPUID_INDEX_7].edx); ++ ++ /* Can we call xgetbv? */ ++ if (HAS_CPU_FEATURE (OSXSAVE)) ++ { ++ unsigned int xcrlow; ++ unsigned int xcrhigh; ++ asm ("xgetbv" : "=a" (xcrlow), "=d" (xcrhigh) : "c" (0)); ++ /* Is YMM and XMM state usable? */ ++ if ((xcrlow & (bit_YMM_state | bit_XMM_state)) == ++ (bit_YMM_state | bit_XMM_state)) ++ { ++ /* Determine if AVX is usable. */ ++ if (HAS_CPU_FEATURE (AVX)) ++ cpu_features->feature[index_AVX_Usable] |= bit_AVX_Usable; ++#if index_AVX2_Usable != index_AVX_Fast_Unaligned_Load ++# error index_AVX2_Usable != index_AVX_Fast_Unaligned_Load ++#endif ++ /* Determine if AVX2 is usable. Unaligned load with 256-bit ++ AVX registers are faster on processors with AVX2. */ ++ if (HAS_CPU_FEATURE (AVX2)) ++ cpu_features->feature[index_AVX2_Usable] ++ |= bit_AVX2_Usable | bit_AVX_Fast_Unaligned_Load; ++ /* Check if OPMASK state, upper 256-bit of ZMM0-ZMM15 and ++ ZMM16-ZMM31 state are enabled. */ ++ if ((xcrlow & (bit_Opmask_state | bit_ZMM0_15_state ++ | bit_ZMM16_31_state)) == ++ (bit_Opmask_state | bit_ZMM0_15_state | bit_ZMM16_31_state)) ++ { ++ /* Determine if AVX512F is usable. */ ++ if (HAS_CPU_FEATURE (AVX512F)) ++ { ++ cpu_features->feature[index_AVX512F_Usable] ++ |= bit_AVX512F_Usable; ++ /* Determine if AVX512DQ is usable. */ ++ if (HAS_CPU_FEATURE (AVX512DQ)) ++ cpu_features->feature[index_AVX512DQ_Usable] ++ |= bit_AVX512DQ_Usable; ++ } ++ } ++ /* Determine if FMA is usable. */ ++ if (HAS_CPU_FEATURE (FMA)) ++ cpu_features->feature[index_FMA_Usable] |= bit_FMA_Usable; ++ /* Determine if FMA4 is usable. */ ++ if (HAS_CPU_FEATURE (FMA4)) ++ cpu_features->feature[index_FMA4_Usable] |= bit_FMA4_Usable; ++ } ++ } ++ ++ cpu_features->family = family; ++ cpu_features->model = model; ++ cpu_features->kind = kind; ++} +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +@@ -0,0 +1,273 @@ ++/* This file is part of the GNU C Library. ++ Copyright (C) 2008-2015 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef cpu_features_h ++#define cpu_features_h ++ ++#define bit_Fast_Rep_String (1 << 0) ++#define bit_Fast_Copy_Backward (1 << 1) ++#define bit_Slow_BSF (1 << 2) ++#define bit_Prefer_SSE_for_memop (1 << 3) ++#define bit_Fast_Unaligned_Load (1 << 4) ++#define bit_Prefer_PMINUB_for_stringop (1 << 5) ++#define bit_AVX_Usable (1 << 6) ++#define bit_FMA_Usable (1 << 7) ++#define bit_FMA4_Usable (1 << 8) ++#define bit_Slow_SSE4_2 (1 << 9) ++#define bit_AVX2_Usable (1 << 10) ++#define bit_AVX_Fast_Unaligned_Load (1 << 11) ++#define bit_AVX512F_Usable (1 << 12) ++#define bit_AVX512DQ_Usable (1 << 13) ++ ++/* CPUID Feature flags. */ ++ ++/* COMMON_CPUID_INDEX_1. */ ++#define bit_SSE2 (1 << 26) ++#define bit_SSSE3 (1 << 9) ++#define bit_SSE4_1 (1 << 19) ++#define bit_SSE4_2 (1 << 20) ++#define bit_OSXSAVE (1 << 27) ++#define bit_AVX (1 << 28) ++#define bit_POPCOUNT (1 << 23) ++#define bit_FMA (1 << 12) ++#define bit_FMA4 (1 << 16) ++ ++/* COMMON_CPUID_INDEX_7. */ ++#define bit_RTM (1 << 11) ++#define bit_AVX2 (1 << 5) ++#define bit_AVX512F (1 << 16) ++#define bit_AVX512DQ (1 << 17) ++ ++/* XCR0 Feature flags. */ ++#define bit_XMM_state (1 << 1) ++#define bit_YMM_state (2 << 1) ++#define bit_Opmask_state (1 << 5) ++#define bit_ZMM0_15_state (1 << 6) ++#define bit_ZMM16_31_state (1 << 7) ++ ++/* The integer bit array index for the first set of internal feature bits. */ ++#define FEATURE_INDEX_1 0 ++ ++/* The current maximum size of the feature integer bit array. */ ++#define FEATURE_INDEX_MAX 1 ++ ++#ifdef __ASSEMBLER__ ++ ++# include ++# include ++ ++# define index_SSE2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET ++# define index_SSSE3 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET ++# define index_SSE4_1 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET ++# define index_SSE4_2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET ++# define index_AVX COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET ++# define index_AVX2 COMMON_CPUID_INDEX_7*CPUID_SIZE+CPUID_EBX_OFFSET ++ ++# define index_Fast_Rep_String FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Fast_Copy_Backward FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Slow_BSF FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Prefer_SSE_for_memop FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1*FEATURE_SIZE ++# define index_AVX_Usable FEATURE_INDEX_1*FEATURE_SIZE ++# define index_FMA_Usable FEATURE_INDEX_1*FEATURE_SIZE ++# define index_FMA4_Usable FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Slow_SSE4_2 FEATURE_INDEX_1*FEATURE_SIZE ++# define index_AVX2_Usable FEATURE_INDEX_1*FEATURE_SIZE ++# define index_AVX_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE ++# define index_AVX512F_Usable FEATURE_INDEX_1*FEATURE_SIZE ++# define index_AVX512DQ_Usable FEATURE_INDEX_1*FEATURE_SIZE ++ ++# if defined (_LIBC) && !IS_IN (nonlib) ++# ifdef __x86_64__ ++# ifdef SHARED ++# if IS_IN (rtld) ++# define LOAD_RTLD_GLOBAL_RO_RDX ++# define HAS_FEATURE(offset, name) \ ++ testl $(bit_##name), _rtld_local_ro+offset+(index_##name)(%rip) ++# else ++# define LOAD_RTLD_GLOBAL_RO_RDX \ ++ mov _rtld_global_ro@GOTPCREL(%rip), %RDX_LP ++# define HAS_FEATURE(offset, name) \ ++ testl $(bit_##name), \ ++ RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+offset+(index_##name)(%rdx) ++# endif ++# else /* SHARED */ ++# define LOAD_RTLD_GLOBAL_RO_RDX ++# define HAS_FEATURE(offset, name) \ ++ testl $(bit_##name), _dl_x86_cpu_features+offset+(index_##name)(%rip) ++# endif /* !SHARED */ ++# else /* __x86_64__ */ ++# ifdef SHARED ++# define LOAD_FUNC_GOT_EAX(func) \ ++ leal func@GOTOFF(%edx), %eax ++# if IS_IN (rtld) ++# define LOAD_GOT_AND_RTLD_GLOBAL_RO \ ++ LOAD_PIC_REG(dx) ++# define HAS_FEATURE(offset, name) \ ++ testl $(bit_##name), offset+(index_##name)+_rtld_local_ro@GOTOFF(%edx) ++# else ++# define LOAD_GOT_AND_RTLD_GLOBAL_RO \ ++ LOAD_PIC_REG(dx); \ ++ mov _rtld_global_ro@GOT(%edx), %ecx ++# define HAS_FEATURE(offset, name) \ ++ testl $(bit_##name), \ ++ RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+offset+(index_##name)(%ecx) ++# endif ++# else /* SHARED */ ++# define LOAD_FUNC_GOT_EAX(func) \ ++ leal func, %eax ++# define LOAD_GOT_AND_RTLD_GLOBAL_RO ++# define HAS_FEATURE(offset, name) \ ++ testl $(bit_##name), _dl_x86_cpu_features+offset+(index_##name) ++# endif /* !SHARED */ ++# endif /* !__x86_64__ */ ++# else /* _LIBC && !nonlib */ ++# error "Sorry, is unimplemented for assembler" ++# endif /* !_LIBC || nonlib */ ++ ++/* HAS_* evaluates to true if we may use the feature at runtime. */ ++# define HAS_CPU_FEATURE(name) HAS_FEATURE (CPUID_OFFSET, name) ++# define HAS_ARCH_FEATURE(name) HAS_FEATURE (FEATURE_OFFSET, name) ++ ++#else /* __ASSEMBLER__ */ ++ ++# include ++# include ++# include ++# include ++ ++/* Ugly hack to make it possible to select a strstr and strcasestr ++ implementation that avoids using the stack for 16-byte aligned ++ SSE temporaries. Doing so makes it possible to call the functions ++ with a stack that's not 16-byte aligned as can happen, for example, ++ as a result of compiling the functions' callers with the GCC ++ -mpreferred-stack-boubdary=2 or =3 option, or with the ICC ++ -falign-stack=assume-4-byte option. See rhbz 1150282 for details. ++ ++ The ifunc selector uses the unaligned version by default if this ++ file exists and is accessible. */ ++# define ENABLE_STRSTR_UNALIGNED_PATHNAME \ ++ "/etc/sysconfig/64bit_strstr_via_64bit_strstr_sse2_unaligned" ++ ++static bool __attribute__ ((unused)) ++use_unaligned_strstr (void) ++{ ++ struct stat unaligned_strstr_etc_sysconfig_file; ++ ++ /* TLS may not have been set up yet, so avoid using stat since it tries to ++ set errno. */ ++ return INTERNAL_SYSCALL (stat, , 2, ++ ENABLE_STRSTR_UNALIGNED_PATHNAME, ++ &unaligned_strstr_etc_sysconfig_file) == 0; ++} ++ ++enum ++ { ++ COMMON_CPUID_INDEX_1 = 0, ++ COMMON_CPUID_INDEX_7, ++ COMMON_CPUID_INDEX_80000001, /* for AMD */ ++ /* Keep the following line at the end. */ ++ COMMON_CPUID_INDEX_MAX ++ }; ++ ++struct cpu_features ++{ ++ enum cpu_features_kind ++ { ++ arch_kind_unknown = 0, ++ arch_kind_intel, ++ arch_kind_amd, ++ arch_kind_other ++ } kind; ++ int max_cpuid; ++ struct cpuid_registers ++ { ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ } cpuid[COMMON_CPUID_INDEX_MAX]; ++ unsigned int family; ++ unsigned int model; ++ unsigned int feature[FEATURE_INDEX_MAX]; ++}; ++ ++/* Used from outside of glibc to get access to the CPU features ++ structure. */ ++extern const struct cpu_features *__get_cpu_features (void) ++ __attribute__ ((const)); ++ ++# if defined (_LIBC) && !IS_IN (nonlib) ++/* Unused for x86. */ ++# define INIT_ARCH() ++# define __get_cpu_features() (&GLRO(dl_x86_cpu_features)) ++# endif ++ ++ ++/* HAS_* evaluates to true if we may use the feature at runtime. */ ++# define HAS_CPU_FEATURE(name) \ ++ ((__get_cpu_features ()->cpuid[index_##name].reg_##name & (bit_##name)) != 0) ++# define HAS_ARCH_FEATURE(name) \ ++ ((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0) ++ ++# define index_SSE2 COMMON_CPUID_INDEX_1 ++# define index_SSSE3 COMMON_CPUID_INDEX_1 ++# define index_SSE4_1 COMMON_CPUID_INDEX_1 ++# define index_SSE4_2 COMMON_CPUID_INDEX_1 ++# define index_AVX COMMON_CPUID_INDEX_1 ++# define index_AVX2 COMMON_CPUID_INDEX_7 ++# define index_AVX512F COMMON_CPUID_INDEX_7 ++# define index_AVX512DQ COMMON_CPUID_INDEX_7 ++# define index_RTM COMMON_CPUID_INDEX_7 ++# define index_FMA COMMON_CPUID_INDEX_1 ++# define index_FMA4 COMMON_CPUID_INDEX_80000001 ++# define index_POPCOUNT COMMON_CPUID_INDEX_1 ++# define index_OSXSAVE COMMON_CPUID_INDEX_1 ++ ++# define reg_SSE2 edx ++# define reg_SSSE3 ecx ++# define reg_SSE4_1 ecx ++# define reg_SSE4_2 ecx ++# define reg_AVX ecx ++# define reg_AVX2 ebx ++# define reg_AVX512F ebx ++# define reg_AVX512DQ ebx ++# define reg_RTM ebx ++# define reg_FMA ecx ++# define reg_FMA4 ecx ++# define reg_POPCOUNT ecx ++# define reg_OSXSAVE ecx ++ ++# define index_Fast_Rep_String FEATURE_INDEX_1 ++# define index_Fast_Copy_Backward FEATURE_INDEX_1 ++# define index_Slow_BSF FEATURE_INDEX_1 ++# define index_Prefer_SSE_for_memop FEATURE_INDEX_1 ++# define index_Fast_Unaligned_Load FEATURE_INDEX_1 ++# define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1 ++# define index_AVX_Usable FEATURE_INDEX_1 ++# define index_FMA_Usable FEATURE_INDEX_1 ++# define index_FMA4_Usable FEATURE_INDEX_1 ++# define index_Slow_SSE4_2 FEATURE_INDEX_1 ++# define index_AVX2_Usable FEATURE_INDEX_1 ++# define index_AVX_Fast_Unaligned_Load FEATURE_INDEX_1 ++# define index_AVX512F_Usable FEATURE_INDEX_1 ++# define index_AVX512DQ_Usable FEATURE_INDEX_1 ++ ++#endif /* !__ASSEMBLER__ */ ++ ++#endif /* cpu_features_h */ +Index: glibc-2.17-c758a686/sysdeps/x86/dl-get-cpu-features.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/dl-get-cpu-features.c +@@ -0,0 +1,27 @@ ++/* This file is part of the GNU C Library. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include ++ ++#undef __get_cpu_features ++ ++const struct cpu_features * ++__get_cpu_features (void) ++{ ++ return &GLRO(dl_x86_cpu_features); ++} +Index: glibc-2.17-c758a686/sysdeps/x86/libc-start.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/libc-start.c +@@ -0,0 +1,41 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef SHARED ++# include ++# else ++/* The main work is done in the generic function. */ ++# define LIBC_START_DISABLE_INLINE ++# define LIBC_START_MAIN generic_start_main ++# include ++# include ++# include ++ ++extern struct cpu_features _dl_x86_cpu_features; ++ ++int ++__libc_start_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), ++ int argc, char **argv, ++ __typeof (main) init, ++ void (*fini) (void), ++ void (*rtld_fini) (void), void *stack_end) ++{ ++ init_cpu_features (&_dl_x86_cpu_features); ++ return generic_start_main (main, argc, argv, init, fini, rtld_fini, ++ stack_end); ++} ++#endif +Index: glibc-2.17-c758a686/sysdeps/x86/rtld-global-offsets.sym +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/rtld-global-offsets.sym +@@ -0,0 +1,7 @@ ++#define SHARED 1 ++ ++#include ++ ++#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) ++ ++RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET rtld_global_ro_offsetof (_dl_x86_cpu_features) +Index: glibc-2.17-c758a686/sysdeps/x86/tst-get-cpu-features-static.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/tst-get-cpu-features-static.c +@@ -0,0 +1 @@ ++#include "tst-get-cpu-features.c" +Index: glibc-2.17-c758a686/sysdeps/x86/tst-get-cpu-features.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86/tst-get-cpu-features.c +@@ -0,0 +1,31 @@ ++/* Test case for x86 __get_cpu_features interface ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ if (__get_cpu_features ()->kind == arch_kind_unknown) ++ abort (); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +Index: glibc-2.17-c758a686/sysdeps/x86_64/cacheinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/cacheinfo.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/cacheinfo.c +@@ -21,40 +21,11 @@ + #include + #include + #include ++#include "multiarch/init-arch.h" + +-#ifndef __cpuid_count +-/* FIXME: Provide __cpuid_count if it isn't defined. Copied from gcc +- 4.4.0. Remove this if gcc 4.4 is the minimum requirement. */ +-# if defined(__i386__) && defined(__PIC__) +-/* %ebx may be the PIC register. */ +-# define __cpuid_count(level, count, a, b, c, d) \ +- __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ +- "cpuid\n\t" \ +- "xchg{l}\t{%%}ebx, %1\n\t" \ +- : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ +- : "0" (level), "2" (count)) +-# else +-# define __cpuid_count(level, count, a, b, c, d) \ +- __asm__ ("cpuid\n\t" \ +- : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ +- : "0" (level), "2" (count)) +-# endif +-#endif +- +-#ifdef USE_MULTIARCH +-# include "multiarch/init-arch.h" +- +-# define is_intel __cpu_features.kind == arch_kind_intel +-# define is_amd __cpu_features.kind == arch_kind_amd +-# define max_cpuid __cpu_features.max_cpuid +-#else +- /* This spells out "GenuineIntel". */ +-# define is_intel \ +- ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69 +- /* This spells out "AuthenticAMD". */ +-# define is_amd \ +- ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65 +-#endif ++#define is_intel GLRO(dl_x86_cpu_features).kind == arch_kind_intel ++#define is_amd GLRO(dl_x86_cpu_features).kind == arch_kind_amd ++#define max_cpuid GLRO(dl_x86_cpu_features).max_cpuid + + static const struct intel_02_cache_info + { +@@ -237,21 +208,8 @@ intel_check_word (int name, unsigned int + /* Intel reused this value. For family 15, model 6 it + specifies the 3rd level cache. Otherwise the 2nd + level cache. */ +- unsigned int family; +- unsigned int model; +-#ifdef USE_MULTIARCH +- family = __cpu_features.family; +- model = __cpu_features.model; +-#else +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- __cpuid (1, eax, ebx, ecx, edx); +- +- family = ((eax >> 20) & 0xff) + ((eax >> 8) & 0xf); +- model = (((eax >>16) & 0xf) << 4) + ((eax >> 4) & 0xf); +-#endif ++ unsigned int family = GLRO(dl_x86_cpu_features).family; ++ unsigned int model = GLRO(dl_x86_cpu_features).model; + + if (family == 15 && model == 6) + { +@@ -478,18 +436,6 @@ long int + attribute_hidden + __cache_sysconf (int name) + { +-#ifdef USE_MULTIARCH +- if (__cpu_features.kind == arch_kind_unknown) +- __init_cpu_features (); +-#else +- /* Find out what brand of processor. */ +- unsigned int max_cpuid; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- __cpuid (0, max_cpuid, ebx, ecx, edx); +-#endif +- + if (is_intel) + return handle_intel (name, max_cpuid); + +@@ -525,18 +471,6 @@ long int __x86_64_raw_shared_cache_size + int __x86_64_prefetchw attribute_hidden; + #endif + +-#ifndef DISABLE_PREFERRED_MEMORY_INSTRUCTION +-/* Instructions preferred for memory and string routines. +- +- 0: Regular instructions +- 1: MMX instructions +- 2: SSE2 instructions +- 3: SSSE3 instructions +- +- */ +-int __x86_64_preferred_memory_instruction attribute_hidden; +-#endif +- + + static void + __attribute__((constructor)) +@@ -553,14 +487,6 @@ init_cacheinfo (void) + unsigned int level; + unsigned int threads = 0; + +-#ifdef USE_MULTIARCH +- if (__cpu_features.kind == arch_kind_unknown) +- __init_cpu_features (); +-#else +- int max_cpuid; +- __cpuid (0, max_cpuid, ebx, ecx, edx); +-#endif +- + if (is_intel) + { + data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid); +@@ -576,34 +502,13 @@ init_cacheinfo (void) + shared = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid); + } + +- unsigned int ebx_1; +- +-#ifdef USE_MULTIARCH +- eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; +- ebx_1 = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx; +- ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx; +- edx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx; +-#else +- __cpuid (1, eax, ebx_1, ecx, edx); +-#endif +- +- unsigned int family = (eax >> 8) & 0x0f; +- unsigned int model = (eax >> 4) & 0x0f; +- unsigned int extended_model = (eax >> 12) & 0xf0; +- +-#ifndef DISABLE_PREFERRED_MEMORY_INSTRUCTION +- /* Intel prefers SSSE3 instructions for memory/string routines +- if they are available. */ +- if ((ecx & 0x200)) +- __x86_64_preferred_memory_instruction = 3; +- else +- __x86_64_preferred_memory_instruction = 2; +-#endif +- + /* Figure out the number of logical threads that share the + highest cache level. */ + if (max_cpuid >= 4) + { ++ unsigned int family = GLRO(dl_x86_cpu_features).family; ++ unsigned int model = GLRO(dl_x86_cpu_features).model; ++ + int i = 0; + + /* Query until desired cache level is enumerated. */ +@@ -655,7 +560,6 @@ init_cacheinfo (void) + threads += 1; + if (threads > 2 && level == 2 && family == 6) + { +- model += extended_model; + switch (model) + { + case 0x57: +@@ -678,7 +582,9 @@ init_cacheinfo (void) + intel_bug_no_cache_info: + /* Assume that all logical threads share the highest cache level. */ + +- threads = (ebx_1 >> 16) & 0xff; ++ threads ++ = ((GLRO(dl_x86_cpu_features).cpuid[COMMON_CPUID_INDEX_1].ebx ++ >> 16) & 0xff); + } + + /* Cap usage of highest cache level to the number of supported +@@ -693,25 +599,6 @@ init_cacheinfo (void) + long int core = handle_amd (_SC_LEVEL2_CACHE_SIZE); + shared = handle_amd (_SC_LEVEL3_CACHE_SIZE); + +-#ifndef DISABLE_PREFERRED_MEMORY_INSTRUCTION +-# ifdef USE_MULTIARCH +- eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; +- ebx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx; +- ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx; +- edx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx; +-# else +- __cpuid (1, eax, ebx, ecx, edx); +-# endif +- +- /* AMD prefers SSSE3 instructions for memory/string routines +- if they are avaiable, otherwise it prefers integer +- instructions. */ +- if ((ecx & 0x200)) +- __x86_64_preferred_memory_instruction = 3; +- else +- __x86_64_preferred_memory_instruction = 0; +-#endif +- + /* Get maximum extended function. */ + __cpuid (0x80000000, max_cpuid_ex, ebx, ecx, edx); + +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-machine.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-machine.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-machine.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + /* Return nonzero iff ELF header is compatible with the running host. */ + static inline int __attribute__ ((unused)) +@@ -200,6 +201,8 @@ dl_platform_init (void) + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') + /* Avoid an empty string which would disturb us. */ + GLRO(dl_platform) = NULL; ++ ++ init_cpu_features (&GLRO(dl_x86_cpu_features)); + } + + static inline ElfW(Addr) +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-procinfo.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-procinfo.c +@@ -0,0 +1,57 @@ ++/* Data for x86-64 version of processor capability information. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* If anything should be added here check whether the size of each string ++ is still ok with the given array size. ++ ++ All the #ifdefs in the definitions are quite irritating but ++ necessary if we want to avoid duplicating the information. There ++ are three different modes: ++ ++ - PROCINFO_DECL is defined. This means we are only interested in ++ declarations. ++ ++ - PROCINFO_DECL is not defined: ++ ++ + if SHARED is defined the file is included in an array ++ initializer. The .element = { ... } syntax is needed. ++ ++ + if SHARED is not defined a normal array initialization is ++ needed. ++ */ ++ ++#ifndef PROCINFO_CLASS ++# define PROCINFO_CLASS ++#endif ++ ++#if !defined PROCINFO_DECL && defined SHARED ++ ._dl_x86_cpu_features ++#else ++PROCINFO_CLASS struct cpu_features _dl_x86_cpu_features ++#endif ++#ifndef PROCINFO_DECL ++= { } ++#endif ++#if !defined SHARED || defined PROCINFO_DECL ++; ++#else ++, ++#endif ++ ++#undef PROCINFO_DECL ++#undef PROCINFO_CLASS +Index: glibc-2.17-c758a686/sysdeps/x86_64/ldsodefs.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/ldsodefs.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/ldsodefs.h +@@ -20,6 +20,7 @@ + #define _X86_64_LDSODEFS_H 1 + + #include ++#include + + struct La_x86_64_regs; + struct La_x86_64_retval; +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile +@@ -1,5 +1,4 @@ + ifeq ($(subdir),csu) +-aux += init-arch + tests += test-multiarch + gen-as-const-headers += ifunc-defines.sym + endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Versions +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/Versions ++++ /dev/null +@@ -1,5 +0,0 @@ +-libc { +- GLIBC_PRIVATE { +- __get_cpu_features; +- } +-} +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/cacheinfo.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/cacheinfo.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define DISABLE_PREFERRED_MEMORY_INSTRUCTION +-#include "../cacheinfo.c" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-defines.sym +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/ifunc-defines.sym ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-defines.sym +@@ -4,7 +4,6 @@ + -- + + CPU_FEATURES_SIZE sizeof (struct cpu_features) +-KIND_OFFSET offsetof (struct cpu_features, kind) + CPUID_OFFSET offsetof (struct cpu_features, cpuid) + CPUID_SIZE sizeof (struct cpuid_registers) + CPUID_EAX_OFFSET offsetof (struct cpuid_registers, eax) +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/init-arch.c ++++ /dev/null +@@ -1,183 +0,0 @@ +-/* Initialize CPU feature data. +- This file is part of the GNU C Library. +- Copyright (C) 2008-2012 Free Software Foundation, Inc. +- Contributed by Ulrich Drepper . +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include "init-arch.h" +- +- +-struct cpu_features __cpu_features attribute_hidden; +- +- +-static void +-get_common_indeces (unsigned int *family, unsigned int *model) +-{ +- __cpuid (1, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx); +- +- unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; +- *family = (eax >> 8) & 0x0f; +- *model = (eax >> 4) & 0x0f; +-} +- +- +-void +-__init_cpu_features (void) +-{ +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- unsigned int family = 0; +- unsigned int model = 0; +- enum cpu_features_kind kind; +- +- __cpuid (0, __cpu_features.max_cpuid, ebx, ecx, edx); +- +- /* This spells out "GenuineIntel". */ +- if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) +- { +- kind = arch_kind_intel; +- +- get_common_indeces (&family, &model); +- +- /* Intel processors prefer SSE instruction for memory/string +- routines if they are available. */ +- __cpu_features.feature[index_Prefer_SSE_for_memop] +- |= bit_Prefer_SSE_for_memop; +- +- unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; +- unsigned int extended_family = (eax >> 20) & 0xff; +- unsigned int extended_model = (eax >> 12) & 0xf0; +- if (family == 0x0f) +- { +- family += extended_family; +- model += extended_model; +- } +- else if (family == 0x06) +- { +- ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx; +- model += extended_model; +- switch (model) +- { +- case 0x1c: +- case 0x26: +- /* BSF is slow on Atom. */ +- __cpu_features.feature[index_Slow_BSF] |= bit_Slow_BSF; +- break; +- +- default: +- /* Unknown family 0x06 processors. Assuming this is one +- of Core i3/i5/i7 processors if AVX is available. */ +- if ((ecx & bit_AVX) == 0) +- break; +- +- case 0x1a: +- case 0x1e: +- case 0x1f: +- case 0x25: +- case 0x2c: +- case 0x2e: +- case 0x2f: +- /* Rep string instructions, copy backward, unaligned loads +- and pminub are fast on Intel Core i3, i5 and i7. */ +-#if index_Fast_Rep_String != index_Fast_Copy_Backward +-# error index_Fast_Rep_String != index_Fast_Copy_Backward +-#endif +-#if index_Fast_Rep_String != index_Fast_Unaligned_Load +-# error index_Fast_Rep_String != index_Fast_Unaligned_Load +-#endif +-#if index_Fast_Rep_String != index_Prefer_PMINUB_for_stringop +-# error index_Fast_Rep_String != index_Prefer_PMINUB_for_stringop +-#endif +- __cpu_features.feature[index_Fast_Rep_String] +- |= (bit_Fast_Rep_String +- | bit_Fast_Copy_Backward +- | bit_Fast_Unaligned_Load +- | bit_Prefer_PMINUB_for_stringop); +- break; +- } +- } +- } +- /* This spells out "AuthenticAMD". */ +- else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) +- { +- kind = arch_kind_amd; +- +- get_common_indeces (&family, &model); +- +- ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx; +- +- /* AMD processors prefer SSE instructions for memory/string routines +- if they are available, otherwise they prefer integer instructions. */ +- if ((ecx & 0x200)) +- __cpu_features.feature[index_Prefer_SSE_for_memop] +- |= bit_Prefer_SSE_for_memop; +- +- unsigned int eax; +- __cpuid (0x80000000, eax, ebx, ecx, edx); +- if (eax >= 0x80000001) +- __cpuid (0x80000001, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_80000001].eax, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_80000001].ebx, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_80000001].ecx, +- __cpu_features.cpuid[COMMON_CPUID_INDEX_80000001].edx); +- } +- else +- kind = arch_kind_other; +- +- /* Can we call xgetbv? */ +- if (CPUID_OSXSAVE) +- { +- unsigned int xcrlow; +- unsigned int xcrhigh; +- asm ("xgetbv" : "=a" (xcrlow), "=d" (xcrhigh) : "c" (0)); +- /* Is YMM and XMM state usable? */ +- if ((xcrlow & (bit_YMM_state | bit_XMM_state)) == +- (bit_YMM_state | bit_XMM_state)) +- { +- /* Determine if AVX is usable. */ +- if (CPUID_AVX) +- __cpu_features.feature[index_AVX_Usable] |= bit_AVX_Usable; +- /* Determine if FMA is usable. */ +- if (CPUID_FMA) +- __cpu_features.feature[index_FMA_Usable] |= bit_FMA_Usable; +- /* Determine if FMA4 is usable. */ +- if (CPUID_FMA4) +- __cpu_features.feature[index_FMA4_Usable] |= bit_FMA4_Usable; +- } +- } +- +- __cpu_features.family = family; +- __cpu_features.model = model; +- atomic_write_barrier (); +- __cpu_features.kind = kind; +-} +- +-#undef __get_cpu_features +- +-const struct cpu_features * +-__get_cpu_features (void) +-{ +- if (__cpu_features.kind == arch_kind_unknown) +- __init_cpu_features (); +- +- return &__cpu_features; +-} +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/init-arch.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/init-arch.h +@@ -15,183 +15,8 @@ + License along with the GNU C Library; if not, see + . */ + +-#define bit_Fast_Rep_String (1 << 0) +-#define bit_Fast_Copy_Backward (1 << 1) +-#define bit_Slow_BSF (1 << 2) +-#define bit_Prefer_SSE_for_memop (1 << 3) +-#define bit_Fast_Unaligned_Load (1 << 4) +-#define bit_Prefer_PMINUB_for_stringop (1 << 5) +-#define bit_AVX_Usable (1 << 6) +-#define bit_FMA_Usable (1 << 7) +-#define bit_FMA4_Usable (1 << 8) +- +-/* CPUID Feature flags. */ +-#define bit_SSE2 (1 << 26) +-#define bit_SSSE3 (1 << 9) +-#define bit_SSE4_1 (1 << 19) +-#define bit_SSE4_2 (1 << 20) +-#define bit_OSXSAVE (1 << 27) +-#define bit_AVX (1 << 28) +-#define bit_POPCOUNT (1 << 23) +-#define bit_FMA (1 << 12) +-#define bit_FMA4 (1 << 16) +- +-/* XCR0 Feature flags. */ +-#define bit_XMM_state (1 << 1) +-#define bit_YMM_state (2 << 1) +- +-#ifdef __ASSEMBLER__ +- +-# include +- +-# define index_SSE2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET +-# define index_SSSE3 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET +-# define index_SSE4_1 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET +-# define index_SSE4_2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET +-# define index_AVX COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET +- +-# define index_Fast_Rep_String FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Fast_Copy_Backward FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Slow_BSF FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Prefer_SSE_for_memop FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Prefer_PMINUB_for_stringop FEATURE_INDEX_1*FEATURE_SIZE +-# define index_AVX_Usable FEATURE_INDEX_1*FEATURE_SIZE +-# define index_FMA_Usable FEATURE_INDEX_1*FEATURE_SIZE +-# define index_FMA4_Usable FEATURE_INDEX_1*FEATURE_SIZE +- +-#else /* __ASSEMBLER__ */ +- +-# include +-# include +-# include +-# include +- +-/* Ugly hack to make it possible to select a strstr and strcasestr +- implementation that avoids using the stack for 16-byte aligned +- SSE temporaries. Doing so makes it possible to call the functions +- with a stack that's not 16-byte aligned as can happen, for example, +- as a result of compiling the functions' callers with the GCC +- -mpreferred-stack-boubdary=2 or =3 option, or with the ICC +- -falign-stack=assume-4-byte option. See rhbz 1150282 for details. +- +- The ifunc selector uses the unaligned version by default if this +- file exists and is accessible. */ +-# define ENABLE_STRSTR_UNALIGNED_PATHNAME \ +- "/etc/sysconfig/64bit_strstr_via_64bit_strstr_sse2_unaligned" +- +-static bool __attribute__ ((unused)) +-use_unaligned_strstr (void) +-{ +- struct stat unaligned_strstr_etc_sysconfig_file; +- +- /* TLS may not have been set up yet, so avoid using stat since it tries to +- set errno. */ +- return INTERNAL_SYSCALL (stat, , 2, +- ENABLE_STRSTR_UNALIGNED_PATHNAME, +- &unaligned_strstr_etc_sysconfig_file) == 0; +-} +- +-enum +- { +- COMMON_CPUID_INDEX_1 = 0, +- COMMON_CPUID_INDEX_80000001, /* for AMD */ +- /* Keep the following line at the end. */ +- COMMON_CPUID_INDEX_MAX +- }; +- +-enum +- { +- FEATURE_INDEX_1 = 0, +- /* Keep the following line at the end. */ +- FEATURE_INDEX_MAX +- }; +- +-extern struct cpu_features +-{ +- enum cpu_features_kind +- { +- arch_kind_unknown = 0, +- arch_kind_intel, +- arch_kind_amd, +- arch_kind_other +- } kind; +- int max_cpuid; +- struct cpuid_registers +- { +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- } cpuid[COMMON_CPUID_INDEX_MAX]; +- unsigned int family; +- unsigned int model; +- unsigned int feature[FEATURE_INDEX_MAX]; +-} __cpu_features attribute_hidden; +- +- +-extern void __init_cpu_features (void) attribute_hidden; +-# define INIT_ARCH() \ +- do \ +- if (__cpu_features.kind == arch_kind_unknown) \ +- __init_cpu_features (); \ +- while (0) +- +-/* Used from outside libc.so to get access to the CPU features structure. */ +-extern const struct cpu_features *__get_cpu_features (void) +- __attribute__ ((const)); +- +-# if IS_IN (libc) +-# define __get_cpu_features() (&__cpu_features) +-# endif +- +-# define HAS_CPU_FEATURE(idx, reg, bit) \ +- ((__get_cpu_features ()->cpuid[idx].reg & (bit)) != 0) +- +-/* Following are the feature tests used throughout libc. */ +- +-/* CPUID_* evaluates to true if the feature flag is enabled. +- We always use &__cpu_features because the HAS_CPUID_* macros +- are called only within __init_cpu_features, where we can't +- call __get_cpu_features without infinite recursion. */ +-# define HAS_CPUID_FLAG(idx, reg, bit) \ +- (((&__cpu_features)->cpuid[idx].reg & (bit)) != 0) +- +-# define CPUID_OSXSAVE \ +- HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_OSXSAVE) +-# define CPUID_AVX \ +- HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_AVX) +-# define CPUID_FMA \ +- HAS_CPUID_FLAG (COMMON_CPUID_INDEX_1, ecx, bit_FMA) +-# define CPUID_FMA4 \ +- HAS_CPUID_FLAG (COMMON_CPUID_INDEX_80000001, ecx, bit_FMA4) +- +-/* HAS_* evaluates to true if we may use the feature at runtime. */ +-# define HAS_SSE2 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, edx, bit_SSE2) +-# define HAS_POPCOUNT HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_POPCOUNT) +-# define HAS_SSSE3 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSSE3) +-# define HAS_SSE4_1 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_1) +-# define HAS_SSE4_2 HAS_CPU_FEATURE (COMMON_CPUID_INDEX_1, ecx, bit_SSE4_2) +- +-# define index_Fast_Rep_String FEATURE_INDEX_1 +-# define index_Fast_Copy_Backward FEATURE_INDEX_1 +-# define index_Slow_BSF FEATURE_INDEX_1 +-# define index_Prefer_SSE_for_memop FEATURE_INDEX_1 +-# define index_Fast_Unaligned_Load FEATURE_INDEX_1 +-# define index_AVX_Usable FEATURE_INDEX_1 +-# define index_FMA_Usable FEATURE_INDEX_1 +-# define index_FMA4_Usable FEATURE_INDEX_1 +- +-# define HAS_ARCH_FEATURE(name) \ +- ((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0) +- +-# define HAS_FAST_REP_STRING HAS_ARCH_FEATURE (Fast_Rep_String) +-# define HAS_FAST_COPY_BACKWARD HAS_ARCH_FEATURE (Fast_Copy_Backward) +-# define HAS_SLOW_BSF HAS_ARCH_FEATURE (Slow_BSF) +-# define HAS_PREFER_SSE_FOR_MEMOP HAS_ARCH_FEATURE (Prefer_SSE_for_memop) +-# define HAS_FAST_UNALIGNED_LOAD HAS_ARCH_FEATURE (Fast_Unaligned_Load) +-# define HAS_AVX HAS_ARCH_FEATURE (AVX_Usable) +-# define HAS_FMA HAS_ARCH_FEATURE (FMA_Usable) +-# define HAS_FMA4 HAS_ARCH_FEATURE (FMA4_Usable) +- +-#endif /* __ASSEMBLER__ */ ++#ifdef __ASSEMBLER__ ++# include ++#else ++# include ++#endif diff --git a/SOURCES/glibc-rh1292018-2.patch b/SOURCES/glibc-rh1292018-2.patch new file mode 100644 index 00000000..bc22259b --- /dev/null +++ b/SOURCES/glibc-rh1292018-2.patch @@ -0,0 +1,1251 @@ +We keep with the idea behind this patch but adjust all of the changes +to match the existing impelementations in RHEL 7.3. + +commit 0b5395f052ee09cd7e3d219af4e805c38058afb5 +Author: H.J. Lu +Date: Thu Aug 13 03:38:47 2015 -0700 + + Update x86_64 multiarch functions for + + This patch updates x86_64 multiarch functions to use the newly defined + HAS_CPU_FEATURE, HAS_ARCH_FEATURE and LOAD_RTLD_GLOBAL_RO_RDX from + . + +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_asin.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/e_asin.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_asin.c +@@ -8,11 +8,15 @@ extern double __ieee754_acos_fma4 (doubl + extern double __ieee754_asin_fma4 (double); + + libm_ifunc (__ieee754_acos, +- HAS_FMA4 ? __ieee754_acos_fma4 : __ieee754_acos_sse2); ++ HAS_ARCH_FEATURE (FMA4_Usable) ++ ? __ieee754_acos_fma4 ++ : __ieee754_acos_sse2); + strong_alias (__ieee754_acos, __acos_finite) + + libm_ifunc (__ieee754_asin, +- HAS_FMA4 ? __ieee754_asin_fma4 : __ieee754_asin_sse2); ++ HAS_ARCH_FEATURE (FMA4_Usable) ++ ? __ieee754_asin_fma4 ++ : __ieee754_asin_sse2); + strong_alias (__ieee754_asin, __asin_finite) + + # define __ieee754_acos __ieee754_acos_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_atan2.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/e_atan2.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_atan2.c +@@ -7,14 +7,15 @@ extern double __ieee754_atan2_avx (doubl + # ifdef HAVE_FMA4_SUPPORT + extern double __ieee754_atan2_fma4 (double, double); + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __ieee754_atan2_fma4 ((void *) 0) + # endif + + libm_ifunc (__ieee754_atan2, +- HAS_FMA4 ? __ieee754_atan2_fma4 +- : (HAS_AVX ? __ieee754_atan2_avx : __ieee754_atan2_sse2)); ++ HAS_ARCH_FEATURE (FMA4_Usable) ? __ieee754_atan2_fma4 ++ : (HAS_ARCH_FEATURE (AVX_Usable) ++ ? __ieee754_atan2_avx : __ieee754_atan2_sse2)); + strong_alias (__ieee754_atan2, __atan2_finite) + + # define __ieee754_atan2 __ieee754_atan2_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_exp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/e_exp.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_exp.c +@@ -7,14 +7,15 @@ extern double __ieee754_exp_avx (double) + # ifdef HAVE_FMA4_SUPPORT + extern double __ieee754_exp_fma4 (double); + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __ieee754_exp_fma4 ((void *) 0) + # endif + + libm_ifunc (__ieee754_exp, +- HAS_FMA4 ? __ieee754_exp_fma4 +- : (HAS_AVX ? __ieee754_exp_avx : __ieee754_exp_sse2)); ++ HAS_ARCH_FEATURE (FMA4_Usable) ? __ieee754_exp_fma4 ++ : (HAS_ARCH_FEATURE (AVX_Usable) ++ ? __ieee754_exp_avx : __ieee754_exp_sse2)); + strong_alias (__ieee754_exp, __exp_finite) + + # define __ieee754_exp __ieee754_exp_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_log.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/e_log.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_log.c +@@ -7,14 +7,15 @@ extern double __ieee754_log_avx (double) + # ifdef HAVE_FMA4_SUPPORT + extern double __ieee754_log_fma4 (double); + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __ieee754_log_fma4 ((void *) 0) + # endif + + libm_ifunc (__ieee754_log, +- HAS_FMA4 ? __ieee754_log_fma4 +- : (HAS_AVX ? __ieee754_log_avx : __ieee754_log_sse2)); ++ HAS_ARCH_FEATURE (FMA4_Usable) ? __ieee754_log_fma4 ++ : (HAS_ARCH_FEATURE (AVX_Usable) ++ ? __ieee754_log_avx : __ieee754_log_sse2)); + strong_alias (__ieee754_log, __log_finite) + + # define __ieee754_log __ieee754_log_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_pow.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/e_pow.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/e_pow.c +@@ -5,7 +5,10 @@ + extern double __ieee754_pow_sse2 (double, double); + extern double __ieee754_pow_fma4 (double, double); + +-libm_ifunc (__ieee754_pow, HAS_FMA4 ? __ieee754_pow_fma4 : __ieee754_pow_sse2); ++libm_ifunc (__ieee754_pow, ++ HAS_ARCH_FEATURE (FMA4_Usable) ++ ? __ieee754_pow_fma4 ++ : __ieee754_pow_sse2); + strong_alias (__ieee754_pow, __pow_finite) + + # define __ieee754_pow __ieee754_pow_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_atan.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_atan.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_atan.c +@@ -7,13 +7,14 @@ extern double __atan_avx (double); + # ifdef HAVE_FMA4_SUPPORT + extern double __atan_fma4 (double); + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __atan_fma4 ((void *) 0) + # endif + +-libm_ifunc (atan, (HAS_FMA4 ? __atan_fma4 : +- HAS_AVX ? __atan_avx : __atan_sse2)); ++libm_ifunc (atan, (HAS_ARCH_FEATURE (FMA4_Usable) ? __atan_fma4 : ++ HAS_ARCH_FEATURE (AVX_Usable) ++ ? __atan_avx : __atan_sse2)); + + # define atan __atan_sse2 + #endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_ceil.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_ceil.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_ceil.S +@@ -22,10 +22,9 @@ + + ENTRY(__ceil) + .type __ceil, @gnu_indirect_function +- call __get_cpu_features@plt +- movq %rax, %rdx ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq __ceil_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __ceil_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_ceilf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_ceilf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_ceilf.S +@@ -22,10 +22,9 @@ + + ENTRY(__ceilf) + .type __ceilf, @gnu_indirect_function +- call __get_cpu_features@plt +- movq %rax, %rdx ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq __ceilf_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __ceilf_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_floor.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_floor.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_floor.S +@@ -22,10 +22,9 @@ + + ENTRY(__floor) + .type __floor, @gnu_indirect_function +- call __get_cpu_features@plt +- movq %rax, %rdx ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq __floor_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __floor_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_floorf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_floorf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_floorf.S +@@ -22,10 +22,10 @@ + + ENTRY(__floorf) + .type __floorf, @gnu_indirect_function +- call __get_cpu_features@plt ++ LOAD_RTLD_GLOBAL_RO_RDX + movq %rax, %rdx + leaq __floorf_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __floorf_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_fma.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_fma.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_fma.c +@@ -42,14 +42,15 @@ __fma_fma4 (double x, double y, double z + return x; + } + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __fma_fma4 ((void *) 0) + # endif + + +-libm_ifunc (__fma, HAS_FMA +- ? __fma_fma3 : (HAS_FMA4 ? __fma_fma4 : __fma_sse2)); ++libm_ifunc (__fma, HAS_ARCH_FEATURE (FMA_Usable) ++ ? __fma_fma3 : (HAS_ARCH_FEATURE (FMA4_Usable) ++ ? __fma_fma4 : __fma_sse2)); + weak_alias (__fma, fma) + + # define __fma __fma_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_fmaf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_fmaf.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_fmaf.c +@@ -41,14 +41,15 @@ __fmaf_fma4 (float x, float y, float z) + return x; + } + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __fmaf_fma4 ((void *) 0) + # endif + + +-libm_ifunc (__fmaf, HAS_FMA +- ? __fmaf_fma3 : (HAS_FMA4 ? __fmaf_fma4 : __fmaf_sse2)); ++libm_ifunc (__fmaf, HAS_ARCH_FEATURE (FMA_Usable) ++ ? __fmaf_fma3 : (HAS_ARCH_FEATURE (FMA4_Usable) ++ ? __fmaf_fma4 : __fmaf_sse2)); + weak_alias (__fmaf, fmaf) + + # define __fmaf __fmaf_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S +@@ -22,10 +22,10 @@ + + ENTRY(__nearbyint) + .type __nearbyint, @gnu_indirect_function +- call __get_cpu_features@plt ++ LOAD_RTLD_GLOBAL_RO_RDX + movq %rax, %rdx + leaq __nearbyint_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __nearbyint_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_nearbyintf.S +@@ -22,10 +22,9 @@ + + ENTRY(__nearbyintf) + .type __nearbyintf, @gnu_indirect_function +- call __get_cpu_features@plt +- movq %rax, %rdx ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq __nearbyintf_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __nearbyintf_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_rint.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_rint.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_rint.S +@@ -22,10 +22,9 @@ + + ENTRY(__rint) + .type __rint, @gnu_indirect_function +- call __get_cpu_features@plt +- movq %rax, %rdx ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq __rint_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __rint_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_rintf.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_rintf.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_rintf.S +@@ -22,10 +22,9 @@ + + ENTRY(__rintf) + .type __rintf, @gnu_indirect_function +- call __get_cpu_features@plt +- movq %rax, %rdx ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq __rintf_sse41(%rip), %rax +- testl $bit_SSE4_1, CPUID_OFFSET+index_SSE4_1(%rdx) ++ HAS_CPU_FEATURE (SSE4_1) + jnz 2f + leaq __rintf_c(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_sin.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_sin.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_sin.c +@@ -11,18 +11,20 @@ extern double __sin_avx (double); + extern double __cos_fma4 (double); + extern double __sin_fma4 (double); + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __cos_fma4 ((void *) 0) + # define __sin_fma4 ((void *) 0) + # endif + +-libm_ifunc (__cos, (HAS_FMA4 ? __cos_fma4 : +- HAS_AVX ? __cos_avx : __cos_sse2)); ++libm_ifunc (__cos, (HAS_ARCH_FEATURE (FMA4_Usable) ? __cos_fma4 : ++ HAS_ARCH_FEATURE (AVX_Usable) ++ ? __cos_avx : __cos_sse2)); + weak_alias (__cos, cos) + +-libm_ifunc (__sin, (HAS_FMA4 ? __sin_fma4 : +- HAS_AVX ? __sin_avx : __sin_sse2)); ++libm_ifunc (__sin, (HAS_ARCH_FEATURE (FMA4_Usable) ? __sin_fma4 : ++ HAS_ARCH_FEATURE (AVX_Usable) ++ ? __sin_avx : __sin_sse2)); + weak_alias (__sin, sin) + + # define __cos __cos_sse2 +Index: glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_tan.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/fpu/multiarch/s_tan.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/fpu/multiarch/s_tan.c +@@ -7,13 +7,14 @@ extern double __tan_avx (double); + # ifdef HAVE_FMA4_SUPPORT + extern double __tan_fma4 (double); + # else +-# undef HAS_FMA4 +-# define HAS_FMA4 0 ++# undef HAS_ARCH_FEATURE ++# define HAS_ARCH_FEATURE(feature) 0 + # define __tan_fma4 ((void *) 0) + # endif + +-libm_ifunc (tan, (HAS_FMA4 ? __tan_fma4 : +- HAS_AVX ? __tan_avx : __tan_sse2)); ++libm_ifunc (tan, (HAS_ARCH_FEATURE (FMA4_Usable) ? __tan_fma4 : ++ HAS_ARCH_FEATURE (AVX_Usable) ++ ? __tan_avx : __tan_sse2)); + + # define tan __tan_sse2 + #endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -39,25 +39,26 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/memcmp.S. */ + IFUNC_IMPL (i, name, memcmp, +- IFUNC_IMPL_ADD (array, i, memcmp, HAS_SSE4_1, ++ IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_1), + __memcmp_sse4_1) +- IFUNC_IMPL_ADD (array, i, memcmp, HAS_SSSE3, __memcmp_ssse3) ++ IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3), ++ __memcmp_ssse3) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_sse2)) + + /* Support sysdeps/x86_64/multiarch/memmove_chk.S. */ + IFUNC_IMPL (i, name, __memmove_chk, +- IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3_back) +- IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __memmove_chk, 1, + __memmove_chk_sse2)) + + /* Support sysdeps/x86_64/multiarch/memmove.S. */ + IFUNC_IMPL (i, name, memmove, +- IFUNC_IMPL_ADD (array, i, memmove, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3_back) +- IFUNC_IMPL_ADD (array, i, memmove, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3) + IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_sse2)) + +@@ -74,13 +75,13 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/rawmemchr.S. */ + IFUNC_IMPL (i, name, rawmemchr, +- IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE4_2), + __rawmemchr_sse42) + IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_sse2)) + + /* Support sysdeps/x86_64/multiarch/stpncpy.S. */ + IFUNC_IMPL (i, name, stpncpy, +- IFUNC_IMPL_ADD (array, i, stpncpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3), + __stpncpy_ssse3) + IFUNC_IMPL_ADD (array, i, stpncpy, 1, + __stpncpy_sse2_unaligned) +@@ -88,92 +89,105 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/stpcpy.S. */ + IFUNC_IMPL (i, name, stpcpy, +- IFUNC_IMPL_ADD (array, i, stpcpy, HAS_SSSE3, __stpcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSSE3), ++ __stpcpy_ssse3) + IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcasecmp_l.S. */ + IFUNC_IMPL (i, name, strcasecmp, +- IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_AVX, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ HAS_ARCH_FEATURE (AVX_Usable), + __strcasecmp_avx) +- IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ HAS_CPU_FEATURE (SSE4_2), + __strcasecmp_sse42) +- IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ HAS_CPU_FEATURE (SSSE3), + __strcasecmp_ssse3) + IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcasecmp_l.S. */ + IFUNC_IMPL (i, name, strcasecmp_l, +- IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_AVX, ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, ++ HAS_ARCH_FEATURE (AVX_Usable), + __strcasecmp_l_avx) +- IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, ++ HAS_CPU_FEATURE (SSE4_2), + __strcasecmp_l_sse42) +- IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, ++ HAS_CPU_FEATURE (SSSE3), + __strcasecmp_l_ssse3) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, + __strcasecmp_l_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcasestr.c. */ + IFUNC_IMPL (i, name, strcasestr, +- IFUNC_IMPL_ADD (array, i, strcasestr, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcasestr, HAS_CPU_FEATURE (SSE4_2), + __strcasestr_sse42) + IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcat.S. */ + IFUNC_IMPL (i, name, strcat, +- IFUNC_IMPL_ADD (array, i, strcat, HAS_SSSE3, __strcat_ssse3) ++ IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3), ++ __strcat_ssse3) + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_sse2)) + + /* Support sysdeps/x86_64/multiarch/strchr.S. */ + IFUNC_IMPL (i, name, strchr, +- IFUNC_IMPL_ADD (array, i, strchr, HAS_SSE4_2, __strchr_sse42) ++ IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE4_2), ++ __strchr_sse42) + IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_sse2_no_bsf) + IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcmp.S. */ + IFUNC_IMPL (i, name, strcmp, +- IFUNC_IMPL_ADD (array, i, strcmp, HAS_SSE4_2, __strcmp_sse42) +- IFUNC_IMPL_ADD (array, i, strcmp, HAS_SSSE3, __strcmp_ssse3) ++ IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSE4_2), ++ __strcmp_sse42) ++ IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3), ++ __strcmp_ssse3) + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcpy.S. */ + IFUNC_IMPL (i, name, strcpy, +- IFUNC_IMPL_ADD (array, i, strcpy, HAS_SSSE3, __strcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSSE3), ++ __strcpy_ssse3) + IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_sse2_unaligned) + IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/strcspn.S. */ + IFUNC_IMPL (i, name, strcspn, +- IFUNC_IMPL_ADD (array, i, strcspn, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2), + __strcspn_sse42) + IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_sse2)) + + /* Support sysdeps/x86_64/multiarch/strncase_l.S. */ + IFUNC_IMPL (i, name, strncasecmp, +- IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_AVX, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_ARCH_FEATURE (AVX_Usable), + __strncasecmp_avx) +- IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_CPU_FEATURE (SSE4_2), + __strncasecmp_sse42) +- IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_CPU_FEATURE (SSSE3), + __strncasecmp_ssse3) + IFUNC_IMPL_ADD (array, i, strncasecmp, 1, + __strncasecmp_sse2)) + + /* Support sysdeps/x86_64/multiarch/strncase_l.S. */ + IFUNC_IMPL (i, name, strncasecmp_l, +- IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_AVX, ++ IFUNC_IMPL_ADD (array, i, strncasecmp_l, ++ HAS_ARCH_FEATURE (AVX_Usable), + __strncasecmp_l_avx) +- IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_CPU_FEATURE (SSE4_2), + __strncasecmp_l_sse42) +- IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncasecmp_l, HAS_CPU_FEATURE (SSSE3), + __strncasecmp_l_ssse3) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, + __strncasecmp_l_sse2)) + + /* Support sysdeps/x86_64/multiarch/strncat.S. */ + IFUNC_IMPL (i, name, strncat, +- IFUNC_IMPL_ADD (array, i, strncat, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3), + __strncat_ssse3) + IFUNC_IMPL_ADD (array, i, strncat, 1, + __strncat_sse2_unaligned) +@@ -181,7 +195,7 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/strncpy.S. */ + IFUNC_IMPL (i, name, strncpy, +- IFUNC_IMPL_ADD (array, i, strncpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSSE3), + __strncpy_ssse3) + IFUNC_IMPL_ADD (array, i, strncpy, 1, + __strncpy_sse2_unaligned) +@@ -194,79 +208,83 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/strpbrk.S. */ + IFUNC_IMPL (i, name, strpbrk, +- IFUNC_IMPL_ADD (array, i, strpbrk, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strpbrk, HAS_CPU_FEATURE (SSE4_2), + __strpbrk_sse42) + IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_sse2)) + + /* Support sysdeps/x86_64/multiarch/strrchr.S. */ + IFUNC_IMPL (i, name, strrchr, +- IFUNC_IMPL_ADD (array, i, strrchr, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE4_2), + __strrchr_sse42) + IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_sse2_no_bsf) + IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_sse2)) + + /* Support sysdeps/x86_64/multiarch/strspn.S. */ + IFUNC_IMPL (i, name, strspn, +- IFUNC_IMPL_ADD (array, i, strspn, HAS_SSE4_2, __strspn_sse42) ++ IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2), ++ __strspn_sse42) + IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_sse2)) + + /* Support sysdeps/x86_64/multiarch/strstr-c.c. */ + IFUNC_IMPL (i, name, strstr, + IFUNC_IMPL_ADD (array, i, strstr, use_unaligned_strstr (), + __strstr_sse2_unaligned) +- IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42) ++ IFUNC_IMPL_ADD (array, i, strstr, HAS_CPU_FEATURE (SSE4_2), ++ __strstr_sse42) + IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_sse2)) + + /* Support sysdeps/x86_64/multiarch/wcscpy.S. */ + IFUNC_IMPL (i, name, wcscpy, +- IFUNC_IMPL_ADD (array, i, wcscpy, HAS_SSSE3, __wcscpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3), ++ __wcscpy_ssse3) + IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/wmemcmp.S. */ + IFUNC_IMPL (i, name, wmemcmp, +- IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_SSE4_1, ++ IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_1), + __wmemcmp_sse4_1) +- IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3), + __wmemcmp_ssse3) + IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_sse2)) + + #ifdef SHARED + /* Support sysdeps/x86_64/multiarch/memcpy_chk.S. */ + IFUNC_IMPL (i, name, __memcpy_chk, +- IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3_back) +- IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1, + __memcpy_chk_sse2)) + + /* Support sysdeps/x86_64/multiarch/memcpy.S. */ + IFUNC_IMPL (i, name, memcpy, +- IFUNC_IMPL_ADD (array, i, memcpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), + __memcpy_ssse3_back) +- IFUNC_IMPL_ADD (array, i, memcpy, HAS_SSSE3, __memcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), __memcpy_ssse3) + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/mempcpy_chk.S. */ + IFUNC_IMPL (i, name, __mempcpy_chk, +- IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3_back) +- IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1, + __mempcpy_chk_sse2)) + + /* Support sysdeps/x86_64/multiarch/mempcpy.S. */ + IFUNC_IMPL (i, name, mempcpy, +- IFUNC_IMPL_ADD (array, i, mempcpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3_back) +- IFUNC_IMPL_ADD (array, i, mempcpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3) + IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/strlen.S. */ + IFUNC_IMPL (i, name, strlen, +- IFUNC_IMPL_ADD (array, i, strlen, HAS_SSE4_2, __strlen_sse42) ++ IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE4_2), ++ __strlen_sse42) + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_sse2_pminub) + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_sse2_no_bsf) + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_sse2) +@@ -274,9 +292,9 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/strncmp.S. */ + IFUNC_IMPL (i, name, strncmp, +- IFUNC_IMPL_ADD (array, i, strncmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSE4_2), + __strncmp_sse42) +- IFUNC_IMPL_ADD (array, i, strncmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSSE3), + __strncmp_ssse3) + IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_sse2)) + #endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcmp.S +@@ -26,16 +26,13 @@ + .text + ENTRY(memcmp) + .type memcmp, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +- +-1: testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ HAS_CPU_FEATURE (SSSE3) + jnz 2f + leaq __memcmp_sse2(%rip), %rax + ret + +-2: testl $bit_SSE4_1, __cpu_features+CPUID_OFFSET+index_SSE4_1(%rip) ++2: HAS_CPU_FEATURE (SSE4_1) + jz 3f + leaq __memcmp_sse4_1(%rip), %rax + ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy.S +@@ -29,14 +29,12 @@ + .text + ENTRY(__new_memcpy) + .type __new_memcpy, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __memcpy_sse2(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __memcpy_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __memcpy_ssse3(%rip), %rax +- testl $bit_Fast_Copy_Backward, __cpu_features+FEATURE_OFFSET+index_Fast_Copy_Backward(%rip) ++ HAS_ARCH_FEATURE (Fast_Copy_Backward) + jz 2f + leaq __memcpy_ssse3_back(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +@@ -29,14 +29,12 @@ + .text + ENTRY(__memcpy_chk) + .type __memcpy_chk, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __memcpy_chk_sse2(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __memcpy_chk_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __memcpy_chk_ssse3(%rip), %rax +- testl $bit_Fast_Copy_Backward, __cpu_features+FEATURE_OFFSET+index_Fast_Copy_Backward(%rip) ++ HAS_ARCH_FEATURE (Fast_Copy_Backward) + jz 2f + leaq __memcpy_chk_ssse3_back(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memmove.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove.c +@@ -47,8 +47,8 @@ extern __typeof (__redirect_memmove) __m + ifunc symbol properly. */ + extern __typeof (__redirect_memmove) __libc_memmove; + libc_ifunc (__libc_memmove, +- HAS_SSSE3 +- ? (HAS_FAST_COPY_BACKWARD ++ HAS_CPU_FEATURE (SSSE3) ++ ? (HAS_ARCH_FEATURE (Fast_Copy_Backward) + ? __memmove_ssse3_back : __memmove_ssse3) + : __memmove_sse2) + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove_chk.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memmove_chk.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove_chk.c +@@ -29,7 +29,7 @@ extern __typeof (__memmove_chk) __memmov + #include "debug/memmove_chk.c" + + libc_ifunc (__memmove_chk, +- HAS_SSSE3 +- ? (HAS_FAST_COPY_BACKWARD ++ HAS_CPU_FEATURE (SSSE3) ++ ? (HAS_ARCH_FEATURE (Fast_Copy_Backward) + ? __memmove_chk_ssse3_back : __memmove_chk_ssse3) + : __memmove_chk_sse2); +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/mempcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy.S +@@ -27,14 +27,12 @@ + #if defined SHARED && IS_IN (libc) + ENTRY(__mempcpy) + .type __mempcpy, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __mempcpy_sse2(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __mempcpy_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __mempcpy_ssse3(%rip), %rax +- testl $bit_Fast_Copy_Backward, __cpu_features+FEATURE_OFFSET+index_Fast_Copy_Backward(%rip) ++ HAS_ARCH_FEATURE (Fast_Copy_Backward) + jz 2f + leaq __mempcpy_ssse3_back(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/mempcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy_chk.S +@@ -29,14 +29,12 @@ + .text + ENTRY(__mempcpy_chk) + .type __mempcpy_chk, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __mempcpy_chk_sse2(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __mempcpy_chk_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __mempcpy_chk_ssse3(%rip), %rax +- testl $bit_Fast_Copy_Backward, __cpu_features+FEATURE_OFFSET+index_Fast_Copy_Backward(%rip) ++ HAS_ARCH_FEATURE (Fast_Copy_Backward) + jz 2f + leaq __mempcpy_chk_ssse3_back(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset.S +@@ -24,11 +24,9 @@ + #if IS_IN (libc) + ENTRY(memset) + .type memset, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __memset_x86_64(%rip), %rax +- testl $bit_Prefer_SSE_for_memop, __cpu_features+FEATURE_OFFSET+index_Prefer_SSE_for_memop(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __memset_x86_64(%rip), %rax ++ HAS_ARCH_FEATURE (Prefer_SSE_for_memop) + jz 2f + leaq __memset_sse2(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset_chk.S +@@ -25,11 +25,9 @@ + # ifdef SHARED + ENTRY(__memset_chk) + .type __memset_chk, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __memset_chk_x86_64(%rip), %rax +- testl $bit_Prefer_SSE_for_memop, __cpu_features+FEATURE_OFFSET+index_Prefer_SSE_for_memop(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __memset_chk_x86_64(%rip), %rax ++ HAS_ARCH_FEATURE (Prefer_SSE_for_memop) + jz 2f + leaq __memset_chk_sse2(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/sched_cpucount.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/sched_cpucount.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/sched_cpucount.c +@@ -33,4 +33,4 @@ + #undef __sched_cpucount + + libc_ifunc (__sched_cpucount, +- HAS_POPCOUNT ? popcount_cpucount : generic_cpucount); ++ HAS_CPU_FEATURE (POPCOUNT) ? popcount_cpucount : generic_cpucount); +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcat.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcat.S +@@ -47,14 +47,12 @@ + .text + ENTRY(STRCAT) + .type STRCAT, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq STRCAT_SSE2_UNALIGNED(%rip), %rax +- testl $bit_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_Fast_Unaligned_Load(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq STRCAT_SSE2_UNALIGNED(%rip), %rax ++ HAS_ARCH_FEATURE (Fast_Unaligned_Load) + jnz 2f + leaq STRCAT_SSE2(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq STRCAT_SSSE3(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strchr.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strchr.S +@@ -25,15 +25,13 @@ + .text + ENTRY(strchr) + .type strchr, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __strchr_sse2(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __strchr_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f + leaq __strchr_sse42(%rip), %rax + ret +-2: testl $bit_Slow_BSF, __cpu_features+FEATURE_OFFSET+index_Slow_BSF(%rip) ++2: HAS_ARCH_FEATURE (Slow_BSF) + jz 3f + leaq __strchr_sse2_no_bsf(%rip), %rax + 3: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcmp.S +@@ -83,16 +83,12 @@ + .text + ENTRY(STRCMP) + .type STRCMP, @gnu_indirect_function +- /* Manually inlined call to __get_cpu_features. */ +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: ++ LOAD_RTLD_GLOBAL_RO_RDX + leaq STRCMP_SSE42(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ HAS_CPU_FEATURE (SSE4_2) + jnz 2f + leaq STRCMP_SSSE3(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ HAS_CPU_FEATURE (SSSE3) + jnz 2f + leaq STRCMP_SSE2(%rip), %rax + 2: ret +@@ -101,21 +97,17 @@ END(STRCMP) + # ifdef USE_AS_STRCASECMP_L + ENTRY(__strcasecmp) + .type __strcasecmp, @gnu_indirect_function +- /* Manually inlined call to __get_cpu_features. */ +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: ++ LOAD_RTLD_GLOBAL_RO_RDX + # ifdef HAVE_AVX_SUPPORT + leaq __strcasecmp_avx(%rip), %rax +- testl $bit_AVX_Usable, __cpu_features+FEATURE_OFFSET+index_AVX_Usable(%rip) ++ HAS_ARCH_FEATURE (AVX_Usable) + jnz 2f + # endif + leaq __strcasecmp_sse42(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ HAS_CPU_FEATURE (SSE4_2) + jnz 2f + leaq __strcasecmp_ssse3(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ HAS_CPU_FEATURE (SSSE3) + jnz 2f + leaq __strcasecmp_sse2(%rip), %rax + 2: ret +@@ -125,21 +117,17 @@ weak_alias (__strcasecmp, strcasecmp) + # ifdef USE_AS_STRNCASECMP_L + ENTRY(__strncasecmp) + .type __strncasecmp, @gnu_indirect_function +- /* Manually inlined call to __get_cpu_features. */ +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: ++ LOAD_RTLD_GLOBAL_RO_RDX + # ifdef HAVE_AVX_SUPPORT + leaq __strncasecmp_avx(%rip), %rax +- testl $bit_AVX_Usable, __cpu_features+FEATURE_OFFSET+index_AVX_Usable(%rip) ++ HAS_ARCH_FEATURE (AVX_Usable) + jnz 2f + # endif + leaq __strncasecmp_sse42(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ HAS_CPU_FEATURE (SSE4_2) + jnz 2f + leaq __strncasecmp_ssse3(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ HAS_CPU_FEATURE (SSSE3) + jnz 2f + leaq __strncasecmp_sse2(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcpy.S +@@ -61,14 +61,12 @@ + .text + ENTRY(STRCPY) + .type STRCPY, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq STRCPY_SSE2_UNALIGNED(%rip), %rax +- testl $bit_Fast_Unaligned_Load, __cpu_features+FEATURE_OFFSET+index_Fast_Unaligned_Load(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq STRCPY_SSE2_UNALIGNED(%rip), %rax ++ HAS_ARCH_FEATURE (Fast_Unaligned_Load) + jnz 2f + leaq STRCPY_SSE2(%rip), %rax +- testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq STRCPY_SSSE3(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcspn.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcspn.S +@@ -45,11 +45,9 @@ + .text + ENTRY(STRCSPN) + .type STRCSPN, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq STRCSPN_SSE2(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq STRCSPN_SSE2(%rip), %rax ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f + leaq STRCSPN_SSE42(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strspn.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strspn.S +@@ -30,11 +30,9 @@ + .text + ENTRY(strspn) + .type strspn, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __strspn_sse2(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __strspn_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f + leaq __strspn_sse42(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/test-multiarch.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/test-multiarch.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/test-multiarch.c +@@ -75,12 +75,18 @@ do_test (int argc, char **argv) + int fails; + + get_cpuinfo (); +- fails = check_proc ("avx", HAS_AVX, "HAS_AVX"); +- fails += check_proc ("fma4", HAS_FMA4, "HAS_FMA4"); +- fails += check_proc ("sse4_2", HAS_SSE4_2, "HAS_SSE4_2"); +- fails += check_proc ("sse4_1", HAS_SSE4_1, "HAS_SSE4_1"); +- fails += check_proc ("ssse3", HAS_SSSE3, "HAS_SSSE3"); +- fails += check_proc ("popcnt", HAS_POPCOUNT, "HAS_POPCOUNT"); ++ fails = check_proc ("avx", HAS_ARCH_FEATURE (AVX_Usable), ++ "HAS_ARCH_FEATURE (AVX_Usable)"); ++ fails += check_proc ("fma4", HAS_ARCH_FEATURE (FMA4_Usable), ++ "HAS_ARCH_FEATURE (FMA4_Usable)"); ++ fails += check_proc ("sse4_2", HAS_CPU_FEATURE (SSE4_2), ++ "HAS_CPU_FEATURE (SSE4_2)"); ++ fails += check_proc ("sse4_1", HAS_CPU_FEATURE (SSE4_1) ++ , "HAS_CPU_FEATURE (SSE4_1)"); ++ fails += check_proc ("ssse3", HAS_CPU_FEATURE (SSSE3), ++ "HAS_CPU_FEATURE (SSSE3)"); ++ fails += check_proc ("popcnt", HAS_CPU_FEATURE (POPCOUNT), ++ "HAS_CPU_FEATURE (POPCOUNT)"); + + printf ("%d differences between /proc/cpuinfo and glibc code.\n", fails); + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wcscpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wcscpy.S +@@ -27,11 +27,8 @@ + .text + ENTRY(wcscpy) + .type wcscpy, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +- +-1: testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ HAS_CPU_FEATURE (SSSE3) + jnz 2f + leaq __wcscpy_sse2(%rip), %rax + ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wmemcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/wmemcmp.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/wmemcmp.S +@@ -26,16 +26,13 @@ + .text + ENTRY(wmemcmp) + .type wmemcmp, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features(%rip) +- jne 1f +- call __init_cpu_features +- +-1: testl $bit_SSSE3, __cpu_features+CPUID_OFFSET+index_SSSE3(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ HAS_CPU_FEATURE (SSSE3) + jnz 2f + leaq __wmemcmp_sse2(%rip), %rax + ret + +-2: testl $bit_SSE4_1, __cpu_features+CPUID_OFFSET+index_SSE4_1(%rip) ++2: HAS_CPU_FEATURE (SSE4_1) + jz 3f + leaq __wmemcmp_sse4_1(%rip), %rax + ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rawmemchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/rawmemchr.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rawmemchr.S +@@ -27,12 +27,10 @@ + .text + ENTRY(rawmemchr) + .type rawmemchr, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: testl $bit_Prefer_PMINUB_for_stringop, __cpu_features+FEATURE_OFFSET+index_Prefer_PMINUB_for_stringop(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ HAS_ARCH_FEATURE (Prefer_PMINUB_for_stringop) + jnz 2f +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f + leaq __rawmemchr_sse42(%rip), %rax + ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strlen.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strlen.S +@@ -29,18 +29,16 @@ + .text + ENTRY(strlen) + .type strlen, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __strlen_sse2_pminub(%rip), %rax +- testl $bit_Prefer_PMINUB_for_stringop, __cpu_features+FEATURE_OFFSET+index_Prefer_PMINUB_for_stringop(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __strlen_sse2_pminub(%rip), %rax ++ HAS_ARCH_FEATURE (Prefer_PMINUB_for_stringop) + jnz 2f + leaq __strlen_sse2(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f + leaq __strlen_sse42(%rip), %rax + ret +-2: testl $bit_Slow_BSF, __cpu_features+FEATURE_OFFSET+index_Slow_BSF(%rip) ++2: HAS_ARCH_FEATURE (Slow_BSF) + jz 3f + leaq __strlen_sse2_no_bsf(%rip), %rax + 3: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strnlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strnlen.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strnlen.S +@@ -27,11 +27,9 @@ + .text + ENTRY(__strnlen) + .type __strnlen, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __strnlen_sse2(%rip), %rax +- testl $bit_Slow_BSF, __cpu_features+FEATURE_OFFSET+index_Slow_BSF(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __strnlen_sse2(%rip), %rax ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 2f + leaq __strnlen_sse2_no_bsf(%rip), %rax + 2: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strrchr.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strrchr.S +@@ -28,15 +28,13 @@ + .text + ENTRY(strrchr) + .type strrchr, @gnu_indirect_function +- cmpl $0, __cpu_features+KIND_OFFSET(%rip) +- jne 1f +- call __init_cpu_features +-1: leaq __strrchr_sse2(%rip), %rax +- testl $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip) ++ LOAD_RTLD_GLOBAL_RO_RDX ++ leaq __strrchr_sse2(%rip), %rax ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f + leaq __strrchr_sse42(%rip), %rax + ret +-2: testl $bit_Slow_BSF, __cpu_features+FEATURE_OFFSET+index_Slow_BSF(%rip) ++2: HAS_ARCH_FEATURE (Slow_BSF) + jz 3f + leaq __strrchr_sse2_no_bsf(%rip), %rax + 3: ret +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strcasestr-c.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strcasestr-c.c +@@ -12,8 +12,8 @@ extern __typeof (__strcasestr_sse2) __st + + #if 1 + libc_ifunc (__strcasestr, +- HAS_SSE4_2 && !use_unaligned_strstr () ? __strcasestr_sse42 : +- __strcasestr_sse2); ++ HAS_CPU_FEATURE (SSE4_2) && !use_unaligned_strstr () ++ ? __strcasestr_sse42 : __strcasestr_sse2); + #else + libc_ifunc (__strcasestr, + 0 ? __strcasestr_sse42 : __strcasestr_sse2); +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strstr-c.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c +@@ -42,7 +42,7 @@ extern __typeof (__redirect_strstr) __st + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + extern __typeof (__redirect_strstr) __libc_strstr; +-libc_ifunc (__libc_strstr, HAS_SSE4_2 ? (use_unaligned_strstr () ? ++libc_ifunc (__libc_strstr, HAS_CPU_FEATURE (SSE4_2) ? (use_unaligned_strstr () ? + __strstr_sse2_unaligned : + __strstr_sse42) : __strstr_sse2) diff --git a/SOURCES/glibc-rh1292018-3.patch b/SOURCES/glibc-rh1292018-3.patch new file mode 100644 index 00000000..833fbb48 --- /dev/null +++ b/SOURCES/glibc-rh1292018-3.patch @@ -0,0 +1,1948 @@ +commit 1aee37a22e3977de7a89e734e0a1e112f52045f2 +Author: H.J. Lu +Date: Thu Aug 13 03:39:22 2015 -0700 + + Update i686 multiarch functions for + + This patch updates i686 multiarch functions to use the newly defined + HAS_CPU_FEATURE, HAS_ARCH_FEATURE, LOAD_GOT_AND_RTLD_GLOBAL_RO and + LOAD_FUNC_GOT_EAX from . + +commit 4e940b2f4b577f3a530e0580373f7c2d569f4d63 +Author: H.J. Lu +Date: Sun Mar 6 08:23:24 2016 -0800 + + Use HAS_ARCH_FEATURE with Fast_Rep_String + + HAS_ARCH_FEATURE, not HAS_CPU_FEATURE, should be used with + Fast_Rep_String. + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/e_expf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/fpu/multiarch/e_expf.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/e_expf.c +@@ -23,11 +23,15 @@ extern double __ieee754_expf_ia32 (doubl + + double __ieee754_expf (double); + libm_ifunc (__ieee754_expf, +- HAS_SSE2 ? __ieee754_expf_sse2 : __ieee754_expf_ia32); ++ HAS_CPU_FEATURE (SSE2) ++ ? __ieee754_expf_sse2 ++ : __ieee754_expf_ia32); + + extern double __expf_finite_sse2 (double); + extern double __expf_finite_ia32 (double); + + double __expf_finite (double); + libm_ifunc (__expf_finite, +- HAS_SSE2 ? __expf_finite_sse2 : __expf_finite_ia32); ++ HAS_CPU_FEATURE (SSE2) ++ ? __expf_finite_sse2 ++ : __expf_finite_ia32); +Index: glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/s_cosf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/fpu/multiarch/s_cosf.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/s_cosf.c +@@ -22,7 +22,7 @@ extern float __cosf_sse2 (float); + extern float __cosf_ia32 (float); + float __cosf (float); + +-libm_ifunc (__cosf, HAS_SSE2 ? __cosf_sse2 : __cosf_ia32); ++libm_ifunc (__cosf, HAS_CPU_FEATURE (SSE2) ? __cosf_sse2 : __cosf_ia32); + weak_alias (__cosf, cosf); + + #define COSF __cosf_ia32 +Index: glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c +@@ -22,7 +22,8 @@ extern void __sincosf_sse2 (float, float + extern void __sincosf_ia32 (float, float *, float *); + void __sincosf (float, float *, float *); + +-libm_ifunc (__sincosf, HAS_SSE2 ? __sincosf_sse2 : __sincosf_ia32); ++libm_ifunc (__sincosf, ++ HAS_CPU_FEATURE (SSE2) ? __sincosf_sse2 : __sincosf_ia32); + weak_alias (__sincosf, sincosf); + + #define SINCOSF __sincosf_ia32 +Index: glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/s_sinf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/fpu/multiarch/s_sinf.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/fpu/multiarch/s_sinf.c +@@ -22,7 +22,7 @@ extern float __sinf_sse2 (float); + extern float __sinf_ia32 (float); + float __sinf (float); + +-libm_ifunc (__sinf, HAS_SSE2 ? __sinf_sse2 : __sinf_ia32); ++libm_ifunc (__sinf, HAS_CPU_FEATURE (SSE2) ? __sinf_sse2 : __sinf_ia32); + weak_alias (__sinf, sinf); + #define SINF __sinf_ia32 + #include +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bcopy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/bcopy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bcopy.S +@@ -23,46 +23,19 @@ + + /* Define multiple versions only for the definition in lib. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(bcopy) + .type bcopy, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __bcopy_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__bcopy_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __bcopy_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__bcopy_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __bcopy_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(bcopy) +-# else +- .text +-ENTRY(bcopy) +- .type bcopy, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __bcopy_ia32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __bcopy_ssse3, %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features +- jz 2f +- leal __bcopy_ssse3_rep, %eax ++ LOAD_FUNC_GOT_EAX(__bcopy_ssse3_rep) + 2: ret + END(bcopy) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bzero.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/bzero.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/bzero.S +@@ -23,46 +23,19 @@ + + /* Define multiple versions only for the definition in lib. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(__bzero) + .type __bzero, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __bzero_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__bzero_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __bzero_sse2@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX ( __bzero_sse2) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __bzero_sse2_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(__bzero) +-# else +- .text +-ENTRY(__bzero) +- .type __bzero, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __bzero_ia32, %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features +- jz 2f +- leal __bzero_sse2, %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features +- jz 2f +- leal __bzero_sse2_rep, %eax ++ LOAD_FUNC_GOT_EAX (__bzero_sse2_rep) + 2: ret + END(__bzero) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-impl-list.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/ifunc-impl-list.c +@@ -38,152 +38,152 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/i386/i686/multiarch/bcopy.S. */ + IFUNC_IMPL (i, name, bcopy, +- IFUNC_IMPL_ADD (array, i, bcopy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3), + __bcopy_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, bcopy, HAS_SSSE3, __bcopy_ssse3) ++ IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3), __bcopy_ssse3) + IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/bzero.S. */ + IFUNC_IMPL (i, name, bzero, +- IFUNC_IMPL_ADD (array, i, bzero, HAS_SSE2, __bzero_sse2_rep) +- IFUNC_IMPL_ADD (array, i, bzero, HAS_SSE2, __bzero_sse2) ++ IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2), __bzero_sse2_rep) ++ IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2), __bzero_sse2) + IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memchr.S. */ + IFUNC_IMPL (i, name, memchr, +- IFUNC_IMPL_ADD (array, i, memchr, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2), + __memchr_sse2_bsf) +- IFUNC_IMPL_ADD (array, i, memchr, HAS_SSE2, __memchr_sse2) ++ IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2), __memchr_sse2) + IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memcmp.S. */ + IFUNC_IMPL (i, name, memcmp, +- IFUNC_IMPL_ADD (array, i, memcmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_2), + __memcmp_sse4_2) +- IFUNC_IMPL_ADD (array, i, memcmp, HAS_SSSE3, __memcmp_ssse3) ++ IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3), __memcmp_ssse3) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memmove_chk.S. */ + IFUNC_IMPL (i, name, __memmove_chk, +- IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __memmove_chk, 1, + __memmove_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memmove.S. */ + IFUNC_IMPL (i, name, memmove, +- IFUNC_IMPL_ADD (array, i, memmove, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, memmove, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3) + IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memrchr.S. */ + IFUNC_IMPL (i, name, memrchr, +- IFUNC_IMPL_ADD (array, i, memrchr, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2), + __memrchr_sse2_bsf) +- IFUNC_IMPL_ADD (array, i, memrchr, HAS_SSE2, __memrchr_sse2) ++ IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2), __memrchr_sse2) + IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memset_chk.S. */ + IFUNC_IMPL (i, name, __memset_chk, +- IFUNC_IMPL_ADD (array, i, __memset_chk, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, __memset_chk, HAS_CPU_FEATURE (SSE2), + __memset_chk_sse2_rep) +- IFUNC_IMPL_ADD (array, i, __memset_chk, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, __memset_chk, HAS_CPU_FEATURE (SSE2), + __memset_chk_sse2) + IFUNC_IMPL_ADD (array, i, __memset_chk, 1, + __memset_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memset.S. */ + IFUNC_IMPL (i, name, memset, +- IFUNC_IMPL_ADD (array, i, memset, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2), + __memset_sse2_rep) +- IFUNC_IMPL_ADD (array, i, memset, HAS_SSE2, __memset_sse2) ++ IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2), __memset_sse2) + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ia32)) + + /* Support sysdeps/i386/i686/multiarch/rawmemchr.S. */ + IFUNC_IMPL (i, name, rawmemchr, +- IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2), + __rawmemchr_sse2_bsf) +- IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2), + __rawmemchr_sse2) + IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/stpncpy.S. */ + IFUNC_IMPL (i, name, stpncpy, +- IFUNC_IMPL_ADD (array, i, stpncpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3), + __stpncpy_ssse3) +- IFUNC_IMPL_ADD (array, i, stpncpy, HAS_SSE2, __stpncpy_sse2) ++ IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSE2), __stpncpy_sse2) + IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/stpcpy.S. */ + IFUNC_IMPL (i, name, stpcpy, +- IFUNC_IMPL_ADD (array, i, stpcpy, HAS_SSSE3, __stpcpy_ssse3) +- IFUNC_IMPL_ADD (array, i, stpcpy, HAS_SSE2, __stpcpy_sse2) ++ IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSSE3), __stpcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSE2), __stpcpy_sse2) + IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcasecmp.S. */ + IFUNC_IMPL (i, name, strcasecmp, +- IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_CPU_FEATURE (SSE4_2), + __strcasecmp_sse4_2) +- IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, HAS_CPU_FEATURE (SSSE3), + __strcasecmp_ssse3) + IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcasecmp_l.S. */ + IFUNC_IMPL (i, name, strcasecmp_l, +- IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_CPU_FEATURE (SSE4_2), + __strcasecmp_l_sse4_2) +- IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, HAS_CPU_FEATURE (SSSE3), + __strcasecmp_l_ssse3) + IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, + __strcasecmp_l_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcasestr.c. */ + IFUNC_IMPL (i, name, strcasestr, +- IFUNC_IMPL_ADD (array, i, strcasestr, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcasestr, HAS_CPU_FEATURE (SSE4_2), + __strcasestr_sse42) + IFUNC_IMPL_ADD (array, i, strcasestr, 1, __strcasestr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcat.S. */ + IFUNC_IMPL (i, name, strcat, +- IFUNC_IMPL_ADD (array, i, strcat, HAS_SSSE3, __strcat_ssse3) +- IFUNC_IMPL_ADD (array, i, strcat, HAS_SSE2, __strcat_sse2) ++ IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3), __strcat_ssse3) ++ IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSE2), __strcat_sse2) + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strchr.S. */ + IFUNC_IMPL (i, name, strchr, +- IFUNC_IMPL_ADD (array, i, strchr, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2), + __strchr_sse2_bsf) +- IFUNC_IMPL_ADD (array, i, strchr, HAS_SSE2, __strchr_sse2) ++ IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2), __strchr_sse2) + IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcmp.S. */ + IFUNC_IMPL (i, name, strcmp, +- IFUNC_IMPL_ADD (array, i, strcmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSE4_2), + __strcmp_sse4_2) +- IFUNC_IMPL_ADD (array, i, strcmp, HAS_SSSE3, __strcmp_ssse3) ++ IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3), __strcmp_ssse3) + IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcpy.S. */ + IFUNC_IMPL (i, name, strcpy, +- IFUNC_IMPL_ADD (array, i, strcpy, HAS_SSSE3, __strcpy_ssse3) +- IFUNC_IMPL_ADD (array, i, strcpy, HAS_SSE2, __strcpy_sse2) ++ IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSSE3), __strcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSE2), __strcpy_sse2) + IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strcspn.S. */ + IFUNC_IMPL (i, name, strcspn, +- IFUNC_IMPL_ADD (array, i, strcspn, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2), + __strcspn_sse42) + IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncase.S. */ + IFUNC_IMPL (i, name, strncasecmp, +- IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_CPU_FEATURE (SSE4_2), + __strncasecmp_sse4_2) +- IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, HAS_CPU_FEATURE (SSSE3), + __strncasecmp_ssse3) + IFUNC_IMPL_ADD (array, i, strncasecmp, 1, + __strncasecmp_ia32)) +@@ -191,133 +191,133 @@ __libc_ifunc_impl_list (const char *name + /* Support sysdeps/i386/i686/multiarch/strncase_l.S. */ + IFUNC_IMPL (i, name, strncasecmp_l, + IFUNC_IMPL_ADD (array, i, strncasecmp_l, +- HAS_SSE4_2, __strncasecmp_l_sse4_2) ++ HAS_CPU_FEATURE (SSE4_2), __strncasecmp_l_sse4_2) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, +- HAS_SSSE3, __strncasecmp_l_ssse3) ++ HAS_CPU_FEATURE (SSSE3), __strncasecmp_l_ssse3) + IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, + __strncasecmp_l_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncat.S. */ + IFUNC_IMPL (i, name, strncat, +- IFUNC_IMPL_ADD (array, i, strncat, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3), + __strncat_ssse3) +- IFUNC_IMPL_ADD (array, i, strncat, HAS_SSE2, __strncat_sse2) ++ IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2), __strncat_sse2) + IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncpy.S. */ + IFUNC_IMPL (i, name, strncpy, +- IFUNC_IMPL_ADD (array, i, strncpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSSE3), + __strncpy_ssse3) +- IFUNC_IMPL_ADD (array, i, strncpy, HAS_SSE2, __strncpy_sse2) ++ IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSE2), __strncpy_sse2) + IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strnlen.S. */ + IFUNC_IMPL (i, name, strnlen, +- IFUNC_IMPL_ADD (array, i, strnlen, HAS_SSE2, __strnlen_sse2) ++ IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2), __strnlen_sse2) + IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strpbrk.S. */ + IFUNC_IMPL (i, name, strpbrk, +- IFUNC_IMPL_ADD (array, i, strpbrk, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strpbrk, HAS_CPU_FEATURE (SSE4_2), + __strpbrk_sse42) + IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strrchr.S. */ + IFUNC_IMPL (i, name, strrchr, +- IFUNC_IMPL_ADD (array, i, strrchr, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2), + __strrchr_sse2_bsf) +- IFUNC_IMPL_ADD (array, i, strrchr, HAS_SSE2, __strrchr_sse2) ++ IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2), __strrchr_sse2) + IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strspn.S. */ + IFUNC_IMPL (i, name, strspn, +- IFUNC_IMPL_ADD (array, i, strspn, HAS_SSE4_2, __strspn_sse42) ++ IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2), __strspn_sse42) + IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strstr-c.c. */ + IFUNC_IMPL (i, name, strstr, +- IFUNC_IMPL_ADD (array, i, strstr, HAS_SSE4_2, __strstr_sse42) ++ IFUNC_IMPL_ADD (array, i, strstr, HAS_CPU_FEATURE (SSE4_2), __strstr_sse42) + IFUNC_IMPL_ADD (array, i, strstr, 1, __strstr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcschr.S. */ + IFUNC_IMPL (i, name, wcschr, +- IFUNC_IMPL_ADD (array, i, wcschr, HAS_SSE2, __wcschr_sse2) ++ IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2), __wcschr_sse2) + IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcscmp.S. */ + IFUNC_IMPL (i, name, wcscmp, +- IFUNC_IMPL_ADD (array, i, wcscmp, HAS_SSE2, __wcscmp_sse2) ++ IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2), __wcscmp_sse2) + IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcscpy.S. */ + IFUNC_IMPL (i, name, wcscpy, +- IFUNC_IMPL_ADD (array, i, wcscpy, HAS_SSSE3, __wcscpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3), __wcscpy_ssse3) + IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcslen.S. */ + IFUNC_IMPL (i, name, wcslen, +- IFUNC_IMPL_ADD (array, i, wcslen, HAS_SSE2, __wcslen_sse2) ++ IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2), __wcslen_sse2) + IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wcsrchr.S. */ + IFUNC_IMPL (i, name, wcsrchr, +- IFUNC_IMPL_ADD (array, i, wcsrchr, HAS_SSE2, __wcsrchr_sse2) ++ IFUNC_IMPL_ADD (array, i, wcsrchr, HAS_CPU_FEATURE (SSE2), __wcsrchr_sse2) + IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_ia32)) + + /* Support sysdeps/i386/i686/multiarch/wmemcmp.S. */ + IFUNC_IMPL (i, name, wmemcmp, +- IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2), + __wmemcmp_sse4_2) +- IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3), + __wmemcmp_ssse3) + IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_ia32)) + + #ifdef SHARED + /* Support sysdeps/i386/i686/multiarch/memcpy_chk.S. */ + IFUNC_IMPL (i, name, __memcpy_chk, +- IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1, + __memcpy_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/memcpy.S. */ + IFUNC_IMPL (i, name, memcpy, +- IFUNC_IMPL_ADD (array, i, memcpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), + __memcpy_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, memcpy, HAS_SSSE3, __memcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), __memcpy_ssse3) + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S. */ + IFUNC_IMPL (i, name, __mempcpy_chk, +- IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1, + __mempcpy_chk_ia32)) + + /* Support sysdeps/i386/i686/multiarch/mempcpy.S. */ + IFUNC_IMPL (i, name, mempcpy, +- IFUNC_IMPL_ADD (array, i, mempcpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3_rep) +- IFUNC_IMPL_ADD (array, i, mempcpy, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3) + IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strlen.S. */ + IFUNC_IMPL (i, name, strlen, +- IFUNC_IMPL_ADD (array, i, strlen, HAS_SSE2, ++ IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2), + __strlen_sse2_bsf) +- IFUNC_IMPL_ADD (array, i, strlen, HAS_SSE2, __strlen_sse2) ++ IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2), __strlen_sse2) + IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32)) + + /* Support sysdeps/i386/i686/multiarch/strncmp.S. */ + IFUNC_IMPL (i, name, strncmp, +- IFUNC_IMPL_ADD (array, i, strncmp, HAS_SSE4_2, ++ IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSE4_2), + __strncmp_sse4_2) +- IFUNC_IMPL_ADD (array, i, strncmp, HAS_SSSE3, ++ IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSSE3), + __strncmp_ssse3) + IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32)) + #endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memchr.S +@@ -22,46 +22,22 @@ + #include + + #if IS_IN (libc) +-# define CFI_POP(REG) \ +- cfi_adjust_cfa_offset (-4); \ +- cfi_restore (REG) +- +-# define CFI_PUSH(REG) \ +- cfi_adjust_cfa_offset (4); \ +- cfi_rel_offset (REG, 0) +- + .text + ENTRY(__memchr) + .type __memchr, @gnu_indirect_function +- pushl %ebx +- CFI_PUSH (%ebx) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +- +-1: testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- testl $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx) ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 3f + +- leal __memchr_sse2@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++ LOAD_FUNC_GOT_EAX ( __memchr_sse2) + ret + +- CFI_PUSH (%ebx) +- +-2: leal __memchr_ia32@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++2: LOAD_FUNC_GOT_EAX (__memchr_ia32) + ret + +- CFI_PUSH (%ebx) +- +-3: leal __memchr_sse2_bsf@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++3: LOAD_FUNC_GOT_EAX (__memchr_sse2_bsf) + ret + END(__memchr) + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcmp.S +@@ -23,46 +23,19 @@ + + /* Define multiple versions only for the definition in libc. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(memcmp) + .type memcmp, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memcmp_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memcmp_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __memcmp_ssse3@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memcmp_ssse3) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal __memcmp_sse4_2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(memcmp) +-# else +- .text +-ENTRY(memcmp) +- .type memcmp, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __memcmp_ia32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __memcmp_ssse3, %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features +- jz 2f +- leal __memcmp_sse4_2, %eax ++ LOAD_FUNC_GOT_EAX (__memcmp_sse4_2) + 2: ret + END(memcmp) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy.S +@@ -28,24 +28,15 @@ + .text + ENTRY(memcpy) + .type memcpy, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memcpy_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memcpy_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __memcpy_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memcpy_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __memcpy_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__memcpy_ssse3_rep) ++2: ret + END(memcpy) + + # undef ENTRY +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memcpy_chk.S +@@ -29,24 +29,15 @@ + .text + ENTRY(__memcpy_chk) + .type __memcpy_chk, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memcpy_chk_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memcpy_chk_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __memcpy_chk_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memcpy_chk_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __memcpy_chk_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__memcpy_chk_ssse3_rep) ++2: ret + END(__memcpy_chk) + # else + # include "../memcpy_chk.S" +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memmove.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove.S +@@ -23,32 +23,23 @@ + + /* Define multiple versions only for the definition in lib. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(memmove) + .type memmove, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memmove_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memmove_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __memmove_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memmove_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __memmove_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__memmove_ssse3_rep) ++2: ret + END(memmove) + +-# undef ENTRY +-# define ENTRY(name) \ ++# ifdef SHARED ++# undef ENTRY ++# define ENTRY(name) \ + .type __memmove_ia32, @function; \ + .p2align 4; \ + .globl __memmove_ia32; \ +@@ -56,24 +47,9 @@ END(memmove) + __memmove_ia32: cfi_startproc; \ + CALL_MCOUNT + # else +- .text +-ENTRY(memmove) +- .type memmove, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __memmove_ia32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __memmove_ssse3, %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features +- jz 2f +- leal __memmove_ssse3_rep, %eax +-2: ret +-END(memmove) + +-# undef ENTRY +-# define ENTRY(name) \ ++# undef ENTRY ++# define ENTRY(name) \ + .type __memmove_ia32, @function; \ + .globl __memmove_ia32; \ + .p2align 4; \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memmove_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memmove_chk.S +@@ -23,46 +23,21 @@ + + /* Define multiple versions only for the definition in lib. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(__memmove_chk) + .type __memmove_chk, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memmove_chk_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memmove_chk_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __memmove_chk_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memmove_chk_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __memmove_chk_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(__memmove_chk) +-# else +- .text +-ENTRY(__memmove_chk) +- .type __memmove_chk, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __memmove_chk_ia32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __memmove_chk_ssse3, %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features +- jz 2f +- leal __memmove_chk_ssse3_rep, %eax ++ LOAD_FUNC_GOT_EAX (__memmove_chk_ssse3_rep) + 2: ret + END(__memmove_chk) + ++# ifndef SHARED + .type __memmove_chk_ssse3, @function + .p2align 4; + __memmove_chk_ssse3: +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/mempcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy.S +@@ -28,24 +28,15 @@ + .text + ENTRY(__mempcpy) + .type __mempcpy, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __mempcpy_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__mempcpy_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __mempcpy_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__mempcpy_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __mempcpy_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__mempcpy_ssse3_rep) ++2: ret + END(__mempcpy) + + # undef ENTRY +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/mempcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/mempcpy_chk.S +@@ -29,24 +29,15 @@ + .text + ENTRY(__mempcpy_chk) + .type __mempcpy_chk, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__mempcpy_chk_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __mempcpy_chk_ssse3@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__mempcpy_chk_ssse3) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __mempcpy_chk_ssse3_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__mempcpy_chk_ssse3_rep) ++2: ret + END(__mempcpy_chk) + # else + # include "../mempcpy_chk.S" +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memrchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memrchr.S +@@ -22,46 +22,22 @@ + #include + + #if IS_IN (libc) +-# define CFI_POP(REG) \ +- cfi_adjust_cfa_offset (-4); \ +- cfi_restore (REG) +- +-# define CFI_PUSH(REG) \ +- cfi_adjust_cfa_offset (4); \ +- cfi_rel_offset (REG, 0) +- + .text + ENTRY(__memrchr) + .type __memrchr, @gnu_indirect_function +- pushl %ebx +- CFI_PUSH (%ebx) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +- +-1: testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- testl $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx) ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 3f + +- leal __memrchr_sse2@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++ LOAD_FUNC_GOT_EAX (__memrchr_sse2) + ret + +- CFI_PUSH (%ebx) +- +-2: leal __memrchr_ia32@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++2: LOAD_FUNC_GOT_EAX (__memrchr_ia32) + ret + +- CFI_PUSH (%ebx) +- +-3: leal __memrchr_sse2_bsf@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++3: LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf) + ret + END(__memrchr) + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memset.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset.S +@@ -23,46 +23,19 @@ + + /* Define multiple versions only for the definition in lib. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(memset) + .type memset, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memset_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memset_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __memset_sse2@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memset_sse2) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __memset_sse2_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(memset) +-# else +- .text +-ENTRY(memset) +- .type memset, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __memset_ia32, %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features +- jz 2f +- leal __memset_sse2, %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features +- jz 2f +- leal __memset_sse2_rep, %eax ++ LOAD_FUNC_GOT_EAX (__memset_sse2_rep) + 2: ret + END(memset) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/memset_chk.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/memset_chk.S +@@ -23,50 +23,26 @@ + + /* Define multiple versions only for the definition in lib. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(__memset_chk) + .type __memset_chk, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __memset_chk_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__memset_chk_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __memset_chk_sse2@GOTOFF(%ebx), %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__memset_chk_sse2) ++ HAS_ARCH_FEATURE (Fast_Rep_String) + jz 2f +- leal __memset_chk_sse2_rep@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep) ++2: ret + END(__memset_chk) + ++# ifdef SHARED + strong_alias (__memset_chk, __memset_zero_constant_len_parameter) + .section .gnu.warning.__memset_zero_constant_len_parameter + .string "memset used with constant zero length parameter; this could be due to transposed parameters" + # else + .text +-ENTRY(__memset_chk) +- .type __memset_chk, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __memset_chk_ia32, %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features +- jz 2f +- leal __memset_chk_sse2, %eax +- testl $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features +- jz 2f +- leal __memset_chk_sse2_rep, %eax +-2: ret +-END(__memset_chk) +- + .type __memset_chk_sse2, @function + .p2align 4; + __memset_chk_sse2: +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/rawmemchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/rawmemchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/rawmemchr.S +@@ -22,46 +22,22 @@ + #include + + #if IS_IN (libc) +-# define CFI_POP(REG) \ +- cfi_adjust_cfa_offset (-4); \ +- cfi_restore (REG) +- +-# define CFI_PUSH(REG) \ +- cfi_adjust_cfa_offset (4); \ +- cfi_rel_offset (REG, 0) +- + .text + ENTRY(__rawmemchr) + .type __rawmemchr, @gnu_indirect_function +- pushl %ebx +- CFI_PUSH (%ebx) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +- +-1: testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- testl $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx) ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 3f + +- leal __rawmemchr_sse2@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++ LOAD_FUNC_GOT_EAX (__rawmemchr_sse2) + ret + +- CFI_PUSH (%ebx) +- +-2: leal __rawmemchr_ia32@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++2: LOAD_FUNC_GOT_EAX (__rawmemchr_ia32) + ret + +- CFI_PUSH (%ebx) +- +-3: leal __rawmemchr_sse2_bsf@GOTOFF(%ebx), %eax +- popl %ebx +- CFI_POP (%ebx) ++3: LOAD_FUNC_GOT_EAX (__rawmemchr_sse2_bsf) + ret + END(__rawmemchr) + +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/s_fma.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/s_fma.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/s_fma.c +@@ -26,7 +26,8 @@ + extern double __fma_ia32 (double x, double y, double z) attribute_hidden; + extern double __fma_fma (double x, double y, double z) attribute_hidden; + +-libm_ifunc (__fma, HAS_FMA ? __fma_fma : __fma_ia32); ++libm_ifunc (__fma, ++ HAS_ARCH_FEATURE (FMA_Usable) ? __fma_fma : __fma_ia32); + weak_alias (__fma, fma) + + # define __fma __fma_ia32 +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/s_fmaf.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/s_fmaf.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/s_fmaf.c +@@ -26,7 +26,8 @@ + extern float __fmaf_ia32 (float x, float y, float z) attribute_hidden; + extern float __fmaf_fma (float x, float y, float z) attribute_hidden; + +-libm_ifunc (__fmaf, HAS_FMA ? __fmaf_fma : __fmaf_ia32); ++libm_ifunc (__fmaf, ++ HAS_ARCH_FEATURE (FMA_Usable) ? __fmaf_fma : __fmaf_ia32); + weak_alias (__fmaf, fmaf) + + # define __fmaf __fmaf_ia32 +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasecmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcasecmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcasecmp.S +@@ -20,48 +20,18 @@ + #include + #include + +-#ifdef SHARED + .text + ENTRY(__strcasecmp) + .type __strcasecmp, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strcasecmp_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strcasecmp_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __strcasecmp_ssse3@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__strcasecmp_ssse3) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal __strcasecmp_sse4_2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(__strcasecmp) +-#else +- .text +-ENTRY(__strcasecmp) +- .type __strcasecmp, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __strcasecmp_ia32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __strcasecmp_ssse3, %eax +-#if 0 +- // XXX Temporarily +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features +- jz 2f +- leal __strcasecmp_sse4_2, %eax +-#endif ++ LOAD_FUNC_GOT_EAX (__strcasecmp_sse4_2) + 2: ret + END(__strcasecmp) +-#endif + + weak_alias (__strcasecmp, strcasecmp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcat.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcat.S +@@ -45,52 +45,22 @@ + need strncat before the initialization happened. */ + #if IS_IN (libc) + +-# ifdef SHARED + .text + ENTRY(STRCAT) + .type STRCAT, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal STRCAT_IA32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (STRCAT_IA32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal STRCAT_SSE2@GOTOFF(%ebx), %eax +- testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (STRCAT_SSE2) ++ HAS_ARCH_FEATURE (Fast_Unaligned_Load) + jnz 2f +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal STRCAT_SSSE3@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(STRCAT) +-# else +- +-ENTRY(STRCAT) +- .type STRCAT, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal STRCAT_IA32, %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features +- jz 2f +- leal STRCAT_SSE2, %eax +- testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features +- jnz 2f +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal STRCAT_SSSE3, %eax ++ LOAD_FUNC_GOT_EAX (STRCAT_SSSE3) + 2: ret + END(STRCAT) + +-# endif +- + # undef ENTRY + # define ENTRY(name) \ + .type STRCAT_IA32, @function; \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strchr.S +@@ -25,24 +25,15 @@ + .text + ENTRY(strchr) + .type strchr, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strchr_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strchr_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __strchr_sse2_bsf@GOTOFF(%ebx), %eax +- testl $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__strchr_sse2_bsf) ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 2f +- leal __strchr_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__strchr_sse2) ++2: ret + END(strchr) + + # undef ENTRY +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcmp.S +@@ -51,46 +51,19 @@ + define multiple versions for strncmp in static library since we + need strncmp before the initialization happened. */ + #if (defined SHARED || !defined USE_AS_STRNCMP) && IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(STRCMP) + .type STRCMP, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __STRCMP_IA32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__STRCMP_IA32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __STRCMP_SSSE3@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__STRCMP_SSSE3) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal __STRCMP_SSE4_2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(STRCMP) +-# else +- .text +-ENTRY(STRCMP) +- .type STRCMP, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __STRCMP_IA32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __STRCMP_SSSE3, %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features +- jz 2f +- leal __STRCMP_SSE4_2, %eax ++ LOAD_FUNC_GOT_EAX (__STRCMP_SSE4_2) + 2: ret + END(STRCMP) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcpy.S +@@ -61,52 +61,22 @@ + need strncpy before the initialization happened. */ + #if IS_IN (libc) + +-# ifdef SHARED + .text + ENTRY(STRCPY) + .type STRCPY, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal STRCPY_IA32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (STRCPY_IA32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal STRCPY_SSE2@GOTOFF(%ebx), %eax +- testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (STRCPY_SSE2) ++ HAS_ARCH_FEATURE (Fast_Unaligned_Load) + jnz 2f +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal STRCPY_SSSE3@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(STRCPY) +-# else +- +-ENTRY(STRCPY) +- .type STRCPY, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal STRCPY_IA32, %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features +- jz 2f +- leal STRCPY_SSE2, %eax +- testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features +- jnz 2f +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal STRCPY_SSSE3, %eax ++ LOAD_FUNC_GOT_EAX (STRCPY_SSSE3) + 2: ret + END(STRCPY) + +-# endif +- + # undef ENTRY + # define ENTRY(name) \ + .type STRCPY_IA32, @function; \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strcspn.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strcspn.S +@@ -42,40 +42,16 @@ + define multiple versions for strpbrk in static library since we + need strpbrk before the initialization happened. */ + #if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(STRCSPN) + .type STRCSPN, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal STRCSPN_IA32@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (STRCSPN_IA32) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal STRCSPN_SSE42@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret +-END(STRCSPN) +-# else +- .text +-ENTRY(STRCSPN) +- .type STRCSPN, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal STRCSPN_IA32, %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features +- jz 2f +- leal STRCSPN_SSE42, %eax ++ LOAD_FUNC_GOT_EAX (STRCSPN_SSE42) + 2: ret + END(STRCSPN) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strlen.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strlen.S +@@ -28,24 +28,15 @@ + .text + ENTRY(strlen) + .type strlen, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strlen_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strlen_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __strlen_sse2_bsf@GOTOFF(%ebx), %eax +- testl $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__strlen_sse2_bsf) ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 2f +- leal __strlen_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__strlen_sse2) ++2: ret + END(strlen) + + # undef ENTRY +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strncase.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strncase.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strncase.S +@@ -20,48 +20,18 @@ + #include + #include + +-#ifdef SHARED + .text + ENTRY(__strncasecmp) + .type __strncasecmp, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strncasecmp_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strncasecmp_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __strncasecmp_ssse3@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__strncasecmp_ssse3) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal __strncasecmp_sse4_2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret +-END(__strncasecmp) +-#else +- .text +-ENTRY(__strncasecmp) +- .type __strncasecmp, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __strncasecmp_ia32, %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features +- jz 2f +- leal __strncasecmp_ssse3, %eax +-#if 0 +- // XXX Temporarily +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features +- jz 2f +- leal __strncasecmp_sse4_2, %eax +-#endif ++ LOAD_FUNC_GOT_EAX (__strncasecmp_sse4_2) + 2: ret + END(__strncasecmp) +-#endif + + weak_alias (__strncasecmp, strncasecmp) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strnlen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strnlen.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strnlen.S +@@ -25,21 +25,12 @@ + .text + ENTRY(__strnlen) + .type __strnlen, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strnlen_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strnlen_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __strnlen_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__strnlen_sse2) ++2: ret + END(__strnlen) + + weak_alias(__strnlen, strnlen) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strrchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strrchr.S +@@ -25,24 +25,15 @@ + .text + ENTRY(strrchr) + .type strrchr, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strrchr_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strrchr_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __strrchr_sse2_bsf@GOTOFF(%ebx), %eax +- testl $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__strrchr_sse2_bsf) ++ HAS_ARCH_FEATURE (Slow_BSF) + jz 2f +- leal __strrchr_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__strrchr_sse2) ++2: ret + END(strrchr) + + # undef ENTRY +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strspn.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strspn.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strspn.S +@@ -27,40 +27,16 @@ + + /* Define multiple versions only for the definition in libc. */ + #if IS_IN (libc) +-# ifdef SHARED + .text + ENTRY(strspn) + .type strspn, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __strspn_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__strspn_ia32) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal __strspn_sse42@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret +-END(strspn) +-# else +- .text +-ENTRY(strspn) +- .type strspn, @gnu_indirect_function +- cmpl $0, KIND_OFFSET+__cpu_features +- jne 1f +- call __init_cpu_features +-1: leal __strspn_ia32, %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features +- jz 2f +- leal __strspn_sse42, %eax ++ LOAD_FUNC_GOT_EAX (__strspn_sse42) + 2: ret + END(strspn) +-# endif + + # undef ENTRY + # define ENTRY(name) \ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcschr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcschr.S +@@ -25,20 +25,11 @@ + .text + ENTRY(wcschr) + .type wcschr, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __wcschr_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__wcschr_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __wcschr_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__wcschr_sse2) ++2: ret + END(wcschr) + #endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscmp.S +@@ -28,20 +28,11 @@ + .text + ENTRY(wcscmp) + .type wcscmp, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __wcscmp_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__wcscmp_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __wcscmp_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__wcscmp_sse2) ++2: ret + END(wcscmp) + #endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcscpy.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcscpy.S +@@ -26,20 +26,11 @@ + .text + ENTRY(wcscpy) + .type wcscpy, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __wcscpy_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__wcscpy_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __wcscpy_ssse3@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__wcscpy_ssse3) ++2: ret + END(wcscpy) + #endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcslen.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcslen.S +@@ -25,21 +25,12 @@ + .text + ENTRY(__wcslen) + .type __wcslen, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __wcslen_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__wcslen_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __wcslen_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__wcslen_sse2) ++2: ret + END(__wcslen) + + weak_alias(__wcslen, wcslen) +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wcsrchr.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wcsrchr.S +@@ -25,20 +25,11 @@ + .text + ENTRY(wcsrchr) + .type wcsrchr, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __wcsrchr_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__wcsrchr_ia32) ++ HAS_CPU_FEATURE (SSE2) + jz 2f +- leal __wcsrchr_sse2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4); +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__wcsrchr_sse2) ++2: ret + END(wcsrchr) + #endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wmemcmp.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/wmemcmp.S ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/wmemcmp.S +@@ -27,23 +27,14 @@ + .text + ENTRY(wmemcmp) + .type wmemcmp, @gnu_indirect_function +- pushl %ebx +- cfi_adjust_cfa_offset (4) +- cfi_rel_offset (ebx, 0) +- LOAD_PIC_REG(bx) +- cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) +- jne 1f +- call __init_cpu_features +-1: leal __wmemcmp_ia32@GOTOFF(%ebx), %eax +- testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) ++ LOAD_GOT_AND_RTLD_GLOBAL_RO ++ LOAD_FUNC_GOT_EAX (__wmemcmp_ia32) ++ HAS_CPU_FEATURE (SSSE3) + jz 2f +- leal __wmemcmp_ssse3@GOTOFF(%ebx), %eax +- testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) ++ LOAD_FUNC_GOT_EAX (__wmemcmp_ssse3) ++ HAS_CPU_FEATURE (SSE4_2) + jz 2f +- leal __wmemcmp_sse4_2@GOTOFF(%ebx), %eax +-2: popl %ebx +- cfi_adjust_cfa_offset (-4) +- cfi_restore (ebx) +- ret ++ LOAD_FUNC_GOT_EAX (__wmemcmp_sse4_2) ++2: ret + END(wmemcmp) + #endif +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/strstr-c.c ++++ glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/strstr-c.c +@@ -24,7 +24,7 @@ extern __typeof (__redirect_strstr) __st + ifunc symbol properly. */ + extern __typeof (__redirect_strstr) __libc_strstr; + libc_ifunc (__libc_strstr, +- HAS_SSE4_2 && !use_unaligned_strstr () ? ++ HAS_CPU_FEATURE (SSE4_2) && !use_unaligned_strstr () ? + __strstr_sse42 : __strstr_ia32) + + #undef strstr diff --git a/SOURCES/glibc-rh1292018-4.patch b/SOURCES/glibc-rh1292018-4.patch new file mode 100644 index 00000000..54e049ef --- /dev/null +++ b/SOURCES/glibc-rh1292018-4.patch @@ -0,0 +1,41 @@ +commit 37dd6a19ca36b84cdef7e51dffcb68a2cbf54a6a +Author: Siddhesh Poyarekar +Date: Fri Aug 14 05:30:17 2015 -0700 + + Remove incorrect register mov in floorf/nearbyint on x86_64 + + The change in 0b5395f052ee09cd7e3d219af4e805c38058afb5 replaced calls + to __get_cpu_features@plt followed by a mov from rax to rdx, with a + single macro LOAD_RTLD_GLOBAL_RO_RDX. It is pretty clear that there + was a typo in s_floorf and __nearbyint due to which the (now incorrect) + mov was not removed. This patch removes that mov. + + * sysdeps/x86_64/fpu/multiarch/s_floorf.S (__floorf): Remove + unnecessary movq. + * sysdeps/x86_64/fpu/multiarch/s_nearbyint.S (__nearbyint): + Likewise. + +diff --git a/sysdeps/x86_64/fpu/multiarch/s_floorf.S b/sysdeps/x86_64/fpu/multiarch/s_floorf.S +index f60f662..9d67847 100644 +--- a/sysdeps/x86_64/fpu/multiarch/s_floorf.S ++++ b/sysdeps/x86_64/fpu/multiarch/s_floorf.S +@@ -23,7 +23,6 @@ + ENTRY(__floorf) + .type __floorf, @gnu_indirect_function + LOAD_RTLD_GLOBAL_RO_RDX +- movq %rax, %rdx + leaq __floorf_sse41(%rip), %rax + HAS_CPU_FEATURE (SSE4_1) + jnz 2f +diff --git a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S +index 109395c..2c13024 100644 +--- a/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S ++++ b/sysdeps/x86_64/fpu/multiarch/s_nearbyint.S +@@ -23,7 +23,6 @@ + ENTRY(__nearbyint) + .type __nearbyint, @gnu_indirect_function + LOAD_RTLD_GLOBAL_RO_RDX +- movq %rax, %rdx + leaq __nearbyint_sse41(%rip), %rax + HAS_CPU_FEATURE (SSE4_1) + jnz 2f diff --git a/SOURCES/glibc-rh1292018-5.patch b/SOURCES/glibc-rh1292018-5.patch new file mode 100644 index 00000000..f4d7dff0 --- /dev/null +++ b/SOURCES/glibc-rh1292018-5.patch @@ -0,0 +1,26 @@ +commit c9afcaaafaf9126a973883528eed8d0058a264c0 +Author: H.J. Lu +Date: Tue Dec 15 11:46:54 2015 -0800 + + Enable Silvermont optimizations for Knights Landing + + Knights Landing processor is based on Silvermont. This patch enables + Silvermont optimizations for Knights Landing. + + * sysdeps/x86/cpu-features.c (init_cpu_features): Enable + Silvermont optimizations for Knights Landing. + +diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c +index fba3ef0..aff894c 100644 +--- a/sysdeps/x86/cpu-features.c ++++ b/sysdeps/x86/cpu-features.c +@@ -78,6 +78,9 @@ init_cpu_features (struct cpu_features *cpu_features) + cpu_features->feature[index_Slow_BSF] |= bit_Slow_BSF; + break; + ++ case 0x57: ++ /* Knights Landing. Enable Silvermont optimizations. */ ++ + case 0x37: + case 0x4a: + case 0x4d: diff --git a/SOURCES/glibc-rh1292018-6.patch b/SOURCES/glibc-rh1292018-6.patch new file mode 100644 index 00000000..bb0b61fd --- /dev/null +++ b/SOURCES/glibc-rh1292018-6.patch @@ -0,0 +1,188 @@ +commit b9eb92ab05204df772eb4929eccd018637c9f3e9 +Author: H.J. Lu +Date: Wed Oct 21 14:44:23 2015 -0700 + + Add Prefer_MAP_32BIT_EXEC to map executable pages with MAP_32BIT + + According to Silvermont software optimization guide, for 64-bit + applications, branch prediction performance can be negatively impacted + when the target of a branch is more than 4GB away from the branch. Add + the Prefer_MAP_32BIT_EXEC bit so that mmap will try to map executable + pages with MAP_32BIT first. NB: MAP_32BIT will map to lower 2GB, not + lower 4GB, address. Prefer_MAP_32BIT_EXEC reduces bits available for + address space layout randomization (ASLR), which is always disabled for + SUID programs and can only be enabled by setting environment variable, + LD_PREFER_MAP_32BIT_EXEC. + + On Fedora 23, this patch speeds up GCC 5 testsuite by 3% on Silvermont. + + [BZ #19367] + * sysdeps/unix/sysv/linux/wordsize-64/mmap.c: New file. + * sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h: Likewise. + * sysdeps/unix/sysv/linux/x86_64/64/mmap.c: Likewise. + * sysdeps/x86/cpu-features.h (bit_Prefer_MAP_32BIT_EXEC): New. + (index_Prefer_MAP_32BIT_EXEC): Likewise. + +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/wordsize-64/mmap.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/wordsize-64/mmap.c +@@ -0,0 +1,40 @@ ++/* Linux mmap system call. 64-bit version. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* An architecture may override this. */ ++#ifndef MMAP_PREPARE ++# define MMAP_PREPARE(addr, len, prot, flags, fd, offset) ++#endif ++ ++__ptr_t ++__mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset) ++{ ++ MMAP_PREPARE (addr, len, prot, flags, fd, offset); ++ return (__ptr_t) INLINE_SYSCALL (mmap, 6, addr, len, prot, flags, ++ fd, offset); ++} ++ ++weak_alias (__mmap, mmap) ++weak_alias (__mmap, mmap64) ++weak_alias (__mmap, __mmap64) +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +@@ -0,0 +1,44 @@ ++/* Optional code to distinguish library flavours. x86-64 version. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _DL_LIBRECON_H ++ ++#include ++ ++/* Recognizing extra environment variables. For 64-bit applications, ++ branch prediction performance may be negatively impacted when the ++ target of a branch is more than 4GB away from the branch. Add the ++ Prefer_MAP_32BIT_EXEC bit so that mmap will try to map executable ++ pages with MAP_32BIT first. NB: MAP_32BIT will map to lower 2GB, ++ not lower 4GB, address. Prefer_MAP_32BIT_EXEC reduces bits available ++ for address space layout randomization (ASLR). Prefer_MAP_32BIT_EXEC ++ is always disabled for SUID programs and can be enabled by setting ++ environment variable, LD_PREFER_MAP_32BIT_EXEC. */ ++#define EXTRA_LD_ENVVARS \ ++ case 21: \ ++ if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ ++ GLRO(dl_x86_cpu_features).feature[index_Prefer_MAP_32BIT_EXEC] \ ++ = bit_Prefer_MAP_32BIT_EXEC; \ ++ break; ++ ++/* Extra unsecure variables. The names are all stuffed in a single ++ string which means they have to be terminated with a '\0' explicitly. */ ++#define EXTRA_UNSECURE_ENVVARS \ ++ "LD_PREFER_MAP_32BIT_EXEC\0" ++ ++#endif /* dl-librecon.h */ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/mmap.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/x86_64/64/mmap.c +@@ -0,0 +1,37 @@ ++/* Linux mmap system call. x86-64 version. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* If the Prefer_MAP_32BIT_EXEC bit is set, try to map executable pages ++ with MAP_32BIT first. */ ++#define MMAP_PREPARE(addr, len, prot, flags, fd, offset) \ ++ if ((addr) == NULL \ ++ && ((prot) & PROT_EXEC) != 0 \ ++ && HAS_ARCH_FEATURE (Prefer_MAP_32BIT_EXEC)) \ ++ { \ ++ __ptr_t ret = (__ptr_t) INLINE_SYSCALL (mmap, 6, (addr), (len), \ ++ (prot), \ ++ (flags) | MAP_32BIT, \ ++ (fd), (offset)); \ ++ if (ret != MAP_FAILED) \ ++ return ret; \ ++ } ++ ++#include +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.h ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +@@ -32,6 +32,7 @@ + #define bit_AVX_Fast_Unaligned_Load (1 << 11) + #define bit_AVX512F_Usable (1 << 12) + #define bit_AVX512DQ_Usable (1 << 13) ++#define bit_Prefer_MAP_32BIT_EXEC (1 << 16) + + /* CPUID Feature flags. */ + +@@ -91,6 +92,7 @@ + # define index_AVX_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE + # define index_AVX512F_Usable FEATURE_INDEX_1*FEATURE_SIZE + # define index_AVX512DQ_Usable FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1*FEATURE_SIZE + + # if defined (_LIBC) && !IS_IN (nonlib) + # ifdef __x86_64__ +@@ -267,6 +269,7 @@ extern const struct cpu_features *__get_ + # define index_AVX_Fast_Unaligned_Load FEATURE_INDEX_1 + # define index_AVX512F_Usable FEATURE_INDEX_1 + # define index_AVX512DQ_Usable FEATURE_INDEX_1 ++# define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1 + + #endif /* !__ASSEMBLER__ */ diff --git a/SOURCES/glibc-rh1292018-7.patch b/SOURCES/glibc-rh1292018-7.patch new file mode 100644 index 00000000..1bf5ea19 --- /dev/null +++ b/SOURCES/glibc-rh1292018-7.patch @@ -0,0 +1,26 @@ +commit a4754272958a8368701bb2a8d6b0c224fe3b4e73 +Author: H.J. Lu +Date: Thu Mar 3 14:51:40 2016 -0800 + + Or bit_Prefer_MAP_32BIT_EXEC in EXTRA_LD_ENVVARS + + We should turn on bit_Prefer_MAP_32BIT_EXEC in EXTRA_LD_ENVVARS without + overriding other bits. + + [BZ #19758] + * sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h + (EXTRA_LD_ENVVARS): Or bit_Prefer_MAP_32BIT_EXEC. + +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +index c9db5ea..a759934 100644 +--- a/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h ++++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-librecon.h +@@ -33,7 +33,7 @@ + case 21: \ + if (memcmp (envline, "PREFER_MAP_32BIT_EXEC", 21) == 0) \ + GLRO(dl_x86_cpu_features).feature[index_Prefer_MAP_32BIT_EXEC] \ +- = bit_Prefer_MAP_32BIT_EXEC; \ ++ |= bit_Prefer_MAP_32BIT_EXEC; \ + break; + + /* Extra unsecure variables. The names are all stuffed in a single diff --git a/SOURCES/glibc-rh1293433.patch b/SOURCES/glibc-rh1293433.patch new file mode 100644 index 00000000..4aaaad78 --- /dev/null +++ b/SOURCES/glibc-rh1293433.patch @@ -0,0 +1,45 @@ +commit 5a9af6376d43b58c6545feb86002812a57956654 +Author: Florian Weimer +Date: Fri Sep 25 20:20:33 2015 +0200 + + Fix inconsistent passwd compensation in nss/bug17079.c + + It used to be common practice to have a statically linked shell for an + alternative root account, as in: + + root:x:0:0:root:/root:/bin/bash + toor:x:0:0:root recovery account:/root:/sbin/sash + + This causes problems with passwd NSS tests because a UID-based lookup + will only retrieve one of those entries. The original version of + nss/bug17079.c detected this, but failed to use this information later + on. + +diff --git a/nss/bug17079.c b/nss/bug17079.c +index 9846737..0249922 100644 +--- a/nss/bug17079.c ++++ b/nss/bug17079.c +@@ -72,7 +72,11 @@ init_test_items (void) + struct passwd *pwd2 = getpwuid (test_items[i].pw_uid); + if (pwd1 == NULL || !equal (pwd1, test_items + i) + || pwd2 == NULL || !equal (pwd2, test_items + i)) +- test_items[i].pw_name = NULL; ++ { ++ printf ("info: skipping user \"%s\", UID %ld due to inconsistency\n", ++ test_items[i].pw_name, (long) test_items[i].pw_uid); ++ test_items[i].pw_name = NULL; ++ } + else + found = true; + } +@@ -195,6 +199,10 @@ test_buffer_size (size_t buffer_size) + for (int i = 0; i < test_count; ++i) + for (size_t padding_size = 0; padding_size < 3; ++padding_size) + { ++ /* Skip entries with inconsistent name/UID lookups. */ ++ if (test_items[i].pw_name == NULL) ++ continue; ++ + test_one (test_items + i, buffer_size, '\0', padding_size); + if (padding_size > 0) + { diff --git a/SOURCES/glibc-rh1293916.patch b/SOURCES/glibc-rh1293916.patch new file mode 100644 index 00000000..db145e97 --- /dev/null +++ b/SOURCES/glibc-rh1293916.patch @@ -0,0 +1,201 @@ +commit 42d6443faf5e8b5c70474923bfcc021b77ee0095 +Author: Andreas Schwab +Date: Thu Jul 24 17:32:56 2014 +0200 + + Don't emit invalid extra shift character at block boundary by iconv (bug 17197) + +--- a/iconvdata/Makefile ++++ b/iconvdata/Makefile +@@ -67,7 +67,8 @@ + + ifeq (yes,$(build-shared)) + tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ +- tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 ++ tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ ++ bug-iconv10 + ifeq ($(have-thread-library),yes) + tests += bug-iconv3 + endif +@@ -286,6 +287,8 @@ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)bug-iconv5.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) ++$(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \ ++ $(addprefix $(objpfx),$(modules.so)) + $(objpfx)tst-loading.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)tst-iconv4.out: $(objpfx)gconv-modules \ + +diff --git a/iconvdata/bug-iconv10.c b/iconvdata/bug-iconv10.c +new file mode 100644 +index 0000000..98353a2 +--- /dev/null ++++ b/iconvdata/bug-iconv10.c +@@ -0,0 +1,77 @@ ++/* bug 17197: check for redundant shift character at block boundary. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ iconv_t cd = iconv_open ("IBM930", "UTF-8"); ++ if (cd == (iconv_t) -1) ++ { ++ puts ("iconv_open failed"); ++ return 1; ++ } ++ ++ char instr1[] = "\xc2\xa6."; ++ const char expstr1[4] = "\016Bj\017"; ++ const char expstr2[] = "K"; ++ char outstr[4]; ++ size_t inlen = sizeof (instr1); ++ size_t outlen = sizeof (outstr); ++ char *inptr = instr1; ++ char *outptr = outstr; ++ size_t r = iconv (cd, &inptr, &inlen, &outptr, &outlen); ++ if (r != -1 ++ || errno != E2BIG ++ || inlen != sizeof (instr1) - 2 ++ || inptr != instr1 + 2 ++ || outlen != 0 ++ || memcmp (outstr, expstr1, sizeof (expstr1)) != 0) ++ { ++ puts ("wrong first conversion"); ++ return 1; ++ } ++ ++ outlen = sizeof (outstr); ++ outptr = outstr; ++ r = iconv (cd, &inptr, &inlen, &outptr, &outlen); ++ if (r != 0 ++ || inlen != 0 ++ || outlen != sizeof (outstr) - sizeof (expstr2) ++ || memcmp (outstr, expstr2, sizeof (expstr2)) != 0) ++ { ++ puts ("wrong second conversion"); ++ return 1; ++ } ++ ++ if (iconv_close (cd) != 0) ++ { ++ puts ("iconv_close failed"); ++ return 1; ++ } ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- a/iconvdata/ibm930.c 2015-12-01 18:13:56.799658234 -0500 ++++ b/iconvdata/ibm930.c 2015-12-01 18:14:12.729906742 -0500 +@@ -257,6 +257,7 @@ enum + break; \ + } \ + *outptr++ = SI; \ ++ curcs = sb; \ + } \ + \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ +@@ -270,7 +271,6 @@ enum + *outptr++ = 0x5b; \ + else \ + *outptr++ = cp[0]; \ +- curcs = sb; \ + } \ + \ + /* Now that we wrote the output increment the input pointer. */ \ +--- a/iconvdata/ibm933.c 2015-12-01 18:13:56.799658234 -0500 ++++ b/iconvdata/ibm933.c 2015-12-01 18:14:12.729906742 -0500 +@@ -255,6 +255,7 @@ enum + break; \ + } \ + *outptr++ = SI; \ ++ curcs = sb; \ + } \ + \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ +@@ -263,7 +264,6 @@ enum + break; \ + } \ + *outptr++ = cp[0]; \ +- curcs = sb; \ + } \ + \ + /* Now that we wrote the output increment the input pointer. */ \ +--- a/iconvdata/ibm935.c 2015-12-01 18:13:56.799658234 -0500 ++++ b/iconvdata/ibm935.c 2015-12-01 18:14:12.729906742 -0500 +@@ -255,6 +255,7 @@ enum + break; \ + } \ + *outptr++ = SI; \ ++ curcs = sb; \ + } \ + \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ +@@ -263,7 +264,6 @@ enum + break; \ + } \ + *outptr++ = cp[0]; \ +- curcs = sb; \ + } \ + \ + /* Now that we wrote the output increment the input pointer. */ \ +--- a/iconvdata/ibm937.c 2015-12-01 18:13:56.799658234 -0500 ++++ b/iconvdata/ibm937.c 2015-12-01 18:14:12.729906742 -0500 +@@ -255,6 +255,7 @@ enum + break; \ + } \ + *outptr++ = SI; \ ++ curcs = sb; \ + } \ + \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ +@@ -263,7 +264,6 @@ enum + break; \ + } \ + *outptr++ = cp[0]; \ +- curcs = sb; \ + } \ + \ + /* Now that we wrote the output increment the input pointer. */ \ +--- a/iconvdata/ibm939.c 2015-12-01 18:13:56.799658234 -0500 ++++ b/iconvdata/ibm939.c 2015-12-01 18:14:12.739906898 -0500 +@@ -255,6 +255,7 @@ enum + break; \ + } \ + *outptr++ = SI; \ ++ curcs = sb; \ + } \ + \ + if (__builtin_expect (outptr + 1 > outend, 0)) \ +@@ -268,7 +269,6 @@ enum + *outptr++ = 0xb2; \ + else \ + *outptr++ = cp[0]; \ +- curcs = sb; \ + } \ + \ + /* Now that we wrote the output increment the input pointer. */ \ diff --git a/SOURCES/glibc-rh1293976-2.patch b/SOURCES/glibc-rh1293976-2.patch new file mode 100644 index 00000000..b638018f --- /dev/null +++ b/SOURCES/glibc-rh1293976-2.patch @@ -0,0 +1,551 @@ +Short description: malloc: Test various special cases related to allocation failures +Author(s): Florian Weimer +Origin: git://sourceware.org/git/glibc.git +Bug-RHEL: #1296453 (rhel-7.2.z), #1293976 (rhel-7.3), #1256285 (SRT), #1418978 +Bug-Fedora: NA +Bug-Upstream: #19469 +Upstream status: committed +# +# commit 1bd5483e104c8bde6e61dc5e3f8a848bc861872d +# Author: Florian Weimer +# Date: Tue Dec 29 20:32:35 2015 +0100 +# +# malloc: Test various special cases related to allocation failures +# +# This test case exercises unusual code paths in allocation functions, +# related to allocation failures. Specifically, the test can reveal +# the following bugs: +# +# (a) calloc returns non-zero memory on fallback to sysmalloc. +# (b) calloc can self-deadlock because it fails to release +# the arena lock on certain allocation failures. +# (c) pvalloc can dereference a NULL arena pointer. +# +# (a) and (b) appear specific to a faulty downstream backport. +# (c) was fixed as part of commit 10ad46bc6526edc5c7afcc57112da96917ff3629. +# +# commit f690b56979dea81340a397c1b5e44827a6fb06e7 +# Author: Florian Weimer +# Date: Tue Aug 2 17:01:02 2016 +0200 +# +# malloc: Run tests without calling mallopt [BZ #19469] +# +# The compiled tests no longer refer to the mallopt symbol +# from their main functions. (Some tests still call mallopt +# explicitly, which is fine.) + +Index: b/malloc/Makefile +=================================================================== +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -27,7 +27,8 @@ headers := $(dist-headers) obstack.h mch + tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \ + tst-malloc-usable \ +- tst-malloc-backtrace tst-malloc-thread-exit ++ tst-malloc-backtrace tst-malloc-thread-exit \ ++ tst-malloc-thread-fail + test-srcs = tst-mtrace + + routines = malloc morecore mcheck mtrace obstack +@@ -44,6 +45,8 @@ libmemusage-inhibit-o = $(filter-out .os + + $(objpfx)tst-malloc-backtrace: $(common-objpfx)nptl/libpthread.so \ + $(common-objpfx)nptl/libpthread_nonshared.a ++$(objpfx)tst-malloc-thread-fail: $(common-objpfx)nptl/libpthread.so \ ++ $(common-objpfx)nptl/libpthread_nonshared.a + $(objpfx)tst-malloc-thread-exit: $(common-objpfx)nptl/libpthread.so \ + $(common-objpfx)nptl/libpthread_nonshared.a + +@@ -149,3 +152,7 @@ $(objpfx)libmemusage.so: $(common-objpfx + + # Extra dependencies + $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c ++ ++# Compile the tests with a flag which suppresses the mallopt call in ++# the test skeleton. ++$(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT +Index: b/malloc/tst-malloc-thread-fail.c +=================================================================== +--- /dev/null ++++ b/malloc/tst-malloc-thread-fail.c +@@ -0,0 +1,464 @@ ++/* Test allocation function behavior on allocation failure. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++/* This test case attempts to trigger various unusual conditions ++ related to allocation failures, notably switching to a different ++ arena, and falling back to mmap (via sysmalloc). */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* This mirrors the C11 max_align_t type provided by GCC, but it is ++ also available in C99 mode. The aligned attributes are required ++ because some ABIs have reduced alignment requirements for struct ++ and union members. */ ++typedef struct { ++ long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); ++ long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); ++} libc_max_align_t; ++ ++/* Wrapper for calloc with an optimization barrier. */ ++static void * ++__attribute__ ((noinline, noclone)) ++allocate_zeroed (size_t a, size_t b) ++{ ++ return calloc (a, b); ++} ++ ++/* System page size, as determined by sysconf (_SC_PAGE_SIZE). */ ++static unsigned long page_size; ++ ++/* Test parameters. */ ++static size_t allocation_size; ++static size_t alignment; ++static enum { ++ with_malloc, ++ with_realloc, ++ with_aligned_alloc, ++ with_memalign, ++ with_posix_memalign, ++ with_valloc, ++ with_pvalloc, ++ with_calloc, ++ last_allocation_function = with_calloc ++} allocation_function; ++ ++/* True if an allocation function uses the alignment test ++ parameter. */ ++const static bool alignment_sensitive[last_allocation_function + 1] = ++ { ++ [with_aligned_alloc] = true, ++ [with_memalign] = true, ++ [with_posix_memalign] = true, ++ }; ++ ++/* Combined pointer/expected alignment result of an allocation ++ function. */ ++struct allocate_result { ++ void *pointer; ++ size_t alignment; ++}; ++ ++/* Call the allocation function specified by allocation_function, with ++ allocation_size and alignment (if applicable) as arguments. No ++ alignment check. */ ++static struct allocate_result ++allocate_1 (void) ++{ ++ switch (allocation_function) ++ { ++ case with_malloc: ++ return (struct allocate_result) ++ {malloc (allocation_size), __alignof__ (libc_max_align_t)}; ++ case with_realloc: ++ { ++ void *p = realloc (NULL, 16); ++ void *q; ++ if (p == NULL) ++ q = NULL; ++ else ++ { ++ q = realloc (p, allocation_size); ++ if (q == NULL) ++ free (p); ++ } ++ return (struct allocate_result) {q, __alignof__ (libc_max_align_t)}; ++ } ++ case with_aligned_alloc: ++ { ++ void *p = aligned_alloc (alignment, allocation_size); ++ return (struct allocate_result) {p, alignment}; ++ } ++ case with_memalign: ++ { ++ void *p = memalign (alignment, allocation_size); ++ return (struct allocate_result) {p, alignment}; ++ } ++ case with_posix_memalign: ++ { ++ void *p; ++ if (posix_memalign (&p, alignment, allocation_size)) ++ { ++ if (errno == ENOMEM) ++ p = NULL; ++ else ++ { ++ printf ("error: posix_memalign (p, %zu, %zu): %m\n", ++ alignment, allocation_size); ++ abort (); ++ } ++ } ++ return (struct allocate_result) {p, alignment}; ++ } ++ case with_valloc: ++ { ++ void *p = valloc (allocation_size); ++ return (struct allocate_result) {p, page_size}; ++ } ++ case with_pvalloc: ++ { ++ void *p = pvalloc (allocation_size); ++ return (struct allocate_result) {p, page_size}; ++ } ++ case with_calloc: ++ { ++ char *p = allocate_zeroed (1, allocation_size); ++ /* Check for non-zero bytes. */ ++ if (p != NULL) ++ for (size_t i = 0; i < allocation_size; ++i) ++ if (p[i] != 0) ++ { ++ printf ("error: non-zero byte at offset %zu\n", i); ++ abort (); ++ } ++ return (struct allocate_result) {p, __alignof__ (libc_max_align_t)}; ++ } ++ } ++ abort (); ++} ++ ++/* Call allocate_1 and perform the alignment check on the result. */ ++static void * ++allocate (void) ++{ ++ struct allocate_result r = allocate_1 (); ++#if __powerpc__ == 1 && __powerpc64__ == 0 ++ /* Sourceware bug 6527 on 32-bit POWER. ++ Ignore 16-byte alignment requirement when using malloc, realloc, or ++ calloc, since these functions are known not to provide enough ++ alignment. */ ++ if ((((uintptr_t) r.pointer) & (r.alignment - 1)) != 0 ++ && !(r.alignment == 16 ++ && (allocation_function == with_malloc ++ || allocation_function == with_realloc ++ || allocation_function == with_calloc))) ++#else ++ if ((((uintptr_t) r.pointer) & (r.alignment - 1)) != 0) ++#endif ++ { ++ printf ("error: allocation function %d, size %zu not aligned to %zu\n", ++ (int) allocation_function, allocation_size, r.alignment); ++ abort (); ++ } ++ return r.pointer; ++} ++ ++/* Barriers to synchronize thread creation and termination. */ ++static pthread_barrier_t start_barrier; ++static pthread_barrier_t end_barrier; ++ ++/* Thread function which performs the allocation test. Called by ++ pthread_create and from the main thread. */ ++static void * ++allocate_thread (void *closure) ++{ ++ /* Wait for the creation of all threads. */ ++ { ++ int ret = pthread_barrier_wait (&start_barrier); ++ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_wait: %m\n"); ++ abort (); ++ } ++ } ++ ++ /* Allocate until we run out of memory, creating a single-linked ++ list. */ ++ struct list { ++ struct list *next; ++ }; ++ struct list *head = NULL; ++ while (true) ++ { ++ struct list *e = allocate (); ++ if (e == NULL) ++ break; ++ ++ e->next = head; ++ head = e; ++ } ++ ++ /* Wait for the allocation of all available memory. */ ++ { ++ int ret = pthread_barrier_wait (&end_barrier); ++ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_wait: %m\n"); ++ abort (); ++ } ++ } ++ ++ /* Free the allocated memory. */ ++ while (head != NULL) ++ { ++ struct list *next = head->next; ++ free (head); ++ head = next; ++ } ++ ++ return NULL; ++} ++ ++/* Number of threads (plus the main thread. */ ++enum { thread_count = 8 }; ++ ++/* Thread attribute to request creation of threads with a non-default ++ stack size which is rather small. This avoids interfering with the ++ configured address space limit. */ ++static pthread_attr_t small_stack; ++ ++/* Runs one test in multiple threads, all in a subprocess so that ++ subsequent tests do not interfere with each other. */ ++static void ++run_one (void) ++{ ++ /* Isolate the tests in a subprocess, so that we can start over ++ from scratch. */ ++ pid_t pid = fork (); ++ if (pid == 0) ++ { ++ /* In the child process. Create the allocation threads. */ ++ pthread_t threads[thread_count]; ++ ++ for (unsigned i = 0; i < thread_count; ++i) ++ { ++ int ret = pthread_create (threads + i, &small_stack, allocate_thread, NULL); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_create: %m\n"); ++ abort (); ++ } ++ } ++ ++ /* Also run the test on the main thread. */ ++ allocate_thread (NULL); ++ ++ for (unsigned i = 0; i < thread_count; ++i) ++ { ++ int ret = pthread_join (threads[i], NULL); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_join: %m\n"); ++ abort (); ++ } ++ } ++ _exit (0); ++ } ++ else if (pid < 0) ++ { ++ printf ("error: fork: %m\n"); ++ abort (); ++ } ++ ++ /* In the parent process. Wait for the child process to exit. */ ++ int status; ++ if (waitpid (pid, &status, 0) < 0) ++ { ++ printf ("error: waitpid: %m\n"); ++ abort (); ++ } ++ if (status != 0) ++ { ++ printf ("error: exit status %d from child process\n", status); ++ exit (1); ++ } ++} ++ ++/* Run all applicable allocation functions for the current test ++ parameters. */ ++static void ++run_allocation_functions (void) ++{ ++ for (int af = 0; af <= last_allocation_function; ++af) ++ { ++ /* Run alignment-sensitive functions for non-default ++ alignments. */ ++ if (alignment_sensitive[af] != (alignment != 0)) ++ continue; ++ allocation_function = af; ++ run_one (); ++ } ++} ++ ++int ++do_test (void) ++{ ++ /* Limit the number of malloc arenas. We use a very low number so ++ that despute the address space limit configured below, all ++ requested arenas a can be created. */ ++ if (mallopt (M_ARENA_MAX, 2) == 0) ++ { ++ printf ("error: mallopt (M_ARENA_MAX) failed\n"); ++ return 1; ++ } ++ ++ /* Determine the page size. */ ++ { ++ long ret = sysconf (_SC_PAGE_SIZE); ++ if (ret < 0) ++ { ++ printf ("error: sysconf (_SC_PAGE_SIZE): %m\n"); ++ return 1; ++ } ++ page_size = ret; ++ } ++ ++ /* Limit the size of the process, so that memory allocation in ++ allocate_thread will eventually fail, without impacting the ++ entire system. */ ++ { ++ struct rlimit limit; ++ if (getrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("getrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ long target = 200 * 1024 * 1024; ++ if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target) ++ { ++ limit.rlim_cur = target; ++ if (setrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("setrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ } ++ } ++ ++ /* Initialize thread attribute with a reduced stack size. */ ++ { ++ int ret = pthread_attr_init (&small_stack); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_attr_init: %m\n"); ++ abort (); ++ } ++ unsigned long stack_size = ((256 * 1024) / page_size) * page_size; ++ if (stack_size < 4 * page_size) ++ stack_size = 8 * page_size; ++ ret = pthread_attr_setstacksize (&small_stack, stack_size); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_attr_setstacksize: %m\n"); ++ abort (); ++ } ++ } ++ ++ /* Initialize the barriers. We run thread_count threads, plus 1 for ++ the main thread. */ ++ { ++ int ret = pthread_barrier_init (&start_barrier, NULL, thread_count + 1); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_init: %m\n"); ++ abort (); ++ } ++ ++ ret = pthread_barrier_init (&end_barrier, NULL, thread_count + 1); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_init: %m\n"); ++ abort (); ++ } ++ } ++ ++ allocation_size = 144; ++ run_allocation_functions (); ++ allocation_size = page_size; ++ run_allocation_functions (); ++ ++ alignment = 128; ++ allocation_size = 512; ++ run_allocation_functions (); ++ ++ allocation_size = page_size; ++ run_allocation_functions (); ++ ++ allocation_size = 17 * page_size; ++ run_allocation_functions (); ++ ++ /* Deallocation the barriers and the thread attribute. */ ++ { ++ int ret = pthread_barrier_destroy (&end_barrier); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_destroy: %m\n"); ++ return 1; ++ } ++ ret = pthread_barrier_destroy (&start_barrier); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_barrier_destroy: %m\n"); ++ return 1; ++ } ++ ret = pthread_attr_destroy (&small_stack); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_attr_destroy: %m\n"); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* The repeated allocations take some time on slow machines. */ ++#define TIMEOUT 20 ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: b/test-skeleton.c +=================================================================== +--- a/test-skeleton.c ++++ b/test-skeleton.c +@@ -247,8 +247,10 @@ main (int argc, char *argv[]) + unsigned int timeoutfactor = 1; + pid_t termpid; + ++#ifndef TEST_NO_MALLOPT + /* Make uses of freed and uninitialized memory known. */ + mallopt (M_PERTURB, 42); ++#endif + + #ifdef STDOUT_UNBUFFERED + setbuf (stdout, NULL); diff --git a/SOURCES/glibc-rh1293976.patch b/SOURCES/glibc-rh1293976.patch new file mode 100644 index 00000000..7b891f04 --- /dev/null +++ b/SOURCES/glibc-rh1293976.patch @@ -0,0 +1,140 @@ +Short description: CVE-2015-5220: calloc() returns non-zeroed memory. +Author(s): Ondrej Bilka +Origin: git://sourceware.org/git/glibc.git +Bug-RHEL: #1296453 (rhel-7.2.z), #1293976 (rhel-7.3), #1256285 (SRT) +Bug-Fedora: NA +Bug-Upstream: NA +Upstream status: committed +# +# commit e8349efd466cfedc0aa98be61d88ca8795c9e565 +# Author: Ondřej Bílka +# Date: Mon Dec 9 17:25:19 2013 +0100 +# +# Simplify perturb_byte logic. +# +diff --git a/malloc/malloc.c b/malloc/malloc.c +index 4821deb..ac8c3f6 100644 +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1870,8 +1870,20 @@ static int check_action = DEFAULT_CHECK_ACTION; + + static int perturb_byte; + +-#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n) +-#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n) ++static inline void ++alloc_perturb (char *p, size_t n) ++{ ++ if (__glibc_unlikely (perturb_byte)) ++ memset (p, perturb_byte ^ 0xff, n); ++} ++ ++static inline void ++free_perturb (char *p, size_t n) ++{ ++ if (__glibc_unlikely (perturb_byte)) ++ memset (p, perturb_byte, n); ++} ++ + + + #include +@@ -3287,8 +3299,7 @@ _int_malloc(mstate av, size_t bytes) + } + check_remalloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + } +@@ -3323,8 +3334,7 @@ _int_malloc(mstate av, size_t bytes) + victim->size |= NON_MAIN_ARENA; + check_malloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + } +@@ -3403,8 +3413,7 @@ _int_malloc(mstate av, size_t bytes) + + check_malloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + +@@ -3420,8 +3429,7 @@ _int_malloc(mstate av, size_t bytes) + victim->size |= NON_MAIN_ARENA; + check_malloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + +@@ -3545,8 +3553,7 @@ _int_malloc(mstate av, size_t bytes) + } + check_malloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + } +@@ -3649,8 +3656,7 @@ _int_malloc(mstate av, size_t bytes) + } + check_malloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + } +@@ -3684,8 +3690,7 @@ _int_malloc(mstate av, size_t bytes) + + check_malloced_chunk(av, victim, nb); + void *p = chunk2mem(victim); +- if (__builtin_expect (perturb_byte, 0)) +- alloc_perturb (p, bytes); ++ alloc_perturb (p, bytes); + return p; + } + +@@ -3705,7 +3710,7 @@ _int_malloc(mstate av, size_t bytes) + */ + else { + void *p = sysmalloc(nb, av); +- if (p != NULL && __builtin_expect (perturb_byte, 0)) ++ if (p != NULL) + alloc_perturb (p, bytes); + return p; + } +@@ -3798,8 +3803,7 @@ _int_free(mstate av, mchunkptr p, int have_lock) + } + } + +- if (__builtin_expect (perturb_byte, 0)) +- free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); ++ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); + + set_fastchunks(av); + unsigned int idx = fastbin_index(size); +@@ -3881,8 +3885,7 @@ _int_free(mstate av, mchunkptr p, int have_lock) + goto errout; + } + +- if (__builtin_expect (perturb_byte, 0)) +- free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); ++ free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); + + /* consolidate backward */ + if (!prev_inuse(p)) { diff --git a/SOURCES/glibc-rh1296031-0.patch b/SOURCES/glibc-rh1296031-0.patch new file mode 100644 index 00000000..7fcf297a --- /dev/null +++ b/SOURCES/glibc-rh1296031-0.patch @@ -0,0 +1,461 @@ +Sourceware bug 16574 + +commit d668061994a7486a3ba9c7d5e7882d85a2883707 +Author: Andreas Schwab +Date: Thu Feb 13 11:01:57 2014 +0100 + + Fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer + +commit ab7ac0f2cf8731fe4c3f3aea6088a7c0127b5725 +Author: Ondřej Bílka +Date: Sun Feb 16 12:59:23 2014 +0100 + + Deduplicate resolv/nss_dns/dns-host.c + + In resolv/nss_dns/dns-host.c one of code path duplicated code after + that. We merge these paths. + +commit ab09bf616ad527b249aca5f2a4956fd526f0712f +Author: Andreas Schwab +Date: Tue Feb 18 10:57:25 2014 +0100 + + Properly fix memory leak in _nss_dns_gethostbyname4_r with big DNS answer + + Instead of trying to guess whether the second buffer needs to be freed + set a flag at the place it is allocated + +Index: glibc-2.17-c758a686/include/resolv.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/resolv.h ++++ glibc-2.17-c758a686/include/resolv.h +@@ -56,11 +56,11 @@ libc_hidden_proto (__res_randomid) + libc_hidden_proto (__res_state) + + int __libc_res_nquery (res_state, const char *, int, int, u_char *, int, +- u_char **, u_char **, int *, int *); ++ u_char **, u_char **, int *, int *, int *); + int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int, +- u_char **, u_char **, int *, int *); ++ u_char **, u_char **, int *, int *, int *); + int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int, +- u_char *, int, u_char **, u_char **, int *, int *) ++ u_char *, int, u_char **, u_char **, int *, int *, int *) + attribute_hidden; + + libresolv_hidden_proto (_sethtent) +Index: glibc-2.17-c758a686/resolv/gethnamaddr.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/gethnamaddr.c ++++ glibc-2.17-c758a686/resolv/gethnamaddr.c +@@ -616,7 +616,7 @@ gethostbyname2(name, af) + buf.buf = origbuf = (querybuf *) alloca (1024); + + if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, +- &buf.ptr, NULL, NULL, NULL)) < 0) { ++ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { + if (buf.buf != origbuf) + free (buf.buf); + Dprintf("res_nsearch failed (%d)\n", n); +@@ -711,12 +711,12 @@ gethostbyaddr(addr, len, af) + buf.buf = orig_buf = (querybuf *) alloca (1024); + + n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, +- &buf.ptr, NULL, NULL, NULL); ++ &buf.ptr, NULL, NULL, NULL, NULL); + if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) { + strcpy(qp, "ip6.int"); + n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, + buf.buf != orig_buf ? MAXPACKET : 1024, +- &buf.ptr, NULL, NULL, NULL); ++ &buf.ptr, NULL, NULL, NULL, NULL); + } + if (n < 0) { + if (buf.buf != orig_buf) +Index: glibc-2.17-c758a686/resolv/nss_dns/dns-canon.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-canon.c ++++ glibc-2.17-c758a686/resolv/nss_dns/dns-canon.c +@@ -61,7 +61,7 @@ _nss_dns_getcanonname_r (const char *nam + { + int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i], + buf, sizeof (buf), &ansp.ptr, NULL, NULL, +- NULL); ++ NULL, NULL); + if (r > 0) + { + /* We need to decode the response. Just one question record. +Index: glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-host.c ++++ glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +@@ -190,7 +190,7 @@ _nss_dns_gethostbyname3_r (const char *n + host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); + + n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, +- 1024, &host_buffer.ptr, NULL, NULL, NULL); ++ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); + if (n < 0) + { + switch (errno) +@@ -225,7 +225,7 @@ _nss_dns_gethostbyname3_r (const char *n + n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf, + host_buffer.buf != orig_host_buffer + ? MAXPACKET : 1024, &host_buffer.ptr, +- NULL, NULL, NULL); ++ NULL, NULL, NULL, NULL); + + if (n < 0) + { +@@ -308,13 +308,20 @@ _nss_dns_gethostbyname4_r (const char *n + u_char *ans2p = NULL; + int nans2p = 0; + int resplen2 = 0; ++ int ans2p_malloced = 0; + + int olderr = errno; + enum nss_status status; + int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, + host_buffer.buf->buf, 2048, &host_buffer.ptr, +- &ans2p, &nans2p, &resplen2); +- if (n < 0) ++ &ans2p, &nans2p, &resplen2, &ans2p_malloced); ++ if (n >= 0) ++ { ++ status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, ++ resplen2, name, pat, buffer, buflen, ++ errnop, herrnop, ttlp); ++ } ++ else + { + switch (errno) + { +@@ -341,16 +348,11 @@ _nss_dns_gethostbyname4_r (const char *n + *errnop = EAGAIN; + else + __set_errno (olderr); +- +- if (host_buffer.buf != orig_host_buffer) +- free (host_buffer.buf); +- +- return status; + } + +- status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p, +- resplen2, name, pat, buffer, buflen, +- errnop, herrnop, ttlp); ++ /* Check whether ans2p was separately allocated. */ ++ if (ans2p_malloced) ++ free (ans2p); + + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); +@@ -460,7 +462,7 @@ _nss_dns_gethostbyaddr2_r (const void *a + strcpy (qp, "].ip6.arpa"); + n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, + host_buffer.buf->buf, 1024, &host_buffer.ptr, +- NULL, NULL, NULL); ++ NULL, NULL, NULL, NULL); + if (n >= 0) + goto got_it_already; + } +@@ -481,14 +483,14 @@ _nss_dns_gethostbyaddr2_r (const void *a + } + + n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, +- 1024, &host_buffer.ptr, NULL, NULL, NULL); ++ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); + if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) + { + strcpy (qp, "ip6.int"); + n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, + host_buffer.buf != orig_host_buffer + ? MAXPACKET : 1024, &host_buffer.ptr, +- NULL, NULL, NULL); ++ NULL, NULL, NULL, NULL); + } + if (n < 0) + { +Index: glibc-2.17-c758a686/resolv/nss_dns/dns-network.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-network.c ++++ glibc-2.17-c758a686/resolv/nss_dns/dns-network.c +@@ -129,7 +129,7 @@ _nss_dns_getnetbyname_r (const char *nam + net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); + + anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, +- 1024, &net_buffer.ptr, NULL, NULL, NULL); ++ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + if (anslen < 0) + { + /* Nothing found. */ +@@ -205,7 +205,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i + net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); + + anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, +- 1024, &net_buffer.ptr, NULL, NULL, NULL); ++ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + if (anslen < 0) + { + /* Nothing found. */ +Index: glibc-2.17-c758a686/resolv/res_query.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/res_query.c ++++ glibc-2.17-c758a686/resolv/res_query.c +@@ -98,7 +98,7 @@ static int + __libc_res_nquerydomain(res_state statp, const char *name, const char *domain, + int class, int type, u_char *answer, int anslen, + u_char **answerp, u_char **answerp2, int *nanswerp2, +- int *resplen2); ++ int *resplen2, int *answerp2_malloced); + + /* + * Formulate a normal query, send, and await answer. +@@ -119,7 +119,8 @@ __libc_res_nquery(res_state statp, + u_char **answerp, /* if buffer needs to be enlarged */ + u_char **answerp2, + int *nanswerp2, +- int *resplen2) ++ int *resplen2, ++ int *answerp2_malloced) + { + HEADER *hp = (HEADER *) answer; + HEADER *hp2; +@@ -224,7 +225,8 @@ __libc_res_nquery(res_state statp, + } + assert (answerp == NULL || (void *) *answerp == (void *) answer); + n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer, +- anslen, answerp, answerp2, nanswerp2, resplen2); ++ anslen, answerp, answerp2, nanswerp2, resplen2, ++ answerp2_malloced); + if (use_malloc) + free (buf); + if (n < 0) { +@@ -316,7 +318,7 @@ res_nquery(res_state statp, + int anslen) /* size of answer buffer */ + { + return __libc_res_nquery(statp, name, class, type, answer, anslen, +- NULL, NULL, NULL, NULL); ++ NULL, NULL, NULL, NULL, NULL); + } + libresolv_hidden_def (res_nquery) + +@@ -335,7 +337,8 @@ __libc_res_nsearch(res_state statp, + u_char **answerp, + u_char **answerp2, + int *nanswerp2, +- int *resplen2) ++ int *resplen2, ++ int *answerp2_malloced) + { + const char *cp, * const *domain; + HEADER *hp = (HEADER *) answer; +@@ -360,7 +363,7 @@ __libc_res_nsearch(res_state statp, + if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL) + return (__libc_res_nquery(statp, cp, class, type, answer, + anslen, answerp, answerp2, +- nanswerp2, resplen2)); ++ nanswerp2, resplen2, answerp2_malloced)); + + #ifdef DEBUG + if (statp->options & RES_DEBUG) +@@ -377,7 +380,8 @@ __libc_res_nsearch(res_state statp, + if (dots >= statp->ndots || trailing_dot) { + ret = __libc_res_nquerydomain(statp, name, NULL, class, type, + answer, anslen, answerp, +- answerp2, nanswerp2, resplen2); ++ answerp2, nanswerp2, resplen2, ++ answerp2_malloced); + if (ret > 0 || trailing_dot + /* If the second response is valid then we use that. */ + || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) +@@ -388,11 +392,11 @@ __libc_res_nsearch(res_state statp, + answer = *answerp; + anslen = MAXPACKET; + } +- if (answerp2 +- && (*answerp2 < answer || *answerp2 >= answer + anslen)) ++ if (answerp2 && *answerp2_malloced) + { + free (*answerp2); + *answerp2 = NULL; ++ *answerp2_malloced = 0; + } + } + +@@ -419,7 +423,7 @@ __libc_res_nsearch(res_state statp, + class, type, + answer, anslen, answerp, + answerp2, nanswerp2, +- resplen2); ++ resplen2, answerp2_malloced); + if (ret > 0 || (ret == 0 && resplen2 != NULL + && *resplen2 > 0)) + return (ret); +@@ -428,12 +432,11 @@ __libc_res_nsearch(res_state statp, + answer = *answerp; + anslen = MAXPACKET; + } +- if (answerp2 +- && (*answerp2 < answer +- || *answerp2 >= answer + anslen)) ++ if (answerp2 && *answerp2_malloced) + { + free (*answerp2); + *answerp2 = NULL; ++ *answerp2_malloced = 0; + } + + /* +@@ -489,7 +492,8 @@ __libc_res_nsearch(res_state statp, + && !(tried_as_is || root_on_list)) { + ret = __libc_res_nquerydomain(statp, name, NULL, class, type, + answer, anslen, answerp, +- answerp2, nanswerp2, resplen2); ++ answerp2, nanswerp2, resplen2, ++ answerp2_malloced); + if (ret > 0 || (ret == 0 && resplen2 != NULL + && *resplen2 > 0)) + return (ret); +@@ -502,10 +506,11 @@ __libc_res_nsearch(res_state statp, + * else send back meaningless H_ERRNO, that being the one from + * the last DNSRCH we did. + */ +- if (answerp2 && (*answerp2 < answer || *answerp2 >= answer + anslen)) ++ if (answerp2 && *answerp2_malloced) + { + free (*answerp2); + *answerp2 = NULL; ++ *answerp2_malloced = 0; + } + if (saved_herrno != -1) + RES_SET_H_ERRNO(statp, saved_herrno); +@@ -525,7 +530,7 @@ res_nsearch(res_state statp, + int anslen) /* size of answer */ + { + return __libc_res_nsearch(statp, name, class, type, answer, +- anslen, NULL, NULL, NULL, NULL); ++ anslen, NULL, NULL, NULL, NULL, NULL); + } + libresolv_hidden_def (res_nsearch) + +@@ -543,7 +548,8 @@ __libc_res_nquerydomain(res_state statp, + u_char **answerp, + u_char **answerp2, + int *nanswerp2, +- int *resplen2) ++ int *resplen2, ++ int *answerp2_malloced) + { + char nbuf[MAXDNAME]; + const char *longname = nbuf; +@@ -585,7 +591,7 @@ __libc_res_nquerydomain(res_state statp, + } + return (__libc_res_nquery(statp, longname, class, type, answer, + anslen, answerp, answerp2, nanswerp2, +- resplen2)); ++ resplen2, answerp2_malloced)); + } + + int +@@ -597,7 +603,8 @@ res_nquerydomain(res_state statp, + int anslen) /* size of answer */ + { + return __libc_res_nquerydomain(statp, name, domain, class, type, +- answer, anslen, NULL, NULL, NULL, NULL); ++ answer, anslen, NULL, NULL, NULL, NULL, ++ NULL); + } + libresolv_hidden_def (res_nquerydomain) + +Index: glibc-2.17-c758a686/resolv/res_send.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/res_send.c ++++ glibc-2.17-c758a686/resolv/res_send.c +@@ -186,12 +186,12 @@ evNowTime(struct timespec *res) { + static int send_vc(res_state, const u_char *, int, + const u_char *, int, + u_char **, int *, int *, int, u_char **, +- u_char **, int *, int *); ++ u_char **, int *, int *, int *); + static int send_dg(res_state, const u_char *, int, + const u_char *, int, + u_char **, int *, int *, int, + int *, int *, u_char **, +- u_char **, int *, int *); ++ u_char **, int *, int *, int *); + #ifdef DEBUG + static void Aerror(const res_state, FILE *, const char *, int, + const struct sockaddr *); +@@ -343,7 +343,7 @@ int + __libc_res_nsend(res_state statp, const u_char *buf, int buflen, + const u_char *buf2, int buflen2, + u_char *ans, int anssiz, u_char **ansp, u_char **ansp2, +- int *nansp2, int *resplen2) ++ int *nansp2, int *resplen2, int *ansp2_malloced) + { + int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; + +@@ -546,7 +546,8 @@ __libc_res_nsend(res_state statp, const + try = statp->retry; + n = send_vc(statp, buf, buflen, buf2, buflen2, + &ans, &anssiz, &terrno, +- ns, ansp, ansp2, nansp2, resplen2); ++ ns, ansp, ansp2, nansp2, resplen2, ++ ansp2_malloced); + if (n < 0) + return (-1); + if (n == 0 && (buf2 == NULL || *resplen2 == 0)) +@@ -556,7 +557,7 @@ __libc_res_nsend(res_state statp, const + n = send_dg(statp, buf, buflen, buf2, buflen2, + &ans, &anssiz, &terrno, + ns, &v_circuit, &gotsomewhere, ansp, +- ansp2, nansp2, resplen2); ++ ansp2, nansp2, resplen2, ansp2_malloced); + if (n < 0) + return (-1); + if (n == 0 && (buf2 == NULL || *resplen2 == 0)) +@@ -646,7 +647,7 @@ res_nsend(res_state statp, + const u_char *buf, int buflen, u_char *ans, int anssiz) + { + return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz, +- NULL, NULL, NULL, NULL); ++ NULL, NULL, NULL, NULL, NULL); + } + libresolv_hidden_def (res_nsend) + +@@ -657,7 +658,7 @@ send_vc(res_state statp, + const u_char *buf, int buflen, const u_char *buf2, int buflen2, + u_char **ansp, int *anssizp, + int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2, +- int *resplen2) ++ int *resplen2, int *ansp2_malloced) + { + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; +@@ -823,6 +824,8 @@ send_vc(res_state statp, + } + *thisanssizp = MAXPACKET; + *thisansp = newp; ++ if (thisansp == ansp2) ++ *ansp2_malloced = 1; + anhp = (HEADER *) newp; + len = rlen; + } else { +@@ -992,7 +995,7 @@ send_dg(res_state statp, + const u_char *buf, int buflen, const u_char *buf2, int buflen2, + u_char **ansp, int *anssizp, + int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp, +- u_char **ansp2, int *anssizp2, int *resplen2) ++ u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced) + { + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; +@@ -1235,6 +1238,8 @@ send_dg(res_state statp, + if (newp != NULL) { + *anssizp = MAXPACKET; + *thisansp = ans = newp; ++ if (thisansp == ansp2) ++ *ansp2_malloced = 1; + } + } + HEADER *anhp = (HEADER *) *thisansp; diff --git a/SOURCES/glibc-rh1296031-2.patch b/SOURCES/glibc-rh1296031-2.patch new file mode 100644 index 00000000..54cb492a --- /dev/null +++ b/SOURCES/glibc-rh1296031-2.patch @@ -0,0 +1,38 @@ +commit 6b142b3a1d007d7e6f50c26710de7177bc4aca74 +Author: Andreas Schwab +Date: Mon Jun 8 15:21:18 2015 +0200 + + Record TTL also for DNS PTR queries (bug 18513) + + This allows nscd to manage proper TTL for GETHOSTBYADDR[v6] requests. + +2015-06-22 Andreas Schwab + + [BZ #18513] + * resolv/nss_dns/dns-host.c (getanswer_r): Record TTL also for + PTR queries. + +Index: glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/nss_dns/dns-host.c ++++ glibc-2.17-c758a686/resolv/nss_dns/dns-host.c +@@ -800,6 +800,10 @@ getanswer_r (const querybuf *answer, int + + if (qtype == T_PTR && type == T_CNAME) + { ++ /* A CNAME could also have a TTL entry. */ ++ if (ttlp != NULL && ttl < *ttlp) ++ *ttlp = ttl; ++ + n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); + if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0)) + { +@@ -863,6 +867,8 @@ getanswer_r (const querybuf *answer, int + ++had_error; + break; + } ++ if (ttlp != NULL && ttl < *ttlp) ++ *ttlp = ttl; + #if MULTI_PTRS_ARE_ALIASES + cp += n; + if (haveanswer == 0) diff --git a/SOURCES/glibc-rh1296031.patch b/SOURCES/glibc-rh1296031.patch new file mode 100644 index 00000000..ef62f96f --- /dev/null +++ b/SOURCES/glibc-rh1296031.patch @@ -0,0 +1,554 @@ +Upstream commit: + +commit e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca +Author: Carlos O'Donell +Date: Tue Feb 16 21:26:37 2016 -0500 + + CVE-2015-7547: getaddrinfo() stack-based buffer overflow (Bug 18665). + +Index: b/resolv/nss_dns/dns-host.c +=================================================================== +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -1051,7 +1051,10 @@ gaih_getanswer_slice (const querybuf *an + int h_namelen = 0; + + if (ancount == 0) +- return NSS_STATUS_NOTFOUND; ++ { ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; ++ } + + while (ancount-- > 0 && cp < end_of_message && had_error == 0) + { +@@ -1228,7 +1231,14 @@ gaih_getanswer_slice (const querybuf *an + /* Special case here: if the resolver sent a result but it only + contains a CNAME while we are looking for a T_A or T_AAAA record, + we fail with NOTFOUND instead of TRYAGAIN. */ +- return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND; ++ if (canon != NULL) ++ { ++ *h_errnop = HOST_NOT_FOUND; ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_TRYAGAIN; + } + + +@@ -1242,11 +1252,101 @@ gaih_getanswer (const querybuf *answer1, + + enum nss_status status = NSS_STATUS_NOTFOUND; + ++ /* Combining the NSS status of two distinct queries requires some ++ compromise and attention to symmetry (A or AAAA queries can be ++ returned in any order). What follows is a breakdown of how this ++ code is expected to work and why. We discuss only SUCCESS, ++ TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns ++ that apply (though RETURN and MERGE exist). We make a distinction ++ between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable). ++ A recoverable TRYAGAIN is almost always due to buffer size issues ++ and returns ERANGE in errno and the caller is expected to retry ++ with a larger buffer. ++ ++ Lastly, you may be tempted to make significant changes to the ++ conditions in this code to bring about symmetry between responses. ++ Please don't change anything without due consideration for ++ expected application behaviour. Some of the synthesized responses ++ aren't very well thought out and sometimes appear to imply that ++ IPv4 responses are always answer 1, and IPv6 responses are always ++ answer 2, but that's not true (see the implemetnation of send_dg ++ and send_vc to see response can arrive in any order, particlarly ++ for UDP). However, we expect it holds roughly enough of the time ++ that this code works, but certainly needs to be fixed to make this ++ a more robust implementation. ++ ++ ---------------------------------------------- ++ | Answer 1 Status / | Synthesized | Reason | ++ | Answer 2 Status | Status | | ++ |--------------------------------------------| ++ | SUCCESS/SUCCESS | SUCCESS | [1] | ++ | SUCCESS/TRYAGAIN | TRYAGAIN | [5] | ++ | SUCCESS/TRYAGAIN' | SUCCESS | [1] | ++ | SUCCESS/NOTFOUND | SUCCESS | [1] | ++ | SUCCESS/UNAVAIL | SUCCESS | [1] | ++ | TRYAGAIN/SUCCESS | TRYAGAIN | [2] | ++ | TRYAGAIN/TRYAGAIN | TRYAGAIN | [2] | ++ | TRYAGAIN/TRYAGAIN' | TRYAGAIN | [2] | ++ | TRYAGAIN/NOTFOUND | TRYAGAIN | [2] | ++ | TRYAGAIN/UNAVAIL | TRYAGAIN | [2] | ++ | TRYAGAIN'/SUCCESS | SUCCESS | [3] | ++ | TRYAGAIN'/TRYAGAIN | TRYAGAIN | [3] | ++ | TRYAGAIN'/TRYAGAIN' | TRYAGAIN' | [3] | ++ | TRYAGAIN'/NOTFOUND | TRYAGAIN' | [3] | ++ | TRYAGAIN'/UNAVAIL | UNAVAIL | [3] | ++ | NOTFOUND/SUCCESS | SUCCESS | [3] | ++ | NOTFOUND/TRYAGAIN | TRYAGAIN | [3] | ++ | NOTFOUND/TRYAGAIN' | TRYAGAIN' | [3] | ++ | NOTFOUND/NOTFOUND | NOTFOUND | [3] | ++ | NOTFOUND/UNAVAIL | UNAVAIL | [3] | ++ | UNAVAIL/SUCCESS | UNAVAIL | [4] | ++ | UNAVAIL/TRYAGAIN | UNAVAIL | [4] | ++ | UNAVAIL/TRYAGAIN' | UNAVAIL | [4] | ++ | UNAVAIL/NOTFOUND | UNAVAIL | [4] | ++ | UNAVAIL/UNAVAIL | UNAVAIL | [4] | ++ ---------------------------------------------- ++ ++ [1] If the first response is a success we return success. ++ This ignores the state of the second answer and in fact ++ incorrectly sets errno and h_errno to that of the second ++ answer. However because the response is a success we ignore ++ *errnop and *h_errnop (though that means you touched errno on ++ success). We are being conservative here and returning the ++ likely IPv4 response in the first answer as a success. ++ ++ [2] If the first response is a recoverable TRYAGAIN we return ++ that instead of looking at the second response. The ++ expectation here is that we have failed to get an IPv4 response ++ and should retry both queries. ++ ++ [3] If the first response was not a SUCCESS and the second ++ response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN, ++ or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the ++ result from the second response, otherwise the first responses ++ status is used. Again we have some odd side-effects when the ++ second response is NOTFOUND because we overwrite *errnop and ++ *h_errnop that means that a first answer of NOTFOUND might see ++ its *errnop and *h_errnop values altered. Whether it matters ++ in practice that a first response NOTFOUND has the wrong ++ *errnop and *h_errnop is undecided. ++ ++ [4] If the first response is UNAVAIL we return that instead of ++ looking at the second response. The expectation here is that ++ it will have failed similarly e.g. configuration failure. ++ ++ [5] Testing this code is complicated by the fact that truncated ++ second response buffers might be returned as SUCCESS if the ++ first answer is a SUCCESS. To fix this we add symmetry to ++ TRYAGAIN with the second response. If the second response ++ is a recoverable error we now return TRYAGIN even if the first ++ response was SUCCESS. */ ++ + if (anslen1 > 0) + status = gaih_getanswer_slice(answer1, anslen1, qname, + &pat, &buffer, &buflen, + errnop, h_errnop, ttlp, + &first); ++ + if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND + || (status == NSS_STATUS_TRYAGAIN + /* We want to look at the second answer in case of an +@@ -1262,8 +1362,15 @@ gaih_getanswer (const querybuf *answer1, + &pat, &buffer, &buflen, + errnop, h_errnop, ttlp, + &first); ++ /* Use the second response status in some cases. */ + if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) + status = status2; ++ /* Do not return a truncated second response (unless it was ++ unavoidable e.g. unrecoverable TRYAGAIN). */ ++ if (status == NSS_STATUS_SUCCESS ++ && (status2 == NSS_STATUS_TRYAGAIN ++ && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) ++ status = NSS_STATUS_TRYAGAIN; + } + + return status; +Index: b/resolv/res_query.c +=================================================================== +--- a/resolv/res_query.c ++++ b/resolv/res_query.c +@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp, + { + free (*answerp2); + *answerp2 = NULL; ++ *nanswerp2 = 0; + *answerp2_malloced = 0; + } + } +@@ -436,6 +437,7 @@ __libc_res_nsearch(res_state statp, + { + free (*answerp2); + *answerp2 = NULL; ++ *nanswerp2 = 0; + *answerp2_malloced = 0; + } + +@@ -510,6 +512,7 @@ __libc_res_nsearch(res_state statp, + { + free (*answerp2); + *answerp2 = NULL; ++ *nanswerp2 = 0; + *answerp2_malloced = 0; + } + if (saved_herrno != -1) +Index: b/resolv/res_send.c +=================================================================== +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1,3 +1,20 @@ ++/* Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1985, 1989, 1993 + * The Regents of the University of California. All rights reserved. +@@ -360,6 +377,8 @@ __libc_res_nsend(res_state statp, const + #ifdef USE_HOOKS + if (__builtin_expect (statp->qhook || statp->rhook, 0)) { + if (anssiz < MAXPACKET && ansp) { ++ /* Always allocate MAXPACKET, callers expect ++ this specific size. */ + u_char *buf = malloc (MAXPACKET); + if (buf == NULL) + return (-1); +@@ -653,6 +672,77 @@ libresolv_hidden_def (res_nsend) + + /* Private */ + ++/* The send_vc function is responsible for sending a DNS query over TCP ++ to the nameserver numbered NS from the res_state STATP i.e. ++ EXT(statp).nssocks[ns]. The function supports sending both IPv4 and ++ IPv6 queries at the same serially on the same socket. ++ ++ Please note that for TCP there is no way to disable sending both ++ queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP ++ and sends the queries serially and waits for the result after each ++ sent query. This implemetnation should be corrected to honour these ++ options. ++ ++ Please also note that for TCP we send both queries over the same ++ socket one after another. This technically violates best practice ++ since the server is allowed to read the first query, respond, and ++ then close the socket (to service another client). If the server ++ does this, then the remaining second query in the socket data buffer ++ will cause the server to send the client an RST which will arrive ++ asynchronously and the client's OS will likely tear down the socket ++ receive buffer resulting in a potentially short read and lost ++ response data. This will force the client to retry the query again, ++ and this process may repeat until all servers and connection resets ++ are exhausted and then the query will fail. It's not known if this ++ happens with any frequency in real DNS server implementations. This ++ implementation should be corrected to use two sockets by default for ++ parallel queries. ++ ++ The query stored in BUF of BUFLEN length is sent first followed by ++ the query stored in BUF2 of BUFLEN2 length. Queries are sent ++ serially on the same socket. ++ ++ Answers to the query are stored firstly in *ANSP up to a max of ++ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP ++ is non-NULL (to indicate that modifying the answer buffer is allowed) ++ then malloc is used to allocate a new response buffer and ANSCP and ++ ANSP will both point to the new buffer. If more than *ANSSIZP bytes ++ are needed but ANSCP is NULL, then as much of the response as ++ possible is read into the buffer, but the results will be truncated. ++ When truncation happens because of a small answer buffer the DNS ++ packets header feild TC will bet set to 1, indicating a truncated ++ message and the rest of the socket data will be read and discarded. ++ ++ Answers to the query are stored secondly in *ANSP2 up to a max of ++ *ANSSIZP2 bytes, with the actual response length stored in ++ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 ++ is non-NULL (required for a second query) then malloc is used to ++ allocate a new response buffer, *ANSSIZP2 is set to the new buffer ++ size and *ANSP2_MALLOCED is set to 1. ++ ++ The ANSP2_MALLOCED argument will eventually be removed as the ++ change in buffer pointer can be used to detect the buffer has ++ changed and that the caller should use free on the new buffer. ++ ++ Note that the answers may arrive in any order from the server and ++ therefore the first and second answer buffers may not correspond to ++ the first and second queries. ++ ++ It is not supported to call this function with a non-NULL ANSP2 ++ but a NULL ANSCP. Put another way, you can call send_vc with a ++ single unmodifiable buffer or two modifiable buffers, but no other ++ combination is supported. ++ ++ It is the caller's responsibility to free the malloc allocated ++ buffers by detecting that the pointers have changed from their ++ original values i.e. *ANSCP or *ANSP2 has changed. ++ ++ If errors are encountered then *TERRNO is set to an appropriate ++ errno value and a zero result is returned for a recoverable error, ++ and a less-than zero result is returned for a non-recoverable error. ++ ++ If no errors are encountered then *TERRNO is left unmodified and ++ a the length of the first response in bytes is returned. */ + static int + send_vc(res_state statp, + const u_char *buf, int buflen, const u_char *buf2, int buflen2, +@@ -662,11 +752,7 @@ send_vc(res_state statp, + { + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; +- u_char *ans = *ansp; +- int orig_anssizp = *anssizp; +- // XXX REMOVE +- // int anssiz = *anssizp; +- HEADER *anhp = (HEADER *) ans; ++ HEADER *anhp = (HEADER *) *ansp; + struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; + int truncating, connreset, resplen, n; + struct iovec iov[4]; +@@ -742,6 +828,8 @@ send_vc(res_state statp, + * Receive length & response + */ + int recvresp1 = 0; ++ /* Skip the second response if there is no second query. ++ To do that we mark the second response as received. */ + int recvresp2 = buf2 == NULL; + uint16_t rlen16; + read_len: +@@ -778,33 +866,14 @@ send_vc(res_state statp, + u_char **thisansp; + int *thisresplenp; + if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { ++ /* We have not received any responses ++ yet or we only have one response to ++ receive. */ + thisanssizp = anssizp; + thisansp = anscp ?: ansp; + assert (anscp != NULL || ansp2 == NULL); + thisresplenp = &resplen; + } else { +- if (*anssizp != MAXPACKET) { +- /* No buffer allocated for the first +- reply. We can try to use the rest +- of the user-provided buffer. */ +-#ifdef _STRING_ARCH_unaligned +- *anssizp2 = orig_anssizp - resplen; +- *ansp2 = *ansp + resplen; +-#else +- int aligned_resplen +- = ((resplen + __alignof__ (HEADER) - 1) +- & ~(__alignof__ (HEADER) - 1)); +- *anssizp2 = orig_anssizp - aligned_resplen; +- *ansp2 = *ansp + aligned_resplen; +-#endif +- } else { +- /* The first reply did not fit into the +- user-provided buffer. Maybe the second +- answer will. */ +- *anssizp2 = orig_anssizp; +- *ansp2 = *ansp; +- } +- + thisanssizp = anssizp2; + thisansp = ansp2; + thisresplenp = resplen2; +@@ -812,10 +881,14 @@ send_vc(res_state statp, + anhp = (HEADER *) *thisansp; + + *thisresplenp = rlen; +- if (rlen > *thisanssizp) { +- /* Yes, we test ANSCP here. If we have two buffers +- both will be allocatable. */ +- if (__builtin_expect (anscp != NULL, 1)) { ++ /* Is the answer buffer too small? */ ++ if (*thisanssizp < rlen) { ++ /* If the current buffer is non-NULL and it's not ++ pointing at the static user-supplied buffer then ++ we can reallocate it. */ ++ if (thisansp != NULL && thisansp != ansp) { ++ /* Always allocate MAXPACKET, callers expect ++ this specific size. */ + u_char *newp = malloc (MAXPACKET); + if (newp == NULL) { + *terrno = ENOMEM; +@@ -827,6 +900,9 @@ send_vc(res_state statp, + if (thisansp == ansp2) + *ansp2_malloced = 1; + anhp = (HEADER *) newp; ++ /* A uint16_t can't be larger than MAXPACKET ++ thus it's safe to allocate MAXPACKET but ++ read RLEN bytes instead. */ + len = rlen; + } else { + Dprint(statp->options & RES_DEBUG, +@@ -990,6 +1066,66 @@ reopen (res_state statp, int *terrno, in + return 1; + } + ++/* The send_dg function is responsible for sending a DNS query over UDP ++ to the nameserver numbered NS from the res_state STATP i.e. ++ EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries ++ along with the ability to send the query in parallel for both stacks ++ (default) or serially (RES_SINGLKUP). It also supports serial lookup ++ with a close and reopen of the socket used to talk to the server ++ (RES_SNGLKUPREOP) to work around broken name servers. ++ ++ The query stored in BUF of BUFLEN length is sent first followed by ++ the query stored in BUF2 of BUFLEN2 length. Queries are sent ++ in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP). ++ ++ Answers to the query are stored firstly in *ANSP up to a max of ++ *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP ++ is non-NULL (to indicate that modifying the answer buffer is allowed) ++ then malloc is used to allocate a new response buffer and ANSCP and ++ ANSP will both point to the new buffer. If more than *ANSSIZP bytes ++ are needed but ANSCP is NULL, then as much of the response as ++ possible is read into the buffer, but the results will be truncated. ++ When truncation happens because of a small answer buffer the DNS ++ packets header feild TC will bet set to 1, indicating a truncated ++ message, while the rest of the UDP packet is discarded. ++ ++ Answers to the query are stored secondly in *ANSP2 up to a max of ++ *ANSSIZP2 bytes, with the actual response length stored in ++ *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2 ++ is non-NULL (required for a second query) then malloc is used to ++ allocate a new response buffer, *ANSSIZP2 is set to the new buffer ++ size and *ANSP2_MALLOCED is set to 1. ++ ++ The ANSP2_MALLOCED argument will eventually be removed as the ++ change in buffer pointer can be used to detect the buffer has ++ changed and that the caller should use free on the new buffer. ++ ++ Note that the answers may arrive in any order from the server and ++ therefore the first and second answer buffers may not correspond to ++ the first and second queries. ++ ++ It is not supported to call this function with a non-NULL ANSP2 ++ but a NULL ANSCP. Put another way, you can call send_vc with a ++ single unmodifiable buffer or two modifiable buffers, but no other ++ combination is supported. ++ ++ It is the caller's responsibility to free the malloc allocated ++ buffers by detecting that the pointers have changed from their ++ original values i.e. *ANSCP or *ANSP2 has changed. ++ ++ If an answer is truncated because of UDP datagram DNS limits then ++ *V_CIRCUIT is set to 1 and the return value non-zero to indicate to ++ the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1 ++ if any progress was made reading a response from the nameserver and ++ is used by the caller to distinguish between ECONNREFUSED and ++ ETIMEDOUT (the latter if *GOTSOMEWHERE is 1). ++ ++ If errors are encountered then *TERRNO is set to an appropriate ++ errno value and a zero result is returned for a recoverable error, ++ and a less-than zero result is returned for a non-recoverable error. ++ ++ If no errors are encountered then *TERRNO is left unmodified and ++ a the length of the first response in bytes is returned. */ + static int + send_dg(res_state statp, + const u_char *buf, int buflen, const u_char *buf2, int buflen2, +@@ -999,8 +1135,6 @@ send_dg(res_state statp, + { + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; +- u_char *ans = *ansp; +- int orig_anssizp = *anssizp; + struct timespec now, timeout, finish; + struct pollfd pfd[1]; + int ptimeout; +@@ -1033,6 +1167,8 @@ send_dg(res_state statp, + int need_recompute = 0; + int nwritten = 0; + int recvresp1 = 0; ++ /* Skip the second response if there is no second query. ++ To do that we mark the second response as received. */ + int recvresp2 = buf2 == NULL; + pfd[0].fd = EXT(statp).nssocks[ns]; + pfd[0].events = POLLOUT; +@@ -1196,52 +1332,54 @@ send_dg(res_state statp, + int *thisresplenp; + + if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) { ++ /* We have not received any responses ++ yet or we only have one response to ++ receive. */ + thisanssizp = anssizp; + thisansp = anscp ?: ansp; + assert (anscp != NULL || ansp2 == NULL); + thisresplenp = &resplen; + } else { +- if (*anssizp != MAXPACKET) { +- /* No buffer allocated for the first +- reply. We can try to use the rest +- of the user-provided buffer. */ +-#ifdef _STRING_ARCH_unaligned +- *anssizp2 = orig_anssizp - resplen; +- *ansp2 = *ansp + resplen; +-#else +- int aligned_resplen +- = ((resplen + __alignof__ (HEADER) - 1) +- & ~(__alignof__ (HEADER) - 1)); +- *anssizp2 = orig_anssizp - aligned_resplen; +- *ansp2 = *ansp + aligned_resplen; +-#endif +- } else { +- /* The first reply did not fit into the +- user-provided buffer. Maybe the second +- answer will. */ +- *anssizp2 = orig_anssizp; +- *ansp2 = *ansp; +- } +- + thisanssizp = anssizp2; + thisansp = ansp2; + thisresplenp = resplen2; + } + + if (*thisanssizp < MAXPACKET +- /* Yes, we test ANSCP here. If we have two buffers +- both will be allocatable. */ +- && anscp ++ /* If the current buffer is non-NULL and it's not ++ pointing at the static user-supplied buffer then ++ we can reallocate it. */ ++ && (thisansp != NULL && thisansp != ansp) ++ /* Is the size too small? */ + && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0 +- || *thisanssizp < *thisresplenp)) { ++ || *thisanssizp < *thisresplenp) ++ ) { ++ /* Always allocate MAXPACKET, callers expect ++ this specific size. */ + u_char *newp = malloc (MAXPACKET); + if (newp != NULL) { +- *anssizp = MAXPACKET; +- *thisansp = ans = newp; ++ *thisanssizp = MAXPACKET; ++ *thisansp = newp; + if (thisansp == ansp2) + *ansp2_malloced = 1; + } + } ++ /* We could end up with truncation if anscp was NULL ++ (not allowed to change caller's buffer) and the ++ response buffer size is too small. This isn't a ++ reliable way to detect truncation because the ioctl ++ may be an inaccurate report of the UDP message size. ++ Therefore we use this only to issue debug output. ++ To do truncation accurately with UDP we need ++ MSG_TRUNC which is only available on Linux. We ++ can abstract out the Linux-specific feature in the ++ future to detect truncation. */ ++ if (__glibc_unlikely (*thisanssizp < *thisresplenp)) { ++ Dprint(statp->options & RES_DEBUG, ++ (stdout, ";; response may be truncated (UDP)\n") ++ ); ++ } ++ + HEADER *anhp = (HEADER *) *thisansp; + socklen_t fromlen = sizeof(struct sockaddr_in6); + assert (sizeof(from) <= fromlen); diff --git a/SOURCES/glibc-rh1296297-1.patch b/SOURCES/glibc-rh1296297-1.patch new file mode 100644 index 00000000..17af5e73 --- /dev/null +++ b/SOURCES/glibc-rh1296297-1.patch @@ -0,0 +1,201 @@ +Add --list-archive FILE support to localedef. + +This feature largely supports the integrated work +for InstLang support, and does not explicitly change +any help text or behaviour at the API level for these +routines. The basic purpose is to allow a file name to +propagate to through the internal APIs to be used instead +of the default locale archive. Given that build-locale-archive +links against copies of the internal API it can use these +non-public APIs without problem. + +Author: Carlos O'Donell +Date: Mon Feb 24 22:33:35 2014 -0500 + + Fix failure load locale template. + + The call to open_tmpl_archive was being passed a pointer to an + object allocated on the stack. The object on the stack is not + guaranteed to be initialized to zero so we need to minimally + initialize `fname' in the struct locarhandle to ensure that + open_tml_archive loads the default tempalte. + + This error was seen while debugging glibc installs in a qemu + VM where it is more likely the stack pages were dirty. It has + not been reported on non-VM systems. + +Author: Carlos O'Donell +Date: Fri Oct 18 23:27:45 2013 -0400 + + Allow fill_archive to be called with NULL fname. + + The fill_archive function should support being + called with a NULL fname argument. A NULL fname + argument indicates that the default archive should + be opened. We enable this by setting ah.fname to + NULL before initializing ah or calling open_archive. + This way if fname is NULL then ah.fname remains NULL + and open_archive opens the default archive. + +Author: Carlos O'Donell +Date: Thu Oct 3 05:22:51 2013 -0400 + +[snip] + - Support `--list-archive FILE' in localedef utility. + +This landed upstream in: + +commit 484c12fb1e3664fb434291234ea5787c5e3df4f5 +Author: Carlos O'Donell +Date: Fri Oct 18 23:41:30 2013 -0400 + + Enhance localedef --list-archive option. + + The localedef --list-archive option claims that it can + accept a [file] argument and list the contents of that + archive. The support was never implemented. This patch + adds that support and allows --list-archive to work as + expected. You can now use localedef to list the contents + of arbitrary locale archives by using: + ./localedef --list-archive file + +The defaultfname flag was removed there, see +. + +Index: glibc-2.17-c758a686/locale/locarchive.h +=================================================================== +--- glibc-2.17-c758a686.orig/locale/locarchive.h ++++ glibc-2.17-c758a686/locale/locarchive.h +@@ -80,6 +80,8 @@ struct locrecent + + struct locarhandle + { ++ /* Full path to the locale archive file. */ ++ const char *fname; + int fd; + void *addr; + size_t mmaped; +Index: glibc-2.17-c758a686/locale/programs/localedef.c +=================================================================== +--- glibc-2.17-c758a686.orig/locale/programs/localedef.c ++++ glibc-2.17-c758a686/locale/programs/localedef.c +@@ -202,7 +202,7 @@ main (int argc, char *argv[]) + + /* Handle a few special cases. */ + if (list_archive) +- show_archive_content (verbose); ++ show_archive_content (remaining > 1 ? argv[remaining] : NULL, verbose); + if (add_to_archive) + return add_locales_to_archive (argc - remaining, &argv[remaining], + replace_archive); +Index: glibc-2.17-c758a686/locale/programs/localedef.h +=================================================================== +--- glibc-2.17-c758a686.orig/locale/programs/localedef.h ++++ glibc-2.17-c758a686/locale/programs/localedef.h +@@ -176,7 +176,8 @@ extern int add_locales_to_archive (size_ + /* Removed named locales from archive. */ + extern int delete_locales_from_archive (size_t nlist, char *list[]); + +-/* List content of locale archive. */ +-extern void show_archive_content (int verbose) __attribute__ ((noreturn)); ++/* List content of locale archive. If FNAME is non-null use that as ++ the locale archive to list, otherwise the default. */ ++extern void show_archive_content (char *fname, int verbose) __attribute__ ((noreturn)); + + #endif /* localedef.h */ +Index: glibc-2.17-c758a686/locale/programs/locarchive.c +=================================================================== +--- glibc-2.17-c758a686.orig/locale/programs/locarchive.c ++++ glibc-2.17-c758a686/locale/programs/locarchive.c +@@ -197,6 +197,7 @@ create_archive (const char *archivefname + _("cannot change mode of new locale archive")); + } + ++ ah->fname = NULL; + ah->fd = fd; + ah->addr = p; + ah->mmaped = total; +@@ -519,11 +520,19 @@ open_archive (struct locarhandle *ah, bo + struct locarhead head; + int retry = 0; + size_t prefix_len = output_prefix ? strlen (output_prefix) : 0; +- char archivefname[prefix_len + sizeof (ARCHIVE_NAME)]; +- +- if (output_prefix) +- memcpy (archivefname, output_prefix, prefix_len); +- strcpy (archivefname + prefix_len, ARCHIVE_NAME); ++ char fname[prefix_len + sizeof (ARCHIVE_NAME)]; ++ char *archivefname = ah->fname; ++ bool defaultfname = false; ++ ++ /* If ah has a non-NULL fname open that otherwise open the default. */ ++ if (archivefname == NULL) ++ { ++ defaultfname = true; ++ archivefname = fname; ++ if (output_prefix) ++ memcpy (archivefname, output_prefix, prefix_len); ++ strcpy (archivefname + prefix_len, ARCHIVE_NAME); ++ } + + while (1) + { +@@ -531,8 +540,11 @@ open_archive (struct locarhandle *ah, bo + fd = open64 (archivefname, readonly ? O_RDONLY : O_RDWR); + if (fd == -1) + { +- /* Maybe the file does not yet exist. */ +- if (errno == ENOENT) ++ /* Maybe the file does not yet exist? If we are opening ++ the default locale archive we ignore the failure and ++ list an empty archive, otherwise we print an error ++ and exit. */ ++ if (errno == ENOENT && defaultfname) + { + if (readonly) + { +@@ -1258,6 +1270,7 @@ add_locales_to_archive (nlist, list, rep + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ ++ ah.fname = NULL; + open_archive (&ah, false); + + while (nlist-- > 0) +@@ -1457,6 +1470,7 @@ delete_locales_from_archive (nlist, list + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ ++ ah.fname = NULL; + open_archive (&ah, false); + + head = ah.addr; +@@ -1545,7 +1559,7 @@ dataentcmp (const void *a, const void *b + + + void +-show_archive_content (int verbose) ++show_archive_content (char *fname, int verbose) + { + struct locarhandle ah; + struct locarhead *head; +@@ -1555,6 +1569,7 @@ show_archive_content (int verbose) + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ ++ ah.fname = fname; + open_archive (&ah, true); + + head = ah.addr; +Index: glibc-2.17-c758a686/locale/programs/locfile.c +=================================================================== +--- glibc-2.17-c758a686.orig/locale/programs/locfile.c ++++ glibc-2.17-c758a686/locale/programs/locfile.c +@@ -337,6 +337,7 @@ write_all_categories (struct localedef_t + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ ++ ah.fname = NULL; + open_archive (&ah, false); + + if (add_locale_to_archive (&ah, locname, to_archive, true) != 0) diff --git a/SOURCES/glibc-rh1296297.patch b/SOURCES/glibc-rh1296297.patch new file mode 100644 index 00000000..50f3c468 --- /dev/null +++ b/SOURCES/glibc-rh1296297.patch @@ -0,0 +1,356 @@ +Adds --install-langs support build-locale-archive. + +commit 0457f649e3fe6299efe384da13dfc923bbe65707 +Author: Carlos O'Donell +Date: Thu Sep 17 12:24:49 2015 -0400 + +[snip] + - Fix --install-langs bug which causes SIGABRT (#1262040). + +commit 91764bd9ec690d4b8a886c0a3a104aac12d340d2 +Author: Carlos O'Donell +Date: Thu Mar 5 16:05:43 2015 -0500 + + Resolves: #156477 + + - Support installing only those locales specified by the RPM macro + %%_install_langs (#156477). + +Index: glibc-2.17-c758a686/releng/build-locale-archive.c +=================================================================== +--- glibc-2.17-c758a686.orig/releng/build-locale-archive.c ++++ glibc-2.17-c758a686/releng/build-locale-archive.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -21,6 +22,7 @@ const char *alias_file = DATADIR "/local + const char *locar_file = PREFIX "/lib/locale/locale-archive"; + const char *tmpl_file = PREFIX "/lib/locale/locale-archive.tmpl"; + const char *loc_path = PREFIX "/lib/locale/"; ++/* Flags set by `--verbose` option. */ + int be_quiet = 1; + int verbose = 0; + int max_locarchive_open_retry = 10; +@@ -96,7 +98,7 @@ open_tmpl_archive (struct locarhandle *a + struct stat64 st; + int fd; + struct locarhead head; +- const char *archivefname = tmpl_file; ++ const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname; + + /* Open the archive. We must have exclusive write access. */ + fd = open64 (archivefname, O_RDONLY); +@@ -116,7 +118,7 @@ open_tmpl_archive (struct locarhandle *a + ah->mmaped = (head.sumhash_offset + + head.sumhash_size * sizeof (struct sumhashent)); + if (ah->mmaped > (unsigned long) st.st_size) +- error (EXIT_FAILURE, 0, "locale archite template file truncated"); ++ error (EXIT_FAILURE, 0, "locale archive template file truncated"); + ah->mmaped = st.st_size; + ah->reserved = st.st_size; + +@@ -250,7 +252,10 @@ compute_data (struct locarhandle *ah, st + } + + static int +-fill_archive (struct locarhandle *tmpl_ah, size_t nlist, char *list[], ++fill_archive (struct locarhandle *tmpl_ah, ++ const char *fname, ++ size_t install_langs_count, char *install_langs_list[], ++ size_t nlist, char *list[], + const char *primary) + { + struct locarhandle ah; +@@ -281,11 +286,40 @@ fill_archive (struct locarhandle *tmpl_a + for (cnt = used = 0; cnt < head->namehash_size; ++cnt) + if (namehashtab[cnt].locrec_offset != 0) + { ++ char * name; ++ int i; + assert (used < head->namehash_used); +- names[used].name = tmpl_ah->addr + namehashtab[cnt].name_offset; +- names[used++].locrec +- = (struct locrecent *) ((char *) tmpl_ah->addr + +- namehashtab[cnt].locrec_offset); ++ name = tmpl_ah->addr + namehashtab[cnt].name_offset; ++ if (install_langs_count == 0) ++ { ++ /* Always intstall the entry. */ ++ names[used].name = name; ++ names[used++].locrec ++ = (struct locrecent *) ((char *) tmpl_ah->addr + ++ namehashtab[cnt].locrec_offset); ++ } ++ else ++ { ++ /* Only install the entry if the user asked for it via ++ --install-langs. */ ++ for (i = 0; i < install_langs_count; i++) ++ { ++ /* Add one for "_" and one for the null terminator. */ ++ size_t len = strlen (install_langs_list[i]) + 2; ++ char *install_lang = (char *)xmalloc (len); ++ strcpy (install_lang, install_langs_list[i]); ++ if (strchr (install_lang, '_') == NULL) ++ strcat (install_lang, "_"); ++ if (strncmp (name, install_lang, strlen (install_lang)) == 0) ++ { ++ names[used].name = name; ++ names[used++].locrec ++ = (struct locrecent *) ((char *)tmpl_ah->addr ++ + namehashtab[cnt].locrec_offset); ++ } ++ free (install_lang); ++ } ++ } + } + + /* Sort the names. */ +@@ -304,6 +338,9 @@ fill_archive (struct locarhandle *tmpl_a + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ ++ ah.fname = NULL; ++ if (fname != NULL) ++ ah.fname = fname; + open_archive (&ah, false); + + if (primary != NULL) +@@ -532,24 +569,197 @@ fill_archive (struct locarhandle *tmpl_a + return result; + } + +-int main () ++void usage() ++{ ++ printf ("\ ++Usage: build-locale-archive [OPTION]... [TEMPLATE-FILE] [ARCHIVE-FILE]\n\ ++ Builds a locale archive from a template file.\n\ ++ Options:\n\ ++ -h, --help Print this usage message.\n\ ++ -v, --verbose Verbose execution.\n\ ++ -l, --install-langs=LIST Only include locales given in LIST into the \n\ ++ locale archive. LIST is a colon separated list\n\ ++ of locale prefixes, for example \"de:en:ja\".\n\ ++ The special argument \"all\" means to install\n\ ++ all languages and it must be present by itself.\n\ ++ If \"all\" is present with any other language it\n\ ++ will be treated as the name of a locale.\n\ ++ If the --install-langs option is missing, all\n\ ++ locales are installed. The colon separated list\n\ ++ can contain any strings matching the beginning of\n\ ++ locale names.\n\ ++ If a string does not contain a \"_\", it is added.\n\ ++ Examples:\n\ ++ --install-langs=\"en\"\n\ ++ installs en_US, en_US.iso88591,\n\ ++ en_US.iso885915, en_US.utf8,\n\ ++ en_GB ...\n\ ++ --install-langs=\"en_US.utf8\"\n\ ++ installs only en_US.utf8.\n\ ++ --install-langs=\"ko\"\n\ ++ installs ko_KR, ko_KR.euckr,\n\ ++ ko_KR.utf8 but *not* kok_IN\n\ ++ because \"ko\" does not contain\n\ ++ \"_\" and it is silently added\n\ ++ --install-langs\"ko:kok\"\n\ ++ installs ko_KR, ko_KR.euckr,\n\ ++ ko_KR.utf8, kok_IN, and\n\ ++ kok_IN.utf8.\n\ ++ --install-langs=\"POSIX\" will\n\ ++ installs *no* locales at all\n\ ++ because POSIX matches none of\n\ ++ the locales. Actually, any string\n\ ++ matching nothing will do that.\n\ ++ POSIX and C will always be\n\ ++ available because they are\n\ ++ builtin.\n\ ++ Aliases are installed as well,\n\ ++ i.e. --install-langs=\"de\"\n\ ++ will install not only every locale starting with\n\ ++ \"de\" but also the aliases \"deutsch\"\n\ ++ and and \"german\" although the latter does not\n\ ++ start with \"de\".\n\ ++\n\ ++ If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\ ++ where the glibc used expects these files are used by default.\n\ ++"); ++} ++ ++int main (int argc, char *argv[]) + { + char path[4096]; + DIR *dirp; + struct dirent64 *d; + struct stat64 st; + char *list[16384], *primary; ++ char *lang; ++ int install_langs_count = 0; ++ int i; ++ char *install_langs_arg, *ila_start; ++ char **install_langs_list; + unsigned int cnt = 0; + struct locarhandle tmpl_ah; ++ char *new_locar_fname = NULL; + size_t loc_path_len = strlen (loc_path); + ++ while (1) ++ { ++ int c; ++ ++ static struct option long_options[] = ++ { ++ {"help", no_argument, 0, 'h'}, ++ {"verbose", no_argument, 0, 'v'}, ++ {"install-langs", required_argument, 0, 'l'}, ++ {0, 0, 0, 0} ++ }; ++ /* getopt_long stores the option index here. */ ++ int option_index = 0; ++ ++ c = getopt_long (argc, argv, "vhl:", ++ long_options, &option_index); ++ ++ /* Detect the end of the options. */ ++ if (c == -1) ++ break; ++ ++ switch (c) ++ { ++ case 0: ++ printf ("unknown option %s", long_options[option_index].name); ++ if (optarg) ++ printf (" with arg %s", optarg); ++ printf ("\n"); ++ usage (); ++ exit (1); ++ ++ case 'v': ++ verbose = 1; ++ be_quiet = 0; ++ break; ++ ++ case 'h': ++ usage (); ++ exit (0); ++ ++ case 'l': ++ install_langs_arg = ila_start = strdup (optarg); ++ /* If the argument to --install-lang is "all", do ++ not limit the list of languages to install and install ++ them all. We do not support installing a single locale ++ called "all". */ ++#define MAGIC_INSTALL_ALL "all" ++ if (install_langs_arg != NULL ++ && install_langs_arg[0] != '\0' ++ && !(strncmp(install_langs_arg, MAGIC_INSTALL_ALL, ++ strlen(MAGIC_INSTALL_ALL)) == 0 ++ && strlen (install_langs_arg) == 3)) ++ { ++ /* Count the number of languages we will install. */ ++ while (true) ++ { ++ lang = strtok(install_langs_arg, ":;,"); ++ if (lang == NULL) ++ break; ++ install_langs_count++; ++ install_langs_arg = NULL; ++ } ++ free (ila_start); ++ /* Copy the list. */ ++ install_langs_list = (char **)xmalloc (sizeof(char *) * install_langs_count); ++ install_langs_arg = ila_start = strdup (optarg); ++ install_langs_count = 0; ++ while (true) ++ { ++ lang = strtok(install_langs_arg, ":;,"); ++ if (lang == NULL) ++ break; ++ install_langs_list[install_langs_count] = lang; ++ install_langs_count++; ++ install_langs_arg = NULL; ++ } ++ } ++ break; ++ ++ case '?': ++ /* getopt_long already printed an error message. */ ++ usage (); ++ exit (0); ++ ++ default: ++ abort (); ++ } ++ } ++ tmpl_ah.fname = NULL; ++ if (optind < argc) ++ tmpl_ah.fname = argv[optind]; ++ if (optind + 1 < argc) ++ new_locar_fname = argv[optind + 1]; ++ if (verbose) ++ { ++ if (tmpl_ah.fname) ++ printf("input archive file specified on command line: %s\n", ++ tmpl_ah.fname); ++ else ++ printf("using default input archive file.\n"); ++ if (new_locar_fname) ++ printf("output archive file specified on command line: %s\n", ++ new_locar_fname); ++ else ++ printf("using default output archive file.\n"); ++ } ++ + dirp = opendir (loc_path); + if (dirp == NULL) + error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path); + + open_tmpl_archive (&tmpl_ah); + +- unlink (locar_file); ++ if (new_locar_fname) ++ unlink (new_locar_fname); ++ else ++ unlink (locar_file); ++ + primary = getenv ("LC_ALL"); + if (primary == NULL) + primary = getenv ("LANG"); +@@ -560,7 +770,8 @@ int main () + && strncmp (primary, "zh", 2) != 0) + { + char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q; +- ++ /* This leads to invalid locales sometimes: ++ de_DE.iso885915@euro -> de_DE.utf8@euro */ + if (ptr != NULL) + { + p = ptr; +@@ -623,10 +834,19 @@ int main () + cnt++; + } + closedir (dirp); +- fill_archive (&tmpl_ah, cnt, list, primary); ++ /* Store the archive to the file specified as the second argument on the ++ command line or the default locale archive. */ ++ fill_archive (&tmpl_ah, new_locar_fname, ++ install_langs_count, install_langs_list, ++ cnt, list, primary); + close_archive (&tmpl_ah); + truncate (tmpl_file, 0); +- char *argv[] = { "/usr/sbin/tzdata-update", NULL }; +- execve (argv[0], (char *const *)argv, (char *const *)&argv[1]); ++ if (install_langs_count > 0) ++ { ++ free (ila_start); ++ free (install_langs_list); ++ } ++ char *tz_argv[] = { "/usr/sbin/tzdata-update", NULL }; ++ execve (tz_argv[0], (char *const *)tz_argv, (char *const *)&tz_argv[1]); + exit (0); + } diff --git a/SOURCES/glibc-rh1298349.patch b/SOURCES/glibc-rh1298349.patch new file mode 100644 index 00000000..7e1ecd14 --- /dev/null +++ b/SOURCES/glibc-rh1298349.patch @@ -0,0 +1,239 @@ +commit 0897c551c0a098020f145885de06a5c10e5cc96b +Author: Carlos O'Donell +Date: Wed Jan 21 10:08:18 2015 -0500 + + tst-getpw: Rewrite. + + The test is rewritten to look for the testable conditions and + exit once they are all detected. This prevents the test from + iterating over 2000 UIDs and looking up each one. It speeds up + the test and prevents it from failing if the system under test + has an NSS-based passwd that is slower than the test timeout. + + See: + https://sourceware.org/ml/libc-alpha/2015-01/msg00394.html + +diff --git a/pwd/tst-getpw.c b/pwd/tst-getpw.c +index 059c9e0..e3e101b 100644 +--- a/pwd/tst-getpw.c ++++ b/pwd/tst-getpw.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1999 Free Software Foundation, Inc. ++/* Copyright (C) 1999-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -15,26 +15,100 @@ + License along with the GNU C Library; if not, see + . */ + ++#include + #include ++#include ++#include ++ ++/* We want to test getpw by calling it with a uid that does ++ exist and one that doesn't exist. We track if we've met those ++ conditions and exit. We also track if we've failed due to lack ++ of memory. That constitutes all of the standard failure cases. */ ++bool seen_hit; ++bool seen_miss; ++bool seen_oom; ++ ++/* How many errors we've had while running the test. */ ++int errors; + + static void + check (uid_t uid) + { ++ int ret; + char buf[1024]; + +- (void) getpw (uid, buf); ++ ret = getpw (uid, buf); ++ ++ /* Successfully read a password line. */ ++ if (ret == 0 && !seen_hit) ++ { ++ printf ("PASS: Read a password line given a uid.\n"); ++ seen_hit = true; ++ } ++ ++ /* Failed to read a password line. Why? */ ++ if (ret == -1) ++ { ++ /* No entry? Technically the errno could be any number ++ of values including ESRCH, EBADP or EPERM depending ++ on the quality of the nss module that implements the ++ underlying lookup. It should be 0 for getpw.*/ ++ if (errno == 0 && !seen_miss) ++ { ++ printf ("PASS: Found an invalid uid.\n"); ++ seen_miss = true; ++ return; ++ } ++ ++ /* Out of memory? */ ++ if (errno == ENOMEM && !seen_oom) ++ { ++ printf ("FAIL: Failed with ENOMEM.\n"); ++ seen_oom = true; ++ errors++; ++ } ++ ++ /* We don't expect any other values for errno. */ ++ if (errno != ENOMEM && errno != 0) ++ errors++; ++ } + } + +-int +-main (void) ++static int ++do_test (void) + { ++ int ret; + uid_t uid; + +- /* Just call it a different number of times the range should be +- large enough to find some existing and some non existing uids. */ ++ /* Should return -1 and set errnot to EINVAL. */ ++ ret = getpw (0, NULL); ++ if (ret == -1 && errno == EINVAL) ++ { ++ printf ("PASS: NULL buffer returns -1 and sets errno to EINVAL.\n"); ++ } ++ else ++ { ++ printf ("FAIL: NULL buffer did not return -1 or set errno to EINVAL.\n"); ++ errors++; ++ } ++ ++ /* Look for one matching uid, one non-found uid and then stop. ++ Set an upper limit at the 16-bit UID mark; no need to go farther. */ ++ for (uid = 0; uid < ((uid_t) 65535); ++uid) ++ { ++ check (uid); ++ if (seen_miss && seen_hit) ++ break; ++ } + +- for (uid = 0; uid < 2000; ++uid) +- check (uid); ++ if (!seen_hit) ++ printf ("FAIL: Did not read even one password line given a uid.\n"); + +- return 0; ++ if (!seen_miss) ++ printf ("FAIL: Did not find even one invalid uid.\n"); ++ ++ return errors; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" + License along with the GNU C Library; if not, see + . */ + ++#include + #include ++#include ++#include ++ ++/* We want to test getpw by calling it with a uid that does ++ exist and one that doesn't exist. We track if we've met those ++ conditions and exit. We also track if we've failed due to lack ++ of memory. That constitutes all of the standard failure cases. */ ++bool seen_hit; ++bool seen_miss; ++bool seen_oom; ++ ++/* How many errors we've had while running the test. */ ++int errors; + + static void + check (uid_t uid) + { ++ int ret; + char buf[1024]; + +- (void) getpw (uid, buf); ++ ret = getpw (uid, buf); ++ ++ /* Successfully read a password line. */ ++ if (ret == 0 && !seen_hit) ++ { ++ printf ("PASS: Read a password line given a uid.\n"); ++ seen_hit = true; ++ } ++ ++ /* Failed to read a password line. Why? */ ++ if (ret == -1) ++ { ++ /* No entry? Technically the errno could be any number ++ of values including ESRCH, EBADP or EPERM depending ++ on the quality of the nss module that implements the ++ underlying lookup. It should be 0 for getpw.*/ ++ if (errno == 0 && !seen_miss) ++ { ++ printf ("PASS: Found an invalid uid.\n"); ++ seen_miss = true; ++ return; ++ } ++ ++ /* Out of memory? */ ++ if (errno == ENOMEM && !seen_oom) ++ { ++ printf ("FAIL: Failed with ENOMEM.\n"); ++ seen_oom = true; ++ errors++; ++ } ++ ++ /* We don't expect any other values for errno. */ ++ if (errno != ENOMEM && errno != 0) ++ errors++; ++ } + } + + static int + do_test (void) + { ++ int ret; + uid_t uid; + +- /* Just call it a different number of times the range should be +- large enough to find some existing and some non existing uids. */ ++ /* Should return -1 and set errnot to EINVAL. */ ++ ret = getpw (0, NULL); ++ if (ret == -1 && errno == EINVAL) ++ { ++ printf ("PASS: NULL buffer returns -1 and sets errno to EINVAL.\n"); ++ } ++ else ++ { ++ printf ("FAIL: NULL buffer did not return -1 or set errno to EINVAL.\n"); ++ errors++; ++ } ++ ++ /* Look for one matching uid, one non-found uid and then stop. ++ Set an upper limit at the 16-bit UID mark; no need to go farther. */ ++ for (uid = 0; uid < ((uid_t) 65535); ++uid) ++ { ++ check (uid); ++ if (seen_miss && seen_hit) ++ break; ++ } ++ ++ if (!seen_hit) ++ printf ("FAIL: Did not read even one password line given a uid.\n"); + +- for (uid = 0; uid < 2000; ++uid) +- check (uid); ++ if (!seen_miss) ++ printf ("FAIL: Did not find even one invalid uid.\n"); + +- return 0; ++ return errors; + } + + #define TEST_FUNCTION do_test () diff --git a/SOURCES/glibc-rh1298354.patch b/SOURCES/glibc-rh1298354.patch new file mode 100644 index 00000000..375c75b9 --- /dev/null +++ b/SOURCES/glibc-rh1298354.patch @@ -0,0 +1,2805 @@ +commit 29955b5d9658b02d3a678d1f785db3d1e63184ca +Author: Arjun Shankar +Date: Wed Nov 5 15:24:08 2014 +0530 + + Modify several tests to use test-skeleton.c + + This patch modifies several test cases to use test-skeleton.c. + It was generated by a bash script written for this purpose and + thus excludes several other tests which I deemed worth a visual + inspection before making the change. + + I intend to follow up with individual patches to the tests + skipped by the script. + + The script itself resides at http://git.io/WODAmg and should + reproduce this very patch when run against master. + + ChangeLog: + + 2014-10-30 Arjun Shankar + + * catgets/test-gencat.c: Use test-skeleton.c. + * catgets/tst-catgets.c: Likewise. + * csu/tst-empty.c: Likewise. + * elf/tst-audit2.c: Likewise. + * elf/tst-global1.c: Likewise. + * elf/tst-pathopt.c: Likewise. + * elf/tst-piemod1.c: Likewise. + * elf/tst-tls10.c: Likewise. + * elf/tst-tls11.c: Likewise. + * elf/tst-tls12.c: Likewise. + * gnulib/tst-gcc.c: Likewise. + * iconvdata/tst-e2big.c: Likewise. + * iconvdata/tst-loading.c: Likewise. + * iconv/tst-iconv1.c: Likewise. + * iconv/tst-iconv2.c: Likewise. + * inet/test-inet6_opt.c: Likewise. + * inet/tst-gethnm.c: Likewise. + * inet/tst-network.c: Likewise. + * inet/tst-ntoa.c: Likewise. + * intl/tst-codeset.c: Likewise. + * intl/tst-gettext2.c: Likewise. + * intl/tst-gettext3.c: Likewise. + * intl/tst-ngettext.c: Likewise. + * intl/tst-translit.c: Likewise. + * io/test-stat.c: Likewise. + * libio/test-fmemopen.c: Likewise. + * libio/tst-freopen.c: Likewise. + * libio/tst-sscanf.c: Likewise. + * libio/tst-ungetwc1.c: Likewise. + * libio/tst-ungetwc2.c: Likewise. + * libio/tst-widetext.c: Likewise. + * localedata/tst-ctype.c: Likewise. + * localedata/tst-digits.c: Likewise. + * localedata/tst-leaks.c: Likewise. + * localedata/tst-mbswcs1.c: Likewise. + * localedata/tst-mbswcs2.c: Likewise. + * localedata/tst-mbswcs3.c: Likewise. + * localedata/tst-mbswcs4.c: Likewise. + * localedata/tst-mbswcs5.c: Likewise. + * localedata/tst-setlocale.c: Likewise. + * localedata/tst-trans.c: Likewise. + * localedata/tst-wctype.c: Likewise. + * localedata/tst-xlocale1.c: Likewise. + * login/tst-grantpt.c: Likewise. + * malloc/tst-calloc.c: Likewise. + * malloc/tst-malloc.c: Likewise. + * malloc/tst-mallocstate.c: Likewise. + * malloc/tst-mcheck.c: Likewise. + * malloc/tst-mtrace.c: Likewise. + * malloc/tst-obstack.c: Likewise. + * math/atest-exp2.c: Likewise. + * math/atest-exp.c: Likewise. + * math/atest-sincos.c: Likewise. + * math/test-matherr.c: Likewise. + * math/test-misc.c: Likewise. + * math/test-powl.c: Likewise. + * math/tst-definitions.c: Likewise. + * misc/tst-dirname.c: Likewise. + * misc/tst-efgcvt.c: Likewise. + * misc/tst-fdset.c: Likewise. + * misc/tst-hsearch.c: Likewise. + * misc/tst-mntent2.c: Likewise. + * nptl/tst-sem7.c: Likewise. + * nptl/tst-sem8.c: Likewise. + * nptl/tst-sem9.c: Likewise. + * nss/test-netdb.c: Likewise. + * posix/tst-fnmatch.c: Likewise. + * posix/tst-getlogin.c: Likewise. + * posix/tst-gnuglob.c: Likewise. + * posix/tst-mmap.c: Likewise. + * resolv/tst-inet_ntop.c: Likewise. + * rt/tst-timer.c: Likewise. + * stdio-common/test-fseek.c: Likewise. + * stdio-common/test-popen.c: Likewise. + * stdio-common/test-vfprintf.c: Likewise. + * stdio-common/tst-cookie.c: Likewise. + * stdio-common/tst-fileno.c: Likewise. + * stdio-common/tst-gets.c: Likewise. + * stdio-common/tst-obprintf.c: Likewise. + * stdio-common/tst-perror.c: Likewise. + * stdio-common/tst-sprintf2.c: Likewise. + * stdio-common/tst-sprintf3.c: Likewise. + * stdio-common/tst-sprintf.c: Likewise. + * stdio-common/tst-swprintf.c: Likewise. + * stdio-common/tst-tmpnam.c: Likewise. + * stdio-common/tst-unbputc.c: Likewise. + * stdio-common/tst-wc-printf.c: Likewise. + * stdlib/tst-environ.c: Likewise. + * stdlib/tst-fmtmsg.c: Likewise. + * stdlib/tst-limits.c: Likewise. + * stdlib/tst-rand48-2.c: Likewise. + * stdlib/tst-rand48.c: Likewise. + * stdlib/tst-random2.c: Likewise. + * stdlib/tst-random.c: Likewise. + * stdlib/tst-strtol.c: Likewise. + * stdlib/tst-strtoll.c: Likewise. + * stdlib/tst-xpg-basename.c: Likewise. + * string/test-ffs.c: Likewise. + * string/tst-bswap.c: Likewise. + * string/tst-inlcall.c: Likewise. + * string/tst-strtok.c: Likewise. + * string/tst-strxfrm.c: Likewise. + * sysdeps/x86_64/tst-audit10.c: Likewise. + * elf/tst-audit3.c: Likewise. + * elf/tst-audit4.c: Likewise. + * elf/tst-audit5.c: Likewise. + * time/tst-ftime_l.c: Likewise. + * time/tst-getdate.c: Likewise. + * time/tst-mktime3.c: Likewise. + * time/tst-mktime.c: Likewise. + * time/tst-posixtz.c: Likewise. + * time/tst-strptime2.c: Likewise. + * time/tst-strptime3.c: Likewise. + * wcsmbs/tst-btowc.c: Likewise. + * wcsmbs/tst-mbrtowc.c: Likewise. + * wcsmbs/tst-mbsrtowcs.c: Likewise. + * wcsmbs/tst-wchar-h.c: Likewise. + * wcsmbs/tst-wcpncpy.c: Likewise. + * wcsmbs/tst-wcrtomb.c: Likewise. + * wcsmbs/tst-wcsnlen.c: Likewise. + * wcsmbs/tst-wcstof.c: Likewise. + +diff --git a/catgets/test-gencat.c b/catgets/test-gencat.c +index eaa9b89..282974c 100644 +--- a/catgets/test-gencat.c ++++ b/catgets/test-gencat.c +@@ -3,8 +3,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + nl_catd catalog; + setlocale (LC_ALL, ""); +@@ -29,3 +29,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/catgets/tst-catgets.c b/catgets/tst-catgets.c +index fdaa834..a0a4089 100644 +--- a/catgets/tst-catgets.c ++++ b/catgets/tst-catgets.c +@@ -14,8 +14,8 @@ static const char *msgs[] = + + #define ROUNDS 5 + +-int +-main (void) ++static int ++do_test (void) + { + int rnd; + int result = 0; +@@ -64,3 +64,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/csu/tst-empty.c b/csu/tst-empty.c +index 980dcd6..e99468e 100644 +--- a/csu/tst-empty.c ++++ b/csu/tst-empty.c +@@ -1,6 +1,9 @@ + /* The most useful C program known to man. */ +-int +-main (void) ++static int ++do_test (void) + { + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-audit2.c b/elf/tst-audit2.c +index b4fa906..acad1b0 100644 +--- a/elf/tst-audit2.c ++++ b/elf/tst-audit2.c +@@ -31,8 +31,8 @@ calloc (size_t n, size_t m) + return ptr; + } + +-int +-main (void) ++static int ++do_test (void) + { + if (magic[1] != MAGIC1 || magic[0] != MAGIC2) + { +@@ -42,3 +42,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-global1.c b/elf/tst-global1.c +index 1611b51..4df335c 100644 +--- a/elf/tst-global1.c ++++ b/elf/tst-global1.c +@@ -1,8 +1,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + void *h1 = dlopen ("$ORIGIN/testobj6.so", RTLD_GLOBAL|RTLD_LAZY); + if (h1 == NULL) +@@ -34,3 +34,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-pathopt.c b/elf/tst-pathopt.c +index 1f7aac2..8d73ad4 100644 +--- a/elf/tst-pathopt.c ++++ b/elf/tst-pathopt.c +@@ -4,8 +4,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + void *h; + int (*fp) (int); +@@ -37,3 +37,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-piemod1.c b/elf/tst-piemod1.c +index ad439da..6e98b5f 100644 +--- a/elf/tst-piemod1.c ++++ b/elf/tst-piemod1.c +@@ -6,8 +6,8 @@ foo (void) + return 21; + } + +-int +-main (void) ++static int ++do_test (void) + { + int val = foo (); + if (val != 34) +@@ -18,3 +18,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-tls10.c b/elf/tst-tls10.c +index 347243f..eb1ecb9 100644 +--- a/elf/tst-tls10.c ++++ b/elf/tst-tls10.c +@@ -8,8 +8,8 @@ __thread struct A local = { 1, 2, 3 }; + if (p->a != S || p->b != S + 1 || p->c != S + 2) \ + abort () + +-int +-main (void) ++static int ++do_test (void) + { + struct A *p; + if (local.a != 1 || local.b != 2 || local.c != 3) +@@ -35,3 +35,6 @@ main (void) + + exit (0); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-tls11.c b/elf/tst-tls11.c +index 8a2fef4..8ceac14 100644 +--- a/elf/tst-tls11.c ++++ b/elf/tst-tls11.c +@@ -5,8 +5,8 @@ + if (p->a != S || p->b != S + 1 || p->c != S + 2) \ + abort () + +-int +-main (void) ++static int ++do_test (void) + { + struct A *p; + check1 (); +@@ -24,3 +24,6 @@ main (void) + + exit (0); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/elf/tst-tls12.c b/elf/tst-tls12.c +index 9086d17..8093894 100644 +--- a/elf/tst-tls12.c ++++ b/elf/tst-tls12.c +@@ -5,8 +5,8 @@ + if (p->a != S || p->b != S + 1 || p->c != S + 2) \ + abort () + +-int +-main (void) ++static int ++do_test (void) + { + struct A *p; + check1 (); +@@ -15,3 +15,6 @@ main (void) + + exit (0); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/gnulib/tst-gcc.c b/gnulib/tst-gcc.c +index 71fab28..9f4ba83 100644 +--- a/gnulib/tst-gcc.c ++++ b/gnulib/tst-gcc.c +@@ -51,8 +51,8 @@ + }) + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + int __integer_type; +@@ -71,3 +71,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/iconv/tst-iconv1.c b/iconv/tst-iconv1.c +index d806ce6..0609f50 100644 +--- a/iconv/tst-iconv1.c ++++ b/iconv/tst-iconv1.c +@@ -5,8 +5,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char utf8[5]; + wchar_t ucs4[5]; +@@ -42,3 +42,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/iconv/tst-iconv2.c b/iconv/tst-iconv2.c +index 5036ad1..0672a51 100644 +--- a/iconv/tst-iconv2.c ++++ b/iconv/tst-iconv2.c +@@ -25,8 +25,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + char buf[3]; + const wchar_t wc[1] = L"a"; +@@ -97,3 +97,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/iconvdata/tst-e2big.c b/iconvdata/tst-e2big.c +index 9533eb0..8de64b2 100644 +--- a/iconvdata/tst-e2big.c ++++ b/iconvdata/tst-e2big.c +@@ -95,10 +95,13 @@ test_tscii (void) + test ("TSCII", inbuf, sizeof (inbuf), 9); + } + +-int +-main (void) ++static int ++do_test (void) + { + test_euc_jisx0213 (); + test_tscii (); + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/iconvdata/tst-loading.c b/iconvdata/tst-loading.c +index 0d8a959..eff9d78 100644 +--- a/iconvdata/tst-loading.c ++++ b/iconvdata/tst-loading.c +@@ -114,8 +114,8 @@ static const char inbuf[] = + " function. Later modifications of the variable have no effect.\n"; + + +-int +-main (void) ++static int ++do_test (void) + { + size_t count = TEST_ROUNDS; + int result = 0; +@@ -180,3 +180,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/inet/test-inet6_opt.c b/inet/test-inet6_opt.c +index 3bf319e..a7ebf00 100644 +--- a/inet/test-inet6_opt.c ++++ b/inet/test-inet6_opt.c +@@ -194,8 +194,8 @@ decode_inet6_opt (void *eb, socklen_t el) + return ret; + } + +-int +-main (void) ++static int ++do_test (void) + { + void *eb; + socklen_t el; +@@ -206,3 +206,6 @@ main (void) + return 1; + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/inet/tst-gethnm.c b/inet/tst-gethnm.c +index 8af44d6..dd3a547 100644 +--- a/inet/tst-gethnm.c ++++ b/inet/tst-gethnm.c +@@ -10,8 +10,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + struct hostent *ent; + struct in_addr hostaddr; +@@ -62,3 +62,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/inet/tst-network.c b/inet/tst-network.c +index fc90bd7..cc840e0 100644 +--- a/inet/tst-network.c ++++ b/inet/tst-network.c +@@ -51,8 +51,8 @@ struct + }; + + +-int +-main (void) ++static int ++do_test (void) + { + int errors = 0; + size_t i; +@@ -76,3 +76,6 @@ main (void) + + return errors != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/inet/tst-ntoa.c b/inet/tst-ntoa.c +index 9be91eb..ef82d4d 100644 +--- a/inet/tst-ntoa.c ++++ b/inet/tst-ntoa.c +@@ -22,8 +22,8 @@ test (unsigned int inaddr, const char *expected) + } + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -34,3 +34,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/intl/tst-codeset.c b/intl/tst-codeset.c +index f5b37ec..37f731e 100644 +--- a/intl/tst-codeset.c ++++ b/intl/tst-codeset.c +@@ -23,8 +23,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char *s; + int result = 0; +@@ -55,3 +55,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/intl/tst-gettext2.c b/intl/tst-gettext2.c +index 075680a..3c44165 100644 +--- a/intl/tst-gettext2.c ++++ b/intl/tst-gettext2.c +@@ -40,8 +40,8 @@ struct data_t strings[] = + const int lang_cnt = 3; + const char *lang[] = {"lang1", "lang2", "lang3"}; + +-int +-main (void) ++static int ++do_test (void) + { + int i; + +@@ -70,3 +70,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/intl/tst-gettext3.c b/intl/tst-gettext3.c +index dd88987..11e9b08 100644 +--- a/intl/tst-gettext3.c ++++ b/intl/tst-gettext3.c +@@ -24,8 +24,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char *s; + int result = 0; +@@ -57,3 +57,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/intl/tst-ngettext.c b/intl/tst-ngettext.c +index 4fb0ca2..71e91b9 100644 +--- a/intl/tst-ngettext.c ++++ b/intl/tst-ngettext.c +@@ -25,8 +25,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + const char *strs[2] = { "singular", "plural" }; + unsigned long int i; +@@ -63,3 +63,6 @@ main (void) + + return res; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/intl/tst-translit.c b/intl/tst-translit.c +index 1aecee7..299fa40 100644 +--- a/intl/tst-translit.c ++++ b/intl/tst-translit.c +@@ -24,8 +24,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + const char *s; +@@ -49,3 +49,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/io/test-stat.c b/io/test-stat.c +index c5cfd26..e9c8468 100644 +--- a/io/test-stat.c ++++ b/io/test-stat.c +@@ -25,8 +25,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + /* With _FILE_OFFSET_BITS=64 struct stat and struct stat64 should + be identical. */ +@@ -65,3 +65,6 @@ main (void) + #endif + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/libio/test-fmemopen.c b/libio/test-fmemopen.c +index 3099894..211176e 100644 +--- a/libio/test-fmemopen.c ++++ b/libio/test-fmemopen.c +@@ -22,8 +22,8 @@ static char buffer[] = "foobar"; + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int ch; + FILE *stream; +@@ -37,3 +37,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/libio/tst-freopen.c b/libio/tst-freopen.c +index f9e7177..94284ec 100644 +--- a/libio/tst-freopen.c ++++ b/libio/tst-freopen.c +@@ -22,8 +22,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char name[] = "/tmp/tst-freopen.XXXXXX"; + const char * const test = "Let's test freopen.\n"; +@@ -100,3 +100,6 @@ main (void) + unlink (name); + exit (0); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/libio/tst-sscanf.c b/libio/tst-sscanf.c +index b1a2b84..fb4be34 100644 +--- a/libio/tst-sscanf.c ++++ b/libio/tst-sscanf.c +@@ -3,8 +3,8 @@ + + #define WCS_LENGTH 256 + +-int +-main (void) ++static int ++do_test (void) + { + const char cnv[] ="%l[abc]"; + const char str[] = "abbcXab"; +@@ -18,3 +18,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/libio/tst-ungetwc1.c b/libio/tst-ungetwc1.c +index f74c407..f71b390 100644 +--- a/libio/tst-ungetwc1.c ++++ b/libio/tst-ungetwc1.c +@@ -7,8 +7,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + FILE *fp; + const char *str = "abcdef"; +@@ -79,3 +79,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/libio/tst-ungetwc2.c b/libio/tst-ungetwc2.c +index d15e287..a7c5193 100644 +--- a/libio/tst-ungetwc2.c ++++ b/libio/tst-ungetwc2.c +@@ -7,8 +7,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + FILE *fp; + const char *str = "abcdef"; +@@ -79,3 +79,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/libio/tst-widetext.c b/libio/tst-widetext.c +index 179763e..acab72b 100644 +--- a/libio/tst-widetext.c ++++ b/libio/tst-widetext.c +@@ -31,8 +31,8 @@ + #define SIZE 210000 + + +-int +-main (void) ++static int ++do_test (void) + { + char name[] = "/tmp/widetext.out.XXXXXX"; + char mbbuf[SIZE]; +@@ -367,3 +367,6 @@ main (void) + + return status; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-ctype.c b/localedata/tst-ctype.c +index ceda891..a4e8fcf 100644 +--- a/localedata/tst-ctype.c ++++ b/localedata/tst-ctype.c +@@ -61,8 +61,8 @@ static struct classes + } + + +-int +-main (void) ++static int ++do_test (void) + { + const char *cp; + const char *cp2; +@@ -447,3 +447,6 @@ punct = %04x alnum = %04x\n", + printf (" No errors for `%s' locale\n\n\n", setlocale (LC_ALL, NULL)); + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-digits.c b/localedata/tst-digits.c +index 9b3ebcd..76356e9 100644 +--- a/localedata/tst-digits.c ++++ b/localedata/tst-digits.c +@@ -111,8 +111,8 @@ static struct wprintf_int_test + (sizeof (wprintf_int_tests) / sizeof (wprintf_int_tests[0])) + + +-int +-main (void) ++static int ++do_test (void) + { + int cnt; + int failures; +@@ -246,3 +246,6 @@ main (void) + + return status; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-leaks.c b/localedata/tst-leaks.c +index 7a4b557..ccd44f2 100644 +--- a/localedata/tst-leaks.c ++++ b/localedata/tst-leaks.c +@@ -1,8 +1,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int cnt; + +@@ -16,3 +16,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-mbswcs1.c b/localedata/tst-mbswcs1.c +index 14f1372..1404829 100644 +--- a/localedata/tst-mbswcs1.c ++++ b/localedata/tst-mbswcs1.c +@@ -33,8 +33,8 @@ + } \ + putc ('\n', stdout) + +-int +-main (void) ++static int ++do_test (void) + { + const unsigned char buf[6] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb }; + mbstate_t state; +@@ -60,3 +60,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-mbswcs2.c b/localedata/tst-mbswcs2.c +index 25fa951..9cd95d6 100644 +--- a/localedata/tst-mbswcs2.c ++++ b/localedata/tst-mbswcs2.c +@@ -35,8 +35,8 @@ + } \ + putc ('\n', stdout) + +-int +-main (void) ++static int ++do_test (void) + { + unsigned char buf[6] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb }; + mbstate_t state; +@@ -62,3 +62,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-mbswcs3.c b/localedata/tst-mbswcs3.c +index 8db65c5..a068541 100644 +--- a/localedata/tst-mbswcs3.c ++++ b/localedata/tst-mbswcs3.c +@@ -38,8 +38,8 @@ + putc ('\n', stdout); \ + } + +-int +-main (void) ++static int ++do_test (void) + { + unsigned char buf[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + const unsigned char bufcheck[6] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb }; +@@ -73,3 +73,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-mbswcs4.c b/localedata/tst-mbswcs4.c +index 09b7417..a4fe60d 100644 +--- a/localedata/tst-mbswcs4.c ++++ b/localedata/tst-mbswcs4.c +@@ -34,8 +34,8 @@ + } \ + putc ('\n', stdout) + +-int +-main (void) ++static int ++do_test (void) + { + unsigned char buf[6] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb }; + mbstate_t state; +@@ -60,3 +60,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-mbswcs5.c b/localedata/tst-mbswcs5.c +index e18862c..c44f12a 100644 +--- a/localedata/tst-mbswcs5.c ++++ b/localedata/tst-mbswcs5.c +@@ -37,8 +37,8 @@ + putc ('\n', stdout); \ + } + +-int +-main (void) ++static int ++do_test (void) + { + unsigned char buf[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + const unsigned char bufcheck[7] = { 0x25, 0xe2, 0x82, 0xac, 0xce, 0xbb, 0 }; +@@ -72,3 +72,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-setlocale.c b/localedata/tst-setlocale.c +index 1f8e68d..a09a4de 100644 +--- a/localedata/tst-setlocale.c ++++ b/localedata/tst-setlocale.c +@@ -3,8 +3,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char q[30]; + char *s; +@@ -23,3 +23,6 @@ main (void) + + return strcmp (s, "de_DE.UTF-8") != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-trans.c b/localedata/tst-trans.c +index 5e09631..0b0be83 100644 +--- a/localedata/tst-trans.c ++++ b/localedata/tst-trans.c +@@ -24,8 +24,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char buf[30]; + wchar_t wbuf[30]; +@@ -68,3 +68,6 @@ main (void) + + return errors; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-wctype.c b/localedata/tst-wctype.c +index bd2b057..eb72030 100644 +--- a/localedata/tst-wctype.c ++++ b/localedata/tst-wctype.c +@@ -24,8 +24,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + wctype_t wct; + wchar_t buf[1000]; +@@ -141,3 +141,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/localedata/tst-xlocale1.c b/localedata/tst-xlocale1.c +index 297c9ad..9f545a0 100644 +--- a/localedata/tst-xlocale1.c ++++ b/localedata/tst-xlocale1.c +@@ -20,8 +20,8 @@ static struct + #define ntests (sizeof (tests) / sizeof (tests[0])) + + +-int +-main (void) ++static int ++do_test (void) + { + size_t cnt; + int result = 0; +@@ -73,3 +73,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/login/tst-grantpt.c b/login/tst-grantpt.c +index 5078dac..65bb344 100644 +--- a/login/tst-grantpt.c ++++ b/login/tst-grantpt.c +@@ -66,8 +66,8 @@ test_einval (void) + return ret; + } + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -76,3 +76,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/malloc/tst-calloc.c b/malloc/tst-calloc.c +index 51e6c25..7ad5124 100644 +--- a/malloc/tst-calloc.c ++++ b/malloc/tst-calloc.c +@@ -104,8 +104,8 @@ null_test (void) + } + + +-int +-main (void) ++static int ++do_test (void) + { + /* We are allocating blocks with `calloc' and check whether every + block is completely cleared. We first try this for some fixed +@@ -123,3 +123,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/malloc/tst-malloc.c b/malloc/tst-malloc.c +index a75ab1e..2685315 100644 +--- a/malloc/tst-malloc.c ++++ b/malloc/tst-malloc.c +@@ -29,8 +29,8 @@ merror (const char *msg) + printf ("Error: %s\n", msg); + } + +-int +-main (void) ++static int ++do_test (void) + { + void *p, *q; + int save; +@@ -75,3 +75,6 @@ main (void) + + return errors != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/malloc/tst-mallocstate.c b/malloc/tst-mallocstate.c +index 69c4500..539539e 100644 +--- a/malloc/tst-mallocstate.c ++++ b/malloc/tst-mallocstate.c +@@ -29,8 +29,8 @@ merror (const char *msg) + printf ("Error: %s\n", msg); + } + +-int +-main (void) ++static int ++do_test (void) + { + void *p1, *p2; + void *save_state; +@@ -79,3 +79,6 @@ main (void) + * c-basic-offset: 2 + * End: + */ ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/malloc/tst-mcheck.c b/malloc/tst-mcheck.c +index 478ca8c..bd9ab0e 100644 +--- a/malloc/tst-mcheck.c ++++ b/malloc/tst-mcheck.c +@@ -29,8 +29,8 @@ merror (const char *msg) + printf ("Error: %s\n", msg); + } + +-int +-main (void) ++static int ++do_test (void) + { + void *p, *q; + +@@ -88,3 +88,6 @@ main (void) + + return errors != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/malloc/tst-mtrace.c b/malloc/tst-mtrace.c +index 9b5151c..b2c0c2c 100644 +--- a/malloc/tst-mtrace.c ++++ b/malloc/tst-mtrace.c +@@ -30,8 +30,8 @@ static void print (const void *node, VISIT value, int level); + static FILE *fp; + + +-int +-main (void) ++static int ++do_test (void) + { + void *root = NULL; + size_t linelen = 0; +@@ -100,3 +100,6 @@ print (const void *node, VISIT value, int level) + if (value == postorder || value == leaf) + fprintf (fp, "%3d: %s", ++cnt, *(const char **) node); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/malloc/tst-obstack.c b/malloc/tst-obstack.c +index 769697f..ee1385d 100644 +--- a/malloc/tst-obstack.c ++++ b/malloc/tst-obstack.c +@@ -25,8 +25,8 @@ verbose_free (void *buf) + printf ("free (%p)\n", buf); + } + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + int align = 2; +@@ -62,3 +62,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/atest-exp.c b/math/atest-exp.c +index 3a538b2..6a551de 100644 +--- a/math/atest-exp.c ++++ b/math/atest-exp.c +@@ -102,8 +102,8 @@ mpn_bitsize(const mp_limb_t *SRC_PTR, mp_size_t SIZE) + return i * mpbpl + j; + } + +-int +-main (void) ++static int ++do_test (void) + { + mp1 ex, x, xt, e2, e3; + int i; +@@ -190,3 +190,6 @@ main (void) + + return failures == 0 ? 0 : 1; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/atest-exp2.c b/math/atest-exp2.c +index 3442715..945bb7a 100644 +--- a/math/atest-exp2.c ++++ b/math/atest-exp2.c +@@ -144,8 +144,8 @@ mpn_bitsize(const mp_limb_t *SRC_PTR, mp_size_t SIZE) + return i * mpbpl + j; + } + +-int +-main (void) ++static int ++do_test (void) + { + mp1 ex, x, xt, e2, e3; + int i; +@@ -227,3 +227,6 @@ main (void) + + return failures == 0 ? 0 : 1; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/atest-sincos.c b/math/atest-sincos.c +index 5ad59b2..1f5e730 100644 +--- a/math/atest-sincos.c ++++ b/math/atest-sincos.c +@@ -141,8 +141,8 @@ mpn_bitsize (const mp_limb_t *SRC_PTR, mp_size_t SIZE) + return i * mpbpl + j; + } + +-int +-main (void) ++static int ++do_test (void) + { + mp1 si, co, x, ox, xt, s2, c2, s3, c3; + int i; +@@ -277,3 +277,6 @@ main (void) + + return (sin_failures == 0 && cos_failures == 0) ? 0 : 1; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/test-matherr.c b/math/test-matherr.c +index cd09a39..6983879 100644 +--- a/math/test-matherr.c ++++ b/math/test-matherr.c +@@ -12,10 +12,13 @@ matherr (struct exception *s) + return 1; + } + +-int +-main (void) ++static int ++do_test (void) + { + _LIB_VERSION = _SVID_; + acos (2.0); + return fail; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/test-misc.c b/math/test-misc.c +index 3fd2bca..4801bfe 100644 +--- a/math/test-misc.c ++++ b/math/test-misc.c +@@ -25,8 +25,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -1201,3 +1201,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/test-powl.c b/math/test-powl.c +index fd2a1cb..66ef886 100644 +--- a/math/test-powl.c ++++ b/math/test-powl.c +@@ -21,8 +21,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -48,3 +48,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/math/tst-definitions.c b/math/tst-definitions.c +index 2501c8c..76a4125 100644 +--- a/math/tst-definitions.c ++++ b/math/tst-definitions.c +@@ -21,8 +21,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -44,3 +44,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-dirname.c b/misc/tst-dirname.c +index d8f33df..d6c05ad 100644 +--- a/misc/tst-dirname.c ++++ b/misc/tst-dirname.c +@@ -37,8 +37,8 @@ test (const char *input, const char *result) + return retval; + } + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -67,3 +67,6 @@ main (void) + + return result != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-efgcvt.c b/misc/tst-efgcvt.c +index 303042d..11427a0 100644 +--- a/misc/tst-efgcvt.c ++++ b/misc/tst-efgcvt.c +@@ -200,8 +200,8 @@ special (void) + } + + +-int +-main (void) ++static int ++do_test (void) + { + test (ecvt_tests, ecvt, "ecvt"); + test (fcvt_tests, fcvt, "fcvt"); +@@ -211,3 +211,6 @@ main (void) + + return error_count; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-fdset.c b/misc/tst-fdset.c +index 78a34e9..ef93ac3 100644 +--- a/misc/tst-fdset.c ++++ b/misc/tst-fdset.c +@@ -20,8 +20,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int retval = 0; + int i; +@@ -62,3 +62,6 @@ main (void) + + return retval; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-hsearch.c b/misc/tst-hsearch.c +index 6c19b22..d390f1d 100644 +--- a/misc/tst-hsearch.c ++++ b/misc/tst-hsearch.c +@@ -1,8 +1,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int a = 1; + int b = 2; +@@ -29,3 +29,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/misc/tst-mntent2.c b/misc/tst-mntent2.c +index 6c25e01..e61d506 100644 +--- a/misc/tst-mntent2.c ++++ b/misc/tst-mntent2.c +@@ -3,8 +3,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + struct mntent mef; +@@ -39,3 +39,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/nptl/tst-sem7.c b/nptl/tst-sem7.c +index d0e7f05..4fc5f1f 100644 +--- a/nptl/tst-sem7.c ++++ b/nptl/tst-sem7.c +@@ -31,8 +31,8 @@ remove_sem (int status, void *arg) + } + + +-int +-main (void) ++static int ++do_test (void) + { + sem_t *s; + sem_t *s2; +@@ -106,3 +106,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/nptl/tst-sem8.c b/nptl/tst-sem8.c +index 1aeb1e1..4d7197c 100644 +--- a/nptl/tst-sem8.c ++++ b/nptl/tst-sem8.c +@@ -31,8 +31,8 @@ remove_sem (int status, void *arg) + } + + +-int +-main (void) ++static int ++do_test (void) + { + sem_t *s; + int i; +@@ -71,3 +71,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/nptl/tst-sem9.c b/nptl/tst-sem9.c +index 9727486..b7d81a9 100644 +--- a/nptl/tst-sem9.c ++++ b/nptl/tst-sem9.c +@@ -31,8 +31,8 @@ remove_sem (int status, void *arg) + } + + +-int +-main (void) ++static int ++do_test (void) + { + sem_t *s; + int i; +@@ -78,3 +78,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/nss/test-netdb.c b/nss/test-netdb.c +index 1620b5b..384f32b 100644 +--- a/nss/test-netdb.c ++++ b/nss/test-netdb.c +@@ -356,8 +356,8 @@ setdb (const char *dbname) + } + + +-int +-main (void) ++static int ++do_test (void) + { + /* + setdb ("db"); +@@ -376,3 +376,6 @@ main (void) + + return (error_count != 0); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/posix/tst-fnmatch.c b/posix/tst-fnmatch.c +index ff2674c..021734d 100644 +--- a/posix/tst-fnmatch.c ++++ b/posix/tst-fnmatch.c +@@ -33,8 +33,8 @@ static char *flag_output (int flags); + static char *escape (const char *str, size_t *reslenp, char **resbuf); + + +-int +-main (void) ++static int ++do_test (void) + { + char *linebuf = NULL; + size_t linebuflen = 0; +@@ -388,3 +388,6 @@ escape (const char *str, size_t *reslenp, char **resbufp) + + return resbuf; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/posix/tst-getlogin.c b/posix/tst-getlogin.c +index 1393c3a..141a699 100644 +--- a/posix/tst-getlogin.c ++++ b/posix/tst-getlogin.c +@@ -19,8 +19,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char *login; + int errors = 0; +@@ -55,3 +55,6 @@ main (void) + + return errors != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c +index 1c72357..39b5b24 100644 +--- a/posix/tst-gnuglob.c ++++ b/posix/tst-gnuglob.c +@@ -379,8 +379,8 @@ test_result (const char *fmt, int flags, glob_t *gl, const char *str[]) + } + + +-int +-main (void) ++static int ++do_test (void) + { + glob_t gl; + int errval; +@@ -497,3 +497,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/posix/tst-mmap.c b/posix/tst-mmap.c +index c03acf5..5e52b49 100644 +--- a/posix/tst-mmap.c ++++ b/posix/tst-mmap.c +@@ -6,8 +6,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + FILE *fp; +@@ -195,3 +195,6 @@ main (void) + /* That's it. */ + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/resolv/tst-inet_ntop.c b/resolv/tst-inet_ntop.c +index f968ec4..f0de063 100644 +--- a/resolv/tst-inet_ntop.c ++++ b/resolv/tst-inet_ntop.c +@@ -4,8 +4,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + struct in_addr addr4; + struct in6_addr addr6; +@@ -109,3 +109,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/rt/tst-timer.c b/rt/tst-timer.c +index f35d3e7..87f6491 100644 +--- a/rt/tst-timer.c ++++ b/rt/tst-timer.c +@@ -20,8 +20,8 @@ + + /* This file is only used if there is no other implementation and it should + means that there is no implementation of POSIX timers. */ +-int +-main (void) ++static int ++do_test (void) + { + #ifdef _POSIX_TIMERS + /* There should be a test. */ +@@ -30,3 +30,6 @@ main (void) + return 0; + #endif + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/test-fseek.c b/stdio-common/test-fseek.c +index fe57df6..8a7f1ae 100644 +--- a/stdio-common/test-fseek.c ++++ b/stdio-common/test-fseek.c +@@ -19,8 +19,8 @@ + + #define TESTFILE "/tmp/test.dat" + +-int +-main (void) ++static int ++do_test (void) + { + FILE *fp; + int i, j; +@@ -82,3 +82,6 @@ main (void) + puts ((i > 255) ? "Test succeeded." : "Test FAILED!"); + return (i > 255) ? 0 : 1; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/test-popen.c b/stdio-common/test-popen.c +index d36cd61..1f1c88a 100644 +--- a/stdio-common/test-popen.c ++++ b/stdio-common/test-popen.c +@@ -49,8 +49,8 @@ read_data (FILE *stream) + } + } + +-int +-main (void) ++static int ++do_test (void) + { + FILE *output, *input; + int wstatus, rstatus; +@@ -100,3 +100,6 @@ main (void) + puts (wstatus | rstatus ? "Test FAILED!" : "Test succeeded."); + return (wstatus | rstatus); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/test-vfprintf.c b/stdio-common/test-vfprintf.c +index a936c28..9cc56d7 100644 +--- a/stdio-common/test-vfprintf.c ++++ b/stdio-common/test-vfprintf.c +@@ -36,8 +36,8 @@ const char *locs[] = + + char large[50000]; + +-int +-main (void) ++static int ++do_test (void) + { + char buf[25]; + size_t i; +@@ -124,3 +124,6 @@ main (void) + + return res; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-cookie.c b/stdio-common/tst-cookie.c +index dcdabf3..030e684 100644 +--- a/stdio-common/tst-cookie.c ++++ b/stdio-common/tst-cookie.c +@@ -63,8 +63,8 @@ cookieclose (void *cookie) + } + + +-int +-main (void) ++static int ++do_test (void) + { + cookie_io_functions_t fcts; + char buf[1]; +@@ -90,3 +90,6 @@ main (void) + + return errors != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-fileno.c b/stdio-common/tst-fileno.c +index a0c8853..753df9f 100644 +--- a/stdio-common/tst-fileno.c ++++ b/stdio-common/tst-fileno.c +@@ -28,10 +28,13 @@ check (const char *name, FILE *stream, int fd) + return sfd != fd; + } + +-int +-main (void) ++static int ++do_test (void) + { + return (check ("stdin", stdin, STDIN_FILENO) || + check ("stdout", stdout, STDOUT_FILENO) || + check ("stderr", stderr, STDERR_FILENO)); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-gets.c b/stdio-common/tst-gets.c +index 7f78fc1..052f1f9 100644 +--- a/stdio-common/tst-gets.c ++++ b/stdio-common/tst-gets.c +@@ -21,8 +21,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + char buf[100]; + int result = 0; +@@ -61,3 +61,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-obprintf.c b/stdio-common/tst-obprintf.c +index 39e8fda..5151593 100644 +--- a/stdio-common/tst-obprintf.c ++++ b/stdio-common/tst-obprintf.c +@@ -4,8 +4,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + struct obstack ob; + int n; +@@ -40,3 +40,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-perror.c b/stdio-common/tst-perror.c +index b809c2f..416b120 100644 +--- a/stdio-common/tst-perror.c ++++ b/stdio-common/tst-perror.c +@@ -24,8 +24,8 @@ + #define WC_EXP_LEN (sizeof (WC_EXP) - 1) + + +-int +-main (void) ++static int ++do_test (void) + { + int fd; + char fname[] = "/tmp/tst-perror.XXXXXX"; +@@ -152,3 +152,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-sprintf.c b/stdio-common/tst-sprintf.c +index c4e911f..2fe373f 100644 +--- a/stdio-common/tst-sprintf.c ++++ b/stdio-common/tst-sprintf.c +@@ -4,8 +4,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + char buf[100]; + int result = 0; +@@ -73,3 +73,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-sprintf2.c b/stdio-common/tst-sprintf2.c +index 422278d..0ddf15b 100644 +--- a/stdio-common/tst-sprintf2.c ++++ b/stdio-common/tst-sprintf2.c +@@ -3,8 +3,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + #if LDBL_MANT_DIG >= 106 + volatile union { long double l; long long x[2]; } u, v; +@@ -82,3 +82,6 @@ main (void) + #endif + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-sprintf3.c b/stdio-common/tst-sprintf3.c +index e54b23b..e927761 100644 +--- a/stdio-common/tst-sprintf3.c ++++ b/stdio-common/tst-sprintf3.c +@@ -22,8 +22,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + #if LDBL_MANT_DIG >= 106 + volatile union { long double l; long long x[2]; } u, v; +@@ -88,3 +88,6 @@ main (void) + #endif + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-swprintf.c b/stdio-common/tst-swprintf.c +index e65234b..ce62c6b 100644 +--- a/stdio-common/tst-swprintf.c ++++ b/stdio-common/tst-swprintf.c +@@ -12,8 +12,8 @@ + + const char input[] = "\x8e\xa1g\x8e\xa2h\x8e\xa3i\x8e\xa4j"; + +-int +-main (void) ++static int ++do_test (void) + { + wchar_t buf[1000]; + #define nbuf (sizeof (buf) / sizeof (buf[0])) +@@ -54,3 +54,6 @@ swprintf (.., .., L\"%ls\", \"%ls\") produced \"%ls\", not \"%ls\"\n", \ + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-tmpnam.c b/stdio-common/tst-tmpnam.c +index a3bd9fb..3b97064 100644 +--- a/stdio-common/tst-tmpnam.c ++++ b/stdio-common/tst-tmpnam.c +@@ -19,8 +19,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + const char *name; + int retval = 0; +@@ -48,3 +48,6 @@ main (void) + + return retval; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-unbputc.c b/stdio-common/tst-unbputc.c +index bbd8622..7200a82 100644 +--- a/stdio-common/tst-unbputc.c ++++ b/stdio-common/tst-unbputc.c +@@ -1,11 +1,14 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + putc ('1', stderr); + putc ('2', stderr); + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdio-common/tst-wc-printf.c b/stdio-common/tst-wc-printf.c +index abbeeb5..2a2acb5 100644 +--- a/stdio-common/tst-wc-printf.c ++++ b/stdio-common/tst-wc-printf.c +@@ -4,8 +4,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + wchar_t tmp[3]; + tmp[0] = '8'; +@@ -20,3 +20,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-environ.c b/stdlib/tst-environ.c +index 3316d7e..b1de2f9 100644 +--- a/stdlib/tst-environ.c ++++ b/stdlib/tst-environ.c +@@ -25,8 +25,8 @@ + + char putenv_val[100] = VAR "=some longer value"; + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + const char *valp; +@@ -219,3 +219,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-fmtmsg.c b/stdlib/tst-fmtmsg.c +index c3748d6..b7948c5 100644 +--- a/stdlib/tst-fmtmsg.c ++++ b/stdlib/tst-fmtmsg.c +@@ -7,8 +7,8 @@ + + #define MM_TEST 10 + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -80,3 +80,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-limits.c b/stdlib/tst-limits.c +index 265b9db..6e51dca 100644 +--- a/stdlib/tst-limits.c ++++ b/stdlib/tst-limits.c +@@ -16,8 +16,8 @@ bitval (int bits) + } + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -67,3 +67,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-rand48-2.c b/stdlib/tst-rand48-2.c +index 3079b98..8b8fef4 100644 +--- a/stdlib/tst-rand48-2.c ++++ b/stdlib/tst-rand48-2.c +@@ -3,8 +3,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + time_t t = time (NULL); + int i, ret = 0; +@@ -111,3 +111,6 @@ main (void) + + return ret; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-rand48.c b/stdlib/tst-rand48.c +index 52e1b96..973c62e 100644 +--- a/stdlib/tst-rand48.c ++++ b/stdlib/tst-rand48.c +@@ -8,8 +8,8 @@ + #endif + + +-int +-main (void) ++static int ++do_test (void) + { + unsigned short int xs[3] = { 0x0001, 0x0012, 0x0123 }; + unsigned short int lxs[7]; +@@ -388,3 +388,6 @@ drand48() and erand48 in lines %d and %d produce different results\n", + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-random.c b/stdlib/tst-random.c +index 47195d6..8fe0993 100644 +--- a/stdlib/tst-random.c ++++ b/stdlib/tst-random.c +@@ -46,8 +46,8 @@ const unsigned int seed[3] = { 0x12344321U, 0xEE11DD22U, 0xFEDCBA98 }; + + void fail (const char *msg, int s, int i) __attribute__ ((__noreturn__)); + +-int +-main (void) ++static int ++do_test (void) + { + long int rnd[nseq][nrnd]; /* pseudorandom numbers */ + char* state[nseq]; /* state for PRNG */ +@@ -117,3 +117,6 @@ fail (const char *msg, int s, int i) + printf ("%s (seq %d, pos %d).\n", msg, s, i); + exit (1); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-random2.c b/stdlib/tst-random2.c +index 0553b62..da840f3 100644 +--- a/stdlib/tst-random2.c ++++ b/stdlib/tst-random2.c +@@ -20,8 +20,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int pass; + int ret = 0; +@@ -56,3 +56,6 @@ main (void) + } + return ret; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-strtol.c b/stdlib/tst-strtol.c +index eebd8f7..448102a 100644 +--- a/stdlib/tst-strtol.c ++++ b/stdlib/tst-strtol.c +@@ -534,8 +534,8 @@ static const struct ltest tests[] = + /* Prototypes for local functions. */ + static void expand (char *dst, int c); + +-int +-main (void) ++static int ++do_test (void) + { + register const struct ltest *lt; + char *ep; +@@ -623,3 +623,6 @@ expand (dst, c) + else + (void) sprintf (dst, "%#.3o", (unsigned int) c); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-strtoll.c b/stdlib/tst-strtoll.c +index 0c77254..93f1a56 100644 +--- a/stdlib/tst-strtoll.c ++++ b/stdlib/tst-strtoll.c +@@ -309,8 +309,8 @@ static const struct ltest tests[] = + /* Prototypes for local functions. */ + static void expand (char *dst, int c); + +-int +-main (void) ++static int ++do_test (void) + { + register const struct ltest *lt; + char *ep; +@@ -398,3 +398,6 @@ expand (dst, c) + else + (void) sprintf (dst, "%#.3o", (unsigned int) c); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/stdlib/tst-xpg-basename.c b/stdlib/tst-xpg-basename.c +index 61e2e4b..facc783 100644 +--- a/stdlib/tst-xpg-basename.c ++++ b/stdlib/tst-xpg-basename.c +@@ -37,8 +37,8 @@ static struct + }; + + +-int +-main (void) ++static int ++do_test (void) + { + size_t i = 0; + int errors = 0; +@@ -64,3 +64,6 @@ main (void) + + return errors; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/string/test-ffs.c b/string/test-ffs.c +index 7ac1dd6..a64a1cc 100644 +--- a/string/test-ffs.c ++++ b/string/test-ffs.c +@@ -21,8 +21,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int failures = 0; + int i; +@@ -61,3 +61,6 @@ main (void) + + return failures; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/string/tst-bswap.c b/string/tst-bswap.c +index cca704c..6c1c911 100644 +--- a/string/tst-bswap.c ++++ b/string/tst-bswap.c +@@ -21,8 +21,8 @@ + + extern unsigned long long int wash (unsigned long long int a); + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -71,3 +71,6 @@ wash (unsigned long long int a) + regards the argument to the bswap_*() functions as constant. */ + return a + 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/string/tst-inlcall.c b/string/tst-inlcall.c +index 32d8863..0f8b1bd 100644 +--- a/string/tst-inlcall.c ++++ b/string/tst-inlcall.c +@@ -31,8 +31,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int status; + int errors = 0; +@@ -80,3 +80,6 @@ main (void) + } + return status; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/string/tst-strtok.c b/string/tst-strtok.c +index 7e34aee..6fbef9f 100644 +--- a/string/tst-strtok.c ++++ b/string/tst-strtok.c +@@ -2,8 +2,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + char buf[1] = { 0 }; + int result = 0; +@@ -21,3 +21,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/string/tst-strxfrm.c b/string/tst-strxfrm.c +index 2ae2e29..f48cfc0 100644 +--- a/string/tst-strxfrm.c ++++ b/string/tst-strxfrm.c +@@ -58,8 +58,8 @@ test (const char *locale) + } + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -69,3 +69,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/sysdeps/x86_64/tst-audit10.c b/sysdeps/x86_64/tst-audit10.c +index 24c9696..8d6721a 100644 +--- a/sysdeps/x86_64/tst-audit10.c ++++ b/sysdeps/x86_64/tst-audit10.c +@@ -45,8 +45,8 @@ avx512_enabled (void) + + extern __m512i audit_test (__m512i, __m512i, __m512i, __m512i, + __m512i, __m512i, __m512i, __m512i); +-int +-main (void) ++static int ++do_test (void) + { + /* Run AVX512 test only if AVX512 is supported. */ + if (avx512_enabled ()) +@@ -62,9 +62,12 @@ main (void) + return 0; + } + #else +-int +-main (void) ++static int ++do_test (void) + { + return 0; + } + #endif ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +diff --git a/elf/tst-audit3.c b/elf/tst-audit3.c +index d00db99..0602aa2 100644 +--- a/elf/tst-audit3.c ++++ b/elf/tst-audit3.c +@@ -7,8 +7,8 @@ + + extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, + __m128i, __m128i, __m128i, __m128i); +-int +-main (void) ++static int ++do_test (void) + { + __m128i xmm = _mm_setzero_si128 (); + __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); +@@ -18,3 +18,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +diff --git a/elf/tst-audit4.c b/elf/tst-audit4.c +index c4f1d5b..44d5123 100644 +--- a/elf/tst-audit4.c ++++ b/elf/tst-audit4.c +@@ -25,8 +25,8 @@ avx_enabled (void) + + extern __m256i audit_test (__m256i, __m256i, __m256i, __m256i, + __m256i, __m256i, __m256i, __m256i); +-int +-main (void) ++static int ++do_test (void) + { + /* Run AVX test only if AVX is supported. */ + if (avx_enabled ()) +@@ -41,9 +41,12 @@ main (void) + return 0; + } + #else +-int +-main (void) ++static int ++do_test (void) + { + return 0; + } + #endif ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +diff --git a/elf/tst-audit5.c b/elf/tst-audit5.c +index 0094fee..225b4c8 100644 +--- a/elf/tst-audit5.c ++++ b/elf/tst-audit5.c +@@ -7,8 +7,8 @@ + + extern __m128i audit_test (__m128i, __m128i, __m128i, __m128i, + __m128i, __m128i, __m128i, __m128i); +-int +-main (void) ++static int ++do_test (void) + { + __m128i xmm = _mm_setzero_si128 (); + __m128i ret = audit_test (xmm, xmm, xmm, xmm, xmm, xmm, xmm, xmm); +@@ -19,3 +19,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +diff --git a/time/tst-ftime_l.c b/time/tst-ftime_l.c +index fc3d78d..6690efe 100644 +--- a/time/tst-ftime_l.c ++++ b/time/tst-ftime_l.c +@@ -6,8 +6,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + locale_t l; + locale_t old; +@@ -124,3 +124,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/time/tst-getdate.c b/time/tst-getdate.c +index fd87923..b3377ee 100644 +--- a/time/tst-getdate.c ++++ b/time/tst-getdate.c +@@ -76,8 +76,8 @@ report_date_error (int err) + } + + +-int +-main (void) ++static int ++do_test (void) + { + int errors = 0; + size_t i; +@@ -121,3 +121,6 @@ main (void) + printf ("No errors found.\n"); + return errors != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/time/tst-mktime.c b/time/tst-mktime.c +index 416a856..c147360 100644 +--- a/time/tst-mktime.c ++++ b/time/tst-mktime.c +@@ -3,8 +3,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + struct tm time_str, *tm; + time_t t; +@@ -68,3 +68,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/time/tst-mktime3.c b/time/tst-mktime3.c +index 60d0e0b..c738e53 100644 +--- a/time/tst-mktime3.c ++++ b/time/tst-mktime3.c +@@ -17,8 +17,8 @@ struct tm expected[] = + { .tm_sec = 5, .tm_mday = 1, .tm_year = 102, .tm_wday = 2 } + }; + +-int +-main (void) ++static int ++do_test (void) + { + setenv ("TZ", "UTC", 1); + int i; +@@ -48,3 +48,6 @@ main (void) + } + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/time/tst-posixtz.c b/time/tst-posixtz.c +index 019d92a..c1ea267 100644 +--- a/time/tst-posixtz.c ++++ b/time/tst-posixtz.c +@@ -28,8 +28,8 @@ struct + "1999/02/25 15:18:12 dst=0 zone=EST" }, + }; + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + size_t cnt; +@@ -116,3 +116,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/time/tst-strptime2.c b/time/tst-strptime2.c +index 73552bb..bcd6cc8 100644 +--- a/time/tst-strptime2.c ++++ b/time/tst-strptime2.c +@@ -26,8 +26,8 @@ static const struct + #define ntests (sizeof (tests) / sizeof (tests[0])) + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -57,3 +57,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/time/tst-strptime3.c b/time/tst-strptime3.c +index 9a8c648..75b57c1 100644 +--- a/time/tst-strptime3.c ++++ b/time/tst-strptime3.c +@@ -4,8 +4,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + struct tm tm; +@@ -53,3 +53,6 @@ main (void) + + return 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-btowc.c b/wcsmbs/tst-btowc.c +index d793622..dc34f2b 100644 +--- a/wcsmbs/tst-btowc.c ++++ b/wcsmbs/tst-btowc.c +@@ -74,8 +74,8 @@ eof_test (void) + + + /* Test the btowc() function for a few locales with known character sets. */ +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -172,3 +172,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-mbrtowc.c b/wcsmbs/tst-mbrtowc.c +index 3e1eb72..a30b619 100644 +--- a/wcsmbs/tst-mbrtowc.c ++++ b/wcsmbs/tst-mbrtowc.c +@@ -151,8 +151,8 @@ utf8_test (void) + } + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -230,3 +230,6 @@ check_ascii (const char *locname) + + return res != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-mbsrtowcs.c b/wcsmbs/tst-mbsrtowcs.c +index 8d7e2cb..405534d 100644 +--- a/wcsmbs/tst-mbsrtowcs.c ++++ b/wcsmbs/tst-mbsrtowcs.c +@@ -21,8 +21,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + const unsigned char buf[] = { 'a', 'b', '\0', 'c', 'd', '\0', 'e' }; + wchar_t out[sizeof (buf)]; +@@ -62,3 +62,6 @@ main (void) + } + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-wchar-h.c b/wcsmbs/tst-wchar-h.c +index 4cf2dd0..fd2ad56 100644 +--- a/wcsmbs/tst-wchar-h.c ++++ b/wcsmbs/tst-wchar-h.c +@@ -1,9 +1,12 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + mbstate_t x; + return sizeof (x) - sizeof (mbstate_t); + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-wcpncpy.c b/wcsmbs/tst-wcpncpy.c +index 74765e7..4cf4aec 100644 +--- a/wcsmbs/tst-wcpncpy.c ++++ b/wcsmbs/tst-wcpncpy.c +@@ -20,8 +20,8 @@ + #include + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -74,3 +74,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-wcrtomb.c b/wcsmbs/tst-wcrtomb.c +index 3f052f3..cad343e 100644 +--- a/wcsmbs/tst-wcrtomb.c ++++ b/wcsmbs/tst-wcrtomb.c +@@ -26,8 +26,8 @@ + static int check_ascii (const char *locname); + + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + +@@ -92,3 +92,6 @@ check_ascii (const char *locname) + + return res != 0; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-wcsnlen.c b/wcsmbs/tst-wcsnlen.c +index 60e64ad..8d4b8b5 100644 +--- a/wcsmbs/tst-wcsnlen.c ++++ b/wcsmbs/tst-wcsnlen.c +@@ -27,8 +27,8 @@ + printf ("wcsnlen (L\"%s\", %d) = %d, not %d\n", Str, Max, n, Exp); \ + } + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + int n; +@@ -48,3 +48,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/wcsmbs/tst-wcstof.c b/wcsmbs/tst-wcstof.c +index 197cb5c..576a58c 100644 +--- a/wcsmbs/tst-wcstof.c ++++ b/wcsmbs/tst-wcstof.c +@@ -4,8 +4,8 @@ + #include + #include + +-int +-main (void) ++static int ++do_test (void) + { + int result = 0; + char buf[100]; +@@ -21,3 +21,6 @@ main (void) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh1298526-0.patch b/SOURCES/glibc-rh1298526-0.patch new file mode 100644 index 00000000..ae6cf62a --- /dev/null +++ b/SOURCES/glibc-rh1298526-0.patch @@ -0,0 +1,347 @@ +commit 83d776f979342f923b5c3d2a5b43afab841c6086 +Author: Andrew Senkevich +Date: Sat Dec 19 02:47:28 2015 +0300 + + Added memset optimized with AVX512 for KNL hardware. + + It shows improvement up to 28% over AVX2 memset (performance results + attached at ). + + * sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S: New file. + * sysdeps/x86_64/multiarch/Makefile (sysdep_routines): Added new file. + * sysdeps/x86_64/multiarch/ifunc-impl-list.c: Added new tests. + * sysdeps/x86_64/multiarch/memset.S: Added new IFUNC branch. + * sysdeps/x86_64/multiarch/memset_chk.S: Likewise. + * sysdeps/x86/cpu-features.h (bit_Prefer_No_VZEROUPPER, + index_Prefer_No_VZEROUPPER): New. + * sysdeps/x86/cpu-features.c (init_cpu_features): Set the + Prefer_No_VZEROUPPER for Knights Landing. + +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.c ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +@@ -76,6 +76,8 @@ init_cpu_features (struct cpu_features * + + case 0x57: + /* Knights Landing. Enable Silvermont optimizations. */ ++ cpu_features->feature[index_Prefer_No_VZEROUPPER] ++ |= bit_Prefer_No_VZEROUPPER; + + case 0x37: + case 0x4a: +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.h ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +@@ -33,6 +33,7 @@ + #define bit_AVX512F_Usable (1 << 12) + #define bit_AVX512DQ_Usable (1 << 13) + #define bit_Prefer_MAP_32BIT_EXEC (1 << 16) ++#define bit_Prefer_No_VZEROUPPER (1 << 17) + + /* CPUID Feature flags. */ + +@@ -93,6 +94,7 @@ + # define index_AVX512F_Usable FEATURE_INDEX_1*FEATURE_SIZE + # define index_AVX512DQ_Usable FEATURE_INDEX_1*FEATURE_SIZE + # define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Prefer_No_VZEROUPPER FEATURE_INDEX_1*FEATURE_SIZE + + # if defined (_LIBC) && !IS_IN (nonlib) + # ifdef __x86_64__ +@@ -270,6 +272,7 @@ extern const struct cpu_features *__get_ + # define index_AVX512F_Usable FEATURE_INDEX_1 + # define index_AVX512DQ_Usable FEATURE_INDEX_1 + # define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1 ++# define index_Prefer_No_VZEROUPPER FEATURE_INDEX_1 + + #endif /* !__ASSEMBLER__ */ + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile +@@ -16,7 +16,8 @@ sysdep_routines += strncat-c stpncpy-c s + strcat-sse2-unaligned strncat-sse2-unaligned \ + strcat-ssse3 strncat-ssse3 strlen-sse2-pminub \ + strnlen-sse2-no-bsf strrchr-sse2-no-bsf strchr-sse2-no-bsf \ +- memcmp-ssse3 strstr-sse2-unaligned ++ memcmp-ssse3 strstr-sse2-unaligned \ ++ memset-avx512-no-vzeroupper + ifeq (yes,$(config-cflags-sse4)) + sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c varshift + CFLAGS-varshift.c += -msse4 +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include "init-arch.h" + + /* Maximum number of IFUNC implementations. */ +@@ -66,12 +67,24 @@ __libc_ifunc_impl_list (const char *name + IFUNC_IMPL (i, name, __memset_chk, + IFUNC_IMPL_ADD (array, i, __memset_chk, 1, __memset_chk_sse2) + IFUNC_IMPL_ADD (array, i, __memset_chk, 1, +- __memset_chk_x86_64)) ++ __memset_chk_x86_64) ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ IFUNC_IMPL_ADD (array, i, __memset_chk, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __memset_chk_avx512_no_vzeroupper) ++#endif ++ ) + + /* Support sysdeps/x86_64/multiarch/memset.S. */ + IFUNC_IMPL (i, name, memset, + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_sse2) +- IFUNC_IMPL_ADD (array, i, memset, 1, __memset_x86_64)) ++ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_x86_64) ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ IFUNC_IMPL_ADD (array, i, memset, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __memset_avx512_no_vzeroupper) ++#endif ++ ) + + /* Support sysdeps/x86_64/multiarch/rawmemchr.S. */ + IFUNC_IMPL (i, name, rawmemchr, +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset-avx512-no-vzeroupper.S +@@ -0,0 +1,194 @@ ++/* memset optimized with AVX512 for KNL hardware. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined HAVE_AVX512_ASM_SUPPORT && IS_IN (libc) ++ ++#include "asm-syntax.h" ++#ifndef MEMSET ++# define MEMSET __memset_avx512_no_vzeroupper ++# define MEMSET_CHK __memset_chk_avx512_no_vzeroupper ++#endif ++ ++ .section .text,"ax",@progbits ++#if defined PIC ++ENTRY (MEMSET_CHK) ++ cmpq %rdx, %rcx ++ jb HIDDEN_JUMPTARGET (__chk_fail) ++END (MEMSET_CHK) ++#endif ++ ++ENTRY (MEMSET) ++ vpxor %xmm0, %xmm0, %xmm0 ++ vmovd %esi, %xmm1 ++ lea (%rdi, %rdx), %rsi ++ mov %rdi, %rax ++ vpshufb %xmm0, %xmm1, %xmm0 ++ cmp $16, %rdx ++ jb L(less_16bytes) ++ cmp $512, %rdx ++ vbroadcastss %xmm0, %zmm2 ++ ja L(512bytesormore) ++ cmp $256, %rdx ++ jb L(less_256bytes) ++ vmovups %zmm2, (%rdi) ++ vmovups %zmm2, 0x40(%rdi) ++ vmovups %zmm2, 0x80(%rdi) ++ vmovups %zmm2, 0xC0(%rdi) ++ vmovups %zmm2, -0x100(%rsi) ++ vmovups %zmm2, -0xC0(%rsi) ++ vmovups %zmm2, -0x80(%rsi) ++ vmovups %zmm2, -0x40(%rsi) ++ ret ++ ++L(less_256bytes): ++ cmp $128, %dl ++ jb L(less_128bytes) ++ vmovups %zmm2, (%rdi) ++ vmovups %zmm2, 0x40(%rdi) ++ vmovups %zmm2, -0x80(%rsi) ++ vmovups %zmm2, -0x40(%rsi) ++ ret ++ ++L(less_128bytes): ++ cmp $64, %dl ++ jb L(less_64bytes) ++ vmovups %zmm2, (%rdi) ++ vmovups %zmm2, -0x40(%rsi) ++ ret ++ ++L(less_64bytes): ++ cmp $32, %dl ++ jb L(less_32bytes) ++ vmovdqu %ymm2, (%rdi) ++ vmovdqu %ymm2, -0x20(%rsi) ++ ret ++ ++L(less_32bytes): ++ vmovdqu %xmm0, (%rdi) ++ vmovdqu %xmm0, -0x10(%rsi) ++ ret ++ ++L(less_16bytes): ++ cmp $8, %dl ++ jb L(less_8bytes) ++ vmovq %xmm0, (%rdi) ++ vmovq %xmm0, -0x08(%rsi) ++ ret ++ ++L(less_8bytes): ++ vmovd %xmm0, %ecx ++ cmp $4, %dl ++ jb L(less_4bytes) ++ mov %ecx, (%rdi) ++ mov %ecx, -0x04(%rsi) ++ ret ++ ++L(less_4bytes): ++ cmp $2, %dl ++ jb L(less_2bytes) ++ mov %cx, (%rdi) ++ mov %cx, -0x02(%rsi) ++ ret ++ ++L(less_2bytes): ++ cmp $1, %dl ++ jb L(less_1bytes) ++ mov %cl, (%rdi) ++L(less_1bytes): ++ ret ++ ++L(512bytesormore): ++ mov __x86_64_shared_cache_size_half(%rip), %rcx ++ cmp %rcx, %rdx ++ ja L(preloop_large) ++ cmp $1024, %rdx ++ ja L(1024bytesormore) ++ ++ vmovups %zmm2, (%rdi) ++ vmovups %zmm2, 0x40(%rdi) ++ vmovups %zmm2, 0x80(%rdi) ++ vmovups %zmm2, 0xC0(%rdi) ++ vmovups %zmm2, 0x100(%rdi) ++ vmovups %zmm2, 0x140(%rdi) ++ vmovups %zmm2, 0x180(%rdi) ++ vmovups %zmm2, 0x1C0(%rdi) ++ vmovups %zmm2, -0x200(%rsi) ++ vmovups %zmm2, -0x1C0(%rsi) ++ vmovups %zmm2, -0x180(%rsi) ++ vmovups %zmm2, -0x140(%rsi) ++ vmovups %zmm2, -0x100(%rsi) ++ vmovups %zmm2, -0xC0(%rsi) ++ vmovups %zmm2, -0x80(%rsi) ++ vmovups %zmm2, -0x40(%rsi) ++ ret ++ ++/* Align on 64 and loop with aligned stores. */ ++L(1024bytesormore): ++ sub $0x100, %rsi ++ vmovups %zmm2, (%rax) ++ and $-0x40, %rdi ++ add $0x40, %rdi ++ ++L(gobble_256bytes_loop): ++ vmovaps %zmm2, (%rdi) ++ vmovaps %zmm2, 0x40(%rdi) ++ vmovaps %zmm2, 0x80(%rdi) ++ vmovaps %zmm2, 0xC0(%rdi) ++ add $0x100, %rdi ++ cmp %rsi, %rdi ++ jb L(gobble_256bytes_loop) ++ vmovups %zmm2, (%rsi) ++ vmovups %zmm2, 0x40(%rsi) ++ vmovups %zmm2, 0x80(%rsi) ++ vmovups %zmm2, 0xC0(%rsi) ++ ret ++ ++/* Align on 128 and loop with non-temporal stores. */ ++L(preloop_large): ++ and $-0x80, %rdi ++ add $0x80, %rdi ++ vmovups %zmm2, (%rax) ++ vmovups %zmm2, 0x40(%rax) ++ sub $0x200, %rsi ++ ++L(gobble_512bytes_nt_loop): ++ vmovntdq %zmm2, (%rdi) ++ vmovntdq %zmm2, 0x40(%rdi) ++ vmovntdq %zmm2, 0x80(%rdi) ++ vmovntdq %zmm2, 0xC0(%rdi) ++ vmovntdq %zmm2, 0x100(%rdi) ++ vmovntdq %zmm2, 0x140(%rdi) ++ vmovntdq %zmm2, 0x180(%rdi) ++ vmovntdq %zmm2, 0x1C0(%rdi) ++ add $0x200, %rdi ++ cmp %rsi, %rdi ++ jb L(gobble_512bytes_nt_loop) ++ sfence ++ vmovups %zmm2, (%rsi) ++ vmovups %zmm2, 0x40(%rsi) ++ vmovups %zmm2, 0x80(%rsi) ++ vmovups %zmm2, 0xC0(%rsi) ++ vmovups %zmm2, 0x100(%rsi) ++ vmovups %zmm2, 0x140(%rsi) ++ vmovups %zmm2, 0x180(%rsi) ++ vmovups %zmm2, 0x1C0(%rsi) ++ ret ++END (MEMSET) ++#endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset.S +@@ -29,6 +29,13 @@ ENTRY(memset) + HAS_ARCH_FEATURE (Prefer_SSE_for_memop) + jz 2f + leaq __memset_sse2(%rip), %rax ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ jz 2f ++ HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ jz 2f ++ leaq __memset_avx512_no_vzeroupper(%rip), %rax ++#endif + 2: ret + END(memset) + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memset_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memset_chk.S +@@ -30,6 +30,13 @@ ENTRY(__memset_chk) + HAS_ARCH_FEATURE (Prefer_SSE_for_memop) + jz 2f + leaq __memset_chk_sse2(%rip), %rax ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ jz 2f ++ HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ jz 2f ++ leaq __memset_chk_avx512_no_vzeroupper(%rip), %rax ++#endif + 2: ret + END(__memset_chk) diff --git a/SOURCES/glibc-rh1298526-1.patch b/SOURCES/glibc-rh1298526-1.patch new file mode 100644 index 00000000..65110890 --- /dev/null +++ b/SOURCES/glibc-rh1298526-1.patch @@ -0,0 +1,725 @@ +commit 72276d6e8843db6df5971b06787f0a5e39bda138 +Author: Andrew Senkevich +Date: Sat Jan 16 00:49:45 2016 +0300 + + Added memcpy/memmove family optimized with AVX512 for KNL hardware. + + Added AVX512 implementations of memcpy, mempcpy, memmove, memcpy_chk, + mempcpy_chk, memmove_chk. + It shows average improvement more than 30% over AVX versions on KNL + hardware (performance results in the thread + ). + + * sysdeps/x86_64/multiarch/Makefile (sysdep_routines): Added new files. + * sysdeps/x86_64/multiarch/ifunc-impl-list.c: Added new tests. + * sysdeps/x86_64/multiarch/memcpy-avx512-no-vzeroupper.S: New file. + * sysdeps/x86_64/multiarch/mempcpy-avx512-no-vzeroupper.S: Likewise. + * sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S: Likewise. + * sysdeps/x86_64/multiarch/memcpy.S: Added new IFUNC branch. + * sysdeps/x86_64/multiarch/memcpy_chk.S: Likewise. + * sysdeps/x86_64/multiarch/memmove.c: Likewise. + * sysdeps/x86_64/multiarch/memmove_chk.c: Likewise. + * sysdeps/x86_64/multiarch/mempcpy.S: Likewise. + * sysdeps/x86_64/multiarch/mempcpy_chk.S: Likewise. + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/Makefile +@@ -17,7 +17,8 @@ sysdep_routines += strncat-c stpncpy-c s + strcat-ssse3 strncat-ssse3 strlen-sse2-pminub \ + strnlen-sse2-no-bsf strrchr-sse2-no-bsf strchr-sse2-no-bsf \ + memcmp-ssse3 strstr-sse2-unaligned \ +- memset-avx512-no-vzeroupper ++ memset-avx512-no-vzeroupper memcpy-avx512-no-vzeroupper \ ++ mempcpy-avx512-no-vzeroupper memmove-avx512-no-vzeroupper + ifeq (yes,$(config-cflags-sse4)) + sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c varshift + CFLAGS-varshift.c += -msse4 +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -24,7 +24,7 @@ + #include "init-arch.h" + + /* Maximum number of IFUNC implementations. */ +-#define MAX_IFUNC 4 ++#define MAX_IFUNC 5 + + /* Fill ARRAY of MAX elements with IFUNC implementations for function + NAME supported on target machine and return the number of valid +@@ -46,8 +46,11 @@ __libc_ifunc_impl_list (const char *name + __memcmp_ssse3) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_sse2)) + +- /* Support sysdeps/x86_64/multiarch/memmove_chk.S. */ ++ /* Support sysdeps/x86_64/multiarch/memmove_chk.c. */ + IFUNC_IMPL (i, name, __memmove_chk, ++ IFUNC_IMPL_ADD (array, i, __memmove_chk, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __memmove_chk_avx512_no_vzeroupper) + IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3_back) + IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), +@@ -57,6 +60,9 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/memmove.S. */ + IFUNC_IMPL (i, name, memmove, ++ IFUNC_IMPL_ADD (array, i, memmove, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __memmove_avx512_no_vzeroupper) + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3_back) + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), +@@ -263,6 +269,9 @@ __libc_ifunc_impl_list (const char *name + #ifdef SHARED + /* Support sysdeps/x86_64/multiarch/memcpy_chk.S. */ + IFUNC_IMPL (i, name, __memcpy_chk, ++ IFUNC_IMPL_ADD (array, i, __memcpy_chk, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __memcpy_chk_avx512_no_vzeroupper) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3_back) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), +@@ -274,11 +283,18 @@ __libc_ifunc_impl_list (const char *name + IFUNC_IMPL (i, name, memcpy, + IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), + __memcpy_ssse3_back) +- IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), __memcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), ++ __memcpy_ssse3) ++ IFUNC_IMPL_ADD (array, i, memcpy, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __memcpy_avx512_no_vzeroupper) + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/mempcpy_chk.S. */ + IFUNC_IMPL (i, name, __mempcpy_chk, ++ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __mempcpy_chk_avx512_no_vzeroupper) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3_back) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), +@@ -288,6 +304,9 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/mempcpy.S. */ + IFUNC_IMPL (i, name, mempcpy, ++ IFUNC_IMPL_ADD (array, i, mempcpy, ++ HAS_ARCH_FEATURE (AVX512F_Usable), ++ __mempcpy_avx512_no_vzeroupper) + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3_back) + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy-avx512-no-vzeroupper.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy-avx512-no-vzeroupper.S +@@ -0,0 +1,408 @@ ++/* memcpy optimized with AVX512 for KNL hardware. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined HAVE_AVX512_ASM_SUPPORT && IS_IN (libc) \ ++ && (defined SHARED \ ++ || defined USE_AS_MEMMOVE \ ++ || !defined USE_MULTIARCH) ++ ++#include "asm-syntax.h" ++#ifndef MEMCPY ++# define MEMCPY __memcpy_avx512_no_vzeroupper ++# define MEMCPY_CHK __memcpy_chk_avx512_no_vzeroupper ++#endif ++ ++ .section .text,"ax",@progbits ++#if !defined USE_AS_BCOPY ++ENTRY (MEMCPY_CHK) ++ cmpq %rdx, %rcx ++ jb HIDDEN_JUMPTARGET (__chk_fail) ++END (MEMCPY_CHK) ++#endif ++ ++ENTRY (MEMCPY) ++ mov %rdi, %rax ++#ifdef USE_AS_MEMPCPY ++ add %rdx, %rax ++#endif ++ lea (%rsi, %rdx), %rcx ++ lea (%rdi, %rdx), %r9 ++ cmp $512, %rdx ++ ja L(512bytesormore) ++ ++L(check): ++ cmp $16, %rdx ++ jbe L(less_16bytes) ++ cmp $256, %rdx ++ jb L(less_256bytes) ++ vmovups (%rsi), %zmm0 ++ vmovups 0x40(%rsi), %zmm1 ++ vmovups 0x80(%rsi), %zmm2 ++ vmovups 0xC0(%rsi), %zmm3 ++ vmovups -0x100(%rcx), %zmm4 ++ vmovups -0xC0(%rcx), %zmm5 ++ vmovups -0x80(%rcx), %zmm6 ++ vmovups -0x40(%rcx), %zmm7 ++ vmovups %zmm0, (%rdi) ++ vmovups %zmm1, 0x40(%rdi) ++ vmovups %zmm2, 0x80(%rdi) ++ vmovups %zmm3, 0xC0(%rdi) ++ vmovups %zmm4, -0x100(%r9) ++ vmovups %zmm5, -0xC0(%r9) ++ vmovups %zmm6, -0x80(%r9) ++ vmovups %zmm7, -0x40(%r9) ++ ret ++ ++L(less_256bytes): ++ cmp $128, %dl ++ jb L(less_128bytes) ++ vmovups (%rsi), %zmm0 ++ vmovups 0x40(%rsi), %zmm1 ++ vmovups -0x80(%rcx), %zmm2 ++ vmovups -0x40(%rcx), %zmm3 ++ vmovups %zmm0, (%rdi) ++ vmovups %zmm1, 0x40(%rdi) ++ vmovups %zmm2, -0x80(%r9) ++ vmovups %zmm3, -0x40(%r9) ++ ret ++ ++L(less_128bytes): ++ cmp $64, %dl ++ jb L(less_64bytes) ++ vmovdqu (%rsi), %ymm0 ++ vmovdqu 0x20(%rsi), %ymm1 ++ vmovdqu -0x40(%rcx), %ymm2 ++ vmovdqu -0x20(%rcx), %ymm3 ++ vmovdqu %ymm0, (%rdi) ++ vmovdqu %ymm1, 0x20(%rdi) ++ vmovdqu %ymm2, -0x40(%r9) ++ vmovdqu %ymm3, -0x20(%r9) ++ ret ++ ++L(less_64bytes): ++ cmp $32, %dl ++ jb L(less_32bytes) ++ vmovdqu (%rsi), %ymm0 ++ vmovdqu -0x20(%rcx), %ymm1 ++ vmovdqu %ymm0, (%rdi) ++ vmovdqu %ymm1, -0x20(%r9) ++ ret ++ ++L(less_32bytes): ++ vmovdqu (%rsi), %xmm0 ++ vmovdqu -0x10(%rcx), %xmm1 ++ vmovdqu %xmm0, (%rdi) ++ vmovdqu %xmm1, -0x10(%r9) ++ ret ++ ++L(less_16bytes): ++ cmp $8, %dl ++ jb L(less_8bytes) ++ movq (%rsi), %rsi ++ movq -0x8(%rcx), %rcx ++ movq %rsi, (%rdi) ++ movq %rcx, -0x8(%r9) ++ ret ++ ++L(less_8bytes): ++ cmp $4, %dl ++ jb L(less_4bytes) ++ mov (%rsi), %esi ++ mov -0x4(%rcx), %ecx ++ mov %esi, (%rdi) ++ mov %ecx, -0x4(%r9) ++ ret ++ ++L(less_4bytes): ++ cmp $2, %dl ++ jb L(less_2bytes) ++ mov (%rsi), %si ++ mov -0x2(%rcx), %cx ++ mov %si, (%rdi) ++ mov %cx, -0x2(%r9) ++ ret ++ ++L(less_2bytes): ++ cmp $1, %dl ++ jb L(less_1bytes) ++ mov (%rsi), %cl ++ mov %cl, (%rdi) ++L(less_1bytes): ++ ret ++ ++L(512bytesormore): ++#ifdef SHARED_CACHE_SIZE_HALF ++ mov $SHARED_CACHE_SIZE_HALF, %r8 ++#else ++ mov __x86_64_shared_cache_size_half(%rip), %r8 ++#endif ++ cmp %r8, %rdx ++ jae L(preloop_large) ++ cmp $1024, %rdx ++ ja L(1024bytesormore) ++ prefetcht1 (%rsi) ++ prefetcht1 0x40(%rsi) ++ prefetcht1 0x80(%rsi) ++ prefetcht1 0xC0(%rsi) ++ prefetcht1 0x100(%rsi) ++ prefetcht1 0x140(%rsi) ++ prefetcht1 0x180(%rsi) ++ prefetcht1 0x1C0(%rsi) ++ prefetcht1 -0x200(%rcx) ++ prefetcht1 -0x1C0(%rcx) ++ prefetcht1 -0x180(%rcx) ++ prefetcht1 -0x140(%rcx) ++ prefetcht1 -0x100(%rcx) ++ prefetcht1 -0xC0(%rcx) ++ prefetcht1 -0x80(%rcx) ++ prefetcht1 -0x40(%rcx) ++ vmovups (%rsi), %zmm0 ++ vmovups 0x40(%rsi), %zmm1 ++ vmovups 0x80(%rsi), %zmm2 ++ vmovups 0xC0(%rsi), %zmm3 ++ vmovups 0x100(%rsi), %zmm4 ++ vmovups 0x140(%rsi), %zmm5 ++ vmovups 0x180(%rsi), %zmm6 ++ vmovups 0x1C0(%rsi), %zmm7 ++ vmovups -0x200(%rcx), %zmm8 ++ vmovups -0x1C0(%rcx), %zmm9 ++ vmovups -0x180(%rcx), %zmm10 ++ vmovups -0x140(%rcx), %zmm11 ++ vmovups -0x100(%rcx), %zmm12 ++ vmovups -0xC0(%rcx), %zmm13 ++ vmovups -0x80(%rcx), %zmm14 ++ vmovups -0x40(%rcx), %zmm15 ++ vmovups %zmm0, (%rdi) ++ vmovups %zmm1, 0x40(%rdi) ++ vmovups %zmm2, 0x80(%rdi) ++ vmovups %zmm3, 0xC0(%rdi) ++ vmovups %zmm4, 0x100(%rdi) ++ vmovups %zmm5, 0x140(%rdi) ++ vmovups %zmm6, 0x180(%rdi) ++ vmovups %zmm7, 0x1C0(%rdi) ++ vmovups %zmm8, -0x200(%r9) ++ vmovups %zmm9, -0x1C0(%r9) ++ vmovups %zmm10, -0x180(%r9) ++ vmovups %zmm11, -0x140(%r9) ++ vmovups %zmm12, -0x100(%r9) ++ vmovups %zmm13, -0xC0(%r9) ++ vmovups %zmm14, -0x80(%r9) ++ vmovups %zmm15, -0x40(%r9) ++ ret ++ ++L(1024bytesormore): ++ cmp %rsi, %rdi ++ ja L(1024bytesormore_bkw) ++ sub $512, %r9 ++ vmovups -0x200(%rcx), %zmm8 ++ vmovups -0x1C0(%rcx), %zmm9 ++ vmovups -0x180(%rcx), %zmm10 ++ vmovups -0x140(%rcx), %zmm11 ++ vmovups -0x100(%rcx), %zmm12 ++ vmovups -0xC0(%rcx), %zmm13 ++ vmovups -0x80(%rcx), %zmm14 ++ vmovups -0x40(%rcx), %zmm15 ++ prefetcht1 (%rsi) ++ prefetcht1 0x40(%rsi) ++ prefetcht1 0x80(%rsi) ++ prefetcht1 0xC0(%rsi) ++ prefetcht1 0x100(%rsi) ++ prefetcht1 0x140(%rsi) ++ prefetcht1 0x180(%rsi) ++ prefetcht1 0x1C0(%rsi) ++ ++/* Loop with unaligned memory access. */ ++L(gobble_512bytes_loop): ++ vmovups (%rsi), %zmm0 ++ vmovups 0x40(%rsi), %zmm1 ++ vmovups 0x80(%rsi), %zmm2 ++ vmovups 0xC0(%rsi), %zmm3 ++ vmovups 0x100(%rsi), %zmm4 ++ vmovups 0x140(%rsi), %zmm5 ++ vmovups 0x180(%rsi), %zmm6 ++ vmovups 0x1C0(%rsi), %zmm7 ++ add $512, %rsi ++ prefetcht1 (%rsi) ++ prefetcht1 0x40(%rsi) ++ prefetcht1 0x80(%rsi) ++ prefetcht1 0xC0(%rsi) ++ prefetcht1 0x100(%rsi) ++ prefetcht1 0x140(%rsi) ++ prefetcht1 0x180(%rsi) ++ prefetcht1 0x1C0(%rsi) ++ vmovups %zmm0, (%rdi) ++ vmovups %zmm1, 0x40(%rdi) ++ vmovups %zmm2, 0x80(%rdi) ++ vmovups %zmm3, 0xC0(%rdi) ++ vmovups %zmm4, 0x100(%rdi) ++ vmovups %zmm5, 0x140(%rdi) ++ vmovups %zmm6, 0x180(%rdi) ++ vmovups %zmm7, 0x1C0(%rdi) ++ add $512, %rdi ++ cmp %r9, %rdi ++ jb L(gobble_512bytes_loop) ++ vmovups %zmm8, (%r9) ++ vmovups %zmm9, 0x40(%r9) ++ vmovups %zmm10, 0x80(%r9) ++ vmovups %zmm11, 0xC0(%r9) ++ vmovups %zmm12, 0x100(%r9) ++ vmovups %zmm13, 0x140(%r9) ++ vmovups %zmm14, 0x180(%r9) ++ vmovups %zmm15, 0x1C0(%r9) ++ ret ++ ++L(1024bytesormore_bkw): ++ add $512, %rdi ++ vmovups 0x1C0(%rsi), %zmm8 ++ vmovups 0x180(%rsi), %zmm9 ++ vmovups 0x140(%rsi), %zmm10 ++ vmovups 0x100(%rsi), %zmm11 ++ vmovups 0xC0(%rsi), %zmm12 ++ vmovups 0x80(%rsi), %zmm13 ++ vmovups 0x40(%rsi), %zmm14 ++ vmovups (%rsi), %zmm15 ++ prefetcht1 -0x40(%rcx) ++ prefetcht1 -0x80(%rcx) ++ prefetcht1 -0xC0(%rcx) ++ prefetcht1 -0x100(%rcx) ++ prefetcht1 -0x140(%rcx) ++ prefetcht1 -0x180(%rcx) ++ prefetcht1 -0x1C0(%rcx) ++ prefetcht1 -0x200(%rcx) ++ ++/* Backward loop with unaligned memory access. */ ++L(gobble_512bytes_loop_bkw): ++ vmovups -0x40(%rcx), %zmm0 ++ vmovups -0x80(%rcx), %zmm1 ++ vmovups -0xC0(%rcx), %zmm2 ++ vmovups -0x100(%rcx), %zmm3 ++ vmovups -0x140(%rcx), %zmm4 ++ vmovups -0x180(%rcx), %zmm5 ++ vmovups -0x1C0(%rcx), %zmm6 ++ vmovups -0x200(%rcx), %zmm7 ++ sub $512, %rcx ++ prefetcht1 -0x40(%rcx) ++ prefetcht1 -0x80(%rcx) ++ prefetcht1 -0xC0(%rcx) ++ prefetcht1 -0x100(%rcx) ++ prefetcht1 -0x140(%rcx) ++ prefetcht1 -0x180(%rcx) ++ prefetcht1 -0x1C0(%rcx) ++ prefetcht1 -0x200(%rcx) ++ vmovups %zmm0, -0x40(%r9) ++ vmovups %zmm1, -0x80(%r9) ++ vmovups %zmm2, -0xC0(%r9) ++ vmovups %zmm3, -0x100(%r9) ++ vmovups %zmm4, -0x140(%r9) ++ vmovups %zmm5, -0x180(%r9) ++ vmovups %zmm6, -0x1C0(%r9) ++ vmovups %zmm7, -0x200(%r9) ++ sub $512, %r9 ++ cmp %rdi, %r9 ++ ja L(gobble_512bytes_loop_bkw) ++ vmovups %zmm8, -0x40(%rdi) ++ vmovups %zmm9, -0x80(%rdi) ++ vmovups %zmm10, -0xC0(%rdi) ++ vmovups %zmm11, -0x100(%rdi) ++ vmovups %zmm12, -0x140(%rdi) ++ vmovups %zmm13, -0x180(%rdi) ++ vmovups %zmm14, -0x1C0(%rdi) ++ vmovups %zmm15, -0x200(%rdi) ++ ret ++ ++L(preloop_large): ++ cmp %rsi, %rdi ++ ja L(preloop_large_bkw) ++ vmovups (%rsi), %zmm4 ++ vmovups 0x40(%rsi), %zmm5 ++ ++/* Align destination for access with non-temporal stores in the loop. */ ++ mov %rdi, %r8 ++ and $-0x80, %rdi ++ add $0x80, %rdi ++ sub %rdi, %r8 ++ sub %r8, %rsi ++ add %r8, %rdx ++L(gobble_256bytes_nt_loop): ++ prefetcht1 0x200(%rsi) ++ prefetcht1 0x240(%rsi) ++ prefetcht1 0x280(%rsi) ++ prefetcht1 0x2C0(%rsi) ++ prefetcht1 0x300(%rsi) ++ prefetcht1 0x340(%rsi) ++ prefetcht1 0x380(%rsi) ++ prefetcht1 0x3C0(%rsi) ++ vmovdqu64 (%rsi), %zmm0 ++ vmovdqu64 0x40(%rsi), %zmm1 ++ vmovdqu64 0x80(%rsi), %zmm2 ++ vmovdqu64 0xC0(%rsi), %zmm3 ++ vmovntdq %zmm0, (%rdi) ++ vmovntdq %zmm1, 0x40(%rdi) ++ vmovntdq %zmm2, 0x80(%rdi) ++ vmovntdq %zmm3, 0xC0(%rdi) ++ sub $256, %rdx ++ add $256, %rsi ++ add $256, %rdi ++ cmp $256, %rdx ++ ja L(gobble_256bytes_nt_loop) ++ sfence ++ vmovups %zmm4, (%rax) ++ vmovups %zmm5, 0x40(%rax) ++ jmp L(check) ++ ++L(preloop_large_bkw): ++ vmovups -0x80(%rcx), %zmm4 ++ vmovups -0x40(%rcx), %zmm5 ++ ++/* Align end of destination for access with non-temporal stores. */ ++ mov %r9, %r8 ++ and $-0x80, %r9 ++ sub %r9, %r8 ++ sub %r8, %rcx ++ sub %r8, %rdx ++ add %r9, %r8 ++L(gobble_256bytes_nt_loop_bkw): ++ prefetcht1 -0x400(%rcx) ++ prefetcht1 -0x3C0(%rcx) ++ prefetcht1 -0x380(%rcx) ++ prefetcht1 -0x340(%rcx) ++ prefetcht1 -0x300(%rcx) ++ prefetcht1 -0x2C0(%rcx) ++ prefetcht1 -0x280(%rcx) ++ prefetcht1 -0x240(%rcx) ++ vmovdqu64 -0x100(%rcx), %zmm0 ++ vmovdqu64 -0xC0(%rcx), %zmm1 ++ vmovdqu64 -0x80(%rcx), %zmm2 ++ vmovdqu64 -0x40(%rcx), %zmm3 ++ vmovntdq %zmm0, -0x100(%r9) ++ vmovntdq %zmm1, -0xC0(%r9) ++ vmovntdq %zmm2, -0x80(%r9) ++ vmovntdq %zmm3, -0x40(%r9) ++ sub $256, %rdx ++ sub $256, %rcx ++ sub $256, %r9 ++ cmp $256, %rdx ++ ja L(gobble_256bytes_nt_loop_bkw) ++ sfence ++ vmovups %zmm4, -0x80(%r8) ++ vmovups %zmm5, -0x40(%r8) ++ jmp L(check) ++END (MEMCPY) ++#endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy.S +@@ -30,7 +30,15 @@ + ENTRY(__new_memcpy) + .type __new_memcpy, @gnu_indirect_function + LOAD_RTLD_GLOBAL_RO_RDX +- leaq __memcpy_sse2(%rip), %rax ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ jz 1f ++ HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ jz 1f ++ leaq __memcpy_avx512_no_vzeroupper(%rip), %rax ++ ret ++#endif ++1: leaq __memcpy_sse2(%rip), %rax + HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __memcpy_ssse3(%rip), %rax +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +@@ -30,7 +30,15 @@ + ENTRY(__memcpy_chk) + .type __memcpy_chk, @gnu_indirect_function + LOAD_RTLD_GLOBAL_RO_RDX +- leaq __memcpy_chk_sse2(%rip), %rax ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ jz 1f ++# HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++# jz 1f ++ leaq __memcpy_avx512_no_vzeroupper(%rip), %rax ++ ret ++#endif ++1: leaq __memcpy_chk_sse2(%rip), %rax + HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __memcpy_chk_ssse3(%rip), %rax +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove-avx512-no-vzeroupper.S +@@ -0,0 +1,22 @@ ++/* memmove optimized with AVX512 for KNL hardware. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_MEMMOVE ++#define MEMCPY __memmove_avx512_no_vzeroupper ++#define MEMCPY_CHK __memmove_chk_avx512_no_vzeroupper ++#include "memcpy-avx512-no-vzeroupper.S" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memmove.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove.c +@@ -35,6 +35,9 @@ + extern __typeof (__redirect_memmove) __memmove_sse2 attribute_hidden; + extern __typeof (__redirect_memmove) __memmove_ssse3 attribute_hidden; + extern __typeof (__redirect_memmove) __memmove_ssse3_back attribute_hidden; ++# ifdef HAVE_AVX512_ASM_SUPPORT ++extern __typeof (__redirect_memmove) __memmove_avx512_no_vzeroupper attribute_hidden; ++# endif + #endif + + #include "string/memmove.c" +@@ -47,10 +50,16 @@ extern __typeof (__redirect_memmove) __m + ifunc symbol properly. */ + extern __typeof (__redirect_memmove) __libc_memmove; + libc_ifunc (__libc_memmove, +- HAS_CPU_FEATURE (SSSE3) ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ && HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ ? __memmove_avx512_no_vzeroupper ++ : ++#endif ++ (HAS_CPU_FEATURE (SSSE3) + ? (HAS_ARCH_FEATURE (Fast_Copy_Backward) + ? __memmove_ssse3_back : __memmove_ssse3) +- : __memmove_sse2) ++ : __memmove_sse2)) + + strong_alias (__libc_memmove, memmove) + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove_chk.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memmove_chk.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memmove_chk.c +@@ -25,11 +25,20 @@ + extern __typeof (__memmove_chk) __memmove_chk_sse2 attribute_hidden; + extern __typeof (__memmove_chk) __memmove_chk_ssse3 attribute_hidden; + extern __typeof (__memmove_chk) __memmove_chk_ssse3_back attribute_hidden; ++# ifdef HAVE_AVX512_ASM_SUPPORT ++extern __typeof (__memmove_chk) __memmove_chk_avx512_no_vzeroupper attribute_hidden; ++# endif + + #include "debug/memmove_chk.c" + + libc_ifunc (__memmove_chk, +- HAS_CPU_FEATURE (SSSE3) ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ && HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ ? __memmove_chk_avx512_no_vzeroupper ++ : ++#endif ++ (HAS_CPU_FEATURE (SSSE3) + ? (HAS_ARCH_FEATURE (Fast_Copy_Backward) + ? __memmove_chk_ssse3_back : __memmove_chk_ssse3) +- : __memmove_chk_sse2); ++ : __memmove_chk_sse2)); +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy-avx512-no-vzeroupper.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy-avx512-no-vzeroupper.S +@@ -0,0 +1,22 @@ ++/* mempcpy optimized with AVX512 for KNL hardware. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_MEMPCPY ++#define MEMCPY __mempcpy_avx512_no_vzeroupper ++#define MEMCPY_CHK __mempcpy_chk_avx512_no_vzeroupper ++#include "memcpy-avx512-no-vzeroupper.S" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/mempcpy.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy.S +@@ -28,7 +28,15 @@ + ENTRY(__mempcpy) + .type __mempcpy, @gnu_indirect_function + LOAD_RTLD_GLOBAL_RO_RDX +- leaq __mempcpy_sse2(%rip), %rax ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ jz 1f ++ HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ jz 1f ++ leaq __mempcpy_avx512_no_vzeroupper(%rip), %rax ++ ret ++#endif ++1: leaq __mempcpy_sse2(%rip), %rax + HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __mempcpy_ssse3(%rip), %rax +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/mempcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/mempcpy_chk.S +@@ -30,7 +30,15 @@ + ENTRY(__mempcpy_chk) + .type __mempcpy_chk, @gnu_indirect_function + LOAD_RTLD_GLOBAL_RO_RDX +- leaq __mempcpy_chk_sse2(%rip), %rax ++#ifdef HAVE_AVX512_ASM_SUPPORT ++ HAS_ARCH_FEATURE (AVX512F_Usable) ++ jz 1f ++ HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ jz 1f ++ leaq __mempcpy_chk_avx512_no_vzeroupper(%rip), %rax ++ ret ++#endif ++1: leaq __mempcpy_chk_sse2(%rip), %rax + HAS_CPU_FEATURE (SSSE3) + jz 2f + leaq __mempcpy_chk_ssse3(%rip), %rax diff --git a/SOURCES/glibc-rh1298526-2.patch b/SOURCES/glibc-rh1298526-2.patch new file mode 100644 index 00000000..0993e051 --- /dev/null +++ b/SOURCES/glibc-rh1298526-2.patch @@ -0,0 +1,25 @@ +commit 214a44f3949624623bd9f5ced82a47915259324e +Author: Andrew Senkevich +Date: Sat Jan 16 14:42:26 2016 +0300 + + Fixed typos in __memcpy_chk. + + * sysdeps/x86_64/multiarch/memcpy_chk.S: Fixed typos. + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/memcpy_chk.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/memcpy_chk.S +@@ -33,9 +33,9 @@ ENTRY(__memcpy_chk) + #ifdef HAVE_AVX512_ASM_SUPPORT + HAS_ARCH_FEATURE (AVX512F_Usable) + jz 1f +-# HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) +-# jz 1f +- leaq __memcpy_avx512_no_vzeroupper(%rip), %rax ++ HAS_ARCH_FEATURE (Prefer_No_VZEROUPPER) ++ jz 1f ++ leaq __memcpy_chk_avx512_no_vzeroupper(%rip), %rax + ret + #endif + 1: leaq __memcpy_chk_sse2(%rip), %rax diff --git a/SOURCES/glibc-rh1298526-3.patch b/SOURCES/glibc-rh1298526-3.patch new file mode 100644 index 00000000..405143ff --- /dev/null +++ b/SOURCES/glibc-rh1298526-3.patch @@ -0,0 +1,82 @@ +commit df782dc690775d93b0cc1076655a9b92b5a44ad0 +Author: Andrew Senkevich +Date: Tue Jan 19 14:34:53 2016 +0300 + + Fixed build with assembler w/o AVX-512 support. + + * sysdeps/x86_64/multiarch/ifunc-impl-list.c: Fixed build with + assembler not supporting AVX-512. + +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/ifunc-impl-list.c +@@ -48,9 +48,11 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/memmove_chk.c. */ + IFUNC_IMPL (i, name, __memmove_chk, ++#ifdef HAVE_AVX512_ASM_SUPPORT + IFUNC_IMPL_ADD (array, i, __memmove_chk, + HAS_ARCH_FEATURE (AVX512F_Usable), + __memmove_chk_avx512_no_vzeroupper) ++#endif + IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), + __memmove_chk_ssse3_back) + IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_CPU_FEATURE (SSSE3), +@@ -60,9 +62,11 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/memmove.S. */ + IFUNC_IMPL (i, name, memmove, ++#ifdef HAVE_AVX512_ASM_SUPPORT + IFUNC_IMPL_ADD (array, i, memmove, + HAS_ARCH_FEATURE (AVX512F_Usable), + __memmove_avx512_no_vzeroupper) ++#endif + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), + __memmove_ssse3_back) + IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3), +@@ -269,9 +273,11 @@ __libc_ifunc_impl_list (const char *name + #ifdef SHARED + /* Support sysdeps/x86_64/multiarch/memcpy_chk.S. */ + IFUNC_IMPL (i, name, __memcpy_chk, ++#ifdef HAVE_AVX512_ASM_SUPPORT + IFUNC_IMPL_ADD (array, i, __memcpy_chk, + HAS_ARCH_FEATURE (AVX512F_Usable), + __memcpy_chk_avx512_no_vzeroupper) ++#endif + IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), + __memcpy_chk_ssse3_back) + IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_CPU_FEATURE (SSSE3), +@@ -285,16 +291,20 @@ __libc_ifunc_impl_list (const char *name + __memcpy_ssse3_back) + IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3), + __memcpy_ssse3) ++#ifdef HAVE_AVX512_ASM_SUPPORT + IFUNC_IMPL_ADD (array, i, memcpy, + HAS_ARCH_FEATURE (AVX512F_Usable), + __memcpy_avx512_no_vzeroupper) ++#endif + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_sse2)) + + /* Support sysdeps/x86_64/multiarch/mempcpy_chk.S. */ + IFUNC_IMPL (i, name, __mempcpy_chk, ++#ifdef HAVE_AVX512_ASM_SUPPORT + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, + HAS_ARCH_FEATURE (AVX512F_Usable), + __mempcpy_chk_avx512_no_vzeroupper) ++#endif + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), + __mempcpy_chk_ssse3_back) + IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_CPU_FEATURE (SSSE3), +@@ -304,9 +314,11 @@ __libc_ifunc_impl_list (const char *name + + /* Support sysdeps/x86_64/multiarch/mempcpy.S. */ + IFUNC_IMPL (i, name, mempcpy, ++#ifdef HAVE_AVX512_ASM_SUPPORT + IFUNC_IMPL_ADD (array, i, mempcpy, + HAS_ARCH_FEATURE (AVX512F_Usable), + __mempcpy_avx512_no_vzeroupper) ++#endif + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), + __mempcpy_ssse3_back) + IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3), diff --git a/SOURCES/glibc-rh1298526-4.patch b/SOURCES/glibc-rh1298526-4.patch new file mode 100644 index 00000000..249da9e0 --- /dev/null +++ b/SOURCES/glibc-rh1298526-4.patch @@ -0,0 +1,61 @@ +Allows testing of AVX512 changes in a chroot (normally as root) +without build issues. + +commit d7e06450b9d730d7b62ba52f611585810fa902df +Author: Carlos O'Donell +Date: Tue Jul 16 17:55:43 2013 -0400 + + BZ #15711: Avoid circular dependency for syscall.h + + The generated header is compiled with `-ffreestanding' to avoid any + circular dependencies against the installed implementation headers. + Such a dependency would require the implementation header to be + installed before the generated header could be built (See bug 15711). + In current practice the generated header dependencies do not include + any of the implementation headers removed by the use of `-ffreestanding'. + + --- + + 2013-07-15 Carlos O'Donell + + [BZ #15711] + * sysdeps/unix/sysv/linux/Makefile ($(objpfx)bits/syscall%h): + Avoid system header dependency with -ffreestanding. + ($(objpfx)bits/syscall%d): Likewise. + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index f580635..94916a2 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -50,6 +50,13 @@ tests += tst-clone + # be the condition for those options to use in a C #if condition. + # abi-includes may be defined to a list of headers to include + # in the generated header, if the default does not suffice. ++# ++# The generated header is compiled with `-ffreestanding' to avoid any ++# circular dependencies against the installed implementation headers. ++# Such a dependency would require the implementation header to be ++# installed before the generated header could be built (See bug 15711). ++# In current practice the generated header dependencies do not include ++# any of the implementation headers removed by the use of `-ffreestanding'. + + $(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/syscall.h + $(make-target-directory) +@@ -64,7 +71,7 @@ $(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/ + echo ''; \ + $(if $(abi-variants), \ + $(foreach v,$(abi-variants),\ +- $(CC) -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \ ++ $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \ + -x c $(sysincludes) $< $(abi-$(v)-options) \ + -D_LIBC -dM | \ + sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ +@@ -75,7 +82,7 @@ $(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/ + $(if $(abi-$(v)-condition),echo '#endif';) \ + rm -f $(@:.d=.h).new$(v); \ + ), \ +- $(CC) -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \ ++ $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \ + -x c $(sysincludes) $< \ + -D_LIBC -dM | \ + sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ diff --git a/SOURCES/glibc-rh1298975.patch b/SOURCES/glibc-rh1298975.patch new file mode 100644 index 00000000..cf0e5ee6 --- /dev/null +++ b/SOURCES/glibc-rh1298975.patch @@ -0,0 +1,617 @@ +commit ced8f8933673f4efda1d666d26a1a949602035ed +Author: Stephen Gallagher +Date: Fri Apr 29 22:11:09 2016 -0400 + + NSS: Implement group merging support. + +commit 2413e73c32fc36470885ae548631e081d66f4201 +Author: Zack Weinberg +Date: Mon Jul 18 09:33:21 2016 -0300 + + Don't install the internal header grp-merge.h + +--- glibc-2.17-c758a686/grp/Makefile ++++ glibc-2.17-c758a686/grp/Makefile +@@ -23,7 +23,8 @@ + + routines := fgetgrent initgroups setgroups \ + getgrent getgrgid getgrnam putgrent \ +- getgrent_r getgrgid_r getgrnam_r fgetgrent_r ++ getgrent_r getgrgid_r getgrnam_r fgetgrent_r \ ++ grp-merge + + include ../Makeconfig + +--- glibc-2.17-c758a686/grp/Versions ++++ glibc-2.17-c758a686/grp/Versions +@@ -28,4 +28,7 @@ + # g* + getgrouplist; + } ++ GLIBC_PRIVATE { ++ __merge_grp; __copy_grp; ++ } + } +--- glibc-2.17-c758a686/grp/getgrgid_r.c ++++ glibc-2.17-c758a686/grp/getgrgid_r.c +@@ -18,6 +18,7 @@ + + #include + ++#include + + #define LOOKUP_TYPE struct group + #define FUNCTION_NAME getgrgid +@@ -25,5 +26,7 @@ + #define ADD_PARAMS gid_t gid + #define ADD_VARIABLES gid + #define BUFLEN NSS_BUFLEN_GROUP ++#define DEEPCOPY_FN __copy_grp ++#define MERGE_FN __merge_grp + + #include +--- glibc-2.17-c758a686/grp/getgrnam_r.c ++++ glibc-2.17-c758a686/grp/getgrnam_r.c +@@ -18,6 +18,7 @@ + + #include + ++#include + + #define LOOKUP_TYPE struct group + #define FUNCTION_NAME getgrnam +@@ -25,4 +26,7 @@ + #define ADD_PARAMS const char *name + #define ADD_VARIABLES name + ++#define DEEPCOPY_FN __copy_grp ++#define MERGE_FN __merge_grp ++ + #include +--- glibc-2.17-c758a686/grp/grp-merge.c ++++ glibc-2.17-c758a686/grp/grp-merge.c +@@ -0,0 +1,186 @@ ++/* Group merging implementation. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define BUFCHECK(size) \ ++ ({ \ ++ do \ ++ { \ ++ if (c + (size) > buflen) \ ++ { \ ++ free (members); \ ++ return ERANGE; \ ++ } \ ++ } \ ++ while (0); \ ++ }) ++ ++int ++internal_function ++__copy_grp (const struct group srcgrp, const size_t buflen, ++ struct group *destgrp, char *destbuf, char **endptr) ++{ ++ size_t i; ++ size_t c = 0; ++ size_t len; ++ size_t memcount; ++ char **members = NULL; ++ ++ /* Copy the GID. */ ++ destgrp->gr_gid = srcgrp.gr_gid; ++ ++ /* Copy the name. */ ++ len = strlen (srcgrp.gr_name) + 1; ++ BUFCHECK (len); ++ memcpy (&destbuf[c], srcgrp.gr_name, len); ++ destgrp->gr_name = &destbuf[c]; ++ c += len; ++ ++ /* Copy the password. */ ++ len = strlen (srcgrp.gr_passwd) + 1; ++ BUFCHECK (len); ++ memcpy (&destbuf[c], srcgrp.gr_passwd, len); ++ destgrp->gr_passwd = &destbuf[c]; ++ c += len; ++ ++ /* Count all of the members. */ ++ for (memcount = 0; srcgrp.gr_mem[memcount]; memcount++) ++ ; ++ ++ /* Allocate a temporary holding area for the pointers to the member ++ contents, including space for a NULL-terminator. */ ++ members = malloc (sizeof (char *) * (memcount + 1)); ++ if (members == NULL) ++ return ENOMEM; ++ ++ /* Copy all of the group members to destbuf and add a pointer to each of ++ them into the 'members' array. */ ++ for (i = 0; srcgrp.gr_mem[i]; i++) ++ { ++ len = strlen (srcgrp.gr_mem[i]) + 1; ++ BUFCHECK (len); ++ memcpy (&destbuf[c], srcgrp.gr_mem[i], len); ++ members[i] = &destbuf[c]; ++ c += len; ++ } ++ members[i] = NULL; ++ ++ /* Copy the pointers from the members array into the buffer and assign them ++ to the gr_mem member of destgrp. */ ++ destgrp->gr_mem = (char **) &destbuf[c]; ++ len = sizeof (char *) * (memcount + 1); ++ BUFCHECK (len); ++ memcpy (&destbuf[c], members, len); ++ c += len; ++ free (members); ++ members = NULL; ++ ++ /* Save the count of members at the end. */ ++ BUFCHECK (sizeof (size_t)); ++ memcpy (&destbuf[c], &memcount, sizeof (size_t)); ++ c += sizeof (size_t); ++ ++ if (endptr) ++ *endptr = destbuf + c; ++ return 0; ++} ++libc_hidden_def (__copy_grp) ++ ++/* Check that the name, GID and passwd fields match, then ++ copy in the gr_mem array. */ ++int ++internal_function ++__merge_grp (struct group *savedgrp, char *savedbuf, char *savedend, ++ size_t buflen, struct group *mergegrp, char *mergebuf) ++{ ++ size_t c, i, len; ++ size_t savedmemcount; ++ size_t memcount; ++ size_t membersize; ++ char **members = NULL; ++ ++ /* We only support merging members of groups with identical names and ++ GID values. If we hit this case, we need to overwrite the current ++ buffer with the saved one (which is functionally equivalent to ++ treating the new lookup as NSS_STATUS_NOTFOUND). */ ++ if (mergegrp->gr_gid != savedgrp->gr_gid ++ || strcmp (mergegrp->gr_name, savedgrp->gr_name)) ++ return __copy_grp (*savedgrp, buflen, mergegrp, mergebuf, NULL); ++ ++ /* Get the count of group members from the last sizeof (size_t) bytes in the ++ mergegrp buffer. */ ++ savedmemcount = (size_t) *(savedend - sizeof (size_t)); ++ ++ /* Get the count of new members to add. */ ++ for (memcount = 0; mergegrp->gr_mem[memcount]; memcount++) ++ ; ++ ++ /* Create a temporary array to hold the pointers to the member values from ++ both the saved and merge groups. */ ++ membersize = savedmemcount + memcount + 1; ++ members = malloc (sizeof (char *) * membersize); ++ if (members == NULL) ++ return ENOMEM; ++ ++ /* Copy in the existing member pointers from the saved group ++ Note: this is not NULL-terminated yet. */ ++ memcpy (members, savedgrp->gr_mem, sizeof (char *) * savedmemcount); ++ ++ /* Back up into the savedbuf until we get back to the NULL-terminator of the ++ group member list. (This means walking back savedmemcount + 1 (char *) pointers ++ and the member count value. ++ The value of c is going to be the used length of the buffer backed up by ++ the member count and further backed up by the size of the pointers. */ ++ c = savedend - savedbuf ++ - sizeof (size_t) ++ - sizeof (char *) * (savedmemcount + 1); ++ ++ /* Add all the new group members, overwriting the old NULL-terminator while ++ adding the new pointers to the temporary array. */ ++ for (i = 0; mergegrp->gr_mem[i]; i++) ++ { ++ len = strlen (mergegrp->gr_mem[i]) + 1; ++ BUFCHECK (len); ++ memcpy (&savedbuf[c], mergegrp->gr_mem[i], len); ++ members[savedmemcount + i] = &savedbuf[c]; ++ c += len; ++ } ++ /* Add the NULL-terminator. */ ++ members[savedmemcount + memcount] = NULL; ++ ++ /* Copy the member array back into the buffer after the member list and free ++ the member array. */ ++ savedgrp->gr_mem = (char **) &savedbuf[c]; ++ len = sizeof (char *) * membersize; ++ BUFCHECK (len); ++ memcpy (&savedbuf[c], members, len); ++ c += len; ++ ++ free (members); ++ members = NULL; ++ ++ /* Finally, copy the results back into mergebuf, since that's the buffer ++ that we were provided by the caller. */ ++ return __copy_grp (*savedgrp, buflen, mergegrp, mergebuf, NULL); ++} ++libc_hidden_def (__merge_grp) +--- glibc-2.17-c758a686/grp/grp-merge.h ++++ glibc-2.17-c758a686/grp/grp-merge.h +@@ -0,0 +1,37 @@ ++/* Group merging implementation. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _GRP_MERGE_H ++#define _GRP_MERGE_H 1 ++ ++#include ++ ++/* Duplicate a grp struct (and its members). When no longer needed, the ++ calling function must free(newbuf). */ ++int ++__copy_grp (const struct group srcgrp, const size_t buflen, ++ struct group *destgrp, char *destbuf, char **endptr) ++ internal_function; ++ ++/* Merge the member lists of two grp structs together. */ ++int ++__merge_grp (struct group *savedgrp, char *savedbuf, char *savedend, ++ size_t buflen, struct group *mergegrp, char *mergebuf) ++ internal_function; ++ ++#endif /* _GRP_MERGE_H */ +--- glibc-2.17-c758a686/include/grp-merge.h ++++ glibc-2.17-c758a686/include/grp-merge.h +@@ -0,0 +1,7 @@ ++#ifndef _GRP_MERGE_H ++#include ++ ++libc_hidden_proto (__copy_grp) ++libc_hidden_proto (__merge_grp) ++ ++#endif /* _GRP_MERGE_H */ +--- glibc-2.17-c758a686/manual/nss.texi ++++ glibc-2.17-c758a686/manual/nss.texi +@@ -180,7 +180,7 @@ + + The case of the keywords is insignificant. The @var{status} + values are the results of a call to a lookup function of a specific +-service. They mean ++service. They mean: + + @ftable @samp + @item success +@@ -204,6 +204,50 @@ + @end ftable + + @noindent ++The @var{action} values mean: ++ ++@ftable @samp ++@item return ++ ++If the status matches, stop the lookup process at this service ++specification. If an entry is available, provide it to the application. ++If an error occurred, report it to the application. In case of a prior ++@samp{merge} action, the data is combined with previous lookup results, ++as explained below. ++ ++@item continue ++ ++If the status matches, proceed with the lookup process at the next ++entry, discarding the result of the current lookup (and any merged ++data). An exception is the @samp{initgroups} database and the ++@samp{success} status, where @samp{continue} acts like @code{merge} ++below. ++ ++@item merge ++ ++Proceed with the lookup process, retaining the current lookup result. ++This action is useful only with the @samp{success} status. If a ++subsequent service lookup succeeds and has a matching @samp{return} ++specification, the results are merged, the lookup process ends, and the ++merged results are returned to the application. If the following service ++has a matching @samp{merge} action, the lookup process continues, ++retaining the combined data from this and any previous lookups. ++ ++After a @code{merge} action, errors from subsequent lookups are ignored, ++and the data gathered so far will be returned. ++ ++The @samp{merge} only applies to the @samp{success} status. It is ++currently implemented for the @samp{group} database and its group ++members field, @samp{gr_mem}. If specified for other databases, it ++causes the lookup to fail (if the @var{status} matches). ++ ++When processing @samp{merge} for @samp{group} membership, the group GID ++and name must be identical for both entries. If only one or the other is ++a match, the behavior is undefined. ++ ++@end ftable ++ ++@noindent + If we have a line like + + @smallexample +--- glibc-2.17-c758a686/nscd/getgrgid_r.c ++++ glibc-2.17-c758a686/nscd/getgrgid_r.c +@@ -17,6 +17,7 @@ + + #include + ++#include + + #define LOOKUP_TYPE struct group + #define FUNCTION_NAME getgrgid +@@ -25,6 +26,9 @@ + #define ADD_VARIABLES gid + #define BUFLEN NSS_BUFLEN_GROUP + ++#define DEEPCOPY_FN __copy_grp ++#define MERGE_FN __merge_grp ++ + /* We are nscd, so we don't want to be talking to ourselves. */ + #undef USE_NSCD + +--- glibc-2.17-c758a686/nscd/getgrnam_r.c ++++ glibc-2.17-c758a686/nscd/getgrnam_r.c +@@ -17,6 +17,7 @@ + + #include + ++#include + + #define LOOKUP_TYPE struct group + #define FUNCTION_NAME getgrnam +@@ -24,6 +25,9 @@ + #define ADD_PARAMS const char *name + #define ADD_VARIABLES name + ++#define DEEPCOPY_FN __copy_grp ++#define MERGE_FN __merge_grp ++ + /* We are nscd, so we don't want to be talking to ourselves. */ + #undef USE_NSCD + +--- glibc-2.17-c758a686/nss/getXXbyYY_r.c ++++ glibc-2.17-c758a686/nss/getXXbyYY_r.c +@@ -131,6 +131,52 @@ + # define AF_VAL AF_INET + #endif + ++ ++/* Set defaults for merge functions that haven't been defined. */ ++#ifndef DEEPCOPY_FN ++static inline int ++__copy_einval (LOOKUP_TYPE a, ++ const size_t b, ++ LOOKUP_TYPE *c, ++ char *d, ++ char **e) ++{ ++ return EINVAL; ++} ++# define DEEPCOPY_FN __copy_einval ++#endif ++ ++#ifndef MERGE_FN ++static inline int ++__merge_einval (LOOKUP_TYPE *a, ++ char *b, ++ char *c, ++ size_t d, ++ LOOKUP_TYPE *e, ++ char *f) ++{ ++ return EINVAL; ++} ++# define MERGE_FN __merge_einval ++#endif ++ ++#define CHECK_MERGE(err, status) \ ++ ({ \ ++ do \ ++ { \ ++ if (err) \ ++ { \ ++ __set_errno (err); \ ++ if (err == ERANGE) \ ++ status = NSS_STATUS_TRYAGAIN; \ ++ else \ ++ status = NSS_STATUS_UNAVAIL; \ ++ break; \ ++ } \ ++ } \ ++ while (0); \ ++ }) ++ + /* Type of the lookup function we need here. */ + typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, + size_t, int * H_ERRNO_PARM +@@ -152,13 +198,16 @@ + static service_user *startp; + static lookup_function start_fct; + service_user *nip; ++ int do_merge = 0; ++ LOOKUP_TYPE mergegrp; ++ char *mergebuf = NULL; ++ char *endptr = NULL; + union + { + lookup_function l; + void *ptr; + } fct; +- +- int no_more; ++ int no_more, err; + enum nss_status status = NSS_STATUS_UNAVAIL; + #ifdef USE_NSCD + int nscd_status; +@@ -278,9 +327,66 @@ + && errno == ERANGE) + break; + ++ if (do_merge) ++ { ++ ++ if (status == NSS_STATUS_SUCCESS) ++ { ++ /* The previous loop saved a buffer for merging. ++ Perform the merge now. */ ++ err = MERGE_FN (&mergegrp, mergebuf, endptr, buflen, resbuf, ++ buffer); ++ CHECK_MERGE (err,status); ++ do_merge = 0; ++ } ++ else ++ { ++ /* If the result wasn't SUCCESS, copy the saved buffer back ++ into the result buffer and set the status back to ++ NSS_STATUS_SUCCESS to match the previous pass through the ++ loop. ++ * If the next action is CONTINUE, it will overwrite the value ++ currently in the buffer and return the new value. ++ * If the next action is RETURN, we'll return the previously- ++ acquired values. ++ * If the next action is MERGE, then it will be added to the ++ buffer saved from the previous source. */ ++ err = DEEPCOPY_FN (mergegrp, buflen, resbuf, buffer, NULL); ++ CHECK_MERGE (err, status); ++ status = NSS_STATUS_SUCCESS; ++ } ++ } ++ ++ /* If we were are configured to merge this value with the next one, ++ save the current value of the group struct. */ ++ if (nss_next_action (nip, status) == NSS_ACTION_MERGE ++ && status == NSS_STATUS_SUCCESS) ++ { ++ /* Copy the current values into a buffer to be merged with the next ++ set of retrieved values. */ ++ if (mergebuf == NULL) ++ { ++ /* Only allocate once and reuse it for as many merges as we need ++ to perform. */ ++ mergebuf = malloc (buflen); ++ if (mergebuf == NULL) ++ { ++ __set_errno (ENOMEM); ++ status = NSS_STATUS_UNAVAIL; ++ break; ++ } ++ } ++ ++ err = DEEPCOPY_FN (*resbuf, buflen, &mergegrp, mergebuf, &endptr); ++ CHECK_MERGE (err, status); ++ do_merge = 1; ++ } ++ + no_more = __nss_next2 (&nip, REENTRANT_NAME_STRING, + REENTRANT2_NAME_STRING, &fct.ptr, status, 0); + } ++ free (mergebuf); ++ mergebuf = NULL; + + #ifdef HANDLE_DIGITS_DOTS + done: +--- glibc-2.17-c758a686/nss/getnssent_r.c ++++ glibc-2.17-c758a686/nss/getnssent_r.c +@@ -79,7 +79,18 @@ + else + status = DL_CALL_FCT (fct.f, (0)); + +- no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0); ++ ++ /* This is a special-case. When [SUCCESS=merge] is in play, ++ _nss_next2() will skip to the next database. Due to the ++ implementation of that function, we can't know whether we're ++ in an enumeration or an individual lookup, which behaves ++ differently with regards to merging. We'll treat SUCCESS as ++ an indication to start the enumeration at this database. */ ++ if (nss_next_action (*nip, status) == NSS_ACTION_MERGE) ++ no_more = 1; ++ else ++ no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0); ++ + if (is_last_nip) + *last_nip = *nip; + } +@@ -175,8 +186,18 @@ + + do + { +- no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr, +- status, 0); ++ /* This is a special-case. When [SUCCESS=merge] is in play, ++ _nss_next2() will skip to the next database. Due to the ++ implementation of that function, we can't know whether we're ++ in an enumeration or an individual lookup, which behaves ++ differently with regards to merging. We'll treat SUCCESS as ++ an indication to return the results here. */ ++ if (status == NSS_STATUS_SUCCESS ++ && nss_next_action (*nip, status) == NSS_ACTION_MERGE) ++ no_more = 1; ++ else ++ no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr, ++ status, 0); + + if (is_last_nip) + *last_nip = *nip; +--- glibc-2.17-c758a686/nss/nsswitch.c ++++ glibc-2.17-c758a686/nss/nsswitch.c +@@ -712,6 +712,9 @@ + else if (line - name == 8 + && __strncasecmp (name, "CONTINUE", 8) == 0) + action = NSS_ACTION_CONTINUE; ++ else if (line - name == 5 ++ && __strncasecmp (name, "MERGE", 5) == 0) ++ action = NSS_ACTION_MERGE; + else + goto finish; + +--- glibc-2.17-c758a686/nss/nsswitch.h ++++ glibc-2.17-c758a686/nss/nsswitch.h +@@ -32,7 +32,8 @@ + typedef enum + { + NSS_ACTION_CONTINUE, +- NSS_ACTION_RETURN ++ NSS_ACTION_RETURN, ++ NSS_ACTION_MERGE + } lookup_actions; diff --git a/SOURCES/glibc-rh1302086-1.patch b/SOURCES/glibc-rh1302086-1.patch new file mode 100644 index 00000000..acc6523a --- /dev/null +++ b/SOURCES/glibc-rh1302086-1.patch @@ -0,0 +1,35 @@ +commit 196f456b842ee96e1bf1e5ae6ed21ba427dee3f3 +Author: Marcus Shawcroft +Date: Tue Jan 7 16:16:35 2014 +0000 + + [AArch64] Fix FP_ROUNDMODE. + + [BZ #16387] Fix FP_ROUNDMODE to extract the correct bits from FPCR. + +diff --git a/ports/sysdeps/aarch64/fpu/fpu_control.h b/ports/sysdeps/aarch64/fpu/fpu_control.h +index 79ab5fb..6a265e8 100644 +--- a/ports/sysdeps/aarch64/fpu/fpu_control.h ++++ b/ports/sysdeps/aarch64/fpu/fpu_control.h +@@ -59,6 +59,9 @@ + E E D D + E E + */ ++ ++#define _FPU_FPCR_RM_MASK 0xc00000 ++ + #define _FPU_FPCR_MASK_IXE 0x1000 + #define _FPU_FPCR_MASK_UFE 0x0800 + #define _FPU_FPCR_MASK_OFE 0x0400 +diff --git a/ports/sysdeps/aarch64/soft-fp/sfp-machine.h b/ports/sysdeps/aarch64/soft-fp/sfp-machine.h +index d21d00a..9bb94e5 100644 +--- a/ports/sysdeps/aarch64/soft-fp/sfp-machine.h ++++ b/ports/sysdeps/aarch64/soft-fp/sfp-machine.h +@@ -47,7 +47,7 @@ + + #define _FP_DECL_EX fpu_control_t _fcw + +-#define FP_ROUNDMODE (_fcw & 0x3) ++#define FP_ROUNDMODE (_fcw & _FPU_FPCR_RM_MASK) + + #define FP_RND_NEAREST FE_TONEAREST + #define FP_RND_ZERO FE_TOWARDZERO diff --git a/SOURCES/glibc-rh1302086-10.patch b/SOURCES/glibc-rh1302086-10.patch new file mode 100644 index 00000000..0545de2b --- /dev/null +++ b/SOURCES/glibc-rh1302086-10.patch @@ -0,0 +1,205 @@ +commit e6d90d675d4cae810be76a5ff41b8ae8bd6bc914 +Author: Wilco Dijkstra +Date: Mon Jun 23 17:15:41 2014 +0100 + + Add generic HAVE_RM_CTX implementation + + This patch adds a generic implementation of HAVE_RM_CTX using standard + fenv calls. As a result math functions using SET_RESTORE_ROUND* macros + do not suffer from a large slowdown on targets which do not implement + optimized libc_fe*_ctx inline functions. Most of the libc_fe* inline + functions are now unused and could be removed in the future (there are + a few math functions left which use a mixture of standard fenv calls + and libc_fe* inline functions - they could be updated to use + SET_RESTORE_ROUND or improved to avoid expensive fenv manipulations + across just a few FP instructions). + + libc_feholdsetround*_noex_ctx is added to enable better optimization of + SET_RESTORE_ROUND_NOEX* implementations. + + Performance measurements on ARM and x86 of sin() show significant gains + over the current default, fairly close to a highly optimized fenv_private: + + ARM x86 + no fenv_private : 100% 100% + generic HAVE_RM_CTX : 250% 350% + fenv_private (CTX) : 250% 450% + + 2014-06-23 Will Newton + Wilco + + * sysdeps/generic/math_private.h: Add generic HAVE_RM_CTX + implementation. Include get-rounding-mode.h. + [!HAVE_RM_CTX]: Define HAVE_RM_CTX to zero. + [!libc_feholdsetround_noex_ctx]: Define + libc_feholdsetround_noex_ctx. + [!libc_feholdsetround_noexf_ctx]: Define + libc_feholdsetround_noexf_ctx. + [!libc_feholdsetround_noexl_ctx]: Define + libc_feholdsetround_noexl_ctx. + (libc_feholdsetround_ctx): New function. + (libc_feresetround_ctx): New function. + (libc_feholdsetround_noex_ctx): New function. + (libc_feresetround_noex_ctx): New function. + +diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h +index 9b881a3..94c1e4a 100644 +--- a/sysdeps/generic/math_private.h ++++ b/sysdeps/generic/math_private.h +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + /* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * +@@ -551,12 +552,26 @@ default_libc_feupdateenv_test (fenv_t *e, int ex) + # define libc_feresetround_noexl libc_fesetenvl + #endif + ++#ifndef HAVE_RM_CTX ++# define HAVE_RM_CTX 0 ++#endif ++ + #if HAVE_RM_CTX + /* Set/Restore Rounding Modes only when necessary. If defined, these functions + set/restore floating point state only if the state needed within the lexical + block is different from the current state. This saves a lot of time when + the floating point unit is much slower than the fixed point units. */ + ++# ifndef libc_feholdsetround_noex_ctx ++# define libc_feholdsetround_noex_ctx libc_feholdsetround_ctx ++# endif ++# ifndef libc_feholdsetround_noexf_ctx ++# define libc_feholdsetround_noexf_ctx libc_feholdsetroundf_ctx ++# endif ++# ifndef libc_feholdsetround_noexl_ctx ++# define libc_feholdsetround_noexl_ctx libc_feholdsetroundl_ctx ++# endif ++ + # ifndef libc_feresetround_noex_ctx + # define libc_feresetround_noex_ctx libc_fesetenv_ctx + # endif +@@ -567,24 +582,80 @@ default_libc_feupdateenv_test (fenv_t *e, int ex) + # define libc_feresetround_noexl_ctx libc_fesetenvl_ctx + # endif + +-# ifndef libc_feholdsetround_53bit_ctx +-# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx +-# endif ++#else + +-# ifndef libc_feresetround_53bit_ctx +-# define libc_feresetround_53bit_ctx libc_feresetround_ctx +-# endif ++/* Default implementation using standard fenv functions. ++ Avoid unnecessary rounding mode changes by first checking the ++ current rounding mode. Note the use of __glibc_unlikely is ++ important for performance. */ + +-# define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \ +- struct rm_ctx ctx __attribute__((cleanup(CLEANUPFUNC ## _ctx))); \ +- ROUNDFUNC ## _ctx (&ctx, (RM)) +-#else +-# define SET_RESTORE_ROUND_GENERIC(RM, ROUNDFUNC, CLEANUPFUNC) \ +- fenv_t __libc_save_rm __attribute__((cleanup(CLEANUPFUNC))); \ +- ROUNDFUNC (&__libc_save_rm, (RM)) ++static __always_inline void ++libc_feholdsetround_ctx (struct rm_ctx *ctx, int round) ++{ ++ ctx->updated_status = false; ++ ++ /* Update rounding mode only if different. */ ++ if (__glibc_unlikely (round != get_rounding_mode ())) ++ { ++ ctx->updated_status = true; ++ fegetenv (&ctx->env); ++ fesetround (round); ++ } ++} ++ ++static __always_inline void ++libc_feresetround_ctx (struct rm_ctx *ctx) ++{ ++ /* Restore the rounding mode if updated. */ ++ if (__glibc_unlikely (ctx->updated_status)) ++ feupdateenv (&ctx->env); ++} ++ ++static __always_inline void ++libc_feholdsetround_noex_ctx (struct rm_ctx *ctx, int round) ++{ ++ /* Save exception flags and rounding mode. */ ++ fegetenv (&ctx->env); ++ ++ /* Update rounding mode only if different. */ ++ if (__glibc_unlikely (round != get_rounding_mode ())) ++ fesetround (round); ++} ++ ++static __always_inline void ++libc_feresetround_noex_ctx (struct rm_ctx *ctx) ++{ ++ /* Restore exception flags and rounding mode. */ ++ fesetenv (&ctx->env); ++} ++ ++# define libc_feholdsetroundf_ctx libc_feholdsetround_ctx ++# define libc_feholdsetroundl_ctx libc_feholdsetround_ctx ++# define libc_feresetroundf_ctx libc_feresetround_ctx ++# define libc_feresetroundl_ctx libc_feresetround_ctx ++ ++# define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_ctx ++# define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_ctx ++# define libc_feresetround_noexf_ctx libc_feresetround_noex_ctx ++# define libc_feresetround_noexl_ctx libc_feresetround_noex_ctx ++ ++#endif ++ ++#ifndef libc_feholdsetround_53bit_ctx ++# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx ++#endif ++#ifndef libc_feresetround_53bit_ctx ++# define libc_feresetround_53bit_ctx libc_feresetround_ctx + #endif + +-/* Save and restore the rounding mode within a lexical block. */ ++#define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \ ++ struct rm_ctx ctx __attribute__((cleanup (CLEANUPFUNC ## _ctx))); \ ++ ROUNDFUNC ## _ctx (&ctx, (RM)) ++ ++/* Set the rounding mode within a lexical block. Restore the rounding mode to ++ the value at the start of the block. The exception mode must be preserved. ++ Exceptions raised within the block must be set in the exception flags. ++ Non-stop mode may be enabled inside the block. */ + + #define SET_RESTORE_ROUND(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround) +@@ -593,15 +664,21 @@ default_libc_feupdateenv_test (fenv_t *e, int ex) + #define SET_RESTORE_ROUNDL(RM) \ + SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl) + +-/* Save and restore the rounding mode within a lexical block, and also +- the set of exceptions raised within the block may be discarded. */ ++/* Set the rounding mode within a lexical block. Restore the rounding mode to ++ the value at the start of the block. The exception mode must be preserved. ++ Exceptions raised within the block must be discarded, and exception flags ++ are restored to the value at the start of the block. ++ Non-stop mode may be enabled inside the block. */ + + #define SET_RESTORE_ROUND_NOEX(RM) \ +- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround_noex) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noex, \ ++ libc_feresetround_noex) + #define SET_RESTORE_ROUND_NOEXF(RM) \ +- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetround_noexf) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexf, \ ++ libc_feresetround_noexf) + #define SET_RESTORE_ROUND_NOEXL(RM) \ +- SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetround_noexl) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_noexl, \ ++ libc_feresetround_noexl) + + /* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */ + #define SET_RESTORE_ROUND_53BIT(RM) \ diff --git a/SOURCES/glibc-rh1302086-11.patch b/SOURCES/glibc-rh1302086-11.patch new file mode 100644 index 00000000..699e5a34 --- /dev/null +++ b/SOURCES/glibc-rh1302086-11.patch @@ -0,0 +1,61 @@ +commit 656b84c2ef525e3b69802c9057c5897e327b0332 +Author: Wilco Dijkstra +Date: Thu Aug 7 16:29:55 2014 +0000 + + This patch adds new function libc_feholdsetround_noex_aarch64_ctx, enabling + further optimization. libc_feholdsetround_aarch64_ctx now only needs to + read the FPCR in the typical case, avoiding a redundant FPSR read. + Performance results show a good improvement (5-10% on sin()) on cores with + expensive FPCR/FPSR instructions. + +diff --git a/ports/sysdeps/aarch64/fpu/math_private.h b/ports/sysdeps/aarch64/fpu/math_private.h +index 023c9d0..b13c030 100644 +--- a/ports/sysdeps/aarch64/fpu/math_private.h ++++ b/ports/sysdeps/aarch64/fpu/math_private.h +@@ -228,12 +228,9 @@ static __always_inline void + libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r) + { + fpu_control_t fpcr; +- fpu_fpsr_t fpsr; + int round; + + _FPU_GETCW (fpcr); +- _FPU_GETFPSR (fpsr); +- ctx->env.__fpsr = fpsr; + + /* Check whether rounding modes are different. */ + round = (fpcr ^ r) & _FPU_FPCR_RM_MASK; +@@ -264,6 +261,33 @@ libc_feresetround_aarch64_ctx (struct rm_ctx *ctx) + #define libc_feresetroundl_ctx libc_feresetround_aarch64_ctx + + static __always_inline void ++libc_feholdsetround_noex_aarch64_ctx (struct rm_ctx *ctx, int r) ++{ ++ fpu_control_t fpcr; ++ fpu_fpsr_t fpsr; ++ int round; ++ ++ _FPU_GETCW (fpcr); ++ _FPU_GETFPSR (fpsr); ++ ctx->env.__fpsr = fpsr; ++ ++ /* Check whether rounding modes are different. */ ++ round = (fpcr ^ r) & _FPU_FPCR_RM_MASK; ++ ctx->updated_status = round != 0; ++ ++ /* Set the rounding mode if changed. */ ++ if (__glibc_unlikely (round != 0)) ++ { ++ ctx->env.__fpcr = fpcr; ++ _FPU_SETCW (fpcr ^ round); ++ } ++} ++ ++#define libc_feholdsetround_noex_ctx libc_feholdsetround_noex_aarch64_ctx ++#define libc_feholdsetround_noexf_ctx libc_feholdsetround_noex_aarch64_ctx ++#define libc_feholdsetround_noexl_ctx libc_feholdsetround_noex_aarch64_ctx ++ ++static __always_inline void + libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx) + { + /* Restore the rounding mode if updated. */ diff --git a/SOURCES/glibc-rh1302086-2.patch b/SOURCES/glibc-rh1302086-2.patch new file mode 100644 index 00000000..1618aad3 --- /dev/null +++ b/SOURCES/glibc-rh1302086-2.patch @@ -0,0 +1,226 @@ +commit 7e0b6763e96ef9706ea9ecc7fad83fc97b837913 +Author: Ian Bolton +Date: Wed Apr 16 14:41:52 2014 +0000 + + [AArch64] Provide initial implementation of math_private.h. + +diff --git a/ports/sysdeps/aarch64/fpu/math_private.h b/ports/sysdeps/aarch64/fpu/math_private.h +new file mode 100644 +index 0000000..dbf203d +--- /dev/null ++++ b/ports/sysdeps/aarch64/fpu/math_private.h +@@ -0,0 +1,214 @@ ++/* Private floating point rounding and exceptions handling. AArch64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef AARCH64_MATH_PRIVATE_H ++#define AARCH64_MATH_PRIVATE_H 1 ++ ++#include ++#include ++ ++static __always_inline void ++libc_feholdexcept_aarch64 (fenv_t *envp) ++{ ++ fpu_control_t fpcr, new_fpcr, fpsr, new_fpsr; ++ ++ _FPU_GETCW (fpcr); ++ _FPU_GETFPSR (fpsr); ++ envp->__fpcr = fpcr; ++ envp->__fpsr = fpsr; ++ ++ /* Clear exception flags and set all exceptions to non-stop. */ ++ new_fpcr = fpcr & ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); ++ new_fpsr = fpsr & ~FE_ALL_EXCEPT; ++ ++ if (__glibc_unlikely (new_fpcr != fpcr)) ++ _FPU_SETCW (new_fpcr); ++ ++ if (new_fpsr != fpsr) ++ _FPU_SETFPSR (new_fpsr); ++} ++ ++#define libc_feholdexcept libc_feholdexcept_aarch64 ++#define libc_feholdexceptf libc_feholdexcept_aarch64 ++#define libc_feholdexceptl libc_feholdexcept_aarch64 ++ ++static __always_inline void ++libc_fesetround_aarch64 (int round) ++{ ++ fpu_control_t fpcr; ++ ++ _FPU_GETCW (fpcr); ++ ++ /* Check whether rounding modes are different. */ ++ round = (fpcr ^ round) & FE_TOWARDZERO; ++ ++ /* Set new rounding mode if different. */ ++ if (__glibc_unlikely (round != 0)) ++ _FPU_SETCW (fpcr ^ round); ++} ++ ++#define libc_fesetround libc_fesetround_aarch64 ++#define libc_fesetroundf libc_fesetround_aarch64 ++#define libc_fesetroundl libc_fesetround_aarch64 ++ ++static __always_inline void ++libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round) ++{ ++ fpu_control_t fpcr, new_fpcr, fpsr, new_fpsr; ++ ++ _FPU_GETCW (fpcr); ++ _FPU_GETFPSR (fpsr); ++ envp->__fpcr = fpcr; ++ envp->__fpsr = fpsr; ++ ++ /* Clear exception flags, set all exceptions to non-stop, ++ and set new rounding mode. */ ++ new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | FE_TOWARDZERO); ++ new_fpcr |= round; ++ new_fpsr = fpsr & ~FE_ALL_EXCEPT; ++ ++ if (__glibc_unlikely (new_fpcr != fpcr)) ++ _FPU_SETCW (new_fpcr); ++ ++ if (new_fpsr != fpsr) ++ _FPU_SETFPSR (new_fpsr); ++} ++ ++#define libc_feholdexcept_setround libc_feholdexcept_setround_aarch64 ++#define libc_feholdexcept_setroundf libc_feholdexcept_setround_aarch64 ++#define libc_feholdexcept_setroundl libc_feholdexcept_setround_aarch64 ++ ++static __always_inline int ++libc_fetestexcept_aarch64 (int ex) ++{ ++ fpu_control_t fpsr; ++ ++ _FPU_GETFPSR (fpsr); ++ return fpsr & ex & FE_ALL_EXCEPT; ++} ++ ++#define libc_fetestexcept libc_fetestexcept_aarch64 ++#define libc_fetestexceptf libc_fetestexcept_aarch64 ++#define libc_fetestexceptl libc_fetestexcept_aarch64 ++ ++static __always_inline void ++libc_fesetenv_aarch64 (const fenv_t *envp) ++{ ++ fpu_control_t fpcr, new_fpcr; ++ ++ _FPU_GETCW (fpcr); ++ new_fpcr = envp->__fpcr; ++ ++ if (__glibc_unlikely (fpcr != new_fpcr)) ++ _FPU_SETCW (new_fpcr); ++ ++ _FPU_SETFPSR (envp->__fpsr); ++} ++ ++#define libc_fesetenv libc_fesetenv_aarch64 ++#define libc_fesetenvf libc_fesetenv_aarch64 ++#define libc_fesetenvl libc_fesetenv_aarch64 ++#define libc_feresetround_noex libc_fesetenv_aarch64 ++#define libc_feresetround_noexf libc_fesetenv_aarch64 ++#define libc_feresetround_noexl libc_fesetenv_aarch64 ++ ++static __always_inline int ++libc_feupdateenv_test_aarch64 (const fenv_t *envp, int ex) ++{ ++ fpu_control_t fpcr, new_fpcr, fpsr, new_fpsr; ++ int excepts; ++ ++ _FPU_GETCW (fpcr); ++ _FPU_GETFPSR (fpsr); ++ ++ /* Merge current exception flags with the saved fenv. */ ++ excepts = fpsr & FE_ALL_EXCEPT; ++ new_fpcr = envp->__fpcr; ++ new_fpsr = envp->__fpsr | excepts; ++ ++ if (__glibc_unlikely (fpcr != new_fpcr)) ++ _FPU_SETCW (new_fpcr); ++ ++ if (fpsr != new_fpsr) ++ _FPU_SETFPSR (new_fpsr); ++ ++ /* Raise the exceptions if enabled in the new FP state. */ ++ if (__glibc_unlikely (excepts & (new_fpcr >> FE_EXCEPT_SHIFT))) ++ feraiseexcept (excepts); ++ ++ return excepts & ex; ++} ++ ++#define libc_feupdateenv_test libc_feupdateenv_test_aarch64 ++#define libc_feupdateenv_testf libc_feupdateenv_test_aarch64 ++#define libc_feupdateenv_testl libc_feupdateenv_test_aarch64 ++ ++static __always_inline void ++libc_feupdateenv_aarch64 (const fenv_t *envp) ++{ ++ libc_feupdateenv_test_aarch64 (envp, 0); ++} ++ ++#define libc_feupdateenv libc_feupdateenv_aarch64 ++#define libc_feupdateenvf libc_feupdateenv_aarch64 ++#define libc_feupdateenvl libc_feupdateenv_aarch64 ++ ++static __always_inline void ++libc_feholdsetround_aarch64 (fenv_t *envp, int round) ++{ ++ fpu_control_t fpcr, fpsr; ++ ++ _FPU_GETCW (fpcr); ++ _FPU_GETFPSR (fpsr); ++ envp->__fpcr = fpcr; ++ envp->__fpsr = fpsr; ++ ++ /* Check whether rounding modes are different. */ ++ round = (fpcr ^ round) & FE_TOWARDZERO; ++ ++ /* Set new rounding mode if different. */ ++ if (__glibc_unlikely (round != 0)) ++ _FPU_SETCW (fpcr ^ round); ++} ++ ++#define libc_feholdsetround libc_feholdsetround_aarch64 ++#define libc_feholdsetroundf libc_feholdsetround_aarch64 ++#define libc_feholdsetroundl libc_feholdsetround_aarch64 ++ ++static __always_inline void ++libc_feresetround_aarch64 (fenv_t *envp) ++{ ++ fpu_control_t fpcr, round; ++ ++ _FPU_GETCW (fpcr); ++ ++ /* Check whether rounding modes are different. */ ++ round = (envp->__fpcr ^ fpcr) & FE_TOWARDZERO; ++ ++ /* Restore the rounding mode if it was changed. */ ++ if (__glibc_unlikely (round != 0)) ++ _FPU_SETCW (fpcr ^ round); ++} ++ ++#define libc_feresetround libc_feresetround_aarch64 ++#define libc_feresetroundf libc_feresetround_aarch64 ++#define libc_feresetroundl libc_feresetround_aarch64 ++ ++#include_next ++ ++#endif diff --git a/SOURCES/glibc-rh1302086-3.patch b/SOURCES/glibc-rh1302086-3.patch new file mode 100644 index 00000000..742a5f0c --- /dev/null +++ b/SOURCES/glibc-rh1302086-3.patch @@ -0,0 +1,72 @@ +commit bc93ab2946efe008bb0ce2d4d3c212bd01384fca +Author: Ian Bolton +Date: Wed Apr 16 23:41:04 2014 +0100 + + [AArch64] Define HAVE_RM_CTX and related hooks. + +diff --git a/ports/sysdeps/aarch64/fpu/math_private.h b/ports/sysdeps/aarch64/fpu/math_private.h +index dbf203d..7424952 100644 +--- a/ports/sysdeps/aarch64/fpu/math_private.h ++++ b/ports/sysdeps/aarch64/fpu/math_private.h +@@ -209,6 +209,61 @@ libc_feresetround_aarch64 (fenv_t *envp) + #define libc_feresetroundf libc_feresetround_aarch64 + #define libc_feresetroundl libc_feresetround_aarch64 + ++/* We have support for rounding mode context. */ ++#define HAVE_RM_CTX 1 ++ ++static __always_inline void ++libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r) ++{ ++ fpu_control_t fpcr, fpsr, round; ++ ++ _FPU_GETCW (fpcr); ++ _FPU_GETFPSR (fpsr); ++ ctx->env.__fpsr = fpsr; ++ ++ /* Check whether rounding modes are different. */ ++ round = (fpcr ^ r) & FE_TOWARDZERO; ++ ctx->updated_status = round != 0; ++ ++ /* Set the rounding mode if changed. */ ++ if (__glibc_unlikely (round != 0)) ++ { ++ ctx->env.__fpcr = fpcr; ++ _FPU_SETCW (fpcr ^ round); ++ } ++} ++ ++#define libc_feholdsetround_ctx libc_feholdsetround_aarch64_ctx ++#define libc_feholdsetroundf_ctx libc_feholdsetround_aarch64_ctx ++#define libc_feholdsetroundl_ctx libc_feholdsetround_aarch64_ctx ++ ++static __always_inline void ++libc_feresetround_aarch64_ctx (struct rm_ctx *ctx) ++{ ++ /* Restore the rounding mode if updated. */ ++ if (__glibc_unlikely (ctx->updated_status)) ++ _FPU_SETCW (ctx->env.__fpcr); ++} ++ ++#define libc_feresetround_ctx libc_feresetround_aarch64_ctx ++#define libc_feresetroundf_ctx libc_feresetround_aarch64_ctx ++#define libc_feresetroundl_ctx libc_feresetround_aarch64_ctx ++ ++static __always_inline void ++libc_feresetround_noex_aarch64_ctx (struct rm_ctx *ctx) ++{ ++ /* Restore the rounding mode if updated. */ ++ if (__glibc_unlikely (ctx->updated_status)) ++ _FPU_SETCW (ctx->env.__fpcr); ++ ++ /* Write new FPSR to restore exception flags. */ ++ _FPU_SETFPSR (ctx->env.__fpsr); ++} ++ ++#define libc_feresetround_noex_ctx libc_feresetround_noex_aarch64_ctx ++#define libc_feresetround_noexf_ctx libc_feresetround_noex_aarch64_ctx ++#define libc_feresetround_noexl_ctx libc_feresetround_noex_aarch64_ctx ++ + #include_next + + #endif diff --git a/SOURCES/glibc-rh1302086-4.patch b/SOURCES/glibc-rh1302086-4.patch new file mode 100644 index 00000000..01acc8cf --- /dev/null +++ b/SOURCES/glibc-rh1302086-4.patch @@ -0,0 +1,34 @@ +commit 39e6cd8d643779188fd43d9e2d5ed4e47a64d924 +Author: Ian Bolton +Date: Thu Apr 17 15:31:01 2014 +0000 + + Add fenv test support for AArch64. + +diff --git a/ports/sysdeps/aarch64/math-tests.h b/ports/sysdeps/aarch64/math-tests.h +new file mode 100644 +index 0000000..6a0b898 +--- /dev/null ++++ b/ports/sysdeps/aarch64/math-tests.h +@@ -0,0 +1,22 @@ ++/* Configuration for math tests. AArch64 version. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Trapping exceptions are optional on AArch64. */ ++#define EXCEPTION_ENABLE_SUPPORTED(EXCEPT) ((EXCEPT) == 0) ++ ++#include_next diff --git a/SOURCES/glibc-rh1302086-5.patch b/SOURCES/glibc-rh1302086-5.patch new file mode 100644 index 00000000..8b505584 --- /dev/null +++ b/SOURCES/glibc-rh1302086-5.patch @@ -0,0 +1,229 @@ +commit e5e0d9a4f632735cf3bb440eecb5caee5eea44c1 +Author: Ian Bolton +Date: Thu Apr 24 07:15:33 2014 +0100 + + [AArch64] Suppress unnecessary FPSR and FPCR writes. + +diff --git a/ports/sysdeps/aarch64/fpu/fclrexcpt.c b/ports/sysdeps/aarch64/fpu/fclrexcpt.c +index 531269f..b24f0ff 100644 +--- a/ports/sysdeps/aarch64/fpu/fclrexcpt.c ++++ b/ports/sysdeps/aarch64/fpu/fclrexcpt.c +@@ -23,13 +23,15 @@ int + feclearexcept (int excepts) + { + fpu_fpsr_t fpsr; ++ fpu_fpsr_t fpsr_new; + + excepts &= FE_ALL_EXCEPT; + + _FPU_GETFPSR (fpsr); +- fpsr = (fpsr & ~FE_ALL_EXCEPT) | (fpsr & FE_ALL_EXCEPT & ~excepts); ++ fpsr_new = (fpsr & ~FE_ALL_EXCEPT) | (fpsr & FE_ALL_EXCEPT & ~excepts); + +- _FPU_SETFPSR (fpsr); ++ if (fpsr != fpsr_new) ++ _FPU_SETFPSR (fpsr_new); + + return 0; + } +diff --git a/ports/sysdeps/aarch64/fpu/fedisblxcpt.c b/ports/sysdeps/aarch64/fpu/fedisblxcpt.c +index 719d52f..c43335c 100644 +--- a/ports/sysdeps/aarch64/fpu/fedisblxcpt.c ++++ b/ports/sysdeps/aarch64/fpu/fedisblxcpt.c +@@ -23,6 +23,7 @@ int + fedisableexcept (int excepts) + { + fpu_control_t fpcr; ++ fpu_control_t fpcr_new; + int original_excepts; + + _FPU_GETCW (fpcr); +@@ -31,9 +32,10 @@ fedisableexcept (int excepts) + + excepts &= FE_ALL_EXCEPT; + +- fpcr &= ~(excepts << FE_EXCEPT_SHIFT); ++ fpcr_new = fpcr & ~(excepts << FE_EXCEPT_SHIFT); + +- _FPU_SETCW (fpcr); ++ if (fpcr != fpcr_new) ++ _FPU_SETCW (fpcr_new); + + return original_excepts; + } +diff --git a/ports/sysdeps/aarch64/fpu/feenablxcpt.c b/ports/sysdeps/aarch64/fpu/feenablxcpt.c +index 07a4bbb..70e413c 100644 +--- a/ports/sysdeps/aarch64/fpu/feenablxcpt.c ++++ b/ports/sysdeps/aarch64/fpu/feenablxcpt.c +@@ -23,6 +23,7 @@ int + feenableexcept (int excepts) + { + fpu_control_t fpcr; ++ fpu_control_t fpcr_new; + int original_excepts; + + _FPU_GETCW (fpcr); +@@ -31,9 +32,10 @@ feenableexcept (int excepts) + + excepts &= FE_ALL_EXCEPT; + +- fpcr |= (excepts << FE_EXCEPT_SHIFT); ++ fpcr_new = fpcr | (excepts << FE_EXCEPT_SHIFT); + +- _FPU_SETCW (fpcr); ++ if (fpcr != fpcr_new) ++ _FPU_SETCW (fpcr_new); + + /* Trapping exceptions are optional in AArch64 the relevant enable + bits in FPCR are RES0 hence the absence of support can be +diff --git a/ports/sysdeps/aarch64/fpu/feholdexcpt.c b/ports/sysdeps/aarch64/fpu/feholdexcpt.c +index 0514ac1..973ba4a 100644 +--- a/ports/sysdeps/aarch64/fpu/feholdexcpt.c ++++ b/ports/sysdeps/aarch64/fpu/feholdexcpt.c +@@ -22,8 +22,10 @@ + int + feholdexcept (fenv_t *envp) + { +- fpu_fpsr_t fpsr; + fpu_control_t fpcr; ++ fpu_control_t fpcr_new; ++ fpu_fpsr_t fpsr; ++ fpu_fpsr_t fpsr_new; + + _FPU_GETCW (fpcr); + envp->__fpcr = fpcr; +@@ -32,14 +34,16 @@ feholdexcept (fenv_t *envp) + envp->__fpsr = fpsr; + + /* Now set all exceptions to non-stop. */ +- fpcr &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); ++ fpcr_new = fpcr & ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); + + /* And clear all exception flags. */ +- fpsr &= ~FE_ALL_EXCEPT; ++ fpsr_new = fpsr & ~FE_ALL_EXCEPT; + +- _FPU_SETFPSR (fpsr); ++ if (fpsr != fpsr_new) ++ _FPU_SETFPSR (fpsr_new); + +- _FPU_SETCW (fpcr); ++ if (fpcr != fpcr_new) ++ _FPU_SETCW (fpcr_new); + + return 0; + } +diff --git a/ports/sysdeps/aarch64/fpu/fesetenv.c b/ports/sysdeps/aarch64/fpu/fesetenv.c +index a2434e3..30193e9 100644 +--- a/ports/sysdeps/aarch64/fpu/fesetenv.c ++++ b/ports/sysdeps/aarch64/fpu/fesetenv.c +@@ -23,34 +23,38 @@ int + fesetenv (const fenv_t *envp) + { + fpu_control_t fpcr; +- fpu_fpsr_t fpsr; ++ fpu_control_t fpcr_new; + fpu_control_t updated_fpcr; ++ fpu_fpsr_t fpsr; ++ fpu_fpsr_t fpsr_new; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); + +- fpcr &= _FPU_RESERVED; +- fpsr &= _FPU_FPSR_RESERVED; ++ fpcr_new = fpcr & _FPU_RESERVED; ++ fpsr_new = fpsr & _FPU_FPSR_RESERVED; + + if (envp == FE_DFL_ENV) + { +- fpcr |= _FPU_DEFAULT; +- fpsr |= _FPU_FPSR_DEFAULT; ++ fpcr_new |= _FPU_DEFAULT; ++ fpsr_new |= _FPU_FPSR_DEFAULT; + } + else if (envp == FE_NOMASK_ENV) + { +- fpcr |= _FPU_FPCR_IEEE; +- fpsr |= _FPU_FPSR_IEEE; ++ fpcr_new |= _FPU_FPCR_IEEE; ++ fpsr_new |= _FPU_FPSR_IEEE; + } + else + { +- fpcr |= envp->__fpcr & ~_FPU_RESERVED; +- fpsr |= envp->__fpsr & ~_FPU_FPSR_RESERVED; ++ fpcr_new |= envp->__fpcr & ~_FPU_RESERVED; ++ fpsr_new |= envp->__fpsr & ~_FPU_FPSR_RESERVED; + } + +- _FPU_SETFPSR (fpsr); ++ if (fpsr != fpsr_new) ++ _FPU_SETFPSR (fpsr_new); + +- _FPU_SETCW (fpcr); ++ if (fpcr != fpcr_new) ++ _FPU_SETCW (fpcr_new); + + /* Trapping exceptions are optional in AArch64 the relevant enable + bits in FPCR are RES0 hence the absence of support can be +@@ -58,7 +62,7 @@ fesetenv (const fenv_t *envp) + value. */ + + _FPU_GETCW (updated_fpcr); +- if ((updated_fpcr & fpcr) != fpcr) ++ if ((updated_fpcr & fpcr_new) != fpcr_new) + return 1; + + return 0; +diff --git a/ports/sysdeps/aarch64/fpu/fesetround.c b/ports/sysdeps/aarch64/fpu/fesetround.c +index 40a05f6..225096a 100644 +--- a/ports/sysdeps/aarch64/fpu/fesetround.c ++++ b/ports/sysdeps/aarch64/fpu/fesetround.c +@@ -23,6 +23,7 @@ int + fesetround (int round) + { + fpu_control_t fpcr; ++ fpu_control_t fpcr_new; + + switch (round) + { +@@ -31,9 +32,10 @@ fesetround (int round) + case FE_DOWNWARD: + case FE_TOWARDZERO: + _FPU_GETCW (fpcr); +- fpcr = (fpcr & ~FE_TOWARDZERO) | round; ++ fpcr_new = (fpcr & ~FE_TOWARDZERO) | round; + +- _FPU_SETCW (fpcr); ++ if (fpcr != fpcr_new) ++ _FPU_SETCW (fpcr_new); + return 0; + + default: +diff --git a/ports/sysdeps/aarch64/fpu/fsetexcptflg.c b/ports/sysdeps/aarch64/fpu/fsetexcptflg.c +index 49cd1e4..60bb1c9 100644 +--- a/ports/sysdeps/aarch64/fpu/fsetexcptflg.c ++++ b/ports/sysdeps/aarch64/fpu/fsetexcptflg.c +@@ -24,16 +24,18 @@ int + fesetexceptflag (const fexcept_t *flagp, int excepts) + { + fpu_fpsr_t fpsr; ++ fpu_fpsr_t fpsr_new; + + /* Get the current environment. */ + _FPU_GETFPSR (fpsr); + + /* Set the desired exception mask. */ +- fpsr &= ~(excepts & FE_ALL_EXCEPT); +- fpsr |= (*flagp & excepts & FE_ALL_EXCEPT); ++ fpsr_new = fpsr & ~(excepts & FE_ALL_EXCEPT); ++ fpsr_new |= (*flagp & excepts & FE_ALL_EXCEPT); + + /* Save state back to the FPU. */ +- _FPU_SETFPSR (fpsr); ++ if (fpsr != fpsr_new) ++ _FPU_SETFPSR (fpsr_new); + + return 0; + } diff --git a/SOURCES/glibc-rh1302086-6.patch b/SOURCES/glibc-rh1302086-6.patch new file mode 100644 index 00000000..c7ad9010 --- /dev/null +++ b/SOURCES/glibc-rh1302086-6.patch @@ -0,0 +1,81 @@ +commit c95b3011018893fcc473279768a67a24a73bbef2 +Author: Wilco +Date: Mon Jun 2 12:20:17 2014 +0100 + + [AArch64] Rewrite feupdateenv (BZ 17009). + +diff --git a/ports/sysdeps/aarch64/fpu/feupdateenv.c b/ports/sysdeps/aarch64/fpu/feupdateenv.c +index 6d64a9b..ac2f6fe 100644 +--- a/ports/sysdeps/aarch64/fpu/feupdateenv.c ++++ b/ports/sysdeps/aarch64/fpu/feupdateenv.c +@@ -22,16 +22,65 @@ + int + feupdateenv (const fenv_t *envp) + { ++ fpu_control_t fpcr; ++ fpu_control_t fpcr_new; ++ fpu_control_t updated_fpcr; + fpu_fpsr_t fpsr; ++ fpu_fpsr_t fpsr_new; ++ int excepts; + +- /* Get the current exception state. */ ++ _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); ++ excepts = fpsr & FE_ALL_EXCEPT; + +- /* Install new environment. */ +- fesetenv (envp); ++ if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) ++ { ++ fpcr_new = envp->__fpcr; ++ fpsr_new = envp->__fpsr | excepts; + +- /* Raise the saved exceptions. */ +- feraiseexcept (fpsr & FE_ALL_EXCEPT); ++ if (fpcr != fpcr_new) ++ _FPU_SETCW (fpcr_new); ++ ++ if (fpsr != fpsr_new) ++ _FPU_SETFPSR (fpsr_new); ++ ++ if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT)) ++ return feraiseexcept (excepts); ++ ++ return 0; ++ } ++ ++ fpcr_new = fpcr & _FPU_RESERVED; ++ fpsr_new = fpsr & (_FPU_FPSR_RESERVED | FE_ALL_EXCEPT); ++ ++ if (envp == FE_DFL_ENV) ++ { ++ fpcr_new |= _FPU_DEFAULT; ++ fpsr_new |= _FPU_FPSR_DEFAULT; ++ } ++ else ++ { ++ fpcr_new |= _FPU_FPCR_IEEE; ++ fpsr_new |= _FPU_FPSR_IEEE; ++ } ++ ++ _FPU_SETFPSR (fpsr_new); ++ ++ if (fpcr != fpcr_new) ++ { ++ _FPU_SETCW (fpcr_new); ++ ++ /* Trapping exceptions are optional in AArch64; the relevant enable ++ bits in FPCR are RES0 hence the absence of support can be detected ++ by reading back the FPCR and comparing with the required value. */ ++ _FPU_GETCW (updated_fpcr); ++ ++ if (fpcr_new & ~updated_fpcr) ++ return 1; ++ } ++ ++ if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT)) ++ return feraiseexcept (excepts); + + return 0; + } diff --git a/SOURCES/glibc-rh1302086-7.patch b/SOURCES/glibc-rh1302086-7.patch new file mode 100644 index 00000000..de238061 --- /dev/null +++ b/SOURCES/glibc-rh1302086-7.patch @@ -0,0 +1,24 @@ +commit a88dadbed5d7589ac7880efe62ea511844107795 +Author: Wilco +Date: Mon Jun 2 12:44:21 2014 +0100 + + [AArch64] Remove ISB after FPCR write. + +diff --git a/ports/sysdeps/aarch64/fpu/fpu_control.h b/ports/sysdeps/aarch64/fpu/fpu_control.h +index 6a265e8..d5a890d 100644 +--- a/ports/sysdeps/aarch64/fpu/fpu_control.h ++++ b/ports/sysdeps/aarch64/fpu/fpu_control.h +@@ -24,11 +24,8 @@ + #define _FPU_GETCW(fpcr) \ + __asm__ __volatile__ ("mrs %0, fpcr" : "=r" (fpcr)) + +-#define _FPU_SETCW(fpcr) \ +- { \ +- __asm__ __volatile__ ("msr fpcr, %0" : : "r" (fpcr)); \ +- __asm__ __volatile__ ("isb"); \ +- } ++#define _FPU_SETCW(fpcr) \ ++ __asm__ __volatile__ ("msr fpcr, %0" : : "r" (fpcr)) + + #define _FPU_GETFPSR(fpsr) \ + __asm__ __volatile__ ("mrs %0, fpsr" : "=r" (fpsr)) diff --git a/SOURCES/glibc-rh1302086-8.patch b/SOURCES/glibc-rh1302086-8.patch new file mode 100644 index 00000000..1f541ab9 --- /dev/null +++ b/SOURCES/glibc-rh1302086-8.patch @@ -0,0 +1,96 @@ +commit 0b4366bc9bca9be8a2208455545c138bcd1e826c +Author: Wilco +Date: Tue Jun 3 08:08:36 2014 +0000 + + [AArch64] Cleanup declarations in math_private.h. + +diff --git a/ports/sysdeps/aarch64/fpu/math_private.h b/ports/sysdeps/aarch64/fpu/math_private.h +index 7424952..a3f466b 100644 +--- a/ports/sysdeps/aarch64/fpu/math_private.h ++++ b/ports/sysdeps/aarch64/fpu/math_private.h +@@ -25,7 +25,10 @@ + static __always_inline void + libc_feholdexcept_aarch64 (fenv_t *envp) + { +- fpu_control_t fpcr, new_fpcr, fpsr, new_fpsr; ++ fpu_control_t fpcr; ++ fpu_control_t new_fpcr; ++ fpu_fpsr_t fpsr; ++ fpu_fpsr_t new_fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); +@@ -69,7 +72,10 @@ libc_fesetround_aarch64 (int round) + static __always_inline void + libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round) + { +- fpu_control_t fpcr, new_fpcr, fpsr, new_fpsr; ++ fpu_control_t fpcr; ++ fpu_control_t new_fpcr; ++ fpu_fpsr_t fpsr; ++ fpu_fpsr_t new_fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); +@@ -96,7 +102,7 @@ libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round) + static __always_inline int + libc_fetestexcept_aarch64 (int ex) + { +- fpu_control_t fpsr; ++ fpu_fpsr_t fpsr; + + _FPU_GETFPSR (fpsr); + return fpsr & ex & FE_ALL_EXCEPT; +@@ -109,7 +115,8 @@ libc_fetestexcept_aarch64 (int ex) + static __always_inline void + libc_fesetenv_aarch64 (const fenv_t *envp) + { +- fpu_control_t fpcr, new_fpcr; ++ fpu_control_t fpcr; ++ fpu_control_t new_fpcr; + + _FPU_GETCW (fpcr); + new_fpcr = envp->__fpcr; +@@ -130,7 +137,10 @@ libc_fesetenv_aarch64 (const fenv_t *envp) + static __always_inline int + libc_feupdateenv_test_aarch64 (const fenv_t *envp, int ex) + { +- fpu_control_t fpcr, new_fpcr, fpsr, new_fpsr; ++ fpu_control_t fpcr; ++ fpu_control_t new_fpcr; ++ fpu_fpsr_t fpsr; ++ fpu_fpsr_t new_fpsr; + int excepts; + + _FPU_GETCW (fpcr); +@@ -171,7 +181,8 @@ libc_feupdateenv_aarch64 (const fenv_t *envp) + static __always_inline void + libc_feholdsetround_aarch64 (fenv_t *envp, int round) + { +- fpu_control_t fpcr, fpsr; ++ fpu_control_t fpcr; ++ fpu_fpsr_t fpsr; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); +@@ -193,7 +204,8 @@ libc_feholdsetround_aarch64 (fenv_t *envp, int round) + static __always_inline void + libc_feresetround_aarch64 (fenv_t *envp) + { +- fpu_control_t fpcr, round; ++ fpu_control_t fpcr; ++ int round; + + _FPU_GETCW (fpcr); + +@@ -215,7 +227,9 @@ libc_feresetround_aarch64 (fenv_t *envp) + static __always_inline void + libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r) + { +- fpu_control_t fpcr, fpsr, round; ++ fpu_control_t fpcr; ++ fpu_fpsr_t fpsr; ++ int round; + + _FPU_GETCW (fpcr); + _FPU_GETFPSR (fpsr); diff --git a/SOURCES/glibc-rh1302086-9.patch b/SOURCES/glibc-rh1302086-9.patch new file mode 100644 index 00000000..658221f0 --- /dev/null +++ b/SOURCES/glibc-rh1302086-9.patch @@ -0,0 +1,68 @@ +commit 693096cc7b397a709f075865993027c14c06d3e5 +Author: Wilco +Date: Tue Jun 3 08:10:39 2014 +0000 + + [AArch64] Switch from FE_TOWARDZERO to _FPU_FPCR_RM_MASK + +diff --git a/ports/sysdeps/aarch64/fpu/get-rounding-mode.h b/ports/sysdeps/aarch64/fpu/get-rounding-mode.h +index 5c1615d..425b50e 100644 +--- a/ports/sysdeps/aarch64/fpu/get-rounding-mode.h ++++ b/ports/sysdeps/aarch64/fpu/get-rounding-mode.h +@@ -32,7 +32,7 @@ get_rounding_mode (void) + fpu_control_t fpcr; + + _FPU_GETCW (fpcr); +- return fpcr & FE_TOWARDZERO; ++ return fpcr & _FPU_FPCR_RM_MASK; + } + + #endif /* get-rounding-mode.h */ +diff --git a/ports/sysdeps/aarch64/fpu/math_private.h b/ports/sysdeps/aarch64/fpu/math_private.h +index a3f466b..023c9d0 100644 +--- a/ports/sysdeps/aarch64/fpu/math_private.h ++++ b/ports/sysdeps/aarch64/fpu/math_private.h +@@ -58,7 +58,7 @@ libc_fesetround_aarch64 (int round) + _FPU_GETCW (fpcr); + + /* Check whether rounding modes are different. */ +- round = (fpcr ^ round) & FE_TOWARDZERO; ++ round = (fpcr ^ round) & _FPU_FPCR_RM_MASK; + + /* Set new rounding mode if different. */ + if (__glibc_unlikely (round != 0)) +@@ -84,7 +84,7 @@ libc_feholdexcept_setround_aarch64 (fenv_t *envp, int round) + + /* Clear exception flags, set all exceptions to non-stop, + and set new rounding mode. */ +- new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | FE_TOWARDZERO); ++ new_fpcr = fpcr & ~((FE_ALL_EXCEPT << FE_EXCEPT_SHIFT) | _FPU_FPCR_RM_MASK); + new_fpcr |= round; + new_fpsr = fpsr & ~FE_ALL_EXCEPT; + +@@ -190,7 +190,7 @@ libc_feholdsetround_aarch64 (fenv_t *envp, int round) + envp->__fpsr = fpsr; + + /* Check whether rounding modes are different. */ +- round = (fpcr ^ round) & FE_TOWARDZERO; ++ round = (fpcr ^ round) & _FPU_FPCR_RM_MASK; + + /* Set new rounding mode if different. */ + if (__glibc_unlikely (round != 0)) +@@ -210,7 +210,7 @@ libc_feresetround_aarch64 (fenv_t *envp) + _FPU_GETCW (fpcr); + + /* Check whether rounding modes are different. */ +- round = (envp->__fpcr ^ fpcr) & FE_TOWARDZERO; ++ round = (envp->__fpcr ^ fpcr) & _FPU_FPCR_RM_MASK; + + /* Restore the rounding mode if it was changed. */ + if (__glibc_unlikely (round != 0)) +@@ -236,7 +236,7 @@ libc_feholdsetround_aarch64_ctx (struct rm_ctx *ctx, int r) + ctx->env.__fpsr = fpsr; + + /* Check whether rounding modes are different. */ +- round = (fpcr ^ r) & FE_TOWARDZERO; ++ round = (fpcr ^ r) & _FPU_FPCR_RM_MASK; + ctx->updated_status = round != 0; + + /* Set the rounding mode if changed. */ diff --git a/SOURCES/glibc-rh1308728.patch b/SOURCES/glibc-rh1308728.patch new file mode 100644 index 00000000..c91d10c4 --- /dev/null +++ b/SOURCES/glibc-rh1308728.patch @@ -0,0 +1,37 @@ +commit 58a1335e76a553e1cf4edeebc27f16fc9b53d6e6 +Author: Petr Baudis +Date: Thu Mar 14 01:16:53 2013 +0100 + + Fix __times() handling of EFAULT when buf is NULL + +diff --git a/sysdeps/unix/sysv/linux/times.c b/sysdeps/unix/sysv/linux/times.c +index f3b5f01..e59bb4e 100644 +--- a/sysdeps/unix/sysv/linux/times.c ++++ b/sysdeps/unix/sysv/linux/times.c +@@ -26,13 +26,14 @@ __times (struct tms *buf) + INTERNAL_SYSCALL_DECL (err); + clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf); + if (INTERNAL_SYSCALL_ERROR_P (ret, err) +- && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0)) ++ && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0) ++ && buf) + { + /* This might be an error or not. For architectures which have + no separate return value and error indicators we cannot + distinguish a return value of -1 from an error. Do it the +- hard way. We crash applications which pass in an invalid BUF +- pointer. */ ++ hard way. We crash applications which pass in an invalid ++ non-NULL BUF pointer. Linux allows BUF to be NULL. */ + #define touch(v) \ + do { \ + clock_t temp = v; \ +@@ -44,7 +45,8 @@ __times (struct tms *buf) + touch (buf->tms_cutime); + touch (buf->tms_cstime); + +- /* If we come here the memory is valid and the kernel did not ++ /* If we come here the memory is valid (or BUF is NULL, which is ++ * a valid condition for the kernel syscall) and the kernel did not + return an EFAULT error. Return the value given by the kernel. */ + } diff --git a/SOURCES/glibc-rh1310530.patch b/SOURCES/glibc-rh1310530.patch new file mode 100644 index 00000000..20042ae8 --- /dev/null +++ b/SOURCES/glibc-rh1310530.patch @@ -0,0 +1,18 @@ +commit 984c0ea97f649c869130a1ff099098e2b6f70aad +Author: Tim Lammens +Date: Thu Sep 11 10:35:54 2014 +0530 + + Fix memory leak in libio/wfileops.c do_ftell_wide [BZ #17370] + +diff --git a/libio/wfileops.c b/libio/wfileops.c +index f123add..ebc06e8 100644 +--- a/libio/wfileops.c ++++ b/libio/wfileops.c +@@ -711,6 +711,7 @@ do_ftell_wide (_IO_FILE *fp) + return WEOF; + + offset += outstop - out; ++ free (out); + } + + /* We don't trust _IO_read_end to represent the current file offset diff --git a/SOURCES/glibc-rh1318877.patch b/SOURCES/glibc-rh1318877.patch new file mode 100644 index 00000000..832dd6c0 --- /dev/null +++ b/SOURCES/glibc-rh1318877.patch @@ -0,0 +1,62 @@ +commit 1ef74943ce2f114c78b215af57c2ccc72ccdb0b7 +Author: Paul Pluzhnikov +Date: Thu Apr 25 11:08:31 2013 -0700 + + Get rid of __STDC_FORMAT_MACROS, __STDC_LIMIT_MACROS and + __STDC_CONSTANT_MACROS. + +--- glibc-2.17-c758a686/sysdeps/generic/inttypes.h ++++ glibc-2.17-c758a686/sysdeps/generic/inttypes.h +@@ -41,10 +41,6 @@ + #endif + + +-/* The ISO C99 standard specifies that these macros must only be +- defined if explicitly requested. */ +-#if !defined __cplusplus || defined __STDC_FORMAT_MACROS +- + # if __WORDSIZE == 64 + # define __PRI64_PREFIX "l" + # define __PRIPTR_PREFIX "l" +@@ -267,8 +263,6 @@ + # define SCNuPTR __PRIPTR_PREFIX "u" + # define SCNxPTR __PRIPTR_PREFIX "x" + +-#endif /* C++ && format macros */ +- + + __BEGIN_DECLS + +--- glibc-2.17-c758a686/sysdeps/generic/stdint.h ++++ glibc-2.17-c758a686/sysdeps/generic/stdint.h +@@ -141,10 +141,6 @@ + #endif + + +-/* The ISO C99 standard specifies that in C++ implementations these +- macros should only be defined if explicitly requested. */ +-#if !defined __cplusplus || defined __STDC_LIMIT_MACROS +- + # if __WORDSIZE == 64 + # define __INT64_C(c) c ## L + # define __UINT64_C(c) c ## UL +@@ -278,12 +274,6 @@ + # define WINT_MIN (0u) + # define WINT_MAX (4294967295u) + +-#endif /* C++ && limit macros */ +- +- +-/* The ISO C99 standard specifies that in C++ implementations these +- should only be defined if explicitly requested. */ +-#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS + + /* Signed. */ + # define INT8_C(c) c +@@ -314,6 +304,4 @@ + # define UINTMAX_C(c) c ## ULL + # endif + +-#endif /* C++ && constant macros */ +- + #endif /* stdint.h */ diff --git a/SOURCES/glibc-rh1318890.patch b/SOURCES/glibc-rh1318890.patch new file mode 100644 index 00000000..1564e053 --- /dev/null +++ b/SOURCES/glibc-rh1318890.patch @@ -0,0 +1,35 @@ +commit a6033052d08027f745867e5e346852da1959226c +Author: Florian Weimer +Date: Tue Mar 29 11:27:32 2016 +0200 + + nss_db: Propagate ERANGE error if parse_line fails [BZ #19837] + + Reproducer (needs to run as root): + + perl -e \ + 'print "large:x:999:" . join(",", map {"user$_"} (1 .. 135))."\n"' \ + >> /etc/group + cd /var/db + make + getent -s db group + + After the fix, the last command should list the "large" group. + + The magic number 135 has been chosen so that the line is shorter than + 1024 bytes, but the pointers required to encode the member array will + cross the threshold, triggering the bug. + +Index: b/nss/nss_db/db-XXX.c +=================================================================== +--- a/nss/nss_db/db-XXX.c ++++ b/nss/nss_db/db-XXX.c +@@ -284,8 +284,8 @@ CONCAT(_nss_db_get,ENTNAME_r) (struct ST + } + if (err < 0) + { +- H_ERRNO_SET (HOST_NOT_FOUND); +- status = NSS_STATUS_NOTFOUND; ++ H_ERRNO_SET (NETDB_INTERNAL); ++ status = NSS_STATUS_TRYAGAIN; + break; + } diff --git a/SOURCES/glibc-rh1320596.patch b/SOURCES/glibc-rh1320596.patch new file mode 100644 index 00000000..96e4bf18 --- /dev/null +++ b/SOURCES/glibc-rh1320596.patch @@ -0,0 +1,216 @@ +commit b66d837bb5398795c6b0f651bd5a5d66091d8577 +Author: Florian Weimer +Date: Fri Mar 25 11:49:51 2016 +0100 + + resolv: Always set *resplen2 out parameter in send_dg [BZ #19791] + + Since commit 44d20bca52ace85850012b0ead37b360e3ecd96e (Implement + second fallback mode for DNS requests), there is a code path which + returns early, before *resplen2 is initialized. This happens if the + name server address is immediately recognized as invalid (because of + lack of protocol support, or if it is a broadcast address such + 255.255.255.255, or another invalid address). + + If this happens and *resplen2 was non-zero (which is the case if a + previous query resulted in a failure), __libc_res_nquery would reuse + an existing second answer buffer. This answer has been previously + identified as unusable (for example, it could be an NXDOMAIN + response). Due to the presence of a second answer, no name server + switching will occur. The result is a name resolution failure, + although a successful resolution would have been possible if name + servers have been switched and queries had proceeded along the search + path. + + The above paragraph still simplifies the situation. Before glibc + 2.23, if the second answer needed malloc, the stub resolver would + still attempt to reuse the second answer, but this is not possible + because __libc_res_nsearch has freed it, after the unsuccessful call + to __libc_res_nquerydomain, and set the buffer pointer to NULL. This + eventually leads to an assertion failure in __libc_res_nquery: + + /* Make sure both hp and hp2 are defined */ + assert((hp != NULL) && (hp2 != NULL)); + + If assertions are disabled, the consequence is a NULL pointer + dereference on the next line. + + Starting with glibc 2.23, as a result of commit + e9db92d3acfe1822d56d11abcea5bfc4c41cf6ca (CVE-2015-7547: getaddrinfo() + stack-based buffer overflow (Bug 18665)), the second answer is always + allocated with malloc. This means that the assertion failure happens + with small responses as well because there is no buffer to reuse, as + soon as there is a name resolution failure which triggers a search for + an answer along the search path. + + This commit addresses the issue by ensuring that *resplen2 is + initialized before the send_dg function returns. + + This commit also addresses a bug where an invalid second reply is + incorrectly returned as a valid to the caller. + +Index: glibc-2.17-c758a686/resolv/res_send.c +=================================================================== +--- glibc-2.17-c758a686.orig/resolv/res_send.c ++++ glibc-2.17-c758a686/resolv/res_send.c +@@ -672,6 +672,18 @@ libresolv_hidden_def (res_nsend) + + /* Private */ + ++/* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2 ++ is not NULL, and return zero. */ ++static int ++__attribute__ ((warn_unused_result)) ++close_and_return_error (res_state statp, int *resplen2) ++{ ++ __res_iclose(statp, false); ++ if (resplen2 != NULL) ++ *resplen2 = 0; ++ return 0; ++} ++ + /* The send_vc function is responsible for sending a DNS query over TCP + to the nameserver numbered NS from the res_state STATP i.e. + EXT(statp).nssocks[ns]. The function supports sending both IPv4 and +@@ -1159,7 +1171,11 @@ send_dg(res_state statp, + retry_reopen: + retval = reopen (statp, terrno, ns); + if (retval <= 0) +- return retval; ++ { ++ if (resplen2 != NULL) ++ *resplen2 = 0; ++ return retval; ++ } + retry: + evNowTime(&now); + evConsTime(&timeout, seconds, 0); +@@ -1172,8 +1188,6 @@ send_dg(res_state statp, + int recvresp2 = buf2 == NULL; + pfd[0].fd = EXT(statp).nssocks[ns]; + pfd[0].events = POLLOUT; +- if (resplen2 != NULL) +- *resplen2 = 0; + wait: + if (need_recompute) { + recompute_resend: +@@ -1181,9 +1195,7 @@ send_dg(res_state statp, + if (evCmpTime(finish, now) <= 0) { + poll_err_out: + Perror(statp, stderr, "poll", errno); +- err_out: +- __res_iclose(statp, false); +- return (0); ++ return close_and_return_error (statp, resplen2); + } + evSubTime(&timeout, &finish, &now); + need_recompute = 0; +@@ -1230,7 +1242,9 @@ send_dg(res_state statp, + } + + *gotsomewhere = 1; +- return (0); ++ if (resplen2 != NULL) ++ *resplen2 = 0; ++ return 0; + } + if (n < 0) { + if (errno == EINTR) +@@ -1298,7 +1312,7 @@ send_dg(res_state statp, + + fail_sendmmsg: + Perror(statp, stderr, "sendmmsg", errno); +- goto err_out; ++ return close_and_return_error (statp, resplen2); + } + } + else +@@ -1316,7 +1330,7 @@ send_dg(res_state statp, + if (errno == EINTR || errno == EAGAIN) + goto recompute_resend; + Perror(statp, stderr, "send", errno); +- goto err_out; ++ return close_and_return_error (statp, resplen2); + } + just_one: + if (nwritten != 0 || buf2 == NULL || single_request) +@@ -1392,7 +1406,7 @@ send_dg(res_state statp, + goto wait; + } + Perror(statp, stderr, "recvfrom", errno); +- goto err_out; ++ return close_and_return_error (statp, resplen2); + } + *gotsomewhere = 1; + if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) { +@@ -1403,7 +1417,7 @@ send_dg(res_state statp, + (stdout, ";; undersized: %d\n", + *thisresplenp)); + *terrno = EMSGSIZE; +- goto err_out; ++ return close_and_return_error (statp, resplen2); + } + if ((recvresp1 || hp->id != anhp->id) + && (recvresp2 || hp2->id != anhp->id)) { +@@ -1452,7 +1466,7 @@ send_dg(res_state statp, + ? *thisanssizp : *thisresplenp); + /* record the error */ + statp->_flags |= RES_F_EDNS0ERR; +- goto err_out; ++ return close_and_return_error (statp, resplen2); + } + #endif + if (!(statp->options & RES_INSECURE2) +@@ -1504,10 +1518,10 @@ send_dg(res_state statp, + goto wait; + } + +- __res_iclose(statp, false); + /* don't retry if called from dig */ + if (!statp->pfcode) +- return (0); ++ return close_and_return_error (statp, resplen2); ++ __res_iclose(statp, false); + } + if (anhp->rcode == NOERROR && anhp->ancount == 0 + && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) { +@@ -1529,6 +1543,8 @@ send_dg(res_state statp, + __res_iclose(statp, false); + // XXX if we have received one reply we could + // XXX use it and not repeat it over TCP... ++ if (resplen2 != NULL) ++ *resplen2 = 0; + return (1); + } + /* Mark which reply we received. */ +@@ -1544,21 +1560,22 @@ send_dg(res_state statp, + __res_iclose (statp, false); + retval = reopen (statp, terrno, ns); + if (retval <= 0) +- return retval; ++ { ++ if (resplen2 != NULL) ++ *resplen2 = 0; ++ return retval; ++ } + pfd[0].fd = EXT(statp).nssocks[ns]; + } + } + goto wait; + } +- /* +- * All is well, or the error is fatal. Signal that the +- * next nameserver ought not be tried. +- */ ++ /* All is well. We have received both responses (if ++ two responses were requested). */ + return (resplen); +- } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { +- /* Something went wrong. We can stop trying. */ +- goto err_out; +- } ++ } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) ++ /* Something went wrong. We can stop trying. */ ++ return close_and_return_error (statp, resplen2); + else { + /* poll should not have returned > 0 in this case. */ + abort (); diff --git a/SOURCES/glibc-rh1321993.patch b/SOURCES/glibc-rh1321993.patch new file mode 100644 index 00000000..078e294b --- /dev/null +++ b/SOURCES/glibc-rh1321993.patch @@ -0,0 +1,32 @@ +commit 317b199b4aff8cfa27f2302ab404d2bb5032b9a4 +Author: Florian Weimer +Date: Tue Mar 29 12:57:56 2016 +0200 + + CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879] + + The defensive copy is not needed because the name may not alias the + output buffer. + +diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c +index 2eb2f67..8f301a7 100644 +--- a/resolv/nss_dns/dns-network.c ++++ b/resolv/nss_dns/dns-network.c +@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, + } net_buffer; + querybuf *orig_net_buffer; + int anslen; +- char *qbuf; + enum nss_status status; + + if (__res_maybe_init (&_res, 0) == -1) + return NSS_STATUS_UNAVAIL; + +- qbuf = strdupa (name); +- + net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); + +- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, ++ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf, + 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + if (anslen < 0) + { diff --git a/SOURCES/glibc-rh1322544.patch b/SOURCES/glibc-rh1322544.patch new file mode 100644 index 00000000..56e8fbb4 --- /dev/null +++ b/SOURCES/glibc-rh1322544.patch @@ -0,0 +1,19 @@ +commit 217a74a85cdd60df236c296ad88142b78d35eccf +Author: Andreas Schwab +Date: Mon Dec 8 15:13:38 2014 +0100 + + Don't touch user-controlled stdio locks in forked child (bug 12847) + + The stdio locks for streams with the _IO_USER_LOCK flag should not be + touched by internal code. + +--- glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/fork.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/fork.c +@@ -45,7 +45,8 @@ + _IO_ITER i; + + for (i = _IO_iter_begin(); i != _IO_iter_end(); i = _IO_iter_next(i)) +- _IO_lock_init (*((_IO_lock_t *) _IO_iter_file(i)->_lock)); ++ if ((_IO_iter_file (i)->_flags & _IO_USER_LOCK) == 0) ++ _IO_lock_init (*((_IO_lock_t *) _IO_iter_file(i)->_lock)); + } diff --git a/SOURCES/glibc-rh1324427-1.patch b/SOURCES/glibc-rh1324427-1.patch new file mode 100644 index 00000000..ae3aac70 --- /dev/null +++ b/SOURCES/glibc-rh1324427-1.patch @@ -0,0 +1,891 @@ +commit 4603c51ef7989d7eb800cdd6f42aab206f891077 +Author: Stefan Liebler +Date: Thu Mar 31 17:37:16 2016 +0200 + + S390: Save and restore fprs/vrs while resolving symbols. + + On s390, no fpr/vrs were saved while resolving a symbol + via _dl_runtime_resolve/_dl_runtime_profile. + + According to the abi, the fpr-arguments are defined as call clobbered. + In leaf-functions, gcc 4.9 and newer can use fprs for saving/restoring gprs + instead of saving them to the stack. + If gcc do this in one of the resolver-functions, then the floating point + arguments of a library-function are invalid for the first library-function-call. + Thus, this patch saves/restores the fprs around the resolving code. + + The same could occur for vector registers. Furthermore an ifunc-resolver + could also clobber the vector/floating point argument registers. + Thus this patch provides the further variants _dl_runtime_resolve_vx/ + _dl_runtime_profile_vx, which are used if the kernel claims, that + we run on a machine with vector registers. + + Furthermore, if _dl_runtime_profile calls _dl_call_pltexit, + the pointers to inregs-/outregs-structs were setup invalid. + Now they point to the correct location in the stack-frame. + Before branching back to the caller, the return values are now + restored instead of containing the return values of the + _dl_call_pltexit() call. + On s390-32, an endless loop occurs if _dl_call_pltexit() should be called. + Now, this code-path branches to this function instead of just after the + preceding basr-instruction. + + ChangeLog: + + * sysdeps/s390/s390-32/dl-trampoline.S: Include dl-trampoline.h twice + to create a non-vector/vector version for _dl_runtime_resolve and + _dl_runtime_profile. Move implementation to ... + * sysdeps/s390/s390-32/dl-trampoline.h: ... here. + (_dl_runtime_resolve) Save and restore fpr/vrs. + (_dl_runtime_profile) Save and restore vrs and fix some issues + if _dl_call_pltexit is called. + * sysdeps/s390/s390-32/dl-machine.h (elf_machine_runtime_setup): + Choose the correct resolver function if running on a machine with vx. + * sysdeps/s390/s390-64/dl-trampoline.S: Include dl-trampoline.h twice + to create a non-vector/vector version for _dl_runtime_resolve and + _dl_runtime_profile. Move implementation to ... + * sysdeps/s390/s390-64/dl-trampoline.h: ... here. + (_dl_runtime_resolve) Save and restore fpr/vrs. + (_dl_runtime_profile) Save and restore vrs and fix some issues + * sysdeps/s390/s390-64/dl-machine.h: (elf_machine_runtime_setup): + Choose the correct resolver function if running on a machine with vx. + +diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h +index 14bde3b..ec0ae4a 100644 +--- a/sysdeps/s390/s390-32/dl-machine.h ++++ b/sysdeps/s390/s390-32/dl-machine.h +@@ -89,6 +89,11 @@ + { + extern void _dl_runtime_resolve (Elf32_Word); + extern void _dl_runtime_profile (Elf32_Word); ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ extern void _dl_runtime_resolve_vx (Elf32_Word); ++ extern void _dl_runtime_profile_vx (Elf32_Word); ++#endif ++ + + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -116,7 +121,14 @@ + end in this function. */ + if (__builtin_expect (profile, 0)) + { ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (GLRO(dl_hwcap) & HWCAP_S390_VX) ++ got[2] = (Elf32_Addr) &_dl_runtime_profile_vx; ++ else ++ got[2] = (Elf32_Addr) &_dl_runtime_profile; ++#else + got[2] = (Elf32_Addr) &_dl_runtime_profile; ++#endif + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) +@@ -125,9 +137,18 @@ + GL(dl_profile_map) = l; + } + else +- /* This function will get called to fix up the GOT entry indicated by +- the offset on the stack, and then jump to the resolved address. */ +- got[2] = (Elf32_Addr) &_dl_runtime_resolve; ++ { ++ /* This function will get called to fix up the GOT entry indicated by ++ the offset on the stack, and then jump to the resolved address. */ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (GLRO(dl_hwcap) & HWCAP_S390_VX) ++ got[2] = (Elf32_Addr) &_dl_runtime_resolve_vx; ++ else ++ got[2] = (Elf32_Addr) &_dl_runtime_resolve; ++#else ++ got[2] = (Elf32_Addr) &_dl_runtime_resolve; ++#endif ++ } + } + + return lazy; +diff --git a/sysdeps/s390/s390-32/dl-trampoline.S b/sysdeps/s390/s390-32/dl-trampoline.S +index 1645610..859183c 100644 +--- a/sysdeps/s390/s390-32/dl-trampoline.S ++++ b/sysdeps/s390/s390-32/dl-trampoline.S +@@ -16,130 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-/* This code is used in dl-runtime.c to call the `fixup' function +- and then redirect to the address it returns. */ +- +-/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile +- * with the following linkage: +- * r2 - r6 : parameter registers +- * f0, f2 : floating point parameter registers +- * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 +- * 96(r15) : additional stack parameters +- * The normal clobber rules for function calls apply: +- * r0 - r5 : call clobbered +- * r6 - r13 : call saved +- * r14 : return address (call clobbered) +- * r15 : stack pointer (call saved) +- * f4, f6 : call saved +- * f0 - f3, f5, f7 - f15 : call clobbered +- */ +- + #include + + .text +- .globl _dl_runtime_resolve +- .type _dl_runtime_resolve, @function +- cfi_startproc +- .align 16 +-_dl_runtime_resolve: +- stm %r2,%r5,32(%r15) # save registers +- st %r14,8(%r15) +- cfi_offset (r14, -88) +- lr %r0,%r15 # create stack frame +- ahi %r15,-96 +- cfi_adjust_cfa_offset (96) +- st 0,0(%r15) +- lm %r2,%r3,120(%r15) # load args saved by PLT +- basr %r1,0 +-0: l %r14,1f-0b(%r1) +- bas %r14,0(%r14,%r1) # call resolver +- lr %r1,%r2 # function addr returned in r2 +- ahi %r15,96 # remove stack frame +- cfi_adjust_cfa_offset (-96) +- l %r14,8(15) # restore registers +- lm %r2,%r5,32(%r15) +- br %r1 +-1: .long _dl_fixup - 0b +- cfi_endproc +- .size _dl_runtime_resolve, .-_dl_runtime_resolve +- +- +-#ifndef PROF +- .globl _dl_runtime_profile +- .type _dl_runtime_profile, @function +- cfi_startproc +- .align 16 +-_dl_runtime_profile: +- stm %r2,%r6,32(%r15) # save registers +- std %f0,56(%r15) +- std %f2,64(%r15) +- st %r6,8(%r15) +- st %r12,12(%r15) +- st %r14,16(%r15) +- cfi_offset (r6, -64) +- cfi_offset (f0, -40) +- cfi_offset (f2, -32) +- cfi_offset (r12, -84) +- cfi_offset (r14, -80) +- lr %r12,%r15 # create stack frame +- cfi_def_cfa_register (12) +- ahi %r15,-96 +- st %r12,0(%r15) +- lm %r2,%r3,24(%r12) # load arguments saved by PLT +- lr %r4,%r14 # return address as third parameter +- basr %r1,0 +-0: l %r14,6f-0b(%r1) +- la %r5,32(%r12) # pointer to struct La_s390_32_regs +- la %r6,20(%r12) # long int * framesize +- bas %r14,0(%r14,%r1) # call resolver +- lr %r1,%r2 # function addr returned in r2 +- icm %r0,15,20(%r12) # load & test framesize +- jnm 2f +- +- lm %r2,%r6,32(%r12) +- ld %f0,56(%r12) +- ld %f2,64(%r12) +- lr %r15,%r12 # remove stack frame +- cfi_def_cfa_register (15) +- l %r14,16(%r15) # restore registers +- l %r12,12(%r15) +- br %r1 # tail-call to the resolved function +- +- cfi_def_cfa_register (12) +-2: jz 4f # framesize == 0 ? +- ahi %r0,7 # align framesize to 8 +- lhi %r2,-8 +- nr %r0,%r2 +- slr %r15,%r0 # make room for framesize bytes +- st %r12,0(%r15) +- la %r2,96(%r15) +- la %r3,96(%r12) +- srl %r0,3 +-3: mvc 0(8,%r2),0(%r3) # copy additional parameters +- la %r2,8(%r2) +- la %r3,8(%r3) +- brct %r0,3b +-4: lm %r2,%r6,32(%r12) # load register parameters +- ld %f0,56(%r12) +- ld %f2,64(%r12) +- basr %r14,%r1 # call resolved function +- stm %r2,%r3,72(%r12) +- std %f0,80(%r12) +- lm %r2,%r3,24(%r12) # load arguments saved by PLT +- basr %r1,0 +-5: l %r14,7f-5b(%r1) +- la %r4,32(%r12) # pointer to struct La_s390_32_regs +- la %r5,72(%r12) # pointer to struct La_s390_32_retval +- basr %r14,%r1 # call _dl_call_pltexit +- +- lr %r15,%r12 # remove stack frame +- cfi_def_cfa_register (15) +- l %r14,16(%r15) # restore registers +- l %r12,12(%r15) +- br %r14 +- +-6: .long _dl_profile_fixup - 0b +-7: .long _dl_call_pltexit - 5b +- cfi_endproc +- .size _dl_runtime_profile, .-_dl_runtime_profile ++/* Create variant of _dl_runtime_resolve/profile for machines before z13. ++ No vector registers are saved/restored. */ ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Create variant of _dl_runtime_resolve/profile for z13 and newer. ++ The vector registers are saved/restored, too.*/ ++# define _dl_runtime_resolve _dl_runtime_resolve_vx ++# define _dl_runtime_profile _dl_runtime_profile_vx ++# define RESTORE_VRS ++# include + #endif +diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h +new file mode 100644 +index 0000000..a152a7b +--- /dev/null ++++ b/sysdeps/s390/s390-32/dl-trampoline.h +@@ -0,0 +1,215 @@ ++/* PLT trampolines. s390 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This code is used in dl-runtime.c to call the `fixup' function ++ and then redirect to the address it returns. */ ++ ++/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile ++ * with the following linkage: ++ * r2 - r6 : parameter registers ++ * f0, f2 : floating point parameter registers ++ * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers ++ * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 ++ * 96(r15) : additional stack parameters ++ * The normal clobber rules for function calls apply: ++ * r0 - r5 : call clobbered ++ * r6 - r13 : call saved ++ * r14 : return address (call clobbered) ++ * r15 : stack pointer (call saved) ++ * f4, f6 : call saved ++ * f0 - f3, f5, f7 - f15 : call clobbered ++ * v0 - v3, v5, v7 - v15 : bytes 0-7 overlap with fprs: call clobbered ++ bytes 8-15: call clobbered ++ * v4, v6 : bytes 0-7 overlap with f4, f6: call saved ++ bytes 8-15: call clobbered ++ * v16 - v31 : call clobbered ++ */ ++ ++ ++ .globl _dl_runtime_resolve ++ .type _dl_runtime_resolve, @function ++ cfi_startproc ++ .align 16 ++_dl_runtime_resolve: ++ stm %r2,%r5,32(%r15) # save registers ++ cfi_offset (r2, -64) ++ cfi_offset (r3, -60) ++ cfi_offset (r4, -56) ++ cfi_offset (r5, -52) ++ std %f0,56(%r15) ++ cfi_offset (f0, -40) ++ std %f2,64(%r15) ++ cfi_offset (f2, -32) ++ st %r14,8(%r15) ++ cfi_offset (r14, -88) ++ lr %r0,%r15 ++ lm %r2,%r3,24(%r15) # load args saved by PLT ++#ifdef RESTORE_VRS ++ ahi %r15,-224 # create stack frame ++ cfi_adjust_cfa_offset (224) ++ .machine push ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ vstm %v24,%v31,96(%r15) # store call-clobbered vr arguments ++ cfi_offset (v24, -224) ++ cfi_offset (v25, -208) ++ cfi_offset (v26, -192) ++ cfi_offset (v27, -176) ++ cfi_offset (v28, -160) ++ cfi_offset (v29, -144) ++ cfi_offset (v30, -128) ++ cfi_offset (v31, -112) ++ .machine pop ++#else ++ ahi %r15,-96 # create stack frame ++ cfi_adjust_cfa_offset (96) ++#endif ++ st %r0,0(%r15) # write backchain ++ basr %r1,0 ++0: l %r14,1f-0b(%r1) ++ bas %r14,0(%r14,%r1) # call _dl_fixup ++ lr %r1,%r2 # function addr returned in r2 ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ vlm %v24,%v31,96(%r15) # restore vector registers ++ .machine pop ++ aghi %r15,224 # remove stack frame ++ cfi_adjust_cfa_offset (-224) ++#else ++ ahi %r15,96 # remove stack frame ++ cfi_adjust_cfa_offset (-96) ++#endif ++ l %r14,8(15) # restore registers ++ ld %f0,56(%r15) ++ ld %f2,64(%r15) ++ lm %r2,%r5,32(%r15) ++ br %r1 ++1: .long _dl_fixup - 0b ++ cfi_endproc ++ .size _dl_runtime_resolve, .-_dl_runtime_resolve ++ ++ ++#ifndef PROF ++ .globl _dl_runtime_profile ++ .type _dl_runtime_profile, @function ++ cfi_startproc ++ .align 16 ++_dl_runtime_profile: ++ stm %r2,%r6,32(%r15) # save registers ++ cfi_offset (r2, -64) # + r6 needed as arg for ++ cfi_offset (r3, -60) # _dl_profile_fixup ++ cfi_offset (r4, -56) ++ cfi_offset (r5, -52) ++ cfi_offset (r6, -48) ++ std %f0,56(%r15) ++ cfi_offset (f0, -40) ++ std %f2,64(%r15) ++ cfi_offset (f2, -32) ++ st %r12,12(%r15) # r12 is used as backup of r15 ++ cfi_offset (r12, -84) ++ st %r14,16(%r15) ++ cfi_offset (r14, -80) ++ lr %r12,%r15 # backup stack pointer ++ cfi_def_cfa_register (12) ++#ifdef RESTORE_VRS ++ ahi %r15,-224 # create stack frame ++ .machine push ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ vstm %v24,%v31,96(%r15) # store call-clobbered vr arguments ++ cfi_offset (v24, -224) ++ cfi_offset (v25, -208) ++ cfi_offset (v26, -192) ++ cfi_offset (v27, -176) ++ cfi_offset (v28, -160) ++ cfi_offset (v29, -144) ++ cfi_offset (v30, -128) ++ cfi_offset (v31, -112) ++ .machine pop ++#else ++ ahi %r15,-96 # create stack frame ++#endif ++ st %r12,0(%r15) # save backchain ++ lm %r2,%r3,24(%r12) # load arguments saved by PLT ++ lr %r4,%r14 # return address as third parameter ++ basr %r1,0 ++0: l %r14,6f-0b(%r1) ++ la %r5,32(%r12) # pointer to struct La_s390_32_regs ++ la %r6,20(%r12) # long int * framesize ++ bas %r14,0(%r14,%r1) # call resolver ++ lr %r1,%r2 # function addr returned in r2 ++ ld %f0,56(%r12) # restore call-clobbered arg fprs ++ ld %f2,64(%r12) ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ .machinemode "zarch_nohighgprs" ++ vlm %v24,%v31,96(%r15) # restore call-clobbered arg vrs ++ .machine pop ++#endif ++ icm %r0,15,20(%r12) # load & test framesize ++ jnm 2f ++ ++ lm %r2,%r6,32(%r12) ++ lr %r15,%r12 # remove stack frame ++ cfi_def_cfa_register (15) ++ l %r14,16(%r15) # restore registers ++ l %r12,12(%r15) ++ br %r1 # tail-call to the resolved function ++ ++ cfi_def_cfa_register (12) ++2: jz 4f # framesize == 0 ? ++ ahi %r0,7 # align framesize to 8 ++ lhi %r2,-8 ++ nr %r0,%r2 ++ slr %r15,%r0 # make room for framesize bytes ++ st %r12,0(%r15) # save backchain ++ la %r2,96(%r15) ++ la %r3,96(%r12) ++ srl %r0,3 ++3: mvc 0(8,%r2),0(%r3) # copy additional parameters ++ la %r2,8(%r2) ++ la %r3,8(%r3) ++ brct %r0,3b ++4: lm %r2,%r6,32(%r12) # load register parameters ++ basr %r14,%r1 # call resolved function ++ stm %r2,%r3,72(%r12) # store return values r2, r3, f0 ++ std %f0,80(%r12) # to struct La_s390_32_retval ++ lm %r2,%r3,24(%r12) # load arguments saved by PLT ++ basr %r1,0 ++5: l %r14,7f-5b(%r1) ++ la %r4,32(%r12) # pointer to struct La_s390_32_regs ++ la %r5,72(%r12) # pointer to struct La_s390_32_retval ++ bas %r14,0(%r14,%r1) # call _dl_call_pltexit ++ ++ lr %r15,%r12 # remove stack frame ++ cfi_def_cfa_register (15) ++ l %r14,16(%r15) # restore registers ++ l %r12,12(%r15) ++ l %r2,72(%r15) # restore return values ++ l %r3,76(%r15) ++ ld %f0,80(%r15) ++ br %r14 ++ ++6: .long _dl_profile_fixup - 0b ++7: .long _dl_call_pltexit - 5b ++ cfi_endproc ++ .size _dl_runtime_profile, .-_dl_runtime_profile ++#endif +diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h +index cb81aaf..9ee7c92 100644 +--- a/sysdeps/s390/s390-64/dl-machine.h ++++ b/sysdeps/s390/s390-64/dl-machine.h +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + #define ELF_MACHINE_IRELATIVE R_390_IRELATIVE +@@ -78,6 +79,10 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + { + extern void _dl_runtime_resolve (Elf64_Word); + extern void _dl_runtime_profile (Elf64_Word); ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ extern void _dl_runtime_resolve_vx (Elf64_Word); ++ extern void _dl_runtime_profile_vx (Elf64_Word); ++#endif + + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -105,7 +110,14 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + end in this function. */ + if (__builtin_expect (profile, 0)) + { ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (GLRO(dl_hwcap) & HWCAP_S390_VX) ++ got[2] = (Elf64_Addr) &_dl_runtime_profile_vx; ++ else ++ got[2] = (Elf64_Addr) &_dl_runtime_profile; ++#else + got[2] = (Elf64_Addr) &_dl_runtime_profile; ++#endif + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) +@@ -114,9 +126,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + GL(dl_profile_map) = l; + } + else +- /* This function will get called to fix up the GOT entry indicated by +- the offset on the stack, and then jump to the resolved address. */ +- got[2] = (Elf64_Addr) &_dl_runtime_resolve; ++ { ++ /* This function will get called to fix up the GOT entry indicated by ++ the offset on the stack, and then jump to the resolved address. */ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (GLRO(dl_hwcap) & HWCAP_S390_VX) ++ got[2] = (Elf64_Addr) &_dl_runtime_resolve_vx; ++ else ++ got[2] = (Elf64_Addr) &_dl_runtime_resolve; ++#else ++ got[2] = (Elf64_Addr) &_dl_runtime_resolve; ++#endif ++ } + } + + return lazy; +diff --git a/sysdeps/s390/s390-64/dl-trampoline.S b/sysdeps/s390/s390-64/dl-trampoline.S +index 6919ed0..1b0c9e2 100644 +--- a/sysdeps/s390/s390-64/dl-trampoline.S ++++ b/sysdeps/s390/s390-64/dl-trampoline.S +@@ -16,126 +16,18 @@ + License along with the GNU C Library; if not, see + . */ + +-/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile +- * with the following linkage: +- * r2 - r6 : parameter registers +- * f0, f2, f4, f6 : floating point parameter registers +- * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 +- * 160(r15) : additional stack parameters +- * The normal clobber rules for function calls apply: +- * r0 - r5 : call clobbered +- * r6 - r13 : call saved +- * r14 : return address (call clobbered) +- * r15 : stack pointer (call saved) +- * f1, f3, f5, f7 : call saved +- * f0 - f3, f5, f7 - f15 : call clobbered +- */ +- + #include + + .text +- .globl _dl_runtime_resolve +- .type _dl_runtime_resolve, @function +- cfi_startproc +- .align 16 +-_dl_runtime_resolve: +- stmg %r2,%r5,64(15) # save call-clobbered argument registers +- stg %r14,96(15) +- cfi_offset (r14, -64) +- lgr %r0,%r15 +- aghi %r15,-160 # create stack frame +- cfi_adjust_cfa_offset (160) +- stg %r0,0(%r15) # write backchain +- lmg %r2,%r3,208(%r15)# load args saved by PLT +- brasl %r14,_dl_fixup # call fixup +- lgr %r1,%r2 # function addr returned in r2 +- aghi %r15,160 # remove stack frame +- cfi_adjust_cfa_offset (-160) +- lg %r14,96(15) # restore registers +- lmg %r2,%r5,64(15) +- br %r1 +- cfi_endproc +- .size _dl_runtime_resolve, .-_dl_runtime_resolve +- +- +-#ifndef PROF +- .globl _dl_runtime_profile +- .type _dl_runtime_profile, @function +- cfi_startproc +- .align 16 +-_dl_runtime_profile: +- stmg %r2,%r6,64(%r15) # save call-clobbered arg regs +- std %f0,104(%r15) # + r6 needed as arg for +- std %f2,112(%r15) # _dl_profile_fixup +- std %f4,120(%r15) +- std %f6,128(%r15) +- stg %r12,24(%r15) # r12 is used as backup of r15 +- stg %r14,32(%r15) +- cfi_offset (r6, -96) +- cfi_offset (f0, -56) +- cfi_offset (f2, -48) +- cfi_offset (f4, -40) +- cfi_offset (f6, -32) +- cfi_offset (r12, -136) +- cfi_offset (r14, -128) +- lgr %r12,%r15 # backup stack pointer +- cfi_def_cfa_register (12) +- aghi %r15,-160 # create stack frame +- stg %r12,0(%r15) # save backchain +- lmg %r2,%r3,48(%r12) # load arguments saved by PLT +- lgr %r4,%r14 # return address as third parameter +- la %r5,64(%r12) # pointer to struct La_s390_32_regs +- la %r6,40(%r12) # long int * framesize +- brasl %r14,_dl_profile_fixup # call resolver +- lgr %r1,%r2 # function addr returned in r2 +- lg %r0,40(%r12) # load framesize +- ltgr %r0,%r0 +- jnm 1f +- +- lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call +- ld %f0,104(%r12) # so we can do a tail call without +- ld %f2,112(%r12) # copying the arg overflow area +- ld %f4,120(%r12) +- ld %f6,128(%r12) +- +- lgr %r15,%r12 # remove stack frame +- cfi_def_cfa_register (15) +- lg %r14,32(%r15) # restore registers +- lg %r12,24(%r15) +- br %r1 # tail-call to resolved function +- +- cfi_def_cfa_register (12) +-1: jz 4f # framesize == 0 ? +- aghi %r0,7 # align framesize to 8 +- nill %r0,0xfff8 +- slgr %r15,%r0 # make room for framesize bytes +- stg %r12,0(%r15) +- la %r2,160(%r15) +- la %r3,160(%r12) +- srlg %r0,%r0,3 +-3: mvc 0(8,%r2),0(%r3) # copy additional parameters +- la %r2,8(%r2) +- la %r3,8(%r3) +- brctg %r0,3b +-4: lmg %r2,%r6,64(%r12) # load register parameters +- ld %f0,104(%r12) # restore call-clobbered arg regs +- ld %f2,112(%r12) +- ld %f4,120(%r12) +- ld %f6,128(%r12) +- basr %r14,%r1 # call resolved function +- stg %r2,136(%r12) +- std %f0,144(%r12) +- lmg %r2,%r3,48(%r12) # load arguments saved by PLT +- la %r4,32(%r12) # pointer to struct La_s390_32_regs +- la %r5,72(%r12) # pointer to struct La_s390_32_retval +- brasl %r14,_dl_call_pltexit +- +- lgr %r15,%r12 # remove stack frame +- cfi_def_cfa_register (15) +- lg %r14,32(%r15) # restore registers +- lg %r12,24(%r15) +- br %r14 +- +- cfi_endproc +- .size _dl_runtime_profile, .-_dl_runtime_profile ++/* Create variant of _dl_runtime_resolve/profile for machines before z13. ++ No vector registers are saved/restored. */ ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Create variant of _dl_runtime_resolve/profile for z13 and newer. ++ The vector registers are saved/restored, too.*/ ++# define _dl_runtime_resolve _dl_runtime_resolve_vx ++# define _dl_runtime_profile _dl_runtime_profile_vx ++# define RESTORE_VRS ++# include + #endif +diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h +new file mode 100644 +index 0000000..658e3a3 +--- /dev/null ++++ b/sysdeps/s390/s390-64/dl-trampoline.h +@@ -0,0 +1,211 @@ ++/* PLT trampolines. s390x version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile ++ * with the following linkage: ++ * r2 - r6 : parameter registers ++ * f0, f2, f4, f6 : floating point parameter registers ++ * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers ++ * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 ++ * 160(r15) : additional stack parameters ++ * The normal clobber rules for function calls apply: ++ * r0 - r5 : call clobbered ++ * r6 - r13 : call saved ++ * r14 : return address (call clobbered) ++ * r15 : stack pointer (call saved) ++ * f0 - f7 : call clobbered ++ * f8 - f15 : call saved ++ * v0 - v7 : bytes 0-7 overlap with f0-f7: call clobbered ++ bytes 8-15: call clobbered ++ * v8 - v15 : bytes 0-7 overlap with f8-f15: call saved ++ bytes 8-15: call clobbered ++ * v16 - v31 : call clobbered ++ */ ++ ++ .globl _dl_runtime_resolve ++ .type _dl_runtime_resolve, @function ++ cfi_startproc ++ .align 16 ++_dl_runtime_resolve: ++ stmg %r2,%r5,64(%r15) # save call-clobbered argument registers ++ cfi_offset (r2, -96) ++ cfi_offset (r3, -88) ++ cfi_offset (r4, -80) ++ cfi_offset (r5, -72) ++ std %f0,104(%r15) ++ cfi_offset (f0, -56) ++ std %f2,112(%r15) ++ cfi_offset (f2, -48) ++ std %f4,120(%r15) ++ cfi_offset (f4, -40) ++ std %f6,128(%r15) ++ cfi_offset (f6, -32) ++ stg %r14,96(15) ++ cfi_offset (r14, -64) ++ lmg %r2,%r3,48(%r15) # load args for fixup saved by PLT ++ lgr %r0,%r15 ++#ifdef RESTORE_VRS ++ aghi %r15,-288 # create stack frame ++ cfi_adjust_cfa_offset (288) ++ .machine push ++ .machine "z13" ++ vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers ++ cfi_offset (v24, -288) ++ cfi_offset (v25, -272) ++ cfi_offset (v26, -256) ++ cfi_offset (v27, -240) ++ cfi_offset (v28, -224) ++ cfi_offset (v29, -208) ++ cfi_offset (v30, -192) ++ cfi_offset (v31, -176) ++ .machine pop ++#else ++ aghi %r15,-160 # create stack frame ++ cfi_adjust_cfa_offset (160) ++#endif ++ stg %r0,0(%r15) # write backchain ++ brasl %r14,_dl_fixup # call _dl_fixup ++ lgr %r1,%r2 # function addr returned in r2 ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ vlm %v24,%v31,160(%r15)# restore vector registers ++ .machine pop ++ aghi %r15,288 # remove stack frame ++ cfi_adjust_cfa_offset (-288) ++#else ++ aghi %r15,160 # remove stack frame ++ cfi_adjust_cfa_offset (-160) ++#endif ++ lg %r14,96(%r15) # restore registers ++ ld %f0,104(%r15) ++ ld %f2,112(%r15) ++ ld %f4,120(%r15) ++ ld %f6,128(%r15) ++ lmg %r2,%r5,64(%r15) ++ br %r1 ++ cfi_endproc ++ .size _dl_runtime_resolve, .-_dl_runtime_resolve ++ ++ ++#ifndef PROF ++ .globl _dl_runtime_profile ++ .type _dl_runtime_profile, @function ++ cfi_startproc ++ .align 16 ++_dl_runtime_profile: ++ stmg %r2,%r6,64(%r15) # save call-clobbered arg regs ++ cfi_offset (r2, -96) # + r6 needed as arg for ++ cfi_offset (r3, -88) # _dl_profile_fixup ++ cfi_offset (r4, -80) ++ cfi_offset (r5, -72) ++ cfi_offset (r6, -64) ++ std %f0,104(%r15) ++ cfi_offset (f0, -56) ++ std %f2,112(%r15) ++ cfi_offset (f2, -48) ++ std %f4,120(%r15) ++ cfi_offset (f4, -40) ++ std %f6,128(%r15) ++ cfi_offset (f6, -32) ++ stg %r12,24(%r15) # r12 is used as backup of r15 ++ cfi_offset (r12, -136) ++ stg %r14,32(%r15) ++ cfi_offset (r14, -128) ++ lgr %r12,%r15 # backup stack pointer ++ cfi_def_cfa_register (12) ++#ifdef RESTORE_VRS ++ aghi %r15,-288 # create stack frame ++ .machine push ++ .machine "z13" ++ vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers ++ cfi_offset (v24, -288) ++ cfi_offset (v25, -272) ++ cfi_offset (v26, -256) ++ cfi_offset (v27, -240) ++ cfi_offset (v28, -224) ++ cfi_offset (v29, -208) ++ cfi_offset (v30, -192) ++ cfi_offset (v31, -176) ++ .machine pop ++#else ++ aghi %r15,-160 # create stack frame ++#endif ++ stg %r12,0(%r15) # save backchain ++ lmg %r2,%r3,48(%r12) # load arguments saved by PLT ++ lgr %r4,%r14 # return address as third parameter ++ la %r5,64(%r12) # pointer to struct La_s390_64_regs ++ la %r6,40(%r12) # long int * framesize ++ brasl %r14,_dl_profile_fixup # call resolver ++ lgr %r1,%r2 # function addr returned in r2 ++ ld %f0,104(%r12) # restore call-clobbered arg fprs ++ ld %f2,112(%r12) ++ ld %f4,120(%r12) ++ ld %f6,128(%r12) ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ vlm %v24,%v31,160(%r15) # restore call-clobbered arg vrs ++ .machine pop ++#endif ++ lg %r0,40(%r12) # load framesize ++ ltgr %r0,%r0 ++ jnm 1f ++ ++ lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call ++ # so we can do a tail call without ++ # copying the arg overflow area ++ lgr %r15,%r12 # remove stack frame ++ cfi_def_cfa_register (15) ++ lg %r14,32(%r15) # restore registers ++ lg %r12,24(%r15) ++ br %r1 # tail-call to resolved function ++ ++ cfi_def_cfa_register (12) ++1: jz 4f # framesize == 0 ? ++ aghi %r0,7 # align framesize to 8 ++ nill %r0,0xfff8 ++ slgr %r15,%r0 # make room for framesize bytes ++ stg %r12,0(%r15) # save backchain ++ la %r2,160(%r15) ++ la %r3,160(%r12) ++ srlg %r0,%r0,3 ++3: mvc 0(8,%r2),0(%r3) # copy additional parameters ++ la %r2,8(%r2) # depending on framesize ++ la %r3,8(%r3) ++ brctg %r0,3b ++4: lmg %r2,%r6,64(%r12) # restore call-clobbered arg gprs ++ basr %r14,%r1 # call resolved function ++ stg %r2,136(%r12) # store return values r2, f0 ++ std %f0,144(%r12) # to struct La_s390_64_retval ++ lmg %r2,%r3,48(%r12) # load arguments saved by PLT ++ la %r4,64(%r12) # pointer to struct La_s390_64_regs ++ la %r5,136(%r12) # pointer to struct La_s390_64_retval ++ brasl %r14,_dl_call_pltexit ++ ++ lgr %r15,%r12 # remove stack frame ++ cfi_def_cfa_register (15) ++ lg %r14,32(%r15) # restore registers ++ lg %r12,24(%r15) ++ lg %r2,136(%r15) # restore return values ++ ld %f0,144(%r15) ++ br %r14 # Jump back to caller ++ ++ cfi_endproc ++ .size _dl_runtime_profile, .-_dl_runtime_profile ++#endif diff --git a/SOURCES/glibc-rh1324427-2.patch b/SOURCES/glibc-rh1324427-2.patch new file mode 100644 index 00000000..fe5f4674 --- /dev/null +++ b/SOURCES/glibc-rh1324427-2.patch @@ -0,0 +1,384 @@ +commit 5cdd1989d1d2f135d02e66250f37ba8e767f9772 +Author: Stefan Liebler +Date: Thu Mar 31 17:37:16 2016 +0200 + + S390: Extend structs La_s390_regs / La_s390_retval with vector-registers. + + Starting with z13, vector registers can also occur as argument registers. + Thus the passed input/output register structs for + la_s390_[32|64]_gnu_plt[enter|exit] functions should reflect those new + registers. This patch extends these structs La_s390_regs and La_s390_retval + and adjusts _dl_runtime_profile() to handle those fields in case of + running on a z13 machine. + + ChangeLog: + + * sysdeps/s390/bits/link.h: (La_s390_vr) New typedef. + (La_s390_32_regs): Append vector register lr_v24-lr_v31. + (La_s390_64_regs): Likewise. + (La_s390_32_retval): Append vector register lrv_v24. + (La_s390_64_retval): Likeweise. + * sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_profile): + Handle extended structs La_s390_32_regs and La_s390_32_retval. + * sysdeps/s390/s390-64/dl-trampoline.h (_dl_runtime_profile): + Handle extended structs La_s390_64_regs and La_s390_64_retval. + +diff --git a/sysdeps/s390/bits/link.h b/sysdeps/s390/bits/link.h +index 2ef7f44..e27ed67 100644 +--- a/sysdeps/s390/bits/link.h ++++ b/sysdeps/s390/bits/link.h +@@ -19,6 +19,9 @@ + # error "Never include directly; use instead." + #endif + ++#if defined HAVE_S390_VX_ASM_SUPPORT ++typedef char La_s390_vr[16]; ++#endif + + #if __ELF_NATIVE_CLASS == 32 + +@@ -32,6 +35,16 @@ typedef struct La_s390_32_regs + uint32_t lr_r6; + double lr_fp0; + double lr_fp2; ++# if defined HAVE_S390_VX_ASM_SUPPORT ++ La_s390_vr lr_v24; ++ La_s390_vr lr_v25; ++ La_s390_vr lr_v26; ++ La_s390_vr lr_v27; ++ La_s390_vr lr_v28; ++ La_s390_vr lr_v29; ++ La_s390_vr lr_v30; ++ La_s390_vr lr_v31; ++# endif + } La_s390_32_regs; + + /* Return values for calls from PLT on s390-32. */ +@@ -40,6 +53,9 @@ typedef struct La_s390_32_retval + uint32_t lrv_r2; + uint32_t lrv_r3; + double lrv_fp0; ++# if defined HAVE_S390_VX_ASM_SUPPORT ++ La_s390_vr lrv_v24; ++# endif + } La_s390_32_retval; + + +@@ -77,6 +93,16 @@ typedef struct La_s390_64_regs + double lr_fp2; + double lr_fp4; + double lr_fp6; ++# if defined HAVE_S390_VX_ASM_SUPPORT ++ La_s390_vr lr_v24; ++ La_s390_vr lr_v25; ++ La_s390_vr lr_v26; ++ La_s390_vr lr_v27; ++ La_s390_vr lr_v28; ++ La_s390_vr lr_v29; ++ La_s390_vr lr_v30; ++ La_s390_vr lr_v31; ++# endif + } La_s390_64_regs; + + /* Return values for calls from PLT on s390-64. */ +@@ -84,6 +110,9 @@ typedef struct La_s390_64_retval + { + uint64_t lrv_r2; + double lrv_fp0; ++# if defined HAVE_S390_VX_ASM_SUPPORT ++ La_s390_vr lrv_v24; ++# endif + } La_s390_64_retval; + + +diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h +index a152a7b..bb74d27 100644 +--- a/sysdeps/s390/s390-32/dl-trampoline.h ++++ b/sysdeps/s390/s390-32/dl-trampoline.h +@@ -112,28 +112,31 @@ _dl_runtime_resolve: + cfi_startproc + .align 16 + _dl_runtime_profile: +- stm %r2,%r6,32(%r15) # save registers +- cfi_offset (r2, -64) # + r6 needed as arg for +- cfi_offset (r3, -60) # _dl_profile_fixup +- cfi_offset (r4, -56) +- cfi_offset (r5, -52) +- cfi_offset (r6, -48) +- std %f0,56(%r15) +- cfi_offset (f0, -40) +- std %f2,64(%r15) +- cfi_offset (f2, -32) + st %r12,12(%r15) # r12 is used as backup of r15 + cfi_offset (r12, -84) + st %r14,16(%r15) + cfi_offset (r14, -80) + lr %r12,%r15 # backup stack pointer + cfi_def_cfa_register (12) ++ ahi %r15,-264 # create stack frame: ++ # 96 + sizeof(La_s390_32_regs) ++ st %r12,0(%r15) # save backchain ++ ++ stm %r2,%r6,96(%r15) # save registers ++ cfi_offset (r2, -264) # + r6 needed as arg for ++ cfi_offset (r3, -260) # _dl_profile_fixup ++ cfi_offset (r4, -256) ++ cfi_offset (r5, -252) ++ cfi_offset (r6, -248) ++ std %f0,120(%r15) ++ cfi_offset (f0, -240) ++ std %f2,128(%r15) ++ cfi_offset (f2, -232) + #ifdef RESTORE_VRS +- ahi %r15,-224 # create stack frame + .machine push + .machine "z13" + .machinemode "zarch_nohighgprs" +- vstm %v24,%v31,96(%r15) # store call-clobbered vr arguments ++ vstm %v24,%v31,136(%r15) # store call-clobbered vr arguments + cfi_offset (v24, -224) + cfi_offset (v25, -208) + cfi_offset (v26, -192) +@@ -143,31 +146,31 @@ _dl_runtime_profile: + cfi_offset (v30, -128) + cfi_offset (v31, -112) + .machine pop +-#else +- ahi %r15,-96 # create stack frame + #endif +- st %r12,0(%r15) # save backchain ++ + lm %r2,%r3,24(%r12) # load arguments saved by PLT + lr %r4,%r14 # return address as third parameter + basr %r1,0 + 0: l %r14,6f-0b(%r1) +- la %r5,32(%r12) # pointer to struct La_s390_32_regs ++ la %r5,96(%r15) # pointer to struct La_s390_32_regs + la %r6,20(%r12) # long int * framesize + bas %r14,0(%r14,%r1) # call resolver + lr %r1,%r2 # function addr returned in r2 +- ld %f0,56(%r12) # restore call-clobbered arg fprs +- ld %f2,64(%r12) ++ ld %f0,120(%r15) # restore call-clobbered arg fprs ++ ld %f2,128(%r15) + #ifdef RESTORE_VRS + .machine push + .machine "z13" + .machinemode "zarch_nohighgprs" +- vlm %v24,%v31,96(%r15) # restore call-clobbered arg vrs ++ vlm %v24,%v31,136(%r15) # restore call-clobbered arg vrs + .machine pop + #endif + icm %r0,15,20(%r12) # load & test framesize + jnm 2f + +- lm %r2,%r6,32(%r12) ++ lm %r2,%r6,96(%r15) # framesize < 0 means no pltexit call ++ # so we can do a tail call without ++ # copying the arg overflow area + lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + l %r14,16(%r15) # restore registers +@@ -175,7 +178,9 @@ _dl_runtime_profile: + br %r1 # tail-call to the resolved function + + cfi_def_cfa_register (12) +-2: jz 4f # framesize == 0 ? ++2: la %r4,96(%r15) # pointer to struct La_s390_32_regs ++ st %r4,32(%r12) ++ jz 4f # framesize == 0 ? + ahi %r0,7 # align framesize to 8 + lhi %r2,-8 + nr %r0,%r2 +@@ -188,24 +193,35 @@ _dl_runtime_profile: + la %r2,8(%r2) + la %r3,8(%r3) + brct %r0,3b +-4: lm %r2,%r6,32(%r12) # load register parameters ++4: lm %r2,%r6,0(%r4) # load register parameters + basr %r14,%r1 # call resolved function +- stm %r2,%r3,72(%r12) # store return values r2, r3, f0 +- std %f0,80(%r12) # to struct La_s390_32_retval +- lm %r2,%r3,24(%r12) # load arguments saved by PLT ++ stm %r2,%r3,40(%r12) # store return values r2, r3, f0 ++ std %f0,48(%r12) # to struct La_s390_32_retval ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ vst %v24,56(%r12) # store return value v24 ++ .machine pop ++#endif ++ lm %r2,%r4,24(%r12) # r2, r3: load arguments saved by PLT ++ # r4: pointer to struct La_s390_32_regs + basr %r1,0 + 5: l %r14,7f-5b(%r1) +- la %r4,32(%r12) # pointer to struct La_s390_32_regs +- la %r5,72(%r12) # pointer to struct La_s390_32_retval ++ la %r5,40(%r12) # pointer to struct La_s390_32_retval + bas %r14,0(%r14,%r1) # call _dl_call_pltexit + + lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + l %r14,16(%r15) # restore registers + l %r12,12(%r15) +- l %r2,72(%r15) # restore return values +- l %r3,76(%r15) +- ld %f0,80(%r15) ++ lm %r2,%r3,40(%r15) # restore return values ++ ld %f0,48(%r15) ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ vl %v24,56(%r15) # restore return value v24 ++ .machine pop ++#endif + br %r14 + + 6: .long _dl_profile_fixup - 0b +diff --git a/sysdeps/s390/s390-64/dl-trampoline.h b/sysdeps/s390/s390-64/dl-trampoline.h +index 658e3a3..33ea3de 100644 +--- a/sysdeps/s390/s390-64/dl-trampoline.h ++++ b/sysdeps/s390/s390-64/dl-trampoline.h +@@ -109,31 +109,34 @@ _dl_runtime_resolve: + cfi_startproc + .align 16 + _dl_runtime_profile: +- stmg %r2,%r6,64(%r15) # save call-clobbered arg regs +- cfi_offset (r2, -96) # + r6 needed as arg for +- cfi_offset (r3, -88) # _dl_profile_fixup +- cfi_offset (r4, -80) +- cfi_offset (r5, -72) +- cfi_offset (r6, -64) +- std %f0,104(%r15) +- cfi_offset (f0, -56) +- std %f2,112(%r15) +- cfi_offset (f2, -48) +- std %f4,120(%r15) +- cfi_offset (f4, -40) +- std %f6,128(%r15) +- cfi_offset (f6, -32) + stg %r12,24(%r15) # r12 is used as backup of r15 + cfi_offset (r12, -136) + stg %r14,32(%r15) + cfi_offset (r14, -128) + lgr %r12,%r15 # backup stack pointer + cfi_def_cfa_register (12) ++ aghi %r15,-360 # create stack frame: ++ # 160 + sizeof(La_s390_64_regs) ++ stg %r12,0(%r15) # save backchain ++ ++ stmg %r2,%r6,160(%r15) # save call-clobbered arg regs ++ cfi_offset (r2, -360) # + r6 needed as arg for ++ cfi_offset (r3, -352) # _dl_profile_fixup ++ cfi_offset (r4, -344) ++ cfi_offset (r5, -336) ++ cfi_offset (r6, -328) ++ std %f0,200(%r15) ++ cfi_offset (f0, -320) ++ std %f2,208(%r15) ++ cfi_offset (f2, -312) ++ std %f4,216(%r15) ++ cfi_offset (f4, -304) ++ std %f6,224(%r15) ++ cfi_offset (f6, -296) + #ifdef RESTORE_VRS +- aghi %r15,-288 # create stack frame + .machine push + .machine "z13" +- vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers ++ vstm %v24,%v31,232(%r15) # store call-clobbered vector arguments + cfi_offset (v24, -288) + cfi_offset (v25, -272) + cfi_offset (v26, -256) +@@ -143,31 +146,28 @@ _dl_runtime_profile: + cfi_offset (v30, -192) + cfi_offset (v31, -176) + .machine pop +-#else +- aghi %r15,-160 # create stack frame + #endif +- stg %r12,0(%r15) # save backchain + lmg %r2,%r3,48(%r12) # load arguments saved by PLT + lgr %r4,%r14 # return address as third parameter +- la %r5,64(%r12) # pointer to struct La_s390_64_regs ++ la %r5,160(%r15) # pointer to struct La_s390_64_regs + la %r6,40(%r12) # long int * framesize + brasl %r14,_dl_profile_fixup # call resolver + lgr %r1,%r2 # function addr returned in r2 +- ld %f0,104(%r12) # restore call-clobbered arg fprs +- ld %f2,112(%r12) +- ld %f4,120(%r12) +- ld %f6,128(%r12) ++ ld %f0,200(%r15) # restore call-clobbered arg fprs ++ ld %f2,208(%r15) ++ ld %f4,216(%r15) ++ ld %f6,224(%r15) + #ifdef RESTORE_VRS + .machine push + .machine "z13" +- vlm %v24,%v31,160(%r15) # restore call-clobbered arg vrs ++ vlm %v24,%v31,232(%r15) # restore call-clobbered arg vrs + .machine pop + #endif + lg %r0,40(%r12) # load framesize + ltgr %r0,%r0 + jnm 1f + +- lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call ++ lmg %r2,%r6,160(%r15) # framesize < 0 means no pltexit call + # so we can do a tail call without + # copying the arg overflow area + lgr %r15,%r12 # remove stack frame +@@ -177,7 +177,9 @@ _dl_runtime_profile: + br %r1 # tail-call to resolved function + + cfi_def_cfa_register (12) +-1: jz 4f # framesize == 0 ? ++1: la %r4,160(%r15) # pointer to struct La_s390_64_regs ++ stg %r4,64(%r12) ++ jz 4f # framesize == 0 ? + aghi %r0,7 # align framesize to 8 + nill %r0,0xfff8 + slgr %r15,%r0 # make room for framesize bytes +@@ -189,21 +191,33 @@ _dl_runtime_profile: + la %r2,8(%r2) # depending on framesize + la %r3,8(%r3) + brctg %r0,3b +-4: lmg %r2,%r6,64(%r12) # restore call-clobbered arg gprs ++4: lmg %r2,%r6,0(%r4) # restore call-clobbered arg gprs + basr %r14,%r1 # call resolved function +- stg %r2,136(%r12) # store return values r2, f0 +- std %f0,144(%r12) # to struct La_s390_64_retval +- lmg %r2,%r3,48(%r12) # load arguments saved by PLT +- la %r4,64(%r12) # pointer to struct La_s390_64_regs +- la %r5,136(%r12) # pointer to struct La_s390_64_retval ++ stg %r2,72(%r12) # store return values r2, f0 ++ std %f0,80(%r12) # to struct La_s390_64_retval ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ vst %v24,88(%r12) # store return value v24 ++ .machine pop ++#endif ++ lmg %r2,%r4,48(%r12) # r2, r3: load arguments saved by PLT ++ # r4: pointer to struct La_s390_64_regs ++ la %r5,72(%r12) # pointer to struct La_s390_64_retval + brasl %r14,_dl_call_pltexit + + lgr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) +- lg %r2,136(%r15) # restore return values +- ld %f0,144(%r15) ++ lg %r2,72(%r15) # restore return values ++ ld %f0,80(%r15) ++#ifdef RESTORE_VRS ++ .machine push ++ .machine "z13" ++ vl %v24,88(%r15) # restore return value v24 ++ .machine pop ++#endif + br %r14 # Jump back to caller + + cfi_endproc diff --git a/SOURCES/glibc-rh1324427-3.patch b/SOURCES/glibc-rh1324427-3.patch new file mode 100644 index 00000000..47dd3949 --- /dev/null +++ b/SOURCES/glibc-rh1324427-3.patch @@ -0,0 +1,28 @@ +commit d8a012c5c9e4bfc1b8db2bc6deacb85b44a2e1eb +Author: Stefan Liebler +Date: Fri Apr 1 10:42:54 2016 +0200 + + S390: Use ahi instead of aghi in 32bit _dl_runtime_resolve. + + This patch uses ahi instead of aghi in 32bit _dl_runtime_resolve + to adjust the stack pointer. This is no functional change, + but a cosmetic one. + + ChangeLog: + + * sysdeps/s390/s390-32/dl-trampoline.h (_dl_runtime_resolve): + Use ahi instead of aghi to adjust stack pointer. + +diff --git a/sysdeps/s390/s390-32/dl-trampoline.h b/sysdeps/s390/s390-32/dl-trampoline.h +index bb74d27..086449f 100644 +--- a/sysdeps/s390/s390-32/dl-trampoline.h ++++ b/sysdeps/s390/s390-32/dl-trampoline.h +@@ -90,7 +90,7 @@ _dl_runtime_resolve: + .machinemode "zarch_nohighgprs" + vlm %v24,%v31,96(%r15) # restore vector registers + .machine pop +- aghi %r15,224 # remove stack frame ++ ahi %r15,224 # remove stack frame + cfi_adjust_cfa_offset (-224) + #else + ahi %r15,96 # remove stack frame diff --git a/SOURCES/glibc-rh1324568.patch b/SOURCES/glibc-rh1324568.patch new file mode 100644 index 00000000..1f1eaa20 --- /dev/null +++ b/SOURCES/glibc-rh1324568.patch @@ -0,0 +1,54 @@ +Upstream commits: + +commit a071766ebfd853179ac39f9773f894029bf86d36 +Author: Andreas Schwab +Date: Thu Mar 20 15:05:25 2014 +0100 + + Fix use of half-initialized result in getaddrinfo when using nscd (bug 16743) + + This fixes a bug in the way the results from __nscd_getai are collected: + for every returned result a new entry is first added to the + gaih_addrtuple list, but if that result doesn't match the request this + entry remains uninitialized. So for this non-matching result an extra + result with uninitialized content is returned. + + To reproduce (with nscd running): + + $ getent ahostsv4 localhost + 127.0.0.1 STREAM localhost + 127.0.0.1 DGRAM + 127.0.0.1 RAW + (null) STREAM + (null) DGRAM + (null) RAW + +commit 8dc9751764eb1bedf06d19695524b31a16773413 +Author: Andreas Schwab +Date: Wed May 7 11:47:20 2014 +0200 + + Fix parsing of getai result from nscd for IPv6-only request + + +Index: b/sysdeps/posix/getaddrinfo.c +=================================================================== +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -725,6 +725,18 @@ gaih_inet (const char *name, const struc + { + socklen_t size = (air->family[i] == AF_INET + ? INADDRSZ : IN6ADDRSZ); ++ ++ if (!((air->family[i] == AF_INET ++ && req->ai_family == AF_INET6 ++ && (req->ai_flags & AI_V4MAPPED) != 0) ++ || req->ai_family == AF_UNSPEC ++ || air->family[i] == req->ai_family)) ++ { ++ /* Skip over non-matching result. */ ++ addrs += size; ++ continue; ++ } ++ + if (*pat == NULL) + { + *pat = addrfree++; diff --git a/SOURCES/glibc-rh1325138.patch b/SOURCES/glibc-rh1325138.patch new file mode 100644 index 00000000..0d20c144 --- /dev/null +++ b/SOURCES/glibc-rh1325138.patch @@ -0,0 +1,19 @@ +commit 6a1cf708dd5681b517744d6d4fac02e4e4a0aa2e +Author: Aurelien Jarno +Date: Wed Mar 11 21:03:50 2015 -0400 + + Fix ldconfig segmentation fault with corrupted cache (Bug 18093). + +--- glibc-2.17-c758a686/elf/cache.c ++++ glibc-2.17-c758a686/elf/cache.c +@@ -688,7 +688,9 @@ + if (aux_cache == MAP_FAILED + || aux_cache_size < sizeof (struct aux_cache_file) + || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1) +- || aux_cache->nlibs >= aux_cache_size) ++ || aux_cache_size != (sizeof(struct aux_cache_file) + ++ aux_cache->nlibs * sizeof(struct aux_cache_file_entry) + ++ aux_cache->len_strings)) + { + close (fd); + init_aux_cache (); diff --git a/SOURCES/glibc-rh1326739.patch b/SOURCES/glibc-rh1326739.patch new file mode 100644 index 00000000..32d2aec4 --- /dev/null +++ b/SOURCES/glibc-rh1326739.patch @@ -0,0 +1,28 @@ +commit 52ffbdf25a1100986f4ae27bb0febbe5a722ab25 +Author: Florian Weimer +Date: Wed Sep 10 20:29:15 2014 +0200 + + malloc: additional unlink hardening for non-small bins [BZ #17344] + + Turn two asserts into a conditional call to malloc_printerr. The + memory locations are accessed later anyway, so the performance + impact is minor. + +Index: b/malloc/malloc.c +=================================================================== +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -1441,8 +1441,11 @@ typedef struct malloc_chunk* mbinptr; + BK->fd = FD; \ + if (!in_smallbin_range (P->size) \ + && __builtin_expect (P->fd_nextsize != NULL, 0)) { \ +- assert (P->fd_nextsize->bk_nextsize == P); \ +- assert (P->bk_nextsize->fd_nextsize == P); \ ++ if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0) \ ++ || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)) \ ++ malloc_printerr (check_action, \ ++ "corrupted double-linked list (not small)", P,\ ++ AV); \ + if (FD->fd_nextsize == NULL) { \ + if (P->fd_nextsize == P) \ + FD->fd_nextsize = FD->bk_nextsize = FD; \ diff --git a/SOURCES/glibc-rh1330705-1.patch b/SOURCES/glibc-rh1330705-1.patch new file mode 100644 index 00000000..63a6c745 --- /dev/null +++ b/SOURCES/glibc-rh1330705-1.patch @@ -0,0 +1,64 @@ +commit ffdd31816a67f48697ea4d6b852e58d2886d42ca +Author: Andreas Schwab +Date: Wed Sep 11 11:15:45 2013 +0200 + + Add O_TMPFILE to + +diff --git a/ports/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h b/ports/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h +index 2e31691..02c9a7f 100644 +--- a/ports/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h ++++ b/ports/sysdeps/unix/sysv/linux/alpha/bits/fcntl.h +@@ -36,6 +36,7 @@ + #define __O_DIRECT 02000000 /* Direct disk access. */ + #define __O_NOATIME 04000000 /* Do not set atime. */ + #define __O_PATH 040000000 /* Resolve pathname but do not open file. */ ++#define __O_TMPFILE 0100100000 /* Atomically create nameless file. */ + + /* Not necessary, files are always with 64bit off_t. */ + #define __O_LARGEFILE 0 +diff --git a/ports/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h b/ports/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h +index 744548a..76faa40 100644 +--- a/ports/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h ++++ b/ports/sysdeps/unix/sysv/linux/hppa/bits/fcntl.h +@@ -37,6 +37,7 @@ + #define __O_CLOEXEC 010000000 /* Set close_on_exec. */ + #define __O_NOATIME 004000000 /* Do not set atime. */ + #define __O_PATH 020000000 ++#define __O_TMPFILE 040010000 /* Atomically create nameless file. */ + + #define __O_LARGEFILE 00004000 + +diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +index b5929bd..9b0421e 100644 +--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h ++++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +@@ -96,6 +96,9 @@ + #ifndef __O_DSYNC + # define __O_DSYNC 010000 + #endif ++#ifndef __O_TMPFILE ++# define __O_TMPFILE 020200000 ++#endif + + #ifndef F_GETLK + # ifndef __USE_FILE_OFFSET64 +@@ -128,6 +131,7 @@ + # define O_DIRECT __O_DIRECT /* Direct disk access. */ + # define O_NOATIME __O_NOATIME /* Do not set atime. */ + # define O_PATH __O_PATH /* Resolve pathname but do not open file. */ ++# define O_TMPFILE __O_TMPFILE /* Atomically create nameless file. */ + #endif + + /* For now, Linux has no separate synchronicitiy options for read +diff --git a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h +index 01084bb..f384bc7 100644 +--- a/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h ++++ b/sysdeps/unix/sysv/linux/sparc/bits/fcntl.h +@@ -39,6 +39,7 @@ + #define __O_DIRECT 0x100000 /* direct disk access hint */ + #define __O_NOATIME 0x200000 /* Do not set atime. */ + #define __O_PATH 0x1000000 /* Resolve pathname but do not open file. */ ++#define __O_TMPFILE 0x2010000 /* Atomically create nameless file. */ + + #if __WORDSIZE == 64 + # define __O_LARGEFILE 0 diff --git a/SOURCES/glibc-rh1330705-2.patch b/SOURCES/glibc-rh1330705-2.patch new file mode 100644 index 00000000..9e4b9974 --- /dev/null +++ b/SOURCES/glibc-rh1330705-2.patch @@ -0,0 +1,19 @@ +commit 59b61c82fe18e612058302e4c726385c4eb301d8 +Author: Andreas Schwab +Date: Sun Feb 1 14:04:15 2015 +0100 + + Fix value of O_TMPFILE for architectures with non-default O_DIRECTORY (bug 17912) + +diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +index 3d28c84..d2baeb3 100644 +--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h ++++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +@@ -97,7 +97,7 @@ + # define __O_DSYNC 010000 + #endif + #ifndef __O_TMPFILE +-# define __O_TMPFILE 020200000 ++# define __O_TMPFILE (020000000 | __O_DIRECTORY) + #endif + + #ifndef F_GETLK diff --git a/SOURCES/glibc-rh1330705-3.patch b/SOURCES/glibc-rh1330705-3.patch new file mode 100644 index 00000000..e412f7c7 --- /dev/null +++ b/SOURCES/glibc-rh1330705-3.patch @@ -0,0 +1,457 @@ +commit cc0e6ed81fa3ab0eeecfc576098b4522f0323c4b +Author: Roland McGrath +Date: Fri May 3 16:33:26 2013 -0700 + + Consolidate definitions of _FORTIFY_SOURCE wrappers for open{,64}{,at}. + +Index: b/io/Makefile +=================================================================== +--- a/io/Makefile ++++ b/io/Makefile +@@ -36,10 +36,10 @@ routines := \ + statvfs fstatvfs statvfs64 fstatvfs64 \ + umask chmod fchmod lchmod fchmodat \ + mkdir mkdirat \ +- open open64 openat openat64 close \ ++ open open_2 open64 open64_2 openat openat_2 openat64 openat64_2 \ + read write lseek lseek64 access euidaccess faccessat \ + fcntl flock lockf lockf64 \ +- dup dup2 dup3 pipe pipe2 \ ++ close dup dup2 dup3 pipe pipe2 \ + creat creat64 \ + chdir fchdir \ + getcwd getwd getdirname \ +Index: b/io/open.c +=================================================================== +--- a/io/open.c ++++ b/io/open.c +@@ -22,7 +22,6 @@ + #include + #include + +-extern char **__libc_argv attribute_hidden; + + /* Open FILE with access OFLAG. If OFLAG includes O_CREAT, + a third argument is the file protection. */ +@@ -57,15 +56,6 @@ weak_alias (__libc_open, open) + + stub_warning (open) + +- +-int +-__open_2 (file, oflag) +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open call: O_CREAT without mode"); +- +- return __open (file, oflag); +-} ++/* __open_2 is a generic wrapper that calls __open. ++ So give a stub warning for that symbol too. */ + stub_warning (__open_2) +Index: b/io/open64.c +=================================================================== +--- a/io/open64.c ++++ b/io/open64.c +@@ -54,15 +54,6 @@ weak_alias (__libc_open64, open64) + + stub_warning (open64) + +- +-int +-__open64_2 (file, oflag) +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open64 call: O_CREAT without mode"); +- +- return __open64 (file, oflag); +-} ++/* __open64_2 is a generic wrapper that calls __open64. ++ So give a stub warning for that symbol too. */ + stub_warning (__open64_2) +Index: b/io/open64_2.c +=================================================================== +--- /dev/null ++++ b/io/open64_2.c +@@ -0,0 +1,29 @@ ++/* _FORTIFY_SOURCE wrapper for open64. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++__open64_2 (const char *file, int oflag) ++{ ++ if (oflag & O_CREAT) ++ __fortify_fail ("invalid open64 call: O_CREAT without mode"); ++ ++ return __open64 (file, oflag); ++} +Index: b/io/open_2.c +=================================================================== +--- /dev/null ++++ b/io/open_2.c +@@ -0,0 +1,29 @@ ++/* _FORTIFY_SOURCE wrapper for open. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++__open_2 (const char *file, int oflag) ++{ ++ if (oflag & O_CREAT) ++ __fortify_fail ("invalid open call: O_CREAT without mode"); ++ ++ return __open (file, oflag); ++} +Index: b/io/openat.c +=================================================================== +--- a/io/openat.c ++++ b/io/openat.c +@@ -75,16 +75,6 @@ libc_hidden_def (__openat) + weak_alias (__openat, openat) + stub_warning (openat) + +- +-int +-__openat_2 (fd, file, oflag) +- int fd; +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid openat call: O_CREAT without mode"); +- +- return __openat (fd, file, oflag); +-} ++/* __openat_2 is a generic wrapper that calls __openat. ++ So give a stub warning for that symbol too. */ + stub_warning (__openat_2) +Index: b/io/openat64.c +=================================================================== +--- a/io/openat64.c ++++ b/io/openat64.c +@@ -68,16 +68,6 @@ libc_hidden_def (__openat64) + weak_alias (__openat64, openat64) + stub_warning (openat64) + +- +-int +-__openat64_2 (fd, file, oflag) +- int fd; +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid openat64 call: O_CREAT without mode"); +- +- return __openat64 (fd, file, oflag); +-} ++/* __openat64_2 is a generic wrapper that calls __openat64. ++ So give a stub warning for that symbol too. */ + stub_warning (__openat_2) +Index: b/io/openat64_2.c +=================================================================== +--- /dev/null ++++ b/io/openat64_2.c +@@ -0,0 +1,29 @@ ++/* _FORTIFY_SOURCE wrapper for openat64. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++__openat64_2 (int fd, const char *file, int oflag) ++{ ++ if (oflag & O_CREAT) ++ __fortify_fail ("invalid openat64 call: O_CREAT without mode"); ++ ++ return __openat64 (fd, file, oflag); ++} +Index: b/io/openat_2.c +=================================================================== +--- /dev/null ++++ b/io/openat_2.c +@@ -0,0 +1,29 @@ ++/* _FORTIFY_SOURCE wrapper for openat. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++int ++__openat_2 (int fd, const char *file, int oflag) ++{ ++ if (oflag & O_CREAT) ++ __fortify_fail ("invalid openat call: O_CREAT without mode"); ++ ++ return __openat (fd, file, oflag); ++} +Index: b/sysdeps/mach/hurd/open.c +=================================================================== +--- a/sysdeps/mach/hurd/open.c ++++ b/sysdeps/mach/hurd/open.c +@@ -52,20 +52,9 @@ weak_alias (__libc_open, __open) + libc_hidden_weak (__open) + weak_alias (__libc_open, open) + +-int +-__open_2 (file, oflag) +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open call: O_CREAT without mode"); +- +- return __open (file, oflag); +-} + + /* open64 is just the same as open for us. */ + weak_alias (__libc_open, __libc_open64) + weak_alias (__libc_open, __open64) + libc_hidden_weak (_open64) + weak_alias (__libc_open, open64) +-strong_alias (__open_2, __open64_2) +Index: b/sysdeps/mach/hurd/openat.c +=================================================================== +--- a/sysdeps/mach/hurd/openat.c ++++ b/sysdeps/mach/hurd/openat.c +@@ -56,20 +56,7 @@ __openat (fd, file, oflag) + libc_hidden_def (__openat) + weak_alias (__openat, openat) + +-int +-__openat_2 (fd, file, oflag) +- int fd; +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid openat call: O_CREAT without mode"); +- +- return __openat (fd, file, oflag); +-} +- + /* openat64 is just the same as openat for us. */ + weak_alias (__openat, __openat64) + libc_hidden_weak (__openat64) + weak_alias (__openat, openat64) +-strong_alias (__openat_2, __openat64_2) +Index: b/sysdeps/unix/sysv/linux/Makefile +=================================================================== +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -158,7 +158,7 @@ endif + + ifeq ($(subdir),io) + sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ +- sync_file_range open_2 open64_2 fallocate fallocate64 ++ sync_file_range fallocate fallocate64 + sysdep_headers += bits/fcntl-linux.h + endif + +Index: b/sysdeps/unix/sysv/linux/open64_2.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/open64_2.c ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* Copyright (C) 2007 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- +-int +-__open64_2 (file, oflag) +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open64 call: O_CREAT without mode"); +- +- return __open64 (file, oflag); +-} +Index: b/sysdeps/unix/sysv/linux/open_2.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/open_2.c ++++ /dev/null +@@ -1,31 +0,0 @@ +-/* Copyright (C) 2007 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- +-int +-__open_2 (file, oflag) +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open call: O_CREAT without mode"); +- +- return __open (file, oflag); +-} +Index: b/sysdeps/unix/sysv/linux/openat.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/openat.c ++++ b/sysdeps/unix/sysv/linux/openat.c +@@ -29,7 +29,6 @@ + + #ifndef OPENAT + # define OPENAT openat +-# define __OPENAT_2 __openat_2 + + # ifndef __ASSUME_ATFCTS + /* Set errno after a failed call. If BUF is not null, +@@ -179,18 +178,3 @@ __OPENAT (fd, file, oflag) + } + libc_hidden_def (__OPENAT) + weak_alias (__OPENAT, OPENAT) +- +- +-int +-__OPENAT_2 (fd, file, oflag) +- int fd; +- const char *file; +- int oflag; +-{ +- if (oflag & O_CREAT) +-#define MSG(s) MSG2 (s) +-#define MSG2(s) "invalid " #s " call: O_CREAT without mode" +- __fortify_fail (MSG (OPENAT)); +- +- return __OPENAT (fd, file, oflag); +-} +Index: b/sysdeps/unix/sysv/linux/openat64.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/openat64.c ++++ b/sysdeps/unix/sysv/linux/openat64.c +@@ -1,5 +1,4 @@ + #define OPENAT openat64 +-#define __OPENAT_2 __openat64_2 + #define MORE_OFLAGS O_LARGEFILE + + #include "openat.c" +Index: b/sysdeps/unix/sysv/linux/wordsize-64/openat.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/wordsize-64/openat.c ++++ b/sysdeps/unix/sysv/linux/wordsize-64/openat.c +@@ -1,16 +1,14 @@ + #define __openat64 __rename___openat64 +-#define __openat64_2 __rename___openat64_2 + #define __openat64_nocancel __rename___openat64_nocancel + #define openat64 __rename_openat64 + + #include "../openat.c" + + #undef __openat64 +-#undef __openat64_2 + #undef __openat64_nocancel + #undef openat64 + +-weak_alias (__openat, __openat64) +-weak_alias (__openat_2, __openat64_2) +-weak_alias (__openat_nocancel, __openat64_nocancel) ++strong_alias (__openat, __openat64) ++hidden_ver (__openat, __openat64) ++strong_alias (__openat_nocancel, __openat64_nocancel) + weak_alias (openat, openat64) diff --git a/SOURCES/glibc-rh1330705-4.patch b/SOURCES/glibc-rh1330705-4.patch new file mode 100644 index 00000000..7f883536 --- /dev/null +++ b/SOURCES/glibc-rh1330705-4.patch @@ -0,0 +1,462 @@ +Adjusted for the lack of the ports move. + +commit 65f6f938cd562a614a68e15d0581a34b177ec29d +Author: Eric Rannaud +Date: Tue Feb 24 13:12:26 2015 +0530 + + linux: open and openat ignore 'mode' with O_TMPFILE in flags + + Both open and openat load their last argument 'mode' lazily, using + va_arg() only if O_CREAT is found in oflag. This is wrong, mode is also + necessary if O_TMPFILE is in oflag. + + By chance on x86_64, the problem wasn't evident when using O_TMPFILE + with open, as the 3rd argument of open, even when not loaded with + va_arg, is left untouched in RDX, where the syscall expects it. + + However, openat was not so lucky, and O_TMPFILE couldn't be used: mode + is the 4th argument, in RCX, but the syscall expects its 4th argument in + a different register than the glibc wrapper, in R10. + + Introduce a macro __OPEN_NEEDS_MODE (oflag) to test if either O_CREAT or + O_TMPFILE is set in oflag. + +Index: b/io/bits/fcntl2.h +=================================================================== +--- a/io/bits/fcntl2.h ++++ b/io/bits/fcntl2.h +@@ -20,7 +20,7 @@ + # error "Never include directly; use instead." + #endif + +-/* Check that calls to open and openat with O_CREAT set have an ++/* Check that calls to open and openat with O_CREAT or O_TMPFILE set have an + appropriate third/fourth parameter. */ + #ifndef __USE_FILE_OFFSET64 + extern int __open_2 (const char *__path, int __oflag) __nonnull ((1)); +@@ -35,7 +35,7 @@ extern int __REDIRECT (__open_alias, (co + __errordecl (__open_too_many_args, + "open can be called either with 2 or 3 arguments, not more"); + __errordecl (__open_missing_mode, +- "open with O_CREAT in second argument needs 3 arguments"); ++ "open with O_CREAT or O_TMPFILE in second argument needs 3 arguments"); + + __fortify_function int + open (const char *__path, int __oflag, ...) +@@ -45,7 +45,7 @@ open (const char *__path, int __oflag, . + + if (__builtin_constant_p (__oflag)) + { +- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1) ++ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1) + { + __open_missing_mode (); + return __open_2 (__path, __oflag); +@@ -67,7 +67,7 @@ extern int __REDIRECT (__open64_alias, ( + __errordecl (__open64_too_many_args, + "open64 can be called either with 2 or 3 arguments, not more"); + __errordecl (__open64_missing_mode, +- "open64 with O_CREAT in second argument needs 3 arguments"); ++ "open64 with O_CREAT or O_TMPFILE in second argument needs 3 arguments"); + + __fortify_function int + open64 (const char *__path, int __oflag, ...) +@@ -77,7 +77,7 @@ open64 (const char *__path, int __oflag, + + if (__builtin_constant_p (__oflag)) + { +- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1) ++ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1) + { + __open64_missing_mode (); + return __open64_2 (__path, __oflag); +@@ -111,7 +111,7 @@ extern int __REDIRECT (__openat_alias, ( + __errordecl (__openat_too_many_args, + "openat can be called either with 3 or 4 arguments, not more"); + __errordecl (__openat_missing_mode, +- "openat with O_CREAT in third argument needs 4 arguments"); ++ "openat with O_CREAT or O_TMPFILE in third argument needs 4 arguments"); + + __fortify_function int + openat (int __fd, const char *__path, int __oflag, ...) +@@ -121,7 +121,7 @@ openat (int __fd, const char *__path, in + + if (__builtin_constant_p (__oflag)) + { +- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1) ++ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1) + { + __openat_missing_mode (); + return __openat_2 (__fd, __path, __oflag); +@@ -145,7 +145,7 @@ extern int __REDIRECT (__openat64_alias, + __errordecl (__openat64_too_many_args, + "openat64 can be called either with 3 or 4 arguments, not more"); + __errordecl (__openat64_missing_mode, +- "openat64 with O_CREAT in third argument needs 4 arguments"); ++ "openat64 with O_CREAT or O_TMPFILE in third argument needs 4 arguments"); + + __fortify_function int + openat64 (int __fd, const char *__path, int __oflag, ...) +@@ -155,7 +155,7 @@ openat64 (int __fd, const char *__path, + + if (__builtin_constant_p (__oflag)) + { +- if ((__oflag & O_CREAT) != 0 && __va_arg_pack_len () < 1) ++ if (__OPEN_NEEDS_MODE (__oflag) && __va_arg_pack_len () < 1) + { + __openat64_missing_mode (); + return __openat64_2 (__fd, __path, __oflag); +Index: b/io/fcntl.h +=================================================================== +--- a/io/fcntl.h ++++ b/io/fcntl.h +@@ -34,6 +34,15 @@ __BEGIN_DECLS + numbers and flag bits for `open', `fcntl', et al. */ + #include + ++/* Detect if open needs mode as a third argument (or for openat as a fourth ++ argument). */ ++#ifdef __O_TMPFILE ++# define __OPEN_NEEDS_MODE(oflag) \ ++ (((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE) ++#else ++# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0) ++#endif ++ + /* POSIX.1-2001 specifies that these types are defined by . + Earlier POSIX standards permitted any type ending in `_t' to be defined + by any POSIX header, so we don't conditionalize the definitions here. */ +@@ -154,8 +163,9 @@ typedef __pid_t pid_t; + extern int fcntl (int __fd, int __cmd, ...); + + /* Open FILE and return a new file descriptor for it, or -1 on error. +- OFLAG determines the type of access used. If O_CREAT is on OFLAG, +- the third argument is taken as a `mode_t', the mode of the created file. ++ OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set ++ in OFLAG, the third argument is taken as a `mode_t', the mode of the ++ created file. + + This function is a cancellation point and therefore not marked with + __THROW. */ +Index: b/io/open.c +=================================================================== +--- a/io/open.c ++++ b/io/open.c +@@ -23,7 +23,7 @@ + #include + + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open (file, oflag) +@@ -38,7 +38,7 @@ __libc_open (file, oflag) + return -1; + } + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start(arg, oflag); +Index: b/io/open64.c +=================================================================== +--- a/io/open64.c ++++ b/io/open64.c +@@ -22,7 +22,7 @@ + #include + #include + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open64 (file, oflag) +@@ -37,7 +37,7 @@ __libc_open64 (file, oflag) + return -1; + } + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/io/open64_2.c +=================================================================== +--- a/io/open64_2.c ++++ b/io/open64_2.c +@@ -22,8 +22,8 @@ + int + __open64_2 (const char *file, int oflag) + { +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open64 call: O_CREAT without mode"); ++ if (__OPEN_NEEDS_MODE (oflag)) ++ __fortify_fail ("invalid open64 call: O_CREAT or O_TMPFILE without mode"); + + return __open64 (file, oflag); + } +Index: b/io/open_2.c +=================================================================== +--- a/io/open_2.c ++++ b/io/open_2.c +@@ -22,8 +22,8 @@ + int + __open_2 (const char *file, int oflag) + { +- if (oflag & O_CREAT) +- __fortify_fail ("invalid open call: O_CREAT without mode"); ++ if (__OPEN_NEEDS_MODE (oflag)) ++ __fortify_fail ("invalid open call: O_CREAT or O_TMPFILE without mode"); + + return __open (file, oflag); + } +Index: b/io/openat.c +=================================================================== +--- a/io/openat.c ++++ b/io/openat.c +@@ -30,7 +30,7 @@ int __have_atfcts; + #endif + + /* Open FILE with access OFLAG. Interpret relative paths relative to +- the directory associated with FD. If OFLAG includes O_CREAT, a ++ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a + third argument is the file protection. */ + int + __openat (fd, file, oflag) +@@ -60,7 +60,7 @@ __openat (fd, file, oflag) + } + } + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/io/openat64.c +=================================================================== +--- a/io/openat64.c ++++ b/io/openat64.c +@@ -23,7 +23,7 @@ + #include + + /* Open FILE with access OFLAG. Interpret relative paths relative to +- the directory associated with FD. If OFLAG includes O_CREAT, a ++ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a + third argument is the file protection. */ + int + __openat64 (fd, file, oflag) +@@ -53,7 +53,7 @@ __openat64 (fd, file, oflag) + } + } + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/io/openat64_2.c +=================================================================== +--- a/io/openat64_2.c ++++ b/io/openat64_2.c +@@ -22,8 +22,8 @@ + int + __openat64_2 (int fd, const char *file, int oflag) + { +- if (oflag & O_CREAT) +- __fortify_fail ("invalid openat64 call: O_CREAT without mode"); ++ if (__OPEN_NEEDS_MODE (oflag)) ++ __fortify_fail ("invalid openat64 call: O_CREAT or O_TMPFILE without mode"); + + return __openat64 (fd, file, oflag); + } +Index: b/io/openat_2.c +=================================================================== +--- a/io/openat_2.c ++++ b/io/openat_2.c +@@ -22,8 +22,8 @@ + int + __openat_2 (int fd, const char *file, int oflag) + { +- if (oflag & O_CREAT) +- __fortify_fail ("invalid openat call: O_CREAT without mode"); ++ if (__OPEN_NEEDS_MODE (oflag)) ++ __fortify_fail ("invalid openat call: O_CREAT or O_TMPFILE without mode"); + + return __openat (fd, file, oflag); + } +Index: b/sysdeps/mach/hurd/open.c +=================================================================== +--- a/sysdeps/mach/hurd/open.c ++++ b/sysdeps/mach/hurd/open.c +@@ -22,7 +22,7 @@ + #include + #include + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open (const char *file, int oflag, ...) +@@ -30,7 +30,7 @@ __libc_open (const char *file, int oflag + mode_t mode; + io_t port; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/sysdeps/mach/hurd/openat.c +=================================================================== +--- a/sysdeps/mach/hurd/openat.c ++++ b/sysdeps/mach/hurd/openat.c +@@ -26,7 +26,7 @@ + #include + + /* Open FILE with access OFLAG. Interpret relative paths relative to +- the directory associated with FD. If OFLAG includes O_CREAT, a ++ the directory associated with FD. If O_CREAT or O_TMPFILE is in OFLAG, a + third argument is the file protection. */ + int + __openat (fd, file, oflag) +@@ -37,7 +37,7 @@ __openat (fd, file, oflag) + mode_t mode; + io_t port; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/sysdeps/posix/open64.c +=================================================================== +--- a/sysdeps/posix/open64.c ++++ b/sysdeps/posix/open64.c +@@ -20,14 +20,14 @@ + #include + #include + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open64 (const char *file, int oflag, ...) + { + int mode = 0; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/sysdeps/unix/sysv/linux/dl-openat64.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/dl-openat64.c ++++ b/sysdeps/unix/sysv/linux/dl-openat64.c +@@ -28,7 +28,7 @@ openat64 (dfd, file, oflag) + const char *file; + int oflag; + { +- assert ((oflag & O_CREAT) == 0); ++ assert (!__OPEN_NEEDS_MODE (oflag)); + + #ifdef __NR_openat + return INLINE_SYSCALL (openat, 3, dfd, file, oflag | O_LARGEFILE); +Index: b/ports/sysdeps/unix/sysv/linux/generic/open.c +=================================================================== +--- a/ports/sysdeps/unix/sysv/linux/generic/open.c ++++ b/ports/sysdeps/unix/sysv/linux/generic/open.c +@@ -22,14 +22,14 @@ + #include + #include + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open (const char *file, int oflag, ...) + { + int mode = 0; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +@@ -59,7 +59,7 @@ __open_nocancel (const char *file, int o + { + int mode = 0; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/ports/sysdeps/unix/sysv/linux/generic/open64.c +=================================================================== +--- a/ports/sysdeps/unix/sysv/linux/generic/open64.c ++++ b/ports/sysdeps/unix/sysv/linux/generic/open64.c +@@ -22,14 +22,14 @@ + #include + #include + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open64 (const char *file, int oflag, ...) + { + int mode = 0; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/sysdeps/unix/sysv/linux/open64.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/open64.c ++++ b/sysdeps/unix/sysv/linux/open64.c +@@ -22,14 +22,14 @@ + #include + #include + +-/* Open FILE with access OFLAG. If OFLAG includes O_CREAT, ++/* Open FILE with access OFLAG. If O_CREAT or O_TMPFILE is in OFLAG, + a third argument is the file protection. */ + int + __libc_open64 (const char *file, int oflag, ...) + { + int mode = 0; + +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); +Index: b/sysdeps/unix/sysv/linux/openat.c +=================================================================== +--- a/sysdeps/unix/sysv/linux/openat.c ++++ b/sysdeps/unix/sysv/linux/openat.c +@@ -148,8 +148,8 @@ OPENAT_NOT_CANCEL (fd, file, oflag, mode + + + /* Open FILE with access OFLAG. Interpret relative paths relative to +- the directory associated with FD. If OFLAG includes O_CREAT, a +- third argument is the file protection. */ ++ the directory associated with FD. If OFLAG includes O_CREAT or ++ O_TMPFILE, a fourth argument is the file protection. */ + int + __OPENAT (fd, file, oflag) + int fd; +@@ -157,7 +157,7 @@ __OPENAT (fd, file, oflag) + int oflag; + { + mode_t mode = 0; +- if (oflag & O_CREAT) ++ if (__OPEN_NEEDS_MODE (oflag)) + { + va_list arg; + va_start (arg, oflag); diff --git a/SOURCES/glibc-rh1330705-5.patch b/SOURCES/glibc-rh1330705-5.patch new file mode 100644 index 00000000..437c68c1 --- /dev/null +++ b/SOURCES/glibc-rh1330705-5.patch @@ -0,0 +1,385 @@ +commit 85f7554cd97e7f03d8dc66278653045ef63a2221 +Author: Florian Weimer +Date: Wed Sep 21 15:24:01 2016 +0200 + + Add test case for O_TMPFILE handling in open, openat + + Also put xasprintf into test-skeleton.c (written in such a way that + including is not needed). + +commit 51364ff23e9760777bfea4eb9ac89c29a794074b +Author: Florian Weimer +Date: Fri Sep 23 09:41:35 2016 +0200 + + test-skeleton.c: Remove unintended #include . + +Index: b/io/tst-open-tmpfile.c +=================================================================== +--- /dev/null ++++ b/io/tst-open-tmpfile.c +@@ -0,0 +1,319 @@ ++/* Test open and openat with O_TMPFILE. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test verifies that open and openat work as expected, i.e. they ++ create a deleted file with the requested file mode. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int do_test (void); ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++#ifdef O_TMPFILE ++typedef int (*wrapper_func) (const char *, int, mode_t); ++ ++/* Error-checking wrapper for the open function, compatible with the ++ wrapper_func type. */ ++static int ++wrap_open (const char *path, int flags, mode_t mode) ++{ ++ int ret = open (path, flags, mode); ++ if (ret < 0) ++ { ++ printf ("error: open (\"%s\", 0x%x, 0%03o): %m\n", path, flags, mode); ++ exit (1); ++ } ++ return ret; ++} ++ ++/* Error-checking wrapper for the openat function, compatible with the ++ wrapper_func type. */ ++static int ++wrap_openat (const char *path, int flags, mode_t mode) ++{ ++ int ret = openat (AT_FDCWD, path, flags, mode); ++ if (ret < 0) ++ { ++ printf ("error: openat (\"%s\", 0x%x, 0%03o): %m\n", path, flags, mode); ++ exit (1); ++ } ++ return ret; ++} ++ ++/* Error-checking wrapper for the open64 function, compatible with the ++ wrapper_func type. */ ++static int ++wrap_open64 (const char *path, int flags, mode_t mode) ++{ ++ int ret = open64 (path, flags, mode); ++ if (ret < 0) ++ { ++ printf ("error: open64 (\"%s\", 0x%x, 0%03o): %m\n", path, flags, mode); ++ exit (1); ++ } ++ return ret; ++} ++ ++/* Error-checking wrapper for the openat64 function, compatible with the ++ wrapper_func type. */ ++static int ++wrap_openat64 (const char *path, int flags, mode_t mode) ++{ ++ int ret = openat64 (AT_FDCWD, path, flags, mode); ++ if (ret < 0) ++ { ++ printf ("error: openat64 (\"%s\", 0x%x, 0%03o): %m\n", path, flags, mode); ++ exit (1); ++ } ++ return ret; ++} ++ ++/* Return true if FD is flagged as deleted in /proc/self/fd, false if ++ not. */ ++static bool ++is_file_deteted (int fd) ++{ ++ char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd); ++ char file_path[4096]; ++ ssize_t file_path_length ++ = readlink (proc_fd_path, file_path, sizeof (file_path)); ++ if (file_path_length < 0) ++ { ++ printf ("error: readlink (\"%s\"): %m", proc_fd_path); ++ free (proc_fd_path); ++ exit (1); ++ } ++ free (proc_fd_path); ++ if (file_path_length == sizeof (file_path)) ++ { ++ printf ("error: path in /proc resolves to overlong file name: %.*s\n", ++ (int) file_path_length, file_path); ++ exit (1); ++ } ++ const char *deleted = " (deleted)"; ++ if (file_path_length < strlen (deleted)) ++ { ++ printf ("error: path in /proc is too short: %.*s\n", ++ (int) file_path_length, file_path); ++ exit (1); ++ } ++ return memcmp (file_path + file_path_length - strlen (deleted), ++ deleted, strlen (deleted)) == 0; ++} ++ ++/* Obtain a file name which is difficult to guess. */ ++static char * ++get_random_name (void) ++{ ++ unsigned long long bytes[2]; ++ int random_device = open ("/dev/urandom", O_RDONLY); ++ if (random_device < 0) ++ { ++ printf ("error: open (\"/dev/urandom\"): %m\n"); ++ exit (1); ++ } ++ ssize_t ret = read (random_device, bytes, sizeof (bytes)); ++ if (ret < 0) ++ { ++ printf ("error: read (\"/dev/urandom\"): %m\n"); ++ exit (1); ++ } ++ if (ret != sizeof (bytes)) ++ { ++ printf ("error: short read from /dev/urandom: %zd\n", ret); ++ exit (1); ++ } ++ close (random_device); ++ return xasprintf ("tst-open-tmpfile-%08llx%08llx.tmp", bytes[0], bytes[1]); ++} ++ ++/* Check open/openat (as specified by OP and WRAPPER) with a specific ++ PATH/FLAGS/MODE combination. */ ++static void ++check_wrapper_flags_mode (const char *op, wrapper_func wrapper, ++ const char *path, int flags, mode_t mode) ++{ ++ int fd = wrapper (path, flags | O_TMPFILE, mode); ++ struct stat64 st; ++ if (fstat64 (fd, &st) != 0) ++ { ++ printf ("error: fstat64: %m\n"); ++ exit (1); ++ } ++ ++ /* Verify that the mode was correctly processed. */ ++ int actual_mode = st.st_mode & 0777; ++ if (actual_mode != mode) ++ { ++ printf ("error: unexpected mode; expected 0%03o, actual 0%03o\n", ++ mode, actual_mode); ++ exit (1); ++ } ++ ++ /* Check that the file is marked as deleted in /proc. */ ++ if (!is_file_deteted (fd)) ++ { ++ printf ("error: path in /proc is not marked as deleted\n"); ++ exit (1); ++ } ++ ++ /* Check that the file can be turned into a regular file with ++ linkat. Open a file descriptor for the directory at PATH. Use ++ AT_FDCWD if PATH is ".", to exercise that functionality as ++ well. */ ++ int path_fd; ++ if (strcmp (path, ".") == 0) ++ path_fd = AT_FDCWD; ++ else ++ { ++ path_fd = open (path, O_RDONLY | O_DIRECTORY); ++ if (path_fd < 0) ++ { ++ printf ("error: open (\"%s\"): %m\n", path); ++ exit (1); ++ } ++ } ++ ++ /* Use a hard-to-guess name for the new directory entry. */ ++ char *new_name = get_random_name (); ++ ++ /* linkat does not require privileges if the path in /proc/self/fd ++ is used. */ ++ char *proc_fd_path = xasprintf ("/proc/self/fd/%d", fd); ++ if (linkat (AT_FDCWD, proc_fd_path, path_fd, new_name, ++ AT_SYMLINK_FOLLOW) == 0) ++ { ++ if (unlinkat (path_fd, new_name, 0) != 0 && errno != ENOENT) ++ { ++ printf ("error: unlinkat (\"%s/%s\"): %m\n", path, new_name); ++ exit (1); ++ } ++ } ++ else ++ { ++ /* linkat failed. This is expected if O_EXCL was specified. */ ++ if ((flags & O_EXCL) == 0) ++ { ++ printf ("error: linkat failed after %s (\"%s\", 0x%x, 0%03o): %m\n", ++ op, path, flags, mode); ++ exit (1); ++ } ++ } ++ ++ free (proc_fd_path); ++ free (new_name); ++ if (path_fd != AT_FDCWD) ++ close (path_fd); ++ close (fd); ++} ++ ++/* Check OP/WRAPPER with various flags at a specific PATH and ++ MODE. */ ++static void ++check_wrapper_mode (const char *op, wrapper_func wrapper, ++ const char *path, mode_t mode) ++{ ++ check_wrapper_flags_mode (op, wrapper, path, O_WRONLY, mode); ++ check_wrapper_flags_mode (op, wrapper, path, O_WRONLY | O_EXCL, mode); ++ check_wrapper_flags_mode (op, wrapper, path, O_RDWR, mode); ++ check_wrapper_flags_mode (op, wrapper, path, O_RDWR | O_EXCL, mode); ++} ++ ++/* Check open/openat with varying permissions. */ ++static void ++check_wrapper (const char *op, wrapper_func wrapper, ++ const char *path) ++{ ++ printf ("info: testing %s at: %s\n", op, path); ++ check_wrapper_mode (op, wrapper, path, 0); ++ check_wrapper_mode (op, wrapper, path, 0640); ++ check_wrapper_mode (op, wrapper, path, 0600); ++ check_wrapper_mode (op, wrapper, path, 0755); ++ check_wrapper_mode (op, wrapper, path, 0750); ++} ++ ++/* Verify that the directory at PATH supports O_TMPFILE. Exit with ++ status 77 (unsupported) if the kernel does not support O_TMPFILE. ++ Even with kernel support, not all file systems O_TMPFILE, so return ++ true if the directory supports O_TMPFILE, false if not. */ ++static bool ++probe_path (const char *path) ++{ ++ int fd = openat (AT_FDCWD, path, O_TMPFILE | O_RDWR, 0); ++ if (fd < 0) ++ { ++ if (errno == EISDIR) ++ /* The system does not support O_TMPFILE. */ ++ { ++ printf ("info: kernel does not support O_TMPFILE\n"); ++ exit (77); ++ } ++ if (errno == EOPNOTSUPP) ++ { ++ printf ("info: path does not support O_TMPFILE: %s\n", path); ++ return false; ++ } ++ printf ("error: openat (\"%s\", O_TMPFILE | O_RDWR): %m\n", path); ++ exit (1); ++ } ++ close (fd); ++ return true; ++} ++ ++static int ++do_test (void) ++{ ++ umask (0); ++ const char *paths[] = { ".", "/dev/shm", "/tmp", ++ getenv ("TEST_TMPFILE_PATH"), ++ NULL }; ++ bool supported = false; ++ for (int i = 0; paths[i] != NULL; ++i) ++ if (probe_path (paths[i])) ++ { ++ supported = true; ++ check_wrapper ("open", wrap_open, paths[i]); ++ check_wrapper ("openat", wrap_openat, paths[i]); ++ check_wrapper ("open64", wrap_open64, paths[i]); ++ check_wrapper ("openat64", wrap_openat64, paths[i]); ++ } ++ ++ if (!supported) ++ return 77; ++ ++ return 0; ++} ++ ++#else /* !O_TMPFILE */ ++ ++static int ++do_test (void) ++{ ++ return 77; ++} ++ ++#endif /* O_TMPFILE */ +Index: b/test-skeleton.c +=================================================================== +--- a/test-skeleton.c ++++ b/test-skeleton.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + /* The test function is normally called `do_test' and it is called + with argc and argv as the arguments. We nevertheless provide the +@@ -63,6 +64,20 @@ static pid_t pid; + /* Directory to place temporary files in. */ + static const char *test_dir; + ++/* Call asprintf with error checking. */ ++__attribute__ ((always_inline, format (printf, 1, 2))) ++static __inline__ char * ++xasprintf (const char *format, ...) ++{ ++ char *result; ++ if (asprintf (&result, format, __builtin_va_arg_pack ()) < 0) ++ { ++ printf ("error: asprintf: %m\n"); ++ exit (1); ++ } ++ return result; ++} ++ + /* List of temporary files. */ + struct temp_name_list + { +Index: b/io/Makefile +=================================================================== +--- a/io/Makefile ++++ b/io/Makefile +@@ -69,7 +69,8 @@ tests := test-utime test-stat test-stat + tst-renameat tst-fchownat tst-fchmodat tst-faccessat \ + tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \ + tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \ +- tst-posix_fallocate ++ tst-posix_fallocate \ ++ tst-open-tmpfile + + include ../Rules diff --git a/SOURCES/glibc-rh1330705-6.patch b/SOURCES/glibc-rh1330705-6.patch new file mode 100644 index 00000000..ada33284 --- /dev/null +++ b/SOURCES/glibc-rh1330705-6.patch @@ -0,0 +1,94 @@ +Do not expose O_TMPFILE in a public header. + +Adjust tst-open-tmpfile so that it exits with 0 in case of missing +kernel support. + +Index: b/io/tst-open-tmpfile.c +=================================================================== +--- a/io/tst-open-tmpfile.c ++++ b/io/tst-open-tmpfile.c +@@ -33,7 +33,6 @@ static int do_test (void); + #define TEST_FUNCTION do_test () + #include "../test-skeleton.c" + +-#ifdef O_TMPFILE + typedef int (*wrapper_func) (const char *, int, mode_t); + + /* Error-checking wrapper for the open function, compatible with the +@@ -157,7 +156,7 @@ static void + check_wrapper_flags_mode (const char *op, wrapper_func wrapper, + const char *path, int flags, mode_t mode) + { +- int fd = wrapper (path, flags | O_TMPFILE, mode); ++ int fd = wrapper (path, flags | __O_TMPFILE, mode); + struct stat64 st; + if (fstat64 (fd, &st) != 0) + { +@@ -257,20 +256,20 @@ check_wrapper (const char *op, wrapper_f + } + + /* Verify that the directory at PATH supports O_TMPFILE. Exit with +- status 77 (unsupported) if the kernel does not support O_TMPFILE. +- Even with kernel support, not all file systems O_TMPFILE, so return +- true if the directory supports O_TMPFILE, false if not. */ ++ status 0 if the kernel does not support O_TMPFILE. Even with ++ kernel support, not all file systems O_TMPFILE, so return true if ++ the directory supports O_TMPFILE, false if not. */ + static bool + probe_path (const char *path) + { +- int fd = openat (AT_FDCWD, path, O_TMPFILE | O_RDWR, 0); ++ int fd = openat (AT_FDCWD, path, __O_TMPFILE | O_RDWR, 0); + if (fd < 0) + { + if (errno == EISDIR) + /* The system does not support O_TMPFILE. */ + { + printf ("info: kernel does not support O_TMPFILE\n"); +- exit (77); ++ exit (0); + } + if (errno == EOPNOTSUPP) + { +@@ -291,29 +290,14 @@ do_test (void) + const char *paths[] = { ".", "/dev/shm", "/tmp", + getenv ("TEST_TMPFILE_PATH"), + NULL }; +- bool supported = false; + for (int i = 0; paths[i] != NULL; ++i) + if (probe_path (paths[i])) + { +- supported = true; + check_wrapper ("open", wrap_open, paths[i]); + check_wrapper ("openat", wrap_openat, paths[i]); + check_wrapper ("open64", wrap_open64, paths[i]); + check_wrapper ("openat64", wrap_openat64, paths[i]); + } + +- if (!supported) +- return 77; +- + return 0; + } +- +-#else /* !O_TMPFILE */ +- +-static int +-do_test (void) +-{ +- return 77; +-} +- +-#endif /* O_TMPFILE */ +Index: b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +=================================================================== +--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h ++++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h +@@ -131,7 +131,6 @@ + # define O_DIRECT __O_DIRECT /* Direct disk access. */ + # define O_NOATIME __O_NOATIME /* Do not set atime. */ + # define O_PATH __O_PATH /* Resolve pathname but do not open file. */ +-# define O_TMPFILE __O_TMPFILE /* Atomically create nameless file. */ + #endif + + /* For now, Linux has no separate synchronicitiy options for read diff --git a/SOURCES/glibc-rh1331283-1.patch b/SOURCES/glibc-rh1331283-1.patch new file mode 100644 index 00000000..ed464e24 --- /dev/null +++ b/SOURCES/glibc-rh1331283-1.patch @@ -0,0 +1,34 @@ +commit 3bfff2edbef578746211ba231f3942efffd38f86 +Author: Carlos O'Donell +Date: Thu Feb 6 11:12:48 2014 -0500 + + BZ #16529: Fix pedantic warning with netinet/in.h. + + When compiling with pedantic the following warning is seen: + + gcc -Wall -pedantic -O0 -o test test.c + In file included from test.c:3:0: + /path/inet/netinet/in.h:111:21: warning: comma at end of \ + enumerator list [-Wpedantic] + IPPROTO_MH = 135, /* IPv6 mobility header. */ + ^ + + It is valid C99 to have a trailing comma after the last item in + an enumeration. However it is not valid C90. If possible glibc + attempts to keep all headers C90 + long long without requiring + C99 features. In this case it's easy to fix the headers and it + removes the warning seem with -pedantic. + +diff --git a/inet/netinet/in.h b/inet/netinet/in.h +index ad9ce6c..d8d8e53 100644 +--- a/inet/netinet/in.h ++++ b/inet/netinet/in.h +@@ -108,7 +108,7 @@ enum + #define IPPROTO_NONE IPPROTO_NONE + IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ + #define IPPROTO_DSTOPTS IPPROTO_DSTOPTS +- IPPROTO_MH = 135, /* IPv6 mobility header. */ ++ IPPROTO_MH = 135 /* IPv6 mobility header. */ + #define IPPROTO_MH IPPROTO_MH + }; + #endif /* !__USE_KERNEL_IPV6_DEFS */ diff --git a/SOURCES/glibc-rh1331283-2.patch b/SOURCES/glibc-rh1331283-2.patch new file mode 100644 index 00000000..6216b5a9 --- /dev/null +++ b/SOURCES/glibc-rh1331283-2.patch @@ -0,0 +1,52 @@ +commit cb43bb0d68f001fc3d6e054d712ab8794b5fd1de +Author: Cong Wang +Date: Tue Jan 6 16:13:19 2015 -0800 + + in.h: Coordinate in6_pktinfo and ip6_mtuinfo for kernel and glibc [BZ #15850] + + Similarly to what we did for in6_addr, we need a macro + to guard in6_pktinfo and ip6_mtuinfo too. + + Cc: Carlos O'Donell + Signed-off-by: Cong Wang + +diff --git a/inet/netinet/in.h b/inet/netinet/in.h +index bf3c8b1..f541c58 100644 +--- a/inet/netinet/in.h ++++ b/inet/netinet/in.h +@@ -530,6 +530,7 @@ extern int bindresvport6 (int __sockfd, struct sockaddr_in6 *__sock_in) + #ifdef __USE_GNU + struct cmsghdr; /* Forward declaration. */ + ++#ifndef __USE_KERNEL_IPV6_DEFS + /* IPv6 packet information. */ + struct in6_pktinfo + { +@@ -543,7 +544,7 @@ struct ip6_mtuinfo + struct sockaddr_in6 ip6m_addr; /* dst address including zone ID */ + uint32_t ip6m_mtu; /* path MTU in host byte order */ + }; +- ++#endif /* !__USE_KERNEL_IPV6_DEFS */ + + /* Obsolete hop-by-hop and Destination Options Processing (RFC 2292). */ + extern int inet6_option_space (int __nbytes) +diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h +index b80a27f..b1d2cf6 100644 +--- a/sysdeps/unix/sysv/linux/bits/in.h ++++ b/sysdeps/unix/sysv/linux/bits/in.h +@@ -23,10 +23,10 @@ + + /* If the application has already included linux/in6.h from a linux-based + kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the +- defines), sockaddr_in6, or ipv6_mreq. The ABI used by the linux-kernel and +- glibc match exactly. Neither the linux kernel nor glibc should break this +- ABI without coordination. */ +-#ifdef _UAPI_LINUX_IN6_H ++ defines), sockaddr_in6, or ipv6_mreq. Same for in6_ptkinfo or ip6_mtuinfo ++ in linux/ipv6.h. The ABI used by the linux-kernel and glibc match exactly. ++ Neither the linux kernel nor glibc should break this ABI without coordination. */ ++#if defined _UAPI_LINUX_IN6_H || defined _UAPI_IPV6_H + /* This is not quite the same API since the kernel always defines s6_addr16 and + s6_addr32. This is not a violation of POSIX since POSIX says "at least the + following member" and that holds true. */ diff --git a/SOURCES/glibc-rh1331283-3.patch b/SOURCES/glibc-rh1331283-3.patch new file mode 100644 index 00000000..1e383cd7 --- /dev/null +++ b/SOURCES/glibc-rh1331283-3.patch @@ -0,0 +1,89 @@ +commit 1c1e7fb65828c99d6e0f0f3857089b559a0c8189 +Author: Carlos O'Donell +Date: Thu Jun 2 23:30:11 2016 -0400 + + Fix macro API for __USE_KERNEL_IPV6_DEFS. + + The use of __USE_KERNEL_IPV6_DEFS with ifndef is bad + practice per: https://sourceware.org/glibc/wiki/Wundef. + This change moves it to use 'if' and always define the + macro. + + Please note that this is not the only problem with this + code. I have a series of fixes after this one to resolve + breakage with this code and add regression tests for it + via compile-only source testing (to be discussed in another + thread). + + Unfortunately __USE_KERNEL_XATTR_DEFS is set by the kernel + and not glibc, and uses 'define', so we can't fix that yet. + +Index: glibc-2.17-c758a686/inet/netinet/in.h +=================================================================== +--- glibc-2.17-c758a686.orig/inet/netinet/in.h ++++ glibc-2.17-c758a686/inet/netinet/in.h +@@ -91,10 +91,10 @@ enum + IPPROTO_MAX + }; + +-/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel ++/* If __USE_KERNEL_IPV6_DEFS is 1 then the user has included the kernel + network headers first and we should use those ABI-identical definitions +- instead of our own. */ +-#ifndef __USE_KERNEL_IPV6_DEFS ++ instead of our own, otherwise 0. */ ++#if !__USE_KERNEL_IPV6_DEFS + enum + { + IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ +@@ -205,7 +205,7 @@ enum + #define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) /* 224.0.0.2 */ + #define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */ + +-#ifndef __USE_KERNEL_IPV6_DEFS ++#if !__USE_KERNEL_IPV6_DEFS + /* IPv6 address */ + struct in6_addr + { +@@ -248,7 +248,7 @@ struct sockaddr_in + sizeof (struct in_addr)]; + }; + +-#ifndef __USE_KERNEL_IPV6_DEFS ++#if !__USE_KERNEL_IPV6_DEFS + /* Ditto, for IPv6. */ + struct sockaddr_in6 + { +@@ -284,7 +284,7 @@ struct ip_mreq_source + }; + #endif + +-#ifndef __USE_KERNEL_IPV6_DEFS ++#if !__USE_KERNEL_IPV6_DEFS + /* Likewise, for IPv6. */ + struct ipv6_mreq + { +@@ -531,7 +531,7 @@ extern int bindresvport6 (int __sockfd, + #ifdef __USE_GNU + struct cmsghdr; /* Forward declaration. */ + +-#ifndef __USE_KERNEL_IPV6_DEFS ++#if !__USE_KERNEL_IPV6_DEFS + /* IPv6 packet information. */ + struct in6_pktinfo + { +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/bits/in.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/bits/in.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/bits/in.h +@@ -30,7 +30,9 @@ + /* This is not quite the same API since the kernel always defines s6_addr16 and + s6_addr32. This is not a violation of POSIX since POSIX says "at least the + following member" and that holds true. */ +-# define __USE_KERNEL_IPV6_DEFS ++# define __USE_KERNEL_IPV6_DEFS 1 ++#else ++# define __USE_KERNEL_IPV6_DEFS 0 + #endif + + /* Options for use with `getsockopt' and `setsockopt' at the IP level. diff --git a/SOURCES/glibc-rh1331283-4.patch b/SOURCES/glibc-rh1331283-4.patch new file mode 100644 index 00000000..56320c78 --- /dev/null +++ b/SOURCES/glibc-rh1331283-4.patch @@ -0,0 +1,61 @@ +commit c9bd40daaee18cf1d9824e4a7ebaebe321e0a5a8 +Author: Carlos O'Donell +Date: Tue Jun 7 04:46:37 2016 -0400 + + Bug 20214: Fix linux/in6.h and netinet/in.h sync. + + In: https://sourceware.org/glibc/wiki/Synchronizing_Headers + we explain how we synchronize our headers with Linux kernel + headers. + + In order to synchronize with the Linux linux/in6.h and + linux/ipv6.h headers we checked for their guard macros and + then defined __USE_KERNEL_IPV6_DEFS and conditionalized code + on this macro. + + In upstream kernel 56c176c9 the _UAPI prefix was stripped and + this broke our synchronized headers again. We now need to check + for _LINUX_IN6_H and _IPV6_H, and keep checking the old versions + of the header guard checks for maximum backwards compatibility + with older Linux headers (the history is actually a bit muddled + here and it appears upstream linus kernel broke this 10 months + *before* our fix was ever applied to glibc, but without glibc + testing we didn't notice and distro kernels have their own + testing to fix this). + + This patch fixes synchronization with linux/in6.h and + with netinet/in.h. + +diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h +index 9bdadf3..4d70a6b 100644 +--- a/sysdeps/unix/sysv/linux/bits/in.h ++++ b/sysdeps/unix/sysv/linux/bits/in.h +@@ -25,8 +25,14 @@ + kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the + defines), sockaddr_in6, or ipv6_mreq. Same for in6_ptkinfo or ip6_mtuinfo + in linux/ipv6.h. The ABI used by the linux-kernel and glibc match exactly. +- Neither the linux kernel nor glibc should break this ABI without coordination. */ +-#if defined _UAPI_LINUX_IN6_H || defined _UAPI_IPV6_H ++ Neither the linux kernel nor glibc should break this ABI without coordination. ++ In upstream kernel 56c176c9 the _UAPI prefix was stripped so we need to check ++ for _LINUX_IN6_H and _IPV6_H now, and keep checking the old versions for ++ maximum backwards compatibility. */ ++#if defined _UAPI_LINUX_IN6_H \ ++ || defined _UAPI_IPV6_H \ ++ || defined _LINUX_IN6_H \ ++ || defined _IPV6_H + /* This is not quite the same API since the kernel always defines s6_addr16 and + s6_addr32. This is not a violation of POSIX since POSIX says "at least the + following member" and that holds true. */ +@@ -209,8 +215,10 @@ struct in_pktinfo + #define IPV6_TCLASS 67 + + /* Obsolete synonyms for the above. */ +-#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +-#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP ++#if !__USE_KERNEL_IPV6_DEFS ++# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP ++# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP ++#endif + #define IPV6_RXHOPOPTS IPV6_HOPOPTS + #define IPV6_RXDSTOPTS IPV6_DSTOPTS diff --git a/SOURCES/glibc-rh1331283.patch b/SOURCES/glibc-rh1331283.patch new file mode 100644 index 00000000..df20886a --- /dev/null +++ b/SOURCES/glibc-rh1331283.patch @@ -0,0 +1,201 @@ +commit 6c82a2f8d7c8e21e39237225c819f182ae438db3 +Author: Carlos O'Donell +Date: Fri Sep 6 01:02:30 2013 -0400 + + Coordinate IPv6 definitions for Linux and glibc + + This change synchronizes the glibc headers with the Linux kernel + headers and arranges to coordinate the definition of structures + already defined the Linux kernel UAPI headers. + + It is now safe to include glibc's netinet/in.h or Linux's linux/in6.h + in any order in a userspace application and you will get the same + ABI. The ABI is guaranteed by UAPI and glibc. + +diff --git a/inet/netinet/in.h b/inet/netinet/in.h +index 89e3813..05c77e2 100644 +--- a/inet/netinet/in.h ++++ b/inet/netinet/in.h +@@ -26,13 +26,21 @@ + + __BEGIN_DECLS + ++/* Internet address. */ ++typedef uint32_t in_addr_t; ++struct in_addr ++ { ++ in_addr_t s_addr; ++ }; ++ ++/* Get system-specific definitions. */ ++#include ++ + /* Standard well-defined IP protocols. */ + enum + { + IPPROTO_IP = 0, /* Dummy protocol for TCP. */ + #define IPPROTO_IP IPPROTO_IP +- IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ +-#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS + IPPROTO_ICMP = 1, /* Internet Control Message Protocol. */ + #define IPPROTO_ICMP IPPROTO_ICMP + IPPROTO_IGMP = 2, /* Internet Group Management Protocol. */ +@@ -55,10 +63,6 @@ enum + #define IPPROTO_DCCP IPPROTO_DCCP + IPPROTO_IPV6 = 41, /* IPv6 header. */ + #define IPPROTO_IPV6 IPPROTO_IPV6 +- IPPROTO_ROUTING = 43, /* IPv6 routing header. */ +-#define IPPROTO_ROUTING IPPROTO_ROUTING +- IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ +-#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT + IPPROTO_RSVP = 46, /* Reservation Protocol. */ + #define IPPROTO_RSVP IPPROTO_RSVP + IPPROTO_GRE = 47, /* General Routing Encapsulation. */ +@@ -67,14 +71,10 @@ enum + #define IPPROTO_ESP IPPROTO_ESP + IPPROTO_AH = 51, /* authentication header. */ + #define IPPROTO_AH IPPROTO_AH +- IPPROTO_ICMPV6 = 58, /* ICMPv6. */ +-#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 +- IPPROTO_NONE = 59, /* IPv6 no next header. */ +-#define IPPROTO_NONE IPPROTO_NONE +- IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ +-#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS + IPPROTO_MTP = 92, /* Multicast Transport Protocol. */ + #define IPPROTO_MTP IPPROTO_MTP ++ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET. */ ++#define IPPROTO_BEETPH IPPROTO_BEETPH + IPPROTO_ENCAP = 98, /* Encapsulation Header. */ + #define IPPROTO_ENCAP IPPROTO_ENCAP + IPPROTO_PIM = 103, /* Protocol Independent Multicast. */ +@@ -90,6 +90,28 @@ enum + IPPROTO_MAX + }; + ++/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel ++ network headers first and we should use those ABI-identical definitions ++ instead of our own. */ ++#ifndef __USE_KERNEL_IPV6_DEFS ++enum ++ { ++ IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ ++#define IPPROTO_HOPOPTS IPPROTO_HOPOPTS ++ IPPROTO_ROUTING = 43, /* IPv6 routing header. */ ++#define IPPROTO_ROUTING IPPROTO_ROUTING ++ IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header. */ ++#define IPPROTO_FRAGMENT IPPROTO_FRAGMENT ++ IPPROTO_ICMPV6 = 58, /* ICMPv6. */ ++#define IPPROTO_ICMPV6 IPPROTO_ICMPV6 ++ IPPROTO_NONE = 59, /* IPv6 no next header. */ ++#define IPPROTO_NONE IPPROTO_NONE ++ IPPROTO_DSTOPTS = 60, /* IPv6 destination options. */ ++#define IPPROTO_DSTOPTS IPPROTO_DSTOPTS ++ IPPROTO_MH = 135, /* IPv6 mobility header. */ ++#define IPPROTO_MH IPPROTO_MH ++ }; ++#endif /* !__USE_KERNEL_IPV6_DEFS */ + + /* Type to represent a port. */ + typedef uint16_t in_port_t; +@@ -134,15 +156,6 @@ enum + IPPORT_USERRESERVED = 5000 + }; + +- +-/* Internet address. */ +-typedef uint32_t in_addr_t; +-struct in_addr +- { +- in_addr_t s_addr; +- }; +- +- + /* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to +@@ -191,7 +204,7 @@ struct in_addr + #define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) /* 224.0.0.2 */ + #define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */ + +- ++#ifndef __USE_KERNEL_IPV6_DEFS + /* IPv6 address */ + struct in6_addr + { +@@ -209,6 +222,7 @@ struct in6_addr + # define s6_addr32 __in6_u.__u6_addr32 + #endif + }; ++#endif /* !__USE_KERNEL_IPV6_DEFS */ + + extern const struct in6_addr in6addr_any; /* :: */ + extern const struct in6_addr in6addr_loopback; /* ::1 */ +@@ -233,6 +247,7 @@ struct sockaddr_in + sizeof (struct in_addr)]; + }; + ++#ifndef __USE_KERNEL_IPV6_DEFS + /* Ditto, for IPv6. */ + struct sockaddr_in6 + { +@@ -242,7 +257,7 @@ struct sockaddr_in6 + struct in6_addr sin6_addr; /* IPv6 address */ + uint32_t sin6_scope_id; /* IPv6 scope-id */ + }; +- ++#endif /* !__USE_KERNEL_IPV6_DEFS */ + + #if defined __USE_MISC || defined __USE_GNU + /* IPv4 multicast request. */ +@@ -268,7 +283,7 @@ struct ip_mreq_source + }; + #endif + +- ++#ifndef __USE_KERNEL_IPV6_DEFS + /* Likewise, for IPv6. */ + struct ipv6_mreq + { +@@ -278,7 +293,7 @@ struct ipv6_mreq + /* local interface */ + unsigned int ipv6mr_interface; + }; +- ++#endif /* !__USE_KERNEL_IPV6_DEFS */ + + #if defined __USE_MISC || defined __USE_GNU + /* Multicast group request. */ +@@ -349,10 +364,6 @@ struct group_filter + * sizeof (struct sockaddr_storage))) + #endif + +- +-/* Get system-specific definitions. */ +-#include +- + /* Functions to convert between host and network byte order. + + Please note that these functions normally take `unsigned long int' or +diff --git a/sysdeps/unix/sysv/linux/bits/in.h b/sysdeps/unix/sysv/linux/bits/in.h +index e959b33..d763ce9 100644 +--- a/sysdeps/unix/sysv/linux/bits/in.h ++++ b/sysdeps/unix/sysv/linux/bits/in.h +@@ -21,6 +21,18 @@ + # error "Never use directly; include instead." + #endif + ++/* If the application has already included linux/in6.h from a linux-based ++ kernel then we will not define the IPv6 IPPROTO_* defines, in6_addr (nor the ++ defines), sockaddr_in6, or ipv6_mreq. The ABI used by the linux-kernel and ++ glibc match exactly. Neither the linux kernel nor glibc should break this ++ ABI without coordination. */ ++#ifdef _UAPI_LINUX_IN6_H ++/* This is not quite the same API since the kernel always defines s6_addr16 and ++ s6_addr32. This is not a violation of POSIX since POSIX says "at least the ++ following member" and that holds true. */ ++# define __USE_KERNEL_IPV6_DEFS ++#endif ++ + /* Options for use with `getsockopt' and `setsockopt' at the IP level. + The first word in the comment at the right is the data type used; + "bool" means a boolean value stored in an `int'. */ diff --git a/SOURCES/glibc-rh1335286-0.patch b/SOURCES/glibc-rh1335286-0.patch new file mode 100644 index 00000000..b9bc3624 --- /dev/null +++ b/SOURCES/glibc-rh1335286-0.patch @@ -0,0 +1,78 @@ +On top of this patch we include a few more redirecting versions of +the rtld-* routines in multiarch, this is needed because of the +sysd-rules which try to build from multiarch first and will even +use memset.S from multiarch to buidl rtld-memset.os, which results +in SSE register usage in rtld which we can't allow because of +lazy binding (though in some cases we use RTLD_PREPARE_FOREIGN_CALL +and others to wrap such calls). + +commit 747ef469ffc9c9179ca9d76854167925b4e44346 +Author: Siddhesh Poyarekar +Date: Sat Jun 15 00:09:26 2013 +0530 + + Add rtld-memset.S for x86_64 + + Resolves: BZ #15627 + + Add an assembler version of rtld-memset to avoid using SSE registers. + +Index: glibc-2.17-c758a686/sysdeps/x86_64/rtld-memset.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/rtld-memset.S +@@ -0,0 +1,37 @@ ++/* memset implementation for the dynamic linker. This is separate from the ++ libc implementation to avoid writing to SSE registers. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include "asm-syntax.h" ++ ++ ++ .text ++/* void *memset (void *dest, char c, size_t count) ++ dest => %rdi ++ c => %rsi ++ count => %rdx */ ++ENTRY (memset) ++ mov %rdx, %rcx ++ movzbl %sil, %eax ++ mov %rdi, %rdx ++ rep stosb ++ mov %rdx, %rax ++ ret ++END (memset) ++libc_hidden_builtin_def (memset) +Index: glibc-2.17-c758a686/sysdeps/x86_64/rtld-memset.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/rtld-memset.c ++++ /dev/null +@@ -1 +0,0 @@ +-#include +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rtld-memset.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rtld-memset.S +@@ -0,0 +1 @@ ++#include "../rtld-memset.S" +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rtld-strchr.S +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/rtld-strchr.S +@@ -0,0 +1 @@ ++#include "../rtld-strchr.S" diff --git a/SOURCES/glibc-rh1335286.patch b/SOURCES/glibc-rh1335286.patch new file mode 100644 index 00000000..1cbb1452 --- /dev/null +++ b/SOURCES/glibc-rh1335286.patch @@ -0,0 +1,1449 @@ +From 143ce75a4203a78d79549b00e570a5bb429c44cf Mon Sep 17 00:00:00 2001 +From: Ondrej Bilka +Date: Mon, 20 May 2013 08:26:00 +0200 +Subject: [PATCH] Faster memset on x64 + +This implementation speed up memset in several ways. First is +avoiding expensive computed jump. Second is using fact that arguments +of memset are most of time aligned to 8 bytes. + +Benchmark results on: + +kam.mff.cuni.cz/~ondra/benchmark_string/memset_profile_result27_04_13.tar.bz2 + +(cherry picked from commit b2b671b677d92429a3d41bf451668f476aa267ed) +--- + sysdeps/x86_64/memset.S | 1406 +++-------------------------------------------- + 1 file changed, 91 insertions(+), 1315 deletions(-) + +Index: glibc-2.17-c758a686/sysdeps/x86_64/memset.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/memset.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/memset.S +@@ -19,17 +19,31 @@ + + #include + +-#define __STOS_LOWER_BOUNDARY $8192 +-#define __STOS_UPPER_BOUNDARY $65536 ++#ifndef ALIGN ++# define ALIGN(n) .p2align n ++#endif + + .text + #if IS_IN (libc) && !defined USE_MULTIARCH + ENTRY(__bzero) +- mov %rsi,%rdx /* Adjust parameter. */ +- xorl %esi,%esi /* Fill with 0s. */ +- jmp L(memset_entry) ++ movq %rdi, %rax /* Set return value. */ ++ movq %rsi, %rdx /* Set n. */ ++ pxor %xmm8, %xmm8 ++ jmp L(entry_from_bzero) + END(__bzero) + weak_alias (__bzero, bzero) ++ ++/* Like memset but takes additional parameter with return value. */ ++ENTRY(__memset_tail) ++ movq %rcx, %rax /* Set return value. */ ++ ++ movd %esi, %xmm8 ++ punpcklbw %xmm8, %xmm8 ++ punpcklwd %xmm8, %xmm8 ++ pshufd $0, %xmm8, %xmm8 ++ ++ jmp L(entry_from_bzero) ++END(__memset_tail) + #endif + + #if defined PIC && IS_IN (libc) +@@ -38,1318 +52,80 @@ ENTRY_CHK (__memset_chk) + jb HIDDEN_JUMPTARGET (__chk_fail) + END_CHK (__memset_chk) + #endif +-ENTRY (memset) +-L(memset_entry): +- cmp $0x1,%rdx +- mov %rdi,%rax /* memset returns the dest address. */ +- jne L(ck2) +- mov %sil,(%rdi) +- retq +-L(ck2): +- mov $0x101010101010101,%r9 +- mov %rdx,%r8 +- movzbq %sil,%rdx +- imul %r9,%rdx +-L(now_dw_aligned): +- cmp $0x90,%r8 +- ja L(ck_mem_ops_method) +-L(now_dw_aligned_small): +- add %r8,%rdi +-#ifndef PIC +- lea L(setPxQx)(%rip),%r11 +- jmpq *(%r11,%r8,8) +-#else +- lea L(Got0)(%rip),%r11 +- lea L(setPxQx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-#endif +- +-L(Got0): +- retq +- +- .pushsection .rodata +- .balign 16 +-#ifndef PIC +-L(setPxQx): +- .quad L(Got0), L(P1Q0), L(P2Q0), L(P3Q0) +- .quad L(P4Q0), L(P5Q0), L(P6Q0), L(P7Q0) +- .quad L(P0Q1), L(P1Q1), L(P2Q1), L(P3Q1) +- .quad L(P4Q1), L(P5Q1), L(P6Q1), L(P7Q1) +- .quad L(P0Q2), L(P1Q2), L(P2Q2), L(P3Q2) +- .quad L(P4Q2), L(P5Q2), L(P6Q2), L(P7Q2) +- .quad L(P0Q3), L(P1Q3), L(P2Q3), L(P3Q3) +- .quad L(P4Q3), L(P5Q3), L(P6Q3), L(P7Q3) +- .quad L(P0Q4), L(P1Q4), L(P2Q4), L(P3Q4) +- .quad L(P4Q4), L(P5Q4), L(P6Q4), L(P7Q4) +- .quad L(P0Q5), L(P1Q5), L(P2Q5), L(P3Q5) +- .quad L(P4Q5), L(P5Q5), L(P6Q5), L(P7Q5) +- .quad L(P0Q6), L(P1Q6), L(P2Q6), L(P3Q6) +- .quad L(P4Q6), L(P5Q6), L(P6Q6), L(P7Q6) +- .quad L(P0Q7), L(P1Q7), L(P2Q7), L(P3Q7) +- .quad L(P4Q7), L(P5Q7), L(P6Q7), L(P7Q7) +- .quad L(P0Q8), L(P1Q8), L(P2Q8), L(P3Q8) +- .quad L(P4Q8), L(P5Q8), L(P6Q8), L(P7Q8) +- .quad L(P0Q9), L(P1Q9), L(P2Q9), L(P3Q9) +- .quad L(P4Q9), L(P5Q9), L(P6Q9), L(P7Q9) +- .quad L(P0QA), L(P1QA), L(P2QA), L(P3QA) +- .quad L(P4QA), L(P5QA), L(P6QA), L(P7QA) +- .quad L(P0QB), L(P1QB), L(P2QB), L(P3QB) +- .quad L(P4QB), L(P5QB), L(P6QB), L(P7QB) +- .quad L(P0QC), L(P1QC), L(P2QC), L(P3QC) +- .quad L(P4QC), L(P5QC), L(P6QC), L(P7QC) +- .quad L(P0QD), L(P1QD), L(P2QD), L(P3QD) +- .quad L(P4QD), L(P5QD), L(P6QD), L(P7QD) +- .quad L(P0QE), L(P1QE), L(P2QE), L(P3QE) +- .quad L(P4QE), L(P5QE), L(P6QE), L(P7QE) +- .quad L(P0QF), L(P1QF), L(P2QF), L(P3QF) +- .quad L(P4QF), L(P5QF), L(P6QF), L(P7QF) +- .quad L(P0QG), L(P1QG), L(P2QG), L(P3QG) +- .quad L(P4QG), L(P5QG), L(P6QG), L(P7QG) +- .quad L(P0QH), L(P1QH), L(P2QH), L(P3QH) +- .quad L(P4QH), L(P5QH), L(P6QH), L(P7QH) +- .quad L(P0QI) +-# ifdef USE_EXTRA_TABLE +- .quad L(P1QI), L(P2QI), L(P3QI), L(P4QI) +- .quad L(P5QI), L(P6QI), L(P7QI) +-# endif +-#else +-L(setPxQx): +- .short L(Got0)-L(Got0) +- .short L(P1Q0)-L(Got0) +- .short L(P2Q0)-L(Got0) +- .short L(P3Q0)-L(Got0) +- .short L(P4Q0)-L(Got0) +- .short L(P5Q0)-L(Got0) +- .short L(P6Q0)-L(Got0) +- .short L(P7Q0)-L(Got0) +- +- .short L(P0Q1)-L(Got0) +- .short L(P1Q1)-L(Got0) +- .short L(P2Q1)-L(Got0) +- .short L(P3Q1)-L(Got0) +- .short L(P4Q1)-L(Got0) +- .short L(P5Q1)-L(Got0) +- .short L(P6Q1)-L(Got0) +- .short L(P7Q1)-L(Got0) +- +- .short L(P0Q2)-L(Got0) +- .short L(P1Q2)-L(Got0) +- .short L(P2Q2)-L(Got0) +- .short L(P3Q2)-L(Got0) +- .short L(P4Q2)-L(Got0) +- .short L(P5Q2)-L(Got0) +- .short L(P6Q2)-L(Got0) +- .short L(P7Q2)-L(Got0) +- +- .short L(P0Q3)-L(Got0) +- .short L(P1Q3)-L(Got0) +- .short L(P2Q3)-L(Got0) +- .short L(P3Q3)-L(Got0) +- .short L(P4Q3)-L(Got0) +- .short L(P5Q3)-L(Got0) +- .short L(P6Q3)-L(Got0) +- .short L(P7Q3)-L(Got0) +- +- .short L(P0Q4)-L(Got0) +- .short L(P1Q4)-L(Got0) +- .short L(P2Q4)-L(Got0) +- .short L(P3Q4)-L(Got0) +- .short L(P4Q4)-L(Got0) +- .short L(P5Q4)-L(Got0) +- .short L(P6Q4)-L(Got0) +- .short L(P7Q4)-L(Got0) +- +- .short L(P0Q5)-L(Got0) +- .short L(P1Q5)-L(Got0) +- .short L(P2Q5)-L(Got0) +- .short L(P3Q5)-L(Got0) +- .short L(P4Q5)-L(Got0) +- .short L(P5Q5)-L(Got0) +- .short L(P6Q5)-L(Got0) +- .short L(P7Q5)-L(Got0) +- +- .short L(P0Q6)-L(Got0) +- .short L(P1Q6)-L(Got0) +- .short L(P2Q6)-L(Got0) +- .short L(P3Q6)-L(Got0) +- .short L(P4Q6)-L(Got0) +- .short L(P5Q6)-L(Got0) +- .short L(P6Q6)-L(Got0) +- .short L(P7Q6)-L(Got0) +- +- .short L(P0Q7)-L(Got0) +- .short L(P1Q7)-L(Got0) +- .short L(P2Q7)-L(Got0) +- .short L(P3Q7)-L(Got0) +- .short L(P4Q7)-L(Got0) +- .short L(P5Q7)-L(Got0) +- .short L(P6Q7)-L(Got0) +- .short L(P7Q7)-L(Got0) +- +- .short L(P0Q8)-L(Got0) +- .short L(P1Q8)-L(Got0) +- .short L(P2Q8)-L(Got0) +- .short L(P3Q8)-L(Got0) +- .short L(P4Q8)-L(Got0) +- .short L(P5Q8)-L(Got0) +- .short L(P6Q8)-L(Got0) +- .short L(P7Q8)-L(Got0) +- +- .short L(P0Q9)-L(Got0) +- .short L(P1Q9)-L(Got0) +- .short L(P2Q9)-L(Got0) +- .short L(P3Q9)-L(Got0) +- .short L(P4Q9)-L(Got0) +- .short L(P5Q9)-L(Got0) +- .short L(P6Q9)-L(Got0) +- .short L(P7Q9)-L(Got0) +- +- .short L(P0QA)-L(Got0) +- .short L(P1QA)-L(Got0) +- .short L(P2QA)-L(Got0) +- .short L(P3QA)-L(Got0) +- .short L(P4QA)-L(Got0) +- .short L(P5QA)-L(Got0) +- .short L(P6QA)-L(Got0) +- .short L(P7QA)-L(Got0) +- +- .short L(P0QB)-L(Got0) +- .short L(P1QB)-L(Got0) +- .short L(P2QB)-L(Got0) +- .short L(P3QB)-L(Got0) +- .short L(P4QB)-L(Got0) +- .short L(P5QB)-L(Got0) +- .short L(P6QB)-L(Got0) +- .short L(P7QB)-L(Got0) +- +- .short L(P0QC)-L(Got0) +- .short L(P1QC)-L(Got0) +- .short L(P2QC)-L(Got0) +- .short L(P3QC)-L(Got0) +- .short L(P4QC)-L(Got0) +- .short L(P5QC)-L(Got0) +- .short L(P6QC)-L(Got0) +- .short L(P7QC)-L(Got0) +- +- .short L(P0QD)-L(Got0) +- .short L(P1QD)-L(Got0) +- .short L(P2QD)-L(Got0) +- .short L(P3QD)-L(Got0) +- .short L(P4QD)-L(Got0) +- .short L(P5QD)-L(Got0) +- .short L(P6QD)-L(Got0) +- .short L(P7QD)-L(Got0) +- +- .short L(P0QE)-L(Got0) +- .short L(P1QE)-L(Got0) +- .short L(P2QE)-L(Got0) +- .short L(P3QE)-L(Got0) +- .short L(P4QE)-L(Got0) +- .short L(P5QE)-L(Got0) +- .short L(P6QE)-L(Got0) +- .short L(P7QE)-L(Got0) +- +- .short L(P0QF)-L(Got0) +- .short L(P1QF)-L(Got0) +- .short L(P2QF)-L(Got0) +- .short L(P3QF)-L(Got0) +- .short L(P4QF)-L(Got0) +- .short L(P5QF)-L(Got0) +- .short L(P6QF)-L(Got0) +- .short L(P7QF)-L(Got0) +- +- .short L(P0QG)-L(Got0) +- .short L(P1QG)-L(Got0) +- .short L(P2QG)-L(Got0) +- .short L(P3QG)-L(Got0) +- .short L(P4QG)-L(Got0) +- .short L(P5QG)-L(Got0) +- .short L(P6QG)-L(Got0) +- .short L(P7QG)-L(Got0) +- +- .short L(P0QH)-L(Got0) +- .short L(P1QH)-L(Got0) +- .short L(P2QH)-L(Got0) +- .short L(P3QH)-L(Got0) +- .short L(P4QH)-L(Got0) +- .short L(P5QH)-L(Got0) +- .short L(P6QH)-L(Got0) +- .short L(P7QH)-L(Got0) +- +- .short L(P0QI)-L(Got0) +-# ifdef USE_EXTRA_TABLE +- .short L(P1QI)-L(Got0) +- .short L(P2QI)-L(Got0) +- .short L(P3QI)-L(Got0) +- .short L(P4QI)-L(Got0) +- .short L(P5QI)-L(Got0) +- .short L(P6QI)-L(Got0) +- .short L(P7QI)-L(Got0) +-# endif +-#endif +- .popsection +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P1QI): mov %rdx,-0x91(%rdi) +-#endif +-L(P1QH): mov %rdx,-0x89(%rdi) +-L(P1QG): mov %rdx,-0x81(%rdi) +-# .balign 16 +-L(P1QF): mov %rdx,-0x79(%rdi) +-L(P1QE): mov %rdx,-0x71(%rdi) +-L(P1QD): mov %rdx,-0x69(%rdi) +-L(P1QC): mov %rdx,-0x61(%rdi) +-L(P1QB): mov %rdx,-0x59(%rdi) +-L(P1QA): mov %rdx,-0x51(%rdi) +-L(P1Q9): mov %rdx,-0x49(%rdi) +-L(P1Q8): mov %rdx,-0x41(%rdi) +-L(P1Q7): mov %rdx,-0x39(%rdi) +-L(P1Q6): mov %rdx,-0x31(%rdi) +-L(P1Q5): mov %rdx,-0x29(%rdi) +-L(P1Q4): mov %rdx,-0x21(%rdi) +-L(P1Q3): mov %rdx,-0x19(%rdi) +-L(P1Q2): mov %rdx,-0x11(%rdi) +-L(P1Q1): mov %rdx,-0x9(%rdi) +-L(P1Q0): mov %dl,-0x1(%rdi) +- retq +- +- .balign 16 +-L(P0QI): mov %rdx,-0x90(%rdi) +-L(P0QH): mov %rdx,-0x88(%rdi) +-# .balign 16 +-L(P0QG): mov %rdx,-0x80(%rdi) +-L(P0QF): mov %rdx,-0x78(%rdi) +-L(P0QE): mov %rdx,-0x70(%rdi) +-L(P0QD): mov %rdx,-0x68(%rdi) +-L(P0QC): mov %rdx,-0x60(%rdi) +-L(P0QB): mov %rdx,-0x58(%rdi) +-L(P0QA): mov %rdx,-0x50(%rdi) +-L(P0Q9): mov %rdx,-0x48(%rdi) +-L(P0Q8): mov %rdx,-0x40(%rdi) +-L(P0Q7): mov %rdx,-0x38(%rdi) +-L(P0Q6): mov %rdx,-0x30(%rdi) +-L(P0Q5): mov %rdx,-0x28(%rdi) +-L(P0Q4): mov %rdx,-0x20(%rdi) +-L(P0Q3): mov %rdx,-0x18(%rdi) +-L(P0Q2): mov %rdx,-0x10(%rdi) +-L(P0Q1): mov %rdx,-0x8(%rdi) +-L(P0Q0): retq +- +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P2QI): mov %rdx,-0x92(%rdi) +-#endif +-L(P2QH): mov %rdx,-0x8a(%rdi) +-L(P2QG): mov %rdx,-0x82(%rdi) +-# .balign 16 +-L(P2QF): mov %rdx,-0x7a(%rdi) +-L(P2QE): mov %rdx,-0x72(%rdi) +-L(P2QD): mov %rdx,-0x6a(%rdi) +-L(P2QC): mov %rdx,-0x62(%rdi) +-L(P2QB): mov %rdx,-0x5a(%rdi) +-L(P2QA): mov %rdx,-0x52(%rdi) +-L(P2Q9): mov %rdx,-0x4a(%rdi) +-L(P2Q8): mov %rdx,-0x42(%rdi) +-L(P2Q7): mov %rdx,-0x3a(%rdi) +-L(P2Q6): mov %rdx,-0x32(%rdi) +-L(P2Q5): mov %rdx,-0x2a(%rdi) +-L(P2Q4): mov %rdx,-0x22(%rdi) +-L(P2Q3): mov %rdx,-0x1a(%rdi) +-L(P2Q2): mov %rdx,-0x12(%rdi) +-L(P2Q1): mov %rdx,-0xa(%rdi) +-L(P2Q0): mov %dx,-0x2(%rdi) +- retq +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P3QI): mov %rdx,-0x93(%rdi) +-#endif +-L(P3QH): mov %rdx,-0x8b(%rdi) +-L(P3QG): mov %rdx,-0x83(%rdi) +-# .balign 16 +-L(P3QF): mov %rdx,-0x7b(%rdi) +-L(P3QE): mov %rdx,-0x73(%rdi) +-L(P3QD): mov %rdx,-0x6b(%rdi) +-L(P3QC): mov %rdx,-0x63(%rdi) +-L(P3QB): mov %rdx,-0x5b(%rdi) +-L(P3QA): mov %rdx,-0x53(%rdi) +-L(P3Q9): mov %rdx,-0x4b(%rdi) +-L(P3Q8): mov %rdx,-0x43(%rdi) +-L(P3Q7): mov %rdx,-0x3b(%rdi) +-L(P3Q6): mov %rdx,-0x33(%rdi) +-L(P3Q5): mov %rdx,-0x2b(%rdi) +-L(P3Q4): mov %rdx,-0x23(%rdi) +-L(P3Q3): mov %rdx,-0x1b(%rdi) +-L(P3Q2): mov %rdx,-0x13(%rdi) +-L(P3Q1): mov %rdx,-0xb(%rdi) +-L(P3Q0): mov %dx,-0x3(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P4QI): mov %rdx,-0x94(%rdi) +-#endif +-L(P4QH): mov %rdx,-0x8c(%rdi) +-L(P4QG): mov %rdx,-0x84(%rdi) +-# .balign 16 +-L(P4QF): mov %rdx,-0x7c(%rdi) +-L(P4QE): mov %rdx,-0x74(%rdi) +-L(P4QD): mov %rdx,-0x6c(%rdi) +-L(P4QC): mov %rdx,-0x64(%rdi) +-L(P4QB): mov %rdx,-0x5c(%rdi) +-L(P4QA): mov %rdx,-0x54(%rdi) +-L(P4Q9): mov %rdx,-0x4c(%rdi) +-L(P4Q8): mov %rdx,-0x44(%rdi) +-L(P4Q7): mov %rdx,-0x3c(%rdi) +-L(P4Q6): mov %rdx,-0x34(%rdi) +-L(P4Q5): mov %rdx,-0x2c(%rdi) +-L(P4Q4): mov %rdx,-0x24(%rdi) +-L(P4Q3): mov %rdx,-0x1c(%rdi) +-L(P4Q2): mov %rdx,-0x14(%rdi) +-L(P4Q1): mov %rdx,-0xc(%rdi) +-L(P4Q0): mov %edx,-0x4(%rdi) +- retq +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P5QI): mov %rdx,-0x95(%rdi) +-#endif +-L(P5QH): mov %rdx,-0x8d(%rdi) +-L(P5QG): mov %rdx,-0x85(%rdi) +-# .balign 16 +-L(P5QF): mov %rdx,-0x7d(%rdi) +-L(P5QE): mov %rdx,-0x75(%rdi) +-L(P5QD): mov %rdx,-0x6d(%rdi) +-L(P5QC): mov %rdx,-0x65(%rdi) +-L(P5QB): mov %rdx,-0x5d(%rdi) +-L(P5QA): mov %rdx,-0x55(%rdi) +-L(P5Q9): mov %rdx,-0x4d(%rdi) +-L(P5Q8): mov %rdx,-0x45(%rdi) +-L(P5Q7): mov %rdx,-0x3d(%rdi) +-L(P5Q6): mov %rdx,-0x35(%rdi) +-L(P5Q5): mov %rdx,-0x2d(%rdi) +-L(P5Q4): mov %rdx,-0x25(%rdi) +-L(P5Q3): mov %rdx,-0x1d(%rdi) +-L(P5Q2): mov %rdx,-0x15(%rdi) +-L(P5Q1): mov %rdx,-0xd(%rdi) +-L(P5Q0): mov %edx,-0x5(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P6QI): mov %rdx,-0x96(%rdi) +-#endif +-L(P6QH): mov %rdx,-0x8e(%rdi) +-L(P6QG): mov %rdx,-0x86(%rdi) +-# .balign 16 +-L(P6QF): mov %rdx,-0x7e(%rdi) +-L(P6QE): mov %rdx,-0x76(%rdi) +-L(P6QD): mov %rdx,-0x6e(%rdi) +-L(P6QC): mov %rdx,-0x66(%rdi) +-L(P6QB): mov %rdx,-0x5e(%rdi) +-L(P6QA): mov %rdx,-0x56(%rdi) +-L(P6Q9): mov %rdx,-0x4e(%rdi) +-L(P6Q8): mov %rdx,-0x46(%rdi) +-L(P6Q7): mov %rdx,-0x3e(%rdi) +-L(P6Q6): mov %rdx,-0x36(%rdi) +-L(P6Q5): mov %rdx,-0x2e(%rdi) +-L(P6Q4): mov %rdx,-0x26(%rdi) +-L(P6Q3): mov %rdx,-0x1e(%rdi) +-L(P6Q2): mov %rdx,-0x16(%rdi) +-L(P6Q1): mov %rdx,-0xe(%rdi) +-L(P6Q0): mov %edx,-0x6(%rdi) +- mov %dx,-0x2(%rdi) +- retq +- +- .balign 16 +-#ifdef USE_EXTRA_TABLE +-L(P7QI): mov %rdx,-0x97(%rdi) +-#endif +-L(P7QH): mov %rdx,-0x8f(%rdi) +-L(P7QG): mov %rdx,-0x87(%rdi) +-# .balign 16 +-L(P7QF): mov %rdx,-0x7f(%rdi) +-L(P7QE): mov %rdx,-0x77(%rdi) +-L(P7QD): mov %rdx,-0x6f(%rdi) +-L(P7QC): mov %rdx,-0x67(%rdi) +-L(P7QB): mov %rdx,-0x5f(%rdi) +-L(P7QA): mov %rdx,-0x57(%rdi) +-L(P7Q9): mov %rdx,-0x4f(%rdi) +-L(P7Q8): mov %rdx,-0x47(%rdi) +-L(P7Q7): mov %rdx,-0x3f(%rdi) +-L(P7Q6): mov %rdx,-0x37(%rdi) +-L(P7Q5): mov %rdx,-0x2f(%rdi) +-L(P7Q4): mov %rdx,-0x27(%rdi) +-L(P7Q3): mov %rdx,-0x1f(%rdi) +-L(P7Q2): mov %rdx,-0x17(%rdi) +-L(P7Q1): mov %rdx,-0xf(%rdi) +-L(P7Q0): mov %edx,-0x7(%rdi) +- mov %dx,-0x3(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +- .balign 16 +-L(ck_mem_ops_method): +- +-# align to 16 byte boundary first +- #test $0xf,%rdi +- #jz L(aligned_now) +- mov $0x10,%r10 +- mov %rdi,%r9 +- and $0xf,%r9 +- sub %r9,%r10 +- and $0xf,%r10 +- add %r10,%rdi +- sub %r10,%r8 +-#ifndef PIC +- lea L(AliPxQx)(%rip),%r11 +- jmpq *(%r11,%r10,8) +-#else +- lea L(aligned_now)(%rip), %r11 +- lea L(AliPxQx)(%rip),%rcx +- movswq (%rcx,%r10,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-#endif +- +- .pushsection .rodata +- .balign 16 +-#ifndef PIC +-L(AliPxQx): +- .quad L(aligned_now), L(A1Q0), L(A2Q0), L(A3Q0) +- .quad L(A4Q0), L(A5Q0), L(A6Q0), L(A7Q0) +- .quad L(A0Q1), L(A1Q1), L(A2Q1), L(A3Q1) +- .quad L(A4Q1), L(A5Q1), L(A6Q1), L(A7Q1) +-#else +-L(AliPxQx): +- .short L(aligned_now)-L(aligned_now) +- .short L(A1Q0)-L(aligned_now) +- .short L(A2Q0)-L(aligned_now) +- .short L(A3Q0)-L(aligned_now) +- .short L(A4Q0)-L(aligned_now) +- .short L(A5Q0)-L(aligned_now) +- .short L(A6Q0)-L(aligned_now) +- .short L(A7Q0)-L(aligned_now) +- +- .short L(A0Q1)-L(aligned_now) +- .short L(A1Q1)-L(aligned_now) +- .short L(A2Q1)-L(aligned_now) +- .short L(A3Q1)-L(aligned_now) +- .short L(A4Q1)-L(aligned_now) +- .short L(A5Q1)-L(aligned_now) +- .short L(A6Q1)-L(aligned_now) +- .short L(A7Q1)-L(aligned_now) +-#endif +- .popsection +- +- .balign 16 +-L(A5Q1): mov %dl,-0xd(%rdi) +-L(A4Q1): mov %edx,-0xc(%rdi) +-L(A0Q1): mov %rdx,-0x8(%rdi) +-L(A0Q0): jmp L(aligned_now) +- +- .balign 16 +-L(A1Q1): mov %dl,-0x9(%rdi) +- mov %rdx,-0x8(%rdi) +- jmp L(aligned_now) +- +- .balign 16 +-L(A1Q0): mov %dl,-0x1(%rdi) +- jmp L(aligned_now) +- +- .balign 16 +-L(A3Q1): mov %dl,-0xb(%rdi) +-L(A2Q1): mov %dx,-0xa(%rdi) +- mov %rdx,-0x8(%rdi) +- jmp L(aligned_now) +- +- .balign 16 +-L(A3Q0): mov %dl,-0x3(%rdi) +-L(A2Q0): mov %dx,-0x2(%rdi) +- jmp L(aligned_now) +- +- .balign 16 +-L(A5Q0): mov %dl,-0x5(%rdi) +-L(A4Q0): mov %edx,-0x4(%rdi) +- jmp L(aligned_now) +- +- .balign 16 +-L(A7Q1): mov %dl,-0xf(%rdi) +-L(A6Q1): mov %dx,-0xe(%rdi) +- mov %edx,-0xc(%rdi) +- mov %rdx,-0x8(%rdi) +- jmp L(aligned_now) +- +- .balign 16 +-L(A7Q0): mov %dl,-0x7(%rdi) +-L(A6Q0): mov %dx,-0x6(%rdi) +- mov %edx,-0x4(%rdi) +- +-#ifndef USE_MULTIARCH +- jmp L(aligned_now) +- +-L(SSE_pre): +-#else +-L(aligned_now): +-#endif +-#if !defined USE_MULTIARCH || defined USE_SSE2 +- # fill RegXMM0 with the pattern +- movd %rdx,%xmm0 +- punpcklqdq %xmm0,%xmm0 +- +- cmp $0xb0,%r8 # 176 +- jae L(byte32sse2_pre) +- +- add %r8,%rdi +-# ifndef PIC +- lea L(SSExDx)(%rip),%r9 +- jmpq *(%r9,%r8,8) +-# else +- lea L(SSE0Q0)(%rip),%r9 +- lea L(SSExDx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r9,1),%r9 +- jmpq *%r9 +-# endif +- +-L(SSE0QB): movdqa %xmm0,-0xb0(%rdi) +-L(SSE0QA): movdqa %xmm0,-0xa0(%rdi) +-L(SSE0Q9): movdqa %xmm0,-0x90(%rdi) +-L(SSE0Q8): movdqa %xmm0,-0x80(%rdi) +-L(SSE0Q7): movdqa %xmm0,-0x70(%rdi) +-L(SSE0Q6): movdqa %xmm0,-0x60(%rdi) +-L(SSE0Q5): movdqa %xmm0,-0x50(%rdi) +-L(SSE0Q4): movdqa %xmm0,-0x40(%rdi) +-L(SSE0Q3): movdqa %xmm0,-0x30(%rdi) +-L(SSE0Q2): movdqa %xmm0,-0x20(%rdi) +-L(SSE0Q1): movdqa %xmm0,-0x10(%rdi) +-L(SSE0Q0): retq +- +-L(SSE1QB): movdqa %xmm0,-0xb1(%rdi) +-L(SSE1QA): movdqa %xmm0,-0xa1(%rdi) +-L(SSE1Q9): movdqa %xmm0,-0x91(%rdi) +-L(SSE1Q8): movdqa %xmm0,-0x81(%rdi) +-L(SSE1Q7): movdqa %xmm0,-0x71(%rdi) +-L(SSE1Q6): movdqa %xmm0,-0x61(%rdi) +-L(SSE1Q5): movdqa %xmm0,-0x51(%rdi) +-L(SSE1Q4): movdqa %xmm0,-0x41(%rdi) +-L(SSE1Q3): movdqa %xmm0,-0x31(%rdi) +-L(SSE1Q2): movdqa %xmm0,-0x21(%rdi) +-L(SSE1Q1): movdqa %xmm0,-0x11(%rdi) +-L(SSE1Q0): mov %dl,-0x1(%rdi) +- retq +- +-L(SSE2QB): movdqa %xmm0,-0xb2(%rdi) +-L(SSE2QA): movdqa %xmm0,-0xa2(%rdi) +-L(SSE2Q9): movdqa %xmm0,-0x92(%rdi) +-L(SSE2Q8): movdqa %xmm0,-0x82(%rdi) +-L(SSE2Q7): movdqa %xmm0,-0x72(%rdi) +-L(SSE2Q6): movdqa %xmm0,-0x62(%rdi) +-L(SSE2Q5): movdqa %xmm0,-0x52(%rdi) +-L(SSE2Q4): movdqa %xmm0,-0x42(%rdi) +-L(SSE2Q3): movdqa %xmm0,-0x32(%rdi) +-L(SSE2Q2): movdqa %xmm0,-0x22(%rdi) +-L(SSE2Q1): movdqa %xmm0,-0x12(%rdi) +-L(SSE2Q0): mov %dx,-0x2(%rdi) +- retq +- +-L(SSE3QB): movdqa %xmm0,-0xb3(%rdi) +-L(SSE3QA): movdqa %xmm0,-0xa3(%rdi) +-L(SSE3Q9): movdqa %xmm0,-0x93(%rdi) +-L(SSE3Q8): movdqa %xmm0,-0x83(%rdi) +-L(SSE3Q7): movdqa %xmm0,-0x73(%rdi) +-L(SSE3Q6): movdqa %xmm0,-0x63(%rdi) +-L(SSE3Q5): movdqa %xmm0,-0x53(%rdi) +-L(SSE3Q4): movdqa %xmm0,-0x43(%rdi) +-L(SSE3Q3): movdqa %xmm0,-0x33(%rdi) +-L(SSE3Q2): movdqa %xmm0,-0x23(%rdi) +-L(SSE3Q1): movdqa %xmm0,-0x13(%rdi) +-L(SSE3Q0): mov %dx,-0x3(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +-L(SSE4QB): movdqa %xmm0,-0xb4(%rdi) +-L(SSE4QA): movdqa %xmm0,-0xa4(%rdi) +-L(SSE4Q9): movdqa %xmm0,-0x94(%rdi) +-L(SSE4Q8): movdqa %xmm0,-0x84(%rdi) +-L(SSE4Q7): movdqa %xmm0,-0x74(%rdi) +-L(SSE4Q6): movdqa %xmm0,-0x64(%rdi) +-L(SSE4Q5): movdqa %xmm0,-0x54(%rdi) +-L(SSE4Q4): movdqa %xmm0,-0x44(%rdi) +-L(SSE4Q3): movdqa %xmm0,-0x34(%rdi) +-L(SSE4Q2): movdqa %xmm0,-0x24(%rdi) +-L(SSE4Q1): movdqa %xmm0,-0x14(%rdi) +-L(SSE4Q0): mov %edx,-0x4(%rdi) +- retq +- +-L(SSE5QB): movdqa %xmm0,-0xb5(%rdi) +-L(SSE5QA): movdqa %xmm0,-0xa5(%rdi) +-L(SSE5Q9): movdqa %xmm0,-0x95(%rdi) +-L(SSE5Q8): movdqa %xmm0,-0x85(%rdi) +-L(SSE5Q7): movdqa %xmm0,-0x75(%rdi) +-L(SSE5Q6): movdqa %xmm0,-0x65(%rdi) +-L(SSE5Q5): movdqa %xmm0,-0x55(%rdi) +-L(SSE5Q4): movdqa %xmm0,-0x45(%rdi) +-L(SSE5Q3): movdqa %xmm0,-0x35(%rdi) +-L(SSE5Q2): movdqa %xmm0,-0x25(%rdi) +-L(SSE5Q1): movdqa %xmm0,-0x15(%rdi) +-L(SSE5Q0): mov %edx,-0x5(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +- +-L(SSE6QB): movdqa %xmm0,-0xb6(%rdi) +-L(SSE6QA): movdqa %xmm0,-0xa6(%rdi) +-L(SSE6Q9): movdqa %xmm0,-0x96(%rdi) +-L(SSE6Q8): movdqa %xmm0,-0x86(%rdi) +-L(SSE6Q7): movdqa %xmm0,-0x76(%rdi) +-L(SSE6Q6): movdqa %xmm0,-0x66(%rdi) +-L(SSE6Q5): movdqa %xmm0,-0x56(%rdi) +-L(SSE6Q4): movdqa %xmm0,-0x46(%rdi) +-L(SSE6Q3): movdqa %xmm0,-0x36(%rdi) +-L(SSE6Q2): movdqa %xmm0,-0x26(%rdi) +-L(SSE6Q1): movdqa %xmm0,-0x16(%rdi) +-L(SSE6Q0): mov %edx,-0x6(%rdi) +- mov %dx,-0x2(%rdi) +- retq +- +-L(SSE7QB): movdqa %xmm0,-0xb7(%rdi) +-L(SSE7QA): movdqa %xmm0,-0xa7(%rdi) +-L(SSE7Q9): movdqa %xmm0,-0x97(%rdi) +-L(SSE7Q8): movdqa %xmm0,-0x87(%rdi) +-L(SSE7Q7): movdqa %xmm0,-0x77(%rdi) +-L(SSE7Q6): movdqa %xmm0,-0x67(%rdi) +-L(SSE7Q5): movdqa %xmm0,-0x57(%rdi) +-L(SSE7Q4): movdqa %xmm0,-0x47(%rdi) +-L(SSE7Q3): movdqa %xmm0,-0x37(%rdi) +-L(SSE7Q2): movdqa %xmm0,-0x27(%rdi) +-L(SSE7Q1): movdqa %xmm0,-0x17(%rdi) +-L(SSE7Q0): mov %edx,-0x7(%rdi) +- mov %dx,-0x3(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +-L(SSE8QB): movdqa %xmm0,-0xb8(%rdi) +-L(SSE8QA): movdqa %xmm0,-0xa8(%rdi) +-L(SSE8Q9): movdqa %xmm0,-0x98(%rdi) +-L(SSE8Q8): movdqa %xmm0,-0x88(%rdi) +-L(SSE8Q7): movdqa %xmm0,-0x78(%rdi) +-L(SSE8Q6): movdqa %xmm0,-0x68(%rdi) +-L(SSE8Q5): movdqa %xmm0,-0x58(%rdi) +-L(SSE8Q4): movdqa %xmm0,-0x48(%rdi) +-L(SSE8Q3): movdqa %xmm0,-0x38(%rdi) +-L(SSE8Q2): movdqa %xmm0,-0x28(%rdi) +-L(SSE8Q1): movdqa %xmm0,-0x18(%rdi) +-L(SSE8Q0): mov %rdx,-0x8(%rdi) +- retq +- +-L(SSE9QB): movdqa %xmm0,-0xb9(%rdi) +-L(SSE9QA): movdqa %xmm0,-0xa9(%rdi) +-L(SSE9Q9): movdqa %xmm0,-0x99(%rdi) +-L(SSE9Q8): movdqa %xmm0,-0x89(%rdi) +-L(SSE9Q7): movdqa %xmm0,-0x79(%rdi) +-L(SSE9Q6): movdqa %xmm0,-0x69(%rdi) +-L(SSE9Q5): movdqa %xmm0,-0x59(%rdi) +-L(SSE9Q4): movdqa %xmm0,-0x49(%rdi) +-L(SSE9Q3): movdqa %xmm0,-0x39(%rdi) +-L(SSE9Q2): movdqa %xmm0,-0x29(%rdi) +-L(SSE9Q1): movdqa %xmm0,-0x19(%rdi) +-L(SSE9Q0): mov %rdx,-0x9(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +-L(SSE10QB): movdqa %xmm0,-0xba(%rdi) +-L(SSE10QA): movdqa %xmm0,-0xaa(%rdi) +-L(SSE10Q9): movdqa %xmm0,-0x9a(%rdi) +-L(SSE10Q8): movdqa %xmm0,-0x8a(%rdi) +-L(SSE10Q7): movdqa %xmm0,-0x7a(%rdi) +-L(SSE10Q6): movdqa %xmm0,-0x6a(%rdi) +-L(SSE10Q5): movdqa %xmm0,-0x5a(%rdi) +-L(SSE10Q4): movdqa %xmm0,-0x4a(%rdi) +-L(SSE10Q3): movdqa %xmm0,-0x3a(%rdi) +-L(SSE10Q2): movdqa %xmm0,-0x2a(%rdi) +-L(SSE10Q1): movdqa %xmm0,-0x1a(%rdi) +-L(SSE10Q0): mov %rdx,-0xa(%rdi) +- mov %dx,-0x2(%rdi) +- retq +- +-L(SSE11QB): movdqa %xmm0,-0xbb(%rdi) +-L(SSE11QA): movdqa %xmm0,-0xab(%rdi) +-L(SSE11Q9): movdqa %xmm0,-0x9b(%rdi) +-L(SSE11Q8): movdqa %xmm0,-0x8b(%rdi) +-L(SSE11Q7): movdqa %xmm0,-0x7b(%rdi) +-L(SSE11Q6): movdqa %xmm0,-0x6b(%rdi) +-L(SSE11Q5): movdqa %xmm0,-0x5b(%rdi) +-L(SSE11Q4): movdqa %xmm0,-0x4b(%rdi) +-L(SSE11Q3): movdqa %xmm0,-0x3b(%rdi) +-L(SSE11Q2): movdqa %xmm0,-0x2b(%rdi) +-L(SSE11Q1): movdqa %xmm0,-0x1b(%rdi) +-L(SSE11Q0): mov %rdx,-0xb(%rdi) +- mov %dx,-0x3(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +-L(SSE12QB): movdqa %xmm0,-0xbc(%rdi) +-L(SSE12QA): movdqa %xmm0,-0xac(%rdi) +-L(SSE12Q9): movdqa %xmm0,-0x9c(%rdi) +-L(SSE12Q8): movdqa %xmm0,-0x8c(%rdi) +-L(SSE12Q7): movdqa %xmm0,-0x7c(%rdi) +-L(SSE12Q6): movdqa %xmm0,-0x6c(%rdi) +-L(SSE12Q5): movdqa %xmm0,-0x5c(%rdi) +-L(SSE12Q4): movdqa %xmm0,-0x4c(%rdi) +-L(SSE12Q3): movdqa %xmm0,-0x3c(%rdi) +-L(SSE12Q2): movdqa %xmm0,-0x2c(%rdi) +-L(SSE12Q1): movdqa %xmm0,-0x1c(%rdi) +-L(SSE12Q0): mov %rdx,-0xc(%rdi) +- mov %edx,-0x4(%rdi) +- retq +- +-L(SSE13QB): movdqa %xmm0,-0xbd(%rdi) +-L(SSE13QA): movdqa %xmm0,-0xad(%rdi) +-L(SSE13Q9): movdqa %xmm0,-0x9d(%rdi) +-L(SSE13Q8): movdqa %xmm0,-0x8d(%rdi) +-L(SSE13Q7): movdqa %xmm0,-0x7d(%rdi) +-L(SSE13Q6): movdqa %xmm0,-0x6d(%rdi) +-L(SSE13Q5): movdqa %xmm0,-0x5d(%rdi) +-L(SSE13Q4): movdqa %xmm0,-0x4d(%rdi) +-L(SSE13Q3): movdqa %xmm0,-0x3d(%rdi) +-L(SSE13Q2): movdqa %xmm0,-0x2d(%rdi) +-L(SSE13Q1): movdqa %xmm0,-0x1d(%rdi) +-L(SSE13Q0): mov %rdx,-0xd(%rdi) +- mov %edx,-0x5(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +-L(SSE14QB): movdqa %xmm0,-0xbe(%rdi) +-L(SSE14QA): movdqa %xmm0,-0xae(%rdi) +-L(SSE14Q9): movdqa %xmm0,-0x9e(%rdi) +-L(SSE14Q8): movdqa %xmm0,-0x8e(%rdi) +-L(SSE14Q7): movdqa %xmm0,-0x7e(%rdi) +-L(SSE14Q6): movdqa %xmm0,-0x6e(%rdi) +-L(SSE14Q5): movdqa %xmm0,-0x5e(%rdi) +-L(SSE14Q4): movdqa %xmm0,-0x4e(%rdi) +-L(SSE14Q3): movdqa %xmm0,-0x3e(%rdi) +-L(SSE14Q2): movdqa %xmm0,-0x2e(%rdi) +-L(SSE14Q1): movdqa %xmm0,-0x1e(%rdi) +-L(SSE14Q0): mov %rdx,-0xe(%rdi) +- mov %edx,-0x6(%rdi) +- mov %dx,-0x2(%rdi) +- retq +- +-L(SSE15QB): movdqa %xmm0,-0xbf(%rdi) +-L(SSE15QA): movdqa %xmm0,-0xaf(%rdi) +-L(SSE15Q9): movdqa %xmm0,-0x9f(%rdi) +-L(SSE15Q8): movdqa %xmm0,-0x8f(%rdi) +-L(SSE15Q7): movdqa %xmm0,-0x7f(%rdi) +-L(SSE15Q6): movdqa %xmm0,-0x6f(%rdi) +-L(SSE15Q5): movdqa %xmm0,-0x5f(%rdi) +-L(SSE15Q4): movdqa %xmm0,-0x4f(%rdi) +-L(SSE15Q3): movdqa %xmm0,-0x3f(%rdi) +-L(SSE15Q2): movdqa %xmm0,-0x2f(%rdi) +-L(SSE15Q1): movdqa %xmm0,-0x1f(%rdi) +-L(SSE15Q0): mov %rdx,-0xf(%rdi) +- mov %edx,-0x7(%rdi) +- mov %dx,-0x3(%rdi) +- mov %dl,-0x1(%rdi) +- retq +- +- .balign 16 +-L(byte32sse2_pre): +- +- mov __x86_64_shared_cache_size(%rip),%r9d # The largest cache size +- cmp %r9,%r8 +- ja L(sse2_nt_move_pre) +- #jmp L(byte32sse2) +- .balign 16 +-L(byte32sse2): +- lea -0x80(%r8),%r8 # 128 +- cmp $0x80,%r8 # 128 +- movdqa %xmm0,(%rdi) +- movdqa %xmm0,0x10(%rdi) +- movdqa %xmm0,0x20(%rdi) +- movdqa %xmm0,0x30(%rdi) +- movdqa %xmm0,0x40(%rdi) +- movdqa %xmm0,0x50(%rdi) +- movdqa %xmm0,0x60(%rdi) +- movdqa %xmm0,0x70(%rdi) +- +- lea 0x80(%rdi),%rdi +- jae L(byte32sse2) +- add %r8,%rdi +-# ifndef PIC +- lea L(SSExDx)(%rip),%r11 +- jmpq *(%r11,%r8,8) +-# else +- lea L(SSE0Q0)(%rip),%r11 +- lea L(SSExDx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-# endif +- +- .balign 16 +-L(sse2_nt_move_pre): +- cmp $0x0,%r9 +- je L(byte32sse2) +- jmp L(sse2_nt_move) +- +- .balign 16 +-L(sse2_nt_move): +- lea -0x80(%r8),%r8 +- cmp $0x80,%r8 +- +- movntdq %xmm0,(%rdi) +- movntdq %xmm0,0x10(%rdi) +- movntdq %xmm0,0x20(%rdi) +- movntdq %xmm0,0x30(%rdi) +- movntdq %xmm0,0x40(%rdi) +- movntdq %xmm0,0x50(%rdi) +- movntdq %xmm0,0x60(%rdi) +- movntdq %xmm0,0x70(%rdi) +- +- lea 0x80(%rdi),%rdi +- jae L(sse2_nt_move) +- sfence +- add %r8,%rdi +-# ifndef PIC +- lea L(SSExDx)(%rip),%r11 +- jmpq *(%r11,%r8,8) +-# else +- lea L(SSE0Q0)(%rip),%r11 +- lea L(SSExDx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-# endif +- +- .pushsection .rodata +- .balign 16 +-# ifndef PIC +-L(SSExDx): +- .quad L(SSE0Q0), L(SSE1Q0), L(SSE2Q0), L(SSE3Q0) +- .quad L(SSE4Q0), L(SSE5Q0), L(SSE6Q0), L(SSE7Q0) +- .quad L(SSE8Q0), L(SSE9Q0), L(SSE10Q0), L(SSE11Q0) +- .quad L(SSE12Q0), L(SSE13Q0), L(SSE14Q0), L(SSE15Q0) +- .quad L(SSE0Q1), L(SSE1Q1), L(SSE2Q1), L(SSE3Q1) +- .quad L(SSE4Q1), L(SSE5Q1), L(SSE6Q1), L(SSE7Q1) +- .quad L(SSE8Q1), L(SSE9Q1), L(SSE10Q1), L(SSE11Q1) +- .quad L(SSE12Q1), L(SSE13Q1), L(SSE14Q1), L(SSE15Q1) +- .quad L(SSE0Q2), L(SSE1Q2), L(SSE2Q2), L(SSE3Q2) +- .quad L(SSE4Q2), L(SSE5Q2), L(SSE6Q2), L(SSE7Q2) +- .quad L(SSE8Q2), L(SSE9Q2), L(SSE10Q2), L(SSE11Q2) +- .quad L(SSE12Q2), L(SSE13Q2), L(SSE14Q2), L(SSE15Q2) +- .quad L(SSE0Q3), L(SSE1Q3), L(SSE2Q3), L(SSE3Q3) +- .quad L(SSE4Q3), L(SSE5Q3), L(SSE6Q3), L(SSE7Q3) +- .quad L(SSE8Q3), L(SSE9Q3), L(SSE10Q3), L(SSE11Q3) +- .quad L(SSE12Q3), L(SSE13Q3), L(SSE14Q3), L(SSE15Q3) +- .quad L(SSE0Q4), L(SSE1Q4), L(SSE2Q4), L(SSE3Q4) +- .quad L(SSE4Q4), L(SSE5Q4), L(SSE6Q4), L(SSE7Q4) +- .quad L(SSE8Q4), L(SSE9Q4), L(SSE10Q4), L(SSE11Q4) +- .quad L(SSE12Q4), L(SSE13Q4), L(SSE14Q4), L(SSE15Q4) +- .quad L(SSE0Q5), L(SSE1Q5), L(SSE2Q5), L(SSE3Q5) +- .quad L(SSE4Q5), L(SSE5Q5), L(SSE6Q5), L(SSE7Q5) +- .quad L(SSE8Q5), L(SSE9Q5), L(SSE10Q5), L(SSE11Q5) +- .quad L(SSE12Q5), L(SSE13Q5), L(SSE14Q5), L(SSE15Q5) +- .quad L(SSE0Q6), L(SSE1Q6), L(SSE2Q6), L(SSE3Q6) +- .quad L(SSE4Q6), L(SSE5Q6), L(SSE6Q6), L(SSE7Q6) +- .quad L(SSE8Q6), L(SSE9Q6), L(SSE10Q6), L(SSE11Q6) +- .quad L(SSE12Q6), L(SSE13Q6), L(SSE14Q6), L(SSE15Q6) +- .quad L(SSE0Q7), L(SSE1Q7), L(SSE2Q7), L(SSE3Q7) +- .quad L(SSE4Q7), L(SSE5Q7), L(SSE6Q7), L(SSE7Q7) +- .quad L(SSE8Q7), L(SSE9Q7), L(SSE10Q7), L(SSE11Q7) +- .quad L(SSE12Q7), L(SSE13Q7), L(SSE14Q7), L(SSE15Q7) +- .quad L(SSE0Q8), L(SSE1Q8), L(SSE2Q8), L(SSE3Q8) +- .quad L(SSE4Q8), L(SSE5Q8), L(SSE6Q8), L(SSE7Q8) +- .quad L(SSE8Q8), L(SSE9Q8), L(SSE10Q8), L(SSE11Q8) +- .quad L(SSE12Q8), L(SSE13Q8), L(SSE14Q8), L(SSE15Q8) +- .quad L(SSE0Q9), L(SSE1Q9), L(SSE2Q9), L(SSE3Q9) +- .quad L(SSE4Q9), L(SSE5Q9), L(SSE6Q9), L(SSE7Q9) +- .quad L(SSE8Q9), L(SSE9Q9), L(SSE10Q9), L(SSE11Q9) +- .quad L(SSE12Q9), L(SSE13Q9), L(SSE14Q9), L(SSE15Q9) +- .quad L(SSE0QA), L(SSE1QA), L(SSE2QA), L(SSE3QA) +- .quad L(SSE4QA), L(SSE5QA), L(SSE6QA), L(SSE7QA) +- .quad L(SSE8QA), L(SSE9QA), L(SSE10QA), L(SSE11QA) +- .quad L(SSE12QA), L(SSE13QA), L(SSE14QA), L(SSE15QA) +- .quad L(SSE0QB), L(SSE1QB), L(SSE2QB), L(SSE3QB) +- .quad L(SSE4QB), L(SSE5QB), L(SSE6QB), L(SSE7QB) +- .quad L(SSE8QB), L(SSE9QB), L(SSE10QB), L(SSE11QB) +- .quad L(SSE12QB), L(SSE13QB), L(SSE14QB), L(SSE15QB) +-# else +-L(SSExDx): +- .short L(SSE0Q0) -L(SSE0Q0) +- .short L(SSE1Q0) -L(SSE0Q0) +- .short L(SSE2Q0) -L(SSE0Q0) +- .short L(SSE3Q0) -L(SSE0Q0) +- .short L(SSE4Q0) -L(SSE0Q0) +- .short L(SSE5Q0) -L(SSE0Q0) +- .short L(SSE6Q0) -L(SSE0Q0) +- .short L(SSE7Q0) -L(SSE0Q0) +- +- .short L(SSE8Q0) -L(SSE0Q0) +- .short L(SSE9Q0) -L(SSE0Q0) +- .short L(SSE10Q0)-L(SSE0Q0) +- .short L(SSE11Q0)-L(SSE0Q0) +- .short L(SSE12Q0)-L(SSE0Q0) +- .short L(SSE13Q0)-L(SSE0Q0) +- .short L(SSE14Q0)-L(SSE0Q0) +- .short L(SSE15Q0)-L(SSE0Q0) +- +- .short L(SSE0Q1) -L(SSE0Q0) +- .short L(SSE1Q1) -L(SSE0Q0) +- .short L(SSE2Q1) -L(SSE0Q0) +- .short L(SSE3Q1) -L(SSE0Q0) +- .short L(SSE4Q1) -L(SSE0Q0) +- .short L(SSE5Q1) -L(SSE0Q0) +- .short L(SSE6Q1) -L(SSE0Q0) +- .short L(SSE7Q1) -L(SSE0Q0) +- +- .short L(SSE8Q1) -L(SSE0Q0) +- .short L(SSE9Q1) -L(SSE0Q0) +- .short L(SSE10Q1)-L(SSE0Q0) +- .short L(SSE11Q1)-L(SSE0Q0) +- .short L(SSE12Q1)-L(SSE0Q0) +- .short L(SSE13Q1)-L(SSE0Q0) +- .short L(SSE14Q1)-L(SSE0Q0) +- .short L(SSE15Q1)-L(SSE0Q0) +- +- .short L(SSE0Q2) -L(SSE0Q0) +- .short L(SSE1Q2) -L(SSE0Q0) +- .short L(SSE2Q2) -L(SSE0Q0) +- .short L(SSE3Q2) -L(SSE0Q0) +- .short L(SSE4Q2) -L(SSE0Q0) +- .short L(SSE5Q2) -L(SSE0Q0) +- .short L(SSE6Q2) -L(SSE0Q0) +- .short L(SSE7Q2) -L(SSE0Q0) +- +- .short L(SSE8Q2) -L(SSE0Q0) +- .short L(SSE9Q2) -L(SSE0Q0) +- .short L(SSE10Q2)-L(SSE0Q0) +- .short L(SSE11Q2)-L(SSE0Q0) +- .short L(SSE12Q2)-L(SSE0Q0) +- .short L(SSE13Q2)-L(SSE0Q0) +- .short L(SSE14Q2)-L(SSE0Q0) +- .short L(SSE15Q2)-L(SSE0Q0) +- +- .short L(SSE0Q3) -L(SSE0Q0) +- .short L(SSE1Q3) -L(SSE0Q0) +- .short L(SSE2Q3) -L(SSE0Q0) +- .short L(SSE3Q3) -L(SSE0Q0) +- .short L(SSE4Q3) -L(SSE0Q0) +- .short L(SSE5Q3) -L(SSE0Q0) +- .short L(SSE6Q3) -L(SSE0Q0) +- .short L(SSE7Q3) -L(SSE0Q0) +- +- .short L(SSE8Q3) -L(SSE0Q0) +- .short L(SSE9Q3) -L(SSE0Q0) +- .short L(SSE10Q3)-L(SSE0Q0) +- .short L(SSE11Q3)-L(SSE0Q0) +- .short L(SSE12Q3)-L(SSE0Q0) +- .short L(SSE13Q3)-L(SSE0Q0) +- .short L(SSE14Q3)-L(SSE0Q0) +- .short L(SSE15Q3)-L(SSE0Q0) +- +- .short L(SSE0Q4) -L(SSE0Q0) +- .short L(SSE1Q4) -L(SSE0Q0) +- .short L(SSE2Q4) -L(SSE0Q0) +- .short L(SSE3Q4) -L(SSE0Q0) +- .short L(SSE4Q4) -L(SSE0Q0) +- .short L(SSE5Q4) -L(SSE0Q0) +- .short L(SSE6Q4) -L(SSE0Q0) +- .short L(SSE7Q4) -L(SSE0Q0) +- +- .short L(SSE8Q4) -L(SSE0Q0) +- .short L(SSE9Q4) -L(SSE0Q0) +- .short L(SSE10Q4)-L(SSE0Q0) +- .short L(SSE11Q4)-L(SSE0Q0) +- .short L(SSE12Q4)-L(SSE0Q0) +- .short L(SSE13Q4)-L(SSE0Q0) +- .short L(SSE14Q4)-L(SSE0Q0) +- .short L(SSE15Q4)-L(SSE0Q0) +- +- .short L(SSE0Q5) -L(SSE0Q0) +- .short L(SSE1Q5) -L(SSE0Q0) +- .short L(SSE2Q5) -L(SSE0Q0) +- .short L(SSE3Q5) -L(SSE0Q0) +- .short L(SSE4Q5) -L(SSE0Q0) +- .short L(SSE5Q5) -L(SSE0Q0) +- .short L(SSE6Q5) -L(SSE0Q0) +- .short L(SSE7Q5) -L(SSE0Q0) +- +- .short L(SSE8Q5) -L(SSE0Q0) +- .short L(SSE9Q5) -L(SSE0Q0) +- .short L(SSE10Q5)-L(SSE0Q0) +- .short L(SSE11Q5)-L(SSE0Q0) +- .short L(SSE12Q5)-L(SSE0Q0) +- .short L(SSE13Q5)-L(SSE0Q0) +- .short L(SSE14Q5)-L(SSE0Q0) +- .short L(SSE15Q5)-L(SSE0Q0) +- +- .short L(SSE0Q6) -L(SSE0Q0) +- .short L(SSE1Q6) -L(SSE0Q0) +- .short L(SSE2Q6) -L(SSE0Q0) +- .short L(SSE3Q6) -L(SSE0Q0) +- .short L(SSE4Q6) -L(SSE0Q0) +- .short L(SSE5Q6) -L(SSE0Q0) +- .short L(SSE6Q6) -L(SSE0Q0) +- .short L(SSE7Q6) -L(SSE0Q0) +- +- .short L(SSE8Q6) -L(SSE0Q0) +- .short L(SSE9Q6) -L(SSE0Q0) +- .short L(SSE10Q6)-L(SSE0Q0) +- .short L(SSE11Q6)-L(SSE0Q0) +- .short L(SSE12Q6)-L(SSE0Q0) +- .short L(SSE13Q6)-L(SSE0Q0) +- .short L(SSE14Q6)-L(SSE0Q0) +- .short L(SSE15Q6)-L(SSE0Q0) +- +- .short L(SSE0Q7) -L(SSE0Q0) +- .short L(SSE1Q7) -L(SSE0Q0) +- .short L(SSE2Q7) -L(SSE0Q0) +- .short L(SSE3Q7) -L(SSE0Q0) +- .short L(SSE4Q7) -L(SSE0Q0) +- .short L(SSE5Q7) -L(SSE0Q0) +- .short L(SSE6Q7) -L(SSE0Q0) +- .short L(SSE7Q7) -L(SSE0Q0) +- +- .short L(SSE8Q7) -L(SSE0Q0) +- .short L(SSE9Q7) -L(SSE0Q0) +- .short L(SSE10Q7)-L(SSE0Q0) +- .short L(SSE11Q7)-L(SSE0Q0) +- .short L(SSE12Q7)-L(SSE0Q0) +- .short L(SSE13Q7)-L(SSE0Q0) +- .short L(SSE14Q7)-L(SSE0Q0) +- .short L(SSE15Q7)-L(SSE0Q0) +- +- .short L(SSE0Q8) -L(SSE0Q0) +- .short L(SSE1Q8) -L(SSE0Q0) +- .short L(SSE2Q8) -L(SSE0Q0) +- .short L(SSE3Q8) -L(SSE0Q0) +- .short L(SSE4Q8) -L(SSE0Q0) +- .short L(SSE5Q8) -L(SSE0Q0) +- .short L(SSE6Q8) -L(SSE0Q0) +- .short L(SSE7Q8) -L(SSE0Q0) +- +- .short L(SSE8Q8) -L(SSE0Q0) +- .short L(SSE9Q8) -L(SSE0Q0) +- .short L(SSE10Q8)-L(SSE0Q0) +- .short L(SSE11Q8)-L(SSE0Q0) +- .short L(SSE12Q8)-L(SSE0Q0) +- .short L(SSE13Q8)-L(SSE0Q0) +- .short L(SSE14Q8)-L(SSE0Q0) +- .short L(SSE15Q8)-L(SSE0Q0) +- +- .short L(SSE0Q9) -L(SSE0Q0) +- .short L(SSE1Q9) -L(SSE0Q0) +- .short L(SSE2Q9) -L(SSE0Q0) +- .short L(SSE3Q9) -L(SSE0Q0) +- .short L(SSE4Q9) -L(SSE0Q0) +- .short L(SSE5Q9) -L(SSE0Q0) +- .short L(SSE6Q9) -L(SSE0Q0) +- .short L(SSE7Q9) -L(SSE0Q0) +- +- .short L(SSE8Q9) -L(SSE0Q0) +- .short L(SSE9Q9) -L(SSE0Q0) +- .short L(SSE10Q9)-L(SSE0Q0) +- .short L(SSE11Q9)-L(SSE0Q0) +- .short L(SSE12Q9)-L(SSE0Q0) +- .short L(SSE13Q9)-L(SSE0Q0) +- .short L(SSE14Q9)-L(SSE0Q0) +- .short L(SSE15Q9)-L(SSE0Q0) +- +- .short L(SSE0QA) -L(SSE0Q0) +- .short L(SSE1QA) -L(SSE0Q0) +- .short L(SSE2QA) -L(SSE0Q0) +- .short L(SSE3QA) -L(SSE0Q0) +- .short L(SSE4QA) -L(SSE0Q0) +- .short L(SSE5QA) -L(SSE0Q0) +- .short L(SSE6QA) -L(SSE0Q0) +- .short L(SSE7QA) -L(SSE0Q0) +- +- .short L(SSE8QA) -L(SSE0Q0) +- .short L(SSE9QA) -L(SSE0Q0) +- .short L(SSE10QA)-L(SSE0Q0) +- .short L(SSE11QA)-L(SSE0Q0) +- .short L(SSE12QA)-L(SSE0Q0) +- .short L(SSE13QA)-L(SSE0Q0) +- .short L(SSE14QA)-L(SSE0Q0) +- .short L(SSE15QA)-L(SSE0Q0) +- +- .short L(SSE0QB) -L(SSE0Q0) +- .short L(SSE1QB) -L(SSE0Q0) +- .short L(SSE2QB) -L(SSE0Q0) +- .short L(SSE3QB) -L(SSE0Q0) +- .short L(SSE4QB) -L(SSE0Q0) +- .short L(SSE5QB) -L(SSE0Q0) +- .short L(SSE6QB) -L(SSE0Q0) +- .short L(SSE7QB) -L(SSE0Q0) +- +- .short L(SSE8QB) -L(SSE0Q0) +- .short L(SSE9QB) -L(SSE0Q0) +- .short L(SSE10QB)-L(SSE0Q0) +- .short L(SSE11QB)-L(SSE0Q0) +- .short L(SSE12QB)-L(SSE0Q0) +- .short L(SSE13QB)-L(SSE0Q0) +- .short L(SSE14QB)-L(SSE0Q0) +- .short L(SSE15QB)-L(SSE0Q0) +-# endif +- .popsection +-#endif /* !defined USE_MULTIARCH || defined USE_SSE2 */ +- +- .balign 16 +-#ifndef USE_MULTIARCH +-L(aligned_now): +- +- cmpl $0x1,__x86_64_preferred_memory_instruction(%rip) +- jg L(SSE_pre) +-#endif /* USE_MULTIARCH */ +- +-L(8byte_move_try): +- cmpq __STOS_LOWER_BOUNDARY,%r8 +- jae L(8byte_stos_try) +- +- .balign 16 +-L(8byte_move): +- movq %r8,%rcx +- shrq $7,%rcx +- jz L(8byte_move_skip) +- +- .p2align 4 +- +-L(8byte_move_loop): +- decq %rcx +- +- movq %rdx, (%rdi) +- movq %rdx, 8 (%rdi) +- movq %rdx, 16 (%rdi) +- movq %rdx, 24 (%rdi) +- movq %rdx, 32 (%rdi) +- movq %rdx, 40 (%rdi) +- movq %rdx, 48 (%rdi) +- movq %rdx, 56 (%rdi) +- movq %rdx, 64 (%rdi) +- movq %rdx, 72 (%rdi) +- movq %rdx, 80 (%rdi) +- movq %rdx, 88 (%rdi) +- movq %rdx, 96 (%rdi) +- movq %rdx, 104 (%rdi) +- movq %rdx, 112 (%rdi) +- movq %rdx, 120 (%rdi) +- +- leaq 128 (%rdi),%rdi +- +- jnz L(8byte_move_loop) +- +-L(8byte_move_skip): +- andl $127,%r8d +- lea (%rdi,%r8,1),%rdi +- +-#ifndef PIC +- lea L(setPxQx)(%rip),%r11 +- jmpq *(%r11,%r8,8) # old scheme remained for nonPIC +-#else +- lea L(Got0)(%rip),%r11 +- lea L(setPxQx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-#endif +- +- .balign 16 +-L(8byte_stos_try): +- mov __x86_64_shared_cache_size(%rip),%r9d // ck largest cache size +- cmpq %r8,%r9 // calculate the lesser of remaining +- cmovaq %r8,%r9 // bytes and largest cache size +- jbe L(8byte_stos) +- +-L(8byte_move_reuse_try): +- cmp __STOS_UPPER_BOUNDARY,%r8 +- jae L(8byte_move) +- +- .balign 16 +-L(8byte_stos): +- movq %r9,%rcx +- andq $-8,%r9 +- +- shrq $3,%rcx +- jz L(8byte_stos_skip) +- +- xchgq %rax,%rdx + ++ENTRY (memset) ++ movd %esi, %xmm8 ++ movq %rdi, %rax ++ punpcklbw %xmm8, %xmm8 ++ punpcklwd %xmm8, %xmm8 ++ pshufd $0, %xmm8, %xmm8 ++L(entry_from_bzero): ++ cmpq $64, %rdx ++ ja L(loop_start) ++ cmpq $16, %rdx ++ jbe L(less_16_bytes) ++ cmpq $32, %rdx ++ movdqu %xmm8, (%rdi) ++ movdqu %xmm8, -16(%rdi,%rdx) ++ ja L(between_32_64_bytes) ++L(return): + rep +- stosq +- +- xchgq %rax,%rdx +- +-L(8byte_stos_skip): +- subq %r9,%r8 +- ja L(8byte_nt_move) +- +- andl $7,%r8d +- lea (%rdi,%r8,1),%rdi +-#ifndef PIC +- lea L(setPxQx)(%rip),%r11 +- jmpq *(%r11,%r8,8) # old scheme remained for nonPIC +-#else +- lea L(Got0)(%rip),%r11 +- lea L(setPxQx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-#endif +- +- .balign 16 +-L(8byte_nt_move): +- movq %r8,%rcx +- shrq $7,%rcx +- jz L(8byte_nt_move_skip) +- +- .balign 16 +-L(8byte_nt_move_loop): +- decq %rcx ++ ret + +- movntiq %rdx, (%rdi) +- movntiq %rdx, 8 (%rdi) +- movntiq %rdx, 16 (%rdi) +- movntiq %rdx, 24 (%rdi) +- movntiq %rdx, 32 (%rdi) +- movntiq %rdx, 40 (%rdi) +- movntiq %rdx, 48 (%rdi) +- movntiq %rdx, 56 (%rdi) +- movntiq %rdx, 64 (%rdi) +- movntiq %rdx, 72 (%rdi) +- movntiq %rdx, 80 (%rdi) +- movntiq %rdx, 88 (%rdi) +- movntiq %rdx, 96 (%rdi) +- movntiq %rdx, 104 (%rdi) +- movntiq %rdx, 112 (%rdi) +- movntiq %rdx, 120 (%rdi) +- +- leaq 128 (%rdi),%rdi +- +- jnz L(8byte_nt_move_loop) +- +- sfence +- +-L(8byte_nt_move_skip): +- andl $127,%r8d +- +- lea (%rdi,%r8,1),%rdi +-#ifndef PIC +- lea L(setPxQx)(%rip),%r11 +- jmpq *(%r11,%r8,8) # old scheme remained for nonPIC +-#else +- lea L(Got0)(%rip),%r11 +- lea L(setPxQx)(%rip),%rcx +- movswq (%rcx,%r8,2),%rcx +- lea (%rcx,%r11,1),%r11 +- jmpq *%r11 +-#endif ++ ALIGN (4) ++L(between_32_64_bytes): ++ movdqu %xmm8, 16(%rdi) ++ movdqu %xmm8, -32(%rdi,%rdx) ++ ret ++ ALIGN (4) ++L(loop_start): ++ leaq 64(%rdi), %rcx ++ movdqu %xmm8, (%rdi) ++ andq $-64, %rcx ++ movdqu %xmm8, -16(%rdi,%rdx) ++ movdqu %xmm8, 16(%rdi) ++ movdqu %xmm8, -32(%rdi,%rdx) ++ movdqu %xmm8, 32(%rdi) ++ movdqu %xmm8, -48(%rdi,%rdx) ++ movdqu %xmm8, 48(%rdi) ++ movdqu %xmm8, -64(%rdi,%rdx) ++ addq %rdi, %rdx ++ andq $-64, %rdx ++ cmpq %rdx, %rcx ++ je L(return) ++ ALIGN (4) ++L(loop): ++ movdqa %xmm8, (%rcx) ++ movdqa %xmm8, 16(%rcx) ++ movdqa %xmm8, 32(%rcx) ++ movdqa %xmm8, 48(%rcx) ++ addq $64, %rcx ++ cmpq %rcx, %rdx ++ jne L(loop) ++ rep ++ ret ++L(less_16_bytes): ++ movq %xmm8, %rcx ++ testb $24, %dl ++ jne L(between8_16bytes) ++ testb $4, %dl ++ jne L(between4_7bytes) ++ testb $1, %dl ++ je L(odd_byte) ++ movb %cl, (%rdi) ++L(odd_byte): ++ testb $2, %dl ++ je L(return) ++ movw %cx, -2(%rax,%rdx) ++ ret ++L(between4_7bytes): ++ movl %ecx, (%rdi) ++ movl %ecx, -4(%rdi,%rdx) ++ ret ++L(between8_16bytes): ++ movq %rcx, (%rdi) ++ movq %rcx, -8(%rdi,%rdx) ++ ret + + END (memset) + libc_hidden_builtin_def (memset) diff --git a/SOURCES/glibc-rh1335629.patch b/SOURCES/glibc-rh1335629.patch new file mode 100644 index 00000000..908e32dc --- /dev/null +++ b/SOURCES/glibc-rh1335629.patch @@ -0,0 +1,66 @@ +commit b763f6ae859ecea70a5dacb8ad45c71d5f667e2e +Author: Andreas Schwab +Date: Tue Sep 30 12:41:11 2014 +0200 + + aarch64: Increase MINSIGSTKSZ and SIGSTKSZ (bug 16850) + +diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/sigstack.h b/sysdeps/unix/sysv/linux/aarch64/bits/sigstack.h +new file mode 100644 +index 0000000..8f2fb76 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/aarch64/bits/sigstack.h +@@ -0,0 +1,54 @@ ++/* sigstack, sigaltstack definitions. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SIGNAL_H ++# error "Never include this file directly. Use instead" ++#endif ++ ++ ++/* Structure describing a signal stack (obsolete). */ ++struct sigstack ++ { ++ void *ss_sp; /* Signal stack pointer. */ ++ int ss_onstack; /* Nonzero if executing on this stack. */ ++ }; ++ ++ ++/* Possible values for `ss_flags.'. */ ++enum ++{ ++ SS_ONSTACK = 1, ++#define SS_ONSTACK SS_ONSTACK ++ SS_DISABLE ++#define SS_DISABLE SS_DISABLE ++}; ++ ++/* Minimum stack size for a signal handler. */ ++#define MINSIGSTKSZ 5120 ++ ++/* System default stack size. */ ++#define SIGSTKSZ 16384 ++ ++ ++/* Alternate, preferred interface. */ ++typedef struct sigaltstack ++ { ++ void *ss_sp; ++ int ss_flags; ++ size_t ss_size; ++ } stack_t; diff --git a/SOURCES/glibc-rh1335925-1.patch b/SOURCES/glibc-rh1335925-1.patch new file mode 100644 index 00000000..60f4eb5c --- /dev/null +++ b/SOURCES/glibc-rh1335925-1.patch @@ -0,0 +1,71 @@ +Backport of this upstream commit, with ports/ readded to the path. + +commit 5c40c3bab2fddaca8cfe12d75944d1fef8adf1a4 +Author: Alan Hayward +Date: Tue Nov 11 16:32:34 2014 +0000 + + [AArch64] Add ipc.h. + + Adding ipc.h for AArch64 adjusted to behave correctly on big endian + targets. + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h b/ports/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h +new file mode 100644 +index 0000000..aa50eb0 +--- /dev/null ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/bits/ipc.h +@@ -0,0 +1,54 @@ ++/* Copyright (C) 1995-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SYS_IPC_H ++# error "Never use directly; include instead." ++#endif ++ ++#include ++ ++/* Mode bits for `msgget', `semget', and `shmget'. */ ++#define IPC_CREAT 01000 /* Create key if key does not exist. */ ++#define IPC_EXCL 02000 /* Fail if key exists. */ ++#define IPC_NOWAIT 04000 /* Return error on wait. */ ++ ++/* Control commands for `msgctl', `semctl', and `shmctl'. */ ++#define IPC_RMID 0 /* Remove identifier. */ ++#define IPC_SET 1 /* Set `ipc_perm' options. */ ++#define IPC_STAT 2 /* Get `ipc_perm' options. */ ++#ifdef __USE_GNU ++# define IPC_INFO 3 /* See ipcs. */ ++#endif ++ ++/* Special key values. */ ++#define IPC_PRIVATE ((__key_t) 0) /* Private key. */ ++ ++ ++/* Data structure used to pass permission information to IPC operations. */ ++struct ipc_perm ++ { ++ __key_t __key; /* Key. */ ++ __uid_t uid; /* Owner's user ID. */ ++ __gid_t gid; /* Owner's group ID. */ ++ __uid_t cuid; /* Creator's user ID. */ ++ __gid_t cgid; /* Creator's group ID. */ ++ unsigned int mode; /* Read/write permission. */ ++ unsigned short int __seq; /* Sequence number. */ ++ unsigned short int __pad1; ++ __syscall_ulong_t __glibc_reserved1; ++ __syscall_ulong_t __glibc_reserved2; ++ }; diff --git a/SOURCES/glibc-rh1335925-2.patch b/SOURCES/glibc-rh1335925-2.patch new file mode 100644 index 00000000..253d124e --- /dev/null +++ b/SOURCES/glibc-rh1335925-2.patch @@ -0,0 +1,34 @@ +Backport of this upstream commit, with ports/ readded to the path. + +commit 14d623bcd178d336b47fdb4f0c973720d56d907c +Author: Szabolcs Nagy +Date: Thu Jul 9 09:39:51 2015 +0100 + + [AArch64][BZ 18400] fix elf_prpsinfo in procfs.h + + Kernel uses int pr_uid, pr_gid, but glibc used unsigned short. + + This is an ABI breaking change, but the size and alignment of + the struct and the layout of other members is not changed and + there is no known usage of pr_uid and pr_gid so it is expected + to be safe. + + [BZ #18400] + * sysdeps/unix/sysv/linux/aarch64/sys/procfs.h (struct elf_prpsinfo): + Fix pr_uid and pr_gid members. + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/sys/procfs.h b/ports/sysdeps/unix/sysv/linux/aarch64/sys/procfs.h +index cf5e76c..ecc65ab 100644 +--- a/ports/sysdeps/unix/sysv/linux/aarch64/sys/procfs.h ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/sys/procfs.h +@@ -91,8 +91,8 @@ struct elf_prpsinfo + char pr_zomb; /* Zombie. */ + char pr_nice; /* Nice val. */ + unsigned long int pr_flag; /* Flags. */ +- unsigned short int pr_uid; +- unsigned short int pr_gid; ++ unsigned int pr_uid; ++ unsigned int pr_gid; + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* Filename of executable. */ diff --git a/SOURCES/glibc-rh1335925-3.patch b/SOURCES/glibc-rh1335925-3.patch new file mode 100644 index 00000000..d4efbdc2 --- /dev/null +++ b/SOURCES/glibc-rh1335925-3.patch @@ -0,0 +1,39 @@ +Backport of this upstream commit, with ports/ readded to the path. + +commit b8528e771c0f31ebb8ac2470e2cf7ee9a50693e2 +Author: Szabolcs Nagy +Date: Thu Jul 9 09:53:30 2015 +0100 + + [AArch64][BZ 18648] change greg_t definition in ucontext.h + + This is an ABI breaking change, but + + typedef int greg_t; + + is not a useful definition on aarch64. + + greg_t is usually used for defining gregset_t which is used + in mcontext_t. The general registers in mcontext_t can only + be accessed by target specific code and on aarch64 greg_t + is not needed for that so this change is not supposed to break + existing code, just fix the definition. + + [BZ #18648] + * sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h (greg_t): Change the + definition to elf_greg_t. + + (Added another BZ entry that was missed in the previous commit). + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h b/ports/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h +index db7a7c1..e7268ce 100644 +--- a/ports/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h +@@ -29,7 +29,7 @@ + included in . */ + #include + +-typedef int greg_t; ++typedef elf_greg_t greg_t; + + /* Container for all general registers. */ + typedef elf_gregset_t gregset_t; diff --git a/SOURCES/glibc-rh1335925-4.patch b/SOURCES/glibc-rh1335925-4.patch new file mode 100644 index 00000000..593f31ac --- /dev/null +++ b/SOURCES/glibc-rh1335925-4.patch @@ -0,0 +1,142 @@ +Backport of this upstream commit, with ports/ readded to the path. + +commit 2b1d7148e3664eeb177ae2fc91bf282d75da7623 +Author: Szabolcs Nagy +Date: Mon Jul 6 12:46:43 2015 +0100 + + [AArch64] make setcontext etc functions consistent with the kernel + + since + https://sourceware.org/ml/libc-alpha/2014-04/msg00006.html + setcontext etc is no longer tied to the kernel use of ucontext. + + in that patch the ucontext reserved space is not used consistently + with the kernel abi: the d8,d9 pair is saved in the slot of q8. + + this is ok (*context functions work together), but probably not + desirable (ucontexts created by the kernel and getcontext are + subtly different). + + the fix just replaces dN with qN in the save/restore code, which + does a bit more than needed (saves/restores the top half of qN that + is not callee saved), but this should not be an issue (and avoids + having to deal with endianness). + + (kernel fpsimd context layout: the first 64bit contains 0x210 the fpsimd + context size and 0x46508001 the FPSIMD_MAGIC, the second 64bit is for + fpsr and fpcr, and the rest is the 128bit q0..q31 registers). + + given d8=8.1, d9=9.1,... d15=15.1, the context created by getcontext is + + current: + + (gdb) x/40xg ctx.uc_mcontext.__reserved + 0x410df0 : 0x0000021046508001 0x0000000000000000 + 0x410e00 : 0x0000000000000000 0x0000000000000000 + 0x410e10 : 0x0000000000000000 0x0000000000000000 + 0x410e20 : 0x0000000000000000 0x0000000000000000 + 0x410e30 : 0x0000000000000000 0x0000000000000000 + 0x410e40 : 0x0000000000000000 0x0000000000000000 + 0x410e50 : 0x0000000000000000 0x0000000000000000 + 0x410e60 : 0x0000000000000000 0x0000000000000000 + 0x410e70 : 0x0000000000000000 0x0000000000000000 + 0x410e80 : 0x4020333333333333 0x4022333333333333 + 0x410e90 : 0x0000000000000000 0x0000000000000000 + 0x410ea0 : 0x4024333333333333 0x4026333333333333 + 0x410eb0 : 0x0000000000000000 0x0000000000000000 + 0x410ec0 : 0x4028333333333333 0x402a333333333333 + 0x410ed0 : 0x0000000000000000 0x0000000000000000 + 0x410ee0 : 0x402c333333333333 0x402e333333333333 + 0x410ef0 : 0x0000000000000000 0x0000000000000000 + 0x410f00 : 0x0000000000000000 0x0000000000000000 + 0x410f10 : 0x0000000000000000 0x0000000000000000 + 0x410f20 : 0x0000000000000000 0x0000000000000000 + + fixed: + + (gdb) x/40xg ctx.uc_mcontext.__reserved + 0x410d70 : 0x0000021046508001 0x0000000000000000 + 0x410d80 : 0x0000000000000000 0x0000000000000000 + 0x410d90 : 0x0000000000000000 0x0000000000000000 + 0x410da0 : 0x0000000000000000 0x0000000000000000 + 0x410db0 : 0x0000000000000000 0x0000000000000000 + 0x410dc0 : 0x0000000000000000 0x0000000000000000 + 0x410dd0 : 0x0000000000000000 0x0000000000000000 + 0x410de0 : 0x0000000000000000 0x0000000000000000 + 0x410df0 : 0x0000000000000000 0x0000000000000000 + 0x410e00 : 0x4020333333333333 0x0000000000000000 + 0x410e10 : 0x4022333333333333 0x0000000000000000 + 0x410e20 : 0x4024333333333333 0x0000000000000000 + 0x410e30 : 0x4026333333333333 0x0000000000000000 + 0x410e40 : 0x4028333333333333 0x0000000000000000 + 0x410e50 : 0x402a333333333333 0x0000000000000000 + 0x410e60 : 0x402c333333333333 0x0000000000000000 + 0x410e70 : 0x402e333333333333 0x0000000000000000 + 0x410e80 : 0x0000000000000000 0x0000000000000000 + 0x410e90 : 0x0000000000000000 0x0000000000000000 + 0x410ea0 : 0x0000000000000000 0x0000000000000000 + + 2015-07-06 Szabolcs Nagy + + * sysdeps/unix/sysv/linux/aarch64/getcontext.S (__getcontext): Use q + registers instead of d ones so the layout is kernel abi compatible. + * sysdeps/unix/sysv/linux/aarch64/setcontext.S (__setcontext): Likewise. + * sysdeps/unix/sysv/linux/aarch64/swapcontext.S (__swapcontext): + Likewise.# Please enter the commit message for your changes. Lines starting + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S b/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S +index adf8037..b72436f 100644 +--- a/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/getcontext.S +@@ -69,10 +69,10 @@ ENTRY(__getcontext) + + /* Fill in the FP SIMD context. */ + add x3, x2, #oV0 + 8 * SZVREG +- stp d8, d9, [x3], # 2 * SZVREG +- stp d10, d11, [x3], # 2 * SZVREG +- stp d12, d13, [x3], # 2 * SZVREG +- stp d14, d15, [x3], # 2 * SZVREG ++ stp q8, q9, [x3], # 2 * SZVREG ++ stp q10, q11, [x3], # 2 * SZVREG ++ stp q12, q13, [x3], # 2 * SZVREG ++ stp q14, q15, [x3], # 2 * SZVREG + + add x3, x2, oFPSR + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S b/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S +index ae67581..8d926f7 100644 +--- a/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/setcontext.S +@@ -97,10 +97,10 @@ ENTRY (__setcontext) + + /* Restore the FP SIMD context. */ + add x3, x2, #oV0 + 8 * SZVREG +- ldp d8, d9, [x3], #2 * SZVREG +- ldp d10, d11, [x3], #2 * SZVREG +- ldp d12, d13, [x3], #2 * SZVREG +- ldp d14, d15, [x3], #2 * SZVREG ++ ldp q8, q9, [x3], #2 * SZVREG ++ ldp q10, q11, [x3], #2 * SZVREG ++ ldp q12, q13, [x3], #2 * SZVREG ++ ldp q14, q15, [x3], #2 * SZVREG + + add x3, x2, oFPSR + +diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/swapcontext.S b/ports/sysdeps/unix/sysv/linux/aarch64/swapcontext.S +index f62fc11..05ad8d3 100644 +--- a/ports/sysdeps/unix/sysv/linux/aarch64/swapcontext.S ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/swapcontext.S +@@ -54,10 +54,10 @@ ENTRY(__swapcontext) + + /* Fill in the FP SIMD context. */ + add x3, x2, #oV0 + 8 * SZVREG +- stp d8, d9, [x3], #2 * SZVREG +- stp d10, d11, [x3], #2 * SZVREG +- stp d12, d13, [x3], #2 * SZVREG +- stp d14, d15, [x3], #2 * SZVREG ++ stp q8, q9, [x3], #2 * SZVREG ++ stp q10, q11, [x3], #2 * SZVREG ++ stp q12, q13, [x3], #2 * SZVREG ++ stp q14, q15, [x3], #2 * SZVREG + + add x3, x2, #oFPSR diff --git a/SOURCES/glibc-rh1337242.patch b/SOURCES/glibc-rh1337242.patch new file mode 100644 index 00000000..84ade8dc --- /dev/null +++ b/SOURCES/glibc-rh1337242.patch @@ -0,0 +1,61 @@ +commit b3a810d0d3d5c6ce7ddfb61321cd7971808ca703 +Author: Stefan Liebler +Date: Tue May 17 10:45:48 2016 +0200 + + Fix tst-cancel17/tst-cancelx17, which sometimes segfaults while exiting. + + The testcase tst-cancel[x]17 ends sometimes with a segmentation fault. + This happens in one of 10000 cases. Then the real testcase has already + exited with success and returned from do_test(). The segmentation fault + occurs after returning from main in _dl_fini(). + + In those cases, the aio_read(&a) was not canceled because the read + request was already in progress. In the meanwhile aio_write(ap) wrote + something to the pipe and the read request is able to read the + requested byte. + The read request hasn't finished before returning from do_test(). + After it finishes, it writes the return value and error code from the + read syscall to the struct aiocb a, which lies on the stack of do_test. + The stack of the subsequent function call of _dl_fini or _dl_sort_fini, + which is inlined in _dl_fini is corrupted. + + In case of S390, it reads a zero and decrements it by 1: + unsigned int k = nmaps - 1; + struct link_map **runp = maps[k]->l_initfini; + The load from unmapped memory leads to the segmentation fault. + The stack corruption also happens on other architectures. + I saw them e.g. on x86 and ppc, too. + + This patch adds an aio_suspend call to ensure, that the read request + is finished before returning from do_test(). + + ChangeLog: + + * nptl/tst-cancel17.c (do_test): Wait for finishing aio_read(&a). + +diff --git a/nptl/tst-cancel17.c b/nptl/tst-cancel17.c +index fb89292..eedd28e 100644 +--- a/nptl/tst-cancel17.c ++++ b/nptl/tst-cancel17.c +@@ -333,6 +333,22 @@ do_test (void) + + puts ("early cancellation succeeded"); + ++ if (ap == &a2) ++ { ++ /* The aio_read(&a) was not canceled because the read request was ++ already in progress. In the meanwhile aio_write(ap) wrote something ++ to the pipe and the read request either has already been finished or ++ is able to read the requested byte. ++ Wait for the read request before returning from this function because ++ the return value and error code from the read syscall will be written ++ to the struct aiocb a, which lies on the stack of this function. ++ Otherwise the stack from subsequent function calls - e.g. _dl_fini - ++ will be corrupted, which can lead to undefined behaviour like a ++ segmentation fault. */ ++ const struct aiocb *l[1] = { &a }; ++ TEMP_FAILURE_RETRY (aio_suspend(l, 1, NULL)); ++ } ++ + return 0; + } diff --git a/SOURCES/glibc-rh1338672.patch b/SOURCES/glibc-rh1338672.patch new file mode 100644 index 00000000..aa72e26b --- /dev/null +++ b/SOURCES/glibc-rh1338672.patch @@ -0,0 +1,294 @@ +commit 3375cfafa7961c6ae0e509c31c3b3cef9ad1f03d +Author: Florian Weimer +Date: Mon May 23 19:43:09 2016 +0200 + + Make padding in struct sockaddr_storage explicit [BZ #20111] + + This avoids aliasing issues with GCC 6 in -fno-strict-aliasing + mode. (With implicit padding, not all data is copied.) + + This change makes it explicit that struct sockaddr_storage is + only 126 bytes large on m68k (unlike elsewhere, where we end up + with the requested 128 bytes). The new test case makes sure that + this does not happen on other architectures. + +[modified by DJ Delorie for RHEL] + +diff -rupN a/bits/sockaddr.h b/bits/sockaddr.h +--- a/bits/sockaddr.h 2012-12-24 22:02:13.000000000 -0500 ++++ b/bits/sockaddr.h 2017-03-01 16:54:46.606261055 -0500 +@@ -1,4 +1,4 @@ +-/* Definition of `struct sockaddr_*' common members. Generic/4.2 BSD version. ++/* Definition of struct sockaddr_* common members and sizes, generic version. + Copyright (C) 1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -36,4 +36,7 @@ typedef unsigned short int sa_family_t; + + #define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int)) + ++/* Size of struct sockaddr_storage. */ ++#define _SS_SIZE 128 ++ + #endif /* bits/sockaddr.h */ +diff -rupN a/bits/socket.h b/bits/socket.h +--- a/bits/socket.h 2012-12-24 22:02:13.000000000 -0500 ++++ b/bits/socket.h 2017-03-01 16:38:24.861208175 -0500 +@@ -133,20 +133,20 @@ struct sockaddr + + + /* Structure large enough to hold any socket address (with the historical +- exception of AF_UNIX). We reserve 128 bytes. */ ++ exception of AF_UNIX). */ + #if ULONG_MAX > 0xffffffff + # define __ss_aligntype __uint64_t + #else + # define __ss_aligntype __uint32_t + #endif +-#define _SS_SIZE 128 +-#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype))) ++#define _SS_PADSIZE \ ++ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + + struct sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ +- __ss_aligntype __ss_align; /* Force desired alignment. */ + char __ss_padding[_SS_PADSIZE]; ++ __ss_aligntype __ss_align; /* Force desired alignment. */ + }; + + +diff -rupN a/inet/Makefile b/inet/Makefile +--- a/inet/Makefile 2017-03-01 16:06:12.000000000 -0500 ++++ b/inet/Makefile 2017-03-01 16:55:21.919485376 -0500 +@@ -51,7 +51,7 @@ aux := check_pf check_native ifreq + + tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ + tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ +- tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-deadline ++ tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-deadline tst-sockaddr + + # tst-deadline must be linked statically so that we can access + # internal functions. +@@ -89,6 +89,8 @@ CFLAGS-either_hton.c = -fexceptions + CFLAGS-getnetgrent.c = -fexceptions + CFLAGS-getnetgrent_r.c = -fexceptions + ++CFLAGS-tst-sockaddr.c = -fno-strict-aliasing ++ + endif + + ifeq ($(build-static-nss),yes) +diff -rupN a/inet/tst-sockaddr.c b/inet/tst-sockaddr.c +--- a/inet/tst-sockaddr.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/inet/tst-sockaddr.c 2017-03-01 16:38:24.869208278 -0500 +@@ -0,0 +1,125 @@ ++/* Tests for socket address type definitions. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* This is a copy of the previous definition of struct ++ sockaddr_storage. It is not equal to the old value of _SS_SIZE ++ (128) on all architectures. We must stay compatible with the old ++ definition. */ ++ ++#define OLD_REFERENCE_SIZE 128 ++#define OLD_PADSIZE (OLD_REFERENCE_SIZE - (2 * sizeof (__ss_aligntype))) ++struct sockaddr_storage_old ++ { ++ __SOCKADDR_COMMON (old_); ++ __ss_aligntype old_align; ++ char old_padding[OLD_PADSIZE]; ++ }; ++ ++static bool errors; ++ ++static void ++check (bool ok, const char *message) ++{ ++ if (!ok) ++ { ++ printf ("error: failed check: %s\n", message); ++ errors = true; ++ } ++} ++ ++static int ++do_test (void) ++{ ++ check (OLD_REFERENCE_SIZE >= _SS_SIZE, ++ "old target size is not smaller than actual size"); ++ check (sizeof (struct sockaddr_storage_old) ++ == sizeof (struct sockaddr_storage), ++ "old and new sizes match"); ++ check (__alignof (struct sockaddr_storage_old) ++ == __alignof (struct sockaddr_storage), ++ "old and new alignment matches"); ++ check (offsetof (struct sockaddr_storage_old, old_family) ++ == offsetof (struct sockaddr_storage, ss_family), ++ "old and new family offsets match"); ++ check (sizeof (struct sockaddr_storage) == _SS_SIZE, ++ "struct sockaddr_storage size"); ++ ++ /* Check for lack of holes in the struct definition. */ ++ check (offsetof (struct sockaddr_storage, __ss_padding) ++ == __SOCKADDR_COMMON_SIZE, ++ "implicit padding before explicit padding"); ++ check (offsetof (struct sockaddr_storage, __ss_align) ++ == __SOCKADDR_COMMON_SIZE ++ + sizeof (((struct sockaddr_storage) {}).__ss_padding), ++ "implicit padding before explicit padding"); ++ ++ /* Check for POSIX compatibility requirements between struct ++ sockaddr_storage and struct sockaddr_un. */ ++ check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_un), ++ "sockaddr_storage is at least as large as sockaddr_un"); ++ check (__alignof (struct sockaddr_storage) ++ >= __alignof (struct sockaddr_un), ++ "sockaddr_storage is at least as aligned as sockaddr_un"); ++ check (offsetof (struct sockaddr_storage, ss_family) ++ == offsetof (struct sockaddr_un, sun_family), ++ "family offsets match"); ++ ++ /* Check that the compiler preserves bit patterns in aggregate ++ copies. Based on . */ ++ check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_in), ++ "sockaddr_storage is at least as large as sockaddr_in"); ++ { ++ struct sockaddr_storage addr; ++ memset (&addr, 0, sizeof (addr)); ++ { ++ struct sockaddr_in *sinp = (struct sockaddr_in *)&addr; ++ sinp->sin_family = AF_INET; ++ sinp->sin_addr.s_addr = htonl (INADDR_LOOPBACK); ++ sinp->sin_port = htons (80); ++ } ++ struct sockaddr_storage copy; ++ copy = addr; ++ ++ struct sockaddr_storage *p = malloc (sizeof (*p)); ++ if (p == NULL) ++ { ++ printf ("error: malloc: %m\n"); ++ return 1; ++ } ++ *p = copy; ++ const struct sockaddr_in *sinp = (const struct sockaddr_in *)p; ++ check (sinp->sin_family == AF_INET, "sin_family"); ++ check (sinp->sin_addr.s_addr == htonl (INADDR_LOOPBACK), "sin_addr"); ++ check (sinp->sin_port == htons (80), "sin_port"); ++ free (p); ++ } ++ ++ return errors; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -rupN a/sysdeps/mach/hurd/bits/socket.h b/sysdeps/mach/hurd/bits/socket.h +--- a/sysdeps/mach/hurd/bits/socket.h 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/mach/hurd/bits/socket.h 2017-03-01 16:38:24.873208329 -0500 +@@ -156,20 +156,20 @@ struct sockaddr + + + /* Structure large enough to hold any socket address (with the historical +- exception of AF_UNIX). We reserve 128 bytes. */ ++ exception of AF_UNIX). */ + #if ULONG_MAX > 0xffffffff + # define __ss_aligntype __uint64_t + #else + # define __ss_aligntype __uint32_t + #endif +-#define _SS_SIZE 128 +-#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype))) ++#define _SS_PADSIZE \ ++ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + + struct sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ +- __ss_aligntype __ss_align; /* Force desired alignment. */ + char __ss_padding[_SS_PADSIZE]; ++ __ss_aligntype __ss_align; /* Force desired alignment. */ + }; + + +diff -rupN a/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h b/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h +--- a/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/bsd/bsd4.4/bits/sockaddr.h 2017-03-01 17:30:34.962261748 -0500 +@@ -37,6 +37,9 @@ typedef unsigned char sa_family_t; + + #define __SOCKADDR_COMMON_SIZE (2 * sizeof (unsigned char)) + ++/* Size of struct sockaddr_storage. */ ++#define _SS_SIZE 128 ++ + #define _HAVE_SA_LEN 1 /* We have the sa_len field. */ + + #endif /* bits/sockaddr.h */ +diff -rupN a/sysdeps/unix/bsd/bsd4.4/bits/socket.h b/sysdeps/unix/bsd/bsd4.4/bits/socket.h +--- a/sysdeps/unix/bsd/bsd4.4/bits/socket.h 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/bsd/bsd4.4/bits/socket.h 2017-03-01 17:31:23.790246360 -0500 +@@ -142,14 +142,13 @@ struct sockaddr + #else + # define __ss_aligntype __uint32_t + #endif +-#define _SS_SIZE 128 +-#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype))) ++#define _SS_PADSIZE (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + + struct sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ +- __ss_aligntype __ss_align; /* Force desired alignment. */ + char __ss_padding[_SS_PADSIZE]; ++ __ss_aligntype __ss_align; /* Force desired alignment. */ + }; + + +diff -rupN a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +--- a/sysdeps/unix/sysv/linux/bits/socket.h 2017-03-01 16:06:12.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/bits/socket.h 2017-03-01 16:38:26.993235460 -0500 +@@ -155,16 +155,16 @@ struct sockaddr + + + /* Structure large enough to hold any socket address (with the historical +- exception of AF_UNIX). We reserve 128 bytes. */ ++ exception of AF_UNIX). */ + #define __ss_aligntype unsigned long int +-#define _SS_SIZE 128 +-#define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype))) ++#define _SS_PADSIZE \ ++ (_SS_SIZE - __SOCKADDR_COMMON_SIZE - sizeof (__ss_aligntype)) + + struct sockaddr_storage + { + __SOCKADDR_COMMON (ss_); /* Address family, etc. */ +- __ss_aligntype __ss_align; /* Force desired alignment. */ + char __ss_padding[_SS_PADSIZE]; ++ __ss_aligntype __ss_align; /* Force desired alignment. */ + }; diff --git a/SOURCES/glibc-rh1346397.patch b/SOURCES/glibc-rh1346397.patch new file mode 100644 index 00000000..0a252ae6 --- /dev/null +++ b/SOURCES/glibc-rh1346397.patch @@ -0,0 +1,84 @@ +Based on the following commits: + +commit 2c41b52901331f5c761015af786a3976e225d779 +Author: Florian Weimer +Date: Mon Jun 13 13:08:39 2016 +0200 + + debug/tst-longjmp_chk2: Make signal handler more conservative [BZ #20248] + + Currently, printf needs more stack space than what is available with + SIGSTKSZ. This commit use the the write system call directly instead. + + Also use sig_atomic_t for the “pass†variable (for general + correctness), and restore signal handlers to their defaults, to avoid + masking crashes. + +commit 5896c8bdd9f73cdc816a96e107ca1f7a6bc6921e +Author: Mike Frysinger +Date: Sun Dec 29 16:30:35 2013 -0500 + + tst-longjmp_chk2: add comments/sanity check + + If the longjmp checking code is slightly broken, this code can loop + forever which isn't too helpful. Add a sanity check to keep that + from happening. + + Signed-off-by: Mike Frysinger + +Index: b/debug/tst-longjmp_chk2.c +=================================================================== +--- a/debug/tst-longjmp_chk2.c ++++ b/debug/tst-longjmp_chk2.c +@@ -4,27 +4,36 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + + + static jmp_buf mainloop; + static sigset_t mainsigset; +-static int pass; ++static volatile sig_atomic_t pass; + ++static void ++write_message (const char *message) ++{ ++ ssize_t unused __attribute__ ((unused)); ++ for (int i = 0; i < pass; ++i) ++ unused = write (STDOUT_FILENO, " ", 1); ++ unused = write (STDOUT_FILENO, message, strlen (message)); ++} + + static void + stackoverflow_handler (int sig) + { + stack_t altstack; + pass++; ++ assert (pass < 5); + sigaltstack (NULL, &altstack); +- /* Using printf is not really kosher in signal handlers but we know +- it will work. */ +- printf ("%*sin signal handler\n", pass, ""); ++ write_message ("in signal handler\n"); + if (altstack.ss_flags & SS_ONSTACK) +- printf ("%*son alternate stack\n", pass, ""); ++ write_message ("on alternate stack\n"); + siglongjmp (mainloop, pass); + } + +@@ -107,6 +116,11 @@ do_test (void) + else + printf ("disabling alternate stack succeeded \n"); + ++ /* Restore the signal handlers, in case we trigger a crash after the ++ tests above. */ ++ signal (SIGBUS, SIG_DFL); ++ signal (SIGSEGV, SIG_DFL); ++ + return 0; + } diff --git a/SOURCES/glibc-rh1347277.patch b/SOURCES/glibc-rh1347277.patch new file mode 100644 index 00000000..5353402a --- /dev/null +++ b/SOURCES/glibc-rh1347277.patch @@ -0,0 +1,20 @@ +This patch fixes a compile-time type mismatch. No upstream +patch; this originated in Fedora and upstream has changed the +underlying code in a different way. + +diff -rup a/malloc/hooks.c b/malloc/hooks.c +--- a/malloc/hooks.c 2017-08-11 14:20:36.000000000 -0400 ++++ b/malloc/hooks.c 2017-08-11 15:43:15.939831964 -0400 +@@ -240,10 +240,10 @@ top_check(void) + (char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem))) + return 0; + +- mutex_unlock(&main_arena); ++ mutex_unlock(&main_arena.mutex); + malloc_printerr (check_action, "malloc: top chunk is corrupt", t, + &main_arena); +- mutex_lock(&main_arena); ++ mutex_lock(&main_arena.mutex); + + /* Try to set up a new top chunk. */ + brk = MORECORE(0); diff --git a/SOURCES/glibc-rh1348000.patch b/SOURCES/glibc-rh1348000.patch new file mode 100644 index 00000000..8c4c5398 --- /dev/null +++ b/SOURCES/glibc-rh1348000.patch @@ -0,0 +1,138 @@ +From 265cbed8e73b23e3b38ada6cc42482c53a216224 Mon Sep 17 00:00:00 2001 +From: James Lemke +Date: Tue, 19 May 2015 12:10:26 -0700 +Subject: [PATCH] Fix for test "malloc_usable_size: expected 7 but got 11" + +[BZ #17581] The checking chain of unused chunks was terminated by a hash of + the block pointer, which was sometimes confused with the chunk length byte. + We now avoid using a length byte equal to the magic byte. + + +diff -rup a/malloc/hooks.c b/malloc/hooks.c +--- a/malloc/hooks.c 2017-08-01 16:19:28.000000000 -0400 ++++ b/malloc/hooks.c 2017-08-01 16:42:23.651295223 -0400 +@@ -87,11 +87,22 @@ __malloc_check_init() + overruns. The goal here is to avoid obscure crashes due to invalid + usage, unlike in the MALLOC_DEBUG code. */ + +-#define MAGICBYTE(p) ( ( ((size_t)p >> 3) ^ ((size_t)p >> 11)) & 0xFF ) ++static unsigned char ++magicbyte (const void *p) ++{ ++ unsigned char magic; ++ ++ magic = (((uintptr_t) p >> 3) ^ ((uintptr_t) p >> 11)) & 0xFF; ++ /* Do not return 1. See the comment in mem2mem_check(). */ ++ if (magic == 1) ++ ++magic; ++ return magic; ++} ++ + +-/* Visualize the chunk as being partitioned into blocks of 256 bytes from the +- highest address of the chunk, downwards. The beginning of each block tells +- us the size of the previous block, up to the actual size of the requested ++/* Visualize the chunk as being partitioned into blocks of 255 bytes from the ++ highest address of the chunk, downwards. The end of each block tells ++ us the size of that block, up to the actual size of the requested + memory. Our magic byte is right at the end of the requested size, so we + must reach it with this iteration, otherwise we have witnessed a memory + corruption. */ +@@ -100,7 +111,7 @@ malloc_check_get_size(mchunkptr p) + { + size_t size; + unsigned char c; +- unsigned char magic = MAGICBYTE(p); ++ unsigned char magic = magicbyte (p); + + assert(using_malloc_checking == 1); + +@@ -120,29 +131,35 @@ malloc_check_get_size(mchunkptr p) + } + + /* Instrument a chunk with overrun detector byte(s) and convert it +- into a user pointer with requested size sz. */ ++ into a user pointer with requested size req_sz. */ + + static void* + internal_function +-mem2mem_check(void *ptr, size_t sz) ++mem2mem_check(void *ptr, size_t req_sz) + { + mchunkptr p; + unsigned char* m_ptr = ptr; +- size_t i; ++ size_t max_sz, block_sz, i; ++ unsigned char magic; + + if (!ptr) + return ptr; + p = mem2chunk(ptr); +- for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1); +- i > sz; +- i -= 0xFF) { +- if(i-sz < 0x100) { +- m_ptr[i] = (unsigned char)(i-sz); +- break; ++ magic = magicbyte (p); ++ max_sz = chunksize (p) - 2 * SIZE_SZ; ++ if (!chunk_is_mmapped (p)) ++ max_sz += SIZE_SZ; ++ for (i = max_sz - 1; i > req_sz; i -= block_sz) ++ { ++ block_sz = MIN (i - req_sz, 0xff); ++ /* Don't allow the magic byte to appear in the chain of length bytes. ++ For the following to work, magicbyte cannot return 0x01. */ ++ if (block_sz == magic) ++ --block_sz; ++ ++ m_ptr[i] = block_sz; + } +- m_ptr[i] = 0xFF; +- } +- m_ptr[sz] = MAGICBYTE(p); ++ m_ptr[req_sz] = magic; + return (void*)m_ptr; + } + +@@ -159,10 +176,11 @@ mem2chunk_check(void* mem, unsigned char + + if(!aligned_OK(mem)) return NULL; + p = mem2chunk(mem); ++ sz = chunksize (p); ++ magic = magicbyte (p); + if (!chunk_is_mmapped(p)) { + /* Must be a chunk in conventional heap memory. */ + int contig = contiguous(&main_arena); +- sz = chunksize(p); + if((contig && + ((char*)p=(mp_.sbrk_base+main_arena.system_mem) )) || +@@ -171,9 +189,9 @@ mem2chunk_check(void* mem, unsigned char + (contig && (char*)prev_chunk(p)size & PREV_INUSE) || + ( (((unsigned long)p - p->prev_size) & page_mask) != 0 ) || +- ( (sz = chunksize(p)), ((p->prev_size + sz) & page_mask) != 0 ) ) ++ ((p->prev_size + sz) & page_mask) != 0) + return NULL; +- magic = MAGICBYTE(p); ++ + for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) { +- if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL; ++ if(c == 0 || sz < (c + 2 * SIZE_SZ)) ++ return NULL; + } + } + ((unsigned char*)p)[sz] ^= 0xFF; diff --git a/SOURCES/glibc-rh1349962.patch b/SOURCES/glibc-rh1349962.patch new file mode 100644 index 00000000..6cd5aeb1 --- /dev/null +++ b/SOURCES/glibc-rh1349962.patch @@ -0,0 +1,63 @@ +commit cfa8054fbb6212e64d54a3d4926972a6a20e3498 +Author: Andreas Schwab +Date: Tue Jan 15 14:36:09 2013 +0100 + + Hide reference to mktemp in libpthread + +diff --git a/include/stdlib.h b/include/stdlib.h +index 152c12fe9cb41509..edec46fa1ff4cc28 100644 +--- a/include/stdlib.h ++++ b/include/stdlib.h +@@ -78,6 +78,7 @@ extern struct drand48_data __libc_drand48_data attribute_hidden; + extern int __setenv (const char *__name, const char *__value, int __replace); + extern int __unsetenv (const char *__name); + extern int __clearenv (void); ++extern char *__mktemp (char *__template) __THROW __nonnull ((1)); + extern char *__canonicalize_file_name (const char *__name); + extern char *__realpath (const char *__name, char *__resolved); + extern int __ptsname_r (int __fd, char *__buf, size_t __buflen); +diff --git a/misc/Versions b/misc/Versions +index 64632f0bfa81b00a..ec5aea7b523e7041 100644 +--- a/misc/Versions ++++ b/misc/Versions +@@ -151,6 +151,7 @@ libc { + } + GLIBC_PRIVATE { + __madvise; ++ __mktemp; + __libc_ifunc_impl_list; + } + } +diff --git a/misc/mktemp.c b/misc/mktemp.c +index 05a07cb301f9506e..19824f01a11f9af9 100644 +--- a/misc/mktemp.c ++++ b/misc/mktemp.c +@@ -22,7 +22,7 @@ + The last six characters of TEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the filename unique. */ + char * +-mktemp (template) ++__mktemp (template) + char *template; + { + if (__gen_tempname (template, 0, 0, __GT_NOCREATE) < 0) +@@ -31,5 +31,6 @@ mktemp (template) + + return template; + } ++weak_alias (__mktemp, mktemp) + + link_warning (mktemp, "the use of `mktemp' is dangerous, better use `mkstemp'") +diff --git a/nptl/sem_open.c b/nptl/sem_open.c +index d87076e04a55cf71..a0c488b62ffebcc4 100644 +--- a/nptl/sem_open.c ++++ b/nptl/sem_open.c +@@ -334,7 +334,7 @@ sem_open (const char *name, int oflag, ...) + since the file must be opened with a specific mode. The + mode cannot later be set since then we cannot apply the + file create mask. */ +- if (mktemp (tmpfname) == NULL) ++ if (__mktemp (tmpfname) == NULL) + return SEM_FAILED; + + /* Open the file. Make sure we do not overwrite anything. */ diff --git a/SOURCES/glibc-rh1349964.patch b/SOURCES/glibc-rh1349964.patch new file mode 100644 index 00000000..ed85dc87 --- /dev/null +++ b/SOURCES/glibc-rh1349964.patch @@ -0,0 +1,33 @@ +commit 4712799fbb6812cc73f7bd9c8faa6e7b05c0f5ab +Author: Siddhesh Poyarekar +Date: Wed Nov 20 18:19:57 2013 +0530 + + Fix build warning in locarchive.c + +(With an adjustment for the non-upstream version of +glibc-rh1296297-1.patch.) + +diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c +index dd4a5d147f46b0d4..1eae271186bc80a9 100644 +--- a/locale/programs/locarchive.c ++++ b/locale/programs/locarchive.c +@@ -521,7 +521,7 @@ open_archive (struct locarhandle *ah, bool readonly) + int retry = 0; + size_t prefix_len = output_prefix ? strlen (output_prefix) : 0; + char fname[prefix_len + sizeof (ARCHIVE_NAME)]; +- char *archivefname = ah->fname; ++ const char *archivefname = ah->fname; + bool defaultfname = false; + + /* If ah has a non-NULL fname open that otherwise open the default. */ +@@ -530,8 +530,8 @@ open_archive (struct locarhandle *ah, bool readonly) + defaultfname = true; + archivefname = fname; + if (output_prefix) +- memcpy (archivefname, output_prefix, prefix_len); +- strcpy (archivefname + prefix_len, ARCHIVE_NAME); ++ memcpy (fname, output_prefix, prefix_len); ++ strcpy (fname + prefix_len, ARCHIVE_NAME); + } + + while (1) diff --git a/SOURCES/glibc-rh1350733-1.patch b/SOURCES/glibc-rh1350733-1.patch new file mode 100644 index 00000000..d9af9979 --- /dev/null +++ b/SOURCES/glibc-rh1350733-1.patch @@ -0,0 +1,244 @@ +The functions in locarchive.c cannot create files in non-default +locations. Rather than enhancing locarchive.c (and risk regressions +in localedef), this patch adapts build-locale-archive to use the +existing output_prefix configuration variable. + +Index: glibc-2.17-c758a686/releng/build-locale-archive.c +=================================================================== +--- glibc-2.17-c758a686.orig/releng/build-locale-archive.c ++++ glibc-2.17-c758a686/releng/build-locale-archive.c +@@ -92,23 +92,34 @@ xmalloc (size_t size) + return p; + } + ++static char * ++xasprintf (const char *format, ...) ++{ ++ va_list ap; ++ va_start (ap, format); ++ char *result; ++ if (vasprintf (&result, format, ap) < 0) ++ error (EXIT_FAILURE, errno, "could not format string"); ++ va_end (ap); ++ return result; ++} ++ + static void + open_tmpl_archive (struct locarhandle *ah) + { + struct stat64 st; + int fd; + struct locarhead head; +- const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname; + + /* Open the archive. We must have exclusive write access. */ +- fd = open64 (archivefname, O_RDONLY); ++ fd = open64 (tmpl_file, O_RDONLY); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open locale archive template file \"%s\"", +- archivefname); ++ tmpl_file); + + if (fstat64 (fd, &st) < 0) + error (EXIT_FAILURE, errno, "cannot stat locale archive template file \"%s\"", +- archivefname); ++ tmpl_file); + + /* Read the header. */ + if (TEMP_FAILURE_RETRY (read (fd, &head, sizeof (head))) != sizeof (head)) +@@ -253,12 +264,11 @@ compute_data (struct locarhandle *ah, st + + static int + fill_archive (struct locarhandle *tmpl_ah, +- const char *fname, + size_t install_langs_count, char *install_langs_list[], + size_t nlist, char *list[], + const char *primary) + { +- struct locarhandle ah; ++ struct locarhandle ah = {}; + struct locarhead *head; + int result = 0; + struct nameent *names; +@@ -338,9 +348,6 @@ fill_archive (struct locarhandle *tmpl_a + + /* Open the archive. This call never returns if we cannot + successfully open the archive. */ +- ah.fname = NULL; +- if (fname != NULL) +- ah.fname = fname; + open_archive (&ah, false); + + if (primary != NULL) +@@ -619,38 +626,39 @@ Usage: build-locale-archive [OPTION]... + \"de\" but also the aliases \"deutsch\"\n\ + and and \"german\" although the latter does not\n\ + start with \"de\".\n\ ++ --prefix=DIR Operate under the file system root DIR\n\ + \n\ +- If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\ +- where the glibc used expects these files are used by default.\n\ + "); + } + + int main (int argc, char *argv[]) + { +- char path[4096]; + DIR *dirp; + struct dirent64 *d; + struct stat64 st; + char *list[16384], *primary; + char *lang; + int install_langs_count = 0; +- int i; + char *install_langs_arg, *ila_start; + char **install_langs_list; + unsigned int cnt = 0; +- struct locarhandle tmpl_ah; +- char *new_locar_fname = NULL; +- size_t loc_path_len = strlen (loc_path); ++ struct locarhandle tmpl_ah = {}; + + while (1) + { + int c; + ++ enum ++ { ++ opt_prefix = 1000, ++ }; ++ + static struct option long_options[] = + { + {"help", no_argument, 0, 'h'}, + {"verbose", no_argument, 0, 'v'}, + {"install-langs", required_argument, 0, 'l'}, ++ {"prefix", required_argument, 0, opt_prefix}, + {0, 0, 0, 0} + }; + /* getopt_long stores the option index here. */ +@@ -721,6 +729,10 @@ int main (int argc, char *argv[]) + } + break; + ++ case opt_prefix: ++ output_prefix = optarg; ++ break; ++ + case '?': + /* getopt_long already printed an error message. */ + usage (); +@@ -730,23 +742,26 @@ int main (int argc, char *argv[]) + abort (); + } + } +- tmpl_ah.fname = NULL; +- if (optind < argc) +- tmpl_ah.fname = argv[optind]; +- if (optind + 1 < argc) +- new_locar_fname = argv[optind + 1]; ++ if (optind != argc) ++ { ++ usage (); ++ exit (1); ++ } ++ if (output_prefix) ++ { ++ tmpl_file = xasprintf ("%s%s", output_prefix, tmpl_file); ++ alias_file = xasprintf ("%s%s", output_prefix, alias_file); ++ locar_file = xasprintf ("%s%s", output_prefix, locar_file); ++ loc_path = xasprintf ("%s%s", output_prefix, loc_path); ++ } + if (verbose) + { +- if (tmpl_ah.fname) +- printf("input archive file specified on command line: %s\n", +- tmpl_ah.fname); +- else +- printf("using default input archive file.\n"); +- if (new_locar_fname) +- printf("output archive file specified on command line: %s\n", +- new_locar_fname); +- else +- printf("using default output archive file.\n"); ++ if (output_prefix != NULL) ++ printf ("output prefix: %s\n", output_prefix); ++ printf ("input archive file: %s\n", tmpl_file); ++ printf ("input alias file: %s\n", alias_file); ++ printf ("input locale directory prefix: %s\n", loc_path); ++ printf ("output archive file: %s\n", locar_file); + } + + dirp = opendir (loc_path); +@@ -754,11 +769,7 @@ int main (int argc, char *argv[]) + error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path); + + open_tmpl_archive (&tmpl_ah); +- +- if (new_locar_fname) +- unlink (new_locar_fname); +- else +- unlink (locar_file); ++ unlink (locar_file); + + primary = getenv ("LC_ALL"); + if (primary == NULL) +@@ -790,8 +801,6 @@ int main (int argc, char *argv[]) + } + } + +- memcpy (path, loc_path, loc_path_len); +- + while ((d = readdir64 (dirp)) != NULL) + { + if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0) +@@ -799,32 +808,25 @@ int main (int argc, char *argv[]) + if (strchr (d->d_name, '_') == NULL) + continue; + +- size_t d_name_len = strlen (d->d_name); +- if (loc_path_len + d_name_len + 1 > sizeof (path)) +- { +- error (0, 0, "too long filename \"%s\"", d->d_name); +- continue; +- } +- +- memcpy (path + loc_path_len, d->d_name, d_name_len + 1); ++ char *path = xasprintf ("%s%s", loc_path, d->d_name); + if (stat64 (path, &st) < 0) + { + error (0, errno, "cannot stat \"%s\"", path); ++ free (path); + continue; + } + if (! S_ISDIR (st.st_mode)) +- continue; ++ { ++ free (path); ++ continue; ++ } + if (cnt == 16384) + { + error (0, 0, "too many directories in \"%s\"", loc_path); ++ free (path); + break; + } +- list[cnt] = strdup (path); +- if (list[cnt] == NULL) +- { +- error (0, errno, "cannot add file to list \"%s\"", path); +- continue; +- } ++ list[cnt] = path; + if (primary != NULL && cnt > 0 && strcmp (primary, d->d_name) == 0) + { + char *p = list[0]; +@@ -836,7 +838,7 @@ int main (int argc, char *argv[]) + closedir (dirp); + /* Store the archive to the file specified as the second argument on the + command line or the default locale archive. */ +- fill_archive (&tmpl_ah, new_locar_fname, ++ fill_archive (&tmpl_ah, + install_langs_count, install_langs_list, + cnt, list, primary); + close_archive (&tmpl_ah); diff --git a/SOURCES/glibc-rh1366569.patch b/SOURCES/glibc-rh1366569.patch new file mode 100644 index 00000000..1fc66ae3 --- /dev/null +++ b/SOURCES/glibc-rh1366569.patch @@ -0,0 +1,16 @@ +Do not set initgroups. The commented-out setting reflects the +glibc default (derived from group). + +Index: b/releng/nsswitch.conf +=================================================================== +--- a/releng/nsswitch.conf ++++ b/releng/nsswitch.conf +@@ -33,7 +33,7 @@ + passwd: files sss + shadow: files sss + group: files sss +-initgroups: files ++#initgroups: files sss + + #hosts: db files nisplus nis dns + hosts: files dns diff --git a/SOURCES/glibc-rh1370630.patch b/SOURCES/glibc-rh1370630.patch new file mode 100644 index 00000000..de5b4dc1 --- /dev/null +++ b/SOURCES/glibc-rh1370630.patch @@ -0,0 +1,64 @@ +commit 4969890247d7d6a548f17641ed5a18f4b713d211 +Author: Alexandre Oliva +Date: Fri Nov 21 03:29:56 2014 -0200 + + BZ#14498: fix infinite loop in nss_db_getservbyname + + nss_db uses nss_files code for services, but a continue on protocol + mismatch that doesn't affect nss_files skipped the code that advanced + to the next db entry. Any one of these changes would suffice to fix + it, but fixing both makes them both safer to reuse elsewhere. + + for ChangeLog + + [BZ #14498] + * NEWS: Fixed. + * nss/nss_db/db-XXX.c (_nss_db_get##name##_r): Update hidx + after parsing line but before break_if_match. + * nss/nss_files/files-service (DB_LOOKUP): Don't "continue;" + if there is a protocol mismatch. + +Index: b/nss/nss_db/db-XXX.c +=================================================================== +--- a/nss/nss_db/db-XXX.c ++++ b/nss/nss_db/db-XXX.c +@@ -190,6 +190,12 @@ enum nss_status \ + char *p = memcpy (buffer, valstr, len); \ + \ + int err = parse_line (p, result, data, buflen, errnop EXTRA_ARGS); \ ++ \ ++ /* Advance before break_if_match, lest it uses continue to skip ++ to the next entry. */ \ ++ if ((hidx += hval2) >= header->dbs[i].hashsize) \ ++ hidx -= header->dbs[i].hashsize; \ ++ \ + if (err > 0) \ + { \ + status = NSS_STATUS_SUCCESS; \ +@@ -202,9 +208,6 @@ enum nss_status \ + status = NSS_STATUS_TRYAGAIN; \ + break; \ + } \ +- \ +- if ((hidx += hval2) >= header->dbs[i].hashsize) \ +- hidx -= header->dbs[i].hashsize; \ + } \ + \ + if (status == NSS_STATUS_NOTFOUND) \ +Index: b/nss/nss_files/files-service.c +=================================================================== +--- a/nss/nss_files/files-service.c ++++ b/nss/nss_files/files-service.c +@@ -44,8 +44,11 @@ DB_LOOKUP (servbyname, ':', + { + /* Must match both protocol (if specified) and name. */ + if (proto != NULL && strcmp (result->s_proto, proto)) +- continue; +- LOOKUP_NAME (s_name, s_aliases) ++ /* A continue statement here breaks nss_db, because it ++ bypasses advancing to the next db entry, and it ++ doesn't make nss_files any more efficient. */; ++ else ++ LOOKUP_NAME (s_name, s_aliases) + }, + const char *name, const char *proto) diff --git a/SOURCES/glibc-rh1372305.patch b/SOURCES/glibc-rh1372305.patch new file mode 100644 index 00000000..b6d7f22f --- /dev/null +++ b/SOURCES/glibc-rh1372305.patch @@ -0,0 +1,124 @@ +commit 983fd5c41ab7e5a5c33922259ca1ac99b3b413f8 +Author: Florian Weimer +Date: Sat Jun 11 12:07:14 2016 +0200 + + fopencookie: Mangle function pointers stored on the heap [BZ #20222] + +diff --git a/libio/iofopncook.c b/libio/iofopncook.c +index 5dcbe51f11182b68..b1c0d7f6ccc4db15 100644 +--- a/libio/iofopncook.c ++++ b/libio/iofopncook.c +@@ -46,11 +46,13 @@ _IO_cookie_read (fp, buf, size) + _IO_ssize_t size; + { + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; ++ cookie_read_function_t *read_cb = cfile->__io_functions.read; ++ PTR_DEMANGLE (read_cb); + +- if (cfile->__io_functions.read == NULL) ++ if (read_cb == NULL) + return -1; + +- return cfile->__io_functions.read (cfile->__cookie, buf, size); ++ return read_cb (cfile->__cookie, buf, size); + } + + static _IO_ssize_t +@@ -60,14 +62,16 @@ _IO_cookie_write (fp, buf, size) + _IO_ssize_t size; + { + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; ++ cookie_write_function_t *write_cb = cfile->__io_functions.write; ++ PTR_DEMANGLE (write_cb); + +- if (cfile->__io_functions.write == NULL) ++ if (write_cb == NULL) + { + fp->_flags |= _IO_ERR_SEEN; + return 0; + } + +- _IO_ssize_t n = cfile->__io_functions.write (cfile->__cookie, buf, size); ++ _IO_ssize_t n = write_cb (cfile->__cookie, buf, size); + if (n < size) + fp->_flags |= _IO_ERR_SEEN; + +@@ -81,9 +85,11 @@ _IO_cookie_seek (fp, offset, dir) + int dir; + { + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; ++ cookie_seek_function_t *seek_cb = cfile->__io_functions.seek; ++ PTR_DEMANGLE (seek_cb); + +- return ((cfile->__io_functions.seek == NULL +- || (cfile->__io_functions.seek (cfile->__cookie, &offset, dir) ++ return ((seek_cb == NULL ++ || (seek_cb (cfile->__cookie, &offset, dir) + == -1) + || offset == (_IO_off64_t) -1) + ? _IO_pos_BAD : offset); +@@ -94,11 +100,13 @@ _IO_cookie_close (fp) + _IO_FILE *fp; + { + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; ++ cookie_close_function_t *close_cb = cfile->__io_functions.close; ++ PTR_DEMANGLE (close_cb); + +- if (cfile->__io_functions.close == NULL) ++ if (close_cb == NULL) + return 0; + +- return cfile->__io_functions.close (cfile->__cookie); ++ return close_cb (cfile->__cookie); + } + + +@@ -140,6 +148,19 @@ static const struct _IO_jump_t _IO_cookie_jumps libio_vtable = { + }; + + ++/* Copy the callbacks from SOURCE to *TARGET, with pointer ++ mangling. */ ++static void ++set_callbacks (_IO_cookie_io_functions_t *target, ++ _IO_cookie_io_functions_t source) ++{ ++ PTR_MANGLE (source.read); ++ PTR_MANGLE (source.write); ++ PTR_MANGLE (source.seek); ++ PTR_MANGLE (source.close); ++ *target = source; ++} ++ + void + _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, + void *cookie, _IO_cookie_io_functions_t io_functions) +@@ -148,7 +169,7 @@ _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, + _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps; + + cfile->__cookie = cookie; +- cfile->__io_functions = io_functions; ++ set_callbacks (&cfile->__io_functions, io_functions); + + _IO_new_file_init_internal (&cfile->__fp); + +@@ -223,14 +244,14 @@ _IO_old_cookie_seek (fp, offset, dir) + int dir; + { + struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp; +- int (*seek) (_IO_FILE *, _IO_off_t, int); +- int ret; ++ int (*seek_cb) (_IO_FILE *, _IO_off_t, int) ++ = (int (*) (_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek;; ++ PTR_DEMANGLE (seek_cb); + +- seek = (int (*)(_IO_FILE *, _IO_off_t, int)) cfile->__io_functions.seek; +- if (seek == NULL) ++ if (seek_cb == NULL) + return _IO_pos_BAD; + +- ret = seek (cfile->__cookie, offset, dir); ++ int ret = seek_cb (cfile->__cookie, offset, dir); + + return (ret == -1) ? _IO_pos_BAD : ret; + } diff --git a/SOURCES/glibc-rh1374652.patch b/SOURCES/glibc-rh1374652.patch new file mode 100644 index 00000000..c12441f6 --- /dev/null +++ b/SOURCES/glibc-rh1374652.patch @@ -0,0 +1,1212 @@ +From 8f5e8b01a1da2a207228f2072c934fa5918554b8 Mon Sep 17 00:00:00 2001 +From: Joseph Myers +Date: Fri, 4 Dec 2015 20:36:28 +0000 +Subject: [PATCH] Fix nan functions handling of payload strings (bug 16961, bug + 16962). + +The nan, nanf and nanl functions handle payload strings by doing e.g.: + + if (tagp[0] != '\0') + { + char buf[6 + strlen (tagp)]; + sprintf (buf, "NAN(%s)", tagp); + return strtod (buf, NULL); + } + +This is an unbounded stack allocation based on the length of the +argument. Furthermore, if the argument starts with an n-char-sequence +followed by ')', that n-char-sequence is wrongly treated as +significant for determining the payload of the resulting NaN, when ISO +C says the call should be equivalent to strtod ("NAN", NULL), without +being affected by that initial n-char-sequence. This patch fixes both +those problems by using the __strtod_nan etc. functions recently +factored out of strtod etc. for that purpose, with those functions +being exported from libc at version GLIBC_PRIVATE. + +Tested for x86_64, x86, mips64 and powerpc. + + [BZ #16961] + [BZ #16962] + * math/s_nan.c (__nan): Use __strtod_nan instead of constructing a + string on the stack for strtod. + * math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing + a string on the stack for strtof. + * math/s_nanl.c (__nanl): Use __strtold_nan instead of + constructing a string on the stack for strtold. + * stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and + __strtold_nan to GLIBC_PRIVATE. + * math/test-nan-overflow.c: New file. + * math/test-nan-payload.c: Likewise. + * math/Makefile (tests): Add test-nan-overflow and + test-nan-payload. + +From e02cabecf0d025ec4f4ddee290bdf7aadb873bb3 Mon Sep 17 00:00:00 2001 +From: Joseph Myers +Date: Tue, 24 Nov 2015 22:24:52 +0000 +Subject: [PATCH] Refactor strtod parsing of NaN payloads. + +The nan* functions handle their string argument by constructing a +NAN(...) string on the stack as a VLA and passing it to strtod +functions. + +This approach has problems discussed in bug 16961 and bug 16962: the +stack usage is unbounded, and it gives incorrect results in certain +cases where the argument is not a valid n-char-sequence. + +The natural fix for both issues is to refactor the NaN payload parsing +out of strtod into a separate function that the nan* functions can +call directly, so that no temporary string needs constructing on the +stack at all. This patch does that refactoring in preparation for +fixing those bugs (but without actually using the new functions from +nan* - which will also require exporting them from libc at version +GLIBC_PRIVATE). This patch is not intended to change any user-visible +behavior, so no tests are added (fixes for the above bugs will of +course add tests for them). + +This patch builds on my recent fixes for strtol and strtod issues in +Turkish locales. Given those fixes, the parsing of NaN payloads is +locale-independent; thus, the new functions do not need to take a +locale_t argument. + +Tested for x86_64, x86, mips64 and powerpc. + + * stdlib/strtod_nan.c: New file. + * stdlib/strtod_nan_double.h: Likewise. + * stdlib/strtod_nan_float.h: Likewise. + * stdlib/strtod_nan_main.c: Likewise. + * stdlib/strtod_nan_narrow.h: Likewise. + * stdlib/strtod_nan_wide.h: Likewise. + * stdlib/strtof_nan.c: Likewise. + * stdlib/strtold_nan.c: Likewise. + * sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise. + * sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise. + * sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise. + * wcsmbs/wcstod_nan.c: Likewise. + * wcsmbs/wcstof_nan.c: Likewise. + * wcsmbs/wcstold_nan.c: Likewise. + * stdlib/Makefile (routines): Add strtof_nan, strtod_nan and + strtold_nan. + * wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and + wcstof_nan. + * include/stdlib.h (__strtof_nan): Declare and use + libc_hidden_proto. + (__strtod_nan): Likewise. + (__strtold_nan): Likewise. + (__wcstof_nan): Likewise. + (__wcstod_nan): Likewise. + (__wcstold_nan): Likewise. + * include/wchar.h (____wcstoull_l_internal): Declare. + * stdlib/strtod_l.c: Do not include . + (____strtoull_l_internal): Remove declaration. + (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + (STRTOULL): Likewise. + (____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload. + * stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration. + (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define + macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define + macro. + (SET_MANTISSA): Remove macro. + * sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro. + (SET_MANTISSA): Remove macro. + * wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration. + * wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise. + * wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise. + +diff -rupN a/include/stdlib.h b/include/stdlib.h +--- a/include/stdlib.h 2017-03-02 16:34:01.000000000 -0500 ++++ b/include/stdlib.h 2017-03-02 16:45:05.457639119 -0500 +@@ -193,6 +193,24 @@ libc_hidden_proto (strtoll) + libc_hidden_proto (strtoul) + libc_hidden_proto (strtoull) + ++extern float __strtof_nan (const char *, char **, char) internal_function; ++extern double __strtod_nan (const char *, char **, char) internal_function; ++extern long double __strtold_nan (const char *, char **, char) ++ internal_function; ++extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t) ++ internal_function; ++ ++libc_hidden_proto (__strtof_nan) ++libc_hidden_proto (__strtod_nan) ++libc_hidden_proto (__strtold_nan) ++libc_hidden_proto (__wcstof_nan) ++libc_hidden_proto (__wcstod_nan) ++libc_hidden_proto (__wcstold_nan) ++ + extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt, + int *__restrict __sign); + extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt, +diff -rupN a/include/wchar.h b/include/wchar.h +--- a/include/wchar.h 2012-12-24 22:02:13.000000000 -0500 ++++ b/include/wchar.h 2017-03-02 16:45:05.461639109 -0500 +@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull + __restrict __endptr, + int __base, + int __group) __THROW; ++extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, ++ wchar_t **, int, int, ++ __locale_t); + libc_hidden_proto (__wcstof_internal) + libc_hidden_proto (__wcstod_internal) + libc_hidden_proto (__wcstold_internal) +diff -rupN a/math/Makefile b/math/Makefile +--- a/math/Makefile 2017-03-02 16:34:02.000000000 -0500 ++++ b/math/Makefile 2017-03-02 16:44:30.659725844 -0500 +@@ -88,7 +88,8 @@ long-c-yes = $(calls:=l) + tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \ + test-misc test-fpucw tst-definitions test-tgmath test-tgmath-ret \ + bug-nextafter bug-nexttoward bug-tgmath1 test-tgmath-int \ +- test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 ++ test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 \ ++ test-nan-overflow test-nan-payload + # We do the `long double' tests only if this data type is available and + # distinct from `double'. + test-longdouble-yes = test-ldouble test-ildoubl +diff -rupN a/math/s_nan.c b/math/s_nan.c +--- a/math/s_nan.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/math/s_nan.c 2017-03-02 16:43:01.680999065 -0500 +@@ -28,14 +28,7 @@ + double + __nan (const char *tagp) + { +- if (tagp[0] != '\0') +- { +- char buf[6 + strlen (tagp)]; +- sprintf (buf, "NAN(%s)", tagp); +- return strtod (buf, NULL); +- } +- +- return NAN; ++ return __strtod_nan (tagp, NULL, 0); + } + weak_alias (__nan, nan) + #ifdef NO_LONG_DOUBLE +diff -rupN a/math/s_nanf.c b/math/s_nanf.c +--- a/math/s_nanf.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/math/s_nanf.c 2017-03-02 16:43:01.683999054 -0500 +@@ -28,13 +28,6 @@ + float + __nanf (const char *tagp) + { +- if (tagp[0] != '\0') +- { +- char buf[6 + strlen (tagp)]; +- sprintf (buf, "NAN(%s)", tagp); +- return strtof (buf, NULL); +- } +- +- return NAN; ++ return __strtof_nan (tagp, NULL, 0); + } + weak_alias (__nanf, nanf) +diff -rupN a/math/s_nanl.c b/math/s_nanl.c +--- a/math/s_nanl.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/math/s_nanl.c 2017-03-02 16:43:01.686999044 -0500 +@@ -28,13 +28,6 @@ + long double + __nanl (const char *tagp) + { +- if (tagp[0] != '\0') +- { +- char buf[6 + strlen (tagp)]; +- sprintf (buf, "NAN(%s)", tagp); +- return strtold (buf, NULL); +- } +- +- return NAN; ++ return __strtold_nan (tagp, NULL, 0); + } + weak_alias (__nanl, nanl) +diff -rupN a/math/test-nan-overflow.c b/math/test-nan-overflow.c +--- a/math/test-nan-overflow.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/math/test-nan-overflow.c 2017-03-02 16:43:01.689999033 -0500 +@@ -0,0 +1,66 @@ ++/* Test nan functions stack overflow (bug 16962). ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#define STACK_LIM 1048576 ++#define STRING_SIZE (2 * STACK_LIM) ++ ++static int ++do_test (void) ++{ ++ int result = 0; ++ struct rlimit lim; ++ getrlimit (RLIMIT_STACK, &lim); ++ lim.rlim_cur = STACK_LIM; ++ setrlimit (RLIMIT_STACK, &lim); ++ char *nanstr = malloc (STRING_SIZE); ++ if (nanstr == NULL) ++ { ++ puts ("malloc failed, cannot test"); ++ return 77; ++ } ++ memset (nanstr, '0', STRING_SIZE - 1); ++ nanstr[STRING_SIZE - 1] = 0; ++#define NAN_TEST(TYPE, FUNC) \ ++ do \ ++ { \ ++ char *volatile p = nanstr; \ ++ volatile TYPE v = FUNC (p); \ ++ if (isnan (v)) \ ++ puts ("PASS: " #FUNC); \ ++ else \ ++ { \ ++ puts ("FAIL: " #FUNC); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ NAN_TEST (float, nanf); ++ NAN_TEST (double, nan); ++#ifndef NO_LONG_DOUBLE ++ NAN_TEST (long double, nanl); ++#endif ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -rupN a/math/test-nan-payload.c b/math/test-nan-payload.c +--- a/math/test-nan-payload.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/math/test-nan-payload.c 2017-03-02 16:43:01.693999019 -0500 +@@ -0,0 +1,122 @@ ++/* Test nan functions payload handling (bug 16961). ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Avoid built-in functions. */ ++#define WRAP_NAN(FUNC, STR) \ ++ ({ const char *volatile wns = (STR); FUNC (wns); }) ++#define WRAP_STRTO(FUNC, STR) \ ++ ({ const char *volatile wss = (STR); FUNC (wss, NULL); }) ++ ++#define CHECK_IS_NAN(TYPE, A) \ ++ do \ ++ { \ ++ if (isnan (A)) \ ++ puts ("PASS: " #TYPE " " #A); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++#define CHECK_SAME_NAN(TYPE, A, B) \ ++ do \ ++ { \ ++ if (memcmp (&(A), &(B), sizeof (A)) == 0) \ ++ puts ("PASS: " #TYPE " " #A " = " #B); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A " = " #B); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++#define CHECK_DIFF_NAN(TYPE, A, B) \ ++ do \ ++ { \ ++ if (memcmp (&(A), &(B), sizeof (A)) != 0) \ ++ puts ("PASS: " #TYPE " " #A " != " #B); \ ++ else \ ++ { \ ++ puts ("FAIL: " #TYPE " " #A " != " #B); \ ++ result = 1; \ ++ } \ ++ } \ ++ while (0) ++ ++/* Cannot test payloads by memcmp for formats where NaNs have padding ++ bits. */ ++#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106) ++ ++#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \ ++ do \ ++ { \ ++ TYPE n123 = WRAP_NAN (FUNC, "123"); \ ++ CHECK_IS_NAN (TYPE, n123); \ ++ TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \ ++ CHECK_IS_NAN (TYPE, s123); \ ++ TYPE n456 = WRAP_NAN (FUNC, "456"); \ ++ CHECK_IS_NAN (TYPE, n456); \ ++ TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \ ++ CHECK_IS_NAN (TYPE, s456); \ ++ TYPE n123x = WRAP_NAN (FUNC, "123)"); \ ++ CHECK_IS_NAN (TYPE, n123x); \ ++ TYPE nemp = WRAP_NAN (FUNC, ""); \ ++ CHECK_IS_NAN (TYPE, nemp); \ ++ TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \ ++ CHECK_IS_NAN (TYPE, semp); \ ++ TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \ ++ CHECK_IS_NAN (TYPE, sx); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, n123, s123); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, n456, s456); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, nemp, semp); \ ++ if (CAN_TEST_EQ (MANT_DIG)) \ ++ CHECK_SAME_NAN (TYPE, n123x, sx); \ ++ CHECK_DIFF_NAN (TYPE, n123, n456); \ ++ CHECK_DIFF_NAN (TYPE, n123, nemp); \ ++ CHECK_DIFF_NAN (TYPE, n123, n123x); \ ++ CHECK_DIFF_NAN (TYPE, n456, nemp); \ ++ CHECK_DIFF_NAN (TYPE, n456, n123x); \ ++ } \ ++ while (0) ++ ++static int ++do_test (void) ++{ ++ int result = 0; ++ RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG); ++ RUN_TESTS (double, strtod, nan, DBL_MANT_DIG); ++#ifndef NO_LONG_DOUBLE ++ RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG); ++#endif ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -rupN a/stdlib/Makefile b/stdlib/Makefile +--- a/stdlib/Makefile 2017-03-02 16:34:02.000000000 -0500 ++++ b/stdlib/Makefile 2017-03-02 16:45:05.463639105 -0500 +@@ -47,6 +47,7 @@ routines := \ + strtol_l strtoul_l strtoll_l strtoull_l \ + strtof strtod strtold \ + strtof_l strtod_l strtold_l \ ++ strtof_nan strtod_nan strtold_nan \ + system canonicalize \ + a64l l64a \ + rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \ +diff -rupN a/stdlib/Versions b/stdlib/Versions +--- a/stdlib/Versions 2012-12-24 22:02:13.000000000 -0500 ++++ b/stdlib/Versions 2017-03-02 16:44:52.140671064 -0500 +@@ -114,5 +114,6 @@ libc { + __abort_msg; + # Used from other libraries + __libc_secure_getenv; ++ __strtof_nan; __strtod_nan; __strtold_nan; + } + } +diff -rupN a/stdlib/strtod_l.c b/stdlib/strtod_l.c +--- a/stdlib/strtod_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/stdlib/strtod_l.c 2017-03-02 16:59:50.224590342 -0500 +@@ -20,8 +20,6 @@ + #include + + extern double ____strtod_l_internal (const char *, char **, int, __locale_t); +-extern unsigned long long int ____strtoull_l_internal (const char *, char **, +- int, int, __locale_t); + + /* Configuration part. These macros are defined by `strtold.c', + `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the +@@ -33,28 +31,20 @@ extern unsigned long long int ____strtou + # ifdef USE_WIDE_CHAR + # define STRTOF wcstod_l + # define __STRTOF __wcstod_l ++# define STRTOF_NAN __wcstod_nan + # else + # define STRTOF strtod_l + # define __STRTOF __strtod_l ++# define STRTOF_NAN __strtod_nan + # endif + # define MPN2FLOAT __mpn_construct_double + # define FLOAT_HUGE_VAL HUGE_VAL +-# define SET_MANTISSA(flt, mant) \ +- do { union ieee754_double u; \ +- u.d = (flt); \ +- if ((mant & 0xfffffffffffffULL) == 0) \ +- mant = 0x8000000000000ULL; \ +- u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff; \ +- u.ieee.mantissa1 = (mant) & 0xffffffff; \ +- (flt) = u.d; \ +- } while (0) + #endif + /* End of configuration part. */ + + #include + #include + #include +-#include + #include "../locale/localeinfo.h" + #include + #include +@@ -105,7 +95,6 @@ extern unsigned long long int ____strtou + # define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr) + # define STRNCASECMP(S1, S2, N) \ + __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr) +-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc) + #else + # define STRING_TYPE char + # define CHAR_TYPE char +@@ -117,7 +106,6 @@ extern unsigned long long int ____strtou + # define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr) + # define STRNCASECMP(S1, S2, N) \ + __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr) +-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc) + #endif + + +@@ -649,33 +637,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group + if (*cp == L_('(')) + { + const STRING_TYPE *startp = cp; +- do +- ++cp; +- while ((*cp >= L_('0') && *cp <= L_('9')) +- || ({ CHAR_TYPE lo = TOLOWER (*cp); +- lo >= L_('a') && lo <= L_('z'); }) +- || *cp == L_('_')); +- +- if (*cp != L_(')')) +- /* The closing brace is missing. Only match the NAN +- part. */ +- cp = startp; ++ STRING_TYPE *endp; ++ retval = STRTOF_NAN (cp + 1, &endp, L_(')')); ++ if (*endp == L_(')')) ++ /* Consume the closing parenthesis. */ ++ cp = endp + 1; + else +- { +- /* This is a system-dependent way to specify the +- bitmask used for the NaN. We expect it to be +- a number which is put in the mantissa of the +- number. */ +- STRING_TYPE *endp; +- unsigned long long int mant; +- +- mant = STRTOULL (startp + 1, &endp, 0); +- if (endp == cp) +- SET_MANTISSA (retval, mant); +- +- /* Consume the closing brace. */ +- ++cp; +- } ++ /* Only match the NAN part. */ ++ cp = startp; + } + + if (endptr != NULL) +diff -rupN a/stdlib/strtod_nan.c b/stdlib/strtod_nan.c +--- a/stdlib/strtod_nan.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtod_nan.c 2017-03-02 16:45:05.473639081 -0500 +@@ -0,0 +1,24 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define STRTOD_NAN __strtod_nan ++#include +diff -rupN a/stdlib/strtod_nan_double.h b/stdlib/strtod_nan_double.h +--- a/stdlib/strtod_nan_double.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtod_nan_double.h 2017-03-02 16:45:05.477639072 -0500 +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For double. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee754_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.ieee_nan.mantissa1 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +diff -rupN a/stdlib/strtod_nan_float.h b/stdlib/strtod_nan_float.h +--- a/stdlib/strtod_nan_float.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtod_nan_float.h 2017-03-02 16:45:05.480639065 -0500 +@@ -0,0 +1,29 @@ ++/* Convert string for NaN payload to corresponding NaN. For float. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT float ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee754_float u; \ ++ u.f = (flt); \ ++ u.ieee_nan.mantissa = (mant); \ ++ if (u.ieee.mantissa != 0) \ ++ (flt) = u.f; \ ++ } \ ++ while (0) +diff -rupN a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c +--- a/stdlib/strtod_nan_main.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtod_nan_main.c 2017-03-02 16:45:05.483639058 -0500 +@@ -0,0 +1,63 @@ ++/* Convert string for NaN payload to corresponding NaN. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* If STR starts with an optional n-char-sequence as defined by ISO C ++ (a sequence of ASCII letters, digits and underscores), followed by ++ ENDC, return a NaN whose payload is set based on STR. Otherwise, ++ return a default NAN. If ENDPTR is not NULL, set *ENDPTR to point ++ to the character after the initial n-char-sequence. */ ++ ++internal_function ++FLOAT ++STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc) ++{ ++ const STRING_TYPE *cp = str; ++ ++ while ((*cp >= L_('0') && *cp <= L_('9')) ++ || (*cp >= L_('A') && *cp <= L_('Z')) ++ || (*cp >= L_('a') && *cp <= L_('z')) ++ || *cp == L_('_')) ++ ++cp; ++ ++ FLOAT retval = NAN; ++ if (*cp != endc) ++ goto out; ++ ++ /* This is a system-dependent way to specify the bitmask used for ++ the NaN. We expect it to be a number which is put in the ++ mantissa of the number. */ ++ STRING_TYPE *endp; ++ unsigned long long int mant; ++ ++ mant = STRTOULL (str, &endp, 0); ++ if (endp == cp) ++ SET_MANTISSA (retval, mant); ++ ++ out: ++ if (endptr != NULL) ++ *endptr = (STRING_TYPE *) cp; ++ return retval; ++} ++libc_hidden_def (STRTOD_NAN) +diff -rupN a/stdlib/strtod_nan_narrow.h b/stdlib/strtod_nan_narrow.h +--- a/stdlib/strtod_nan_narrow.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtod_nan_narrow.h 2017-03-02 16:45:05.486639051 -0500 +@@ -0,0 +1,22 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow strings. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRING_TYPE char ++#define L_(Ch) Ch ++#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, \ ++ _nl_C_locobj_ptr) +diff -rupN a/stdlib/strtod_nan_wide.h b/stdlib/strtod_nan_wide.h +--- a/stdlib/strtod_nan_wide.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtod_nan_wide.h 2017-03-02 16:45:05.489639044 -0500 +@@ -0,0 +1,22 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRING_TYPE wchar_t ++#define L_(Ch) L##Ch ++#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, \ ++ _nl_C_locobj_ptr) +diff -rupN a/stdlib/strtof_l.c b/stdlib/strtof_l.c +--- a/stdlib/strtof_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/stdlib/strtof_l.c 2017-03-02 17:06:34.349227993 -0500 +@@ -20,27 +20,19 @@ + #include + + extern float ____strtof_l_internal (const char *, char **, int, __locale_t); +-extern unsigned long long int ____strtoull_l_internal (const char *, char **, +- int, int, __locale_t); + + #define FLOAT float + #define FLT FLT + #ifdef USE_WIDE_CHAR + # define STRTOF wcstof_l + # define __STRTOF __wcstof_l ++# define STRTOF_NAN __wcstof_nan + #else + # define STRTOF strtof_l + # define __STRTOF __strtof_l ++# define STRTOF_NAN __strtof_nan + #endif + #define MPN2FLOAT __mpn_construct_float + #define FLOAT_HUGE_VAL HUGE_VALF +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee754_float u; \ +- u.f = (flt); \ +- if ((mant & 0x7fffff) == 0) \ +- mant = 0x400000; \ +- u.ieee.mantissa = (mant) & 0x7fffff; \ +- (flt) = u.f; \ +- } while (0) + + #include "strtod_l.c" +diff -rupN a/stdlib/strtof_nan.c b/stdlib/strtof_nan.c +--- a/stdlib/strtof_nan.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtof_nan.c 2017-03-02 16:45:05.498639023 -0500 +@@ -0,0 +1,24 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, float. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#define STRTOD_NAN __strtof_nan ++#include +diff -rupN a/stdlib/strtold_nan.c b/stdlib/strtold_nan.c +--- a/stdlib/strtold_nan.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/stdlib/strtold_nan.c 2017-03-02 16:45:05.501639016 -0500 +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. Narrow ++ strings, long double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* This function is unused if long double and double have the same ++ representation. */ ++#ifndef __NO_LONG_DOUBLE_MATH ++# include ++# include ++ ++# define STRTOD_NAN __strtold_nan ++# include ++#endif +diff -rupN a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h +--- a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h 2017-03-02 16:45:05.502639014 -0500 +@@ -0,0 +1,33 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-128. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee854_long_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = 0; \ ++ u.ieee_nan.mantissa1 = 0; \ ++ u.ieee_nan.mantissa2 = (mant) >> 32; \ ++ u.ieee_nan.mantissa3 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1 \ ++ | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +diff -rupN a/sysdeps/ieee754/ldbl-128/strtold_l.c b/sysdeps/ieee754/ldbl-128/strtold_l.c +--- a/sysdeps/ieee754/ldbl-128/strtold_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-128/strtold_l.c 2017-03-02 17:07:43.540018882 -0500 +@@ -25,20 +25,13 @@ + #ifdef USE_WIDE_CHAR + # define STRTOF wcstold_l + # define __STRTOF __wcstold_l ++# define STRTOF_NAN __wcstold_nan + #else + # define STRTOF strtold_l + # define __STRTOF __strtold_l ++# define STRTOF_NAN __strtold_nan + #endif + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee.mantissa0 = 0x8000; \ +- u.ieee.mantissa1 = 0; \ +- u.ieee.mantissa2 = ((mant) >> 32); \ +- u.ieee.mantissa3 = (mant) & 0xffffffff; \ +- (flt) = u.d; \ +- } while (0) + + #include +diff -rupN a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h +--- a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h 2017-03-02 16:45:05.505639007 -0500 +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-128ibm. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ibm_extended_long_double u; \ ++ u.ld = (flt); \ ++ u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.d[0].ieee_nan.mantissa1 = (mant); \ ++ if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ ++ (flt) = u.ld; \ ++ } \ ++ while (0) +diff -rupN a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c +--- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c 2017-03-02 16:33:54.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c 2017-03-02 17:10:22.516584043 -0500 +@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (co + # define STRTOF __new_wcstold_l + # define __STRTOF ____new_wcstold_l + # define ____STRTOF_INTERNAL ____wcstold_l_internal ++# define STRTOF_NAN __wcstold_nan + #else + extern long double ____new_strtold_l (const char *, char **, __locale_t); + # define STRTOF __new_strtold_l + # define __STRTOF ____new_strtold_l + # define ____STRTOF_INTERNAL ____strtold_l_internal ++# define STRTOF_NAN __strtold_nan + #endif + extern __typeof (__STRTOF) STRTOF; + libc_hidden_proto (__STRTOF) + libc_hidden_proto (STRTOF) + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-# define SET_MANTISSA(flt, mant) \ +- do { union ibm_extended_long_double u; \ +- u.ld = (flt); \ +- u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \ +- u.d[0].ieee_nan.mantissa1 = (mant); \ +- if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \ +- (flt) = u.ld; \ +- } while (0) + + #include + +diff -rupN a/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/sysdeps/ieee754/ldbl-64-128/strtold_l.c +--- a/sysdeps/ieee754/ldbl-64-128/strtold_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-64-128/strtold_l.c 2017-03-02 17:11:06.062475088 -0500 +@@ -30,26 +30,19 @@ extern long double ____new_wcstold_l (co + # define STRTOF __new_wcstold_l + # define __STRTOF ____new_wcstold_l + # define ____STRTOF_INTERNAL ____wcstold_l_internal ++# define STRTOF_NAN __wcstold_nan + #else + extern long double ____new_strtold_l (const char *, char **, __locale_t); + # define STRTOF __new_strtold_l + # define __STRTOF ____new_strtold_l + # define ____STRTOF_INTERNAL ____strtold_l_internal ++# define STRTOF_NAN __strtold_nan + #endif + extern __typeof (__STRTOF) STRTOF; + libc_hidden_proto (__STRTOF) + libc_hidden_proto (STRTOF) + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- u.ieee.mantissa0 = 0x8000; \ +- u.ieee.mantissa1 = 0; \ +- u.ieee.mantissa2 = ((mant) >> 32); \ +- u.ieee.mantissa3 = (mant) & 0xffffffff; \ +- (flt) = u.d; \ +- } while (0) + + #include + +diff -rupN a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h +--- a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h 2017-03-02 16:45:05.521638969 -0500 +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. For ldbl-96. ++ Copyright (C) 1997-2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define FLOAT long double ++#define SET_MANTISSA(flt, mant) \ ++ do \ ++ { \ ++ union ieee854_long_double u; \ ++ u.d = (flt); \ ++ u.ieee_nan.mantissa0 = (mant) >> 32; \ ++ u.ieee_nan.mantissa1 = (mant); \ ++ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \ ++ (flt) = u.d; \ ++ } \ ++ while (0) +diff -rupN a/sysdeps/ieee754/ldbl-96/strtold_l.c b/sysdeps/ieee754/ldbl-96/strtold_l.c +--- a/sysdeps/ieee754/ldbl-96/strtold_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/ieee754/ldbl-96/strtold_l.c 2017-03-02 17:11:52.927362322 -0500 +@@ -25,20 +25,13 @@ + #ifdef USE_WIDE_CHAR + # define STRTOF wcstold_l + # define __STRTOF __wcstold_l ++# define STRTOF_NAN __wcstold_nan + #else + # define STRTOF strtold_l + # define __STRTOF __strtold_l ++# define STRTOF_NAN __strtold_nan + #endif + #define MPN2FLOAT __mpn_construct_long_double + #define FLOAT_HUGE_VAL HUGE_VALL +-#define SET_MANTISSA(flt, mant) \ +- do { union ieee854_long_double u; \ +- u.d = (flt); \ +- if ((mant & 0x7fffffffffffffffULL) == 0) \ +- mant = 0x4000000000000000ULL; \ +- u.ieee.mantissa0 = (((mant) >> 32) & 0x7fffffff) | 0x80000000; \ +- u.ieee.mantissa1 = (mant) & 0xffffffff; \ +- (flt) = u.d; \ +- } while (0) + + #include +diff -rupN a/wcsmbs/Makefile b/wcsmbs/Makefile +--- a/wcsmbs/Makefile 2017-03-02 16:33:59.000000000 -0500 ++++ b/wcsmbs/Makefile 2017-03-02 16:45:05.529638950 -0500 +@@ -32,6 +32,7 @@ routines := wcscat wcschr wcscmp wcscpy + wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \ + wcstol_l wcstoul_l wcstoll_l wcstoull_l \ + wcstod_l wcstold_l wcstof_l \ ++ wcstod_nan wcstold_nan wcstof_nan \ + wcscoll wcsxfrm \ + wcwidth wcswidth \ + wcscoll_l wcsxfrm_l \ +diff -rupN a/wcsmbs/wcstod_l.c b/wcsmbs/wcstod_l.c +--- a/wcsmbs/wcstod_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/wcsmbs/wcstod_l.c 2017-03-02 16:45:05.532638943 -0500 +@@ -23,9 +23,6 @@ + + extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #define USE_WIDE_CHAR 1 + +diff -rupN a/wcsmbs/wcstod_nan.c b/wcsmbs/wcstod_nan.c +--- a/wcsmbs/wcstod_nan.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/wcsmbs/wcstod_nan.c 2017-03-02 16:45:05.535638936 -0500 +@@ -0,0 +1,23 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "../stdlib/strtod_nan_wide.h" ++#include "../stdlib/strtod_nan_double.h" ++ ++#define STRTOD_NAN __wcstod_nan ++#include "../stdlib/strtod_nan_main.c" +diff -rupN a/wcsmbs/wcstof_l.c b/wcsmbs/wcstof_l.c +--- a/wcsmbs/wcstof_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/wcsmbs/wcstof_l.c 2017-03-02 16:45:05.538638929 -0500 +@@ -25,8 +25,5 @@ + + extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #include +diff -rupN a/wcsmbs/wcstof_nan.c b/wcsmbs/wcstof_nan.c +--- a/wcsmbs/wcstof_nan.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/wcsmbs/wcstof_nan.c 2017-03-02 16:45:05.541638922 -0500 +@@ -0,0 +1,23 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, float. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "../stdlib/strtod_nan_wide.h" ++#include "../stdlib/strtod_nan_float.h" ++ ++#define STRTOD_NAN __wcstof_nan ++#include "../stdlib/strtod_nan_main.c" +diff -rupN a/wcsmbs/wcstold_l.c b/wcsmbs/wcstold_l.c +--- a/wcsmbs/wcstold_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/wcsmbs/wcstold_l.c 2017-03-02 16:45:05.544638915 -0500 +@@ -24,8 +24,5 @@ + + extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int, + __locale_t); +-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *, +- wchar_t **, int, int, +- __locale_t); + + #include +diff -rupN a/wcsmbs/wcstold_nan.c b/wcsmbs/wcstold_nan.c +--- a/wcsmbs/wcstold_nan.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/wcsmbs/wcstold_nan.c 2017-03-02 16:45:05.547638908 -0500 +@@ -0,0 +1,30 @@ ++/* Convert string for NaN payload to corresponding NaN. Wide strings, ++ long double. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* This function is unused if long double and double have the same ++ representation. */ ++#ifndef __NO_LONG_DOUBLE_MATH ++# include "../stdlib/strtod_nan_wide.h" ++# include ++ ++# define STRTOD_NAN __wcstold_nan ++# include "../stdlib/strtod_nan_main.c" ++#endif diff --git a/SOURCES/glibc-rh1374654.patch b/SOURCES/glibc-rh1374654.patch new file mode 100644 index 00000000..4d561409 --- /dev/null +++ b/SOURCES/glibc-rh1374654.patch @@ -0,0 +1,208 @@ +From 0f58539030e436449f79189b6edab17d7479796e Mon Sep 17 00:00:00 2001 +From: Paul Pluzhnikov +Date: Sat, 8 Aug 2015 15:53:03 -0700 +Subject: [PATCH] Fix BZ #17905 + +diff -rupN a/catgets/Makefile b/catgets/Makefile +--- a/catgets/Makefile 2017-03-03 17:54:39.000000000 -0500 ++++ b/catgets/Makefile 2017-03-03 18:05:02.506889588 -0500 +@@ -44,13 +44,15 @@ catgets-CPPFLAGS := -DNLSPATH='"$(msgcat + + generated = de.msg test1.cat test1.h test2.cat test2.h sample.SJIS.cat \ + test-gencat.h ++generated += tst-catgets.mtrace tst-catgets-mem.out ++ + generated-dirs = de + +-tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de ++tst-catgets-ENV = NLSPATH="$(objpfx)%l/%N.cat" LANG=de MALLOC_TRACE=$(objpfx)tst-catgets.mtrace + + ifeq ($(run-built-tests),yes) + tests: $(objpfx)de/libc.cat $(objpfx)test1.cat $(objpfx)test2.cat \ +- $(objpfx)test-gencat.out ++ $(objpfx)test-gencat.out $(objpfx)tst-catgets-mem.out + # This test just checks whether the program produces any error or not. + # The result is not tested. + $(objpfx)test1.cat: test1.msg $(objpfx)gencat +@@ -78,4 +80,8 @@ $(objpfx)test-gencat.out: test-gencat.sh + $(objpfx)sample.SJIS.cat: sample.SJIS $(objpfx)gencat + GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \ + $(built-program-cmd) -H $(objpfx)test-gencat.h < $(word 1,$^) > $@ ++ ++$(objpfx)tst-catgets-mem.out: $(objpfx)tst-catgets.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-catgets.mtrace > $@; \ ++ $(evaluate-test) + endif +diff -rupN a/catgets/catgets.c b/catgets/catgets.c +--- a/catgets/catgets.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/catgets/catgets.c 2017-03-03 17:55:43.750147349 -0500 +@@ -16,7 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-#include + #include + #include + #include +@@ -35,6 +34,7 @@ catopen (const char *cat_name, int flag) + __nl_catd result; + const char *env_var = NULL; + const char *nlspath = NULL; ++ char *tmp = NULL; + + if (strchr (cat_name, '/') == NULL) + { +@@ -54,7 +54,10 @@ catopen (const char *cat_name, int flag) + { + /* Append the system dependent directory. */ + size_t len = strlen (nlspath) + 1 + sizeof NLSPATH; +- char *tmp = alloca (len); ++ tmp = malloc (len); ++ ++ if (__glibc_unlikely (tmp == NULL)) ++ return (nl_catd) -1; + + __stpcpy (__stpcpy (__stpcpy (tmp, nlspath), ":"), NLSPATH); + nlspath = tmp; +@@ -65,16 +68,18 @@ catopen (const char *cat_name, int flag) + + result = (__nl_catd) malloc (sizeof (*result)); + if (result == NULL) +- /* We cannot get enough memory. */ +- return (nl_catd) -1; +- +- if (__open_catalog (cat_name, nlspath, env_var, result) != 0) ++ { ++ /* We cannot get enough memory. */ ++ result = (nl_catd) -1; ++ } ++ else if (__open_catalog (cat_name, nlspath, env_var, result) != 0) + { + /* Couldn't open the file. */ + free ((void *) result); +- return (nl_catd) -1; ++ result = (nl_catd) -1; + } + ++ free (tmp); + return (nl_catd) result; + } + +diff -rupN a/catgets/open_catalog.c b/catgets/open_catalog.c +--- a/catgets/open_catalog.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/catgets/open_catalog.c 2017-03-03 17:55:43.753147332 -0500 +@@ -47,6 +47,7 @@ __open_catalog (const char *cat_name, co + size_t tab_size; + const char *lastp; + int result = -1; ++ char *buf = NULL; + + if (strchr (cat_name, '/') != NULL || nlspath == NULL) + fd = open_not_cancel_2 (cat_name, O_RDONLY); +@@ -57,23 +58,23 @@ __open_catalog (const char *cat_name, co + if (__builtin_expect (bufact + (n) >= bufmax, 0)) \ + { \ + char *old_buf = buf; \ +- bufmax += 256 + (n); \ +- buf = (char *) alloca (bufmax); \ +- memcpy (buf, old_buf, bufact); \ ++ bufmax += (bufmax < 256 + (n)) ? 256 + (n) : bufmax; \ ++ buf = realloc (buf, bufmax); \ ++ if (__glibc_unlikely (buf == NULL)) \ ++ { \ ++ free (old_buf); \ ++ return -1; \ ++ } \ + } + + /* The RUN_NLSPATH variable contains a colon separated list of + descriptions where we expect to find catalogs. We have to + recognize certain % substitutions and stop when we found the + first existing file. */ +- char *buf; + size_t bufact; +- size_t bufmax; ++ size_t bufmax = 0; + size_t len; + +- buf = NULL; +- bufmax = 0; +- + fd = -1; + while (*run_nlspath != '\0') + { +@@ -188,7 +189,10 @@ __open_catalog (const char *cat_name, co + + /* Avoid dealing with directories and block devices */ + if (__builtin_expect (fd, 0) < 0) +- return -1; ++ { ++ free (buf); ++ return -1; ++ } + + if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &st), 0) < 0) + goto close_unlock_return; +@@ -325,6 +329,7 @@ __open_catalog (const char *cat_name, co + /* Release the lock again. */ + close_unlock_return: + close_not_cancel_no_status (fd); ++ free (buf); + + return result; + } +diff -rupN a/catgets/tst-catgets.c b/catgets/tst-catgets.c +--- a/catgets/tst-catgets.c 2017-03-03 17:54:38.000000000 -0500 ++++ b/catgets/tst-catgets.c 2017-03-03 17:55:43.755147321 -0500 +@@ -1,7 +1,10 @@ ++#include + #include + #include + #include ++#include + #include ++#include + + + static const char *msgs[] = +@@ -12,6 +15,33 @@ static const char *msgs[] = + }; + #define nmsgs (sizeof (msgs) / sizeof (msgs[0])) + ++ ++/* Test for unbounded alloca. */ ++static int ++do_bz17905 (void) ++{ ++ char *buf; ++ struct rlimit rl; ++ nl_catd result; ++ ++ const int sz = 1024 * 1024; ++ ++ getrlimit (RLIMIT_STACK, &rl); ++ rl.rlim_cur = sz; ++ setrlimit (RLIMIT_STACK, &rl); ++ ++ buf = malloc (sz + 1); ++ memset (buf, 'A', sz); ++ buf[sz] = '\0'; ++ setenv ("NLSPATH", buf, 1); ++ ++ result = catopen (buf, NL_CAT_LOCALE); ++ assert (result == (nl_catd) -1); ++ ++ free (buf); ++ return 0; ++} ++ + #define ROUNDS 5 + + static int +@@ -62,6 +92,7 @@ do_test (void) + } + } + ++ result += do_bz17905 (); + return result; + } diff --git a/SOURCES/glibc-rh1374657.patch b/SOURCES/glibc-rh1374657.patch new file mode 100644 index 00000000..9e44f2f4 --- /dev/null +++ b/SOURCES/glibc-rh1374657.patch @@ -0,0 +1,188 @@ +commit bae7c7c764413b23e61cb099ce33be4c4ee259bb +Author: Florian Weimer +Date: Thu Jan 28 13:59:11 2016 +0100 + + Improve check against integer wraparound in hcreate_r [BZ #18240] + +commit 2f5c1750558fe64bac361f52d6827ab1bcfe52bc +Author: Ondřej Bílka +Date: Sat Jul 11 17:44:10 2015 +0200 + + Handle overflow in __hcreate_r + +--- glibc-2.17-c758a686/misc/hsearch_r.c ++++ glibc-2.17-c758a686/misc/hsearch_r.c +@@ -20,7 +20,7 @@ + #include + #include + #include +- ++#include + #include + + /* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 +@@ -47,12 +47,10 @@ + isprime (unsigned int number) + { + /* no even number will be passed */ +- unsigned int div = 3; +- +- while (div * div < number && number % div != 0) +- div += 2; +- +- return number % div != 0; ++ for (unsigned int div = 3; div <= number / div; div += 2) ++ if (number % div == 0) ++ return 0; ++ return 1; + } + + +@@ -74,6 +72,12 @@ + return 0; + } + ++ if (nel >= SIZE_MAX / sizeof (_ENTRY)) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ + /* There is still another table active. Return with error. */ + if (htab->table != NULL) + return 0; +@@ -82,10 +86,19 @@ + use will not work. */ + if (nel < 3) + nel = 3; +- /* Change nel to the first prime number not smaller as nel. */ +- nel |= 1; /* make odd */ +- while (!isprime (nel)) +- nel += 2; ++ ++ /* Change nel to the first prime number in the range [nel, UINT_MAX - 2], ++ The '- 2' means 'nel += 2' cannot overflow. */ ++ for (nel |= 1; ; nel += 2) ++ { ++ if (UINT_MAX - 2 < nel) ++ { ++ __set_errno (ENOMEM); ++ return 0; ++ } ++ if (isprime (nel)) ++ break; ++ } + + htab->size = nel; + htab->filled = 0; +--- /dev/null ++++ glibc-2.17-c758a686/misc/bug18240.c +@@ -0,0 +1,97 @@ ++/* Test integer wraparound in hcreate. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++test_size (size_t size) ++{ ++ int res = hcreate (size); ++ if (res == 0) ++ { ++ if (errno == ENOMEM) ++ return; ++ printf ("error: hcreate (%zu): %m\n", size); ++ exit (1); ++ } ++ char *keys[100]; ++ for (int i = 0; i < 100; ++i) ++ { ++ if (asprintf (keys + i, "%d", i) < 0) ++ { ++ printf ("error: asprintf: %m\n"); ++ exit (1); ++ } ++ ENTRY e = { keys[i], (char *) "value" }; ++ if (hsearch (e, ENTER) == NULL) ++ { ++ printf ("error: hsearch (\"%s\"): %m\n", keys[i]); ++ exit (1); ++ } ++ } ++ hdestroy (); ++ ++ for (int i = 0; i < 100; ++i) ++ free (keys[i]); ++} ++ ++static int ++do_test (void) ++{ ++ /* Limit the size of the process, so that memory allocation will ++ fail without impacting the entire system. */ ++ { ++ struct rlimit limit; ++ if (getrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("getrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ long target = 100 * 1024 * 1024; ++ if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target) ++ { ++ limit.rlim_cur = target; ++ if (setrlimit (RLIMIT_AS, &limit) != 0) ++ { ++ printf ("setrlimit (RLIMIT_AS) failed: %m\n"); ++ return 1; ++ } ++ } ++ } ++ ++ test_size (500); ++ test_size (-1); ++ test_size (-3); ++ test_size (INT_MAX - 2); ++ test_size (INT_MAX - 1); ++ test_size (INT_MAX); ++ test_size (((unsigned) INT_MAX) + 1); ++ test_size (UINT_MAX - 2); ++ test_size (UINT_MAX - 1); ++ test_size (UINT_MAX); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- glibc-2.17-c758a686/misc/Makefile ++++ glibc-2.17-c758a686/misc/Makefile +@@ -76,7 +76,7 @@ + gpl2lgpl := error.c error.h + + tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \ +- tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 ++ tst-error1 tst-pselect tst-insremque tst-mntent2 bug-hsearch1 bug18240 + ifeq ($(run-built-tests),yes) + tests: $(objpfx)tst-error1-mem + endif diff --git a/SOURCES/glibc-rh1374658.patch b/SOURCES/glibc-rh1374658.patch new file mode 100644 index 00000000..6e252bbd --- /dev/null +++ b/SOURCES/glibc-rh1374658.patch @@ -0,0 +1,124 @@ +commit d36c75fc0d44deec29635dd239b0fbd206ca49b7 +Author: Paul Pluzhnikov +Date: Sat Sep 26 13:27:48 2015 -0700 + + Fix BZ #18985 -- out of range data to strftime() causes a segfault + +diff --git a/time/strftime_l.c b/time/strftime_l.c +index b48ef34..4eb647c 100644 +--- a/time/strftime_l.c ++++ b/time/strftime_l.c +@@ -510,13 +510,17 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument + only a few elements. Dereference the pointers only if the format + requires this. Then it is ok to fail if the pointers are invalid. */ + # define a_wkday \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) ++ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))) + # define f_wkday \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) ++ ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))) + # define a_month \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))) + # define f_month \ +- ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) ++ ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))) + # define ampm \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ + ? NLW(PM_STR) : NLW(AM_STR))) +@@ -526,8 +530,10 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument + # define ap_len STRLEN (ampm) + #else + # if !HAVE_STRFTIME +-# define f_wkday (weekday_name[tp->tm_wday]) +-# define f_month (month_name[tp->tm_mon]) ++# define f_wkday (tp->tm_wday < 0 || tp->tm_wday > 6 \ ++ ? "?" : weekday_name[tp->tm_wday]) ++# define f_month (tp->tm_mon < 0 || tp->tm_mon > 11 \ ++ ? "?" : month_name[tp->tm_mon]) + # define a_wkday f_wkday + # define a_month f_month + # define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) +@@ -1321,7 +1327,7 @@ __strftime_internal (s, maxsize, format, tp, tzset_called ut_argument + *tzset_called = true; + } + # endif +- zone = tzname[tp->tm_isdst]; ++ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?"; + } + #endif + if (! zone) +diff --git a/time/tst-strftime.c b/time/tst-strftime.c +index 374fba4..af3ff72 100644 +--- a/time/tst-strftime.c ++++ b/time/tst-strftime.c +@@ -4,6 +4,56 @@ + #include + + ++static int ++do_bz18985 (void) ++{ ++ char buf[1000]; ++ struct tm ttm; ++ int rc, ret = 0; ++ ++ memset (&ttm, 1, sizeof (ttm)); ++ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ ++ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); ++ ++ if (rc == 66) ++ { ++ const char expected[] ++ = "? ? ? ? ? ? 16843009 16843009:16843009:16843009 16844909 +467836 ?"; ++ if (0 != strcmp (buf, expected)) ++ { ++ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); ++ ret += 1; ++ } ++ } ++ else ++ { ++ printf ("expected 66, got %d\n", rc); ++ ret += 1; ++ } ++ ++ /* Check negative values as well. */ ++ memset (&ttm, 0xFF, sizeof (ttm)); ++ ttm.tm_zone = NULL; /* Dereferenced directly if non-NULL. */ ++ rc = strftime (buf, sizeof (buf), "%a %A %b %B %c %z %Z", &ttm); ++ ++ if (rc == 30) ++ { ++ const char expected[] = "? ? ? ? ? ? -1 -1:-1:-1 1899 "; ++ if (0 != strcmp (buf, expected)) ++ { ++ printf ("expected:\n %s\ngot:\n %s\n", expected, buf); ++ ret += 1; ++ } ++ } ++ else ++ { ++ printf ("expected 30, got %d\n", rc); ++ ret += 1; ++ } ++ ++ return ret; ++} ++ + static struct + { + const char *fmt; +@@ -104,7 +154,7 @@ do_test (void) + } + } + +- return result; ++ return result + do_bz18985 (); + } + + #define TEST_FUNCTION do_test () diff --git a/SOURCES/glibc-rh1375235-1.patch b/SOURCES/glibc-rh1375235-1.patch new file mode 100644 index 00000000..9b5c1c1a --- /dev/null +++ b/SOURCES/glibc-rh1375235-1.patch @@ -0,0 +1,120 @@ +From 63be4dc8f5be08f40df927377bdf0bae5239ce53 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 01/10] S390: Configure checks + HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT. + +This configure check was added upstream with commit +e9b424881a4f85284e56d8b561c54ff57a7c1c9b +"S390: Do not set FE_INEXACT with feraiseexcept (FE_OWERFLOW|FE_UNDERFLOW)." + +HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT will be defined if gcc/assembler +can handle zarch z196 instructions by default. +Thus it is defined on s390x-glibc on RHEL 7, but not for s390-glibc. + +ChangeLog: + + * config.h.in (HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT): + New undefine. + * sysdeps/s390/configure.ac: Add test for z196 zarch support. + * sysdeps/s390/configure: Regenerated. +--- + config.h.in | 3 +++ + sysdeps/s390/configure | 36 ++++++++++++++++++++++++++++++++++++ + sysdeps/s390/configure.in | 26 ++++++++++++++++++++++++++ + 3 files changed, 65 insertions(+) + +diff --git a/config.h.in b/config.h.in +index 66ac85a..07bc713 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -110,6 +110,9 @@ + /* Define if assembler supports Intel MPX. */ + #undef HAVE_MPX_SUPPORT + ++/* Define if assembler supports z196 zarch instructions as default on S390. */ ++#undef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++ + /* Define if assembler supports vector instructions on S390. */ + #undef HAVE_S390_VX_ASM_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index eb49a4c..bb670f3 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -75,3 +75,39 @@ then + $as_echo "#define HAVE_S390_VX_GCC_SUPPORT 1" >>confdefs.h + + fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5 ++$as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; } ++if ${libc_cv_asm_s390_min_z196_zarch+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++float testinsn (double e) ++{ ++ float d; ++ __asm__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) ); ++ return d; ++} ++EOF ++if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_asm_s390_min_z196_zarch=yes ++else ++ libc_cv_asm_s390_min_z196_zarch=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z196_zarch" >&5 ++$as_echo "$libc_cv_asm_s390_min_z196_zarch" >&6; } ++ ++if test "$libc_cv_asm_s390_min_z196_zarch" = yes ; ++then ++ $as_echo "#define HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT 1" >>confdefs.h ++ ++fi +diff --git a/sysdeps/s390/configure.in b/sysdeps/s390/configure.in +index a3b1f25..bad92bd 100644 +--- a/sysdeps/s390/configure.in ++++ b/sysdeps/s390/configure.in +@@ -53,3 +53,29 @@ if test "$libc_cv_gcc_s390_vx" = yes ; + then + AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) + fi ++ ++AC_CACHE_CHECK(for S390 z196 zarch instruction support as default, ++ libc_cv_asm_s390_min_z196_zarch, [dnl ++cat > conftest.c <<\EOF ++float testinsn (double e) ++{ ++ float d; ++ __asm__ ("ledbra %0,5,%1,4" : "=f" (d) : "f" (e) ); ++ return d; ++} ++EOF ++dnl ++dnl test, if assembler supports S390 z196 zarch instructions as default ++if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c ++ -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_asm_s390_min_z196_zarch=yes ++else ++ libc_cv_asm_s390_min_z196_zarch=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_asm_s390_min_z196_zarch" = yes ; ++then ++ AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT) ++fi +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-10.patch b/SOURCES/glibc-rh1375235-10.patch new file mode 100644 index 00000000..c51ec9f4 --- /dev/null +++ b/SOURCES/glibc-rh1375235-10.patch @@ -0,0 +1,182 @@ +From 5855d3b7d0fc85b2827755bbb3b4dacf6a08dae7 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:59 +0200 +Subject: [PATCH 10/10] S390: Use cu21 instruction for converting from utf16 to + utf8. + +upstream-commit a37b5daa6bc7fbcbbc229b2549a161fa15023f41 + +This patch adds an ifunc variant to use the cu instruction on arch12 CPUs. +This new ifunc variant can be built if binutils support z13 vector +instructions. At runtime, HWCAP_S390_VXE decides if we can use the +cu21 instruction. + +ChangeLog: + + * sysdeps/s390/utf8-utf16-z9.c (__to_utf8_loop_vx_cu): + Use vector and cu21 instruction. + * sysdeps/s390/multiarch/utf8-utf16-z9.c: + Add __to_utf8_loop_vx_cu in ifunc resolver. +--- + sysdeps/s390/multiarch/utf8-utf16-z9.c | 8 ++- + sysdeps/s390/utf8-utf16-z9.c | 117 +++++++++++++++++++++++++++++++++ + 2 files changed, 122 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/multiarch/utf8-utf16-z9.c b/sysdeps/s390/multiarch/utf8-utf16-z9.c +index b55ef1a..1252281 100644 +--- a/sysdeps/s390/multiarch/utf8-utf16-z9.c ++++ b/sysdeps/s390/multiarch/utf8-utf16-z9.c +@@ -41,8 +41,10 @@ s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, + : FROM_LOOP_DEFAULT); + + s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, +- (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) +- ? TO_LOOP_VX +- : TO_LOOP_DEFAULT); ++ (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) ++ ? TO_LOOP_VX_CU ++ : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) ++ ? TO_LOOP_VX ++ : TO_LOOP_DEFAULT); + + #include +diff --git a/sysdeps/s390/utf8-utf16-z9.c b/sysdeps/s390/utf8-utf16-z9.c +index d870a29..76e463a 100644 +--- a/sysdeps/s390/utf8-utf16-z9.c ++++ b/sysdeps/s390/utf8-utf16-z9.c +@@ -52,9 +52,11 @@ + #if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH + # define HAVE_FROM_VX 1 + # define HAVE_TO_VX 1 ++# define HAVE_TO_VX_CU 1 + #else + # define HAVE_FROM_VX 0 + # define HAVE_TO_VX 0 ++# define HAVE_TO_VX_CU 0 + #endif + + #if defined HAVE_S390_VX_GCC_SUPPORT +@@ -817,6 +819,121 @@ gconv_end (struct __gconv_step *data) + # define TO_LOOP_VX NULL + #endif /* HAVE_TO_VX != 1 */ + ++#if HAVE_TO_VX_CU == 1 ++#define BODY_TO_VX_CU \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm ("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for values <= 0x7f. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-16 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ ++ /* Check for > 1byte UTF-8 chars. */ \ ++ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \ ++ " jno 11f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Shorten to UTF-8. */ \ ++ " vpkh %%v18,%%v16,%%v17\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-32\n\t" \ ++ /* Store 16 bytes to buf_out. */ \ ++ " vst %%v18,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch > 0x7f. (v30, v31) */ \ ++ "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ /* Shorten to UTF-8. */ \ ++ " vpkh %%v18,%%v16,%%v17\n\t" \ ++ " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \ ++ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 20f\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handles UTF16 surrogates with convert instruction. */ \ ++ "20: cu21 %[R_OUT],%[R_IN],1\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ \ ++ if (__glibc_likely (inlen == 0) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inlen == 1) \ ++ { \ ++ /* Input does not contain a complete utf16 character. */ \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ else if (result != __GCONV_ILLEGAL_INPUT) \ ++ { \ ++ /* Input is >= 2 and < 4 bytes (as cu21 would have processed \ ++ a possible next utf16 character) and not illegal. \ ++ => we have a single high surrogate at end of input. */ \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (2); \ ++ } ++ ++/* Generate loop-function with vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MAX_NEEDED_INPUT MAX_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define TO_LOOP_VX_CU __to_utf8_loop_vx_cu ++# define LOOPFCT TO_LOOP_VX_CU ++# define BODY BODY_TO_VX_CU ++# define LOOP_NEED_FLAGS ++# include ++#else ++# define TO_LOOP_VX_CU NULL ++#endif /* HAVE_TO_VX_CU != 1 */ ++ + /* This file also exists in sysdeps/s390/multiarch/ which + generates ifunc resolvers for FROM/TO_LOOP functions + and includes iconv/skeleton.c afterwards. */ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-2.patch b/SOURCES/glibc-rh1375235-2.patch new file mode 100644 index 00000000..dab685ef --- /dev/null +++ b/SOURCES/glibc-rh1375235-2.patch @@ -0,0 +1,127 @@ +From 42e0828f582dcc4ff92d65039910ffe5fa9d881b Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 02/10] S390: Use new s390_libc_ifunc_expr macro in s390 + 8bit-generic.c. + +upstream-commit 51213e2b8d89164527131f3bf6c5946b811c5e3e + +This patch adds s390_libc_ifunc_expr macro which uses the __ifunc base macro +(upstream it is in include/libc-symbols.h; this backport implements it +in s390-header) and lets the user define a generic expression to +choose the correct ifunc variant. Furthermore as the base macro is used, +the ifunc resolver functions are now also using inhibit_stack_protector. +S390 needs its own version due to the hwcap argument of the ifunc resolver. + +This new macro is now used in iconv code in 8bit-generic.c instead of using +gcc attribute ifunc directly. + +ChangeLog: + + * sysdeps/s390/multiarch/ifunc-resolve.h + (s390_libc_ifunc_expr_init, s390_libc_ifunc_expr, __ifunc, + __ifunc_resolver): New Define. + * sysdeps/s390/multiarch/8bit-generic.c + (__to_generic, __from_generic): Use s390_libc_ifunc_expr to + define ifunc resolvers. +--- + sysdeps/s390/multiarch/8bit-generic.c | 41 ++++++++++------------------------ + sysdeps/s390/multiarch/ifunc-resolve.h | 20 +++++++++++++++++ + 2 files changed, 32 insertions(+), 29 deletions(-) + +diff --git a/sysdeps/s390/multiarch/8bit-generic.c b/sysdeps/s390/multiarch/8bit-generic.c +index 93565e1..9232240 100644 +--- a/sysdeps/s390/multiarch/8bit-generic.c ++++ b/sysdeps/s390/multiarch/8bit-generic.c +@@ -40,8 +40,7 @@ + to translate between multiple generic characters and "1 byte UCS4" + characters at once. The vector instructions are used to convert between + the "1 byte UCS4" and UCS4. */ +-# include +-# include ++# include + + # undef FROM_LOOP + # undef TO_LOOP +@@ -372,33 +371,17 @@ + + + /* Generate ifunc'ed loop function. */ +-__typeof(__from_generic_c) +-__attribute__ ((ifunc ("__from_generic_resolver"))) +-__from_generic; ++s390_libc_ifunc_expr (__from_generic_c, __from_generic, ++ (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 ++ && hwcap & HWCAP_S390_VX) ++ ? __from_generic_vx ++ : __from_generic_c); + +-static void * +-__from_generic_resolver (unsigned long int dl_hwcap) +-{ +- if (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 +- && dl_hwcap & HWCAP_S390_VX) +- return &__from_generic_vx; +- else +- return &__from_generic_c; +-} +- +-__typeof(__to_generic_c) +-__attribute__ ((ifunc ("__to_generic_resolver"))) +-__to_generic; +- +-static void * +-__to_generic_resolver (unsigned long int dl_hwcap) +-{ +- if (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 +- && dl_hwcap & HWCAP_S390_VX) +- return &__to_generic_vx; +- else +- return &__to_generic_c; +-} ++s390_libc_ifunc_expr (__to_generic_c, __to_generic, ++ (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 ++ && hwcap & HWCAP_S390_VX) ++ ? __to_generic_vx ++ : __to_generic_c); + + strong_alias (__to_generic_c_single, __to_generic_single) + +@@ -410,6 +393,6 @@ strong_alias (__to_generic_c_single, __to_generic_single) + + #else + /* Generate this module without ifunc if build environment lacks vector +- support. Instead the common 8bit-generic.c is used. */ ++ support. Instead the common 8bit-generic.c is used. */ + # include "iconvdata/8bit-generic.c" + #endif /* !defined HAVE_S390_VX_ASM_SUPPORT */ +diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h +index e9fd90e..883365b 100644 +--- a/sysdeps/s390/multiarch/ifunc-resolve.h ++++ b/sysdeps/s390/multiarch/ifunc-resolve.h +@@ -92,3 +92,23 @@ + return &RESOLVERFUNC##_c; \ + } \ + __asm__ (".type " #FUNC ", %gnu_indirect_function"); ++ ++/* Helper / base macros for indirect function symbols ++ (See include/libc-symbols in upstream glibc). */ ++#define __ifunc_resolver(type_name, name, expr, arg, init, classifier) \ ++ classifier void *name##_ifunc (arg) \ ++ { \ ++ init (); \ ++ __typeof (type_name) *res = expr; \ ++ return res; \ ++ } ++ ++#define __ifunc(type_name, name, expr, arg, init) \ ++ extern __typeof (type_name) name __attribute__ \ ++ ((ifunc (#name "_ifunc"))); \ ++ __ifunc_resolver (type_name, name, expr, arg, init, static) ++ ++#define s390_libc_ifunc_expr_init() ++#define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR) \ ++ __ifunc (TYPE_FUNC, FUNC, EXPR, unsigned long int hwcap, \ ++ s390_libc_ifunc_expr_init); +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-3.patch b/SOURCES/glibc-rh1375235-3.patch new file mode 100644 index 00000000..f02294be --- /dev/null +++ b/SOURCES/glibc-rh1375235-3.patch @@ -0,0 +1,373 @@ +From 418f5be91f4c843d63db0d29eee65ff46eb59202 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 03/10] S390: Move utf8-utf16-z9.c to multiarch folder and use + s390_libc_ifunc_expr macro. + +upstream-commit df6cc7ee3b2e032c6c62cedd30b1c0fefbb43018 + +The utf8-utf16-z9.c iconv module is using ifunc and thus the ifunc part should +be in multiarch folder. Otherwise ifunc is used even if you configure +with --disable-multi-arch. + +This patch moves the ifunc resolvers to the new file +sysdeps/s390/multiarch/utf8-utf16-z9.c. The resolvers are now implemented +with s390_libc_ifunc_expr macro instead of using gcc attribute ifunc directly. + +The ifunc versions are implemented in sysdeps/s390/utf8-utf16-z9.c. +Each version is only implemented if needed or supported. Therefore there is +a block at beginning of the file which selects the versions which should be +defined depending on support for multiarch, vector-support and used minimum +architecture level. This block defines HAVE_[FROM|TO]_[C|CU|VX] to 1 or 0. +The code below is rearranged and surrounded +by #if HAVE_[FROM|TO]_[C|CU|VX] == 1. There is no functional change. + +The cu instructions are z9 zarch instructions. As the major distros are +already using the newer z196 as architecture level set, those instructions +can be used as fallback version instead of the c-code. This behaviour is +decided at compile time via HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT. + +ChangeLog: + + * sysdeps/s390/multiarch/utf8-utf16-z9.c: New File. + * sysdeps/s390/utf8-utf16-z9.c: Move ifunc resolvers to multiarch + folder and define ifunc versions depending on HAVE_[FROM|TO]_[C|CU|VX]. + (HAVE_FROM_C, HAVE_FROM_CU, HAVE_FROM_VX, HAVE_TO_C, HAVE_TO_VX, + FROM_LOOP_DEFAULT, FROM_LOOP_C, FROM_LOOP_CU, FROM_LOOP_VX, +--- + sysdeps/s390/multiarch/utf8-utf16-z9.c | 48 ++++++++ + sysdeps/s390/utf8-utf16-z9.c | 197 +++++++++++++++++---------------- + 2 files changed, 150 insertions(+), 95 deletions(-) + create mode 100644 sysdeps/s390/multiarch/utf8-utf16-z9.c + +diff --git a/sysdeps/s390/multiarch/utf8-utf16-z9.c b/sysdeps/s390/multiarch/utf8-utf16-z9.c +new file mode 100644 +index 0000000..b55ef1a +--- /dev/null ++++ b/sysdeps/s390/multiarch/utf8-utf16-z9.c +@@ -0,0 +1,48 @@ ++/* Conversion between UTF-8 and UTF-16 - multiarch s390 version. ++ ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef FROM_LOOP ++#define FROM_LOOP __from_utf8_loop ++#undef TO_LOOP ++#define TO_LOOP __to_utf8_loop ++ ++#define _SINGLE_NAME(NAME) NAME##_single ++#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME) ++strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP)) ++strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) ++ ++/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ ++s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, ++ (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) ++ ? FROM_LOOP_VX ++ : (HAVE_FROM_CU && (hwcap & HWCAP_S390_ZARCH ++ && hwcap & HWCAP_S390_HIGH_GPRS ++ && hwcap & HWCAP_S390_ETF3EH)) ++ ? FROM_LOOP_CU ++ : FROM_LOOP_DEFAULT); ++ ++s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, ++ (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) ++ ? TO_LOOP_VX ++ : TO_LOOP_DEFAULT); ++ ++#include +diff --git a/sysdeps/s390/utf8-utf16-z9.c b/sysdeps/s390/utf8-utf16-z9.c +index d3dc9bd..d870a29 100644 +--- a/sysdeps/s390/utf8-utf16-z9.c ++++ b/sysdeps/s390/utf8-utf16-z9.c +@@ -1,4 +1,4 @@ +-/* Conversion between UTF-16 and UTF-32 BE/internal. ++/* Conversion between UTF-8 and UTF-16 - s390 version. + + This module uses the Z9-109 variants of the Convert Unicode + instructions. +@@ -27,8 +27,35 @@ + #include + #include + #include +-#include + #include ++#include ++ ++/* Select which versions should be defined depending on support ++ for multiarch, vector and used minimum architecture level. */ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_FROM_C 0 ++# define FROM_LOOP_DEFAULT FROM_LOOP_CU ++#else ++# define HAVE_FROM_C 1 ++# define FROM_LOOP_DEFAULT FROM_LOOP_C ++#endif ++ ++#define HAVE_TO_C 1 ++#define TO_LOOP_DEFAULT TO_LOOP_C ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT || defined USE_MULTIARCH ++# define HAVE_FROM_CU 1 ++#else ++# define HAVE_FROM_CU 0 ++#endif ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH ++# define HAVE_FROM_VX 1 ++# define HAVE_TO_VX 1 ++#else ++# define HAVE_FROM_VX 0 ++# define HAVE_TO_VX 0 ++#endif + + #if defined HAVE_S390_VX_GCC_SUPPORT + # define ASM_CLOBBER_VR(NR) , NR +@@ -49,8 +76,8 @@ + #define MAX_NEEDED_FROM 4 + #define MIN_NEEDED_TO 2 + #define MAX_NEEDED_TO 4 +-#define FROM_LOOP __from_utf8_loop +-#define TO_LOOP __to_utf8_loop ++#define FROM_LOOP FROM_LOOP_DEFAULT ++#define TO_LOOP TO_LOOP_DEFAULT + #define FROM_DIRECTION (dir == from_utf8) + #define ONE_DIRECTION 0 + +@@ -214,9 +241,8 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } + +-#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1")) +- +-#define HW_FROM_VX \ ++#if HAVE_FROM_VX == 1 ++# define HW_FROM_VX \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ +@@ -291,11 +317,42 @@ gconv_end (struct __gconv_step *data) + inptr = pInput; \ + outptr = pOutput; \ + } +-#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) ++# define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) + ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++# define FROM_LOOP_VX __from_utf8_loop_vx ++# define LOOPFCT FROM_LOOP_VX ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_VX ++# include ++#else ++# define FROM_LOOP_VX NULL ++#endif /* HAVE_FROM_VX != 1 */ ++ ++#if HAVE_FROM_CU == 1 ++# define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1")) + ++/* Generate loop-function with hardware utf-convert instruction. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++# define FROM_LOOP_CU __from_utf8_loop_etf3eh ++# define LOOPFCT FROM_LOOP_CU ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_ETF3EH ++# include ++#else ++# define FROM_LOOP_CU NULL ++#endif /* HAVE_FROM_CU != 1 */ ++ ++#if HAVE_FROM_C == 1 + /* The software implementation is based on the code in gconv_simple.c. */ +-#define BODY_FROM_C \ ++# define BODY_FROM_C \ + { \ + /* Next input byte. */ \ + uint16_t ch = *inptr; \ +@@ -443,66 +500,26 @@ gconv_end (struct __gconv_step *data) + } + + /* Generate loop-function with software implementation. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_c +-#define LOOP_NEED_FLAGS +-#define BODY BODY_FROM_C +-#include +- +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_etf3eh +-#define LOOP_NEED_FLAGS +-#define BODY BODY_FROM_ETF3EH +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector and utf-convert instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_FROM + # define MAX_NEEDED_INPUT MAX_NEEDED_FROM + # define MIN_NEEDED_OUTPUT MIN_NEEDED_TO + # define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-# define LOOPFCT __from_utf8_loop_vx ++# define FROM_LOOP_C __from_utf8_loop_c ++# define LOOPFCT FROM_LOOP_C + # define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_VX ++# define BODY BODY_FROM_C + # include +-#endif +- +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__from_utf8_loop_c) +-__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) +-__from_utf8_loop; +- +-static void * +-__from_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __from_utf8_loop_vx; +- else +-#endif +- if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS +- && dl_hwcap & HWCAP_S390_ETF3EH) +- return __from_utf8_loop_etf3eh; +- else +- return __from_utf8_loop_c; +-} +- +-strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) ++#else ++# define FROM_LOOP_C NULL ++#endif /* HAVE_FROM_C != 1 */ + + /* Conversion from UTF-16 to UTF-8. */ + ++#if HAVE_TO_C == 1 + /* The software routine is based on the functionality of the S/390 + hardware instruction (cu21) as described in the Principles of + Operation. */ +-#define BODY_TO_C \ ++# define BODY_TO_C \ + { \ + uint16_t c = get16 (inptr); \ + \ +@@ -601,7 +618,22 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + inptr += 2; \ + } + +-#define BODY_TO_VX \ ++/* Generate loop-function with software implementation. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MAX_NEEDED_INPUT MAX_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define TO_LOOP_C __to_utf8_loop_c ++# define LOOPFCT TO_LOOP_C ++# define BODY BODY_TO_C ++# define LOOP_NEED_FLAGS ++# include ++#else ++# define TO_LOOP_C NULL ++#endif /* HAVE_TO_C != 1 */ ++ ++#if HAVE_TO_VX == 1 ++# define BODY_TO_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ +@@ -771,48 +803,23 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + STANDARD_TO_LOOP_ERR_HANDLER (2); \ + } + +-/* Generate loop-function with software implementation. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MAX_NEEDED_INPUT MAX_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#if defined HAVE_S390_VX_ASM_SUPPORT +-# define LOOPFCT __to_utf8_loop_c +-# define BODY BODY_TO_C +-# define LOOP_NEED_FLAGS +-# include +- +-/* Generate loop-function with software implementation. */ ++/* Generate loop-function with vector implementation. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_TO + # define MAX_NEEDED_INPUT MAX_NEEDED_TO + # define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM + # define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-# define LOOPFCT __to_utf8_loop_vx ++# define TO_LOOP_VX __to_utf8_loop_vx ++# define LOOPFCT TO_LOOP_VX + # define BODY BODY_TO_VX + # define LOOP_NEED_FLAGS + # include +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__to_utf8_loop_c) +-__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) +-__to_utf8_loop; +- +-static void * +-__to_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +- if (dl_hwcap & HWCAP_S390_VX) +- return __to_utf8_loop_vx; +- else +- return __to_utf8_loop_c; +-} +- +-strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) +- + #else +-# define LOOPFCT TO_LOOP +-# define BODY BODY_TO_C +-# define LOOP_NEED_FLAGS +-# include +-#endif /* !HAVE_S390_VX_ASM_SUPPORT */ +- +-#include ++# define TO_LOOP_VX NULL ++#endif /* HAVE_TO_VX != 1 */ ++ ++/* This file also exists in sysdeps/s390/multiarch/ which ++ generates ifunc resolvers for FROM/TO_LOOP functions ++ and includes iconv/skeleton.c afterwards. */ ++#if ! defined USE_MULTIARCH ++# include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-4.patch b/SOURCES/glibc-rh1375235-4.patch new file mode 100644 index 00000000..da3e4121 --- /dev/null +++ b/SOURCES/glibc-rh1375235-4.patch @@ -0,0 +1,313 @@ +From 9acd7055583a99e912d353ded6a3b4715ee2562a Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 04/10] S390: Move utf16-utf32-z9.c to multiarch folder and use + s390_libc_ifunc_expr macro. + +upstream-commit 85286aaf1dd7216a64964752d147c5ce3c4067d0 + +The utf16-utf32-z9.c iconv module is using ifunc and thus the ifunc part should +be in multiarch folder. Otherwise ifunc is used even if you configure +with --disable-multi-arch. + +This patch moves the ifunc resolvers to the new file +sysdeps/s390/multiarch/utf16-utf32-z9.c. The resolvers are now implemented +with s390_libc_ifunc_expr macro instead of using gcc attribute ifunc directly. + +The ifunc versions are implemented in sysdeps/s390/utf16-utf32-z9.c. +Each version is only implemented if needed or supported. Therefore there is +a block at beginning of the file which selects the versions which should be +defined depending on support for multiarch, vector-support and used minimum +architecture level. This block defines HAVE_[FROM|TO]_[C|VX] to 1 or 0. +The code below is rearranged and surrounded +by #if HAVE_[FROM|TO]_[C|VX] == 1. There is no functional change. + +ChangeLog: + + * sysdeps/s390/multiarch/utf16-utf32-z9.c: New File. + * sysdeps/s390/utf16-utf32-z9.c: Move ifunc resolvers to multiarch + folder and define ifunc versions depending on HAVE_[FROM|TO]_[C|VX]. + (HAVE_FROM_C, HAVE_FROM_VX, HAVE_TO_C, HAVE_TO_VX, FROM_LOOP_DEFAULT, + FROM_LOOP_C, FROM_LOOP_VX, TO_LOOP_DEFAULT, TO_LOOP_C, TO_LOOP_VX): + New Define. +--- + sysdeps/s390/multiarch/utf16-utf32-z9.c | 44 ++++++++++ + sysdeps/s390/utf16-utf32-z9.c | 142 ++++++++++++++++---------------- + 2 files changed, 114 insertions(+), 72 deletions(-) + create mode 100644 sysdeps/s390/multiarch/utf16-utf32-z9.c + +diff --git a/sysdeps/s390/multiarch/utf16-utf32-z9.c b/sysdeps/s390/multiarch/utf16-utf32-z9.c +new file mode 100644 +index 0000000..6e64169 +--- /dev/null ++++ b/sysdeps/s390/multiarch/utf16-utf32-z9.c +@@ -0,0 +1,44 @@ ++/* Conversion between UTF-16 and UTF-32 BE/internal - multiarch s390 version. ++ ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef FROM_LOOP ++#define FROM_LOOP __from_utf16_loop ++#undef TO_LOOP ++#define TO_LOOP __to_utf16_loop ++ ++#define _SINGLE_NAME(NAME) NAME##_single ++#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME) ++strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP)) ++strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) ++ ++/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ ++s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, ++ (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) ++ ? FROM_LOOP_VX ++ : FROM_LOOP_DEFAULT); ++ ++s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, ++ (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) ++ ? TO_LOOP_VX ++ : TO_LOOP_DEFAULT); ++ ++#include +diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c +index 5d2ac44..5a39d5d 100644 +--- a/sysdeps/s390/utf16-utf32-z9.c ++++ b/sysdeps/s390/utf16-utf32-z9.c +@@ -27,8 +27,23 @@ + #include + #include + #include +-#include + #include ++#include ++ ++/* Select which versions should be defined depending on support ++ for multiarch, vector and used minimum architecture level. */ ++#define HAVE_FROM_C 1 ++#define FROM_LOOP_DEFAULT FROM_LOOP_C ++#define HAVE_TO_C 1 ++#define TO_LOOP_DEFAULT TO_LOOP_C ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH ++# define HAVE_FROM_VX 1 ++# define HAVE_TO_VX 1 ++#else ++# define HAVE_FROM_VX 0 ++# define HAVE_TO_VX 0 ++#endif + + #if defined HAVE_S390_VX_GCC_SUPPORT + # define ASM_CLOBBER_VR(NR) , NR +@@ -53,8 +68,8 @@ + #define MIN_NEEDED_FROM 2 + #define MAX_NEEDED_FROM 4 + #define MIN_NEEDED_TO 4 +-#define FROM_LOOP __from_utf16_loop +-#define TO_LOOP __to_utf16_loop ++#define FROM_LOOP FROM_LOOP_DEFAULT ++#define TO_LOOP TO_LOOP_DEFAULT + #define FROM_DIRECTION (dir == from_utf16) + #define ONE_DIRECTION 0 + +@@ -174,9 +189,10 @@ gconv_end (struct __gconv_step *data) + + /* Conversion function from UTF-16 to UTF-32 internal/BE. */ + ++#if HAVE_FROM_C == 1 + /* The software routine is copied from utf-16.c (minus bytes + swapping). */ +-#define BODY_FROM_C \ ++# define BODY_FROM_C \ + { \ + uint16_t u1 = get16 (inptr); \ + \ +@@ -220,7 +236,22 @@ gconv_end (struct __gconv_step *data) + outptr += 4; \ + } + +-#define BODY_FROM_VX \ ++ ++/* Generate loop-function with software routing. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define FROM_LOOP_C __from_utf16_loop_c ++# define LOOPFCT FROM_LOOP_C ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_C ++# include ++#else ++# define FROM_LOOP_C NULL ++#endif /* HAVE_FROM_C != 1 */ ++ ++#if HAVE_FROM_VX == 1 ++# define BODY_FROM_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ +@@ -255,7 +286,7 @@ gconv_end (struct __gconv_step *data) + /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ + "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ + " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ +- /* At least on uint16_t is in range of surrogates. \ ++ /* At least one uint16_t is in range of surrogates. \ + Store the preceding chars. */ \ + "10: vlgvb %[R_TMP],%%v19,7\n\t" \ + " vuplhh %%v17,%%v16\n\t" \ +@@ -351,52 +382,26 @@ gconv_end (struct __gconv_step *data) + } + + +-/* Generate loop-function with software routing. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#if defined HAVE_S390_VX_ASM_SUPPORT +-# define LOOPFCT __from_utf16_loop_c +-# define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_C +-# include +- + /* Generate loop-function with hardware vector instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_FROM + # define MAX_NEEDED_INPUT MAX_NEEDED_FROM + # define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-# define LOOPFCT __from_utf16_loop_vx ++# define FROM_LOOP_VX __from_utf16_loop_vx ++# define LOOPFCT FROM_LOOP_VX + # define LOOP_NEED_FLAGS + # define BODY BODY_FROM_VX + # include +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__from_utf16_loop_c) +-__attribute__ ((ifunc ("__from_utf16_loop_resolver"))) +-__from_utf16_loop; +- +-static void * +-__from_utf16_loop_resolver (unsigned long int dl_hwcap) +-{ +- if (dl_hwcap & HWCAP_S390_VX) +- return __from_utf16_loop_vx; +- else +- return __from_utf16_loop_c; +-} +- +-strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + #else +-# define LOOPFCT FROM_LOOP +-# define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_C +-# include +-#endif ++# define FROM_LOOP_VX NULL ++#endif /* HAVE_FROM_VX != 1 */ ++ + + /* Conversion from UTF-32 internal/BE to UTF-16. */ + ++#if HAVE_TO_C == 1 + /* The software routine is copied from utf-16.c (minus bytes + swapping). */ +-#define BODY_TO_C \ ++# define BODY_TO_C \ + { \ + uint32_t c = get32 (inptr); \ + \ +@@ -439,7 +444,21 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + inptr += 4; \ + } + +-#define BODY_TO_VX \ ++/* Generate loop-function with software routing. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define TO_LOOP_C __to_utf16_loop_c ++# define LOOPFCT TO_LOOP_C ++# define LOOP_NEED_FLAGS ++# define BODY BODY_TO_C ++# include ++#else ++# define TO_LOOP_C NULL ++#endif /* HAVE_TO_C != 1 */ ++ ++#if HAVE_TO_VX == 1 ++# define BODY_TO_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ +@@ -563,43 +582,22 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +-/* Generate loop-function with software routing. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf16_loop_c +-#define LOOP_NEED_FLAGS +-#define BODY BODY_TO_C +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT + /* Generate loop-function with hardware vector instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_TO + # define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM + # define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-# define LOOPFCT __to_utf16_loop_vx ++# define TO_LOOP_VX __to_utf16_loop_vx ++# define LOOPFCT TO_LOOP_VX + # define LOOP_NEED_FLAGS + # define BODY BODY_TO_VX + # include ++#else ++# define TO_LOOP_VX NULL ++#endif /* HAVE_TO_VX != 1 */ ++ ++/* This file also exists in sysdeps/s390/multiarch/ which ++ generates ifunc resolvers for FROM/TO_LOOP functions ++ and includes iconv/skeleton.c afterwards. */ ++#if ! defined USE_MULTIARCH ++# include + #endif +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__to_utf16_loop_c) +-__attribute__ ((ifunc ("__to_utf16_loop_resolver"))) +-__to_utf16_loop; +- +-static void * +-__to_utf16_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __to_utf16_loop_vx; +- else +-#endif +- return __to_utf16_loop_c; +-} +- +-strong_alias (__to_utf16_loop_c_single, __to_utf16_loop_single) +- +- +-#include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-5.patch b/SOURCES/glibc-rh1375235-5.patch new file mode 100644 index 00000000..51fd2161 --- /dev/null +++ b/SOURCES/glibc-rh1375235-5.patch @@ -0,0 +1,387 @@ +From f69ff8906aeb1c4fd762bc9964f8a261963c30d5 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 05/10] S390: Move utf8-utf32-z9.c to multiarch folder and use + s390_libc_ifunc_expr macro. + +upstream-commit 5ea9ce3749007348a8d12e8eef9e0ccc6fd90aec + +The utf8-utf32-z9.c iconv module is using ifunc and thus the ifunc part should +be in multiarch folder. Otherwise ifunc is used even if you configure +with --disable-multi-arch. + +This patch moves the ifunc resolvers to the new file +sysdeps/s390/multiarch/utf8-utf32-z9.c. The resolvers are now implemented +with s390_libc_ifunc_expr macro instead of using gcc attribute ifunc directly. + +The ifunc versions are implemented in sysdeps/s390/utf8-utf32-z9.c. +Each version is only implemented if needed or supported. Therefore there is +a block at beginning of the file which selects the versions which should be +defined depending on support for multiarch, vector-support and used minimum +architecture level. This block defines HAVE_[FROM|TO]_[C|CU|VX] to 1 or 0. +The code below is rearranged and surrounded +by #if HAVE_[FROM|TO]_[C|CU|VX] == 1. There is no functional change. + +The cu instructions are z9 zarch instructions. As the major distros are +already using the newer z196 as architecture level set, those instructions +can be used as fallback version instead of the c-code. This behaviour is +decided at compile time via HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT. + +ChangeLog: + + * sysdeps/s390/multiarch/utf8-utf32-z9.c: New File. + * sysdeps/s390/utf8-utf32-z9.c: Move ifunc resolvers to multiarch + folder and define ifunc versions depending on HAVE_[FROM|TO]_[C|CU|VX]. + (HAVE_FROM_C, HAVE_FROM_CU, HAVE_FROM_VX, HAVE_TO_C, HAVE_TO_VX, + FROM_LOOP_DEFAULT, FROM_LOOP_C, FROM_LOOP_CU, FROM_LOOP_VX, + TO_LOOP_DEFAULT, TO_LOOP_C, TO_LOOP_VX): New Define. +--- + sysdeps/s390/multiarch/utf8-utf32-z9.c | 48 ++++++++ + sysdeps/s390/utf8-utf32-z9.c | 215 +++++++++++++++++---------------- + 2 files changed, 160 insertions(+), 103 deletions(-) + create mode 100644 sysdeps/s390/multiarch/utf8-utf32-z9.c + +diff --git a/sysdeps/s390/multiarch/utf8-utf32-z9.c b/sysdeps/s390/multiarch/utf8-utf32-z9.c +new file mode 100644 +index 0000000..faf1f46 +--- /dev/null ++++ b/sysdeps/s390/multiarch/utf8-utf32-z9.c +@@ -0,0 +1,48 @@ ++/* Conversion between UTF-8 and UTF-32 - multiarch s390 version. ++ ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef FROM_LOOP ++#define FROM_LOOP __from_utf8_loop ++#undef TO_LOOP ++#define TO_LOOP __to_utf8_loop ++ ++#define _SINGLE_NAME(NAME) NAME##_single ++#define SINGLE_NAME(NAME) _SINGLE_NAME(NAME) ++strong_alias (SINGLE_NAME (FROM_LOOP_DEFAULT), SINGLE_NAME (FROM_LOOP)) ++strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) ++ ++/* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ ++s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, ++ (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) ++ ? FROM_LOOP_VX ++ : (HAVE_FROM_CU && (hwcap & HWCAP_S390_ZARCH ++ && hwcap & HWCAP_S390_HIGH_GPRS ++ && hwcap & HWCAP_S390_ETF3EH)) ++ ? FROM_LOOP_CU ++ : FROM_LOOP_DEFAULT); ++ ++s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, ++ (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) ++ ? TO_LOOP_VX ++ : TO_LOOP_DEFAULT); ++ ++#include +diff --git a/sysdeps/s390/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c +index efae745..e06d11e 100644 +--- a/sysdeps/s390/utf8-utf32-z9.c ++++ b/sysdeps/s390/utf8-utf32-z9.c +@@ -27,8 +27,35 @@ + #include + #include + #include +-#include + #include ++#include ++ ++/* Select which versions should be defined depending on support ++ for multiarch, vector and used minimum architecture level. */ ++#ifdef HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT ++# define HAVE_FROM_C 0 ++# define FROM_LOOP_DEFAULT FROM_LOOP_CU ++#else ++# define HAVE_FROM_C 1 ++# define FROM_LOOP_DEFAULT FROM_LOOP_C ++#endif ++ ++#define HAVE_TO_C 1 ++#define TO_LOOP_DEFAULT TO_LOOP_C ++ ++#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT || defined USE_MULTIARCH ++# define HAVE_FROM_CU 1 ++#else ++# define HAVE_FROM_CU 0 ++#endif ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH ++# define HAVE_FROM_VX 1 ++# define HAVE_TO_VX 1 ++#else ++# define HAVE_FROM_VX 0 ++# define HAVE_TO_VX 0 ++#endif + + #if defined HAVE_S390_VX_GCC_SUPPORT + # define ASM_CLOBBER_VR(NR) , NR +@@ -48,8 +75,8 @@ + #define MIN_NEEDED_FROM 1 + #define MAX_NEEDED_FROM 6 + #define MIN_NEEDED_TO 4 +-#define FROM_LOOP __from_utf8_loop +-#define TO_LOOP __to_utf8_loop ++#define FROM_LOOP FROM_LOOP_DEFAULT ++#define TO_LOOP TO_LOOP_DEFAULT + #define FROM_DIRECTION (dir == from_utf8) + #define ONE_DIRECTION 0 + +@@ -303,12 +330,9 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } + +-/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */ +-#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1")) +- +- ++#if HAVE_FROM_C == 1 + /* The software routine is copied from gconv_simple.c. */ +-#define BODY_FROM_C \ ++# define BODY_FROM_C \ + { \ + /* Next input byte. */ \ + uint32_t ch = *inptr; \ +@@ -408,7 +432,50 @@ gconv_end (struct __gconv_step *data) + outptr += sizeof (uint32_t); \ + } + +-#define HW_FROM_VX \ ++/* These definitions apply to the UTF-8 to UTF-32 direction. The ++ software implementation for UTF-8 still supports multibyte ++ characters up to 6 bytes whereas the hardware variant does not. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define FROM_LOOP_C __from_utf8_loop_c ++# define LOOPFCT FROM_LOOP_C ++ ++# define LOOP_NEED_FLAGS ++ ++# define STORE_REST STORE_REST_COMMON ++# define UNPACK_BYTES UNPACK_BYTES_COMMON ++# define CLEAR_STATE CLEAR_STATE_COMMON ++# define BODY BODY_FROM_C ++# include ++#else ++# define FROM_LOOP_C NULL ++#endif /* HAVE_FROM_C != 1 */ ++ ++#if HAVE_FROM_CU == 1 ++/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */ ++# define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1")) ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define FROM_LOOP_CU __from_utf8_loop_etf3eh ++# define LOOPFCT FROM_LOOP_CU ++ ++# define LOOP_NEED_FLAGS ++ ++# define STORE_REST STORE_REST_COMMON ++# define UNPACK_BYTES UNPACK_BYTES_COMMON ++# define CLEAR_STATE CLEAR_STATE_COMMON ++# define BODY BODY_FROM_ETF3EH ++# include ++#else ++# define FROM_LOOP_CU NULL ++#endif /* HAVE_FROM_CU != 1 */ ++ ++#if HAVE_FROM_VX == 1 ++# define HW_FROM_VX \ + { \ + register const unsigned char* pInput asm ("8") = inptr; \ + register size_t inlen asm ("9") = inend - inptr; \ +@@ -500,45 +567,14 @@ gconv_end (struct __gconv_step *data) + inptr = pInput; \ + outptr = pOutput; \ + } +-#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) ++# define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) + +-/* These definitions apply to the UTF-8 to UTF-32 direction. The +- software implementation for UTF-8 still supports multibyte +- characters up to 6 bytes whereas the hardware variant does not. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_c +- +-#define LOOP_NEED_FLAGS +- +-#define STORE_REST STORE_REST_COMMON +-#define UNPACK_BYTES UNPACK_BYTES_COMMON +-#define CLEAR_STATE CLEAR_STATE_COMMON +-#define BODY BODY_FROM_C +-#include +- +- +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_etf3eh +- +-#define LOOP_NEED_FLAGS +- +-#define STORE_REST STORE_REST_COMMON +-#define UNPACK_BYTES UNPACK_BYTES_COMMON +-#define CLEAR_STATE CLEAR_STATE_COMMON +-#define BODY BODY_FROM_ETF3EH +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector instructions. */ ++/* Generate loop-function with hardware vector and utf-convert instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_FROM + # define MAX_NEEDED_INPUT MAX_NEEDED_FROM + # define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-# define LOOPFCT __from_utf8_loop_vx ++# define FROM_LOOP_VX __from_utf8_loop_vx ++# define LOOPFCT FROM_LOOP_VX + + # define LOOP_NEED_FLAGS + +@@ -547,33 +583,13 @@ gconv_end (struct __gconv_step *data) + # define CLEAR_STATE CLEAR_STATE_COMMON + # define BODY BODY_FROM_VX + # include +-#endif +- +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__from_utf8_loop_c) +-__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) +-__from_utf8_loop; +- +-static void * +-__from_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __from_utf8_loop_vx; +- else +-#endif +- if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS +- && dl_hwcap & HWCAP_S390_ETF3EH) +- return __from_utf8_loop_etf3eh; +- else +- return __from_utf8_loop_c; +-} +- +-strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) ++#else ++# define FROM_LOOP_VX NULL ++#endif /* HAVE_FROM_VX != 1 */ + ++#if HAVE_TO_C == 1 + /* The software routine mimics the S/390 cu41 instruction. */ +-#define BODY_TO_C \ ++# define BODY_TO_C \ + { \ + uint32_t wc = *((const uint32_t *) inptr); \ + \ +@@ -657,8 +673,22 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + inptr += 4; \ + } + ++/* Generate loop-function with software routing. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define TO_LOOP_C __to_utf8_loop_c ++# define LOOPFCT TO_LOOP_C ++# define BODY BODY_TO_C ++# define LOOP_NEED_FLAGS ++# include ++#else ++# define TO_LOOP_C NULL ++#endif /* HAVE_TO_C != 1 */ ++ ++#if HAVE_TO_VX == 1 + /* The hardware routine uses the S/390 vector instructions. */ +-#define BODY_TO_VX \ ++# define BODY_TO_VX \ + { \ + size_t inlen = inend - inptr; \ + size_t outlen = outend - outptr; \ +@@ -820,43 +850,22 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +-/* Generate loop-function with software routing. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf8_loop_c +-#define BODY BODY_TO_C +-#define LOOP_NEED_FLAGS +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector and utf-convert instructions. */ ++/* Generate loop-function with hardware vector instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_TO + # define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM + # define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-# define LOOPFCT __to_utf8_loop_vx ++# define TO_LOOP_VX __to_utf8_loop_vx ++# define LOOPFCT TO_LOOP_VX + # define BODY BODY_TO_VX + # define LOOP_NEED_FLAGS + # include ++#else ++# define TO_LOOP_VX NULL ++#endif /* HAVE_TO_VX != 1 */ ++ ++/* This file also exists in sysdeps/s390/multiarch/ which ++ generates ifunc resolvers for FROM/TO_LOOP functions ++ and includes iconv/skeleton.c afterwards. */ ++#if ! defined USE_MULTIARCH ++# include + #endif +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__to_utf8_loop_c) +-__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) +-__to_utf8_loop; +- +-static void * +-__to_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __to_utf8_loop_vx; +- else +-#endif +- return __to_utf8_loop_c; +-} +- +-strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) +- +- +-#include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-6.patch b/SOURCES/glibc-rh1375235-6.patch new file mode 100644 index 00000000..4646beda --- /dev/null +++ b/SOURCES/glibc-rh1375235-6.patch @@ -0,0 +1,85 @@ +From 71956c369a72a64ff26ca90198a42f0bf2967217 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 06/10] S390: Add new hwcap values for new cpu architecture - + arch12. + +upstream-commit f21f59124d8a4d22b20e7a926462937d89e8988e + +The new hwcap values indicate support for: +- Vector packed decimal facility +- Vector enhancements facility 1 +- Guarded storage facility + +Note: arch12 is NOT the official name of the new CPU. +It refers to the edition number of the Principle of Operations manual. + +ChangeLog: + + * sysdeps/s390/dl-procinfo.c (_dl_s390_cap_flags): + Add vxd, vxe, gs flag. + * sysdeps/s390/dl-procinfo.h: Add HWCAP_S390_VXD, HWCAP_S390_VXE, + HWCAP_S390_GS capability. + * sysdeps/unix/sysv/linux/s390/bits/hwcap.h + (HWCAP_S390_VXD, HWCAP_S390_VXE, HWCAP_S390_GS): Define. +--- + sysdeps/s390/dl-procinfo.c | 5 +++-- + sysdeps/s390/dl-procinfo.h | 5 ++++- + sysdeps/unix/sysv/linux/s390/bits/hwcap.h | 3 +++ + 3 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/dl-procinfo.c b/sysdeps/s390/dl-procinfo.c +index f353528..aa08eca 100644 +--- a/sysdeps/s390/dl-procinfo.c ++++ b/sysdeps/s390/dl-procinfo.c +@@ -46,11 +46,12 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_s390_cap_flags + #else +-PROCINFO_CLASS const char _dl_s390_cap_flags[12][9] ++PROCINFO_CLASS const char _dl_s390_cap_flags[15][9] + #endif + #ifndef PROCINFO_DECL + = { +- "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", "highgprs", "te", "vx" ++ "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", "edat", "etf3eh", ++ "highgprs", "te", "vx", "vxd", "vxe", "gs" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/s390/dl-procinfo.h b/sysdeps/s390/dl-procinfo.h +index 80747f0..748c3d1 100644 +--- a/sysdeps/s390/dl-procinfo.h ++++ b/sysdeps/s390/dl-procinfo.h +@@ -21,7 +21,7 @@ + #define _DL_PROCINFO_H 1 + #include + +-#define _DL_HWCAP_COUNT 12 ++#define _DL_HWCAP_COUNT 15 + + #define _DL_PLATFORMS_COUNT 8 + +@@ -51,6 +51,9 @@ enum + HWCAP_S390_HIGH_GPRS = 1 << 9, + HWCAP_S390_TE = 1 << 10, + HWCAP_S390_VX = 1 << 11, ++ HWCAP_S390_VXD = 1 << 12, ++ HWCAP_S390_VXE = 1 << 13, ++ HWCAP_S390_GS = 1 << 14, + }; + + #define HWCAP_IMPORTANT (HWCAP_S390_ZARCH | HWCAP_S390_LDISP \ +diff --git a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +index bd2ce3a..58b1929 100644 +--- a/sysdeps/unix/sysv/linux/s390/bits/hwcap.h ++++ b/sysdeps/unix/sysv/linux/s390/bits/hwcap.h +@@ -36,3 +36,6 @@ + #define HWCAP_S390_HIGH_GPRS 512 + #define HWCAP_S390_TE 1024 + #define HWCAP_S390_VX 2048 ++#define HWCAP_S390_VXD 4096 ++#define HWCAP_S390_VXE 8192 ++#define HWCAP_S390_GS 16384 +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-7.patch b/SOURCES/glibc-rh1375235-7.patch new file mode 100644 index 00000000..0d19affe --- /dev/null +++ b/SOURCES/glibc-rh1375235-7.patch @@ -0,0 +1,177 @@ +From 9b9fd1ec26b5386072fa967bac0771df5e86a284 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:58 +0200 +Subject: [PATCH 07/10] S390: Use cu41 instruction for converting from utf32 to + utf8. + +upstream-commit 23ea69a9d6e9ab28c66a232b767a800b04eaa938 + +This patch adds an ifunc variant to use the cu instruction on arch12 CPUs. +This new ifunc variant can be built if binutils support z13 vector +instructions. At runtime, HWCAP_S390_VXE decides if we can use the +cu41 instruction. + +ChangeLog: + + * sysdeps/s390/utf8-utf32-z9.c (__to_utf8_loop_vx_cu): + Use vector and cu41 instruction. + * sysdeps/s390/multiarch/utf8-utf32-z9.c: Add __to_utf8_loop_vx_cu + in ifunc resolver. +--- + sysdeps/s390/multiarch/utf8-utf32-z9.c | 8 ++- + sysdeps/s390/utf8-utf32-z9.c | 112 +++++++++++++++++++++++++++++++++ + 2 files changed, 117 insertions(+), 3 deletions(-) + +diff --git a/sysdeps/s390/multiarch/utf8-utf32-z9.c b/sysdeps/s390/multiarch/utf8-utf32-z9.c +index faf1f46..0c6d9e9 100644 +--- a/sysdeps/s390/multiarch/utf8-utf32-z9.c ++++ b/sysdeps/s390/multiarch/utf8-utf32-z9.c +@@ -41,8 +41,10 @@ s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, + : FROM_LOOP_DEFAULT); + + s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, +- (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) +- ? TO_LOOP_VX +- : TO_LOOP_DEFAULT); ++ (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) ++ ? TO_LOOP_VX_CU ++ : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) ++ ? TO_LOOP_VX ++ : TO_LOOP_DEFAULT); + + #include +diff --git a/sysdeps/s390/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c +index e06d11e..e4f2e0c 100644 +--- a/sysdeps/s390/utf8-utf32-z9.c ++++ b/sysdeps/s390/utf8-utf32-z9.c +@@ -52,9 +52,11 @@ + #if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH + # define HAVE_FROM_VX 1 + # define HAVE_TO_VX 1 ++# define HAVE_TO_VX_CU 1 + #else + # define HAVE_FROM_VX 0 + # define HAVE_TO_VX 0 ++# define HAVE_TO_VX_CU 0 + #endif + + #if defined HAVE_S390_VX_GCC_SUPPORT +@@ -863,6 +865,116 @@ gconv_end (struct __gconv_step *data) + # define TO_LOOP_VX NULL + #endif /* HAVE_TO_VX != 1 */ + ++#if HAVE_TO_VX_CU == 1 ++#define BODY_TO_VX_CU \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm ("11") = outend - outptr; \ ++ unsigned long tmp, tmp2; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ ++ " vzero %%v21\n\t" \ ++ " vleih %%v21,8192,0\n\t" /* element 0: > */ \ ++ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-32 chars <= 0x7f. */ \ ++ "0: clgijl %[R_INLEN],64,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP],0\n\t" \ ++ /* Shorten to byte values. */ \ ++ " vpkf %%v23,%%v16,%%v17\n\t" \ ++ " vpkf %%v24,%%v18,%%v19\n\t" \ ++ " vpkh %%v23,%%v23,%%v24\n\t" \ ++ /* Checking for values > 0x7f. */ \ ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ ++ " jno 12f\n\t" \ ++ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ ++ " jno 13f\n\t" \ ++ /* Store 16bytes to outptr. */ \ ++ " vst %%v23,0(%[R_OUT])\n\t" \ ++ " aghi %[R_INLEN],-64\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_IN],64(%[R_IN])\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],64,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Found a value > 0x7f. */ \ ++ "13: ahi %[R_TMP],4\n\t" \ ++ "12: ahi %[R_TMP],4\n\t" \ ++ "11: ahi %[R_TMP],4\n\t" \ ++ "10: vlgvb %[R_I],%%v22,7\n\t" \ ++ " srlg %[R_I],%[R_I],2\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ " je 20f\n\t" \ ++ /* Store characters before invalid one... */ \ ++ " slgr %[R_OUTLEN],%[R_I]\n\t" \ ++ "15: aghi %[R_I],-1\n\t" \ ++ " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ ++ /* ... and update pointers. */ \ ++ " aghi %[R_I],1\n\t" \ ++ " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ ++ " sllg %[R_I],%[R_I],2\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_I]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu41 %[R_OUT],%[R_IN]\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \ ++ , [R_I] "=a" (tmp2) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ ++ ASM_CLOBBER_VR ("v24") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define TO_LOOP_VX_CU __to_utf8_loop_vx_cu ++# define LOOPFCT TO_LOOP_VX_CU ++# define BODY BODY_TO_VX_CU ++# define LOOP_NEED_FLAGS ++# include ++#else ++# define TO_LOOP_VX_CU NULL ++#endif /* HAVE_TO_VX_CU != 1 */ ++ + /* This file also exists in sysdeps/s390/multiarch/ which + generates ifunc resolvers for FROM/TO_LOOP functions + and includes iconv/skeleton.c afterwards. */ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-8.patch b/SOURCES/glibc-rh1375235-8.patch new file mode 100644 index 00000000..ed67d69c --- /dev/null +++ b/SOURCES/glibc-rh1375235-8.patch @@ -0,0 +1,179 @@ +From ed26260ce20cd6c05e8c8526bd2bd9fadfee8d19 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:59 +0200 +Subject: [PATCH 08/10] S390: Use cu42 instruction for converting from utf32 to + utf16. + +upstream-commit 593e4da186906525e2a0bdc4d87601bd0c2625eb + +This patch adds an ifunc variant to use the cu instruction on arch12 CPUs. +This new ifunc variant can be built if binutils support z13 vector +instructions. At runtime, HWCAP_S390_VXE decides if we can use the +cu42 instruction. + +ChangeLog: + + * sysdeps/s390/utf16-utf32-z9.c (__to_utf16_loop_vx_cu): + Use vector and cu42 instruction. + * sysdeps/s390/multiarch/utf16-utf32-z9.c: + Add __to_utf16_loop_vx_cu in ifunc resolver. +--- + sysdeps/s390/multiarch/utf16-utf32-z9.c | 8 ++- + sysdeps/s390/utf16-utf32-z9.c | 107 +++++++++++++++++++++++++++++++- + 2 files changed, 111 insertions(+), 4 deletions(-) + +diff --git a/sysdeps/s390/multiarch/utf16-utf32-z9.c b/sysdeps/s390/multiarch/utf16-utf32-z9.c +index 6e64169..ded3cc2 100644 +--- a/sysdeps/s390/multiarch/utf16-utf32-z9.c ++++ b/sysdeps/s390/multiarch/utf16-utf32-z9.c +@@ -37,8 +37,10 @@ s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, + : FROM_LOOP_DEFAULT); + + s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, +- (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) +- ? TO_LOOP_VX +- : TO_LOOP_DEFAULT); ++ (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) ++ ? TO_LOOP_VX_CU ++ : (HAVE_TO_VX && (hwcap & HWCAP_S390_VX)) ++ ? TO_LOOP_VX ++ : TO_LOOP_DEFAULT); + + #include +diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c +index 5a39d5d..b1728d6 100644 +--- a/sysdeps/s390/utf16-utf32-z9.c ++++ b/sysdeps/s390/utf16-utf32-z9.c +@@ -40,9 +40,11 @@ + #if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH + # define HAVE_FROM_VX 1 + # define HAVE_TO_VX 1 ++# define HAVE_TO_VX_CU 1 + #else + # define HAVE_FROM_VX 0 + # define HAVE_TO_VX 0 ++# define HAVE_TO_VX_CU 0 + #endif + + #if defined HAVE_S390_VX_GCC_SUPPORT +@@ -471,7 +473,7 @@ gconv_end (struct __gconv_step *data) + " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ +- /* Loop which handles UTF-16 chars \ ++ /* Loop which handles UTF-32 chars \ + ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ + "0: clgijl %[R_INLEN],32,2f\n\t" \ + " clgijl %[R_OUTLEN],16,2f\n\t" \ +@@ -595,6 +597,109 @@ gconv_end (struct __gconv_step *data) + # define TO_LOOP_VX NULL + #endif /* HAVE_TO_VX != 1 */ + ++#if HAVE_TO_VX_CU == 1 ++#define BODY_TO_VX_CU \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm ("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for surrogates. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-32 chars \ ++ ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ ++ "0: clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ ++ /* Shorten to UTF-16. */ \ ++ " vpkf %%v18,%%v16,%%v17\n\t" \ ++ /* Check for surrogate chars. */ \ ++ " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \ ++ " jno 11f\n\t" \ ++ /* Store 16 bytes to buf_out. */ \ ++ " vst %%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-32\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ ++ and check for ch >= 0x10000. (v30, v31) */ \ ++ "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ ++ " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \ ++ /* At least one UTF32 char is in range of surrogates. \ ++ Store the preceding characters. */ \ ++ "11: ahi %[R_TMP2],16\n\t" \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " agr %[R_TMP],%[R_TMP2]\n\t" \ ++ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 20f\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handles UTF16 surrogates with convert instruction. */ \ ++ "20: cu42 %[R_OUT],%[R_IN]\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ \ ++ if (__glibc_likely (inlen == 0) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inlen < 4) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define TO_LOOP_VX_CU __to_utf16_loop_vx_cu ++# define LOOPFCT TO_LOOP_VX_CU ++# define LOOP_NEED_FLAGS ++# define BODY BODY_TO_VX_CU ++# include ++#else ++# define TO_LOOP_VX_CU NULL ++#endif /* HAVE_TO_VX_CU != 1 */ ++ + /* This file also exists in sysdeps/s390/multiarch/ which + generates ifunc resolvers for FROM/TO_LOOP functions + and includes iconv/skeleton.c afterwards. */ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1375235-9.patch b/SOURCES/glibc-rh1375235-9.patch new file mode 100644 index 00000000..13b18b60 --- /dev/null +++ b/SOURCES/glibc-rh1375235-9.patch @@ -0,0 +1,187 @@ +From 8430e4e5d5da2ed14d33638c476654c2a0474d2a Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Thu, 27 Jul 2017 10:53:59 +0200 +Subject: [PATCH 09/10] S390: Use cu24 instruction for converting from utf16 to + utf32. + +upstream-commit f0137ff31da85bc7d9bd4e621af958d8b7249475 + +This patch adds an ifunc variant to use the cu instruction on arch12 CPUs. +This new ifunc variant can be built if binutils support z13 vector +instructions. At runtime, HWCAP_S390_VXE decides if we can use the +cu24 instruction. + +ChangeLog: + + * sysdeps/s390/utf16-utf32-z9.c (__from_utf16_loop_vx_cu): + Use vector and cu24 instruction. + * sysdeps/s390/multiarch/utf16-utf32-z9.c: + Add __from_utf16_loop_vx_cu in ifunc resolver. +--- + sysdeps/s390/multiarch/utf16-utf32-z9.c | 8 ++- + sysdeps/s390/utf16-utf32-z9.c | 113 +++++++++++++++++++++++++++++++- + 2 files changed, 117 insertions(+), 4 deletions(-) + +diff --git a/sysdeps/s390/multiarch/utf16-utf32-z9.c b/sysdeps/s390/multiarch/utf16-utf32-z9.c +index ded3cc2..917de5f 100644 +--- a/sysdeps/s390/multiarch/utf16-utf32-z9.c ++++ b/sysdeps/s390/multiarch/utf16-utf32-z9.c +@@ -32,9 +32,11 @@ strong_alias (SINGLE_NAME (TO_LOOP_DEFAULT), SINGLE_NAME (TO_LOOP)) + + /* Generate ifunc'ed loop functions for FROM/TO_LOOP. */ + s390_libc_ifunc_expr (FROM_LOOP_DEFAULT, FROM_LOOP, +- (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) +- ? FROM_LOOP_VX +- : FROM_LOOP_DEFAULT); ++ (HAVE_FROM_VX_CU && (hwcap & HWCAP_S390_VXE)) ++ ? FROM_LOOP_VX_CU ++ : (HAVE_FROM_VX && (hwcap & HWCAP_S390_VX)) ++ ? FROM_LOOP_VX ++ : FROM_LOOP_DEFAULT); + + s390_libc_ifunc_expr (TO_LOOP_DEFAULT, TO_LOOP, + (HAVE_TO_VX_CU && (hwcap & HWCAP_S390_VXE)) +diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c +index b1728d6..c09a425 100644 +--- a/sysdeps/s390/utf16-utf32-z9.c ++++ b/sysdeps/s390/utf16-utf32-z9.c +@@ -39,10 +39,12 @@ + + #if defined HAVE_S390_VX_ASM_SUPPORT && defined USE_MULTIARCH + # define HAVE_FROM_VX 1 ++# define HAVE_FROM_VX_CU 1 + # define HAVE_TO_VX 1 + # define HAVE_TO_VX_CU 1 + #else + # define HAVE_FROM_VX 0 ++# define HAVE_FROM_VX_CU 0 + # define HAVE_TO_VX 0 + # define HAVE_TO_VX_CU 0 + #endif +@@ -383,7 +385,6 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } + +- + /* Generate loop-function with hardware vector instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_FROM + # define MAX_NEEDED_INPUT MAX_NEEDED_FROM +@@ -397,6 +398,116 @@ gconv_end (struct __gconv_step *data) + # define FROM_LOOP_VX NULL + #endif /* HAVE_FROM_VX != 1 */ + ++#if HAVE_FROM_VX_CU == 1 ++#define BODY_FROM_VX_CU \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm ("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for surrogates. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ ++ "0: clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],32,20f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ /* Check for surrogate chars. */ \ ++ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ /* Enlarge to UTF-32. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ /* Store 32 bytes to buf_out. */ \ ++ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-32\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],32,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ ++ "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* At least one uint16_t is in range of surrogates. \ ++ Store the preceding chars. */ \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 20f\n\t" \ ++ " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ "11: \n\t" /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handles UTF16 surrogates with convert instruction. */ \ ++ "20: cu24 %[R_OUT],%[R_IN],1\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ \ ++ if (__glibc_likely (inlen == 0) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inlen == 1) \ ++ { \ ++ /* Input does not contain a complete utf16 character. */ \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ else if (result != __GCONV_ILLEGAL_INPUT) \ ++ { \ ++ /* Input is >= 2 and < 4 bytes (as cu24 would have processed \ ++ a possible next utf16 character) and not illegal. \ ++ => we have a single high surrogate at end of input. */ \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } ++ ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define FROM_LOOP_VX_CU __from_utf16_loop_vx_cu ++# define LOOPFCT FROM_LOOP_VX_CU ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_VX_CU ++# include ++#else ++# define FROM_LOOP_VX_CU NULL ++#endif /* HAVE_FROM_VX_CU != 1 */ + + /* Conversion from UTF-32 internal/BE to UTF-16. */ + +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-1.patch b/SOURCES/glibc-rh1380680-1.patch new file mode 100644 index 00000000..5d2c26b2 --- /dev/null +++ b/SOURCES/glibc-rh1380680-1.patch @@ -0,0 +1,189 @@ +From af67490e3e2ad2a32c1bcfac8923c025ac247518 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 15:05:28 +0100 +Subject: [PATCH 01/17] S390: Get rid of make warning: overriding recipe for + target gconv-modules. + +Upstream commit c70e9913d2fc2d0bf6a3ca98a4dece759d40a4ec + +This patch introduces a way to provide an architecture dependent gconv-modules +file. Before this patch, the gconv-modules file was normally installed from +src-dir/iconvdata/gconv-modules. The S390 Makefile had overridden the +installation recipe (with a make warning) in order to install the +gconv-module-s390 file from build-dir. +The iconvdata/Makefile provides another recipe, which copies the gconv-modules +file from src to build dir, which are used by the testcases. +Thus the testcases does not use the currently build s390-modules. + +This patch uses build-dir/iconvdata/gconv-modules for installation, which +is generated by concatenating src-dir/iconvdata/gconv-modules and the +architecture specific one. The latter one can be specified by setting the variable +sysdeps-gconv-modules in sysdeps/.../Makefile. + +The architecture specific gconv-modules file is emitted before the common one +because these modules aren't used in all possible conversions. E.g. the converting +from INTERNAL to UTF-16 used the common UTF-16.so module instead of UTF16_UTF32_Z9.so. + +This way, the s390-Makefile does not need to override the recipe for gconv-modules +and no warning is emitted anymore. +Since we no longer support empty objpfx the conditional test in iconvdata/Makefile +is removed. + +ChangeLog: + + * iconvdata/Makefile ($(inst_gconvdir)/gconv-modules): + Install file from $(objpfx)gconv-modules. + ($(objpfx)gconv-modules): Concatenate architecture specific file + in variable sysdeps-gconv-modules and gconv-modules in src dir. + * sysdeps/s390/gconv-modules: New file. + * sysdeps/s390/s390-64/Makefile: ($(inst_gconvdir)/gconv-modules): + Deleted. + ($(objpfx)gconv-modules-s390): Deleted. + (sysdeps-gconv-modules): New variable. +--- + iconvdata/Makefile | 6 ++--- + sysdeps/s390/gconv-modules | 50 ++++++++++++++++++++++++++++++++++++++++++ + sysdeps/s390/s390-64/Makefile | 51 +------------------------------------------ + 3 files changed, 53 insertions(+), 54 deletions(-) + create mode 100644 sysdeps/s390/gconv-modules + +diff --git a/iconvdata/Makefile b/iconvdata/Makefile +index a99539e..e2624de 100644 +--- a/iconvdata/Makefile ++++ b/iconvdata/Makefile +@@ -244,7 +244,7 @@ headers: $(addprefix $(objpfx), $(generated-modules:=.h)) + $(addprefix $(inst_gconvdir)/, $(modules.so)): \ + $(inst_gconvdir)/%: $(objpfx)% $(+force) + $(do-install-program) +-$(inst_gconvdir)/gconv-modules: gconv-modules $(+force) ++$(inst_gconvdir)/gconv-modules: $(objpfx)gconv-modules $(+force) + $(do-install) + ifeq (no,$(cross-compiling)) + # Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary +@@ -319,7 +319,5 @@ do-tests-clean common-mostlyclean: tst-tables-clean + tst-tables-clean: + -rm -f $(objpfx)tst-*.table $(objpfx)tst-EUC-TW.irreversible + +-ifdef objpfx + $(objpfx)gconv-modules: gconv-modules +- cp $^ $@ +-endif ++ cat $(sysdeps-gconv-modules) $^ > $@ +diff --git a/sysdeps/s390/gconv-modules b/sysdeps/s390/gconv-modules +new file mode 100644 +index 0000000..7021105 +--- /dev/null ++++ b/sysdeps/s390/gconv-modules +@@ -0,0 +1,50 @@ ++# GNU libc iconv configuration. ++# Copyright (C) 1997-2016 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# All lines contain the following information: ++ ++# If the lines start with `module' ++# fromset: either a name triple or a regular expression triple. ++# toset: a name triple or an expression with \N to get regular ++# expression matching results. ++# filename: filename of the module implementing the transformation. ++# If it is not absolute the path is made absolute by prepending ++# the directory the configuration file is found in. ++# cost: optional cost of the transformation. Default is 1. ++ ++# If the lines start with `alias' ++# alias: alias name which is not really recognized. ++# name: the real name of the character set ++ ++# S/390 hardware accelerated modules ++# from to module cost ++module ISO-8859-1// IBM037// ISO-8859-1_CP037_Z900 1 ++module IBM037// ISO-8859-1// ISO-8859-1_CP037_Z900 1 ++module ISO-10646/UTF8/ UTF-32// UTF8_UTF32_Z9 1 ++module UTF-32BE// ISO-10646/UTF8/ UTF8_UTF32_Z9 1 ++module ISO-10646/UTF8/ UTF-32BE// UTF8_UTF32_Z9 1 ++module UTF-16BE// UTF-32// UTF16_UTF32_Z9 1 ++module UTF-32BE// UTF-16// UTF16_UTF32_Z9 1 ++module INTERNAL UTF-16// UTF16_UTF32_Z9 1 ++module UTF-32BE// UTF-16BE// UTF16_UTF32_Z9 1 ++module INTERNAL UTF-16BE// UTF16_UTF32_Z9 1 ++module UTF-16BE// UTF-32BE// UTF16_UTF32_Z9 1 ++module UTF-16BE// INTERNAL UTF16_UTF32_Z9 1 ++module UTF-16BE// ISO-10646/UTF8/ UTF8_UTF16_Z9 1 ++module ISO-10646/UTF8/ UTF-16// UTF8_UTF16_Z9 1 ++module ISO-10646/UTF8/ UTF-16BE// UTF8_UTF16_Z9 1 +diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile +index 939e947..bb958bd 100644 +--- a/sysdeps/s390/s390-64/Makefile ++++ b/sysdeps/s390/s390-64/Makefile +@@ -39,54 +39,5 @@ $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ + $(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) + $(do-install-program) + +-$(objpfx)gconv-modules-s390: gconv-modules $(+force) +- cp $< $@ +- echo >> $@ +- echo "# S/390 hardware accelerated modules" >> $@ +- echo -n "module ISO-8859-1// IBM037// " >> $@ +- echo " ISO-8859-1_CP037_Z900 1" >> $@ +- echo -n "module IBM037// ISO-8859-1// " >> $@ +- echo " ISO-8859-1_CP037_Z900 1" >> $@ +- echo -n "module ISO-10646/UTF8/ UTF-32// " >> $@ +- echo " UTF8_UTF32_Z9 1" >> $@ +- echo -n "module UTF-32BE// ISO-10646/UTF8/ " >> $@ +- echo " UTF8_UTF32_Z9 1" >> $@ +- echo -n "module ISO-10646/UTF8/ UTF-32BE// " >> $@ +- echo " UTF8_UTF32_Z9 1" >> $@ +- echo -n "module UTF-16BE// UTF-32// " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module UTF-32BE// UTF-16// " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module INTERNAL UTF-16// " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module UTF-32BE// UTF-16BE// " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module INTERNAL UTF-16BE// " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module UTF-16BE// UTF-32BE// " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module UTF-16BE// INTERNAL " >> $@ +- echo " UTF16_UTF32_Z9 1" >> $@ +- echo -n "module UTF-16BE// ISO-10646/UTF8/ " >> $@ +- echo " UTF8_UTF16_Z9 1" >> $@ +- echo -n "module ISO-10646/UTF8/ UTF-16// " >> $@ +- echo " UTF8_UTF16_Z9 1" >> $@ +- echo -n "module ISO-10646/UTF8/ UTF-16BE// " >> $@ +- echo " UTF8_UTF16_Z9 1" >> $@ +- +-$(inst_gconvdir)/gconv-modules: $(objpfx)gconv-modules-s390 $(+force) +- $(do-install) +-ifeq (no,$(cross-compiling)) +-# Update the $(prefix)/lib/gconv/gconv-modules.cache file. This is necessary +-# if this libc has more gconv modules than the previously installed one. +- if test -f "$(inst_gconvdir)/gconv-modules.cache"; then \ +- LC_ALL=C LANGUAGE=C \ +- $(common-objpfx)elf/ld.so --library-path $(rpath-link) \ +- $(common-objpfx)iconv/iconvconfig \ +- $(addprefix --prefix=,$(install_root)); \ +- fi +-else +- @echo '*@*@*@ You should recreate $(inst_gconvdir)/gconv-modules.cache' +-endif +- ++sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules + endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-10.patch b/SOURCES/glibc-rh1380680-10.patch new file mode 100644 index 00000000..319e1876 --- /dev/null +++ b/SOURCES/glibc-rh1380680-10.patch @@ -0,0 +1,48 @@ +From 8b42b08a1bce2899c0f66ce66ef5fc75745c8f38 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:19:30 +0100 +Subject: [PATCH 10/17] S390: Fix build error with gcc6 in utf8_utf16-z9.c. + +upstream commit 808d70228891ab4d4795ab3dd1e015bf63ba18d6 + +This patch fixes the build error with gcc6: +array subscript is above array bounds [-Werror=array-bounds] + +While including loop.c to construct the SINGLE(LOOPFCT) method +for converting from UTF-16 to UTF-8, the bytebuf array with length +MAX_NEEDED_INPUT is used as inptr. MAX_NEEDED_INPUT defaults to +MIN_NEEDED_INPUT if not defined before including loop.c. +Thus bytebuf has a length of 2. +This patch defines MAX_NEEDED_INPUT to MAX_NEEDED_TO, which is 4. + +ChangeLog: + + * sysdeps/s390/s390-64/utf8-utf16-z9.c + (MAX_NEEDED_INPUT): New define. + (MAX_NEEDED_OUTPUT): New define. +--- + sysdeps/s390/s390-64/utf8-utf16-z9.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +index 6dad1c2..590a149 100644 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c +@@ -183,6 +183,7 @@ gconv_end (struct __gconv_step *data) + #define MIN_NEEDED_INPUT MIN_NEEDED_FROM + #define MAX_NEEDED_INPUT MAX_NEEDED_FROM + #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO + #define LOOPFCT FROM_LOOP + /* The software implementation is based on the code in gconv_simple.c. */ + #define BODY \ +@@ -340,6 +341,7 @@ gconv_end (struct __gconv_step *data) + /* Conversion from UTF-16 to UTF-8. */ + + #define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MAX_NEEDED_INPUT MAX_NEEDED_TO + #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM + #define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM + #define LOOPFCT TO_LOOP +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-11.patch b/SOURCES/glibc-rh1380680-11.patch new file mode 100644 index 00000000..586e455b --- /dev/null +++ b/SOURCES/glibc-rh1380680-11.patch @@ -0,0 +1,762 @@ +From ec79c95f95869a30d3f13c6229ebef1ad4931281 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:20:45 +0100 +Subject: [PATCH 11/17] S390: Optimize utf8-utf16 module. + +Upstream commit 5bd11b19099b3f22d821515f9c93f1ecc1a7e15e + +This patch reworks the s390 specific module to convert between utf8 and utf16. +Now ifunc is used to choose either the c or etf3eh (with convert utf instruction) +variants at runtime. Furthermore a new vector variant for z13 is introduced +which will be build and chosen if vector support is available at build / runtime. + +In case of converting utf 8 to utf16, the vector variant optimizes input of +1byte utf8 characters. The convert utf instruction is used if a multibyte utf8 +character is found. + +For the other direction utf16 to utf8, the cu21 instruction can't be re-enabled, +because it does not report an error, if the input-stream consists of a single +low surrogate utf16 char (e.g. 0xdc00). This applies to the newest z13, too. +Thus there is only the c or the new vector variant, which can handle 1..4 byte +utf8 characters. + +The c variant from utf16 to utf8 has beed fixed. If a high surrogate was at the +end of the input-buffer, then errno was set to EINVAL and the input-pointer +pointed just after the high surrogate. Now it points to the beginning of the +high surrogate. + +This patch also fixes some whitespace errors. The c variant from utf8 to utf16 +is now checking that tail-bytes starts with 0b10... and the value is not in +range of an utf16 surrogate. + +Furthermore, the etf3eh variants are handling the "UTF-xx//IGNORE" case now. +Before they ignored the ignore-case and always stopped at an error. + +ChangeLog: + + * sysdeps/s390/s390-64/utf8-utf16-z9.c: Use ifunc to select c, + etf3eh or new vector loop-variant. +--- + sysdeps/s390/s390-64/utf8-utf16-z9.c | 547 ++++++++++++++++++++++++++++------- + 1 file changed, 441 insertions(+), 106 deletions(-) + +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +index 590a149..b36ee9e 100644 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c +@@ -30,33 +30,27 @@ + #include + #include + +-/* UTF-16 big endian byte order mark. */ +-#define BOM_UTF16 0xfeff ++#if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++#else ++# define ASM_CLOBBER_VR(NR) ++#endif + ++/* Defines for skeleton.c. */ + #define DEFINE_INIT 0 + #define DEFINE_FINI 0 + #define MIN_NEEDED_FROM 1 + #define MAX_NEEDED_FROM 4 + #define MIN_NEEDED_TO 2 + #define MAX_NEEDED_TO 4 +-#define FROM_LOOP from_utf8_loop +-#define TO_LOOP to_utf8_loop ++#define FROM_LOOP __from_utf8_loop ++#define TO_LOOP __to_utf8_loop + #define FROM_DIRECTION (dir == from_utf8) + #define ONE_DIRECTION 0 +-#define PREPARE_LOOP \ +- enum direction dir = ((struct utf8_data *) step->__data)->dir; \ +- int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ +- \ +- if (emit_bom && !data->__internal_use \ +- && data->__invocation_counter == 0) \ +- { \ +- /* Emit the UTF-16 Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 2 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put16u (outbuf, BOM_UTF16); \ +- outbuf += 2; \ +- } ++ ++ ++/* UTF-16 big endian byte order mark. */ ++#define BOM_UTF16 0xfeff + + /* Direction of the transformation. */ + enum direction +@@ -151,16 +145,16 @@ gconv_end (struct __gconv_step *data) + register unsigned long long outlen __asm__("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- __asm__ volatile (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ ++ __asm__ __volatile__ (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ +@@ -169,50 +163,135 @@ gconv_end (struct __gconv_step *data) + if (cc == 1) \ + { \ + result = __GCONV_FULL_OUTPUT; \ +- break; \ + } \ + else if (cc == 2) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ +- break; \ + } \ + } + ++#define PREPARE_LOOP \ ++ enum direction dir = ((struct utf8_data *) step->__data)->dir; \ ++ int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ ++ \ ++ if (emit_bom && !data->__internal_use \ ++ && data->__invocation_counter == 0) \ ++ { \ ++ /* Emit the UTF-16 Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 2 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put16u (outbuf, BOM_UTF16); \ ++ outbuf += 2; \ ++ } ++ + /* Conversion function from UTF-8 to UTF-16. */ ++#define BODY_FROM_HW(ASM) \ ++ { \ ++ ASM; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ \ ++ int i; \ ++ for (i = 1; inptr + i < inend && i < 5; ++i) \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ break; \ ++ \ ++ if (__glibc_likely (inptr + i == inend \ ++ && result == __GCONV_EMPTY_INPUT)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (i); \ ++ } ++ ++#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1")) ++ ++#define HW_FROM_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ ++ " vrepib %%v31,0x20\n\t" \ ++ /* Loop which handles UTF-8 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],32,20f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Enlarge to UTF-16. */ \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ /* Store 32 bytes to buf_out. */ \ ++ " vstm %%v18,%%v19,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-32\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],32,20f\n\t" \ ++ " j 1b\n\t" \ ++ "10:\n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ " vlgvb %[R_TMP],%%v17,7\n\t" \ ++ " sllk %[R_TMP2],%[R_TMP],1\n\t" /* Compute highest \ ++ index to store. */ \ ++ " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ ++ " ahi %[R_TMP2],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " vstl %%v19,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ "11: \n\t" /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu12 %[R_OUT],%[R_IN],1\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ } ++#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) ++ + +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-#define LOOPFCT FROM_LOOP + /* The software implementation is based on the code in gconv_simple.c. */ +-#define BODY \ ++#define BODY_FROM_C \ + { \ +- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ +- { \ +- HARDWARE_CONVERT ("cu12 %0, %1, 1"); \ +- \ +- if (inptr != inend) \ +- { \ +- int i; \ +- for (i = 1; inptr + i < inend; ++i) \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- break; \ +- \ +- if (__glibc_likely (inptr + i == inend)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_FROM_LOOP_ERR_HANDLER (i); \ +- } \ +- continue; \ +- } \ +- \ + /* Next input byte. */ \ + uint16_t ch = *inptr; \ + \ +- if (__glibc_likely (ch < 0x80)) \ ++ if (__glibc_likely (ch < 0x80)) \ + { \ + /* One byte sequence. */ \ + ++inptr; \ +@@ -230,13 +309,13 @@ gconv_end (struct __gconv_step *data) + cnt = 2; \ + ch &= 0x1f; \ + } \ +- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ +- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ +@@ -257,7 +336,7 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } \ + \ +- if (__glibc_unlikely (inptr + cnt > inend)) \ ++ if (__glibc_unlikely (inptr + cnt > inend)) \ + { \ + /* We don't have enough input. But before we report \ + that check that all the bytes are correct. */ \ +@@ -265,7 +344,7 @@ gconv_end (struct __gconv_step *data) + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ +- if (__glibc_likely (inptr + i == inend)) \ ++ if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +@@ -280,23 +359,31 @@ gconv_end (struct __gconv_step *data) + low) are needed. */ \ + uint16_t zabcd, high, low; \ + \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ ++ /* Check if tail-bytes >= 0x80, < 0xc0. */ \ ++ for (i = 1; i < cnt; ++i) \ ++ { \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ /* This is an illegal encoding. */ \ ++ goto errout; \ ++ } \ ++ \ + /* See Principles of Operations cu12. */ \ + zabcd = (((inptr[0] & 0x7) << 2) | \ +- ((inptr[1] & 0x30) >> 4)) - 1; \ ++ ((inptr[1] & 0x30) >> 4)) - 1; \ + \ + /* z-bit must be zero after subtracting 1. */ \ + if (zabcd & 0x10) \ + STANDARD_FROM_LOOP_ERR_HANDLER (4) \ + \ + high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \ +- high |= zabcd << 6; /* abcd bits */ \ ++ high |= zabcd << 6; /* abcd bits */ \ + high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \ + high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \ + \ +@@ -326,8 +413,19 @@ gconv_end (struct __gconv_step *data) + ch <<= 6; \ + ch |= byte & 0x3f; \ + } \ +- inptr += cnt; \ + \ ++ /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ ++ If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ ++ have been represented with fewer than cnt bytes. */ \ ++ if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ ++ /* Do not accept UTF-16 surrogates. */ \ ++ || (ch >= 0xd800 && ch <= 0xdfff)) \ ++ { \ ++ /* This is an illegal encoding. */ \ ++ goto errout; \ ++ } \ ++ \ ++ inptr += cnt; \ + } \ + } \ + /* Now adjust the pointers and store the result. */ \ +@@ -335,43 +433,70 @@ gconv_end (struct __gconv_step *data) + outptr += sizeof (uint16_t); \ + } + ++/* Generate loop-function with software implementation. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_c ++#define LOOP_NEED_FLAGS ++#define BODY BODY_FROM_C ++#include ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_etf3eh + #define LOOP_NEED_FLAGS ++#define BODY BODY_FROM_ETF3EH + #include + ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++# define LOOPFCT __from_utf8_loop_vx ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_VX ++# include ++#endif ++ ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_utf8_loop_c) ++__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) ++__from_utf8_loop; ++ ++static void * ++__from_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __from_utf8_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ETF3EH) ++ return __from_utf8_loop_etf3eh; ++ else ++ return __from_utf8_loop_c; ++} ++ ++strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) ++ + /* Conversion from UTF-16 to UTF-8. */ + +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MAX_NEEDED_INPUT MAX_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT TO_LOOP + /* The software routine is based on the functionality of the S/390 + hardware instruction (cu21) as described in the Principles of + Operation. */ +-#define BODY \ ++#define BODY_TO_C \ + { \ +- /* The hardware instruction currently fails to report an error for \ +- isolated low surrogates so we have to disable the instruction \ +- until this gets resolved. */ \ +- if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \ +- { \ +- HARDWARE_CONVERT ("cu21 %0, %1, 1"); \ +- if (inptr != inend) \ +- { \ +- /* Check if the third byte is \ +- a valid start of a UTF-16 surrogate. */ \ +- if (inend - inptr == 3 && (inptr[3] & 0xfc) != 0xdc) \ +- STANDARD_TO_LOOP_ERR_HANDLER (3); \ +- \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- continue; \ +- } \ +- \ + uint16_t c = get16 (inptr); \ + \ +- if (__glibc_likely (c <= 0x007f)) \ ++ if (__glibc_likely (c <= 0x007f)) \ + { \ + /* Single byte UTF-8 char. */ \ + *outptr = c & 0xff; \ +@@ -379,20 +504,20 @@ gconv_end (struct __gconv_step *data) + } \ + else if (c >= 0x0080 && c <= 0x07ff) \ + { \ +- /* Two byte UTF-8 char. */ \ ++ /* Two byte UTF-8 char. */ \ + \ +- if (__glibc_unlikely (outptr + 2 > outend)) \ ++ if (__glibc_unlikely (outptr + 2 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ +- outptr[0] = 0xc0; \ +- outptr[0] |= c >> 6; \ ++ outptr[0] = 0xc0; \ ++ outptr[0] |= c >> 6; \ + \ +- outptr[1] = 0x80; \ +- outptr[1] |= c & 0x3f; \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= c & 0x3f; \ + \ + outptr += 2; \ + } \ +@@ -400,7 +525,7 @@ gconv_end (struct __gconv_step *data) + { \ + /* Three byte UTF-8 char. */ \ + \ +- if (__glibc_unlikely (outptr + 3 > outend)) \ ++ if (__glibc_unlikely (outptr + 3 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -419,22 +544,22 @@ gconv_end (struct __gconv_step *data) + } \ + else if (c >= 0xd800 && c <= 0xdbff) \ + { \ +- /* Four byte UTF-8 char. */ \ ++ /* Four byte UTF-8 char. */ \ + uint16_t low, uvwxy; \ + \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ +- inptr += 2; \ +- if (__glibc_unlikely (inptr + 2 > inend)) \ ++ if (__glibc_unlikely (inptr + 4 > inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ + } \ + \ ++ inptr += 2; \ + low = get16 (inptr); \ + \ + if ((low & 0xfc00) != 0xdc00) \ +@@ -461,11 +586,221 @@ gconv_end (struct __gconv_step *data) + } \ + else \ + { \ +- STANDARD_TO_LOOP_ERR_HANDLER (2); \ ++ STANDARD_TO_LOOP_ERR_HANDLER (2); \ + } \ + inptr += 2; \ + } +-#define LOOP_NEED_FLAGS +-#include ++ ++#define BODY_TO_VX \ ++ { \ ++ size_t inlen = inend - inptr; \ ++ size_t outlen = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for values <= 0x7f. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ /* Loop which handles UTF-16 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],32,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ ++ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ ++ /* Check for > 1byte UTF-8 chars. */ \ ++ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \ ++ " jno 11f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Shorten to UTF-8. */ \ ++ " vpkh %%v18,%%v16,%%v17\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-32\n\t" \ ++ /* Store 16 bytes to buf_out. */ \ ++ " vst %%v18,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],32,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch > 0x7f. (v30, v31) */ \ ++ "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \ ++ "10:\n\t" \ ++ " vlgvb %[R_TMP],%%v19,7\n\t" \ ++ /* Shorten to UTF-8. */ \ ++ " vpkh %%v18,%%v16,%%v17\n\t" \ ++ " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \ ++ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 13f\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ "13: \n\t" \ ++ /* Calculate remaining uint16_t values in loaded vrs. */ \ ++ " lghi %[R_TMP2],16\n\t" \ ++ " slgr %[R_TMP2],%[R_TMP3]\n\t" \ ++ " llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-2\n\t" \ ++ " j 22f\n\t" \ ++ /* Handle remaining bytes. */ \ ++ "2: \n\t" \ ++ /* Zero, one or more bytes available? */ \ ++ " clgfi %[R_INLEN],1\n\t" \ ++ " locghie %[R_RES],%[RES_IN_FULL]\n\t" /* Only one byte. */ \ ++ " jle 99f\n\t" /* End if less than two bytes. */ \ ++ /* Calculate remaining uint16_t values in inptr. */ \ ++ " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ ++ /* Handle multibyte utf8-char. */ \ ++ "20: llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-2\n\t" \ ++ /* Test if ch is 1-byte UTF-8 char. */ \ ++ "21: clijh %[R_TMP],0x7f,22f\n\t" \ ++ /* Handle 1-byte UTF-8 char. */ \ ++ "31: slgfi %[R_OUTLEN],1\n\t" \ ++ " jl 90f \n\t" \ ++ " stc %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " la %[R_OUT],1(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 2-byte UTF-8 char. */ \ ++ "22: clfi %[R_TMP],0x7ff\n\t" \ ++ " jh 23f\n\t" \ ++ /* Handle 2-byte UTF-8 char. */ \ ++ "32: slgfi %[R_OUTLEN],2\n\t" \ ++ " jl 90f \n\t" \ ++ " llill %[R_TMP3],0xc080\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \ ++ " sth %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],2(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 3-byte UTF-8 char. */ \ ++ "23: clfi %[R_TMP],0xd7ff\n\t" \ ++ " jh 24f\n\t" \ ++ /* Handle 3-byte UTF-8 char. */ \ ++ "33: slgfi %[R_OUTLEN],3\n\t" \ ++ " jl 90f \n\t" \ ++ " llilf %[R_TMP3],0xe08080\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \ ++ " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],3(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 4-byte UTF-8 char. */ \ ++ "24: clfi %[R_TMP],0xdfff\n\t" \ ++ " jh 33b\n\t" /* Handle this 3-byte UTF-8 char. */ \ ++ " clfi %[R_TMP],0xdbff\n\t" \ ++ " locghih %[R_RES],%[RES_IN_ILL]\n\t" \ ++ " jh 99f\n\t" /* Jump away if this is a low surrogate \ ++ without a preceding high surrogate. */ \ ++ /* Handle 4-byte UTF-8 char. */ \ ++ "34: slgfi %[R_OUTLEN],4\n\t" \ ++ " jl 90f \n\t" \ ++ " slgfi %[R_INLEN],2\n\t" \ ++ " locghil %[R_RES],%[RES_IN_FULL]\n\t" \ ++ " jl 99f\n\t" /* Jump away if low surrogate is missing. */ \ ++ " llilf %[R_TMP3],0xf0808080\n\t" \ ++ " aghi %[R_TMP],0x40\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],37,39,16\n\t" /* 1. byte: uvw */ \ ++ " risbgn %[R_TMP3],%[R_TMP],42,43,14\n\t" /* 2. byte: xy */ \ ++ " risbgn %[R_TMP3],%[R_TMP],44,47,14\n\t" /* 2. byte: efgh */ \ ++ " risbgn %[R_TMP3],%[R_TMP],50,51,12\n\t" /* 3. byte: ij */ \ ++ " llh %[R_TMP],2(%[R_IN])\n\t" /* Load low surrogate. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],52,55,2\n\t" /* 3. byte: klmn */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte: opqrst */ \ ++ " nilf %[R_TMP],0xfc00\n\t" \ ++ " clfi %[R_TMP],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ ++ " locghine %[R_RES],%[RES_IN_ILL]\n\t" \ ++ " jne 99f\n\t" /* Jump away if low surrogate is invalid. */ \ ++ " st %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " aghi %[R_TMP2],-2\n\t" \ ++ " jh 20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Exit with __GCONV_FULL_OUTPUT. */ \ ++ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ ++ "99: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ if (__glibc_likely (inptr == inend) \ ++ || result != __GCONV_ILLEGAL_INPUT) \ ++ break; \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (2); \ ++ } ++ ++/* Generate loop-function with software implementation. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MAX_NEEDED_INPUT MAX_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#if defined HAVE_S390_VX_ASM_SUPPORT ++# define LOOPFCT __to_utf8_loop_c ++# define BODY BODY_TO_C ++# define LOOP_NEED_FLAGS ++# include ++ ++/* Generate loop-function with software implementation. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MAX_NEEDED_INPUT MAX_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define LOOPFCT __to_utf8_loop_vx ++# define BODY BODY_TO_VX ++# define LOOP_NEED_FLAGS ++# include ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__to_utf8_loop_c) ++__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) ++__to_utf8_loop; ++ ++static void * ++__to_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __to_utf8_loop_vx; ++ else ++ return __to_utf8_loop_c; ++} ++ ++strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) ++ ++#else ++# define LOOPFCT TO_LOOP ++# define BODY BODY_TO_C ++# define LOOP_NEED_FLAGS ++# include ++#endif /* !HAVE_S390_VX_ASM_SUPPORT */ + + #include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-12.patch b/SOURCES/glibc-rh1380680-12.patch new file mode 100644 index 00000000..658faf4c --- /dev/null +++ b/SOURCES/glibc-rh1380680-12.patch @@ -0,0 +1,608 @@ +From c806cab89b52a644b5c563b8f1c8ae59abfc2c13 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:22:17 +0100 +Subject: [PATCH 12/17] S390: Optimize utf16-utf32 module. + +Upstream commit 6896776c3c9c32fd22324e6de6737dd69ae73213 + +This patch reworks the s390 specific module to convert between utf16 and utf32. +Now ifunc is used to choose either the c or etf3eh (with convert utf +instruction) variants at runtime. +Furthermore a new vector variant for z13 is introduced which will be build +and chosen if vector support is available at build / runtime. + +In case of converting utf 32 to utf16, the vector variant optimizes input of +2byte utf16 characters. The convert utf instruction is used if an utf16 +surrogate is found. + +For the other direction utf16 to utf32, the cu24 instruction can't be re- +enabled, because it does not report an error, if the input-stream consists of +a single low surrogate utf16 char (e.g. 0xdc00). This applies to the newest z13, +too. Thus there is only the c or the new vector variant, which can handle utf16 +surrogate characters. + +This patch also fixes some whitespace errors. Furthermore, the etf3eh variant is +handling the "UTF-xx//IGNORE" case now. Before they ignored the ignore-case and +always stopped at an error. + +ChangeLog: + + * sysdeps/s390/s390-64/utf16-utf32-z9.c: Use ifunc to select c, + etf3eh or new vector loop-variant. +--- + sysdeps/s390/s390-64/utf16-utf32-z9.c | 471 +++++++++++++++++++++++++++------- + 1 file changed, 379 insertions(+), 92 deletions(-) + +diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c +index e6a033d..33594f1 100644 +--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf16-utf32-z9.c +@@ -30,47 +30,27 @@ + #include + #include + ++#if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++#else ++# define ASM_CLOBBER_VR(NR) ++#endif ++ + /* UTF-32 big endian byte order mark. */ + #define BOM_UTF32 0x0000feffu + + /* UTF-16 big endian byte order mark. */ +-#define BOM_UTF16 0xfeff ++#define BOM_UTF16 0xfeff + + #define DEFINE_INIT 0 + #define DEFINE_FINI 0 + #define MIN_NEEDED_FROM 2 + #define MAX_NEEDED_FROM 4 + #define MIN_NEEDED_TO 4 +-#define FROM_LOOP from_utf16_loop +-#define TO_LOOP to_utf16_loop ++#define FROM_LOOP __from_utf16_loop ++#define TO_LOOP __to_utf16_loop + #define FROM_DIRECTION (dir == from_utf16) + #define ONE_DIRECTION 0 +-#define PREPARE_LOOP \ +- enum direction dir = ((struct utf16_data *) step->__data)->dir; \ +- int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ +- \ +- if (emit_bom && !data->__internal_use \ +- && data->__invocation_counter == 0) \ +- { \ +- if (dir == to_utf16) \ +- { \ +- /* Emit the UTF-16 Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 2 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put16u (outbuf, BOM_UTF16); \ +- outbuf += 2; \ +- } \ +- else \ +- { \ +- /* Emit the UTF-32 Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 4 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put32u (outbuf, BOM_UTF32); \ +- outbuf += 4; \ +- } \ +- } + + /* Direction of the transformation. */ + enum direction +@@ -169,16 +149,16 @@ gconv_end (struct __gconv_step *data) + register unsigned long long outlen __asm__("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- __asm__ volatile (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ ++ __asm__ __volatile__ (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ +@@ -187,44 +167,46 @@ gconv_end (struct __gconv_step *data) + if (cc == 1) \ + { \ + result = __GCONV_FULL_OUTPUT; \ +- break; \ + } \ + else if (cc == 2) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ +- break; \ + } \ + } + ++#define PREPARE_LOOP \ ++ enum direction dir = ((struct utf16_data *) step->__data)->dir; \ ++ int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ ++ \ ++ if (emit_bom && !data->__internal_use \ ++ && data->__invocation_counter == 0) \ ++ { \ ++ if (dir == to_utf16) \ ++ { \ ++ /* Emit the UTF-16 Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 2 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put16u (outbuf, BOM_UTF16); \ ++ outbuf += 2; \ ++ } \ ++ else \ ++ { \ ++ /* Emit the UTF-32 Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 4 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put32u (outbuf, BOM_UTF32); \ ++ outbuf += 4; \ ++ } \ ++ } ++ + /* Conversion function from UTF-16 to UTF-32 internal/BE. */ + +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT FROM_LOOP + /* The software routine is copied from utf-16.c (minus bytes + swapping). */ +-#define BODY \ ++#define BODY_FROM_C \ + { \ +- /* The hardware instruction currently fails to report an error for \ +- isolated low surrogates so we have to disable the instruction \ +- until this gets resolved. */ \ +- if (0) /* (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) */ \ +- { \ +- HARDWARE_CONVERT ("cu24 %0, %1, 1"); \ +- if (inptr != inend) \ +- { \ +- /* Check if the third byte is \ +- a valid start of a UTF-16 surrogate. */ \ +- if (inend - inptr == 3 && (inptr[3] & 0xfc) != 0xdc) \ +- STANDARD_FROM_LOOP_ERR_HANDLER (3); \ +- \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- continue; \ +- } \ +- \ + uint16_t u1 = get16 (inptr); \ + \ + if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \ +@@ -235,15 +217,15 @@ gconv_end (struct __gconv_step *data) + } \ + else \ + { \ +- /* An isolated low-surrogate was found. This has to be \ ++ /* An isolated low-surrogate was found. This has to be \ + considered ill-formed. */ \ +- if (__glibc_unlikely (u1 >= 0xdc00)) \ ++ if (__glibc_unlikely (u1 >= 0xdc00)) \ + { \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } \ + /* It's a surrogate character. At least the first word says \ + it is. */ \ +- if (__glibc_unlikely (inptr + 4 > inend)) \ ++ if (__glibc_unlikely (inptr + 4 > inend)) \ + { \ + /* We don't have enough input for another complete input \ + character. */ \ +@@ -266,48 +248,200 @@ gconv_end (struct __gconv_step *data) + } \ + outptr += 4; \ + } +-#define LOOP_NEED_FLAGS +-#include ++ ++#define BODY_FROM_VX \ ++ { \ ++ size_t inlen = inend - inptr; \ ++ size_t outlen = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for surrogates. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ ++ "0: clgijl %[R_INLEN],16,2f\n\t" \ ++ " clgijl %[R_OUTLEN],32,2f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ /* Check for surrogate chars. */ \ ++ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ /* Enlarge to UTF-32. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ /* Store 32 bytes to buf_out. */ \ ++ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-32\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,2f\n\t" \ ++ " clgijl %[R_OUTLEN],32,2f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ ++ "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* At least on uint16_t is in range of surrogates. \ ++ Store the preceding chars. */ \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 12f\n\t" \ ++ " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ "11: \n\t" /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Calculate remaining uint16_t values in loaded vrs. */ \ ++ "12: lghi %[R_TMP2],16\n\t" \ ++ " sgr %[R_TMP2],%[R_TMP]\n\t" \ ++ " srl %[R_TMP2],1\n\t" \ ++ " llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_OUTLEN],-4\n\t" \ ++ " j 16f\n\t" \ ++ /* Handle remaining bytes. */ \ ++ "2: \n\t" \ ++ /* Zero, one or more bytes available? */ \ ++ " clgfi %[R_INLEN],1\n\t" \ ++ " je 97f\n\t" /* Only one byte available. */ \ ++ " jl 99f\n\t" /* End if no bytes available. */ \ ++ /* Calculate remaining uint16_t values in inptr. */ \ ++ " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ ++ /* Handle remaining uint16_t values. */ \ ++ "13: llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " slgfi %[R_OUTLEN],4\n\t" \ ++ " jl 96f \n\t" \ ++ " clfi %[R_TMP],0xd800\n\t" \ ++ " jhe 15f\n\t" \ ++ "14: st %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-2\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],13b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Handle UTF-16 surrogate pair. */ \ ++ "15: clfi %[R_TMP],0xdfff\n\t" \ ++ " jh 14b\n\t" /* Jump away if ch > 0xdfff. */ \ ++ "16: clfi %[R_TMP],0xdc00\n\t" \ ++ " jhe 98f\n\t" /* Jump away in case of low-surrogate. */ \ ++ " slgfi %[R_INLEN],4\n\t" \ ++ " jl 97f\n\t" /* Big enough input? */ \ ++ " llh %[R_TMP3],2(%[R_IN])\n\t" /* Load low surrogate. */ \ ++ " slfi %[R_TMP],0xd7c0\n\t" \ ++ " sll %[R_TMP],10\n\t" \ ++ " risbgn %[R_TMP],%[R_TMP3],54,63,0\n\t" /* Insert klmnopqrst. */ \ ++ " nilf %[R_TMP3],0xfc00\n\t" \ ++ " clfi %[R_TMP3],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ ++ " jne 98f\n\t" \ ++ " st %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " aghi %[R_TMP2],-2\n\t" \ ++ " jh 13b\n\t" /* Handle remaining uint16_t values. */ \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ "96: \n\t" /* Return full output. */ \ ++ " lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ ++ " j 99f\n\t" \ ++ "97: \n\t" /* Return incomplete input. */ \ ++ " lghi %[R_RES],%[RES_IN_FULL]\n\t" \ ++ " j 99f\n\t" \ ++ "98:\n\t" /* Return Illegal character. */ \ ++ " lghi %[R_RES],%[RES_IN_ILL]\n\t" \ ++ "99:\n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ if (__glibc_likely (inptr == inend) \ ++ || result != __GCONV_ILLEGAL_INPUT) \ ++ break; \ ++ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } ++ ++ ++/* Generate loop-function with software routing. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#if defined HAVE_S390_VX_ASM_SUPPORT ++# define LOOPFCT __from_utf16_loop_c ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_C ++# include ++ ++/* Generate loop-function with hardware vector instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT __from_utf16_loop_vx ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_VX ++# include ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_utf16_loop_c) ++__attribute__ ((ifunc ("__from_utf16_loop_resolver"))) ++__from_utf16_loop; ++ ++static void * ++__from_utf16_loop_resolver (unsigned long int dl_hwcap) ++{ ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __from_utf16_loop_vx; ++ else ++ return __from_utf16_loop_c; ++} ++ ++strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) ++#else ++# define LOOPFCT FROM_LOOP ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_C ++# include ++#endif + + /* Conversion from UTF-32 internal/BE to UTF-16. */ + +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT TO_LOOP + /* The software routine is copied from utf-16.c (minus bytes + swapping). */ +-#define BODY \ ++#define BODY_TO_C \ + { \ +- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ +- { \ +- HARDWARE_CONVERT ("cu42 %0, %1"); \ +- \ +- if (inptr != inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- continue; \ +- } \ +- \ + uint32_t c = get32 (inptr); \ + \ + if (__builtin_expect (c <= 0xd7ff, 1) \ + || (c >=0xdc00 && c <= 0xffff)) \ + { \ +- /* Two UTF-16 chars. */ \ +- put16 (outptr, c); \ ++ /* Two UTF-16 chars. */ \ ++ put16 (outptr, c); \ + } \ + else if (__builtin_expect (c >= 0x10000, 1) \ + && __builtin_expect (c <= 0x10ffff, 1)) \ + { \ + /* Four UTF-16 chars. */ \ +- uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \ ++ uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \ + uint16_t out; \ + \ + /* Generate a surrogate character. */ \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -326,12 +460,165 @@ gconv_end (struct __gconv_step *data) + } \ + else \ + { \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } \ + outptr += 2; \ + inptr += 4; \ + } ++ ++#define BODY_TO_ETF3EH \ ++ { \ ++ HARDWARE_CONVERT ("cu42 %0, %1"); \ ++ \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++#define BODY_TO_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for surrogates. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ /* Loop which handles UTF-16 chars \ ++ ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ ++ "0: clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ ++ /* Shorten to UTF-16. */ \ ++ " vpkf %%v18,%%v16,%%v17\n\t" \ ++ /* Check for surrogate chars. */ \ ++ " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \ ++ " jno 11f\n\t" \ ++ /* Store 16 bytes to buf_out. */ \ ++ " vst %%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-32\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ ++ and check for ch >= 0x10000. (v30, v31) */ \ ++ "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ ++ " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \ ++ /* At least on UTF32 char is in range of surrogates. \ ++ Store the preceding characters. */ \ ++ "11: ahi %[R_TMP2],16\n\t" \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " agr %[R_TMP],%[R_TMP2]\n\t" \ ++ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 20f\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handles UTF16 surrogates with convert instruction. */ \ ++ "20: cu42 %[R_OUT],%[R_IN]\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++/* Generate loop-function with software routing. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf16_loop_c ++#define LOOP_NEED_FLAGS ++#define BODY BODY_TO_C ++#include ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf16_loop_etf3eh + #define LOOP_NEED_FLAGS ++#define BODY BODY_TO_ETF3EH + #include + ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define LOOPFCT __to_utf16_loop_vx ++# define LOOP_NEED_FLAGS ++# define BODY BODY_TO_VX ++# include ++#endif ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__to_utf16_loop_c) ++__attribute__ ((ifunc ("__to_utf16_loop_resolver"))) ++__to_utf16_loop; ++ ++static void * ++__to_utf16_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __to_utf16_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ETF3EH) ++ return __to_utf16_loop_etf3eh; ++ else ++ return __to_utf16_loop_c; ++} ++ ++strong_alias (__to_utf16_loop_c_single, __to_utf16_loop_single) ++ ++ + #include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-13.patch b/SOURCES/glibc-rh1380680-13.patch new file mode 100644 index 00000000..6910bea8 --- /dev/null +++ b/SOURCES/glibc-rh1380680-13.patch @@ -0,0 +1,5226 @@ +From 3d1533c907648137e92cbbd9ae1427995aff4584 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:28:26 +0100 +Subject: [PATCH 13/17] S390: Use s390-64 specific ionv-modules on s390-32, + too. + +Upstream commit ee518b7070b1bcb41382b6db10f513e071b2c20e + +This patch reworks the existing s390 64bit specific iconv modules in order +to use them on s390 31bit, too. + +Thus the parts for subdirectory iconvdata in sysdeps/s390/s390-64/Makefile +were moved to sysdeps/s390/Makefile so that they apply on 31bit, too. +All those modules are moved from sysdeps/s390/s390-64 directory to sysdeps/s390. + +The iso-8859-1 to/from cp037 module was adjusted, to use brct (branch relative +on count) instruction on 31bit s390 instead of brctg, because the brctg is a +zarch instruction and is not available on a 31bit kernel. + +The utf modules are using zarch instructions, thus the directive machinemode +zarch_nohighgprs was added to the inline assemblies to omit the high-gprs flag +in the shared libraries. Otherwise they can't be loaded on a 31bit kernel. +The ifunc resolvers were adjusted in order to call the etf3eh or vector variants +only if zarch instructions are available (64bit kernel in 31bit compat-mode). +Furthermore some variable types were changed. E.g. unsigned long long would be +a register pair on s390 31bit, but we want only one single register. +For variables of type size_t the register contents have to be enlarged from a +32bit to a 64bit value on 31bit, because the inline assemblies uses 64bit values +in such cases. + +ChangeLog: + + * sysdeps/s390/s390-64/Makefile (iconvdata-subdirectory): + Move to ... + * sysdeps/s390/Makefile: ... here. + * sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c: Move to ... + * sysdeps/s390/iso-8859-1_cp037_z900.c: ... here. + (BRANCH_ON_COUNT): New define. + (TR_LOOP): Use BRANCH_ON_COUNT instead of brctg. + * sysdeps/s390/s390-64/utf16-utf32-z9.c: Move to ... + * sysdeps/s390/utf16-utf32-z9.c: ... here and adjust to + run on s390-32, too. + * sysdeps/s390/s390-64/utf8-utf16-z9.c: Move to ... + * sysdeps/s390/utf8-utf16-z9.c: ... here and adjust to + run on s390-32, too. + * sysdeps/s390/s390-64/utf8-utf32-z9.c: Move to ... + * sysdeps/s390/utf8-utf32-z9.c: ... here and adjust to + run on s390-32, too. +--- + sysdeps/s390/Makefile | 31 + + sysdeps/s390/iso-8859-1_cp037_z900.c | 262 +++++++++ + sysdeps/s390/s390-64/Makefile | 32 -- + sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c | 256 --------- + sysdeps/s390/s390-64/utf16-utf32-z9.c | 624 -------------------- + sysdeps/s390/s390-64/utf8-utf16-z9.c | 806 -------------------------- + sysdeps/s390/s390-64/utf8-utf32-z9.c | 807 -------------------------- + sysdeps/s390/utf16-utf32-z9.c | 636 +++++++++++++++++++++ + sysdeps/s390/utf8-utf16-z9.c | 818 ++++++++++++++++++++++++++ + sysdeps/s390/utf8-utf32-z9.c | 820 +++++++++++++++++++++++++++ + 10 files changed, 2567 insertions(+), 2525 deletions(-) + create mode 100644 sysdeps/s390/Makefile + create mode 100644 sysdeps/s390/iso-8859-1_cp037_z900.c + delete mode 100644 sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c + delete mode 100644 sysdeps/s390/s390-64/utf16-utf32-z9.c + delete mode 100644 sysdeps/s390/s390-64/utf8-utf16-z9.c + delete mode 100644 sysdeps/s390/s390-64/utf8-utf32-z9.c + create mode 100644 sysdeps/s390/utf16-utf32-z9.c + create mode 100644 sysdeps/s390/utf8-utf16-z9.c + create mode 100644 sysdeps/s390/utf8-utf32-z9.c + +diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile +new file mode 100644 +index 0000000..d508365 +--- /dev/null ++++ b/sysdeps/s390/Makefile +@@ -0,0 +1,31 @@ ++ifeq ($(subdir),iconvdata) ++ISO-8859-1_CP037_Z900-routines := iso-8859-1_cp037_z900 ++ISO-8859-1_CP037_Z900-map := gconv.map ++ ++UTF8_UTF32_Z9-routines := utf8-utf32-z9 ++UTF8_UTF32_Z9-map := gconv.map ++ ++UTF16_UTF32_Z9-routines := utf16-utf32-z9 ++UTF16_UTF32_Z9-map := gconv.map ++ ++UTF8_UTF16_Z9-routines := utf8-utf16-z9 ++UTF8_UTF16_Z9-map := gconv.map ++ ++s390x-iconv-modules = ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9 UTF16_UTF32_Z9 UTF8_UTF32_Z9 ++ ++extra-modules-left += $(s390x-iconv-modules) ++include extra-module.mk ++ ++cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) ++lib := iconvdata ++include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) ++ ++extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) ++install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) ++ ++$(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ ++$(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) ++ $(do-install-program) ++ ++sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules ++endif +diff --git a/sysdeps/s390/iso-8859-1_cp037_z900.c b/sysdeps/s390/iso-8859-1_cp037_z900.c +new file mode 100644 +index 0000000..fc25dff +--- /dev/null ++++ b/sysdeps/s390/iso-8859-1_cp037_z900.c +@@ -0,0 +1,262 @@ ++/* Conversion between ISO 8859-1 and IBM037. ++ ++ This module uses the translate instruction. ++ Copyright (C) 1997-2016 Free Software Foundation, Inc. ++ ++ Author: Andreas Krebbel ++ Based on the work by Ulrich Drepper , 1997. ++ ++ Thanks to Daniel Appich who covered the relevant performance work ++ in his diploma thesis. ++ ++ This is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++// conversion table from ISO-8859-1 to IBM037 ++static const unsigned char table_iso8859_1_to_cp037[256] ++__attribute__ ((aligned (8))) = ++{ ++ [0x00] = 0x00, [0x01] = 0x01, [0x02] = 0x02, [0x03] = 0x03, ++ [0x04] = 0x37, [0x05] = 0x2D, [0x06] = 0x2E, [0x07] = 0x2F, ++ [0x08] = 0x16, [0x09] = 0x05, [0x0A] = 0x25, [0x0B] = 0x0B, ++ [0x0C] = 0x0C, [0x0D] = 0x0D, [0x0E] = 0x0E, [0x0F] = 0x0F, ++ [0x10] = 0x10, [0x11] = 0x11, [0x12] = 0x12, [0x13] = 0x13, ++ [0x14] = 0x3C, [0x15] = 0x3D, [0x16] = 0x32, [0x17] = 0x26, ++ [0x18] = 0x18, [0x19] = 0x19, [0x1A] = 0x3F, [0x1B] = 0x27, ++ [0x1C] = 0x1C, [0x1D] = 0x1D, [0x1E] = 0x1E, [0x1F] = 0x1F, ++ [0x20] = 0x40, [0x21] = 0x5A, [0x22] = 0x7F, [0x23] = 0x7B, ++ [0x24] = 0x5B, [0x25] = 0x6C, [0x26] = 0x50, [0x27] = 0x7D, ++ [0x28] = 0x4D, [0x29] = 0x5D, [0x2A] = 0x5C, [0x2B] = 0x4E, ++ [0x2C] = 0x6B, [0x2D] = 0x60, [0x2E] = 0x4B, [0x2F] = 0x61, ++ [0x30] = 0xF0, [0x31] = 0xF1, [0x32] = 0xF2, [0x33] = 0xF3, ++ [0x34] = 0xF4, [0x35] = 0xF5, [0x36] = 0xF6, [0x37] = 0xF7, ++ [0x38] = 0xF8, [0x39] = 0xF9, [0x3A] = 0x7A, [0x3B] = 0x5E, ++ [0x3C] = 0x4C, [0x3D] = 0x7E, [0x3E] = 0x6E, [0x3F] = 0x6F, ++ [0x40] = 0x7C, [0x41] = 0xC1, [0x42] = 0xC2, [0x43] = 0xC3, ++ [0x44] = 0xC4, [0x45] = 0xC5, [0x46] = 0xC6, [0x47] = 0xC7, ++ [0x48] = 0xC8, [0x49] = 0xC9, [0x4A] = 0xD1, [0x4B] = 0xD2, ++ [0x4C] = 0xD3, [0x4D] = 0xD4, [0x4E] = 0xD5, [0x4F] = 0xD6, ++ [0x50] = 0xD7, [0x51] = 0xD8, [0x52] = 0xD9, [0x53] = 0xE2, ++ [0x54] = 0xE3, [0x55] = 0xE4, [0x56] = 0xE5, [0x57] = 0xE6, ++ [0x58] = 0xE7, [0x59] = 0xE8, [0x5A] = 0xE9, [0x5B] = 0xBA, ++ [0x5C] = 0xE0, [0x5D] = 0xBB, [0x5E] = 0xB0, [0x5F] = 0x6D, ++ [0x60] = 0x79, [0x61] = 0x81, [0x62] = 0x82, [0x63] = 0x83, ++ [0x64] = 0x84, [0x65] = 0x85, [0x66] = 0x86, [0x67] = 0x87, ++ [0x68] = 0x88, [0x69] = 0x89, [0x6A] = 0x91, [0x6B] = 0x92, ++ [0x6C] = 0x93, [0x6D] = 0x94, [0x6E] = 0x95, [0x6F] = 0x96, ++ [0x70] = 0x97, [0x71] = 0x98, [0x72] = 0x99, [0x73] = 0xA2, ++ [0x74] = 0xA3, [0x75] = 0xA4, [0x76] = 0xA5, [0x77] = 0xA6, ++ [0x78] = 0xA7, [0x79] = 0xA8, [0x7A] = 0xA9, [0x7B] = 0xC0, ++ [0x7C] = 0x4F, [0x7D] = 0xD0, [0x7E] = 0xA1, [0x7F] = 0x07, ++ [0x80] = 0x20, [0x81] = 0x21, [0x82] = 0x22, [0x83] = 0x23, ++ [0x84] = 0x24, [0x85] = 0x15, [0x86] = 0x06, [0x87] = 0x17, ++ [0x88] = 0x28, [0x89] = 0x29, [0x8A] = 0x2A, [0x8B] = 0x2B, ++ [0x8C] = 0x2C, [0x8D] = 0x09, [0x8E] = 0x0A, [0x8F] = 0x1B, ++ [0x90] = 0x30, [0x91] = 0x31, [0x92] = 0x1A, [0x93] = 0x33, ++ [0x94] = 0x34, [0x95] = 0x35, [0x96] = 0x36, [0x97] = 0x08, ++ [0x98] = 0x38, [0x99] = 0x39, [0x9A] = 0x3A, [0x9B] = 0x3B, ++ [0x9C] = 0x04, [0x9D] = 0x14, [0x9E] = 0x3E, [0x9F] = 0xFF, ++ [0xA0] = 0x41, [0xA1] = 0xAA, [0xA2] = 0x4A, [0xA3] = 0xB1, ++ [0xA4] = 0x9F, [0xA5] = 0xB2, [0xA6] = 0x6A, [0xA7] = 0xB5, ++ [0xA8] = 0xBD, [0xA9] = 0xB4, [0xAA] = 0x9A, [0xAB] = 0x8A, ++ [0xAC] = 0x5F, [0xAD] = 0xCA, [0xAE] = 0xAF, [0xAF] = 0xBC, ++ [0xB0] = 0x90, [0xB1] = 0x8F, [0xB2] = 0xEA, [0xB3] = 0xFA, ++ [0xB4] = 0xBE, [0xB5] = 0xA0, [0xB6] = 0xB6, [0xB7] = 0xB3, ++ [0xB8] = 0x9D, [0xB9] = 0xDA, [0xBA] = 0x9B, [0xBB] = 0x8B, ++ [0xBC] = 0xB7, [0xBD] = 0xB8, [0xBE] = 0xB9, [0xBF] = 0xAB, ++ [0xC0] = 0x64, [0xC1] = 0x65, [0xC2] = 0x62, [0xC3] = 0x66, ++ [0xC4] = 0x63, [0xC5] = 0x67, [0xC6] = 0x9E, [0xC7] = 0x68, ++ [0xC8] = 0x74, [0xC9] = 0x71, [0xCA] = 0x72, [0xCB] = 0x73, ++ [0xCC] = 0x78, [0xCD] = 0x75, [0xCE] = 0x76, [0xCF] = 0x77, ++ [0xD0] = 0xAC, [0xD1] = 0x69, [0xD2] = 0xED, [0xD3] = 0xEE, ++ [0xD4] = 0xEB, [0xD5] = 0xEF, [0xD6] = 0xEC, [0xD7] = 0xBF, ++ [0xD8] = 0x80, [0xD9] = 0xFD, [0xDA] = 0xFE, [0xDB] = 0xFB, ++ [0xDC] = 0xFC, [0xDD] = 0xAD, [0xDE] = 0xAE, [0xDF] = 0x59, ++ [0xE0] = 0x44, [0xE1] = 0x45, [0xE2] = 0x42, [0xE3] = 0x46, ++ [0xE4] = 0x43, [0xE5] = 0x47, [0xE6] = 0x9C, [0xE7] = 0x48, ++ [0xE8] = 0x54, [0xE9] = 0x51, [0xEA] = 0x52, [0xEB] = 0x53, ++ [0xEC] = 0x58, [0xED] = 0x55, [0xEE] = 0x56, [0xEF] = 0x57, ++ [0xF0] = 0x8C, [0xF1] = 0x49, [0xF2] = 0xCD, [0xF3] = 0xCE, ++ [0xF4] = 0xCB, [0xF5] = 0xCF, [0xF6] = 0xCC, [0xF7] = 0xE1, ++ [0xF8] = 0x70, [0xF9] = 0xDD, [0xFA] = 0xDE, [0xFB] = 0xDB, ++ [0xFC] = 0xDC, [0xFD] = 0x8D, [0xFE] = 0x8E, [0xFF] = 0xDF ++}; ++ ++// conversion table from IBM037 to ISO-8859-1 ++static const unsigned char table_cp037_iso8859_1[256] ++__attribute__ ((aligned (8))) = ++{ ++ [0x00] = 0x00, [0x01] = 0x01, [0x02] = 0x02, [0x03] = 0x03, ++ [0x04] = 0x9C, [0x05] = 0x09, [0x06] = 0x86, [0x07] = 0x7F, ++ [0x08] = 0x97, [0x09] = 0x8D, [0x0A] = 0x8E, [0x0B] = 0x0B, ++ [0x0C] = 0x0C, [0x0D] = 0x0D, [0x0E] = 0x0E, [0x0F] = 0x0F, ++ [0x10] = 0x10, [0x11] = 0x11, [0x12] = 0x12, [0x13] = 0x13, ++ [0x14] = 0x9D, [0x15] = 0x85, [0x16] = 0x08, [0x17] = 0x87, ++ [0x18] = 0x18, [0x19] = 0x19, [0x1A] = 0x92, [0x1B] = 0x8F, ++ [0x1C] = 0x1C, [0x1D] = 0x1D, [0x1E] = 0x1E, [0x1F] = 0x1F, ++ [0x20] = 0x80, [0x21] = 0x81, [0x22] = 0x82, [0x23] = 0x83, ++ [0x24] = 0x84, [0x25] = 0x0A, [0x26] = 0x17, [0x27] = 0x1B, ++ [0x28] = 0x88, [0x29] = 0x89, [0x2A] = 0x8A, [0x2B] = 0x8B, ++ [0x2C] = 0x8C, [0x2D] = 0x05, [0x2E] = 0x06, [0x2F] = 0x07, ++ [0x30] = 0x90, [0x31] = 0x91, [0x32] = 0x16, [0x33] = 0x93, ++ [0x34] = 0x94, [0x35] = 0x95, [0x36] = 0x96, [0x37] = 0x04, ++ [0x38] = 0x98, [0x39] = 0x99, [0x3A] = 0x9A, [0x3B] = 0x9B, ++ [0x3C] = 0x14, [0x3D] = 0x15, [0x3E] = 0x9E, [0x3F] = 0x1A, ++ [0x40] = 0x20, [0x41] = 0xA0, [0x42] = 0xE2, [0x43] = 0xE4, ++ [0x44] = 0xE0, [0x45] = 0xE1, [0x46] = 0xE3, [0x47] = 0xE5, ++ [0x48] = 0xE7, [0x49] = 0xF1, [0x4A] = 0xA2, [0x4B] = 0x2E, ++ [0x4C] = 0x3C, [0x4D] = 0x28, [0x4E] = 0x2B, [0x4F] = 0x7C, ++ [0x50] = 0x26, [0x51] = 0xE9, [0x52] = 0xEA, [0x53] = 0xEB, ++ [0x54] = 0xE8, [0x55] = 0xED, [0x56] = 0xEE, [0x57] = 0xEF, ++ [0x58] = 0xEC, [0x59] = 0xDF, [0x5A] = 0x21, [0x5B] = 0x24, ++ [0x5C] = 0x2A, [0x5D] = 0x29, [0x5E] = 0x3B, [0x5F] = 0xAC, ++ [0x60] = 0x2D, [0x61] = 0x2F, [0x62] = 0xC2, [0x63] = 0xC4, ++ [0x64] = 0xC0, [0x65] = 0xC1, [0x66] = 0xC3, [0x67] = 0xC5, ++ [0x68] = 0xC7, [0x69] = 0xD1, [0x6A] = 0xA6, [0x6B] = 0x2C, ++ [0x6C] = 0x25, [0x6D] = 0x5F, [0x6E] = 0x3E, [0x6F] = 0x3F, ++ [0x70] = 0xF8, [0x71] = 0xC9, [0x72] = 0xCA, [0x73] = 0xCB, ++ [0x74] = 0xC8, [0x75] = 0xCD, [0x76] = 0xCE, [0x77] = 0xCF, ++ [0x78] = 0xCC, [0x79] = 0x60, [0x7A] = 0x3A, [0x7B] = 0x23, ++ [0x7C] = 0x40, [0x7D] = 0x27, [0x7E] = 0x3D, [0x7F] = 0x22, ++ [0x80] = 0xD8, [0x81] = 0x61, [0x82] = 0x62, [0x83] = 0x63, ++ [0x84] = 0x64, [0x85] = 0x65, [0x86] = 0x66, [0x87] = 0x67, ++ [0x88] = 0x68, [0x89] = 0x69, [0x8A] = 0xAB, [0x8B] = 0xBB, ++ [0x8C] = 0xF0, [0x8D] = 0xFD, [0x8E] = 0xFE, [0x8F] = 0xB1, ++ [0x90] = 0xB0, [0x91] = 0x6A, [0x92] = 0x6B, [0x93] = 0x6C, ++ [0x94] = 0x6D, [0x95] = 0x6E, [0x96] = 0x6F, [0x97] = 0x70, ++ [0x98] = 0x71, [0x99] = 0x72, [0x9A] = 0xAA, [0x9B] = 0xBA, ++ [0x9C] = 0xE6, [0x9D] = 0xB8, [0x9E] = 0xC6, [0x9F] = 0xA4, ++ [0xA0] = 0xB5, [0xA1] = 0x7E, [0xA2] = 0x73, [0xA3] = 0x74, ++ [0xA4] = 0x75, [0xA5] = 0x76, [0xA6] = 0x77, [0xA7] = 0x78, ++ [0xA8] = 0x79, [0xA9] = 0x7A, [0xAA] = 0xA1, [0xAB] = 0xBF, ++ [0xAC] = 0xD0, [0xAD] = 0xDD, [0xAE] = 0xDE, [0xAF] = 0xAE, ++ [0xB0] = 0x5E, [0xB1] = 0xA3, [0xB2] = 0xA5, [0xB3] = 0xB7, ++ [0xB4] = 0xA9, [0xB5] = 0xA7, [0xB6] = 0xB6, [0xB7] = 0xBC, ++ [0xB8] = 0xBD, [0xB9] = 0xBE, [0xBA] = 0x5B, [0xBB] = 0x5D, ++ [0xBC] = 0xAF, [0xBD] = 0xA8, [0xBE] = 0xB4, [0xBF] = 0xD7, ++ [0xC0] = 0x7B, [0xC1] = 0x41, [0xC2] = 0x42, [0xC3] = 0x43, ++ [0xC4] = 0x44, [0xC5] = 0x45, [0xC6] = 0x46, [0xC7] = 0x47, ++ [0xC8] = 0x48, [0xC9] = 0x49, [0xCA] = 0xAD, [0xCB] = 0xF4, ++ [0xCC] = 0xF6, [0xCD] = 0xF2, [0xCE] = 0xF3, [0xCF] = 0xF5, ++ [0xD0] = 0x7D, [0xD1] = 0x4A, [0xD2] = 0x4B, [0xD3] = 0x4C, ++ [0xD4] = 0x4D, [0xD5] = 0x4E, [0xD6] = 0x4F, [0xD7] = 0x50, ++ [0xD8] = 0x51, [0xD9] = 0x52, [0xDA] = 0xB9, [0xDB] = 0xFB, ++ [0xDC] = 0xFC, [0xDD] = 0xF9, [0xDE] = 0xFA, [0xDF] = 0xFF, ++ [0xE0] = 0x5C, [0xE1] = 0xF7, [0xE2] = 0x53, [0xE3] = 0x54, ++ [0xE4] = 0x55, [0xE5] = 0x56, [0xE6] = 0x57, [0xE7] = 0x58, ++ [0xE8] = 0x59, [0xE9] = 0x5A, [0xEA] = 0xB2, [0xEB] = 0xD4, ++ [0xEC] = 0xD6, [0xED] = 0xD2, [0xEE] = 0xD3, [0xEF] = 0xD5, ++ [0xF0] = 0x30, [0xF1] = 0x31, [0xF2] = 0x32, [0xF3] = 0x33, ++ [0xF4] = 0x34, [0xF5] = 0x35, [0xF6] = 0x36, [0xF7] = 0x37, ++ [0xF8] = 0x38, [0xF9] = 0x39, [0xFA] = 0xB3, [0xFB] = 0xDB, ++ [0xFC] = 0xDC, [0xFD] = 0xD9, [0xFE] = 0xDA, [0xFF] = 0x9F ++}; ++ ++/* Definitions used in the body of the `gconv' function. */ ++#define CHARSET_NAME "ISO-8859-1//" ++#define FROM_LOOP iso8859_1_to_cp037_z900 ++#define TO_LOOP cp037_to_iso8859_1_z900 ++#define DEFINE_INIT 1 ++#define DEFINE_FINI 1 ++#define MIN_NEEDED_FROM 1 ++#define MIN_NEEDED_TO 1 ++ ++# if defined __s390x__ ++# define BRANCH_ON_COUNT(REG,LBL) "brctg %" #REG "," #LBL "\n\t" ++# else ++# define BRANCH_ON_COUNT(REG,LBL) "brct %" #REG "," #LBL "\n\t" ++# endif ++ ++#define TR_LOOP(TABLE) \ ++ { \ ++ size_t length = (inend - inptr < outend - outptr \ ++ ? inend - inptr : outend - outptr); \ ++ \ ++ /* Process in 256 byte blocks. */ \ ++ if (__builtin_expect (length >= 256, 0)) \ ++ { \ ++ size_t blocks = length / 256; \ ++ __asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \ ++ " tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \ ++ " la %[R_IN],256(%[R_IN])\n\t" \ ++ " la %[R_OUT],256(%[R_OUT])\n\t" \ ++ BRANCH_ON_COUNT ([R_LI], 0b) \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \ ++ : /* inputs */ [R_TBL] "a" (TABLE) \ ++ : /* clobber list */ "memory" \ ++ ); \ ++ length = length % 256; \ ++ } \ ++ \ ++ /* Process remaining 0...248 bytes in 8byte blocks. */ \ ++ if (length >= 8) \ ++ { \ ++ size_t blocks = length / 8; \ ++ for (int i = 0; i < blocks; i++) \ ++ { \ ++ outptr[0] = TABLE[inptr[0]]; \ ++ outptr[1] = TABLE[inptr[1]]; \ ++ outptr[2] = TABLE[inptr[2]]; \ ++ outptr[3] = TABLE[inptr[3]]; \ ++ outptr[4] = TABLE[inptr[4]]; \ ++ outptr[5] = TABLE[inptr[5]]; \ ++ outptr[6] = TABLE[inptr[6]]; \ ++ outptr[7] = TABLE[inptr[7]]; \ ++ inptr += 8; \ ++ outptr += 8; \ ++ } \ ++ length = length % 8; \ ++ } \ ++ \ ++ /* Process remaining 0...7 bytes. */ \ ++ switch (length) \ ++ { \ ++ case 7: outptr[6] = TABLE[inptr[6]]; \ ++ case 6: outptr[5] = TABLE[inptr[5]]; \ ++ case 5: outptr[4] = TABLE[inptr[4]]; \ ++ case 4: outptr[3] = TABLE[inptr[3]]; \ ++ case 3: outptr[2] = TABLE[inptr[2]]; \ ++ case 2: outptr[1] = TABLE[inptr[1]]; \ ++ case 1: outptr[0] = TABLE[inptr[0]]; \ ++ case 0: break; \ ++ } \ ++ inptr += length; \ ++ outptr += length; \ ++ } ++ ++ ++/* First define the conversion function from ISO 8859-1 to CP037. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT FROM_LOOP ++#define BODY TR_LOOP (table_iso8859_1_to_cp037) ++ ++#include ++ ++ ++/* Next, define the conversion function from CP037 to ISO 8859-1. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define LOOPFCT TO_LOOP ++#define BODY TR_LOOP (table_cp037_iso8859_1); ++ ++#include ++ ++ ++/* Now define the toplevel functions. */ ++#include +diff --git a/sysdeps/s390/s390-64/Makefile b/sysdeps/s390/s390-64/Makefile +index bb958bd..0a50514 100644 +--- a/sysdeps/s390/s390-64/Makefile ++++ b/sysdeps/s390/s390-64/Makefile +@@ -9,35 +9,3 @@ CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused + CFLAGS-dl-load.c += -Wno-unused + CFLAGS-dl-reloc.c += -Wno-unused + endif +- +-ifeq ($(subdir),iconvdata) +-ISO-8859-1_CP037_Z900-routines := iso-8859-1_cp037_z900 +-ISO-8859-1_CP037_Z900-map := gconv.map +- +-UTF8_UTF32_Z9-routines := utf8-utf32-z9 +-UTF8_UTF32_Z9-map := gconv.map +- +-UTF16_UTF32_Z9-routines := utf16-utf32-z9 +-UTF16_UTF32_Z9-map := gconv.map +- +-UTF8_UTF16_Z9-routines := utf8-utf16-z9 +-UTF8_UTF16_Z9-map := gconv.map +- +-s390x-iconv-modules = ISO-8859-1_CP037_Z900 UTF8_UTF16_Z9 UTF16_UTF32_Z9 UTF8_UTF32_Z9 +- +-extra-modules-left += $(s390x-iconv-modules) +-include extra-module.mk +- +-cpp-srcs-left := $(foreach mod,$(s390x-iconv-modules),$($(mod)-routines)) +-lib := iconvdata +-include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left)) +- +-extra-objs += $(addsuffix .so, $(s390x-iconv-modules)) +-install-others += $(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) +- +-$(patsubst %, $(inst_gconvdir)/%.so, $(s390x-iconv-modules)) : \ +-$(inst_gconvdir)/%.so: $(objpfx)%.so $(+force) +- $(do-install-program) +- +-sysdeps-gconv-modules = ../sysdeps/s390/gconv-modules +-endif +diff --git a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c b/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c +deleted file mode 100644 +index 3b63e6a..0000000 +--- a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c ++++ /dev/null +@@ -1,256 +0,0 @@ +-/* Conversion between ISO 8859-1 and IBM037. +- +- This module uses the translate instruction. +- Copyright (C) 1997-2016 Free Software Foundation, Inc. +- +- Author: Andreas Krebbel +- Based on the work by Ulrich Drepper , 1997. +- +- Thanks to Daniel Appich who covered the relevant performance work +- in his diploma thesis. +- +- This is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +-// conversion table from ISO-8859-1 to IBM037 +-static const unsigned char table_iso8859_1_to_cp037[256] +-__attribute__ ((aligned (8))) = +-{ +- [0x00] = 0x00, [0x01] = 0x01, [0x02] = 0x02, [0x03] = 0x03, +- [0x04] = 0x37, [0x05] = 0x2D, [0x06] = 0x2E, [0x07] = 0x2F, +- [0x08] = 0x16, [0x09] = 0x05, [0x0A] = 0x25, [0x0B] = 0x0B, +- [0x0C] = 0x0C, [0x0D] = 0x0D, [0x0E] = 0x0E, [0x0F] = 0x0F, +- [0x10] = 0x10, [0x11] = 0x11, [0x12] = 0x12, [0x13] = 0x13, +- [0x14] = 0x3C, [0x15] = 0x3D, [0x16] = 0x32, [0x17] = 0x26, +- [0x18] = 0x18, [0x19] = 0x19, [0x1A] = 0x3F, [0x1B] = 0x27, +- [0x1C] = 0x1C, [0x1D] = 0x1D, [0x1E] = 0x1E, [0x1F] = 0x1F, +- [0x20] = 0x40, [0x21] = 0x5A, [0x22] = 0x7F, [0x23] = 0x7B, +- [0x24] = 0x5B, [0x25] = 0x6C, [0x26] = 0x50, [0x27] = 0x7D, +- [0x28] = 0x4D, [0x29] = 0x5D, [0x2A] = 0x5C, [0x2B] = 0x4E, +- [0x2C] = 0x6B, [0x2D] = 0x60, [0x2E] = 0x4B, [0x2F] = 0x61, +- [0x30] = 0xF0, [0x31] = 0xF1, [0x32] = 0xF2, [0x33] = 0xF3, +- [0x34] = 0xF4, [0x35] = 0xF5, [0x36] = 0xF6, [0x37] = 0xF7, +- [0x38] = 0xF8, [0x39] = 0xF9, [0x3A] = 0x7A, [0x3B] = 0x5E, +- [0x3C] = 0x4C, [0x3D] = 0x7E, [0x3E] = 0x6E, [0x3F] = 0x6F, +- [0x40] = 0x7C, [0x41] = 0xC1, [0x42] = 0xC2, [0x43] = 0xC3, +- [0x44] = 0xC4, [0x45] = 0xC5, [0x46] = 0xC6, [0x47] = 0xC7, +- [0x48] = 0xC8, [0x49] = 0xC9, [0x4A] = 0xD1, [0x4B] = 0xD2, +- [0x4C] = 0xD3, [0x4D] = 0xD4, [0x4E] = 0xD5, [0x4F] = 0xD6, +- [0x50] = 0xD7, [0x51] = 0xD8, [0x52] = 0xD9, [0x53] = 0xE2, +- [0x54] = 0xE3, [0x55] = 0xE4, [0x56] = 0xE5, [0x57] = 0xE6, +- [0x58] = 0xE7, [0x59] = 0xE8, [0x5A] = 0xE9, [0x5B] = 0xBA, +- [0x5C] = 0xE0, [0x5D] = 0xBB, [0x5E] = 0xB0, [0x5F] = 0x6D, +- [0x60] = 0x79, [0x61] = 0x81, [0x62] = 0x82, [0x63] = 0x83, +- [0x64] = 0x84, [0x65] = 0x85, [0x66] = 0x86, [0x67] = 0x87, +- [0x68] = 0x88, [0x69] = 0x89, [0x6A] = 0x91, [0x6B] = 0x92, +- [0x6C] = 0x93, [0x6D] = 0x94, [0x6E] = 0x95, [0x6F] = 0x96, +- [0x70] = 0x97, [0x71] = 0x98, [0x72] = 0x99, [0x73] = 0xA2, +- [0x74] = 0xA3, [0x75] = 0xA4, [0x76] = 0xA5, [0x77] = 0xA6, +- [0x78] = 0xA7, [0x79] = 0xA8, [0x7A] = 0xA9, [0x7B] = 0xC0, +- [0x7C] = 0x4F, [0x7D] = 0xD0, [0x7E] = 0xA1, [0x7F] = 0x07, +- [0x80] = 0x20, [0x81] = 0x21, [0x82] = 0x22, [0x83] = 0x23, +- [0x84] = 0x24, [0x85] = 0x15, [0x86] = 0x06, [0x87] = 0x17, +- [0x88] = 0x28, [0x89] = 0x29, [0x8A] = 0x2A, [0x8B] = 0x2B, +- [0x8C] = 0x2C, [0x8D] = 0x09, [0x8E] = 0x0A, [0x8F] = 0x1B, +- [0x90] = 0x30, [0x91] = 0x31, [0x92] = 0x1A, [0x93] = 0x33, +- [0x94] = 0x34, [0x95] = 0x35, [0x96] = 0x36, [0x97] = 0x08, +- [0x98] = 0x38, [0x99] = 0x39, [0x9A] = 0x3A, [0x9B] = 0x3B, +- [0x9C] = 0x04, [0x9D] = 0x14, [0x9E] = 0x3E, [0x9F] = 0xFF, +- [0xA0] = 0x41, [0xA1] = 0xAA, [0xA2] = 0x4A, [0xA3] = 0xB1, +- [0xA4] = 0x9F, [0xA5] = 0xB2, [0xA6] = 0x6A, [0xA7] = 0xB5, +- [0xA8] = 0xBD, [0xA9] = 0xB4, [0xAA] = 0x9A, [0xAB] = 0x8A, +- [0xAC] = 0x5F, [0xAD] = 0xCA, [0xAE] = 0xAF, [0xAF] = 0xBC, +- [0xB0] = 0x90, [0xB1] = 0x8F, [0xB2] = 0xEA, [0xB3] = 0xFA, +- [0xB4] = 0xBE, [0xB5] = 0xA0, [0xB6] = 0xB6, [0xB7] = 0xB3, +- [0xB8] = 0x9D, [0xB9] = 0xDA, [0xBA] = 0x9B, [0xBB] = 0x8B, +- [0xBC] = 0xB7, [0xBD] = 0xB8, [0xBE] = 0xB9, [0xBF] = 0xAB, +- [0xC0] = 0x64, [0xC1] = 0x65, [0xC2] = 0x62, [0xC3] = 0x66, +- [0xC4] = 0x63, [0xC5] = 0x67, [0xC6] = 0x9E, [0xC7] = 0x68, +- [0xC8] = 0x74, [0xC9] = 0x71, [0xCA] = 0x72, [0xCB] = 0x73, +- [0xCC] = 0x78, [0xCD] = 0x75, [0xCE] = 0x76, [0xCF] = 0x77, +- [0xD0] = 0xAC, [0xD1] = 0x69, [0xD2] = 0xED, [0xD3] = 0xEE, +- [0xD4] = 0xEB, [0xD5] = 0xEF, [0xD6] = 0xEC, [0xD7] = 0xBF, +- [0xD8] = 0x80, [0xD9] = 0xFD, [0xDA] = 0xFE, [0xDB] = 0xFB, +- [0xDC] = 0xFC, [0xDD] = 0xAD, [0xDE] = 0xAE, [0xDF] = 0x59, +- [0xE0] = 0x44, [0xE1] = 0x45, [0xE2] = 0x42, [0xE3] = 0x46, +- [0xE4] = 0x43, [0xE5] = 0x47, [0xE6] = 0x9C, [0xE7] = 0x48, +- [0xE8] = 0x54, [0xE9] = 0x51, [0xEA] = 0x52, [0xEB] = 0x53, +- [0xEC] = 0x58, [0xED] = 0x55, [0xEE] = 0x56, [0xEF] = 0x57, +- [0xF0] = 0x8C, [0xF1] = 0x49, [0xF2] = 0xCD, [0xF3] = 0xCE, +- [0xF4] = 0xCB, [0xF5] = 0xCF, [0xF6] = 0xCC, [0xF7] = 0xE1, +- [0xF8] = 0x70, [0xF9] = 0xDD, [0xFA] = 0xDE, [0xFB] = 0xDB, +- [0xFC] = 0xDC, [0xFD] = 0x8D, [0xFE] = 0x8E, [0xFF] = 0xDF +-}; +- +-// conversion table from IBM037 to ISO-8859-1 +-static const unsigned char table_cp037_iso8859_1[256] +-__attribute__ ((aligned (8))) = +-{ +- [0x00] = 0x00, [0x01] = 0x01, [0x02] = 0x02, [0x03] = 0x03, +- [0x04] = 0x9C, [0x05] = 0x09, [0x06] = 0x86, [0x07] = 0x7F, +- [0x08] = 0x97, [0x09] = 0x8D, [0x0A] = 0x8E, [0x0B] = 0x0B, +- [0x0C] = 0x0C, [0x0D] = 0x0D, [0x0E] = 0x0E, [0x0F] = 0x0F, +- [0x10] = 0x10, [0x11] = 0x11, [0x12] = 0x12, [0x13] = 0x13, +- [0x14] = 0x9D, [0x15] = 0x85, [0x16] = 0x08, [0x17] = 0x87, +- [0x18] = 0x18, [0x19] = 0x19, [0x1A] = 0x92, [0x1B] = 0x8F, +- [0x1C] = 0x1C, [0x1D] = 0x1D, [0x1E] = 0x1E, [0x1F] = 0x1F, +- [0x20] = 0x80, [0x21] = 0x81, [0x22] = 0x82, [0x23] = 0x83, +- [0x24] = 0x84, [0x25] = 0x0A, [0x26] = 0x17, [0x27] = 0x1B, +- [0x28] = 0x88, [0x29] = 0x89, [0x2A] = 0x8A, [0x2B] = 0x8B, +- [0x2C] = 0x8C, [0x2D] = 0x05, [0x2E] = 0x06, [0x2F] = 0x07, +- [0x30] = 0x90, [0x31] = 0x91, [0x32] = 0x16, [0x33] = 0x93, +- [0x34] = 0x94, [0x35] = 0x95, [0x36] = 0x96, [0x37] = 0x04, +- [0x38] = 0x98, [0x39] = 0x99, [0x3A] = 0x9A, [0x3B] = 0x9B, +- [0x3C] = 0x14, [0x3D] = 0x15, [0x3E] = 0x9E, [0x3F] = 0x1A, +- [0x40] = 0x20, [0x41] = 0xA0, [0x42] = 0xE2, [0x43] = 0xE4, +- [0x44] = 0xE0, [0x45] = 0xE1, [0x46] = 0xE3, [0x47] = 0xE5, +- [0x48] = 0xE7, [0x49] = 0xF1, [0x4A] = 0xA2, [0x4B] = 0x2E, +- [0x4C] = 0x3C, [0x4D] = 0x28, [0x4E] = 0x2B, [0x4F] = 0x7C, +- [0x50] = 0x26, [0x51] = 0xE9, [0x52] = 0xEA, [0x53] = 0xEB, +- [0x54] = 0xE8, [0x55] = 0xED, [0x56] = 0xEE, [0x57] = 0xEF, +- [0x58] = 0xEC, [0x59] = 0xDF, [0x5A] = 0x21, [0x5B] = 0x24, +- [0x5C] = 0x2A, [0x5D] = 0x29, [0x5E] = 0x3B, [0x5F] = 0xAC, +- [0x60] = 0x2D, [0x61] = 0x2F, [0x62] = 0xC2, [0x63] = 0xC4, +- [0x64] = 0xC0, [0x65] = 0xC1, [0x66] = 0xC3, [0x67] = 0xC5, +- [0x68] = 0xC7, [0x69] = 0xD1, [0x6A] = 0xA6, [0x6B] = 0x2C, +- [0x6C] = 0x25, [0x6D] = 0x5F, [0x6E] = 0x3E, [0x6F] = 0x3F, +- [0x70] = 0xF8, [0x71] = 0xC9, [0x72] = 0xCA, [0x73] = 0xCB, +- [0x74] = 0xC8, [0x75] = 0xCD, [0x76] = 0xCE, [0x77] = 0xCF, +- [0x78] = 0xCC, [0x79] = 0x60, [0x7A] = 0x3A, [0x7B] = 0x23, +- [0x7C] = 0x40, [0x7D] = 0x27, [0x7E] = 0x3D, [0x7F] = 0x22, +- [0x80] = 0xD8, [0x81] = 0x61, [0x82] = 0x62, [0x83] = 0x63, +- [0x84] = 0x64, [0x85] = 0x65, [0x86] = 0x66, [0x87] = 0x67, +- [0x88] = 0x68, [0x89] = 0x69, [0x8A] = 0xAB, [0x8B] = 0xBB, +- [0x8C] = 0xF0, [0x8D] = 0xFD, [0x8E] = 0xFE, [0x8F] = 0xB1, +- [0x90] = 0xB0, [0x91] = 0x6A, [0x92] = 0x6B, [0x93] = 0x6C, +- [0x94] = 0x6D, [0x95] = 0x6E, [0x96] = 0x6F, [0x97] = 0x70, +- [0x98] = 0x71, [0x99] = 0x72, [0x9A] = 0xAA, [0x9B] = 0xBA, +- [0x9C] = 0xE6, [0x9D] = 0xB8, [0x9E] = 0xC6, [0x9F] = 0xA4, +- [0xA0] = 0xB5, [0xA1] = 0x7E, [0xA2] = 0x73, [0xA3] = 0x74, +- [0xA4] = 0x75, [0xA5] = 0x76, [0xA6] = 0x77, [0xA7] = 0x78, +- [0xA8] = 0x79, [0xA9] = 0x7A, [0xAA] = 0xA1, [0xAB] = 0xBF, +- [0xAC] = 0xD0, [0xAD] = 0xDD, [0xAE] = 0xDE, [0xAF] = 0xAE, +- [0xB0] = 0x5E, [0xB1] = 0xA3, [0xB2] = 0xA5, [0xB3] = 0xB7, +- [0xB4] = 0xA9, [0xB5] = 0xA7, [0xB6] = 0xB6, [0xB7] = 0xBC, +- [0xB8] = 0xBD, [0xB9] = 0xBE, [0xBA] = 0x5B, [0xBB] = 0x5D, +- [0xBC] = 0xAF, [0xBD] = 0xA8, [0xBE] = 0xB4, [0xBF] = 0xD7, +- [0xC0] = 0x7B, [0xC1] = 0x41, [0xC2] = 0x42, [0xC3] = 0x43, +- [0xC4] = 0x44, [0xC5] = 0x45, [0xC6] = 0x46, [0xC7] = 0x47, +- [0xC8] = 0x48, [0xC9] = 0x49, [0xCA] = 0xAD, [0xCB] = 0xF4, +- [0xCC] = 0xF6, [0xCD] = 0xF2, [0xCE] = 0xF3, [0xCF] = 0xF5, +- [0xD0] = 0x7D, [0xD1] = 0x4A, [0xD2] = 0x4B, [0xD3] = 0x4C, +- [0xD4] = 0x4D, [0xD5] = 0x4E, [0xD6] = 0x4F, [0xD7] = 0x50, +- [0xD8] = 0x51, [0xD9] = 0x52, [0xDA] = 0xB9, [0xDB] = 0xFB, +- [0xDC] = 0xFC, [0xDD] = 0xF9, [0xDE] = 0xFA, [0xDF] = 0xFF, +- [0xE0] = 0x5C, [0xE1] = 0xF7, [0xE2] = 0x53, [0xE3] = 0x54, +- [0xE4] = 0x55, [0xE5] = 0x56, [0xE6] = 0x57, [0xE7] = 0x58, +- [0xE8] = 0x59, [0xE9] = 0x5A, [0xEA] = 0xB2, [0xEB] = 0xD4, +- [0xEC] = 0xD6, [0xED] = 0xD2, [0xEE] = 0xD3, [0xEF] = 0xD5, +- [0xF0] = 0x30, [0xF1] = 0x31, [0xF2] = 0x32, [0xF3] = 0x33, +- [0xF4] = 0x34, [0xF5] = 0x35, [0xF6] = 0x36, [0xF7] = 0x37, +- [0xF8] = 0x38, [0xF9] = 0x39, [0xFA] = 0xB3, [0xFB] = 0xDB, +- [0xFC] = 0xDC, [0xFD] = 0xD9, [0xFE] = 0xDA, [0xFF] = 0x9F +-}; +- +-/* Definitions used in the body of the `gconv' function. */ +-#define CHARSET_NAME "ISO-8859-1//" +-#define FROM_LOOP iso8859_1_to_cp037_z900 +-#define TO_LOOP cp037_to_iso8859_1_z900 +-#define DEFINE_INIT 1 +-#define DEFINE_FINI 1 +-#define MIN_NEEDED_FROM 1 +-#define MIN_NEEDED_TO 1 +- +-#define TR_LOOP(TABLE) \ +- { \ +- size_t length = (inend - inptr < outend - outptr \ +- ? inend - inptr : outend - outptr); \ +- \ +- /* Process in 256 byte blocks. */ \ +- if (__builtin_expect (length >= 256, 0)) \ +- { \ +- size_t blocks = length / 256; \ +- __asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \ +- " tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \ +- " la %[R_IN],256(%[R_IN])\n\t" \ +- " la %[R_OUT],256(%[R_OUT])\n\t" \ +- " brctg %[R_LI],0b\n\t" \ +- : /* outputs */ [R_IN] "+a" (inptr) \ +- , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \ +- : /* inputs */ [R_TBL] "a" (TABLE) \ +- : /* clobber list */ "memory" \ +- ); \ +- length = length % 256; \ +- } \ +- \ +- /* Process remaining 0...248 bytes in 8byte blocks. */ \ +- if (length >= 8) \ +- { \ +- size_t blocks = length / 8; \ +- for (int i = 0; i < blocks; i++) \ +- { \ +- outptr[0] = TABLE[inptr[0]]; \ +- outptr[1] = TABLE[inptr[1]]; \ +- outptr[2] = TABLE[inptr[2]]; \ +- outptr[3] = TABLE[inptr[3]]; \ +- outptr[4] = TABLE[inptr[4]]; \ +- outptr[5] = TABLE[inptr[5]]; \ +- outptr[6] = TABLE[inptr[6]]; \ +- outptr[7] = TABLE[inptr[7]]; \ +- inptr += 8; \ +- outptr += 8; \ +- } \ +- length = length % 8; \ +- } \ +- \ +- /* Process remaining 0...7 bytes. */ \ +- switch (length) \ +- { \ +- case 7: outptr[6] = TABLE[inptr[6]]; \ +- case 6: outptr[5] = TABLE[inptr[5]]; \ +- case 5: outptr[4] = TABLE[inptr[4]]; \ +- case 4: outptr[3] = TABLE[inptr[3]]; \ +- case 3: outptr[2] = TABLE[inptr[2]]; \ +- case 2: outptr[1] = TABLE[inptr[1]]; \ +- case 1: outptr[0] = TABLE[inptr[0]]; \ +- case 0: break; \ +- } \ +- inptr += length; \ +- outptr += length; \ +- } +- +- +-/* First define the conversion function from ISO 8859-1 to CP037. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT FROM_LOOP +-#define BODY TR_LOOP (table_iso8859_1_to_cp037) +- +-#include +- +- +-/* Next, define the conversion function from CP037 to ISO 8859-1. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define LOOPFCT TO_LOOP +-#define BODY TR_LOOP (table_cp037_iso8859_1); +- +-#include +- +- +-/* Now define the toplevel functions. */ +-#include +diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c +deleted file mode 100644 +index 33594f1..0000000 +--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c ++++ /dev/null +@@ -1,624 +0,0 @@ +-/* Conversion between UTF-16 and UTF-32 BE/internal. +- +- This module uses the Z9-109 variants of the Convert Unicode +- instructions. +- Copyright (C) 1997-2009 Free Software Foundation, Inc. +- +- Author: Andreas Krebbel +- Based on the work by Ulrich Drepper , 1997. +- +- Thanks to Daniel Appich who covered the relevant performance work +- in his diploma thesis. +- +- This is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +-#if defined HAVE_S390_VX_GCC_SUPPORT +-# define ASM_CLOBBER_VR(NR) , NR +-#else +-# define ASM_CLOBBER_VR(NR) +-#endif +- +-/* UTF-32 big endian byte order mark. */ +-#define BOM_UTF32 0x0000feffu +- +-/* UTF-16 big endian byte order mark. */ +-#define BOM_UTF16 0xfeff +- +-#define DEFINE_INIT 0 +-#define DEFINE_FINI 0 +-#define MIN_NEEDED_FROM 2 +-#define MAX_NEEDED_FROM 4 +-#define MIN_NEEDED_TO 4 +-#define FROM_LOOP __from_utf16_loop +-#define TO_LOOP __to_utf16_loop +-#define FROM_DIRECTION (dir == from_utf16) +-#define ONE_DIRECTION 0 +- +-/* Direction of the transformation. */ +-enum direction +-{ +- illegal_dir, +- to_utf16, +- from_utf16 +-}; +- +-struct utf16_data +-{ +- enum direction dir; +- int emit_bom; +-}; +- +- +-extern int gconv_init (struct __gconv_step *step); +-int +-gconv_init (struct __gconv_step *step) +-{ +- /* Determine which direction. */ +- struct utf16_data *new_data; +- enum direction dir = illegal_dir; +- int emit_bom; +- int result; +- +- emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0 +- || __strcasecmp (step->__to_name, "UTF-16//") == 0); +- +- if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 +- && (__strcasecmp (step->__to_name, "UTF-32//") == 0 +- || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 +- || __strcasecmp (step->__to_name, "INTERNAL") == 0)) +- { +- dir = from_utf16; +- } +- else if ((__strcasecmp (step->__to_name, "UTF-16//") == 0 +- || __strcasecmp (step->__to_name, "UTF-16BE//") == 0) +- && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 +- || __strcasecmp (step->__from_name, "INTERNAL") == 0)) +- { +- dir = to_utf16; +- } +- +- result = __GCONV_NOCONV; +- if (dir != illegal_dir) +- { +- new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data)); +- +- result = __GCONV_NOMEM; +- if (new_data != NULL) +- { +- new_data->dir = dir; +- new_data->emit_bom = emit_bom; +- step->__data = new_data; +- +- if (dir == from_utf16) +- { +- step->__min_needed_from = MIN_NEEDED_FROM; +- step->__max_needed_from = MIN_NEEDED_FROM; +- step->__min_needed_to = MIN_NEEDED_TO; +- step->__max_needed_to = MIN_NEEDED_TO; +- } +- else +- { +- step->__min_needed_from = MIN_NEEDED_TO; +- step->__max_needed_from = MIN_NEEDED_TO; +- step->__min_needed_to = MIN_NEEDED_FROM; +- step->__max_needed_to = MIN_NEEDED_FROM; +- } +- +- step->__stateful = 0; +- +- result = __GCONV_OK; +- } +- } +- +- return result; +-} +- +- +-extern void gconv_end (struct __gconv_step *data); +-void +-gconv_end (struct __gconv_step *data) +-{ +- free (data->__data); +-} +- +-/* The macro for the hardware loop. This is used for both +- directions. */ +-#define HARDWARE_CONVERT(INSTRUCTION) \ +- { \ +- register const unsigned char* pInput __asm__ ("8") = inptr; \ +- register unsigned long long inlen __asm__ ("9") = inend - inptr; \ +- register unsigned char* pOutput __asm__ ("10") = outptr; \ +- register unsigned long long outlen __asm__("11") = outend - outptr; \ +- uint64_t cc = 0; \ +- \ +- __asm__ __volatile__ (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ +- \ +- inptr = pInput; \ +- outptr = pOutput; \ +- cc >>= 28; \ +- \ +- if (cc == 1) \ +- { \ +- result = __GCONV_FULL_OUTPUT; \ +- } \ +- else if (cc == 2) \ +- { \ +- result = __GCONV_ILLEGAL_INPUT; \ +- } \ +- } +- +-#define PREPARE_LOOP \ +- enum direction dir = ((struct utf16_data *) step->__data)->dir; \ +- int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ +- \ +- if (emit_bom && !data->__internal_use \ +- && data->__invocation_counter == 0) \ +- { \ +- if (dir == to_utf16) \ +- { \ +- /* Emit the UTF-16 Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 2 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put16u (outbuf, BOM_UTF16); \ +- outbuf += 2; \ +- } \ +- else \ +- { \ +- /* Emit the UTF-32 Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 4 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put32u (outbuf, BOM_UTF32); \ +- outbuf += 4; \ +- } \ +- } +- +-/* Conversion function from UTF-16 to UTF-32 internal/BE. */ +- +-/* The software routine is copied from utf-16.c (minus bytes +- swapping). */ +-#define BODY_FROM_C \ +- { \ +- uint16_t u1 = get16 (inptr); \ +- \ +- if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \ +- { \ +- /* No surrogate. */ \ +- put32 (outptr, u1); \ +- inptr += 2; \ +- } \ +- else \ +- { \ +- /* An isolated low-surrogate was found. This has to be \ +- considered ill-formed. */ \ +- if (__glibc_unlikely (u1 >= 0xdc00)) \ +- { \ +- STANDARD_FROM_LOOP_ERR_HANDLER (2); \ +- } \ +- /* It's a surrogate character. At least the first word says \ +- it is. */ \ +- if (__glibc_unlikely (inptr + 4 > inend)) \ +- { \ +- /* We don't have enough input for another complete input \ +- character. */ \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- \ +- inptr += 2; \ +- uint16_t u2 = get16 (inptr); \ +- if (__builtin_expect (u2 < 0xdc00, 0) \ +- || __builtin_expect (u2 > 0xdfff, 0)) \ +- { \ +- /* This is no valid second word for a surrogate. */ \ +- inptr -= 2; \ +- STANDARD_FROM_LOOP_ERR_HANDLER (2); \ +- } \ +- \ +- put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \ +- inptr += 2; \ +- } \ +- outptr += 4; \ +- } +- +-#define BODY_FROM_VX \ +- { \ +- size_t inlen = inend - inptr; \ +- size_t outlen = outend - outptr; \ +- unsigned long tmp, tmp2, tmp3; \ +- asm volatile (".machine push\n\t" \ +- ".machine \"z13\"\n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- /* Setup to check for surrogates. */ \ +- " larl %[R_TMP],9f\n\t" \ +- " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ +- /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ +- "0: clgijl %[R_INLEN],16,2f\n\t" \ +- " clgijl %[R_OUTLEN],32,2f\n\t" \ +- "1: vl %%v16,0(%[R_IN])\n\t" \ +- /* Check for surrogate chars. */ \ +- " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ +- " jno 10f\n\t" \ +- /* Enlarge to UTF-32. */ \ +- " vuplhh %%v17,%%v16\n\t" \ +- " la %[R_IN],16(%[R_IN])\n\t" \ +- " vupllh %%v18,%%v16\n\t" \ +- " aghi %[R_INLEN],-16\n\t" \ +- /* Store 32 bytes to buf_out. */ \ +- " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ +- " aghi %[R_OUTLEN],-32\n\t" \ +- " la %[R_OUT],32(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],16,2f\n\t" \ +- " clgijl %[R_OUTLEN],32,2f\n\t" \ +- " j 1b\n\t" \ +- /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ +- "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ +- " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ +- /* At least on uint16_t is in range of surrogates. \ +- Store the preceding chars. */ \ +- "10: vlgvb %[R_TMP],%%v19,7\n\t" \ +- " vuplhh %%v17,%%v16\n\t" \ +- " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ +- " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ +- " jl 12f\n\t" \ +- " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \ +- " vupllh %%v18,%%v16\n\t" \ +- " ahi %[R_TMP2],-16\n\t" \ +- " jl 11f\n\t" \ +- " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \ +- "11: \n\t" /* Update pointers. */ \ +- " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_TMP]\n\t" \ +- " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ +- " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ +- /* Calculate remaining uint16_t values in loaded vrs. */ \ +- "12: lghi %[R_TMP2],16\n\t" \ +- " sgr %[R_TMP2],%[R_TMP]\n\t" \ +- " srl %[R_TMP2],1\n\t" \ +- " llh %[R_TMP],0(%[R_IN])\n\t" \ +- " aghi %[R_OUTLEN],-4\n\t" \ +- " j 16f\n\t" \ +- /* Handle remaining bytes. */ \ +- "2: \n\t" \ +- /* Zero, one or more bytes available? */ \ +- " clgfi %[R_INLEN],1\n\t" \ +- " je 97f\n\t" /* Only one byte available. */ \ +- " jl 99f\n\t" /* End if no bytes available. */ \ +- /* Calculate remaining uint16_t values in inptr. */ \ +- " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ +- /* Handle remaining uint16_t values. */ \ +- "13: llh %[R_TMP],0(%[R_IN])\n\t" \ +- " slgfi %[R_OUTLEN],4\n\t" \ +- " jl 96f \n\t" \ +- " clfi %[R_TMP],0xd800\n\t" \ +- " jhe 15f\n\t" \ +- "14: st %[R_TMP],0(%[R_OUT])\n\t" \ +- " la %[R_IN],2(%[R_IN])\n\t" \ +- " aghi %[R_INLEN],-2\n\t" \ +- " la %[R_OUT],4(%[R_OUT])\n\t" \ +- " brctg %[R_TMP2],13b\n\t" \ +- " j 0b\n\t" /* Switch to vx-loop. */ \ +- /* Handle UTF-16 surrogate pair. */ \ +- "15: clfi %[R_TMP],0xdfff\n\t" \ +- " jh 14b\n\t" /* Jump away if ch > 0xdfff. */ \ +- "16: clfi %[R_TMP],0xdc00\n\t" \ +- " jhe 98f\n\t" /* Jump away in case of low-surrogate. */ \ +- " slgfi %[R_INLEN],4\n\t" \ +- " jl 97f\n\t" /* Big enough input? */ \ +- " llh %[R_TMP3],2(%[R_IN])\n\t" /* Load low surrogate. */ \ +- " slfi %[R_TMP],0xd7c0\n\t" \ +- " sll %[R_TMP],10\n\t" \ +- " risbgn %[R_TMP],%[R_TMP3],54,63,0\n\t" /* Insert klmnopqrst. */ \ +- " nilf %[R_TMP3],0xfc00\n\t" \ +- " clfi %[R_TMP3],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ +- " jne 98f\n\t" \ +- " st %[R_TMP],0(%[R_OUT])\n\t" \ +- " la %[R_IN],4(%[R_IN])\n\t" \ +- " la %[R_OUT],4(%[R_OUT])\n\t" \ +- " aghi %[R_TMP2],-2\n\t" \ +- " jh 13b\n\t" /* Handle remaining uint16_t values. */ \ +- " j 0b\n\t" /* Switch to vx-loop. */ \ +- "96: \n\t" /* Return full output. */ \ +- " lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ +- " j 99f\n\t" \ +- "97: \n\t" /* Return incomplete input. */ \ +- " lghi %[R_RES],%[RES_IN_FULL]\n\t" \ +- " j 99f\n\t" \ +- "98:\n\t" /* Return Illegal character. */ \ +- " lghi %[R_RES],%[RES_IN_ILL]\n\t" \ +- "99:\n\t" \ +- ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (inptr) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ +- , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ +- , [R_RES] "+d" (result) \ +- : /* inputs */ \ +- [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ +- , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ +- , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ +- : /* clobber list */ "memory", "cc" \ +- ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ +- ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +- ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ +- ); \ +- if (__glibc_likely (inptr == inend) \ +- || result != __GCONV_ILLEGAL_INPUT) \ +- break; \ +- \ +- STANDARD_FROM_LOOP_ERR_HANDLER (2); \ +- } +- +- +-/* Generate loop-function with software routing. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#if defined HAVE_S390_VX_ASM_SUPPORT +-# define LOOPFCT __from_utf16_loop_c +-# define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_C +-# include +- +-/* Generate loop-function with hardware vector instructions. */ +-# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-# define LOOPFCT __from_utf16_loop_vx +-# define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_VX +-# include +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__from_utf16_loop_c) +-__attribute__ ((ifunc ("__from_utf16_loop_resolver"))) +-__from_utf16_loop; +- +-static void * +-__from_utf16_loop_resolver (unsigned long int dl_hwcap) +-{ +- if (dl_hwcap & HWCAP_S390_VX) +- return __from_utf16_loop_vx; +- else +- return __from_utf16_loop_c; +-} +- +-strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) +-#else +-# define LOOPFCT FROM_LOOP +-# define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_C +-# include +-#endif +- +-/* Conversion from UTF-32 internal/BE to UTF-16. */ +- +-/* The software routine is copied from utf-16.c (minus bytes +- swapping). */ +-#define BODY_TO_C \ +- { \ +- uint32_t c = get32 (inptr); \ +- \ +- if (__builtin_expect (c <= 0xd7ff, 1) \ +- || (c >=0xdc00 && c <= 0xffff)) \ +- { \ +- /* Two UTF-16 chars. */ \ +- put16 (outptr, c); \ +- } \ +- else if (__builtin_expect (c >= 0x10000, 1) \ +- && __builtin_expect (c <= 0x10ffff, 1)) \ +- { \ +- /* Four UTF-16 chars. */ \ +- uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \ +- uint16_t out; \ +- \ +- /* Generate a surrogate character. */ \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- \ +- out = 0xd800; \ +- out |= (zabcd & 0xff) << 6; \ +- out |= (c >> 10) & 0x3f; \ +- put16 (outptr, out); \ +- outptr += 2; \ +- \ +- out = 0xdc00; \ +- out |= c & 0x3ff; \ +- put16 (outptr, out); \ +- } \ +- else \ +- { \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } \ +- outptr += 2; \ +- inptr += 4; \ +- } +- +-#define BODY_TO_ETF3EH \ +- { \ +- HARDWARE_CONVERT ("cu42 %0, %1"); \ +- \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- \ +- if (inptr + 4 > inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } +- +-#define BODY_TO_VX \ +- { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register size_t inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register size_t outlen asm("11") = outend - outptr; \ +- unsigned long tmp, tmp2, tmp3; \ +- asm volatile (".machine push\n\t" \ +- ".machine \"z13\"\n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- /* Setup to check for surrogates. */ \ +- " larl %[R_TMP],9f\n\t" \ +- " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ +- /* Loop which handles UTF-16 chars \ +- ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ +- "0: clgijl %[R_INLEN],32,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ +- "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ +- " lghi %[R_TMP2],0\n\t" \ +- /* Shorten to UTF-16. */ \ +- " vpkf %%v18,%%v16,%%v17\n\t" \ +- /* Check for surrogate chars. */ \ +- " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \ +- " jno 10f\n\t" \ +- " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \ +- " jno 11f\n\t" \ +- /* Store 16 bytes to buf_out. */ \ +- " vst %%v18,0(%[R_OUT])\n\t" \ +- " la %[R_IN],32(%[R_IN])\n\t" \ +- " aghi %[R_INLEN],-32\n\t" \ +- " aghi %[R_OUTLEN],-16\n\t" \ +- " la %[R_OUT],16(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],32,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ +- " j 1b\n\t" \ +- /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ +- and check for ch >= 0x10000. (v30, v31) */ \ +- "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ +- " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \ +- /* At least on UTF32 char is in range of surrogates. \ +- Store the preceding characters. */ \ +- "11: ahi %[R_TMP2],16\n\t" \ +- "10: vlgvb %[R_TMP],%%v19,7\n\t" \ +- " agr %[R_TMP],%[R_TMP2]\n\t" \ +- " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ +- " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ +- " jl 20f\n\t" \ +- " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ +- /* Update pointers. */ \ +- " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_TMP]\n\t" \ +- " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ +- " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ +- /* Handles UTF16 surrogates with convert instruction. */ \ +- "20: cu42 %[R_OUT],%[R_IN]\n\t" \ +- " jo 0b\n\t" /* Try vector implemenation again. */ \ +- " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ +- " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ +- ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (pInput) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ +- , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ +- , [R_RES] "+d" (result) \ +- : /* inputs */ \ +- [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ +- , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ +- , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ +- : /* clobber list */ "memory", "cc" \ +- ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ +- ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +- ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ +- ); \ +- inptr = pInput; \ +- outptr = pOutput; \ +- \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- if (inptr + 4 > inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } +- +-/* Generate loop-function with software routing. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf16_loop_c +-#define LOOP_NEED_FLAGS +-#define BODY BODY_TO_C +-#include +- +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf16_loop_etf3eh +-#define LOOP_NEED_FLAGS +-#define BODY BODY_TO_ETF3EH +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector instructions. */ +-# define MIN_NEEDED_INPUT MIN_NEEDED_TO +-# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-# define LOOPFCT __to_utf16_loop_vx +-# define LOOP_NEED_FLAGS +-# define BODY BODY_TO_VX +-# include +-#endif +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__to_utf16_loop_c) +-__attribute__ ((ifunc ("__to_utf16_loop_resolver"))) +-__to_utf16_loop; +- +-static void * +-__to_utf16_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __to_utf16_loop_vx; +- else +-#endif +- if (dl_hwcap & HWCAP_S390_ETF3EH) +- return __to_utf16_loop_etf3eh; +- else +- return __to_utf16_loop_c; +-} +- +-strong_alias (__to_utf16_loop_c_single, __to_utf16_loop_single) +- +- +-#include +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +deleted file mode 100644 +index b36ee9e..0000000 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ /dev/null +@@ -1,806 +0,0 @@ +-/* Conversion between UTF-16 and UTF-32 BE/internal. +- +- This module uses the Z9-109 variants of the Convert Unicode +- instructions. +- Copyright (C) 1997-2009 Free Software Foundation, Inc. +- +- Author: Andreas Krebbel +- Based on the work by Ulrich Drepper , 1997. +- +- Thanks to Daniel Appich who covered the relevant performance work +- in his diploma thesis. +- +- This is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +-#if defined HAVE_S390_VX_GCC_SUPPORT +-# define ASM_CLOBBER_VR(NR) , NR +-#else +-# define ASM_CLOBBER_VR(NR) +-#endif +- +-/* Defines for skeleton.c. */ +-#define DEFINE_INIT 0 +-#define DEFINE_FINI 0 +-#define MIN_NEEDED_FROM 1 +-#define MAX_NEEDED_FROM 4 +-#define MIN_NEEDED_TO 2 +-#define MAX_NEEDED_TO 4 +-#define FROM_LOOP __from_utf8_loop +-#define TO_LOOP __to_utf8_loop +-#define FROM_DIRECTION (dir == from_utf8) +-#define ONE_DIRECTION 0 +- +- +-/* UTF-16 big endian byte order mark. */ +-#define BOM_UTF16 0xfeff +- +-/* Direction of the transformation. */ +-enum direction +-{ +- illegal_dir, +- to_utf8, +- from_utf8 +-}; +- +-struct utf8_data +-{ +- enum direction dir; +- int emit_bom; +-}; +- +- +-extern int gconv_init (struct __gconv_step *step); +-int +-gconv_init (struct __gconv_step *step) +-{ +- /* Determine which direction. */ +- struct utf8_data *new_data; +- enum direction dir = illegal_dir; +- int emit_bom; +- int result; +- +- emit_bom = (__strcasecmp (step->__to_name, "UTF-16//") == 0); +- +- if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 +- && (__strcasecmp (step->__to_name, "UTF-16//") == 0 +- || __strcasecmp (step->__to_name, "UTF-16BE//") == 0)) +- { +- dir = from_utf8; +- } +- else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 +- && __strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0) +- { +- dir = to_utf8; +- } +- +- result = __GCONV_NOCONV; +- if (dir != illegal_dir) +- { +- new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); +- +- result = __GCONV_NOMEM; +- if (new_data != NULL) +- { +- new_data->dir = dir; +- new_data->emit_bom = emit_bom; +- step->__data = new_data; +- +- if (dir == from_utf8) +- { +- step->__min_needed_from = MIN_NEEDED_FROM; +- step->__max_needed_from = MIN_NEEDED_FROM; +- step->__min_needed_to = MIN_NEEDED_TO; +- step->__max_needed_to = MIN_NEEDED_TO; +- } +- else +- { +- step->__min_needed_from = MIN_NEEDED_TO; +- step->__max_needed_from = MIN_NEEDED_TO; +- step->__min_needed_to = MIN_NEEDED_FROM; +- step->__max_needed_to = MIN_NEEDED_FROM; +- } +- +- step->__stateful = 0; +- +- result = __GCONV_OK; +- } +- } +- +- return result; +-} +- +- +-extern void gconv_end (struct __gconv_step *data); +-void +-gconv_end (struct __gconv_step *data) +-{ +- free (data->__data); +-} +- +-/* The macro for the hardware loop. This is used for both +- directions. */ +-#define HARDWARE_CONVERT(INSTRUCTION) \ +- { \ +- register const unsigned char* pInput __asm__ ("8") = inptr; \ +- register unsigned long long inlen __asm__ ("9") = inend - inptr; \ +- register unsigned char* pOutput __asm__ ("10") = outptr; \ +- register unsigned long long outlen __asm__("11") = outend - outptr; \ +- uint64_t cc = 0; \ +- \ +- __asm__ __volatile__ (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ +- \ +- inptr = pInput; \ +- outptr = pOutput; \ +- cc >>= 28; \ +- \ +- if (cc == 1) \ +- { \ +- result = __GCONV_FULL_OUTPUT; \ +- } \ +- else if (cc == 2) \ +- { \ +- result = __GCONV_ILLEGAL_INPUT; \ +- } \ +- } +- +-#define PREPARE_LOOP \ +- enum direction dir = ((struct utf8_data *) step->__data)->dir; \ +- int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ +- \ +- if (emit_bom && !data->__internal_use \ +- && data->__invocation_counter == 0) \ +- { \ +- /* Emit the UTF-16 Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 2 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put16u (outbuf, BOM_UTF16); \ +- outbuf += 2; \ +- } +- +-/* Conversion function from UTF-8 to UTF-16. */ +-#define BODY_FROM_HW(ASM) \ +- { \ +- ASM; \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- \ +- int i; \ +- for (i = 1; inptr + i < inend && i < 5; ++i) \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- break; \ +- \ +- if (__glibc_likely (inptr + i == inend \ +- && result == __GCONV_EMPTY_INPUT)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_FROM_LOOP_ERR_HANDLER (i); \ +- } +- +-#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1")) +- +-#define HW_FROM_VX \ +- { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register size_t inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register size_t outlen asm("11") = outend - outptr; \ +- unsigned long tmp, tmp2, tmp3; \ +- asm volatile (".machine push\n\t" \ +- ".machine \"z13\"\n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ +- " vrepib %%v31,0x20\n\t" \ +- /* Loop which handles UTF-8 chars <=0x7f. */ \ +- "0: clgijl %[R_INLEN],16,20f\n\t" \ +- " clgijl %[R_OUTLEN],32,20f\n\t" \ +- "1: vl %%v16,0(%[R_IN])\n\t" \ +- " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ +- " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ +- UTF8 chars. */ \ +- /* Enlarge to UTF-16. */ \ +- " vuplhb %%v18,%%v16\n\t" \ +- " la %[R_IN],16(%[R_IN])\n\t" \ +- " vupllb %%v19,%%v16\n\t" \ +- " aghi %[R_INLEN],-16\n\t" \ +- /* Store 32 bytes to buf_out. */ \ +- " vstm %%v18,%%v19,0(%[R_OUT])\n\t" \ +- " aghi %[R_OUTLEN],-32\n\t" \ +- " la %[R_OUT],32(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],16,20f\n\t" \ +- " clgijl %[R_OUTLEN],32,20f\n\t" \ +- " j 1b\n\t" \ +- "10:\n\t" \ +- /* At least one byte is > 0x7f. \ +- Store the preceding 1-byte chars. */ \ +- " vlgvb %[R_TMP],%%v17,7\n\t" \ +- " sllk %[R_TMP2],%[R_TMP],1\n\t" /* Compute highest \ +- index to store. */ \ +- " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ +- " ahi %[R_TMP2],-1\n\t" \ +- " jl 20f\n\t" \ +- " vuplhb %%v18,%%v16\n\t" \ +- " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ +- " ahi %[R_TMP2],-16\n\t" \ +- " jl 11f\n\t" \ +- " vupllb %%v19,%%v16\n\t" \ +- " vstl %%v19,%[R_TMP2],16(%[R_OUT])\n\t" \ +- "11: \n\t" /* Update pointers. */ \ +- " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_TMP]\n\t" \ +- " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ +- " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ +- /* Handle multibyte utf8-char with convert instruction. */ \ +- "20: cu12 %[R_OUT],%[R_IN],1\n\t" \ +- " jo 0b\n\t" /* Try vector implemenation again. */ \ +- " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ +- " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ +- ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (pInput) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ +- , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ +- , [R_RES] "+d" (result) \ +- : /* inputs */ \ +- [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ +- , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ +- : /* clobber list */ "memory", "cc" \ +- ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ +- ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +- ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ +- ); \ +- inptr = pInput; \ +- outptr = pOutput; \ +- } +-#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) +- +- +-/* The software implementation is based on the code in gconv_simple.c. */ +-#define BODY_FROM_C \ +- { \ +- /* Next input byte. */ \ +- uint16_t ch = *inptr; \ +- \ +- if (__glibc_likely (ch < 0x80)) \ +- { \ +- /* One byte sequence. */ \ +- ++inptr; \ +- } \ +- else \ +- { \ +- uint_fast32_t cnt; \ +- uint_fast32_t i; \ +- \ +- if (ch >= 0xc2 && ch < 0xe0) \ +- { \ +- /* We expect two bytes. The first byte cannot be 0xc0 \ +- or 0xc1, otherwise the wide character could have been \ +- represented using a single byte. */ \ +- cnt = 2; \ +- ch &= 0x1f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ +- { \ +- /* We expect three bytes. */ \ +- cnt = 3; \ +- ch &= 0x0f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ +- { \ +- /* We expect four bytes. */ \ +- cnt = 4; \ +- ch &= 0x07; \ +- } \ +- else \ +- { \ +- /* Search the end of this ill-formed UTF-8 character. This \ +- is the next byte with (x & 0xc0) != 0x80. */ \ +- i = 0; \ +- do \ +- ++i; \ +- while (inptr + i < inend \ +- && (*(inptr + i) & 0xc0) == 0x80 \ +- && i < 5); \ +- \ +- errout: \ +- STANDARD_FROM_LOOP_ERR_HANDLER (i); \ +- } \ +- \ +- if (__glibc_unlikely (inptr + cnt > inend)) \ +- { \ +- /* We don't have enough input. But before we report \ +- that check that all the bytes are correct. */ \ +- for (i = 1; inptr + i < inend; ++i) \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- break; \ +- \ +- if (__glibc_likely (inptr + i == inend)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- \ +- goto errout; \ +- } \ +- \ +- if (cnt == 4) \ +- { \ +- /* For 4 byte UTF-8 chars two UTF-16 chars (high and \ +- low) are needed. */ \ +- uint16_t zabcd, high, low; \ +- \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- \ +- /* Check if tail-bytes >= 0x80, < 0xc0. */ \ +- for (i = 1; i < cnt; ++i) \ +- { \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- /* This is an illegal encoding. */ \ +- goto errout; \ +- } \ +- \ +- /* See Principles of Operations cu12. */ \ +- zabcd = (((inptr[0] & 0x7) << 2) | \ +- ((inptr[1] & 0x30) >> 4)) - 1; \ +- \ +- /* z-bit must be zero after subtracting 1. */ \ +- if (zabcd & 0x10) \ +- STANDARD_FROM_LOOP_ERR_HANDLER (4) \ +- \ +- high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \ +- high |= zabcd << 6; /* abcd bits */ \ +- high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \ +- high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \ +- \ +- low = (uint16_t)(0xdc << 8); /* low surrogate id */ \ +- low |= ((uint16_t)inptr[2] & 0xc) << 6; /* kl bits */ \ +- low |= (inptr[2] & 0x3) << 6; /* mn bits */ \ +- low |= inptr[3] & 0x3f; /* opqrst bits */ \ +- \ +- put16 (outptr, high); \ +- outptr += 2; \ +- put16 (outptr, low); \ +- outptr += 2; \ +- inptr += 4; \ +- continue; \ +- } \ +- else \ +- { \ +- /* Read the possible remaining bytes. */ \ +- for (i = 1; i < cnt; ++i) \ +- { \ +- uint16_t byte = inptr[i]; \ +- \ +- if ((byte & 0xc0) != 0x80) \ +- /* This is an illegal encoding. */ \ +- break; \ +- \ +- ch <<= 6; \ +- ch |= byte & 0x3f; \ +- } \ +- \ +- /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ +- If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ +- have been represented with fewer than cnt bytes. */ \ +- if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ +- /* Do not accept UTF-16 surrogates. */ \ +- || (ch >= 0xd800 && ch <= 0xdfff)) \ +- { \ +- /* This is an illegal encoding. */ \ +- goto errout; \ +- } \ +- \ +- inptr += cnt; \ +- } \ +- } \ +- /* Now adjust the pointers and store the result. */ \ +- *((uint16_t *) outptr) = ch; \ +- outptr += sizeof (uint16_t); \ +- } +- +-/* Generate loop-function with software implementation. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_c +-#define LOOP_NEED_FLAGS +-#define BODY BODY_FROM_C +-#include +- +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_etf3eh +-#define LOOP_NEED_FLAGS +-#define BODY BODY_FROM_ETF3EH +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector and utf-convert instructions. */ +-# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO +-# define LOOPFCT __from_utf8_loop_vx +-# define LOOP_NEED_FLAGS +-# define BODY BODY_FROM_VX +-# include +-#endif +- +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__from_utf8_loop_c) +-__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) +-__from_utf8_loop; +- +-static void * +-__from_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __from_utf8_loop_vx; +- else +-#endif +- if (dl_hwcap & HWCAP_S390_ETF3EH) +- return __from_utf8_loop_etf3eh; +- else +- return __from_utf8_loop_c; +-} +- +-strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) +- +-/* Conversion from UTF-16 to UTF-8. */ +- +-/* The software routine is based on the functionality of the S/390 +- hardware instruction (cu21) as described in the Principles of +- Operation. */ +-#define BODY_TO_C \ +- { \ +- uint16_t c = get16 (inptr); \ +- \ +- if (__glibc_likely (c <= 0x007f)) \ +- { \ +- /* Single byte UTF-8 char. */ \ +- *outptr = c & 0xff; \ +- outptr++; \ +- } \ +- else if (c >= 0x0080 && c <= 0x07ff) \ +- { \ +- /* Two byte UTF-8 char. */ \ +- \ +- if (__glibc_unlikely (outptr + 2 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- \ +- outptr[0] = 0xc0; \ +- outptr[0] |= c >> 6; \ +- \ +- outptr[1] = 0x80; \ +- outptr[1] |= c & 0x3f; \ +- \ +- outptr += 2; \ +- } \ +- else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \ +- { \ +- /* Three byte UTF-8 char. */ \ +- \ +- if (__glibc_unlikely (outptr + 3 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- outptr[0] = 0xe0; \ +- outptr[0] |= c >> 12; \ +- \ +- outptr[1] = 0x80; \ +- outptr[1] |= (c >> 6) & 0x3f; \ +- \ +- outptr[2] = 0x80; \ +- outptr[2] |= c & 0x3f; \ +- \ +- outptr += 3; \ +- } \ +- else if (c >= 0xd800 && c <= 0xdbff) \ +- { \ +- /* Four byte UTF-8 char. */ \ +- uint16_t low, uvwxy; \ +- \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- if (__glibc_unlikely (inptr + 4 > inend)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- \ +- inptr += 2; \ +- low = get16 (inptr); \ +- \ +- if ((low & 0xfc00) != 0xdc00) \ +- { \ +- inptr -= 2; \ +- STANDARD_TO_LOOP_ERR_HANDLER (2); \ +- } \ +- uvwxy = ((c >> 6) & 0xf) + 1; \ +- outptr[0] = 0xf0; \ +- outptr[0] |= uvwxy >> 2; \ +- \ +- outptr[1] = 0x80; \ +- outptr[1] |= (uvwxy << 4) & 0x30; \ +- outptr[1] |= (c >> 2) & 0x0f; \ +- \ +- outptr[2] = 0x80; \ +- outptr[2] |= (c & 0x03) << 4; \ +- outptr[2] |= (low >> 6) & 0x0f; \ +- \ +- outptr[3] = 0x80; \ +- outptr[3] |= low & 0x3f; \ +- \ +- outptr += 4; \ +- } \ +- else \ +- { \ +- STANDARD_TO_LOOP_ERR_HANDLER (2); \ +- } \ +- inptr += 2; \ +- } +- +-#define BODY_TO_VX \ +- { \ +- size_t inlen = inend - inptr; \ +- size_t outlen = outend - outptr; \ +- unsigned long tmp, tmp2, tmp3; \ +- asm volatile (".machine push\n\t" \ +- ".machine \"z13\"\n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- /* Setup to check for values <= 0x7f. */ \ +- " larl %[R_TMP],9f\n\t" \ +- " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ +- /* Loop which handles UTF-16 chars <=0x7f. */ \ +- "0: clgijl %[R_INLEN],32,2f\n\t" \ +- " clgijl %[R_OUTLEN],16,2f\n\t" \ +- "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ +- " lghi %[R_TMP2],0\n\t" \ +- /* Check for > 1byte UTF-8 chars. */ \ +- " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ +- " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ +- UTF8 chars. */ \ +- " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \ +- " jno 11f\n\t" /* Jump away if not all bytes are 1byte \ +- UTF8 chars. */ \ +- /* Shorten to UTF-8. */ \ +- " vpkh %%v18,%%v16,%%v17\n\t" \ +- " la %[R_IN],32(%[R_IN])\n\t" \ +- " aghi %[R_INLEN],-32\n\t" \ +- /* Store 16 bytes to buf_out. */ \ +- " vst %%v18,0(%[R_OUT])\n\t" \ +- " aghi %[R_OUTLEN],-16\n\t" \ +- " la %[R_OUT],16(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],32,2f\n\t" \ +- " clgijl %[R_OUTLEN],16,2f\n\t" \ +- " j 1b\n\t" \ +- /* Setup to check for ch > 0x7f. (v30, v31) */ \ +- "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ +- " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ +- /* At least one byte is > 0x7f. \ +- Store the preceding 1-byte chars. */ \ +- "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \ +- "10:\n\t" \ +- " vlgvb %[R_TMP],%%v19,7\n\t" \ +- /* Shorten to UTF-8. */ \ +- " vpkh %%v18,%%v16,%%v17\n\t" \ +- " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \ +- " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ +- " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ +- " jl 13f\n\t" \ +- " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ +- /* Update pointers. */ \ +- " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_TMP]\n\t" \ +- " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ +- " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ +- "13: \n\t" \ +- /* Calculate remaining uint16_t values in loaded vrs. */ \ +- " lghi %[R_TMP2],16\n\t" \ +- " slgr %[R_TMP2],%[R_TMP3]\n\t" \ +- " llh %[R_TMP],0(%[R_IN])\n\t" \ +- " aghi %[R_INLEN],-2\n\t" \ +- " j 22f\n\t" \ +- /* Handle remaining bytes. */ \ +- "2: \n\t" \ +- /* Zero, one or more bytes available? */ \ +- " clgfi %[R_INLEN],1\n\t" \ +- " locghie %[R_RES],%[RES_IN_FULL]\n\t" /* Only one byte. */ \ +- " jle 99f\n\t" /* End if less than two bytes. */ \ +- /* Calculate remaining uint16_t values in inptr. */ \ +- " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ +- /* Handle multibyte utf8-char. */ \ +- "20: llh %[R_TMP],0(%[R_IN])\n\t" \ +- " aghi %[R_INLEN],-2\n\t" \ +- /* Test if ch is 1-byte UTF-8 char. */ \ +- "21: clijh %[R_TMP],0x7f,22f\n\t" \ +- /* Handle 1-byte UTF-8 char. */ \ +- "31: slgfi %[R_OUTLEN],1\n\t" \ +- " jl 90f \n\t" \ +- " stc %[R_TMP],0(%[R_OUT])\n\t" \ +- " la %[R_IN],2(%[R_IN])\n\t" \ +- " la %[R_OUT],1(%[R_OUT])\n\t" \ +- " brctg %[R_TMP2],20b\n\t" \ +- " j 0b\n\t" /* Switch to vx-loop. */ \ +- /* Test if ch is 2-byte UTF-8 char. */ \ +- "22: clfi %[R_TMP],0x7ff\n\t" \ +- " jh 23f\n\t" \ +- /* Handle 2-byte UTF-8 char. */ \ +- "32: slgfi %[R_OUTLEN],2\n\t" \ +- " jl 90f \n\t" \ +- " llill %[R_TMP3],0xc080\n\t" \ +- " la %[R_IN],2(%[R_IN])\n\t" \ +- " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \ +- " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \ +- " sth %[R_TMP3],0(%[R_OUT])\n\t" \ +- " la %[R_OUT],2(%[R_OUT])\n\t" \ +- " brctg %[R_TMP2],20b\n\t" \ +- " j 0b\n\t" /* Switch to vx-loop. */ \ +- /* Test if ch is 3-byte UTF-8 char. */ \ +- "23: clfi %[R_TMP],0xd7ff\n\t" \ +- " jh 24f\n\t" \ +- /* Handle 3-byte UTF-8 char. */ \ +- "33: slgfi %[R_OUTLEN],3\n\t" \ +- " jl 90f \n\t" \ +- " llilf %[R_TMP3],0xe08080\n\t" \ +- " la %[R_IN],2(%[R_IN])\n\t" \ +- " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \ +- " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \ +- " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \ +- " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \ +- " la %[R_OUT],3(%[R_OUT])\n\t" \ +- " brctg %[R_TMP2],20b\n\t" \ +- " j 0b\n\t" /* Switch to vx-loop. */ \ +- /* Test if ch is 4-byte UTF-8 char. */ \ +- "24: clfi %[R_TMP],0xdfff\n\t" \ +- " jh 33b\n\t" /* Handle this 3-byte UTF-8 char. */ \ +- " clfi %[R_TMP],0xdbff\n\t" \ +- " locghih %[R_RES],%[RES_IN_ILL]\n\t" \ +- " jh 99f\n\t" /* Jump away if this is a low surrogate \ +- without a preceding high surrogate. */ \ +- /* Handle 4-byte UTF-8 char. */ \ +- "34: slgfi %[R_OUTLEN],4\n\t" \ +- " jl 90f \n\t" \ +- " slgfi %[R_INLEN],2\n\t" \ +- " locghil %[R_RES],%[RES_IN_FULL]\n\t" \ +- " jl 99f\n\t" /* Jump away if low surrogate is missing. */ \ +- " llilf %[R_TMP3],0xf0808080\n\t" \ +- " aghi %[R_TMP],0x40\n\t" \ +- " risbgn %[R_TMP3],%[R_TMP],37,39,16\n\t" /* 1. byte: uvw */ \ +- " risbgn %[R_TMP3],%[R_TMP],42,43,14\n\t" /* 2. byte: xy */ \ +- " risbgn %[R_TMP3],%[R_TMP],44,47,14\n\t" /* 2. byte: efgh */ \ +- " risbgn %[R_TMP3],%[R_TMP],50,51,12\n\t" /* 3. byte: ij */ \ +- " llh %[R_TMP],2(%[R_IN])\n\t" /* Load low surrogate. */ \ +- " risbgn %[R_TMP3],%[R_TMP],52,55,2\n\t" /* 3. byte: klmn */ \ +- " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte: opqrst */ \ +- " nilf %[R_TMP],0xfc00\n\t" \ +- " clfi %[R_TMP],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ +- " locghine %[R_RES],%[RES_IN_ILL]\n\t" \ +- " jne 99f\n\t" /* Jump away if low surrogate is invalid. */ \ +- " st %[R_TMP3],0(%[R_OUT])\n\t" \ +- " la %[R_IN],4(%[R_IN])\n\t" \ +- " la %[R_OUT],4(%[R_OUT])\n\t" \ +- " aghi %[R_TMP2],-2\n\t" \ +- " jh 20b\n\t" \ +- " j 0b\n\t" /* Switch to vx-loop. */ \ +- /* Exit with __GCONV_FULL_OUTPUT. */ \ +- "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ +- "99: \n\t" \ +- ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (inptr) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ +- , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ +- , [R_RES] "+d" (result) \ +- : /* inputs */ \ +- [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ +- , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ +- , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ +- : /* clobber list */ "memory", "cc" \ +- ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ +- ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +- ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ +- ); \ +- if (__glibc_likely (inptr == inend) \ +- || result != __GCONV_ILLEGAL_INPUT) \ +- break; \ +- \ +- STANDARD_TO_LOOP_ERR_HANDLER (2); \ +- } +- +-/* Generate loop-function with software implementation. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MAX_NEEDED_INPUT MAX_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#if defined HAVE_S390_VX_ASM_SUPPORT +-# define LOOPFCT __to_utf8_loop_c +-# define BODY BODY_TO_C +-# define LOOP_NEED_FLAGS +-# include +- +-/* Generate loop-function with software implementation. */ +-# define MIN_NEEDED_INPUT MIN_NEEDED_TO +-# define MAX_NEEDED_INPUT MAX_NEEDED_TO +-# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-# define LOOPFCT __to_utf8_loop_vx +-# define BODY BODY_TO_VX +-# define LOOP_NEED_FLAGS +-# include +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__to_utf8_loop_c) +-__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) +-__to_utf8_loop; +- +-static void * +-__to_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +- if (dl_hwcap & HWCAP_S390_VX) +- return __to_utf8_loop_vx; +- else +- return __to_utf8_loop_c; +-} +- +-strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) +- +-#else +-# define LOOPFCT TO_LOOP +-# define BODY BODY_TO_C +-# define LOOP_NEED_FLAGS +-# include +-#endif /* !HAVE_S390_VX_ASM_SUPPORT */ +- +-#include +diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c +deleted file mode 100644 +index 1ce5ac5..0000000 +--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c ++++ /dev/null +@@ -1,807 +0,0 @@ +-/* Conversion between UTF-8 and UTF-32 BE/internal. +- +- This module uses the Z9-109 variants of the Convert Unicode +- instructions. +- Copyright (C) 1997-2009 Free Software Foundation, Inc. +- +- Author: Andreas Krebbel +- Based on the work by Ulrich Drepper , 1997. +- +- Thanks to Daniel Appich who covered the relevant performance work +- in his diploma thesis. +- +- This is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- This is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +-#include +- +-#if defined HAVE_S390_VX_GCC_SUPPORT +-# define ASM_CLOBBER_VR(NR) , NR +-#else +-# define ASM_CLOBBER_VR(NR) +-#endif +- +-/* Defines for skeleton.c. */ +-#define DEFINE_INIT 0 +-#define DEFINE_FINI 0 +-#define MIN_NEEDED_FROM 1 +-#define MAX_NEEDED_FROM 6 +-#define MIN_NEEDED_TO 4 +-#define FROM_LOOP __from_utf8_loop +-#define TO_LOOP __to_utf8_loop +-#define FROM_DIRECTION (dir == from_utf8) +-#define ONE_DIRECTION 0 +- +-/* UTF-32 big endian byte order mark. */ +-#define BOM 0x0000feffu +- +-/* Direction of the transformation. */ +-enum direction +-{ +- illegal_dir, +- to_utf8, +- from_utf8 +-}; +- +-struct utf8_data +-{ +- enum direction dir; +- int emit_bom; +-}; +- +- +-extern int gconv_init (struct __gconv_step *step); +-int +-gconv_init (struct __gconv_step *step) +-{ +- /* Determine which direction. */ +- struct utf8_data *new_data; +- enum direction dir = illegal_dir; +- int emit_bom; +- int result; +- +- emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0); +- +- if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 +- && (__strcasecmp (step->__to_name, "UTF-32//") == 0 +- || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 +- || __strcasecmp (step->__to_name, "INTERNAL") == 0)) +- { +- dir = from_utf8; +- } +- else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0 +- && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 +- || __strcasecmp (step->__from_name, "INTERNAL") == 0)) +- { +- dir = to_utf8; +- } +- +- result = __GCONV_NOCONV; +- if (dir != illegal_dir) +- { +- new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); +- +- result = __GCONV_NOMEM; +- if (new_data != NULL) +- { +- new_data->dir = dir; +- new_data->emit_bom = emit_bom; +- step->__data = new_data; +- +- if (dir == from_utf8) +- { +- step->__min_needed_from = MIN_NEEDED_FROM; +- step->__max_needed_from = MIN_NEEDED_FROM; +- step->__min_needed_to = MIN_NEEDED_TO; +- step->__max_needed_to = MIN_NEEDED_TO; +- } +- else +- { +- step->__min_needed_from = MIN_NEEDED_TO; +- step->__max_needed_from = MIN_NEEDED_TO; +- step->__min_needed_to = MIN_NEEDED_FROM; +- step->__max_needed_to = MIN_NEEDED_FROM; +- } +- +- step->__stateful = 0; +- +- result = __GCONV_OK; +- } +- } +- +- return result; +-} +- +- +-extern void gconv_end (struct __gconv_step *data); +-void +-gconv_end (struct __gconv_step *data) +-{ +- free (data->__data); +-} +- +-/* The macro for the hardware loop. This is used for both +- directions. */ +-#define HARDWARE_CONVERT(INSTRUCTION) \ +- { \ +- register const unsigned char* pInput __asm__ ("8") = inptr; \ +- register unsigned long long inlen __asm__ ("9") = inend - inptr; \ +- register unsigned char* pOutput __asm__ ("10") = outptr; \ +- register unsigned long long outlen __asm__("11") = outend - outptr; \ +- uint64_t cc = 0; \ +- \ +- __asm__ __volatile__ (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ +- \ +- inptr = pInput; \ +- outptr = pOutput; \ +- cc >>= 28; \ +- \ +- if (cc == 1) \ +- { \ +- result = __GCONV_FULL_OUTPUT; \ +- } \ +- else if (cc == 2) \ +- { \ +- result = __GCONV_ILLEGAL_INPUT; \ +- } \ +- } +- +-#define PREPARE_LOOP \ +- enum direction dir = ((struct utf8_data *) step->__data)->dir; \ +- int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ +- \ +- if (emit_bom && !data->__internal_use \ +- && data->__invocation_counter == 0) \ +- { \ +- /* Emit the Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 4 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put32u (outbuf, BOM); \ +- outbuf += 4; \ +- } +- +-/* Conversion function from UTF-8 to UTF-32 internal/BE. */ +- +-#define STORE_REST_COMMON \ +- { \ +- /* We store the remaining bytes while converting them into the UCS4 \ +- format. We can assume that the first byte in the buffer is \ +- correct and that it requires a larger number of bytes than there \ +- are in the input buffer. */ \ +- wint_t ch = **inptrp; \ +- size_t cnt, r; \ +- \ +- state->__count = inend - *inptrp; \ +- \ +- assert (ch != 0xc0 && ch != 0xc1); \ +- if (ch >= 0xc2 && ch < 0xe0) \ +- { \ +- /* We expect two bytes. The first byte cannot be 0xc0 or \ +- 0xc1, otherwise the wide character could have been \ +- represented using a single byte. */ \ +- cnt = 2; \ +- ch &= 0x1f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ +- { \ +- /* We expect three bytes. */ \ +- cnt = 3; \ +- ch &= 0x0f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ +- { \ +- /* We expect four bytes. */ \ +- cnt = 4; \ +- ch &= 0x07; \ +- } \ +- else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ +- { \ +- /* We expect five bytes. */ \ +- cnt = 5; \ +- ch &= 0x03; \ +- } \ +- else \ +- { \ +- /* We expect six bytes. */ \ +- cnt = 6; \ +- ch &= 0x01; \ +- } \ +- \ +- /* The first byte is already consumed. */ \ +- r = cnt - 1; \ +- while (++(*inptrp) < inend) \ +- { \ +- ch <<= 6; \ +- ch |= **inptrp & 0x3f; \ +- --r; \ +- } \ +- \ +- /* Shift for the so far missing bytes. */ \ +- ch <<= r * 6; \ +- \ +- /* Store the number of bytes expected for the entire sequence. */ \ +- state->__count |= cnt << 8; \ +- \ +- /* Store the value. */ \ +- state->__value.__wch = ch; \ +- } +- +-#define UNPACK_BYTES_COMMON \ +- { \ +- static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \ +- wint_t wch = state->__value.__wch; \ +- size_t ntotal = state->__count >> 8; \ +- \ +- inlen = state->__count & 255; \ +- \ +- bytebuf[0] = inmask[ntotal - 2]; \ +- \ +- do \ +- { \ +- if (--ntotal < inlen) \ +- bytebuf[ntotal] = 0x80 | (wch & 0x3f); \ +- wch >>= 6; \ +- } \ +- while (ntotal > 1); \ +- \ +- bytebuf[0] |= wch; \ +- } +- +-#define CLEAR_STATE_COMMON \ +- state->__count = 0 +- +-#define BODY_FROM_HW(ASM) \ +- { \ +- ASM; \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- \ +- int i; \ +- for (i = 1; inptr + i < inend && i < 5; ++i) \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- break; \ +- \ +- if (__glibc_likely (inptr + i == inend \ +- && result == __GCONV_EMPTY_INPUT)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_FROM_LOOP_ERR_HANDLER (i); \ +- } +- +-/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */ +-#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1")) +- +- +-/* The software routine is copied from gconv_simple.c. */ +-#define BODY_FROM_C \ +- { \ +- /* Next input byte. */ \ +- uint32_t ch = *inptr; \ +- \ +- if (__glibc_likely (ch < 0x80)) \ +- { \ +- /* One byte sequence. */ \ +- ++inptr; \ +- } \ +- else \ +- { \ +- uint_fast32_t cnt; \ +- uint_fast32_t i; \ +- \ +- if (ch >= 0xc2 && ch < 0xe0) \ +- { \ +- /* We expect two bytes. The first byte cannot be 0xc0 or \ +- 0xc1, otherwise the wide character could have been \ +- represented using a single byte. */ \ +- cnt = 2; \ +- ch &= 0x1f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ +- { \ +- /* We expect three bytes. */ \ +- cnt = 3; \ +- ch &= 0x0f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ +- { \ +- /* We expect four bytes. */ \ +- cnt = 4; \ +- ch &= 0x07; \ +- } \ +- else \ +- { \ +- /* Search the end of this ill-formed UTF-8 character. This \ +- is the next byte with (x & 0xc0) != 0x80. */ \ +- i = 0; \ +- do \ +- ++i; \ +- while (inptr + i < inend \ +- && (*(inptr + i) & 0xc0) == 0x80 \ +- && i < 5); \ +- \ +- errout: \ +- STANDARD_FROM_LOOP_ERR_HANDLER (i); \ +- } \ +- \ +- if (__glibc_unlikely (inptr + cnt > inend)) \ +- { \ +- /* We don't have enough input. But before we report \ +- that check that all the bytes are correct. */ \ +- for (i = 1; inptr + i < inend; ++i) \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- break; \ +- \ +- if (__glibc_likely (inptr + i == inend)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- \ +- goto errout; \ +- } \ +- \ +- /* Read the possible remaining bytes. */ \ +- for (i = 1; i < cnt; ++i) \ +- { \ +- uint32_t byte = inptr[i]; \ +- \ +- if ((byte & 0xc0) != 0x80) \ +- /* This is an illegal encoding. */ \ +- break; \ +- \ +- ch <<= 6; \ +- ch |= byte & 0x3f; \ +- } \ +- \ +- /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ +- If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ +- have been represented with fewer than cnt bytes. */ \ +- if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ +- /* Do not accept UTF-16 surrogates. */ \ +- || (ch >= 0xd800 && ch <= 0xdfff) \ +- || (ch > 0x10ffff)) \ +- { \ +- /* This is an illegal encoding. */ \ +- goto errout; \ +- } \ +- \ +- inptr += cnt; \ +- } \ +- \ +- /* Now adjust the pointers and store the result. */ \ +- *((uint32_t *) outptr) = ch; \ +- outptr += sizeof (uint32_t); \ +- } +- +-#define HW_FROM_VX \ +- { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register size_t inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register size_t outlen asm("11") = outend - outptr; \ +- unsigned long tmp, tmp2, tmp3; \ +- asm volatile (".machine push\n\t" \ +- ".machine \"z13\"\n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ +- " vrepib %%v31,0x20\n\t" \ +- /* Loop which handles UTF-8 chars <=0x7f. */ \ +- "0: clgijl %[R_INLEN],16,20f\n\t" \ +- " clgijl %[R_OUTLEN],64,20f\n\t" \ +- "1: vl %%v16,0(%[R_IN])\n\t" \ +- " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ +- " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ +- UTF8 chars. */ \ +- /* Enlarge to UCS4. */ \ +- " vuplhb %%v18,%%v16\n\t" \ +- " vupllb %%v19,%%v16\n\t" \ +- " la %[R_IN],16(%[R_IN])\n\t" \ +- " vuplhh %%v20,%%v18\n\t" \ +- " aghi %[R_INLEN],-16\n\t" \ +- " vupllh %%v21,%%v18\n\t" \ +- " aghi %[R_OUTLEN],-64\n\t" \ +- " vuplhh %%v22,%%v19\n\t" \ +- " vupllh %%v23,%%v19\n\t" \ +- /* Store 64 bytes to buf_out. */ \ +- " vstm %%v20,%%v23,0(%[R_OUT])\n\t" \ +- " la %[R_OUT],64(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],16,20f\n\t" \ +- " clgijl %[R_OUTLEN],64,20f\n\t" \ +- " j 1b\n\t" \ +- "10: \n\t" \ +- /* At least one byte is > 0x7f. \ +- Store the preceding 1-byte chars. */ \ +- " vlgvb %[R_TMP],%%v17,7\n\t" \ +- " sllk %[R_TMP2],%[R_TMP],2\n\t" /* Compute highest \ +- index to store. */ \ +- " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ +- " ahi %[R_TMP2],-1\n\t" \ +- " jl 20f\n\t" \ +- " vuplhb %%v18,%%v16\n\t" \ +- " vuplhh %%v20,%%v18\n\t" \ +- " vstl %%v20,%[R_TMP2],0(%[R_OUT])\n\t" \ +- " ahi %[R_TMP2],-16\n\t" \ +- " jl 11f\n\t" \ +- " vupllh %%v21,%%v18\n\t" \ +- " vstl %%v21,%[R_TMP2],16(%[R_OUT])\n\t" \ +- " ahi %[R_TMP2],-16\n\t" \ +- " jl 11f\n\t" \ +- " vupllb %%v19,%%v16\n\t" \ +- " vuplhh %%v22,%%v19\n\t" \ +- " vstl %%v22,%[R_TMP2],32(%[R_OUT])\n\t" \ +- " ahi %[R_TMP2],-16\n\t" \ +- " jl 11f\n\t" \ +- " vupllh %%v23,%%v19\n\t" \ +- " vstl %%v23,%[R_TMP2],48(%[R_OUT])\n\t" \ +- "11: \n\t" \ +- /* Update pointers. */ \ +- " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_TMP]\n\t" \ +- " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ +- " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ +- /* Handle multibyte utf8-char with convert instruction. */ \ +- "20: cu14 %[R_OUT],%[R_IN],1\n\t" \ +- " jo 0b\n\t" /* Try vector implemenation again. */ \ +- " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ +- " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ +- ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (pInput) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ +- , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ +- , [R_RES] "+d" (result) \ +- : /* inputs */ \ +- [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ +- , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ +- : /* clobber list */ "memory", "cc" \ +- ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ +- ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +- ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ +- ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \ +- ASM_CLOBBER_VR ("v31") \ +- ); \ +- inptr = pInput; \ +- outptr = pOutput; \ +- } +-#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) +- +-/* These definitions apply to the UTF-8 to UTF-32 direction. The +- software implementation for UTF-8 still supports multibyte +- characters up to 6 bytes whereas the hardware variant does not. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_c +- +-#define LOOP_NEED_FLAGS +- +-#define STORE_REST STORE_REST_COMMON +-#define UNPACK_BYTES UNPACK_BYTES_COMMON +-#define CLEAR_STATE CLEAR_STATE_COMMON +-#define BODY BODY_FROM_C +-#include +- +- +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT __from_utf8_loop_etf3eh +- +-#define LOOP_NEED_FLAGS +- +-#define STORE_REST STORE_REST_COMMON +-#define UNPACK_BYTES UNPACK_BYTES_COMMON +-#define CLEAR_STATE CLEAR_STATE_COMMON +-#define BODY BODY_FROM_ETF3EH +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector instructions. */ +-# define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-# define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-# define LOOPFCT __from_utf8_loop_vx +- +-# define LOOP_NEED_FLAGS +- +-# define STORE_REST STORE_REST_COMMON +-# define UNPACK_BYTES UNPACK_BYTES_COMMON +-# define CLEAR_STATE CLEAR_STATE_COMMON +-# define BODY BODY_FROM_VX +-# include +-#endif +- +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__from_utf8_loop_c) +-__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) +-__from_utf8_loop; +- +-static void * +-__from_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __from_utf8_loop_vx; +- else +-#endif +- if (dl_hwcap & HWCAP_S390_ETF3EH) +- return __from_utf8_loop_etf3eh; +- else +- return __from_utf8_loop_c; +-} +- +-strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) +- +- +-/* Conversion from UTF-32 internal/BE to UTF-8. */ +-#define BODY_TO_HW(ASM) \ +- { \ +- ASM; \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- if (inptr + 4 > inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } +- +-/* The hardware routine uses the S/390 cu41 instruction. */ +-#define BODY_TO_ETF3EH BODY_TO_HW (HARDWARE_CONVERT ("cu41 %0, %1")) +- +-/* The hardware routine uses the S/390 vector and cu41 instructions. */ +-#define BODY_TO_VX BODY_TO_HW (HW_TO_VX) +- +-/* The software routine mimics the S/390 cu41 instruction. */ +-#define BODY_TO_C \ +- { \ +- uint32_t wc = *((const uint32_t *) inptr); \ +- \ +- if (__glibc_likely (wc <= 0x7f)) \ +- { \ +- /* Single UTF-8 char. */ \ +- *outptr = (uint8_t)wc; \ +- outptr++; \ +- } \ +- else if (wc <= 0x7ff) \ +- { \ +- /* Two UTF-8 chars. */ \ +- if (__glibc_unlikely (outptr + 2 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- \ +- outptr[0] = 0xc0; \ +- outptr[0] |= wc >> 6; \ +- \ +- outptr[1] = 0x80; \ +- outptr[1] |= wc & 0x3f; \ +- \ +- outptr += 2; \ +- } \ +- else if (wc <= 0xffff) \ +- { \ +- /* Three UTF-8 chars. */ \ +- if (__glibc_unlikely (outptr + 3 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- if (wc >= 0xd800 && wc < 0xdc00) \ +- { \ +- /* Do not accept UTF-16 surrogates. */ \ +- result = __GCONV_ILLEGAL_INPUT; \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } \ +- outptr[0] = 0xe0; \ +- outptr[0] |= wc >> 12; \ +- \ +- outptr[1] = 0x80; \ +- outptr[1] |= (wc >> 6) & 0x3f; \ +- \ +- outptr[2] = 0x80; \ +- outptr[2] |= wc & 0x3f; \ +- \ +- outptr += 3; \ +- } \ +- else if (wc <= 0x10ffff) \ +- { \ +- /* Four UTF-8 chars. */ \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ +- { \ +- /* Overflow in the output buffer. */ \ +- result = __GCONV_FULL_OUTPUT; \ +- break; \ +- } \ +- outptr[0] = 0xf0; \ +- outptr[0] |= wc >> 18; \ +- \ +- outptr[1] = 0x80; \ +- outptr[1] |= (wc >> 12) & 0x3f; \ +- \ +- outptr[2] = 0x80; \ +- outptr[2] |= (wc >> 6) & 0x3f; \ +- \ +- outptr[3] = 0x80; \ +- outptr[3] |= wc & 0x3f; \ +- \ +- outptr += 4; \ +- } \ +- else \ +- { \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } \ +- inptr += 4; \ +- } +- +-#define HW_TO_VX \ +- { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register size_t inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register size_t outlen asm("11") = outend - outptr; \ +- unsigned long tmp, tmp2; \ +- asm volatile (".machine push\n\t" \ +- ".machine \"z13\"\n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ +- " vzero %%v21\n\t" \ +- " vleih %%v21,8192,0\n\t" /* element 0: > */ \ +- " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ +- /* Loop which handles UTF-32 chars <=0x7f. */ \ +- "0: clgijl %[R_INLEN],64,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ +- "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ +- " lghi %[R_TMP],0\n\t" \ +- /* Shorten to byte values. */ \ +- " vpkf %%v23,%%v16,%%v17\n\t" \ +- " vpkf %%v24,%%v18,%%v19\n\t" \ +- " vpkh %%v23,%%v23,%%v24\n\t" \ +- /* Checking for values > 0x7f. */ \ +- " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ +- " jno 10f\n\t" \ +- " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ +- " jno 11f\n\t" \ +- " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ +- " jno 12f\n\t" \ +- " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ +- " jno 13f\n\t" \ +- /* Store 16bytes to outptr. */ \ +- " vst %%v23,0(%[R_OUT])\n\t" \ +- " aghi %[R_INLEN],-64\n\t" \ +- " aghi %[R_OUTLEN],-16\n\t" \ +- " la %[R_IN],64(%[R_IN])\n\t" \ +- " la %[R_OUT],16(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],64,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ +- " j 1b\n\t" \ +- /* Found a value > 0x7f. */ \ +- "13: ahi %[R_TMP],4\n\t" \ +- "12: ahi %[R_TMP],4\n\t" \ +- "11: ahi %[R_TMP],4\n\t" \ +- "10: vlgvb %[R_I],%%v22,7\n\t" \ +- " srlg %[R_I],%[R_I],2\n\t" \ +- " agr %[R_I],%[R_TMP]\n\t" \ +- " je 20f\n\t" \ +- /* Store characters before invalid one... */ \ +- " slgr %[R_OUTLEN],%[R_I]\n\t" \ +- "15: aghi %[R_I],-1\n\t" \ +- " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ +- /* ... and update pointers. */ \ +- " aghi %[R_I],1\n\t" \ +- " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ +- " sllg %[R_I],%[R_I],2\n\t" \ +- " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_I]\n\t" \ +- /* Handle multibyte utf8-char with convert instruction. */ \ +- "20: cu41 %[R_OUT],%[R_IN]\n\t" \ +- " jo 0b\n\t" /* Try vector implemenation again. */ \ +- " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ +- " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ +- ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (pInput) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \ +- , [R_I] "=a" (tmp2) \ +- , [R_RES] "+d" (result) \ +- : /* inputs */ \ +- [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ +- , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ +- : /* clobber list */ "memory", "cc" \ +- ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ +- ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +- ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ +- ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ +- ASM_CLOBBER_VR ("v24") \ +- ); \ +- inptr = pInput; \ +- outptr = pOutput; \ +- } +- +-/* Generate loop-function with software routing. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf8_loop_c +-#define BODY BODY_TO_C +-#define LOOP_NEED_FLAGS +-#include +- +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf8_loop_etf3eh +-#define LOOP_NEED_FLAGS +-#define BODY BODY_TO_ETF3EH +-#include +- +-#if defined HAVE_S390_VX_ASM_SUPPORT +-/* Generate loop-function with hardware vector and utf-convert instructions. */ +-# define MIN_NEEDED_INPUT MIN_NEEDED_TO +-# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-# define LOOPFCT __to_utf8_loop_vx +-# define BODY BODY_TO_VX +-# define LOOP_NEED_FLAGS +-# include +-#endif +- +-/* Generate ifunc'ed loop function. */ +-__typeof(__to_utf8_loop_c) +-__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) +-__to_utf8_loop; +- +-static void * +-__to_utf8_loop_resolver (unsigned long int dl_hwcap) +-{ +-#if defined HAVE_S390_VX_ASM_SUPPORT +- if (dl_hwcap & HWCAP_S390_VX) +- return __to_utf8_loop_vx; +- else +-#endif +- if (dl_hwcap & HWCAP_S390_ETF3EH) +- return __to_utf8_loop_etf3eh; +- else +- return __to_utf8_loop_c; +-} +- +-strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) +- +- +-#include +diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c +new file mode 100644 +index 0000000..8d42ab8 +--- /dev/null ++++ b/sysdeps/s390/utf16-utf32-z9.c +@@ -0,0 +1,636 @@ ++/* Conversion between UTF-16 and UTF-32 BE/internal. ++ ++ This module uses the Z9-109 variants of the Convert Unicode ++ instructions. ++ Copyright (C) 1997-2016 Free Software Foundation, Inc. ++ ++ Author: Andreas Krebbel ++ Based on the work by Ulrich Drepper , 1997. ++ ++ Thanks to Daniel Appich who covered the relevant performance work ++ in his diploma thesis. ++ ++ This is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++#else ++# define ASM_CLOBBER_VR(NR) ++#endif ++ ++#if defined __s390x__ ++# define CONVERT_32BIT_SIZE_T(REG) ++#else ++# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" ++#endif ++ ++/* UTF-32 big endian byte order mark. */ ++#define BOM_UTF32 0x0000feffu ++ ++/* UTF-16 big endian byte order mark. */ ++#define BOM_UTF16 0xfeff ++ ++#define DEFINE_INIT 0 ++#define DEFINE_FINI 0 ++#define MIN_NEEDED_FROM 2 ++#define MAX_NEEDED_FROM 4 ++#define MIN_NEEDED_TO 4 ++#define FROM_LOOP __from_utf16_loop ++#define TO_LOOP __to_utf16_loop ++#define FROM_DIRECTION (dir == from_utf16) ++#define ONE_DIRECTION 0 ++ ++/* Direction of the transformation. */ ++enum direction ++{ ++ illegal_dir, ++ to_utf16, ++ from_utf16 ++}; ++ ++struct utf16_data ++{ ++ enum direction dir; ++ int emit_bom; ++}; ++ ++ ++extern int gconv_init (struct __gconv_step *step); ++int ++gconv_init (struct __gconv_step *step) ++{ ++ /* Determine which direction. */ ++ struct utf16_data *new_data; ++ enum direction dir = illegal_dir; ++ int emit_bom; ++ int result; ++ ++ emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0 ++ || __strcasecmp (step->__to_name, "UTF-16//") == 0); ++ ++ if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 ++ && (__strcasecmp (step->__to_name, "UTF-32//") == 0 ++ || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 ++ || __strcasecmp (step->__to_name, "INTERNAL") == 0)) ++ { ++ dir = from_utf16; ++ } ++ else if ((__strcasecmp (step->__to_name, "UTF-16//") == 0 ++ || __strcasecmp (step->__to_name, "UTF-16BE//") == 0) ++ && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 ++ || __strcasecmp (step->__from_name, "INTERNAL") == 0)) ++ { ++ dir = to_utf16; ++ } ++ ++ result = __GCONV_NOCONV; ++ if (dir != illegal_dir) ++ { ++ new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data)); ++ ++ result = __GCONV_NOMEM; ++ if (new_data != NULL) ++ { ++ new_data->dir = dir; ++ new_data->emit_bom = emit_bom; ++ step->__data = new_data; ++ ++ if (dir == from_utf16) ++ { ++ step->__min_needed_from = MIN_NEEDED_FROM; ++ step->__max_needed_from = MIN_NEEDED_FROM; ++ step->__min_needed_to = MIN_NEEDED_TO; ++ step->__max_needed_to = MIN_NEEDED_TO; ++ } ++ else ++ { ++ step->__min_needed_from = MIN_NEEDED_TO; ++ step->__max_needed_from = MIN_NEEDED_TO; ++ step->__min_needed_to = MIN_NEEDED_FROM; ++ step->__max_needed_to = MIN_NEEDED_FROM; ++ } ++ ++ step->__stateful = 0; ++ ++ result = __GCONV_OK; ++ } ++ } ++ ++ return result; ++} ++ ++ ++extern void gconv_end (struct __gconv_step *data); ++void ++gconv_end (struct __gconv_step *data) ++{ ++ free (data->__data); ++} ++ ++/* The macro for the hardware loop. This is used for both ++ directions. */ ++#define HARDWARE_CONVERT(INSTRUCTION) \ ++ { \ ++ register const unsigned char* pInput __asm__ ("8") = inptr; \ ++ register size_t inlen __asm__ ("9") = inend - inptr; \ ++ register unsigned char* pOutput __asm__ ("10") = outptr; \ ++ register size_t outlen __asm__("11") = outend - outptr; \ ++ unsigned long cc = 0; \ ++ \ ++ __asm__ __volatile__ (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ ++ \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ cc >>= 28; \ ++ \ ++ if (cc == 1) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ } \ ++ else if (cc == 2) \ ++ { \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ } \ ++ } ++ ++#define PREPARE_LOOP \ ++ enum direction dir = ((struct utf16_data *) step->__data)->dir; \ ++ int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ ++ \ ++ if (emit_bom && !data->__internal_use \ ++ && data->__invocation_counter == 0) \ ++ { \ ++ if (dir == to_utf16) \ ++ { \ ++ /* Emit the UTF-16 Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 2 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put16u (outbuf, BOM_UTF16); \ ++ outbuf += 2; \ ++ } \ ++ else \ ++ { \ ++ /* Emit the UTF-32 Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 4 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put32u (outbuf, BOM_UTF32); \ ++ outbuf += 4; \ ++ } \ ++ } ++ ++/* Conversion function from UTF-16 to UTF-32 internal/BE. */ ++ ++/* The software routine is copied from utf-16.c (minus bytes ++ swapping). */ ++#define BODY_FROM_C \ ++ { \ ++ uint16_t u1 = get16 (inptr); \ ++ \ ++ if (__builtin_expect (u1 < 0xd800, 1) || u1 > 0xdfff) \ ++ { \ ++ /* No surrogate. */ \ ++ put32 (outptr, u1); \ ++ inptr += 2; \ ++ } \ ++ else \ ++ { \ ++ /* An isolated low-surrogate was found. This has to be \ ++ considered ill-formed. */ \ ++ if (__glibc_unlikely (u1 >= 0xdc00)) \ ++ { \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } \ ++ /* It's a surrogate character. At least the first word says \ ++ it is. */ \ ++ if (__glibc_unlikely (inptr + 4 > inend)) \ ++ { \ ++ /* We don't have enough input for another complete input \ ++ character. */ \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ inptr += 2; \ ++ uint16_t u2 = get16 (inptr); \ ++ if (__builtin_expect (u2 < 0xdc00, 0) \ ++ || __builtin_expect (u2 > 0xdfff, 0)) \ ++ { \ ++ /* This is no valid second word for a surrogate. */ \ ++ inptr -= 2; \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } \ ++ \ ++ put32 (outptr, ((u1 - 0xd7c0) << 10) + (u2 - 0xdc00)); \ ++ inptr += 2; \ ++ } \ ++ outptr += 4; \ ++ } ++ ++#define BODY_FROM_VX \ ++ { \ ++ size_t inlen = inend - inptr; \ ++ size_t outlen = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for surrogates. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-16 chars <0xd800, >0xdfff. */ \ ++ "0: clgijl %[R_INLEN],16,2f\n\t" \ ++ " clgijl %[R_OUTLEN],32,2f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ /* Check for surrogate chars. */ \ ++ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ /* Enlarge to UTF-32. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ /* Store 32 bytes to buf_out. */ \ ++ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-32\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,2f\n\t" \ ++ " clgijl %[R_OUTLEN],32,2f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff. (v30, v31) */ \ ++ "9: .short 0xd800,0xdfff,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ " .short 0xa000,0xc000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* At least on uint16_t is in range of surrogates. \ ++ Store the preceding chars. */ \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " sllg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 12f\n\t" \ ++ " vstl %%v17,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vstl %%v18,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ "11: \n\t" /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Calculate remaining uint16_t values in loaded vrs. */ \ ++ "12: lghi %[R_TMP2],16\n\t" \ ++ " sgr %[R_TMP2],%[R_TMP]\n\t" \ ++ " srl %[R_TMP2],1\n\t" \ ++ " llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_OUTLEN],-4\n\t" \ ++ " j 16f\n\t" \ ++ /* Handle remaining bytes. */ \ ++ "2: \n\t" \ ++ /* Zero, one or more bytes available? */ \ ++ " clgfi %[R_INLEN],1\n\t" \ ++ " je 97f\n\t" /* Only one byte available. */ \ ++ " jl 99f\n\t" /* End if no bytes available. */ \ ++ /* Calculate remaining uint16_t values in inptr. */ \ ++ " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ ++ /* Handle remaining uint16_t values. */ \ ++ "13: llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " slgfi %[R_OUTLEN],4\n\t" \ ++ " jl 96f \n\t" \ ++ " clfi %[R_TMP],0xd800\n\t" \ ++ " jhe 15f\n\t" \ ++ "14: st %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-2\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],13b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Handle UTF-16 surrogate pair. */ \ ++ "15: clfi %[R_TMP],0xdfff\n\t" \ ++ " jh 14b\n\t" /* Jump away if ch > 0xdfff. */ \ ++ "16: clfi %[R_TMP],0xdc00\n\t" \ ++ " jhe 98f\n\t" /* Jump away in case of low-surrogate. */ \ ++ " slgfi %[R_INLEN],4\n\t" \ ++ " jl 97f\n\t" /* Big enough input? */ \ ++ " llh %[R_TMP3],2(%[R_IN])\n\t" /* Load low surrogate. */ \ ++ " slfi %[R_TMP],0xd7c0\n\t" \ ++ " sll %[R_TMP],10\n\t" \ ++ " risbgn %[R_TMP],%[R_TMP3],54,63,0\n\t" /* Insert klmnopqrst. */ \ ++ " nilf %[R_TMP3],0xfc00\n\t" \ ++ " clfi %[R_TMP3],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ ++ " jne 98f\n\t" \ ++ " st %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " aghi %[R_TMP2],-2\n\t" \ ++ " jh 13b\n\t" /* Handle remaining uint16_t values. */ \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ "96: \n\t" /* Return full output. */ \ ++ " lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ ++ " j 99f\n\t" \ ++ "97: \n\t" /* Return incomplete input. */ \ ++ " lghi %[R_RES],%[RES_IN_FULL]\n\t" \ ++ " j 99f\n\t" \ ++ "98:\n\t" /* Return Illegal character. */ \ ++ " lghi %[R_RES],%[RES_IN_ILL]\n\t" \ ++ "99:\n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ if (__glibc_likely (inptr == inend) \ ++ || result != __GCONV_ILLEGAL_INPUT) \ ++ break; \ ++ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } ++ ++ ++/* Generate loop-function with software routing. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#if defined HAVE_S390_VX_ASM_SUPPORT ++# define LOOPFCT __from_utf16_loop_c ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_C ++# include ++ ++/* Generate loop-function with hardware vector instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT __from_utf16_loop_vx ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_VX ++# include ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_utf16_loop_c) ++__attribute__ ((ifunc ("__from_utf16_loop_resolver"))) ++__from_utf16_loop; ++ ++static void * ++__from_utf16_loop_resolver (unsigned long int dl_hwcap) ++{ ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __from_utf16_loop_vx; ++ else ++ return __from_utf16_loop_c; ++} ++ ++strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) ++#else ++# define LOOPFCT FROM_LOOP ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_C ++# include ++#endif ++ ++/* Conversion from UTF-32 internal/BE to UTF-16. */ ++ ++/* The software routine is copied from utf-16.c (minus bytes ++ swapping). */ ++#define BODY_TO_C \ ++ { \ ++ uint32_t c = get32 (inptr); \ ++ \ ++ if (__builtin_expect (c <= 0xd7ff, 1) \ ++ || (c >=0xdc00 && c <= 0xffff)) \ ++ { \ ++ /* Two UTF-16 chars. */ \ ++ put16 (outptr, c); \ ++ } \ ++ else if (__builtin_expect (c >= 0x10000, 1) \ ++ && __builtin_expect (c <= 0x10ffff, 1)) \ ++ { \ ++ /* Four UTF-16 chars. */ \ ++ uint16_t zabcd = ((c & 0x1f0000) >> 16) - 1; \ ++ uint16_t out; \ ++ \ ++ /* Generate a surrogate character. */ \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ ++ out = 0xd800; \ ++ out |= (zabcd & 0xff) << 6; \ ++ out |= (c >> 10) & 0x3f; \ ++ put16 (outptr, out); \ ++ outptr += 2; \ ++ \ ++ out = 0xdc00; \ ++ out |= c & 0x3ff; \ ++ put16 (outptr, out); \ ++ } \ ++ else \ ++ { \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ outptr += 2; \ ++ inptr += 4; \ ++ } ++ ++#define BODY_TO_ETF3EH \ ++ { \ ++ HARDWARE_CONVERT ("cu42 %0, %1"); \ ++ \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++#define BODY_TO_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for surrogates. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-16 chars \ ++ ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ ++ "0: clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ ++ /* Shorten to UTF-16. */ \ ++ " vpkf %%v18,%%v16,%%v17\n\t" \ ++ /* Check for surrogate chars. */ \ ++ " vstrcfs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v19,%%v17,%%v30,%%v31\n\t" \ ++ " jno 11f\n\t" \ ++ /* Store 16 bytes to buf_out. */ \ ++ " vst %%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-32\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],32,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ ++ and check for ch >= 0x10000. (v30, v31) */ \ ++ "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ ++ " .long 0xa0000000,0xc0000000, 0xa0000000,0xa0000000\n\t" \ ++ /* At least on UTF32 char is in range of surrogates. \ ++ Store the preceding characters. */ \ ++ "11: ahi %[R_TMP2],16\n\t" \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " agr %[R_TMP],%[R_TMP2]\n\t" \ ++ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 20f\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handles UTF16 surrogates with convert instruction. */ \ ++ "20: cu42 %[R_OUT],%[R_IN]\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++/* Generate loop-function with software routing. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf16_loop_c ++#define LOOP_NEED_FLAGS ++#define BODY BODY_TO_C ++#include ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf16_loop_etf3eh ++#define LOOP_NEED_FLAGS ++#define BODY BODY_TO_ETF3EH ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define LOOPFCT __to_utf16_loop_vx ++# define LOOP_NEED_FLAGS ++# define BODY BODY_TO_VX ++# include ++#endif ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__to_utf16_loop_c) ++__attribute__ ((ifunc ("__to_utf16_loop_resolver"))) ++__to_utf16_loop; ++ ++static void * ++__to_utf16_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __to_utf16_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS ++ && dl_hwcap & HWCAP_S390_ETF3EH) ++ return __to_utf16_loop_etf3eh; ++ else ++ return __to_utf16_loop_c; ++} ++ ++strong_alias (__to_utf16_loop_c_single, __to_utf16_loop_single) ++ ++ ++#include +diff --git a/sysdeps/s390/utf8-utf16-z9.c b/sysdeps/s390/utf8-utf16-z9.c +new file mode 100644 +index 0000000..d3dc9bd +--- /dev/null ++++ b/sysdeps/s390/utf8-utf16-z9.c +@@ -0,0 +1,818 @@ ++/* Conversion between UTF-16 and UTF-32 BE/internal. ++ ++ This module uses the Z9-109 variants of the Convert Unicode ++ instructions. ++ Copyright (C) 1997-2016 Free Software Foundation, Inc. ++ ++ Author: Andreas Krebbel ++ Based on the work by Ulrich Drepper , 1997. ++ ++ Thanks to Daniel Appich who covered the relevant performance work ++ in his diploma thesis. ++ ++ This is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++#else ++# define ASM_CLOBBER_VR(NR) ++#endif ++ ++#if defined __s390x__ ++# define CONVERT_32BIT_SIZE_T(REG) ++#else ++# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" ++#endif ++ ++/* Defines for skeleton.c. */ ++#define DEFINE_INIT 0 ++#define DEFINE_FINI 0 ++#define MIN_NEEDED_FROM 1 ++#define MAX_NEEDED_FROM 4 ++#define MIN_NEEDED_TO 2 ++#define MAX_NEEDED_TO 4 ++#define FROM_LOOP __from_utf8_loop ++#define TO_LOOP __to_utf8_loop ++#define FROM_DIRECTION (dir == from_utf8) ++#define ONE_DIRECTION 0 ++ ++ ++/* UTF-16 big endian byte order mark. */ ++#define BOM_UTF16 0xfeff ++ ++/* Direction of the transformation. */ ++enum direction ++{ ++ illegal_dir, ++ to_utf8, ++ from_utf8 ++}; ++ ++struct utf8_data ++{ ++ enum direction dir; ++ int emit_bom; ++}; ++ ++ ++extern int gconv_init (struct __gconv_step *step); ++int ++gconv_init (struct __gconv_step *step) ++{ ++ /* Determine which direction. */ ++ struct utf8_data *new_data; ++ enum direction dir = illegal_dir; ++ int emit_bom; ++ int result; ++ ++ emit_bom = (__strcasecmp (step->__to_name, "UTF-16//") == 0); ++ ++ if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 ++ && (__strcasecmp (step->__to_name, "UTF-16//") == 0 ++ || __strcasecmp (step->__to_name, "UTF-16BE//") == 0)) ++ { ++ dir = from_utf8; ++ } ++ else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0 ++ && __strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0) ++ { ++ dir = to_utf8; ++ } ++ ++ result = __GCONV_NOCONV; ++ if (dir != illegal_dir) ++ { ++ new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); ++ ++ result = __GCONV_NOMEM; ++ if (new_data != NULL) ++ { ++ new_data->dir = dir; ++ new_data->emit_bom = emit_bom; ++ step->__data = new_data; ++ ++ if (dir == from_utf8) ++ { ++ step->__min_needed_from = MIN_NEEDED_FROM; ++ step->__max_needed_from = MIN_NEEDED_FROM; ++ step->__min_needed_to = MIN_NEEDED_TO; ++ step->__max_needed_to = MIN_NEEDED_TO; ++ } ++ else ++ { ++ step->__min_needed_from = MIN_NEEDED_TO; ++ step->__max_needed_from = MIN_NEEDED_TO; ++ step->__min_needed_to = MIN_NEEDED_FROM; ++ step->__max_needed_to = MIN_NEEDED_FROM; ++ } ++ ++ step->__stateful = 0; ++ ++ result = __GCONV_OK; ++ } ++ } ++ ++ return result; ++} ++ ++ ++extern void gconv_end (struct __gconv_step *data); ++void ++gconv_end (struct __gconv_step *data) ++{ ++ free (data->__data); ++} ++ ++/* The macro for the hardware loop. This is used for both ++ directions. */ ++#define HARDWARE_CONVERT(INSTRUCTION) \ ++ { \ ++ register const unsigned char* pInput __asm__ ("8") = inptr; \ ++ register size_t inlen __asm__ ("9") = inend - inptr; \ ++ register unsigned char* pOutput __asm__ ("10") = outptr; \ ++ register size_t outlen __asm__("11") = outend - outptr; \ ++ unsigned long cc = 0; \ ++ \ ++ __asm__ __volatile__ (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ ++ \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ cc >>= 28; \ ++ \ ++ if (cc == 1) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ } \ ++ else if (cc == 2) \ ++ { \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ } \ ++ } ++ ++#define PREPARE_LOOP \ ++ enum direction dir = ((struct utf8_data *) step->__data)->dir; \ ++ int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ ++ \ ++ if (emit_bom && !data->__internal_use \ ++ && data->__invocation_counter == 0) \ ++ { \ ++ /* Emit the UTF-16 Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 2 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put16u (outbuf, BOM_UTF16); \ ++ outbuf += 2; \ ++ } ++ ++/* Conversion function from UTF-8 to UTF-16. */ ++#define BODY_FROM_HW(ASM) \ ++ { \ ++ ASM; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ \ ++ int i; \ ++ for (i = 1; inptr + i < inend && i < 5; ++i) \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ break; \ ++ \ ++ if (__glibc_likely (inptr + i == inend \ ++ && result == __GCONV_EMPTY_INPUT)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (i); \ ++ } ++ ++#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu12 %0, %1, 1")) ++ ++#define HW_FROM_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ ++ " vrepib %%v31,0x20\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-8 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],32,20f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Enlarge to UTF-16. */ \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ /* Store 32 bytes to buf_out. */ \ ++ " vstm %%v18,%%v19,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-32\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],32,20f\n\t" \ ++ " j 1b\n\t" \ ++ "10:\n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ " vlgvb %[R_TMP],%%v17,7\n\t" \ ++ " sllk %[R_TMP2],%[R_TMP],1\n\t" /* Compute highest \ ++ index to store. */ \ ++ " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ ++ " ahi %[R_TMP2],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " vstl %%v19,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ "11: \n\t" /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu12 %[R_OUT],%[R_IN],1\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ } ++#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) ++ ++ ++/* The software implementation is based on the code in gconv_simple.c. */ ++#define BODY_FROM_C \ ++ { \ ++ /* Next input byte. */ \ ++ uint16_t ch = *inptr; \ ++ \ ++ if (__glibc_likely (ch < 0x80)) \ ++ { \ ++ /* One byte sequence. */ \ ++ ++inptr; \ ++ } \ ++ else \ ++ { \ ++ uint_fast32_t cnt; \ ++ uint_fast32_t i; \ ++ \ ++ if (ch >= 0xc2 && ch < 0xe0) \ ++ { \ ++ /* We expect two bytes. The first byte cannot be 0xc0 \ ++ or 0xc1, otherwise the wide character could have been \ ++ represented using a single byte. */ \ ++ cnt = 2; \ ++ ch &= 0x1f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ ++ { \ ++ /* We expect three bytes. */ \ ++ cnt = 3; \ ++ ch &= 0x0f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ ++ { \ ++ /* We expect four bytes. */ \ ++ cnt = 4; \ ++ ch &= 0x07; \ ++ } \ ++ else \ ++ { \ ++ /* Search the end of this ill-formed UTF-8 character. This \ ++ is the next byte with (x & 0xc0) != 0x80. */ \ ++ i = 0; \ ++ do \ ++ ++i; \ ++ while (inptr + i < inend \ ++ && (*(inptr + i) & 0xc0) == 0x80 \ ++ && i < 5); \ ++ \ ++ errout: \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (i); \ ++ } \ ++ \ ++ if (__glibc_unlikely (inptr + cnt > inend)) \ ++ { \ ++ /* We don't have enough input. But before we report \ ++ that check that all the bytes are correct. */ \ ++ for (i = 1; inptr + i < inend; ++i) \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ break; \ ++ \ ++ if (__glibc_likely (inptr + i == inend)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ goto errout; \ ++ } \ ++ \ ++ if (cnt == 4) \ ++ { \ ++ /* For 4 byte UTF-8 chars two UTF-16 chars (high and \ ++ low) are needed. */ \ ++ uint16_t zabcd, high, low; \ ++ \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ ++ /* Check if tail-bytes >= 0x80, < 0xc0. */ \ ++ for (i = 1; i < cnt; ++i) \ ++ { \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ /* This is an illegal encoding. */ \ ++ goto errout; \ ++ } \ ++ \ ++ /* See Principles of Operations cu12. */ \ ++ zabcd = (((inptr[0] & 0x7) << 2) | \ ++ ((inptr[1] & 0x30) >> 4)) - 1; \ ++ \ ++ /* z-bit must be zero after subtracting 1. */ \ ++ if (zabcd & 0x10) \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (4) \ ++ \ ++ high = (uint16_t)(0xd8 << 8); /* high surrogate id */ \ ++ high |= zabcd << 6; /* abcd bits */ \ ++ high |= (inptr[1] & 0xf) << 2; /* efgh bits */ \ ++ high |= (inptr[2] & 0x30) >> 4; /* ij bits */ \ ++ \ ++ low = (uint16_t)(0xdc << 8); /* low surrogate id */ \ ++ low |= ((uint16_t)inptr[2] & 0xc) << 6; /* kl bits */ \ ++ low |= (inptr[2] & 0x3) << 6; /* mn bits */ \ ++ low |= inptr[3] & 0x3f; /* opqrst bits */ \ ++ \ ++ put16 (outptr, high); \ ++ outptr += 2; \ ++ put16 (outptr, low); \ ++ outptr += 2; \ ++ inptr += 4; \ ++ continue; \ ++ } \ ++ else \ ++ { \ ++ /* Read the possible remaining bytes. */ \ ++ for (i = 1; i < cnt; ++i) \ ++ { \ ++ uint16_t byte = inptr[i]; \ ++ \ ++ if ((byte & 0xc0) != 0x80) \ ++ /* This is an illegal encoding. */ \ ++ break; \ ++ \ ++ ch <<= 6; \ ++ ch |= byte & 0x3f; \ ++ } \ ++ \ ++ /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ ++ If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ ++ have been represented with fewer than cnt bytes. */ \ ++ if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ ++ /* Do not accept UTF-16 surrogates. */ \ ++ || (ch >= 0xd800 && ch <= 0xdfff)) \ ++ { \ ++ /* This is an illegal encoding. */ \ ++ goto errout; \ ++ } \ ++ \ ++ inptr += cnt; \ ++ } \ ++ } \ ++ /* Now adjust the pointers and store the result. */ \ ++ *((uint16_t *) outptr) = ch; \ ++ outptr += sizeof (uint16_t); \ ++ } ++ ++/* Generate loop-function with software implementation. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_c ++#define LOOP_NEED_FLAGS ++#define BODY BODY_FROM_C ++#include ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_etf3eh ++#define LOOP_NEED_FLAGS ++#define BODY BODY_FROM_ETF3EH ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_TO ++# define LOOPFCT __from_utf8_loop_vx ++# define LOOP_NEED_FLAGS ++# define BODY BODY_FROM_VX ++# include ++#endif ++ ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_utf8_loop_c) ++__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) ++__from_utf8_loop; ++ ++static void * ++__from_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __from_utf8_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS ++ && dl_hwcap & HWCAP_S390_ETF3EH) ++ return __from_utf8_loop_etf3eh; ++ else ++ return __from_utf8_loop_c; ++} ++ ++strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) ++ ++/* Conversion from UTF-16 to UTF-8. */ ++ ++/* The software routine is based on the functionality of the S/390 ++ hardware instruction (cu21) as described in the Principles of ++ Operation. */ ++#define BODY_TO_C \ ++ { \ ++ uint16_t c = get16 (inptr); \ ++ \ ++ if (__glibc_likely (c <= 0x007f)) \ ++ { \ ++ /* Single byte UTF-8 char. */ \ ++ *outptr = c & 0xff; \ ++ outptr++; \ ++ } \ ++ else if (c >= 0x0080 && c <= 0x07ff) \ ++ { \ ++ /* Two byte UTF-8 char. */ \ ++ \ ++ if (__glibc_unlikely (outptr + 2 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ ++ outptr[0] = 0xc0; \ ++ outptr[0] |= c >> 6; \ ++ \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= c & 0x3f; \ ++ \ ++ outptr += 2; \ ++ } \ ++ else if ((c >= 0x0800 && c <= 0xd7ff) || c > 0xdfff) \ ++ { \ ++ /* Three byte UTF-8 char. */ \ ++ \ ++ if (__glibc_unlikely (outptr + 3 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ outptr[0] = 0xe0; \ ++ outptr[0] |= c >> 12; \ ++ \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= (c >> 6) & 0x3f; \ ++ \ ++ outptr[2] = 0x80; \ ++ outptr[2] |= c & 0x3f; \ ++ \ ++ outptr += 3; \ ++ } \ ++ else if (c >= 0xd800 && c <= 0xdbff) \ ++ { \ ++ /* Four byte UTF-8 char. */ \ ++ uint16_t low, uvwxy; \ ++ \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ if (__glibc_unlikely (inptr + 4 > inend)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ inptr += 2; \ ++ low = get16 (inptr); \ ++ \ ++ if ((low & 0xfc00) != 0xdc00) \ ++ { \ ++ inptr -= 2; \ ++ STANDARD_TO_LOOP_ERR_HANDLER (2); \ ++ } \ ++ uvwxy = ((c >> 6) & 0xf) + 1; \ ++ outptr[0] = 0xf0; \ ++ outptr[0] |= uvwxy >> 2; \ ++ \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= (uvwxy << 4) & 0x30; \ ++ outptr[1] |= (c >> 2) & 0x0f; \ ++ \ ++ outptr[2] = 0x80; \ ++ outptr[2] |= (c & 0x03) << 4; \ ++ outptr[2] |= (low >> 6) & 0x0f; \ ++ \ ++ outptr[3] = 0x80; \ ++ outptr[3] |= low & 0x3f; \ ++ \ ++ outptr += 4; \ ++ } \ ++ else \ ++ { \ ++ STANDARD_TO_LOOP_ERR_HANDLER (2); \ ++ } \ ++ inptr += 2; \ ++ } ++ ++#define BODY_TO_VX \ ++ { \ ++ size_t inlen = inend - inptr; \ ++ size_t outlen = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for values <= 0x7f. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v30,%%v31,0(%[R_TMP])\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-16 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],32,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ ++ "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ ++ /* Check for > 1byte UTF-8 chars. */ \ ++ " vstrchs %%v19,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ " vstrchs %%v19,%%v17,%%v30,%%v31\n\t" \ ++ " jno 11f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Shorten to UTF-8. */ \ ++ " vpkh %%v18,%%v16,%%v17\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-32\n\t" \ ++ /* Store 16 bytes to buf_out. */ \ ++ " vst %%v18,0(%[R_OUT])\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],32,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ ++ " j 1b\n\t" \ ++ /* Setup to check for ch > 0x7f. (v30, v31) */ \ ++ "9: .short 0x7f,0x7f,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ " .short 0x2000,0x2000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ "11: lghi %[R_TMP2],16\n\t" /* match was found in v17. */ \ ++ "10:\n\t" \ ++ " vlgvb %[R_TMP],%%v19,7\n\t" \ ++ /* Shorten to UTF-8. */ \ ++ " vpkh %%v18,%%v16,%%v17\n\t" \ ++ " ar %[R_TMP],%[R_TMP2]\n\t" /* Number of in bytes. */ \ ++ " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ ++ " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ ++ " jl 13f\n\t" \ ++ " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ "13: \n\t" \ ++ /* Calculate remaining uint16_t values in loaded vrs. */ \ ++ " lghi %[R_TMP2],16\n\t" \ ++ " slgr %[R_TMP2],%[R_TMP3]\n\t" \ ++ " llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-2\n\t" \ ++ " j 22f\n\t" \ ++ /* Handle remaining bytes. */ \ ++ "2: \n\t" \ ++ /* Zero, one or more bytes available? */ \ ++ " clgfi %[R_INLEN],1\n\t" \ ++ " locghie %[R_RES],%[RES_IN_FULL]\n\t" /* Only one byte. */ \ ++ " jle 99f\n\t" /* End if less than two bytes. */ \ ++ /* Calculate remaining uint16_t values in inptr. */ \ ++ " srlg %[R_TMP2],%[R_INLEN],1\n\t" \ ++ /* Handle multibyte utf8-char. */ \ ++ "20: llh %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-2\n\t" \ ++ /* Test if ch is 1-byte UTF-8 char. */ \ ++ "21: clijh %[R_TMP],0x7f,22f\n\t" \ ++ /* Handle 1-byte UTF-8 char. */ \ ++ "31: slgfi %[R_OUTLEN],1\n\t" \ ++ " jl 90f \n\t" \ ++ " stc %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " la %[R_OUT],1(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 2-byte UTF-8 char. */ \ ++ "22: clfi %[R_TMP],0x7ff\n\t" \ ++ " jh 23f\n\t" \ ++ /* Handle 2-byte UTF-8 char. */ \ ++ "32: slgfi %[R_OUTLEN],2\n\t" \ ++ " jl 90f \n\t" \ ++ " llill %[R_TMP3],0xc080\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \ ++ " sth %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],2(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 3-byte UTF-8 char. */ \ ++ "23: clfi %[R_TMP],0xd7ff\n\t" \ ++ " jh 24f\n\t" \ ++ /* Handle 3-byte UTF-8 char. */ \ ++ "33: slgfi %[R_OUTLEN],3\n\t" \ ++ " jl 90f \n\t" \ ++ " llilf %[R_TMP3],0xe08080\n\t" \ ++ " la %[R_IN],2(%[R_IN])\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \ ++ " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],3(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 4-byte UTF-8 char. */ \ ++ "24: clfi %[R_TMP],0xdfff\n\t" \ ++ " jh 33b\n\t" /* Handle this 3-byte UTF-8 char. */ \ ++ " clfi %[R_TMP],0xdbff\n\t" \ ++ " locghih %[R_RES],%[RES_IN_ILL]\n\t" \ ++ " jh 99f\n\t" /* Jump away if this is a low surrogate \ ++ without a preceding high surrogate. */ \ ++ /* Handle 4-byte UTF-8 char. */ \ ++ "34: slgfi %[R_OUTLEN],4\n\t" \ ++ " jl 90f \n\t" \ ++ " slgfi %[R_INLEN],2\n\t" \ ++ " locghil %[R_RES],%[RES_IN_FULL]\n\t" \ ++ " jl 99f\n\t" /* Jump away if low surrogate is missing. */ \ ++ " llilf %[R_TMP3],0xf0808080\n\t" \ ++ " aghi %[R_TMP],0x40\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],37,39,16\n\t" /* 1. byte: uvw */ \ ++ " risbgn %[R_TMP3],%[R_TMP],42,43,14\n\t" /* 2. byte: xy */ \ ++ " risbgn %[R_TMP3],%[R_TMP],44,47,14\n\t" /* 2. byte: efgh */ \ ++ " risbgn %[R_TMP3],%[R_TMP],50,51,12\n\t" /* 3. byte: ij */ \ ++ " llh %[R_TMP],2(%[R_IN])\n\t" /* Load low surrogate. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],52,55,2\n\t" /* 3. byte: klmn */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte: opqrst */ \ ++ " nilf %[R_TMP],0xfc00\n\t" \ ++ " clfi %[R_TMP],0xdc00\n\t" /* Check if it starts with 0xdc00. */ \ ++ " locghine %[R_RES],%[RES_IN_ILL]\n\t" \ ++ " jne 99f\n\t" /* Jump away if low surrogate is invalid. */ \ ++ " st %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " aghi %[R_TMP2],-2\n\t" \ ++ " jh 20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Exit with __GCONV_FULL_OUTPUT. */ \ ++ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ ++ "99: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ if (__glibc_likely (inptr == inend) \ ++ || result != __GCONV_ILLEGAL_INPUT) \ ++ break; \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (2); \ ++ } ++ ++/* Generate loop-function with software implementation. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MAX_NEEDED_INPUT MAX_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#if defined HAVE_S390_VX_ASM_SUPPORT ++# define LOOPFCT __to_utf8_loop_c ++# define BODY BODY_TO_C ++# define LOOP_NEED_FLAGS ++# include ++ ++/* Generate loop-function with software implementation. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MAX_NEEDED_INPUT MAX_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define LOOPFCT __to_utf8_loop_vx ++# define BODY BODY_TO_VX ++# define LOOP_NEED_FLAGS ++# include ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__to_utf8_loop_c) ++__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) ++__to_utf8_loop; ++ ++static void * ++__to_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __to_utf8_loop_vx; ++ else ++ return __to_utf8_loop_c; ++} ++ ++strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) ++ ++#else ++# define LOOPFCT TO_LOOP ++# define BODY BODY_TO_C ++# define LOOP_NEED_FLAGS ++# include ++#endif /* !HAVE_S390_VX_ASM_SUPPORT */ ++ ++#include +diff --git a/sysdeps/s390/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c +new file mode 100644 +index 0000000..e39e0a7 +--- /dev/null ++++ b/sysdeps/s390/utf8-utf32-z9.c +@@ -0,0 +1,820 @@ ++/* Conversion between UTF-8 and UTF-32 BE/internal. ++ ++ This module uses the Z9-109 variants of the Convert Unicode ++ instructions. ++ Copyright (C) 1997-2016 Free Software Foundation, Inc. ++ ++ Author: Andreas Krebbel ++ Based on the work by Ulrich Drepper , 1997. ++ ++ Thanks to Daniel Appich who covered the relevant performance work ++ in his diploma thesis. ++ ++ This is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++#else ++# define ASM_CLOBBER_VR(NR) ++#endif ++ ++#if defined __s390x__ ++# define CONVERT_32BIT_SIZE_T(REG) ++#else ++# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" ++#endif ++ ++/* Defines for skeleton.c. */ ++#define DEFINE_INIT 0 ++#define DEFINE_FINI 0 ++#define MIN_NEEDED_FROM 1 ++#define MAX_NEEDED_FROM 6 ++#define MIN_NEEDED_TO 4 ++#define FROM_LOOP __from_utf8_loop ++#define TO_LOOP __to_utf8_loop ++#define FROM_DIRECTION (dir == from_utf8) ++#define ONE_DIRECTION 0 ++ ++/* UTF-32 big endian byte order mark. */ ++#define BOM 0x0000feffu ++ ++/* Direction of the transformation. */ ++enum direction ++{ ++ illegal_dir, ++ to_utf8, ++ from_utf8 ++}; ++ ++struct utf8_data ++{ ++ enum direction dir; ++ int emit_bom; ++}; ++ ++ ++extern int gconv_init (struct __gconv_step *step); ++int ++gconv_init (struct __gconv_step *step) ++{ ++ /* Determine which direction. */ ++ struct utf8_data *new_data; ++ enum direction dir = illegal_dir; ++ int emit_bom; ++ int result; ++ ++ emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0); ++ ++ if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 ++ && (__strcasecmp (step->__to_name, "UTF-32//") == 0 ++ || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 ++ || __strcasecmp (step->__to_name, "INTERNAL") == 0)) ++ { ++ dir = from_utf8; ++ } ++ else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0 ++ && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 ++ || __strcasecmp (step->__from_name, "INTERNAL") == 0)) ++ { ++ dir = to_utf8; ++ } ++ ++ result = __GCONV_NOCONV; ++ if (dir != illegal_dir) ++ { ++ new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); ++ ++ result = __GCONV_NOMEM; ++ if (new_data != NULL) ++ { ++ new_data->dir = dir; ++ new_data->emit_bom = emit_bom; ++ step->__data = new_data; ++ ++ if (dir == from_utf8) ++ { ++ step->__min_needed_from = MIN_NEEDED_FROM; ++ step->__max_needed_from = MIN_NEEDED_FROM; ++ step->__min_needed_to = MIN_NEEDED_TO; ++ step->__max_needed_to = MIN_NEEDED_TO; ++ } ++ else ++ { ++ step->__min_needed_from = MIN_NEEDED_TO; ++ step->__max_needed_from = MIN_NEEDED_TO; ++ step->__min_needed_to = MIN_NEEDED_FROM; ++ step->__max_needed_to = MIN_NEEDED_FROM; ++ } ++ ++ step->__stateful = 0; ++ ++ result = __GCONV_OK; ++ } ++ } ++ ++ return result; ++} ++ ++ ++extern void gconv_end (struct __gconv_step *data); ++void ++gconv_end (struct __gconv_step *data) ++{ ++ free (data->__data); ++} ++ ++/* The macro for the hardware loop. This is used for both ++ directions. */ ++#define HARDWARE_CONVERT(INSTRUCTION) \ ++ { \ ++ register const unsigned char* pInput __asm__ ("8") = inptr; \ ++ register size_t inlen __asm__ ("9") = inend - inptr; \ ++ register unsigned char* pOutput __asm__ ("10") = outptr; \ ++ register size_t outlen __asm__("11") = outend - outptr; \ ++ unsigned long cc = 0; \ ++ \ ++ __asm__ __volatile__ (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ ++ \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ cc >>= 28; \ ++ \ ++ if (cc == 1) \ ++ { \ ++ result = __GCONV_FULL_OUTPUT; \ ++ } \ ++ else if (cc == 2) \ ++ { \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ } \ ++ } ++ ++#define PREPARE_LOOP \ ++ enum direction dir = ((struct utf8_data *) step->__data)->dir; \ ++ int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ ++ \ ++ if (emit_bom && !data->__internal_use \ ++ && data->__invocation_counter == 0) \ ++ { \ ++ /* Emit the Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 4 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put32u (outbuf, BOM); \ ++ outbuf += 4; \ ++ } ++ ++/* Conversion function from UTF-8 to UTF-32 internal/BE. */ ++ ++#define STORE_REST_COMMON \ ++ { \ ++ /* We store the remaining bytes while converting them into the UCS4 \ ++ format. We can assume that the first byte in the buffer is \ ++ correct and that it requires a larger number of bytes than there \ ++ are in the input buffer. */ \ ++ wint_t ch = **inptrp; \ ++ size_t cnt, r; \ ++ \ ++ state->__count = inend - *inptrp; \ ++ \ ++ assert (ch != 0xc0 && ch != 0xc1); \ ++ if (ch >= 0xc2 && ch < 0xe0) \ ++ { \ ++ /* We expect two bytes. The first byte cannot be 0xc0 or \ ++ 0xc1, otherwise the wide character could have been \ ++ represented using a single byte. */ \ ++ cnt = 2; \ ++ ch &= 0x1f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ ++ { \ ++ /* We expect three bytes. */ \ ++ cnt = 3; \ ++ ch &= 0x0f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ ++ { \ ++ /* We expect four bytes. */ \ ++ cnt = 4; \ ++ ch &= 0x07; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ ++ { \ ++ /* We expect five bytes. */ \ ++ cnt = 5; \ ++ ch &= 0x03; \ ++ } \ ++ else \ ++ { \ ++ /* We expect six bytes. */ \ ++ cnt = 6; \ ++ ch &= 0x01; \ ++ } \ ++ \ ++ /* The first byte is already consumed. */ \ ++ r = cnt - 1; \ ++ while (++(*inptrp) < inend) \ ++ { \ ++ ch <<= 6; \ ++ ch |= **inptrp & 0x3f; \ ++ --r; \ ++ } \ ++ \ ++ /* Shift for the so far missing bytes. */ \ ++ ch <<= r * 6; \ ++ \ ++ /* Store the number of bytes expected for the entire sequence. */ \ ++ state->__count |= cnt << 8; \ ++ \ ++ /* Store the value. */ \ ++ state->__value.__wch = ch; \ ++ } ++ ++#define UNPACK_BYTES_COMMON \ ++ { \ ++ static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \ ++ wint_t wch = state->__value.__wch; \ ++ size_t ntotal = state->__count >> 8; \ ++ \ ++ inlen = state->__count & 255; \ ++ \ ++ bytebuf[0] = inmask[ntotal - 2]; \ ++ \ ++ do \ ++ { \ ++ if (--ntotal < inlen) \ ++ bytebuf[ntotal] = 0x80 | (wch & 0x3f); \ ++ wch >>= 6; \ ++ } \ ++ while (ntotal > 1); \ ++ \ ++ bytebuf[0] |= wch; \ ++ } ++ ++#define CLEAR_STATE_COMMON \ ++ state->__count = 0 ++ ++#define BODY_FROM_HW(ASM) \ ++ { \ ++ ASM; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ \ ++ int i; \ ++ for (i = 1; inptr + i < inend && i < 5; ++i) \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ break; \ ++ \ ++ if (__glibc_likely (inptr + i == inend \ ++ && result == __GCONV_EMPTY_INPUT)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (i); \ ++ } ++ ++/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */ ++#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1")) ++ ++ ++/* The software routine is copied from gconv_simple.c. */ ++#define BODY_FROM_C \ ++ { \ ++ /* Next input byte. */ \ ++ uint32_t ch = *inptr; \ ++ \ ++ if (__glibc_likely (ch < 0x80)) \ ++ { \ ++ /* One byte sequence. */ \ ++ ++inptr; \ ++ } \ ++ else \ ++ { \ ++ uint_fast32_t cnt; \ ++ uint_fast32_t i; \ ++ \ ++ if (ch >= 0xc2 && ch < 0xe0) \ ++ { \ ++ /* We expect two bytes. The first byte cannot be 0xc0 or \ ++ 0xc1, otherwise the wide character could have been \ ++ represented using a single byte. */ \ ++ cnt = 2; \ ++ ch &= 0x1f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ ++ { \ ++ /* We expect three bytes. */ \ ++ cnt = 3; \ ++ ch &= 0x0f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ ++ { \ ++ /* We expect four bytes. */ \ ++ cnt = 4; \ ++ ch &= 0x07; \ ++ } \ ++ else \ ++ { \ ++ /* Search the end of this ill-formed UTF-8 character. This \ ++ is the next byte with (x & 0xc0) != 0x80. */ \ ++ i = 0; \ ++ do \ ++ ++i; \ ++ while (inptr + i < inend \ ++ && (*(inptr + i) & 0xc0) == 0x80 \ ++ && i < 5); \ ++ \ ++ errout: \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (i); \ ++ } \ ++ \ ++ if (__glibc_unlikely (inptr + cnt > inend)) \ ++ { \ ++ /* We don't have enough input. But before we report \ ++ that check that all the bytes are correct. */ \ ++ for (i = 1; inptr + i < inend; ++i) \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ break; \ ++ \ ++ if (__glibc_likely (inptr + i == inend)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ \ ++ goto errout; \ ++ } \ ++ \ ++ /* Read the possible remaining bytes. */ \ ++ for (i = 1; i < cnt; ++i) \ ++ { \ ++ uint32_t byte = inptr[i]; \ ++ \ ++ if ((byte & 0xc0) != 0x80) \ ++ /* This is an illegal encoding. */ \ ++ break; \ ++ \ ++ ch <<= 6; \ ++ ch |= byte & 0x3f; \ ++ } \ ++ \ ++ /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ ++ If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ ++ have been represented with fewer than cnt bytes. */ \ ++ if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ ++ /* Do not accept UTF-16 surrogates. */ \ ++ || (ch >= 0xd800 && ch <= 0xdfff) \ ++ || (ch > 0x10ffff)) \ ++ { \ ++ /* This is an illegal encoding. */ \ ++ goto errout; \ ++ } \ ++ \ ++ inptr += cnt; \ ++ } \ ++ \ ++ /* Now adjust the pointers and store the result. */ \ ++ *((uint32_t *) outptr) = ch; \ ++ outptr += sizeof (uint32_t); \ ++ } ++ ++#define HW_FROM_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ ++ " vrepib %%v31,0x20\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-8 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],64,20f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Enlarge to UCS4. */ \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vuplhh %%v20,%%v18\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ " vupllh %%v21,%%v18\n\t" \ ++ " aghi %[R_OUTLEN],-64\n\t" \ ++ " vuplhh %%v22,%%v19\n\t" \ ++ " vupllh %%v23,%%v19\n\t" \ ++ /* Store 64 bytes to buf_out. */ \ ++ " vstm %%v20,%%v23,0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],64(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],64,20f\n\t" \ ++ " j 1b\n\t" \ ++ "10: \n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ " vlgvb %[R_TMP],%%v17,7\n\t" \ ++ " sllk %[R_TMP2],%[R_TMP],2\n\t" /* Compute highest \ ++ index to store. */ \ ++ " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ ++ " ahi %[R_TMP2],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " vuplhh %%v20,%%v18\n\t" \ ++ " vstl %%v20,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v21,%%v18\n\t" \ ++ " vstl %%v21,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " vuplhh %%v22,%%v19\n\t" \ ++ " vstl %%v22,%[R_TMP2],32(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v23,%%v19\n\t" \ ++ " vstl %%v23,%[R_TMP2],48(%[R_OUT])\n\t" \ ++ "11: \n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu14 %[R_OUT],%[R_IN],1\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \ ++ ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ } ++#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) ++ ++/* These definitions apply to the UTF-8 to UTF-32 direction. The ++ software implementation for UTF-8 still supports multibyte ++ characters up to 6 bytes whereas the hardware variant does not. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_c ++ ++#define LOOP_NEED_FLAGS ++ ++#define STORE_REST STORE_REST_COMMON ++#define UNPACK_BYTES UNPACK_BYTES_COMMON ++#define CLEAR_STATE CLEAR_STATE_COMMON ++#define BODY BODY_FROM_C ++#include ++ ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_etf3eh ++ ++#define LOOP_NEED_FLAGS ++ ++#define STORE_REST STORE_REST_COMMON ++#define UNPACK_BYTES UNPACK_BYTES_COMMON ++#define CLEAR_STATE CLEAR_STATE_COMMON ++#define BODY BODY_FROM_ETF3EH ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT __from_utf8_loop_vx ++ ++# define LOOP_NEED_FLAGS ++ ++# define STORE_REST STORE_REST_COMMON ++# define UNPACK_BYTES UNPACK_BYTES_COMMON ++# define CLEAR_STATE CLEAR_STATE_COMMON ++# define BODY BODY_FROM_VX ++# include ++#endif ++ ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_utf8_loop_c) ++__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) ++__from_utf8_loop; ++ ++static void * ++__from_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __from_utf8_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS ++ && dl_hwcap & HWCAP_S390_ETF3EH) ++ return __from_utf8_loop_etf3eh; ++ else ++ return __from_utf8_loop_c; ++} ++ ++strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) ++ ++ ++/* Conversion from UTF-32 internal/BE to UTF-8. */ ++#define BODY_TO_HW(ASM) \ ++ { \ ++ ASM; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++/* The hardware routine uses the S/390 cu41 instruction. */ ++#define BODY_TO_ETF3EH BODY_TO_HW (HARDWARE_CONVERT ("cu41 %0, %1")) ++ ++/* The hardware routine uses the S/390 vector and cu41 instructions. */ ++#define BODY_TO_VX BODY_TO_HW (HW_TO_VX) ++ ++/* The software routine mimics the S/390 cu41 instruction. */ ++#define BODY_TO_C \ ++ { \ ++ uint32_t wc = *((const uint32_t *) inptr); \ ++ \ ++ if (__glibc_likely (wc <= 0x7f)) \ ++ { \ ++ /* Single UTF-8 char. */ \ ++ *outptr = (uint8_t)wc; \ ++ outptr++; \ ++ } \ ++ else if (wc <= 0x7ff) \ ++ { \ ++ /* Two UTF-8 chars. */ \ ++ if (__glibc_unlikely (outptr + 2 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ \ ++ outptr[0] = 0xc0; \ ++ outptr[0] |= wc >> 6; \ ++ \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= wc & 0x3f; \ ++ \ ++ outptr += 2; \ ++ } \ ++ else if (wc <= 0xffff) \ ++ { \ ++ /* Three UTF-8 chars. */ \ ++ if (__glibc_unlikely (outptr + 3 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ if (wc >= 0xd800 && wc < 0xdc00) \ ++ { \ ++ /* Do not accept UTF-16 surrogates. */ \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ outptr[0] = 0xe0; \ ++ outptr[0] |= wc >> 12; \ ++ \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= (wc >> 6) & 0x3f; \ ++ \ ++ outptr[2] = 0x80; \ ++ outptr[2] |= wc & 0x3f; \ ++ \ ++ outptr += 3; \ ++ } \ ++ else if (wc <= 0x10ffff) \ ++ { \ ++ /* Four UTF-8 chars. */ \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ ++ { \ ++ /* Overflow in the output buffer. */ \ ++ result = __GCONV_FULL_OUTPUT; \ ++ break; \ ++ } \ ++ outptr[0] = 0xf0; \ ++ outptr[0] |= wc >> 18; \ ++ \ ++ outptr[1] = 0x80; \ ++ outptr[1] |= (wc >> 12) & 0x3f; \ ++ \ ++ outptr[2] = 0x80; \ ++ outptr[2] |= (wc >> 6) & 0x3f; \ ++ \ ++ outptr[3] = 0x80; \ ++ outptr[3] |= wc & 0x3f; \ ++ \ ++ outptr += 4; \ ++ } \ ++ else \ ++ { \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ inptr += 4; \ ++ } ++ ++#define HW_TO_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ ++ " vzero %%v21\n\t" \ ++ " vleih %%v21,8192,0\n\t" /* element 0: > */ \ ++ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ ++ CONVERT_32BIT_SIZE_T ([R_INLEN]) \ ++ CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ ++ /* Loop which handles UTF-32 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],64,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP],0\n\t" \ ++ /* Shorten to byte values. */ \ ++ " vpkf %%v23,%%v16,%%v17\n\t" \ ++ " vpkf %%v24,%%v18,%%v19\n\t" \ ++ " vpkh %%v23,%%v23,%%v24\n\t" \ ++ /* Checking for values > 0x7f. */ \ ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ ++ " jno 12f\n\t" \ ++ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ ++ " jno 13f\n\t" \ ++ /* Store 16bytes to outptr. */ \ ++ " vst %%v23,0(%[R_OUT])\n\t" \ ++ " aghi %[R_INLEN],-64\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_IN],64(%[R_IN])\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],64,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Found a value > 0x7f. */ \ ++ "13: ahi %[R_TMP],4\n\t" \ ++ "12: ahi %[R_TMP],4\n\t" \ ++ "11: ahi %[R_TMP],4\n\t" \ ++ "10: vlgvb %[R_I],%%v22,7\n\t" \ ++ " srlg %[R_I],%[R_I],2\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ " je 20f\n\t" \ ++ /* Store characters before invalid one... */ \ ++ " slgr %[R_OUTLEN],%[R_I]\n\t" \ ++ "15: aghi %[R_I],-1\n\t" \ ++ " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ ++ /* ... and update pointers. */ \ ++ " aghi %[R_I],1\n\t" \ ++ " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ ++ " sllg %[R_I],%[R_I],2\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_I]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu41 %[R_OUT],%[R_IN]\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \ ++ , [R_I] "=a" (tmp2) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ ++ ASM_CLOBBER_VR ("v24") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ } ++ ++/* Generate loop-function with software routing. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf8_loop_c ++#define BODY BODY_TO_C ++#define LOOP_NEED_FLAGS ++#include ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf8_loop_etf3eh ++#define LOOP_NEED_FLAGS ++#define BODY BODY_TO_ETF3EH ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define LOOPFCT __to_utf8_loop_vx ++# define BODY BODY_TO_VX ++# define LOOP_NEED_FLAGS ++# include ++#endif ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__to_utf8_loop_c) ++__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) ++__to_utf8_loop; ++ ++static void * ++__to_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __to_utf8_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS ++ && dl_hwcap & HWCAP_S390_ETF3EH) ++ return __to_utf8_loop_etf3eh; ++ else ++ return __to_utf8_loop_c; ++} ++ ++strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) ++ ++ ++#include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-14.patch b/SOURCES/glibc-rh1380680-14.patch new file mode 100644 index 00000000..e462c16d --- /dev/null +++ b/SOURCES/glibc-rh1380680-14.patch @@ -0,0 +1,287 @@ +From 1ae5597025b342ee8fec59e04970b44fc1361744 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 17:17:51 +0100 +Subject: [PATCH 14/17] S390: Fix utf32 to utf8 handling of low surrogates + (disable cu41). + +Upstream commit 52f8a48e24563daa807f94824ce9782b9a9eece9 + +According to the latest Unicode standard, a conversion from/to UTF-xx has +to report an error if the character value is in range of an utf16 surrogate +(0xd800..0xdfff). See https://sourceware.org/ml/libc-help/2015-12/msg00015.html. + +Thus the cu41 instruction, which converts from utf32 to utf8, has to be +disabled because it does not report an error in case of a value in range of +a low surrogate (0xdc00..0xdfff). The etf3eh variant is removed and the c, +vector variant is adjusted to handle the value in range of an utf16 low +surrogate correctly. + +ChangeLog: + + * sysdeps/s390/utf8-utf32-z9.c: Disable cu41 instruction and report + an error in case of a value in range of an utf16 low surrogate. +--- + sysdeps/s390/utf8-utf32-z9.c | 188 ++++++++++++++++++++++++++----------------- + 1 file changed, 115 insertions(+), 73 deletions(-) + +diff --git a/sysdeps/s390/utf8-utf32-z9.c b/sysdeps/s390/utf8-utf32-z9.c +index e39e0a7..efae745 100644 +--- a/sysdeps/s390/utf8-utf32-z9.c ++++ b/sysdeps/s390/utf8-utf32-z9.c +@@ -572,28 +572,6 @@ __from_utf8_loop_resolver (unsigned long int dl_hwcap) + + strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + +- +-/* Conversion from UTF-32 internal/BE to UTF-8. */ +-#define BODY_TO_HW(ASM) \ +- { \ +- ASM; \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- if (inptr + 4 > inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } +- +-/* The hardware routine uses the S/390 cu41 instruction. */ +-#define BODY_TO_ETF3EH BODY_TO_HW (HARDWARE_CONVERT ("cu41 %0, %1")) +- +-/* The hardware routine uses the S/390 vector and cu41 instructions. */ +-#define BODY_TO_VX BODY_TO_HW (HW_TO_VX) +- + /* The software routine mimics the S/390 cu41 instruction. */ + #define BODY_TO_C \ + { \ +@@ -632,7 +610,7 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ +- if (wc >= 0xd800 && wc < 0xdc00) \ ++ if (wc >= 0xd800 && wc <= 0xdfff) \ + { \ + /* Do not accept UTF-16 surrogates. */ \ + result = __GCONV_ILLEGAL_INPUT; \ +@@ -679,13 +657,12 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + inptr += 4; \ + } + +-#define HW_TO_VX \ ++/* The hardware routine uses the S/390 vector instructions. */ ++#define BODY_TO_VX \ + { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register size_t inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register size_t outlen asm("11") = outend - outptr; \ +- unsigned long tmp, tmp2; \ ++ size_t inlen = inend - inptr; \ ++ size_t outlen = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ + ".machinemode \"zarch_nohighgprs\"\n\t" \ +@@ -696,10 +673,10 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + CONVERT_32BIT_SIZE_T ([R_INLEN]) \ + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-32 chars <=0x7f. */ \ +- "0: clgijl %[R_INLEN],64,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "0: clgijl %[R_INLEN],64,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ + "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ +- " lghi %[R_TMP],0\n\t" \ ++ " lghi %[R_TMP2],0\n\t" \ + /* Shorten to byte values. */ \ + " vpkf %%v23,%%v16,%%v17\n\t" \ + " vpkf %%v24,%%v18,%%v19\n\t" \ +@@ -719,41 +696,116 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_IN],64(%[R_IN])\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],64,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " clgijl %[R_INLEN],64,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ + " j 1b\n\t" \ + /* Found a value > 0x7f. */ \ +- "13: ahi %[R_TMP],4\n\t" \ +- "12: ahi %[R_TMP],4\n\t" \ +- "11: ahi %[R_TMP],4\n\t" \ +- "10: vlgvb %[R_I],%%v22,7\n\t" \ +- " srlg %[R_I],%[R_I],2\n\t" \ +- " agr %[R_I],%[R_TMP]\n\t" \ +- " je 20f\n\t" \ ++ "13: ahi %[R_TMP2],4\n\t" \ ++ "12: ahi %[R_TMP2],4\n\t" \ ++ "11: ahi %[R_TMP2],4\n\t" \ ++ "10: vlgvb %[R_TMP],%%v22,7\n\t" \ ++ " srlg %[R_TMP],%[R_TMP],2\n\t" \ ++ " agr %[R_TMP],%[R_TMP2]\n\t" \ ++ " je 16f\n\t" \ + /* Store characters before invalid one... */ \ +- " slgr %[R_OUTLEN],%[R_I]\n\t" \ +- "15: aghi %[R_I],-1\n\t" \ +- " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP]\n\t" \ ++ "15: aghi %[R_TMP],-1\n\t" \ ++ " vstl %%v23,%[R_TMP],0(%[R_OUT])\n\t" \ + /* ... and update pointers. */ \ +- " aghi %[R_I],1\n\t" \ +- " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ +- " sllg %[R_I],%[R_I],2\n\t" \ +- " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ +- " slgr %[R_INLEN],%[R_I]\n\t" \ +- /* Handle multibyte utf8-char with convert instruction. */ \ +- "20: cu41 %[R_OUT],%[R_IN]\n\t" \ +- " jo 0b\n\t" /* Try vector implemenation again. */ \ +- " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ +- " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ " aghi %[R_TMP],1\n\t" \ ++ " la %[R_OUT],0(%[R_TMP],%[R_OUT])\n\t" \ ++ " sllg %[R_TMP2],%[R_TMP],2\n\t" \ ++ " la %[R_IN],0(%[R_TMP2],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP2]\n\t" \ ++ /* Calculate remaining uint32_t values in loaded vrs. */ \ ++ "16: lghi %[R_TMP2],16\n\t" \ ++ " sgr %[R_TMP2],%[R_TMP]\n\t" \ ++ " l %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-4\n\t" \ ++ " j 22f\n\t" \ ++ /* Handle remaining bytes. */ \ ++ "2: clgije %[R_INLEN],0,99f\n\t" \ ++ " clgijl %[R_INLEN],4,92f\n\t" \ ++ /* Calculate remaining uint32_t values in inptr. */ \ ++ " srlg %[R_TMP2],%[R_INLEN],2\n\t" \ ++ /* Handle multibyte utf8-char. */ \ ++ "20: l %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-4\n\t" \ ++ /* Test if ch is 1byte UTF-8 char. */ \ ++ "21: clijh %[R_TMP],0x7f,22f\n\t" \ ++ /* Handle 1-byte UTF-8 char. */ \ ++ "31: slgfi %[R_OUTLEN],1\n\t" \ ++ " jl 90f \n\t" \ ++ " stc %[R_TMP],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],1(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 2byte UTF-8 char. */ \ ++ "22: clfi %[R_TMP],0x7ff\n\t" \ ++ " jh 23f\n\t" \ ++ /* Handle 2-byte UTF-8 char. */ \ ++ "32: slgfi %[R_OUTLEN],2\n\t" \ ++ " jl 90f \n\t" \ ++ " llill %[R_TMP3],0xc080\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],51,55,2\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 2. byte. */ \ ++ " sth %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],2(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 3-byte UTF-8 char. */ \ ++ "23: clfi %[R_TMP],0xffff\n\t" \ ++ " jh 24f\n\t" \ ++ /* Handle 3-byte UTF-8 char. */ \ ++ "33: slgfi %[R_OUTLEN],3\n\t" \ ++ " jl 90f \n\t" \ ++ " llilf %[R_TMP3],0xe08080\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],44,47,4\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 2. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 3. byte. */ \ ++ /* Test if ch is a UTF-16 surrogate: ch & 0xf800 == 0xd800 */ \ ++ " nilf %[R_TMP],0xf800\n\t" \ ++ " clfi %[R_TMP],0xd800\n\t" \ ++ " je 91f\n\t" /* Do not accept UTF-16 surrogates. */ \ ++ " stcm %[R_TMP3],7,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],3(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 4-byte UTF-8 char. */ \ ++ "24: clfi %[R_TMP],0x10ffff\n\t" \ ++ " jh 91f\n\t" /* ch > 0x10ffff is not allowed! */ \ ++ /* Handle 4-byte UTF-8 char. */ \ ++ "34: slgfi %[R_OUTLEN],4\n\t" \ ++ " jl 90f \n\t" \ ++ " llilf %[R_TMP3],0xf0808080\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],37,39,6\n\t" /* 1. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],42,47,4\n\t" /* 2. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],50,55,2\n\t" /* 3. byte. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],58,63,0\n\t" /* 4. byte. */ \ ++ " st %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ "92: lghi %[R_RES],%[RES_IN_FULL]\n\t" \ ++ " j 99f\n\t" \ ++ "91: lghi %[R_RES],%[RES_IN_ILL]\n\t" \ ++ " j 99f\n\t" \ ++ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ ++ "99: \n\t" \ + ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (pInput) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ +- , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \ +- , [R_I] "=a" (tmp2) \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=a" (tmp2), [R_TMP3] "=d" (tmp3) \ + , [R_RES] "+d" (result) \ + : /* inputs */ \ + [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ + , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ , [RES_IN_FULL] "i" (__GCONV_INCOMPLETE_INPUT) \ + : /* clobber list */ "memory", "cc" \ + ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ +@@ -761,8 +813,11 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ + ASM_CLOBBER_VR ("v24") \ + ); \ +- inptr = pInput; \ +- outptr = pOutput; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result != __GCONV_ILLEGAL_INPUT) \ ++ break; \ ++ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + + /* Generate loop-function with software routing. */ +@@ -774,15 +829,6 @@ strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) + #define LOOP_NEED_FLAGS + #include + +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf8_loop_etf3eh +-#define LOOP_NEED_FLAGS +-#define BODY BODY_TO_ETF3EH +-#include +- + #if defined HAVE_S390_VX_ASM_SUPPORT + /* Generate loop-function with hardware vector and utf-convert instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_TO +@@ -807,10 +853,6 @@ __to_utf8_loop_resolver (unsigned long int dl_hwcap) + return __to_utf8_loop_vx; + else + #endif +- if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS +- && dl_hwcap & HWCAP_S390_ETF3EH) +- return __to_utf8_loop_etf3eh; +- else + return __to_utf8_loop_c; + } + +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-15.patch b/SOURCES/glibc-rh1380680-15.patch new file mode 100644 index 00000000..8574c5b6 --- /dev/null +++ b/SOURCES/glibc-rh1380680-15.patch @@ -0,0 +1,269 @@ +From cddea07761373ce92dc75e8306212d71fa2043ba Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 17:18:39 +0100 +Subject: [PATCH 15/17] S390: Fix utf32 to utf16 handling of low surrogates + (disable cu42). + +Upstream commit a42a95c43133d69b1108f582cffa0f6986a9c3da + +According to the latest Unicode standard, a conversion from/to UTF-xx has +to report an error if the character value is in range of an utf16 surrogate +(0xd800..0xdfff). See https://sourceware.org/ml/libc-help/2015-12/msg00015.html. + +Thus the cu42 instruction, which converts from utf32 to utf16, has to be +disabled because it does not report an error in case of a value in range of +a low surrogate (0xdc00..0xdfff). The etf3eh variant is removed and the c, +vector variant is adjusted to handle the value in range of an utf16 low +surrogate correctly. + +ChangeLog: + + * sysdeps/s390/utf16-utf32-z9.c: Disable cu42 instruction and report + an error in case of a value in range of an utf16 low surrogate. +--- + sysdeps/s390/utf16-utf32-z9.c | 155 +++++++++++++++++------------------------- + 1 file changed, 62 insertions(+), 93 deletions(-) + +diff --git a/sysdeps/s390/utf16-utf32-z9.c b/sysdeps/s390/utf16-utf32-z9.c +index 8d42ab8..5d2ac44 100644 +--- a/sysdeps/s390/utf16-utf32-z9.c ++++ b/sysdeps/s390/utf16-utf32-z9.c +@@ -145,42 +145,6 @@ gconv_end (struct __gconv_step *data) + free (data->__data); + } + +-/* The macro for the hardware loop. This is used for both +- directions. */ +-#define HARDWARE_CONVERT(INSTRUCTION) \ +- { \ +- register const unsigned char* pInput __asm__ ("8") = inptr; \ +- register size_t inlen __asm__ ("9") = inend - inptr; \ +- register unsigned char* pOutput __asm__ ("10") = outptr; \ +- register size_t outlen __asm__("11") = outend - outptr; \ +- unsigned long cc = 0; \ +- \ +- __asm__ __volatile__ (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- ".machinemode \"zarch_nohighgprs\"\n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ +- \ +- inptr = pInput; \ +- outptr = pOutput; \ +- cc >>= 28; \ +- \ +- if (cc == 1) \ +- { \ +- result = __GCONV_FULL_OUTPUT; \ +- } \ +- else if (cc == 2) \ +- { \ +- result = __GCONV_ILLEGAL_INPUT; \ +- } \ +- } +- + #define PREPARE_LOOP \ + enum direction dir = ((struct utf16_data *) step->__data)->dir; \ + int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ +@@ -310,7 +274,7 @@ gconv_end (struct __gconv_step *data) + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ + /* Calculate remaining uint16_t values in loaded vrs. */ \ + "12: lghi %[R_TMP2],16\n\t" \ +- " sgr %[R_TMP2],%[R_TMP]\n\t" \ ++ " slgr %[R_TMP2],%[R_TMP]\n\t" \ + " srl %[R_TMP2],1\n\t" \ + " llh %[R_TMP],0(%[R_IN])\n\t" \ + " aghi %[R_OUTLEN],-4\n\t" \ +@@ -437,7 +401,7 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + uint32_t c = get32 (inptr); \ + \ + if (__builtin_expect (c <= 0xd7ff, 1) \ +- || (c >=0xdc00 && c <= 0xffff)) \ ++ || (c > 0xdfff && c <= 0xffff)) \ + { \ + /* Two UTF-16 chars. */ \ + put16 (outptr, c); \ +@@ -475,29 +439,10 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + inptr += 4; \ + } + +-#define BODY_TO_ETF3EH \ +- { \ +- HARDWARE_CONVERT ("cu42 %0, %1"); \ +- \ +- if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ +- break; \ +- \ +- if (inptr + 4 > inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- \ +- STANDARD_TO_LOOP_ERR_HANDLER (4); \ +- } +- + #define BODY_TO_VX \ + { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register size_t inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register size_t outlen asm("11") = outend - outptr; \ ++ size_t inlen = inend - inptr; \ ++ size_t outlen = outend - outptr; \ + unsigned long tmp, tmp2, tmp3; \ + asm volatile (".machine push\n\t" \ + ".machine \"z13\"\n\t" \ +@@ -509,8 +454,8 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + CONVERT_32BIT_SIZE_T ([R_OUTLEN]) \ + /* Loop which handles UTF-16 chars \ + ch < 0xd800 || (ch > 0xdfff && ch < 0x10000). */ \ +- "0: clgijl %[R_INLEN],32,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "0: clgijl %[R_INLEN],32,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ + "1: vlm %%v16,%%v17,0(%[R_IN])\n\t" \ + " lghi %[R_TMP2],0\n\t" \ + /* Shorten to UTF-16. */ \ +@@ -526,9 +471,15 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + " aghi %[R_INLEN],-32\n\t" \ + " aghi %[R_OUTLEN],-16\n\t" \ + " la %[R_OUT],16(%[R_OUT])\n\t" \ +- " clgijl %[R_INLEN],32,20f\n\t" \ +- " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " clgijl %[R_INLEN],32,2f\n\t" \ ++ " clgijl %[R_OUTLEN],16,2f\n\t" \ + " j 1b\n\t" \ ++ /* Calculate remaining uint32_t values in inptr. */ \ ++ "2: \n\t" \ ++ " clgije %[R_INLEN],0,99f\n\t" \ ++ " clgijl %[R_INLEN],4,92f\n\t" \ ++ " srlg %[R_TMP2],%[R_INLEN],2\n\t" \ ++ " j 20f\n\t" \ + /* Setup to check for ch >= 0xd800 && ch <= 0xdfff \ + and check for ch >= 0x10000. (v30, v31) */ \ + "9: .long 0xd800,0xdfff,0x10000,0x10000\n\t" \ +@@ -540,21 +491,59 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + " agr %[R_TMP],%[R_TMP2]\n\t" \ + " srlg %[R_TMP3],%[R_TMP],1\n\t" /* Number of out bytes. */ \ + " ahik %[R_TMP2],%[R_TMP3],-1\n\t" /* Highest index to store. */ \ +- " jl 20f\n\t" \ ++ " jl 12f\n\t" \ + " vstl %%v18,%[R_TMP2],0(%[R_OUT])\n\t" \ + /* Update pointers. */ \ + " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ + " slgr %[R_INLEN],%[R_TMP]\n\t" \ + " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ + " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ +- /* Handles UTF16 surrogates with convert instruction. */ \ +- "20: cu42 %[R_OUT],%[R_IN]\n\t" \ +- " jo 0b\n\t" /* Try vector implemenation again. */ \ +- " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ +- " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ /* Calculate remaining uint32_t values in vrs. */ \ ++ "12: lghi %[R_TMP2],8\n\t" \ ++ " srlg %[R_TMP3],%[R_TMP3],1\n\t" \ ++ " slgr %[R_TMP2],%[R_TMP3]\n\t" \ ++ /* Handle remaining UTF-32 characters. */ \ ++ "20: l %[R_TMP],0(%[R_IN])\n\t" \ ++ " aghi %[R_INLEN],-4\n\t" \ ++ /* Test if ch is 2byte UTF-16 char. */ \ ++ " clfi %[R_TMP],0xffff\n\t" \ ++ " jh 21f\n\t" \ ++ /* Handle 2 byte UTF16 char. */ \ ++ " lgr %[R_TMP3],%[R_TMP]\n\t" \ ++ " nilf %[R_TMP],0xf800\n\t" \ ++ " clfi %[R_TMP],0xd800\n\t" \ ++ " je 91f\n\t" /* Do not accept UTF-16 surrogates. */ \ ++ " slgfi %[R_OUTLEN],2\n\t" \ ++ " jl 90f \n\t" \ ++ " sth %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " la %[R_OUT],2(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ /* Test if ch is 4byte UTF-16 char. */ \ ++ "21: clfi %[R_TMP],0x10ffff\n\t" \ ++ " jh 91f\n\t" /* ch > 0x10ffff is not allowed! */ \ ++ /* Handle 4 byte UTF16 char. */ \ ++ " slgfi %[R_OUTLEN],4\n\t" \ ++ " jl 90f \n\t" \ ++ " slfi %[R_TMP],0x10000\n\t" /* zabcd = uvwxy - 1. */ \ ++ " llilf %[R_TMP3],0xd800dc00\n\t" \ ++ " la %[R_IN],4(%[R_IN])\n\t" \ ++ " risbgn %[R_TMP3],%[R_TMP],38,47,6\n\t" /* High surrogate. */ \ ++ " risbgn %[R_TMP3],%[R_TMP],54,63,0\n\t" /* Low surrogate. */ \ ++ " st %[R_TMP3],0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],4(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP2],20b\n\t" \ ++ " j 0b\n\t" /* Switch to vx-loop. */ \ ++ "92: lghi %[R_RES],%[RES_IN_FULL]\n\t" \ ++ " j 99f\n\t" \ ++ "91: lghi %[R_RES],%[RES_IN_ILL]\n\t" \ ++ " j 99f\n\t" \ ++ "90: lghi %[R_RES],%[RES_OUT_FULL]\n\t" \ ++ "99: \n\t" \ + ".machine pop" \ +- : /* outputs */ [R_IN] "+a" (pInput) \ +- , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (outptr) \ + , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ + , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ + , [R_RES] "+d" (result) \ +@@ -567,17 +556,10 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ + ASM_CLOBBER_VR ("v30") ASM_CLOBBER_VR ("v31") \ + ); \ +- inptr = pInput; \ +- outptr = pOutput; \ +- \ + if (__glibc_likely (inptr == inend) \ +- || result == __GCONV_FULL_OUTPUT) \ ++ || result != __GCONV_ILLEGAL_INPUT) \ + break; \ +- if (inptr + 4 > inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ ++ \ + STANDARD_TO_LOOP_ERR_HANDLER (4); \ + } + +@@ -590,15 +572,6 @@ strong_alias (__from_utf16_loop_c_single, __from_utf16_loop_single) + #define BODY BODY_TO_C + #include + +-/* Generate loop-function with hardware utf-convert instruction. */ +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT __to_utf16_loop_etf3eh +-#define LOOP_NEED_FLAGS +-#define BODY BODY_TO_ETF3EH +-#include +- + #if defined HAVE_S390_VX_ASM_SUPPORT + /* Generate loop-function with hardware vector instructions. */ + # define MIN_NEEDED_INPUT MIN_NEEDED_TO +@@ -623,10 +596,6 @@ __to_utf16_loop_resolver (unsigned long int dl_hwcap) + return __to_utf16_loop_vx; + else + #endif +- if (dl_hwcap & HWCAP_S390_ZARCH && dl_hwcap & HWCAP_S390_HIGH_GPRS +- && dl_hwcap & HWCAP_S390_ETF3EH) +- return __to_utf16_loop_etf3eh; +- else + return __to_utf16_loop_c; + } + +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-16.patch b/SOURCES/glibc-rh1380680-16.patch new file mode 100644 index 00000000..c736e5d0 --- /dev/null +++ b/SOURCES/glibc-rh1380680-16.patch @@ -0,0 +1,182 @@ +From e4613df21e25e063d120ee23a650c65cd16df4be Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 17:30:22 +0100 +Subject: [PATCH 16/17] Fix ucs4le_internal_loop in error case. [BZ #19726] + +Upstream commit 8f25676c83eef5c85db98f9cf027890fbe810447 + +When converting from UCS4LE to INTERNAL, the input-value is checked for a too +large value and the iconv() call sets errno to EILSEQ. In this case the inbuf +argument of the iconv() call should point to the invalid character, but it +points to the beginning of the inbuf. +Thus this patch updates the pointers inptrp and outptrp before returning in +this error case. + +This patch also adds a new testcase for this issue. +The new test was tested on a s390, power, intel machine. + +ChangeLog: + + [BZ #19726] + * iconv/gconv_simple.c (ucs4le_internal_loop): Update inptrp and + outptrp in case of an illegal input. + * iconv/tst-iconv6.c: New file. + * iconv/Makefile (tests): Add tst-iconv6. +--- + iconv/Makefile | 2 +- + iconv/gconv_simple.c | 2 + + iconv/tst-iconv6.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 120 insertions(+), 1 deletion(-) + create mode 100644 iconv/tst-iconv6.c + +diff --git a/iconv/Makefile b/iconv/Makefile +index 3e7f567..4d34c3f 100644 +--- a/iconv/Makefile ++++ b/iconv/Makefile +@@ -43,7 +43,7 @@ CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \ + CFLAGS-linereader.c = -DNO_TRANSLITERATION + CFLAGS-simple-hash.c = -I../locale + +-tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 ++tests = tst-iconv1 tst-iconv2 tst-iconv3 tst-iconv4 tst-iconv5 tst-iconv6 + + others = iconv_prog iconvconfig + install-others-programs = $(inst_bindir)/iconv +diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c +index 8697309..b9f846d 100644 +--- a/iconv/gconv_simple.c ++++ b/iconv/gconv_simple.c +@@ -634,6 +634,8 @@ ucs4le_internal_loop (struct __gconv_step *step, + continue; + } + ++ *inptrp = inptr; ++ *outptrp = outptr; + return __GCONV_ILLEGAL_INPUT; + } + +diff --git a/iconv/tst-iconv6.c b/iconv/tst-iconv6.c +new file mode 100644 +index 0000000..57d7f38 +--- /dev/null ++++ b/iconv/tst-iconv6.c +@@ -0,0 +1,117 @@ ++/* Testing ucs4le_internal_loop() in gconv_simple.c. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ iconv_t cd; ++ char *inptr; ++ size_t inlen; ++ char *outptr; ++ size_t outlen; ++ size_t n; ++ int e; ++ int result = 0; ++ ++#if __BYTE_ORDER == __BIG_ENDIAN ++ /* On big-endian machines, ucs4le_internal_loop() swaps the bytes before ++ error checking. Thus the input values has to be swapped. */ ++# define VALUE(val) bswap_32 (val) ++#else ++# define VALUE(val) val ++#endif ++ uint32_t inbuf[3] = { VALUE (0x41), VALUE (0x80000000), VALUE (0x42) }; ++ uint32_t outbuf[3] = { 0, 0, 0 }; ++ ++ cd = iconv_open ("WCHAR_T", "UCS-4LE"); ++ if (cd == (iconv_t) -1) ++ { ++ printf ("cannot convert from UCS4LE to wchar_t: %m\n"); ++ return 1; ++ } ++ ++ inptr = (char *) inbuf; ++ inlen = sizeof (inbuf); ++ outptr = (char *) outbuf; ++ outlen = sizeof (outbuf); ++ ++ n = iconv (cd, &inptr, &inlen, &outptr, &outlen); ++ e = errno; ++ ++ if (n != (size_t) -1) ++ { ++ printf ("incorrect iconv() return value: %zd, expected -1\n", n); ++ result = 1; ++ } ++ ++ if (e != EILSEQ) ++ { ++ printf ("incorrect error value: %s, expected %s\n", ++ strerror (e), strerror (EILSEQ)); ++ result = 1; ++ } ++ ++ if (inptr != (char *) &inbuf[1]) ++ { ++ printf ("inptr=0x%p does not point to invalid character! Expected=0x%p\n" ++ , inptr, &inbuf[1]); ++ result = 1; ++ } ++ ++ if (inlen != sizeof (inbuf) - sizeof (uint32_t)) ++ { ++ printf ("inlen=%zd != %zd\n" ++ , inlen, sizeof (inbuf) - sizeof (uint32_t)); ++ result = 1; ++ } ++ ++ if (outptr != (char *) &outbuf[1]) ++ { ++ printf ("outptr=0x%p does not point to invalid character in inbuf! " ++ "Expected=0x%p\n" ++ , outptr, &outbuf[1]); ++ result = 1; ++ } ++ ++ if (outlen != sizeof (inbuf) - sizeof (uint32_t)) ++ { ++ printf ("outlen=%zd != %zd\n" ++ , outlen, sizeof (outbuf) - sizeof (uint32_t)); ++ result = 1; ++ } ++ ++ if (outbuf[0] != 0x41 || outbuf[1] != 0 || outbuf[2] != 0) ++ { ++ puts ("Characters conversion is incorrect!"); ++ result = 1; ++ } ++ ++ iconv_close (cd); ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-17.patch b/SOURCES/glibc-rh1380680-17.patch new file mode 100644 index 00000000..748e09b7 --- /dev/null +++ b/SOURCES/glibc-rh1380680-17.patch @@ -0,0 +1,399 @@ +From dd5820453c8c8c6521e45e1cb229f70a5ab5f6b0 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 17:45:56 +0100 +Subject: [PATCH 17/17] Fix UTF-16 surrogate handling. [BZ #19727] + +Upstream commit 7ab1de21067d72460ac14089bf6541b10fc14c80 + +According to the latest Unicode standard, a conversion from/to UTF-xx has +to report an error if the character value is in range of an utf16 surrogate +(0xd800..0xdfff). See https://sourceware.org/ml/libc-help/2015-12/msg00015.html. +Thus this patch fixes this behaviour for converting from utf32 to internal and +from internal to utf8. + +Furthermore the conversion from utf16 to internal does not report an error if the +input-stream consists of two low-surrogate values. If an uint16_t value is in the +range of 0xd800 .. 0xdfff, the next uint16_t value is checked, if it is in the +range of a low surrogate (0xdc00 .. 0xdfff). Afterwards these two uint16_t +values are interpreted as a high- and low-surrogates pair. But there is no test +if the first uint16_t value is really in the range of a high-surrogate +(0xd800 .. 0xdbff). If there would be two uint16_t values in the range of a low +surrogate, then they will be treated as a valid high- and low-surrogates pair. +This patch adds this test. + +This patch also adds a new testcase, which checks UTF conversions with input +values in range of UTF16 surrogates. The test converts from UTF-xx to INTERNAL, +INTERNAL to UTF-xx and directly between UTF-xx to UTF-yy. The latter conversion +is needed because s390 has iconv-modules, which converts from/to UTF in one step. +The new testcase was tested on a s390, power and intel machine. + +ChangeLog: + + [BZ #19727] + * iconvdata/utf-16.c (BODY): Report an error if first word is not a + valid high surrogate. + * iconvdata/utf-32.c (BODY): Report an error if the value is in range + of an utf16 surrogate. + * iconv/gconv_simple.c (BODY): Likewise. + * iconvdata/bug-iconv12.c: New file. + * iconvdata/Makefile (tests): Add bug-iconv12. +--- + iconv/gconv_simple.c | 3 +- + iconvdata/Makefile | 4 +- + iconvdata/bug-iconv12.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++++ + iconvdata/utf-16.c | 12 +++ + iconvdata/utf-32.c | 3 +- + 5 files changed, 282 insertions(+), 3 deletions(-) + create mode 100644 iconvdata/bug-iconv12.c + +diff --git a/iconv/gconv_simple.c b/iconv/gconv_simple.c +index b9f846d..48932ee 100644 +--- a/iconv/gconv_simple.c ++++ b/iconv/gconv_simple.c +@@ -888,7 +888,8 @@ ucs4le_internal_loop_single (struct __gconv_step *step, + if (__builtin_expect (wc < 0x80, 1)) \ + /* It's an one byte sequence. */ \ + *outptr++ = (unsigned char) wc; \ +- else if (__builtin_expect (wc <= 0x7fffffff, 1)) \ ++ else if (__builtin_expect (wc <= 0x7fffffff \ ++ && (wc < 0xd800 || wc > 0xdfff), 1)) \ + { \ + size_t step; \ + unsigned char *start; \ +diff --git a/iconvdata/Makefile b/iconvdata/Makefile +index e2624de..0ec6755 100644 +--- a/iconvdata/Makefile ++++ b/iconvdata/Makefile +@@ -68,7 +68,7 @@ include ../Makeconfig + ifeq (yes,$(build-shared)) + tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \ + tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \ +- bug-iconv10 ++ bug-iconv10 bug-iconv12 + ifeq ($(have-thread-library),yes) + tests += bug-iconv3 + endif +@@ -294,6 +294,8 @@ $(objpfx)bug-iconv5.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)bug-iconv10.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) ++$(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \ ++ $(addprefix $(objpfx),$(modules.so)) + $(objpfx)tst-loading.out: $(objpfx)gconv-modules \ + $(addprefix $(objpfx),$(modules.so)) + $(objpfx)tst-iconv4.out: $(objpfx)gconv-modules \ +diff --git a/iconvdata/bug-iconv12.c b/iconvdata/bug-iconv12.c +new file mode 100644 +index 0000000..49f5208 +--- /dev/null ++++ b/iconvdata/bug-iconv12.c +@@ -0,0 +1,263 @@ ++/* bug 19727: Testing UTF conversions with UTF16 surrogates as input. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++run_conversion (const char *from, const char *to, char *inbuf, size_t inbuflen, ++ int exp_errno, int line) ++{ ++ char outbuf[16]; ++ iconv_t cd; ++ char *inptr; ++ size_t inlen; ++ char *outptr; ++ size_t outlen; ++ size_t n; ++ int e; ++ int fails = 0; ++ ++ cd = iconv_open (to, from); ++ if (cd == (iconv_t) -1) ++ { ++ printf ("line %d: cannot convert from %s to %s: %m\n", line, from, to); ++ return 1; ++ } ++ ++ inptr = (char *) inbuf; ++ inlen = inbuflen; ++ outptr = outbuf; ++ outlen = sizeof (outbuf); ++ ++ errno = 0; ++ n = iconv (cd, &inptr, &inlen, &outptr, &outlen); ++ e = errno; ++ ++ if (exp_errno == 0) ++ { ++ if (n == (size_t) -1) ++ { ++ puts ("n should be >= 0, but n == -1"); ++ fails ++; ++ } ++ ++ if (e != 0) ++ { ++ printf ("errno should be 0: 'Success', but errno == %d: '%s'\n" ++ , e, strerror(e)); ++ fails ++; ++ } ++ } ++ else ++ { ++ if (n != (size_t) -1) ++ { ++ printf ("n should be -1, but n == %zd\n", n); ++ fails ++; ++ } ++ ++ if (e != exp_errno) ++ { ++ printf ("errno should be %d: '%s', but errno == %d: '%s'\n" ++ , exp_errno, strerror (exp_errno), e, strerror (e)); ++ fails ++; ++ } ++ } ++ ++ iconv_close (cd); ++ ++ if (fails > 0) ++ { ++ printf ("Errors in line %d while converting %s to %s.\n\n" ++ , line, from, to); ++ } ++ ++ return fails; ++} ++ ++static int ++do_test (void) ++{ ++ int fails = 0; ++ char buf[4]; ++ ++ /* This test runs iconv() with UTF character in range of an UTF16 surrogate. ++ UTF-16 high surrogate is in range 0xD800..0xDBFF and ++ UTF-16 low surrogate is in range 0xDC00..0xDFFF. ++ Converting from or to UTF-xx has to report errors in those cases. ++ In UTF-16, surrogate pairs with a high surrogate in front of a low ++ surrogate is valid. */ ++ ++ /* Use RUN_UCS4_UTF32_INPUT to test conversion ... ++ ++ ... from INTERNAL to UTF-xx[LE|BE]: ++ Converting from UCS4 to UTF-xx[LE|BE] first converts UCS4 to INTERNAL ++ without checking for UTF-16 surrogate values ++ and then converts from INTERNAL to UTF-xx[LE|BE]. ++ The latter conversion has to report an error in those cases. ++ ++ ... from UTF-32[LE|BE] to INTERNAL: ++ Converting directly from UTF-32LE to UTF-8|16 is needed, ++ because e.g. s390x has iconv-modules which converts directly. */ ++#define RUN_UCS4_UTF32_INPUT(b0, b1, b2, b3, err, line) \ ++ buf[0] = b0; \ ++ buf[1] = b1; \ ++ buf[2] = b2; \ ++ buf[3] = b3; \ ++ fails += run_conversion ("UCS4", "UTF-8", buf, 4, err, line); \ ++ fails += run_conversion ("UCS4", "UTF-16LE", buf, 4, err, line); \ ++ fails += run_conversion ("UCS4", "UTF-16BE", buf, 4, err, line); \ ++ fails += run_conversion ("UCS4", "UTF-32LE", buf, 4, err, line); \ ++ fails += run_conversion ("UCS4", "UTF-32BE", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32BE", "WCHAR_T", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32BE", "UTF-8", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32BE", "UTF-16LE", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32BE", "UTF-16BE", buf, 4, err, line); \ ++ buf[0] = b3; \ ++ buf[1] = b2; \ ++ buf[2] = b1; \ ++ buf[3] = b0; \ ++ fails += run_conversion ("UTF-32LE", "WCHAR_T", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32LE", "UTF-8", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32LE", "UTF-16LE", buf, 4, err, line); \ ++ fails += run_conversion ("UTF-32LE", "UTF-16BE", buf, 4, err, line); ++ ++ /* Use UCS4/UTF32 input of 0xD7FF. */ ++ RUN_UCS4_UTF32_INPUT (0x0, 0x0, 0xD7, 0xFF, 0, __LINE__); ++ ++ /* Use UCS4/UTF32 input of 0xD800. */ ++ RUN_UCS4_UTF32_INPUT (0x0, 0x0, 0xD8, 0x00, EILSEQ, __LINE__); ++ ++ /* Use UCS4/UTF32 input of 0xDBFF. */ ++ RUN_UCS4_UTF32_INPUT (0x0, 0x0, 0xDB, 0xFF, EILSEQ, __LINE__); ++ ++ /* Use UCS4/UTF32 input of 0xDC00. */ ++ RUN_UCS4_UTF32_INPUT (0x0, 0x0, 0xDC, 0x00, EILSEQ, __LINE__); ++ ++ /* Use UCS4/UTF32 input of 0xDFFF. */ ++ RUN_UCS4_UTF32_INPUT (0x0, 0x0, 0xDF, 0xFF, EILSEQ, __LINE__); ++ ++ /* Use UCS4/UTF32 input of 0xE000. */ ++ RUN_UCS4_UTF32_INPUT (0x0, 0x0, 0xE0, 0x00, 0, __LINE__); ++ ++ ++ /* Use RUN_UTF16_INPUT to test conversion from UTF16[LE|BE] to INTERNAL. ++ Converting directly from UTF-16 to UTF-8|32 is needed, ++ because e.g. s390x has iconv-modules which converts directly. ++ Use len == 2 or 4 to specify one or two UTF-16 characters. */ ++#define RUN_UTF16_INPUT(b0, b1, b2, b3, len, err, line) \ ++ buf[0] = b0; \ ++ buf[1] = b1; \ ++ buf[2] = b2; \ ++ buf[3] = b3; \ ++ fails += run_conversion ("UTF-16BE", "WCHAR_T", buf, len, err, line); \ ++ fails += run_conversion ("UTF-16BE", "UTF-8", buf, len, err, line); \ ++ fails += run_conversion ("UTF-16BE", "UTF-32LE", buf, len, err, line); \ ++ fails += run_conversion ("UTF-16BE", "UTF-32BE", buf, len, err, line); \ ++ buf[0] = b1; \ ++ buf[1] = b0; \ ++ buf[2] = b3; \ ++ buf[3] = b2; \ ++ fails += run_conversion ("UTF-16LE", "WCHAR_T", buf, len, err, line); \ ++ fails += run_conversion ("UTF-16LE", "UTF-8", buf, len, err, line); \ ++ fails += run_conversion ("UTF-16LE", "UTF-32LE", buf, len, err, line); \ ++ fails += run_conversion ("UTF-16LE", "UTF-32BE", buf, len, err, line); ++ ++ /* Use UTF16 input of 0xD7FF. */ ++ RUN_UTF16_INPUT (0xD7, 0xFF, 0xD7, 0xFF, 4, 0, __LINE__); ++ ++ /* Use [single] UTF16 high surrogate 0xD800 [with a valid character behind]. ++ And check an UTF16 surrogate pair [without valid low surrogate]. */ ++ RUN_UTF16_INPUT (0xD8, 0x0, 0x0, 0x0, 2, EINVAL, __LINE__); ++ RUN_UTF16_INPUT (0xD8, 0x0, 0xD7, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xD8, 0x0, 0xD8, 0x0, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xD8, 0x0, 0xE0, 0x0, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xD8, 0x0, 0xDC, 0x0, 4, 0, __LINE__); ++ ++ /* Use [single] UTF16 high surrogate 0xDBFF [with a valid character behind]. ++ And check an UTF16 surrogate pair [without valid low surrogate]. */ ++ RUN_UTF16_INPUT (0xDB, 0xFF, 0x0, 0x0, 2, EINVAL, __LINE__); ++ RUN_UTF16_INPUT (0xDB, 0xFF, 0xD7, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDB, 0xFF, 0xDB, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDB, 0xFF, 0xE0, 0x0, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDB, 0xFF, 0xDF, 0xFF, 4, 0, __LINE__); ++ ++ /* Use single UTF16 low surrogate 0xDC00 [with a valid character behind]. ++ And check an UTF16 surrogate pair [without valid high surrogate]. */ ++ RUN_UTF16_INPUT (0xDC, 0x0, 0x0, 0x0, 2, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDC, 0x0, 0xD7, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xD8, 0x0, 0xDC, 0x0, 4, 0, __LINE__); ++ RUN_UTF16_INPUT (0xD7, 0xFF, 0xDC, 0x0, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDC, 0x0, 0xDC, 0x0, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xE0, 0x0, 0xDC, 0x0, 4, EILSEQ, __LINE__); ++ ++ /* Use single UTF16 low surrogate 0xDFFF [with a valid character behind]. ++ And check an UTF16 surrogate pair [without valid high surrogate]. */ ++ RUN_UTF16_INPUT (0xDF, 0xFF, 0x0, 0x0, 2, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDF, 0xFF, 0xD7, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDB, 0xFF, 0xDF, 0xFF, 4, 0, __LINE__); ++ RUN_UTF16_INPUT (0xD7, 0xFF, 0xDF, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xDF, 0xFF, 0xDF, 0xFF, 4, EILSEQ, __LINE__); ++ RUN_UTF16_INPUT (0xE0, 0x0, 0xDF, 0xFF, 4, EILSEQ, __LINE__); ++ ++ /* Use UCS4/UTF32 input of 0xE000. */ ++ RUN_UTF16_INPUT (0xE0, 0x0, 0xE0, 0x0, 4, 0, __LINE__); ++ ++ ++ /* Use RUN_UTF8_3BYTE_INPUT to test conversion from UTF-8 to INTERNAL. ++ Converting directly from UTF-8 to UTF-16|32 is needed, ++ because e.g. s390x has iconv-modules which converts directly. */ ++#define RUN_UTF8_3BYTE_INPUT(b0, b1, b2, err, line) \ ++ buf[0] = b0; \ ++ buf[1] = b1; \ ++ buf[2] = b2; \ ++ fails += run_conversion ("UTF-8", "WCHAR_T", buf, 3, err, line); \ ++ fails += run_conversion ("UTF-8", "UTF-16LE", buf, 3, err, line); \ ++ fails += run_conversion ("UTF-8", "UTF-16BE", buf, 3, err, line); \ ++ fails += run_conversion ("UTF-8", "UTF-32LE", buf, 3, err, line); \ ++ fails += run_conversion ("UTF-8", "UTF-32BE", buf, 3, err, line); ++ ++ /* Use UTF-8 input of 0xD7FF. */ ++ RUN_UTF8_3BYTE_INPUT (0xED, 0x9F, 0xBF, 0, __LINE__); ++ ++ /* Use UTF-8 input of 0xD800. */ ++ RUN_UTF8_3BYTE_INPUT (0xED, 0xA0, 0x80, EILSEQ, __LINE__); ++ ++ /* Use UTF-8 input of 0xDBFF. */ ++ RUN_UTF8_3BYTE_INPUT (0xED, 0xAF, 0xBF, EILSEQ, __LINE__); ++ ++ /* Use UTF-8 input of 0xDC00. */ ++ RUN_UTF8_3BYTE_INPUT (0xED, 0xB0, 0x80, EILSEQ, __LINE__); ++ ++ /* Use UTF-8 input of 0xDFFF. */ ++ RUN_UTF8_3BYTE_INPUT (0xED, 0xBF, 0xBF, EILSEQ, __LINE__); ++ ++ /* Use UTF-8 input of 0xF000. */ ++ RUN_UTF8_3BYTE_INPUT (0xEF, 0x80, 0x80, 0, __LINE__); ++ ++ return fails > 0 ? EXIT_FAILURE : EXIT_SUCCESS; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/iconvdata/utf-16.c b/iconvdata/utf-16.c +index b4ddfeb..e833d3c 100644 +--- a/iconvdata/utf-16.c ++++ b/iconvdata/utf-16.c +@@ -294,6 +294,12 @@ gconv_end (struct __gconv_step *data) + { \ + uint16_t u2; \ + \ ++ if (__glibc_unlikely (u1 >= 0xdc00)) \ ++ { \ ++ /* This is no valid first word for a surrogate. */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } \ ++ \ + /* It's a surrogate character. At least the first word says \ + it is. */ \ + if (__builtin_expect (inptr + 4 > inend, 0)) \ +@@ -328,6 +334,12 @@ gconv_end (struct __gconv_step *data) + } \ + else \ + { \ ++ if (__glibc_unlikely (u1 >= 0xdc00)) \ ++ { \ ++ /* This is no valid first word for a surrogate. */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); \ ++ } \ ++ \ + /* It's a surrogate character. At least the first word says \ + it is. */ \ + if (__builtin_expect (inptr + 4 > inend, 0)) \ +diff --git a/iconvdata/utf-32.c b/iconvdata/utf-32.c +index e0c4b19..1173d6f 100644 +--- a/iconvdata/utf-32.c ++++ b/iconvdata/utf-32.c +@@ -238,7 +238,8 @@ gconv_end (struct __gconv_step *data) + if (swap) \ + u1 = bswap_32 (u1); \ + \ +- if (__builtin_expect (u1 >= 0x110000, 0)) \ ++ if (__builtin_expect (u1 >= 0x110000 \ ++ || (u1 >= 0xd800 && u1 < 0xe000), 0)) \ + { \ + /* This is illegal. */ \ + STANDARD_FROM_LOOP_ERR_HANDLER (4); \ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-2.patch b/SOURCES/glibc-rh1380680-2.patch new file mode 100644 index 00000000..680d9be1 --- /dev/null +++ b/SOURCES/glibc-rh1380680-2.patch @@ -0,0 +1,113 @@ +From 29f8926b153d59ba18f67ce5445dce66bacc0cbf Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 15:25:04 +0100 +Subject: [PATCH 02/17] S390: Configure check for vector support in gcc. + +Upstream commit 9b7f05599a92dead97d6683bc838a57bc63ac52b + +The S390 specific test checks if the gcc has support for vector registers +by compiling an inline assembly which clobbers vector registers. +On success the macro HAVE_S390_VX_GCC_SUPPORT is defined. +This macro can be used to determine if e.g. clobbering vector registers +is allowed or not. + +ChangeLog: + + * config.h.in (HAVE_S390_VX_GCC_SUPPORT): New macro undefine. + * sysdeps/s390/configure.in: Add test for S390 vector register + support in gcc. + * sysdeps/s390/configure: Regenerated. +--- + config.h.in | 4 ++++ + sysdeps/s390/configure | 33 +++++++++++++++++++++++++++++++++ + sysdeps/s390/configure.in | 22 ++++++++++++++++++++++ + 3 files changed, 59 insertions(+) + +diff --git a/config.h.in b/config.h.in +index f7f2388..62e04c7 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -113,6 +113,10 @@ + /* Define if assembler supports vector instructions on S390. */ + #undef HAVE_S390_VX_ASM_SUPPORT + ++/* Define if gcc supports vector registers as clobbers in inline assembly ++ on S390. */ ++#undef HAVE_S390_VX_GCC_SUPPORT ++ + /* Define if gcc supports FMA4. */ + #undef HAVE_FMA4_SUPPORT + +diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure +index cc4c1e0..eb49a4c 100644 +--- a/sysdeps/s390/configure ++++ b/sysdeps/s390/configure +@@ -42,3 +42,36 @@ else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Use binutils with vector-support in order to use optimized implementations." >&5 + $as_echo "$as_me: WARNING: Use binutils with vector-support in order to use optimized implementations." >&2;} + fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 vector support in gcc" >&5 ++$as_echo_n "checking for S390 vector support in gcc... " >&6; } ++if ${libc_cv_gcc_s390_vx+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <<\EOF ++void testvecclobber () ++{ ++ __asm__ ("" : : : "v16"); ++} ++EOF ++if { ac_try='${CC-cc} --shared conftest.c -o conftest.o &> /dev/null' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ; ++then ++ libc_cv_gcc_s390_vx=yes ++else ++ libc_cv_gcc_s390_vx=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_s390_vx" >&5 ++$as_echo "$libc_cv_gcc_s390_vx" >&6; } ++ ++if test "$libc_cv_gcc_s390_vx" = yes ; ++then ++ $as_echo "#define HAVE_S390_VX_GCC_SUPPORT 1" >>confdefs.h ++ ++fi +diff --git a/sysdeps/s390/configure.in b/sysdeps/s390/configure.in +index 733e356..a3b1f25 100644 +--- a/sysdeps/s390/configure.in ++++ b/sysdeps/s390/configure.in +@@ -31,3 +31,25 @@ then + else + AC_MSG_WARN([Use binutils with vector-support in order to use optimized implementations.]) + fi ++ ++AC_CACHE_CHECK(for S390 vector support in gcc, libc_cv_gcc_s390_vx, [dnl ++cat > conftest.c <<\EOF ++void testvecclobber () ++{ ++ __asm__ ("" : : : "v16"); ++} ++EOF ++dnl ++dnl test, if gcc supports S390 vector registers as clobber in inline assembly ++if AC_TRY_COMMAND([${CC-cc} --shared conftest.c -o conftest.o &> /dev/null]) ; ++then ++ libc_cv_gcc_s390_vx=yes ++else ++ libc_cv_gcc_s390_vx=no ++fi ++rm -f conftest* ]) ++ ++if test "$libc_cv_gcc_s390_vx" = yes ; ++then ++ AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) ++fi +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-3.patch b/SOURCES/glibc-rh1380680-3.patch new file mode 100644 index 00000000..5d149748 --- /dev/null +++ b/SOURCES/glibc-rh1380680-3.patch @@ -0,0 +1,524 @@ +From c3fd92047b3cc1b66b9b241be0765fe1e72678a1 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 15:29:26 +0100 +Subject: [PATCH 03/17] S390: Optimize 8bit-generic iconv modules. + +Upstream commit 4690dab084f854bf0013b5eaabcf90c2d5b692ff + +This patch introduces a s390 specific 8bit-generic.c file which provides an +optimized version for z13 with translate-/vector-instructions, which will be +chosen at runtime via ifunc. +If the build-environment lacks vector support, then iconvdata/8bit-generic.c +is used wihtout any change. Otherwise iconvdata/8bit-generic.c is used to create +conversion loop routines without vector instructions as fallback, if vector +instructions aren't available at runtime. + +The vector routines can only be used with charsets where the maximum UCS4 value +fits in 1 byte size. Then the hardware translate-instruction is used +to translate between up to 256 generic characters and "1 byte UCS4" +characters at once. The vector instructions are used to convert between +the "1 byte UCS4" and UCS4. + +The gen-8bit.sh script in sysdeps/s390/multiarch generates the conversion +table to_ucs1. Therefore in sysdeps/s390/multiarch/Makefile is added an +override define generate-8bit-table, which is originally defined in +iconvdata/Makefile. This version calls the gen-8bit.sh in iconvdata folder +and the s390 one. + +ChangeLog: + + * sysdeps/s390/multiarch/8bit-generic.c: New File. + * sysdeps/s390/multiarch/gen-8bit.sh: New File. + * sysdeps/s390/multiarch/Makefile (generate-8bit-table): + New override define. + * sysdeps/s390/multiarch/iconv/skeleton.c: Likewise. +--- + sysdeps/s390/multiarch/8bit-generic.c | 415 ++++++++++++++++++++++++++++++++ + sysdeps/s390/multiarch/Makefile | 10 + + sysdeps/s390/multiarch/gen-8bit.sh | 6 + + sysdeps/s390/multiarch/iconv/skeleton.c | 21 ++ + 4 files changed, 452 insertions(+) + create mode 100644 sysdeps/s390/multiarch/8bit-generic.c + create mode 100644 sysdeps/s390/multiarch/gen-8bit.sh + create mode 100644 sysdeps/s390/multiarch/iconv/skeleton.c + +diff --git a/sysdeps/s390/multiarch/8bit-generic.c b/sysdeps/s390/multiarch/8bit-generic.c +new file mode 100644 +index 0000000..93565e1 +--- /dev/null ++++ b/sysdeps/s390/multiarch/8bit-generic.c +@@ -0,0 +1,415 @@ ++/* Generic conversion to and from 8bit charsets - S390 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ ++# if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++# else ++# define ASM_CLOBBER_VR(NR) ++# endif ++ ++/* Generate the conversion loop routines without vector instructions as ++ fallback, if vector instructions aren't available at runtime. */ ++# define IGNORE_ICONV_SKELETON ++# define from_generic __from_generic_c ++# define to_generic __to_generic_c ++# include "iconvdata/8bit-generic.c" ++# undef IGNORE_ICONV_SKELETON ++# undef from_generic ++# undef to_generic ++ ++/* Generate the converion routines with vector instructions. The vector ++ routines can only be used with charsets where the maximum UCS4 value ++ fits in 1 byte size. Then the hardware translate-instruction is used ++ to translate between multiple generic characters and "1 byte UCS4" ++ characters at once. The vector instructions are used to convert between ++ the "1 byte UCS4" and UCS4. */ ++# include ++# include ++ ++# undef FROM_LOOP ++# undef TO_LOOP ++# define FROM_LOOP __from_generic_vx ++# define TO_LOOP __to_generic_vx ++ ++# define MIN_NEEDED_FROM 1 ++# define MIN_NEEDED_TO 4 ++# define ONE_DIRECTION 0 ++ ++/* First define the conversion function from the 8bit charset to UCS4. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT FROM_LOOP ++# define BODY_FROM_ORIG \ ++ { \ ++ uint32_t ch = to_ucs4[*inptr]; \ ++ \ ++ if (HAS_HOLES && __builtin_expect (ch == L'\0', 0) && *inptr != '\0') \ ++ { \ ++ /* This is an illegal character. */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (1); \ ++ } \ ++ \ ++ put32 (outptr, ch); \ ++ outptr += 4; \ ++ ++inptr; \ ++ } ++ ++# define BODY \ ++ { \ ++ if (__builtin_expect (inend - inptr < 16, 1) \ ++ || outend - outptr < 64) \ ++ /* Convert remaining bytes with c code. */ \ ++ BODY_FROM_ORIG \ ++ else \ ++ { \ ++ /* Convert 16 ... 256 bytes at once with tr-instruction. */ \ ++ size_t index; \ ++ char buf[256]; \ ++ size_t loop_count = (inend - inptr) / 16; \ ++ if (loop_count > (outend - outptr) / 64) \ ++ loop_count = (outend - outptr) / 64; \ ++ if (loop_count > 16) \ ++ loop_count = 16; \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " sllk %[R_I],%[R_LI],4\n\t" \ ++ " ahi %[R_I],-1\n\t" \ ++ /* Execute mvc and tr with correct len. */ \ ++ " exrl %[R_I],21f\n\t" \ ++ " exrl %[R_I],22f\n\t" \ ++ /* Post-processing. */ \ ++ " lghi %[R_I],0\n\t" \ ++ " vzero %%v0\n\t" \ ++ "0: \n\t" \ ++ /* Find invalid character - value is zero. */ \ ++ " vl %%v16,0(%[R_I],%[R_BUF])\n\t" \ ++ " vceqbs %%v23,%%v0,%%v16\n\t" \ ++ " jle 10f\n\t" \ ++ "1: \n\t" \ ++ /* Enlarge to UCS4. */ \ ++ " vuplhb %%v17,%%v16\n\t" \ ++ " vupllb %%v18,%%v16\n\t" \ ++ " vuplhh %%v19,%%v17\n\t" \ ++ " vupllh %%v20,%%v17\n\t" \ ++ " vuplhh %%v21,%%v18\n\t" \ ++ " vupllh %%v22,%%v18\n\t" \ ++ /* Store 64bytes to buf_out. */ \ ++ " vstm %%v19,%%v22,0(%[R_OUT])\n\t" \ ++ " aghi %[R_I],16\n\t" \ ++ " la %[R_OUT],64(%[R_OUT])\n\t" \ ++ " brct %[R_LI],0b\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " j 20f\n\t" \ ++ "21: mvc 0(1,%[R_BUF]),0(%[R_IN])\n\t" \ ++ "22: tr 0(1,%[R_BUF]),0(%[R_TBL])\n\t" \ ++ /* Possibly invalid character found. */ \ ++ "10: \n\t" \ ++ /* Test if input was zero, too. */ \ ++ " vl %%v24,0(%[R_I],%[R_IN])\n\t" \ ++ " vceqb %%v24,%%v0,%%v24\n\t" \ ++ /* Zeros in buf (v23) and inptr (v24) are marked \ ++ with one bits. After xor, invalid characters \ ++ are marked as one bits. Proceed, if no \ ++ invalid characters are found. */ \ ++ " vx %%v24,%%v23,%%v24\n\t" \ ++ " vfenebs %%v24,%%v24,%%v0\n\t" \ ++ " jo 1b\n\t" \ ++ /* Found an invalid translation. \ ++ Store the preceding chars. */ \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " vlgvb %[R_I],%%v24,7\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " sll %[R_I],2\n\t" \ ++ " ahi %[R_I],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " lgr %[R_LI],%[R_I]\n\t" \ ++ " vuplhb %%v17,%%v16\n\t" \ ++ " vuplhh %%v19,%%v17\n\t" \ ++ " vstl %%v19,%[R_I],0(%[R_OUT])\n\t" \ ++ " ahi %[R_I],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v20,%%v17\n\t" \ ++ " vstl %%v20,%[R_I],16(%[R_OUT])\n\t" \ ++ " ahi %[R_I],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllb %%v18,%%v16\n\t" \ ++ " vuplhh %%v21,%%v18\n\t" \ ++ " vstl %%v21,%[R_I],32(%[R_OUT])\n\t" \ ++ " ahi %[R_I],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v22,%%v18\n\t" \ ++ " vstl %%v22,%[R_I],48(%[R_OUT])\n\t" \ ++ "11: \n\t" \ ++ " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" \ ++ "20: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_OUT] "+a" (outptr), [R_I] "=&a" (index) \ ++ , [R_LI] "+a" (loop_count) \ ++ : /* inputs */ [R_BUF] "a" (buf) \ ++ , [R_TBL] "a" (to_ucs1) \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v0") ASM_CLOBBER_VR ("v16") \ ++ ASM_CLOBBER_VR ("v17") ASM_CLOBBER_VR ("v18") \ ++ ASM_CLOBBER_VR ("v19") ASM_CLOBBER_VR ("v20") \ ++ ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") \ ++ ASM_CLOBBER_VR ("v23") ASM_CLOBBER_VR ("v24") \ ++ ); \ ++ /* Error occured? */ \ ++ if (loop_count != 0) \ ++ { \ ++ /* Found an invalid character! */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (1); \ ++ } \ ++ } \ ++ } ++ ++# define LOOP_NEED_FLAGS ++# include ++ ++/* Next, define the other direction - from UCS4 to 8bit charset. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define LOOPFCT TO_LOOP ++# define BODY_TO_ORIG \ ++ { \ ++ uint32_t ch = get32 (inptr); \ ++ \ ++ if (__builtin_expect (ch >= sizeof (from_ucs4) / sizeof (from_ucs4[0]), 0)\ ++ || (__builtin_expect (from_ucs4[ch], '\1') == '\0' && ch != 0)) \ ++ { \ ++ UNICODE_TAG_HANDLER (ch, 4); \ ++ \ ++ /* This is an illegal character. */ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ \ ++ *outptr++ = from_ucs4[ch]; \ ++ inptr += 4; \ ++ } ++# define BODY \ ++ { \ ++ if (__builtin_expect (inend - inptr < 64, 1) \ ++ || outend - outptr < 16) \ ++ /* Convert remaining bytes with c code. */ \ ++ BODY_TO_ORIG \ ++ else \ ++ { \ ++ /* Convert 64 ... 1024 bytes at once with tr-instruction. */ \ ++ size_t index, tmp; \ ++ char buf[256]; \ ++ size_t loop_count = (inend - inptr) / 64; \ ++ uint32_t max = sizeof (from_ucs4) / sizeof (from_ucs4[0]); \ ++ if (loop_count > (outend - outptr) / 16) \ ++ loop_count = (outend - outptr) / 16; \ ++ if (loop_count > 16) \ ++ loop_count = 16; \ ++ size_t remaining_loop_count = loop_count; \ ++ /* Step 1: Check for ch>=max, ch == 0 and shorten to bytes. \ ++ (ch == 0 is no error, but is handled differently) */ \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ /* Setup to check for ch >= max. */ \ ++ " vzero %%v21\n\t" \ ++ " vleih %%v21,-24576,0\n\t" /* element 0: > */ \ ++ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ ++ " vlvgf %%v20,%[R_MAX],0\n\t" /* element 0: val */ \ ++ /* Process in 64byte - 16 characters blocks. */ \ ++ " lghi %[R_I],0\n\t" \ ++ " lghi %[R_TMP],0\n\t" \ ++ "0: \n\t" \ ++ " vlm %%v16,%%v19,0(%[R_IN])\n\t" \ ++ /* Test for ch >= max and ch == 0. */ \ ++ " vstrczfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrczfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ " vstrczfs %%v22,%%v18,%%v20,%%v21\n\t" \ ++ " jno 12f\n\t" \ ++ " vstrczfs %%v22,%%v19,%%v20,%%v21\n\t" \ ++ " jno 13f\n\t" \ ++ /* Shorten to byte values. */ \ ++ " vpkf %%v16,%%v16,%%v17\n\t" \ ++ " vpkf %%v18,%%v18,%%v19\n\t" \ ++ " vpkh %%v16,%%v16,%%v18\n\t" \ ++ /* Store 16bytes to buf. */ \ ++ " vst %%v16,0(%[R_I],%[R_BUF])\n\t" \ ++ /* Loop until all blocks are processed. */ \ ++ " la %[R_IN],64(%[R_IN])\n\t" \ ++ " aghi %[R_I],16\n\t" \ ++ " brct %[R_LI],0b\n\t" \ ++ " j 20f\n\t" \ ++ /* Found error ch >= max or ch == 0. */ \ ++ "13: aghi %[R_TMP],4\n\t" \ ++ "12: aghi %[R_TMP],4\n\t" \ ++ "11: aghi %[R_TMP],4\n\t" \ ++ "10: vlgvb %[R_I],%%v22,7\n\t" \ ++ " srlg %[R_I],%[R_I],2\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ "20: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_I] "=&a" (index) \ ++ , [R_TMP] "=d" (tmp) \ ++ , [R_LI] "+d" (remaining_loop_count) \ ++ : /* inputs */ [R_BUF] "a" (buf) \ ++ , [R_MAX] "d" (max) \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") \ ++ ); \ ++ /* Error occured in step 1? An error (ch >= max || ch == 0) \ ++ occured, if remaining_loop_count > 0. The error occured \ ++ at character-index (index) after already processed blocks. */ \ ++ loop_count -= remaining_loop_count; \ ++ if (loop_count > 0) \ ++ { \ ++ /* Step 2: Translate already processed blocks in buf and \ ++ check for errors (from_ucs4[ch] == 0). */ \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " sllk %[R_I],%[R_LI],4\n\t" \ ++ " ahi %[R_I],-1\n\t" \ ++ /* Execute tr with correct len. */ \ ++ " exrl %[R_I],21f\n\t" \ ++ /* Post-processing. */ \ ++ " lghi %[R_I],0\n\t" \ ++ "0: \n\t" \ ++ /* Find invalid character - value == 0. */ \ ++ " vl %%v16,0(%[R_I],%[R_BUF])\n\t" \ ++ " vfenezbs %%v17,%%v16,%%v16\n\t" \ ++ " je 10f\n\t" \ ++ /* Store 16bytes to buf_out. */ \ ++ " vst %%v16,0(%[R_I],%[R_OUT])\n\t" \ ++ " aghi %[R_I],16\n\t" \ ++ " brct %[R_LI],0b\n\t" \ ++ " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ ++ " j 20f\n\t" \ ++ "21: tr 0(1,%[R_BUF]),0(%[R_TBL])\n\t" \ ++ /* Found an error: from_ucs4[ch] == 0. */ \ ++ "10: la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ ++ " vlgvb %[R_I],%%v17,7\n\t" \ ++ "20: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_I] "=&a" (tmp) \ ++ , [R_LI] "+d" (loop_count) \ ++ : /* inputs */ [R_BUF] "a" (buf) \ ++ , [R_TBL] "a" (from_ucs4) \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") \ ++ ASM_CLOBBER_VR ("v17") \ ++ ); \ ++ /* Error occured in processed bytes of step 2? \ ++ Thus possible error in step 1 is obselete.*/ \ ++ if (tmp < 16) \ ++ { \ ++ index = tmp; \ ++ inptr -= loop_count * 64; \ ++ } \ ++ } \ ++ /* Error occured in step 1/2? */ \ ++ if (index < 16) \ ++ { \ ++ /* Found an invalid character (see step 2) or zero \ ++ (see step 1) at index! Convert the chars before index \ ++ manually. If there is a zero at index detected by step 1, \ ++ there could be invalid characters before this zero. */ \ ++ int i; \ ++ uint32_t ch; \ ++ for (i = 0; i < index; i++) \ ++ { \ ++ ch = get32 (inptr); \ ++ if (__builtin_expect (from_ucs4[ch], '\1') == '\0') \ ++ break; \ ++ *outptr++ = from_ucs4[ch]; \ ++ inptr += 4; \ ++ } \ ++ if (i == index) \ ++ { \ ++ ch = get32 (inptr); \ ++ if (ch == 0) \ ++ { \ ++ /* This is no error, but handled differently. */ \ ++ *outptr++ = from_ucs4[ch]; \ ++ inptr += 4; \ ++ continue; \ ++ } \ ++ } \ ++ \ ++ UNICODE_TAG_HANDLER (ch, 4); \ ++ \ ++ /* This is an illegal character. */ \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ } \ ++ } ++ ++# define LOOP_NEED_FLAGS ++# include ++ ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_generic_c) ++__attribute__ ((ifunc ("__from_generic_resolver"))) ++__from_generic; ++ ++static void * ++__from_generic_resolver (unsigned long int dl_hwcap) ++{ ++ if (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 ++ && dl_hwcap & HWCAP_S390_VX) ++ return &__from_generic_vx; ++ else ++ return &__from_generic_c; ++} ++ ++__typeof(__to_generic_c) ++__attribute__ ((ifunc ("__to_generic_resolver"))) ++__to_generic; ++ ++static void * ++__to_generic_resolver (unsigned long int dl_hwcap) ++{ ++ if (sizeof (from_ucs4) / sizeof (from_ucs4[0]) <= 256 ++ && dl_hwcap & HWCAP_S390_VX) ++ return &__to_generic_vx; ++ else ++ return &__to_generic_c; ++} ++ ++strong_alias (__to_generic_c_single, __to_generic_single) ++ ++# undef FROM_LOOP ++# undef TO_LOOP ++# define FROM_LOOP __from_generic ++# define TO_LOOP __to_generic ++# include ++ ++#else ++/* Generate this module without ifunc if build environment lacks vector ++ support. Instead the common 8bit-generic.c is used. */ ++# include "iconvdata/8bit-generic.c" ++#endif /* !defined HAVE_S390_VX_ASM_SUPPORT */ +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 0805b07..11ad2b9 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -42,3 +42,13 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \ + wmemset wmemset-vx wmemset-c \ + wmemcmp wmemcmp-vx wmemcmp-c + endif ++ ++ifeq ($(subdir),iconvdata) ++override define generate-8bit-table ++$(make-target-directory) ++LC_ALL=C $(SHELL) ./gen-8bit.sh $< > $(@:stmp=T) ++LC_ALL=C $(SHELL) ../sysdeps/s390/multiarch/gen-8bit.sh $< >> $(@:stmp=T) ++$(move-if-change) $(@:stmp=T) $(@:stmp=h) ++touch $@ ++endef ++endif +diff --git a/sysdeps/s390/multiarch/gen-8bit.sh b/sysdeps/s390/multiarch/gen-8bit.sh +new file mode 100644 +index 0000000..6f88c4b +--- /dev/null ++++ b/sysdeps/s390/multiarch/gen-8bit.sh +@@ -0,0 +1,6 @@ ++#!/bin/sh ++echo "static const uint8_t to_ucs1[256] = {" ++sed -ne '/^[^[:space:]]*[[:space:]]*.x00/d;/^END/q' \ ++ -e 's/^[[:space:]]*.x\(..\).*/ [0x\2] = 0x\1,/p' \ ++ "$@" | sort -u ++echo "};" +diff --git a/sysdeps/s390/multiarch/iconv/skeleton.c b/sysdeps/s390/multiarch/iconv/skeleton.c +new file mode 100644 +index 0000000..3a90031 +--- /dev/null ++++ b/sysdeps/s390/multiarch/iconv/skeleton.c +@@ -0,0 +1,21 @@ ++/* Skeleton for a conversion module - S390 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef IGNORE_ICONV_SKELETON ++# include_next ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-4.patch b/SOURCES/glibc-rh1380680-4.patch new file mode 100644 index 00000000..e526b543 --- /dev/null +++ b/SOURCES/glibc-rh1380680-4.patch @@ -0,0 +1,1313 @@ +From 53f860e80162b09c44b48f207342c1452289072c Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 15:37:29 +0100 +Subject: [PATCH 04/17] S390: Optimize builtin iconv-modules. + +Upstream commit 3b704e26b33e35d99de920f8462d8e438f89be39 + +This patch introduces a s390 specific gconv_simple.c file which provides +optimized versions for z13 with vector instructions, which will be chosen at +runtime via ifunc. +The optimized conversions can convert between internal and ascii, ucs4, ucs4le, +ucs2, ucs2le. +If the build-environment lacks vector support, then iconv/gconv_simple.c +is used wihtout any change. Otherwise iconvdata/gconv_simple.c is used to create +conversion loop routines without vector instructions as fallback, if vector +instructions aren't available at runtime. + +ChangeLog: + + * sysdeps/s390/multiarch/gconv_simple.c: New File. + * sysdeps/s390/multiarch/Makefile (sysdep_routines): Add gconv_simple. +--- + sysdeps/s390/multiarch/Makefile | 4 + + sysdeps/s390/multiarch/gconv_simple.c | 1266 +++++++++++++++++++++++++++++++++ + 2 files changed, 1270 insertions(+) + create mode 100644 sysdeps/s390/multiarch/gconv_simple.c + +diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile +index 11ad2b9..24949cd 100644 +--- a/sysdeps/s390/multiarch/Makefile ++++ b/sysdeps/s390/multiarch/Makefile +@@ -52,3 +52,7 @@ $(move-if-change) $(@:stmp=T) $(@:stmp=h) + touch $@ + endef + endif ++ ++ifeq ($(subdir),iconv) ++sysdep_routines += gconv_simple ++endif +diff --git a/sysdeps/s390/multiarch/gconv_simple.c b/sysdeps/s390/multiarch/gconv_simple.c +new file mode 100644 +index 0000000..dc53a48 +--- /dev/null ++++ b/sysdeps/s390/multiarch/gconv_simple.c +@@ -0,0 +1,1266 @@ ++/* Simple transformations functions - s390 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++# include ++ ++# if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++# else ++# define ASM_CLOBBER_VR(NR) ++# endif ++ ++# define ICONV_C_NAME(NAME) __##NAME##_c ++# define ICONV_VX_NAME(NAME) __##NAME##_vx ++# define ICONV_VX_IFUNC(FUNC) \ ++ extern __typeof (ICONV_C_NAME (FUNC)) __##FUNC; \ ++ s390_vx_libc_ifunc (__##FUNC) \ ++ int FUNC (struct __gconv_step *step, struct __gconv_step_data *data, \ ++ const unsigned char **inptrp, const unsigned char *inend, \ ++ unsigned char **outbufstart, size_t *irreversible, \ ++ int do_flush, int consume_incomplete) \ ++ { \ ++ return __##FUNC (step, data, inptrp, inend,outbufstart, \ ++ irreversible, do_flush, consume_incomplete); \ ++ } ++# define ICONV_VX_SINGLE(NAME) \ ++ static __typeof (NAME##_single) __##NAME##_vx_single __attribute__((alias(#NAME "_single"))); ++ ++/* Generate the transformations which are used, if the target machine does not ++ support vector instructions. */ ++# define __gconv_transform_ascii_internal \ ++ ICONV_C_NAME (__gconv_transform_ascii_internal) ++# define __gconv_transform_internal_ascii \ ++ ICONV_C_NAME (__gconv_transform_internal_ascii) ++# define __gconv_transform_internal_ucs4le \ ++ ICONV_C_NAME (__gconv_transform_internal_ucs4le) ++# define __gconv_transform_ucs4_internal \ ++ ICONV_C_NAME (__gconv_transform_ucs4_internal) ++# define __gconv_transform_ucs4le_internal \ ++ ICONV_C_NAME (__gconv_transform_ucs4le_internal) ++# define __gconv_transform_ucs2_internal \ ++ ICONV_C_NAME (__gconv_transform_ucs2_internal) ++# define __gconv_transform_ucs2reverse_internal \ ++ ICONV_C_NAME (__gconv_transform_ucs2reverse_internal) ++# define __gconv_transform_internal_ucs2 \ ++ ICONV_C_NAME (__gconv_transform_internal_ucs2) ++# define __gconv_transform_internal_ucs2reverse \ ++ ICONV_C_NAME (__gconv_transform_internal_ucs2reverse) ++ ++ ++# include ++ ++# undef __gconv_transform_ascii_internal ++# undef __gconv_transform_internal_ascii ++# undef __gconv_transform_internal_ucs4le ++# undef __gconv_transform_ucs4_internal ++# undef __gconv_transform_ucs4le_internal ++# undef __gconv_transform_ucs2_internal ++# undef __gconv_transform_ucs2reverse_internal ++# undef __gconv_transform_internal_ucs2 ++# undef __gconv_transform_internal_ucs2reverse ++ ++/* Now define the functions with vector support. */ ++# if defined __s390x__ ++# define CONVERT_32BIT_SIZE_T(REG) ++# else ++# define CONVERT_32BIT_SIZE_T(REG) "llgfr %" #REG ",%" #REG "\n\t" ++# endif ++ ++/* Convert from ISO 646-IRV to the internal (UCS4-like) format. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 1 ++# define MIN_NEEDED_TO 4 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (ascii_internal_loop) ++# define TO_LOOP ICONV_VX_NAME (ascii_internal_loop) /* This is not used. */ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ascii_internal) ++# define ONE_DIRECTION 1 ++ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT FROM_LOOP ++# define BODY_ORIG_ERROR \ ++ /* The value is too large. We don't try transliteration here since \ ++ this is not an error because of the lack of possibilities to \ ++ represent the result. This is a genuine bug in the input since \ ++ ASCII does not allow such values. */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (1); ++ ++# define BODY_ORIG \ ++ { \ ++ if (__glibc_unlikely (*inptr > '\x7f')) \ ++ { \ ++ BODY_ORIG_ERROR \ ++ } \ ++ else \ ++ { \ ++ /* It's an one byte sequence. */ \ ++ *((uint32_t *) outptr) = *inptr++; \ ++ outptr += sizeof (uint32_t); \ ++ } \ ++ } ++# define BODY \ ++ { \ ++ size_t len = inend - inptr; \ ++ if (len > (outend - outptr) / 4) \ ++ len = (outend - outptr) / 4; \ ++ size_t loop_count, tmp; \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_LEN]) \ ++ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ ++ " srlg %[R_LI],%[R_LEN],4\n\t" \ ++ " vrepib %%v31,0x20\n\t" \ ++ " clgije %[R_LI],0,1f\n\t" \ ++ "0: \n\t" /* Handle 16-byte blocks. */ \ ++ " vl %%v16,0(%[R_IN])\n\t" \ ++ /* Checking for values > 0x7f. */ \ ++ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" \ ++ /* Enlarge to UCS4. */ \ ++ " vuplhb %%v17,%%v16\n\t" \ ++ " vupllb %%v18,%%v16\n\t" \ ++ " vuplhh %%v19,%%v17\n\t" \ ++ " vupllh %%v20,%%v17\n\t" \ ++ " vuplhh %%v21,%%v18\n\t" \ ++ " vupllh %%v22,%%v18\n\t" \ ++ /* Store 64bytes to buf_out. */ \ ++ " vstm %%v19,%%v22,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " la %[R_OUT],64(%[R_OUT])\n\t" \ ++ " brctg %[R_LI],0b\n\t" \ ++ " lghi %[R_LI],15\n\t" \ ++ " ngr %[R_LEN],%[R_LI]\n\t" \ ++ " je 20f\n\t" /* Jump away if no remaining bytes. */ \ ++ /* Handle remaining bytes. */ \ ++ "1: aghik %[R_LI],%[R_LEN],-1\n\t" \ ++ " jl 20f\n\t" /* Jump away if no remaining bytes. */ \ ++ " vll %%v16,%[R_LI],0(%[R_IN])\n\t" \ ++ /* Checking for values > 0x7f. */ \ ++ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ ++ " vlgvb %[R_TMP],%%v17,7\n\t" \ ++ " clr %[R_TMP],%[R_LI]\n\t" \ ++ " locrh %[R_TMP],%[R_LEN]\n\t" \ ++ " locghih %[R_LEN],0\n\t" \ ++ " j 12f\n\t" \ ++ "10:\n\t" \ ++ /* Found a value > 0x7f. \ ++ Store the preceding chars. */ \ ++ " vlgvb %[R_TMP],%%v17,7\n\t" \ ++ "12: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " sllk %[R_TMP],%[R_TMP],2\n\t" \ ++ " ahi %[R_TMP],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " lgr %[R_LI],%[R_TMP]\n\t" \ ++ " vuplhb %%v17,%%v16\n\t" \ ++ " vuplhh %%v19,%%v17\n\t" \ ++ " vstl %%v19,%[R_LI],0(%[R_OUT])\n\t" \ ++ " ahi %[R_LI],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v20,%%v17\n\t" \ ++ " vstl %%v20,%[R_LI],16(%[R_OUT])\n\t" \ ++ " ahi %[R_LI],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllb %%v18,%%v16\n\t" \ ++ " vuplhh %%v21,%%v18\n\t" \ ++ " vstl %%v21,%[R_LI],32(%[R_OUT])\n\t" \ ++ " ahi %[R_LI],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v22,%%v18\n\t" \ ++ " vstl %%v22,%[R_LI],48(%[R_OUT])\n\t" \ ++ "11:\n\t" \ ++ " la %[R_OUT],1(%[R_TMP],%[R_OUT])\n\t" \ ++ "20:\n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_IN] "+a" (inptr) \ ++ , [R_LEN] "+d" (len) \ ++ , [R_LI] "=d" (loop_count) \ ++ , [R_TMP] "=a" (tmp) \ ++ : /* inputs */ \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \ ++ ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ if (len > 0) \ ++ { \ ++ /* Found an invalid character at the next input byte. */ \ ++ BODY_ORIG_ERROR \ ++ } \ ++ } ++ ++# define LOOP_NEED_FLAGS ++# include ++# include ++# undef BODY_ORIG ++# undef BODY_ORIG_ERROR ++ICONV_VX_IFUNC (__gconv_transform_ascii_internal) ++ ++/* Convert from the internal (UCS4-like) format to ISO 646-IRV. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 4 ++# define MIN_NEEDED_TO 1 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (internal_ascii_loop) ++# define TO_LOOP ICONV_VX_NAME (internal_ascii_loop) /* This is not used. */ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ascii) ++# define ONE_DIRECTION 1 ++ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT FROM_LOOP ++# define BODY_ORIG_ERROR \ ++ UNICODE_TAG_HANDLER (*((const uint32_t *) inptr), 4); \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); ++ ++# define BODY_ORIG \ ++ { \ ++ if (__glibc_unlikely (*((const uint32_t *) inptr) > 0x7f)) \ ++ { \ ++ BODY_ORIG_ERROR \ ++ } \ ++ else \ ++ { \ ++ /* It's an one byte sequence. */ \ ++ *outptr++ = *((const uint32_t *) inptr); \ ++ inptr += sizeof (uint32_t); \ ++ } \ ++ } ++# define BODY \ ++ { \ ++ size_t len = (inend - inptr) / 4; \ ++ if (len > outend - outptr) \ ++ len = outend - outptr; \ ++ size_t loop_count, tmp, tmp2; \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_LEN]) \ ++ /* Setup to check for ch > 0x7f. */ \ ++ " vzero %%v21\n\t" \ ++ " srlg %[R_LI],%[R_LEN],4\n\t" \ ++ " vleih %%v21,8192,0\n\t" /* element 0: > */ \ ++ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ ++ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ ++ " lghi %[R_TMP],0\n\t" \ ++ " clgije %[R_LI],0,1f\n\t" \ ++ "0:\n\t" \ ++ " vlm %%v16,%%v19,0(%[R_IN])\n\t" \ ++ /* Shorten to byte values. */ \ ++ " vpkf %%v23,%%v16,%%v17\n\t" \ ++ " vpkf %%v24,%%v18,%%v19\n\t" \ ++ " vpkh %%v23,%%v23,%%v24\n\t" \ ++ /* Checking for values > 0x7f. */ \ ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ ++ " jno 12f\n\t" \ ++ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ ++ " jno 13f\n\t" \ ++ /* Store 16bytes to outptr. */ \ ++ " vst %%v23,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],64(%[R_IN])\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " brctg %[R_LI],0b\n\t" \ ++ " lghi %[R_LI],15\n\t" \ ++ " ngr %[R_LEN],%[R_LI]\n\t" \ ++ " je 20f\n\t" /* Jump away if no remaining bytes. */ \ ++ /* Handle remaining bytes. */ \ ++ "1: sllg %[R_LI],%[R_LEN],2\n\t" \ ++ " aghi %[R_LI],-1\n\t" \ ++ " jl 20f\n\t" /* Jump away if no remaining bytes. */ \ ++ /* Load remaining 1...63 bytes. */ \ ++ " vll %%v16,%[R_LI],0(%[R_IN])\n\t" \ ++ " ahi %[R_LI],-16\n\t" \ ++ " jl 2f\n\t" \ ++ " vll %%v17,%[R_LI],16(%[R_IN])\n\t" \ ++ " ahi %[R_LI],-16\n\t" \ ++ " jl 2f\n\t" \ ++ " vll %%v18,%[R_LI],32(%[R_IN])\n\t" \ ++ " ahi %[R_LI],-16\n\t" \ ++ " jl 2f\n\t" \ ++ " vll %%v19,%[R_LI],48(%[R_IN])\n\t" \ ++ "2:\n\t" \ ++ /* Shorten to byte values. */ \ ++ " vpkf %%v23,%%v16,%%v17\n\t" \ ++ " vpkf %%v24,%%v18,%%v19\n\t" \ ++ " vpkh %%v23,%%v23,%%v24\n\t" \ ++ " sllg %[R_LI],%[R_LEN],2\n\t" \ ++ " aghi %[R_LI],-16\n\t" \ ++ " jl 3f\n\t" /* v16 is not fully loaded. */ \ ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ " aghi %[R_LI],-16\n\t" \ ++ " jl 4f\n\t" /* v17 is not fully loaded. */ \ ++ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ " aghi %[R_LI],-16\n\t" \ ++ " jl 5f\n\t" /* v18 is not fully loaded. */ \ ++ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ ++ " jno 12f\n\t" \ ++ " aghi %[R_LI],-16\n\t" \ ++ /* v19 is not fully loaded. */ \ ++ " lghi %[R_TMP],12\n\t" \ ++ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ ++ "6: vlgvb %[R_I],%%v22,7\n\t" \ ++ " aghi %[R_LI],16\n\t" \ ++ " clrjl %[R_I],%[R_LI],14f\n\t" \ ++ " lgr %[R_I],%[R_LEN]\n\t" \ ++ " lghi %[R_LEN],0\n\t" \ ++ " j 15f\n\t" \ ++ "3: vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " j 6b\n\t" \ ++ "4: vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " lghi %[R_TMP],4\n\t" \ ++ " j 6b\n\t" \ ++ "5: vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " lghi %[R_TMP],8\n\t" \ ++ " j 6b\n\t" \ ++ /* Found a value > 0x7f. */ \ ++ "13: ahi %[R_TMP],4\n\t" \ ++ "12: ahi %[R_TMP],4\n\t" \ ++ "11: ahi %[R_TMP],4\n\t" \ ++ "10: vlgvb %[R_I],%%v22,7\n\t" \ ++ "14: srlg %[R_I],%[R_I],2\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ " je 20f\n\t" \ ++ /* Store characters before invalid one... */ \ ++ "15: aghi %[R_I],-1\n\t" \ ++ " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ ++ /* ... and update pointers. */ \ ++ " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \ ++ " sllg %[R_I],%[R_I],2\n\t" \ ++ " la %[R_IN],4(%[R_I],%[R_IN])\n\t" \ ++ "20:\n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_IN] "+a" (inptr) \ ++ , [R_LEN] "+d" (len) \ ++ , [R_LI] "=d" (loop_count) \ ++ , [R_I] "=a" (tmp2) \ ++ , [R_TMP] "=d" (tmp) \ ++ : /* inputs */ \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ ++ ASM_CLOBBER_VR ("v24") \ ++ ); \ ++ if (len > 0) \ ++ { \ ++ /* Found an invalid character > 0x7f at next character. */ \ ++ BODY_ORIG_ERROR \ ++ } \ ++ } ++# define LOOP_NEED_FLAGS ++# include ++# include ++# undef BODY_ORIG ++# undef BODY_ORIG_ERROR ++ICONV_VX_IFUNC (__gconv_transform_internal_ascii) ++ ++ ++/* Convert from internal UCS4 to UCS4 little endian form. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 4 ++# define MIN_NEEDED_TO 4 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (internal_ucs4le_loop) ++# define TO_LOOP ICONV_VX_NAME (internal_ucs4le_loop) /* This is not used. */ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs4le) ++# define ONE_DIRECTION 0 ++ ++static inline int ++__attribute ((always_inline)) ++ICONV_VX_NAME (internal_ucs4le_loop) (struct __gconv_step *step, ++ struct __gconv_step_data *step_data, ++ const unsigned char **inptrp, ++ const unsigned char *inend, ++ unsigned char **outptrp, ++ unsigned char *outend, ++ size_t *irreversible) ++{ ++ const unsigned char *inptr = *inptrp; ++ unsigned char *outptr = *outptrp; ++ int result; ++ size_t len = MIN (inend - inptr, outend - outptr) / 4; ++ size_t loop_count; ++ __asm__ volatile (".machine push\n\t" ++ ".machine \"z13\"\n\t" ++ ".machinemode \"zarch_nohighgprs\"\n\t" ++ CONVERT_32BIT_SIZE_T ([R_LEN]) ++ " bras %[R_LI],1f\n\t" ++ /* Vector permute mask: */ ++ " .long 0x03020100,0x7060504,0x0B0A0908,0x0F0E0D0C\n\t" ++ "1: vl %%v20,0(%[R_LI])\n\t" ++ /* Process 64byte (16char) blocks. */ ++ " srlg %[R_LI],%[R_LEN],4\n\t" ++ " clgije %[R_LI],0,10f\n\t" ++ "0: vlm %%v16,%%v19,0(%[R_IN])\n\t" ++ " vperm %%v16,%%v16,%%v16,%%v20\n\t" ++ " vperm %%v17,%%v17,%%v17,%%v20\n\t" ++ " vperm %%v18,%%v18,%%v18,%%v20\n\t" ++ " vperm %%v19,%%v19,%%v19,%%v20\n\t" ++ " vstm %%v16,%%v19,0(%[R_OUT])\n\t" ++ " la %[R_IN],64(%[R_IN])\n\t" ++ " la %[R_OUT],64(%[R_OUT])\n\t" ++ " brctg %[R_LI],0b\n\t" ++ " llgfr %[R_LEN],%[R_LEN]\n\t" ++ " nilf %[R_LEN],15\n\t" ++ /* Process 16byte (4char) blocks. */ ++ "10: srlg %[R_LI],%[R_LEN],2\n\t" ++ " clgije %[R_LI],0,20f\n\t" ++ "11: vl %%v16,0(%[R_IN])\n\t" ++ " vperm %%v16,%%v16,%%v16,%%v20\n\t" ++ " vst %%v16,0(%[R_OUT])\n\t" ++ " la %[R_IN],16(%[R_IN])\n\t" ++ " la %[R_OUT],16(%[R_OUT])\n\t" ++ " brctg %[R_LI],11b\n\t" ++ " nill %[R_LEN],3\n\t" ++ /* Process <16bytes. */ ++ "20: sll %[R_LEN],2\n\t" ++ " ahi %[R_LEN],-1\n\t" ++ " jl 30f\n\t" ++ " vll %%v16,%[R_LEN],0(%[R_IN])\n\t" ++ " vperm %%v16,%%v16,%%v16,%%v20\n\t" ++ " vstl %%v16,%[R_LEN],0(%[R_OUT])\n\t" ++ " la %[R_IN],1(%[R_LEN],%[R_IN])\n\t" ++ " la %[R_OUT],1(%[R_LEN],%[R_OUT])\n\t" ++ "30: \n\t" ++ ".machine pop" ++ : /* outputs */ [R_OUT] "+a" (outptr) ++ , [R_IN] "+a" (inptr) ++ , [R_LI] "=a" (loop_count) ++ , [R_LEN] "+a" (len) ++ : /* inputs */ ++ : /* clobber list*/ "memory", "cc" ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") ++ ASM_CLOBBER_VR ("v20") ++ ); ++ *inptrp = inptr; ++ *outptrp = outptr; ++ ++ /* Determine the status. */ ++ if (*inptrp == inend) ++ result = __GCONV_EMPTY_INPUT; ++ else if (*outptrp + 4 > outend) ++ result = __GCONV_FULL_OUTPUT; ++ else ++ result = __GCONV_INCOMPLETE_INPUT; ++ ++ return result; ++} ++ ++ICONV_VX_SINGLE (internal_ucs4le_loop) ++# include ++ICONV_VX_IFUNC (__gconv_transform_internal_ucs4le) ++ ++ ++/* Transform from UCS4 to the internal, UCS4-like format. Unlike ++ for the other direction we have to check for correct values here. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 4 ++# define MIN_NEEDED_TO 4 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (ucs4_internal_loop) ++# define TO_LOOP ICONV_VX_NAME (ucs4_internal_loop) /* This is not used. */ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs4_internal) ++# define ONE_DIRECTION 0 ++ ++ ++static inline int ++__attribute ((always_inline)) ++ICONV_VX_NAME (ucs4_internal_loop) (struct __gconv_step *step, ++ struct __gconv_step_data *step_data, ++ const unsigned char **inptrp, ++ const unsigned char *inend, ++ unsigned char **outptrp, ++ unsigned char *outend, ++ size_t *irreversible) ++{ ++ int flags = step_data->__flags; ++ const unsigned char *inptr = *inptrp; ++ unsigned char *outptr = *outptrp; ++ int result; ++ size_t len, loop_count; ++ do ++ { ++ len = MIN (inend - inptr, outend - outptr) / 4; ++ __asm__ volatile (".machine push\n\t" ++ ".machine \"z13\"\n\t" ++ ".machinemode \"zarch_nohighgprs\"\n\t" ++ CONVERT_32BIT_SIZE_T ([R_LEN]) ++ /* Setup to check for ch > 0x7fffffff. */ ++ " larl %[R_LI],9f\n\t" ++ " vlm %%v20,%%v21,0(%[R_LI])\n\t" ++ " srlg %[R_LI],%[R_LEN],2\n\t" ++ " clgije %[R_LI],0,1f\n\t" ++ /* Process 16byte (4char) blocks. */ ++ "0: vl %%v16,0(%[R_IN])\n\t" ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" ++ " jno 10f\n\t" ++ " vst %%v16,0(%[R_OUT])\n\t" ++ " la %[R_IN],16(%[R_IN])\n\t" ++ " la %[R_OUT],16(%[R_OUT])\n\t" ++ " brctg %[R_LI],0b\n\t" ++ " llgfr %[R_LEN],%[R_LEN]\n\t" ++ " nilf %[R_LEN],3\n\t" ++ /* Process <16bytes. */ ++ "1: sll %[R_LEN],2\n\t" ++ " ahik %[R_LI],%[R_LEN],-1\n\t" ++ " jl 20f\n\t" /* No further bytes available. */ ++ " vll %%v16,%[R_LI],0(%[R_IN])\n\t" ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" ++ " vlgvb %[R_LI],%%v22,7\n\t" ++ " clr %[R_LI],%[R_LEN]\n\t" ++ " locgrhe %[R_LI],%[R_LEN]\n\t" ++ " locghihe %[R_LEN],0\n\t" ++ " j 11f\n\t" ++ /* v20: Vector string range compare values. */ ++ "9: .long 0x7fffffff,0x0,0x0,0x0\n\t" ++ /* v21: Vector string range compare control-bits. ++ element 0: >; element 1: =<> (always true) */ ++ " .long 0x20000000,0xE0000000,0x0,0x0\n\t" ++ /* Found a value > 0x7fffffff. */ ++ "10: vlgvb %[R_LI],%%v22,7\n\t" ++ /* Store characters before invalid one. */ ++ "11: aghi %[R_LI],-1\n\t" ++ " jl 20f\n\t" ++ " vstl %%v16,%[R_LI],0(%[R_OUT])\n\t" ++ " la %[R_IN],1(%[R_LI],%[R_IN])\n\t" ++ " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" ++ "20:\n\t" ++ ".machine pop" ++ : /* outputs */ [R_OUT] "+a" (outptr) ++ , [R_IN] "+a" (inptr) ++ , [R_LI] "=a" (loop_count) ++ , [R_LEN] "+d" (len) ++ : /* inputs */ ++ : /* clobber list*/ "memory", "cc" ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v20") ++ ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") ++ ); ++ if (len > 0) ++ { ++ /* The value is too large. We don't try transliteration here since ++ this is not an error because of the lack of possibilities to ++ represent the result. This is a genuine bug in the input since ++ UCS4 does not allow such values. */ ++ if (irreversible == NULL) ++ /* We are transliterating, don't try to correct anything. */ ++ return __GCONV_ILLEGAL_INPUT; ++ ++ if (flags & __GCONV_IGNORE_ERRORS) ++ { ++ /* Just ignore this character. */ ++ ++*irreversible; ++ inptr += 4; ++ continue; ++ } ++ ++ *inptrp = inptr; ++ *outptrp = outptr; ++ return __GCONV_ILLEGAL_INPUT; ++ } ++ } ++ while (len > 0); ++ ++ *inptrp = inptr; ++ *outptrp = outptr; ++ ++ /* Determine the status. */ ++ if (*inptrp == inend) ++ result = __GCONV_EMPTY_INPUT; ++ else if (*outptrp + 4 > outend) ++ result = __GCONV_FULL_OUTPUT; ++ else ++ result = __GCONV_INCOMPLETE_INPUT; ++ ++ return result; ++} ++ ++ICONV_VX_SINGLE (ucs4_internal_loop) ++# include ++ICONV_VX_IFUNC (__gconv_transform_ucs4_internal) ++ ++ ++/* Transform from UCS4-LE to the internal encoding. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 4 ++# define MIN_NEEDED_TO 4 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (ucs4le_internal_loop) ++# define TO_LOOP ICONV_VX_NAME (ucs4le_internal_loop) /* This is not used. */ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs4le_internal) ++# define ONE_DIRECTION 0 ++ ++static inline int ++__attribute ((always_inline)) ++ICONV_VX_NAME (ucs4le_internal_loop) (struct __gconv_step *step, ++ struct __gconv_step_data *step_data, ++ const unsigned char **inptrp, ++ const unsigned char *inend, ++ unsigned char **outptrp, ++ unsigned char *outend, ++ size_t *irreversible) ++{ ++ int flags = step_data->__flags; ++ const unsigned char *inptr = *inptrp; ++ unsigned char *outptr = *outptrp; ++ int result; ++ size_t len, loop_count; ++ do ++ { ++ len = MIN (inend - inptr, outend - outptr) / 4; ++ __asm__ volatile (".machine push\n\t" ++ ".machine \"z13\"\n\t" ++ ".machinemode \"zarch_nohighgprs\"\n\t" ++ CONVERT_32BIT_SIZE_T ([R_LEN]) ++ /* Setup to check for ch > 0x7fffffff. */ ++ " larl %[R_LI],9f\n\t" ++ " vlm %%v20,%%v22,0(%[R_LI])\n\t" ++ " srlg %[R_LI],%[R_LEN],2\n\t" ++ " clgije %[R_LI],0,1f\n\t" ++ /* Process 16byte (4char) blocks. */ ++ "0: vl %%v16,0(%[R_IN])\n\t" ++ " vperm %%v16,%%v16,%%v16,%%v22\n\t" ++ " vstrcfs %%v23,%%v16,%%v20,%%v21\n\t" ++ " jno 10f\n\t" ++ " vst %%v16,0(%[R_OUT])\n\t" ++ " la %[R_IN],16(%[R_IN])\n\t" ++ " la %[R_OUT],16(%[R_OUT])\n\t" ++ " brctg %[R_LI],0b\n\t" ++ " llgfr %[R_LEN],%[R_LEN]\n\t" ++ " nilf %[R_LEN],3\n\t" ++ /* Process <16bytes. */ ++ "1: sll %[R_LEN],2\n\t" ++ " ahik %[R_LI],%[R_LEN],-1\n\t" ++ " jl 20f\n\t" /* No further bytes available. */ ++ " vll %%v16,%[R_LI],0(%[R_IN])\n\t" ++ " vperm %%v16,%%v16,%%v16,%%v22\n\t" ++ " vstrcfs %%v23,%%v16,%%v20,%%v21\n\t" ++ " vlgvb %[R_LI],%%v23,7\n\t" ++ " clr %[R_LI],%[R_LEN]\n\t" ++ " locgrhe %[R_LI],%[R_LEN]\n\t" ++ " locghihe %[R_LEN],0\n\t" ++ " j 11f\n\t" ++ /* v20: Vector string range compare values. */ ++ "9: .long 0x7fffffff,0x0,0x0,0x0\n\t" ++ /* v21: Vector string range compare control-bits. ++ element 0: >; element 1: =<> (always true) */ ++ " .long 0x20000000,0xE0000000,0x0,0x0\n\t" ++ /* v22: Vector permute mask. */ ++ " .long 0x03020100,0x7060504,0x0B0A0908,0x0F0E0D0C\n\t" ++ /* Found a value > 0x7fffffff. */ ++ "10: vlgvb %[R_LI],%%v23,7\n\t" ++ /* Store characters before invalid one. */ ++ "11: aghi %[R_LI],-1\n\t" ++ " jl 20f\n\t" ++ " vstl %%v16,%[R_LI],0(%[R_OUT])\n\t" ++ " la %[R_IN],1(%[R_LI],%[R_IN])\n\t" ++ " la %[R_OUT],1(%[R_LI],%[R_OUT])\n\t" ++ "20:\n\t" ++ ".machine pop" ++ : /* outputs */ [R_OUT] "+a" (outptr) ++ , [R_IN] "+a" (inptr) ++ , [R_LI] "=a" (loop_count) ++ , [R_LEN] "+d" (len) ++ : /* inputs */ ++ : /* clobber list*/ "memory", "cc" ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v20") ++ ASM_CLOBBER_VR ("v21") ASM_CLOBBER_VR ("v22") ++ ASM_CLOBBER_VR ("v23") ++ ); ++ if (len > 0) ++ { ++ /* The value is too large. We don't try transliteration here since ++ this is not an error because of the lack of possibilities to ++ represent the result. This is a genuine bug in the input since ++ UCS4 does not allow such values. */ ++ if (irreversible == NULL) ++ /* We are transliterating, don't try to correct anything. */ ++ return __GCONV_ILLEGAL_INPUT; ++ ++ if (flags & __GCONV_IGNORE_ERRORS) ++ { ++ /* Just ignore this character. */ ++ ++*irreversible; ++ inptr += 4; ++ continue; ++ } ++ ++ *inptrp = inptr; ++ *outptrp = outptr; ++ return __GCONV_ILLEGAL_INPUT; ++ } ++ } ++ while (len > 0); ++ ++ *inptrp = inptr; ++ *outptrp = outptr; ++ ++ /* Determine the status. */ ++ if (*inptrp == inend) ++ result = __GCONV_EMPTY_INPUT; ++ else if (*inptrp + 4 > inend) ++ result = __GCONV_INCOMPLETE_INPUT; ++ else ++ { ++ assert (*outptrp + 4 > outend); ++ result = __GCONV_FULL_OUTPUT; ++ } ++ ++ return result; ++} ++ICONV_VX_SINGLE (ucs4le_internal_loop) ++# include ++ICONV_VX_IFUNC (__gconv_transform_ucs4le_internal) ++ ++/* Convert from UCS2 to the internal (UCS4-like) format. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 2 ++# define MIN_NEEDED_TO 4 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (ucs2_internal_loop) ++# define TO_LOOP ICONV_VX_NAME (ucs2_internal_loop) /* This is not used. */ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs2_internal) ++# define ONE_DIRECTION 1 ++ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT FROM_LOOP ++# define BODY_ORIG_ERROR \ ++ /* Surrogate characters in UCS-2 input are not valid. Reject \ ++ them. (Catching this here is not security relevant.) */ \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (2); ++# define BODY_ORIG \ ++ { \ ++ uint16_t u1 = get16 (inptr); \ ++ \ ++ if (__glibc_unlikely (u1 >= 0xd800 && u1 < 0xe000)) \ ++ { \ ++ BODY_ORIG_ERROR \ ++ } \ ++ \ ++ *((uint32_t *) outptr) = u1; \ ++ outptr += sizeof (uint32_t); \ ++ inptr += 2; \ ++ } ++# define BODY \ ++ { \ ++ size_t len, tmp, tmp2; \ ++ len = MIN ((inend - inptr) / 2, (outend - outptr) / 4); \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_LEN]) \ ++ /* Setup to check for ch >= 0xd800 && ch < 0xe000. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v20,%%v21,0(%[R_TMP])\n\t" \ ++ " srlg %[R_TMP],%[R_LEN],3\n\t" \ ++ " clgije %[R_TMP],0,1f\n\t" \ ++ /* Process 16byte (8char) blocks. */ \ ++ "0: vl %%v16,0(%[R_IN])\n\t" \ ++ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ ++ /* Enlarge UCS2 to UCS4. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " jno 10f\n\t" \ ++ /* Store 32bytes to buf_out. */ \ ++ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP],0b\n\t" \ ++ " llgfr %[R_LEN],%[R_LEN]\n\t" \ ++ " nilf %[R_LEN],7\n\t" \ ++ /* Process <16bytes. */ \ ++ "1: sll %[R_LEN],1\n\t" \ ++ " ahik %[R_TMP],%[R_LEN],-1\n\t" \ ++ " jl 20f\n\t" /* No further bytes available. */ \ ++ " vll %%v16,%[R_TMP],0(%[R_IN])\n\t" \ ++ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ ++ /* Enlarge UCS2 to UCS4. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " clr %[R_TMP],%[R_LEN]\n\t" \ ++ " locgrhe %[R_TMP],%[R_LEN]\n\t" \ ++ " locghihe %[R_LEN],0\n\t" \ ++ " j 11f\n\t" \ ++ /* v20: Vector string range compare values. */ \ ++ "9: .short 0xd800,0xe000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* v21: Vector string range compare control-bits. \ ++ element 0: =>; element 1: < */ \ ++ " .short 0xa000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* Found an element: ch >= 0xd800 && ch < 0xe000 */ \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ "11: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " sll %[R_TMP],1\n\t" \ ++ " lgr %[R_TMP2],%[R_TMP]\n\t" \ ++ " ahi %[R_TMP],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vstl %%v17,%[R_TMP],0(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP],-16\n\t" \ ++ " jl 19f\n\t" \ ++ " vstl %%v18,%[R_TMP],16(%[R_OUT])\n\t" \ ++ "19: la %[R_OUT],0(%[R_TMP2],%[R_OUT])\n\t" \ ++ "20: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_IN] "+a" (inptr) \ ++ , [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=a" (tmp2) \ ++ , [R_LEN] "+d" (len) \ ++ : /* inputs */ \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ); \ ++ if (len > 0) \ ++ { \ ++ /* Found an invalid character at next input-char. */ \ ++ BODY_ORIG_ERROR \ ++ } \ ++ } ++ ++# define LOOP_NEED_FLAGS ++# include ++# include ++# undef BODY_ORIG ++# undef BODY_ORIG_ERROR ++ICONV_VX_IFUNC (__gconv_transform_ucs2_internal) ++ ++/* Convert from UCS2 in other endianness to the internal (UCS4-like) format. */ ++# define DEFINE_INIT 0 ++# define DEFINE_FINI 0 ++# define MIN_NEEDED_FROM 2 ++# define MIN_NEEDED_TO 4 ++# define FROM_DIRECTION 1 ++# define FROM_LOOP ICONV_VX_NAME (ucs2reverse_internal_loop) ++# define TO_LOOP ICONV_VX_NAME (ucs2reverse_internal_loop) /* This is not used.*/ ++# define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_ucs2reverse_internal) ++# define ONE_DIRECTION 1 ++ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT FROM_LOOP ++# define BODY_ORIG_ERROR \ ++ /* Surrogate characters in UCS-2 input are not valid. Reject \ ++ them. (Catching this here is not security relevant.) */ \ ++ if (! ignore_errors_p ()) \ ++ { \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ break; \ ++ } \ ++ inptr += 2; \ ++ ++*irreversible; \ ++ continue; ++ ++# define BODY_ORIG \ ++ { \ ++ uint16_t u1 = bswap_16 (get16 (inptr)); \ ++ \ ++ if (__glibc_unlikely (u1 >= 0xd800 && u1 < 0xe000)) \ ++ { \ ++ BODY_ORIG_ERROR \ ++ } \ ++ \ ++ *((uint32_t *) outptr) = u1; \ ++ outptr += sizeof (uint32_t); \ ++ inptr += 2; \ ++ } ++# define BODY \ ++ { \ ++ size_t len, tmp, tmp2; \ ++ len = MIN ((inend - inptr) / 2, (outend - outptr) / 4); \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_LEN]) \ ++ /* Setup to check for ch >= 0xd800 && ch < 0xe000. */ \ ++ " larl %[R_TMP],9f\n\t" \ ++ " vlm %%v20,%%v22,0(%[R_TMP])\n\t" \ ++ " srlg %[R_TMP],%[R_LEN],3\n\t" \ ++ " clgije %[R_TMP],0,1f\n\t" \ ++ /* Process 16byte (8char) blocks. */ \ ++ "0: vl %%v16,0(%[R_IN])\n\t" \ ++ " vperm %%v16,%%v16,%%v16,%%v22\n\t" \ ++ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ ++ /* Enlarge UCS2 to UCS4. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " jno 10f\n\t" \ ++ /* Store 32bytes to buf_out. */ \ ++ " vstm %%v17,%%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " la %[R_OUT],32(%[R_OUT])\n\t" \ ++ " brctg %[R_TMP],0b\n\t" \ ++ " llgfr %[R_LEN],%[R_LEN]\n\t" \ ++ " nilf %[R_LEN],7\n\t" \ ++ /* Process <16bytes. */ \ ++ "1: sll %[R_LEN],1\n\t" \ ++ " ahik %[R_TMP],%[R_LEN],-1\n\t" \ ++ " jl 20f\n\t" /* No further bytes available. */ \ ++ " vll %%v16,%[R_TMP],0(%[R_IN])\n\t" \ ++ " vperm %%v16,%%v16,%%v16,%%v22\n\t" \ ++ " vstrchs %%v19,%%v16,%%v20,%%v21\n\t" \ ++ /* Enlarge UCS2 to UCS4. */ \ ++ " vuplhh %%v17,%%v16\n\t" \ ++ " vupllh %%v18,%%v16\n\t" \ ++ " vlgvb %[R_TMP],%%v19,7\n\t" \ ++ " clr %[R_TMP],%[R_LEN]\n\t" \ ++ " locgrhe %[R_TMP],%[R_LEN]\n\t" \ ++ " locghihe %[R_LEN],0\n\t" \ ++ " j 11f\n\t" \ ++ /* v20: Vector string range compare values. */ \ ++ "9: .short 0xd800,0xe000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* v21: Vector string range compare control-bits. \ ++ element 0: =>; element 1: < */ \ ++ " .short 0xa000,0x4000,0x0,0x0,0x0,0x0,0x0,0x0\n\t" \ ++ /* v22: Vector permute mask. */ \ ++ " .short 0x0100,0x0302,0x0504,0x0706\n\t" \ ++ " .short 0x0908,0x0b0a,0x0d0c,0x0f0e\n\t" \ ++ /* Found an element: ch >= 0xd800 && ch < 0xe000 */ \ ++ "10: vlgvb %[R_TMP],%%v19,7\n\t" \ ++ "11: la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " sll %[R_TMP],1\n\t" \ ++ " lgr %[R_TMP2],%[R_TMP]\n\t" \ ++ " ahi %[R_TMP],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vstl %%v17,%[R_TMP],0(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP],-16\n\t" \ ++ " jl 19f\n\t" \ ++ " vstl %%v18,%[R_TMP],16(%[R_OUT])\n\t" \ ++ "19: la %[R_OUT],0(%[R_TMP2],%[R_OUT])\n\t" \ ++ "20: \n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_IN] "+a" (inptr) \ ++ , [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=a" (tmp2) \ ++ , [R_LEN] "+d" (len) \ ++ : /* inputs */ \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") \ ++ ); \ ++ if (len > 0) \ ++ { \ ++ /* Found an invalid character at next input-char. */ \ ++ BODY_ORIG_ERROR \ ++ } \ ++ } ++# define LOOP_NEED_FLAGS ++# include ++# include ++# undef BODY_ORIG ++# undef BODY_ORIG_ERROR ++ICONV_VX_IFUNC (__gconv_transform_ucs2reverse_internal) ++ ++/* Convert from the internal (UCS4-like) format to UCS2. */ ++#define DEFINE_INIT 0 ++#define DEFINE_FINI 0 ++#define MIN_NEEDED_FROM 4 ++#define MIN_NEEDED_TO 2 ++#define FROM_DIRECTION 1 ++#define FROM_LOOP ICONV_VX_NAME (internal_ucs2_loop) ++#define TO_LOOP ICONV_VX_NAME (internal_ucs2_loop) /* This is not used. */ ++#define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs2) ++#define ONE_DIRECTION 1 ++ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT FROM_LOOP ++#define BODY_ORIG \ ++ { \ ++ uint32_t val = *((const uint32_t *) inptr); \ ++ \ ++ if (__glibc_unlikely (val >= 0x10000)) \ ++ { \ ++ UNICODE_TAG_HANDLER (val, 4); \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ else if (__glibc_unlikely (val >= 0xd800 && val < 0xe000)) \ ++ { \ ++ /* Surrogate characters in UCS-4 input are not valid. \ ++ We must catch this, because the UCS-2 output might be \ ++ interpreted as UTF-16 by other programs. If we let \ ++ surrogates pass through, attackers could make a security \ ++ hole exploit by synthesizing any desired plane 1-16 \ ++ character. */ \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ if (! ignore_errors_p ()) \ ++ break; \ ++ inptr += 4; \ ++ ++*irreversible; \ ++ continue; \ ++ } \ ++ else \ ++ { \ ++ put16 (outptr, val); \ ++ outptr += sizeof (uint16_t); \ ++ inptr += 4; \ ++ } \ ++ } ++# define BODY \ ++ { \ ++ if (__builtin_expect (inend - inptr < 32, 1) \ ++ || outend - outptr < 16) \ ++ /* Convert remaining bytes with c code. */ \ ++ BODY_ORIG \ ++ else \ ++ { \ ++ /* Convert in 32 byte blocks. */ \ ++ size_t loop_count = (inend - inptr) / 32; \ ++ size_t tmp, tmp2; \ ++ if (loop_count > (outend - outptr) / 16) \ ++ loop_count = (outend - outptr) / 16; \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_LI]) \ ++ " larl %[R_I],3f\n\t" \ ++ " vlm %%v20,%%v23,0(%[R_I])\n\t" \ ++ "0: \n\t" \ ++ " vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ /* Shorten UCS4 to UCS2. */ \ ++ " vpkf %%v18,%%v16,%%v17\n\t" \ ++ " vstrcfs %%v19,%%v16,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ "1: vstrcfs %%v19,%%v17,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ /* Store 16bytes to buf_out. */ \ ++ "2: vst %%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " brctg %[R_LI],0b\n\t" \ ++ " j 20f\n\t" \ ++ /* Setup to check for ch >= 0xd800. (v20, v21) */ \ ++ "3: .long 0xd800,0xd800,0x0,0x0\n\t" \ ++ " .long 0xa0000000,0xa0000000,0x0,0x0\n\t" \ ++ /* Setup to check for ch >= 0xe000 \ ++ && ch < 0x10000. (v22,v23) */ \ ++ " .long 0xe000,0x10000,0x0,0x0\n\t" \ ++ " .long 0xa0000000,0x40000000,0x0,0x0\n\t" \ ++ /* v16 contains only valid chars. Check in v17: \ ++ ch >= 0xe000 && ch <= 0xffff. */ \ ++ "10: vstrcfs %%v19,%%v17,%%v22,%%v23,8\n\t" \ ++ " jo 2b\n\t" /* All ch's in this range, proceed. */ \ ++ " lghi %[R_TMP],16\n\t" \ ++ " j 12f\n\t" \ ++ /* Maybe v16 contains invalid chars. \ ++ Check ch >= 0xe000 && ch <= 0xffff. */ \ ++ "11: vstrcfs %%v19,%%v16,%%v22,%%v23,8\n\t" \ ++ " jo 1b\n\t" /* All ch's in this range, proceed. */ \ ++ " lghi %[R_TMP],0\n\t" \ ++ "12: vlgvb %[R_I],%%v19,7\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " srl %[R_I],1\n\t" \ ++ " ahi %[R_I],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vstl %%v18,%[R_I],0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \ ++ "20:\n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_IN] "+a" (inptr) \ ++ , [R_LI] "+d" (loop_count) \ ++ , [R_I] "=a" (tmp2) \ ++ , [R_TMP] "=d" (tmp) \ ++ : /* inputs */ \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ ++ ); \ ++ if (loop_count > 0) \ ++ { \ ++ /* Found an invalid character at next character. */ \ ++ BODY_ORIG \ ++ } \ ++ } \ ++ } ++#define LOOP_NEED_FLAGS ++#include ++#include ++# undef BODY_ORIG ++ICONV_VX_IFUNC (__gconv_transform_internal_ucs2) ++ ++/* Convert from the internal (UCS4-like) format to UCS2 in other endianness. */ ++#define DEFINE_INIT 0 ++#define DEFINE_FINI 0 ++#define MIN_NEEDED_FROM 4 ++#define MIN_NEEDED_TO 2 ++#define FROM_DIRECTION 1 ++#define FROM_LOOP ICONV_VX_NAME (internal_ucs2reverse_loop) ++#define TO_LOOP ICONV_VX_NAME (internal_ucs2reverse_loop)/* This is not used.*/ ++#define FUNCTION_NAME ICONV_VX_NAME (__gconv_transform_internal_ucs2reverse) ++#define ONE_DIRECTION 1 ++ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT FROM_LOOP ++#define BODY_ORIG \ ++ { \ ++ uint32_t val = *((const uint32_t *) inptr); \ ++ if (__glibc_unlikely (val >= 0x10000)) \ ++ { \ ++ UNICODE_TAG_HANDLER (val, 4); \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ ++ else if (__glibc_unlikely (val >= 0xd800 && val < 0xe000)) \ ++ { \ ++ /* Surrogate characters in UCS-4 input are not valid. \ ++ We must catch this, because the UCS-2 output might be \ ++ interpreted as UTF-16 by other programs. If we let \ ++ surrogates pass through, attackers could make a security \ ++ hole exploit by synthesizing any desired plane 1-16 \ ++ character. */ \ ++ if (! ignore_errors_p ()) \ ++ { \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ break; \ ++ } \ ++ inptr += 4; \ ++ ++*irreversible; \ ++ continue; \ ++ } \ ++ else \ ++ { \ ++ put16 (outptr, bswap_16 (val)); \ ++ outptr += sizeof (uint16_t); \ ++ inptr += 4; \ ++ } \ ++ } ++# define BODY \ ++ { \ ++ if (__builtin_expect (inend - inptr < 32, 1) \ ++ || outend - outptr < 16) \ ++ /* Convert remaining bytes with c code. */ \ ++ BODY_ORIG \ ++ else \ ++ { \ ++ /* Convert in 32 byte blocks. */ \ ++ size_t loop_count = (inend - inptr) / 32; \ ++ size_t tmp, tmp2; \ ++ if (loop_count > (outend - outptr) / 16) \ ++ loop_count = (outend - outptr) / 16; \ ++ __asm__ volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ CONVERT_32BIT_SIZE_T ([R_LI]) \ ++ " larl %[R_I],3f\n\t" \ ++ " vlm %%v20,%%v24,0(%[R_I])\n\t" \ ++ "0: \n\t" \ ++ " vlm %%v16,%%v17,0(%[R_IN])\n\t" \ ++ /* Shorten UCS4 to UCS2 and byteswap. */ \ ++ " vpkf %%v18,%%v16,%%v17\n\t" \ ++ " vperm %%v18,%%v18,%%v18,%%v24\n\t" \ ++ " vstrcfs %%v19,%%v16,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ "1: vstrcfs %%v19,%%v17,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ /* Store 16bytes to buf_out. */ \ ++ "2: vst %%v18,0(%[R_OUT])\n\t" \ ++ " la %[R_IN],32(%[R_IN])\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " brctg %[R_LI],0b\n\t" \ ++ " j 20f\n\t" \ ++ /* Setup to check for ch >= 0xd800. (v20, v21) */ \ ++ "3: .long 0xd800,0xd800,0x0,0x0\n\t" \ ++ " .long 0xa0000000,0xa0000000,0x0,0x0\n\t" \ ++ /* Setup to check for ch >= 0xe000 \ ++ && ch < 0x10000. (v22,v23) */ \ ++ " .long 0xe000,0x10000,0x0,0x0\n\t" \ ++ " .long 0xa0000000,0x40000000,0x0,0x0\n\t" \ ++ /* Vector permute mask (v24) */ \ ++ " .short 0x0100,0x0302,0x0504,0x0706\n\t" \ ++ " .short 0x0908,0x0b0a,0x0d0c,0x0f0e\n\t" \ ++ /* v16 contains only valid chars. Check in v17: \ ++ ch >= 0xe000 && ch <= 0xffff. */ \ ++ "10: vstrcfs %%v19,%%v17,%%v22,%%v23,8\n\t" \ ++ " jo 2b\n\t" /* All ch's in this range, proceed. */ \ ++ " lghi %[R_TMP],16\n\t" \ ++ " j 12f\n\t" \ ++ /* Maybe v16 contains invalid chars. \ ++ Check ch >= 0xe000 && ch <= 0xffff. */ \ ++ "11: vstrcfs %%v19,%%v16,%%v22,%%v23,8\n\t" \ ++ " jo 1b\n\t" /* All ch's in this range, proceed. */ \ ++ " lghi %[R_TMP],0\n\t" \ ++ "12: vlgvb %[R_I],%%v19,7\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " srl %[R_I],1\n\t" \ ++ " ahi %[R_I],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vstl %%v18,%[R_I],0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],1(%[R_I],%[R_OUT])\n\t" \ ++ "20:\n\t" \ ++ ".machine pop" \ ++ : /* outputs */ [R_OUT] "+a" (outptr) \ ++ , [R_IN] "+a" (inptr) \ ++ , [R_LI] "+d" (loop_count) \ ++ , [R_I] "=a" (tmp2) \ ++ , [R_TMP] "=d" (tmp) \ ++ : /* inputs */ \ ++ : /* clobber list*/ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ ++ ASM_CLOBBER_VR ("v24") \ ++ ); \ ++ if (loop_count > 0) \ ++ { \ ++ /* Found an invalid character at next character. */ \ ++ BODY_ORIG \ ++ } \ ++ } \ ++ } ++#define LOOP_NEED_FLAGS ++#include ++#include ++# undef BODY_ORIG ++ICONV_VX_IFUNC (__gconv_transform_internal_ucs2reverse) ++ ++ ++#else ++/* Generate the internal transformations without ifunc if build environment ++ lacks vector support. Instead simply include the common version. */ ++# include ++#endif /* !defined HAVE_S390_VX_ASM_SUPPORT */ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-5.patch b/SOURCES/glibc-rh1380680-5.patch new file mode 100644 index 00000000..bbca3d6f --- /dev/null +++ b/SOURCES/glibc-rh1380680-5.patch @@ -0,0 +1,150 @@ +From 832572eac8a661d25efe0f2bcc6a861e2c29c3b8 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 15:50:46 +0100 +Subject: [PATCH 05/17] S390: Optimize iso-8859-1 to ibm037 iconv-module. + +Upstream commit 81c6380887c6d62c56e5f0f85a241f759f58b2fd + +This patch reworks the s390 specific module which used the z900 +translate one to one instruction. Now the g5 translate instruction is used, +because it outperforms the troo instruction. + +ChangeLog: + + * sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c (TROO_LOOP): + Rename to TR_LOOP and usage of tr instead of troo instruction. +--- + sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c | 95 +++++++++++++++++----------- + 1 file changed, 57 insertions(+), 38 deletions(-) + +diff --git a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c b/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c +index 58641f5..3b63e6a 100644 +--- a/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c ++++ b/sysdeps/s390/s390-64/iso-8859-1_cp037_z900.c +@@ -1,8 +1,7 @@ + /* Conversion between ISO 8859-1 and IBM037. + +- This module uses the Z900 variant of the Translate One To One +- instruction. +- Copyright (C) 1997-2009 Free Software Foundation, Inc. ++ This module uses the translate instruction. ++ Copyright (C) 1997-2016 Free Software Foundation, Inc. + + Author: Andreas Krebbel + Based on the work by Ulrich Drepper , 1997. +@@ -176,50 +175,70 @@ __attribute__ ((aligned (8))) = + #define MIN_NEEDED_FROM 1 + #define MIN_NEEDED_TO 1 + +-/* The Z900 variant of troo forces us to always specify a test +- character which ends the translation. So if we run into the +- situation where the translation has been interrupted due to the +- test character we translate the character by hand and jump back +- into the instruction. */ +- +-#define TROO_LOOP(TABLE) \ ++#define TR_LOOP(TABLE) \ + { \ +- register const unsigned char test asm ("0") = 0; \ +- register const unsigned char *pTable asm ("1") = TABLE; \ +- register unsigned char *pOutput asm ("2") = outptr; \ +- register uint64_t length asm ("3"); \ +- const unsigned char* pInput = inptr; \ +- uint64_t tmp; \ +- \ +- length = (inend - inptr < outend - outptr \ +- ? inend - inptr : outend - outptr); \ ++ size_t length = (inend - inptr < outend - outptr \ ++ ? inend - inptr : outend - outptr); \ + \ +- asm volatile ("0: \n\t" \ +- " troo %0,%1 \n\t" \ +- " jz 1f \n\t" \ +- " jo 0b \n\t" \ +- " llgc %3,0(%1) \n\t" \ +- " la %3,0(%3,%4) \n\t" \ +- " mvc 0(1,%0),0(%3) \n\t" \ +- " aghi %1,1 \n\t" \ +- " aghi %0,1 \n\t" \ +- " aghi %2,-1 \n\t" \ +- " j 0b \n\t" \ +- "1: \n" \ ++ /* Process in 256 byte blocks. */ \ ++ if (__builtin_expect (length >= 256, 0)) \ ++ { \ ++ size_t blocks = length / 256; \ ++ __asm__ __volatile__("0: mvc 0(256,%[R_OUT]),0(%[R_IN])\n\t" \ ++ " tr 0(256,%[R_OUT]),0(%[R_TBL])\n\t" \ ++ " la %[R_IN],256(%[R_IN])\n\t" \ ++ " la %[R_OUT],256(%[R_OUT])\n\t" \ ++ " brctg %[R_LI],0b\n\t" \ ++ : /* outputs */ [R_IN] "+a" (inptr) \ ++ , [R_OUT] "+a" (outptr), [R_LI] "+d" (blocks) \ ++ : /* inputs */ [R_TBL] "a" (TABLE) \ ++ : /* clobber list */ "memory" \ ++ ); \ ++ length = length % 256; \ ++ } \ + \ +- : "+a" (pOutput), "+a" (pInput), "+d" (length), "=&a" (tmp) \ +- : "a" (pTable), "d" (test) \ +- : "cc"); \ ++ /* Process remaining 0...248 bytes in 8byte blocks. */ \ ++ if (length >= 8) \ ++ { \ ++ size_t blocks = length / 8; \ ++ for (int i = 0; i < blocks; i++) \ ++ { \ ++ outptr[0] = TABLE[inptr[0]]; \ ++ outptr[1] = TABLE[inptr[1]]; \ ++ outptr[2] = TABLE[inptr[2]]; \ ++ outptr[3] = TABLE[inptr[3]]; \ ++ outptr[4] = TABLE[inptr[4]]; \ ++ outptr[5] = TABLE[inptr[5]]; \ ++ outptr[6] = TABLE[inptr[6]]; \ ++ outptr[7] = TABLE[inptr[7]]; \ ++ inptr += 8; \ ++ outptr += 8; \ ++ } \ ++ length = length % 8; \ ++ } \ + \ +- inptr = pInput; \ +- outptr = pOutput; \ ++ /* Process remaining 0...7 bytes. */ \ ++ switch (length) \ ++ { \ ++ case 7: outptr[6] = TABLE[inptr[6]]; \ ++ case 6: outptr[5] = TABLE[inptr[5]]; \ ++ case 5: outptr[4] = TABLE[inptr[4]]; \ ++ case 4: outptr[3] = TABLE[inptr[3]]; \ ++ case 3: outptr[2] = TABLE[inptr[2]]; \ ++ case 2: outptr[1] = TABLE[inptr[1]]; \ ++ case 1: outptr[0] = TABLE[inptr[0]]; \ ++ case 0: break; \ ++ } \ ++ inptr += length; \ ++ outptr += length; \ + } + ++ + /* First define the conversion function from ISO 8859-1 to CP037. */ + #define MIN_NEEDED_INPUT MIN_NEEDED_FROM + #define MIN_NEEDED_OUTPUT MIN_NEEDED_TO + #define LOOPFCT FROM_LOOP +-#define BODY TROO_LOOP (table_iso8859_1_to_cp037) ++#define BODY TR_LOOP (table_iso8859_1_to_cp037) + + #include + +@@ -228,7 +247,7 @@ __attribute__ ((aligned (8))) = + #define MIN_NEEDED_INPUT MIN_NEEDED_TO + #define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM + #define LOOPFCT TO_LOOP +-#define BODY TROO_LOOP (table_cp037_iso8859_1); ++#define BODY TR_LOOP (table_cp037_iso8859_1); + + #include + +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-6.patch b/SOURCES/glibc-rh1380680-6.patch new file mode 100644 index 00000000..9c23038e --- /dev/null +++ b/SOURCES/glibc-rh1380680-6.patch @@ -0,0 +1,319 @@ +From 6806b6f3b4870204737e5d465bab2fdbc1c15de0 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:03:46 +0100 +Subject: [PATCH 06/17] Use glibc_likely instead __builtin_expect. + +Upstream commit a1ffb40e32741f992c743e7b16c061fefa3747ac + +This part is a prerequirement for the s390 iconv patches. +--- + sysdeps/s390/s390-64/utf16-utf32-z9.c | 10 +++++----- + sysdeps/s390/s390-64/utf8-utf16-z9.c | 26 +++++++++++++------------- + sysdeps/s390/s390-64/utf8-utf32-z9.c | 32 ++++++++++++++++---------------- + 3 files changed, 34 insertions(+), 34 deletions(-) + +diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c +index 9eaa1a5..94a1a33 100644 +--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf16-utf32-z9.c +@@ -54,7 +54,7 @@ + if (dir == to_utf16) \ + { \ + /* Emit the UTF-16 Byte Order Mark. */ \ +- if (__builtin_expect (outbuf + 2 > outend, 0)) \ ++ if (__glibc_unlikely (outbuf + 2 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put16u (outbuf, BOM_UTF16); \ +@@ -63,7 +63,7 @@ + else \ + { \ + /* Emit the UTF-32 Byte Order Mark. */ \ +- if (__builtin_expect (outbuf + 4 > outend, 0)) \ ++ if (__glibc_unlikely (outbuf + 4 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put32u (outbuf, BOM_UTF32); \ +@@ -236,13 +236,13 @@ gconv_end (struct __gconv_step *data) + { \ + /* An isolated low-surrogate was found. This has to be \ + considered ill-formed. */ \ +- if (__builtin_expect (u1 >= 0xdc00, 0)) \ ++ if (__glibc_unlikely (u1 >= 0xdc00)) \ + { \ + STANDARD_FROM_LOOP_ERR_HANDLER (2); \ + } \ + /* It's a surrogate character. At least the first word says \ + it is. */ \ +- if (__builtin_expect (inptr + 4 > inend, 0)) \ ++ if (__glibc_unlikely (inptr + 4 > inend)) \ + { \ + /* We don't have enough input for another complete input \ + character. */ \ +@@ -306,7 +306,7 @@ gconv_end (struct __gconv_step *data) + uint16_t out; \ + \ + /* Generate a surrogate character. */ \ +- if (__builtin_expect (outptr + 4 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +index 9f59177..8e0515c 100644 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c +@@ -50,7 +50,7 @@ + && data->__invocation_counter == 0) \ + { \ + /* Emit the UTF-16 Byte Order Mark. */ \ +- if (__builtin_expect (outbuf + 2 > outend, 0)) \ ++ if (__glibc_unlikely (outbuf + 2 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put16u (outbuf, BOM_UTF16); \ +@@ -197,7 +197,7 @@ gconv_end (struct __gconv_step *data) + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ +- if (__builtin_expect (inptr + i == inend, 1)) \ ++ if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +@@ -210,7 +210,7 @@ gconv_end (struct __gconv_step *data) + /* Next input byte. */ \ + uint16_t ch = *inptr; \ + \ +- if (__builtin_expect (ch < 0x80, 1)) \ ++ if (__glibc_likely (ch < 0x80)) \ + { \ + /* One byte sequence. */ \ + ++inptr; \ +@@ -228,13 +228,13 @@ gconv_end (struct __gconv_step *data) + cnt = 2; \ + ch &= 0x1f; \ + } \ +- else if (__builtin_expect ((ch & 0xf0) == 0xe0, 1)) \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ +- else if (__builtin_expect ((ch & 0xf8) == 0xf0, 1)) \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ +@@ -255,7 +255,7 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } \ + \ +- if (__builtin_expect (inptr + cnt > inend, 0)) \ ++ if (__glibc_unlikely (inptr + cnt > inend)) \ + { \ + /* We don't have enough input. But before we report \ + that check that all the bytes are correct. */ \ +@@ -263,7 +263,7 @@ gconv_end (struct __gconv_step *data) + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ +- if (__builtin_expect (inptr + i == inend, 1)) \ ++ if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +@@ -278,7 +278,7 @@ gconv_end (struct __gconv_step *data) + low) are needed. */ \ + uint16_t zabcd, high, low; \ + \ +- if (__builtin_expect (outptr + 4 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -368,7 +368,7 @@ gconv_end (struct __gconv_step *data) + \ + uint16_t c = get16 (inptr); \ + \ +- if (__builtin_expect (c <= 0x007f, 1)) \ ++ if (__glibc_likely (c <= 0x007f)) \ + { \ + /* Single byte UTF-8 char. */ \ + *outptr = c & 0xff; \ +@@ -378,7 +378,7 @@ gconv_end (struct __gconv_step *data) + { \ + /* Two byte UTF-8 char. */ \ + \ +- if (__builtin_expect (outptr + 2 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 2 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -397,7 +397,7 @@ gconv_end (struct __gconv_step *data) + { \ + /* Three byte UTF-8 char. */ \ + \ +- if (__builtin_expect (outptr + 3 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 3 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -419,14 +419,14 @@ gconv_end (struct __gconv_step *data) + /* Four byte UTF-8 char. */ \ + uint16_t low, uvwxy; \ + \ +- if (__builtin_expect (outptr + 4 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + inptr += 2; \ +- if (__builtin_expect (inptr + 2 > inend, 0)) \ ++ if (__glibc_unlikely (inptr + 2 > inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c +index a807980..c657a38 100644 +--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf32-z9.c +@@ -52,7 +52,7 @@ + && data->__invocation_counter == 0) \ + { \ + /* Emit the Byte Order Mark. */ \ +- if (__builtin_expect (outbuf + 4 > outend, 0)) \ ++ if (__glibc_unlikely (outbuf + 4 > outend)) \ + return __GCONV_FULL_OUTPUT; \ + \ + put32u (outbuf, BOM); \ +@@ -201,7 +201,7 @@ gconv_end (struct __gconv_step *data) + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ +- if (__builtin_expect (inptr + i == inend, 1)) \ ++ if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +@@ -214,7 +214,7 @@ gconv_end (struct __gconv_step *data) + /* Next input byte. */ \ + uint32_t ch = *inptr; \ + \ +- if (__builtin_expect (ch < 0x80, 1)) \ ++ if (__glibc_likely (ch < 0x80)) \ + { \ + /* One byte sequence. */ \ + ++inptr; \ +@@ -232,25 +232,25 @@ gconv_end (struct __gconv_step *data) + cnt = 2; \ + ch &= 0x1f; \ + } \ +- else if (__builtin_expect ((ch & 0xf0) == 0xe0, 1)) \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ +- else if (__builtin_expect ((ch & 0xf8) == 0xf0, 1)) \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ + ch &= 0x07; \ + } \ +- else if (__builtin_expect ((ch & 0xfc) == 0xf8, 1)) \ ++ else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ + { \ + /* We expect five bytes. */ \ + cnt = 5; \ + ch &= 0x03; \ + } \ +- else if (__builtin_expect ((ch & 0xfe) == 0xfc, 1)) \ ++ else if (__glibc_likely ((ch & 0xfe) == 0xfc)) \ + { \ + /* We expect six bytes. */ \ + cnt = 6; \ +@@ -271,7 +271,7 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } \ + \ +- if (__builtin_expect (inptr + cnt > inend, 0)) \ ++ if (__glibc_unlikely (inptr + cnt > inend)) \ + { \ + /* We don't have enough input. But before we report \ + that check that all the bytes are correct. */ \ +@@ -279,7 +279,7 @@ gconv_end (struct __gconv_step *data) + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ +- if (__builtin_expect (inptr + i == inend, 1)) \ ++ if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +@@ -338,19 +338,19 @@ gconv_end (struct __gconv_step *data) + cnt = 2; \ + ch &= 0x1f; \ + } \ +- else if (__builtin_expect ((ch & 0xf0) == 0xe0, 1)) \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ +- else if (__builtin_expect ((ch & 0xf8) == 0xf0, 1)) \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ + ch &= 0x07; \ + } \ +- else if (__builtin_expect ((ch & 0xfc) == 0xf8, 1)) \ ++ else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ + { \ + /* We expect five bytes. */ \ + cnt = 5; \ +@@ -431,7 +431,7 @@ gconv_end (struct __gconv_step *data) + \ + uint32_t wc = *((const uint32_t *) inptr); \ + \ +- if (__builtin_expect (wc <= 0x7f, 1)) \ ++ if (__glibc_likely (wc <= 0x7f)) \ + { \ + /* Single UTF-8 char. */ \ + *outptr = (uint8_t)wc; \ +@@ -440,7 +440,7 @@ gconv_end (struct __gconv_step *data) + else if (wc <= 0x7ff) \ + { \ + /* Two UTF-8 chars. */ \ +- if (__builtin_expect (outptr + 2 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 2 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -458,7 +458,7 @@ gconv_end (struct __gconv_step *data) + else if (wc <= 0xffff) \ + { \ + /* Three UTF-8 chars. */ \ +- if (__builtin_expect (outptr + 3 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 3 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -478,7 +478,7 @@ gconv_end (struct __gconv_step *data) + else if (wc <= 0x10ffff) \ + { \ + /* Four UTF-8 chars. */ \ +- if (__builtin_expect (outptr + 4 > outend, 0)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-7.patch b/SOURCES/glibc-rh1380680-7.patch new file mode 100644 index 00000000..ef7e42e1 --- /dev/null +++ b/SOURCES/glibc-rh1380680-7.patch @@ -0,0 +1,62 @@ +From d2cd5e641efe08a4f5f467ec16297a704a391e81 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:06:01 +0100 +Subject: [PATCH 07/17] S390: Fix remaining ONE_DIRECTION warning messages + +upstream commit f349489e7e5b5341a9c1a590e9a41c2e07d3bdbb + +This patch fixes the remaining ONE_DIRECTION warnings for s390 specific conversions. +It defines ONE_DIRECTION to 0 like the patch from Steve Ellcey: +https://www.sourceware.org/ml/libc-alpha/2014-05/msg00039.html + + Changelog: + * sysdeps/s390/s390-64/utf16-utf32-z9.c + (ONE_DIRECTION): Define. + * sysdeps/s390/s390-64/utf8-utf16-z9.c + (ONE_DIRECTION): Define. + * sysdeps/s390/s390-64/utf8-utf32-z9.c + (ONE_DIRECTION): Define. +--- + sysdeps/s390/s390-64/utf16-utf32-z9.c | 1 + + sysdeps/s390/s390-64/utf8-utf16-z9.c | 1 + + sysdeps/s390/s390-64/utf8-utf32-z9.c | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c +index 94a1a33..ddc42fe 100644 +--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf16-utf32-z9.c +@@ -44,6 +44,7 @@ + #define FROM_LOOP from_utf16_loop + #define TO_LOOP to_utf16_loop + #define FROM_DIRECTION (dir == from_utf16) ++#define ONE_DIRECTION 0 + #define PREPARE_LOOP \ + enum direction dir = ((struct utf16_data *) step->__data)->dir; \ + int emit_bom = ((struct utf16_data *) step->__data)->emit_bom; \ +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +index 8e0515c..2c2d92c 100644 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c +@@ -42,6 +42,7 @@ + #define FROM_LOOP from_utf8_loop + #define TO_LOOP to_utf8_loop + #define FROM_DIRECTION (dir == from_utf8) ++#define ONE_DIRECTION 0 + #define PREPARE_LOOP \ + enum direction dir = ((struct utf8_data *) step->__data)->dir; \ + int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ +diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c +index c657a38..c582155 100644 +--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf32-z9.c +@@ -44,6 +44,7 @@ + #define FROM_LOOP from_utf8_loop + #define TO_LOOP to_utf8_loop + #define FROM_DIRECTION (dir == from_utf8) ++#define ONE_DIRECTION 0 + #define PREPARE_LOOP \ + enum direction dir = ((struct utf8_data *) step->__data)->dir; \ + int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-8.patch b/SOURCES/glibc-rh1380680-8.patch new file mode 100644 index 00000000..af71f9f5 --- /dev/null +++ b/SOURCES/glibc-rh1380680-8.patch @@ -0,0 +1,139 @@ +From a6e4fa635fea4576c65747cc4b9e3a1fe9c9911f Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:12:24 +0100 +Subject: [PATCH 08/17] S390: Use __asm__ instead of asm. + +upstream commit 31cf39421bae23ffc7b6c6a229e14f8faa41608f + +This part is a prerequirement for the s390 iconv patches. +--- + sysdeps/s390/s390-64/utf16-utf32-z9.c | 28 ++++++++++++++-------------- + sysdeps/s390/s390-64/utf8-utf16-z9.c | 28 ++++++++++++++-------------- + sysdeps/s390/s390-64/utf8-utf32-z9.c | 28 ++++++++++++++-------------- + 3 files changed, 42 insertions(+), 42 deletions(-) + +diff --git a/sysdeps/s390/s390-64/utf16-utf32-z9.c b/sysdeps/s390/s390-64/utf16-utf32-z9.c +index ddc42fe..e6a033d 100644 +--- a/sysdeps/s390/s390-64/utf16-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf16-utf32-z9.c +@@ -163,22 +163,22 @@ gconv_end (struct __gconv_step *data) + directions. */ + #define HARDWARE_CONVERT(INSTRUCTION) \ + { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register unsigned long long inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register unsigned long long outlen asm("11") = outend - outptr; \ ++ register const unsigned char* pInput __asm__ ("8") = inptr; \ ++ register unsigned long long inlen __asm__ ("9") = inend - inptr; \ ++ register unsigned char* pOutput __asm__ ("10") = outptr; \ ++ register unsigned long long outlen __asm__("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- asm volatile (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ ++ __asm__ volatile (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ +diff --git a/sysdeps/s390/s390-64/utf8-utf16-z9.c b/sysdeps/s390/s390-64/utf8-utf16-z9.c +index 2c2d92c..6dad1c2 100644 +--- a/sysdeps/s390/s390-64/utf8-utf16-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf16-z9.c +@@ -145,22 +145,22 @@ gconv_end (struct __gconv_step *data) + directions. */ + #define HARDWARE_CONVERT(INSTRUCTION) \ + { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register unsigned long long inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register unsigned long long outlen asm("11") = outend - outptr; \ ++ register const unsigned char* pInput __asm__ ("8") = inptr; \ ++ register unsigned long long inlen __asm__ ("9") = inend - inptr; \ ++ register unsigned char* pOutput __asm__ ("10") = outptr; \ ++ register unsigned long long outlen __asm__("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- asm volatile (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ ++ __asm__ volatile (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ +diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c +index c582155..721279e 100644 +--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf32-z9.c +@@ -149,22 +149,22 @@ gconv_end (struct __gconv_step *data) + directions. */ + #define HARDWARE_CONVERT(INSTRUCTION) \ + { \ +- register const unsigned char* pInput asm ("8") = inptr; \ +- register unsigned long long inlen asm ("9") = inend - inptr; \ +- register unsigned char* pOutput asm ("10") = outptr; \ +- register unsigned long long outlen asm("11") = outend - outptr; \ ++ register const unsigned char* pInput __asm__ ("8") = inptr; \ ++ register unsigned long long inlen __asm__ ("9") = inend - inptr; \ ++ register unsigned char* pOutput __asm__ ("10") = outptr; \ ++ register unsigned long long outlen __asm__("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- asm volatile (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ ++ __asm__ volatile (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1380680-9.patch b/SOURCES/glibc-rh1380680-9.patch new file mode 100644 index 00000000..3ed8edb2 --- /dev/null +++ b/SOURCES/glibc-rh1380680-9.patch @@ -0,0 +1,839 @@ +From 835c3bf23a119a7fcb8c70734d4fdf49461d8195 Mon Sep 17 00:00:00 2001 +From: Stefan Liebler +Date: Mon, 7 Nov 2016 16:14:07 +0100 +Subject: [PATCH 09/17] S390: Optimize utf8-utf32 module. + +Upstream commit 421c5278d83e72740150259960a431706ac343f9 + +This patch reworks the s390 specific module to convert between utf8 and utf32. +Now ifunc is used to choose either the c or etf3eh (with convert utf +instruction) variants at runtime. +Furthermore a new vector variant for z13 is introduced which will be build +and chosen if vector support is available at build / runtime. +The vector variants optimize input of 1byte utf8 characters. The convert utf +instruction is used if a multibyte utf8 character is found. + +This patch also fixes some whitespace errors. The c variants are rejecting +UTF-16 surrogates and values above 0x10ffff now. +Furthermore, the etf3eh variants are handling the "UTF-xx//IGNORE" case now. +Before they ignored the ignore-case and always stopped at an error. + +ChangeLog: + + * sysdeps/s390/s390-64/utf8-utf32-z9.c: Use ifunc to select c, etf3eh + or new vector loop-variant. +--- + sysdeps/s390/s390-64/utf8-utf32-z9.c | 664 +++++++++++++++++++++++++---------- + 1 file changed, 480 insertions(+), 184 deletions(-) + +diff --git a/sysdeps/s390/s390-64/utf8-utf32-z9.c b/sysdeps/s390/s390-64/utf8-utf32-z9.c +index 721279e..1ce5ac5 100644 +--- a/sysdeps/s390/s390-64/utf8-utf32-z9.c ++++ b/sysdeps/s390/s390-64/utf8-utf32-z9.c +@@ -30,35 +30,25 @@ + #include + #include + +-/* UTF-32 big endian byte order mark. */ +-#define BOM 0x0000feffu ++#if defined HAVE_S390_VX_GCC_SUPPORT ++# define ASM_CLOBBER_VR(NR) , NR ++#else ++# define ASM_CLOBBER_VR(NR) ++#endif + ++/* Defines for skeleton.c. */ + #define DEFINE_INIT 0 + #define DEFINE_FINI 0 +-/* These definitions apply to the UTF-8 to UTF-32 direction. The +- software implementation for UTF-8 still supports multibyte +- characters up to 6 bytes whereas the hardware variant does not. */ + #define MIN_NEEDED_FROM 1 + #define MAX_NEEDED_FROM 6 + #define MIN_NEEDED_TO 4 +-#define FROM_LOOP from_utf8_loop +-#define TO_LOOP to_utf8_loop ++#define FROM_LOOP __from_utf8_loop ++#define TO_LOOP __to_utf8_loop + #define FROM_DIRECTION (dir == from_utf8) + #define ONE_DIRECTION 0 +-#define PREPARE_LOOP \ +- enum direction dir = ((struct utf8_data *) step->__data)->dir; \ +- int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ +- \ +- if (emit_bom && !data->__internal_use \ +- && data->__invocation_counter == 0) \ +- { \ +- /* Emit the Byte Order Mark. */ \ +- if (__glibc_unlikely (outbuf + 4 > outend)) \ +- return __GCONV_FULL_OUTPUT; \ +- \ +- put32u (outbuf, BOM); \ +- outbuf += 4; \ +- } ++ ++/* UTF-32 big endian byte order mark. */ ++#define BOM 0x0000feffu + + /* Direction of the transformation. */ + enum direction +@@ -155,16 +145,16 @@ gconv_end (struct __gconv_step *data) + register unsigned long long outlen __asm__("11") = outend - outptr; \ + uint64_t cc = 0; \ + \ +- __asm__ volatile (".machine push \n\t" \ +- ".machine \"z9-109\" \n\t" \ +- "0: " INSTRUCTION " \n\t" \ +- ".machine pop \n\t" \ +- " jo 0b \n\t" \ +- " ipm %2 \n" \ +- : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ +- "+d" (outlen), "+d" (inlen) \ +- : \ +- : "cc", "memory"); \ ++ __asm__ __volatile__ (".machine push \n\t" \ ++ ".machine \"z9-109\" \n\t" \ ++ "0: " INSTRUCTION " \n\t" \ ++ ".machine pop \n\t" \ ++ " jo 0b \n\t" \ ++ " ipm %2 \n" \ ++ : "+a" (pOutput), "+a" (pInput), "+d" (cc), \ ++ "+d" (outlen), "+d" (inlen) \ ++ : \ ++ : "cc", "memory"); \ + \ + inptr = pInput; \ + outptr = pOutput; \ +@@ -173,49 +163,150 @@ gconv_end (struct __gconv_step *data) + if (cc == 1) \ + { \ + result = __GCONV_FULL_OUTPUT; \ +- break; \ + } \ + else if (cc == 2) \ + { \ + result = __GCONV_ILLEGAL_INPUT; \ +- break; \ + } \ + } + ++#define PREPARE_LOOP \ ++ enum direction dir = ((struct utf8_data *) step->__data)->dir; \ ++ int emit_bom = ((struct utf8_data *) step->__data)->emit_bom; \ ++ \ ++ if (emit_bom && !data->__internal_use \ ++ && data->__invocation_counter == 0) \ ++ { \ ++ /* Emit the Byte Order Mark. */ \ ++ if (__glibc_unlikely (outbuf + 4 > outend)) \ ++ return __GCONV_FULL_OUTPUT; \ ++ \ ++ put32u (outbuf, BOM); \ ++ outbuf += 4; \ ++ } ++ + /* Conversion function from UTF-8 to UTF-32 internal/BE. */ + +-#define MIN_NEEDED_INPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_INPUT MAX_NEEDED_FROM +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO +-#define LOOPFCT FROM_LOOP +-/* The software routine is copied from gconv_simple.c. */ +-#define BODY \ ++#define STORE_REST_COMMON \ ++ { \ ++ /* We store the remaining bytes while converting them into the UCS4 \ ++ format. We can assume that the first byte in the buffer is \ ++ correct and that it requires a larger number of bytes than there \ ++ are in the input buffer. */ \ ++ wint_t ch = **inptrp; \ ++ size_t cnt, r; \ ++ \ ++ state->__count = inend - *inptrp; \ ++ \ ++ assert (ch != 0xc0 && ch != 0xc1); \ ++ if (ch >= 0xc2 && ch < 0xe0) \ ++ { \ ++ /* We expect two bytes. The first byte cannot be 0xc0 or \ ++ 0xc1, otherwise the wide character could have been \ ++ represented using a single byte. */ \ ++ cnt = 2; \ ++ ch &= 0x1f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ ++ { \ ++ /* We expect three bytes. */ \ ++ cnt = 3; \ ++ ch &= 0x0f; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ ++ { \ ++ /* We expect four bytes. */ \ ++ cnt = 4; \ ++ ch &= 0x07; \ ++ } \ ++ else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ ++ { \ ++ /* We expect five bytes. */ \ ++ cnt = 5; \ ++ ch &= 0x03; \ ++ } \ ++ else \ ++ { \ ++ /* We expect six bytes. */ \ ++ cnt = 6; \ ++ ch &= 0x01; \ ++ } \ ++ \ ++ /* The first byte is already consumed. */ \ ++ r = cnt - 1; \ ++ while (++(*inptrp) < inend) \ ++ { \ ++ ch <<= 6; \ ++ ch |= **inptrp & 0x3f; \ ++ --r; \ ++ } \ ++ \ ++ /* Shift for the so far missing bytes. */ \ ++ ch <<= r * 6; \ ++ \ ++ /* Store the number of bytes expected for the entire sequence. */ \ ++ state->__count |= cnt << 8; \ ++ \ ++ /* Store the value. */ \ ++ state->__value.__wch = ch; \ ++ } ++ ++#define UNPACK_BYTES_COMMON \ ++ { \ ++ static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \ ++ wint_t wch = state->__value.__wch; \ ++ size_t ntotal = state->__count >> 8; \ ++ \ ++ inlen = state->__count & 255; \ ++ \ ++ bytebuf[0] = inmask[ntotal - 2]; \ ++ \ ++ do \ ++ { \ ++ if (--ntotal < inlen) \ ++ bytebuf[ntotal] = 0x80 | (wch & 0x3f); \ ++ wch >>= 6; \ ++ } \ ++ while (ntotal > 1); \ ++ \ ++ bytebuf[0] |= wch; \ ++ } ++ ++#define CLEAR_STATE_COMMON \ ++ state->__count = 0 ++ ++#define BODY_FROM_HW(ASM) \ + { \ +- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ +- { \ +- HARDWARE_CONVERT ("cu14 %0, %1, 1"); \ ++ ASM; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ + \ +- if (inptr != inend) \ +- { \ +- int i; \ +- for (i = 1; inptr + i < inend; ++i) \ +- if ((inptr[i] & 0xc0) != 0x80) \ +- break; \ ++ int i; \ ++ for (i = 1; inptr + i < inend && i < 5; ++i) \ ++ if ((inptr[i] & 0xc0) != 0x80) \ ++ break; \ + \ +- if (__glibc_likely (inptr + i == inend)) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- STANDARD_FROM_LOOP_ERR_HANDLER (i); \ +- } \ +- continue; \ ++ if (__glibc_likely (inptr + i == inend \ ++ && result == __GCONV_EMPTY_INPUT)) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ + } \ +- \ ++ STANDARD_FROM_LOOP_ERR_HANDLER (i); \ ++ } ++ ++/* This hardware routine uses the Convert UTF8 to UTF32 (cu14) instruction. */ ++#define BODY_FROM_ETF3EH BODY_FROM_HW (HARDWARE_CONVERT ("cu14 %0, %1, 1")) ++ ++ ++/* The software routine is copied from gconv_simple.c. */ ++#define BODY_FROM_C \ ++ { \ + /* Next input byte. */ \ + uint32_t ch = *inptr; \ + \ +- if (__glibc_likely (ch < 0x80)) \ ++ if (__glibc_likely (ch < 0x80)) \ + { \ + /* One byte sequence. */ \ + ++inptr; \ +@@ -233,30 +324,18 @@ gconv_end (struct __gconv_step *data) + cnt = 2; \ + ch &= 0x1f; \ + } \ +- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ ++ else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ + { \ + /* We expect three bytes. */ \ + cnt = 3; \ + ch &= 0x0f; \ + } \ +- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ ++ else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ + { \ + /* We expect four bytes. */ \ + cnt = 4; \ + ch &= 0x07; \ + } \ +- else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ +- { \ +- /* We expect five bytes. */ \ +- cnt = 5; \ +- ch &= 0x03; \ +- } \ +- else if (__glibc_likely ((ch & 0xfe) == 0xfc)) \ +- { \ +- /* We expect six bytes. */ \ +- cnt = 6; \ +- ch &= 0x01; \ +- } \ + else \ + { \ + /* Search the end of this ill-formed UTF-8 character. This \ +@@ -272,7 +351,7 @@ gconv_end (struct __gconv_step *data) + STANDARD_FROM_LOOP_ERR_HANDLER (i); \ + } \ + \ +- if (__glibc_unlikely (inptr + cnt > inend)) \ ++ if (__glibc_unlikely (inptr + cnt > inend)) \ + { \ + /* We don't have enough input. But before we report \ + that check that all the bytes are correct. */ \ +@@ -280,7 +359,7 @@ gconv_end (struct __gconv_step *data) + if ((inptr[i] & 0xc0) != 0x80) \ + break; \ + \ +- if (__glibc_likely (inptr + i == inend)) \ ++ if (__glibc_likely (inptr + i == inend)) \ + { \ + result = __GCONV_INCOMPLETE_INPUT; \ + break; \ +@@ -305,7 +384,10 @@ gconv_end (struct __gconv_step *data) + /* If i < cnt, some trail byte was not >= 0x80, < 0xc0. \ + If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could \ + have been represented with fewer than cnt bytes. */ \ +- if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0)) \ ++ if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0) \ ++ /* Do not accept UTF-16 surrogates. */ \ ++ || (ch >= 0xd800 && ch <= 0xdfff) \ ++ || (ch > 0x10ffff)) \ + { \ + /* This is an illegal encoding. */ \ + goto errout; \ +@@ -318,137 +400,212 @@ gconv_end (struct __gconv_step *data) + *((uint32_t *) outptr) = ch; \ + outptr += sizeof (uint32_t); \ + } +-#define LOOP_NEED_FLAGS + +-#define STORE_REST \ +- { \ +- /* We store the remaining bytes while converting them into the UCS4 \ +- format. We can assume that the first byte in the buffer is \ +- correct and that it requires a larger number of bytes than there \ +- are in the input buffer. */ \ +- wint_t ch = **inptrp; \ +- size_t cnt, r; \ +- \ +- state->__count = inend - *inptrp; \ +- \ +- if (ch >= 0xc2 && ch < 0xe0) \ +- { \ +- /* We expect two bytes. The first byte cannot be 0xc0 or \ +- 0xc1, otherwise the wide character could have been \ +- represented using a single byte. */ \ +- cnt = 2; \ +- ch &= 0x1f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf0) == 0xe0)) \ +- { \ +- /* We expect three bytes. */ \ +- cnt = 3; \ +- ch &= 0x0f; \ +- } \ +- else if (__glibc_likely ((ch & 0xf8) == 0xf0)) \ +- { \ +- /* We expect four bytes. */ \ +- cnt = 4; \ +- ch &= 0x07; \ +- } \ +- else if (__glibc_likely ((ch & 0xfc) == 0xf8)) \ +- { \ +- /* We expect five bytes. */ \ +- cnt = 5; \ +- ch &= 0x03; \ +- } \ +- else \ +- { \ +- /* We expect six bytes. */ \ +- cnt = 6; \ +- ch &= 0x01; \ +- } \ +- \ +- /* The first byte is already consumed. */ \ +- r = cnt - 1; \ +- while (++(*inptrp) < inend) \ +- { \ +- ch <<= 6; \ +- ch |= **inptrp & 0x3f; \ +- --r; \ +- } \ +- \ +- /* Shift for the so far missing bytes. */ \ +- ch <<= r * 6; \ +- \ +- /* Store the number of bytes expected for the entire sequence. */ \ +- state->__count |= cnt << 8; \ +- \ +- /* Store the value. */ \ +- state->__value.__wch = ch; \ ++#define HW_FROM_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2, tmp3; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vrepib %%v30,0x7f\n\t" /* For compare > 0x7f. */ \ ++ " vrepib %%v31,0x20\n\t" \ ++ /* Loop which handles UTF-8 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],64,20f\n\t" \ ++ "1: vl %%v16,0(%[R_IN])\n\t" \ ++ " vstrcbs %%v17,%%v16,%%v30,%%v31\n\t" \ ++ " jno 10f\n\t" /* Jump away if not all bytes are 1byte \ ++ UTF8 chars. */ \ ++ /* Enlarge to UCS4. */ \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " la %[R_IN],16(%[R_IN])\n\t" \ ++ " vuplhh %%v20,%%v18\n\t" \ ++ " aghi %[R_INLEN],-16\n\t" \ ++ " vupllh %%v21,%%v18\n\t" \ ++ " aghi %[R_OUTLEN],-64\n\t" \ ++ " vuplhh %%v22,%%v19\n\t" \ ++ " vupllh %%v23,%%v19\n\t" \ ++ /* Store 64 bytes to buf_out. */ \ ++ " vstm %%v20,%%v23,0(%[R_OUT])\n\t" \ ++ " la %[R_OUT],64(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],16,20f\n\t" \ ++ " clgijl %[R_OUTLEN],64,20f\n\t" \ ++ " j 1b\n\t" \ ++ "10: \n\t" \ ++ /* At least one byte is > 0x7f. \ ++ Store the preceding 1-byte chars. */ \ ++ " vlgvb %[R_TMP],%%v17,7\n\t" \ ++ " sllk %[R_TMP2],%[R_TMP],2\n\t" /* Compute highest \ ++ index to store. */ \ ++ " llgfr %[R_TMP3],%[R_TMP2]\n\t" \ ++ " ahi %[R_TMP2],-1\n\t" \ ++ " jl 20f\n\t" \ ++ " vuplhb %%v18,%%v16\n\t" \ ++ " vuplhh %%v20,%%v18\n\t" \ ++ " vstl %%v20,%[R_TMP2],0(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v21,%%v18\n\t" \ ++ " vstl %%v21,%[R_TMP2],16(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllb %%v19,%%v16\n\t" \ ++ " vuplhh %%v22,%%v19\n\t" \ ++ " vstl %%v22,%[R_TMP2],32(%[R_OUT])\n\t" \ ++ " ahi %[R_TMP2],-16\n\t" \ ++ " jl 11f\n\t" \ ++ " vupllh %%v23,%%v19\n\t" \ ++ " vstl %%v23,%[R_TMP2],48(%[R_OUT])\n\t" \ ++ "11: \n\t" \ ++ /* Update pointers. */ \ ++ " la %[R_IN],0(%[R_TMP],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_TMP]\n\t" \ ++ " la %[R_OUT],0(%[R_TMP3],%[R_OUT])\n\t" \ ++ " slgr %[R_OUTLEN],%[R_TMP3]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu14 %[R_OUT],%[R_IN],1\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=a" (tmp) \ ++ , [R_TMP2] "=d" (tmp2), [R_TMP3] "=a" (tmp3) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v30") \ ++ ASM_CLOBBER_VR ("v31") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ + } ++#define BODY_FROM_VX BODY_FROM_HW (HW_FROM_VX) + +-#define UNPACK_BYTES \ +- { \ +- static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc }; \ +- wint_t wch = state->__value.__wch; \ +- size_t ntotal = state->__count >> 8; \ +- \ +- inlen = state->__count & 255; \ +- \ +- bytebuf[0] = inmask[ntotal - 2]; \ +- \ +- do \ +- { \ +- if (--ntotal < inlen) \ +- bytebuf[ntotal] = 0x80 | (wch & 0x3f); \ +- wch >>= 6; \ +- } \ +- while (ntotal > 1); \ +- \ +- bytebuf[0] |= wch; \ +- } ++/* These definitions apply to the UTF-8 to UTF-32 direction. The ++ software implementation for UTF-8 still supports multibyte ++ characters up to 6 bytes whereas the hardware variant does not. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_c + +-#define CLEAR_STATE \ +- state->__count = 0 ++#define LOOP_NEED_FLAGS + ++#define STORE_REST STORE_REST_COMMON ++#define UNPACK_BYTES UNPACK_BYTES_COMMON ++#define CLEAR_STATE CLEAR_STATE_COMMON ++#define BODY BODY_FROM_C + #include + ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++#define LOOPFCT __from_utf8_loop_etf3eh ++ ++#define LOOP_NEED_FLAGS ++ ++#define STORE_REST STORE_REST_COMMON ++#define UNPACK_BYTES UNPACK_BYTES_COMMON ++#define CLEAR_STATE CLEAR_STATE_COMMON ++#define BODY BODY_FROM_ETF3EH ++#include ++ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_INPUT MAX_NEEDED_FROM ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_TO ++# define LOOPFCT __from_utf8_loop_vx ++ ++# define LOOP_NEED_FLAGS ++ ++# define STORE_REST STORE_REST_COMMON ++# define UNPACK_BYTES UNPACK_BYTES_COMMON ++# define CLEAR_STATE CLEAR_STATE_COMMON ++# define BODY BODY_FROM_VX ++# include ++#endif ++ ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__from_utf8_loop_c) ++__attribute__ ((ifunc ("__from_utf8_loop_resolver"))) ++__from_utf8_loop; ++ ++static void * ++__from_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __from_utf8_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ETF3EH) ++ return __from_utf8_loop_etf3eh; ++ else ++ return __from_utf8_loop_c; ++} ++ ++strong_alias (__from_utf8_loop_c_single, __from_utf8_loop_single) ++ ++ + /* Conversion from UTF-32 internal/BE to UTF-8. */ ++#define BODY_TO_HW(ASM) \ ++ { \ ++ ASM; \ ++ if (__glibc_likely (inptr == inend) \ ++ || result == __GCONV_FULL_OUTPUT) \ ++ break; \ ++ if (inptr + 4 > inend) \ ++ { \ ++ result = __GCONV_INCOMPLETE_INPUT; \ ++ break; \ ++ } \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } ++ ++/* The hardware routine uses the S/390 cu41 instruction. */ ++#define BODY_TO_ETF3EH BODY_TO_HW (HARDWARE_CONVERT ("cu41 %0, %1")) ++ ++/* The hardware routine uses the S/390 vector and cu41 instructions. */ ++#define BODY_TO_VX BODY_TO_HW (HW_TO_VX) + +-#define MIN_NEEDED_INPUT MIN_NEEDED_TO +-#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM +-#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM +-#define LOOPFCT TO_LOOP + /* The software routine mimics the S/390 cu41 instruction. */ +-#define BODY \ ++#define BODY_TO_C \ + { \ +- if (GLRO (dl_hwcap) & HWCAP_S390_ETF3EH) \ +- { \ +- HARDWARE_CONVERT ("cu41 %0, %1"); \ +- \ +- if (inptr != inend) \ +- { \ +- result = __GCONV_INCOMPLETE_INPUT; \ +- break; \ +- } \ +- continue; \ +- } \ +- \ + uint32_t wc = *((const uint32_t *) inptr); \ + \ +- if (__glibc_likely (wc <= 0x7f)) \ ++ if (__glibc_likely (wc <= 0x7f)) \ + { \ +- /* Single UTF-8 char. */ \ +- *outptr = (uint8_t)wc; \ ++ /* Single UTF-8 char. */ \ ++ *outptr = (uint8_t)wc; \ + outptr++; \ + } \ + else if (wc <= 0x7ff) \ + { \ +- /* Two UTF-8 chars. */ \ +- if (__glibc_unlikely (outptr + 2 > outend)) \ ++ /* Two UTF-8 chars. */ \ ++ if (__glibc_unlikely (outptr + 2 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ + \ +- outptr[0] = 0xc0; \ ++ outptr[0] = 0xc0; \ + outptr[0] |= wc >> 6; \ + \ + outptr[1] = 0x80; \ +@@ -459,12 +616,18 @@ gconv_end (struct __gconv_step *data) + else if (wc <= 0xffff) \ + { \ + /* Three UTF-8 chars. */ \ +- if (__glibc_unlikely (outptr + 3 > outend)) \ ++ if (__glibc_unlikely (outptr + 3 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ + break; \ + } \ ++ if (wc >= 0xd800 && wc < 0xdc00) \ ++ { \ ++ /* Do not accept UTF-16 surrogates. */ \ ++ result = __GCONV_ILLEGAL_INPUT; \ ++ STANDARD_TO_LOOP_ERR_HANDLER (4); \ ++ } \ + outptr[0] = 0xe0; \ + outptr[0] |= wc >> 12; \ + \ +@@ -479,7 +642,7 @@ gconv_end (struct __gconv_step *data) + else if (wc <= 0x10ffff) \ + { \ + /* Four UTF-8 chars. */ \ +- if (__glibc_unlikely (outptr + 4 > outend)) \ ++ if (__glibc_unlikely (outptr + 4 > outend)) \ + { \ + /* Overflow in the output buffer. */ \ + result = __GCONV_FULL_OUTPUT; \ +@@ -505,7 +668,140 @@ gconv_end (struct __gconv_step *data) + } \ + inptr += 4; \ + } ++ ++#define HW_TO_VX \ ++ { \ ++ register const unsigned char* pInput asm ("8") = inptr; \ ++ register size_t inlen asm ("9") = inend - inptr; \ ++ register unsigned char* pOutput asm ("10") = outptr; \ ++ register size_t outlen asm("11") = outend - outptr; \ ++ unsigned long tmp, tmp2; \ ++ asm volatile (".machine push\n\t" \ ++ ".machine \"z13\"\n\t" \ ++ ".machinemode \"zarch_nohighgprs\"\n\t" \ ++ " vleif %%v20,127,0\n\t" /* element 0: 127 */ \ ++ " vzero %%v21\n\t" \ ++ " vleih %%v21,8192,0\n\t" /* element 0: > */ \ ++ " vleih %%v21,-8192,2\n\t" /* element 1: =<> */ \ ++ /* Loop which handles UTF-32 chars <=0x7f. */ \ ++ "0: clgijl %[R_INLEN],64,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ "1: vlm %%v16,%%v19,0(%[R_IN])\n\t" \ ++ " lghi %[R_TMP],0\n\t" \ ++ /* Shorten to byte values. */ \ ++ " vpkf %%v23,%%v16,%%v17\n\t" \ ++ " vpkf %%v24,%%v18,%%v19\n\t" \ ++ " vpkh %%v23,%%v23,%%v24\n\t" \ ++ /* Checking for values > 0x7f. */ \ ++ " vstrcfs %%v22,%%v16,%%v20,%%v21\n\t" \ ++ " jno 10f\n\t" \ ++ " vstrcfs %%v22,%%v17,%%v20,%%v21\n\t" \ ++ " jno 11f\n\t" \ ++ " vstrcfs %%v22,%%v18,%%v20,%%v21\n\t" \ ++ " jno 12f\n\t" \ ++ " vstrcfs %%v22,%%v19,%%v20,%%v21\n\t" \ ++ " jno 13f\n\t" \ ++ /* Store 16bytes to outptr. */ \ ++ " vst %%v23,0(%[R_OUT])\n\t" \ ++ " aghi %[R_INLEN],-64\n\t" \ ++ " aghi %[R_OUTLEN],-16\n\t" \ ++ " la %[R_IN],64(%[R_IN])\n\t" \ ++ " la %[R_OUT],16(%[R_OUT])\n\t" \ ++ " clgijl %[R_INLEN],64,20f\n\t" \ ++ " clgijl %[R_OUTLEN],16,20f\n\t" \ ++ " j 1b\n\t" \ ++ /* Found a value > 0x7f. */ \ ++ "13: ahi %[R_TMP],4\n\t" \ ++ "12: ahi %[R_TMP],4\n\t" \ ++ "11: ahi %[R_TMP],4\n\t" \ ++ "10: vlgvb %[R_I],%%v22,7\n\t" \ ++ " srlg %[R_I],%[R_I],2\n\t" \ ++ " agr %[R_I],%[R_TMP]\n\t" \ ++ " je 20f\n\t" \ ++ /* Store characters before invalid one... */ \ ++ " slgr %[R_OUTLEN],%[R_I]\n\t" \ ++ "15: aghi %[R_I],-1\n\t" \ ++ " vstl %%v23,%[R_I],0(%[R_OUT])\n\t" \ ++ /* ... and update pointers. */ \ ++ " aghi %[R_I],1\n\t" \ ++ " la %[R_OUT],0(%[R_I],%[R_OUT])\n\t" \ ++ " sllg %[R_I],%[R_I],2\n\t" \ ++ " la %[R_IN],0(%[R_I],%[R_IN])\n\t" \ ++ " slgr %[R_INLEN],%[R_I]\n\t" \ ++ /* Handle multibyte utf8-char with convert instruction. */ \ ++ "20: cu41 %[R_OUT],%[R_IN]\n\t" \ ++ " jo 0b\n\t" /* Try vector implemenation again. */ \ ++ " lochil %[R_RES],%[RES_OUT_FULL]\n\t" /* cc == 1. */ \ ++ " lochih %[R_RES],%[RES_IN_ILL]\n\t" /* cc == 2. */ \ ++ ".machine pop" \ ++ : /* outputs */ [R_IN] "+a" (pInput) \ ++ , [R_INLEN] "+d" (inlen), [R_OUT] "+a" (pOutput) \ ++ , [R_OUTLEN] "+d" (outlen), [R_TMP] "=d" (tmp) \ ++ , [R_I] "=a" (tmp2) \ ++ , [R_RES] "+d" (result) \ ++ : /* inputs */ \ ++ [RES_OUT_FULL] "i" (__GCONV_FULL_OUTPUT) \ ++ , [RES_IN_ILL] "i" (__GCONV_ILLEGAL_INPUT) \ ++ : /* clobber list */ "memory", "cc" \ ++ ASM_CLOBBER_VR ("v16") ASM_CLOBBER_VR ("v17") \ ++ ASM_CLOBBER_VR ("v18") ASM_CLOBBER_VR ("v19") \ ++ ASM_CLOBBER_VR ("v20") ASM_CLOBBER_VR ("v21") \ ++ ASM_CLOBBER_VR ("v22") ASM_CLOBBER_VR ("v23") \ ++ ASM_CLOBBER_VR ("v24") \ ++ ); \ ++ inptr = pInput; \ ++ outptr = pOutput; \ ++ } ++ ++/* Generate loop-function with software routing. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf8_loop_c ++#define BODY BODY_TO_C ++#define LOOP_NEED_FLAGS ++#include ++ ++/* Generate loop-function with hardware utf-convert instruction. */ ++#define MIN_NEEDED_INPUT MIN_NEEDED_TO ++#define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++#define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++#define LOOPFCT __to_utf8_loop_etf3eh + #define LOOP_NEED_FLAGS ++#define BODY BODY_TO_ETF3EH + #include + ++#if defined HAVE_S390_VX_ASM_SUPPORT ++/* Generate loop-function with hardware vector and utf-convert instructions. */ ++# define MIN_NEEDED_INPUT MIN_NEEDED_TO ++# define MIN_NEEDED_OUTPUT MIN_NEEDED_FROM ++# define MAX_NEEDED_OUTPUT MAX_NEEDED_FROM ++# define LOOPFCT __to_utf8_loop_vx ++# define BODY BODY_TO_VX ++# define LOOP_NEED_FLAGS ++# include ++#endif ++ ++/* Generate ifunc'ed loop function. */ ++__typeof(__to_utf8_loop_c) ++__attribute__ ((ifunc ("__to_utf8_loop_resolver"))) ++__to_utf8_loop; ++ ++static void * ++__to_utf8_loop_resolver (unsigned long int dl_hwcap) ++{ ++#if defined HAVE_S390_VX_ASM_SUPPORT ++ if (dl_hwcap & HWCAP_S390_VX) ++ return __to_utf8_loop_vx; ++ else ++#endif ++ if (dl_hwcap & HWCAP_S390_ETF3EH) ++ return __to_utf8_loop_etf3eh; ++ else ++ return __to_utf8_loop_c; ++} ++ ++strong_alias (__to_utf8_loop_c_single, __to_utf8_loop_single) ++ ++ + #include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1383951.patch b/SOURCES/glibc-rh1383951.patch new file mode 100644 index 00000000..a2292c23 --- /dev/null +++ b/SOURCES/glibc-rh1383951.patch @@ -0,0 +1,71 @@ +From a014cecd82b71b70a6a843e250e06b541ad524f7 Mon Sep 17 00:00:00 2001 +From: Florian Weimer +Date: Thu, 15 Oct 2015 09:23:07 +0200 +Subject: [PATCH] Always enable pointer guard [BZ #18928] + +Honoring the LD_POINTER_GUARD environment variable in AT_SECURE mode +has security implications. This commit enables pointer guard +unconditionally, and the environment variable is now ignored. + + [BZ #18928] + * sysdeps/generic/ldsodefs.h (struct rtld_global_ro): Remove + _dl_pointer_guard member. + * elf/rtld.c (_rtld_global_ro): Remove _dl_pointer_guard + initializer. + (security_init): Always set up pointer guard. + (process_envvars): Do not process LD_POINTER_GUARD. + +diff -rup a/elf/rtld.c b/elf/rtld.c +--- a/elf/rtld.c 2017-03-06 14:38:55.000000000 -0500 ++++ b/elf/rtld.c 2017-03-06 14:41:19.502556336 -0500 +@@ -160,7 +160,6 @@ struct rtld_global_ro _rtld_global_ro at + ._dl_hwcap_mask = HWCAP_IMPORTANT, + ._dl_lazy = 1, + ._dl_fpu_control = _FPU_DEFAULT, +- ._dl_pointer_guard = 1, + ._dl_pagesize = EXEC_PAGESIZE, + ._dl_inhibit_cache = 0, + +@@ -844,15 +843,12 @@ security_init (void) + #endif + + /* Set up the pointer guard as well, if necessary. */ +- if (GLRO(dl_pointer_guard)) +- { +- uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random, +- stack_chk_guard); ++ uintptr_t pointer_chk_guard ++ = _dl_setup_pointer_guard (_dl_random, stack_chk_guard); + #ifdef THREAD_SET_POINTER_GUARD +- THREAD_SET_POINTER_GUARD (pointer_chk_guard); ++ THREAD_SET_POINTER_GUARD (pointer_chk_guard); + #endif +- __pointer_chk_guard_local = pointer_chk_guard; +- } ++ __pointer_chk_guard_local = pointer_chk_guard; + + /* We do not need the _dl_random value anymore. The less + information we leave behind, the better, so clear the +@@ -2599,9 +2595,6 @@ process_envvars (enum mode *modep) + GLRO(dl_use_load_bias) = envline[14] == '1' ? -1 : 0; + break; + } +- +- if (memcmp (envline, "POINTER_GUARD", 13) == 0) +- GLRO(dl_pointer_guard) = envline[14] != '0'; + break; + + case 14: +diff -rup a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +--- a/sysdeps/generic/ldsodefs.h 2017-03-06 14:38:57.000000000 -0500 ++++ b/sysdeps/generic/ldsodefs.h 2017-03-06 14:41:19.506556361 -0500 +@@ -588,9 +588,6 @@ struct rtld_global_ro + /* List of auditing interfaces. */ + struct audit_ifaces *_dl_audit; + unsigned int _dl_naudit; +- +- /* 0 if internal pointer values should not be guarded, 1 if they should. */ +- EXTERN int _dl_pointer_guard; + }; + # define __rtld_global_attribute__ + # if IS_IN (rtld) diff --git a/SOURCES/glibc-rh1385003.patch b/SOURCES/glibc-rh1385003.patch new file mode 100644 index 00000000..28fc23d5 --- /dev/null +++ b/SOURCES/glibc-rh1385003.patch @@ -0,0 +1,41 @@ +commit 26011b5cfa6a1a8d8005d65f11d97498444a4e95 +Author: Stefan Liebler +Date: Mon Mar 24 16:46:51 2014 +0100 + + S390: Define SIZE_MAX as unsigned long (BZ #16712). + +--- glibc-2.17-c758a686/sysdeps/generic/stdint.h ++++ glibc-2.17-c758a686/sysdeps/generic/stdint.h +@@ -264,7 +264,11 @@ + # if __WORDSIZE == 64 + # define SIZE_MAX (18446744073709551615UL) + # else +-# define SIZE_MAX (4294967295U) ++# ifdef __WORDSIZE32_SIZE_ULONG ++# define SIZE_MAX (4294967295UL) ++# else ++# define SIZE_MAX (4294967295U) ++# endif + # endif + + /* Limits of `wchar_t'. */ +--- glibc-2.17-c758a686/sysdeps/s390/s390-32/bits/wordsize.h ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/bits/wordsize.h +@@ -4,6 +4,7 @@ + # define __WORDSIZE 64 + #else + # define __WORDSIZE 32 ++# define __WORDSIZE32_SIZE_ULONG 1 + #endif + + #if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL +--- glibc-2.17-c758a686/sysdeps/s390/s390-64/bits/wordsize.h ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/bits/wordsize.h +@@ -4,6 +4,7 @@ + # define __WORDSIZE 64 + #else + # define __WORDSIZE 32 ++# define __WORDSIZE32_SIZE_ULONG 1 + #endif + + #if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL diff --git a/SOURCES/glibc-rh1385004-1.patch b/SOURCES/glibc-rh1385004-1.patch new file mode 100644 index 00000000..ab1afeec --- /dev/null +++ b/SOURCES/glibc-rh1385004-1.patch @@ -0,0 +1,710 @@ +From 5db5f0071917cf14b454596f847fc7ff6e63e317 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 24 Jun 2015 02:08:21 -0400 +Subject: [PATCH] powerpc: strstr optimization + +This patch optimizes strstr function for power >= 7 systems. Performance +gain is obtained using aligned memory access and usage of cmpb +instruction for quicker comparison. The average improvement of this +optimization is ~40%. Tested on ppc64 and ppc64le. + +2015-07-16 Rajalakshmi Srinivasaraghavan + + * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strstr(). + * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c: Likewise. + * sysdeps/powerpc/powerpc64/power7/strstr.S: New File. + * sysdeps/powerpc/powerpc64/multiarch/strstr-power7.S: New File. + * sysdeps/powerpc/powerpc64/multiarch/strstr-ppc64.c: New File. + * sysdeps/powerpc/powerpc64/multiarch/strstr.c: New File. + +(cherry picked from commit b42f8cad52ebfbfd43ebf6e42e606b489ffbd466) +--- + ChangeLog | 10 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 9 + + .../powerpc/powerpc64/multiarch/strstr-power7.S | 44 ++ + sysdeps/powerpc/powerpc64/multiarch/strstr-ppc64.c | 29 ++ + sysdeps/powerpc/powerpc64/multiarch/strstr.c | 34 ++ + sysdeps/powerpc/powerpc64/power7/strstr.S | 509 +++++++++++++++++++++ + 7 files changed, 636 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strstr-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strstr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strstr.c + create mode 100644 sysdeps/powerpc/powerpc64/power7/strstr.S + +diff --git a/ChangeLog b/ChangeLog +index 1aeb84b..8e98192 100644 + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 17265bd..3b0e3a0 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -19,6 +19,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + stpncpy-power8 stpncpy-power7 stpncpy-ppc64 \ + strncpy-power8 strncpy-power7 strncpy-ppc64 \ + strncat-power7 \ ++ strstr-power7 strstr-ppc64 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index f5fdea5..364385b 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -322,6 +322,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strcat, 1, + __strcat_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strstr.c. */ ++ IFUNC_IMPL (i, name, strstr, ++ IFUNC_IMPL_ADD (array, i, strstr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strstr_power7) ++ IFUNC_IMPL_ADD (array, i, strstr, 1, ++ __strstr_ppc)) ++ + /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c. */ + IFUNC_IMPL (i, name, wcschr, + IFUNC_IMPL_ADD (array, i, wcschr, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strstr-power7.S +new file mode 100644 +index 0000000..94ce95b +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strstr-power7.S +@@ -0,0 +1,44 @@ ++/* Optimized strstr implementation for POWER7. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strstr_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strstr_power7): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strstr_power7) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strstr_power7) \ ++ END_2(__strstr_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define STRLEN __strlen_power7 ++#define STRNLEN __strnlen_power7 ++#define STRCHR __strchr_power7 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strstr-ppc64.c +new file mode 100644 +index 0000000..7fa2ace +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strstr-ppc64.c +@@ -0,0 +1,29 @@ ++/* Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRSTR __strstr_ppc ++#if IS_IN (libc) && defined(SHARED) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1(__strstr_ppc, __GI_strstr, __strstr_ppc); ++#endif ++ ++extern __typeof (strstr) __strstr_ppc attribute_hidden; ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c +new file mode 100644 +index 0000000..2be7646 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c +@@ -0,0 +1,34 @@ ++/* Multiple versions of strstr. PowerPC64 version. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#if IS_IN (libc) ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strstr) __strstr_ppc attribute_hidden; ++extern __typeof (strstr) __strstr_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (strstr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strstr_power7 ++ : __strstr_ppc); ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power7/strstr.S b/sysdeps/powerpc/powerpc64/power7/strstr.S +new file mode 100644 +index 0000000..8dca31c +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/strstr.S +@@ -0,0 +1,509 @@ ++/* Optimized strstr implementation for PowerPC64/POWER7. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Char * [r3] strstr (char *s [r3], char * pat[r4]) */ ++ ++/* The performance gain is obtained using aligned memory access, load ++ * doubleword and usage of cmpb instruction for quicker comparison. */ ++ ++#ifndef STRLEN ++/* For builds with no IFUNC support, local calls should be made to internal ++ GLIBC symbol (created by libc_hidden_builtin_def). */ ++# ifdef SHARED ++# define STRLEN __GI_strlen ++# else ++# define STRLEN strlen ++# endif ++#endif ++ ++#ifndef STRNLEN ++/* For builds with no IFUNC support, local calls should be made to internal ++ GLIBC symbol (created by libc_hidden_builtin_def). */ ++# ifdef SHARED ++# define STRNLEN __GI_strnlen ++# else ++# define STRNLEN strnlen ++# endif ++#endif ++ ++#ifndef STRCHR ++# ifdef SHARED ++# define STRCHR __GI_strchr ++# else ++# define STRCHR strchr ++# endif ++#endif ++ ++#define FRAMESIZE (FRAME_MIN_SIZE+32) ++ .machine power7 ++EALIGN (strstr, 4, 0) ++ CALL_MCOUNT 2 ++ mflr r0 /* Load link register LR to r0. */ ++ std r31, -8(r1) /* Save callers register r31. */ ++ cfi_offset(r31, -8) ++ std r30, -16(r1) /* Save callers register r30. */ ++ cfi_offset(r30, -16) ++ std r29, -24(r1) /* Save callers register r29. */ ++ cfi_offset(r29, -24) ++ std r0, 16(r1) /* Store the link register. */ ++ cfi_offset(lr, 16) ++ stdu r1, -FRAMESIZE(r1) /* Create the stack frame. */ ++ cfi_adjust_cfa_offset(FRAMESIZE) ++ ++ dcbt 0, r3 ++ dcbt 0, r4 ++ ++ cmpdi cr7, r3, 0 ++ beq cr7, L(retnull) ++ cmpdi cr7, r4, 0 ++ beq cr7, L(retnull) ++ ++ mr r29, r3 ++ mr r30, r4 ++ mr r3, r4 ++ bl STRLEN ++ nop ++ ++ cmpdi cr7, r3, 0 /* If search str is null. */ ++ beq cr7, L(ret_r3) ++ ++ /* Call __strstr_ppc if needle len > 2048 */ ++ cmpdi cr7, r3, 2048 ++ bgt cr7, L(default) ++ ++ mr r31, r3 ++ mr r4, r3 ++ mr r3, r29 ++ bl STRNLEN ++ nop ++ ++ cmpd cr7, r3, r31 /* If len(r3) < len(r4). */ ++ blt cr7, L(retnull) ++ mr r3, r29 ++ lbz r4, 0(r30) ++ bl STRCHR ++ nop ++ ++ mr r11, r3 ++ /* If first char of search str is not present. */ ++ cmpdi cr7, r3, 0 ++ ble cr7, L(end) ++ ++ rldicl r8, r3, 0, 52 /* Page cross check. */ ++ cmpldi cr7, r8, 4096-16 ++ bgt cr7, L(bytebybyte) ++ ++ rldicl r8, r30, 0, 52 ++ cmpldi cr7, r8, 4096-16 ++ bgt cr7, L(bytebybyte) ++ ++ /* If len(r4) < 8 handle in a different way. */ ++ /* Shift position based on null and use cmpb. */ ++ cmpdi cr7, r31, 8 ++ blt cr7, L(lessthan8) ++ ++ /* Len(r4) >= 8 reaches here. */ ++ mr r8, r3 /* Save r3 for future use. */ ++ mr r4, r30 /* Restore r4. */ ++ li r0, 0 ++ rlwinm r10, r30, 3, 26, 28 /* Calculate padding in bits. */ ++ clrrdi r4, r4, 3 /* Make r4 aligned to 8. */ ++ ld r6, 0(r4) ++ addi r4, r4, 8 ++ cmpdi cr7, r10, 0 /* Check if its already aligned? */ ++ beq cr7, L(begin1) ++#ifdef __LITTLE_ENDIAN__ ++ srd r6, r6, r10 /* Discard unwanted bits. */ ++#else ++ sld r6, r6, r10 ++#endif ++ ld r9, 0(r4) ++ subfic r10, r10, 64 ++#ifdef __LITTLE_ENDIAN__ ++ sld r9, r9, r10 /* Discard unwanted bits. */ ++#else ++ srd r9, r9, r10 ++#endif ++ or r6, r6, r9 /* Form complete search str. */ ++L(begin1): ++ mr r29, r6 ++ rlwinm r10, r3, 3, 26, 28 ++ clrrdi r3, r3, 3 ++ ld r5, 0(r3) ++ cmpb r9, r0, r6 /* Check if input has null. */ ++ cmpdi cr7, r9, 0 ++ bne cr7, L(return3) ++ cmpb r9, r0, r5 /* Check if input has null. */ ++#ifdef __LITTLE_ENDIAN__ ++ srd r9, r9, r10 ++#else ++ sld r9, r9, r10 ++#endif ++ cmpdi cr7, r9, 0 ++ bne cr7, L(retnull) ++ ++ li r12, -8 /* Shift values. */ ++ li r11, 72 /* Shift values. */ ++ cmpdi cr7, r10, 0 ++ beq cr7, L(nextbyte1) ++ mr r12, r10 ++ addi r12, r12, -8 ++ subfic r11, r12, 64 ++ ++L(nextbyte1): ++ ldu r7, 8(r3) /* Load next dw. */ ++ addi r12, r12, 8 /* Shift one byte and compare. */ ++ addi r11, r11, -8 ++#ifdef __LITTLE_ENDIAN__ ++ srd r9, r5, r12 /* Rotate based on mask. */ ++ sld r10, r7, r11 ++#else ++ sld r9, r5, r12 ++ srd r10, r7, r11 ++#endif ++ /* Form single dw from few bytes on first load and second load. */ ++ or r10, r9, r10 ++ /* Check for null in the formed dw. */ ++ cmpb r9, r0, r10 ++ cmpdi cr7, r9, 0 ++ bne cr7, L(retnull) ++ /* Cmpb search str and input str. */ ++ cmpb r9, r10, r6 ++ cmpdi cr7, r9, -1 ++ beq cr7, L(match) ++ addi r8, r8, 1 ++ b L(begin) ++ ++ .align 4 ++L(match): ++ /* There is a match of 8 bytes, check next bytes. */ ++ cmpdi cr7, r31, 8 ++ beq cr7, L(return) ++ /* Update next starting point r8. */ ++ srdi r9, r11, 3 ++ subf r9, r9, r3 ++ mr r8, r9 ++ ++L(secondmatch): ++ mr r5, r7 ++ rlwinm r10, r30, 3, 26, 28 /* Calculate padding in bits. */ ++ ld r6, 0(r4) ++ addi r4, r4, 8 ++ cmpdi cr7, r10, 0 /* Check if its already aligned? */ ++ beq cr7, L(proceed3) ++#ifdef __LITTLE_ENDIAN__ ++ srd r6, r6, r10 /* Discard unwanted bits. */ ++ cmpb r9, r0, r6 ++ sld r9, r9, r10 ++#else ++ sld r6, r6, r10 ++ cmpb r9, r0, r6 ++ srd r9, r9, r10 ++#endif ++ cmpdi cr7, r9, 0 ++ bne cr7, L(proceed3) ++ ld r9, 0(r4) ++ subfic r10, r10, 64 ++#ifdef __LITTLE_ENDIAN__ ++ sld r9, r9, r10 /* Discard unwanted bits. */ ++#else ++ srd r9, r9, r10 ++#endif ++ or r6, r6, r9 /* Form complete search str. */ ++ ++L(proceed3): ++ li r7, 0 ++ addi r3, r3, 8 ++ cmpb r9, r0, r5 ++ cmpdi cr7, r9, 0 ++ bne cr7, L(proceed4) ++ ld r7, 0(r3) ++L(proceed4): ++#ifdef __LITTLE_ENDIAN__ ++ srd r9, r5, r12 ++ sld r10, r7, r11 ++#else ++ sld r9, r5, r12 ++ srd r10, r7, r11 ++#endif ++ /* Form single dw with few bytes from first and second load. */ ++ or r10, r9, r10 ++ cmpb r9, r0, r6 ++ cmpdi cr7, r9, 0 ++ bne cr7, L(return4) ++ /* Check for null in the formed dw. */ ++ cmpb r9, r0, r10 ++ cmpdi cr7, r9, 0 ++ bne cr7, L(retnull) ++ /* If the next 8 bytes dont match, start search again. */ ++ cmpb r9, r10, r6 ++ cmpdi cr7, r9, -1 ++ bne cr7, L(reset) ++ /* If the next 8 bytes match, load and compare next 8. */ ++ b L(secondmatch) ++ ++ .align 4 ++L(reset): ++ /* Start the search again. */ ++ addi r8, r8, 1 ++ b L(begin) ++ ++ .align 4 ++L(return3): ++ /* Count leading zeros and compare partial dw. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi r7, r9, -1 ++ andc r7, r7, r9 ++ popcntd r7, r7 ++ subfic r7, r7, 64 ++ sld r10, r5, r7 ++ sld r6, r6, r7 ++#else ++ cntlzd r7, r9 ++ subfic r7, r7, 64 ++ srd r10, r5, r7 ++ srd r6, r6, r7 ++#endif ++ cmpb r9, r10, r6 ++ cmpdi cr7, r9, -1 ++ addi r8, r8, 1 ++ /* Start search again if there is no match. */ ++ bne cr7, L(begin) ++ /* If the words match, update return values. */ ++ subfic r7, r7, 64 ++ srdi r7, r7, 3 ++ add r3, r3, r7 ++ subf r3, r31, r3 ++ b L(end) ++ ++ .align 4 ++L(return4): ++ /* Count leading zeros and compare partial dw. */ ++#ifdef __LITTLE_ENDIAN__ ++ addi r7, r9, -1 ++ andc r7, r7, r9 ++ popcntd r7, r7 ++ subfic r7, r7, 64 ++ sld r10, r10, r7 ++ sld r6, r6, r7 ++#else ++ cntlzd r7, r9 ++ subfic r7, r7, 64 ++ srd r10, r10, r7 ++ srd r6, r6, r7 ++#endif ++ cmpb r9, r10, r6 ++ cmpdi cr7, r9, -1 ++ addi r8, r8, 1 ++ bne cr7, L(begin) ++ subfic r7, r7, 64 ++ srdi r11, r11, 3 ++ subf r3, r11, r3 ++ srdi r7, r7, 3 ++ add r3, r3, r7 ++ subf r3, r31, r3 ++ b L(end) ++ ++ .align 4 ++L(begin): ++ mr r3, r8 ++ lbz r4, 0(r30) ++ bl STRCHR ++ nop ++ /* If first char of search str is not present. */ ++ cmpdi cr7, r3, 0 ++ ble cr7, L(end) ++ mr r8, r3 ++ mr r4, r30 /* Restore r4. */ ++ li r0, 0 ++ mr r6, r29 ++ clrrdi r4, r4, 3 ++ addi r4, r4, 8 ++ b L(begin1) ++ ++ /* Handle less than 8 search string. */ ++ .align 4 ++L(lessthan8): ++ mr r4, r3 ++ mr r9, r30 ++ li r0, 0 ++ ++ rlwinm r10, r9, 3, 26, 28 /* Calculate padding in bits. */ ++ srdi r8, r10, 3 /* Padding in bytes. */ ++ clrrdi r9, r9, 3 /* Make r4 aligned to 8. */ ++ ld r6, 0(r9) ++ cmpdi cr7, r10, 0 /* Check if its already aligned? */ ++ beq cr7, L(proceed2) ++#ifdef __LITTLE_ENDIAN__ ++ srd r6, r6, r10 /* Discard unwanted bits. */ ++#else ++ sld r6, r6, r10 ++#endif ++ subfic r8, r8, 8 ++ cmpd cr7, r8, r31 /* Next load needed? */ ++ bge cr7, L(proceed2) ++ ld r7, 8(r9) ++ subfic r10, r10, 64 ++#ifdef __LITTLE_ENDIAN__ ++ sld r7, r7, r10 /* Discard unwanted bits. */ ++#else ++ srd r7, r7, r10 ++#endif ++ or r6, r6, r7 /* Form complete search str. */ ++L(proceed2): ++ mr r29, r6 ++ rlwinm r10, r3, 3, 26, 28 ++ clrrdi r7, r3, 3 /* Make r3 aligned. */ ++ ld r5, 0(r7) ++ sldi r8, r31, 3 ++ subfic r8, r8, 64 ++#ifdef __LITTLE_ENDIAN__ ++ sld r6, r6, r8 ++ cmpb r9, r0, r5 ++ srd r9, r9, r10 ++#else ++ srd r6, r6, r8 ++ cmpb r9, r0, r5 ++ sld r9, r9, r10 ++#endif ++ cmpdi cr7, r9, 0 ++ bne cr7, L(noload) ++ cmpdi cr7, r10, 0 ++ beq cr7, L(continue) ++ ld r7, 8(r7) ++L(continue1): ++ mr r12, r10 ++ addi r12, r12, -8 ++ subfic r11, r12, 64 ++ b L(nextbyte) ++ ++ .align 4 ++L(continue): ++ ld r7, 8(r7) ++ li r12, -8 /* Shift values. */ ++ li r11, 72 /* Shift values. */ ++L(nextbyte): ++ addi r12, r12, 8 /* Mask for rotation. */ ++ addi r11, r11, -8 ++#ifdef __LITTLE_ENDIAN__ ++ srd r9, r5, r12 ++ sld r10, r7, r11 ++ or r10, r9, r10 ++ sld r10, r10, r8 ++ cmpb r9, r0, r10 ++ srd r9, r9, r8 ++#else ++ sld r9, r5, r12 ++ srd r10, r7, r11 ++ or r10, r9, r10 ++ srd r10, r10, r8 ++ cmpb r9, r0, r10 ++ sld r9, r9, r8 ++#endif ++ cmpdi cr7, r9, 0 ++ bne cr7, L(retnull) ++ cmpb r9, r10, r6 ++ cmpdi cr7, r9, -1 ++ beq cr7, L(end) ++ addi r3, r4, 1 ++ lbz r4, 0(r30) ++ bl STRCHR ++ nop ++ /* If first char of search str is not present. */ ++ cmpdi cr7, r3, 0 ++ ble cr7, L(end) ++ mr r4, r3 ++ mr r6, r29 ++ li r0, 0 ++ b L(proceed2) ++ ++ .align 4 ++L(noload): ++ /* Reached null in r3, so skip next load. */ ++ li r7, 0 ++ b L(continue1) ++ ++ .align 4 ++L(return): ++ /* Update return values. */ ++ srdi r9, r11, 3 ++ subf r3, r9, r3 ++ b L(end) ++ ++ /* Handling byte by byte. */ ++ .align 4 ++L(bytebybyte): ++ mr r8, r3 ++ addi r8, r8, -1 ++L(loop1): ++ addi r8, r8, 1 ++ mr r3, r8 ++ mr r4, r30 ++ lbz r6, 0(r4) ++ cmpdi cr7, r6, 0 ++ beq cr7, L(updater3) ++L(loop): ++ lbz r5, 0(r3) ++ cmpdi cr7, r5, 0 ++ beq cr7, L(retnull) ++ cmpld cr7, r6, r5 ++ bne cr7, L(loop1) ++ addi r3, r3, 1 ++ addi r4, r4, 1 ++ lbz r6, 0(r4) ++ cmpdi cr7, r6, 0 ++ beq cr7, L(updater3) ++ b L(loop) ++ ++ /* Handling return values. */ ++ .align 4 ++L(updater3): ++ subf r3, r31, r3 /* Reduce len of r4 from r3. */ ++ b L(end) ++ ++ .align 4 ++L(ret_r3): ++ mr r3, r29 /* Return r3. */ ++ b L(end) ++ ++ .align 4 ++L(retnull): ++ li r3, 0 /* Return NULL. */ ++ b L(end) ++ ++ .align 4 ++L(default): ++ mr r3, r29 ++ mr r4, r30 ++ bl __strstr_ppc ++ nop ++ ++ .align 4 ++L(end): ++ addi r1, r1, FRAMESIZE /* Restore stack pointer. */ ++ cfi_adjust_cfa_offset(-FRAMESIZE) ++ ld r0, 16(r1) /* Restore the saved link register. */ ++ ld r29, -24(r1) /* Restore callers save register r29. */ ++ ld r30, -16(r1) /* Restore callers save register r30. */ ++ ld r31, -8(r1) /* Restore callers save register r31. */ ++ mtlr r0 /* Branch to link register. */ ++ blr ++END (strstr) ++libc_hidden_builtin_def (strstr) +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-10.patch b/SOURCES/glibc-rh1385004-10.patch new file mode 100644 index 00000000..af05dea8 --- /dev/null +++ b/SOURCES/glibc-rh1385004-10.patch @@ -0,0 +1,33 @@ +From cecfeab756960639684ce7b95c39d8f1a80b71cf Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Fri, 16 Sep 2016 17:31:58 -0300 +Subject: [PATCH] powerpc: Fix POWER9 implies + +Fix multiarch build for POWER9 by correcting the order of the +directories listed at sysnames configure variable. + +(cherry picked from commit 1850ce5a2ea3b908b26165e7e951cd4334129f07) +--- + ChangeLog | 8 ++++++++ + sysdeps/powerpc/powerpc32/power9/multiarch/Implies | 2 +- + sysdeps/powerpc/powerpc64/power9/fpu/Implies | 1 - + 3 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 565da33..496ef12 100644 +diff --git a/sysdeps/powerpc/powerpc32/power9/multiarch/Implies b/sysdeps/powerpc/powerpc32/power9/multiarch/Implies +index 4393b56..1a46ef0 100644 +--- a/sysdeps/powerpc/powerpc32/power9/multiarch/Implies ++++ b/sysdeps/powerpc/powerpc32/power9/multiarch/Implies +@@ -1 +1 @@ +-powerpc/powerpc32/power8/fpu/multiarch ++powerpc/powerpc32/power8/multiarch +diff --git a/sysdeps/powerpc/powerpc64/power9/fpu/Implies b/sysdeps/powerpc/powerpc64/power9/fpu/Implies +index fad2505..ae0dbaf 100644 +--- a/sysdeps/powerpc/powerpc64/power9/fpu/Implies ++++ b/sysdeps/powerpc/powerpc64/power9/fpu/Implies +@@ -1,2 +1 @@ + powerpc/powerpc64/power8/fpu +-powerpc/powerpc64/power8 +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-11.patch b/SOURCES/glibc-rh1385004-11.patch new file mode 100644 index 00000000..1f9b46bc --- /dev/null +++ b/SOURCES/glibc-rh1385004-11.patch @@ -0,0 +1,363 @@ +From 1cf3bb5ec15f28245a6840b5b0443685c828a467 Mon Sep 17 00:00:00 2001 +From: "Paul E. Murphy" +Date: Mon, 14 Mar 2016 17:40:46 -0400 +Subject: [PATCH] powerpc: Add optimized P8 strspn + +This utilizes vectors and bitmasks. For small needle, large +haystack, the performance improvement is upto 8x. For short +strings (0-4B), the cost of computing the bitmask dominates, +and is a tad slower. + +(cherry picked from commit 25dba0ad054723196fb633ba5d8a463ef5cb775c) +--- + ChangeLog | 15 ++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 + + .../powerpc/powerpc64/multiarch/strspn-power8.S | 40 +++++ + sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c | 25 +++ + sysdeps/powerpc/powerpc64/multiarch/strspn.c | 35 ++++ + sysdeps/powerpc/powerpc64/power8/strspn.S | 179 +++++++++++++++++++++ + 7 files changed, 304 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strspn.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/strspn.S + +diff --git a/ChangeLog b/ChangeLog +index 496ef12..f030b68 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 3b0e3a0..7ed56bf 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -19,6 +19,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncpy-power8 strncpy-power7 strncpy-ppc64 \ + strncat-power7 \ + strstr-power7 strstr-ppc64 \ ++ strspn-power8 strspn-ppc64 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 364385b..f6c70ba 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -322,6 +322,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strcat, 1, + __strcat_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strspn.c. */ ++ IFUNC_IMPL (i, name, strspn, ++ IFUNC_IMPL_ADD (array, i, strspn, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strspn_power8) ++ IFUNC_IMPL_ADD (array, i, strspn, 1, ++ __strspn_ppc)) ++ + /* Support sysdeps/powerpc/powerpc64/multiarch/strstr.c. */ + IFUNC_IMPL (i, name, strstr, + IFUNC_IMPL_ADD (array, i, strstr, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S +new file mode 100644 +index 0000000..86a4e09 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S +@@ -0,0 +1,40 @@ ++/* Optimized strspn implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strspn_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strspn_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strspn_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strspn_power8) \ ++ END_2(__strspn_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c +new file mode 100644 +index 0000000..4c63665 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c +@@ -0,0 +1,25 @@ ++/* Default strspn implementation for PowerPC64. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRSPN __strspn_ppc ++#ifdef SHARED ++#undef libc_hidden_def ++#define libc_hidden_def(name) ++#endif ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn.c +new file mode 100644 +index 0000000..0e653f3 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strspn.c +@@ -0,0 +1,35 @@ ++/* Multiple versions of strspn. PowerPC64 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++# include ++# include ++# include "init-arch.h" ++ ++#undef strspn ++extern __typeof (strspn) __libc_strspn; ++ ++extern __typeof (strspn) __strspn_ppc attribute_hidden; ++extern __typeof (strspn) __strspn_power8 attribute_hidden; ++ ++libc_ifunc (__libc_strspn, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strspn_power8 ++ : __strspn_ppc); ++ ++weak_alias (__libc_strspn, strspn) ++libc_hidden_builtin_def (strspn) +diff --git a/sysdeps/powerpc/powerpc64/power8/strspn.S b/sysdeps/powerpc/powerpc64/power8/strspn.S +new file mode 100644 +index 0000000..0dda437 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strspn.S +@@ -0,0 +1,179 @@ ++/* Optimized strspn implementation for Power8. ++ ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* size_t [r3] strspn (const char *string [r3], ++ const char *needleAccept [r4]) */ ++ ++/* This takes a novel approach by computing a 256 bit mask whereby ++ each set bit implies the byte is "accepted". P8 vector hardware ++ has extremely efficient hardware for selecting bits from a mask. ++ ++ One might ask "why not use bpermd for short strings"? It is ++ so slow that its performance about matches the generic PPC64 ++ variant without any fancy masking, with the added expense of ++ making the mask. That was the first variant of this. */ ++ ++ ++ ++#include "sysdep.h" ++ ++/* Simple macro to use VSX instructions in overlapping VR's. */ ++#define XXVR(insn, vrt, vra, vrb) \ ++ insn 32+vrt, 32+vra, 32+vrb ++ ++/* ISA 2.07B instructions are not all defined for older binutils. ++ Macros are defined below for these newer instructions in order ++ to maintain compatibility. */ ++ ++/* Note, TX/SX is always set as VMX regs are the high 32 VSX regs. */ ++#define MTVRD(v,r) .long (0x7c000167 | ((v)<<(32-11)) | ((r)<<(32-16))) ++#define MFVRD(r,v) .long (0x7c000067 | ((v)<<(32-11)) | ((r)<<(32-16))) ++ ++#define VBPERMQ(t,a,b) .long (0x1000054c \ ++ | ((t)<<(32-11)) \ ++ | ((a)<<(32-16)) \ ++ | ((b)<<(32-21)) ) ++ ++ /* This can be updated to power8 once the minimum version of ++ binutils supports power8 and the above instructions. */ ++ .machine power7 ++EALIGN(strspn, 4, 0) ++ CALL_MCOUNT 2 ++ ++ /* Generate useful constants for later on. */ ++ vspltisb v1, 7 ++ vspltisb v2, -1 ++ vslb v1, v1, v1 /* 0x80 to swap high bit for vbpermq. */ ++ vspltisb v10, 0 ++ vsldoi v4, v10, v2, 2 /* 0xFFFF into vr4. */ ++ XXVR(xxmrgld, v4, v4, v10) /* Mask for checking matches. */ ++ ++ /* Prepare to compute 256b mask. */ ++ addi r4, r4, -1 ++ li r5, 0 ++ li r6, 0 ++ li r7, 0 ++ li r8, 0 ++ li r11, 1 ++ sldi r11, r11, 63 ++ ++ /* Start interleaved Mask computation. ++ This will eventually or 1's into ignored bits from vbpermq. */ ++ lvsr v11, 0, r3 ++ vspltb v11, v11, 0 /* Splat shift constant. */ ++ ++ /* Build a 256b mask in r5-r8. */ ++ .align 4 ++L(next_needle): ++ lbzu r9, 1(r4) ++ ++ cmpldi cr0, r9, 0 ++ cmpldi cr1, r9, 128 ++ ++ /* This is a little tricky. srd only uses the first 7 bits, ++ and if bit 7 is set, value is always 0. So, we can ++ effectively shift 128b in this case. */ ++ xori r12, r9, 0x40 /* Invert bit 6. */ ++ srd r10, r11, r9 /* Mask for bits 0-63. */ ++ srd r12, r11, r12 /* Mask for bits 64-127. */ ++ ++ beq cr0, L(start_cmp) ++ ++ /* Now, or the value into the correct GPR. */ ++ bge cr1,L(needle_gt128) ++ or r5, r5, r10 /* 0 - 63. */ ++ or r6, r6, r12 /* 64 - 127. */ ++ b L(next_needle) ++ ++ .align 4 ++L(needle_gt128): ++ or r7, r7, r10 /* 128 - 191. */ ++ or r8, r8, r12 /* 192 - 255. */ ++ b L(next_needle) ++ ++ ++ .align 4 ++L(start_cmp): ++ /* Move and merge bitmap into 2 VRs. bpermd is slower on P8. */ ++ mr r0, r3 /* Save r3 for final length computation. */ ++ MTVRD (v5, r5) ++ MTVRD (v6, r6) ++ MTVRD (v7, r7) ++ MTVRD (v8, r8) ++ ++ /* Continue interleaved mask generation. */ ++#ifdef __LITTLE_ENDIAN__ ++ vsrw v11, v2, v11 /* Note, shift ignores higher order bits. */ ++ vsplth v11, v11, 0 /* Only care about the high 16 bits of v10. */ ++#else ++ vslw v11, v2, v11 /* Note, shift ignores higher order bits. */ ++ vsplth v11, v11, 1 /* Only care about the low 16 bits of v10. */ ++#endif ++ lvx v0, 0, r3 /* Note, unaligned load ignores lower bits. */ ++ ++ /* Do the merging of the bitmask. */ ++ XXVR(xxmrghd, v5, v5, v6) ++ XXVR(xxmrghd, v6, v7, v8) ++ ++ /* Finish mask generation. */ ++ vand v11, v11, v4 /* Throwaway bits not in the mask. */ ++ ++ /* Compare the first 1-16B, while masking unwanted bytes. */ ++ clrrdi r3, r3, 4 /* Note, counts from qw boundaries. */ ++ vxor v9, v0, v1 /* Swap high bit. */ ++ VBPERMQ (v8, v5, v0) ++ VBPERMQ (v7, v6, v9) ++ vor v7, v7, v8 ++ vor v7, v7, v11 /* Ignore non-participating bytes. */ ++ vcmpequh. v8, v7, v4 ++ bnl cr6, L(done) ++ ++ addi r3, r3, 16 ++ ++ .align 4 ++L(vec): ++ lvx v0, 0, r3 ++ addi r3, r3, 16 ++ vxor v9, v0, v1 /* Swap high bit. */ ++ VBPERMQ (v8, v5, v0) ++ VBPERMQ (v7, v6, v9) ++ vor v7, v7, v8 ++ vcmpequh. v8, v7, v4 ++ blt cr6, L(vec) ++ ++ addi r3, r3, -16 ++L(done): ++ subf r3, r0, r3 ++ MFVRD (r10, v7) ++ ++#ifdef __LITTLE_ENDIAN__ ++ addi r0, r10, 1 /* Count the trailing 1's. */ ++ andc r10, r10, r0 ++ popcntd r10, r10 ++#else ++ xori r10, r10, 0xffff /* Count leading 1's by inverting. */ ++ addi r3, r3, -48 /* Account for the extra leading zeros. */ ++ cntlzd r10, r10 ++#endif ++ ++ add r3, r3, r10 ++ blr ++ ++END(strspn) ++libc_hidden_builtin_def (strspn) +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-12.patch b/SOURCES/glibc-rh1385004-12.patch new file mode 100644 index 00000000..71159aa8 --- /dev/null +++ b/SOURCES/glibc-rh1385004-12.patch @@ -0,0 +1,420 @@ +From 0d3555b9b4d5cefe116c32bfa38ac70f1d6c25cb Mon Sep 17 00:00:00 2001 +From: Carlos Eduardo Seo +Date: Wed, 11 Nov 2015 17:31:28 -0200 +Subject: [PATCH] powerpc: Optimization for strlen for POWER8. + +This implementation takes advantage of vectorization to improve performance of +the loop over the current strlen implementation for POWER7. + +(cherry picked from commit 1b045ee53e0b8bed75745b931b33f27d21c9ed22) +--- + ChangeLog | 13 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 2 + + .../powerpc/powerpc64/multiarch/strlen-power8.S | 39 +++ + sysdeps/powerpc/powerpc64/multiarch/strlen.c | 9 +- + sysdeps/powerpc/powerpc64/power8/strlen.S | 297 +++++++++++++++++++++ + 6 files changed, 358 insertions(+), 4 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/power8/strlen.S + +diff --git a/ChangeLog b/ChangeLog +index f030b68..e7ea58a 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 7ed56bf..57abe8f 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -20,7 +20,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncpy-power8 strncpy-power7 strncpy-ppc64 \ + strncat-power7 \ + strstr-power7 strstr-ppc64 \ +- strspn-power8 strspn-ppc64 \ ++ strspn-power8 strspn-ppc64 strlen-power8 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index f6c70ba..583885c 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -101,6 +101,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/powerpc/powerpc64/multiarch/strlen.c. */ + IFUNC_IMPL (i, name, strlen, ++ IFUNC_IMPL_ADD (array, i, strlen, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strlen_power8) + IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_HAS_VSX, + __strlen_power7) + IFUNC_IMPL_ADD (array, i, strlen, 1, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strlen-power8.S +new file mode 100644 +index 0000000..686dc3d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen-power8.S +@@ -0,0 +1,39 @@ ++/* Optimized strlen implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strlen_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strlen_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strlen_power8) ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strlen_power8) \ ++ END_2(__strlen_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c +index 79a53d9..4b400a5 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strlen.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c +@@ -29,11 +29,14 @@ extern __typeof (__redirect_strlen) __libc_strlen; + + extern __typeof (__redirect_strlen) __strlen_ppc attribute_hidden; + extern __typeof (__redirect_strlen) __strlen_power7 attribute_hidden; ++extern __typeof (__redirect_strlen) __strlen_power8 attribute_hidden; + + libc_ifunc (__libc_strlen, +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __strlen_power7 +- : __strlen_ppc); ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strlen_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strlen_power7 ++ : __strlen_ppc); + + #undef strlen + strong_alias (__libc_strlen, strlen) +diff --git a/sysdeps/powerpc/powerpc64/power8/strlen.S b/sysdeps/powerpc/powerpc64/power8/strlen.S +new file mode 100644 +index 0000000..0142747 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strlen.S +@@ -0,0 +1,297 @@ ++/* Optimized strlen implementation for PowerPC64/POWER8 using a vectorized ++ loop. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* TODO: change these to the actual instructions when the minimum required ++ binutils allows it. */ ++#define MFVRD(r,v) .long (0x7c000067 | ((v)<<(32-11)) | ((r)<<(32-16))) ++#define VBPERMQ(t,a,b) .long (0x1000054c \ ++ | ((t)<<(32-11)) \ ++ | ((a)<<(32-16)) \ ++ | ((b)<<(32-21)) ) ++ ++/* int [r3] strlen (char *s [r3]) */ ++ ++/* TODO: change this to .machine power8 when the minimum required binutils ++ allows it. */ ++ .machine power7 ++EALIGN (strlen, 4, 0) ++ CALL_MCOUNT 1 ++ dcbt 0,r3 ++ clrrdi r4,r3,3 /* Align the address to doubleword boundary. */ ++ rlwinm r6,r3,3,26,28 /* Calculate padding. */ ++ li r0,0 /* Doubleword with null chars to use ++ with cmpb. */ ++ li r5,-1 /* MASK = 0xffffffffffffffff. */ ++ ld r12,0(r4) /* Load doubleword from memory. */ ++#ifdef __LITTLE_ENDIAN__ ++ sld r5,r5,r6 ++#else ++ srd r5,r5,r6 /* MASK = MASK >> padding. */ ++#endif ++ orc r9,r12,r5 /* Mask bits that are not part of the string. */ ++ cmpb r10,r9,r0 /* Check for null bytes in DWORD1. */ ++ cmpdi cr7,r10,0 /* If r10 == 0, no null's have been found. */ ++ bne cr7,L(done) ++ ++ /* For shorter strings (< 64 bytes), we will not use vector registers, ++ as the overhead isn't worth it. So, let's use GPRs instead. This ++ will be done the same way as we do in the POWER7 implementation. ++ Let's see if we are aligned to a quadword boundary. If so, we can ++ jump to the first (non-vectorized) loop. Otherwise, we have to ++ handle the next DWORD first. */ ++ mtcrf 0x01,r4 ++ mr r9,r4 ++ addi r9,r9,8 ++ bt 28,L(align64) ++ ++ /* Handle the next 8 bytes so we are aligned to a quadword ++ boundary. */ ++ ldu r5,8(r4) ++ cmpb r10,r5,r0 ++ cmpdi cr7,r10,0 ++ addi r9,r9,8 ++ bne cr7,L(done) ++ ++L(align64): ++ /* Proceed to the old (POWER7) implementation, checking two doublewords ++ per iteraction. For the first 56 bytes, we will just check for null ++ characters. After that, we will also check if we are 64-byte aligned ++ so we can jump to the vectorized implementation. We will unroll ++ these loops to avoid excessive branching. */ ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ bne cr7,L(dword_zero) ++ ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ bne cr7,L(dword_zero) ++ ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ bne cr7,L(dword_zero) ++ ++ /* Are we 64-byte aligned? If so, jump to the vectorized loop. ++ Note: aligning to 64-byte will necessarily slow down performance for ++ strings around 64 bytes in length due to the extra comparisons ++ required to check alignment for the vectorized loop. This is a ++ necessary tradeoff we are willing to take in order to speed up the ++ calculation for larger strings. */ ++ andi. r10,r9,63 ++ beq cr0,L(preloop) ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ bne cr7,L(dword_zero) ++ ++ andi. r10,r9,63 ++ beq cr0,L(preloop) ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ bne cr7,L(dword_zero) ++ ++ andi. r10,r9,63 ++ beq cr0,L(preloop) ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ bne cr7,L(dword_zero) ++ ++ andi. r10,r9,63 ++ beq cr0,L(preloop) ++ ld r6,8(r4) ++ ldu r5,16(r4) ++ cmpb r10,r6,r0 ++ cmpb r11,r5,r0 ++ or r5,r10,r11 ++ cmpdi cr7,r5,0 ++ addi r9,r9,16 ++ ++ /* At this point, we are necessarily 64-byte aligned. If no zeroes were ++ found, jump to the vectorized loop. */ ++ beq cr7,L(preloop) ++ ++L(dword_zero): ++ /* OK, one (or both) of the doublewords contains a null byte. Check ++ the first doubleword and decrement the address in case the first ++ doubleword really contains a null byte. */ ++ ++ cmpdi cr6,r10,0 ++ addi r4,r4,-8 ++ bne cr6,L(done) ++ ++ /* The null byte must be in the second doubleword. Adjust the address ++ again and move the result of cmpb to r10 so we can calculate the ++ length. */ ++ ++ mr r10,r11 ++ addi r4,r4,8 ++ ++ /* If the null byte was found in the non-vectorized code, compute the ++ final length. r10 has the output of the cmpb instruction, that is, ++ it contains 0xff in the same position as the null byte in the ++ original doubleword from the string. Use that to calculate the ++ length. */ ++L(done): ++#ifdef __LITTLE_ENDIAN__ ++ addi r9, r10,-1 /* Form a mask from trailing zeros. */ ++ andc r9, r9,r10 ++ popcntd r0, r9 /* Count the bits in the mask. */ ++#else ++ cntlzd r0,r10 /* Count leading zeros before the match. */ ++#endif ++ subf r5,r3,r4 ++ srdi r0,r0,3 /* Convert leading/trailing zeros to bytes. */ ++ add r3,r5,r0 /* Compute final length. */ ++ blr ++ ++ /* Vectorized implementation starts here. */ ++ .p2align 4 ++L(preloop): ++ /* Set up for the loop. */ ++ mr r4,r9 ++ li r7, 16 /* Load required offsets. */ ++ li r8, 32 ++ li r9, 48 ++ li r12, 8 ++ vxor v0,v0,v0 /* VR with null chars to use with ++ vcmpequb. */ ++ ++ /* Main loop to look for the end of the string. We will read in ++ 64-byte chunks. Align it to 32 bytes and unroll it 3 times to ++ leverage the icache performance. */ ++ .p2align 5 ++L(loop): ++ lvx v1,r4,r0 /* Load 4 quadwords. */ ++ lvx v2,r4,r7 ++ lvx v3,r4,r8 ++ lvx v4,r4,r9 ++ vminub v5,v1,v2 /* Compare and merge into one VR for speed. */ ++ vminub v6,v3,v4 ++ vminub v7,v5,v6 ++ vcmpequb. v7,v7,v0 /* Check for NULLs. */ ++ addi r4,r4,64 /* Adjust address for the next iteration. */ ++ bne cr6,L(vmx_zero) ++ ++ lvx v1,r4,r0 /* Load 4 quadwords. */ ++ lvx v2,r4,r7 ++ lvx v3,r4,r8 ++ lvx v4,r4,r9 ++ vminub v5,v1,v2 /* Compare and merge into one VR for speed. */ ++ vminub v6,v3,v4 ++ vminub v7,v5,v6 ++ vcmpequb. v7,v7,v0 /* Check for NULLs. */ ++ addi r4,r4,64 /* Adjust address for the next iteration. */ ++ bne cr6,L(vmx_zero) ++ ++ lvx v1,r4,r0 /* Load 4 quadwords. */ ++ lvx v2,r4,r7 ++ lvx v3,r4,r8 ++ lvx v4,r4,r9 ++ vminub v5,v1,v2 /* Compare and merge into one VR for speed. */ ++ vminub v6,v3,v4 ++ vminub v7,v5,v6 ++ vcmpequb. v7,v7,v0 /* Check for NULLs. */ ++ addi r4,r4,64 /* Adjust address for the next iteration. */ ++ beq cr6,L(loop) ++ ++L(vmx_zero): ++ /* OK, we found a null byte. Let's look for it in the current 64-byte ++ block and mark it in its corresponding VR. */ ++ vcmpequb v1,v1,v0 ++ vcmpequb v2,v2,v0 ++ vcmpequb v3,v3,v0 ++ vcmpequb v4,v4,v0 ++ ++ /* We will now 'compress' the result into a single doubleword, so it ++ can be moved to a GPR for the final calculation. First, we ++ generate an appropriate mask for vbpermq, so we can permute bits into ++ the first halfword. */ ++ vspltisb v10,3 ++ lvsl v11,r0,r0 ++ vslb v10,v11,v10 ++ ++ /* Permute the first bit of each byte into bits 48-63. */ ++ VBPERMQ(v1,v1,v10) ++ VBPERMQ(v2,v2,v10) ++ VBPERMQ(v3,v3,v10) ++ VBPERMQ(v4,v4,v10) ++ ++ /* Shift each component into its correct position for merging. */ ++#ifdef __LITTLE_ENDIAN__ ++ vsldoi v2,v2,v2,2 ++ vsldoi v3,v3,v3,4 ++ vsldoi v4,v4,v4,6 ++#else ++ vsldoi v1,v1,v1,6 ++ vsldoi v2,v2,v2,4 ++ vsldoi v3,v3,v3,2 ++#endif ++ ++ /* Merge the results and move to a GPR. */ ++ vor v1,v2,v1 ++ vor v2,v3,v4 ++ vor v4,v1,v2 ++ MFVRD(r10,v4) ++ ++ /* Adjust address to the begninning of the current 64-byte block. */ ++ addi r4,r4,-64 ++ ++#ifdef __LITTLE_ENDIAN__ ++ addi r9, r10,-1 /* Form a mask from trailing zeros. */ ++ andc r9, r9,r10 ++ popcntd r0, r9 /* Count the bits in the mask. */ ++#else ++ cntlzd r0,r10 /* Count leading zeros before the match. */ ++#endif ++ subf r5,r3,r4 ++ add r3,r5,r0 /* Compute final length. */ ++ blr ++ ++END (strlen) ++libc_hidden_builtin_def (strlen) +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-13.patch b/SOURCES/glibc-rh1385004-13.patch new file mode 100644 index 00000000..a8a97550 --- /dev/null +++ b/SOURCES/glibc-rh1385004-13.patch @@ -0,0 +1,795 @@ +From 7cb28f3e21ff0c9658fad3d021e5a5548e1e49ae Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 20 Apr 2016 23:10:42 +0530 +Subject: [PATCH] powerpc: strcasestr optmization for power8 + +This patch optimizes strcasestr function for power >= 8 systems. The average +improvement of this optimization is ~40% and compares 16 bytes at a time +using vector instructions. This patch is tested on powerpc64 and powerpc64le. + +(cherry picked from commit e413b14e18ac635b5683ab7bbb1c901f79d1b06b) +--- + ChangeLog | 15 + + sysdeps/powerpc/locale-defines.sym | 4 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 + + .../powerpc64/multiarch/strcasestr-power8.S | 49 ++ + .../powerpc/powerpc64/multiarch/strcasestr-ppc64.c | 34 ++ + sysdeps/powerpc/powerpc64/multiarch/strcasestr.c | 37 ++ + sysdeps/powerpc/powerpc64/power8/Makefile | 3 + + .../powerpc/powerpc64/power8/strcasestr-ppc64.c | 29 ++ + sysdeps/powerpc/powerpc64/power8/strcasestr.S | 531 +++++++++++++++++++++ + 10 files changed, 712 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasestr-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasestr.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/Makefile + create mode 100644 sysdeps/powerpc/powerpc64/power8/strcasestr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/strcasestr.S + +diff --git a/ChangeLog b/ChangeLog +index e7ea58a..6677ea2 100644 +diff --git a/sysdeps/powerpc/locale-defines.sym b/sysdeps/powerpc/locale-defines.sym +index af64b92..5c5379c 100644 +--- a/sysdeps/powerpc/locale-defines.sym ++++ b/sysdeps/powerpc/locale-defines.sym +@@ -3,3 +3,7 @@ + -- + + LOCALE_CTYPE_TOLOWER offsetof (struct __locale_struct, __ctype_tolower) ++LOCALE_CTYPE_TOUPPER offsetof (struct __locale_struct, __ctype_toupper) ++_NL_CTYPE_NONASCII_CASE ++LOCALE_DATA_VALUES offsetof (struct __locale_data, values) ++SIZEOF_VALUES sizeof (((struct __locale_data *) 0)->values[0]) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 57abe8f..7f70ceb 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -20,6 +20,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ ++ strcasestr-power8 strcasestr-ppc64 \ + strcat-power8 strcat-power7 strcat-ppc64 \ + strcmp-power8 strcmp-power7 strcmp-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 583885c..994e852 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -341,6 +341,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strstr, 1, + __strstr_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcasestr.c. */ ++ IFUNC_IMPL (i, name, strcasestr, ++ IFUNC_IMPL_ADD (array, i, strcasestr, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strcasestr_power8) ++ IFUNC_IMPL_ADD (array, i, strcasestr, 1, ++ __strcasestr_ppc)) ++ + /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c. */ + IFUNC_IMPL (i, name, wcschr, + IFUNC_IMPL_ADD (array, i, wcschr, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-power8.S +new file mode 100644 +index 0000000..c77ff9f +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-power8.S +@@ -0,0 +1,49 @@ ++/* Optimized strcasestr implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcasestr_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcasestr_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcasestr_power8) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcasestr_power8) \ ++ END_2(__strcasestr_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++/* The following definitions are used in strcasestr optimization. */ ++ ++/* strlen is used to calculate len of r4. */ ++#define STRLEN __strlen_power8 ++/* strnlen is used to check if len of r3 is more than r4. */ ++#define STRNLEN __strnlen_power7 ++/* strchr is used to check if first char of r4 is present in r3. */ ++#define STRCHR __strchr_power7 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c +new file mode 100644 +index 0000000..7f7bb9e +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c +@@ -0,0 +1,34 @@ ++/* PowerPC64 default implementation of strcasestr. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRCASESTR __strcasestr_ppc ++#if IS_IN (libc) && defined(SHARED) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1(__strcasestr_ppc, __GI_strcasestr, __strcasestr_ppc); ++#endif ++ ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++extern __typeof (strcasestr) __strcasestr_ppc attribute_hidden; ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c +new file mode 100644 +index 0000000..17ba188 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c +@@ -0,0 +1,37 @@ ++/* Multiple versions of strcasestr. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if IS_IN (libc) ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__strcasestr) __strcasestr_ppc attribute_hidden; ++extern __typeof (__strcasestr) __strcasestr_power8 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__strcasestr, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strcasestr_power8 ++ : __strcasestr_ppc); ++ ++weak_alias (__strcasestr, strcasestr) ++#else ++#include ++#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/Makefile b/sysdeps/powerpc/powerpc64/power8/Makefile +new file mode 100644 +index 0000000..71a5952 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/Makefile +@@ -0,0 +1,3 @@ ++ifeq ($(subdir),string) ++sysdep_routines += strcasestr-ppc64 ++endif +diff --git a/sysdeps/powerpc/powerpc64/power8/strcasestr-ppc64.c b/sysdeps/powerpc/powerpc64/power8/strcasestr-ppc64.c +new file mode 100644 +index 0000000..09a07b0 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strcasestr-ppc64.c +@@ -0,0 +1,29 @@ ++/* Optimized strcasestr implementation for PowerPC64/POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRCASESTR __strcasestr_ppc ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(__name) ++ ++#undef weak_alias ++#define weak_alias(a,b) ++extern __typeof (strcasestr) __strcasestr_ppc attribute_hidden; ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/power8/strcasestr.S b/sysdeps/powerpc/powerpc64/power8/strcasestr.S +new file mode 100644 +index 0000000..24b2b76 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strcasestr.S +@@ -0,0 +1,531 @@ ++/* Optimized strcasestr implementation for PowerPC64/POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++/* Char * [r3] strcasestr (char *s [r3], char * pat[r4]) */ ++ ++/* The performance gain is obtained by comparing 16 bytes. */ ++ ++/* When the first char of r4 is hit ITERATIONS times in r3 ++ fallback to default. */ ++#define ITERATIONS 64 ++ ++#ifndef STRLEN ++/* For builds without IFUNC support, local calls should be made to internal ++ GLIBC symbol (created by libc_hidden_builtin_def). */ ++# ifdef SHARED ++# define STRLEN __GI_strlen ++# else ++# define STRLEN strlen ++# endif ++#endif ++ ++#ifndef STRNLEN ++/* For builds without IFUNC support, local calls should be made to internal ++ GLIBC symbol (created by libc_hidden_builtin_def). */ ++# ifdef SHARED ++# define STRNLEN __GI_strnlen ++# else ++# define STRNLEN __strnlen ++# endif ++#endif ++ ++#ifndef STRCHR ++# ifdef SHARED ++# define STRCHR __GI_strchr ++# else ++# define STRCHR strchr ++# endif ++#endif ++ ++/* Convert 16 bytes of v4 and reg to lowercase and compare. */ ++#define TOLOWER(reg) \ ++ vcmpgtub v6, v4, v1; \ ++ vcmpgtub v7, v2, v4; \ ++ vand v8, v7, v6; \ ++ vand v8, v8, v3; \ ++ vor v4, v8, v4; \ ++ vcmpgtub v6, reg, v1; \ ++ vcmpgtub v7, v2, reg; \ ++ vand v8, v7, v6; \ ++ vand v8, v8, v3; \ ++ vor reg, v8, reg; \ ++ vcmpequb. v6, reg, v4; ++ ++/* TODO: change these to the actual instructions when the minimum required ++ binutils allows it. */ ++#ifdef _ARCH_PWR8 ++#define VCLZD_V8_v7 vclzd v8, v7; ++#else ++#define VCLZD_V8_v7 .long 0x11003fc2 ++#endif ++ ++#define FRAMESIZE (FRAME_MIN_SIZE+48) ++/* TODO: change this to .machine power8 when the minimum required binutils ++ allows it. */ ++ .machine power7 ++EALIGN (strcasestr, 4, 0) ++ CALL_MCOUNT 2 ++ mflr r0 /* Load link register LR to r0. */ ++ std r31, -8(r1) /* Save callers register r31. */ ++ std r30, -16(r1) /* Save callers register r30. */ ++ std r29, -24(r1) /* Save callers register r29. */ ++ std r28, -32(r1) /* Save callers register r28. */ ++ std r27, -40(r1) /* Save callers register r27. */ ++ std r0, 16(r1) /* Store the link register. */ ++ cfi_offset(r31, -8) ++ cfi_offset(r30, -16) ++ cfi_offset(r29, -24) ++ cfi_offset(r28, -32) ++ cfi_offset(r27, -40) ++ cfi_offset(lr, 16) ++ stdu r1, -FRAMESIZE(r1) /* Create the stack frame. */ ++ cfi_adjust_cfa_offset(FRAMESIZE) ++ ++ dcbt 0, r3 ++ dcbt 0, r4 ++ cmpdi cr7, r3, 0 /* Input validation. */ ++ beq cr7, L(retnull) ++ cmpdi cr7, r4, 0 ++ beq cr7, L(retnull) ++ ++ mr r29, r3 ++ mr r30, r4 ++ /* Load first byte from r4 and check if its null. */ ++ lbz r6, 0(r4) ++ cmpdi cr7, r6, 0 ++ beq cr7, L(ret_r3) ++ ++ ld r10, __libc_tsd_LOCALE@got@tprel(r2) ++ add r9, r10, __libc_tsd_LOCALE@tls ++ ld r9, 0(r9) ++ ld r9, LOCALE_CTYPE_TOUPPER(r9) ++ sldi r10, r6, 2 /* Convert to upper case. */ ++ lwzx r28, r9, r10 ++ ++ ld r10, __libc_tsd_LOCALE@got@tprel(r2) ++ add r11, r10, __libc_tsd_LOCALE@tls ++ ld r11, 0(r11) ++ ld r11, LOCALE_CTYPE_TOLOWER(r11) ++ sldi r10, r6, 2 /* Convert to lower case. */ ++ lwzx r27, r11, r10 ++ ++ /* Check if the first char is present. */ ++ mr r4, r27 ++ bl STRCHR ++ nop ++ mr r5, r3 ++ mr r3, r29 ++ mr r29, r5 ++ mr r4, r28 ++ bl STRCHR ++ nop ++ cmpdi cr7, r29, 0 ++ beq cr7, L(firstpos) ++ cmpdi cr7, r3, 0 ++ beq cr7, L(skipcheck) ++ cmpw cr7, r3, r29 ++ ble cr7, L(firstpos) ++ /* Move r3 to the first occurence. */ ++L(skipcheck): ++ mr r3, r29 ++L(firstpos): ++ mr r29, r3 ++ ++ sldi r9, r27, 8 ++ or r28, r9, r28 ++ /* Reg r27 is used to count the number of iterations. */ ++ li r27, 0 ++ /* If first char of search str is not present. */ ++ cmpdi cr7, r3, 0 ++ ble cr7, L(end) ++ ++ /* Find the length of pattern. */ ++ mr r3, r30 ++ bl STRLEN ++ nop ++ ++ cmpdi cr7, r3, 0 /* If search str is null. */ ++ beq cr7, L(ret_r3) ++ ++ mr r31, r3 ++ mr r4, r3 ++ mr r3, r29 ++ bl STRNLEN ++ nop ++ ++ cmpd cr7, r3, r31 /* If len(r3) < len(r4). */ ++ blt cr7, L(retnull) ++ ++ mr r3, r29 ++ ++ /* Locales not matching ASCII for single bytes. */ ++ ld r10, __libc_tsd_LOCALE@got@tprel(r2) ++ add r9, r10, __libc_tsd_LOCALE@tls ++ ld r9, 0(r9) ++ ld r7, 0(r9) ++ addi r7, r7, LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES ++ lwz r8, 0(r7) ++ cmpdi cr7, r8, 1 ++ beq cr7, L(bytebybyte) ++ ++ /* If len(r4) < 16 handle byte by byte. */ ++ /* For shorter strings we will not use vector registers. */ ++ cmpdi cr7, r31, 16 ++ blt cr7, L(bytebybyte) ++ ++ /* Comparison values used for TOLOWER. */ ++ /* Load v1 = 64('A' - 1), v2 = 91('Z' + 1), v3 = 32 in each byte. */ ++ vspltish v0, 0 ++ vspltisb v5, 2 ++ vspltisb v4, 4 ++ vsl v3, v5, v4 ++ vaddubm v1, v3, v3 ++ vspltisb v5, 15 ++ vaddubm v2, v5, v5 ++ vaddubm v2, v1, v2 ++ vspltisb v4, -3 ++ vaddubm v2, v2, v4 ++ ++ /* ++ 1. Load 16 bytes from r3 and r4 ++ 2. Check if there is null, If yes, proceed byte by byte path. ++ 3. Else,Convert both to lowercase and compare. ++ 4. If they are same proceed to 1. ++ 5. If they dont match, find if first char of r4 is present in the ++ loaded 16 byte of r3. ++ 6. If yes, move position, load next 16 bytes of r3 and proceed to 2. ++ */ ++ ++ mr r8, r3 /* Save r3 for future use. */ ++ mr r4, r30 /* Restore r4. */ ++ clrldi r10, r4, 60 ++ lvx v5, 0, r4 /* Load 16 bytes from r4. */ ++ cmpdi cr7, r10, 0 ++ beq cr7, L(begin2) ++ /* If r4 is unaligned, load another 16 bytes. */ ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v7, 0, r4 ++#else ++ lvsl v7, 0, r4 ++#endif ++ addi r5, r4, 16 ++ lvx v9, 0, r5 ++#ifdef __LITTLE_ENDIAN__ ++ vperm v5, v9, v5, v7 ++#else ++ vperm v5, v5, v9, v7 ++#endif ++L(begin2): ++ lvx v4, 0, r3 ++ vcmpequb. v7, v0, v4 /* Check for null. */ ++ beq cr6, L(nullchk6) ++ b L(trailcheck) ++ ++ .align 4 ++L(nullchk6): ++ clrldi r10, r3, 60 ++ cmpdi cr7, r10, 0 ++ beq cr7, L(next16) ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v7, 0, r3 ++#else ++ lvsl v7, 0, r3 ++#endif ++ addi r5, r3, 16 ++ /* If r3 is unaligned, load another 16 bytes. */ ++ lvx v10, 0, r5 ++#ifdef __LITTLE_ENDIAN__ ++ vperm v4, v10, v4, v7 ++#else ++ vperm v4, v4, v10, v7 ++#endif ++L(next16): ++ vcmpequb. v6, v0, v5 /* Check for null. */ ++ beq cr6, L(nullchk) ++ b L(trailcheck) ++ ++ .align 4 ++L(nullchk): ++ vcmpequb. v6, v0, v4 ++ beq cr6, L(nullchk1) ++ b L(retnull) ++ ++ .align 4 ++L(nullchk1): ++ /* Convert both v3 and v4 to lower. */ ++ TOLOWER(v5) ++ /* If both are same, branch to match. */ ++ blt cr6, L(match) ++ /* Find if the first char is present in next 15 bytes. */ ++#ifdef __LITTLE_ENDIAN__ ++ vspltb v6, v5, 15 ++ vsldoi v7, v0, v4, 15 ++#else ++ vspltb v6, v5, 0 ++ vspltisb v7, 8 ++ vslo v7, v4, v7 ++#endif ++ vcmpequb v7, v6, v7 ++ vcmpequb. v6, v0, v7 ++ /* Shift r3 by 16 bytes and proceed. */ ++ blt cr6, L(shift16) ++ VCLZD_V8_v7 ++#ifdef __LITTLE_ENDIAN__ ++ vspltb v6, v8, 15 ++#else ++ vspltb v6, v8, 7 ++#endif ++ vcmpequb. v6, v6, v1 ++ /* Shift r3 by 8 bytes and proceed. */ ++ blt cr6, L(shift8) ++ b L(begin) ++ ++ .align 4 ++L(match): ++ /* There is a match of 16 bytes, check next bytes. */ ++ cmpdi cr7, r31, 16 ++ mr r29, r3 ++ beq cr7, L(ret_r3) ++ ++L(secondmatch): ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ /* Load next 16 bytes of r3 and r4 and compare. */ ++ clrldi r10, r4, 60 ++ cmpdi cr7, r10, 0 ++ beq cr7, L(nextload) ++ /* Handle unaligned case. */ ++ vor v6, v9, v9 ++ vcmpequb. v7, v0, v6 ++ beq cr6, L(nullchk2) ++ b L(trailcheck) ++ ++ .align 4 ++L(nullchk2): ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v7, 0, r4 ++#else ++ lvsl v7, 0, r4 ++#endif ++ addi r5, r4, 16 ++ /* If r4 is unaligned, load another 16 bytes. */ ++ lvx v9, 0, r5 ++#ifdef __LITTLE_ENDIAN__ ++ vperm v11, v9, v6, v7 ++#else ++ vperm v11, v6, v9, v7 ++#endif ++ b L(compare) ++ ++ .align 4 ++L(nextload): ++ lvx v11, 0, r4 ++L(compare): ++ vcmpequb. v7, v0, v11 ++ beq cr6, L(nullchk3) ++ b L(trailcheck) ++ ++ .align 4 ++L(nullchk3): ++ clrldi r10, r3, 60 ++ cmpdi cr7, r10, 0 ++ beq cr7, L(nextload1) ++ /* Handle unaligned case. */ ++ vor v4, v10, v10 ++ vcmpequb. v7, v0, v4 ++ beq cr6, L(nullchk4) ++ b L(retnull) ++ ++ .align 4 ++L(nullchk4): ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v7, 0, r3 ++#else ++ lvsl v7, 0, r3 ++#endif ++ addi r5, r3, 16 ++ /* If r3 is unaligned, load another 16 bytes. */ ++ lvx v10, 0, r5 ++#ifdef __LITTLE_ENDIAN__ ++ vperm v4, v10, v4, v7 ++#else ++ vperm v4, v4, v10, v7 ++#endif ++ b L(compare1) ++ ++ .align 4 ++L(nextload1): ++ lvx v4, 0, r3 ++L(compare1): ++ vcmpequb. v7, v0, v4 ++ beq cr6, L(nullchk5) ++ b L(retnull) ++ ++ .align 4 ++L(nullchk5): ++ /* Convert both v3 and v4 to lower. */ ++ TOLOWER(v11) ++ /* If both are same, branch to secondmatch. */ ++ blt cr6, L(secondmatch) ++ /* Continue the search. */ ++ b L(begin) ++ ++ .align 4 ++L(trailcheck): ++ ld r10, __libc_tsd_LOCALE@got@tprel(r2) ++ add r11, r10, __libc_tsd_LOCALE@tls ++ ld r11, 0(r11) ++ ld r11, LOCALE_CTYPE_TOLOWER(r11) ++L(loop2): ++ lbz r5, 0(r3) /* Load byte from r3. */ ++ lbz r6, 0(r4) /* Load next byte from r4. */ ++ cmpdi cr7, r6, 0 /* Is it null? */ ++ beq cr7, L(updater3) ++ cmpdi cr7, r5, 0 /* Is it null? */ ++ beq cr7, L(retnull) /* If yes, return. */ ++ addi r3, r3, 1 ++ addi r4, r4, 1 /* Increment r4. */ ++ sldi r10, r5, 2 /* Convert to lower case. */ ++ lwzx r10, r11, r10 ++ sldi r7, r6, 2 /* Convert to lower case. */ ++ lwzx r7, r11, r7 ++ cmpw cr7, r7, r10 /* Compare with byte from r4. */ ++ bne cr7, L(begin) ++ b L(loop2) ++ ++ .align 4 ++L(shift8): ++ addi r8, r8, 7 ++ b L(begin) ++ .align 4 ++L(shift16): ++ addi r8, r8, 15 ++ .align 4 ++L(begin): ++ addi r8, r8, 1 ++ mr r3, r8 ++ /* When our iterations exceed ITERATIONS,fall back to default. */ ++ addi r27, r27, 1 ++ cmpdi cr7, r27, ITERATIONS ++ beq cr7, L(default) ++ mr r4, r30 /* Restore r4. */ ++ b L(begin2) ++ ++ /* Handling byte by byte. */ ++ .align 4 ++L(loop1): ++ mr r3, r8 ++ addi r27, r27, 1 ++ cmpdi cr7, r27, ITERATIONS ++ beq cr7, L(default) ++ mr r29, r8 ++ srdi r4, r28, 8 ++ /* Check if the first char is present. */ ++ bl STRCHR ++ nop ++ mr r5, r3 ++ mr r3, r29 ++ mr r29, r5 ++ sldi r4, r28, 56 ++ srdi r4, r4, 56 ++ bl STRCHR ++ nop ++ cmpdi cr7, r29, 0 ++ beq cr7, L(nextpos) ++ cmpdi cr7, r3, 0 ++ beq cr7, L(skipcheck1) ++ cmpw cr7, r3, r29 ++ ble cr7, L(nextpos) ++ /* Move r3 to first occurence. */ ++L(skipcheck1): ++ mr r3, r29 ++L(nextpos): ++ mr r29, r3 ++ cmpdi cr7, r3, 0 ++ ble cr7, L(retnull) ++L(bytebybyte): ++ ld r10, __libc_tsd_LOCALE@got@tprel(r2) ++ add r11, r10, __libc_tsd_LOCALE@tls ++ ld r11, 0(r11) ++ ld r11, LOCALE_CTYPE_TOLOWER(r11) ++ mr r4, r30 /* Restore r4. */ ++ mr r8, r3 /* Save r3. */ ++ addi r8, r8, 1 ++ ++L(loop): ++ addi r3, r3, 1 ++ lbz r5, 0(r3) /* Load byte from r3. */ ++ addi r4, r4, 1 /* Increment r4. */ ++ lbz r6, 0(r4) /* Load next byte from r4. */ ++ cmpdi cr7, r6, 0 /* Is it null? */ ++ beq cr7, L(updater3) ++ cmpdi cr7, r5, 0 /* Is it null? */ ++ beq cr7, L(retnull) /* If yes, return. */ ++ sldi r10, r5, 2 /* Convert to lower case. */ ++ lwzx r10, r11, r10 ++ sldi r7, r6, 2 /* Convert to lower case. */ ++ lwzx r7, r11, r7 ++ cmpw cr7, r7, r10 /* Compare with byte from r4. */ ++ bne cr7, L(loop1) ++ b L(loop) ++ ++ /* Handling return values. */ ++ .align 4 ++L(updater3): ++ subf r3, r31, r3 /* Reduce r31 (len of r4) from r3. */ ++ b L(end) ++ ++ .align 4 ++L(ret_r3): ++ mr r3, r29 /* Return point of match. */ ++ b L(end) ++ ++ .align 4 ++L(retnull): ++ li r3, 0 /* Substring was not found. */ ++ b L(end) ++ ++ .align 4 ++L(default): ++ mr r4, r30 ++ bl __strcasestr_ppc ++ nop ++ ++ .align 4 ++L(end): ++ addi r1, r1, FRAMESIZE /* Restore stack pointer. */ ++ cfi_adjust_cfa_offset(-FRAMESIZE) ++ ld r0, 16(r1) /* Restore the saved link register. */ ++ ld r27, -40(r1) ++ ld r28, -32(r1) ++ ld r29, -24(r1) /* Restore callers save register r29. */ ++ ld r30, -16(r1) /* Restore callers save register r30. */ ++ ld r31, -8(r1) /* Restore callers save register r31. */ ++ cfi_restore(lr) ++ cfi_restore(r27) ++ cfi_restore(r28) ++ cfi_restore(r29) ++ cfi_restore(r30) ++ cfi_restore(r31) ++ mtlr r0 /* Branch to link register. */ ++ blr ++END (strcasestr) ++libc_hidden_builtin_def (strcasestr) +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-14.patch b/SOURCES/glibc-rh1385004-14.patch new file mode 100644 index 00000000..dab158e5 --- /dev/null +++ b/SOURCES/glibc-rh1385004-14.patch @@ -0,0 +1,303 @@ +From f4f918430b6b74f1801ebe39a8824cc5437ba9d4 Mon Sep 17 00:00:00 2001 +From: "Paul E. Murphy" +Date: Mon, 25 Apr 2016 09:11:02 -0500 +Subject: [PATCH] powerpc: Add optimized strcspn for P8 + +A few minor adjustments to the P8 strspn gives us +an almost equally optimized P8 strcspn. + +(cherry picked from commit 8f1b841e452dbb083112fd036033b7f4af506ba0) +--- + ChangeLog | 25 ++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 4 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 ++++ + .../powerpc/powerpc64/multiarch/strcspn-power8.S | 25 ++++++++++++ + .../powerpc/powerpc64/multiarch/strcspn-ppc64.c | 26 +++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strcspn.c | 35 +++++++++++++++++ + .../powerpc/powerpc64/multiarch/strspn-power8.S | 17 +------- + sysdeps/powerpc/powerpc64/power8/strcspn.S | 20 ++++++++++ + sysdeps/powerpc/powerpc64/power8/strspn.S | 45 ++++++++++++++++------ + 9 files changed, 176 insertions(+), 29 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcspn-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcspn.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/strcspn.S + +diff --git a/ChangeLog b/ChangeLog +index 6677ea2..5537fc6 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 7f70ceb..9ee9bc2 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -20,6 +20,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strcat-power8 strcat-power7 strcat-ppc64 \ + strcmp-power8 strcmp-power7 strcmp-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ ++ strcspn-power8 strcspn-ppc64 \ + stpncpy-power8 stpncpy-power7 stpncpy-ppc64 \ + strncpy-power8 strncpy-power7 strncpy-ppc64 \ + strncat-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 994e852..228891f 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -332,6 +332,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strspn, 1, + __strspn_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcspn.c. */ ++ IFUNC_IMPL (i, name, strcspn, ++ IFUNC_IMPL_ADD (array, i, strcspn, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strcspn_power8) ++ IFUNC_IMPL_ADD (array, i, strcspn, 1, ++ __strcspn_ppc)) ++ + /* Support sysdeps/powerpc/powerpc64/multiarch/strstr.c. */ + IFUNC_IMPL (i, name, strstr, + IFUNC_IMPL_ADD (array, i, strstr, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcspn-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strcspn-power8.S +new file mode 100644 +index 0000000..25545f8 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn-power8.S +@@ -0,0 +1,25 @@ ++/* Optimized strcspn implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRSPN __strcspn_power8 ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c +new file mode 100644 +index 0000000..4c16386 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c +@@ -0,0 +1,26 @@ ++/* Default strcspn implementation for PowerPC64. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRCSPN __strcspn_ppc ++ ++#ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) ++#endif ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcspn.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c +new file mode 100644 +index 0000000..e7343ee +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c +@@ -0,0 +1,35 @@ ++/* Multiple versions of strcspn. PowerPC64 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include "init-arch.h" ++ ++#undef strcspn ++extern __typeof (strcspn) __libc_strcspn; ++ ++extern __typeof (strcspn) __strcspn_ppc attribute_hidden; ++extern __typeof (strcspn) __strcspn_power8 attribute_hidden; ++ ++libc_ifunc (__libc_strcspn, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strcspn_power8 ++ : __strcspn_ppc); ++ ++weak_alias (__libc_strcspn, strcspn) ++libc_hidden_builtin_def (strcspn) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S +index 86a4e09..27d25e0 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/strspn-power8.S +@@ -18,22 +18,7 @@ + + #include + +-#undef EALIGN +-#define EALIGN(name, alignt, words) \ +- .section ".text"; \ +- ENTRY_2(__strspn_power8) \ +- .align ALIGNARG(alignt); \ +- EALIGN_W_##words; \ +- BODY_LABEL(__strspn_power8): \ +- cfi_startproc; \ +- LOCALENTRY(__strspn_power8) +- +-#undef END +-#define END(name) \ +- cfi_endproc; \ +- TRACEBACK(__strspn_power8) \ +- END_2(__strspn_power8) +- ++#define STRSPN __strspn_power8 + #undef libc_hidden_builtin_def + #define libc_hidden_builtin_def(name) + +diff --git a/sysdeps/powerpc/powerpc64/power8/strcspn.S b/sysdeps/powerpc/powerpc64/power8/strcspn.S +new file mode 100644 +index 0000000..bfc58a8 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strcspn.S +@@ -0,0 +1,20 @@ ++/* Optimized strcspn implementation for PowerPC64/POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_STRCSPN 1 ++#include +diff --git a/sysdeps/powerpc/powerpc64/power8/strspn.S b/sysdeps/powerpc/powerpc64/power8/strspn.S +index 0dda437..011081d 100644 +--- a/sysdeps/powerpc/powerpc64/power8/strspn.S ++++ b/sysdeps/powerpc/powerpc64/power8/strspn.S +@@ -33,6 +33,21 @@ + + #include "sysdep.h" + ++#ifndef USE_AS_STRCSPN ++# define USE_AS_STRCSPN 0 ++# ifndef STRSPN ++# define STRSPN strspn ++# endif ++# define INITIAL_MASK 0 ++# define UPDATE_MASK(RA, RS, RB) or RA, RS, RB ++#else ++# ifndef STRSPN ++# define STRSPN strcspn ++# endif ++# define INITIAL_MASK -1 ++# define UPDATE_MASK(RA, RS, RB) andc RA, RS, RB ++#endif ++ + /* Simple macro to use VSX instructions in overlapping VR's. */ + #define XXVR(insn, vrt, vra, vrb) \ + insn 32+vrt, 32+vra, 32+vrb +@@ -53,7 +68,7 @@ + /* This can be updated to power8 once the minimum version of + binutils supports power8 and the above instructions. */ + .machine power7 +-EALIGN(strspn, 4, 0) ++EALIGN(STRSPN, 4, 0) + CALL_MCOUNT 2 + + /* Generate useful constants for later on. */ +@@ -66,10 +81,18 @@ EALIGN(strspn, 4, 0) + + /* Prepare to compute 256b mask. */ + addi r4, r4, -1 +- li r5, 0 +- li r6, 0 +- li r7, 0 +- li r8, 0 ++ li r5, INITIAL_MASK ++ li r6, INITIAL_MASK ++ li r7, INITIAL_MASK ++ li r8, INITIAL_MASK ++ ++#if USE_AS_STRCSPN ++ /* Ensure the null character never matches by clearing ISA bit 0 in ++ in r5 which is the bit which will check for it in the later usage ++ of vbpermq. */ ++ srdi r5, r5, 1 ++#endif ++ + li r11, 1 + sldi r11, r11, 63 + +@@ -97,14 +120,14 @@ L(next_needle): + + /* Now, or the value into the correct GPR. */ + bge cr1,L(needle_gt128) +- or r5, r5, r10 /* 0 - 63. */ +- or r6, r6, r12 /* 64 - 127. */ ++ UPDATE_MASK (r5, r5, r10) /* 0 - 63. */ ++ UPDATE_MASK (r6, r6, r12) /* 64 - 127. */ + b L(next_needle) + + .align 4 + L(needle_gt128): +- or r7, r7, r10 /* 128 - 191. */ +- or r8, r8, r12 /* 192 - 255. */ ++ UPDATE_MASK (r7, r7, r10) /* 128 - 191. */ ++ UPDATE_MASK (r8, r8, r12) /* 192 - 255. */ + b L(next_needle) + + +@@ -175,5 +198,5 @@ L(done): + add r3, r3, r10 + blr + +-END(strspn) +-libc_hidden_builtin_def (strspn) ++END(STRSPN) ++libc_hidden_builtin_def (STRSPN) +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-15.patch b/SOURCES/glibc-rh1385004-15.patch new file mode 100644 index 00000000..a855fb56 --- /dev/null +++ b/SOURCES/glibc-rh1385004-15.patch @@ -0,0 +1,632 @@ +From 71ae86478edc7b21872464f43fb29ff650c1681a Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Tue, 15 Jul 2014 12:19:09 -0400 +Subject: [PATCH] PowerPC: memset optimization for POWER8/PPC64 + +This patch adds an optimized memset implementation for POWER8. For +sizes from 0 to 255 bytes, a word/doubleword algorithm similar to +POWER7 optimized one is used. + +For size higher than 255 two strategies are used: + +1. If the constant is different than 0, the memory is written with + altivec vector instruction; + +2. If constant is 0, dbcz instructions are used. The loop is unrolled + to clear 512 byte at time. + +Using vector instructions increases throughput considerable, with a +double performance for sizes larger than 1024. The dcbz loops unrolls +also shows performance improvement, by doubling throughput for sizes +larger than 8192 bytes. +--- + ChangeLog | 15 + + benchtests/bench-memset.c | 5 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + sysdeps/powerpc/powerpc64/multiarch/bzero.c | 11 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 6 + + .../powerpc/powerpc64/multiarch/memset-power8.S | 43 ++ + sysdeps/powerpc/powerpc64/multiarch/memset.c | 11 +- + sysdeps/powerpc/powerpc64/power8/memset.S | 449 +++++++++++++++++++++ + 8 files changed, 533 insertions(+), 9 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/power8/memset.S + +diff --git a/ChangeLog b/ChangeLog +index ddaf70f..dc61c87 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 0de3804..abc9d2e 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -1,7 +1,8 @@ ifeq ($(subdir),string) + ifeq ($(subdir),string) + sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \ +- memcmp-ppc64 memset-power7 memset-power6 memset-power4 \ ++ memcmp-ppc64 memset-power8 memset-power7 memset-power6 \ ++ memset-power4 \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero.c b/sysdeps/powerpc/powerpc64/multiarch/bzero.c +index ed83541..298cf00 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/bzero.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/bzero.c +@@ -26,14 +26,17 @@ extern __typeof (bzero) __bzero_ppc attribute_hidden; + extern __typeof (bzero) __bzero_power4 attribute_hidden; + extern __typeof (bzero) __bzero_power6 attribute_hidden; + extern __typeof (bzero) __bzero_power7 attribute_hidden; ++extern __typeof (bzero) __bzero_power8 attribute_hidden; + + libc_ifunc (__bzero, +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __bzero_power7 : +- (hwcap & PPC_FEATURE_ARCH_2_05) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __bzero_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __bzero_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) + ? __bzero_power6 : + (hwcap & PPC_FEATURE_POWER4) +- ? __bzero_power4 ++ ? __bzero_power4 + : __bzero_ppc); + + weak_alias (__bzero, bzero) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index a574487..06d5be9 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -69,6 +71,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/powerpc/powerpc64/multiarch/memset.c. */ + IFUNC_IMPL (i, name, memset, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __memset_power8) + IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX, + __memset_power7) + IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05, +@@ -134,6 +138,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/powerpc/powerpc64/multiarch/bzero.c. */ + IFUNC_IMPL (i, name, bzero, ++ IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __bzero_power8) + IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX, + __bzero_power7) + IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power8.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power8.S +new file mode 100644 +index 0000000..e8a604b +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power8.S +@@ -0,0 +1,43 @@ ++/* Optimized memset implementation for PowerPC64/POWER8. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memset_power8) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memset_power8): \ ++ cfi_startproc; \ ++ LOCALENTRY(__memset_power8) ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memset_power8,mask) \ ++ END_2(__memset_power8) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#undef __bzero ++#define __bzero __bzero_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c +index aa2ae70..9c7ed10 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c +@@ -32,16 +32,19 @@ extern __typeof (__redirect_memset) __memset_ppc attribute_hidden; + extern __typeof (__redirect_memset) __memset_power4 attribute_hidden; + extern __typeof (__redirect_memset) __memset_power6 attribute_hidden; + extern __typeof (__redirect_memset) __memset_power7 attribute_hidden; ++extern __typeof (__redirect_memset) __memset_power8 attribute_hidden; + + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (__libc_memset, +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __memset_power7 : +- (hwcap & PPC_FEATURE_ARCH_2_05) ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __memset_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __memset_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) + ? __memset_power6 : + (hwcap & PPC_FEATURE_POWER4) +- ? __memset_power4 ++ ? __memset_power4 + : __memset_ppc); + + #undef memset +diff --git a/sysdeps/powerpc/powerpc64/power8/memset.S b/sysdeps/powerpc/powerpc64/power8/memset.S +new file mode 100644 +index 0000000..191a4df +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/memset.S +@@ -0,0 +1,449 @@ ++/* Optimized memset implementation for PowerPC64/POWER8. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5])); ++ Returns 's'. */ ++ ++ .machine power8 ++EALIGN (memset, 5, 0) ++ CALL_MCOUNT 3 ++ ++L(_memset): ++ cmpldi cr7,r5,31 ++ neg r0,r3 ++ mr r10,r3 ++ ++ insrdi r4,r4,8,48 ++ insrdi r4,r4,16,32 /* Replicate byte to word. */ ++ ble cr7,L(write_LT_32) ++ ++ andi. r11,r10,15 /* Check alignment of DST. */ ++ insrdi r4,r4,32,0 /* Replicate word to double word. */ ++ ++ beq L(big_aligned) ++ ++ mtocrf 0x01,r0 ++ clrldi r0,r0,60 ++ ++ /* Get DST aligned to 16 bytes. */ ++1: bf 31,2f ++ stb r4,0(r10) ++ addi r10,r10,1 ++ ++2: bf 30,4f ++ sth r4,0(r10) ++ addi r10,r10,2 ++ ++4: bf 29,8f ++ stw r4,0(r10) ++ addi r10,r10,4 ++ ++8: bf 28,16f ++ std r4,0(r10) ++ addi r10,r10,8 ++ ++16: subf r5,r0,r5 ++ ++ .align 4 ++L(big_aligned): ++ /* For sizes larger than 255 two possible paths: ++ - if constant is '0', zero full cache lines with dcbz ++ - otherwise uses vector instructions. */ ++ cmpldi cr5,r5,255 ++ dcbtst 0,r10 ++ cmpldi cr6,r4,0 ++ crand 27,26,21 ++ bt 27,L(huge_dcbz) ++ bge cr5,L(huge_vector) ++ ++ ++ /* Size between 32 and 255 bytes with constant different than 0, use ++ doubleword store instruction to achieve best throughput. */ ++ srdi r8,r5,5 ++ clrldi r11,r5,59 ++ cmpldi cr6,r11,0 ++ cmpdi r8,0 ++ beq L(tail_bytes) ++ mtctr r8 ++ ++ /* Main aligned write loop, writes 32-bytes at a time. */ ++ .align 4 ++L(big_loop): ++ std r4,0(r10) ++ std r4,8(r10) ++ std r4,16(r10) ++ std r4,24(r10) ++ addi r10,r10,32 ++ bdz L(tail_bytes) ++ ++ std r4,0(r10) ++ std r4,8(r10) ++ std r4,16(r10) ++ std r4,24(r10) ++ addi r10,10,32 ++ bdnz L(big_loop) ++ ++ b L(tail_bytes) ++ ++ /* Write remaining 1~31 bytes. */ ++ .align 4 ++L(tail_bytes): ++ beqlr cr6 ++ ++ srdi r7,r11,4 ++ clrldi r8,r11,60 ++ mtocrf 0x01,r7 ++ ++ .align 4 ++ bf 31,8f ++ std r4,0(r10) ++ std r4,8(r10) ++ addi r10,r10,16 ++ ++ .align 4 ++8: mtocrf 0x1,r8 ++ bf 28,4f ++ std r4,0(r10) ++ addi r10,r10,8 ++ ++ .align 4 ++4: bf 29,2f ++ stw 4,0(10) ++ addi 10,10,4 ++ ++ .align 4 ++2: bf 30,1f ++ sth 4,0(10) ++ addi 10,10,2 ++ ++ .align 4 ++1: bflr 31 ++ stb 4,0(10) ++ blr ++ ++ /* Size larger than 255 bytes with constant different than 0, use ++ vector instruction to achieve best throughput. */ ++L(huge_vector): ++ /* Replicate set byte to quadword in VMX register. */ ++ mtvsrd v1,r4 ++ xxpermdi 32,v0,v1,0 ++ vspltb v2,v0,15 ++ ++ /* Main aligned write loop: 128 bytes at a time. */ ++ li r6,16 ++ li r7,32 ++ li r8,48 ++ mtocrf 0x02,r5 ++ srdi r12,r5,7 ++ cmpdi r12,0 ++ beq L(aligned_tail) ++ mtctr r12 ++ b L(aligned_128loop) ++ ++ .align 4 ++L(aligned_128loop): ++ stvx v2,0,r10 ++ stvx v2,r10,r6 ++ stvx v2,r10,r7 ++ stvx v2,r10,r8 ++ addi r10,r10,64 ++ stvx v2,0,r10 ++ stvx v2,r10,r6 ++ stvx v2,r10,r7 ++ stvx v2,r10,r8 ++ addi r10,r10,64 ++ bdnz L(aligned_128loop) ++ ++ /* Write remaining 1~127 bytes. */ ++L(aligned_tail): ++ mtocrf 0x01,r5 ++ bf 25,32f ++ stvx v2,0,r10 ++ stvx v2,r10,r6 ++ stvx v2,r10,r7 ++ stvx v2,r10,r8 ++ addi r10,r10,64 ++ ++32: bf 26,16f ++ stvx v2,0,r10 ++ stvx v2,r10,r6 ++ addi r10,r10,32 ++ ++16: bf 27,8f ++ stvx v2,0,r10 ++ addi r10,r10,16 ++ ++8: bf 28,4f ++ std r4,0(r10) ++ addi r10,r10,8 ++ ++ /* Copies 4~7 bytes. */ ++4: bf 29,L(tail2) ++ stw r4,0(r10) ++ bf 30,L(tail5) ++ sth r4,4(r10) ++ bflr 31 ++ stb r4,6(r10) ++ /* Return original DST pointer. */ ++ blr ++ ++ /* Special case when value is 0 and we have a long length to deal ++ with. Use dcbz to zero out a full cacheline of 128 bytes at a time. ++ Before using dcbz though, we need to get the destination 128-byte ++ aligned. */ ++ .align 4 ++L(huge_dcbz): ++ andi. r11,r10,127 ++ neg r0,r10 ++ beq L(huge_dcbz_aligned) ++ ++ clrldi r0,r0,57 ++ subf r5,r0,r5 ++ srdi r0,r0,3 ++ mtocrf 0x01,r0 ++ ++ /* Write 1~128 bytes until DST is aligned to 128 bytes. */ ++8: bf 28,4f ++ ++ std r4,0(r10) ++ std r4,8(r10) ++ std r4,16(r10) ++ std r4,24(r10) ++ std r4,32(r10) ++ std r4,40(r10) ++ std r4,48(r10) ++ std r4,56(r10) ++ addi r10,r10,64 ++ ++ .align 4 ++4: bf 29,2f ++ std r4,0(r10) ++ std r4,8(r10) ++ std r4,16(r10) ++ std r4,24(r10) ++ addi r10,r10,32 ++ ++ .align 4 ++2: bf 30,1f ++ std r4,0(r10) ++ std r4,8(r10) ++ addi r10,r10,16 ++ ++ .align 4 ++1: bf 31,L(huge_dcbz_aligned) ++ std r4,0(r10) ++ addi r10,r10,8 ++ ++L(huge_dcbz_aligned): ++ /* Setup dcbz unroll offsets and count numbers. */ ++ srdi r8,r5,9 ++ clrldi r11,r5,55 ++ cmpldi cr6,r11,0 ++ li r9,128 ++ cmpdi r8,0 ++ beq L(huge_tail) ++ li r7,256 ++ li r6,384 ++ mtctr r8 ++ ++ .align 4 ++L(huge_loop): ++ /* Sets 512 bytes to zero in each iteration, the loop unrolling shows ++ a throughput boost for large sizes (2048 bytes or higher). */ ++ dcbz 0,r10 ++ dcbz r9,r10 ++ dcbz r7,r10 ++ dcbz r6,r10 ++ addi r10,r10,512 ++ bdnz L(huge_loop) ++ ++ beqlr cr6 ++ ++L(huge_tail): ++ srdi r6,r11,8 ++ srdi r7,r11,4 ++ clrldi r8,r11,4 ++ cmpldi cr6,r8,0 ++ mtocrf 0x01,r6 ++ ++ beq cr6,L(tail) ++ ++ /* We have 1~511 bytes remaining. */ ++ .align 4 ++32: bf 31,16f ++ dcbz 0,r10 ++ dcbz r9,r10 ++ addi r10,r10,256 ++ ++ .align 4 ++16: mtocrf 0x01,r7 ++ bf 28,8f ++ dcbz 0,r10 ++ addi r10,r10,128 ++ ++ .align 4 ++8: bf 29,4f ++ std r4,0(r10) ++ std r4,8(r10) ++ std r4,16(r10) ++ std r4,24(r10) ++ std r4,32(r10) ++ std r4,40(r10) ++ std r4,48(r10) ++ std r4,56(r10) ++ addi r10,r10,64 ++ ++ .align 4 ++4: bf 30,2f ++ std r4,0(r10) ++ std r4,8(r10) ++ std r4,16(r10) ++ std r4,24(r10) ++ addi r10,r10,32 ++ ++ .align 4 ++2: bf 31,L(tail) ++ std r4,0(r10) ++ std r4,8(r10) ++ addi r10,r10,16 ++ .align 4 ++ ++ /* Remaining 1~15 bytes. */ ++L(tail): ++ mtocrf 0x01,r8 ++ ++ .align ++8: bf 28,4f ++ std r4,0(r10) ++ addi r10,r10,8 ++ ++ .align 4 ++4: bf 29,2f ++ stw r4,0(r10) ++ addi r10,r10,4 ++ ++ .align 4 ++2: bf 30,1f ++ sth r4,0(r10) ++ addi r10,r10,2 ++ ++ .align 4 ++1: bflr 31 ++ stb r4,0(r10) ++ blr ++ ++ /* Handle short copies of 0~31 bytes. Best throughput is achieved ++ by just unrolling all operations. */ ++ .align 4 ++L(write_LT_32): ++ cmpldi cr6,5,8 ++ mtocrf 0x01,r5 ++ ble cr6,L(write_LE_8) ++ ++ /* At least 9 bytes to go. */ ++ neg r8,r4 ++ andi. r0,r8,3 ++ cmpldi cr1,r5,16 ++ beq L(write_LT_32_aligned) ++ ++ /* Force 4-byte alignment for SRC. */ ++ mtocrf 0x01,r0 ++ subf r5,r0,r5 ++ ++2: bf 30,1f ++ sth r4,0(r10) ++ addi r10,r10,2 ++ ++1: bf 31,L(end_4bytes_alignment) ++ stb r4,0(r10) ++ addi r10,r10,1 ++ ++ .align 4 ++L(end_4bytes_alignment): ++ cmpldi cr1,r5,16 ++ mtocrf 0x01,r5 ++ ++L(write_LT_32_aligned): ++ blt cr1,8f ++ ++ stw r4,0(r10) ++ stw r4,4(r10) ++ stw r4,8(r10) ++ stw r4,12(r10) ++ addi r10,r10,16 ++ ++8: bf 28,L(tail4) ++ stw r4,0(r10) ++ stw r4,4(r10) ++ addi r10,r10,8 ++ ++ .align 4 ++ /* Copies 4~7 bytes. */ ++L(tail4): ++ bf 29,L(tail2) ++ stw r4,0(r10) ++ bf 30,L(tail5) ++ sth r4,4(r10) ++ bflr 31 ++ stb r4,6(r10) ++ blr ++ ++ .align 4 ++ /* Copies 2~3 bytes. */ ++L(tail2): ++ bf 30,1f ++ sth r4,0(r10) ++ bflr 31 ++ stb r4,2(r10) ++ blr ++ ++ .align 4 ++L(tail5): ++ bflr 31 ++ stb r4,4(r10) ++ blr ++ ++ .align 4 ++1: bflr 31 ++ stb r4,0(r10) ++ blr ++ ++ /* Handles copies of 0~8 bytes. */ ++ .align 4 ++L(write_LE_8): ++ bne cr6,L(tail4) ++ ++ stw r4,0(r10) ++ stw r4,4(r10) ++ blr ++END_GEN_TB (memset,TB_TOCLESS) ++libc_hidden_builtin_def (memset) ++ ++/* Copied from bzero.S to prevent the linker from inserting a stub ++ between bzero and memset. */ ++ENTRY (__bzero) ++ CALL_MCOUNT 3 ++ mr r5,r4 ++ li r4,0 ++ b L(_memset) ++END (__bzero) ++#ifndef __bzero ++weak_alias (__bzero, bzero) ++#endif +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-16.patch b/SOURCES/glibc-rh1385004-16.patch new file mode 100644 index 00000000..a6632809 --- /dev/null +++ b/SOURCES/glibc-rh1385004-16.patch @@ -0,0 +1,189 @@ +From 2ffa8b8660a7a17572ae5a398171c8be59985eb3 Mon Sep 17 00:00:00 2001 +From: "Gabriel F. T. Gomes" +Date: Mon, 25 Jan 2016 10:50:34 -0500 +Subject: [PATCH] powerpc: Zero pad using memset in strncpy/stpncpy + +Call __memset_power8 to pad, with zeros, the remaining bytes in the +dest string on __strncpy_power8 and __stpncpy_power8. This improves +performance when n is larger than the input string, giving ~30% gain for +larger strings without impacting much shorter strings. + +(cherry picked from commit 72c11b353ede72931cc474c9071d143d9a05c0d7) +--- + ChangeLog | 5 ++ + sysdeps/powerpc/powerpc64/power8/strncpy.S | 123 +++++++++++++---------------- + 2 files changed, 61 insertions(+), 67 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5537fc6..8d0e296 100644 +diff --git a/sysdeps/powerpc/powerpc64/power8/strncpy.S b/sysdeps/powerpc/powerpc64/power8/strncpy.S +index 5fda953..80136cc 100644 +--- a/sysdeps/powerpc/powerpc64/power8/strncpy.S ++++ b/sysdeps/powerpc/powerpc64/power8/strncpy.S +@@ -24,6 +24,8 @@ + # define FUNC_NAME strncpy + #endif + ++#define FRAMESIZE (FRAME_MIN_SIZE+48) ++ + /* Implements the function + + char * [r3] strncpy (char *dest [r3], const char *src [r4], size_t n [r5]) +@@ -54,8 +56,7 @@ EALIGN (FUNC_NAME, 4, 0) + addi r10,r4,16 + rlwinm r9,r4,0,19,19 + +- /* Since it is a leaf function, save some non-volatile registers on the +- protected/red zone. */ ++ /* Save some non-volatile registers on the stack. */ + std r26,-48(r1) + std r27,-40(r1) + +@@ -69,6 +70,14 @@ EALIGN (FUNC_NAME, 4, 0) + std r30,-16(r1) + std r31,-8(r1) + ++ /* Update CFI. */ ++ cfi_offset(r26, -48) ++ cfi_offset(r27, -40) ++ cfi_offset(r28, -32) ++ cfi_offset(r29, -24) ++ cfi_offset(r30, -16) ++ cfi_offset(r31, -8) ++ + beq cr7,L(unaligned_lt_16) + rldicl r9,r4,0,61 + subfic r8,r9,8 +@@ -144,74 +153,58 @@ L(short_path_loop_end): + ld r31,-8(r1) + blr + +- /* This code pads the remainder dest with NULL bytes. The algorithm +- calculate the remanining size and issues a doubleword unrolled +- loops followed by a byte a byte set. */ ++ /* This code pads the remainder of dest with NULL bytes. The algorithm ++ calculates the remaining size and calls memset. */ + .align 4 + L(zero_pad_start): + mr r5,r10 + mr r9,r6 + L(zero_pad_start_1): +- srdi. r8,r5,r3 +- mr r10,r9 +-#ifdef USE_AS_STPNCPY +- mr r3,r9 ++ /* At this point: ++ - r5 holds the number of bytes that still have to be written to ++ dest. ++ - r9 points to the position, in dest, where the first null byte ++ will be written. ++ The above statements are true both when control reaches this label ++ from a branch or when falling through the previous lines. */ ++#ifndef USE_AS_STPNCPY ++ mr r30,r3 /* Save the return value of strncpy. */ ++#endif ++ /* Prepare the call to memset. */ ++ mr r3,r9 /* Pointer to the area to be zero-filled. */ ++ li r4,0 /* Byte to be written (zero). */ ++ ++ /* We delayed the creation of the stack frame, as well as the saving of ++ the link register, because only at this point, we are sure that ++ doing so is actually needed. */ ++ ++ /* Save the link register. */ ++ mflr r0 ++ std r0,16(r1) ++ cfi_offset(lr, 16) ++ ++ /* Create the stack frame. */ ++ stdu r1,-FRAMESIZE(r1) ++ cfi_adjust_cfa_offset(FRAMESIZE) ++ ++ bl __memset_power8 ++ nop ++ ++ /* Restore the stack frame. */ ++ addi r1,r1,FRAMESIZE ++ cfi_adjust_cfa_offset(-FRAMESIZE) ++ /* Restore the link register. */ ++ ld r0,16(r1) ++ mtlr r0 ++ ++#ifndef USE_AS_STPNCPY ++ mr r3,r30 /* Restore the return value of strncpy, i.e.: ++ dest. For stpncpy, the return value is the ++ same as return value of memset. */ + #endif +- beq- cr0,L(zero_pad_loop_b_start) +- cmpldi cr7,r8,1 +- li cr7,0 +- std r7,0(r9) +- beq cr7,L(zero_pad_loop_b_prepare) +- addic. r8,r8,-2 +- addi r10,r9,r16 +- std r7,8(r9) +- beq cr0,L(zero_pad_loop_dw_2) +- std r7,16(r9) +- li r9,0 +- b L(zero_pad_loop_dw_1) +- +- .align 4 +-L(zero_pad_loop_dw): +- addi r10,r10,16 +- std r9,-8(r10) +- beq cr0,L(zero_pad_loop_dw_2) +- std r9,0(r10) +-L(zero_pad_loop_dw_1): +- cmpldi cr7,r8,1 +- std r9,0(r10) +- addic. r8,r8,-2 +- bne cr7,L(zero_pad_loop_dw) +- addi r10,r10,8 +-L(zero_pad_loop_dw_2): +- rldicl r5,r5,0,61 +-L(zero_pad_loop_b_start): +- cmpdi cr7,r5,0 +- addi r5,r5,-1 +- addi r9,r10,-1 +- add r10,r10,5 +- subf r10,r9,r10 +- li r8,0 +- beq- cr7,L(short_path_loop_end) +- +- /* Write remaining 1-8 bytes. */ +- .align 4 +- addi r9,r9,1 +- mtocrf 0x1,r10 +- bf 29,4f +- stw r8,0(r9) +- addi r9,r9,4 +- +- .align 4 +-4: bf 30,2f +- sth r8,0(r9) +- addi r9,r9,2 +- +- .align 4 +-2: bf 31,1f +- stb r8,0(r9) + +- /* Restore non-volatile registers. */ +-1: ld r26,-48(r1) ++ /* Restore non-volatile registers and return. */ ++ ld r26,-48(r1) + ld r27,-40(r1) + ld r28,-32(r1) + ld r29,-24(r1) +@@ -407,10 +400,6 @@ L(short_path_prepare_2_3): + mr r4,r28 + mr r9,r29 + b L(short_path_2) +-L(zero_pad_loop_b_prepare): +- addi r10,r9,8 +- rldicl r5,r5,0,61 +- b L(zero_pad_loop_b_start) + L(zero_pad_start_prepare_1): + mr r5,r6 + mr r9,r8 +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-17.patch b/SOURCES/glibc-rh1385004-17.patch new file mode 100644 index 00000000..5e9eaac9 --- /dev/null +++ b/SOURCES/glibc-rh1385004-17.patch @@ -0,0 +1,122 @@ +From e883cafe35f52b3e511dbaf85052f8dddd395a2e Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Mon, 30 May 2016 18:00:57 -0300 +Subject: [PATCH] powerpc: Fix --disable-multi-arch build on POWER8 + +Add missing symbols of stpncpy and strcasestr when multi-arch is +disabled. +Fix memset call from strncpy/stpncpy when multi-arch is disabled. + +(cherry picked from commit c24480ce3b5fed848243fc9642932ef2fa670109) +--- + ChangeLog | 15 +++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S | 3 +++ + sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S | 3 +++ + sysdeps/powerpc/powerpc64/power8/stpncpy.S | 4 ++++ + sysdeps/powerpc/powerpc64/power8/strcasestr.S | 7 +++++-- + sysdeps/powerpc/powerpc64/power8/strncpy.S | 16 ++++++++++++---- + 6 files changed, 42 insertions(+), 6 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 8d0e296..c01d1a0 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S +index d5d835d..d9babb5 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power8.S +@@ -36,4 +36,7 @@ + TRACEBACK(__stpncpy_power8) \ + END_2(__stpncpy_power8) + ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ + #include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S +index ed906a4..f86a0f0 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power8.S +@@ -37,4 +37,7 @@ + #undef libc_hidden_builtin_def + #define libc_hidden_builtin_def(name) + ++/* memset is used to pad the end of the string. */ ++#define MEMSET __memset_power8 ++ + #include +diff --git a/sysdeps/powerpc/powerpc64/power8/stpncpy.S b/sysdeps/powerpc/powerpc64/power8/stpncpy.S +index 76a1466..e66bd0a 100644 +--- a/sysdeps/powerpc/powerpc64/power8/stpncpy.S ++++ b/sysdeps/powerpc/powerpc64/power8/stpncpy.S +@@ -18,3 +18,7 @@ + + #define USE_AS_STPNCPY + #include ++ ++weak_alias (__stpncpy, stpncpy) ++libc_hidden_def (__stpncpy) ++libc_hidden_builtin_def (stpncpy) +diff --git a/sysdeps/powerpc/powerpc64/power8/strcasestr.S b/sysdeps/powerpc/powerpc64/power8/strcasestr.S +index 24b2b76..60015ae 100644 +--- a/sysdeps/powerpc/powerpc64/power8/strcasestr.S ++++ b/sysdeps/powerpc/powerpc64/power8/strcasestr.S +@@ -81,7 +81,7 @@ + /* TODO: change this to .machine power8 when the minimum required binutils + allows it. */ + .machine power7 +-EALIGN (strcasestr, 4, 0) ++EALIGN (__strcasestr, 4, 0) + CALL_MCOUNT 2 + mflr r0 /* Load link register LR to r0. */ + std r31, -8(r1) /* Save callers register r31. */ +@@ -527,5 +527,8 @@ L(end): + cfi_restore(r31) + mtlr r0 /* Branch to link register. */ + blr +-END (strcasestr) ++END (__strcasestr) ++ ++weak_alias (__strcasestr, strcasestr) ++libc_hidden_def (__strcasestr) + libc_hidden_builtin_def (strcasestr) +diff --git a/sysdeps/powerpc/powerpc64/power8/strncpy.S b/sysdeps/powerpc/powerpc64/power8/strncpy.S +index 80136cc..05c7d8a 100644 +--- a/sysdeps/powerpc/powerpc64/power8/strncpy.S ++++ b/sysdeps/powerpc/powerpc64/power8/strncpy.S +@@ -24,6 +24,16 @@ + # define FUNC_NAME strncpy + #endif + ++#ifndef MEMSET ++/* For builds without IFUNC support, local calls should be made to internal ++ GLIBC symbol (created by libc_hidden_builtin_def). */ ++# ifdef SHARED ++# define MEMSET __GI_memset ++# else ++# define MEMSET memset ++# endif ++#endif ++ + #define FRAMESIZE (FRAME_MIN_SIZE+48) + + /* Implements the function +@@ -187,7 +197,7 @@ L(zero_pad_start_1): + stdu r1,-FRAMESIZE(r1) + cfi_adjust_cfa_offset(FRAMESIZE) + +- bl __memset_power8 ++ bl MEMSET + nop + + /* Restore the stack frame. */ +@@ -406,8 +416,6 @@ L(zero_pad_start_prepare_1): + b L(zero_pad_start_1) + END (FUNC_NAME) + +-#ifdef USE_AS_STPNCPY +-libc_hidden_def (__stpncpy) +-#else ++#ifndef USE_AS_STPNCPY + libc_hidden_builtin_def (strncpy) + #endif +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-18.patch b/SOURCES/glibc-rh1385004-18.patch new file mode 100644 index 00000000..858869f0 --- /dev/null +++ b/SOURCES/glibc-rh1385004-18.patch @@ -0,0 +1,803 @@ +From 7dd60718b327b3eb6112ec3900750007b0259189 Mon Sep 17 00:00:00 2001 +From: raji +Date: Tue, 14 Jun 2016 14:51:16 +0530 +Subject: [PATCH] powerpc: strcasecmp/strncasecmp optmization for power8 + +This implementation utilizes vectors to improve performance +compared to current byte by byte implementation for POWER7. +The performance improvement is upto 4x. This patch is tested +on powerpc64 and powerpc64le. + +(cherry picked from commit c8376f3e07602aaef9cb843bb73cb5f2b860634a) + +Conflicts: + sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S + sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +--- + ChangeLog | 22 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 4 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 6 + + .../powerpc64/multiarch/strcasecmp-power7.S | 20 +- + .../powerpc64/multiarch/strcasecmp-power8.S | 28 ++ + .../powerpc/powerpc64/multiarch/strcasecmp-ppc64.c | 21 + + sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c | 32 +- + .../powerpc/powerpc64/multiarch/strncase-power8.S | 28 ++ + .../powerpc/powerpc64/multiarch/strncase-ppc64.c | 21 + + sysdeps/powerpc/powerpc64/multiarch/strncase.c | 25 +- + sysdeps/powerpc/powerpc64/power8/strcasecmp.S | 446 +++++++++++++++++++++ + sysdeps/powerpc/powerpc64/power8/strncase.S | 20 + + 12 files changed, 622 insertions(+), 51 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/strcasecmp.S + create mode 100644 sysdeps/powerpc/powerpc64/power8/strncase.S + +diff --git a/ChangeLog b/ChangeLog +index c01d1a0..9385bd0 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 9ee9bc2..e3ac285 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -21,6 +21,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + stpcpy-power8 stpcpy-power7 stpcpy-ppc64 \ ++ strcasecmp-ppc64 strcasecmp-power8 \ ++ strncase-ppc64 strncase-power8 \ + strcasestr-power8 strcasestr-ppc64 \ + strcat-power8 strcat-power7 strcat-ppc64 \ + strcmp-power8 strcmp-power7 strcmp-ppc64 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 228891f..aabd7bc 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -204,6 +204,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c. */ + IFUNC_IMPL (i, name, strcasecmp, + IFUNC_IMPL_ADD (array, i, strcasecmp, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strcasecmp_power8) ++ IFUNC_IMPL_ADD (array, i, strcasecmp, + hwcap & PPC_FEATURE_HAS_VSX, + __strcasecmp_power7) + IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ppc)) +@@ -219,6 +222,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strncase.c. */ + IFUNC_IMPL (i, name, strncasecmp, + IFUNC_IMPL_ADD (array, i, strncasecmp, ++ hwcap2 & PPC_FEATURE2_ARCH_2_07, ++ __strncasecmp_power8) ++ IFUNC_IMPL_ADD (array, i, strncasecmp, + hwcap & PPC_FEATURE_HAS_VSX, + __strncasecmp_power7) + IFUNC_IMPL_ADD (array, i, strncasecmp, 1, __strncasecmp_ppc)) +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S +index 56eed9a..99cd7bd 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S +@@ -1,5 +1,5 @@ +-/* Optimized strcasecmp implementation foOWER7. +- Copyright (C) 2013-2014 Free Software Foundation, Inc. ++/* Optimized strcasecmp implementation for POWER7. ++ Copyright (C) 2013-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -18,21 +18,7 @@ + + #include + +-#undef ENTRY +-#define ENTRY(name) \ +- .section ".text"; \ +- ENTRY_2(__strcasecmp_power7) \ +- .align ALIGNARG(2); \ +- BODY_LABEL(__strcasecmp_power7): \ +- cfi_startproc; \ +- LOCALENTRY(__strcasecmp_power7) +- +-#undef END +-#define END(name) \ +- cfi_endproc; \ +- TRACEBACK(__strcasecmp_power7) \ +- END_2(__strcasecmp_power7) +- ++#define __strcasecmp __strcasecmp_power7 + #undef weak_alias + #define weak_alias(name, alias) + +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power8.S +new file mode 100644 +index 0000000..492047a +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power8.S +@@ -0,0 +1,28 @@ ++/* Optimized strcasecmp implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define __strcasecmp __strcasecmp_power8 ++#undef weak_alias ++#define weak_alias(name, alias) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-ppc64.c +new file mode 100644 +index 0000000..6318b4a +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-ppc64.c +@@ -0,0 +1,21 @@ ++/* Multiarch strcasecmp for PPC64. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define strcasecmp __strcasecmp_ppc ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +index 979e9f1..5ec6885 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +@@ -1,5 +1,5 @@ +-/* Multiple versions of strcasecmp. +- Copyright (C) 2013-2014 Free Software Foundation, Inc. ++/* Multiple versions of strcasecmp ++ Copyright (C) 2013-2016 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -16,25 +16,21 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) +-# include +-# define strcasecmp __strcasecmp_ppc +-extern __typeof (__strcasecmp) __strcasecmp_ppc attribute_hidden; +-extern __typeof (__strcasecmp) __strcasecmp_power7 attribute_hidden; +-#endif ++#include ++#include ++#include "init-arch.h" + +-#include +-#undef strcasecmp ++extern __typeof (__strcasecmp) __libc_strcasecmp; + +-#if IS_IN (libc) +-# include +-# include "init-arch.h" ++extern __typeof (__strcasecmp) __strcasecmp_ppc attribute_hidden; ++extern __typeof (__strcasecmp) __strcasecmp_power7 attribute_hidden; ++extern __typeof (__strcasecmp) __strcasecmp_power8 attribute_hidden; + +-extern __typeof (__strcasecmp) __libc_strcasecmp; + libc_ifunc (__libc_strcasecmp, +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __strcasecmp_power7 +- : __strcasecmp_ppc); ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strcasecmp_power8: ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcasecmp_power7 ++ : __strcasecmp_ppc); + + weak_alias (__libc_strcasecmp, strcasecmp) +-#endif +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase-power8.S b/sysdeps/powerpc/powerpc64/multiarch/strncase-power8.S +new file mode 100644 +index 0000000..01a63b5 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase-power8.S +@@ -0,0 +1,28 @@ ++/* Optimized strncasecmp implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define __strncasecmp __strncasecmp_power8 ++#undef weak_alias ++#define weak_alias(name, alias) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strncase-ppc64.c +new file mode 100644 +index 0000000..c245d77 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase-ppc64.c +@@ -0,0 +1,21 @@ ++/* Multiarch strncasecmp for PPC64. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define strncasecmp __strncasecmp_ppc ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncase.c b/sysdeps/powerpc/powerpc64/multiarch/strncase.c +index 4339f3a..5bfaf65 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncase.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncase.c +@@ -16,26 +16,21 @@ + License along with the GNU C Library; if not, see + . */ + +-#if IS_IN (libc) +-# include +-# define strncasecmp __strncasecmp_ppc +-extern __typeof (__strncasecmp) __strncasecmp_ppc attribute_hidden; +-extern __typeof (__strncasecmp) __strncasecmp_power7 attribute_hidden; +-#endif ++#include ++#include ++#include "init-arch.h" + +-#include +-#undef strncasecmp ++extern __typeof (__strncasecmp) __libc_strncasecmp; + +-#if IS_IN (libc) +-# include +-# include "init-arch.h" ++extern __typeof (__strncasecmp) __strncasecmp_ppc attribute_hidden; ++extern __typeof (__strncasecmp) __strncasecmp_power7 attribute_hidden; ++extern __typeof (__strncasecmp) __strncasecmp_power8 attribute_hidden; + +-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle +- ifunc symbol properly. */ +-extern __typeof (__strncasecmp) __libc_strncasecmp; + libc_ifunc (__libc_strncasecmp, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strncasecmp_power8: + (hwcap & PPC_FEATURE_HAS_VSX) + ? __strncasecmp_power7 + : __strncasecmp_ppc); ++ + weak_alias (__libc_strncasecmp, strncasecmp) +-#endif +diff --git a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S +new file mode 100644 +index 0000000..63f6217 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S +@@ -0,0 +1,446 @@ ++/* Optimized strcasecmp implementation for PowerPC64. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++/* int [r3] strcasecmp (const char *s1 [r3], const char *s2 [r4] ) */ ++ ++#ifndef USE_AS_STRNCASECMP ++# define __STRCASECMP __strcasecmp ++# define STRCASECMP strcasecmp ++#else ++# define __STRCASECMP __strncasecmp ++# define STRCASECMP strncasecmp ++#endif ++/* Convert 16 bytes to lowercase and compare */ ++#define TOLOWER() \ ++ vaddubm v8, v4, v1; \ ++ vaddubm v7, v4, v3; \ ++ vcmpgtub v8, v8, v2; \ ++ vsel v4, v7, v4, v8; \ ++ vaddubm v8, v5, v1; \ ++ vaddubm v7, v5, v3; \ ++ vcmpgtub v8, v8, v2; \ ++ vsel v5, v7, v5, v8; \ ++ vcmpequb. v7, v5, v4; ++ ++/* Get 16 bytes for unaligned case. */ ++#ifdef __LITTLE_ENDIAN__ ++#define GET16BYTES(reg1, reg2, reg3) \ ++ lvx reg1, 0, reg2; \ ++ vcmpequb. v8, v0, reg1; \ ++ beq cr6, 1f; \ ++ vspltisb v9, 0; \ ++ b 2f; \ ++ .align 4; \ ++1: \ ++ addi r6, reg2, 16; \ ++ lvx v9, 0, r6; \ ++2: \ ++ vperm reg1, v9, reg1, reg3; ++#else ++#define GET16BYTES(reg1, reg2, reg3) \ ++ lvx reg1, 0, reg2; \ ++ vcmpequb. v8, v0, reg1; \ ++ beq cr6, 1f; \ ++ vspltisb v9, 0; \ ++ b 2f; \ ++ .align 4; \ ++1: \ ++ addi r6, reg2, 16; \ ++ lvx v9, 0, r6; \ ++2: \ ++ vperm reg1, reg1, v9, reg3; ++#endif ++ ++/* Check null in v4, v5 and convert to lower. */ ++#define CHECKNULLANDCONVERT() \ ++ vcmpequb. v7, v0, v5; \ ++ beq cr6, 3f; \ ++ vcmpequb. v7, v0, v4; \ ++ beq cr6, 3f; \ ++ b L(null_found); \ ++ .align 4; \ ++3: \ ++ TOLOWER() ++ ++#ifdef _ARCH_PWR8 ++# define VCLZD_V8_v7 vclzd v8, v7; ++# define MFVRD_R3_V1 mfvrd r3, v1; ++# define VSUBUDM_V9_V8 vsubudm v9, v9, v8; ++# define VPOPCNTD_V8_V8 vpopcntd v8, v8; ++# define VADDUQM_V7_V8 vadduqm v9, v7, v8; ++#else ++# define VCLZD_V8_v7 .long 0x11003fc2 ++# define MFVRD_R3_V1 .long 0x7c230067 ++# define VSUBUDM_V9_V8 .long 0x112944c0 ++# define VPOPCNTD_V8_V8 .long 0x110047c3 ++# define VADDUQM_V7_V8 .long 0x11274100 ++#endif ++ ++ .machine power7 ++ ++ENTRY (__STRCASECMP) ++#ifdef USE_AS_STRNCASECMP ++ CALL_MCOUNT 3 ++#else ++ CALL_MCOUNT 2 ++#endif ++#define rRTN r3 /* Return value */ ++#define rSTR1 r10 /* 1st string */ ++#define rSTR2 r4 /* 2nd string */ ++#define rCHAR1 r6 /* Byte read from 1st string */ ++#define rCHAR2 r7 /* Byte read from 2nd string */ ++#define rADDR1 r8 /* Address of tolower(rCHAR1) */ ++#define rADDR2 r12 /* Address of tolower(rCHAR2) */ ++#define rLWR1 r8 /* Word tolower(rCHAR1) */ ++#define rLWR2 r12 /* Word tolower(rCHAR2) */ ++#define rTMP r9 ++#define rLOC r11 /* Default locale address */ ++ ++ cmpd cr7, rRTN, rSTR2 ++ ++ /* Get locale address. */ ++ ld rTMP, __libc_tsd_LOCALE@got@tprel(r2) ++ add rLOC, rTMP, __libc_tsd_LOCALE@tls ++ ld rLOC, 0(rLOC) ++ ++ mr rSTR1, rRTN ++ li rRTN, 0 ++ beqlr cr7 ++#ifdef USE_AS_STRNCASECMP ++ cmpdi cr7, r5, 0 ++ beq cr7, L(retnull) ++ cmpdi cr7, r5, 16 ++ blt cr7, L(bytebybyte) ++#endif ++ vspltisb v0, 0 ++ vspltisb v8, -1 ++ /* Check for null in initial characters. ++ Check max of 16 char depending on the alignment. ++ If null is present, proceed byte by byte. */ ++ lvx v4, 0, rSTR1 ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v10, 0, rSTR1 /* Compute mask. */ ++ vperm v9, v8, v4, v10 /* Mask bits that are not part of string. */ ++#else ++ lvsl v10, 0, rSTR1 ++ vperm v9, v4, v8, v10 ++#endif ++ vcmpequb. v9, v0, v9 /* Check for null bytes. */ ++ bne cr6, L(bytebybyte) ++ lvx v5, 0, rSTR2 ++ /* Calculate alignment. */ ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v6, 0, rSTR2 ++ vperm v9, v8, v5, v6 /* Mask bits that are not part of string. */ ++#else ++ lvsl v6, 0, rSTR2 ++ vperm v9, v5, v8, v6 ++#endif ++ vcmpequb. v9, v0, v9 /* Check for null bytes. */ ++ bne cr6, L(bytebybyte) ++ /* Check if locale has non ascii characters. */ ++ ld rTMP, 0(rLOC) ++ addi r6, rTMP,LOCALE_DATA_VALUES+_NL_CTYPE_NONASCII_CASE*SIZEOF_VALUES ++ lwz rTMP, 0(r6) ++ cmpdi cr7, rTMP, 1 ++ beq cr7, L(bytebybyte) ++ ++ /* Load vector registers with values used for TOLOWER. */ ++ /* Load v1 = 0xbf, v2 = 0x19 v3 = 0x20 in each byte. */ ++ vspltisb v3, 2 ++ vspltisb v9, 4 ++ vsl v3, v3, v9 ++ vaddubm v1, v3, v3 ++ vnor v1, v1, v1 ++ vspltisb v2, 7 ++ vsububm v2, v3, v2 ++ ++ andi. rADDR1, rSTR1, 0xF ++ beq cr0, L(align) ++ addi r6, rSTR1, 16 ++ lvx v9, 0, r6 ++ /* Compute 16 bytes from previous two loads. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm v4, v9, v4, v10 ++#else ++ vperm v4, v4, v9, v10 ++#endif ++L(align): ++ andi. rADDR2, rSTR2, 0xF ++ beq cr0, L(align1) ++ addi r6, rSTR2, 16 ++ lvx v9, 0, r6 ++ /* Compute 16 bytes from previous two loads. */ ++#ifdef __LITTLE_ENDIAN__ ++ vperm v5, v9, v5, v6 ++#else ++ vperm v5, v5, v9, v6 ++#endif ++L(align1): ++ CHECKNULLANDCONVERT() ++ blt cr6, L(match) ++ b L(different) ++ .align 4 ++L(match): ++ clrldi r6, rSTR1, 60 ++ subfic r7, r6, 16 ++#ifdef USE_AS_STRNCASECMP ++ sub r5, r5, r7 ++#endif ++ add rSTR1, rSTR1, r7 ++ add rSTR2, rSTR2, r7 ++ andi. rADDR2, rSTR2, 0xF ++ addi rSTR1, rSTR1, -16 ++ addi rSTR2, rSTR2, -16 ++ beq cr0, L(aligned) ++#ifdef __LITTLE_ENDIAN__ ++ lvsr v6, 0, rSTR2 ++#else ++ lvsl v6, 0, rSTR2 ++#endif ++ /* There are 2 loops depending on the input alignment. ++ Each loop gets 16 bytes from s1 and s2, check for null, ++ convert to lowercase and compare. Loop till difference ++ or null occurs. */ ++L(s1_align): ++ addi rSTR1, rSTR1, 16 ++ addi rSTR2, rSTR2, 16 ++#ifdef USE_AS_STRNCASECMP ++ cmpdi cr7, r5, 16 ++ blt cr7, L(bytebybyte) ++ addi r5, r5, -16 ++#endif ++ lvx v4, 0, rSTR1 ++ GET16BYTES(v5, rSTR2, v6) ++ CHECKNULLANDCONVERT() ++ blt cr6, L(s1_align) ++ b L(different) ++ .align 4 ++L(aligned): ++ addi rSTR1, rSTR1, 16 ++ addi rSTR2, rSTR2, 16 ++#ifdef USE_AS_STRNCASECMP ++ cmpdi cr7, r5, 16 ++ blt cr7, L(bytebybyte) ++ addi r5, r5, -16 ++#endif ++ lvx v4, 0, rSTR1 ++ lvx v5, 0, rSTR2 ++ CHECKNULLANDCONVERT() ++ blt cr6, L(aligned) ++ ++ /* Calculate and return the difference. */ ++L(different): ++ vaddubm v1, v3, v3 ++ vcmpequb v7, v0, v7 ++#ifdef __LITTLE_ENDIAN__ ++ /* Count trailing zero. */ ++ vspltisb v8, -1 ++ VADDUQM_V7_V8 ++ vandc v8, v9, v7 ++ VPOPCNTD_V8_V8 ++ vspltb v6, v8, 15 ++ vcmpequb. v6, v6, v1 ++ blt cr6, L(shift8) ++#else ++ /* Count leading zero. */ ++ VCLZD_V8_v7 ++ vspltb v6, v8, 7 ++ vcmpequb. v6, v6, v1 ++ blt cr6, L(shift8) ++ vsro v8, v8, v1 ++#endif ++ b L(skipsum) ++ .align 4 ++L(shift8): ++ vsumsws v8, v8, v0 ++L(skipsum): ++#ifdef __LITTLE_ENDIAN__ ++ /* Shift registers based on leading zero count. */ ++ vsro v6, v5, v8 ++ vsro v7, v4, v8 ++ /* Merge and move to GPR. */ ++ vmrglb v6, v6, v7 ++ vslo v1, v6, v1 ++ MFVRD_R3_V1 ++ /* Place the characters that are different in first position. */ ++ sldi rSTR2, rRTN, 56 ++ srdi rSTR2, rSTR2, 56 ++ sldi rSTR1, rRTN, 48 ++ srdi rSTR1, rSTR1, 56 ++#else ++ vslo v6, v5, v8 ++ vslo v7, v4, v8 ++ vmrghb v1, v6, v7 ++ MFVRD_R3_V1 ++ srdi rSTR2, rRTN, 48 ++ sldi rSTR2, rSTR2, 56 ++ srdi rSTR2, rSTR2, 56 ++ srdi rSTR1, rRTN, 56 ++#endif ++ subf rRTN, rSTR1, rSTR2 ++ extsw rRTN, rRTN ++ blr ++ ++ .align 4 ++ /* OK. We've hit the end of the string. We need to be careful that ++ we don't compare two strings as different because of junk beyond ++ the end of the strings... */ ++L(null_found): ++ vaddubm v10, v3, v3 ++#ifdef __LITTLE_ENDIAN__ ++ /* Count trailing zero. */ ++ vspltisb v8, -1 ++ VADDUQM_V7_V8 ++ vandc v8, v9, v7 ++ VPOPCNTD_V8_V8 ++ vspltb v6, v8, 15 ++ vcmpequb. v6, v6, v10 ++ blt cr6, L(shift_8) ++#else ++ /* Count leading zero. */ ++ VCLZD_V8_v7 ++ vspltb v6, v8, 7 ++ vcmpequb. v6, v6, v10 ++ blt cr6, L(shift_8) ++ vsro v8, v8, v10 ++#endif ++ b L(skipsum1) ++ .align 4 ++L(shift_8): ++ vsumsws v8, v8, v0 ++L(skipsum1): ++ /* Calculate shift count based on count of zero. */ ++ vspltisb v10, 7 ++ vslb v10, v10, v10 ++ vsldoi v9, v0, v10, 1 ++ VSUBUDM_V9_V8 ++ vspltisb v8, 8 ++ vsldoi v8, v0, v8, 1 ++ VSUBUDM_V9_V8 ++ /* Shift and remove junk after null character. */ ++#ifdef __LITTLE_ENDIAN__ ++ vslo v5, v5, v9 ++ vslo v4, v4, v9 ++#else ++ vsro v5, v5, v9 ++ vsro v4, v4, v9 ++#endif ++ /* Convert and compare 16 bytes. */ ++ TOLOWER() ++ blt cr6, L(retnull) ++ b L(different) ++ .align 4 ++L(retnull): ++ li rRTN, 0 ++ blr ++ .align 4 ++L(bytebybyte): ++ /* Unrolling loop for POWER: loads are done with 'lbz' plus ++ offset and string descriptors are only updated in the end ++ of loop unrolling. */ ++ ld rLOC, LOCALE_CTYPE_TOLOWER(rLOC) ++ lbz rCHAR1, 0(rSTR1) /* Load char from s1 */ ++ lbz rCHAR2, 0(rSTR2) /* Load char from s2 */ ++#ifdef USE_AS_STRNCASECMP ++ rldicl rTMP, r5, 62, 2 ++ cmpdi cr7, rTMP, 0 ++ beq cr7, L(lessthan4) ++ mtctr rTMP ++#endif ++L(loop): ++ cmpdi rCHAR1, 0 /* *s1 == '\0' ? */ ++ sldi rADDR1, rCHAR1, 2 /* Calculate address for tolower(*s1) */ ++ sldi rADDR2, rCHAR2, 2 /* Calculate address for tolower(*s2) */ ++ lwzx rLWR1, rLOC, rADDR1 /* Load tolower(*s1) */ ++ lwzx rLWR2, rLOC, rADDR2 /* Load tolower(*s2) */ ++ cmpw cr1, rLWR1, rLWR2 /* r = tolower(*s1) == tolower(*s2) ? */ ++ crorc 4*cr1+eq,eq,4*cr1+eq /* (*s1 != '\0') || (r == 1) */ ++ beq cr1, L(done) ++ lbz rCHAR1, 1(rSTR1) ++ lbz rCHAR2, 1(rSTR2) ++ cmpdi rCHAR1, 0 ++ sldi rADDR1, rCHAR1, 2 ++ sldi rADDR2, rCHAR2, 2 ++ lwzx rLWR1, rLOC, rADDR1 ++ lwzx rLWR2, rLOC, rADDR2 ++ cmpw cr1, rLWR1, rLWR2 ++ crorc 4*cr1+eq,eq,4*cr1+eq ++ beq cr1, L(done) ++ lbz rCHAR1, 2(rSTR1) ++ lbz rCHAR2, 2(rSTR2) ++ cmpdi rCHAR1, 0 ++ sldi rADDR1, rCHAR1, 2 ++ sldi rADDR2, rCHAR2, 2 ++ lwzx rLWR1, rLOC, rADDR1 ++ lwzx rLWR2, rLOC, rADDR2 ++ cmpw cr1, rLWR1, rLWR2 ++ crorc 4*cr1+eq,eq,4*cr1+eq ++ beq cr1, L(done) ++ lbz rCHAR1, 3(rSTR1) ++ lbz rCHAR2, 3(rSTR2) ++ cmpdi rCHAR1, 0 ++ /* Increment both string descriptors */ ++ addi rSTR1, rSTR1, 4 ++ addi rSTR2, rSTR2, 4 ++ sldi rADDR1, rCHAR1, 2 ++ sldi rADDR2, rCHAR2, 2 ++ lwzx rLWR1, rLOC, rADDR1 ++ lwzx rLWR2, rLOC, rADDR2 ++ cmpw cr1, rLWR1, rLWR2 ++ crorc 4*cr1+eq,eq,4*cr1+eq ++ beq cr1, L(done) ++ lbz rCHAR1, 0(rSTR1) /* Load char from s1 */ ++ lbz rCHAR2, 0(rSTR2) /* Load char from s2 */ ++#ifdef USE_AS_STRNCASECMP ++ bdnz L(loop) ++#else ++ b L(loop) ++#endif ++#ifdef USE_AS_STRNCASECMP ++L(lessthan4): ++ clrldi r5, r5, 62 ++ cmpdi cr7, r5, 0 ++ beq cr7, L(retnull) ++ mtctr r5 ++L(loop1): ++ cmpdi rCHAR1, 0 ++ sldi rADDR1, rCHAR1, 2 ++ sldi rADDR2, rCHAR2, 2 ++ lwzx rLWR1, rLOC, rADDR1 ++ lwzx rLWR2, rLOC, rADDR2 ++ cmpw cr1, rLWR1, rLWR2 ++ crorc 4*cr1+eq,eq,4*cr1+eq ++ beq cr1, L(done) ++ addi rSTR1, rSTR1, 1 ++ addi rSTR2, rSTR2, 1 ++ lbz rCHAR1, 0(rSTR1) ++ lbz rCHAR2, 0(rSTR2) ++ bdnz L(loop1) ++#endif ++L(done): ++ subf r0, rLWR2, rLWR1 ++ extsw rRTN, r0 ++ blr ++END (__STRCASECMP) ++ ++weak_alias (__STRCASECMP, STRCASECMP) ++libc_hidden_builtin_def (__STRCASECMP) +diff --git a/sysdeps/powerpc/powerpc64/power8/strncase.S b/sysdeps/powerpc/powerpc64/power8/strncase.S +new file mode 100644 +index 0000000..7ce2ed0 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/strncase.S +@@ -0,0 +1,20 @@ ++/* Optimized strncasecmp implementation for POWER8. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define USE_AS_STRNCASECMP 1 ++#include +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-19.patch b/SOURCES/glibc-rh1385004-19.patch new file mode 100644 index 00000000..22cd2713 --- /dev/null +++ b/SOURCES/glibc-rh1385004-19.patch @@ -0,0 +1,58 @@ +From 2fd1041a8d9684978546886d58fdf8add8c8d9f7 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Tue, 5 Jul 2016 21:20:41 +0530 +Subject: [PATCH] powerpc: Fix return code of strcasecmp for unaligned inputs + +If the input values are unaligned and if there are null characters in the +memory before the starting address of the input values, strcasecmp +gives incorrect return code. Fixed it by adding mask the bits that +are not part of the string. + +(cherry picked from commit 30e4cc5413f72c2c728a544389da0c48500d9904) +--- + ChangeLog | 6 ++++++ + sysdeps/powerpc/powerpc64/power8/strcasecmp.S | 17 ++++++++++++++--- + 2 files changed, 20 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 9385bd0..af5f694 100644 +diff --git a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S +index 63f6217..c83dc52 100644 +--- a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S ++++ b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S +@@ -40,11 +40,20 @@ + vsel v5, v7, v5, v8; \ + vcmpequb. v7, v5, v4; + +-/* Get 16 bytes for unaligned case. */ ++/* ++ * Get 16 bytes for unaligned case. ++ * reg1: Vector to hold next 16 bytes. ++ * reg2: Address to read from. ++ * reg3: Permute control vector. ++ * v8: Tmp vector used to mask unwanted bytes. ++ * v9: Tmp vector,0 when null is found on first 16 bytes ++ */ + #ifdef __LITTLE_ENDIAN__ + #define GET16BYTES(reg1, reg2, reg3) \ + lvx reg1, 0, reg2; \ +- vcmpequb. v8, v0, reg1; \ ++ vspltisb v8, -1; \ ++ vperm v8, v8, reg1, reg3; \ ++ vcmpequb. v8, v0, v8; \ + beq cr6, 1f; \ + vspltisb v9, 0; \ + b 2f; \ +@@ -57,7 +66,9 @@ + #else + #define GET16BYTES(reg1, reg2, reg3) \ + lvx reg1, 0, reg2; \ +- vcmpequb. v8, v0, reg1; \ ++ vspltisb v8, -1; \ ++ vperm v8, reg1, v8, reg3; \ ++ vcmpequb. v8, v0, v8; \ + beq cr6, 1f; \ + vspltisb v9, 0; \ + b 2f; \ +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-2.patch b/SOURCES/glibc-rh1385004-2.patch new file mode 100644 index 00000000..a885c08d --- /dev/null +++ b/SOURCES/glibc-rh1385004-2.patch @@ -0,0 +1,72 @@ +From c86e89a09d187da3aca1ee7ff9bfee4957fe70ff Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Tue, 28 Jul 2015 15:34:25 -0300 +Subject: [PATCH] powerpc: Fix strstr/power7 build + +This patch fixes the strstr build with --disable-multi-arch option. +The optimization calls the __strstr_ppc symbol, which always build +for multiarch config but not if it is disable. This patch fixes it +by adding the default C implementation object with the expected +symbol name. + + * sysdeps/powerpc/powerpc64/power7/Makefile [$(subdir) = string] + (sysdep_routines): Add strstr-ppc64. + * sysdeps/powerpc/powerpc64/power7/strstr-ppc64.c: New file. + +(cherry picked from commit 357bb400f1b25e48e265fd55b5996328d2a8c142) +--- + ChangeLog | 6 ++++++ + sysdeps/powerpc/powerpc64/power7/Makefile | 1 + + sysdeps/powerpc/powerpc64/power7/strstr-ppc64.c | 27 +++++++++++++++++++++++++ + 3 files changed, 34 insertions(+) + create mode 100644 sysdeps/powerpc/powerpc64/power7/strstr-ppc64.c + +diff --git a/ChangeLog b/ChangeLog +index 8e98192..d70df5c 100644 +diff --git a/sysdeps/powerpc/powerpc64/power7/Makefile b/sysdeps/powerpc/powerpc64/power7/Makefile +index 40aacfa..89a2296 100644 +--- a/sysdeps/powerpc/powerpc64/power7/Makefile ++++ b/sysdeps/powerpc/powerpc64/power7/Makefile +@@ -5,6 +5,7 @@ CFLAGS-rtld.c += -mno-vsx + endif + + ifeq ($(subdir),string) ++sysdep_routines += strstr-ppc64 + CFLAGS-strncase.c += -funroll-loops + CFLAGS-strncase_l.c += -funroll-loops + endif +diff --git a/sysdeps/powerpc/powerpc64/power7/strstr-ppc64.c b/sysdeps/powerpc/powerpc64/power7/strstr-ppc64.c +new file mode 100644 +index 0000000..bbab92d +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power7/strstr-ppc64.c +@@ -0,0 +1,27 @@ ++/* Optimized strstr implementation for PowerPC64/POWER7. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRSTR __strstr_ppc ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(__name) ++ ++extern __typeof (strstr) __strstr_ppc attribute_hidden; ++ ++#include +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-20.patch b/SOURCES/glibc-rh1385004-20.patch new file mode 100644 index 00000000..6895a1c5 --- /dev/null +++ b/SOURCES/glibc-rh1385004-20.patch @@ -0,0 +1,452 @@ +From fdd895c45c52241f786cf4e29ccc45c240b1acb5 Mon Sep 17 00:00:00 2001 +From: Tulio Magno Quites Machado Filho +Date: Mon, 27 Jun 2016 16:03:10 -0300 +Subject: [PATCH] powerpc: Add a POWER8-optimized version of expf() + +This implementation is based on the one already used at +sysdeps/x86_64/fpu/e_expf.S. + +This implementation improves the performance by ~14% on average in synthetic +benchmarks at the cost of decreasing accuracy to 1 ULP. + +(cherry picked from commit 35da2541c382d1d4b7c9a15049a3cd1c7a6863a3) +--- + ChangeLog | 11 + + sysdeps/powerpc/fpu/libm-test-ulps | 2 + + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/e_expf-power8.S | 26 ++ + .../powerpc/powerpc64/fpu/multiarch/e_expf-ppc64.c | 24 ++ + sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf.c | 31 +++ + sysdeps/powerpc/powerpc64/power8/fpu/e_expf.S | 303 +++++++++++++++++++++ + 7 files changed, 399 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/e_expf.S + +diff --git a/ChangeLog b/ChangeLog +index af5f694..6cb2578 100644 +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 0e3eac7..331763e 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -24,7 +24,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \ + e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \ + s_isnan-power8 s_isinf-power8 s_finite-power8 \ +- s_llrint-power8 s_llround-power8 ++ s_llrint-power8 s_llround-power8 \ ++ e_expf-power8 e_expf-ppc64 + + CFLAGS-s_logbf-power7.c = -mcpu=power7 + CFLAGS-s_logbl-power7.c = -mcpu=power7 +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-power8.S +new file mode 100644 +index 0000000..02eff24 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-power8.S +@@ -0,0 +1,26 @@ ++/* __ieee754_expf() POWER8 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __ieee754_expf __ieee754_expf_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-ppc64.c +new file mode 100644 +index 0000000..40f9e3a +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf-ppc64.c +@@ -0,0 +1,24 @@ ++/* __ieee_expf() PowerPC64 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __ieee754_expf __ieee754_expf_ppc64 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf.c +new file mode 100644 +index 0000000..1d9a8c6 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_expf.c +@@ -0,0 +1,31 @@ ++/* Multiple versions of ieee754_expf. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__ieee754_expf) __ieee754_expf_ppc64 attribute_hidden; ++extern __typeof (__ieee754_expf) __ieee754_expf_power8 attribute_hidden; ++ ++libc_ifunc (__ieee754_expf, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __ieee754_expf_power8 ++ : __ieee754_expf_ppc64); ++ ++strong_alias (__ieee754_expf, __expf_finite) +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/e_expf.S b/sysdeps/powerpc/powerpc64/power8/fpu/e_expf.S +new file mode 100644 +index 0000000..a5e68bb +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/e_expf.S +@@ -0,0 +1,303 @@ ++/* Optimized expf(). PowerPC64/POWER8 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Short algorithm description: ++ * ++ * Let K = 64 (table size). ++ * e^x = 2^(x/log(2)) = 2^n * T[j] * (1 + P(y)) ++ * where: ++ * x = m*log(2)/K + y, y in [0.0..log(2)/K] ++ * m = n*K + j, m,n,j - signed integer, j in [0..K-1] ++ * values of 2^(j/K) are tabulated as T[j]. ++ * ++ * P(y) is a minimax polynomial approximation of expf(y)-1 ++ * on small interval [0.0..log(2)/K]. ++ * ++ * P(y) = P3*y*y*y*y + P2*y*y*y + P1*y*y + P0*y, calculated as ++ * z = y*y; P(y) = (P3*z + P1)*z + (P2*z + P0)*y ++ * ++ * Special cases: ++ * expf(NaN) = NaN ++ * expf(+INF) = +INF ++ * expf(-INF) = 0 ++ * expf(x) = 1 for subnormals ++ * for finite argument, only expf(0)=1 is exact ++ * expf(x) overflows if x>88.7228317260742190 ++ * expf(x) underflows if x<-103.972076416015620 ++ */ ++ ++#define C1 0x42ad496b /* Single precision 125*log(2). */ ++#define C2 0x31800000 /* Single precision 2^(-28). */ ++#define SP_INF 0x7f800000 /* Single precision Inf. */ ++#define SP_EXP_BIAS 0x1fc0 /* Single precision exponent bias. */ ++ ++#define DATA_OFFSET r9 ++ ++/* Implements the function ++ ++ float [fp1] expf (float [fp1] x) */ ++ ++ .machine power8 ++EALIGN(__ieee754_expf, 4, 0) ++ addis DATA_OFFSET,r2,.Lanchor@toc@ha ++ addi DATA_OFFSET,DATA_OFFSET,.Lanchor@toc@l ++ ++ xscvdpspn v0,v1 ++ mfvsrd r8,v0 /* r8 = x */ ++ lfd fp2,(.KLN2-.Lanchor)(DATA_OFFSET) ++ lfd fp3,(.P2-.Lanchor)(DATA_OFFSET) ++ rldicl r3,r8,32,33 /* r3 = |x| */ ++ lis r4,C1@ha /* r4 = 125*log(2) */ ++ ori r4,r4,C1@l ++ cmpw r3,r4 ++ lfd fp5,(.P3-.Lanchor)(DATA_OFFSET) ++ lfd fp4,(.RS-.Lanchor)(DATA_OFFSET) ++ fmadd fp2,fp1,fp2,fp4 /* fp2 = x * K/log(2) + (2^23 + 2^22) */ ++ bge L(special_paths) /* |x| >= 125*log(2) ? */ ++ ++ lis r4,C2@ha ++ ori r4,r4,C2@l ++ cmpw r3,r4 ++ blt L(small_args) /* |x| < 2^(-28) ? */ ++ ++ /* Main path: here if 2^(-28) <= |x| < 125*log(2) */ ++ frsp fp6,fp2 ++ xscvdpsp v2,v2 ++ mfvsrd r8,v2 ++ mr r3,r8 /* r3 = m */ ++ rldicl r8,r8,32,58 /* r8 = j */ ++ lfs fp4,(.SP_RS-.Lanchor)(DATA_OFFSET) ++ fsubs fp2,fp6,fp4 /* fp2 = m = x * K/log(2) */ ++ srdi r3,r3,32 ++ clrrwi r3,r3,6 /* r3 = n */ ++ lfd fp6,(.NLN2K-.Lanchor)(DATA_OFFSET) ++ fmadd fp0,fp2,fp6,fp1 /* fp0 = y = x - m*log(2)/K */ ++ fmul fp2,fp0,fp0 /* fp2 = z = y^2 */ ++ lfd fp4,(.P1-.Lanchor)(DATA_OFFSET) ++ lfd fp6,(.P0-.Lanchor)(DATA_OFFSET) ++ lis r4,SP_EXP_BIAS@ha ++ ori r4,r4,SP_EXP_BIAS@l ++ add r3,r3,r4 ++ rldic r3,r3,49,1 /* r3 = 2^n */ ++ fmadd fp4,fp5,fp2,fp4 /* fp4 = P3 * z + P1 */ ++ fmadd fp6,fp3,fp2,fp6 /* fp6 = P2 * z + P0 */ ++ mtvsrd v1,r3 ++ xscvspdp v1,v1 ++ fmul fp4,fp4,fp2 /* fp4 = (P3 * z + P1)*z */ ++ fmadd fp0,fp0,fp6,fp4 /* fp0 = P(y) */ ++ sldi r8,r8,3 /* Access doublewords from T[j]. */ ++ addi r6,DATA_OFFSET,(.Ttable-.Lanchor) ++ lfdx fp3,r6,r8 ++ fmadd fp0,fp0,fp3,fp3 /* fp0 = T[j] * (1 + P(y)) */ ++ fmul fp1,fp1,fp0 /* fp1 = 2^n * T[j] * (1 + P(y)) */ ++ frsp fp1,fp1 ++ blr ++ ++ .align 4 ++/* x is either underflow, overflow, infinite or NaN. */ ++L(special_paths): ++ srdi r8,r8,32 ++ rlwinm r8,r8,3,29,29 /* r8 = 0, if x positive. ++ r8 = 4, otherwise. */ ++ addi r6,DATA_OFFSET,(.SPRANGE-.Lanchor) ++ lwzx r4,r6,r8 /* r4 = .SPRANGE[signbit(x)] */ ++ cmpw r3,r4 ++ /* |x| <= .SPRANGE[signbit(x)] */ ++ ble L(near_under_or_overflow) ++ ++ lis r4,SP_INF@ha ++ ori r4,r4,SP_INF@l ++ cmpw r3,r4 ++ bge L(arg_inf_or_nan) /* |x| > Infinite ? */ ++ ++ addi r6,DATA_OFFSET,(.SPLARGE_SMALL-.Lanchor) ++ lfsx fp1,r6,r8 ++ fmuls fp1,fp1,fp1 ++ blr ++ ++ ++ .align 4 ++L(small_args): ++ /* expf(x) = 1.0, where |x| < |2^(-28)| */ ++ lfs fp2,(.SPone-.Lanchor)(DATA_OFFSET) ++ fadds fp1,fp1,fp2 ++ blr ++ ++ ++ .align 4 ++L(arg_inf_or_nan:) ++ bne L(arg_nan) ++ ++ /* expf(+INF) = +INF ++ expf(-INF) = 0 */ ++ addi r6,DATA_OFFSET,(.INF_ZERO-.Lanchor) ++ lfsx fp1,r6,r8 ++ blr ++ ++ ++ .align 4 ++L(arg_nan): ++ /* expf(NaN) = NaN */ ++ fadd fp1,fp1,fp1 ++ frsp fp1,fp1 ++ blr ++ ++ .align 4 ++L(near_under_or_overflow): ++ frsp fp6,fp2 ++ xscvdpsp v2,v2 ++ mfvsrd r8,v2 ++ mr r3,r8 /* r3 = m */ ++ rldicl r8,r8,32,58 /* r8 = j */ ++ lfs fp4,(.SP_RS-.Lanchor)(DATA_OFFSET) ++ fsubs fp2,fp6,fp4 /* fp2 = m = x * K/log(2) */ ++ srdi r3,r3,32 ++ clrrwi r3,r3,6 /* r3 = n */ ++ lfd fp6,(.NLN2K-.Lanchor)(DATA_OFFSET) ++ fmadd fp0,fp2,fp6,fp1 /* fp0 = y = x - m*log(2)/K */ ++ fmul fp2,fp0,fp0 /* fp2 = z = y^2 */ ++ lfd fp4,(.P1-.Lanchor)(DATA_OFFSET) ++ lfd fp6,(.P0-.Lanchor)(DATA_OFFSET) ++ ld r4,(.DP_EXP_BIAS-.Lanchor)(DATA_OFFSET) ++ add r3,r3,r4 ++ rldic r3,r3,46,1 /* r3 = 2 */ ++ fmadd fp4,fp5,fp2,fp4 /* fp4 = P3 * z + P1 */ ++ fmadd fp6,fp3,fp2,fp6 /* fp6 = P2 * z + P0 */ ++ mtvsrd v1,r3 ++ fmul fp4,fp4,fp2 /* fp4 = (P3*z + P1)*z */ ++ fmadd fp0,fp0,fp6,fp4 /* fp0 = P(y) */ ++ sldi r8,r8,3 /* Access doublewords from T[j]. */ ++ addi r6,DATA_OFFSET,(.Ttable-.Lanchor) ++ lfdx fp3,r6,r8 ++ fmadd fp0,fp0,fp3,fp3 /* fp0 = T[j] * (1 + T[j]) */ ++ fmul fp1,fp1,fp0 /* fp1 = 2^n * T[j] * (1 + T[j]) */ ++ frsp fp1,fp1 ++ blr ++END(__ieee754_expf) ++ ++ .section .rodata, "a",@progbits ++.Lanchor: ++ .balign 8 ++/* Table T[j] = 2^(j/K). Double precision. */ ++.Ttable: ++ .8byte 0x3ff0000000000000 ++ .8byte 0x3ff02c9a3e778061 ++ .8byte 0x3ff059b0d3158574 ++ .8byte 0x3ff0874518759bc8 ++ .8byte 0x3ff0b5586cf9890f ++ .8byte 0x3ff0e3ec32d3d1a2 ++ .8byte 0x3ff11301d0125b51 ++ .8byte 0x3ff1429aaea92de0 ++ .8byte 0x3ff172b83c7d517b ++ .8byte 0x3ff1a35beb6fcb75 ++ .8byte 0x3ff1d4873168b9aa ++ .8byte 0x3ff2063b88628cd6 ++ .8byte 0x3ff2387a6e756238 ++ .8byte 0x3ff26b4565e27cdd ++ .8byte 0x3ff29e9df51fdee1 ++ .8byte 0x3ff2d285a6e4030b ++ .8byte 0x3ff306fe0a31b715 ++ .8byte 0x3ff33c08b26416ff ++ .8byte 0x3ff371a7373aa9cb ++ .8byte 0x3ff3a7db34e59ff7 ++ .8byte 0x3ff3dea64c123422 ++ .8byte 0x3ff4160a21f72e2a ++ .8byte 0x3ff44e086061892d ++ .8byte 0x3ff486a2b5c13cd0 ++ .8byte 0x3ff4bfdad5362a27 ++ .8byte 0x3ff4f9b2769d2ca7 ++ .8byte 0x3ff5342b569d4f82 ++ .8byte 0x3ff56f4736b527da ++ .8byte 0x3ff5ab07dd485429 ++ .8byte 0x3ff5e76f15ad2148 ++ .8byte 0x3ff6247eb03a5585 ++ .8byte 0x3ff6623882552225 ++ .8byte 0x3ff6a09e667f3bcd ++ .8byte 0x3ff6dfb23c651a2f ++ .8byte 0x3ff71f75e8ec5f74 ++ .8byte 0x3ff75feb564267c9 ++ .8byte 0x3ff7a11473eb0187 ++ .8byte 0x3ff7e2f336cf4e62 ++ .8byte 0x3ff82589994cce13 ++ .8byte 0x3ff868d99b4492ed ++ .8byte 0x3ff8ace5422aa0db ++ .8byte 0x3ff8f1ae99157736 ++ .8byte 0x3ff93737b0cdc5e5 ++ .8byte 0x3ff97d829fde4e50 ++ .8byte 0x3ff9c49182a3f090 ++ .8byte 0x3ffa0c667b5de565 ++ .8byte 0x3ffa5503b23e255d ++ .8byte 0x3ffa9e6b5579fdbf ++ .8byte 0x3ffae89f995ad3ad ++ .8byte 0x3ffb33a2b84f15fb ++ .8byte 0x3ffb7f76f2fb5e47 ++ .8byte 0x3ffbcc1e904bc1d2 ++ .8byte 0x3ffc199bdd85529c ++ .8byte 0x3ffc67f12e57d14b ++ .8byte 0x3ffcb720dcef9069 ++ .8byte 0x3ffd072d4a07897c ++ .8byte 0x3ffd5818dcfba487 ++ .8byte 0x3ffda9e603db3285 ++ .8byte 0x3ffdfc97337b9b5f ++ .8byte 0x3ffe502ee78b3ff6 ++ .8byte 0x3ffea4afa2a490da ++ .8byte 0x3ffefa1bee615a27 ++ .8byte 0x3fff50765b6e4540 ++ .8byte 0x3fffa7c1819e90d8 ++ ++.KLN2: ++ .8byte 0x40571547652b82fe /* Double precision K/log(2). */ ++ ++/* Double precision polynomial coefficients. */ ++.P0: ++ .8byte 0x3fefffffffffe7c6 ++.P1: ++ .8byte 0x3fe00000008d6118 ++.P2: ++ .8byte 0x3fc55550da752d4f ++.P3: ++ .8byte 0x3fa56420eb78fa85 ++ ++.RS: ++ .8byte 0x4168000000000000 /* Double precision 2^23 + 2^22. */ ++.NLN2K: ++ .8byte 0xbf862e42fefa39ef /* Double precision -log(2)/K. */ ++.DP_EXP_BIAS: ++ .8byte 0x000000000000ffc0 /* Double precision exponent bias. */ ++ ++ .balign 4 ++.SPone: ++ .4byte 0x3f800000 /* Single precision 1.0. */ ++.SP_RS: ++ .4byte 0x4b400000 /* Single precision 2^23 + 2^22. */ ++ ++.SPRANGE: /* Single precision overflow/underflow bounds. */ ++ .4byte 0x42b17217 /* if x>this bound, then result overflows. */ ++ .4byte 0x42cff1b4 /* if x +Date: Tue, 28 Jun 2016 21:59:40 +1000 +Subject: [PATCH] powerpc: Add a POWER8-optimized version of sinf() + +This uses the implementation of sinf() in sysdeps/x86_64/fpu/s_sinf.S +as inspiration. + +(cherry picked from commit aa95fc13f5b02044eadc3af3d9e1c025f2e1edda) +--- + ChangeLog | 10 + + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/s_sinf-power8.S | 26 ++ + .../powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c | 26 ++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c | 31 ++ + sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S | 519 +++++++++++++++++++++ + 6 files changed, 614 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c + create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S + +diff --git a/ChangeLog b/ChangeLog +index 6cb2578..6d6aab3 100644 +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 331763e..add1fb8 100644 +--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -25,7 +25,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \ + s_isnan-power8 s_isinf-power8 s_finite-power8 \ + s_llrint-power8 s_llround-power8 \ +- e_expf-power8 e_expf-ppc64 ++ e_expf-power8 e_expf-ppc64 \ ++ s_sinf-ppc64 s_sinf-power8 + + CFLAGS-s_logbf-power7.c = -mcpu=power7 + CFLAGS-s_logbl-power7.c = -mcpu=power7 +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S +new file mode 100644 +index 0000000..579019c +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-power8.S +@@ -0,0 +1,26 @@ ++/* sinf(). PowerPC64/POWER8 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#define __sinf __sinf_power8 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c +new file mode 100644 +index 0000000..eaf83fa +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf-ppc64.c +@@ -0,0 +1,26 @@ ++/* sinf(). PowerPC64 default version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#define __sinf __sinf_ppc64 ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c +new file mode 100644 +index 0000000..4269d58 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_sinf.c +@@ -0,0 +1,31 @@ ++/* Multiple versions of sinf. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__sinf) __sinf_ppc64 attribute_hidden; ++extern __typeof (__sinf) __sinf_power8 attribute_hidden; ++ ++libc_ifunc (__sinf, ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __sinf_power8 ++ : __sinf_ppc64); ++ ++weak_alias (__sinf, sinf) +diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S +new file mode 100644 +index 0000000..3b8f5af +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S +@@ -0,0 +1,519 @@ ++/* Optimized sinf(). PowerPC64/POWER8 version. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#define _ERRNO_H 1 ++#include ++ ++#define FRAMESIZE (FRAME_MIN_SIZE+16) ++ ++#define FLOAT_EXPONENT_SHIFT 23 ++#define FLOAT_EXPONENT_BIAS 127 ++#define INTEGER_BITS 3 ++ ++#define PI_4 0x3f490fdb /* PI/4 */ ++#define NINEPI_4 0x40e231d6 /* 9 * PI/4 */ ++#define TWO_PN5 0x3d000000 /* 2^-5 */ ++#define TWO_PN27 0x32000000 /* 2^-27 */ ++#define INFINITY 0x7f800000 ++#define TWO_P23 0x4b000000 /* 2^27 */ ++#define FX_FRACTION_1_28 0x9249250 /* 0x100000000 / 28 + 1 */ ++ ++ /* Implements the function ++ ++ float [fp1] sinf (float [fp1] x) */ ++ ++ .machine power8 ++EALIGN(__sinf, 4, 0) ++ addis r9,r2,L(anchor)@toc@ha ++ addi r9,r9,L(anchor)@toc@l ++ ++ lis r4,PI_4@h ++ ori r4,r4,PI_4@l ++ ++ xscvdpspn v0,v1 ++ mfvsrd r8,v0 ++ rldicl r3,r8,32,33 /* Remove sign bit. */ ++ ++ cmpw r3,r4 ++ bge L(greater_or_equal_pio4) ++ ++ lis r4,TWO_PN5@h ++ ori r4,r4,TWO_PN5@l ++ ++ cmpw r3,r4 ++ blt L(less_2pn5) ++ ++ /* Chebyshev polynomial of the form: ++ * x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))). */ ++ ++ lfd fp9,(L(S0)-L(anchor))(r9) ++ lfd fp10,(L(S1)-L(anchor))(r9) ++ lfd fp11,(L(S2)-L(anchor))(r9) ++ lfd fp12,(L(S3)-L(anchor))(r9) ++ lfd fp13,(L(S4)-L(anchor))(r9) ++ ++ fmul fp2,fp1,fp1 /* x^2 */ ++ fmul fp3,fp2,fp1 /* x^3 */ ++ ++ fmadd fp4,fp2,fp13,fp12 /* S3+x^2*S4 */ ++ fmadd fp4,fp2,fp4,fp11 /* S2+x^2*(S3+x^2*S4) */ ++ fmadd fp4,fp2,fp4,fp10 /* S1+x^2*(S2+x^2*(S3+x^2*S4)) */ ++ fmadd fp4,fp2,fp4,fp9 /* S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4))) */ ++ fmadd fp1,fp3,fp4,fp1 /* x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))) */ ++ frsp fp1,fp1 /* Round to single precision. */ ++ ++ blr ++ ++ .balign 16 ++L(greater_or_equal_pio4): ++ lis r4,NINEPI_4@h ++ ori r4,r4,NINEPI_4@l ++ cmpw r3,r4 ++ bge L(greater_or_equal_9pio4) ++ ++ /* Calculate quotient of |x|/(PI/4). */ ++ lfd fp2,(L(invpio4)-L(anchor))(r9) ++ fabs fp1,fp1 /* |x| */ ++ fmul fp2,fp1,fp2 /* |x|/(PI/4) */ ++ fctiduz fp2,fp2 ++ mfvsrd r3,v2 /* n = |x| mod PI/4 */ ++ ++ /* Now use that quotient to find |x| mod (PI/2). */ ++ addi r7,r3,1 ++ rldicr r5,r7,2,60 /* ((n+1) >> 1) << 3 */ ++ addi r6,r9,(L(pio2_table)-L(anchor)) ++ lfdx fp4,r5,r6 ++ fsub fp1,fp1,fp4 ++ ++ .balign 16 ++L(reduced): ++ /* Now we are in the range -PI/4 to PI/4. */ ++ ++ /* Work out if we are in a positive or negative primary interval. */ ++ rldicl r4,r7,62,63 /* ((n+1) >> 2) & 1 */ ++ ++ /* We are operating on |x|, so we need to add back the original ++ sign. */ ++ rldicl r8,r8,33,63 /* (x >> 31) & 1, ie the sign bit. */ ++ xor r4,r4,r8 /* 0 if result should be positive, ++ 1 if negative. */ ++ ++ /* Load a 1.0 or -1.0. */ ++ addi r5,r9,(L(ones)-L(anchor)) ++ sldi r4,r4,3 ++ lfdx fp0,r4,r5 ++ ++ /* Are we in the primary interval of sin or cos? */ ++ andi. r4,r7,0x2 ++ bne L(cos) ++ ++ /* Chebyshev polynomial of the form: ++ x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))). */ ++ ++ lfd fp9,(L(S0)-L(anchor))(r9) ++ lfd fp10,(L(S1)-L(anchor))(r9) ++ lfd fp11,(L(S2)-L(anchor))(r9) ++ lfd fp12,(L(S3)-L(anchor))(r9) ++ lfd fp13,(L(S4)-L(anchor))(r9) ++ ++ fmul fp2,fp1,fp1 /* x^2 */ ++ fmul fp3,fp2,fp1 /* x^3 */ ++ ++ fmadd fp4,fp2,fp13,fp12 /* S3+x^2*S4 */ ++ fmadd fp4,fp2,fp4,fp11 /* S2+x^2*(S3+x^2*S4) */ ++ fmadd fp4,fp2,fp4,fp10 /* S1+x^2*(S2+x^2*(S3+x^2*S4)) */ ++ fmadd fp4,fp2,fp4,fp9 /* S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4))) */ ++ fmadd fp4,fp3,fp4,fp1 /* x+x^3*(S0+x^2*(S1+x^2*(S2+x^2*(S3+x^2*S4)))) */ ++ fmul fp4,fp4,fp0 /* Add in the sign. */ ++ frsp fp1,fp4 /* Round to single precision. */ ++ ++ blr ++ ++ .balign 16 ++L(cos): ++ /* Chebyshev polynomial of the form: ++ 1.0+x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))). */ ++ ++ lfd fp9,(L(C0)-L(anchor))(r9) ++ lfd fp10,(L(C1)-L(anchor))(r9) ++ lfd fp11,(L(C2)-L(anchor))(r9) ++ lfd fp12,(L(C3)-L(anchor))(r9) ++ lfd fp13,(L(C4)-L(anchor))(r9) ++ ++ fmul fp2,fp1,fp1 /* x^2 */ ++ lfd fp3,(L(DPone)-L(anchor))(r9) ++ ++ fmadd fp4,fp2,fp13,fp12 /* C3+x^2*C4 */ ++ fmadd fp4,fp2,fp4,fp11 /* C2+x^2*(C3+x^2*C4) */ ++ fmadd fp4,fp2,fp4,fp10 /* C1+x^2*(C2+x^2*(C3+x^2*C4)) */ ++ fmadd fp4,fp2,fp4,fp9 /* C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4))) */ ++ fmadd fp4,fp2,fp4,fp3 /* 1.0 + x^2*(C0+x^2*(C1+x^2*(C2+x^2*(C3+x^2*C4)))) */ ++ fmul fp4,fp4,fp0 /* Add in the sign. */ ++ frsp fp1,fp4 /* Round to single precision. */ ++ ++ blr ++ ++ .balign 16 ++L(greater_or_equal_9pio4): ++ lis r4,INFINITY@h ++ ori r4,r4,INFINITY@l ++ cmpw r3,r4 ++ bge L(inf_or_nan) ++ ++ lis r4,TWO_P23@h ++ ori r4,r4,TWO_P23@l ++ cmpw r3,r4 ++ bge L(greater_or_equal_2p23) ++ ++ fabs fp1,fp1 /* |x| */ ++ ++ /* Calculate quotient of |x|/(PI/4). */ ++ lfd fp2,(L(invpio4)-L(anchor))(r9) ++ ++ lfd fp3,(L(DPone)-L(anchor))(r9) ++ lfd fp4,(L(DPhalf)-L(anchor))(r9) ++ fmul fp2,fp1,fp2 /* |x|/(PI/4) */ ++ friz fp2,fp2 /* n = floor(|x|/(PI/4)) */ ++ ++ /* Calculate (n + 1) / 2. */ ++ fadd fp2,fp2,fp3 /* n + 1 */ ++ fmul fp3,fp2,fp4 /* (n + 1) / 2 */ ++ friz fp3,fp3 ++ ++ lfd fp4,(L(pio2hi)-L(anchor))(r9) ++ lfd fp5,(L(pio2lo)-L(anchor))(r9) ++ ++ fmul fp6,fp4,fp3 ++ fadd fp6,fp6,fp1 ++ fmadd fp1,fp5,fp3,fp6 ++ ++ fctiduz fp2,fp2 ++ mfvsrd r7,v2 /* n + 1 */ ++ ++ b L(reduced) ++ ++ .balign 16 ++L(inf_or_nan): ++ bne L(skip_errno_setting) /* Is a NAN? */ ++ ++ /* We delayed the creation of the stack frame, as well as the saving of ++ the link register, because only at this point, we are sure that ++ doing so is actually needed. */ ++ ++ stfd fp1,-8(r1) ++ ++ /* Save the link register. */ ++ mflr r0 ++ std r0,16(r1) ++ cfi_offset(lr, 16) ++ ++ /* Create the stack frame. */ ++ stdu r1,-FRAMESIZE(r1) ++ cfi_adjust_cfa_offset(FRAMESIZE) ++ ++ bl JUMPTARGET(__errno_location) ++ nop ++ ++ /* Restore the stack frame. */ ++ addi r1,r1,FRAMESIZE ++ cfi_adjust_cfa_offset(-FRAMESIZE) ++ /* Restore the link register. */ ++ ld r0,16(r1) ++ mtlr r0 ++ ++ lfd fp1,-8(r1) ++ ++ /* errno = EDOM */ ++ li r4,EDOM ++ stw r4,0(r3) ++ ++L(skip_errno_setting): ++ fsub fp1,fp1,fp1 /* x - x */ ++ blr ++ ++ .balign 16 ++L(greater_or_equal_2p23): ++ fabs fp1,fp1 ++ ++ srwi r4,r3,FLOAT_EXPONENT_SHIFT ++ subi r4,r4,FLOAT_EXPONENT_BIAS ++ ++ /* We reduce the input modulo pi/4, so we need 3 bits of integer ++ to determine where in 2*pi we are. Index into our array ++ accordingly. */ ++ addi r4,r4,INTEGER_BITS ++ ++ /* To avoid an expensive divide, for the range we care about (0 - 127) ++ we can transform x/28 into: ++ ++ x/28 = (x * ((0x100000000 / 28) + 1)) >> 32 ++ ++ mulhwu returns the top 32 bits of the 64 bit result, doing the ++ shift for us in the same instruction. The top 32 bits are undefined, ++ so we have to mask them. */ ++ ++ lis r6,FX_FRACTION_1_28@h ++ ori r6,r6,FX_FRACTION_1_28@l ++ mulhwu r5,r4,r6 ++ clrldi r5,r5,32 ++ ++ /* Get our pointer into the invpio4_table array. */ ++ sldi r4,r5,3 ++ addi r6,r9,(L(invpio4_table)-L(anchor)) ++ add r4,r4,r6 ++ ++ lfd fp2,0(r4) ++ lfd fp3,8(r4) ++ lfd fp4,16(r4) ++ lfd fp5,24(r4) ++ ++ fmul fp6,fp2,fp1 ++ fmul fp7,fp3,fp1 ++ fmul fp8,fp4,fp1 ++ fmul fp9,fp5,fp1 ++ ++ /* Mask off larger integer bits in highest double word that we don't ++ care about to avoid losing precision when combining with smaller ++ values. */ ++ fctiduz fp10,fp6 ++ mfvsrd r7,v10 ++ rldicr r7,r7,0,(63-INTEGER_BITS) ++ mtvsrd v10,r7 ++ fcfidu fp10,fp10 /* Integer bits. */ ++ ++ fsub fp6,fp6,fp10 /* highest -= integer bits */ ++ ++ /* Work out the integer component, rounded down. Use the top two ++ limbs for this. */ ++ fadd fp10,fp6,fp7 /* highest + higher */ ++ ++ fctiduz fp10,fp10 ++ mfvsrd r7,v10 ++ andi. r0,r7,1 ++ fcfidu fp10,fp10 ++ ++ /* Subtract integer component from highest limb. */ ++ fsub fp12,fp6,fp10 ++ ++ beq L(even_integer) ++ ++ /* Our integer component is odd, so we are in the -PI/4 to 0 primary ++ region. We need to shift our result down by PI/4, and to do this ++ in the mod (4/PI) space we simply subtract 1. */ ++ lfd fp11,(L(DPone)-L(anchor))(r9) ++ fsub fp12,fp12,fp11 ++ ++ /* Now add up all the limbs in order. */ ++ fadd fp12,fp12,fp7 ++ fadd fp12,fp12,fp8 ++ fadd fp12,fp12,fp9 ++ ++ /* And finally multiply by pi/4. */ ++ lfd fp13,(L(pio4)-L(anchor))(r9) ++ fmul fp1,fp12,fp13 ++ ++ addi r7,r7,1 ++ b L(reduced) ++ ++L(even_integer): ++ lfd fp11,(L(DPone)-L(anchor))(r9) ++ ++ /* Now add up all the limbs in order. */ ++ fadd fp12,fp12,fp7 ++ fadd fp12,r12,fp8 ++ fadd fp12,r12,fp9 ++ ++ /* We need to check if the addition of all the limbs resulted in us ++ overflowing 1.0. */ ++ fcmpu 0,fp12,fp11 ++ bgt L(greater_than_one) ++ ++ /* And finally multiply by pi/4. */ ++ lfd fp13,(L(pio4)-L(anchor))(r9) ++ fmul fp1,fp12,fp13 ++ ++ addi r7,r7,1 ++ b L(reduced) ++ ++L(greater_than_one): ++ /* We did overflow 1.0 when adding up all the limbs. Add 1.0 to our ++ integer, and subtract 1.0 from our result. Since that makes the ++ integer component odd, we need to subtract another 1.0 as ++ explained above. */ ++ addi r7,r7,1 ++ ++ lfd fp11,(L(DPtwo)-L(anchor))(r9) ++ fsub fp12,fp12,fp11 ++ ++ /* And finally multiply by pi/4. */ ++ lfd fp13,(L(pio4)-L(anchor))(r9) ++ fmul fp1,fp12,fp13 ++ ++ addi r7,r7,1 ++ b L(reduced) ++ ++ .balign 16 ++L(less_2pn5): ++ lis r4,TWO_PN27@h ++ ori r4,r4,TWO_PN27@l ++ ++ cmpw r3,r4 ++ blt L(less_2pn27) ++ ++ /* A simpler Chebyshev approximation is close enough for this range: ++ x+x^3*(SS0+x^2*SS1). */ ++ ++ lfd fp10,(L(SS0)-L(anchor))(r9) ++ lfd fp11,(L(SS1)-L(anchor))(r9) ++ ++ fmul fp2,fp1,fp1 /* x^2 */ ++ fmul fp3,fp2,fp1 /* x^3 */ ++ ++ fmadd fp4,fp2,fp11,fp10 /* SS0+x^2*SS1 */ ++ fmadd fp1,fp3,fp4,fp1 /* x+x^3*(SS0+x^2*SS1) */ ++ ++ frsp fp1,fp1 /* Round to single precision. */ ++ ++ blr ++ ++ .balign 16 ++L(less_2pn27): ++ cmpwi r3,0 ++ beq L(zero) ++ ++ /* Handle some special cases: ++ ++ sinf(subnormal) raises inexact/underflow ++ sinf(min_normalized) raises inexact/underflow ++ sinf(normalized) raises inexact. */ ++ ++ lfd fp2,(L(small)-L(anchor))(r9) ++ ++ fmul fp2,fp1,fp2 /* x * small */ ++ fsub fp1,fp1,fp2 /* x - x * small */ ++ ++ frsp fp1,fp1 ++ ++ blr ++ ++ .balign 16 ++L(zero): ++ blr ++ ++END (__sinf) ++ ++ .section .rodata, "a" ++ ++ .balign 8 ++ ++L(anchor): ++ ++ /* Chebyshev constants for sin, range -PI/4 - PI/4. */ ++L(S0): .8byte 0xbfc5555555551cd9 ++L(S1): .8byte 0x3f81111110c2688b ++L(S2): .8byte 0xbf2a019f8b4bd1f9 ++L(S3): .8byte 0x3ec71d7264e6b5b4 ++L(S4): .8byte 0xbe5a947e1674b58a ++ ++ /* Chebyshev constants for sin, range 2^-27 - 2^-5. */ ++L(SS0): .8byte 0xbfc555555543d49d ++L(SS1): .8byte 0x3f8110f475cec8c5 ++ ++ /* Chebyshev constants for cos, range -PI/4 - PI/4. */ ++L(C0): .8byte 0xbfdffffffffe98ae ++L(C1): .8byte 0x3fa55555545c50c7 ++L(C2): .8byte 0xbf56c16b348b6874 ++L(C3): .8byte 0x3efa00eb9ac43cc0 ++L(C4): .8byte 0xbe923c97dd8844d7 ++ ++L(invpio2): ++ .8byte 0x3fe45f306dc9c883 /* 2/PI */ ++ ++L(invpio4): ++ .8byte 0x3ff45f306dc9c883 /* 4/PI */ ++ ++L(invpio4_table): ++ .8byte 0x0000000000000000 ++ .8byte 0x3ff45f306c000000 ++ .8byte 0x3e3c9c882a000000 ++ .8byte 0x3c54fe13a8000000 ++ .8byte 0x3aaf47d4d0000000 ++ .8byte 0x38fbb81b6c000000 ++ .8byte 0x3714acc9e0000000 ++ .8byte 0x3560e4107c000000 ++ .8byte 0x33bca2c756000000 ++ .8byte 0x31fbd778ac000000 ++ .8byte 0x300b7246e0000000 ++ .8byte 0x2e5d2126e8000000 ++ .8byte 0x2c97003248000000 ++ .8byte 0x2ad77504e8000000 ++ .8byte 0x290921cfe0000000 ++ .8byte 0x274deb1cb0000000 ++ .8byte 0x25829a73e0000000 ++ .8byte 0x23fd1046be000000 ++ .8byte 0x2224baed10000000 ++ .8byte 0x20709d338e000000 ++ .8byte 0x1e535a2f80000000 ++ .8byte 0x1cef904e64000000 ++ .8byte 0x1b0d639830000000 ++ .8byte 0x1964ce7d24000000 ++ .8byte 0x17b908bf16000000 ++ ++L(pio4): ++ .8byte 0x3fe921fb54442d18 /* PI/4 */ ++ ++/* PI/2 as a sum of two doubles. We only use 32 bits of the upper limb ++ to avoid losing significant bits when multiplying with up to ++ (2^22)/(pi/2). */ ++L(pio2hi): ++ .8byte 0xbff921fb54400000 ++ ++L(pio2lo): ++ .8byte 0xbdd0b4611a626332 ++ ++L(pio2_table): ++ .8byte 0 ++ .8byte 0x3ff921fb54442d18 /* 1 * PI/2 */ ++ .8byte 0x400921fb54442d18 /* 2 * PI/2 */ ++ .8byte 0x4012d97c7f3321d2 /* 3 * PI/2 */ ++ .8byte 0x401921fb54442d18 /* 4 * PI/2 */ ++ .8byte 0x401f6a7a2955385e /* 5 * PI/2 */ ++ .8byte 0x4022d97c7f3321d2 /* 6 * PI/2 */ ++ .8byte 0x4025fdbbe9bba775 /* 7 * PI/2 */ ++ .8byte 0x402921fb54442d18 /* 8 * PI/2 */ ++ .8byte 0x402c463abeccb2bb /* 9 * PI/2 */ ++ .8byte 0x402f6a7a2955385e /* 10 * PI/2 */ ++ ++L(small): ++ .8byte 0x3cd0000000000000 /* 2^-50 */ ++ ++L(ones): ++ .8byte 0x3ff0000000000000 /* +1.0 */ ++ .8byte 0xbff0000000000000 /* -1.0 */ ++ ++L(DPhalf): ++ .8byte 0x3fe0000000000000 /* 0.5 */ ++ ++L(DPone): ++ .8byte 0x3ff0000000000000 /* 1.0 */ ++ ++L(DPtwo): ++ .8byte 0x4000000000000000 /* 2.0 */ ++ ++weak_alias(__sinf, sinf) +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-22.patch b/SOURCES/glibc-rh1385004-22.patch new file mode 100644 index 00000000..b285e4b4 --- /dev/null +++ b/SOURCES/glibc-rh1385004-22.patch @@ -0,0 +1,410 @@ +From 1e5a0d609f20a613e1e989802bbe479f61bed1ca Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Thu, 1 Dec 2016 11:35:43 +0530 +Subject: [PATCH] powerpc: strcmp optimization for power9 + +Vectorized loops are used for strings > 32B when compared +to power8 optimization. + +Tested on power9 ppc64le simulator. + +(cherry picked from commit 80ab6401a9bb566de940cc6a5fb7a6af650f17b9) + +Conflicts: + sysdeps/powerpc/powerpc64/multiarch/strcmp.c +--- + ChangeLog | 11 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 3 + + .../powerpc/powerpc64/multiarch/strcmp-power9.S | 40 +++ + sysdeps/powerpc/powerpc64/multiarch/strcmp.c | 13 +- + sysdeps/powerpc/powerpc64/power9/strcmp.S | 278 +++++++++++++++++++++ + 6 files changed, 341 insertions(+), 6 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcmp-power9.S + create mode 100644 sysdeps/powerpc/powerpc64/power9/strcmp.S + +diff --git a/ChangeLog b/ChangeLog +index 6d6aab3..57152b8 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index e3ac285..2c83c22 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -16,7 +16,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncase-ppc64 strncase-power8 \ + strcasestr-power8 strcasestr-ppc64 \ + strcat-power8 strcat-power7 strcat-ppc64 \ +- strcmp-power8 strcmp-power7 strcmp-ppc64 \ ++ strcmp-power9 strcmp-power8 strcmp-power7 strcmp-ppc64 \ + strcpy-power8 strcpy-power7 strcpy-ppc64 \ + strcspn-power8 strcspn-ppc64 \ + stpncpy-power8 stpncpy-power7 stpncpy-ppc64 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index aabd7bc..404a226 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -311,6 +311,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + /* Support sysdeps/powerpc/powerpc64/multiarch/strcmp.c. */ + IFUNC_IMPL (i, name, strcmp, + IFUNC_IMPL_ADD (array, i, strcmp, ++ hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ __strcmp_power9) ++ IFUNC_IMPL_ADD (array, i, strcmp, + hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strcmp_power8) + IFUNC_IMPL_ADD (array, i, strcmp, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-power9.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power9.S +new file mode 100644 +index 0000000..0a09e5b +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power9.S +@@ -0,0 +1,40 @@ ++/* Optimized strcmp implementation for POWER9/PPC64. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__strcmp_power9) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strcmp_power9): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strcmp_power9) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcmp_power9) \ ++ END_2(__strcmp_power9) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +index b45ba1f..7345f5a 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c +@@ -24,11 +24,14 @@ + extern __typeof (strcmp) __strcmp_ppc attribute_hidden; + extern __typeof (strcmp) __strcmp_power7 attribute_hidden; + extern __typeof (strcmp) __strcmp_power8 attribute_hidden; ++extern __typeof (strcmp) __strcmp_power9 attribute_hidden; + + libc_ifunc (strcmp, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) +- ? __strcmp_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __strcmp_power7 +- : __strcmp_ppc); ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ ? __strcmp_power9 : ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strcmp_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcmp_power7 ++ : __strcmp_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/power9/strcmp.S b/sysdeps/powerpc/powerpc64/power9/strcmp.S +new file mode 100644 +index 0000000..754d508 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power9/strcmp.S +@@ -0,0 +1,278 @@ ++/* Optimized strcmp implementation for PowerPC64/POWER9. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#ifdef __LITTLE_ENDIAN__ ++#include ++ ++/* Implements the function ++ ++ int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) ++ ++ The implementation uses unaligned doubleword access for first 32 bytes ++ as in POWER8 patch and uses vectorised loops after that. */ ++ ++/* TODO: Change this to actual instructions when minimum binutils is upgraded ++ to 2.27. Macros are defined below for these newer instructions in order ++ to maintain compatibility. */ ++# define VCTZLSBB(r,v) .long (0x10010602 | ((r)<<(32-11)) | ((v)<<(32-21))) ++ ++# define VEXTUBRX(t,a,b) .long (0x1000070d \ ++ | ((t)<<(32-11)) \ ++ | ((a)<<(32-16)) \ ++ | ((b)<<(32-21)) ) ++ ++# define VCMPNEZB(t,a,b) .long (0x10000507 \ ++ | ((t)<<(32-11)) \ ++ | ((a)<<(32-16)) \ ++ | ((b)<<(32-21)) ) ++ ++/* Get 16 bytes for unaligned case. ++ reg1: Vector to hold next 16 bytes. ++ reg2: Address to read from. ++ reg3: Permute control vector. */ ++# define GET16BYTES(reg1, reg2, reg3) \ ++ lvx reg1, 0, reg2; \ ++ vperm v8, v2, reg1, reg3; \ ++ vcmpequb. v8, v0, v8; \ ++ beq cr6, 1f; \ ++ vspltisb v9, 0; \ ++ b 2f; \ ++ .align 4; \ ++1: \ ++ addi r6, reg2, 16; \ ++ lvx v9, 0, r6; \ ++2: \ ++ vperm reg1, v9, reg1, reg3; ++ ++/* TODO: change this to .machine power9 when the minimum required binutils ++ allows it. */ ++ ++ .machine power7 ++EALIGN (strcmp, 4, 0) ++ li r0, 0 ++ ++ /* Check if [s1]+32 or [s2]+32 will cross a 4K page boundary using ++ the code: ++ ++ (((size_t) s1) % PAGE_SIZE > (PAGE_SIZE - ITER_SIZE)) ++ ++ with PAGE_SIZE being 4096 and ITER_SIZE begin 32. */ ++ ++ rldicl r7, r3, 0, 52 ++ rldicl r9, r4, 0, 52 ++ cmpldi cr7, r7, 4096-32 ++ bgt cr7, L(pagecross_check) ++ cmpldi cr5, r9, 4096-32 ++ bgt cr5, L(pagecross_check) ++ ++ /* For short strings up to 32 bytes, load both s1 and s2 using ++ unaligned dwords and compare. */ ++ ld r8, 0(r3) ++ ld r10, 0(r4) ++ cmpb r12, r8, r0 ++ cmpb r11, r8, r10 ++ orc. r9, r12, r11 ++ bne cr0, L(different_nocmpb) ++ ++ ld r8, 8(r3) ++ ld r10, 8(r4) ++ cmpb r12, r8, r0 ++ cmpb r11, r8, r10 ++ orc. r9, r12, r11 ++ bne cr0, L(different_nocmpb) ++ ++ ld r8, 16(r3) ++ ld r10, 16(r4) ++ cmpb r12, r8, r0 ++ cmpb r11, r8, r10 ++ orc. r9, r12, r11 ++ bne cr0, L(different_nocmpb) ++ ++ ld r8, 24(r3) ++ ld r10, 24(r4) ++ cmpb r12, r8, r0 ++ cmpb r11, r8, r10 ++ orc. r9, r12, r11 ++ bne cr0, L(different_nocmpb) ++ ++ addi r7, r3, 32 ++ addi r4, r4, 32 ++ ++L(align): ++ /* Now it has checked for first 32 bytes. */ ++ vspltisb v0, 0 ++ vspltisb v2, -1 ++ lvsr v6, 0, r4 /* Compute mask. */ ++ or r5, r4, r7 ++ andi. r5, r5, 0xF ++ beq cr0, L(aligned) ++ andi. r5, r7, 0xF ++ beq cr0, L(s1_align) ++ lvsr v10, 0, r7 /* Compute mask. */ ++ ++ /* Both s1 and s2 are unaligned. */ ++ GET16BYTES(v4, r7, v10) ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ beq cr6, L(match) ++ b L(different) ++ ++ /* Align s1 to qw and adjust s2 address. */ ++ .align 4 ++L(match): ++ clrldi r6, r7, 60 ++ subfic r5, r6, 16 ++ add r7, r7, r5 ++ add r4, r4, r5 ++ andi. r5, r4, 0xF ++ beq cr0, L(aligned) ++ lvsr v6, 0, r4 ++ /* There are 2 loops depending on the input alignment. ++ Each loop gets 16 bytes from s1 and s2 and compares. ++ Loop until a mismatch or null occurs. */ ++L(s1_align): ++ lvx v4, r7, r0 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ bne cr6, L(different) ++ ++ lvx v4, r7, r0 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ bne cr6, L(different) ++ ++ lvx v4, r7, r0 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ bne cr6, L(different) ++ ++ lvx v4, r7, r0 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ beq cr6, L(s1_align) ++ b L(different) ++ ++ .align 4 ++L(aligned): ++ lvx v4, 0, r7 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ bne cr6, L(different) ++ ++ lvx v4, 0, r7 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ bne cr6, L(different) ++ ++ lvx v4, 0, r7 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ bne cr6, L(different) ++ ++ lvx v4, 0, r7 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ addi r7, r7, 16 ++ addi r4, r4, 16 ++ beq cr6, L(aligned) ++ ++ /* Calculate and return the difference. */ ++L(different): ++ VCTZLSBB(r6, v7) ++ VEXTUBRX(r5, r6, v4) ++ VEXTUBRX(r4, r6, v5) ++ subf r3, r4, r5 ++ extsw r3, r3 ++ blr ++ ++ .align 4 ++L(different_nocmpb): ++ neg r3, r9 ++ and r9, r9, r3 ++ cntlzd r9, r9 ++ subfic r9, r9, 63 ++ srd r3, r8, r9 ++ srd r10, r10, r9 ++ rldicl r10, r10, 0, 56 ++ rldicl r3, r3, 0, 56 ++ subf r3, r10, r3 ++ extsw r3, r3 ++ blr ++ ++ .align 4 ++L(pagecross_check): ++ subfic r9, r9, 4096 ++ subfic r7, r7, 4096 ++ cmpld cr7, r7, r9 ++ bge cr7, L(pagecross) ++ mr r7, r9 ++ ++ /* If unaligned 16 bytes reads across a 4K page boundary, it uses ++ a simple byte a byte comparison until the page alignment for s1 ++ is reached. */ ++L(pagecross): ++ add r7, r3, r7 ++ subf r9, r3, r7 ++ mtctr r9 ++ ++ .align 4 ++L(pagecross_loop): ++ /* Loads a byte from s1 and s2, compare if *s1 is equal to *s2 ++ and if *s1 is '\0'. */ ++ lbz r9, 0(r3) ++ lbz r10, 0(r4) ++ addi r3, r3, 1 ++ addi r4, r4, 1 ++ cmplw cr7, r9, r10 ++ cmpdi cr5, r9, r0 ++ bne cr7, L(pagecross_ne) ++ beq cr5, L(pagecross_nullfound) ++ bdnz L(pagecross_loop) ++ b L(align) ++ ++ .align 4 ++L(pagecross_ne): ++ extsw r3, r9 ++ mr r9, r10 ++L(pagecross_retdiff): ++ subf r9, r9, r3 ++ extsw r3, r9 ++ blr ++ ++ .align 4 ++L(pagecross_nullfound): ++ li r3, 0 ++ b L(pagecross_retdiff) ++END (strcmp) ++libc_hidden_builtin_def (strcmp) ++#else ++#include ++#endif +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-23.patch b/SOURCES/glibc-rh1385004-23.patch new file mode 100644 index 00000000..55178c49 --- /dev/null +++ b/SOURCES/glibc-rh1385004-23.patch @@ -0,0 +1,513 @@ +From fabf4e24731762be7ed1fded89b536fe7150fe13 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Tue, 13 Dec 2016 10:53:42 +0530 +Subject: [PATCH] powerpc: strncmp optimization for power9 + +Vectorized loops are used for strings > 32B when compared +to power8 optimization. + +Tested on power9 ppc64le simulator. + +(cherry picked from commit d89060d60307c84995177a6fba2ed80c96f6b914) + +Conflicts: + sysdeps/powerpc/powerpc64/multiarch/strncmp.c +--- + ChangeLog | 11 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 2 + + .../powerpc/powerpc64/multiarch/strncmp-power9.S | 40 +++ + sysdeps/powerpc/powerpc64/multiarch/strncmp.c | 17 +- + sysdeps/powerpc/powerpc64/power9/strncmp.S | 375 +++++++++++++++++++++ + 6 files changed, 440 insertions(+), 8 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-power9.S + create mode 100644 sysdeps/powerpc/powerpc64/power9/strncmp.S + +diff --git a/ChangeLog b/ChangeLog +index 57152b8..0446268 100644 +diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 2c83c22..2997b9d 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -8,7 +8,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 \ +- strncmp-power8 strncmp-power7 strncmp-power4 strncmp-ppc64 \ ++ strncmp-power9 strncmp-power8 strncmp-power7 \ ++ strncmp-power4 strncmp-ppc64 \ + strchr-power7 strchr-ppc64 \ + strchrnul-power7 strchrnul-ppc64 wcschr-power7 \ + wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \ +diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 404a226..a140583 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -110,6 +110,8 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + + /* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */ + IFUNC_IMPL (i, name, strncmp, ++ IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_3_00, ++ __strncmp_power9) + IFUNC_IMPL_ADD (array, i, strncmp, hwcap2 & PPC_FEATURE2_ARCH_2_07, + __strncmp_power8) + IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_HAS_VSX, +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp-power9.S b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power9.S +new file mode 100644 +index 0000000..2f8d0c4 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp-power9.S +@@ -0,0 +1,40 @@ ++/* Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name,alignt,words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncmp_power9) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncmp_power9): \ ++ cfi_startproc; \ ++ LOCALENTRY(__strncmp_power9) ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncmp_power9) \ ++ END_2(__strncmp_power9) ++ ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +index 9b6a659..3859cbc 100644 +--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c ++++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +@@ -26,15 +26,18 @@ extern __typeof (strncmp) __strncmp_ppc attribute_hidden; + extern __typeof (strncmp) __strncmp_power4 attribute_hidden; + extern __typeof (strncmp) __strncmp_power7 attribute_hidden; + extern __typeof (strncmp) __strncmp_power8 attribute_hidden; ++extern __typeof (strncmp) __strncmp_power9 attribute_hidden; + + /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ + libc_ifunc (strncmp, +- (hwcap2 & PPC_FEATURE2_ARCH_2_07) +- ? __strncmp_power8 : +- (hwcap & PPC_FEATURE_HAS_VSX) +- ? __strncmp_power7 : +- (hwcap & PPC_FEATURE_POWER4) +- ? __strncmp_power4 +- : __strncmp_ppc); ++ (hwcap2 & PPC_FEATURE2_ARCH_3_00) ++ ? __strncmp_power9 : ++ (hwcap2 & PPC_FEATURE2_ARCH_2_07) ++ ? __strncmp_power8 : ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strncmp_power7 : ++ (hwcap & PPC_FEATURE_POWER4) ++ ? __strncmp_power4 ++ : __strncmp_ppc); + #endif +diff --git a/sysdeps/powerpc/powerpc64/power9/strncmp.S b/sysdeps/powerpc/powerpc64/power9/strncmp.S +new file mode 100644 +index 0000000..3f2fa75 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power9/strncmp.S +@@ -0,0 +1,375 @@ ++/* Optimized strncmp implementation for PowerPC64/POWER9. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#ifdef __LITTLE_ENDIAN__ ++#include ++ ++/* Implements the function ++ ++ int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t [r5] n) ++ ++ The implementation uses unaligned doubleword access to avoid specialized ++ code paths depending of data alignment for first 32 bytes and uses ++ vectorised loops after that. */ ++ ++/* TODO: Change this to actual instructions when minimum binutils is upgraded ++ to 2.27. Macros are defined below for these newer instructions in order ++ to maintain compatibility. */ ++# define VCTZLSBB(r,v) .long (0x10010602 | ((r)<<(32-11)) | ((v)<<(32-21))) ++ ++# define VEXTUBRX(t,a,b) .long (0x1000070d \ ++ | ((t)<<(32-11)) \ ++ | ((a)<<(32-16)) \ ++ | ((b)<<(32-21)) ) ++ ++# define VCMPNEZB(t,a,b) .long (0x10000507 \ ++ | ((t)<<(32-11)) \ ++ | ((a)<<(32-16)) \ ++ | ((b)<<(32-21)) ) ++ ++/* Get 16 bytes for unaligned case. ++ reg1: Vector to hold next 16 bytes. ++ reg2: Address to read from. ++ reg3: Permute control vector. */ ++# define GET16BYTES(reg1, reg2, reg3) \ ++ lvx reg1, 0, reg2; \ ++ vperm v8, v2, reg1, reg3; \ ++ vcmpequb. v8, v0, v8; \ ++ beq cr6, 1f; \ ++ vspltisb v9, 0; \ ++ b 2f; \ ++ .align 4; \ ++1: \ ++ cmplw cr6, r5, r11; \ ++ ble cr6, 2f; \ ++ addi r6, reg2, 16; \ ++ lvx v9, 0, r6; \ ++2: \ ++ vperm reg1, v9, reg1, reg3; ++ ++/* TODO: change this to .machine power9 when minimum binutils ++ is upgraded to 2.27. */ ++ .machine power7 ++EALIGN (strncmp, 4, 0) ++ /* Check if size is 0. */ ++ cmpdi cr0, r5, 0 ++ beq cr0, L(ret0) ++ li r0, 0 ++ ++ /* Check if [s1]+32 or [s2]+32 will cross a 4K page boundary using ++ the code: ++ ++ (((size_t) s1) % PAGE_SIZE > (PAGE_SIZE - ITER_SIZE)) ++ ++ with PAGE_SIZE being 4096 and ITER_SIZE begin 32. */ ++ rldicl r8, r3, 0, 52 ++ cmpldi cr7, r8, 4096-32 ++ bgt cr7, L(pagecross) ++ rldicl r9, r4, 0, 52 ++ cmpldi cr7, r9, 4096-32 ++ bgt cr7, L(pagecross) ++ ++ /* For short strings up to 32 bytes, load both s1 and s2 using ++ unaligned dwords and compare. */ ++ ++ ld r7, 0(r3) ++ ld r9, 0(r4) ++ li r8, 0 ++ cmpb r8, r7, r8 ++ cmpb r6, r7, r9 ++ orc. r8, r8, r6 ++ bne cr0, L(different1) ++ ++ /* If the strings compared are equal, but size is less or equal ++ to 8, return 0. */ ++ cmpldi cr7, r5, 8 ++ li r9, 0 ++ ble cr7, L(ret1) ++ addi r5, r5, -8 ++ ++ ld r7, 8(r3) ++ ld r9, 8(r4) ++ cmpb r8, r7, r8 ++ cmpb r6, r7, r9 ++ orc. r8, r8, r6 ++ bne cr0, L(different1) ++ cmpldi cr7, r5, 8 ++ mr r9, r8 ++ ble cr7, L(ret1) ++ /* Update pointers and size. */ ++ addi r5, r5, -8 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ ld r7, 0(r3) ++ ld r9, 0(r4) ++ li r8, 0 ++ cmpb r8, r7, r8 ++ cmpb r6, r7, r9 ++ orc. r8, r8, r6 ++ bne cr0, L(different1) ++ cmpldi cr7, r5, 8 ++ li r9, 0 ++ ble cr7, L(ret1) ++ addi r5, r5, -8 ++ ++ ld r7, 8(r3) ++ ld r9, 8(r4) ++ cmpb r8, r7, r8 ++ cmpb r6, r7, r9 ++ orc. r8, r8, r6 ++ bne cr0, L(different1) ++ cmpldi cr7, r5, 8 ++ mr r9, r8 ++ ble cr7, L(ret1) ++ ++ /* Update pointers and size. */ ++ addi r5, r5, -8 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++L(align): ++ /* Now it has checked for first 32 bytes, align source1 to doubleword ++ and adjust source2 address. */ ++ vspltisb v0, 0 ++ vspltisb v2, -1 ++ or r6, r4, r3 ++ andi. r6, r6, 0xF ++ beq cr0, L(aligned) ++ lvsr v6, 0, r4 /* Compute mask. */ ++ clrldi r6, r4, 60 ++ subfic r11, r6, 16 ++ andi. r6, r3, 0xF ++ beq cr0, L(s1_align) ++ /* Both s1 and s2 are unaligned. */ ++ GET16BYTES(v5, r4, v6) ++ lvsr v10, 0, r3 /* Compute mask. */ ++ clrldi r6, r3, 60 ++ subfic r11, r6, 16 ++ GET16BYTES(v4, r3, v10) ++ VCMPNEZB(v7, v5, v4) ++ beq cr6, L(match) ++ b L(different) ++ ++ /* Align s1 to qw and adjust s2 address. */ ++ .align 4 ++L(match): ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ subf r5, r11, r5 ++ add r3, r3, r11 ++ add r4, r4, r11 ++ andi. r11, r4, 0xF ++ beq cr0, L(aligned) ++ lvsr v6, 0, r4 ++ clrldi r6, r4, 60 ++ subfic r11, r6, 16 ++ /* There are 2 loops depending on the input alignment. ++ Each loop gets 16 bytes from s1 and s2, checks for null ++ and compares them. Loops until a mismatch or null occurs. */ ++L(s1_align): ++ lvx v4, 0, r3 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ lvx v4, 0, r3 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ lvx v4, 0, r3 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ lvx v4, 0, r3 ++ GET16BYTES(v5, r4, v6) ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ b L(s1_align) ++ .align 4 ++L(aligned): ++ lvx v4, 0, r3 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ lvx v4, 0, r3 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ lvx v4, 0, r3 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ ++ lvx v4, 0, r3 ++ lvx v5, 0, r4 ++ VCMPNEZB(v7, v5, v4) ++ bne cr6, L(different) ++ cmpldi cr7, r5, 16 ++ ble cr7, L(ret0) ++ addi r5, r5, -16 ++ addi r3, r3, 16 ++ addi r4, r4, 16 ++ b L(aligned) ++ /* Calculate and return the difference. */ ++L(different): ++ VCTZLSBB(r6, v7) ++ cmplw cr7, r5, r6 ++ ble cr7, L(ret0) ++ VEXTUBRX(r5, r6, v4) ++ VEXTUBRX(r4, r6, v5) ++ subf r3, r4, r5 ++ extsw r3, r3 ++ blr ++ ++ .align 4 ++L(ret0): ++ li r9, 0 ++L(ret1): ++ mr r3, r9 ++ blr ++ ++ /* The code now checks if r8 and r5 are different by issuing a ++ cmpb and shifts the result based on its output: ++ ++ leadzero = (__builtin_ffsl (z1) - 1); ++ leadzero = leadzero > (n-1)*8 ? (n-1)*8 : leadzero; ++ r1 = (r1 >> leadzero) & 0xFFUL; ++ r2 = (r2 >> leadzero) & 0xFFUL; ++ return r1 - r2; */ ++ ++ .align 4 ++L(different1): ++ neg r11, r8 ++ sldi r5, r5, 3 ++ and r8, r11, r8 ++ addi r5, r5, -8 ++ cntlzd r8, r8 ++ subfic r8, r8, 63 ++ extsw r8, r8 ++ cmpld cr7, r8, r5 ++ ble cr7, L(different2) ++ mr r8, r5 ++L(different2): ++ extsw r8, r8 ++ srd r7, r7, r8 ++ srd r9, r9, r8 ++ rldicl r3, r7, 0, 56 ++ rldicl r9, r9, 0, 56 ++ subf r9, r9, 3 ++ extsw r9, r9 ++ mr r3, r9 ++ blr ++ ++ /* If unaligned 16 bytes reads across a 4K page boundary, it uses ++ a simple byte a byte comparison until the page alignment for s1 ++ is reached. */ ++ .align 4 ++L(pagecross): ++ lbz r7, 0(r3) ++ lbz r9, 0(r4) ++ subfic r8, r8,4095 ++ cmplw cr7, r9, r7 ++ bne cr7, L(byte_ne_3) ++ cmpdi cr7, r9, 0 ++ beq cr7, L(byte_ne_0) ++ addi r5, r5, -1 ++ subf r7, r8, r5 ++ subf r9, r7, r5 ++ addi r9, r9, 1 ++ mtctr r9 ++ b L(pagecross_loop1) ++ ++ .align 4 ++L(pagecross_loop0): ++ beq cr7, L(ret0) ++ lbz r9, 0(r3) ++ lbz r8, 0(r4) ++ addi r5, r5, -1 ++ cmplw cr7, r9, r8 ++ cmpdi cr5, r9, 0 ++ bne cr7, L(byte_ne_2) ++ beq cr5, L(byte_ne_0) ++L(pagecross_loop1): ++ cmpdi cr7, r5, 0 ++ addi r3, r3, 1 ++ addi r4, r4, 1 ++ bdnz L(pagecross_loop0) ++ cmpdi cr7, r7, 0 ++ li r9, 0 ++ bne+ cr7, L(align) ++ b L(ret1) ++ ++ .align 4 ++L(byte_ne_0): ++ li r7, 0 ++L(byte_ne_1): ++ subf r9, r9, r7 ++ extsw r9, r9 ++ b L(ret1) ++ ++ .align 4 ++L(byte_ne_2): ++ extsw r7, r9 ++ mr r9, r8 ++ b L(byte_ne_1) ++L(byte_ne_3): ++ extsw r7, r7 ++ b L(byte_ne_1) ++END(strncmp) ++libc_hidden_builtin_def(strncmp) ++#else ++#include ++#endif +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-24.patch b/SOURCES/glibc-rh1385004-24.patch new file mode 100644 index 00000000..5985c0ce --- /dev/null +++ b/SOURCES/glibc-rh1385004-24.patch @@ -0,0 +1,72 @@ +Update powerpc64 ULPs. + +The last upstream ULP update before the branch, in + +commit c6922934363f44b88250567f52036d8e9972c255 +Author: Andreas Schwab +Date: Sat Mar 3 14:20:24 2012 +0100 + + Update powerpc libm ULPs + +did not specify 1-ULP tolerance for all tests because some of them +returned the exact result. Current upstream uses a different way for +specifying ULPs, after this commit: + +commit e6b6a85705be16373fb3f78ef998edc62150499c +Author: Joseph Myers +Date: Wed Mar 5 15:02:38 2014 +0000 + + Don't include individual test ulps in libm-test-ulps. + +This implicitly increased the test tolerance for most (all?) math +functions to 1 ULP because at least one subtest was off by 1 ULP. + +Index: b/sysdeps/powerpc/fpu/libm-test-ulps +=================================================================== +--- a/sysdeps/powerpc/fpu/libm-test-ulps ++++ b/sysdeps/powerpc/fpu/libm-test-ulps +@@ -2396,6 +2396,9 @@ ldouble: 2 + Test "sin_downward (8) == 0.9893582466233817778081235982452886721164": + ildouble: 1 + ldouble: 1 ++Test "sin_downward (9) == 0.4121184852417565697562725663524351793439": ++float: 1 ++ifloat: 1 + + # sin_tonearest + Test "sin_tonearest (1) == 0.8414709848078965066525023216302989996226": +@@ -2438,10 +2441,15 @@ float: 1 + ifloat: 1 + ildouble: 2 + ldouble: 2 ++Test "sin_upward (10) == -0.5440211108893698134047476618513772816836": ++float: 1 ++ifloat: 1 + Test "sin_upward (2) == 0.9092974268256816953960198659117448427023": + float: 2 + ifloat: 2 + Test "sin_upward (3) == 0.1411200080598672221007448028081102798469": ++float: 1 ++ifloat: 1 + ildouble: 1 + ldouble: 1 + Test "sin_upward (4) == -0.7568024953079282513726390945118290941359": +@@ -2449,9 +2457,18 @@ float: 1 + ifloat: 1 + ildouble: 1 + ldouble: 1 ++Test "sin_upward (5) == -0.9589242746631384688931544061559939733525": ++float: 1 ++ifloat: 1 + Test "sin_upward (6) == -0.2794154981989258728115554466118947596280": + ildouble: 1 + ldouble: 1 ++Test "sin_upward (7) == 0.6569865987187890903969990915936351779369": ++float: 1 ++ifloat: 1 ++Test "sin_upward (8) == 0.9893582466233817778081235982452886721164": ++float: 1 ++ifloat: 1 + Test "sin_upward (9) == 0.4121184852417565697562725663524351793439": + float: 1 + ifloat: 1 diff --git a/SOURCES/glibc-rh1385004-3.patch b/SOURCES/glibc-rh1385004-3.patch new file mode 100644 index 00000000..0d5e09b2 --- /dev/null +++ b/SOURCES/glibc-rh1385004-3.patch @@ -0,0 +1,35 @@ +From 7235e7a509ef1f93cb895f6cdd2bf27f497a3d0a Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 31 Jul 2015 10:48:20 -0300 +Subject: [PATCH] powerpc: Fix PPC64/POWER7 conform tests + +When building with --disable-multi-arch the strstr POWER7 +optimization create and uses symbols that conflict with expect conform +tests. + + * sysdeps/powerpc/powerpc64/power7/strstr.S (strstr): Use __strnlen + for static build. + +(cherry picked from commit 6f714aa4ad5af2745ae2d185821d20ce8fabc2c5) +--- + ChangeLog | 7 +++++++ + sysdeps/powerpc/powerpc64/power7/strstr.S | 2 +- + 3 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index d70df5c..cf95a84 100644 +diff --git a/sysdeps/powerpc/powerpc64/power7/strstr.S b/sysdeps/powerpc/powerpc64/power7/strstr.S +index 8dca31c..bfb0c49 100644 +--- a/sysdeps/powerpc/powerpc64/power7/strstr.S ++++ b/sysdeps/powerpc/powerpc64/power7/strstr.S +@@ -39,7 +39,7 @@ + # ifdef SHARED + # define STRNLEN __GI_strnlen + # else +-# define STRNLEN strnlen ++# define STRNLEN __strnlen + # endif + #endif + +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-4.patch b/SOURCES/glibc-rh1385004-4.patch new file mode 100644 index 00000000..e659010e --- /dev/null +++ b/SOURCES/glibc-rh1385004-4.patch @@ -0,0 +1,112 @@ +From 561857f53a543684862c2b6d2308bc13affa2a18 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Tue, 18 Aug 2015 22:40:56 +0530 +Subject: [PATCH] powerpc: Handle worstcase behavior in strstr() for POWER7 + +Instead of checking needle length, constant 'n' number of comparisons +is checked to fall back to default implementation. This patch is tested +on powerpc64 and powerpc64le. + +2015-08-25 Rajalakshmi Srinivasaraghavan + + * sysdeps/powerpc/powerpc64/power7/strstr.S: Handle worst case. + +(cherry picked from commit fe7faec3e56a8dd64f78023a2f4a74fc8d42e79f) +--- + ChangeLog | 4 ++++ + sysdeps/powerpc/powerpc64/power7/strstr.S | 22 +++++++++++++++------- + 2 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index cf95a84..5cbd6d6 100644 +diff --git a/sysdeps/powerpc/powerpc64/power7/strstr.S b/sysdeps/powerpc/powerpc64/power7/strstr.S +index bfb0c49..fb3c810 100644 +--- a/sysdeps/powerpc/powerpc64/power7/strstr.S ++++ b/sysdeps/powerpc/powerpc64/power7/strstr.S +@@ -23,6 +23,8 @@ + /* The performance gain is obtained using aligned memory access, load + * doubleword and usage of cmpb instruction for quicker comparison. */ + ++#define ITERATIONS 64 ++ + #ifndef STRLEN + /* For builds with no IFUNC support, local calls should be made to internal + GLIBC symbol (created by libc_hidden_builtin_def). */ +@@ -62,6 +64,8 @@ EALIGN (strstr, 4, 0) + cfi_offset(r30, -16) + std r29, -24(r1) /* Save callers register r29. */ + cfi_offset(r29, -24) ++ std r28, -32(r1) /* Save callers register r28. */ ++ cfi_offset(r28, -32) + std r0, 16(r1) /* Store the link register. */ + cfi_offset(lr, 16) + stdu r1, -FRAMESIZE(r1) /* Create the stack frame. */ +@@ -69,7 +73,6 @@ EALIGN (strstr, 4, 0) + + dcbt 0, r3 + dcbt 0, r4 +- + cmpdi cr7, r3, 0 + beq cr7, L(retnull) + cmpdi cr7, r4, 0 +@@ -84,10 +87,6 @@ EALIGN (strstr, 4, 0) + cmpdi cr7, r3, 0 /* If search str is null. */ + beq cr7, L(ret_r3) + +- /* Call __strstr_ppc if needle len > 2048 */ +- cmpdi cr7, r3, 2048 +- bgt cr7, L(default) +- + mr r31, r3 + mr r4, r3 + mr r3, r29 +@@ -105,7 +104,8 @@ EALIGN (strstr, 4, 0) + /* If first char of search str is not present. */ + cmpdi cr7, r3, 0 + ble cr7, L(end) +- ++ /* Reg r28 is used to count the number of iterations. */ ++ li r28, 0 + rldicl r8, r3, 0, 52 /* Page cross check. */ + cmpldi cr7, r8, 4096-16 + bgt cr7, L(bytebybyte) +@@ -324,6 +324,10 @@ L(return4): + .align 4 + L(begin): + mr r3, r8 ++ /* When our iterations exceed ITERATIONS,fall back to default. */ ++ addi r28, r28, 1 ++ cmpdi cr7, r28, ITERATIONS ++ beq cr7, L(default) + lbz r4, 0(r30) + bl STRCHR + nop +@@ -423,6 +427,10 @@ L(nextbyte): + cmpdi cr7, r9, -1 + beq cr7, L(end) + addi r3, r4, 1 ++ /* When our iterations exceed ITERATIONS,fall back to default. */ ++ addi r28, r28, 1 ++ cmpdi cr7, r28, ITERATIONS ++ beq cr7, L(default) + lbz r4, 0(r30) + bl STRCHR + nop +@@ -490,7 +498,6 @@ L(retnull): + + .align 4 + L(default): +- mr r3, r29 + mr r4, r30 + bl __strstr_ppc + nop +@@ -500,6 +507,7 @@ L(end): + addi r1, r1, FRAMESIZE /* Restore stack pointer. */ + cfi_adjust_cfa_offset(-FRAMESIZE) + ld r0, 16(r1) /* Restore the saved link register. */ ++ ld r28, -32(r1) /* Restore callers save register r28. */ + ld r29, -24(r1) /* Restore callers save register r29. */ + ld r30, -16(r1) /* Restore callers save register r30. */ + ld r31, -8(r1) /* Restore callers save register r31. */ +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-5.patch b/SOURCES/glibc-rh1385004-5.patch new file mode 100644 index 00000000..a9d56ba5 --- /dev/null +++ b/SOURCES/glibc-rh1385004-5.patch @@ -0,0 +1,68 @@ +From de9b90366c27db80777d5099e4b22298f0b61a29 Mon Sep 17 00:00:00 2001 +From: Carlos Eduardo Seo +Date: Thu, 13 Aug 2015 14:33:06 -0300 +Subject: [PATCH] powerpc: Add missing hwcap strings. + +Some features in hwcap.h do not have matching string descriptors +to be displayed when LD_SHOW_AUXV=1. This patch fixes the problem. + +2015-08-13 Carlos Eduardo Seo + + * sysdeps/powerpc/dl-procinfo.c: + (_dl_powerpc_cap_flags): Added missing strings for some + hwcap features. + * sysdeps/powerpc/dl-procinfo.h: Updated hwcap bit count. + +(cherry picked from commit 94ec7e007f4845de284d4f7569721b225ba77572) +--- + ChangeLog | 7 +++++++ + sysdeps/powerpc/dl-procinfo.c | 6 +++--- + sysdeps/powerpc/dl-procinfo.h | 4 ++-- + 3 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/ChangeLog b/ChangeLog +index 5cbd6d6..d9d3659 100644 +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index 3a8cc41..6eda5d9 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -45,11 +45,11 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_cap_flags + #else +-PROCINFO_CLASS const char _dl_powerpc_cap_flags[57][10] ++PROCINFO_CLASS const char _dl_powerpc_cap_flags[60][10] + #endif + #ifndef PROCINFO_DECL + = { +- "vsx", ++ "ppcle", "true_le", "archpmu", "vsx", + "arch_2_06", "power6x", "dfp", "pa6t", + "arch_2_05", "ic_snoop", "smt", "booke", + "cellbe", "power5+", "power5", "power4", +@@ -62,7 +62,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[57][10] + "", "", "", "", + "", "", "", "", + "", "", "", "", +- "", "", "tar", "isel", ++ "", "vcrypto", "tar", "isel", + "ebb", "dscr", "htm", "arch_2_07", + } + #endif +diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h +index cf167b0..36873cf 100644 +--- a/sysdeps/powerpc/dl-procinfo.h ++++ b/sysdeps/powerpc/dl-procinfo.h +@@ -22,8 +22,8 @@ + #include + #include /* This defines the PPC_FEATURE[2]_* macros. */ + +-/* There are 25 bits used, but they are bits 7..31. */ +-#define _DL_HWCAP_FIRST 7 ++/* There are 28 bits used, but they are bits 4..31. */ ++#define _DL_HWCAP_FIRST 4 + + /* The total number of available bits (including those prior to + _DL_HWCAP_FIRST). Some of these bits might not be used. */ +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-6.patch b/SOURCES/glibc-rh1385004-6.patch new file mode 100644 index 00000000..55d60a5d --- /dev/null +++ b/SOURCES/glibc-rh1385004-6.patch @@ -0,0 +1,28 @@ +From db22400947e1c82153e5270d23fed53fc1e3a659 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Mon, 23 Jun 2014 09:38:47 -0500 +Subject: [PATCH] PowerPC: sync hwcap.h capabilities + +Linux commit dd58a092c4202f2bd490adab7285b3ff77f8e467 added the +PPC_FEATURE2_VEC_CRYPTO auvx capability to indicate whether to +hardware supports vector crypto hardware instructions. This patch +adds its definition to powerpc hwcap bits. +--- + ChangeLog | 5 +++++ + sysdeps/powerpc/bits/hwcap.h | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/ChangeLog b/ChangeLog +index 426af5d..b4f687f 100644 +diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h +index 7daec91..e894bd4 100644 +--- a/sysdeps/powerpc/bits/hwcap.h ++++ b/sysdeps/powerpc/bits/hwcap.h +@@ -62,3 +62,5 @@ + #define PPC_FEATURE2_HAS_EBB 0x10000000 /* Event Base Branching */ + #define PPC_FEATURE2_HAS_ISEL 0x08000000 /* Integer Select */ + #define PPC_FEATURE2_HAS_TAR 0x04000000 /* Target Address Register */ ++#define PPC_FEATURE2_HAS_VEC_CRYPTO 0x02000000 /* Target supports vector ++ instruction. */ +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-7.patch b/SOURCES/glibc-rh1385004-7.patch new file mode 100644 index 00000000..0a33f04e --- /dev/null +++ b/SOURCES/glibc-rh1385004-7.patch @@ -0,0 +1,51 @@ +From 6edf51a1d5d2f070998553f99f3a6dc90c5c2969 Mon Sep 17 00:00:00 2001 +From: Carlos Eduardo Seo +Date: Wed, 19 Aug 2015 01:42:55 -0300 +Subject: [PATCH] powerpc: Sync hwcap.h with kernel + +Linux commit b4b56f9ecab40f3b4ef53e130c9f6663be491894 introduced +a new HWCAP2 bit to indicate that the kernel now aborts a memory +transaction when a syscall is made. This patch adds that bit to +sysdeps/powerpc/bits/hwcap.h. + +2015-08-26 Carlos Eduardo Seo + + * sysdeps/powerpc/bits/hwcap.h: Add PPC_FEATURE2_HTM_NOSC. + * sysdeps/powerpc/dl-procinfo.c: + (_dl_powerpc_cap_flags): Added descriptor for this hwcap + feature so it shows when LD_SHOW_AUXV=1. + +(cherry picked from commit 3c13f28c8eac1e5a883d1b3801314430a094fc99) +--- + ChangeLog | 7 +++++++ + sysdeps/powerpc/bits/hwcap.h | 2 ++ + sysdeps/powerpc/dl-procinfo.c | 2 +- + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index d9d3659..079da2a 100644 +diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h +index f8c48cd..12554ca 100644 +--- a/sysdeps/powerpc/bits/hwcap.h ++++ b/sysdeps/powerpc/bits/hwcap.h +@@ -64,3 +64,5 @@ + #define PPC_FEATURE2_HAS_TAR 0x04000000 /* Target Address Register */ + #define PPC_FEATURE2_HAS_VEC_CRYPTO 0x02000000 /* Target supports vector + instruction. */ ++#define PPC_FEATURE2_HTM_NOSC 0x01000000 /* Kernel aborts transaction ++ when a syscall is made. */ +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index 6eda5d9..770c1f3 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -62,7 +62,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[60][10] + "", "", "", "", + "", "", "", "", + "", "", "", "", +- "", "vcrypto", "tar", "isel", ++ "htm-nosc", "vcrypto", "tar", "isel", + "ebb", "dscr", "htm", "arch_2_07", + } + #endif +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-8.patch b/SOURCES/glibc-rh1385004-8.patch new file mode 100644 index 00000000..3aedb3f1 --- /dev/null +++ b/SOURCES/glibc-rh1385004-8.patch @@ -0,0 +1,136 @@ +From c2b54e66e194405a1ff062bb442ede9a8c4b913a Mon Sep 17 00:00:00 2001 +From: Carlos Eduardo Seo +Date: Wed, 4 Nov 2015 19:30:49 -0200 +Subject: [PATCH] powerpc: Add basic support for POWER9 sans hwcap. + +This patch adds the minimum changes for supporting the POWER9 processor. + +(cherry picked from commit b1f19b8ef1003f202424ca222003a18b880bf914) +--- + ChangeLog | 13 +++++++++++++ + sysdeps/powerpc/dl-procinfo.c | 3 ++- + sysdeps/powerpc/dl-procinfo.h | 6 +++++- + sysdeps/powerpc/powerpc32/power9/Implies | 2 ++ + sysdeps/powerpc/powerpc32/power9/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc32/power9/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power9/Implies | 2 ++ + sysdeps/powerpc/powerpc64/power9/fpu/Implies | 2 ++ + sysdeps/powerpc/powerpc64/power9/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power9/multiarch/Implies | 1 + + 10 files changed, 30 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power9/Implies + create mode 100644 sysdeps/powerpc/powerpc32/power9/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc32/power9/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power9/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power9/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power9/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power9/multiarch/Implies + +diff --git a/ChangeLog b/ChangeLog +index 079da2a..cecd77c 100644 +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index 770c1f3..a8df5b8 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -75,7 +75,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[60][10] + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_platforms + #else +-PROCINFO_CLASS const char _dl_powerpc_platforms[14][12] ++PROCINFO_CLASS const char _dl_powerpc_platforms[15][12] + #endif + #ifndef PROCINFO_DECL + = { +@@ -93,6 +93,7 @@ PROCINFO_CLASS const char _dl_powerpc_platforms[14][12] + [PPC_PLATFORM_PPC464] = "ppc464", + [PPC_PLATFORM_PPC476] = "ppc476", + [PPC_PLATFORM_POWER8] = "power8", ++ [PPC_PLATFORM_POWER9] = "power9" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h +index 36873cf..407149b 100644 +--- a/sysdeps/powerpc/dl-procinfo.h ++++ b/sysdeps/powerpc/dl-procinfo.h +@@ -40,7 +40,7 @@ + #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ + + PPC_FEATURE_HAS_DFP) + +-#define _DL_PLATFORMS_COUNT 14 ++#define _DL_PLATFORMS_COUNT 15 + + #define _DL_FIRST_PLATFORM 32 + /* Mask to filter out platforms. */ +@@ -62,6 +62,7 @@ + #define PPC_PLATFORM_PPC464 11 + #define PPC_PLATFORM_PPC476 12 + #define PPC_PLATFORM_POWER8 13 ++#define PPC_PLATFORM_POWER9 14 + + static inline const char * + __attribute__ ((unused)) +@@ -125,6 +126,9 @@ _dl_string_platform (const char *str) + case '8': + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER8; + break; ++ case '9': ++ ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER9; ++ break; + default: + return -1; + } +diff --git a/sysdeps/powerpc/powerpc32/power9/Implies b/sysdeps/powerpc/powerpc32/power9/Implies +new file mode 100644 +index 0000000..066dea2 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power9/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc32/power8/fpu ++powerpc/powerpc32/power8 +diff --git a/sysdeps/powerpc/powerpc32/power9/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc32/power9/fpu/multiarch/Implies +new file mode 100644 +index 0000000..4393b56 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power9/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc32/power8/fpu/multiarch +diff --git a/sysdeps/powerpc/powerpc32/power9/multiarch/Implies b/sysdeps/powerpc/powerpc32/power9/multiarch/Implies +new file mode 100644 +index 0000000..4393b56 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc32/power9/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc32/power8/fpu/multiarch +diff --git a/sysdeps/powerpc/powerpc64/power9/Implies b/sysdeps/powerpc/powerpc64/power9/Implies +new file mode 100644 +index 0000000..fad2505 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power9/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc64/power8/fpu ++powerpc/powerpc64/power8 +diff --git a/sysdeps/powerpc/powerpc64/power9/fpu/Implies b/sysdeps/powerpc/powerpc64/power9/fpu/Implies +new file mode 100644 +index 0000000..fad2505 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power9/fpu/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc64/power8/fpu ++powerpc/powerpc64/power8 +diff --git a/sysdeps/powerpc/powerpc64/power9/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power9/fpu/multiarch/Implies +new file mode 100644 +index 0000000..f11e1bd +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power9/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power8/fpu/multiarch +diff --git a/sysdeps/powerpc/powerpc64/power9/multiarch/Implies b/sysdeps/powerpc/powerpc64/power9/multiarch/Implies +new file mode 100644 +index 0000000..dd6bca4 +--- /dev/null ++++ b/sysdeps/powerpc/powerpc64/power9/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power8/multiarch +-- +2.1.0 diff --git a/SOURCES/glibc-rh1385004-9.patch b/SOURCES/glibc-rh1385004-9.patch new file mode 100644 index 00000000..cf24a9a0 --- /dev/null +++ b/SOURCES/glibc-rh1385004-9.patch @@ -0,0 +1,43 @@ +From 2f308f69b40f960729d4358afb1b1effb218b6cb Mon Sep 17 00:00:00 2001 +From: Carlos Eduardo Seo +Date: Tue, 5 Jan 2016 15:13:18 -0200 +Subject: [PATCH] powerpc: Add hwcap2 bits for POWER9. + +Added hwcap2 bit masks for Power ISA 3.0 and VSX IEEE binary float 128-bit +features. + +(cherry picked from commit d2de9ef7ad35341fd6f098f7e84a1128f2027d0c) +--- + ChangeLog | 7 +++++++ + sysdeps/powerpc/bits/hwcap.h | 3 +++ + sysdeps/powerpc/dl-procinfo.c | 2 +- + 3 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/ChangeLog b/ChangeLog +index cecd77c..565da33 100644 +diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h +index 12554ca..55b37a4 100644 +--- a/sysdeps/powerpc/bits/hwcap.h ++++ b/sysdeps/powerpc/bits/hwcap.h +@@ -66,3 +66,6 @@ + instruction. */ + #define PPC_FEATURE2_HTM_NOSC 0x01000000 /* Kernel aborts transaction + when a syscall is made. */ ++#define PPC_FEATURE2_ARCH_3_00 0x00800000 /* ISA 3.0 */ ++#define PPC_FEATURE2_HAS_IEEE128 0x00400000 /* VSX IEEE Binary Float ++ 128-bit */ +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index a8df5b8..1bbeb89 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -61,7 +61,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[60][10] + "", "", "", "", + "", "", "", "", + "", "", "", "", +- "", "", "", "", ++ "", "", "ieee128", "arch_3_00", + "htm-nosc", "vcrypto", "tar", "isel", + "ebb", "dscr", "htm", "arch_2_07", + } +-- +2.1.0 diff --git a/SOURCES/glibc-rh1387874.patch b/SOURCES/glibc-rh1387874.patch new file mode 100644 index 00000000..1ea87493 --- /dev/null +++ b/SOURCES/glibc-rh1387874.patch @@ -0,0 +1,23 @@ +commit c6fe55cf6089fc5cf1cea15fc7e1c9a8b90d9fda +Author: Andreas Jaeger +Date: Fri Jan 11 11:53:13 2013 +0100 + + Add MSG_FASTOPEN + + [BZ #15003] + * sysdeps/unix/sysv/linux/bits/socket.h (MSG_FASTOPEN): New + value. Sync with Linux 3.7. + +diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h +index 25b115e..eadd7d9 100644 +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -207,6 +207,8 @@ enum + #define MSG_MORE MSG_MORE + MSG_WAITFORONE = 0x10000, /* Wait for at least one packet to return.*/ + #define MSG_WAITFORONE MSG_WAITFORONE ++ MSG_FASTOPEN = 0x20000000, /* Send data in TCP SYN. */ ++#define MSG_FASTOPEN MSG_FASTOPEN + + MSG_CMSG_CLOEXEC = 0x40000000 /* Set close_on_exit for file + descriptor received through diff --git a/SOURCES/glibc-rh1392540.patch b/SOURCES/glibc-rh1392540.patch new file mode 100644 index 00000000..ac67735f --- /dev/null +++ b/SOURCES/glibc-rh1392540.patch @@ -0,0 +1,15 @@ +Add "sss" to the automount database. The sss service ordering is +based on passwd (and others; sss comes after files) and netgroup (sss +comes after nisplus). + +Index: b/releng/nsswitch.conf +=================================================================== +--- a/releng/nsswitch.conf ++++ b/releng/nsswitch.conf +@@ -59,6 +59,6 @@ netgroup: nisplus sss + + publickey: nisplus + +-automount: files nisplus ++automount: files nisplus sss + aliases: files nisplus diff --git a/SOURCES/glibc-rh1398244.patch b/SOURCES/glibc-rh1398244.patch new file mode 100644 index 00000000..cb56643d --- /dev/null +++ b/SOURCES/glibc-rh1398244.patch @@ -0,0 +1,17 @@ +2016-10-28 Tulio Magno Quites Machado Filho + + [BZ #20728] + * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Replace a + branch to _exit() by a function call. + +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S +@@ -112,7 +112,7 @@ + #ifdef SHARED + b JUMPTARGET(__GI__exit) + #else +- b JUMPTARGET(_exit) ++ bl JUMPTARGET(_exit) + /* We won't ever get here but provide a nop so that the linker + will insert a toc adjusting stub if necessary. */ + nop diff --git a/SOURCES/glibc-rh1398413.patch b/SOURCES/glibc-rh1398413.patch new file mode 100644 index 00000000..fdd737f4 --- /dev/null +++ b/SOURCES/glibc-rh1398413.patch @@ -0,0 +1,726 @@ +commit db3476aff19b75c4fdefbe65fcd5f0a90588ba51 +Author: Florian Weimer +Date: Thu Jun 23 20:01:40 2016 +0200 + + libio: Implement vtable verification [BZ #20191] + + This commit puts all libio vtables in a dedicated, read-only ELF + section, so that they are consecutive in memory. Before any indirect + jump, the vtable pointer is checked against the section boundaries, + and the process is terminated if the vtable pointer does not fall into + the special ELF section. + + To enable backwards compatibility, a special flag variable + (_IO_accept_foreign_vtables), protected by the pointer guard, avoids + process termination if libio stream object constructor functions have + been called earlier. Such constructor functions are called by the GCC + 2.95 libstdc++ library, and this mechanism ensures compatibility with + old binaries. Existing callers inside glibc of these functions are + adjusted to call the original functions, not the wrappers which enable + vtable compatiblity. + + The compatibility mechanism is used to enable passing FILE * objects + across a static dlopen boundary, too. + +diff -rupN a/Makerules b/Makerules +--- a/Makerules 2017-08-24 14:50:27.000000000 -0400 ++++ b/Makerules 2017-08-24 14:56:40.194819878 -0400 +@@ -520,6 +520,9 @@ $(common-objpfx)shlib.lds: $(common-objp + PROVIDE(__start___libc_thread_subfreeres = .);\ + __libc_thread_subfreeres : { *(__libc_thread_subfreeres) }\ + PROVIDE(__stop___libc_thread_subfreeres = .);\ ++ PROVIDE(__start___libc_IO_vtables = .);\ ++ __libc_IO_vtables : { *(__libc_IO_vtables) }\ ++ PROVIDE(__stop___libc_IO_vtables = .);\ + /DISCARD/ : { *(.gnu.glibc-stub.*) }@' + test -s $@T + mv -f $@T $@ +diff -rupN a/debug/obprintf_chk.c b/debug/obprintf_chk.c +--- a/debug/obprintf_chk.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/debug/obprintf_chk.c 2017-08-24 14:56:40.194819878 -0400 +@@ -35,7 +35,7 @@ struct _IO_obstack_file + struct obstack *obstack; + }; + +-extern const struct _IO_jump_t _IO_obstack_jumps attribute_hidden; ++extern const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden; + + int + __obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format, +diff -rupN a/debug/vdprintf_chk.c b/debug/vdprintf_chk.c +--- a/debug/vdprintf_chk.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/debug/vdprintf_chk.c 2017-08-24 14:56:40.194819878 -0400 +@@ -39,7 +39,7 @@ __vdprintf_chk (int d, int flags, const + #endif + _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); + _IO_JUMPS (&tmpfil) = &_IO_file_jumps; +- _IO_file_init (&tmpfil); ++ _IO_new_file_init_internal (&tmpfil); + #if !_IO_UNIFIED_JUMPTABLES + tmpfil.vtable = NULL; + #endif +diff -rupN a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c +--- a/debug/vsnprintf_chk.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/debug/vsnprintf_chk.c 2017-08-24 14:56:40.194819878 -0400 +@@ -20,7 +20,7 @@ + #include "../libio/libioP.h" + #include "../libio/strfile.h" + +-extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden; ++extern const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden; + + /* Write formatted output into S, according to the format + string FORMAT, writing no more than MAXLEN characters. */ +diff -rupN a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c +--- a/debug/vsprintf_chk.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/debug/vsprintf_chk.c 2017-08-24 14:56:40.194819878 -0400 +@@ -34,7 +34,7 @@ _IO_str_chk_overflow (fp, c) + } + + +-static const struct _IO_jump_t _IO_str_chk_jumps = ++static const struct _IO_jump_t _IO_str_chk_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), +diff -rupN a/libio/Makefile b/libio/Makefile +--- a/libio/Makefile 2017-08-24 14:50:22.000000000 -0400 ++++ b/libio/Makefile 2017-08-24 17:29:03.754025266 -0400 +@@ -44,7 +44,7 @@ routines := \ + __fbufsize __freading __fwriting __freadable __fwritable __flbf \ + __fpurge __fpending __fsetlocking \ + \ +- libc_fatal fmemopen ++ libc_fatal fmemopen vtables + + include ../Makeconfig + +diff -rupN a/libio/fileops.c b/libio/fileops.c +--- a/libio/fileops.c 2017-08-24 14:50:23.000000000 -0400 ++++ b/libio/fileops.c 2017-08-24 14:57:57.765902179 -0400 +@@ -139,7 +139,7 @@ extern struct __gconv_trans_data __libio + + + void +-_IO_new_file_init (fp) ++_IO_new_file_init_internal (fp) + struct _IO_FILE_plus *fp; + { + /* POSIX.1 allows another file handle to be used to change the position +@@ -151,7 +151,15 @@ _IO_new_file_init (fp) + _IO_link_in (fp); + fp->file._fileno = -1; + } +-libc_hidden_ver (_IO_new_file_init, _IO_file_init) ++ ++/* External version of _IO_new_file_init_internal which switches off ++ vtable validation. */ ++void ++_IO_new_file_init (struct _IO_FILE_plus *fp) ++{ ++ IO_set_accept_foreign_vtables (&_IO_vtable_check); ++ _IO_new_file_init_internal (fp); ++} + + int + _IO_new_file_close_it (fp) +@@ -1586,7 +1594,7 @@ versioned_symbol (libc, _IO_new_file_wri + versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1); + #endif + +-const struct _IO_jump_t _IO_file_jumps = ++const struct _IO_jump_t _IO_file_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), +@@ -1611,7 +1619,7 @@ const struct _IO_jump_t _IO_file_jumps = + }; + libc_hidden_data_def (_IO_file_jumps) + +-const struct _IO_jump_t _IO_file_jumps_mmap = ++const struct _IO_jump_t _IO_file_jumps_mmap libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), +@@ -1635,7 +1643,7 @@ const struct _IO_jump_t _IO_file_jumps_m + JUMP_INIT(imbue, _IO_default_imbue) + }; + +-const struct _IO_jump_t _IO_file_jumps_maybe_mmap = ++const struct _IO_jump_t _IO_file_jumps_maybe_mmap libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), +diff -rupN a/libio/genops.c b/libio/genops.c +--- a/libio/genops.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/genops.c 2017-08-24 15:44:28.757584527 -0400 +@@ -595,13 +595,19 @@ _IO_default_doallocate (fp) + libc_hidden_def (_IO_default_doallocate) + + void +-_IO_init (fp, flags) ++_IO_init_internal (fp, flags) + _IO_FILE *fp; + int flags; + { + _IO_no_init (fp, flags, -1, NULL, NULL); + } +-libc_hidden_def (_IO_init) ++ ++void ++_IO_init (_IO_FILE *fp, int flags) ++{ ++ IO_set_accept_foreign_vtables (&_IO_vtable_check); ++ _IO_init_internal (fp, flags); ++} + + void + _IO_old_init (fp, flags) +diff -rupN a/libio/iofdopen.c b/libio/iofdopen.c +--- a/libio/iofdopen.c 2017-08-24 14:50:21.000000000 -0400 ++++ b/libio/iofdopen.c 2017-08-24 14:56:40.220819906 -0400 +@@ -158,15 +158,15 @@ _IO_new_fdopen (fd, mode) + (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap : + #endif + &_IO_file_jumps; +- _IO_file_init (&new_f->fp); ++ _IO_new_file_init_internal (&new_f->fp); + #if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; + #endif +- /* We only need to record the fd because _IO_file_init will have unset the +- offset. It is important to unset the cached offset because the real +- offset in the file could change between now and when the handle is +- activated and we would then mislead ftell into believing that we have a +- valid offset. */ ++ /* We only need to record the fd because _IO_file_init_internal will ++ have unset the offset. It is important to unset the cached ++ offset because the real offset in the file could change between ++ now and when the handle is activated and we would then mislead ++ ftell into believing that we have a valid offset. */ + new_f->fp.file._fileno = fd; + new_f->fp.file._flags &= ~_IO_DELETE_DONT_CLOSE; + +diff -rupN a/libio/iofopen.c b/libio/iofopen.c +--- a/libio/iofopen.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/iofopen.c 2017-08-24 14:56:40.223819909 -0400 +@@ -83,7 +83,7 @@ __fopen_internal (filename, mode, is32) + _IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL); + #endif + _IO_JUMPS (&new_f->fp) = &_IO_file_jumps; +- _IO_file_init (&new_f->fp); ++ _IO_new_file_init_internal (&new_f->fp); + #if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; + #endif +diff -rupN a/libio/iofopncook.c b/libio/iofopncook.c +--- a/libio/iofopncook.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/iofopncook.c 2017-08-24 15:46:49.061694225 -0400 +@@ -116,7 +116,7 @@ _IO_cookie_seekoff (fp, offset, dir, mod + } + + +-static const struct _IO_jump_t _IO_cookie_jumps = { ++static const struct _IO_jump_t _IO_cookie_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), +@@ -144,13 +144,13 @@ void + _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write, + void *cookie, _IO_cookie_io_functions_t io_functions) + { +- _IO_init (&cfile->__fp.file, 0); ++ _IO_init_internal (&cfile->__fp.file, 0); + _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps; + + cfile->__cookie = cookie; + cfile->__io_functions = io_functions; + +- _IO_file_init (&cfile->__fp); ++ _IO_new_file_init_internal (&cfile->__fp); + + _IO_mask_flags (&cfile->__fp.file, read_write, + _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); +@@ -235,7 +235,7 @@ _IO_old_cookie_seek (fp, offset, dir) + return (ret == -1) ? _IO_pos_BAD : ret; + } + +-static const struct _IO_jump_t _IO_old_cookie_jumps = { ++static const struct _IO_jump_t _IO_old_cookie_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_file_finish), + JUMP_INIT(overflow, _IO_file_overflow), +diff -rupN a/libio/iopopen.c b/libio/iopopen.c +--- a/libio/iopopen.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/iopopen.c 2017-08-24 14:56:40.234819921 -0400 +@@ -292,9 +292,9 @@ _IO_new_popen (command, mode) + new_f->fpx.file.file._lock = &new_f->lock; + #endif + fp = &new_f->fpx.file.file; +- _IO_init (fp, 0); ++ _IO_init_internal (fp, 0); + _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps; +- _IO_new_file_init (&new_f->fpx.file); ++ _IO_new_file_init_internal (&new_f->fpx.file); + #if !_IO_UNIFIED_JUMPTABLES + new_f->fpx.file.vtable = NULL; + #endif +@@ -350,7 +350,7 @@ _IO_new_proc_close (fp) + return wstatus; + } + +-static const struct _IO_jump_t _IO_proc_jumps = { ++static const struct _IO_jump_t _IO_proc_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), + JUMP_INIT(overflow, _IO_new_file_overflow), +diff -rupN a/libio/iovdprintf.c b/libio/iovdprintf.c +--- a/libio/iovdprintf.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/iovdprintf.c 2017-08-24 14:56:40.237819924 -0400 +@@ -42,7 +42,7 @@ _IO_vdprintf (d, format, arg) + #endif + _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); + _IO_JUMPS (&tmpfil) = &_IO_file_jumps; +- _IO_file_init (&tmpfil); ++ _IO_new_file_init_internal (&tmpfil); + #if !_IO_UNIFIED_JUMPTABLES + tmpfil.vtable = NULL; + #endif +diff -rupN a/libio/libioP.h b/libio/libioP.h +--- a/libio/libioP.h 2017-08-24 14:50:26.000000000 -0400 ++++ b/libio/libioP.h 2017-08-24 17:26:39.918165252 -0400 +@@ -108,11 +108,12 @@ extern "C" { + + #if _IO_JUMPS_OFFSET + # define _IO_JUMPS_FUNC(THIS) \ +- (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) \ +- + (THIS)->_vtable_offset)) ++ (IO_validate_vtable \ ++ (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) \ ++ + (THIS)->_vtable_offset))) + # define _IO_vtable_offset(THIS) (THIS)->_vtable_offset + #else +-# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) ++# define _IO_JUMPS_FUNC(THIS) (IO_validate_vtable (_IO_JUMPS ((struct _IO_FILE_plus *) (THIS)))) + # define _IO_vtable_offset(THIS) 0 + #endif + #define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS) +@@ -361,8 +362,7 @@ extern void _IO_switch_to_main_get_area + extern void _IO_switch_to_backup_area (_IO_FILE *) __THROW; + extern int _IO_switch_to_get_mode (_IO_FILE *); + libc_hidden_proto (_IO_switch_to_get_mode) +-extern void _IO_init (_IO_FILE *, int) __THROW; +-libc_hidden_proto (_IO_init) ++extern void _IO_init_internal (_IO_FILE *, int) attribute_hidden; + extern int _IO_sputbackc (_IO_FILE *, int) __THROW; + libc_hidden_proto (_IO_sputbackc) + extern int _IO_sungetc (_IO_FILE *) __THROW; +@@ -570,8 +570,6 @@ extern int _IO_file_underflow_maybe_mmap + extern int _IO_file_overflow (_IO_FILE *, int); + libc_hidden_proto (_IO_file_overflow) + #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1) +-extern void _IO_file_init (struct _IO_FILE_plus *) __THROW; +-libc_hidden_proto (_IO_file_init) + extern _IO_FILE* _IO_file_attach (_IO_FILE *, int); + libc_hidden_proto (_IO_file_attach) + extern _IO_FILE* _IO_file_open (_IO_FILE *, const char *, int, int, int, int); +@@ -597,7 +595,8 @@ extern _IO_FILE* _IO_new_file_fopen (_IO + int); + extern void _IO_no_init (_IO_FILE *, int, int, struct _IO_wide_data *, + const struct _IO_jump_t *) __THROW; +-extern void _IO_new_file_init (struct _IO_FILE_plus *) __THROW; ++extern void _IO_new_file_init_internal (struct _IO_FILE_plus *) ++ __THROW attribute_hidden; + extern _IO_FILE* _IO_new_file_setbuf (_IO_FILE *, char *, _IO_ssize_t); + extern _IO_FILE* _IO_file_setbuf_mmap (_IO_FILE *, char *, _IO_ssize_t); + extern int _IO_new_file_sync (_IO_FILE *); +@@ -612,7 +611,8 @@ extern _IO_off64_t _IO_old_file_seekoff + extern _IO_size_t _IO_old_file_xsputn (_IO_FILE *, const void *, _IO_size_t); + extern int _IO_old_file_underflow (_IO_FILE *); + extern int _IO_old_file_overflow (_IO_FILE *, int); +-extern void _IO_old_file_init (struct _IO_FILE_plus *) __THROW; ++extern void _IO_old_file_init_internal (struct _IO_FILE_plus *) ++ __THROW attribute_hidden; + extern _IO_FILE* _IO_old_file_attach (_IO_FILE *, int); + extern _IO_FILE* _IO_old_file_fopen (_IO_FILE *, const char *, const char *); + extern _IO_ssize_t _IO_old_file_write (_IO_FILE *, const void *, _IO_ssize_t); +@@ -656,10 +656,6 @@ extern void _IO_str_finish (_IO_FILE *, + + /* Other strfile functions */ + struct _IO_strfile_; +-extern void _IO_str_init_static (struct _IO_strfile_ *, char *, int, char *) +- __THROW; +-extern void _IO_str_init_readonly (struct _IO_strfile_ *, const char *, int) +- __THROW; + extern _IO_ssize_t _IO_str_count (_IO_FILE *) __THROW; + + /* And the wide character versions. */ +@@ -913,3 +909,57 @@ _IO_acquire_lock_clear_flags2_fct (_IO_F + | _IO_FLAGS2_SCANF_STD); \ + } while (0) + #endif ++ ++/* Collect all vtables in a special section for vtable verification. ++ These symbols cover the extent of this section. */ ++symbol_set_declare (__libc_IO_vtables) ++ ++/* libio vtables need to carry this attribute so that they pass ++ validation. */ ++#define libio_vtable __attribute__ ((section ("__libc_IO_vtables"))) ++ ++#ifdef SHARED ++/* If equal to &_IO_vtable_check (with pointer guard protection), ++ unknown vtable pointers are valid. This function pointer is solely ++ used as a flag. */ ++extern void (*IO_accept_foreign_vtables) (void) attribute_hidden; ++ ++/* Assigns the passed function pointer (either NULL or ++ &_IO_vtable_check) to IO_accept_foreign_vtables. */ ++static inline void ++IO_set_accept_foreign_vtables (void (*flag) (void)) ++{ ++ PTR_MANGLE (flag); ++ atomic_store_relaxed (&IO_accept_foreign_vtables, flag); ++} ++ ++#else /* !SHARED */ ++ ++/* The statically-linked version does nothing. */ ++static inline void ++IO_set_accept_foreign_vtables (void (*flag) (void)) ++{ ++} ++ ++#endif ++ ++/* Check if unknown vtable pointers are permitted; otherwise, ++ terminate the process. */ ++void _IO_vtable_check (void) attribute_hidden; ++ ++/* Perform vtable pointer validation. If validation fails, terminate ++ the process. */ ++static inline const struct _IO_jump_t * ++IO_validate_vtable (const struct _IO_jump_t *vtable) ++{ ++ /* Fast path: The vtable pointer is within the __libc_IO_vtables ++ section. */ ++ uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables; ++ const char *ptr = (const char *) vtable; ++ uintptr_t offset = ptr - __start___libc_IO_vtables; ++ if (__glibc_unlikely (offset >= section_length)) ++ /* The vtable pointer is not in the expected section. Use the ++ slow path, which will terminate the process if necessary. */ ++ _IO_vtable_check (); ++ return vtable; ++} +diff -rupN a/libio/memstream.c b/libio/memstream.c +--- a/libio/memstream.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/memstream.c 2017-08-24 15:56:02.643120827 -0400 +@@ -33,7 +33,7 @@ static int _IO_mem_sync (_IO_FILE* fp) _ + static void _IO_mem_finish (_IO_FILE* fp, int) __THROW; + + +-static const struct _IO_jump_t _IO_mem_jumps = ++static const struct _IO_jump_t _IO_mem_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_mem_finish), +@@ -85,7 +85,7 @@ open_memstream (bufloc, sizeloc) + buf = calloc (1, _IO_BUFSIZ); + if (buf == NULL) + return NULL; +- _IO_init (&new_f->fp._sf._sbf._f, 0); ++ _IO_init_internal (&new_f->fp._sf._sbf._f, 0); + _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps; + _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf); + new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF; +diff -rupN a/libio/obprintf.c b/libio/obprintf.c +--- a/libio/obprintf.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/obprintf.c 2017-08-24 14:56:40.255819944 -0400 +@@ -91,7 +91,7 @@ _IO_obstack_xsputn (_IO_FILE *fp, const + + + /* the jump table. */ +-const struct _IO_jump_t _IO_obstack_jumps attribute_hidden = ++const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, NULL), +diff -rupN a/libio/oldfileops.c b/libio/oldfileops.c +--- a/libio/oldfileops.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/oldfileops.c 2017-08-24 15:56:27.333139635 -0400 +@@ -113,7 +113,7 @@ extern int errno; + + void + attribute_compat_text_section +-_IO_old_file_init (fp) ++_IO_old_file_init_internal (fp) + struct _IO_FILE_plus *fp; + { + /* POSIX.1 allows another file handle to be used to change the position +@@ -138,6 +138,14 @@ _IO_old_file_init (fp) + #endif + } + ++void ++attribute_compat_text_section ++_IO_old_file_init (struct _IO_FILE_plus *fp) ++{ ++ IO_set_accept_foreign_vtables (&_IO_vtable_check); ++ _IO_old_file_init_internal (fp); ++} ++ + int + attribute_compat_text_section + _IO_old_file_close_it (fp) +@@ -776,7 +784,7 @@ _IO_old_file_xsputn (f, data, n) + } + + +-const struct _IO_jump_t _IO_old_file_jumps = ++const struct _IO_jump_t _IO_old_file_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_old_file_finish), +diff -rupN a/libio/oldiofdopen.c b/libio/oldiofdopen.c +--- a/libio/oldiofdopen.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/oldiofdopen.c 2017-08-24 15:57:15.823176524 -0400 +@@ -114,7 +114,7 @@ _IO_old_fdopen (fd, mode) + #endif + _IO_old_init (&new_f->fp.file._file, 0); + _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps; +- _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp); ++ _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp); + #if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; + #endif +diff -rupN a/libio/oldiofopen.c b/libio/oldiofopen.c +--- a/libio/oldiofopen.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/oldiofopen.c 2017-08-24 15:58:13.978220676 -0400 +@@ -53,7 +53,7 @@ _IO_old_fopen (filename, mode) + #endif + _IO_old_init (&new_f->fp.file._file, 0); + _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps; +- _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp); ++ _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fp); + #if !_IO_UNIFIED_JUMPTABLES + new_f->fp.vtable = NULL; + #endif +diff -rupN a/libio/oldiopopen.c b/libio/oldiopopen.c +--- a/libio/oldiopopen.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/oldiopopen.c 2017-08-24 15:58:32.060234383 -0400 +@@ -216,7 +216,7 @@ _IO_old_popen (command, mode) + fp = &new_f->fpx.file.file._file; + _IO_old_init (fp, 0); + _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fpx.file) = &_IO_old_proc_jumps; +- _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fpx.file); ++ _IO_old_file_init_internal ((struct _IO_FILE_plus *) &new_f->fpx.file); + #if !_IO_UNIFIED_JUMPTABLES + new_f->fpx.file.vtable = NULL; + #endif +@@ -273,7 +273,7 @@ _IO_old_proc_close (fp) + return wstatus; + } + +-const struct _IO_jump_t _IO_old_proc_jumps = { ++const struct _IO_jump_t _IO_old_proc_jumps libio_vtable = { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_old_file_finish), + JUMP_INIT(overflow, _IO_old_file_overflow), +diff -rupN a/libio/strops.c b/libio/strops.c +--- a/libio/strops.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/strops.c 2017-08-24 14:56:40.289819980 -0400 +@@ -345,7 +345,7 @@ _IO_str_finish (fp, dummy) + _IO_default_finish (fp, 0); + } + +-const struct _IO_jump_t _IO_str_jumps = ++const struct _IO_jump_t _IO_str_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), +diff -rupN a/libio/vsnprintf.c b/libio/vsnprintf.c +--- a/libio/vsnprintf.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/vsnprintf.c 2017-08-24 14:56:40.292819983 -0400 +@@ -66,7 +66,7 @@ _IO_strn_overflow (fp, c) + } + + +-const struct _IO_jump_t _IO_strn_jumps attribute_hidden = ++const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), +diff -rupN a/libio/vswprintf.c b/libio/vswprintf.c +--- a/libio/vswprintf.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/vswprintf.c 2017-08-24 14:56:40.296819988 -0400 +@@ -65,7 +65,7 @@ _IO_wstrn_overflow (fp, c) + } + + +-const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden = ++const struct _IO_jump_t _IO_wstrn_jumps libio_vtable attribute_hidden = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), +diff -rupN a/libio/vtables.c b/libio/vtables.c +--- a/libio/vtables.c 1969-12-31 19:00:00.000000000 -0500 ++++ b/libio/vtables.c 2017-08-24 14:56:40.299819991 -0400 +@@ -0,0 +1,70 @@ ++/* libio vtable validation. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#ifdef SHARED ++ ++void (*IO_accept_foreign_vtables) (void) attribute_hidden; ++ ++/* Used to detected multiple libcs. */ ++extern struct dl_open_hook *_dl_open_hook; ++libc_hidden_proto (_dl_open_hook); ++ ++#else /* !SHARED */ ++ ++/* Used to check whether static dlopen support is needed. */ ++# pragma weak __dlopen ++ ++#endif ++ ++void attribute_hidden ++_IO_vtable_check (void) ++{ ++#ifdef SHARED ++ /* Honor the compatibility flag. */ ++ void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables); ++ PTR_DEMANGLE (flag); ++ if (flag == &_IO_vtable_check) ++ return; ++ ++ /* In case this libc copy is in a non-default namespace, we always ++ need to accept foreign vtables because there is always a ++ possibility that FILE * objects are passed across the linking ++ boundary. */ ++ { ++ Dl_info di; ++ struct link_map *l; ++ if (_dl_open_hook != NULL ++ || (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0 ++ && l->l_ns != LM_ID_BASE)) ++ return; ++ } ++ ++#else /* !SHARED */ ++ /* We cannot perform vtable validation in the static dlopen case ++ because FILE * handles might be passed back and forth across the ++ boundary. Therefore, we disable checking in this case. */ ++ if (__dlopen != NULL) ++ return; ++#endif ++ ++ __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n"); ++} +diff -rupN a/libio/wfileops.c b/libio/wfileops.c +--- a/libio/wfileops.c 2017-08-24 14:50:25.000000000 -0400 ++++ b/libio/wfileops.c 2017-08-24 14:56:40.303819995 -0400 +@@ -1035,7 +1035,7 @@ _IO_wfile_xsputn (f, data, n) + libc_hidden_def (_IO_wfile_xsputn) + + +-const struct _IO_jump_t _IO_wfile_jumps = ++const struct _IO_jump_t _IO_wfile_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), +@@ -1061,7 +1061,7 @@ const struct _IO_jump_t _IO_wfile_jumps + libc_hidden_data_def (_IO_wfile_jumps) + + +-const struct _IO_jump_t _IO_wfile_jumps_mmap = ++const struct _IO_jump_t _IO_wfile_jumps_mmap libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), +@@ -1085,7 +1085,7 @@ const struct _IO_jump_t _IO_wfile_jumps_ + JUMP_INIT(imbue, _IO_default_imbue) + }; + +-const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap = ++const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_new_file_finish), +diff -rupN a/libio/wmemstream.c b/libio/wmemstream.c +--- a/libio/wmemstream.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/libio/wmemstream.c 2017-08-24 14:56:40.307819999 -0400 +@@ -34,7 +34,7 @@ static int _IO_wmem_sync (_IO_FILE* fp) + static void _IO_wmem_finish (_IO_FILE* fp, int) __THROW; + + +-static const struct _IO_jump_t _IO_wmem_jumps = ++static const struct _IO_jump_t _IO_wmem_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_wmem_finish), +diff -rupN a/libio/wstrops.c b/libio/wstrops.c +--- a/libio/wstrops.c 2017-08-24 14:50:23.000000000 -0400 ++++ b/libio/wstrops.c 2017-08-24 14:56:40.310820002 -0400 +@@ -347,7 +347,7 @@ _IO_wstr_finish (fp, dummy) + _IO_wdefault_finish (fp, 0); + } + +-const struct _IO_jump_t _IO_wstr_jumps = ++const struct _IO_jump_t _IO_wstr_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_wstr_finish), +diff -rupN a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c +--- a/stdio-common/vfprintf.c 2017-08-24 14:50:20.000000000 -0400 ++++ b/stdio-common/vfprintf.c 2017-08-24 14:56:40.314820007 -0400 +@@ -2234,7 +2234,7 @@ _IO_helper_overflow (_IO_FILE *s, int c) + } + + #ifdef COMPILE_WPRINTF +-static const struct _IO_jump_t _IO_helper_jumps = ++static const struct _IO_jump_t _IO_helper_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_wdefault_finish), +@@ -2256,7 +2256,7 @@ static const struct _IO_jump_t _IO_helpe + JUMP_INIT (stat, _IO_default_stat) + }; + #else +-static const struct _IO_jump_t _IO_helper_jumps = ++static const struct _IO_jump_t _IO_helper_jumps libio_vtable = + { + JUMP_INIT_DUMMY, + JUMP_INIT (finish, _IO_default_finish), +diff -rupN a/stdlib/strfmon_l.c b/stdlib/strfmon_l.c +--- a/stdlib/strfmon_l.c 2012-12-24 22:02:13.000000000 -0500 ++++ b/stdlib/strfmon_l.c 2017-08-24 14:56:40.314820007 -0400 +@@ -515,7 +515,7 @@ __vstrfmon_l (char *s, size_t maxsize, _ + #ifdef _IO_MTSAFE_IO + f._sbf._f._lock = NULL; + #endif +- _IO_init (&f._sbf._f, 0); ++ _IO_init_internal (&f._sbf._f, 0); + _IO_JUMPS (&f._sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (&f, dest, (s + maxsize) - dest, dest); + /* We clear the last available byte so we can find out whether diff --git a/SOURCES/glibc-rh1404435.patch b/SOURCES/glibc-rh1404435.patch new file mode 100644 index 00000000..f05f9c7b --- /dev/null +++ b/SOURCES/glibc-rh1404435.patch @@ -0,0 +1,37 @@ +Remove the "power8" AT_PLATFORM directory + +Index: b/releng/glibc_post_upgrade.c +=================================================================== +--- a/releng/glibc_post_upgrade.c ++++ b/releng/glibc_post_upgrade.c +@@ -73,14 +73,23 @@ main (void) + int i, j, fd; + off_t base; + ssize_t ret; ++ const char *remove_dirs[] = { + #ifdef __i386__ +- const char *remove_dirs[] = { "/lib/tls", "/lib/i686", "/lib/tls/i486", "/lib/tls/i586", "/lib/tls/i686" }; +-#else +-#ifndef LIBTLS +-#define LIBTLS "/lib/tls" +-#endif +- const char *remove_dirs[] = { LIBTLS }; +-#endif ++ "/lib/tls", "/lib/i686", "/lib/tls/i486", "/lib/tls/i586", "/lib/tls/i686" ++#else /* !__i386__ */ ++# ifndef LIBTLS ++# define LIBTLS "/lib/tls" ++# endif ++# if defined (__powerpc64__) ++ /* Covers both big endian and little endian. */ ++ "/lib64/power8", ++# elif defined (__powerpc__) ++ /* Covers 32-bit only (because of the previous conditional). */ ++ "/lib/power8", ++# endif ++ LIBTLS ++#endif /* !__i386__ */ ++ }; + for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j) + { + size_t rmlen = strlen (remove_dirs[j]); diff --git a/SOURCES/glibc-rh1409611.patch b/SOURCES/glibc-rh1409611.patch new file mode 100644 index 00000000..fd456ddf --- /dev/null +++ b/SOURCES/glibc-rh1409611.patch @@ -0,0 +1,3262 @@ +Partial backports of: +===================== + +commit c5d5d574cbfa96d0f6c1db24d1e072c472627e41 +Author: Ondřej Bílka +Date: Thu Oct 17 16:03:24 2013 +0200 + + Format floating routines. + +commit da08f647d58d674db08cdb3e61c8826c89470e2e +Author: Siddhesh Poyarekar +Date: Fri Dec 21 09:15:10 2012 +0530 + + Move more constants into static variables + + Code cleanup. + +commit f93a8d15699ee699282465dc1e03e033f3fabb52 +Author: Siddhesh Poyarekar +Date: Wed Jan 16 16:06:48 2013 +0530 + + Consolidate constant defines into mpa.h + +commit caa99d06e7f1403887294442af520b0f8c6f3de0 +Author: Siddhesh Poyarekar +Date: Fri Jan 18 11:18:13 2013 +0530 + + Simplify calculation of 2^-m in __mpexp + +commit 107a5bf085f5c4ef8c28266a34d476724cfc3475 +Author: Joseph Myers +Date: Tue Nov 18 15:40:56 2014 +0000 + + Fix libm mpone, mptwo namespace (bug 17616). + +To provided __mptwo for __inv. + +Full backports of the following: +================================ + +commit 44e0d4c20ce5bf3825897e5d4b7caae94016214d +Author: Siddhesh Poyarekar +Date: Wed Jan 2 11:44:13 2013 +0530 + + Split mantissa calculation loop and add branch prediction + +commit f8af25d218202ff2f5d167b8e44e4b79f91d147f +Author: Siddhesh Poyarekar +Date: Fri Jan 4 15:09:33 2013 +0530 + + Remove commented declarations + +commit a9e48ab40e230c7fe34e4892bec8af4f3f975a20 +Author: Siddhesh Poyarekar +Date: Fri Jan 4 15:42:09 2013 +0530 + + Clean up comment for MP_NO + +commit fffb407f4668b40b3df1eb8ee3ae3bc64ee79e20 +Author: Siddhesh Poyarekar +Date: Fri Jan 4 22:52:12 2013 +0530 + + Remove unused __cr and __cpymn + +commit 950c99ca9094e7dc6394e90395f51e12093393aa +Author: Siddhesh Poyarekar +Date: Wed Jan 9 19:07:15 2013 +0530 + + Update comments in mpa.c + + Fixed comment style and clearer wording in some cases. + +commit 1066a53440d2744566e97c59bcd0d422186b3e90 +Author: Siddhesh Poyarekar +Date: Mon Jan 14 21:31:25 2013 +0530 + + Fix code formatting in mpa.c + + This includes the overridden mpa.c in power4. + +commit 2a91b5735ac1bc65ce5c2a3646d75ba7208e26e9 +Author: Siddhesh Poyarekar +Date: Mon Jan 14 21:36:58 2013 +0530 + + Minor tweak to mp multiplication + + Add a local variable to remove extra copies to/from memory in the Z + array. + +ommit 45f058844c33f670475bd02f266942746bcb332b +Author: Siddhesh Poyarekar +Date: Tue Feb 26 21:28:16 2013 +0530 + + Another tweak to the multiplication algorithm + + Reduce the formula to calculate mantissa so that we reduce the net + number of multiplications performed. + +commit bab8a695ee79a5a6e9b2b699938952b006fcbbec +Author: Siddhesh Poyarekar +Date: Thu Feb 21 14:29:18 2013 +0530 + + Fix whitespace differences between generic and powerpc mpa.c + + +commit 2d0e0f29f85036d1189231cb7c1f19f27ba14a89 +Author: Siddhesh Poyarekar +Date: Fri Feb 15 23:56:20 2013 +0530 + + Fix determination of lower precision in __mul + +commit 909279a5cfa938c989c9b01c8f48a0276291ec45 +Author: Siddhesh Poyarekar +Date: Wed Feb 13 14:16:23 2013 +0530 + + Optimized mp multiplication + + Don't bother multiplying zeroes since that only wastes cycles. + +commit bdf028142eb77d6ae59500db875068fa5d7b059d +Author: Siddhesh Poyarekar +Date: Wed Feb 13 13:55:29 2013 +0530 + + Clean up add_magnitudes and sub_magnitudes + +commit d6752ccd696c71d23cd3df8fb9cc60b61c32e65a +Author: Siddhesh Poyarekar +Date: Thu Feb 14 10:31:09 2013 +0530 + + New __sqr function as a faster special case of __mul + +commit 4709fe7602b56e9f6ee1ab6afb4067409a784f29 +Author: Siddhesh Poyarekar +Date: Sat Feb 16 00:09:29 2013 +0530 + + Use intermediate variable to compute exponent in __mul + +commit 20cd7fb3ae63795ae7c9a464abf5ed19b364ade0 +Author: Siddhesh Poyarekar +Date: Wed Feb 20 18:56:20 2013 +0530 + + Copy comment about inner loop from powerpc mpa.c to the default one + +commit e69804d14e43f14c3c65dc570afdbfb822c9838b +Author: Siddhesh Poyarekar +Date: Mon Feb 25 16:43:02 2013 +0530 + + Use long wherever possible in mpa.c + + Using long throughout like powerpc does is beneficial since it reduces + the need to switch to 32-bit instructions. It gives a very minor + performance improvement. + +commit 82a9811d29c00161c7c8ea7f70e2cc30988e192e +Author: Siddhesh Poyarekar +Date: Thu Mar 7 12:23:29 2013 +0530 + + Use generic mpa.c code for everything except __mul and __sqr + +commit 6f2e90e78f151bab153c2b38492505ae2012db06 +Author: Siddhesh Poyarekar +Date: Tue Mar 26 19:28:50 2013 +0530 + + Make mantissa type of mp_no configurable + + The mantissa of mp_no is intended to take only integral values. This + is a relatively good choice for powerpc due to its 4 fpus, but not for + other architectures, which suffer due to this choice. This change + makes the default mantissa a long integer and allows powerpc to + override it. Additionally, some operations have been optimized for + integer manipulation, resulting in a significant improvement in + performance. + +commit 5739f705eed5cf58e7b439e5983542e06d7fc2da +Author: Siddhesh Poyarekar +Date: Tue Mar 26 20:24:04 2013 +0530 + + Use integral constants + + The compiler is smart enough to convert those into double for powerpc, + but if we put them as doubles, it adds overhead by performing those + operations in floating point mode. + +commit 89f3b6e18c6e7833438789746fcfc2e7189f7cac +Author: Joseph Myers +Date: Thu May 21 23:05:45 2015 +0000 + + Fix sysdeps/ieee754/dbl-64/mpa.c for -Wuninitialized. + + If you remove the "override CFLAGS += -Wno-uninitialized" in + math/Makefile, one of the errors you get is: + + ../sysdeps/ieee754/dbl-64/mpa.c: In function '__mp_dbl.part.0': + ../sysdeps/ieee754/dbl-64/mpa.c:183:5: error: 'c' may be used uninitialized in this function [-Werror=maybe-uninitialized] + c *= X[0]; + + The problem is that the p < 5 case initializes c if p is 1, 2, 3 or 4 + but not otherwise, and in fact p is positive for all calls to this + function so the uninitialized case can't actually occur. This patch + replaces the "if (p == 4)" last case with a comment so the compiler + can see that all paths do initialize c. + + Tested for x86_64. + + * sysdeps/ieee754/dbl-64/mpa.c (norm): Remove if condition on + (p == 4) case. + +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpa.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa.c +@@ -1,7 +1,7 @@ + /* + * IBM Accurate Mathematical Library + * written by International Business Machines Corp. +- * Copyright (C) 2001, 2011 Free Software Foundation ++ * Copyright (C) 2001-2017 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by +@@ -22,9 +22,7 @@ + /* FUNCTIONS: */ + /* mcr */ + /* acr */ +-/* cr */ + /* cpy */ +-/* cpymn */ + /* norm */ + /* denorm */ + /* mp_dbl */ +@@ -44,479 +42,868 @@ + + #include "endian.h" + #include "mpa.h" +-#include "mpa2.h" +-#include /* For MIN() */ ++#include ++#include + + #ifndef SECTION + # define SECTION + #endif + ++#ifndef NO__CONST ++/* TODO: With only a partial backport of the constant cleanup from ++ upstream we limit the definition of these two constants to ++ this file. */ ++static const mp_no __mpone = { 1, { 1.0, 1.0 } }; ++static const mp_no __mptwo = { 1, { 1.0, 2.0 } }; ++#endif ++ + #ifndef NO___ACR +-/* mcr() compares the sizes of the mantissas of two multiple precision */ +-/* numbers. Mantissas are compared regardless of the signs of the */ +-/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */ +-/* disregarded. */ ++/* Compare mantissa of two multiple precision numbers regardless of the sign ++ and exponent of the numbers. */ + static int +-mcr(const mp_no *x, const mp_no *y, int p) { +- int i; +- for (i=1; i<=p; i++) { +- if (X[i] == Y[i]) continue; +- else if (X[i] > Y[i]) return 1; +- else return -1; } ++mcr (const mp_no *x, const mp_no *y, int p) ++{ ++ long i; ++ long p2 = p; ++ for (i = 1; i <= p2; i++) ++ { ++ if (X[i] == Y[i]) ++ continue; ++ else if (X[i] > Y[i]) ++ return 1; ++ else ++ return -1; ++ } + return 0; + } + +- +-/* acr() compares the absolute values of two multiple precision numbers */ ++/* Compare the absolute values of two multiple precision numbers. */ + int +-__acr(const mp_no *x, const mp_no *y, int p) { +- int i; +- +- if (X[0] == ZERO) { +- if (Y[0] == ZERO) i= 0; +- else i=-1; +- } +- else if (Y[0] == ZERO) i= 1; +- else { +- if (EX > EY) i= 1; +- else if (EX < EY) i=-1; +- else i= mcr(x,y,p); +- } +- +- return i; +-} +-#endif +- ++__acr (const mp_no *x, const mp_no *y, int p) ++{ ++ long i; + +-#if 0 +-/* cr() compares the values of two multiple precision numbers */ +-static int __cr(const mp_no *x, const mp_no *y, int p) { +- int i; +- +- if (X[0] > Y[0]) i= 1; +- else if (X[0] < Y[0]) i=-1; +- else if (X[0] < ZERO ) i= __acr(y,x,p); +- else i= __acr(x,y,p); ++ if (X[0] == 0) ++ { ++ if (Y[0] == 0) ++ i = 0; ++ else ++ i = -1; ++ } ++ else if (Y[0] == 0) ++ i = 1; ++ else ++ { ++ if (EX > EY) ++ i = 1; ++ else if (EX < EY) ++ i = -1; ++ else ++ i = mcr (x, y, p); ++ } + + return i; + } + #endif + +- + #ifndef NO___CPY +-/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */ +-void __cpy(const mp_no *x, mp_no *y, int p) { ++/* Copy multiple precision number X into Y. They could be the same ++ number. */ ++void ++__cpy (const mp_no *x, mp_no *y, int p) ++{ ++ long i; ++ + EY = EX; +- for (int i=0; i <= p; i++) Y[i] = X[i]; ++ for (i = 0; i <= p; i++) ++ Y[i] = X[i]; + } + #endif + ++#ifndef NO___MP_DBL ++/* Convert a multiple precision number *X into a double precision ++ number *Y, normalized case (|x| >= 2**(-1022))). X has precision ++ P, which is positive. */ ++static void ++norm (const mp_no *x, double *y, int p) ++{ ++# define R RADIXI ++ long i; ++ double c; ++ mantissa_t a, u, v, z[5]; ++ if (p < 5) ++ { ++ if (p == 1) ++ c = X[1]; ++ else if (p == 2) ++ c = X[1] + R * X[2]; ++ else if (p == 3) ++ c = X[1] + R * (X[2] + R * X[3]); ++ else /* p == 4. */ ++ c = (X[1] + R * X[2]) + R * R * (X[3] + R * X[4]); ++ } ++ else ++ { ++ for (a = 1, z[1] = X[1]; z[1] < TWO23; ) ++ { ++ a *= 2; ++ z[1] *= 2; ++ } + +-#if 0 +-/* Copy a multiple precision number x of precision m into a */ +-/* multiple precision number y of precision n. In case n>m, */ +-/* the digits of y beyond the m'th are set to zero. In case */ +-/* n= 2**(-1022))) */ +-static void norm(const mp_no *x, double *y, int p) +-{ +- #define R radixi.d +- int i; +-#if 0 +- int k; +-#endif +- double a,c,u,v,z[5]; +- if (p<5) { +- if (p==1) c = X[1]; +- else if (p==2) c = X[1] + R* X[2]; +- else if (p==3) c = X[1] + R*(X[2] + R* X[3]); +- else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]); +- } +- else { +- for (a=ONE, z[1]=X[1]; z[1] < TWO23; ) +- {a *= TWO; z[1] *= TWO; } +- +- for (i=2; i<5; i++) { +- z[i] = X[i]*a; +- u = (z[i] + CUTTER)-CUTTER; +- if (u > z[i]) u -= RADIX; +- z[i] -= u; +- z[i-1] += u*RADIXI; +- } +- +- u = (z[3] + TWO71) - TWO71; +- if (u > z[3]) u -= TWO19; +- v = z[3]-u; +- +- if (v == TWO18) { +- if (z[4] == ZERO) { +- for (i=5; i <= p; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } ++ if (v == TWO18) ++ { ++ if (z[4] == 0) ++ { ++ for (i = 5; i <= p; i++) ++ { ++ if (X[i] == 0) ++ continue; ++ else ++ { ++ z[3] += 1; ++ break; ++ } ++ } ++ } ++ else ++ z[3] += 1; + } +- } +- else z[3] += ONE; +- } + +- c = (z[1] + R *(z[2] + R * z[3]))/a; +- } ++ c = (z[1] + R * (z[2] + R * z[3])) / a; ++ } + + c *= X[0]; + +- for (i=1; iEX; i--) c *= RADIXI; ++ for (i = 1; i < EX; i++) ++ c *= RADIX; ++ for (i = 1; i > EX; i--) ++ c *= RADIXI; + + *y = c; +-#undef R ++# undef R + } + +-/* Convert a multiple precision number *x into a double precision */ +-/* number *y, denormalized case (|x| < 2**(-1022))) */ +-static void denorm(const mp_no *x, double *y, int p) ++/* Convert a multiple precision number *X into a double precision ++ number *Y, Denormal case (|x| < 2**(-1022))). */ ++static void ++denorm (const mp_no *x, double *y, int p) + { +- int i,k; +- double c,u,z[5]; +-#if 0 +- double a,v; +-#endif ++ long i, k; ++ long p2 = p; ++ double c; ++ mantissa_t u, z[5]; ++ ++# define R RADIXI ++ if (EX < -44 || (EX == -44 && X[1] < TWO5)) ++ { ++ *y = 0; ++ return; ++ } + +-#define R radixi.d +- if (EX<-44 || (EX==-44 && X[1] z[3]) u -= TWO5; +- +- if (u==z[3]) { +- for (i=k+1; i <= p; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } +- } +- } +- +- c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10); +- +- *y = c*TWOM1032; +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision number *y. */ +-/* The result is correctly rounded to the nearest/even. *x is left unchanged */ +- +-void __mp_dbl(const mp_no *x, double *y, int p) { +-#if 0 +- int i,k; +- double a,c,u,v,z[5]; +-#endif ++ if (p2 == 1) ++ { ++ if (EX == -42) ++ { ++ z[1] = X[1] + TWO10; ++ z[2] = 0; ++ z[3] = 0; ++ k = 3; ++ } ++ else if (EX == -43) ++ { ++ z[1] = TWO10; ++ z[2] = X[1]; ++ z[3] = 0; ++ k = 2; ++ } ++ else ++ { ++ z[1] = TWO10; ++ z[2] = 0; ++ z[3] = X[1]; ++ k = 1; ++ } ++ } ++ else if (p2 == 2) ++ { ++ if (EX == -42) ++ { ++ z[1] = X[1] + TWO10; ++ z[2] = X[2]; ++ z[3] = 0; ++ k = 3; ++ } ++ else if (EX == -43) ++ { ++ z[1] = TWO10; ++ z[2] = X[1]; ++ z[3] = X[2]; ++ k = 2; ++ } ++ else ++ { ++ z[1] = TWO10; ++ z[2] = 0; ++ z[3] = X[1]; ++ k = 1; ++ } ++ } ++ else ++ { ++ if (EX == -42) ++ { ++ z[1] = X[1] + TWO10; ++ z[2] = X[2]; ++ k = 3; ++ } ++ else if (EX == -43) ++ { ++ z[1] = TWO10; ++ z[2] = X[1]; ++ k = 2; ++ } ++ else ++ { ++ z[1] = TWO10; ++ z[2] = 0; ++ k = 1; ++ } ++ z[3] = X[k]; ++ } + +- if (X[0] == ZERO) {*y = ZERO; return; } ++ u = ALIGN_DOWN_TO (z[3], TWO5); + +- if (EX> -42) norm(x,y,p); +- else if (EX==-42 && X[1]>=TWO10) norm(x,y,p); +- else denorm(x,y,p); ++ if (u == z[3]) ++ { ++ for (i = k + 1; i <= p2; i++) ++ { ++ if (X[i] == 0) ++ continue; ++ else ++ { ++ z[3] += 1; ++ break; ++ } ++ } ++ } ++ ++ c = X[0] * ((z[1] + R * (z[2] + R * z[3])) - TWO10); ++ ++ *y = c * TWOM1032; ++# undef R + } +-#endif + ++/* Convert multiple precision number *X into double precision number *Y. The ++ result is correctly rounded to the nearest/even. */ ++void ++__mp_dbl (const mp_no *x, double *y, int p) ++{ ++ if (X[0] == 0) ++ { ++ *y = 0; ++ return; ++ } + +-/* dbl_mp() converts a double precision number x into a multiple precision */ +-/* number *y. If the precision p is too small the result is truncated. x is */ +-/* left unchanged. */ ++ if (__glibc_likely (EX > -42 || (EX == -42 && X[1] >= TWO10))) ++ norm (x, y, p); ++ else ++ denorm (x, y, p); ++} ++#endif + ++/* Get the multiple precision equivalent of X into *Y. If the precision is too ++ small, the result is truncated. */ + void + SECTION +-__dbl_mp(double x, mp_no *y, int p) { ++__dbl_mp (double x, mp_no *y, int p) ++{ ++ long i, n; ++ long p2 = p; + +- int i,n; +- double u; ++ /* Sign. */ ++ if (x == 0) ++ { ++ Y[0] = 0; ++ return; ++ } ++ else if (x > 0) ++ Y[0] = 1; ++ else ++ { ++ Y[0] = -1; ++ x = -x; ++ } + +- /* Sign */ +- if (x == ZERO) {Y[0] = ZERO; return; } +- else if (x > ZERO) Y[0] = ONE; +- else {Y[0] = MONE; x=-x; } +- +- /* Exponent */ +- for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI; +- for ( ; x < ONE; EY -= ONE) x *= RADIX; +- +- /* Digits */ +- n=MIN(p,4); +- for (i=1; i<=n; i++) { +- u = (x + TWO52) - TWO52; +- if (u>x) u -= ONE; +- Y[i] = u; x -= u; x *= RADIX; } +- for ( ; i<=p; i++) Y[i] = ZERO; ++ /* Exponent. */ ++ for (EY = 1; x >= RADIX; EY += 1) ++ x *= RADIXI; ++ for (; x < 1; EY -= 1) ++ x *= RADIX; ++ ++ /* Digits. */ ++ n = MIN (p2, 4); ++ for (i = 1; i <= n; i++) ++ { ++ INTEGER_OF (x, Y[i]); ++ x *= RADIX; ++ } ++ for (; i <= p2; i++) ++ Y[i] = 0; + } + +- +-/* add_magnitudes() adds the magnitudes of *x & *y assuming that */ +-/* abs(*x) >= abs(*y) > 0. */ +-/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */ +-/* No guard digit is used. The result equals the exact sum, truncated. */ +-/* *x & *y are left unchanged. */ +- ++/* Add magnitudes of *X and *Y assuming that abs (*X) >= abs (*Y) > 0. The ++ sign of the sum *Z is not changed. X and Y may overlap but not X and Z or ++ Y and Z. No guard digit is used. The result equals the exact sum, ++ truncated. */ + static void + SECTION +-add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int i,j,k; ++add_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p) ++{ ++ long i, j, k; ++ long p2 = p; ++ mantissa_t zk; + + EZ = EX; + +- i=p; j=p+ EY - EX; k=p+1; ++ i = p2; ++ j = p2 + EY - EX; ++ k = p2 + 1; ++ ++ if (__glibc_unlikely (j < 1)) ++ { ++ __cpy (x, z, p); ++ return; ++ } + +- if (j<1) +- {__cpy(x,z,p); return; } +- else Z[k] = ZERO; +- +- for (; j>0; i--,j--) { +- Z[k] += X[i] + Y[j]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- if (Z[1] == ZERO) { +- for (i=1; i<=p; i++) Z[i] = Z[i+1]; } +- else EZ += ONE; +-} ++ zk = 0; + ++ for (; j > 0; i--, j--) ++ { ++ zk += X[i] + Y[j]; ++ if (zk >= RADIX) ++ { ++ Z[k--] = zk - RADIX; ++ zk = 1; ++ } ++ else ++ { ++ Z[k--] = zk; ++ zk = 0; ++ } ++ } + +-/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */ +-/* abs(*x) > abs(*y) > 0. */ +-/* The sign of the difference *z is undefined. x&y may overlap but not x&z */ +-/* or y&z. One guard digit is used. The error is less than one ulp. */ +-/* *x & *y are left unchanged. */ ++ for (; i > 0; i--) ++ { ++ zk += X[i]; ++ if (zk >= RADIX) ++ { ++ Z[k--] = zk - RADIX; ++ zk = 1; ++ } ++ else ++ { ++ Z[k--] = zk; ++ zk = 0; ++ } ++ } + ++ if (zk == 0) ++ { ++ for (i = 1; i <= p2; i++) ++ Z[i] = Z[i + 1]; ++ } ++ else ++ { ++ Z[1] = zk; ++ EZ += 1; ++ } ++} ++ ++/* Subtract the magnitudes of *X and *Y assuming that abs (*x) > abs (*y) > 0. ++ The sign of the difference *Z is not changed. X and Y may overlap but not X ++ and Z or Y and Z. One guard digit is used. The error is less than one ++ ULP. */ + static void + SECTION +-sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int i,j,k; ++sub_magnitudes (const mp_no *x, const mp_no *y, mp_no *z, int p) ++{ ++ long i, j, k; ++ long p2 = p; ++ mantissa_t zk; + + EZ = EX; ++ i = p2; ++ j = p2 + EY - EX; ++ k = p2; ++ ++ /* Y is too small compared to X, copy X over to the result. */ ++ if (__glibc_unlikely (j < 1)) ++ { ++ __cpy (x, z, p); ++ return; ++ } ++ ++ /* The relevant least significant digit in Y is non-zero, so we factor it in ++ to enhance accuracy. */ ++ if (j < p2 && Y[j + 1] > 0) ++ { ++ Z[k + 1] = RADIX - Y[j + 1]; ++ zk = -1; ++ } ++ else ++ zk = Z[k + 1] = 0; + +- if (EX == EY) { +- i=j=k=p; +- Z[k] = Z[k+1] = ZERO; } +- else { +- j= EX - EY; +- if (j > p) {__cpy(x,z,p); return; } +- else { +- i=p; j=p+1-j; k=p; +- if (Y[j] > ZERO) { +- Z[k+1] = RADIX - Y[j--]; +- Z[k] = MONE; } +- else { +- Z[k+1] = ZERO; +- Z[k] = ZERO; j--;} +- } +- } +- +- for (; j>0; i--,j--) { +- Z[k] += (X[i] - Y[j]); +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } ++ /* Subtract and borrow. */ ++ for (; j > 0; i--, j--) ++ { ++ zk += (X[i] - Y[j]); ++ if (zk < 0) ++ { ++ Z[k--] = zk + RADIX; ++ zk = -1; ++ } ++ else ++ { ++ Z[k--] = zk; ++ zk = 0; ++ } ++ } + +- for (i=1; Z[i] == ZERO; i++) ; ++ /* We're done with digits from Y, so it's just digits in X. */ ++ for (; i > 0; i--) ++ { ++ zk += X[i]; ++ if (zk < 0) ++ { ++ Z[k--] = zk + RADIX; ++ zk = -1; ++ } ++ else ++ { ++ Z[k--] = zk; ++ zk = 0; ++ } ++ } ++ ++ /* Normalize. */ ++ for (i = 1; Z[i] == 0; i++) ++ ; + EZ = EZ - i + 1; +- for (k=1; i <= p+1; ) ++ for (k = 1; i <= p2 + 1; ) + Z[k++] = Z[i++]; +- for (; k <= p; ) +- Z[k++] = ZERO; ++ for (; k <= p2; ) ++ Z[k++] = 0; + } + +- +-/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */ +-/* but not x&z or y&z. One guard digit is used. The error is less than */ +-/* one ulp. *x & *y are left unchanged. */ +- ++/* Add *X and *Y and store the result in *Z. X and Y may overlap, but not X ++ and Z or Y and Z. One guard digit is used. The error is less than one ++ ULP. */ + void + SECTION +-__add(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- ++__add (const mp_no *x, const mp_no *y, mp_no *z, int p) ++{ + int n; + +- if (X[0] == ZERO) {__cpy(y,z,p); return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } ++ if (X[0] == 0) ++ { ++ __cpy (y, z, p); ++ return; ++ } ++ else if (Y[0] == 0) ++ { ++ __cpy (x, z, p); ++ return; ++ } + +- if (X[0] == Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- else Z[0] = ZERO; +- } ++ if (X[0] == Y[0]) ++ { ++ if (__acr (x, y, p) > 0) ++ { ++ add_magnitudes (x, y, z, p); ++ Z[0] = X[0]; ++ } ++ else ++ { ++ add_magnitudes (y, x, z, p); ++ Z[0] = Y[0]; ++ } ++ } ++ else ++ { ++ if ((n = __acr (x, y, p)) == 1) ++ { ++ sub_magnitudes (x, y, z, p); ++ Z[0] = X[0]; ++ } ++ else if (n == -1) ++ { ++ sub_magnitudes (y, x, z, p); ++ Z[0] = Y[0]; ++ } ++ else ++ Z[0] = 0; ++ } + } + ++/* Subtract *Y from *X and return the result in *Z. X and Y may overlap but ++ not X and Z or Y and Z. One guard digit is used. The error is less than ++ one ULP. */ ++void ++SECTION ++__sub (const mp_no *x, const mp_no *y, mp_no *z, int p) ++{ ++ int n; ++ ++ if (X[0] == 0) ++ { ++ __cpy (y, z, p); ++ Z[0] = -Z[0]; ++ return; ++ } ++ else if (Y[0] == 0) ++ { ++ __cpy (x, z, p); ++ return; ++ } + +-/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */ +-/* overlap but not x&z or y&z. One guard digit is used. The error is */ +-/* less than one ulp. *x & *y are left unchanged. */ ++ if (X[0] != Y[0]) ++ { ++ if (__acr (x, y, p) > 0) ++ { ++ add_magnitudes (x, y, z, p); ++ Z[0] = X[0]; ++ } ++ else ++ { ++ add_magnitudes (y, x, z, p); ++ Z[0] = -Y[0]; ++ } ++ } ++ else ++ { ++ if ((n = __acr (x, y, p)) == 1) ++ { ++ sub_magnitudes (x, y, z, p); ++ Z[0] = X[0]; ++ } ++ else if (n == -1) ++ { ++ sub_magnitudes (y, x, z, p); ++ Z[0] = -Y[0]; ++ } ++ else ++ Z[0] = 0; ++ } ++} + ++#ifndef NO__MUL ++/* Multiply *X and *Y and store result in *Z. X and Y may overlap but not X ++ and Z or Y and Z. For P in [1, 2, 3], the exact result is truncated to P ++ digits. In case P > 3 the error is bounded by 1.001 ULP. */ + void + SECTION +-__sub(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++__mul (const mp_no *x, const mp_no *y, mp_no *z, int p) ++{ ++ long i, j, k, ip, ip2; ++ long p2 = p; ++ mantissa_store_t zk; ++ const mp_no *a; ++ mantissa_store_t *diag; ++ ++ /* Is z=0? */ ++ if (__glibc_unlikely (X[0] * Y[0] == 0)) ++ { ++ Z[0] = 0; ++ return; ++ } + +- int n; ++ /* We need not iterate through all X's and Y's since it's pointless to ++ multiply zeroes. Here, both are zero... */ ++ for (ip2 = p2; ip2 > 0; ip2--) ++ if (X[ip2] != 0 || Y[ip2] != 0) ++ break; ++ ++ a = X[ip2] != 0 ? y : x; ++ ++ /* ... and here, at least one of them is still zero. */ ++ for (ip = ip2; ip > 0; ip--) ++ if (a->d[ip] != 0) ++ break; ++ ++ /* The product looks like this for p = 3 (as an example): ++ ++ ++ a1 a2 a3 ++ x b1 b2 b3 ++ ----------------------------- ++ a1*b3 a2*b3 a3*b3 ++ a1*b2 a2*b2 a3*b2 ++ a1*b1 a2*b1 a3*b1 ++ ++ So our K needs to ideally be P*2, but we're limiting ourselves to P + 3 ++ for P >= 3. We compute the above digits in two parts; the last P-1 ++ digits and then the first P digits. The last P-1 digits are a sum of ++ products of the input digits from P to P-k where K is 0 for the least ++ significant digit and increases as we go towards the left. The product ++ term is of the form X[k]*X[P-k] as can be seen in the above example. ++ ++ The first P digits are also a sum of products with the same product term, ++ except that the sum is from 1 to k. This is also evident from the above ++ example. ++ ++ Another thing that becomes evident is that only the most significant ++ ip+ip2 digits of the result are non-zero, where ip and ip2 are the ++ 'internal precision' of the input numbers, i.e. digits after ip and ip2 ++ are all 0. */ ++ ++ k = (__glibc_unlikely (p2 < 3)) ? p2 + p2 : p2 + 3; ++ ++ while (k > ip + ip2 + 1) ++ Z[k--] = 0; ++ ++ zk = 0; ++ ++ /* Precompute sums of diagonal elements so that we can directly use them ++ later. See the next comment to know we why need them. */ ++ diag = alloca (k * sizeof (mantissa_store_t)); ++ mantissa_store_t d = 0; ++ for (i = 1; i <= ip; i++) ++ { ++ d += X[i] * (mantissa_store_t) Y[i]; ++ diag[i] = d; ++ } ++ while (i < k) ++ diag[i++] = d; + +- if (X[0] == ZERO) {__cpy(y,z,p); Z[0] = -Z[0]; return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } ++ while (k > p2) ++ { ++ long lim = k / 2; + +- if (X[0] != Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- else Z[0] = ZERO; +- } +-} ++ if (k % 2 == 0) ++ /* We want to add this only once, but since we subtract it in the sum ++ of products above, we add twice. */ ++ zk += 2 * X[lim] * (mantissa_store_t) Y[lim]; + ++ for (i = k - p2, j = p2; i < j; i++, j--) ++ zk += (X[i] + X[j]) * (mantissa_store_t) (Y[i] + Y[j]); + +-/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */ +-/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */ +-/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */ +-/* *x & *y are left unchanged. */ ++ zk -= diag[k - 1]; + +-void +-SECTION +-__mul(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ DIV_RADIX (zk, Z[k]); ++ k--; ++ } + +- int i, i1, i2, j, k, k2; +- double u; ++ /* The real deal. Mantissa digit Z[k] is the sum of all X[i] * Y[j] where i ++ goes from 1 -> k - 1 and j goes the same range in reverse. To reduce the ++ number of multiplications, we halve the range and if k is an even number, ++ add the diagonal element X[k/2]Y[k/2]. Through the half range, we compute ++ X[i] * Y[j] as (X[i] + X[j]) * (Y[i] + Y[j]) - X[i] * Y[i] - X[j] * Y[j]. ++ ++ This reduction tells us that we're summing two things, the first term ++ through the half range and the negative of the sum of the product of all ++ terms of X and Y in the full range. i.e. ++ ++ SUM(X[i] * Y[i]) for k terms. This is precalculated above for each k in ++ a single loop so that it completes in O(n) time and can hence be directly ++ used in the loop below. */ ++ while (k > 1) ++ { ++ long lim = k / 2; ++ ++ if (k % 2 == 0) ++ /* We want to add this only once, but since we subtract it in the sum ++ of products above, we add twice. */ ++ zk += 2 * X[lim] * (mantissa_store_t) Y[lim]; + +- /* Is z=0? */ +- if (X[0]*Y[0]==ZERO) +- { Z[0]=ZERO; return; } +- +- /* Multiply, add and carry */ +- k2 = (p<3) ? p+p : p+3; +- Z[k2]=ZERO; +- for (k=k2; k>1; ) { +- if (k > p) {i1=k-p; i2=p+1; } +- else {i1=1; i2=k; } +- for (i=i1,j=i2-1; i Z[k]) u -= RADIX; +- Z[k] -= u; +- Z[--k] = u*RADIXI; +- } +- +- /* Is there a carry beyond the most significant digit? */ +- if (Z[1] == ZERO) { +- for (i=1; i<=p; i++) Z[i]=Z[i+1]; +- EZ = EX + EY - 1; } +- else +- EZ = EX + EY; ++ for (i = 1, j = k - 1; i < j; i++, j--) ++ zk += (X[i] + X[j]) * (mantissa_store_t) (Y[i] + Y[j]); ++ ++ zk -= diag[k - 1]; ++ ++ DIV_RADIX (zk, Z[k]); ++ k--; ++ } ++ Z[k] = zk; ++ ++ /* Get the exponent sum into an intermediate variable. This is a subtle ++ optimization, where given enough registers, all operations on the exponent ++ happen in registers and the result is written out only once into EZ. */ ++ int e = EX + EY; ++ ++ /* Is there a carry beyond the most significant digit? */ ++ if (__glibc_unlikely (Z[1] == 0)) ++ { ++ for (i = 1; i <= p2; i++) ++ Z[i] = Z[i + 1]; ++ e--; ++ } + ++ EZ = e; + Z[0] = X[0] * Y[0]; + } ++#endif ++ ++#ifndef NO__SQR ++/* Square *X and store result in *Y. X and Y may not overlap. For P in ++ [1, 2, 3], the exact result is truncated to P digits. In case P > 3 the ++ error is bounded by 1.001 ULP. This is a faster special case of ++ multiplication. */ ++void ++SECTION ++__sqr (const mp_no *x, mp_no *y, int p) ++{ ++ long i, j, k, ip; ++ mantissa_store_t yk; + ++ /* Is z=0? */ ++ if (__glibc_unlikely (X[0] == 0)) ++ { ++ Y[0] = 0; ++ return; ++ } + +-/* Invert a multiple precision number. Set *y = 1 / *x. */ +-/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */ +-/* 2.001*r**(1-p) for p>3. */ +-/* *x=0 is not permissible. *x is left unchanged. */ ++ /* We need not iterate through all X's since it's pointless to ++ multiply zeroes. */ ++ for (ip = p; ip > 0; ip--) ++ if (X[ip] != 0) ++ break; + +-static +-SECTION +-void __inv(const mp_no *x, mp_no *y, int p) { +- int i; +-#if 0 +- int l; ++ k = (__glibc_unlikely (p < 3)) ? p + p : p + 3; ++ ++ while (k > 2 * ip + 1) ++ Y[k--] = 0; ++ ++ yk = 0; ++ ++ while (k > p) ++ { ++ mantissa_store_t yk2 = 0; ++ long lim = k / 2; ++ ++ if (k % 2 == 0) ++ yk += X[lim] * (mantissa_store_t) X[lim]; ++ ++ /* In __mul, this loop (and the one within the next while loop) run ++ between a range to calculate the mantissa as follows: ++ ++ Z[k] = X[k] * Y[n] + X[k+1] * Y[n-1] ... + X[n-1] * Y[k+1] ++ + X[n] * Y[k] ++ ++ For X == Y, we can get away with summing halfway and doubling the ++ result. For cases where the range size is even, the mid-point needs ++ to be added separately (above). */ ++ for (i = k - p, j = p; i < j; i++, j--) ++ yk2 += X[i] * (mantissa_store_t) X[j]; ++ ++ yk += 2 * yk2; ++ ++ DIV_RADIX (yk, Y[k]); ++ k--; ++ } ++ ++ while (k > 1) ++ { ++ mantissa_store_t yk2 = 0; ++ long lim = k / 2; ++ ++ if (k % 2 == 0) ++ yk += X[lim] * (mantissa_store_t) X[lim]; ++ ++ /* Likewise for this loop. */ ++ for (i = 1, j = k - 1; i < j; i++, j--) ++ yk2 += X[i] * (mantissa_store_t) X[j]; ++ ++ yk += 2 * yk2; ++ ++ DIV_RADIX (yk, Y[k]); ++ k--; ++ } ++ Y[k] = yk; ++ ++ /* Squares are always positive. */ ++ Y[0] = 1; ++ ++ /* Get the exponent sum into an intermediate variable. This is a subtle ++ optimization, where given enough registers, all operations on the exponent ++ happen in registers and the result is written out only once into EZ. */ ++ int e = EX * 2; ++ ++ /* Is there a carry beyond the most significant digit? */ ++ if (__glibc_unlikely (Y[1] == 0)) ++ { ++ for (i = 1; i <= p; i++) ++ Y[i] = Y[i + 1]; ++ e--; ++ } ++ ++ EY = e; ++} + #endif ++ ++/* Invert *X and store in *Y. Relative error bound: ++ - For P = 2: 1.001 * R ^ (1 - P) ++ - For P = 3: 1.063 * R ^ (1 - P) ++ - For P > 3: 2.001 * R ^ (1 - P) ++ ++ *X = 0 is not permissible. */ ++static void ++SECTION ++__inv (const mp_no *x, mp_no *y, int p) ++{ ++ long i; + double t; +- mp_no z,w; +- static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3, +- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4}; +- const mp_no mptwo = {1,{1.0,2.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,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.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}}; +- +- __cpy(x,&z,p); z.e=0; __mp_dbl(&z,&t,p); +- t=ONE/t; __dbl_mp(t,y,p); EY -= EX; +- +- for (i=0; i 3: 3.001 * R ^ (1 - P) + +-/* Divide one multiple precision number by another.Set *z = *x / *y. *x & *y */ +-/* are left unchanged. x&y may overlap but not x&z or y&z. */ +-/* Relative error bound = 2.001*r**(1-p) for p=2, 2.063*r**(1-p) for p=3 */ +-/* and 3.001*r**(1-p) for p>3. *y=0 is not permissible. */ +- ++ *X = 0 is not permissible. */ + void + SECTION +-__dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- ++__dvd (const mp_no *x, const mp_no *y, mp_no *z, int p) ++{ + mp_no w; + +- if (X[0] == ZERO) Z[0] = ZERO; +- else {__inv(y,&w,p); __mul(x,&w,z,p);} ++ if (X[0] == 0) ++ Z[0] = 0; ++ else ++ { ++ __inv (y, &w, p); ++ __mul (x, &w, z, p); ++ } + } +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpa.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa.h +@@ -1,7 +1,7 @@ + /* + * IBM Accurate Mathematical Library + * Written by International Business Machines Corp. +- * Copyright (C) 2001, 2011 Free Software Foundation, Inc. ++ * Copyright (C) 2001-2017 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by +@@ -23,36 +23,58 @@ + /* FUNCTIONS: */ + /* mcr */ + /* acr */ +-/* cr */ + /* cpy */ +-/* cpymn */ + /* mp_dbl */ + /* dbl_mp */ + /* add */ + /* sub */ + /* mul */ +-/* inv */ + /* dvd */ + /* */ + /* Arithmetic functions for multiple precision numbers. */ + /* Common types and definition */ + /************************************************************************/ + ++#include + +-typedef struct {/* This structure holds the details of a multi-precision */ +- int e; /* floating point number, x: d[0] holds its sign (-1,0 or 1) */ +- double d[40]; /* e holds its exponent (...,-2,-1,0,1,2,...) and */ +-} mp_no; /* d[1]...d[p] hold its mantissa digits. The value of x is, */ +- /* x = d[1]*r**(e-1) + d[2]*r**(e-2) + ... + d[p]*r**(e-p). */ +- /* Here r = 2**24, 0 <= d[i] < r and 1 <= p <= 32. */ +- /* p is a global variable. A multi-precision number is */ +- /* always normalized. Namely, d[1] > 0. An exception is */ +- /* a zero which is characterized by d[0] = 0. The terms */ +- /* d[p+1], d[p+2], ... of a none zero number have no */ +- /* significance and so are the terms e, d[1],d[2],... */ +- /* of a zero. */ ++/* The mp_no structure holds the details of a multi-precision floating point ++ number. + +-typedef union { int i[2]; double d; } number; ++ - The radix of the number (R) is 2 ^ 24. ++ ++ - E: The exponent of the number. ++ ++ - D[0]: The sign (-1, 1) or 0 if the value is 0. In the latter case, the ++ values of the remaining members of the structure are ignored. ++ ++ - D[1] - D[p]: The mantissa of the number where: ++ ++ 0 <= D[i] < R and ++ P is the precision of the number and 1 <= p <= 32 ++ ++ D[p+1] ... D[39] have no significance. ++ ++ - The value of the number is: ++ ++ D[1] * R ^ (E - 1) + D[2] * R ^ (E - 2) ... D[p] * R ^ (E - p) ++ ++ */ ++typedef struct ++{ ++ int e; ++ mantissa_t d[40]; ++} mp_no; ++ ++typedef union ++{ ++ int i[2]; ++ double d; ++} number; ++ ++/* TODO: With only a partial backport of the constant cleanup we don't ++ define __mpone or __mptwo here for other code to use. */ ++/* extern const mp_no __mpone; ++extern const mp_no __mptwo; */ + + #define X x->d + #define Y y->d +@@ -63,21 +85,73 @@ typedef union { int i[2]; double d; } nu + + #define ABS(x) ((x) < 0 ? -(x) : (x)) + +-int __acr(const mp_no *, const mp_no *, int); +-// int __cr(const mp_no *, const mp_no *, int); +-void __cpy(const mp_no *, mp_no *, int); +-// void __cpymn(const mp_no *, int, mp_no *, int); +-void __mp_dbl(const mp_no *, double *, int); +-void __dbl_mp(double, mp_no *, int); +-void __add(const mp_no *, const mp_no *, mp_no *, int); +-void __sub(const mp_no *, const mp_no *, mp_no *, int); +-void __mul(const mp_no *, const mp_no *, mp_no *, int); +-// void __inv(const mp_no *, mp_no *, int); +-void __dvd(const mp_no *, const mp_no *, mp_no *, int); ++#ifndef RADIXI ++# define RADIXI 0x1.0p-24 /* 2^-24 */ ++#endif ++ ++#ifndef TWO52 ++# define TWO52 0x1.0p52 /* 2^52 */ ++#endif ++ ++#define TWO5 TWOPOW (5) /* 2^5 */ ++#define TWO8 TWOPOW (8) /* 2^52 */ ++#define TWO10 TWOPOW (10) /* 2^10 */ ++#define TWO18 TWOPOW (18) /* 2^18 */ ++#define TWO19 TWOPOW (19) /* 2^19 */ ++#define TWO23 TWOPOW (23) /* 2^23 */ ++ ++#define TWO57 0x1.0p57 /* 2^57 */ ++#define TWO71 0x1.0p71 /* 2^71 */ ++#define TWOM1032 0x1.0p-1032 /* 2^-1032 */ ++#define TWOM1022 0x1.0p-1022 /* 2^-1022 */ ++ ++#define HALF 0x1.0p-1 /* 1/2 */ ++#define MHALF -0x1.0p-1 /* -1/2 */ ++#define HALFRAD 0x1.0p23 /* 2^23 */ ++ ++int __acr (const mp_no *, const mp_no *, int); ++void __cpy (const mp_no *, mp_no *, int); ++void __mp_dbl (const mp_no *, double *, int); ++void __dbl_mp (double, mp_no *, int); ++void __add (const mp_no *, const mp_no *, mp_no *, int); ++void __sub (const mp_no *, const mp_no *, mp_no *, int); ++void __mul (const mp_no *, const mp_no *, mp_no *, int); ++void __sqr (const mp_no *, mp_no *, int); ++void __dvd (const mp_no *, const mp_no *, mp_no *, int); + + extern void __mpatan (mp_no *, mp_no *, int); + extern void __mpatan2 (mp_no *, mp_no *, mp_no *, int); + extern void __mpsqrt (mp_no *, mp_no *, int); +-extern void __mpexp (mp_no *, mp_no *__y, int); ++extern void __mpexp (mp_no *, mp_no *, int); + extern void __c32 (mp_no *, mp_no *, mp_no *, int); + extern int __mpranred (double, mp_no *, int); ++ ++/* Given a power POW, build a multiprecision number 2^POW. */ ++static inline void ++__pow_mp (int pow, mp_no *y, int p) ++{ ++ int i, rem; ++ ++ /* The exponent is E such that E is a factor of 2^24. The remainder (of the ++ form 2^x) goes entirely into the first digit of the mantissa as it is ++ always less than 2^24. */ ++ EY = pow / 24; ++ rem = pow - EY * 24; ++ EY++; ++ ++ /* If the remainder is negative, it means that POW was negative since ++ |EY * 24| <= |pow|. Adjust so that REM is positive and still less than ++ 24 because of which, the mantissa digit is less than 2^24. */ ++ if (rem < 0) ++ { ++ EY--; ++ rem += 24; ++ } ++ /* The sign of any 2^x is always positive. */ ++ Y[0] = 1; ++ Y[1] = 1 << rem; ++ ++ /* Everything else is 0. */ ++ for (i = 2; i <= p; i++) ++ Y[i] = 0; ++} +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpexp.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpexp.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpexp.c +@@ -69,13 +69,13 @@ __mpexp(mp_no *x, mp_no *y, int p) { + for (i=0; iEX; i--) a *= RADIX; + b = X[1]*RADIXI; m2 = 24*EX; +- for (; b0; i--,n--) { if (m1np[i][p]+m2>0) break; } + } + +@@ -84,8 +84,8 @@ __mpexp(mp_no *x, mp_no *y, int p) { + __mul(x,&mpt1,&mps,p); + + /* Evaluate the polynomial. Put result in mpt2 */ +- mpone.e=1; mpone.d[0]=ONE; mpone.d[1]=ONE; +- mpk.e = 1; mpk.d[0] = ONE; mpk.d[1]=__mpexp_nn[n].d; ++ mpone.e=1; mpone.d[0]=1; mpone.d[1]=1; ++ mpk.e = 1; mpk.d[0] = 1; mpk.d[1]=__mpexp_nn[n].d; + __dvd(&mps,&mpk,&mpt1,p); + __add(&mpone,&mpt1,&mpak,p); + for (k=n-1; k>1; k--) { +@@ -99,9 +99,9 @@ __mpexp(mp_no *x, mp_no *y, int p) { + + /* Raise polynomial value to the power of 2**m. Put result in y */ + for (k=0,j=0; k. + */ +-/************************************************************************/ +-/* MODULE_NAME: mpa.c */ +-/* */ +-/* FUNCTIONS: */ +-/* mcr */ +-/* acr */ +-/* cr */ +-/* cpy */ +-/* cpymn */ +-/* norm */ +-/* denorm */ +-/* mp_dbl */ +-/* dbl_mp */ +-/* add_magnitudes */ +-/* sub_magnitudes */ +-/* add */ +-/* sub */ +-/* mul */ +-/* inv */ +-/* dvd */ +-/* */ +-/* Arithmetic functions for multiple precision numbers. */ +-/* Relative errors are bounded */ +-/************************************************************************/ +- +- +-#include "endian.h" +-#include "mpa.h" +-#include "mpa2.h" +-#include /* For MIN() */ +-/* mcr() compares the sizes of the mantissas of two multiple precision */ +-/* numbers. Mantissas are compared regardless of the signs of the */ +-/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */ +-/* disregarded. */ +-static int mcr(const mp_no *x, const mp_no *y, int p) { +- long i; +- long p2 = p; +- for (i=1; i<=p2; i++) { +- if (X[i] == Y[i]) continue; +- else if (X[i] > Y[i]) return 1; +- else return -1; } +- return 0; +-} +- +- +- +-/* acr() compares the absolute values of two multiple precision numbers */ +-int __acr(const mp_no *x, const mp_no *y, int p) { +- long i; +- +- if (X[0] == ZERO) { +- if (Y[0] == ZERO) i= 0; +- else i=-1; +- } +- else if (Y[0] == ZERO) i= 1; +- else { +- if (EX > EY) i= 1; +- else if (EX < EY) i=-1; +- else i= mcr(x,y,p); +- } +- +- return i; +-} +- +- +-/* cr90 compares the values of two multiple precision numbers */ +-int __cr(const mp_no *x, const mp_no *y, int p) { +- int i; +- +- if (X[0] > Y[0]) i= 1; +- else if (X[0] < Y[0]) i=-1; +- else if (X[0] < ZERO ) i= __acr(y,x,p); +- else i= __acr(x,y,p); +- +- return i; +-} +- +- +-/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */ +-void __cpy(const mp_no *x, mp_no *y, int p) { +- long i; +- +- EY = EX; +- for (i=0; i <= p; i++) Y[i] = X[i]; +- +- return; +-} +- +- +-/* Copy a multiple precision number x of precision m into a */ +-/* multiple precision number y of precision n. In case n>m, */ +-/* the digits of y beyond the m'th are set to zero. In case */ +-/* n= 2**(-1022))) */ +-static void norm(const mp_no *x, double *y, int p) +-{ +- #define R radixi.d +- long i; +-#if 0 +- int k; +-#endif +- double a,c,u,v,z[5]; +- if (p<5) { +- if (p==1) c = X[1]; +- else if (p==2) c = X[1] + R* X[2]; +- else if (p==3) c = X[1] + R*(X[2] + R* X[3]); +- else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]); +- } +- else { +- for (a=ONE, z[1]=X[1]; z[1] < TWO23; ) +- {a *= TWO; z[1] *= TWO; } +- +- for (i=2; i<5; i++) { +- z[i] = X[i]*a; +- u = (z[i] + CUTTER)-CUTTER; +- if (u > z[i]) u -= RADIX; +- z[i] -= u; +- z[i-1] += u*RADIXI; +- } +- +- u = (z[3] + TWO71) - TWO71; +- if (u > z[3]) u -= TWO19; +- v = z[3]-u; +- +- if (v == TWO18) { +- if (z[4] == ZERO) { +- for (i=5; i <= p; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } +- } +- } +- else z[3] += ONE; +- } +- +- c = (z[1] + R *(z[2] + R * z[3]))/a; +- } + +- c *= X[0]; +- +- for (i=1; iEX; i--) c *= RADIXI; +- +- *y = c; +- return; +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision */ +-/* number *y, denormalized case (|x| < 2**(-1022))) */ +-static void denorm(const mp_no *x, double *y, int p) ++/* Define __mul and __sqr and use the rest from generic code. */ ++#define NO__MUL ++#define NO__SQR ++ ++#include ++ ++/* Multiply *X and *Y and store result in *Z. X and Y may overlap but not X ++ and Z or Y and Z. For P in [1, 2, 3], the exact result is truncated to P ++ digits. In case P > 3 the error is bounded by 1.001 ULP. */ ++void ++__mul (const mp_no *x, const mp_no *y, mp_no *z, int p) + { +- long i,k; ++ long i, i1, i2, j, k, k2; + long p2 = p; +- double c,u,z[5]; +-#if 0 +- double a,v; +-#endif ++ double u, zk, zk2; + +-#define R radixi.d +- if (EX<-44 || (EX==-44 && X[1] z[3]) u -= TWO5; +- +- if (u==z[3]) { +- for (i=k+1; i <= p2; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } ++ /* Is z=0? */ ++ if (__glibc_unlikely (X[0] * Y[0] == 0)) ++ { ++ Z[0] = 0; ++ return; + } +- } +- +- c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10); + +- *y = c*TWOM1032; +- return; +- +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision number *y. */ +-/* The result is correctly rounded to the nearest/even. *x is left unchanged */ +- +-void __mp_dbl(const mp_no *x, double *y, int p) { +-#if 0 +- int i,k; +- double a,c,u,v,z[5]; ++ /* Multiply, add and carry */ ++ k2 = (p2 < 3) ? p2 + p2 : p2 + 3; ++ zk = Z[k2] = 0; ++ for (k = k2; k > 1;) ++ { ++ if (k > p2) ++ { ++ i1 = k - p2; ++ i2 = p2 + 1; ++ } ++ else ++ { ++ i1 = 1; ++ i2 = k; ++ } ++#if 1 ++ /* Rearrange this inner loop to allow the fmadd instructions to be ++ independent and execute in parallel on processors that have ++ dual symmetrical FP pipelines. */ ++ if (i1 < (i2 - 1)) ++ { ++ /* Make sure we have at least 2 iterations. */ ++ if (((i2 - i1) & 1L) == 1L) ++ { ++ /* Handle the odd iterations case. */ ++ zk2 = x->d[i2 - 1] * y->d[i1]; ++ } ++ else ++ zk2 = 0.0; ++ /* Do two multiply/adds per loop iteration, using independent ++ accumulators; zk and zk2. */ ++ for (i = i1, j = i2 - 1; i < i2 - 1; i += 2, j -= 2) ++ { ++ zk += x->d[i] * y->d[j]; ++ zk2 += x->d[i + 1] * y->d[j - 1]; ++ } ++ zk += zk2; /* Final sum. */ ++ } ++ else ++ { ++ /* Special case when iterations is 1. */ ++ zk += x->d[i1] * y->d[i1]; ++ } ++#else ++ /* The original code. */ ++ for (i = i1, j = i2 - 1; i < i2; i++, j--) ++ zk += X[i] * Y[j]; + #endif + +- if (X[0] == ZERO) {*y = ZERO; return; } +- +- if (EX> -42) norm(x,y,p); +- else if (EX==-42 && X[1]>=TWO10) norm(x,y,p); +- else denorm(x,y,p); +-} +- +- +-/* dbl_mp() converts a double precision number x into a multiple precision */ +-/* number *y. If the precision p is too small the result is truncated. x is */ +-/* left unchanged. */ +- +-void __dbl_mp(double x, mp_no *y, int p) { ++ u = (zk + CUTTER) - CUTTER; ++ if (u > zk) ++ u -= RADIX; ++ Z[k] = zk - u; ++ zk = u * RADIXI; ++ --k; ++ } ++ Z[k] = zk; + +- long i,n; +- long p2 = p; +- double u; ++ int e = EX + EY; ++ /* Is there a carry beyond the most significant digit? */ ++ if (Z[1] == 0) ++ { ++ for (i = 1; i <= p2; i++) ++ Z[i] = Z[i + 1]; ++ e--; ++ } + +- /* Sign */ +- if (x == ZERO) {Y[0] = ZERO; return; } +- else if (x > ZERO) Y[0] = ONE; +- else {Y[0] = MONE; x=-x; } +- +- /* Exponent */ +- for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI; +- for ( ; x < ONE; EY -= ONE) x *= RADIX; +- +- /* Digits */ +- n=MIN(p2,4); +- for (i=1; i<=n; i++) { +- u = (x + TWO52) - TWO52; +- if (u>x) u -= ONE; +- Y[i] = u; x -= u; x *= RADIX; } +- for ( ; i<=p2; i++) Y[i] = ZERO; +- return; ++ EZ = e; ++ Z[0] = X[0] * Y[0]; + } + ++/* Square *X and store result in *Y. X and Y may not overlap. For P in ++ [1, 2, 3], the exact result is truncated to P digits. In case P > 3 the ++ error is bounded by 1.001 ULP. This is a faster special case of ++ multiplication. */ ++void ++__sqr (const mp_no *x, mp_no *y, int p) ++{ ++ long i, j, k, ip; ++ double u, yk; + +-/* add_magnitudes() adds the magnitudes of *x & *y assuming that */ +-/* abs(*x) >= abs(*y) > 0. */ +-/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */ +-/* No guard digit is used. The result equals the exact sum, truncated. */ +-/* *x & *y are left unchanged. */ ++ /* Is z=0? */ ++ if (__glibc_unlikely (X[0] == 0)) ++ { ++ Y[0] = 0; ++ return; ++ } + +-static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ /* We need not iterate through all X's since it's pointless to ++ multiply zeroes. */ ++ for (ip = p; ip > 0; ip--) ++ if (X[ip] != 0) ++ break; + +- long i,j,k; +- long p2 = p; ++ k = (__glibc_unlikely (p < 3)) ? p + p : p + 3; + +- EZ = EX; ++ while (k > 2 * ip + 1) ++ Y[k--] = 0; + +- i=p2; j=p2+ EY - EX; k=p2+1; ++ yk = 0; + +- if (j<1) +- {__cpy(x,z,p); return; } +- else Z[k] = ZERO; +- +- for (; j>0; i--,j--) { +- Z[k] += X[i] + Y[j]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- if (Z[1] == ZERO) { +- for (i=1; i<=p2; i++) Z[i] = Z[i+1]; } +- else EZ += ONE; +-} ++ while (k > p) ++ { ++ double yk2 = 0.0; ++ long lim = k / 2; + ++ if (k % 2 == 0) ++ { ++ yk += X[lim] * X[lim]; ++ lim--; ++ } + +-/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */ +-/* abs(*x) > abs(*y) > 0. */ +-/* The sign of the difference *z is undefined. x&y may overlap but not x&z */ +-/* or y&z. One guard digit is used. The error is less than one ulp. */ +-/* *x & *y are left unchanged. */ ++ /* In __mul, this loop (and the one within the next while loop) run ++ between a range to calculate the mantissa as follows: + +-static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ Z[k] = X[k] * Y[n] + X[k+1] * Y[n-1] ... + X[n-1] * Y[k+1] ++ + X[n] * Y[k] + +- long i,j,k; +- long p2 = p; ++ For X == Y, we can get away with summing halfway and doubling the ++ result. For cases where the range size is even, the mid-point needs ++ to be added separately (above). */ ++ for (i = k - p, j = p; i <= lim; i++, j--) ++ yk2 += X[i] * X[j]; + +- EZ = EX; ++ yk += 2.0 * yk2; + +- if (EX == EY) { +- i=j=k=p2; +- Z[k] = Z[k+1] = ZERO; } +- else { +- j= EX - EY; +- if (j > p2) {__cpy(x,z,p); return; } +- else { +- i=p2; j=p2+1-j; k=p2; +- if (Y[j] > ZERO) { +- Z[k+1] = RADIX - Y[j--]; +- Z[k] = MONE; } +- else { +- Z[k+1] = ZERO; +- Z[k] = ZERO; j--;} ++ u = (yk + CUTTER) - CUTTER; ++ if (u > yk) ++ u -= RADIX; ++ Y[k--] = yk - u; ++ yk = u * RADIXI; + } +- } +- +- for (; j>0; i--,j--) { +- Z[k] += (X[i] - Y[j]); +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (i=1; Z[i] == ZERO; i++) ; +- EZ = EZ - i + 1; +- for (k=1; i <= p2+1; ) +- Z[k++] = Z[i++]; +- for (; k <= p2; ) +- Z[k++] = ZERO; +- +- return; +-} +- +- +-/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */ +-/* but not x&z or y&z. One guard digit is used. The error is less than */ +-/* one ulp. *x & *y are left unchanged. */ +- +-void __add(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int n; +- +- if (X[0] == ZERO) {__cpy(y,z,p); return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } +- +- if (X[0] == Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- else Z[0] = ZERO; +- } +- return; +-} +- +- +-/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */ +-/* overlap but not x&z or y&z. One guard digit is used. The error is */ +-/* less than one ulp. *x & *y are left unchanged. */ +- +-void __sub(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int n; +- +- if (X[0] == ZERO) {__cpy(y,z,p); Z[0] = -Z[0]; return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } +- +- if (X[0] != Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- else Z[0] = ZERO; +- } +- return; +-} +- +- +-/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */ +-/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */ +-/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */ +-/* *x & *y are left unchanged. */ + +-void __mul(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i, i1, i2, j, k, k2; +- long p2 = p; +- double u, zk, zk2; +- +- /* Is z=0? */ +- if (X[0]*Y[0]==ZERO) +- { Z[0]=ZERO; return; } +- +- /* Multiply, add and carry */ +- k2 = (p2<3) ? p2+p2 : p2+3; +- zk = Z[k2]=ZERO; +- for (k=k2; k>1; ) { +- if (k > p2) {i1=k-p2; i2=p2+1; } +- else {i1=1; i2=k; } +-#if 1 +- /* rearange this inner loop to allow the fmadd instructions to be +- independent and execute in parallel on processors that have +- dual symetrical FP pipelines. */ +- if (i1 < (i2-1)) ++ while (k > 1) + { +- /* make sure we have at least 2 iterations */ +- if (((i2 - i1) & 1L) == 1L) +- { +- /* Handle the odd iterations case. */ +- zk2 = x->d[i2-1]*y->d[i1]; +- } +- else +- zk2 = zero.d; +- /* Do two multiply/adds per loop iteration, using independent +- accumulators; zk and zk2. */ +- for (i=i1,j=i2-1; id[i]*y->d[j]; +- zk2 += x->d[i+1]*y->d[j-1]; ++ double yk2 = 0.0; ++ long lim = k / 2; ++ ++ if (k % 2 == 0) ++ { ++ yk += X[lim] * X[lim]; ++ lim--; + } +- zk += zk2; /* final sum. */ +- } +- else ++ ++ /* Likewise for this loop. */ ++ for (i = 1, j = k - 1; i <= lim; i++, j--) ++ yk2 += X[i] * X[j]; ++ ++ yk += 2.0 * yk2; ++ ++ u = (yk + CUTTER) - CUTTER; ++ if (u > yk) ++ u -= RADIX; ++ Y[k--] = yk - u; ++ yk = u * RADIXI; ++ } ++ Y[k] = yk; ++ ++ /* Squares are always positive. */ ++ Y[0] = 1.0; ++ ++ int e = EX * 2; ++ /* Is there a carry beyond the most significant digit? */ ++ if (__glibc_unlikely (Y[1] == 0)) + { +- /* Special case when iterations is 1. */ +- zk += x->d[i1]*y->d[i1]; ++ for (i = 1; i <= p; i++) ++ Y[i] = Y[i + 1]; ++ e--; + } +-#else +- /* The orginal code. */ +- for (i=i1,j=i2-1; i zk) u -= RADIX; +- Z[k] = zk - u; +- zk = u*RADIXI; +- --k; +- } +- Z[k] = zk; +- +- /* Is there a carry beyond the most significant digit? */ +- if (Z[1] == ZERO) { +- for (i=1; i<=p2; i++) Z[i]=Z[i+1]; +- EZ = EX + EY - 1; } +- else +- EZ = EX + EY; +- +- Z[0] = X[0] * Y[0]; +- return; +-} +- +- +-/* Invert a multiple precision number. Set *y = 1 / *x. */ +-/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */ +-/* 2.001*r**(1-p) for p>3. */ +-/* *x=0 is not permissible. *x is left unchanged. */ +- +-void __inv(const mp_no *x, mp_no *y, int p) { +- long i; +-#if 0 +- int l; +-#endif +- double t; +- mp_no z,w; +- static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3, +- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4}; +- const mp_no mptwo = {1,{1.0,2.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,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.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}}; +- +- __cpy(x,&z,p); z.e=0; __mp_dbl(&z,&t,p); +- t=ONE/t; __dbl_mp(t,y,p); EY -= EX; +- +- for (i=0; i3. *y=0 is not permissible. */ +- +-void __dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- mp_no w; +- +- if (X[0] == ZERO) Z[0] = ZERO; +- else {__inv(y,&w,p); __mul(x,&w,z,p);} +- return; ++ EY = e; + } +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/atnat.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/atnat.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/atnat.h +@@ -138,8 +138,6 @@ + #endif + #endif + +-#define ZERO zero.d +-#define ONE one.d + #define A a.d + #define B b.d + #define C c.d +@@ -160,7 +158,5 @@ + #define U6 u6.d + #define U7 u7.d + #define U8 u8.d +-#define TWO8 two8.d +-#define TWO52 two52.d + + #endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/atnat2.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/atnat2.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/atnat2.h +@@ -174,11 +174,4 @@ + #endif + #endif + +-#define ZERO zero.d +-#define MZERO mzero.d +-#define ONE one.d +-#define TWO8 two8.d +-#define TWO52 two52.d +-#define TWOM1022 twom1022.d +- + #endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa2.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpa2.h ++++ /dev/null +@@ -1,94 +0,0 @@ +- +-/* +- * IBM Accurate Mathematical Library +- * Written by International Business Machines Corp. +- * Copyright (C) 2001 Free Software Foundation, Inc. +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU Lesser General Public License as published by +- * the Free Software Foundation; either version 2.1 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public License +- * along with this program; if not, see . +- */ +- +-/**************************************************************************/ +-/* */ +-/* MODULE_NAME:mpa2.h */ +-/* */ +-/* */ +-/* variables prototype and definition according to type of processor */ +-/* types definition */ +-/**************************************************************************/ +- +-#ifndef MPA2_H +-#define MPA2_H +- +- +-#ifdef BIG_ENDI +-static const number +-/**/ radix = {{0x41700000, 0x00000000} }, /* 2**24 */ +-/**/ radixi = {{0x3e700000, 0x00000000} }, /* 2**-24 */ +-/**/ cutter = {{0x44b00000, 0x00000000} }, /* 2**76 */ +-/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */ +-/**/ one = {{0x3ff00000, 0x00000000} }, /* 1 */ +-/**/ mone = {{0xbff00000, 0x00000000} }, /* -1 */ +-/**/ two = {{0x40000000, 0x00000000} }, /* 2 */ +-/**/ two5 = {{0x40400000, 0x00000000} }, /* 2**5 */ +-/**/ two10 = {{0x40900000, 0x00000000} }, /* 2**10 */ +-/**/ two18 = {{0x41100000, 0x00000000} }, /* 2**18 */ +-/**/ two19 = {{0x41200000, 0x00000000} }, /* 2**19 */ +-/**/ two23 = {{0x41600000, 0x00000000} }, /* 2**23 */ +-/**/ two52 = {{0x43300000, 0x00000000} }, /* 2**52 */ +-/**/ two57 = {{0x43800000, 0x00000000} }, /* 2**57 */ +-/**/ two71 = {{0x44600000, 0x00000000} }, /* 2**71 */ +-/**/ twom1032 = {{0x00000400, 0x00000000} }; /* 2**-1032 */ +- +-#else +-#ifdef LITTLE_ENDI +-static const number +-/**/ radix = {{0x00000000, 0x41700000} }, /* 2**24 */ +-/**/ radixi = {{0x00000000, 0x3e700000} }, /* 2**-24 */ +-/**/ cutter = {{0x00000000, 0x44b00000} }, /* 2**76 */ +-/**/ zero = {{0x00000000, 0x00000000} }, /* 0 */ +-/**/ one = {{0x00000000, 0x3ff00000} }, /* 1 */ +-/**/ mone = {{0x00000000, 0xbff00000} }, /* -1 */ +-/**/ two = {{0x00000000, 0x40000000} }, /* 2 */ +-/**/ two5 = {{0x00000000, 0x40400000} }, /* 2**5 */ +-/**/ two10 = {{0x00000000, 0x40900000} }, /* 2**10 */ +-/**/ two18 = {{0x00000000, 0x41100000} }, /* 2**18 */ +-/**/ two19 = {{0x00000000, 0x41200000} }, /* 2**19 */ +-/**/ two23 = {{0x00000000, 0x41600000} }, /* 2**23 */ +-/**/ two52 = {{0x00000000, 0x43300000} }, /* 2**52 */ +-/**/ two57 = {{0x00000000, 0x43800000} }, /* 2**57 */ +-/**/ two71 = {{0x00000000, 0x44600000} }, /* 2**71 */ +-/**/ twom1032 = {{0x00000000, 0x00000400} }; /* 2**-1032 */ +- +-#endif +-#endif +- +-#define RADIX radix.d +-#define RADIXI radixi.d +-#define CUTTER cutter.d +-#define ZERO zero.d +-#define ONE one.d +-#define MONE mone.d +-#define TWO two.d +-#define TWO5 two5.d +-#define TWO10 two10.d +-#define TWO18 two18.d +-#define TWO19 two19.d +-#define TWO23 two23.d +-#define TWO52 two52.d +-#define TWO57 two57.d +-#define TWO71 two71.d +-#define TWOM1032 twom1032.d +- +- +-#endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpatan.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpatan.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpatan.h +@@ -177,6 +177,3 @@ __atan_twonm1[33] = { + + #endif + #endif +- +-#define ONE __atan_one.d +-#define TWO __atan_two.d +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpatan2.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpatan2.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpatan2.c +@@ -49,18 +49,16 @@ void + SECTION + __mpatan2(mp_no *y, mp_no *x, mp_no *z, int p) { + +- static const double ZERO = 0.0, ONE = 1.0; +- + mp_no mpone = {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,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.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}}; + mp_no mpt1,mpt2,mpt3; + + +- if (X[0] <= ZERO) { +- mpone.e = 1; mpone.d[0] = mpone.d[1] = ONE; ++ if (X[0] <= 0) { ++ mpone.e = 1; mpone.d[0] = mpone.d[1] = 1; + __dvd(x,y,&mpt1,p); __mul(&mpt1,&mpt1,&mpt2,p); +- if (mpt1.d[0] != ZERO) mpt1.d[0] = ONE; ++ if (mpt1.d[0] != 0) mpt1.d[0] = 1; + __add(&mpt2,&mpone,&mpt3,p); __mpsqrt(&mpt3,&mpt2,p); + __add(&mpt1,&mpt2,&mpt3,p); mpt3.d[0]=Y[0]; + __mpatan(&mpt3,&mpt1,p); __add(&mpt1,&mpt1,z,p); +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpexp.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpexp.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpexp.h +@@ -159,11 +159,4 @@ extern const number __mpexp_half attribu + #endif + #endif + +-#define RADIX __mpexp_radix.d +-#define RADIXI __mpexp_radixi.d +-#define ZERO __mpexp_zero.d +-#define ONE __mpexp_one.d +-#define TWO __mpexp_two.d +-#define HALF __mpexp_half.d +- + #endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpsqrt.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpsqrt.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpsqrt.h +@@ -51,7 +51,4 @@ extern const int __mpsqrt_mp[33] attribu + 4,4,4,4,4,4,4,4,4}; + #endif + +-#define ONE __mpsqrt_one.d +-#define HALFRAD __mpsqrt_halfrad.d +- + #endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mptan.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mptan.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mptan.c +@@ -47,8 +47,6 @@ void + SECTION + __mptan(double x, mp_no *mpy, int p) { + +- static const double MONE = -1.0; +- + int n; + mp_no mpw, mpc, mps; + +@@ -56,7 +54,7 @@ __mptan(double x, mp_no *mpy, int p) { + __c32(&mpw, &mpc, &mps, p); /* computing sin(x) and cos(x) */ + if (n) /* second or fourth quarter of unit circle */ + { __dvd(&mpc,&mps,mpy,p); +- mpy->d[0] *= MONE; ++ mpy->d[0] *= -1; + } /* tan is negative in this area */ + else __dvd(&mps,&mpc,mpy,p); + +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/ulog.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/ulog.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/ulog.h +@@ -181,10 +181,6 @@ + #endif + #endif + +-#define ZERO zero.d +-#define ONE one.d +-#define HALF half.d +-#define MHALF mhalf.d + #define SQRT_2 sqrt_2.d + #define DEL_U delu.d + #define DEL_V delv.d +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/utan.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/utan.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/utan.h +@@ -270,10 +270,4 @@ + #endif + #endif + +- +-#define ZERO zero.d +-#define ONE one.d +-#define MONE mone.d +-#define TWO8 two8.d +- + #endif +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa-arch.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpa-arch.h +@@ -0,0 +1,47 @@ ++/* Overridable constants and operations. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published by ++ the Free Software Foundation; either version 2.1 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program; if not, see . */ ++ ++#include ++ ++typedef long mantissa_t; ++typedef int64_t mantissa_store_t; ++ ++#define TWOPOW(i) (1L << i) ++ ++#define RADIX_EXP 24 ++#define RADIX TWOPOW (RADIX_EXP) /* 2^24 */ ++ ++/* Divide D by RADIX and put the remainder in R. D must be a non-negative ++ integral value. */ ++#define DIV_RADIX(d, r) \ ++ ({ \ ++ r = d & (RADIX - 1); \ ++ d >>= RADIX_EXP; \ ++ }) ++ ++/* Put the integer component of a double X in R and retain the fraction in ++ X. This is used in extracting mantissa digits for MP_NO by using the ++ integer portion of the current value of the number as the current mantissa ++ digit and then scaling by RADIX to get the next mantissa digit in the same ++ manner. */ ++#define INTEGER_OF(x, i) \ ++ ({ \ ++ i = (mantissa_t) x; \ ++ x -= i; \ ++ }) ++ ++/* Align IN down to F. The code assumes that F is a power of two. */ ++#define ALIGN_DOWN_TO(in, f) ((in) & -(f)) +Index: glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/mpa-arch.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/mpa-arch.h +@@ -0,0 +1,56 @@ ++/* Overridable constants and operations. ++ Copyright (C) 2013-2017 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU Lesser General Public License as published by ++ the Free Software Foundation; either version 2.1 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public License ++ along with this program; if not, see . */ ++ ++typedef double mantissa_t; ++typedef double mantissa_store_t; ++ ++#define TWOPOW(i) (0x1.0p##i) ++ ++#define RADIX TWOPOW (24) /* 2^24 */ ++#define CUTTER TWOPOW (76) /* 2^76 */ ++#define RADIXI 0x1.0p-24 /* 2^-24 */ ++#define TWO52 TWOPOW (52) /* 2^52 */ ++ ++/* Divide D by RADIX and put the remainder in R. */ ++#define DIV_RADIX(d,r) \ ++ ({ \ ++ double u = ((d) + CUTTER) - CUTTER; \ ++ if (u > (d)) \ ++ u -= RADIX; \ ++ r = (d) - u; \ ++ (d) = u * RADIXI; \ ++ }) ++ ++/* Put the integer component of a double X in R and retain the fraction in ++ X. */ ++#define INTEGER_OF(x, r) \ ++ ({ \ ++ double u = ((x) + TWO52) - TWO52; \ ++ if (u > (x)) \ ++ u -= 1; \ ++ (r) = u; \ ++ (x) -= u; \ ++ }) ++ ++/* Align IN down to a multiple of F, where F is a power of two. */ ++#define ALIGN_DOWN_TO(in, f) \ ++ ({ \ ++ double factor = f * TWO52; \ ++ double u = (in + factor) - factor; \ ++ if (u > in) \ ++ u -= f; \ ++ u; \ ++ }) +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/e_atan2.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/e_atan2.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/e_atan2.c +@@ -98,15 +98,15 @@ __ieee754_atan2(double y,double x) { + /* y=+-0 */ + if (uy==0x00000000) { + if (dy==0x00000000) { +- if ((ux&0x80000000)==0x00000000) return ZERO; ++ if ((ux&0x80000000)==0x00000000) return 0; + else return opi.d; } } + else if (uy==0x80000000) { + if (dy==0x00000000) { +- if ((ux&0x80000000)==0x00000000) return MZERO; ++ if ((ux&0x80000000)==0x00000000) return -0.0; + else return mopi.d;} } + + /* x=+-0 */ +- if (x==ZERO) { ++ if (x==0) { + if ((uy&0x80000000)==0x00000000) return hpi.d; + else return mhpi.d; } + +@@ -118,8 +118,8 @@ __ieee754_atan2(double y,double x) { + else if (uy==0xfff00000) { + if (dy==0x00000000) return mqpi.d; } + else { +- if ((uy&0x80000000)==0x00000000) return ZERO; +- else return MZERO; } ++ if ((uy&0x80000000)==0x00000000) return 0; ++ else return -0.0; } + } + } + else if (ux==0xfff00000) { +@@ -141,14 +141,14 @@ __ieee754_atan2(double y,double x) { + if (dy==0x00000000) return mhpi.d; } + + /* either x/y or y/x is very close to zero */ +- ax = (x=ep) { return ((y>ZERO) ? hpi.d : mhpi.d); } ++ if (de>=ep) { return ((y>0) ? hpi.d : mhpi.d); } + else if (de<=em) { +- if (x>ZERO) { ++ if (x>0) { + if ((z=ay/ax)ZERO) ? opi.d : mopi.d); } } ++ else { return ((y>0) ? opi.d : mopi.d); } } + + /* if either x or y is extremely close to zero, scale abs(x), abs(y). */ + if (axZERO) { ++ if (x>0) { + + /* (i) x>0, abs(y)< abs(x): atan(ay/ax) */ + if (ay U03, 1)) { goto case_03; } + + +@@ -113,25 +113,25 @@ __ieee754_log(double x) { + w*(d17.d+w*(d18.d+w*(d19.d+w*d20.d)))))))); + EMULV(w,a,s2,ss2,t1,t2,t3,t4,t5) + ADD2(d10.d,dd10.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d9.d,dd9.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d8.d,dd8.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d7.d,dd7.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d6.d,dd6.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d5.d,dd5.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d4.d,dd4.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d3.d,dd3.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(d2.d,dd2.d,s2,ss2,s3,ss3,t1,t2) +- MUL2(w,ZERO,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) +- MUL2(w,ZERO,s2,ss2,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8) +- ADD2(w,ZERO, s3,ss3, b, bb,t1,t2) ++ MUL2(w,0,s3,ss3,s2,ss2,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(w,0,s2,ss2,s3,ss3,t1,t2,t3,t4,t5,t6,t7,t8) ++ ADD2(w,0, s3,ss3, b, bb,t1,t2) + + /* End stage II, case abs(x-1) < 0.03 */ + if ((y=b+(bb+b*E4)) == b+(bb-b*E4)) return y; +@@ -155,7 +155,7 @@ __ieee754_log(double x) { + j = (num.i[HIGH_HALF] & 0x000fffff) >> 4; + + /* Compute w=(u-ui*vj)/(ui*vj) */ +- p0=(ONE+(i-75)*DEL_U)*(ONE+(j-180)*DEL_V); ++ p0=(1+(i-75)*DEL_U)*(1+(j-180)*DEL_V); + q=u-p0; r0=Iu[i].d*Iv[j].d; w=q*r0; + + /* Evaluate polynomial I */ +@@ -178,11 +178,11 @@ __ieee754_log(double x) { + + /* Improve the accuracy of r0 */ + EMULV(p0,r0,sa,sb,t1,t2,t3,t4,t5) +- t=r0*((ONE-sa)-sb); ++ t=r0*((1-sa)-sb); + EADD(r0,t,ra,rb) + + /* Compute w */ +- MUL2(q,ZERO,ra,rb,w,ww,t1,t2,t3,t4,t5,t6,t7,t8) ++ MUL2(q,0,ra,rb,w,ww,t1,t2,t3,t4,t5,t6,t7,t8) + + EADD(A,B0,a0,aa0) + +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/s_atan.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/s_atan.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/s_atan.c +@@ -82,7 +82,7 @@ double atan(double x) { + return x+x; + + /* Regular values of x, including denormals +-0 and +-INF */ +- u = (x= 1/2 */ + if ((y=t1+(yy-u3)) == t1+(yy+u3)) return __signArctan(x,y); + +- DIV2(ONE,ZERO,u,ZERO,w,ww,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) ++ DIV2(1,0,u,0,w,ww,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) + t1=w-hij[i][0].d; + EADD(t1,ww,z,zz) + s1=z*(hij[i][11].d+z*(hij[i][12].d+z*(hij[i][13].d+ + z*(hij[i][14].d+z* hij[i][15].d)))); +- ADD2(hij[i][9].d,hij[i][10].d,s1,ZERO,s2,ss2,t1,t2) ++ ADD2(hij[i][9].d,hij[i][10].d,s1,0,s2,ss2,t1,t2) + MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8) + ADD2(hij[i][7].d,hij[i][8].d,s1,ss1,s2,ss2,t1,t2) + MUL2(z,zz,s2,ss2,s1,ss1,t1,t2,t3,t4,t5,t6,t7,t8) +@@ -173,18 +173,18 @@ double atan(double x) { + } + else { + if (u__atan_xm[m].d) break;} + } + mpone.e = mptwo.e = mptwoim1.e = 1; +- mpone.d[0] = mpone.d[1] = mptwo.d[0] = mptwoim1.d[0] = ONE; +- mptwo.d[1] = TWO; ++ mpone.d[0] = mpone.d[1] = mptwo.d[0] = mptwoim1.d[0] = 1; ++ mptwo.d[1] = 2; + + /* Reduce x m times */ + __mul(x,x,&mpsm,p); +@@ -92,7 +92,7 @@ __mpatan(mp_no *x, mp_no *y, int p) { + n=__atan_np[p]; mptwoim1.d[1] = __atan_twonm1[p].d; + __dvd(&mpsm,&mptwoim1,&mpt,p); + for (i=n-1; i>1; i--) { +- mptwoim1.d[1] -= TWO; ++ mptwoim1.d[1] -= 2; + __dvd(&mpsm,&mptwoim1,&mpt1,p); + __mul(&mpsm,&mpt,&mpt2,p); + __sub(&mpt1,&mpt2,&mpt,p); +Index: glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpsqrt.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/ieee754/dbl-64/mpsqrt.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/mpsqrt.c +@@ -62,8 +62,8 @@ __mpsqrt(mp_no *x, mp_no *y, int p) { + mp_no mpxn,mpz,mpu,mpt1,mpt2; + + /* Prepare multi-precision 1/2 and 3/2 */ +- mphalf.e =0; mphalf.d[0] =ONE; mphalf.d[1] =HALFRAD; +- mp3halfs.e=1; mp3halfs.d[0]=ONE; mp3halfs.d[1]=ONE; mp3halfs.d[2]=HALFRAD; ++ mphalf.e =0; mphalf.d[0] =1; mphalf.d[1] =HALFRAD; ++ mp3halfs.e=1; mp3halfs.d[0]=1; mp3halfs.d[1]=1; mp3halfs.d[2]=HALFRAD; + + ey=EX/2; __cpy(x,&mpxn,p); mpxn.e -= (ey+ey); + __mp_dbl(&mpxn,&dx,p); dy=fastiroot(dx); __dbl_mp(dy,&mpu,p); diff --git a/SOURCES/glibc-rh1413638-1.patch b/SOURCES/glibc-rh1413638-1.patch new file mode 100644 index 00000000..f5255d57 --- /dev/null +++ b/SOURCES/glibc-rh1413638-1.patch @@ -0,0 +1,16 @@ +commit cb756c6d686242acdc942e3d4276e399a69a6f02 +Author: Marcus Shawcroft +Date: Tue Dec 17 18:12:30 2013 +0000 + + Compile e_sqrt.c with -ffp-contract=off. + +diff --git a/sysdeps/ieee754/dbl-64/Makefile b/sysdeps/ieee754/dbl-64/Makefile +index 1a7b311..35f545f 100644 +--- a/sysdeps/ieee754/dbl-64/Makefile ++++ b/sysdeps/ieee754/dbl-64/Makefile +@@ -1,4 +1,5 @@ + ifeq ($(subdir),math) + # branred depends on precise IEEE double rounding + CFLAGS-branred.c = $(config-cflags-nofma) ++CFLAGS-e_sqrt.c = $(config-cflags-nofma) + endif diff --git a/SOURCES/glibc-rh1413638-2.patch b/SOURCES/glibc-rh1413638-2.patch new file mode 100644 index 00000000..7815491b --- /dev/null +++ b/SOURCES/glibc-rh1413638-2.patch @@ -0,0 +1,19 @@ +commit d421868bb85d1459b1d2df520bb26f3e11aa195a +Author: Adhemerval Zanella +Date: Tue Mar 10 09:38:54 2015 -0400 + + powerpc: Fix incorrect results for pow when using FMA + + This patch adds no FMA generation for e_pow to avoid precision issues + for powerpc. This fixes BZ#18104. + +diff --git a/sysdeps/ieee754/dbl-64/Makefile b/sysdeps/ieee754/dbl-64/Makefile +index 35f545f..5557c75 100644 +--- a/sysdeps/ieee754/dbl-64/Makefile ++++ b/sysdeps/ieee754/dbl-64/Makefile +@@ -2,4 +2,5 @@ ifeq ($(subdir),math) + # branred depends on precise IEEE double rounding + CFLAGS-branred.c = $(config-cflags-nofma) + CFLAGS-e_sqrt.c = $(config-cflags-nofma) ++CFLAGS-e_pow.c = $(config-cflags-nofma) + endif diff --git a/SOURCES/glibc-rh1417205.patch b/SOURCES/glibc-rh1417205.patch new file mode 100644 index 00000000..04a9718a --- /dev/null +++ b/SOURCES/glibc-rh1417205.patch @@ -0,0 +1,46 @@ +commit 164fd39d05925717e75715929c7ced14a2c1505e +Author: Andreas Jaeger +Date: Fri May 3 20:51:27 2013 +0200 + + Sync with Linux 3.9 + + * sysdeps/gnu/netinet/tcp.h (TCP_TIMESTAMP): New value, from + Linux 3.9. + * sysdeps/unix/sysv/linux/bits/socket.h (PF_VSOCK, AF_VSOCK): + Add. + (PF_MAX): Adjust for VSOCK change. + +Index: b/sysdeps/gnu/netinet/tcp.h +=================================================================== +--- a/sysdeps/gnu/netinet/tcp.h ++++ b/sysdeps/gnu/netinet/tcp.h +@@ -60,6 +60,7 @@ + #define TCP_QUEUE_SEQ 21 /* Set sequence number of repaired queue. */ + #define TCP_REPAIR_OPTIONS 22 /* Repair TCP connection options */ + #define TCP_FASTOPEN 23 /* Enable FastOpen on listeners */ ++#define TCP_TIMESTAMP 24 /* TCP time stamp */ + + #ifdef __USE_MISC + # include +Index: b/sysdeps/unix/sysv/linux/bits/socket.h +=================================================================== +--- a/sysdeps/unix/sysv/linux/bits/socket.h ++++ b/sysdeps/unix/sysv/linux/bits/socket.h +@@ -80,7 +80,8 @@ typedef __socklen_t socklen_t; + #define PF_CAIF 37 /* CAIF sockets. */ + #define PF_ALG 38 /* Algorithm sockets. */ + #define PF_NFC 39 /* NFC sockets. */ +-#define PF_MAX 40 /* For now.. */ ++#define PF_VSOCK 40 /* vSockets. */ ++#define PF_MAX 41 /* For now.. */ + + /* Address families. */ + #define AF_UNSPEC PF_UNSPEC +@@ -124,6 +125,7 @@ typedef __socklen_t socklen_t; + #define AF_CAIF PF_CAIF + #define AF_ALG PF_ALG + #define AF_NFC PF_NFC ++#define AF_VSOCK PF_VSOCK + #define AF_MAX PF_MAX + + /* Socket level values. Others are defined in the appropriate headers. diff --git a/SOURCES/glibc-rh1418978-0.patch b/SOURCES/glibc-rh1418978-0.patch new file mode 100644 index 00000000..7ad7a91b --- /dev/null +++ b/SOURCES/glibc-rh1418978-0.patch @@ -0,0 +1,108 @@ +This patch backports the makefile changes related to the support/ +framework. It is based on upstream commits +c23de0aacbeaa7a091609b35764bed931475a16d (support: Introduce new +subdirectory for test infrastructure) and +76dcbf42df83c970c13c786d287f1ec69e1b91eb (Expose linking against +libsupport as make dependency). + +The actual contents of the support/ subdirectory is kept in a separate +patch, so that it can be updated separately. + +diff --git a/Makeconfig b/Makeconfig +index 1673eea7f2667aae..948c46420193051d 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -384,6 +384,9 @@ LDFLAGS.so += $(hashstyle-LDFLAGS) + LDFLAGS-rtld += $(hashstyle-LDFLAGS) + endif + ++# Additional libraries to link into every test. ++link-extra-libs-tests = $(libsupport) ++ + # Command for linking PIE programs with the C library. + ifndef +link-pie + +link-pie = $(CC) -pie -Wl,-O1 -nostdlib -nostartfiles -o $@ \ +@@ -464,7 +467,7 @@ link-libc-before-gnulib = -Wl,-rpath-link=$(rpath-link) \ + link-libc = $(link-libc-before-gnulib) $(gnulib) + link-libc-tests = $(link-libc-before-gnulib) $(gnulib-tests) + # This is how to find at build-time things that will be installed there. +-rpath-dirs = math elf dlfcn nss nis rt resolv crypt ++rpath-dirs = math elf dlfcn nss nis rt resolv crypt support + rpath-link = \ + $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%))) + else +@@ -732,7 +735,7 @@ libio-include = -I$(..)libio + # List of non-library modules that we build. + built-modules = iconvprogs iconvdata ldconfig lddlibc4 libmemusage \ + libSegFault libpcprofile librpcsvc locale-programs \ +- memusagestat nonlib nscd extramodules libnldbl ++ memusagestat nonlib nscd extramodules libnldbl libsupport + + in-module = $(subst -,_,$(firstword $(libof-$(basename $(@F))) \ + $(libof-$( +Date: Mon Jan 8 14:33:17 2018 +0100 + + resolv: Support binary labels in test framework + + The old implementation based on hsearch_r used an ad-hoc C string + encoding and produced an incorrect format on the wire for domain + names which contained bytes which needed escaping when printed. + + This commit switches to ns_name_pton for the wire format conversion + (now that we have separate tests for it) and uses a tsearch tree + with a suitable comparison function to locate compression targets. + +diff --git a/scripts/backport-support.sh b/scripts/backport-support.sh +new file mode 100644 +index 0000000000..4057e42d3c +--- /dev/null ++++ b/scripts/backport-support.sh +@@ -0,0 +1,110 @@ ++#!/bin/bash ++# Create a patch which backports the support/ subdirectory. ++# Copyright (C) 2017-2018 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# This script does not backport the Makefile tweaks outside the ++# support/ directory (which need to be backported separately), or the ++# changes to test-skeleton.c (which should not be backported). ++ ++set -e ++ ++export LC_ALL=C ++export GIT_CONFIG=/dev/null ++export GTT_CONFIG_NOSYSTEM=0 ++export GIT_PAGER= ++ ++usage () { ++ cat >&2 <&2 ++ echo "# rm -rf $patch_targets" >&2 ++} ++ ++command_commit () { ++ git status --porcelain | while read line ; do ++ echo "error: working copy is not clean, cannot commit" >&2 ++ exit 1 ++ done ++ for path in $patch_targets; do ++ echo "# Processing $path" >&2 ++ case "$path" in ++ [a-zA-Z0-9]*/) ++ # Directory. ++ git rm --cached --ignore-unmatch -r "$path" ++ rm -rf "$path" ++ git read-tree --prefix="$path" "$latest_commit":"$path" ++ git checkout "$path" ++ ;; ++ *) ++ # File. ++ git show "$latest_commit":"$path" > "$path" ++ git add "$path" ++ esac ++ done ++ git commit -m "Synchronize support/ infrastructure with $branch_name ++ ++This commit updates the support/ subdirectory to ++commit $latest_commit ++on the $branch_name branch. ++" ++} ++ ++command_$command +diff --git a/support/Makefile b/support/Makefile +new file mode 100644 +index 0000000000..1bda81e55e +--- /dev/null ++++ b/support/Makefile +@@ -0,0 +1,171 @@ ++# Makefile for support library, used only at build and test time ++# Copyright (C) 2016-2018 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++ ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++ ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++subdir := support ++ ++include ../Makeconfig ++ ++extra-libs := libsupport ++extra-libs-others = $(extra-libs) ++extra-libs-noinstall := $(extra-libs) ++ ++libsupport-routines = \ ++ check \ ++ check_addrinfo \ ++ check_dns_packet \ ++ check_hostent \ ++ check_netent \ ++ delayed_exit \ ++ ignore_stderr \ ++ next_to_fault \ ++ oom_error \ ++ resolv_test \ ++ set_fortify_handler \ ++ support-xfstat \ ++ support-xstat \ ++ support_become_root \ ++ support_can_chroot \ ++ support_capture_subprocess \ ++ support_capture_subprocess_check \ ++ support_chroot \ ++ support_enter_mount_namespace \ ++ support_enter_network_namespace \ ++ support_format_address_family \ ++ support_format_addrinfo \ ++ support_format_dns_packet \ ++ support_format_herrno \ ++ support_format_hostent \ ++ support_format_netent \ ++ support_isolate_in_subprocess \ ++ support_record_failure \ ++ support_run_diff \ ++ support_shared_allocate \ ++ support_test_compare_failure \ ++ support_write_file_string \ ++ support_test_main \ ++ support_test_verify_impl \ ++ temp_file \ ++ write_message \ ++ xaccept \ ++ xaccept4 \ ++ xasprintf \ ++ xbind \ ++ xcalloc \ ++ xchroot \ ++ xclose \ ++ xconnect \ ++ xdlfcn \ ++ xdup2 \ ++ xfclose \ ++ xfopen \ ++ xfork \ ++ xftruncate \ ++ xgetsockname \ ++ xlisten \ ++ xlseek \ ++ xmalloc \ ++ xmemstream \ ++ xmkdir \ ++ xmmap \ ++ xmprotect \ ++ xmunmap \ ++ xopen \ ++ xpipe \ ++ xpoll \ ++ xpthread_attr_destroy \ ++ xpthread_attr_init \ ++ xpthread_attr_setdetachstate \ ++ xpthread_attr_setguardsize \ ++ xpthread_attr_setstacksize \ ++ xpthread_barrier_destroy \ ++ xpthread_barrier_init \ ++ xpthread_barrier_wait \ ++ xpthread_cancel \ ++ xpthread_check_return \ ++ xpthread_cond_wait \ ++ xpthread_create \ ++ xpthread_detach \ ++ xpthread_join \ ++ xpthread_mutex_consistent \ ++ xpthread_mutex_destroy \ ++ xpthread_mutex_init \ ++ xpthread_mutex_lock \ ++ xpthread_mutex_unlock \ ++ xpthread_mutexattr_destroy \ ++ xpthread_mutexattr_init \ ++ xpthread_mutexattr_setprotocol \ ++ xpthread_mutexattr_setpshared \ ++ xpthread_mutexattr_setrobust \ ++ xpthread_mutexattr_settype \ ++ xpthread_once \ ++ xpthread_rwlock_init \ ++ xpthread_rwlock_rdlock \ ++ xpthread_rwlock_unlock \ ++ xpthread_rwlock_wrlock \ ++ xpthread_rwlockattr_init \ ++ xpthread_rwlockattr_setkind_np \ ++ xpthread_sigmask \ ++ xpthread_spin_lock \ ++ xpthread_spin_unlock \ ++ xraise \ ++ xreadlink \ ++ xrealloc \ ++ xrecvfrom \ ++ xsendto \ ++ xsetsockopt \ ++ xsigaction \ ++ xsignal \ ++ xsocket \ ++ xstrdup \ ++ xstrndup \ ++ xsysconf \ ++ xunlink \ ++ xwaitpid \ ++ xwrite \ ++ ++libsupport-static-only-routines := $(libsupport-routines) ++# Only build one variant of the library. ++libsupport-inhibit-o := .os ++ifeq ($(build-shared),yes) ++libsupport-inhibit-o += .o ++endif ++ ++tests = \ ++ README-testing \ ++ tst-support-namespace \ ++ tst-support_capture_subprocess \ ++ tst-support_format_dns_packet \ ++ tst-support_record_failure \ ++ tst-test_compare \ ++ tst-xreadlink \ ++ ++ifeq ($(run-built-tests),yes) ++tests-special = \ ++ $(objpfx)tst-support_record_failure-2.out ++ ++$(objpfx)tst-support_record_failure-2.out: tst-support_record_failure-2.sh \ ++ $(objpfx)tst-support_record_failure ++ $(SHELL) $< $(common-objpfx) '$(test-program-prefix-before-env)' \ ++ '$(run-program-env)' '$(test-program-prefix-after-env)' \ ++ > $@; \ ++ $(evaluate-test) ++endif ++ ++$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so ++ ++include ../Rules +diff --git a/support/README b/support/README +new file mode 100644 +index 0000000000..476cfcda59 +--- /dev/null ++++ b/support/README +@@ -0,0 +1,29 @@ ++This subdirectory contains infrastructure which is not put into ++installed libraries, but may be linked into programs (installed or ++not) and tests. ++ ++# Error-checking wrappers ++ ++These wrappers test for error return codes an terminate the process on ++error. They are declared in these header files: ++ ++* support.h ++* xsignal.h ++* xthread.h ++ ++In general, new wrappers should be added to support.h if possible. ++However, support.h must remain fully compatible with C90 and therefore ++cannot include headers which use identifers not reserved in C90. If ++the wrappers need additional types, additional headers such as ++signal.h need to be introduced. ++ ++# Test framework ++ ++The test framework provides a main program for tests, including a ++timeout for hanging tests. See README-testing.c for a minimal ++example, and test-driver.c for details how to use it. The following ++header files provide related declarations: ++ ++* check.h ++* temp_file.h ++* test-driver.h +diff --git a/support/README-testing.c b/support/README-testing.c +new file mode 100644 +index 0000000000..9d289c3020 +--- /dev/null ++++ b/support/README-testing.c +@@ -0,0 +1,19 @@ ++/* This file contains an example test case which shows minimal use of ++ the test framework. Additional testing hooks are described in ++ . */ ++ ++/* This function will be called from the test driver. */ ++static int ++do_test (void) ++{ ++ if (3 == 5) ++ /* Indicate failure. */ ++ return 1; ++ else ++ /* Indicate success. */ ++ return 0; ++} ++ ++/* This file references do_test above and contains the definition of ++ the main function. */ ++#include +diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h +new file mode 100644 +index 0000000000..b0886ba1d1 +--- /dev/null ++++ b/support/capture_subprocess.h +@@ -0,0 +1,61 @@ ++/* Capture output from a subprocess. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_CAPTURE_SUBPROCESS_H ++#define SUPPORT_CAPTURE_SUBPROCESS_H ++ ++#include ++ ++struct support_capture_subprocess ++{ ++ struct xmemstream out; ++ struct xmemstream err; ++ int status; ++}; ++ ++/* Invoke CALLBACK (CLOSURE) in a subprocess and capture standard ++ output, standard error, and the exit status. The out.buffer and ++ err.buffer members in the result are null-terminated strings which ++ can be examined by the caller (out.out and err.out are NULL). */ ++struct support_capture_subprocess support_capture_subprocess ++ (void (*callback) (void *), void *closure); ++ ++/* Deallocate the subprocess data captured by ++ support_capture_subprocess. */ ++void support_capture_subprocess_free (struct support_capture_subprocess *); ++ ++enum support_capture_allow ++{ ++ /* No output is allowed. */ ++ sc_allow_none = 0x01, ++ /* Output to stdout is permitted. */ ++ sc_allow_stdout = 0x02, ++ /* Output to standard error is permitted. */ ++ sc_allow_stderr = 0x04, ++}; ++ ++/* Check that the subprocess exited with STATUS and that only the ++ allowed outputs happened. ALLOWED is a combination of ++ support_capture_allow flags. Report errors under the CONTEXT ++ message. */ ++void support_capture_subprocess_check (struct support_capture_subprocess *, ++ const char *context, int status, ++ int allowed) ++ __attribute__ ((nonnull (1, 2))); ++ ++#endif /* SUPPORT_CAPTURE_SUBPROCESS_H */ +diff --git a/support/check.c b/support/check.c +new file mode 100644 +index 0000000000..688ed569ac +--- /dev/null ++++ b/support/check.c +@@ -0,0 +1,57 @@ ++/* Support code for reporting test results. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++static void ++print_failure (const char *file, int line, const char *format, va_list ap) ++{ ++ printf ("error: %s:%d: ", file, line); ++ vprintf (format, ap); ++ puts (""); ++} ++ ++int ++support_print_failure_impl (const char *file, int line, ++ const char *format, ...) ++{ ++ support_record_failure (); ++ va_list ap; ++ va_start (ap, format); ++ print_failure (file, line, format, ap); ++ va_end (ap); ++ return 1; ++} ++ ++void ++support_exit_failure_impl (int status, const char *file, int line, ++ const char *format, ...) ++{ ++ if (status != EXIT_SUCCESS && status != EXIT_UNSUPPORTED) ++ support_record_failure (); ++ va_list ap; ++ va_start (ap, format); ++ print_failure (file, line, format, ap); ++ va_end (ap); ++ exit (status); ++} +diff --git a/support/check.h b/support/check.h +new file mode 100644 +index 0000000000..2192f38941 +--- /dev/null ++++ b/support/check.h +@@ -0,0 +1,153 @@ ++/* Functionality for reporting test results. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_CHECK_H ++#define SUPPORT_CHECK_H ++ ++#include ++ ++__BEGIN_DECLS ++ ++/* Record a test failure, print the failure message to standard output ++ and return 1. */ ++#define FAIL_RET(...) \ ++ return support_print_failure_impl (__FILE__, __LINE__, __VA_ARGS__) ++ ++/* Print the failure message and terminate the process with STATUS. ++ Record a the process as failed if STATUS is neither EXIT_SUCCESS ++ nor EXIT_UNSUPPORTED. */ ++#define FAIL_EXIT(status, ...) \ ++ support_exit_failure_impl (status, __FILE__, __LINE__, __VA_ARGS__) ++ ++/* Record a test failure, print the failure message and terminate with ++ exit status 1. */ ++#define FAIL_EXIT1(...) \ ++ support_exit_failure_impl (1, __FILE__, __LINE__, __VA_ARGS__) ++ ++/* Print failure message and terminate with as unsupported test (exit ++ status of 77). */ ++#define FAIL_UNSUPPORTED(...) \ ++ support_exit_failure_impl (77, __FILE__, __LINE__, __VA_ARGS__) ++ ++/* Record a test failure (but continue executing) if EXPR evaluates to ++ false. */ ++#define TEST_VERIFY(expr) \ ++ ({ \ ++ if (expr) \ ++ ; \ ++ else \ ++ support_test_verify_impl (__FILE__, __LINE__, #expr); \ ++ }) ++ ++/* Record a test failure and exit if EXPR evaluates to false. */ ++#define TEST_VERIFY_EXIT(expr) \ ++ ({ \ ++ if (expr) \ ++ ; \ ++ else \ ++ support_test_verify_exit_impl \ ++ (1, __FILE__, __LINE__, #expr); \ ++ }) ++ ++int support_print_failure_impl (const char *file, int line, ++ const char *format, ...) ++ __attribute__ ((nonnull (1), format (printf, 3, 4))); ++void support_exit_failure_impl (int exit_status, ++ const char *file, int line, ++ const char *format, ...) ++ __attribute__ ((noreturn, nonnull (2), format (printf, 4, 5))); ++void support_test_verify_impl (const char *file, int line, ++ const char *expr); ++void support_test_verify_exit_impl (int status, const char *file, int line, ++ const char *expr) ++ __attribute__ ((noreturn)); ++ ++/* Record a test failure. This function returns and does not ++ terminate the process. The failure counter is stored in a shared ++ memory mapping, so that failures reported in child processes are ++ visible to the parent process and test driver. This function ++ depends on initialization by an ELF constructor, so it can only be ++ invoked after the test driver has run. Note that this function ++ does not support reporting failures from a DSO. */ ++void support_record_failure (void); ++ ++/* Static assertion, under a common name for both C++ and C11. */ ++#ifdef __cplusplus ++# define support_static_assert static_assert ++#else ++# define support_static_assert _Static_assert ++#endif ++ ++/* Compare the two integers LEFT and RIGHT and report failure if they ++ are different. */ ++#define TEST_COMPARE(left, right) \ ++ ({ \ ++ /* + applies the integer promotions, for bitfield support. */ \ ++ typedef __typeof__ (+ (left)) __left_type; \ ++ typedef __typeof__ (+ (right)) __right_type; \ ++ __left_type __left_value = (left); \ ++ __right_type __right_value = (right); \ ++ int __left_is_positive = __left_value > 0; \ ++ int __right_is_positive = __right_value > 0; \ ++ /* Prevent use with floating-point types. */ \ ++ support_static_assert ((__left_type) 1.0 == (__left_type) 1.5, \ ++ "left value has floating-point type"); \ ++ support_static_assert ((__right_type) 1.0 == (__right_type) 1.5, \ ++ "right value has floating-point type"); \ ++ /* Prevent accidental use with larger-than-long long types. */ \ ++ support_static_assert (sizeof (__left_value) <= sizeof (long long), \ ++ "left value fits into long long"); \ ++ support_static_assert (sizeof (__right_value) <= sizeof (long long), \ ++ "right value fits into long long"); \ ++ /* Compare the value. */ \ ++ if (__left_value != __right_value \ ++ || __left_is_positive != __right_is_positive) \ ++ /* Pass the sign for printing the correct value. */ \ ++ support_test_compare_failure \ ++ (__FILE__, __LINE__, \ ++ #left, __left_value, __left_is_positive, sizeof (__left_type), \ ++ #right, __right_value, __right_is_positive, sizeof (__right_type)); \ ++ }) ++ ++/* Internal implementation of TEST_COMPARE. LEFT_POSITIVE and ++ RIGHT_POSITIVE are used to store the sign separately, so that both ++ unsigned long long and long long arguments fit into LEFT_VALUE and ++ RIGHT_VALUE, and the function can still print the original value. ++ LEFT_SIZE and RIGHT_SIZE specify the size of the argument in bytes, ++ for hexadecimal formatting. */ ++void support_test_compare_failure (const char *file, int line, ++ const char *left_expr, ++ long long left_value, ++ int left_positive, ++ int left_size, ++ const char *right_expr, ++ long long right_value, ++ int right_positive, ++ int right_size); ++ ++ ++/* Internal function called by the test driver. */ ++int support_report_failure (int status) ++ __attribute__ ((weak, warn_unused_result)); ++ ++/* Internal function used to test the failure recording framework. */ ++void support_record_failure_reset (void); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_CHECK_H */ +diff --git a/support/check_addrinfo.c b/support/check_addrinfo.c +new file mode 100644 +index 0000000000..91ad7c56bd +--- /dev/null ++++ b/support/check_addrinfo.c +@@ -0,0 +1,43 @@ ++/* Compare struct addrinfo values against a formatted string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++check_addrinfo (const char *query_description, struct addrinfo *ai, int ret, ++ const char *expected) ++{ ++ char *formatted = support_format_addrinfo (ai, ret); ++ if (strcmp (formatted, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: addrinfo comparison failure\n"); ++ if (query_description != NULL) ++ printf ("query: %s\n", query_description); ++ support_run_diff ("expected", expected, ++ "actual", formatted); ++ } ++ free (formatted); ++} +diff --git a/support/check_dns_packet.c b/support/check_dns_packet.c +new file mode 100644 +index 0000000000..6c1277bd67 +--- /dev/null ++++ b/support/check_dns_packet.c +@@ -0,0 +1,43 @@ ++/* Check that a DNS packet buffer has the expected contents. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++check_dns_packet (const char *query_description, ++ const unsigned char *buffer, size_t length, ++ const char *expected) ++{ ++ char *formatted = support_format_dns_packet (buffer, length); ++ if (strcmp (formatted, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: packet comparison failure\n"); ++ if (query_description != NULL) ++ printf ("query: %s\n", query_description); ++ support_run_diff ("expected", expected, "actual", formatted); ++ } ++ free (formatted); ++} +diff --git a/support/check_hostent.c b/support/check_hostent.c +new file mode 100644 +index 0000000000..56384f9b03 +--- /dev/null ++++ b/support/check_hostent.c +@@ -0,0 +1,43 @@ ++/* Compare struct hostent values against a formatted string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++check_hostent (const char *query_description, struct hostent *h, ++ const char *expected) ++{ ++ char *formatted = support_format_hostent (h); ++ if (strcmp (formatted, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: hostent comparison failure\n"); ++ if (query_description != NULL) ++ printf ("query: %s\n", query_description); ++ support_run_diff ("expected", expected, ++ "actual", formatted); ++ } ++ free (formatted); ++} +diff --git a/support/check_netent.c b/support/check_netent.c +new file mode 100644 +index 0000000000..cbcbfb14e5 +--- /dev/null ++++ b/support/check_netent.c +@@ -0,0 +1,43 @@ ++/* Compare struct netent values against a formatted string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ++check_netent (const char *query_description, struct netent *e, ++ const char *expected) ++{ ++ char *formatted = support_format_netent (e); ++ if (strcmp (formatted, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: netent comparison failure\n"); ++ if (query_description != NULL) ++ printf ("query: %s\n", query_description); ++ support_run_diff ("expected", expected, ++ "actual", formatted); ++ } ++ free (formatted); ++} +diff --git a/support/check_nss.h b/support/check_nss.h +new file mode 100644 +index 0000000000..6aa28fa24e +--- /dev/null ++++ b/support/check_nss.h +@@ -0,0 +1,42 @@ ++/* Test verification functions for NSS- and DNS-related data. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_CHECK_NSS_H ++#define SUPPORT_CHECK_NSS_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Compare the data structures against the expected values (which have ++ to be formatted according to the support_format_* functions in ++ ). If there is a difference, a delayed test ++ failure is recorded, and a diff is written to standard output. */ ++void check_addrinfo (const char *query_description, ++ struct addrinfo *, int ret, const char *expected); ++void check_dns_packet (const char *query_description, ++ const unsigned char *, size_t, const char *expected); ++void check_hostent (const char *query_description, ++ struct hostent *, const char *expected); ++void check_netent (const char *query_description, ++ struct netent *, const char *expected); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_CHECK_NSS_H */ +diff --git a/support/delayed_exit.c b/support/delayed_exit.c +new file mode 100644 +index 0000000000..2780d9a6fe +--- /dev/null ++++ b/support/delayed_exit.c +@@ -0,0 +1,55 @@ ++/* Time-triggered process termination. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static void * ++delayed_exit_thread (void *seconds_as_ptr) ++{ ++ int seconds = (uintptr_t) seconds_as_ptr; ++ struct timespec delay = { seconds, 0 }; ++ struct timespec remaining = { 0 }; ++ if (nanosleep (&delay, &remaining) != 0) ++ FAIL_EXIT1 ("nanosleep: %m"); ++ /* Exit the process sucessfully. */ ++ exit (0); ++ return NULL; ++} ++ ++void ++delayed_exit (int seconds) ++{ ++ /* Create the new thread with all signals blocked. */ ++ sigset_t all_blocked; ++ sigfillset (&all_blocked); ++ sigset_t old_set; ++ xpthread_sigmask (SIG_SETMASK, &all_blocked, &old_set); ++ /* Create a detached thread. */ ++ pthread_t thr = xpthread_create ++ (NULL, delayed_exit_thread, (void *) (uintptr_t) seconds); ++ xpthread_detach (thr); ++ /* Restore the original signal mask. */ ++ xpthread_sigmask (SIG_SETMASK, &old_set, NULL); ++} +diff --git a/support/format_nss.h b/support/format_nss.h +new file mode 100644 +index 0000000000..e55354e788 +--- /dev/null ++++ b/support/format_nss.h +@@ -0,0 +1,41 @@ ++/* String formatting functions for NSS- and DNS-related data. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_FORMAT_NSS_H ++#define SUPPORT_FORMAT_NSS_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* The following functions format their arguments as human-readable ++ strings (which can span multiple lines). The caller must free the ++ returned buffer. For NULL pointers or failure status arguments, ++ error variables such as h_errno and errno are included in the ++ result. */ ++char *support_format_address_family (int); ++char *support_format_addrinfo (struct addrinfo *, int ret); ++char *support_format_dns_packet (const unsigned char *buffer, size_t length); ++char *support_format_herrno (int); ++char *support_format_hostent (struct hostent *); ++char *support_format_netent (struct netent *); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_FORMAT_NSS_H */ +diff --git a/support/ignore_stderr.c b/support/ignore_stderr.c +new file mode 100644 +index 0000000000..450333ad38 +--- /dev/null ++++ b/support/ignore_stderr.c +@@ -0,0 +1,38 @@ ++/* Avoid all the buffer overflow messages on stderr. ++ Copyright (C) 2015-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++void ++ignore_stderr (void) ++{ ++ int fd = open (_PATH_DEVNULL, O_WRONLY); ++ if (fd == -1) ++ close (STDERR_FILENO); ++ else ++ { ++ dup2 (fd, STDERR_FILENO); ++ close (fd); ++ } ++ setenv ("LIBC_FATAL_STDERR_", "1", 1); ++} +diff --git a/support/namespace.h b/support/namespace.h +new file mode 100644 +index 0000000000..3c3842a49b +--- /dev/null ++++ b/support/namespace.h +@@ -0,0 +1,107 @@ ++/* Entering namespaces for test case isolation. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_NAMESPACE_H ++#define SUPPORT_NAMESPACE_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Attempts to become root (or acquire root-like privileges), possibly ++ with the help of user namespaces. Return true if (restricted) root ++ privileges could be attained in some way. Print diagnostics to ++ standard output. ++ ++ Note that this function generally has to be called before a process ++ becomes multi-threaded, otherwise it may fail with insufficient ++ privileges on systems which would support this operation for ++ single-threaded processes. */ ++bool support_become_root (void); ++ ++/* Return true if this process can perform a chroot operation. In ++ general, this is only possible if support_become_root has been ++ called. Note that the actual test is performed in a subprocess, ++ after fork, so that the file system root of the original process is ++ not changed. */ ++bool support_can_chroot (void); ++ ++/* Enter a network namespace (and a UTS namespace if possible) and ++ configure the loopback interface. Return true if a network ++ namespace could be created. Print diagnostics to standard output. ++ If a network namespace could be created, but networking in it could ++ not be configured, terminate the process. It is recommended to ++ call support_become_root before this function so that the process ++ has sufficient privileges. */ ++bool support_enter_network_namespace (void); ++ ++/* Enter a mount namespace and mark / as private (not shared). If ++ this function returns true, mount operations in this process will ++ not affect the host system afterwards. */ ++bool support_enter_mount_namespace (void); ++ ++/* Return true if support_enter_network_namespace managed to enter a ++ UTS namespace. */ ++bool support_in_uts_namespace (void); ++ ++/* Invoke CALLBACK (CLOSURE) in a subprocess created using fork. ++ Terminate the calling process if the subprocess exits with a ++ non-zero exit status. */ ++void support_isolate_in_subprocess (void (*callback) (void *), void *closure); ++ ++/* Describe the setup of a chroot environment, for ++ support_chroot_create below. */ ++struct support_chroot_configuration ++{ ++ /* File contents. The files are not created if the field is ++ NULL. */ ++ const char *resolv_conf; /* /etc/resolv.conf. */ ++ const char *hosts; /* /etc/hosts. */ ++ const char *host_conf; /* /etc/host.conf. */ ++}; ++ ++/* The result of the creation of a chroot. */ ++struct support_chroot ++{ ++ /* Path information. All these paths are relative to the parent ++ chroot. */ ++ ++ /* Path to the chroot directory. */ ++ char *path_chroot; ++ ++ /* Paths to files in the chroot. These are absolute and outside of ++ the chroot. */ ++ char *path_resolv_conf; /* /etc/resolv.conf. */ ++ char *path_hosts; /* /etc/hosts. */ ++ char *path_host_conf; /* /etc/host.conf. */ ++}; ++ ++/* Create a chroot environment. The returned data should be freed ++ using support_chroot_free below. The files will be deleted when ++ the process exits. This function does not enter the chroot. */ ++struct support_chroot *support_chroot_create ++ (struct support_chroot_configuration); ++ ++/* Deallocate the chroot information created by ++ support_chroot_create. */ ++void support_chroot_free (struct support_chroot *); ++ ++__END_DECLS ++ ++#endif +diff --git a/support/next_to_fault.c b/support/next_to_fault.c +new file mode 100644 +index 0000000000..1971bf7cd7 +--- /dev/null ++++ b/support/next_to_fault.c +@@ -0,0 +1,52 @@ ++/* Memory allocation next to an unmapped page. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct support_next_to_fault ++support_next_to_fault_allocate (size_t size) ++{ ++ long page_size = sysconf (_SC_PAGE_SIZE); ++ TEST_VERIFY_EXIT (page_size > 0); ++ struct support_next_to_fault result; ++ result.region_size = roundup (size, page_size) + page_size; ++ if (size + page_size <= size || result.region_size <= size) ++ FAIL_EXIT1 ("support_next_to_fault_allocate (%zu): overflow", size); ++ result.region_start ++ = xmmap (NULL, result.region_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ /* Unmap the page after the allocation. */ ++ xmprotect (result.region_start + (result.region_size - page_size), ++ page_size, PROT_NONE); ++ /* Align the allocation within the region so that it ends just ++ before the PROT_NONE page. */ ++ result.buffer = result.region_start + result.region_size - page_size - size; ++ result.length = size; ++ return result; ++} ++ ++void ++support_next_to_fault_free (struct support_next_to_fault *ntf) ++{ ++ xmunmap (ntf->region_start, ntf->region_size); ++ *ntf = (struct support_next_to_fault) { NULL, }; ++} +diff --git a/support/next_to_fault.h b/support/next_to_fault.h +new file mode 100644 +index 0000000000..75759b586c +--- /dev/null ++++ b/support/next_to_fault.h +@@ -0,0 +1,48 @@ ++/* Memory allocation next to an unmapped page. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_NEXT_TO_FAULT_H ++#define SUPPORT_NEXT_TO_FAULT_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* The memory region created by next_to_fault_allocate. */ ++struct support_next_to_fault ++{ ++ /* The user data. */ ++ char *buffer; ++ size_t length; ++ ++ /* The entire allocated region. */ ++ void *region_start; ++ size_t region_size; ++}; ++ ++/* Allocate a buffer of SIZE bytes just before a page which is mapped ++ with PROT_NONE (so that overrunning the buffer will cause a ++ fault). */ ++struct support_next_to_fault support_next_to_fault_allocate (size_t size); ++ ++/* Deallocate the memory region allocated by ++ next_to_fault_allocate. */ ++void support_next_to_fault_free (struct support_next_to_fault *); ++ ++#endif /* SUPPORT_NEXT_TO_FAULT_H */ +diff --git a/support/oom_error.c b/support/oom_error.c +new file mode 100644 +index 0000000000..fd87fe2305 +--- /dev/null ++++ b/support/oom_error.c +@@ -0,0 +1,29 @@ ++/* Reporting out-of-memory errors. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++void ++oom_error (const char *function, size_t size) ++{ ++ printf ("%s: unable to allocate %zu bytes: %m\n", function, size); ++ exit (1); ++} +diff --git a/support/resolv_test.c b/support/resolv_test.c +new file mode 100644 +index 0000000000..3f2a09f36f +--- /dev/null ++++ b/support/resolv_test.c +@@ -0,0 +1,1263 @@ ++/* DNS test framework and libresolv redirection. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Response builder. */ ++ ++enum ++ { ++ max_response_length = 65536 ++ }; ++ ++/* Used for locating domain names containing for the purpose of ++ forming compression references. */ ++struct compressed_name ++{ ++ uint16_t offset; ++ unsigned char length; ++ unsigned char name[]; /* Without terminating NUL. */ ++}; ++ ++static struct compressed_name * ++allocate_compressed_name (const unsigned char *encoded, unsigned int offset) ++{ ++ /* Compute the length of the domain name. */ ++ size_t length; ++ { ++ const unsigned char *p; ++ for (p = encoded; *p != '\0';) ++ { ++ /* No compression references are allowed. */ ++ TEST_VERIFY (*p <= 63); ++ /* Skip over the label. */ ++ p += 1 + *p; ++ } ++ length = p - encoded; ++ ++length; /* For the terminating NUL byte. */ ++ } ++ TEST_VERIFY_EXIT (length <= 255); ++ ++ struct compressed_name *result ++ = xmalloc (offsetof (struct compressed_name, name) + length); ++ result->offset = offset; ++ result->length = length; ++ memcpy (result->name, encoded, length); ++ return result; ++} ++ ++/* Convert CH to lower case. Only change letters in the ASCII ++ range. */ ++static inline unsigned char ++ascii_tolower (unsigned char ch) ++{ ++ if ('A' <= ch && ch <= 'Z') ++ return ch - 'A' + 'a'; ++ else ++ return ch; ++} ++ ++/* Compare both names, for use with tsearch. The order is arbitrary, ++ but the comparison is case-insenstive. */ ++static int ++compare_compressed_name (const void *left, const void *right) ++{ ++ const struct compressed_name *crleft = left; ++ const struct compressed_name *crright = right; ++ ++ if (crleft->length != crright->length) ++ /* The operands are converted to int before the subtraction. */ ++ return crleft->length - crright->length; ++ ++ const unsigned char *nameleft = crleft->name; ++ const unsigned char *nameright = crright->name; ++ ++ while (true) ++ { ++ int lenleft = *nameleft++; ++ int lenright = *nameright++; ++ ++ /* Labels must not e compression references. */ ++ TEST_VERIFY (lenleft <= 63); ++ TEST_VERIFY (lenright <= 63); ++ ++ if (lenleft != lenright) ++ return left - right; ++ if (lenleft == 0) ++ /* End of name reached without spotting a difference. */ ++ return 0; ++ /* Compare the label in a case-insenstive manner. */ ++ const unsigned char *endnameleft = nameleft + lenleft; ++ while (nameleft < endnameleft) ++ { ++ int l = *nameleft++; ++ int r = *nameright++; ++ if (l != r) ++ { ++ l = ascii_tolower (l); ++ r = ascii_tolower (r); ++ if (l != r) ++ return l - r; ++ } ++ } ++ } ++} ++ ++struct resolv_response_builder ++{ ++ const unsigned char *query_buffer; ++ size_t query_length; ++ ++ size_t offset; /* Bytes written so far in buffer. */ ++ ns_sect section; /* Current section in the DNS packet. */ ++ unsigned int truncate_bytes; /* Bytes to remove at end of response. */ ++ bool drop; /* Discard generated response. */ ++ bool close; /* Close TCP client connection. */ ++ ++ /* Offset of the two-byte RDATA length field in the currently ++ written RDATA sub-structure. 0 if no RDATA is being written. */ ++ size_t current_rdata_offset; ++ ++ /* tsearch tree for locating targets for label compression. */ ++ void *compression_offsets; ++ ++ /* Must be last. Not zeroed for performance reasons. */ ++ unsigned char buffer[max_response_length]; ++}; ++ ++/* Response builder. */ ++ ++void ++resolv_response_init (struct resolv_response_builder *b, ++ struct resolv_response_flags flags) ++{ ++ if (b->offset > 0) ++ FAIL_EXIT1 ("response_init: called at offset %zu", b->offset); ++ if (b->query_length < 12) ++ FAIL_EXIT1 ("response_init called for a query of size %zu", ++ b->query_length); ++ if (flags.rcode > 15) ++ FAIL_EXIT1 ("response_init: invalid RCODE %u", flags.rcode); ++ ++ /* Copy the transaction ID. */ ++ b->buffer[0] = b->query_buffer[0]; ++ b->buffer[1] = b->query_buffer[1]; ++ ++ /* Initialize the flags. */ ++ b->buffer[2] = 0x80; /* Mark as response. */ ++ b->buffer[2] |= b->query_buffer[2] & 0x01; /* Copy the RD bit. */ ++ if (flags.tc) ++ b->buffer[2] |= 0x02; ++ b->buffer[3] = 0x80 | flags.rcode; /* Always set RA. */ ++ ++ /* Fill in the initial section count values. */ ++ b->buffer[4] = flags.qdcount >> 8; ++ b->buffer[5] = flags.qdcount; ++ b->buffer[6] = flags.ancount >> 8; ++ b->buffer[7] = flags.ancount; ++ b->buffer[8] = flags.nscount >> 8; ++ b->buffer[9] = flags.nscount; ++ b->buffer[10] = flags.adcount >> 8; ++ b->buffer[11] = flags.adcount; ++ ++ b->offset = 12; ++} ++ ++void ++resolv_response_section (struct resolv_response_builder *b, ns_sect section) ++{ ++ if (b->offset == 0) ++ FAIL_EXIT1 ("resolv_response_section: response_init not called before"); ++ if (section < b->section) ++ FAIL_EXIT1 ("resolv_response_section: cannot go back to previous section"); ++ b->section = section; ++} ++ ++/* Add a single byte to B. */ ++static inline void ++response_add_byte (struct resolv_response_builder *b, unsigned char ch) ++{ ++ if (b->offset == max_response_length) ++ FAIL_EXIT1 ("DNS response exceeds 64 KiB limit"); ++ b->buffer[b->offset] = ch; ++ ++b->offset; ++} ++ ++/* Add a 16-bit word VAL to B, in big-endian format. */ ++static void ++response_add_16 (struct resolv_response_builder *b, uint16_t val) ++{ ++ response_add_byte (b, val >> 8); ++ response_add_byte (b, val); ++} ++ ++/* Increment the pers-section record counter in the packet header. */ ++static void ++response_count_increment (struct resolv_response_builder *b) ++{ ++ unsigned int offset = b->section; ++ offset = 4 + 2 * offset; ++ ++b->buffer[offset + 1]; ++ if (b->buffer[offset + 1] == 0) ++ { ++ /* Carry. */ ++ ++b->buffer[offset]; ++ if (b->buffer[offset] == 0) ++ /* Overflow. */ ++ FAIL_EXIT1 ("too many records in section"); ++ } ++} ++ ++void ++resolv_response_add_question (struct resolv_response_builder *b, ++ const char *name, uint16_t class, uint16_t type) ++{ ++ if (b->offset == 0) ++ FAIL_EXIT1 ("resolv_response_add_question: " ++ "resolv_response_init not called"); ++ if (b->section != ns_s_qd) ++ FAIL_EXIT1 ("resolv_response_add_question: " ++ "must be called in the question section"); ++ ++ resolv_response_add_name (b, name); ++ response_add_16 (b, type); ++ response_add_16 (b, class); ++ ++ response_count_increment (b); ++} ++ ++void ++resolv_response_add_name (struct resolv_response_builder *b, ++ const char *const origname) ++{ ++ unsigned char encoded_name[NS_MAXDNAME]; ++ if (ns_name_pton (origname, encoded_name, sizeof (encoded_name)) < 0) ++ FAIL_EXIT1 ("ns_name_pton (\"%s\"): %m", origname); ++ ++ /* Copy the encoded name into the output buffer, apply compression ++ where possible. */ ++ for (const unsigned char *name = encoded_name; ;) ++ { ++ if (*name == '\0') ++ { ++ /* We have reached the end of the name. Add the terminating ++ NUL byte. */ ++ response_add_byte (b, '\0'); ++ break; ++ } ++ ++ /* Set to the compression target if compression is possible. */ ++ struct compressed_name *crname_target; ++ ++ /* Compression references can only reach the beginning of the ++ packet. */ ++ enum { compression_limit = 1 << 12 }; ++ ++ { ++ /* The trailing part of the name to be looked up in the tree ++ with the compression targets. */ ++ struct compressed_name *crname ++ = allocate_compressed_name (name, b->offset); ++ ++ if (b->offset < compression_limit) ++ { ++ /* Add the name to the tree, for future compression ++ references. */ ++ void **ptr = tsearch (crname, &b->compression_offsets, ++ compare_compressed_name); ++ if (ptr == NULL) ++ FAIL_EXIT1 ("tsearch out of memory"); ++ crname_target = *ptr; ++ ++ if (crname_target != crname) ++ /* The new name was not actually added to the tree. ++ Deallocate it. */ ++ free (crname); ++ else ++ /* Signal that the tree did not yet contain the name, ++ but keep the allocation because it is now part of the ++ tree. */ ++ crname_target = NULL; ++ } ++ else ++ { ++ /* This name cannot be reached by a compression reference. ++ No need to add it to the tree for future reference. */ ++ void **ptr = tfind (crname, &b->compression_offsets, ++ compare_compressed_name); ++ if (ptr != NULL) ++ crname_target = *ptr; ++ else ++ crname_target = NULL; ++ TEST_VERIFY (crname_target != crname); ++ /* Not added to the tree. */ ++ free (crname); ++ } ++ } ++ ++ if (crname_target != NULL) ++ { ++ /* The name is known. Reference the previous location. */ ++ unsigned int old_offset = crname_target->offset; ++ TEST_VERIFY_EXIT (old_offset < compression_limit); ++ response_add_byte (b, 0xC0 | (old_offset >> 8)); ++ response_add_byte (b, old_offset); ++ break; ++ } ++ else ++ { ++ /* The name is new. Add this label. */ ++ unsigned int len = 1 + *name; ++ resolv_response_add_data (b, name, len); ++ name += len; ++ } ++ } ++} ++ ++void ++resolv_response_open_record (struct resolv_response_builder *b, ++ const char *name, ++ uint16_t class, uint16_t type, uint32_t ttl) ++{ ++ if (b->section == ns_s_qd) ++ FAIL_EXIT1 ("resolv_response_open_record called in question section"); ++ if (b->current_rdata_offset != 0) ++ FAIL_EXIT1 ("resolv_response_open_record called with open record"); ++ ++ resolv_response_add_name (b, name); ++ response_add_16 (b, type); ++ response_add_16 (b, class); ++ response_add_16 (b, ttl >> 16); ++ response_add_16 (b, ttl); ++ ++ b->current_rdata_offset = b->offset; ++ /* Add room for the RDATA length. */ ++ response_add_16 (b, 0); ++} ++ ++ ++void ++resolv_response_close_record (struct resolv_response_builder *b) ++{ ++ size_t rdata_offset = b->current_rdata_offset; ++ if (rdata_offset == 0) ++ FAIL_EXIT1 ("response_close_record called without open record"); ++ size_t rdata_length = b->offset - rdata_offset - 2; ++ if (rdata_length > 65535) ++ FAIL_EXIT1 ("RDATA length %zu exceeds limit", rdata_length); ++ b->buffer[rdata_offset] = rdata_length >> 8; ++ b->buffer[rdata_offset + 1] = rdata_length; ++ response_count_increment (b); ++ b->current_rdata_offset = 0; ++} ++ ++void ++resolv_response_add_data (struct resolv_response_builder *b, ++ const void *data, size_t length) ++{ ++ size_t remaining = max_response_length - b->offset; ++ if (remaining < length) ++ FAIL_EXIT1 ("resolv_response_add_data: not enough room for %zu bytes", ++ length); ++ memcpy (b->buffer + b->offset, data, length); ++ b->offset += length; ++} ++ ++void ++resolv_response_drop (struct resolv_response_builder *b) ++{ ++ b->drop = true; ++} ++ ++void ++resolv_response_close (struct resolv_response_builder *b) ++{ ++ b->close = true; ++} ++ ++void ++resolv_response_truncate_data (struct resolv_response_builder *b, size_t count) ++{ ++ if (count > 65535) ++ FAIL_EXIT1 ("resolv_response_truncate_data: argument too large: %zu", ++ count); ++ b->truncate_bytes = count; ++} ++ ++ ++size_t ++resolv_response_length (const struct resolv_response_builder *b) ++{ ++ return b->offset; ++} ++ ++unsigned char * ++resolv_response_buffer (const struct resolv_response_builder *b) ++{ ++ unsigned char *result = xmalloc (b->offset); ++ memcpy (result, b->buffer, b->offset); ++ return result; ++} ++ ++static struct resolv_response_builder * ++response_builder_allocate ++ (const unsigned char *query_buffer, size_t query_length) ++{ ++ struct resolv_response_builder *b = xmalloc (sizeof (*b)); ++ memset (b, 0, offsetof (struct resolv_response_builder, buffer)); ++ b->query_buffer = query_buffer; ++ b->query_length = query_length; ++ return b; ++} ++ ++static void ++response_builder_free (struct resolv_response_builder *b) ++{ ++ tdestroy (b->compression_offsets, free); ++ free (b); ++} ++ ++/* DNS query processing. */ ++ ++/* Data extracted from the question section of a DNS packet. */ ++struct query_info ++{ ++ char qname[MAXDNAME]; ++ uint16_t qclass; ++ uint16_t qtype; ++ struct resolv_edns_info edns; ++}; ++ ++/* Update *INFO from the specified DNS packet. */ ++static void ++parse_query (struct query_info *info, ++ const unsigned char *buffer, size_t length) ++{ ++ HEADER hd; ++ _Static_assert (sizeof (hd) == 12, "DNS header size"); ++ if (length < sizeof (hd)) ++ FAIL_EXIT1 ("malformed DNS query: too short: %zu bytes", length); ++ memcpy (&hd, buffer, sizeof (hd)); ++ ++ if (ntohs (hd.qdcount) != 1) ++ FAIL_EXIT1 ("malformed DNS query: wrong question count: %d", ++ (int) ntohs (hd.qdcount)); ++ if (ntohs (hd.ancount) != 0) ++ FAIL_EXIT1 ("malformed DNS query: wrong answer count: %d", ++ (int) ntohs (hd.ancount)); ++ if (ntohs (hd.nscount) != 0) ++ FAIL_EXIT1 ("malformed DNS query: wrong authority count: %d", ++ (int) ntohs (hd.nscount)); ++ if (ntohs (hd.arcount) > 1) ++ FAIL_EXIT1 ("malformed DNS query: wrong additional count: %d", ++ (int) ntohs (hd.arcount)); ++ ++ int ret = dn_expand (buffer, buffer + length, buffer + sizeof (hd), ++ info->qname, sizeof (info->qname)); ++ if (ret < 0) ++ FAIL_EXIT1 ("malformed DNS query: cannot uncompress QNAME"); ++ ++ /* Obtain QTYPE and QCLASS. */ ++ size_t remaining = length - (12 + ret); ++ struct ++ { ++ uint16_t qtype; ++ uint16_t qclass; ++ } qtype_qclass; ++ if (remaining < sizeof (qtype_qclass)) ++ FAIL_EXIT1 ("malformed DNS query: " ++ "query lacks QCLASS/QTYPE, QNAME: %s", info->qname); ++ memcpy (&qtype_qclass, buffer + 12 + ret, sizeof (qtype_qclass)); ++ info->qclass = ntohs (qtype_qclass.qclass); ++ info->qtype = ntohs (qtype_qclass.qtype); ++ ++ memset (&info->edns, 0, sizeof (info->edns)); ++ if (ntohs (hd.arcount) > 0) ++ { ++ /* Parse EDNS record. */ ++ struct __attribute__ ((packed, aligned (1))) ++ { ++ uint8_t root; ++ uint16_t rtype; ++ uint16_t payload; ++ uint8_t edns_extended_rcode; ++ uint8_t edns_version; ++ uint16_t flags; ++ uint16_t rdatalen; ++ } rr; ++ _Static_assert (sizeof (rr) == 11, "EDNS record size"); ++ ++ if (remaining < 4 + sizeof (rr)) ++ FAIL_EXIT1 ("mailformed DNS query: no room for EDNS record"); ++ memcpy (&rr, buffer + 12 + ret + 4, sizeof (rr)); ++ if (rr.root != 0) ++ FAIL_EXIT1 ("malformed DNS query: invalid OPT RNAME: %d\n", rr.root); ++ if (rr.rtype != htons (41)) ++ FAIL_EXIT1 ("malformed DNS query: invalid OPT type: %d\n", ++ ntohs (rr.rtype)); ++ info->edns.active = true; ++ info->edns.extended_rcode = rr.edns_extended_rcode; ++ info->edns.version = rr.edns_version; ++ info->edns.flags = ntohs (rr.flags); ++ info->edns.payload_size = ntohs (rr.payload); ++ } ++} ++ ++ ++/* Main testing framework. */ ++ ++/* Per-server information. One struct is allocated for each test ++ server. */ ++struct resolv_test_server ++{ ++ /* Local address of the server. UDP and TCP use the same port. */ ++ struct sockaddr_in address; ++ ++ /* File descriptor of the UDP server, or -1 if this server is ++ disabled. */ ++ int socket_udp; ++ ++ /* File descriptor of the TCP server, or -1 if this server is ++ disabled. */ ++ int socket_tcp; ++ ++ /* Counter of the number of responses processed so far. */ ++ size_t response_number; ++ ++ /* Thread handles for the server threads (if not disabled in the ++ configuration). */ ++ pthread_t thread_udp; ++ pthread_t thread_tcp; ++}; ++ ++/* Main struct for keeping track of libresolv redirection and ++ testing. */ ++struct resolv_test ++{ ++ /* After initialization, any access to the struct must be performed ++ while this lock is acquired. */ ++ pthread_mutex_t lock; ++ ++ /* Data for each test server. */ ++ struct resolv_test_server servers[resolv_max_test_servers]; ++ ++ /* Used if config.single_thread_udp is true. */ ++ pthread_t thread_udp_single; ++ ++ struct resolv_redirect_config config; ++ bool termination_requested; ++}; ++ ++/* Function implementing a server thread. */ ++typedef void (*thread_callback) (struct resolv_test *, int server_index); ++ ++/* Storage for thread-specific data, for passing to the ++ thread_callback function. */ ++struct thread_closure ++{ ++ struct resolv_test *obj; /* Current test object. */ ++ thread_callback callback; /* Function to call. */ ++ int server_index; /* Index of the implemented server. */ ++}; ++ ++/* Wrap response_callback as a function which can be passed to ++ pthread_create. */ ++static void * ++thread_callback_wrapper (void *arg) ++{ ++ struct thread_closure *closure = arg; ++ closure->callback (closure->obj, closure->server_index); ++ free (closure); ++ return NULL; ++} ++ ++/* Start a server thread for the specified SERVER_INDEX, implemented ++ by CALLBACK. */ ++static pthread_t ++start_server_thread (struct resolv_test *obj, int server_index, ++ thread_callback callback) ++{ ++ struct thread_closure *closure = xmalloc (sizeof (*closure)); ++ *closure = (struct thread_closure) ++ { ++ .obj = obj, ++ .callback = callback, ++ .server_index = server_index, ++ }; ++ return xpthread_create (NULL, thread_callback_wrapper, closure); ++} ++ ++/* Process one UDP query. Return false if a termination requested has ++ been detected. */ ++static bool ++server_thread_udp_process_one (struct resolv_test *obj, int server_index) ++{ ++ unsigned char query[512]; ++ struct sockaddr_storage peer; ++ socklen_t peerlen = sizeof (peer); ++ size_t length = xrecvfrom (obj->servers[server_index].socket_udp, ++ query, sizeof (query), 0, ++ (struct sockaddr *) &peer, &peerlen); ++ /* Check for termination. */ ++ { ++ bool termination_requested; ++ xpthread_mutex_lock (&obj->lock); ++ termination_requested = obj->termination_requested; ++ xpthread_mutex_unlock (&obj->lock); ++ if (termination_requested) ++ return false; ++ } ++ ++ ++ struct query_info qinfo; ++ parse_query (&qinfo, query, length); ++ if (test_verbose > 0) ++ { ++ if (test_verbose > 1) ++ printf ("info: UDP server %d: incoming query:" ++ " %zd bytes, %s/%u/%u, tnxid=0x%02x%02x\n", ++ server_index, length, qinfo.qname, qinfo.qclass, qinfo.qtype, ++ query[0], query[1]); ++ else ++ printf ("info: UDP server %d: incoming query:" ++ " %zd bytes, %s/%u/%u\n", ++ server_index, length, qinfo.qname, qinfo.qclass, qinfo.qtype); ++ } ++ ++ struct resolv_response_context ctx = ++ { ++ .query_buffer = query, ++ .query_length = length, ++ .server_index = server_index, ++ .tcp = false, ++ .edns = qinfo.edns, ++ }; ++ struct resolv_response_builder *b = response_builder_allocate (query, length); ++ obj->config.response_callback ++ (&ctx, b, qinfo.qname, qinfo.qclass, qinfo.qtype); ++ ++ if (b->drop) ++ { ++ if (test_verbose) ++ printf ("info: UDP server %d: dropping response to %s/%u/%u\n", ++ server_index, qinfo.qname, qinfo.qclass, qinfo.qtype); ++ } ++ else ++ { ++ if (test_verbose) ++ { ++ if (b->offset >= 12) ++ printf ("info: UDP server %d: sending response:" ++ " %zu bytes, RCODE %d (for %s/%u/%u)\n", ++ server_index, b->offset, b->buffer[3] & 0x0f, ++ qinfo.qname, qinfo.qclass, qinfo.qtype); ++ else ++ printf ("info: UDP server %d: sending response: %zu bytes" ++ " (for %s/%u/%u)\n", ++ server_index, b->offset, ++ qinfo.qname, qinfo.qclass, qinfo.qtype); ++ if (b->truncate_bytes > 0) ++ printf ("info: truncated by %u bytes\n", b->truncate_bytes); ++ } ++ size_t to_send = b->offset; ++ if (to_send < b->truncate_bytes) ++ to_send = 0; ++ else ++ to_send -= b->truncate_bytes; ++ ++ /* Ignore most errors here because the other end may have closed ++ the socket. */ ++ if (sendto (obj->servers[server_index].socket_udp, ++ b->buffer, to_send, 0, ++ (struct sockaddr *) &peer, peerlen) < 0) ++ TEST_VERIFY_EXIT (errno != EBADF); ++ } ++ response_builder_free (b); ++ return true; ++} ++ ++/* UDP thread_callback function. Variant for one thread per ++ server. */ ++static void ++server_thread_udp (struct resolv_test *obj, int server_index) ++{ ++ while (server_thread_udp_process_one (obj, server_index)) ++ ; ++} ++ ++/* Single-threaded UDP processing function, for the single_thread_udp ++ case. */ ++static void * ++server_thread_udp_single (void *closure) ++{ ++ struct resolv_test *obj = closure; ++ ++ struct pollfd fds[resolv_max_test_servers]; ++ for (int server_index = 0; server_index < resolv_max_test_servers; ++ ++server_index) ++ if (obj->config.servers[server_index].disable_udp) ++ fds[server_index] = (struct pollfd) {.fd = -1}; ++ else ++ { ++ fds[server_index] = (struct pollfd) ++ { ++ .fd = obj->servers[server_index].socket_udp, ++ .events = POLLIN ++ }; ++ ++ /* Make the socket non-blocking. */ ++ int flags = fcntl (obj->servers[server_index].socket_udp, F_GETFL, 0); ++ if (flags < 0) ++ FAIL_EXIT1 ("fcntl (F_GETFL): %m"); ++ flags |= O_NONBLOCK; ++ if (fcntl (obj->servers[server_index].socket_udp, F_SETFL, flags) < 0) ++ FAIL_EXIT1 ("fcntl (F_SETFL): %m"); ++ } ++ ++ while (true) ++ { ++ xpoll (fds, resolv_max_test_servers, -1); ++ for (int server_index = 0; server_index < resolv_max_test_servers; ++ ++server_index) ++ if (fds[server_index].revents != 0) ++ { ++ if (!server_thread_udp_process_one (obj, server_index)) ++ goto out; ++ fds[server_index].revents = 0; ++ } ++ } ++ ++ out: ++ return NULL; ++} ++ ++/* Start the single UDP handler thread (for the single_thread_udp ++ case). */ ++static void ++start_server_thread_udp_single (struct resolv_test *obj) ++{ ++ obj->thread_udp_single ++ = xpthread_create (NULL, server_thread_udp_single, obj); ++} ++ ++/* Data describing a TCP client connect. */ ++struct tcp_thread_closure ++{ ++ struct resolv_test *obj; ++ int server_index; ++ int client_socket; ++}; ++ ++/* Read a complete DNS query packet. If EOF_OK, an immediate ++ end-of-file condition is acceptable. */ ++static bool ++read_fully (int fd, void *buf, size_t len, bool eof_ok) ++{ ++ const void *const end = buf + len; ++ while (buf < end) ++ { ++ ssize_t ret = read (fd, buf, end - buf); ++ if (ret == 0) ++ { ++ if (!eof_ok) ++ { ++ support_record_failure (); ++ printf ("error: unexpected EOF on TCP connection\n"); ++ } ++ return false; ++ } ++ else if (ret < 0) ++ { ++ if (!eof_ok || errno != ECONNRESET) ++ { ++ support_record_failure (); ++ printf ("error: TCP read: %m\n"); ++ } ++ return false; ++ } ++ buf += ret; ++ eof_ok = false; ++ } ++ return true; ++} ++ ++/* Write an array of iovecs. Terminate the process on failure. */ ++static void ++writev_fully (int fd, struct iovec *buffers, size_t count) ++{ ++ while (count > 0) ++ { ++ /* Skip zero-length write requests. */ ++ if (buffers->iov_len == 0) ++ { ++ ++buffers; ++ --count; ++ continue; ++ } ++ /* Try to rewrite the remaing buffers. */ ++ ssize_t ret = writev (fd, buffers, count); ++ if (ret < 0) ++ FAIL_EXIT1 ("writev: %m"); ++ if (ret == 0) ++ FAIL_EXIT1 ("writev: invalid return value zero"); ++ /* Find the buffers that were successfully written. */ ++ while (ret > 0) ++ { ++ if (count == 0) ++ FAIL_EXIT1 ("internal writev consistency failure"); ++ /* Current buffer was partially written. */ ++ if (buffers->iov_len > (size_t) ret) ++ { ++ buffers->iov_base += ret; ++ buffers->iov_len -= ret; ++ ret = 0; ++ } ++ else ++ { ++ ret -= buffers->iov_len; ++ buffers->iov_len = 0; ++ ++buffers; ++ --count; ++ } ++ } ++ } ++} ++ ++/* Thread callback for handling a single established TCP connection to ++ a client. */ ++static void * ++server_thread_tcp_client (void *arg) ++{ ++ struct tcp_thread_closure *closure = arg; ++ ++ while (true) ++ { ++ /* Read packet length. */ ++ uint16_t query_length; ++ if (!read_fully (closure->client_socket, ++ &query_length, sizeof (query_length), true)) ++ break; ++ query_length = ntohs (query_length); ++ ++ /* Read the packet. */ ++ unsigned char *query_buffer = xmalloc (query_length); ++ read_fully (closure->client_socket, query_buffer, query_length, false); ++ ++ struct query_info qinfo; ++ parse_query (&qinfo, query_buffer, query_length); ++ if (test_verbose > 0) ++ { ++ if (test_verbose > 1) ++ printf ("info: UDP server %d: incoming query:" ++ " %d bytes, %s/%u/%u, tnxid=0x%02x%02x\n", ++ closure->server_index, query_length, ++ qinfo.qname, qinfo.qclass, qinfo.qtype, ++ query_buffer[0], query_buffer[1]); ++ else ++ printf ("info: TCP server %d: incoming query:" ++ " %u bytes, %s/%u/%u\n", ++ closure->server_index, query_length, ++ qinfo.qname, qinfo.qclass, qinfo.qtype); ++ } ++ ++ struct resolv_response_context ctx = ++ { ++ .query_buffer = query_buffer, ++ .query_length = query_length, ++ .server_index = closure->server_index, ++ .tcp = true, ++ .edns = qinfo.edns, ++ }; ++ struct resolv_response_builder *b = response_builder_allocate ++ (query_buffer, query_length); ++ closure->obj->config.response_callback ++ (&ctx, b, qinfo.qname, qinfo.qclass, qinfo.qtype); ++ ++ if (b->drop) ++ { ++ if (test_verbose) ++ printf ("info: TCP server %d: dropping response to %s/%u/%u\n", ++ closure->server_index, ++ qinfo.qname, qinfo.qclass, qinfo.qtype); ++ } ++ else ++ { ++ if (test_verbose) ++ printf ("info: TCP server %d: sending response: %zu bytes" ++ " (for %s/%u/%u)\n", ++ closure->server_index, b->offset, ++ qinfo.qname, qinfo.qclass, qinfo.qtype); ++ uint16_t length = htons (b->offset); ++ size_t to_send = b->offset; ++ if (to_send < b->truncate_bytes) ++ to_send = 0; ++ else ++ to_send -= b->truncate_bytes; ++ struct iovec buffers[2] = ++ { ++ {&length, sizeof (length)}, ++ {b->buffer, to_send} ++ }; ++ writev_fully (closure->client_socket, buffers, 2); ++ } ++ bool close_flag = b->close; ++ response_builder_free (b); ++ free (query_buffer); ++ if (close_flag) ++ break; ++ } ++ ++ xclose (closure->client_socket); ++ free (closure); ++ return NULL; ++} ++ ++/* thread_callback for the TCP case. Accept connections and create a ++ new thread for each client. */ ++static void ++server_thread_tcp (struct resolv_test *obj, int server_index) ++{ ++ while (true) ++ { ++ /* Get the client conenction. */ ++ int client_socket = xaccept ++ (obj->servers[server_index].socket_tcp, NULL, NULL); ++ ++ /* Check for termination. */ ++ xpthread_mutex_lock (&obj->lock); ++ if (obj->termination_requested) ++ { ++ xpthread_mutex_unlock (&obj->lock); ++ xclose (client_socket); ++ break; ++ } ++ xpthread_mutex_unlock (&obj->lock); ++ ++ /* Spawn a new thread for handling this connection. */ ++ struct tcp_thread_closure *closure = xmalloc (sizeof (*closure)); ++ *closure = (struct tcp_thread_closure) ++ { ++ .obj = obj, ++ .server_index = server_index, ++ .client_socket = client_socket, ++ }; ++ ++ pthread_t thr ++ = xpthread_create (NULL, server_thread_tcp_client, closure); ++ /* TODO: We should keep track of this thread so that we can ++ block in resolv_test_end until it has exited. */ ++ xpthread_detach (thr); ++ } ++} ++ ++/* Create UDP and TCP server sockets. */ ++static void ++make_server_sockets (struct resolv_test_server *server) ++{ ++ while (true) ++ { ++ server->socket_udp = xsocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ server->socket_tcp = xsocket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ ++ /* Pick the address for the UDP socket. */ ++ server->address = (struct sockaddr_in) ++ { ++ .sin_family = AF_INET, ++ .sin_addr = {.s_addr = htonl (INADDR_LOOPBACK)} ++ }; ++ xbind (server->socket_udp, ++ (struct sockaddr *)&server->address, sizeof (server->address)); ++ ++ /* Retrieve the address. */ ++ socklen_t addrlen = sizeof (server->address); ++ xgetsockname (server->socket_udp, ++ (struct sockaddr *)&server->address, &addrlen); ++ ++ /* Bind the TCP socket to the same address. */ ++ { ++ int on = 1; ++ xsetsockopt (server->socket_tcp, SOL_SOCKET, SO_REUSEADDR, ++ &on, sizeof (on)); ++ } ++ if (bind (server->socket_tcp, ++ (struct sockaddr *)&server->address, ++ sizeof (server->address)) != 0) ++ { ++ /* Port collision. The UDP bind succeeded, but the TCP BIND ++ failed. We assume here that the kernel will pick the ++ next local UDP address randomly. */ ++ if (errno == EADDRINUSE) ++ { ++ xclose (server->socket_udp); ++ xclose (server->socket_tcp); ++ continue; ++ } ++ FAIL_EXIT1 ("TCP bind: %m"); ++ } ++ xlisten (server->socket_tcp, 5); ++ break; ++ } ++} ++ ++/* Like make_server_sockets, but the caller supplies the address to ++ use. */ ++static void ++make_server_sockets_for_address (struct resolv_test_server *server, ++ const struct sockaddr *addr) ++{ ++ server->socket_udp = xsocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ server->socket_tcp = xsocket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ ++ if (addr->sa_family == AF_INET) ++ server->address = *(const struct sockaddr_in *) addr; ++ else ++ /* We cannot store the server address in the socket. This should ++ not matter if disable_redirect is used. */ ++ server->address = (struct sockaddr_in) { .sin_family = 0, }; ++ ++ xbind (server->socket_udp, ++ (struct sockaddr *)&server->address, sizeof (server->address)); ++ xbind (server->socket_tcp, ++ (struct sockaddr *)&server->address, sizeof (server->address)); ++ xlisten (server->socket_tcp, 5); ++} ++ ++/* One-time initialization of NSS. */ ++static void ++resolv_redirect_once (void) ++{ ++ /* Only use nss_dns. */ ++ __nss_configure_lookup ("hosts", "dns"); ++ __nss_configure_lookup ("networks", "dns"); ++ /* Enter a network namespace for isolation and firewall state ++ cleanup. The tests will still work if these steps fail, but they ++ may be less reliable. */ ++ support_become_root (); ++ support_enter_network_namespace (); ++} ++pthread_once_t resolv_redirect_once_var = PTHREAD_ONCE_INIT; ++ ++void ++resolv_test_init (void) ++{ ++ /* Perform one-time initialization of NSS. */ ++ xpthread_once (&resolv_redirect_once_var, resolv_redirect_once); ++} ++ ++/* Copy the search path from CONFIG.search to the _res object. */ ++static void ++set_search_path (struct resolv_redirect_config config) ++{ ++ memset (_res.defdname, 0, sizeof (_res.defdname)); ++ memset (_res.dnsrch, 0, sizeof (_res.dnsrch)); ++ ++ char *current = _res.defdname; ++ char *end = current + sizeof (_res.defdname); ++ ++ for (unsigned int i = 0; ++ i < sizeof (config.search) / sizeof (config.search[0]); ++i) ++ { ++ if (config.search[i] == NULL) ++ continue; ++ ++ size_t length = strlen (config.search[i]) + 1; ++ size_t remaining = end - current; ++ TEST_VERIFY_EXIT (length <= remaining); ++ memcpy (current, config.search[i], length); ++ _res.dnsrch[i] = current; ++ current += length; ++ } ++} ++ ++struct resolv_test * ++resolv_test_start (struct resolv_redirect_config config) ++{ ++ /* Apply configuration defaults. */ ++ if (config.nscount == 0) ++ config.nscount = resolv_max_test_servers; ++ ++ struct resolv_test *obj = xmalloc (sizeof (*obj)); ++ *obj = (struct resolv_test) { ++ .config = config, ++ .lock = PTHREAD_MUTEX_INITIALIZER, ++ }; ++ ++ if (!config.disable_redirect) ++ resolv_test_init (); ++ ++ /* Create all the servers, to reserve the necessary ports. */ ++ for (int server_index = 0; server_index < config.nscount; ++server_index) ++ if (config.disable_redirect && config.server_address_overrides != NULL) ++ make_server_sockets_for_address ++ (obj->servers + server_index, ++ config.server_address_overrides[server_index]); ++ else ++ make_server_sockets (obj->servers + server_index); ++ ++ /* Start server threads. Disable the server ports, as ++ requested. */ ++ for (int server_index = 0; server_index < config.nscount; ++server_index) ++ { ++ struct resolv_test_server *server = obj->servers + server_index; ++ if (config.servers[server_index].disable_udp) ++ { ++ xclose (server->socket_udp); ++ server->socket_udp = -1; ++ } ++ else if (!config.single_thread_udp) ++ server->thread_udp = start_server_thread (obj, server_index, ++ server_thread_udp); ++ if (config.servers[server_index].disable_tcp) ++ { ++ xclose (server->socket_tcp); ++ server->socket_tcp = -1; ++ } ++ else ++ server->thread_tcp = start_server_thread (obj, server_index, ++ server_thread_tcp); ++ } ++ if (config.single_thread_udp) ++ start_server_thread_udp_single (obj); ++ ++ if (config.disable_redirect) ++ return obj; ++ ++ int timeout = 1; ++ ++ /* Initialize libresolv. */ ++ TEST_VERIFY_EXIT (res_init () == 0); ++ ++ /* Disable IPv6 name server addresses. The code below only ++ overrides the IPv4 addresses. */ ++ __res_iclose (&_res, true); ++ _res._u._ext.nscount = 0; ++ ++ /* Redirect queries to the server socket. */ ++ if (test_verbose) ++ { ++ printf ("info: old timeout value: %d\n", _res.retrans); ++ printf ("info: old retry attempt value: %d\n", _res.retry); ++ printf ("info: old _res.options: 0x%lx\n", _res.options); ++ printf ("info: old _res.nscount value: %d\n", _res.nscount); ++ printf ("info: old _res.ndots value: %d\n", _res.ndots); ++ } ++ _res.retrans = timeout; ++ _res.retry = 4; ++ _res.nscount = config.nscount; ++ _res.options = RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH; ++ _res.ndots = 1; ++ if (test_verbose) ++ { ++ printf ("info: new timeout value: %d\n", _res.retrans); ++ printf ("info: new retry attempt value: %d\n", _res.retry); ++ printf ("info: new _res.options: 0x%lx\n", _res.options); ++ printf ("info: new _res.nscount value: %d\n", _res.nscount); ++ printf ("info: new _res.ndots value: %d\n", _res.ndots); ++ } ++ for (int server_index = 0; server_index < config.nscount; ++server_index) ++ { ++ TEST_VERIFY_EXIT (obj->servers[server_index].address.sin_port != 0); ++ _res.nsaddr_list[server_index] = obj->servers[server_index].address; ++ if (test_verbose) ++ { ++ char buf[256]; ++ TEST_VERIFY_EXIT ++ (inet_ntop (AF_INET, &obj->servers[server_index].address.sin_addr, ++ buf, sizeof (buf)) != NULL); ++ printf ("info: server %d: %s/%u\n", ++ server_index, buf, ++ htons (obj->servers[server_index].address.sin_port)); ++ } ++ } ++ ++ set_search_path (config); ++ ++ return obj; ++} ++ ++void ++resolv_test_end (struct resolv_test *obj) ++{ ++ res_close (); ++ ++ xpthread_mutex_lock (&obj->lock); ++ obj->termination_requested = true; ++ xpthread_mutex_unlock (&obj->lock); ++ ++ /* Send trigger packets to unblock the server threads. */ ++ for (int server_index = 0; server_index < obj->config.nscount; ++ ++server_index) ++ { ++ if (!obj->config.servers[server_index].disable_udp) ++ { ++ int sock = xsocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ xsendto (sock, "", 1, 0, ++ (struct sockaddr *) &obj->servers[server_index].address, ++ sizeof (obj->servers[server_index].address)); ++ xclose (sock); ++ } ++ if (!obj->config.servers[server_index].disable_tcp) ++ { ++ int sock = xsocket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ xconnect (sock, ++ (struct sockaddr *) &obj->servers[server_index].address, ++ sizeof (obj->servers[server_index].address)); ++ xclose (sock); ++ } ++ } ++ ++ if (obj->config.single_thread_udp) ++ xpthread_join (obj->thread_udp_single); ++ ++ /* Wait for the server threads to terminate. */ ++ for (int server_index = 0; server_index < obj->config.nscount; ++ ++server_index) ++ { ++ if (!obj->config.servers[server_index].disable_udp) ++ { ++ if (!obj->config.single_thread_udp) ++ xpthread_join (obj->servers[server_index].thread_udp); ++ xclose (obj->servers[server_index].socket_udp); ++ } ++ if (!obj->config.servers[server_index].disable_tcp) ++ { ++ xpthread_join (obj->servers[server_index].thread_tcp); ++ xclose (obj->servers[server_index].socket_tcp); ++ } ++ } ++ ++ free (obj); ++} +diff --git a/support/resolv_test.h b/support/resolv_test.h +new file mode 100644 +index 0000000000..4c2e6c1b41 +--- /dev/null ++++ b/support/resolv_test.h +@@ -0,0 +1,190 @@ ++/* DNS test framework and libresolv redirection. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_RESOLV_TEST_H ++#define SUPPORT_RESOLV_TEST_H ++ ++#include ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Information about EDNS properties of a DNS query. */ ++struct resolv_edns_info ++{ ++ bool active; ++ uint8_t extended_rcode; ++ uint8_t version; ++ uint16_t flags; ++ uint16_t payload_size; ++}; ++ ++/* This struct provides context information when the response callback ++ specified in struct resolv_redirect_config is invoked. */ ++struct resolv_response_context ++{ ++ const unsigned char *query_buffer; ++ size_t query_length; ++ int server_index; ++ bool tcp; ++ struct resolv_edns_info edns; ++}; ++ ++/* This opaque struct is used to construct responses from within the ++ response callback function. */ ++struct resolv_response_builder; ++ ++/* This opaque struct collects information about the resolver testing ++ currently in progress. */ ++struct resolv_test; ++ ++enum ++ { ++ /* Maximum number of test servers supported by the framework. */ ++ resolv_max_test_servers = 3, ++ }; ++ ++/* Configuration settings specific to individual test servers. */ ++struct resolv_redirect_server_config ++{ ++ bool disable_tcp; /* If true, no TCP server is listening. */ ++ bool disable_udp; /* If true, no UDP server is listening. */ ++}; ++ ++/* Instructions for setting up the libresolv redirection. */ ++struct resolv_redirect_config ++{ ++ /* The response_callback function is called for every incoming DNS ++ packet, over UDP or TCP. It must be specified, the other ++ configuration settings are optional. */ ++ void (*response_callback) (const struct resolv_response_context *, ++ struct resolv_response_builder *, ++ const char *qname, ++ uint16_t qclass, uint16_t qtype); ++ ++ /* Per-server configuration. */ ++ struct resolv_redirect_server_config servers[resolv_max_test_servers]; ++ ++ /* Search path entries. The first entry serves as the default ++ domain name as well. */ ++ const char *search[7]; ++ ++ /* Number of servers to activate in resolv. 0 means the default, ++ resolv_max_test_servers. */ ++ int nscount; ++ ++ /* If true, use a single thread to process all UDP queries. This ++ may results in more predictable ordering of queries and ++ responses. */ ++ bool single_thread_udp; ++ ++ /* Do not rewrite the _res variable or change NSS defaults. Use ++ server_address_overrides below to tell the testing framework on ++ which addresses to create the servers. */ ++ bool disable_redirect; ++ ++ /* Use these addresses for creating the DNS servers. The array must ++ have ns_count (or resolv_max_test_servers) sockaddr * elements if ++ not NULL. */ ++ const struct sockaddr *const *server_address_overrides; ++}; ++ ++/* Configure NSS to use, nss_dns only for aplicable databases, and try ++ to put the process into a network namespace for better isolation. ++ This may have to be called before resolv_test_start, before the ++ process creates any threads. Otherwise, initialization is ++ performed by resolv_test_start implicitly. */ ++void resolv_test_init (void); ++ ++/* Initiate resolver testing. This updates the _res variable as ++ needed. As a side effect, NSS is reconfigured to use nss_dns only ++ for aplicable databases, and the process may enter a network ++ namespace for better isolation. */ ++struct resolv_test *resolv_test_start (struct resolv_redirect_config); ++ ++/* Call this function at the end of resolver testing, to free ++ resources and report pending errors (if any). */ ++void resolv_test_end (struct resolv_test *); ++ ++/* The remaining facilities in this file are used for constructing ++ response packets from the response_callback function. */ ++ ++/* Special settings for constructing responses from the callback. */ ++struct resolv_response_flags ++{ ++ /* 4-bit response code to incorporate into the response. */ ++ unsigned char rcode; ++ ++ /* If true, the TC (truncation) flag will be set. */ ++ bool tc; ++ ++ /* Initial section count values. Can be used to artificially ++ increase the counts, for malformed packet testing.*/ ++ unsigned short qdcount; ++ unsigned short ancount; ++ unsigned short nscount; ++ unsigned short adcount; ++}; ++ ++/* Begin a new response with the requested flags. Must be called ++ first. */ ++void resolv_response_init (struct resolv_response_builder *, ++ struct resolv_response_flags); ++ ++/* Switches to the section in the response packet. Only forward ++ movement is supported. */ ++void resolv_response_section (struct resolv_response_builder *, ns_sect); ++ ++/* Add a question record to the question section. */ ++void resolv_response_add_question (struct resolv_response_builder *, ++ const char *name, uint16_t class, ++ uint16_t type); ++/* Starts a new resource record with the specified owner name, class, ++ type, and TTL. Data is supplied with resolv_response_add_data or ++ resolv_response_add_name. */ ++void resolv_response_open_record (struct resolv_response_builder *, ++ const char *name, uint16_t class, ++ uint16_t type, uint32_t ttl); ++ ++/* Add unstructed bytes to the RDATA part of a resource record. */ ++void resolv_response_add_data (struct resolv_response_builder *, ++ const void *, size_t); ++ ++/* Add a compressed domain name to the RDATA part of a resource ++ record. */ ++void resolv_response_add_name (struct resolv_response_builder *, ++ const char *name); ++ ++/* Mark the end of the constructed record. Must be called last. */ ++void resolv_response_close_record (struct resolv_response_builder *); ++ ++/* Drop this query packet (that is, do not send a response, not even ++ an empty packet). */ ++void resolv_response_drop (struct resolv_response_builder *); ++ ++/* In TCP mode, close the connection after this packet (if a response ++ is sent). */ ++void resolv_response_close (struct resolv_response_builder *); ++ ++/* The size of the response packet built so far. */ ++size_t resolv_response_length (const struct resolv_response_builder *); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_RESOLV_TEST_H */ +diff --git a/support/run_diff.h b/support/run_diff.h +new file mode 100644 +index 0000000000..6e949226fa +--- /dev/null ++++ b/support/run_diff.h +@@ -0,0 +1,31 @@ ++/* Invoke the system diff tool to compare two strings. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_RUN_DIFF_H ++#define SUPPORT_RUN_DIFF_H ++ ++/* Compare the two NUL-terminated strings LEFT and RIGHT using the ++ diff tool. Label the sides of the diff with LEFT_LABEL and ++ RIGHT_LABEL, respectively. ++ ++ This function assumes that LEFT and RIGHT are different ++ strings. */ ++void support_run_diff (const char *left_label, const char *left, ++ const char *right_label, const char *right); ++ ++#endif /* SUPPORT_RUN_DIFF_H */ +diff --git a/support/set_fortify_handler.c b/support/set_fortify_handler.c +new file mode 100644 +index 0000000000..c2dacbb179 +--- /dev/null ++++ b/support/set_fortify_handler.c +@@ -0,0 +1,34 @@ ++/* Set signal handler for use in fortify tests. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++void ++set_fortify_handler (void (*handler) (int sig)) ++{ ++ struct sigaction sa; ++ ++ sa.sa_handler = handler; ++ sa.sa_flags = 0; ++ sigemptyset (&sa.sa_mask); ++ ++ sigaction (SIGABRT, &sa, NULL); ++ ignore_stderr (); ++} +diff --git a/support/support-xfstat.c b/support/support-xfstat.c +new file mode 100644 +index 0000000000..f69253af09 +--- /dev/null ++++ b/support/support-xfstat.c +@@ -0,0 +1,28 @@ ++/* fstat64 with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++xfstat (int fd, struct stat64 *result) ++{ ++ if (fstat64 (fd, result) != 0) ++ FAIL_EXIT1 ("fstat64 (%d): %m", fd); ++} +diff --git a/support/support-xstat.c b/support/support-xstat.c +new file mode 100644 +index 0000000000..fc10c6dcb7 +--- /dev/null ++++ b/support/support-xstat.c +@@ -0,0 +1,30 @@ ++/* stat64 with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* NB: Non-standard file name to avoid sysdeps override for xstat. */ ++ ++#include ++#include ++#include ++ ++void ++xstat (const char *path, struct stat64 *result) ++{ ++ if (stat64 (path, result) != 0) ++ FAIL_EXIT1 ("stat64 (\"%s\"): %m", path); ++} +diff --git a/support/support.h b/support/support.h +new file mode 100644 +index 0000000000..bc5827ed87 +--- /dev/null ++++ b/support/support.h +@@ -0,0 +1,75 @@ ++/* Common extra functions. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This header file should only contain definitions compatible with ++ C90. (Using __attribute__ is fine because provides a ++ fallback.) */ ++ ++#ifndef SUPPORT_H ++#define SUPPORT_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Write a message to standard output. Can be used in signal ++ handlers. */ ++void write_message (const char *message) __attribute__ ((nonnull (1))); ++ ++/* Avoid all the buffer overflow messages on stderr. */ ++void ignore_stderr (void); ++ ++/* Set fortification error handler. Used when tests want to verify that bad ++ code is caught by the library. */ ++void set_fortify_handler (void (*handler) (int sig)); ++ ++/* Report an out-of-memory error for the allocation of SIZE bytes in ++ FUNCTION, terminating the process. */ ++void oom_error (const char *function, size_t size) ++ __attribute__ ((nonnull (1))); ++ ++/* Return a pointer to a memory region of SIZE bytes. The memory is ++ initialized to zero and will be shared with subprocesses (across ++ fork). The returned pointer must be freed using ++ support_shared_free; it is not compatible with the malloc ++ functions. */ ++void *support_shared_allocate (size_t size); ++ ++/* Deallocate a pointer returned by support_shared_allocate. */ ++void support_shared_free (void *); ++ ++/* Write CONTENTS to the file PATH. Create or truncate the file as ++ needed. The file mode is 0666 masked by the umask. Terminate the ++ process on error. */ ++void support_write_file_string (const char *path, const char *contents); ++ ++/* Error-checking wrapper functions which terminate the process on ++ error. */ ++ ++void *xmalloc (size_t) __attribute__ ((malloc)); ++void *xcalloc (size_t n, size_t s) __attribute__ ((malloc)); ++void *xrealloc (void *p, size_t n); ++char *xasprintf (const char *format, ...) ++ __attribute__ ((format (printf, 1, 2), malloc)); ++char *xstrdup (const char *); ++char *xstrndup (const char *, size_t); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_H */ +diff --git a/support/support_become_root.c b/support/support_become_root.c +new file mode 100644 +index 0000000000..6947dbaa80 +--- /dev/null ++++ b/support/support_become_root.c +@@ -0,0 +1,102 @@ ++/* Acquire root privileges. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CLONE_NEWUSER ++/* The necessary steps to allow file creation in user namespaces. */ ++static void ++setup_uid_gid_mapping (uid_t original_uid, gid_t original_gid) ++{ ++ int fd = open64 ("/proc/self/uid_map", O_WRONLY); ++ if (fd < 0) ++ { ++ printf ("warning: could not open /proc/self/uid_map: %m\n" ++ "warning: file creation may not be possible\n"); ++ return; ++ } ++ ++ /* We map our original UID to the same UID in the container so we ++ own our own files normally. Without that, file creation could ++ fail with EOVERFLOW (sic!). */ ++ char buf[100]; ++ int ret = snprintf (buf, sizeof (buf), "%llu %llu 1\n", ++ (unsigned long long) original_uid, ++ (unsigned long long) original_uid); ++ TEST_VERIFY_EXIT (ret < sizeof (buf)); ++ xwrite (fd, buf, ret); ++ xclose (fd); ++ ++ /* Linux 3.19 introduced the setgroups file. We need write "deny" to this ++ file otherwise writing to gid_map will fail with EPERM. */ ++ fd = open64 ("/proc/self/setgroups", O_WRONLY, 0); ++ if (fd < 0) ++ { ++ if (errno != ENOENT) ++ FAIL_EXIT1 ("open64 (\"/proc/self/setgroups\", 0x%x, 0%o): %m", ++ O_WRONLY, 0); ++ /* This kernel doesn't expose the setgroups file so simply move on. */ ++ } ++ else ++ { ++ xwrite (fd, "deny\n", strlen ("deny\n")); ++ xclose (fd); ++ } ++ ++ /* Now map our own GID, like we did for the user ID. */ ++ fd = xopen ("/proc/self/gid_map", O_WRONLY, 0); ++ ret = snprintf (buf, sizeof (buf), "%llu %llu 1\n", ++ (unsigned long long) original_gid, ++ (unsigned long long) original_gid); ++ TEST_VERIFY_EXIT (ret < sizeof (buf)); ++ xwrite (fd, buf, ret); ++ xclose (fd); ++} ++#endif /* CLONE_NEWUSER */ ++ ++bool ++support_become_root (void) ++{ ++#ifdef CLONE_NEWUSER ++ uid_t original_uid = getuid (); ++ gid_t original_gid = getgid (); ++ ++ if (unshare (CLONE_NEWUSER | CLONE_NEWNS) == 0) ++ { ++ setup_uid_gid_mapping (original_uid, original_gid); ++ /* Even if we do not have UID zero, we have extended privileges at ++ this point. */ ++ return true; ++ } ++#endif ++ if (setuid (0) != 0) ++ { ++ printf ("warning: could not become root outside namespace (%m)\n"); ++ return false; ++ } ++ return true; ++} +diff --git a/support/support_can_chroot.c b/support/support_can_chroot.c +new file mode 100644 +index 0000000000..8922576d19 +--- /dev/null ++++ b/support/support_can_chroot.c +@@ -0,0 +1,65 @@ ++/* Return true if the process can perform a chroot operation. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++callback (void *closure) ++{ ++ int *result = closure; ++ struct stat64 before; ++ xstat ("/dev", &before); ++ if (chroot ("/dev") != 0) ++ { ++ *result = errno; ++ return; ++ } ++ struct stat64 after; ++ xstat ("/", &after); ++ TEST_VERIFY (before.st_dev == after.st_dev); ++ TEST_VERIFY (before.st_ino == after.st_ino); ++ *result = 0; ++} ++ ++bool ++support_can_chroot (void) ++{ ++ int *result = support_shared_allocate (sizeof (*result)); ++ *result = 0; ++ support_isolate_in_subprocess (callback, result); ++ bool ok = *result == 0; ++ if (!ok) ++ { ++ static bool already_warned; ++ if (!already_warned) ++ { ++ already_warned = true; ++ errno = *result; ++ printf ("warning: this process does not support chroot: %m\n"); ++ } ++ } ++ support_shared_free (result); ++ return ok; ++} +diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c +new file mode 100644 +index 0000000000..6d2029e13b +--- /dev/null ++++ b/support/support_capture_subprocess.c +@@ -0,0 +1,108 @@ ++/* Capture output from a subprocess. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static void ++transfer (const char *what, struct pollfd *pfd, struct xmemstream *stream) ++{ ++ if (pfd->revents != 0) ++ { ++ char buf[1024]; ++ ssize_t ret = TEMP_FAILURE_RETRY (read (pfd->fd, buf, sizeof (buf))); ++ if (ret < 0) ++ { ++ support_record_failure (); ++ printf ("error: reading from subprocess %s: %m", what); ++ pfd->events = 0; ++ pfd->revents = 0; ++ } ++ else if (ret == 0) ++ { ++ /* EOF reached. Stop listening. */ ++ pfd->events = 0; ++ pfd->revents = 0; ++ } ++ else ++ /* Store the data just read. */ ++ TEST_VERIFY (fwrite (buf, ret, 1, stream->out) == 1); ++ } ++} ++ ++struct support_capture_subprocess ++support_capture_subprocess (void (*callback) (void *), void *closure) ++{ ++ struct support_capture_subprocess result; ++ xopen_memstream (&result.out); ++ xopen_memstream (&result.err); ++ ++ int stdout_pipe[2]; ++ xpipe (stdout_pipe); ++ int stderr_pipe[2]; ++ xpipe (stderr_pipe); ++ ++ TEST_VERIFY (fflush (stdout) == 0); ++ TEST_VERIFY (fflush (stderr) == 0); ++ ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ xclose (stdout_pipe[0]); ++ xclose (stderr_pipe[0]); ++ xdup2 (stdout_pipe[1], STDOUT_FILENO); ++ xdup2 (stderr_pipe[1], STDERR_FILENO); ++ callback (closure); ++ _exit (0); ++ } ++ xclose (stdout_pipe[1]); ++ xclose (stderr_pipe[1]); ++ ++ struct pollfd fds[2] = ++ { ++ { .fd = stdout_pipe[0], .events = POLLIN }, ++ { .fd = stderr_pipe[0], .events = POLLIN }, ++ }; ++ ++ do ++ { ++ xpoll (fds, 2, -1); ++ transfer ("stdout", &fds[0], &result.out); ++ transfer ("stderr", &fds[1], &result.err); ++ } ++ while (fds[0].events != 0 || fds[1].events != 0); ++ xclose (stdout_pipe[0]); ++ xclose (stderr_pipe[0]); ++ ++ xfclose_memstream (&result.out); ++ xfclose_memstream (&result.err); ++ xwaitpid (pid, &result.status, 0); ++ return result; ++} ++ ++void ++support_capture_subprocess_free (struct support_capture_subprocess *p) ++{ ++ free (p->out.buffer); ++ free (p->err.buffer); ++} +diff --git a/support/support_capture_subprocess_check.c b/support/support_capture_subprocess_check.c +new file mode 100644 +index 0000000000..ff5ee89fb0 +--- /dev/null ++++ b/support/support_capture_subprocess_check.c +@@ -0,0 +1,67 @@ ++/* Verify capture output from a subprocess. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static void ++print_context (const char *context, bool *failed) ++{ ++ if (*failed) ++ /* Do not duplicate message. */ ++ return; ++ support_record_failure (); ++ printf ("error: subprocess failed: %s\n", context); ++} ++ ++void ++support_capture_subprocess_check (struct support_capture_subprocess *proc, ++ const char *context, int status, ++ int allowed) ++{ ++ TEST_VERIFY ((allowed & sc_allow_none) ++ || (allowed & sc_allow_stdout) ++ || (allowed & sc_allow_stderr)); ++ TEST_VERIFY (!((allowed & sc_allow_none) ++ && ((allowed & sc_allow_stdout) ++ || (allowed & sc_allow_stderr)))); ++ ++ bool failed = false; ++ if (proc->status != status) ++ { ++ print_context (context, &failed); ++ printf ("error: expected exit status: %d\n", status); ++ printf ("error: actual exit status: %d\n", proc->status); ++ } ++ if (!(allowed & sc_allow_stdout) && proc->out.length != 0) ++ { ++ print_context (context, &failed); ++ printf ("error: unexpected output from subprocess\n"); ++ fwrite (proc->out.buffer, proc->out.length, 1, stdout); ++ puts ("\n"); ++ } ++ if (!(allowed & sc_allow_stderr) && proc->err.length != 0) ++ { ++ print_context (context, &failed); ++ printf ("error: unexpected error output from subprocess\n"); ++ fwrite (proc->err.buffer, proc->err.length, 1, stdout); ++ puts ("\n"); ++ } ++} +diff --git a/support/support_chroot.c b/support/support_chroot.c +new file mode 100644 +index 0000000000..6356b1af6c +--- /dev/null ++++ b/support/support_chroot.c +@@ -0,0 +1,81 @@ ++/* Setup a chroot environment for use within tests. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* If CONTENTS is not NULL, write it to the file at DIRECTORY/RELPATH, ++ and store the name in *ABSPATH. If CONTENTS is NULL, store NULL in ++ *ABSPATH. */ ++static void ++write_file (const char *directory, const char *relpath, const char *contents, ++ char **abspath) ++{ ++ if (contents != NULL) ++ { ++ *abspath = xasprintf ("%s/%s", directory, relpath); ++ add_temp_file (*abspath); ++ support_write_file_string (*abspath, contents); ++ } ++ else ++ *abspath = NULL; ++} ++ ++struct support_chroot * ++support_chroot_create (struct support_chroot_configuration conf) ++{ ++ struct support_chroot *chroot = xmalloc (sizeof (*chroot)); ++ chroot->path_chroot = support_create_temp_directory ("tst-resolv-res_init-"); ++ ++ /* Create the /etc directory in the chroot environment. */ ++ char *path_etc = xasprintf ("%s/etc", chroot->path_chroot); ++ xmkdir (path_etc, 0777); ++ add_temp_file (path_etc); ++ ++ write_file (path_etc, "resolv.conf", conf.resolv_conf, ++ &chroot->path_resolv_conf); ++ write_file (path_etc, "hosts", conf.hosts, &chroot->path_hosts); ++ write_file (path_etc, "host.conf", conf.host_conf, &chroot->path_host_conf); ++ ++ free (path_etc); ++ ++ /* valgrind needs a temporary directory in the chroot. */ ++ { ++ char *path_tmp = xasprintf ("%s/tmp", chroot->path_chroot); ++ xmkdir (path_tmp, 0777); ++ add_temp_file (path_tmp); ++ free (path_tmp); ++ } ++ ++ return chroot; ++} ++ ++void ++support_chroot_free (struct support_chroot *chroot) ++{ ++ free (chroot->path_chroot); ++ free (chroot->path_resolv_conf); ++ free (chroot->path_hosts); ++ free (chroot->path_host_conf); ++ free (chroot); ++} +diff --git a/support/support_enter_mount_namespace.c b/support/support_enter_mount_namespace.c +new file mode 100644 +index 0000000000..ba68e990f2 +--- /dev/null ++++ b/support/support_enter_mount_namespace.c +@@ -0,0 +1,47 @@ ++/* Enter a mount namespace. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#ifdef CLONE_NEWNS ++# include ++#endif /* CLONE_NEWNS */ ++ ++bool ++support_enter_mount_namespace (void) ++{ ++#ifdef CLONE_NEWNS ++ if (unshare (CLONE_NEWNS) == 0) ++ { ++ /* On some systems, / is marked as MS_SHARED, which means that ++ mounts within the namespace leak to the rest of the system, ++ which is not what we want. */ ++ if (mount ("none", "/", NULL, MS_REC | MS_PRIVATE, NULL) != 0) ++ { ++ printf ("warning: making the mount namespace private failed: %m\n"); ++ return false; ++ } ++ return true; ++ } ++ else ++ printf ("warning: unshare (CLONE_NEWNS) failed: %m\n"); ++#endif /* CLONE_NEWNS */ ++ return false; ++} +diff --git a/support/support_enter_network_namespace.c b/support/support_enter_network_namespace.c +new file mode 100644 +index 0000000000..1d874df885 +--- /dev/null ++++ b/support/support_enter_network_namespace.c +@@ -0,0 +1,75 @@ ++/* Enter a network namespace. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static bool in_uts_namespace; ++ ++bool ++support_enter_network_namespace (void) ++{ ++#ifdef CLONE_NEWUTS ++ if (unshare (CLONE_NEWUTS) == 0) ++ in_uts_namespace = true; ++ else ++ printf ("warning: unshare (CLONE_NEWUTS) failed: %m\n"); ++#endif ++ ++#ifdef CLONE_NEWNET ++ if (unshare (CLONE_NEWNET) == 0) ++ { ++ /* Bring up the loopback interface. */ ++ int fd = xsocket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++ struct ifreq req; ++ strcpy (req.ifr_name, "lo"); ++ TEST_VERIFY_EXIT (ioctl (fd, SIOCGIFFLAGS, &req) == 0); ++ bool already_up = req.ifr_flags & IFF_UP; ++ if (already_up) ++ /* This means that we likely have not achieved isolation from ++ the parent namespace. */ ++ printf ("warning: loopback interface already exists" ++ " in new network namespace\n"); ++ else ++ { ++ req.ifr_flags |= IFF_UP | IFF_RUNNING; ++ TEST_VERIFY_EXIT (ioctl (fd, SIOCSIFFLAGS, &req) == 0); ++ } ++ xclose (fd); ++ ++ return !already_up; ++ } ++#endif ++ printf ("warning: could not enter network namespace\n"); ++ return false; ++} ++ ++bool ++support_in_uts_namespace (void) ++{ ++ return in_uts_namespace; ++} +diff --git a/support/support_format_address_family.c b/support/support_format_address_family.c +new file mode 100644 +index 0000000000..2acb9afffd +--- /dev/null ++++ b/support/support_format_address_family.c +@@ -0,0 +1,35 @@ ++/* Convert an address family to a string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++char * ++support_format_address_family (int family) ++{ ++ switch (family) ++ { ++ case AF_INET: ++ return xstrdup ("INET"); ++ case AF_INET6: ++ return xstrdup ("INET6"); ++ default: ++ return xasprintf ("", family); ++ } ++} +diff --git a/support/support_format_addrinfo.c b/support/support_format_addrinfo.c +new file mode 100644 +index 0000000000..c5e00e516a +--- /dev/null ++++ b/support/support_format_addrinfo.c +@@ -0,0 +1,240 @@ ++/* Convert struct addrinfo values to a string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static size_t ++socket_address_length (int family) ++{ ++ switch (family) ++ { ++ case AF_INET: ++ return sizeof (struct sockaddr_in); ++ case AF_INET6: ++ return sizeof (struct sockaddr_in6); ++ default: ++ return -1; ++ } ++} ++ ++static void ++format_ai_flags_1 (FILE *out, struct addrinfo *ai, int flag, const char *name, ++ int * flags_printed) ++{ ++ if ((ai->ai_flags & flag) != 0) ++ fprintf (out, " %s", name); ++ *flags_printed |= flag; ++} ++ ++static void ++format_ai_flags (FILE *out, struct addrinfo *ai) ++{ ++ if (ai == NULL) ++ return; ++ ++ if (ai->ai_flags != 0) ++ { ++ fprintf (out, "flags:"); ++ int flags_printed = 0; ++#define FLAG(flag) format_ai_flags_1 (out, ai, flag, #flag, &flags_printed) ++ FLAG (AI_PASSIVE); ++ FLAG (AI_CANONNAME); ++ FLAG (AI_NUMERICHOST); ++ FLAG (AI_V4MAPPED); ++ FLAG (AI_ALL); ++ FLAG (AI_ADDRCONFIG); ++ FLAG (AI_IDN); ++ FLAG (AI_CANONIDN); ++ FLAG (AI_IDN_ALLOW_UNASSIGNED); ++ FLAG (AI_IDN_USE_STD3_ASCII_RULES); ++ FLAG (AI_NUMERICSERV); ++#undef FLAG ++ int remaining = ai->ai_flags & ~flags_printed; ++ if (remaining != 0) ++ fprintf (out, " %08x", remaining); ++ fprintf (out, "\n"); ++ } ++ ++ /* Report flag mismatches within the list. */ ++ int flags = ai->ai_flags; ++ int index = 1; ++ ai = ai->ai_next; ++ while (ai != NULL) ++ { ++ if (ai->ai_flags != flags) ++ fprintf (out, "error: flags at %d: 0x%x expected, 0x%x actual\n", ++ index, flags, ai->ai_flags); ++ ai = ai->ai_next; ++ ++index; ++ } ++} ++ ++static void ++format_ai_canonname (FILE *out, struct addrinfo *ai) ++{ ++ if (ai == NULL) ++ return; ++ if (ai->ai_canonname != NULL) ++ fprintf (out, "canonname: %s\n", ai->ai_canonname); ++ ++ /* Report incorrectly set ai_canonname fields on subsequent list ++ entries. */ ++ int index = 1; ++ ai = ai->ai_next; ++ while (ai != NULL) ++ { ++ if (ai->ai_canonname != NULL) ++ fprintf (out, "error: canonname set at %d: %s\n", ++ index, ai->ai_canonname); ++ ai = ai->ai_next; ++ ++index; ++ } ++} ++ ++static void ++format_ai_one (FILE *out, struct addrinfo *ai) ++{ ++ { ++ char type_buf[32]; ++ const char *type_str; ++ char proto_buf[32]; ++ const char *proto_str; ++ ++ /* ai_socktype */ ++ switch (ai->ai_socktype) ++ { ++ case SOCK_RAW: ++ type_str = "RAW"; ++ break; ++ case SOCK_DGRAM: ++ type_str = "DGRAM"; ++ break; ++ case SOCK_STREAM: ++ type_str = "STREAM"; ++ break; ++ default: ++ snprintf (type_buf, sizeof (type_buf), "%d", ai->ai_socktype); ++ type_str = type_buf; ++ } ++ ++ /* ai_protocol */ ++ switch (ai->ai_protocol) ++ { ++ case IPPROTO_IP: ++ proto_str = "IP"; ++ break; ++ case IPPROTO_UDP: ++ proto_str = "UDP"; ++ break; ++ case IPPROTO_TCP: ++ proto_str = "TCP"; ++ break; ++ default: ++ snprintf (proto_buf, sizeof (proto_buf), "%d", ai->ai_protocol); ++ proto_str = proto_buf; ++ } ++ fprintf (out, "address: %s/%s", type_str, proto_str); ++ } ++ ++ /* ai_addrlen */ ++ if (ai->ai_addrlen != socket_address_length (ai->ai_family)) ++ { ++ char *family = support_format_address_family (ai->ai_family); ++ fprintf (out, "error: invalid address length %d for %s\n", ++ ai->ai_addrlen, family); ++ free (family); ++ } ++ ++ /* ai_addr */ ++ { ++ char buf[128]; ++ uint16_t port; ++ const char *ret; ++ switch (ai->ai_family) ++ { ++ case AF_INET: ++ { ++ struct sockaddr_in *sin = (struct sockaddr_in *) ai->ai_addr; ++ ret = inet_ntop (AF_INET, &sin->sin_addr, buf, sizeof (buf)); ++ port = sin->sin_port; ++ } ++ break; ++ case AF_INET6: ++ { ++ struct sockaddr_in6 *sin = (struct sockaddr_in6 *) ai->ai_addr; ++ ret = inet_ntop (AF_INET6, &sin->sin6_addr, buf, sizeof (buf)); ++ port = sin->sin6_port; ++ } ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ ret = NULL; ++ } ++ if (ret == NULL) ++ fprintf (out, "error: inet_top failed: %m\n"); ++ else ++ fprintf (out, " %s %u\n", buf, ntohs (port)); ++ } ++} ++ ++/* Format all the addresses in one address family. */ ++static void ++format_ai_family (FILE *out, struct addrinfo *ai, int family) ++{ ++ while (ai) ++ { ++ if (ai->ai_family == family) ++ format_ai_one (out, ai); ++ ai = ai->ai_next; ++ } ++} ++ ++char * ++support_format_addrinfo (struct addrinfo *ai, int ret) ++{ ++ int errno_copy = errno; ++ ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ if (ret != 0) ++ { ++ fprintf (mem.out, "error: %s\n", gai_strerror (ret)); ++ if (ret == EAI_SYSTEM) ++ { ++ errno = errno_copy; ++ fprintf (mem.out, "error: %m\n"); ++ } ++ } ++ else ++ { ++ format_ai_flags (mem.out, ai); ++ format_ai_canonname (mem.out, ai); ++ format_ai_family (mem.out, ai, AF_INET); ++ format_ai_family (mem.out, ai, AF_INET6); ++ } ++ ++ xfclose_memstream (&mem); ++ return mem.buffer; ++} +diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c +new file mode 100644 +index 0000000000..1170eafb0f +--- /dev/null ++++ b/support/support_format_dns_packet.c +@@ -0,0 +1,223 @@ ++/* Convert a DNS packet to a human-readable representation. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct in_buffer ++{ ++ const unsigned char *data; ++ size_t size; ++}; ++ ++static inline bool ++extract_8 (struct in_buffer *in, unsigned char *value) ++{ ++ if (in->size == 0) ++ return false; ++ *value = in->data[0]; ++ ++in->data; ++ --in->size; ++ return true; ++} ++ ++static inline bool ++extract_16 (struct in_buffer *in, unsigned short *value) ++{ ++ if (in->size < 2) ++ return false; ++ *value = (in->data[0] << 8) | in->data[1]; ++ in->data += 2; ++ in->size -= 2; ++ return true; ++} ++ ++static inline bool ++extract_32 (struct in_buffer *in, unsigned *value) ++{ ++ if (in->size < 4) ++ return false; ++ unsigned a = in->data[0]; ++ unsigned b = in->data[1]; ++ unsigned c = in->data[2]; ++ unsigned d = in->data[3]; ++ *value = (a << 24) | (b << 16) | (c << 8) | d; ++ in->data += 4; ++ in->size -= 4; ++ return true; ++} ++ ++static inline bool ++extract_bytes (struct in_buffer *in, size_t length, struct in_buffer *value) ++{ ++ if (in->size < length) ++ return false; ++ *value = (struct in_buffer) {in->data, length}; ++ in->data += length; ++ in->size -= length; ++ return true; ++} ++ ++struct dname ++{ ++ char name[MAXDNAME + 1]; ++}; ++ ++static bool ++extract_name (struct in_buffer full, struct in_buffer *in, struct dname *value) ++{ ++ const unsigned char *full_end = full.data + full.size; ++ /* Sanity checks; these indicate buffer misuse. */ ++ TEST_VERIFY_EXIT ++ (!(in->data < full.data || in->data > full_end ++ || in->size > (size_t) (full_end - in->data))); ++ int ret = dn_expand (full.data, full_end, in->data, ++ value->name, sizeof (value->name)); ++ if (ret < 0) ++ return false; ++ in->data += ret; ++ in->size -= ret; ++ return true; ++} ++ ++char * ++support_format_dns_packet (const unsigned char *buffer, size_t length) ++{ ++ struct in_buffer full = { buffer, length }; ++ struct in_buffer in = full; ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ ++ unsigned short txnid; ++ unsigned short flags; ++ unsigned short qdcount; ++ unsigned short ancount; ++ unsigned short nscount; ++ unsigned short adcount; ++ if (!(extract_16 (&in, &txnid) ++ && extract_16 (&in, &flags) ++ && extract_16 (&in, &qdcount) ++ && extract_16 (&in, &ancount) ++ && extract_16 (&in, &nscount) ++ && extract_16 (&in, &adcount))) ++ { ++ fprintf (mem.out, "error: could not parse DNS header\n"); ++ goto out; ++ } ++ if (qdcount != 1) ++ { ++ fprintf (mem.out, "error: question count is %d, not 1\n", qdcount); ++ goto out; ++ } ++ struct dname qname; ++ if (!extract_name (full, &in, &qname)) ++ { ++ fprintf (mem.out, "error: malformed QNAME\n"); ++ goto out; ++ } ++ unsigned short qtype; ++ unsigned short qclass; ++ if (!(extract_16 (&in, &qtype) ++ && extract_16 (&in, &qclass))) ++ { ++ fprintf (mem.out, "error: malformed question\n"); ++ goto out; ++ } ++ if (qtype != T_A && qtype != T_AAAA && qtype != T_PTR) ++ { ++ fprintf (mem.out, "error: unsupported QTYPE %d\n", qtype); ++ goto out; ++ } ++ ++ fprintf (mem.out, "name: %s\n", qname.name); ++ ++ for (int i = 0; i < ancount; ++i) ++ { ++ struct dname rname; ++ if (!extract_name (full, &in, &rname)) ++ { ++ fprintf (mem.out, "error: malformed record name\n"); ++ goto out; ++ } ++ unsigned short rtype; ++ unsigned short rclass; ++ unsigned ttl; ++ unsigned short rdlen; ++ struct in_buffer rdata; ++ if (!(extract_16 (&in, &rtype) ++ && extract_16 (&in, &rclass) ++ && extract_32 (&in, &ttl) ++ && extract_16 (&in, &rdlen) ++ && extract_bytes (&in, rdlen, &rdata))) ++ { ++ fprintf (mem.out, "error: malformed record header\n"); ++ goto out; ++ } ++ /* Skip non-matching record types. */ ++ if ((rtype != qtype && rtype != T_CNAME) || rclass != qclass) ++ continue; ++ switch (rtype) ++ { ++ case T_A: ++ if (rdlen == 4) ++ fprintf (mem.out, "address: %d.%d.%d.%d\n", ++ rdata.data[0], ++ rdata.data[1], ++ rdata.data[2], ++ rdata.data[3]); ++ else ++ fprintf (mem.out, "error: A record of size %d: %s\n", ++ rdlen, rname.name); ++ break; ++ case T_AAAA: ++ { ++ if (rdlen == 16) ++ { ++ char buf[100]; ++ if (inet_ntop (AF_INET6, rdata.data, buf, sizeof (buf)) == NULL) ++ fprintf (mem.out, "error: AAAA record decoding failed: %m\n"); ++ else ++ fprintf (mem.out, "address: %s\n", buf); ++ } ++ else ++ fprintf (mem.out, "error: AAAA record of size %d: %s\n", ++ rdlen, rname.name); ++ } ++ break; ++ case T_CNAME: ++ case T_PTR: ++ { ++ struct dname name; ++ if (extract_name (full, &rdata, &name)) ++ fprintf (mem.out, "name: %s\n", name.name); ++ else ++ fprintf (mem.out, "error: malformed CNAME/PTR record\n"); ++ } ++ } ++ } ++ ++ out: ++ xfclose_memstream (&mem); ++ return mem.buffer; ++} +diff --git a/support/support_format_herrno.c b/support/support_format_herrno.c +new file mode 100644 +index 0000000000..3d2dc8b27a +--- /dev/null ++++ b/support/support_format_herrno.c +@@ -0,0 +1,45 @@ ++/* Convert a h_errno error code to a string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++char * ++support_format_herrno (int code) ++{ ++ const char *errstr; ++ switch (code) ++ { ++ case HOST_NOT_FOUND: ++ errstr = "HOST_NOT_FOUND"; ++ break; ++ case NO_ADDRESS: ++ errstr = "NO_ADDRESS"; ++ break; ++ case NO_RECOVERY: ++ errstr = "NO_RECOVERY"; ++ break; ++ case TRY_AGAIN: ++ errstr = "TRY_AGAIN"; ++ break; ++ default: ++ return xasprintf ("\n", code); ++ } ++ return xstrdup (errstr); ++} +diff --git a/support/support_format_hostent.c b/support/support_format_hostent.c +new file mode 100644 +index 0000000000..a4a62afe0a +--- /dev/null ++++ b/support/support_format_hostent.c +@@ -0,0 +1,82 @@ ++/* Convert a struct hostent object to a string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++address_length (int family) ++{ ++ switch (family) ++ { ++ case AF_INET: ++ return 4; ++ case AF_INET6: ++ return 16; ++ } ++ return -1; ++} ++ ++char * ++support_format_hostent (struct hostent *h) ++{ ++ if (h == NULL) ++ { ++ if (h_errno == NETDB_INTERNAL) ++ return xasprintf ("error: NETDB_INTERNAL (errno %d, %m)\n", errno); ++ else ++ { ++ char *value = support_format_herrno (h_errno); ++ char *result = xasprintf ("error: %s\n", value); ++ free (value); ++ return result; ++ } ++ } ++ ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ ++ fprintf (mem.out, "name: %s\n", h->h_name); ++ for (char **alias = h->h_aliases; *alias != NULL; ++alias) ++ fprintf (mem.out, "alias: %s\n", *alias); ++ for (unsigned i = 0; h->h_addr_list[i] != NULL; ++i) ++ { ++ char buf[128]; ++ if (inet_ntop (h->h_addrtype, h->h_addr_list[i], ++ buf, sizeof (buf)) == NULL) ++ fprintf (mem.out, "error: inet_ntop failed: %m\n"); ++ else ++ fprintf (mem.out, "address: %s\n", buf); ++ } ++ if (h->h_length != address_length (h->h_addrtype)) ++ { ++ char *family = support_format_address_family (h->h_addrtype); ++ fprintf (mem.out, "error: invalid address length %d for %s\n", ++ h->h_length, family); ++ free (family); ++ } ++ ++ xfclose_memstream (&mem); ++ return mem.buffer; ++} +diff --git a/support/support_format_netent.c b/support/support_format_netent.c +new file mode 100644 +index 0000000000..0d15e78440 +--- /dev/null ++++ b/support/support_format_netent.c +@@ -0,0 +1,53 @@ ++/* Convert a struct netent object to a string. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++char * ++support_format_netent (struct netent *e) ++{ ++ if (e == NULL) ++ { ++ char *value = support_format_herrno (h_errno); ++ char *result = xasprintf ("error: %s\n", value); ++ free (value); ++ return result; ++ } ++ ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ ++ if (e->n_name != NULL) ++ fprintf (mem.out, "name: %s\n", e->n_name); ++ for (char **ap = e->n_aliases; *ap != NULL; ++ap) ++ fprintf (mem.out, "alias: %s\n", *ap); ++ if (e->n_addrtype != AF_INET) ++ fprintf (mem.out, "addrtype: %d\n", e->n_addrtype); ++ /* On alpha, e->n_net is an unsigned long. */ ++ unsigned int n_net = e->n_net; ++ fprintf (mem.out, "net: 0x%08x\n", n_net); ++ ++ xfclose_memstream (&mem); ++ return mem.buffer; ++} +diff --git a/support/support_isolate_in_subprocess.c b/support/support_isolate_in_subprocess.c +new file mode 100644 +index 0000000000..25edc00385 +--- /dev/null ++++ b/support/support_isolate_in_subprocess.c +@@ -0,0 +1,38 @@ ++/* Run a function in a subprocess. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++support_isolate_in_subprocess (void (*callback) (void *), void *closure) ++{ ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ /* Child process. */ ++ callback (closure); ++ _exit (0); ++ } ++ ++ /* Parent process. */ ++ int status; ++ xwaitpid (pid, &status, 0); ++ if (status != 0) ++ FAIL_EXIT1 ("child process exited with status %d", status); ++} +diff --git a/support/support_record_failure.c b/support/support_record_failure.c +new file mode 100644 +index 0000000000..356798f556 +--- /dev/null ++++ b/support/support_record_failure.c +@@ -0,0 +1,106 @@ ++/* Global test failure counter. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* This structure keeps track of test failures. The counter is ++ incremented on each failure. The failed member is set to true if a ++ failure is detected, so that even if the counter wraps around to ++ zero, the failure of a test can be detected. ++ ++ The init constructor function below puts *state on a shared ++ annonymous mapping, so that failure reports from subprocesses ++ propagate to the parent process. */ ++struct test_failures ++{ ++ unsigned int counter; ++ unsigned int failed; ++}; ++static struct test_failures *state; ++ ++static __attribute__ ((constructor)) void ++init (void) ++{ ++ void *ptr = mmap (NULL, sizeof (*state), PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_SHARED, -1, 0); ++ if (ptr == MAP_FAILED) ++ { ++ printf ("error: could not map %zu bytes: %m\n", sizeof (*state)); ++ exit (1); ++ } ++ /* Zero-initialization of the struct is sufficient. */ ++ state = ptr; ++} ++ ++void ++support_record_failure (void) ++{ ++ if (state == NULL) ++ { ++ write_message ++ ("error: support_record_failure called without initialization\n"); ++ _exit (1); ++ } ++ /* Relaxed MO is sufficient because we are only interested in the ++ values themselves, in isolation. */ ++ __atomic_store_n (&state->failed, 1, __ATOMIC_RELEASE); ++ __atomic_add_fetch (&state->counter, 1, __ATOMIC_RELEASE); ++} ++ ++int ++support_report_failure (int status) ++{ ++ if (state == NULL) ++ { ++ write_message ++ ("error: support_report_failure called without initialization\n"); ++ return 1; ++ } ++ ++ /* Relaxed MO is sufficient because acquire test result reporting ++ assumes that exiting from the main thread happens before the ++ error reporting via support_record_failure, which requires some ++ form of external synchronization. */ ++ bool failed = __atomic_load_n (&state->failed, __ATOMIC_RELAXED); ++ if (failed) ++ printf ("error: %u test failures\n", ++ __atomic_load_n (&state->counter, __ATOMIC_RELAXED)); ++ ++ if ((status == 0 || status == EXIT_UNSUPPORTED) && failed) ++ /* If we have a recorded failure, it overrides a non-failure ++ report from the test function. */ ++ status = 1; ++ return status; ++} ++ ++void ++support_record_failure_reset (void) ++{ ++ /* Only used for testing the test framework, with external ++ synchronization, but use release MO for consistency. */ ++ __atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED); ++ __atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED); ++} +diff --git a/support/support_run_diff.c b/support/support_run_diff.c +new file mode 100644 +index 0000000000..f24f6c3281 +--- /dev/null ++++ b/support/support_run_diff.c +@@ -0,0 +1,76 @@ ++/* Invoke the system diff tool to compare two strings. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static char * ++write_to_temp_file (const char *prefix, const char *str) ++{ ++ char *template = xasprintf ("run_diff-%s", prefix); ++ char *name = NULL; ++ int fd = create_temp_file (template, &name); ++ TEST_VERIFY_EXIT (fd >= 0); ++ free (template); ++ xwrite (fd, str, strlen (str)); ++ xclose (fd); ++ return name; ++} ++ ++void ++support_run_diff (const char *left_label, const char *left, ++ const char *right_label, const char *right) ++{ ++ /* Ensure that the diff command output is ordered properly with ++ standard output. */ ++ TEST_VERIFY_EXIT (fflush (stdout) == 0); ++ ++ char *left_path = write_to_temp_file ("left-diff", left); ++ char *right_path = write_to_temp_file ("right-diff", right); ++ ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ execlp ("diff", "diff", "-u", ++ "--label", left_label, "--label", right_label, ++ "--", left_path, right_path, ++ NULL); ++ _exit (17); ++ } ++ else ++ { ++ int status; ++ xwaitpid (pid, &status, 0); ++ if (!WIFEXITED (status) || WEXITSTATUS (status) != 1) ++ printf ("warning: could not run diff, exit status: %d\n" ++ "*** %s ***\n%s\n" ++ "*** %s ***\n%s\n", ++ status, left_label, left, right_label, right); ++ } ++ ++ free (right_path); ++ free (left_path); ++} +diff --git a/support/support_shared_allocate.c b/support/support_shared_allocate.c +new file mode 100644 +index 0000000000..8ab43c4b38 +--- /dev/null ++++ b/support/support_shared_allocate.c +@@ -0,0 +1,57 @@ ++/* Allocate a memory region shared across processes. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Header for the allocation. It contains the size of the allocation ++ for subsequent unmapping. */ ++struct header ++{ ++ size_t total_size; ++ char data[] __attribute__ ((aligned (__alignof__ (max_align_t)))); ++}; ++ ++void * ++support_shared_allocate (size_t size) ++{ ++ size_t total_size = size + offsetof (struct header, data); ++ if (total_size < size) ++ { ++ errno = ENOMEM; ++ oom_error (__func__, size); ++ return NULL; ++ } ++ else ++ { ++ struct header *result = xmmap (NULL, total_size, PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_SHARED, -1); ++ result->total_size = total_size; ++ return &result->data; ++ } ++} ++ ++void ++support_shared_free (void *data) ++{ ++ struct header *header = data - offsetof (struct header, data); ++ xmunmap (header, header->total_size); ++} +diff --git a/support/support_test_compare_failure.c b/support/support_test_compare_failure.c +new file mode 100644 +index 0000000000..e5596fd121 +--- /dev/null ++++ b/support/support_test_compare_failure.c +@@ -0,0 +1,55 @@ ++/* Reporting a numeric comparison failure. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++static void ++report (const char *which, const char *expr, long long value, int positive, ++ int size) ++{ ++ printf (" %s: ", which); ++ if (positive) ++ printf ("%llu", (unsigned long long) value); ++ else ++ printf ("%lld", value); ++ unsigned long long mask ++ = (~0ULL) >> (8 * (sizeof (unsigned long long) - size)); ++ printf (" (0x%llx); from: %s\n", (unsigned long long) value & mask, expr); ++} ++ ++void ++support_test_compare_failure (const char *file, int line, ++ const char *left_expr, ++ long long left_value, ++ int left_positive, ++ int left_size, ++ const char *right_expr, ++ long long right_value, ++ int right_positive, ++ int right_size) ++{ ++ support_record_failure (); ++ if (left_size != right_size) ++ printf ("%s:%d: numeric comparison failure (widths %d and %d)\n", ++ file, line, left_size * 8, right_size * 8); ++ else ++ printf ("%s:%d: numeric comparison failure\n", file, line); ++ report (" left", left_expr, left_value, left_positive, left_size); ++ report ("right", right_expr, right_value, right_positive, right_size); ++} +diff --git a/support/support_test_main.c b/support/support_test_main.c +new file mode 100644 +index 0000000000..396385729b +--- /dev/null ++++ b/support/support_test_main.c +@@ -0,0 +1,424 @@ ++/* Main worker function for the test driver. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const struct option default_options[] = ++{ ++ TEST_DEFAULT_OPTIONS ++ { NULL, 0, NULL, 0 } ++}; ++ ++/* Show people how to run the program. */ ++static void ++usage (const struct option *options) ++{ ++ size_t i; ++ ++ printf ("Usage: %s [options]\n" ++ "\n" ++ "Environment Variables:\n" ++ " TIMEOUTFACTOR An integer used to scale the timeout\n" ++ " TMPDIR Where to place temporary files\n" ++ " TEST_COREDUMPS Do not disable coredumps if set\n" ++ "\n", ++ program_invocation_short_name); ++ printf ("Options:\n"); ++ for (i = 0; options[i].name; ++i) ++ { ++ int indent; ++ ++ indent = printf (" --%s", options[i].name); ++ if (options[i].has_arg == required_argument) ++ indent += printf (" "); ++ printf ("%*s", 25 - indent, ""); ++ switch (options[i].val) ++ { ++ case 'v': ++ printf ("Increase the output verbosity"); ++ break; ++ case OPT_DIRECT: ++ printf ("Run the test directly (instead of forking & monitoring)"); ++ break; ++ case OPT_TESTDIR: ++ printf ("Override the TMPDIR env var"); ++ break; ++ } ++ printf ("\n"); ++ } ++} ++ ++/* The PID of the test process. */ ++static pid_t test_pid; ++ ++/* The cleanup handler passed to test_main. */ ++static void (*cleanup_function) (void); ++ ++/* Timeout handler. We kill the child and exit with an error. */ ++static void ++__attribute__ ((noreturn)) ++signal_handler (int sig) ++{ ++ int killed; ++ int status; ++ ++ assert (test_pid > 1); ++ /* Kill the whole process group. */ ++ kill (-test_pid, SIGKILL); ++ /* In case setpgid failed in the child, kill it individually too. */ ++ kill (test_pid, SIGKILL); ++ ++ /* Wait for it to terminate. */ ++ int i; ++ for (i = 0; i < 5; ++i) ++ { ++ killed = waitpid (test_pid, &status, WNOHANG|WUNTRACED); ++ if (killed != 0) ++ break; ++ ++ /* Delay, give the system time to process the kill. If the ++ nanosleep() call return prematurely, all the better. We ++ won't restart it since this probably means the child process ++ finally died. */ ++ struct timespec ts; ++ ts.tv_sec = 0; ++ ts.tv_nsec = 100000000; ++ nanosleep (&ts, NULL); ++ } ++ if (killed != 0 && killed != test_pid) ++ { ++ printf ("Failed to kill test process: %m\n"); ++ exit (1); ++ } ++ ++ if (cleanup_function != NULL) ++ cleanup_function (); ++ ++ if (sig == SIGINT) ++ { ++ signal (sig, SIG_DFL); ++ raise (sig); ++ } ++ ++ if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL)) ++ puts ("Timed out: killed the child process"); ++ else if (WIFSTOPPED (status)) ++ printf ("Timed out: the child process was %s\n", ++ strsignal (WSTOPSIG (status))); ++ else if (WIFSIGNALED (status)) ++ printf ("Timed out: the child process got signal %s\n", ++ strsignal (WTERMSIG (status))); ++ else ++ printf ("Timed out: killed the child process but it exited %d\n", ++ WEXITSTATUS (status)); ++ ++ /* Exit with an error. */ ++ exit (1); ++} ++ ++/* Run test_function or test_function_argv. */ ++static int ++run_test_function (int argc, char **argv, const struct test_config *config) ++{ ++ if (config->test_function != NULL) ++ return config->test_function (); ++ else if (config->test_function_argv != NULL) ++ return config->test_function_argv (argc, argv); ++ else ++ { ++ printf ("error: no test function defined\n"); ++ exit (1); ++ } ++} ++ ++static bool test_main_called; ++ ++const char *test_dir = NULL; ++unsigned int test_verbose = 0; ++ ++/* If test failure reporting has been linked in, it may contribute ++ additional test failures. */ ++static int ++adjust_exit_status (int status) ++{ ++ if (support_report_failure != NULL) ++ return support_report_failure (status); ++ return status; ++} ++ ++int ++support_test_main (int argc, char **argv, const struct test_config *config) ++{ ++ if (test_main_called) ++ { ++ printf ("error: test_main called for a second time\n"); ++ exit (1); ++ } ++ test_main_called = true; ++ const struct option *options; ++ if (config->options != NULL) ++ options = config->options; ++ else ++ options = default_options; ++ ++ cleanup_function = config->cleanup_function; ++ ++ int direct = 0; /* Directly call the test function? */ ++ int status; ++ int opt; ++ unsigned int timeoutfactor = 1; ++ pid_t termpid; ++ ++ if (!config->no_mallopt) ++ { ++ /* Make uses of freed and uninitialized memory known. Do not ++ pull in a definition for mallopt if it has not been defined ++ already. */ ++ extern __typeof__ (mallopt) mallopt __attribute__ ((weak)); ++ if (mallopt != NULL) ++ mallopt (M_PERTURB, 42); ++ } ++ ++ while ((opt = getopt_long (argc, argv, config->optstring, options, NULL)) ++ != -1) ++ switch (opt) ++ { ++ case '?': ++ usage (options); ++ exit (1); ++ case 'v': ++ ++test_verbose; ++ break; ++ case OPT_DIRECT: ++ direct = 1; ++ break; ++ case OPT_TESTDIR: ++ test_dir = optarg; ++ break; ++ default: ++ if (config->cmdline_function != NULL) ++ config->cmdline_function (opt); ++ } ++ ++ /* If set, read the test TIMEOUTFACTOR value from the environment. ++ This value is used to scale the default test timeout values. */ ++ char *envstr_timeoutfactor = getenv ("TIMEOUTFACTOR"); ++ if (envstr_timeoutfactor != NULL) ++ { ++ char *envstr_conv = envstr_timeoutfactor; ++ unsigned long int env_fact; ++ ++ env_fact = strtoul (envstr_timeoutfactor, &envstr_conv, 0); ++ if (*envstr_conv == '\0' && envstr_conv != envstr_timeoutfactor) ++ timeoutfactor = MAX (env_fact, 1); ++ } ++ ++ /* Set TMPDIR to specified test directory. */ ++ if (test_dir != NULL) ++ { ++ setenv ("TMPDIR", test_dir, 1); ++ ++ if (chdir (test_dir) < 0) ++ { ++ printf ("chdir: %m\n"); ++ exit (1); ++ } ++ } ++ else ++ { ++ test_dir = getenv ("TMPDIR"); ++ if (test_dir == NULL || test_dir[0] == '\0') ++ test_dir = "/tmp"; ++ } ++ if (support_set_test_dir != NULL) ++ support_set_test_dir (test_dir); ++ ++ int timeout = config->timeout; ++ if (timeout == 0) ++ timeout = DEFAULT_TIMEOUT; ++ ++ /* Make sure we see all message, even those on stdout. */ ++ setvbuf (stdout, NULL, _IONBF, 0); ++ ++ /* Make sure temporary files are deleted. */ ++ if (support_delete_temp_files != NULL) ++ atexit (support_delete_temp_files); ++ ++ /* Correct for the possible parameters. */ ++ argv[optind - 1] = argv[0]; ++ argv += optind - 1; ++ argc -= optind - 1; ++ ++ /* Call the initializing function, if one is available. */ ++ if (config->prepare_function != NULL) ++ config->prepare_function (argc, argv); ++ ++ const char *envstr_direct = getenv ("TEST_DIRECT"); ++ if (envstr_direct != NULL) ++ { ++ FILE *f = fopen (envstr_direct, "w"); ++ if (f == NULL) ++ { ++ printf ("cannot open TEST_DIRECT output file '%s': %m\n", ++ envstr_direct); ++ exit (1); ++ } ++ ++ fprintf (f, "timeout=%u\ntimeoutfactor=%u\n", ++ config->timeout, timeoutfactor); ++ if (config->expected_status != 0) ++ fprintf (f, "exit=%u\n", config->expected_status); ++ if (config->expected_signal != 0) ++ fprintf (f, "signal=%s\n", strsignal (config->expected_signal)); ++ ++ if (support_print_temp_files != NULL) ++ support_print_temp_files (f); ++ ++ fclose (f); ++ direct = 1; ++ } ++ ++ bool disable_coredumps; ++ { ++ const char *coredumps = getenv ("TEST_COREDUMPS"); ++ disable_coredumps = coredumps == NULL || coredumps[0] == '\0'; ++ } ++ ++ /* If we are not expected to fork run the function immediately. */ ++ if (direct) ++ return adjust_exit_status (run_test_function (argc, argv, config)); ++ ++ /* Set up the test environment: ++ - prevent core dumps ++ - set up the timer ++ - fork and execute the function. */ ++ ++ test_pid = fork (); ++ if (test_pid == 0) ++ { ++ /* This is the child. */ ++ if (disable_coredumps) ++ { ++ /* Try to avoid dumping core. This is necessary because we ++ run the test from the source tree, and the coredumps ++ would end up there (and not in the build tree). */ ++ struct rlimit core_limit; ++ core_limit.rlim_cur = 0; ++ core_limit.rlim_max = 0; ++ setrlimit (RLIMIT_CORE, &core_limit); ++ } ++ ++ /* We put the test process in its own pgrp so that if it bogusly ++ generates any job control signals, they won't hit the whole build. */ ++ if (setpgid (0, 0) != 0) ++ printf ("Failed to set the process group ID: %m\n"); ++ ++ /* Execute the test function and exit with the return value. */ ++ exit (run_test_function (argc, argv, config)); ++ } ++ else if (test_pid < 0) ++ { ++ printf ("Cannot fork test program: %m\n"); ++ exit (1); ++ } ++ ++ /* Set timeout. */ ++ signal (SIGALRM, signal_handler); ++ alarm (timeout * timeoutfactor); ++ ++ /* Make sure we clean up if the wrapper gets interrupted. */ ++ signal (SIGINT, signal_handler); ++ ++ /* Wait for the regular termination. */ ++ termpid = TEMP_FAILURE_RETRY (waitpid (test_pid, &status, 0)); ++ if (termpid == -1) ++ { ++ printf ("Waiting for test program failed: %m\n"); ++ exit (1); ++ } ++ if (termpid != test_pid) ++ { ++ printf ("Oops, wrong test program terminated: expected %ld, got %ld\n", ++ (long int) test_pid, (long int) termpid); ++ exit (1); ++ } ++ ++ /* Process terminated normaly without timeout etc. */ ++ if (WIFEXITED (status)) ++ { ++ if (config->expected_status == 0) ++ { ++ if (config->expected_signal == 0) ++ /* Exit with the return value of the test. */ ++ return adjust_exit_status (WEXITSTATUS (status)); ++ else ++ { ++ printf ("Expected signal '%s' from child, got none\n", ++ strsignal (config->expected_signal)); ++ exit (1); ++ } ++ } ++ else ++ { ++ /* Non-zero exit status is expected */ ++ if (WEXITSTATUS (status) != config->expected_status) ++ { ++ printf ("Expected status %d, got %d\n", ++ config->expected_status, WEXITSTATUS (status)); ++ exit (1); ++ } ++ } ++ return adjust_exit_status (0); ++ } ++ /* Process was killed by timer or other signal. */ ++ else ++ { ++ if (config->expected_signal == 0) ++ { ++ printf ("Didn't expect signal from child: got `%s'\n", ++ strsignal (WTERMSIG (status))); ++ exit (1); ++ } ++ else if (WTERMSIG (status) != config->expected_signal) ++ { ++ printf ("Incorrect signal from child: got `%s', need `%s'\n", ++ strsignal (WTERMSIG (status)), ++ strsignal (config->expected_signal)); ++ exit (1); ++ } ++ ++ return adjust_exit_status (0); ++ } ++} +diff --git a/support/support_test_verify_impl.c b/support/support_test_verify_impl.c +new file mode 100644 +index 0000000000..80311a8265 +--- /dev/null ++++ b/support/support_test_verify_impl.c +@@ -0,0 +1,37 @@ ++/* Implementation of the TEST_VERIFY and TEST_VERIFY_EXIT macros. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++void ++support_test_verify_impl (const char *file, int line, const char *expr) ++{ ++ support_record_failure (); ++ printf ("error: %s:%d: not true: %s\n", file, line, expr); ++} ++ ++void ++support_test_verify_exit_impl (int status, const char *file, int line, ++ const char *expr) ++{ ++ support_test_verify_impl (file, line, expr); ++ exit (status); ++} +diff --git a/support/support_write_file_string.c b/support/support_write_file_string.c +new file mode 100644 +index 0000000000..7505679401 +--- /dev/null ++++ b/support/support_write_file_string.c +@@ -0,0 +1,39 @@ ++/* Write a string to a file. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++void ++support_write_file_string (const char *path, const char *contents) ++{ ++ int fd = xopen (path, O_CREAT | O_TRUNC | O_WRONLY, 0666); ++ const char *end = contents + strlen (contents); ++ for (const char *p = contents; p < end; ) ++ { ++ ssize_t ret = write (fd, p, end - p); ++ if (ret < 0) ++ FAIL_EXIT1 ("cannot write to \"%s\": %m", path); ++ if (ret == 0) ++ FAIL_EXIT1 ("zero-length write to \"%s\"", path); ++ p += ret; ++ } ++ xclose (fd); ++} +diff --git a/support/temp_file-internal.h b/support/temp_file-internal.h +new file mode 100644 +index 0000000000..4cee3c0c35 +--- /dev/null ++++ b/support/temp_file-internal.h +@@ -0,0 +1,31 @@ ++/* Internal weak declarations for temporary file handling. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_TEMP_FILE_INTERNAL_H ++#define SUPPORT_TEMP_FILE_INTERNAL_H ++ ++/* These functions are called by the test driver if they are ++ defined. Tests should not call them directly. */ ++ ++#include ++ ++void support_set_test_dir (const char *name) __attribute__ ((weak)); ++void support_delete_temp_files (void) __attribute__ ((weak)); ++void support_print_temp_files (FILE *) __attribute__ ((weak)); ++ ++#endif /* SUPPORT_TEMP_FILE_INTERNAL_H */ +diff --git a/support/temp_file.c b/support/temp_file.c +new file mode 100644 +index 0000000000..0bbc7f9972 +--- /dev/null ++++ b/support/temp_file.c +@@ -0,0 +1,145 @@ ++/* Temporary file handling for tests. ++ Copyright (C) 1998-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This is required to get an mkstemp which can create large files on ++ some 32-bit platforms. */ ++#define _FILE_OFFSET_BITS 64 ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* List of temporary files. */ ++static struct temp_name_list ++{ ++ struct temp_name_list *next; ++ char *name; ++ pid_t owner; ++} *temp_name_list; ++ ++/* Location of the temporary files. Set by the test skeleton via ++ support_set_test_dir. The string is not be freed. */ ++static const char *test_dir = _PATH_TMP; ++ ++void ++add_temp_file (const char *name) ++{ ++ struct temp_name_list *newp ++ = (struct temp_name_list *) xcalloc (sizeof (*newp), 1); ++ char *newname = strdup (name); ++ if (newname != NULL) ++ { ++ newp->name = newname; ++ newp->next = temp_name_list; ++ newp->owner = getpid (); ++ temp_name_list = newp; ++ } ++ else ++ free (newp); ++} ++ ++int ++create_temp_file (const char *base, char **filename) ++{ ++ char *fname; ++ int fd; ++ ++ fname = (char *) xmalloc (strlen (test_dir) + 1 + strlen (base) ++ + sizeof ("XXXXXX")); ++ strcpy (stpcpy (stpcpy (stpcpy (fname, test_dir), "/"), base), "XXXXXX"); ++ ++ fd = mkstemp (fname); ++ if (fd == -1) ++ { ++ printf ("cannot open temporary file '%s': %m\n", fname); ++ free (fname); ++ return -1; ++ } ++ ++ add_temp_file (fname); ++ if (filename != NULL) ++ *filename = fname; ++ else ++ free (fname); ++ ++ return fd; ++} ++ ++char * ++support_create_temp_directory (const char *base) ++{ ++ char *path = xasprintf ("%s/%sXXXXXX", test_dir, base); ++ if (mkdtemp (path) == NULL) ++ { ++ printf ("error: mkdtemp (\"%s\"): %m", path); ++ exit (1); ++ } ++ add_temp_file (path); ++ return path; ++} ++ ++/* Helper functions called by the test skeleton follow. */ ++ ++void ++support_set_test_dir (const char *path) ++{ ++ test_dir = path; ++} ++ ++void ++support_delete_temp_files (void) ++{ ++ pid_t pid = getpid (); ++ while (temp_name_list != NULL) ++ { ++ /* Only perform the removal if the path was registed in the same ++ process, as identified by the PID. (This assumes that the ++ parent process which registered the temporary file sticks ++ around, to prevent PID reuse.) */ ++ if (temp_name_list->owner == pid) ++ { ++ if (remove (temp_name_list->name) != 0) ++ printf ("warning: could not remove temporary file: %s: %m\n", ++ temp_name_list->name); ++ } ++ free (temp_name_list->name); ++ ++ struct temp_name_list *next = temp_name_list->next; ++ free (temp_name_list); ++ temp_name_list = next; ++ } ++} ++ ++void ++support_print_temp_files (FILE *f) ++{ ++ if (temp_name_list != NULL) ++ { ++ struct temp_name_list *n; ++ fprintf (f, "temp_files=(\n"); ++ for (n = temp_name_list; n != NULL; n = n->next) ++ fprintf (f, " '%s'\n", n->name); ++ fprintf (f, ")\n"); ++ } ++} +diff --git a/support/temp_file.h b/support/temp_file.h +new file mode 100644 +index 0000000000..c7795cc577 +--- /dev/null ++++ b/support/temp_file.h +@@ -0,0 +1,42 @@ ++/* Declarations for temporary file handling. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_TEMP_FILE_H ++#define SUPPORT_TEMP_FILE_H ++ ++#include ++ ++__BEGIN_DECLS ++ ++/* Schedule a temporary file for deletion on exit. */ ++void add_temp_file (const char *name); ++ ++/* Create a temporary file. Return the opened file descriptor on ++ success, or -1 on failure. Write the file name to *FILENAME if ++ FILENAME is not NULL. In this case, the caller is expected to free ++ *FILENAME. */ ++int create_temp_file (const char *base, char **filename); ++ ++/* Create a temporary directory and schedule it for deletion. BASE is ++ used as a prefix for the unique directory name, which the function ++ returns. The caller should free this string. */ ++char *support_create_temp_directory (const char *base); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_TEMP_FILE_H */ +diff --git a/support/test-driver.c b/support/test-driver.c +new file mode 100644 +index 0000000000..09c8783e4f +--- /dev/null ++++ b/support/test-driver.c +@@ -0,0 +1,165 @@ ++/* Main function for test programs. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This file should be included from test cases. It will define a ++ main function which provides the test wrapper. ++ ++ It assumes that the test case defines a function ++ ++ int do_test (void); ++ ++ and arranges for that function being called under the test wrapper. ++ The do_test function should return 0 to indicate a passing test, 1 ++ to indicate a failing test, or 77 to indicate an unsupported test. ++ Other result values could be used to indicate a failing test, but ++ the result of the expression is passed to exit and exit only ++ returns the lower 8 bits of its input. A non-zero return with some ++ values could cause a test to incorrectly be considered passing when ++ it really failed. For this reason, the function should always ++ return 0 (EXIT_SUCCESS), 1 (EXIT_FAILURE), or 77 ++ (EXIT_UNSUPPORTED). ++ ++ The test function may print out diagnostic or warning messages as well ++ as messages about failures. These messages should be printed to stdout ++ and not stderr so that the output is properly ordered with respect to ++ the rest of the glibc testsuite run output. ++ ++ Several preprocessors macros can be defined before including this ++ file. ++ ++ The name of the do_test function can be changed with the ++ TEST_FUNCTION macro. It must expand to the desired function name. ++ ++ If the test case needs access to command line parameters, it must ++ define the TEST_FUNCTION_ARGV macro with the name of the test ++ function. It must have the following type: ++ ++ int TEST_FUNCTION_ARGV (int argc, char **argv); ++ ++ This overrides the do_test default function and is incompatible ++ with the TEST_FUNCTION macro. ++ ++ If PREPARE is defined, it must expand to the name of a function of ++ the type ++ ++ void PREPARE (int argc, char **); ++ ++ This function will be called early, after parsing the command line, ++ but before running the test, in the parent process which acts as ++ the test supervisor. ++ ++ If CLEANUP_HANDLER is defined, it must expand to the name of a ++ function of the type ++ ++ void CLEANUP_HANDLER (void); ++ ++ This function will be called from the timeout (SIGALRM) signal ++ handler. ++ ++ If EXPECTED_SIGNAL is defined, it must expanded to a constant which ++ denotes the expected signal number. ++ ++ If EXPECTED_STATUS is defined, it must expand to the expected exit ++ status. ++ ++ If TIMEOUT is defined, it must be positive constant. It overrides ++ the default test timeout and is measured in seconds. ++ ++ If TEST_NO_MALLOPT is defined, the test wrapper will not call ++ mallopt. ++ ++ Custom command line handling can be implemented by defining the ++ CMDLINE_OPTION macro (after including the header; this ++ requires _GNU_SOURCE to be defined). This macro must expand to a ++ to a comma-separated list of braced initializers for struct option ++ from , with a trailing comma. CMDLINE_PROCESS can be ++ defined as the name of a function which is called to process these ++ options. The function is passed the option character/number and ++ has this type: ++ ++ void CMDLINE_PROCESS (int); ++ ++ If the program also to process custom default short command line ++ argument (similar to getopt) it must define CMDLINE_OPTSTRING ++ with the expected options (for instance "vb"). ++*/ ++ ++#include ++ ++#include ++ ++int ++main (int argc, char **argv) ++{ ++ struct test_config test_config; ++ memset (&test_config, 0, sizeof (test_config)); ++ ++#ifdef PREPARE ++ test_config.prepare_function = (PREPARE); ++#endif ++ ++#if defined (TEST_FUNCTION) && defined (TEST_FUNCTON_ARGV) ++# error TEST_FUNCTION and TEST_FUNCTION_ARGV cannot be defined at the same time ++#endif ++#if defined (TEST_FUNCTION) ++ test_config.test_function = TEST_FUNCTION; ++#elif defined (TEST_FUNCTION_ARGV) ++ test_config.test_function_argv = TEST_FUNCTION_ARGV; ++#else ++ test_config.test_function = do_test; ++#endif ++ ++#ifdef CLEANUP_HANDLER ++ test_config.cleanup_function = CLEANUP_HANDLER; ++#endif ++ ++#ifdef EXPECTED_SIGNAL ++ test_config.expected_signal = (EXPECTED_SIGNAL); ++#endif ++ ++#ifdef EXPECTED_STATUS ++ test_config.expected_status = (EXPECTED_STATUS); ++#endif ++ ++#ifdef TEST_NO_MALLOPT ++ test_config.no_mallopt = 1; ++#endif ++ ++#ifdef TIMEOUT ++ test_config.timeout = TIMEOUT; ++#endif ++ ++#ifdef CMDLINE_OPTIONS ++ struct option options[] = ++ { ++ CMDLINE_OPTIONS ++ TEST_DEFAULT_OPTIONS ++ }; ++ test_config.options = &options; ++#endif ++#ifdef CMDLINE_PROCESS ++ test_config.cmdline_function = CMDLINE_PROCESS; ++#endif ++#ifdef CMDLINE_OPTSTRING ++ test_config.optstring = "+" CMDLINE_OPTSTRING; ++#else ++ test_config.optstring = "+"; ++#endif ++ ++ return support_test_main (argc, argv, &test_config); ++} +diff --git a/support/test-driver.h b/support/test-driver.h +new file mode 100644 +index 0000000000..1708d68d60 +--- /dev/null ++++ b/support/test-driver.h +@@ -0,0 +1,75 @@ ++/* Interfaces for the test driver. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_TEST_DRIVER_H ++#define SUPPORT_TEST_DRIVER_H ++ ++#include ++ ++__BEGIN_DECLS ++ ++struct test_config ++{ ++ void (*prepare_function) (int argc, char **argv); ++ int (*test_function) (void); ++ int (*test_function_argv) (int argc, char **argv); ++ void (*cleanup_function) (void); ++ void (*cmdline_function) (int); ++ const void *options; /* Custom options if not NULL. */ ++ int timeout; /* Test timeout in seconds. */ ++ int expected_status; /* Expected exit status. */ ++ int expected_signal; /* If non-zero, expect termination by signal. */ ++ char no_mallopt; /* Boolean flag to disable mallopt. */ ++ const char *optstring; /* Short command line options. */ ++}; ++ ++enum ++ { ++ /* Test exit status which indicates that the feature is ++ unsupported. */ ++ EXIT_UNSUPPORTED = 77, ++ ++ /* Default timeout is twenty seconds. Tests should normally ++ complete faster than this, but if they don't, that's abnormal ++ (a bug) anyways. */ ++ DEFAULT_TIMEOUT = 20, ++ ++ /* Used for command line argument parsing. */ ++ OPT_DIRECT = 1000, ++ OPT_TESTDIR, ++ }; ++ ++/* Options provided by the test driver. */ ++#define TEST_DEFAULT_OPTIONS \ ++ { "verbose", no_argument, NULL, 'v' }, \ ++ { "direct", no_argument, NULL, OPT_DIRECT }, \ ++ { "test-dir", required_argument, NULL, OPT_TESTDIR }, \ ++ ++/* The directory the test should use for temporary files. */ ++extern const char *test_dir; ++ ++/* The number of --verbose arguments specified during program ++ invocation. This variable can be used to control the verbosity of ++ tests. */ ++extern unsigned int test_verbose; ++ ++int support_test_main (int argc, char **argv, const struct test_config *); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_TEST_DRIVER_H */ +diff --git a/support/tst-support-namespace.c b/support/tst-support-namespace.c +new file mode 100644 +index 0000000000..e20423c4a3 +--- /dev/null ++++ b/support/tst-support-namespace.c +@@ -0,0 +1,114 @@ ++/* Test entering namespaces. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Check that the loopback interface provides multiple addresses which ++ can be used to run independent servers. */ ++static void ++test_localhost_bind (void) ++{ ++ printf ("info: testing loopback interface with multiple addresses\n"); ++ ++ /* Create the two server addresses. */ ++ static const struct addrinfo hints = ++ { ++ .ai_family = AF_INET, ++ .ai_socktype = SOCK_DGRAM, ++ .ai_protocol = IPPROTO_UDP, ++ }; ++ struct addrinfo *ai[3]; ++ TEST_VERIFY_EXIT (getaddrinfo ("127.0.0.1", "53", &hints, ai + 0) == 0); ++ TEST_VERIFY_EXIT (getaddrinfo ("127.0.0.2", "53", &hints, ai + 1) == 0); ++ TEST_VERIFY_EXIT (getaddrinfo ("127.0.0.3", "53", &hints, ai + 2) == 0); ++ ++ /* Create the server scokets and bind them to these addresses. */ ++ int sockets[3]; ++ for (int i = 0; i < 3; ++i) ++ { ++ sockets[i] = xsocket ++ (ai[i]->ai_family, ai[i]->ai_socktype, ai[i]->ai_protocol); ++ xbind (sockets[i], ai[i]->ai_addr, ai[i]->ai_addrlen); ++ } ++ ++ /* Send two packets to each server. */ ++ int client = xsocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ for (int i = 0; i < 3; ++i) ++ { ++ TEST_VERIFY (sendto (client, &i, sizeof (i), 0, ++ ai[i]->ai_addr, ai[i]->ai_addrlen) == sizeof (i)); ++ int j = i + 256; ++ TEST_VERIFY (sendto (client, &j, sizeof (j), 0, ++ ai[i]->ai_addr, ai[i]->ai_addrlen) == sizeof (j)); ++ } ++ ++ /* Check that the packets can be received with the expected ++ contents. Note that the receive calls interleave differently, ++ which hopefully proves that the sockets are, indeed, ++ independent. */ ++ for (int i = 0; i < 3; ++i) ++ { ++ int buf; ++ TEST_VERIFY (recv (sockets[i], &buf, sizeof (buf), 0) == sizeof (buf)); ++ TEST_VERIFY (buf == i); ++ } ++ for (int i = 0; i < 3; ++i) ++ { ++ int buf; ++ TEST_VERIFY (recv (sockets[i], &buf, sizeof (buf), 0) == sizeof (buf)); ++ TEST_VERIFY (buf == i + 256); ++ /* Check that there is no more data to receive. */ ++ TEST_VERIFY (recv (sockets[i], &buf, sizeof (buf), MSG_DONTWAIT) == -1); ++ TEST_VERIFY (errno == EWOULDBLOCK || errno == EAGAIN); ++ } ++ ++ /* Close all sockets and free the addresses. */ ++ for (int i = 0; i < 3; ++i) ++ { ++ freeaddrinfo (ai[i]); ++ xclose (sockets[i]); ++ } ++ xclose (client); ++} ++ ++ ++static int ++do_test (void) ++{ ++ bool root = support_become_root (); ++ if (root) ++ printf ("info: acquired root-like privileges\n"); ++ bool netns = support_enter_network_namespace (); ++ if (netns) ++ printf ("info: entered network namespace\n"); ++ if (support_in_uts_namespace ()) ++ printf ("info: also entered UTS namespace\n"); ++ ++ if (root && netns) ++ test_localhost_bind (); ++ ++ return 0; ++} ++ ++#include +diff --git a/support/tst-support_capture_subprocess.c b/support/tst-support_capture_subprocess.c +new file mode 100644 +index 0000000000..a685256091 +--- /dev/null ++++ b/support/tst-support_capture_subprocess.c +@@ -0,0 +1,188 @@ ++/* Test capturing output from a subprocess. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Write one byte at *P to FD and advance *P. Do nothing if *P is ++ '\0'. */ ++static void ++transfer (const unsigned char **p, int fd) ++{ ++ if (**p != '\0') ++ { ++ TEST_VERIFY (write (fd, *p, 1) == 1); ++ ++*p; ++ } ++} ++ ++/* Determine the order in which stdout and stderr are written. */ ++enum write_mode { out_first, err_first, interleave, ++ write_mode_last = interleave }; ++ ++/* Describe what to write in the subprocess. */ ++struct test ++{ ++ char *out; ++ char *err; ++ enum write_mode write_mode; ++ int signal; ++ int status; ++}; ++ ++/* For use with support_capture_subprocess. */ ++static void ++callback (void *closure) ++{ ++ const struct test *test = closure; ++ bool mode_ok = false; ++ switch (test->write_mode) ++ { ++ case out_first: ++ TEST_VERIFY (fputs (test->out, stdout) >= 0); ++ TEST_VERIFY (fflush (stdout) == 0); ++ TEST_VERIFY (fputs (test->err, stderr) >= 0); ++ TEST_VERIFY (fflush (stderr) == 0); ++ mode_ok = true; ++ break; ++ case err_first: ++ TEST_VERIFY (fputs (test->err, stderr) >= 0); ++ TEST_VERIFY (fflush (stderr) == 0); ++ TEST_VERIFY (fputs (test->out, stdout) >= 0); ++ TEST_VERIFY (fflush (stdout) == 0); ++ mode_ok = true; ++ break; ++ case interleave: ++ { ++ const unsigned char *pout = (const unsigned char *) test->out; ++ const unsigned char *perr = (const unsigned char *) test->err; ++ do ++ { ++ transfer (&pout, STDOUT_FILENO); ++ transfer (&perr, STDERR_FILENO); ++ } ++ while (*pout != '\0' || *perr != '\0'); ++ } ++ mode_ok = true; ++ break; ++ } ++ TEST_VERIFY (mode_ok); ++ ++ if (test->signal != 0) ++ raise (test->signal); ++ exit (test->status); ++} ++ ++/* Create a heap-allocated random string of letters. */ ++static char * ++random_string (size_t length) ++{ ++ char *result = xmalloc (length + 1); ++ for (size_t i = 0; i < length; ++i) ++ result[i] = 'a' + (rand () % 26); ++ result[length] = '\0'; ++ return result; ++} ++ ++/* Check that the specific stream from the captured subprocess matches ++ expectations. */ ++static void ++check_stream (const char *what, const struct xmemstream *stream, ++ const char *expected) ++{ ++ if (strcmp (stream->buffer, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: captured %s data incorrect\n" ++ " expected: %s\n" ++ " actual: %s\n", ++ what, expected, stream->buffer); ++ } ++ if (stream->length != strlen (expected)) ++ { ++ support_record_failure (); ++ printf ("error: captured %s data length incorrect\n" ++ " expected: %zu\n" ++ " actual: %zu\n", ++ what, strlen (expected), stream->length); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ const int lengths[] = {0, 1, 17, 512, 20000, -1}; ++ ++ /* Test multiple combinations of support_capture_subprocess. ++ ++ length_idx_stdout: Index into the lengths array above, ++ controls how many bytes are written by the subprocess to ++ standard output. ++ length_idx_stderr: Same for standard error. ++ write_mode: How standard output and standard error writes are ++ ordered. ++ signal: Exit with no signal if zero, with SIGTERM if one. ++ status: Process exit status: 0 if zero, 3 if one. */ ++ for (int length_idx_stdout = 0; lengths[length_idx_stdout] >= 0; ++ ++length_idx_stdout) ++ for (int length_idx_stderr = 0; lengths[length_idx_stderr] >= 0; ++ ++length_idx_stderr) ++ for (int write_mode = 0; write_mode < write_mode_last; ++write_mode) ++ for (int signal = 0; signal < 2; ++signal) ++ for (int status = 0; status < 2; ++status) ++ { ++ struct test test = ++ { ++ .out = random_string (lengths[length_idx_stdout]), ++ .err = random_string (lengths[length_idx_stderr]), ++ .write_mode = write_mode, ++ .signal = signal * SIGTERM, /* 0 or SIGTERM. */ ++ .status = status * 3, /* 0 or 3. */ ++ }; ++ TEST_VERIFY (strlen (test.out) == lengths[length_idx_stdout]); ++ TEST_VERIFY (strlen (test.err) == lengths[length_idx_stderr]); ++ ++ struct support_capture_subprocess result ++ = support_capture_subprocess (callback, &test); ++ check_stream ("stdout", &result.out, test.out); ++ check_stream ("stderr", &result.err, test.err); ++ if (test.signal != 0) ++ { ++ TEST_VERIFY (WIFSIGNALED (result.status)); ++ TEST_VERIFY (WTERMSIG (result.status) == test.signal); ++ } ++ else ++ { ++ TEST_VERIFY (WIFEXITED (result.status)); ++ TEST_VERIFY (WEXITSTATUS (result.status) == test.status); ++ } ++ support_capture_subprocess_free (&result); ++ free (test.out); ++ free (test.err); ++ } ++ return 0; ++} ++ ++#include +diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c +new file mode 100644 +index 0000000000..b1135eebc6 +--- /dev/null ++++ b/support/tst-support_format_dns_packet.c +@@ -0,0 +1,101 @@ ++/* Tests for the support_format_dns_packet function. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++static void ++check_packet (const void *buffer, size_t length, ++ const char *name, const char *expected) ++{ ++ char *actual = support_format_dns_packet (buffer, length); ++ if (strcmp (actual, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: formatted packet does not match: %s\n", name); ++ support_run_diff ("expected", expected, ++ "actual", actual); ++ } ++ free (actual); ++} ++ ++static void ++test_aaaa_length (void) ++{ ++ static const char packet[] = ++ /* Header: Response with two records. */ ++ "\x12\x34\x80\x00\x00\x01\x00\x02\x00\x00\x00\x00" ++ /* Question section. www.example/IN/AAAA. */ ++ "\x03www\x07""example\x00\x00\x1c\x00\x01" ++ /* Answer section. www.example AAAA [corrupted]. */ ++ "\xc0\x0c" ++ "\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x10" ++ "\x20\x01\x0d\xb8\x05\x06\x07\x08" ++ "\x11\x12\x13\x14\x15\x16\x17\x18" ++ /* www.example AAAA [corrupted]. */ ++ "\xc0\x0c" ++ "\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x11" ++ "\x01\x02\x03\x04\x05\x06\x07\x08" ++ "\x11\x12\x13\x14\x15\x16\x17\x18" "\xff"; ++ check_packet (packet, sizeof (packet) - 1, __func__, ++ "name: www.example\n" ++ "address: 2001:db8:506:708:1112:1314:1516:1718\n" ++ "error: AAAA record of size 17: www.example\n"); ++} ++ ++static void ++test_multiple_cnames (void) ++{ ++ static const char packet[] = ++ /* Header: Response with three records. */ ++ "\x12\x34\x80\x00\x00\x01\x00\x03\x00\x00\x00\x00" ++ /* Question section. www.example/IN/A. */ ++ "\x03www\x07""example\x00\x00\x01\x00\x01" ++ /* Answer section. www.example CNAME www1.example. */ ++ "\xc0\x0c" ++ "\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07" ++ "\x04www1\xc0\x10" ++ /* www1 CNAME www2. */ ++ "\x04www1\xc0\x10" ++ "\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07" ++ "\x04www2\xc0\x10" ++ /* www2 A 192.0.2.1. */ ++ "\x04www2\xc0\x10" ++ "\x00\x01\x00\x01\x00\x00\x00\x00\x00\x04" ++ "\xc0\x00\x02\x01"; ++ check_packet (packet, sizeof (packet) - 1, __func__, ++ "name: www.example\n" ++ "name: www1.example\n" ++ "name: www2.example\n" ++ "address: 192.0.2.1\n"); ++} ++ ++static int ++do_test (void) ++{ ++ test_aaaa_length (); ++ test_multiple_cnames (); ++ return 0; ++} ++ ++#include +diff --git a/support/tst-support_record_failure-2.sh b/support/tst-support_record_failure-2.sh +new file mode 100644 +index 0000000000..09cd96290a +--- /dev/null ++++ b/support/tst-support_record_failure-2.sh +@@ -0,0 +1,69 @@ ++#!/bin/sh ++# Test failure recording (with and without --direct). ++# Copyright (C) 2016-2018 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++ ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . */ ++ ++set -e ++ ++common_objpfx=$1; shift ++test_program_prefix_before_env=$1; shift ++run_program_env=$1; shift ++test_program_prefix_after_env=$1; shift ++ ++run_test () { ++ expected_status="$1" ++ expected_output="$2" ++ shift 2 ++ args="${common_objpfx}support/tst-support_record_failure $*" ++ echo "running: $args" ++ set +e ++ output="$(${test_program_prefix_before_env} \ ++ ${run_program} ${test_program_prefix_after_env} $args)" ++ status=$? ++ set -e ++ echo " exit status: $status" ++ if test "$output" != "$expected_output" ; then ++ echo "error: unexpected output: $output" ++ exit 1 ++ fi ++ if test "$status" -ne "$expected_status" ; then ++ echo "error: exit status $expected_status expected" ++ exit 1 ++ fi ++} ++ ++different_status () { ++ direct="$1" ++ run_test 1 "error: 1 test failures" $direct --status=0 ++ run_test 1 "error: 1 test failures" $direct --status=1 ++ run_test 2 "error: 1 test failures" $direct --status=2 ++ run_test 1 "error: 1 test failures" $direct --status=77 ++ run_test 2 "error: tst-support_record_failure.c:109: not true: false ++error: 1 test failures" $direct --test-verify ++ run_test 2 "error: tst-support_record_failure.c:109: not true: false ++info: execution passed failed TEST_VERIFY ++error: 1 test failures" $direct --test-verify --verbose ++} ++ ++different_status ++different_status --direct ++ ++run_test 1 "error: tst-support_record_failure.c:116: not true: false ++error: 1 test failures" --test-verify-exit ++# --direct does not print the summary error message if exit is called. ++run_test 1 "error: tst-support_record_failure.c:116: not true: false" \ ++ --direct --test-verify-exit +diff --git a/support/tst-support_record_failure.c b/support/tst-support_record_failure.c +new file mode 100644 +index 0000000000..8757f2da02 +--- /dev/null ++++ b/support/tst-support_record_failure.c +@@ -0,0 +1,153 @@ ++/* Test support_record_failure state sharing. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int exit_status_with_failure = -1; ++static bool test_verify; ++static bool test_verify_exit; ++enum ++ { ++ OPT_STATUS = 10001, ++ OPT_TEST_VERIFY, ++ OPT_TEST_VERIFY_EXIT, ++ }; ++#define CMDLINE_OPTIONS \ ++ { "status", required_argument, NULL, OPT_STATUS }, \ ++ { "test-verify", no_argument, NULL, OPT_TEST_VERIFY }, \ ++ { "test-verify-exit", no_argument, NULL, OPT_TEST_VERIFY_EXIT }, ++static void ++cmdline_process (int c) ++{ ++ switch (c) ++ { ++ case OPT_STATUS: ++ exit_status_with_failure = atoi (optarg); ++ break; ++ case OPT_TEST_VERIFY: ++ test_verify = true; ++ break; ++ case OPT_TEST_VERIFY_EXIT: ++ test_verify_exit = true; ++ break; ++ } ++} ++#define CMDLINE_PROCESS cmdline_process ++ ++static void ++check_failure_reporting (int phase, int zero, int unsupported) ++{ ++ int status = support_report_failure (0); ++ if (status != zero) ++ { ++ printf ("real-error (phase %d): support_report_failure (0) == %d\n", ++ phase, status); ++ exit (1); ++ } ++ status = support_report_failure (1); ++ if (status != 1) ++ { ++ printf ("real-error (phase %d): support_report_failure (1) == %d\n", ++ phase, status); ++ exit (1); ++ } ++ status = support_report_failure (2); ++ if (status != 2) ++ { ++ printf ("real-error (phase %d): support_report_failure (2) == %d\n", ++ phase, status); ++ exit (1); ++ } ++ status = support_report_failure (EXIT_UNSUPPORTED); ++ if (status != unsupported) ++ { ++ printf ("real-error (phase %d): " ++ "support_report_failure (EXIT_UNSUPPORTED) == %d\n", ++ phase, status); ++ exit (1); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ if (exit_status_with_failure >= 0) ++ { ++ /* External invocation with requested error status. Used by ++ tst-support_report_failure-2.sh. */ ++ support_record_failure (); ++ return exit_status_with_failure; ++ } ++ TEST_VERIFY (true); ++ TEST_VERIFY_EXIT (true); ++ if (test_verify) ++ { ++ TEST_VERIFY (false); ++ if (test_verbose) ++ printf ("info: execution passed failed TEST_VERIFY\n"); ++ return 2; /* Expected exit status. */ ++ } ++ if (test_verify_exit) ++ { ++ TEST_VERIFY_EXIT (false); ++ return 3; /* Not reached. Expected exit status is 1. */ ++ } ++ ++ printf ("info: This test tests the test framework.\n" ++ "info: It reports some expected errors on stdout.\n"); ++ ++ /* Check that the status is passed through unchanged. */ ++ check_failure_reporting (1, 0, EXIT_UNSUPPORTED); ++ ++ /* Check state propagation from a subprocess. */ ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ support_record_failure (); ++ _exit (0); ++ } ++ int status; ++ xwaitpid (pid, &status, 0); ++ if (status != 0) ++ { ++ printf ("real-error: incorrect status from subprocess: %d\n", status); ++ return 1; ++ } ++ check_failure_reporting (2, 1, 1); ++ ++ /* Also test directly in the parent process. */ ++ support_record_failure_reset (); ++ check_failure_reporting (3, 0, EXIT_UNSUPPORTED); ++ support_record_failure (); ++ check_failure_reporting (4, 1, 1); ++ ++ /* We need to mask the failure above. */ ++ support_record_failure_reset (); ++ return 0; ++} ++ ++#include +diff --git a/support/tst-test_compare.c b/support/tst-test_compare.c +new file mode 100644 +index 0000000000..123ba1bc3c +--- /dev/null ++++ b/support/tst-test_compare.c +@@ -0,0 +1,116 @@ ++/* Basic test for the TEST_COMPARE macro. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static void ++subprocess (void *closure) ++{ ++ char ch = 1; ++ /* These tests should fail. */ ++ TEST_COMPARE (ch, -1); /* Line 28. */ ++ TEST_COMPARE (2LL, -2LL); /* Line 29. */ ++ TEST_COMPARE (3LL, (short) -3); /* Line 30. */ ++} ++ ++struct bitfield ++{ ++ int i2 : 2; ++ int i3 : 3; ++ unsigned int u2 : 2; ++ unsigned int u3 : 3; ++ int i31 : 31; ++ unsigned int u31 : 31 ; ++ long long int i63 : 63; ++ unsigned long long int u63 : 63; ++}; ++ ++/* Functions which return signed sizes are common, so test that these ++ results can readily checked using TEST_COMPARE. */ ++ ++static int ++return_ssize_t (void) ++{ ++ return 4; ++} ++ ++static int ++return_int (void) ++{ ++ return 4; ++} ++ ++ ++static int ++do_test (void) ++{ ++ /* This should succeed. */ ++ TEST_COMPARE (1, 1); ++ TEST_COMPARE (2LL, 2U); ++ { ++ char i8 = 3; ++ unsigned short u16 = 3; ++ TEST_COMPARE (i8, u16); ++ } ++ TEST_COMPARE (return_ssize_t (), sizeof (char[4])); ++ TEST_COMPARE (return_int (), sizeof (char[4])); ++ ++ struct bitfield bitfield = { 0 }; ++ TEST_COMPARE (bitfield.i2, bitfield.i3); ++ TEST_COMPARE (bitfield.u2, bitfield.u3); ++ TEST_COMPARE (bitfield.u2, bitfield.i3); ++ TEST_COMPARE (bitfield.u3, bitfield.i3); ++ TEST_COMPARE (bitfield.i2, bitfield.u3); ++ TEST_COMPARE (bitfield.i3, bitfield.u2); ++ TEST_COMPARE (bitfield.i63, bitfield.i63); ++ TEST_COMPARE (bitfield.u63, bitfield.u63); ++ TEST_COMPARE (bitfield.i31, bitfield.i63); ++ TEST_COMPARE (bitfield.i63, bitfield.i31); ++ ++ struct support_capture_subprocess proc = support_capture_subprocess ++ (&subprocess, NULL); ++ ++ /* Discard the reported error. */ ++ support_record_failure_reset (); ++ ++ puts ("info: *** subprocess output starts ***"); ++ fputs (proc.out.buffer, stdout); ++ puts ("info: *** subprocess output ends ***"); ++ ++ TEST_VERIFY ++ (strcmp (proc.out.buffer, ++ "tst-test_compare.c:28: numeric comparison failure\n" ++ " left: 1 (0x1); from: ch\n" ++ " right: -1 (0xffffffff); from: -1\n" ++ "tst-test_compare.c:29: numeric comparison failure\n" ++ " left: 2 (0x2); from: 2LL\n" ++ " right: -2 (0xfffffffffffffffe); from: -2LL\n" ++ "tst-test_compare.c:30: numeric comparison failure" ++ " (widths 64 and 32)\n" ++ " left: 3 (0x3); from: 3LL\n" ++ " right: -3 (0xfffffffd); from: (short) -3\n") == 0); ++ ++ /* Check that there is no output on standard error. */ ++ support_capture_subprocess_check (&proc, "TEST_COMPARE", 0, sc_allow_stdout); ++ ++ return 0; ++} ++ ++#include +diff --git a/support/tst-xreadlink.c b/support/tst-xreadlink.c +new file mode 100644 +index 0000000000..b142207228 +--- /dev/null ++++ b/support/tst-xreadlink.c +@@ -0,0 +1,72 @@ ++/* Test the xreadlink function. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ char *dir = support_create_temp_directory ("tst-xreadlink-"); ++ char *symlink_name = xasprintf ("%s/symlink", dir); ++ add_temp_file (symlink_name); ++ ++ /* The limit 10000 is arbitrary and simply there to prevent an ++ attempt to exhaust all available disk space. */ ++ for (int size = 1; size < 10000; ++size) ++ { ++ char *contents = xmalloc (size + 1); ++ for (int i = 0; i < size; ++i) ++ contents[i] = 'a' + (rand () % 26); ++ contents[size] = '\0'; ++ if (symlink (contents, symlink_name) != 0) ++ { ++ if (errno == ENAMETOOLONG) ++ { ++ printf ("info: ENAMETOOLONG failure at %d bytes\n", size); ++ free (contents); ++ break; ++ } ++ FAIL_EXIT1 ("symlink (%d bytes): %m", size); ++ } ++ ++ char *readlink_result = xreadlink (symlink_name); ++ TEST_VERIFY (strcmp (readlink_result, contents) == 0); ++ free (readlink_result); ++ xunlink (symlink_name); ++ free (contents); ++ } ++ ++ /* Create an empty file to suppress the temporary file deletion ++ warning. */ ++ xclose (xopen (symlink_name, O_WRONLY | O_CREAT, 0)); ++ ++ free (symlink_name); ++ free (dir); ++ ++ return 0; ++} ++ ++#include +diff --git a/support/write_message.c b/support/write_message.c +new file mode 100644 +index 0000000000..9d0f267a2f +--- /dev/null ++++ b/support/write_message.c +@@ -0,0 +1,29 @@ ++/* Write a message to standard output. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++void ++write_message (const char *message) ++{ ++ ssize_t unused __attribute__ ((unused)); ++ unused = write (STDOUT_FILENO, message, strlen (message)); ++} +diff --git a/support/xaccept.c b/support/xaccept.c +new file mode 100644 +index 0000000000..fd65fc6c3a +--- /dev/null ++++ b/support/xaccept.c +@@ -0,0 +1,32 @@ ++/* accept with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++int ++xaccept (int fd, struct sockaddr *sa, socklen_t *salen) ++{ ++ int clientfd = accept (fd, sa, salen); ++ if (clientfd < 0) ++ FAIL_EXIT1 ("accept (%d): %m", fd); ++ return clientfd; ++} +diff --git a/support/xaccept4.c b/support/xaccept4.c +new file mode 100644 +index 0000000000..ada3c92267 +--- /dev/null ++++ b/support/xaccept4.c +@@ -0,0 +1,32 @@ ++/* accept4 with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++int ++xaccept4 (int fd, struct sockaddr *sa, socklen_t *salen, int flags) ++{ ++ int clientfd = accept4 (fd, sa, salen, flags); ++ if (clientfd < 0) ++ FAIL_EXIT1 ("accept4 (%d, 0x%x): %m", fd, flags); ++ return clientfd; ++} +diff --git a/support/xasprintf.c b/support/xasprintf.c +new file mode 100644 +index 0000000000..e593ec5e82 +--- /dev/null ++++ b/support/xasprintf.c +@@ -0,0 +1,36 @@ ++/* Error-checking wrapper for asprintf. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++char * ++xasprintf (const char *format, ...) ++{ ++ va_list ap; ++ va_start (ap, format); ++ char *result; ++ if (vasprintf (&result, format, ap) < 0) ++ FAIL_EXIT1 ("asprintf: %m"); ++ va_end (ap); ++ return result; ++} +diff --git a/support/xbind.c b/support/xbind.c +new file mode 100644 +index 0000000000..938e7c07d6 +--- /dev/null ++++ b/support/xbind.c +@@ -0,0 +1,30 @@ ++/* bind with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void ++xbind (int fd, const struct sockaddr *sa, socklen_t sa_len) ++{ ++ if (bind (fd, sa, sa_len) != 0) ++ FAIL_EXIT1 ("bind (%d), family %d: %m", fd, sa->sa_family); ++} +diff --git a/support/xcalloc.c b/support/xcalloc.c +new file mode 100644 +index 0000000000..403569041f +--- /dev/null ++++ b/support/xcalloc.c +@@ -0,0 +1,34 @@ ++/* Error-checking wrapper for calloc. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void * ++xcalloc (size_t n, size_t s) ++{ ++ void *p; ++ ++ p = calloc (n, s); ++ if (p == NULL) ++ oom_error ("calloc", n * s); ++ return p; ++} +diff --git a/support/xchroot.c b/support/xchroot.c +new file mode 100644 +index 0000000000..d4759a1bd1 +--- /dev/null ++++ b/support/xchroot.c +@@ -0,0 +1,28 @@ ++/* chroot with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++xchroot (const char *path) ++{ ++ if (chroot (path) != 0) ++ FAIL_EXIT1 ("chroot (\"%s\"): %m", path); ++} +diff --git a/support/xclose.c b/support/xclose.c +new file mode 100644 +index 0000000000..702bef6c6e +--- /dev/null ++++ b/support/xclose.c +@@ -0,0 +1,28 @@ ++/* close with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++xclose (int fd) ++{ ++ if (close (fd) < 0 && errno != EINTR) ++ FAIL_EXIT1 ("close of descriptor %d failed: %m", fd); ++} +diff --git a/support/xconnect.c b/support/xconnect.c +new file mode 100644 +index 0000000000..341805d80d +--- /dev/null ++++ b/support/xconnect.c +@@ -0,0 +1,30 @@ ++/* connect with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void ++xconnect (int fd, const struct sockaddr *sa, socklen_t sa_len) ++{ ++ if (connect (fd, sa, sa_len) != 0) ++ FAIL_EXIT1 ("connect (%d), family %d: %m", fd, sa->sa_family); ++} +diff --git a/support/xdlfcn.c b/support/xdlfcn.c +new file mode 100644 +index 0000000000..f34bb059c0 +--- /dev/null ++++ b/support/xdlfcn.c +@@ -0,0 +1,59 @@ ++/* Support functionality for using dlopen/dlclose/dlsym. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void * ++xdlopen (const char *filename, int flags) ++{ ++ void *dso = dlopen (filename, flags); ++ ++ if (dso == NULL) ++ FAIL_EXIT1 ("error: dlopen: %s\n", dlerror ()); ++ ++ /* Clear any errors. */ ++ dlerror (); ++ ++ return dso; ++} ++ ++void * ++xdlsym (void *handle, const char *symbol) ++{ ++ void *sym = dlsym (handle, symbol); ++ ++ if (sym == NULL) ++ FAIL_EXIT1 ("error: dlsym: %s\n", dlerror ()); ++ ++ /* Clear any errors. */ ++ dlerror (); ++ ++ return sym; ++} ++ ++void ++xdlclose (void *handle) ++{ ++ if (dlclose (handle) != 0) ++ FAIL_EXIT1 ("error: dlclose: %s\n", dlerror ()); ++ ++ /* Clear any errors. */ ++ dlerror (); ++} +diff --git a/support/xdlfcn.h b/support/xdlfcn.h +new file mode 100644 +index 0000000000..5ab7494e70 +--- /dev/null ++++ b/support/xdlfcn.h +@@ -0,0 +1,34 @@ ++/* Support functionality for using dlopen/dlclose/dlsym. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_DLOPEN_H ++#define SUPPORT_DLOPEN_H ++ ++#include ++ ++__BEGIN_DECLS ++ ++/* Each of these terminates process on failure with relevant error message. */ ++void *xdlopen (const char *filename, int flags); ++void *xdlsym (void *handle, const char *symbol); ++void xdlclose (void *handle); ++ ++ ++__END_DECLS ++ ++#endif /* SUPPORT_DLOPEN_H */ +diff --git a/support/xdup2.c b/support/xdup2.c +new file mode 100644 +index 0000000000..b8c4c223fb +--- /dev/null ++++ b/support/xdup2.c +@@ -0,0 +1,28 @@ ++/* dup2 with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++void ++xdup2 (int from, int to) ++{ ++ if (dup2 (from, to) < 0) ++ FAIL_EXIT1 ("dup2 (%d, %d): %m", from, to); ++} +diff --git a/support/xfclose.c b/support/xfclose.c +new file mode 100644 +index 0000000000..39d46f042a +--- /dev/null ++++ b/support/xfclose.c +@@ -0,0 +1,33 @@ ++/* fclose with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++void ++xfclose (FILE *fp) ++{ ++ if (ferror (fp)) ++ FAIL_EXIT1 ("stdio stream closed with pending errors"); ++ if (fflush (fp) != 0) ++ FAIL_EXIT1 ("fflush: %m"); ++ if (fclose (fp) != 0) ++ FAIL_EXIT1 ("fclose: %m"); ++} +diff --git a/support/xfopen.c b/support/xfopen.c +new file mode 100644 +index 0000000000..fb931cf22b +--- /dev/null ++++ b/support/xfopen.c +@@ -0,0 +1,31 @@ ++/* fopen with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++ ++FILE * ++xfopen (const char *path, const char *mode) ++{ ++ FILE *fp = fopen (path, mode); ++ if (fp == NULL) ++ FAIL_EXIT1 ("could not open %s (mode \"%s\"): %m", path, mode); ++ return fp; ++} +diff --git a/support/xfork.c b/support/xfork.c +new file mode 100644 +index 0000000000..dffa2a13d0 +--- /dev/null ++++ b/support/xfork.c +@@ -0,0 +1,32 @@ ++/* fork with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++pid_t ++xfork (void) ++{ ++ pid_t result = fork (); ++ if (result < 0) ++ FAIL_EXIT1 ("fork: %m"); ++ return result; ++} +diff --git a/support/xftruncate.c b/support/xftruncate.c +new file mode 100644 +index 0000000000..27c7e12ba2 +--- /dev/null ++++ b/support/xftruncate.c +@@ -0,0 +1,27 @@ ++/* ftruncate with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++xftruncate (int fd, long long length) ++{ ++ if (ftruncate64 (fd, length) != 0) ++ FAIL_EXIT1 ("ftruncate64 (%d, %lld): %m", fd, length); ++} +diff --git a/support/xgetsockname.c b/support/xgetsockname.c +new file mode 100644 +index 0000000000..797194f79d +--- /dev/null ++++ b/support/xgetsockname.c +@@ -0,0 +1,30 @@ ++/* getsockname with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void ++xgetsockname (int fd, struct sockaddr *sa, socklen_t *plen) ++{ ++ if (getsockname (fd, sa, plen) != 0) ++ FAIL_EXIT1 ("setsockopt (%d): %m", fd); ++} +diff --git a/support/xlisten.c b/support/xlisten.c +new file mode 100644 +index 0000000000..aa70091adb +--- /dev/null ++++ b/support/xlisten.c +@@ -0,0 +1,30 @@ ++/* listen with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void ++xlisten (int fd, int backlog) ++{ ++ if (listen (fd, backlog) != 0) ++ FAIL_EXIT1 ("listen (%d, %d): %m", fd, backlog); ++} +diff --git a/support/xlseek.c b/support/xlseek.c +new file mode 100644 +index 0000000000..2422939908 +--- /dev/null ++++ b/support/xlseek.c +@@ -0,0 +1,29 @@ ++/* lseek with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++long long ++xlseek (int fd, long long offset, int whence) ++{ ++ long long result = lseek64 (fd, offset, whence); ++ if (result < 0) ++ FAIL_EXIT1 ("lseek64 (%d, %lld, %d): %m", fd, offset, whence); ++ return result; ++} +diff --git a/support/xmalloc.c b/support/xmalloc.c +new file mode 100644 +index 0000000000..78317e2b12 +--- /dev/null ++++ b/support/xmalloc.c +@@ -0,0 +1,34 @@ ++/* Error-checking wrapper for malloc. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void * ++xmalloc (size_t n) ++{ ++ void *p; ++ ++ p = malloc (n); ++ if (p == NULL) ++ oom_error ("malloc", n); ++ return p; ++} +diff --git a/support/xmemstream.c b/support/xmemstream.c +new file mode 100644 +index 0000000000..df5fbc489a +--- /dev/null ++++ b/support/xmemstream.c +@@ -0,0 +1,42 @@ ++/* Error-checking wrappers for memstream functions. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++void ++xopen_memstream (struct xmemstream *stream) ++{ ++ int old_errno = errno; ++ *stream = (struct xmemstream) {}; ++ stream->out = open_memstream (&stream->buffer, &stream->length); ++ if (stream->out == NULL) ++ FAIL_EXIT1 ("open_memstream: %m"); ++ errno = old_errno; ++} ++ ++void ++xfclose_memstream (struct xmemstream *stream) ++{ ++ xfclose (stream->out); ++ stream->out = NULL; ++} +diff --git a/support/xmemstream.h b/support/xmemstream.h +new file mode 100644 +index 0000000000..2d4a577f29 +--- /dev/null ++++ b/support/xmemstream.h +@@ -0,0 +1,49 @@ ++/* Error-checking wrappers for memstream functions. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_XMEMSTREAM_H ++#define SUPPORT_XMEMSTREAM_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Wrappers for other libc functions. */ ++struct xmemstream ++{ ++ FILE *out; ++ char *buffer; ++ size_t length; ++}; ++ ++/* Create a new in-memory stream. Initializes *STREAM. After this ++ function returns, STREAM->out is a file descriptor open for ++ writing. errno is preserved, so that the %m format specifier can ++ be used for writing to STREAM->out. */ ++void xopen_memstream (struct xmemstream *stream); ++ ++/* Closes STREAM->OUT. After this function returns, STREAM->buffer ++ and STREAM->length denote a memory range which contains the bytes ++ written to the output stream. The caller should free ++ STREAM->buffer. */ ++void xfclose_memstream (struct xmemstream *stream); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_XMEMSTREAM_H */ +diff --git a/support/xmkdir.c b/support/xmkdir.c +new file mode 100644 +index 0000000000..7e67f783de +--- /dev/null ++++ b/support/xmkdir.c +@@ -0,0 +1,28 @@ ++/* mkdir with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++xmkdir (const char *path, mode_t mode) ++{ ++ if (mkdir (path, mode) != 0) ++ FAIL_EXIT1 ("mkdir (\"%s\", 0%o): %m", path, mode); ++} +diff --git a/support/xmmap.c b/support/xmmap.c +new file mode 100644 +index 0000000000..d580c07013 +--- /dev/null ++++ b/support/xmmap.c +@@ -0,0 +1,31 @@ ++/* mmap with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void * ++xmmap (void *addr, size_t length, int prot, int flags, int fd) ++{ ++ void *result = mmap (addr, length, prot, flags, fd, 0); ++ if (result == MAP_FAILED) ++ FAIL_EXIT1 ("mmap of %zu bytes, prot=0x%x, flags=0x%x: %m", ++ length, prot, flags); ++ return result; ++} +diff --git a/support/xmprotect.c b/support/xmprotect.c +new file mode 100644 +index 0000000000..e6870988e0 +--- /dev/null ++++ b/support/xmprotect.c +@@ -0,0 +1,28 @@ ++/* mprotect with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++xmprotect (void *addr, size_t length, int prot) ++{ ++ if (mprotect (addr, length, prot) != 0) ++ FAIL_EXIT1 ("mprotect (%p, %zu, 0x%x): %m", addr, length, prot); ++} +diff --git a/support/xmunmap.c b/support/xmunmap.c +new file mode 100644 +index 0000000000..e8e5bc2d59 +--- /dev/null ++++ b/support/xmunmap.c +@@ -0,0 +1,28 @@ ++/* munmap with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void ++xmunmap (void *addr, size_t length) ++{ ++ if (munmap (addr, length) != 0) ++ FAIL_EXIT1 ("munmap of %zu bytes: %m", length); ++} +diff --git a/support/xopen.c b/support/xopen.c +new file mode 100644 +index 0000000000..3d888e8862 +--- /dev/null ++++ b/support/xopen.c +@@ -0,0 +1,30 @@ ++/* open64 with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++xopen (const char *path, int flags, mode_t mode) ++{ ++ int ret = open64 (path, flags, mode); ++ if (ret < 0) ++ FAIL_EXIT1 ("open64 (\"%s\", 0x%x, 0%o): %m", path, flags, mode); ++ return ret; ++} +diff --git a/support/xpipe.c b/support/xpipe.c +new file mode 100644 +index 0000000000..b8529df620 +--- /dev/null ++++ b/support/xpipe.c +@@ -0,0 +1,28 @@ ++/* pipe with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++void ++xpipe (int fds[2]) ++{ ++ if (pipe (fds) < 0) ++ FAIL_EXIT1 ("pipe: %m"); ++} +diff --git a/support/xpoll.c b/support/xpoll.c +new file mode 100644 +index 0000000000..b24bf32fc5 +--- /dev/null ++++ b/support/xpoll.c +@@ -0,0 +1,32 @@ ++/* poll with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++int ++xpoll (struct pollfd *fds, nfds_t nfds, int timeout) ++{ ++ int ret = poll (fds, nfds, timeout); ++ if (ret < 0) ++ FAIL_EXIT1 ("poll: %m"); ++ return ret; ++} +diff --git a/support/xpthread_attr_destroy.c b/support/xpthread_attr_destroy.c +new file mode 100644 +index 0000000000..52aa2602fe +--- /dev/null ++++ b/support/xpthread_attr_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_attr_destroy with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_attr_destroy (pthread_attr_t *attr) ++{ ++ xpthread_check_return ("pthread_attr_destroy", ++ pthread_attr_destroy (attr)); ++} +diff --git a/support/xpthread_attr_init.c b/support/xpthread_attr_init.c +new file mode 100644 +index 0000000000..c7aa903db2 +--- /dev/null ++++ b/support/xpthread_attr_init.c +@@ -0,0 +1,25 @@ ++/* pthread_attr_init with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_attr_init (pthread_attr_t *attr) ++{ ++ xpthread_check_return ("pthread_attr_init", pthread_attr_init (attr)); ++} +diff --git a/support/xpthread_attr_setdetachstate.c b/support/xpthread_attr_setdetachstate.c +new file mode 100644 +index 0000000000..6e845acc97 +--- /dev/null ++++ b/support/xpthread_attr_setdetachstate.c +@@ -0,0 +1,27 @@ ++/* pthread_attr_setdetachstate with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate) ++{ ++ xpthread_check_return ("pthread_attr_setdetachstate", ++ pthread_attr_setdetachstate (attr, ++ detachstate)); ++} +diff --git a/support/xpthread_attr_setguardsize.c b/support/xpthread_attr_setguardsize.c +new file mode 100644 +index 0000000000..964ec058c9 +--- /dev/null ++++ b/support/xpthread_attr_setguardsize.c +@@ -0,0 +1,26 @@ ++/* pthread_attr_setguardsize with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize) ++{ ++ xpthread_check_return ("pthread_attr_setguardize", ++ pthread_attr_setguardsize (attr, guardsize)); ++} +diff --git a/support/xpthread_attr_setstacksize.c b/support/xpthread_attr_setstacksize.c +new file mode 100644 +index 0000000000..c5517c0c66 +--- /dev/null ++++ b/support/xpthread_attr_setstacksize.c +@@ -0,0 +1,26 @@ ++/* pthread_attr_setstacksize with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize) ++{ ++ xpthread_check_return ("pthread_attr_setstacksize", ++ pthread_attr_setstacksize (attr, stacksize)); ++} +diff --git a/support/xpthread_barrier_destroy.c b/support/xpthread_barrier_destroy.c +new file mode 100644 +index 0000000000..1dae148b46 +--- /dev/null ++++ b/support/xpthread_barrier_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_barrier_destroy with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_barrier_destroy (pthread_barrier_t *barrier) ++{ ++ xpthread_check_return ("pthread_barrier_destroy", ++ pthread_barrier_destroy (barrier)); ++} +diff --git a/support/xpthread_barrier_init.c b/support/xpthread_barrier_init.c +new file mode 100644 +index 0000000000..4a2975ad12 +--- /dev/null ++++ b/support/xpthread_barrier_init.c +@@ -0,0 +1,27 @@ ++/* pthread_barrier_init with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_barrier_init (pthread_barrier_t *barrier, ++ pthread_barrierattr_t *attr, unsigned int count) ++{ ++ xpthread_check_return ("pthread_barrier_init", ++ pthread_barrier_init (barrier, attr, count)); ++} +diff --git a/support/xpthread_barrier_wait.c b/support/xpthread_barrier_wait.c +new file mode 100644 +index 0000000000..61690c5e7c +--- /dev/null ++++ b/support/xpthread_barrier_wait.c +@@ -0,0 +1,28 @@ ++/* pthread_barrier_wait with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int ++xpthread_barrier_wait (pthread_barrier_t *barrier) ++{ ++ int ret = pthread_barrier_wait (barrier); ++ if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) ++ xpthread_check_return ("pthread_barrier_wait", ret); ++ return ret == PTHREAD_BARRIER_SERIAL_THREAD; ++} +diff --git a/support/xpthread_cancel.c b/support/xpthread_cancel.c +new file mode 100644 +index 0000000000..26e864ea3e +--- /dev/null ++++ b/support/xpthread_cancel.c +@@ -0,0 +1,25 @@ ++/* pthread_cancel with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_cancel (pthread_t thr) ++{ ++ xpthread_check_return ("pthread_cancel", pthread_cancel (thr)); ++} +diff --git a/support/xpthread_check_return.c b/support/xpthread_check_return.c +new file mode 100644 +index 0000000000..1658db4b62 +--- /dev/null ++++ b/support/xpthread_check_return.c +@@ -0,0 +1,34 @@ ++/* Return value checking for pthread functions, exit variant. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++void ++xpthread_check_return (const char *function, int value) ++{ ++ if (value != 0) ++ { ++ errno = value; ++ FAIL_EXIT1 ("%s: %m", function); ++ } ++} +diff --git a/support/xpthread_cond_wait.c b/support/xpthread_cond_wait.c +new file mode 100644 +index 0000000000..08ec683b66 +--- /dev/null ++++ b/support/xpthread_cond_wait.c +@@ -0,0 +1,26 @@ ++/* pthread_cond_wait with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) ++{ ++ xpthread_check_return ++ ("pthread_cond_wait", pthread_cond_wait (cond, mutex)); ++} +diff --git a/support/xpthread_create.c b/support/xpthread_create.c +new file mode 100644 +index 0000000000..24b8456db9 +--- /dev/null ++++ b/support/xpthread_create.c +@@ -0,0 +1,29 @@ ++/* pthread_create with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++pthread_t ++xpthread_create (pthread_attr_t *attr, ++ void *(*thread_func) (void *), void *closure) ++{ ++ pthread_t thr; ++ xpthread_check_return ++ ("pthread_create", pthread_create (&thr, attr, thread_func, closure)); ++ return thr; ++} +diff --git a/support/xpthread_detach.c b/support/xpthread_detach.c +new file mode 100644 +index 0000000000..c65f2d7db1 +--- /dev/null ++++ b/support/xpthread_detach.c +@@ -0,0 +1,25 @@ ++/* pthread_detach with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_detach (pthread_t thr) ++{ ++ xpthread_check_return ("pthread_detach", pthread_detach (thr)); ++} +diff --git a/support/xpthread_join.c b/support/xpthread_join.c +new file mode 100644 +index 0000000000..29acbd283a +--- /dev/null ++++ b/support/xpthread_join.c +@@ -0,0 +1,27 @@ ++/* pthread_join with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void * ++xpthread_join (pthread_t thr) ++{ ++ void *result; ++ xpthread_check_return ("pthread_join", pthread_join (thr, &result)); ++ return result; ++} +diff --git a/support/xpthread_mutex_consistent.c b/support/xpthread_mutex_consistent.c +new file mode 100644 +index 0000000000..d337163609 +--- /dev/null ++++ b/support/xpthread_mutex_consistent.c +@@ -0,0 +1,26 @@ ++/* pthread_mutex_consistent with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutex_consistent (pthread_mutex_t *mutex) ++{ ++ xpthread_check_return ("pthread_mutex_consistent", ++ pthread_mutex_consistent (mutex)); ++} +diff --git a/support/xpthread_mutex_destroy.c b/support/xpthread_mutex_destroy.c +new file mode 100644 +index 0000000000..d03f016629 +--- /dev/null ++++ b/support/xpthread_mutex_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_mutex_destroy with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutex_destroy (pthread_mutex_t *mutex) ++{ ++ xpthread_check_return ("pthread_mutex_destroy", ++ pthread_mutex_destroy (mutex)); ++} +diff --git a/support/xpthread_mutex_init.c b/support/xpthread_mutex_init.c +new file mode 100644 +index 0000000000..40855954a8 +--- /dev/null ++++ b/support/xpthread_mutex_init.c +@@ -0,0 +1,26 @@ ++/* pthread_mutex_init with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) ++{ ++ xpthread_check_return ("pthread_mutex_init", ++ pthread_mutex_init (mutex, attr)); ++} +diff --git a/support/xpthread_mutex_lock.c b/support/xpthread_mutex_lock.c +new file mode 100644 +index 0000000000..4257960aaa +--- /dev/null ++++ b/support/xpthread_mutex_lock.c +@@ -0,0 +1,25 @@ ++/* pthread_mutex_lock with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutex_lock (pthread_mutex_t *mutex) ++{ ++ xpthread_check_return ("pthread_mutex_lock", pthread_mutex_lock (mutex)); ++} +diff --git a/support/xpthread_mutex_unlock.c b/support/xpthread_mutex_unlock.c +new file mode 100644 +index 0000000000..5c385c6934 +--- /dev/null ++++ b/support/xpthread_mutex_unlock.c +@@ -0,0 +1,25 @@ ++/* pthread_mutex_unlock with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutex_unlock (pthread_mutex_t *mutex) ++{ ++ xpthread_check_return ("pthread_mutex_unlock", pthread_mutex_unlock (mutex)); ++} +diff --git a/support/xpthread_mutexattr_destroy.c b/support/xpthread_mutexattr_destroy.c +new file mode 100644 +index 0000000000..f352a7ad93 +--- /dev/null ++++ b/support/xpthread_mutexattr_destroy.c +@@ -0,0 +1,26 @@ ++/* pthread_mutexattr_destroy with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutexattr_destroy (pthread_mutexattr_t *attr) ++{ ++ xpthread_check_return ("pthread_mutexattr_destroy", ++ pthread_mutexattr_destroy (attr)); ++} +diff --git a/support/xpthread_mutexattr_init.c b/support/xpthread_mutexattr_init.c +new file mode 100644 +index 0000000000..fe231581e3 +--- /dev/null ++++ b/support/xpthread_mutexattr_init.c +@@ -0,0 +1,25 @@ ++/* pthread_mutexattr_init with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutexattr_init (pthread_mutexattr_t *attr) ++{ ++ xpthread_check_return ("pthread_mutexattr_init", pthread_mutexattr_init (attr)); ++} +diff --git a/support/xpthread_mutexattr_setprotocol.c b/support/xpthread_mutexattr_setprotocol.c +new file mode 100644 +index 0000000000..e2f544d38c +--- /dev/null ++++ b/support/xpthread_mutexattr_setprotocol.c +@@ -0,0 +1,26 @@ ++/* pthread_mutexattr_setprotocol with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int flag) ++{ ++ xpthread_check_return ("pthread_mutexattr_setprotocol", ++ pthread_mutexattr_setprotocol (attr, flag)); ++} +diff --git a/support/xpthread_mutexattr_setpshared.c b/support/xpthread_mutexattr_setpshared.c +new file mode 100644 +index 0000000000..2380560d79 +--- /dev/null ++++ b/support/xpthread_mutexattr_setpshared.c +@@ -0,0 +1,26 @@ ++/* pthread_mutexattr_setpshared with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int flag) ++{ ++ xpthread_check_return ("pthread_mutexattr_setpshared", ++ pthread_mutexattr_setpshared (attr, flag)); ++} +diff --git a/support/xpthread_mutexattr_setrobust.c b/support/xpthread_mutexattr_setrobust.c +new file mode 100644 +index 0000000000..7886c72a77 +--- /dev/null ++++ b/support/xpthread_mutexattr_setrobust.c +@@ -0,0 +1,26 @@ ++/* pthread_mutexattr_setrobust with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutexattr_setrobust (pthread_mutexattr_t *attr, int flag) ++{ ++ xpthread_check_return ("pthread_mutexattr_setrobust", ++ pthread_mutexattr_setrobust (attr, flag)); ++} +diff --git a/support/xpthread_mutexattr_settype.c b/support/xpthread_mutexattr_settype.c +new file mode 100644 +index 0000000000..91f790c9e5 +--- /dev/null ++++ b/support/xpthread_mutexattr_settype.c +@@ -0,0 +1,26 @@ ++/* pthread_mutexattr_settype with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_mutexattr_settype (pthread_mutexattr_t *attr, int flag) ++{ ++ xpthread_check_return ("pthread_mutexattr_settype", ++ pthread_mutexattr_settype (attr, flag)); ++} +diff --git a/support/xpthread_once.c b/support/xpthread_once.c +new file mode 100644 +index 0000000000..b22c1ce3dd +--- /dev/null ++++ b/support/xpthread_once.c +@@ -0,0 +1,25 @@ ++/* pthread_once with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_once (pthread_once_t *guard, void (*func) (void)) ++{ ++ xpthread_check_return ("pthread_once", pthread_once (guard, func)); ++} +diff --git a/support/xpthread_rwlock_init.c b/support/xpthread_rwlock_init.c +new file mode 100644 +index 0000000000..e6c38115d8 +--- /dev/null ++++ b/support/xpthread_rwlock_init.c +@@ -0,0 +1,27 @@ ++/* pthread_rwlock_init with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlock_init (pthread_rwlock_t *rwlock, ++ const pthread_rwlockattr_t *attr) ++{ ++ xpthread_check_return ("pthread_rwlock_init", ++ pthread_rwlock_init (rwlock, attr)); ++} +diff --git a/support/xpthread_rwlock_rdlock.c b/support/xpthread_rwlock_rdlock.c +new file mode 100644 +index 0000000000..a88068fc86 +--- /dev/null ++++ b/support/xpthread_rwlock_rdlock.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlock_rdlock with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock) ++{ ++ xpthread_check_return ("pthread_rwlock_rdlock", ++ pthread_rwlock_rdlock (rwlock)); ++} +diff --git a/support/xpthread_rwlock_unlock.c b/support/xpthread_rwlock_unlock.c +new file mode 100644 +index 0000000000..7eb282fd18 +--- /dev/null ++++ b/support/xpthread_rwlock_unlock.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlock_unlock with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlock_unlock (pthread_rwlock_t *rwlock) ++{ ++ xpthread_check_return ("pthread_rwlock_unlock", ++ pthread_rwlock_unlock (rwlock)); ++} +diff --git a/support/xpthread_rwlock_wrlock.c b/support/xpthread_rwlock_wrlock.c +new file mode 100644 +index 0000000000..0de37146c3 +--- /dev/null ++++ b/support/xpthread_rwlock_wrlock.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlock_wrlock with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock) ++{ ++ xpthread_check_return ("pthread_rwlock_wrlock", ++ pthread_rwlock_wrlock (rwlock)); ++} +diff --git a/support/xpthread_rwlockattr_init.c b/support/xpthread_rwlockattr_init.c +new file mode 100644 +index 0000000000..96ac47d777 +--- /dev/null ++++ b/support/xpthread_rwlockattr_init.c +@@ -0,0 +1,26 @@ ++/* pthread_rwlockattr_init with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlockattr_init (pthread_rwlockattr_t *attr) ++{ ++ xpthread_check_return ("pthread_rwlockattr_init", ++ pthread_rwlockattr_init (attr)); ++} +diff --git a/support/xpthread_rwlockattr_setkind_np.c b/support/xpthread_rwlockattr_setkind_np.c +new file mode 100644 +index 0000000000..34aa3df0a9 +--- /dev/null ++++ b/support/xpthread_rwlockattr_setkind_np.c +@@ -0,0 +1,27 @@ ++/* pthread_rwlockattr_setkind_np with error checking. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, ++ int pref) ++{ ++ xpthread_check_return ("pthread_rwlockattr_setkind_np", ++ pthread_rwlockattr_setkind_np (attr, pref)); ++} +diff --git a/support/xpthread_sigmask.c b/support/xpthread_sigmask.c +new file mode 100644 +index 0000000000..1fb91dcc20 +--- /dev/null ++++ b/support/xpthread_sigmask.c +@@ -0,0 +1,34 @@ ++/* pthread_sigmask with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include ++ ++void ++xpthread_sigmask (int how, const sigset_t *set, sigset_t *oldset) ++{ ++ if (pthread_sigmask (how, set, oldset) != 0) ++ { ++ write_message ("error: pthread_setmask failed\n"); ++ /* Do not use exit because pthread_sigmask can be called from a ++ signal handler. */ ++ _exit (1); ++ } ++} +diff --git a/support/xpthread_spin_lock.c b/support/xpthread_spin_lock.c +new file mode 100644 +index 0000000000..4cadbf70f9 +--- /dev/null ++++ b/support/xpthread_spin_lock.c +@@ -0,0 +1,25 @@ ++/* pthread_spin_lock with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_spin_lock (pthread_spinlock_t *lock) ++{ ++ xpthread_check_return ("pthread_spin_lock", pthread_spin_lock (lock)); ++} +diff --git a/support/xpthread_spin_unlock.c b/support/xpthread_spin_unlock.c +new file mode 100644 +index 0000000000..194613993a +--- /dev/null ++++ b/support/xpthread_spin_unlock.c +@@ -0,0 +1,25 @@ ++/* pthread_spin_unlock with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void ++xpthread_spin_unlock (pthread_spinlock_t *lock) ++{ ++ xpthread_check_return ("pthread_spin_unlock", pthread_spin_unlock (lock)); ++} +diff --git a/support/xraise.c b/support/xraise.c +new file mode 100644 +index 0000000000..1901e741eb +--- /dev/null ++++ b/support/xraise.c +@@ -0,0 +1,27 @@ ++/* Error-checking wrapper for raise. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++xraise (int sig) ++{ ++ if (raise (sig) != 0) ++ FAIL_EXIT1 ("raise (%d): %m" , sig); ++} +diff --git a/support/xreadlink.c b/support/xreadlink.c +new file mode 100644 +index 0000000000..c6386491db +--- /dev/null ++++ b/support/xreadlink.c +@@ -0,0 +1,44 @@ ++/* Error-checking, allocating wrapper for readlink. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++char * ++xreadlink (const char *path) ++{ ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ ++ while (true) ++ { ++ ssize_t count = readlink (path, buf.data, buf.length); ++ if (count < 0) ++ FAIL_EXIT1 ("readlink (\"%s\"): %m", path); ++ if (count < buf.length) ++ { ++ char *result = xstrndup (buf.data, count); ++ scratch_buffer_free (&buf); ++ return result; ++ } ++ if (!scratch_buffer_grow (&buf)) ++ FAIL_EXIT1 ("scratch_buffer_grow in xreadlink"); ++ } ++} +diff --git a/support/xrealloc.c b/support/xrealloc.c +new file mode 100644 +index 0000000000..4d9987c9bb +--- /dev/null ++++ b/support/xrealloc.c +@@ -0,0 +1,32 @@ ++/* Error-checking wrapper for realloc. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void * ++xrealloc (void *p, size_t n) ++{ ++ void *result = realloc (p, n); ++ if (result == NULL && (n > 0 || p == NULL)) ++ oom_error ("realloc", n); ++ return result; ++} +diff --git a/support/xrecvfrom.c b/support/xrecvfrom.c +new file mode 100644 +index 0000000000..a1011a5062 +--- /dev/null ++++ b/support/xrecvfrom.c +@@ -0,0 +1,33 @@ ++/* recvfrom with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++size_t ++xrecvfrom (int fd, void *buf, size_t buflen, int flags, ++ struct sockaddr *sa, socklen_t *salen) ++{ ++ ssize_t ret = recvfrom (fd, buf, buflen, flags, sa, salen); ++ if (ret < 0) ++ FAIL_EXIT1 ("error: recvfrom (%d), %zu bytes buffer: %m", fd, buflen); ++ return ret; ++} +diff --git a/support/xsendto.c b/support/xsendto.c +new file mode 100644 +index 0000000000..f51530793e +--- /dev/null ++++ b/support/xsendto.c +@@ -0,0 +1,35 @@ ++/* sendto with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void ++xsendto (int fd, const void *buf, size_t buflen, int flags, ++ const struct sockaddr *sa, socklen_t salen) ++{ ++ ssize_t ret = sendto (fd, buf, buflen, flags, sa, salen); ++ if (ret < 0) ++ FAIL_EXIT1 ("sendto (%d), %zu bytes, family %d: %m", ++ fd, buflen, sa->sa_family); ++ if (ret != buflen) ++ FAIL_EXIT1 ("sendto (%d) sent %zd bytes instead of %zu", fd, ret, buflen); ++} +diff --git a/support/xsetsockopt.c b/support/xsetsockopt.c +new file mode 100644 +index 0000000000..b7c07f21f9 +--- /dev/null ++++ b/support/xsetsockopt.c +@@ -0,0 +1,31 @@ ++/* setsockopt with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++void ++xsetsockopt (int fd, int level, int name, const void *val, socklen_t vallen) ++{ ++ if (setsockopt (fd, level, name, val, vallen) != 0) ++ FAIL_EXIT1 ("setsockopt (%d, %d, %d), %zu bytes: %m", ++ fd, level, name, (size_t) vallen); ++} +diff --git a/support/xsigaction.c b/support/xsigaction.c +new file mode 100644 +index 0000000000..51657de2b7 +--- /dev/null ++++ b/support/xsigaction.c +@@ -0,0 +1,27 @@ ++/* Error-checking wrapper for sigaction. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++xsigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) ++{ ++ if (sigaction (sig, newact, oldact)) ++ FAIL_EXIT1 ("sigaction (%d): %m" , sig); ++} +diff --git a/support/xsignal.c b/support/xsignal.c +new file mode 100644 +index 0000000000..e7369f0324 +--- /dev/null ++++ b/support/xsignal.c +@@ -0,0 +1,29 @@ ++/* Error-checking wrapper for signal. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++sighandler_t ++xsignal (int sig, sighandler_t handler) ++{ ++ sighandler_t result = signal (sig, handler); ++ if (result == SIG_ERR) ++ FAIL_EXIT1 ("signal (%d, %p): %m", sig, handler); ++ return result; ++} +diff --git a/support/xsignal.h b/support/xsignal.h +new file mode 100644 +index 0000000000..9ab8d1bfdd +--- /dev/null ++++ b/support/xsignal.h +@@ -0,0 +1,42 @@ ++/* Support functionality for using signals. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_SIGNAL_H ++#define SUPPORT_SIGNAL_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* The following functions call the corresponding libc functions and ++ terminate the process on error. */ ++ ++void xraise (int sig); ++sighandler_t xsignal (int sig, sighandler_t handler); ++void xsigaction (int sig, const struct sigaction *newact, ++ struct sigaction *oldact); ++ ++/* The following functions call the corresponding libpthread functions ++ and terminate the process on error. */ ++ ++void xpthread_sigmask (int how, const sigset_t *set, sigset_t *oldset); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_SIGNAL_H */ +diff --git a/support/xsocket.c b/support/xsocket.c +new file mode 100644 +index 0000000000..20282fb810 +--- /dev/null ++++ b/support/xsocket.c +@@ -0,0 +1,32 @@ ++/* socket with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++ ++int ++xsocket (int domain, int type, int protocol) ++{ ++ int fd = socket (domain, type, protocol); ++ if (fd < 0) ++ FAIL_EXIT1 ("socket (%d, %d, %d): %m\n", domain, type, protocol); ++ return fd; ++} +diff --git a/support/xsocket.h b/support/xsocket.h +new file mode 100644 +index 0000000000..9673abdf54 +--- /dev/null ++++ b/support/xsocket.h +@@ -0,0 +1,39 @@ ++/* Error-checking wrappers for socket functions. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_XSOCKET_H ++#define SUPPORT_XSOCKET_H ++ ++#include ++#include ++#include ++ ++int xsocket (int, int, int); ++void xsetsockopt (int, int, int, const void *, socklen_t); ++void xgetsockname (int, struct sockaddr *, socklen_t *); ++void xconnect (int, const struct sockaddr *, socklen_t); ++void xbind (int, const struct sockaddr *, socklen_t); ++void xlisten (int, int); ++int xaccept (int, struct sockaddr *, socklen_t *); ++int xaccept4 (int, struct sockaddr *, socklen_t *, int); ++void xsendto (int, const void *, size_t, int, ++ const struct sockaddr *, socklen_t); ++size_t xrecvfrom (int, void *, size_t, int, struct sockaddr *, socklen_t *); ++int xpoll (struct pollfd *, nfds_t, int); ++ ++#endif /* SUPPORT_XSOCKET_H */ +diff --git a/support/xstdio.h b/support/xstdio.h +new file mode 100644 +index 0000000000..e7d0274474 +--- /dev/null ++++ b/support/xstdio.h +@@ -0,0 +1,32 @@ ++/* Error-checking wrappers for stdio functions. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_XSTDIO_H ++#define SUPPORT_XSTDIO_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++FILE *xfopen (const char *path, const char *mode); ++void xfclose (FILE *); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_XSTDIO_H */ +diff --git a/support/xstrdup.c b/support/xstrdup.c +new file mode 100644 +index 0000000000..89eee8584e +--- /dev/null ++++ b/support/xstrdup.c +@@ -0,0 +1,30 @@ ++/* strdup with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++char * ++xstrdup (const char *s) ++{ ++ char *p = strdup (s); ++ if (p == NULL) ++ oom_error ("strdup", strlen (s)); ++ return p; ++} +diff --git a/support/xstrndup.c b/support/xstrndup.c +new file mode 100644 +index 0000000000..e85fddd439 +--- /dev/null ++++ b/support/xstrndup.c +@@ -0,0 +1,30 @@ ++/* strndup with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++char * ++xstrndup (const char *s, size_t length) ++{ ++ char *p = strndup (s, length); ++ if (p == NULL) ++ oom_error ("strndup", length); ++ return p; ++} +diff --git a/support/xsysconf.c b/support/xsysconf.c +new file mode 100644 +index 0000000000..afefc2d098 +--- /dev/null ++++ b/support/xsysconf.c +@@ -0,0 +1,36 @@ ++/* Error-checking wrapper for sysconf. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++long ++xsysconf (int name) ++{ ++ /* Detect errors by a changed errno value, in case -1 is a valid ++ value. Make sure that the caller does not see the zero value for ++ errno. */ ++ int old_errno = errno; ++ errno = 0; ++ long result = sysconf (name); ++ if (errno != 0) ++ FAIL_EXIT1 ("sysconf (%d): %m", name); ++ errno = old_errno; ++ return result; ++} +diff --git a/support/xthread.h b/support/xthread.h +new file mode 100644 +index 0000000000..79358e7c99 +--- /dev/null ++++ b/support/xthread.h +@@ -0,0 +1,87 @@ ++/* Support functionality for using threads. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef SUPPORT_THREAD_H ++#define SUPPORT_THREAD_H ++ ++#include ++#include ++ ++__BEGIN_DECLS ++ ++/* Terminate the process (with exit status 0) after SECONDS have ++ elapsed, from a helper thread. The process is terminated with the ++ exit function, so atexit handlers are executed. */ ++void delayed_exit (int seconds); ++ ++/* Terminate the process (with exit status 1) if VALUE is not zero. ++ In that case, print a failure message to standard output mentioning ++ FUNCTION. The process is terminated with the exit function, so ++ atexit handlers are executed. */ ++void xpthread_check_return (const char *function, int value); ++ ++/* The following functions call the corresponding libpthread functions ++ and terminate the process on error. */ ++ ++void xpthread_barrier_init (pthread_barrier_t *barrier, ++ pthread_barrierattr_t *attr, unsigned int count); ++void xpthread_barrier_destroy (pthread_barrier_t *barrier); ++void xpthread_mutexattr_destroy (pthread_mutexattr_t *); ++void xpthread_mutexattr_init (pthread_mutexattr_t *); ++void xpthread_mutexattr_setprotocol (pthread_mutexattr_t *, int); ++void xpthread_mutexattr_setpshared (pthread_mutexattr_t *, int); ++void xpthread_mutexattr_setrobust (pthread_mutexattr_t *, int); ++void xpthread_mutexattr_settype (pthread_mutexattr_t *, int); ++void xpthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *); ++void xpthread_mutex_destroy (pthread_mutex_t *); ++void xpthread_mutex_lock (pthread_mutex_t *mutex); ++void xpthread_mutex_unlock (pthread_mutex_t *mutex); ++void xpthread_mutex_consistent (pthread_mutex_t *); ++void xpthread_spin_lock (pthread_spinlock_t *lock); ++void xpthread_spin_unlock (pthread_spinlock_t *lock); ++void xpthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex); ++pthread_t xpthread_create (pthread_attr_t *attr, ++ void *(*thread_func) (void *), void *closure); ++void xpthread_detach (pthread_t thr); ++void xpthread_cancel (pthread_t thr); ++void *xpthread_join (pthread_t thr); ++void xpthread_once (pthread_once_t *guard, void (*func) (void)); ++void xpthread_attr_destroy (pthread_attr_t *attr); ++void xpthread_attr_init (pthread_attr_t *attr); ++void xpthread_attr_setdetachstate (pthread_attr_t *attr, ++ int detachstate); ++void xpthread_attr_setstacksize (pthread_attr_t *attr, ++ size_t stacksize); ++void xpthread_attr_setguardsize (pthread_attr_t *attr, ++ size_t guardsize); ++ ++/* This function returns non-zero if pthread_barrier_wait returned ++ PTHREAD_BARRIER_SERIAL_THREAD. */ ++int xpthread_barrier_wait (pthread_barrier_t *barrier); ++ ++void xpthread_rwlock_init (pthread_rwlock_t *rwlock, ++ const pthread_rwlockattr_t *attr); ++void xpthread_rwlockattr_init (pthread_rwlockattr_t *attr); ++void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref); ++void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock); ++void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock); ++void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_THREAD_H */ +diff --git a/support/xunistd.h b/support/xunistd.h +new file mode 100644 +index 0000000000..5fe5dae818 +--- /dev/null ++++ b/support/xunistd.h +@@ -0,0 +1,65 @@ ++/* POSIX-specific extra functions. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* These wrapper functions use POSIX types and therefore cannot be ++ declared in . */ ++ ++#ifndef SUPPORT_XUNISTD_H ++#define SUPPORT_XUNISTD_H ++ ++#include ++#include ++#include ++ ++__BEGIN_DECLS ++ ++struct stat64; ++ ++pid_t xfork (void); ++pid_t xwaitpid (pid_t, int *status, int flags); ++void xpipe (int[2]); ++void xdup2 (int, int); ++int xopen (const char *path, int flags, mode_t); ++void xstat (const char *path, struct stat64 *); ++void xfstat (int fd, struct stat64 *); ++void xmkdir (const char *path, mode_t); ++void xchroot (const char *path); ++void xunlink (const char *path); ++long xsysconf (int name); ++long long xlseek (int fd, long long offset, int whence); ++void xftruncate (int fd, long long length); ++ ++/* Read the link at PATH. The caller should free the returned string ++ with free. */ ++char *xreadlink (const char *path); ++ ++/* Close the file descriptor. Ignore EINTR errors, but terminate the ++ process on other errors. */ ++void xclose (int); ++ ++/* Write the buffer. Retry on short writes. */ ++void xwrite (int, const void *, size_t); ++ ++/* Invoke mmap with a zero file offset. */ ++void *xmmap (void *addr, size_t length, int prot, int flags, int fd); ++void xmprotect (void *addr, size_t length, int prot); ++void xmunmap (void *addr, size_t length); ++ ++__END_DECLS ++ ++#endif /* SUPPORT_XUNISTD_H */ +diff --git a/support/xunlink.c b/support/xunlink.c +new file mode 100644 +index 0000000000..2ff9296fca +--- /dev/null ++++ b/support/xunlink.c +@@ -0,0 +1,27 @@ ++/* Error-checking wrapper for unlink. ++ Copyright (C) 2017-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++xunlink (const char *path) ++{ ++ if (unlink (path) != 0) ++ FAIL_EXIT1 ("unlink (\"%s\"): %m", path); ++} +diff --git a/support/xwaitpid.c b/support/xwaitpid.c +new file mode 100644 +index 0000000000..1cb039ca17 +--- /dev/null ++++ b/support/xwaitpid.c +@@ -0,0 +1,33 @@ ++/* waitpid with error checking. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++int ++xwaitpid (int pid, int *status, int flags) ++{ ++ pid_t result = waitpid (pid, status, flags); ++ if (result < 0) ++ FAIL_EXIT1 ("waitpid: %m\n"); ++ return result; ++} +diff --git a/support/xwrite.c b/support/xwrite.c +new file mode 100644 +index 0000000000..bbaae9130a +--- /dev/null ++++ b/support/xwrite.c +@@ -0,0 +1,39 @@ ++/* write with error checking and retries. ++ Copyright (C) 2016-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++void ++xwrite (int fd, const void *buffer, size_t length) ++{ ++ const char *p = buffer; ++ const char *end = p + length; ++ while (p < end) ++ { ++ ssize_t ret = write (fd, p, end - p); ++ if (ret < 0) ++ FAIL_EXIT1 ("write of %zu bytes failed after %td: %m", ++ length, p - (const char *) buffer); ++ if (ret == 0) ++ FAIL_EXIT1 ("write return 0 after writing %td bytes of %zu", ++ p - (const char *) buffer, length); ++ p += ret; ++ } ++} diff --git a/SOURCES/glibc-rh1418978-2-1.patch b/SOURCES/glibc-rh1418978-2-1.patch new file mode 100644 index 00000000..56896d8d --- /dev/null +++ b/SOURCES/glibc-rh1418978-2-1.patch @@ -0,0 +1,18 @@ +commit ace4acc8ace692f64051594afe47efb1135b3c29 +Author: Siddhesh Poyarekar +Date: Fri Mar 1 20:45:17 2013 +0530 + + Fix build warning + +Index: b/nptl/tst-oddstacklimit.c +=================================================================== +--- a/nptl/tst-oddstacklimit.c ++++ b/nptl/tst-oddstacklimit.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + /* This sets the stack resource limit to 1023kb, which is not a multiple + of the page size since every architecture's page size is > 1k. */ diff --git a/SOURCES/glibc-rh1418978-2-2.patch b/SOURCES/glibc-rh1418978-2-2.patch new file mode 100644 index 00000000..0b42b59e --- /dev/null +++ b/SOURCES/glibc-rh1418978-2-2.patch @@ -0,0 +1,18 @@ +commit aba8ef95b56313269512f5ec449e0d9c74d2a1e2 +Author: Roland McGrath +Date: Mon Jun 23 14:07:59 2014 -0700 + + Add missing #include in get-rounding-mode.h + +Index: b/sysdeps/generic/get-rounding-mode.h +=================================================================== +--- a/sysdeps/generic/get-rounding-mode.h ++++ b/sysdeps/generic/get-rounding-mode.h +@@ -20,6 +20,7 @@ + #define _GET_ROUNDING_MODE_H 1 + + #include ++#include + + /* Define values for FE_* modes not defined for this architecture. */ + #ifdef FE_DOWNWARD diff --git a/SOURCES/glibc-rh1418978-2-3.patch b/SOURCES/glibc-rh1418978-2-3.patch new file mode 100644 index 00000000..10c2d561 --- /dev/null +++ b/SOURCES/glibc-rh1418978-2-3.patch @@ -0,0 +1,20 @@ +commit d3c827e7c8208afeaed880cf8cf2515c86d10f17 +Author: Andreas Krebbel +Date: Fri Sep 19 11:26:31 2014 +0200 + + stdlib/longlong.h: Add __udiv_w_sdiv prototype. + +Index: b/stdlib/longlong.h +=================================================================== +--- a/stdlib/longlong.h ++++ b/stdlib/longlong.h +@@ -1642,7 +1642,8 @@ extern UHItype __stormy16_count_leading_ + #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) + #define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ +- USItype __r; \ ++ extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype); \ ++ UWtype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) diff --git a/SOURCES/glibc-rh1418978-2-4.patch b/SOURCES/glibc-rh1418978-2-4.patch new file mode 100644 index 00000000..618a0c11 --- /dev/null +++ b/SOURCES/glibc-rh1418978-2-4.patch @@ -0,0 +1,18 @@ +commit a849e800352ac5068dc6f1191c86ff62ba014c61 +Author: Andreas Schwab +Date: Thu May 1 22:00:34 2014 +0200 + + Fix implicit declaration + +Index: b/nscd/nscd-client.h +=================================================================== +--- a/nscd/nscd-client.h ++++ b/nscd/nscd-client.h +@@ -24,6 +24,7 @@ + + #include + #include ++#include + #include + #include + #include diff --git a/SOURCES/glibc-rh1418978-2-5.patch b/SOURCES/glibc-rh1418978-2-5.patch new file mode 100644 index 00000000..a089dbcc --- /dev/null +++ b/SOURCES/glibc-rh1418978-2-5.patch @@ -0,0 +1,56 @@ +commit ffaa74cf68a370e232279a9a9b0a02ade287cc99 +Author: Siddhesh Poyarekar +Date: Mon Feb 18 18:17:05 2013 +0530 + + Fix build warnings in some test cases + + Include stdlib.h to get declaration of exit(3) + +Index: b/misc/tst-pselect.c +=================================================================== +--- a/misc/tst-pselect.c ++++ b/misc/tst-pselect.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + + static volatile int handler_called; +Index: b/nptl/sysdeps/pthread/tst-timer.c +=================================================================== +--- a/nptl/sysdeps/pthread/tst-timer.c ++++ b/nptl/sysdeps/pthread/tst-timer.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + + static void +Index: b/nptl/tst-barrier4.c +=================================================================== +--- a/nptl/tst-barrier4.c ++++ b/nptl/tst-barrier4.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + + static pthread_barrier_t b1; +Index: b/nptl/tst-robust7.c +=================================================================== +--- a/nptl/tst-robust7.c ++++ b/nptl/tst-robust7.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + + static pthread_barrier_t b; diff --git a/SOURCES/glibc-rh1418978-2-6.patch b/SOURCES/glibc-rh1418978-2-6.patch new file mode 100644 index 00000000..f4e935ec --- /dev/null +++ b/SOURCES/glibc-rh1418978-2-6.patch @@ -0,0 +1,24 @@ +commit e6fb95871cd3557e5882a6f969c11bc6a3cbe781 +Author: Florian Weimer +Date: Mon Sep 8 13:49:36 2014 +0200 + + Turn on -Werror=implicit-function-declaration + + GCC 4.4, the minimum compiler version, supports this option. Unlike + other warnings, -Wimplicit-function-declaration warnings should be + independent of compiler versions, so this change should not cause + compiler-specific build failures. + +Index: b/Makeconfig +=================================================================== +--- a/Makeconfig ++++ b/Makeconfig +@@ -643,7 +643,7 @@ ifeq ($(all-warnings),yes) + else + +gccwarn := -Wall -Wwrite-strings -Winline + endif +-+gccwarn-c = -Wstrict-prototypes +++gccwarn-c = -Wstrict-prototypes -Werror=implicit-function-declaration + + # We do not depend on the address of constants in different files to be + # actually different, so allow the compiler to merge them all. diff --git a/SOURCES/glibc-rh1418978-3-1.patch b/SOURCES/glibc-rh1418978-3-1.patch new file mode 100644 index 00000000..9cc535d2 --- /dev/null +++ b/SOURCES/glibc-rh1418978-3-1.patch @@ -0,0 +1,126 @@ +commit c5c13355132e73578bbc0c612ddff964e6199747 +Author: Will Newton +Date: Fri Apr 11 15:21:23 2014 +0100 + + test-skeleton.c: Use stdout for error messages + + At the moment the test skeleton uses a mixture of stdout and + stderr for error message output. Using stdout for all test output + keeps all output correctly ordered and properly redirected to the + output file. The suggestion to use stdout is also made on the wiki: + + https://sourceware.org/glibc/wiki/Testing/Testsuite#Writing_a_test_case + + ChangeLog: + + 2014-06-23 Will Newton + + * test-skeleton.c (signal_handler): Use printf and %m + rather than perror. Use printf rather than fprintf to + stderr. Use puts rather than fputs to stderr. + (main): Likewise. + +Index: b/test-skeleton.c +=================================================================== +--- a/test-skeleton.c ++++ b/test-skeleton.c +@@ -188,7 +188,7 @@ signal_handler (int sig __attribute__ (( + } + if (killed != 0 && killed != pid) + { +- perror ("Failed to kill test process"); ++ printf ("Failed to kill test process: %m\n"); + exit (1); + } + +@@ -209,16 +209,16 @@ signal_handler (int sig __attribute__ (( + #endif + + if (killed == 0 || (WIFSIGNALED (status) && WTERMSIG (status) == SIGKILL)) +- fputs ("Timed out: killed the child process\n", stderr); ++ puts ("Timed out: killed the child process"); + else if (WIFSTOPPED (status)) +- fprintf (stderr, "Timed out: the child process was %s\n", +- strsignal (WSTOPSIG (status))); ++ printf ("Timed out: the child process was %s\n", ++ strsignal (WSTOPSIG (status))); + else if (WIFSIGNALED (status)) +- fprintf (stderr, "Timed out: the child process got signal %s\n", +- strsignal (WTERMSIG (status))); ++ printf ("Timed out: the child process got signal %s\n", ++ strsignal (WTERMSIG (status))); + else +- fprintf (stderr, "Timed out: killed the child process but it exited %d\n", +- WEXITSTATUS (status)); ++ printf ("Timed out: killed the child process but it exited %d\n", ++ WEXITSTATUS (status)); + + /* Exit with an error. */ + exit (1); +@@ -308,7 +308,7 @@ main (int argc, char *argv[]) + + if (chdir (test_dir) < 0) + { +- perror ("chdir"); ++ printf ("chdir: %m\n"); + exit (1); + } + } +@@ -367,10 +367,10 @@ main (int argc, char *argv[]) + data_limit.rlim_cur = MIN ((rlim_t) TEST_DATA_LIMIT, + data_limit.rlim_max); + if (setrlimit (RLIMIT_DATA, &data_limit) < 0) +- perror ("setrlimit: RLIMIT_DATA"); ++ printf ("setrlimit: RLIMIT_DATA: %m\n"); + } + else +- perror ("getrlimit: RLIMIT_DATA"); ++ printf ("getrlimit: RLIMIT_DATA: %m\n"); + #endif + + /* We put the test process in its own pgrp so that if it bogusly +@@ -382,7 +382,7 @@ main (int argc, char *argv[]) + } + else if (pid < 0) + { +- perror ("Cannot fork test program"); ++ printf ("Cannot fork test program: %m\n"); + exit (1); + } + +@@ -420,18 +420,16 @@ main (int argc, char *argv[]) + if (EXPECTED_SIGNAL != 0) + { + if (WTERMSIG (status) == 0) +- fprintf (stderr, +- "Expected signal '%s' from child, got none\n", +- strsignal (EXPECTED_SIGNAL)); ++ printf ("Expected signal '%s' from child, got none\n", ++ strsignal (EXPECTED_SIGNAL)); + else +- fprintf (stderr, +- "Incorrect signal from child: got `%s', need `%s'\n", +- strsignal (WTERMSIG (status)), +- strsignal (EXPECTED_SIGNAL)); ++ printf ("Incorrect signal from child: got `%s', need `%s'\n", ++ strsignal (WTERMSIG (status)), ++ strsignal (EXPECTED_SIGNAL)); + } + else +- fprintf (stderr, "Didn't expect signal from child: got `%s'\n", +- strsignal (WTERMSIG (status))); ++ printf ("Didn't expect signal from child: got `%s'\n", ++ strsignal (WTERMSIG (status))); + exit (1); + } + +@@ -441,8 +439,8 @@ main (int argc, char *argv[]) + #else + if (WEXITSTATUS (status) != EXPECTED_STATUS) + { +- fprintf (stderr, "Expected status %d, got %d\n", +- EXPECTED_STATUS, WEXITSTATUS (status)); ++ printf ("Expected status %d, got %d\n", ++ EXPECTED_STATUS, WEXITSTATUS (status)); + exit (1); + } diff --git a/SOURCES/glibc-rh1418978-3-2.patch b/SOURCES/glibc-rh1418978-3-2.patch new file mode 100644 index 00000000..f64c37c6 --- /dev/null +++ b/SOURCES/glibc-rh1418978-3-2.patch @@ -0,0 +1,41 @@ +commit 900056024b75eae8b550d7fee1dec9e71f28344e +Author: Florian Weimer +Date: Mon Mar 7 13:48:47 2016 +0100 + + test-skeleton.c: Do not set RLIMIT_DATA [BZ #19648] + + With older kernels, it is mostly ineffective because it causes malloc + to switch from sbrk to mmap (potentially invalidating malloc testing + compared to what real appliations do). With newer kernels which + have switched to enforcing RLIMIT_DATA for mmap as well, some test + cases will fail in an unintended fashion because the limit which was + set previously does not include room for all mmap mappings. + +Index: b/test-skeleton.c +=================================================================== +--- a/test-skeleton.c ++++ b/test-skeleton.c +@@ -356,23 +356,6 @@ main (int argc, char *argv[]) + setrlimit (RLIMIT_CORE, &core_limit); + #endif + +-#ifdef RLIMIT_DATA +- /* Try to avoid eating all memory if a test leaks. */ +- struct rlimit data_limit; +- if (getrlimit (RLIMIT_DATA, &data_limit) == 0) +- { +- if (TEST_DATA_LIMIT == RLIM_INFINITY) +- data_limit.rlim_cur = data_limit.rlim_max; +- else if (data_limit.rlim_cur > (rlim_t) TEST_DATA_LIMIT) +- data_limit.rlim_cur = MIN ((rlim_t) TEST_DATA_LIMIT, +- data_limit.rlim_max); +- if (setrlimit (RLIMIT_DATA, &data_limit) < 0) +- printf ("setrlimit: RLIMIT_DATA: %m\n"); +- } +- else +- printf ("getrlimit: RLIMIT_DATA: %m\n"); +-#endif +- + /* We put the test process in its own pgrp so that if it bogusly + generates any job control signals, they won't hit the whole build. */ + setpgid (0, 0); diff --git a/SOURCES/glibc-rh1418978-max_align_t.patch b/SOURCES/glibc-rh1418978-max_align_t.patch new file mode 100644 index 00000000..abdfa1ce --- /dev/null +++ b/SOURCES/glibc-rh1418978-max_align_t.patch @@ -0,0 +1,82 @@ +This patch adds a definition of max_align_t to the internal + header, for use in support/ functionality and elsewhere. + +The definition must support being compiled in C11 or C++11 mode and +must check both __STDC_VERSION__ and __cplusplus versions. + +Upstream does not need this because all files are compiled in C11 +mode, making available the GCC definition in + +Also change malloc/tst-malloc-thread-fail.c to use the new definition. + +Index: glibc-2.17-c758a686/include/sys/cdefs.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/sys/cdefs.h ++++ glibc-2.17-c758a686/include/sys/cdefs.h +@@ -15,6 +15,18 @@ rtld_hidden_proto (__chk_fail) + + + # define __attribute_alloc_size(...) __attribute__ ((alloc_size (__VA_ARGS__))) ++ ++/* This mirrors the C11/C++11 max_align_t type provided by GCC, but it ++ is also available in C99 mode. The aligned attributes are required ++ because some ABIs have reduced alignment requirements for struct and ++ union members. */ ++#if __STDC_VERSION__ < 201112L && __cplusplus < 201103L ++typedef struct { ++ long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); ++ long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); ++} max_align_t; ++#endif /* __STDC_VERSION__ < 201112 && __cplusplus < 201103L */ ++ + #endif + + #endif +Index: glibc-2.17-c758a686/malloc/tst-malloc-thread-fail.c +=================================================================== +--- glibc-2.17-c758a686.orig/malloc/tst-malloc-thread-fail.c ++++ glibc-2.17-c758a686/malloc/tst-malloc-thread-fail.c +@@ -30,16 +30,6 @@ + #include + #include + #include +-#include +- +-/* This mirrors the C11 max_align_t type provided by GCC, but it is +- also available in C99 mode. The aligned attributes are required +- because some ABIs have reduced alignment requirements for struct +- and union members. */ +-typedef struct { +- long long ll __attribute__ ((__aligned__ (__alignof__ (long long)))); +- long double ld __attribute__ ((__aligned__ (__alignof__ (long double)))); +-} libc_max_align_t; + + /* Wrapper for calloc with an optimization barrier. */ + static void * +@@ -93,7 +83,7 @@ allocate_1 (void) + { + case with_malloc: + return (struct allocate_result) +- {malloc (allocation_size), __alignof__ (libc_max_align_t)}; ++ {malloc (allocation_size), _Alignof (max_align_t)}; + case with_realloc: + { + void *p = realloc (NULL, 16); +@@ -106,7 +96,7 @@ allocate_1 (void) + if (q == NULL) + free (p); + } +- return (struct allocate_result) {q, __alignof__ (libc_max_align_t)}; ++ return (struct allocate_result) {q, _Alignof (max_align_t)}; + } + case with_aligned_alloc: + { +@@ -155,7 +145,7 @@ allocate_1 (void) + printf ("error: non-zero byte at offset %zu\n", i); + abort (); + } +- return (struct allocate_result) {p, __alignof__ (libc_max_align_t)}; ++ return (struct allocate_result) {p, _Alignof (max_align_t)}; + } + } + abort (); diff --git a/SOURCES/glibc-rh1418997.patch b/SOURCES/glibc-rh1418997.patch new file mode 100644 index 00000000..9ddda79d --- /dev/null +++ b/SOURCES/glibc-rh1418997.patch @@ -0,0 +1,51 @@ +commit 78b7adbaea643f2f213bb113e3ec933416a769a8 +Author: Joseph Myers +Date: Tue Oct 25 15:54:16 2016 +0000 + + Fix cmpli usage in power6 memset. + + Building glibc for powerpc64 with recent (2.27.51.20161012) binutils, + with multi-arch enabled, I get the error: + + ../sysdeps/powerpc/powerpc64/power6/memset.S: Assembler messages: + ../sysdeps/powerpc/powerpc64/power6/memset.S:254: Error: operand out of range (5 is not between 0 and 1) + ../sysdeps/powerpc/powerpc64/power6/memset.S:254: Error: operand out of range (128 is not between 0 and 31) + ../sysdeps/powerpc/powerpc64/power6/memset.S:254: Error: missing operand + + Indeed, cmpli is documented as a four-operand instruction, and looking + at nearby code it seems likely cmpldi was intended. This patch fixes + this powerpc64 code accordingly, and makes a corresponding change to + the powerpc32 code. + + Tested for powerpc, powerpc64 and powerpc64le by Tulio Magno Quites + Machado Filho + + * sysdeps/powerpc/powerpc32/power6/memset.S (memset): Use cmplwi + instead of cmpli. + * sysdeps/powerpc/powerpc64/power6/memset.S (memset): Use cmpldi + instead of cmpli. + +diff -rup a/sysdeps/powerpc/powerpc32/power6/memset.S b/sysdeps/powerpc/powerpc32/power6/memset.S +--- a/sysdeps/powerpc/powerpc32/power6/memset.S 2017-03-06 13:52:27.000000000 -0500 ++++ b/sysdeps/powerpc/powerpc32/power6/memset.S 2017-03-06 13:54:49.705201476 -0500 +@@ -396,7 +396,7 @@ L(cacheAlignedx): + /* A simple loop for the longer (>640 bytes) lengths. This form limits + the branch miss-predicted to exactly 1 at loop exit.*/ + L(cacheAligned512): +- cmpli cr1,rLEN,128 ++ cmplwi cr1,rLEN,128 + blt cr1,L(cacheAligned1) + dcbz 0,rMEMP + addi rLEN,rLEN,-128 +diff -rup a/sysdeps/powerpc/powerpc64/power6/memset.S b/sysdeps/powerpc/powerpc64/power6/memset.S +--- a/sysdeps/powerpc/powerpc64/power6/memset.S 2017-03-06 13:52:22.000000000 -0500 ++++ b/sysdeps/powerpc/powerpc64/power6/memset.S 2017-03-06 13:54:35.824216755 -0500 +@@ -269,7 +269,7 @@ L(cacheAlignedx): + /* A simple loop for the longer (>640 bytes) lengths. This form limits + the branch miss-predicted to exactly 1 at loop exit.*/ + L(cacheAligned512): +- cmpli cr1,rLEN,128 ++ cmpldi cr1,rLEN,128 + blt cr1,L(cacheAligned1) + dcbz 0,rMEMP + addi rLEN,rLEN,-128 diff --git a/SOURCES/glibc-rh1421155.patch b/SOURCES/glibc-rh1421155.patch new file mode 100644 index 00000000..2ca4f0cd --- /dev/null +++ b/SOURCES/glibc-rh1421155.patch @@ -0,0 +1,2278 @@ +Full backports of the following patches: + +commit b97eb2bdb1ed72982a7821c3078be591051cef59 +Author: H.J. Lu +Date: Mon Mar 16 14:58:43 2015 -0700 + + Preserve bound registers in _dl_runtime_resolve + + We need to add a BND prefix before indirect branch at the end of + _dl_runtime_resolve to preserve bound registers. + +commit ddd85a65b6e3d6ec1e756c1f78559f99a2c943ca +Author: H.J. Lu +Date: Tue Jul 7 05:23:24 2015 -0700 + + Add and use sysdeps/i386/link-defines.sym + + Define macros for fields in La_i86_regs and La_i86_retval and use them + in dl-trampoline.S, instead of hardcoded values. + +commit 14c5cbabc2d11004ab223ae5eae761ddf83ef99e +Author: Igor Zamyatin +Date: Thu Jul 9 06:50:12 2015 -0700 + + Preserve bound registers for pointer pass/return + + We need to save/restore bound registers and add a BND prefix before + branches in _dl_runtime_profile so that bound registers for pointer + pass and return are preserved when LD_AUDIT is used. + + +commit f3dcae82d54e5097e18e1d6ef4ff55c2ea4e621e +Author: H.J. Lu +Date: Tue Aug 25 04:33:54 2015 -0700 + + Save and restore vector registers in x86-64 ld.so + + This patch adds SSE, AVX and AVX512 versions of _dl_runtime_resolve + and _dl_runtime_profile, which save and restore the first 8 vector + registers used for parameter passing. elf_machine_runtime_setup + selects the proper _dl_runtime_resolve or _dl_runtime_profile based + on _dl_x86_cpu_features. It avoids race condition caused by + FOREIGN_CALL macros, which are only used for x86-64. + + Performance impact of saving and restoring 8 vector registers are + negligible on Nehalem, Sandy Bridge, Ivy Bridge and Haswell when + ld.so is optimized with SSE2. + +commit fb0f7a6755c1bfaec38f490fbfcaa39a66ee3604 +Author: H.J. Lu +Date: Tue Sep 6 08:50:55 2016 -0700 + + X86-64: Add _dl_runtime_resolve_avx[512]_{opt|slow} [BZ #20508] + + There is transition penalty when SSE instructions are mixed with 256-bit + AVX or 512-bit AVX512 load instructions. Since _dl_runtime_resolve_avx + and _dl_runtime_profile_avx512 save/restore 256-bit YMM/512-bit ZMM + registers, there is transition penalty when SSE instructions are used + with lazy binding on AVX and AVX512 processors. + + To avoid SSE transition penalty, if only the lower 128 bits of the first + 8 vector registers are non-zero, we can preserve %xmm0 - %xmm7 registers + with the zero upper bits. + + For AVX and AVX512 processors which support XGETBV with ECX == 1, we can + use XGETBV with ECX == 1 to check if the upper 128 bits of YMM registers + or the upper 256 bits of ZMM registers are zero. We can restore only the + non-zero portion of vector registers with AVX/AVX512 load instructions + which will zero-extend upper bits of vector registers. + + This patch adds _dl_runtime_resolve_sse_vex which saves and restores + XMM registers with 128-bit AVX store/load instructions. It is used to + preserve YMM/ZMM registers when only the lower 128 bits are non-zero. + _dl_runtime_resolve_avx_opt and _dl_runtime_resolve_avx512_opt are added + and used on AVX/AVX512 processors supporting XGETBV with ECX == 1 so + that we store and load only the non-zero portion of vector registers. + This avoids SSE transition penalty caused by _dl_runtime_resolve_avx and + _dl_runtime_profile_avx512 when only the lower 128 bits of vector + registers are used. + + _dl_runtime_resolve_avx_slow is added and used for AVX processors which + don't support XGETBV with ECX == 1. Since there is no SSE transition + penalty on AVX512 processors which don't support XGETBV with ECX == 1, + _dl_runtime_resolve_avx512_slow isn't provided. + +commit 3403a17fea8ccef7dc5f99553a13231acf838744 +Author: H.J. Lu +Date: Thu Feb 9 12:19:44 2017 -0800 + + x86-64: Verify that _dl_runtime_resolve preserves vector registers + + On x86-64, _dl_runtime_resolve must preserve the first 8 vector + registers. Add 3 _dl_runtime_resolve tests to verify that SSE, + AVX and AVX512 registers are preserved. + +commit c15f8eb50cea7ad1a4ccece6e0982bf426d52c00 +Author: H.J. Lu +Date: Tue Mar 21 10:59:31 2017 -0700 + + x86-64: Improve branch predication in _dl_runtime_resolve_avx512_opt [BZ #21258] + + On Skylake server, _dl_runtime_resolve_avx512_opt is used to preserve + the first 8 vector registers. The code layout is + + if only %xmm0 - %xmm7 registers are used + preserve %xmm0 - %xmm7 registers + if only %ymm0 - %ymm7 registers are used + preserve %ymm0 - %ymm7 registers + preserve %zmm0 - %zmm7 registers + + Branch predication always executes the fallthrough code path to preserve + %zmm0 - %zmm7 registers speculatively, even though only %xmm0 - %xmm7 + registers are used. This leads to lower CPU frequency on Skylake + server. This patch changes the fallthrough code path to preserve + %xmm0 - %xmm7 registers instead: + + if whole %zmm0 - %zmm7 registers are used + preserve %zmm0 - %zmm7 registers + if only %ymm0 - %ymm7 registers are used + preserve %ymm0 - %ymm7 registers + preserve %xmm0 - %xmm7 registers + + Tested on Skylake server. + + [BZ #21258] + * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_resolve_opt): + Define only if _dl_runtime_resolve is defined to + _dl_runtime_resolve_sse_vex. + * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve_opt): + Fallthrough to _dl_runtime_resolve_sse_vex. + +Index: glibc-2.17-c758a686/nptl/sysdeps/x86_64/tcb-offsets.sym +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/x86_64/tcb-offsets.sym ++++ glibc-2.17-c758a686/nptl/sysdeps/x86_64/tcb-offsets.sym +@@ -15,7 +15,6 @@ VGETCPU_CACHE_OFFSET offsetof (tcbhead_t + #ifndef __ASSUME_PRIVATE_FUTEX + PRIVATE_FUTEX offsetof (tcbhead_t, private_futex) + #endif +-RTLD_SAVESPACE_SSE offsetof (tcbhead_t, rtld_savespace_sse) + + -- Not strictly offsets, but these values are also used in the TCB. + TCB_CANCELSTATE_BITMASK CANCELSTATE_BITMASK +Index: glibc-2.17-c758a686/nptl/sysdeps/x86_64/tls.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/x86_64/tls.h ++++ glibc-2.17-c758a686/nptl/sysdeps/x86_64/tls.h +@@ -67,12 +67,13 @@ typedef struct + # else + int __unused1; + # endif +- int rtld_must_xmm_save; ++ int __glibc_unused1; + /* Reservation of some values for the TM ABI. */ + void *__private_tm[5]; + long int __unused2; +- /* Have space for the post-AVX register size. */ +- __128bits rtld_savespace_sse[8][4] __attribute__ ((aligned (32))); ++ /* Must be kept even if it is no longer used by glibc since programs, ++ like AddressSanitizer, depend on the size of tcbhead_t. */ ++ __128bits __glibc_unused2[8][4] __attribute__ ((aligned (32))); + + void *__padding[8]; + } tcbhead_t; +@@ -380,41 +381,6 @@ typedef struct + # define THREAD_GSCOPE_WAIT() \ + GL(dl_wait_lookup_done) () + +- +-# ifdef SHARED +-/* Defined in dl-trampoline.S. */ +-extern void _dl_x86_64_save_sse (void); +-extern void _dl_x86_64_restore_sse (void); +- +-# define RTLD_CHECK_FOREIGN_CALL \ +- (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) != 0) +- +-/* NB: Don't use the xchg operation because that would imply a lock +- prefix which is expensive and unnecessary. The cache line is also +- not contested at all. */ +-# define RTLD_ENABLE_FOREIGN_CALL \ +- int old_rtld_must_xmm_save = THREAD_GETMEM (THREAD_SELF, \ +- header.rtld_must_xmm_save); \ +- THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 1) +- +-# define RTLD_PREPARE_FOREIGN_CALL \ +- do if (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save)) \ +- { \ +- _dl_x86_64_save_sse (); \ +- THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, 0); \ +- } \ +- while (0) +- +-# define RTLD_FINALIZE_FOREIGN_CALL \ +- do { \ +- if (THREAD_GETMEM (THREAD_SELF, header.rtld_must_xmm_save) == 0) \ +- _dl_x86_64_restore_sse (); \ +- THREAD_SETMEM (THREAD_SELF, header.rtld_must_xmm_save, \ +- old_rtld_must_xmm_save); \ +- } while (0) +-# endif +- +- + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +Index: glibc-2.17-c758a686/sysdeps/i386/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/Makefile ++++ glibc-2.17-c758a686/sysdeps/i386/Makefile +@@ -33,6 +33,7 @@ sysdep-CFLAGS += -mpreferred-stack-bound + else + ifeq ($(subdir),csu) + sysdep-CFLAGS += -mpreferred-stack-boundary=4 ++gen-as-const-headers += link-defines.sym + else + # Likewise, any function which calls user callbacks + uses-callbacks += -mpreferred-stack-boundary=4 +Index: glibc-2.17-c758a686/sysdeps/i386/configure +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/configure ++++ glibc-2.17-c758a686/sysdeps/i386/configure +@@ -179,5 +179,32 @@ fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_novzeroupper" >&5 + $as_echo "$libc_cv_cc_novzeroupper" >&6; } + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Intel MPX support" >&5 ++$as_echo_n "checking for Intel MPX support... " >&6; } ++if ${libc_cv_asm_mpx+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.s <<\EOF ++ bndmov %bnd0,(%esp) ++EOF ++if { ac_try='${CC-cc} -c $ASFLAGS conftest.s 1>&5' ++ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; }; then ++ libc_cv_asm_mpx=yes ++else ++ libc_cv_asm_mpx=no ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_mpx" >&5 ++$as_echo "$libc_cv_asm_mpx" >&6; } ++if test $libc_cv_asm_mpx == yes; then ++ $as_echo "#define HAVE_MPX_SUPPORT 1" >>confdefs.h ++ ++fi ++ + $as_echo "#define PI_STATIC_AND_HIDDEN 1" >>confdefs.h + +Index: glibc-2.17-c758a686/sysdeps/i386/configure.in +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/configure.in ++++ glibc-2.17-c758a686/sysdeps/i386/configure.in +@@ -53,6 +53,21 @@ LIBC_TRY_CC_OPTION([-mno-vzeroupper], + [libc_cv_cc_novzeroupper=no]) + ]) + ++dnl Check whether asm supports Intel MPX ++AC_CACHE_CHECK(for Intel MPX support, libc_cv_asm_mpx, [dnl ++cat > conftest.s <<\EOF ++ bndmov %bnd0,(%esp) ++EOF ++if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then ++ libc_cv_asm_mpx=yes ++else ++ libc_cv_asm_mpx=no ++fi ++rm -f conftest*]) ++if test $libc_cv_asm_mpx == yes; then ++ AC_DEFINE(HAVE_MPX_SUPPORT) ++fi ++ + dnl It is always possible to access static and hidden symbols in an + dnl position independent way. + AC_DEFINE(PI_STATIC_AND_HIDDEN) +Index: glibc-2.17-c758a686/sysdeps/i386/dl-trampoline.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/dl-trampoline.S ++++ glibc-2.17-c758a686/sysdeps/i386/dl-trampoline.S +@@ -17,6 +17,13 @@ + . */ + + #include ++#include ++ ++#ifdef HAVE_MPX_SUPPORT ++# define PRESERVE_BND_REGS_PREFIX bnd ++#else ++# define PRESERVE_BND_REGS_PREFIX .byte 0xf2 ++#endif + + .text + .globl _dl_runtime_resolve +@@ -161,24 +168,47 @@ _dl_runtime_profile: + +4 free + %esp free + */ +- subl $20, %esp +- cfi_adjust_cfa_offset (20) +- movl %eax, (%esp) +- movl %edx, 4(%esp) +- fstpt 8(%esp) +- fstpt 20(%esp) ++#if LONG_DOUBLE_SIZE != 12 ++# error "long double size must be 12 bytes" ++#endif ++ # Allocate space for La_i86_retval and subtract 12 free bytes. ++ subl $(LRV_SIZE - 12), %esp ++ cfi_adjust_cfa_offset (LRV_SIZE - 12) ++ movl %eax, LRV_EAX_OFFSET(%esp) ++ movl %edx, LRV_EDX_OFFSET(%esp) ++ fstpt LRV_ST0_OFFSET(%esp) ++ fstpt LRV_ST1_OFFSET(%esp) ++#ifdef HAVE_MPX_SUPPORT ++ bndmov %bnd0, LRV_BND0_OFFSET(%esp) ++ bndmov %bnd1, LRV_BND1_OFFSET(%esp) ++#else ++ .byte 0x66,0x0f,0x1b,0x44,0x24,LRV_BND0_OFFSET ++ .byte 0x66,0x0f,0x1b,0x4c,0x24,LRV_BND1_OFFSET ++#endif + pushl %esp + cfi_adjust_cfa_offset (4) +- leal 36(%esp), %ecx +- movl 56(%esp), %eax +- movl 60(%esp), %edx ++ # Address of La_i86_regs area. ++ leal (LRV_SIZE + 4)(%esp), %ecx ++ # PLT2 ++ movl (LRV_SIZE + 4 + LR_SIZE)(%esp), %eax ++ # PLT1 ++ movl (LRV_SIZE + 4 + LR_SIZE + 4)(%esp), %edx + call _dl_call_pltexit +- movl (%esp), %eax +- movl 4(%esp), %edx +- fldt 20(%esp) +- fldt 8(%esp) +- addl $60, %esp +- cfi_adjust_cfa_offset (-60) ++ movl LRV_EAX_OFFSET(%esp), %eax ++ movl LRV_EDX_OFFSET(%esp), %edx ++ fldt LRV_ST1_OFFSET(%esp) ++ fldt LRV_ST0_OFFSET(%esp) ++#ifdef HAVE_MPX_SUPPORT ++ bndmov LRV_BND0_OFFSET(%esp), %bnd0 ++ bndmov LRV_BND1_OFFSET(%esp), %bnd1 ++#else ++ .byte 0x66,0x0f,0x1a,0x44,0x24,LRV_BND0_OFFSET ++ .byte 0x66,0x0f,0x1a,0x4c,0x24,LRV_BND1_OFFSET ++#endif ++ # Restore stack before return. ++ addl $(LRV_SIZE + 4 + LR_SIZE + 4), %esp ++ cfi_adjust_cfa_offset (-(LRV_SIZE + 4 + LR_SIZE + 4)) ++ PRESERVE_BND_REGS_PREFIX + ret + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile +Index: glibc-2.17-c758a686/sysdeps/i386/link-defines.sym +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/i386/link-defines.sym +@@ -0,0 +1,20 @@ ++#include "link.h" ++#include ++ ++-- ++LONG_DOUBLE_SIZE sizeof (long double) ++ ++LR_SIZE sizeof (struct La_i86_regs) ++LR_EDX_OFFSET offsetof (struct La_i86_regs, lr_edx) ++LR_ECX_OFFSET offsetof (struct La_i86_regs, lr_ecx) ++LR_EAX_OFFSET offsetof (struct La_i86_regs, lr_eax) ++LR_EBP_OFFSET offsetof (struct La_i86_regs, lr_ebp) ++LR_ESP_OFFSET offsetof (struct La_i86_regs, lr_esp) ++ ++LRV_SIZE sizeof (struct La_i86_retval) ++LRV_EAX_OFFSET offsetof (struct La_i86_retval, lrv_eax) ++LRV_EDX_OFFSET offsetof (struct La_i86_retval, lrv_edx) ++LRV_ST0_OFFSET offsetof (struct La_i86_retval, lrv_st0) ++LRV_ST1_OFFSET offsetof (struct La_i86_retval, lrv_st1) ++LRV_BND0_OFFSET offsetof (struct La_i86_retval, lrv_bnd0) ++LRV_BND1_OFFSET offsetof (struct La_i86_retval, lrv_bnd1) +Index: glibc-2.17-c758a686/sysdeps/x86/bits/link.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/bits/link.h ++++ glibc-2.17-c758a686/sysdeps/x86/bits/link.h +@@ -38,6 +38,8 @@ typedef struct La_i86_retval + uint32_t lrv_edx; + long double lrv_st0; + long double lrv_st1; ++ uint64_t lrv_bnd0; ++ uint64_t lrv_bnd1; + } La_i86_retval; + + +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.c ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +@@ -130,6 +130,20 @@ init_cpu_features (struct cpu_features * + break; + } + } ++ ++ /* To avoid SSE transition penalty, use _dl_runtime_resolve_slow. ++ If XGETBV suports ECX == 1, use _dl_runtime_resolve_opt. */ ++ cpu_features->feature[index_Use_dl_runtime_resolve_slow] ++ |= bit_Use_dl_runtime_resolve_slow; ++ if (cpu_features->max_cpuid >= 0xd) ++ { ++ unsigned int eax; ++ ++ __cpuid_count (0xd, 1, eax, ebx, ecx, edx); ++ if ((eax & (1 << 2)) != 0) ++ cpu_features->feature[index_Use_dl_runtime_resolve_opt] ++ |= bit_Use_dl_runtime_resolve_opt; ++ } + } + /* This spells out "AuthenticAMD". */ + else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.h ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +@@ -34,6 +34,9 @@ + #define bit_AVX512DQ_Usable (1 << 13) + #define bit_Prefer_MAP_32BIT_EXEC (1 << 16) + #define bit_Prefer_No_VZEROUPPER (1 << 17) ++#define bit_Use_dl_runtime_resolve_opt (1 << 20) ++#define bit_Use_dl_runtime_resolve_slow (1 << 21) ++ + + /* CPUID Feature flags. */ + +@@ -95,6 +98,9 @@ + # define index_AVX512DQ_Usable FEATURE_INDEX_1*FEATURE_SIZE + # define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1*FEATURE_SIZE + # define index_Prefer_No_VZEROUPPER FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Use_dl_runtime_resolve_opt FEATURE_INDEX_1*FEATURE_SIZE ++# define index_Use_dl_runtime_resolve_slow FEATURE_INDEX_1*FEATURE_SIZE ++ + + # if defined (_LIBC) && !IS_IN (nonlib) + # ifdef __x86_64__ +@@ -273,6 +279,8 @@ extern const struct cpu_features *__get_ + # define index_AVX512DQ_Usable FEATURE_INDEX_1 + # define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1 + # define index_Prefer_No_VZEROUPPER FEATURE_INDEX_1 ++# define index_Use_dl_runtime_resolve_opt FEATURE_INDEX_1 ++# define index_Use_dl_runtime_resolve_slow FEATURE_INDEX_1 + + #endif /* !__ASSEMBLER__ */ + +Index: glibc-2.17-c758a686/sysdeps/x86_64/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/Makefile ++++ glibc-2.17-c758a686/sysdeps/x86_64/Makefile +@@ -21,6 +21,11 @@ endif + ifeq ($(subdir),elf) + sysdep-dl-routines += tlsdesc dl-tlsdesc + ++tests += ifuncmain8 ++modules-names += ifuncmod8 ++ ++$(objpfx)ifuncmain8: $(objpfx)ifuncmod8.so ++ + tests += tst-quad1 tst-quad2 + modules-names += tst-quadmod1 tst-quadmod2 + +@@ -34,18 +39,32 @@ tests-pie += $(quad-pie-test) + $(objpfx)tst-quad1pie: $(objpfx)tst-quadmod1pie.o + $(objpfx)tst-quad2pie: $(objpfx)tst-quadmod2pie.o + ++tests += tst-sse tst-avx tst-avx512 ++test-extras += tst-avx-aux tst-avx512-aux ++extra-test-objs += tst-avx-aux.o tst-avx512-aux.o ++ + tests += tst-audit10 +-modules-names += tst-auditmod10a tst-auditmod10b ++modules-names += tst-auditmod10a tst-auditmod10b \ ++ tst-ssemod tst-avxmod tst-avx512mod + + $(objpfx)tst-audit10: $(objpfx)tst-auditmod10a.so + $(objpfx)tst-audit10.out: $(objpfx)tst-auditmod10b.so + tst-audit10-ENV = LD_AUDIT=$(objpfx)tst-auditmod10b.so + ++$(objpfx)tst-sse: $(objpfx)tst-ssemod.so ++$(objpfx)tst-avx: $(objpfx)tst-avx-aux.o $(objpfx)tst-avxmod.so ++$(objpfx)tst-avx512: $(objpfx)tst-avx512-aux.o $(objpfx)tst-avx512mod.so ++ ++CFLAGS-tst-avx-aux.c += $(AVX-CFLAGS) ++CFLAGS-tst-avxmod.c += $(AVX-CFLAGS) ++ + ifeq (yes,$(config-cflags-avx512)) + AVX512-CFLAGS = -mavx512f + CFLAGS-tst-audit10.c += $(AVX512-CFLAGS) + CFLAGS-tst-auditmod10a.c += $(AVX512-CFLAGS) + CFLAGS-tst-auditmod10b.c += $(AVX512-CFLAGS) ++CFLAGS-tst-avx512-aux.c += $(AVX512-CFLAGS) ++CFLAGS-tst-avx512mod.c += $(AVX512-CFLAGS) + endif + endif + +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-machine.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-machine.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-machine.h +@@ -66,8 +66,15 @@ static inline int __attribute__ ((unused + elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + { + Elf64_Addr *got; +- extern void _dl_runtime_resolve (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_profile (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_sse (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_avx (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_avx_slow (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_avx_opt (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_avx512 (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_avx512_opt (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden; + + if (l->l_info[DT_JMPREL] && lazy) + { +@@ -95,7 +102,12 @@ elf_machine_runtime_setup (struct link_m + end in this function. */ + if (__builtin_expect (profile, 0)) + { +- *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile; ++ if (HAS_ARCH_FEATURE (AVX512F_Usable)) ++ *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile_avx512; ++ else if (HAS_ARCH_FEATURE (AVX_Usable)) ++ *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile_avx; ++ else ++ *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_profile_sse; + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) +@@ -104,9 +116,34 @@ elf_machine_runtime_setup (struct link_m + GL(dl_profile_map) = l; + } + else +- /* This function will get called to fix up the GOT entry indicated by +- the offset on the stack, and then jump to the resolved address. */ +- *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve; ++ { ++ /* This function will get called to fix up the GOT entry ++ indicated by the offset on the stack, and then jump to ++ the resolved address. */ ++ if (HAS_ARCH_FEATURE (AVX512F_Usable)) ++ { ++ if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt)) ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_avx512_opt; ++ else ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_avx512; ++ } ++ else if (HAS_ARCH_FEATURE (AVX_Usable)) ++ { ++ if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt)) ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_avx_opt; ++ else if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_slow)) ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_avx_slow; ++ else ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_avx; ++ } ++ else ++ *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_sse; ++ } + } + + if (l->l_info[ADDRIDX (DT_TLSDESC_GOT)] && lazy) +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-trampoline.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S +@@ -18,28 +18,52 @@ + + #include + #include ++#include + #include + +-#if (RTLD_SAVESPACE_SSE % 32) != 0 +-# error RTLD_SAVESPACE_SSE must be aligned to 32 bytes ++#ifndef DL_STACK_ALIGNMENT ++/* Due to GCC bug: ++ ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 ++ ++ __tls_get_addr may be called with 8-byte stack alignment. Although ++ this bug has been fixed in GCC 4.9.4, 5.3 and 6, we can't assume ++ that stack will be always aligned at 16 bytes. We use unaligned ++ 16-byte move to load and store SSE registers, which has no penalty ++ on modern processors if stack is 16-byte aligned. */ ++# define DL_STACK_ALIGNMENT 8 + #endif + ++#ifndef DL_RUNIME_UNALIGNED_VEC_SIZE ++/* The maximum size of unaligned vector load and store. */ ++# define DL_RUNIME_UNALIGNED_VEC_SIZE 16 ++#endif ++ ++/* True if _dl_runtime_resolve should align stack to VEC_SIZE bytes. */ ++#define DL_RUNIME_RESOLVE_REALIGN_STACK \ ++ (VEC_SIZE > DL_STACK_ALIGNMENT \ ++ && VEC_SIZE > DL_RUNIME_UNALIGNED_VEC_SIZE) ++ ++/* Align vector register save area to 16 bytes. */ ++#define REGISTER_SAVE_VEC_OFF 0 ++ + /* Area on stack to save and restore registers used for parameter + passing when calling _dl_fixup. */ + #ifdef __ILP32__ +-/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX. */ +-# define REGISTER_SAVE_AREA (8 * 7) +-# define REGISTER_SAVE_RAX 0 ++# define REGISTER_SAVE_RAX (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8) ++# define PRESERVE_BND_REGS_PREFIX + #else +-/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as BND0, +- BND1, BND2, BND3. */ +-# define REGISTER_SAVE_AREA (8 * 7 + 16 * 4) + /* Align bound register save area to 16 bytes. */ +-# define REGISTER_SAVE_BND0 0 ++# define REGISTER_SAVE_BND0 (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8) + # define REGISTER_SAVE_BND1 (REGISTER_SAVE_BND0 + 16) + # define REGISTER_SAVE_BND2 (REGISTER_SAVE_BND1 + 16) + # define REGISTER_SAVE_BND3 (REGISTER_SAVE_BND2 + 16) + # define REGISTER_SAVE_RAX (REGISTER_SAVE_BND3 + 16) ++# ifdef HAVE_MPX_SUPPORT ++# define PRESERVE_BND_REGS_PREFIX bnd ++# else ++# define PRESERVE_BND_REGS_PREFIX .byte 0xf2 ++# endif + #endif + #define REGISTER_SAVE_RCX (REGISTER_SAVE_RAX + 8) + #define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8) +@@ -48,376 +72,71 @@ + #define REGISTER_SAVE_R8 (REGISTER_SAVE_RDI + 8) + #define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8) + +- .text +- .globl _dl_runtime_resolve +- .type _dl_runtime_resolve, @function +- .align 16 +- cfi_startproc +-_dl_runtime_resolve: +- cfi_adjust_cfa_offset(16) # Incorporate PLT +- subq $REGISTER_SAVE_AREA,%rsp +- cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) +- # Preserve registers otherwise clobbered. +- movq %rax, REGISTER_SAVE_RAX(%rsp) +- movq %rcx, REGISTER_SAVE_RCX(%rsp) +- movq %rdx, REGISTER_SAVE_RDX(%rsp) +- movq %rsi, REGISTER_SAVE_RSI(%rsp) +- movq %rdi, REGISTER_SAVE_RDI(%rsp) +- movq %r8, REGISTER_SAVE_R8(%rsp) +- movq %r9, REGISTER_SAVE_R9(%rsp) +-#ifndef __ILP32__ +- # We also have to preserve bound registers. These are nops if +- # Intel MPX isn't available or disabled. +-# ifdef HAVE_MPX_SUPPORT +- bndmov %bnd0, REGISTER_SAVE_BND0(%rsp) +- bndmov %bnd1, REGISTER_SAVE_BND1(%rsp) +- bndmov %bnd2, REGISTER_SAVE_BND2(%rsp) +- bndmov %bnd3, REGISTER_SAVE_BND3(%rsp) +-# else +- .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0 +- .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1 +- .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2 +- .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3 +-# endif +-#endif +- # Copy args pushed by PLT in register. +- # %rdi: link_map, %rsi: reloc_index +- movq (REGISTER_SAVE_AREA + 8)(%rsp), %rsi +- movq REGISTER_SAVE_AREA(%rsp), %rdi +- call _dl_fixup # Call resolver. +- movq %rax, %r11 # Save return value +-#ifndef __ILP32__ +- # Restore bound registers. These are nops if Intel MPX isn't +- # avaiable or disabled. +-# ifdef HAVE_MPX_SUPPORT +- bndmov REGISTER_SAVE_BND3(%rsp), %bnd3 +- bndmov REGISTER_SAVE_BND2(%rsp), %bnd2 +- bndmov REGISTER_SAVE_BND1(%rsp), %bnd1 +- bndmov REGISTER_SAVE_BND0(%rsp), %bnd0 +-# else +- .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3 +- .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2 +- .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1 +- .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0 +-# endif ++#define VEC_SIZE 64 ++#define VMOVA vmovdqa64 ++#if DL_RUNIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT ++# define VMOV vmovdqa64 ++#else ++# define VMOV vmovdqu64 + #endif +- # Get register content back. +- movq REGISTER_SAVE_R9(%rsp), %r9 +- movq REGISTER_SAVE_R8(%rsp), %r8 +- movq REGISTER_SAVE_RDI(%rsp), %rdi +- movq REGISTER_SAVE_RSI(%rsp), %rsi +- movq REGISTER_SAVE_RDX(%rsp), %rdx +- movq REGISTER_SAVE_RCX(%rsp), %rcx +- movq REGISTER_SAVE_RAX(%rsp), %rax +- # Adjust stack(PLT did 2 pushes) +- addq $(REGISTER_SAVE_AREA + 16), %rsp +- cfi_adjust_cfa_offset(-(REGISTER_SAVE_AREA + 16)) +- jmp *%r11 # Jump to function address. +- cfi_endproc +- .size _dl_runtime_resolve, .-_dl_runtime_resolve +- +- +-#ifndef PROF +- .globl _dl_runtime_profile +- .type _dl_runtime_profile, @function +- .align 16 +- cfi_startproc +- +-_dl_runtime_profile: +- cfi_adjust_cfa_offset(16) # Incorporate PLT +- /* The La_x86_64_regs data structure pointed to by the +- fourth paramater must be 16-byte aligned. This must +- be explicitly enforced. We have the set up a dynamically +- sized stack frame. %rbx points to the top half which +- has a fixed size and preserves the original stack pointer. */ +- +- subq $32, %rsp # Allocate the local storage. +- cfi_adjust_cfa_offset(32) +- movq %rbx, (%rsp) +- cfi_rel_offset(%rbx, 0) +- +- /* On the stack: +- 56(%rbx) parameter #1 +- 48(%rbx) return address +- +- 40(%rbx) reloc index +- 32(%rbx) link_map +- +- 24(%rbx) La_x86_64_regs pointer +- 16(%rbx) framesize +- 8(%rbx) rax +- (%rbx) rbx +- */ +- +- movq %rax, 8(%rsp) +- movq %rsp, %rbx +- cfi_def_cfa_register(%rbx) +- +- /* Actively align the La_x86_64_regs structure. */ +- andq $0xfffffffffffffff0, %rsp +-# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT +- /* sizeof(La_x86_64_regs). Need extra space for 8 SSE registers +- to detect if any xmm0-xmm7 registers are changed by audit +- module. */ +- subq $(LR_SIZE + XMM_SIZE*8), %rsp +-# else +- subq $LR_SIZE, %rsp # sizeof(La_x86_64_regs) +-# endif +- movq %rsp, 24(%rbx) +- +- /* Fill the La_x86_64_regs structure. */ +- movq %rdx, LR_RDX_OFFSET(%rsp) +- movq %r8, LR_R8_OFFSET(%rsp) +- movq %r9, LR_R9_OFFSET(%rsp) +- movq %rcx, LR_RCX_OFFSET(%rsp) +- movq %rsi, LR_RSI_OFFSET(%rsp) +- movq %rdi, LR_RDI_OFFSET(%rsp) +- movq %rbp, LR_RBP_OFFSET(%rsp) +- +- leaq 48(%rbx), %rax +- movq %rax, LR_RSP_OFFSET(%rsp) +- +- /* We always store the XMM registers even if AVX is available. +- This is to provide backward binary compatility for existing +- audit modules. */ +- movaps %xmm0, (LR_XMM_OFFSET)(%rsp) +- movaps %xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp) +- movaps %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp) +- movaps %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp) +- movaps %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp) +- movaps %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp) +- movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp) +- movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp) +- +-# ifndef __ILP32__ +-# ifdef HAVE_MPX_SUPPORT +- bndmov %bnd0, (LR_BND_OFFSET)(%rsp) # Preserve bound +- bndmov %bnd1, (LR_BND_OFFSET + BND_SIZE)(%rsp) # registers. Nops if +- bndmov %bnd2, (LR_BND_OFFSET + BND_SIZE*2)(%rsp) # MPX not available +- bndmov %bnd3, (LR_BND_OFFSET + BND_SIZE*3)(%rsp) # or disabled. +-# else +- .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET) +- .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE) +- .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET + BND_SIZE*2) +- .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3) +-# endif +-# endif +- +-# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT +- .data +-L(have_avx): +- .zero 4 +- .size L(have_avx), 4 +- .previous +- +- cmpl $0, L(have_avx)(%rip) +- jne L(defined) +- movq %rbx, %r11 # Save rbx +- movl $1, %eax +- cpuid +- movq %r11,%rbx # Restore rbx +- xorl %eax, %eax +- // AVX and XSAVE supported? +- andl $((1 << 28) | (1 << 27)), %ecx +- cmpl $((1 << 28) | (1 << 27)), %ecx +- jne 10f +-# ifdef HAVE_AVX512_ASM_SUPPORT +- // AVX512 supported in processor? +- movq %rbx, %r11 # Save rbx +- xorl %ecx, %ecx +- mov $0x7, %eax +- cpuid +- andl $(1 << 16), %ebx +-# endif +- xorl %ecx, %ecx +- // Get XFEATURE_ENABLED_MASK +- xgetbv +-# ifdef HAVE_AVX512_ASM_SUPPORT +- test %ebx, %ebx +- movq %r11, %rbx # Restore rbx +- je 20f +- // Verify that XCR0[7:5] = '111b' and +- // XCR0[2:1] = '11b' which means +- // that zmm state is enabled +- andl $0xe6, %eax +- cmpl $0xe6, %eax +- jne 20f +- movl %eax, L(have_avx)(%rip) +-L(avx512): +-# define RESTORE_AVX +-# define VMOV vmovdqu64 +-# define VEC(i) zmm##i +-# define MORE_CODE +-# include "dl-trampoline.h" +-# undef VMOV +-# undef VEC +-# undef RESTORE_AVX +-# endif +-20: andl $0x6, %eax +-10: subl $0x5, %eax +- movl %eax, L(have_avx)(%rip) +- cmpl $0, %eax +- +-L(defined): +- js L(no_avx) +-# ifdef HAVE_AVX512_ASM_SUPPORT +- cmpl $0xe6, L(have_avx)(%rip) +- je L(avx512) +-# endif +- +-# define RESTORE_AVX +-# define VMOV vmovdqu +-# define VEC(i) ymm##i +-# define MORE_CODE +-# include "dl-trampoline.h" +- +- .align 16 +-L(no_avx): +-# endif +- +-# undef RESTORE_AVX +-# include "dl-trampoline.h" +- +- cfi_endproc +- .size _dl_runtime_profile, .-_dl_runtime_profile ++#define VEC(i) zmm##i ++#define _dl_runtime_resolve _dl_runtime_resolve_avx512 ++#define _dl_runtime_profile _dl_runtime_profile_avx512 ++#define RESTORE_AVX ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef _dl_runtime_profile ++#undef VEC ++#undef VMOV ++#undef VMOVA ++#undef VEC_SIZE ++ ++#define VEC_SIZE 32 ++#define VMOVA vmovdqa ++#if DL_RUNIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT ++# define VMOV vmovdqa ++#else ++# define VMOV vmovdqu + #endif +- +- +-#ifdef SHARED +- .globl _dl_x86_64_save_sse +- .type _dl_x86_64_save_sse, @function +- .align 16 +- cfi_startproc +-_dl_x86_64_save_sse: +-# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT +- cmpl $0, L(have_avx)(%rip) +- jne L(defined_5) +- movq %rbx, %r11 # Save rbx +- movl $1, %eax +- cpuid +- movq %r11,%rbx # Restore rbx +- xorl %eax, %eax +- // AVX and XSAVE supported? +- andl $((1 << 28) | (1 << 27)), %ecx +- cmpl $((1 << 28) | (1 << 27)), %ecx +- jne 1f +-# ifdef HAVE_AVX512_ASM_SUPPORT +- // AVX512 supported in a processor? +- movq %rbx, %r11 # Save rbx +- xorl %ecx,%ecx +- mov $0x7,%eax +- cpuid +- andl $(1 << 16), %ebx +-# endif +- xorl %ecx, %ecx +- // Get XFEATURE_ENABLED_MASK +- xgetbv +-# ifdef HAVE_AVX512_ASM_SUPPORT +- test %ebx, %ebx +- movq %r11, %rbx # Restore rbx +- je 2f +- // Verify that XCR0[7:5] = '111b' and +- // XCR0[2:1] = '11b' which means +- // that zmm state is enabled +- andl $0xe6, %eax +- movl %eax, L(have_avx)(%rip) +- cmpl $0xe6, %eax +- je L(avx512_5) +-# endif +- +-2: andl $0x6, %eax +-1: subl $0x5, %eax +- movl %eax, L(have_avx)(%rip) +- cmpl $0, %eax +- +-L(defined_5): +- js L(no_avx5) +-# ifdef HAVE_AVX512_ASM_SUPPORT +- cmpl $0xe6, L(have_avx)(%rip) +- je L(avx512_5) +-# endif +- +- vmovdqa %ymm0, %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE +- vmovdqa %ymm1, %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE +- vmovdqa %ymm2, %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE +- vmovdqa %ymm3, %fs:RTLD_SAVESPACE_SSE+3*YMM_SIZE +- vmovdqa %ymm4, %fs:RTLD_SAVESPACE_SSE+4*YMM_SIZE +- vmovdqa %ymm5, %fs:RTLD_SAVESPACE_SSE+5*YMM_SIZE +- vmovdqa %ymm6, %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE +- vmovdqa %ymm7, %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE +- ret +-# ifdef HAVE_AVX512_ASM_SUPPORT +-L(avx512_5): +- vmovdqu64 %zmm0, %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE +- vmovdqu64 %zmm1, %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE +- vmovdqu64 %zmm2, %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE +- vmovdqu64 %zmm3, %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE +- vmovdqu64 %zmm4, %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE +- vmovdqu64 %zmm5, %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE +- vmovdqu64 %zmm6, %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE +- vmovdqu64 %zmm7, %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE +- ret +-# endif +-L(no_avx5): +-# endif +- movdqa %xmm0, %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE +- movdqa %xmm1, %fs:RTLD_SAVESPACE_SSE+1*XMM_SIZE +- movdqa %xmm2, %fs:RTLD_SAVESPACE_SSE+2*XMM_SIZE +- movdqa %xmm3, %fs:RTLD_SAVESPACE_SSE+3*XMM_SIZE +- movdqa %xmm4, %fs:RTLD_SAVESPACE_SSE+4*XMM_SIZE +- movdqa %xmm5, %fs:RTLD_SAVESPACE_SSE+5*XMM_SIZE +- movdqa %xmm6, %fs:RTLD_SAVESPACE_SSE+6*XMM_SIZE +- movdqa %xmm7, %fs:RTLD_SAVESPACE_SSE+7*XMM_SIZE +- ret +- cfi_endproc +- .size _dl_x86_64_save_sse, .-_dl_x86_64_save_sse +- +- +- .globl _dl_x86_64_restore_sse +- .type _dl_x86_64_restore_sse, @function +- .align 16 +- cfi_startproc +-_dl_x86_64_restore_sse: +-# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT +- cmpl $0, L(have_avx)(%rip) +- js L(no_avx6) +-# ifdef HAVE_AVX512_ASM_SUPPORT +- cmpl $0xe6, L(have_avx)(%rip) +- je L(avx512_6) +-# endif +- +- vmovdqa %fs:RTLD_SAVESPACE_SSE+0*YMM_SIZE, %ymm0 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+1*YMM_SIZE, %ymm1 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+2*YMM_SIZE, %ymm2 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+3*YMM_SIZE, %ymm3 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+4*YMM_SIZE, %ymm4 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+5*YMM_SIZE, %ymm5 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+6*YMM_SIZE, %ymm6 +- vmovdqa %fs:RTLD_SAVESPACE_SSE+7*YMM_SIZE, %ymm7 +- ret +-# ifdef HAVE_AVX512_ASM_SUPPORT +-L(avx512_6): +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+0*ZMM_SIZE, %zmm0 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+1*ZMM_SIZE, %zmm1 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+2*ZMM_SIZE, %zmm2 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+3*ZMM_SIZE, %zmm3 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+4*ZMM_SIZE, %zmm4 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+5*ZMM_SIZE, %zmm5 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+6*ZMM_SIZE, %zmm6 +- vmovdqu64 %fs:RTLD_SAVESPACE_SSE+7*ZMM_SIZE, %zmm7 +- ret +-# endif +-L(no_avx6): +-# endif +- movdqa %fs:RTLD_SAVESPACE_SSE+0*XMM_SIZE, %xmm0 +- movdqa %fs:RTLD_SAVESPACE_SSE+1*XMM_SIZE, %xmm1 +- movdqa %fs:RTLD_SAVESPACE_SSE+2*XMM_SIZE, %xmm2 +- movdqa %fs:RTLD_SAVESPACE_SSE+3*XMM_SIZE, %xmm3 +- movdqa %fs:RTLD_SAVESPACE_SSE+4*XMM_SIZE, %xmm4 +- movdqa %fs:RTLD_SAVESPACE_SSE+5*XMM_SIZE, %xmm5 +- movdqa %fs:RTLD_SAVESPACE_SSE+6*XMM_SIZE, %xmm6 +- movdqa %fs:RTLD_SAVESPACE_SSE+7*XMM_SIZE, %xmm7 +- ret +- cfi_endproc +- .size _dl_x86_64_restore_sse, .-_dl_x86_64_restore_sse ++#define VEC(i) ymm##i ++#define _dl_runtime_resolve _dl_runtime_resolve_avx ++#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx_opt ++#define _dl_runtime_profile _dl_runtime_profile_avx ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef _dl_runtime_resolve_opt ++#undef _dl_runtime_profile ++#undef VEC ++#undef VMOV ++#undef VMOVA ++#undef VEC_SIZE ++ ++/* movaps/movups is 1-byte shorter. */ ++#define VEC_SIZE 16 ++#define VMOVA movaps ++#if DL_RUNIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT ++# define VMOV movaps ++#else ++# define VMOV movups ++ #endif ++#define VEC(i) xmm##i ++#define _dl_runtime_resolve _dl_runtime_resolve_sse ++#define _dl_runtime_profile _dl_runtime_profile_sse ++#undef RESTORE_AVX ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef _dl_runtime_profile ++#undef VMOV ++#undef VMOVA ++ ++/* Used by _dl_runtime_resolve_avx_opt/_dl_runtime_resolve_avx512_opt ++ to preserve the full vector registers with zero upper bits. */ ++#define VMOVA vmovdqa ++#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT ++# define VMOV vmovdqa ++#else ++# define VMOV vmovdqu + #endif ++#define _dl_runtime_resolve _dl_runtime_resolve_sse_vex ++#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx512_opt ++#include "dl-trampoline.h" +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-trampoline.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h +@@ -1,6 +1,5 @@ +-/* Partial PLT profile trampoline to save and restore x86-64 vector +- registers. +- Copyright (C) 2009, 2011 Free Software Foundation, Inc. ++/* PLT trampolines. x86-64 version. ++ Copyright (C) 2009-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,16 +16,355 @@ + License along with the GNU C Library; if not, see + . */ + +-#ifdef RESTORE_AVX ++#undef REGISTER_SAVE_AREA_RAW ++#ifdef __ILP32__ ++/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as VEC0 to ++ VEC7. */ ++# define REGISTER_SAVE_AREA_RAW (8 * 7 + VEC_SIZE * 8) ++#else ++/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as ++ BND0, BND1, BND2, BND3 and VEC0 to VEC7. */ ++# define REGISTER_SAVE_AREA_RAW (8 * 7 + 16 * 4 + VEC_SIZE * 8) ++#endif ++ ++#undef REGISTER_SAVE_AREA ++#undef LOCAL_STORAGE_AREA ++#undef BASE ++#if DL_RUNIME_RESOLVE_REALIGN_STACK ++# define REGISTER_SAVE_AREA (REGISTER_SAVE_AREA_RAW + 8) ++/* Local stack area before jumping to function address: RBX. */ ++# define LOCAL_STORAGE_AREA 8 ++# define BASE rbx ++# if (REGISTER_SAVE_AREA % VEC_SIZE) != 0 ++# error REGISTER_SAVE_AREA must be multples of VEC_SIZE ++# endif ++#else ++# define REGISTER_SAVE_AREA REGISTER_SAVE_AREA_RAW ++/* Local stack area before jumping to function address: All saved ++ registers. */ ++# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA ++# define BASE rsp ++# if (REGISTER_SAVE_AREA % 16) != 8 ++# error REGISTER_SAVE_AREA must be odd multples of 8 ++# endif ++#endif ++ ++ .text ++#ifdef _dl_runtime_resolve_opt ++/* Use the smallest vector registers to preserve the full YMM/ZMM ++ registers to avoid SSE transition penalty. */ ++ ++# if VEC_SIZE == 32 ++/* Check if the upper 128 bits in %ymm0 - %ymm7 registers are non-zero ++ and preserve %xmm0 - %xmm7 registers with the zero upper bits. Since ++ there is no SSE transition penalty on AVX512 processors which don't ++ support XGETBV with ECX == 1, _dl_runtime_resolve_avx512_slow isn't ++ provided. */ ++ .globl _dl_runtime_resolve_avx_slow ++ .hidden _dl_runtime_resolve_avx_slow ++ .type _dl_runtime_resolve_avx_slow, @function ++ .align 16 ++_dl_runtime_resolve_avx_slow: ++ cfi_startproc ++ cfi_adjust_cfa_offset(16) # Incorporate PLT ++ vorpd %ymm0, %ymm1, %ymm8 ++ vorpd %ymm2, %ymm3, %ymm9 ++ vorpd %ymm4, %ymm5, %ymm10 ++ vorpd %ymm6, %ymm7, %ymm11 ++ vorpd %ymm8, %ymm9, %ymm9 ++ vorpd %ymm10, %ymm11, %ymm10 ++ vpcmpeqd %xmm8, %xmm8, %xmm8 ++ vorpd %ymm9, %ymm10, %ymm10 ++ vptest %ymm10, %ymm8 ++ # Preserve %ymm0 - %ymm7 registers if the upper 128 bits of any ++ # %ymm0 - %ymm7 registers aren't zero. ++ PRESERVE_BND_REGS_PREFIX ++ jnc _dl_runtime_resolve_avx ++ # Use vzeroupper to avoid SSE transition penalty. ++ vzeroupper ++ # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits ++ # when the upper 128 bits of %ymm0 - %ymm7 registers are zero. ++ PRESERVE_BND_REGS_PREFIX ++ jmp _dl_runtime_resolve_sse_vex ++ cfi_adjust_cfa_offset(-16) # Restore PLT adjustment ++ cfi_endproc ++ .size _dl_runtime_resolve_avx_slow, .-_dl_runtime_resolve_avx_slow ++# endif ++ ++/* Use XGETBV with ECX == 1 to check which bits in vector registers are ++ non-zero and only preserve the non-zero lower bits with zero upper ++ bits. */ ++ .globl _dl_runtime_resolve_opt ++ .hidden _dl_runtime_resolve_opt ++ .type _dl_runtime_resolve_opt, @function ++ .align 16 ++_dl_runtime_resolve_opt: ++ cfi_startproc ++ cfi_adjust_cfa_offset(16) # Incorporate PLT ++ pushq %rax ++ cfi_adjust_cfa_offset(8) ++ cfi_rel_offset(%rax, 0) ++ pushq %rcx ++ cfi_adjust_cfa_offset(8) ++ cfi_rel_offset(%rcx, 0) ++ pushq %rdx ++ cfi_adjust_cfa_offset(8) ++ cfi_rel_offset(%rdx, 0) ++ movl $1, %ecx ++ xgetbv ++ movl %eax, %r11d ++ popq %rdx ++ cfi_adjust_cfa_offset(-8) ++ cfi_restore (%rdx) ++ popq %rcx ++ cfi_adjust_cfa_offset(-8) ++ cfi_restore (%rcx) ++ popq %rax ++ cfi_adjust_cfa_offset(-8) ++ cfi_restore (%rax) ++# if VEC_SIZE == 32 ++ # For YMM registers, check if YMM state is in use. ++ andl $bit_YMM_state, %r11d ++ # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits if ++ # YMM state isn't in use. ++ PRESERVE_BND_REGS_PREFIX ++ jz _dl_runtime_resolve_sse_vex ++# elif VEC_SIZE == 16 ++ # For ZMM registers, check if YMM state and ZMM state are in ++ # use. ++ andl $(bit_YMM_state | bit_ZMM0_15_state), %r11d ++ cmpl $bit_YMM_state, %r11d ++ # Preserve %zmm0 - %zmm7 registers if ZMM state is in use. ++ PRESERVE_BND_REGS_PREFIX ++ jg _dl_runtime_resolve_avx512 ++ # Preserve %ymm0 - %ymm7 registers with the zero upper 256 bits if ++ # ZMM state isn't in use. ++ PRESERVE_BND_REGS_PREFIX ++ je _dl_runtime_resolve_avx ++ # Preserve %xmm0 - %xmm7 registers with the zero upper 384 bits if ++ # neither YMM state nor ZMM state are in use. ++# else ++# error Unsupported VEC_SIZE! ++# endif ++ cfi_adjust_cfa_offset(-16) # Restore PLT adjustment ++ cfi_endproc ++ .size _dl_runtime_resolve_opt, .-_dl_runtime_resolve_opt ++#endif ++ .globl _dl_runtime_resolve ++ .hidden _dl_runtime_resolve ++ .type _dl_runtime_resolve, @function ++ .align 16 ++ cfi_startproc ++_dl_runtime_resolve: ++ cfi_adjust_cfa_offset(16) # Incorporate PLT ++#if DL_RUNIME_RESOLVE_REALIGN_STACK ++# if LOCAL_STORAGE_AREA != 8 ++# error LOCAL_STORAGE_AREA must be 8 ++# endif ++ pushq %rbx # push subtracts stack by 8. ++ cfi_adjust_cfa_offset(8) ++ cfi_rel_offset(%rbx, 0) ++ mov %RSP_LP, %RBX_LP ++ cfi_def_cfa_register(%rbx) ++ and $-VEC_SIZE, %RSP_LP ++#endif ++ sub $REGISTER_SAVE_AREA, %RSP_LP ++ cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) ++ # Preserve registers otherwise clobbered. ++ movq %rax, REGISTER_SAVE_RAX(%rsp) ++ movq %rcx, REGISTER_SAVE_RCX(%rsp) ++ movq %rdx, REGISTER_SAVE_RDX(%rsp) ++ movq %rsi, REGISTER_SAVE_RSI(%rsp) ++ movq %rdi, REGISTER_SAVE_RDI(%rsp) ++ movq %r8, REGISTER_SAVE_R8(%rsp) ++ movq %r9, REGISTER_SAVE_R9(%rsp) ++ VMOV %VEC(0), (REGISTER_SAVE_VEC_OFF)(%rsp) ++ VMOV %VEC(1), (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp) ++ VMOV %VEC(2), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp) ++ VMOV %VEC(3), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp) ++ VMOV %VEC(4), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp) ++ VMOV %VEC(5), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp) ++ VMOV %VEC(6), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp) ++ VMOV %VEC(7), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp) ++#ifndef __ILP32__ ++ # We also have to preserve bound registers. These are nops if ++ # Intel MPX isn't available or disabled. ++# ifdef HAVE_MPX_SUPPORT ++ bndmov %bnd0, REGISTER_SAVE_BND0(%rsp) ++ bndmov %bnd1, REGISTER_SAVE_BND1(%rsp) ++ bndmov %bnd2, REGISTER_SAVE_BND2(%rsp) ++ bndmov %bnd3, REGISTER_SAVE_BND3(%rsp) ++# else ++# if REGISTER_SAVE_BND0 == 0 ++ .byte 0x66,0x0f,0x1b,0x04,0x24 ++# else ++ .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0 ++# endif ++ .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1 ++ .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2 ++ .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3 ++# endif ++#endif ++ # Copy args pushed by PLT in register. ++ # %rdi: link_map, %rsi: reloc_index ++ mov (LOCAL_STORAGE_AREA + 8)(%BASE), %RSI_LP ++ mov LOCAL_STORAGE_AREA(%BASE), %RDI_LP ++ call _dl_fixup # Call resolver. ++ mov %RAX_LP, %R11_LP # Save return value ++#ifndef __ILP32__ ++ # Restore bound registers. These are nops if Intel MPX isn't ++ # avaiable or disabled. ++# ifdef HAVE_MPX_SUPPORT ++ bndmov REGISTER_SAVE_BND3(%rsp), %bnd3 ++ bndmov REGISTER_SAVE_BND2(%rsp), %bnd2 ++ bndmov REGISTER_SAVE_BND1(%rsp), %bnd1 ++ bndmov REGISTER_SAVE_BND0(%rsp), %bnd0 ++# else ++ .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3 ++ .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2 ++ .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1 ++# if REGISTER_SAVE_BND0 == 0 ++ .byte 0x66,0x0f,0x1a,0x04,0x24 ++# else ++ .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0 ++# endif ++# endif ++#endif ++ # Get register content back. ++ movq REGISTER_SAVE_R9(%rsp), %r9 ++ movq REGISTER_SAVE_R8(%rsp), %r8 ++ movq REGISTER_SAVE_RDI(%rsp), %rdi ++ movq REGISTER_SAVE_RSI(%rsp), %rsi ++ movq REGISTER_SAVE_RDX(%rsp), %rdx ++ movq REGISTER_SAVE_RCX(%rsp), %rcx ++ movq REGISTER_SAVE_RAX(%rsp), %rax ++ VMOV (REGISTER_SAVE_VEC_OFF)(%rsp), %VEC(0) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp), %VEC(1) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp), %VEC(2) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp), %VEC(3) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp), %VEC(4) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp), %VEC(5) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp), %VEC(6) ++ VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp), %VEC(7) ++#if DL_RUNIME_RESOLVE_REALIGN_STACK ++ mov %RBX_LP, %RSP_LP ++ cfi_def_cfa_register(%rsp) ++ movq (%rsp), %rbx ++ cfi_restore(%rbx) ++#endif ++ # Adjust stack(PLT did 2 pushes) ++ add $(LOCAL_STORAGE_AREA + 16), %RSP_LP ++ cfi_adjust_cfa_offset(-(LOCAL_STORAGE_AREA + 16)) ++ # Preserve bound registers. ++ PRESERVE_BND_REGS_PREFIX ++ jmp *%r11 # Jump to function address. ++ cfi_endproc ++ .size _dl_runtime_resolve, .-_dl_runtime_resolve ++ ++ ++/* To preserve %xmm0 - %xmm7 registers, dl-trampoline.h is included ++ twice, for _dl_runtime_resolve_sse and _dl_runtime_resolve_sse_vex. ++ But we don't need another _dl_runtime_profile for XMM registers. */ ++#if !defined PROF && defined _dl_runtime_profile ++# if (LR_VECTOR_OFFSET % VEC_SIZE) != 0 ++# error LR_VECTOR_OFFSET must be multples of VEC_SIZE ++# endif ++ ++ .globl _dl_runtime_profile ++ .hidden _dl_runtime_profile ++ .type _dl_runtime_profile, @function ++ .align 16 ++_dl_runtime_profile: ++ cfi_startproc ++ cfi_adjust_cfa_offset(16) # Incorporate PLT ++ /* The La_x86_64_regs data structure pointed to by the ++ fourth paramater must be VEC_SIZE-byte aligned. This must ++ be explicitly enforced. We have the set up a dynamically ++ sized stack frame. %rbx points to the top half which ++ has a fixed size and preserves the original stack pointer. */ ++ ++ sub $32, %RSP_LP # Allocate the local storage. ++ cfi_adjust_cfa_offset(32) ++ movq %rbx, (%rsp) ++ cfi_rel_offset(%rbx, 0) ++ ++ /* On the stack: ++ 56(%rbx) parameter #1 ++ 48(%rbx) return address ++ ++ 40(%rbx) reloc index ++ 32(%rbx) link_map ++ ++ 24(%rbx) La_x86_64_regs pointer ++ 16(%rbx) framesize ++ 8(%rbx) rax ++ (%rbx) rbx ++ */ ++ ++ movq %rax, 8(%rsp) ++ mov %RSP_LP, %RBX_LP ++ cfi_def_cfa_register(%rbx) ++ ++ /* Actively align the La_x86_64_regs structure. */ ++ and $-VEC_SIZE, %RSP_LP ++# if defined HAVE_AVX_SUPPORT || defined HAVE_AVX512_ASM_SUPPORT ++ /* sizeof(La_x86_64_regs). Need extra space for 8 SSE registers ++ to detect if any xmm0-xmm7 registers are changed by audit ++ module. */ ++ sub $(LR_SIZE + XMM_SIZE*8), %RSP_LP ++# else ++ sub $LR_SIZE, %RSP_LP # sizeof(La_x86_64_regs) ++# endif ++ movq %rsp, 24(%rbx) ++ ++ /* Fill the La_x86_64_regs structure. */ ++ movq %rdx, LR_RDX_OFFSET(%rsp) ++ movq %r8, LR_R8_OFFSET(%rsp) ++ movq %r9, LR_R9_OFFSET(%rsp) ++ movq %rcx, LR_RCX_OFFSET(%rsp) ++ movq %rsi, LR_RSI_OFFSET(%rsp) ++ movq %rdi, LR_RDI_OFFSET(%rsp) ++ movq %rbp, LR_RBP_OFFSET(%rsp) ++ ++ lea 48(%rbx), %RAX_LP ++ movq %rax, LR_RSP_OFFSET(%rsp) ++ ++ /* We always store the XMM registers even if AVX is available. ++ This is to provide backward binary compatibility for existing ++ audit modules. */ ++ movaps %xmm0, (LR_XMM_OFFSET)(%rsp) ++ movaps %xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp) ++ movaps %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp) ++ movaps %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp) ++ movaps %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp) ++ movaps %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp) ++ movaps %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp) ++ movaps %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp) ++ ++# ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov %bnd0, (LR_BND_OFFSET)(%rsp) # Preserve bound ++ bndmov %bnd1, (LR_BND_OFFSET + BND_SIZE)(%rsp) # registers. Nops if ++ bndmov %bnd2, (LR_BND_OFFSET + BND_SIZE*2)(%rsp) # MPX not available ++ bndmov %bnd3, (LR_BND_OFFSET + BND_SIZE*3)(%rsp) # or disabled. ++# else ++ .byte 0x66,0x0f,0x1b,0x84,0x24;.long (LR_BND_OFFSET) ++ .byte 0x66,0x0f,0x1b,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE) ++ .byte 0x66,0x0f,0x1b,0x94,0x24;.long (LR_BND_OFFSET + BND_SIZE*2) ++ .byte 0x66,0x0f,0x1b,0x9c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3) ++# endif ++# endif ++ ++# ifdef RESTORE_AVX + /* This is to support AVX audit modules. */ +- VMOV %VEC(0), (LR_VECTOR_OFFSET)(%rsp) +- VMOV %VEC(1), (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp) +- VMOV %VEC(2), (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp) +- VMOV %VEC(3), (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp) +- VMOV %VEC(4), (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp) +- VMOV %VEC(5), (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp) +- VMOV %VEC(6), (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp) +- VMOV %VEC(7), (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp) ++ VMOVA %VEC(0), (LR_VECTOR_OFFSET)(%rsp) ++ VMOVA %VEC(1), (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp) ++ VMOVA %VEC(2), (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp) ++ VMOVA %VEC(3), (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp) ++ VMOVA %VEC(4), (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp) ++ VMOVA %VEC(5), (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp) ++ VMOVA %VEC(6), (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp) ++ VMOVA %VEC(7), (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp) + + /* Save xmm0-xmm7 registers to detect if any of them are + changed by audit module. */ +@@ -38,7 +376,7 @@ + vmovdqa %xmm5, (LR_SIZE + XMM_SIZE*5)(%rsp) + vmovdqa %xmm6, (LR_SIZE + XMM_SIZE*6)(%rsp) + vmovdqa %xmm7, (LR_SIZE + XMM_SIZE*7)(%rsp) +-#endif ++# endif + + mov %RSP_LP, %RCX_LP # La_x86_64_regs pointer to %rcx. + mov 48(%rbx), %RDX_LP # Load return address if needed. +@@ -63,21 +401,7 @@ + movaps (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp), %xmm6 + movaps (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp), %xmm7 + +-#ifndef __ILP32__ +-# ifdef HAVE_MPX_SUPPORT +- bndmov (LR_BND_OFFSET)(%rsp), %bnd0 # Restore bound +- bndmov (LR_BND_OFFSET + BND_SIZE)(%rsp), %bnd1 # registers. +- bndmov (LR_BND_OFFSET + BND_SIZE*2)(%rsp), %bnd2 +- bndmov (LR_BND_OFFSET + BND_SIZE*3)(%rsp), %bnd3 +-# else +- .byte 0x66,0x0f,0x1a,0x84,0x24;.long (LR_BND_OFFSET) +- .byte 0x66,0x0f,0x1a,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE) +- .byte 0x66,0x0f,0x1a,0x94,0x24;.long (LR_BND_OFFSET + BND_SIZE*2) +- .byte 0x66,0x0f,0x1a,0x9c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3) +-# endif +-#endif +- +-#ifdef RESTORE_AVX ++# ifdef RESTORE_AVX + /* Check if any xmm0-xmm7 registers are changed by audit + module. */ + vpcmpeqq (LR_SIZE)(%rsp), %xmm0, %xmm8 +@@ -86,7 +410,7 @@ + je 2f + vmovdqa %xmm0, (LR_VECTOR_OFFSET)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET)(%rsp), %VEC(0) ++2: VMOVA (LR_VECTOR_OFFSET)(%rsp), %VEC(0) + vmovdqa %xmm0, (LR_XMM_OFFSET)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm8 +@@ -95,7 +419,7 @@ + je 2f + vmovdqa %xmm1, (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %VEC(1) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE)(%rsp), %VEC(1) + vmovdqa %xmm1, (LR_XMM_OFFSET + XMM_SIZE)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*2)(%rsp), %xmm2, %xmm8 +@@ -104,7 +428,7 @@ + je 2f + vmovdqa %xmm2, (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %VEC(2) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE*2)(%rsp), %VEC(2) + vmovdqa %xmm2, (LR_XMM_OFFSET + XMM_SIZE*2)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*3)(%rsp), %xmm3, %xmm8 +@@ -113,7 +437,7 @@ + je 2f + vmovdqa %xmm3, (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %VEC(3) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE*3)(%rsp), %VEC(3) + vmovdqa %xmm3, (LR_XMM_OFFSET + XMM_SIZE*3)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*4)(%rsp), %xmm4, %xmm8 +@@ -122,7 +446,7 @@ + je 2f + vmovdqa %xmm4, (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %VEC(4) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE*4)(%rsp), %VEC(4) + vmovdqa %xmm4, (LR_XMM_OFFSET + XMM_SIZE*4)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*5)(%rsp), %xmm5, %xmm8 +@@ -131,7 +455,7 @@ + je 2f + vmovdqa %xmm5, (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %VEC(5) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE*5)(%rsp), %VEC(5) + vmovdqa %xmm5, (LR_XMM_OFFSET + XMM_SIZE*5)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*6)(%rsp), %xmm6, %xmm8 +@@ -140,7 +464,7 @@ + je 2f + vmovdqa %xmm6, (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %VEC(6) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE*6)(%rsp), %VEC(6) + vmovdqa %xmm6, (LR_XMM_OFFSET + XMM_SIZE*6)(%rsp) + + 1: vpcmpeqq (LR_SIZE + XMM_SIZE*7)(%rsp), %xmm7, %xmm8 +@@ -149,13 +473,29 @@ + je 2f + vmovdqa %xmm7, (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp) + jmp 1f +-2: VMOV (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %VEC(7) ++2: VMOVA (LR_VECTOR_OFFSET + VECTOR_SIZE*7)(%rsp), %VEC(7) + vmovdqa %xmm7, (LR_XMM_OFFSET + XMM_SIZE*7)(%rsp) + + 1: +-#endif ++# endif ++ ++# ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov (LR_BND_OFFSET)(%rsp), %bnd0 # Restore bound ++ bndmov (LR_BND_OFFSET + BND_SIZE)(%rsp), %bnd1 # registers. ++ bndmov (LR_BND_OFFSET + BND_SIZE*2)(%rsp), %bnd2 ++ bndmov (LR_BND_OFFSET + BND_SIZE*3)(%rsp), %bnd3 ++# else ++ .byte 0x66,0x0f,0x1a,0x84,0x24;.long (LR_BND_OFFSET) ++ .byte 0x66,0x0f,0x1a,0x8c,0x24;.long (LR_BND_OFFSET + BND_SIZE) ++ .byte 0x66,0x0f,0x1a,0x94,0x24;.long (LR_BND_OFFSET + BND_SIZE*2) ++ .byte 0x66,0x0f,0x1a,0x9c,0x24;.long (LR_BND_OFFSET + BND_SIZE*3) ++# endif ++# endif ++ + mov 16(%rbx), %R10_LP # Anything in framesize? + test %R10_LP, %R10_LP ++ PRESERVE_BND_REGS_PREFIX + jns 3f + + /* There's nothing in the frame size, so there +@@ -166,14 +506,15 @@ + movq LR_RSI_OFFSET(%rsp), %rsi + movq LR_RDI_OFFSET(%rsp), %rdi + +- movq %rbx, %rsp ++ mov %RBX_LP, %RSP_LP + movq (%rsp), %rbx +- cfi_restore(rbx) ++ cfi_restore(%rbx) + cfi_def_cfa_register(%rsp) + +- addq $48, %rsp # Adjust the stack to the return value ++ add $48, %RSP_LP # Adjust the stack to the return value + # (eats the reloc index and link_map) + cfi_adjust_cfa_offset(-48) ++ PRESERVE_BND_REGS_PREFIX + jmp *%r11 # Jump to function address. + + 3: +@@ -186,13 +527,13 @@ + temporary buffer of the size specified by the 'framesize' + returned from _dl_profile_fixup */ + +- leaq LR_RSP_OFFSET(%rbx), %rsi # stack +- addq $8, %r10 +- andq $0xfffffffffffffff0, %r10 +- movq %r10, %rcx +- subq %r10, %rsp +- movq %rsp, %rdi +- shrq $3, %rcx ++ lea LR_RSP_OFFSET(%rbx), %RSI_LP # stack ++ add $8, %R10_LP ++ and $-16, %R10_LP ++ mov %R10_LP, %RCX_LP ++ sub %R10_LP, %RSP_LP ++ mov %RSP_LP, %RDI_LP ++ shr $3, %RCX_LP + rep + movsq + +@@ -200,23 +541,24 @@ + movq 32(%rdi), %rsi + movq 40(%rdi), %rdi + ++ PRESERVE_BND_REGS_PREFIX + call *%r11 + +- mov 24(%rbx), %rsp # Drop the copied stack content ++ mov 24(%rbx), %RSP_LP # Drop the copied stack content + + /* Now we have to prepare the La_x86_64_retval structure for the + _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now, + so we just need to allocate the sizeof(La_x86_64_retval) space on + the stack, since the alignment has already been taken care of. */ +-#ifdef RESTORE_AVX ++# ifdef RESTORE_AVX + /* sizeof(La_x86_64_retval). Need extra space for 2 SSE + registers to detect if xmm0/xmm1 registers are changed + by audit module. */ +- subq $(LRV_SIZE + XMM_SIZE*2), %rsp +-#else +- subq $LRV_SIZE, %rsp # sizeof(La_x86_64_retval) +-#endif +- movq %rsp, %rcx # La_x86_64_retval argument to %rcx. ++ sub $(LRV_SIZE + XMM_SIZE*2), %RSP_LP ++# else ++ sub $LRV_SIZE, %RSP_LP # sizeof(La_x86_64_retval) ++# endif ++ mov %RSP_LP, %RCX_LP # La_x86_64_retval argument to %rcx. + + /* Fill in the La_x86_64_retval structure. */ + movq %rax, LRV_RAX_OFFSET(%rcx) +@@ -225,26 +567,26 @@ + movaps %xmm0, LRV_XMM0_OFFSET(%rcx) + movaps %xmm1, LRV_XMM1_OFFSET(%rcx) + +-#ifdef RESTORE_AVX ++# ifdef RESTORE_AVX + /* This is to support AVX audit modules. */ +- VMOV %VEC(0), LRV_VECTOR0_OFFSET(%rcx) +- VMOV %VEC(1), LRV_VECTOR1_OFFSET(%rcx) ++ VMOVA %VEC(0), LRV_VECTOR0_OFFSET(%rcx) ++ VMOVA %VEC(1), LRV_VECTOR1_OFFSET(%rcx) + + /* Save xmm0/xmm1 registers to detect if they are changed + by audit module. */ + vmovdqa %xmm0, (LRV_SIZE)(%rcx) + vmovdqa %xmm1, (LRV_SIZE + XMM_SIZE)(%rcx) +-#endif ++# endif + +-#ifndef __ILP32__ +-# ifdef HAVE_MPX_SUPPORT ++# ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT + bndmov %bnd0, LRV_BND0_OFFSET(%rcx) # Preserve returned bounds. + bndmov %bnd1, LRV_BND1_OFFSET(%rcx) +-# else ++# else + .byte 0x66,0x0f,0x1b,0x81;.long (LRV_BND0_OFFSET) + .byte 0x66,0x0f,0x1b,0x89;.long (LRV_BND1_OFFSET) ++# endif + # endif +-#endif + + fstpt LRV_ST0_OFFSET(%rcx) + fstpt LRV_ST1_OFFSET(%rcx) +@@ -261,49 +603,47 @@ + movaps LRV_XMM0_OFFSET(%rsp), %xmm0 + movaps LRV_XMM1_OFFSET(%rsp), %xmm1 + +-#ifdef RESTORE_AVX ++# ifdef RESTORE_AVX + /* Check if xmm0/xmm1 registers are changed by audit module. */ + vpcmpeqq (LRV_SIZE)(%rsp), %xmm0, %xmm2 + vpmovmskb %xmm2, %esi + cmpl $0xffff, %esi + jne 1f +- VMOV LRV_VECTOR0_OFFSET(%rsp), %VEC(0) ++ VMOVA LRV_VECTOR0_OFFSET(%rsp), %VEC(0) + + 1: vpcmpeqq (LRV_SIZE + XMM_SIZE)(%rsp), %xmm1, %xmm2 + vpmovmskb %xmm2, %esi + cmpl $0xffff, %esi + jne 1f +- VMOV LRV_VECTOR1_OFFSET(%rsp), %VEC(1) ++ VMOVA LRV_VECTOR1_OFFSET(%rsp), %VEC(1) + + 1: +-#endif ++# endif + +-#ifndef __ILP32__ +-# ifdef HAVE_MPX_SUPPORT +- bndmov LRV_BND0_OFFSET(%rcx), %bnd0 # Restore bound registers. +- bndmov LRV_BND1_OFFSET(%rcx), %bnd1 +-# else +- .byte 0x66,0x0f,0x1a,0x81;.long (LRV_BND0_OFFSET) +- .byte 0x66,0x0f,0x1a,0x89;.long (LRV_BND1_OFFSET) ++# ifndef __ILP32__ ++# ifdef HAVE_MPX_SUPPORT ++ bndmov LRV_BND0_OFFSET(%rsp), %bnd0 # Restore bound registers. ++ bndmov LRV_BND1_OFFSET(%rsp), %bnd1 ++# else ++ .byte 0x66,0x0f,0x1a,0x84,0x24;.long (LRV_BND0_OFFSET) ++ .byte 0x66,0x0f,0x1a,0x8c,0x24;.long (LRV_BND1_OFFSET) ++# endif + # endif +-#endif + + fldt LRV_ST1_OFFSET(%rsp) + fldt LRV_ST0_OFFSET(%rsp) + +- movq %rbx, %rsp ++ mov %RBX_LP, %RSP_LP + movq (%rsp), %rbx +- cfi_restore(rbx) ++ cfi_restore(%rbx) + cfi_def_cfa_register(%rsp) + +- addq $48, %rsp # Adjust the stack to the return value ++ add $48, %RSP_LP # Adjust the stack to the return value + # (eats the reloc index and link_map) + cfi_adjust_cfa_offset(-48) ++ PRESERVE_BND_REGS_PREFIX + retq + +-#ifdef MORE_CODE +- cfi_adjust_cfa_offset(48) +- cfi_rel_offset(%rbx, 0) +- cfi_def_cfa_register(%rbx) +-# undef MORE_CODE ++ cfi_endproc ++ .size _dl_runtime_profile, .-_dl_runtime_profile + #endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/ifuncmain8.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/ifuncmain8.c +@@ -0,0 +1,32 @@ ++/* Test IFUNC selector with floating-point parameters. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++extern float foo (float); ++ ++static int ++do_test (void) ++{ ++ if (foo (2) != 3) ++ abort (); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +Index: glibc-2.17-c758a686/sysdeps/x86_64/ifuncmod8.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/ifuncmod8.c +@@ -0,0 +1,36 @@ ++/* Test IFUNC selector with floating-point parameters. ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++void * foo_ifunc (void) __asm__ ("foo"); ++__asm__(".type foo, %gnu_indirect_function"); ++ ++static float ++foo_impl (float x) ++{ ++ return x + 1; ++} ++ ++void * ++foo_ifunc (void) ++{ ++ __m128i xmm = _mm_set1_epi32 (-1); ++ asm volatile ("movdqa %0, %%xmm0" : : "x" (xmm) : "xmm0" ); ++ return foo_impl; ++} +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-avx-aux.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-avx-aux.c +@@ -0,0 +1,47 @@ ++/* Test case for preserved AVX registers in dynamic linker, -mavx part. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++tst_avx_aux (void) ++{ ++#ifdef __AVX__ ++ extern __m256i avx_test (__m256i, __m256i, __m256i, __m256i, ++ __m256i, __m256i, __m256i, __m256i); ++ ++ __m256i ymm0 = _mm256_set1_epi32 (0); ++ __m256i ymm1 = _mm256_set1_epi32 (1); ++ __m256i ymm2 = _mm256_set1_epi32 (2); ++ __m256i ymm3 = _mm256_set1_epi32 (3); ++ __m256i ymm4 = _mm256_set1_epi32 (4); ++ __m256i ymm5 = _mm256_set1_epi32 (5); ++ __m256i ymm6 = _mm256_set1_epi32 (6); ++ __m256i ymm7 = _mm256_set1_epi32 (7); ++ __m256i ret = avx_test (ymm0, ymm1, ymm2, ymm3, ++ ymm4, ymm5, ymm6, ymm7); ++ ymm0 = _mm256_set1_epi32 (0x12349876); ++ if (memcmp (&ymm0, &ret, sizeof (ret))) ++ abort (); ++ return 0; ++#else /* __AVX__ */ ++ return 77; ++#endif /* __AVX__ */ ++} +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-avx.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-avx.c +@@ -0,0 +1,49 @@ ++/* Test case for preserved AVX registers in dynamic linker. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int tst_avx_aux (void); ++ ++static int ++avx_enabled (void) ++{ ++ unsigned int eax, ebx, ecx, edx; ++ ++ if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 ++ || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) ++ return 0; ++ ++ /* Check the OS has AVX and SSE saving enabled. */ ++ asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); ++ ++ return (eax & 6) == 6; ++} ++ ++static int ++do_test (void) ++{ ++ /* Run AVX test only if AVX is supported. */ ++ if (avx_enabled ()) ++ return tst_avx_aux (); ++ else ++ return 77; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-avx512-aux.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-avx512-aux.c +@@ -0,0 +1,48 @@ ++/* Test case for preserved AVX512 registers in dynamic linker, ++ -mavx512 part. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++int ++tst_avx512_aux (void) ++{ ++#ifdef __AVX512F__ ++ extern __m512i avx512_test (__m512i, __m512i, __m512i, __m512i, ++ __m512i, __m512i, __m512i, __m512i); ++ ++ __m512i zmm0 = _mm512_set1_epi32 (0); ++ __m512i zmm1 = _mm512_set1_epi32 (1); ++ __m512i zmm2 = _mm512_set1_epi32 (2); ++ __m512i zmm3 = _mm512_set1_epi32 (3); ++ __m512i zmm4 = _mm512_set1_epi32 (4); ++ __m512i zmm5 = _mm512_set1_epi32 (5); ++ __m512i zmm6 = _mm512_set1_epi32 (6); ++ __m512i zmm7 = _mm512_set1_epi32 (7); ++ __m512i ret = avx512_test (zmm0, zmm1, zmm2, zmm3, ++ zmm4, zmm5, zmm6, zmm7); ++ zmm0 = _mm512_set1_epi32 (0x12349876); ++ if (memcmp (&zmm0, &ret, sizeof (ret))) ++ abort (); ++ return 0; ++#else /* __AVX512F__ */ ++ return 77; ++#endif /* __AVX512F__ */ ++} +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-avx512.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-avx512.c +@@ -0,0 +1,57 @@ ++/* Test case for preserved AVX512 registers in dynamic linker. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++int tst_avx512_aux (void); ++ ++static int ++avx512_enabled (void) ++{ ++#ifdef bit_AVX512F ++ unsigned int eax, ebx, ecx, edx; ++ ++ if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0 ++ || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE)) ++ return 0; ++ ++ __cpuid_count (7, 0, eax, ebx, ecx, edx); ++ if (!(ebx & bit_AVX512F)) ++ return 0; ++ ++ asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); ++ ++ /* Verify that ZMM, YMM and XMM states are enabled. */ ++ return (eax & 0xe6) == 0xe6; ++#else ++ return 0; ++#endif ++} ++ ++static int ++do_test (void) ++{ ++ /* Run AVX512 test only if AVX512 is supported. */ ++ if (avx512_enabled ()) ++ return tst_avx512_aux (); ++ else ++ return 77; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-avx512mod.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-avx512mod.c +@@ -0,0 +1,48 @@ ++/* Test case for x86-64 preserved AVX512 registers in dynamic linker. */ ++ ++#ifdef __AVX512F__ ++#include ++#include ++#include ++ ++__m512i ++avx512_test (__m512i x0, __m512i x1, __m512i x2, __m512i x3, ++ __m512i x4, __m512i x5, __m512i x6, __m512i x7) ++{ ++ __m512i zmm; ++ ++ zmm = _mm512_set1_epi32 (0); ++ if (memcmp (&zmm, &x0, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (1); ++ if (memcmp (&zmm, &x1, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (2); ++ if (memcmp (&zmm, &x2, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (3); ++ if (memcmp (&zmm, &x3, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (4); ++ if (memcmp (&zmm, &x4, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (5); ++ if (memcmp (&zmm, &x5, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (6); ++ if (memcmp (&zmm, &x6, sizeof (zmm))) ++ abort (); ++ ++ zmm = _mm512_set1_epi32 (7); ++ if (memcmp (&zmm, &x7, sizeof (zmm))) ++ abort (); ++ ++ return _mm512_set1_epi32 (0x12349876); ++} ++#endif +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-ssemod.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-ssemod.c +@@ -0,0 +1,46 @@ ++/* Test case for x86-64 preserved SSE registers in dynamic linker. */ ++ ++#include ++#include ++#include ++ ++__m128i ++sse_test (__m128i x0, __m128i x1, __m128i x2, __m128i x3, ++ __m128i x4, __m128i x5, __m128i x6, __m128i x7) ++{ ++ __m128i xmm; ++ ++ xmm = _mm_set1_epi32 (0); ++ if (memcmp (&xmm, &x0, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (1); ++ if (memcmp (&xmm, &x1, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (2); ++ if (memcmp (&xmm, &x2, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (3); ++ if (memcmp (&xmm, &x3, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (4); ++ if (memcmp (&xmm, &x4, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (5); ++ if (memcmp (&xmm, &x5, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (6); ++ if (memcmp (&xmm, &x6, sizeof (xmm))) ++ abort (); ++ ++ xmm = _mm_set1_epi32 (7); ++ if (memcmp (&xmm, &x7, sizeof (xmm))) ++ abort (); ++ ++ return _mm_set1_epi32 (0x12349876); ++} +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-sse.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-sse.c +@@ -0,0 +1,46 @@ ++/* Test case for preserved SSE registers in dynamic linker. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++extern __m128i sse_test (__m128i, __m128i, __m128i, __m128i, ++ __m128i, __m128i, __m128i, __m128i); ++ ++static int ++do_test (void) ++{ ++ __m128i xmm0 = _mm_set1_epi32 (0); ++ __m128i xmm1 = _mm_set1_epi32 (1); ++ __m128i xmm2 = _mm_set1_epi32 (2); ++ __m128i xmm3 = _mm_set1_epi32 (3); ++ __m128i xmm4 = _mm_set1_epi32 (4); ++ __m128i xmm5 = _mm_set1_epi32 (5); ++ __m128i xmm6 = _mm_set1_epi32 (6); ++ __m128i xmm7 = _mm_set1_epi32 (7); ++ __m128i ret = sse_test (xmm0, xmm1, xmm2, xmm3, ++ xmm4, xmm5, xmm6, xmm7); ++ xmm0 = _mm_set1_epi32 (0x12349876); ++ if (memcmp (&xmm0, &ret, sizeof (ret))) ++ abort (); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../../test-skeleton.c" +Index: glibc-2.17-c758a686/sysdeps/x86_64/tst-avxmod.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/x86_64/tst-avxmod.c +@@ -0,0 +1,49 @@ ++ ++/* Test case for x86-64 preserved AVX registers in dynamic linker. */ ++ ++#ifdef __AVX__ ++#include ++#include ++#include ++ ++__m256i ++avx_test (__m256i x0, __m256i x1, __m256i x2, __m256i x3, ++ __m256i x4, __m256i x5, __m256i x6, __m256i x7) ++{ ++ __m256i ymm; ++ ++ ymm = _mm256_set1_epi32 (0); ++ if (memcmp (&ymm, &x0, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (1); ++ if (memcmp (&ymm, &x1, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (2); ++ if (memcmp (&ymm, &x2, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (3); ++ if (memcmp (&ymm, &x3, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (4); ++ if (memcmp (&ymm, &x4, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (5); ++ if (memcmp (&ymm, &x5, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (6); ++ if (memcmp (&ymm, &x6, sizeof (ymm))) ++ abort (); ++ ++ ymm = _mm256_set1_epi32 (7); ++ if (memcmp (&ymm, &x7, sizeof (ymm))) ++ abort (); ++ ++ return _mm256_set1_epi32 (0x12349876); ++} ++#endif diff --git a/SOURCES/glibc-rh1435615.patch b/SOURCES/glibc-rh1435615.patch new file mode 100644 index 00000000..67fdb903 --- /dev/null +++ b/SOURCES/glibc-rh1435615.patch @@ -0,0 +1,26 @@ +From 3de93d194a5d27cabfe40ddf58aea36939498ba4 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Mon, 25 Sep 2017 19:43:09 -0400 +Subject: nscd: Release read lock after resetting timeout. + + [BZ #22161] + * nscd/netgroupcache.c (addinnetgrX): Release read lock after + resetting timeout. + +Reviewed-by: Jonathan Nieder +Reviewed-by: Andreas Schwab + +A lock is held by mempool_allocate() when CACHEABLE is true; we +must release this lock if we exit early. + +diff -rup a/nscd/netgroupcache.c b/nscd/netgroupcache.c +--- a/nscd/netgroupcache.c 2017-09-19 15:37:22.000000000 -0400 ++++ b/nscd/netgroupcache.c 2017-09-20 16:33:54.982679050 -0400 +@@ -586,6 +586,8 @@ addinnetgrX (struct database_dyn *db, in + dh->timeout = timeout; + dh->ttl = dataset->head.ttl; + ++dh->nreloads; ++ if (cacheable) ++ pthread_rwlock_unlock (&db->lock); + return timeout; + } diff --git a/SOURCES/glibc-rh1436312.patch b/SOURCES/glibc-rh1436312.patch new file mode 100644 index 00000000..1f1eaa20 --- /dev/null +++ b/SOURCES/glibc-rh1436312.patch @@ -0,0 +1,54 @@ +Upstream commits: + +commit a071766ebfd853179ac39f9773f894029bf86d36 +Author: Andreas Schwab +Date: Thu Mar 20 15:05:25 2014 +0100 + + Fix use of half-initialized result in getaddrinfo when using nscd (bug 16743) + + This fixes a bug in the way the results from __nscd_getai are collected: + for every returned result a new entry is first added to the + gaih_addrtuple list, but if that result doesn't match the request this + entry remains uninitialized. So for this non-matching result an extra + result with uninitialized content is returned. + + To reproduce (with nscd running): + + $ getent ahostsv4 localhost + 127.0.0.1 STREAM localhost + 127.0.0.1 DGRAM + 127.0.0.1 RAW + (null) STREAM + (null) DGRAM + (null) RAW + +commit 8dc9751764eb1bedf06d19695524b31a16773413 +Author: Andreas Schwab +Date: Wed May 7 11:47:20 2014 +0200 + + Fix parsing of getai result from nscd for IPv6-only request + + +Index: b/sysdeps/posix/getaddrinfo.c +=================================================================== +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -725,6 +725,18 @@ gaih_inet (const char *name, const struc + { + socklen_t size = (air->family[i] == AF_INET + ? INADDRSZ : IN6ADDRSZ); ++ ++ if (!((air->family[i] == AF_INET ++ && req->ai_family == AF_INET6 ++ && (req->ai_flags & AI_V4MAPPED) != 0) ++ || req->ai_family == AF_UNSPEC ++ || air->family[i] == req->ai_family)) ++ { ++ /* Skip over non-matching result. */ ++ addrs += size; ++ continue; ++ } ++ + if (*pat == NULL) + { + *pat = addrfree++; diff --git a/SOURCES/glibc-rh1439165-syscall-names.patch b/SOURCES/glibc-rh1439165-syscall-names.patch new file mode 100644 index 00000000..247e3f26 --- /dev/null +++ b/SOURCES/glibc-rh1439165-syscall-names.patch @@ -0,0 +1,610 @@ +This patch contains the sysdeps/unix/sysv/linux/syscall-names.list file +from upstream and is continuously updated for new kernel versions. + +diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list +new file mode 100644 +index 0000000000000000..584a762126fca55b +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/syscall-names.list +@@ -0,0 +1,601 @@ ++# List of all known Linux system calls. ++# Copyright (C) 2017 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# This file contains the list of system call names names. It has to ++# remain in alphabetica order. Lines which start with # are treated ++# as comments. This file can list all potential system calls. The ++# names are only used if the installed kernel headers also provide ++# them. ++ ++# The list of system calls is current as of Linux 4.13. ++kernel 4.13 ++ ++FAST_atomic_update ++FAST_cmpxchg ++FAST_cmpxchg64 ++_llseek ++_newselect ++_sysctl ++accept ++accept4 ++access ++acct ++acl_get ++acl_set ++add_key ++adjtimex ++afs_syscall ++alarm ++alloc_hugepages ++arch_prctl ++arm_fadvise64_64 ++arm_sync_file_range ++atomic_barrier ++atomic_cmpxchg_32 ++attrctl ++bdflush ++bind ++bpf ++break ++brk ++cachectl ++cacheflush ++capget ++capset ++chdir ++chmod ++chown ++chown32 ++chroot ++clock_adjtime ++clock_getres ++clock_gettime ++clock_nanosleep ++clock_settime ++clone ++clone2 ++close ++cmpxchg_badaddr ++connect ++copy_file_range ++creat ++create_module ++delete_module ++dipc ++dup ++dup2 ++dup3 ++epoll_create ++epoll_create1 ++epoll_ctl ++epoll_ctl_old ++epoll_pwait ++epoll_wait ++epoll_wait_old ++eventfd ++eventfd2 ++exec_with_loader ++execv ++execve ++execveat ++exit ++exit_group ++faccessat ++fadvise64 ++fadvise64_64 ++fallocate ++fanotify_init ++fanotify_mark ++fchdir ++fchmod ++fchmodat ++fchown ++fchown32 ++fchownat ++fcntl ++fcntl64 ++fdatasync ++fgetxattr ++finit_module ++flistxattr ++flock ++fork ++free_hugepages ++fremovexattr ++fsetxattr ++fstat ++fstat64 ++fstatat64 ++fstatfs ++fstatfs64 ++fsync ++ftime ++ftruncate ++ftruncate64 ++futex ++futimesat ++get_kernel_syms ++get_mempolicy ++get_robust_list ++get_thread_area ++getcpu ++getcwd ++getdents ++getdents64 ++getdomainname ++getdtablesize ++getegid ++getegid32 ++geteuid ++geteuid32 ++getgid ++getgid32 ++getgroups ++getgroups32 ++gethostname ++getitimer ++getpagesize ++getpeername ++getpgid ++getpgrp ++getpid ++getpmsg ++getppid ++getpriority ++getrandom ++getresgid ++getresgid32 ++getresuid ++getresuid32 ++getrlimit ++getrusage ++getsid ++getsockname ++getsockopt ++gettid ++gettimeofday ++getuid ++getuid32 ++getunwind ++getxattr ++getxgid ++getxpid ++getxuid ++gtty ++idle ++init_module ++inotify_add_watch ++inotify_init ++inotify_init1 ++inotify_rm_watch ++io_cancel ++io_destroy ++io_getevents ++io_setup ++io_submit ++ioctl ++ioperm ++iopl ++ioprio_get ++ioprio_set ++ipc ++kcmp ++kern_features ++kexec_file_load ++kexec_load ++keyctl ++kill ++lchown ++lchown32 ++lgetxattr ++link ++linkat ++listen ++listxattr ++llistxattr ++llseek ++lock ++lookup_dcookie ++lremovexattr ++lseek ++lsetxattr ++lstat ++lstat64 ++madvise ++mbind ++membarrier ++memfd_create ++memory_ordering ++migrate_pages ++mincore ++mkdir ++mkdirat ++mknod ++mknodat ++mlock ++mlock2 ++mlockall ++mmap ++mmap2 ++modify_ldt ++mount ++move_pages ++mprotect ++mpx ++mq_getsetattr ++mq_notify ++mq_open ++mq_timedreceive ++mq_timedsend ++mq_unlink ++mremap ++msgctl ++msgget ++msgrcv ++msgsnd ++msync ++multiplexer ++munlock ++munlockall ++munmap ++name_to_handle_at ++nanosleep ++newfstatat ++nfsservctl ++ni_syscall ++nice ++old_adjtimex ++oldfstat ++oldlstat ++oldolduname ++oldstat ++oldumount ++olduname ++open ++open_by_handle_at ++openat ++osf_adjtime ++osf_afs_syscall ++osf_alt_plock ++osf_alt_setsid ++osf_alt_sigpending ++osf_asynch_daemon ++osf_audcntl ++osf_audgen ++osf_chflags ++osf_execve ++osf_exportfs ++osf_fchflags ++osf_fdatasync ++osf_fpathconf ++osf_fstat ++osf_fstatfs ++osf_fstatfs64 ++osf_fuser ++osf_getaddressconf ++osf_getdirentries ++osf_getdomainname ++osf_getfh ++osf_getfsstat ++osf_gethostid ++osf_getitimer ++osf_getlogin ++osf_getmnt ++osf_getrusage ++osf_getsysinfo ++osf_gettimeofday ++osf_kloadcall ++osf_kmodcall ++osf_lstat ++osf_memcntl ++osf_mincore ++osf_mount ++osf_mremap ++osf_msfs_syscall ++osf_msleep ++osf_mvalid ++osf_mwakeup ++osf_naccept ++osf_nfssvc ++osf_ngetpeername ++osf_ngetsockname ++osf_nrecvfrom ++osf_nrecvmsg ++osf_nsendmsg ++osf_ntp_adjtime ++osf_ntp_gettime ++osf_old_creat ++osf_old_fstat ++osf_old_getpgrp ++osf_old_killpg ++osf_old_lstat ++osf_old_open ++osf_old_sigaction ++osf_old_sigblock ++osf_old_sigreturn ++osf_old_sigsetmask ++osf_old_sigvec ++osf_old_stat ++osf_old_vadvise ++osf_old_vtrace ++osf_old_wait ++osf_oldquota ++osf_pathconf ++osf_pid_block ++osf_pid_unblock ++osf_plock ++osf_priocntlset ++osf_profil ++osf_proplist_syscall ++osf_reboot ++osf_revoke ++osf_sbrk ++osf_security ++osf_select ++osf_set_program_attributes ++osf_set_speculative ++osf_sethostid ++osf_setitimer ++osf_setlogin ++osf_setsysinfo ++osf_settimeofday ++osf_shmat ++osf_signal ++osf_sigprocmask ++osf_sigsendset ++osf_sigstack ++osf_sigwaitprim ++osf_sstk ++osf_stat ++osf_statfs ++osf_statfs64 ++osf_subsys_info ++osf_swapctl ++osf_swapon ++osf_syscall ++osf_sysinfo ++osf_table ++osf_uadmin ++osf_usleep_thread ++osf_uswitch ++osf_utc_adjtime ++osf_utc_gettime ++osf_utimes ++osf_utsname ++osf_wait4 ++osf_waitid ++pause ++pciconfig_iobase ++pciconfig_read ++pciconfig_write ++perf_event_open ++perfctr ++perfmonctl ++personality ++pipe ++pipe2 ++pivot_root ++pkey_alloc ++pkey_free ++pkey_mprotect ++poll ++ppoll ++prctl ++pread64 ++preadv ++preadv2 ++prlimit64 ++process_vm_readv ++process_vm_writev ++prof ++profil ++pselect6 ++ptrace ++putpmsg ++pwrite64 ++pwritev ++pwritev2 ++query_module ++quotactl ++read ++readahead ++readdir ++readlink ++readlinkat ++readv ++reboot ++recv ++recvfrom ++recvmmsg ++recvmsg ++remap_file_pages ++removexattr ++rename ++renameat ++renameat2 ++request_key ++restart_syscall ++rmdir ++rt_sigaction ++rt_sigpending ++rt_sigprocmask ++rt_sigqueueinfo ++rt_sigreturn ++rt_sigsuspend ++rt_sigtimedwait ++rt_tgsigqueueinfo ++rtas ++s390_guarded_storage ++s390_pci_mmio_read ++s390_pci_mmio_write ++s390_runtime_instr ++sched_get_affinity ++sched_get_priority_max ++sched_get_priority_min ++sched_getaffinity ++sched_getattr ++sched_getparam ++sched_getscheduler ++sched_rr_get_interval ++sched_set_affinity ++sched_setaffinity ++sched_setattr ++sched_setparam ++sched_setscheduler ++sched_yield ++seccomp ++security ++select ++semctl ++semget ++semop ++semtimedop ++send ++sendfile ++sendfile64 ++sendmmsg ++sendmsg ++sendto ++set_mempolicy ++set_robust_list ++set_thread_area ++set_tid_address ++setdomainname ++setfsgid ++setfsgid32 ++setfsuid ++setfsuid32 ++setgid ++setgid32 ++setgroups ++setgroups32 ++sethae ++sethostname ++setitimer ++setns ++setpgid ++setpgrp ++setpriority ++setregid ++setregid32 ++setresgid ++setresgid32 ++setresuid ++setresuid32 ++setreuid ++setreuid32 ++setrlimit ++setsid ++setsockopt ++settimeofday ++setuid ++setuid32 ++setxattr ++sgetmask ++shmat ++shmctl ++shmdt ++shmget ++shutdown ++sigaction ++sigaltstack ++signal ++signalfd ++signalfd4 ++sigpending ++sigprocmask ++sigreturn ++sigsuspend ++socket ++socketcall ++socketpair ++splice ++spu_create ++spu_run ++ssetmask ++stat ++stat64 ++statfs ++statfs64 ++statx ++stime ++stty ++subpage_prot ++swapcontext ++swapoff ++swapon ++switch_endian ++symlink ++symlinkat ++sync ++sync_file_range ++sync_file_range2 ++syncfs ++sys_debug_setcontext ++sys_epoll_create ++sys_epoll_ctl ++sys_epoll_wait ++syscall ++sysfs ++sysinfo ++syslog ++sysmips ++tee ++tgkill ++time ++timer_create ++timer_delete ++timer_getoverrun ++timer_gettime ++timer_settime ++timerfd ++timerfd_create ++timerfd_gettime ++timerfd_settime ++times ++tkill ++truncate ++truncate64 ++tuxcall ++ugetrlimit ++ulimit ++umask ++umount ++umount2 ++uname ++unlink ++unlinkat ++unshare ++uselib ++userfaultfd ++ustat ++utime ++utimensat ++utimes ++utrap_install ++vfork ++vhangup ++vm86 ++vm86old ++vmsplice ++vserver ++wait4 ++waitid ++waitpid ++write ++writev diff --git a/SOURCES/glibc-rh1439165.patch b/SOURCES/glibc-rh1439165.patch new file mode 100644 index 00000000..35566006 --- /dev/null +++ b/SOURCES/glibc-rh1439165.patch @@ -0,0 +1,348 @@ +Posted upstream at: + + https://sourceware.org/ml/libc-alpha/2017-04/msg00082.html + +sysdeps/unix/sysv/linux/syscall-names.list is stored as a separate patch +(glibc-rh1439165-syscall-names.patch) in the source RPM for easier +updates. + +Author: Florian Weimer + + : Use an arch-independent system call list on Linux + + This commit changes the way the list of SYS_* system call macros + is created on Linux. glibc now contains a list of all known system + calls, and the generated file defines the SYS_ + macro only if the correspnding __NR_ macro is defined by the kernel + headers. + + As a result, there glibc does not have to be rebuilt to pick up + system calls if the glibc sources already know about them. This + means that glibc can be built with older kernel headers, and if + the installed kernel headers are upgraded afterwards, additional + SYS_ macros become available as long as glibc has a record for + those system calls. + +The explicit system call list for system call management was not +accepted upstream. + +Fedora bug: https://bugzilla.redhat.com/show_bug.cgi?id=1484729 +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 366b1d7..95cff0e 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -39,75 +39,46 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ + + tests += tst-clone + +-# Generate the list of SYS_* macros for the system calls (__NR_* macros). +- +-# If there is more than one syscall list for different architecture +-# variants, the CPU/Makefile defines abi-variants to be a list of names +-# for those variants (e.g. 32 64), and, for each variant, defines +-# abi-$(variant)-options to be compiler options to cause +-# to define the desired list of syscalls and abi-$(variant)-condition to +-# be the condition for those options to use in a C #if condition. +-# abi-includes may be defined to a list of headers to include +-# in the generated header, if the default does not suffice. +-# +-# The generated header is compiled with `-ffreestanding' to avoid any +-# circular dependencies against the installed implementation headers. +-# Such a dependency would require the implementation header to be +-# installed before the generated header could be built (See bug 15711). +-# In current practice the generated header dependencies do not include +-# any of the implementation headers removed by the use of `-ffreestanding'. +- +-$(objpfx)bits/syscall%h $(objpfx)bits/syscall%d: ../sysdeps/unix/sysv/linux/sys/syscall.h ++# Generate the list of SYS_* macros for the system calls (__NR_* ++# macros). The file syscall-names.list contains all possible system ++# call names, and the generated header file produces SYS_* macros for ++# the __NR_* macros which are actually defined. ++ ++generated += bits/syscall.h ++$(objpfx)bits/syscall.h: \ ++ ../sysdeps/unix/sysv/linux/gen-syscall-h.awk \ ++ ../sysdeps/unix/sysv/linux/syscall-names.list + $(make-target-directory) +- { \ +- echo '/* Generated at libc build time from kernel syscall list. */';\ +- echo ''; \ +- echo '#ifndef _SYSCALL_H'; \ +- echo '# error "Never use directly; include instead."'; \ +- echo '#endif'; \ +- echo ''; \ +- $(foreach h,$(abi-includes), echo '#include <$(h)>';) \ +- echo ''; \ +- $(if $(abi-variants), \ +- $(foreach v,$(abi-variants),\ +- $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \ +- -x c $(sysincludes) $< $(abi-$(v)-options) \ +- -D_LIBC -dM | \ +- sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ +- LC_ALL=C sort > $(@:.d=.h).new$(v); \ +- $(if $(abi-$(v)-condition),\ +- echo '#if $(abi-$(v)-condition)';) \ +- cat $(@:.d=.h).new$(v); \ +- $(if $(abi-$(v)-condition),echo '#endif';) \ +- rm -f $(@:.d=.h).new$(v); \ +- ), \ +- $(CC) -ffreestanding -E -MD -MP -MF $(@:.h=.d)-t$(v) -MT '$(@:.d=.h) $(@:.h=.d)' \ +- -x c $(sysincludes) $< \ +- -D_LIBC -dM | \ +- sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ +- LC_ALL=C sort;) \ +- } > $(@:.d=.h).new +- mv -f $(@:.d=.h).new $(@:.d=.h) +-ifdef abi-variants +-ifneq (,$(objpfx)) +- sed $(sed-remove-objpfx) \ +- $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) > $(@:.h=.d)-t3 +-else +- cat $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) \ +- > $(@:.h=.d)-t3 +-endif +- rm -f $(foreach v,$(abi-variants),$(@:.h=.d)-t$(v)) +- mv -f $(@:.h=.d)-t3 $(@:.h=.d) +-else +- mv -f $(@:.h=.d)-t $(@:.h=.d) +-endif +- +-ifndef no_deps +-# Get the generated list of dependencies (probably /usr/include/asm/unistd.h). +--include $(objpfx)bits/syscall.d +-endif +-generated += bits/syscall.h bits/syscall.d +-endif ++ $(AWK) -f $^ > $@-tmp ++ $(move-if-change) $@-tmp $@ ++ ++# All macros defined by . Include ++# explicitly because skips it if _LIBC is defined. ++$(objpfx)tst-syscall-list-macros.list: \ ++ $(objpfx)bits/syscall.h ../sysdeps/unix/sysv/linux/sys/syscall.h ++ printf '#include \n#include \n' | \ ++ $(CC) -E -o $@-tmp $(CFLAGS) $(CPPFLAGS) -x c - -dM ++ $(move-if-change) $@-tmp $@ ++ ++# __NR_* system call names. Used by the test below. ++$(objpfx)tst-syscall-list-nr.list: \ ++ ../sysdeps/unix/sysv/linux/filter-nr-syscalls.awk \ ++ $(objpfx)tst-syscall-list-macros.list ++ $(AWK) -f $^ > $@-tmp ++ $(move-if-change) $@-tmp $@ ++ ++# SYS_* system call names. Used by the test below. ++$(objpfx)tst-syscall-list-sys.list: $(objpfx)tst-syscall-list-macros.list ++ $(AWK) '/^#define SYS_/ { print substr($$2, 5) }' $< > $@-tmp ++ $(move-if-change) $@-tmp $@ ++ ++tests: $(objpfx)tst-syscall-list.out ++$(objpfx)tst-syscall-list.out: \ ++ ../sysdeps/unix/sysv/linux/tst-syscall-list.sh \ ++ $(objpfx)tst-syscall-list-nr.list $(objpfx)tst-syscall-list-sys.list ++ $(BASH) $^ > $@ ++ ++endif # $(subdir) == misc + + ifeq ($(subdir),time) + sysdep_headers += sys/timex.h bits/timex.h +diff --git a/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk +new file mode 100644 +index 0000000..15b052a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/filter-nr-syscalls.awk +@@ -0,0 +1,35 @@ ++# Filter preprocessor __NR_* macros and extract system call names. ++# Copyright (C) 2017 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# Skip reserved system calls. ++/^#define __NR_(unused|reserved)[0-9]+ / { ++ next; ++} ++ ++# Skip pseudo-system calls which describe ranges. ++/^#define __NR_(syscalls|arch_specific_syscall|(OABI_)?SYSCALL_BASE) / { ++ next; ++} ++/^#define __NR_(|64_|[NO]32_)Linux(_syscalls)? / { ++ next; ++} ++ ++# Print the remaining _NR_* macros as system call names. ++/^#define __NR_/ { ++ print substr($2, 6); ++} +diff --git a/sysdeps/unix/sysv/linux/gen-syscall-h.awk b/sysdeps/unix/sysv/linux/gen-syscall-h.awk +new file mode 100644 +index 0000000..0a27b3c +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/gen-syscall-h.awk +@@ -0,0 +1,75 @@ ++# Generate SYS_* macros from a list in a text file. ++# Copyright (C) 2017 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# Emit a conditional definition for SYS_NAME. ++function emit(name) { ++ print "#ifdef __NR_" name; ++ print "# define SYS_" name " __NR_" name; ++ print "#endif"; ++ print ""; ++} ++ ++# Bail out with an error. ++function fatal(message) { ++ print FILENAME ":" FNR ": " message > "/dev/stderr"; ++ exit 1; ++} ++ ++BEGIN { ++ name = ""; ++ kernel = ""; ++} ++ ++# Skip empty lines and comments. ++/^\s*(|#.*)$/ { ++ next; ++} ++ ++# Kernel version. Used for documentation purposes only. ++/^kernel [0-9.]+$/ { ++ if (kernel != "") { ++ fatal("duplicate kernel directive"); ++ } ++ kernel = $2; ++ print "/* Generated at libc build time from syscall list. */"; ++ print "/* The system call list corresponds to kernel " kernel ". */"; ++ print ""; ++ print "#ifndef _SYSCALL_H" ++ print "# error \"Never use directly; include instead.\""; ++ print "#endif"; ++ print ""; ++ next; ++} ++ ++# If there is just one word, it is a system call. ++/^[a-zA-Z_][a-zA-Z0-9_]+$/ { ++ if (kernel == "") { ++ fatal("expected kernel directive before this line"); ++ } ++ if ($1 <= name) { ++ fatal("name " name " violates ordering"); ++ } ++ emit($1); ++ name = $1; ++ next; ++} ++ ++# The rest has to be syntax errors. ++// { ++ fatal("unrecognized syntax"); ++} +diff --git a/sysdeps/unix/sysv/linux/tst-syscall-list.sh b/sysdeps/unix/sysv/linux/tst-syscall-list.sh +new file mode 100644 +index 0000000..f48b7cd +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-syscall-list.sh +@@ -0,0 +1,72 @@ ++#!/bin/bash ++# Consistency checks for the system call list ++# Copyright (C) 2017 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++export LC_ALL=C ++set -e ++set -o pipefail ++ ++if test $# != 2 ; then ++ echo "error: wrong number of arguments: $#" ++ exit 1 ++fi ++ ++list_nr="$1" ++list_sys="$2" ++ ++errors=0 ++ ++# Use getpid as a system call which is expected to be always defined. ++# alpha uses getxpid instead, so it is permitted as an alternative. ++if ! grep -E -q '^getx?pid$' -- "$list_nr" ; then ++ echo "error: __NR_getpid not defined" ++ errors=1 ++fi ++if ! grep -E -q '^getx?pid$' -- "$list_sys" ; then ++ echo "error: SYS_getpid not defined" ++ errors=1 ++fi ++ ++comm_1="$(mktemp)" ++comm_2="$(mktemp)" ++comm_result="$(mktemp)" ++cleanup () { ++ rm -f -- "$comm_1" "$comm_2" "$comm_result" ++} ++trap cleanup 0 ++ ++sort -o "$comm_1" -- "$list_nr" ++sort -o "$comm_2" -- "$list_sys" ++ ++# Check for missing SYS_* macros. ++comm --check-order -2 -3 -- "$comm_1" "$comm_2" > "$comm_result" ++if test -s "$comm_result"; then ++ echo "error: These system calls need to be added to syscall-names.list:" ++ cat -- "$comm_result" ++ errors=1 ++fi ++ ++# Check for additional SYS_* macros. ++comm --check-order -1 -3 -- "$comm_1" "$comm_2" > "$comm_result" ++if test -s "$comm_result"; then ++ echo "error: The following system calls have unexpected SYS_* macros:" ++ cat -- "$comm_result" ++ errors=1 ++fi ++ ++exit "$errors" diff --git a/SOURCES/glibc-rh1440250.patch b/SOURCES/glibc-rh1440250.patch new file mode 100644 index 00000000..7ba09c95 --- /dev/null +++ b/SOURCES/glibc-rh1440250.patch @@ -0,0 +1,406 @@ +commit 9637d8a253493be471d9a71640e91349f7a8a050 +Author: H.J. Lu +Date: Wed Jul 29 11:57:54 2015 -0700 + + Extend local PLT reference check + + On x86, linker in binutils 2.26 and newer consolidates R_*_JUMP_SLOT with + R_*_GLOB_DAT relocation against the same symbol. This patch extends + local PLT reference check to support alternate relocations. + + [BZ #18078] + * scripts/check-localplt.awk: Support alternate relocations. + * scripts/localplt.awk: Also check relocations in DT_RELA/DT_REL + sections. + * sysdeps/unix/sysv/linux/i386/localplt.data: Mark free and + malloc entries with + REL R_386_GLOB_DAT. + * sysdeps/x86_64/localplt.data: New file. + + +commit da53d6dbc28d2a90d6e14dd661e68611c3b741cf +Author: Carlos O'Donell +Date: Thu Nov 6 15:48:44 2014 -0500 + + Run check-localpltk/textrel/execstack over ld.so. + + For maximum paranoia we run ld.so through the normal set + of tests for all of the shared libraries. This includes + running ld.so through check-localplt, check-textrel, and + check-execstack. While none of these should trigger any + failures given the way ld.so is built, it might possibly + fail if a developer does something wrong. This paranoia + was triggered by a discussion over the use of __strcpy + vs. strcpy [1] and if the symbol could leak and use the + libc.so version. + + The check-localplt test fails right away because localplt.data + needs updating for all arches. By default we add 6 new symbols: + __tls_get_addr, __libc_memalign, malloc, calloc, realloc and + free. Other machines like i386, power, and s390 require some + different symbol sets e.g. ___tls_get_addr vs. __tls_get_addr + for i386. + +commit d3d9c95aefded7716d037e241f9d23a1cccab45a +Author: H.J. Lu +Date: Wed Oct 14 05:59:50 2015 -0700 + + Support PLT and GOT references in local PIC check + +commit a0af371c25ac1f215cf0db64e54cbb9a1b51f78c +Author: Alan Modra +Date: Fri Feb 20 15:23:28 2015 +1030 + + Fix localplt test breakage with new readelf + + Since 2014-11-24 binutils git commit bb4d2ac2, readelf has appended + the symbol version to symbols shown in reloc dumps. + + [BZ #16512] + * scripts/localplt.awk: Strip off symbol version. + * NEWS: Mention bug fix. + +diff -Nrup a/elf/Makefile b/elf/Makefile +--- a/elf/Makefile 2017-10-22 09:16:02.451399056 -0400 ++++ b/elf/Makefile 2017-10-22 09:16:39.217285466 -0400 +@@ -915,7 +915,7 @@ $(objpfx)tst-pie1: $(objpfx)tst-piemod1. + ifeq (yes,$(build-shared)) + tests: $(objpfx)check-textrel.out $(objpfx)check-execstack.out + +-all-built-dso := $(common-objpfx)libc.so \ ++all-built-dso := $(common-objpfx)elf/ld.so $(common-objpfx)libc.so \ + $(filter-out $(common-objpfx)linkobj/libc.so, \ + $(sort $(wildcard $(addprefix $(common-objpfx), \ + */lib*.so \ +@@ -974,6 +974,7 @@ tests: $(objpfx)check-localplt.out + + localplt-built-dso := $(addprefix $(common-objpfx),\ + libc.so \ ++ elf/ld.so \ + math/libm.so \ + rt/librt.so \ + dlfcn/libdl.so \ +diff -Nrup a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data +--- a/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data 2017-10-22 09:16:01.379402341 -0400 ++++ b/ports/sysdeps/unix/sysv/linux/aarch64/nptl/localplt.data 2017-10-22 09:16:39.217285466 -0400 +@@ -12,3 +12,15 @@ libm.so: matherr + libm.so: __signbit + libm.so: __signbitf + libm.so: __signbitl ++# The dynamic loader needs __tls_get_addr for TLS. ++ld.so: __tls_get_addr ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign + RELA R_X86_64_GLOB_DAT ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc ++ld.so: calloc ++ld.so: realloc ++ld.so: free +diff -Nrup a/scripts/check-localplt.awk b/scripts/check-localplt.awk +--- a/scripts/check-localplt.awk 2012-12-24 22:02:13.000000000 -0500 ++++ b/scripts/check-localplt.awk 2017-10-22 09:16:39.218285463 -0400 +@@ -3,9 +3,16 @@ + # Each line is either a comment starting with # or it looks like: + # libfoo.so: function + # or ++# libfoo.so: function + {RELA|REL} RELOC ++# or + # libfoo.so: function ? + # The latter means that a PLT entry for function is optional in libfoo.so. + # The former means one is required. ++# The first entry means that one is required. ++# The second entry means that one is required and relocation may also be ++# {RELA|REL} RELOC. ++# The third entry means that a PLT entry for function is optional in ++# libfoo.so. + # The second file argument is - and this (stdin) receives the output + # of the check-localplt program. + +@@ -14,7 +21,10 @@ BEGIN { result = 0 } + FILENAME != "-" && /^#/ { next } + + FILENAME != "-" { +- if (NF != 2 && !(NF == 3 && $3 == "?")) { ++ if (NF == 5 && $3 == "+" && ($4 == "RELA" || $4 == "REL")) { ++ accept_type[$1 " " $2] = $4; ++ accept_reloc[$1 " " $2] = $5; ++ } else if (NF != 2 && !(NF == 3 && $3 == "?")) { + printf "%s:%d: bad data line: %s\n", FILENAME, FNR, $0 > "/dev/stderr"; + result = 2; + } else { +@@ -23,7 +33,7 @@ FILENAME != "-" { + next; + } + +-NF != 2 { ++NF != 2 && !(NF == 4 && ($3 == "RELA" || $3 == "REL")) { + print "Unexpected output from check-localplt:", $0 > "/dev/stderr"; + result = 2; + next +@@ -31,7 +41,23 @@ NF != 2 { + + { + key = $1 " " $2 +- if (key in accept) { ++ if ($3 == "RELA" || $3 == "REL") { ++ # Entries like: ++ # libc.so: free + RELA R_X86_64_GLOB_DAT ++ # may be ignored. ++ if (key in accept_type && accept_type[key] == $3 && accept_reloc[key] == $4) { ++ # Match ++ # libc.so: free + RELA R_X86_64_GLOB_DAT ++ delete accept_type[key] ++ } ++ } else if (NF == 2 && key in accept_reloc) { ++ # Match ++ # libc.so: free ++ # against ++ # libc.so: free + RELA R_X86_64_GLOB_DAT ++ if (key in accept_type) ++ delete accept_type[key] ++ } else if (key in accept) { + delete accept[key] + } else { + print "Extra PLT reference:", $0; +@@ -49,5 +75,11 @@ END { + } + } + ++ for (key in accept_type) { ++ # It's mandatory. ++ print "Missing required PLT or " accept_reloc[key] " reference:", key; ++ result = 1; ++ } ++ + exit(result); + } +diff -Nrup a/scripts/localplt.awk b/scripts/localplt.awk +--- a/scripts/localplt.awk 2012-12-24 22:02:13.000000000 -0500 ++++ b/scripts/localplt.awk 2017-10-22 09:16:39.218285463 -0400 +@@ -7,12 +7,14 @@ + BEGIN { result = 0 } + + FILENAME != lastfile { +- if (lastfile && jmprel_offset == 0) { ++ if (lastfile && jmprel_offset == 0 && rela_offset == 0 && rel_offset == 0) { + print FILENAME ": *** failed to find expected output (readelf -WSdr)"; + result = 2; + } + lastfile = FILENAME; + jmprel_offset = 0; ++ rela_offset = 0; ++ rel_offset = 0; + delete section_offset_by_address; + } + +@@ -32,9 +34,39 @@ $1 == "Offset" && $2 == "Info" { in_relo + NF == 0 { in_relocs = 0 } + + in_relocs && relocs_offset == jmprel_offset && NF >= 5 { +- symval = strtonum("0x" $4); +- if (symval != 0) +- print whatfile, $5 ++ # Relocations against GNU_IFUNC symbols are not shown as an hexadecimal ++ # value, but rather as the resolver symbol followed by (). ++ if ($4 ~ /\(\)/) { ++ print whatfile, gensub(/@.*/, "", "g", $5) ++ } else { ++ symval = strtonum("0x" $4); ++ if (symval != 0) ++ print whatfile, gensub(/@.*/, "", "g", $5) ++ } ++} ++ ++in_relocs && relocs_offset == rela_offset && NF >= 5 { ++ # Relocations against GNU_IFUNC symbols are not shown as an hexadecimal ++ # value, but rather as the resolver symbol followed by (). ++ if ($4 ~ /\(\)/) { ++ print whatfile, gensub(/@.*/, "", "g", $5), "RELA", $3 ++ } else { ++ symval = strtonum("0x" $4); ++ if (symval != 0) ++ print whatfile, gensub(/@.*/, "", "g", $5), "RELA", $3 ++ } ++} ++ ++in_relocs && relocs_offset == rel_offset && NF >= 5 { ++ # Relocations against GNU_IFUNC symbols are not shown as an hexadecimal ++ # value, but rather as the resolver symbol followed by (). ++ if ($4 ~ /\(\)/) { ++ print whatfile, gensub(/@.*/, "", "g", $5), "REL", $3 ++ } else { ++ symval = strtonum("0x" $4); ++ if (symval != 0) ++ print whatfile, gensub(/@.*/, "", "g", $5), "REL", $3 ++ } + } + + in_relocs { next } +@@ -56,4 +88,25 @@ $2 == "(JMPREL)" { + next + } + ++$2 == "(RELA)" { ++ rela_addr = strtonum($3); ++ if (rela_addr in section_offset_by_address) { ++ rela_offset = section_offset_by_address[rela_addr]; ++ } else { ++ print FILENAME ": *** DT_RELA does not match any section's address"; ++ result = 2; ++ } ++ next ++} ++ ++$2 == "(REL)" { ++ rel_addr = strtonum($3); ++ if (rel_addr in section_offset_by_address) { ++ rel_offset = section_offset_by_address[rel_addr]; ++ } else { ++ print FILENAME ": *** DT_REL does not match any section's address"; ++ result = 2; ++ } ++ next ++} + END { exit(result) } +diff -Nrup a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data +--- a/sysdeps/generic/localplt.data 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/generic/localplt.data 2017-10-22 09:18:03.383023954 -0400 +@@ -7,3 +7,9 @@ libc.so: malloc + libc.so: memalign + libc.so: realloc + libm.so: matherr ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc ++ld.so: calloc ++ld.so: realloc ++ld.so: free +diff -Nrup a/sysdeps/unix/sysv/linux/i386/nptl/localplt.data b/sysdeps/unix/sysv/linux/i386/nptl/localplt.data +--- a/sysdeps/unix/sysv/linux/i386/nptl/localplt.data 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/i386/nptl/localplt.data 2017-10-22 09:16:39.218285463 -0400 +@@ -1,7 +1,21 @@ +-libc.so: _Unwind_Find_FDE +-libc.so: calloc +-libc.so: free +-libc.so: malloc +-libc.so: memalign +-libc.so: realloc +-libm.so: matherr ++# Linker in binutils 2.26 and newer consolidates R_X86_64_JUMP_SLOT ++# relocation with R_386_GLOB_DAT relocation against the same symbol. ++libc.so: _Unwind_Find_FDE + REL R_386_GLOB_DAT ++libc.so: calloc + REL R_386_GLOB_DAT ++libc.so: free + REL R_386_GLOB_DAT ++libc.so: malloc + REL R_386_GLOB_DAT ++libc.so: memalign + REL R_386_GLOB_DAT ++libc.so: realloc + REL R_386_GLOB_DAT ++libm.so: matherr + REL R_386_GLOB_DAT ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign + REL R_386_GLOB_DAT ++# The dynamic loader needs __tls_get_addr for TLS. ++ld.so: ___tls_get_addr + REL R_386_GLOB_DAT ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc + REL R_386_GLOB_DAT ++ld.so: calloc + REL R_386_GLOB_DAT ++ld.so: realloc + REL R_386_GLOB_DAT ++ld.so: free + REL R_386_GLOB_DAT +diff -Nrup a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/localplt.data +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/localplt.data 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/nptl/localplt.data 2017-10-22 09:16:39.218285463 -0400 +@@ -5,3 +5,13 @@ libc.so: malloc + libc.so: memalign + libc.so: realloc + libm.so: matherr ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc ++ld.so: calloc ++ld.so: realloc ++ld.so: free +diff -Nrup a/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/localplt.data b/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/localplt.data +--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/localplt.data 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/nptl/localplt.data 2017-10-22 09:16:39.218285463 -0400 +@@ -4,3 +4,13 @@ libc.so: malloc + libc.so: memalign + libc.so: realloc + libm.so: matherr ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc ++ld.so: calloc ++ld.so: realloc ++ld.so: free +diff -Nrup a/sysdeps/unix/sysv/linux/s390/s390-32/nptl/localplt.data b/sysdeps/unix/sysv/linux/s390/s390-32/nptl/localplt.data +--- a/sysdeps/unix/sysv/linux/s390/s390-32/nptl/localplt.data 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/s390/s390-32/nptl/localplt.data 2017-10-22 09:16:39.219285460 -0400 +@@ -5,3 +5,13 @@ libc.so: malloc + libc.so: memalign + libc.so: realloc + libm.so: matherr ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc ++ld.so: calloc ++ld.so: realloc ++ld.so: free +diff -Nrup a/sysdeps/unix/sysv/linux/s390/s390-64/nptl/localplt.data b/sysdeps/unix/sysv/linux/s390/s390-64/nptl/localplt.data +--- a/sysdeps/unix/sysv/linux/s390/s390-64/nptl/localplt.data 2012-12-24 22:02:13.000000000 -0500 ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/nptl/localplt.data 2017-10-22 09:16:39.219285460 -0400 +@@ -5,3 +5,13 @@ libc.so: malloc + libc.so: memalign + libc.so: realloc + libm.so: matherr ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc ++ld.so: calloc ++ld.so: realloc ++ld.so: free +diff -Nrup a/sysdeps/x86_64/nptl/localplt.data b/sysdeps/x86_64/nptl/localplt.data +--- a/sysdeps/x86_64/nptl/localplt.data 1969-12-31 19:00:00.000000000 -0500 ++++ b/sysdeps/x86_64/nptl/localplt.data 2017-10-22 09:16:39.219285460 -0400 +@@ -0,0 +1,23 @@ ++# See scripts/check-localplt.awk for how this file is processed. ++# PLT use is required for the malloc family and for matherr because ++# users can define their own functions and have library internals call them. ++# Linker in binutils 2.26 and newer consolidates R_X86_64_JUMP_SLOT ++# relocation with R_X86_64_GLOB_DAT relocation against the same symbol. ++libc.so: calloc + RELA R_X86_64_GLOB_DAT ++libc.so: free + RELA R_X86_64_GLOB_DAT ++libc.so: malloc + RELA R_X86_64_GLOB_DAT ++libc.so: memalign + RELA R_X86_64_GLOB_DAT ++libc.so: realloc + RELA R_X86_64_GLOB_DAT ++libm.so: matherr + RELA R_X86_64_GLOB_DAT ++# The dynamic loader uses __libc_memalign internally to allocate aligned ++# TLS storage. The other malloc family of functions are expected to allow ++# user symbol interposition. ++ld.so: __libc_memalign + RELA R_X86_64_GLOB_DAT ++# The dynamic loader needs __tls_get_addr for TLS. ++ld.so: __tls_get_addr + RELA R_X86_64_GLOB_DAT ++# The main malloc is interposed into the dynamic linker, for ++# allocations after the initial link (when dlopen is used). ++ld.so: malloc + RELA R_X86_64_GLOB_DAT ++ld.so: calloc + RELA R_X86_64_GLOB_DAT ++ld.so: realloc + RELA R_X86_64_GLOB_DAT ++ld.so: free + RELA R_X86_64_GLOB_DAT diff --git a/SOURCES/glibc-rh1443236.patch b/SOURCES/glibc-rh1443236.patch new file mode 100644 index 00000000..6a4949d3 --- /dev/null +++ b/SOURCES/glibc-rh1443236.patch @@ -0,0 +1,31 @@ +From 9317ea653afc26402387cac67042f9890af6add2 Mon Sep 17 00:00:00 2001 +From: Bram +Date: Thu, 18 Apr 2013 16:50:49 +0200 +Subject: [PATCH] Fix segmentation fault when LD_LIBRARY_PATH contains only + non-existings paths + +--- + ChangeLog | 6 ++++++ + NEWS | 18 +++++++++--------- + elf/dl-load.c | 6 +++--- + 3 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/elf/dl-load.c b/elf/dl-load.c +index 73174aa..41b91fc 100644 +--- a/elf/dl-load.c ++++ b/elf/dl-load.c +@@ -1889,9 +1889,9 @@ open_path (const char *name, size_t namelen, int mode, + if (sps->malloced) + free (sps->dirs); + +- /* rtld_search_dirs is attribute_relro, therefore avoid writing +- into it. */ +- if (sps != &rtld_search_dirs) ++ /* rtld_search_dirs and env_path_list are attribute_relro, therefore ++ avoid writing into it. */ ++ if (sps != &rtld_search_dirs && sps != &env_path_list) + sps->dirs = (void *) -1; + } + +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1445644.patch b/SOURCES/glibc-rh1445644.patch new file mode 100644 index 00000000..40d7574a --- /dev/null +++ b/SOURCES/glibc-rh1445644.patch @@ -0,0 +1,78 @@ +commit e0ed2fb40a0e29c43cf60addc74741dab15f2e05 +Author: H.J. Lu +Date: Fri Mar 6 04:55:56 2015 -0800 + + Replace __attribute__((visibility("protected"))) + + With copy relocation, address of protected data defined in the shared + library may be external. Compiler shouldn't asssume protected data will + be local. But due to + + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 + + __attribute__((visibility("protected"))) doesn't work correctly, we need + to use asm (".protected xxx") instead. + + * elf/ifuncdep2.c (global): Replace + __attribute__((visibility("protected"))) with + asm (".protected global"). + * elf/ifuncmod1.c (global): Likewise. + * elf/ifuncmod5.c (global): Likewise. + +Index: b/elf/ifuncdep2.c +=================================================================== +--- a/elf/ifuncdep2.c ++++ b/elf/ifuncdep2.c +@@ -2,7 +2,13 @@ + + #include "ifunc-sel.h" + +-int global __attribute__ ((visibility ("protected"))) = -1; ++int global = -1; ++/* Can't use __attribute__((visibility("protected"))) until the GCC bug: ++ ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 ++ ++ is fixed. */ ++asm (".protected global"); + + static int + one (void) +Index: b/elf/ifuncmod1.c +=================================================================== +--- a/elf/ifuncmod1.c ++++ b/elf/ifuncmod1.c +@@ -6,7 +6,13 @@ + */ + #include "ifunc-sel.h" + +-int global __attribute__ ((visibility ("protected"))) = -1; ++int global = -1; ++/* Can't use __attribute__((visibility("protected"))) until the GCC bug: ++ ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 ++ ++ is fixed. */ ++asm (".protected global"); + + static int + one (void) +Index: b/elf/ifuncmod5.c +=================================================================== +--- a/elf/ifuncmod5.c ++++ b/elf/ifuncmod5.c +@@ -1,7 +1,13 @@ + /* Test STT_GNU_IFUNC symbols without direct function call. */ + #include "ifunc-sel.h" + +-int global __attribute__ ((visibility ("protected"))) = -1; ++int global = -1; ++/* Can't use __attribute__((visibility("protected"))) until the GCC bug: ++ ++ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 ++ ++ is fixed. */ ++asm (".protected global"); + + static int + one (void) diff --git a/SOURCES/glibc-rh1445781-1.patch b/SOURCES/glibc-rh1445781-1.patch new file mode 100644 index 00000000..6b7aa387 --- /dev/null +++ b/SOURCES/glibc-rh1445781-1.patch @@ -0,0 +1,49 @@ +commit 3e058c9d7eab6d6361e7cda5ba1394bc1757c9f6 +Author: H.J. Lu +Date: Fri May 22 17:46:42 2015 -0700 + + Don't issue an error if DT_PLTRELSZ is missing + + A shared object doesn't need PLT if there are no PLT relocations. It + shouldn't be an error if DT_PLTRELSZ is missing. + + [BZ #18410] + * elf/dl-reloc.c (_dl_relocate_object): Don't issue an error + for missing DT_PLTRELSZ. + +diff -rup a/elf/dl-reloc.c b/elf/dl-reloc.c +--- a/elf/dl-reloc.c 2017-10-04 16:42:16.000000000 -0400 ++++ b/elf/dl-reloc.c 2017-10-05 17:44:14.486358084 -0400 +@@ -259,21 +259,13 @@ _dl_relocate_object (struct link_map *l, + ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); + + #ifndef PROF +- if (__builtin_expect (consider_profiling, 0)) ++ if (__builtin_expect (consider_profiling, 0) ++ && l->l_info[DT_PLTRELSZ] != NULL) + { + /* Allocate the array which will contain the already found + relocations. If the shared object lacks a PLT (for example + if it only contains lead function) the l_info[DT_PLTRELSZ] + will be NULL. */ +- if (l->l_info[DT_PLTRELSZ] == NULL) +- { +- errstring = N_("%s: no PLTREL found in object %s\n"); +- fatal: +- _dl_fatal_printf (errstring, +- rtld_progname ?: "", +- l->l_name); +- } +- + size_t sizeofrel = l->l_info[DT_PLTREL]->d_un.d_val == DT_RELA + ? sizeof (ElfW(Rela)) + : sizeof (ElfW(Rel)); +@@ -284,7 +276,7 @@ _dl_relocate_object (struct link_map *l, + { + errstring = N_("\ + %s: out of memory to store relocation results for %s\n"); +- goto fatal; ++ _dl_fatal_printf (errstring, rtld_progname, l->l_name); + } + } + #endif diff --git a/SOURCES/glibc-rh1445781-2.patch b/SOURCES/glibc-rh1445781-2.patch new file mode 100644 index 00000000..d9d938c7 --- /dev/null +++ b/SOURCES/glibc-rh1445781-2.patch @@ -0,0 +1,88 @@ +commit 58007e9e68913290b1f4f73afc1055f779a8ed5d +Author: H.J. Lu +Date: Thu May 28 05:06:27 2015 -0700 + + Make sure that calloc is called at least once + + PLT relocations aren't required when -z now used. + + + [BZ #18422] + * Makefile ($(objpfx)tst-audit2): Depend on $(libdl). + ($(objpfx)tst-audit2.out): Also depend on + $(objpfx)tst-auditmod9b.so. + * elf/tst-audit2.c: Include . + (calloc_called): New. + (calloc): Allow to be called more than once. + (do_test): dllopen/dlclose $ORIGIN/tst-auditmod9b.so. + +diff -rup a/elf/Makefile b/elf/Makefile +--- a/elf/Makefile 2017-10-04 16:42:22.000000000 -0400 ++++ b/elf/Makefile 2017-10-05 17:40:38.402451971 -0400 +@@ -1020,7 +1020,8 @@ $(objpfx)tst-dlmopen3.out: $(objpfx)tst- + $(objpfx)tst-audit1.out: $(objpfx)tst-auditmod1.so + tst-audit1-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + +-$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so ++$(objpfx)tst-audit2: $(libdl) ++$(objpfx)tst-audit2.out: $(objpfx)tst-auditmod1.so $(objpfx)tst-auditmod9b.so + tst-audit2-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so + + $(objpfx)tst-audit3: $(objpfx)tst-auditmod3a.so +diff -rup a/elf/tst-audit2.c b/elf/tst-audit2.c +--- a/elf/tst-audit2.c 2017-10-04 16:42:18.000000000 -0400 ++++ b/elf/tst-audit2.c 2017-10-05 17:40:51.570518031 -0400 +@@ -3,26 +3,35 @@ + #include + #include + #include ++#include + + #define MAGIC1 0xabcdef72 + #define MAGIC2 0xd8675309 + static __thread unsigned int magic[] = { MAGIC1, MAGIC2 }; ++static __thread int calloc_called; + + #undef calloc + + /* This calloc definition will be called by the dynamic linker itself. +- We test that it has initialized our TLS block by the time it does so. */ ++ We test that interposed calloc is called by the dynamic loader, and ++ that TLS is fully initialized by then. */ + + void * + calloc (size_t n, size_t m) + { +- if (magic[0] != MAGIC1 || magic[1] != MAGIC2) ++ if (!calloc_called) + { +- printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC1, MAGIC2); +- abort (); ++ /* Allow our calloc to be called more than once. */ ++ calloc_called = 1; ++ if (magic[0] != MAGIC1 || magic[1] != MAGIC2) ++ { ++ printf ("{%x, %x} != {%x, %x}\n", ++ magic[0], magic[1], MAGIC1, MAGIC2); ++ abort (); ++ } ++ magic[0] = MAGIC2; ++ magic[1] = MAGIC1; + } +- magic[0] = MAGIC2; +- magic[1] = MAGIC1; + + n *= m; + void *ptr = malloc (n); +@@ -34,6 +43,11 @@ calloc (size_t n, size_t m) + static int + do_test (void) + { ++ /* Make sure that our calloc is called from the dynamic linker at least ++ once. */ ++ void *h = dlopen("$ORIGIN/tst-auditmod9b.so", RTLD_LAZY); ++ if (h != NULL) ++ dlclose (h); + if (magic[1] != MAGIC1 || magic[0] != MAGIC2) + { + printf ("{%x, %x} != {%x, %x}\n", magic[0], magic[1], MAGIC2, MAGIC1); diff --git a/SOURCES/glibc-rh1447556.patch b/SOURCES/glibc-rh1447556.patch new file mode 100644 index 00000000..0429e2dd --- /dev/null +++ b/SOURCES/glibc-rh1447556.patch @@ -0,0 +1,25 @@ +From 17f487b7afa7cd6c316040f3e6c86dc96b2eec30 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Fri, 17 Mar 2017 15:31:38 -0400 +Subject: [PATCH] Further harden glibc malloc metadata against 1-byte + overflows. + +Additional check for chunk_size == next->prev->chunk_size in unlink() + +2017-03-17 Chris Evans + + * malloc/malloc.c (unlink): Add consistency check between size and + next->prev->size, to further harden against 1-byte overflows. + +diff -rup a/malloc/malloc.c b/malloc/malloc.c +--- a/malloc/malloc.c 2017-08-01 18:11:00.000000000 -0400 ++++ b/malloc/malloc.c 2017-08-01 18:13:07.907438098 -0400 +@@ -1429,6 +1429,8 @@ typedef struct malloc_chunk* mbinptr; + + /* Take a chunk off a bin list */ + #define unlink(AV, P, BK, FD) { \ ++ if (__builtin_expect (chunksize(P) != next_chunk(P)->prev_size, 0)) \ ++ malloc_printerr (check_action, "corrupted size vs. prev_size", P, AV); \ + FD = P->fd; \ + BK = P->bk; \ + if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) { \ diff --git a/SOURCES/glibc-rh1448822.patch b/SOURCES/glibc-rh1448822.patch new file mode 100644 index 00000000..ddbf6268 --- /dev/null +++ b/SOURCES/glibc-rh1448822.patch @@ -0,0 +1,19 @@ +commit e9ff8efb5cb0fd944f4a5c8f03b14dee508cf7e8 +Author: Ryan Cumming +Date: Mon Nov 24 15:14:31 2014 +0100 + + Define CLOCK_TAI on Linux (bug 17608) + +diff --git a/sysdeps/unix/sysv/linux/bits/time.h b/sysdeps/unix/sysv/linux/bits/time.h +index 7805ce7e012256ea..561587ed3c620628 100644 +--- a/sysdeps/unix/sysv/linux/bits/time.h ++++ b/sysdeps/unix/sysv/linux/bits/time.h +@@ -77,6 +77,8 @@ extern long int __sysconf (int); + # define CLOCK_REALTIME_ALARM 8 + /* Like CLOCK_BOOTTIME but also wakes suspended system. */ + # define CLOCK_BOOTTIME_ALARM 9 ++/* Like CLOCK_REALTIME but in International Atomic Time. */ ++# define CLOCK_TAI 11 + + /* Flag to indicate time is absolute. */ + # define TIMER_ABSTIME 1 diff --git a/SOURCES/glibc-rh1452720-1.patch b/SOURCES/glibc-rh1452720-1.patch new file mode 100644 index 00000000..579a1d4d --- /dev/null +++ b/SOURCES/glibc-rh1452720-1.patch @@ -0,0 +1,23 @@ +commit TBD +Author: Florian Weimer +Date: Fri May 19 17:46:47 2017 +0200 + + rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1 programs + +LD_LIBRARY_PATH can only be used to reorder system search paths, which +is not useful functionality. + +Index: glibc-2.17-c758a686/elf/rtld.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/rtld.c ++++ glibc-2.17-c758a686/elf/rtld.c +@@ -2580,7 +2701,8 @@ process_envvars (enum mode *modep) + + case 12: + /* The library search path. */ +- if (memcmp (envline, "LIBRARY_PATH", 12) == 0) ++ if (!__libc_enable_secure ++ && memcmp (envline, "LIBRARY_PATH", 12) == 0) + { + library_path = &envline[13]; + break; diff --git a/SOURCES/glibc-rh1452720-2.patch b/SOURCES/glibc-rh1452720-2.patch new file mode 100644 index 00000000..22a78521 --- /dev/null +++ b/SOURCES/glibc-rh1452720-2.patch @@ -0,0 +1,103 @@ +commit TBD +Author: Florian Weimer +Date: Fri May 19 17:46:47 2017 +0200 + + rtld: Reject overly long LD_PRELOAD path elements + +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -99,6 +99,22 @@ uintptr_t __pointer_chk_guard_local + strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) + #endif + ++/* Check that AT_SECURE=0, or that the passed name does not contain ++ directories and is not overly long. Reject empty names ++ unconditionally. */ ++static bool ++dso_name_valid_for_suid (const char *p) ++{ ++ if (__builtin_expect (INTUSE(__libc_enable_secure), 0)) ++ { ++ /* Ignore pathnames with directories for AT_SECURE=1 ++ programs, and also skip overlong names. */ ++ size_t len = strlen (p); ++ if (len >= NAME_MAX || memchr (p, '/', len) != NULL) ++ return false; ++ } ++ return *p != '\0'; ++} + + /* List of auditing DSOs. */ + static struct audit_list +@@ -880,6 +896,44 @@ static const char *preloadlist attribute + /* Nonzero if information about versions has to be printed. */ + static int version_info attribute_relro; + ++/* The LD_PRELOAD environment variable gives list of libraries ++ separated by white space or colons that are loaded before the ++ executable's dependencies and prepended to the global scope list. ++ (If the binary is running setuid all elements containing a '/' are ++ ignored since it is insecure.) Return the number of preloads ++ performed. */ ++unsigned int ++handle_ld_preload (const char *preloadlist, struct link_map *main_map) ++{ ++ unsigned int npreloads = 0; ++ const char *p = preloadlist; ++ char fname[PATH_MAX]; ++ ++ while (*p != '\0') ++ { ++ /* Split preload list at space/colon. */ ++ size_t len = strcspn (p, " :"); ++ if (len > 0 && len < PATH_MAX) ++ { ++ memcpy (fname, p, len); ++ fname[len] = '\0'; ++ } ++ else ++ fname[0] = '\0'; ++ ++ /* Skip over the substring and the following delimiter. */ ++ p += len; ++ if (*p == ' ' || *p == ':') ++ ++p; ++ ++ if (dso_name_valid_for_suid (fname)) ++ npreloads += do_preload (fname, main_map, "LD_PRELOAD"); ++ } ++ return npreloads; ++} ++ ++ ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1611,23 +1665,8 @@ ERROR: ld.so: object '%s' cannot be load + + if (__builtin_expect (preloadlist != NULL, 0)) + { +- /* The LD_PRELOAD environment variable gives list of libraries +- separated by white space or colons that are loaded before the +- executable's dependencies and prepended to the global scope +- list. If the binary is running setuid all elements +- containing a '/' are ignored since it is insecure. */ +- char *list = strdupa (preloadlist); +- char *p; +- + HP_TIMING_NOW (start); +- +- /* Prevent optimizing strsep. Speed is not important here. */ +- while ((p = (strsep) (&list, " :")) != NULL) +- if (p[0] != '\0' +- && (__builtin_expect (! INTUSE(__libc_enable_secure), 1) +- || strchr (p, '/') == NULL)) +- npreloads += do_preload (p, main_map, "LD_PRELOAD"); +- ++ npreloads += handle_ld_preload (preloadlist, main_map); + HP_TIMING_NOW (stop); + HP_TIMING_DIFF (diff, start, stop); + HP_TIMING_ACCUM_NT (load_time, diff); diff --git a/SOURCES/glibc-rh1452720-3.patch b/SOURCES/glibc-rh1452720-3.patch new file mode 100644 index 00000000..d0ad5d32 --- /dev/null +++ b/SOURCES/glibc-rh1452720-3.patch @@ -0,0 +1,196 @@ +commit TBD +Author: Florian Weimer +Date: Fri May 19 17:46:47 2017 +0200 + + rtld: Reject overly long LD_AUDIT path elements + +Also only process the last LD_AUDIT entry. + +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -116,13 +116,91 @@ dso_name_valid_for_suid (const char *p) + return *p != '\0'; + } + +-/* List of auditing DSOs. */ ++/* LD_AUDIT variable contents. Must be processed before the ++ audit_list below. */ ++const char *audit_list_string; ++ ++/* Cyclic list of auditing DSOs. audit_list->next is the first ++ element. */ + static struct audit_list + { + const char *name; + struct audit_list *next; + } *audit_list; + ++/* Iterator for audit_list_string followed by audit_list. */ ++struct audit_list_iter ++{ ++ /* Tail of audit_list_string still needing processing, or NULL. */ ++ const char *audit_list_tail; ++ ++ /* The list element returned in the previous iteration. NULL before ++ the first element. */ ++ struct audit_list *previous; ++ ++ /* Scratch buffer for returning a name which is part of ++ audit_list_string. */ ++ char fname[PATH_MAX]; ++}; ++ ++/* Initialize an audit list iterator. */ ++static void ++audit_list_iter_init (struct audit_list_iter *iter) ++{ ++ iter->audit_list_tail = audit_list_string; ++ iter->previous = NULL; ++} ++ ++/* Iterate through both audit_list_string and audit_list. */ ++static const char * ++audit_list_iter_next (struct audit_list_iter *iter) ++{ ++ if (iter->audit_list_tail != NULL) ++ { ++ /* First iterate over audit_list_string. */ ++ while (*iter->audit_list_tail != '\0') ++ { ++ /* Split audit list at colon. */ ++ size_t len = strcspn (iter->audit_list_tail, ":"); ++ if (len > 0 && len < PATH_MAX) ++ { ++ memcpy (iter->fname, iter->audit_list_tail, len); ++ iter->fname[len] = '\0'; ++ } ++ else ++ /* Do not return this name to the caller. */ ++ iter->fname[0] = '\0'; ++ ++ /* Skip over the substring and the following delimiter. */ ++ iter->audit_list_tail += len; ++ if (*iter->audit_list_tail == ':') ++ ++iter->audit_list_tail; ++ ++ /* If the name is valid, return it. */ ++ if (dso_name_valid_for_suid (iter->fname)) ++ return iter->fname; ++ /* Otherwise, wrap around and try the next name. */ ++ } ++ /* Fall through to the procesing of audit_list. */ ++ } ++ ++ if (iter->previous == NULL) ++ { ++ if (audit_list == NULL) ++ /* No pre-parsed audit list. */ ++ return NULL; ++ /* Start of audit list. The first list element is at ++ audit_list->next (cyclic list). */ ++ iter->previous = audit_list->next; ++ return iter->previous->name; ++ } ++ if (iter->previous == audit_list) ++ /* Cyclic list wrap-around. */ ++ return NULL; ++ iter->previous = iter->previous->next; ++ return iter->previous->name; ++} ++ + /* Set nonzero during loading and initialization of executable and + libraries, cleared before the executable's entry point runs. This + must not be initialized to nonzero, because the unused dynamic +@@ -1441,11 +1519,13 @@ of this helper program; chances are you + GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); + + /* If we have auditing DSOs to load, do it now. */ +- if (__builtin_expect (audit_list != NULL, 0)) ++ bool need_security_init = true; ++ if (__builtin_expect (audit_list != NULL, 0) ++ || __builtin_expect (audit_list_string != NULL, 0)) + { +- /* Iterate over all entries in the list. The order is important. */ + struct audit_ifaces *last_audit = NULL; +- struct audit_list *al = audit_list->next; ++ struct audit_list_iter al_iter; ++ audit_list_iter_init (&al_iter); + + /* Since we start using the auditing DSOs right away we need to + initialize the data structures now. */ +@@ -1456,9 +1536,14 @@ of this helper program; chances are you + use different values (especially the pointer guard) and will + fail later on. */ + security_init (); ++ need_security_init = false; + +- do ++ while (true) + { ++ const char *name = audit_list_iter_next (&al_iter); ++ if (name == NULL) ++ break; ++ + int tls_idx = GL(dl_tls_max_dtv_idx); + + /* Now it is time to determine the layout of the static TLS +@@ -1467,7 +1552,7 @@ of this helper program; chances are you + no DF_STATIC_TLS bit is set. The reason is that we know + glibc will use the static model. */ + struct dlmopen_args dlmargs; +- dlmargs.fname = al->name; ++ dlmargs.fname = name; + dlmargs.map = NULL; + + const char *objname; +@@ -1480,7 +1565,7 @@ of this helper program; chances are you + not_loaded: + _dl_error_printf ("\ + ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", +- al->name, err_str); ++ name, err_str); + if (malloced) + free ((char *) err_str); + } +@@ -1584,10 +1669,7 @@ ERROR: ld.so: object '%s' cannot be load + goto not_loaded; + } + } +- +- al = al->next; + } +- while (al != audit_list->next); + + /* If we have any auditing modules, announce that we already + have two objects loaded. */ +@@ -1851,7 +1933,7 @@ ERROR: ld.so: object '%s' cannot be load + if (tcbp == NULL) + tcbp = init_tls (); + +- if (__builtin_expect (audit_list == NULL, 1)) ++ if (need_security_init) + /* Initialize security features. But only if we have not done it + earlier. */ + security_init (); +@@ -2495,9 +2577,7 @@ process_dl_audit (char *str) + char *p; + + while ((p = (strsep) (&str, ":")) != NULL) +- if (p[0] != '\0' +- && (__builtin_expect (! INTUSE(__libc_enable_secure), 1) +- || strchr (p, '/') == NULL)) ++ if (dso_name_valid_for_suid (p)) + { + /* This is using the local malloc, not the system malloc. The + memory can never be freed. */ +@@ -2561,7 +2641,7 @@ process_envvars (enum mode *modep) + break; + } + if (memcmp (envline, "AUDIT", 5) == 0) +- process_dl_audit (&envline[6]); ++ audit_list_string = &envline[6]; + break; + + case 7: diff --git a/SOURCES/glibc-rh1452720-4.patch b/SOURCES/glibc-rh1452720-4.patch new file mode 100644 index 00000000..09446fb6 --- /dev/null +++ b/SOURCES/glibc-rh1452720-4.patch @@ -0,0 +1,51 @@ +Partial backport (without the test) of: + +commit 1c1243b6fc33c029488add276e56570a07803bfd +Author: Siddhesh Poyarekar +Date: Tue Mar 7 20:52:04 2017 +0530 + + Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug #21209) + + The LD_HWCAP_MASK environment variable may alter the selection of + function variants for some architectures. For AT_SECURE process it + means that if an outdated routine has a bug that would otherwise not + affect newer platforms by default, LD_HWCAP_MASK will allow that bug + to be exploited. + + To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid + binaries. + + [BZ #21209] + * elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for + AT_SECURE processes. + * sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK. + * elf/tst-env-setuid.c (test_parent): Test LD_HWCAP_MASK. + (test_child): Likewise. + * elf/Makefile (tst-env-setuid-ENV): Add LD_HWCAP_MASK. + +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2688,7 +2688,8 @@ process_envvars (enum mode *modep) + + case 10: + /* Mask for the important hardware capabilities. */ +- if (memcmp (envline, "HWCAP_MASK", 10) == 0) ++ if (!__libc_enable_secure ++ && memcmp (envline, "HWCAP_MASK", 10) == 0) + GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, + 0, 0); + break; +Index: b/sysdeps/generic/unsecvars.h +=================================================================== +--- a/sysdeps/generic/unsecvars.h ++++ b/sysdeps/generic/unsecvars.h +@@ -9,6 +9,7 @@ + "LD_DEBUG\0" \ + "LD_DEBUG_OUTPUT\0" \ + "LD_DYNAMIC_WEAK\0" \ ++ "LD_HWCAP_MASK\0" \ + "LD_LIBRARY_PATH\0" \ + "LD_ORIGIN_PATH\0" \ + "LD_PRELOAD\0" \ diff --git a/SOURCES/glibc-rh1452721-1.patch b/SOURCES/glibc-rh1452721-1.patch new file mode 100644 index 00000000..579a1d4d --- /dev/null +++ b/SOURCES/glibc-rh1452721-1.patch @@ -0,0 +1,23 @@ +commit TBD +Author: Florian Weimer +Date: Fri May 19 17:46:47 2017 +0200 + + rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1 programs + +LD_LIBRARY_PATH can only be used to reorder system search paths, which +is not useful functionality. + +Index: glibc-2.17-c758a686/elf/rtld.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/rtld.c ++++ glibc-2.17-c758a686/elf/rtld.c +@@ -2580,7 +2701,8 @@ process_envvars (enum mode *modep) + + case 12: + /* The library search path. */ +- if (memcmp (envline, "LIBRARY_PATH", 12) == 0) ++ if (!__libc_enable_secure ++ && memcmp (envline, "LIBRARY_PATH", 12) == 0) + { + library_path = &envline[13]; + break; diff --git a/SOURCES/glibc-rh1452721-2.patch b/SOURCES/glibc-rh1452721-2.patch new file mode 100644 index 00000000..22a78521 --- /dev/null +++ b/SOURCES/glibc-rh1452721-2.patch @@ -0,0 +1,103 @@ +commit TBD +Author: Florian Weimer +Date: Fri May 19 17:46:47 2017 +0200 + + rtld: Reject overly long LD_PRELOAD path elements + +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -99,6 +99,22 @@ uintptr_t __pointer_chk_guard_local + strong_alias (__pointer_chk_guard_local, __pointer_chk_guard) + #endif + ++/* Check that AT_SECURE=0, or that the passed name does not contain ++ directories and is not overly long. Reject empty names ++ unconditionally. */ ++static bool ++dso_name_valid_for_suid (const char *p) ++{ ++ if (__builtin_expect (INTUSE(__libc_enable_secure), 0)) ++ { ++ /* Ignore pathnames with directories for AT_SECURE=1 ++ programs, and also skip overlong names. */ ++ size_t len = strlen (p); ++ if (len >= NAME_MAX || memchr (p, '/', len) != NULL) ++ return false; ++ } ++ return *p != '\0'; ++} + + /* List of auditing DSOs. */ + static struct audit_list +@@ -880,6 +896,44 @@ static const char *preloadlist attribute + /* Nonzero if information about versions has to be printed. */ + static int version_info attribute_relro; + ++/* The LD_PRELOAD environment variable gives list of libraries ++ separated by white space or colons that are loaded before the ++ executable's dependencies and prepended to the global scope list. ++ (If the binary is running setuid all elements containing a '/' are ++ ignored since it is insecure.) Return the number of preloads ++ performed. */ ++unsigned int ++handle_ld_preload (const char *preloadlist, struct link_map *main_map) ++{ ++ unsigned int npreloads = 0; ++ const char *p = preloadlist; ++ char fname[PATH_MAX]; ++ ++ while (*p != '\0') ++ { ++ /* Split preload list at space/colon. */ ++ size_t len = strcspn (p, " :"); ++ if (len > 0 && len < PATH_MAX) ++ { ++ memcpy (fname, p, len); ++ fname[len] = '\0'; ++ } ++ else ++ fname[0] = '\0'; ++ ++ /* Skip over the substring and the following delimiter. */ ++ p += len; ++ if (*p == ' ' || *p == ':') ++ ++p; ++ ++ if (dso_name_valid_for_suid (fname)) ++ npreloads += do_preload (fname, main_map, "LD_PRELOAD"); ++ } ++ return npreloads; ++} ++ ++ ++ + static void + dl_main (const ElfW(Phdr) *phdr, + ElfW(Word) phnum, +@@ -1611,23 +1665,8 @@ ERROR: ld.so: object '%s' cannot be load + + if (__builtin_expect (preloadlist != NULL, 0)) + { +- /* The LD_PRELOAD environment variable gives list of libraries +- separated by white space or colons that are loaded before the +- executable's dependencies and prepended to the global scope +- list. If the binary is running setuid all elements +- containing a '/' are ignored since it is insecure. */ +- char *list = strdupa (preloadlist); +- char *p; +- + HP_TIMING_NOW (start); +- +- /* Prevent optimizing strsep. Speed is not important here. */ +- while ((p = (strsep) (&list, " :")) != NULL) +- if (p[0] != '\0' +- && (__builtin_expect (! INTUSE(__libc_enable_secure), 1) +- || strchr (p, '/') == NULL)) +- npreloads += do_preload (p, main_map, "LD_PRELOAD"); +- ++ npreloads += handle_ld_preload (preloadlist, main_map); + HP_TIMING_NOW (stop); + HP_TIMING_DIFF (diff, start, stop); + HP_TIMING_ACCUM_NT (load_time, diff); diff --git a/SOURCES/glibc-rh1452721-3.patch b/SOURCES/glibc-rh1452721-3.patch new file mode 100644 index 00000000..d0ad5d32 --- /dev/null +++ b/SOURCES/glibc-rh1452721-3.patch @@ -0,0 +1,196 @@ +commit TBD +Author: Florian Weimer +Date: Fri May 19 17:46:47 2017 +0200 + + rtld: Reject overly long LD_AUDIT path elements + +Also only process the last LD_AUDIT entry. + +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -116,13 +116,91 @@ dso_name_valid_for_suid (const char *p) + return *p != '\0'; + } + +-/* List of auditing DSOs. */ ++/* LD_AUDIT variable contents. Must be processed before the ++ audit_list below. */ ++const char *audit_list_string; ++ ++/* Cyclic list of auditing DSOs. audit_list->next is the first ++ element. */ + static struct audit_list + { + const char *name; + struct audit_list *next; + } *audit_list; + ++/* Iterator for audit_list_string followed by audit_list. */ ++struct audit_list_iter ++{ ++ /* Tail of audit_list_string still needing processing, or NULL. */ ++ const char *audit_list_tail; ++ ++ /* The list element returned in the previous iteration. NULL before ++ the first element. */ ++ struct audit_list *previous; ++ ++ /* Scratch buffer for returning a name which is part of ++ audit_list_string. */ ++ char fname[PATH_MAX]; ++}; ++ ++/* Initialize an audit list iterator. */ ++static void ++audit_list_iter_init (struct audit_list_iter *iter) ++{ ++ iter->audit_list_tail = audit_list_string; ++ iter->previous = NULL; ++} ++ ++/* Iterate through both audit_list_string and audit_list. */ ++static const char * ++audit_list_iter_next (struct audit_list_iter *iter) ++{ ++ if (iter->audit_list_tail != NULL) ++ { ++ /* First iterate over audit_list_string. */ ++ while (*iter->audit_list_tail != '\0') ++ { ++ /* Split audit list at colon. */ ++ size_t len = strcspn (iter->audit_list_tail, ":"); ++ if (len > 0 && len < PATH_MAX) ++ { ++ memcpy (iter->fname, iter->audit_list_tail, len); ++ iter->fname[len] = '\0'; ++ } ++ else ++ /* Do not return this name to the caller. */ ++ iter->fname[0] = '\0'; ++ ++ /* Skip over the substring and the following delimiter. */ ++ iter->audit_list_tail += len; ++ if (*iter->audit_list_tail == ':') ++ ++iter->audit_list_tail; ++ ++ /* If the name is valid, return it. */ ++ if (dso_name_valid_for_suid (iter->fname)) ++ return iter->fname; ++ /* Otherwise, wrap around and try the next name. */ ++ } ++ /* Fall through to the procesing of audit_list. */ ++ } ++ ++ if (iter->previous == NULL) ++ { ++ if (audit_list == NULL) ++ /* No pre-parsed audit list. */ ++ return NULL; ++ /* Start of audit list. The first list element is at ++ audit_list->next (cyclic list). */ ++ iter->previous = audit_list->next; ++ return iter->previous->name; ++ } ++ if (iter->previous == audit_list) ++ /* Cyclic list wrap-around. */ ++ return NULL; ++ iter->previous = iter->previous->next; ++ return iter->previous->name; ++} ++ + /* Set nonzero during loading and initialization of executable and + libraries, cleared before the executable's entry point runs. This + must not be initialized to nonzero, because the unused dynamic +@@ -1441,11 +1519,13 @@ of this helper program; chances are you + GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); + + /* If we have auditing DSOs to load, do it now. */ +- if (__builtin_expect (audit_list != NULL, 0)) ++ bool need_security_init = true; ++ if (__builtin_expect (audit_list != NULL, 0) ++ || __builtin_expect (audit_list_string != NULL, 0)) + { +- /* Iterate over all entries in the list. The order is important. */ + struct audit_ifaces *last_audit = NULL; +- struct audit_list *al = audit_list->next; ++ struct audit_list_iter al_iter; ++ audit_list_iter_init (&al_iter); + + /* Since we start using the auditing DSOs right away we need to + initialize the data structures now. */ +@@ -1456,9 +1536,14 @@ of this helper program; chances are you + use different values (especially the pointer guard) and will + fail later on. */ + security_init (); ++ need_security_init = false; + +- do ++ while (true) + { ++ const char *name = audit_list_iter_next (&al_iter); ++ if (name == NULL) ++ break; ++ + int tls_idx = GL(dl_tls_max_dtv_idx); + + /* Now it is time to determine the layout of the static TLS +@@ -1467,7 +1552,7 @@ of this helper program; chances are you + no DF_STATIC_TLS bit is set. The reason is that we know + glibc will use the static model. */ + struct dlmopen_args dlmargs; +- dlmargs.fname = al->name; ++ dlmargs.fname = name; + dlmargs.map = NULL; + + const char *objname; +@@ -1480,7 +1565,7 @@ of this helper program; chances are you + not_loaded: + _dl_error_printf ("\ + ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", +- al->name, err_str); ++ name, err_str); + if (malloced) + free ((char *) err_str); + } +@@ -1584,10 +1669,7 @@ ERROR: ld.so: object '%s' cannot be load + goto not_loaded; + } + } +- +- al = al->next; + } +- while (al != audit_list->next); + + /* If we have any auditing modules, announce that we already + have two objects loaded. */ +@@ -1851,7 +1933,7 @@ ERROR: ld.so: object '%s' cannot be load + if (tcbp == NULL) + tcbp = init_tls (); + +- if (__builtin_expect (audit_list == NULL, 1)) ++ if (need_security_init) + /* Initialize security features. But only if we have not done it + earlier. */ + security_init (); +@@ -2495,9 +2577,7 @@ process_dl_audit (char *str) + char *p; + + while ((p = (strsep) (&str, ":")) != NULL) +- if (p[0] != '\0' +- && (__builtin_expect (! INTUSE(__libc_enable_secure), 1) +- || strchr (p, '/') == NULL)) ++ if (dso_name_valid_for_suid (p)) + { + /* This is using the local malloc, not the system malloc. The + memory can never be freed. */ +@@ -2561,7 +2641,7 @@ process_envvars (enum mode *modep) + break; + } + if (memcmp (envline, "AUDIT", 5) == 0) +- process_dl_audit (&envline[6]); ++ audit_list_string = &envline[6]; + break; + + case 7: diff --git a/SOURCES/glibc-rh1452721-4.patch b/SOURCES/glibc-rh1452721-4.patch new file mode 100644 index 00000000..09446fb6 --- /dev/null +++ b/SOURCES/glibc-rh1452721-4.patch @@ -0,0 +1,51 @@ +Partial backport (without the test) of: + +commit 1c1243b6fc33c029488add276e56570a07803bfd +Author: Siddhesh Poyarekar +Date: Tue Mar 7 20:52:04 2017 +0530 + + Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug #21209) + + The LD_HWCAP_MASK environment variable may alter the selection of + function variants for some architectures. For AT_SECURE process it + means that if an outdated routine has a bug that would otherwise not + affect newer platforms by default, LD_HWCAP_MASK will allow that bug + to be exploited. + + To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid + binaries. + + [BZ #21209] + * elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for + AT_SECURE processes. + * sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK. + * elf/tst-env-setuid.c (test_parent): Test LD_HWCAP_MASK. + (test_child): Likewise. + * elf/Makefile (tst-env-setuid-ENV): Add LD_HWCAP_MASK. + +Index: b/elf/rtld.c +=================================================================== +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -2688,7 +2688,8 @@ process_envvars (enum mode *modep) + + case 10: + /* Mask for the important hardware capabilities. */ +- if (memcmp (envline, "HWCAP_MASK", 10) == 0) ++ if (!__libc_enable_secure ++ && memcmp (envline, "HWCAP_MASK", 10) == 0) + GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, + 0, 0); + break; +Index: b/sysdeps/generic/unsecvars.h +=================================================================== +--- a/sysdeps/generic/unsecvars.h ++++ b/sysdeps/generic/unsecvars.h +@@ -9,6 +9,7 @@ + "LD_DEBUG\0" \ + "LD_DEBUG_OUTPUT\0" \ + "LD_DYNAMIC_WEAK\0" \ ++ "LD_HWCAP_MASK\0" \ + "LD_LIBRARY_PATH\0" \ + "LD_ORIGIN_PATH\0" \ + "LD_PRELOAD\0" \ diff --git a/SOURCES/glibc-rh1457177-1.patch b/SOURCES/glibc-rh1457177-1.patch new file mode 100644 index 00000000..780964f3 --- /dev/null +++ b/SOURCES/glibc-rh1457177-1.patch @@ -0,0 +1,158 @@ +commit 38f3458175ecf7c3588bd5b6e465f4d9205fbe1c +Author: Adhemerval Zanella +Date: Wed Jan 8 05:10:41 2014 -0600 + + PowerPC: remove wrong truncl implementation for PowerPC64 + + The truncl assembly implementation (sysdeps/powerpc/powerpc64/fpu/s_truncl.S) + returns wrong results for some inputs where first double is a exact integer + and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_truncl.c instead it fixes tgammal + issues regarding wrong result sign. + +Index: b/sysdeps/ieee754/ldbl-128ibm/s_truncl.c +=================================================================== +--- a/sysdeps/ieee754/ldbl-128ibm/s_truncl.c ++++ b/sysdeps/ieee754/ldbl-128ibm/s_truncl.c +@@ -17,9 +17,6 @@ + License along with the GNU C Library; if not, see + . */ + +-/* This has been coded in assembler because GCC makes such a mess of it +- when it's coded in C. */ +- + #include + #include + #include +Index: b/sysdeps/powerpc/powerpc64/fpu/s_truncl.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_truncl.S ++++ /dev/null +@@ -1,120 +0,0 @@ +-/* long double trunc function. +- IBM extended format long double version. +- Copyright (C) 2004, 2006 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +-.LC1: /* 0.5 */ +- .tc FD_3fe00000_0[TC],0x3fe0000000000000 +- .section ".text" +- +-/* long double [fp1,fp2] truncl (long double x [fp1,fp2]) */ +- +-ENTRY (__truncl) +- mffs fp11 /* Save current FPU rounding mode. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fabs fp9,fp2 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- ble- cr6,.L1 +- fneg fp2,fp12 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */ +-.L0: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +-.L1: +- fneg fp2,fp12 +- bge- cr6,.L0 /* if (x < 0.0) */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */ +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. In this case we have to round the low +- double and handle any adjustment to the high double that may be +- caused by rounding (up). This is complicated by the fact that the +- high double may already be rounded and the low double may have the +- opposite sign to compensate.This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = rint(x1); +- y_high = x0 + r1; +- y_low = x0 - y_high + r1; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ +- bgelr- cr7 /* return x; */ +- beqlr- cr0 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- +- bng- cr6,.L6 /* if (x > 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- fadd fp8,fp8,fp8 /* tau++; Make tau even */ +- bng cr5,.L4 /* if (x_low > 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L5 +-.L4: /* if (x_low < 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L5: +- fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L9 +-.L6: /* if (x < 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- fadd fp8,fp8,fp8 /* tau++; Make tau even */ +- bnl cr5,.L7 /* if (x_low < 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L8 +-.L7: /* if (x_low > 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L8: +- fsub fp5,fp4,fp13 /* r1-= TWO52; */ +- fadd fp5,fp5,fp13 /* r1+= TWO52; */ +-.L9: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ +- fadd fp2,fp2,fp5 +- blr +-END (__truncl) +- +-long_double_symbol (libm, __truncl, truncl) diff --git a/SOURCES/glibc-rh1457177-2.patch b/SOURCES/glibc-rh1457177-2.patch new file mode 100644 index 00000000..0b9722b2 --- /dev/null +++ b/SOURCES/glibc-rh1457177-2.patch @@ -0,0 +1,179 @@ +Backport of this upstream commit (with libm-test.inc adjustments): + +commit 374f7f61214967bb4e2257695aeeeecc2a77f369 +Author: Adhemerval Zanella +Date: Fri Mar 14 07:35:43 2014 -0500 + + PowerPC: remove wrong ceill implementation for PowerPC64 + + The ceill assembly implementation (sysdeps/powerpc/powerpc64/fpu/s_ceill.S) + returns wrong results for some inputs where first double is a exact + integer and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_ceill.c instead fixes the failing math. + + Fixes BZ#16701. + +Index: b/math/libm-test.inc +=================================================================== +--- a/math/libm-test.inc ++++ b/math/libm-test.inc +@@ -2241,6 +2241,15 @@ ceil_test (void) + TEST_f_f (ceil, -72057594037927936.75L, -72057594037927936.0L); + TEST_f_f (ceil, -72057594037927937.5L, -72057594037927937.0L); + ++ /* Check cases where first double is a exact integer higher than 2^52 and ++ the precision is determined by second long double for IBM long double. */ ++ TEST_f_f (ceil, 34503599627370498.515625L, 34503599627370499.0L); ++ TEST_f_f (ceil, -34503599627370498.515625L, -34503599627370498.0L); ++# if LDBL_MANT_DIG >= 106 ++ TEST_f_f (ceil, 1192568192774434123539907640624.484375L, 1192568192774434123539907640625.0L); ++ TEST_f_f (ceil, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L); ++# endif ++ + TEST_f_f (ceil, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L); + TEST_f_f (ceil, 10141204801825835211973625643008.25L, 10141204801825835211973625643009.0L); + TEST_f_f (ceil, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L); +Index: b/sysdeps/powerpc/powerpc64/fpu/s_ceill.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_ceill.S ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* s_ceill.S IBM extended format long double version. +- Copyright (C) 2004, 2006 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +- +- .section ".text" +- +-/* long double [fp1,fp2] ceill (long double x [fp1,fp2]) +- IEEE 1003.1 ceil function. +- +- PowerPC64 long double uses the IBM extended format which is +- represented two 64-floating point double values. The values are +- non-overlapping giving an effective precision of 106 bits. The first +- double contains the high order bits of mantisa and is always ceiled +- to represent a normal ceiling of long double to double. Since the +- long double value is sum of the high and low values, the low double +- normally has the opposite sign to compensate for the this ceiling. +- +- For long double there are two cases: +- 1) |x| < 2**52, all the integer bits are in the high double. +- ceil the high double and set the low double to -0.0. +- 2) |x| >= 2**52, ceiling involves both doubles. +- See the comment before lable .L2 for details. +- */ +- +-ENTRY (__ceill) +- mffs fp11 /* Save current FPU rounding mode. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fabs fp9,fp2 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- fneg fp2,fp12 +- ble- cr6,.L1 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) */ +-.L0: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr /* x = 0.0; */ +-.L1: +- bge- cr6,.L0 /* if (x < 0.0) */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fcmpu cr5,fp1,fp12 /* if (x > 0.0) */ +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fnabs fp1,fp1 /* if (x == 0.0) */ +- blr /* x = -0.0; */ +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. In this case we have to round the low +- double and handle any adjustment to the high double that may be +- caused by rounding (up). This is complicated by the fact that the +- high double may already be rounded and the low double may have the +- opposite sign to compensate.This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = rint(x1); +- y_high = x0 + r1; +- y_low = x0 - y_high + r1; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ +- bgelr- cr7 /* return x; */ +- beqlr- cr0 +- mtfsfi 7,2 /* Set rounding mode toward +inf. */ +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- +- bng- cr6,.L6 /* if (x > 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bng cr5,.L4 /* if (x_low > 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L5 +-.L4: /* if (x_low < 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L5: +- fadd fp5,fp4,fp13 /* r1 = r1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L9 +-.L6: /* if (x < 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bnl cr5,.L7 /* if (x_low < 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L8 +-.L7: /* if (x_low > 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L8: +- fsub fp5,fp4,fp13 /* r1-= TWO52; */ +- fadd fp5,fp5,fp13 /* r1+= TWO52; */ +-.L9: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ +- fadd fp2,fp2,fp5 +- blr +-END (__ceill) +- +-long_double_symbol (libm, __ceill, ceill) diff --git a/SOURCES/glibc-rh1457177-3.patch b/SOURCES/glibc-rh1457177-3.patch new file mode 100644 index 00000000..41c10375 --- /dev/null +++ b/SOURCES/glibc-rh1457177-3.patch @@ -0,0 +1,163 @@ +Backport of this upstream commit (with libm-test.inc adjustments): + +commit 98fb27a373f37554232e0060eef1a5bb00a07eb0 +Author: Adhemerval Zanella +Date: Fri Mar 14 12:27:52 2014 -0500 + + PowerPC: remove wrong nearbyintl implementation for PPC64 + + The nearbyintl assembly implementation + (sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S) + returns wrong results for some inputs where first double is a exact + integer and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c instead fixes the failing + math. + + Fixes BZ#16706. + +Index: b/math/libm-test.inc +=================================================================== +--- a/math/libm-test.inc ++++ b/math/libm-test.inc +@@ -7619,6 +7619,16 @@ nearbyint_test (void) + TEST_f_f (nearbyint, -562949953421312.75, -562949953421313.0); + TEST_f_f (nearbyint, -1125899906842624.75, -1125899906842625.0); + #endif ++#ifdef TEST_LDOUBLE ++ /* Check cases where first double is a exact integer higher than 2^52 and ++ the precision is determined by second long double for IBM long double. */ ++ TEST_f_f (nearbyint, 34503599627370498.515625L, 34503599627370499.0L); ++ TEST_f_f (nearbyint, -34503599627370498.515625L, -34503599627370499.0L); ++# if LDBL_MANT_DIG >= 106 ++ TEST_f_f (nearbyint, 1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L); ++ TEST_f_f (nearbyint, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L); ++# endif ++#endif + + END (nearbyint); + } +Index: b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S ++++ /dev/null +@@ -1,113 +0,0 @@ +-/* nearbyint long double. +- IBM extended format long double version. +- Copyright (C) 2004, 2006 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +- .section ".text" +- +-/* long double [fp1,fp2] nearbyintl (long double x [fp1,fp2]) +- IEEE 1003.1 nearbyintl function. nearbyintl is simular to the rintl +- but does raise the "inexact" exception. This implementation is +- based on rintl but explicitly maskes the inexact exception on entry +- and clears any pending inexact before restoring the exception mask +- on exit. +- +- PowerPC64 long double uses the IBM extended format which is +- represented two 64-floating point double values. The values are +- non-overlapping giving an effective precision of 106 bits. The first +- double contains the high order bits of mantisa and is always rounded +- to represent a normal rounding of long double to double. Since the +- long double value is sum of the high and low values, the low double +- normally has the opposite sign to compensate for the this rounding. +- +- For long double there are two cases: +- 1) |x| < 2**52, all the integer bits are in the high double. +- floor the high double and set the low double to -0.0. +- 2) |x| >= 2**52, Rounding involves both doubles. +- See the comment before lable .L2 for details. +- */ +-ENTRY (__nearbyintl) +- mffs fp11 /* Save current FPSCR. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- mtfsb0 28 /* Disable "inexact" exceptions. */ +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fabs fp9,fp2 +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- fmr fp2,fp12 +- bng- cr6,.L4 +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- b .L9 +-.L4: +- bnl- cr6,.L9 /* if (x < 0.0) */ +- fsub fp1,fp13,fp1 /* x = TWO52 - x; */ +- fsub fp0,fp1,fp13 /* x = - (x - TWO52); */ +- fneg fp1,fp0 +-.L9: +- mtfsb0 6 /* Clear any pending "inexact" exceptions. */ +- mtfsf 0x01,fp11 /* restore exception mask. */ +- blr +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = nearbyint(x1); +- y_high = x0 + r1; +- y_low = r1 - tau; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- bge- cr7,.L9 /* return x; */ +- beq- cr0,.L9 +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +- +- fcmpu cr6,fp4,fp12 /* if (x1 > 0.0) */ +- bng- cr6,.L8 +- fadd fp5,fp4,fp13 /* r1 = x1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L6 +-.L8: +- fmr fp5,fp4 +- bge- cr6,.L6 /* if (x1 < 0.0) */ +- fsub fp5,fp13,fp4 /* r1 = TWO52 - x1; */ +- fsub fp0,fp5,fp13 /* r1 = - (r1 - TWO52); */ +- fneg fp5,fp0 +-.L6: +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp5,fp8 /* y_low = r1 - tau; */ +- b .L9 +-END (__nearbyintl) +- +-long_double_symbol (libm, __nearbyintl, nearbyintl) diff --git a/SOURCES/glibc-rh1457177-4.patch b/SOURCES/glibc-rh1457177-4.patch new file mode 100644 index 00000000..b2b65ed2 --- /dev/null +++ b/SOURCES/glibc-rh1457177-4.patch @@ -0,0 +1,180 @@ +Backport of this upstream commit (with libm-test.inc adjustments): + +commit c7de50250367167d8c9f35594b264f6a0af8dd0c +Author: Adhemerval Zanella +Date: Fri Mar 14 12:49:45 2014 -0500 + + PowerPC: remove wrong roundl implementation for PowerPC64 + + The roundl assembly implementation + (sysdeps/powerpc/powerpc64/fpu/s_roundl.S) + returns wrong results for some inputs where first double is a exact + integer and the precision is determined by second long double. + + Checking on implementation comments and history, I am very confident the + assembly implementation was based on a version before commit + 5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in + long double (ldbl-128ibm) rounding functions in glibc-2.4). + + By just removing the implementation and make the build select + sysdeps/ieee754/ldbl-128ibm/s_roundl.c instead fixes the failing math. + + This fixes 16707. + +Index: b/math/libm-test.inc +=================================================================== +--- a/math/libm-test.inc ++++ b/math/libm-test.inc +@@ -9268,6 +9268,15 @@ round_test (void) + TEST_f_f (round, -72057594037927936.75L, -72057594037927937.0L); + TEST_f_f (round, -72057594037927937.5L, -72057594037927938.0L); + ++ /* Check cases where first double is a exact integer higher than 2^52 and ++ the precision is determined by second long double for IBM long double. */ ++ TEST_f_f (round, 34503599627370498.515625L, 34503599627370499.0L); ++ TEST_f_f (round, -34503599627370498.515625L, -34503599627370499.0L); ++# if LDBL_MANT_DIG >= 106 ++ TEST_f_f (round, 1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L); ++ TEST_f_f (round, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L); ++# endif ++ + TEST_f_f (round, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L); + TEST_f_f (round, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L); + TEST_f_f (round, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L); +Index: b/sysdeps/powerpc/powerpc64/fpu/s_roundl.S +=================================================================== +--- a/sysdeps/powerpc/powerpc64/fpu/s_roundl.S ++++ /dev/null +@@ -1,132 +0,0 @@ +-/* long double round function. +- IBM extended format long double version. +- Copyright (C) 2004, 2006 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +- +- .section ".toc","aw" +-.LC0: /* 2**52 */ +- .tc FD_43300000_0[TC],0x4330000000000000 +-.LC1: /* 0.5 */ +- .tc FD_3fe00000_0[TC],0x3fe0000000000000 +- .section ".text" +- +-/* long double [fp1,fp2] roundl (long double x [fp1,fp2]) +- IEEE 1003.1 round function. IEEE specifies "round to the nearest +- integer value, rounding halfway cases away from zero, regardless of +- the current rounding mode." However PowerPC Architecture defines +- "Round to Nearest" as "Choose the best approximation. In case of a +- tie, choose the one that is even (least significant bit o).". +- So we can't use the PowerPC "Round to Nearest" mode. Instead we set +- "Round toward Zero" mode and round by adding +-0.5 before rounding +- to the integer value. */ +- +-ENTRY (__roundl) +- mffs fp11 /* Save current FPU rounding mode. */ +- lfd fp13,.LC0@toc(2) +- fabs fp0,fp1 +- fabs fp9,fp2 +- fsub fp12,fp13,fp13 /* generate 0.0 */ +- fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ +- fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnl- cr7,.L2 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- lfd fp10,.LC1@toc(2) +- ble- cr6,.L1 +- fneg fp2,fp12 +- fadd fp1,fp1,fp10 /* x+= 0.5; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fsub fp1,fp1,fp13 /* x-= TWO52; */ +- fabs fp1,fp1 /* if (x == 0.0) x = 0.0; */ +-.L0: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +-.L1: +- fsub fp9,fp1,fp10 /* x-= 0.5; */ +- fneg fp2,fp12 +- bge- cr6,.L0 /* if (x < 0.0) */ +- fsub fp1,fp9,fp13 /* x-= TWO52; */ +- fadd fp1,fp1,fp13 /* x+= TWO52; */ +- fnabs fp1,fp1 /* if (x == 0.0) x = -0.0; */ +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- blr +- +-/* The high double is > TWO52 so we need to round the low double and +- perhaps the high double. In this case we have to round the low +- double and handle any adjustment to the high double that may be +- caused by rounding (up). This is complicated by the fact that the +- high double may already be rounded and the low double may have the +- opposite sign to compensate.This gets a bit tricky so we use the +- following algorithm: +- +- tau = floor(x_high/TWO52); +- x0 = x_high - tau; +- x1 = x_low + tau; +- r1 = rint(x1); +- y_high = x0 + r1; +- y_low = x0 - y_high + r1; +- return y; */ +-.L2: +- fcmpu cr7,fp9,fp13 /* if (|x_low| > TWO52) */ +- fcmpu cr0,fp9,fp12 /* || (|x_low| == 0.0) */ +- fcmpu cr5,fp2,fp12 /* if (x_low > 0.0) */ +- lfd fp10,.LC1@toc(2) +- bgelr- cr7 /* return x; */ +- beqlr- cr0 +- mtfsfi 7,1 /* Set rounding mode toward 0. */ +- fdiv fp8,fp1,fp13 /* x_high/TWO52 */ +- +- bng- cr6,.L6 /* if (x > 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bng cr5,.L4 /* if (x_low > 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L5 +-.L4: /* if (x_low < 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L5: +- fadd fp5,fp4,fp10 /* r1 = x1 + 0.5; */ +- fadd fp5,fp5,fp13 /* r1 = r1 + TWO52; */ +- fsub fp5,fp5,fp13 /* r1 = r1 - TWO52; */ +- b .L9 +-.L6: /* if (x < 0.0) */ +- fctidz fp0,fp8 +- fcfid fp8,fp0 /* tau = floor(x_high/TWO52); */ +- bnl cr5,.L7 /* if (x_low < 0.0) */ +- fmr fp3,fp1 +- fmr fp4,fp2 +- b .L8 +-.L7: /* if (x_low > 0.0) */ +- fsub fp3,fp1,fp8 /* x0 = x_high - tau; */ +- fadd fp4,fp2,fp8 /* x1 = x_low + tau; */ +-.L8: +- fsub fp5,fp4,fp10 /* r1 = x1 - 0.5; */ +- fsub fp5,fp5,fp13 /* r1-= TWO52; */ +- fadd fp5,fp5,fp13 /* r1+= TWO52; */ +-.L9: +- mtfsf 0x01,fp11 /* restore previous rounding mode. */ +- fadd fp1,fp3,fp5 /* y_high = x0 + r1; */ +- fsub fp2,fp3,fp1 /* y_low = x0 - y_high + r1; */ +- fadd fp2,fp2,fp5 +- blr +-END (__roundl) +- +-long_double_symbol (libm, __roundl, roundl) diff --git a/SOURCES/glibc-rh1463692-1.patch b/SOURCES/glibc-rh1463692-1.patch new file mode 100644 index 00000000..171bc857 --- /dev/null +++ b/SOURCES/glibc-rh1463692-1.patch @@ -0,0 +1,49 @@ +From 4fa8ae49aa169fb8d97882938e8bee3ed9ce5410 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Fri, 14 Jul 2017 21:46:42 -0400 +Subject: [PATCH] Fix BZ #21654 - grp-merge.c alignment + +* grp/grp_merge.c (__copy_grp): Align char** to minimum pointer +alignment not char alignment. +(__merge_grp): Likewise. +--- + ChangeLog | 7 +++++++ + grp/grp-merge.c | 16 ++++++++++++++++ + 2 files changed, 23 insertions(+) + +diff --git a/grp/grp-merge.c b/grp/grp-merge.c +index 77c494d..6590e5d 100644 +--- a/grp/grp-merge.c ++++ b/grp/grp-merge.c +@@ -85,6 +85,14 @@ __copy_grp (const struct group srcgrp, const size_t buflen, + } + members[i] = NULL; + ++ /* Align for pointers. We can't simply align C because we need to ++ align destbuf[c]. */ ++ if ((((uintptr_t)destbuf + c) & (__alignof__(char **) - 1)) != 0) ++ { ++ uintptr_t mis_align = ((uintptr_t)destbuf + c) & (__alignof__(char **) - 1); ++ c += __alignof__(char **) - mis_align; ++ } ++ + /* Copy the pointers from the members array into the buffer and assign them + to the gr_mem member of destgrp. */ + destgrp->gr_mem = (char **) &destbuf[c]; +@@ -168,6 +176,14 @@ __merge_grp (struct group *savedgrp, char *savedbuf, char *savedend, + /* Add the NULL-terminator. */ + members[savedmemcount + memcount] = NULL; + ++ /* Align for pointers. We can't simply align C because we need to ++ align savedbuf[c]. */ ++ if ((((uintptr_t)savedbuf + c) & (__alignof__(char **) - 1)) != 0) ++ { ++ uintptr_t mis_align = ((uintptr_t)savedbuf + c) & (__alignof__(char **) - 1); ++ c += __alignof__(char **) - mis_align; ++ } ++ + /* Copy the member array back into the buffer after the member list and free + the member array. */ + savedgrp->gr_mem = (char **) &savedbuf[c]; +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1463692-2.patch b/SOURCES/glibc-rh1463692-2.patch new file mode 100644 index 00000000..f5197db4 --- /dev/null +++ b/SOURCES/glibc-rh1463692-2.patch @@ -0,0 +1,27 @@ +From f8cef4d07d9641e27629bd3ce2d13f5d702fb251 Mon Sep 17 00:00:00 2001 +From: DJ Delorie +Date: Wed, 19 Jul 2017 13:14:34 -0400 +Subject: [PATCH] Fix cast-after-dereference + +Original code was dereferencing a char*, then casting the value +to size_t. Should cast the pointer to size_t* then deference. +--- + ChangeLog | 4 ++++ + grp/grp-merge.c | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grp/grp-merge.c b/grp/grp-merge.c +index 6590e5d..035e7a6 100644 +--- a/grp/grp-merge.c ++++ b/grp/grp-merge.c +@@ -137,7 +137,7 @@ __merge_grp (struct group *savedgrp, char *savedbuf, char *savedend, + + /* Get the count of group members from the last sizeof (size_t) bytes in the + mergegrp buffer. */ +- savedmemcount = (size_t) *(savedend - sizeof (size_t)); ++ savedmemcount = *(size_t *) (savedend - sizeof (size_t)); + + /* Get the count of new members to add. */ + for (memcount = 0; mergegrp->gr_mem[memcount]; memcount++) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh1468807.patch b/SOURCES/glibc-rh1468807.patch new file mode 100644 index 00000000..42ca09f7 --- /dev/null +++ b/SOURCES/glibc-rh1468807.patch @@ -0,0 +1,226 @@ +Backport of this upstream patch: + +commit 031e519c95c069abe4e4c7c59e2b4b67efccdee5 +Author: H.J. Lu +Date: Thu Jul 6 04:43:06 2017 -0700 + + x86-64: Align the stack in __tls_get_addr [BZ #21609] + + This change forces realignment of the stack pointer in __tls_get_addr, so + that binaries compiled by GCCs older than GCC 4.9: + + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 + + continue to work even if vector instructions are used in glibc which + require the ABI stack realignment. + + __tls_get_addr_slow is added to handle the slow paths in the default + implementation of__tls_get_addr in elf/dl-tls.c. The new __tls_get_addr + calls __tls_get_addr_slow after realigning the stack. Internal calls + within ld.so go directly to the default implementation of __tls_get_addr + because they do not need stack realignment. + + [BZ #21609] + * sysdeps/x86_64/Makefile (sysdep-dl-routines): Add tls_get_addr. + (gen-as-const-headers): Add rtld-offsets.sym. + * sysdeps/x86_64/dl-tls.c: New file. + * sysdeps/x86_64/rtld-offsets.sym: Likwise. + * sysdeps/x86_64/tls_get_addr.S: Likewise. + * sysdeps/x86_64/dl-tls.h: Add multiple inclusion guards. + * sysdeps/x86_64/tlsdesc.sym (TI_MODULE_OFFSET): New. + (TI_OFFSET_OFFSET): Likwise. + +Adjusted for drift in sysdeps/x86_64/Makefile and lack of +TLS_DTV_UNALLOCATED consolidation (upstream commit +aca1daef298b43bd7b1987b31f5aabcf6c2f6021). + +diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile +index 6c03a89fb3ea3063..c6766bb2b443a28a 100644 +--- a/sysdeps/x86_64/Makefile ++++ b/sysdeps/x86_64/Makefile +@@ -19,7 +19,7 @@ gen-as-const-headers += locale-defines.sym + endif + + ifeq ($(subdir),elf) +-sysdep-dl-routines += tlsdesc dl-tlsdesc ++sysdep-dl-routines += tlsdesc dl-tlsdesc tls_get_addr + + tests += ifuncmain8 + modules-names += ifuncmod8 +@@ -69,5 +69,5 @@ endif + endif + + ifeq ($(subdir),csu) +-gen-as-const-headers += tlsdesc.sym ++gen-as-const-headers += tlsdesc.sym rtld-offsets.sym + endif +diff --git a/sysdeps/x86_64/dl-tls.c b/sysdeps/x86_64/dl-tls.c +new file mode 100644 +index 0000000000000000..3584805c8ecca59a +--- /dev/null ++++ b/sysdeps/x86_64/dl-tls.c +@@ -0,0 +1,53 @@ ++/* Thread-local storage handling in the ELF dynamic linker. x86-64 version. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef SHARED ++/* Work around GCC PR58066, due to which __tls_get_addr may be called ++ with an unaligned stack. The compat implementation is in ++ tls_get_addr-compat.S. */ ++ ++# include ++ ++/* Define __tls_get_addr within elf/dl-tls.c under a different ++ name. */ ++extern __typeof__ (__tls_get_addr) ___tls_get_addr; ++ ++# define __tls_get_addr ___tls_get_addr ++# include ++# undef __tls_get_addr ++ ++hidden_ver (___tls_get_addr, __tls_get_addr) ++ ++/* Only handle slow paths for __tls_get_addr. */ ++attribute_hidden ++void * ++__tls_get_addr_slow (GET_ADDR_ARGS) ++{ ++ dtv_t *dtv = THREAD_DTV (); ++ ++ if (__glibc_unlikely (dtv[0].counter != GL(dl_tls_generation))) ++ return update_get_addr (GET_ADDR_PARAM); ++ ++ return tls_get_addr_tail (GET_ADDR_PARAM, dtv, NULL); ++} ++#else ++ ++/* No compatibility symbol needed. */ ++# include ++ ++#endif +diff --git a/sysdeps/x86_64/dl-tls.h b/sysdeps/x86_64/dl-tls.h +index 56162ee64a4aae7d..0b4a6b3b634a83f4 100644 +--- a/sysdeps/x86_64/dl-tls.h ++++ b/sysdeps/x86_64/dl-tls.h +@@ -16,6 +16,10 @@ + License along with the GNU C Library; if not, see + . */ + ++#ifndef _X86_64_DL_TLS_H ++#define _X86_64_DL_TLS_H ++ ++#include + + /* Type used for the representation of TLS information in the GOT. */ + typedef struct dl_tls_index +@@ -29,3 +33,5 @@ extern void *__tls_get_addr (tls_index *ti); + + /* Value used for dtv entries for which the allocation is delayed. */ + #define TLS_DTV_UNALLOCATED ((void *) -1l) ++ ++#endif /* _X86_64_DL_TLS_H */ +diff --git a/sysdeps/x86_64/rtld-offsets.sym b/sysdeps/x86_64/rtld-offsets.sym +new file mode 100644 +index 0000000000000000..fd41b51521ac80bd +--- /dev/null ++++ b/sysdeps/x86_64/rtld-offsets.sym +@@ -0,0 +1,6 @@ ++#define SHARED ++#include ++ ++-- ++ ++GL_TLS_GENERATION_OFFSET offsetof (struct rtld_global, _dl_tls_generation) +diff --git a/sysdeps/x86_64/tls_get_addr.S b/sysdeps/x86_64/tls_get_addr.S +new file mode 100644 +index 0000000000000000..9d38fb3be54fbcb5 +--- /dev/null ++++ b/sysdeps/x86_64/tls_get_addr.S +@@ -0,0 +1,61 @@ ++/* Stack-aligning implementation of __tls_get_addr. x86-64 version. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef SHARED ++ ++# include ++# include "tlsdesc.h" ++# include "rtld-offsets.h" ++ ++/* See __tls_get_addr and __tls_get_addr_slow in dl-tls.c. This function ++ call __tls_get_addr_slow on both slow paths. It realigns the stack ++ before the call to work around GCC PR58066. */ ++ ++ENTRY (__tls_get_addr) ++ mov %fs:DTV_OFFSET, %RDX_LP ++ mov GL_TLS_GENERATION_OFFSET+_rtld_local(%rip), %RAX_LP ++ /* GL(dl_tls_generation) == dtv[0].counter */ ++ cmp %RAX_LP, (%rdx) ++ jne 1f ++ mov TI_MODULE_OFFSET(%rdi), %RAX_LP ++ /* dtv[ti->ti_module] */ ++# ifdef __LP64__ ++ salq $4, %rax ++ movq (%rdx,%rax), %rax ++# else ++ movl (%rdx,%rax, 8), %eax ++# endif ++ cmp $-1, %RAX_LP ++ je 1f ++ add TI_OFFSET_OFFSET(%rdi), %RAX_LP ++ ret ++1: ++ /* On the slow path, align the stack. */ ++ pushq %rbp ++ cfi_def_cfa_offset (16) ++ cfi_offset (%rbp, -16) ++ mov %RSP_LP, %RBP_LP ++ cfi_def_cfa_register (%rbp) ++ and $-16, %RSP_LP ++ call __tls_get_addr_slow ++ mov %RBP_LP, %RSP_LP ++ popq %rbp ++ cfi_def_cfa (%rsp, 8) ++ ret ++END (__tls_get_addr) ++#endif /* SHARED */ +diff --git a/sysdeps/x86_64/tlsdesc.sym b/sysdeps/x86_64/tlsdesc.sym +index 33854975d04184b2..fc897ab4b522b1a9 100644 +--- a/sysdeps/x86_64/tlsdesc.sym ++++ b/sysdeps/x86_64/tlsdesc.sym +@@ -15,3 +15,6 @@ TLSDESC_ARG offsetof(struct tlsdesc, arg) + TLSDESC_GEN_COUNT offsetof(struct tlsdesc_dynamic_arg, gen_count) + TLSDESC_MODID offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_module) + TLSDESC_MODOFF offsetof(struct tlsdesc_dynamic_arg, tlsinfo.ti_offset) ++ ++TI_MODULE_OFFSET offsetof(tls_index, ti_module) ++TI_OFFSET_OFFSET offsetof(tls_index, ti_offset) diff --git a/SOURCES/glibc-rh1498566.patch b/SOURCES/glibc-rh1498566.patch new file mode 100644 index 00000000..e1c88629 --- /dev/null +++ b/SOURCES/glibc-rh1498566.patch @@ -0,0 +1,70 @@ +This patch is from the upstream release/2.20/master branch, which is a +backport containing only the syscalls.list changes in commit 016495b8 in +master. + +commit adba20cf74bc6ea3910afe57d40ed755c92c2ddb +Author: Stefan Liebler +Date: Thu Mar 3 08:24:18 2016 +0100 + + S390: Do not use direct socket syscalls if build on kernels >= 4.3. [BZ #19682] + + Beginning with Linux 4.3, the kernel headers contain direct + system call numbers __NR_socket etc. on s390x. On older kernels, + the socket-multiplexer syscall __NR_socketcall was used. + + To enable these new syscalls, the patch + "S390: Call direct system calls for socket operations." + (https://sourceware.org/git/?p=glibc.git;a=commit;h=016495b818cb61df7d0d10e6db54074271b3e3a5) + was applied upstream. + + If glibc 2.23 is configured with --enable-kernel=4.3 and newer, + the direct socket syscalls are used. + For older kernels, the socket-multiplexer syscall is used instead. + + In glibc 2.22 and earlier, this patch is not applied. + If you build glibc on a kernel < 4.3, the socket-multiplexer + syscall is used. But if you build glibc on kernel >= 4.3, the + direct socket-syscalls are used. If you install this glibc on a + kernel < 4.3, all socket operations will fail. + See "Bug 19682 - s390x: Incorrect syscall definitions cause + breakage with Linux 4.3 headers" + (https://sourceware.org/bugzilla/show_bug.cgi?id=19682) + The configure switch --enable-kernel does not influence this + behaviour on older glibc-releases. + + The solution is to remove the direct socket-syscalls in + sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list + (this patch) on older glibc-releases as it was done by the + upstream patch, too. These entries were never used on s390x, + but the c-files in sysdeps/unix/sysv/linux/. + After this removal, the behaviour of the socket functions are + not changed compared to the original glibc release version + and the socket-multiplexer-syscall is always used. + +Index: b/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list +=================================================================== +--- a/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list +@@ -14,22 +14,3 @@ shmget - shmget i:iii __shmget shmget + semop - semop i:ipi __semop semop + semget - semget i:iii __semget semget + semctl - semctl i:iiii __semctl semctl +- +-# proper socket implementations: +-accept - accept Ci:iBN __libc_accept __accept accept +-bind - bind i:ipi __bind bind +-connect - connect Ci:ipi __libc_connect __connect connect +-getpeername - getpeername i:ipp __getpeername getpeername +-getsockname - getsockname i:ipp __getsockname getsockname +-getsockopt - getsockopt i:iiiBN __getsockopt getsockopt +-listen - listen i:ii __listen listen +-recv - recv Ci:ibni __libc_recv __recv recv +-recvfrom - recvfrom Ci:ibniBN __libc_recvfrom __recvfrom recvfrom +-recvmsg - recvmsg Ci:ipi __libc_recvmsg __recvmsg recvmsg +-send - send Ci:ibni __libc_send __send send +-sendmsg - sendmsg Ci:ipi __libc_sendmsg __sendmsg sendmsg +-sendto - sendto Ci:ibnibn __libc_sendto __sendto sendto +-setsockopt - setsockopt i:iiibn __setsockopt setsockopt +-shutdown - shutdown i:ii __shutdown shutdown +-socket - socket i:iii __socket socket +-socketpair - socketpair i:iiif __socketpair socketpair diff --git a/SOURCES/glibc-rh1498925-1.patch b/SOURCES/glibc-rh1498925-1.patch new file mode 100644 index 00000000..3e003907 --- /dev/null +++ b/SOURCES/glibc-rh1498925-1.patch @@ -0,0 +1,89 @@ +commit 87868c2418fb74357757e3b739ce5b76b17a8929 +Author: Adhemerval Zanella +Date: Wed Jun 25 11:54:31 2014 -0500 + + PowerPC: Align power7 memcpy using VSX to quadword + + This patch changes power7 memcpy to use VSX instructions only when + memory is aligned to quardword. It is to avoid unaligned kernel traps + on non-cacheable memory (for instance, memory-mapped I/O). + +diff --git a/sysdeps/powerpc/powerpc32/power7/memcpy.S b/sysdeps/powerpc/powerpc32/power7/memcpy.S +index 52c2a6b..e540fea 100644 +--- a/sysdeps/powerpc/powerpc32/power7/memcpy.S ++++ b/sysdeps/powerpc/powerpc32/power7/memcpy.S +@@ -38,8 +38,8 @@ EALIGN (memcpy, 5, 0) + ble cr1, L(copy_LT_32) /* If move < 32 bytes use short move + code. */ + +- andi. 11,3,7 /* Check alignment of DST. */ +- clrlwi 10,4,29 /* Check alignment of SRC. */ ++ andi. 11,3,15 /* Check alignment of DST. */ ++ clrlwi 10,4,28 /* Check alignment of SRC. */ + cmplw cr6,10,11 /* SRC and DST alignments match? */ + mr 12,4 + mr 31,5 +diff --git a/sysdeps/powerpc/powerpc64/power7/memcpy.S b/sysdeps/powerpc/powerpc64/power7/memcpy.S +index bbfd381..58d9b12 100644 +--- a/sysdeps/powerpc/powerpc64/power7/memcpy.S ++++ b/sysdeps/powerpc/powerpc64/power7/memcpy.S +@@ -36,16 +36,11 @@ EALIGN (memcpy, 5, 0) + ble cr1, L(copy_LT_32) /* If move < 32 bytes use short move + code. */ + +-#ifdef __LITTLE_ENDIAN__ +-/* In little-endian mode, power7 takes an alignment trap on any lxvd2x +- or stxvd2x crossing a 32-byte boundary, so ensure the aligned_copy +- loop is only used for quadword aligned copies. */ ++/* Align copies using VSX instructions to quadword. It is to avoid alignment ++ traps when memcpy is used on non-cacheable memory (for instance, memory ++ mapped I/O). */ + andi. 10,3,15 + clrldi 11,4,60 +-#else +- andi. 10,3,7 /* Check alignment of DST. */ +- clrldi 11,4,61 /* Check alignment of SRC. */ +-#endif + cmpld cr6,10,11 /* SRC and DST alignments match? */ + + mr dst,3 +@@ -53,13 +48,9 @@ EALIGN (memcpy, 5, 0) + beq L(aligned_copy) + + mtocrf 0x01,0 +-#ifdef __LITTLE_ENDIAN__ + clrldi 0,0,60 +-#else +- clrldi 0,0,61 +-#endif + +-/* Get the DST and SRC aligned to 8 bytes (16 for little-endian). */ ++/* Get the DST and SRC aligned to 16 bytes. */ + 1: + bf 31,2f + lbz 6,0(src) +@@ -79,14 +70,12 @@ EALIGN (memcpy, 5, 0) + stw 6,0(dst) + addi dst,dst,4 + 8: +-#ifdef __LITTLE_ENDIAN__ + bf 28,16f + ld 6,0(src) + addi src,src,8 + std 6,0(dst) + addi dst,dst,8 + 16: +-#endif + subf cnt,0,cnt + + /* Main aligned copy loop. Copies 128 bytes at a time. */ +@@ -298,9 +287,6 @@ L(copy_LE_8): + .align 4 + L(copy_GE_32_unaligned): + clrldi 0,0,60 /* Number of bytes until the 1st dst quadword. */ +-#ifndef __LITTLE_ENDIAN__ +- andi. 10,3,15 /* Check alignment of DST (against quadwords). */ +-#endif + srdi 9,cnt,4 /* Number of full quadwords remaining. */ + + beq L(copy_GE_32_unaligned_cont) diff --git a/SOURCES/glibc-rh1498925-2.patch b/SOURCES/glibc-rh1498925-2.patch new file mode 100644 index 00000000..09bab3d4 --- /dev/null +++ b/SOURCES/glibc-rh1498925-2.patch @@ -0,0 +1,123 @@ +The memmove related fix is dropped in this patch because rhel-7.5 +does not have optimized memmove for POWER7. + +commit 63da5cd4a097d089033d980c42254c3356fa723f +Author: Rajalakshmi Srinivasaraghavan +Date: Wed Oct 25 13:13:53 2017 -0200 + + powerpc: Replace lxvd2x/stxvd2x with lvx/stvx in P7's memcpy/memmove + + POWER9 DD2.1 and earlier has an issue where some cache inhibited + vector load traps to the kernel, causing a performance degradation. To + handle this in memcpy and memmove, lvx/stvx is used for aligned + addresses instead of lxvd2x/stxvd2x. + + Reference: https://patchwork.ozlabs.org/patch/814059/ + + * sysdeps/powerpc/powerpc64/power7/memcpy.S: Replace + lxvd2x/stxvd2x with lvx/stvx. + * sysdeps/powerpc/powerpc64/power7/memmove.S: Likewise. + + Reviewed-by: Tulio Magno Quites Machado Filho + Reviewed-by: Adhemerval Zanella + +diff --git a/sysdeps/powerpc/powerpc64/power7/memcpy.S b/sysdeps/powerpc/powerpc64/power7/memcpy.S +index 1ccbc2e..a7cdf8b 100644 +--- a/sysdeps/powerpc/powerpc64/power7/memcpy.S ++++ b/sysdeps/powerpc/powerpc64/power7/memcpy.S +@@ -91,63 +91,63 @@ L(aligned_copy): + srdi 12,cnt,7 + cmpdi 12,0 + beq L(aligned_tail) +- lxvd2x 6,0,src +- lxvd2x 7,src,6 ++ lvx 6,0,src ++ lvx 7,src,6 + mtctr 12 + b L(aligned_128loop) + + .align 4 + L(aligned_128head): + /* for the 2nd + iteration of this loop. */ +- lxvd2x 6,0,src +- lxvd2x 7,src,6 ++ lvx 6,0,src ++ lvx 7,src,6 + L(aligned_128loop): +- lxvd2x 8,src,7 +- lxvd2x 9,src,8 +- stxvd2x 6,0,dst ++ lvx 8,src,7 ++ lvx 9,src,8 ++ stvx 6,0,dst + addi src,src,64 +- stxvd2x 7,dst,6 +- stxvd2x 8,dst,7 +- stxvd2x 9,dst,8 +- lxvd2x 6,0,src +- lxvd2x 7,src,6 ++ stvx 7,dst,6 ++ stvx 8,dst,7 ++ stvx 9,dst,8 ++ lvx 6,0,src ++ lvx 7,src,6 + addi dst,dst,64 +- lxvd2x 8,src,7 +- lxvd2x 9,src,8 ++ lvx 8,src,7 ++ lvx 9,src,8 + addi src,src,64 +- stxvd2x 6,0,dst +- stxvd2x 7,dst,6 +- stxvd2x 8,dst,7 +- stxvd2x 9,dst,8 ++ stvx 6,0,dst ++ stvx 7,dst,6 ++ stvx 8,dst,7 ++ stvx 9,dst,8 + addi dst,dst,64 + bdnz L(aligned_128head) + + L(aligned_tail): + mtocrf 0x01,cnt + bf 25,32f +- lxvd2x 6,0,src +- lxvd2x 7,src,6 +- lxvd2x 8,src,7 +- lxvd2x 9,src,8 ++ lvx 6,0,src ++ lvx 7,src,6 ++ lvx 8,src,7 ++ lvx 9,src,8 + addi src,src,64 +- stxvd2x 6,0,dst +- stxvd2x 7,dst,6 +- stxvd2x 8,dst,7 +- stxvd2x 9,dst,8 ++ stvx 6,0,dst ++ stvx 7,dst,6 ++ stvx 8,dst,7 ++ stvx 9,dst,8 + addi dst,dst,64 + 32: + bf 26,16f +- lxvd2x 6,0,src +- lxvd2x 7,src,6 ++ lvx 6,0,src ++ lvx 7,src,6 + addi src,src,32 +- stxvd2x 6,0,dst +- stxvd2x 7,dst,6 ++ stvx 6,0,dst ++ stvx 7,dst,6 + addi dst,dst,32 + 16: + bf 27,8f +- lxvd2x 6,0,src ++ lvx 6,0,src + addi src,src,16 +- stxvd2x 6,0,dst ++ stvx 6,0,dst + addi dst,dst,16 + 8: + bf 28,4f diff --git a/SOURCES/glibc-rh1500908.patch b/SOURCES/glibc-rh1500908.patch new file mode 100644 index 00000000..c9f0a7a2 --- /dev/null +++ b/SOURCES/glibc-rh1500908.patch @@ -0,0 +1,28 @@ +Backport of: + +commit e9177fba13549a8e2a6232f46080e5c6d3e467b1 +Author: Szabolcs Nagy +Date: Wed Jun 21 13:47:07 2017 +0100 + + [AArch64] Use hidden __GI__dl_argv in rtld startup code + + We rely on the symbol being locally defined so using extern symbol + is not correct and the linker may complain about the relocations. + +Adjusted to the old INTDEF/INTUSE mechanism. + +diff --git a/ports/sysdeps/aarch64/dl-machine.h b/ports/sysdeps/aarch64/dl-machine.h +index 0e76ca8f146905ef..40b0587ba42cd59e 100644 +--- a/ports/sysdeps/aarch64/dl-machine.h ++++ b/ports/sysdeps/aarch64/dl-machine.h +@@ -169,8 +169,8 @@ _dl_start_user: \n\ + cmp x0, #0 \n\ + bne 1b \n\ + // Update _dl_argv \n\ +- adrp x3, _dl_argv \n\ +- str x2, [x3, #:lo12:_dl_argv] \n\ ++ adrp x3, _dl_argv_internal \n\ ++ str x2, [x3, #:lo12:_dl_argv_internal] \n\ + .L_done_stack_adjust: \n\ + // compute envp \n\ + add x3, x2, x1, lsl #3 \n\ diff --git a/SOURCES/glibc-rh1503854-1.patch b/SOURCES/glibc-rh1503854-1.patch new file mode 100644 index 00000000..7ee6abc2 --- /dev/null +++ b/SOURCES/glibc-rh1503854-1.patch @@ -0,0 +1,70 @@ +commit 911569d02dec023d949d96aa7b0e828c91c06f55 +Author: Carlos Eduardo Seo +Date: Mon Dec 28 16:36:46 2015 -0200 + + powerpc: Fix dl-procinfo HWCAP + + HWCAP-related code should had been updated when the 32 bits of HWCAP were + used. This patch updates the code in dl-procinfo.h to loop through all + the 32 bits in HWCAP and updates _dl_powerpc_cap_flags accordingly. + +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index 6e7850e..0b55906 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -45,11 +45,12 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_cap_flags + #else +-PROCINFO_CLASS const char _dl_powerpc_cap_flags[60][10] ++PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][10] + #endif + #ifndef PROCINFO_DECL + = { +- "ppcle", "true_le", "archpmu", "vsx", ++ "ppcle", "true_le", "", "", ++ "", "", "archpmu", "vsx", + "arch_2_06", "power6x", "dfp", "pa6t", + "arch_2_05", "ic_snoop", "smt", "booke", + "cellbe", "power5+", "power5", "power4", +diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h +index bce3a49..2187c5e 100644 +--- a/sysdeps/powerpc/dl-procinfo.h ++++ b/sysdeps/powerpc/dl-procinfo.h +@@ -22,9 +22,6 @@ + #include + #include /* This defines the PPC_FEATURE[2]_* macros. */ + +-/* There are 28 bits used, but they are bits 4..31. */ +-#define _DL_HWCAP_FIRST 4 +- + /* The total number of available bits (including those prior to + _DL_HWCAP_FIRST). Some of these bits might not be used. */ + #define _DL_HWCAP_COUNT 64 +@@ -68,7 +65,7 @@ static inline const char * + __attribute__ ((unused)) + _dl_hwcap_string (int idx) + { +- return GLRO(dl_powerpc_cap_flags)[idx - _DL_HWCAP_FIRST]; ++ return GLRO(dl_powerpc_cap_flags)[idx]; + } + + static inline const char * +@@ -82,7 +79,7 @@ static inline int + __attribute__ ((unused)) + _dl_string_hwcap (const char *str) + { +- for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) ++ for (int i = 0; i < _DL_HWCAP_COUNT; ++i) + if (strcmp (str, _dl_hwcap_string (i)) == 0) + return i; + return -1; +@@ -180,7 +177,7 @@ _dl_procinfo (unsigned int type, unsigned long int word) + case AT_HWCAP: + _dl_printf ("AT_HWCAP: "); + +- for (int i = _DL_HWCAP_FIRST; i <= _DL_HWCAP_LAST; ++i) ++ for (int i = 0; i <= _DL_HWCAP_LAST; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (i)); + break; diff --git a/SOURCES/glibc-rh1503854-2.patch b/SOURCES/glibc-rh1503854-2.patch new file mode 100644 index 00000000..165fe91d --- /dev/null +++ b/SOURCES/glibc-rh1503854-2.patch @@ -0,0 +1,49 @@ +commit 7dcdfbcf6749cdc4c63e2613cbb3e2392d2fc2fb +Author: Tulio Magno Quites Machado Filho +Date: Fri Jun 23 09:10:32 2017 -0300 + + powerpc: Update AT_HWCAP[2] bits + + Linux commit ID a4700a26107241cc7b9ac8528b2c6714ff99983d reserved 2 more + bits for the instructions darn (Deliver a Random Number) and scv (System + Call Vectored). + + Linux commit ID 6997e57d693b07289694239e52a10d2f02c3a46f reserved + another bit for internal usage. + + * sysdeps/powerpc/bits/hwcap.h: Add PPC_FEATURE2_DARN and + PPC_FEATURE2_SCV. + * sysdeps/powerpc/dl-procinfo.c (_dl_powerpc_cap_flags): Add scv + and darn. + +diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h +index c9daeed..dfc71c2 100644 +--- a/sysdeps/powerpc/bits/hwcap.h ++++ b/sysdeps/powerpc/bits/hwcap.h +@@ -50,6 +50,7 @@ + #define PPC_FEATURE_ARCH_2_06 0x00000100 /* ISA 2.06 */ + #define PPC_FEATURE_HAS_VSX 0x00000080 /* P7 Vector Extension. */ + #define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040 ++/* Reserved by the kernel. 0x00000004 Do not use. */ + #define PPC_FEATURE_TRUE_LE 0x00000002 + #define PPC_FEATURE_PPC_LE 0x00000001 + +@@ -69,3 +70,5 @@ + #define PPC_FEATURE2_ARCH_3_00 0x00800000 /* ISA 3.0 */ + #define PPC_FEATURE2_HAS_IEEE128 0x00400000 /* VSX IEEE Binary Float + 128-bit */ ++#define PPC_FEATURE2_DARN 0x00200000 /* darn instruction. */ ++#define PPC_FEATURE2_SCV 0x00100000 /* scv syscall. */ +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index cd7329b..4dac16d 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -62,7 +62,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][10] + "", "", "", "", + "", "", "", "", + "", "", "", "", +- "", "", "ieee128", "arch_3_00", ++ "scv", "darn", "ieee128", "arch_3_00", + "htm-nosc", "vcrypto", "tar", "isel", + "ebb", "dscr", "htm", "arch_2_07", + } diff --git a/SOURCES/glibc-rh1503854-3.patch b/SOURCES/glibc-rh1503854-3.patch new file mode 100644 index 00000000..831ced36 --- /dev/null +++ b/SOURCES/glibc-rh1503854-3.patch @@ -0,0 +1,49 @@ +commit df0c40ee3a893238ac11f4c0d876a0c3b49d198d +Author: Tulio Magno Quites Machado Filho +Date: Fri Nov 17 21:15:15 2017 -0200 + + powerpc: Update AT_HWCAP2 bits + + Linux commit ID cba6ac4869e45cc93ac5497024d1d49576e82666 reserved a new + bit for a scenario where transactional memory is available, but the + suspended state is disabled. + + * sysdeps/powerpc/bits/hwcap.h (PPC_FEATURE2_HTM_NO_SUSPEND): New + macro. + * sysdeps/powerpc/dl-procinfo.c (_dl_powerpc_cap_flags): Add + htm-no-suspend. + + Signed-off-by: Tulio Magno Quites Machado Filho + +diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h +index dfc71c2..0668ca0 100644 +--- a/sysdeps/powerpc/bits/hwcap.h ++++ b/sysdeps/powerpc/bits/hwcap.h +@@ -72,3 +72,5 @@ + 128-bit */ + #define PPC_FEATURE2_DARN 0x00200000 /* darn instruction. */ + #define PPC_FEATURE2_SCV 0x00100000 /* scv syscall. */ ++#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 /* TM without suspended ++ state. */ +diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c +index 4dac16d..55a6e78 100644 +--- a/sysdeps/powerpc/dl-procinfo.c ++++ b/sysdeps/powerpc/dl-procinfo.c +@@ -45,7 +45,7 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_cap_flags + #else +-PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][10] ++PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][15] + #endif + #ifndef PROCINFO_DECL + = { +@@ -61,7 +61,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][10] + "", "", "", "", + "", "", "", "", + "", "", "", "", +- "", "", "", "", ++ "", "", "", "htm-no-suspend", + "scv", "darn", "ieee128", "arch_3_00", + "htm-nosc", "vcrypto", "tar", "isel", + "ebb", "dscr", "htm", "arch_2_07", diff --git a/SOURCES/glibc-rh1504809-1.patch b/SOURCES/glibc-rh1504809-1.patch new file mode 100644 index 00000000..cc635e90 --- /dev/null +++ b/SOURCES/glibc-rh1504809-1.patch @@ -0,0 +1,19 @@ +commit c369d66e5426a30e4725b100d5cd28e372754f90 +Author: Paul Eggert +Date: Fri Oct 20 18:41:14 2017 +0200 + + CVE-2017-15670: glob: Fix one-byte overflow [BZ #22320] + +diff --git a/posix/glob.c b/posix/glob.c +index 87d4f1bd2a7ef5a0..15cf3d5cccab0ee0 100644 +--- a/posix/glob.c ++++ b/posix/glob.c +@@ -826,7 +826,7 @@ glob (pattern, flags, errfunc, pglob) + *p = '\0'; + } + else +- *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) ++ *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1)) + = '\0'; + user_name = newp; + } diff --git a/SOURCES/glibc-rh1504809-2.patch b/SOURCES/glibc-rh1504809-2.patch new file mode 100644 index 00000000..ff6753d3 --- /dev/null +++ b/SOURCES/glibc-rh1504809-2.patch @@ -0,0 +1,26 @@ +commit a159b53fa059947cc2548e3b0d5bdcf7b9630ba8 +Author: Paul Eggert +Date: Sun Oct 22 10:00:57 2017 +0200 + + glob: Fix buffer overflow during GLOB_TILDE unescaping [BZ #22332] + +CVE-2017-15804 was assigned to this issue after commit. + +diff --git a/posix/glob.c b/posix/glob.c +index 15cf3d5cccab0ee0..e09314712d68c1b8 100644 +--- a/posix/glob.c ++++ b/posix/glob.c +@@ -806,11 +806,11 @@ glob (pattern, flags, errfunc, pglob) + char *p = mempcpy (newp, dirname + 1, + unescape - dirname - 1); + char *q = unescape; +- while (*q != '\0') ++ while (q != end_name) + { + if (*q == '\\') + { +- if (q[1] == '\0') ++ if (q + 1 == end_name) + { + /* "~fo\\o\\" unescape to user_name "foo\\", + but "~fo\\o\\/" unescape to user_name diff --git a/SOURCES/glibc-rh1504969.patch b/SOURCES/glibc-rh1504969.patch new file mode 100644 index 00000000..2cf639d3 --- /dev/null +++ b/SOURCES/glibc-rh1504969.patch @@ -0,0 +1,781 @@ +Backport from Hongjiu Lu of these upstream +commits: + +commit b52b0d793dcb226ecb0ecca1e672ca265973233c +Author: H.J. Lu +Date: Fri Oct 20 11:00:08 2017 -0700 + + x86-64: Use fxsave/xsave/xsavec in _dl_runtime_resolve [BZ #21265] + + In _dl_runtime_resolve, use fxsave/xsave/xsavec to preserve all vector, + mask and bound registers. It simplifies _dl_runtime_resolve and supports + different calling conventions. ld.so code size is reduced by more than + 1 KB. However, use fxsave/xsave/xsavec takes a little bit more cycles + than saving and restoring vector and bound registers individually. + + Latency for _dl_runtime_resolve to lookup the function, foo, from one + shared library plus libc.so: + + Before After Change + + Westmere (SSE)/fxsave 345 866 151% + IvyBridge (AVX)/xsave 420 643 53% + Haswell (AVX)/xsave 713 1252 75% + Skylake (AVX+MPX)/xsavec 559 719 28% + Skylake (AVX512+MPX)/xsavec 145 272 87% + Ryzen (AVX)/xsavec 280 553 97% + + This is the worst case where portion of time spent for saving and + restoring registers is bigger than majority of cases. With smaller + _dl_runtime_resolve code size, overall performance impact is negligible. + + On IvyBridge, differences in build and test time of binutils with lazy + binding GCC and binutils are noises. On Westmere, differences in + bootstrap and "makc check" time of GCC 7 with lazy binding GCC and + binutils are also noises. + +commit 0ac8ee53e8efbfd6e1c37094b4653f5c2dad65b5 +Author: H.J. Lu +Date: Fri Aug 26 08:57:42 2016 -0700 + + X86-64: Correct CFA in _dl_runtime_resolve + + When stack is re-aligned in _dl_runtime_resolve, there is no need to + adjust CFA when allocating register save area on stack. + + * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve): Don't + adjust CFA when allocating register save area on re-aligned + stack. + +Storing the full xsave state size in xsave_state_full_size was not needed +because RHEL7 does not have the full tunables support that would use this, +therefore support for xsave_state_full_size has been removed from the +changes in b52b0d793dcb226ecb0ecca1e672ca265973233c + +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features-offsets.sym +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features-offsets.sym ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features-offsets.sym +@@ -5,3 +5,5 @@ + #define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) + + RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET rtld_global_ro_offsetof (_dl_x86_cpu_features) ++ ++XSAVE_STATE_SIZE_OFFSET offsetof (struct cpu_features, xsave_state_size) +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.c ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +@@ -18,6 +18,7 @@ + + #include + #include ++#include + + static inline void + get_common_indeces (struct cpu_features *cpu_features, +@@ -148,20 +149,6 @@ init_cpu_features (struct cpu_features * + break; + } + } +- +- /* To avoid SSE transition penalty, use _dl_runtime_resolve_slow. +- If XGETBV suports ECX == 1, use _dl_runtime_resolve_opt. */ +- cpu_features->feature[index_Use_dl_runtime_resolve_slow] +- |= bit_Use_dl_runtime_resolve_slow; +- if (cpu_features->max_cpuid >= 0xd) +- { +- unsigned int eax; +- +- __cpuid_count (0xd, 1, eax, ebx, ecx, edx); +- if ((eax & (1 << 2)) != 0) +- cpu_features->feature[index_Use_dl_runtime_resolve_opt] +- |= bit_Use_dl_runtime_resolve_opt; +- } + } + /* This spells out "AuthenticAMD". */ + else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) +@@ -244,6 +231,71 @@ init_cpu_features (struct cpu_features * + if (HAS_CPU_FEATURE (FMA4)) + cpu_features->feature[index_FMA4_Usable] |= bit_FMA4_Usable; + } ++ ++ /* For _dl_runtime_resolve, set xsave_state_size to xsave area ++ size + integer register save size and align it to 64 bytes. */ ++ if (cpu_features->max_cpuid >= 0xd) ++ { ++ unsigned int eax, ebx, ecx, edx; ++ ++ __cpuid_count (0xd, 0, eax, ebx, ecx, edx); ++ if (ebx != 0) ++ { ++ cpu_features->xsave_state_size ++ = ALIGN_UP (ebx + STATE_SAVE_OFFSET, 64); ++ ++ __cpuid_count (0xd, 1, eax, ebx, ecx, edx); ++ ++ /* Check if XSAVEC is available. */ ++ if ((eax & (1 << 1)) != 0) ++ { ++ unsigned int xstate_comp_offsets[32]; ++ unsigned int xstate_comp_sizes[32]; ++ unsigned int i; ++ ++ xstate_comp_offsets[0] = 0; ++ xstate_comp_offsets[1] = 160; ++ xstate_comp_offsets[2] = 576; ++ xstate_comp_sizes[0] = 160; ++ xstate_comp_sizes[1] = 256; ++ ++ for (i = 2; i < 32; i++) ++ { ++ if ((STATE_SAVE_MASK & (1 << i)) != 0) ++ { ++ __cpuid_count (0xd, i, eax, ebx, ecx, edx); ++ xstate_comp_sizes[i] = eax; ++ } ++ else ++ { ++ ecx = 0; ++ xstate_comp_sizes[i] = 0; ++ } ++ ++ if (i > 2) ++ { ++ xstate_comp_offsets[i] ++ = (xstate_comp_offsets[i - 1] ++ + xstate_comp_sizes[i -1]); ++ if ((ecx & (1 << 1)) != 0) ++ xstate_comp_offsets[i] ++ = ALIGN_UP (xstate_comp_offsets[i], 64); ++ } ++ } ++ ++ /* Use XSAVEC. */ ++ unsigned int size ++ = xstate_comp_offsets[31] + xstate_comp_sizes[31]; ++ if (size) ++ { ++ cpu_features->xsave_state_size ++ = ALIGN_UP (size + STATE_SAVE_OFFSET, 64); ++ cpu_features->feature[index_XSAVEC_Usable] ++ |= bit_XSAVEC_Usable; ++ } ++ } ++ } ++ } + } + + cpu_features->family = family; +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.h ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.h +@@ -34,8 +34,7 @@ + #define bit_AVX512DQ_Usable (1 << 13) + #define bit_Prefer_MAP_32BIT_EXEC (1 << 16) + #define bit_Prefer_No_VZEROUPPER (1 << 17) +-#define bit_Use_dl_runtime_resolve_opt (1 << 20) +-#define bit_Use_dl_runtime_resolve_slow (1 << 21) ++#define bit_XSAVEC_Usable (1 << 18) + + + /* CPUID Feature flags. */ +@@ -70,10 +69,20 @@ + /* The current maximum size of the feature integer bit array. */ + #define FEATURE_INDEX_MAX 1 + ++/* Offset for fxsave/xsave area used by _dl_runtime_resolve. Also need ++ space to preserve RCX, RDX, RSI, RDI, R8, R9 and RAX. It must be ++ aligned to 16 bytes for fxsave and 64 bytes for xsave. */ ++#define STATE_SAVE_OFFSET (8 * 7 + 8) ++ ++/* Save SSE, AVX, AVX512, mask and bound registers. */ ++#define STATE_SAVE_MASK \ ++ ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 5) | (1 << 6) | (1 << 7)) ++ + #ifdef __ASSEMBLER__ + + # include + # include ++# include + + # define index_SSE2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET + # define index_SSSE3 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET +@@ -98,8 +107,6 @@ + # define index_AVX512DQ_Usable FEATURE_INDEX_1*FEATURE_SIZE + # define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1*FEATURE_SIZE + # define index_Prefer_No_VZEROUPPER FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Use_dl_runtime_resolve_opt FEATURE_INDEX_1*FEATURE_SIZE +-# define index_Use_dl_runtime_resolve_slow FEATURE_INDEX_1*FEATURE_SIZE + + + # if defined (_LIBC) && !IS_IN (nonlib) +@@ -214,6 +221,12 @@ struct cpu_features + } cpuid[COMMON_CPUID_INDEX_MAX]; + unsigned int family; + unsigned int model; ++ /* The type must be unsigned long int so that we use ++ ++ sub xsave_state_size_offset(%rip) %RSP_LP ++ ++ in _dl_runtime_resolve. */ ++ unsigned long int xsave_state_size; + unsigned int feature[FEATURE_INDEX_MAX]; + }; + +@@ -279,8 +292,7 @@ extern const struct cpu_features *__get_ + # define index_AVX512DQ_Usable FEATURE_INDEX_1 + # define index_Prefer_MAP_32BIT_EXEC FEATURE_INDEX_1 + # define index_Prefer_No_VZEROUPPER FEATURE_INDEX_1 +-# define index_Use_dl_runtime_resolve_opt FEATURE_INDEX_1 +-# define index_Use_dl_runtime_resolve_slow FEATURE_INDEX_1 ++# define index_XSAVEC_Usable FEATURE_INDEX_1 + + #endif /* !__ASSEMBLER__ */ + +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-machine.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-machine.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-machine.h +@@ -66,12 +66,9 @@ static inline int __attribute__ ((unused + elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) + { + Elf64_Addr *got; +- extern void _dl_runtime_resolve_sse (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx_slow (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx_opt (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx512 (ElfW(Word)) attribute_hidden; +- extern void _dl_runtime_resolve_avx512_opt (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_xsave (ElfW(Word)) attribute_hidden; ++ extern void _dl_runtime_resolve_xsavec (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile_sse (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile_avx (ElfW(Word)) attribute_hidden; + extern void _dl_runtime_profile_avx512 (ElfW(Word)) attribute_hidden; +@@ -120,29 +117,14 @@ elf_machine_runtime_setup (struct link_m + /* This function will get called to fix up the GOT entry + indicated by the offset on the stack, and then jump to + the resolved address. */ +- if (HAS_ARCH_FEATURE (AVX512F_Usable)) +- { +- if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt)) +- *(ElfW(Addr) *) (got + 2) +- = (ElfW(Addr)) &_dl_runtime_resolve_avx512_opt; +- else +- *(ElfW(Addr) *) (got + 2) +- = (ElfW(Addr)) &_dl_runtime_resolve_avx512; +- } +- else if (HAS_ARCH_FEATURE (AVX_Usable)) +- { +- if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_opt)) +- *(ElfW(Addr) *) (got + 2) +- = (ElfW(Addr)) &_dl_runtime_resolve_avx_opt; +- else if (HAS_ARCH_FEATURE (Use_dl_runtime_resolve_slow)) +- *(ElfW(Addr) *) (got + 2) +- = (ElfW(Addr)) &_dl_runtime_resolve_avx_slow; +- else +- *(ElfW(Addr) *) (got + 2) +- = (ElfW(Addr)) &_dl_runtime_resolve_avx; +- } ++ if (GLRO(dl_x86_cpu_features).xsave_state_size != 0) ++ *(ElfW(Addr) *) (got + 2) ++ = (HAS_ARCH_FEATURE (XSAVEC_Usable) ++ ? (ElfW(Addr)) &_dl_runtime_resolve_xsavec ++ : (ElfW(Addr)) &_dl_runtime_resolve_xsave); + else +- *(ElfW(Addr) *) (got + 2) = (ElfW(Addr)) &_dl_runtime_resolve_sse; ++ *(ElfW(Addr) *) (got + 2) ++ = (ElfW(Addr)) &_dl_runtime_resolve_fxsave; + } + } + +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-trampoline.S ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.S +@@ -34,37 +34,24 @@ + # define DL_STACK_ALIGNMENT 8 + #endif + +-#ifndef DL_RUNIME_UNALIGNED_VEC_SIZE +-/* The maximum size of unaligned vector load and store. */ +-# define DL_RUNIME_UNALIGNED_VEC_SIZE 16 +-#endif +- +-/* True if _dl_runtime_resolve should align stack to VEC_SIZE bytes. */ +-#define DL_RUNIME_RESOLVE_REALIGN_STACK \ +- (VEC_SIZE > DL_STACK_ALIGNMENT \ +- && VEC_SIZE > DL_RUNIME_UNALIGNED_VEC_SIZE) +- +-/* Align vector register save area to 16 bytes. */ +-#define REGISTER_SAVE_VEC_OFF 0 ++/* True if _dl_runtime_resolve should align stack for STATE_SAVE or align ++ stack to 16 bytes before calling _dl_fixup. */ ++#define DL_RUNTIME_RESOLVE_REALIGN_STACK \ ++ (STATE_SAVE_ALIGNMENT > DL_STACK_ALIGNMENT \ ++ || 16 > DL_STACK_ALIGNMENT) + + /* Area on stack to save and restore registers used for parameter + passing when calling _dl_fixup. */ + #ifdef __ILP32__ +-# define REGISTER_SAVE_RAX (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8) + # define PRESERVE_BND_REGS_PREFIX + #else +-/* Align bound register save area to 16 bytes. */ +-# define REGISTER_SAVE_BND0 (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 8) +-# define REGISTER_SAVE_BND1 (REGISTER_SAVE_BND0 + 16) +-# define REGISTER_SAVE_BND2 (REGISTER_SAVE_BND1 + 16) +-# define REGISTER_SAVE_BND3 (REGISTER_SAVE_BND2 + 16) +-# define REGISTER_SAVE_RAX (REGISTER_SAVE_BND3 + 16) + # ifdef HAVE_MPX_SUPPORT + # define PRESERVE_BND_REGS_PREFIX bnd + # else + # define PRESERVE_BND_REGS_PREFIX .byte 0xf2 + # endif + #endif ++#define REGISTER_SAVE_RAX 0 + #define REGISTER_SAVE_RCX (REGISTER_SAVE_RAX + 8) + #define REGISTER_SAVE_RDX (REGISTER_SAVE_RCX + 8) + #define REGISTER_SAVE_RSI (REGISTER_SAVE_RDX + 8) +@@ -72,71 +59,60 @@ + #define REGISTER_SAVE_R8 (REGISTER_SAVE_RDI + 8) + #define REGISTER_SAVE_R9 (REGISTER_SAVE_R8 + 8) + ++#define RESTORE_AVX ++ + #define VEC_SIZE 64 + #define VMOVA vmovdqa64 +-#if DL_RUNIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV vmovdqa64 +-#else +-# define VMOV vmovdqu64 +-#endif + #define VEC(i) zmm##i +-#define _dl_runtime_resolve _dl_runtime_resolve_avx512 + #define _dl_runtime_profile _dl_runtime_profile_avx512 +-#define RESTORE_AVX + #include "dl-trampoline.h" +-#undef _dl_runtime_resolve + #undef _dl_runtime_profile + #undef VEC +-#undef VMOV + #undef VMOVA + #undef VEC_SIZE + + #define VEC_SIZE 32 + #define VMOVA vmovdqa +-#if DL_RUNIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV vmovdqa +-#else +-# define VMOV vmovdqu +-#endif + #define VEC(i) ymm##i +-#define _dl_runtime_resolve _dl_runtime_resolve_avx +-#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx_opt + #define _dl_runtime_profile _dl_runtime_profile_avx + #include "dl-trampoline.h" +-#undef _dl_runtime_resolve +-#undef _dl_runtime_resolve_opt + #undef _dl_runtime_profile + #undef VEC +-#undef VMOV + #undef VMOVA + #undef VEC_SIZE + + /* movaps/movups is 1-byte shorter. */ + #define VEC_SIZE 16 + #define VMOVA movaps +-#if DL_RUNIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV movaps +-#else +-# define VMOV movups +- #endif + #define VEC(i) xmm##i +-#define _dl_runtime_resolve _dl_runtime_resolve_sse + #define _dl_runtime_profile _dl_runtime_profile_sse + #undef RESTORE_AVX + #include "dl-trampoline.h" +-#undef _dl_runtime_resolve + #undef _dl_runtime_profile +-#undef VMOV ++#undef VEC + #undef VMOVA ++#undef VEC_SIZE + +-/* Used by _dl_runtime_resolve_avx_opt/_dl_runtime_resolve_avx512_opt +- to preserve the full vector registers with zero upper bits. */ +-#define VMOVA vmovdqa +-#if DL_RUNTIME_RESOLVE_REALIGN_STACK || VEC_SIZE <= DL_STACK_ALIGNMENT +-# define VMOV vmovdqa +-#else +-# define VMOV vmovdqu +-#endif +-#define _dl_runtime_resolve _dl_runtime_resolve_sse_vex +-#define _dl_runtime_resolve_opt _dl_runtime_resolve_avx512_opt ++#define USE_FXSAVE ++#define STATE_SAVE_ALIGNMENT 16 ++#define _dl_runtime_resolve _dl_runtime_resolve_fxsave + #include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef USE_FXSAVE ++#undef STATE_SAVE_ALIGNMENT ++ ++#define USE_XSAVE ++#define STATE_SAVE_ALIGNMENT 64 ++#define _dl_runtime_resolve _dl_runtime_resolve_xsave ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef USE_XSAVE ++#undef STATE_SAVE_ALIGNMENT ++ ++#define USE_XSAVEC ++#define STATE_SAVE_ALIGNMENT 64 ++#define _dl_runtime_resolve _dl_runtime_resolve_xsavec ++#include "dl-trampoline.h" ++#undef _dl_runtime_resolve ++#undef USE_XSAVEC ++#undef STATE_SAVE_ALIGNMENT +Index: glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/dl-trampoline.h ++++ glibc-2.17-c758a686/sysdeps/x86_64/dl-trampoline.h +@@ -16,140 +16,47 @@ + License along with the GNU C Library; if not, see + . */ + +-#undef REGISTER_SAVE_AREA_RAW +-#ifdef __ILP32__ +-/* X32 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as VEC0 to +- VEC7. */ +-# define REGISTER_SAVE_AREA_RAW (8 * 7 + VEC_SIZE * 8) +-#else +-/* X86-64 saves RCX, RDX, RSI, RDI, R8 and R9 plus RAX as well as +- BND0, BND1, BND2, BND3 and VEC0 to VEC7. */ +-# define REGISTER_SAVE_AREA_RAW (8 * 7 + 16 * 4 + VEC_SIZE * 8) +-#endif ++ .text ++#ifdef _dl_runtime_resolve + +-#undef REGISTER_SAVE_AREA +-#undef LOCAL_STORAGE_AREA +-#undef BASE +-#if DL_RUNIME_RESOLVE_REALIGN_STACK +-# define REGISTER_SAVE_AREA (REGISTER_SAVE_AREA_RAW + 8) +-/* Local stack area before jumping to function address: RBX. */ +-# define LOCAL_STORAGE_AREA 8 +-# define BASE rbx +-# if (REGISTER_SAVE_AREA % VEC_SIZE) != 0 +-# error REGISTER_SAVE_AREA must be multples of VEC_SIZE +-# endif +-#else +-# define REGISTER_SAVE_AREA REGISTER_SAVE_AREA_RAW +-/* Local stack area before jumping to function address: All saved +- registers. */ +-# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA +-# define BASE rsp +-# if (REGISTER_SAVE_AREA % 16) != 8 +-# error REGISTER_SAVE_AREA must be odd multples of 8 ++# undef REGISTER_SAVE_AREA ++# undef LOCAL_STORAGE_AREA ++# undef BASE ++ ++# if (STATE_SAVE_ALIGNMENT % 16) != 0 ++# error STATE_SAVE_ALIGNMENT must be multples of 16 + # endif +-#endif + +- .text +-#ifdef _dl_runtime_resolve_opt +-/* Use the smallest vector registers to preserve the full YMM/ZMM +- registers to avoid SSE transition penalty. */ +- +-# if VEC_SIZE == 32 +-/* Check if the upper 128 bits in %ymm0 - %ymm7 registers are non-zero +- and preserve %xmm0 - %xmm7 registers with the zero upper bits. Since +- there is no SSE transition penalty on AVX512 processors which don't +- support XGETBV with ECX == 1, _dl_runtime_resolve_avx512_slow isn't +- provided. */ +- .globl _dl_runtime_resolve_avx_slow +- .hidden _dl_runtime_resolve_avx_slow +- .type _dl_runtime_resolve_avx_slow, @function +- .align 16 +-_dl_runtime_resolve_avx_slow: +- cfi_startproc +- cfi_adjust_cfa_offset(16) # Incorporate PLT +- vorpd %ymm0, %ymm1, %ymm8 +- vorpd %ymm2, %ymm3, %ymm9 +- vorpd %ymm4, %ymm5, %ymm10 +- vorpd %ymm6, %ymm7, %ymm11 +- vorpd %ymm8, %ymm9, %ymm9 +- vorpd %ymm10, %ymm11, %ymm10 +- vpcmpeqd %xmm8, %xmm8, %xmm8 +- vorpd %ymm9, %ymm10, %ymm10 +- vptest %ymm10, %ymm8 +- # Preserve %ymm0 - %ymm7 registers if the upper 128 bits of any +- # %ymm0 - %ymm7 registers aren't zero. +- PRESERVE_BND_REGS_PREFIX +- jnc _dl_runtime_resolve_avx +- # Use vzeroupper to avoid SSE transition penalty. +- vzeroupper +- # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits +- # when the upper 128 bits of %ymm0 - %ymm7 registers are zero. +- PRESERVE_BND_REGS_PREFIX +- jmp _dl_runtime_resolve_sse_vex +- cfi_adjust_cfa_offset(-16) # Restore PLT adjustment +- cfi_endproc +- .size _dl_runtime_resolve_avx_slow, .-_dl_runtime_resolve_avx_slow ++# if (STATE_SAVE_OFFSET % STATE_SAVE_ALIGNMENT) != 0 ++# error STATE_SAVE_OFFSET must be multples of STATE_SAVE_ALIGNMENT + # endif + +-/* Use XGETBV with ECX == 1 to check which bits in vector registers are +- non-zero and only preserve the non-zero lower bits with zero upper +- bits. */ +- .globl _dl_runtime_resolve_opt +- .hidden _dl_runtime_resolve_opt +- .type _dl_runtime_resolve_opt, @function +- .align 16 +-_dl_runtime_resolve_opt: +- cfi_startproc +- cfi_adjust_cfa_offset(16) # Incorporate PLT +- pushq %rax +- cfi_adjust_cfa_offset(8) +- cfi_rel_offset(%rax, 0) +- pushq %rcx +- cfi_adjust_cfa_offset(8) +- cfi_rel_offset(%rcx, 0) +- pushq %rdx +- cfi_adjust_cfa_offset(8) +- cfi_rel_offset(%rdx, 0) +- movl $1, %ecx +- xgetbv +- movl %eax, %r11d +- popq %rdx +- cfi_adjust_cfa_offset(-8) +- cfi_restore (%rdx) +- popq %rcx +- cfi_adjust_cfa_offset(-8) +- cfi_restore (%rcx) +- popq %rax +- cfi_adjust_cfa_offset(-8) +- cfi_restore (%rax) +-# if VEC_SIZE == 32 +- # For YMM registers, check if YMM state is in use. +- andl $bit_YMM_state, %r11d +- # Preserve %xmm0 - %xmm7 registers with the zero upper 128 bits if +- # YMM state isn't in use. +- PRESERVE_BND_REGS_PREFIX +- jz _dl_runtime_resolve_sse_vex +-# elif VEC_SIZE == 16 +- # For ZMM registers, check if YMM state and ZMM state are in +- # use. +- andl $(bit_YMM_state | bit_ZMM0_15_state), %r11d +- cmpl $bit_YMM_state, %r11d +- # Preserve %zmm0 - %zmm7 registers if ZMM state is in use. +- PRESERVE_BND_REGS_PREFIX +- jg _dl_runtime_resolve_avx512 +- # Preserve %ymm0 - %ymm7 registers with the zero upper 256 bits if +- # ZMM state isn't in use. +- PRESERVE_BND_REGS_PREFIX +- je _dl_runtime_resolve_avx +- # Preserve %xmm0 - %xmm7 registers with the zero upper 384 bits if +- # neither YMM state nor ZMM state are in use. ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK ++/* Local stack area before jumping to function address: RBX. */ ++# define LOCAL_STORAGE_AREA 8 ++# define BASE rbx ++# ifdef USE_FXSAVE ++/* Use fxsave to save XMM registers. */ ++# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET) ++# if (REGISTER_SAVE_AREA % 16) != 0 ++# error REGISTER_SAVE_AREA must be multples of 16 ++# endif ++# endif + # else +-# error Unsupported VEC_SIZE! ++# ifndef USE_FXSAVE ++# error USE_FXSAVE must be defined ++# endif ++/* Use fxsave to save XMM registers. */ ++# define REGISTER_SAVE_AREA (512 + STATE_SAVE_OFFSET + 8) ++/* Local stack area before jumping to function address: All saved ++ registers. */ ++# define LOCAL_STORAGE_AREA REGISTER_SAVE_AREA ++# define BASE rsp ++# if (REGISTER_SAVE_AREA % 16) != 8 ++# error REGISTER_SAVE_AREA must be odd multples of 8 ++# endif + # endif +- cfi_adjust_cfa_offset(-16) # Restore PLT adjustment +- cfi_endproc +- .size _dl_runtime_resolve_opt, .-_dl_runtime_resolve_opt +-#endif ++ + .globl _dl_runtime_resolve + .hidden _dl_runtime_resolve + .type _dl_runtime_resolve, @function +@@ -157,19 +64,30 @@ _dl_runtime_resolve_opt: + cfi_startproc + _dl_runtime_resolve: + cfi_adjust_cfa_offset(16) # Incorporate PLT +-#if DL_RUNIME_RESOLVE_REALIGN_STACK +-# if LOCAL_STORAGE_AREA != 8 +-# error LOCAL_STORAGE_AREA must be 8 +-# endif ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK ++# if LOCAL_STORAGE_AREA != 8 ++# error LOCAL_STORAGE_AREA must be 8 ++# endif + pushq %rbx # push subtracts stack by 8. + cfi_adjust_cfa_offset(8) + cfi_rel_offset(%rbx, 0) + mov %RSP_LP, %RBX_LP + cfi_def_cfa_register(%rbx) +- and $-VEC_SIZE, %RSP_LP +-#endif ++ and $-STATE_SAVE_ALIGNMENT, %RSP_LP ++# endif ++# ifdef REGISTER_SAVE_AREA + sub $REGISTER_SAVE_AREA, %RSP_LP ++# if !DL_RUNTIME_RESOLVE_REALIGN_STACK + cfi_adjust_cfa_offset(REGISTER_SAVE_AREA) ++# endif ++# else ++ # Allocate stack space of the required size to save the state. ++# if IS_IN (rtld) ++ sub _rtld_local_ro+RTLD_GLOBAL_RO_DL_X86_CPU_FEATURES_OFFSET+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP ++# else ++ sub _dl_x86_cpu_features+XSAVE_STATE_SIZE_OFFSET(%rip), %RSP_LP ++# endif ++# endif + # Preserve registers otherwise clobbered. + movq %rax, REGISTER_SAVE_RAX(%rsp) + movq %rcx, REGISTER_SAVE_RCX(%rsp) +@@ -178,59 +96,48 @@ _dl_runtime_resolve: + movq %rdi, REGISTER_SAVE_RDI(%rsp) + movq %r8, REGISTER_SAVE_R8(%rsp) + movq %r9, REGISTER_SAVE_R9(%rsp) +- VMOV %VEC(0), (REGISTER_SAVE_VEC_OFF)(%rsp) +- VMOV %VEC(1), (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp) +- VMOV %VEC(2), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp) +- VMOV %VEC(3), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp) +- VMOV %VEC(4), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp) +- VMOV %VEC(5), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp) +- VMOV %VEC(6), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp) +- VMOV %VEC(7), (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp) +-#ifndef __ILP32__ +- # We also have to preserve bound registers. These are nops if +- # Intel MPX isn't available or disabled. +-# ifdef HAVE_MPX_SUPPORT +- bndmov %bnd0, REGISTER_SAVE_BND0(%rsp) +- bndmov %bnd1, REGISTER_SAVE_BND1(%rsp) +- bndmov %bnd2, REGISTER_SAVE_BND2(%rsp) +- bndmov %bnd3, REGISTER_SAVE_BND3(%rsp) ++# ifdef USE_FXSAVE ++ fxsave STATE_SAVE_OFFSET(%rsp) + # else +-# if REGISTER_SAVE_BND0 == 0 +- .byte 0x66,0x0f,0x1b,0x04,0x24 ++ movl $STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ # Clear the XSAVE Header. ++# ifdef USE_XSAVE ++ movq %rdx, (STATE_SAVE_OFFSET + 512)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8)(%rsp) ++# endif ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 2)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 3)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 4)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 5)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 6)(%rsp) ++ movq %rdx, (STATE_SAVE_OFFSET + 512 + 8 * 7)(%rsp) ++# ifdef USE_XSAVE ++ xsave STATE_SAVE_OFFSET(%rsp) + # else +- .byte 0x66,0x0f,0x1b,0x44,0x24,REGISTER_SAVE_BND0 ++ # Since glibc 2.23 requires only binutils 2.22 or later, xsavec ++ # may not be supported. Use .byte directive instead. ++# if STATE_SAVE_OFFSET != 0x40 ++# error STATE_SAVE_OFFSET != 0x40 ++# endif ++ # xsavec STATE_SAVE_OFFSET(%rsp) ++ .byte 0x0f, 0xc7, 0x64, 0x24, 0x40 + # endif +- .byte 0x66,0x0f,0x1b,0x4c,0x24,REGISTER_SAVE_BND1 +- .byte 0x66,0x0f,0x1b,0x54,0x24,REGISTER_SAVE_BND2 +- .byte 0x66,0x0f,0x1b,0x5c,0x24,REGISTER_SAVE_BND3 + # endif +-#endif + # Copy args pushed by PLT in register. + # %rdi: link_map, %rsi: reloc_index + mov (LOCAL_STORAGE_AREA + 8)(%BASE), %RSI_LP + mov LOCAL_STORAGE_AREA(%BASE), %RDI_LP + call _dl_fixup # Call resolver. + mov %RAX_LP, %R11_LP # Save return value +-#ifndef __ILP32__ +- # Restore bound registers. These are nops if Intel MPX isn't +- # avaiable or disabled. +-# ifdef HAVE_MPX_SUPPORT +- bndmov REGISTER_SAVE_BND3(%rsp), %bnd3 +- bndmov REGISTER_SAVE_BND2(%rsp), %bnd2 +- bndmov REGISTER_SAVE_BND1(%rsp), %bnd1 +- bndmov REGISTER_SAVE_BND0(%rsp), %bnd0 ++ # Get register content back. ++# ifdef USE_FXSAVE ++ fxrstor STATE_SAVE_OFFSET(%rsp) + # else +- .byte 0x66,0x0f,0x1a,0x5c,0x24,REGISTER_SAVE_BND3 +- .byte 0x66,0x0f,0x1a,0x54,0x24,REGISTER_SAVE_BND2 +- .byte 0x66,0x0f,0x1a,0x4c,0x24,REGISTER_SAVE_BND1 +-# if REGISTER_SAVE_BND0 == 0 +- .byte 0x66,0x0f,0x1a,0x04,0x24 +-# else +- .byte 0x66,0x0f,0x1a,0x44,0x24,REGISTER_SAVE_BND0 +-# endif ++ movl $STATE_SAVE_MASK, %eax ++ xorl %edx, %edx ++ xrstor STATE_SAVE_OFFSET(%rsp) + # endif +-#endif +- # Get register content back. + movq REGISTER_SAVE_R9(%rsp), %r9 + movq REGISTER_SAVE_R8(%rsp), %r8 + movq REGISTER_SAVE_RDI(%rsp), %rdi +@@ -238,20 +145,12 @@ _dl_runtime_resolve: + movq REGISTER_SAVE_RDX(%rsp), %rdx + movq REGISTER_SAVE_RCX(%rsp), %rcx + movq REGISTER_SAVE_RAX(%rsp), %rax +- VMOV (REGISTER_SAVE_VEC_OFF)(%rsp), %VEC(0) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE)(%rsp), %VEC(1) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 2)(%rsp), %VEC(2) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 3)(%rsp), %VEC(3) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 4)(%rsp), %VEC(4) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 5)(%rsp), %VEC(5) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 6)(%rsp), %VEC(6) +- VMOV (REGISTER_SAVE_VEC_OFF + VEC_SIZE * 7)(%rsp), %VEC(7) +-#if DL_RUNIME_RESOLVE_REALIGN_STACK ++# if DL_RUNTIME_RESOLVE_REALIGN_STACK + mov %RBX_LP, %RSP_LP + cfi_def_cfa_register(%rsp) + movq (%rsp), %rbx + cfi_restore(%rbx) +-#endif ++# endif + # Adjust stack(PLT did 2 pushes) + add $(LOCAL_STORAGE_AREA + 16), %RSP_LP + cfi_adjust_cfa_offset(-(LOCAL_STORAGE_AREA + 16)) +@@ -260,11 +159,9 @@ _dl_runtime_resolve: + jmp *%r11 # Jump to function address. + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve ++#endif + + +-/* To preserve %xmm0 - %xmm7 registers, dl-trampoline.h is included +- twice, for _dl_runtime_resolve_sse and _dl_runtime_resolve_sse_vex. +- But we don't need another _dl_runtime_profile for XMM registers. */ + #if !defined PROF && defined _dl_runtime_profile + # if (LR_VECTOR_OFFSET % VEC_SIZE) != 0 + # error LR_VECTOR_OFFSET must be multples of VEC_SIZE diff --git a/SOURCES/glibc-rh1523119-compat-symbols.patch b/SOURCES/glibc-rh1523119-compat-symbols.patch new file mode 100644 index 00000000..af15096c --- /dev/null +++ b/SOURCES/glibc-rh1523119-compat-symbols.patch @@ -0,0 +1,175 @@ +Provide GLIBC_PRIVATE symbols no longer used by the current library +version to increase backwards compatibility during glibc updates. +This will help to avoid some of the issues that surface while a +glibc update is performed with concurrent application updates, +and it also allows old nscd to trigger cache invalidation in a +running nscd daemon. + +While at this, also add interfaces for supporting old nss_dns modules. + +This patch is not needed upstream because upstream does not provide +backwards compatibility for GLIBC_PRIVATE symbols. + +diff --git a/inet/herrno.c b/inet/herrno.c +index 0cd84445190728b3..4d26e9b254181422 100644 +--- a/inet/herrno.c ++++ b/inet/herrno.c +@@ -28,3 +28,9 @@ __thread int __h_errno; + extern __thread int __libc_h_errno __attribute__ ((alias ("__h_errno"))) + attribute_hidden; + #define h_errno __libc_h_errno ++ ++#ifdef SHARED ++/* Provide an alias for use by the old libpthread.so.0 during ++ updates. */ ++asm (".symver __h_errno, h_errno@GLIBC_PRIVATE"); ++#endif +diff --git a/resolv/res_libc.c b/resolv/res_libc.c +index 9f2d3c3bd442bb38..5ab02c79c72eb1ac 100644 +--- a/resolv/res_libc.c ++++ b/resolv/res_libc.c +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + + int + res_init (void) +@@ -80,7 +81,34 @@ res_init (void) + + return __res_vinit (&_res, 1); + } +- ++ ++#ifdef SHARED ++ ++/* An old nscd binary may bind to __res_maybe_init during a glibc ++ update. Emulate it using the new functions. Ignore PREINIT ++ because almost all existing __res_maybe_init callers used zero ++ PREINIT, and the difference for RESP == &_res is very minor (a ++ potential override of application configuration). */ ++attribute_compat_text_section ++int ++__res_maybe_init (res_state resp, int preinit) ++{ ++ if (resp == &_res) ++ { ++ /* This performs an implicit initialization of _res. */ ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ return -1; ++ __resolv_context_put (ctx); ++ return 0; ++ } ++ else ++ return __res_vinit (resp, 0); ++} ++asm (".symver __res_maybe_init, __res_maybe_init@GLIBC_PRIVATE"); ++ ++#endif /* SHARED */ ++ + /* This needs to be after the use of _res in res_init, above. */ + #undef _res + +diff --git a/resolv/res_query.c b/resolv/res_query.c +index ebbe5a6a4ed86abe..24fefb561e7f1f5e 100644 +--- a/resolv/res_query.c ++++ b/resolv/res_query.c +@@ -705,6 +705,96 @@ hostalias (const char *name) + (__resolv_context_get (), name, abuf, sizeof (abuf)); + } + ++#ifdef SHARED ++/* Compatibiliaty functions to support old nss_dns modules. */ ++ ++typedef int (*compat_query_function) (struct resolv_context *, ++ const char *name, ++ int class, int type, ++ u_char *answer, ++ int anslen, ++ u_char **answerp, ++ u_char **answerp2, ++ int *nanswerp2, ++ int *resplen2, ++ int *answerp2_malloced); ++ ++attribute_compat_text_section ++static int ++wrap_compat_call (compat_query_function qf, ++ res_state statp, ++ const char *name, /* domain name */ ++ int class, int type, /* class and type of query */ ++ u_char *answer, /* buffer to put answer */ ++ int anslen, /* size of answer buffer */ ++ u_char **answerp, /* if buffer needs to be enlarged */ ++ u_char **answerp2, ++ int *nanswerp2, ++ int *resplen2, ++ int *answerp2_malloced) ++{ ++ if (statp == &_res) ++ { ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ __set_h_errno (NO_RECOVERY); ++ return -1; ++ } ++ int ret = qf (ctx, name, class, type, ++ answer, anslen, answerp, answerp2, ++ nanswerp2, resplen2, answerp2_malloced); ++ __resolv_context_put (ctx); ++ return ret; ++ } ++ else ++ { ++ __set_h_errno (NO_RECOVERY); ++ __set_errno (ENOTSUP); ++ return -1; ++ } ++} ++ ++attribute_compat_text_section ++int ++__libc_res_nquery(res_state statp, ++ const char *name, /* domain name */ ++ int class, int type, /* class and type of query */ ++ u_char *answer, /* buffer to put answer */ ++ int anslen, /* size of answer buffer */ ++ u_char **answerp, /* if buffer needs to be enlarged */ ++ u_char **answerp2, ++ int *nanswerp2, ++ int *resplen2, ++ int *answerp2_malloced) ++{ ++ return wrap_compat_call (__res_context_query, statp, name, class, type, ++ answer, anslen, answerp, answerp2, ++ nanswerp2, resplen2, answerp2_malloced); ++} ++asm (".symver __libc_res_nquery, __libc_res_nquery@GLIBC_PRIVATE"); ++ ++attribute_compat_text_section ++int ++__libc_res_nsearch(res_state statp, ++ const char *name, /* domain name */ ++ int class, int type, /* class and type of query */ ++ u_char *answer, /* buffer to put answer */ ++ int anslen, /* size of answer */ ++ u_char **answerp, ++ u_char **answerp2, ++ int *nanswerp2, ++ int *resplen2, ++ int *answerp2_malloced) ++{ ++ return wrap_compat_call (__res_context_search, statp, name, class, type, ++ answer, anslen, answerp, answerp2, ++ nanswerp2, resplen2, answerp2_malloced); ++} ++asm (".symver __libc_res_nsearch, __libc_res_nsearch@GLIBC_PRIVATE"); ++ ++#endif /* SHARED */ ++ + #if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2) + # undef res_query + # undef res_querydomain diff --git a/SOURCES/glibc-rh1527904-1.patch b/SOURCES/glibc-rh1527904-1.patch new file mode 100644 index 00000000..2fc1cf5c --- /dev/null +++ b/SOURCES/glibc-rh1527904-1.patch @@ -0,0 +1,135 @@ +commit d8b778907e5270fdeb70459842ffbc20bd2ca5e1 +Author: Florian Weimer +Date: Thu Jan 11 13:13:14 2018 +0100 + + nptl: Add tst-minstack-cancel, tst-minstack-exit [BZ #22636] + + I verified that without the guard accounting change in commit + 630f4cc3aa019ede55976ea561f1a7af2f068639 (Fix stack guard size + accounting) and RTLD_NOW for libgcc_s introduced by commit + f993b8754080ac7572b692870e926d8b493db16c (nptl: Open libgcc.so with + RTLD_NOW during pthread_cancel), the tst-minstack-cancel test fails on + an AVX-512F machine. tst-minstack-exit still passes, and either of + the mentioned commit by itself frees sufficient stack space to make + tst-minstack-cancel pass, too. + + Reviewed-by: Carlos O'Donell + +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -267,7 +267,8 @@ tests = tst-typesizes \ + tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \ + tst-getpid1 tst-getpid2 tst-getpid3 \ + tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) \ +- tst-mutex-errorcheck ++ tst-mutex-errorcheck \ ++ tst-minstack-cancel tst-minstack-exit + xtests = tst-setuid1 tst-setuid1-static tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 + test-srcs = tst-oddstacklimit + +Index: glibc-2.17-c758a686/nptl/tst-minstack-cancel.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-minstack-cancel.c +@@ -0,0 +1,48 @@ ++/* Test cancellation with a minimal stack size. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Note: This test is similar to tst-minstack-exit, but is separate to ++ avoid spurious test passes due to warm-up effects. */ ++ ++#include ++#include ++#include ++#include ++ ++static void * ++threadfunc (void *closure) ++{ ++ while (1) ++ pause (); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_attr_t attr; ++ xpthread_attr_init (&attr); ++ xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); ++ pthread_t thr = xpthread_create (&attr, threadfunc, NULL); ++ xpthread_cancel (thr); ++ TEST_VERIFY (xpthread_join (thr) == PTHREAD_CANCELED); ++ xpthread_attr_destroy (&attr); ++ return 0; ++} ++ ++#include +Index: glibc-2.17-c758a686/nptl/tst-minstack-exit.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-minstack-exit.c +@@ -0,0 +1,46 @@ ++/* Test that pthread_exit works with the minimum stack size. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Note: This test is similar to tst-minstack-cancel, but is separate ++ to avoid spurious test passes due to warm-up effects. */ ++ ++#include ++#include ++#include ++#include ++ ++static void * ++threadfunc (void *closure) ++{ ++ pthread_exit (threadfunc); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ pthread_attr_t attr; ++ xpthread_attr_init (&attr); ++ xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); ++ pthread_t thr = xpthread_create (&attr, threadfunc, NULL); ++ TEST_VERIFY (xpthread_join (thr) == threadfunc); ++ xpthread_attr_destroy (&attr); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1527904-2.patch b/SOURCES/glibc-rh1527904-2.patch new file mode 100644 index 00000000..31be77b9 --- /dev/null +++ b/SOURCES/glibc-rh1527904-2.patch @@ -0,0 +1,136 @@ +This test requires a fix for max_align_t which is rolled into the +glibc-rh1418978-max_align_t.patch file. + +commit b725132d2b0aeddf970b1ce3e5a24f8637a7b4c2 +Author: Florian Weimer +Date: Tue Jan 16 07:19:28 2018 +0100 + + nptl/tst-minstack-throw: Compile in C++11 mode with GNU extensions + +commit 860b0240a5645edd6490161de3f8d1d1f2786025 +Author: Florian Weimer +Date: Mon Jan 15 15:30:00 2018 +0100 + + nptl: Add PTHREAD_MIN_STACK C++ throw test [BZ #22636] + +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -198,6 +198,7 @@ CFLAGS-send.c = -fexceptions -fasynchron + + CFLAGS-pt-system.c = -fexceptions + ++CFLAGS-tst-minstack-throw.cc = -std=gnu++11 + + tests = tst-typesizes \ + tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ +@@ -268,7 +269,7 @@ tests = tst-typesizes \ + tst-getpid1 tst-getpid2 tst-getpid3 \ + tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) \ + tst-mutex-errorcheck \ +- tst-minstack-cancel tst-minstack-exit ++ tst-minstack-cancel tst-minstack-exit tst-minstack-throw + xtests = tst-setuid1 tst-setuid1-static tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 + test-srcs = tst-oddstacklimit + +@@ -527,6 +528,7 @@ $(objpfx)tst-_res1: $(objpfx)tst-_res1mo + + LDLIBS-tst-cancel24 = $(no-as-needed) -lstdc++ + LDLIBS-tst-cancel24-static = $(LDLIBS-tst-cancel24) ++LDLIBS-tst-minstack-throw = -lstdc++ + + extra-B-pthread.so = -B$(common-objpfx)nptl/ + $(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs)) +Index: glibc-2.17-c758a686/nptl/tst-minstack-throw.cc +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-minstack-throw.cc +@@ -0,0 +1,87 @@ ++/* Test that throwing C++ exceptions works with the minimum stack size. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Throw a std::runtime_exception. */ ++__attribute__ ((noinline, noclone, weak)) ++void ++do_throw_exception () ++{ ++ throw std::runtime_error ("test exception"); ++} ++ ++/* Class with a destructor, to trigger unwind handling. */ ++struct class_with_destructor ++{ ++ class_with_destructor (); ++ ~class_with_destructor (); ++}; ++ ++__attribute__ ((noinline, noclone, weak)) ++class_with_destructor::class_with_destructor () ++{ ++} ++ ++__attribute__ ((noinline, noclone, weak)) ++class_with_destructor::~class_with_destructor () ++{ ++} ++ ++__attribute__ ((noinline, noclone, weak)) ++void ++function_with_destructed_object () ++{ ++ class_with_destructor obj; ++ do_throw_exception (); ++} ++ ++static void * ++threadfunc (void *closure) ++{ ++ try ++ { ++ function_with_destructed_object (); ++ FAIL_EXIT1 ("no exception thrown"); ++ } ++ catch (std::exception &e) ++ { ++ TEST_COMPARE (strcmp (e.what (), "test exception"), 0); ++ return reinterpret_cast (threadfunc); ++ } ++ FAIL_EXIT1 ("no exception caught"); ++} ++ ++static int ++do_test (void) ++{ ++ pthread_attr_t attr; ++ xpthread_attr_init (&attr); ++ xpthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); ++ pthread_t thr = xpthread_create (&attr, threadfunc, NULL); ++ TEST_VERIFY (xpthread_join (thr) == threadfunc); ++ xpthread_attr_destroy (&attr); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1527904-3.patch b/SOURCES/glibc-rh1527904-3.patch new file mode 100644 index 00000000..66d21040 --- /dev/null +++ b/SOURCES/glibc-rh1527904-3.patch @@ -0,0 +1,88 @@ +commit 630f4cc3aa019ede55976ea561f1a7af2f068639 +Author: Szabolcs Nagy +Date: Wed Dec 6 13:05:50 2017 +0000 + + [BZ #22637] Fix stack guard size accounting + + Previously if user requested S stack and G guard when creating a + thread, the total mapping was S and the actual available stack was + S - G - static_tls, which is not what the user requested. + + This patch fixes the guard size accounting by pretending the user + requested S+G stack. This way all later logic works out except + when reporting the user requested stack size (pthread_getattr_np) + or when computing the minimal stack size (__pthread_get_minstack). + + Normally this will increase thread stack allocations by one page. + TLS accounting is not affected, that will require a separate fix. + + [BZ #22637] + * nptl/descr.h (stackblock, stackblock_size): Update comments. + * nptl/allocatestack.c (allocate_stack): Add guardsize to stacksize. + * nptl/nptl-init.c (__pthread_get_minstack): Remove guardsize from + stacksize. + * nptl/pthread_getattr_np.c (pthread_getattr_np): Likewise. + +Index: glibc-2.17-c758a686/nptl/allocatestack.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/allocatestack.c ++++ glibc-2.17-c758a686/nptl/allocatestack.c +@@ -470,6 +470,10 @@ allocate_stack (const struct pthread_att + /* Make sure the size of the stack is enough for the guard and + eventually the thread descriptor. */ + guardsize = (attr->guardsize + pagesize_m1) & ~pagesize_m1; ++ if (guardsize < attr->guardsize || size + guardsize < guardsize) ++ /* Arithmetic overflow. */ ++ return EINVAL; ++ size += guardsize; + if (__builtin_expect (size < ((guardsize + __static_tls_size + + MINIMAL_REST_STACK + pagesize_m1) + & ~pagesize_m1), +Index: glibc-2.17-c758a686/nptl/descr.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/descr.h ++++ glibc-2.17-c758a686/nptl/descr.h +@@ -366,9 +366,9 @@ struct pthread + struct _Unwind_Exception exc; + #endif + +- /* If nonzero pointer to area allocated for the stack and its +- size. */ ++ /* If nonzero, pointer to the area allocated for the stack and guard. */ + void *stackblock; ++ /* Size of the stackblock area including the guard. */ + size_t stackblock_size; + /* Size of the included guard area. */ + size_t guardsize; +Index: glibc-2.17-c758a686/nptl/nptl-init.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/nptl-init.c ++++ glibc-2.17-c758a686/nptl/nptl-init.c +@@ -500,8 +500,5 @@ strong_alias (__pthread_initialize_minim + size_t + __pthread_get_minstack (const pthread_attr_t *attr) + { +- struct pthread_attr *iattr = (struct pthread_attr *) attr; +- +- return (GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN +- + iattr->guardsize); ++ return GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN; + } +Index: glibc-2.17-c758a686/nptl/pthread_getattr_np.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_getattr_np.c ++++ glibc-2.17-c758a686/nptl/pthread_getattr_np.c +@@ -59,8 +59,11 @@ pthread_getattr_np (thread_id, attr) + /* The sizes are subject to alignment. */ + if (__builtin_expect (thread->stackblock != NULL, 1)) + { +- iattr->stacksize = thread->stackblock_size; +- iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize; ++ /* The stack size reported to the user should not include the ++ guard size. */ ++ iattr->stacksize = thread->stackblock_size - thread->guardsize; ++ iattr->stackaddr = (char *) thread->stackblock ++ + thread->stackblock_size; + } + else + { diff --git a/SOURCES/glibc-rh1527904-4.patch b/SOURCES/glibc-rh1527904-4.patch new file mode 100644 index 00000000..b718b3ef --- /dev/null +++ b/SOURCES/glibc-rh1527904-4.patch @@ -0,0 +1,58 @@ +commit 08c6e95234c60a5c2f37532d1111acf084f39345 +Author: Florian Weimer +Date: Thu Jan 11 13:13:28 2018 +0100 + + csu: Update __libgcc_s_init comment + + Reviewed-by: Carlos O'Donell + +commit f993b8754080ac7572b692870e926d8b493db16c +Author: Florian Weimer +Date: Wed Jan 10 13:18:04 2018 +0100 + + nptl: Open libgcc.so with RTLD_NOW during pthread_cancel [BZ #22636] + + Disabling lazy binding reduces stack usage during unwinding. + + Note that RTLD_NOW only makes a difference if libgcc.so has not + already been loaded, so this is only a partial fix. + + Reviewed-by: Adhemerval Zanella + +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/unwind-forcedunwind.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/unwind-forcedunwind.c ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/unwind-forcedunwind.c +@@ -51,7 +51,7 @@ pthread_cancel_init (void) + return; + } + +- handle = __libc_dlopen (LIBGCC_S_SO); ++ handle = __libc_dlopen_mode (LIBGCC_S_SO, RTLD_NOW | __RTLD_DLOPEN); + + if (handle == NULL + || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL +Index: glibc-2.17-c758a686/sysdeps/gnu/unwind-resume.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/gnu/unwind-resume.c ++++ glibc-2.17-c758a686/sysdeps/gnu/unwind-resume.c +@@ -35,12 +35,17 @@ init (void) + void *resume, *personality; + void *handle; + +- handle = __libc_dlopen (LIBGCC_S_SO); ++ /* Use RTLD_NOW here for consistency with pthread_cancel_init. ++ RTLD_NOW will rarely make a difference here because unwinding is ++ already in progress, so libgcc_s.so has already been loaded if ++ its unwinder is used. */ ++ handle = __libc_dlopen_mode (LIBGCC_S_SO, RTLD_NOW | __RTLD_DLOPEN); + + if (handle == NULL + || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL + || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) +- __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); ++ __libc_fatal (LIBGCC_S_SO ++ " must be installed for unwinding to work\n"); + + libgcc_s_resume = resume; + libgcc_s_personality = personality; diff --git a/SOURCES/glibc-rh1529982.patch b/SOURCES/glibc-rh1529982.patch new file mode 100644 index 00000000..104c1dcc --- /dev/null +++ b/SOURCES/glibc-rh1529982.patch @@ -0,0 +1,301 @@ +The required TEST_COMPARE and C++ changes are included in the +support/ rebase in glibc-rh1418978-1.patch + +commit 579396ee082565ab5f42ff166a264891223b7b82 +Author: Florian Weimer +Date: Mon Jan 8 14:57:25 2018 +0100 + + nptl: Add test for callee-saved register restore in pthread_exit + + GCC PR 83641 results in a miscompilation of libpthread, which + causes pthread_exit not to restore callee-saved registers before + running destructors for objects on the stack. This test detects + this situation: + + info: unsigned int, direct pthread_exit call + tst-thread-exit-clobber.cc:80: numeric comparison failure + left: 4148288912 (0xf741dd90); from: value + right: 1600833940 (0x5f6ac994); from: magic_values.v2 + info: double, direct pthread_exit call + info: unsigned int, indirect pthread_exit call + info: double, indirect pthread_exit call + error: 1 test failures + +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -199,6 +199,7 @@ CFLAGS-send.c = -fexceptions -fasynchron + CFLAGS-pt-system.c = -fexceptions + + CFLAGS-tst-minstack-throw.cc = -std=gnu++11 ++CFLAGS-tst-thread-exit-clobber.o = -std=gnu++11 + + tests = tst-typesizes \ + tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ +@@ -269,7 +270,8 @@ tests = tst-typesizes \ + tst-getpid1 tst-getpid2 tst-getpid3 \ + tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) \ + tst-mutex-errorcheck \ +- tst-minstack-cancel tst-minstack-exit tst-minstack-throw ++ tst-minstack-cancel tst-minstack-exit tst-minstack-throw \ ++ tst-thread-exit-clobber + xtests = tst-setuid1 tst-setuid1-static tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 + test-srcs = tst-oddstacklimit + +@@ -529,6 +531,7 @@ $(objpfx)tst-_res1: $(objpfx)tst-_res1mo + LDLIBS-tst-cancel24 = $(no-as-needed) -lstdc++ + LDLIBS-tst-cancel24-static = $(LDLIBS-tst-cancel24) + LDLIBS-tst-minstack-throw = -lstdc++ ++LDLIBS-tst-thread-exit-clobber = -lstdc++ + + extra-B-pthread.so = -B$(common-objpfx)nptl/ + $(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs)) +Index: glibc-2.17-c758a686/nptl/tst-thread-exit-clobber.cc +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-thread-exit-clobber.cc +@@ -0,0 +1,243 @@ ++/* Test that pthread_exit does not clobber callee-saved registers. ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* This test attempts to check that callee-saved registers are ++ restored to their original values when destructors are run after ++ pthread_exit is called. GCC PR 83641 causes this test to fail. ++ ++ The constants have been chosen randomly and are magic values which ++ are used to detect whether registers have been clobbered. The idea ++ is that these values are hidden behind a compiler barrier and only ++ present in .rodata initially, so that it is less likely that they ++ are in a register by accident. ++ ++ The checker class can be stored in registers, and the magic values ++ are directly loaded into these registers. The checker destructor ++ is eventually invoked by pthread_exit and calls one of the ++ check_magic functions to verify that the class contents (that is, ++ register value) is correct. ++ ++ These tests are performed both for unsigned int and double values, ++ to cover different calling conventions. */ ++ ++template ++struct values ++{ ++ T v0; ++ T v1; ++ T v2; ++ T v3; ++ T v4; ++}; ++ ++static const values magic_values = ++ { ++ 0x57f7fc72, ++ 0xe582daba, ++ 0x5f6ac994, ++ 0x35efddb7, ++ 0x1fbf5a74, ++ }; ++ ++static const values magic_values_double = ++ { ++ 0.6764041905675465, ++ 0.9533336788140494, ++ 0.6091161359041452, ++ 0.7668653957125336, ++ 0.010374520235509666, ++ }; ++ ++/* Special index value which tells check_magic that no check should be ++ performed. */ ++enum { no_check = -1 }; ++ ++/* Check that VALUE is the magic value for INDEX, behind a compiler ++ barrier. */ ++__attribute__ ((noinline, noclone, weak)) ++void ++check_magic (int index, unsigned int value) ++{ ++ switch (index) ++ { ++ case 0: ++ TEST_COMPARE (value, magic_values.v0); ++ break; ++ case 1: ++ TEST_COMPARE (value, magic_values.v1); ++ break; ++ case 2: ++ TEST_COMPARE (value, magic_values.v2); ++ break; ++ case 3: ++ TEST_COMPARE (value, magic_values.v3); ++ break; ++ case 4: ++ TEST_COMPARE (value, magic_values.v4); ++ break; ++ case no_check: ++ break; ++ default: ++ FAIL_EXIT1 ("invalid magic value index %d", index); ++ } ++} ++ ++/* Check that VALUE is the magic value for INDEX, behind a compiler ++ barrier. Double variant. */ ++__attribute__ ((noinline, noclone, weak)) ++void ++check_magic (int index, double value) ++{ ++ switch (index) ++ { ++ case 0: ++ TEST_VERIFY (value == magic_values_double.v0); ++ break; ++ case 1: ++ TEST_VERIFY (value == magic_values_double.v1); ++ break; ++ case 2: ++ TEST_VERIFY (value == magic_values_double.v2); ++ break; ++ case 3: ++ TEST_VERIFY (value == magic_values_double.v3); ++ break; ++ case 4: ++ TEST_VERIFY (value == magic_values_double.v4); ++ break; ++ case no_check: ++ break; ++ default: ++ FAIL_EXIT1 ("invalid magic value index %d", index); ++ } ++} ++ ++/* Store a magic value and check, via the destructor, that it has the ++ expected value. */ ++template ++struct checker ++{ ++ T value; ++ ++ checker (T v) ++ : value (v) ++ { ++ } ++ ++ ~checker () ++ { ++ check_magic (I, value); ++ } ++}; ++ ++/* The functions call_pthread_exit_0, call_pthread_exit_1, ++ call_pthread_exit are used to call pthread_exit indirectly, with ++ the intent of clobbering the register values. */ ++ ++__attribute__ ((noinline, noclone, weak)) ++void ++call_pthread_exit_0 (const values *pvalues) ++{ ++ checker c0 (pvalues->v0); ++ checker c1 (pvalues->v1); ++ checker c2 (pvalues->v2); ++ checker c3 (pvalues->v3); ++ checker c4 (pvalues->v4); ++ ++ pthread_exit (NULL); ++} ++ ++__attribute__ ((noinline, noclone, weak)) ++void ++call_pthread_exit_1 (const values *pvalues) ++{ ++ checker c0 (pvalues->v0); ++ checker c1 (pvalues->v1); ++ checker c2 (pvalues->v2); ++ checker c3 (pvalues->v3); ++ checker c4 (pvalues->v4); ++ ++ values other_values = { 0, }; ++ call_pthread_exit_0 (&other_values); ++} ++ ++__attribute__ ((noinline, noclone, weak)) ++void ++call_pthread_exit () ++{ ++ values other_values = { 0, }; ++ call_pthread_exit_1 (&other_values); ++} ++ ++/* Create on-stack objects and check that their values are restored by ++ pthread_exit. If Nested is true, call pthread_exit indirectly via ++ call_pthread_exit. */ ++template ++__attribute__ ((noinline, noclone, weak)) ++void * ++threadfunc (void *closure) ++{ ++ const values *pvalues = static_cast *> (closure); ++ ++ checker c0 (pvalues->v0); ++ checker c1 (pvalues->v1); ++ checker c2 (pvalues->v2); ++ checker c3 (pvalues->v3); ++ checker c4 (pvalues->v4); ++ ++ if (Nested) ++ call_pthread_exit (); ++ else ++ pthread_exit (NULL); ++ ++ /* This should not be reached. */ ++ return const_cast (""); ++} ++ ++static int ++do_test () ++{ ++ puts ("info: unsigned int, direct pthread_exit call"); ++ pthread_t thr ++ = xpthread_create (NULL, &threadfunc, ++ const_cast *> (&magic_values)); ++ TEST_VERIFY (xpthread_join (thr) == NULL); ++ ++ puts ("info: double, direct pthread_exit call"); ++ thr = xpthread_create (NULL, &threadfunc, ++ const_cast *> (&magic_values_double)); ++ TEST_VERIFY (xpthread_join (thr) == NULL); ++ ++ puts ("info: unsigned int, indirect pthread_exit call"); ++ thr = xpthread_create (NULL, &threadfunc, ++ const_cast *> (&magic_values)); ++ TEST_VERIFY (xpthread_join (thr) == NULL); ++ ++ puts ("info: double, indirect pthread_exit call"); ++ thr = xpthread_create (NULL, &threadfunc, ++ const_cast *> (&magic_values_double)); ++ TEST_VERIFY (xpthread_join (thr) == NULL); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1534635.patch b/SOURCES/glibc-rh1534635.patch new file mode 100644 index 00000000..cf0be04a --- /dev/null +++ b/SOURCES/glibc-rh1534635.patch @@ -0,0 +1,141 @@ +commit 52a713fdd0a30e1bd79818e2e3c4ab44ddca1a94 +Author: Dmitry V. Levin +Date: Sun Jan 7 02:03:41 2018 +0000 + + linux: make getcwd(3) fail if it cannot obtain an absolute path [BZ #22679] + + Currently getcwd(3) can succeed without returning an absolute path + because the underlying getcwd syscall, starting with linux commit + v2.6.36-rc1~96^2~2, may succeed without returning an absolute path. + + This is a conformance issue because "The getcwd() function shall + place an absolute pathname of the current working directory + in the array pointed to by buf, and return buf". + + This is also a security issue because a non-absolute path returned + by getcwd(3) causes a buffer underflow in realpath(3). + + Fix this by checking the path returned by getcwd syscall and falling + back to generic_getcwd if the path is not absolute, effectively making + getcwd(3) fail with ENOENT. The error code is chosen for consistency + with the case when the current directory is unlinked. + + [BZ #22679] + CVE-2018-1000001 + * sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Fall back to + generic_getcwd if the path returned by getcwd syscall is not absolute. + * io/tst-getcwd-abspath.c: New test. + * io/Makefile (tests): Add tst-getcwd-abspath. + +Index: glibc-2.17-c758a686/io/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/io/Makefile ++++ glibc-2.17-c758a686/io/Makefile +@@ -70,7 +70,8 @@ tests := test-utime test-stat test-stat + tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \ + tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5 \ + tst-posix_fallocate \ +- tst-open-tmpfile ++ tst-open-tmpfile \ ++ tst-getcwd-abspath + + include ../Rules + +Index: glibc-2.17-c758a686/io/tst-getcwd-abspath.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/io/tst-getcwd-abspath.c +@@ -0,0 +1,66 @@ ++/* BZ #22679 getcwd(3) should not succeed without returning an absolute path. ++ ++ Copyright (C) 2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static char *chroot_dir; ++ ++/* The actual test. Run it in a subprocess, so that the test harness ++ can remove the temporary directory in --direct mode. */ ++static void ++getcwd_callback (void *closure) ++{ ++ xchroot (chroot_dir); ++ ++ errno = 0; ++ char *cwd = getcwd (NULL, 0); ++ TEST_COMPARE (errno, ENOENT); ++ TEST_VERIFY (cwd == NULL); ++ ++ errno = 0; ++ cwd = realpath (".", NULL); ++ TEST_COMPARE (errno, ENOENT); ++ TEST_VERIFY (cwd == NULL); ++ ++ _exit (0); ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ if (!support_can_chroot ()) ++ return EXIT_UNSUPPORTED; ++ ++ chroot_dir = support_create_temp_directory ("tst-getcwd-abspath-"); ++ support_isolate_in_subprocess (getcwd_callback, NULL); ++ ++ return 0; ++} ++ ++#include +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/getcwd.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/getcwd.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/getcwd.c +@@ -79,7 +79,7 @@ __getcwd (char *buf, size_t size) + int retval; + + retval = INLINE_SYSCALL (getcwd, 2, CHECK_STRING (path), alloc_size); +- if (retval >= 0) ++ if (retval >= 0 && path[0] == '/') + { + #ifndef NO_ALLOCATION + if (buf == NULL && size == 0) +@@ -95,10 +95,10 @@ __getcwd (char *buf, size_t size) + return buf; + } + +- /* The system call cannot handle paths longer than a page. +- Neither can the magic symlink in /proc/self. Just use the ++ /* The system call either cannot handle paths longer than a page ++ or can succeed without returning an absolute path. Just use the + generic implementation right away. */ +- if (errno == ENAMETOOLONG) ++ if (retval >= 0 || errno == ENAMETOOLONG) + { + #ifndef NO_ALLOCATION + if (buf == NULL && size == 0) diff --git a/SOURCES/glibc-rh677316-RES_USE_INET6.patch b/SOURCES/glibc-rh677316-RES_USE_INET6.patch new file mode 100644 index 00000000..686e279d --- /dev/null +++ b/SOURCES/glibc-rh677316-RES_USE_INET6.patch @@ -0,0 +1,461 @@ +Backport this upstream commit, but without the resolv/resolv.h change +which introduces the deprecation warning: + +commit b76e065991ec01299225d9da90a627ebe6c1ac97 +Author: Florian Weimer +Date: Tue Oct 4 11:52:10 2016 +0200 + + resolv: Deprecate the "inet6" option and RES_USE_INET6 [BZ #19582] + +No Makefile changes are needed here because we have not backported the +resolver testsuite at this point. Furthermore, due to the lack of +actual RES_USE_INET6 deprecation, resolv/gethnamaddr.c is not modified +in this patch (because it still compiles). + +diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c +index d79b0bd9c79173c8..fa2d79e7b69da57b 100644 +--- a/nis/nss_nis/nis-hosts.c ++++ b/nis/nss_nis/nis-hosts.c +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -232,8 +232,8 @@ _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen, + __libc_lock_lock (lock); + + status = internal_nis_gethostent_r (host, buffer, buflen, errnop, h_errnop, +- ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), +- ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0 )); ++ (res_use_inet6 () ? AF_INET6 : AF_INET), ++ (res_use_inet6 () ? AI_V4MAPPED : 0 )); + + __libc_lock_unlock (lock); + +@@ -345,7 +345,7 @@ _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host, + + return internal_gethostbyname2_r (name, af, host, buffer, buflen, errnop, + h_errnop, +- ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)); ++ (res_use_inet6 () ? AI_V4MAPPED : 0)); + } + + +@@ -353,7 +353,7 @@ enum nss_status + _nss_nis_gethostbyname_r (const char *name, struct hostent *host, char *buffer, + size_t buflen, int *errnop, int *h_errnop) + { +- if (_res.options & RES_USE_INET6) ++ if (res_use_inet6 ()) + { + enum nss_status status; + +@@ -427,9 +427,8 @@ _nss_nis_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, + free (result); + + int parse_res = parse_line (p, host, data, buflen, errnop, af, +- ((_res.options & RES_USE_INET6) +- ? AI_V4MAPPED : 0)); +- if (__builtin_expect (parse_res < 1, 0)) ++ (res_use_inet6 () ? AI_V4MAPPED : 0)); ++ if (__glibc_unlikely (parse_res < 1)) + { + if (parse_res == -1) + { +diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c +index 772d71097d6a2442..fb7461579b5408c9 100644 +--- a/nis/nss_nisplus/nisplus-hosts.c ++++ b/nis/nss_nisplus/nisplus-hosts.c +@@ -43,6 +43,7 @@ static u_long tablename_len; + (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) + + /* Get implementation for some internal functions. */ ++#include + #include + + +@@ -321,7 +322,7 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer, + } + } + +- if (_res.options & RES_USE_INET6) ++ if (res_use_inet6 ()) + parse_res = _nss_nisplus_parse_hostent (result, AF_INET6, host, buffer, + buflen, errnop, AI_V4MAPPED); + else +@@ -488,7 +489,7 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host, + + return internal_gethostbyname2_r (name, af, host, buffer, buflen, errnop, + herrnop, +- ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)); ++ (res_use_inet6 () ? AI_V4MAPPED : 0)); + } + + +@@ -497,7 +498,7 @@ _nss_nisplus_gethostbyname_r (const char *name, struct hostent *host, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) + { +- if (_res.options & RES_USE_INET6) ++ if (res_use_inet6 ()) + { + enum nss_status status; + +@@ -558,7 +559,7 @@ _nss_nisplus_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, + + parse_res = _nss_nisplus_parse_hostent (result, af, host, + buffer, buflen, errnop, +- ((_res.options & RES_USE_INET6) ++ (res_use_inet6 () + ? AI_V4MAPPED : 0)); + nis_freeresult (result); + +diff --git a/nscd/aicache.c b/nscd/aicache.c +index abab042757920811..0ee25247cd464940 100644 +--- a/nscd/aicache.c ++++ b/nscd/aicache.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + #include "dbg_log.h" +@@ -112,7 +113,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + IPv6 addresses. Currently this is decided by setting the + RES_USE_INET6 bit in _res.options. */ + int old_res_options = _res.options; +- _res.options &= ~RES_USE_INET6; ++ _res.options &= ~DEPRECATED_RES_USE_INET6; + + size_t tmpbuf6len = 1024; + char *tmpbuf6 = alloca (tmpbuf6len); +@@ -537,7 +538,7 @@ next_nip: + } + + out: +- _res.options |= old_res_options & RES_USE_INET6; ++ _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; + + if (dataset != NULL && !alloca_used) + { +diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c +index d64ad2e7b6c9e58b..41488ed6c033ffcd 100644 +--- a/nscd/nscd_gethst_r.c ++++ b/nscd/nscd_gethst_r.c +@@ -17,7 +17,7 @@ + . */ + + #include +-#include ++#include + #include + #include + #include +@@ -41,7 +41,7 @@ __nscd_gethostbyname_r (const char *name, struct hostent *resultbuf, + { + request_type reqtype; + +- reqtype = (_res.options & RES_USE_INET6) ? GETHOSTBYNAMEv6 : GETHOSTBYNAME; ++ reqtype = res_use_inet6 () ? GETHOSTBYNAMEv6 : GETHOSTBYNAME; + + return nscd_gethst_r (name, strlen (name) + 1, reqtype, resultbuf, + buffer, buflen, result, h_errnop); +diff --git a/nss/digits_dots.c b/nss/digits_dots.c +index ee530c69610d5393..7a2b57bdebe03408 100644 +--- a/nss/digits_dots.c ++++ b/nss/digits_dots.c +@@ -22,7 +22,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include "nsswitch.h" +@@ -80,7 +80,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + break; + + default: +- af = (_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET; ++ af = res_use_inet6 () ? AF_INET6 : AF_INET; + addr_size = af == AF_INET6 ? IN6ADDRSZ : INADDRSZ; + break; + } +@@ -167,7 +167,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + (*h_addr_ptrs)[0] = (char *) host_addr; + (*h_addr_ptrs)[1] = NULL; + resbuf->h_addr_list = *h_addr_ptrs; +- if (af == AF_INET && (_res.options & RES_USE_INET6)) ++ if (af == AF_INET && res_use_inet6 ()) + { + /* We need to change the IP v4 address into the + IP v6 address. */ +@@ -211,7 +211,7 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + switch (af) + { + default: +- af = (_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET; ++ af = res_use_inet6 () ? AF_INET6 : AF_INET; + if (af == AF_INET6) + { + addr_size = IN6ADDRSZ; +diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c +index 6c06b89dc179fd9a..b25ebe5ed19bdded 100644 +--- a/nss/nss_files/files-hosts.c ++++ b/nss/nss_files/files-hosts.c +@@ -21,7 +21,7 @@ + #include + #include + #include +-#include ++#include + + + /* Get implementation for some internal functions. */ +@@ -98,8 +98,8 @@ LINE_PARSER + }) + + #define EXTRA_ARGS_VALUE \ +- , ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \ +- ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0) ++ , (res_use_inet6 () ? AF_INET6 : AF_INET), \ ++ (res_use_inet6 () ? AI_V4MAPPED : 0) + #include "files-XXX.c" + #undef EXTRA_ARGS_VALUE + +@@ -133,7 +133,7 @@ _nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result, + { + /* XXX Is using _res to determine whether we want to convert IPv4 + addresses to IPv6 addresses really the right thing to do? */ +- int flags = ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0); ++ int flags = (res_use_inet6 () ? AI_V4MAPPED : 0); + + /* Tell getent function that we have repositioned the file pointer. */ + last_use = getby; +@@ -358,7 +358,7 @@ _nss_files_gethostbyname_r (const char *name, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *herrnop) + { +- int af = ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET); ++ int af = (res_use_inet6 () ? AF_INET6 : AF_INET); + + return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen, + errnop, herrnop, NULL, NULL); +diff --git a/resolv/README b/resolv/README +index 416205da77a15564..1a70bbb1dc615ac9 100644 +--- a/resolv/README ++++ b/resolv/README +@@ -84,11 +84,7 @@ code: + + * In Multi-threaded that manipulate the _res structure, calls to + functions like `gethostbyname' in threads other than the "main" +- thread won't be influenced by the those changes anymore. So if you +- set RES_USE_INET6, a call to `gethostbyname' won't return any IPv6 +- hosts anymore. If you recompile such programs, manipulating the +- _res structure will affect the thread in which you do so instead of +- the "main" thread. ++ thread won't be influenced by the those changes anymore. + + We recommend to use the new thread-safe interfaces in new code, since + the traditional interfaces have been deprecated by the BIND folks. +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 774d575dd1ce22af..7fc154db5d3130a3 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -82,7 +82,8 @@ + + #include "nsswitch.h" + +-/* Get implementation for some internal functions. */ ++/* Get implementeation for some internal functions. */ ++#include + #include + #include + +@@ -221,7 +222,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, + /* If we are looking for an IPv6 address and mapping is enabled + by having the RES_USE_INET6 bit in _res.options set, we try + another lookup. */ +- if (af == AF_INET6 && (_res.options & RES_USE_INET6)) ++ if (af == AF_INET6 && res_use_inet6 ()) + n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf, + host_buffer.buf != orig_host_buffer + ? MAXPACKET : 1024, &host_buffer.ptr, +@@ -266,7 +267,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + { + enum nss_status status = NSS_STATUS_NOTFOUND; + +- if (_res.options & RES_USE_INET6) ++ if (res_use_inet6 ()) + status = _nss_dns_gethostbyname3_r (name, AF_INET6, result, buffer, + buflen, errnop, h_errnop, NULL, NULL); + if (status == NSS_STATUS_NOTFOUND) +@@ -519,17 +520,6 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + memcpy (host_data->host_addr, addr, len); + host_data->h_addr_ptrs[0] = (char *) host_data->host_addr; + host_data->h_addr_ptrs[1] = NULL; +-#if 0 +- /* XXX I think this is wrong. Why should an IPv4 address be +- converted to IPv6 if the user explicitly asked for IPv4? */ +- if (af == AF_INET && (_res.options & RES_USE_INET6)) +- { +- map_v4v6_address ((char *) host_data->host_addr, +- (char *) host_data->host_addr); +- result->h_addrtype = AF_INET6; +- result->h_length = IN6ADDRSZ; +- } +-#endif + *h_errnop = NETDB_SUCCESS; + return NSS_STATUS_SUCCESS; + } +diff --git a/resolv/res_debug.c b/resolv/res_debug.c +index 3daa44e273db5a41..6549e4ba5ee77f93 100644 +--- a/resolv/res_debug.c ++++ b/resolv/res_debug.c +@@ -106,7 +106,7 @@ static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vix + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -582,7 +582,7 @@ p_option(u_long option) { + case RES_DNSRCH: return "dnsrch"; + case RES_INSECURE1: return "insecure1"; + case RES_INSECURE2: return "insecure2"; +- case RES_USE_INET6: return "inet6"; ++ case DEPRECATED_RES_USE_INET6: return "inet6"; + case RES_ROTATE: return "rotate"; + case RES_NOCHECKNAME: return "no-check-names"; + case RES_USEBSTRING: return "ip6-bytstring"; +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 2e3d0f746e855aff..0ed74e0520131418 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -71,7 +71,7 @@ static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixi + + #include + #include +-#include ++#include + #include + #include + #include +@@ -530,7 +530,7 @@ res_setoptions(res_state statp, const char *options, const char *source) { + unsigned long int flag; + } options[] = { + #define STRnLEN(str) str, sizeof (str) - 1 +- { STRnLEN ("inet6"), 0, RES_USE_INET6 }, ++ { STRnLEN ("inet6"), 0, DEPRECATED_RES_USE_INET6 }, + { STRnLEN ("ip6-bytestring"), 0, RES_USEBSTRING }, + { STRnLEN ("no-ip6-dotint"), 0, RES_NOIP6DOTINT }, + { STRnLEN ("ip6-dotint"), 1, ~RES_NOIP6DOTINT }, +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +new file mode 100644 +index 0000000000000000..269758c416544cb4 +--- /dev/null ++++ b/resolv/resolv-internal.h +@@ -0,0 +1,35 @@ ++/* libresolv interfaces for internal use across glibc. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _RESOLV_INTERNAL_H ++#define _RESOLV_INTERNAL_H 1 ++ ++#include ++#include ++ ++/* Internal version of RES_USE_INET6 which does not trigger a ++ deprecation warning. */ ++#define DEPRECATED_RES_USE_INET6 0x00002000 ++ ++static inline bool ++res_use_inet6 (void) ++{ ++ return _res.options & DEPRECATED_RES_USE_INET6; ++} ++ ++#endif /* _RESOLV_INTERNAL_H */ +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index a678d8d7e8b23d1d..7a6cf71c170ec42f 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -41,7 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + #include + #include + #include +@@ -222,7 +222,7 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, + if (herrno == NETDB_INTERNAL) \ + { \ + __set_h_errno (herrno); \ +- _res.options |= old_res_options & RES_USE_INET6; \ ++ _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \ + result = -EAI_SYSTEM; \ + goto free_and_return; \ + } \ +@@ -839,7 +839,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + addresses to IPv6 addresses. Currently this is decided + by setting the RES_USE_INET6 bit in _res.options. */ + old_res_options = _res.options; +- _res.options &= ~RES_USE_INET6; ++ _res.options &= ~DEPRECATED_RES_USE_INET6; + + size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple); + malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen); +@@ -900,7 +900,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + 2 * tmpbuflen); + if (newp == NULL) + { +- _res.options |= old_res_options & RES_USE_INET6; ++ _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; + result = -EAI_MEMORY; + goto free_and_return; + } +@@ -1021,7 +1021,8 @@ gaih_inet (const char *name, const struct gaih_service *service, + if (canonbuf == NULL) + { + _res.options +- |= old_res_options & RES_USE_INET6; ++ |= old_res_options ++ & DEPRECATED_RES_USE_INET6; + result = -EAI_MEMORY; + goto free_and_return; + } +@@ -1082,7 +1083,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + nip = nip->next; + } + +- _res.options |= old_res_options & RES_USE_INET6; ++ _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; + + if (h_errno == NETDB_INTERNAL) + { diff --git a/SOURCES/glibc-rh677316-alloc_buffer.patch b/SOURCES/glibc-rh677316-alloc_buffer.patch new file mode 100644 index 00000000..837f88c6 --- /dev/null +++ b/SOURCES/glibc-rh677316-alloc_buffer.patch @@ -0,0 +1,1307 @@ +Backport of the following upstream commits: + +commit d54bb9b1d3fd25779fba2c403003c5097ba9af73 +Author: Tulio Magno Quites Machado Filho +Date: Mon Jun 26 09:55:41 2017 -0300 + + Prevent an implicit int promotion in malloc/tst-alloc_buffer.c + +commit 4dd8e7c0ce5ecc7f65e33e60ad2f717b31de32ec +Author: Florian Weimer +Date: Wed Jun 21 22:43:57 2017 +0200 + + Implement allocation buffers for internal use + +diff --git a/include/alloc_buffer.h b/include/alloc_buffer.h +new file mode 100644 +index 0000000000000000..d668a60d66c5b076 +--- /dev/null ++++ b/include/alloc_buffer.h +@@ -0,0 +1,367 @@ ++/* Allocation from a fixed-size buffer. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Allocation buffers are used to carve out sub-allocations from a ++ larger allocation. Their primary application is in writing NSS ++ modules, which receive a caller-allocated buffer in which they are ++ expected to store variable-length results: ++ ++ void *buffer = ...; ++ size_t buffer_size = ...; ++ ++ struct alloc_buffer buf = alloc_buffer_create (buffer, buffer_size); ++ result->gr_name = alloc_buffer_copy_string (&buf, name); ++ ++ // Allocate a list of group_count groups and copy strings into it. ++ char **group_list = alloc_buffer_alloc_array ++ (&buf, char *, group_count + 1); ++ if (group_list == NULL) ++ return ...; // Request a larger buffer. ++ for (int i = 0; i < group_count; ++i) ++ group_list[i] = alloc_buffer_copy_string (&buf, group_list_src[i]); ++ group_list[group_count] = NULL; ++ ... ++ ++ if (alloc_buffer_has_failed (&buf)) ++ return ...; // Request a larger buffer. ++ result->gr_mem = group_list; ++ ... ++ ++ Note that it is not necessary to check the results of individual ++ allocation operations if the returned pointer is not dereferenced. ++ Allocation failure is sticky, so one check using ++ alloc_buffer_has_failed at the end covers all previous failures. ++ ++ A different use case involves combining multiple heap allocations ++ into a single, large one. In the following example, an array of ++ doubles and an array of ints is allocated: ++ ++ size_t double_array_size = ...; ++ size_t int_array_size = ...; ++ ++ void *heap_ptr; ++ struct alloc_buffer buf = alloc_buffer_allocate ++ (double_array_size * sizeof (double) + int_array_size * sizeof (int), ++ &heap_ptr); ++ _Static_assert (__alignof__ (double) >= __alignof__ (int), ++ "no padding after double array"); ++ double *double_array = alloc_buffer_alloc_array ++ (&buf, double, double_array_size); ++ int *int_array = alloc_buffer_alloc_array (&buf, int, int_array_size); ++ if (alloc_buffer_has_failed (&buf)) ++ return ...; // Report error. ++ ... ++ free (heap_ptr); ++ ++ The advantage over manual coding is that the computation of the ++ allocation size does not need an overflow check. In case of an ++ overflow, one of the subsequent allocations from the buffer will ++ fail. The initial size computation is checked for consistency at ++ run time, too. */ ++ ++#ifndef _ALLOC_BUFFER_H ++#define _ALLOC_BUFFER_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* struct alloc_buffer objects refer to a region of bytes in memory of a ++ fixed size. The functions below can be used to allocate single ++ objects and arrays from this memory region, or write to its end. ++ On allocation failure (or if an attempt to write beyond the end of ++ the buffer with one of the copy functions), the buffer enters a ++ failed state. ++ ++ struct alloc_buffer objects can be copied. The backing buffer will ++ be shared, but the current write position will be independent. ++ ++ Conceptually, the memory region consists of a current write pointer ++ and a limit, beyond which the write pointer cannot move. */ ++struct alloc_buffer ++{ ++ /* uintptr_t is used here to simplify the alignment code, and to ++ avoid issues undefined subtractions if the buffer covers more ++ than half of the address space (which would result in differences ++ which could not be represented as a ptrdiff_t value). */ ++ uintptr_t __alloc_buffer_current; ++ uintptr_t __alloc_buffer_end; ++}; ++ ++enum ++ { ++ /* The value for the __alloc_buffer_current member which marks the ++ buffer as invalid (together with a zero-length buffer). */ ++ __ALLOC_BUFFER_INVALID_POINTER = 0, ++ }; ++ ++/* Internal function. Terminate the process using __libc_fatal. */ ++void __libc_alloc_buffer_create_failure (void *start, size_t size); ++ ++/* Create a new allocation buffer. The byte range from START to START ++ + SIZE - 1 must be valid, and the allocation buffer allocates ++ objects from that range. If START is NULL (so that SIZE must be ++ 0), the buffer is marked as failed immediately. */ ++static inline struct alloc_buffer ++alloc_buffer_create (void *start, size_t size) ++{ ++ uintptr_t current = (uintptr_t) start; ++ uintptr_t end = (uintptr_t) start + size; ++ if (end < current) ++ __libc_alloc_buffer_create_failure (start, size); ++ return (struct alloc_buffer) { current, end }; ++} ++ ++/* Internal function. See alloc_buffer_allocate below. */ ++struct alloc_buffer __libc_alloc_buffer_allocate (size_t size, void **pptr) ++ __attribute__ ((nonnull (2))); ++ ++/* Allocate a buffer of SIZE bytes using malloc. The returned buffer ++ is in a failed state if malloc fails. *PPTR points to the start of ++ the buffer and can be used to free it later, after the returned ++ buffer has been freed. */ ++static __always_inline __attribute__ ((nonnull (2))) ++struct alloc_buffer alloc_buffer_allocate (size_t size, void **pptr) ++{ ++ return __libc_alloc_buffer_allocate (size, pptr); ++} ++ ++/* Mark the buffer as failed. */ ++static inline void __attribute__ ((nonnull (1))) ++alloc_buffer_mark_failed (struct alloc_buffer *buf) ++{ ++ buf->__alloc_buffer_current = __ALLOC_BUFFER_INVALID_POINTER; ++ buf->__alloc_buffer_end = __ALLOC_BUFFER_INVALID_POINTER; ++} ++ ++/* Return the remaining number of bytes in the buffer. */ ++static __always_inline __attribute__ ((nonnull (1))) size_t ++alloc_buffer_size (const struct alloc_buffer *buf) ++{ ++ return buf->__alloc_buffer_end - buf->__alloc_buffer_current; ++} ++ ++/* Return true if the buffer has been marked as failed. */ ++static inline bool __attribute__ ((nonnull (1))) ++alloc_buffer_has_failed (const struct alloc_buffer *buf) ++{ ++ return buf->__alloc_buffer_current == __ALLOC_BUFFER_INVALID_POINTER; ++} ++ ++/* Add a single byte to the buffer (consuming the space for this ++ byte). Mark the buffer as failed if there is not enough room. */ ++static inline void __attribute__ ((nonnull (1))) ++alloc_buffer_add_byte (struct alloc_buffer *buf, unsigned char b) ++{ ++ if (__glibc_likely (buf->__alloc_buffer_current < buf->__alloc_buffer_end)) ++ { ++ *(unsigned char *) buf->__alloc_buffer_current = b; ++ ++buf->__alloc_buffer_current; ++ } ++ else ++ alloc_buffer_mark_failed (buf); ++} ++ ++/* Obtain a pointer to LENGTH bytes in BUF, and consume these bytes. ++ NULL is returned if there is not enough room, and the buffer is ++ marked as failed, or if the buffer has already failed. ++ (Zero-length allocations from an empty buffer which has not yet ++ failed succeed.) */ ++static inline __attribute__ ((nonnull (1))) void * ++alloc_buffer_alloc_bytes (struct alloc_buffer *buf, size_t length) ++{ ++ if (length <= alloc_buffer_size (buf)) ++ { ++ void *result = (void *) buf->__alloc_buffer_current; ++ buf->__alloc_buffer_current += length; ++ return result; ++ } ++ else ++ { ++ alloc_buffer_mark_failed (buf); ++ return NULL; ++ } ++} ++ ++/* Internal function. Statically assert that the type size is ++ constant and valid. */ ++static __always_inline size_t ++__alloc_buffer_assert_size (size_t size) ++{ ++ if (!__builtin_constant_p (size)) ++ { ++ __errordecl (error, "type size is not constant"); ++ error (); ++ } ++ else if (size == 0) ++ { ++ __errordecl (error, "type size is zero"); ++ error (); ++ } ++ return size; ++} ++ ++/* Internal function. Statically assert that the type alignment is ++ constant and valid. */ ++static __always_inline size_t ++__alloc_buffer_assert_align (size_t align) ++{ ++ if (!__builtin_constant_p (align)) ++ { ++ __errordecl (error, "type alignment is not constant"); ++ error (); ++ } ++ else if (align == 0) ++ { ++ __errordecl (error, "type alignment is zero"); ++ error (); ++ } ++ else if (!powerof2 (align)) ++ { ++ __errordecl (error, "type alignment is not a power of two"); ++ error (); ++ } ++ return align; ++} ++ ++/* Internal function. Obtain a pointer to an object. */ ++static inline __attribute__ ((nonnull (1))) void * ++__alloc_buffer_alloc (struct alloc_buffer *buf, size_t size, size_t align) ++{ ++ if (size == 1 && align == 1) ++ return alloc_buffer_alloc_bytes (buf, size); ++ ++ size_t current = buf->__alloc_buffer_current; ++ size_t aligned = roundup (current, align); ++ size_t new_current = aligned + size; ++ if (aligned >= current /* No overflow in align step. */ ++ && new_current >= size /* No overflow in size computation. */ ++ && new_current <= buf->__alloc_buffer_end) /* Room in buffer. */ ++ { ++ buf->__alloc_buffer_current = new_current; ++ return (void *) aligned; ++ } ++ else ++ { ++ alloc_buffer_mark_failed (buf); ++ return NULL; ++ } ++} ++ ++/* Obtain a TYPE * pointer to an object in BUF of TYPE. Consume these ++ bytes from the buffer. Return NULL and mark the buffer as failed ++ if if there is not enough room in the buffer, or if the buffer has ++ failed before. */ ++#define alloc_buffer_alloc(buf, type) \ ++ ((type *) __alloc_buffer_alloc \ ++ (buf, __alloc_buffer_assert_size (sizeof (type)), \ ++ __alloc_buffer_assert_align (__alignof__ (type)))) ++ ++/* Internal function. Obtain a pointer to an object which is ++ subsequently added. */ ++static inline const __attribute__ ((nonnull (1))) void * ++__alloc_buffer_next (struct alloc_buffer *buf, size_t align) ++{ ++ if (align == 1) ++ return (const void *) buf->__alloc_buffer_current; ++ ++ size_t current = buf->__alloc_buffer_current; ++ size_t aligned = roundup (current, align); ++ if (aligned >= current /* No overflow in align step. */ ++ && aligned <= buf->__alloc_buffer_end) /* Room in buffer. */ ++ { ++ buf->__alloc_buffer_current = aligned; ++ return (const void *) aligned; ++ } ++ else ++ { ++ alloc_buffer_mark_failed (buf); ++ return NULL; ++ } ++} ++ ++/* Like alloc_buffer_alloc, but do not advance the pointer beyond the ++ object (so a subseqent call to alloc_buffer_next or ++ alloc_buffer_alloc returns the same pointer). Note that the buffer ++ is still aligned according to the requirements of TYPE. The effect ++ of this function is similar to allocating a zero-length array from ++ the buffer. */ ++#define alloc_buffer_next(buf, type) \ ++ ((const type *) __alloc_buffer_next \ ++ (buf, __alloc_buffer_assert_align (__alignof__ (type)))) ++ ++/* Internal function. Allocate an array. */ ++void * __libc_alloc_buffer_alloc_array (struct alloc_buffer *buf, ++ size_t size, size_t align, ++ size_t count) ++ __attribute__ ((nonnull (1))); ++ ++/* Obtain a TYPE * pointer to an array of COUNT objects in BUF of ++ TYPE. Consume these bytes from the buffer. Return NULL and mark ++ the buffer as failed if if there is not enough room in the buffer, ++ or if the buffer has failed before. (Zero-length allocations from ++ an empty buffer which has not yet failed succeed.) */ ++#define alloc_buffer_alloc_array(buf, type, count) \ ++ ((type *) __libc_alloc_buffer_alloc_array \ ++ (buf, __alloc_buffer_assert_size (sizeof (type)), \ ++ __alloc_buffer_assert_align (__alignof__ (type)), \ ++ count)) ++ ++/* Internal function. See alloc_buffer_copy_bytes below. */ ++struct alloc_buffer __libc_alloc_buffer_copy_bytes (struct alloc_buffer, ++ const void *, size_t) ++ __attribute__ ((nonnull (2))); ++ ++/* Copy SIZE bytes starting at SRC into the buffer. If there is not ++ enough room in the buffer, the buffer is marked as failed. No ++ alignment of the buffer is performed. */ ++static inline __attribute__ ((nonnull (1, 2))) void ++alloc_buffer_copy_bytes (struct alloc_buffer *buf, const void *src, size_t size) ++{ ++ *buf = __libc_alloc_buffer_copy_bytes (*buf, src, size); ++} ++ ++/* Internal function. See alloc_buffer_copy_string below. */ ++struct alloc_buffer __libc_alloc_buffer_copy_string (struct alloc_buffer, ++ const char *) ++ __attribute__ ((nonnull (2))); ++ ++/* Copy the string at SRC into the buffer, including its null ++ terminator. If there is not enough room in the buffer, the buffer ++ is marked as failed. Return a pointer to the string. */ ++static inline __attribute__ ((nonnull (1, 2))) char * ++alloc_buffer_copy_string (struct alloc_buffer *buf, const char *src) ++{ ++ char *result = (char *) buf->__alloc_buffer_current; ++ *buf = __libc_alloc_buffer_copy_string (*buf, src); ++ if (alloc_buffer_has_failed (buf)) ++ result = NULL; ++ return result; ++} ++ ++#ifndef _ISOMAC ++libc_hidden_proto (__libc_alloc_buffer_alloc_array) ++libc_hidden_proto (__libc_alloc_buffer_allocate) ++libc_hidden_proto (__libc_alloc_buffer_copy_bytes) ++libc_hidden_proto (__libc_alloc_buffer_copy_string) ++libc_hidden_proto (__libc_alloc_buffer_create_failure) ++#endif ++ ++#endif /* _ALLOC_BUFFER_H */ +diff --git a/malloc/Makefile b/malloc/Makefile +index 63fc3291dcc4077a..db4b1f921d56da32 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -37,6 +37,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-dynarray \ + tst-dynarray-fail \ + tst-dynarray-at-fail \ ++ tst-alloc_buffer \ + + tests-static := \ + tst-interpose-static-nothread \ +@@ -55,6 +56,11 @@ routines = malloc morecore mcheck mtrace obstack \ + dynarray_finalize \ + dynarray_resize \ + dynarray_resize_clear \ ++ alloc_buffer_alloc_array \ ++ alloc_buffer_allocate \ ++ alloc_buffer_copy_bytes \ ++ alloc_buffer_copy_string \ ++ alloc_buffer_create_failure \ + + + install-lib := libmcheck.a +diff --git a/malloc/Versions b/malloc/Versions +index 16f9dab418a4e3f6..0b7b690bbbdd1c2c 100644 +--- a/malloc/Versions ++++ b/malloc/Versions +@@ -79,5 +79,12 @@ libc { + __libc_dynarray_finalize; + __libc_dynarray_resize; + __libc_dynarray_resize_clear; ++ ++ # struct alloc_buffer support ++ __libc_alloc_buffer_alloc_array; ++ __libc_alloc_buffer_allocate; ++ __libc_alloc_buffer_copy_bytes; ++ __libc_alloc_buffer_copy_string; ++ __libc_alloc_buffer_create_failure; + } + } +diff --git a/malloc/alloc_buffer_alloc_array.c b/malloc/alloc_buffer_alloc_array.c +new file mode 100644 +index 0000000000000000..68e14da8dd4e545c +--- /dev/null ++++ b/malloc/alloc_buffer_alloc_array.c +@@ -0,0 +1,47 @@ ++/* Array allocation from a fixed-size buffer. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++void * ++__libc_alloc_buffer_alloc_array (struct alloc_buffer *buf, size_t element_size, ++ size_t align, size_t count) ++{ ++ size_t current = buf->__alloc_buffer_current; ++ /* The caller asserts that align is a power of two. */ ++ size_t aligned = ALIGN_UP (current, align); ++ size_t size; ++ bool overflow = check_mul_overflow_size_t (element_size, count, &size); ++ size_t new_current = aligned + size; ++ if (!overflow /* Multiplication did not overflow. */ ++ && aligned >= current /* No overflow in align step. */ ++ && new_current >= size /* No overflow in size computation. */ ++ && new_current <= buf->__alloc_buffer_end) /* Room in buffer. */ ++ { ++ buf->__alloc_buffer_current = new_current; ++ return (void *) aligned; ++ } ++ else ++ { ++ alloc_buffer_mark_failed (buf); ++ return NULL; ++ } ++} ++libc_hidden_def (__libc_alloc_buffer_alloc_array) +diff --git a/malloc/alloc_buffer_allocate.c b/malloc/alloc_buffer_allocate.c +new file mode 100644 +index 0000000000000000..cbde72b842f0b5d1 +--- /dev/null ++++ b/malloc/alloc_buffer_allocate.c +@@ -0,0 +1,36 @@ ++/* Allocate a fixed-size allocation buffer using malloc. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++struct alloc_buffer ++__libc_alloc_buffer_allocate (size_t size, void **pptr) ++{ ++ *pptr = malloc (size); ++ if (*pptr == NULL) ++ return (struct alloc_buffer) ++ { ++ .__alloc_buffer_current = __ALLOC_BUFFER_INVALID_POINTER, ++ .__alloc_buffer_end = __ALLOC_BUFFER_INVALID_POINTER ++ }; ++ else ++ return alloc_buffer_create (*pptr, size); ++} ++libc_hidden_def (__libc_alloc_buffer_allocate) +diff --git a/malloc/alloc_buffer_copy_bytes.c b/malloc/alloc_buffer_copy_bytes.c +new file mode 100644 +index 0000000000000000..66196f1520c6fc84 +--- /dev/null ++++ b/malloc/alloc_buffer_copy_bytes.c +@@ -0,0 +1,34 @@ ++/* Copy an array of bytes into the buffer. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++/* This function works on a copy of the buffer object, so that it can ++ remain non-addressable in the caller. */ ++struct alloc_buffer ++__libc_alloc_buffer_copy_bytes (struct alloc_buffer buf, ++ const void *src, size_t len) ++{ ++ void *ptr = alloc_buffer_alloc_bytes (&buf, len); ++ if (ptr != NULL) ++ memcpy (ptr, src, len); ++ return buf; ++} ++libc_hidden_def (__libc_alloc_buffer_copy_bytes) +diff --git a/malloc/alloc_buffer_copy_string.c b/malloc/alloc_buffer_copy_string.c +new file mode 100644 +index 0000000000000000..77c0023d510b43be +--- /dev/null ++++ b/malloc/alloc_buffer_copy_string.c +@@ -0,0 +1,30 @@ ++/* Copy a string into the allocation buffer. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++ ++/* This function works on a copy of the buffer object, so that it can ++ remain non-addressable in the caller. */ ++struct alloc_buffer ++__libc_alloc_buffer_copy_string (struct alloc_buffer buf, const char *src) ++{ ++ return __libc_alloc_buffer_copy_bytes (buf, src, strlen (src) + 1); ++} ++libc_hidden_def (__libc_alloc_buffer_copy_string) +diff --git a/malloc/alloc_buffer_create_failure.c b/malloc/alloc_buffer_create_failure.c +new file mode 100644 +index 0000000000000000..5ffba22f7b1e0dc5 +--- /dev/null ++++ b/malloc/alloc_buffer_create_failure.c +@@ -0,0 +1,31 @@ ++/* Terminate the process as the result of an invalid allocation buffer. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++__libc_alloc_buffer_create_failure (void *start, size_t size) ++{ ++ char buf[200]; ++ __snprintf (buf, sizeof (buf), "Fatal glibc error: " ++ "invalid allocation buffer of size %zu\n", ++ size); ++ __libc_fatal (buf); ++} ++libc_hidden_def (__libc_alloc_buffer_create_failure) +diff --git a/malloc/tst-alloc_buffer.c b/malloc/tst-alloc_buffer.c +new file mode 100644 +index 0000000000000000..9b2bd2046a12c0f2 +--- /dev/null ++++ b/malloc/tst-alloc_buffer.c +@@ -0,0 +1,665 @@ ++/* Tests for struct alloc_buffer. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Return true if PTR is sufficiently aligned for TYPE. */ ++#define IS_ALIGNED(ptr, type) \ ++ ((((uintptr_t) ptr) & (__alloc_buffer_assert_align (__alignof (type)) - 1)) \ ++ == 0) ++ ++/* Structure with non-power-of-two size. */ ++struct twelve ++{ ++ uint32_t buffer[3] __attribute__ ((aligned (4))); ++}; ++_Static_assert (sizeof (struct twelve) == 12, "struct twelve"); ++_Static_assert (__alignof__ (struct twelve) == 4, "struct twelve"); ++ ++/* Check for success obtaining empty arrays. Does not assume the ++ buffer is empty. */ ++static void ++test_empty_array (struct alloc_buffer refbuf) ++{ ++ bool refbuf_failed = alloc_buffer_has_failed (&refbuf); ++ if (test_verbose) ++ printf ("info: %s: current=0x%llx end=0x%llx refbuf_failed=%d\n", ++ __func__, (unsigned long long) refbuf.__alloc_buffer_current, ++ (unsigned long long) refbuf.__alloc_buffer_end, refbuf_failed); ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY ((alloc_buffer_alloc_bytes (&buf, 0) == NULL) ++ == refbuf_failed); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf) == refbuf_failed); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY ((alloc_buffer_alloc_array (&buf, char, 0) == NULL) ++ == refbuf_failed); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf) == refbuf_failed); ++ } ++ /* The following tests can fail due to the need for aligning the ++ returned pointer. */ ++ { ++ struct alloc_buffer buf = refbuf; ++ bool expect_failure = refbuf_failed ++ || !IS_ALIGNED (alloc_buffer_next (&buf, void), double); ++ double *ptr = alloc_buffer_alloc_array (&buf, double, 0); ++ TEST_VERIFY (IS_ALIGNED (ptr, double)); ++ TEST_VERIFY ((ptr == NULL) == expect_failure); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf) == expect_failure); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ bool expect_failure = refbuf_failed ++ || !IS_ALIGNED (alloc_buffer_next (&buf, void), struct twelve); ++ struct twelve *ptr = alloc_buffer_alloc_array (&buf, struct twelve, 0); ++ TEST_VERIFY (IS_ALIGNED (ptr, struct twelve)); ++ TEST_VERIFY ((ptr == NULL) == expect_failure); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf) == expect_failure); ++ } ++} ++ ++/* Test allocation of impossibly large arrays. */ ++static void ++test_impossible_array (struct alloc_buffer refbuf) ++{ ++ if (test_verbose) ++ printf ("info: %s: current=0x%llx end=0x%llx\n", ++ __func__, (unsigned long long) refbuf.__alloc_buffer_current, ++ (unsigned long long) refbuf.__alloc_buffer_end); ++ static const size_t counts[] = ++ { SIZE_MAX, SIZE_MAX - 1, SIZE_MAX - 2, SIZE_MAX - 3, SIZE_MAX - 4, ++ SIZE_MAX / 2, SIZE_MAX / 2 + 1, SIZE_MAX / 2 - 1, 0}; ++ ++ for (int i = 0; counts[i] != 0; ++i) ++ { ++ size_t count = counts[i]; ++ if (test_verbose) ++ printf ("info: %s: count=%zu\n", __func__, count); ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_bytes (&buf, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, count) ++ == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ } ++} ++ ++/* Check for failure to obtain anything from a failed buffer. */ ++static void ++test_after_failure (struct alloc_buffer refbuf) ++{ ++ if (test_verbose) ++ printf ("info: %s: current=0x%llx end=0x%llx\n", ++ __func__, (unsigned long long) refbuf.__alloc_buffer_current, ++ (unsigned long long) refbuf.__alloc_buffer_end); ++ TEST_VERIFY (alloc_buffer_has_failed (&refbuf)); ++ { ++ struct alloc_buffer buf = refbuf; ++ alloc_buffer_add_byte (&buf, 17); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ ++ test_impossible_array (refbuf); ++ for (int count = 0; count <= 4; ++count) ++ { ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_bytes (&buf, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, count) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, count) ++ == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ } ++} ++ ++static void ++test_empty (struct alloc_buffer refbuf) ++{ ++ TEST_VERIFY (alloc_buffer_size (&refbuf) == 0); ++ if (alloc_buffer_next (&refbuf, void) != NULL) ++ TEST_VERIFY (!alloc_buffer_has_failed (&refbuf)); ++ test_empty_array (refbuf); ++ test_impossible_array (refbuf); ++ ++ /* Failure to obtain non-empty objects. */ ++ { ++ struct alloc_buffer buf = refbuf; ++ alloc_buffer_add_byte (&buf, 17); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, 1) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, 1) == NULL); ++ test_after_failure (buf); ++ } ++} ++ ++static void ++test_size_1 (struct alloc_buffer refbuf) ++{ ++ TEST_VERIFY (!alloc_buffer_has_failed (&refbuf)); ++ TEST_VERIFY (alloc_buffer_size (&refbuf) == 1); ++ test_empty_array (refbuf); ++ test_impossible_array (refbuf); ++ ++ /* Success adding a single byte. */ ++ { ++ struct alloc_buffer buf = refbuf; ++ alloc_buffer_add_byte (&buf, 17); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ test_empty (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x11", 1) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ signed char *ptr = alloc_buffer_alloc (&buf, signed char); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ *ptr = 126; ++ test_empty (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\176", 1) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ char *ptr = alloc_buffer_alloc_array (&buf, char, 1); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ *ptr = (char) 253; ++ test_empty (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\xfd", 1) == 0); ++ ++ /* Failure with larger objects. */ ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, short) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, 1) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL); ++ test_after_failure (buf); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, 1) == NULL); ++ test_after_failure (buf); ++ } ++} ++ ++static void ++test_size_2 (struct alloc_buffer refbuf) ++{ ++ TEST_VERIFY (!alloc_buffer_has_failed (&refbuf)); ++ TEST_VERIFY (alloc_buffer_size (&refbuf) == 2); ++ TEST_VERIFY (IS_ALIGNED (alloc_buffer_next (&refbuf, void), short)); ++ test_empty_array (refbuf); ++ test_impossible_array (refbuf); ++ ++ /* Success adding two bytes. */ ++ { ++ struct alloc_buffer buf = refbuf; ++ alloc_buffer_add_byte (&buf, '@'); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ test_size_1 (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "@\xfd", 2) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ signed char *ptr = alloc_buffer_alloc (&buf, signed char); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ *ptr = 'A'; ++ test_size_1 (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "A\xfd", 2) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ char *ptr = alloc_buffer_alloc_array (&buf, char, 1); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ *ptr = 'B'; ++ test_size_1 (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "B\xfd", 2) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ unsigned short *ptr = alloc_buffer_alloc (&buf, unsigned short); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (IS_ALIGNED (ptr, unsigned short)); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ *ptr = htons (0x12f4); ++ test_empty (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x12\xf4", 2) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ unsigned short *ptr = alloc_buffer_alloc_array (&buf, unsigned short, 1); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (IS_ALIGNED (ptr, unsigned short)); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ *ptr = htons (0x13f5); ++ test_empty (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x13\xf5", 2) == 0); ++ { ++ struct alloc_buffer buf = refbuf; ++ char *ptr = alloc_buffer_alloc_array (&buf, char, 2); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ memcpy (ptr, "12", 2); ++ test_empty (buf); ++ } ++ TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "12", 2) == 0); ++} ++ ++static void ++test_misaligned (char pad) ++{ ++ enum { SIZE = 23 }; ++ char *backing = xmalloc (SIZE + 2); ++ backing[0] = ~pad; ++ backing[SIZE + 1] = pad; ++ struct alloc_buffer refbuf = alloc_buffer_create (backing + 1, SIZE); ++ ++ { ++ struct alloc_buffer buf = refbuf; ++ short *ptr = alloc_buffer_alloc_array (&buf, short, SIZE / sizeof (short)); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (IS_ALIGNED (ptr, short)); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ for (int i = 0; i < SIZE / sizeof (short); ++i) ++ ptr[i] = htons (0xff01 + i); ++ TEST_VERIFY (memcmp (ptr, ++ "\xff\x01\xff\x02\xff\x03\xff\x04" ++ "\xff\x05\xff\x06\xff\x07\xff\x08" ++ "\xff\x09\xff\x0a\xff\x0b", 22) == 0); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ uint32_t *ptr = alloc_buffer_alloc_array ++ (&buf, uint32_t, SIZE / sizeof (uint32_t)); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (IS_ALIGNED (ptr, uint32_t)); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ for (int i = 0; i < SIZE / sizeof (uint32_t); ++i) ++ ptr[i] = htonl (0xf1e2d301 + i); ++ TEST_VERIFY (memcmp (ptr, ++ "\xf1\xe2\xd3\x01\xf1\xe2\xd3\x02" ++ "\xf1\xe2\xd3\x03\xf1\xe2\xd3\x04" ++ "\xf1\xe2\xd3\x05", 20) == 0); ++ } ++ { ++ struct alloc_buffer buf = refbuf; ++ struct twelve *ptr = alloc_buffer_alloc (&buf, struct twelve); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (IS_ALIGNED (ptr, struct twelve)); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ ptr->buffer[0] = htonl (0x11223344); ++ ptr->buffer[1] = htonl (0x55667788); ++ ptr->buffer[2] = htonl (0x99aabbcc); ++ TEST_VERIFY (memcmp (ptr, ++ "\x11\x22\x33\x44" ++ "\x55\x66\x77\x88" ++ "\x99\xaa\xbb\xcc", 12) == 0); ++ } ++ { ++ static const double nums[] = { 1, 2 }; ++ struct alloc_buffer buf = refbuf; ++ double *ptr = alloc_buffer_alloc_array (&buf, double, 2); ++ TEST_VERIFY_EXIT (ptr != NULL); ++ TEST_VERIFY (IS_ALIGNED (ptr, double)); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ ptr[0] = nums[0]; ++ ptr[1] = nums[1]; ++ TEST_VERIFY (memcmp (ptr, nums, sizeof (nums)) == 0); ++ } ++ ++ /* Verify that padding was not overwritten. */ ++ TEST_VERIFY (backing[0] == (char) ~pad); ++ TEST_VERIFY (backing[SIZE + 1] == pad); ++ free (backing); ++} ++ ++/* Check that overflow during alignment is handled properly. */ ++static void ++test_large_misaligned (void) ++{ ++ uintptr_t minus1 = -1; ++ uintptr_t start = minus1 & ~0xfe; ++ struct alloc_buffer refbuf = alloc_buffer_create ((void *) start, 16); ++ TEST_VERIFY (!alloc_buffer_has_failed (&refbuf)); ++ ++ struct __attribute__ ((aligned (256))) align256 ++ { ++ int dymmy; ++ }; ++ ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc (&buf, struct align256) == NULL); ++ test_after_failure (buf); ++ } ++ for (int count = 0; count < 3; ++count) ++ { ++ struct alloc_buffer buf = refbuf; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct align256, count) ++ == NULL); ++ test_after_failure (buf); ++ } ++} ++ ++/* Check behavior of large allocations. */ ++static void ++test_large (void) ++{ ++ { ++ /* Allocation which wraps around. */ ++ struct alloc_buffer buf = { 1, SIZE_MAX }; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, SIZE_MAX) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ ++ { ++ /* Successful very large allocation. */ ++ struct alloc_buffer buf = { 1, SIZE_MAX }; ++ uintptr_t val = (uintptr_t) alloc_buffer_alloc_array ++ (&buf, char, SIZE_MAX - 1); ++ TEST_VERIFY (val == 1); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ test_empty (buf); ++ } ++ ++ { ++ typedef char __attribute__ ((aligned (2))) char2; ++ ++ /* Overflow in array size computation. */ ++ struct alloc_buffer buf = { 1, SIZE_MAX }; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, char2, SIZE_MAX - 1) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ ++ /* Successful allocation after alignment. */ ++ buf = (struct alloc_buffer) { 1, SIZE_MAX }; ++ uintptr_t val = (uintptr_t) alloc_buffer_alloc_array ++ (&buf, char2, SIZE_MAX - 2); ++ TEST_VERIFY (val == 2); ++ test_empty (buf); ++ ++ /* Alignment behavior near the top of the address space. */ ++ buf = (struct alloc_buffer) { SIZE_MAX, SIZE_MAX }; ++ TEST_VERIFY (alloc_buffer_next (&buf, char2) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ buf = (struct alloc_buffer) { SIZE_MAX, SIZE_MAX }; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, char2, 0) == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ } ++ ++ { ++ typedef short __attribute__ ((aligned (2))) short2; ++ ++ /* Test overflow in size computation. */ ++ struct alloc_buffer buf = { 1, SIZE_MAX }; ++ TEST_VERIFY (alloc_buffer_alloc_array (&buf, short2, SIZE_MAX / 2) ++ == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ ++ /* A slightly smaller array fits within the allocation. */ ++ buf = (struct alloc_buffer) { 2, SIZE_MAX - 1 }; ++ uintptr_t val = (uintptr_t) alloc_buffer_alloc_array ++ (&buf, short2, SIZE_MAX / 2 - 1); ++ TEST_VERIFY (val == 2); ++ test_empty (buf); ++ } ++} ++ ++static void ++test_copy_bytes (void) ++{ ++ char backing[4]; ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ alloc_buffer_copy_bytes (&buf, "1", 1); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 3); ++ TEST_VERIFY (memcmp (backing, "1@@@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ alloc_buffer_copy_bytes (&buf, "12", 3); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 1); ++ TEST_VERIFY (memcmp (backing, "12\0@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ alloc_buffer_copy_bytes (&buf, "1234", 4); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 0); ++ TEST_VERIFY (memcmp (backing, "1234", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ alloc_buffer_copy_bytes (&buf, "1234", 5); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ alloc_buffer_copy_bytes (&buf, "1234", -1); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0); ++ } ++} ++ ++static void ++test_copy_string (void) ++{ ++ char backing[4]; ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ const char *p = alloc_buffer_copy_string (&buf, ""); ++ TEST_VERIFY (p == backing); ++ TEST_VERIFY (strcmp (p, "") == 0); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 3); ++ TEST_VERIFY (memcmp (backing, "\0@@@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ const char *p = alloc_buffer_copy_string (&buf, "1"); ++ TEST_VERIFY (p == backing); ++ TEST_VERIFY (strcmp (p, "1") == 0); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 2); ++ TEST_VERIFY (memcmp (backing, "1\0@@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ const char *p = alloc_buffer_copy_string (&buf, "12"); ++ TEST_VERIFY (p == backing); ++ TEST_VERIFY (strcmp (p, "12") == 0); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 1); ++ TEST_VERIFY (memcmp (backing, "12\0@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ const char *p = alloc_buffer_copy_string (&buf, "123"); ++ TEST_VERIFY (p == backing); ++ TEST_VERIFY (strcmp (p, "123") == 0); ++ TEST_VERIFY (!alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (alloc_buffer_size (&buf) == 0); ++ TEST_VERIFY (memcmp (backing, "123", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ TEST_VERIFY (alloc_buffer_copy_string (&buf, "1234") == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0); ++ } ++ { ++ memset (backing, '@', sizeof (backing)); ++ struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing)); ++ TEST_VERIFY (alloc_buffer_copy_string (&buf, "12345") == NULL); ++ TEST_VERIFY (alloc_buffer_has_failed (&buf)); ++ TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ test_empty (alloc_buffer_create (NULL, 0)); ++ test_empty (alloc_buffer_create ((char *) "", 0)); ++ test_empty (alloc_buffer_create ((void *) 1, 0)); ++ ++ { ++ void *ptr = (void *) ""; /* Cannot be freed. */ ++ struct alloc_buffer buf = alloc_buffer_allocate (1, &ptr); ++ test_size_1 (buf); ++ free (ptr); /* Should have been overwritten. */ ++ } ++ ++ { ++ void *ptr= (void *) ""; /* Cannot be freed. */ ++ struct alloc_buffer buf = alloc_buffer_allocate (2, &ptr); ++ test_size_2 (buf); ++ free (ptr); /* Should have been overwritten. */ ++ } ++ ++ test_misaligned (0); ++ test_misaligned (0xc7); ++ test_misaligned (0xff); ++ ++ test_large_misaligned (); ++ test_large (); ++ test_copy_bytes (); ++ test_copy_string (); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh677316-check_mul_overflow_size_t.patch b/SOURCES/glibc-rh677316-check_mul_overflow_size_t.patch new file mode 100644 index 00000000..3edbb380 --- /dev/null +++ b/SOURCES/glibc-rh677316-check_mul_overflow_size_t.patch @@ -0,0 +1,37 @@ +Backport the check_mul_overflow_size_t function from this upstream commit: + +commit 2e0bbbfbf95fc9e22692e93658a6fbdd2d4554da +Author: Dennis Wölfing +Date: Tue May 30 18:26:19 2017 -0300 + + Add reallocarray function + +diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h +index b830d3f58fe74ca3..6ffa091ba3292901 100644 +--- a/malloc/malloc-internal.h ++++ b/malloc/malloc-internal.h +@@ -28,5 +28,24 @@ void __malloc_fork_unlock_parent (void) internal_function attribute_hidden; + /* Called in the child process after a fork. */ + void __malloc_fork_unlock_child (void) internal_function attribute_hidden; + ++/* Set *RESULT to LEFT * RIGHT. Return true if the multiplication ++ overflowed. */ ++static inline bool ++check_mul_overflow_size_t (size_t left, size_t right, size_t *result) ++{ ++#if __GNUC__ >= 5 ++ return __builtin_mul_overflow (left, right, result); ++#else ++ /* size_t is unsigned so the behavior on overflow is defined. */ ++ *result = left * right; ++ size_t half_size_t = ((size_t) 1) << (8 * sizeof (size_t) / 2); ++ if (__glibc_unlikely ((left | right) >= half_size_t)) ++ { ++ if (__glibc_unlikely (right != 0 && *result / right != left)) ++ return true; ++ } ++ return false; ++#endif ++} + + #endif /* _MALLOC_PRIVATE_H */ diff --git a/SOURCES/glibc-rh677316-dynarray.patch b/SOURCES/glibc-rh677316-dynarray.patch new file mode 100644 index 00000000..cd3ee944 --- /dev/null +++ b/SOURCES/glibc-rh677316-dynarray.patch @@ -0,0 +1,2359 @@ +Backport of the following upstream commits: + +commit ab5ac271e6210fa0af11cf3ca525ce573bc47c48 +Author: Florian Weimer +Date: Wed Sep 6 11:25:14 2017 +0200 + + __libc_dynarray_emplace_enlarge: Add missing else + + Before, arrays of small elements received a starting allocation size of + 8, not 16. + +commit 5898f4548efdcd7c0fd437a74eeb80facc51a117 +Author: Florian Weimer +Date: Wed Aug 30 20:10:56 2017 +0200 + + dynarray: Set errno on overflow-induced allocation failure + + This allows the caller to return directly on such an error, with an + appropriate errno value. + +commit 5b83faf6a7ca57ef2bfbca2c77992cafc8daa0be +Author: Florian Weimer +Date: Mon Jun 19 12:58:08 2017 +0200 + + dynarray: Use libc_hidden_proto only for !_ISOMAC + + With this change, it is possible to use dynarray from non-internal + tests. + +commit f8bf87face3304f216bcd838081fa33bb4976ac6 +Author: Florian Weimer +Date: Tue Jun 13 17:03:56 2017 +0200 + + dynarray: Implement begin/end functions in the spirit of C++ + +commit 990c32b93a29d8b8d599e10ebca19a260f84cbba +Author: Florian Weimer +Date: Fri Jun 9 14:08:57 2017 +0200 + + malloc: Remove tst-dynarray, tst-dynarray-fail from test-srcs + + They are already covered through the tests variable. + +commit 91b6eb1140eda6bab324821ee3785e5d0ca155b8 +Author: Florian Weimer +Date: Fri Jun 2 11:59:28 2017 +0200 + + Add internal facility for dynamic array handling + + This is intended as a type-safe alternative to obstacks and + hand-written realloc constructs. The implementation avoids + writing function pointers to the heap. + +malloc/tst-dynarray-at-fail.c has been adjusted to use __WORDSIZE +instead of SIZE_WIDTH. + +malloc/Makefile has been adjusted to the changes in the build and test +process (no tests-internal in glibc 2.17, mtrace tests are handled +differently, there is no evaluate-test Makefile macro). + +diff --git a/malloc/Makefile b/malloc/Makefile +index 38aa9e0993d4880c..63fc3291dcc4077a 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -34,6 +34,9 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-interpose-static-nothread \ + tst-interpose-static-thread \ + tst-scratch_buffer \ ++ tst-dynarray \ ++ tst-dynarray-fail \ ++ tst-dynarray-at-fail \ + + tests-static := \ + tst-interpose-static-nothread \ +@@ -41,10 +44,17 @@ tests-static := \ + + test-srcs = tst-mtrace + ++generated += tst-dynarray-mem tst-dynarray-fail-mem ++ + routines = malloc morecore mcheck mtrace obstack \ + scratch_buffer_grow \ + scratch_buffer_grow_preserve \ + scratch_buffer_set_array_size \ ++ dynarray_at_failure \ ++ dynarray_emplace_enlarge \ ++ dynarray_finalize \ ++ dynarray_resize \ ++ dynarray_resize_clear \ + + + install-lib := libmcheck.a +@@ -143,8 +153,7 @@ ifeq ($(run-built-tests),yes) + ifeq (yes,$(build-shared)) + ifneq ($(PERL),no) + tests: $(objpfx)tst-mtrace.out +-$(objpfx)tst-mtrace.out: tst-mtrace.sh $(objpfx)tst-mtrace +- $(SHELL) $< $(common-objpfx) '$(run-program-prefix)' ++tests: $(objpfx)tst-dynarray-mem $(objpfx)tst-dynarray-fail-mem + endif + endif + endif +@@ -194,3 +203,11 @@ $(objpfx)tst-interpose-static-thread: \ + # Compile the tests with a flag which suppresses the mallopt call in + # the test skeleton. + $(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT ++ ++tst-dynarray-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray.mtrace ++$(objpfx)tst-dynarray-mem: $(objpfx)tst-dynarray.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray.mtrace > $@ ++ ++tst-dynarray-fail-ENV = MALLOC_TRACE=$(objpfx)tst-dynarray-fail.mtrace ++$(objpfx)tst-dynarray-fail-mem: $(objpfx)tst-dynarray-fail.out ++ $(common-objpfx)malloc/mtrace $(objpfx)tst-dynarray-fail.mtrace > $@ +diff --git a/malloc/Versions b/malloc/Versions +index f3c3d8a0934bdcd3..16f9dab418a4e3f6 100644 +--- a/malloc/Versions ++++ b/malloc/Versions +@@ -72,5 +72,12 @@ libc { + __libc_scratch_buffer_grow; + __libc_scratch_buffer_grow_preserve; + __libc_scratch_buffer_set_array_size; ++ ++ # dynarray support ++ __libc_dynarray_at_failure; ++ __libc_dynarray_emplace_enlarge; ++ __libc_dynarray_finalize; ++ __libc_dynarray_resize; ++ __libc_dynarray_resize_clear; + } + } +diff --git a/malloc/dynarray-skeleton.c b/malloc/dynarray-skeleton.c +new file mode 100644 +index 0000000000000000..7ec58788087e80d3 +--- /dev/null ++++ b/malloc/dynarray-skeleton.c +@@ -0,0 +1,521 @@ ++/* Type-safe arrays which grow dynamically. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Pre-processor macros which act as parameters: ++ ++ DYNARRAY_STRUCT ++ The struct tag of dynamic array to be defined. ++ DYNARRAY_ELEMENT ++ The type name of the element type. Elements are copied ++ as if by memcpy, and can change address as the dynamic ++ array grows. ++ DYNARRAY_PREFIX ++ The prefix of the functions which are defined. ++ ++ The following parameters are optional: ++ ++ DYNARRAY_ELEMENT_FREE ++ DYNARRAY_ELEMENT_FREE (E) is evaluated to deallocate the ++ contents of elements. E is of type DYNARRAY_ELEMENT *. ++ DYNARRAY_ELEMENT_INIT ++ DYNARRAY_ELEMENT_INIT (E) is evaluated to initialize a new ++ element. E is of type DYNARRAY_ELEMENT *. ++ If DYNARRAY_ELEMENT_FREE but not DYNARRAY_ELEMENT_INIT is ++ defined, new elements are automatically zero-initialized. ++ Otherwise, new elements have undefined contents. ++ DYNARRAY_INITIAL_SIZE ++ The size of the statically allocated array (default: ++ at least 2, more elements if they fit into 128 bytes). ++ Must be a preprocessor constant. If DYNARRAY_INITIAL_SIZE is 0, ++ there is no statically allocated array at, and all non-empty ++ arrays are heap-allocated. ++ DYNARRAY_FINAL_TYPE ++ The name of the type which holds the final array. If not ++ defined, is PREFIX##finalize not provided. DYNARRAY_FINAL_TYPE ++ must be a struct type, with members of type DYNARRAY_ELEMENT and ++ size_t at the start (in this order). ++ ++ These macros are undefined after this header file has been ++ included. ++ ++ The following types are provided (their members are private to the ++ dynarray implementation): ++ ++ struct DYNARRAY_STRUCT ++ ++ The following functions are provided: ++ ++ void DYNARRAY_PREFIX##init (struct DYNARRAY_STRUCT *); ++ void DYNARRAY_PREFIX##free (struct DYNARRAY_STRUCT *); ++ bool DYNARRAY_PREFIX##has_failed (const struct DYNARRAY_STRUCT *); ++ void DYNARRAY_PREFIX##mark_failed (struct DYNARRAY_STRUCT *); ++ size_t DYNARRAY_PREFIX##size (const struct DYNARRAY_STRUCT *); ++ DYNARRAY_ELEMENT *DYNARRAY_PREFIX##begin (const struct DYNARRAY_STRUCT *); ++ DYNARRAY_ELEMENT *DYNARRAY_PREFIX##end (const struct DYNARRAY_STRUCT *); ++ DYNARRAY_ELEMENT *DYNARRAY_PREFIX##at (struct DYNARRAY_STRUCT *, size_t); ++ void DYNARRAY_PREFIX##add (struct DYNARRAY_STRUCT *, DYNARRAY_ELEMENT); ++ DYNARRAY_ELEMENT *DYNARRAY_PREFIX##emplace (struct DYNARRAY_STRUCT *); ++ bool DYNARRAY_PREFIX##resize (struct DYNARRAY_STRUCT *, size_t); ++ void DYNARRAY_PREFIX##remove_last (struct DYNARRAY_STRUCT *); ++ void DYNARRAY_PREFIX##clear (struct DYNARRAY_STRUCT *); ++ ++ The following functions are provided are provided if the ++ prerequisites are met: ++ ++ bool DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *, ++ DYNARRAY_FINAL_TYPE *); ++ (if DYNARRAY_FINAL_TYPE is defined) ++ DYNARRAY_ELEMENT *DYNARRAY_PREFIX##finalize (struct DYNARRAY_STRUCT *, ++ size_t *); ++ (if DYNARRAY_FINAL_TYPE is not defined) ++*/ ++ ++#include ++ ++#include ++#include ++#include ++ ++#ifndef DYNARRAY_STRUCT ++# error "DYNARRAY_STRUCT must be defined" ++#endif ++ ++#ifndef DYNARRAY_ELEMENT ++# error "DYNARRAY_ELEMENT must be defined" ++#endif ++ ++#ifndef DYNARRAY_PREFIX ++# error "DYNARRAY_PREFIX must be defined" ++#endif ++ ++#ifdef DYNARRAY_INITIAL_SIZE ++# if DYNARRAY_INITIAL_SIZE < 0 ++# error "DYNARRAY_INITIAL_SIZE must be non-negative" ++# endif ++# if DYNARRAY_INITIAL_SIZE > 0 ++# define DYNARRAY_HAVE_SCRATCH 1 ++# else ++# define DYNARRAY_HAVE_SCRATCH 0 ++# endif ++#else ++/* Provide a reasonable default which limits the size of ++ DYNARRAY_STRUCT. */ ++# define DYNARRAY_INITIAL_SIZE \ ++ (sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT)) ++# define DYNARRAY_HAVE_SCRATCH 1 ++#endif ++ ++/* Public type definitions. */ ++ ++/* All fields of this struct are private to the implementation. */ ++struct DYNARRAY_STRUCT ++{ ++ union ++ { ++ struct dynarray_header dynarray_abstract; ++ struct ++ { ++ /* These fields must match struct dynarray_header. */ ++ size_t used; ++ size_t allocated; ++ DYNARRAY_ELEMENT *array; ++ } dynarray_header; ++ }; ++ ++#if DYNARRAY_HAVE_SCRATCH ++ /* Initial inline allocation. */ ++ DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE]; ++#endif ++}; ++ ++/* Internal use only: Helper macros. */ ++ ++/* Ensure macro-expansion of DYNARRAY_PREFIX. */ ++#define DYNARRAY_CONCAT0(prefix, name) prefix##name ++#define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name) ++#define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name) ++ ++/* Address of the scratch buffer if any. */ ++#if DYNARRAY_HAVE_SCRATCH ++# define DYNARRAY_SCRATCH(list) (list)->scratch ++#else ++# define DYNARRAY_SCRATCH(list) NULL ++#endif ++ ++/* Internal use only: Helper functions. */ ++ ++/* Internal function. Call DYNARRAY_ELEMENT_FREE with the array ++ elements. Name mangling needed due to the DYNARRAY_ELEMENT_FREE ++ macro expansion. */ ++static inline void ++DYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array, ++ size_t __dynarray_used) ++{ ++#ifdef DYNARRAY_ELEMENT_FREE ++ for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i) ++ DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]); ++#endif /* DYNARRAY_ELEMENT_FREE */ ++} ++ ++/* Internal function. Free the non-scratch array allocation. */ ++static inline void ++DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list) ++{ ++#if DYNARRAY_HAVE_SCRATCH ++ if (list->dynarray_header.array != list->scratch) ++ free (list->dynarray_header.array); ++#else ++ free (list->dynarray_header.array); ++#endif ++} ++ ++/* Public functions. */ ++ ++/* Initialize a dynamic array object. This must be called before any ++ use of the object. */ ++__attribute__ ((nonnull (1))) ++static void ++DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list) ++{ ++ list->dynarray_header.used = 0; ++ list->dynarray_header.allocated = DYNARRAY_INITIAL_SIZE; ++ list->dynarray_header.array = DYNARRAY_SCRATCH (list); ++} ++ ++/* Deallocate the dynamic array and its elements. */ ++__attribute__ ((unused, nonnull (1))) ++static void ++DYNARRAY_NAME (free) (struct DYNARRAY_STRUCT *list) ++{ ++ DYNARRAY_NAME (free__elements__) ++ (list->dynarray_header.array, list->dynarray_header.used); ++ DYNARRAY_NAME (free__array__) (list); ++ DYNARRAY_NAME (init) (list); ++} ++ ++/* Return true if the dynamic array is in an error state. */ ++__attribute__ ((nonnull (1))) ++static inline bool ++DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list) ++{ ++ return list->dynarray_header.allocated == __dynarray_error_marker (); ++} ++ ++/* Mark the dynamic array as failed. All elements are deallocated as ++ a side effect. */ ++__attribute__ ((nonnull (1))) ++static void ++DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list) ++{ ++ DYNARRAY_NAME (free__elements__) ++ (list->dynarray_header.array, list->dynarray_header.used); ++ DYNARRAY_NAME (free__array__) (list); ++ list->dynarray_header.array = DYNARRAY_SCRATCH (list); ++ list->dynarray_header.used = 0; ++ list->dynarray_header.allocated = __dynarray_error_marker (); ++} ++ ++/* Return the number of elements which have been added to the dynamic ++ array. */ ++__attribute__ ((nonnull (1))) ++static inline size_t ++DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list) ++{ ++ return list->dynarray_header.used; ++} ++ ++/* Return a pointer to the array element at INDEX. Terminate the ++ process if INDEX is out of bounds. */ ++__attribute__ ((nonnull (1))) ++static inline DYNARRAY_ELEMENT * ++DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index) ++{ ++ if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list))) ++ __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index); ++ return list->dynarray_header.array + index; ++} ++ ++/* Return a pointer to the first array element, if any. For a ++ zero-length array, the pointer can be NULL even though the dynamic ++ array has not entered the failure state. */ ++__attribute__ ((nonnull (1))) ++static inline DYNARRAY_ELEMENT * ++DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list) ++{ ++ return list->dynarray_header.array; ++} ++ ++/* Return a pointer one element past the last array element. For a ++ zero-length array, the pointer can be NULL even though the dynamic ++ array has not entered the failure state. */ ++__attribute__ ((nonnull (1))) ++static inline DYNARRAY_ELEMENT * ++DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list) ++{ ++ return list->dynarray_header.array + list->dynarray_header.used; ++} ++ ++/* Internal function. Slow path for the add function below. */ ++static void ++DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item) ++{ ++ if (__glibc_unlikely ++ (!__libc_dynarray_emplace_enlarge (&list->dynarray_abstract, ++ DYNARRAY_SCRATCH (list), ++ sizeof (DYNARRAY_ELEMENT)))) ++ { ++ DYNARRAY_NAME (mark_failed) (list); ++ return; ++ } ++ ++ /* Copy the new element and increase the array length. */ ++ list->dynarray_header.array[list->dynarray_header.used++] = item; ++} ++ ++/* Add ITEM at the end of the array, enlarging it by one element. ++ Mark *LIST as failed if the dynamic array allocation size cannot be ++ increased. */ ++__attribute__ ((unused, nonnull (1))) ++static inline void ++DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item) ++{ ++ /* Do nothing in case of previous error. */ ++ if (DYNARRAY_NAME (has_failed) (list)) ++ return; ++ ++ /* Enlarge the array if necessary. */ ++ if (__glibc_unlikely (list->dynarray_header.used ++ == list->dynarray_header.allocated)) ++ { ++ DYNARRAY_NAME (add__) (list, item); ++ return; ++ } ++ ++ /* Copy the new element and increase the array length. */ ++ list->dynarray_header.array[list->dynarray_header.used++] = item; ++} ++ ++/* Internal function. Building block for the emplace functions below. ++ Assumes space for one more element in *LIST. */ ++static inline DYNARRAY_ELEMENT * ++DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list) ++{ ++ DYNARRAY_ELEMENT *result ++ = &list->dynarray_header.array[list->dynarray_header.used]; ++ ++list->dynarray_header.used; ++#if defined (DYNARRAY_ELEMENT_INIT) ++ DYNARRAY_ELEMENT_INIT (result); ++#elif defined (DYNARRAY_ELEMENT_FREE) ++ memset (result, 0, sizeof (*result)); ++#endif ++ return result; ++} ++ ++/* Internal function. Slow path for the emplace function below. */ ++static DYNARRAY_ELEMENT * ++DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list) ++{ ++ if (__glibc_unlikely ++ (!__libc_dynarray_emplace_enlarge (&list->dynarray_abstract, ++ DYNARRAY_SCRATCH (list), ++ sizeof (DYNARRAY_ELEMENT)))) ++ { ++ DYNARRAY_NAME (mark_failed) (list); ++ return NULL; ++ } ++ return DYNARRAY_NAME (emplace__tail__) (list); ++} ++ ++/* Allocate a place for a new element in *LIST and return a pointer to ++ it. The pointer can be NULL if the dynamic array cannot be ++ enlarged due to a memory allocation failure. */ ++__attribute__ ((unused, warn_unused_result, nonnull (1))) ++static ++/* Avoid inlining with the larger initialization code. */ ++#if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE)) ++inline ++#endif ++DYNARRAY_ELEMENT * ++DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list) ++{ ++ /* Do nothing in case of previous error. */ ++ if (DYNARRAY_NAME (has_failed) (list)) ++ return NULL; ++ ++ /* Enlarge the array if necessary. */ ++ if (__glibc_unlikely (list->dynarray_header.used ++ == list->dynarray_header.allocated)) ++ return (DYNARRAY_NAME (emplace__) (list)); ++ return DYNARRAY_NAME (emplace__tail__) (list); ++} ++ ++/* Change the size of *LIST to SIZE. If SIZE is larger than the ++ existing size, new elements are added (which can be initialized). ++ Otherwise, the list is truncated, and elements are freed. Return ++ false on memory allocation failure (and mark *LIST as failed). */ ++__attribute__ ((unused, nonnull (1))) ++static bool ++DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size) ++{ ++ if (size > list->dynarray_header.used) ++ { ++ bool ok; ++#if defined (DYNARRAY_ELEMENT_INIT) ++ /* The new elements have to be initialized. */ ++ size_t old_size = list->dynarray_header.used; ++ ok = __libc_dynarray_resize (&list->dynarray_abstract, ++ size, DYNARRAY_SCRATCH (list), ++ sizeof (DYNARRAY_ELEMENT)); ++ if (ok) ++ for (size_t i = old_size; i < size; ++i) ++ { ++ DYNARRAY_ELEMENT_INIT (&list->dynarray_header.array[i]); ++ } ++#elif defined (DYNARRAY_ELEMENT_FREE) ++ /* Zero initialization is needed so that the elements can be ++ safely freed. */ ++ ok = __libc_dynarray_resize_clear ++ (&list->dynarray_abstract, size, ++ DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT)); ++#else ++ ok = __libc_dynarray_resize (&list->dynarray_abstract, ++ size, DYNARRAY_SCRATCH (list), ++ sizeof (DYNARRAY_ELEMENT)); ++#endif ++ if (__glibc_unlikely (!ok)) ++ DYNARRAY_NAME (mark_failed) (list); ++ return ok; ++ } ++ else ++ { ++ /* The list has shrunk in size. Free the removed elements. */ ++ DYNARRAY_NAME (free__elements__) ++ (list->dynarray_header.array + size, ++ list->dynarray_header.used - size); ++ list->dynarray_header.used = size; ++ return true; ++ } ++} ++ ++/* Remove the last element of LIST if it is present. */ ++__attribute__ ((unused, nonnull (1))) ++static void ++DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list) ++{ ++ /* used > 0 implies that the array is the non-failed state. */ ++ if (list->dynarray_header.used > 0) ++ { ++ size_t new_length = list->dynarray_header.used - 1; ++#ifdef DYNARRAY_ELEMENT_FREE ++ DYNARRAY_ELEMENT_FREE (&list->dynarray_header.array[new_length]); ++#endif ++ list->dynarray_header.used = new_length; ++ } ++} ++ ++/* Remove all elements from the list. The elements are freed, but the ++ list itself is not. */ ++__attribute__ ((unused, nonnull (1))) ++static void ++DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list) ++{ ++ /* free__elements__ does nothing if the list is in the failed ++ state. */ ++ DYNARRAY_NAME (free__elements__) ++ (list->dynarray_header.array, list->dynarray_header.used); ++ list->dynarray_header.used = 0; ++} ++ ++#ifdef DYNARRAY_FINAL_TYPE ++/* Transfer the dynamic array to a permanent location at *RESULT. ++ Returns true on success on false on allocation failure. In either ++ case, *LIST is re-initialized and can be reused. A NULL pointer is ++ stored in *RESULT if LIST refers to an empty list. On success, the ++ pointer in *RESULT is heap-allocated and must be deallocated using ++ free. */ ++__attribute__ ((unused, warn_unused_result, nonnull (1, 2))) ++static bool ++DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, ++ DYNARRAY_FINAL_TYPE *result) ++{ ++ struct dynarray_finalize_result res; ++ if (__libc_dynarray_finalize (&list->dynarray_abstract, ++ DYNARRAY_SCRATCH (list), ++ sizeof (DYNARRAY_ELEMENT), &res)) ++ { ++ /* On success, the result owns all the data. */ ++ DYNARRAY_NAME (init) (list); ++ *result = (DYNARRAY_FINAL_TYPE) { res.array, res.length }; ++ return true; ++ } ++ else ++ { ++ /* On error, we need to free all data. */ ++ DYNARRAY_NAME (free) (list); ++ errno = ENOMEM; ++ return false; ++ } ++} ++#else /* !DYNARRAY_FINAL_TYPE */ ++/* Transfer the dynamic array to a heap-allocated array and return a ++ pointer to it. The pointer is NULL if memory allocation fails, or ++ if the array is empty, so this function should be used only for ++ arrays which are known not be empty (usually because they always ++ have a sentinel at the end). If LENGTHP is not NULL, the array ++ length is written to *LENGTHP. *LIST is re-initialized and can be ++ reused. */ ++__attribute__ ((unused, warn_unused_result, nonnull (1))) ++static DYNARRAY_ELEMENT * ++DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp) ++{ ++ struct dynarray_finalize_result res; ++ if (__libc_dynarray_finalize (&list->dynarray_abstract, ++ DYNARRAY_SCRATCH (list), ++ sizeof (DYNARRAY_ELEMENT), &res)) ++ { ++ /* On success, the result owns all the data. */ ++ DYNARRAY_NAME (init) (list); ++ if (lengthp != NULL) ++ *lengthp = res.length; ++ return res.array; ++ } ++ else ++ { ++ /* On error, we need to free all data. */ ++ DYNARRAY_NAME (free) (list); ++ errno = ENOMEM; ++ return NULL; ++ } ++} ++#endif /* !DYNARRAY_FINAL_TYPE */ ++ ++/* Undo macro definitions. */ ++ ++#undef DYNARRAY_CONCAT0 ++#undef DYNARRAY_CONCAT1 ++#undef DYNARRAY_NAME ++#undef DYNARRAY_SCRATCH ++#undef DYNARRAY_HAVE_SCRATCH ++ ++#undef DYNARRAY_STRUCT ++#undef DYNARRAY_ELEMENT ++#undef DYNARRAY_PREFIX ++#undef DYNARRAY_ELEMENT_FREE ++#undef DYNARRAY_ELEMENT_INIT ++#undef DYNARRAY_INITIAL_SIZE ++#undef DYNARRAY_FINAL_TYPE +diff --git a/malloc/dynarray.h b/malloc/dynarray.h +new file mode 100644 +index 0000000000000000..5888bcbc1d4ae9bf +--- /dev/null ++++ b/malloc/dynarray.h +@@ -0,0 +1,179 @@ ++/* Type-safe arrays which grow dynamically. Shared definitions. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* To use the dynarray facility, you need to include ++ and define the parameter macros ++ documented in that file. ++ ++ A minimal example which provides a growing list of integers can be ++ defined like this: ++ ++ struct int_array ++ { ++ // Pointer to result array followed by its length, ++ // as required by DYNARRAY_FINAL_TYPE. ++ int *array; ++ size_t length; ++ }; ++ ++ #define DYNARRAY_STRUCT dynarray_int ++ #define DYNARRAY_ELEMENT int ++ #define DYNARRAY_PREFIX dynarray_int_ ++ #define DYNARRAY_FINAL_TYPE struct int_array ++ #include ++ ++ To create a three-element array with elements 1, 2, 3, use this ++ code: ++ ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ for (int i = 1; i <= 3; ++i) ++ { ++ int *place = dynarray_int_emplace (&dyn); ++ assert (place != NULL); ++ *place = i; ++ } ++ struct int_array result; ++ bool ok = dynarray_int_finalize (&dyn, &result); ++ assert (ok); ++ assert (result.length == 3); ++ assert (result.array[0] == 1); ++ assert (result.array[1] == 2); ++ assert (result.array[2] == 3); ++ free (result.array); ++ ++ If the elements contain resources which must be freed, define ++ DYNARRAY_ELEMENT_FREE appropriately, like this: ++ ++ struct str_array ++ { ++ char **array; ++ size_t length; ++ }; ++ ++ #define DYNARRAY_STRUCT dynarray_str ++ #define DYNARRAY_ELEMENT char * ++ #define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr) ++ #define DYNARRAY_PREFIX dynarray_str_ ++ #define DYNARRAY_FINAL_TYPE struct str_array ++ #include ++ ++ Compared to scratch buffers, dynamic arrays have the following ++ features: ++ ++ - They have an element type, and are not just an untyped buffer of ++ bytes. ++ ++ - When growing, previously stored elements are preserved. (It is ++ expected that scratch_buffer_grow_preserve and ++ scratch_buffer_set_array_size eventually go away because all ++ current users are moved to dynamic arrays.) ++ ++ - Scratch buffers have a more aggressive growth policy because ++ growing them typically means a retry of an operation (across an ++ NSS service module boundary), which is expensive. ++ ++ - For the same reason, scratch buffers have a much larger initial ++ stack allocation. */ ++ ++#ifndef _DYNARRAY_H ++#define _DYNARRAY_H ++ ++#include ++#include ++#include ++ ++struct dynarray_header ++{ ++ size_t used; ++ size_t allocated; ++ void *array; ++}; ++ ++/* Marker used in the allocated member to indicate that an error was ++ encountered. */ ++static inline size_t ++__dynarray_error_marker (void) ++{ ++ return -1; ++} ++ ++/* Internal function. See the has_failed function in ++ dynarray-skeleton.c. */ ++static inline bool ++__dynarray_error (struct dynarray_header *list) ++{ ++ return list->allocated == __dynarray_error_marker (); ++} ++ ++/* Internal function. Enlarge the dynamically allocated area of the ++ array to make room for one more element. SCRATCH is a pointer to ++ the scratch area (which is not heap-allocated and must not be ++ freed). ELEMENT_SIZE is the size, in bytes, of one element. ++ Return false on failure, true on success. */ ++bool __libc_dynarray_emplace_enlarge (struct dynarray_header *, ++ void *scratch, size_t element_size); ++ ++/* Internal function. Enlarge the dynamically allocated area of the ++ array to make room for at least SIZE elements (which must be larger ++ than the existing used part of the dynamic array). SCRATCH is a ++ pointer to the scratch area (which is not heap-allocated and must ++ not be freed). ELEMENT_SIZE is the size, in bytes, of one element. ++ Return false on failure, true on success. */ ++bool __libc_dynarray_resize (struct dynarray_header *, size_t size, ++ void *scratch, size_t element_size); ++ ++/* Internal function. Like __libc_dynarray_resize, but clear the new ++ part of the dynamic array. */ ++bool __libc_dynarray_resize_clear (struct dynarray_header *, size_t size, ++ void *scratch, size_t element_size); ++ ++/* Internal type. */ ++struct dynarray_finalize_result ++{ ++ void *array; ++ size_t length; ++}; ++ ++/* Internal function. Copy the dynamically-allocated area to an ++ explicitly-sized heap allocation. SCRATCH is a pointer to the ++ embedded scratch space. ELEMENT_SIZE is the size, in bytes, of the ++ element type. On success, true is returned, and pointer and length ++ are written to *RESULT. On failure, false is returned. The caller ++ has to take care of some of the memory management; this function is ++ expected to be called from dynarray-skeleton.c. */ ++bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch, ++ size_t element_size, ++ struct dynarray_finalize_result *result); ++ ++ ++/* Internal function. Terminate the process after an index error. ++ SIZE is the number of elements of the dynamic array. INDEX is the ++ lookup index which triggered the failure. */ ++void __libc_dynarray_at_failure (size_t size, size_t index) ++ __attribute__ ((noreturn)); ++ ++#ifndef _ISOMAC ++libc_hidden_proto (__libc_dynarray_emplace_enlarge) ++libc_hidden_proto (__libc_dynarray_resize) ++libc_hidden_proto (__libc_dynarray_resize_clear) ++libc_hidden_proto (__libc_dynarray_finalize) ++libc_hidden_proto (__libc_dynarray_at_failure) ++#endif ++ ++#endif /* _DYNARRAY_H */ +diff --git a/malloc/dynarray_at_failure.c b/malloc/dynarray_at_failure.c +new file mode 100644 +index 0000000000000000..fcc06f030b035165 +--- /dev/null ++++ b/malloc/dynarray_at_failure.c +@@ -0,0 +1,31 @@ ++/* Report an dynamic array index out of bounds condition. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++void ++__libc_dynarray_at_failure (size_t size, size_t index) ++{ ++ char buf[200]; ++ __snprintf (buf, sizeof (buf), "Fatal glibc error: " ++ "array index %zu not less than array length %zu\n", ++ index, size); ++ __libc_fatal (buf); ++} ++libc_hidden_def (__libc_dynarray_at_failure) +diff --git a/malloc/dynarray_emplace_enlarge.c b/malloc/dynarray_emplace_enlarge.c +new file mode 100644 +index 0000000000000000..a15245f4cb3d4288 +--- /dev/null ++++ b/malloc/dynarray_emplace_enlarge.c +@@ -0,0 +1,73 @@ ++/* Increase the size of a dynamic array in preparation of an emplace operation. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++bool ++__libc_dynarray_emplace_enlarge (struct dynarray_header *list, ++ void *scratch, size_t element_size) ++{ ++ size_t new_allocated; ++ if (list->allocated == 0) ++ { ++ /* No scratch buffer provided. Choose a reasonable default ++ size. */ ++ if (element_size < 4) ++ new_allocated = 16; ++ else if (element_size < 8) ++ new_allocated = 8; ++ else ++ new_allocated = 4; ++ } ++ else ++ /* Increase the allocated size, using an exponential growth ++ policy. */ ++ { ++ new_allocated = list->allocated + list->allocated / 2 + 1; ++ if (new_allocated <= list->allocated) ++ { ++ /* Overflow. */ ++ __set_errno (ENOMEM); ++ return false; ++ } ++ } ++ ++ size_t new_size; ++ if (check_mul_overflow_size_t (new_allocated, element_size, &new_size)) ++ return false; ++ void *new_array; ++ if (list->array == scratch) ++ { ++ /* The previous array was not heap-allocated. */ ++ new_array = malloc (new_size); ++ if (new_array != NULL && list->array != NULL) ++ memcpy (new_array, list->array, list->used * element_size); ++ } ++ else ++ new_array = realloc (list->array, new_size); ++ if (new_array == NULL) ++ return false; ++ list->array = new_array; ++ list->allocated = new_allocated; ++ return true; ++} ++libc_hidden_def (__libc_dynarray_emplace_enlarge) +diff --git a/malloc/dynarray_finalize.c b/malloc/dynarray_finalize.c +new file mode 100644 +index 0000000000000000..6dd8705382c73ae8 +--- /dev/null ++++ b/malloc/dynarray_finalize.c +@@ -0,0 +1,62 @@ ++/* Copy the dynamically-allocated area to an explicitly-sized heap allocation. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++bool ++__libc_dynarray_finalize (struct dynarray_header *list, ++ void *scratch, size_t element_size, ++ struct dynarray_finalize_result *result) ++{ ++ if (__dynarray_error (list)) ++ /* The caller will reported the deferred error. */ ++ return false; ++ ++ size_t used = list->used; ++ ++ /* Empty list. */ ++ if (used == 0) ++ { ++ /* An empty list could still be backed by a heap-allocated ++ array. Free it if necessary. */ ++ if (list->array != scratch) ++ free (list->array); ++ *result = (struct dynarray_finalize_result) { NULL, 0 }; ++ return true; ++ } ++ ++ size_t allocation_size = used * element_size; ++ void *heap_array = malloc (allocation_size); ++ if (heap_array != NULL) ++ { ++ /* The new array takes ownership of the strings. */ ++ if (list->array != NULL) ++ memcpy (heap_array, list->array, allocation_size); ++ if (list->array != scratch) ++ free (list->array); ++ *result = (struct dynarray_finalize_result) ++ { .array = heap_array, .length = used }; ++ return true; ++ } ++ else ++ /* The caller will perform the freeing operation. */ ++ return false; ++} ++libc_hidden_def (__libc_dynarray_finalize) +diff --git a/malloc/dynarray_resize.c b/malloc/dynarray_resize.c +new file mode 100644 +index 0000000000000000..63c981bf61f67145 +--- /dev/null ++++ b/malloc/dynarray_resize.c +@@ -0,0 +1,64 @@ ++/* Increase the size of a dynamic array. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++bool ++__libc_dynarray_resize (struct dynarray_header *list, size_t size, ++ void *scratch, size_t element_size) ++{ ++ /* The existing allocation provides sufficient room. */ ++ if (size <= list->allocated) ++ { ++ list->used = size; ++ return true; ++ } ++ ++ /* Otherwise, use size as the new allocation size. The caller is ++ expected to provide the final size of the array, so there is no ++ over-allocation here. */ ++ ++ size_t new_size_bytes; ++ if (check_mul_overflow_size_t (size, element_size, &new_size_bytes)) ++ { ++ /* Overflow. */ ++ __set_errno (ENOMEM); ++ return false; ++ } ++ void *new_array; ++ if (list->array == scratch) ++ { ++ /* The previous array was not heap-allocated. */ ++ new_array = malloc (new_size_bytes); ++ if (new_array != NULL && list->array != NULL) ++ memcpy (new_array, list->array, list->used * element_size); ++ } ++ else ++ new_array = realloc (list->array, new_size_bytes); ++ if (new_array == NULL) ++ return false; ++ list->array = new_array; ++ list->allocated = size; ++ list->used = size; ++ return true; ++} ++libc_hidden_def (__libc_dynarray_resize) +diff --git a/malloc/dynarray_resize_clear.c b/malloc/dynarray_resize_clear.c +new file mode 100644 +index 0000000000000000..0c4ced1d38b77918 +--- /dev/null ++++ b/malloc/dynarray_resize_clear.c +@@ -0,0 +1,35 @@ ++/* Increase the size of a dynamic array and clear the new part. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++bool ++__libc_dynarray_resize_clear (struct dynarray_header *list, size_t size, ++ void *scratch, size_t element_size) ++{ ++ size_t old_size = list->used; ++ if (!__libc_dynarray_resize (list, size, scratch, element_size)) ++ return false; ++ /* __libc_dynarray_resize already checked for overflow. */ ++ memset (list->array + (old_size * element_size), 0, ++ (size - old_size) * element_size); ++ return true; ++} ++libc_hidden_def (__libc_dynarray_resize_clear) +diff --git a/malloc/tst-dynarray-at-fail.c b/malloc/tst-dynarray-at-fail.c +new file mode 100644 +index 0000000000000000..8ba5f92b58141c52 +--- /dev/null ++++ b/malloc/tst-dynarray-at-fail.c +@@ -0,0 +1,125 @@ ++/* Test reporting of out-of-bounds access for dynamic arrays. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dynarray-shared.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Run CALLBACK and check that the data on standard error equals ++ EXPECTED. */ ++static void ++check (const char *test, void (*callback) (void *), size_t index, ++ const char *expected) ++{ ++ struct support_capture_subprocess result ++ = support_capture_subprocess (callback, &index); ++ if (strcmp (result.err.buffer, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: test %s (%zu) unexpected standard error data\n" ++ " expected: %s\n" ++ " actual: %s\n", ++ test, index, expected, result.err.buffer); ++ } ++ TEST_VERIFY (strlen (result.out.buffer) == 0); ++ TEST_VERIFY (WIFSIGNALED (result.status)); ++ if (WIFSIGNALED (result.status)) ++ TEST_VERIFY (WTERMSIG (result.status) == SIGABRT); ++ support_capture_subprocess_free (&result); ++} ++ ++/* Try indexing an empty array. */ ++static void ++test_empty (void *closure) ++{ ++ size_t *pindex = closure; ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ dynarray_int_at (&dyn, *pindex); ++} ++ ++/* Try indexing a one-element array. */ ++static void ++test_one (void *closure) ++{ ++ size_t *pindex = closure; ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ TEST_VERIFY (dynarray_int_resize (&dyn, 1)); ++ dynarray_int_at (&dyn, *pindex); ++} ++ ++/* Try indexing a longer array. */ ++static void ++test_many (void *closure) ++{ ++ size_t *pindex = closure; ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ TEST_VERIFY (dynarray_int_resize (&dyn, 5371)); ++ dynarray_int_at (&dyn, *pindex); ++} ++ ++/* (size_t) -1 for use in string literals. */ ++#if __WORDSIZE == 32 ++# define MINUS_1 "4294967295" ++#elif __WORDSIZE == 64 ++# define MINUS_1 "18446744073709551615" ++#else ++# error "unknown value for __WORDSIZE" ++#endif ++ ++static int ++do_test (void) ++{ ++ TEST_VERIFY (setenv ("LIBC_FATAL_STDERR_", "1", 1) == 0); ++ ++ check ("test_empty", test_empty, 0, ++ "Fatal glibc error: array index 0 not less than array length 0\n"); ++ check ("test_empty", test_empty, 1, ++ "Fatal glibc error: array index 1 not less than array length 0\n"); ++ check ("test_empty", test_empty, -1, ++ "Fatal glibc error: array index " MINUS_1 ++ " not less than array length 0\n"); ++ ++ check ("test_one", test_one, 1, ++ "Fatal glibc error: array index 1 not less than array length 1\n"); ++ check ("test_one", test_one, 2, ++ "Fatal glibc error: array index 2 not less than array length 1\n"); ++ check ("test_one", test_one, -1, ++ "Fatal glibc error: array index " MINUS_1 ++ " not less than array length 1\n"); ++ ++ check ("test_many", test_many, 5371, ++ "Fatal glibc error: array index 5371" ++ " not less than array length 5371\n"); ++ check ("test_many", test_many, 5372, ++ "Fatal glibc error: array index 5372" ++ " not less than array length 5371\n"); ++ check ("test_many", test_many, -1, ++ "Fatal glibc error: array index " MINUS_1 ++ " not less than array length 5371\n"); ++ ++ return 0; ++} ++ ++#include +diff --git a/malloc/tst-dynarray-fail.c b/malloc/tst-dynarray-fail.c +new file mode 100644 +index 0000000000000000..508dbae93e6bce31 +--- /dev/null ++++ b/malloc/tst-dynarray-fail.c +@@ -0,0 +1,418 @@ ++/* Test allocation failures with dynamic arrays. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test is separate from tst-dynarray because it cannot run under ++ valgrind. */ ++ ++#include "tst-dynarray-shared.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Data structure to fill up the heap. */ ++struct heap_filler ++{ ++ struct heap_filler *next; ++}; ++ ++/* Allocate objects until the heap is full. */ ++static struct heap_filler * ++fill_heap (void) ++{ ++ size_t pad = 4096; ++ struct heap_filler *head = NULL; ++ while (true) ++ { ++ struct heap_filler *new_head = malloc (sizeof (*new_head) + pad); ++ if (new_head == NULL) ++ { ++ if (pad > 0) ++ { ++ /* Try again with smaller allocations. */ ++ pad = 0; ++ continue; ++ } ++ else ++ break; ++ } ++ new_head->next = head; ++ head = new_head; ++ } ++ return head; ++} ++ ++/* Free the heap-filling allocations, so that we can continue testing ++ and detect memory leaks elsewhere. */ ++static void ++free_fill_heap (struct heap_filler *head) ++{ ++ while (head != NULL) ++ { ++ struct heap_filler *next = head->next; ++ free (head); ++ head = next; ++ } ++} ++ ++/* Check allocation failures for int arrays (without an element free ++ function). */ ++static void ++test_int_fail (void) ++{ ++ /* Exercise failure in add/emplace. ++ ++ do_add: Use emplace (false) or add (true) to add elements. ++ do_finalize: Perform finalization at the end (instead of free). */ ++ for (int do_add = 0; do_add < 2; ++do_add) ++ for (int do_finalize = 0; do_finalize < 2; ++do_finalize) ++ { ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ size_t count = 0; ++ while (true) ++ { ++ if (do_add) ++ { ++ dynarray_int_add (&dyn, 0); ++ if (dynarray_int_has_failed (&dyn)) ++ break; ++ } ++ else ++ { ++ int *place = dynarray_int_emplace (&dyn); ++ if (place == NULL) ++ break; ++ TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); ++ *place = 0; ++ } ++ ++count; ++ } ++ printf ("info: %s: failure after %zu elements\n", __func__, count); ++ TEST_VERIFY_EXIT (dynarray_int_has_failed (&dyn)); ++ if (do_finalize) ++ { ++ struct int_array result = { (int *) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (!dynarray_int_finalize (&dyn, &result)); ++ TEST_VERIFY_EXIT (result.array == (int *) (uintptr_t) -1); ++ TEST_VERIFY_EXIT (result.length == (size_t) -1); ++ } ++ else ++ dynarray_int_free (&dyn); ++ CHECK_INIT_STATE (int, &dyn); ++ } ++ ++ /* Exercise failure in finalize. */ ++ for (int do_add = 0; do_add < 2; ++do_add) ++ { ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ for (unsigned int i = 0; i < 10000; ++i) ++ { ++ if (do_add) ++ { ++ dynarray_int_add (&dyn, i); ++ TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); ++ } ++ else ++ { ++ int *place = dynarray_int_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ *place = i; ++ } ++ } ++ TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); ++ struct heap_filler *heap_filler = fill_heap (); ++ struct int_array result = { (int *) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (!dynarray_int_finalize (&dyn, &result)); ++ TEST_VERIFY_EXIT (result.array == (int *) (uintptr_t) -1); ++ TEST_VERIFY_EXIT (result.length == (size_t) -1); ++ CHECK_INIT_STATE (int, &dyn); ++ free_fill_heap (heap_filler); ++ } ++ ++ /* Exercise failure in resize. */ ++ { ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ struct heap_filler *heap_filler = fill_heap (); ++ TEST_VERIFY (!dynarray_int_resize (&dyn, 1000)); ++ TEST_VERIFY (dynarray_int_has_failed (&dyn)); ++ free_fill_heap (heap_filler); ++ ++ dynarray_int_init (&dyn); ++ TEST_VERIFY (dynarray_int_resize (&dyn, 1)); ++ heap_filler = fill_heap (); ++ TEST_VERIFY (!dynarray_int_resize (&dyn, 1000)); ++ TEST_VERIFY (dynarray_int_has_failed (&dyn)); ++ free_fill_heap (heap_filler); ++ ++ dynarray_int_init (&dyn); ++ TEST_VERIFY (dynarray_int_resize (&dyn, 1000)); ++ heap_filler = fill_heap (); ++ TEST_VERIFY (!dynarray_int_resize (&dyn, 2000)); ++ TEST_VERIFY (dynarray_int_has_failed (&dyn)); ++ free_fill_heap (heap_filler); ++ } ++} ++ ++/* Check allocation failures for char * arrays (which automatically ++ free the pointed-to strings). */ ++static void ++test_str_fail (void) ++{ ++ /* Exercise failure in add/emplace. ++ ++ do_add: Use emplace (false) or add (true) to add elements. ++ do_finalize: Perform finalization at the end (instead of free). */ ++ for (int do_add = 0; do_add < 2; ++do_add) ++ for (int do_finalize = 0; do_finalize < 2; ++do_finalize) ++ { ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ size_t count = 0; ++ while (true) ++ { ++ char **place; ++ if (do_add) ++ { ++ dynarray_str_add (&dyn, NULL); ++ if (dynarray_str_has_failed (&dyn)) ++ break; ++ else ++ place = dynarray_str_at (&dyn, dynarray_str_size (&dyn) - 1); ++ } ++ else ++ { ++ place = dynarray_str_emplace (&dyn); ++ if (place == NULL) ++ break; ++ } ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ TEST_VERIFY_EXIT (*place == NULL); ++ *place = strdup ("placeholder"); ++ if (*place == NULL) ++ { ++ /* Second loop to wait for failure of ++ dynarray_str_emplace. */ ++ while (true) ++ { ++ if (do_add) ++ { ++ dynarray_str_add (&dyn, NULL); ++ if (dynarray_str_has_failed (&dyn)) ++ break; ++ } ++ else ++ { ++ char **place = dynarray_str_emplace (&dyn); ++ if (place == NULL) ++ break; ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ *place = NULL; ++ } ++ ++count; ++ } ++ break; ++ } ++ ++count; ++ } ++ printf ("info: %s: failure after %zu elements\n", __func__, count); ++ TEST_VERIFY_EXIT (dynarray_str_has_failed (&dyn)); ++ if (do_finalize) ++ { ++ struct str_array result = { (char **) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (!dynarray_str_finalize (&dyn, &result)); ++ TEST_VERIFY_EXIT (result.array == (char **) (uintptr_t) -1); ++ TEST_VERIFY_EXIT (result.length == (size_t) -1); ++ } ++ else ++ dynarray_str_free (&dyn); ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch); ++ TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0); ++ TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0); ++ } ++ ++ /* Exercise failure in finalize. */ ++ for (int do_add = 0; do_add < 2; ++do_add) ++ { ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ for (unsigned int i = 0; i < 1000; ++i) ++ { ++ if (do_add) ++ dynarray_str_add (&dyn, xstrdup ("placeholder")); ++ else ++ { ++ char **place = dynarray_str_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ TEST_VERIFY_EXIT (*place == NULL); ++ *place = xstrdup ("placeholder"); ++ } ++ } ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ struct heap_filler *heap_filler = fill_heap (); ++ struct str_array result = { (char **) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (!dynarray_str_finalize (&dyn, &result)); ++ TEST_VERIFY_EXIT (result.array == (char **) (uintptr_t) -1); ++ TEST_VERIFY_EXIT (result.length == (size_t) -1); ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch); ++ TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0); ++ TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0); ++ free_fill_heap (heap_filler); ++ } ++ ++ /* Exercise failure in resize. */ ++ { ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ struct heap_filler *heap_filler = fill_heap (); ++ TEST_VERIFY (!dynarray_str_resize (&dyn, 1000)); ++ TEST_VERIFY (dynarray_str_has_failed (&dyn)); ++ free_fill_heap (heap_filler); ++ ++ dynarray_str_init (&dyn); ++ TEST_VERIFY (dynarray_str_resize (&dyn, 1)); ++ *dynarray_str_at (&dyn, 0) = xstrdup ("allocated"); ++ heap_filler = fill_heap (); ++ TEST_VERIFY (!dynarray_str_resize (&dyn, 1000)); ++ TEST_VERIFY (dynarray_str_has_failed (&dyn)); ++ free_fill_heap (heap_filler); ++ ++ dynarray_str_init (&dyn); ++ TEST_VERIFY (dynarray_str_resize (&dyn, 1000)); ++ *dynarray_str_at (&dyn, 0) = xstrdup ("allocated"); ++ heap_filler = fill_heap (); ++ TEST_VERIFY (!dynarray_str_resize (&dyn, 2000)); ++ TEST_VERIFY (dynarray_str_has_failed (&dyn)); ++ free_fill_heap (heap_filler); ++ } ++} ++ ++/* Test if mmap can allocate a page. This is necessary because ++ setrlimit does not fail even if it reduces the RLIMIT_AS limit ++ below what is currently needed by the process. */ ++static bool ++mmap_works (void) ++{ ++ void *ptr = mmap (NULL, 1, PROT_READ | PROT_WRITE, ++ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ++ if (ptr == MAP_FAILED) ++ return false; ++ xmunmap (ptr, 1); ++ return true; ++} ++ ++/* Set the RLIMIT_AS limit to the value in *LIMIT. */ ++static void ++xsetrlimit_as (const struct rlimit *limit) ++{ ++ if (setrlimit (RLIMIT_AS, limit) != 0) ++ FAIL_EXIT1 ("setrlimit (RLIMIT_AS, %lu): %m", ++ (unsigned long) limit->rlim_cur); ++} ++ ++/* Approximately this many bytes can be allocated after ++ reduce_rlimit_as has run. */ ++enum { as_limit_reserve = 2 * 1024 * 1024 }; ++ ++/* Limit the size of the process, so that memory allocation in ++ allocate_thread will eventually fail, without impacting the entire ++ system. By default, a dynamic limit which leaves room for 2 MiB is ++ activated. The TEST_RLIMIT_AS environment variable overrides ++ it. */ ++static void ++reduce_rlimit_as (void) ++{ ++ struct rlimit limit; ++ if (getrlimit (RLIMIT_AS, &limit) != 0) ++ FAIL_EXIT1 ("getrlimit (RLIMIT_AS) failed: %m"); ++ ++ /* Use the TEST_RLIMIT_AS setting if available. */ ++ { ++ long target = 0; ++ const char *variable = "TEST_RLIMIT_AS"; ++ const char *target_str = getenv (variable); ++ if (target_str != NULL) ++ { ++ target = atoi (target_str); ++ if (target <= 0) ++ FAIL_EXIT1 ("invalid %s value: \"%s\"", variable, target_str); ++ printf ("info: setting RLIMIT_AS to %ld MiB\n", target); ++ target *= 1024 * 1024; /* Convert to megabytes. */ ++ limit.rlim_cur = target; ++ xsetrlimit_as (&limit); ++ return; ++ } ++ } ++ ++ /* Otherwise, try to find the limit with a binary search. */ ++ unsigned long low = 1 << 20; ++ limit.rlim_cur = low; ++ xsetrlimit_as (&limit); ++ ++ /* Find working upper limit. */ ++ unsigned long high = 1 << 30; ++ while (true) ++ { ++ limit.rlim_cur = high; ++ xsetrlimit_as (&limit); ++ if (mmap_works ()) ++ break; ++ if (2 * high < high) ++ FAIL_EXIT1 ("cannot find upper AS limit"); ++ high *= 2; ++ } ++ ++ /* Perform binary search. */ ++ while ((high - low) > 128 * 1024) ++ { ++ unsigned long middle = (low + high) / 2; ++ limit.rlim_cur = middle; ++ xsetrlimit_as (&limit); ++ if (mmap_works ()) ++ high = middle; ++ else ++ low = middle; ++ } ++ ++ unsigned long target = high + as_limit_reserve; ++ limit.rlim_cur = target; ++ xsetrlimit_as (&limit); ++ printf ("info: RLIMIT_AS limit: %lu bytes\n", target); ++} ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ reduce_rlimit_as (); ++ test_int_fail (); ++ test_str_fail (); ++ return 0; ++} ++ ++#define TIMEOUT 90 ++#include +diff --git a/malloc/tst-dynarray-shared.h b/malloc/tst-dynarray-shared.h +new file mode 100644 +index 0000000000000000..1de9c04be88843d0 +--- /dev/null ++++ b/malloc/tst-dynarray-shared.h +@@ -0,0 +1,80 @@ ++/* Shared definitions for dynarray tests. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++struct int_array ++{ ++ int *array; ++ size_t length; ++}; ++ ++#define DYNARRAY_STRUCT dynarray_int ++#define DYNARRAY_ELEMENT int ++#define DYNARRAY_PREFIX dynarray_int_ ++#define DYNARRAY_FINAL_TYPE struct int_array ++#include ++ ++struct str_array ++{ ++ char **array; ++ size_t length; ++}; ++ ++#define DYNARRAY_STRUCT dynarray_str ++#define DYNARRAY_ELEMENT char * ++#define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr) ++#define DYNARRAY_PREFIX dynarray_str_ ++#define DYNARRAY_FINAL_TYPE struct str_array ++#include ++ ++/* Check that *DYN is equivalent to its initial state. */ ++#define CHECK_INIT_STATE(type, dyn) \ ++ ({ \ ++ TEST_VERIFY_EXIT (!dynarray_##type##_has_failed (dyn)); \ ++ TEST_VERIFY_EXIT (dynarray_##type##_size (dyn) == 0); \ ++ TEST_VERIFY_EXIT ((dyn)->dynarray_header.array \ ++ == (dyn)->scratch); \ ++ TEST_VERIFY_EXIT ((dyn)->dynarray_header.allocated > 0); \ ++ (void) 0; \ ++ }) ++ ++/* Check that *DYN behaves as if it is in its initial state. */ ++#define CHECK_EMPTY(type, dyn) \ ++ ({ \ ++ CHECK_INIT_STATE (type, (dyn)); \ ++ dynarray_##type##_free (dyn); \ ++ CHECK_INIT_STATE (type, (dyn)); \ ++ dynarray_##type##_clear (dyn); \ ++ CHECK_INIT_STATE (type, (dyn)); \ ++ dynarray_##type##_remove_last (dyn); \ ++ CHECK_INIT_STATE (type, (dyn)); \ ++ dynarray_##type##_mark_failed (dyn); \ ++ TEST_VERIFY_EXIT (dynarray_##type##_has_failed (dyn)); \ ++ dynarray_##type##_clear (dyn); \ ++ TEST_VERIFY_EXIT (dynarray_##type##_has_failed (dyn)); \ ++ dynarray_##type##_remove_last (dyn); \ ++ TEST_VERIFY_EXIT (dynarray_##type##_has_failed (dyn)); \ ++ TEST_VERIFY_EXIT (dynarray_##type##_emplace (dyn) == NULL); \ ++ dynarray_##type##_free (dyn); \ ++ CHECK_INIT_STATE (type, (dyn)); \ ++ /* These functions should not assert. */ \ ++ dynarray_##type##_begin (dyn); \ ++ dynarray_##type##_end (dyn); \ ++ (void) 0; \ ++ }) +diff --git a/malloc/tst-dynarray.c b/malloc/tst-dynarray.c +new file mode 100644 +index 0000000000000000..d11f7bb8a343a16a +--- /dev/null ++++ b/malloc/tst-dynarray.c +@@ -0,0 +1,574 @@ ++/* Test for dynamic arrays. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "tst-dynarray-shared.h" ++ ++#include ++#include ++ ++#define DYNARRAY_STRUCT dynarray_long ++#define DYNARRAY_ELEMENT long ++#define DYNARRAY_PREFIX dynarray_long_ ++#define DYNARRAY_ELEMENT_INIT(e) (*(e) = 17) ++#include ++ ++struct long_array ++{ ++ long *array; ++ size_t length; ++}; ++ ++#define DYNARRAY_STRUCT dynarray_long_noscratch ++#define DYNARRAY_ELEMENT long ++#define DYNARRAY_PREFIX dynarray_long_noscratch_ ++#define DYNARRAY_ELEMENT_INIT(e) (*(e) = 23) ++#define DYNARRAY_FINAL_TYPE struct long_array ++#define DYNARRAY_INITIAL_SIZE 0 ++#include ++ ++#define DYNARRAY_STRUCT zstr ++#define DYNARRAY_ELEMENT char ++#define DYNARRAY_PREFIX zstr_ ++#define DYNARRAY_INITIAL_SIZE 128 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++enum { max_count = 20 }; ++ ++/* Test dynamic arrays with int elements (no automatic deallocation ++ for elements). */ ++static void ++test_int (void) ++{ ++ /* Empty array. */ ++ { ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ CHECK_EMPTY (int, &dyn); ++ } ++ ++ /* Empty array with finalization. */ ++ { ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ CHECK_INIT_STATE (int, &dyn); ++ struct int_array result = { (int *) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result)); ++ CHECK_INIT_STATE (int, &dyn); ++ TEST_VERIFY_EXIT (result.array == NULL); ++ TEST_VERIFY_EXIT (result.length == 0); ++ } ++ ++ /* Non-empty array tests. ++ ++ do_add: Switch between emplace (false) and add (true). ++ do_finalize: Perform finalize call at the end. ++ do_clear: Perform clear call at the end. ++ do_remove_last: Perform remove_last call after adding elements. ++ count: Number of elements added to the array. */ ++ for (int do_add = 0; do_add < 2; ++do_add) ++ for (int do_finalize = 0; do_finalize < 2; ++do_finalize) ++ for (int do_clear = 0; do_clear < 2; ++do_clear) ++ for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last) ++ for (unsigned int count = 0; count < max_count; ++count) ++ { ++ if (do_remove_last && count == 0) ++ continue; ++ unsigned int base = count * count; ++ struct dynarray_int dyn; ++ dynarray_int_init (&dyn); ++ for (unsigned int i = 0; i < count; ++i) ++ { ++ if (do_add) ++ dynarray_int_add (&dyn, base + i); ++ else ++ { ++ int *place = dynarray_int_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ *place = base + i; ++ } ++ TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); ++ TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == i + 1); ++ TEST_VERIFY_EXIT (dynarray_int_size (&dyn) ++ <= dyn.dynarray_header.allocated); ++ } ++ TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == count); ++ TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated); ++ if (count > 0) ++ { ++ TEST_VERIFY (dynarray_int_begin (&dyn) ++ == dynarray_int_at (&dyn, 0)); ++ TEST_VERIFY (dynarray_int_end (&dyn) ++ == dynarray_int_at (&dyn, count - 1) + 1); ++ } ++ unsigned final_count; ++ bool heap_array = dyn.dynarray_header.array != dyn.scratch; ++ if (do_remove_last) ++ { ++ dynarray_int_remove_last (&dyn); ++ if (count == 0) ++ final_count = 0; ++ else ++ final_count = count - 1; ++ } ++ else ++ final_count = count; ++ if (final_count > 0) ++ { ++ TEST_VERIFY (dynarray_int_begin (&dyn) ++ == dynarray_int_at (&dyn, 0)); ++ TEST_VERIFY (dynarray_int_end (&dyn) ++ == dynarray_int_at (&dyn, final_count - 1) + 1); ++ } ++ if (do_clear) ++ { ++ dynarray_int_clear (&dyn); ++ final_count = 0; ++ } ++ TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); ++ TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch) ++ == heap_array); ++ TEST_VERIFY_EXIT (dynarray_int_size (&dyn) == final_count); ++ TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count); ++ if (!do_clear) ++ for (unsigned int i = 0; i < final_count; ++i) ++ TEST_VERIFY_EXIT (*dynarray_int_at (&dyn, i) == base + i); ++ if (do_finalize) ++ { ++ struct int_array result = { (int *) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (dynarray_int_finalize (&dyn, &result)); ++ CHECK_INIT_STATE (int, &dyn); ++ TEST_VERIFY_EXIT (result.length == final_count); ++ if (final_count == 0) ++ TEST_VERIFY_EXIT (result.array == NULL); ++ else ++ { ++ TEST_VERIFY_EXIT (result.array != NULL); ++ TEST_VERIFY_EXIT (result.array != (int *) (uintptr_t) -1); ++ TEST_VERIFY_EXIT ++ (malloc_usable_size (result.array) ++ >= final_count * sizeof (result.array[0])); ++ for (unsigned int i = 0; i < final_count; ++i) ++ TEST_VERIFY_EXIT (result.array[i] == base + i); ++ free (result.array); ++ } ++ } ++ else /* !do_finalize */ ++ { ++ dynarray_int_free (&dyn); ++ CHECK_INIT_STATE (int, &dyn); ++ } ++ } ++} ++ ++/* Test dynamic arrays with char * elements (with automatic ++ deallocation of the pointed-to strings). */ ++static void ++test_str (void) ++{ ++ /* Empty array. */ ++ { ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ CHECK_EMPTY (str, &dyn); ++ } ++ ++ /* Empty array with finalization. */ ++ { ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ struct str_array result = { (char **) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result)); ++ CHECK_INIT_STATE (str, &dyn); ++ TEST_VERIFY_EXIT (result.array == NULL); ++ TEST_VERIFY_EXIT (result.length == 0); ++ } ++ ++ /* Non-empty array tests. ++ ++ do_add: Switch between emplace (false) and add (true). ++ do_finalize: Perform finalize call at the end. ++ do_clear: Perform clear call at the end. ++ do_remove_last: Perform remove_last call after adding elements. ++ count: Number of elements added to the array. */ ++ for (int do_add = 0; do_add < 2; ++do_add) ++ for (int do_finalize = 0; do_finalize < 2; ++do_finalize) ++ for (int do_clear = 0; do_clear < 2; ++do_clear) ++ for (int do_remove_last = 0; do_remove_last < 2; ++do_remove_last) ++ for (unsigned int count = 0; count < max_count; ++count) ++ { ++ if (do_remove_last && count == 0) ++ continue; ++ unsigned int base = count * count; ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ for (unsigned int i = 0; i < count; ++i) ++ { ++ char *item = xasprintf ("%d", base + i); ++ if (do_add) ++ dynarray_str_add (&dyn, item); ++ else ++ { ++ char **place = dynarray_str_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ TEST_VERIFY_EXIT (*place == NULL); ++ *place = item; ++ } ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == i + 1); ++ TEST_VERIFY_EXIT (dynarray_str_size (&dyn) ++ <= dyn.dynarray_header.allocated); ++ } ++ TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == count); ++ TEST_VERIFY_EXIT (count <= dyn.dynarray_header.allocated); ++ if (count > 0) ++ { ++ TEST_VERIFY (dynarray_str_begin (&dyn) ++ == dynarray_str_at (&dyn, 0)); ++ TEST_VERIFY (dynarray_str_end (&dyn) ++ == dynarray_str_at (&dyn, count - 1) + 1); ++ } ++ unsigned final_count; ++ bool heap_array = dyn.dynarray_header.array != dyn.scratch; ++ if (do_remove_last) ++ { ++ dynarray_str_remove_last (&dyn); ++ if (count == 0) ++ final_count = 0; ++ else ++ final_count = count - 1; ++ } ++ else ++ final_count = count; ++ if (final_count > 0) ++ { ++ TEST_VERIFY (dynarray_str_begin (&dyn) ++ == dynarray_str_at (&dyn, 0)); ++ TEST_VERIFY (dynarray_str_end (&dyn) ++ == dynarray_str_at (&dyn, final_count - 1) + 1); ++ } ++ if (do_clear) ++ { ++ dynarray_str_clear (&dyn); ++ final_count = 0; ++ } ++ TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); ++ TEST_VERIFY_EXIT ((dyn.dynarray_header.array != dyn.scratch) ++ == heap_array); ++ TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == final_count); ++ TEST_VERIFY_EXIT (dyn.dynarray_header.allocated >= final_count); ++ if (!do_clear) ++ for (unsigned int i = 0; i < count - do_remove_last; ++i) ++ { ++ char *expected = xasprintf ("%d", base + i); ++ const char *actual = *dynarray_str_at (&dyn, i); ++ TEST_VERIFY_EXIT (strcmp (actual, expected) == 0); ++ free (expected); ++ } ++ if (do_finalize) ++ { ++ struct str_array result = { (char **) (uintptr_t) -1, -1 }; ++ TEST_VERIFY_EXIT (dynarray_str_finalize (&dyn, &result)); ++ CHECK_INIT_STATE (str, &dyn); ++ TEST_VERIFY_EXIT (result.length == final_count); ++ if (final_count == 0) ++ TEST_VERIFY_EXIT (result.array == NULL); ++ else ++ { ++ TEST_VERIFY_EXIT (result.array != NULL); ++ TEST_VERIFY_EXIT (result.array ++ != (char **) (uintptr_t) -1); ++ TEST_VERIFY_EXIT (result.length ++ == count - do_remove_last); ++ TEST_VERIFY_EXIT ++ (malloc_usable_size (result.array) ++ >= final_count * sizeof (result.array[0])); ++ for (unsigned int i = 0; i < count - do_remove_last; ++i) ++ { ++ char *expected = xasprintf ("%d", base + i); ++ char *actual = result.array[i]; ++ TEST_VERIFY_EXIT (strcmp (actual, expected) == 0); ++ free (expected); ++ free (actual); ++ } ++ free (result.array); ++ } ++ } ++ else /* !do_finalize */ ++ { ++ dynarray_str_free (&dyn); ++ CHECK_INIT_STATE (str, &dyn); ++ } ++ } ++ ++ /* Test resizing. */ ++ { ++ enum { count = 2131 }; ++ struct dynarray_str dyn; ++ dynarray_str_init (&dyn); ++ ++ /* From length 0 to length 1. */ ++ TEST_VERIFY (dynarray_str_resize (&dyn, 1)); ++ TEST_VERIFY (dynarray_str_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL); ++ *dynarray_str_at (&dyn, 0) = xstrdup ("allocated"); ++ dynarray_str_free (&dyn); ++ ++ /* From length 0 to length 1 and 2. */ ++ TEST_VERIFY (dynarray_str_resize (&dyn, 1)); ++ TEST_VERIFY (dynarray_str_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_str_at (&dyn, 0) == NULL); ++ *dynarray_str_at (&dyn, 0) = xstrdup ("allocated0"); ++ TEST_VERIFY (dynarray_str_resize (&dyn, 2)); ++ TEST_VERIFY (dynarray_str_size (&dyn) == 2); ++ TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0); ++ TEST_VERIFY (*dynarray_str_at (&dyn, 1) == NULL); ++ *dynarray_str_at (&dyn, 1) = xstrdup ("allocated1"); ++ TEST_VERIFY (dynarray_str_resize (&dyn, count)); ++ TEST_VERIFY (dynarray_str_size (&dyn) == count); ++ TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0); ++ TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0); ++ for (int i = 2; i < count; ++i) ++ TEST_VERIFY (*dynarray_str_at (&dyn, i) == NULL); ++ *dynarray_str_at (&dyn, count - 1) = xstrdup ("allocated2"); ++ TEST_VERIFY (dynarray_str_resize (&dyn, 3)); ++ TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 0), "allocated0") == 0); ++ TEST_VERIFY (strcmp (*dynarray_str_at (&dyn, 1), "allocated1") == 0); ++ TEST_VERIFY (*dynarray_str_at (&dyn, 2) == NULL); ++ dynarray_str_free (&dyn); ++ } ++} ++ ++/* Verify that DYNARRAY_ELEMENT_INIT has an effect. */ ++static void ++test_long_init (void) ++{ ++ enum { count = 2131 }; ++ { ++ struct dynarray_long dyn; ++ dynarray_long_init (&dyn); ++ for (int i = 0; i < count; ++i) ++ { ++ long *place = dynarray_long_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ TEST_VERIFY (*place == 17); ++ } ++ TEST_VERIFY (dynarray_long_size (&dyn) == count); ++ for (int i = 0; i < count; ++i) ++ TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17); ++ dynarray_long_free (&dyn); ++ ++ TEST_VERIFY (dynarray_long_resize (&dyn, 1)); ++ TEST_VERIFY (dynarray_long_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17); ++ *dynarray_long_at (&dyn, 0) = 18; ++ dynarray_long_free (&dyn); ++ TEST_VERIFY (dynarray_long_resize (&dyn, 1)); ++ TEST_VERIFY (dynarray_long_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17); ++ TEST_VERIFY (dynarray_long_resize (&dyn, 2)); ++ TEST_VERIFY (dynarray_long_size (&dyn) == 2); ++ TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 17); ++ TEST_VERIFY (*dynarray_long_at (&dyn, 1) == 17); ++ *dynarray_long_at (&dyn, 0) = 18; ++ TEST_VERIFY (dynarray_long_resize (&dyn, count)); ++ TEST_VERIFY (dynarray_long_size (&dyn) == count); ++ TEST_VERIFY (*dynarray_long_at (&dyn, 0) == 18); ++ for (int i = 1; i < count; ++i) ++ TEST_VERIFY (*dynarray_long_at (&dyn, i) == 17); ++ dynarray_long_free (&dyn); ++ } ++ ++ /* Similar, but without an on-stack scratch region ++ (DYNARRAY_INITIAL_SIZE is 0). */ ++ { ++ struct dynarray_long_noscratch dyn; ++ dynarray_long_noscratch_init (&dyn); ++ struct long_array result; ++ TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result)); ++ TEST_VERIFY (result.array == NULL); ++ TEST_VERIFY (result.length == 0); ++ ++ /* Test with one element. */ ++ { ++ long *place = dynarray_long_noscratch_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ TEST_VERIFY (*place == 23); ++ } ++ TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23); ++ TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result)); ++ TEST_VERIFY_EXIT (result.array != NULL); ++ TEST_VERIFY (result.length == 1); ++ TEST_VERIFY (result.array[0] == 23); ++ free (result.array); ++ ++ for (int i = 0; i < count; ++i) ++ { ++ long *place = dynarray_long_noscratch_emplace (&dyn); ++ TEST_VERIFY_EXIT (place != NULL); ++ TEST_VERIFY (*place == 23); ++ if (i == 0) ++ *place = 29; ++ } ++ TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 29); ++ for (int i = 1; i < count; ++i) ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23); ++ TEST_VERIFY_EXIT (dynarray_long_noscratch_finalize (&dyn, &result)); ++ TEST_VERIFY_EXIT (result.array != NULL); ++ TEST_VERIFY (result.length == count); ++ TEST_VERIFY (result.array[0] == 29); ++ for (int i = 1; i < count; ++i) ++ TEST_VERIFY (result.array[i] == 23); ++ free (result.array); ++ ++ TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1)); ++ TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23); ++ *dynarray_long_noscratch_at (&dyn, 0) = 24; ++ dynarray_long_noscratch_free (&dyn); ++ TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 1)); ++ TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 1); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23); ++ TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, 2)); ++ TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == 2); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 23); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 1) == 23); ++ *dynarray_long_noscratch_at (&dyn, 0) = 24; ++ TEST_VERIFY (dynarray_long_noscratch_resize (&dyn, count)); ++ TEST_VERIFY (dynarray_long_noscratch_size (&dyn) == count); ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, 0) == 24); ++ for (int i = 1; i < count; ++i) ++ TEST_VERIFY (*dynarray_long_noscratch_at (&dyn, i) == 23); ++ dynarray_long_noscratch_free (&dyn); ++ } ++} ++ ++/* Test overflow in resize. */ ++static void ++test_long_overflow (void) ++{ ++ { ++ struct dynarray_long dyn; ++ dynarray_long_init (&dyn); ++ errno = EINVAL; ++ TEST_VERIFY (!dynarray_long_resize ++ (&dyn, (SIZE_MAX / sizeof (long)) + 1)); ++ TEST_VERIFY (errno == ENOMEM); ++ TEST_VERIFY (dynarray_long_has_failed (&dyn)); ++ } ++ ++ { ++ struct dynarray_long_noscratch dyn; ++ dynarray_long_noscratch_init (&dyn); ++ errno = EINVAL; ++ TEST_VERIFY (!dynarray_long_noscratch_resize ++ (&dyn, (SIZE_MAX / sizeof (long)) + 1)); ++ TEST_VERIFY (errno == ENOMEM); ++ TEST_VERIFY (dynarray_long_noscratch_has_failed (&dyn)); ++ } ++} ++ ++/* Test NUL-terminated string construction with the add function and ++ the simple finalize function. */ ++static void ++test_zstr (void) ++{ ++ /* Totally empty string (no NUL termination). */ ++ { ++ struct zstr s; ++ zstr_init (&s); ++ char *result = zstr_finalize (&s, NULL); ++ TEST_VERIFY (result == NULL); ++ TEST_VERIFY (zstr_size (&s) == 0); ++ size_t length = 1; ++ result = zstr_finalize (&s, &length); ++ TEST_VERIFY (result == NULL); ++ TEST_VERIFY (length == 0); ++ TEST_VERIFY (zstr_size (&s) == 0); ++ } ++ ++ /* Empty string. */ ++ { ++ struct zstr s; ++ zstr_init (&s); ++ zstr_add (&s, '\0'); ++ char *result = zstr_finalize (&s, NULL); ++ TEST_VERIFY_EXIT (result != NULL); ++ TEST_VERIFY (*result == '\0'); ++ TEST_VERIFY (zstr_size (&s) == 0); ++ free (result); ++ ++ zstr_add (&s, '\0'); ++ size_t length = 1; ++ result = zstr_finalize (&s, &length); ++ TEST_VERIFY_EXIT (result != NULL); ++ TEST_VERIFY (*result == '\0'); ++ TEST_VERIFY (length == 1); ++ TEST_VERIFY (zstr_size (&s) == 0); ++ free (result); ++ } ++ ++ /* A few characters. */ ++ { ++ struct zstr s; ++ zstr_init (&s); ++ zstr_add (&s, 'A'); ++ zstr_add (&s, 'b'); ++ zstr_add (&s, 'c'); ++ zstr_add (&s, '\0'); ++ char *result = zstr_finalize (&s, NULL); ++ TEST_VERIFY_EXIT (result != NULL); ++ TEST_VERIFY (strcmp (result, "Abc") == 0); ++ TEST_VERIFY (zstr_size (&s) == 0); ++ free (result); ++ ++ zstr_add (&s, 'X'); ++ zstr_add (&s, 'y'); ++ zstr_add (&s, 'z'); ++ zstr_add (&s, '\0'); ++ size_t length = 1; ++ result = zstr_finalize (&s, &length); ++ TEST_VERIFY_EXIT (result != NULL); ++ TEST_VERIFY (strcmp (result, "Xyz") == 0); ++ TEST_VERIFY (length == 4); ++ TEST_VERIFY (zstr_size (&s) == 0); ++ free (result); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ test_int (); ++ test_str (); ++ test_long_init (); ++ test_long_overflow (); ++ test_zstr (); ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh677316-fgets_unlocked.patch b/SOURCES/glibc-rh677316-fgets_unlocked.patch new file mode 100644 index 00000000..802d9554 --- /dev/null +++ b/SOURCES/glibc-rh677316-fgets_unlocked.patch @@ -0,0 +1,83 @@ +Partial backport of: + +commit c4eae75271734f820a7477dbce33f8752af6f003 +Author: Joseph Myers +Date: Wed Nov 12 22:39:36 2014 +0000 + + Fix __get_nprocs fgets_unlocked namespace (bug 17582). + +(alpha part is missing) + +diff --git a/include/stdio.h b/include/stdio.h +index 53a2c58ab0c7d7be..cc1908ef0566cea9 100644 +--- a/include/stdio.h ++++ b/include/stdio.h +@@ -151,6 +151,8 @@ libc_hidden_proto (fflush_unlocked) + libc_hidden_proto (fread_unlocked) + libc_hidden_proto (fwrite_unlocked) + libc_hidden_proto (fgets_unlocked) ++extern __typeof (fgets_unlocked) __fgets_unlocked; ++libc_hidden_proto (__fgets_unlocked) + libc_hidden_proto (fputs_unlocked) + libc_hidden_proto (fmemopen) + libc_hidden_proto (open_memstream) +diff --git a/libio/iofgets.c b/libio/iofgets.c +index 984cb86103b13c0f..3621f1c00ec9ea4d 100644 +--- a/libio/iofgets.c ++++ b/libio/iofgets.c +@@ -73,6 +73,8 @@ _IO_fgets (buf, n, fp) + weak_alias (_IO_fgets, fgets) + + # ifndef _IO_MTSAFE_IO ++strong_alias (_IO_fgets, __fgets_unlocked) ++libc_hidden_def (__fgets_unlocked) + weak_alias (_IO_fgets, fgets_unlocked) + libc_hidden_weak (fgets_unlocked) + # endif +diff --git a/libio/iofgets_u.c b/libio/iofgets_u.c +index e524943a54ba107a..e2cf6373b8178097 100644 +--- a/libio/iofgets_u.c ++++ b/libio/iofgets_u.c +@@ -28,7 +28,7 @@ + #include + + char * +-fgets_unlocked (buf, n, fp) ++__fgets_unlocked (buf, n, fp) + char *buf; + int n; + _IO_FILE *fp; +@@ -66,4 +66,6 @@ fgets_unlocked (buf, n, fp) + fp->_IO_file_flags |= old_error; + return result; + } +-libc_hidden_def (fgets_unlocked) ++libc_hidden_def (__fgets_unlocked) ++weak_alias (__fgets_unlocked, fgets_unlocked) ++libc_hidden_weak (fgets_unlocked) +diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c +index 22285f39f33bf26c..9082b1a7ab29a9f9 100644 +--- a/sysdeps/unix/sysv/linux/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/getsysstats.c +@@ -304,7 +304,7 @@ phys_pages_info (const char *format) + string "processor". We don't have to fear extremely long + lines since the kernel will not generate them. 8192 + bytes are really enough. */ +- while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL) ++ while (__fgets_unlocked (buffer, sizeof buffer, fp) != NULL) + if (sscanf (buffer, format, &result) == 1) + { + result /= (__getpagesize () / 1024); +diff --git a/sysdeps/unix/sysv/linux/sparc/getsysstats.c b/sysdeps/unix/sysv/linux/sparc/getsysstats.c +index 57d9b95223c6ab33..ceb8a2ba1f9cc9d5 100644 +--- a/sysdeps/unix/sysv/linux/sparc/getsysstats.c ++++ b/sysdeps/unix/sysv/linux/sparc/getsysstats.c +@@ -46,7 +46,7 @@ + probed cpus. We don't have to fear extremely long lines since \ + the kernel will not generate them. 8192 bytes are really \ + enough. */ \ +- while (fgets_unlocked ((BUFFER), sizeof (BUFFER), (FP)) != NULL) \ ++ while (__fgets_unlocked ((BUFFER), sizeof (BUFFER), (FP)) != NULL) \ + if (sscanf (buffer, "ncpus probed : %d", &(RESULT)) == 1) \ + break; \ + } \ diff --git a/SOURCES/glibc-rh677316-h_errno.patch b/SOURCES/glibc-rh677316-h_errno.patch new file mode 100644 index 00000000..a47adf84 --- /dev/null +++ b/SOURCES/glibc-rh677316-h_errno.patch @@ -0,0 +1,70 @@ +Partial backport of this upstream commit: + +commit 9acacaa02f3b75fddc07a56f3d848df45281a5de +Author: Joseph Myers +Date: Fri Jun 12 10:10:18 2015 +0000 + + Fix h_errno namespace (bug 18520). + +The linknamespace test changes in conform/Makefile are not included here +because glibc 2.17 did not have these tests. + +diff --git a/include/netdb.h b/include/netdb.h +index b6d7b90bbf8abd2e..6a6dca9ef57aaa37 100644 +--- a/include/netdb.h ++++ b/include/netdb.h +@@ -8,7 +8,7 @@ + # if IS_IN (libc) + # define h_errno __libc_h_errno + # else +-# define h_errno h_errno /* For #ifndef h_errno tests. */ ++# define h_errno __h_errno + # endif + extern __thread int h_errno attribute_tls_model_ie; + # endif /* IS_IN_LIB */ +diff --git a/inet/herrno.c b/inet/herrno.c +index 1802d0e00563839a..0cd84445190728b3 100644 +--- a/inet/herrno.c ++++ b/inet/herrno.c +@@ -24,7 +24,7 @@ + /* We need to have the error status variable of the resolver + accessible in the libc. */ + +-__thread int h_errno; +-extern __thread int __libc_h_errno __attribute__ ((alias ("h_errno"))) ++__thread int __h_errno; ++extern __thread int __libc_h_errno __attribute__ ((alias ("__h_errno"))) + attribute_hidden; + #define h_errno __libc_h_errno +diff --git a/nptl/herrno.c b/nptl/herrno.c +index c0488e4f6754873f..5056e3df88211123 100644 +--- a/nptl/herrno.c ++++ b/nptl/herrno.c +@@ -23,12 +23,12 @@ + + /* We need to have the error status variable of the resolver + accessible in the libc. */ +-extern __thread int h_errno; ++extern __thread int __h_errno; + + + /* When threaded, h_errno may be a per-thread variable. */ + int * + __h_errno_location (void) + { +- return &h_errno; ++ return &__h_errno; + } +diff --git a/resolv/Versions b/resolv/Versions +index 93faf1e2f5faac79..152ef3f68f9a8b48 100644 +--- a/resolv/Versions ++++ b/resolv/Versions +@@ -26,7 +26,7 @@ libc { + GLIBC_PRIVATE { + __gai_sigqueue; + +- h_errno; __resp; ++ __h_errno; __resp; + + __res_maybe_init; __res_iclose; + } diff --git a/SOURCES/glibc-rh677316-hesiod.patch b/SOURCES/glibc-rh677316-hesiod.patch new file mode 100644 index 00000000..c8d1a32a --- /dev/null +++ b/SOURCES/glibc-rh677316-hesiod.patch @@ -0,0 +1,575 @@ +This backports the hesiod subdirectory up to and including these +upstream commits: + +commit bfff8b1becd7d01c074177df7196ab327cd8c844 +Author: Joseph Myers +Date: Sun Jan 1 00:14:16 2017 +0000 + + Update copyright dates with scripts/update-copyrights. + +commit 8a03ccbb77f52ec4b55062eeedddb8daec1a33e4 +Author: Florian Weimer +Date: Mon May 2 16:04:32 2016 +0200 + + hesiod: Avoid heap overflow in get_txt_records [BZ #20031] + +It is required to eliminate a dependency on resolver internals. + +diff --git a/hesiod/Makefile b/hesiod/Makefile +index 5aeb86eaf8971535..3c967441e17240b4 100644 +--- a/hesiod/Makefile ++++ b/hesiod/Makefile +@@ -1,4 +1,4 @@ +-# Copyright (C) 1997, 1998, 2000, 2001, 2012 Free Software Foundation, Inc. ++# Copyright (C) 1997-2017 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -20,13 +20,15 @@ + # + subdir := hesiod + ++include ../Makeconfig ++ + extra-libs := libnss_hesiod + extra-libs-others = $(extra-libs) + + subdir-dirs = nss_hesiod + vpath %.c nss_hesiod + +-libnss_hesiod-routines := hesiod hesiod-grp hesiod-init hesiod-proto \ ++libnss_hesiod-routines := hesiod hesiod-grp hesiod-proto \ + hesiod-pwd hesiod-service + # Build only shared library + libnss_hesiod-inhibit-o = $(filter-out .os,$(object-suffixes)) +diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c +index 657dabebc144db7d..9b54d1cb6b18f0e5 100644 +--- a/hesiod/hesiod.c ++++ b/hesiod/hesiod.c +@@ -1,6 +1,19 @@ +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie Exp $"; +-#endif ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ + + /* + * Copyright (c) 1996,1999 by Internet Software Consortium. +@@ -46,24 +59,14 @@ static const char rcsid[] = "$BINDId: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie + + #include "hesiod.h" + #include "hesiod_p.h" +-#undef DEF_RHS + + #define _PATH_HESIOD_CONF "/etc/hesiod.conf" + + /* Forward */ + +-int hesiod_init(void **context); +-void hesiod_end(void *context); +-char * hesiod_to_bind(void *context, const char *name, +- const char *type); +-char ** hesiod_resolve(void *context, const char *name, +- const char *type); +-void hesiod_free_list(void *context, char **list); +- + static int parse_config_file(struct hesiod_p *ctx, const char *filename); + static char ** get_txt_records(struct hesiod_p *ctx, int class, + const char *name); +-static int init(struct hesiod_p *ctx); + + /* Public */ + +@@ -82,7 +85,6 @@ hesiod_init(void **context) { + + ctx->LHS = NULL; + ctx->RHS = NULL; +- ctx->res = NULL; + /* Set default query classes. */ + ctx->classes[0] = C_IN; + ctx->classes[1] = C_HS; +@@ -91,19 +93,7 @@ hesiod_init(void **context) { + if (!configname) + configname = _PATH_HESIOD_CONF; + if (parse_config_file(ctx, configname) < 0) { +-#ifdef DEF_RHS +- /* +- * Use compiled in defaults. +- */ +- ctx->LHS = malloc(strlen(DEF_LHS)+1); +- ctx->RHS = malloc(strlen(DEF_RHS)+1); +- if (ctx->LHS == 0 || ctx->RHS == 0) +- goto cleanup; +- strcpy(ctx->LHS, DEF_LHS); +- strcpy(ctx->RHS, DEF_RHS); +-#else + goto cleanup; +-#endif + } + /* + * The default RHS can be overridden by an environment +@@ -131,11 +121,6 @@ hesiod_init(void **context) { + goto cleanup; + } + +-#if 0 +- if (res_ninit(ctx->res) < 0) +- goto cleanup; +-#endif +- + *context = ctx; + return (0); + +@@ -152,12 +137,8 @@ hesiod_end(void *context) { + struct hesiod_p *ctx = (struct hesiod_p *) context; + int save_errno = errno; + +- if (ctx->res) +- res_nclose(ctx->res); + free(ctx->RHS); + free(ctx->LHS); +- if (ctx->res && ctx->free_res) +- (*ctx->free_res)(ctx->res); + free(ctx); + __set_errno(save_errno); + } +@@ -232,10 +213,6 @@ hesiod_resolve(void *context, const char *name, const char *type) { + + if (bindname == NULL) + return (NULL); +- if (init(ctx) == -1) { +- free(bindname); +- return (NULL); +- } + + retvec = get_txt_records(ctx, ctx->classes[0], bindname); + +@@ -365,13 +342,13 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) { + /* + * Construct the query and send it. + */ +- n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0, ++ n = res_mkquery(QUERY, name, class, T_TXT, NULL, 0, + NULL, qbuf, MAX_HESRESP); + if (n < 0) { + __set_errno(EMSGSIZE); + return (NULL); + } +- n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP); ++ n = res_send(qbuf, n, abuf, MAX_HESRESP); + if (n < 0) { + __set_errno(ECONNREFUSED); + return (NULL); +@@ -421,7 +398,7 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) { + cp += INT16SZ + INT32SZ; /* skip the ttl, too */ + rr.dlen = ns_get16(cp); + cp += INT16SZ; +- if (cp + rr.dlen > eom) { ++ if (rr.dlen == 0 || cp + rr.dlen > eom) { + __set_errno(EMSGSIZE); + goto cleanup; + } +@@ -464,44 +441,3 @@ get_txt_records(struct hesiod_p *ctx, int class, const char *name) { + free(list); + return (NULL); + } +- +-struct __res_state * +-__hesiod_res_get(void *context) { +- struct hesiod_p *ctx = context; +- +- if (!ctx->res) { +- struct __res_state *res; +- res = (struct __res_state *)calloc(1, sizeof *res); +- if (res == NULL) +- return (NULL); +- __hesiod_res_set(ctx, res, free); +- } +- +- return (ctx->res); +-} +- +-void +-__hesiod_res_set(void *context, struct __res_state *res, +- void (*free_res)(void *)) { +- struct hesiod_p *ctx = context; +- +- if (ctx->res && ctx->free_res) { +- res_nclose(ctx->res); +- (*ctx->free_res)(ctx->res); +- } +- +- ctx->res = res; +- ctx->free_res = free_res; +-} +- +-static int +-init(struct hesiod_p *ctx) { +- +- if (!ctx->res && !__hesiod_res_get(ctx)) +- return (-1); +- +- if (__res_maybe_init (ctx->res, 0) == -1) +- return (-1); +- +- return (0); +-} +diff --git a/hesiod/hesiod.h b/hesiod/hesiod.h +index 82fce30764e15071..2cb640a7df668cab 100644 +--- a/hesiod/hesiod.h ++++ b/hesiod/hesiod.h +@@ -1,3 +1,20 @@ ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * +@@ -19,22 +36,15 @@ + * This file is primarily maintained by and . + */ + +-/* +- * $BINDId: hesiod.h,v 1.7 1999/01/08 19:22:45 vixie Exp $ +- */ +- + #ifndef _HESIOD_H_INCLUDED + #define _HESIOD_H_INCLUDED + +-int hesiod_init (void **context); +-void hesiod_end (void *context); ++int hesiod_init (void **context) attribute_hidden; ++void hesiod_end (void *context) attribute_hidden; + char * hesiod_to_bind (void *context, const char *name, +- const char *type); ++ const char *type) attribute_hidden; + char ** hesiod_resolve (void *context, const char *name, +- const char *type); +-void hesiod_free_list (void *context, char **list); +-struct __res_state * __hesiod_res_get (void *context); +-void __hesiod_res_set (void *context, struct __res_state *, +- void (*)(void *)); ++ const char *type) attribute_hidden; ++void hesiod_free_list (void *context, char **list) attribute_hidden; + + #endif /*_HESIOD_H_INCLUDED*/ +diff --git a/hesiod/hesiod_p.h b/hesiod/hesiod_p.h +index 5010d71bc91879c4..7ed70158d9ffc5cc 100644 +--- a/hesiod/hesiod_p.h ++++ b/hesiod/hesiod_p.h +@@ -1,3 +1,20 @@ ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * +@@ -20,27 +37,17 @@ + */ + + /* +- * $BINDId: hesiod_p.h,v 1.9 1999/01/08 19:24:39 vixie Exp $ +- */ +- +-/* + * hesiod_p.h -- private definitions for the hesiod library + */ + + #ifndef _HESIOD_P_H_INCLUDED + #define _HESIOD_P_H_INCLUDED + +-#define DEF_RHS ".Athena.MIT.EDU" /* Defaults if HESIOD_CONF */ + #define DEF_LHS ".ns" /* file is not */ + /* present. */ + struct hesiod_p { + char * LHS; /* normally ".ns" */ + char * RHS; /* AKA the default hesiod domain */ +- struct __res_state * res; /* resolver context */ +- void (*free_res)(void *); +- void (*res_set)(struct hesiod_p *, struct __res_state *, +- void (*)(void *)); +- struct __res_state * (*res_get)(struct hesiod_p *); + int classes[2]; /* The class search order. */ + }; + +diff --git a/hesiod/nss_hesiod/hesiod-grp.c b/hesiod/nss_hesiod/hesiod-grp.c +index 5c14554ce9fd647e..a04f5309453047e2 100644 +--- a/hesiod/nss_hesiod/hesiod-grp.c ++++ b/hesiod/nss_hesiod/hesiod-grp.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997, 1999, 2000, 2002 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis , 1997. + +@@ -26,8 +26,6 @@ + #include + #include + +-#include "nss_hesiod.h" +- + /* Get the declaration of the parser function. */ + #define ENTNAME grent + #define STRUCTURE group +@@ -58,8 +56,7 @@ lookup (const char *name, const char *type, struct group *grp, + size_t len; + int olderr = errno; + +- context = _nss_hesiod_init (); +- if (context == NULL) ++ if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); +@@ -179,8 +176,7 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start, + gid_t *groups = *groupsp; + int save_errno; + +- context = _nss_hesiod_init (); +- if (context == NULL) ++ if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, user, "grplist"); +@@ -191,33 +187,6 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start, + return errno == ENOENT ? NSS_STATUS_NOTFOUND : NSS_STATUS_UNAVAIL; + } + +- if (!internal_gid_in_list (groups, group, *start)) +- { +- if (__builtin_expect (*start == *size, 0)) +- { +- /* Need a bigger buffer. */ +- gid_t *newgroups; +- long int newsize; +- +- if (limit > 0 && *size == limit) +- /* We reached the maximum. */ +- goto done; +- +- if (limit <= 0) +- newsize = 2 * *size; +- else +- newsize = MIN (limit, 2 * *size); +- +- newgroups = realloc (groups, newsize * sizeof (*groups)); +- if (newgroups == NULL) +- goto done; +- *groupsp = groups = newgroups; +- *size = newsize; +- } +- +- groups[(*start)++] = group; +- } +- + save_errno = errno; + + p = *list; +@@ -254,7 +223,7 @@ _nss_hesiod_initgroups_dyn (const char *user, gid_t group, long int *start, + if (status == NSS_STATUS_SUCCESS + && !internal_gid_in_list (groups, group, *start)) + { +- if (__builtin_expect (*start == *size, 0)) ++ if (__glibc_unlikely (*start == *size)) + { + /* Need a bigger buffer. */ + gid_t *newgroups; +diff --git a/hesiod/nss_hesiod/hesiod-init.c b/hesiod/nss_hesiod/hesiod-init.c +deleted file mode 100644 +index 964987d0755425b5..0000000000000000 +--- a/hesiod/nss_hesiod/hesiod-init.c ++++ /dev/null +@@ -1,38 +0,0 @@ +-/* Copyright (C) 2000 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Mark Kettenis , 2000. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include /* Needs to come before . */ +-#include +-#include +-#include +- +-#include "nss_hesiod.h" +- +-void * +-_nss_hesiod_init (void) +-{ +- void *context; +- +- if (hesiod_init (&context) == -1) +- return NULL; +- +- /* Use the default (per-thread) resolver state. */ +- __hesiod_res_set (context, &_res, NULL); +- +- return context; +-} +diff --git a/hesiod/nss_hesiod/hesiod-proto.c b/hesiod/nss_hesiod/hesiod-proto.c +index 7ea38bc24fbff3ca..6af32aad35edfc0a 100644 +--- a/hesiod/nss_hesiod/hesiod-proto.c ++++ b/hesiod/nss_hesiod/hesiod-proto.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis , 1997. + +@@ -25,8 +25,6 @@ + #include + #include + +-#include "nss_hesiod.h" +- + /* Declare a parser for Hesiod protocol entries. Although the format + of the entries is identical to those in /etc/protocols, here is no + predefined parser for us to use. */ +@@ -68,8 +66,7 @@ lookup (const char *name, const char *type, struct protoent *proto, + int found; + int olderr = errno; + +- context = _nss_hesiod_init (); +- if (context == NULL) ++ if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); +diff --git a/hesiod/nss_hesiod/hesiod-pwd.c b/hesiod/nss_hesiod/hesiod-pwd.c +index 929cbce80e238a67..8309af245d3f0268 100644 +--- a/hesiod/nss_hesiod/hesiod-pwd.c ++++ b/hesiod/nss_hesiod/hesiod-pwd.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis , 1997. + +@@ -24,8 +24,6 @@ + #include + #include + +-#include "nss_hesiod.h" +- + /* Get the declaration of the parser function. */ + #define ENTNAME pwent + #define STRUCTURE passwd +@@ -56,8 +54,7 @@ lookup (const char *name, const char *type, struct passwd *pwd, + size_t len; + int olderr = errno; + +- context = _nss_hesiod_init (); +- if (context == NULL) ++ if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); +diff --git a/hesiod/nss_hesiod/hesiod-service.c b/hesiod/nss_hesiod/hesiod-service.c +index 28bd31a70f31c89c..1942188517d94508 100644 +--- a/hesiod/nss_hesiod/hesiod-service.c ++++ b/hesiod/nss_hesiod/hesiod-service.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Mark Kettenis , 1997. + +@@ -25,8 +25,6 @@ + #include + #include + +-#include "nss_hesiod.h" +- + /* Hesiod uses a format for service entries that differs from the + traditional format. We therefore declare our own parser. */ + +@@ -69,8 +67,7 @@ lookup (const char *name, const char *type, const char *protocol, + int found; + int olderr = errno; + +- context = _nss_hesiod_init (); +- if (context == NULL) ++ if (hesiod_init (&context) < 0) + return NSS_STATUS_UNAVAIL; + + list = hesiod_resolve (context, name, type); +diff --git a/hesiod/nss_hesiod/nss_hesiod.h b/hesiod/nss_hesiod/nss_hesiod.h +deleted file mode 100644 +index fdf0241860b7e825..0000000000000000 +--- a/hesiod/nss_hesiod/nss_hesiod.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-/* Copyright (C) 2000 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Mark Kettenis , 2000. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* Initialize a Hesiod context. */ +-extern void *_nss_hesiod_init (void); diff --git a/SOURCES/glibc-rh677316-in6addr_any.patch b/SOURCES/glibc-rh677316-in6addr_any.patch new file mode 100644 index 00000000..8b6ccecf --- /dev/null +++ b/SOURCES/glibc-rh677316-in6addr_any.patch @@ -0,0 +1,62 @@ +Partial backport of: + +commit 17c199ee92e4ca8a34a47c42924608a25a444eb2 +Author: Joseph Myers +Date: Wed Jun 17 20:08:22 2015 +0000 + + Fix gethostbyaddr in6addr_any, in6addr_loopback namespace (bug 18532). + +The conform/Makefile changes have been omitted because glibc 2.17 did +not have linknamespace tests. + +diff --git a/include/netinet/in.h b/include/netinet/in.h +index 6fb5c86de999ba82..5e377469e782a5b1 100644 +--- a/include/netinet/in.h ++++ b/include/netinet/in.h +@@ -5,7 +5,11 @@ + #ifndef _ISOMAC + libc_hidden_proto (bindresvport) + libc_hidden_proto (in6addr_loopback) ++extern __typeof (in6addr_loopback) __in6addr_loopback; ++libc_hidden_proto (__in6addr_loopback) + libc_hidden_proto (in6addr_any) ++extern __typeof (in6addr_any) __in6addr_any; ++libc_hidden_proto (__in6addr_any) + #endif + + #endif +diff --git a/inet/gethstbyad_r.c b/inet/gethstbyad_r.c +index d8e4988a312a0799..5ae854b4f91e72ad 100644 +--- a/inet/gethstbyad_r.c ++++ b/inet/gethstbyad_r.c +@@ -32,7 +32,7 @@ + be performed. */ + #define PREPROCESS \ + if (len == sizeof (struct in6_addr) \ +- && __builtin_expect (memcmp (&in6addr_any, addr, \ ++ && __builtin_expect (memcmp (&__in6addr_any, addr, \ + sizeof (struct in6_addr)), 1) == 0) \ + { \ + *h_errnop = HOST_NOT_FOUND; \ +diff --git a/inet/in6_addr.c b/inet/in6_addr.c +index 558b375e46dc62dc..03fbb85803e3d0b7 100644 +--- a/inet/in6_addr.c ++++ b/inet/in6_addr.c +@@ -18,9 +18,13 @@ + + #include + +-const struct in6_addr in6addr_any = ++const struct in6_addr __in6addr_any = + { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }; +-libc_hidden_data_def (in6addr_any) +-const struct in6_addr in6addr_loopback = ++libc_hidden_data_def (__in6addr_any) ++weak_alias (__in6addr_any, in6addr_any) ++libc_hidden_data_weak (in6addr_any) ++const struct in6_addr __in6addr_loopback = + { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }; +-libc_hidden_data_def (in6addr_loopback) ++libc_hidden_data_def (__in6addr_loopback) ++weak_alias (__in6addr_loopback, in6addr_loopback) ++libc_hidden_data_weak (in6addr_loopback) diff --git a/SOURCES/glibc-rh677316-inet_pton-zeros.patch b/SOURCES/glibc-rh677316-inet_pton-zeros.patch new file mode 100644 index 00000000..382b6bed --- /dev/null +++ b/SOURCES/glibc-rh677316-inet_pton-zeros.patch @@ -0,0 +1,116 @@ +Revert this upstream commit: + +commit 9a0cc8c1bd7645bf3c988890ffb59639c07a5812 +Author: Florian Weimer +Date: Fri Jun 23 22:51:00 2017 +0200 + + inet_pton: Reject IPv6 addresses with many leading zeros [BZ #16637] + + 2001:db8:00001::f is not a valid IPv6 address according to RFC 2373. + +We do not want this behavioral change in Red Hat Enterprise Linux 7. +See rhbz#1484034 for some discussion. + +diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c +index 16ee33e0c0dfb015..b95da47c17ef8afc 100644 +--- a/resolv/inet_pton.c ++++ b/resolv/inet_pton.c +@@ -144,8 +144,7 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst) + { + unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *curtok; +- int ch; +- size_t xdigits_seen; /* Number of hex digits since colon. */ ++ int ch, saw_xdigit; + unsigned int val; + + tp = memset (tmp, '\0', NS_IN6ADDRSZ); +@@ -163,7 +162,7 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst) + } + + curtok = src; +- xdigits_seen = 0; ++ saw_xdigit = 0; + val = 0; + while (src < src_endp) + { +@@ -171,19 +170,17 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst) + int digit = hex_digit_value (ch); + if (digit >= 0) + { +- if (xdigits_seen == 4) +- return 0; + val <<= 4; + val |= digit; + if (val > 0xffff) + return 0; +- ++xdigits_seen; ++ saw_xdigit = 1; + continue; + } + if (ch == ':') + { + curtok = src; +- if (xdigits_seen == 0) ++ if (!saw_xdigit) + { + if (colonp) + return 0; +@@ -196,7 +193,7 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst) + return 0; + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; +- xdigits_seen = 0; ++ saw_xdigit = 0; + val = 0; + continue; + } +@@ -204,12 +201,12 @@ inet_pton6 (const char *src, const char *src_endp, unsigned char *dst) + && inet_pton4 (curtok, src_endp, tp) > 0) + { + tp += NS_INADDRSZ; +- xdigits_seen = 0; ++ saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4. */ + } + return 0; + } +- if (xdigits_seen > 0) ++ if (saw_xdigit) + { + if (tp + NS_INT16SZ > endp) + return 0; +diff --git a/resolv/tst-inet_pton.c b/resolv/tst-inet_pton.c +index 4bb9f8119378b467..7fffb24cdf9eb1f4 100644 +--- a/resolv/tst-inet_pton.c ++++ b/resolv/tst-inet_pton.c +@@ -226,7 +226,13 @@ const struct test_case test_cases[] = + }, + {.input = "2", }, + {.input = "2.", }, +- {.input = "2001:db8:00001::f", }, ++ {.input = "2001:db8:00001::f", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x1, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf ++ }, ++ }, + {.input = "2001:db8:10000::f", }, + {.input = "2001:db8:1234:5678:abcd:ef01:2345:67", + .ipv6_ok = true, +@@ -448,7 +454,13 @@ const struct test_case test_cases[] = + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + }, + }, +- {.input = "::00001", }, ++ {.input = "::00001", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1 ++ }, ++ }, + {.input = "::1", + .ipv6_ok = true, + .ipv6_expected = { diff --git a/SOURCES/glibc-rh677316-inet_pton.patch b/SOURCES/glibc-rh677316-inet_pton.patch new file mode 100644 index 00000000..646dc37d --- /dev/null +++ b/SOURCES/glibc-rh677316-inet_pton.patch @@ -0,0 +1,1613 @@ +Backport of + +inet/if_index.c +inet/inet6_scopeid_pton.c +inet/inet_mkadr.c +inet/tst-inet6_scopeid_pton.c +resolv/inet_pton.c +resolv/tst-inet_pton.c + +up to and including this upstream commit on the 2.26 branch: + +commit 77db8772bd3f6f2bbad697dcf46861ce310f5b95 +Author: Florian Weimer +Date: Thu Aug 10 16:06:52 2017 +0200 + + __inet6_scopeid_pton: Remove attribute_hidden, internal_function + +This change makes the inet_pton parser more strict for IPv6 addresses +(upstream bug 16637). The stricter __inet6_scopeid_pton parser is not +effective yet with this patch because it is not used by the library yet. + +diff --git a/include/arpa/inet.h b/include/arpa/inet.h +index 63ece7029aa1d417..c3f28f2baaa2ed66 100644 +--- a/include/arpa/inet.h ++++ b/include/arpa/inet.h +@@ -7,6 +7,9 @@ libc_hidden_proto (__inet_aton) + libc_hidden_proto (inet_aton) + libc_hidden_proto (inet_ntop) + libc_hidden_proto (inet_pton) +-libc_hidden_proto (inet_makeaddr) ++extern __typeof (inet_pton) __inet_pton; ++libc_hidden_proto (__inet_pton) ++extern __typeof (inet_makeaddr) __inet_makeaddr; ++libc_hidden_proto (__inet_makeaddr) + libc_hidden_proto (inet_netof) + #endif +diff --git a/include/net/if.h b/include/net/if.h +index 1d862260c7e83977..6c4cbc96c3733a01 100644 +--- a/include/net/if.h ++++ b/include/net/if.h +@@ -4,9 +4,13 @@ + + #ifndef _ISOMAC + libc_hidden_proto (if_nametoindex) ++extern __typeof (if_nametoindex) __if_nametoindex; ++libc_hidden_proto (__if_nametoindex) + libc_hidden_proto (if_indextoname) + libc_hidden_proto (if_nameindex) + libc_hidden_proto (if_freenameindex) ++extern __typeof (if_freenameindex) __if_freenameindex; ++libc_hidden_proto (__if_freenameindex) + #endif + + #endif +diff --git a/inet/Makefile b/inet/Makefile +index 768df21b92534a31..4abf2ddf6dfff327 100644 +--- a/inet/Makefile ++++ b/inet/Makefile +@@ -45,7 +45,7 @@ routines := htonl htons \ + in6_addr getnameinfo if_index ifaddrs inet6_option \ + getipv4sourcefilter setipv4sourcefilter \ + getsourcefilter setsourcefilter inet6_opt inet6_rth \ +- deadline ++ inet6_scopeid_pton deadline + + aux := check_pf check_native ifreq + +@@ -57,6 +57,10 @@ tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ + # internal functions. + tests-static += tst-deadline + ++# tst-inet6_scopeid_pton also needs internal functions but does not ++# need to be linked statically. ++tests += tst-inet6_scopeid_pton ++ + include ../Rules + + ifeq ($(have-thread-library),yes) +diff --git a/inet/Versions b/inet/Versions +index 06507199a92b3c51..157559c44442259e 100644 +--- a/inet/Versions ++++ b/inet/Versions +@@ -88,5 +88,8 @@ libc { + # functions used in other libraries + __internal_endnetgrent; __internal_getnetgrent_r; + __internal_setnetgrent; ++ ++ # Used from nscd. ++ __inet6_scopeid_pton; + } + } +diff --git a/inet/if_index.c b/inet/if_index.c +index 3d706766be62b91b..4604e0a35b890471 100644 +--- a/inet/if_index.c ++++ b/inet/if_index.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997,98,99,2000,02 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -20,44 +20,41 @@ + #include + + unsigned int +-if_nametoindex (const char *ifname) ++__if_nametoindex (const char *ifname) + { + __set_errno (ENOSYS); + return 0; + } +-libc_hidden_def (if_nametoindex) ++libc_hidden_def (__if_nametoindex) ++weak_alias (__if_nametoindex, if_nametoindex) ++libc_hidden_weak (if_nametoindex) + stub_warning (if_nametoindex) + + char * +-if_indextoname (unsigned int ifindex, char *ifname) ++__if_indextoname (unsigned int ifindex, char *ifname) + { + __set_errno (ENOSYS); + return NULL; + } +-libc_hidden_def (if_indextoname) ++weak_alias (__if_indextoname, if_indextoname) ++libc_hidden_weak (if_indextoname) + stub_warning (if_indextoname) + + void +-if_freenameindex (struct if_nameindex *ifn) ++__if_freenameindex (struct if_nameindex *ifn) + { + } ++libc_hidden_def (__if_freenameindex) ++weak_alias (__if_freenameindex, if_freenameindex) ++libc_hidden_weak (if_freenameindex) + stub_warning (if_freenameindex) + + struct if_nameindex * +-if_nameindex (void) ++__if_nameindex (void) + { + __set_errno (ENOSYS); + return NULL; + } ++weak_alias (__if_nameindex, if_nameindex) ++libc_hidden_weak (if_nameindex) + stub_warning (if_nameindex) +- +-#if 0 +-void +-internal_function +-__protocol_available (int *have_inet, int *have_inet6) +-{ +- /* By default we assume that IPv4 is available, IPv6 not. */ +- *have_inet = 1; +- *have_inet6 = 0; +-} +-#endif +diff --git a/inet/inet6_scopeid_pton.c b/inet/inet6_scopeid_pton.c +new file mode 100644 +index 0000000000000000..cc8803fa108f7bcb +--- /dev/null ++++ b/inet/inet6_scopeid_pton.c +@@ -0,0 +1,64 @@ ++/* Convert an IPv6 scope ID from text to the internal representation. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Parse SOURCE as a scope ID for ADDRESS. Return 0 on success and -1 ++ on error. */ ++int ++__inet6_scopeid_pton (const struct in6_addr *address, const char *scope, ++ uint32_t *result) ++{ ++ if (IN6_IS_ADDR_LINKLOCAL (address) ++ || IN6_IS_ADDR_MC_NODELOCAL (address) ++ || IN6_IS_ADDR_MC_LINKLOCAL (address)) ++ { ++ uint32_t number = __if_nametoindex (scope); ++ if (number != 0) ++ { ++ *result = number; ++ return 0; ++ } ++ } ++ ++ if (isdigit_l (scope[0], _nl_C_locobj_ptr)) ++ { ++ char *end; ++ unsigned long long number ++ = ____strtoull_l_internal (scope, &end, /*base */ 10, /* group */ 0, ++ _nl_C_locobj_ptr); ++ if (*end == '\0' && number <= UINT32_MAX) ++ { ++ *result = number; ++ return 0; ++ } ++ } ++ ++ __set_errno (EINVAL); ++ return -1; ++} ++ ++libc_hidden_def (__inet6_scopeid_pton) +diff --git a/inet/inet_mkadr.c b/inet/inet_mkadr.c +index d8d92da768b2ede0..88faef74cf50b722 100644 +--- a/inet/inet_mkadr.c ++++ b/inet/inet_mkadr.c +@@ -27,10 +27,6 @@ + * SUCH DAMAGE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +@@ -40,8 +36,7 @@ static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; + * building addresses stored in the ifnet structure. + */ + struct in_addr +-inet_makeaddr(net, host) +- in_addr_t net, host; ++__inet_makeaddr (in_addr_t net, in_addr_t host) + { + struct in_addr in; + +@@ -56,4 +51,5 @@ inet_makeaddr(net, host) + in.s_addr = htonl(in.s_addr); + return in; + } +-libc_hidden_def (inet_makeaddr) ++libc_hidden_def (__inet_makeaddr) ++weak_alias (__inet_makeaddr, inet_makeaddr) +diff --git a/inet/net-internal.h b/inet/net-internal.h +index 58349f54ea126698..6c666752493811be 100644 +--- a/inet/net-internal.h ++++ b/inet/net-internal.h +@@ -19,10 +19,15 @@ + #ifndef _NET_INTERNAL_H + #define _NET_INTERNAL_H 1 + ++#include + #include + #include + #include + ++int __inet6_scopeid_pton (const struct in6_addr *address, ++ const char *scope, uint32_t *result); ++libc_hidden_proto (__inet6_scopeid_pton) ++ + /* Deadline handling for enforcing timeouts. + + Code should call __deadline_current_time to obtain the current time +diff --git a/inet/tst-inet6_scopeid_pton.c b/inet/tst-inet6_scopeid_pton.c +new file mode 100644 +index 0000000000000000..8225b3b80abe6331 +--- /dev/null ++++ b/inet/tst-inet6_scopeid_pton.c +@@ -0,0 +1,230 @@ ++/* Tests for __inet6_scopeid_pton and IPv6 scopes in getaddrinfo. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* An interface which is known to the system. */ ++static const char *interface_name; ++static uint32_t interface_index; ++ ++/* Initiale the variables above. */ ++static void ++setup_interface (void) ++{ ++ struct if_nameindex *list = if_nameindex (); ++ if (list != NULL && list[0].if_index != 0 && list[0].if_name[0] != '\0') ++ { ++ interface_name = list[0].if_name; ++ interface_index = list[0].if_index; ++ } ++} ++ ++/* Convert ADDRESS to struct in6_addr. */ ++static struct in6_addr ++from_string (const char *address) ++{ ++ struct in6_addr addr; ++ if (inet_pton (AF_INET6, address, &addr) != 1) ++ FAIL_EXIT1 ("inet_pton (\"%s\")", address); ++ return addr; ++} ++ ++/* Invoke getaddrinfo to parse ADDRESS%SCOPE. Return true if ++ getaddrinfo was successful. */ ++static bool ++call_gai (int family, const char *address, const char *scope, ++ struct sockaddr_in6 *result) ++{ ++ struct addrinfo hints = ++ { ++ .ai_family = family, ++ .ai_flags = AI_NUMERICHOST, ++ .ai_socktype = SOCK_DGRAM, ++ .ai_protocol = IPPROTO_UDP, ++ }; ++ char *fulladdr = xasprintf ("%s%%%s", address, scope); ++ struct addrinfo *ai = NULL; ++ int ret = getaddrinfo (fulladdr, NULL, &hints, &ai); ++ if (ret == EAI_ADDRFAMILY || ret == EAI_NONAME) ++ { ++ if (test_verbose > 0) ++ printf ("info: getaddrinfo (\"%s\"): %s (%d)\n", ++ fulladdr, gai_strerror (ret), ret); ++ free (fulladdr); ++ return false; ++ } ++ if (ret != 0) ++ FAIL_EXIT1 ("getaddrinfo (\"%s\"): %s (%d)\n", ++ fulladdr, gai_strerror (ret), ret); ++ TEST_VERIFY_EXIT (ai != NULL); ++ TEST_VERIFY_EXIT (ai->ai_addrlen == sizeof (*result)); ++ TEST_VERIFY (ai->ai_family == AF_INET6); ++ TEST_VERIFY (ai->ai_next == NULL); ++ memcpy (result, ai->ai_addr, sizeof (*result)); ++ free (fulladdr); ++ freeaddrinfo (ai); ++ return true; ++} ++ ++/* Verify that a successful call to getaddrinfo returned the expected ++ scope data. */ ++static void ++check_ai (const char *what, const char *addr_string, const char *scope_string, ++ const struct sockaddr_in6 *sa, ++ const struct in6_addr *addr, uint32_t scope) ++{ ++ if (memcmp (addr, &sa->sin6_addr, sizeof (*addr)) != 0) ++ { ++ support_record_failure (); ++ printf ("error: getaddrinfo %s address mismatch for %s%%%s\n", ++ what, addr_string, scope_string); ++ } ++ if (sa->sin6_scope_id != scope) ++ { ++ support_record_failure (); ++ printf ("error: getaddrinfo %s scope mismatch for %s%%%s\n" ++ " expected: %" PRIu32 "\n" ++ " actual: %" PRIu32 "\n", ++ what, addr_string, scope_string, scope, sa->sin6_scope_id); ++ } ++} ++ ++/* Check a single address were we expected a failure. */ ++static void ++expect_failure (const char *address, const char *scope) ++{ ++ if (test_verbose > 0) ++ printf ("info: expecting failure for %s%%%s\n", address, scope); ++ struct in6_addr addr = from_string (address); ++ uint32_t result = 1234; ++ if (__inet6_scopeid_pton (&addr, scope, &result) == 0) ++ { ++ support_record_failure (); ++ printf ("error: unexpected success for %s%%%s\n", ++ address, scope); ++ } ++ if (result != 1234) ++ { ++ support_record_failure (); ++ printf ("error: unexpected result update for %s%%%s\n", ++ address, scope); ++ } ++ ++ struct sockaddr_in6 sa; ++ if (call_gai (AF_UNSPEC, address, scope, &sa)) ++ { ++ support_record_failure (); ++ printf ("error: unexpected getaddrinfo success for %s%%%s (AF_UNSPEC)\n", ++ address, scope); ++ } ++ if (call_gai (AF_INET6, address, scope, &sa)) ++ { ++ support_record_failure (); ++ printf ("error: unexpected getaddrinfo success for %s%%%s (AF_INET6)\n", ++ address, scope); ++ } ++} ++ ++/* Check a single address were we expected a success. */ ++static void ++expect_success (const char *address, const char *scope, uint32_t expected) ++{ ++ if (test_verbose > 0) ++ printf ("info: expecting success for %s%%%s\n", address, scope); ++ struct in6_addr addr = from_string (address); ++ uint32_t actual = expected + 1; ++ if (__inet6_scopeid_pton (&addr, scope, &actual) != 0) ++ { ++ support_record_failure (); ++ printf ("error: unexpected failure for %s%%%s\n", ++ address, scope); ++ } ++ if (actual != expected) ++ { ++ support_record_failure (); ++ printf ("error: unexpected result for for %s%%%s\n", ++ address, scope); ++ printf (" expected: %" PRIu32 "\n", expected); ++ printf (" actual: %" PRIu32 "\n", actual); ++ } ++ ++ struct sockaddr_in6 sa; ++ memset (&sa, 0xc0, sizeof (sa)); ++ if (call_gai (AF_UNSPEC, address, scope, &sa)) ++ check_ai ("AF_UNSPEC", address, scope, &sa, &addr, expected); ++ else ++ { ++ support_record_failure (); ++ printf ("error: unexpected getaddrinfo failure for %s%%%s (AF_UNSPEC)\n", ++ address, scope); ++ } ++ memset (&sa, 0xc0, sizeof (sa)); ++ if (call_gai (AF_INET6, address, scope, &sa)) ++ check_ai ("AF_INET6", address, scope, &sa, &addr, expected); ++ else ++ { ++ support_record_failure (); ++ printf ("error: unexpected getaddrinfo failure for %s%%%s (AF_INET6)\n", ++ address, scope); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ setup_interface (); ++ ++ static const char *test_addresses[] ++ = { "::", "::1", "2001:db8::1", NULL }; ++ for (int i = 0; test_addresses[i] != NULL; ++i) ++ { ++ expect_success (test_addresses[i], "0", 0); ++ expect_success (test_addresses[i], "5555", 5555); ++ ++ expect_failure (test_addresses[i], ""); ++ expect_failure (test_addresses[i], "-1"); ++ expect_failure (test_addresses[i], "-99"); ++ expect_failure (test_addresses[i], "037777777777"); ++ expect_failure (test_addresses[i], "0x"); ++ expect_failure (test_addresses[i], "0x1"); ++ } ++ ++ if (interface_name != NULL) ++ { ++ expect_success ("fe80::1", interface_name, interface_index); ++ expect_success ("ff02::1", interface_name, interface_index); ++ expect_success ("ff01::1", interface_name, interface_index); ++ expect_failure ("::", interface_name); ++ expect_failure ("::1", interface_name); ++ expect_failure ("2001:db8::1", interface_name); ++ } ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/Makefile b/resolv/Makefile +index a86646d4ef61b77d..3f525bcc75ee83ae 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -29,7 +29,7 @@ headers := resolv.h \ + routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ + res_hconf res_libc res-state + +-tests = tst-aton tst-leaks tst-inet_ntop ++tests = tst-aton tst-leaks tst-inet_ntop tst-inet_pton + xtests = tst-leaks2 + + generate := mtrace-tst-leaks tst-leaks.mtrace tst-leaks2.mtrace +diff --git a/resolv/Versions b/resolv/Versions +index 152ef3f68f9a8b48..24b07ef770ed3915 100644 +--- a/resolv/Versions ++++ b/resolv/Versions +@@ -29,6 +29,7 @@ libc { + __h_errno; __resp; + + __res_maybe_init; __res_iclose; ++ __inet_pton_length; + } + } + +diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c +index c507013e4ea9a90b..16ee33e0c0dfb015 100644 +--- a/resolv/inet_pton.c ++++ b/resolv/inet_pton.c +@@ -1,3 +1,20 @@ ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1996,1999 by Internet Software Consortium. + * +@@ -15,207 +32,203 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: inet_pton.c,v 1.7 1999/10/13 16:39:28 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- +-#include +-#include +-#include +-#include + #include + #include + #include +-#include + #include ++#include ++#include ++#include ++#include ++#include + +-/* +- * WARNING: Don't even consider trying to compile this on a system where +- * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. +- */ ++static int inet_pton4 (const char *src, const char *src_end, u_char *dst); ++static int inet_pton6 (const char *src, const char *src_end, u_char *dst); + +-static int inet_pton4 (const char *src, u_char *dst) internal_function; +-static int inet_pton6 (const char *src, u_char *dst) internal_function; +- +-/* int +- * inet_pton(af, src, dst) +- * convert from presentation format (which usually means ASCII printable) +- * to network format (which is usually some kind of binary format). +- * return: +- * 1 if the address was valid for the specified address family +- * 0 if the address wasn't valid (`dst' is untouched in this case) +- * -1 if some other error occurred (`dst' is untouched in this case, too) +- * author: +- * Paul Vixie, 1996. +- */ + int +-inet_pton(af, src, dst) +- int af; +- const char *src; +- void *dst; ++__inet_pton_length (int af, const char *src, size_t srclen, void *dst) + { +- switch (af) { +- case AF_INET: +- return (inet_pton4(src, dst)); +- case AF_INET6: +- return (inet_pton6(src, dst)); +- default: +- __set_errno (EAFNOSUPPORT); +- return (-1); +- } +- /* NOTREACHED */ ++ switch (af) ++ { ++ case AF_INET: ++ return inet_pton4 (src, src + srclen, dst); ++ case AF_INET6: ++ return inet_pton6 (src, src + srclen, dst); ++ default: ++ __set_errno (EAFNOSUPPORT); ++ return -1; ++ } + } +-libc_hidden_def (inet_pton) +- +-/* int +- * inet_pton4(src, dst) +- * like inet_aton() but without all the hexadecimal, octal (with the +- * exception of 0) and shorthand. +- * return: +- * 1 if `src' is a valid dotted quad, else 0. +- * notice: +- * does not touch `dst' unless it's returning 1. +- * author: +- * Paul Vixie, 1996. +- */ ++libc_hidden_def (__inet_pton_length) ++ ++/* Like __inet_pton_length, but use strlen (SRC) as the length of ++ SRC. */ ++int ++__inet_pton (int af, const char *src, void *dst) ++{ ++ return __inet_pton_length (af, src, strlen (src), dst); ++} ++libc_hidden_def (__inet_pton) ++weak_alias (__inet_pton, inet_pton) ++libc_hidden_weak (inet_pton) ++ ++/* Like inet_aton but without all the hexadecimal, octal and shorthand ++ (and trailing garbage is not ignored). Return 1 if SRC is a valid ++ dotted quad, else 0. This function does not touch DST unless it's ++ returning 1. ++ Author: Paul Vixie, 1996. */ + static int +-internal_function +-inet_pton4(src, dst) +- const char *src; +- u_char *dst; ++inet_pton4 (const char *src, const char *end, unsigned char *dst) + { +- int saw_digit, octets, ch; +- u_char tmp[NS_INADDRSZ], *tp; +- +- saw_digit = 0; +- octets = 0; +- *(tp = tmp) = 0; +- while ((ch = *src++) != '\0') { +- +- if (ch >= '0' && ch <= '9') { +- u_int new = *tp * 10 + (ch - '0'); +- +- if (saw_digit && *tp == 0) +- return (0); +- if (new > 255) +- return (0); +- *tp = new; +- if (! saw_digit) { +- if (++octets > 4) +- return (0); +- saw_digit = 1; +- } +- } else if (ch == '.' && saw_digit) { +- if (octets == 4) +- return (0); +- *++tp = 0; +- saw_digit = 0; +- } else +- return (0); +- } +- if (octets < 4) +- return (0); +- memcpy(dst, tmp, NS_INADDRSZ); +- return (1); ++ int saw_digit, octets, ch; ++ unsigned char tmp[NS_INADDRSZ], *tp; ++ ++ saw_digit = 0; ++ octets = 0; ++ *(tp = tmp) = 0; ++ while (src < end) ++ { ++ ch = *src++; ++ if (ch >= '0' && ch <= '9') ++ { ++ unsigned int new = *tp * 10 + (ch - '0'); ++ ++ if (saw_digit && *tp == 0) ++ return 0; ++ if (new > 255) ++ return 0; ++ *tp = new; ++ if (! saw_digit) ++ { ++ if (++octets > 4) ++ return 0; ++ saw_digit = 1; ++ } ++ } ++ else if (ch == '.' && saw_digit) ++ { ++ if (octets == 4) ++ return 0; ++ *++tp = 0; ++ saw_digit = 0; ++ } ++ else ++ return 0; ++ } ++ if (octets < 4) ++ return 0; ++ memcpy (dst, tmp, NS_INADDRSZ); ++ return 1; + } + +-/* int +- * inet_pton6(src, dst) +- * convert presentation level address to network order binary form. +- * return: +- * 1 if `src' is a valid [RFC1884 2.2] address, else 0. +- * notice: +- * (1) does not touch `dst' unless it's returning 1. +- * (2) :: in a full address is silently ignored. +- * credit: +- * inspired by Mark Andrews. +- * author: +- * Paul Vixie, 1996. +- */ ++/* Return the value of CH as a hexademical digit, or -1 if it is a ++ different type of character. */ ++static int ++hex_digit_value (char ch) ++{ ++ if ('0' <= ch && ch <= '9') ++ return ch - '0'; ++ if ('a' <= ch && ch <= 'f') ++ return ch - 'a' + 10; ++ if ('A' <= ch && ch <= 'F') ++ return ch - 'A' + 10; ++ return -1; ++} ++ ++/* Convert presentation-level IPv6 address to network order binary ++ form. Return 1 if SRC is a valid [RFC1884 2.2] address, else 0. ++ This function does not touch DST unless it's returning 1. ++ Author: Paul Vixie, 1996. Inspired by Mark Andrews. */ + static int +-internal_function +-inet_pton6(src, dst) +- const char *src; +- u_char *dst; ++inet_pton6 (const char *src, const char *src_endp, unsigned char *dst) + { +- static const char xdigits[] = "0123456789abcdef"; +- u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; +- const char *curtok; +- int ch, saw_xdigit; +- u_int val; +- +- tp = memset(tmp, '\0', NS_IN6ADDRSZ); +- endp = tp + NS_IN6ADDRSZ; +- colonp = NULL; +- /* Leading :: requires some special handling. */ +- if (*src == ':') +- if (*++src != ':') +- return (0); +- curtok = src; +- saw_xdigit = 0; +- val = 0; +- while ((ch = tolower (*src++)) != '\0') { +- const char *pch; +- +- pch = strchr(xdigits, ch); +- if (pch != NULL) { +- val <<= 4; +- val |= (pch - xdigits); +- if (val > 0xffff) +- return (0); +- saw_xdigit = 1; +- continue; +- } +- if (ch == ':') { +- curtok = src; +- if (!saw_xdigit) { +- if (colonp) +- return (0); +- colonp = tp; +- continue; +- } else if (*src == '\0') { +- return (0); +- } +- if (tp + NS_INT16SZ > endp) +- return (0); +- *tp++ = (u_char) (val >> 8) & 0xff; +- *tp++ = (u_char) val & 0xff; +- saw_xdigit = 0; +- val = 0; +- continue; +- } +- if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && +- inet_pton4(curtok, tp) > 0) { +- tp += NS_INADDRSZ; +- saw_xdigit = 0; +- break; /* '\0' was seen by inet_pton4(). */ +- } +- return (0); ++ unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; ++ const char *curtok; ++ int ch; ++ size_t xdigits_seen; /* Number of hex digits since colon. */ ++ unsigned int val; ++ ++ tp = memset (tmp, '\0', NS_IN6ADDRSZ); ++ endp = tp + NS_IN6ADDRSZ; ++ colonp = NULL; ++ ++ /* Leading :: requires some special handling. */ ++ if (src == src_endp) ++ return 0; ++ if (*src == ':') ++ { ++ ++src; ++ if (src == src_endp || *src != ':') ++ return 0; ++ } ++ ++ curtok = src; ++ xdigits_seen = 0; ++ val = 0; ++ while (src < src_endp) ++ { ++ ch = *src++; ++ int digit = hex_digit_value (ch); ++ if (digit >= 0) ++ { ++ if (xdigits_seen == 4) ++ return 0; ++ val <<= 4; ++ val |= digit; ++ if (val > 0xffff) ++ return 0; ++ ++xdigits_seen; ++ continue; + } +- if (saw_xdigit) { +- if (tp + NS_INT16SZ > endp) +- return (0); +- *tp++ = (u_char) (val >> 8) & 0xff; +- *tp++ = (u_char) val & 0xff; ++ if (ch == ':') ++ { ++ curtok = src; ++ if (xdigits_seen == 0) ++ { ++ if (colonp) ++ return 0; ++ colonp = tp; ++ continue; ++ } ++ else if (src == src_endp) ++ return 0; ++ if (tp + NS_INT16SZ > endp) ++ return 0; ++ *tp++ = (unsigned char) (val >> 8) & 0xff; ++ *tp++ = (unsigned char) val & 0xff; ++ xdigits_seen = 0; ++ val = 0; ++ continue; + } +- if (colonp != NULL) { +- /* +- * Since some memmove()'s erroneously fail to handle +- * overlapping regions, we'll do the shift by hand. +- */ +- const int n = tp - colonp; +- int i; +- +- if (tp == endp) +- return (0); +- for (i = 1; i <= n; i++) { +- endp[- i] = colonp[n - i]; +- colonp[n - i] = 0; +- } +- tp = endp; ++ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) ++ && inet_pton4 (curtok, src_endp, tp) > 0) ++ { ++ tp += NS_INADDRSZ; ++ xdigits_seen = 0; ++ break; /* '\0' was seen by inet_pton4. */ + } +- if (tp != endp) +- return (0); +- memcpy(dst, tmp, NS_IN6ADDRSZ); +- return (1); ++ return 0; ++ } ++ if (xdigits_seen > 0) ++ { ++ if (tp + NS_INT16SZ > endp) ++ return 0; ++ *tp++ = (unsigned char) (val >> 8) & 0xff; ++ *tp++ = (unsigned char) val & 0xff; ++ } ++ if (colonp != NULL) ++ { ++ /* Replace :: with zeros. */ ++ if (tp == endp) ++ /* :: would expand to a zero-width field. */ ++ return 0; ++ size_t n = tp - colonp; ++ memmove (endp - n, colonp, n); ++ memset (colonp, 0, endp - n - colonp); ++ tp = endp; ++ } ++ if (tp != endp) ++ return 0; ++ memcpy (dst, tmp, NS_IN6ADDRSZ); ++ return 1; + } +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +index 269758c416544cb4..a9f5659dbbacb477 100644 +--- a/resolv/resolv-internal.h ++++ b/resolv/resolv-internal.h +@@ -32,4 +32,13 @@ res_use_inet6 (void) + return _res.options & DEPRECATED_RES_USE_INET6; + } + ++/* Convert from presentation format (which usually means ASCII ++ printable) to network format (which is usually some kind of binary ++ format). The input is in the range [SRC, SRC + SRCLEN). The ++ output is written to DST (which has to be 4 or 16 bytes long, ++ depending on AF). Return 0 for invalid input, 1 for success, -1 ++ for an invalid address family. */ ++int __inet_pton_length (int af, const char *src, size_t srclen, void *); ++libc_hidden_proto (__inet_pton_length) ++ + #endif /* _RESOLV_INTERNAL_H */ +diff --git a/resolv/tst-inet_pton.c b/resolv/tst-inet_pton.c +new file mode 100644 +index 0000000000000000..4bb9f8119378b467 +--- /dev/null ++++ b/resolv/tst-inet_pton.c +@@ -0,0 +1,537 @@ ++/* Test inet_pton functions. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Memory region created by next_to_fault_allocate. */ ++struct next_to_fault ++{ ++ /* The user data. */ ++ char *buffer; ++ size_t length; ++ ++ /* The entire allocated region. */ ++ void *region_start; ++ size_t region_size; ++}; ++ ++/* Allocate a buffer of SIZE bytes just before a page which is mapped ++ with PROT_NONE (so that overrunning the buffer will cause a ++ fault). */ ++static struct next_to_fault ++next_to_fault_allocate (size_t size) ++{ ++ long page_size = sysconf (_SC_PAGE_SIZE); ++ TEST_VERIFY_EXIT (page_size > 0); ++ struct next_to_fault result; ++ result.region_size = roundup (size, page_size) + page_size; ++ TEST_VERIFY_EXIT (size + page_size > size); ++ TEST_VERIFY_EXIT (result.region_size > size); ++ result.region_start ++ = xmmap (NULL, result.region_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1); ++ /* Unmap the page after the allocation. */ ++ xmprotect (result.region_start + (result.region_size - page_size), ++ page_size, PROT_NONE); ++ /* Align the allocation within the region so that it ends just ++ before the PROT_NONE page. */ ++ result.buffer = result.region_start + result.region_size - page_size - size; ++ result.length = size; ++ return result; ++} ++ ++/* Deallocate the memory region allocated by ++ next_to_fault_allocate. */ ++static void ++next_to_fault_free (struct next_to_fault *ntf) ++{ ++ xmunmap (ntf->region_start, ntf->region_size); ++ *ntf = (struct next_to_fault) { NULL, }; ++} ++ ++struct test_case ++{ ++ /* The input data. */ ++ const char *input; ++ ++ /* True if AF_INET parses successfully. */ ++ bool ipv4_ok; ++ ++ /* True if AF_INET6 parses successfully. */ ++ bool ipv6_ok; ++ ++ /* Expected result for AF_INET. */ ++ unsigned char ipv4_expected[4]; ++ ++ /* Expected result for AF_INET6. */ ++ unsigned char ipv6_expected[16]; ++}; ++ ++static void ++check_result (const char *what, const struct test_case *t, int family, ++ void *result_buffer, int inet_ret) ++{ ++ TEST_VERIFY_EXIT (inet_ret >= -1); ++ TEST_VERIFY_EXIT (inet_ret <= 1); ++ ++ int ok; ++ const unsigned char *expected; ++ size_t result_size; ++ switch (family) ++ { ++ case AF_INET: ++ ok = t->ipv4_ok; ++ expected = t->ipv4_expected; ++ result_size = 4; ++ break; ++ case AF_INET6: ++ ok = t->ipv6_ok; ++ expected = t->ipv6_expected; ++ result_size = 16; ++ break; ++ default: ++ FAIL_EXIT1 ("invalid address family %d", family); ++ } ++ ++ if (inet_ret != ok) ++ { ++ support_record_failure (); ++ printf ("error: %s return value mismatch for [[%s]], family %d\n" ++ " expected: %d\n" ++ " actual: %d\n", ++ what, t->input, family, ok, inet_ret); ++ return; ++ } ++ if (memcmp (result_buffer, expected, result_size) != 0) ++ { ++ support_record_failure (); ++ printf ("error: %s result mismatch for [[%s]], family %d\n", ++ what, t->input, family); ++ } ++} ++ ++static void ++run_one_test (const struct test_case *t) ++{ ++ size_t test_len = strlen (t->input); ++ ++ struct next_to_fault ntf_out4 = next_to_fault_allocate (4); ++ struct next_to_fault ntf_out6 = next_to_fault_allocate (16); ++ ++ /* inet_pton requires NUL termination. */ ++ { ++ struct next_to_fault ntf_in = next_to_fault_allocate (test_len + 1); ++ memcpy (ntf_in.buffer, t->input, test_len + 1); ++ memset (ntf_out4.buffer, 0, 4); ++ check_result ("inet_pton", t, AF_INET, ntf_out4.buffer, ++ inet_pton (AF_INET, ntf_in.buffer, ntf_out4.buffer)); ++ memset (ntf_out6.buffer, 0, 16); ++ check_result ("inet_pton", t, AF_INET6, ntf_out6.buffer, ++ inet_pton (AF_INET6, ntf_in.buffer, ntf_out6.buffer)); ++ next_to_fault_free (&ntf_in); ++ } ++ ++ /* __inet_pton_length does not require NUL termination. */ ++ { ++ struct next_to_fault ntf_in = next_to_fault_allocate (test_len); ++ memcpy (ntf_in.buffer, t->input, test_len); ++ memset (ntf_out4.buffer, 0, 4); ++ check_result ("__inet_pton_length", t, AF_INET, ntf_out4.buffer, ++ __inet_pton_length (AF_INET, ntf_in.buffer, ntf_in.length, ++ ntf_out4.buffer)); ++ memset (ntf_out6.buffer, 0, 16); ++ check_result ("__inet_pton_length", t, AF_INET6, ntf_out6.buffer, ++ __inet_pton_length (AF_INET6, ntf_in.buffer, ntf_in.length, ++ ntf_out6.buffer)); ++ next_to_fault_free (&ntf_in); ++ } ++ ++ next_to_fault_free (&ntf_out4); ++ next_to_fault_free (&ntf_out6); ++} ++ ++/* The test cases were manually crafted and the set enhanced with ++ American Fuzzy Lop. */ ++const struct test_case test_cases[] = ++ { ++ {.input = ".:", }, ++ {.input = "0.0.0.0", ++ .ipv4_ok = true, ++ .ipv4_expected = {0, 0, 0, 0}, ++ }, ++ {.input = "0.:", }, ++ {.input = "00", }, ++ {.input = "0000000", }, ++ {.input = "00000000000000000", }, ++ {.input = "092.", }, ++ {.input = "10.0.301.2", }, ++ {.input = "127.0.0.1", ++ .ipv4_ok = true, ++ .ipv4_expected = {127, 0, 0, 1}, ++ }, ++ {.input = "19..", }, ++ {.input = "192.0.2.-1", }, ++ {.input = "192.0.2.01", }, ++ {.input = "192.0.2.1.", }, ++ {.input = "192.0.2.1192.", }, ++ {.input = "192.0.2.192.\377..", }, ++ {.input = "192.0.2.256", }, ++ {.input = "192.0.2.27", ++ .ipv4_ok = true, ++ .ipv4_expected = {192, 0, 2, 27}, ++ }, ++ {.input = "192.0.201.", }, ++ {.input = "192.0.261.", }, ++ {.input = "192.0.2\256", }, ++ {.input = "192.0.\262.", }, ++ {.input = "192.062.", }, ++ {.input = "192.092.\256", }, ++ {.input = "192.0\2562.", }, ++ {.input = "192.192.0.2661\031", }, ++ {.input = "192.192.00n2.1.", }, ++ {.input = "192.192.2.190.", }, ++ {.input = "192.255.255.2555", }, ++ {.input = "192.92.219\023.", }, ++ {.input = "192.\260.2.", }, ++ {.input = "1:1::1:1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1 ++ }, ++ }, ++ {.input = "2", }, ++ {.input = "2.", }, ++ {.input = "2001:db8:00001::f", }, ++ {.input = "2001:db8:10000::f", }, ++ {.input = "2001:db8:1234:5678:abcd:ef01:2345:67", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x12, 0x34, 0x56, 0x78, ++ 0xab, 0xcd, 0xef, 0x1, 0x23, 0x45, 0x0, 0x67 ++ }, ++ }, ++ {.input = "2001:db8:1234:5678:abcd:ef01:2345:6789:1", }, ++ {.input = "2001:db8:1234:5678:abcd:ef01:2345::6789", }, ++ {.input = "2001:db8::0", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ++ }, ++ }, ++ {.input = "2001:db8::00", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ++ }, ++ }, ++ {.input = "2001:db8::1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1 ++ }, ++ }, ++ {.input = "2001:db8::10", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10 ++ }, ++ }, ++ {.input = "2001:db8::19", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19 ++ }, ++ }, ++ {.input = "2001:db8::1::\012", }, ++ {.input = "2001:db8::1::2\012", }, ++ {.input = "2001:db8::2", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 ++ }, ++ }, ++ {.input = "2001:db8::3", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3 ++ }, ++ }, ++ {.input = "2001:db8::4", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 ++ }, ++ }, ++ {.input = "2001:db8::5", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5 ++ }, ++ }, ++ {.input = "2001:db8::6", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6 ++ }, ++ }, ++ {.input = "2001:db8::7", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7 ++ }, ++ }, ++ {.input = "2001:db8::8", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8 ++ }, ++ }, ++ {.input = "2001:db8::9", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9 ++ }, ++ }, ++ {.input = "2001:db8::A", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa ++ }, ++ }, ++ {.input = "2001:db8::B", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb ++ }, ++ }, ++ {.input = "2001:db8::C", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc ++ }, ++ }, ++ {.input = "2001:db8::D", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd ++ }, ++ }, ++ {.input = "2001:db8::E", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe ++ }, ++ }, ++ {.input = "2001:db8::F", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf ++ }, ++ }, ++ {.input = "2001:db8::a", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa ++ }, ++ }, ++ {.input = "2001:db8::b", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb ++ }, ++ }, ++ {.input = "2001:db8::c", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc ++ }, ++ }, ++ {.input = "2001:db8::d", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd ++ }, ++ }, ++ {.input = "2001:db8::e", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe ++ }, ++ }, ++ {.input = "2001:db8::f", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf ++ }, ++ }, ++ {.input = "2001:db8::ff", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff ++ }, ++ }, ++ {.input = "2001:db8::ffff:2\012", }, ++ {.input = "22", }, ++ {.input = "2222@", }, ++ {.input = "255.255.255.255", ++ .ipv4_ok = true, ++ .ipv4_expected = {255, 255, 255, 255}, ++ }, ++ {.input = "255.255.255.255\001", }, ++ {.input = "255.255.255.25555", }, ++ {.input = "2:", }, ++ {.input = "2:a:8:EEEE::EEEE:F:EEE8:EEEE\034*:", }, ++ {.input = "2:ff:1:1:7:ff:1:1:7.", }, ++ {.input = "2f:0000000000000000000000000000000000000000000000000000000000" ++ "0000000000000000000000000000000000000000000000000000000000000000000000" ++ "0G01", ++ }, ++ {.input = "429495", }, ++ {.input = "5::5::", }, ++ {.input = "6.6.", }, ++ {.input = "992.", }, ++ {.input = "::", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ++ }, ++ }, ++ {.input = "::00001", }, ++ {.input = "::1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1 ++ }, ++ }, ++ {.input = "::10000", }, ++ {.input = "::1:1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1 ++ }, ++ }, ++ {.input = "::ff:1:1:7.0.0.1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, ++ 0x0, 0x1, 0x0, 0x1, 0x7, 0x0, 0x0, 0x1 ++ }, ++ }, ++ {.input = "::ff:1:1:7:ff:1:1:7.", }, ++ {.input = "::ff:1:1:7ff:1:8:7.0.0.1", }, ++ {.input = "::ff:1:1:7ff:1:8f:1:1:71", }, ++ {.input = "::ffff:02fff:127.0.S1", }, ++ {.input = "::ffff:127.0.0.1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x1 ++ }, ++ }, ++ {.input = "::ffff:1:7.0.0.1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0xff, 0xff, 0x0, 0x1, 0x7, 0x0, 0x0, 0x1 ++ }, ++ }, ++ {.input = ":\272", }, ++ {.input = "A:f:ff:1:1:D:ff:1:1::7.", }, ++ {.input = "AAAAA.", }, ++ {.input = "D:::", }, ++ {.input = "DF8F", }, ++ {.input = "F::", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ++ }, ++ }, ++ {.input = "F:A:8:EEEE:8:EEEE\034*:", }, ++ {.input = "F:a:8:EEEE:8:EEEE\034*:", }, ++ {.input = "F:ff:100:7ff:1:8:7.0.10.1", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0x0, 0xf, 0x0, 0xff, 0x1, 0x0, 0x7, 0xff, ++ 0x0, 0x1, 0x0, 0x8, 0x7, 0x0, 0xa, 0x1 ++ }, ++ }, ++ {.input = "d92.", }, ++ {.input = "ff:00000000000000000000000000000000000000000000000000000000000" ++ "00000000000000000000000000000000000000000000000000000000000000000001", ++ }, ++ {.input = "fff2:2::ff2:2:f7", ++ .ipv6_ok = true, ++ .ipv6_expected = { ++ 0xff, 0xf2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0xf, 0xf2, 0x0, 0x2, 0x0, 0xf7 ++ }, ++ }, ++ {.input = "ffff:ff:ff:fff:ff:ff:ff:", }, ++ {.input = "\272:", }, ++ {NULL} ++ }; ++ ++static int ++do_test (void) ++{ ++ for (size_t i = 0; test_cases[i].input != NULL; ++i) ++ run_one_test (test_cases + i); ++ return 0; ++} ++ ++#include +diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c +index cf336839259b24b6..8ba5eae7818b49cd 100644 +--- a/sysdeps/unix/sysv/linux/if_index.c ++++ b/sysdeps/unix/sysv/linux/if_index.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -24,15 +24,14 @@ + #include + #include + #include +-#include ++#include + #include +-#include + + #include "netlinkaccess.h" + + + unsigned int +-if_nametoindex (const char *ifname) ++__if_nametoindex (const char *ifname) + { + #ifndef SIOCGIFINDEX + __set_errno (ENOSYS); +@@ -57,11 +56,13 @@ if_nametoindex (const char *ifname) + return ifr.ifr_ifindex; + #endif + } +-libc_hidden_def (if_nametoindex) ++libc_hidden_def (__if_nametoindex) ++weak_alias (__if_nametoindex, if_nametoindex) ++libc_hidden_weak (if_nametoindex) + + + void +-if_freenameindex (struct if_nameindex *ifn) ++__if_freenameindex (struct if_nameindex *ifn) + { + struct if_nameindex *ptr = ifn; + while (ptr->if_name || ptr->if_index) +@@ -71,7 +72,9 @@ if_freenameindex (struct if_nameindex *ifn) + } + free (ifn); + } +-libc_hidden_def (if_freenameindex) ++libc_hidden_def (__if_freenameindex) ++weak_alias (__if_freenameindex, if_freenameindex) ++libc_hidden_weak (if_freenameindex) + + + static struct if_nameindex * +@@ -163,7 +166,7 @@ if_nameindex_netlink (void) + if (idx[nifs].if_name == NULL) + { + idx[nifs].if_index = 0; +- if_freenameindex (idx); ++ __if_freenameindex (idx); + idx = NULL; + goto nomem; + } +@@ -190,7 +193,7 @@ if_nameindex_netlink (void) + + + struct if_nameindex * +-if_nameindex (void) ++__if_nameindex (void) + { + #ifndef SIOCGIFINDEX + __set_errno (ENOSYS); +@@ -200,11 +203,12 @@ if_nameindex (void) + return result; + #endif + } +-libc_hidden_def (if_nameindex) ++weak_alias (__if_nameindex, if_nameindex) ++libc_hidden_weak (if_nameindex) + + + char * +-if_indextoname (unsigned int ifindex, char *ifname) ++__if_indextoname (unsigned int ifindex, char *ifname) + { + /* We may be able to do the conversion directly, rather than searching a + list. This ioctl is not present in kernels before version 2.1.50. */ +@@ -233,4 +237,5 @@ if_indextoname (unsigned int ifindex, char *ifname) + else + return strncpy (ifname, ifr.ifr_name, IFNAMSIZ); + } +-libc_hidden_def (if_indextoname) ++weak_alias (__if_indextoname, if_indextoname) ++libc_hidden_weak (if_indextoname) diff --git a/SOURCES/glibc-rh677316-legacy.patch b/SOURCES/glibc-rh677316-legacy.patch new file mode 100644 index 00000000..1d807c2e --- /dev/null +++ b/SOURCES/glibc-rh677316-legacy.patch @@ -0,0 +1,61 @@ +This patch restores the legacy resolv.conf option parsing behavior which +was removed during the rebase. It also adds back formatting of legacy +options. + +diff --git a/resolv/res_debug.c b/resolv/res_debug.c +index 919b86e2b37dc150..e175229913b5f644 100644 +--- a/resolv/res_debug.c ++++ b/resolv/res_debug.c +@@ -597,7 +597,9 @@ p_option(u_long option) { + switch (option) { + case RES_INIT: return "init"; + case RES_DEBUG: return "debug"; +- case RES_USEVC: return "use-vc"; ++ case RES_AAONLY: return "aaonly(unimpl)"; ++ case RES_USEVC: return "usevc"; ++ case RES_PRIMARY: return "primry(unimpl)"; + case RES_IGNTC: return "igntc"; + case RES_RECURSE: return "recurs"; + case RES_DEFNAMES: return "defnam"; +@@ -608,6 +610,11 @@ p_option(u_long option) { + case RES_NOALIASES: return "noaliases"; + case DEPRECATED_RES_USE_INET6: return "inet6"; + case RES_ROTATE: return "rotate"; ++ case RES_NOCHECKNAME: return "no-check-names"; ++ case RES_KEEPTSIG: return "keeptsig(unimpl)"; ++ case RES_BLAST: return "blast"; ++ case RES_USEBSTRING: return "ip6-bytstring"; ++ case RES_NOIP6DOTINT: return "no-ip6-dotint"; + case RES_USE_EDNS0: return "edns0"; + case RES_SNGLKUP: return "single-request"; + case RES_SNGLKUPREOP: return "single-request-reopen"; +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 4e1f9fe8dea93e8a..c29bc4e9b99b6bee 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -668,7 +668,11 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options) + } options[] = { + #define STRnLEN(str) str, sizeof (str) - 1 + { STRnLEN ("inet6"), 0, DEPRECATED_RES_USE_INET6 }, ++ { STRnLEN ("ip6-bytestring"), 0, RES_USEBSTRING }, ++ { STRnLEN ("no-ip6-dotint"), 0, RES_NOIP6DOTINT }, ++ { STRnLEN ("ip6-dotint"), 1, ~RES_NOIP6DOTINT }, + { STRnLEN ("rotate"), 0, RES_ROTATE }, ++ { STRnLEN ("no-check-names"), 0, RES_NOCHECKNAME }, + { STRnLEN ("edns0"), 0, RES_USE_EDNS0 }, + { STRnLEN ("single-request-reopen"), 0, RES_SNGLKUPREOP }, + { STRnLEN ("single-request"), 0, RES_SNGLKUP }, +diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c +index 3b7b4129e31eaa22..288c2466e573507c 100644 +--- a/resolv/tst-resolv-res_init-skeleton.c ++++ b/resolv/tst-resolv-res_init-skeleton.c +@@ -106,7 +106,8 @@ print_resp (FILE *fp, res_state resp) + /* Also mask out other default flags which cannot be set through + the options directive. */ + int options +- = resp->options & ~(RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH); ++ = resp->options & ~(RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH ++ | RES_NOIP6DOTINT); + if (options != 0 + || resp->ndots != 1 + || resp->retrans != RES_TIMEOUT diff --git a/SOURCES/glibc-rh677316-libc-diag.patch b/SOURCES/glibc-rh677316-libc-diag.patch new file mode 100644 index 00000000..54f4d6bd --- /dev/null +++ b/SOURCES/glibc-rh677316-libc-diag.patch @@ -0,0 +1,90 @@ +Partial backport of this upstream commit: + +commit e15f7de60c26bb75fe1923b17c5f0461164d1a41 +Author: Zack Weinberg +Date: Sun Nov 20 20:46:30 2016 -0500 + + Split DIAG_* macros to new header libc-diag.h. + +Only the include/libc-diag.h header file is added. + +diff --git a/include/libc-diag.h b/include/libc-diag.h +new file mode 100644 +index 0000000000000000..db138c63b1573256 +--- /dev/null ++++ b/include/libc-diag.h +@@ -0,0 +1,74 @@ ++/* Macros for controlling diagnostic output from the compiler. ++ Copyright (C) 2014-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _LIBC_DIAG_H ++#define _LIBC_DIAG_H 1 ++ ++/* Ignore the value of an expression when a cast to void does not ++ suffice (in particular, for a call to a function declared with ++ attribute warn_unused_result). */ ++#define ignore_value(x) \ ++ ({ __typeof__ (x) __ignored_value = (x); (void) __ignored_value; }) ++ ++/* The macros to control diagnostics are structured like this, rather ++ than a single macro that both pushes and pops diagnostic state and ++ takes the affected code as an argument, because the GCC pragmas ++ work by disabling the diagnostic for a range of source locations ++ and do not work when all the pragmas and the affected code are in a ++ single macro expansion. */ ++ ++/* Push diagnostic state. */ ++#define DIAG_PUSH_NEEDS_COMMENT _Pragma ("GCC diagnostic push") ++ ++/* Pop diagnostic state. */ ++#define DIAG_POP_NEEDS_COMMENT _Pragma ("GCC diagnostic pop") ++ ++#define _DIAG_STR1(s) #s ++#define _DIAG_STR(s) _DIAG_STR1(s) ++ ++/* Ignore the diagnostic OPTION. VERSION is the most recent GCC ++ version for which the diagnostic has been confirmed to appear in ++ the absence of the pragma (in the form MAJOR.MINOR for GCC 4.x, ++ just MAJOR for GCC 5 and later). Uses of this pragma should be ++ reviewed when the GCC version given is no longer supported for ++ building glibc; the version number should always be on the same ++ source line as the macro name, so such uses can be found with grep. ++ Uses should come with a comment giving more details of the ++ diagnostic, and an architecture on which it is seen if possibly ++ optimization-related and not in architecture-specific code. This ++ macro should only be used if the diagnostic seems hard to fix (for ++ example, optimization-related false positives). */ ++#define DIAG_IGNORE_NEEDS_COMMENT(version, option) \ ++ _Pragma (_DIAG_STR (GCC diagnostic ignored option)) ++ ++/* Similar to DIAG_IGNORE_NEEDS_COMMENT the following macro ignores the ++ diagnostic OPTION but only if optimizations for size are enabled. ++ This is required because different warnings may be generated for ++ different optimization levels. For example a key piece of code may ++ only generate a warning when compiled at -Os, but at -O2 you could ++ still want the warning to be enabled to catch errors. In this case ++ you would use DIAG_IGNORE_Os_NEEDS_COMMENT to disable the warning ++ only for -Os. */ ++#ifdef __OPTIMIZE_SIZE__ ++# define DIAG_IGNORE_Os_NEEDS_COMMENT(version, option) \ ++ _Pragma (_DIAG_STR (GCC diagnostic ignored option)) ++#else ++# define DIAG_IGNORE_Os_NEEDS_COMMENT(version, option) ++#endif ++ ++#endif /* libc-diag.h */ diff --git a/SOURCES/glibc-rh677316-libc-lock.patch b/SOURCES/glibc-rh677316-libc-lock.patch new file mode 100644 index 00000000..98e6c97c --- /dev/null +++ b/SOURCES/glibc-rh677316-libc-lock.patch @@ -0,0 +1,12 @@ +This patch adds an include file . This simplifies +backports because upstream moved to this file in +commit ec999b8e5ede67f42759657beb8c5fef87c8cc63 (Move bits/libc-lock.h +and bits/libc-lockP.h out of bits/ (bug 14912)). + +diff --git a/include/libc-lock.h b/include/libc-lock.h +new file mode 100644 +index 0000000000000000..1f2fd8433454e870 +--- /dev/null ++++ b/include/libc-lock.h +@@ -0,0 +1 @@ ++#include diff --git a/SOURCES/glibc-rh677316-libc-pointer-arith.patch b/SOURCES/glibc-rh677316-libc-pointer-arith.patch new file mode 100644 index 00000000..7edaaf41 --- /dev/null +++ b/SOURCES/glibc-rh677316-libc-pointer-arith.patch @@ -0,0 +1,10 @@ +Add header for simplifying backports. + +diff --git a/include/libc-pointer-arith.h b/include/libc-pointer-arith.h +new file mode 100644 +index 0000000000000000..775374c9b8b31bcc +--- /dev/null ++++ b/include/libc-pointer-arith.h +@@ -0,0 +1,2 @@ ++/* Compatibility header to simplify backports. */ ++#include diff --git a/SOURCES/glibc-rh677316-mtrace.patch b/SOURCES/glibc-rh677316-mtrace.patch new file mode 100644 index 00000000..c5bffed5 --- /dev/null +++ b/SOURCES/glibc-rh677316-mtrace.patch @@ -0,0 +1,19 @@ +commit 74589f738efd72e07f759a4aabd2e32613aaefb8 +Author: Paul Pluzhnikov +Date: Tue Sep 1 08:35:38 2015 -0700 + + Filter out NULL entries. + +diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl +index adf61c73737160fb..c48e227e9fee8521 100644 +--- a/malloc/mtrace.pl ++++ b/malloc/mtrace.pl +@@ -167,7 +167,7 @@ while () { + printf ("+ %#0@XXX@x Alloc %d duplicate: %s %s\n", + hex($allocaddr), $nr, &location($addrwas{$allocaddr}), + $where); +- } else { ++ } elsif ($allocaddr =~ /^0x/) { + $allocated{$allocaddr}=$howmuch; + $addrwas{$allocaddr}=$where; + } diff --git a/SOURCES/glibc-rh677316-netdb-reentrant.patch b/SOURCES/glibc-rh677316-netdb-reentrant.patch new file mode 100644 index 00000000..74b3df92 --- /dev/null +++ b/SOURCES/glibc-rh677316-netdb-reentrant.patch @@ -0,0 +1,37 @@ +Backport of this upstream commit: + +commit 7f9d00341057eb80b43fa83956b8d7798b4dabea +Author: Roland McGrath +Date: Tue Aug 27 11:09:33 2013 -0700 + + Clean up h_errno declaration to use __thread unconditionally. + +Adjusted for the IS_IN changes, which were applied upstream after this +commit (and downstream before its backport). + +diff --git a/include/netdb.h b/include/netdb.h +index 3b24747fd5df6562..b6d7b90bbf8abd2e 100644 +--- a/include/netdb.h ++++ b/include/netdb.h +@@ -5,17 +5,12 @@ + /* Macros for accessing h_errno from inside libc. */ + # if IS_IN_LIB + # undef h_errno +-# ifdef _LIBC_REENTRANT +-# include +-# if IS_IN (libc) +-# define h_errno __libc_h_errno +-# else +-# define h_errno h_errno /* For #ifndef h_errno tests. */ +-# endif +-extern __thread int h_errno attribute_tls_model_ie; ++# if IS_IN (libc) ++# define h_errno __libc_h_errno + # else +-extern int h_errno; +-# endif /* _LIBC_REENTRANT */ ++# define h_errno h_errno /* For #ifndef h_errno tests. */ ++# endif ++extern __thread int h_errno attribute_tls_model_ie; + # endif /* IS_IN_LIB */ + # define __set_h_errno(x) (h_errno = (x)) diff --git a/SOURCES/glibc-rh677316-qsort_r.patch b/SOURCES/glibc-rh677316-qsort_r.patch new file mode 100644 index 00000000..ed523b2a --- /dev/null +++ b/SOURCES/glibc-rh677316-qsort_r.patch @@ -0,0 +1,115 @@ +commit bef8fd6013f7d398661077340753c745a8939279 +Author: Joseph Myers +Date: Wed Nov 12 22:33:41 2014 +0000 + + Fix qsort_r namespace (bug 17571). + +diff --git a/include/stdlib.h b/include/stdlib.h +index c20ce9da58bd2cdf..152c12fe9cb41509 100644 +--- a/include/stdlib.h ++++ b/include/stdlib.h +@@ -37,7 +37,8 @@ extern __typeof (secure_getenv) __libc_secure_getenv; + libc_hidden_proto (__libc_secure_getenv) + libc_hidden_proto (bsearch) + libc_hidden_proto (qsort) +-libc_hidden_proto (qsort_r) ++extern __typeof (qsort_r) __qsort_r; ++libc_hidden_proto (__qsort_r) + libc_hidden_proto (lrand48_r) + libc_hidden_proto (wctomb) + +diff --git a/nscd/gai.c b/nscd/gai.c +index 060933293838c4ee..018b449339813df5 100644 +--- a/nscd/gai.c ++++ b/nscd/gai.c +@@ -29,6 +29,7 @@ + #define __sendto sendto + #define __strchrnul strchrnul + #define __getline getline ++#define __qsort_r qsort_r + /* nscd uses 1MB or 2MB thread stacks. */ + #define __libc_use_alloca(size) (size <= __MAX_ALLOCA_CUTOFF) + +diff --git a/posix/tst-rfc3484-2.c b/posix/tst-rfc3484-2.c +index a37be36e6ad5a279..afd4b2959fc830f0 100644 +--- a/posix/tst-rfc3484-2.c ++++ b/posix/tst-rfc3484-2.c +@@ -9,6 +9,7 @@ + #define __inet_aton inet_aton + #define __gethostbyaddr_r gethostbyaddr_r + #define __gethostbyname2_r gethostbyname2_r ++#define __qsort_r qsort_r + + void + attribute_hidden +diff --git a/posix/tst-rfc3484-3.c b/posix/tst-rfc3484-3.c +index 493e76015c74be9e..92efecd242a0baa3 100644 +--- a/posix/tst-rfc3484-3.c ++++ b/posix/tst-rfc3484-3.c +@@ -9,6 +9,7 @@ + #define __inet_aton inet_aton + #define __gethostbyaddr_r gethostbyaddr_r + #define __gethostbyname2_r gethostbyname2_r ++#define __qsort_r qsort_r + + void + attribute_hidden +diff --git a/posix/tst-rfc3484.c b/posix/tst-rfc3484.c +index db3ae1b7bb86406a..8e886d987fd42b1d 100644 +--- a/posix/tst-rfc3484.c ++++ b/posix/tst-rfc3484.c +@@ -9,6 +9,7 @@ + #define __inet_aton inet_aton + #define __gethostbyaddr_r gethostbyaddr_r + #define __gethostbyname2_r gethostbyname2_r ++#define __qsort_r qsort_r + + void + attribute_hidden +diff --git a/stdlib/msort.c b/stdlib/msort.c +index e419734cd634ba5c..6f4b846b05fea8b9 100644 +--- a/stdlib/msort.c ++++ b/stdlib/msort.c +@@ -162,7 +162,7 @@ msort_with_tmp (const struct msort_param *p, void *b, size_t n) + + + void +-qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) ++__qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) + { + size_t size = n * s; + char *tmp = NULL; +@@ -298,12 +298,13 @@ qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg) + } + free (tmp); + } +-libc_hidden_def (qsort_r) ++libc_hidden_def (__qsort_r) ++weak_alias (__qsort_r, qsort_r) + + + void + qsort (void *b, size_t n, size_t s, __compar_fn_t cmp) + { +- return qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL); ++ return __qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL); + } + libc_hidden_def (qsort) +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index b1c72fda9d2aa365..a678d8d7e8b23d1d 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -2639,11 +2639,11 @@ getaddrinfo (const char *name, const char *service, + __libc_lock_lock (lock); + if (__libc_once_get (old_once) && gaiconf_reload_flag) + gaiconf_reload (); +- qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src); ++ __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src); + __libc_lock_unlock (lock); + } + else +- qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src); ++ __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src); + + /* Queue the results up as they come out of sorting. */ + q = p = results[order[0]].dest_addr; diff --git a/SOURCES/glibc-rh677316-res_state.patch b/SOURCES/glibc-rh677316-res_state.patch new file mode 100644 index 00000000..4080498f --- /dev/null +++ b/SOURCES/glibc-rh677316-res_state.patch @@ -0,0 +1,11 @@ +This patch adds a header, to simplify +backporting. + +diff --git a/include/bits/types/res_state.h b/include/bits/types/res_state.h +new file mode 100644 +index 0000000000000000..568c768f444d0198 +--- /dev/null ++++ b/include/bits/types/res_state.h +@@ -0,0 +1,2 @@ ++#define __need_res_state ++#include diff --git a/SOURCES/glibc-rh677316-resolv.patch b/SOURCES/glibc-rh677316-resolv.patch new file mode 100644 index 00000000..9a44a446 --- /dev/null +++ b/SOURCES/glibc-rh677316-resolv.patch @@ -0,0 +1,19195 @@ +Rebase the stub resolver and getaddrinfo to the glibc 2.26 version. +This eliminates the DNS search path limit (#677316), enables automatic +reloading of /etc/resolv.conf (#1432085), and makes the handling of IPv6 +scope IDs more strict (#1484034). + +This patch rebases the stub resolver up to and including this upstream +commit on release/2.26/master upstream branch: + +commit 27233446a62ca35ce0b54566279a99a6774d4210 +Author: Florian Weimer +Date: Wed Sep 6 15:47:27 2017 +0200 + + resolv: __resolv_conf_attach must not free passed conf object [BZ #22096] + + (cherry picked from commit a83047308196e3e54716a39dd85c0a08b198d6bd) + +The following files are rebased completely: + +include/arpa/nameser.h +include/arpa/nameser_compat.h +include/resolv.h +inet/gethstbyad_r.c +inet/gethstbynm2_r.c +inet/gethstbynm_r.c +nscd/aicache.c +nscd/gethstbyad_r.c +nscd/gethstbynm3_r.c +nss/digits_dots.c +nss/getXXbyYY.c +nss/getXXbyYY_r.c +nss/getnssent_r.c +nss/nsswitch.h +nss/tst-nss-files-hosts-erange.c +resolv/Depend +resolv/README +resolv/Versions +resolv/arpa/nameser.h +resolv/arpa/nameser_compat.h +resolv/base64.c +resolv/compat-gethnamaddr.c +resolv/compat-hooks.c +resolv/herror.c +resolv/inet_addr.c +resolv/inet_net_ntop.c +resolv/inet_net_pton.c +resolv/inet_neta.c +resolv/inet_ntop.c +resolv/ns_date.c +resolv/ns_name.c +resolv/ns_netint.c +resolv/ns_parse.c +resolv/ns_print.c +resolv/ns_samedomain.c +resolv/ns_ttl.c +resolv/nsap_addr.c +resolv/nss_dns/dns-canon.c +resolv/nss_dns/dns-host.c +resolv/nss_dns/dns-network.c +resolv/res-close.c +resolv/res-state.c +resolv/res_comp.c +resolv/res_data.c +resolv/res_debug.c +resolv/res_hconf.c +resolv/res_hconf.h +resolv/res_init.c +resolv/res_libc.c +resolv/res_mkquery.c +resolv/res_query.c +resolv/res_randomid.c +resolv/res_send.c +resolv/res_use_inet6.h +resolv/resolv-internal.h +resolv/resolv_conf.c +resolv/resolv_conf.h +resolv/resolv_context.c +resolv/resolv_context.h +resolv/tst-aton.c +resolv/tst-bug18665-tcp.c +resolv/tst-bug18665.c +resolv/tst-inet_ntop.c +resolv/tst-leaks.c +resolv/tst-leaks2.c +resolv/tst-ns_name.c +resolv/tst-ns_name.data +resolv/tst-ns_name_compress.c +resolv/tst-res_hconf_reorder.c +resolv/tst-res_use_inet6.c +resolv/tst-resolv-basic.c +resolv/tst-resolv-canonname.c +resolv/tst-resolv-edns.c +resolv/tst-resolv-network.c +resolv/tst-resolv-qtypes.c +resolv/tst-resolv-res_init-multi.c +resolv/tst-resolv-res_init-skeleton.c +resolv/tst-resolv-res_init-thread.c +resolv/tst-resolv-res_init.c +resolv/tst-resolv-res_ninit.c +resolv/tst-resolv-rotate.c +resolv/tst-resolv-search.c +resolv/tst-resolv-threads.c +sysdeps/posix/getaddrinfo.c + +The following files have been deleted because they are no longer needed: + +resolv/res_debug.h +resolv/gethnamaddr.c (renamed to resolv/compat-gethnamaddr.c) + +The following files have remaining differences: + +resolv/Makefile (build system, not installed) +resolv/resolv.h (limited changes to public header file) + +diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h +index 57f7457848bc1700..7a8290e1f26070e0 100644 +--- a/include/arpa/nameser.h ++++ b/include/arpa/nameser.h +@@ -2,6 +2,8 @@ + + #include + ++# ifndef _ISOMAC ++ + /* If the machine allows unaligned access we can do better than using + the NS_GET16, NS_GET32, NS_PUT16, and NS_PUT32 macros from the + installed header. */ +@@ -47,8 +49,11 @@ extern const struct _ns_flagdata _ns_flagdata[] attribute_hidden; + + #endif + +-extern u_int __ns_get16 (const u_char *) __THROW; +-extern u_long __ns_get32 (const u_char *) __THROW; ++extern unsigned int __ns_get16 (const unsigned char *) __THROW; ++extern unsigned long __ns_get32 (const unsigned char *) __THROW; ++int __ns_name_ntop (const unsigned char *, char *, size_t) __THROW; ++int __ns_name_unpack (const unsigned char *, const unsigned char *, ++ const unsigned char *, unsigned char *, size_t) __THROW; + + #define ns_msg_getflag(handle, flag) \ + (((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift) +@@ -74,4 +79,5 @@ libresolv_hidden_proto (ns_samename) + libresolv_hidden_proto (ns_makecanon) + libresolv_hidden_proto (ns_format_ttl) + ++# endif /* !_ISOMAC */ + #endif +diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h +index 2e735ede4c0e922b..f7d0e043c6eedc88 100644 +--- a/include/arpa/nameser_compat.h ++++ b/include/arpa/nameser_compat.h +@@ -1,8 +1,11 @@ + #ifndef _ARPA_NAMESER_COMPAT_ + #include + +-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e., +- T_A and T_AAAA). */ +-#define T_UNSPEC 62321 ++# ifndef _ISOMAC + ++/* The number is outside the 16-bit RR type range and is used ++ internally by the implementation. */ ++#define T_QUERY_A_AND_AAAA 439963904 ++ ++# endif /* !_ISOMAC */ + #endif +diff --git a/include/resolv.h b/include/resolv.h +index e1e3caa2a2ecb6ea..634f5525fe9d357a 100644 +--- a/include/resolv.h ++++ b/include/resolv.h +@@ -1,68 +1,45 @@ + #ifndef _RESOLV_H_ + +-#define RES_SET_H_ERRNO(r,x) \ ++# ifndef _ISOMAC ++# include ++# define RES_SET_H_ERRNO(r,x) \ + do \ + { \ + (r)->res_h_errno = x; \ + __set_h_errno(x); \ + } \ + while (0) ++# endif + +-#include + #include + +-#ifdef _RESOLV_H_ ++# if defined _RESOLV_H_ && !defined _ISOMAC + +-# ifdef _LIBC_REENTRANT +-# include +-# undef _res +-# if IS_IN (libc) +-# define __resp __libc_resp +-# endif +-# define _res (*__resp) +-extern __thread struct __res_state *__resp attribute_tls_model_ie; +-# else +-# ifndef __BIND_NOSTATIC +-# undef _res +-extern struct __res_state _res; +-# endif ++# if IS_IN (libc) ++# define __resp __libc_resp + # endif ++extern __thread struct __res_state *__resp attribute_tls_model_ie; ++# undef _res ++# define _res (*__resp) + + /* Now define the internal interfaces. */ +-extern int __res_vinit (res_state, int); +-extern int __res_maybe_init (res_state, int); ++extern int __res_vinit (res_state, int) attribute_hidden; + extern void _sethtent (int); +-extern void _endhtent (void); + extern struct hostent *_gethtent (void); + extern struct hostent *_gethtbyname (const char *__name); + extern struct hostent *_gethtbyname2 (const char *__name, int __af); + struct hostent *_gethtbyaddr (const char *addr, size_t __len, int __af); +-extern u_int32_t _getlong (const u_char *__src); +-extern u_int16_t _getshort (const u_char *__src); +-extern void res_pquery (const res_state __statp, const u_char *__msg, +- int __len, FILE *__file); +-extern void res_send_setqhook (res_send_qhook __hook); +-extern void res_send_setrhook (res_send_rhook __hook); ++extern uint32_t _getlong (const unsigned char *__src); ++extern uint16_t _getshort (const unsigned char *__src); + extern int res_ourserver_p (const res_state __statp, + const struct sockaddr_in6 *__inp); + extern void __res_iclose (res_state statp, bool free_addr); +-extern int __res_nopt(res_state statp, int n0, u_char *buf, int buflen, +- int anslen); + libc_hidden_proto (__res_ninit) +-libc_hidden_proto (__res_maybe_init) + libc_hidden_proto (__res_nclose) + libc_hidden_proto (__res_iclose) + libc_hidden_proto (__res_randomid) + libc_hidden_proto (__res_state) + +-int __libc_res_nquery (res_state, const char *, int, int, u_char *, int, +- u_char **, u_char **, int *, int *, int *); +-int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int, +- u_char **, u_char **, int *, int *, int *); +-int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int, +- u_char *, int, u_char **, u_char **, int *, int *, int *) +- attribute_hidden; +- + libresolv_hidden_proto (_sethtent) + libresolv_hidden_proto (_gethtent) + libresolv_hidden_proto (_gethtbyaddr) +@@ -84,25 +61,11 @@ libresolv_hidden_proto (__p_type) + libresolv_hidden_proto (__loc_ntoa) + libresolv_hidden_proto (__fp_nquery) + libresolv_hidden_proto (__fp_query) +-libresolv_hidden_proto (__hostalias) +-libresolv_hidden_proto (__res_nmkquery) +-libresolv_hidden_proto (__libc_res_nquery) +-libresolv_hidden_proto (__res_nquery) +-libresolv_hidden_proto (__res_nquerydomain) +-libresolv_hidden_proto (__res_hostalias) +-libresolv_hidden_proto (__libc_res_nsearch) +-libresolv_hidden_proto (__res_nsearch) + libresolv_hidden_proto (__res_nameinquery) + libresolv_hidden_proto (__res_queriesmatch) +-libresolv_hidden_proto (__res_nsend) + libresolv_hidden_proto (__b64_ntop) +-libresolv_hidden_proto (__res_nopt) + libresolv_hidden_proto (__dn_count_labels) + libresolv_hidden_proto (__p_secstodate) + +-extern const char *_res_opcodes[]; +-libresolv_hidden_proto (_res_opcodes) +- +-#endif +- ++# endif /* _RESOLV_H_ && !_ISOMAC */ + #endif +diff --git a/inet/gethstbyad_r.c b/inet/gethstbyad_r.c +index 5ae854b4f91e72ad..6b5c13105059dd35 100644 +--- a/inet/gethstbyad_r.c ++++ b/inet/gethstbyad_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2000,2002,2007 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + +@@ -18,7 +18,7 @@ + + #include + #include +- ++#include + + #define LOOKUP_TYPE struct hostent + #define FUNCTION_NAME gethostbyaddr +@@ -27,7 +27,6 @@ + #define ADD_VARIABLES addr, len, type + #define NEED_H_ERRNO 1 + #define NEED__RES 1 +-#define NEED__RES_HCONF 1 + /* If the addr parameter is the IPv6 unspecified address no query must + be performed. */ + #define PREPROCESS \ +diff --git a/inet/gethstbynm2_r.c b/inet/gethstbynm2_r.c +index 48e4946f29145bef..580ba6d1cfbd63ec 100644 +--- a/inet/gethstbynm2_r.c ++++ b/inet/gethstbynm2_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996, 1997, 2002, 2007 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + +@@ -22,7 +22,7 @@ + #include + #include + #include +- ++#include + + #define LOOKUP_TYPE struct hostent + #define FUNCTION_NAME gethostbyname2 +@@ -30,7 +30,7 @@ + #define ADD_PARAMS const char *name, int af + #define ADD_VARIABLES name, af + #define NEED_H_ERRNO 1 +-#define NEED__RES_HCONF 1 ++#define NEED__RES 1 + #define POSTPROCESS \ + if (status == NSS_STATUS_SUCCESS) \ + _res_hconf_reorder_addrs (resbuf); +diff --git a/inet/gethstbynm_r.c b/inet/gethstbynm_r.c +index 49e7028a1fe71a09..8f464b5ff1914b86 100644 +--- a/inet/gethstbynm_r.c ++++ b/inet/gethstbynm_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996, 1997, 1998, 2002, 2007 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + +@@ -22,7 +22,7 @@ + #include + #include + #include +- ++#include + + #define LOOKUP_TYPE struct hostent + #define FUNCTION_NAME gethostbyname +@@ -30,7 +30,7 @@ + #define ADD_PARAMS const char *name + #define ADD_VARIABLES name + #define NEED_H_ERRNO 1 +-#define NEED__RES_HCONF 1 ++#define NEED__RES 1 + #define POSTPROCESS \ + if (status == NSS_STATUS_SUCCESS) \ + _res_hconf_reorder_addrs (resbuf); +diff --git a/nscd/aicache.c b/nscd/aicache.c +index 0ee25247cd464940..a3de792cc429b546 100644 +--- a/nscd/aicache.c ++++ b/nscd/aicache.c +@@ -1,5 +1,5 @@ + /* Cache handling for host lookup. +- Copyright (C) 2004-2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. ++ Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + +@@ -26,7 +26,8 @@ + #include + #include + #include +-#include ++#include ++#include + + #include "dbg_log.h" + #include "nscd.h" +@@ -78,7 +79,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + char strdata[0]; + } *dataset = NULL; + +- if (__builtin_expect (debug_level > 0, 0)) ++ if (__glibc_unlikely (debug_level > 0)) + { + if (he == NULL) + dbg_log (_("Haven't found \"%s\" in hosts cache!"), (char *) key); +@@ -87,34 +88,29 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + } + + static service_user *hosts_database; +- service_user *nip = NULL; ++ service_user *nip; + int no_more; + int rc6 = 0; + int rc4 = 0; + int herrno = 0; + +- if (hosts_database != NULL) +- { +- nip = hosts_database; +- no_more = 0; +- } +- else ++ if (hosts_database == NULL) + no_more = __nss_database_lookup ("hosts", NULL, +- "dns [!UNAVAIL=return] files", &nip); +- +- /* Initialize configurations. */ +- if (__builtin_expect (!_res_hconf.initialized, 0)) +- _res_hconf_init (); +- if (__res_maybe_init (&_res, 0) == -1) ++ "dns [!UNAVAIL=return] files", ++ &hosts_database); ++ else ++ no_more = 0; ++ nip = hosts_database; ++ ++ /* Initialize configurations. If we are looking for both IPv4 and ++ IPv6 address we don't want the lookup functions to automatically ++ promote IPv4 addresses to IPv6 addresses. Therefore, use the ++ _no_inet6 variant. */ ++ struct resolv_context *ctx = __resolv_context_get (); ++ bool enable_inet6 = __resolv_context_disable_inet6 (ctx); ++ if (ctx == NULL) + no_more = 1; + +- /* If we are looking for both IPv4 and IPv6 address we don't want +- the lookup functions to automatically promote IPv4 addresses to +- IPv6 addresses. Currently this is decided by setting the +- RES_USE_INET6 bit in _res.options. */ +- int old_res_options = _res.options; +- _res.options &= ~DEPRECATED_RES_USE_INET6; +- + size_t tmpbuf6len = 1024; + char *tmpbuf6 = alloca (tmpbuf6len); + size_t tmpbuf4len = 0; +@@ -431,7 +427,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, + struct dataset *newp + = (struct dataset *) mempool_alloc (db, total + req->key_len, + 1); +- if (__builtin_expect (newp != NULL, 1)) ++ if (__glibc_likely (newp != NULL)) + { + /* Adjust pointer into the memory block. */ + key_copy = (char *) newp + (key_copy - (char *) dataset); +@@ -538,7 +534,8 @@ next_nip: + } + + out: +- _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; ++ __resolv_context_enable_inet6 (ctx, enable_inet6); ++ __resolv_context_put (ctx); + + if (dataset != NULL && !alloca_used) + { +diff --git a/nscd/gethstbyad_r.c b/nscd/gethstbyad_r.c +index c0988b862da3ef03..842ced2ec64048ea 100644 +--- a/nscd/gethstbyad_r.c ++++ b/nscd/gethstbyad_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + +@@ -28,7 +28,6 @@ + #define EXTRA_VARIABLES , ttlp + #define NEED_H_ERRNO 1 + #define NEED__RES 1 +-#define NEED__RES_HCONF 1 + + /* We are nscd, so we don't want to be talking to ourselves. */ + #undef USE_NSCD +diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c +index a7d25548a8ef3f36..2ab75e469eca1589 100644 +--- a/nscd/gethstbynm3_r.c ++++ b/nscd/gethstbynm3_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + +@@ -32,7 +32,7 @@ + #define ADD_VARIABLES name, af + #define EXTRA_VARIABLES , ttlp, canonp + #define NEED_H_ERRNO 1 +-#define NEED__RES_HCONF 1 ++#define NEED__RES 1 + + #define HANDLE_DIGITS_DOTS 1 + #define HAVE_LOOKUP_BUFFER 1 +diff --git a/nss/Makefile b/nss/Makefile +index 4d6a9ef83b885d7c..dda1e5e51b7a3ea3 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -39,7 +39,7 @@ makedb-modules = xmalloc hash-string + extra-objs += $(makedb-modules:=.o) + + tests = test-netdb tst-nss-test1 bug17079 tst-nss-getpwent \ +- test-digits-dots ++ test-digits-dots tst-nss-files-hosts-erange + xtests = bug-erange + + include ../Makeconfig +@@ -115,3 +115,5 @@ $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so + $(make-link) + endif + $(objpfx)tst-nss-test1.out: $(objpfx)/libnss_test1.so$(libnss_test1.so-version) ++ ++$(objpfx)tst-nss-files-hosts-erange: $(libdl) +diff --git a/nss/digits_dots.c b/nss/digits_dots.c +index 7a2b57bdebe03408..0c1fa97e3977a81e 100644 +--- a/nss/digits_dots.c ++++ b/nss/digits_dots.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1997, 1999, 2000, 2001, 2004 Free Software Foundation, Inc. ++/* Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by H.J. Lu , 1997. + +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include "nsswitch.h" +@@ -38,11 +39,10 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + size_t buflen, struct hostent **result, + enum nss_status *status, int af, int *h_errnop) + { +- int save; +- + /* We have to test for the use of IPv6 which can only be done by + examining `_res'. */ +- if (__res_maybe_init (&_res, 0) == -1) ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) + { + if (h_errnop) + *h_errnop = NETDB_INTERNAL; +@@ -52,6 +52,21 @@ __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, + *result = NULL; + return -1; + } ++ int ret = __nss_hostname_digits_dots_context ++ (ctx, name, resbuf, buffer, buffer_size, buflen, ++ result, status, af, h_errnop); ++ __resolv_context_put (ctx); ++ return ret; ++} ++ ++int ++__nss_hostname_digits_dots_context (struct resolv_context *ctx, ++ const char *name, struct hostent *resbuf, ++ char **buffer, size_t *buffer_size, ++ size_t buflen, struct hostent **result, ++ enum nss_status *status, int af, int *h_errnop) ++{ ++ int save; + + /* + * disallow names consisting only of digits/dots, unless +diff --git a/nss/getXXbyYY.c b/nss/getXXbyYY.c +index c308a70b93ba8a77..a439b816f70aa2e7 100644 +--- a/nss/getXXbyYY.c ++++ b/nss/getXXbyYY.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2001,2003, 2004 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -17,7 +17,7 @@ + + #include + #include +-#include ++#include + #include + #include + +@@ -47,6 +47,11 @@ + |* *| + \*******************************************************************/ + ++ ++#ifdef HANDLE_DIGITS_DOTS ++# include ++#endif ++ + /* To make the real sources a bit prettier. */ + #define REENTRANT_NAME APPEND_R (FUNCTION_NAME) + #define APPEND_R(name) APPEND_R1 (name) +@@ -93,6 +98,19 @@ FUNCTION_NAME (ADD_PARAMS) + int h_errno_tmp = 0; + #endif + ++#ifdef HANDLE_DIGITS_DOTS ++ /* Wrap both __nss_hostname_digits_dots and the actual lookup ++ function call in the same context. */ ++ struct resolv_context *res_ctx = __resolv_context_get (); ++ if (res_ctx == NULL) ++ { ++# if NEED_H_ERRNO ++ __set_h_errno (NETDB_INTERNAL); ++# endif ++ return NULL; ++ } ++#endif ++ + /* Get lock. */ + __libc_lock_lock (lock); + +@@ -105,9 +123,9 @@ FUNCTION_NAME (ADD_PARAMS) + #ifdef HANDLE_DIGITS_DOTS + if (buffer != NULL) + { +- if (__nss_hostname_digits_dots (name, &resbuf, &buffer, +- &buffer_size, 0, &result, NULL, AF_VAL, +- H_ERRNO_VAR_P)) ++ if (__nss_hostname_digits_dots_context ++ (res_ctx, name, &resbuf, &buffer, &buffer_size, 0, &result, NULL, ++ AF_VAL, H_ERRNO_VAR_P)) + goto done; + } + #endif +@@ -143,6 +161,10 @@ done: + /* Release lock. */ + __libc_lock_unlock (lock); + ++#ifdef HANDLE_DIGITS_DOTS ++ __resolv_context_put (res_ctx); ++#endif ++ + #ifdef NEED_H_ERRNO + if (h_errno_tmp != 0) + __set_h_errno (h_errno_tmp); +diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c +index 1b457897517fdfb8..bce80e05dd2d1764 100644 +--- a/nss/getXXbyYY_r.c ++++ b/nss/getXXbyYY_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + +@@ -25,11 +25,8 @@ + #ifdef USE_NSCD + # include + #endif +-#ifdef NEED__RES_HCONF +-# include +-#endif + #ifdef NEED__RES +-# include ++# include + #endif + /*******************************************************************\ + |* Here we assume several symbols to be defined: *| +@@ -56,8 +53,7 @@ + |* NEED_H_ERRNO - an extra parameter will be passed to point to *| + |* the global `h_errno' variable. *| + |* *| +-|* NEED__RES - the global _res variable might be used so we *| +-|* will have to initialize it if necessary *| ++|* NEED__RES - obtain a struct resolv_context resolver context *| + |* *| + |* PREPROCESS - code run before anything else *| + |* *| +@@ -216,6 +212,18 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, + bool any_service = false; + #endif + ++#ifdef NEED__RES ++ /* The HANDLE_DIGITS_DOTS case below already needs the resolver ++ configuration, so this has to happen early. */ ++ struct resolv_context *res_ctx = __resolv_context_get (); ++ if (res_ctx == NULL) ++ { ++ *h_errnop = NETDB_INTERNAL; ++ *result = NULL; ++ return errno; ++ } ++#endif /* NEED__RES */ ++ + #ifdef PREPROCESS + PREPROCESS; + #endif +@@ -226,6 +234,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, + H_ERRNO_VAR_P)) + { + case -1: ++# ifdef NEED__RES ++ __resolv_context_put (res_ctx); ++# endif + return errno; + case 1: + #ifdef NEED_H_ERRNO +@@ -245,7 +256,12 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, + nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result + H_ERRNO_VAR); + if (nscd_status >= 0) +- return nscd_status; ++ { ++# ifdef NEED__RES ++ __resolv_context_put (res_ctx); ++# endif ++ return nscd_status; ++ } + } + #endif + +@@ -263,21 +279,6 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, + } + else + { +-#ifdef NEED__RES +- /* The resolver code will really be used so we have to +- initialize it. */ +- if (__res_maybe_init (&_res, 0) == -1) +- { +- *h_errnop = NETDB_INTERNAL; +- *result = NULL; +- return errno; +- } +-#endif /* need _res */ +-#ifdef NEED__RES_HCONF +- if (!_res_hconf.initialized) +- _res_hconf_init (); +-#endif /* need _res_hconf */ +- + void *tmp_ptr = fct.l; + #ifdef PTR_MANGLE + PTR_MANGLE (tmp_ptr); +@@ -406,6 +407,12 @@ done: + POSTPROCESS; + #endif + ++#ifdef NEED__RES ++ /* This has to happen late because the POSTPROCESS stage above might ++ need the resolver context. */ ++ __resolv_context_put (res_ctx); ++#endif /* NEED__RES */ ++ + int res; + if (status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND) + res = 0; +diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c +index 25e952f5317e6999..d85065b6cc05dbcb 100644 +--- a/nss/getnssent_r.c ++++ b/nss/getnssent_r.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2000, 2002, 2004, 2007, 2011 Free Software Foundation, Inc. ++/* Copyright (C) 2000-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -18,6 +18,7 @@ + #include + #include + #include "nsswitch.h" ++#include + + /* Set up NIP to run through the services. If ALL is zero, use NIP's + current location if it's not nil. Return nonzero if there are no +@@ -59,10 +60,15 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct, + } fct; + int no_more; + +- if (res && __res_maybe_init (&_res, 0) == -1) ++ struct resolv_context *res_ctx = NULL; ++ if (res) + { +- __set_h_errno (NETDB_INTERNAL); +- return; ++ res_ctx = __resolv_context_get (); ++ if (res_ctx == NULL) ++ { ++ __set_h_errno (NETDB_INTERNAL); ++ return; ++ } + } + + /* Cycle through the services and run their `setXXent' functions until +@@ -95,6 +101,8 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct, + *last_nip = *nip; + } + ++ __resolv_context_put (res_ctx); ++ + if (stayopen_tmp) + *stayopen_tmp = stayopen; + } +@@ -112,10 +120,15 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct, + } fct; + int no_more; + +- if (res && __res_maybe_init (&_res, 0) == -1) ++ struct resolv_context *res_ctx = NULL; ++ if (res) + { +- __set_h_errno (NETDB_INTERNAL); +- return; ++ res_ctx = __resolv_context_get (); ++ if (res_ctx == NULL) ++ { ++ __set_h_errno (NETDB_INTERNAL); ++ return; ++ } + } + + /* Cycle through all the services and run their endXXent functions. */ +@@ -132,6 +145,8 @@ __nss_endent (const char *func_name, db_lookup_function lookup_fct, + no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, 0, 1); + } + *last_nip = *nip = NULL; ++ ++ __resolv_context_put (res_ctx); + } + + +@@ -152,11 +167,16 @@ __nss_getent_r (const char *getent_func_name, + int no_more; + enum nss_status status; + +- if (res && __res_maybe_init (&_res, 0) == -1) ++ struct resolv_context *res_ctx = NULL; ++ if (res) + { +- *h_errnop = NETDB_INTERNAL; +- *result = NULL; +- return errno; ++ res_ctx = __resolv_context_get (); ++ if (res_ctx == NULL) ++ { ++ *h_errnop = NETDB_INTERNAL; ++ *result = NULL; ++ return errno; ++ } + } + + /* Initialize status to return if no more functions are found. */ +@@ -227,6 +247,8 @@ __nss_getent_r (const char *getent_func_name, + while (! no_more && status != NSS_STATUS_SUCCESS); + } + ++ __resolv_context_put (res_ctx); ++ + *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL; + return (status == NSS_STATUS_SUCCESS ? 0 + : status != NSS_STATUS_TRYAGAIN ? ENOENT +diff --git a/nss/nsswitch.h b/nss/nsswitch.h +index 23a77747555fab53..bd3fbcb08250c61c 100644 +--- a/nss/nsswitch.h ++++ b/nss/nsswitch.h +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -197,7 +197,17 @@ extern int __nss_getent_r (const char *getent_func_name, + extern void *__nss_getent (getent_r_function func, + void **resbuf, char **buffer, size_t buflen, + size_t *buffer_size, int *h_errnop); ++struct resolv_context; + struct hostent; ++extern int __nss_hostname_digits_dots_context (struct resolv_context *, ++ const char *name, ++ struct hostent *resbuf, ++ char **buffer, ++ size_t *buffer_size, ++ size_t buflen, ++ struct hostent **result, ++ enum nss_status *status, int af, ++ int *h_errnop) attribute_hidden; + extern int __nss_hostname_digits_dots (const char *name, + struct hostent *resbuf, char **buffer, + size_t *buffer_size, size_t buflen, +diff --git a/nss/tst-nss-files-hosts-erange.c b/nss/tst-nss-files-hosts-erange.c +new file mode 100644 +index 0000000000000000..beb7aa9fa0b5926f +--- /dev/null ++++ b/nss/tst-nss-files-hosts-erange.c +@@ -0,0 +1,109 @@ ++/* Parse /etc/hosts in multi mode with a trailing long line (bug 21915). ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct support_chroot *chroot_env; ++ ++#define X10 "XXXXXXXXXX" ++#define X100 X10 X10 X10 X10 X10 X10 X10 X10 X10 X10 ++#define X1000 X100 X100 X100 X100 X100 X100 X100 X100 X100 X100 ++ ++static void ++prepare (int argc, char **argv) ++{ ++ chroot_env = support_chroot_create ++ ((struct support_chroot_configuration) ++ { ++ .resolv_conf = "", ++ .hosts = ++ "127.0.0.1 localhost localhost.localdomain\n" ++ "::1 localhost localhost.localdomain\n" ++ "192.0.2.1 example.com\n" ++ "#" X1000 X100 "\n", ++ .host_conf = "multi on\n", ++ }); ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ if (!support_can_chroot ()) ++ return EXIT_UNSUPPORTED; ++ ++ __nss_configure_lookup ("hosts", "files"); ++ if (dlopen (LIBNSS_FILES_SO, RTLD_LAZY) == NULL) ++ FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ()); ++ ++ xchroot (chroot_env->path_chroot); ++ ++ errno = ERANGE; ++ h_errno = NETDB_INTERNAL; ++ check_hostent ("gethostbyname example.com", ++ gethostbyname ("example.com"), ++ "name: example.com\n" ++ "address: 192.0.2.1\n"); ++ errno = ERANGE; ++ h_errno = NETDB_INTERNAL; ++ check_hostent ("gethostbyname2 AF_INET example.com", ++ gethostbyname2 ("example.com", AF_INET), ++ "name: example.com\n" ++ "address: 192.0.2.1\n"); ++ { ++ struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ errno = ERANGE; ++ h_errno = NETDB_INTERNAL; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("example.com", "80", &hints, &ai); ++ check_addrinfo ("example.com AF_UNSPEC", ai, ret, ++ "address: STREAM/TCP 192.0.2.1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ++ hints.ai_family = AF_INET; ++ errno = ERANGE; ++ h_errno = NETDB_INTERNAL; ++ ret = getaddrinfo ("example.com", "80", &hints, &ai); ++ check_addrinfo ("example.com AF_INET", ai, ret, ++ "address: STREAM/TCP 192.0.2.1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++ ++ support_chroot_free (chroot_env); ++ return 0; ++} ++ ++#define PREPARE prepare ++#include +diff --git a/resolv/Depend b/resolv/Depend +index 8d2587bbc1fd0b89..6c1aa44e6eb7b9a3 100644 +--- a/resolv/Depend ++++ b/resolv/Depend +@@ -1,2 +1 @@ +-linuxthreads + nptl +diff --git a/resolv/Makefile b/resolv/Makefile +index 3f525bcc75ee83ae..1124897ce5f9610b 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -1,5 +1,4 @@ +-# Copyright (C) 1994-2001,2003,2004,2007,2008,2011,2012 +-# Free Software Foundation, Inc. ++# Copyright (C) 1994-2017 Free Software Foundation, Inc. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -21,33 +20,73 @@ + # + subdir := resolv + ++include ../Makeconfig ++ + headers := resolv.h \ + netdb.h bits/netdb.h \ + arpa/nameser.h arpa/nameser_compat.h \ + sys/bitypes.h + + routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \ +- res_hconf res_libc res-state ++ res_hconf res_libc res-state res_randomid res-close \ ++ resolv_context resolv_conf + +-tests = tst-aton tst-leaks tst-inet_ntop tst-inet_pton ++tests = tst-aton tst-leaks tst-inet_ntop + xtests = tst-leaks2 + +-generate := mtrace-tst-leaks tst-leaks.mtrace tst-leaks2.mtrace +- +-include ../Makeconfig ++generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace + + extra-libs := libresolv libnss_dns + ifeq ($(have-thread-library),yes) + extra-libs += libanl + routines += gai_sigqueue +-tests += tst-res_hconf_reorder ++ ++tests += \ ++ tst-bug18665 \ ++ tst-bug18665-tcp \ ++ tst-ns_name \ ++ tst-ns_name_compress \ ++ tst-res_hconf_reorder \ ++ tst-res_use_inet6 \ ++ tst-resolv-basic \ ++ tst-resolv-edns \ ++ tst-resolv-network \ ++ tst-resolv-res_init-multi \ ++ tst-resolv-search \ ++ ++# These tests need libdl. ++ifeq (yes,$(build-shared)) ++tests += \ ++ tst-resolv-canonname \ ++ ++# uses DEPRECATED_RES_USE_INET6 from . ++tests += \ ++ tst-resolv-res_init \ ++ tst-resolv-res_init-thread \ ++ ++# Needs resolv_context. ++tests += \ ++ tst-resolv-res_ninit \ ++ tst-resolv-threads \ ++ ++endif ++ ++# This test accesses __inet_ntop_range, an internal libc function. ++tests += tst-inet_pton ++ ++# This test sends millions of packets and is rather slow. ++xtests += tst-resolv-qtypes ++ ++# This test has dropped packet tests and runs for a long time. ++xtests += tst-resolv-rotate + endif + extra-libs-others = $(extra-libs) +-libresolv-routines := gethnamaddr res_comp res_debug \ ++libresolv-routines := res_comp res_debug \ + res_data res_mkquery res_query res_send \ + inet_net_ntop inet_net_pton inet_neta base64 \ + ns_parse ns_name ns_netint ns_ttl ns_print \ +- ns_samedomain ns_date ++ ns_samedomain ns_date \ ++ compat-hooks compat-gethnamaddr + + libanl-routines := gai_cancel gai_error gai_misc gai_notify gai_suspend \ + getaddrinfo_a +@@ -66,29 +105,23 @@ ifeq (yesyes,$(build-shared)$(have-thread-library)) + tests: $(objpfx)ga_test + endif + +-generated := mtrace-tst-leaks tst-leaks.mtrace \ +- mtrace-tst-leaks2 tst-leaks2.mtrace ++ifeq (,$(filter sunrpc,$(subdirs))) ++# The netdb.h we install does '#include ', so one must exist. ++# If sunrpc/ is built in this configuration, it installs a real . ++# If that's not going to happen, install our dummy file. ++headers += rpc/netdb.h ++endif + +-include ../Rules ++generated += mtrace-tst-leaks.out tst-leaks.mtrace \ ++ mtrace-tst-leaks2.out tst-leaks2.mtrace \ ++ mtrace-tst-resolv-res_ninit.out tst-resolv-res_ninit.mtrace \ + +-CPPFLAGS += -Dgethostbyname=res_gethostbyname \ +- -Dgethostbyname2=res_gethostbyname2 \ +- -Dgethostbyaddr=res_gethostbyaddr \ +- -Dgetnetbyname=res_getnetbyname \ +- -Dgetnetbyaddr=res_getnetbyaddr ++include ../Rules + +-ifeq (yes,$(have-ssp)) +-CFLAGS-libresolv += -fstack-protector +-endif +-ifeq (yes,$(have-ssp-strong)) + CFLAGS-libresolv += -fstack-protector-strong +-endif +- ++CFLAGS-libnss_dns += -fstack-protector-strong + CFLAGS-res_hconf.c = -fexceptions + +-# The BIND code elicits some harmless warnings. +-+cflags += -Wno-strict-prototypes -Wno-write-strings +- + # The DNS NSS modules needs the resolver. + $(objpfx)libnss_dns.so: $(objpfx)libresolv.so + +@@ -104,17 +137,45 @@ $(objpfx)tst-leaks: $(objpfx)libresolv.so + tst-leaks-ENV = MALLOC_TRACE=$(objpfx)tst-leaks.mtrace + $(objpfx)mtrace-tst-leaks: $(objpfx)tst-leaks.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks.mtrace > $@ +-ifeq ($(run-built-tests),yes) +-ifneq (no,$(PERL)) +-tests: $(objpfx)mtrace-tst-leaks +-endif +-endif + + tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace + $(objpfx)mtrace-tst-leaks2: $(objpfx)tst-leaks2.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@ +-ifeq ($(run-built-tests),yes) ++ ++tst-resolv-res_ninit-ENV = MALLOC_TRACE=$(objpfx)tst-resolv-res_ninit.mtrace ++$(objpfx)mtrace-tst-resolv-res_ninit: $(objpfx)tst-resolv-res_ninit.out ++ $(common-objpfx)malloc/mtrace \ ++ $(objpfx)tst-resolv-res_ninit.mtrace > $@ ++ + ifneq (no,$(PERL)) ++tests: $(objpfx)mtrace-tst-leaks $(objpfx)mtrace-tst-resolv-res_ninit + xtests: $(objpfx)mtrace-tst-leaks2 + endif +-endif ++ ++ ++$(objpfx)tst-bug18665-tcp: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-bug18665: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-res_use_inet6: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-basic: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-edns: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-network: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-res_init: $(libdl) $(objpfx)libresolv.so ++$(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \ ++ $(shared-thread-library) ++$(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \ ++ $(shared-thread-library) ++$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-threads: \ ++ $(libdl) $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-canonname: \ ++ $(libdl) $(objpfx)libresolv.so $(shared-thread-library) ++ ++$(objpfx)tst-ns_name: $(objpfx)libresolv.so ++$(objpfx)tst-ns_name.out: tst-ns_name.data ++$(objpfx)tst-ns_name_compress: $(objpfx)libresolv.so ++ ++ ++# This test case uses the deprecated RES_USE_INET6 resolver option. ++CFLAGS-tst-res_use_inet6.c += -Wno-error +diff --git a/resolv/README b/resolv/README +index 1a70bbb1dc615ac9..514e9bb617e710f1 100644 +--- a/resolv/README ++++ b/resolv/README +@@ -18,10 +18,6 @@ Differences + The resolver in the GNU C Library still differs from what's in BIND + 8.2.3-T5B: + +-* The resolver in glibc strictly adheres to the recommendations in RFC +- 1535. BIND 8.2.3-T5B seems to relax those rules a bit (see the code +- that's wrapped in `#ifndef RFC1535'). +- + * The RES_DEBUG option (`options debug' in /etc/resolv.conf) has been + disabled. + +@@ -62,7 +58,7 @@ the `gethostby*' family of functions, which means that for example + traditional resolver interfaces however, continue to use a single + resolver state and are therefore still thread-unsafe. The resolver + state is the same resolver state that is used for the initial ("main") +-thread. ++thread. + + This has the following consequences for existing binaries and source + code: +@@ -118,7 +114,6 @@ src/lib/resolv/ + res_comp.c + res_data.c + res_debug.c +- res_debug.h + res_init.c + res_mkquery.c + res_query.c +@@ -145,8 +140,7 @@ src/lib/isc/ + base64.c + + Some of these files have been optimised a bit, and adaptations have +-been made to make them fit in with the rest of glibc. The more +-non-obvious changes are wrapped in something like `#ifdef _LIBC'. ++been made to make them fit in with the rest of glibc. + + res_libc.c is home-brewn, although parts of it are taken from res_data.c. + +diff --git a/resolv/Versions b/resolv/Versions +index 24b07ef770ed3915..b05778d9654aa0f2 100644 +--- a/resolv/Versions ++++ b/resolv/Versions +@@ -1,5 +1,3 @@ +-%include +- + libc { + GLIBC_2.0 { + _res; +@@ -28,8 +26,12 @@ libc { + + __h_errno; __resp; + +- __res_maybe_init; __res_iclose; ++ __res_iclose; + __inet_pton_length; ++ __resolv_context_get; ++ __resolv_context_get_preinit; ++ __resolv_context_get_override; ++ __resolv_context_put; + } + } + +@@ -81,7 +83,9 @@ libresolv { + # Needed in libnss_dns. + __ns_name_unpack; __ns_name_ntop; + __ns_get16; __ns_get32; +- __libc_res_nquery; __libc_res_nsearch; ++ __res_context_query; ++ __res_context_search; ++ __res_context_hostalias; + } + } + +@@ -98,6 +102,6 @@ libnss_dns { + + libanl { + GLIBC_2.2.3 { +- getaddrinfo_a; gai_cancel; gai_error; gai_suspend; ++ gai_cancel; gai_error; gai_suspend; getaddrinfo_a; + } + } +diff --git a/resolv/arpa/nameser.h b/resolv/arpa/nameser.h +index 6a2c8376bd6565cb..a99d5ec508592486 100644 +--- a/resolv/arpa/nameser.h ++++ b/resolv/arpa/nameser.h +@@ -45,34 +45,13 @@ + * SOFTWARE. + */ + +-/* +- * $BINDId: nameser.h,v 8.37 2000/03/30 21:16:49 vixie Exp $ +- */ +- + #ifndef _ARPA_NAMESER_H_ + #define _ARPA_NAMESER_H_ + +-/*! \file */ +- +-#define BIND_4_COMPAT +- + #include +-#if (!defined(BSD)) || (BSD < 199306) +-# include +-#else +-# include +-#endif +-#include ++#include ++#include + +-/*% +- * Revision information. This is the release date in YYYYMMDD format. +- * It can change every day so the right thing to do with it is use it +- * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not +- * compare for equality; rather, use it to determine whether your libbind.a +- * contains a new enough lib/nameser/ to support the feature you need. +- */ +- +-#define __NAMESER 19991006 /*%< New interface version stamp. */ + /* + * Define constants based on RFC 883, RFC 1034, RFC 1035 + */ +@@ -84,9 +63,9 @@ + #define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ + #define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ + #define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ +-#define NS_INT32SZ 4 /*%< #/bytes of data in a u_int32_t */ +-#define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ +-#define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ ++#define NS_INT32SZ 4 /*%< #/bytes of data in a uint32_t */ ++#define NS_INT16SZ 2 /*%< #/bytes of data in a uint16_t */ ++#define NS_INT8SZ 1 /*%< #/bytes of data in a uint8_t */ + #define NS_INADDRSZ 4 /*%< IPv4 T_A */ + #define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ + #define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ +@@ -112,12 +91,12 @@ typedef enum __ns_sect { + * leading _'s on the member names. Use the accessor functions, not the _'s. + */ + typedef struct __ns_msg { +- const u_char *_msg, *_eom; +- u_int16_t _id, _flags, _counts[ns_s_max]; +- const u_char *_sections[ns_s_max]; +- ns_sect _sect; +- int _rrnum; +- const u_char *_msg_ptr; ++ const unsigned char *_msg, *_eom; ++ uint16_t _id, _flags, _counts[ns_s_max]; ++ const unsigned char *_sections[ns_s_max]; ++ ns_sect _sect; ++ int _rrnum; ++ const unsigned char *_msg_ptr; + } ns_msg; + + /* Private data structure - do not use from outside library. */ +@@ -136,12 +115,12 @@ extern const struct _ns_flagdata _ns_flagdata[]; + * This is a parsed record. It is caller allocated and has no dynamic data. + */ + typedef struct __ns_rr { +- char name[NS_MAXDNAME]; +- u_int16_t type; +- u_int16_t rr_class; +- u_int32_t ttl; +- u_int16_t rdlength; +- const u_char * rdata; ++ char name[NS_MAXDNAME]; ++ uint16_t type; ++ uint16_t rr_class; ++ uint32_t ttl; ++ uint16_t rdlength; ++ const unsigned char * rdata; + } ns_rr; + + /* Accessor macros - this is part of the public interface. */ +@@ -249,71 +228,97 @@ typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; + /*% + * Currently defined type values for resources and queries. + */ +-typedef enum __ns_type { +- ns_t_invalid = 0, /*%< Cookie. */ +- ns_t_a = 1, /*%< Host address. */ +- ns_t_ns = 2, /*%< Authoritative server. */ +- ns_t_md = 3, /*%< Mail destination. */ +- ns_t_mf = 4, /*%< Mail forwarder. */ +- ns_t_cname = 5, /*%< Canonical name. */ +- ns_t_soa = 6, /*%< Start of authority zone. */ +- ns_t_mb = 7, /*%< Mailbox domain name. */ +- ns_t_mg = 8, /*%< Mail group member. */ +- ns_t_mr = 9, /*%< Mail rename name. */ +- ns_t_null = 10, /*%< Null resource record. */ +- ns_t_wks = 11, /*%< Well known service. */ +- ns_t_ptr = 12, /*%< Domain name pointer. */ +- ns_t_hinfo = 13, /*%< Host information. */ +- ns_t_minfo = 14, /*%< Mailbox information. */ +- ns_t_mx = 15, /*%< Mail routing information. */ +- ns_t_txt = 16, /*%< Text strings. */ +- ns_t_rp = 17, /*%< Responsible person. */ +- ns_t_afsdb = 18, /*%< AFS cell database. */ +- ns_t_x25 = 19, /*%< X_25 calling address. */ +- ns_t_isdn = 20, /*%< ISDN calling address. */ +- ns_t_rt = 21, /*%< Router. */ +- ns_t_nsap = 22, /*%< NSAP address. */ +- ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ +- ns_t_sig = 24, /*%< Security signature. */ +- ns_t_key = 25, /*%< Security key. */ +- ns_t_px = 26, /*%< X.400 mail mapping. */ +- ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ +- ns_t_aaaa = 28, /*%< Ip6 Address. */ +- ns_t_loc = 29, /*%< Location Information. */ +- ns_t_nxt = 30, /*%< Next domain (security). */ +- ns_t_eid = 31, /*%< Endpoint identifier. */ +- ns_t_nimloc = 32, /*%< Nimrod Locator. */ +- ns_t_srv = 33, /*%< Server Selection. */ +- ns_t_atma = 34, /*%< ATM Address */ +- ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ +- ns_t_kx = 36, /*%< Key Exchange */ +- ns_t_cert = 37, /*%< Certification record */ +- ns_t_a6 = 38, /*%< IPv6 address (deprecated, use ns_t_aaaa) */ +- ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */ +- ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ +- ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ +- ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ +- ns_t_tkey = 249, /*%< Transaction key */ +- ns_t_tsig = 250, /*%< Transaction signature. */ +- ns_t_ixfr = 251, /*%< Incremental zone transfer. */ +- ns_t_axfr = 252, /*%< Transfer zone of authority. */ +- ns_t_mailb = 253, /*%< Transfer mailbox records. */ +- ns_t_maila = 254, /*%< Transfer mail agent records. */ +- ns_t_any = 255, /*%< Wildcard match. */ +- ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ +- ns_t_max = 65536 +-} ns_type; +- +-/* Exclusively a QTYPE? (not also an RTYPE) */ +-#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \ +- (t) == ns_t_mailb || (t) == ns_t_maila) +-/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */ +-#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt) +-/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */ +-#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t)) +-#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr) +-#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \ +- (t) == ns_t_zxfr) ++typedef enum __ns_type ++ { ++ ns_t_invalid = 0, ++ ++ ns_t_a = 1, ++ ns_t_ns = 2, ++ ns_t_md = 3, ++ ns_t_mf = 4, ++ ns_t_cname = 5, ++ ns_t_soa = 6, ++ ns_t_mb = 7, ++ ns_t_mg = 8, ++ ns_t_mr = 9, ++ ns_t_null = 10, ++ ns_t_wks = 11, ++ ns_t_ptr = 12, ++ ns_t_hinfo = 13, ++ ns_t_minfo = 14, ++ ns_t_mx = 15, ++ ns_t_txt = 16, ++ ns_t_rp = 17, ++ ns_t_afsdb = 18, ++ ns_t_x25 = 19, ++ ns_t_isdn = 20, ++ ns_t_rt = 21, ++ ns_t_nsap = 22, ++ ns_t_nsap_ptr = 23, ++ ns_t_sig = 24, ++ ns_t_key = 25, ++ ns_t_px = 26, ++ ns_t_gpos = 27, ++ ns_t_aaaa = 28, ++ ns_t_loc = 29, ++ ns_t_nxt = 30, ++ ns_t_eid = 31, ++ ns_t_nimloc = 32, ++ ns_t_srv = 33, ++ ns_t_atma = 34, ++ ns_t_naptr = 35, ++ ns_t_kx = 36, ++ ns_t_cert = 37, ++ ns_t_a6 = 38, ++ ns_t_dname = 39, ++ ns_t_sink = 40, ++ ns_t_opt = 41, ++ ns_t_apl = 42, ++ ns_t_ds = 43, ++ ns_t_sshfp = 44, ++ ns_t_ipseckey = 45, ++ ns_t_rrsig = 46, ++ ns_t_nsec = 47, ++ ns_t_dnskey = 48, ++ ns_t_dhcid = 49, ++ ns_t_nsec3 = 50, ++ ns_t_nsec3param = 51, ++ ns_t_tlsa = 52, ++ ns_t_smimea = 53, ++ ns_t_hip = 55, ++ ns_t_ninfo = 56, ++ ns_t_rkey = 57, ++ ns_t_talink = 58, ++ ns_t_cds = 59, ++ ns_t_cdnskey = 60, ++ ns_t_openpgpkey = 61, ++ ns_t_csync = 62, ++ ns_t_spf = 99, ++ ns_t_uinfo = 100, ++ ns_t_uid = 101, ++ ns_t_gid = 102, ++ ns_t_unspec = 103, ++ ns_t_nid = 104, ++ ns_t_l32 = 105, ++ ns_t_l64 = 106, ++ ns_t_lp = 107, ++ ns_t_eui48 = 108, ++ ns_t_eui64 = 109, ++ ns_t_tkey = 249, ++ ns_t_tsig = 250, ++ ns_t_ixfr = 251, ++ ns_t_axfr = 252, ++ ns_t_mailb = 253, ++ ns_t_maila = 254, ++ ns_t_any = 255, ++ ns_t_uri = 256, ++ ns_t_caa = 257, ++ ns_t_avc = 258, ++ ns_t_ta = 32768, ++ ns_t_dlv = 32769, ++ ++ ns_t_max = 65536 ++ } ns_type; + + /*% + * Values for class field +@@ -330,15 +335,7 @@ typedef enum __ns_class { + ns_c_max = 65536 + } ns_class; + +-/* DNSSEC constants. */ +- +-typedef enum __ns_key_types { +- ns_kt_rsa = 1, /*%< key type RSA/MD5 */ +- ns_kt_dh = 2, /*%< Diffie Hellman */ +- ns_kt_dsa = 3, /*%< Digital Signature Standard (MANDATORY) */ +- ns_kt_private = 254 /*%< Private key type starts with OID */ +-} ns_key_types; +- ++/* Certificate type values in CERT resource records. */ + typedef enum __ns_cert_types { + cert_t_pkix = 1, /*%< PKIX (X.509v3) */ + cert_t_spki = 2, /*%< SPKI */ +@@ -347,82 +344,6 @@ typedef enum __ns_cert_types { + cert_t_oid = 254 /*%< OID private type */ + } ns_cert_types; + +-/* Flags field of the KEY RR rdata. */ +-#define NS_KEY_TYPEMASK 0xC000 /*%< Mask for "type" bits */ +-#define NS_KEY_TYPE_AUTH_CONF 0x0000 /*%< Key usable for both */ +-#define NS_KEY_TYPE_CONF_ONLY 0x8000 /*%< Key usable for confidentiality */ +-#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /*%< Key usable for authentication */ +-#define NS_KEY_TYPE_NO_KEY 0xC000 /*%< No key usable for either; no key */ +-/* The type bits can also be interpreted independently, as single bits: */ +-#define NS_KEY_NO_AUTH 0x8000 /*%< Key unusable for authentication */ +-#define NS_KEY_NO_CONF 0x4000 /*%< Key unusable for confidentiality */ +-#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */ +-#define NS_KEY_EXTENDED_FLAGS 0x1000 /*%< reserved - must be zero */ +-#define NS_KEY_RESERVED4 0x0800 /*%< reserved - must be zero */ +-#define NS_KEY_RESERVED5 0x0400 /*%< reserved - must be zero */ +-#define NS_KEY_NAME_TYPE 0x0300 /*%< these bits determine the type */ +-#define NS_KEY_NAME_USER 0x0000 /*%< key is assoc. with user */ +-#define NS_KEY_NAME_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ +-#define NS_KEY_NAME_ZONE 0x0100 /*%< key is zone key */ +-#define NS_KEY_NAME_RESERVED 0x0300 /*%< reserved meaning */ +-#define NS_KEY_RESERVED8 0x0080 /*%< reserved - must be zero */ +-#define NS_KEY_RESERVED9 0x0040 /*%< reserved - must be zero */ +-#define NS_KEY_RESERVED10 0x0020 /*%< reserved - must be zero */ +-#define NS_KEY_RESERVED11 0x0010 /*%< reserved - must be zero */ +-#define NS_KEY_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ +-#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \ +- NS_KEY_RESERVED4 | \ +- NS_KEY_RESERVED5 | \ +- NS_KEY_RESERVED8 | \ +- NS_KEY_RESERVED9 | \ +- NS_KEY_RESERVED10 | \ +- NS_KEY_RESERVED11 ) +-#define NS_KEY_RESERVED_BITMASK2 0xFFFF /*%< no bits defined here */ +-/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ +-#define NS_ALG_MD5RSA 1 /*%< MD5 with RSA */ +-#define NS_ALG_DH 2 /*%< Diffie Hellman KEY */ +-#define NS_ALG_DSA 3 /*%< DSA KEY */ +-#define NS_ALG_DSS NS_ALG_DSA +-#define NS_ALG_EXPIRE_ONLY 253 /*%< No alg, no security */ +-#define NS_ALG_PRIVATE_OID 254 /*%< Key begins with OID giving alg */ +-/* Protocol values */ +-/* value 0 is reserved */ +-#define NS_KEY_PROT_TLS 1 +-#define NS_KEY_PROT_EMAIL 2 +-#define NS_KEY_PROT_DNSSEC 3 +-#define NS_KEY_PROT_IPSEC 4 +-#define NS_KEY_PROT_ANY 255 +- +-/* Signatures */ +-#define NS_MD5RSA_MIN_BITS 512 /*%< Size of a mod or exp in bits */ +-#define NS_MD5RSA_MAX_BITS 4096 +- /* Total of binary mod and exp */ +-#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3) +- /* Max length of text sig block */ +-#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4) +-#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8) +-#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8) +- +-#define NS_DSA_SIG_SIZE 41 +-#define NS_DSA_MIN_SIZE 213 +-#define NS_DSA_MAX_BYTES 405 +- +-/* Offsets into SIG record rdata to find various values */ +-#define NS_SIG_TYPE 0 /*%< Type flags */ +-#define NS_SIG_ALG 2 /*%< Algorithm */ +-#define NS_SIG_LABELS 3 /*%< How many labels in name */ +-#define NS_SIG_OTTL 4 /*%< Original TTL */ +-#define NS_SIG_EXPIR 8 /*%< Expiration time */ +-#define NS_SIG_SIGNED 12 /*%< Signature time */ +-#define NS_SIG_FOOT 16 /*%< Key footprint */ +-#define NS_SIG_SIGNER 18 /*%< Domain name of who signed it */ +-/* How RR types are represented as bit-flags in NXT records */ +-#define NS_NXT_BITS 8 +-#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS))) +-#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS))) +-#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS))) +-#define NS_NXT_MAX 127 +- + /*% + * EDNS0 extended flags and option codes, host order. + */ +@@ -433,34 +354,34 @@ typedef enum __ns_cert_types { + * Inline versions of get/put short/long. Pointer is advanced. + */ + #define NS_GET16(s, cp) do { \ +- register const u_char *t_cp = (const u_char *)(cp); \ +- (s) = ((u_int16_t)t_cp[0] << 8) \ +- | ((u_int16_t)t_cp[1]) \ ++ const unsigned char *t_cp = (const unsigned char *)(cp); \ ++ (s) = ((uint16_t)t_cp[0] << 8) \ ++ | ((uint16_t)t_cp[1]) \ + ; \ + (cp) += NS_INT16SZ; \ + } while (0) + + #define NS_GET32(l, cp) do { \ +- register const u_char *t_cp = (const u_char *)(cp); \ +- (l) = ((u_int32_t)t_cp[0] << 24) \ +- | ((u_int32_t)t_cp[1] << 16) \ +- | ((u_int32_t)t_cp[2] << 8) \ +- | ((u_int32_t)t_cp[3]) \ ++ const unsigned char *t_cp = (const unsigned char *)(cp); \ ++ (l) = ((uint32_t)t_cp[0] << 24) \ ++ | ((uint32_t)t_cp[1] << 16) \ ++ | ((uint32_t)t_cp[2] << 8) \ ++ | ((uint32_t)t_cp[3]) \ + ; \ + (cp) += NS_INT32SZ; \ + } while (0) + + #define NS_PUT16(s, cp) do { \ +- register u_int16_t t_s = (u_int16_t)(s); \ +- register u_char *t_cp = (u_char *)(cp); \ ++ uint16_t t_s = (uint16_t)(s); \ ++ unsigned char *t_cp = (unsigned char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += NS_INT16SZ; \ + } while (0) + + #define NS_PUT32(l, cp) do { \ +- register u_int32_t t_l = (u_int32_t)(l); \ +- register u_char *t_cp = (u_char *)(cp); \ ++ uint32_t t_l = (uint32_t)(l); \ ++ unsigned char *t_cp = (unsigned char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ +@@ -470,66 +391,53 @@ typedef enum __ns_cert_types { + + __BEGIN_DECLS + int ns_msg_getflag (ns_msg, int) __THROW; +-u_int ns_get16 (const u_char *) __THROW; +-u_long ns_get32 (const u_char *) __THROW; +-void ns_put16 (u_int, u_char *) __THROW; +-void ns_put32 (u_long, u_char *) __THROW; +-int ns_initparse (const u_char *, int, ns_msg *) __THROW; +-int ns_skiprr (const u_char *, const u_char *, ns_sect, int) +- __THROW; ++unsigned int ns_get16 (const unsigned char *) __THROW; ++unsigned long ns_get32 (const unsigned char *) __THROW; ++void ns_put16 (unsigned int, unsigned char *) __THROW; ++void ns_put32 (unsigned long, unsigned char *) __THROW; ++int ns_initparse (const unsigned char *, int, ns_msg *) __THROW; ++int ns_skiprr (const unsigned char *, const unsigned char *, ++ ns_sect, int) __THROW; + int ns_parserr (ns_msg *, ns_sect, int, ns_rr *) __THROW; + int ns_sprintrr (const ns_msg *, const ns_rr *, + const char *, const char *, char *, size_t) + __THROW; +-int ns_sprintrrf (const u_char *, size_t, const char *, +- ns_class, ns_type, u_long, const u_char *, +- size_t, const char *, const char *, +- char *, size_t) __THROW; +-int ns_format_ttl (u_long, char *, size_t) __THROW; +-int ns_parse_ttl (const char *, u_long *) __THROW; +-u_int32_t ns_datetosecs (const char *, int *) __THROW; +-int ns_name_ntol (const u_char *, u_char *, size_t) __THROW; +-int ns_name_ntop (const u_char *, char *, size_t) __THROW; +-int ns_name_pton (const char *, u_char *, size_t) __THROW; +-int ns_name_unpack (const u_char *, const u_char *, +- const u_char *, u_char *, size_t) __THROW; +-int ns_name_pack (const u_char *, u_char *, int, +- const u_char **, const u_char **) __THROW; +-int ns_name_uncompress (const u_char *, const u_char *, +- const u_char *, char *, size_t) __THROW; +-int ns_name_compress (const char *, u_char *, size_t, +- const u_char **, const u_char **) __THROW; +-int ns_name_skip (const u_char **, const u_char *) __THROW; +-void ns_name_rollback (const u_char *, const u_char **, +- const u_char **) __THROW; +-int ns_sign (u_char *, int *, int, int, void *, +- const u_char *, int, u_char *, int *, time_t) __THROW; +-int ns_sign2 (u_char *, int *, int, int, void *, +- const u_char *, int, u_char *, int *, time_t, +- u_char **, u_char **) __THROW; +-int ns_sign_tcp (u_char *, int *, int, int, +- ns_tcp_tsig_state *, int) __THROW; +-int ns_sign_tcp2 (u_char *, int *, int, int, +- ns_tcp_tsig_state *, int, +- u_char **, u_char **) __THROW; +-int ns_sign_tcp_init (void *, const u_char *, int, +- ns_tcp_tsig_state *) __THROW; +-u_char *ns_find_tsig (u_char *, u_char *) __THROW; +-int ns_verify (u_char *, int *, void *, const u_char *, int, +- u_char *, int *, time_t *, int) __THROW; +-int ns_verify_tcp (u_char *, int *, ns_tcp_tsig_state *, int) ++int ns_sprintrrf (const unsigned char *, size_t, const char *, ++ ns_class, ns_type, unsigned long, ++ const unsigned char *, size_t, const char *, ++ const char *, char *, size_t) __THROW; ++int ns_format_ttl (unsigned long, char *, size_t) __THROW; ++int ns_parse_ttl (const char *, unsigned long *) __THROW; ++uint32_t ns_datetosecs (const char *, int *) __THROW; ++int ns_name_ntol (const unsigned char *, unsigned char *, size_t) ++ __THROW; ++int ns_name_ntop (const unsigned char *, char *, size_t) __THROW; ++int ns_name_pton (const char *, unsigned char *, size_t) __THROW; ++int ns_name_unpack (const unsigned char *, const unsigned char *, ++ const unsigned char *, unsigned char *, size_t) ++ __THROW; ++int ns_name_pack (const unsigned char *, unsigned char *, int, ++ const unsigned char **, const unsigned char **) ++ __THROW; ++int ns_name_uncompress (const unsigned char *, ++ const unsigned char *, ++ const unsigned char *, ++ char *, size_t) __THROW; ++int ns_name_compress (const char *, unsigned char *, size_t, ++ const unsigned char **, ++ const unsigned char **) __THROW; ++int ns_name_skip (const unsigned char **, const unsigned char *) + __THROW; +-int ns_verify_tcp_init (void *, const u_char *, int, +- ns_tcp_tsig_state *) __THROW; ++void ns_name_rollback (const unsigned char *, ++ const unsigned char **, ++ const unsigned char **) __THROW; + int ns_samedomain (const char *, const char *) __THROW; + int ns_subdomain (const char *, const char *) __THROW; + int ns_makecanon (const char *, char *, size_t) __THROW; + int ns_samename (const char *, const char *) __THROW; + __END_DECLS + +-#ifdef BIND_4_COMPAT + #include +-#endif + + #endif /* !_ARPA_NAMESER_H_ */ + /*! \file */ +diff --git a/resolv/arpa/nameser_compat.h b/resolv/arpa/nameser_compat.h +index d59c9e41b3a5c45c..f1c390f3b918b547 100644 +--- a/resolv/arpa/nameser_compat.h ++++ b/resolv/arpa/nameser_compat.h +@@ -26,16 +26,9 @@ + * SUCH DAMAGE. + */ + +-/*% +- * from nameser.h 8.1 (Berkeley) 6/2/93 +- * $BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $ +- */ +- + #ifndef _ARPA_NAMESER_COMPAT_ + #define _ARPA_NAMESER_COMPAT_ + +-#define __BIND 19950621 /*%< (DEAD) interface version stamp. */ +- + #include + + /*% +@@ -47,7 +40,7 @@ + + typedef struct { + unsigned id :16; /*%< query identification number */ +-#if BYTE_ORDER == BIG_ENDIAN ++#if __BYTE_ORDER == __BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /*%< response flag */ + unsigned opcode: 4; /*%< purpose of message */ +@@ -61,7 +54,7 @@ typedef struct { + unsigned cd: 1; /*%< checking disabled by resolver */ + unsigned rcode :4; /*%< response code */ + #endif +-#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN ++#if __BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /*%< recursion desired */ + unsigned tc :1; /*%< truncated message */ +@@ -127,49 +120,90 @@ typedef struct { + #define DELETE ns_uop_delete + #define ADD ns_uop_add + +-#define T_A ns_t_a +-#define T_NS ns_t_ns +-#define T_MD ns_t_md +-#define T_MF ns_t_mf +-#define T_CNAME ns_t_cname +-#define T_SOA ns_t_soa +-#define T_MB ns_t_mb +-#define T_MG ns_t_mg +-#define T_MR ns_t_mr +-#define T_NULL ns_t_null +-#define T_WKS ns_t_wks +-#define T_PTR ns_t_ptr +-#define T_HINFO ns_t_hinfo +-#define T_MINFO ns_t_minfo +-#define T_MX ns_t_mx +-#define T_TXT ns_t_txt +-#define T_RP ns_t_rp +-#define T_AFSDB ns_t_afsdb +-#define T_X25 ns_t_x25 +-#define T_ISDN ns_t_isdn +-#define T_RT ns_t_rt +-#define T_NSAP ns_t_nsap +-#define T_NSAP_PTR ns_t_nsap_ptr +-#define T_SIG ns_t_sig +-#define T_KEY ns_t_key +-#define T_PX ns_t_px +-#define T_GPOS ns_t_gpos +-#define T_AAAA ns_t_aaaa +-#define T_LOC ns_t_loc +-#define T_NXT ns_t_nxt +-#define T_EID ns_t_eid +-#define T_NIMLOC ns_t_nimloc +-#define T_SRV ns_t_srv +-#define T_ATMA ns_t_atma +-#define T_NAPTR ns_t_naptr +-#define T_A6 ns_t_a6 +-#define T_DNAME ns_t_dname +-#define T_TSIG ns_t_tsig +-#define T_IXFR ns_t_ixfr +-#define T_AXFR ns_t_axfr +-#define T_MAILB ns_t_mailb +-#define T_MAILA ns_t_maila +-#define T_ANY ns_t_any ++#define T_A ns_t_a ++#define T_NS ns_t_ns ++#define T_MD ns_t_md ++#define T_MF ns_t_mf ++#define T_CNAME ns_t_cname ++#define T_SOA ns_t_soa ++#define T_MB ns_t_mb ++#define T_MG ns_t_mg ++#define T_MR ns_t_mr ++#define T_NULL ns_t_null ++#define T_WKS ns_t_wks ++#define T_PTR ns_t_ptr ++#define T_HINFO ns_t_hinfo ++#define T_MINFO ns_t_minfo ++#define T_MX ns_t_mx ++#define T_TXT ns_t_txt ++#define T_RP ns_t_rp ++#define T_AFSDB ns_t_afsdb ++#define T_X25 ns_t_x25 ++#define T_ISDN ns_t_isdn ++#define T_RT ns_t_rt ++#define T_NSAP ns_t_nsap ++#define T_NSAP_PTR ns_t_nsap_ptr ++#define T_SIG ns_t_sig ++#define T_KEY ns_t_key ++#define T_PX ns_t_px ++#define T_GPOS ns_t_gpos ++#define T_AAAA ns_t_aaaa ++#define T_LOC ns_t_loc ++#define T_NXT ns_t_nxt ++#define T_EID ns_t_eid ++#define T_NIMLOC ns_t_nimloc ++#define T_SRV ns_t_srv ++#define T_ATMA ns_t_atma ++#define T_NAPTR ns_t_naptr ++#define T_KX ns_t_kx ++#define T_CERT ns_t_cert ++#define T_A6 ns_t_a6 ++#define T_DNAME ns_t_dname ++#define T_SINK ns_t_sink ++#define T_OPT ns_t_opt ++#define T_APL ns_t_apl ++#define T_DS ns_t_ds ++#define T_SSHFP ns_t_sshfp ++#define T_IPSECKEY ns_t_ipseckey ++#define T_RRSIG ns_t_rrsig ++#define T_NSEC ns_t_nsec ++#define T_DNSKEY ns_t_dnskey ++#define T_DHCID ns_t_dhcid ++#define T_NSEC3 ns_t_nsec3 ++#define T_NSEC3PARAM ns_t_nsec3param ++#define T_TLSA ns_t_tlsa ++#define T_SMIMEA ns_t_smimea ++#define T_HIP ns_t_hip ++#define T_NINFO ns_t_ninfo ++#define T_RKEY ns_t_rkey ++#define T_TALINK ns_t_talink ++#define T_CDS ns_t_cds ++#define T_CDNSKEY ns_t_cdnskey ++#define T_OPENPGPKEY ns_t_openpgpkey ++#define T_CSYNC ns_t_csync ++#define T_SPF ns_t_spf ++#define T_UINFO ns_t_uinfo ++#define T_UID ns_t_uid ++#define T_GID ns_t_gid ++#define T_UNSPEC ns_t_unspec ++#define T_NID ns_t_nid ++#define T_L32 ns_t_l32 ++#define T_L64 ns_t_l64 ++#define T_LP ns_t_lp ++#define T_EUI48 ns_t_eui48 ++#define T_EUI64 ns_t_eui64 ++#define T_TKEY ns_t_tkey ++#define T_TSIG ns_t_tsig ++#define T_IXFR ns_t_ixfr ++#define T_AXFR ns_t_axfr ++#define T_MAILB ns_t_mailb ++#define T_MAILA ns_t_maila ++#define T_ANY ns_t_any ++#define T_URI ns_t_uri ++#define T_CAA ns_t_caa ++#define T_AVC ns_t_avc ++#define T_TA ns_t_ta ++#define T_DLV ns_t_dlv + + #define C_IN ns_c_in + #define C_CHAOS ns_c_chaos +diff --git a/resolv/base64.c b/resolv/base64.c +index ea584ed357f02a66..fedc086b0c1b28a0 100644 +--- a/resolv/base64.c ++++ b/resolv/base64.c +@@ -40,10 +40,6 @@ + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +-#if !defined(LINT) && !defined(CODECENTER) +-static const char rcsid[] = "$BINDId: base64.c,v 8.7 1999/10/13 16:39:33 vixie Exp $"; +-#endif /* not lint */ +- + #include + #include + #include +@@ -195,10 +191,7 @@ libresolv_hidden_def (b64_ntop) + */ + + int +-b64_pton(src, target, targsize) +- char const *src; +- u_char *target; +- size_t targsize; ++b64_pton (char const *src, u_char *target, size_t targsize) + { + int tarindex, state, ch; + char *pos; +diff --git a/resolv/gethnamaddr.c b/resolv/compat-gethnamaddr.c +similarity index 74% +rename from resolv/gethnamaddr.c +rename to resolv/compat-gethnamaddr.c +index bea3ec588cf60991..259378b2be2d5f63 100644 +--- a/resolv/gethnamaddr.c ++++ b/resolv/compat-gethnamaddr.c +@@ -49,54 +49,32 @@ + * --Copyright-- + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; +-#endif /* LIBC_SCCS and not lint */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define RESOLVSORT +- +-#ifndef LOG_AUTH +-# define LOG_AUTH 0 +-#endif +- +-#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ +- +-#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) ++/* XXX This file is not used by any of the resolver functions implemented by ++ glibc (i.e. get*info and gethostby*). It cannot be removed however because ++ it exports symbols in the libresolv ABI. The file is not maintained any ++ more, nor are these functions. */ ++ ++#include ++#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_25) ++ ++# include ++# include ++# include ++# include ++# include ++# include ++ ++# include ++# include ++# include ++# include ++# include ++# include + # include + # include +-#else +-# include "../conf/portability.h" +-#endif + +-#if defined(USE_OPTIONS_H) +-# include <../conf/options.h> +-#endif +- +-#ifdef SPRINTF_CHAR +-# define SPRINTF(x) strlen(sprintf/**/x) +-#else +-# define SPRINTF(x) ((size_t)sprintf x) +-#endif +- +-#define MAXALIASES 35 +-#define MAXADDRS 35 +- +-static const char AskedForGot[] = +- "gethostby*.getanswer: asked for \"%s\", got \"%s\""; ++# define MAXALIASES 35 ++# define MAXADDRS 35 + + static char *h_addr_ptrs[MAXADDRS + 1]; + +@@ -107,24 +85,25 @@ static u_char host_addr[16]; /* IPv4 or IPv6 */ + static FILE *hostf = NULL; + static int stayopen = 0; + ++static struct hostent *res_gethostbyname2_context (struct resolv_context *, ++ const char *name, int af); ++ + static void map_v4v6_address (const char *src, char *dst) __THROW; + static void map_v4v6_hostent (struct hostent *hp, char **bp, int *len) __THROW; + +-#ifdef RESOLVSORT + extern void addrsort (char **, int) __THROW; +-#endif + +-#if PACKETSZ > 65536 +-#define MAXPACKET PACKETSZ +-#else +-#define MAXPACKET 65536 +-#endif ++# if PACKETSZ > 65536 ++# define MAXPACKET PACKETSZ ++# else ++# define MAXPACKET 65536 ++# endif + + /* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length. */ +-#ifdef MAXHOSTNAMELEN +-# undef MAXHOSTNAMELEN +-#endif +-#define MAXHOSTNAMELEN 256 ++# ifdef MAXHOSTNAMELEN ++# undef MAXHOSTNAMELEN ++# endif ++# define MAXHOSTNAMELEN 256 + + typedef union { + HEADER hdr; +@@ -136,15 +115,13 @@ typedef union { + char ac; + } align; + +-#ifndef h_errno ++# ifndef h_errno + extern int h_errno; +-#endif ++# endif + +-#ifdef DEBUG ++# ifdef DEBUG + static void +-Dprintf(msg, num) +- char *msg; +- int num; ++Dprintf (char *msg, int num) + { + if (_res.options & RES_DEBUG) { + int save = errno; +@@ -153,11 +130,11 @@ Dprintf(msg, num) + __set_errno (save); + } + } +-#else +-# define Dprintf(msg, num) /*nada*/ +-#endif ++# else ++# define Dprintf(msg, num) /*nada*/ ++# endif + +-#define BOUNDED_INCR(x) \ ++# define BOUNDED_INCR(x) \ + do { \ + cp += x; \ + if (cp > eom) { \ +@@ -166,7 +143,7 @@ Dprintf(msg, num) + } \ + } while (0) + +-#define BOUNDS_CHECK(ptr, count) \ ++# define BOUNDS_CHECK(ptr, count) \ + do { \ + if ((ptr) + (count) > eom) { \ + __set_h_errno (NO_RECOVERY); \ +@@ -178,9 +155,9 @@ Dprintf(msg, num) + static struct hostent * + getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + { +- register const HEADER *hp; +- register const u_char *cp; +- register int n; ++ const HEADER *hp; ++ const u_char *cp; ++ int n; + const u_char *eom, *erdata; + char *bp, **ap, **hap; + int type, class, buflen, ancount, qdcount; +@@ -332,20 +309,12 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + * uses many different types in responses that do not + * match QTYPE. + */ +- if ((_res.options & RES_USE_DNSSEC) == 0) { +- syslog(LOG_NOTICE|LOG_AUTH, +- "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", +- qname, p_class(C_IN), p_type(qtype), +- p_type(type)); +- } + cp += n; + continue; /* XXX - had_error++ ? */ + } + switch (type) { + case T_PTR: + if (strcasecmp(tname, bp) != 0) { +- syslog(LOG_NOTICE|LOG_AUTH, +- AskedForGot, qname, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } +@@ -354,7 +323,6 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + had_error++; + break; + } +-#if MULTI_PTRS_ARE_ALIASES + cp += n; + if (cp != erdata) { + __set_h_errno (NO_RECOVERY); +@@ -376,26 +344,9 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + buflen -= n; + } + break; +-#else +- host.h_name = bp; +- if (_res.options & RES_USE_INET6) { +- n = strlen(bp) + 1; /* for the \0 */ +- if (n >= MAXHOSTNAMELEN) { +- had_error++; +- break; +- } +- bp += n; +- buflen -= n; +- map_v4v6_hostent(&host, &bp, &buflen); +- } +- __set_h_errno (NETDB_SUCCESS); +- return (&host); +-#endif + case T_A: + case T_AAAA: + if (strcasecmp(host.h_name, bp) != 0) { +- syslog(LOG_NOTICE|LOG_AUTH, +- AskedForGot, host.h_name, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } +@@ -404,7 +355,7 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + continue; + } + if (!haveanswer) { +- register int nn; ++ int nn; + + host.h_name = bp; + nn = strlen(bp) + 1; /* for the \0 */ +@@ -449,7 +400,6 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + if (haveanswer) { + *ap = NULL; + *hap = NULL; +-# if defined(RESOLVSORT) + /* + * Note: we sort even if host can take only one address + * in its return structures - should give it the "best" +@@ -457,7 +407,6 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + */ + if (_res.nsort && haveanswer > 1 && qtype == T_A) + addrsort(h_addr_ptrs, haveanswer); +-# endif /*RESOLVSORT*/ + if (!host.h_name) { + n = strlen(qname) + 1; /* for the \0 */ + if (n > buflen || n >= MAXHOSTNAMELEN) +@@ -467,7 +416,7 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + bp += n; + buflen -= n; + } +- if (_res.options & RES_USE_INET6) ++ if (res_use_inet6 ()) + map_v4v6_hostent(&host, &bp, &buflen); + __set_h_errno (NETDB_SUCCESS); + return (&host); +@@ -477,31 +426,37 @@ getanswer (const querybuf *answer, int anslen, const char *qname, int qtype) + return (NULL); + } + +-extern struct hostent *gethostbyname2(const char *name, int af); +-libresolv_hidden_proto (gethostbyname2) ++extern struct hostent *res_gethostbyname2(const char *name, int af); ++libresolv_hidden_proto (res_gethostbyname2) + + struct hostent * +-gethostbyname(name) +- const char *name; ++res_gethostbyname (const char *name) + { +- struct hostent *hp; +- +- if (__res_maybe_init (&_res, 0) == -1) { +- __set_h_errno (NETDB_INTERNAL); +- return (NULL); +- } +- if (_res.options & RES_USE_INET6) { +- hp = gethostbyname2(name, AF_INET6); +- if (hp) +- return (hp); ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ __set_h_errno (NETDB_INTERNAL); ++ return NULL; ++ } ++ ++ if (res_use_inet6 ()) ++ { ++ struct hostent *hp = res_gethostbyname2_context (ctx, name, AF_INET6); ++ if (hp != NULL) ++ { ++ __resolv_context_put (ctx); ++ return hp; + } +- return (gethostbyname2(name, AF_INET)); ++ } ++ struct hostent *hp = res_gethostbyname2_context (ctx, name, AF_INET); ++ __resolv_context_put (ctx); ++ return hp; + } ++compat_symbol (libresolv, res_gethostbyname, res_gethostbyname, GLIBC_2_0); + +-struct hostent * +-gethostbyname2(name, af) +- const char *name; +- int af; ++static struct hostent * ++res_gethostbyname2_context (struct resolv_context *ctx, ++ const char *name, int af) + { + union + { +@@ -509,16 +464,11 @@ gethostbyname2(name, af) + u_char *ptr; + } buf; + querybuf *origbuf; +- register const char *cp; ++ const char *cp; + char *bp; + int n, size, type, len; + struct hostent *ret; + +- if (__res_maybe_init (&_res, 0) == -1) { +- __set_h_errno (NETDB_INTERNAL); +- return (NULL); +- } +- + switch (af) { + case AF_INET: + size = INADDRSZ; +@@ -542,8 +492,10 @@ gethostbyname2(name, af) + * this is also done in res_query() since we are not the only + * function that looks up host names. + */ +- if (!strchr(name, '.') && (cp = __hostalias(name))) +- name = cp; ++ char abuf[MAXDNAME]; ++ if (strchr (name, '.') != NULL ++ && (cp = __res_context_hostalias (ctx, name, abuf, sizeof (abuf)))) ++ name = cp; + + /* + * disallow names consisting only of digits/dots, unless +@@ -573,7 +525,7 @@ gethostbyname2(name, af) + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + host.h_addr_list = h_addr_ptrs; +- if (_res.options & RES_USE_INET6) ++ if (res_use_inet6 ()) + map_v4v6_hostent(&host, &bp, &len); + __set_h_errno (NETDB_SUCCESS); + return (&host); +@@ -615,8 +567,9 @@ gethostbyname2(name, af) + + buf.buf = origbuf = (querybuf *) alloca (1024); + +- if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, +- &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { ++ if ((n = __res_context_search ++ (ctx, name, C_IN, type, buf.buf->buf, 1024, ++ &buf.ptr, NULL, NULL, NULL, NULL)) < 0) { + if (buf.buf != origbuf) + free (buf.buf); + Dprintf("res_nsearch failed (%d)\n", n); +@@ -629,13 +582,26 @@ gethostbyname2(name, af) + free (buf.buf); + return ret; + } +-libresolv_hidden_def (gethostbyname2) + + struct hostent * +-gethostbyaddr(addr, len, af) +- const void *addr; +- socklen_t len; +- int af; ++res_gethostbyname2 (const char *name, int af) ++{ ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ __set_h_errno (NETDB_INTERNAL); ++ return NULL; ++ } ++ struct hostent *hp = res_gethostbyname2_context (ctx, name, AF_INET); ++ __resolv_context_put (ctx); ++ return hp; ++} ++libresolv_hidden_def (res_gethostbyname2) ++compat_symbol (libresolv, res_gethostbyname2, res_gethostbyname2, GLIBC_2_0); ++ ++static struct hostent * ++res_gethostbyaddr_context (struct resolv_context *ctx, ++ const void *addr, socklen_t len, int af) + { + const u_char *uaddr = (const u_char *)addr; + static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; +@@ -648,22 +614,12 @@ gethostbyaddr(addr, len, af) + u_char *ptr; + } buf; + querybuf *orig_buf; +- register struct hostent *hp; ++ struct hostent *hp; + char qbuf[MAXDNAME+1], *qp = NULL; +-#ifdef SUNSECURITY +- register struct hostent *rhp; +- char **haddr; +- u_long old_options; +- char hname2[MAXDNAME+1]; +-#endif /*SUNSECURITY*/ +- +- if (__res_maybe_init (&_res, 0) == -1) { +- __set_h_errno (NETDB_INTERNAL); +- return (NULL); +- } ++ + if (af == AF_INET6 && len == IN6ADDRSZ && +- (!bcmp(uaddr, mapped, sizeof mapped) || +- !bcmp(uaddr, tunnelled, sizeof tunnelled))) { ++ (!memcmp(uaddr, mapped, sizeof mapped) || ++ !memcmp(uaddr, tunnelled, sizeof tunnelled))) { + /* Unmap. */ + addr += sizeof mapped; + uaddr += sizeof mapped; +@@ -698,9 +654,9 @@ gethostbyaddr(addr, len, af) + case AF_INET6: + qp = qbuf; + for (n = IN6ADDRSZ - 1; n >= 0; n--) { +- qp += SPRINTF((qp, "%x.%x.", +- uaddr[n] & 0xf, +- (uaddr[n] >> 4) & 0xf)); ++ qp += sprintf(qp, "%x.%x.", ++ uaddr[n] & 0xf, ++ (uaddr[n] >> 4) & 0xf); + } + strcpy(qp, "ip6.arpa"); + break; +@@ -710,14 +666,8 @@ gethostbyaddr(addr, len, af) + + buf.buf = orig_buf = (querybuf *) alloca (1024); + +- n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, +- &buf.ptr, NULL, NULL, NULL, NULL); +- if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) { +- strcpy(qp, "ip6.int"); +- n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, +- buf.buf != orig_buf ? MAXPACKET : 1024, +- &buf.ptr, NULL, NULL, NULL, NULL); +- } ++ n = __res_context_query (ctx, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, ++ &buf.ptr, NULL, NULL, NULL, NULL); + if (n < 0) { + if (buf.buf != orig_buf) + free (buf.buf); +@@ -731,44 +681,12 @@ gethostbyaddr(addr, len, af) + free (buf.buf); + if (!hp) + return (NULL); /* h_errno was set by getanswer() */ +-#ifdef SUNSECURITY +- if (af == AF_INET) { +- /* +- * turn off search as the name should be absolute, +- * 'localhost' should be matched by defnames +- */ +- strncpy(hname2, hp->h_name, MAXDNAME); +- hname2[MAXDNAME] = '\0'; +- old_options = _res.options; +- _res.options &= ~RES_DNSRCH; +- _res.options |= RES_DEFNAMES; +- if (!(rhp = gethostbyname(hname2))) { +- syslog(LOG_NOTICE|LOG_AUTH, +- "gethostbyaddr: No A record for %s (verifying [%s])", +- hname2, inet_ntoa(*((struct in_addr *)addr))); +- _res.options = old_options; +- __set_h_errno (HOST_NOT_FOUND); +- return (NULL); +- } +- _res.options = old_options; +- for (haddr = rhp->h_addr_list; *haddr; haddr++) +- if (!memcmp(*haddr, addr, INADDRSZ)) +- break; +- if (!*haddr) { +- syslog(LOG_NOTICE|LOG_AUTH, +- "gethostbyaddr: A record of %s != PTR record [%s]", +- hname2, inet_ntoa(*((struct in_addr *)addr))); +- __set_h_errno (HOST_NOT_FOUND); +- return (NULL); +- } +- } +-#endif /*SUNSECURITY*/ + hp->h_addrtype = af; + hp->h_length = len; + memmove(host_addr, addr, len); + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; +- if (af == AF_INET && (_res.options & RES_USE_INET6)) { ++ if (af == AF_INET && res_use_inet6 ()) { + map_v4v6_address((char*)host_addr, (char*)host_addr); + hp->h_addrtype = AF_INET6; + hp->h_length = IN6ADDRSZ; +@@ -777,9 +695,23 @@ gethostbyaddr(addr, len, af) + return (hp); + } + ++struct hostent * ++res_gethostbyaddr (const void *addr, socklen_t len, int af) ++{ ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ __set_h_errno (NETDB_INTERNAL); ++ return NULL; ++ } ++ struct hostent *hp = res_gethostbyaddr_context (ctx, addr, len, af); ++ __resolv_context_put (ctx); ++ return hp; ++} ++compat_symbol (libresolv, res_gethostbyaddr, res_gethostbyaddr, GLIBC_2_0); ++ + void +-_sethtent(f) +- int f; ++_sethtent (int f) + { + if (!hostf) + hostf = fopen(_PATH_HOSTS, "rce" ); +@@ -788,9 +720,10 @@ _sethtent(f) + stayopen = f; + } + libresolv_hidden_def (_sethtent) ++compat_symbol (libresolv, _sethtent, _sethtent, GLIBC_2_0); + +-void +-_endhtent() ++static void ++_endhtent (void) + { + if (hostf && !stayopen) { + (void) fclose(hostf); +@@ -799,10 +732,10 @@ _endhtent() + } + + struct hostent * +-_gethtent() ++_gethtent (void) + { + char *p; +- register char *cp, **q; ++ char *cp, **q; + int af, len; + + if (!hostf && !(hostf = fopen(_PATH_HOSTS, "rce" ))) { +@@ -826,7 +759,7 @@ _gethtent() + af = AF_INET6; + len = IN6ADDRSZ; + } else if (inet_pton(AF_INET, p, host_addr) > 0) { +- if (_res.options & RES_USE_INET6) { ++ if (res_use_inet6 ()) { + map_v4v6_address((char*)host_addr, (char*)host_addr); + af = AF_INET6; + len = IN6ADDRSZ; +@@ -863,28 +796,27 @@ _gethtent() + return (&host); + } + libresolv_hidden_def (_gethtent) ++compat_symbol (libresolv, _gethtent, _gethtent, GLIBC_2_0); + + struct hostent * +-_gethtbyname(name) +- const char *name; ++_gethtbyname (const char *name) + { + struct hostent *hp; + +- if (_res.options & RES_USE_INET6) { ++ if (res_use_inet6 ()) { + hp = _gethtbyname2(name, AF_INET6); + if (hp) + return (hp); + } + return (_gethtbyname2(name, AF_INET)); + } ++compat_symbol (libresolv, _gethtbyname, _gethtbyname, GLIBC_2_0); + + struct hostent * +-_gethtbyname2(name, af) +- const char *name; +- int af; ++_gethtbyname2 (const char *name, int af) + { +- register struct hostent *p; +- register char **cp; ++ struct hostent *p; ++ char **cp; + + _sethtent(0); + while ((p = _gethtent())) { +@@ -901,28 +833,25 @@ _gethtbyname2(name, af) + return (p); + } + libresolv_hidden_def (_gethtbyname2) ++compat_symbol (libresolv, _gethtbyname2, _gethtbyname2, GLIBC_2_0); + + struct hostent * +-_gethtbyaddr(addr, len, af) +- const char *addr; +- size_t len; +- int af; ++_gethtbyaddr (const char *addr, size_t len, int af) + { +- register struct hostent *p; ++ struct hostent *p; + + _sethtent(0); + while ((p = _gethtent())) +- if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) ++ if (p->h_addrtype == af && !memcmp(p->h_addr, addr, len)) + break; + _endhtent(); + return (p); + } + libresolv_hidden_def (_gethtbyaddr) ++compat_symbol (libresolv, _gethtbyaddr, _gethtbyaddr, GLIBC_2_0); + + static void +-map_v4v6_address(src, dst) +- const char *src; +- char *dst; ++map_v4v6_address (const char *src, char *dst) + { + u_char *p = (u_char *)dst; + char tmp[INADDRSZ]; +@@ -940,10 +869,7 @@ map_v4v6_address(src, dst) + } + + static void +-map_v4v6_hostent(hp, bpp, lenp) +- struct hostent *hp; +- char **bpp; +- int *lenp; ++map_v4v6_hostent (struct hostent *hp, char **bpp, int *lenp) + { + char **ap; + +@@ -968,11 +894,8 @@ map_v4v6_hostent(hp, bpp, lenp) + } + } + +-#ifdef RESOLVSORT + extern void +-addrsort(ap, num) +- char **ap; +- int num; ++addrsort (char **ap, int num) + { + int i, j; + char **p; +@@ -1011,55 +934,5 @@ addrsort(ap, num) + needsort++; + } + } +-#endif +- +-#if defined(BSD43_BSD43_NFS) || defined(sun) +-/* some libc's out there are bound internally to these names (UMIPS) */ +-void +-ht_sethostent(stayopen) +- int stayopen; +-{ +- _sethtent(stayopen); +-} +- +-void +-ht_endhostent() +-{ +- _endhtent(); +-} +- +-struct hostent * +-ht_gethostbyname(name) +- char *name; +-{ +- return (_gethtbyname(name)); +-} +- +-struct hostent * +-ht_gethostbyaddr(addr, len, af) +- const char *addr; +- size_t len; +- int af; +-{ +- return (_gethtbyaddr(addr, len, af)); +-} +- +-struct hostent * +-gethostent() +-{ +- return (_gethtent()); +-} + +-void +-dns_service() +-{ +- return; +-} +- +-#undef dn_skipname +-dn_skipname(comp_dn, eom) +- const u_char *comp_dn, *eom; +-{ +- return (__dn_skipname(comp_dn, eom)); +-} +-#endif /*old-style libc with yp junk in it*/ ++#endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_25) */ +diff --git a/resolv/compat-hooks.c b/resolv/compat-hooks.c +new file mode 100644 +index 0000000000000000..e36a370f04837340 +--- /dev/null ++++ b/resolv/compat-hooks.c +@@ -0,0 +1,56 @@ ++/* Compatibility functions for obsolete libresolv hooks. ++ Copyright (C) 1999-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* ++ * Copyright (c) 1995-1999 by Internet Software Consortium. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS ++ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE ++ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++#include ++ ++#include ++ ++#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_25) ++ ++void ++attribute_compat_text_section ++res_send_setqhook(void *hook) { ++ _res.__glibc_unused_qhook = hook; ++} ++compat_symbol (libresolv, res_send_setqhook, res_send_setqhook, GLIBC_2_0); ++ ++void ++attribute_compat_text_section ++res_send_setrhook(void *hook) { ++ _res.__glibc_unused_rhook = hook; ++} ++compat_symbol (libresolv, res_send_setrhook, res_send_setrhook, GLIBC_2_0); ++ ++#endif +diff --git a/resolv/herror.c b/resolv/herror.c +index 0aaf29f9db724bb3..b3df236bc95d67df 100644 +--- a/resolv/herror.c ++++ b/resolv/herror.c +@@ -44,11 +44,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; +-static const char rcsid[] = "$BINDId: herror.c,v 8.11 1999/10/13 16:39:39 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +@@ -85,14 +80,14 @@ herror(const char *s) { + v->iov_base = (/*noconst*/ char *)s; + v->iov_len = strlen(s); + v++; +- v->iov_base = ": "; ++ v->iov_base = (char *) ": "; + v->iov_len = 2; + v++; + } + v->iov_base = (char *)hstrerror(h_errno); + v->iov_len = strlen(v->iov_base); + v++; +- v->iov_base = "\n"; ++ v->iov_base = (char *) "\n"; + v->iov_len = 1; + writev_not_cancel_no_status(STDERR_FILENO, iov, (v - iov) + 1); + } +diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c +index 144b87a74c1aef62..022f7ea0841b6bae 100644 +--- a/resolv/inet_addr.c ++++ b/resolv/inet_addr.c +@@ -64,11 +64,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +-static const char rcsid[] = "$BINDId: inet_addr.c,v 8.11 1999/10/13 16:39:25 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + +@@ -77,26 +72,25 @@ static const char rcsid[] = "$BINDId: inet_addr.c,v 8.11 1999/10/13 16:39:25 vix + + #include + +-#ifdef _LIBC +-# include +-# include +-# include +-# include +-# include +-#endif ++#include ++#include ++#include ++#include ++#include + + /* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ + in_addr_t +-inet_addr(const char *cp) { ++__inet_addr(const char *cp) { + struct in_addr val; + + if (__inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); + } ++weak_alias (__inet_addr, inet_addr) + + /* + * Check whether "cp" is a valid ascii representation +@@ -110,9 +104,6 @@ __inet_aton(const char *cp, struct in_addr *addr) + { + static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; + in_addr_t val; +-#ifndef _LIBC +- int base; +-#endif + char c; + union iaddr { + uint8_t bytes[4]; +@@ -121,10 +112,8 @@ __inet_aton(const char *cp, struct in_addr *addr) + uint8_t *pp = res.bytes; + int digit; + +-#ifdef _LIBC + int saved_errno = errno; + __set_errno (0); +-#endif + + res.word = 0; + +@@ -137,7 +126,6 @@ __inet_aton(const char *cp, struct in_addr *addr) + */ + if (!isdigit(c)) + goto ret_0; +-#ifdef _LIBC + { + char *endp; + unsigned long ul = strtoul (cp, (char **) &endp, 0); +@@ -150,33 +138,6 @@ __inet_aton(const char *cp, struct in_addr *addr) + cp = endp; + } + c = *cp; +-#else +- val = 0; base = 10; digit = 0; +- if (c == '0') { +- c = *++cp; +- if (c == 'x' || c == 'X') +- base = 16, c = *++cp; +- else { +- base = 8; +- digit = 1 ; +- } +- } +- for (;;) { +- if (isascii(c) && isdigit(c)) { +- if (base == 8 && (c == '8' || c == '9')) +- return (0); +- val = (val * base) + (c - '0'); +- c = *++cp; +- digit = 1; +- } else if (base == 16 && isascii(c) && isxdigit(c)) { +- val = (val << 4) | +- (c + 10 - (islower(c) ? 'a' : 'A')); +- c = *++cp; +- digit = 1; +- } else +- break; +- } +-#endif + if (c == '.') { + /* + * Internet format: +@@ -210,15 +171,11 @@ __inet_aton(const char *cp, struct in_addr *addr) + if (addr != NULL) + addr->s_addr = res.word | htonl (val); + +-#ifdef _LIBC + __set_errno (saved_errno); +-#endif + return (1); + + ret_0: +-#ifdef _LIBC + __set_errno (saved_errno); +-#endif + return (0); + } + weak_alias (__inet_aton, inet_aton) +diff --git a/resolv/inet_net_ntop.c b/resolv/inet_net_ntop.c +index e50c6a049b875555..aaa78f664b5bc261 100644 +--- a/resolv/inet_net_ntop.c ++++ b/resolv/inet_net_ntop.c +@@ -15,10 +15,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: inet_net_ntop.c,v 1.6 1999/01/08 19:23:42 vixie Exp $"; +-#endif +- + #include + #include + #include +@@ -49,12 +45,7 @@ static char * inet_net_ntop_ipv4 (const u_char *src, int bits, + * Paul Vixie (ISC), July 1996 + */ + char * +-inet_net_ntop(af, src, bits, dst, size) +- int af; +- const void *src; +- int bits; +- char *dst; +- size_t size; ++inet_net_ntop (int af, const void *src, int bits, char *dst, size_t size) + { + switch (af) { + case AF_INET: +@@ -79,11 +70,7 @@ inet_net_ntop(af, src, bits, dst, size) + * Paul Vixie (ISC), July 1996 + */ + static char * +-inet_net_ntop_ipv4(src, bits, dst, size) +- const u_char *src; +- int bits; +- char *dst; +- size_t size; ++inet_net_ntop_ipv4 (const u_char *src, int bits, char *dst, size_t size) + { + char *odst = dst; + char *t; +diff --git a/resolv/inet_net_pton.c b/resolv/inet_net_pton.c +index 14916f83f840bcef..aab9b7b58228bb2d 100644 +--- a/resolv/inet_net_pton.c ++++ b/resolv/inet_net_pton.c +@@ -15,10 +15,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp $"; +-#endif +- + #include + #include + #include +@@ -54,11 +50,7 @@ static int inet_net_pton_ipv4 (const char *src, u_char *dst, + * Paul Vixie (ISC), June 1996 + */ + int +-inet_net_pton(af, src, dst, size) +- int af; +- const char *src; +- void *dst; +- size_t size; ++inet_net_pton (int af, const char *src, void *dst, size_t size) + { + switch (af) { + case AF_INET: +@@ -86,10 +78,7 @@ inet_net_pton(af, src, dst, size) + * Paul Vixie (ISC), June 1996 + */ + static int +-inet_net_pton_ipv4(src, dst, size) +- const char *src; +- u_char *dst; +- size_t size; ++inet_net_pton_ipv4 (const char *src, u_char *dst, size_t size) + { + static const char xdigits[] = "0123456789abcdef"; + int n, ch, tmp, dirty, bits; +diff --git a/resolv/inet_neta.c b/resolv/inet_neta.c +index 349e6bd8802b21fb..348ff4784f412bc0 100644 +--- a/resolv/inet_neta.c ++++ b/resolv/inet_neta.c +@@ -15,10 +15,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: inet_neta.c,v 1.6 1999/01/08 19:23:45 vixie Exp $"; +-#endif +- + #include + #include + #include +@@ -46,10 +42,7 @@ static const char rcsid[] = "$BINDId: inet_neta.c,v 1.6 1999/01/08 19:23:45 vixi + * Paul Vixie (ISC), July 1996 + */ + char * +-inet_neta(src, dst, size) +- u_int32_t src; +- char *dst; +- size_t size; ++inet_neta (u_int32_t src, char *dst, size_t size) + { + char *odst = dst; + char *tp; +diff --git a/resolv/inet_ntop.c b/resolv/inet_ntop.c +index 6e89f2d0589ad013..01c45ce8b79bec56 100644 +--- a/resolv/inet_ntop.c ++++ b/resolv/inet_ntop.c +@@ -15,10 +15,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: inet_ntop.c,v 1.8 1999/10/13 16:39:28 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +@@ -56,11 +52,7 @@ static const char *inet_ntop6 (const u_char *src, char *dst, socklen_t size) + * Paul Vixie, 1996. + */ + const char * +-inet_ntop(af, src, dst, size) +- int af; +- const void *src; +- char *dst; +- socklen_t size; ++inet_ntop (int af, const void *src, char *dst, socklen_t size) + { + switch (af) { + case AF_INET: +@@ -88,10 +80,7 @@ libc_hidden_def (inet_ntop) + */ + static const char * + internal_function +-inet_ntop4(src, dst, size) +- const u_char *src; +- char *dst; +- socklen_t size; ++inet_ntop4 (const u_char *src, char *dst, socklen_t size) + { + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; +@@ -111,10 +100,7 @@ inet_ntop4(src, dst, size) + */ + static const char * + internal_function +-inet_ntop6(src, dst, size) +- const u_char *src; +- char *dst; +- socklen_t size; ++inet_ntop6 (const u_char *src, char *dst, socklen_t size) + { + /* + * Note that int32_t and int16_t need only be "at least" large enough +diff --git a/resolv/ns_date.c b/resolv/ns_date.c +index 9801ac46d40b501c..31cef74c928013e8 100644 +--- a/resolv/ns_date.c ++++ b/resolv/ns_date.c +@@ -15,10 +15,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$Id$"; +-#endif +- + /* Import. */ + + #include +diff --git a/resolv/ns_name.c b/resolv/ns_name.c +index adf64bbd9ac8e503..08a75e2fe0b4edd6 100644 +--- a/resolv/ns_name.c ++++ b/resolv/ns_name.c +@@ -15,10 +15,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp $"; +-#endif +- + #include + + #include +@@ -33,32 +29,10 @@ static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie + + # define SPRINTF(x) ((size_t)sprintf x) + +-#define NS_TYPE_ELT 0x40 /*%< EDNS0 extended label type */ +-#define DNS_LABELTYPE_BITSTRING 0x41 +- + /* Data. */ + + static const char digits[] = "0123456789"; + +-static const char digitvalue[256] = { +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/ +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/ +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/ +- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/ +- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/ +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/ +- -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/ +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/ +- -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, -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, -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, -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, /*256*/ +-}; +- + /* Forward. */ + + static int special(int); +@@ -66,12 +40,7 @@ static int printable(int); + static int dn_find(const u_char *, const u_char *, + const u_char * const *, + const u_char * const *); +-static int encode_bitstring(const char **, const char *, +- unsigned char **, unsigned char **, +- unsigned const char *); + static int labellen(const u_char *); +-static int decode_bitstring(const unsigned char **, +- char *, const char *); + + /* Public. */ + +@@ -119,22 +88,6 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) + __set_errno (EMSGSIZE); + return (-1); + } +- if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) { +- int m; +- +- if (n != DNS_LABELTYPE_BITSTRING) { +- /* XXX: labellen should reject this case */ +- __set_errno (EINVAL); +- return(-1); +- } +- if ((m = decode_bitstring(&cp, dn, eom)) < 0) +- { +- __set_errno (EMSGSIZE); +- return(-1); +- } +- dn += m; +- continue; +- } + for ((void)NULL; l > 0; l--) { + c = *cp++; + if (special(c)) { +@@ -180,7 +133,7 @@ libresolv_hidden_def (ns_name_ntop) + strong_alias (ns_name_ntop, __ns_name_ntop) + + /*% +- * Convert a ascii string into an encoded domain name as per RFC1035. ++ * Convert an ascii string into an encoded domain name as per RFC1035. + * + * return: + * +@@ -196,7 +149,7 @@ int + ns_name_pton(const char *src, u_char *dst, size_t dstsiz) + { + u_char *label, *bp, *eom; +- int c, n, escaped, e = 0; ++ int c, n, escaped; + char *cp; + + escaped = 0; +@@ -206,28 +159,7 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) + + while ((c = *src++) != 0) { + if (escaped) { +- if (c == '[') { /*%< start a bit string label */ +- if ((cp = strchr(src, ']')) == NULL) { +- __set_errno (EINVAL); +- return(-1); +- } +- if ((e = encode_bitstring(&src, cp + 2, +- &label, &bp, eom)) +- != 0) { +- __set_errno (e); +- return(-1); +- } +- escaped = 0; +- label = bp++; +- if ((c = *src++) == 0) +- goto done; +- else if (c != '.') { +- __set_errno (EINVAL); +- return(-1); +- } +- continue; +- } +- else if ((cp = strchr(digits, c)) != NULL) { ++ if ((cp = strchr(digits, c)) != NULL) { + n = (cp - digits) * 100; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { +@@ -295,7 +227,6 @@ ns_name_pton(const char *src, u_char *dst, size_t dstsiz) + __set_errno (EMSGSIZE); + return (-1); + } +- done: + if (label >= eom) { + __set_errno (EMSGSIZE); + return (-1); +@@ -398,7 +329,6 @@ ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, + /* Check for indirection. */ + switch (n & NS_CMPRSFLGS) { + case 0: +- case NS_TYPE_ELT: + /* Limit checks. */ + if ((l = labellen(srcp - 1)) < 0) { + __set_errno (EMSGSIZE); +@@ -545,7 +475,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, + goto cleanup; + } + n = labellen(srcp); +- if (dstp + 1 + n >= eob) { ++ if (n + 1 > eob - dstp) { + goto cleanup; + } + memcpy(dstp, srcp, n + 1); +@@ -643,7 +573,6 @@ ns_name_skip(const u_char **ptrptr, const u_char *eom) + { + const u_char *cp; + u_int n; +- int l; + + cp = *ptrptr; + while (cp < eom && (n = *cp++) != 0) { +@@ -652,13 +581,6 @@ ns_name_skip(const u_char **ptrptr, const u_char *eom) + case 0: /*%< normal case, n == len */ + cp += n; + continue; +- case NS_TYPE_ELT: /*%< EDNS0 extended label */ +- if ((l = labellen(cp - 1)) < 0) { +- __set_errno (EMSGSIZE); +- return(-1); +- } +- cp += l; +- continue; + case NS_CMPRSFLGS: /*%< indirection */ + cp++; + break; +@@ -681,7 +603,7 @@ libresolv_hidden_def (ns_name_skip) + + /*% + * Thinking in noninternationalized USASCII (per the DNS spec), +- * is this characted special ("in need of quoting") ? ++ * is this character special ("in need of quoting") ? + * + * return: + *\li boolean. +@@ -795,180 +717,14 @@ dn_find(const u_char *domain, const u_char *msg, + return (-1); + } + ++/* Return the length of the encoded label starting at LP, or -1 for ++ compression references and extended label types. */ + static int +-decode_bitstring(const unsigned char **cpp, char *dn, const char *eom) +-{ +- const unsigned char *cp = *cpp; +- char *beg = dn, tc; +- int b, blen, plen, i; +- +- if ((blen = (*cp & 0xff)) == 0) +- blen = 256; +- plen = (blen + 3) / 4; +- plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1); +- if (dn + plen >= eom) +- return(-1); +- +- cp++; +- i = SPRINTF((dn, "\\[x")); +- if (i < 0) +- return (-1); +- dn += i; +- for (b = blen; b > 7; b -= 8, cp++) { +- i = SPRINTF((dn, "%02x", *cp & 0xff)); +- if (i < 0) +- return (-1); +- dn += i; +- } +- if (b > 4) { +- tc = *cp++; +- i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b)))); +- if (i < 0) +- return (-1); +- dn += i; +- } else if (b > 0) { +- tc = *cp++; +- i = SPRINTF((dn, "%1x", +- ((tc >> 4) & 0x0f) & (0x0f << (4 - b)))); +- if (i < 0) +- return (-1); +- dn += i; +- } +- i = SPRINTF((dn, "/%d]", blen)); +- if (i < 0) +- return (-1); +- dn += i; +- +- *cpp = cp; +- return(dn - beg); +-} +- +-static int +-encode_bitstring(const char **bp, const char *end, unsigned char **labelp, +- unsigned char ** dst, unsigned const char *eom) +-{ +- int afterslash = 0; +- const char *cp = *bp; +- unsigned char *tp; +- char c; +- const char *beg_blen; +- char *end_blen = NULL; +- int value = 0, count = 0, tbcount = 0, blen = 0; +- +- beg_blen = end_blen = NULL; +- +- /* a bitstring must contain at least 2 characters */ +- if (end - cp < 2) +- return(EINVAL); +- +- /* XXX: currently, only hex strings are supported */ +- if (*cp++ != 'x') +- return(EINVAL); +- if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */ +- return(EINVAL); +- +- for (tp = *dst + 1; cp < end && tp < eom; cp++) { +- switch((c = *cp)) { +- case ']': /*%< end of the bitstring */ +- if (afterslash) { +- if (beg_blen == NULL) +- return(EINVAL); +- blen = (int)strtol(beg_blen, &end_blen, 10); +- if (*end_blen != ']') +- return(EINVAL); +- } +- if (count) +- *tp++ = ((value << 4) & 0xff); +- cp++; /*%< skip ']' */ +- goto done; +- case '/': +- afterslash = 1; +- break; +- default: +- if (afterslash) { +- if (!isdigit(c&0xff)) +- return(EINVAL); +- if (beg_blen == NULL) { +- +- if (c == '0') { +- /* blen never begings with 0 */ +- return(EINVAL); +- } +- beg_blen = cp; +- } +- } else { +- if (!isxdigit(c&0xff)) +- return(EINVAL); +- value <<= 4; +- value += digitvalue[(int)c]; +- count += 4; +- tbcount += 4; +- if (tbcount > 256) +- return(EINVAL); +- if (count == 8) { +- *tp++ = value; +- count = 0; +- } +- } +- break; +- } +- } +- done: +- if (cp >= end || tp >= eom) +- return(EMSGSIZE); +- +- /* +- * bit length validation: +- * If a is present, the number of digits in the +- * MUST be just sufficient to contain the number of bits specified +- * by the . If there are insignificant bits in a final +- * hexadecimal or octal digit, they MUST be zero. +- * RFC2673, Section 3.2. +- */ +- if (blen > 0) { +- int traillen; +- +- if (((blen + 3) & ~3) != tbcount) +- return(EINVAL); +- traillen = tbcount - blen; /*%< between 0 and 3 */ +- if (((value << (8 - traillen)) & 0xff) != 0) +- return(EINVAL); +- } +- else +- blen = tbcount; +- if (blen == 256) +- blen = 0; +- +- /* encode the type and the significant bit fields */ +- **labelp = DNS_LABELTYPE_BITSTRING; +- **dst = blen; +- +- *bp = cp; +- *dst = tp; +- +- return(0); +-} +- +-static int +-labellen(const u_char *lp) ++labellen (const unsigned char *lp) + { +- int bitlen; +- u_char l = *lp; +- +- if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) { +- /* should be avoided by the caller */ +- return(-1); +- } +- +- if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) { +- if (l == DNS_LABELTYPE_BITSTRING) { +- if ((bitlen = *(lp + 1)) == 0) +- bitlen = 256; +- return((bitlen + 7 ) / 8 + 1); +- } +- return(-1); /*%< unknwon ELT */ +- } +- return(l); ++ if (*lp <= 63) ++ return *lp; ++ return -1; + } + + /*! \file */ +diff --git a/resolv/ns_netint.c b/resolv/ns_netint.c +index 4318f18879d774dd..6a365a3b8c37e21a 100644 +--- a/resolv/ns_netint.c ++++ b/resolv/ns_netint.c +@@ -15,10 +15,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$BINDId: ns_netint.c,v 8.4 1999/10/13 16:39:35 vixie Exp $"; +-#endif +- + /* Import. */ + + #include +diff --git a/resolv/ns_parse.c b/resolv/ns_parse.c +index 712469be1d88c58a..863b20a9f7fd902b 100644 +--- a/resolv/ns_parse.c ++++ b/resolv/ns_parse.c +@@ -15,10 +15,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$BINDId: ns_parse.c,v 8.13 1999/10/13 16:39:35 vixie Exp $"; +-#endif +- + /* Import. */ + + #include +diff --git a/resolv/ns_print.c b/resolv/ns_print.c +index 36d39784a5bfce1b..f55680c311bd015b 100644 +--- a/resolv/ns_print.c ++++ b/resolv/ns_print.c +@@ -16,10 +16,6 @@ + * SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$BINDId: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $"; +-#endif +- + /* Import. */ + + #include +@@ -51,8 +47,6 @@ static int addstr(const char *src, size_t len, + static int addtab(size_t len, size_t target, int spaced, + char **buf, size_t *buflen); + +-static u_int16_t dst_s_dns_key_id(const u_char *, const int); +- + /* Macros. */ + + #define T(x) \ +@@ -440,124 +434,6 @@ ns_sprintrrf(const u_char *msg, size_t msglen, + break; + } + +- case ns_t_key: { +- char base64_key[NS_MD5RSA_MAX_BASE64]; +- u_int keyflags, protocol, algorithm, key_id; +- const char *leader; +- int n; +- +- if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ) +- goto formerr; +- +- /* Key flags, Protocol, Algorithm. */ +- key_id = dst_s_dns_key_id(rdata, edata-rdata); +- keyflags = ns_get16(rdata); rdata += NS_INT16SZ; +- protocol = *rdata++; +- algorithm = *rdata++; +- len = SPRINTF((tmp, "0x%04x %u %u", +- keyflags, protocol, algorithm)); +- T(addstr(tmp, len, &buf, &buflen)); +- +- /* Public key data. */ +- len = b64_ntop(rdata, edata - rdata, +- base64_key, sizeof base64_key); +- if (len < 0) +- goto formerr; +- if (len > 15) { +- T(addstr(" (", 2, &buf, &buflen)); +- leader = "\n\t\t"; +- spaced = 0; +- } else +- leader = " "; +- for (n = 0; n < len; n += 48) { +- T(addstr(leader, strlen(leader), &buf, &buflen)); +- T(addstr(base64_key + n, MIN(len - n, 48), +- &buf, &buflen)); +- } +- if (len > 15) +- T(addstr(" )", 2, &buf, &buflen)); +- n = SPRINTF((tmp, " ; key_tag= %u", key_id)); +- T(addstr(tmp, n, &buf, &buflen)); +- +- break; +- } +- +- case ns_t_sig: { +- char base64_key[NS_MD5RSA_MAX_BASE64]; +- u_int type, algorithm, labels, footprint; +- const char *leader; +- u_long t; +- int n; +- +- if (rdlen < 22U) +- goto formerr; +- +- /* Type covered, Algorithm, Label count, Original TTL. */ +- type = ns_get16(rdata); rdata += NS_INT16SZ; +- algorithm = *rdata++; +- labels = *rdata++; +- t = ns_get32(rdata); rdata += NS_INT32SZ; +- len = SPRINTF((tmp, "%s %d %d %lu ", +- p_type(type), algorithm, labels, t)); +- T(addstr(tmp, len, &buf, &buflen)); +- if (labels > (u_int)dn_count_labels(name)) +- goto formerr; +- +- /* Signature expiry. */ +- t = ns_get32(rdata); rdata += NS_INT32SZ; +- len = SPRINTF((tmp, "%s ", p_secstodate(t))); +- T(addstr(tmp, len, &buf, &buflen)); +- +- /* Time signed. */ +- t = ns_get32(rdata); rdata += NS_INT32SZ; +- len = SPRINTF((tmp, "%s ", p_secstodate(t))); +- T(addstr(tmp, len, &buf, &buflen)); +- +- /* Signature Footprint. */ +- footprint = ns_get16(rdata); rdata += NS_INT16SZ; +- len = SPRINTF((tmp, "%u ", footprint)); +- T(addstr(tmp, len, &buf, &buflen)); +- +- /* Signer's name. */ +- T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); +- +- /* Signature. */ +- len = b64_ntop(rdata, edata - rdata, +- base64_key, sizeof base64_key); +- if (len > 15) { +- T(addstr(" (", 2, &buf, &buflen)); +- leader = "\n\t\t"; +- spaced = 0; +- } else +- leader = " "; +- if (len < 0) +- goto formerr; +- for (n = 0; n < len; n += 48) { +- T(addstr(leader, strlen(leader), &buf, &buflen)); +- T(addstr(base64_key + n, MIN(len - n, 48), +- &buf, &buflen)); +- } +- if (len > 15) +- T(addstr(" )", 2, &buf, &buflen)); +- break; +- } +- +- case ns_t_nxt: { +- int n, c; +- +- /* Next domain name. */ +- T(addname(msg, msglen, &rdata, origin, &buf, &buflen)); +- +- /* Type bit map. */ +- n = edata - rdata; +- for (c = 0; c < n*8; c++) +- if (NS_NXT_BIT_ISSET(c, rdata)) { +- len = SPRINTF((tmp, " %s", p_type(c))); +- T(addstr(tmp, len, &buf, &buflen)); +- } +- break; +- } +- + case ns_t_cert: { + u_int c_type, key_tag, alg; + int n; +@@ -891,81 +767,3 @@ addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) { + } + return (spaced); + } +- +-/* DST algorithm codes */ +-#define KEY_RSA 1 +-#define KEY_HMAC_MD5 157 +- +-/*% +- * calculates a checksum used in dst for an id. +- * takes an array of bytes and a length. +- * returns a 16 bit checksum. +- */ +-static u_int16_t +-dst_s_id_calc(const u_char *key, const int keysize) +-{ +- u_int32_t ac; +- const u_char *kp = key; +- int size = keysize; +- +- if (!key || (keysize <= 0)) +- return (0xffffU); +- +- for (ac = 0; size > 1; size -= 2, kp += 2) +- ac += ((*kp) << 8) + *(kp + 1); +- +- if (size > 0) +- ac += ((*kp) << 8); +- ac += (ac >> 16) & 0xffff; +- +- return (ac & 0xffff); +-} +- +-/*% +- * dst_s_get_int16 +- * This routine extracts a 16 bit integer from a two byte character +- * string. The character string is assumed to be in network byte +- * order and may be unaligned. The number returned is in host order. +- * Parameter +- * buf A two byte character string. +- * Return +- * The converted integer value. +- */ +- +-static u_int16_t +-dst_s_get_int16(const u_char *buf) +-{ +- register u_int16_t a = 0; +- a = ((u_int16_t)(buf[0] << 8)) | ((u_int16_t)(buf[1])); +- return (a); +-} +- +-/*% +- * dst_s_dns_key_id() Function to calculate DNSSEC footprint from KEY record +- * rdata +- * Input: +- * dns_key_rdata: the raw data in wire format +- * rdata_len: the size of the input data +- * Output: +- * the key footprint/id calculated from the key data +- */ +-static u_int16_t +-dst_s_dns_key_id(const u_char *dns_key_rdata, const int rdata_len) +-{ +- if (!dns_key_rdata) +- return 0; +- +- /* compute id */ +- if (dns_key_rdata[3] == KEY_RSA) /*%< Algorithm RSA */ +- return dst_s_get_int16((const u_char *) +- &dns_key_rdata[rdata_len - 3]); +- else if (dns_key_rdata[3] == KEY_HMAC_MD5) +- /* compatibility */ +- return 0; +- else +- /* compute a checksum on the key part of the key rr */ +- return dst_s_id_calc(dns_key_rdata, rdata_len); +-} +- +- +-/*! \file */ +diff --git a/resolv/ns_samedomain.c b/resolv/ns_samedomain.c +index 44b843a74b342d61..5d1bf39fc7280d3b 100644 +--- a/resolv/ns_samedomain.c ++++ b/resolv/ns_samedomain.c +@@ -16,10 +16,6 @@ + * SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$BINDId: ns_samedomain.c,v 8.9 1999/10/15 21:06:51 vixie Exp $"; +-#endif +- + #include + #include + #include +@@ -29,7 +25,7 @@ static const char rcsid[] = "$BINDId: ns_samedomain.c,v 8.9 1999/10/15 21:06:51 + * Check whether a name belongs to a domain. + * + * Inputs: +- *\li a - the domain whose ancestory is being verified ++ *\li a - the domain whose ancestry is being verified + *\li b - the potential ancestor we're checking against + * + * Return: +diff --git a/resolv/ns_ttl.c b/resolv/ns_ttl.c +index d4c98bcf3ae2757d..079948790b94b05e 100644 +--- a/resolv/ns_ttl.c ++++ b/resolv/ns_ttl.c +@@ -16,10 +16,6 @@ + * SOFTWARE. + */ + +-#if !defined(_LIBC) && !defined(lint) +-static const char rcsid[] = "$BINDId: ns_ttl.c,v 8.8 1999/10/13 16:39:36 vixie Exp $"; +-#endif +- + /* Import. */ + + #include +diff --git a/resolv/nsap_addr.c b/resolv/nsap_addr.c +index 7041e5282ebae4ed..9a1d3f7fdc960e54 100644 +--- a/resolv/nsap_addr.c ++++ b/resolv/nsap_addr.c +@@ -15,10 +15,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: nsap_addr.c,v 8.10 1999/10/13 16:39:28 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c +index 7f735f51ffb69f19..7a5c39dc20f6ebb8 100644 +--- a/resolv/nss_dns/dns-canon.c ++++ b/resolv/nss_dns/dns-canon.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc. ++/* Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2004. + +@@ -20,9 +20,11 @@ + #include + #include + #include ++#include + #include + #include +- ++#include ++#include + + #if PACKETSZ > 65536 + # define MAXPACKET PACKETSZ +@@ -57,11 +59,19 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, + } ansp = { .ptr = buf }; + enum nss_status status = NSS_STATUS_UNAVAIL; + ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } ++ + for (int i = 0; i < nqtypes; ++i) + { +- int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i], +- buf, sizeof (buf), &ansp.ptr, NULL, NULL, +- NULL, NULL); ++ int r = __res_context_query (ctx, name, ns_c_in, qtypes[i], ++ buf, sizeof (buf), &ansp.ptr, NULL, NULL, ++ NULL, NULL); + if (r > 0) + { + /* We need to decode the response. Just one question record. +@@ -102,6 +112,11 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, + + ptr += s; + ++ /* Check that there are enough bytes for the RR ++ metadata. */ ++ if (endptr - ptr < 10) ++ goto unavail; ++ + /* Check whether type and class match. */ + uint_fast16_t type; + NS_GET16 (type, ptr); +@@ -136,13 +151,25 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, + if (__ns_get16 (ptr) != ns_c_in) + goto unavail; + +- /* Also skip over the TTL. */ ++ /* Also skip over class and TTL. */ + ptr += sizeof (uint16_t) + sizeof (uint32_t); + +- /* Skip over the data length and data. */ +- ptr += sizeof (uint16_t) + __ns_get16 (ptr); ++ /* Skip over RDATA length and RDATA itself. */ ++ uint16_t rdatalen = __ns_get16 (ptr); ++ ptr += sizeof (uint16_t); ++ /* Not enough room for RDATA. */ ++ if (endptr - ptr < rdatalen) ++ goto unavail; ++ ptr += rdatalen; + } + } ++ ++ /* Restore original buffer before retry. */ ++ if (ansp.ptr != buf) ++ { ++ free (ansp.ptr); ++ ansp.ptr = buf; ++ } + } + + out: +@@ -150,6 +177,6 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, + + if (ansp.ptr != buf) + free (ansp.ptr); +- ++ __resolv_context_put (ctx); + return status; + } +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c +index 7fc154db5d3130a3..1e85e4f08ffc8600 100644 +--- a/resolv/nss_dns/dns-host.c ++++ b/resolv/nss_dns/dns-host.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996-2012 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Extended from original form by Ulrich Drepper , 1996. + +@@ -78,12 +78,13 @@ + #include + #include + #include +-#include + + #include "nsswitch.h" ++#include + + /* Get implementeation for some internal functions. */ + #include ++#include + #include + #include + +@@ -100,10 +101,6 @@ + #endif + #define MAXHOSTNAMELEN 256 + +-static const char AskedForGot[] = "\ +-gethostby*.getanswer: asked for \"%s\", got \"%s\""; +- +- + /* We need this time later. */ + typedef union querybuf + { +@@ -111,14 +108,8 @@ typedef union querybuf + u_char buf[MAXPACKET]; + } querybuf; + +-/* These functions are defined in res_comp.c. */ +-#define NS_MAXCDNAME 255 /* maximum compressed domain name */ +-extern int __ns_name_ntop (const u_char *, char *, size_t); +-extern int __ns_name_unpack (const u_char *, const u_char *, +- const u_char *, u_char *, size_t); +- +- +-static enum nss_status getanswer_r (const querybuf *answer, int anslen, ++static enum nss_status getanswer_r (struct resolv_context *ctx, ++ const querybuf *answer, int anslen, + const char *qname, int qtype, + struct hostent *result, char *buffer, + size_t buflen, int *errnop, int *h_errnop, +@@ -132,19 +123,55 @@ static enum nss_status gaih_getanswer (const querybuf *answer1, int anslen1, + int *errnop, int *h_errnop, + int32_t *ttlp); + +-extern enum nss_status _nss_dns_gethostbyname3_r (const char *name, int af, +- struct hostent *result, +- char *buffer, size_t buflen, +- int *errnop, int *h_errnop, +- int32_t *ttlp, +- char **canonp); +-hidden_proto (_nss_dns_gethostbyname3_r) ++static enum nss_status gethostbyname3_context (struct resolv_context *ctx, ++ const char *name, int af, ++ struct hostent *result, ++ char *buffer, size_t buflen, ++ int *errnop, int *h_errnop, ++ int32_t *ttlp, ++ char **canonp); ++ ++/* Return the expected RDATA length for an address record type (A or ++ AAAA). */ ++static int ++rrtype_to_rdata_length (int type) ++{ ++ switch (type) ++ { ++ case T_A: ++ return INADDRSZ; ++ case T_AAAA: ++ return IN6ADDRSZ; ++ default: ++ return -1; ++ } ++} ++ + + enum nss_status + _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop, int32_t *ttlp, char **canonp) + { ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } ++ enum nss_status status = gethostbyname3_context ++ (ctx, name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp); ++ __resolv_context_put (ctx); ++ return status; ++} ++ ++static enum nss_status ++gethostbyname3_context (struct resolv_context *ctx, ++ const char *name, int af, struct hostent *result, ++ char *buffer, size_t buflen, int *errnop, ++ int *h_errnop, int32_t *ttlp, char **canonp) ++{ + union + { + querybuf *buf; +@@ -158,9 +185,6 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, + int olderr = errno; + enum nss_status status; + +- if (__res_maybe_init (&_res, 0) == -1) +- return NSS_STATUS_UNAVAIL; +- + switch (af) { + case AF_INET: + size = INADDRSZ; +@@ -185,13 +209,13 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, + * function that looks up host names. + */ + if (strchr (name, '.') == NULL +- && (cp = res_hostalias (&_res, name, tmp, sizeof (tmp))) != NULL) ++ && (cp = __res_context_hostalias (ctx, name, tmp, sizeof (tmp))) != NULL) + name = cp; + + host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); + +- n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, +- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); ++ n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf, ++ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); + if (n < 0) + { + switch (errno) +@@ -223,10 +247,10 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, + by having the RES_USE_INET6 bit in _res.options set, we try + another lookup. */ + if (af == AF_INET6 && res_use_inet6 ()) +- n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf, +- host_buffer.buf != orig_host_buffer +- ? MAXPACKET : 1024, &host_buffer.ptr, +- NULL, NULL, NULL, NULL); ++ n = __res_context_search (ctx, name, C_IN, T_A, host_buffer.buf->buf, ++ host_buffer.buf != orig_host_buffer ++ ? MAXPACKET : 1024, &host_buffer.ptr, ++ NULL, NULL, NULL, NULL); + + if (n < 0) + { +@@ -241,14 +265,13 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result, + result->h_length = INADDRSZ; + } + +- status = getanswer_r (host_buffer.buf, n, name, type, result, buffer, buflen, +- errnop, h_errnop, map, ttlp, canonp); ++ status = getanswer_r ++ (ctx, host_buffer.buf, n, name, type, result, buffer, buflen, ++ errnop, h_errnop, map, ttlp, canonp); + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); + return status; + } +-hidden_def (_nss_dns_gethostbyname3_r) +- + + enum nss_status + _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result, +@@ -265,15 +288,21 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, + char *buffer, size_t buflen, int *errnop, + int *h_errnop) + { ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } + enum nss_status status = NSS_STATUS_NOTFOUND; +- + if (res_use_inet6 ()) +- status = _nss_dns_gethostbyname3_r (name, AF_INET6, result, buffer, +- buflen, errnop, h_errnop, NULL, NULL); ++ status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer, ++ buflen, errnop, h_errnop, NULL, NULL); + if (status == NSS_STATUS_NOTFOUND) +- status = _nss_dns_gethostbyname3_r (name, AF_INET, result, buffer, +- buflen, errnop, h_errnop, NULL, NULL); +- ++ status = gethostbyname3_context (ctx, name, AF_INET, result, buffer, ++ buflen, errnop, h_errnop, NULL, NULL); ++ __resolv_context_put (ctx); + return status; + } + +@@ -283,8 +312,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) + { +- if (__res_maybe_init (&_res, 0) == -1) +- return NSS_STATUS_UNAVAIL; ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *herrnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } + + /* + * if there aren't any dots, it could be a user-level alias. +@@ -294,7 +328,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + if (strchr (name, '.') == NULL) + { + char *tmp = alloca (NS_MAXDNAME); +- const char *cp = res_hostalias (&_res, name, tmp, NS_MAXDNAME); ++ const char *cp = __res_context_hostalias (ctx, name, tmp, NS_MAXDNAME); + if (cp != NULL) + name = cp; + } +@@ -313,9 +347,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + + int olderr = errno; + enum nss_status status; +- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, +- host_buffer.buf->buf, 2048, &host_buffer.ptr, +- &ans2p, &nans2p, &resplen2, &ans2p_malloced); ++ int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, ++ host_buffer.buf->buf, 2048, &host_buffer.ptr, ++ &ans2p, &nans2p, &resplen2, &ans2p_malloced); + if (n >= 0) + { + status = gaih_getanswer (host_buffer.buf, n, (const querybuf *) ans2p, +@@ -358,6 +392,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); + ++ __resolv_context_put (ctx); + return status; + } + +@@ -401,7 +436,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + buffer += pad; + buflen = buflen > pad ? buflen - pad : 0; + +- if (__builtin_expect (buflen < sizeof (struct host_data), 0)) ++ if (__glibc_unlikely (buflen < sizeof (struct host_data))) + { + *errnop = ERANGE; + *h_errnop = NETDB_INTERNAL; +@@ -410,8 +445,13 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + + host_data = (struct host_data *) buffer; + +- if (__res_maybe_init (&_res, 0) == -1) +- return NSS_STATUS_UNAVAIL; ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *h_errnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } + + if (af == AF_INET6 && len == IN6ADDRSZ + && (memcmp (uaddr, mapped, sizeof mapped) == 0 +@@ -436,12 +476,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + default: + *errnop = EAFNOSUPPORT; + *h_errnop = NETDB_INTERNAL; ++ __resolv_context_put (ctx); + return NSS_STATUS_UNAVAIL; + } + if (size > len) + { + *errnop = EAFNOSUPPORT; + *h_errnop = NETDB_INTERNAL; ++ __resolv_context_put (ctx); + return NSS_STATUS_UNAVAIL; + } + +@@ -454,19 +496,6 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff)); + break; + case AF_INET6: +- /* Only lookup with the byte string format if the user wants it. */ +- if (__builtin_expect (_res.options & RES_USEBSTRING, 0)) +- { +- qp = stpcpy (qbuf, "\\[x"); +- for (n = 0; n < IN6ADDRSZ; ++n) +- qp += sprintf (qp, "%02hhx", uaddr[n]); +- strcpy (qp, "].ip6.arpa"); +- n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, +- host_buffer.buf->buf, 1024, &host_buffer.ptr, +- NULL, NULL, NULL, NULL); +- if (n >= 0) +- goto got_it_already; +- } + qp = qbuf; + for (n = IN6ADDRSZ - 1; n >= 0; n--) + { +@@ -483,37 +512,28 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + break; + } + +- n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, +- 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); +- if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) +- { +- strcpy (qp, "ip6.int"); +- n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, +- host_buffer.buf != orig_host_buffer +- ? MAXPACKET : 1024, &host_buffer.ptr, +- NULL, NULL, NULL, NULL); +- } ++ n = __res_context_query (ctx, qbuf, C_IN, T_PTR, host_buffer.buf->buf, ++ 1024, &host_buffer.ptr, NULL, NULL, NULL, NULL); + if (n < 0) + { + *h_errnop = h_errno; + __set_errno (olderr); + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); ++ __resolv_context_put (ctx); + return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; + } + +- got_it_already: +- status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen, +- errnop, h_errnop, 0 /* XXX */, ttlp, NULL); ++ status = getanswer_r ++ (ctx, host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen, ++ errnop, h_errnop, 0 /* XXX */, ttlp, NULL); + if (host_buffer.buf != orig_host_buffer) + free (host_buffer.buf); + if (status != NSS_STATUS_SUCCESS) +- return status; +- +-#ifdef SUNSECURITY +- This is not implemented because it is not possible to use the current +- source from bind in a multi-threaded program. +-#endif ++ { ++ __resolv_context_put (ctx); ++ return status; ++ } + + result->h_addrtype = af; + result->h_length = len; +@@ -521,6 +541,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, + host_data->h_addr_ptrs[0] = (char *) host_data->host_addr; + host_data->h_addr_ptrs[1] = NULL; + *h_errnop = NETDB_SUCCESS; ++ __resolv_context_put (ctx); + return NSS_STATUS_SUCCESS; + } + hidden_def (_nss_dns_gethostbyaddr2_r) +@@ -535,26 +556,27 @@ _nss_dns_gethostbyaddr_r (const void *addr, socklen_t len, int af, + errnop, h_errnop, NULL); + } + +-#ifdef RESOLVSORT +-static void addrsort (char **ap, int num); +- + static void +-addrsort (char **ap, int num) ++addrsort (struct resolv_context *ctx, char **ap, int num) + { + int i, j; + char **p; + short aval[MAX_NR_ADDRS]; + int needsort = 0; ++ size_t nsort = __resolv_context_sort_count (ctx); + + p = ap; + if (num > MAX_NR_ADDRS) + num = MAX_NR_ADDRS; + for (i = 0; i < num; i++, p++) + { +- for (j = 0 ; (unsigned)j < _res.nsort; j++) +- if (_res.sort_list[j].addr.s_addr == +- (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) +- break; ++ for (j = 0 ; (unsigned)j < nsort; j++) ++ { ++ struct resolv_sortlist_entry e ++ = __resolv_context_sort_entry (ctx, j); ++ if (e.addr.s_addr == (((struct in_addr *)(*p))->s_addr & e.mask)) ++ break; ++ } + aval[i] = j; + if (needsort == 0 && i > 0 && j < aval[i-1]) + needsort = i; +@@ -579,10 +601,10 @@ addrsort (char **ap, int num) + else + break; + } +-#endif + + static enum nss_status +-getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, ++getanswer_r (struct resolv_context *ctx, ++ const querybuf *answer, int anslen, const char *qname, int qtype, + struct hostent *result, char *buffer, size_t buflen, + int *errnop, int *h_errnop, int map, int32_t *ttlp, char **canonp) + { +@@ -593,7 +615,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + char *h_addr_ptrs[0]; + } *host_data; + int linebuflen; +- register const HEADER *hp; ++ const HEADER *hp; + const u_char *end_of_message, *cp; + int n, ancount, qdcount; + int haveanswer, had_error; +@@ -606,7 +628,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data); + buffer += pad; + buflen = buflen > pad ? buflen - pad : 0; +- if (__builtin_expect (buflen < sizeof (struct host_data), 0)) ++ if (__glibc_unlikely (buflen < sizeof (struct host_data))) + { + /* The buffer is too small. */ + too_small: +@@ -643,7 +665,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + ancount = ntohs (hp->ancount); + qdcount = ntohs (hp->qdcount); + cp = answer->buf + HFIXEDSZ; +- if (__builtin_expect (qdcount, 1) != 1) ++ if (__glibc_unlikely (qdcount != 1)) + { + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; +@@ -657,7 +679,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + packtmp, sizeof packtmp); + if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) + { +- if (__builtin_expect (errno, 0) == EMSGSIZE) ++ if (__glibc_unlikely (errno == EMSGSIZE)) + goto too_small; + + n = -1; +@@ -666,13 +688,19 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + if (n > 0 && bp[0] == '.') + bp[0] = '\0'; + +- if (__builtin_expect (n < 0 || ((*name_ok) (bp) == 0 && (errno = EBADMSG)), +- 0)) ++ if (__glibc_unlikely (n < 0)) + { + *errnop = errno; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; + } ++ if (__glibc_unlikely (name_ok (bp) == 0)) ++ { ++ errno = EBADMSG; ++ *errnop = EBADMSG; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; ++ } + cp += n + QFIXEDSZ; + + if (qtype == T_A || qtype == T_AAAA) +@@ -714,20 +742,20 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + packtmp, sizeof packtmp); + if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) + { +- if (__builtin_expect (errno, 0) == EMSGSIZE) ++ if (__glibc_unlikely (errno == EMSGSIZE)) + goto too_small; + + n = -1; + } + +- if (__builtin_expect (n < 0 || (*name_ok) (bp) == 0, 0)) ++ if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0)) + { + ++had_error; + continue; + } + cp += n; /* name */ + +- if (__builtin_expect (cp + 10 > end_of_message, 0)) ++ if (__glibc_unlikely (cp + 10 > end_of_message)) + { + ++had_error; + continue; +@@ -741,7 +769,15 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + cp += INT32SZ; /* TTL */ + n = __ns_get16 (cp); + cp += INT16SZ; /* len */ +- if (__builtin_expect (class != C_IN, 0)) ++ ++ if (end_of_message - cp < n) ++ { ++ /* RDATA extends beyond the end of the packet. */ ++ ++had_error; ++ continue; ++ } ++ ++ if (__glibc_unlikely (class != C_IN)) + { + /* XXX - debug? syslog? */ + cp += n; +@@ -757,7 +793,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) + continue; + n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); +- if (__builtin_expect (n < 0 || (*name_ok) (tbuf) == 0, 0)) ++ if (__glibc_unlikely (n < 0 || (*name_ok) (tbuf) == 0)) + { + ++had_error; + continue; +@@ -766,7 +802,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + /* Store alias. */ + *ap++ = bp; + n = strlen (bp) + 1; /* For the \0. */ +- if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN) ++ if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) + { + ++had_error; + continue; +@@ -775,9 +811,9 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + linebuflen -= n; + /* Get canonical name. */ + n = strlen (tbuf) + 1; /* For the \0. */ +- if (__builtin_expect (n > linebuflen, 0)) ++ if (__glibc_unlikely (n > linebuflen)) + goto too_small; +- if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN) ++ if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) + { + ++had_error; + continue; +@@ -795,7 +831,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + *ttlp = ttl; + + n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); +- if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0)) ++ if (__glibc_unlikely (n < 0 || res_dnok (tbuf) == 0)) + { + ++had_error; + continue; +@@ -803,9 +839,9 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + cp += n; + /* Get canonical name. */ + n = strlen (tbuf) + 1; /* For the \0. */ +- if (__builtin_expect (n > linebuflen, 0)) ++ if (__glibc_unlikely (n > linebuflen)) + goto too_small; +- if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN) ++ if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) + { + ++had_error; + continue; +@@ -818,16 +854,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + + if (type == T_A && qtype == T_AAAA && map) + have_to_map = 1; +- else if (__builtin_expect (type != qtype, 0)) ++ else if (__glibc_unlikely (type != qtype)) + { +- /* Log a low priority message if we get an unexpected record, but +- skip it if we are using DNSSEC since it uses many different types +- in responses that do not match QTYPE. */ +- if ((_res.options & RES_USE_DNSSEC) == 0) +- syslog (LOG_NOTICE | LOG_AUTH, +- "gethostby*.getanswer: asked for \"%s %s %s\", " +- "got type \"%s\"", +- qname, p_class (C_IN), p_type (qtype), p_type (type)); + cp += n; + continue; /* XXX - had_error++ ? */ + } +@@ -835,9 +863,8 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + switch (type) + { + case T_PTR: +- if (__builtin_expect (strcasecmp (tname, bp) != 0, 0)) ++ if (__glibc_unlikely (strcasecmp (tname, bp) != 0)) + { +- syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } +@@ -846,65 +873,40 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + packtmp, sizeof packtmp); + if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) + { +- if (__builtin_expect (errno, 0) == EMSGSIZE) ++ if (__glibc_unlikely (errno == EMSGSIZE)) + goto too_small; + + n = -1; + } + +- if (__builtin_expect (n < 0 || res_hnok (bp) == 0, 0)) ++ if (__glibc_unlikely (n < 0 || res_hnok (bp) == 0)) + { + ++had_error; + break; + } + if (ttlp != NULL && ttl < *ttlp) + *ttlp = ttl; +-#if MULTI_PTRS_ARE_ALIASES +- cp += n; +- if (haveanswer == 0) +- result->h_name = bp; +- else if (ap < &host_data->aliases[MAXALIASES-1]) +- *ap++ = bp; +- else +- n = -1; +- if (n != -1) +- { +- n = strlen (bp) + 1; /* for the \0 */ +- if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN) +- { +- ++had_error; +- break; +- } +- bp += n; +- linebuflen -= n; +- } +- break; +-#else ++ /* bind would put multiple PTR records as aliases, but we don't do ++ that. */ + result->h_name = bp; +- if (have_to_map) +- { +- n = strlen (bp) + 1; /* for the \0 */ +- if (__builtin_expect (n >= MAXHOSTNAMELEN, 0)) +- { +- ++had_error; +- break; +- } +- bp += n; +- linebuflen -= n; +- if (map_v4v6_hostent (result, &bp, &linebuflen)) +- goto too_small; +- } + *h_errnop = NETDB_SUCCESS; + return NSS_STATUS_SUCCESS; +-#endif + case T_A: + case T_AAAA: +- if (__builtin_expect (strcasecmp (result->h_name, bp), 0) != 0) ++ if (__glibc_unlikely (strcasecmp (result->h_name, bp) != 0)) + { +- syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } ++ ++ /* Stop parsing at a record whose length is incorrect. */ ++ if (n != rrtype_to_rdata_length (type)) ++ { ++ ++had_error; ++ break; ++ } ++ ++ /* Skip records of the wrong type. */ + if (n != result->h_length) + { + cp += n; +@@ -912,7 +914,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + } + if (!haveanswer) + { +- register int nn; ++ int nn; + + /* We compose a single hostent out of the entire chain of + entries, so the TTL of the hostent is essentially the lowest +@@ -930,7 +932,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + linebuflen -= sizeof (align) - ((u_long) bp % sizeof (align)); + bp += sizeof (align) - ((u_long) bp % sizeof (align)); + +- if (__builtin_expect (n > linebuflen, 0)) ++ if (__glibc_unlikely (n > linebuflen)) + goto too_small; + bp = __mempcpy (*hap++ = bp, cp, n); + cp += n; +@@ -947,15 +949,14 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, + { + *ap = NULL; + *hap = NULL; +-#if defined RESOLVSORT + /* + * Note: we sort even if host can take only one address + * in its return structures - should give it the "best" + * address in that case, not some random one + */ +- if (_res.nsort && haveanswer > 1 && qtype == T_A) +- addrsort (host_data->h_addr_ptrs, haveanswer); +-#endif /*RESOLVSORT*/ ++ if (haveanswer > 1 && qtype == T_A ++ && __resolv_context_sort_count (ctx) > 0) ++ addrsort (ctx, host_data->h_addr_ptrs, haveanswer); + + if (result->h_name == NULL) + { +@@ -1001,7 +1002,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + int qdcount = ntohs (hp->qdcount); + const u_char *cp = answer->buf + HFIXEDSZ; + const u_char *end_of_message = answer->buf + anslen; +- if (__builtin_expect (qdcount != 1, 0)) ++ if (__glibc_unlikely (qdcount != 1)) + { + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; +@@ -1014,7 +1015,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + it later. */ + if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1) + { +- if (__builtin_expect (errno, 0) == EMSGSIZE) ++ if (__glibc_unlikely (errno == EMSGSIZE)) + { + too_small: + *errnop = ERANGE; +@@ -1025,13 +1026,19 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + n = -1; + } + +- if (__builtin_expect (n < 0 || (res_hnok (buffer) == 0 +- && (errno = EBADMSG)), 0)) ++ if (__glibc_unlikely (n < 0)) + { + *errnop = errno; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_UNAVAIL; + } ++ if (__glibc_unlikely (res_hnok (buffer) == 0)) ++ { ++ errno = EBADMSG; ++ *errnop = EBADMSG; ++ *h_errnop = NO_RECOVERY; ++ return NSS_STATUS_UNAVAIL; ++ } + cp += n + QFIXEDSZ; + + int haveanswer = 0; +@@ -1053,12 +1060,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + if (n != -1 && + (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1) + { +- if (__builtin_expect (errno, 0) == EMSGSIZE) ++ if (__glibc_unlikely (errno == EMSGSIZE)) + goto too_small; + + n = -1; + } +- if (__builtin_expect (n < 0 || res_hnok (buffer) == 0, 0)) ++ if (__glibc_unlikely (n < 0 || res_hnok (buffer) == 0)) + { + ++had_error; + continue; +@@ -1072,7 +1079,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + + cp += n; /* name */ + +- if (__builtin_expect (cp + 10 > end_of_message, 0)) ++ if (__glibc_unlikely (cp + 10 > end_of_message)) + { + ++had_error; + continue; +@@ -1087,6 +1094,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + n = __ns_get16 (cp); + cp += INT16SZ; /* len */ + ++ if (end_of_message - cp < n) ++ { ++ /* RDATA extends beyond the end of the packet. */ ++ ++had_error; ++ continue; ++ } ++ + if (class != C_IN) + { + cp += n; +@@ -1102,7 +1116,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + *ttlp = ttl; + + n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); +- if (__builtin_expect (n < 0 || res_hnok (tbuf) == 0, 0)) ++ if (__glibc_unlikely (n < 0 || res_hnok (tbuf) == 0)) + { + ++had_error; + continue; +@@ -1119,9 +1133,9 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + } + + n = strlen (tbuf) + 1; +- if (__builtin_expect (n > buflen, 0)) ++ if (__glibc_unlikely (n > buflen)) + goto too_small; +- if (__builtin_expect (n >= MAXHOSTNAMELEN, 0)) ++ if (__glibc_unlikely (n >= MAXHOSTNAMELEN)) + { + ++had_error; + continue; +@@ -1134,32 +1148,25 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + } + continue; + } +-#if 1 +- // We should not see any types other than those explicitly listed +- // below. Some types sent by server seem missing, though. Just +- // collect the data for now. +- if (__builtin_expect (type != T_A && type != T_AAAA, 0)) +-#else +- if (__builtin_expect (type == T_SIG, 0) +- || __builtin_expect (type == T_KEY, 0) +- || __builtin_expect (type == T_NXT, 0) +- || __builtin_expect (type == T_PTR, 0) +- || __builtin_expect (type == T_DNAME, 0)) +-#endif +- { +- /* We don't support DNSSEC yet. For now, ignore the record +- and send a low priority message to syslog. + +- We also don't expect T_PTR or T_DNAME messages. */ +- syslog (LOG_DEBUG | LOG_AUTH, +- "getaddrinfo*.gaih_getanswer: got type \"%s\"", +- p_type (type)); ++ /* Stop parsing if we encounter a record with incorrect RDATA ++ length. */ ++ if (type == T_A || type == T_AAAA) ++ { ++ if (n != rrtype_to_rdata_length (type)) ++ { ++ ++had_error; ++ continue; ++ } ++ } ++ else ++ { ++ /* Skip unknown records. */ + cp += n; + continue; + } +- if (type != T_A && type != T_AAAA) +- abort (); + ++ assert (type == T_A || type == T_AAAA); + if (*pat == NULL) + { + uintptr_t pad = (-(uintptr_t) buffer +@@ -1167,8 +1174,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + buffer += pad; + buflen = buflen > pad ? buflen - pad : 0; + +- if (__builtin_expect (buflen < sizeof (struct gaih_addrtuple), +- 0)) ++ if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple))) + goto too_small; + + *pat = (struct gaih_addrtuple *) buffer; +@@ -1193,12 +1199,6 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, + } + + (*pat)->family = type == T_A ? AF_INET : AF_INET6; +- if (__builtin_expect ((type == T_A && n != INADDRSZ) +- || (type == T_AAAA && n != IN6ADDRSZ), 0)) +- { +- ++had_error; +- continue; +- } + memcpy ((*pat)->addr, cp, n); + cp += n; + (*pat)->scopeid = 0; +@@ -1259,8 +1259,8 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + expected application behaviour. Some of the synthesized responses + aren't very well thought out and sometimes appear to imply that + IPv4 responses are always answer 1, and IPv6 responses are always +- answer 2, but that's not true (see the implemetnation of send_dg +- and send_vc to see response can arrive in any order, particlarly ++ answer 2, but that's not true (see the implementation of send_dg ++ and send_vc to see response can arrive in any order, particularly + for UDP). However, we expect it holds roughly enough of the time + that this code works, but certainly needs to be fixed to make this + a more robust implementation. +@@ -1297,12 +1297,12 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + ---------------------------------------------- + + [1] If the first response is a success we return success. +- This ignores the state of the second answer and in fact +- incorrectly sets errno and h_errno to that of the second ++ This ignores the state of the second answer and in fact ++ incorrectly sets errno and h_errno to that of the second + answer. However because the response is a success we ignore + *errnop and *h_errnop (though that means you touched errno on +- success). We are being conservative here and returning the +- likely IPv4 response in the first answer as a success. ++ success). We are being conservative here and returning the ++ likely IPv4 response in the first answer as a success. + + [2] If the first response is a recoverable TRYAGAIN we return + that instead of looking at the second response. The +@@ -1356,7 +1356,7 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, + if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) + status = status2; + /* Do not return a truncated second response (unless it was +- unavoidable e.g. unrecoverable TRYAGAIN). */ ++ unavoidable e.g. unrecoverable TRYAGAIN). */ + if (status == NSS_STATUS_SUCCESS + && (status2 == NSS_STATUS_TRYAGAIN + && *errnop == ERANGE && *h_errnop != NO_RECOVERY)) +diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c +index ccf871c8e4cb25e0..f190eb2225d39d16 100644 +--- a/resolv/nss_dns/dns-network.c ++++ b/resolv/nss_dns/dns-network.c +@@ -1,5 +1,4 @@ +-/* Copyright (C) 1996,1997,1998,1999,2002,2004,2007,2008,2011 +- Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Extended from original form by Ulrich Drepper , 1996. + +@@ -62,9 +61,14 @@ + #include + #include + #include ++#include ++#include + + #include "nsswitch.h" + #include ++#include ++#include ++#include + + /* Maximum number of aliases we allow. */ + #define MAX_NR_ALIASES 48 +@@ -91,13 +95,6 @@ typedef union querybuf + u_char buf[MAXPACKET]; + } querybuf; + +-/* These functions are defined in res_comp.c. */ +-#define NS_MAXCDNAME 255 /* maximum compressed domain name */ +-extern int __ns_name_ntop (const u_char *, char *, size_t) __THROW; +-extern int __ns_name_unpack (const u_char *, const u_char *, +- const u_char *, u_char *, size_t) __THROW; +- +- + /* Prototypes for local functions. */ + static enum nss_status getanswer_r (const querybuf *answer, int anslen, + struct netent *result, char *buffer, +@@ -120,19 +117,26 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, + int anslen; + enum nss_status status; + +- if (__res_maybe_init (&_res, 0) == -1) +- return NSS_STATUS_UNAVAIL; ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *herrnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } + + net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); + +- anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf, +- 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); ++ anslen = __res_context_search ++ (ctx, name, C_IN, T_PTR, net_buffer.buf->buf, ++ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + if (anslen < 0) + { + /* Nothing found. */ + *errnop = errno; + if (net_buffer.buf != orig_net_buffer) + free (net_buffer.buf); ++ __resolv_context_put (ctx); + return (errno == ECONNREFUSED + || errno == EPFNOSUPPORT + || errno == EAFNOSUPPORT) +@@ -143,6 +147,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, + errnop, herrnop, BYNAME); + if (net_buffer.buf != orig_net_buffer) + free (net_buffer.buf); ++ __resolv_context_put (ctx); + return status; + } + +@@ -170,8 +175,13 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, + if (type != AF_INET) + return NSS_STATUS_UNAVAIL; + +- if (__res_maybe_init (&_res, 0) == -1) +- return NSS_STATUS_UNAVAIL; ++ struct resolv_context *ctx = __resolv_context_get (); ++ if (ctx == NULL) ++ { ++ *errnop = errno; ++ *herrnop = NETDB_INTERNAL; ++ return NSS_STATUS_UNAVAIL; ++ } + + net2 = (u_int32_t) net; + for (cnt = 4; net2 != 0; net2 >>= 8) +@@ -201,8 +211,8 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, + + net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); + +- anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, +- 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); ++ anslen = __res_context_query (ctx, qbuf, C_IN, T_PTR, net_buffer.buf->buf, ++ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL); + if (anslen < 0) + { + /* Nothing found. */ +@@ -210,6 +220,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, + __set_errno (olderr); + if (net_buffer.buf != orig_net_buffer) + free (net_buffer.buf); ++ __resolv_context_put (ctx); + return (err == ECONNREFUSED + || err == EPFNOSUPPORT + || err == EAFNOSUPPORT) +@@ -230,13 +241,11 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result, + result->n_net = u_net; + } + ++ __resolv_context_put (ctx); + return status; + } + + +-#undef offsetof +-#define offsetof(Type, Member) ((size_t) &((Type *) NULL)->Member) +- + static enum nss_status + getanswer_r (const querybuf *answer, int anslen, struct netent *result, + char *buffer, size_t buflen, int *errnop, int *h_errnop, +@@ -265,7 +274,7 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, + uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct net_data); + buffer += pad; + +- if (__builtin_expect (buflen < sizeof (*net_data) + pad, 0)) ++ if (__glibc_unlikely (buflen < sizeof (*net_data) + pad)) + { + /* The buffer is too small. */ + too_small: +@@ -326,11 +335,8 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, + + while (--answer_count >= 0 && cp < end_of_message) + { +- int n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen); +- int type, class; +- +- n = __ns_name_unpack (answer->buf, end_of_message, cp, +- packtmp, sizeof packtmp); ++ int n = __ns_name_unpack (answer->buf, end_of_message, cp, ++ packtmp, sizeof packtmp); + if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1) + { + if (errno == EMSGSIZE) +@@ -345,10 +351,24 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, + if (n < 0 || res_dnok (bp) == 0) + break; + cp += n; ++ ++ if (end_of_message - cp < 10) ++ { ++ __set_h_errno (NO_RECOVERY); ++ return NSS_STATUS_UNAVAIL; ++ } ++ ++ int type, class; + GETSHORT (type, cp); + GETSHORT (class, cp); + cp += INT32SZ; /* TTL */ +- GETSHORT (n, cp); ++ uint16_t rdatalen; ++ GETSHORT (rdatalen, cp); ++ if (end_of_message - cp < rdatalen) ++ { ++ __set_h_errno (NO_RECOVERY); ++ return NSS_STATUS_UNAVAIL; ++ } + + if (class == C_IN && type == T_PTR) + { +@@ -370,7 +390,7 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, + cp += n; + return NSS_STATUS_UNAVAIL; + } +- cp += n; ++ cp += rdatalen; + if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES]) + { + *alias_pointer++ = bp; +@@ -381,6 +401,9 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, + ++have_answer; + } + } ++ else ++ /* Skip over unknown record data. */ ++ cp += rdatalen; + } + + if (have_answer) +@@ -395,8 +418,8 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result, + + case BYNAME: + { +- char **ap = result->n_aliases++; +- while (*ap != NULL) ++ char **ap; ++ for (ap = result->n_aliases; *ap != NULL; ++ap) + { + /* Check each alias name for being of the forms: + 4.3.2.1.in-addr.arpa = net 1.2.3.4 +diff --git a/resolv/res-close.c b/resolv/res-close.c +new file mode 100644 +index 0000000000000000..21f038c2c77f7375 +--- /dev/null ++++ b/resolv/res-close.c +@@ -0,0 +1,143 @@ ++/* Deallocation functions for the resolver state. ++ Copyright (C) 1995-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* ++ * Copyright (c) 1985, 1989, 1993 ++ * The Regents of the University of California. 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. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. ++ */ ++ ++/* ++ * Portions Copyright (c) 1993 by Digital Equipment Corporation. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies, and that ++ * the name of Digital Equipment Corporation not be used in advertising or ++ * publicity pertaining to distribution of the document or software without ++ * specific, written prior permission. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL ++ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT ++ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++/* ++ * Portions Copyright (c) 1996-1999 by Internet Software Consortium. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS ++ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE ++ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* Close all open sockets. If FREE_ADDR is true, deallocate any ++ separately allocated name server addresses. */ ++void ++__res_iclose (res_state statp, bool free_addr) ++{ ++ if (statp->_vcsock >= 0) ++ { ++ close_not_cancel_no_status (statp->_vcsock); ++ statp->_vcsock = -1; ++ statp->_flags &= ~(RES_F_VC | RES_F_CONN); ++ } ++ for (int ns = 0; ns < statp->nscount; ns++) ++ if (statp->_u._ext.nsaddrs[ns] != NULL) ++ { ++ if (statp->_u._ext.nssocks[ns] != -1) ++ { ++ close_not_cancel_no_status (statp->_u._ext.nssocks[ns]); ++ statp->_u._ext.nssocks[ns] = -1; ++ } ++ if (free_addr) ++ { ++ free (statp->_u._ext.nsaddrs[ns]); ++ statp->_u._ext.nsaddrs[ns] = NULL; ++ } ++ } ++ if (free_addr) ++ __resolv_conf_detach (statp); ++} ++libc_hidden_def (__res_iclose) ++ ++void ++res_nclose (res_state statp) ++{ ++ __res_iclose (statp, true); ++} ++libc_hidden_def (__res_nclose) ++ ++/* This is called when a thread is exiting to free resources held in _res. */ ++static void __attribute__ ((section ("__libc_thread_freeres_fn"))) ++res_thread_freeres (void) ++{ ++ __resolv_context_freeres (); ++ ++ if (_res.nscount == 0) ++ /* Never called res_ninit. */ ++ return; ++ ++ __res_iclose (&_res, true); /* Close any VC sockets. */ ++ ++ /* Make sure we do a full re-initialization the next time. */ ++ _res.options = 0; ++} ++text_set_element (__libc_thread_subfreeres, res_thread_freeres); ++text_set_element (__libc_subfreeres, res_thread_freeres); +diff --git a/resolv/res-state.c b/resolv/res-state.c +index 3a2a4d5649c9af3f..4d4245459bfc68ca 100644 +--- a/resolv/res-state.c ++++ b/resolv/res-state.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996, 97, 98, 2002, 2003, 2011 Free Software Foundation, Inc. ++/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +diff --git a/resolv/res_comp.c b/resolv/res_comp.c +index c7212fab11deda78..ffb2ed59147d3680 100644 +--- a/resolv/res_comp.c ++++ b/resolv/res_comp.c +@@ -64,11 +64,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; +-static const char rcsid[] = "$BINDId: res_comp.c,v 8.15 1999/10/13 16:39:39 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +@@ -81,7 +76,7 @@ static const char rcsid[] = "$BINDId: res_comp.c,v 8.15 1999/10/13 16:39:39 vixi + + /* + * Expand compressed domain name 'comp_dn' to full domain name. +- * 'msg' is a pointer to the begining of the message, ++ * 'msg' is a pointer to the beginning of the message, + * 'eomorig' points to the first location after the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. + * Return size of compressed name or -1 if there was an error. +@@ -233,7 +228,6 @@ res_dnok(const char *dn) { + } + libresolv_hidden_def (res_dnok) + +-#ifdef BIND_4_COMPAT + /* + * This module must export the following externally-visible symbols: + * ___putlong +@@ -246,11 +240,8 @@ void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); } + libresolv_hidden_def (__putlong) + void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); } + libresolv_hidden_def (__putshort) +-#ifndef __ultrix__ + u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); } + u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); } +-#endif /*__ultrix__*/ +-#endif /*BIND_4_COMPAT*/ + + + #include +diff --git a/resolv/res_data.c b/resolv/res_data.c +index 1beea1dc4fb8c2c4..2cafd3805548d8e4 100644 +--- a/resolv/res_data.c ++++ b/resolv/res_data.c +@@ -1,3 +1,21 @@ ++/* Miscellaneous definitions for libresolv. ++ Copyright (C) 1995-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1995-1999 by Internet Software Consortium. + * +@@ -15,322 +33,22 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char rcsid[] = "$BINDId: res_data.c,v 8.17 1999/10/13 17:11:31 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#include +-#include + #include +-#ifdef BIND_UPDATE +-#include +-#endif +-#include +-#include +-#include +-#include +- +-const char *_res_opcodes[] = { +- "QUERY", +- "IQUERY", +- "CQUERYM", +- "CQUERYU", /* experimental */ +- "NOTIFY", /* experimental */ +- "UPDATE", +- "6", +- "7", +- "8", +- "9", +- "10", +- "11", +- "12", +- "13", +- "ZONEINIT", +- "ZONEREF", +-}; +-libresolv_hidden_data_def (_res_opcodes) +- +-#ifdef BIND_UPDATE +-const char *_res_sectioncodes[] attribute_hidden = { +- "ZONE", +- "PREREQUISITES", +- "UPDATE", +- "ADDITIONAL", +-}; +-#endif +- +-#ifndef __BIND_NOSTATIC +-#ifdef _LIBC +-/* The definition has been moved to res_libc.c. */ +-#else +-#undef _res +-struct __res_state _res +-# if defined(__BIND_RES_TEXT) +- = { RES_TIMEOUT, } /* Motorola, et al. */ +-# endif +- ; +-#endif +- +-/* Proto. */ +-#ifndef _LIBC +-int res_ourserver_p(const res_state, const struct sockaddr_in *); +-void res_pquery(const res_state, const u_char *, int, FILE *); +-#endif +- +-#ifndef _LIBC +-/* Moved to res_libc.c since res_init() should go into libc.so but the +- rest of this file not. */ +-int +-res_init(void) { +- extern int __res_vinit(res_state, int); +- +- /* +- * These three fields used to be statically initialized. This made +- * it hard to use this code in a shared library. It is necessary, +- * now that we're doing dynamic initialization here, that we preserve +- * the old semantics: if an application modifies one of these three +- * fields of _res before res_init() is called, res_init() will not +- * alter them. Of course, if an application is setting them to +- * _zero_ before calling res_init(), hoping to override what used +- * to be the static default, we can't detect it and unexpected results +- * will follow. Zero for any of these fields would make no sense, +- * so one can safely assume that the applications were already getting +- * unexpected results. +- * +- * _res.options is tricky since some apps were known to diddle the bits +- * before res_init() was first called. We can't replicate that semantic +- * with dynamic initialization (they may have turned bits off that are +- * set in RES_DEFAULT). Our solution is to declare such applications +- * "broken". They could fool us by setting RES_INIT but none do (yet). +- */ +- if (!_res.retrans) +- _res.retrans = RES_TIMEOUT; +- if (!_res.retry) +- _res.retry = 4; +- if (!(_res.options & RES_INIT)) +- _res.options = RES_DEFAULT; +- +- /* +- * This one used to initialize implicitly to zero, so unless the app +- * has set it to something in particular, we can randomize it now. +- */ +- if (!_res.id) +- _res.id = res_randomid(); +- +- return (__res_vinit(&_res, 1)); +-} +-#endif + ++/* This function belongs to libresolv, which is why it is not included ++ in res-close.c. */ + void +-p_query(const u_char *msg) { +- fp_query(msg, stdout); +-} +- +-void +-fp_query(const u_char *msg, FILE *file) { +- fp_nquery(msg, PACKETSZ, file); +-} +-libresolv_hidden_def (fp_query) +- +-void +-fp_nquery(const u_char *msg, int len, FILE *file) { +- if (__res_maybe_init (&_res, 0) == -1) +- return; +- +- res_pquery(&_res, msg, len, file); +-} +-libresolv_hidden_def (fp_nquery) +- +-int +-res_mkquery(int op, /* opcode of query */ +- const char *dname, /* domain name */ +- int class, int type, /* class and type of query */ +- const u_char *data, /* resource record data */ +- int datalen, /* length of data */ +- const u_char *newrr_in, /* new rr for modify or append */ +- u_char *buf, /* buffer to put query */ +- int buflen) /* size of buffer */ ++__res_close (void) + { +- if (__res_maybe_init (&_res, 1) == -1) { +- RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); +- return (-1); +- } +- return (res_nmkquery(&_res, op, dname, class, type, +- data, datalen, +- newrr_in, buf, buflen)); ++ /* Some programs call res_close before res_init. Since _res._vcsock ++ isn't explicitly initialized, these means that we could call ++ close (0), which might lead to some security problems. Therefore ++ we check if res_init was called before by looking at the RES_INIT ++ bit in _res.options. If it hasn't been set we bail out ++ early. */ ++ if ((_res.options & RES_INIT) == 0) ++ return; ++ /* We don't free the name server addresses because we never did it ++ and it would be done implicitly on shutdown. */ ++ __res_iclose (&_res, false); + } +- +-#ifdef BIND_UPDATE +-int +-res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { +- if (__res_maybe_init (&_res, 1) == -1) { +- RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); +- return (-1); +- } +- +- return (res_nmkupdate(&_res, rrecp_in, buf, buflen)); +-} +-#endif +- +-int +-res_query(const char *name, /* domain name */ +- int class, int type, /* class and type of query */ +- u_char *answer, /* buffer to put answer */ +- int anslen) /* size of answer buffer */ +-{ +- if (__res_maybe_init (&_res, 1) == -1) { +- RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); +- return (-1); +- } +- return (res_nquery(&_res, name, class, type, answer, anslen)); +-} +- +-void +-res_send_setqhook(res_send_qhook hook) { +- _res.qhook = hook; +-} +- +-void +-res_send_setrhook(res_send_rhook hook) { +- _res.rhook = hook; +-} +- +-int +-res_isourserver(const struct sockaddr_in *inp) { +- return (res_ourserver_p(&_res, (const struct sockaddr_in6 *) inp)); +-} +- +-int +-res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { +- if (__res_maybe_init (&_res, 1) == -1) { +- /* errno should have been set by res_init() in this case. */ +- return (-1); +- } +- +- return (res_nsend(&_res, buf, buflen, ans, anssiz)); +-} +- +-#ifndef _LIBC +-int +-res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, +- u_char *ans, int anssiz) +-{ +- if (__res_maybe_init (&_res, 1) == -1) { +- /* errno should have been set by res_init() in this case. */ +- return (-1); +- } +- +- return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz)); +-} +-#endif +- +-void +-res_close(void) { +-#ifdef _LIBC +- /* +- * Some stupid programs out there call res_close() before res_init(). +- * Since _res._vcsock isn't explicitly initialized, these means that +- * we could do a close(0), which might lead to some security problems. +- * Therefore we check if res_init() was called before by looking at +- * the RES_INIT bit in _res.options. If it hasn't been set we bail out +- * early. */ +- if ((_res.options & RES_INIT) == 0) +- return; +-#endif +- /* We don't free the name server addresses because we never +- did it and it would be done implicitly on shutdown. */ +- __res_iclose(&_res, false); +-} +- +-#ifdef BIND_UPDATE +-int +-res_update(ns_updrec *rrecp_in) { +- if (__res_maybe_init (&_res, 1) == -1) { +- RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); +- return (-1); +- } +- +- return (res_nupdate(&_res, rrecp_in, NULL)); +-} +-#endif +- +-int +-res_search(const char *name, /* domain name */ +- int class, int type, /* class and type of query */ +- u_char *answer, /* buffer to put answer */ +- int anslen) /* size of answer */ +-{ +- if (__res_maybe_init (&_res, 1) == -1) { +- RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); +- return (-1); +- } +- +- return (res_nsearch(&_res, name, class, type, answer, anslen)); +-} +- +-int +-res_querydomain(const char *name, +- const char *domain, +- int class, int type, /* class and type of query */ +- u_char *answer, /* buffer to put answer */ +- int anslen) /* size of answer */ +-{ +- if (__res_maybe_init (&_res, 1) == -1) { +- RES_SET_H_ERRNO(&_res, NETDB_INTERNAL); +- return (-1); +- } +- +- return (res_nquerydomain(&_res, name, domain, +- class, type, +- answer, anslen)); +-} +- +-const char * +-hostalias(const char *name) { +- static char abuf[MAXDNAME]; +- +- return (res_hostalias(&_res, name, abuf, sizeof abuf)); +-} +-libresolv_hidden_def (hostalias) +- +-#ifdef ultrix +-int +-local_hostname_length(const char *hostname) { +- int len_host, len_domain; +- +- if (!*_res.defdname) +- res_init(); +- len_host = strlen(hostname); +- len_domain = strlen(_res.defdname); +- if (len_host > len_domain && +- !strcasecmp(hostname + len_host - len_domain, _res.defdname) && +- hostname[len_host - len_domain - 1] == '.') +- return (len_host - len_domain - 1); +- return (0); +-} +-#endif /*ultrix*/ +- +-#endif +- +- +-#include +- +-#if SHLIB_COMPAT(libresolv, GLIBC_2_0, GLIBC_2_2) +-# undef res_mkquery +-# undef res_query +-# undef res_querydomain +-# undef res_search +-weak_alias (__res_mkquery, res_mkquery); +-weak_alias (__res_query, res_query); +-weak_alias (__res_querydomain, res_querydomain); +-weak_alias (__res_search, res_search); +-#endif +diff --git a/resolv/res_debug.c b/resolv/res_debug.c +index 6549e4ba5ee77f93..919b86e2b37dc150 100644 +--- a/resolv/res_debug.c ++++ b/resolv/res_debug.c +@@ -89,11 +89,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; +-static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +@@ -111,6 +106,7 @@ static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vix + #include + #include + #include ++#include + + #ifdef SPRINTF_CHAR + # define SPRINTF(x) strlen(sprintf/**/x) +@@ -120,6 +116,36 @@ static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vix + + extern const char *_res_sectioncodes[] attribute_hidden; + ++/* _res_opcodes was exported by accident as a variable. */ ++#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_26) ++static const char *res_opcodes[] = ++#else ++static const char res_opcodes[][9] = ++#endif ++ { ++ "QUERY", ++ "IQUERY", ++ "CQUERYM", ++ "CQUERYU", /* experimental */ ++ "NOTIFY", /* experimental */ ++ "UPDATE", ++ "6", ++ "7", ++ "8", ++ "9", ++ "10", ++ "11", ++ "12", ++ "13", ++ "ZONEINIT", ++ "ZONEREF", ++ }; ++#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_26) ++strong_alias (res_opcodes, _res_opcodes) ++#endif ++ ++static const char *p_section(int section, int opcode); ++ + /* + * Print the current options. + */ +@@ -135,9 +161,7 @@ fp_resstat(const res_state statp, FILE *file) { + } + + static void +-do_section(const res_state statp, +- ns_msg *handle, ns_sect section, +- int pflag, FILE *file) ++do_section (int pfcode, ns_msg *handle, ns_sect section, int pflag, FILE *file) + { + int n, sflag, rrnum; + static int buflen = 2048; +@@ -148,8 +172,8 @@ do_section(const res_state statp, + /* + * Print answer records. + */ +- sflag = (statp->pfcode & pflag); +- if (statp->pfcode && !sflag) ++ sflag = (pfcode & pflag); ++ if (pfcode && !sflag) + return; + + buf = malloc(buflen); +@@ -166,11 +190,11 @@ do_section(const res_state statp, + fprintf(file, ";; ns_parserr: %s\n", + strerror(errno)); + else if (rrnum > 0 && sflag != 0 && +- (statp->pfcode & RES_PRF_HEAD1)) ++ (pfcode & RES_PRF_HEAD1)) + putc('\n', file); + goto cleanup; + } +- if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) ++ if (rrnum == 0 && sflag != 0 && (pfcode & RES_PRF_HEAD1)) + fprintf(file, ";; %s SECTION:\n", + p_section(section, opcode)); + if (section == ns_s_qd) +@@ -212,11 +236,19 @@ do_section(const res_state statp, + * This is intended to be primarily a debugging routine. + */ + void +-res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { ++fp_nquery (const unsigned char *msg, int len, FILE *file) ++{ + ns_msg handle; + int qdcount, ancount, nscount, arcount; + u_int opcode, rcode, id; + ++ /* There is no need to initialize _res: If _res is not yet ++ initialized, _res.pfcode is zero. But initialization will ++ leave it at zero, too. _res.pfcode is an unsigned long, ++ but the code here assumes that the flags fit into an int, ++ so use that. */ ++ int pfcode = _res.pfcode; ++ + if (ns_initparse(msg, len, &handle) < 0) { + fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); + return; +@@ -232,13 +264,13 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { + /* + * Print header fields. + */ +- if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode) ++ if ((!pfcode) || (pfcode & RES_PRF_HEADX) || rcode) + fprintf(file, + ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", +- _res_opcodes[opcode], p_rcode(rcode), id); +- if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX)) ++ res_opcodes[opcode], p_rcode(rcode), id); ++ if ((!pfcode) || (pfcode & RES_PRF_HEADX)) + putc(';', file); +- if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) { ++ if ((!pfcode) || (pfcode & RES_PRF_HEAD2)) { + fprintf(file, "; flags:"); + if (ns_msg_getflag(handle, ns_f_qr)) + fprintf(file, " qr"); +@@ -257,7 +289,7 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { + if (ns_msg_getflag(handle, ns_f_cd)) + fprintf(file, " cd"); + } +- if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) { ++ if ((!pfcode) || (pfcode & RES_PRF_HEAD1)) { + fprintf(file, "; %s: %d", + p_section(ns_s_qd, opcode), qdcount); + fprintf(file, ", %s: %d", +@@ -267,21 +299,35 @@ res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { + fprintf(file, ", %s: %d", + p_section(ns_s_ar, opcode), arcount); + } +- if ((!statp->pfcode) || (statp->pfcode & ++ if ((!pfcode) || (pfcode & + (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { + putc('\n',file); + } + /* + * Print the various sections. + */ +- do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file); +- do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file); +- do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file); +- do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file); ++ do_section (pfcode, &handle, ns_s_qd, RES_PRF_QUES, file); ++ do_section (pfcode, &handle, ns_s_an, RES_PRF_ANS, file); ++ do_section (pfcode, &handle, ns_s_ns, RES_PRF_AUTH, file); ++ do_section (pfcode, &handle, ns_s_ar, RES_PRF_ADD, file); + if (qdcount == 0 && ancount == 0 && + nscount == 0 && arcount == 0) + putc('\n', file); + } ++libresolv_hidden_def (fp_nquery) ++ ++void ++fp_query (const unsigned char *msg, FILE *file) ++{ ++ fp_nquery (msg, PACKETSZ, file); ++} ++libresolv_hidden_def (fp_query) ++ ++void ++p_query (const unsigned char *msg) ++{ ++ fp_query (msg, stdout); ++} + + const u_char * + p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) { +@@ -307,11 +353,8 @@ p_cdname(const u_char *cp, const u_char *msg, FILE *file) { + length supplied). */ + + const u_char * +-p_fqnname(cp, msg, msglen, name, namelen) +- const u_char *cp, *msg; +- int msglen; +- char *name; +- int namelen; ++p_fqnname (const u_char *cp, const u_char *msg, int msglen, char *name, ++ int namelen) + { + int n, newlen; + +@@ -350,13 +393,13 @@ p_fqname(const u_char *cp, const u_char *msg, FILE *file) { + extern const struct res_sym __p_class_syms[]; + libresolv_hidden_proto (__p_class_syms) + const struct res_sym __p_class_syms[] = { +- {C_IN, "IN"}, +- {C_CHAOS, "CHAOS"}, +- {C_HS, "HS"}, +- {C_HS, "HESIOD"}, +- {C_ANY, "ANY"}, +- {C_NONE, "NONE"}, +- {C_IN, (char *)0} ++ {C_IN, (char *) "IN"}, ++ {C_CHAOS, (char *) "CHAOS"}, ++ {C_HS, (char *) "HS"}, ++ {C_HS, (char *) "HESIOD"}, ++ {C_ANY, (char *) "ANY"}, ++ {C_NONE, (char *) "NONE"}, ++ {C_IN, NULL, NULL} + }; + libresolv_hidden_data_def (__p_class_syms) + +@@ -364,93 +407,75 @@ libresolv_hidden_data_def (__p_class_syms) + * Names of message sections. + */ + const struct res_sym __p_default_section_syms[] attribute_hidden = { +- {ns_s_qd, "QUERY"}, +- {ns_s_an, "ANSWER"}, +- {ns_s_ns, "AUTHORITY"}, +- {ns_s_ar, "ADDITIONAL"}, +- {0, (char *)0} ++ {ns_s_qd, (char *) "QUERY"}, ++ {ns_s_an, (char *) "ANSWER"}, ++ {ns_s_ns, (char *) "AUTHORITY"}, ++ {ns_s_ar, (char *) "ADDITIONAL"}, ++ {0, NULL, NULL} + }; + + const struct res_sym __p_update_section_syms[] attribute_hidden = { +- {S_ZONE, "ZONE"}, +- {S_PREREQ, "PREREQUISITE"}, +- {S_UPDATE, "UPDATE"}, +- {S_ADDT, "ADDITIONAL"}, +- {0, (char *)0} +-}; +- +-const struct res_sym __p_key_syms[] attribute_hidden = { +- {NS_ALG_MD5RSA, "RSA", "RSA KEY with MD5 hash"}, +- {NS_ALG_DH, "DH", "Diffie Hellman"}, +- {NS_ALG_DSA, "DSA", "Digital Signature Algorithm"}, +- {NS_ALG_EXPIRE_ONLY, "EXPIREONLY", "No algorithm"}, +- {NS_ALG_PRIVATE_OID, "PRIVATE", "Algorithm obtained from OID"}, +- {0, NULL, NULL} +-}; +- +-const struct res_sym __p_cert_syms[] attribute_hidden = { +- {cert_t_pkix, "PKIX", "PKIX (X.509v3) Certificate"}, +- {cert_t_spki, "SPKI", "SPKI certificate"}, +- {cert_t_pgp, "PGP", "PGP certificate"}, +- {cert_t_url, "URL", "URL Private"}, +- {cert_t_oid, "OID", "OID Private"}, +- {0, NULL, NULL} ++ {S_ZONE, (char *) "ZONE"}, ++ {S_PREREQ, (char *) "PREREQUISITE"}, ++ {S_UPDATE, (char *) "UPDATE"}, ++ {S_ADDT, (char *) "ADDITIONAL"}, ++ {0, NULL, NULL} + }; + + /* +- * Names of RR types and qtypes. Types and qtypes are the same, except +- * that T_ANY is a qtype but not a type. (You can ask for records of type +- * T_ANY, but you can't have any records of that type in the database.) ++ * Names of RR types and qtypes. The list is incomplete because its ++ * size is part of the ABI. + */ + extern const struct res_sym __p_type_syms[]; + libresolv_hidden_proto (__p_type_syms) + const struct res_sym __p_type_syms[] = { +- {ns_t_a, "A", "address"}, +- {ns_t_ns, "NS", "name server"}, +- {ns_t_md, "MD", "mail destination (deprecated)"}, +- {ns_t_mf, "MF", "mail forwarder (deprecated)"}, +- {ns_t_cname, "CNAME", "canonical name"}, +- {ns_t_soa, "SOA", "start of authority"}, +- {ns_t_mb, "MB", "mailbox"}, +- {ns_t_mg, "MG", "mail group member"}, +- {ns_t_mr, "MR", "mail rename"}, +- {ns_t_null, "NULL", "null"}, +- {ns_t_wks, "WKS", "well-known service (deprecated)"}, +- {ns_t_ptr, "PTR", "domain name pointer"}, +- {ns_t_hinfo, "HINFO", "host information"}, +- {ns_t_minfo, "MINFO", "mailbox information"}, +- {ns_t_mx, "MX", "mail exchanger"}, +- {ns_t_txt, "TXT", "text"}, +- {ns_t_rp, "RP", "responsible person"}, +- {ns_t_afsdb, "AFSDB", "DCE or AFS server"}, +- {ns_t_x25, "X25", "X25 address"}, +- {ns_t_isdn, "ISDN", "ISDN address"}, +- {ns_t_rt, "RT", "router"}, +- {ns_t_nsap, "NSAP", "nsap address"}, +- {ns_t_nsap_ptr, "NSAP_PTR", "domain name pointer"}, +- {ns_t_sig, "SIG", "signature"}, +- {ns_t_key, "KEY", "key"}, +- {ns_t_px, "PX", "mapping information"}, +- {ns_t_gpos, "GPOS", "geographical position (withdrawn)"}, +- {ns_t_aaaa, "AAAA", "IPv6 address"}, +- {ns_t_loc, "LOC", "location"}, +- {ns_t_nxt, "NXT", "next valid name (unimplemented)"}, +- {ns_t_eid, "EID", "endpoint identifier (unimplemented)"}, +- {ns_t_nimloc, "NIMLOC", "NIMROD locator (unimplemented)"}, +- {ns_t_srv, "SRV", "server selection"}, +- {ns_t_atma, "ATMA", "ATM address (unimplemented)"}, +- {ns_t_dname, "DNAME", "Non-terminal DNAME (for IPv6)"}, +- {ns_t_tsig, "TSIG", "transaction signature"}, +- {ns_t_ixfr, "IXFR", "incremental zone transfer"}, +- {ns_t_axfr, "AXFR", "zone transfer"}, +- {ns_t_zxfr, "ZXFR", "compressed zone transfer"}, +- {ns_t_mailb, "MAILB", "mailbox-related data (deprecated)"}, +- {ns_t_maila, "MAILA", "mail agent (deprecated)"}, +- {ns_t_naptr, "NAPTR", "URN Naming Authority"}, +- {ns_t_kx, "KX", "Key Exchange"}, +- {ns_t_cert, "CERT", "Certificate"}, +- {ns_t_any, "ANY", "\"any\""}, +- {0, NULL, NULL} ++ {ns_t_a, (char *) "A", (char *) "address"}, ++ {ns_t_ns, (char *) "NS", (char *) "name server"}, ++ {ns_t_md, (char *) "MD", (char *) "mail destination (deprecated)"}, ++ {ns_t_mf, (char *) "MF", (char *) "mail forwarder (deprecated)"}, ++ {ns_t_cname, (char *) "CNAME", (char *) "canonical name"}, ++ {ns_t_soa, (char *) "SOA", (char *) "start of authority"}, ++ {ns_t_mb, (char *) "MB", (char *) "mailbox"}, ++ {ns_t_mg, (char *) "MG", (char *) "mail group member"}, ++ {ns_t_mr, (char *) "MR", (char *) "mail rename"}, ++ {ns_t_null, (char *) "NULL", (char *) "null"}, ++ {ns_t_wks, (char *) "WKS", (char *) "well-known service (deprecated)"}, ++ {ns_t_ptr, (char *) "PTR", (char *) "domain name pointer"}, ++ {ns_t_hinfo, (char *) "HINFO", (char *) "host information"}, ++ {ns_t_minfo, (char *) "MINFO", (char *) "mailbox information"}, ++ {ns_t_mx, (char *) "MX", (char *) "mail exchanger"}, ++ {ns_t_txt, (char *) "TXT", (char *) "text"}, ++ {ns_t_rp, (char *) "RP", (char *) "responsible person"}, ++ {ns_t_afsdb, (char *) "AFSDB", (char *) "DCE or AFS server"}, ++ {ns_t_x25, (char *) "X25", (char *) "X25 address"}, ++ {ns_t_isdn, (char *) "ISDN", (char *) "ISDN address"}, ++ {ns_t_rt, (char *) "RT", (char *) "router"}, ++ {ns_t_nsap, (char *) "NSAP", (char *) "nsap address"}, ++ {ns_t_nsap_ptr, (char *) "NSAP_PTR", (char *) "domain name pointer"}, ++ {ns_t_sig, (char *) "SIG", (char *) "signature"}, ++ {ns_t_key, (char *) "KEY", (char *) "key"}, ++ {ns_t_px, (char *) "PX", (char *) "mapping information"}, ++ {ns_t_gpos, (char *) "GPOS", ++ (char *) "geographical position (withdrawn)"}, ++ {ns_t_aaaa, (char *) "AAAA", (char *) "IPv6 address"}, ++ {ns_t_loc, (char *) "LOC", (char *) "location"}, ++ {ns_t_nxt, (char *) "NXT", (char *) "next valid name (unimplemented)"}, ++ {ns_t_eid, (char *) "EID", (char *) "endpoint identifier (unimplemented)"}, ++ {ns_t_nimloc, (char *) "NIMLOC", (char *) "NIMROD locator (unimplemented)"}, ++ {ns_t_srv, (char *) "SRV", (char *) "server selection"}, ++ {ns_t_atma, (char *) "ATMA", (char *) "ATM address (unimplemented)"}, ++ {ns_t_dname, (char *) "DNAME", (char *) "Non-terminal DNAME (for IPv6)"}, ++ {ns_t_tsig, (char *) "TSIG", (char *) "transaction signature"}, ++ {ns_t_ixfr, (char *) "IXFR", (char *) "incremental zone transfer"}, ++ {ns_t_axfr, (char *) "AXFR", (char *) "zone transfer"}, ++ {ns_t_mailb, (char *) "MAILB", (char *) "mailbox-related data (deprecated)"}, ++ {ns_t_maila, (char *) "MAILA", (char *) "mail agent (deprecated)"}, ++ {ns_t_naptr, (char *) "NAPTR", (char *) "URN Naming Authority"}, ++ {ns_t_kx, (char *) "KX", (char *) "Key Exchange"}, ++ {ns_t_cert, (char *) "CERT", (char *) "Certificate"}, ++ {ns_t_any, (char *) "ANY", (char *) "\"any\""}, ++ {0, NULL, NULL}, /* Padding to preserve ABI. */ ++ {0, NULL, NULL} + }; + libresolv_hidden_data_def (__p_type_syms) + +@@ -458,22 +483,22 @@ libresolv_hidden_data_def (__p_type_syms) + * Names of DNS rcodes. + */ + const struct res_sym __p_rcode_syms[] attribute_hidden = { +- {ns_r_noerror, "NOERROR", "no error"}, +- {ns_r_formerr, "FORMERR", "format error"}, +- {ns_r_servfail, "SERVFAIL", "server failed"}, +- {ns_r_nxdomain, "NXDOMAIN", "no such domain name"}, +- {ns_r_notimpl, "NOTIMP", "not implemented"}, +- {ns_r_refused, "REFUSED", "refused"}, +- {ns_r_yxdomain, "YXDOMAIN", "domain name exists"}, +- {ns_r_yxrrset, "YXRRSET", "rrset exists"}, +- {ns_r_nxrrset, "NXRRSET", "rrset doesn't exist"}, +- {ns_r_notauth, "NOTAUTH", "not authoritative"}, +- {ns_r_notzone, "NOTZONE", "Not in zone"}, +- {ns_r_max, "", ""}, +- {ns_r_badsig, "BADSIG", "bad signature"}, +- {ns_r_badkey, "BADKEY", "bad key"}, +- {ns_r_badtime, "BADTIME", "bad time"}, +- {0, NULL, NULL} ++ {ns_r_noerror, (char *) "NOERROR", (char *) "no error"}, ++ {ns_r_formerr, (char *) "FORMERR", (char *) "format error"}, ++ {ns_r_servfail, (char *) "SERVFAIL", (char *) "server failed"}, ++ {ns_r_nxdomain, (char *) "NXDOMAIN", (char *) "no such domain name"}, ++ {ns_r_notimpl, (char *) "NOTIMP", (char *) "not implemented"}, ++ {ns_r_refused, (char *) "REFUSED", (char *) "refused"}, ++ {ns_r_yxdomain, (char *) "YXDOMAIN", (char *) "domain name exists"}, ++ {ns_r_yxrrset, (char *) "YXRRSET", (char *) "rrset exists"}, ++ {ns_r_nxrrset, (char *) "NXRRSET", (char *) "rrset doesn't exist"}, ++ {ns_r_notauth, (char *) "NOTAUTH", (char *) "not authoritative"}, ++ {ns_r_notzone, (char *) "NOTZONE", (char *) "Not in zone"}, ++ {ns_r_max, (char *) "", (char *) ""}, ++ {ns_r_badsig, (char *) "BADSIG", (char *) "bad signature"}, ++ {ns_r_badkey, (char *) "BADKEY", (char *) "bad key"}, ++ {ns_r_badtime, (char *) "BADTIME", (char *) "bad time"}, ++ {0, NULL, NULL} + }; + + int +@@ -538,7 +563,7 @@ libresolv_hidden_def (p_type) + /* + * Return a string for the type. + */ +-const char * ++static const char * + p_section(int section, int opcode) { + const struct res_sym *symbols; + +@@ -572,9 +597,7 @@ p_option(u_long option) { + switch (option) { + case RES_INIT: return "init"; + case RES_DEBUG: return "debug"; +- case RES_AAONLY: return "aaonly(unimpl)"; +- case RES_USEVC: return "usevc"; +- case RES_PRIMARY: return "primry(unimpl)"; ++ case RES_USEVC: return "use-vc"; + case RES_IGNTC: return "igntc"; + case RES_RECURSE: return "recurs"; + case RES_DEFNAMES: return "defnam"; +@@ -582,13 +605,15 @@ p_option(u_long option) { + case RES_DNSRCH: return "dnsrch"; + case RES_INSECURE1: return "insecure1"; + case RES_INSECURE2: return "insecure2"; ++ case RES_NOALIASES: return "noaliases"; + case DEPRECATED_RES_USE_INET6: return "inet6"; + case RES_ROTATE: return "rotate"; +- case RES_NOCHECKNAME: return "no-check-names"; +- case RES_USEBSTRING: return "ip6-bytstring"; + case RES_USE_EDNS0: return "edns0"; ++ case RES_SNGLKUP: return "single-request"; ++ case RES_SNGLKUPREOP: return "single-request-reopen"; + case RES_USE_DNSSEC: return "dnssec"; + case RES_NOTLDQUERY: return "no-tld-query"; ++ case RES_NORELOAD: return "no-reload"; + /* XXX nonreentrant */ + default: sprintf(nbuf, "?0x%lx?", (u_long)option); + return (nbuf); +@@ -784,9 +809,7 @@ latlon2ul (const char **latlonstrptr, int *which) + /* converts a zone file representation in a string to an RDATA on-the-wire + * representation. */ + int +-loc_aton(ascii, binary) +- const char *ascii; +- u_char *binary; ++loc_aton (const char *ascii, u_char *binary) + { + const char *cp, *maxcp; + u_char *bcp; +@@ -895,9 +918,7 @@ loc_aton(ascii, binary) + + /* takes an on-the-wire LOC RR and formats it in a human readable format. */ + const char * +-loc_ntoa(binary, ascii) +- const u_char *binary; +- char *ascii; ++loc_ntoa (const u_char *binary, char *ascii) + { + static const char error[] = "?"; + static char tmpbuf[sizeof +@@ -1041,13 +1062,8 @@ p_secstodate (u_long secs) { + time_t clock = secs; + struct tm *time; + +-#ifdef HAVE_TIME_R + struct tm timebuf; +- +- time = gmtime_r(&clock, &timebuf); +-#else +- time = gmtime(&clock); +-#endif ++ time = __gmtime_r(&clock, &timebuf); + time->tm_year += 1900; + time->tm_mon += 1; + sprintf(output, "%04d%02d%02d%02d%02d%02d", +diff --git a/resolv/res_debug.h b/resolv/res_debug.h +deleted file mode 100644 +index 4a0aa99ab48f362c..0000000000000000 +--- a/resolv/res_debug.h ++++ /dev/null +@@ -1,34 +0,0 @@ +-/* +- * Copyright (c) 1999 by Internet Software Consortium. +- * +- * Permission to use, copy, modify, and distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS +- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE +- * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +- * SOFTWARE. +- */ +- +-#ifndef _RES_DEBUG_H_ +-#define _RES_DEBUG_H_ +- +-#ifndef DEBUG +-# define Dprint(cond, args) /*empty*/ +-# define DprintQ(cond, args, query, size) /*empty*/ +-# define Aerror(statp, file, string, error, address) /*empty*/ +-# define Perror(statp, file, string, error) /*empty*/ +-#else +-# define Dprint(cond, args) if (cond) {fprintf args;} else {} +-# define DprintQ(cond, args, query, size) if (cond) {\ +- fprintf args;\ +- res_pquery(statp, query, size, stdout);\ +- } else {} +-#endif +- +-#endif /* _RES_DEBUG_H_ */ +diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c +index 66383deea81cf3eb..8fc06e9abdc084f6 100644 +--- a/resolv/res_hconf.c ++++ b/resolv/res_hconf.c +@@ -1,5 +1,4 @@ +-/* Copyright (C) 1993,1995-2006,2007,2009,2011 +- Free Software Foundation, Inc. ++/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Mosberger (davidm@azstarnet.com). + +@@ -22,9 +21,6 @@ + Though mostly compatibly, the following differences exist compared + to the original implementation: + +- - new command "spoof" takes an arguments like RESOLV_SPOOF_CHECK +- environment variable (i.e., `off', `nowarn', or `warn'). +- + - line comments can appear anywhere (not just at the beginning of + a line) + */ +@@ -42,16 +38,20 @@ + #include + #include + #include +-#include ++#include + #include "ifreq.h" + #include "res_hconf.h" + #include ++#include ++ ++#if IS_IN (libc) ++# define fgets_unlocked __fgets_unlocked ++#endif + + #define _PATH_HOSTCONF "/etc/host.conf" + + /* Environment vars that all user to override default behavior: */ + #define ENV_HOSTCONF "RESOLV_HOST_CONF" +-#define ENV_SPOOF "RESOLV_SPOOF_CHECK" + #define ENV_TRIM_OVERR "RESOLV_OVERRIDE_TRIM_DOMAINS" + #define ENV_TRIM_ADD "RESOLV_ADD_TRIM_DOMAINS" + #define ENV_MULTI "RESOLV_MULTI" +@@ -61,7 +61,6 @@ enum parse_cbs + { + CB_none, + CB_arg_trimdomain_list, +- CB_arg_spoof, + CB_arg_bool + }; + +@@ -74,10 +73,7 @@ static const struct cmd + { + {"order", CB_none, 0}, + {"trim", CB_arg_trimdomain_list, 0}, +- {"spoof", CB_arg_spoof, 0}, + {"multi", CB_arg_bool, HCONF_FLAG_MULTI}, +- {"nospoof", CB_arg_bool, HCONF_FLAG_SPOOF}, +- {"spoofalert", CB_arg_bool, HCONF_FLAG_SPOOFALERT}, + {"reorder", CB_arg_bool, HCONF_FLAG_REORDER} + }; + +@@ -160,28 +156,6 @@ arg_trimdomain_list (const char *fname, int line_num, const char *args) + + + static const char * +-arg_spoof (const char *fname, int line_num, const char *args) +-{ +- const char *start = args; +- size_t len; +- +- args = skip_string (args); +- len = args - start; +- +- if (len == 3 && __strncasecmp (start, "off", len) == 0) +- _res_hconf.flags &= ~(HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT); +- else +- { +- _res_hconf.flags |= (HCONF_FLAG_SPOOF | HCONF_FLAG_SPOOFALERT); +- if ((len == 6 && __strncasecmp (start, "nowarn", len) == 0) +- || !(len == 4 && __strncasecmp (start, "warn", len) == 0)) +- _res_hconf.flags &= ~HCONF_FLAG_SPOOFALERT; +- } +- return args; +-} +- +- +-static const char * + arg_bool (const char *fname, int line_num, const char *args, unsigned flag) + { + if (__strncasecmp (args, "on", 2) == 0) +@@ -257,8 +231,6 @@ parse_line (const char *fname, int line_num, const char *str) + + if (c->cb == CB_arg_trimdomain_list) + str = arg_trimdomain_list (fname, line_num, str); +- else if (c->cb == CB_arg_spoof) +- str = arg_spoof (fname, line_num, str); + else if (c->cb == CB_arg_bool) + str = arg_bool (fname, line_num, str, c->arg); + else +@@ -321,10 +293,6 @@ do_init (void) + fclose (fp); + } + +- envval = getenv (ENV_SPOOF); +- if (envval) +- arg_spoof (ENV_SPOOF, 1, envval); +- + envval = getenv (ENV_MULTI); + if (envval) + arg_bool (ENV_MULTI, 1, envval, HCONF_FLAG_MULTI); +@@ -344,7 +312,8 @@ do_init (void) + arg_trimdomain_list (ENV_TRIM_OVERR, 1, envval); + } + +- _res_hconf.initialized = 1; ++ /* See comments on the declaration of _res_hconf. */ ++ atomic_store_release (&_res_hconf.initialized, 1); + } + + +@@ -360,6 +329,7 @@ _res_hconf_init (void) + + + #if IS_IN (libc) ++# if defined SIOCGIFCONF && defined SIOCGIFNETMASK + /* List of known interfaces. */ + libc_freeres_ptr ( + static struct netaddr +@@ -374,6 +344,7 @@ static struct netaddr + } ipv4; + } u; + } *ifaddrs); ++# endif + + /* Reorder addresses returned in a hostent such that the first address + is an address on the local subnet, if there is such an address. +@@ -386,9 +357,14 @@ _res_hconf_reorder_addrs (struct hostent *hp) + { + #if defined SIOCGIFCONF && defined SIOCGIFNETMASK + int i, j; +- /* Number of interfaces. */ ++ /* Number of interfaces. Also serves as a flag for the ++ double-checked locking idiom. */ + static int num_ifs = -1; +- /* We need to protect the dynamic buffer handling. */ ++ /* Local copy of num_ifs, for non-atomic access. */ ++ int num_ifs_local; ++ /* We need to protect the dynamic buffer handling. The lock is only ++ acquired during initialization. Afterwards, a positive num_ifs ++ value indicates completed initialization. */ + __libc_lock_define_initialized (static, lock); + + /* Only reorder if we're supposed to. */ +@@ -399,7 +375,10 @@ _res_hconf_reorder_addrs (struct hostent *hp) + if (hp->h_addrtype != AF_INET) + return; + +- if (num_ifs <= 0) ++ /* This load synchronizes with the release MO store in the ++ initialization block below. */ ++ num_ifs_local = atomic_load_acquire (&num_ifs); ++ if (num_ifs_local <= 0) + { + struct ifreq *ifr, *cur_ifr; + int sd, num, i; +@@ -409,16 +388,26 @@ _res_hconf_reorder_addrs (struct hostent *hp) + /* Initialize interface table. */ + + /* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket. */ +- sd = __socket (AF_INET, SOCK_DGRAM, 0); ++ sd = __socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sd < 0) + return; + + /* Get lock. */ + __libc_lock_lock (lock); + +- /* Recheck, somebody else might have done the work by done. */ +- if (num_ifs <= 0) ++ /* Recheck, somebody else might have done the work by now. No ++ ordering is required for the load because we have the lock, ++ and num_ifs is only updated under the lock. Also see (3) in ++ the analysis below. */ ++ num_ifs_local = atomic_load_relaxed (&num_ifs); ++ if (num_ifs_local <= 0) + { ++ /* This is the only block which writes to num_ifs. It can ++ be executed several times (sequentially) if ++ initialization does not yield any interfaces, and num_ifs ++ remains zero. However, once we stored a positive value ++ in num_ifs below, this block cannot be entered again due ++ to the condition above. */ + int new_num_ifs = 0; + + /* Get a list of interfaces. */ +@@ -434,18 +423,24 @@ _res_hconf_reorder_addrs (struct hostent *hp) + for (cur_ifr = ifr, i = 0; i < num; + cur_ifr = __if_nextreq (cur_ifr), ++i) + { ++ union ++ { ++ struct sockaddr sa; ++ struct sockaddr_in sin; ++ } ss; ++ + if (cur_ifr->ifr_addr.sa_family != AF_INET) + continue; + + ifaddrs[new_num_ifs].addrtype = AF_INET; +- ifaddrs[new_num_ifs].u.ipv4.addr = +- ((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr; ++ ss.sa = cur_ifr->ifr_addr; ++ ifaddrs[new_num_ifs].u.ipv4.addr = ss.sin.sin_addr.s_addr; + + if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0) + continue; + +- ifaddrs[new_num_ifs].u.ipv4.mask = +- ((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr; ++ ss.sa = cur_ifr->ifr_netmask; ++ ifaddrs[new_num_ifs].u.ipv4.mask = ss.sin.sin_addr.s_addr; + + /* Now we're committed to this entry. */ + ++new_num_ifs; +@@ -461,7 +456,14 @@ _res_hconf_reorder_addrs (struct hostent *hp) + /* Release lock, preserve error value, and close socket. */ + errno = save; + +- num_ifs = new_num_ifs; ++ /* Advertise successful initialization if new_num_ifs is ++ positive (and no updates to ifaddrs are permitted after ++ that). Otherwise, num_ifs remains unchanged, at zero. ++ This store synchronizes with the initial acquire MO ++ load. */ ++ atomic_store_release (&num_ifs, new_num_ifs); ++ /* Keep the local copy current, to save another load. */ ++ num_ifs_local = new_num_ifs; + } + + __libc_lock_unlock (lock); +@@ -469,15 +471,43 @@ _res_hconf_reorder_addrs (struct hostent *hp) + __close (sd); + } + +- if (num_ifs == 0) ++ /* num_ifs_local cannot be negative because the if statement above ++ covered this case. It can still be zero if we just performed ++ initialization, but could not find any interfaces. */ ++ if (num_ifs_local == 0) + return; + ++ /* The code below accesses ifaddrs, so we need to ensure that the ++ initialization happens-before this point. ++ ++ The actual initialization is sequenced-before the release store ++ to num_ifs, and sequenced-before the end of the critical section. ++ ++ This means there are three possible executions: ++ ++ (1) The thread that initialized the data also uses it, so ++ sequenced-before is sufficient to ensure happens-before. ++ ++ (2) The release MO store of num_ifs synchronizes-with the acquire ++ MO load, and the acquire MO load is sequenced before the use ++ of the initialized data below. ++ ++ (3) We enter the critical section, and the relaxed MO load of ++ num_ifs yields a positive value. The write to ifaddrs is ++ sequenced-before leaving the critical section. Leaving the ++ critical section happens-before we entered the critical ++ section ourselves, which means that the write to ifaddrs ++ happens-before this point. ++ ++ Consequently, all potential writes to ifaddrs (and the data it ++ points to) happens-before this point. */ ++ + /* Find an address for which we have a direct connection. */ + for (i = 0; hp->h_addr_list[i]; ++i) + { + struct in_addr *haddr = (struct in_addr *) hp->h_addr_list[i]; + +- for (j = 0; j < num_ifs; ++j) ++ for (j = 0; j < num_ifs_local; ++j) + { + u_int32_t if_addr = ifaddrs[j].u.ipv4.addr; + u_int32_t if_netmask = ifaddrs[j].u.ipv4.mask; +diff --git a/resolv/res_hconf.h b/resolv/res_hconf.h +index 90c56eb61a87ba26..209f76a0d6ef8193 100644 +--- a/resolv/res_hconf.h ++++ b/resolv/res_hconf.h +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1993, 1995-1998, 2006 Free Software Foundation, Inc. ++/* Copyright (C) 1993-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by David Mosberger (davidm@azstarnet.com). + +@@ -25,6 +25,15 @@ + + struct hconf + { ++ /* We keep the INITIALIZED member only for backwards compatibility. New ++ code should just call _res_hconf_init unconditionally. For this field ++ to be used safely, users must ensure that either (1) a call to ++ _res_hconf_init happens-before any load from INITIALIZED, or (2) an ++ assignment of zero to INITIALIZED happens-before any load from it, and ++ these loads use acquire MO if the intent is to skip calling ++ _res_hconf_init if the load returns a nonzero value. Such acquire MO ++ loads will then synchronize with the release MO store to INITIALIZED ++ in do_init in res_hconf.c; see pthread_once for more detail. */ + int initialized; + int unused1; + int unused2[4]; +@@ -32,14 +41,12 @@ struct hconf + const char *trimdomain[TRIMDOMAINS_MAX]; + unsigned int flags; + # define HCONF_FLAG_INITED (1 << 0) /* initialized? */ +-# define HCONF_FLAG_SPOOF (1 << 1) /* refuse spoofed addresses */ +-# define HCONF_FLAG_SPOOFALERT (1 << 2) /* syslog warning of spoofed */ + # define HCONF_FLAG_REORDER (1 << 3) /* list best address first */ + # define HCONF_FLAG_MULTI (1 << 4) /* see comments for gethtbyname() */ + }; + extern struct hconf _res_hconf; + +-extern void _res_hconf_init (void); ++extern void _res_hconf_init (void) attribute_hidden; + extern void _res_hconf_trim_domain (char *domain); + extern void _res_hconf_trim_domains (struct hostent *hp); + extern void _res_hconf_reorder_addrs (struct hostent *hp); +diff --git a/resolv/res_init.c b/resolv/res_init.c +index 0ed74e0520131418..4e1f9fe8dea93e8a 100644 +--- a/resolv/res_init.c ++++ b/resolv/res_init.c +@@ -1,3 +1,21 @@ ++/* Resolver state initialization and resolv.conf parsing. ++ Copyright (C) 1995-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1985, 1989, 1993 + * The Regents of the University of California. All rights reserved. +@@ -64,19 +82,16 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; +-static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -85,570 +100,608 @@ static const char rcsid[] = "$BINDId: res_init.c,v 8.16 2000/05/09 07:10:12 vixi + #include + #include + #include ++#include ++#include ++#include + +-#include ++static uint32_t net_mask (struct in_addr); + +-/* Options. Should all be left alone. */ +-#define RESOLVSORT +-#define RFC1535 +-/* #undef DEBUG */ ++int ++res_ninit (res_state statp) ++{ ++ return __res_vinit (statp, 0); ++} ++libc_hidden_def (__res_ninit) + +-static void res_setoptions (res_state, const char *, const char *) +- internal_function; ++/* Return true if CH separates the netmask in the "sortlist" ++ directive. */ ++static inline bool ++is_sort_mask (char ch) ++{ ++ return ch == '/' || ch == '&'; ++} + +-#ifdef RESOLVSORT +-static const char sort_mask_chars[] = "/&"; +-#define ISSORTMASK(ch) (strchr(sort_mask_chars, ch) != NULL) +-static u_int32_t net_mask (struct in_addr) __THROW; +-#endif ++/* Array of name server addresses. */ ++#define DYNARRAY_STRUCT nameserver_list ++#define DYNARRAY_ELEMENT const struct sockaddr * ++#define DYNARRAY_ELEMENT_FREE(e) free ((struct sockaddr *) *(e)) ++#define DYNARRAY_INITIAL_SIZE 3 ++#define DYNARRAY_PREFIX nameserver_list_ ++#include ++ ++/* Array of strings for the search array. The backing store is ++ managed separately. */ ++#define DYNARRAY_STRUCT search_list ++#define DYNARRAY_ELEMENT const char * ++#define DYNARRAY_INITIAL_SIZE 6 ++#define DYNARRAY_PREFIX search_list_ ++#include ++ ++/* Array of name server addresses. */ ++#define DYNARRAY_STRUCT sort_list ++#define DYNARRAY_ELEMENT struct resolv_sortlist_entry ++#define DYNARRAY_INITIAL_SIZE 0 ++#define DYNARRAY_PREFIX sort_list_ ++#include ++ ++/* resolv.conf parser state and results. */ ++struct resolv_conf_parser ++{ ++ char *buffer; /* Temporary buffer for reading lines. */ + +-#if !defined(isascii) /* XXX - could be a function */ +-# define isascii(c) (!(c & 0200)) +-#endif ++ struct nameserver_list nameserver_list; /* Nameserver addresses. */ + +-#ifdef _LIBC +-unsigned long long int __res_initstamp attribute_hidden; +-#endif ++ char *search_list_store; /* Backing storage for search list entries. */ ++ struct search_list search_list; /* Points into search_list_store. */ + +-/* +- * Resolver state default settings. +- */ ++ struct sort_list sort_list; /* Address preference sorting list. */ + +-/* +- * Set up default settings. If the configuration file exist, the values +- * there will have precedence. Otherwise, the server address is set to +- * INADDR_ANY and the default domain name comes from the gethostname(). +- * +- * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 +- * rather than INADDR_ANY ("0.0.0.0") as the default name server address +- * since it was noted that INADDR_ANY actually meant ``the first interface +- * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, +- * it had to be "up" in order for you to reach your own name server. It +- * was later decided that since the recommended practice is to always +- * install local static routes through 127.0.0.1 for all your network +- * interfaces, that we could solve this problem without a code change. +- * +- * The configuration file should always be used, since it is the only way +- * to specify a default domain. If you are running a server on your local +- * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" +- * in the configuration file. +- * +- * Return 0 if completes successfully, -1 on error +- */ +-int +-res_ninit(res_state statp) { +- extern int __res_vinit(res_state, int); ++ /* Configuration template. The non-array elements are filled in ++ directly. The array elements are updated prior to the call to ++ __resolv_conf_attach. */ ++ struct resolv_conf template; ++}; + +- return (__res_vinit(statp, 0)); ++/* Return true if *PREINIT contains actual preinitialization. */ ++static bool ++has_preinit_values (const struct __res_state *preinit) ++{ ++ return (preinit->retrans != 0 && preinit->retrans != RES_TIMEOUT) ++ || (preinit->retry != 0 && preinit->retry != RES_DFLRETRY) ++ || (preinit->options != 0 ++ && (preinit->options & ~RES_INIT) != RES_DEFAULT); + } +-#ifdef _LIBC +-libc_hidden_def (__res_ninit) +-#endif + +-/* This function has to be reachable by res_data.c but not publically. */ +-int +-__res_vinit(res_state statp, int preinit) { +- register FILE *fp; +- register char *cp, **pp; +- register int n; +- char buf[BUFSIZ]; +- int nserv = 0; /* number of nameserver records read from file */ +-#ifdef _LIBC +- int nservall = 0; /* number of NS records read, nserv IPv4 only */ +-#endif +- int haveenv = 0; +- int havesearch = 0; +-#ifdef RESOLVSORT +- int nsort = 0; +- char *net; +-#endif +-#ifndef RFC1535 +- int dots; +-#endif +-#ifdef _LIBC +- statp->_u._ext.initstamp = __res_initstamp; +-#endif +- +- if (!preinit) { +- statp->retrans = RES_TIMEOUT; +- statp->retry = RES_DFLRETRY; +- statp->options = RES_DEFAULT; +- statp->id = res_randomid(); +- } +- +- statp->nscount = 0; +- statp->ndots = 1; +- statp->pfcode = 0; +- statp->_vcsock = -1; +- statp->_flags = 0; +- statp->qhook = NULL; +- statp->rhook = NULL; +- statp->_u._ext.nsinit = 0; +- statp->_u._ext.nscount = 0; +-#ifdef _LIBC +- statp->_u._ext.nscount6 = 0; +- for (n = 0; n < MAXNS; n++) { +- statp->_u._ext.nsaddrs[n] = NULL; +- statp->_u._ext.nsmap[n] = MAXNS; +- } +-#endif +- +- /* Allow user to override the local domain definition */ +- if ((cp = getenv("LOCALDOMAIN")) != NULL) { +- (void)strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); +- statp->defdname[sizeof(statp->defdname) - 1] = '\0'; +- haveenv++; +- +- /* +- * Set search list to be blank-separated strings +- * from rest of env value. Permits users of LOCALDOMAIN +- * to still have a search list, and anyone to set the +- * one that they want to use as an individual (even more +- * important now that the rfc1535 stuff restricts searches) +- */ +- cp = statp->defdname; +- pp = statp->dnsrch; +- *pp++ = cp; +- for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) { +- if (*cp == '\n') /* silly backwards compat */ +- break; +- else if (*cp == ' ' || *cp == '\t') { +- *cp = 0; +- n = 1; +- } else if (n) { +- *pp++ = cp; +- n = 0; +- havesearch = 1; +- } +- } +- /* null terminate last domain if there are excess */ +- while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') +- cp++; +- *cp = '\0'; +- *pp++ = 0; +- } +- +-#define MATCH(line, name) \ +- (!strncmp(line, name, sizeof(name) - 1) && \ +- (line[sizeof(name) - 1] == ' ' || \ +- line[sizeof(name) - 1] == '\t')) +- +- if ((fp = fopen(_PATH_RESCONF, "rce")) != NULL) { +- /* No threads use this stream. */ +- __fsetlocking (fp, FSETLOCKING_BYCALLER); +- /* read the config file */ +- while (fgets_unlocked(buf, sizeof(buf), fp) != NULL) { +- /* skip comments */ +- if (*buf == ';' || *buf == '#') +- continue; +- /* read default domain name */ +- if (MATCH(buf, "domain")) { +- if (haveenv) /* skip if have from environ */ +- continue; +- cp = buf + sizeof("domain") - 1; +- while (*cp == ' ' || *cp == '\t') +- cp++; +- if ((*cp == '\0') || (*cp == '\n')) +- continue; +- strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); +- statp->defdname[sizeof(statp->defdname) - 1] = '\0'; +- if ((cp = strpbrk(statp->defdname, " \t\n")) != NULL) +- *cp = '\0'; +- havesearch = 0; +- continue; +- } +- /* set search list */ +- if (MATCH(buf, "search")) { +- if (haveenv) /* skip if have from environ */ +- continue; +- cp = buf + sizeof("search") - 1; +- while (*cp == ' ' || *cp == '\t') +- cp++; +- if ((*cp == '\0') || (*cp == '\n')) +- continue; +- strncpy(statp->defdname, cp, sizeof(statp->defdname) - 1); +- statp->defdname[sizeof(statp->defdname) - 1] = '\0'; +- if ((cp = strchr(statp->defdname, '\n')) != NULL) +- *cp = '\0'; +- /* +- * Set search list to be blank-separated strings +- * on rest of line. +- */ +- cp = statp->defdname; +- pp = statp->dnsrch; +- *pp++ = cp; +- for (n = 0; *cp && pp < statp->dnsrch + MAXDNSRCH; cp++) { +- if (*cp == ' ' || *cp == '\t') { +- *cp = 0; +- n = 1; +- } else if (n) { +- *pp++ = cp; +- n = 0; +- } +- } +- /* null terminate last domain if there are excess */ +- while (*cp != '\0' && *cp != ' ' && *cp != '\t') +- cp++; +- *cp = '\0'; +- *pp++ = 0; +- havesearch = 1; +- continue; +- } +- /* read nameservers to query */ +-#ifdef _LIBC +- if (MATCH(buf, "nameserver") && nservall < MAXNS) { +-#else +- if (MATCH(buf, "nameserver") && nserv < MAXNS) { +-#endif +- struct in_addr a; +- +- cp = buf + sizeof("nameserver") - 1; +- while (*cp == ' ' || *cp == '\t') +- cp++; +- if ((*cp != '\0') && (*cp != '\n') +- && __inet_aton(cp, &a)) { +- statp->nsaddr_list[nserv].sin_addr = a; +- statp->nsaddr_list[nserv].sin_family = AF_INET; +- statp->nsaddr_list[nserv].sin_port = +- htons(NAMESERVER_PORT); +- nserv++; +-#ifdef _LIBC +- nservall++; +- } else { +- struct in6_addr a6; +- char *el; +- +- if ((el = strpbrk(cp, " \t\n")) != NULL) +- *el = '\0'; +- if ((el = strchr(cp, SCOPE_DELIMITER)) != NULL) +- *el = '\0'; +- if ((*cp != '\0') && +- (inet_pton(AF_INET6, cp, &a6) > 0)) { +- struct sockaddr_in6 *sa6; +- +- sa6 = malloc(sizeof(*sa6)); +- if (sa6 != NULL) { +- sa6->sin6_family = AF_INET6; +- sa6->sin6_port = htons(NAMESERVER_PORT); +- sa6->sin6_flowinfo = 0; +- sa6->sin6_addr = a6; +- +- if (__builtin_expect (el == NULL, 1)) +- sa6->sin6_scope_id = 0; +- else { +- int try_numericscope = 1; +- if (IN6_IS_ADDR_LINKLOCAL (&a6) +- || IN6_IS_ADDR_MC_LINKLOCAL (&a6)) { +- sa6->sin6_scope_id +- = if_nametoindex (el + 1); +- if (sa6->sin6_scope_id != 0) +- try_numericscope = 0; +- } +- +- if (try_numericscope) { +- char *end; +- sa6->sin6_scope_id +- = (uint32_t) strtoul (el + 1, &end, +- 10); +- if (*end != '\0') +- sa6->sin6_scope_id = 0; +- } +- } +- +- statp->_u._ext.nsaddrs[nservall] = sa6; +- statp->_u._ext.nssocks[nservall] = -1; +- statp->_u._ext.nsmap[nservall] = MAXNS + 1; +- nservall++; +- } +- } +-#endif +- } +- continue; +- } +-#ifdef RESOLVSORT +- if (MATCH(buf, "sortlist")) { +- struct in_addr a; +- +- cp = buf + sizeof("sortlist") - 1; +- while (nsort < MAXRESOLVSORT) { +- while (*cp == ' ' || *cp == '\t') +- cp++; +- if (*cp == '\0' || *cp == '\n' || *cp == ';') +- break; +- net = cp; +- while (*cp && !ISSORTMASK(*cp) && *cp != ';' && +- isascii(*cp) && !isspace(*cp)) +- cp++; +- n = *cp; +- *cp = 0; +- if (__inet_aton(net, &a)) { +- statp->sort_list[nsort].addr = a; +- if (ISSORTMASK(n)) { +- *cp++ = n; +- net = cp; +- while (*cp && *cp != ';' && +- isascii(*cp) && !isspace(*cp)) +- cp++; +- n = *cp; +- *cp = 0; +- if (__inet_aton(net, &a)) { +- statp->sort_list[nsort].mask = a.s_addr; +- } else { +- statp->sort_list[nsort].mask = +- net_mask(statp->sort_list[nsort].addr); +- } +- } else { +- statp->sort_list[nsort].mask = +- net_mask(statp->sort_list[nsort].addr); +- } +- nsort++; +- } +- *cp = n; +- } +- continue; +- } +-#endif +- if (MATCH(buf, "options")) { +- res_setoptions(statp, buf + sizeof("options") - 1, "conf"); +- continue; +- } +- } +- statp->nscount = nservall; +-#ifdef _LIBC +- if (nservall - nserv > 0) { +- statp->_u._ext.nscount6 = nservall - nserv; +- /* We try IPv6 servers again. */ +- statp->ipv6_unavail = false; +- } +-#endif +-#ifdef RESOLVSORT +- statp->nsort = nsort; +-#endif +- (void) fclose(fp); +- } +- if (__builtin_expect(statp->nscount == 0, 0)) { +- statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); +- statp->nsaddr.sin_family = AF_INET; +- statp->nsaddr.sin_port = htons(NAMESERVER_PORT); +- statp->nscount = 1; +- } +- if (statp->defdname[0] == 0 && +- __gethostname(buf, sizeof(statp->defdname) - 1) == 0 && +- (cp = strchr(buf, '.')) != NULL) +- strcpy(statp->defdname, cp + 1); +- +- /* find components of local domain that might be searched */ +- if (havesearch == 0) { +- pp = statp->dnsrch; +- *pp++ = statp->defdname; +- *pp = NULL; +- +-#ifndef RFC1535 +- dots = 0; +- for (cp = statp->defdname; *cp; cp++) +- dots += (*cp == '.'); +- +- cp = statp->defdname; +- while (pp < statp->dnsrch + MAXDFLSRCH) { +- if (dots < LOCALDOMAINPARTS) +- break; +- cp = __rawmemchr(cp, '.') + 1; /* we know there is one */ +- *pp++ = cp; +- dots--; +- } +- *pp = NULL; +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) { +- printf(";; res_init()... default dnsrch list:\n"); +- for (pp = statp->dnsrch; *pp; pp++) +- printf(";;\t%s\n", *pp); +- printf(";;\t..END..\n"); +- } +-#endif +-#endif /* !RFC1535 */ +- } +- +- if ((cp = getenv("RES_OPTIONS")) != NULL) +- res_setoptions(statp, cp, "env"); +- statp->options |= RES_INIT; +- return (0); ++static void ++resolv_conf_parser_init (struct resolv_conf_parser *parser, ++ const struct __res_state *preinit) ++{ ++ parser->buffer = NULL; ++ parser->search_list_store = NULL; ++ nameserver_list_init (&parser->nameserver_list); ++ search_list_init (&parser->search_list); ++ sort_list_init (&parser->sort_list); ++ ++ if (preinit != NULL) ++ { ++ parser->template.retrans = preinit->retrans; ++ parser->template.retry = preinit->retry; ++ parser->template.options = preinit->options | RES_INIT; ++ } ++ else ++ { ++ parser->template.retrans = RES_TIMEOUT; ++ parser->template.retry = RES_DFLRETRY; ++ parser->template.options = RES_DEFAULT | RES_INIT; ++ } ++ parser->template.ndots = 1; + } + + static void +-internal_function +-res_setoptions(res_state statp, const char *options, const char *source) { +- const char *cp = options; +- int i; +- +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_setoptions(\"%s\", \"%s\")...\n", +- options, source); +-#endif +- while (*cp) { +- /* skip leading and inner runs of spaces */ +- while (*cp == ' ' || *cp == '\t') +- cp++; +- /* search for and process individual options */ +- if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { +- i = atoi(cp + sizeof("ndots:") - 1); +- if (i <= RES_MAXNDOTS) +- statp->ndots = i; +- else +- statp->ndots = RES_MAXNDOTS; +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";;\tndots=%d\n", statp->ndots); +-#endif +- } else if (!strncmp(cp, "timeout:", sizeof("timeout:") - 1)) { +- i = atoi(cp + sizeof("timeout:") - 1); +- if (i <= RES_MAXRETRANS) +- statp->retrans = i; +- else +- statp->retrans = RES_MAXRETRANS; +- } else if (!strncmp(cp, "attempts:", sizeof("attempts:") - 1)){ +- i = atoi(cp + sizeof("attempts:") - 1); +- if (i <= RES_MAXRETRY) +- statp->retry = i; +- else +- statp->retry = RES_MAXRETRY; +- } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { +-#ifdef DEBUG +- if (!(statp->options & RES_DEBUG)) { +- printf(";; res_setoptions(\"%s\", \"%s\")..\n", +- options, source); +- statp->options |= RES_DEBUG; +- } +- printf(";;\tdebug\n"); +-#endif +- } else { +- static const struct +- { +- char str[22]; +- uint8_t len; +- uint8_t clear; +- unsigned long int flag; +- } options[] = { +-#define STRnLEN(str) str, sizeof (str) - 1 +- { STRnLEN ("inet6"), 0, DEPRECATED_RES_USE_INET6 }, +- { STRnLEN ("ip6-bytestring"), 0, RES_USEBSTRING }, +- { STRnLEN ("no-ip6-dotint"), 0, RES_NOIP6DOTINT }, +- { STRnLEN ("ip6-dotint"), 1, ~RES_NOIP6DOTINT }, +- { STRnLEN ("rotate"), 0, RES_ROTATE }, +- { STRnLEN ("no-check-names"), 0, RES_NOCHECKNAME }, +- { STRnLEN ("edns0"), 0, RES_USE_EDNS0 }, +- { STRnLEN ("single-request-reopen"), 0, RES_SNGLKUPREOP }, +- { STRnLEN ("single-request"), 0, RES_SNGLKUP }, +- { STRnLEN ("no_tld_query"), 0, RES_NOTLDQUERY }, +- { STRnLEN ("no-tld-query"), 0, RES_NOTLDQUERY }, +- { STRnLEN ("use-vc"), 0, RES_USEVC } +- }; +-#define noptions (sizeof (options) / sizeof (options[0])) +- int i; +- for (i = 0; i < noptions; ++i) +- if (strncmp (cp, options[i].str, options[i].len) == 0) +- { +- if (options[i].clear) +- statp->options &= options[i].flag; +- else +- statp->options |= options[i].flag; +- break; +- } +- if (i == noptions) { +- /* XXX - print a warning here? */ +- } +- } +- /* skip to next run of spaces */ +- while (*cp && *cp != ' ' && *cp != '\t') +- cp++; +- } ++resolv_conf_parser_free (struct resolv_conf_parser *parser) ++{ ++ free (parser->buffer); ++ free (parser->search_list_store); ++ nameserver_list_free (&parser->nameserver_list); ++ search_list_free (&parser->search_list); ++ sort_list_free (&parser->sort_list); + } + +-#ifdef RESOLVSORT +-/* XXX - should really support CIDR which means explicit masks always. */ +-static u_int32_t +-net_mask(in) /* XXX - should really use system's version of this */ +- struct in_addr in; ++/* Allocate a struct sockaddr_in object on the heap, with the ++ specified address and port. */ ++static struct sockaddr * ++allocate_address_v4 (struct in_addr a, uint16_t port) + { +- register u_int32_t i = ntohl(in.s_addr); +- +- if (IN_CLASSA(i)) +- return (htonl(IN_CLASSA_NET)); +- else if (IN_CLASSB(i)) +- return (htonl(IN_CLASSB_NET)); +- return (htonl(IN_CLASSC_NET)); ++ struct sockaddr_in *sa4 = malloc (sizeof (*sa4)); ++ if (sa4 == NULL) ++ return NULL; ++ sa4->sin_family = AF_INET; ++ sa4->sin_addr = a; ++ sa4->sin_port = htons (port); ++ return (struct sockaddr *) sa4; + } +-#endif + +-u_int +-res_randomid(void) { +- return 0xffff & __getpid(); ++/* Try to obtain the domain name from the host name and store it in ++ *RESULT. Return false on memory allocation failure. If the domain ++ name cannot be determined for any other reason, write NULL to ++ *RESULT and return true. */ ++static bool ++domain_from_hostname (char **result) ++{ ++ char buf[256]; ++ /* gethostbyname may not terminate the buffer. */ ++ buf[sizeof (buf) - 1] = '\0'; ++ if (__gethostname (buf, sizeof (buf) - 1) == 0) ++ { ++ char *dot = strchr (buf, '.'); ++ if (dot != NULL) ++ { ++ *result = __strdup (dot + 1); ++ if (*result == NULL) ++ return false; ++ return true; ++ } ++ } ++ *result = NULL; ++ return true; + } +-#ifdef _LIBC +-libc_hidden_def (__res_randomid) +-#endif + ++static void res_setoptions (struct resolv_conf_parser *, const char *options); + +-/* +- * This routine is for closing the socket if a virtual circuit is used and +- * the program wants to close it. This provides support for endhostent() +- * which expects to close the socket. +- * +- * This routine is not expected to be user visible. +- */ +-void +-__res_iclose(res_state statp, bool free_addr) { +- int ns; +- +- if (statp->_vcsock >= 0) { +- close_not_cancel_no_status(statp->_vcsock); +- statp->_vcsock = -1; +- statp->_flags &= ~(RES_F_VC | RES_F_CONN); +- } +-#ifdef _LIBC +- for (ns = 0; ns < MAXNS; ns++) +-#else +- for (ns = 0; ns < statp->_u._ext.nscount; ns++) +-#endif +- if (statp->_u._ext.nsaddrs[ns]) { +- if (statp->_u._ext.nssocks[ns] != -1) { +- close_not_cancel_no_status(statp->_u._ext.nssocks[ns]); +- statp->_u._ext.nssocks[ns] = -1; +- } +- if (free_addr) { +- free (statp->_u._ext.nsaddrs[ns]); +- statp->_u._ext.nsaddrs[ns] = NULL; +- } +- } +- statp->_u._ext.nsinit = 0; ++/* Internal helper function for __res_vinit, to aid with resource ++ deallocation and error handling. Return true on success, false on ++ failure. */ ++static bool ++res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser) ++{ ++ char *cp; ++ size_t buffer_size = 0; ++ bool haveenv = false; ++ ++ /* Allow user to override the local domain definition. */ ++ if ((cp = getenv ("LOCALDOMAIN")) != NULL) ++ { ++ /* The code below splits the string in place. */ ++ cp = __strdup (cp); ++ if (cp == NULL) ++ return false; ++ free (parser->search_list_store); ++ parser->search_list_store = cp; ++ haveenv = true; ++ ++ /* The string will be truncated as needed below. */ ++ search_list_add (&parser->search_list, cp); ++ ++ /* Set search list to be blank-separated strings from rest of ++ env value. Permits users of LOCALDOMAIN to still have a ++ search list, and anyone to set the one that they want to use ++ as an individual (even more important now that the rfc1535 ++ stuff restricts searches). */ ++ for (bool in_name = true; *cp != '\0'; cp++) ++ { ++ if (*cp == '\n') ++ { ++ *cp = '\0'; ++ break; ++ } ++ else if (*cp == ' ' || *cp == '\t') ++ { ++ *cp = '\0'; ++ in_name = false; ++ } ++ else if (!in_name) ++ { ++ search_list_add (&parser->search_list, cp); ++ in_name = true; ++ } ++ } ++ } ++ ++#define MATCH(line, name) \ ++ (!strncmp ((line), name, sizeof (name) - 1) \ ++ && ((line)[sizeof (name) - 1] == ' ' \ ++ || (line)[sizeof (name) - 1] == '\t')) ++ ++ if (fp != NULL) ++ { ++ /* No threads use this stream. */ ++ __fsetlocking (fp, FSETLOCKING_BYCALLER); ++ /* Read the config file. */ ++ while (true) ++ { ++ { ++ ssize_t ret = __getline (&parser->buffer, &buffer_size, fp); ++ if (ret <= 0) ++ { ++ if (_IO_ferror_unlocked (fp)) ++ return false; ++ else ++ break; ++ } ++ } ++ ++ /* Skip comments. */ ++ if (*parser->buffer == ';' || *parser->buffer == '#') ++ continue; ++ /* Read default domain name. */ ++ if (MATCH (parser->buffer, "domain")) ++ { ++ if (haveenv) ++ /* LOCALDOMAIN overrides the configuration file. */ ++ continue; ++ cp = parser->buffer + sizeof ("domain") - 1; ++ while (*cp == ' ' || *cp == '\t') ++ cp++; ++ if ((*cp == '\0') || (*cp == '\n')) ++ continue; ++ ++ cp = __strdup (cp); ++ if (cp == NULL) ++ return false; ++ free (parser->search_list_store); ++ parser->search_list_store = cp; ++ search_list_clear (&parser->search_list); ++ search_list_add (&parser->search_list, cp); ++ /* Replace trailing whitespace. */ ++ if ((cp = strpbrk (cp, " \t\n")) != NULL) ++ *cp = '\0'; ++ continue; ++ } ++ /* Set search list. */ ++ if (MATCH (parser->buffer, "search")) ++ { ++ if (haveenv) ++ /* LOCALDOMAIN overrides the configuration file. */ ++ continue; ++ cp = parser->buffer + sizeof ("search") - 1; ++ while (*cp == ' ' || *cp == '\t') ++ cp++; ++ if ((*cp == '\0') || (*cp == '\n')) ++ continue; ++ ++ { ++ char *p = strchr (cp, '\n'); ++ if (p != NULL) ++ *p = '\0'; ++ } ++ cp = __strdup (cp); ++ if (cp == NULL) ++ return false; ++ free (parser->search_list_store); ++ parser->search_list_store = cp; ++ ++ /* The string is truncated below. */ ++ search_list_clear (&parser->search_list); ++ search_list_add (&parser->search_list, cp); ++ ++ /* Set search list to be blank-separated strings on rest ++ of line. */ ++ for (bool in_name = true; *cp != '\0'; cp++) ++ { ++ if (*cp == ' ' || *cp == '\t') ++ { ++ *cp = '\0'; ++ in_name = false; ++ } ++ else if (!in_name) ++ { ++ search_list_add (&parser->search_list, cp); ++ in_name = true; ++ } ++ } ++ continue; ++ } ++ /* Read nameservers to query. */ ++ if (MATCH (parser->buffer, "nameserver")) ++ { ++ struct in_addr a; ++ ++ cp = parser->buffer + sizeof ("nameserver") - 1; ++ while (*cp == ' ' || *cp == '\t') ++ cp++; ++ struct sockaddr *sa; ++ if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a)) ++ { ++ sa = allocate_address_v4 (a, NAMESERVER_PORT); ++ if (sa == NULL) ++ return false; ++ } ++ else ++ { ++ struct in6_addr a6; ++ char *el; ++ ++ if ((el = strpbrk (cp, " \t\n")) != NULL) ++ *el = '\0'; ++ if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL) ++ *el = '\0'; ++ if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0)) ++ { ++ struct sockaddr_in6 *sa6; ++ ++ sa6 = malloc (sizeof (*sa6)); ++ if (sa6 == NULL) ++ return false; ++ ++ sa6->sin6_family = AF_INET6; ++ sa6->sin6_port = htons (NAMESERVER_PORT); ++ sa6->sin6_flowinfo = 0; ++ sa6->sin6_addr = a6; ++ ++ sa6->sin6_scope_id = 0; ++ if (__glibc_likely (el != NULL)) ++ /* Ignore errors, for backwards ++ compatibility. */ ++ __inet6_scopeid_pton ++ (&a6, el + 1, &sa6->sin6_scope_id); ++ sa = (struct sockaddr *) sa6; ++ } ++ else ++ /* IPv6 address parse failure. */ ++ sa = NULL; ++ } ++ if (sa != NULL) ++ { ++ const struct sockaddr **p = nameserver_list_emplace ++ (&parser->nameserver_list); ++ if (p != NULL) ++ *p = sa; ++ else ++ { ++ free (sa); ++ return false; ++ } ++ } ++ continue; ++ } ++ if (MATCH (parser->buffer, "sortlist")) ++ { ++ struct in_addr a; ++ ++ cp = parser->buffer + sizeof ("sortlist") - 1; ++ while (true) ++ { ++ while (*cp == ' ' || *cp == '\t') ++ cp++; ++ if (*cp == '\0' || *cp == '\n' || *cp == ';') ++ break; ++ char *net = cp; ++ while (*cp && !is_sort_mask (*cp) && *cp != ';' ++ && isascii (*cp) && !isspace (*cp)) ++ cp++; ++ char separator = *cp; ++ *cp = 0; ++ struct resolv_sortlist_entry e; ++ if (__inet_aton (net, &a)) ++ { ++ e.addr = a; ++ if (is_sort_mask (separator)) ++ { ++ *cp++ = separator; ++ net = cp; ++ while (*cp && *cp != ';' ++ && isascii (*cp) && !isspace (*cp)) ++ cp++; ++ separator = *cp; ++ *cp = 0; ++ if (__inet_aton (net, &a)) ++ e.mask = a.s_addr; ++ else ++ e.mask = net_mask (e.addr); ++ } ++ else ++ e.mask = net_mask (e.addr); ++ sort_list_add (&parser->sort_list, e); ++ } ++ *cp = separator; ++ } ++ continue; ++ } ++ if (MATCH (parser->buffer, "options")) ++ { ++ res_setoptions (parser, parser->buffer + sizeof ("options") - 1); ++ continue; ++ } ++ } ++ fclose (fp); ++ } ++ if (__glibc_unlikely (nameserver_list_size (&parser->nameserver_list) == 0)) ++ { ++ const struct sockaddr **p ++ = nameserver_list_emplace (&parser->nameserver_list); ++ if (p == NULL) ++ return false; ++ *p = allocate_address_v4 (__inet_makeaddr (IN_LOOPBACKNET, 1), ++ NAMESERVER_PORT); ++ if (*p == NULL) ++ return false; ++ } ++ ++ if (search_list_size (&parser->search_list) == 0) ++ { ++ char *domain; ++ if (!domain_from_hostname (&domain)) ++ return false; ++ if (domain != NULL) ++ { ++ free (parser->search_list_store); ++ parser->search_list_store = domain; ++ search_list_add (&parser->search_list, domain); ++ } ++ } ++ ++ if ((cp = getenv ("RES_OPTIONS")) != NULL) ++ res_setoptions (parser, cp); ++ ++ if (nameserver_list_has_failed (&parser->nameserver_list) ++ || search_list_has_failed (&parser->search_list) ++ || sort_list_has_failed (&parser->sort_list)) ++ { ++ __set_errno (ENOMEM); ++ return false; ++ } ++ ++ return true; + } +-libc_hidden_def (__res_iclose) + +-void +-res_nclose(res_state statp) ++struct resolv_conf * ++__resolv_conf_load (struct __res_state *preinit) + { +- __res_iclose (statp, true); ++ /* Ensure that /etc/hosts.conf has been loaded (once). */ ++ _res_hconf_init (); ++ ++ FILE *fp = fopen (_PATH_RESCONF, "rce"); ++ if (fp == NULL) ++ switch (errno) ++ { ++ case EACCES: ++ case EISDIR: ++ case ELOOP: ++ case ENOENT: ++ case ENOTDIR: ++ case EPERM: ++ /* Ignore these errors. They are persistent errors caused ++ by file system contents. */ ++ break; ++ default: ++ /* Other errors refer to resource allocation problems and ++ need to be handled by the application. */ ++ return NULL; ++ } ++ ++ struct resolv_conf_parser parser; ++ resolv_conf_parser_init (&parser, preinit); ++ ++ struct resolv_conf *conf = NULL; ++ if (res_vinit_1 (fp, &parser)) ++ { ++ parser.template.nameserver_list ++ = nameserver_list_begin (&parser.nameserver_list); ++ parser.template.nameserver_list_size ++ = nameserver_list_size (&parser.nameserver_list); ++ parser.template.search_list = search_list_begin (&parser.search_list); ++ parser.template.search_list_size ++ = search_list_size (&parser.search_list); ++ parser.template.sort_list = sort_list_begin (&parser.sort_list); ++ parser.template.sort_list_size = sort_list_size (&parser.sort_list); ++ conf = __resolv_conf_allocate (&parser.template); ++ } ++ resolv_conf_parser_free (&parser); ++ ++ return conf; + } +-#ifdef _LIBC +-libc_hidden_def (__res_nclose) +-#endif +- +-#ifdef _LIBC +-# ifdef _LIBC_REENTRANT +-/* This is called when a thread is exiting to free resources held in _res. */ +-static void __attribute__ ((section ("__libc_thread_freeres_fn"))) +-res_thread_freeres (void) ++ ++/* Set up default settings. If the /etc/resolv.conf configuration ++ file exist, the values there will have precedence. Otherwise, the ++ server address is set to INADDR_LOOPBACK and the default domain ++ name comes from gethostname. The RES_OPTIONS and LOCALDOMAIN ++ environment variables can be used to override some settings. ++ Return 0 if completes successfully, -1 on error. */ ++int ++__res_vinit (res_state statp, int preinit) + { +- if (_res.nscount == 0) +- /* Never called res_ninit. */ +- return; ++ struct resolv_conf *conf; ++ if (preinit && has_preinit_values (statp)) ++ /* For the preinit case, we cannot use the cached configuration ++ because some settings could be different. */ ++ conf = __resolv_conf_load (statp); ++ else ++ conf = __resolv_conf_get_current (); ++ if (conf == NULL) ++ return -1; ++ ++ bool ok = __resolv_conf_attach (statp, conf); ++ __resolv_conf_put (conf); ++ if (ok) ++ { ++ if (preinit) ++ statp->id = res_randomid (); ++ return 0; ++ } ++ else ++ return -1; ++} + +- __res_iclose (&_res, true); /* Close any VC sockets. */ ++static void ++res_setoptions (struct resolv_conf_parser *parser, const char *options) ++{ ++ const char *cp = options; ++ ++ while (*cp) ++ { ++ /* Skip leading and inner runs of spaces. */ ++ while (*cp == ' ' || *cp == '\t') ++ cp++; ++ /* Search for and process individual options. */ ++ if (!strncmp (cp, "ndots:", sizeof ("ndots:") - 1)) ++ { ++ int i = atoi (cp + sizeof ("ndots:") - 1); ++ if (i <= RES_MAXNDOTS) ++ parser->template.ndots = i; ++ else ++ parser->template.ndots = RES_MAXNDOTS; ++ } ++ else if (!strncmp (cp, "timeout:", sizeof ("timeout:") - 1)) ++ { ++ int i = atoi (cp + sizeof ("timeout:") - 1); ++ if (i <= RES_MAXRETRANS) ++ parser->template.retrans = i; ++ else ++ parser->template.retrans = RES_MAXRETRANS; ++ } ++ else if (!strncmp (cp, "attempts:", sizeof ("attempts:") - 1)) ++ { ++ int i = atoi (cp + sizeof ("attempts:") - 1); ++ if (i <= RES_MAXRETRY) ++ parser->template.retry = i; ++ else ++ parser->template.retry = RES_MAXRETRY; ++ } ++ else ++ { ++ static const struct ++ { ++ char str[22]; ++ uint8_t len; ++ uint8_t clear; ++ unsigned long int flag; ++ } options[] = { ++#define STRnLEN(str) str, sizeof (str) - 1 ++ { STRnLEN ("inet6"), 0, DEPRECATED_RES_USE_INET6 }, ++ { STRnLEN ("rotate"), 0, RES_ROTATE }, ++ { STRnLEN ("edns0"), 0, RES_USE_EDNS0 }, ++ { STRnLEN ("single-request-reopen"), 0, RES_SNGLKUPREOP }, ++ { STRnLEN ("single-request"), 0, RES_SNGLKUP }, ++ { STRnLEN ("no_tld_query"), 0, RES_NOTLDQUERY }, ++ { STRnLEN ("no-tld-query"), 0, RES_NOTLDQUERY }, ++ { STRnLEN ("no-reload"), 0, RES_NORELOAD }, ++ { STRnLEN ("use-vc"), 0, RES_USEVC } ++ }; ++#define noptions (sizeof (options) / sizeof (options[0])) ++ for (int i = 0; i < noptions; ++i) ++ if (strncmp (cp, options[i].str, options[i].len) == 0) ++ { ++ if (options[i].clear) ++ parser->template.options &= options[i].flag; ++ else ++ parser->template.options |= options[i].flag; ++ break; ++ } ++ } ++ /* Skip to next run of spaces. */ ++ while (*cp && *cp != ' ' && *cp != '\t') ++ cp++; ++ } ++} ++ ++static uint32_t ++net_mask (struct in_addr in) ++{ ++ uint32_t i = ntohl (in.s_addr); + +- /* Make sure we do a full re-initialization the next time. */ +- _res.options = 0; ++ if (IN_CLASSA (i)) ++ return htonl (IN_CLASSA_NET); ++ else if (IN_CLASSB (i)) ++ return htonl (IN_CLASSB_NET); ++ return htonl (IN_CLASSC_NET); + } +-text_set_element (__libc_thread_subfreeres, res_thread_freeres); +-text_set_element (__libc_subfreeres, res_thread_freeres); +-# endif +-#endif +diff --git a/resolv/res_libc.c b/resolv/res_libc.c +index 48d3200b7e2cd913..9f2d3c3bd442bb38 100644 +--- a/resolv/res_libc.c ++++ b/resolv/res_libc.c +@@ -1,3 +1,21 @@ ++/* Definitions related to res_init linked into libc instead of libresolv. ++ Copyright (C) 1995-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1995-1999 by Internet Software Consortium. + * +@@ -21,99 +39,47 @@ + #include + #include + #include +-#include +- +- +-/* The following bit is copied from res_data.c (where it is #ifdef'ed +- out) since res_init() should go into libc.so but the rest of that +- file should not. */ +- +-extern unsigned long long int __res_initstamp attribute_hidden; +-/* We have atomic increment operations on 64-bit platforms. */ +-#if __WORDSIZE == 64 +-# define atomicinclock(lock) (void) 0 +-# define atomicincunlock(lock) (void) 0 +-# define atomicinc(var) catomic_increment (&(var)) +-#else +-__libc_lock_define_initialized (static, lock); +-# define atomicinclock(lock) __libc_lock_lock (lock) +-# define atomicincunlock(lock) __libc_lock_unlock (lock) +-# define atomicinc(var) ++var +-#endif +- +-int +-res_init(void) { +- extern int __res_vinit(res_state, int); ++#include ++#include + +- /* +- * These three fields used to be statically initialized. This made +- * it hard to use this code in a shared library. It is necessary, +- * now that we're doing dynamic initialization here, that we preserve +- * the old semantics: if an application modifies one of these three +- * fields of _res before res_init() is called, res_init() will not +- * alter them. Of course, if an application is setting them to +- * _zero_ before calling res_init(), hoping to override what used +- * to be the static default, we can't detect it and unexpected results +- * will follow. Zero for any of these fields would make no sense, +- * so one can safely assume that the applications were already getting +- * unexpected results. +- * +- * _res.options is tricky since some apps were known to diddle the bits +- * before res_init() was first called. We can't replicate that semantic +- * with dynamic initialization (they may have turned bits off that are +- * set in RES_DEFAULT). Our solution is to declare such applications +- * "broken". They could fool us by setting RES_INIT but none do (yet). +- */ +- if (!_res.retrans) +- _res.retrans = RES_TIMEOUT; +- if (!_res.retry) +- _res.retry = 4; +- if (!(_res.options & RES_INIT)) +- _res.options = RES_DEFAULT; +- else if (_res.nscount > 0) +- __res_iclose (&_res, true); /* Close any VC sockets. */ +- +- /* +- * This one used to initialize implicitly to zero, so unless the app +- * has set it to something in particular, we can randomize it now. +- */ +- if (!_res.id) +- _res.id = res_randomid(); +- +- atomicinclock (lock); +- /* Request all threads to re-initialize their resolver states, +- resolv.conf might have changed. */ +- atomicinc (__res_initstamp); +- atomicincunlock (lock); +- +- return (__res_vinit(&_res, 1)); +-} +- +-/* Initialize resp if RES_INIT is not yet set or if res_init in some other +- thread requested re-initializing. */ + int +-__res_maybe_init (res_state resp, int preinit) ++res_init (void) + { +- if (resp->options & RES_INIT) { +- if (__res_initstamp != resp->_u._ext.initstamp) { +- if (resp->nscount > 0) +- __res_iclose (resp, true); +- return __res_vinit (resp, 1); +- } +- return 0; +- } else if (preinit) { +- if (!resp->retrans) +- resp->retrans = RES_TIMEOUT; +- if (!resp->retry) +- resp->retry = 4; +- resp->options = RES_DEFAULT; +- if (!resp->id) +- resp->id = res_randomid (); +- return __res_vinit (resp, 1); +- } else +- return __res_ninit (resp); ++ /* These three fields used to be statically initialized. This made ++ it hard to use this code in a shared library. It is necessary, ++ now that we're doing dynamic initialization here, that we ++ preserve the old semantics: if an application modifies one of ++ these three fields of _res before res_init is called, ++ res_init will not alter them. Of course, if an application is ++ setting them to _zero_ before calling res_init, hoping to ++ override what used to be the static default, we can't detect it ++ and unexpected results will follow. Zero for any of these fields ++ would make no sense, so one can safely assume that the ++ applications were already getting unexpected results. ++ ++ _res.options is tricky since some apps were known to diddle the ++ bits before res_init was first called. We can't replicate that ++ semantic with dynamic initialization (they may have turned bits ++ off that are set in RES_DEFAULT). Our solution is to declare ++ such applications "broken". They could fool us by setting ++ RES_INIT but none do (yet). */ ++ if (!_res.retrans) ++ _res.retrans = RES_TIMEOUT; ++ if (!_res.retry) ++ _res.retry = RES_DFLRETRY; ++ if (!(_res.options & RES_INIT)) ++ _res.options = RES_DEFAULT; ++ else if (_res.nscount > 0) ++ __res_iclose (&_res, true); /* Close any VC sockets. */ ++ ++ /* This one used to initialize implicitly to zero, so unless the app ++ has set it to something in particular, we can randomize it * ++ now. */ ++ if (!_res.id) ++ _res.id = res_randomid (); ++ ++ return __res_vinit (&_res, 1); + } +-libc_hidden_def (__res_maybe_init) + + /* This needs to be after the use of _res in res_init, above. */ + #undef _res +@@ -122,25 +88,22 @@ libc_hidden_def (__res_maybe_init) + This differs from plain `struct __res_state _res;' in that it doesn't + create a common definition, but a plain symbol that resides in .bss, + which can have an alias. */ +-struct __res_state _res __attribute__((section (".bss"))); +- +-#include ++struct __res_state _res __attribute__ ((nocommon)); + + #undef __resp + __thread struct __res_state *__resp = &_res; + extern __thread struct __res_state *__libc_resp + __attribute__ ((alias ("__resp"))) attribute_hidden; + ++#include ++ + /* We declare this with compat_symbol so that it's not + visible at link time. Programs must use the accessor functions. */ +-#if defined SHARED && defined DO_VERSIONING +-# include ++#ifdef SHARED + compat_symbol (libc, _res, _res, GLIBC_2_0); + #endif + +-#include +- +-#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2) ++#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) + # undef res_init + extern int __res_init_weak (void); + weak_extern (__res_init_weak); +diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c +index 2bc2d2497fdf5dfa..59fc5ab28c0faa66 100644 +--- a/resolv/res_mkquery.c ++++ b/resolv/res_mkquery.c +@@ -1,3 +1,21 @@ ++/* Creation of DNS query packets. ++ Copyright (C) 1995-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. +@@ -64,202 +82,222 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; +-static const char rcsid[] = "$BINDId: res_mkquery.c,v 8.12 1999/10/13 16:39:40 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include + #include + #include +-#include +-#include ++#include ++#include + #include ++#include ++#include + +-/* Options. Leave them on. */ +-/* #define DEBUG */ +- +-#ifdef _LIBC +-# include +-# if HP_TIMING_AVAIL +-# define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; } +-# endif ++#include ++#include ++#if HP_TIMING_AVAIL ++# define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; } + #endif + +-/* +- * Form all types of queries. +- * Returns the size of the result or -1. +- */ + int +-res_nmkquery(res_state statp, +- int op, /* opcode of query */ +- const char *dname, /* domain name */ +- int class, int type, /* class and type of query */ +- const u_char *data, /* resource record data */ +- int datalen, /* length of data */ +- const u_char *newrr_in, /* new rr for modify or append */ +- u_char *buf, /* buffer to put query */ +- int buflen) /* size of buffer */ ++__res_context_mkquery (struct resolv_context *ctx, int op, const char *dname, ++ int class, int type, const unsigned char *data, ++ unsigned char *buf, int buflen) + { +- register HEADER *hp; +- register u_char *cp; +- register int n; +- u_char *dnptrs[20], **dpp, **lastdnptr; +- +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_nmkquery(%s, %s, %s, %s)\n", +- _res_opcodes[op], dname, p_class(class), p_type(type)); +-#endif +- /* +- * Initialize header fields. +- */ +- if ((buf == NULL) || (buflen < HFIXEDSZ)) +- return (-1); +- memset(buf, 0, HFIXEDSZ); +- hp = (HEADER *) buf; +- /* We randomize the IDs every time. The old code just +- incremented by one after the initial randomization which +- still predictable if the application does multiple +- requests. */ +- int randombits; +- do +- { ++ HEADER *hp; ++ unsigned char *cp; ++ int n; ++ unsigned char *dnptrs[20], **dpp, **lastdnptr; ++ ++ if (class < 0 || class > 65535 || type < 0 || type > 65535) ++ return -1; ++ ++ /* Initialize header fields. */ ++ if ((buf == NULL) || (buflen < HFIXEDSZ)) ++ return -1; ++ memset (buf, 0, HFIXEDSZ); ++ hp = (HEADER *) buf; ++ /* We randomize the IDs every time. The old code just incremented ++ by one after the initial randomization which still predictable if ++ the application does multiple requests. */ ++ int randombits; + #ifdef RANDOM_BITS +- RANDOM_BITS (randombits); ++ RANDOM_BITS (randombits); + #else +- struct timeval tv; +- __gettimeofday (&tv, NULL); +- randombits = (tv.tv_sec << 8) ^ tv.tv_usec; ++ struct timeval tv; ++ __gettimeofday (&tv, NULL); ++ randombits = (tv.tv_sec << 8) ^ tv.tv_usec; + #endif +- } +- while ((randombits & 0xffff) == 0); +- statp->id = (statp->id + randombits) & 0xffff; +- hp->id = statp->id; +- hp->opcode = op; +- hp->rd = (statp->options & RES_RECURSE) != 0; +- hp->rcode = NOERROR; +- cp = buf + HFIXEDSZ; +- buflen -= HFIXEDSZ; +- dpp = dnptrs; +- *dpp++ = buf; +- *dpp++ = NULL; +- lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; +- /* +- * perform opcode specific processing +- */ +- switch (op) { +- case NS_NOTIFY_OP: +- if ((buflen -= QFIXEDSZ + (data == NULL ? 0 : RRFIXEDSZ)) < 0) +- return (-1); +- goto compose; +- +- case QUERY: +- if ((buflen -= QFIXEDSZ) < 0) +- return (-1); +- compose: +- n = ns_name_compress(dname, cp, buflen, +- (const u_char **) dnptrs, +- (const u_char **) lastdnptr); +- if (n < 0) +- return (-1); +- cp += n; +- buflen -= n; +- NS_PUT16 (type, cp); +- NS_PUT16 (class, cp); +- hp->qdcount = htons(1); +- if (op == QUERY || data == NULL) +- break; +- /* +- * Make an additional record for completion domain. +- */ +- n = ns_name_compress((char *)data, cp, buflen, +- (const u_char **) dnptrs, +- (const u_char **) lastdnptr); +- if (__builtin_expect (n < 0, 0)) +- return (-1); +- cp += n; +- buflen -= n; +- NS_PUT16 (T_NULL, cp); +- NS_PUT16 (class, cp); +- NS_PUT32 (0, cp); +- NS_PUT16 (0, cp); +- hp->arcount = htons(1); +- break; +- +- case IQUERY: +- /* +- * Initialize answer section +- */ +- if (__builtin_expect (buflen < 1 + RRFIXEDSZ + datalen, 0)) +- return (-1); +- *cp++ = '\0'; /* no domain name */ +- NS_PUT16 (type, cp); +- NS_PUT16 (class, cp); +- NS_PUT32 (0, cp); +- NS_PUT16 (datalen, cp); +- if (datalen) { +- memcpy(cp, data, datalen); +- cp += datalen; +- } +- hp->ancount = htons(1); +- break; +- +- default: +- return (-1); +- } +- return (cp - buf); ++ ++ hp->id = randombits; ++ hp->opcode = op; ++ hp->rd = (ctx->resp->options & RES_RECURSE) != 0; ++ hp->rcode = NOERROR; ++ cp = buf + HFIXEDSZ; ++ buflen -= HFIXEDSZ; ++ dpp = dnptrs; ++ *dpp++ = buf; ++ *dpp++ = NULL; ++ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; ++ ++ /* Perform opcode specific processing. */ ++ switch (op) ++ { ++ case NS_NOTIFY_OP: ++ if ((buflen -= QFIXEDSZ + (data == NULL ? 0 : RRFIXEDSZ)) < 0) ++ return -1; ++ goto compose; ++ ++ case QUERY: ++ if ((buflen -= QFIXEDSZ) < 0) ++ return -1; ++ compose: ++ n = ns_name_compress (dname, cp, buflen, ++ (const unsigned char **) dnptrs, ++ (const unsigned char **) lastdnptr); ++ if (n < 0) ++ return -1; ++ cp += n; ++ buflen -= n; ++ NS_PUT16 (type, cp); ++ NS_PUT16 (class, cp); ++ hp->qdcount = htons (1); ++ if (op == QUERY || data == NULL) ++ break; ++ ++ /* Make an additional record for completion domain. */ ++ n = ns_name_compress ((char *)data, cp, buflen, ++ (const unsigned char **) dnptrs, ++ (const unsigned char **) lastdnptr); ++ if (__glibc_unlikely (n < 0)) ++ return -1; ++ cp += n; ++ buflen -= n; ++ NS_PUT16 (T_NULL, cp); ++ NS_PUT16 (class, cp); ++ NS_PUT32 (0, cp); ++ NS_PUT16 (0, cp); ++ hp->arcount = htons (1); ++ break; ++ ++ default: ++ return -1; ++ } ++ return cp - buf; ++} ++ ++/* Common part of res_nmkquery and res_mkquery. */ ++static int ++context_mkquery_common (struct resolv_context *ctx, ++ int op, const char *dname, int class, int type, ++ const unsigned char *data, ++ unsigned char *buf, int buflen) ++{ ++ if (ctx == NULL) ++ return -1; ++ int result = __res_context_mkquery ++ (ctx, op, dname, class, type, data, buf, buflen); ++ if (result >= 2) ++ memcpy (&ctx->resp->id, buf, 2); ++ __resolv_context_put (ctx); ++ return result; + } +-libresolv_hidden_def (res_nmkquery) + ++/* Form all types of queries. Returns the size of the result or -1 on ++ error. + +-/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */ +-#ifndef T_OPT +-#define T_OPT 41 +-#endif ++ STATP points to an initialized resolver state. OP is the opcode of ++ the query. DNAME is the domain. CLASS and TYPE are the DNS query ++ class and type. DATA can be NULL; otherwise, it is a pointer to a ++ domain name which is included in the generated packet (if op == ++ NS_NOTIFY_OP). BUF must point to the out buffer of BUFLEN bytes. + ++ DATALEN and NEWRR_IN are currently ignored. */ + int +-__res_nopt(res_state statp, +- int n0, /* current offset in buffer */ +- u_char *buf, /* buffer to put query */ +- int buflen, /* size of buffer */ +- int anslen) /* UDP answer buffer size */ ++res_nmkquery (res_state statp, int op, const char *dname, ++ int class, int type, ++ const unsigned char *data, int datalen, ++ const unsigned char *newrr_in, ++ unsigned char *buf, int buflen) + { +- u_int16_t flags = 0; ++ return context_mkquery_common ++ (__resolv_context_get_override (statp), ++ op, dname, class, type, data, buf, buflen); ++} + +-#ifdef DEBUG +- if ((statp->options & RES_DEBUG) != 0U) +- printf(";; res_nopt()\n"); +-#endif ++int ++res_mkquery (int op, const char *dname, int class, int type, ++ const unsigned char *data, int datalen, ++ const unsigned char *newrr_in, ++ unsigned char *buf, int buflen) ++{ ++ return context_mkquery_common ++ (__resolv_context_get_preinit (), ++ op, dname, class, type, data, buf, buflen); ++} + +- HEADER *hp = (HEADER *) buf; +- u_char *cp = buf + n0; +- u_char *ep = buf + buflen; ++/* Create an OPT resource record. Return the length of the final ++ packet, or -1 on error. + +- if ((ep - cp) < 1 + RRFIXEDSZ) +- return -1; ++ STATP must be an initialized resolver state. N0 is the current ++ number of bytes of the packet (already written to BUF by the ++ aller). BUF is the packet being constructed. The array it ++ pointers to must be BUFLEN bytes long. ANSLEN is the advertised ++ EDNS buffer size (to be included in the OPT resource record). */ ++int ++__res_nopt (struct resolv_context *ctx, ++ int n0, unsigned char *buf, int buflen, int anslen) ++{ ++ uint16_t flags = 0; ++ HEADER *hp = (HEADER *) buf; ++ unsigned char *cp = buf + n0; ++ unsigned char *ep = buf + buflen; + +- *cp++ = 0; /* "." */ ++ if ((ep - cp) < 1 + RRFIXEDSZ) ++ return -1; + +- NS_PUT16(T_OPT, cp); /* TYPE */ +- NS_PUT16(MIN(anslen, 0xffff), cp); /* CLASS = UDP payload size */ +- *cp++ = NOERROR; /* extended RCODE */ +- *cp++ = 0; /* EDNS version */ ++ /* Add the root label. */ ++ *cp++ = 0; + +- if (statp->options & RES_USE_DNSSEC) { +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_opt()... ENDS0 DNSSEC\n"); +-#endif +- flags |= NS_OPT_DNSSEC_OK; +- } ++ NS_PUT16 (T_OPT, cp); /* Record type. */ ++ ++ /* Lowering the advertised buffer size based on the actual ++ answer buffer size is desirable because the server will ++ minimize the reply to fit into the UDP packet (and A ++ non-minimal response might not fit the buffer). ++ ++ The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP ++ fallback and a non-minimal response which has to be ++ hard-truncated in the stub resolver, but this is price to ++ pay for avoiding fragmentation. (This issue does not ++ affect the nss_dns functions because they use the stub ++ resolver in such a way that it allocates a properly sized ++ response buffer.) */ ++ { ++ uint16_t buffer_size; ++ if (anslen < 512) ++ buffer_size = 512; ++ else if (anslen > RESOLV_EDNS_BUFFER_SIZE) ++ buffer_size = RESOLV_EDNS_BUFFER_SIZE; ++ else ++ buffer_size = anslen; ++ NS_PUT16 (buffer_size, cp); ++ } + +- NS_PUT16(flags, cp); +- NS_PUT16(0, cp); /* RDLEN */ +- hp->arcount = htons(ntohs(hp->arcount) + 1); ++ *cp++ = NOERROR; /* Extended RCODE. */ ++ *cp++ = 0; /* EDNS version. */ + +- return cp - buf; ++ if (ctx->resp->options & RES_USE_DNSSEC) ++ flags |= NS_OPT_DNSSEC_OK; ++ ++ NS_PUT16 (flags, cp); ++ NS_PUT16 (0, cp); /* RDATA length (no options are preent). */ ++ hp->arcount = htons (ntohs (hp->arcount) + 1); ++ ++ return cp - buf; + } +-libresolv_hidden_def (__res_nopt) ++ ++#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2) ++# undef res_mkquery ++weak_alias (__res_mkquery, res_mkquery); ++#endif +diff --git a/resolv/res_query.c b/resolv/res_query.c +index 57c679d6fca5d9dc..ebbe5a6a4ed86abe 100644 +--- a/resolv/res_query.c ++++ b/resolv/res_query.c +@@ -64,11 +64,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; +-static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + #include + #include + #include +@@ -79,12 +74,12 @@ static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vix + #include + #include + #include ++#include ++#include + #include + #include + #include +- +-/* Options. Leave them on. */ +-/* #undef DEBUG */ ++#include + + #if PACKETSZ > 65536 + #define MAXPACKET PACKETSZ +@@ -95,39 +90,33 @@ static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vix + #define QUERYSIZE (HFIXEDSZ + QFIXEDSZ + MAXCDNAME + 1) + + static int +-__libc_res_nquerydomain(res_state statp, const char *name, const char *domain, +- int class, int type, u_char *answer, int anslen, +- u_char **answerp, u_char **answerp2, int *nanswerp2, +- int *resplen2, int *answerp2_malloced); +- +-/* +- * Formulate a normal query, send, and await answer. +- * Returned answer is placed in supplied buffer "answer". +- * Perform preliminary check of answer, returning success only +- * if no error is indicated and the answer count is nonzero. +- * Return the size of the response on success, -1 on error. +- * Error number is left in H_ERRNO. +- * +- * Caller must parse answer and determine whether it answers the question. +- */ ++__res_context_querydomain (struct resolv_context *, ++ const char *name, const char *domain, ++ int class, int type, unsigned char *answer, int anslen, ++ unsigned char **answerp, unsigned char **answerp2, int *nanswerp2, ++ int *resplen2, int *answerp2_malloced); ++ ++/* Formulate a normal query, send, and await answer. Returned answer ++ is placed in supplied buffer ANSWER. Perform preliminary check of ++ answer, returning success only if no error is indicated and the ++ answer count is nonzero. Return the size of the response on ++ success, -1 on error. Error number is left in h_errno. ++ ++ Caller must parse answer and determine whether it answers the ++ question. */ + int +-__libc_res_nquery(res_state statp, +- const char *name, /* domain name */ +- int class, int type, /* class and type of query */ +- u_char *answer, /* buffer to put answer */ +- int anslen, /* size of answer buffer */ +- u_char **answerp, /* if buffer needs to be enlarged */ +- u_char **answerp2, +- int *nanswerp2, +- int *resplen2, +- int *answerp2_malloced) ++__res_context_query (struct resolv_context *ctx, const char *name, ++ int class, int type, ++ unsigned char *answer, int anslen, ++ unsigned char **answerp, unsigned char **answerp2, ++ int *nanswerp2, int *resplen2, int *answerp2_malloced) + { ++ struct __res_state *statp = ctx->resp; + HEADER *hp = (HEADER *) answer; + HEADER *hp2; + int n, use_malloc = 0; +- u_int oflags = statp->_flags; + +- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE; ++ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE; + u_char *buf = alloca (bufsize); + u_char *query1 = buf; + int nquery1 = -1; +@@ -137,21 +126,18 @@ __libc_res_nquery(res_state statp, + again: + hp->rcode = NOERROR; /* default */ + +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_query(%s, %d, %d)\n", name, class, type); +-#endif +- +- if (type == T_UNSPEC) ++ if (type == T_QUERY_A_AND_AAAA) + { +- n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL, +- query1, bufsize); ++ n = __res_context_mkquery (ctx, QUERY, name, class, T_A, NULL, ++ query1, bufsize); + if (n > 0) + { +- if ((oflags & RES_F_EDNS0ERR) == 0 +- && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) ++ if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) + { +- n = __res_nopt(statp, n, query1, bufsize, anslen / 2); ++ /* Use RESOLV_EDNS_BUFFER_SIZE because the receive ++ buffer can be reallocated. */ ++ n = __res_nopt (ctx, n, query1, bufsize, ++ RESOLV_EDNS_BUFFER_SIZE); + if (n < 0) + goto unspec_nomem; + } +@@ -167,13 +153,14 @@ __libc_res_nquery(res_state statp, + } + int nused = n + npad; + query2 = buf + nused; +- n = res_nmkquery(statp, QUERY, name, class, T_AAAA, NULL, 0, +- NULL, query2, bufsize - nused); ++ n = __res_context_mkquery (ctx, QUERY, name, class, T_AAAA, ++ NULL, query2, bufsize - nused); + if (n > 0 +- && (oflags & RES_F_EDNS0ERR) == 0 + && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) +- n = __res_nopt(statp, n, query2, bufsize - nused - n, +- anslen / 2); ++ /* Use RESOLV_EDNS_BUFFER_SIZE because the receive ++ buffer can be reallocated. */ ++ n = __res_nopt (ctx, n, query2, bufsize, ++ RESOLV_EDNS_BUFFER_SIZE); + nquery2 = n; + } + +@@ -181,21 +168,29 @@ __libc_res_nquery(res_state statp, + } + else + { +- n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, +- query1, bufsize); ++ n = __res_context_mkquery (ctx, QUERY, name, class, type, NULL, ++ query1, bufsize); + + if (n > 0 +- && (oflags & RES_F_EDNS0ERR) == 0 + && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0) +- n = __res_nopt(statp, n, query1, bufsize, anslen); ++ { ++ /* Use RESOLV_EDNS_BUFFER_SIZE if the receive buffer ++ can be reallocated. */ ++ size_t advertise; ++ if (answerp == NULL) ++ advertise = anslen; ++ else ++ advertise = RESOLV_EDNS_BUFFER_SIZE; ++ n = __res_nopt (ctx, n, query1, bufsize, advertise); ++ } + + nquery1 = n; + } + +- if (__builtin_expect (n <= 0, 0) && !use_malloc) { ++ if (__glibc_unlikely (n <= 0) && !use_malloc) { + /* Retry just in case res_nmkquery failed because of too + short buffer. Shouldn't happen. */ +- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET; ++ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET; + buf = malloc (bufsize); + if (buf != NULL) { + query1 = buf; +@@ -203,43 +198,25 @@ __libc_res_nquery(res_state statp, + goto again; + } + } +- if (__builtin_expect (n <= 0, 0)) { +- /* If the query choked with EDNS0, retry without EDNS0. */ +- if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0 +- && ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) { +- statp->_flags |= RES_F_EDNS0ERR; +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_nquery: retry without EDNS0\n"); +-#endif +- goto again; +- } +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_query: mkquery failed\n"); +-#endif ++ if (__glibc_unlikely (n <= 0)) { + RES_SET_H_ERRNO(statp, NO_RECOVERY); + if (use_malloc) + free (buf); + return (n); + } + assert (answerp == NULL || (void *) *answerp == (void *) answer); +- n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer, +- anslen, answerp, answerp2, nanswerp2, resplen2, +- answerp2_malloced); ++ n = __res_context_send (ctx, query1, nquery1, query2, nquery2, answer, ++ anslen, answerp, answerp2, nanswerp2, resplen2, ++ answerp2_malloced); + if (use_malloc) + free (buf); + if (n < 0) { +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_query: send error\n"); +-#endif + RES_SET_H_ERRNO(statp, TRY_AGAIN); + return (n); + } + + if (answerp != NULL) +- /* __libc_res_nsend might have reallocated the buffer. */ ++ /* __res_context_send might have reallocated the buffer. */ + hp = (HEADER *) *answerp; + + /* We simplify the following tests by assigning HP to HP2 or +@@ -263,15 +240,6 @@ __libc_res_nquery(res_state statp, + + if ((hp->rcode != NOERROR || ntohs(hp->ancount) == 0) + && (hp2->rcode != NOERROR || ntohs(hp2->ancount) == 0)) { +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) { +- printf(";; rcode = %d, ancount=%d\n", hp->rcode, +- ntohs(hp->ancount)); +- if (hp != hp2) +- printf(";; rcode2 = %d, ancount2=%d\n", hp2->rcode, +- ntohs(hp2->ancount)); +- } +-#endif + switch (hp->rcode == NOERROR ? hp2->rcode : hp->rcode) { + case NXDOMAIN: + if ((hp->rcode == NOERROR && ntohs (hp->ancount) != 0) +@@ -308,7 +276,24 @@ __libc_res_nquery(res_state statp, + success: + return (n); + } +-libresolv_hidden_def (__libc_res_nquery) ++libresolv_hidden_def (__res_context_query) ++ ++/* Common part of res_nquery and res_query. */ ++static int ++context_query_common (struct resolv_context *ctx, ++ const char *name, int class, int type, ++ unsigned char *answer, int anslen) ++{ ++ if (ctx == NULL) ++ { ++ RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); ++ return -1; ++ } ++ int result = __res_context_query (ctx, name, class, type, answer, anslen, ++ NULL, NULL, NULL, NULL, NULL); ++ __resolv_context_put (ctx); ++ return result; ++} + + int + res_nquery(res_state statp, +@@ -317,30 +302,31 @@ res_nquery(res_state statp, + u_char *answer, /* buffer to put answer */ + int anslen) /* size of answer buffer */ + { +- return __libc_res_nquery(statp, name, class, type, answer, anslen, +- NULL, NULL, NULL, NULL, NULL); ++ return context_query_common ++ (__resolv_context_get_override (statp), name, class, type, answer, anslen); + } +-libresolv_hidden_def (res_nquery) + +-/* +- * Formulate a normal query, send, and retrieve answer in supplied buffer. +- * Return the size of the response on success, -1 on error. +- * If enabled, implement search rules until answer or unrecoverable failure +- * is detected. Error code, if any, is left in H_ERRNO. +- */ + int +-__libc_res_nsearch(res_state statp, +- const char *name, /* domain name */ +- int class, int type, /* class and type of query */ +- u_char *answer, /* buffer to put answer */ +- int anslen, /* size of answer */ +- u_char **answerp, +- u_char **answerp2, +- int *nanswerp2, +- int *resplen2, +- int *answerp2_malloced) ++res_query (const char *name, int class, int type, ++ unsigned char *answer, int anslen) + { +- const char *cp, * const *domain; ++ return context_query_common ++ (__resolv_context_get (), name, class, type, answer, anslen); ++} ++ ++/* Formulate a normal query, send, and retrieve answer in supplied ++ buffer. Return the size of the response on success, -1 on error. ++ If enabled, implement search rules until answer or unrecoverable ++ failure is detected. Error code, if any, is left in h_errno. */ ++int ++__res_context_search (struct resolv_context *ctx, ++ const char *name, int class, int type, ++ unsigned char *answer, int anslen, ++ unsigned char **answerp, unsigned char **answerp2, ++ int *nanswerp2, int *resplen2, int *answerp2_malloced) ++{ ++ struct __res_state *statp = ctx->resp; ++ const char *cp; + HEADER *hp = (HEADER *) answer; + char tmp[NS_MAXDNAME]; + u_int dots; +@@ -360,16 +346,11 @@ __libc_res_nsearch(res_state statp, + trailing_dot++; + + /* If there aren't any dots, it could be a user-level alias. */ +- if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL) +- return (__libc_res_nquery(statp, cp, class, type, answer, +- anslen, answerp, answerp2, +- nanswerp2, resplen2, answerp2_malloced)); +- +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf("dots=%d, statp->ndots=%d, trailing_dot=%d, name=%s\n", +- (int)dots,(int)statp->ndots,(int)trailing_dot,name); +-#endif ++ if (!dots && (cp = __res_context_hostalias ++ (ctx, name, tmp, sizeof tmp))!= NULL) ++ return __res_context_query (ctx, cp, class, type, answer, ++ anslen, answerp, answerp2, ++ nanswerp2, resplen2, answerp2_malloced); + + /* + * If there are enough dots in the name, let's just give it a +@@ -378,10 +359,10 @@ __libc_res_nsearch(res_state statp, + */ + saved_herrno = -1; + if (dots >= statp->ndots || trailing_dot) { +- ret = __libc_res_nquerydomain(statp, name, NULL, class, type, +- answer, anslen, answerp, +- answerp2, nanswerp2, resplen2, +- answerp2_malloced); ++ ret = __res_context_querydomain (ctx, name, NULL, class, type, ++ answer, anslen, answerp, ++ answerp2, nanswerp2, resplen2, ++ answerp2_malloced); + if (ret > 0 || trailing_dot + /* If the second response is valid then we use that. */ + || (ret == 0 && resplen2 != NULL && *resplen2 > 0)) +@@ -411,20 +392,31 @@ __libc_res_nsearch(res_state statp, + (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0)) { + int done = 0; + +- for (domain = (const char * const *)statp->dnsrch; +- *domain && !done; +- domain++) { ++ for (size_t domain_index = 0; !done; ++domain_index) { ++ const char *dname = __resolv_context_search_list ++ (ctx, domain_index); ++ if (dname == NULL) ++ break; + searched = 1; + +- if (domain[0][0] == '\0' || +- (domain[0][0] == '.' && domain[0][1] == '\0')) ++ /* __res_context_querydoman concatenates name ++ with dname with a "." in between. If we ++ pass it in dname the "." we got from the ++ configured default search path, we'll end ++ up with "name..", which won't resolve. ++ OTOH, passing it "" will result in "name.", ++ which has the intended effect for both ++ possible representations of the root ++ domain. */ ++ if (dname[0] == '.') ++ dname++; ++ if (dname[0] == '\0') + root_on_list++; + +- ret = __libc_res_nquerydomain(statp, name, *domain, +- class, type, +- answer, anslen, answerp, +- answerp2, nanswerp2, +- resplen2, answerp2_malloced); ++ ret = __res_context_querydomain ++ (ctx, name, dname, class, type, ++ answer, anslen, answerp, answerp2, nanswerp2, ++ resplen2, answerp2_malloced); + if (ret > 0 || (ret == 0 && resplen2 != NULL + && *resplen2 > 0)) + return (ret); +@@ -487,15 +479,15 @@ __libc_res_nsearch(res_state statp, + } + + /* +- * f the query has not already been tried as is then try it ++ * If the query has not already been tried as is then try it + * unless RES_NOTLDQUERY is set and there were no dots. + */ + if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0) + && !(tried_as_is || root_on_list)) { +- ret = __libc_res_nquerydomain(statp, name, NULL, class, type, +- answer, anslen, answerp, +- answerp2, nanswerp2, resplen2, +- answerp2_malloced); ++ ret = __res_context_querydomain ++ (ctx, name, NULL, class, type, ++ answer, anslen, answerp, answerp2, nanswerp2, ++ resplen2, answerp2_malloced); + if (ret > 0 || (ret == 0 && resplen2 != NULL + && *resplen2 > 0)) + return (ret); +@@ -523,7 +515,24 @@ __libc_res_nsearch(res_state statp, + RES_SET_H_ERRNO(statp, TRY_AGAIN); + return (-1); + } +-libresolv_hidden_def (__libc_res_nsearch) ++libresolv_hidden_def (__res_context_search) ++ ++/* Common part of res_nsearch and res_search. */ ++static int ++context_search_common (struct resolv_context *ctx, ++ const char *name, int class, int type, ++ unsigned char *answer, int anslen) ++{ ++ if (ctx == NULL) ++ { ++ RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); ++ return -1; ++ } ++ int result = __res_context_search (ctx, name, class, type, answer, anslen, ++ NULL, NULL, NULL, NULL, NULL); ++ __resolv_context_put (ctx); ++ return result; ++} + + int + res_nsearch(res_state statp, +@@ -532,42 +541,35 @@ res_nsearch(res_state statp, + u_char *answer, /* buffer to put answer */ + int anslen) /* size of answer */ + { +- return __libc_res_nsearch(statp, name, class, type, answer, +- anslen, NULL, NULL, NULL, NULL, NULL); ++ return context_search_common ++ (__resolv_context_get_override (statp), name, class, type, answer, anslen); + } +-libresolv_hidden_def (res_nsearch) + +-/* +- * Perform a call on res_query on the concatenation of name and domain, +- * removing a trailing dot from name if domain is NULL. +- */ ++int ++res_search (const char *name, int class, int type, ++ unsigned char *answer, int anslen) ++{ ++ return context_search_common ++ (__resolv_context_get (), name, class, type, answer, anslen); ++} ++ ++/* Perform a call on res_query on the concatenation of name and ++ domain. */ + static int +-__libc_res_nquerydomain(res_state statp, +- const char *name, +- const char *domain, +- int class, int type, /* class and type of query */ +- u_char *answer, /* buffer to put answer */ +- int anslen, /* size of answer */ +- u_char **answerp, +- u_char **answerp2, +- int *nanswerp2, +- int *resplen2, +- int *answerp2_malloced) ++__res_context_querydomain (struct resolv_context *ctx, ++ const char *name, const char *domain, ++ int class, int type, ++ unsigned char *answer, int anslen, ++ unsigned char **answerp, unsigned char **answerp2, ++ int *nanswerp2, int *resplen2, ++ int *answerp2_malloced) + { ++ struct __res_state *statp = ctx->resp; + char nbuf[MAXDNAME]; + const char *longname = nbuf; + size_t n, d; + +-#ifdef DEBUG +- if (statp->options & RES_DEBUG) +- printf(";; res_nquerydomain(%s, %s, %d, %d)\n", +- name, domain?domain:"", class, type); +-#endif + if (domain == NULL) { +- /* +- * Check for trailing '.'; +- * copy without '.' if present. +- */ + n = strlen(name); + + /* Decrement N prior to checking it against MAXDNAME +@@ -578,11 +580,7 @@ __libc_res_nquerydomain(res_state statp, + RES_SET_H_ERRNO(statp, NO_RECOVERY); + return (-1); + } +- if (name[n] == '.') { +- strncpy(nbuf, name, n); +- nbuf[n] = '\0'; +- } else +- longname = name; ++ longname = name; + } else { + n = strlen(name); + d = strlen(domain); +@@ -592,9 +590,28 @@ __libc_res_nquerydomain(res_state statp, + } + sprintf(nbuf, "%s.%s", name, domain); + } +- return (__libc_res_nquery(statp, longname, class, type, answer, +- anslen, answerp, answerp2, nanswerp2, +- resplen2, answerp2_malloced)); ++ return __res_context_query (ctx, longname, class, type, answer, ++ anslen, answerp, answerp2, nanswerp2, ++ resplen2, answerp2_malloced); ++} ++ ++/* Common part of res_nquerydomain and res_querydomain. */ ++static int ++context_querydomain_common (struct resolv_context *ctx, ++ const char *name, const char *domain, ++ int class, int type, ++ unsigned char *answer, int anslen) ++{ ++ if (ctx == NULL) ++ { ++ RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); ++ return -1; ++ } ++ int result = __res_context_querydomain (ctx, name, domain, class, type, ++ answer, anslen, ++ NULL, NULL, NULL, NULL, NULL); ++ __resolv_context_put (ctx); ++ return result; + } + + int +@@ -605,19 +622,28 @@ res_nquerydomain(res_state statp, + u_char *answer, /* buffer to put answer */ + int anslen) /* size of answer */ + { +- return __libc_res_nquerydomain(statp, name, domain, class, type, +- answer, anslen, NULL, NULL, NULL, NULL, +- NULL); ++ return context_querydomain_common ++ (__resolv_context_get_override (statp), ++ name, domain, class, type, answer, anslen); ++} ++ ++int ++res_querydomain (const char *name, const char *domain, int class, int type, ++ unsigned char *answer, int anslen) ++{ ++ return context_querydomain_common ++ (__resolv_context_get (), name, domain, class, type, answer, anslen); + } +-libresolv_hidden_def (res_nquerydomain) + + const char * +-res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { ++__res_context_hostalias (struct resolv_context *ctx, ++ const char *name, char *dst, size_t siz) ++{ + char *file, *cp1, *cp2; + char buf[BUFSIZ]; + FILE *fp; + +- if (statp->options & RES_NOALIASES) ++ if (ctx->resp->options & RES_NOALIASES) + return (NULL); + file = getenv("HOSTALIASES"); + if (file == NULL || (fp = fopen(file, "rce")) == NULL) +@@ -647,4 +673,43 @@ res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) { + fclose(fp); + return (NULL); + } +-libresolv_hidden_def (res_hostalias) ++libresolv_hidden_def (__res_context_hostalias) ++ ++/* Common part of res_hostalias and hostalias. */ ++static const char * ++context_hostalias_common (struct resolv_context *ctx, ++ const char *name, char *dst, size_t siz) ++{ ++ if (ctx == NULL) ++ { ++ RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); ++ return NULL; ++ } ++ const char *result = __res_context_hostalias (ctx, name, dst, siz); ++ __resolv_context_put (ctx); ++ return result; ++} ++ ++const char * ++res_hostalias (res_state statp, const char *name, char *dst, size_t siz) ++{ ++ return context_hostalias_common ++ (__resolv_context_get_override (statp), name, dst, siz); ++} ++ ++const char * ++hostalias (const char *name) ++{ ++ static char abuf[MAXDNAME]; ++ return context_hostalias_common ++ (__resolv_context_get (), name, abuf, sizeof (abuf)); ++} ++ ++#if SHLIB_COMPAT (libresolv, GLIBC_2_0, GLIBC_2_2) ++# undef res_query ++# undef res_querydomain ++# undef res_search ++weak_alias (__res_query, res_query); ++weak_alias (__res_querydomain, res_querydomain); ++weak_alias (__res_search, res_search); ++#endif +diff --git a/resolv/res_randomid.c b/resolv/res_randomid.c +new file mode 100644 +index 0000000000000000..e0dbe4c8ff259527 +--- /dev/null ++++ b/resolv/res_randomid.c +@@ -0,0 +1,92 @@ ++/* Legacy libresolv random number generator. ++ Copyright (C) 1995-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* ++ * Copyright (c) 1985, 1989, 1993 ++ * The Regents of the University of California. 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. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. ++ */ ++ ++/* ++ * Portions Copyright (c) 1993 by Digital Equipment Corporation. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies, and that ++ * the name of Digital Equipment Corporation not be used in advertising or ++ * publicity pertaining to distribution of the document or software without ++ * specific, written prior permission. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL ++ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT ++ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++/* ++ * Portions Copyright (c) 1996-1999 by Internet Software Consortium. ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS ++ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE ++ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. ++ */ ++ ++#include ++#include ++ ++unsigned int ++res_randomid (void) { ++ return 0xffff & __getpid (); ++} ++libc_hidden_def (__res_randomid) +diff --git a/resolv/res_send.c b/resolv/res_send.c +index 0cb573857583dd93..b396aae03c9eeb6e 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2016 Free Software Foundation, Inc. ++/* Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -81,11 +81,6 @@ + * SOFTWARE. + */ + +-#if defined(LIBC_SCCS) && !defined(lint) +-static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; +-static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixie Exp $"; +-#endif /* LIBC_SCCS and not lint */ +- + /* + * Send query to name server and wait for reply. + */ +@@ -106,13 +101,15 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi + #include + #include + #include +-#include ++#include ++#include + #include +-#include + #include + #include + #include + #include ++#include ++#include + + #if PACKETSZ > 65536 + #define MAXPACKET PACKETSZ +@@ -120,14 +117,6 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi + #define MAXPACKET 65536 + #endif + +- +-#ifndef __ASSUME_SOCK_CLOEXEC +-static int __have_o_nonblock; +-#else +-# define __have_o_nonblock 0 +-#endif +- +- + /* From ev_streams.c. */ + + static inline void +@@ -172,7 +161,7 @@ evSubTime(struct timespec *res, const struct timespec *minuend, + } + } + +-static inline int ++static int + evCmpTime(struct timespec a, struct timespec b) { + long x = a.tv_sec - b.tv_sec; + +@@ -181,7 +170,7 @@ evCmpTime(struct timespec a, struct timespec b) { + return (x < 0L ? (-1) : x > 0L ? (1) : (0)); + } + +-static inline void ++static void + evNowTime(struct timespec *res) { + struct timeval now; + +@@ -192,14 +181,11 @@ evNowTime(struct timespec *res) { + } + + +-/* Options. Leave them on. */ +-/* #undef DEBUG */ +-#include "res_debug.h" +- + #define EXT(res) ((res)->_u._ext) + + /* Forward. */ + ++static struct sockaddr *get_nsaddr (res_state, unsigned int); + static int send_vc(res_state, const u_char *, int, + const u_char *, int, + u_char **, int *, int *, int, u_char **, +@@ -209,11 +195,6 @@ static int send_dg(res_state, const u_char *, int, + u_char **, int *, int *, int, + int *, int *, u_char **, + u_char **, int *, int *, int *); +-#ifdef DEBUG +-static void Aerror(const res_state, FILE *, const char *, int, +- const struct sockaddr *); +-static void Perror(const res_state, FILE *, const char *, int); +-#endif + static int sock_eq(struct sockaddr_in6 *, struct sockaddr_in6 *); + + /* Public. */ +@@ -237,20 +218,21 @@ res_ourserver_p(const res_state statp, const struct sockaddr_in6 *inp) + in_port_t port = in4p->sin_port; + in_addr_t addr = in4p->sin_addr.s_addr; + +- for (ns = 0; ns < MAXNS; ns++) { ++ for (ns = 0; ns < statp->nscount; ns++) { + const struct sockaddr_in *srv = +- (struct sockaddr_in *)EXT(statp).nsaddrs[ns]; ++ (struct sockaddr_in *) get_nsaddr (statp, ns); + +- if ((srv != NULL) && (srv->sin_family == AF_INET) && ++ if ((srv->sin_family == AF_INET) && + (srv->sin_port == port) && + (srv->sin_addr.s_addr == INADDR_ANY || + srv->sin_addr.s_addr == addr)) + return (1); + } + } else if (inp->sin6_family == AF_INET6) { +- for (ns = 0; ns < MAXNS; ns++) { +- const struct sockaddr_in6 *srv = EXT(statp).nsaddrs[ns]; +- if ((srv != NULL) && (srv->sin6_family == AF_INET6) && ++ for (ns = 0; ns < statp->nscount; ns++) { ++ const struct sockaddr_in6 *srv ++ = (struct sockaddr_in6 *) get_nsaddr (statp, ns); ++ if ((srv->sin6_family == AF_INET6) && + (srv->sin6_port == inp->sin6_port) && + !(memcmp(&srv->sin6_addr, &in6addr_any, + sizeof (struct in6_addr)) && +@@ -262,6 +244,12 @@ res_ourserver_p(const res_state statp, const struct sockaddr_in6 *inp) + return (0); + } + ++int ++res_isourserver (const struct sockaddr_in *inp) ++{ ++ return res_ourserver_p (&_res, (const struct sockaddr_in6 *) inp); ++} ++ + /* int + * res_nameinquery(name, type, class, buf, eom) + * look for (name,type,class) in the query section of packet (buf,eom) +@@ -301,6 +289,62 @@ res_nameinquery(const char *name, int type, int class, + } + libresolv_hidden_def (res_nameinquery) + ++/* Returns a shift value for the name server index. Used to implement ++ RES_ROTATE. */ ++static unsigned int ++nameserver_offset (struct __res_state *statp) ++{ ++ /* If we only have one name server or rotation is disabled, return ++ offset 0 (no rotation). */ ++ unsigned int nscount = statp->nscount; ++ if (nscount <= 1 || !(statp->options & RES_ROTATE)) ++ return 0; ++ ++ /* Global offset. The lowest bit indicates whether the offset has ++ been initialized with a random value. Use relaxed MO to access ++ global_offset because all we need is a sequence of roughly ++ sequential value. */ ++ static unsigned int global_offset; ++ unsigned int offset = atomic_fetch_add_relaxed (&global_offset, 2); ++ if ((offset & 1) == 0) ++ { ++ /* Initialization is required. */ ++#if HP_TIMING_AVAIL ++ uint64_t ticks; ++ HP_TIMING_NOW (ticks); ++ offset = ticks; ++#else ++ struct timeval tv; ++ __gettimeofday (&tv, NULL); ++ offset = ((tv.tv_sec << 8) ^ tv.tv_usec); ++#endif ++ /* The lowest bit is the most random. Preserve it. */ ++ offset <<= 1; ++ ++ /* Store the new starting value. atomic_fetch_add_relaxed ++ returns the old value, so emulate that by storing the new ++ (incremented) value. Concurrent initialization with ++ different random values is harmless. */ ++ atomic_store_relaxed (&global_offset, (offset | 1) + 2); ++ } ++ ++ /* Remove the initialization bit. */ ++ offset >>= 1; ++ ++ /* Avoid the division in the most common cases. */ ++ switch (nscount) ++ { ++ case 2: ++ return offset & 1; ++ case 3: ++ return offset % 3; ++ case 4: ++ return offset & 3; ++ default: ++ return offset % nscount; ++ } ++} ++ + /* int + * res_queriesmatch(buf1, eom1, buf2, eom2) + * is there a 1:1 mapping of (name,type,class) +@@ -357,12 +401,15 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, + libresolv_hidden_def (res_queriesmatch) + + int +-__libc_res_nsend(res_state statp, const u_char *buf, int buflen, +- const u_char *buf2, int buflen2, +- u_char *ans, int anssiz, u_char **ansp, u_char **ansp2, +- int *nansp2, int *resplen2, int *ansp2_malloced) ++__res_context_send (struct resolv_context *ctx, ++ const unsigned char *buf, int buflen, ++ const unsigned char *buf2, int buflen2, ++ unsigned char *ans, int anssiz, ++ unsigned char **ansp, unsigned char **ansp2, ++ int *nansp2, int *resplen2, int *ansp2_malloced) + { +- int gotsomewhere, terrno, try, v_circuit, resplen, ns, n; ++ struct __res_state *statp = ctx->resp; ++ int gotsomewhere, terrno, try, v_circuit, resplen, n; + + if (statp->nscount == 0) { + __set_errno (ESRCH); +@@ -374,24 +421,6 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, + return (-1); + } + +-#ifdef USE_HOOKS +- if (__builtin_expect (statp->qhook || statp->rhook, 0)) { +- if (anssiz < MAXPACKET && ansp) { +- /* Always allocate MAXPACKET, callers expect +- this specific size. */ +- u_char *buf = malloc (MAXPACKET); +- if (buf == NULL) +- return (-1); +- memcpy (buf, ans, HFIXEDSZ); +- *ansp = buf; +- ans = buf; +- anssiz = MAXPACKET; +- } +- } +-#endif +- +- DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY), +- (stdout, ";; res_send()\n"), buf, buflen); + v_circuit = ((statp->options & RES_USEVC) + || buflen > PACKETSZ + || buflen2 > PACKETSZ); +@@ -402,165 +431,68 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, + * If the ns_addr_list in the resolver context has changed, then + * invalidate our cached copy and the associated timing data. + */ +- if (EXT(statp).nsinit) { ++ if (EXT(statp).nscount != 0) { + int needclose = 0; + + if (EXT(statp).nscount != statp->nscount) + needclose++; + else +- for (ns = 0; ns < MAXNS; ns++) { +- unsigned int map = EXT(statp).nsmap[ns]; +- if (map < MAXNS ++ for (unsigned int ns = 0; ns < statp->nscount; ns++) { ++ if (statp->nsaddr_list[ns].sin_family != 0 + && !sock_eq((struct sockaddr_in6 *) +- &statp->nsaddr_list[map], ++ &statp->nsaddr_list[ns], + EXT(statp).nsaddrs[ns])) + { + needclose++; + break; + } + } +- if (needclose) ++ if (needclose) { + __res_iclose(statp, false); ++ EXT(statp).nscount = 0; ++ } + } + + /* + * Maybe initialize our private copy of the ns_addr_list. + */ +- if (EXT(statp).nsinit == 0) { +- unsigned char map[MAXNS]; +- +- memset (map, MAXNS, sizeof (map)); +- for (n = 0; n < MAXNS; n++) { +- ns = EXT(statp).nsmap[n]; +- if (ns < statp->nscount) +- map[ns] = n; +- else if (ns < MAXNS) { +- free(EXT(statp).nsaddrs[n]); +- EXT(statp).nsaddrs[n] = NULL; +- EXT(statp).nsmap[n] = MAXNS; +- } +- } +- n = statp->nscount - EXT(statp).nscount6; +- if (n > EXT(statp).nscount) +- for (n = EXT(statp).nscount, ns = 0; +- n < statp->nscount - EXT(statp).nscount6; n++) { +- while (ns < MAXNS +- && EXT(statp).nsmap[ns] != MAXNS) +- ns++; +- if (ns == MAXNS) +- break; +- EXT(statp).nsmap[ns] = n; +- map[n] = ns++; +- } +- EXT(statp).nscount = n; +- for (ns = 0; ns < EXT(statp).nscount; ns++) { +- n = map[ns]; +- if (EXT(statp).nsaddrs[n] == NULL) +- EXT(statp).nsaddrs[n] = ++ if (EXT(statp).nscount == 0) { ++ for (unsigned int ns = 0; ns < statp->nscount; ns++) { ++ EXT(statp).nssocks[ns] = -1; ++ if (statp->nsaddr_list[ns].sin_family == 0) ++ continue; ++ if (EXT(statp).nsaddrs[ns] == NULL) ++ EXT(statp).nsaddrs[ns] = + malloc(sizeof (struct sockaddr_in6)); +- if (EXT(statp).nsaddrs[n] != NULL) { +- memset (mempcpy(EXT(statp).nsaddrs[n], ++ if (EXT(statp).nsaddrs[ns] != NULL) ++ memset (mempcpy(EXT(statp).nsaddrs[ns], + &statp->nsaddr_list[ns], + sizeof (struct sockaddr_in)), + '\0', + sizeof (struct sockaddr_in6) + - sizeof (struct sockaddr_in)); +- EXT(statp).nssocks[n] = -1; +- n++; +- } + } +- EXT(statp).nsinit = 1; ++ EXT(statp).nscount = statp->nscount; + } + +- /* +- * Some resolvers want to even out the load on their nameservers. +- * Note that RES_BLAST overrides RES_ROTATE. +- */ +- if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) && +- (statp->options & RES_BLAST) == 0) { +- struct sockaddr_in6 *ina; +- unsigned int map; +- +- n = 0; +- while (n < MAXNS && EXT(statp).nsmap[n] == MAXNS) +- n++; +- if (n < MAXNS) { +- ina = EXT(statp).nsaddrs[n]; +- map = EXT(statp).nsmap[n]; +- for (;;) { +- ns = n + 1; +- while (ns < MAXNS +- && EXT(statp).nsmap[ns] == MAXNS) +- ns++; +- if (ns == MAXNS) +- break; +- EXT(statp).nsaddrs[n] = EXT(statp).nsaddrs[ns]; +- EXT(statp).nsmap[n] = EXT(statp).nsmap[ns]; +- n = ns; +- } +- EXT(statp).nsaddrs[n] = ina; +- EXT(statp).nsmap[n] = map; +- } +- } ++ /* Name server index offset. Used to implement ++ RES_ROTATE. */ ++ unsigned int ns_offset = nameserver_offset (statp); + + /* + * Send request, RETRY times, or until successful. + */ + for (try = 0; try < statp->retry; try++) { +- for (ns = 0; ns < MAXNS; ns++) ++ for (unsigned ns_shift = 0; ns_shift < statp->nscount; ns_shift++) + { +-#ifdef DEBUG +- char tmpbuf[40]; +-#endif +- struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; ++ /* The actual name server index. This implements ++ RES_ROTATE. */ ++ unsigned int ns = ns_shift + ns_offset; ++ if (ns >= statp->nscount) ++ ns -= statp->nscount; + +- if (nsap == NULL) +- goto next_ns; + same_ns: +-#ifdef USE_HOOKS +- if (__builtin_expect (statp->qhook != NULL, 0)) { +- int done = 0, loops = 0; +- +- do { +- res_sendhookact act; +- +- struct sockaddr_in *nsap4; +- nsap4 = (struct sockaddr_in *) nsap; +- act = (*statp->qhook)(&nsap4, &buf, &buflen, +- ans, anssiz, &resplen); +- nsap = (struct sockaddr_in6 *) nsap4; +- switch (act) { +- case res_goahead: +- done = 1; +- break; +- case res_nextns: +- __res_iclose(statp, false); +- goto next_ns; +- case res_done: +- return (resplen); +- case res_modified: +- /* give the hook another try */ +- if (++loops < 42) /*doug adams*/ +- break; +- /*FALLTHROUGH*/ +- case res_error: +- /*FALLTHROUGH*/ +- default: +- return (-1); +- } +- } while (!done); +- } +-#endif +- +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; Querying server (# %d) address = %s\n", +- ns + 1, inet_ntop(nsap->sin6_family, +- (nsap->sin6_family == AF_INET6 +- ? &nsap->sin6_addr +- : &((struct sockaddr_in *) nsap)->sin_addr), +- tmpbuf, sizeof (tmpbuf)))); +- +- if (__builtin_expect (v_circuit, 0)) { ++ if (__glibc_unlikely (v_circuit)) { + /* Use VC; at most one attempt per server. */ + try = statp->retry; + n = send_vc(statp, buf, buflen, buf2, buflen2, +@@ -589,22 +521,6 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, + + resplen = n; + +- Dprint((statp->options & RES_DEBUG) || +- ((statp->pfcode & RES_PRF_REPLY) && +- (statp->pfcode & RES_PRF_HEAD1)), +- (stdout, ";; got answer:\n")); +- +- DprintQ((statp->options & RES_DEBUG) || +- (statp->pfcode & RES_PRF_REPLY), +- (stdout, "%s", ""), +- ans, (resplen > anssiz) ? anssiz : resplen); +- if (buf2 != NULL) { +- DprintQ((statp->options & RES_DEBUG) || +- (statp->pfcode & RES_PRF_REPLY), +- (stdout, "%s", ""), +- *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2); +- } +- + /* + * If we have temporarily opened a virtual circuit, + * or if we haven't been asked to keep a socket open, +@@ -614,38 +530,6 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, + (statp->options & RES_STAYOPEN) == 0) { + __res_iclose(statp, false); + } +-#ifdef USE_HOOKS +- if (__builtin_expect (statp->rhook, 0)) { +- int done = 0, loops = 0; +- +- do { +- res_sendhookact act; +- +- act = (*statp->rhook)((struct sockaddr_in *) +- nsap, buf, buflen, +- ans, anssiz, &resplen); +- switch (act) { +- case res_goahead: +- case res_done: +- done = 1; +- break; +- case res_nextns: +- __res_iclose(statp, false); +- goto next_ns; +- case res_modified: +- /* give the hook another try */ +- if (++loops < 42) /*doug adams*/ +- break; +- /*FALLTHROUGH*/ +- case res_error: +- /*FALLTHROUGH*/ +- default: +- return (-1); +- } +- } while (!done); +- +- } +-#endif + return (resplen); + next_ns: ; + } /*foreach ns*/ +@@ -661,17 +545,56 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, + return (-1); + } + ++/* Common part of res_nsend and res_send. */ ++static int ++context_send_common (struct resolv_context *ctx, ++ const unsigned char *buf, int buflen, ++ unsigned char *ans, int anssiz) ++{ ++ if (ctx == NULL) ++ { ++ RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); ++ return -1; ++ } ++ int result = __res_context_send (ctx, buf, buflen, NULL, 0, ans, anssiz, ++ NULL, NULL, NULL, NULL, NULL); ++ __resolv_context_put (ctx); ++ return result; ++} ++ ++int ++res_nsend (res_state statp, const unsigned char *buf, int buflen, ++ unsigned char *ans, int anssiz) ++{ ++ return context_send_common ++ (__resolv_context_get_override (statp), buf, buflen, ans, anssiz); ++} ++ + int +-res_nsend(res_state statp, +- const u_char *buf, int buflen, u_char *ans, int anssiz) ++res_send (const unsigned char *buf, int buflen, unsigned char *ans, int anssiz) + { +- return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz, +- NULL, NULL, NULL, NULL, NULL); ++ return context_send_common ++ (__resolv_context_get (), buf, buflen, ans, anssiz); + } +-libresolv_hidden_def (res_nsend) + + /* Private */ + ++static struct sockaddr * ++get_nsaddr (res_state statp, unsigned int n) ++{ ++ assert (n < statp->nscount); ++ ++ if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL) ++ /* EXT(statp).nsaddrs[n] holds an address that is larger than ++ struct sockaddr, and user code did not update ++ statp->nsaddr_list[n]. */ ++ return (struct sockaddr *) EXT(statp).nsaddrs[n]; ++ else ++ /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n] ++ has the same content as EXT(statp).nsaddrs[n]. */ ++ return (struct sockaddr *) (void *) &statp->nsaddr_list[n]; ++} ++ + /* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2 + is not NULL, and return zero. */ + static int +@@ -692,7 +615,7 @@ close_and_return_error (res_state statp, int *resplen2) + Please note that for TCP there is no way to disable sending both + queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP + and sends the queries serially and waits for the result after each +- sent query. This implemetnation should be corrected to honour these ++ sent query. This implementation should be corrected to honour these + options. + + Please also note that for TCP we send both queries over the same +@@ -722,7 +645,7 @@ close_and_return_error (res_state statp, int *resplen2) + are needed but ANSCP is NULL, then as much of the response as + possible is read into the buffer, but the results will be truncated. + When truncation happens because of a small answer buffer the DNS +- packets header feild TC will bet set to 1, indicating a truncated ++ packets header field TC will bet set to 1, indicating a truncated + message and the rest of the socket data will be read and discarded. + + Answers to the query are stored secondly in *ANSP2 up to a max of +@@ -765,15 +688,26 @@ send_vc(res_state statp, + const HEADER *hp = (HEADER *) buf; + const HEADER *hp2 = (HEADER *) buf2; + HEADER *anhp = (HEADER *) *ansp; +- struct sockaddr_in6 *nsap = EXT(statp).nsaddrs[ns]; +- int truncating, connreset, resplen, n; ++ struct sockaddr *nsap = get_nsaddr (statp, ns); ++ int truncating, connreset, n; ++ /* On some architectures compiler might emit a warning indicating ++ 'resplen' may be used uninitialized. However if buf2 == NULL ++ then this code won't be executed; if buf2 != NULL, then first ++ time round the loop recvresp1 and recvresp2 will be 0 so this ++ code won't be executed but "thisresplenp = &resplen;" followed ++ by "*thisresplenp = rlen;" will be executed so that subsequent ++ times round the loop resplen has been initialized. So this is ++ a false-positive. ++ */ ++ DIAG_PUSH_NEEDS_COMMENT; ++ DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); ++ int resplen; ++ DIAG_POP_NEEDS_COMMENT; + struct iovec iov[4]; + u_short len; + u_short len2; + u_char *cp; + +- if (resplen2 != NULL) +- *resplen2 = 0; + connreset = 0; + same_ns: + truncating = 0; +@@ -785,8 +719,8 @@ send_vc(res_state statp, + + if (getpeername(statp->_vcsock, + (struct sockaddr *)&peer, &size) < 0 || +- !sock_eq(&peer, nsap)) { +- __res_iclose(statp, false); ++ !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) { ++ __res_iclose(statp, false); + statp->_flags &= ~RES_F_VC; + } + } +@@ -795,22 +729,21 @@ send_vc(res_state statp, + if (statp->_vcsock >= 0) + __res_iclose(statp, false); + +- statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0); ++ statp->_vcsock = socket ++ (nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (statp->_vcsock < 0) { + *terrno = errno; +- Perror(statp, stderr, "socket(vc)", errno); ++ if (resplen2 != NULL) ++ *resplen2 = 0; + return (-1); + } + __set_errno (0); +- if (connect(statp->_vcsock, (struct sockaddr *)nsap, +- nsap->sin6_family == AF_INET ++ if (connect(statp->_vcsock, nsap, ++ nsap->sa_family == AF_INET + ? sizeof (struct sockaddr_in) + : sizeof (struct sockaddr_in6)) < 0) { + *terrno = errno; +- Aerror(statp, stderr, "connect/vc", errno, +- (struct sockaddr *) nsap); +- __res_iclose(statp, false); +- return (0); ++ return close_and_return_error (statp, resplen2); + } + statp->_flags |= RES_F_VC; + } +@@ -832,16 +765,14 @@ send_vc(res_state statp, + } + if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) { + *terrno = errno; +- Perror(statp, stderr, "write failed", errno); +- __res_iclose(statp, false); +- return (0); ++ return close_and_return_error (statp, resplen2); + } + /* + * Receive length & response + */ + int recvresp1 = 0; + /* Skip the second response if there is no second query. +- To do that we mark the second response as received. */ ++ To do that we mark the second response as received. */ + int recvresp2 = buf2 == NULL; + uint16_t rlen16; + read_len: +@@ -855,8 +786,6 @@ send_vc(res_state statp, + } + if (n <= 0) { + *terrno = errno; +- Perror(statp, stderr, "read failed", errno); +- __res_iclose(statp, false); + /* + * A long running process might get its TCP + * connection reset if the remote server was +@@ -866,11 +795,13 @@ send_vc(res_state statp, + * instead of failing. We only allow one reset + * per query to prevent looping. + */ +- if (*terrno == ECONNRESET && !connreset) { +- connreset = 1; +- goto same_ns; +- } +- return (0); ++ if (*terrno == ECONNRESET && !connreset) ++ { ++ __res_iclose (statp, false); ++ connreset = 1; ++ goto same_ns; ++ } ++ return close_and_return_error (statp, resplen2); + } + int rlen = ntohs (rlen16); + +@@ -895,18 +826,18 @@ send_vc(res_state statp, + *thisresplenp = rlen; + /* Is the answer buffer too small? */ + if (*thisanssizp < rlen) { +- /* If the current buffer is non-NULL and it's not +- pointing at the static user-supplied buffer then +- we can reallocate it. */ ++ /* If the current buffer is not the the static ++ user-supplied buffer then we can reallocate ++ it. */ + if (thisansp != NULL && thisansp != ansp) { + /* Always allocate MAXPACKET, callers expect + this specific size. */ + u_char *newp = malloc (MAXPACKET); +- if (newp == NULL) { +- *terrno = ENOMEM; +- __res_iclose(statp, false); +- return (0); +- } ++ if (newp == NULL) ++ { ++ *terrno = ENOMEM; ++ return close_and_return_error (statp, resplen2); ++ } + *thisanssizp = MAXPACKET; + *thisansp = newp; + if (thisansp == ansp2) +@@ -917,24 +848,18 @@ send_vc(res_state statp, + read RLEN bytes instead. */ + len = rlen; + } else { +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; response truncated\n") +- ); + truncating = 1; + len = *thisanssizp; + } + } else + len = rlen; + +- if (__builtin_expect (len < HFIXEDSZ, 0)) { ++ if (__glibc_unlikely (len < HFIXEDSZ)) { + /* + * Undersized message. + */ +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; undersized: %d\n", len)); + *terrno = EMSGSIZE; +- __res_iclose(statp, false); +- return (0); ++ return close_and_return_error (statp, resplen2); + } + + cp = *thisansp; +@@ -942,13 +867,11 @@ send_vc(res_state statp, + cp += n; + len -= n; + } +- if (__builtin_expect (n <= 0, 0)) { ++ if (__glibc_unlikely (n <= 0)) { + *terrno = errno; +- Perror(statp, stderr, "read(vc)", errno); +- __res_iclose(statp, false); +- return (0); ++ return close_and_return_error (statp, resplen2); + } +- if (__builtin_expect (truncating, 0)) { ++ if (__glibc_unlikely (truncating)) { + /* + * Flush rest of answer so connection stays in synch. + */ +@@ -966,21 +889,15 @@ send_vc(res_state statp, + } + } + /* +- * If the calling applicating has bailed out of ++ * If the calling application has bailed out of + * a previous call and failed to arrange to have + * the circuit closed or the server has got + * itself confused, then drop the packet and + * wait for the correct one. + */ + if ((recvresp1 || hp->id != anhp->id) +- && (recvresp2 || hp2->id != anhp->id)) { +- DprintQ((statp->options & RES_DEBUG) || +- (statp->pfcode & RES_PRF_REPLY), +- (stdout, ";; old answer (unexpected):\n"), +- *thisansp, +- (rlen > *thisanssizp) ? *thisanssizp: rlen); ++ && (recvresp2 || hp2->id != anhp->id)) + goto read_len; +- } + + /* Mark which reply we received. */ + if (recvresp1 == 0 && hp->id == anhp->id) +@@ -1002,49 +919,25 @@ static int + reopen (res_state statp, int *terrno, int ns) + { + if (EXT(statp).nssocks[ns] == -1) { +- struct sockaddr *nsap +- = (struct sockaddr *) EXT(statp).nsaddrs[ns]; ++ struct sockaddr *nsap = get_nsaddr (statp, ns); + socklen_t slen; + + /* only try IPv6 if IPv6 NS and if not failed before */ + if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) { +- if (__builtin_expect (__have_o_nonblock >= 0, 1)) { +- EXT(statp).nssocks[ns] = +- socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, +- 0); +-#ifndef __ASSUME_SOCK_CLOEXEC +- if (__have_o_nonblock == 0) +- __have_o_nonblock +- = (EXT(statp).nssocks[ns] == -1 +- && errno == EINVAL ? -1 : 1); +-#endif +- } +- if (__builtin_expect (__have_o_nonblock < 0, 0)) +- EXT(statp).nssocks[ns] = +- socket(PF_INET6, SOCK_DGRAM, 0); ++ EXT(statp).nssocks[ns] = socket ++ (PF_INET6, ++ SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + if (EXT(statp).nssocks[ns] < 0) + statp->ipv6_unavail = errno == EAFNOSUPPORT; + slen = sizeof (struct sockaddr_in6); + } else if (nsap->sa_family == AF_INET) { +- if (__builtin_expect (__have_o_nonblock >= 0, 1)) { +- EXT(statp).nssocks[ns] +- = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, +- 0); +-#ifndef __ASSUME_SOCK_CLOEXEC +- if (__have_o_nonblock == 0) +- __have_o_nonblock +- = (EXT(statp).nssocks[ns] == -1 +- && errno == EINVAL ? -1 : 1); +-#endif +- } +- if (__builtin_expect (__have_o_nonblock < 0, 0)) +- EXT(statp).nssocks[ns] +- = socket(PF_INET, SOCK_DGRAM, 0); ++ EXT(statp).nssocks[ns] = socket ++ (PF_INET, ++ SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + slen = sizeof (struct sockaddr_in); + } + if (EXT(statp).nssocks[ns] < 0) { + *terrno = errno; +- Perror(statp, stderr, "socket(dg)", errno); + return (-1); + } + +@@ -1059,20 +952,19 @@ reopen (res_state statp, int *terrno, int ns) + * error message is received. We can thus detect + * the absence of a nameserver without timing out. + */ ++ /* With GCC 5.3 when compiling with -Os the compiler ++ emits a warning that slen may be used uninitialized, ++ but that is never true. Both slen and ++ EXT(statp).nssocks[ns] are initialized together or ++ the function return -1 before control flow reaches ++ the call to connect with slen. */ ++ DIAG_PUSH_NEEDS_COMMENT; ++ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); + if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) { +- Aerror(statp, stderr, "connect(dg)", errno, nsap); ++ DIAG_POP_NEEDS_COMMENT; + __res_iclose(statp, false); + return (0); + } +- if (__builtin_expect (__have_o_nonblock < 0, 0)) { +- /* Make socket non-blocking. */ +- int fl = __fcntl (EXT(statp).nssocks[ns], F_GETFL); +- if (fl != -1) +- __fcntl (EXT(statp).nssocks[ns], F_SETFL, +- fl | O_NONBLOCK); +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; new DG socket\n")) +- } + } + + return 1; +@@ -1098,7 +990,7 @@ reopen (res_state statp, int *terrno, int ns) + are needed but ANSCP is NULL, then as much of the response as + possible is read into the buffer, but the results will be truncated. + When truncation happens because of a small answer buffer the DNS +- packets header feild TC will bet set to 1, indicating a truncated ++ packets header field TC will bet set to 1, indicating a truncated + message, while the rest of the UDP packet is discarded. + + Answers to the query are stored secondly in *ANSP2 up to a max of +@@ -1184,7 +1076,7 @@ send_dg(res_state statp, + int nwritten = 0; + int recvresp1 = 0; + /* Skip the second response if there is no second query. +- To do that we mark the second response as received. */ ++ To do that we mark the second response as received. */ + int recvresp2 = buf2 == NULL; + pfd[0].fd = EXT(statp).nssocks[ns]; + pfd[0].events = POLLOUT; +@@ -1194,7 +1086,6 @@ send_dg(res_state statp, + evNowTime(&now); + if (evCmpTime(finish, now) <= 0) { + poll_err_out: +- Perror(statp, stderr, "poll", errno); + return close_and_return_error (statp, resplen2); + } + evSubTime(&timeout, &finish, &now); +@@ -1206,12 +1097,11 @@ send_dg(res_state statp, + n = 0; + if (nwritten == 0) + n = __poll (pfd, 1, 0); +- if (__builtin_expect (n == 0, 0)) { ++ if (__glibc_unlikely (n == 0)) { + n = __poll (pfd, 1, ptimeout); + need_recompute = 1; + } + if (n == 0) { +- Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); + if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2))) + { + /* There are quite a few broken name servers out +@@ -1283,7 +1173,7 @@ send_dg(res_state statp, + reqs[1].msg_hdr.msg_controllen = 0; + + int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL); +- if (__builtin_expect (ndg == 2, 1)) ++ if (__glibc_likely (ndg == 2)) + { + if (reqs[0].msg_len != buflen + || reqs[1].msg_len != buflen2) +@@ -1299,7 +1189,7 @@ send_dg(res_state statp, + else + { + #ifndef __ASSUME_SENDMMSG +- if (__builtin_expect (have_sendmmsg == 0, 0)) ++ if (__glibc_unlikely (have_sendmmsg == 0)) + { + if (ndg < 0 && errno == ENOSYS) + { +@@ -1311,7 +1201,6 @@ send_dg(res_state statp, + #endif + + fail_sendmmsg: +- Perror(statp, stderr, "sendmmsg", errno); + return close_and_return_error (statp, resplen2); + } + } +@@ -1329,7 +1218,6 @@ send_dg(res_state statp, + if (sr != (nwritten != 0 ? buflen2 : buflen)) { + if (errno == EINTR || errno == EAGAIN) + goto recompute_resend; +- Perror(statp, stderr, "send", errno); + return close_and_return_error (statp, resplen2); + } + just_one: +@@ -1360,14 +1248,16 @@ send_dg(res_state statp, + } + + if (*thisanssizp < MAXPACKET +- /* If the current buffer is non-NULL and it's not +- pointing at the static user-supplied buffer then +- we can reallocate it. */ ++ /* If the current buffer is not the the static ++ user-supplied buffer then we can reallocate ++ it. */ + && (thisansp != NULL && thisansp != ansp) ++#ifdef FIONREAD + /* Is the size too small? */ + && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0 + || *thisanssizp < *thisresplenp) +- ) { ++#endif ++ ) { + /* Always allocate MAXPACKET, callers expect + this specific size. */ + u_char *newp = malloc (MAXPACKET); +@@ -1388,34 +1278,24 @@ send_dg(res_state statp, + MSG_TRUNC which is only available on Linux. We + can abstract out the Linux-specific feature in the + future to detect truncation. */ +- if (__glibc_unlikely (*thisanssizp < *thisresplenp)) { +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; response may be truncated (UDP)\n") +- ); +- } +- + HEADER *anhp = (HEADER *) *thisansp; + socklen_t fromlen = sizeof(struct sockaddr_in6); + assert (sizeof(from) <= fromlen); + *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp, + *thisanssizp, 0, + (struct sockaddr *)&from, &fromlen); +- if (__builtin_expect (*thisresplenp <= 0, 0)) { ++ if (__glibc_unlikely (*thisresplenp <= 0)) { + if (errno == EINTR || errno == EAGAIN) { + need_recompute = 1; + goto wait; + } +- Perror(statp, stderr, "recvfrom", errno); + return close_and_return_error (statp, resplen2); + } + *gotsomewhere = 1; +- if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) { ++ if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) { + /* + * Undersized message. + */ +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; undersized: %d\n", +- *thisresplenp)); + *terrno = EMSGSIZE; + return close_and_return_error (statp, resplen2); + } +@@ -1426,12 +1306,6 @@ send_dg(res_state statp, + * XXX - potential security hazard could + * be detected here. + */ +- DprintQ((statp->options & RES_DEBUG) || +- (statp->pfcode & RES_PRF_REPLY), +- (stdout, ";; old answer:\n"), +- *thisansp, +- (*thisresplenp > *thisanssizp) +- ? *thisanssizp : *thisresplenp); + goto wait; + } + if (!(statp->options & RES_INSECURE1) && +@@ -1441,34 +1315,8 @@ send_dg(res_state statp, + * XXX - potential security hazard could + * be detected here. + */ +- DprintQ((statp->options & RES_DEBUG) || +- (statp->pfcode & RES_PRF_REPLY), +- (stdout, ";; not our server:\n"), +- *thisansp, +- (*thisresplenp > *thisanssizp) +- ? *thisanssizp : *thisresplenp); + goto wait; + } +-#ifdef RES_USE_EDNS0 +- if (anhp->rcode == FORMERR +- && (statp->options & RES_USE_EDNS0) != 0U) { +- /* +- * Do not retry if the server does not understand +- * EDNS0. The case has to be captured here, as +- * FORMERR packet do not carry query section, hence +- * res_queriesmatch() returns 0. +- */ +- DprintQ(statp->options & RES_DEBUG, +- (stdout, +- "server rejected query with EDNS0:\n"), +- *thisansp, +- (*thisresplenp > *thisanssizp) +- ? *thisanssizp : *thisresplenp); +- /* record the error */ +- statp->_flags |= RES_F_EDNS0ERR; +- return close_and_return_error (statp, resplen2); +- } +-#endif + if (!(statp->options & RES_INSECURE2) + && (recvresp1 || !res_queriesmatch(buf, buf + buflen, + *thisansp, +@@ -1483,23 +1331,11 @@ send_dg(res_state statp, + * XXX - potential security hazard could + * be detected here. + */ +- DprintQ((statp->options & RES_DEBUG) || +- (statp->pfcode & RES_PRF_REPLY), +- (stdout, ";; wrong query name:\n"), +- *thisansp, +- (*thisresplenp > *thisanssizp) +- ? *thisanssizp : *thisresplenp); + goto wait; + } + if (anhp->rcode == SERVFAIL || + anhp->rcode == NOTIMP || + anhp->rcode == REFUSED) { +- DprintQ(statp->options & RES_DEBUG, +- (stdout, "server rejected query:\n"), +- *thisansp, +- (*thisresplenp > *thisanssizp) +- ? *thisanssizp : *thisresplenp); +- + next_ns: + if (recvresp1 || (buf2 != NULL && recvresp2)) { + *resplen2 = 0; +@@ -1525,11 +1361,6 @@ send_dg(res_state statp, + } + if (anhp->rcode == NOERROR && anhp->ancount == 0 + && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) { +- DprintQ(statp->options & RES_DEBUG, +- (stdout, "referred query:\n"), +- *thisansp, +- (*thisresplenp > *thisanssizp) +- ? *thisanssizp : *thisresplenp); + goto next_ns; + } + if (!(statp->options & RES_IGNTC) && anhp->tc) { +@@ -1537,8 +1368,6 @@ send_dg(res_state statp, + * To get the rest of answer, + * use TCP with same server. + */ +- Dprint(statp->options & RES_DEBUG, +- (stdout, ";; truncated answer\n")); + *v_circuit = 1; + __res_iclose(statp, false); + // XXX if we have received one reply we could +@@ -1582,46 +1411,6 @@ send_dg(res_state statp, + } + } + +-#ifdef DEBUG +-static void +-Aerror(const res_state statp, FILE *file, const char *string, int error, +- const struct sockaddr *address) +-{ +- int save = errno; +- +- if ((statp->options & RES_DEBUG) != 0) { +- char tmp[sizeof "xxxx.xxxx.xxxx.255.255.255.255"]; +- +- fprintf(file, "res_send: %s ([%s].%u): %s\n", +- string, +- (address->sa_family == AF_INET +- ? inet_ntop(address->sa_family, +- &((const struct sockaddr_in *) address)->sin_addr, +- tmp, sizeof tmp) +- : inet_ntop(address->sa_family, +- &((const struct sockaddr_in6 *) address)->sin6_addr, +- tmp, sizeof tmp)), +- (address->sa_family == AF_INET +- ? ntohs(((struct sockaddr_in *) address)->sin_port) +- : address->sa_family == AF_INET6 +- ? ntohs(((struct sockaddr_in6 *) address)->sin6_port) +- : 0), +- strerror(error)); +- } +- __set_errno (save); +-} +- +-static void +-Perror(const res_state statp, FILE *file, const char *string, int error) { +- int save = errno; +- +- if ((statp->options & RES_DEBUG) != 0) +- fprintf(file, "res_send: %s: %s\n", +- string, strerror(error)); +- __set_errno (save); +-} +-#endif +- + static int + sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) { + if (a1->sin6_family == a2->sin6_family) { +diff --git a/resolv/res_use_inet6.h b/resolv/res_use_inet6.h +new file mode 100644 +index 0000000000000000..8649833072ade9cf +--- /dev/null ++++ b/resolv/res_use_inet6.h +@@ -0,0 +1,49 @@ ++/* Support functions for handling RES_USE_INET6 in getaddrinfo/nscd. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _RES_USE_INET6_H ++#define _RES_USE_INET6_H ++ ++#include ++#include ++ ++/* Ensure that RES_USE_INET6 is disabled in *CTX. Return true if ++ __resolv_context_enable_inet6 below should enable RES_USE_INET6 ++ again. */ ++static inline bool ++__resolv_context_disable_inet6 (struct resolv_context *ctx) ++{ ++ if (ctx != NULL && ctx->resp->options & DEPRECATED_RES_USE_INET6) ++ { ++ ctx->resp->options &= ~DEPRECATED_RES_USE_INET6; ++ return true; ++ } ++ else ++ return false; ++} ++ ++/* If ENABLE, re-enable RES_USE_INET6 in *CTX. To be paired with ++ __resolv_context_disable_inet6. */ ++static inline void ++__resolv_context_enable_inet6 (struct resolv_context *ctx, bool enable) ++{ ++ if (ctx != NULL && enable) ++ ctx->resp->options |= DEPRECATED_RES_USE_INET6; ++} ++ ++#endif +diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h +index a9f5659dbbacb477..32dc44777e311849 100644 +--- a/resolv/resolv-internal.h ++++ b/resolv/resolv-internal.h +@@ -1,5 +1,5 @@ + /* libresolv interfaces for internal use across glibc. +- Copyright (C) 2016 Free Software Foundation, Inc. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -22,6 +22,12 @@ + #include + #include + ++/* Resolver flags. Used for _flags in struct __res_state. */ ++#define RES_F_VC 0x00000001 /* Socket is TCP. */ ++#define RES_F_CONN 0x00000002 /* Socket is connected. */ ++#define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors. */ ++ ++ + /* Internal version of RES_USE_INET6 which does not trigger a + deprecation warning. */ + #define DEPRECATED_RES_USE_INET6 0x00002000 +@@ -32,6 +38,56 @@ res_use_inet6 (void) + return _res.options & DEPRECATED_RES_USE_INET6; + } + ++enum ++ { ++ /* The advertized EDNS buffer size. The value 1200 is derived ++ from the IPv6 minimum MTU (1280 bytes) minus some arbitrary ++ space for tunneling overhead. If the DNS server does not react ++ to ICMP Fragmentation Needed But DF Set messages, this should ++ avoid all UDP fragments on current networks. Avoiding UDP ++ fragments is desirable because it prevents fragmentation-based ++ spoofing attacks because the randomness in a DNS packet is ++ concentrated in the first fragment (with the headers) and does ++ not protect subsequent fragments. */ ++ RESOLV_EDNS_BUFFER_SIZE = 1200, ++ }; ++ ++struct resolv_context; ++ ++/* Internal function for implementing res_nmkquery and res_mkquery. ++ Also used by __res_context_query. */ ++int __res_context_mkquery (struct resolv_context *, int op, const char *dname, ++ int class, int type, const unsigned char *data, ++ unsigned char *buf, int buflen) attribute_hidden; ++ ++/* Main resolver query function for use within glibc. */ ++int __res_context_search (struct resolv_context *, const char *, int, int, ++ unsigned char *, int, unsigned char **, ++ unsigned char **, int *, int *, int *); ++libresolv_hidden_proto (__res_context_search) ++ ++/* Main resolver query function for use within glibc. */ ++int __res_context_query (struct resolv_context *, const char *, int, int, ++ unsigned char *, int, unsigned char **, ++ unsigned char **, int *, int *, int *); ++libresolv_hidden_proto (__res_context_query) ++ ++/* Internal function used to implement the query and search ++ functions. */ ++int __res_context_send (struct resolv_context *, const unsigned char *, int, ++ const unsigned char *, int, unsigned char *, ++ int, unsigned char **, unsigned char **, ++ int *, int *, int *) attribute_hidden; ++ ++/* Internal function similar to res_hostalias. */ ++const char *__res_context_hostalias (struct resolv_context *, ++ const char *, char *, size_t); ++libresolv_hidden_proto (__res_context_hostalias); ++ ++/* Add an OPT record to a DNS query. */ ++int __res_nopt (struct resolv_context *, int n0, ++ unsigned char *buf, int buflen, int anslen) attribute_hidden; ++ + /* Convert from presentation format (which usually means ASCII + printable) to network format (which is usually some kind of binary + format). The input is in the range [SRC, SRC + SRCLEN). The +diff --git a/resolv/resolv.h b/resolv/resolv.h +index ed15a702bf3bb9e8..7d85cbd011acf669 100644 +--- a/resolv/resolv.h ++++ b/resolv/resolv.h +@@ -123,8 +123,8 @@ struct __res_state { + u_int32_t mask; + } sort_list[MAXRESOLVSORT]; + /* 4 byte hole here on 64-bit architectures. */ +- res_send_qhook qhook; /* query hook */ +- res_send_rhook rhook; /* response hook */ ++ res_send_qhook __glibc_unused_qhook; ++ res_send_rhook __glibc_unused_rhook; + int res_h_errno; /* last one set for this context */ + int _vcsock; /* PRIVATE: for res_send VC i/o */ + u_int _flags; /* PRIVATE: see below */ +@@ -139,10 +139,10 @@ struct __res_state { + u_int16_t nsinit; + struct sockaddr_in6 *nsaddrs[MAXNS]; + #ifdef _LIBC +- unsigned long long int initstamp ++ unsigned long long int __glibc_extension_index + __attribute__((packed)); + #else +- unsigned int _initstamp[2]; ++ unsigned int __glibc_reserved[2]; + #endif + } _ext; + } _u; +@@ -221,6 +221,7 @@ struct res_sym { + #define RES_USE_DNSSEC 0x00800000 /* use DNSSEC using OK bit in OPT */ + #define RES_NOTLDQUERY 0x01000000 /* Do not look up unqualified name + as a TLD. */ ++#define RES_NORELOAD 0x02000000 /* No automatic configuration reload. */ + + #define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT) + +@@ -250,7 +251,6 @@ extern struct __res_state *__res_state(void) __attribute__ ((__const__)); + __END_DECLS + #define _res (*__res_state()) + +-#ifndef __BIND_NOSTATIC + #define fp_nquery __fp_nquery + #define fp_query __fp_query + #define hostalias __hostalias +@@ -265,22 +265,25 @@ __END_DECLS + #define res_send __res_send + + __BEGIN_DECLS +-void fp_nquery (const u_char *, int, FILE *) __THROW; +-void fp_query (const u_char *, FILE *) __THROW; ++void fp_nquery (const unsigned char *, int, FILE *) __THROW; ++void fp_query (const unsigned char *, FILE *) __THROW; + const char * hostalias (const char *) __THROW; +-void p_query (const u_char *) __THROW; ++void p_query (const unsigned char *) __THROW; + void res_close (void) __THROW; + int res_init (void) __THROW; + int res_isourserver (const struct sockaddr_in *) __THROW; +-int res_mkquery (int, const char *, int, int, const u_char *, +- int, const u_char *, u_char *, int) __THROW; +-int res_query (const char *, int, int, u_char *, int) __THROW; ++int res_mkquery (int, const char *, int, int, ++ const unsigned char *, int, const unsigned char *, ++ unsigned char *, int) __THROW; ++int res_query (const char *, int, int, unsigned char *, int) ++ __THROW; + int res_querydomain (const char *, const char *, int, int, +- u_char *, int) __THROW; +-int res_search (const char *, int, int, u_char *, int) __THROW; +-int res_send (const u_char *, int, u_char *, int) __THROW; ++ unsigned char *, int) __THROW; ++int res_search (const char *, int, int, unsigned char *, int) ++ __THROW; ++int res_send (const unsigned char *, int, unsigned char *, int) ++ __THROW; + __END_DECLS +-#endif + + #define b64_ntop __b64_ntop + #define b64_pton __b64_pton +@@ -298,7 +301,6 @@ __END_DECLS + #define p_fqnname __p_fqnname + #define p_option __p_option + #define p_secstodate __p_secstodate +-#define p_section __p_section + #define p_time __p_time + #define p_type __p_type + #define p_rcode __p_rcode +@@ -312,12 +314,10 @@ __END_DECLS + #define res_nclose __res_nclose + #define res_ninit __res_ninit + #define res_nmkquery __res_nmkquery +-#define res_npquery __res_npquery + #define res_nquery __res_nquery + #define res_nquerydomain __res_nquerydomain + #define res_nsearch __res_nsearch + #define res_nsend __res_nsend +-#define res_nisourserver __res_nisourserver + #define res_ownok __res_ownok + #define res_queriesmatch __res_queriesmatch + #define res_randomid __res_randomid +@@ -332,57 +332,62 @@ int res_dnok (const char *) __THROW; + int sym_ston (const struct res_sym *, const char *, int *) __THROW; + const char * sym_ntos (const struct res_sym *, int, int *) __THROW; + const char * sym_ntop (const struct res_sym *, int, int *) __THROW; +-int b64_ntop (u_char const *, size_t, char *, size_t) __THROW; +-int b64_pton (char const *, u_char *, size_t) __THROW; +-int loc_aton (const char *__ascii, u_char *__binary) __THROW; +-const char * loc_ntoa (const u_char *__binary, char *__ascii) __THROW; +-int dn_skipname (const u_char *, const u_char *) __THROW; +-void putlong (u_int32_t, u_char *) __THROW; +-void putshort (u_int16_t, u_char *) __THROW; ++int b64_ntop (const unsigned char *, size_t, char *, size_t) ++ __THROW; ++int b64_pton (char const *, unsigned char *, size_t) __THROW; ++int loc_aton (const char *__ascii, unsigned char *__binary) __THROW; ++const char * loc_ntoa (const unsigned char *__binary, char *__ascii) __THROW; ++int dn_skipname (const unsigned char *, const unsigned char *) ++ __THROW; ++void putlong (uint32_t, unsigned char *) __THROW; ++void putshort (uint16_t, unsigned char *) __THROW; + const char * p_class (int) __THROW; +-const char * p_time (u_int32_t) __THROW; ++const char * p_time (uint32_t) __THROW; + const char * p_type (int) __THROW; + const char * p_rcode (int) __THROW; +-const u_char * p_cdnname (const u_char *, const u_char *, int, FILE *) +- __THROW; +-const u_char * p_cdname (const u_char *, const u_char *, FILE *) __THROW; +-const u_char * p_fqnname (const u_char *__cp, const u_char *__msg, +- int, char *, int) __THROW; +-const u_char * p_fqname (const u_char *, const u_char *, FILE *) __THROW; +-const char * p_option (u_long __option) __THROW; +-char * p_secstodate (u_long) __THROW; ++const unsigned char * p_cdnname (const unsigned char *, ++ const unsigned char *, int, FILE *) __THROW; ++const unsigned char * p_cdname (const unsigned char *, const unsigned char *, ++ FILE *) __THROW; ++const unsigned char * p_fqnname (const unsigned char *__cp, ++ const unsigned char *__msg, ++ int, char *, int) __THROW; ++const unsigned char * p_fqname (const unsigned char *, ++ const unsigned char *, FILE *) __THROW; ++const char * p_option (unsigned long __option) __THROW; ++char * p_secstodate (unsigned long) __THROW; + int dn_count_labels (const char *) __THROW; +-int dn_comp (const char *, u_char *, int, u_char **, u_char **) +- __THROW; +-int dn_expand (const u_char *, const u_char *, const u_char *, +- char *, int) __THROW; +-u_int res_randomid (void) __THROW; ++int dn_comp (const char *, unsigned char *, int, unsigned char **, ++ unsigned char **) __THROW; ++int dn_expand (const unsigned char *, const unsigned char *, ++ const unsigned char *, char *, int) __THROW; ++unsigned int res_randomid (void) __THROW; + int res_nameinquery (const char *, int, int, +- const u_char *, const u_char *) __THROW; +-int res_queriesmatch (const u_char *, const u_char *, +- const u_char *, const u_char *) __THROW; +-const char * p_section (int __section, int __opcode) __THROW; ++ const unsigned char *, ++ const unsigned char *) __THROW; ++int res_queriesmatch (const unsigned char *, ++ const unsigned char *, ++ const unsigned char *, ++ const unsigned char *) __THROW; + /* Things involving a resolver context. */ + int res_ninit (res_state) __THROW; +-int res_nisourserver (const res_state, +- const struct sockaddr_in *) __THROW; + void fp_resstat (const res_state, FILE *) __THROW; +-void res_npquery (const res_state, const u_char *, int, FILE *) +- __THROW; + const char * res_hostalias (const res_state, const char *, char *, size_t) + __THROW; +-int res_nquery (res_state, const char *, int, int, u_char *, int) +- __THROW; +-int res_nsearch (res_state, const char *, int, int, u_char *, int) +- __THROW; ++int res_nquery (res_state, const char *, int, int, ++ unsigned char *, int) __THROW; ++int res_nsearch (res_state, const char *, int, int, ++ unsigned char *, int) __THROW; + int res_nquerydomain (res_state, const char *, const char *, int, +- int, u_char *, int) __THROW; ++ int, unsigned char *, int) __THROW; + int res_nmkquery (res_state, int, const char *, int, int, +- const u_char *, int, const u_char *, u_char *, +- int) __THROW; +-int res_nsend (res_state, const u_char *, int, u_char *, int) ++ const unsigned char *, int, ++ const unsigned char *, unsigned char *, int) + __THROW; ++int res_nsend (res_state, const unsigned char *, int, ++ unsigned char *, int) __THROW; + void res_nclose (res_state) __THROW; ++ + __END_DECLS + #endif + +diff --git a/resolv/resolv_conf.c b/resolv/resolv_conf.c +new file mode 100644 +index 0000000000000000..e0f296d02e061a89 +--- /dev/null ++++ b/resolv/resolv_conf.c +@@ -0,0 +1,701 @@ ++/* Extended resolver state separate from struct __res_state. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* _res._u._ext.__glibc_extension_index is used as an index into a ++ struct resolv_conf_array object. The intent of this construction ++ is to make reasonably sure that even if struct __res_state objects ++ are copied around and patched by applications, we can still detect ++ accesses to stale extended resolver state. The array elements are ++ either struct resolv_conf * pointers (if the LSB is cleared) or ++ free list entries (if the LSB is set). The free list is used to ++ speed up finding available entries in the array. */ ++#define DYNARRAY_STRUCT resolv_conf_array ++#define DYNARRAY_ELEMENT uintptr_t ++#define DYNARRAY_PREFIX resolv_conf_array_ ++#define DYNARRAY_INITIAL_SIZE 0 ++#include ++ ++/* A magic constant for XORing the extension index ++ (_res._u._ext.__glibc_extension_index). This makes it less likely ++ that a valid index is created by accident. In particular, a zero ++ value leads to an invalid index. */ ++#define INDEX_MAGIC 0x26a8fa5e48af8061ULL ++ ++/* Global resolv.conf-related state. */ ++struct resolv_conf_global ++{ ++ /* struct __res_state objects contain the extension index ++ (_res._u._ext.__glibc_extension_index ^ INDEX_MAGIC), which ++ refers to an element of this array. When a struct resolv_conf ++ object (extended resolver state) is associated with a struct ++ __res_state object (legacy resolver state), its reference count ++ is increased and added to this array. Conversely, if the ++ extended state is detached from the basic state (during ++ reinitialization or deallocation), the index is decremented, and ++ the array element is overwritten with NULL. */ ++ struct resolv_conf_array array; ++ ++ /* Start of the free list in the array. Zero if the free list is ++ empty. Otherwise, free_list_start >> 1 is the first element of ++ the free list (and the free list entries all have their LSB set ++ and are shifted one to the left). */ ++ uintptr_t free_list_start; ++ ++ /* Cached current configuration object for /etc/resolv.conf. */ ++ struct resolv_conf *conf_current; ++ ++ /* These properties of /etc/resolv.conf are used to check if the ++ configuration needs reloading. */ ++ struct timespec conf_mtime; ++ struct timespec conf_ctime; ++ off64_t conf_size; ++ ino64_t conf_ino; ++}; ++ ++/* Lazily allocated storage for struct resolv_conf_global. */ ++static struct resolv_conf_global *global; ++ ++/* The lock synchronizes access to global and *global. It also ++ protects the __refcount member of struct resolv_conf. */ ++__libc_lock_define_initialized (static, lock); ++ ++/* Ensure that GLOBAL is allocated and lock it. Return NULL if ++ memory allocation failes. */ ++static struct resolv_conf_global * ++get_locked_global (void) ++{ ++ __libc_lock_lock (lock); ++ /* Use relaxed MO through because of load outside the lock in ++ __resolv_conf_detach. */ ++ struct resolv_conf_global *global_copy = atomic_load_relaxed (&global); ++ if (global_copy == NULL) ++ { ++ global_copy = calloc (1, sizeof (*global)); ++ if (global_copy == NULL) ++ return NULL; ++ atomic_store_relaxed (&global, global_copy); ++ resolv_conf_array_init (&global_copy->array); ++ } ++ return global_copy; ++} ++ ++/* Relinquish the lock acquired by get_locked_global. */ ++static void ++put_locked_global (struct resolv_conf_global *global_copy) ++{ ++ __libc_lock_unlock (lock); ++} ++ ++/* Decrement the reference counter. The caller must acquire the lock ++ around the function call. */ ++static void ++conf_decrement (struct resolv_conf *conf) ++{ ++ assert (conf->__refcount > 0); ++ if (--conf->__refcount == 0) ++ free (conf); ++} ++ ++struct resolv_conf * ++__resolv_conf_get_current (void) ++{ ++ struct stat64 st; ++ if (stat64 (_PATH_RESCONF, &st) != 0) ++ { ++ switch (errno) ++ { ++ case EACCES: ++ case EISDIR: ++ case ELOOP: ++ case ENOENT: ++ case ENOTDIR: ++ case EPERM: ++ /* Ignore errors due to file system contents. */ ++ memset (&st, 0, sizeof (st)); ++ break; ++ default: ++ /* Other errors are fatal. */ ++ return NULL; ++ } ++ } ++ ++ struct resolv_conf_global *global_copy = get_locked_global (); ++ if (global_copy == NULL) ++ return NULL; ++ struct resolv_conf *conf; ++ if (global_copy->conf_current != NULL ++ && (global_copy->conf_mtime.tv_sec == st.st_mtim.tv_sec ++ && global_copy->conf_mtime.tv_nsec == st.st_mtim.tv_nsec ++ && global_copy->conf_ctime.tv_sec == st.st_ctim.tv_sec ++ && global_copy->conf_ctime.tv_nsec == st.st_ctim.tv_nsec ++ && global_copy->conf_ino == st.st_ino ++ && global_copy->conf_size == st.st_size)) ++ /* We can reuse the cached configuration object. */ ++ conf = global_copy->conf_current; ++ else ++ { ++ /* Parse configuration while holding the lock. This avoids ++ duplicate work. */ ++ conf = __resolv_conf_load (NULL); ++ if (conf != NULL) ++ { ++ if (global_copy->conf_current != NULL) ++ conf_decrement (global_copy->conf_current); ++ global_copy->conf_current = conf; /* Takes ownership. */ ++ ++ /* Update file modification stamps. The configuration we ++ read could be a newer version of the file, but this does ++ not matter because this will lead to an extraneous reload ++ later. */ ++ global_copy->conf_mtime = st.st_mtim; ++ global_copy->conf_ctime = st.st_ctim; ++ global_copy->conf_ino = st.st_ino; ++ global_copy->conf_size = st.st_size; ++ } ++ } ++ ++ if (conf != NULL) ++ { ++ /* Return an additional reference. */ ++ assert (conf->__refcount > 0); ++ ++conf->__refcount; ++ assert (conf->__refcount > 0); ++ } ++ put_locked_global (global_copy); ++ return conf; ++} ++ ++/* Internal implementation of __resolv_conf_get, without validation ++ against *RESP. */ ++static struct resolv_conf * ++resolv_conf_get_1 (const struct __res_state *resp) ++{ ++ /* Not initialized, and therefore no assoicated context. */ ++ if (!(resp->options & RES_INIT)) ++ return NULL; ++ ++ struct resolv_conf_global *global_copy = get_locked_global (); ++ if (global_copy == NULL) ++ /* A memory allocation failure here means that no associated ++ contexts exists, so returning NULL is correct. */ ++ return NULL; ++ size_t index = resp->_u._ext.__glibc_extension_index ^ INDEX_MAGIC; ++ struct resolv_conf *conf = NULL; ++ if (index < resolv_conf_array_size (&global_copy->array)) ++ { ++ uintptr_t *slot = resolv_conf_array_at (&global_copy->array, index); ++ if (!(*slot & 1)) ++ { ++ conf = (struct resolv_conf *) *slot; ++ assert (conf->__refcount > 0); ++ ++conf->__refcount; ++ } ++ } ++ put_locked_global (global_copy); ++ return conf; ++} ++ ++/* Return true if both IPv4 addresses are equal. */ ++static bool ++same_address_v4 (const struct sockaddr_in *left, ++ const struct sockaddr_in *right) ++{ ++ return left->sin_addr.s_addr == right->sin_addr.s_addr ++ && left->sin_port == right->sin_port; ++} ++ ++/* Return true if both IPv6 addresses are equal. This ignores the ++ flow label. */ ++static bool ++same_address_v6 (const struct sockaddr_in6 *left, ++ const struct sockaddr_in6 *right) ++{ ++ return memcmp (&left->sin6_addr, &right->sin6_addr, ++ sizeof (left->sin6_addr)) == 0 ++ && left->sin6_port == right->sin6_port ++ && left->sin6_scope_id == right->sin6_scope_id; ++} ++ ++static bool ++same_address (const struct sockaddr *left, const struct sockaddr *right) ++{ ++ if (left->sa_family != right->sa_family) ++ return false; ++ switch (left->sa_family) ++ { ++ case AF_INET: ++ return same_address_v4 ((const struct sockaddr_in *) left, ++ (const struct sockaddr_in *) right); ++ case AF_INET6: ++ return same_address_v6 ((const struct sockaddr_in6 *) left, ++ (const struct sockaddr_in6 *) right); ++ } ++ return false; ++} ++ ++/* Check that *RESP and CONF match. Used by __resolv_conf_get. */ ++static bool ++resolv_conf_matches (const struct __res_state *resp, ++ const struct resolv_conf *conf) ++{ ++ /* NB: Do not compare the options, retrans, retry, ndots. These can ++ be changed by applicaiton. */ ++ ++ /* Check that the name servers in *RESP have not been modified by ++ the application. */ ++ { ++ size_t nserv = conf->nameserver_list_size; ++ if (nserv > MAXNS) ++ nserv = MAXNS; ++ /* _ext.nscount is 0 until initialized by res_send.c. */ ++ if (resp->nscount != nserv ++ || (resp->_u._ext.nscount != 0 && resp->_u._ext.nscount != nserv)) ++ return false; ++ for (size_t i = 0; i < nserv; ++i) ++ { ++ if (resp->nsaddr_list[i].sin_family == 0) ++ { ++ if (resp->_u._ext.nsaddrs[i]->sin6_family != AF_INET6) ++ return false; ++ if (!same_address ((struct sockaddr *) resp->_u._ext.nsaddrs[i], ++ conf->nameserver_list[i])) ++ return false; ++ } ++ else if (resp->nsaddr_list[i].sin_family != AF_INET) ++ return false; ++ else if (!same_address ((struct sockaddr *) &resp->nsaddr_list[i], ++ conf->nameserver_list[i])) ++ return false; ++ } ++ } ++ ++ /* Check that the search list in *RESP has not been modified by the ++ application. */ ++ { ++ if (resp->dnsrch[0] == NULL) ++ { ++ /* Empty search list. No default domain name. */ ++ return conf->search_list_size == 0 && resp->defdname[0] == '\0'; ++ } ++ ++ if (resp->dnsrch[0] != resp->defdname) ++ /* If the search list is not empty, it must start with the ++ default domain name. */ ++ return false; ++ ++ size_t nsearch; ++ for (nsearch = 0; nsearch < MAXDNSRCH; ++nsearch) ++ if (resp->dnsrch[nsearch] == NULL) ++ break; ++ if (nsearch > MAXDNSRCH) ++ /* Search list is not null-terminated. */ ++ return false; ++ ++ size_t search_list_size = 0; ++ for (size_t i = 0; i < conf->search_list_size; ++i) ++ { ++ if (resp->dnsrch[i] != NULL) ++ { ++ search_list_size += strlen (resp->dnsrch[i]) + 1; ++ if (strcmp (resp->dnsrch[i], conf->search_list[i]) != 0) ++ return false; ++ } ++ else ++ { ++ /* resp->dnsrch is truncated if the number of elements ++ exceeds MAXDNSRCH, or if the combined storage space for ++ the search list exceeds what can be stored in ++ resp->defdname. */ ++ if (i == MAXDNSRCH || search_list_size > sizeof (resp->dnsrch)) ++ break; ++ /* Otherwise, a mismatch indicates a match failure. */ ++ return false; ++ } ++ } ++ } ++ ++ /* Check that the sort list has not been modified. */ ++ { ++ size_t nsort = conf->sort_list_size; ++ if (nsort > MAXRESOLVSORT) ++ nsort = MAXRESOLVSORT; ++ if (resp->nsort != nsort) ++ return false; ++ for (size_t i = 0; i < nsort; ++i) ++ if (resp->sort_list[i].addr.s_addr != conf->sort_list[i].addr.s_addr ++ || resp->sort_list[i].mask != conf->sort_list[i].mask) ++ return false; ++ } ++ ++ return true; ++} ++ ++struct resolv_conf * ++__resolv_conf_get (struct __res_state *resp) ++{ ++ struct resolv_conf *conf = resolv_conf_get_1 (resp); ++ if (conf == NULL) ++ return NULL; ++ if (resolv_conf_matches (resp, conf)) ++ return conf; ++ __resolv_conf_put (conf); ++ return NULL; ++} ++ ++void ++__resolv_conf_put (struct resolv_conf *conf) ++{ ++ if (conf == NULL) ++ return; ++ ++ __libc_lock_lock (lock); ++ conf_decrement (conf); ++ __libc_lock_unlock (lock); ++} ++ ++struct resolv_conf * ++__resolv_conf_allocate (const struct resolv_conf *init) ++{ ++ /* Allocate in decreasing order of alignment. */ ++ _Static_assert (__alignof__ (const char *const *) ++ <= __alignof__ (struct resolv_conf), "alignment"); ++ _Static_assert (__alignof__ (struct sockaddr_in6) ++ <= __alignof__ (const char *const *), "alignment"); ++ _Static_assert (__alignof__ (struct sockaddr_in) ++ == __alignof__ (struct sockaddr_in6), "alignment"); ++ _Static_assert (__alignof__ (struct resolv_sortlist_entry) ++ <= __alignof__ (struct sockaddr_in), "alignment"); ++ ++ /* Space needed by the nameserver addresses. */ ++ size_t address_space = 0; ++ for (size_t i = 0; i < init->nameserver_list_size; ++i) ++ if (init->nameserver_list[i]->sa_family == AF_INET) ++ address_space += sizeof (struct sockaddr_in); ++ else ++ { ++ assert (init->nameserver_list[i]->sa_family == AF_INET6); ++ address_space += sizeof (struct sockaddr_in6); ++ } ++ ++ /* Space needed by the search list strings. */ ++ size_t string_space = 0; ++ for (size_t i = 0; i < init->search_list_size; ++i) ++ string_space += strlen (init->search_list[i]) + 1; ++ ++ /* Allocate the buffer. */ ++ void *ptr; ++ struct alloc_buffer buffer = alloc_buffer_allocate ++ (sizeof (struct resolv_conf) ++ + init->nameserver_list_size * sizeof (init->nameserver_list[0]) ++ + address_space ++ + init->search_list_size * sizeof (init->search_list[0]) ++ + init->sort_list_size * sizeof (init->sort_list[0]) ++ + string_space, ++ &ptr); ++ struct resolv_conf *conf ++ = alloc_buffer_alloc (&buffer, struct resolv_conf); ++ if (conf == NULL) ++ /* Memory allocation failure. */ ++ return NULL; ++ assert (conf == ptr); ++ ++ /* Initialize the contents. */ ++ conf->__refcount = 1; ++ conf->retrans = init->retrans; ++ conf->retry = init->retry; ++ conf->options = init->options; ++ conf->ndots = init->ndots; ++ ++ /* Allocate the arrays with pointers. These must come first because ++ they have the highets alignment. */ ++ conf->nameserver_list_size = init->nameserver_list_size; ++ const struct sockaddr **nameserver_array = alloc_buffer_alloc_array ++ (&buffer, const struct sockaddr *, init->nameserver_list_size); ++ conf->nameserver_list = nameserver_array; ++ ++ conf->search_list_size = init->search_list_size; ++ const char **search_array = alloc_buffer_alloc_array ++ (&buffer, const char *, init->search_list_size); ++ conf->search_list = search_array; ++ ++ /* Fill the name server list array. */ ++ for (size_t i = 0; i < init->nameserver_list_size; ++i) ++ if (init->nameserver_list[i]->sa_family == AF_INET) ++ { ++ struct sockaddr_in *sa = alloc_buffer_alloc ++ (&buffer, struct sockaddr_in); ++ *sa = *(struct sockaddr_in *) init->nameserver_list[i]; ++ nameserver_array[i] = (struct sockaddr *) sa; ++ } ++ else ++ { ++ struct sockaddr_in6 *sa = alloc_buffer_alloc ++ (&buffer, struct sockaddr_in6); ++ *sa = *(struct sockaddr_in6 *) init->nameserver_list[i]; ++ nameserver_array[i] = (struct sockaddr *) sa; ++ } ++ ++ /* Allocate and fill the sort list array. */ ++ { ++ conf->sort_list_size = init->sort_list_size; ++ struct resolv_sortlist_entry *array = alloc_buffer_alloc_array ++ (&buffer, struct resolv_sortlist_entry, init->sort_list_size); ++ conf->sort_list = array; ++ for (size_t i = 0; i < init->sort_list_size; ++i) ++ array[i] = init->sort_list[i]; ++ } ++ ++ /* Fill the search list array. This must come last because the ++ strings are the least aligned part of the allocation. */ ++ { ++ for (size_t i = 0; i < init->search_list_size; ++i) ++ search_array[i] = alloc_buffer_copy_string ++ (&buffer, init->search_list[i]); ++ } ++ ++ assert (!alloc_buffer_has_failed (&buffer)); ++ return conf; ++} ++ ++/* Update *RESP from the extended state. */ ++static __attribute__ ((nonnull (1, 2), warn_unused_result)) bool ++update_from_conf (struct __res_state *resp, const struct resolv_conf *conf) ++{ ++ resp->defdname[0] = '\0'; ++ resp->pfcode = 0; ++ resp->_vcsock = -1; ++ resp->_flags = 0; ++ resp->ipv6_unavail = false; ++ resp->__glibc_unused_qhook = NULL; ++ resp->__glibc_unused_rhook = NULL; ++ ++ resp->retrans = conf->retrans; ++ resp->retry = conf->retry; ++ resp->options = conf->options; ++ resp->ndots = conf->ndots; ++ ++ /* Copy the name server addresses. */ ++ { ++ resp->nscount = 0; ++ resp->_u._ext.nscount = 0; ++ size_t nserv = conf->nameserver_list_size; ++ if (nserv > MAXNS) ++ nserv = MAXNS; ++ for (size_t i = 0; i < nserv; i++) ++ { ++ if (conf->nameserver_list[i]->sa_family == AF_INET) ++ { ++ resp->nsaddr_list[i] ++ = *(struct sockaddr_in *)conf->nameserver_list[i]; ++ resp->_u._ext.nsaddrs[i] = NULL; ++ } ++ else ++ { ++ assert (conf->nameserver_list[i]->sa_family == AF_INET6); ++ resp->nsaddr_list[i].sin_family = 0; ++ /* Make a defensive copy of the name server address, in ++ case the application overwrites it. */ ++ struct sockaddr_in6 *sa = malloc (sizeof (*sa)); ++ if (sa == NULL) ++ { ++ for (size_t j = 0; j < i; ++j) ++ free (resp->_u._ext.nsaddrs[j]); ++ return false; ++ } ++ *sa = *(struct sockaddr_in6 *)conf->nameserver_list[i]; ++ resp->_u._ext.nsaddrs[i] = sa; ++ } ++ resp->_u._ext.nssocks[i] = -1; ++ } ++ resp->nscount = nserv; ++ /* Leave resp->_u._ext.nscount at 0. res_send.c handles this. */ ++ } ++ ++ /* Fill in the prefix of the search list. It is truncated either at ++ MAXDNSRCH, or if reps->defdname has insufficient space. */ ++ { ++ struct alloc_buffer buffer ++ = alloc_buffer_create (resp->defdname, sizeof (resp->defdname)); ++ size_t size = conf->search_list_size; ++ size_t i; ++ for (i = 0; i < size && i < MAXDNSRCH; ++i) ++ { ++ resp->dnsrch[i] = alloc_buffer_copy_string ++ (&buffer, conf->search_list[i]); ++ if (resp->dnsrch[i] == NULL) ++ /* No more space in resp->defdname. Truncate. */ ++ break; ++ } ++ resp->dnsrch[i] = NULL; ++ } ++ ++ /* Copy the sort list. */ ++ { ++ size_t nsort = conf->sort_list_size; ++ if (nsort > MAXRESOLVSORT) ++ nsort = MAXRESOLVSORT; ++ for (size_t i = 0; i < nsort; ++i) ++ { ++ resp->sort_list[i].addr = conf->sort_list[i].addr; ++ resp->sort_list[i].mask = conf->sort_list[i].mask; ++ } ++ resp->nsort = nsort; ++ } ++ ++ /* The overlapping parts of both configurations should agree after ++ initialization. */ ++ assert (resolv_conf_matches (resp, conf)); ++ return true; ++} ++ ++/* Decrement the configuration object at INDEX and free it if the ++ reference counter reaches 0. *GLOBAL_COPY must be locked and ++ remains so. */ ++static void ++decrement_at_index (struct resolv_conf_global *global_copy, size_t index) ++{ ++ if (index < resolv_conf_array_size (&global_copy->array)) ++ { ++ /* Index found. */ ++ uintptr_t *slot = resolv_conf_array_at (&global_copy->array, index); ++ /* Check that the slot is not already part of the free list. */ ++ if (!(*slot & 1)) ++ { ++ struct resolv_conf *conf = (struct resolv_conf *) *slot; ++ conf_decrement (conf); ++ /* Put the slot onto the free list. */ ++ *slot = global_copy->free_list_start; ++ global_copy->free_list_start = (index << 1) | 1; ++ } ++ } ++} ++ ++bool ++__resolv_conf_attach (struct __res_state *resp, struct resolv_conf *conf) ++{ ++ assert (conf->__refcount > 0); ++ ++ struct resolv_conf_global *global_copy = get_locked_global (); ++ if (global_copy == NULL) ++ return false; ++ ++ /* Try to find an unused index in the array. */ ++ size_t index; ++ { ++ if (global_copy->free_list_start & 1) ++ { ++ /* Unlink from the free list. */ ++ index = global_copy->free_list_start >> 1; ++ uintptr_t *slot = resolv_conf_array_at (&global_copy->array, index); ++ global_copy->free_list_start = *slot; ++ assert (global_copy->free_list_start == 0 ++ || global_copy->free_list_start & 1); ++ /* Install the configuration pointer. */ ++ *slot = (uintptr_t) conf; ++ } ++ else ++ { ++ size_t size = resolv_conf_array_size (&global_copy->array); ++ /* No usable index found. Increase the array size. */ ++ resolv_conf_array_add (&global_copy->array, (uintptr_t) conf); ++ if (resolv_conf_array_has_failed (&global_copy->array)) ++ { ++ put_locked_global (global_copy); ++ __set_errno (ENOMEM); ++ return false; ++ } ++ /* The new array element was added at the end. */ ++ index = size; ++ } ++ } ++ ++ /* We have added a new reference to the object. */ ++ ++conf->__refcount; ++ assert (conf->__refcount > 0); ++ put_locked_global (global_copy); ++ ++ if (!update_from_conf (resp, conf)) ++ { ++ /* Drop the reference we acquired. Reacquire the lock. The ++ object has already been allocated, so it cannot be NULL this ++ time. */ ++ global_copy = get_locked_global (); ++ decrement_at_index (global_copy, index); ++ put_locked_global (global_copy); ++ return false; ++ } ++ resp->_u._ext.__glibc_extension_index = index ^ INDEX_MAGIC; ++ ++ return true; ++} ++ ++void ++__resolv_conf_detach (struct __res_state *resp) ++{ ++ if (atomic_load_relaxed (&global) == NULL) ++ /* Detach operation after a shutdown, or without any prior ++ attachment. We cannot free the data (and there might not be ++ anything to free anyway). */ ++ return; ++ ++ struct resolv_conf_global *global_copy = get_locked_global (); ++ size_t index = resp->_u._ext.__glibc_extension_index ^ INDEX_MAGIC; ++ decrement_at_index (global_copy, index); ++ ++ /* Clear the index field, so that accidental reuse is less ++ likely. */ ++ resp->_u._ext.__glibc_extension_index = 0; ++ ++ put_locked_global (global_copy); ++} ++ ++/* Deallocate the global data. */ ++static void __attribute__ ((section ("__libc_thread_freeres_fn"))) ++freeres (void) ++{ ++ /* No locking because this function is supposed to be called when ++ the process has turned single-threaded. */ ++ if (global == NULL) ++ return; ++ ++ if (global->conf_current != NULL) ++ { ++ conf_decrement (global->conf_current); ++ global->conf_current = NULL; ++ } ++ ++ /* Note that this frees only the array itself. The pointed-to ++ configuration objects should have been deallocated by res_nclose ++ and per-thread cleanup functions. */ ++ resolv_conf_array_free (&global->array); ++ ++ free (global); ++ ++ /* Stop potential future __resolv_conf_detach calls from accessing ++ deallocated memory. */ ++ global = NULL; ++} ++text_set_element (__libc_subfreeres, freeres); +diff --git a/resolv/resolv_conf.h b/resolv/resolv_conf.h +new file mode 100644 +index 0000000000000000..0ff8bd7e928708fc +--- /dev/null ++++ b/resolv/resolv_conf.h +@@ -0,0 +1,103 @@ ++/* Extended resolver state separate from struct __res_state. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef RESOLV_STATE_H ++#define RESOLV_STATE_H ++ ++#include ++#include ++#include ++ ++/* This type corresponds to members of the _res.sort_list array. */ ++struct resolv_sortlist_entry ++{ ++ struct in_addr addr; ++ uint32_t mask; ++}; ++ ++/* Extended resolver state associated with res_state objects. Client ++ code can reach this state through a struct resolv_context ++ object. */ ++struct resolv_conf ++{ ++ /* Reference counter. The object is deallocated once it reaches ++ zero. For internal use within resolv_conf only. */ ++ size_t __refcount; ++ ++ /* List of IPv4 and IPv6 name server addresses. */ ++ const struct sockaddr **nameserver_list; ++ size_t nameserver_list_size; ++ ++ /* The domain names forming the search list. */ ++ const char *const *search_list; ++ size_t search_list_size; ++ ++ /* IPv4 address preference rules. */ ++ const struct resolv_sortlist_entry *sort_list; ++ size_t sort_list_size; ++ ++ /* _res.options has type unsigned long, but we can only use 32 bits ++ for portability across all architectures. */ ++ unsigned int options; ++ unsigned int retrans; /* Timeout. */ ++ unsigned int retry; /* Number of times to retry. */ ++ unsigned int ndots; /* Dots needed for initial non-search query. */ ++}; ++ ++/* The functions below are for use by the res_init resolv.conf parser ++ and the struct resolv_context facility. */ ++ ++struct __res_state; ++ ++/* Read /etc/resolv.conf and return a configuration object, or NULL if ++ /etc/resolv.conf cannot be read due to memory allocation errors. ++ If PREINIT is not NULL, some configuration values are taken from the ++ struct __res_state object. */ ++struct resolv_conf *__resolv_conf_load (struct __res_state *preinit) ++ attribute_hidden __attribute__ ((warn_unused_result)); ++ ++/* Return a configuration object for the current /etc/resolv.conf ++ settings, or NULL on failure. The object is cached. */ ++struct resolv_conf *__resolv_conf_get_current (void) ++ attribute_hidden __attribute__ ((warn_unused_result)); ++ ++/* Return the extended resolver state for *RESP, or NULL if it cannot ++ be determined. A call to this function must be paired with a call ++ to __resolv_conf_put. */ ++struct resolv_conf *__resolv_conf_get (struct __res_state *) attribute_hidden; ++ ++/* Converse of __resolv_conf_get. */ ++void __resolv_conf_put (struct resolv_conf *) attribute_hidden; ++ ++/* Allocate a new struct resolv_conf object and copy the ++ pre-configured values from *INIT. Return NULL on allocation ++ failure. The object must be deallocated using ++ __resolv_conf_put. */ ++struct resolv_conf *__resolv_conf_allocate (const struct resolv_conf *init) ++ attribute_hidden __attribute__ ((nonnull (1), warn_unused_result)); ++ ++/* Associate an existing extended resolver state with *RESP. Return ++ false on allocation failure. In addition, update *RESP with the ++ overlapping non-extended resolver state. */ ++bool __resolv_conf_attach (struct __res_state *, struct resolv_conf *) ++ attribute_hidden; ++ ++/* Detach the extended resolver state from *RESP. */ ++void __resolv_conf_detach (struct __res_state *resp) attribute_hidden; ++ ++#endif /* RESOLV_STATE_H */ +diff --git a/resolv/resolv_context.c b/resolv/resolv_context.c +new file mode 100644 +index 0000000000000000..35d4b3d41d59fc98 +--- /dev/null ++++ b/resolv/resolv_context.c +@@ -0,0 +1,252 @@ ++/* Temporary, thread-local resolver state. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Currently active struct resolv_context object. This pointer forms ++ the start of a single-linked list, using the __next member of ++ struct resolv_context. This list serves two purposes: ++ ++ (a) A subsequent call to __resolv_context_get will only increment ++ the reference counter and will not allocate a new object. The ++ _res state freshness check is skipped in this case, too. ++ ++ (b) The per-thread cleanup function defined by the resolver calls ++ __resolv_context_freeres, which will deallocate all the context ++ objects. This avoids the need for cancellation handlers and ++ the complexity they bring, but it requires heap allocation of ++ the context object because the per-thread cleanup functions run ++ only after the stack has been fully unwound (and all on-stack ++ objects have been deallocated at this point). ++ ++ The TLS variable current is updated even in ++ __resolv_context_get_override, to support case (b) above. This does ++ not override the per-thread resolver state (as obtained by the ++ non-res_state function such as __resolv_context_get) in an ++ observable way because the wrapped context is only used to ++ implement the res_n* functions in the resolver, and those do not ++ call back into user code which could indirectly use the per-thread ++ resolver state. */ ++static __thread struct resolv_context *current attribute_tls_model_ie; ++ ++/* The resolv_conf handling will gives us a ctx->conf pointer even if ++ these fields do not match because a mis-match does not cause a loss ++ of state (_res objects can store the full information). This ++ function checks to ensure that there is a full patch, to prevent ++ overwriting a patched configuration. */ ++static bool ++replicated_configuration_matches (const struct resolv_context *ctx) ++{ ++ return ctx->resp->options == ctx->conf->options ++ && ctx->resp->retrans == ctx->conf->retrans ++ && ctx->resp->retry == ctx->conf->retry ++ && ctx->resp->ndots == ctx->conf->ndots; ++} ++ ++/* Initialize *RESP if RES_INIT is not yet set in RESP->options, or if ++ res_init in some other thread requested re-initializing. */ ++static __attribute__ ((warn_unused_result)) bool ++maybe_init (struct resolv_context *ctx, bool preinit) ++{ ++ struct __res_state *resp = ctx->resp; ++ if (resp->options & RES_INIT) ++ { ++ if (resp->options & RES_NORELOAD) ++ /* Configuration reloading was explicitly disabled. */ ++ return true; ++ ++ /* If there is no associated resolv_conf object despite the ++ initialization, something modified *ctx->resp. Do not ++ override those changes. */ ++ if (ctx->conf != NULL && replicated_configuration_matches (ctx)) ++ { ++ struct resolv_conf *current = __resolv_conf_get_current (); ++ if (current == NULL) ++ return false; ++ ++ /* Check if the configuration changed. */ ++ if (current != ctx->conf) ++ { ++ /* This call will detach the extended resolver state. */ ++ if (resp->nscount > 0) ++ __res_iclose (resp, true); ++ /* Reattach the current configuration. */ ++ if (__resolv_conf_attach (ctx->resp, current)) ++ { ++ __resolv_conf_put (ctx->conf); ++ /* ctx takes ownership, so we do not release current. */ ++ ctx->conf = current; ++ } ++ } ++ else ++ /* No change. Drop the reference count for current. */ ++ __resolv_conf_put (current); ++ } ++ return true; ++ } ++ ++ assert (ctx->conf == NULL); ++ if (preinit) ++ { ++ if (!resp->retrans) ++ resp->retrans = RES_TIMEOUT; ++ if (!resp->retry) ++ resp->retry = RES_DFLRETRY; ++ resp->options = RES_DEFAULT; ++ if (!resp->id) ++ resp->id = res_randomid (); ++ } ++ ++ if (__res_vinit (resp, preinit) < 0) ++ return false; ++ ctx->conf = __resolv_conf_get (ctx->resp); ++ return true; ++} ++ ++/* Allocate a new context object and initialize it. The object is put ++ on the current list. */ ++static struct resolv_context * ++context_alloc (struct __res_state *resp) ++{ ++ struct resolv_context *ctx = malloc (sizeof (*ctx)); ++ if (ctx == NULL) ++ return NULL; ++ ctx->resp = resp; ++ ctx->conf = __resolv_conf_get (resp); ++ ctx->__refcount = 1; ++ ctx->__from_res = true; ++ ctx->__next = current; ++ current = ctx; ++ return ctx; ++} ++ ++/* Deallocate the context object and all the state within. */ ++static void ++context_free (struct resolv_context *ctx) ++{ ++ int error_code = errno; ++ current = ctx->__next; ++ __resolv_conf_put (ctx->conf); ++ free (ctx); ++ __set_errno (error_code); ++} ++ ++/* Reuse the current context object. */ ++static struct resolv_context * ++context_reuse (void) ++{ ++ /* A context object created by __resolv_context_get_override cannot ++ be reused. */ ++ assert (current->__from_res); ++ ++ ++current->__refcount; ++ ++ /* Check for reference counter wraparound. This can only happen if ++ the get/put functions are not properly paired. */ ++ assert (current->__refcount > 0); ++ ++ return current; ++} ++ ++/* Backing function for the __resolv_context_get family of ++ functions. */ ++static struct resolv_context * ++context_get (bool preinit) ++{ ++ if (current != NULL) ++ return context_reuse (); ++ ++ struct resolv_context *ctx = context_alloc (&_res); ++ if (ctx == NULL) ++ return NULL; ++ if (!maybe_init (ctx, preinit)) ++ { ++ context_free (ctx); ++ return NULL; ++ } ++ return ctx; ++} ++ ++struct resolv_context * ++__resolv_context_get (void) ++{ ++ return context_get (false); ++} ++libc_hidden_def (__resolv_context_get) ++ ++struct resolv_context * ++__resolv_context_get_preinit (void) ++{ ++ return context_get (true); ++} ++libc_hidden_def (__resolv_context_get_preinit) ++ ++struct resolv_context * ++__resolv_context_get_override (struct __res_state *resp) ++{ ++ /* NB: As explained asbove, context_alloc will put the context on ++ the current list. */ ++ struct resolv_context *ctx = context_alloc (resp); ++ if (ctx == NULL) ++ return NULL; ++ ++ ctx->__from_res = false; ++ return ctx; ++} ++libc_hidden_def (__resolv_context_get_override) ++ ++void ++__resolv_context_put (struct resolv_context *ctx) ++{ ++ if (ctx == NULL) ++ return; ++ ++ /* NB: Callers assume that this function preserves errno and ++ h_errno. */ ++ ++ assert (current == ctx); ++ assert (ctx->__refcount > 0); ++ ++ if (ctx->__from_res && --ctx->__refcount > 0) ++ /* Do not pop this context yet. */ ++ return; ++ ++ context_free (ctx); ++} ++libc_hidden_def (__resolv_context_put) ++ ++void ++__resolv_context_freeres (void) ++{ ++ /* Deallocate the entire chain of context objects. */ ++ struct resolv_context *ctx = current; ++ current = NULL; ++ while (ctx != NULL) ++ { ++ struct resolv_context *next = ctx->__next; ++ context_free (ctx); ++ ctx = next; ++ } ++} +diff --git a/resolv/resolv_context.h b/resolv/resolv_context.h +new file mode 100644 +index 0000000000000000..e2f7ad66458f94bc +--- /dev/null ++++ b/resolv/resolv_context.h +@@ -0,0 +1,182 @@ ++/* Temporary, thread-local resolver state. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* struct resolv_context objects are allocated on the heap, ++ initialized by __resolv_context_get (and its variants), and ++ destroyed by __resolv_context_put. ++ ++ A nested call to __resolv_context_get (after another call to ++ __resolv_context_get without a matching __resolv_context_put call, ++ on the same thread) returns the original pointer, instead of ++ allocating a new context. This prevents unexpected reloading of ++ the resolver configuration. Care is taken to keep the context in ++ sync with the thread-local _res object. (This does not happen with ++ __resolv_context_get_override, and __resolv_context_get_no_inet6 may ++ also interpose another context object if RES_USE_INET6 needs to be ++ disabled.) ++ ++ In contrast to struct __res_state, struct resolv_context is not ++ affected by ABI compatibility concerns. ++ ++ For the benefit of the res_n* functions, a struct __res_state ++ pointer is included in the context object, and a separate ++ initialization function is provided. */ ++ ++#ifndef _RESOLV_CONTEXT_H ++#define _RESOLV_CONTEXT_H ++ ++#include ++#include ++#include ++#include ++ ++/* Temporary resolver state. */ ++struct resolv_context ++{ ++ struct __res_state *resp; /* Backing resolver state. */ ++ ++ /* Extended resolver state. This is set to NULL if the ++ __resolv_context_get functions are unable to locate an associated ++ extended state. In this case, the configuration data in *resp ++ has to be used; otherwise, the data from *conf should be ++ preferred (because it is a superset). */ ++ struct resolv_conf *conf; ++ ++ /* The following fields are for internal use within the ++ resolv_context module. */ ++ size_t __refcount; /* Count of reusages by the get functions. */ ++ bool __from_res; /* True if created from _res. */ ++ ++ /* If RES_USE_INET6 was disabled at this level, this field points to ++ the previous context. */ ++ struct resolv_context *__next; ++}; ++ ++/* Return the current temporary resolver context, or NULL if there was ++ an error (indicated by errno). A call to this function must be ++ paired with a call to __resolv_context_put. */ ++struct resolv_context *__resolv_context_get (void) ++ __attribute__ ((warn_unused_result)); ++libc_hidden_proto (__resolv_context_get) ++ ++/* Deallocate the temporary resolver context. Converse of ++ __resolv_context_get. Restore the RES_USE_INET6 flag if necessary. ++ Do nothing if CTX is NULL. */ ++void __resolv_context_put (struct resolv_context *ctx); ++libc_hidden_proto (__resolv_context_put) ++ ++/* Like __resolv_context_get, but the _res structure can be partially ++ initialzed and those changes will not be overwritten. */ ++struct resolv_context *__resolv_context_get_preinit (void) ++ __attribute__ ((warn_unused_result)); ++libc_hidden_proto (__resolv_context_get_preinit) ++ ++/* Wrap a struct __res_state object in a struct resolv_context object. ++ A call to this function must be paired with a call to ++ __resolv_context_put. */ ++struct resolv_context *__resolv_context_get_override (struct __res_state *) ++ __attribute__ ((nonnull (1), warn_unused_result)); ++libc_hidden_proto (__resolv_context_get_override) ++ ++/* Return the search path entry at INDEX, or NULL if there are fewer ++ than INDEX entries. */ ++static __attribute__ ((nonnull (1), unused)) const char * ++__resolv_context_search_list (const struct resolv_context *ctx, size_t index) ++{ ++ if (ctx->conf != NULL) ++ { ++ if (index < ctx->conf->search_list_size) ++ return ctx->conf->search_list[index]; ++ else ++ return NULL; ++ } ++ /* Fallback. ctx->resp->dnsrch is a NULL-terminated array. */ ++ for (size_t i = 0; ctx->resp->dnsrch[i] != NULL && i < MAXDNSRCH; ++i) ++ if (i == index) ++ return ctx->resp->dnsrch[i]; ++ return NULL; ++} ++ ++/* Return the number of name servers. */ ++static __attribute__ ((nonnull (1), unused)) size_t ++__resolv_context_nameserver_count (const struct resolv_context *ctx) ++{ ++ if (ctx->conf != NULL) ++ return ctx->conf->nameserver_list_size; ++ else ++ return ctx->resp->nscount; ++} ++ ++/* Return a pointer to the socket address of the name server INDEX, or ++ NULL if the index is out of bounds. */ ++static __attribute__ ((nonnull (1), unused)) const struct sockaddr * ++__resolv_context_nameserver (const struct resolv_context *ctx, size_t index) ++{ ++ if (ctx->conf != NULL) ++ { ++ if (index < ctx->conf->nameserver_list_size) ++ return ctx->conf->nameserver_list[index]; ++ } ++ else ++ if (index < ctx->resp->nscount) ++ { ++ if (ctx->resp->nsaddr_list[index].sin_family != 0) ++ return (const struct sockaddr *) &ctx->resp->nsaddr_list[index]; ++ else ++ return (const struct sockaddr *) &ctx->resp->_u._ext.nsaddrs[index]; ++ } ++ return NULL; ++} ++ ++/* Return the number of sort list entries. */ ++static __attribute__ ((nonnull (1), unused)) size_t ++__resolv_context_sort_count (const struct resolv_context *ctx) ++{ ++ if (ctx->conf != NULL) ++ return ctx->conf->sort_list_size; ++ else ++ return ctx->resp->nsort; ++} ++ ++/* Return the sort list entry at INDEX. */ ++static __attribute__ ((nonnull (1), unused)) struct resolv_sortlist_entry ++__resolv_context_sort_entry (const struct resolv_context *ctx, size_t index) ++{ ++ if (ctx->conf != NULL) ++ { ++ if (index < ctx->conf->sort_list_size) ++ return ctx->conf->sort_list[index]; ++ /* Fall through. */ ++ } ++ else if (index < ctx->resp->nsort) ++ return (struct resolv_sortlist_entry) ++ { ++ .addr = ctx->resp->sort_list[index].addr, ++ .mask = ctx->resp->sort_list[index].mask, ++ }; ++ ++ return (struct resolv_sortlist_entry) { .mask = 0, }; ++} ++ ++/* Called during thread shutdown to free the associated resolver ++ context (mostly in response to cancellation, otherwise the ++ __resolv_context_get/__resolv_context_put pairing will already have ++ deallocated the context object). */ ++void __resolv_context_freeres (void) attribute_hidden; ++ ++#endif /* _RESOLV_CONTEXT_H */ +diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c +index 6cb59604961ebd93..08110a007af909ff 100644 +--- a/resolv/tst-aton.c ++++ b/resolv/tst-aton.c +@@ -1,4 +1,5 @@ + #include ++#include + #include + #include + #include +@@ -43,8 +44,8 @@ static struct tests + }; + + +-int +-main (int argc, char *argv[]) ++static int ++do_test (void) + { + int result = 0; + size_t cnt; +@@ -71,3 +72,6 @@ main (int argc, char *argv[]) + + return result; + } ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git a/resolv/tst-bug18665-tcp.c b/resolv/tst-bug18665-tcp.c +new file mode 100644 +index 0000000000000000..4bc0c262b1cd7aab +--- /dev/null ++++ b/resolv/tst-bug18665-tcp.c +@@ -0,0 +1,230 @@ ++/* Test __libc_res_nsend buffer mismanagement, basic TCP coverage. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; ++ ++static int initial_address_count = 1; ++static int subsequent_address_count = 2000; ++static int response_number = 0; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_VERIFY_EXIT (qname != NULL); ++ ++ /* If not using TCP, just force its use. */ ++ if (!ctx->tcp) ++ { ++ struct resolv_response_flags flags = {.tc = true}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ struct resolv_response_flags flags = {}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ resolv_response_section (b, ns_s_an); ++ ++ /* The number of addresses (in the additional section) for the name ++ server record (in the authoritative section). */ ++ int address_count; ++ xpthread_mutex_lock (&lock); ++ ++response_number; ++ if (response_number == 1) ++ address_count = initial_address_count; ++ else if (response_number == 2) ++ { ++ address_count = 0; ++ resolv_response_drop (b); ++ resolv_response_close (b); ++ } ++ else ++ address_count = subsequent_address_count; ++ xpthread_mutex_unlock (&lock); ++ ++ /* Only add the address record to the answer section if we requested ++ any name server addresses. */ ++ if (address_count > 0) ++ { ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {10, response_number >> 8, response_number, 0}; ++ ipv4[3] = 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, ++ response_number >> 8, response_number, 0, 0}; ++ ipv6[15] = 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ support_record_failure (); ++ printf ("error: unexpected QTYPE: %s/%u/%u\n", ++ qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++ ++ /* Add the name server record. */ ++ resolv_response_section (b, ns_s_ns); ++ resolv_response_open_record (b, "example", C_IN, T_NS, 0); ++ resolv_response_add_name (b, "ns.example"); ++ resolv_response_close_record (b); ++ ++ /* Increase the response size with name server addresses. These ++ addresses are not copied out of nss_dns, and thus do not ++ trigger getaddrinfo retries with a larger buffer, making ++ testing more predictable. */ ++ resolv_response_section (b, ns_s_ar); ++ for (int i = 1; i <= address_count; ++i) ++ { ++ resolv_response_open_record (b, "ns.example", qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {response_number, i >> 8, i, 0}; ++ ipv4[3] = 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, ++ response_number >> 8, response_number, ++ i >> 8, i, 0, 0}; ++ ipv6[15] = 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ support_record_failure (); ++ printf ("error: unexpected QTYPE: %s/%u/%u\n", ++ qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++ } ++ } ++} ++ ++static char * ++expected_result (unsigned port, unsigned response_number) ++{ ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ /* We fail the second TCP query to the first server by closing the ++ connection immediately, without returning any data. This should ++ cause failover to the second server. */ ++ int server_index = 1; ++ fprintf (mem.out, "address: STREAM/TCP 10.%u.%u.%u %u\n", ++ (response_number >> 8) & 0xff, response_number & 0xff, ++ 2 + 4 * server_index, port); ++ fprintf (mem.out, "address: STREAM/TCP 2001:db8::%x:%x %u\n", ++ (response_number + 1) & 0xffff, ++ 2 + 4 * server_index, port); ++ xfclose_memstream (&mem); ++ return mem.buffer; ++} ++ ++static void ++test_different_sizes (void) ++{ ++ struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ struct addrinfo *ai; ++ char *expected; ++ int ret; ++ ++ /* This magic number produces a response size close to 2048 ++ bytes. */ ++ initial_address_count = 124; ++ response_number = 0; ++ ++ ret = getaddrinfo ("www.example", "80", &hints, &ai); ++ expected = expected_result (80, 3); ++ check_addrinfo ("www.example:80", ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (expected); ++ ++ response_number = 0; ++ ret = getaddrinfo ("www123.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ++ response_number = 0; ++ ret = getaddrinfo ("www1234.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ++ response_number = 0; ++ ret = getaddrinfo ("www12345.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ test_different_sizes (); ++ ++ _res.options |= RES_SNGLKUP; ++ test_different_sizes (); ++ ++ _res.options |= RES_SNGLKUPREOP; ++ test_different_sizes (); ++ ++ resolv_test_end (obj); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-bug18665.c b/resolv/tst-bug18665.c +new file mode 100644 +index 0000000000000000..3c699919fcfe4231 +--- /dev/null ++++ b/resolv/tst-bug18665.c +@@ -0,0 +1,138 @@ ++/* Test for __libc_res_nsend buffer mismanagent (bug 18665), UDP case. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; ++ ++static int initial_address_count; ++static int response_count; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_VERIFY_EXIT (qname != NULL); ++ struct resolv_response_flags flags = {}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ resolv_response_section (b, ns_s_an); ++ ++ /* Add many A/AAAA records to the second response. */ ++ int address_count; ++ xpthread_mutex_lock (&lock); ++ if (response_count == 0) ++ address_count = initial_address_count; ++ else ++ address_count = 2000; ++ ++response_count; ++ xpthread_mutex_unlock (&lock); ++ ++ for (int i = 0; i < address_count; ++i) ++ { ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {10, i >> 8, i, 0}; ++ ipv4[3] = 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ i >> 8, i, 0}; ++ ipv6[15] = 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ support_record_failure (); ++ printf ("error: unexpected QTYPE: %s/%u/%u\n", ++ qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++ } ++} ++ ++static void ++test_different_sizes (void) ++{ ++ struct addrinfo hints = { .ai_family = AF_UNSPEC, }; ++ struct addrinfo *ai; ++ int ret; ++ ++ /* This magic number produces a response size close to 2048 ++ bytes. */ ++ initial_address_count = 126; ++ response_count = 0; ++ ++ ret = getaddrinfo ("www.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ++ response_count = 0; ++ ret = getaddrinfo ("www123.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ++ response_count = 0; ++ ret = getaddrinfo ("www1234.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ++ response_count = 0; ++ ret = getaddrinfo ("www12345.example", "80", &hints, &ai); ++ if (ret == 0) ++ freeaddrinfo (ai); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ test_different_sizes (); ++ ++ _res.options |= RES_SNGLKUP; ++ test_different_sizes (); ++ ++ _res.options |= RES_SNGLKUPREOP; ++ test_different_sizes (); ++ ++ resolv_test_end (obj); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-inet_ntop.c b/resolv/tst-inet_ntop.c +index 7267c5b4f2f48b8c..f0de06306c20b1c5 100644 +--- a/resolv/tst-inet_ntop.c ++++ b/resolv/tst-inet_ntop.c +@@ -106,7 +106,7 @@ do_test (void) + result++; + } + +- ++ + return result; + } + +diff --git a/resolv/tst-leaks.c b/resolv/tst-leaks.c +index 4e47a6a12152adb4..4f6453517fe66a88 100644 +--- a/resolv/tst-leaks.c ++++ b/resolv/tst-leaks.c +@@ -1,5 +1,5 @@ + /* Tests for res_query in libresolv +- Copyright (C) 2003, 2004 Free Software Foundation, Inc. ++ Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +diff --git a/resolv/tst-leaks2.c b/resolv/tst-leaks2.c +index b098e8af5d858d18..5a68a4c6574b66c0 100644 +--- a/resolv/tst-leaks2.c ++++ b/resolv/tst-leaks2.c +@@ -1,5 +1,5 @@ + /* Tests for res_init in libresolv +- Copyright (C) 2004 Free Software Foundation, Inc. ++ Copyright (C) 2004-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +diff --git a/resolv/tst-ns_name.c b/resolv/tst-ns_name.c +new file mode 100644 +index 0000000000000000..65eea4c827780826 +--- /dev/null ++++ b/resolv/tst-ns_name.c +@@ -0,0 +1,438 @@ ++/* Test ns_name-related functions. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* This test program processes the tst-ns_name.data file. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* A byte buffer and its length. */ ++struct buffer ++{ ++ unsigned char *data; ++ size_t length; ++}; ++ ++/* Convert a base64-encoded string to its binary representation. */ ++static bool ++base64_to_buffer (const char *base64, struct buffer *result) ++{ ++ /* "-" denotes an empty input. */ ++ if (strcmp (base64, "-") == 0) ++ { ++ result->data = xmalloc (1); ++ result->length = 0; ++ return true; ++ } ++ ++ size_t size = strlen (base64); ++ unsigned char *data = xmalloc (size); ++ int ret = b64_pton (base64, data, size); ++ if (ret < 0 || ret > size) ++ return false; ++ result->data = xrealloc (data, ret); ++ result->length = ret; ++ return true; ++} ++ ++/* A test case for ns_name_unpack and ns_name_ntop. */ ++struct test_case ++{ ++ char *path; ++ size_t lineno; ++ struct buffer input; ++ size_t input_offset; ++ int unpack_result; ++ struct buffer unpack_output; ++ int ntop_result; ++ char *ntop_text; ++}; ++ ++/* Deallocate the buffers associated with the test case. */ ++static void ++free_test_case (struct test_case *t) ++{ ++ free (t->path); ++ free (t->input.data); ++ free (t->unpack_output.data); ++ free (t->ntop_text); ++} ++ ++/* Extract the test case information from a test file line. */ ++static bool ++parse_test_case (const char *path, size_t lineno, const char *line, ++ struct test_case *result) ++{ ++ memset (result, 0, sizeof (*result)); ++ result->path = xstrdup (path); ++ result->lineno = lineno; ++ result->ntop_result = -1; ++ char *input = NULL; ++ char *unpack_output = NULL; ++ int ret = sscanf (line, "%ms %zu %d %ms %d %ms", ++ &input, &result->input_offset, ++ &result->unpack_result, &unpack_output, ++ &result->ntop_result, &result->ntop_text); ++ if (ret < 3) ++ { ++ printf ("%s:%zu: error: missing input fields\n", path, lineno); ++ free (input); ++ return false; ++ } ++ if (!base64_to_buffer (input, &result->input)) ++ { ++ printf ("%s:%zu: error: malformed base64 input data\n", path, lineno); ++ free (input); ++ free (unpack_output); ++ free (result->ntop_text); ++ return false; ++ } ++ free (input); ++ ++ if (unpack_output == NULL) ++ result->unpack_output = (struct buffer) { NULL, 0 }; ++ else if (!base64_to_buffer (unpack_output, &result->unpack_output)) ++ { ++ printf ("%s:%zu: error: malformed base64 unpack data\n", path, lineno); ++ free (result->input.data); ++ free (unpack_output); ++ free (result->ntop_text); ++ return false; ++ } ++ free (unpack_output); ++ ++ /* At this point, all allocated buffers have been transferred to ++ *result. */ ++ ++ if (result->input_offset > result->input.length) ++ { ++ printf ("%s:%zu: error: input offset %zu exceeds buffer size %zu\n", ++ path, lineno, result->input_offset, result->input.length); ++ free_test_case (result); ++ return false; ++ } ++ if (result->unpack_result < -1) ++ { ++ printf ("%s:%zu: error: invalid unpack result %d\n", ++ path, lineno, result->unpack_result); ++ free_test_case (result); ++ return false; ++ } ++ if (result->ntop_result < -1) ++ { ++ printf ("%s:%zu: error: invalid ntop result %d\n", ++ path, lineno, result->ntop_result); ++ free_test_case (result); ++ return false; ++ } ++ ++ bool fields_consistent; ++ switch (ret) ++ { ++ case 3: ++ fields_consistent = result->unpack_result == -1; ++ break; ++ case 5: ++ fields_consistent = result->unpack_result != -1 ++ && result->ntop_result == -1; ++ break; ++ case 6: ++ fields_consistent = result->unpack_result != -1 ++ && result->ntop_result != -1; ++ break; ++ default: ++ fields_consistent = false; ++ } ++ if (!fields_consistent) ++ { ++ printf ("%s:%zu: error: wrong number of fields: %d\n", ++ path, lineno, ret); ++ free_test_case (result); ++ return false; ++ } ++ return true; ++} ++ ++/* Format the buffer as a hexadecimal string and write it to standard ++ output. */ ++static void ++print_hex (const char *label, struct buffer buffer) ++{ ++ printf (" %s ", label); ++ unsigned char *p = buffer.data; ++ unsigned char *end = p + buffer.length; ++ while (p < end) ++ { ++ printf ("%02X", *p & 0xFF); ++ ++p; ++ } ++ putchar ('\n'); ++} ++ ++/* Run the test case specified in *T. */ ++static void ++run_test_case (struct test_case *t) ++{ ++ /* Test ns_name_unpack. */ ++ unsigned char *unpacked = xmalloc (NS_MAXCDNAME); ++ int consumed = ns_name_unpack ++ (t->input.data, t->input.data + t->input.length, ++ t->input.data + t->input_offset, ++ unpacked, NS_MAXCDNAME); ++ if (consumed != t->unpack_result) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong result from ns_name_unpack\n" ++ " expected: %d\n" ++ " actual: %d\n", ++ t->path, t->lineno, t->unpack_result, consumed); ++ return; ++ } ++ if (consumed != -1) ++ { ++ if (memcmp (unpacked, t->unpack_output.data, ++ t->unpack_output.length) != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong data from ns_name_unpack\n", ++ t->path, t->lineno); ++ print_hex ("expected:", t->unpack_output); ++ print_hex ("actual: ", ++ (struct buffer) { unpacked, t->unpack_output.length }); ++ return; ++ } ++ ++ /* Test ns_name_ntop. */ ++ char *text = xmalloc (NS_MAXDNAME); ++ int ret = ns_name_ntop (unpacked, text, NS_MAXDNAME); ++ if (ret != t->ntop_result) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong result from ns_name_top\n" ++ " expected: %d\n" ++ " actual: %d\n", ++ t->path, t->lineno, t->ntop_result, ret); ++ return; ++ } ++ if (ret != -1) ++ { ++ if (strcmp (text, t->ntop_text) != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong data from ns_name_ntop\n", ++ t->path, t->lineno); ++ printf (" expected: \"%s\"\n", t->ntop_text); ++ printf (" actual: \"%s\"\n", text); ++ return; ++ } ++ ++ /* Test ns_name_pton. Unpacking does not check the ++ NS_MAXCDNAME limit, but packing does, so we need to ++ adjust the expected result. */ ++ int expected; ++ if (t->unpack_output.length > NS_MAXCDNAME) ++ expected = -1; ++ else if (strcmp (text, ".") == 0) ++ /* The root domain is fully qualified. */ ++ expected = 1; ++ else ++ /* The domain name is never fully qualified. */ ++ expected = 0; ++ unsigned char *repacked = xmalloc (NS_MAXCDNAME); ++ ret = ns_name_pton (text, repacked, NS_MAXCDNAME); ++ if (ret != expected) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong result from ns_name_pton\n" ++ " expected: %d\n" ++ " actual: %d\n", ++ t->path, t->lineno, expected, ret); ++ return; ++ } ++ if (ret >= 0 ++ && memcmp (repacked, unpacked, t->unpack_output.length) != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong data from ns_name_pton\n", ++ t->path, t->lineno); ++ print_hex ("expected:", t->unpack_output); ++ print_hex ("actual: ", ++ (struct buffer) { repacked, t->unpack_output.length }); ++ return; ++ } ++ ++ /* Test ns_name_compress, no compression case. */ ++ if (t->unpack_output.length > NS_MAXCDNAME) ++ expected = -1; ++ else ++ expected = t->unpack_output.length; ++ memset (repacked, '$', NS_MAXCDNAME); ++ { ++ enum { ptr_count = 5 }; ++ const unsigned char *dnptrs[ptr_count] = { repacked, }; ++ ret = ns_name_compress (text, repacked, NS_MAXCDNAME, ++ dnptrs, dnptrs + ptr_count); ++ if (ret != expected) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong result from ns_name_compress\n" ++ " expected: %d\n" ++ " actual: %d\n", ++ t->path, t->lineno, expected, ret); ++ return; ++ } ++ if (ret < 0) ++ { ++ TEST_VERIFY (dnptrs[0] == repacked); ++ TEST_VERIFY (dnptrs[1] == NULL); ++ } ++ else ++ { ++ if (memcmp (repacked, unpacked, t->unpack_output.length) != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong data from ns_name_compress\n", ++ t->path, t->lineno); ++ print_hex ("expected:", t->unpack_output); ++ print_hex ("actual: ", (struct buffer) { repacked, ret }); ++ return; ++ } ++ TEST_VERIFY (dnptrs[0] == repacked); ++ if (unpacked[0] == '\0') ++ /* The root domain is not a compression target. */ ++ TEST_VERIFY (dnptrs[1] == NULL); ++ else ++ { ++ TEST_VERIFY (dnptrs[1] == repacked); ++ TEST_VERIFY (dnptrs[2] == NULL); ++ } ++ } ++ } ++ ++ /* Test ns_name_compress, full compression case. Skip this ++ test for invalid names and the root domain. */ ++ if (expected >= 0 && unpacked[0] != '\0') ++ { ++ /* The destination buffer needs additional room for the ++ offset, the initial name, and the compression ++ reference. */ ++ enum { name_offset = 259 }; ++ size_t target_offset = name_offset + t->unpack_output.length; ++ size_t repacked_size = target_offset + 2; ++ repacked = xrealloc (repacked, repacked_size); ++ memset (repacked, '@', repacked_size); ++ memcpy (repacked + name_offset, ++ t->unpack_output.data, t->unpack_output.length); ++ enum { ptr_count = 5 }; ++ const unsigned char *dnptrs[ptr_count] ++ = { repacked, repacked + name_offset, }; ++ ret = ns_name_compress ++ (text, repacked + target_offset, NS_MAXCDNAME, ++ dnptrs, dnptrs + ptr_count); ++ if (ret != 2) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong result from ns_name_compress" ++ " (2)\n" ++ " expected: 2\n" ++ " actual: %d\n", ++ t->path, t->lineno, ret); ++ return; ++ } ++ if (memcmp (repacked + target_offset, "\xc1\x03", 2) != 0) ++ { ++ support_record_failure (); ++ printf ("%s:%zu: error: wrong data from ns_name_compress" ++ " (2)\n" ++ " expected: C103\n", ++ t->path, t->lineno); ++ print_hex ("actual: ", ++ (struct buffer) { repacked + target_offset, ret }); ++ return; ++ } ++ TEST_VERIFY (dnptrs[0] == repacked); ++ TEST_VERIFY (dnptrs[1] == repacked + name_offset); ++ TEST_VERIFY (dnptrs[2] == NULL); ++ } ++ ++ free (repacked); ++ } ++ free (text); ++ } ++ free (unpacked); ++} ++ ++/* Open the file at PATH, parse the test cases contained in it, and ++ run them. */ ++static void ++run_test_file (const char *path) ++{ ++ FILE *fp = xfopen (path, "re"); ++ char *line = NULL; ++ size_t line_allocated = 0; ++ size_t lineno = 0; ++ ++ while (true) ++ { ++ ssize_t ret = getline (&line, &line_allocated, fp); ++ if (ret < 0) ++ { ++ if (ferror (fp)) ++ { ++ printf ("%s: error reading file: %m\n", path); ++ exit (1); ++ } ++ TEST_VERIFY (feof (fp)); ++ break; ++ } ++ ++ ++lineno; ++ char *p = line; ++ while (isspace (*p)) ++ ++p; ++ if (*p == '\0' || *p == '#') ++ continue; ++ ++ struct test_case test_case; ++ if (!parse_test_case (path, lineno, line, &test_case)) ++ { ++ support_record_failure (); ++ continue; ++ } ++ run_test_case (&test_case); ++ free_test_case (&test_case); ++ } ++ free (line); ++ xfclose (fp); ++} ++ ++static int ++do_test (void) ++{ ++ run_test_file ("tst-ns_name.data"); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-ns_name.data b/resolv/tst-ns_name.data +new file mode 100644 +index 0000000000000000..0ff0dc3de7a722ae +--- /dev/null ++++ b/resolv/tst-ns_name.data +@@ -0,0 +1,548 @@ ++# Test input for ns_name_unpack and ns_name_ntop. ++# Copyright (C) 2017 Free Software Foundation, Inc. ++# This file is part of the GNU C Library. ++# ++# The GNU C Library is free software; you can redistribute it and/or ++# modify it under the terms of the GNU Lesser General Public ++# License as published by the Free Software Foundation; either ++# version 2.1 of the License, or (at your option) any later version. ++# ++# The GNU C Library is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# Lesser General Public License for more details. ++# ++# You should have received a copy of the GNU Lesser General Public ++# License along with the GNU C Library; if not, see ++# . ++ ++# This file contains test input and expected output for the ++# ns_name_unpack and ns_name_ntop functions. Empty lines and comments ++# (lines starting with #) are ignored. Test data lines have the ++# following format: ++# ++# INPUT INPUT-OFFSET UNPACK-RESULT UNPACK-OUTPUT NTOP-RESULT NTOP-OUTPUT ++# ++# INPUT, UNPACK-OUTPUT are base64-encoded binary blobs. INPUT-OFFSET, ++# UNPACK-RESULT, NTOP-RESULT are signed integers. NTOP-OUTPUT is an ++# ASCII string (without spaces). If UNPACK-RESULT or NTOP-RESULT are ++# -1, the fields after that are missing (-1 is an error code, so the ++# output buffer is undefined). ++ ++# First some manually-crafted test cases. ++ ++# bytes-1 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8BQAFBAUIBQwFEAUUBRgFHAUgBSQFKAUsBTAFNAU4BTwFQAVEBUgFTAVQBVQFWAVcBWAFZAVoBWwFcAV0BXgFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwGAAYEBggGDAYQBhQGGAYcBiAGJAYoBiwGMAY0BjgGPAZABkQGSAZMBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAG5AboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QH+Af8A 0 -1 ++# bytes-1a ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8A 0 129 AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8A 233 \000.\001.\002.\003.\004.\005.\006.\007.\008.\009.\010.\011.\012.\013.\014.\015.\016.\017.\018.\019.\020.\021.\022.\023.\024.\025.\026.\027.\028.\029.\030.\031.\032.!.\".#.\$.%.&.'.\(.\).*.+.,.-.\../.0.1.2.3.4.5.6.7.8.9.:.\;.<.=.>.? ++# bytes-1b ++AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8A 0 129 AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8A 133 \@.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.[.\\.].^._.`.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.{.|.}.~.\127 ++# bytes-1c ++AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8A 0 129 AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8A 320 \128.\129.\130.\131.\132.\133.\134.\135.\136.\137.\138.\139.\140.\141.\142.\143.\144.\145.\146.\147.\148.\149.\150.\151.\152.\153.\154.\155.\156.\157.\158.\159.\160.\161.\162.\163.\164.\165.\166.\167.\168.\169.\170.\171.\172.\173.\174.\175.\176.\177.\178.\179.\180.\181.\182.\183.\184.\185.\186.\187.\188.\189.\190.\191 ++# bytes-1d ++AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QH+Af8A 0 129 AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QH+Af8A 320 \192.\193.\194.\195.\196.\197.\198.\199.\200.\201.\202.\203.\204.\205.\206.\207.\208.\209.\210.\211.\212.\213.\214.\215.\216.\217.\218.\219.\220.\221.\222.\223.\224.\225.\226.\227.\228.\229.\230.\231.\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253.\254.\255 ++# bytes-4 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXV5fBGBhYmMEZGVmZwRoaWprBGxtbm8EcHFycwR0dXZ3BHh5ensEfH1+fwSAgYKDBISFhocEiImKiwSMjY6PBJCRkpMElJWWlwSYmZqbBJydnp8EoKGiowSkpaanBKipqqsErK2urwSwsbKzBLS1trcEuLm6uwS8vb6/BMDBwsMExMXGxwTIycrLBMzNzs8E0NHS0wTU1dbXBNjZ2tsE3N3e3wTg4eLjBOTl5ucE6Onq6wTs7e7vBPDx8vME9PX29wT4+fr7BPz9/v8A 0 -1 ++# bytes-4a ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 185 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++# bytes-4b ++BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8A 0 81 BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8A 85 \@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk.lmno.pqrs.tuvw.xyz{.|}~\127 ++# bytes-4c ++BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaKjBKSlpqcEqKmqqwSsra6vBLCxsrMEtLW2twS4ubq7BLy9vr8A 0 81 BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaKjBKSlpqcEqKmqqwSsra6vBLCxsrMEtLW2twS4ubq7BLy9vr8A 272 \128\129\130\131.\132\133\134\135.\136\137\138\139.\140\141\142\143.\144\145\146\147.\148\149\150\151.\152\153\154\155.\156\157\158\159.\160\161\162\163.\164\165\166\167.\168\169\170\171.\172\173\174\175.\176\177\178\179.\180\181\182\183.\184\185\186\187.\188\189\190\191 ++# bytes-4d ++BMDBwsMExMXGxwTIycrLBMzNzs8E0NHS0wTU1dbXBNjZ2tsE3N3e3wTg4eLjBOTl5ucE6Onq6wTs7e7vBPDx8vME9PX29wT4+fr7BPz9/v8A 0 81 BMDBwsMExMXGxwTIycrLBMzNzs8E0NHS0wTU1dbXBNjZ2tsE3N3e3wTg4eLjBOTl5ucE6Onq6wTs7e7vBPDx8vME9PX29wT4+fr7BPz9/v8A 272 \192\193\194\195.\196\197\198\199.\200\201\202\203.\204\205\206\207.\208\209\210\211.\212\213\214\215.\216\217\218\219.\220\221\222\223.\224\225\226\227.\228\229\230\231.\232\233\234\235.\236\237\238\239.\240\241\242\243.\244\245\246\247.\248\249\250\251.\252\253\254\255 ++# bytes-63 ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0/fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8P72+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+wT8/f7/AA== 0 -1 ++# bytes-63a ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9PgE/AA== 0 67 PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9PgE/AA== 171 \000\001\002\003\004\005\006\007\008\009\010\011\012\013\014\015\016\017\018\019\020\021\022\023\024\025\026\027\028\029\030\031\032!\"#\$%&'\(\)*+,-\./0123456789:\;<=>.? ++# bytes-63b ++P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fgF/AA== 0 67 P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fgF/AA== 71 \@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.\127 ++# bytes-63c ++P4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vgG/AA== 0 67 P4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vgG/AA== 258 \128\129\130\131\132\133\134\135\136\137\138\139\140\141\142\143\144\145\146\147\148\149\150\151\152\153\154\155\156\157\158\159\160\161\162\163\164\165\166\167\168\169\170\171\172\173\174\175\176\177\178\179\180\181\182\183\184\185\186\187\188\189\190.\191 ++# bytes-63d ++P8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/gH/AA== 0 67 P8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/gH/AA== 258 \192\193\194\195\196\197\198\199\200\201\202\203\204\205\206\207\208\209\210\211\212\213\214\215\216\217\218\219\220\221\222\223\224\225\226\227\228\229\230\231\232\233\234\235\236\237\238\239\240\241\242\243\244\245\246\247\248\249\250\251\252\253\254.\255 ++# compression-loop ++wAA= 0 -1 ++# compression-loop-2 ++wALAAA== 0 -1 ++# empty ++- 0 -1 ++# root ++AA== 0 1 AA== 2 . ++# truncated-compression ++wA== 0 -1 ++# www ++A3d3dwA= 0 5 A3d3dwA= 4 www ++# www-truncated ++A3d3dw== 0 -1 ++# www-truncated-2 ++A3d3 0 -1 ++# www.example.com ++5jrGq8kVxMt3ZS3RA3d3dwdleGFtcGxlA2NvbQA= 12 17 A3d3dwdleGFtcGxlA2NvbQA= 16 www.example.com ++# www.example.com-answer ++5jrGq8kVxMt3ZS3RA3d3dwdleGFtcGxlA2NvbQAAAQABwAw= 33 2 A3d3dwdleGFtcGxlA2NvbQA= 16 www.example.com ++# www.example.com-answer-truncated ++5jrGq8kVxMt3ZS3RA3d3dwdleGFtcGxlA2NvbQAAAQABwA== 33 -1 ++# www.example.com-truncated ++5jrGq8kVxMt3ZS3RA3d3dwdleGFtcGw= 12 -1 ++# www1.example.com-answer ++5jrGq8kVxMt3ZS3RA3d3dwdleGFtcGxlA2NvbQAAAQABBHd3dzHAEA== 33 7 BHd3dzEHZXhhbXBsZQNjb20A 17 www1.example.com ++ ++# Then test cases derived from the above by American Fuzzy Lop (AFL). ++BAABAgMEBAUGBwQICQoLAAwN 0 16 BAABAgMEBAUGBwQICQoLAA== 51 \000\001\002\003.\004\005\006\007.\008\009\010\011 ++PwABAgMEBQYHCAmztLUAABYXGBmInAoLDA0ODyQRNDU2NwE5Ojs8PT4/PwkKCwwNDg8kSwoLDA0ODyQpKSkpKSkpPT4/VTAxMjM0NDY3AYeLjCspCSkpKSkpKSkpKSkpZCcoKSorLC0uPD0+Pz9AQUJDREVGLzAxMjM0NDY3AYoEAKytrq8= 0 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2ADwBAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2ADwBAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAA 618 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000<\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\@\@\000\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AA8BAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AA8BAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAA 621 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\015\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\@\@\000\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjbJNjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAAAQAb 0 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NskAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NskAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAA 624 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.6\201\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\@\@\000\000 ++BAABAgMEBAUGBwQICQoLBBINDg8QAAAAEwQUFRYXBBgZGhsEHB0eNjY2AAA2NjY2Njw2ATYYNkUAAAIQ//9/TExMTExMTExMTExMTExMTExMTExMTENMTBMTExNqEykTlhMTEyYLAAEUFAAABjY2NjYAAAE2NhwAAAABAAABBDb/fwAAAzY2NgX//wU2NgD7SDYkNjk5OTk5OTk5OTk5OTk5OTk5OTk5PTY0pDY2NjY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Coq0DPQ0P/QM9DQ//9//9AAAAHSu9DRkNAABgAA/xQUAAAGfzYkNjY0Nks2AAQeVTb/AAABNn////8= 0 -1 ++BAABAgMEBAUGBwQICQoLBBINDg8EAAAQAAQUFRYXBBgZGhsEHB0eNjY2AAA2NjY2Njw2ATYYNkUAAAIQ//9/TExMTExMTExMTExMTExMTExMTExMTENMTBMTExNqEykTlhMTEyYLAAEUFAAABjY2NjYAAAE2NhwAAAABAAABBDb/fwAAAzY2NgX//wU2NgD7SDYkNjk5OTk5OTk5OTk5OTk5OTk5OTk5PTY0pDY2NjY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Coq0DPQ0P/QM9DQ//9//9AAAAHSu9DRkNAABgAA/xQUAAAGfzYkNjY0Nks2AAQeVTb/AAABNn////8= 0 -1 ++AgIhIiMEJCUkAScBKAEpASoBKwEsAS0BLgExATgBOQE6IDsBASoBKwEsAS0BLgE3ATgBOQE6IDsBPAE9AT4BPw0BDgEPARABEQESARMBFAEBDgEPARABEQESARMBFCEhISEhISEhISEhISEhIX4hISEhISEhISEhARcFGAEZARoBGwEcAR0BASYBJwEoASkBKjwBPQE+AT8NAQ4BDwEQAREBEgETARQBFwUYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBAAACQCsBLAEtAS4BJwEoAUgBKgErASwBLQEuATsBPAE9AT4BPwA= 0 242 AgIhIiMEJCUkAScBKAEpASoBKwEsAS0BLgExATgBOQE6IDsBASoBKwEsAS0BLgE3ATgBOQE6IDsBPAE9AT4BPw0BDgEPARABEQESARMBFAEBDgEPARABEQESARMBFCEhISEhISEhISEhISEhIX4hISEhISEhISEhARcFGAEZARoBGwEcAR0BASYBJwEoASkBKjwBPQE+AT8NAQ4BDwEQAREBEgETARQBFwUYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBAAACQCsBLAEtAS4BJwEoAUgBKgErASwBLQEuATsBPAE9AT4BPwA= 607 \002!.#\004\$%\$\001'\001\(\001\)\001*\001+\001,\001-\001\.\0011\0018\0019\001:\032\;\001\001*.+.,.-.\..7.8.9.:.\;\001<\001=\001>\001?\013\001\014\001\015\001\016\001\017\001\018\001\019\001\020\001\001\014\001\015\001\016\001.\001\018\001\019\001\020!!!!!!!!!!!.!!!~!!!!!!!!!!\001\023\005\024\001\025\001\026\001\027\001\028\001\029\001\001&\001'.\(.\).*.\001=\001>\001?\013\001\014\001\015\001\016\001\017\001\018\001\019\001\020\001\023\005\024\001\025\001\026\001\027\001\028\001\029\001\030\001\031\001\032\001!\001\"\001#\001\$\001%\001&\001'\001\(\001\000\000.\@+.,.-.\..'.\(.H.*.+.,.-.\..\;.<.=.>.? ++wMAAAcDAwMDAQAA2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2iTY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAUYUwB82Nn7s7OzsEBQUDDY2NgAAATY2NjZYNjYyNk02NlEAEQEANjYABf//BUU2OTY2NiU9PT09NgAAAfI//3Y2AAABNjY0NgAAAYA2PRAA+/v7+/v7+/v///8= 16 -1 ++AwAAJ8AAISEhISEhISEhISEhISEhfiEhISEhISEhISG7u5CjAA== 0 -1 ++AhIAAlBINQAAATU1FTo/SEhIAwMDAwMFRTY5NgA2JT09PQEfNjY8NjYkFTY0NjYyNjY2NjYADDY2QksAAAEBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgD//gABNjY2PDY2JBUAfg== 68 -1 ++AQQBAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAFdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4ASEhISEhISEhISEhISEhIX4hISEhISEhISEhuQG6AbsBvAG9Ab4BvwHAAdwBwgHDAcQBxQHGAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGiEhuQG6AbsBvAG9Ab4BvwHAAdwBwgHDAcQBxQHGAQ3xDQEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBXQEeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAEhISEBqgGrAawBrQGuAa8BsAGxASEhISEhISEhISEhISEhISEhISEhIX4hISEhISEhISEhEhISEhISEhISAAABEhISEhISEhICAgICAgICAgICAgICIssBzAHNAc4BzwHQAdEB0gHTAdQB1QHWASPHAcgByf9/AAABzAHNAc4BzwHQAdEB0gHTg9QB1QHWARISEhISEhISEhISEhISEhIREhISEhISEhISEgAAAH8SAAABEhISEhISEhICAgICAgICAgICAgICIssBzAHNAc4BzwHQAdEB0gHTAdQB1QHWASMELyTrJwQIKSsrACw= 0 -1 ++AQA= 0 -1 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0V3gHfAeAB4QHiAc8B0AHRAdIB0wHUAdUB1gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QD+ 0 -1 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9Af4B/wA= 0 -1 ++BOgDAwgINjY2NjY2NjY2NjY2NjY2NjY2NgAAASY2NjY2NjZAAAAANjY2NjY2NgAAAAE2NjY2NjY2NjY2Ng82NjY2NjY2NjYhNis2RhQ2Nv9///82NjY2NjY2NjY2Nlc2QDY2NjYAAAE2NiM2NjY2NoE2NjY2Np5CPAAhNhM2NjY2NjY2Np42PAAYNhM2NjY2NjY2NgA2NjY2NjY2NjY2NvA2tzY2NjY2NjY2NjY2NjY2NjY2NjY2Njk2NjYxNjY2NjY2Nv9/NjY2NhY2NjY2NgAAATY2NjY2NjaeNjwAGDY2NjY2NjY2FDYAgAAANgAAATY2NjY2NjY2NjYBNgAAATY2 0 255 BOgDAwgINjY2NjY2NjY2NjY2NjY2NjY2NgAAASY2NjY2NjZAAAAANjY2NjY2NgAAAAE2NjY2NjY2NjY2Ng82NjY2NjY2NjYhNis2RhQ2Nv9///82NjY2NjY2NjY2Nlc2QDY2NjYAAAE2NiM2NjY2NoE2NjY2Np5CPAAhNhM2NjY2NjY2Np42PAAYNhM2NjY2NjY2NgA2NjY2NjY2NjY2NvA2tzY2NjY2NjY2NjY2NjY2NjY2NjY2Njk2NjYxNjY2NjY2Nv9/NjY2NhY2NjY2NgAAATY2NjY2NjaeNjwAGDY2NjY2NjY2FDYAgAAANgAAATY2NjY2NjY2NjYBNgAA 412 \232\003\003\008.66666666.6666666666\000\000\001&666666\@\000\000\0006666666\000\000\000\00166666666666\0156666666.6!6+6F\02066\255\127\255\25566666666666W6\@6666\000\000\00166#66666\12966666\158B<\000!6.66666666\1586<\000\0246\0196666.666\00066666666666\2406\183666666666666666666666966616666666\255\1276.66\02266666\000\000\0016666666\1586<\000\02466666666\0206\000\128\000\0006\000\000\0016666666666\0016\000 ++AhIAAlBIAABISEhIUz4AAAE1FTU1LTU1LTW2NTU1NQAAATU1FTo/SEhISEhISEhISEhISEhISEhISEhISAABAABISCZIUw== 68 -1 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgE3ATgBOQE6ATsBPAE9AT4BPwA= 0 113 AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgE3ATgBOQE6ATsBPAE9AT4BPwA= 217 \000.\001.\002.\003.\004.\005.\006.\007.\008.\009.\010.\011.\012.\013.\014.\015.\016.\017.\018.\019.\020.\021.\022.\023.\024.\025.\026.\027.\028.\029.\030.\031.\032.!.\".#.\$.%.&.'.\(.\).*.+.,.-.\..7.8.9.:.\;.<.=.>.? ++BOgAAAEDAwgINjY2NgAAAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAX//wU2NjY0NgAAAQAAAYA2NhY2Njbn0NDQ0NDQ0NA2NjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFDY2NjYAADY2JDY2NDY2NjY2NjY2NjY2NjY2NjY2JDY2f3Z2dnZ2dnZ2dnZ2dnZ2dkE2ATYeBAX//wU2NjY0NgAACQAAAYA2NhY2NjbQ0NDQ0NDQ0NAz0NDQ0NDQ0NDQ0NCQ0AAUFAAAARQUNjY2NjY2Nlg2NjY2TSE2UQARAQAAATY2 0 255 BOgAAAEDAwgINjY2NgAAAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAX//wU2NjY0NgAAAQAAAYA2NhY2Njbn0NDQ0NDQ0NA2NjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFDY2NjYAADY2JDY2NDY2NjY2NjY2NjY2NjY2NjY2JDY2f3Z2dnZ2dnZ2dnZ2dnZ2dkE2ATYeBAX//wU2NjY0NgAACQAAAYA2NhY2NjbQ0NDQ0NDQ0NAz0NDQ0NDQ0NDQ0NCQ0AAUFAAAARQUNjY2NjY2Nlg2NjY2TSE2UQARAQAA 572 \232\000\000\001.\003\008\008.666\000\000\000\192\0316\128\00066\$\021666\0216\000\004666666666646X\004\005\255\255\00566646\000\000\001\000\000\001\12866.666\231\208\208\208\208\208\208\208\2086666666666.\000\000\000\001\0046666666666666\000\000\000\001\000\027KlKKKKKKK\0016\190\031F\0206666\000\00066\$664666.6666666666666\$66\127vvvvvvvvvvvvvvvA6\0016\030\004\005\255\255\00566646\000\000\009\000\000\001\128.6\022666\208\208\208\208\208\208\208\208\2083\208\208\208\208\208\208\208\208\208\208\208\144\208\000\020\020\000\000\001\020\0206666666X6666M!6Q\000\017.\000 ++AQABAwEJAQoYARkBGmwbARwHGgEeAc0BAAAB0AAAA+gB0w== 0 -1 ++AUABQwFEAUUBRgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8A 0 105 AUABQwFEAUUBRgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8A 109 \@.C.D.E.F.O.P.Q.R.S.T.U.V.W.X.Y.Z.[.\\._.`.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.{.|.}.~.\127 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAA 618 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\1276X+66666vvvvvvvv\255\011\000 ++AYABnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+ 0 -1 ++BOgAAAEDAwgINjY2NgAAAMAfNjZkAAAAAAEAFPY2HjY2NDYMAAEABAEAAAE2NgAAATb7IPvz+/sAAAFCRDYkDzI0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/zY+NjY2NjYAADYAAPs2DAEAAAH0wB82NjY2 0 146 BOgAAAEDAwgINjY2NgAAAMAfNjZkAAAAAAEAFPY2HjY2NDYMAAEABAEAAAE2NgAAATb7IPvz+/sAAAFCRDYkDzI0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/zY+NjY2NjYAADYAAPs2DAEAAAH0NjY0NgwAAQAEAQAAATY2AAABNvsg+/P7+wAAAUJENiQPMjQ2NjY2NjY2NgAQNjY2WDY2NjY2NjY2AAABAAE2NjZFNjYVNgAEOTY2AAABNjY2NjY2HDQ2WAAgNjb/Nj42NjY2NgAANgAA+zYMAQAA 607 \232\000\000\001.\003\008\008.666\000\000\000\192\03166d\000\000\000\000\001\000\020\2466\0306646\012\000\001\000\004\001\000\000\00166\000\000\0016\251\032\251\243\251\251\000\000\001BD6\$\015.466666666\000\016666X66666666\000\000\001\000\001666E66\0216\000\004966\000\000\001666666.46X\000\03266\2556>66666\000\0006\000\000\2516\012\001\000\000\001\244.646\012\000\001\000\004\001\000\000\00166\000\000\0016\251\032\251\243\251\251\000\000\001BD6\$\0152466666666\000\016666X666666.6\000\000\001\000\001666E66\0216\000\004966\000\000\001666666\02846X\000\03266\2556>66666\000\0006\000\000\2516\012\001\000 ++AcAB3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QH+ 0 -1 ++BOgAAAENAwgINjY2NgAAAMAfNjY2NjY2NgAQNjY2WDY2NjY2NjY2APP2FgE2NjZFNjYVNgAENjY2NjY2NjY2NjQ2WDY2NjY2NiUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlNjY2NjY2NjYAAAABBB82NgAAATY2NiQVNjQ2NjY2NjY2NjY2NjY2NgAAAAEENgAAATY2NjY2NgAAATY2NjY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2AAAAAQAbS2xLS0tLS0tLATa+HQABNjY2AFA2NiQgNjQ2NjY2NlE2NjY2NjY2NjY2Nho2Nn92dnZ2dpZ2dnZ2dkE2AQAAAQAAARY2 0 255 BOgAAAENAwgINjY2NgAAAMAfNjY2NjY2NgAQNjY2WDY2NjY2NjY2APP2FgE2NjZFNjYVNgAENjY2NjY2NjY2NjQ2WDY2NjY2NiUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlNjY2NjY2NjYAAAABBB82NgAAATY2NiQVNjQ2NjY2NjY2NjY2NjY2NgAAAAEENgAAATY2NjY2NgAAATY2NjY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2AAAAAQAbS2xLS0tLS0tLATa+HQABNjY2AFA2NiQgNjQ2NjY2NlE2NjY2NjY2NjY2Nho2Nn92dnZ2dpZ2dnZ2dkE2AQAAAQAA 460 \232\000\000\001.\003\008\0086666\000\000\000\192\0316.66666\000\016666X66666666\000\243\246\022\001666E66\0216\000\004666666666646X666666%.%%%%%%%%%%%%%%%%%%%%%%%%66666666\000\000\000\001\004.66\000\000\001666\$\0216466666666666666\000\000\000\001\004.\000\000\001666666\000\000\00166666666\000\000\000\001\0046666666666666\000\000\000\001\000\027KlKKKKKKK\001.\190\029\000\001666\000P66\$\0326466666Q66666666666\02666\127vvvvv\150vvvvvA6\001\000\000\001\000 ++BAABAgMEERITBBQVFhceHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXV5fBGBhYmMEZGVmZwRoaWprBGxtbm8EcHFycwR0dXZ3BHh5ensEfH1+fwSAgYKDBISFhocEiImKiwSMjY6PBJCRkpMElJWWlwSYmZqbBJydnp8EoKGiowQ= 0 -1 ++BOgAAAEDAwgIFjY2NgAAAMAfNjY2NjYkFTY0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTYABDY2NjY2NjY2NjY0Nlg2NjY2NjY2NgAAATY2NgAAAADAHzY2NjY2JAkJCf9/CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkVNjQ2NjY2NjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFDY2NjYAADY2JDY2NDY2NjY2NjY2NjY2NjY2NiQ2Nn92dnZ2dnZ2dnZ2dnZ2dnZBNgE2HgQAQP82NjY2NDYAAAEAAAGA 0 255 BOgAAAEDAwgIFjY2NgAAAMAfNjY2NjYkFTY0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTYABDY2NjY2NjY2NjY0Nlg2NjY2NjY2NgAAATY2NgAAAADAHzY2NjY2JAkJCf9/CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkVNjQ2NjY2NjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFDY2NjYAADY2JDY2NDY2NjY2NjY2NjY2NjY2NiQ2Nn92dnZ2dnZ2dnZ2dnZ2dnZBNgE2HgQAQP82NjY2NDYAAAEA 526 \232\000\000\001.\003\008\008.666\000\000\000\192\03166666\$\0216466666.66\000\016666X66666666\000\000\001\000\001666E66\0216\000\004666666666646X66666666\000\000.6.6\000\000\000\000\192\03166666\$\009\009\009\255\127\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\009\021646666666.666666\000\000\000\001\0046666666666666\000\000\000\001\000\027KlKKKKKKK\0016\190\031F\0206666\000\00066\$.64666666666666666\$66\127vvvvvvvvvvvvvvvA6\0016\030\004\000\@\255666646\000\000\001 ++AQABBwEIAQkBCgELAQwBZAEOAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AA== 0 67 AQABBwEIAQkBCgELAQwBZAEOAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAfQB9QH2AfcB+AH5AfoB+wH8Af0B/gH/AA== 162 \000.\007.\008.\009.\010.\011.\012.d.\014.\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253.\254.\255 ++AQAB3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QFAAP8A 0 67 AQAB3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QFAAA== 163 \000.\223.\224.\225.\226.\227.\228.\229.\230.\231.\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253.\@ ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGAEVFhcEGDoaGwQLHR4fDTUpIhkEJDoaGwQUIx4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CAjsA 0 255 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGAEVFhcEGDoaGwQLHR4fDTUpIhkEJDoaGwQUIx4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CAjsA 781 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\004\008\002\002\002\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\001\021\022\023\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$.\026\027\004\020#\030\031&5\)\"\025\004\$\$\000\000\002\000\@\002\016\"\002\016\@\002\016\"\002\016\"\002\016\@\002\016\"\002\016\031\004\032\)\"#\004\$\$\000\000\002\000\@\002\016\"\002.\@\002\016\"\002\016\"\006\004\008\002\@\002\002\002\254.\002\; ++YcAAAcDAwA3AAQAQFBQMNjY2AAABNjY2Hlg2NjY2PzY2UQARAQA2NktLS0sBFrsfRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PAFLATa+H0YUwB82Nn7s7OwAAAEB7OHsFAD/ADY0NjYyNjY2NjY9PT0BNjY2AAAAAQA2NDY2MjInNhgYGBgYGBgYGBgYGBgYGBgYGBgYGBg2NgAQNjYAEDY2AAABQAAAAQAAAUsBNr4fRgEAHzY2fuzs7AAAAQHs4ewUNrY2NgAdNjQ2NjZBNj42NjY2NjY2TtDQ0JDQABQUFBS2NjU2Njo2WDY2NjYAAAHQ0DPQ0NDQ0NDQ0ND///8BABAUFAw2NjYAAAE2Ng== 16 255 NjYAAAE2NjYeWDY2NjY/NjZRABEBADY2S0tLSwEWux9GFDY2NjYAADY2WDZ2PDY2NjY2AAABAAE2NjY8AUsBNr4fRhTAHzY2fuzs7AAAAQHs4ewUAP8ANjQ2NjI2NjY2Nj09PQE2NjYAAAABADY0NjYyMic2GBgYGBgYGBgYGBgYGBgYGBgYGBgYGDY2ABA2NgAQNjYAAAFAAAABAAABSwE2vh9GAQAfNjZ+7OzsAAABAezh7BQ2tjY2AB02NDY2NkE2PjY2NjY2NjZO0NDQkNAAFBQUFLY2NTY2OjZYNjY2NgAAAdDQM9DQ0NDQ0NDQ0P///wEAEBQUDDY2NgAA 660 6\000\000\001666\030X6666?66Q\000\017\001\00066KKKK\001\022\187\031F\0206666\000\00066X6v<66666\000\000\001\000.6.6<\001K\0016\190\031F\020\192\03166~\236\236\236\000\000\001\001\236\225\236\020\000\255\0006466266666===\001666\000\000\000\001\000646.22'6\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\024\02466\000\01666\000\01666\000\000\001\@\000\000\001\000\000\001K\0016\190\031F\001\000.66~\236\236\236\000\000\001\001\236\225\236\0206\18266\000\02964666A6>666.666N\208\208\208\144\208\000\020\020\020\020\1826566:6X6666\000\000\001\208\2083\208\208\208\208\208\208\208\208\208\255\255\255\001\000\016\020\020\012666\000 ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0/fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8P70= 0 -1 ++AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIPAgKAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISJBISAEASEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhICAgICAgICAgICAgICIiMELyTrJwQIKSorACw= 2 239 AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDwICgAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEiQSEgBAEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISAgICAgICAgICAgICAiIjBC8k6ycECCkqKwA= 786 \002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002\128\002\002\002\002\002\002\002\002\002\002\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018.\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\$\018.\000\@\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018.\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018.\018\018\018\018\018\018\018\018\018\018\018\018\018\018\018\002\002\002.\002\002.\002\002.\002\002.\"#./\$\235'.\008\)*+ ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9PgE/ 0 -1 ++AQAh5ifGs8kVxMsAAAHRAAABdwdle2FtcGxlA2NvbQAAGgABBHd3dzHAEA== 0 -1 ++P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fgF/ 0 -1 ++wMAAAcDgwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0s2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BHzY2PDY2JBU2NDY2MjY2NjY2AAw2NktLAAABARa+H0YUNjY2NgAANjZYNnY8NjY2NjYAAP4AATY2Njw2NiQVNgSzNqI2NjY2NgX//wVFNjk2PjYlPT09ATY2NgAAAAEANjQ2NjI2NjY2NgAQNjZLS0tAAAABSwE2vh9GFMAfNi5+7Ozs7AAAAezs7BQ2NjY2AAAAAAE2NjQ2NjZBNj42NjY2NjY2TtDQ0JDQABQUFBQ2NjU2NkM2WDY2NjZNNjZRABEBAA== 16 2 NjY2NgAQNjZLSzY2WDZ2PDY2NjY2AAABAAE2NjY8NjYkFTYEszaiNjY2NjYF//8FRTY5Nj42JT09PQEfNjY8NjYkFTY0NjYyNjY2NjYADDY2S0sAAAEBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAA/gABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAAATY2NDY2NkE2PjY2NjY2NjZO0NDQkNAAFBQUFDY2NTY2QzZYNjY2Nk02NlEAEQEA 523 666\000\01666KK66X6v<66666\000\000\001\000\001666<66\$\0216\004\1796\16266666\005\255\255\005E696>6%.==\001\03166<66\$\0216466266666\000\01266KK\000\000\001\001\022\190\031F\0206666\000\00066X6v<66666\000\000\254\000\001666.66\$\0216\004\1796\16266666\005\255\255\005E696>6%===\001666\000\000\000\001\0006466266666\000\01666KKK\@\000\000\001K\001.\190\031F\020\192\0316\.~\236\236\236\236\000\000\001\236\236\236\0206666\000\000\000\000\001664666A6>6666666N\208\208\208\144\208\000\020\020.\02066566C6X6666M66Q\000\017\001 ++P4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6SlpqeoqaqrrK2ur7CxsrO0tba3uLm6u7y9vgG/ 0 -1 ++P8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/gH/ 0 -1 ++A3c= 0 -1 ++5jrGq8kVxMt3ZS3RA3d3dwdl 12 -1 ++BAALBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9 64 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0rBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0= 32 -1 ++BAAEBQYHBAgJCgsEDA0ODwQQFBUWFysELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PQ== 16 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 8 73 BgcECAkKCwQMDQ4PBBAREhMEFBUWFwQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/AA== 159 \007\004\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++hAA= 0 -1 ++JAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2Nw== 0 -1 ++FAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCsELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PQ== 0 -1 ++DAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 DAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 224 \000\001\002\003\004\004\005\006\007\004\008\009.\011\004\012\013\014\015\004\016\017\018.\004\020\021\022\023\004\024\025\026\027\004\028\029\030\031\004\032!\".\004\$%&'\004\(\)*+\004,-\./\0040123\0044567\00489:\;\004<=>? ++BgABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BgABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 221 \000\001\002\003\004\004.\006\007\004\008\009.\011\004\012\013\014\015\004\016\017\018.\004\020\021\022\023\004\024\025\026\027\004\028\029\030\031\004\032!\".\004\$%&'\004\(\)*+\004,-\./\0040123\0044567\00489:\;\004<=>? ++BQABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BQABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 188 \000\001\002\003\004.\005\006\007\004.\009\010\011\004\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BEABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BEABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 183 \@\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BABBAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BABBAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 182 \000A\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAAhAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAAhAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 182 \000!\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABIgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABIgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 183 \000\001\"\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgMUBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXGwQcHR4fBCAhIiMEJCUmJwQoKSo= 0 -1 ++BAABAgMMBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMMBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 209 \000\001\002\003.\004\005\006\007\004\008\009\010\011\004\012\013.\015\004\016\017\018\019\004\020\021\022\023\004\024\025.\027\004\028\029\030\031\004\032!\"#\004\$%&'\004\(\)*+\004,-\./.0123.4567.89:\;.<=>? ++BAABAgMA 0 6 BAABAgMA 17 \000\001\002\003 ++BAABAgMEAAgJCg== 0 -1 ++BAABAgMEBAUGBwYICQoLBAwNDg8EEAQYGRobBBwdHh8EICEiIwQrBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 0 -1 ++BAABAgMEBAUGBwQIKQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQIKQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 183 \000\001\002\003.\004\005\006\007.\008\)\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLFAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLFAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 209 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015\004\016\017\018\019\004\020\021\022\023\004\024\025\026\027\004.\029\030\031\004\032!\"#\004\$%&'\004\(\)*+\004,-\./\0040123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLBAwNDg8AEA== 0 21 BAABAgMEBAUGBwQICQoLBAwNDg8A 68 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBRgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBRgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 200 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027\004.\029\030\031\004\032!\"#\004\$%&'\004\(\)*+\004,-\./\0040123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGjsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGjsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 183 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\;.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgIaIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgIaIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 187 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\162#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjJA== 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjAA== 0 46 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjAA== 145 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"# ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgJCUmJw== 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwAsLQ== 0 56 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwA= 158 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+ ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBA== 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vADA= 0 61 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vAA== 164 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./ ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMA 0 66 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMA 169 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEAQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwY8PQ== 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8B 0 -1 ++BAAEBQYHBAgJCgsEDA0ODwQQERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 6 71 BAgJCgsEDA0ODwQQERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 151 \008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 3 78 AgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 176 \003\004.\005\006\007\004.\009\010\011\004\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++NAABAgMEBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9 0 -1 ++HAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9 0 -1 ++CAABAgMEBAUGBwQICQoLBAwNDg8EEAQYGRobBBwdHh8EICEiIwQrBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 0 -1 ++AgABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 AgABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 185 \000\001.\003\004.\005\006\007\004.\009\010\011\004\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgM0ERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0= 0 -1 ++AQABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 AQABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 182 \000.\002.\004\004\005.\007\004\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgMmBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMmBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 227 \000\001\002\003.\004\005\006\007\004\008\009\010\011\004\012\013\014\015\004\016\017\018\019\004\020\021\022\023\004\024\025\026\027\004\028\029\030\031\004\032!\".\004\$%&'\004\(\)*+\004,-\./\0040123\0044567\00489:\;\004<=>? ++BAQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELC0uHB0eHwQgISIjBCQlJicEKCkqKwQsLS45BDAxBCAhIiMEJAAB 0 -1 ++BAABAgMEDA0ODwQQERITBBQVFhcEGBkaGwQcLx4fBCAhIiMEJCUmJwQoKyorBA== 0 -1 ++BAABAiAEBAUGBwQICQoLBAxkAA8EEBEeHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDxvPj8A 0 66 BAABAiAEBAUGBwQICQoLBAxkAA8EEBEeHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDxvPj8A 131 \000\001\002\032.\004\005\006\007.\008\009\010\011.\012d\000\015.\016\017\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.? ++BAAkdXV1dR0pELsELC0uPBgZGhsEHgkJ2gEBAmQEBAeAABogBCkJCdonBBQVPUAEGBkaGwQpGgAEKAkJ2gQWJRfaGxITBAEVFgBAGCQwGwT5HClHuwQsLS48GBkaGwQpCQnKARKKBJ2dnZ2dnZ2dnRgsLUAEGCwtLgA= 2 -1 ++BAABAgMEBEAADQ4PBBAREhMEFBUWFwQYGRobBAQgISIjBA8lJicczx4fBCAhIiMEJCUmLwQwMS8EMDEyMww0NTQ3BDg5GwQmJ/UnNjcEODkyMww0NzY3BDg5GwQmJ/UnNjcEODk6OwQ6OwQ8PT4/AA== 0 112 BAABAgMEBEAADQ4PBBAREhMEFBUWFwQYGRobBAQgISIjBA8lJicczx4fBCAhIiMEJCUmLwQwMS8EMDEyMww0NTQ3BDg5GwQmJ/UnNjcEODkyMww0NzY3BDg5GwQmJ/UnNjcEODk6OwQ6OwQ8PT4/AA== 261 \000\001\002\003.\004\@\000\013.\015\004\016\017\018\019\004\020\021\022\023\004\024\025.\027\004\004\032!\"#\004\015%&'\028\207\030\031\004\032!\"#\004\$%&/.01/\004.123\0124547\00489\027\004&'\245'67\0048923\0124767\00489\027\004&'\245'67\00489:\;\004:\;.<=>? ++BAABAgMEBAUiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEOAYHBAgJCoAEDA0ODwQQERITBBQFFhcEGBkaGwQcHR4fBKAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 0 110 BAABAgMEBAUiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEOAYHBAgJCoAEDA0ODwQQERITBBQFFhcEGBkaGwQcHR4fBKAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 222 \000\001\002\003.\004\005\"#.\$%&'.\(\)*+.,-\./.0123.4567.8\006\007\004.\009\010\128\004\012\013\014\015.\016\017\018\019.\020\005\022\023.\024\025\026\027.\028\029\030\031.\160!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BCorBCwtLjL79Pv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+3sEPD0VFhcEGBka0yYMHR4mBCAhIiO0ELS0trTFtLS0tLS09rS0tCsELC0uLQAEAAB/AAA= 4 82 LC0uMvv0+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7ewQ8PRUWFwQYGRrTJgwdHiYEICEiI7QQtLS2tMW0tLS0tLT2tLS0KwQsLS4tAAQAAH8AAA== 270 -\.2\251\244\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251\251{\004<=\021\022\023\004\024\025\026\211&\012\029.&\004\032!\"#\180\016\180\180\182\180\197\180\180\180\180\180\180\246\180\180\180+\004,-\.-\000.\000\000\127\000 ++BAABAh0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dAwQEBQYHBAgJCgsEDP0NDwQQERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKTY3BDg4OjsEPD0+PwA= 0 98 BAABAh0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dAwQEBQYHBAgJCgsEDP0NDwQQERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKTY3BDg4OjsEPD0+PwA= 321 \000\001\002\029.\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029.\003\004\004\005\006\007\004\008\009\010\011\004\012\253\013\015\004\016\017\018\019\004\020\021\022\023\004\024\025.\027\004\028\029\030\031\004\032!\"#\004\$%&'\004\(\)67\00488:\;.<=>? ++BAABAgMEBAUGBwQAAAEABAwNDhQEEBESEwQUNBYXBAcH5wYHogcHBw0HBwcHBwcAEAcHBwcigDUzNjcEODk6OwQ8UT4/AA== 0 70 BAABAgMEBAUGBwQAAAEABAwNDhQEEBESEwQUNBYXBAcH5wYHogcHBw0HBwcHBwcAEAcHBwcigDUzNjcEODk6OwQ8UT4/AA== 200 \000\001\002\003.\004\005\006\007.\000\000\001\000.\012\013\014\020.\016\017\018\019.\0204\022\023.\007\007\231\006.\162\007\007\007\013\007\007.\007\007\007\000\016\007\007.\007\"\1285367.89:\;.? ++DQ4EAAHlDQQEBQYBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBBAgJAA4PAwAAGRobBCchHB0eHwQgISIjBCQlJiciIwQkJSYnBCj+3vH+/u7+/v7+BCQlJichIiME/h7//t7+3/7+/v7+/v7+/v7+BAg/AA== 0 118 DQ4EAAHlDQQEBQYBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBBAgJAA4PAwAAGRobBCchHB0eHwQgISIjBCQlJiciIwQkJSYnBCj+3vH+/u7+/v7+BCQlJichIiME/h7//t7+3/7+/v7+/v7+/v7+BAg/AA== 354 \014\004\000\001\229\013\004\004\005\006\001\001\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\001.\004.\009\000\014\015\003\000\000\025.\027\004'!\028\029\030\031\004\032!\"#\004\$%&'\"#\004\$%&'\004.\254\222\241\254\254\238\254\254\254\254\004\$%&'!\"#\004\254\030\255\254\222\254\223\254\254\254\254\254\254\254\254\254\254\254\004\008? ++BAAIAgMEBwQsLS4vBC0xCAkKCwQMDQ4PfxA3BDgEAAgCAwQHBDwtLjIzBDQ1NggJCgsEDA0OD38QNwQ/OTotLkYELTEyNggJCgsEDA0OD38QNwQ4BAAIAgMEBwQsLS4vBC0xMjMENDU2CAkKCwQ5OjsEPEg+Pw== 0 -1 ++BAABAgMEBAUGBwLrCQoFBgcD6wkKCwQMDQ7//xAREhMEFBUWFwQYGRob 0 -1 ++BAAP/wAXBBgZGhsEHB0eHwQOIZgAIvQJ//8WGRcXFxcXFxcXFxwlF/oXICEiEAxAABcXFxcXFxcXFxcX/xcXFxccJQxAABcXFxcXFxcX 0 -1 ++DAAB/AMEBAUGBwQICQoLAwxADg8EEBESEwQkJSYnBCgpKisELC1ADg8EBgcECAxADg8TBBQiIwQkJSY5OjsEPD0+ 0 -1 ++BH8PEhMEIn4EABD/BCEiIwQkJSYADg8EBEwSEwQiIwQADf8EAXUjBA0ABCIjBAAQ/wQhIiNVDQ4PBgQPEhMEFCMk+gAA+i4AAAADQAAAAC4uLi4uLi5PLi4uLi4uLi4jAAACAAAO 0 101 BH8PEhMEIn4EABD/BCEiIwQkJSYADg8EBEwSEwQiIwQADf8EAXUjBA0ABCIjBAAQ/wQhIiNVDQ4PBgQPEhMEFCMk+gAA+i4AAAADQAAAAC4uLi4uLi5PLi4uLi4uLi4jAAACAAA= 289 \127\015\018\019.\"~\004\000.\255\004!\"#\004\$%&\000\014\015\004\004L\018.\004\"#\004\000\013\255\004\001u#\004\013\000\004\"#\004\000.\255\004!\"#U\013\014\015\006\004\015\018\019\004\020.\$\250\000\000\250\.\000\000\000\003\@\000\000\000\.\.\.\.\.\.\.O\.\.\.\.\.\.\.\.#\000\000\002\000 ++BAAYGRoCAgICAgICAgICAgIC 0 -1 ++BBwBAhwBBQYAABAACgsEDA0OFwMUBAUGAAAQAAoLBAwNDicEKD8qKwQsMjMENA== 0 -1 ++BAABAvsEBDQmNjcEAEA6O6GhoZ2hoaGhoakhoaGhoaEEPD0FHQcECAkKCwB/DQ4uBBAREhMEFBUWFwQYGAACAAAdHh8EICljAAAAADEySwQ0NTY3BABAOjsEPD1APwQ8PT4= 0 -1 ++BP9/AgMEBAUGBwQICQoLBAwNDg8EEBESEwQEGRobBBwdHh8EICEkJSYnMzMzMzMzMzMzMzMzMysELC0uLwQwMTIzBDQ1NjcEODktOwQ8PT4/AA== 0 -1 ++DQ4PBAgICgtADA0ODwQICQoLAAD//w8EBF4GBwwABF4GBwwNBg8EBBMEBv8ICQoDQAQTBgcEDwQICdsLQAwzBDRONjcEOA== 12 -1 ++BAABAgMEBDAxMjMENCwtLi8EBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgAAIAAHF2hHyEiIwQkJTEnBCgpKisELC0uLwQwMTIzBDQsLS4vBDAxMjMENDU2NwQ4OTpkNjcEODk6OwQ8PQ== 0 -1 ++A+cBAgMEBCkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKQcECAkKISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OVc7BDw9PgA= 0 -1 ++BAABAhERAwQEBQYHBCEJCAghCQgICAgJCAgI7REICAAICAgICAiICAgICAgICAgICAgICAoLBAwNDg8EBhESEx0UFRYXfyX/JwQoKSorBCwtLi8EMDEyMwQ0NTw9Pg== 0 -1 ++BAABAgMEBQUG5gMI5ycLBAwNDg8EyxG6EykRHQEBAQEBAQEBAQEBAQEBAQEBAQEBAQF/auUs 0 -1 ++CgsjFSQlJicEKCkqKwQsNDQAEDcUFRYX/wAAABsEHB0bBBwdHh8EICEiIxUkAAAbFhcEMTIzBDQAEBsEHB0eHwQgMwQ0NQ== 0 -1 ++BAABAgMEBAUGBwQI7AoLBAwNDicEEBESEwQUFRYXBAYZGhsEHB0eIgQgISIjAj4/AA== 0 49 BAABAgMEBAUGBwQI7AoLBAwNDicEEBESEwQUFRYXBAYZGhsEHB0eIgQgISIjAj4/AA== 143 \000\001\002\003.\004\005\006\007.\008\236\010\011.\012\013\014'.\016\017\018\019.\020\021\022\023.\006\025\026\027.\028\029\030\".\032!\"#.>? ++BBABAgMsLS4A/zA0MvoAAPo2NwQ4PD03PwAEJwQoKR0eHwQg//8aGwABHR4fBCA2IiMEJCUmJwQoKQACEu4rLS4vBDCysn8ENDU2NwQ4ORUWFwQgISIjBCSyBDQ1NjcEODkVFhcGGBkaGwQwMDAwMCoqKioqKioqKiogKioqKioqKioqKioqKioqJSYnBCgpHR4fBCD///+APT5BAA== 0 -1 ++BBABggMEBAUG6wQICQoLBAxuBBQtLiBQMwQzNTY5BDgeOTsEUFEENDUpNwQ4ADkEMDFQKhcELC0uIAQwMVAzBAQzNTY0NQ== 0 -1 ++GQABAgMEBAUGBAIWCwQL8Q8EChESEwYUFRYXpQIDBAQFBgQIFgsEC/EPBAoREhMGFBYXpRgZGhvuHB0dHh7iPQ0ODwQQERITBhQV+gAAdHB0dOICBBwdQIAAKwQsLS6jvzA= 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEDh0eHwQgISIjBAICAgICAgICAgICAgICAgICAgICAgICAjsEPD0= 0 -1 ++BAABAgMEBAX0BgQICf9/BAwNEg8EEBESEwQUFRYXBBgZGhsEFB0eHwQgKSIjBCQk6ycECCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAX0BgQICf9/BAwNEg8EEBESEwQUFRYXBBgZGhsEFB0eHwQgKSIjBCQk6ycECCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 192 \000\001\002\003.\004\005\244\006.\008\009\255\127.\012\013\018\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\020\029\030\031.\032\)\"#.\$\$\235'.\008\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAGQEBAUGBwQICQouLwQwMTIzBDQAgAAASzk6OwQ8PT4EGBkaGwQcHR4fBCAhIyMKJCUmJwQoKSo4BCYtLi8EMDEyMuI0NTYEJi0uLwQwMTIzBDQAAAABAAA6OwQ8PT4/BDcEODk6Oys8PT4/BA== 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESKQQUFRYXBBgZGigEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLBAwNDg8EEBESKQQUFRYXBBgZGigEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 181 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\).\020\021\022\023.\024\025\026\(.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAABAgICAgICAgICLhwEMDEyMwICAgICAgQUFRYXAgICAgICAgICAgICAgICAgICAgICAgICAgICAi4cBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgICAgICAgICLhwEMDEyMwICAgICAgQUFRYXAgICAgICAgICAgICAgICAgICAgICAgICAgICAi4cBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 191 \000\001\002\002.\002\002.\002\002.\.\028.0123.\002\002.\002\002.\020\021\022\023.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\.\028.0123.4567.89:\;.<=>? ++BAABAgMEBAUGBwQICQoLBAwNDgICAgICAicEKCkqKwQsLS4vBDACAgICAgICAgICAicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAgMEBAUGBwQICQoLBAwNDgICAgICAicEKCkqKwQsLS4vBDACAgICAgICAgICAicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 168 \000\001\002\003.\004\005\006\007.\008\009\010\011.\012\013\014\002.\002\002.\002'.\(\)*+.,-\./.0\002\002\002.\002\002.\002\002.\002'.\(\)*+.,-\./.0123.4567.89:\;.<=>? ++BAAYDQ4PBBAREhMBjAMEBAUGDQ4PBBAREhMEFBUWEwQUFRYXBBgZGhsEkx0eHxobBJMdDB8EICEiIwQ2NDUEkx0eDg8EEBESEwQEGBkaGwSTHQ== 0 -1 ++ZAENAWQBDQAA/w== 1 7 AQ0BZAENAA== 12 \013.d.\013 ++BAQIIwoLDwQQEeQcPx4fBCAhIiMEJCUmJx8FIAQoKSorBCwhLi8EMB0yD6cQEcscPx4fBCA+IiMEJCUmJx8EFd4oKSorFCcEGSkqKwQsLTcEODk6OwQ8BwQYBxobBBwdHg/HEBES 3 -1 ++wAADJRoVHignKiuALC1AAAAABCBNLn////97fwAcPj+A 0 -1 ++BAARAgMEBAUGBwQICQrvAwgJCsAEDBcEGAQMDQ4PBBAdHh8EICEiIwQkJSYnBCgpKisELC0uLwQwMQAAEQIDBAQFBgcECAkK7wP/BDQ1NjcEODk6OwQ8PT4/ 0 -1 ++BAABAgMEBAAGBwQICQoLBAwNDg8EEBESKAQUFRYXBBgZGhsEHB0eHwQgISIrBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwQ4OTo7BDw9AEAA 0 81 BAABAgMEBAAGBwQICQoLBAwNDg8EEBESKAQUFRYXBBgZGhsEHB0eHwQgISIrBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwQ4OTo7BDw9AEAA 185 \000\001\002\003.\004\000\006\007.\008\009\010\011.\012\013\014\015.\016\017\018\(.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"+.,-\./.0123.4567.89:\;.<=>?.89:\;.<=\000\@ ++BAABAgMEBAUGBwQICQoPDwQQFBUWFwQYGRobAQEBAQEBAQEBBBwdHh8EICEiIwQkJSYnBCgpKisELC0uL////38zBDQ1NjcEPBA+P0A= 0 -1 ++BA8EAgAsAID/////MjMEMjU2NwMEFgUEBf//9BEAHALNBAb/f0AA6iAEICEiIwQkJSYn+vr6+vr6BPYGACQICQoQAiADvQABEgMEBAUEBQYHBEAA6iAEICEiIwQkJSYn+vr6+vr6+vr6+vr0BBIdLC0u9gQwMSgMBwRkAAAgBEQAIAQgISI= 0 -1 ++BAABAgMEBAUGBwQICQoLBBobBBwdHh8EICEiIwQkJSYnBCgpKisELDEyMwQ0NTY3BAACOjsEPHI+OwQ8PT4/AA== 0 64 BAABAgMEBAUGBwQICQoLBBobBBwdHh8EICEiIwQkJSYnBCgpKisELDEyMwQ0NTY3BAACOjsEPHI+OwQ8PT4/AA== 147 \000\001\002\003.\004\005\006\007.\008\009\010\011.\026\027\004\028.\030\031\004\032!\"#\004\$%&'\004\(\)*+\004,123\0044567\004\000.:\;.\;.<=>? ++wAABAgMEERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJ/snKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwA= 0 -1 ++BB4fBAQcKSkpKSkpKSkpKSkpKSkpKRMpKSkpBCAhDyMEJCUmJwQ= 0 -1 ++AgAAAhAiAhAiFvQAzwACECICECIW9ADpFvQW9ADpA/QAzw== 0 33 AgAAAhAiAhAiFvQAzwACECICECIW9ADpFvQW9ADpA/QA 108 \000\000.\016\".\016\".\244\000\207\000\002\016\"\002\016\"\022\244\000\233\022\244\022\244\000\233\003\244 ++BAABFwMEBAUWFwQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELDsuLwQgISIjBCQlJicEKCkqKwQsOy4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABFwMEBAUWFwQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELDsuLwQgISIjBCQlJicEKCkqKwQsOy4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 147 \000\001\023\003.\004\005\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,\;\./.\032!\"#.\$%&'.\(\)*+.,\;\./.0123.4567.89:\;.<=>? ++BAABAQEBAQEBAQEBAQoL9gwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJieuDCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 81 BAABAQEBAQEBAQEBAQoL9gwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJieuDCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 214 \000\001\001\001.\001.\001.\001.\001.\011\246\012\013\014\015\004\016\017\018.\004\020\021\022\023\004\024\025\026\027\004\028\029\030\031\004\032!\".\004\$%&'\174\012\)*+\004,-\./\0040123\0044567\00489:\;\004<=>? ++BBgZKhsEHIAAHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMgICAgICAgIC 0 -1 ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0/fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8P70= 64 -1 ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0Afg== 0 129 PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0A 235 \000\001\002\003\004\005\006\007\008\009\010\011\012\013\014\015\016\017\018\019\020\021\022\023\024\025\026\027\028\029\030\031\032!\"#\$%&'\(\)*+,-\./0123456789:\;<=>.?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|} ++PwAhIiMFJSZZKAPoKzQtLi0wMTIzSTU2Nzg5OjsSPT4/PwECy8vLy+fnntTn5wQBBgcILy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL38jBSUmWSgD6Cs0LS4tMDEyMzRGR0hJSktMTYODgwUGBwgJCgsMDQ4PEBETFEAADw== 0 -1 ++wACQkAQAJiYmJiYmJiYmJiYi 0 -1 ++AgBAAhAiAhAiFvQAzwACECICECIW9ADpFvQW9ADpA/QAzw== 0 33 AgBAAhAiAhAiFvQAzwACECICECIW9ADpFvQW9ADpA/QA 106 \000\@.\016\".\016\".\244\000\207\000\002\016\"\002\016\"\022\244\000\233\022\244\022\244\000\233\003\244 ++AgAAAgEiAhAiFusCzwACECICZCIW9A/pFvQW9ADpAwACASICECIW6wLPAAIQDQJkIhb0D+kW9Bb0AOkDJQA= 0 62 AgAAAgEiAhAiFusCzwACECICZCIW9A/pFvQW9ADpAwACASICECIW6wLPAAIQDQJkIhb0D+kW9Bb0AOkDJQA= 200 \000\000.\001\".\016\".\235\002\207\000\002\016\"\002d\"\022\244\015\233\022\244\022\244\000\233\003\000.\001\".\016\".\235\002\207\000\002\016\013\002d\"\022\244\015\233\022\244\022\244\000\233\003% ++AgABAQEBAQEBAQIBAQEBAQEBAQEBAQ== 0 -1 ++AgACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL0 0 -1 ++AgAAAhAiAQEBCQEBAQACENQBAQEBAQEBAQEBAWQBAAEBAgEBAQEBKSkp 0 -1 ++AgABAQEBAQEBAQEBAQECAQACAAACECIBAQEBAQEBAQEBAQEBAQE= 0 -1 ++AgAAAhAiAgAAAhAiAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQIBVwEBAQEBAQEBAQECAVcBAQEBAQEBAQEBAQECAVcBAQEBAQEBFAE= 0 -1 ++BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwTgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8A 0 81 BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwTgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8A 88 \@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ[.\\]^_.\224abc.defg.hijk.lmno.pqrs.tuvw.xyz{.|}~\127 ++BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawBsbQ== 0 56 BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawA= 57 \@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk ++BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fj8A 0 81 BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fj8A 82 \@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk.lmno.pqrs.tuvw.xyz{.|}~? ++PwABAgMEBQYHCAmztLUAABYXGBmInAoLDA0ODyQRNDU2NwE5Ojs8PT4/PwkKCwwNDg8kSwoLDA0ODyQpKSkpKSkpPT4/VTAxMjM0NDY3AYeLjKqObB0eHyB9KSkpKSkpKWQnKCkqKykJKSkpKSkpKSkpKSlkJygpKissLS48PT4/P0BBQkNERUYvMDEyMzQ0NjcBigQArK2urw== 0 -1 ++PwABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyTsJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNLVVZXWFlaW1xdXl9gYWJjZGVmZ2hpMDAwMDEwMDAwMDAwME0wMDAwMDAwMDAwMDAwMDAwMGprbG1ub3BxcnN0dXZ3eHl6ewh9P35/gIGCg4SFhoeIiYo7PD0+Pz9AQUJLTE1OT1BRUouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqMgpaanqKmqq6ytrq+wsbKztLW2t7i5uru8P70= 0 -1 ++KCgoKCgoKDkQgAQwQDJDxsbGyP9EKsbG1sbGxsbGxsbGyP8qxkAqKioqKioqKMbGzcbG1v8qKsbG1sbGxsbGxsbGyP8qKkAqKioqKioqQSoqACgTExMTExMTExMTExMTExMTExMTExMTExMTExMTKioMKioqKir/ACroAyoq 0 -1 ++BAwDAwMDA+gCAwMDAwMDAwMDAwP6A+gCAwMDAwMDAwMDAwP6AAA= 0 38 BAwDAwMDA+gCAwMDAwMDAwMDAwP6A+gCAwMDAwMDAwMDAwP6AAA= 121 \012\003\003\003.\003\232\002.\003\003\003.\003\003\003.\003\003\250.\232\002\003.\003\003\003.\003\003\003.\003\250\000 ++BAABAh0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dAwQEBQYHBAgJCgsEDP0NDwQQERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKTY3BDg4OjsEPD0+P8A= 0 -1 ++//8FDgMEBwQsLS4nBC0AEwIQAAcAAH/fMjMENDU2CAkKTy4gAB8ANgQsLS4vBAcAAH/fMjMENDU2CCAAHwA2BCwtLi8eBC4gAB8ANgQsIAAfAC4vBH8QHgQ/OTpPLiCVlZWVlZWVlZWVlZWVlZWVlZWV 5 -1 ++FgAAEAAnBCgpKisELC0uEdkuEQYDBCEJCAghCQgICBgJCAgIAwIICAAICAgIAAkICCEJCAgIGAgICO0RCAgACAYIFAgICIYICAgICO0RCAgACAYIFAgPBAYREhMdag== 0 -1 ++BA8ICAgEBAUG6wQICQoLBAxuJSY2BBAAAAAEFC0uIFAzBDM1NjkEOB45OwRQUgQ0NSk3BDgAOQQ1NjkEOB45OwRQUQQ0NSk3BDA0UCoX 0 -1 ++PwABFwMEenp6enp6enp6enp6enp6enp6enp6enp6enp6enp6IyQlJicoKSorLC0uLzAxMjM0ACAzODk6Ozw4Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaAVxdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0Afg== 0 129 PwABFwMEenp6enp6enp6enp6enp6enp6enp6enp6enp6enp6IyQlJicoKSorLC0uLzAxMjM0ACAzODk6Ozw4Pj8/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaAVxdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0A 159 \000\001\023\003\004zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz#\$%&'\(\)*+,-\./01234\000\032389:\;<8>.?\@ABCDEFGHIJKLMNOPQRSTUVWXYZ\001\\]^_`abcdefghijklmnopqrstuvwxyz{|} ++PwDuAQMEBQYHCAl8fHx8fHx8fHx8fHx8fHx8fHx8fHx8ICEiIyQlJjU2Nzg5Ojs8ICEiIyQlJjU2Nzg5Ojs8PT4/P0BBQkNEVHx8fHx8fHx8fHx8fHx8fHx8fHx8fCAhVVZXWFlaW1xdXl9gABBjZGVwcXJzdHV2QAAAAHt8fQB+ 0 128 PwDuAQMEBQYHCAl8fHx8fHx8fHx8fHx8fHx8fHx8fHx8ICEiIyQlJjU2Nzg5Ojs8ICEiIyQlJjU2Nzg5Ojs8PT4/P0BBQkNEVHx8fHx8fHx8fHx8fHx8fHx8fHx8fCAhVVZXWFlaW1xdXl9gABBjZGVwcXJzdHV2QAAAAHt8fQA= 190 \000\238\001\003\004\005\006\007\008\009||||||||||||||||||||||\032!\"#\$%&56789:\;<\032!\"#\$%&56789:\;<=.??\@ABCDT|||||||||||||||||||||\032!UVWXYZ[\\]^_`\000\016cdepqrstuv\@\000\000\000{|} ++wACQmAQA 0 -1 ++ARABIQEiAYABJAElASYBJwEoASkBKgEaARsBHAEdAR4BHwEgASEBIgGAASQBJQEmAScBKAEpASsBLAEtAS4BNwE4 0 -1 ++AQABAwEEAQUBBgEnASgBKQEqASkBKgErASwBLQEuATcBOAE5AToBOwE8AT0BKwEsAS0BLgE3ATgBOQE6ATsBPAE9 0 -1 ++A98BAgMEBCkpKCkpKSkpKSkpKSkpBikmKSkrKSkpICkpKSkpKQEnBCgpKSkpKSkpKSkGKSYpJDMENA== 0 -1 ++A2QBAgMEBCkpKSkpKSkpKSkpKSkpKQQEKSkpKSkpKSkpKSkpKSkpKSkMKSkpKSkpKSkpKSkpKSkpKCkHBAgJCiFAKSkpKSkpKSkpKSkpKQcEKSkpKSkpKSkpKTcEODlXOwQ= 0 -1 ++BBABAgMsLS4A/yoqMgUAAH82NwQ1NjcEODwVFhcGGBkaG/0vEQYYIgQoKQACEu4rLS4vBDCysioqKiAqKio2MC4wKioqKioEIEciIwQkCCYnKQoCEu4rLS4vBDCysgRFKQACEu4rAwAAfyoqICoCEu4rLS4BADCysioqKiAqKioqJSoqKioqKioqEiolJicEPCk= 0 -1 ++AUABRQFGAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFfAWABYQFiAWMBZAFlAWYBZwFoAWkBagFrAWwBbQFuAW8BcAFxAXIBcwF0AXUBdgF3AXgBeQF6AXsBfAF9AX4BfwA= 64 37 AW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AA== 39 n.o.p.q.r.s.t.u.v.w.x.y.z.{.|.}.~.\127 ++BAAEBQYHBAgJCgsEDA0ODwQQERITBBQVFhcEGBkaGwQcHSEiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChoqMEpKWmpwSoqao= 32 -1 ++BAAEBQYHBAgJCgsEDA0kJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChoqMEpKWmpwSoqao= 8 -1 ++BAABAgMEBAUGBwQICQocHR4fBCAhIiMEJCUsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXV5fBGBhYmMEZGVmZwRoaWprBGxtHh8EICEiIwQkJSYnBCgpKisELC0uLwSAgYKDBISFhocEiImKiwSMjY6PBJCRkpMElJWWlwSYmZqbBJydnp8EoKGiowSkpaanBKipqqsErK2urwSwsbI= 0 -1 ++BAAEBQYHBAgJCgsEDA0kJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEgAA6OwQ8PT4/BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgNTY3BDg5OjsEPD0+PwRAQUJDBERFRkcEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChoqMEpKWmpwSoqao= 8 -1 ++BAAEBQYHBAgJCgsEDA0kJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT5fBGBhYGMEZGVmZwRoaWprBGxtbm8EcHFycwR0dVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHBIiJiosEjJGOjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChoqMEpKWmpwSoqao= 8 -1 ++BOgCAwMD+gPoAgMDAwMDAwMDAwMD+gAMAwMDAwPoF+gCAwMDAwMDA+ICAwP6AAADAwMDAwMDAwMDA/oD6AIDAwMDAwMDAw== 0 -1 ++BOj6A+gCAwMDAwMDAwMDAwP6AAwDAwMDA+gX6AIDAwMDAwMD4gIDA/oAAAMDAwMDAwMDAwMD+gToAgMDA/oD6AIDAwMDAwMDAwMDA/oADAMDAwMD6BfoAgMDAwMDAwPiAgMD+gAAAwMDAwMDAwMDAwP6A+gCAwMDAwMDAwMSAwP6A+gCAwM= 0 -1 ++BOj6A+gCAwMDAwAMAwMDAwPoF+gCAwMDAwMDA+LwAwP6AAADAQMDA/oD6AIDAwPoF+gCAwMDAwMDA+LwAwMDAwMD+gMDAwMDAwMDAwMD+gAMAwMDAwPoF+gCAwMDAwMDA+LwAwP6AAADAwMDAwMDAwMDA/oD6AIDAwMDAwMDAwMDAw== 0 -1 ++BOgDAwgICAgICAgICAgICAgICAgICAgBCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICHQICAgICAEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIdAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI 0 -1 ++BOgCFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFQMDAwMDAwMJ+gPoAgPwAgM= 0 -1 ++GxsbGxsAGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsVGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbAxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGyYbGxsbGxsbGxsbGxsbGxsbGxsb 27 -1 ++BOgCAwMD+gPoAgMDAwMADAMDAwMD6BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAE6AQDAwP6A+gC 0 -1 ++BOgCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC 0 -1 ++BOgDAwgIDAgICAjvCAgICAgIAgjCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCAMLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwuXCwsLCwsLCwsLCwsLCwsLCwsLCwsK6wsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCssLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCqMLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwggICAEICAgIf3QICAgICAEICAfwCAgICAgIB+8IEwgIgAgICB8ICAgICBgICAgICAgSCAgICAgICAgICAgICAgfJoAICAgICAgICACAAAAF/+kFCH8ICAgICAgICAgICHQICAgICJwIwqrCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwtLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCpcLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsIICAgBCAgICH90CAgICAgBCAgH8AgICAgICAfvCAgICIAICAgfCAgICAgYCAgICAgIEggICAgICAgICAgICAgH8AgICAgIAQgIB/AICAgICAgICAgICAjwCAgIHwgICAgIGAgICAgICBIICAgICAgICCAACAgICAgICAgICAjeCAgICAgICAgICAgICAgFHyYICAgICAgICAgAgAAABf/pCFpaWlpaWlp6WlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWggICAgBCAgH8AgICAgICAgICAgICPAICAgfCAgICAgYCAgICAgIEggICAgICAgICAgICAgICAgICAgICN4ICAgICAgICAgICAgICAUfJggICAgICAgICACAAAAF/+kIWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpahoaGhoaGhoaGkIaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGf4aGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaWlpaTlpaWlpaWlpaWlpaWlpaWlpaWlpaWggICAEICAfwCAgI///CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwgAACAgH8AgICP//AAAICAgI+QcICAgICAUICAgICAgICAgICAgICAgICAgICAgICAgICAgI//8AAAgICAgICAgICAgIBQgICAgICAgICAgICAkICAgICAgICAgICAgIDA== 0 -1 ++BOgDAwgIFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcCFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXAAADFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFwgI 0 -1 ++BOg6OjoIOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Mzo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo= 0 -1 ++BOgDAwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAgQEBAQEBA== 0 -1 ++BOgDAwgINjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjaeNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Np42NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY= 0 -1 ++AQABAQECAQcBCAEJAQoBCwEMAQECAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARkBGgEbARwBHQEeAR8BIAEjASQBJQEmAScBKAEpASoBKwEsAS0BLgE3ATgBOQE6ATsBPAE9AT4BPw0BDgEPARABEQESARMBFAEXBRgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgE3ATgBOQE6ATsBPAE9AT4BPwA= 0 185 AQABAQECAQcBCAEJAQoBCwEMAQECAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARkBGgEbARwBHQEeAR8BIAEjASQBJQEmAScBKAEpASoBKwEsAS0BLgE3ATgBOQE6ATsBPAE9AT4BPw0BDgEPARABEQESARMBFAEXBRgBGQEaARsBHAEdAR4BHwEgASEBIgEjASQBJQEmAScBKAEpASoBKwEsAS0BLgE3ATgBOQE6ATsBPAE9AT4BPwA= 387 \000.\001.\002.\007.\008.\009.\010.\011.\012.\001.\001\011.\012.\013.\014.\015.\016.\017.\018.\019.\020.\021.\022.\025.\026.\027.\028.\029.\030.\031.\032.#.\$.%.&.'.\(.\).*.+.,.-.\..7.8.9.:.\;.<.=.>.?.\001\014\001\015\001\016\001\017\001\018\001\019\001.\001\023\005\024\001\025\001\026\001\027\001\028\001\029\001\030\001\031\001\032.!.\".#.\$.%.&.'.\(.\).*.+.,.-.\..7.8.9.:.\;.<.=.>.? ++AQABAQECAQMBBAEFAQYBJwEoASkBKgEpASoBAQIBOQE6ATsBKwEsAS0BLgE3ATgBOQE6ATsBLQEuATcBOAE5AToBOwE8AQ== 0 -1 ++BAABAgMEAAAEAAQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BEBBQkMEREUwRwRISUtLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnaGiAAA= 0 241 BAABAgMEAAAEAAQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BEBBQkMEREUwRwRISUtLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnaGiAA== 438 \000\001\002\003.\000\000\004\000.\008\009\010\011.\012\013\014\015.\016\017\018\019.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>?.\@ABC.DE0G.HIKK.LMNO.PQRS.TUVW.XYZ[.\\]^_.89:\027.<=>?.\@ABC.DE0G.HIKK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk.lm\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.\128\129\130\131.\132\133\134\135.\136\137\138\139.\140\141\142\143.\144\145\146\147.\148\149\150\151.\152\153\154\155.\156\157\161\162 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFRkcESElKSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EYGFiYwRkZWZnBGhpamsEbG0eHwQgISIjBCQlJicEKCkqKwQsLS4vBICBgoME+oWGhwSIOwQ8PQ== 0 -1 ++BAABAgMEBAgJCgsEDA0gISIjMDEyMwQ0NTY3BDg5OjsEPD0iIwQkJSYnBD8pKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/BEBFRkcESElKSwRMTUNPBFBRUlsEVFVWVwRYWVpbBFxNXl8EYGFiYwRkZWZnBGhpamsEbG0eHwQgISIjBCQlJicEKCkqKwQsLScvBICBgoME+oWGhwSIiYqLBDQ1NjcEODk9Pj8E 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmBwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFRkcESElKSwRMTU5PBFBRUlMEVFVWVwRYWVpbBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUOwQ8PQ== 0 -1 ++AgAAAhBiAgAAAhAiAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQIBVwEBAQEBAQEBAQECAVcBAQEBAQEBAQEBAQECAVcBAQEBAQEBFAE= 0 -1 ++AykpKSkpKSkpKQQEKSkpKSkpKSkpKSkpKSkpDCkMKSkuKSkpKSkpKSkpKSkpKCkG9QgJCiFAKSkpKSn/KSkpKSkAAAEpKQcEKSkpKSkpKSkpKSkpKSkpKQwpKSkpKSkpKSkpKTsEQAApKSkpKCkG9QgJCiFAKSkpKSn/KSkpKSkpKQcEKSkpKSkyKSkpKbckODlXOwRAAD4pBwQgHCkpKSkA 0 162 AykpKSkpKSkpKQQEKSkpKSkpKSkpKSkpKSkpDCkMKSkuKSkpKSkpKSkpKSkpKCkG9QgJCiFAKSkpKSn/KSkpKSkAAAEpKQcEKSkpKSkpKSkpKSkpKSkpKQwpKSkpKSkpKSkpKTsEQAApKSkpKCkG9QgJCiFAKSkpKSn/KSkpKSkpKQcEKSkpKSkyKSkpKbckODlXOwRAAD4pBwQgHCkpKSkA 365 \)\)\).\)\)\)\)\)\004\004\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\012\)\012\)\)\.\)\)\)\)\)\)\)\)\)\)\)\)\(.\006\245\008\009\010!\@\)\)\)\)\)\255\)\)\)\)\)\000\000\001\)\)\007\004\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\).\)\)\)\)\)\)\)\)\)\)\)\;.\@\000\)\).\)\(\)\006\245\008\009\010!\@\)\)\)\)\)\255\)\)\)\)\)\)\)\007\004\)\)\)\)\)2\)\)\)\)\183\$89W\;.\@\000>\).\004\032\028\)\)\)\) ++AgAAAhBiAQEBAQIQYgIiAQEBAQEBAQEBAQEBAQECAVcBAQEBAQEBAQEBAgFXAQEBAQEBAQEBAQEBAgFXAUEBAQEBAQECAVcBAQE= 0 -1 ++AgBAAhAiAhBAAhAiAhATBAEVFhcEGBkaGwQUHR4fBCApIiMEJCTrJwQIKSorBAgJ/38EDA0SDwQQERITBBQVFhcEGBkaGwQUHR4fBCAp 0 -1 ++AgAAAhBiAgAAAhAiAQEBAgFXAhBiAgAAAhABAQEBAQIBVwEBAQEBAQIQYgIAAAIQIgEBAQEBAQIBVwEBAgFXAQEBAQIBVwFBAQEBAQEBAgFXAQ== 0 -1 ++AgBAAhAiAhBAAhAiAhAMDRIPBBAIEhMEARUWFwQYGRobBBQdHh8EICkiIwQkJAAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgZGhsEFB0eHwQgKSIjBCQk6ycECCkAAAE= 0 108 AgBAAhAiAhBAAhAiAhAMDRIPBBAIEhMEARUWFwQYGRobBBQdHh8EICkiIwQkJAAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgZGhsEFB0eHwQgKSIjBCQk6ycECCkA 344 \000\@.\016\".\016\@.\016\".\016\012.\018\015\004\016\008\018\019\004\001\021\022\023\004.\025\026\027\004\020\029\030\031\004\032\)\"#\004\$\$\000\000\002\000\@\002\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\025\026\027\004\020\029\030\031\004\032\)\"#\004\$\$\235'\004\008\) ++AgAfBCApJOsnBAgpKisELC0uLwQwQAIQIgIQQAIQIgIQIgYECAAAAQn/fwQMDRIPBBAIEhMEARUWFwQYGRobBBQdHh8EICkiIwQkJOsnBAgpKisELC0xMjMENDU2IgYECAn/fwQMDRIPBBAREhMEFBEWFwQYGRobBBQdHh8EICkiIwQvJOsnBAgpKisELC0uLwQwMTIzBDRCNjcEODk6OwQ8 0 -1 ++AgBAAhAiAhBAAhAiAhAiAhAiBgQICR0eHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGBksLS6KBDAxMjMENDU2IgYECAn/fwQMDRIPBBAREhMEFBUQAAQYGRobBBQdHh8EICkiIwQkJOsnBAgpKisELC0uLwQwMTIzBDRCNjcEOHk6OwQ86ycECCkAAAEsLS4vBDAGBAgJ/38EDBAREhMEFBUQ 0 -1 ++AgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgZGhsEFB0eHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgJ/38EAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgZGhsEFB0eHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGBkagAQUHR4fBCApIiMEJCTrJwQIKQAAAQw= 0 191 AgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgZGhsEFB0eHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgJ/38EAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgZGhsEFB0eHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGBkagAQUHR4fBCApIiMEJCTrJwQIKQA= 603 \000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\025\026\027\004\020\029\030\031\004\032\)\"#\004\$\$\000\000\002\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\025\026\027\004\020\029\030\031\004\032\)\"#\004\$\$\000\000\002\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\025\026\128\004\020\029\030\031\004\032\)\"#\004\$\$\235'\004\008\) ++AgAAAgBAAhAiAhBAAhAdHh8NNSkiGQQkJAAA/wBAAhAiAhBAAhAiAhAiBgQQIgIQQAIQIgIQHwQgKSIjBAQkAAACAEACEAACEEACECICBBAIEhMEARUWFwQYOhobBBQdHh8mNSkiGQQkJAAAAgBAAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQAAAIAQAIQIgIQQAIQIgIQIgYECAJAAgIC/gICOwA= 0 -1 ++BAABAwMEAwjnJwsEDA0OHwTpASMBAQEBAQEBAADm 0 29 BAABAwMEAwjnJwsEDA0OHwTpASMBAQEBAQEBAAA= 88 \000\001\003\003.\003\008\231'.\004\012\013\014\031\004\233\001#\001\001.\001.\001.\000 ++BAAAAQABAgMEBQAAAQU= 0 12 BAAAAQABAgMEBQAA 35 \000\000\001\000.\002.\004\005\000 ++AQAcqAT1BQbmAwgAAAEEDA0ODwQAABHm/LkzKREyAQDo+w== 0 32 AQAcqAT1BQbmAwgAAAEEDA0ODwQAABHm/LkzKREyAQA= 110 \000.\168\004\245\005\006\230\003\008\000\000\001\004\012\013\014\015\004\000\000\017\230\252\1853\)\0172\001 ++AgICAgICAgICAgICAgIAAAF/ 0 16 AgICAgICAgICAgICAgIAAA== 45 \002\002.\002\002.\002\002.\002\002.\002\000 ++BBwcHAwcHBwcHBwc9KgMAQEBQBwcHBwcAcsRfX19fX76EwAAARw= 0 35 BBwcHAwcHBwcHBwc9KgMAQEBQBwcHBwcAcsRfX19fX76EwA= 113 \028\028\028\012.\028\028\028\028\028\028\244\168\012\001\001\001\@\028\028\028\028\028\001\203\017}}}}~\250\019 ++BEAfPj4+HFBRUlMEVAAAASYmJiYmJiYmJiYmrSYVJiZnBGhpP2sAAABhYmMfZGUmJhgmJiYmJjImJiYmJiYmJiYmJiYmJiYmJiatJhUmJiZmZwRoaT9rACYmJiYmJq0mJiYmJmZnBGhpQAAAAQA= 0 108 BEAfPj4+HFBRUlMEVAAAASYmJiYmJiYmJiYmrSYVJiZnBGhpP2sAAABhYmMfZGUmJhgmJiYmJjImJiYmJiYmJiYmJiYmJiYmJiatJhUmJiZmZwRoaT9rACYmJiYmJq0mJiYmJmZnBGhpQAAA 172 \@\031>>.\028PQRS\004T\000\000\001&&&&&&&&&&&\173&\021&&g\004hi?k\000\000\000abc\031de&&\024&&&&&2&&&&&&&&&&&&.&&&&&\173&\021&&&fg\004hi?k\000&&&&&&\173&&&&&fg\004hi\@\000 ++BOgD6wcINjY2NjY2MzY2NjY2NgD2ABA2UDY2NjY2NjY2NjY2NjY2JDY2NjYAAP//AAA2AAABNgAQNlg2NjaHNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYAgAAAKDY2zjY2Np42NjY2Njb/////6DY2QzY2NjYgAQA2 0 125 BOgD6wcINjY2NjY2MzY2NjY2NgD2ABA2UDY2NjY2NjY2NjY2NjY2JDY2NjYAAP//AAA2AAABNgAQNlg2NjaHNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYAgAAAKDY2zjY2Np42NjY2Njb/////6DY2QzY2NjYgAQA= 225 \232\003\235\007.66666636.6666\000\246\000\0166P66666666666666\$6666\000\000\255\255\000\0006\000\000\0016\000\0166X666\135666666.6666666666666666666666\000\128\000\000\(66\206666\158666666\255\255\255\255\23266C6666\032\001 ++BCYmJiYmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2EhISEhISEhISEhISEhISEhISEhISEhISEhI2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Nhw2njY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2HTY2NjZINjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjaeNjY2NjY2NjY2NjY2NjY2NjY2NjY2NiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Ng== 0 -1 ++BOgAAAEDAwgINjY2NgAAAMAfNjY2NjYkFTY0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTYABDY2NjY2NjY2NjY0Nlg2NjY2NjY2NgAAATY2NgAAAADAHzY2NjY2JBU2NDY2NjY2NjY2NjY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2AAAAAQAbS2xLS0tLS0tLATa+H0YUNjY2NgAANjYkNjY0NjY2NjY2NjY2NjY2NjY2NjYkNjZ/dnZ2dnZ2dnZ2dnZ2dnZ2QTYBNh4EAED/NjY2NjQ2AAABAAABgDY2FjY2NtDQ0NDQ0NDQ0DPQ0NDQ0NDQ0NDQ0JDQABQUFBQ2NjY2NjY2WDY2NjZNNjZRABEBAAABNiU9PT09NgBAAAGANj0QAPv7+/v7+/v7+/sg+/v7+0JEAAABNjYyNjY= 0 -1 ++BOgDAwgINjZWNhU2NgE2NjY2NjY2NjY2NjY2UjY2AzY2NjY2NjY2NjYlNkk2NjY2NjY2NjY2NiIiIiIiIkAiNugDNjY2NjY2NjY2NjZDNjY2NpiYmDY2NjYiICIiIiIiIiIiIiIiIiJJNjY2NjY2NjY2NjYiIiIiIiJAIjboAzYiIiIiIiIiIiIiIiI2NjY2NjY2NjZkNjY2NjY2NjZNNgAAATY2NjYCAAQANjY2NgAQAIAAADY= 0 180 BOgDAwgINjZWNhU2NgE2NjY2NjY2NjY2NjY2UjY2AzY2NjY2NjY2NjYlNkk2NjY2NjY2NjY2NiIiIiIiIkAiNugDNjY2NjY2NjY2NjZDNjY2NpiYmDY2NjYiICIiIiIiIiIiIiIiIiJJNjY2NjY2NjY2NjYiIiIiIiJAIjboAzYiIiIiIiIiIiIiIiI2NjY2NjY2NjZkNjY2NjY2NjZNNgAAATY2NjYCAAQANjY2NgAQAIAA 299 \232\003\003\008.66V6\02166\001.666666666666R66\0036666666666%6I66666666666\"\"\"\"\"\"\@\"6\232\003666.6666666C6666\152\152\1526666\"\032\"\"\"\"\"\"\"\"\"\"\"\"\"I66666666666\"\"\"\"\"\"\@\".\232\0036\"\"\"\"\"\"\"\"\"\"\"\"666666666d66666666M6\000\000\0016666\002\000\004\0006666\000\016\000\128 ++BOgAATY2NjY2fwA2NjY2NjY2NjY2NjY2NjY2NjY2Njb/ADY2NjY2NjY2NjY5NjY2AAAAgFQ2NjY2NjY2NjY2UzY2NjY2tzY2NjY2NjY2NjY2NjY2NjY2NjY2NgAAATY2O0o2NjY2NjY2NjY2NjY2NjYAEDY2OTY2NgAAAIBUNjY2NjY2NjY2NjY2NjY2/zY2NlU2NjY2NjY2NjY2NjY2Nis2NgABAACA/zY2NjY2NjY2NjY2Np42NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2IjY2NjY2IDY2NjY2NjY2NjY2NjY2NjY2IjY2NjY2IDY2NjY2NjY2NjY2IzY2NjY2NjY2NjY2NjZINjY2NjYTDAwMDAwMDAwMDAYMDAwMDAwMDAwMDAwMDDY2NjY2JTY2NjY2NjY2NjY2Np42NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY= 0 -1 ++BOgAAAABAAgINjY2NgAAAMAQNjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTY2NjY2NjQ2WDY2NjY2NjY2AAABNjY2AAD/8cAfNjY2NjYkFTYUNjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFAAAATYAADY2JDY2NDY2NjY2NjY2NnZ2dnZ2QTYBNh4EAED/NjY2NjQ2AAABAAABgDY2FjY2NtDQ0NDQ0NDQ0DPQ0NDQ0NDQ0EDQ0JDQABQUFBQ2NjY2NjY2WDY2NjZNNjZRABEBAAABNjY2RTY5NjY2JT09PT02ADY0NgAAAYA2PRAA+/v7+/v7+w== 0 -1 ++BOgDCAg2NjY2AAAAwB82NjY2NiQVNjQ2NjY2NjY2NgAQNgAAATY2NjY2NjY2AAABAAE2NjZFNjYVNgAENjY2NjY2JzY2NjQ2WDY2NjY2NjY2AAABNjY2AAAAAMAfNjY2NjYkFTY0NjY2NjY2NjY2NjY2NjYAAAABBDY2NjY2NjY2NjY2NjYAAAABABtLbEtLS0tLS0sBAAABRhQ2gDY2AAA2NiQ2NjQ2NjY2NjY2NjY2NjY2NjY2NiQ2Nn92dnZ2dnZ2dnZ2dnZ2dnZBNgE2HgQAQP82NjY2NDYAAAEAAAGANhkWNjY20NDQ0NDQ0NDQM9DQ0NDQ0NDQ0NDQkNAAFBQUFDY2NjY2NjZYNjY2Nk02NlEAEQEAAAEjNjZFNjk2NjYlPT09VDYAQP82NjY2NDYAAAGANj0QAPv7+/v7+/v7+/sg+/v7+0JEAAABNgsLCwsLCwsLCwsLCwsLCws= 0 -1 ++wMAAAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Nn7s7OzsEBQUDDY2NgAAATY2NjZYNjY2Nk02NlEAEQEANjYABf//BUU2OTY2NiU9PT09NgAAAfI//3Y2AAABNjY0NgAAAYA2PRAA+/v7+/v7+/v///8= 16 -1 ++BOgAAGQB4ggISTY2NgAEQMAAAAAAATY2NjY6JDY2NgAQNjZKWDYgNjY2AAA2NjY2Njw2ATYYNkUAAAIQ//9/TExMTExMTExMTExMTExMTExMTExMTENMTBMTExMTEykTExMTEyYLAAEUFAAABjY2NjYAAAE2NhwAAAABAAABBDY2NtAAAzY2NgX//wU2NgD7SDYkNjk5OTk5OTk5OTk5OTk5OTk5OTk5PTY0NjY2NjY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Coq0DPQ0P/QM9DQ//9//9AAAAHSu9DRkNAABgAA/xQUAAAGfzYkNjY0Nks2AAQeVTb/Nn////82TENMTBMTExMTEykTExMTEyYTACATNjYmfwLuAaMYAAABgDY2SlggIDY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Co2Pk4ABQABADcyNjY= 0 -1 ++BOgAAGQB4ggISTY2NgBEQMAAAADOzs7Ozs6wzs7O//9/TExMTExMTExMTExMTExMTExMTExMTENMTBMTEwAAARMTEy0T1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NQcExMTJgsAARQeAAAGNzY2WAAAATY2HAAAAAEAAAEENhY20AADNjY2Bf//BTY2APtIACQ2OTk5OTk5OTk5OTk5OTk5OTk5OTk9NjQ2NjY2NjY2GwAAATY2fzZxdnZ2dnZ2dnbQKirQM9DQ/9Az0ND//3//0AAA5tK70NGQ0AAGAAD/FBQAEAB/NiQ2NjQ2SzY0NjY2NjY2NiRVNv82f+4BoxgAAAGANjZKVSAgNjY2JAAAATY1fzZxdnZ2dnZ2dnbQKjY+TeYFACEANzI2OTk9NjQ2NjY2NjY2GwAAATY2fzZxdnZ2dnZ2dnY= 0 -1 ++AgACAgICAgACAgICAgLXAgICAgICAuEBAgICAgICAgICAgICAgICAgICAgICAgICAgICAAL0 0 52 AgACAgICAgACAgICAgLXAgICAgICAuEBAgICAgICAgICAgICAgICAgICAgICAgICAgICAA== 153 \000\002.\002\002.\000\002.\002\002.\002\215.\002\002.\002\002.\225\001.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002 ++AgwAAhAiAgAAAhAiAQECAVcBAQEBAQEBAQEBAgFXAQEBAQEBAQEBAQEBAgFXAQEBAQA= 0 50 AgwAAhAiAgAAAhAiAQECAVcBAQEBAQEBAQEBAgFXAQEBAQEBAQEBAQEBAgFXAQEBAQA= 120 \012\000.\016\".\000\000.\016\".\001.\001W.\001.\001.\001.\001.\001.\001W.\001.\001.\001.\001.\001.\001.\001W.\001.\001 ++AgAAAhAiAgAAAhAiAQECAVcBAQEBAQEBAQEBAgFXAQEBAQEBARQBAQEBAQIBAQEBAQEBAQIBSgEBAQEBAQEBAQEBAQEBAgFXAVcBAQEBAQEBAQEBAQEAAAEC 0 87 AgAAAhAiAgAAAhAiAQECAVcBAQEBAQEBAQEBAgFXAQEBAQEBARQBAQEBAQIBAQEBAQEBAQIBSgEBAQEBAQEBAQEBAQEBAgFXAVcBAQEBAQEBAQEBAQEA 208 \000\000.\016\".\000\000.\016\".\001.\001W.\001.\001.\001.\001.\001.\001W.\001.\001.\001.\020.\001.\001.\002.\001.\001.\001.\001.\001J.\001.\001.\001.\001.\001.\001.\001.\001W.W.\001.\001.\001.\001.\001.\001 ++BAAEBQYHBAgJCg4PBBAREhMEFBUWFwQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/GEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChoi0EpKWmpwSoqaqrBKytrq8EsLGyswS0tba3BLi5ursEvL3BwgAA 8 225 CQoODwQQERITBBQVFhcEGBkaGwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PxhAQUJDBERFRkcESElKSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EYGFiYwRkZWZnBGhpamsEbG1ubwRwcXJzBHR1dncEeHl6ewR8fX5/BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaItBKSlpqcEqKmqqwSsra6vBLCxsrMEtLW2twS4ubq7BLy9wcIA 520 \010\014\015\004\016\017\018\019\004.\021\022\023\004\024\025\026\027\004\028\029\030\031\004\032!\"#\004\$.&'\004\(\)*+\004,-\./\0040123\0044567\00489:\;\004<=>?\024\@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk.lmno.pqrs.tuvw.xyz{.|}~\127.\128\129\130\131.\132\133\134\135.\136\137\138\139.\140\141\142\143.\144\145\146\147.\148\149\150\151.\152\153\154\155.\156\157\158\159.\160\161\162-.\164\165\166\167.\168\169\170\171.\172\173\174\175.\176\177\178\179.\180\181\182\183.\184\185\186\187.\188\189\193\194 ++AgAAAhBiAgAAAhAiAQECEGICAQIBVwEBAhBiAgAAAhAiAVcBAgFXAQECAVcBAQEBAgFXAAAB 0 52 AgAAAhBiAgAAAhAiAQECEGICAQIBVwEBAhBiAgAAAhAiAVcBAgFXAQECAVcBAQEBAgFXAA== 116 \000\000.\016b.\000\000.\016\".\001.\016b.\001\002.W.\001.\016b.\000\000.\016\".W.\002.W.\001.\001W.\001.\001.\001W ++AgAfBCApIiMEJAgpKisELC0uLwQwQAIQIgIQQAIQIgIQIgYECAAAAQn/fwQMDRIPBBAIEhMEiRUWFwQYGRobBBQdHh8EICkiIwQkJOsnBAgpKisELC0uLwQwMTIzBDQ1NiIGBAgJ/38EDA0SDwQQERITBBQRFhcEGBkaGwQUHR4fBCApIiMELyTrJwQIKSorACw= 0 145 AgAfBCApIiMEJAgpKisELC0uLwQwQAIQIgIQQAIQIgIQIgYECAAAAQn/fwQMDRIPBBAIEhMEiRUWFwQYGRobBBQdHh8EICkiIwQkJOsnBAgpKisELC0uLwQwMTIzBDQ1NiIGBAgJ/38EDA0SDwQQERITBBQRFhcEGBkaGwQUHR4fBCApIiMELyTrJwQIKSorAA== 432 \000\031.\032\)\"#.\$\008\)*.\004,-\./\0040\@\002\016\"\002\016\@\002\016\"\002\016\"\006\004\008\000\000\001\009\255\127\004\012\013\018\015\004\016\008\018\019\004\137\021\022.\004\024\025\026\027\004\020\029\030\031\004\032\)\"#\004\$\$\235'\004\008\).+\004,-\./\0040123\004456\"\006\004\008\009\255\127\004\012\013\018\015\004\016\017\018\019\004\020\017\022\023\004\024\025\026\027.\020\029\030\031.\032\)\"#./\$\235'.\008\)*+ ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYFB0eHyY1KSIZBCQkAAACDkACECICEEACECICECICEEACECICEB8EICkiIwQkJAAAAgBAAhAiAhBAAhAiAhAAAA== 0 202 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYFB0eHyY1KSIZBCQkAAACDkACECICEEACECICECICEEACECICEB8EICkiIwQkJAAAAgBAAhAiAhBAAhAiAhAAAA== 593 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\020\029\030\031&5\)\"\025\004\$\$\000\000\002\014\@\002\016\"\002.\@\002\016\"\002\016\"\002\016\@\002\016\"\002\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\".\016\@.\016\".\016\000 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CADsA 0 232 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CAA== 664 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\128\000\000\0005\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\004\008\002\002\002\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\020\029\030\031&5\)\"\025\004\$\$\000\000\002\000\@.\016\".\016\@.\016\".\016\".\016\@.\016\".\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\002\@\002\002.\254\002 ++AgAAAhBiAgAAAhAiAQECAVcBAQIBVwIQYgIAAAIQYgIAAAIQIgEBAgFXAQECAVcCEGICAAACEAECAAACEGICAAACECIBAQIBVwEBAgFXAhBiAgAAAhBiAgAAAhAiAQECAVcBAQIBVwIQYgIAAAIQAQIBVwAAAQ== 0 116 AgAAAhBiAgAAAhAiAQECAVcBAQIBVwIQYgIAAAIQYgIAAAIQIgEBAgFXAQECAVcCEGICAAACEAECAAACEGICAAACECIBAQIBVwEBAgFXAhBiAgAAAhBiAgAAAhAiAQECAVcBAQIBVwIQYgIAAAIQAQIBVwA= 278 \000\000.\016b.\000\000.\016\".\001.\001W.\001.\001W.\016b.\000\000.\016b.\000\000.\016\".\001.\001W.\001.\001W.\016b.\000\000.\016\001.\000\000.\016b.\000\000.\016\".\001.\001W.\001.\001W.\016b.\000\000.\016b.\000\000.\016\".\001.\001W.\001.\001W.\016b.\000\000.\016\001.\001W ++AQAfBCApIiMEJCTrJ3//BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBf//KwQsLS4vBAAAAQAAAQ== 0 177 AQAfBCApIiMEJCTrJ3//BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBf//KwQsLS4vBAAAAQAA 598 \000.\004\032\)\"#\004\$\$\235'\127\255\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\005\005\005.\005\005\255\255+.,-\./.\000\000\001\000 ++AgAABgYGBgYcBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBAYGBgYGBgYGBgYGBgQGBgYGBgYGBgYGBgYGBgYGBkAGBgYQBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGZAYGBgYGBgYGsgYGBgYGBgYGBgYGBgYFBgYGBgYGBgYGBgYGGgYGBgYGBgYGBgYGBhMGBgYGBgAgBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgboIR4fBCApIiMELyTrJwQIKSorACw= 0 241 AgAABgYGBgYcBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBAYGBgYGBgYGBgYGBgQGBgYGBgYGBgYGBgYGBgYGBkAGBgYQBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGZAYGBgYGBgYGsgYGBgYGBgYGBgYGBgYFBgYGBgYGBgYGBgYGGgYGBgYGBgYGBgYGBhMGBgYGBgAgBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgboIR4fBCApIiMELyTrJwQIKSorAA== 821 \000\000.\006\006\006\006\028\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\004\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\@.\006\006\016\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006d\006\006\006.\006\006\006\006\178\006.\006\006\006\006\006\006.\006\006\006\006\005\006.\006\006\006\006\006\006.\006\006\006\026\006\006.\006\006\006\006\006\006.\006\006\019\006\006\006.\006\000\032\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\232!\030\031.\032\)\"#./\$\235'.\008\)*+ ++AgAfBCApIiMEJCTrJwQIKSqrBCwtLi8EMEECAB8EBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcGBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcOBwcHBwczMzMaOzMzMzMzMzMzMzMzMwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBwcHIQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHFwcHBwcHBwcHBwcHBwIQIgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHAhAiAhAiBi4vAAABBDAx+X8EDA0SDxAiAhAiBi4vBDAxKjMENDU2IgYECAn5fwQMDRIPBCozBAcHBwcHBwcHBwcHBwcHBwcQERITBBQREkAAARYXMzMzMzMzMzMRMzMzMzMzM/9/EwQUERYXBBgkGhsEFB0CECIGBAgJ+X8EDCcSDwQQERITBEAAFhbogAAAGwQUHQAQMwQ0MX/+//8ICQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHBwchBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHBwcHfwAEJDQdAhAiAhBAAhAiAhAiEkAAARYXBBgZGhsEFB0gHwAzMzM= 0 -1 ++AgQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAQQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBOUDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBATlAwQEBAQEBAQEBAQEBAQAAA== 0 165 AgQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAQQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBOUDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBATlAwQEBAQEBAQEBAQEBAQA 554 \004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\000\000.\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\229\003\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\004.\004\004\004\229.\004\004\004.\004\004\004\004.\004\004\004\004 ++AgICAgICAgICAgICAgICAg8CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIiMELyTrJwQIKSorACw= 2 119 AgICAgICAgICAgICAgIPAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIjBC8k6ycECCkqKwA= 337 \002\002.\002\002.\002\002.\002\002.\002\015.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\"#./\$\235'.\008\)*+ ++BAABAgMEAAAEAAQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BEBBQkMEREV/RwRISUtLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbR42BCAhIiMEJCUmJwQoKSorBCwtLi8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChogAA 0 246 BAABAgMEAAAEAAQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BEBBQkMEREV/RwRISUtLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbR42BCAhIiMEJCUmJwQoKSorBCwtLi8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChogAA 455 \000\001\002\003.\000\000\004\000.\008\009\010\011.\012\013\014\015.\016\017\018\019.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>?.\@ABC.DE0G.HIKK.LMNO.PQRS.TUVW.XYZ[.\\]^_.89:\027.<=>?.\@ABC.DE\127G.HIKK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk.lm\0306.\032!\"#.\$%&'.\(\)*+.,-\./.\128\129\130\131.\132\133\134\135.\136\137\138\139.\140\141\142\143.\144\145\146\147.\148\149\150\151.\152\153\154\155.\156\157\158\159.\160\161\162\000 ++BAABAgMEAAAEAAQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BEBBQkMEREUwRwRISUtLBExNTk8EUFFSUwRUVVZXBEJZWlsEXF1eXwRgNTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BJSVlpcEmJmamwScnaGiAAA= 0 241 BAABAgMEAAAEAAQICQoLBAwNDg8EEBESEwQcHR4fBCAhIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BEBBQkMEREUwRwRISUtLBExNTk8EUFFSUwRUVVZXBEJZWlsEXF1eXwRgNTY3BDg5OjsEPD0+PwRAQUJDBERFMEcESElLSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EODk6GwQ8PT4/BJSVlpcEmJmamwScnaGiAA== 370 \000\001\002\003.\000\000\004\000.\008\009\010\011.\012\013\014\015.\016\017\018\019.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>?.\@ABC.DE0G.HIKK.LMNO.PQRS.TUVW.XYZ[.\\]^_.89:\027.<=>?.\@ABC.DE0G.HIKK.LMNO.PQRS.TUVW.BYZ[.\\]^_.`567.89:\;.<=>?.\@ABC.DE0G.HIKK.LMNO.PQRS.TUVW.XYZ[.\\]^_.89:\027.<=>?.\148\149\150\151.\152\153\154\155.\156\157\161\162 ++EMDAwMDANjYAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAA= 0 146 EMDAwMDANjYAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAA= 475 \192\192\192\192\19266\000\003\003\003\003\003\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\003.\003\003\000 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFQACAEACECICEEACECICECICEEACEBYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQWAAIAQAIQIgIQQAIQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CADs= 0 253 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFQACAEACECICEEACECICECICEEACEBYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQWAAIAQAIQIgIQQAIQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CAA== 715 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\000.\000\@.\016\".\016\@.\016\".\016\".\016\@.\016\022.\004\024:\026\027\004\011\128\000\000\0005\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\004\008\002\002\002\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\020\029\030\031&5\)\"\025\004\$\$\022\000\002\000\@.\016\".\016\@.\016\".\016\".\016\@.\016\".\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\002\@\002\002.\254\002 ++AgAfBCApIiMEJCTrJwQIKSqrBCwtLi8EMEECAB8EBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwYHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBzMzMxo7MzMzMzMzMzMzMzMzBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHBwchBwcHBwcHBwcHBwcF//8FBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHAhAiBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBwMHBwcHBwcCECICECIGLi8AAAEEMDH5fwQMDRIPECICECIGLi8EMDEqMwQ0NTYiBgQICfl/BAwNEg8EKjMEBwcHBwcHB8XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHMzMzGjszMzMzMzMzMzMzMzMHBwcHBwcHBwcHBwcHBwcHBwcOBwcHBwcHByEHBwcHBwcHBwcHBwX//wUHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBwcHBwcHBwcCECIHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHFwcHBwcHAwcHBwcHBwIQIgIQIgYuLwAAAQQwMfl/BAwNEg8QIgIQIgYuLwQwMSozBDQ1NiIGBAgJ+X8EDA0SDwQqMwQHBwcHBwcHxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFBwcHBwcHBwcHEBESEwQUERJAAAEWFzMzMzMzMzMzETMzMzMzMzP/fxMEFBEWFwQYJBobBBQdAhAiBgQICfl/BAwnEg8EEBESEwRAABYW6IAAABsEFB0AEDMENDF//v//CAkHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBwcHIQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHFwcHBwcHBwcHBwfFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcUHBwcH 0 -1 ++BB8BAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pl8EYGFgYwRkZWZnBGhpamsEbG1ubwRwcXJzBHR1VlcEWFlaWwRcXV5fBGBhYmMEZGVmZwRoaWprBGxtbm8EcHFycwR0dXZ3BHh5ensEfH1+fwSAgYKDBISFhocAAAGK 8 163 BgcECAkKCwQMDQ4PBBAREhMEFBUWFwQYGRobBBwdHh8EICEiIwQkJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT5fBGBhYGMEZGVmZwRoaWprBGxtbm8EcHFycwR0dVZXBFhZWlsEXF1eXwRgYWJjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHAA== 277 \007\004\008\009\010\011.\012\013\014\015.\016\017\018\019.\020\021\022\023.\024\025\026\027.\028\029\030\031.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<=>_.`a`c.defg.hijk.lmno.pqrs.tuVW.XYZ[.\\]^_.`abc.defg.hijk.lmno.pqrs.tuvw.xyz{.|}~\127.\128\129\130\131.\132\133\134\135 ++AhI1AAABNTUVOj9ISEhISEhISEhISEhISAMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDCAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzYAPRAA+/v7+/v7+wMDAwMDAwMDAwMDAwAAAQMDAwMDAwMDAwMDAwADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMOAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzYAAAGA 68 -1 ++AhIAAlBINQAAATU1FTo/SEhISEhIAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMFRTY5Nj42JT09PQEfNjY8NjYkFTY0NjYyNjY2NjYADDY2S0sAAAEBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAA/gABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2Mh02NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAAATY2NDY2NkE2PjY2NjY2NjZO0NDQkNAAFBQUFDY2NTY2QzZYNjY2Nk02NlEAEQEANjY07Ozs7AAA 68 -1 ++BCAhIiMEJCUmJwQoKSorBCwtLi8EMDEFGAEfASABIQEiASMBJAEnASgBKQEqASsBLAEtAS4BNwE4ATkBOiA7ATwBPQE+AT8NAQ4BDwEQAREBEgETARQBFwUYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BJwEoAUgBKgErASwBLQEuATsBPAE9AT4BPwA= 0 161 BCAhIiMEJCUmJwQoKSorBCwtLi8EMDEFGAEfASABIQEiASMBJAEnASgBKQEqASsBLAEtAS4BNwE4ATkBOiA7ATwBPQE+AT8NAQ4BDwEQAREBEgETARQBFwUYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BJwEoAUgBKgErASwBLQEuATsBPAE9AT4BPwA= 293 \032!\"#.\$%&'.\(\)*+.,-\./.01\005\024.\031.\032.!.\".#.\$.'.\(.\).*.+.,.-.\..7.8.9.:.\;\001<\001=\001>\001?\013\001\014\001\015\001\016\001\017\001\018\001\019\001\020\001\023\005\024\001\025\001\026.\027.\028.\029.\030.\031.\032.!.\".#.\$.%.&.'.\(.\).*.+.,.-.\..'.\(.H.*.+.,.-.\..\;.<.=.>.? ++AX8CAAAA 0 6 AX8CAAAA 14 \127.\000\000 ++AgIAAAEC 0 4 AgIAAA== 9 \002\000 ++AQAAZA== 0 3 AQAA 5 \000 ++AQWhQEBAQAAAAQ== 1 7 BaFAQEBAAA== 13 \161\@\@\@\@ ++JB4kJDUkJCQkJCQkJCQCNCQC/yQkJCQkJAAAASQkJAAkHgcAgAA= 0 38 JB4kJDUkJCQkJCQkJCQCNCQC/yQkJCQkJAAAASQkJAAkHgcAgAA= 95 \030\$\$5\$\$\$\$\$\$\$\$\$\0024\$\002\255\$\$\$\$\$\$\000\000\001\$\$\$\000\$\030\007\000\128 ++AQABAwEiAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwESARMBFAEVARYBFwEYARkBGgEbARwBHRABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAG5AboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QH+Af8A 0 -1 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0V3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AP4= 0 253 AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0V3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AA== 660 \000.\001.\002.\003.\004.\005.\006.\007.\008.\009.\010.\011.\012.\013.\014.\015.\016.\017.\018.\019.\020.\021.\022.\023.\024.\025.\026.\027.\028.\029.\030.\159.\160.\161.\162.\163.\164.\165.\166.\167.\168.\169.\170.\171.\172.\173.\174.\175.\176.\177.\178.\179.\180.\181.\182.\183.\184.\185.\186.\187.\188.\189.\190.\191.\192.\193.\194.\195.\196.\197.\198.\199.\200.\201.\202.\203.\204.\205.\206.\207.\208.\209.\210.\211.\212.\213.\214.\215.\216.\217.\218.\219.\220.\221.\222\001\223\001\224\001\225\001\226\001\227\001\228\001\229\001\230\001\231\001\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHUAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AQEA/wA= 0 255 AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQEaARsBHAEdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHUAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AQEA 635 \000.\001.\002.\003.\004.\005.\006.\007.\008.\009.\010.\011.\012.\013.\014.\015.\016.\017.\018.\019.\020.\021.\022.\023.\024.\025.\026.\027.\028.\029.\030.\159.\160.\161.\162.\163.\164.\165.\166.\167.\168.\169.\170.\171.\172.\173.\174.\175.\176.\177.\178.\179.\180.\181.\182.\183.\184.\185.\186.\187.\188.\189.\190.\191.\192.\193.\194.\195.\196.\197.\198.\199.\200.\201.\202.\203.\204.\205.\206.\207.\208.\209.\210.\211.\212.\213.\214.\215.\216.\217.\218.\219.\212.\221.\222.\223.\224.\225.\226.\227.\228.\229.\230.\231.\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253.\001 ++AgAADABAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsmCx0eHw01KSIZBCQkAAD/AEACEBgCEEACECICECIGBBAiAhBAAgIQIgYECAICAgICECICEEACECICECIGBAgJIgICAhAiAhBAAhAiAhAiBgQICf9/BAwNIA8EEAgSEwQBFRYXBBgBFRYXBBg6GhsECx0eEA01KSIZBCQ6NSkiGQQkJAAAAgBAAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQOAAIAQAIQIgIQQAIQIgIQIgYECAJAAgIC/gICOwA= 0 239 AgAADABAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsmCx0eHw01KSIZBCQkAAD/AEACEBgCEEACECICECIGBBAiAhBAAgIQIgYECAICAgICECICEEACECICECIGBAgJIgICAhAiAhBAAhAiAhAiBgQICf9/BAwNIA8EEAgSEwQBFRYXBBgBFRYXBBg6GhsECx0eEA01KSIZBCQ6NSkiGQQkJAAAAgBAAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQOAAIAQAIQIgIQQAIQIgIQIgYECAJAAgIC/gICOwA= 793 \000\000.\000\@\002\016\"\002\016\@\002\016\"\002.\"\006\004\008\009\255\127\004\012\013\018\015\004\016\008\018.\004\001\021\022\023\004\024:\026\027&\011\029\030\031\0135\)\".\004\$\$\000\000\255\000\@\002\016\024\002\016\@\002\016\"\002\016\"\006\004\016\"\002.\@\002\002\016\"\006\004\008\002\002\002\002\002\016\"\002.\@\002\016\"\002\016\"\006\004\008\009\"\002\002\002\016.\002\016\@\002\016\"\002\016\"\006\004\008\009\255\127\004\012\013\032\015\004\016\008\018\019\004\001\021\022\023\004\024\001\021.\023\004\024:\026\027\004\011\029\030\016\0135\)\"\025\004\$:5\)\".\004\$\$\000\000\002\000\@\002\016\"\002\016\@\002\016\"\002\016\"\002\016\@\002\016.\002\016\031\004\032\)\"#\004\$\$\014\000\002\000\@\002\016\"\002\016\@\002\016\"\002\016\"\006\004\008\002\@\002.\002\254.\002\; ++BOgDAwgINjY2NjY2NjY2PAA3NhM2NjY2NjY2Nkk2NjY2NjZAAAAANjk2NjY2NgAAAAFANjY2NjY2NjY2Ng82NjY8ADc2EzY2NjY2NjY2ADY2NjY2NjY2NjY28Da3NjY2NjbwNrc2NjY2NjY8ADc2EzY2NjY2NjY2NjY2NvA2tzY2NjYaAAE2NiM2NjY2NoE2NjY2NqVCPAAhNhM2NjY2NjY2Np42O/oYNhM2MjY2NjY2NgA2NjYAAAHwNrc2NjY2NjY2NjY2NjY2NjY2NjY2NjY5NjY2MTY2NjY2Njb/fzY2AAE2NjZ/PjZUnjY8ABg2NjY2Nj5SNhQ+AICAADYAAAE2 0 255 BOgDAwgINjY2NjY2NjY2PAA3NhM2NjY2NjY2Nkk2NjY2NjZAAAAANjk2NjY2NgAAAAFANjY2NjY2NjY2Ng82NjY8ADc2EzY2NjY2NjY2ADY2NjY2NjY2NjY28Da3NjY2NjbwNrc2NjY2NjY8ADc2EzY2NjY2NjY2NjY2NvA2tzY2NjYaAAE2NiM2NjY2NoE2NjY2NqVCPAAhNhM2NjY2NjY2Np42O/oYNhM2MjY2NjY2NgA2NjYAAAHwNrc2NjY2NjY2NjY2NjY2NjY2NjY2NjY5NjY2MTY2NjY2Njb/fzY2AAE2NjZ/PjZUnjY8ABg2NjY2Nj5SNhQ+AICAADYA 419 \232\003\003\008.66666666.<\00076\01966666666I666666\@\000\000\0006966666\000\000\000\001\@6666666666\015666<\00076.66666666\0006666666666.\2406\18366666\2406\183666666<\00076\019666666666666\2406\1836666\026\000\00166#66666\1296.666\165B<\000!6\01966666666\1586\;\250\0246\01962666666\000666\000\000\001\2406\18366666666666.666666666966616666666\255\12766\000\001666\127>6T\1586<\000\02466666>R6\020>\000\128\128\0006 ++BOgDAwgINjY2NjY2NjY2NjYAAH//NgAAf/8XAjZ/UV5eIAAXFxcXFxcXFxcXFwI2fzZeAAABXiAAATYAAEVkNgAANjY2NjY2NgABQDY2NjYyNjYjQzb/fxN1Njb8NjaeQjwAIVkTNjY2Nfs2NjaeNFnkGDITNjY2Njb/HDf/fzY2NgAAAf///382VzY2NgA2NjY2NjY2NjY2NjY2AAAANjb/////NgAAAFw2f////zY2NjE2NjY2//82/382NjYAAAH///9/ZAABNjY2NjY2Np5eXl4RATYAAEVkNgAANjY2NjY2NgABQDY2NgABNg== 0 236 BOgDAwgINjY2NjY2NjY2NjYAAH//NgAAf/8XAjZ/UV5eIAAXFxcXFxcXFxcXFwI2fzZeAAABXiAAATYAAEVkNgAANjY2NjY2NgABQDY2NjYyNjYjQzb/fxN1Njb8NjaeQjwAIVkTNjY2Nfs2NjaeNFnkGDITNjY2Njb/HDf/fzY2NgAAAf///382VzY2NgA2NjY2NjY2NjY2NjY2AAAANjb/////NgAAAFw2f////zY2NjE2NjY2//82/382NjYAAAH///9/ZAABNjY2NjY2Np5eXl4RATYAAEVkNgAANjY2NjY2NgABQDY2NgA= 544 \232\003\003\008.66666666.66\000\000\127\2556\000\000\127\255\023\0026\127Q^^\032\000\023\023\023\023\023\023\023\023\023\023\023\0026\1276^\000\000\001^\032\000\0016\000\000Ed6\000\000666.666\000\001\@6666266#C6\255\127\019u66\25266\158B<\000!Y\0196665\251666\1584Y\228\0242\01966666\255\028.\255\127666\000\000\001\255\255\255\1276W666\0006666666666666\000\000\00066\255\255\255\2556\000\000\000\\6\127\255\255\25566616.66\255\2556\255\127666\000\000\001\255\255\255\127d\000\0016666666\158^^^\017\0016\000\000Ed6\000\0006666666\000\001\@666 ++AykpKSkpKSkpKQQEKSkpKSkpKSkpKSkpKSkpDAAAASkMKSkuKSkpKSkpKSkpKSkpKCkG9QgJfyFAKSkpKSn/KSkpKSkAAAEpKQcEKSkpKSkpKSkpKSkpKSkpKQwpKSkpKSkpKSkpKSkpKQwpDCkpLikpKSkpKSkpKSkpKSkpKSkpKTsEQAIpKSkpKCkG9QgJCiFAKSkpKSn/KSkpKUUpKQcEKSkpKSkyKSkpKbckODlXOwRAAD4pBwQgKSkpKQAAEAA= 0 191 AykpKSkpKSkpKQQEKSkpKSkpKSkpKSkpKSkpDAAAASkMKSkuKSkpKSkpKSkpKSkpKCkG9QgJfyFAKSkpKSn/KSkpKSkAAAEpKQcEKSkpKSkpKSkpKSkpKSkpKQwpKSkpKSkpKSkpKSkpKQwpDCkpLikpKSkpKSkpKSkpKSkpKSkpKTsEQAIpKSkpKCkG9QgJCiFAKSkpKSn/KSkpKUUpKQcEKSkpKSkyKSkpKbckODlXOwRAAD4pBwQgKSkpKQA= 441 \)\)\).\)\)\)\)\)\004\004\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\012\000\000\001\)\012\)\)\.\)\)\)\)\)\)\)\)\)\).\)\(\)\006\245\008\009\127!\@\)\)\)\)\)\255\)\)\)\)\)\000\000\001\)\)\007\004\)\)\)\)\)\)\)\)\)\)\)\)\).\)\)\012\)\)\)\)\)\)\)\)\)\)\)\)\)\)\012\)\012\)\)\.\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\).\004\@\002\)\)\)\)\(\)\006\245\008\009\010!\@\)\)\)\)\)\255\)\)\)\)E\)\)\007\004\)\)\)\)\)2\)\)\)\)\183\$89W\;\004\@\000>\)\007\004\032\)\)\)\) ++BAABFwMBBRYXBBgZGhsEHB0eAAAAACIjBCQlJicEKCkqKwQsOy4vBCAhIiMEJCUmJwQoKSorBCw7Li8EBAQFFhcEGBkaGwQcHR4AAAAAIiMEJCUmJwQoKSorBCw7Li8EICEiIwQkJSYnBCgpKisELDsuLwQwMTIzBDQ1NjcEODk6OwQ8PT5BAA== 0 136 BAABFwMBBRYXBBgZGhsEHB0eAAAAACIjBCQlJicEKCkqKwQsOy4vBCAhIiMEJCUmJwQoKSorBCw7Li8EBAQFFhcEGBkaGwQcHR4AAAAAIiMEJCUmJwQoKSorBCw7Li8EICEiIwQkJSYnBCgpKisELDsuLwQwMTIzBDQ1NjcEODk6OwQ8PT5BAA== 309 \000\001\023\003.\005.\023\004\024\025\026\027\004\028\029\030\000\000\000\000\"#\004\$%&'\004.\)*+\004,\;\./\004\032!\"#\004\$%&'\004\(\)*+\004,\;\./\004\004\004\005\022\023\004\024\025\026\027\004.\029\030\000\000\000\000\"#\004\$%&'\004\(\)*+\004,\;\./\004\032!\"#.\$%&'.\(\)*+.,\;\./.0123.4567.89:\;.<=>A ++PwDuAQMEBQYHCAl8fHx8fHx8fHx8fHx8fHx8fHx8fHx8ICEiIyQlJjU2Nzg5Ojs8ICEiIyQlJjU2Nzg5Ojs8PT4/P0BBQkNEVHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8ICEiIyQlJjU2Nzg5Ojs8ICEiIyQlJjU2Nzg5Ojs8PT4/P0BBQkNEVCEiIyQlJjU2Nzg5Ojs8ICEiIyQlJiAhVVZXWFlaW1xdXl9gABBjZGVwcXJzdHV2QAAAfA== 0 188 PwDuAQMEBQYHCAl8fHx8fHx8fHx8fHx8fHx8fHx8fHx8ICEiIyQlJjU2Nzg5Ojs8ICEiIyQlJjU2Nzg5Ojs8PT4/P0BBQkNEVHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8ICEiIyQlJjU2Nzg5Ojs8ICEiIyQlJjU2Nzg5Ojs8PT4/P0BBQkNEVCEiIyQlJjU2Nzg5Ojs8ICEiIyQlJiAhVVZXWFlaW1xdXl9gABBjZGVwcXJzdHV2QAA= 261 \000\238\001\003\004\005\006\007\008\009||||||||||||||||||||||\032!\"#\$%&56789:\;<\032!\"#\$%&56789:\;<=.??\@ABCDT||||||||||||||||||||||||||\032!\"#\$%&56789:\;<\032!\"#\$%&56789:.<=>??\@ABCDT!\"#\$%&56789:\;<\032!\"#\$%&\032!UVWXYZ[\\]^_`\000\016cdepqrstuv\@ ++PwDuKSkpKSkpKSkpRikpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpIikpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKRYpKSlyc3R1dkAAAAB7 0 149 PwDuKSkpKSkpKSkpRikpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpIikpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKRYpKSlyc3R1dkAAAAA= 297 \000\238\)\)\)\)\)\)\)\)\)F\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\".\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\).\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\)\022\)\)\)rstuv\@\000\000 ++PwDuHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAAAR0dHR0dHR0dHR0dHR0+HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAAAR0dHR0dHR0dHR0dHR0+HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0UHR0dHR0dHR0dHR0BAwAAAQT9BQcICXx8fHx8fHx8AAABAHx8fHx8IAB8 0 245 PwDuHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAAAR0dHR0dHR0dHR0dHR0+HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAAAR0dHR0dHR0dHR0dHR0+HR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0UHR0dHR0dHR0dHR0BAwAAAQT9BQcICXx8fHx8fHx8AAABAHx8fHx8IAA= 910 \000\238\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\000\000\001\029\029\029\029\029\029\029\029\029\029\029\029\029>\029\029\029\029\029\029\029\029\029\029.\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029.\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\000\000\001\029\029\029.\029\029\029\029\029\029\029\029\029>\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029.\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029.\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\020\029\029\029\029\029\029\029\029\029\029.\001\003\000\000\001\004\253\005\007\008\009||||||||\000\000\001\000|||||\032 ++AQAAAAEgAAAA8Q8iAhAiAAABDkQICf9/BAAAAAEQCGNjL39jY2NjeHhvY2NjRwEVFjcEGDpaFwQLgAD//3//IgIAAAEQABCAAP//f/8iAhAAEBCb9BYfBENBh6AA+vr6FNkEAAQIZP8zAA== 100 6 BAhk/zMA 11 \008d\2553 ++AgAAAgAAAAEiAg== 0 7 AgAAAgAAAA== 18 \000\000.\000\000 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQIDf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaIiMEBCQAAAIAQAIQAAIfQAIQIgIQIgYECAIChgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEAIECIiAEACECICECIGBAgCQAICAv4CAA== 0 250 AgAAAgBAAhAiAhBAAhAiAhAiBgQIDf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaIiMEBCQAAAIAQAIQAAIfQAIQIgIQIgYECAIChgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEAIECIiAEACECICECIGBAgCQAICAv4CAA== 754 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\013\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\128\000\000\0005\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\"#\004\004\$\000\000\002\000\@\002\016\000\002\031\@\002\016\".\016\".\004\008\002\002\134\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\020\029\030\031&5\)\"\025\004\$\$\016\"\002\016\".\016\@.\016\".\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\"\"\000\@\002\016\".\016\".\004\008\002\@\002\002.\254\002 ++AQABAwEiAQcBCAEJAQoBCwEMAQ0BDgEPARIBEwEUARUBFgEXARgBGQEaARsBHAEdEAERARIBEwEUARUBFgEXAX0BGQEaARsBHAEdAR4BnwGgAaEBAAA= 0 86 AQABAwEiAQcBCAEJAQoBCwEMAQ0BDgEPARIBEwEUARUBFgEXARgBGQEaARsBHAEdEAERARIBEwEUARUBFgEXAX0BGQEaARsBHAEdAR4BnwGgAaEBAAA= 230 \000.\003.\".\007.\008.\009.\010.\011.\012.\013.\014.\015.\018.\019.\020.\021.\022.\023.\024.\025.\026.\027.\028.\029.\001\017\001\018\001\019\001\020\001\021\001\022\001\023\001}.\025.\026.\027.\028.\029.\030.\159.\160.\161.\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sNNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAARU2ClA2NtDO09DQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dgAA//92dnb/CwAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sNNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAARU2ClA2NtDO09DQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dgAA//92dnb/CwAA 633 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0136\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\001\0216\010P66\208\206\211\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\1276X+66666v\000\000\255\255vvv\255\011\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQsNjYAAdDQkAAAFBQUFDY2gH82WCs2NjY2NnZ2dnZ2dnZ2/wsAAAEAGw== 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQsNjYAAdDQkAAAFBQUFDY2gH82WCs2NjY2NnZ2dnZ2dnZ2/wsAAAEA 615 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020,66\000\001\208\208\144\000\000\020\020\020\02066\128\1276X+66666vvvvvvvv\255\011\000\000\001 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QAAAAAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QAAAAAAA 625 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\000\000\000\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEAAAAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEAAAAAA 623 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\@\000\000\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAAAAA 621 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\@\@\000\000 ++BAABAgMEBAUGBwQICQoLBBINDg8EEBESEwQUFRYXBBgZGhsEHB0eNjY2AAA2NjY2Njw2ATYYNkUAAAIQ//9/TExMTExMTExMTExMTExMTExMTExMTENMTBMTExNqEykTlhMTEyYLAAEUFAAABjY2NjYAAAE2NhwAAAABAAABBDb/fwAAAzY2NgX//wU2NgD7SDYkNjk5OTk5OTk5OTk5OTk5OTk5OTk5PTY0pDY2NjY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Coq0DPQ0P/QM9DQ//9//9AAAAHSu9DRkNAABgAA/xQUAAAGfzYkNjY0Nks2AAQeVTb/AAABNn////8= 0 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAQAAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAAAFYKzY2NjY2dnZ2dnZ2QEBAQAAA 619 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\000\001X+66666vvvvvv\@\@\@\@\000 ++ISEhISEhISEhISEhISEhISEhISEAA+gAISEhISEhISEhISEhISEhGiEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhISEhIYAhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhIRAhISEhISEhISEhISEhISEhISEhISEhISEhIYAhISEhISEpcnN0dXZAAA== 33 205 ISEhISEhGiEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhISEhIYAhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhIRAhISEhISEhISEhISEhISEhISEhISEhISEhIYAhISEhISEpcnN0dXZAAA== 218 !!!!!\026!!!!!!!!!!!C!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!!~!!!!!!!!!!!.!\128!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!C!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!~!!!!!!!!!!\016!!!!!!.!!!!!!!!!!!!!!!!!!!\128!!!!!!\)rstuv\@ ++AQABAQEAAAEBBBswGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbBhsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsVGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGyobGxsbGxsbGxsbGxsbGxsbGxsbzs7Ozs7Ozs7Ozs4bGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsmGxsbGhsbGxsbNRsbGxsbGxsbGw== 0 7 AQABAQEAAA== 15 \000.\001.\000 ++AQABAQECAQMbGwAAARsbGxsbGzobGyAbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbG2kbGxsbFRsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGwMbGxsbGxsbGxsbGxsbGxsbGxsbGxsiGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxvfGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsmGxsbGxsbGxsbGxsbGxsbGxsbGw== 0 -1 ++AQABAQECAQMBBAEFAQYBB+sIAQkBCgELxwwBDQEOAQEXJwEoAT42JT09PTYfNjY8NjYkFTY0NjYyAAABNjY2NjYADDY2S0sAAAEBFr4fRhQ2NjY2AAA2Nlg2iTw2HDY2NgAA/gABRDY2TjY2JBA2BLM2ojY2NjY2Bf8AG0Q2OTZNNiU9PT0BNlM2AAAAAQA2NDY2MjY2NjYyJjY2NjYAEDY2S0tLQAAAAUsBNr4fRhTDHzbAQDYufuzs7OwAAAHs7OwUNjY2NgAAAH//NjY0NjY2QTYAAAE+NjY2NjY2Nk7W0NCQ0AAUFBQUGjY1UzZDNlh/NjY2TTY2UQARAQA= 0 -1 ++AQABAQECAQMBBAEFAAABBwEIAQkBCgELAQwBDQEOAQ8BECABIQEiASMBJAElASYBJwEoAAw2NktLAAABARa+/kYkFTY0NjYyNjY2NjYADDY2S0sAAAEBFr7+RhQ2NjY2AAA2Nlg0djw2NjY2NgAA/t4BNjY2PDY2MxU2AbM2ojY2NjY2Bf82NjYAEDY2S0tLQAAAAUt//74fRhTANjQ2NiQ2NjY2NgAQNjZLAAABfvPs7OwAAAHs7OwUNjY2NgAAAAABNjY0NjY2QTY+NjY2NjY2Nk7Q1NCQ0AAUFBQUNjY1NjZDNlg2NjY2TTY2UQARAQA= 0 13 AQABAQECAQMBBAEFAA== 30 \000.\001.\002.\003.\004.\005 ++AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8CAgICAgICAoAAAgICAAABAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC 0 42 AQABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8CAgICAgICAoAA 107 \000.\001.\002.\003.\004.\005.\006.\007.\008.\009.\010.\011.\012.\013.\014.\015.\002\002.\002\002.\002\128 ++BOgAAAEDAwgINjY2NgAAAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAX//wU2NjY0NgAANjYWNjY259DQ0NDQ0NDQNjY2ABtLbEtLS0tLS0sBNr4fRhQ2NjY2AAA2NiQ2NjQ2NjY2NjY2NjY2NjY2NjY2NiQ2Nn92dnZ2dnZ2doF2dnZ2dnZBNgE2HgQF//8FNjY2NDYAAAkAAAGANjYWNjY20NDQ0NDQ0NDQf9DQ0NDQ0NDQ0NDQkNAAFBQAAAEUFDY2NjY2NjZYNjY2Nk0hNlEAEQEAAAE2Ng== 0 -1 ++BOgAAAEDAwgINjY2AAABNgAAAMAAAADAHzaAADY2JBU2NjYVNgAENjw2NjY2NjY2BAX//+fQ0NDQ0NDQ0DY4NjY2NjY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2AAAAAQAbS2xLS0tLS0tLATa+H0YUNjY2NgAANjYgNjY0NjY2NjY2NjY0NjY2NjY2NvoAAPp/dnZ2dnZ2dnZ2dnZ2dnaAQTYBNh4EBf//BTY20NDQ0NDQ0NB2dnZ2dnZ2dnZ2QTYB0NDQ0DPQ0NDQ0ND///+A0JDQABQUAAAaNk0hNlEAEQEAAAE2Ng== 0 -1 ++BOgAAAEDAwgINjY2NeYAAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAH//wU2NjY0NgAAAQDoAYA2NhY2Njbn0NDQ0DY2NjY2Fk//AAAAAAABABtLbEtLS0tLSwAAAQQ2NjQ2NjY2Nic2NjY2NjY2NgABAAA2Nn92dnZ2dnZ2dnZ2dnZ2dnZBNgE2HgQF//8FNjY2NDYAADY2NjY2Fk//AAAAAAABABtLbEtLS0sJAAABgDY2FjY2NtDQ0NDQ0NDQ0DPQw9DQ0NDQ0NDQ0JDQABQUAAABFBQ2NjY2NjY2aTY2NjZNITZAABEBAAABNjY= 0 88 BOgAAAEDAwgINjY2NeYAAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAH//wU2NjY0NgAAAQDoAYA2NhY2Njbn0NDQ0DY2NjY2Fk//AAAAAAABAA== 217 \232\000\000\001.\003\008\008.665\230\000\000\192\0316\128\00066\$\021666\0216\000\004666666666646X\004\001\255\255\00566646\000\000\001\000\232\001\12866.666\231\208\208\208\20866666\022O\255\000\000\000\000\000\001 ++BOgAAAEDAwgINjY2AAABAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAX//wU2NjY0NgAAAQAAAYA2NhY2Njbn0NDQ0NDQ0NA2NjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFDY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2NjY2NjY2JDY2f3Z2dnZ2dnZ2dnZ2dnZ2dkE2ATYeBAX//wU2NjY0NgAACQAAAYA2NhY2NjbQ0NDQ0NDQ0NAz0NDQ0NDQ0NDQ0NCQ0AAUFAAAARQUNjY2NjY2Nlg2NjY2TSE2UQARAQAAATY2 0 255 BOgAAAEDAwgINjY2AAABAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2NDZYBAX//wU2NjY0NgAAAQAAAYA2NhY2Njbn0NDQ0NDQ0NA2NjY2NjY2NjY2NgAAAAEENjY2NjY2NjY2NjY2NgAAAAEAG0tsS0tLS0tLSwE2vh9GFDY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2NjY2NjY2JDY2f3Z2dnZ2dnZ2dnZ2dnZ2dkE2ATYeBAX//wU2NjY0NgAACQAAAYA2NhY2NjbQ0NDQ0NDQ0NAz0NDQ0NDQ0NDQ0NCQ0AAUFAAAARQUNjY2NjY2Nlg2NjY2TSE2UQARAQAA 583 \232\000\000\001.\003\008\008.66\000\000\001\000\192\0316\128\00066\$\021666\0216\000\004666666666646X\004\005\255\255\00566646\000\000\001\000\000\001\12866.666\231\208\208\208\208\208\208\208\2086666666666.\000\000\000\001\0046666666666666\000\000\000\001\000\027KlKKKKKKK\0016\190\031F\02066666\000\000\000\001\00466666.6666666666666\$66\127vvvvvvvvvvvvvvvA6\0016\030\004\005\255\255\00566646\000\000\009\000\000\001\128.6\022666\208\208\208\208\208\208\208\208\2083\208\208\208\208\208\208\208\208\208\208\208\144\208\000\020\020\000\000\001\020\0206666666X6666M!6Q\000\017.\000 ++BOgAAGQAAAA2AAAAwB82gAA2NoAANjYkFTY2NhU2IAQ2NjY2NjY2NjY2NDYAAAFYBAX//wA2NjY0Nu//NTY2AAAAAQQ2NjY2////fzY0NiMAG0tsS2RLS0tLSwEAAAE2vh9GFDY2NjYAAAE2dnZ2dnZ2dnZ2dgAAAUE+ATYeBAX//wU2NjY0NgAACQAAaWlpaWlpaWlpaWnzaWlpaWn/f2lpaWlpaWlYNjY2Nk0hHVEAEQEAAAE2Ng== 0 6 BOgAAGQA 14 \232\000\000d ++BOgAAAEDAwgINjY2NgAAAMAfNoAANjYkFTY2NhU2AAQ2NjY2NjY2NjY2PSIjBCQlJicEPykqFQQsLS4uBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEVGRwRISUpLBExNQ08EUFFSWwRUVVZXBFhZWlsEXE1eXwRgYWJjBGRlZmcEaGlqawRsbR4fBCAhIiMEJCUmJwQoKSorBCwtJy8EgIGCgwT6hYaHBIiJiosENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwQ= 0 -1 ++AAABBOgAAEFAA+gYAAA2TgD/8sAQAAAAATAkAAABAAE2AwAAdj52ATT/YTk5GVQ5Ad42QCL7/zA= 0 1 AA== 2 . ++wMAAAcDgwMDANjY2NgAAGsAfNjY8NjYkFTo0NjYyNjY2NjYAEDY2S0s2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NiU9PT0BHzY2FDY2NjYAADY2WDZ2PDY2NjY2AAD+AAE2NjY8NjYkFTYEszaiNjY2NjYF//8FRTY5Nj42JT09PQEAAAABADY0NjYyNjY2NjYAEDY2S0tLQABAAUsBNr4fRhQ2////fyQVNgTAHzYufuwp7OwAAAHs7OwUNjY2NgAAAAAAAAE0NjYAAAE+NjY2NjY2Nk7Q0NCQ0AsUFBQUNjY1NjZDNlg2NjY2TTY2UQD//wVFNjk2PjYlPT09AR82NhQ2NjY2AAA2Nlg2djw2NjY2NgAA/gABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NjY2Bf//BUU2OTY+NiU9PT0BAAAAAQA2gAAAADY2NjY2ABA2NktLS0AAAAFLATa+H0YUNv///38kFTYEwB82Ln7s7OzsAAAB7OzsFDY2NhEBAA== 16 2 NjY2NgAQNjZLSzY2WDZ2PDY2NjY2AAABAAE2NjY8NjYkFTYEszaiNjY2JT09PQEfNjYUNjY2NgA= 98 666\000\01666KK66X6v<66666\000\000\001\000\001666<66\$\0216\004\1796\162666%===\001\03166\0206666 ++wMgAAcDgwMDANjY2NgAAGsAfNmY8NjY2QzZYNjY2NjY2NjYAAAE2S0s2NgFK4za+H0YUwB82Ln7s7OzsAAAB7BDsFDY2NjYAAAAAAf//NDZKNjZBNj42NjY2gDY2TtDQQTY+NjY2NjY2Nk7Q4tCQ0AAUFP////81NjZDNlg2Nhc2TTY2UQARAQA= 39 -1 ++wMAAAcDgwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0s2OFg2djw2NjY2NgAAAQABNjY2PDY2QDY1NjZDNgAAAVhAADY2TTY2UQARAQA= 16 -1 ++wMAAAcDgwMDANjY2NgAAGsAfNjY8NjY2cjY2NjY2ABA2NktLS0AAAAFLATYAAAEUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAAATY2NDY2NkE2PjY2NjY2NjZOHzY2PDY2JBU2NDY2MjY2NjY2AAw2NktLAAABARa+H0YUNjY2NgAANjZYNnY8NjY2NjYAAP4AATY2Njw2NiQVNgSzNjY2cjY2NjY2ABA2NktLS0AAAAFLATYAAAEUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAAATY2NDY2NkE2PjY2NjY2NjZO0NDQkNAAFBQUFDY2NTY2QzZYNjY2Nk02NlEAEQEA 16 -1 ++wKoAAcDgwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0s2Nlg2djw2NjY2NkAAAQABNjY2PAAAARU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BHzY2PDY2JBU2AAABMjY2NjY2AAw2NktLAAABARa+AAABNjY2NgAANjZYNnY8NjY2NjYAAP4AATY2Njw2NiQVJgSzNqI2NjY2NgX//wVFNjk2PjYlPT09ATY2NgAAAAEANjQ2NjI2NjY2NgAQNjZLgABAAAABSwE2vh9GFMAfNi5+7Ozs7AAAAezs7BQ2NjY2AAAAAAE2NjQ2NjZBNj42NjY2NjY2TtDQ0JDQABQUFBQ2NjU2NkM2WDY2NjZNQDZRABEBAA== 16 2 NjY2NgAQNjZLSzY2WDZ2PDY2NjY2QAABAAE2NjY8AAABFTYEszaiNjY2NjYF//8FRTY5Nj42JT09PQEfNjY8NjYkFTYAAAEyNjY2NjYADDY2S0sAAAEBFr4AAAE2NjY2AAA2Nlg2djw2NjY2NgAA/gABNjY2PDY2JBUmBLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NkuAAEAAAAFLATa+H0YUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAAATY2NDY2NkE2PjY2NjY2NjZO0NDQkNAAFBQUFDY2NTY2QzZYNjY2Nk1ANlEAEQEA 548 666\000\01666KK66X6v<66666\@\000\001\000\001666<\000\000\001\0216\004\1796\16266666\005\255\255\005E696>6%.==\001\03166<66\$\0216\000\000\001266666\000\01266KK\000\000\001\001\022\190\000\000\0016666\000\00066X6v<66666\000\000\254\000\001666.66\$\021&\004\1796\16266666\005\255\255\005E696>6%===\001666\000\000\000\001\0006466266666\000\01666K\128\000\@\000\000\001K\001.\190\031F\020\192\0316\.~\236\236\236\236\000\000\001\236\236\236\0206666\000\000\000\000\001664666A6>6666666N\208\208\208\144\208\000\020\020.\02066566C6X6666M\@6Q\000\017\001 ++P8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXe3+AbGxsbGxsbGxsbGxsbGxsbGxsbGyMbGxsbGxsbGxsbGxsbGxsbGxsbGxsbFRsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGwMbGxsbGxsbGxsbGxsbGxvW19jZ2tvc3d7f4BsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsVGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbAxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGyYbGxsbGxsbGxsbGxsbGxsbGxsb 0 -1 ++wMAAAcDAf////zY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjZLS0tLSwEWAZ8BoAGhAaIBowGkAaUBpgGxAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAG5AboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdFd4B3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QD+ 16 2 NjY2NktLS0tLARYBnwGgAaEBogGjAaQBpQGmAbEBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0V3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AA== 588 666KKKKK\001\022\001\159\001\160\001\161\001\162\001\163\001\164\001\165\001\166\001\177\001\168\001\169\001\170\001\171\001\172\001\173\001\174\001\175\001\176\001\177\001\178\001\179\001\180.\181.\182.\183.\184.\185.\186.\187.\188.\189.\190.\191.\192.\193.\194.\195.\196.\197.\198.\199.\200.\201.\202.\203.\204.\205.\206.\207.\208.\209.\210.\211.\212.\213.\214.\215.\216.\217.\218.\219.\220.\221.\222\001\223\001\224\001\225\001\226\001\227\001\228\001\229\001\230\001\231\001\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253 ++BA8EAgAsAID/////MjMEMjU2NwMEFgUEBf//9BEAHP/NBAb/f0AA6iAEICEiIwQkJTon+vr6+vr6BPYGACQICQoQAgAAAQABEgMEBAUEBQYHBEAA6iDkHyEiIwQkJSYn+vr6+vr6+vr6+vr0BBIdLC0u9gQwMSgMBwRkAAAgBEQAIAQgISI= 0 -1 ++BGQEAgAsAP//8/QQHALNBAb/9P+AFgAEBf//9AAQHALNBAb/9POAIAAiI/r6BgX2BgAkAAABCGQKEAIgBDYl+vr6fwAAAAAEIAAiI/r6BgX2BgAkAAABCGQKEAIgBDYlJif5+/rZ+voE9gYAJAhkChACIAO9AAESGQQEBQQFAwb/fwB/AAAELS72p6enp6enp6enp6enp6cgBJKSkqlxkiAhIg== 0 -1 ++BA8EAgAsAID/////LzMEMjU2NwMEFgUEBf//9BEAHALNBAb/f0AA6iAEICEiIwQkJSYn+vr6+gYHBEAA6iAEICEiIwQkJSYn+vr6+vr6+vr6fwABAAAdLC0u9gQwMSgMBwRkAAAgBBwAIAQgISI= 0 -1 ++BA8EAgAsAID/////MjMEMjU2NwMEJAUAAAH/9BD+HALNBAb/f0AA6iAEICEiIwQkJSYn+voX+vr6BPYGIwQkJSYnABDa+vr6+vr6AAAAgBIdLC0u9gQwMSgMBwRkAAAgBEQAIAQgISI= 0 99 BA8EAgAsAID/////MjMEMjU2NwMEJAUAAAH/9BD+HALNBAb/f0AA6iAEICEiIwQkJSYn+voX+vr6BPYGIwQkJSYnABDa+vr6+vr6AAAAgBIdLC0u9gQwMSgMBwRkAAAgBEQA 306 \015\004\002\000.\000\128\255\255\255\25523\0042567\003\004\$\005\000\000\001\255\244\016\254\028\002\205\004\006\255\127\@\000\234\032\004\032!\"#\004\$%&.\250\250\023\250\250\250\004\246\006#\004\$%&'\000\016\218\250\250\250\250\250\250\000\000\000\128\018\029,-\.\246\00401\(\012.\004d\000\000\032\004D ++73//AO4D9YDuBPOA/0QgIAogChk= 8 -1 ++BA8EAgAsAARAAOogBAIhIiMEJCUmJ/r6+vr6+vr68QT2AQAAAQkKEAIgA70AARIDBAQFBOjMBwRAAOogBAIhIiMEJCUmJ/r6+gAAAfr6+vr6+vr69AT5HSw9LvYEMC8AAAAAAQAAIAZEACAEICEi 0 -1 ++BAABAgMEBAUGBwQICQocHR4fBCAhIiMEJCUsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaMgRcXV5fBGBhYmMEZGVmZwRoaWprBGxtHh8EICEiIwQkJSYnBCgpKgAAAS0uLwSAgYKDBISFhocEiImKiwSMi46PBJCRkpMElJWWlwSYmZqbBJydnp8EoKGiggSkpaanBKipqqsErK2urwSwsbI= 0 126 BAABAgMEBAUGBwQICQocHR4fBCAhIiMEJCUsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaMgRcXV5fBGBhYmMEZGVmZwRoaWprBGxtHh8EICEiIwQkJSYnBCgpKgAA 207 \000\001\002\003.\004\005\006\007.\008\009\010\028.\030\031\004\032!\"#\004\$%,-\./\0040123\0044567\00489:\;.<=>?.\@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ2.\\]^_.`abc.defg.hijk.lm\030\031.\032!\"#.\$%&'.\(\)*\000 ++BAABAgL8BAUGBwQICQoAAAEfBCAhIjMEJCUsLS4vBDAxMjMENDU2NwQ4OTo7BDw9BFRVVmYEWFlaWwRcAAACBGBhYmMMZGVmZwRoAAABaWprBGxtHh8EICEiIwQkJSYnBCgpKisELC0uLwSYs5qbBISdhocEiImKiwSMjY6PBJCRkpMElJWWlwSYs5qbBJydnp8EoKGiowSkpab//6jLqqsErK2urwSwsbI= 0 -1 ++Ig== 0 -1 ++AAABAAAEBAUGBwQICQocHR4fBCAhIiMEJCUsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXV5fBGBhYmMEZGVmZwRoaWprBGxtHh8EICEiIwQkJSYnBCgpKisELC0uLwSAgYKDBISFhocEiImBiwSMjY6PBJCRkpMElJWWlwSYmZqbBKOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8WL0= 0 1 AA== 2 . ++BAAcAgMEBAUGBwQICQocHR4fBCAhIiMEJDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 -1 ++ACA= 2 -1 ++BOgCFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFQUVFRUVFRUVFRUVFRUVFRUVFRQVFRUVFRUVFQAAARUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRU5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5FRUVFRUVFRUVFRU3FRUDAwMDAwMDAAABCfoD6AID8AID 0 -1 ++BOgCFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFfQVFRUVFRQV+RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRU2FRUVFRUVBQUFBQUFBRUVFS0VFX//FRUVFRUVFRUVFQX//wUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRX6FBUVFRUVFRUVFRUAAAEVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFREVFRUVBQUVFRUVFRUVFRUVFRUVFRUVFRUVFfoUFRUVFRUVFRUVFQAAARUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVERUVFRUFBQUFBQUFBQUFBQUFBQUFBQUFBQQsLS4vBAAAAQAAAQ== 0 -1 ++BOgCFRUVFRUVFRUVFQAAAS8AAAEEMDH5fwQMDRIPECICECIGLi8EMDEqMwQ0NTYiBgQICfl+/AwNEg8EKjMEBwcHBwcHB8XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFhcXFxcXFxcXFxcXFxcXFxcXFxcXFxQAAAAHFyMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFwMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxQcHBwcHBykHBwcHBwcHBwcHBwcHBwcIBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHMzMzGjszMzMzMzMzMzMzMzMHBwcHBwcHBwcHBwcHBxYHBwcOBwcHBwcHByEHBwcHBwcHBwcHBwX//wUHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBwcHBwcHBwcCECIHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHFwcHBwcHAwcHBwcHBwIQIgIQIgYuLwAAAQQwMfl/BAwNEg8QIgIQIgYuLwQwMQMzBDQ1NiIGBAgJ+X8EDA0SDwQqMwQHBwcHBwcHxcXlxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcU3CCkqqwQsLS4vBDBBAgAAAQAfBAcHBwcHBwcHB+wGBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBweHBwcHBwcHBwcHBwcHBwcHBwcHcnJycnJycnJycnJycnJycnJycnJycldycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycgcHBwczMzMaOzMzMzMzMzMzMzMzMwcHBwcHBxYHBwcHBwcHBwcHBw4HBwcHBwcHIQcHBwcHBwcHBwcHBf//BQcHBwcHBwcHBwcHBwcHBwcHFwcHBwcHAAAAZAcHBwIQIgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcDBwcHBwcHAhAiAhAiBi4vAAABBDAx+X8EDA0SDxAiAhAiBi4vBDAxKjMENDU2IgYECAn5fvwMDRIPBCozBAcHBwcHBwfFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcUAAAABxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFBwcHBwcHKQcHBwcHBwcHBwcHBwcHBwgHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcGBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcOBwcHBwczMzMaOzMzMzMzMzMzMzMzMwcHBwcHBwcHBwcHBwcHFgcHBw4HBwcHBwcHIQcHBwcHBwcHBwcHBf//BQcHBwcHBwcHBwcBBwcHIgcHFwcHBwcHBwcHBwcHBwIQIgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHDQcXBwcHBwcDBwcHBwcHAhAiAhAiBi4vAAABBDAx+X8EDA0SDxAiAhAiBi4vBDAxAzMENDU2IgYECAn5fwQMDRIPBCozBAcHBwcHBwfFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxebFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXF//9//8XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcUHBwcHBwcHBwcHB3JycnJycnJychYXMzMzMzMzMzMRMzMzMzMzM/9/EwQUERYXBBgkGhsEFB0CECIGBAgJ+X8EDCcSDwQQERITBEAAFhbogAAAGwQUHQAaMwQ0MX/+//8ICQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHBwchBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBygHBwcHIAAHBwcHBwcHBwcHBwcXBwcHBwcHBwcHB8XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcW3xcXFxcXFxcXFxcXFxcXFxcXFxcXFxQcHBwc= 0 -1 ++BBwcHAwcHBwcHBw+9KgLAQEBQBwcHBwcwsI2Nv////82NjY2NjY2AAAAAQAjZyw2AAQ2NjY2Ngk2NjY2NIBYNgAQAcw2NjY0/zZLaUtLATa+dnZ2dh9GNjY2NjY2NjYAAAABABtn6gABbEsxS0tpS0sBNr52dnZ2H0Y1ADY2NgAANjYkNjY0LRAAATY2NjYZNjZPNjY2RzYkNk/pEIAAdnZ2dnZ2dv8LAED/NjY2NgAAAQABAAABAAEAgAAAATY2CjYJNjY2NjSAWDYAEAHMNjY2NP82S2lLSwE2vnZ2dnYfRjY2NjY2NjY2AAAAAQAbZ+oAAWxLMUtLaUtLATa+dnZ2dh9GNQA2NjYAADY2JDY2NC0QAAE2NjY2GTY2TzY2Nkc2JDZP6RCAAHZ2dnZ2dnY2AAHQ0JAABf//BRQ/NoABAAABWCs2NjY2//92VHaRdkBAQAAAAAAAAQAjZyw2AAQ2NjY2Ngk2NjYyNIAAAQAb 0 -1 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfAhBAAgQgKRcjBAQkAAACAEACEAACEEACECICECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGBQdHh8mNSkiGQQkJAAAAg5AAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQAAAIAQAIQIgIQQAIQIgIQAAA= 0 206 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfAhBAAgQgKRcjBAQkAAACAEACEAACEEACECICECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGBQdHh8mNSkiGQQkJAAAAg5AAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQAAAIAQAIQIgIQQAIQIgIQAAA= 626 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\016\@.\004\032.\023#\004\004\$\000\000\002\000\@\002\016\000\002\016\@\002\016\"\002\016\"\002\016\"\006\004\008\009\255\127\004\012\013\018\015\004\016\008\018\019.\001\021\022\023.\024\020\029\030.&5\)\"\025\004\$\$\000\000\002\014\@\002\016\"\002\016\@\002\016\"\002\016\"\002\016\@\002\016\".\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\".\016\@.\016\".\016\000 ++AgAAAuZAAhAiAhBAAhAiAhAiBgQICf9/BAwNAAABEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBAAABQAAAEACECQB8kACECIC8iEGBBAiAhBAAhAiAhAff////yMEByQAAAIAAAABQO0PAAIQQAIQDwIQImAQIh4ECAn/AR8mNSkiGQQkJAAAgiJAZBAiAhAAAAEigBACEAIQIgAAAgBAAhAAAA== 0 64 AgAAAuZAAhAiAhBAAhAiAhAiBgQICf9/BAwNAAABEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBAAABQAAAA== 202 \000\000.\230\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\000\000\001\018\015\004\016\008\018\019\004.\021.\023\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\000\000\005\000\000 ++BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUBJiZmpsEnJ2enwSgoaKjBKSlpqcEqKmqq1RVVldYWZWWlwSYmZqbBJydnp8EoKGiowSkpaanBKipqqtUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH0Afg== 0 -1 ++EgEABIAQABABAIOKAAAB6mtsAaurqwHqa2xtbauri6ChoqMAAAABPVxNP0ABAAEsBf//BQABT20AHgFo6OpzbG2rq6uJb3BxZBZ+ 0 -1 ++AQAAAIMFhIWGhweaiYqLBIyNjo7ykKcAgP//hpaDBISFhocEATY2NjY0hiABADY2NiMAgAAAAAABNjY2NjY2NjZ+AAAAAAAhHxtn6gABbEt2AAAAQBgzNjYAADY2JDY2NP9/ATY2NjY2FTYVTzYAQDY2JACAAAyAGQB2dnZ0dn//Yv8AAAE2NjY0Nt3d3d3d3d0AAAHd3cfd3d3d3d3diosEpI0AIAEAAQB4AAABNjYK3d3d3d3d3d3d3d3d3f3H3cft3d3d3d3diisEpI2PBJCnAID//4aWgwSEhYaHBIiOjwAAAbMgABYWFhYWFgAAARY2fXZ2dgAAAQAb 0 3 AQAA 5 \000 ++BICBgoMEhIWGhwSHiYqLBIyNjo8EkJGSkwQAAAGXBJiZmpsEnJ02AAAAAAsBZxU2AAQ2GjYAAQltbW1tbW1tbW1tbW1tbTY2NjY0gFg2ABABNjY2l5sEnJ02AAAAAAABZxU2AAQ2GjY2NgSYmZqbBJydNgAAAAAAAWcVNgA2NP82NjY2AAAA3gM/NjY2NjY2NjY2NjY2AAAAAQAbZ+oACmxLS0tLaUtLATa+dnaSdh9GFAA2AAABNjT/fzY2NjY2NhVDNk82ABAAACQ2Nv//gAB2dmX///9//wsAAAEiQP82NjYAAAFnFTY0NgHQ0NAz0NDi0NC9EAAA+y0UFAB2AAHQ0JAAABQUZAAAAIABAAABWCs2NjY2NnZ2dnZ2dkABAAAAAAEAGw== 0 41 BICBgoMEhIWGhwSHiYqLBIyNjo8EkJGSkwQAAAGXBJiZmpsEnJ02AAA= 133 \128\129\130\131.\132\133\134\135.\135\137\138\139.\140\141\142\143.\144\145\146\147.\000\000\001\151.\152\153\154\155.\156\1576\000 ++BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ02AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADe/3//NjY2NjY2NjYVNjY2NjYAAAABABtqampqbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2BAAVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/LDY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY3gAEAAAFYKzY2NjY2dnZ2dnZ2QAAAAAAAAQAb 237 1 AA== 2 . ++BGQDAwgINjZWNhU2NgE2NjY2NjY2NjYlNkk2NjY2NjY2NjY2NiIiIiIiLyIiIi8EMBQyMwQ0NTY3BDg5LTsEPD0+PwA= 0 -1 ++AAEAAQ== 0 1 AA== 2 . ++BOgDAwgINjZWNhU2NgE2NjY2NjY2NjY2NjY2UjY2AzY2NjY2NjY2NjYlNkk2NjY2NjY2NjY2NiIiIjYAAEVkNgAANjY2NjY2NgABQDY2NjYyNjYjQzb/fxN1Njb8NjaeQjwAIVkTNjY2Nfs2NjaeNFnkGDITNjY2NjbvHDf/fzY2NgAAAf///382VzY2NgA2NjY2NjY2NjY2NjY2BQAANjb/////NgAAAFw2f////zY2NjE2NjY2//82/382NjYAAAH///9/ZAABNjY2NjY2Np5eXl4RATYAAEVkNgAANjY2NjY2NgABQDY2NgABNg== 0 236 BOgDAwgINjZWNhU2NgE2NjY2NjY2NjY2NjY2UjY2AzY2NjY2NjY2NjYlNkk2NjY2NjY2NjY2NiIiIjYAAEVkNgAANjY2NjY2NgABQDY2NjYyNjYjQzb/fxN1Njb8NjaeQjwAIVkTNjY2Nfs2NjaeNFnkGDITNjY2NjbvHDf/fzY2NgAAAf///382VzY2NgA2NjY2NjY2NjY2NjY2BQAANjb/////NgAAAFw2f////zY2NjE2NjY2//82/382NjYAAAH///9/ZAABNjY2NjY2Np5eXl4RATYAAEVkNgAANjY2NjY2NgABQDY2NgA= 460 \232\003\003\008.66V6\02166\001.666666666666R66\0036666666666%6I66666666666\"\"\"6\000\000Ed6\000\000666.666\000\001\@6666266#C6\255\127\019u66\25266\158B<\000!Y\0196665\251666\1584Y\228\0242\01966666\239\028.\255\127666\000\000\001\255\255\255\1276W666\0006666666666666\005\000\00066\255\255\255\2556\000\000\000\\6\127\255\255\25566616.66\255\2556\255\127666\000\000\001\255\255\255\127d\000\0016666666\158^^^\017\0016\000\000Ed6\000\0006666666\000\001\@666 ++ATY= 0 -1 ++BOgDAwgINjZWAAABNgE2NjY2NjY2NjY2NjY2UjY2AzY2NjY2NjY2NjYlNkk2NjY2Ni02PTY2NiIiIjYAAEVkNgAANjY2NjY2NgABQDY2NjYyNjYjQzb/fxN1Njb8NjaeQgAAATwAIVkTNjY2Nfs2NjaeNFnkGDITNjY2Izb/HDf/f1Q2NgAAAQAAF4AA/382VzY2NgA2NjY2NjY2NjY2NjY2AAAANmT/////FgAAAQAANjb/////NgAAAFw2f////zY2NjE2NjY2//82//9/ZAABNjY2NjY2Np5eXl4RATYAADY2NjY2NjY2NlI2NgM2NjY2NjY2NjY2JTZJNjY2NjYAAAE2NjYiIiI2AABFZDYAADY2NjY2NjYAAUA2NjY2MjY2I0M2/38TdTY2/DY2nkIAAAE8ACFZEzY2NjX7NjY2njRZ5BgyEzY2NjY2/xw3/382NjYAAAEAAAGAAP9/Nlc2NjYANjY2NjY2NjY2NjY2NgAAADY2/////wAAAAEAADY2/////zYAAABcNn////82NjYxNjY2NjY2NgABQDY2NgABNg== 0 -1 ++BAFXAAIEAg== 2 -1 ++BOgDAwgINjZWNhU2NgE2NjY2NjY2NjY2NjY2UjY2EzY2NjY2NjY2NjYlNkk2NjY2NjY2NjY2NiIiIiIiIkAiNugDNjY2NjY2NjY2NjZDNjY2NpiYmDY2NjYiICIiIiIiIiIiIiIiIiJJNjY2NjY2NjY2NjYiIiIiIiJAIjboAzYiIiIiIiIiIiIiIiI2NjY2JzY2NjZkZAAANjY2NjY2NjY2NjYiIiIiIiJAIjboAzYiIiIiIiIiIiIiIgA2NjY2TV8EYGFiYwRkZWZnBGhpamsEbG0eNgQgISIjBCQlJicEKCkqKwQsLS4vBICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaIAAA== 0 -1 ++7I2NjY2NjY2NjY2NjQACjY2NjY2NjY2NjY2NjY2NjY2NAAKNjY2NjY2NjY6NjY2NjY2NjY2Nm42NjY2NjY2NjY2NjWyNjY2NjY2kjY2NjY2NjY2NjTY2NjY2PQAAATY2RDY2U1I2NgAAAQM2NjY2Nvc2dnbQKjYQTfgFACEANzI2OekAABA2NjY2EABxGwAAATY2AAABAHZ2dnZ29g== 0 -1 ++BOgAATY2NjY2fwDiNjY2NjY2NjY2NgAAATY2NjY2NjYmNjb/ADY2NjY2AwAAAQT9BQcICXx8fHx8fHx8AAABAHx8fHx8IAB8 0 61 BOgAATY2NjY2fwDiNjY2NjY2NjY2NgAAATY2NjY2NjYmNjb/ADY2NjY2AwAAAQT9BQcICXx8fHx8fHx8AA== 123 \232\000\0016.666\127\000\2266666666666\000\000\0016666666&66\255\00066666\003\000\000\001\004\253\005\007\008\009|||||||| ++wMAAAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNgAQwMAAAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABPjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Nn7s7OzsEBQUDDY2NgAAATY2NjZYNjY2Nk02NlEAEQEANjYABf//BUU2OTY2NiU9PT09NgAAAV8//3Y2AAABNjY0NgAAAYA2PRAANjYAAAABADY0NjYyNjY2NjYAEDY2S0tLQAAAAUsBNr4fRhTAHzY2fuzs7OwQFBQMNjY2AAABNjY2Nlg2NjY2TTY2UQARAQA2NgAF//8FRTY5NjY2JT09PT02AAABXz//djYAAAE2NjQ2AAABgDY9EAD7+/v76fv7+////w== 16 -1 ++wMAAAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUX/gDY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Nn7s7OzsEBQUDDY2NgAAATY2NjZYNjYkNk02f/8AEQEANjYABf//BUU2OTY2NiU9PT09NgAAAfI//3Y2AAgBNjY0NgAAAYA2PRAA+/v7+/v7+/v///8= 16 -1 ++BAABAgMEBAUGBwQICQoLBBINDg8EEBESEwQUFRYXBBgZGhsEHB0eNjY2AAA2NjY2Njw2ATYYNkUAAAIQ//9/TExMTExMTExMTExMTExMTExMTExMTENMTBMTExNqEykTlhMTEyYLAAEUFAAABjY2NjYAAAE2NhwAAAABAAABBDb/fwAAAzYAAQX//wU2NgD7SDYkNjk5OTk5OTk5OTk5OTk5OTk5OTk5PTY0pjY2NjY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Coq0DPQ0P/QM9DQ//9//9AAAAHSu9DRkNAABgAA/xQUAAAGfzYkNjY0Nks2AAQeVTb/AAABNn////8= 0 -1 ++xcXFxcXFxcXFxcXFxcXFxcXFxcXFxRDAwExMaExMTExMHzY7TTY2JBU2NDY2MjY2NjY2AxA2NktLS0tLwDY2NjYAABrAHzY2MzYQAN4HBzc2ATY2AxA2NktLS0tLwDY2NjYAABrAHzY2NjY2NjYWvh8AAAFGFDA2NjYAADY2WDZ2PDY2NjY2ADY2NjY2NjYAAAE2NjY2NgMQNjZLS0tLS8A2NjY2AAAawB82NjY2NgCAAAA2NjYuLi4uLi4uLi4hLi4uLi4uLi4uLi4uLi4uNjY2NjY2NjY2ozY2NjZENiU2njY2NjY2NjY2NjY2NjY2FzY2NgAA 197 48 Li4uLi4uLi4uLjY2NjY2NjY2NqM2NjY2RDYlNp42NjY2NjY2NjY2NjY2Nhc2NjYA 65 \.\.\.\.\.\.\.\.\.666666666\1636666D6%6\15866666666666666\023666 ++ASY= 0 -1 ++AAEAIA== 0 1 AA== 2 . ++BBABggMEBAAABBABggMEBAUG6wQICQoLBAxuBBQtLiBQMwQzNVEENDUpNwQ4ADkEMDFQKhcELC0uIAQwMVAzBAQzNTY0NQ== 0 -1 ++AAAAGxsfGxv51ED/ACBk/vYbGxsbGxsbWRsbBQAbGxwbEAAAAAEb/QEAgACYAAEbGxsbGxtAG9EbJhsbAAAAGwMbJhsbAAAABwAg0rBpaWlpaWlpaWlpaWJpaWlpaQAAAAAAAQAAHSmJGw== 27 -1 ++AACrq6r/7Q== 0 1 AA== 2 . ++BAABAgLgAeEBgADjAeQB6QHqAesB8wH0AfUB9gH3AfgB+QH6AfsB/AEaAv4= 0 -1 ++/38AAAEAAAHj/CGaygAEAAA= 0 -1 ++BAABAgICAgICAgICLhwEMDEzAiMEABD/BCEiI1UNDg8GBA81/QQUIyT6AAD6LgAAAANAAAAALi4uLi4uLk8uLi4uLi4uLiMAAAIAAA4= 0 -1 ++BAABAgICAgICAgICLhwEMDEyMwICAgICAgQUFRYXAgICAgICAnWAAAAABCIjBACQ/wQhIiNVDQ4PBgQPCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoSEwQUIyT6AAD6LgAAAANAAAAALi4uLi48Lk8uLi4uLi4uLiMAAAIAAA4= 0 40 BAABAgICAgICAgICLhwEMDEyMwICAgICAgQUFRYXAgICAgICAnWAAA== 106 \000\001\002\002.\002\002.\002\002.\.\028.0123.\002\002.\002\002.\020\021\022\023.\002\002.\002\002.u\128 ++BAABAgICAgICAgICLhwEMDEyMwIGBgYGBgYkBgICAgICBBQVFhcCAgICAgICdSMEDQAEIgAAARD/BCEiI1UNDg8GBA8SEwQDIyT6AAD6LgAAAANAAAAALi4uLi4uLk8uLi4uLi4uLiMAAAIAAA4= 0 77 BAABAgICAgICAgICLhwEMDEyMwIGBgYGBgYkBgICAgICBBQVFhcCAgICAgICdSMEDQAEIgAAARD/BCEiI1UNDg8GBA8SEwQDIyT6AAA= 228 \000\001\002\002.\002\002.\002\002.\.\028.0123.\006\006.\006\006\006\$\006\002.\002\002.\004\020.\022\023\002\002\002\002\002\002\002u#\004\013\000\004\"\000\000\001\016\255.!\"#U.\014\015\006\004\015\018\019\004\003#\$\250\000 ++d3gXBf//BUcQp0CAAAABfx4= 2 -1 ++ZAABAgICAgICZS3RA3d3dwdleGFtcIhlA2NvbQAAAQABwAw= 0 -1 ++Af8= 0 -1 ++BAABAgICAgICAgICLhwEMDEyMwICAgICAgICAgICAgICAgICAgICAgICAgICLhwEMDEyMwQ0NXYBdwF4AXkBegF7AXwBfQF+ATZuAW8BcAFxAXIBcwF0AXUBdgF3Af8BeQF6AXsBfAF9AX4BfwA= 0 110 BAABAgICAgICAgICLhwEMDEyMwICAgICAgICAgICAgICAgICAgICAgICAgICLhwEMDEyMwQ0NXYBdwF4AXkBegF7AXwBfQF+ATZuAW8BcAFxAXIBcwF0AXUBdgF3Af8BeQF6AXsBfAF9AX4BfwA= 228 \000\001\002\002.\002\002.\002\002.\.\028.0123.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\002.\002\..\0040123\00445v\001w\001x\001y\001z\001{\001|\001}\001~\0016n.o.p.q.r.s.t.u.v.w.\255.y.z.{.|.}.~.\127 ++BAABAAABAwgINjY2NgAAAMAfNjZkAAAAAAEAFPY2HjY2NPoAAPoABAEAAAE2NgAAATb7IPvz+/sAAAFCAAABRDYkDzI0NjY2NjY2NjYAAAABNlg2Nv9/NjY2NgAAAQA2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2/zY+NjY2NjYAADYA/wA2DAEAAQH0wB82NjY2 0 -1 ++ABAAFwMfExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4BPw== 0 1 AA== 2 . ++hBABAgMAAAERCf//hBABAgMsARAAAAFkCQsADwAQANRMAACEMAECAwAAAAABHQEBKUIK 0 -1 ++AAFAAGQpCgo= 0 1 AA== 2 . ++BBABAAABf/8BCQEBAQACENQBAQEBAQEBAQEBAWQBAAEBAgEBAQEBKSkp 0 -1 ++BBABAgMsLUcBCQEBAQACENQBAQEBAQEBAQEBAWQBAAEBAgEkAQEBKSkp 0 -1 ++BBABAgMsLS4A/zA0MvoAAPo2NwQ4PD03PwAEJwRZWVlZWVlZWVlZGwABHR4fBCA2IiMEJCUmJwQoKQACEu4rLS4v9y+ysn8ENDU2NwQ4ORUWFwQgISIjBCSyBDQ1Nh0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAAAR0dHR0dHR0dHR0dHR0+HR0dHR0dHR0dDx0dHR0dHR0dHR0dHR0FHR0dHR0dHR0dHR0dHR0dFR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0UHR0dHR0dHR0dHQAAAR0BAwAAAQT9BQcICXy0BDB8fHx8AAABAHx8fHx8IAB8 0 222 BBABAgMsLS4A/zA0MvoAAPo2NwQ4PD03PwAEJwRZWVlZWVlZWVlZGwABHR4fBCA2IiMEJCUmJwQoKQACEu4rLS4v9y+ysn8ENDU2NwQ4ORUWFwQgISIjBCSyBDQ1Nh0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQAAAR0dHR0dHR0dHR0dHR0+HR0dHR0dHR0dDx0dHR0dHR0dHR0dHR0FHR0dHR0dHR0dHR0dHR0dFR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0UHR0dHR0dHR0dHQAAAR0BAwAA 709 \016\001\002\003.-\.\000\255042\250\000\000\25067\0048<=7?\000\004'\004YYYYYYYYYY\027\000\001\029\030\031\004\0326\"#.\$%&'.\(\)\000\002.\238+-\./\247/\178\178\127\0044567\00489.\022\023\004\032!\"#\004\$\178\004456\029\029\029\029\029\029\029.\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\000\000\001\029\029\029\029\029\029\029\029\029\029.\029\029>\029\029\029\029\029\029\029\029\029\015\029\029\029\029\029\029\029\029\029\029\029\029\029\005\029\029.\029\029\029\029\029\029\029\029\029\029\029\029\021\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029\029.\029\029\029\029\029\029\029\029\029\029\029\020\029\029\029\029\029\029\029\029\029\029\000\000\001\029\001\003\000 ++4BABAgMsLTw9Nz8ABCcWFwQYGRobBBwdHh8EICEiIwA= 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDgICAgICAicEKCkqqwQsLS4vBDACAi0uLwQwAgICAgICEAICAgICBCgpKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/AA== 0 -1 ++BAABAgMEBAUGBwQICQoLBAwNDgICAgICAicEKCkqKwQsLS4vBDACAgICAgICAgABADY2JzY2NjQ2WDY2NoAAAAA2AAABNjY2AAAAAMAfNjY2NjYkFTY0NjY2NjY2NjY2NjY2NjYAAAABBDY2NjY2NjY2NjY2NjYAAAABABtLbEtLS0tLS0sBAAABRhQ2gDY2NjY2NjY2NjY2NjY2NjY2NiQ2Nn92dnZ2dnZ2dnZ2dnZ2AXZBNgE2HgQAQP82NjY2NDYAAAEAAAGANhkWNjY20NDQ0NDQ0NDQM9DQ0NDQ0NDQ0NDQkNAAFBQUFDY2NjY2NjZYNjY2Nk02NlEAEQEAAAEjNjZFNjk2NjYlPT09VDYAQP82NjY2NDYAAAGANj0QAPsAAAH7AAAAZPv7+/sg+/v7+0JEAAABNgsLCwsLCwsLCwsLCwsLCwuYCwsLCwsLCwsLCws= 0 -1 ++AQLAAA== 0 -1 ++BAABAgMEBAUGBwQEDA2ADwQQBBgZGhsEHB0hIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFRkcESElKSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EYGFiYwRkZWZnBGhpamsEbG1ubwRwcXJzBHR1dncEeHl6ewR8fX5/BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaKjBKSlpqcAAAGqqwSsra6vBLCxsrME 0 195 BAABAgMEBAUGBwQEDA2ADwQQBBgZGhsEHB0hIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+PwRAQUJDBERFRkcESElKSwRMTU5PBFBRUlMEVFVWVwRYWVpbBFxdXl8EYGFiYwRkZWZnBGhpamsEbG1ubwRwcXJzBHR1dncEeHl6ewR8fX5/BICBgoMEhIWGhwSIiYqLBIyNjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaKjBKSlpqcA 415 \000\001\002\003.\004\005\006\007.\004\012\013\128.\004\016\004\024\025\026\027\004\028\029!\"#\004\$.&'\004\(\)*+\004,-\./\0040123\0044567\00489:\;\004<=>?\004\@ABC.DEFG.HIJK.LMNO.PQRS.TUVW.XYZ[.\\]^_.`abc.defg.hijk.lmno.pqrs.tuvw.xyz{.|}~\127.\128\129\130\131.\132\133\134\135.\136\137\138\139.\140\141\142\143.\144\145\146\147.\148\149\150\151.\152\153\154\155.\156\157\158\159.\160\161\162\163.\164\165\166\167 ++GxsAAAEbGxsbGxsbGxsbAxsbGxsbGxsbGxsYIBsbGxsbGxs2GxsbGxsbGxsbCxsbGxsbGxsbGxsbFRsbGxsbGxubGxs3GxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsUGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx8DGxsbGxsbAAEbGxsbGxsAAAHqGxsa+gAbGxsbGxsbGxsXGxsbGxsbG4AbGxsbGxsbGxsbGxsbGxsbGxsbGxv7GxsbGxsbGxsbGxsbGxsbGxsbGxs0G/waGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbJh8bGxsEGxsbGxsbGzEbGxsbAPoAAPo= 155 -1 ++BBgfKgAA 0 6 BBgfKgAA 14 \024\031*\000 ++wMAAAAABAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2MzYAEDY2S0tLABBQNktLS0tLATY2/+I2Nlg2djw2NjYAAAE2KQAAAf+ANjY2PDY2MRU2BLMF9AAB//8FRTYAEDY2S0tLQAAAAUsQNr4fRhTAHzY2fuwAAAHsrOwQAAABJBQMNjYAABAANjY2LVg2NjY2NiQVNjQ2NjI2NkMzNgAQNjZLS0s2JUU2HzM2ABA2NktLS0tLARu+H0YUNgABgDY9ARa+H0YUNjYQAPv7+/v7+/v7//8b 16 1 AA== 2 . ++wMAAAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Nn7s7OzsEBQUDDY2NgAAATY2NjZYNjY2Nk02NlEAEQEANjYABf//BUU2OTY2NiU9PT09NgAAAfJAFXaANj0QAPv7+/v7+/v7//// 16 -1 ++wMAAAcDAwMDANjY2NgAAGtgfNjY8NjYkFTY0NgAAAGQ2NjYAEDY2S0tLS0sBFr4fADaiNjY2NjYF//8FRTY5Nj42JT09PQE2NjYAAAABADY0NncyNjY2NjYAEDY2S0tLQAAAAUsBNr4fRhTAHzY2QOzs7OwQFBQMNjYQAAABNjY2Nlg2NjY2TTY2UQARAQA2NgAF//8FRTY5NjYqJT09PT02AAAB8j//djYAAAE2NjQ2AAABgDY9EAD7+/v7+/v7+////w== 16 -1 ++wMAAAcDAwMA2JBU2NDY2MjY2NjY2ABA2NjY2NjYAADY2WDZ2PDY2NjZLS0tLSwEWvh9GFDZFNjYAADY2WDZ2PDY2NjY2AAABAAE2NjY8NjYkFTYEszaiNjY9NjYF//8FRTY5Nj42JT09PQE2NjYAAAABADY0NjYyNjY2NjYAECc2S0tLQAAAAUsBNr4fRhTAHzY2fuzs7OwQFDY2Nlg2JDY2TTY2UQARAQA2NgAF//8FRTY5NjY2JT09PT02AAAB8j//djYAAAE2NjQ2AAABgDY9EAAAAAH7+/v7+/v7+////w== 16 -1 ++wMAAAcDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ogAENgAQAAD/BWM2OTY+NCU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YQwB82Nn7s7OzsEBQUDDY2NgAAATY2NjZYNjY2Nk02NlEAEQEANjb4Bf//BUU2OTY2NiVEPT09NgAAAfI//3Y2AAABNjY0NgAAAYA2PRAA+/v7+/oAAPr///8= 16 2 NjY2NgAQNjZLS0tLSwEWvh9GFDY2NjYAADY2WDZ2PDY2NjY2AAABAAE2NjY8NjYkFTYEszaiAAQ2ABAAAA== 127 666\000\01666KKKKK\001\022\190\031F\0206666\000\00066X6v<66666\000\000\001\000\001666<66\$\0216\004\1796\162\000.6\000\016\000 ++wMDzAMDAwMDANjY2NgAAGsAfNjY8NjYkFTY0NjYyNjY2NjYAEDY2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2NgAAAQABNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Nn7s7Ow9PT09NgAAAewQFBQMNjY2AAABNjY2Nlg2NjY2TTY2UQARAQA2NgAF//8FRTY5NjY2JT09PT02AAAB8j//djYAAAE2GjQ2AAABgDY9EAD7+/v7+/v7+/9k/w== 16 -1 ++wMAAAcDAwMDANjY2NgA2S0tLS0sBFr4fRhQ2NjY2AAA2Nlg2djw2NjY2BLM2ojY2Bf//BUU4OTY+NiU9PT0BNjY2AAAAAQAuNDY2YjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Nn7s7OzsEBQUDDY2NgAAATQ2NjZYNjY2Nk02NlEAEQEANugDBf//BUU2OTY2NiU9PT09NgAAAfI//3ZCAAABNjY0NjY2NgAAAYA2PRAA+/v7+/v7+/v/ABA= 16 -1 ++wMAAAcDAwMDANjYEHB0eHwQgISIjBCQlJicAKCkqKwQsLS4vBAkJCQkJCQkJCQkJAAABCQkJCQkJCQkJCQkJCTAxMjP+MzU2NwQ4OTo7BDw9 16 11 BCAhIiMEJCUmJwA= 15 \032!\"#.\$%&' ++AX8= 0 -1 ++AQ== 1 -1 ++wMAAAcDAwMDANjY2NgAbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbwxsbGxsbGxsbGxsbGxsbGxsCGxsbGxsbGxsbGxsbGxsbGxsVGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxkbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbAxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGyYbEBsbGxsbGxsbGxsbGxsbGxsb 16 -1 ++wMAAAQAAAcYEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYX6hcZGhsEHB0eBwcHBwcHBwcHB/cHBwcHBwcHBwcfBCAhIvIAASMEJCUmEAQoKSorBCwtLi8AMA== 16 53 CgsEDA0ODwQQERITBBQVFhfqFxkaGwQcHR4HBwcHBwcHBwcH9wcHBwcHBwcHBx8EICEi8gA= 188 \011\004\012\013\014\015\004\016\017\018.\004\020\021\022\023\234\023\025\026\027\004\028\029\030\007\007\007\007\007.\007\007\007\007\247\007\007.\007\007\007\007\007\007\031.\032!\"\242 ++AgAfBCApIiMEJCTrJwQIKSqrBCwtLi8EMEECAB8EBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwYHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBzMzMxo7MzMzMzMzMzMzMzMzBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHBwchBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHAhAiBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBwcHBwcHBwcCECICECIGLi8AAAEEMDH5fwQMDRIPECICECIGLi8EMDEqMwQ0NTYiBgQICfl/BAwNEg8EKjMEBwcHBwcHBwcHBwcHBwcHBxAREhMEFBESQAABFhczMzMzMzMzMxEzMzMzMzMz/38TBBQRFhcEGCQaGwQUHQIQIgYECAn5fwQMJxIPBBAREhMEQAAWFuiAAAAbBBQdABAzBDQxf/7//wgJBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcOBwcHBwcHByEHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBwcHBwcHBwcHBwd/AAQkNB0CECICEEACECICECISQAABFhcEGBkaGwQUHSAfADMzMw== 0 -1 ++AAEAEP8AAQD3 0 1 AA== 2 . ++AegDCAg2HzY2AAAAwB82NjY2NiQVNjQ2NjY2NjY2NgAQNgAAATY2NjY2NjY2AAABAAE2NjZFNjYVNgAENjY2NjY2JzY2NjQ2WDY2NjY2NjY2AAABNjY2AAAAAMAfNjbj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+Pj4+M2NjYkFTY0NjY2NjY2NjY2NjY2NjYAAAABBDY2NjY2NjY2NjY2NjYAAAABABtLbEtLS0tLS0sBAAABRhQ2gDY2AAA2NiQ2NjQ2NjY2NjY2NjY2NjY2NjY2NiQ2Nn92dnZ2dnZ2dnZ2dnZ2dnZBNgE2HgQAQP82NjY2NDYAAAEAAAGANhkWNjY20NDQ0NDQ0NDQM9DQ0NDQ0NDQ0NDQkNAAFBQUFDY2NjY2NjZYNjY2Nk02NlEAEQEAAAEjNjZFNjk2NjYlPT09VDYAQP82NjY2NDYAAAGANj0QAPv7+/v7+/v7+/sg+/v7+0JEAAABNgsLCwsLCwsLCwsLCwsLCws= 0 -1 ++Bf//BcDAwMDANjY2NgAAVwECAVcBAQIBVwEBAQECAVcAAA== 16 17 AQIBVwEBAgFXAQEBAQIBVwA= 34 \002.W.\001.\001W.\001.\001.\001W ++BAABAgMEBAUGBwSICQoLBAwA//wNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIj538lRicEKCkqKwQsLS4vBDAxMjMENDU2PgQ4OTo7BDwQPj8A 0 -1 ++BAABAgMEBAUSEwQUFRYXBBgZGhsEHB0eOQQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw8Pj8A 0 66 BAABAgMEBAUSEwQUFRYXBBgZGhsEHB0eOQQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw8Pj8A 131 \000\001\002\003.\004\005\018\019.\020\021\022\023.\024\025\026\027.\028\029\0309.\032!\"#.\$%&'.\(\)*+.,-\./.0123.4567.89:\;.<<>? ++NwAAAAABAQQdIh8EICEiI/8QJSYnBCgpA+j4LBvrGx0eHwQgISKGBKQlJicEKP8qKwAAG4aGhgAQhoaGhoaGhoaGIh8EIICGhoY4PT5SAA== 0 -1 ++AAABAgMEBAXrBgQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8A 0 1 AA== 2 . ++AAEBAgMEBAUGBwQICQoLBAwNBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEAgKSIjBAQkAAACAEACAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYOhobBBQdHh8mNSkiGQQkJAAAAg5AAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQAAAIAQAIQIgIQQAIQIgIQAAA= 0 1 AA== 2 . ++BAABAAABBAUGDQYECAn/fwAAARIPEBAJCgsEfwAAABMEByAACQoLBGQNEgkQEAgSEwQBFRYXBBg6Gv9/Hx0eHw01KSIZBCQkAAD/AEACECICEEACECLzDyIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAJkAAIQQAL+AgAQywIQIgYECAn/fyQkAAAAAAECDkACQCIAAAECEEACJiIBBCQkAAACAEACECJTENQCECICEAAA 0 -1 ++5f8AAgAAAAEEBAX/ZAAICQoL5AwNBgQIgAAAAA38DgQQCBIZBCQcAAAAAUACEP9kAAgJECLtECL/D///AhBAAhAiAhAtBCApIiPpEgAAAAABAAIAQAAAAQJkAAIQCAAAEAAFACkJ/wL/fxcKGOoAAToa/wIcJ/R6enp6enp6enp6enp6enp6enp6enp6AAECA+gAAIACECICEAAA 0 -1 ++A9YBAgMmAAABBwQIGQoACwQMCxQMDQ4AAAAA 0 -1 ++lJWWogwA6P8A 0 -1 ++wMAAAQBkn8CiNjY2NgAAGsAfNjY8yQAhEAACCSICAgIQIgIQQAA= 16 2 AhAiAhBAAA== 14 \016\".\016\@ ++3g== 0 -1 ++AQ== 0 -1 ++AgAAAhBiAgAAAhAiAQECAVcBAQIBVwIQYgIAAAIQAQIBVwEBAhBiAgAAAhAiAVcBAgFXAQECAVcBAQEBAgFXAAAB 0 64 AgAAAhBiAgAAAhAiAQECAVcBAQIBVwIQYgIAAAIQAQIBVwEBAhBiAgAAAhAiAVcBAgFXAQECAVcBAQEBAgFXAA== 146 \000\000.\016b.\000\000.\016\".\001.\001W.\001.\001W.\016b.\000\000.\016\001.\001W.\001.\016b.\000\000.\016\".W.\002.W.\001.\001W.\001.\001.\001W ++AQABAwEJAQoYARkBGmwbARwHGgEeAc0BAAAB0AAAA+gB01NTAZ8= 0 -1 ++wMAAAcD/AMAbAgICAgICAgIAAgICAgABAAA= 16 7 AgACAgICAA== 18 \000\002.\002\002 ++BOgAAAEDAwgINjY2NgAAAMAfNjZkAAAAAAEAFPY2HjY2NDYMAAEABAEAAAE2NgAAATb7IAAAAfsAAAFCRDYkDzI0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTY2FTYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/zY+NjY2NjYAADYAAPs2DAEAAAH0ATY2Njw2NiQVNgSzNqI2NjY2NgX//wVFNjk2PjYlPT09ATY2NgAAAAEANjQ2NjI2NjY2NgAQNjZLS0tAAAABSwE2vh9GFMAfNi5+7Ozs7AAAAezs7BQ2NjY2AAAAAAE2NjQ2GTZBNj42LTY2NjY2TtDQ0ID///8UFBQ2NjU2NkM2WDY2NjZNNjZRABEBAA== 0 -1 ++BDY2KwAAAMAfNjZkAAAAAAAAFHY2HjY2NDYMAAEABAEAAAE2NgAAATb7IPvz+/sAAUsBNr4fRhTAHzYufuzs7OwAAAHs7OwUNgABQkQ2JA8yNDY2NjY2NjY2ABA2Nj1YNjY2NjY2NjYAAAEAATY2NkU2EzY2HDQ2WAAgNjb/Nj42NjY2NgAANgAA+zYMAQAA8PMBNjY2PDY2JBU2BLM2ojY2NjY2Bf//BUU2OTY+NiU9PT0BNjY2AOj/AAAyNDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAg+/P7+wAAAUJENiQPMjQ2NjY2SDY2AAE2NjQ2NjZRQzZYNjY2Nk02NlEAEQEA 0 6 BDY2KwAA 8 66+\000 ++BOgANvsE+/vZ+wAAAX////8AMjQ2DjY2NjY2NgAAAID//wEAWCD7T1ZYEzY2NjY2NjYAAAEAATY2NkU2NhU21dXn1dXVINXV1dXV1dXV1dXV1RDV1dXL1dXV1dUABDk2NgAAAv///4c2PjY2NlY2AAAfRhTAHwAAA+g2PDY2fuzs7OwVAAAAADY2UQAR9gA= 0 11 BOgANvsE+/vZ+wA= 31 \232\0006\251.\251\251\217\251 ++BOgAAAEDAwgINjYxNgD/5MApIPvz+wAAAQFCRDYkHjY2NDYMAAE2NjY2NjYAEDY2Nlj7IPvz+/sAAAFCRDYkDzI0NjY2NjY2NjYAEDY2Nlg2EzY2NjY2NgAcAQABNjY2RTY2FTYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/zY+NjY2NugDADYAAPs2DAEAAAH0ATY2NjwpNiQVNgSzG6I2NjY2NgX//wVFNjk2PjYlPT09ATY2NgAAAAEANjQ2NjI2NjYfNjZkAAAAAAEAFPY2HjY2NDYMAAEABAEAAAE2NgAAAezs7BQ2NjY2AAAAAAE2NjY2QzZYNjY2Nk02NlEAEQEA 0 202 BOgAAAEDAwgINjYxNgD/5MApIPvz+wAAAQFCRDYkHjY2NDYMAAE2NjY2NjYAEDY2Nlj7IPvz+/sAAAFCRDYkDzI0NjY2NjY2NjYAEDY2Nlg2EzY2NjY2NgAcAQABNjY2RTY2FTYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/zY+NjY2NugDADYAAPs2DAEAAAH0ATY2NjwpNiQVNgSzG6I2NjY2NgX//wVFNjk2PjYlPT09ATY2NgAAAAEANjQ2NjI2NjYfNjZkAAAAAA== 455 \232\000\000\001.\003\008\008.616\000\255\228\192\)\032\251\243\251\000\000\001\001BD6\$\0306646\012\000\001666666\000\016666X\251\032\251\243\251\251\000\000\001BD6\$\015.466666666\000\016666X6\019666666\000\028\001\000\001666E66\0216\000\004966\000\000\001666666.46X\000\03266\2556>6666\232\003\0006\000\000\2516\012\001\000\000\001\244.6.6<\)6\$\0216\004\179\027\16266666\005\255\255\005E696>6%===\001666\000\000\000\001\00064662666\03166d\000\000\000 ++BOgAAAEDAwgINjY2NgAAAMAfNjZkAAAAAAE2vh9GFMAfNi5+7AAAAezs7AAAAezs7BQ2NgEAFAEAJA8yNDY2NjY2NjY2ABA2NjZYNvQBNjY2PDY2JBU2BLM2ojY2NgAAATY2Bf//BUU2OTY+NiU9PT0BNjY2AAAAAQA2NDY2MjY2NjY2ABA2NktLS0AAAAFLATa+H0YUwB82Ln7s7OzsAAAB7OzsFDY2NjYAAAAAATY2NDY2NkE2PjY2NjY2NjZO0DZRABEBAA== 0 120 BOgAAAEDAwgINjY2NgAAAMAfNjZkAAAAAAE2vh9GFMAfNi5+7AAAAezs7AAAAezs7BQ2NgEAFAEAJA8yNDY2NjY2NjY2ABA2NjZYNvQBNjY2PDY2JBU2BLM2ojY2NgAAATY2Bf//BUU2OTY+NiU9PT0BNjY2AAAA 302 \232\000\000\001.\003\008\008.666\000\000\000\192\03166d\000\000\000\000\0016\190\031F\020\192\0316\.~\236\000\000\001\236\236\236\000\000\001\236\236\236\02066\001\000\020\001\000\$\01524666.6666\000\016666X6\244\001666<66\$\0216\004\1796\162666\000\000\00166\005\255\255\005E696>6%===\001666\000\000 ++BOgAAAEDAwgINjY2NgAAAAEfNjZkAAAAAAEAFPY2HjY2NDYMAAEABAEAAAE2NgAAATb7IPvz+/t/AAFCRDYkDzI0NjY2NjY2NjYAEFY2Nlg2NjY2NjY2NgAAAQABWTY2RQAAATYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/zY+NjY2NjYAADYAAPs2DAEAAAH0ATYVNjw2NiQVNgSzNqI2NjY2NgX//wVFNjk2PktLQAAAAUsBNr4fRhTAHzYufuzs7OwAAAHs7OwUNjY2NgAAAAABNjY0NjY2QTY+NjY2NjY2Nk7Q0NCQ0AAUFBQUNjY1NjZDNlg2NjY2TSE2UQARAQA= 0 -1 ++BOgAAAEDAwgINjY2NgAAAMAfNjZkAAAAAAABAAEAFPY2HjY2NDYMAAEABAEAAPM2NgAAIzb7IPvz+/sAAAFCRDYkDzI0NjY2NjY2NjYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTa1FTYABDk2NgAAATY2NjY2Nhw0JlgAIDY2/zY+NjY2NjYAADYAAPs2DAEAAAH0ATY2Njw2NiQVNgSzNqI2NjY2NgX//wVFNjk2PjYlPT09ATY2NgAAAAEANjQ2NjI2NjY2NgAQNjZLS0tAAAABSwE2vh9GFMAeNi5+7Ozs7AAAgADs7BQ2NjY2AAAAAAE2NjQ2NjZBNj42NjY2NjY2TtDQ0JDQABQUFBQ2NjU2NkM2WDY2NjZNNDZRABEBAA== 0 -1 ++BOgAAAEDAwgINjY2NgAA6R8fNjZkAAAAAAEAFPY2HjY2NDYMAAEABAEAAAE2NgAAATb7IPvz+wEBAAFCRDYkDzI0NjY2NjYAATYAEDY2Nlg2NjY2NjY2NgAAAQABNjY2RTYyFTYABDk2NgAAATY2NjY2Nhw0NlgAIDY2/w0NDQ0NDQ0NDQ0NNj42NgAAAQAANgAA+zYMAQAAAfQBNjY2PDY2JBU2BLM2ogX//wVFNjk2MjYlPT09ATY2MgAAAAEANjQ2NjI2NjY2NgAQNjZLS0tAAN8AAAEASwE2vh9GFMAfNi5+7Ozs7AAAAezs7BQ2NjY2AAAAAAE2NjQ2NjJBNj42NjY2NjY2TtDQ0JDQABQUFBTOUTU2NkM2WDY2NjZNNjZRABEBAA== 0 -1 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAjyEgQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACFyICECIGBBAiAhBAAoAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGAEVFhcEGDoaGwQL/x4fDTUpIhljJDoaGwQUIx4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIvIQIgIQQAIQIgAQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgAAAECAv4CAjsA 0 255 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAjyEgQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACFyICECIGBBAiAhBAAoAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGAEVFhcEGDoaGwQL/x4fDTUpIhljJDoaGwQUIx4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIvIQIgIQQAIQIgAQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgAAAECAv4CAjsA 780 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\242\018\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\023\".\016\".\004\016\"\002\016\@.\128\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\004\008\002\002\002\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\001\021\022\023\004\024:\026\027\004\011\255\030\031\0135\)\"\025c\$.\026\027\004\020#\030\031&5\)\"\025\004\$\$\000\000\002\000\@\002\016\"\002\016\@\002\016\"\242\016\"\002\016\@\002\016\"\000\016\031\004\032\)\"#\004\$\$\000\000\002\000\@\002\016\"\002.\@\002\016\"\002\016\"\006\004\008\000\000\001\002\002\254.\002\; ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/GgwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGAEVFhcEGDoaGwQLHR4fDTUpIhkEJDoaGwQUIx4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIgIQIgIQJQIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CAjsA 0 255 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/GgwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgYECAICAgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGAEVFhcEGDoaGwQLHR4fDTUpIhkEJDoaGwQUIx4fJjUpIhkEJCQAAAIAQAIQIgIQQAIQIgIQIgIQJQIQIgIQHwQgKSIjBCQkAAACAEACECICEEACECICECIGBAgCQAICAv4CAjsA 780 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\026.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\004\008\002\002\002\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024\001\021\022\023\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$.\026\027\004\020#\030\031&5\)\"\025\004\$\$\000\000\002\000\@\002\016\"\002\016\@\002\016\"\002\016\"\002\016%\002\016\"\002\016\031\004\032\)\"#\004\$\$\000\000\002\000\@\002\016\"\002.\@\002\016\"\002\016\"\006\004\008\002\@\002\002\002\254.\002\; ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw3oAwAABCQkAAD/AEACECICEEACECICECIGBBAiAkACEAACEEACECICECIGBAgCAgICAhAiAiY1KSIZBCQkBgQICf9/BAwNEg8EEAgSEwQBFRYXBBgBFRYXBBg6GhsECx0eHw01KSIZBCQ6GhsEFCMAAAEMHyY1KSIZBCQkGwACAEACECHtEEACECICECICEEACECICEB8EIBwiIwQkJAAAAgBAAhAiAhBAAhAiAhAiBgQIAkACAgL+AgI7AA== 0 -1 ++DGQAAADKBhgi////fxA33d3d3QECAA0B+/HWEAA43iABAQyAEM/V3d3d8d3d3d3d3d3/AN3d3d3dyADGA+gAIvgP8gbz9A3z9PX2ECIB7SIB7AX43d3d3egD/wDd3d3d3cjd3d3/AAD19hAiAefTAARFAPgB6UD7BCUB/AUjIf8= 16 -1 ++rgGvAbABsQGyAbMBtAG1AbYBtwEBtgG3AbgBuboBuQG6AbsBvAG9Ab4= 0 -1 ++6AU2 3 -1 ++BAABAgMEBAUGBwQICQoLBAwNDg8EEBESEwQUFRYXBBgZGhsEHB0eHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxAwMDAwMDAwMDAwMDAwMCAwMDAwMDAwMDAwMDCAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzYAPRAA+/v7+/v7+wMDAwMDAwMDAwMDAwAAAQMDAwMDAwMDAwMDAwADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAQMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMOAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzYAAAGA 3 -1 ++IBJDAQAQAAAAOj9IWUhISGVIAwMA//8AACBIAwMAAAHsSDD//wAAAwMDAwMAf9z//wAAAQMDAQMDAwMLAwMDAAEDAwMDAwQDAAA= 68 5 AwMEAwA= 13 \003\004\003 ++BOiACwBA/78AABA2NjYyZxVHAOY1NDYfNkg2NP82NgABNjY2NGcVRwDmNTQYHzY2NjT/NjY2NgAA/wADNjY2H8LCwkYUAFA2NgAAgH0AAAfzATY+BFCCwkYUADYAAAGANjYkNv9//wB/NjY2NjYUAAABNjZPNjYYPgQ5NjbQztDQ0NDQ0Mcz0NDi0NDQAAAA+xAN+TY2BwEBAIkAABQUFBQ2NoAHAH8A6AE2WCs2NjYZNnZ2knZ2dnZ2gAsAAAEAGw== 0 -1 ++BOgA8r8fNFI2wsK+wsLCBABSUBYAAQAAFBuQAAAA7DUmNgAEAAA2EAABAAAUG5AAAAA2AAAA3gAAgOXQ0NDQM9DQAAABAAAAAeZ/NjY2NjZ2dn92dgE2dn92dgE2Jgr//QFQNsLCwsLCwh80f////8JQNsLCwsLCwh80Nk3CwsLCwsLCwsLCADY2+gAA+nZ2AAABSwE0vjYAAACA5dDQ0NAy/+EB0NAAAAEAAAAB5n82NjY2NjZ2f3Z2ATZ2CgAQAAE2NgDo/4Dl0NDQ0DPQ0AAAAQAAAABAztDQ0M12dv/2AAC5ubm5ubm5ubm5ubm5ubkBAUZUADY2ADI2JDY2NJAAAQAA 0 38 BOgA8r8fNFI2wsK+wsLCBABSUBYAAQAAFBuQAAAA7DUmNgAEAAA= 118 \232\000\242\191.4R6\194\194\190\194\194\194\004\000RP\022\000\001\000\000\020\027\144\000\000\000\2365&6\000\004\000 ++BOgAAMAfNjY2wsJCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADe4TU2NjY2NjY2NjY2NjYAAAABABtn6gABbEsAAAFLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQAAUAADPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2AHZ2dnZ2dnb/CwAAAQAb 0 93 BOgAAMAfNjY2wsJCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADe4TU2NjY2NjY2NjY2NjYAAAABABtn6gABbEsA 216 \232\000\000\192.666\194\194B\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.66\00966664\128X6\000\016\00166664\2556666\000\000\000\222\2255666666666666\000\000\000\001\000\027g\234\000\001lK ++BOgAAMAfNjY2wvoAAPrCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0NjY2AAAA3gM2NjY2NjY2NjY2NjY2AAAAAQAbZ+oAAWxLS0tLaUtLATa+dnZ2dh9GFAA2NjYAADY2JDY2NP9/NjY2NjY2FTY2TzY2NjY2JDY2//+AAHZ2dnZ2dnb/CwBA/zY2NjY2NgA0NgAAAQABAIAAAAE2NgpQNjbQztDQ0NDQ0NAz0NDi0NDQAABA+xAUFDY2AAHQ0JAAABQUFBQ2NoABAH82WCs2NjY2NnZ2dnZ2dnZ2/wsAAAEAGw== 0 -1 ++Z+oAASAAS0tLaUtLATa+AAAE6AAAwB82NjbCwsLCwsLCwsLCn8LCwsLCwjY2JBU2NDY2NjY2NjYAAAABABtnFTYABDY2NjY2CTY2NjY0gFg2ABABNl82NjT/NjY2NgABAN4DNjY2NjY2NjY2Njb6AAD6AP8AG2fqAAEgAEtLS2lLSwE2vnZ2dnYfRhQANjY2ACA2NiQ2NjT/fzY2NjY2NhU2Nk82NjY2NiQ2Nv//gAB2dnZ2dnb//3//QP+Dg4ODgzY2NjY0NgAAAQABAIAAAAE2NgpQNjYAAAHQNP9/NjY2NjY2FdA2WCs2NjY2NnZ2dnZ2anZ2/wsAAAEAGw== 27 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngn/fzY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NlI2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngn/fzY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NlI2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAA 624 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\009\255\127664\128X6\000\016\00166664\2556666\000\000\000\222\003666666666R.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\1276X+66666vvvvvvvv\255\011\000 ++BOgAAMBgYGBgYGBgYGBgYGBgYGBgYJ/Cs8LCwsLqNh0VNiE2NkI2NkM2AAAAEOkaZxU2AAQ2NlY2Ngk2lpaWlpaWlpaWlpaWlpaWHTY2IIBYNvQAAQAtATYiNn8AAAA2Nh02NjSAWDgALQE2NjZ/AOQANjY1///13gM2NjYFAGQAAwAAATY2NjZnFTYABDY2VjY2ZAD/f+//f4w2NjY2//82NjZQACAAHBwYHBwcHBwcHBwcAQB//xwcHBwcARAbZ+rwAWxLS3Z2djY2NP8QNjY2NjY2FTY2T3Z2dv8LAEAeNhQgf////xtn6vABbEtLdnZ2NjY0/xA2AdDQkAAAARTSFEAAAAABABs= 0 -1 ++AAAAAQH/Hwb/AB7pAAAAAAAAAABAHyUlJSVWVlZfAP9/ADR3NjYjFBg2VTY29xQYNlU2NvdWVlZWVlYAAAFWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVl8A/wAAEiKA//8C////AATnVwAAxxUAAAAB//++hhAEiDsEOD0= 9 1 AA== 2 . ++ATYkNjb/NiQgAF9fgF9XX184X71fX19fAF9fKysrfwBfAAABAHtfAwAAXwADAwMAAgMD/zYkIABfX19fAAABX19fOV+9X182NjYAAAEVaQAABgQ8PQ== 0 44 ATYkNjb/NiQgAF9fgF9XX184X71fX19fAF9fKysrfwBfAAABAHtfAwAAXwA= 86 6.66\2556\$\032\000__\128_W__8_\189____\000__+++\127\000_\000\000\001\000{_.\000\000_ ++AOgAAMAfNjY2wsLCwsLCwuTiwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZwAAARU2AAQ2NjYAAAE2Ngk2NjY2NIBYNgAQAT02NjY0/zY2NjYAAADeAzY2NjY2NjY2NjYTNjbCwsLk4sKfwsLZwsLCNjYkFTY0NjY2NjY2NgAAABcAGwAAAQE2AAABNv+AhocEiDsEPD0= 0 1 AA== 2 . ++8A== 1 -1 ++BCorBCwtLjL79Pv7/BX7+/v7+/v7+/v7+/v7+/v7+wcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcBBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwYHBwcHBwcHBwcHB9EHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBzMzMxo7MzMzMzMzMzMzMzMzBwcHBwcHBwcHBwcHBwcHBwcHDgcHBwcHBwchBwcHBwcHBwcHBwcF//8FBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHAhAiBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHAAEEMDH5fwQMDRIAECICECIGLi8EMDEqMwQ0NTYiBgQICfl/BAwNEgB/KjMEBwcHBwcHB8XFxcXFxcXFx8XFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFAAABxcXFxcXFxcXFxcXFxcXFxQAAAcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFvcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwMHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHDgcHKgcHMzMzGjszMzMzMzMzMzMzMzMHBwcHBwcHBwcHBwcHBwcHAAABBwcOBwcHBwcHxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcUHBwcHBwcHBwcHBwcCECIHBwcHBwcHBwcHBwcHBwcHBwcHBwcHAAABBwcHFwcHBwcHAwcHBwcHBwIQIgIQIgYuLwAAAQQwMfl/BAwNEg8QIgIQIgYuLwQwMSozBDQ1NiIGBAgJ+X8EDA0SDwQqMwQHBwcHBwcHxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFscXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxbfFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxeHFxcXFxcXFxcXFxcXFxcXFxcXFxcXNxcXFxcXFxcXFxcXFxcXFxcXFxcXF28XFxcXFxcXFxcXFxcXFxcXVxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxQHFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxdTFxcXFxQcHBwcHBwcHBxAREhMEFBESQAABFjEzMzMzMzMzMxEzMzMzMzMz/38TBBQRFhcEGCQaGwQUHQIQIgYECAn5fwQMJxIPBBAREhMEQAAWFuiAAAAbBBQdABAzBDQxf/7//wgJBwcHBwcHBwcHBwcHBwcGBwcHBwcHBwcHBwcHBwcOB08HBwcHByEHBwcHBwcHBwcHBwcHBwcHBwcHCQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBwcHBwcHxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxfv7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7xcXFxcXFAMXFxcXFxcXFxQAAAcXFxcXFxcXFxcXFxcUHBwcH 15 -1 ++AAABASIAwA4= 0 1 AA== 2 . ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2NjY2NjY0Ejc2NjYAAADeAzYAAAE2NjY2NjY2NjbeAzYAAAE2NjY2NiQ2NjT/fzY2NjY2NhU2Nk82NjY2NiQ2Nv//gAB2dnZ2dnZ2/wsAQP82NjY2NDYAAAEAAQCAAAABNjYLUDY20M7Q0NDQ0NDQM9DQ4tDQ/38AAAABFBQ2NgAB0NCQAAAUFBQUNjaAAQB/NlgrNjY2NjZ2dnZ2dnZ2dv8LAAABABs= 0 148 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2NjY2NjY0Ejc2NjYAAADeAzYAAAE2NjY2NjY2NjbeAzYAAAE2NjY2NiQ2NjT/fzY2NjY2NhU2Nk82NjY2NiQ2Nv//gAB2dnZ2dnZ2/wsAQP82NjY2NDYAAAEAAQCAAA== 340 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\0046666666664\0187666\000\000\000\222\0036\000\000\001666666666\222\0036\000\000\001666.6\$664\255\127666666\02166O66666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATYmNjY0/zY2NjYAAADeCDY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATYmNjY0/zY2NjYAAADeCDY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAA 618 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\0016&664\2556666\000\000\000\222\0086666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\1276X+66666vvvvvvvv\255\011\000 ++NjYAAAF2ZAAAFwtAAAABgn//AAABA0SAgAABCALLFTZXLNDGAAAU/wABAAIAAAAAgAAAAQkiHBU2V0XQ0JAAABQD6DZPrQAAAQCAAAAAAAEBAAIcFTZXRdDQkAAAFKP/AAAAo5Ojo6O+o56jo6Ojo6Ojo6Ojo6Ojo6MAAAGjdtB/AAAUAAAnNjVA3gABNv8AAzb/AAABdnZ2dnb/CwD8AQAb 54 -1 ++ARERERERES42wsLCwuKfwsLCwsLCNjYkFTYiNjY2NjZ2Ngk2NjY2NIBYNg4QATYF//8F/zYXNjYAAACAAzY2VjY2SjY2NjY2ADYAAAABABsAECcAARw2NjYnpxknJycAAABAAOUBHDY2NgAAAQAAEjY0/382NjZNFzYVNhZPNgABAACA//////8F/zYXNjYRAPLeAzY2NjY2NjY2JCw2//+AAHYAABABNgX//wX/Nhc2NhEA8t4DNjY2NjY2djPQ0OLQ0NAAAAD7EBQUHTblgNDQkAAQKBQUGw== 0 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAqATY2NjY0/zY2NjYAAADeAzZPNjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAqATY2NjY0/zY2NjYAAADeAzZPNjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sBNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAATY2ClA2NtDO0NDQ0NDQ0DPQ0OLQ0NAAAAD7EBQUNjYAAdDQkAAAFBQUFDY2gAEAfzZYKzY2NjY2dnZ2dnZ2dnb/CwAA 615 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000*\00166664\2556666\000\000\000\222\0036O66666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0016\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\00166\010P66\208\206\208\208\208\208\208\208\208.\208\208\226\208\208\208\000\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\02066\128\001\000\1276X+66666vvvvvvvv\255\011\000 ++BOhtAG0AAAA= 0 6 BOhtAG0A 11 \232m\000m ++MzY238LYnwCAf8LCbzY2th82bzY2thU2NDYANiQlJicEKAAAAAHpARA2NwQ4OAE7BD49Pj8A 4 -1 ++BOgAAMAfNjY2wsJAwsLCwsLCwp/CNjY2NjYAAIABABtnFTYABDY2NjY2CTY2NjY0gGA2ABABNjY2NmcxNgAENjYjNjYnBCgpNjcEODg6OwQ8PT4/AA== 0 -1 ++BOgAEACf1MLCwsLCNgABABtnFTYABjY2NjY2CTY2NjY0gFhZADg4OTsEPD0+PwA= 0 -1 ++ZAGU0g== 0 -1 ++AAEp 1 -1 ++//9/A4o= 5 -1 ++//8FDgMEBwQsLS4nBC0AEwIQAAcAAH/fMjMEAAABCAkKTy4gAB8ANgQsLS4vBAcAAH/fMjMENDU2CCAAHwA2BCwtLi8eBC4gAB8ANgQsIAAfAC4vBH8QHgQ/OTpPLiCVlZWVlZWVlZWVlZWVBwcHBwcHBwcHBwYHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBzMzMxo7MzMzMzMzMzMzMzMzBwcHBwcHBwcHBwcHBxgHBwcHDgcHBwcHBwchBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHAhAiBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBxcHBwcHBw0HBwcHBwcCECICECIGLi8AAAEEMDH5fwQMDRIPECICECIGLi8EMDEqMwQ0NTYiBgQICfl/BAz/EQ8EKjMEBwcHBwcHBwcHBwcHBwcHBxAREhMEFBESQAABFhczMzMzMzMzMxEzMzMzMzMz/38TBBQRFhcEGCQaGwQUHQIQIgYECAn5fwQMJxIPBBAREhMEQAAWFuiAAAAbBBQdABAzBDQxf/7/FAgJBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcOBzMzMwcHBwcHBwcHBwcHBwcHBwcHBw4HBwcHBwcHIQcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHFwcHBwcHBwcHBwcHBwIQIgcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcNBwcHBwcHAhAiAhAiBi4vAAABBDAx+X8EDA0SDxAiAhAiBi4vBDAxKjMENDU2IgYECAn5hgQMDRIPBCozBAcHBwcHBwcHBwcHBwcHBwcQERITBBQREkAAARYXMzMzMzMzMzMRMzMzMzMzM/9/EwQUERYXBBgkGhsEFB0CECIGBAgJ+X8EDCcSBwcHBwcHBwcHBwcHBwcHBwcHBwcXBwcHBwcHBwcHBwcHBwcHfwAEJDQdAhAiAhBAAhAiAhAiEkAAARYXBBgZGhsEFB0gHwAzMzM= 5 -1 ++BA8ICAgEBAUG6wQICQoLBAxuJSY2BBAAAAAEFC0uIFAzBDM1NjkEOB45OwQAAAE0NSk3BDgAOQQrNjkEOH////9QUQQ0KQIQIgYEECICEEACAhAiBgQIAgICAgIQIgIQQAIQIgIQIgYECAkiAgICkCICEEACECICECIGBAgJ/37hDA0gDwQQDRITBAEVFhcEGAEVFhcEGDoaGwQLHR4Q8TQpIhkEJDo1KSIZBCQkAAACAEAQQAIQIgIEECICEEACAhAiBgQIAgICAgIQIgIQQAIQIgIQIgYECAkiAgICECICBBAiAhBAAgIQIgYECAICAgICECICEEACECICECIGBAgJIgICApAiAhBAAhAiAhAiBgQICf9+4QwNIA8EEA0SEwQBFRYXBBgBFRYXBBg6GhsECx0eApAiAhBAAhAiAhAiBgQICf9+4QwNIA8EEA0SEwQBFRYXBBgBFRYXBBg6GhsECx0d/PEkJAAAAgBAEEACECICECIGBAgCHQICAv4QIgYECAJAAgIC/gICOwIQIgIQQAIQIgIQIgIQQAIQIgIQBAQgKSIjBCQkDgACAEACECICEEACECICEAAAASIGBAgCQAICAv4CAjsA 0 -1 ++BAABAgMEERITBBQVFhceHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXV5fBGBhYmMEZGVmZwRoaWprBGxtbm8EcHFycwR0dXZ3BHh5ensEfH1+fwSAgYKDBISFhocEiImKiwSMjY6PBJCRkpMElJWWlwSYmZqbBJydnp8EoKGiowSkpaanBKipqqsErK2urwSwsbKzBA== 0 -1 ++BAABAgMEBAUGBwQAAAEABAwNDhQEEBESEwQUNBYXBAcH5wYHogcHByoHBwcHBwcHDQcHBwcHBwAQBwcHByKANTM2NwQ4OTo7BDxRPj8A 0 78 BAABAgMEBAUGBwQAAAEABAwNDhQEEBESEwQUNBYXBAcH5wYHogcHByoHBwcHBwcHDQcHBwcHBwAQBwcHByKANTM2NwQ4OTo7BDxRPj8A 226 \000\001\002\003.\004\005\006\007.\000\000\001\000.\012\013\014\020.\016\017\018\019.\0204\022\023.\007\007\231\006.\162\007\007\007*\007\007.\007\007\007\007\013\007\007.\007\007\007\000\016\007\007.\007\"\1285367.89:\;.? ++BAAJCgsEGA0ODwQQERIEBAUGDQ4PBBAREhMEFBUWEwQUFRYXBBgZGhsEkx0eHxobBJMdDB8EICEiIwQ2NDUEkx0eDg8EEBESEwQEGBkaGwSTHQ== 0 -1 ++BAAEBQYHBAgJCgsEDA0kJSYnBCgpKisELC0uLwQwMTIzBDQ1NjcEgAA6OwQ8PT4/BEBBQkMEREVGRwRISUpLBExNTk8EUFFSUwRUVVZXBFhZWlsEXF1eXwRgNTY3BDg5OjsEPD0+PwRAQUJDBERFRkcEdHV2dwR4eXp7BHx9fn8EgIGCgwSEhYaHBIiJiosEjI2OjwSQkZKTBJSVlpcEmJmamwScnZ6fBKChoqMEpKWmpwSoqaqrBKytrq8EsLGyswQ= 8 -1 ++BAAEBQYHBAgJCgsEDA0ODwQQBBgZGhsEHB0hIiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NTY3BDg5OjsEPD0+XwRgYWBjBGRlZmcEaGlqawRsbW5vBHBxcnMEdHVWVwRYWVpbBFxdXl8EYGFiYwRkZWZnBGhpamsEbG1ubwRwcXJzBHR1dncEeHl6ewR8fX5/BICBgoMEhIWGhwSIiYqLBIyRjo8EkJGSkwSUlZaXBJiZmpsEnJ2enwSgoaKjBKSlpqcEqKmqqwSsra6vBLCxsrME 8 -1 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYOhobBCY1KSIZBCQkAAACDkACECICEEACECICECICEEACECICEB8EICkiIwQkJAAAAgBAAhAiAhBAAhAiAhAAAA== 0 202 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYOhobBCY1KSIZBCQkAAACDkACECICEEACECICECICEEACECICEB8EICkiIwQkJAAAAgBAAhAiAhBAAhAiAhAAAA== 590 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004&5\)\"\025\004\$\$\000\000\002\014\@\002\016\"\002.\@\002\016\"\002\016\"\002\016\@\002\016\"\002\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\".\016\@.\016\".\016\000 ++5h3eAgMEBAUGByQrCS0QAADy/38AzSoAAAFkLi8BLC0uL4AAAAEwMf///4ABQH8AQAAAAQAAY2QAZS8BLC1AZQAAAWVmZwQAAAFwZQBleARkZWZn6AP0//xwAAABYGRlAAAA5RAQAAABAQAAAAHw7uzs/+x/AEBlAPABgoMWEAD//w== 8 8 BgckKwktEAA= 17 \007\$+\009-\016 ++BB8BAAAAAAEEBCEGBwAAAQQICQQhBgQICQoT2xMVAAABFhAoKRsuLwQwE9sTFQAAARYXBBgZMCsCAwQhPw== 8 6 BAQhBgcA 14 \004!\006\007 ++BB8BAgMEBAUGCwQMDQ4PBAgIAQgICAgICAgICAcECAkKCwQMDQ4PBAgIAQgICAgICAgICAgICAgJCAgICAgICAgICAgICAgICAh0B/AICAgBCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAj/fwAACAgAAAAACHQAAAH/AAgICAg= 8 122 BgsEDA0ODwQICAEICAgICAgICAgHBAgJCgsEDA0ODwQICAEICAgICAgICAgICAgICQgICAgICAgICAgICAgICAgIdAfwCAgIAQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI/38AAAgIAAAAAAh0AAAB/wA= 427 \011\004\012\013\014\015.\008\008\001\008.\008\008\008\008\008\008\008\007.\008\009\010\011.\012\013\014\015.\008\008\001\008.\008\008\008\008\008\008\008\008.\008\008\009\008\008\008\008\008.\008\008\008\008\008\008\008\008.\008\008t\007\240\008\008\008.\008.\008\008\008\008\008\008\008\008.\008\008\008\008\008\008\008\008.\008\008\008\008\008\008\008\008.\008\008\008\255\127\000\000\008.\000\000\000\000\008t\000\000.\255 ++AgAAAgBAAhAiAhBAAhAiAhAiBgQIDf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaIiMEBCQAAAIAQAIQAAIfQAIQIgIQIgYECAIChgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEAIECIiAEACECICECIGBAgCQAICAv4CADsA 0 250 AgAAAgBAAhAiAhBAAhAiAhAiBgQIDf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsEC4AAAAA1KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaIiMEBCQAAAIAQAIQAAIfQAIQIgIQIgYECAIChgICECICEEACECICECIGBAgJ/38EDA0SDwQQCBITBAEVFhcEGDoaGwQUHR4fJjUpIhkEJCQQIgIQIgIQQAIQIgIQHwQgKSIjBCQkAAACAEAIECIiAEACECICECIGBAgCQAICAv4CAA== 754 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\013\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\128\000\000\0005\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\"#\004\004\$\000\000\002\000\@\002\016\000\002\031\@\002\016\".\016\".\004\008\002\002\134\002.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\020\029\030\031&5\)\"\025\004\$\$\016\"\002\016\".\016\@.\016\".\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\"\"\000\@\002\016\".\016\".\004\008\002\@\002\002.\254\002 ++ISEhISEhISEhISEhISEhISEhISEAA+gAISEhISEhISEhISEhISEhGiEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhISEhIYAhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhIRAhISEhISEhISEhISEhISEhISEhISEhISEhIYAhISEhISEpcnN0dXZAAAAAew== 33 205 ISEhISEhGiEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhISEhIYAhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhQyEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF+ISEhISEhISEhIRAhISEhISEhISEhISEhISEhISEhISEhISEhIYAhISEhISEpcnN0dXZAAA== 218 !!!!!\026!!!!!!!!!!!C!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!!!!!!!~!!!!!!!!!!!.!\128!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!C!!!!!!!!!!!!!!!!!!!!!.!!!!!!!!!!!!!!!~!!!!!!!!!!\016!!!!!!.!!!!!!!!!!!!!!!!!!!\128!!!!!!\)rstuv\@ ++AUABQwFEAUUBRgFPAVABUQFSAVMBVAFVAVYBVwFYAVkPWgFbAVwBXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+NjY2NjYAAAABBB82NgAAATY2NiQVNjQ2NjY2NjY2NjY2NjY2NgAAAAEENgAAATY2NjY2NgAAATY2NjY2NjY2AAAAAQQ2NjY2NjY2NjY2NjY2AAAANjY2NjY2NjYAAAABBDY2NjY2NjY2NjY2NiQgNjQ2NjY2NlE2NjY2NjY2NjY2Nho2Nn92dnZ2dpZ2dnb//0E2AQAAAQAAARY2 0 -1 ++BwEBQwBkAQABRgFPAVABUQFSAesBVAFVAVYBbAFYAVkBWgFbF1wBAAABXwFgAVQBYgFrAWQBZQFmAWcBaAFpAWoBawdsAV0BbfxvAVs2NgBQNjYkZDY0NiQAZjZRNjY2Nv9aAVsBWwFfAQBQtDY2NjY2/1o2ZjZRNrdENjYAAAQ2NjY2MP9aAAEENgAAATY22jY2PwAABDY2AAAAAQQ2Gf4BNkc2Nr5LS0tLAAABSwE2vh0AATY2NuxQNjYkZDY0JCQ2ZjZRNks2AAABNmRaAVsbXAFfAWAAYQFiAWP/////AAABAWYBNgEAAAEAAAEWNg== 0 -1 ++AUABQvZEAUUBRgFPAVABUQFSAVMBVAFVAVYBVwFLS0tLS0tLATa+HQDxNRc2AFgBWWH/AXMXdAF1AZEBdwF4AXkBegF7AXwBZwFo7GkBagFrAWwAAAFuAW8BcAF/AXIBcwEAAAH1kAF3AXgBeQF6AXsBfAAAAQF9AX42NjY2AAABAAEEHzY2AAABNjY2JBVdXV1dXV1dXV02NDY2NjY2NjY2NjY2NjY2AAAAAAABAQQ2AAABNjY2NjY2AAABAAABNjY2NjY2NjYAAAABGjY2NjY2NjY2NjY2NjYAAAEPHh4eHh4eHh4eHh4eHh4A5B4eAAAAAQAbS2xLS0tLS0tLATa+HQDxNRc2AFA2NiQsNjQ2GzY2NlE2NjY2NjY2NjY2Af/pAAABFjY= 0 -1 ++AAAAAQIAAAGgACABgAGDDKABJQ== 0 1 AA== 2 . ++AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYOhobBBQdHh8mNSkiGQQkJAAAAg5AAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQAAAIAQAIQIgIQQAIQIgIQAAA= 0 206 AgAAAgBAAhAiAhBAAhAiAhAiBgQICf9/BAwNEg8EEAgSEwQBFRYXBBg6GhsECx0eHw01KSIZBCQkAAD/AEACECICEEACECICECIGBBAiAhBAAhAiAhAfBCApIiMEBCQAAAIAQAIQAAIQQAIQIgIQIgIQIgYECAn/fwQMDRIPBBAIEhMEARUWFwQYOhobBBQdHh8mNSkiGQQkJAAAAg5AAhAiAhBAAhAiAhAiAhBAAhAiAhAfBCApIiMEJCQAAAIAQAIQIgIQQAIQIgIQAAA= 588 \000\000.\000\@.\016\".\016\@.\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\011\029\030\031\0135\)\"\025\004\$\$\000\000\255\000\@.\016\".\016\@.\016\".\016\".\004\016\"\002\016\@.\016\".\016\031.\032\)\"#.\004\$\000\000.\000\@.\016\000.\016\@.\016\".\016\".\016\".\004\008\009\255\127\004.\013\018\015\004\016\008\018\019\004\001\021\022.\004\024:\026\027\004\020\029\030\031&5\)\"\025\004\$\$\000\000\002\014\@.\016\".\016\@.\016\".\016\".\016\@.\016\".\016\031.\032\)\"#.\$\$\000\000.\000\@.\016\".\016\@.\016\".\016\000 ++AgAABgYGBgYcBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgQGBgYGBgYGBgYGBgYEBgYGBgYGBgYGBgYGBAYGBgYGBgYGBgYGBgYGBgYGQAYG/xAGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgZkBgYGBgYGBgayBgYGBgYGBgYGBgYGBgUGBgYGBgYGBgYGBgYaBgYGBgYGBgYGBgYGEwYGBgYGACAGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBughHh8EICkiIwQvJOsnBAgpKisALA== 0 255 AgAABgYGBgYcBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgQGBgYGBgYGBgYGBgYEBgYGBgYGBgYGBgYGBAYGBgYGBgYGBgYGBgYGBgYGQAYG/xAGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgZkBgYGBgYGBgayBgYGBgYGBgYGBgYGBgUGBgYGBgYGBgYGBgYaBgYGBgYGBgYGBgYGEwYGBgYGACAGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBughHh8EICkiIwQvJOsnBAgpKisA 871 \000\000.\006\006\006\006\028\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\004\006\006\006\006.\006\006\006\006\006\006.\004\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\@.\006\255\016\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006d\006\006\006.\006\006\006\006\178\006.\006\006\006\006\006\006.\006\006\006\006\005\006.\006\006\006\006\006\006.\006\006\006\026\006\006.\006\006\006\006\006\006.\006\006\019\006\006\006.\006\000\032\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\006\006\006\006.\006\006\232!\030\031.\032\)\"#./\$\235'.\008\)*+ ++BAABAgMEERITBBQVFtckHwQgISMjBCQlJicEKCkqKwQsLS4vBIAAMjMENDU2NwQ4/4A7BDw9Pj8EQEFCJwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXV5fBDcEMzk6OwQ6WgQ8PT4/AA== 0 -1 ++BAAB7gMEERITBBQVFhceHwQgIQgjBCQlJgQUFRYXBBgZGhsPHB0eHwQgIQAAAQ== 0 -1 ++AABAAP//ERPyvwJEGB4bBBETNgQUFRPyvwJEGB4fGwQdEzYEKBUWFx4eHwQvHxgekwABDBsAASIjXl5eXl5eXl5eXl5eXl5eXiQ= 0 1 AA== 2 . ++LS4vBDAxMjMENDUAAAE2NwAEAAECAwTyERMEFBUWFx4fBCAhMiMEJCUmJwQoKSorBCwtLi8EMDEyMwQ0NQAAATY3BDg5OjsEPD0+PwRAQUJDBDlFRkcESEn//4AATU5PBFBRUlAEVFVWVwRYWVpbBFxdXl8EYGFiYwRkRmZnamsEbG1ubwRwcXJzBHR1dndpeHl6ewR8fX5/BICBgoMEhIWGEBAQEBAQEBAQEP///38QEBAQEBAQEBCA/xAQEBAQEBAQEBAQEAAAARAQEBAQAAToBAMDgAAAAfoD6AI= 44 -1 ++BAABAgMEERITBBQVFhceHwQgISIjBCQlJicEKCkqKwQsLS4vBDAxMjMENDU2NwQ4OTo7BDw9Pj8EQEFCQwRERUZHBEhJSksETE1OTwRQUVJTBFRVVlcEWFlaWwRcXWRfBGBhYmMEZGVmZwRoaWprfwSAgYKDBISFhhAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAE6AQDAwP6A+gC 0 -1 ++FA== 0 -1 ++AQABAwEiAQcBCAEJAQoBCwEMAZ/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQATZxU2AAQ2Ni42Ngk2NjY2NIBYNgAQATY2NhM0/yI2NjYAAADeAzY2NjY2AAAAAQAbZ+oAAYNLS0tLaUtLATa+kHZ2dh9GFAA2NjYAADYDNjY2NjY2NjY2NjY2NgAAAAEAG2fqAAFsS0tLS2lLSwE2vnZ2dnYfRhQANjY2AAA2NiQ2NjT/fzbsNjY2NhU2NgAAATY2NiQ2Nv//gAB2dnZ2dnZ2/wsANiQ2NjT/fzbCwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NhM0/zY2NjYAAADeAzY2NjYwNjY2NjY2NjYAAAABABtnNjY2Ngk2NjY2NIBYNgAQATZANhM0/zY2NjYAAADeAzY2Njb/NjY2NjYAAAE2NjYAAAABABtn6gABbEtLS0tpS0sBNr6QdnZ2H0YUADY2NgAANgM2NoD///82NjY2NjY2AAAAAQAbZ+oAAWxLS0tLaUtLATkAAAG+dnZ2dh9GFAA2NjYAADY2JDY2NP9/NjY2NjY2FTY2AAABNjY2JDY2//+AAHZ2dnZ2dnb/NjY2AAQ2AAAAAQAbZxU2AAQAAAE2NjY2Ngk2NjY2NIBYNgAQATY2NhM0/zY2NjYAAADeAzY2NjYwNjY2NjY2NjYAAAABABtnNjYhNjYVNjZPNjY2NjYkNjb/34AAbXZ2dnZ2dv8L0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0bnR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0QJA6DY2NjY0NgAAAQABAIAAAAE2NgpQNjbQsSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKQEAGw== 0 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sNNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAARU2ClA2NtDO09DQ0NDQ0DPQ0OLQ0AAgAAD7EBQUNjYAAdDQkAAAFBQUFMLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NgAAAQAb 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjY2NIBYNgAQATY2NjY0/zY2NjYAAADeAzY2NjY2NjY2NjY2NjYAAAABABtn6gABbEtLS0tpS0sNNr52dnZ2H0YUADY2NgAANjYkNjY0/382NjY2NjYVNjZPNjY2NjYkNjb//4AAdnZ2dnZ2dv8LAED/NjY2NjQ2AAABAAEAgAAAARU2ClA2NtDO09DQ0NDQ0DPQ0OLQ0AAgAAD7EBQUNjYAAdDQkAAAFBQUFMLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NgAA 655 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\00966664\128X6\000\016\00166664\2556666\000\000\000\222\0036666666666.66\000\000\000\001\000\027g\234\000\001lKKKKiKK\0136\190vvvv\031F\020\000666\000\00066\$664\255\127666666\02166O.6666\$66\255\255\128\000vvvvvvv\255\011\000\@\255666646\000\000\001\000\001\000\128\000\000\001\0216\010P66\208\206\211\208\208\208\208\208\208.\208\208\226\208\208\000\032\000\000\251\016\020\02066\000\001\208\208\144\000\000\020\020\020\020\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466\000 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxfr6+vr6xcUAAAEAG2cVNgAENjY2NjYJNjY2NjSAWDYAEAE2NjY2NP82NjY2AAAA3gM2Nrw2NjY2NjY2NjY2AAD8AAAbZ+oAAWxLS0tLaUtLDTa+dnZ2dh9GFAA2NjYAADY2JFE2NP9/NjY2NjY2FTY2TzY2NjY2JDY2//+AAHZ2dnZ2dnb/CwBA/zY2NjY0NgAAAQABAIAAAAEVNgpQNjbQztPQ3NDQ0NAz0NDi0NDQAAAA+xAUFDYAAAPo0JAAABQUFBQ2Ns0BAH82WCs2NjY2NnYAAP//dnZ2/wsAAAEAGw== 0 -1 ++BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjYdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugHWEbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHUAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AQEA/wA= 0 255 BOgAAMAfNjY2wsLCwsLCwsLCwp/CwsLCwsI2NiQVNjQ2NjY2NjY2AAAAAQAbZxU2AAQ2NjY2Ngk2NjYdAR4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugHWEbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHUAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9AQEA 717 \232\000\000\192.666\194\194\194\194\194\194\194\194\194\194\159\194\194\194\194\194\19466\$\0216466666.6\000\000\000\001\000\027g\0216\000\00466666\009666\029\001\030\001\159\001\160\001\161\001\162\001\163\001\164\001\165\001\166\001\167\001\168\001\169\001\170\001\171\001\172\001\173.\174.\175.\176.\177.\178.\179.\180.\181.\182.\183.\184.\185.\186.\214.\188\001\189\001\190\001\191\001\192\001\193\001\194\001\195\001\196.\197.\198.\199.\200.\201.\202.\203.\204.\205.\206.\207.\208.\209.\210.\211.\212.\213.\214.\215.\216.\217.\218.\219.\212.\221.\222.\223.\224.\225.\226.\227.\228.\229.\230.\231.\232.\233.\234.\235.\236.\237.\238.\239.\240.\241.\242.\243.\244.\245.\246.\247.\248.\249.\250.\251.\252.\253.\001 ++BOgAAMAfNjY2wsLCwsLCwsLCwp8EMDEFGAEfASABIQEiASMBJAEnASgBKQEqASsBLAEtAS4BNwE4ATkBOiA7ATwBPQE+AT8NAQ4A/gEQAREAAH//ARQBFwUYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASvALMLCwsLCwsLCwp8EMDEFGAEfASABIQEiASMBJAEnASgBKQEqASsBLAEtAS4BNwE4ATkBOiA7ATwBPQE+AT8NAQ4A/gEQAREAAH//ARQBFwUYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASvALAEtAS4BJwEoAUgBKgErASwBLQEuATsBLQEuAScBKAFIASoBKwEsAS0BLgE7ATwBPQE+AT8A 0 -1 ++BAABAgMEAAABBwQICQoLBBINDg8EEBESEwQUFRYXBBgZGhsEHB0eNjY2AAA2NjY2Njw2ATYYNkUAAAIQ//9/TExMTExMTExMTExMTExMTExMTExMTENMbxMTExNqEykTlhMTEyYLAAEUFAAABjY2NjYAUwE2NhwAAAABAAABBDb/fwAAAzY2NgX//wU2NgD7SDYkNjk5OTk5OTk5OTk5OTk5OTk5OTk5PTY0pDY2NjY2NiQAAAE2Nn82cXZ2dnZ2dnZ20Coq0DPQ0P/gM9DQ//9//9AAAAHSu9DRkNAABgAA/xQUAAAGfzYkNjY0Nks2AAQeVTb/AAABNn////8= 0 -1 ++BAABAgMEBAgJCgsEDA0ODwQQERITBAQ0NTY3BDg5OjsEPD0iIwQkJSYnBD8pKisELC0uLwQwMTIzBDQ1NjcEODk6OwQ8PT4/BEBFRkcESElKSwRMTUNPBFBRUlsEVFVWVwRYWVpbBFxNXl8EYGFiYwRkZWZnBGhpamsEbG0eHwQgISIjBCQlJicEKCkqKwQsLScvBICBgoME+oWGhwSIiYqLBDQ1NjcEODk9Pj8EQEFCQw== 0 -1 ++AgAAAhBiAgAAAhAiAQEBAgFXAhBiAgAAAhABAgFXAQECEGICAAACECIBVwEBAgFXAQEBAQIBVwAAAQ== 0 56 AgAAAhBiAgAAAhAiAQEBAgFXAhBiAgAAAhABAgFXAQECEGICAAACECIBVwEBAgFXAQEBAQIBVwA= 129 \000\000.\016b.\000\000.\016\".\001.\002.W.\016b.\000\000.\016\001.\001W.\001.\016b.\000\000.\016\".W.\001.\001W.\001.\001.\001W ++wMAAAcDAwMDANgMDAwMDAwMDA/oAAA== 16 5 AwMD+gA= 13 \003\003\250 +diff --git a/resolv/tst-ns_name_compress.c b/resolv/tst-ns_name_compress.c +new file mode 100644 +index 0000000000000000..0c01b753e7764763 +--- /dev/null ++++ b/resolv/tst-ns_name_compress.c +@@ -0,0 +1,76 @@ ++/* Test ns_name_compress corner cases. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Check that we can process names which fit into the destination ++ buffer exactly. See bug 21359. */ ++static void ++test_exact_fit (const char *name, size_t length) ++{ ++ unsigned char *buf = xmalloc (length + 1); ++ memset (buf, '$', length + 1); ++ enum { ptr_count = 5 }; ++ const unsigned char *dnptrs[ptr_count] = { buf, }; ++ int ret = ns_name_compress (name, buf, length, ++ dnptrs, dnptrs + ptr_count); ++ if (ret < 0) ++ { ++ support_record_failure (); ++ printf ("error: ns_name_compress for %s/%zu failed\n", name, length); ++ return; ++ } ++ if ((size_t) ret != length) ++ { ++ support_record_failure (); ++ printf ("error: ns_name_compress for %s/%zu result mismatch: %d\n", ++ name, length, ret); ++ } ++ if (buf[length] != '$') ++ { ++ support_record_failure (); ++ printf ("error: ns_name_compress for %s/%zu padding write\n", ++ name, length); ++ } ++ free (buf); ++} ++ ++static int ++do_test (void) ++{ ++ test_exact_fit ("abc", 5); ++ test_exact_fit ("abc.", 5); ++ { ++ char long_name[] ++ = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."; ++ TEST_VERIFY (strlen (long_name) == NS_MAXCDNAME - 1); ++ test_exact_fit (long_name, NS_MAXCDNAME); ++ long_name[sizeof (long_name) - 1] = '\0'; ++ test_exact_fit (long_name, NS_MAXCDNAME); ++ } ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-res_hconf_reorder.c b/resolv/tst-res_hconf_reorder.c +index 1e7e0e2fa5aa8735..20e5a5a448437840 100644 +--- a/resolv/tst-res_hconf_reorder.c ++++ b/resolv/tst-res_hconf_reorder.c +@@ -1,6 +1,6 @@ + /* BZ #17977 _res_hconf_reorder_addrs test. + +- Copyright (C) 2015 Free Software Foundation, Inc. ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -19,6 +19,7 @@ + + #include + #include ++#include + #include + #include + #include +diff --git a/resolv/tst-res_use_inet6.c b/resolv/tst-res_use_inet6.c +new file mode 100644 +index 0000000000000000..d819f921d6e6746d +--- /dev/null ++++ b/resolv/tst-res_use_inet6.c +@@ -0,0 +1,509 @@ ++/* Basic functionality tests for inet6 option processing. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Handle IPv4 reverse lookup responses. Product a PTR record ++ A-B-C-D.v4.example. */ ++static void ++response_ptr_v4 (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ int bytes[4]; ++ int offset = -1; ++ TEST_VERIFY (sscanf (qname, "%d.%d.%d.%d.in-addr.arpa%n", ++ bytes + 0, bytes + 1, bytes + 2, bytes + 3, ++ &offset) == 4); ++ TEST_VERIFY (offset == strlen (qname)); ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ char *name = xasprintf ("%d-%d-%d-%d.v4.example", ++ bytes[3], bytes[2], bytes[1], bytes[0]); ++ resolv_response_add_name (b, name); ++ free (name); ++ resolv_response_close_record (b); ++} ++ ++/* Handle IPv6 reverse lookup responses. Produce a PTR record ++ <32 hex digits>.v6.example. */ ++static void ++response_ptr_v6 (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ ++ TEST_VERIFY_EXIT (strlen (qname) > 64); ++ ++ char bytes[33]; ++ for (int i = 0; i < 64; ++i) ++ if ((i % 2) == 0) ++ { ++ TEST_VERIFY (isxdigit ((unsigned char) qname[i])); ++ bytes[31 - i / 2] = qname[i]; ++ } ++ else ++ TEST_VERIFY_EXIT (qname[i] == '.'); ++ bytes[32] = '\0'; ++ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ char *name = xasprintf ("%s.v6.example", bytes); ++ resolv_response_add_name (b, name); ++ free (name); ++ resolv_response_close_record (b); ++} ++ ++/* Produce a response based on QNAME: Certain characters in the first ++ label of QNAME trigger the inclusion of resource records: ++ ++ 'a' A record (IPv4 address) ++ 'q' AAAA record (quad A record, IPv6 address) ++ 'p' PTR record ++ 'm' record type must match QTYPE (no additional records) ++ '6' stop flag processing if QTYPE == AAAA ++ ++ For 'a' and 'q', QTYPE is ignored for record type selection if 'm' ++ is not specified. ++ ++ in-addr.arpa and ip6.arpa queries are handled separately in ++ response_ptr_v4 and response_ptr_v6. */ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ if (strstr (qname, ".in-addr.arpa") != NULL) ++ return response_ptr_v4 (ctx, b, qname, qclass, qtype); ++ else if (strstr (qname, ".ip6.arpa") != NULL) ++ return response_ptr_v6 (ctx, b, qname, qclass, qtype); ++ ++ bool include_a = false; ++ bool include_aaaa = false; ++ bool include_match = false; ++ bool include_ptr = false; ++ for (const char *p = qname; *p != '.' && *p != '\0'; ++p) ++ { ++ if (*p == 'a') ++ include_a = true; ++ else if (*p == 'q') ++ include_aaaa = true; ++ else if (*p == 'm') ++ include_match = true; ++ else if (*p == 'p') ++ include_ptr = true; ++ else if (*p == '6' && qtype == T_AAAA) ++ break; ++ } ++ if (include_match) ++ { ++ if (qtype == T_A) ++ include_aaaa = false; ++ else if (qtype == T_AAAA) ++ include_a = false; ++ } ++ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ if (include_a) ++ { ++ char ipv4[4] = {192, 0, 2, 17}; ++ resolv_response_open_record (b, qname, qclass, T_A, 0); ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ resolv_response_close_record (b); ++ } ++ if (include_aaaa) ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ resolv_response_open_record (b, qname, qclass, T_AAAA, 0); ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ resolv_response_close_record (b); ++ } ++ if (include_ptr) ++ { ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "ptr-target.example"); ++ resolv_response_close_record (b); ++ } ++} ++ ++/* Test that getaddrinfo is not influenced by RES_USE_INET6. */ ++static void ++test_gai (void) ++{ ++ { ++ struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("qam.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_UNSPEC qam.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ret = getaddrinfo ("am.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_UNSPEC am.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ret = getaddrinfo ("qa.example", "80", &hints, &ai); ++ /* Combined A/AAAA responses currently result in address ++ duplication. */ ++ check_addrinfo ("getaddrinfo AF_UNSPEC qa.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++ { ++ struct addrinfo hints = ++ { ++ .ai_family = AF_INET, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("qam.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_INET qam.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ret = getaddrinfo ("am.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_INET am.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ret = getaddrinfo ("qa.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_INET qa.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++ { ++ struct addrinfo hints = ++ { ++ .ai_family = AF_INET6, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("qa.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo (AF_INET6)", ai, ret, ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ret = getaddrinfo ("am.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_INET6 am.example", ai, ret, ++ "error: No address associated with hostname\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ ret = getaddrinfo ("qam.example", "80", &hints, &ai); ++ check_addrinfo ("getaddrinfo AF_INET6 qam.example", ai, ret, ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++} ++ ++/* Test gethostbyaddr and getnameinfo. The results are independent of ++ RES_USE_INET6. */ ++static void ++test_reverse (void) ++{ ++ { ++ char ipv4[4] = { 192, 0, 2, 17 }; ++ check_hostent ("gethostbyaddr AF_INET", ++ gethostbyaddr (ipv4, sizeof (ipv4), AF_INET), ++ "name: 192-0-2-17.v4.example\n" ++ "address: 192.0.2.17\n"); ++ } ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ check_hostent ("gethostbyaddr AF_INET", ++ gethostbyaddr (ipv6, sizeof (ipv6), AF_INET6), ++ "name: 20010db8000000000000000000000001.v6.example\n" ++ "address: 2001:db8::1\n"); ++ } ++ ++ { ++ struct sockaddr_in addr = ++ { ++ .sin_family = AF_INET, ++ .sin_addr = { .s_addr = htonl (0xc0000211) }, ++ .sin_port = htons (80) ++ }; ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ int ret = getnameinfo ((struct sockaddr *) &addr, sizeof (addr), ++ host, sizeof (host), service, sizeof (service), ++ NI_NUMERICSERV); ++ TEST_VERIFY (ret == 0); ++ TEST_VERIFY (strcmp (host, "192-0-2-17.v4.example") == 0); ++ TEST_VERIFY (strcmp (service, "80") == 0); ++ } ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ struct sockaddr_in6 addr = ++ { ++ .sin6_family = AF_INET6, ++ .sin6_port = htons (80), ++ }; ++ TEST_VERIFY (sizeof (ipv6) == sizeof (addr.sin6_addr)); ++ memcpy (&addr.sin6_addr, ipv6, sizeof (addr.sin6_addr)); ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ int ret = getnameinfo ((struct sockaddr *) &addr, sizeof (addr), ++ host, sizeof (host), service, sizeof (service), ++ NI_NUMERICSERV); ++ TEST_VERIFY (ret == 0); ++ TEST_VERIFY ++ (strcmp (host, "20010db8000000000000000000000001.v6.example") == 0); ++ TEST_VERIFY (strcmp (service, "80") == 0); ++ } ++} ++ ++/* Test that gethostbyname2 is mostly not influenced by ++ RES_USE_INET6. */ ++static void ++test_get2_any (void) ++{ ++ check_hostent ("gethostbyname2 AF_INET am.example", ++ gethostbyname2 ("am.example", AF_INET), ++ "name: am.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname2 AF_INET a.example", ++ gethostbyname2 ("a.example", AF_INET), ++ "name: a.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname2 AF_INET qm.example", ++ gethostbyname2 ("qm.example", AF_INET), ++ "error: NO_ADDRESS\n"); ++ check_hostent ("gethostbyname2 AF_INET q.example", ++ gethostbyname2 ("q.example", AF_INET), ++ "error: NO_RECOVERY\n"); ++ check_hostent ("gethostbyname2 AF_INET qam.example", ++ gethostbyname2 ("qam.example", AF_INET), ++ "name: qam.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname2 AF_INET qa.example", ++ gethostbyname2 ("qa.example", AF_INET), ++ "name: qa.example\n" ++ "address: 192.0.2.17\n"); ++ ++ check_hostent ("gethostbyname2 AF_INET6 qm.example", ++ gethostbyname2 ("qm.example", AF_INET6), ++ "name: qm.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname2 AF_INET6 q.example", ++ gethostbyname2 ("q.example", AF_INET6), ++ "name: q.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname2 AF_INET6 qam.example", ++ gethostbyname2 ("qam.example", AF_INET6), ++ "name: qam.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname2 AF_INET6 qa.example", ++ gethostbyname2 ("qa.example", AF_INET6), ++ "name: qa.example\n" ++ "address: 2001:db8::1\n"); ++ /* Additional AF_INET6 tests depend on RES_USE_INET6; see below. */ ++ ++ test_reverse (); ++} ++ ++/* gethostbyname2 tests with RES_USE_INET6 disabled. */ ++static void ++test_get2_no_inet6 (void) ++{ ++ test_get2_any (); ++ ++ check_hostent ("gethostbyname2 AF_INET6 am.example", ++ gethostbyname2 ("am.example", AF_INET6), ++ "error: NO_ADDRESS\n"); ++ check_hostent ("gethostbyname2 AF_INET6 a.example", ++ gethostbyname2 ("a.example", AF_INET6), ++ "error: NO_RECOVERY\n"); ++} ++ ++/* gethostbyname2 tests with RES_USE_INET6 enabled. */ ++static void ++test_get2_inet6 (void) ++{ ++ test_get2_any (); ++ ++ check_hostent ("gethostbyname2 AF_INET6 am.example", ++ gethostbyname2 ("am.example", AF_INET6), ++ "name: am.example\n" ++ "address: ::ffff:192.0.2.17\n"); ++ check_hostent ("gethostbyname2 AF_INET6 a.example", ++ gethostbyname2 ("a.example", AF_INET6), ++ "error: NO_RECOVERY\n"); ++} ++ ++/* Collection of tests which assume no RES_USE_INET6 flag. */ ++static void ++test_no_inet6 (void) ++{ ++ check_hostent ("gethostbyname (\"a.example\")", ++ gethostbyname ("a.example"), ++ "name: a.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"qa.example\")", ++ gethostbyname ("qa.example"), ++ "name: qa.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"am.example\")", ++ gethostbyname ("am.example"), ++ "name: am.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"amp.example\")", ++ gethostbyname ("amp.example"), ++ "name: amp.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"qam.example\")", ++ gethostbyname ("qam.example"), ++ "name: qam.example\n" ++ "address: 192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"q.example\")", ++ gethostbyname ("q.example"), ++ "error: NO_RECOVERY\n"); ++ check_hostent ("gethostbyname (\"qm.example\")", ++ gethostbyname ("qm.example"), ++ "error: NO_ADDRESS\n"); ++ test_get2_no_inet6 (); ++ test_get2_no_inet6 (); ++ test_gai (); ++ test_get2_no_inet6 (); ++ test_get2_no_inet6 (); ++} ++ ++static void * ++threadfunc (void *ignored) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ TEST_VERIFY ((_res.options & RES_USE_INET6) == 0); ++ test_no_inet6 (); ++ ++ _res.options |= RES_USE_INET6; ++ check_hostent ("gethostbyname (\"a.inet6.example\")", ++ gethostbyname ("a.inet6.example"), ++ "error: NO_RECOVERY\n"); ++ check_hostent ("gethostbyname (\"am.inet6.example\")", ++ gethostbyname ("am.inet6.example"), ++ "name: am.inet6.example\n" ++ "address: ::ffff:192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"qa.inet6.example\")", ++ gethostbyname ("qa.inet6.example"), ++ "name: qa.inet6.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname (\"qam.inet6.example\")", ++ gethostbyname ("qam.inet6.example"), ++ "name: qam.inet6.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname (\"q.inet6.example\")", ++ gethostbyname ("q.inet6.example"), ++ "name: q.inet6.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname (\"qm.inet6.example\")", ++ gethostbyname ("qm.inet6.example"), ++ "name: qm.inet6.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname (\"amp.inet6.example\")", ++ gethostbyname ("amp.inet6.example"), ++ "error: NO_RECOVERY\n"); ++ check_hostent ("gethostbyname (\"qmp.inet6.example\")", ++ gethostbyname ("qmp.inet6.example"), ++ "name: qmp.inet6.example\n" ++ "address: 2001:db8::1\n"); ++ check_hostent ("gethostbyname (\"ap.inet6.example\")", ++ gethostbyname ("ap.inet6.example"), ++ "error: NO_RECOVERY\n"); ++ check_hostent ("gethostbyname (\"6ap.inet6.example\")", ++ gethostbyname ("6ap.inet6.example"), ++ "name: 6ap.inet6.example\n" ++ "address: ::ffff:192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"am6p.inet6.example\")", ++ gethostbyname ("am6p.inet6.example"), ++ "name: am6p.inet6.example\n" ++ "address: ::ffff:192.0.2.17\n"); ++ check_hostent ("gethostbyname (\"qp.inet6.example\")", ++ gethostbyname ("qp.inet6.example"), ++ "name: qp.inet6.example\n" ++ "address: 2001:db8::1\n"); ++ test_get2_inet6 (); ++ test_get2_inet6 (); ++ test_gai (); ++ test_get2_inet6 (); ++ test_get2_inet6 (); ++ ++ TEST_VERIFY (_res.options & RES_USE_INET6); ++ _res.options &= ~RES_USE_INET6; ++ test_no_inet6 (); ++ ++ resolv_test_end (obj); ++ ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ resolv_test_init (); ++ ++ /* Attempt to run on a non-main thread first. */ ++ { ++ pthread_t thr = xpthread_create (NULL, threadfunc, NULL); ++ xpthread_join (thr); ++ } ++ ++ /* Try the main thread next. */ ++ threadfunc (NULL); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-basic.c b/resolv/tst-resolv-basic.c +new file mode 100644 +index 0000000000000000..66a0e8a1659219b4 +--- /dev/null ++++ b/resolv/tst-resolv-basic.c +@@ -0,0 +1,503 @@ ++/* Test basic nss_dns functionality and the resolver test harness itself. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define LONG_NAME \ ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax." \ ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay." \ ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz." \ ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat" ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_VERIFY_EXIT (qname != NULL); ++ ++ /* The "t." prefix can be used to request TCP fallback. */ ++ bool force_tcp; ++ if (strncmp ("t.", qname, 2) == 0) ++ force_tcp = true; ++ else ++ force_tcp = false; ++ const char *qname_compare; ++ if (force_tcp) ++ qname_compare = qname + 2; ++ else ++ qname_compare = qname; ++ enum {www, alias, nxdomain, long_name, nodata} requested_qname; ++ if (strcmp (qname_compare, "www.example") == 0) ++ requested_qname = www; ++ else if (strcmp (qname_compare, "alias.example") == 0) ++ requested_qname = alias; ++ else if (strcmp (qname_compare, "nxdomain.example") == 0) ++ requested_qname = nxdomain; ++ else if (strcmp (qname_compare, LONG_NAME) == 0) ++ requested_qname = long_name; ++ else if (strcmp (qname_compare, "nodata.example") == 0) ++ requested_qname = nodata; ++ else ++ { ++ support_record_failure (); ++ printf ("error: unexpected QNAME: %s\n", qname); ++ return; ++ } ++ TEST_VERIFY_EXIT (qclass == C_IN); ++ struct resolv_response_flags flags = {.tc = force_tcp && !ctx->tcp}; ++ if (requested_qname == nxdomain) ++ flags.rcode = 3; /* NXDOMAIN */ ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ if (requested_qname == nxdomain || flags.tc) ++ return; ++ ++ resolv_response_section (b, ns_s_an); ++ switch (requested_qname) ++ { ++ case www: ++ case long_name: ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ break; ++ case alias: ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ resolv_response_add_name (b, "www.example"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, "www.example", qclass, qtype, 0); ++ break; ++ case nodata: ++ return; ++ case nxdomain: ++ FAIL_EXIT1 ("unreachable"); ++ } ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {192, 0, 2, 17}; ++ ipv4[3] += requested_qname + 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ ipv6[15] += requested_qname + 2 * ctx->tcp + 4 * ctx->server_index; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ support_record_failure (); ++ printf ("error: unexpected QTYPE: %s/%u/%u\n", ++ qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++} ++ ++static void ++check_h (const char *name, int family, const char *expected) ++{ ++ if (family == AF_INET) ++ { ++ char *query = xasprintf ("gethostbyname (\"%s\")", name); ++ check_hostent (query, gethostbyname (name), expected); ++ free (query); ++ } ++ { ++ char *query = xasprintf ("gethostbyname2 (\"%s\", %d)", name, family); ++ check_hostent (query, gethostbyname2 (name, family), expected); ++ free (query); ++ } ++ ++ bool too_small = true; ++ for (unsigned int offset = 0; offset < 8; ++offset) ++ for (unsigned int size = 1; too_small; ++size) ++ { ++ char *buf = xmalloc (offset + size); ++ too_small = false; ++ ++ struct hostent hostbuf; ++ struct hostent *result; ++ int herror; ++ if (family == AF_INET) ++ { ++ char *query = xasprintf ("gethostbyname (\"%s\") %u/%u", ++ name, offset, size); ++ int ret = gethostbyname_r ++ (name, &hostbuf, buf + offset, size, &result, &herror); ++ if (ret == 0) ++ { ++ h_errno = herror; ++ check_hostent (query, result, expected); ++ } ++ else if (ret == ERANGE) ++ too_small = true; ++ else ++ { ++ errno = ret; ++ FAIL_EXIT1 ("gethostbyname_r: %m"); ++ } ++ free (query); ++ memset (buf, 0, offset + size); ++ } ++ char *query = xasprintf ("gethostbyname2 (\"%s\", %d) %u/%u", ++ name, family, offset, size); ++ int ret = gethostbyname2_r ++ (name, family, &hostbuf, buf + offset, size, &result, &herror); ++ if (ret == 0) ++ { ++ h_errno = herror; ++ check_hostent (query, result, expected); ++ } ++ else if (ret == ERANGE) ++ too_small = true; ++ else ++ { ++ errno = ret; ++ FAIL_EXIT1 ("gethostbyname_r: %m"); ++ } ++ free (buf); ++ free (query); ++ } ++} ++ ++static void ++check_ai_hints (const char *name, const char *service, ++ struct addrinfo hints, const char *expected) ++{ ++ struct addrinfo *ai; ++ char *query = xasprintf ("%s:%s [%d]/0x%x", name, service, ++ hints.ai_family, hints.ai_flags); ++ int ret = getaddrinfo (name, service, &hints, &ai); ++ check_addrinfo (query, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (query); ++} ++ ++static void ++check_ai (const char *name, const char *service, ++ int family, const char *expected) ++{ ++ return check_ai_hints (name, service, ++ (struct addrinfo) { .ai_family = family, }, ++ expected); ++} ++ ++/* Test for bug 21295: getaddrinfo used to discard address information ++ instead of merging it. */ ++static void ++test_bug_21295 (void) ++{ ++ /* The address order is unpredictable. There are two factors which ++ contribute to that: The stub resolver does not perform proper ++ response matching for A/AAAA queries (an A response could be ++ associated with an AAAA query and vice versa), and without ++ namespaces, system configuration could affect address ++ ordering. */ ++ for (int do_tcp = 0; do_tcp < 2; ++do_tcp) ++ { ++ const struct addrinfo hints = ++ { ++ .ai_family = AF_INET6, ++ .ai_socktype = SOCK_STREAM, ++ .ai_flags = AI_V4MAPPED | AI_ALL, ++ }; ++ const char *qname; ++ if (do_tcp) ++ qname = "t.www.example"; ++ else ++ qname = "www.example"; ++ struct addrinfo *ai = NULL; ++ int ret = getaddrinfo (qname, "80", &hints, &ai); ++ TEST_VERIFY_EXIT (ret == 0); ++ ++ const char *expected_a; ++ const char *expected_b; ++ if (do_tcp) ++ { ++ expected_a = "flags: AI_V4MAPPED AI_ALL\n" ++ "address: STREAM/TCP 2001:db8::3 80\n" ++ "address: STREAM/TCP ::ffff:192.0.2.19 80\n"; ++ expected_b = "flags: AI_V4MAPPED AI_ALL\n" ++ "address: STREAM/TCP ::ffff:192.0.2.19 80\n" ++ "address: STREAM/TCP 2001:db8::3 80\n"; ++ } ++ else ++ { ++ expected_a = "flags: AI_V4MAPPED AI_ALL\n" ++ "address: STREAM/TCP 2001:db8::1 80\n" ++ "address: STREAM/TCP ::ffff:192.0.2.17 80\n"; ++ expected_b = "flags: AI_V4MAPPED AI_ALL\n" ++ "address: STREAM/TCP ::ffff:192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"; ++ } ++ ++ char *actual = support_format_addrinfo (ai, ret); ++ if (!(strcmp (actual, expected_a) == 0 ++ || strcmp (actual, expected_b) == 0)) ++ { ++ support_record_failure (); ++ printf ("error: %s: unexpected response (TCP: %d):\n%s\n", ++ __func__, do_tcp, actual); ++ } ++ free (actual); ++ freeaddrinfo (ai); ++ } ++} ++ ++/* Run tests which do not expect any data. */ ++static void ++test_nodata_nxdomain (void) ++{ ++ /* Iterate through different address families. */ ++ int families[] = { AF_UNSPEC, AF_INET, AF_INET6, -1 }; ++ for (int i = 0; families[i] >= 0; ++i) ++ /* If do_tcp, prepend "t." to the name to trigger TCP ++ fallback. */ ++ for (int do_tcp = 0; do_tcp < 2; ++do_tcp) ++ /* If do_nxdomain, trigger an NXDOMAIN error (DNS failure), ++ otherwise use a NODATA response (empty but successful ++ answer). */ ++ for (int do_nxdomain = 0; do_nxdomain < 2; ++do_nxdomain) ++ { ++ int family = families[i]; ++ char *name = xasprintf ("%s%s.example", ++ do_tcp ? "t." : "", ++ do_nxdomain ? "nxdomain" : "nodata"); ++ ++ if (family != AF_UNSPEC) ++ { ++ if (do_nxdomain) ++ check_h (name, family, "error: HOST_NOT_FOUND\n"); ++ else ++ check_h (name, family, "error: NO_ADDRESS\n"); ++ } ++ ++ const char *expected; ++ if (do_nxdomain) ++ expected = "error: Name or service not known\n"; ++ else ++ expected = "error: No address associated with hostname\n"; ++ ++ check_ai (name, "80", family, expected); ++ ++ struct addrinfo hints = ++ { ++ .ai_family = family, ++ .ai_flags = AI_V4MAPPED | AI_ALL, ++ }; ++ check_ai_hints (name, "80", hints, expected); ++ hints.ai_flags |= AI_CANONNAME; ++ check_ai_hints (name, "80", hints, expected); ++ ++ free (name); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ check_h ("www.example", AF_INET, ++ "name: www.example\n" ++ "address: 192.0.2.17\n"); ++ check_h ("alias.example", AF_INET, ++ "name: www.example\n" ++ "alias: alias.example\n" ++ "address: 192.0.2.18\n"); ++ check_h ("www.example", AF_INET6, ++ "name: www.example\n" ++ "address: 2001:db8::1\n"); ++ check_h ("alias.example", AF_INET6, ++ "name: www.example\n" ++ "alias: alias.example\n" ++ "address: 2001:db8::2\n"); ++ check_h (LONG_NAME, AF_INET, ++ "name: " LONG_NAME "\n" ++ "address: 192.0.2.20\n"); ++ ++ check_ai ("www.example", "80", AF_UNSPEC, ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: DGRAM/UDP 192.0.2.17 80\n" ++ "address: RAW/IP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n" ++ "address: DGRAM/UDP 2001:db8::1 80\n" ++ "address: RAW/IP 2001:db8::1 80\n"); ++ check_ai_hints ("www.example", "80", ++ (struct addrinfo) { .ai_family = AF_UNSPEC, ++ .ai_flags = AI_CANONNAME, }, ++ "flags: AI_CANONNAME\n" ++ "canonname: www.example\n" ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: DGRAM/UDP 192.0.2.17 80\n" ++ "address: RAW/IP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n" ++ "address: DGRAM/UDP 2001:db8::1 80\n" ++ "address: RAW/IP 2001:db8::1 80\n"); ++ check_ai ("alias.example", "80", AF_UNSPEC, ++ "address: STREAM/TCP 192.0.2.18 80\n" ++ "address: DGRAM/UDP 192.0.2.18 80\n" ++ "address: RAW/IP 192.0.2.18 80\n" ++ "address: STREAM/TCP 2001:db8::2 80\n" ++ "address: DGRAM/UDP 2001:db8::2 80\n" ++ "address: RAW/IP 2001:db8::2 80\n"); ++ check_ai_hints ("alias.example", "80", ++ (struct addrinfo) { .ai_family = AF_UNSPEC, ++ .ai_flags = AI_CANONNAME, }, ++ "flags: AI_CANONNAME\n" ++ "canonname: www.example\n" ++ "address: STREAM/TCP 192.0.2.18 80\n" ++ "address: DGRAM/UDP 192.0.2.18 80\n" ++ "address: RAW/IP 192.0.2.18 80\n" ++ "address: STREAM/TCP 2001:db8::2 80\n" ++ "address: DGRAM/UDP 2001:db8::2 80\n" ++ "address: RAW/IP 2001:db8::2 80\n"); ++ check_ai (LONG_NAME, "80", AF_UNSPEC, ++ "address: STREAM/TCP 192.0.2.20 80\n" ++ "address: DGRAM/UDP 192.0.2.20 80\n" ++ "address: RAW/IP 192.0.2.20 80\n" ++ "address: STREAM/TCP 2001:db8::4 80\n" ++ "address: DGRAM/UDP 2001:db8::4 80\n" ++ "address: RAW/IP 2001:db8::4 80\n"); ++ check_ai ("www.example", "80", AF_INET, ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: DGRAM/UDP 192.0.2.17 80\n" ++ "address: RAW/IP 192.0.2.17 80\n"); ++ check_ai_hints ("www.example", "80", ++ (struct addrinfo) { .ai_family = AF_INET, ++ .ai_flags = AI_CANONNAME, }, ++ "flags: AI_CANONNAME\n" ++ "canonname: www.example\n" ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: DGRAM/UDP 192.0.2.17 80\n" ++ "address: RAW/IP 192.0.2.17 80\n"); ++ check_ai ("alias.example", "80", AF_INET, ++ "address: STREAM/TCP 192.0.2.18 80\n" ++ "address: DGRAM/UDP 192.0.2.18 80\n" ++ "address: RAW/IP 192.0.2.18 80\n"); ++ check_ai_hints ("alias.example", "80", ++ (struct addrinfo) { .ai_family = AF_INET, ++ .ai_flags = AI_CANONNAME, }, ++ "flags: AI_CANONNAME\n" ++ "canonname: www.example\n" ++ "address: STREAM/TCP 192.0.2.18 80\n" ++ "address: DGRAM/UDP 192.0.2.18 80\n" ++ "address: RAW/IP 192.0.2.18 80\n"); ++ check_ai (LONG_NAME, "80", AF_INET, ++ "address: STREAM/TCP 192.0.2.20 80\n" ++ "address: DGRAM/UDP 192.0.2.20 80\n" ++ "address: RAW/IP 192.0.2.20 80\n"); ++ check_ai ("www.example", "80", AF_INET6, ++ "address: STREAM/TCP 2001:db8::1 80\n" ++ "address: DGRAM/UDP 2001:db8::1 80\n" ++ "address: RAW/IP 2001:db8::1 80\n"); ++ check_ai_hints ("www.example", "80", ++ (struct addrinfo) { .ai_family = AF_INET6, ++ .ai_flags = AI_CANONNAME, }, ++ "flags: AI_CANONNAME\n" ++ "canonname: www.example\n" ++ "address: STREAM/TCP 2001:db8::1 80\n" ++ "address: DGRAM/UDP 2001:db8::1 80\n" ++ "address: RAW/IP 2001:db8::1 80\n"); ++ check_ai ("alias.example", "80", AF_INET6, ++ "address: STREAM/TCP 2001:db8::2 80\n" ++ "address: DGRAM/UDP 2001:db8::2 80\n" ++ "address: RAW/IP 2001:db8::2 80\n"); ++ check_ai_hints ("alias.example", "80", ++ (struct addrinfo) { .ai_family = AF_INET6, ++ .ai_flags = AI_CANONNAME, }, ++ "flags: AI_CANONNAME\n" ++ "canonname: www.example\n" ++ "address: STREAM/TCP 2001:db8::2 80\n" ++ "address: DGRAM/UDP 2001:db8::2 80\n" ++ "address: RAW/IP 2001:db8::2 80\n"); ++ check_ai (LONG_NAME, "80", AF_INET6, ++ "address: STREAM/TCP 2001:db8::4 80\n" ++ "address: DGRAM/UDP 2001:db8::4 80\n" ++ "address: RAW/IP 2001:db8::4 80\n"); ++ ++ check_h ("t.www.example", AF_INET, ++ "name: t.www.example\n" ++ "address: 192.0.2.19\n"); ++ check_h ("t.alias.example", AF_INET, ++ "name: www.example\n" ++ "alias: t.alias.example\n" ++ "address: 192.0.2.20\n"); ++ check_h ("t.www.example", AF_INET6, ++ "name: t.www.example\n" ++ "address: 2001:db8::3\n"); ++ check_h ("t.alias.example", AF_INET6, ++ "name: www.example\n" ++ "alias: t.alias.example\n" ++ "address: 2001:db8::4\n"); ++ check_ai ("t.www.example", "80", AF_UNSPEC, ++ "address: STREAM/TCP 192.0.2.19 80\n" ++ "address: DGRAM/UDP 192.0.2.19 80\n" ++ "address: RAW/IP 192.0.2.19 80\n" ++ "address: STREAM/TCP 2001:db8::3 80\n" ++ "address: DGRAM/UDP 2001:db8::3 80\n" ++ "address: RAW/IP 2001:db8::3 80\n"); ++ check_ai ("t.alias.example", "80", AF_UNSPEC, ++ "address: STREAM/TCP 192.0.2.20 80\n" ++ "address: DGRAM/UDP 192.0.2.20 80\n" ++ "address: RAW/IP 192.0.2.20 80\n" ++ "address: STREAM/TCP 2001:db8::4 80\n" ++ "address: DGRAM/UDP 2001:db8::4 80\n" ++ "address: RAW/IP 2001:db8::4 80\n"); ++ check_ai ("t.www.example", "80", AF_INET, ++ "address: STREAM/TCP 192.0.2.19 80\n" ++ "address: DGRAM/UDP 192.0.2.19 80\n" ++ "address: RAW/IP 192.0.2.19 80\n"); ++ check_ai ("t.alias.example", "80", AF_INET, ++ "address: STREAM/TCP 192.0.2.20 80\n" ++ "address: DGRAM/UDP 192.0.2.20 80\n" ++ "address: RAW/IP 192.0.2.20 80\n"); ++ check_ai ("t.www.example", "80", AF_INET6, ++ "address: STREAM/TCP 2001:db8::3 80\n" ++ "address: DGRAM/UDP 2001:db8::3 80\n" ++ "address: RAW/IP 2001:db8::3 80\n"); ++ check_ai ("t.alias.example", "80", AF_INET6, ++ "address: STREAM/TCP 2001:db8::4 80\n" ++ "address: DGRAM/UDP 2001:db8::4 80\n" ++ "address: RAW/IP 2001:db8::4 80\n"); ++ ++ test_bug_21295 (); ++ test_nodata_nxdomain (); ++ ++ resolv_test_end (aux); ++ ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-canonname.c b/resolv/tst-resolv-canonname.c +new file mode 100644 +index 0000000000000000..5daac33882957791 +--- /dev/null ++++ b/resolv/tst-resolv-canonname.c +@@ -0,0 +1,313 @@ ++/* Test _nss_dns_getcanonname_r corner cases. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* _nss_dns_getcanonname_r is not called during regular operation ++ because nss_dns directly provides a canonical name, so we have to ++ test it directly. The function pointer is initialized by do_test ++ below. */ ++static enum nss_status ++(*getcanonname) (const char *name, char *buffer, size_t buflen, ++ char **result, int *errnop, int *h_errnop); ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ int code; ++ { ++ char *tail; ++ if (sscanf (qname, "code%d.%ms", &code, &tail) != 2 ++ || strcmp (tail, "example") != 0) ++ FAIL_EXIT1 ("error: invalid QNAME: %s\n", qname); ++ free (tail); ++ } ++ ++ switch (code) ++ { ++ case 1: ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, "www.example", qclass, qtype, 0); ++ resolv_response_add_data (b, "\xC0\x00\x02\x01", 4); ++ resolv_response_close_record (b); ++ break; ++ case 2: ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ if (qtype == T_AAAA) ++ { ++ resolv_response_open_record (b, "www.example", qclass, qtype, 0); ++ resolv_response_add_data (b, "\xC0\x00\x02\x01", 4); ++ resolv_response_close_record (b); ++ for (int i = 0; i < 30000; ++i) ++ resolv_response_add_data (b, "", 1); ++ } ++ break; ++ case 3: ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ if (qtype == T_AAAA) ++ { ++ resolv_response_open_record (b, "www.example", qclass, qtype, 0); ++ resolv_response_add_data (b, "\xC0\x00\x02\x01", 4); ++ resolv_response_close_record (b); ++ } ++ else ++ { ++ for (int i = 0; i < 30000; ++i) ++ resolv_response_add_data (b, "", 1); ++ } ++ break; ++ case 4: ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ resolv_response_add_name (b, "www.example"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, "www.example", qclass, qtype, 0); ++ resolv_response_add_data (b, "\xC0\x00\x02\x01", 4); ++ resolv_response_close_record (b); ++ break; ++ case 5: ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ resolv_response_add_name (b, "www.example"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ resolv_response_add_name (b, "www1.example"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, "www1.example", qclass, qtype, 0); ++ resolv_response_add_data (b, "\xC0\x00\x02\x01", 4); ++ resolv_response_close_record (b); ++ break; ++ case 6: ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ resolv_response_add_name (b, "www.example"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, qname, qclass, 46 /* RRSIG */, 0); ++ resolv_response_add_name (b, "."); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, "www.example", qclass, qtype, 0); ++ resolv_response_add_data (b, "\xC0\x00\x02\x01", 4); ++ resolv_response_close_record (b); ++ break; ++ case 102: ++ if (!ctx->tcp) ++ { ++ resolv_response_init (b, (struct resolv_response_flags) {.tc = true}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ } ++ else ++ { ++ resolv_response_init ++ (b, (struct resolv_response_flags) {.ancount = 1}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ size_t to_fill = 65535 - resolv_response_length (b) ++ - 2 /* length, "n" */ - 2 /* compression reference */ ++ - 2 /* RR type */; ++ for (size_t i = 0; i < to_fill; ++i) ++ resolv_response_add_data (b, "", 1); ++ resolv_response_close_record (b); ++ resolv_response_add_name (b, "n.example"); ++ uint16_t rrtype = htons (T_CNAME); ++ resolv_response_add_data (b, &rrtype, sizeof (rrtype)); ++ } ++ break; ++ case 103: ++ /* NODATA repsonse. */ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ break; ++ case 104: ++ resolv_response_init (b, (struct resolv_response_flags) {.ancount = 1}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ /* No RR metadata. */ ++ resolv_response_add_name (b, "www.example"); ++ break; ++ case 105: ++ if (qtype == T_A) ++ { ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ /* No data, trigger AAAA query. */ ++ } ++ else ++ { ++ resolv_response_init ++ (b, (struct resolv_response_flags) {.ancount = 1}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ /* No RR metadata. */ ++ resolv_response_add_name ++ (b, "long-name-exceed-previously-initialized-buffer.example"); ++ } ++ break; ++ case 106: ++ resolv_response_init (b, (struct resolv_response_flags) {.ancount = 1}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ /* No RR metadata. */ ++ resolv_response_add_name (b, "www.example"); ++ resolv_response_add_data (b, "\xff\xff", 2); ++ break; ++ case 107: ++ if (qtype == T_A) ++ { ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ /* No data, trigger AAAA query. */ ++ } ++ else ++ { ++ resolv_response_init ++ (b, (struct resolv_response_flags) {.ancount = 1}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ /* No RR metadata. */ ++ resolv_response_add_name (b, "www.example"); ++ resolv_response_add_data (b, "\xff\xff", 2); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("error: invalid QNAME: %s (code %d)\n", qname, code); ++ } ++} ++ ++static void ++check (int code, const char *expected) ++{ ++ char qname[200]; ++ snprintf (qname, sizeof (qname), "code%d.example", code); ++ char *result; ++ enum nss_status status; ++ { ++ enum { buffer_size = 4096 }; ++ char *buffer = xmalloc (buffer_size); ++ char *temp_result; ++ int temp_errno; ++ int temp_herrno; ++ status = getcanonname ++ (qname, buffer, buffer_size, &temp_result, &temp_errno, &temp_herrno); ++ if (status == NSS_STATUS_SUCCESS) ++ result = xstrdup (temp_result); ++ else ++ { ++ errno = temp_errno; ++ h_errno = temp_herrno; ++ } ++ free (buffer); ++ } ++ ++ if (status == NSS_STATUS_SUCCESS) ++ { ++ if (expected != NULL) ++ { ++ if (strcmp (result, expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: getcanonname (%s) failed\n", qname); ++ printf ("error: expected: %s\n", expected); ++ printf ("error: actual: %s\n", result); ++ free (result); ++ return; ++ } ++ } ++ else ++ { ++ support_record_failure (); ++ printf ("error: getcanonname (%s) unexpected success\n", qname); ++ printf ("error: actual: %s\n", result); ++ free (result); ++ return; ++ } ++ free (result); ++ } ++ else ++ { ++ if (expected != NULL) ++ { ++ support_record_failure (); ++ printf ("error: getcanonname (%s) failed\n", qname); ++ printf ("error: expected: %s\n", expected); ++ return; ++ } ++ } ++} ++ ++ ++static int ++do_test (void) ++{ ++ void *nss_dns_handle = dlopen (LIBNSS_DNS_SO, RTLD_LAZY); ++ if (nss_dns_handle == NULL) ++ FAIL_EXIT1 ("could not dlopen %s: %s", LIBNSS_DNS_SO, dlerror ()); ++ { ++ const char *func = "_nss_dns_getcanonname_r"; ++ void *ptr = dlsym (nss_dns_handle, func); ++ if (ptr == NULL) ++ FAIL_EXIT1 ("could not look up %s: %s", func, dlerror ()); ++ getcanonname = ptr; ++ } ++ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ check (1, "www.example"); ++ check (2, "www.example"); ++ check (3, "www.example"); ++ check (4, "www.example"); ++ check (5, "www1.example"); ++ ++ /* This should really result in "www.example", but the fake RRSIG ++ record causes the current implementation to stop parsing. */ ++ check (6, NULL); ++ ++ for (int i = 102; i <= 107; ++i) ++ check (i, NULL); ++ ++ resolv_test_end (aux); ++ ++ TEST_VERIFY (dlclose (nss_dns_handle) == 0); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-edns.c b/resolv/tst-resolv-edns.c +new file mode 100644 +index 0000000000000000..8945d79d092ff5d3 +--- /dev/null ++++ b/resolv/tst-resolv-edns.c +@@ -0,0 +1,532 @@ ++/* Test EDNS handling in the stub resolver. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Data produced by a test query. */ ++struct response_data ++{ ++ char *qname; ++ uint16_t qtype; ++ struct resolv_edns_info edns; ++}; ++ ++/* Global array used by put_response and get_response to record ++ response data. The test DNS server returns the index of the array ++ element which contains the actual response data. This enables the ++ test case to return arbitrary amounts of data with the limited ++ number of bits which fit into an IP addres. ++ ++ The volatile specifier is needed because the test case accesses ++ these variables from a callback function called from a function ++ which is marked as __THROW (i.e., a leaf function which actually is ++ not). */ ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++static struct response_data ** volatile response_data_array; ++volatile static size_t response_data_count; ++ ++/* Extract information from the query, store it in a struct ++ response_data object, and return its index in the ++ response_data_array. */ ++static unsigned int ++put_response (const struct resolv_response_context *ctx, ++ const char *qname, uint16_t qtype) ++{ ++ xpthread_mutex_lock (&mutex); ++ ++response_data_count; ++ /* We only can represent 2**24 indexes in 10.0.0.0/8. */ ++ TEST_VERIFY (response_data_count < (1 << 24)); ++ response_data_array = xrealloc ++ (response_data_array, sizeof (*response_data_array) * response_data_count); ++ unsigned int index = response_data_count - 1; ++ struct response_data *data = xmalloc (sizeof (*data)); ++ *data = (struct response_data) ++ { ++ .qname = xstrdup (qname), ++ .qtype = qtype, ++ .edns = ctx->edns, ++ }; ++ response_data_array[index] = data; ++ xpthread_mutex_unlock (&mutex); ++ return index; ++} ++ ++/* Verify the index into the response_data array and return the data ++ at it. */ ++static struct response_data * ++get_response (unsigned int index) ++{ ++ xpthread_mutex_lock (&mutex); ++ TEST_VERIFY_EXIT (index < response_data_count); ++ struct response_data *result = response_data_array[index]; ++ xpthread_mutex_unlock (&mutex); ++ return result; ++} ++ ++/* Deallocate all response data. */ ++static void ++free_response_data (void) ++{ ++ xpthread_mutex_lock (&mutex); ++ size_t count = response_data_count; ++ struct response_data **array = response_data_array; ++ for (unsigned int i = 0; i < count; ++i) ++ { ++ struct response_data *data = array[i]; ++ free (data->qname); ++ free (data); ++ } ++ free (array); ++ response_data_array = NULL; ++ response_data_count = 0; ++ xpthread_mutex_unlock (&mutex); ++} ++ ++#define EDNS_PROBE_EXAMPLE "edns-probe.example" ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_VERIFY_EXIT (qname != NULL); ++ ++ const char *qname_compare = qname; ++ ++ /* The "formerr." prefix can be used to request a FORMERR response on the ++ first server. */ ++ bool send_formerr; ++ if (strncmp ("formerr.", qname, strlen ("formerr.")) == 0) ++ { ++ send_formerr = true; ++ qname_compare = qname + strlen ("formerr."); ++ } ++ else ++ { ++ send_formerr = false; ++ qname_compare = qname; ++ } ++ ++ /* The "tcp." prefix can be used to request TCP fallback. */ ++ bool force_tcp; ++ if (strncmp ("tcp.", qname_compare, strlen ("tcp.")) == 0) ++ { ++ force_tcp = true; ++ qname_compare += strlen ("tcp."); ++ } ++ else ++ force_tcp = false; ++ ++ enum {edns_probe} requested_qname; ++ if (strcmp (qname_compare, EDNS_PROBE_EXAMPLE) == 0) ++ requested_qname = edns_probe; ++ else ++ { ++ support_record_failure (); ++ printf ("error: unexpected QNAME: %s (reduced: %s)\n", ++ qname, qname_compare); ++ return; ++ } ++ TEST_VERIFY_EXIT (qclass == C_IN); ++ struct resolv_response_flags flags = { }; ++ flags.tc = force_tcp && !ctx->tcp; ++ if (!flags.tc && send_formerr && ctx->server_index == 0) ++ /* Send a FORMERR for the first full response from the first ++ server. */ ++ flags.rcode = 1; /* FORMERR */ ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ if (flags.tc || flags.rcode != 0) ++ return; ++ ++ if (test_verbose) ++ printf ("info: edns=%d payload_size=%d\n", ++ ctx->edns.active, ctx->edns.payload_size); ++ ++ /* Encode the response_data object in multiple address records. ++ Each record carries two bytes of payload data, and an index. */ ++ resolv_response_section (b, ns_s_an); ++ switch (requested_qname) ++ { ++ case edns_probe: ++ { ++ unsigned int index = put_response (ctx, qname, qtype); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ uint32_t addr = htonl (0x0a000000 | index); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ resolv_response_add_data (b, &addr, sizeof (addr)); ++ resolv_response_close_record (b); ++ } ++ break; ++ case T_AAAA: ++ { ++ char addr[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ index >> 16, index >> 8, index}; ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ resolv_response_add_data (b, &addr, sizeof (addr)); ++ resolv_response_close_record (b); ++ } ++ } ++ } ++ break; ++ } ++} ++ ++/* Update *DATA with data from ADDRESS of SIZE. Set the corresponding ++ flag in SHADOW for each byte written. */ ++static struct response_data * ++decode_address (const void *address, size_t size) ++{ ++ switch (size) ++ { ++ case 4: ++ TEST_VERIFY (memcmp (address, "\x0a", 1) == 0); ++ break; ++ case 16: ++ TEST_VERIFY (memcmp (address, "\x20\x01\x0d\xb8", 4) == 0); ++ break; ++ default: ++ FAIL_EXIT1 ("unexpected address size %zu", size); ++ } ++ const unsigned char *addr = address; ++ unsigned int index = addr[size - 3] * 256 * 256 ++ + addr[size - 2] * 256 ++ + addr[size - 1]; ++ return get_response (index); ++} ++ ++static struct response_data * ++decode_hostent (struct hostent *e) ++{ ++ TEST_VERIFY_EXIT (e != NULL); ++ TEST_VERIFY_EXIT (e->h_addr_list[0] != NULL); ++ TEST_VERIFY (e->h_addr_list[1] == NULL); ++ return decode_address (e->h_addr_list[0], e->h_length); ++} ++ ++static struct response_data * ++decode_addrinfo (struct addrinfo *ai, int family) ++{ ++ struct response_data *data = NULL; ++ while (ai != NULL) ++ { ++ if (ai->ai_family == family) ++ { ++ struct response_data *new_data; ++ switch (family) ++ { ++ case AF_INET: ++ { ++ struct sockaddr_in *pin = (struct sockaddr_in *) ai->ai_addr; ++ new_data = decode_address (&pin->sin_addr.s_addr, 4); ++ } ++ break; ++ case AF_INET6: ++ { ++ struct sockaddr_in6 *pin = (struct sockaddr_in6 *) ai->ai_addr; ++ new_data = decode_address (&pin->sin6_addr.s6_addr, 16); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("invalid address family %d", ai->ai_family); ++ } ++ if (data == NULL) ++ data = new_data; ++ else ++ /* Check pointer equality because this should be the same ++ response (same index). */ ++ TEST_VERIFY (data == new_data); ++ } ++ ai = ai->ai_next; ++ } ++ TEST_VERIFY_EXIT (data != NULL); ++ return data; ++} ++ ++/* Updated by the main test loop in accordance with what is set in ++ _res.options. */ ++static bool use_edns; ++static bool use_dnssec; ++ ++/* Verify the decoded response data against the flags above. */ ++static void ++verify_response_data_payload (struct response_data *data, ++ size_t expected_payload) ++{ ++ bool edns = use_edns || use_dnssec; ++ TEST_VERIFY (data->edns.active == edns); ++ if (!edns) ++ expected_payload = 0; ++ if (data->edns.payload_size != expected_payload) ++ { ++ support_record_failure (); ++ printf ("error: unexpected payload size %d (edns=%d)\n", ++ (int) data->edns.payload_size, edns); ++ } ++ uint16_t expected_flags = 0; ++ if (use_dnssec) ++ expected_flags |= 0x8000; /* DO flag. */ ++ if (data->edns.flags != expected_flags) ++ { ++ support_record_failure (); ++ printf ("error: unexpected EDNS flags 0x%04x (edns=%d)\n", ++ (int) data->edns.flags, edns); ++ } ++} ++ ++/* Same as verify_response_data_payload, but use the default ++ payload. */ ++static void ++verify_response_data (struct response_data *data) ++{ ++ verify_response_data_payload (data, 1200); ++} ++ ++static void ++check_hostent (struct hostent *e) ++{ ++ TEST_VERIFY_EXIT (e != NULL); ++ verify_response_data (decode_hostent (e)); ++} ++ ++static void ++do_ai (int family) ++{ ++ struct addrinfo hints = { .ai_family = family }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo (EDNS_PROBE_EXAMPLE, "80", &hints, &ai); ++ TEST_VERIFY_EXIT (ret == 0); ++ switch (family) ++ { ++ case AF_INET: ++ case AF_INET6: ++ verify_response_data (decode_addrinfo (ai, family)); ++ break; ++ case AF_UNSPEC: ++ verify_response_data (decode_addrinfo (ai, AF_INET)); ++ verify_response_data (decode_addrinfo (ai, AF_INET6)); ++ break; ++ default: ++ FAIL_EXIT1 ("invalid address family %d", family); ++ } ++ freeaddrinfo (ai); ++} ++ ++enum res_op ++{ ++ res_op_search, ++ res_op_query, ++ res_op_querydomain, ++ res_op_nsearch, ++ res_op_nquery, ++ res_op_nquerydomain, ++ ++ res_op_last = res_op_nquerydomain, ++}; ++ ++static const char * ++res_op_string (enum res_op op) ++{ ++ switch (op) ++ { ++ case res_op_search: ++ return "res_search"; ++ case res_op_query: ++ return "res_query"; ++ case res_op_querydomain: ++ return "res_querydomain"; ++ case res_op_nsearch: ++ return "res_nsearch"; ++ case res_op_nquery: ++ return "res_nquery"; ++ case res_op_nquerydomain: ++ return "res_nquerydomain"; ++ } ++ FAIL_EXIT1 ("invalid res_op value %d", (int) op); ++} ++ ++/* Call libresolv function OP to look up PROBE_NAME, with an answer ++ buffer of SIZE bytes. Check that the advertised UDP buffer size is ++ in fact EXPECTED_BUFFER_SIZE. */ ++static void ++do_res_search (const char *probe_name, enum res_op op, size_t size, ++ size_t expected_buffer_size) ++{ ++ if (test_verbose) ++ printf ("info: testing %s with buffer size %zu\n", ++ res_op_string (op), size); ++ unsigned char *buffer = xmalloc (size); ++ int ret = -1; ++ switch (op) ++ { ++ case res_op_search: ++ ret = res_search (probe_name, C_IN, T_A, buffer, size); ++ break; ++ case res_op_query: ++ ret = res_query (probe_name, C_IN, T_A, buffer, size); ++ break; ++ case res_op_nsearch: ++ ret = res_nsearch (&_res, probe_name, C_IN, T_A, buffer, size); ++ break; ++ case res_op_nquery: ++ ret = res_nquery (&_res, probe_name, C_IN, T_A, buffer, size); ++ break; ++ case res_op_querydomain: ++ case res_op_nquerydomain: ++ { ++ char *example_stripped = xstrdup (probe_name); ++ char *dot_example = strstr (example_stripped, ".example"); ++ if (dot_example != NULL && strcmp (dot_example, ".example") == 0) ++ { ++ /* Truncate the domain name. */ ++ *dot_example = '\0'; ++ if (op == res_op_querydomain) ++ ret = res_querydomain ++ (example_stripped, "example", C_IN, T_A, buffer, size); ++ else ++ ret = res_nquerydomain ++ (&_res, example_stripped, "example", C_IN, T_A, buffer, size); ++ } ++ else ++ FAIL_EXIT1 ("invalid probe name: %s", probe_name); ++ free (example_stripped); ++ } ++ break; ++ } ++ TEST_VERIFY_EXIT (ret > 12); ++ unsigned char *end = buffer + ret; ++ ++ HEADER *hd = (HEADER *) buffer; ++ TEST_VERIFY (ntohs (hd->qdcount) == 1); ++ TEST_VERIFY (ntohs (hd->ancount) == 1); ++ /* Skip over the header. */ ++ unsigned char *p = buffer + sizeof (*hd); ++ /* Skip over the question. */ ++ ret = dn_skipname (p, end); ++ TEST_VERIFY_EXIT (ret > 0); ++ p += ret; ++ TEST_VERIFY_EXIT (end - p >= 4); ++ p += 4; ++ /* Skip over the RNAME and the RR header, but stop at the RDATA ++ length. */ ++ ret = dn_skipname (p, end); ++ TEST_VERIFY_EXIT (ret > 0); ++ p += ret; ++ TEST_VERIFY_EXIT (end - p >= 2 + 2 + 4 + 2 + 4); ++ p += 2 + 2 + 4; ++ /* The IP address should be 4 bytes long. */ ++ TEST_VERIFY_EXIT (p[0] == 0); ++ TEST_VERIFY_EXIT (p[1] == 4); ++ /* Extract the address information. */ ++ p += 2; ++ struct response_data *data = decode_address (p, 4); ++ ++ verify_response_data_payload (data, expected_buffer_size); ++ ++ free (buffer); ++} ++ ++static void ++run_test (const char *probe_name) ++{ ++ if (test_verbose) ++ printf ("\ninfo: * use_edns=%d use_dnssec=%d\n", ++ use_edns, use_dnssec); ++ check_hostent (gethostbyname (probe_name)); ++ check_hostent (gethostbyname2 (probe_name, AF_INET)); ++ check_hostent (gethostbyname2 (probe_name, AF_INET6)); ++ do_ai (AF_UNSPEC); ++ do_ai (AF_INET); ++ do_ai (AF_INET6); ++ ++ for (int op = 0; op <= res_op_last; ++op) ++ { ++ do_res_search (probe_name, op, 301, 512); ++ do_res_search (probe_name, op, 511, 512); ++ do_res_search (probe_name, op, 512, 512); ++ do_res_search (probe_name, op, 513, 513); ++ do_res_search (probe_name, op, 657, 657); ++ do_res_search (probe_name, op, 1199, 1199); ++ do_res_search (probe_name, op, 1200, 1200); ++ do_res_search (probe_name, op, 1201, 1200); ++ do_res_search (probe_name, op, 65535, 1200); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ for (int do_edns = 0; do_edns < 2; ++do_edns) ++ for (int do_dnssec = 0; do_dnssec < 2; ++do_dnssec) ++ for (int do_tcp = 0; do_tcp < 2; ++do_tcp) ++ for (int do_formerr = 0; do_formerr < 2; ++do_formerr) ++ { ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ use_edns = do_edns; ++ if (do_edns) ++ _res.options |= RES_USE_EDNS0; ++ use_dnssec = do_dnssec; ++ if (do_dnssec) ++ _res.options |= RES_USE_DNSSEC; ++ ++ char *probe_name = xstrdup (EDNS_PROBE_EXAMPLE); ++ if (do_tcp) ++ { ++ char *n = xasprintf ("tcp.%s", probe_name); ++ free (probe_name); ++ probe_name = n; ++ } ++ if (do_formerr) ++ { ++ /* Send a garbage query in an attempt to trigger EDNS ++ fallback. */ ++ char *n = xasprintf ("formerr.%s", probe_name); ++ gethostbyname (n); ++ free (n); ++ } ++ ++ run_test (probe_name); ++ ++ free (probe_name); ++ resolv_test_end (aux); ++ } ++ ++ free_response_data (); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-network.c b/resolv/tst-resolv-network.c +new file mode 100644 +index 0000000000000000..df9daf8d5825cf01 +--- /dev/null ++++ b/resolv/tst-resolv-network.c +@@ -0,0 +1,299 @@ ++/* Test getnetbyname and getnetbyaddr. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static void ++send_ptr (struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype, ++ const char *alias) ++{ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, alias); ++ resolv_response_close_record (b); ++} ++ ++static void ++handle_code (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype, ++ int code) ++{ ++ switch (code) ++ { ++ case 1: ++ send_ptr (b, qname, qclass, qtype, "1.in-addr.arpa"); ++ break; ++ case 2: ++ send_ptr (b, qname, qclass, qtype, "2.1.in-addr.arpa"); ++ break; ++ case 3: ++ send_ptr (b, qname, qclass, qtype, "3.2.1.in-addr.arpa"); ++ break; ++ case 4: ++ send_ptr (b, qname, qclass, qtype, "4.3.2.1.in-addr.arpa"); ++ break; ++ case 5: ++ /* Test multiple PTR records. */ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "127.in-addr.arpa"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "0.in-addr.arpa"); ++ resolv_response_close_record (b); ++ break; ++ case 6: ++ /* Test skipping of RRSIG record. */ ++ resolv_response_init (b, (struct resolv_response_flags) { }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "127.in-addr.arpa"); ++ resolv_response_close_record (b); ++ ++ resolv_response_open_record (b, qname, qclass, 46 /* RRSIG */, 0); ++ { ++ char buf[500]; ++ memset (buf, 0x3f, sizeof (buf)); ++ resolv_response_add_data (b, buf, sizeof (buf)); ++ } ++ resolv_response_close_record (b); ++ ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "0.in-addr.arpa"); ++ resolv_response_close_record (b); ++ break; ++ case 7: ++ /* Test CNAME handling. */ ++ resolv_response_init (b, (struct resolv_response_flags) { }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_CNAME, 0); ++ resolv_response_add_name (b, "cname.example"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, "cname.example", qclass, T_PTR, 0); ++ resolv_response_add_name (b, "4.3.2.1.in-addr.arpa"); ++ resolv_response_close_record (b); ++ break; ++ ++ case 100: ++ resolv_response_init (b, (struct resolv_response_flags) { .rcode = 0, }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ break; ++ case 101: ++ resolv_response_init (b, (struct resolv_response_flags) ++ { .rcode = NXDOMAIN, }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ break; ++ case 102: ++ resolv_response_init (b, (struct resolv_response_flags) {.rcode = SERVFAIL}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ break; ++ case 103: ++ /* Check response length matching. */ ++ if (!ctx->tcp) ++ { ++ resolv_response_init (b, (struct resolv_response_flags) {.tc = true}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ } ++ else ++ { ++ resolv_response_init (b, (struct resolv_response_flags) {.ancount = 1}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "127.in-addr.arpa"); ++ resolv_response_close_record (b); ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ resolv_response_add_name (b, "example"); ++ resolv_response_close_record (b); ++ ++ resolv_response_open_record (b, qname, qclass, T_PTR, 0); ++ size_t to_fill = 65535 - resolv_response_length (b) ++ - 2 /* length, "n" */ - 2 /* compression reference */ ++ - 2 /* RR type */; ++ for (size_t i = 0; i < to_fill; ++i) ++ resolv_response_add_data (b, "", 1); ++ resolv_response_close_record (b); ++ resolv_response_add_name (b, "n.example"); ++ uint16_t rrtype = htons (T_PTR); ++ resolv_response_add_data (b, &rrtype, sizeof (rrtype)); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("invalid QNAME: %s (code %d)", qname, code); ++ } ++} ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ int code; ++ if (strstr (qname, "in-addr.arpa") == NULL) ++ { ++ char *tail; ++ if (sscanf (qname, "code%d.%ms", &code, &tail) != 2 ++ || strcmp (tail, "example") != 0) ++ FAIL_EXIT1 ("invalid QNAME: %s", qname); ++ free (tail); ++ handle_code (ctx, b, qname, qclass, qtype, code); ++ } ++ else ++ { ++ /* Reverse lookup. */ ++ int components[4]; ++ char *tail; ++ if (sscanf (qname, "%d.%d.%d.%d.%ms", ++ components, components + 1, components + 2, components + 3, ++ &tail) != 5 ++ || strcmp (tail, "in-addr.arpa") != 0) ++ FAIL_EXIT1 ("invalid QNAME: %s", qname); ++ free (tail); ++ handle_code (ctx, b, qname, qclass, qtype, components[3]); ++ } ++} ++ ++static void ++check_reverse (int code, const char *expected) ++{ ++ char *query = xasprintf ("code=%d", code); ++ check_netent (query, getnetbyaddr (code, AF_INET), expected); ++ free (query); ++} ++ ++/* Test for CVE-2016-3075. */ ++static void ++check_long_name (void) ++{ ++ struct xmemstream mem; ++ xopen_memstream (&mem); ++ ++ char label[65]; ++ memset (label, 'x', 63); ++ label[63] = '.'; ++ label[64] = '\0'; ++ for (unsigned i = 0; i < 64 * 1024 * 1024 / strlen (label); ++i) ++ fprintf (mem.out, "%s", label); ++ ++ xfclose_memstream (&mem); ++ ++ check_netent ("long name", getnetbyname (mem.buffer), ++ "error: NO_RECOVERY\n"); ++ ++ free (mem.buffer); ++} ++ ++int ++main (void) ++{ ++ struct resolv_test *obj = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response ++ }); ++ ++ /* Lookup by name, success cases. */ ++ check_netent ("code1.example", getnetbyname ("code1.example"), ++ "alias: 1.in-addr.arpa\n" ++ "net: 0x00000001\n"); ++ check_netent ("code2.example", getnetbyname ("code2.example"), ++ "alias: 2.1.in-addr.arpa\n" ++ "net: 0x00000102\n"); ++ check_netent ("code3.example", getnetbyname ("code3.example"), ++ "alias: 3.2.1.in-addr.arpa\n" ++ "net: 0x00010203\n"); ++ check_netent ("code4.example", getnetbyname ("code4.example"), ++ "alias: 4.3.2.1.in-addr.arpa\n" ++ "net: 0x01020304\n"); ++ check_netent ("code5.example", getnetbyname ("code5.example"), ++ "alias: 127.in-addr.arpa\n" ++ "alias: 0.in-addr.arpa\n" ++ "net: 0x0000007f\n"); ++ check_netent ("code6.example", getnetbyname ("code6.example"), ++ "alias: 127.in-addr.arpa\n" ++ "alias: 0.in-addr.arpa\n" ++ "net: 0x0000007f\n"); ++ check_netent ("code7.example", getnetbyname ("code7.example"), ++ "alias: 4.3.2.1.in-addr.arpa\n" ++ "net: 0x01020304\n"); ++ ++ /* Lookup by name, failure cases. */ ++ check_netent ("code100.example", getnetbyname ("code100.example"), ++ "error: NO_ADDRESS\n"); ++ check_netent ("code101.example", getnetbyname ("code101.example"), ++ "error: HOST_NOT_FOUND\n"); ++ check_netent ("code102.example", getnetbyname ("code102.example"), ++ "error: TRY_AGAIN\n"); ++ check_netent ("code103.example", getnetbyname ("code103.example"), ++ "error: NO_RECOVERY\n"); ++ ++ /* Lookup by address, success cases. */ ++ check_reverse (1, ++ "name: 1.in-addr.arpa\n" ++ "net: 0x00000001\n"); ++ check_reverse (2, ++ "name: 2.1.in-addr.arpa\n" ++ "net: 0x00000002\n"); ++ check_reverse (3, ++ "name: 3.2.1.in-addr.arpa\n" ++ "net: 0x00000003\n"); ++ check_reverse (4, ++ "name: 4.3.2.1.in-addr.arpa\n" ++ "net: 0x00000004\n"); ++ check_reverse (5, ++ "name: 127.in-addr.arpa\n" ++ "alias: 0.in-addr.arpa\n" ++ "net: 0x00000005\n"); ++ check_reverse (6, ++ "name: 127.in-addr.arpa\n" ++ "alias: 0.in-addr.arpa\n" ++ "net: 0x00000006\n"); ++ check_reverse (7, ++ "name: 4.3.2.1.in-addr.arpa\n" ++ "net: 0x00000007\n"); ++ ++ /* Lookup by address, failure cases. */ ++ check_reverse (100, ++ "error: NO_ADDRESS\n"); ++ check_reverse (101, ++ "error: HOST_NOT_FOUND\n"); ++ check_reverse (102, ++ "error: TRY_AGAIN\n"); ++ check_reverse (103, ++ "error: NO_RECOVERY\n"); ++ ++ check_long_name (); ++ ++ resolv_test_end (obj); ++} +diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c +new file mode 100644 +index 0000000000000000..06ea3dbd1463ef60 +--- /dev/null ++++ b/resolv/tst-resolv-qtypes.c +@@ -0,0 +1,185 @@ ++/* Exercise low-level query functions with different QTYPEs. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* If ture, the response function will send the actual response packet ++ over TCP instead of UDP. */ ++static volatile bool force_tcp; ++ ++/* Send back a fake resource record matching the QTYPE. */ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ if (force_tcp && ctx->tcp) ++ { ++ resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ resolv_response_init (b, (struct resolv_response_flags) { }); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ resolv_response_add_data (b, &qtype, sizeof (qtype)); ++ resolv_response_close_record (b); ++} ++ ++static const char * const domain = "www.example.com"; ++ ++static int ++wrap_res_query (int type, unsigned char *answer, int answer_length) ++{ ++ return res_query (domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_search (int type, unsigned char *answer, int answer_length) ++{ ++ return res_query (domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_querydomain (int type, unsigned char *answer, int answer_length) ++{ ++ return res_querydomain ("www", "example.com", C_IN, type, ++ answer, answer_length); ++} ++ ++static int ++wrap_res_send (int type, unsigned char *answer, int answer_length) ++{ ++ unsigned char buf[512]; ++ int ret = res_mkquery (QUERY, domain, C_IN, type, ++ (const unsigned char *) "", 0, NULL, ++ buf, sizeof (buf)); ++ if (type < 0 || type >= 65536) ++ { ++ /* res_mkquery fails for out-of-range record types. */ ++ TEST_VERIFY_EXIT (ret == -1); ++ return -1; ++ } ++ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ ++ return res_send (buf, ret, answer, answer_length); ++} ++ ++static int ++wrap_res_nquery (int type, unsigned char *answer, int answer_length) ++{ ++ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_nsearch (int type, unsigned char *answer, int answer_length) ++{ ++ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); ++} ++ ++static int ++wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length) ++{ ++ return res_nquerydomain (&_res, "www", "example.com", C_IN, type, ++ answer, answer_length); ++} ++ ++static int ++wrap_res_nsend (int type, unsigned char *answer, int answer_length) ++{ ++ unsigned char buf[512]; ++ int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type, ++ (const unsigned char *) "", 0, NULL, ++ buf, sizeof (buf)); ++ if (type < 0 || type >= 65536) ++ { ++ /* res_mkquery fails for out-of-range record types. */ ++ TEST_VERIFY_EXIT (ret == -1); ++ return -1; ++ } ++ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ ++ return res_nsend (&_res, buf, ret, answer, answer_length); ++} ++ ++static void ++test_function (const char *fname, ++ int (*func) (int type, ++ unsigned char *answer, int answer_length)) ++{ ++ unsigned char buf[512]; ++ for (int tcp = 0; tcp < 2; ++tcp) ++ { ++ force_tcp = tcp; ++ for (unsigned int type = 1; type <= 65535; ++type) ++ { ++ if (test_verbose) ++ printf ("info: sending QTYPE %d with %s (tcp=%d)\n", ++ type, fname, tcp); ++ int ret = func (type, buf, sizeof (buf)); ++ if (ret != 47) ++ FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d", ++ fname,tcp, type, ret); ++ /* One question, one answer record. */ ++ TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0); ++ /* Question section. */ ++ static const char qname[] = "\3www\7example\3com"; ++ size_t qname_length = sizeof (qname); ++ TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0); ++ /* RDATA part of answer. */ ++ uint16_t type16 = type; ++ TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0); ++ } ++ } ++ ++ TEST_VERIFY (func (-1, buf, sizeof (buf) == -1)); ++ TEST_VERIFY (func (65536, buf, sizeof (buf) == -1)); ++} ++ ++static int ++do_test (void) ++{ ++ struct resolv_redirect_config config = ++ { ++ .response_callback = response, ++ }; ++ struct resolv_test *obj = resolv_test_start (config); ++ ++ test_function ("res_query", &wrap_res_query); ++ test_function ("res_search", &wrap_res_search); ++ test_function ("res_querydomain", &wrap_res_querydomain); ++ test_function ("res_send", &wrap_res_send); ++ ++ test_function ("res_nquery", &wrap_res_nquery); ++ test_function ("res_nsearch", &wrap_res_nsearch); ++ test_function ("res_nquerydomain", &wrap_res_nquerydomain); ++ test_function ("res_nsend", &wrap_res_nsend); ++ ++ resolv_test_end (obj); ++ return 0; ++} ++ ++#define TIMEOUT 300 ++#include +diff --git a/resolv/tst-resolv-res_init-multi.c b/resolv/tst-resolv-res_init-multi.c +new file mode 100644 +index 0000000000000000..bdc68a5a33f7f017 +--- /dev/null ++++ b/resolv/tst-resolv-res_init-multi.c +@@ -0,0 +1,89 @@ ++/* Multi-threaded test for resolver initialization. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Whether name lookups succeed does not really matter. We use this ++ to trigger initialization of the resolver. */ ++static const char *test_hostname = "www.gnu.org"; ++ ++/* The different initialization methods. */ ++enum test_type { init, byname, gai }; ++enum { type_count = 3 }; ++ ++/* Thread function. Perform a few resolver options. */ ++static void * ++thread_func (void *closure) ++{ ++ enum test_type *ptype = closure; ++ /* Perform a few calls to the requested operation. */ ++ TEST_VERIFY (*ptype >= 0); ++ TEST_VERIFY (*ptype < (int) type_count); ++ for (int i = 0; i < 3; ++i) ++ switch (*ptype) ++ { ++ case init: ++ res_init (); ++ break; ++ case byname: ++ gethostbyname (test_hostname); ++ break; ++ case gai: ++ { ++ struct addrinfo hints = { 0, }; ++ struct addrinfo *ai = NULL; ++ if (getaddrinfo (test_hostname, "80", &hints, &ai) == 0) ++ freeaddrinfo (ai); ++ } ++ break; ++ } ++ free (ptype); ++ return NULL; ++} ++ ++static int ++do_test (void) ++{ ++ /* Start a small number of threads which perform resolver ++ operations. */ ++ enum { thread_count = 30 }; ++ ++ pthread_t threads[thread_count]; ++ for (int i = 0; i < thread_count; ++i) ++ { ++ enum test_type *ptype = xmalloc (sizeof (*ptype)); ++ *ptype = i % type_count; ++ threads[i] = xpthread_create (NULL, thread_func, ptype); ++ } ++ for (int i = 0; i < type_count; ++i) ++ { ++ enum test_type *ptype = xmalloc (sizeof (*ptype)); ++ *ptype = i; ++ thread_func (ptype); ++ } ++ for (int i = 0; i < thread_count; ++i) ++ xpthread_join (threads[i]); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c +new file mode 100644 +index 0000000000000000..3b7b4129e31eaa22 +--- /dev/null ++++ b/resolv/tst-resolv-res_init-skeleton.c +@@ -0,0 +1,1092 @@ ++/* Test parsing of /etc/resolv.conf. Genric version. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Before including this file, TEST_THREAD has to be defined to 0 or ++ 1, depending on whether the threading tests should be compiled ++ in. */ ++ ++#include ++#include ++#include ++#include ++#include /* For DEPRECATED_RES_USE_INET6. */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if TEST_THREAD ++# include ++#endif ++ ++/* This is the host name used to ensure predictable behavior of ++ res_init. */ ++static const char *const test_hostname = "www.example.com"; ++ ++struct support_chroot *chroot_env; ++ ++static void ++prepare (int argc, char **argv) ++{ ++ chroot_env = support_chroot_create ++ ((struct support_chroot_configuration) ++ { ++ .resolv_conf = "", ++ }); ++} ++ ++/* Verify that the chroot environment has been set up. */ ++static void ++check_chroot_working (void *closure) ++{ ++ xchroot (chroot_env->path_chroot); ++ FILE *fp = xfopen (_PATH_RESCONF, "r"); ++ xfclose (fp); ++ ++ TEST_VERIFY_EXIT (res_init () == 0); ++ TEST_VERIFY (_res.options & RES_INIT); ++ ++ char buf[100]; ++ if (gethostname (buf, sizeof (buf)) < 0) ++ FAIL_EXIT1 ("gethostname: %m"); ++ if (strcmp (buf, test_hostname) != 0) ++ FAIL_EXIT1 ("unexpected host name: %s", buf); ++} ++ ++/* If FLAG is set in *OPTIONS, write NAME to FP, and clear it in ++ *OPTIONS. */ ++static void ++print_option_flag (FILE *fp, int *options, int flag, const char *name) ++{ ++ if (*options & flag) ++ { ++ fprintf (fp, " %s", name); ++ *options &= ~flag; ++ } ++} ++ ++/* Write a decoded version of the resolver configuration *RESP to the ++ stream FP. */ ++static void ++print_resp (FILE *fp, res_state resp) ++{ ++ struct resolv_context *ctx = __resolv_context_get_override (resp); ++ TEST_VERIFY_EXIT (ctx != NULL); ++ if (ctx->conf == NULL) ++ fprintf (fp, "; extended resolver state missing\n"); ++ ++ /* The options directive. */ ++ { ++ /* RES_INIT is used internally for tracking initialization. */ ++ TEST_VERIFY (resp->options & RES_INIT); ++ /* Also mask out other default flags which cannot be set through ++ the options directive. */ ++ int options ++ = resp->options & ~(RES_INIT | RES_RECURSE | RES_DEFNAMES | RES_DNSRCH); ++ if (options != 0 ++ || resp->ndots != 1 ++ || resp->retrans != RES_TIMEOUT ++ || resp->retry != RES_DFLRETRY) ++ { ++ fputs ("options", fp); ++ if (resp->ndots != 1) ++ fprintf (fp, " ndots:%d", resp->ndots); ++ if (resp->retrans != RES_TIMEOUT) ++ fprintf (fp, " timeout:%d", resp->retrans); ++ if (resp->retry != RES_DFLRETRY) ++ fprintf (fp, " attempts:%d", resp->retry); ++ print_option_flag (fp, &options, RES_USEVC, "use-vc"); ++ print_option_flag (fp, &options, DEPRECATED_RES_USE_INET6, "inet6"); ++ print_option_flag (fp, &options, RES_ROTATE, "rotate"); ++ print_option_flag (fp, &options, RES_USE_EDNS0, "edns0"); ++ print_option_flag (fp, &options, RES_SNGLKUP, ++ "single-request"); ++ print_option_flag (fp, &options, RES_SNGLKUPREOP, ++ "single-request-reopen"); ++ print_option_flag (fp, &options, RES_NOTLDQUERY, "no-tld-query"); ++ print_option_flag (fp, &options, RES_NORELOAD, "no-reload"); ++ fputc ('\n', fp); ++ if (options != 0) ++ fprintf (fp, "; error: unresolved option bits: 0x%x\n", options); ++ } ++ } ++ ++ /* The search and domain directives. */ ++ if (resp->dnsrch[0] != NULL) ++ { ++ fputs ("search", fp); ++ for (int i = 0; i < MAXDNSRCH && resp->dnsrch[i] != NULL; ++i) ++ { ++ fputc (' ', fp); ++ fputs (resp->dnsrch[i], fp); ++ } ++ fputc ('\n', fp); ++ } ++ else if (resp->defdname[0] != '\0') ++ fprintf (fp, "domain %s\n", resp->defdname); ++ ++ /* The extended search path. */ ++ { ++ size_t i = 0; ++ while (true) ++ { ++ const char *name = __resolv_context_search_list (ctx, i); ++ if (name == NULL) ++ break; ++ fprintf (fp, "; search[%zu]: %s\n", i, name); ++ ++i; ++ } ++ } ++ ++ /* The sortlist directive. */ ++ if (resp->nsort > 0) ++ { ++ fputs ("sortlist", fp); ++ for (int i = 0; i < resp->nsort && i < MAXRESOLVSORT; ++i) ++ { ++ char net[20]; ++ if (inet_ntop (AF_INET, &resp->sort_list[i].addr, ++ net, sizeof (net)) == NULL) ++ FAIL_EXIT1 ("inet_ntop: %m\n"); ++ char mask[20]; ++ if (inet_ntop (AF_INET, &resp->sort_list[i].mask, ++ mask, sizeof (mask)) == NULL) ++ FAIL_EXIT1 ("inet_ntop: %m\n"); ++ fprintf (fp, " %s/%s", net, mask); ++ } ++ fputc ('\n', fp); ++ } ++ ++ /* The nameserver directives. */ ++ for (size_t i = 0; i < resp->nscount; ++i) ++ { ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ ++ /* See get_nsaddr in res_send.c. */ ++ void *addr; ++ size_t addrlen; ++ if (resp->nsaddr_list[i].sin_family == 0 ++ && resp->_u._ext.nsaddrs[i] != NULL) ++ { ++ addr = resp->_u._ext.nsaddrs[i]; ++ addrlen = sizeof (*resp->_u._ext.nsaddrs[i]); ++ } ++ else ++ { ++ addr = &resp->nsaddr_list[i]; ++ addrlen = sizeof (resp->nsaddr_list[i]); ++ } ++ ++ int ret = getnameinfo (addr, addrlen, ++ host, sizeof (host), service, sizeof (service), ++ NI_NUMERICHOST | NI_NUMERICSERV); ++ if (ret != 0) ++ { ++ if (ret == EAI_SYSTEM) ++ fprintf (fp, "; error: getnameinfo: %m\n"); ++ else ++ fprintf (fp, "; error: getnameinfo: %s\n", gai_strerror (ret)); ++ } ++ else ++ { ++ fprintf (fp, "nameserver %s\n", host); ++ if (strcmp (service, "53") != 0) ++ fprintf (fp, "; unrepresentable port number %s\n\n", service); ++ } ++ } ++ ++ /* The extended name server list. */ ++ { ++ size_t i = 0; ++ while (true) ++ { ++ const struct sockaddr *addr = __resolv_context_nameserver (ctx, i); ++ if (addr == NULL) ++ break; ++ size_t addrlen; ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ addrlen = sizeof (struct sockaddr_in); ++ break; ++ case AF_INET6: ++ addrlen = sizeof (struct sockaddr_in6); ++ break; ++ default: ++ FAIL_EXIT1 ("invalid address family %d", addr->sa_family); ++ } ++ ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ int ret = getnameinfo (addr, addrlen, ++ host, sizeof (host), service, sizeof (service), ++ NI_NUMERICHOST | NI_NUMERICSERV); ++ ++ if (ret != 0) ++ { ++ if (ret == EAI_SYSTEM) ++ fprintf (fp, "; error: getnameinfo: %m\n"); ++ else ++ fprintf (fp, "; error: getnameinfo: %s\n", gai_strerror (ret)); ++ } ++ else ++ fprintf (fp, "; nameserver[%zu]: [%s]:%s\n", i, host, service); ++ ++i; ++ } ++ } ++ ++ TEST_VERIFY (!ferror (fp)); ++ ++ __resolv_context_put (ctx); ++} ++ ++/* Parameters of one test case. */ ++struct test_case ++{ ++ /* A short, descriptive name of the test. */ ++ const char *name; ++ ++ /* The contents of the /etc/resolv.conf file. */ ++ const char *conf; ++ ++ /* The expected output from print_resp. */ ++ const char *expected; ++ ++ /* Setting for the LOCALDOMAIN environment variable. NULL if the ++ variable is not to be set. */ ++ const char *localdomain; ++ ++ /* Setting for the RES_OPTIONS environment variable. NULL if the ++ variable is not to be set. */ ++ const char *res_options; ++ ++ /* Override the system host name. NULL means that no change is made ++ and the default is used (test_hostname). */ ++ const char *hostname; ++}; ++ ++enum test_init ++{ ++ test_init, ++ test_ninit, ++ test_mkquery, ++ test_gethostbyname, ++ test_getaddrinfo, ++ test_init_method_last = test_getaddrinfo ++}; ++ ++static const char *const test_init_names[] = ++ { ++ [test_init] = "res_init", ++ [test_ninit] = "res_ninit", ++ [test_mkquery] = "res_mkquery", ++ [test_gethostbyname] = "gethostbyname", ++ [test_getaddrinfo] = "getaddrinfo", ++ }; ++ ++/* Closure argument for run_res_init. */ ++struct test_context ++{ ++ enum test_init init; ++ const struct test_case *t; ++}; ++ ++static void ++setup_nss_dns_and_chroot (void) ++{ ++ /* Load nss_dns outside of the chroot. */ ++ if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL) ++ FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ()); ++ xchroot (chroot_env->path_chroot); ++ /* Force the use of nss_dns. */ ++ __nss_configure_lookup ("hosts", "dns"); ++} ++ ++/* Run res_ninit or res_init in a subprocess and dump the parsed ++ resolver state to standard output. */ ++static void ++run_res_init (void *closure) ++{ ++ struct test_context *ctx = closure; ++ TEST_VERIFY (getenv ("LOCALDOMAIN") == NULL); ++ TEST_VERIFY (getenv ("RES_OPTIONS") == NULL); ++ if (ctx->t->localdomain != NULL) ++ setenv ("LOCALDOMAIN", ctx->t->localdomain, 1); ++ if (ctx->t->res_options != NULL) ++ setenv ("RES_OPTIONS", ctx->t->res_options, 1); ++ if (ctx->t->hostname != NULL) ++ { ++ /* This test needs its own namespace, to avoid changing the host ++ name for the parent, too. */ ++ TEST_VERIFY_EXIT (unshare (CLONE_NEWUTS) == 0); ++ if (sethostname (ctx->t->hostname, strlen (ctx->t->hostname)) != 0) ++ FAIL_EXIT1 ("sethostname (\"%s\"): %m", ctx->t->hostname); ++ } ++ ++ switch (ctx->init) ++ { ++ case test_init: ++ xchroot (chroot_env->path_chroot); ++ TEST_VERIFY (res_init () == 0); ++ print_resp (stdout, &_res); ++ return; ++ ++ case test_ninit: ++ xchroot (chroot_env->path_chroot); ++ res_state resp = xmalloc (sizeof (*resp)); ++ memset (resp, 0, sizeof (*resp)); ++ TEST_VERIFY (res_ninit (resp) == 0); ++ print_resp (stdout, resp); ++ res_nclose (resp); ++ free (resp); ++ return; ++ ++ case test_mkquery: ++ xchroot (chroot_env->path_chroot); ++ unsigned char buf[512]; ++ TEST_VERIFY (res_mkquery (QUERY, "www.example", ++ C_IN, ns_t_a, NULL, 0, ++ NULL, buf, sizeof (buf)) > 0); ++ print_resp (stdout, &_res); ++ return; ++ ++ case test_gethostbyname: ++ setup_nss_dns_and_chroot (); ++ /* Trigger implicit initialization of the _res structure. The ++ actual lookup result is immaterial. */ ++ (void )gethostbyname ("www.example"); ++ print_resp (stdout, &_res); ++ return; ++ ++ case test_getaddrinfo: ++ setup_nss_dns_and_chroot (); ++ /* Trigger implicit initialization of the _res structure. The ++ actual lookup result is immaterial. */ ++ struct addrinfo *ai; ++ (void) getaddrinfo ("www.example", NULL, NULL, &ai); ++ print_resp (stdout, &_res); ++ return; ++ } ++ ++ FAIL_EXIT1 ("invalid init method %d", ctx->init); ++} ++ ++#if TEST_THREAD ++/* Helper function which calls run_res_init from a thread. */ ++static void * ++run_res_init_thread_func (void *closure) ++{ ++ run_res_init (closure); ++ return NULL; ++} ++ ++/* Variant of res_run_init which runs the function on a non-main ++ thread. */ ++static void ++run_res_init_on_thread (void *closure) ++{ ++ xpthread_join (xpthread_create (NULL, run_res_init_thread_func, closure)); ++} ++#endif /* TEST_THREAD */ ++ ++struct test_case test_cases[] = ++ { ++ {.name = "empty file", ++ .conf = "", ++ .expected = "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n" ++ }, ++ {.name = "empty file, no-dot hostname", ++ .conf = "", ++ .expected = "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n", ++ .hostname = "example", ++ }, ++ {.name = "empty file with LOCALDOMAIN", ++ .conf = "", ++ .expected = "search example.net\n" ++ "; search[0]: example.net\n" ++ "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n", ++ .localdomain = "example.net", ++ }, ++ {.name = "empty file with RES_OPTIONS", ++ .conf = "", ++ .expected = "options attempts:5 edns0\n" ++ "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n", ++ .res_options = "edns0 attempts:5", ++ }, ++ {.name = "empty file with RES_OPTIONS and LOCALDOMAIN", ++ .conf = "", ++ .expected = "options attempts:5 edns0\n" ++ "search example.org\n" ++ "; search[0]: example.org\n" ++ "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n", ++ .localdomain = "example.org", ++ .res_options = "edns0 attempts:5", ++ }, ++ {.name = "basic", ++ .conf = "search corp.example.com example.com\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "search corp.example.com example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "basic with no-dot hostname", ++ .conf = "search corp.example.com example.com\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "search corp.example.com example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n", ++ .hostname = "example", ++ }, ++ {.name = "basic no-reload", ++ .conf = "options no-reload\n" ++ "search corp.example.com example.com\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "options no-reload\n" ++ "search corp.example.com example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "basic no-reload via RES_OPTIONS", ++ .conf = "search corp.example.com example.com\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "options no-reload\n" ++ "search corp.example.com example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n", ++ .res_options = "no-reload" ++ }, ++ {.name = "whitespace", ++ .conf = "# This test covers comment and whitespace processing " ++ " (trailing whitespace,\n" ++ "# missing newline at end of file).\n" ++ "\n" ++ ";search commented out\n" ++ "search corp.example.com\texample.com \n" ++ "#nameserver 192.0.2.3\n" ++ "nameserver 192.0.2.1 \n" ++ "nameserver 192.0.2.2", /* No \n at end of file. */ ++ .expected = "search corp.example.com example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 192.0.2.2\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ "; nameserver[1]: [192.0.2.2]:53\n" ++ }, ++ {.name = "domain", ++ .conf = "domain example.net\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "search example.net\n" ++ "; search[0]: example.net\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "domain space", ++ .conf = "domain example.net \n" ++ "nameserver 192.0.2.1\n", ++ .expected = "search example.net\n" ++ "; search[0]: example.net\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "domain tab", ++ .conf = "domain example.net\t\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "search example.net\n" ++ "; search[0]: example.net\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "domain override", ++ .conf = "search example.com example.org\n" ++ "nameserver 192.0.2.1\n" ++ "domain example.net", /* No \n at end of file. */ ++ .expected = "search example.net\n" ++ "; search[0]: example.net\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "option values, multiple servers", ++ .conf = "options\tinet6\tndots:3 edns0\tattempts:5\ttimeout:19\n" ++ "domain example.net\n" ++ ";domain comment\n" ++ "search corp.example.com\texample.com\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver ::1\n" ++ "nameserver 192.0.2.2\n", ++ .expected = "options ndots:3 timeout:19 attempts:5 inet6 edns0\n" ++ "search corp.example.com example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver ::1\n" ++ "nameserver 192.0.2.2\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ "; nameserver[1]: [::1]:53\n" ++ "; nameserver[2]: [192.0.2.2]:53\n" ++ }, ++ {.name = "out-of-range option vales", ++ .conf = "options use-vc timeout:999 attempts:999 ndots:99\n" ++ "search example.com\n", ++ .expected = "options ndots:15 timeout:30 attempts:5 use-vc\n" ++ "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n" ++ }, ++ {.name = "repeated directives", ++ .conf = "options ndots:3 use-vc\n" ++ "options edns0 ndots:2\n" ++ "domain corp.example\n" ++ "search example.net corp.example.com example.com\n" ++ "search example.org\n" ++ "search\n", ++ .expected = "options ndots:2 use-vc edns0\n" ++ "search example.org\n" ++ "; search[0]: example.org\n" ++ "nameserver 127.0.0.1\n" ++ "; nameserver[0]: [127.0.0.1]:53\n" ++ }, ++ {.name = "many name servers, sortlist", ++ .conf = "options single-request\n" ++ "search example.org example.com example.net corp.example.com\n" ++ "sortlist 192.0.2.0/255.255.255.0\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 192.0.2.2\n" ++ "nameserver 192.0.2.3\n" ++ "nameserver 192.0.2.4\n" ++ "nameserver 192.0.2.5\n" ++ "nameserver 192.0.2.6\n" ++ "nameserver 192.0.2.7\n" ++ "nameserver 192.0.2.8\n", ++ .expected = "options single-request\n" ++ "search example.org example.com example.net corp.example.com\n" ++ "; search[0]: example.org\n" ++ "; search[1]: example.com\n" ++ "; search[2]: example.net\n" ++ "; search[3]: corp.example.com\n" ++ "sortlist 192.0.2.0/255.255.255.0\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 192.0.2.2\n" ++ "nameserver 192.0.2.3\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ "; nameserver[1]: [192.0.2.2]:53\n" ++ "; nameserver[2]: [192.0.2.3]:53\n" ++ "; nameserver[3]: [192.0.2.4]:53\n" ++ "; nameserver[4]: [192.0.2.5]:53\n" ++ "; nameserver[5]: [192.0.2.6]:53\n" ++ "; nameserver[6]: [192.0.2.7]:53\n" ++ "; nameserver[7]: [192.0.2.8]:53\n" ++ }, ++ {.name = "IPv4 and IPv6 nameservers", ++ .conf = "options single-request\n" ++ "search example.org example.com example.net corp.example.com" ++ " legacy.example.com\n" ++ "sortlist 192.0.2.0\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 2001:db8::2\n" ++ "nameserver 192.0.2.3\n" ++ "nameserver 2001:db8::4\n" ++ "nameserver 192.0.2.5\n" ++ "nameserver 2001:db8::6\n" ++ "nameserver 192.0.2.7\n" ++ "nameserver 2001:db8::8\n", ++ .expected = "options single-request\n" ++ "search example.org example.com example.net corp.example.com" ++ " legacy.example.com\n" ++ "; search[0]: example.org\n" ++ "; search[1]: example.com\n" ++ "; search[2]: example.net\n" ++ "; search[3]: corp.example.com\n" ++ "; search[4]: legacy.example.com\n" ++ "sortlist 192.0.2.0/255.255.255.0\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 2001:db8::2\n" ++ "nameserver 192.0.2.3\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ "; nameserver[1]: [2001:db8::2]:53\n" ++ "; nameserver[2]: [192.0.2.3]:53\n" ++ "; nameserver[3]: [2001:db8::4]:53\n" ++ "; nameserver[4]: [192.0.2.5]:53\n" ++ "; nameserver[5]: [2001:db8::6]:53\n" ++ "; nameserver[6]: [192.0.2.7]:53\n" ++ "; nameserver[7]: [2001:db8::8]:53\n", ++ }, ++ {.name = "garbage after nameserver", ++ .conf = "nameserver 192.0.2.1 garbage\n" ++ "nameserver 192.0.2.2:5353\n" ++ "nameserver 192.0.2.3 5353\n", ++ .expected = "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 192.0.2.3\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ "; nameserver[1]: [192.0.2.3]:53\n" ++ }, ++ {.name = "RES_OPTIONS is cummulative", ++ .conf = "options timeout:7 ndots:2 use-vc\n" ++ "nameserver 192.0.2.1\n", ++ .expected = "options ndots:3 timeout:7 attempts:5 use-vc edns0\n" ++ "search example.com\n" ++ "; search[0]: example.com\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n", ++ .res_options = "attempts:5 ndots:3 edns0 ", ++ }, ++ {.name = "many search list entries (bug 19569)", ++ .conf = "nameserver 192.0.2.1\n" ++ "search corp.example.com support.example.com" ++ " community.example.org wan.example.net vpn.example.net" ++ " example.com example.org example.net\n", ++ .expected = "search corp.example.com support.example.com" ++ " community.example.org wan.example.net vpn.example.net example.com\n" ++ "; search[0]: corp.example.com\n" ++ "; search[1]: support.example.com\n" ++ "; search[2]: community.example.org\n" ++ "; search[3]: wan.example.net\n" ++ "; search[4]: vpn.example.net\n" ++ "; search[5]: example.com\n" ++ "; search[6]: example.org\n" ++ "; search[7]: example.net\n" ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ {.name = "very long search list entries (bug 21475)", ++ .conf = "nameserver 192.0.2.1\n" ++ "search example.com " ++#define H63 "this-host-name-is-longer-than-yours-yes-I-really-really-mean-it" ++#define D63 "this-domain-name-is-as-long-as-the-previous-name--63-characters" ++ " " H63 "." D63 ".example.org" ++ " " H63 "." D63 ".example.net\n", ++ .expected = "search example.com " H63 "." D63 ".example.org\n" ++ "; search[0]: example.com\n" ++ "; search[1]: " H63 "." D63 ".example.org\n" ++ "; search[2]: " H63 "." D63 ".example.net\n" ++#undef H63 ++#undef D63 ++ "nameserver 192.0.2.1\n" ++ "; nameserver[0]: [192.0.2.1]:53\n" ++ }, ++ { NULL } ++ }; ++ ++/* Run the indicated test case. This function assumes that the chroot ++ contents has already been set up. */ ++static void ++test_file_contents (const struct test_case *t) ++{ ++#if TEST_THREAD ++ for (int do_thread = 0; do_thread < 2; ++do_thread) ++#endif ++ for (int init_method = 0; init_method <= test_init_method_last; ++ ++init_method) ++ { ++ if (test_verbose > 0) ++ printf ("info: testing init method %s\n", ++ test_init_names[init_method]); ++ struct test_context ctx = { .init = init_method, .t = t }; ++ void (*func) (void *) = run_res_init; ++#if TEST_THREAD ++ if (do_thread) ++ func = run_res_init_on_thread; ++#endif ++ struct support_capture_subprocess proc ++ = support_capture_subprocess (func, &ctx); ++ if (strcmp (proc.out.buffer, t->expected) != 0) ++ { ++ support_record_failure (); ++ printf ("error: output mismatch for %s (init method %s)\n", ++ t->name, test_init_names[init_method]); ++ support_run_diff ("expected", t->expected, ++ "actual", proc.out.buffer); ++ } ++ support_capture_subprocess_check (&proc, t->name, 0, ++ sc_allow_stdout); ++ support_capture_subprocess_free (&proc); ++ } ++} ++ ++/* Special tests which do not follow the general pattern. */ ++enum { special_tests_count = 11 }; ++ ++/* Implementation of special tests. */ ++static void ++special_test_callback (void *closure) ++{ ++ unsigned int *test_indexp = closure; ++ unsigned test_index = *test_indexp; ++ TEST_VERIFY (test_index < special_tests_count); ++ if (test_verbose > 0) ++ printf ("info: special test %u\n", test_index); ++ xchroot (chroot_env->path_chroot); ++ ++ switch (test_index) ++ { ++ case 0: ++ case 1: ++ /* Second res_init with missing or empty file preserves ++ flags. */ ++ if (test_index == 1) ++ TEST_VERIFY (unlink (_PATH_RESCONF) == 0); ++ _res.options = RES_USE_EDNS0; ++ TEST_VERIFY (res_init () == 0); ++ /* First res_init clears flag. */ ++ TEST_VERIFY (!(_res.options & RES_USE_EDNS0)); ++ _res.options |= RES_USE_EDNS0; ++ TEST_VERIFY (res_init () == 0); ++ /* Second res_init preserves flag. */ ++ TEST_VERIFY (_res.options & RES_USE_EDNS0); ++ if (test_index == 1) ++ /* Restore empty file. */ ++ support_write_file_string (_PATH_RESCONF, ""); ++ break; ++ ++ case 2: ++ /* Second res_init is cumulative. */ ++ support_write_file_string (_PATH_RESCONF, ++ "options rotate\n" ++ "nameserver 192.0.2.1\n"); ++ _res.options = RES_USE_EDNS0; ++ TEST_VERIFY (res_init () == 0); ++ /* First res_init clears flag. */ ++ TEST_VERIFY (!(_res.options & RES_USE_EDNS0)); ++ /* And sets RES_ROTATE. */ ++ TEST_VERIFY (_res.options & RES_ROTATE); ++ _res.options |= RES_USE_EDNS0; ++ TEST_VERIFY (res_init () == 0); ++ /* Second res_init preserves flag. */ ++ TEST_VERIFY (_res.options & RES_USE_EDNS0); ++ TEST_VERIFY (_res.options & RES_ROTATE); ++ /* Reloading the configuration does not clear the explicitly set ++ flag. */ ++ support_write_file_string (_PATH_RESCONF, ++ "nameserver 192.0.2.1\n" ++ "nameserver 192.0.2.2\n"); ++ TEST_VERIFY (res_init () == 0); ++ TEST_VERIFY (_res.nscount == 2); ++ TEST_VERIFY (_res.options & RES_USE_EDNS0); ++ /* Whether RES_ROTATE (originally in resolv.conf, now removed) ++ should be preserved is subject to debate. See bug 21701. */ ++ /* TEST_VERIFY (!(_res.options & RES_ROTATE)); */ ++ break; ++ ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ support_write_file_string (_PATH_RESCONF, ++ "options edns0\n" ++ "nameserver 192.0.2.1\n"); ++ goto reload_tests; ++ case 7: /* 7 and the following tests are with no-reload. */ ++ case 8: ++ case 9: ++ case 10: ++ support_write_file_string (_PATH_RESCONF, ++ "options edns0 no-reload\n" ++ "nameserver 192.0.2.1\n"); ++ /* Fall through. */ ++ reload_tests: ++ for (int iteration = 0; iteration < 2; ++iteration) ++ { ++ switch (test_index) ++ { ++ case 3: ++ case 7: ++ TEST_VERIFY (res_init () == 0); ++ break; ++ case 4: ++ case 8: ++ { ++ unsigned char buf[512]; ++ TEST_VERIFY ++ (res_mkquery (QUERY, test_hostname, C_IN, T_A, ++ NULL, 0, NULL, buf, sizeof (buf)) > 0); ++ } ++ break; ++ case 5: ++ case 9: ++ gethostbyname (test_hostname); ++ break; ++ case 6: ++ case 10: ++ { ++ struct addrinfo *ai; ++ (void) getaddrinfo (test_hostname, NULL, NULL, &ai); ++ } ++ break; ++ } ++ /* test_index == 7 is res_init and performs a reload even ++ with no-reload. */ ++ if (iteration == 0 || test_index > 7) ++ { ++ TEST_VERIFY (_res.options & RES_USE_EDNS0); ++ TEST_VERIFY (!(_res.options & RES_ROTATE)); ++ if (test_index < 7) ++ TEST_VERIFY (!(_res.options & RES_NORELOAD)); ++ else ++ TEST_VERIFY (_res.options & RES_NORELOAD); ++ TEST_VERIFY (_res.nscount == 1); ++ /* File change triggers automatic reloading. */ ++ support_write_file_string (_PATH_RESCONF, ++ "options rotate\n" ++ "nameserver 192.0.2.1\n" ++ "nameserver 192.0.2.2\n"); ++ } ++ else ++ { ++ if (test_index != 3 && test_index != 7) ++ /* test_index 3, 7 are res_init; this function does ++ not reset flags. See bug 21701. */ ++ TEST_VERIFY (!(_res.options & RES_USE_EDNS0)); ++ TEST_VERIFY (_res.options & RES_ROTATE); ++ TEST_VERIFY (_res.nscount == 2); ++ } ++ } ++ break; ++ } ++} ++ ++#if TEST_THREAD ++/* Helper function which calls special_test_callback from a ++ thread. */ ++static void * ++special_test_thread_func (void *closure) ++{ ++ special_test_callback (closure); ++ return NULL; ++} ++ ++/* Variant of special_test_callback which runs the function on a ++ non-main thread. */ ++static void ++run_special_test_on_thread (void *closure) ++{ ++ xpthread_join (xpthread_create (NULL, special_test_thread_func, closure)); ++} ++#endif /* TEST_THREAD */ ++ ++/* Perform the requested special test in a subprocess using ++ special_test_callback. */ ++static void ++special_test (unsigned int test_index) ++{ ++#if TEST_THREAD ++ for (int do_thread = 0; do_thread < 2; ++do_thread) ++#endif ++ { ++ void (*func) (void *) = special_test_callback; ++#if TEST_THREAD ++ if (do_thread) ++ func = run_special_test_on_thread; ++#endif ++ struct support_capture_subprocess proc ++ = support_capture_subprocess (func, &test_index); ++ char *test_name = xasprintf ("special test %u", test_index); ++ if (strcmp (proc.out.buffer, "") != 0) ++ { ++ support_record_failure (); ++ printf ("error: output mismatch for %s\n", test_name); ++ support_run_diff ("expected", "", ++ "actual", proc.out.buffer); ++ } ++ support_capture_subprocess_check (&proc, test_name, 0, sc_allow_stdout); ++ free (test_name); ++ support_capture_subprocess_free (&proc); ++ } ++} ++ ++ ++/* Dummy DNS server. It ensures that the probe queries sent by ++ gethostbyname and getaddrinfo receive a reply even if the system ++ applies a very strict rate limit to localhost. */ ++static pid_t ++start_dummy_server (void) ++{ ++ int server_socket = xsocket (AF_INET, SOCK_DGRAM, 0); ++ { ++ struct sockaddr_in sin = ++ { ++ .sin_family = AF_INET, ++ .sin_addr = { .s_addr = htonl (INADDR_LOOPBACK) }, ++ .sin_port = htons (53), ++ }; ++ int ret = bind (server_socket, (struct sockaddr *) &sin, sizeof (sin)); ++ if (ret < 0) ++ { ++ if (errno == EACCES) ++ /* The port is reserved, which means we cannot start the ++ server. */ ++ return -1; ++ FAIL_EXIT1 ("cannot bind socket to port 53: %m"); ++ } ++ } ++ ++ pid_t pid = xfork (); ++ if (pid == 0) ++ { ++ /* Child process. Echo back queries as SERVFAIL responses. */ ++ while (true) ++ { ++ union ++ { ++ HEADER header; ++ unsigned char bytes[512]; ++ } packet; ++ struct sockaddr_in sin; ++ socklen_t sinlen = sizeof (sin); ++ ++ ssize_t ret = recvfrom ++ (server_socket, &packet, sizeof (packet), ++ MSG_NOSIGNAL, (struct sockaddr *) &sin, &sinlen); ++ if (ret < 0) ++ FAIL_EXIT1 ("recvfrom on fake server socket: %m"); ++ if (ret > sizeof (HEADER)) ++ { ++ /* Turn the query into a SERVFAIL response. */ ++ packet.header.qr = 1; ++ packet.header.rcode = ns_r_servfail; ++ ++ /* Send the response. */ ++ ret = sendto (server_socket, &packet, ret, ++ MSG_NOSIGNAL, (struct sockaddr *) &sin, sinlen); ++ if (ret < 0) ++ /* The peer may have closed socket prematurely, so ++ this is not an error. */ ++ printf ("warning: sending DNS server reply: %m\n"); ++ } ++ } ++ } ++ ++ /* In the parent, close the socket. */ ++ xclose (server_socket); ++ ++ return pid; ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ support_enter_network_namespace (); ++ if (!support_in_uts_namespace () || !support_can_chroot ()) ++ return EXIT_UNSUPPORTED; ++ ++ /* We are in an UTS namespace, so we can set the host name without ++ altering the state of the entire system. */ ++ if (sethostname (test_hostname, strlen (test_hostname)) != 0) ++ FAIL_EXIT1 ("sethostname: %m"); ++ ++ /* These environment variables affect resolv.conf parsing. */ ++ unsetenv ("LOCALDOMAIN"); ++ unsetenv ("RES_OPTIONS"); ++ ++ /* Ensure that the chroot setup worked. */ ++ { ++ struct support_capture_subprocess proc ++ = support_capture_subprocess (check_chroot_working, NULL); ++ support_capture_subprocess_check (&proc, "chroot", 0, sc_allow_none); ++ support_capture_subprocess_free (&proc); ++ } ++ ++ pid_t server = start_dummy_server (); ++ ++ for (size_t i = 0; test_cases[i].name != NULL; ++i) ++ { ++ if (test_verbose > 0) ++ printf ("info: running test: %s\n", test_cases[i].name); ++ TEST_VERIFY (test_cases[i].conf != NULL); ++ TEST_VERIFY (test_cases[i].expected != NULL); ++ ++ support_write_file_string (chroot_env->path_resolv_conf, ++ test_cases[i].conf); ++ ++ test_file_contents (&test_cases[i]); ++ ++ /* The expected output from the empty file test is used for ++ further tests. */ ++ if (test_cases[i].conf[0] == '\0') ++ { ++ if (test_verbose > 0) ++ printf ("info: special test: missing file\n"); ++ TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0); ++ test_file_contents (&test_cases[i]); ++ ++ if (test_verbose > 0) ++ printf ("info: special test: dangling symbolic link\n"); ++ TEST_VERIFY (symlink ("does-not-exist", chroot_env->path_resolv_conf) == 0); ++ test_file_contents (&test_cases[i]); ++ TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0); ++ ++ if (test_verbose > 0) ++ printf ("info: special test: unreadable file\n"); ++ support_write_file_string (chroot_env->path_resolv_conf, ""); ++ TEST_VERIFY (chmod (chroot_env->path_resolv_conf, 0) == 0); ++ test_file_contents (&test_cases[i]); ++ ++ /* Restore the empty file. */ ++ TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0); ++ support_write_file_string (chroot_env->path_resolv_conf, ""); ++ } ++ } ++ ++ /* The tests which do not follow a regular pattern. */ ++ for (unsigned int test_index = 0; ++ test_index < special_tests_count; ++test_index) ++ special_test (test_index); ++ ++ if (server > 0) ++ { ++ if (kill (server, SIGTERM) < 0) ++ FAIL_EXIT1 ("could not terminate server process: %m"); ++ xwaitpid (server, NULL, 0); ++ } ++ ++ support_chroot_free (chroot_env); ++ return 0; ++} ++ ++#define PREPARE prepare ++#include +diff --git a/resolv/tst-resolv-res_init-thread.c b/resolv/tst-resolv-res_init-thread.c +new file mode 100644 +index 0000000000000000..f47ac34f7fc7a6c8 +--- /dev/null ++++ b/resolv/tst-resolv-res_init-thread.c +@@ -0,0 +1,20 @@ ++/* Test parsing of /etc/resolv.conf, threading version. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_THREAD 1 ++#include "tst-resolv-res_init-skeleton.c" +diff --git a/resolv/tst-resolv-res_init.c b/resolv/tst-resolv-res_init.c +new file mode 100644 +index 0000000000000000..40c0154eca7363cb +--- /dev/null ++++ b/resolv/tst-resolv-res_init.c +@@ -0,0 +1,20 @@ ++/* Test parsing of /etc/resolv.conf, non-threading version. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define TEST_THREAD 0 ++#include "tst-resolv-res_init-skeleton.c" +diff --git a/resolv/tst-resolv-res_ninit.c b/resolv/tst-resolv-res_ninit.c +new file mode 100644 +index 0000000000000000..d08153fed78b5f03 +--- /dev/null ++++ b/resolv/tst-resolv-res_ninit.c +@@ -0,0 +1,74 @@ ++/* Test the creation of many struct __res_state objects. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Order the resolver states by their extended resolver state ++ index. */ ++static int ++sort_res_state (const void *a, const void *b) ++{ ++ res_state left = (res_state) a; ++ res_state right = (res_state) b; ++ return memcmp (&left->_u._ext.__glibc_extension_index, ++ &right->_u._ext.__glibc_extension_index, ++ sizeof (left->_u._ext.__glibc_extension_index)); ++} ++ ++static int ++do_test (void) ++{ ++ mtrace (); ++ ++ enum { count = 100 * 1000 }; ++ res_state array = calloc (count, sizeof (*array)); ++ const struct resolv_conf *conf = NULL; ++ for (size_t i = 0; i < count; ++i) ++ { ++ TEST_VERIFY (res_ninit (array + i) == 0); ++ TEST_VERIFY (array[i].nscount > 0); ++ struct resolv_context *ctx = __resolv_context_get_override (array + i); ++ TEST_VERIFY_EXIT (ctx != NULL); ++ TEST_VERIFY (ctx->resp == array + i); ++ if (i == 0) ++ { ++ conf = ctx->conf; ++ TEST_VERIFY (conf != NULL); ++ } ++ else ++ /* The underyling configuration should be identical across all ++ res_state opjects because resolv.conf did not change. */ ++ TEST_VERIFY (ctx->conf == conf); ++ } ++ qsort (array, count, sizeof (*array), sort_res_state); ++ for (size_t i = 1; i < count; ++i) ++ /* All extension indices should be different. */ ++ TEST_VERIFY (sort_res_state (array + i - 1, array + i) < 0); ++ for (size_t i = 0; i < count; ++i) ++ res_nclose (array + i); ++ free (array); ++ ++ TEST_VERIFY (res_init () == 0); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-rotate.c b/resolv/tst-resolv-rotate.c +new file mode 100644 +index 0000000000000000..d01b85b2fe82930b +--- /dev/null ++++ b/resolv/tst-resolv-rotate.c +@@ -0,0 +1,263 @@ ++/* Check that RES_ROTATE works with few nameserver entries (bug 13028). ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static volatile int drop_server = -1; ++static volatile unsigned int query_counts[resolv_max_test_servers]; ++ ++static const char address_ipv4[4] = {192, 0, 2, 1}; ++static const char address_ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ if (ctx->server_index == drop_server) ++ { ++ resolv_response_drop (b); ++ resolv_response_close (b); ++ return; ++ } ++ ++ bool force_tcp = strncmp (qname, "2.", 2) == 0; ++ struct resolv_response_flags flags = {.tc = force_tcp && !ctx->tcp}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ if (flags.tc) ++ return; ++ ++ TEST_VERIFY_EXIT (ctx->server_index < resolv_max_test_servers); ++ ++query_counts[ctx->server_index]; ++ ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char addr[sizeof (address_ipv4)]; ++ memcpy (addr, address_ipv4, sizeof (address_ipv4)); ++ addr[3] = 1 + ctx->tcp; ++ resolv_response_add_data (b, addr, sizeof (addr)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char addr[sizeof (address_ipv6)]; ++ memcpy (addr, address_ipv6, sizeof (address_ipv6)); ++ addr[15] = 1 + ctx->tcp; ++ resolv_response_add_data (b, addr, sizeof (addr)); ++ } ++ break; ++ case T_PTR: ++ if (force_tcp) ++ resolv_response_add_name (b, "2.host.example"); ++ else ++ resolv_response_add_name (b, "host.example"); ++ break; ++ default: ++ FAIL_EXIT1 ("unexpected QTYPE: %s/%u/%u", qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++} ++ ++static void ++check_forward_1 (const char *name, int family) ++{ ++ unsigned char lsb; ++ if (strncmp (name, "2.", 2) == 0) ++ lsb = 2; ++ else ++ lsb = 1; ++ ++ char expected_hostent_v4[200]; ++ snprintf (expected_hostent_v4, sizeof (expected_hostent_v4), ++ "name: %s\naddress: 192.0.2.%d\n", name, lsb); ++ char expected_hostent_v6[200]; ++ snprintf (expected_hostent_v6, sizeof (expected_hostent_v6), ++ "name: %s\naddress: 2001:db8::%d\n", name, lsb); ++ char expected_ai[200]; ++ ++ unsigned char address[16]; ++ size_t address_length; ++ ++ char *expected_hostent; ++ switch (family) ++ { ++ case AF_INET: ++ expected_hostent = expected_hostent_v4; ++ snprintf (expected_ai, sizeof (expected_ai), ++ "address: STREAM/TCP 192.0.2.%d 80\n", lsb); ++ TEST_VERIFY_EXIT (sizeof (address_ipv4) == sizeof (struct in_addr)); ++ memcpy (address, address_ipv4, sizeof (address_ipv4)); ++ address_length = sizeof (address_ipv4); ++ break; ++ case AF_INET6: ++ expected_hostent = expected_hostent_v6; ++ snprintf (expected_ai, sizeof (expected_ai), ++ "address: STREAM/TCP 2001:db8::%d 80\n", lsb); ++ TEST_VERIFY_EXIT (sizeof (address_ipv6) == sizeof (struct in6_addr)); ++ memcpy (address, address_ipv6, sizeof (address_ipv6)); ++ address_length = sizeof (address_ipv6); ++ break; ++ case AF_UNSPEC: ++ expected_hostent = NULL; ++ snprintf (expected_ai, sizeof (expected_ai), ++ "address: STREAM/TCP 192.0.2.%d 80\n" ++ "address: STREAM/TCP 2001:db8::%d 80\n", ++ lsb, lsb); ++ address_length = 0; ++ break; ++ default: ++ FAIL_EXIT1 ("unknown address family %d", family); ++ } ++ ++ ++ if (family == AF_INET) ++ { ++ struct hostent *e = gethostbyname (name); ++ check_hostent (name, e, expected_hostent_v4); ++ } ++ ++ if (family != AF_UNSPEC) ++ { ++ struct hostent *e = gethostbyname2 (name, family); ++ check_hostent (name, e, expected_hostent); ++ } ++ ++ if (address_length > 0) ++ { ++ address[address_length - 1] = lsb; ++ struct hostent *e = gethostbyaddr (address, address_length, family); ++ check_hostent (name, e, expected_hostent); ++ } ++ ++ struct addrinfo hints = ++ { ++ .ai_family = family, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo (name, "80", &hints, &ai); ++ check_addrinfo (name, ai, ret, expected_ai); ++ if (ret == 0) ++ { ++ for (struct addrinfo *p = ai; p != NULL; p = p->ai_next) ++ { ++ char host[200]; ++ ret = getnameinfo (p->ai_addr, p->ai_addrlen, ++ host, sizeof (host), ++ NULL, 0, /* service */ ++ 0); ++ if (ret != 0) ++ { ++ support_record_failure (); ++ printf ("error: getnameinfo: %d\n", ret); ++ } ++ else ++ { ++ if (lsb == 1) ++ TEST_VERIFY (strcmp (host, "host.example") == 0); ++ else ++ TEST_VERIFY (strcmp (host, "2.host.example") == 0); ++ } ++ } ++ freeaddrinfo (ai); ++ } ++} ++ ++static void ++check_forward (int family) ++{ ++ check_forward_1 ("host.example", family); ++ check_forward_1 ("2.host.example", family); ++} ++ ++static int ++do_test (void) ++{ ++ for (int force_tcp = 0; force_tcp < 2; ++force_tcp) ++ for (int nscount = 1; nscount <= 3; ++nscount) ++ for (int disable_server = -1; disable_server < nscount; ++disable_server) ++ for (drop_server = -1; drop_server < nscount; ++drop_server) ++ { ++ /* A disabled server will never receive queries and ++ therefore cannot drop them. */ ++ if (drop_server >= 0 && drop_server == disable_server) ++ continue; ++ /* No servers remaining to query, all queries are expected ++ to fail. */ ++ int broken_servers = (disable_server >= 0) + (drop_server >= 0); ++ if (nscount <= broken_servers) ++ continue; ++ ++ if (test_verbose > 0) ++ printf ("info: tcp=%d nscount=%d disable=%d drop=%d\n", ++ force_tcp, nscount, disable_server, drop_server); ++ struct resolv_redirect_config config = ++ { ++ .response_callback = response, ++ .nscount = nscount ++ }; ++ if (disable_server >= 0) ++ { ++ config.servers[disable_server].disable_udp = true; ++ config.servers[disable_server].disable_tcp = true; ++ } ++ ++ struct resolv_test *aux = resolv_test_start (config); ++ _res.options |= RES_ROTATE; ++ ++ /* Run a few queries to make sure that all of them ++ succeed. We always perform more than nscount queries, ++ so we cover all active servers due to RES_ROTATE. */ ++ for (size_t i = 0; i < resolv_max_test_servers; ++i) ++ query_counts[i] = 0; ++ check_forward (AF_INET); ++ check_forward (AF_INET6); ++ check_forward (AF_UNSPEC); ++ ++ for (int i = 0; i < nscount; ++i) ++ { ++ if (i != disable_server && i != drop_server ++ && query_counts[i] == 0) ++ { ++ support_record_failure (); ++ printf ("error: nscount=%d, but no query to server %d\n", ++ nscount, i); ++ } ++ } ++ ++ resolv_test_end (aux); ++ } ++ return 0; ++} ++ ++#define TIMEOUT 300 ++#include +diff --git a/resolv/tst-resolv-search.c b/resolv/tst-resolv-search.c +new file mode 100644 +index 0000000000000000..a5406b3b0ecb28c4 +--- /dev/null ++++ b/resolv/tst-resolv-search.c +@@ -0,0 +1,344 @@ ++/* Test search/default domain name behavior. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct item ++{ ++ const char *name; ++ int response; ++}; ++ ++const struct item items[] = ++ { ++ {"hostname.usersys.example.com", 1}, ++ {"hostname.corp.example.com", 1}, ++ {"hostname.example.com", 1}, ++ ++ {"mail.corp.example.com", 1}, ++ {"mail.example.com", 1}, ++ ++ {"file.corp.example.com", 2}, ++ {"file.corp", 1}, ++ {"file.example.com", 1}, ++ {"servfail-usersys.usersys.example.com", -ns_r_servfail}, ++ {"servfail-usersys.corp.example.com", 1}, ++ {"servfail-usersys.example.com", 1}, ++ {"servfail-corp.usersys.example.com", 1}, ++ {"servfail-corp.corp.example.com", -ns_r_servfail}, ++ {"servfail-corp.example.com", 1}, ++ {"www.example.com", 1}, ++ {"large.example.com", 200}, ++ ++ /* Test query amplification with a SERVFAIL response combined with ++ a large RRset. */ ++ {"large-servfail.usersys.example.com", -ns_r_servfail}, ++ {"large-servfail.example.com", 2000}, ++ {} ++ }; ++ ++enum ++ { ++ name_not_found = -1, ++ name_no_data = -2 ++ }; ++ ++static int ++find_name (const char *name) ++{ ++ for (int i = 0; items[i].name != NULL; ++i) ++ { ++ if (strcmp (name, items[i].name) == 0) ++ return i; ++ } ++ if (strcmp (name, "example.com") == 0 ++ || strcmp (name, "usersys.example.com") == 0 ++ || strcmp (name, "corp.example.com") == 0) ++ return name_no_data; ++ return name_not_found; ++} ++ ++static int rcode_override_server_index = -1; ++static int rcode_override; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ if (ctx->server_index == rcode_override_server_index) ++ { ++ struct resolv_response_flags flags = {.rcode = rcode_override}; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ return; ++ } ++ ++ int index = find_name (qname); ++ struct resolv_response_flags flags = {}; ++ if (index == name_not_found) ++ flags.rcode = ns_r_nxdomain; ++ else if (index >= 0 && items[index].response < 0) ++ flags.rcode = -items[index].response; ++ else if (index >= 0 && items[index].response > 5 && !ctx->tcp) ++ /* Force TCP if more than 5 addresses where requested. */ ++ flags.tc = true; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ if (flags.tc || index < 0 || items[index].response < 0) ++ return; ++ ++ resolv_response_section (b, ns_s_an); ++ ++ for (int i = 0; i < items[index].response; ++i) ++ { ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char addr[4] = {10, index, i >> 8, i}; ++ resolv_response_add_data (b, addr, sizeof (addr)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char addr[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, index + 1, (i + 1) >> 8, i + 1}; ++ resolv_response_add_data (b, addr, sizeof (addr)); ++ } ++ break; ++ default: ++ support_record_failure (); ++ printf ("error: unexpected QTYPE: %s/%u/%u\n", ++ qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++ } ++} ++ ++enum output_format ++ { ++ format_get, format_gai ++ }; ++ ++static void ++format_expected_1 (FILE *out, int family, enum output_format format, int index) ++{ ++ for (int i = 0; i < items[index].response; ++i) ++ { ++ char address[200]; ++ switch (family) ++ { ++ case AF_INET: ++ snprintf (address, sizeof (address), "10.%d.%d.%d", ++ index, (i >> 8) & 0xff, i & 0xff); ++ break; ++ case AF_INET6: ++ snprintf (address, sizeof (address), "2001:db8::%x:%x", ++ index + 1, i + 1); ++ break; ++ default: ++ FAIL_EXIT1 ("unreachable"); ++ } ++ ++ switch (format) ++ { ++ case format_get: ++ fprintf (out, "address: %s\n", address); ++ break; ++ case format_gai: ++ fprintf (out, "address: STREAM/TCP %s 80\n", address); ++ } ++ } ++} ++ ++static char * ++format_expected (const char *fqdn, int family, enum output_format format) ++{ ++ int index = find_name (fqdn); ++ TEST_VERIFY_EXIT (index >= 0); ++ struct xmemstream stream; ++ xopen_memstream (&stream); ++ ++ TEST_VERIFY_EXIT (items[index].response >= 0); ++ if (format == format_get) ++ fprintf (stream.out, "name: %s\n", items[index].name); ++ if (family == AF_INET || family == AF_UNSPEC) ++ format_expected_1 (stream.out, AF_INET, format, index); ++ if (family == AF_INET6 || family == AF_UNSPEC) ++ format_expected_1 (stream.out, AF_INET6, format, index); ++ ++ xfclose_memstream (&stream); ++ return stream.buffer; ++} ++ ++static void ++do_get (const char *name, const char *fqdn, int family) ++{ ++ char *expected = format_expected (fqdn, family, format_get); ++ if (family == AF_INET) ++ { ++ char *query = xasprintf ("gethostbyname (\"%s\")", name); ++ check_hostent (query, gethostbyname (name), expected); ++ free (query); ++ } ++ char *query = xasprintf ("gethostbyname2 (\"%s\", %d)", name, family); ++ check_hostent (query, gethostbyname2 (name, family), expected); ++ ++ /* Test res_search. */ ++ int qtype; ++ switch (family) ++ { ++ case AF_INET: ++ qtype = T_A; ++ break; ++ case AF_INET6: ++ qtype = T_AAAA; ++ break; ++ default: ++ qtype = -1; ++ } ++ if (qtype >= 0) ++ { ++ int sz = 512; ++ unsigned char *response = xmalloc (sz); ++ int ret = res_search (name, C_IN, qtype, response, sz); ++ TEST_VERIFY_EXIT (ret >= 0); ++ if (ret > sz) ++ { ++ /* Truncation. Retry with a larger buffer. */ ++ sz = 65535; ++ unsigned char *newptr = xrealloc (response, sz); ++ response = newptr; ++ ++ ret = res_search (name, C_IN, qtype, response, sz); ++ TEST_VERIFY_EXIT (ret >= 0); ++ TEST_VERIFY_EXIT (ret < sz); ++ } ++ check_dns_packet (query, response, ret, expected); ++ free (response); ++ } ++ ++ free (query); ++ free (expected); ++} ++ ++static void ++do_gai (const char *name, const char *fqdn, int family) ++{ ++ struct addrinfo hints = ++ { ++ .ai_family = family, ++ .ai_protocol = IPPROTO_TCP, ++ .ai_socktype = SOCK_STREAM ++ }; ++ struct addrinfo *ai; ++ char *query = xasprintf ("%s:80 [%d]", name, family); ++ int ret = getaddrinfo (name, "80", &hints, &ai); ++ char *expected = format_expected (fqdn, family, format_gai); ++ check_addrinfo (query, ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ free (expected); ++ free (query); ++} ++ ++static void ++do_both (const char *name, const char *fqdn) ++{ ++ do_get (name, fqdn, AF_INET); ++ do_get (name, fqdn, AF_INET6); ++ do_gai (name, fqdn, AF_INET); ++ do_gai (name, fqdn, AF_INET6); ++ do_gai (name, fqdn, AF_UNSPEC); ++} ++ ++static void ++do_test_all (bool unconnectable_server) ++{ ++ struct resolv_redirect_config config = ++ { ++ .response_callback = response, ++ .search = {"usersys.example.com", "corp.example.com", "example.com"}, ++ }; ++ struct resolv_test *obj = resolv_test_start (config); ++ ++ if (unconnectable_server) ++ { ++ /* 255.255.255.255 results in an immediate connect failure. The ++ next server will supply the answer instead. This is a ++ triggering condition for bug 19791. */ ++ _res.nsaddr_list[0].sin_addr.s_addr = -1; ++ _res.nsaddr_list[0].sin_port = htons (53); ++ } ++ ++ do_both ("file", "file.corp.example.com"); ++ do_both ("www", "www.example.com"); ++ do_both ("servfail-usersys", "servfail-usersys.corp.example.com"); ++ do_both ("servfail-corp", "servfail-corp.usersys.example.com"); ++ do_both ("large", "large.example.com"); ++ do_both ("large-servfail", "large-servfail.example.com"); ++ do_both ("file.corp", "file.corp"); ++ ++ /* Check that SERVFAIL and REFUSED responses do not alter the search ++ path resolution. */ ++ rcode_override_server_index = 0; ++ rcode_override = ns_r_servfail; ++ do_both ("hostname", "hostname.usersys.example.com"); ++ do_both ("large", "large.example.com"); ++ do_both ("large-servfail", "large-servfail.example.com"); ++ rcode_override = ns_r_refused; ++ do_both ("hostname", "hostname.usersys.example.com"); ++ do_both ("large", "large.example.com"); ++ do_both ("large-servfail", "large-servfail.example.com"); ++ /* Likewise, but with an NXDOMAIN for the first search path ++ entry. */ ++ rcode_override = ns_r_servfail; ++ do_both ("mail", "mail.corp.example.com"); ++ rcode_override = ns_r_refused; ++ do_both ("mail", "mail.corp.example.com"); ++ /* Likewise, but with ndots handling. */ ++ rcode_override = ns_r_servfail; ++ do_both ("file.corp", "file.corp"); ++ rcode_override = ns_r_refused; ++ do_both ("file.corp", "file.corp"); ++ ++ resolv_test_end (obj); ++} ++ ++static int ++do_test (void) ++{ ++ for (int unconnectable_server = 0; unconnectable_server < 2; ++ ++unconnectable_server) ++ do_test_all (unconnectable_server); ++ return 0; ++} ++ ++#include +diff --git a/resolv/tst-resolv-threads.c b/resolv/tst-resolv-threads.c +new file mode 100644 +index 0000000000000000..7be417b056f720d8 +--- /dev/null ++++ b/resolv/tst-resolv-threads.c +@@ -0,0 +1,484 @@ ++/* Test basic nss_dns functionality with multiple threads. ++ Copyright (C) 2016-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Unlike tst-resolv-basic, this test does not overwrite the _res ++ structure and relies on namespaces to achieve the redirection to ++ the test servers with a custom /etc/resolv.conf file. */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Each client thread sends this many queries. */ ++enum { queries_per_thread = 500 }; ++ ++/* Return a small positive number identifying this thread. */ ++static int ++get_thread_number (void) ++{ ++ static int __thread local; ++ if (local != 0) ++ return local; ++ static int global = 1; ++ local = __atomic_fetch_add (&global, 1, __ATOMIC_RELAXED); ++ return local; ++} ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ TEST_VERIFY_EXIT (qname != NULL); ++ ++ int counter = 0; ++ int thread = 0; ++ int dummy = 0; ++ TEST_VERIFY (sscanf (qname, "counter%d.thread%d.example.com%n", ++ &counter, &thread, &dummy) == 2); ++ TEST_VERIFY (dummy > 0); ++ ++ struct resolv_response_flags flags = { 0 }; ++ resolv_response_init (b, flags); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {10, 0, counter, thread}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, ++ counter, 0, thread, 0, 0}; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ support_record_failure (); ++ printf ("error: unexpected QTYPE: %s/%u/%u\n", ++ qname, qclass, qtype); ++ } ++ resolv_response_close_record (b); ++} ++ ++/* Check that the resolver configuration for this thread has an ++ extended resolver configuration. */ ++static void ++check_have_conf (void) ++{ ++ struct resolv_context *ctx = __resolv_context_get (); ++ TEST_VERIFY_EXIT (ctx != NULL); ++ TEST_VERIFY (ctx->conf != NULL); ++ __resolv_context_put (ctx); ++} ++ ++/* Verify that E matches the expected response for FAMILY and ++ COUNTER. */ ++static void ++check_hostent (const char *caller, const char *function, const char *qname, ++ int ret, struct hostent *e, int family, int counter) ++{ ++ if (ret != 0) ++ { ++ errno = ret; ++ support_record_failure (); ++ printf ("error: %s: %s for %s failed: %m\n", caller, function, qname); ++ return; ++ } ++ ++ TEST_VERIFY_EXIT (e != NULL); ++ TEST_VERIFY (strcmp (qname, e->h_name) == 0); ++ TEST_VERIFY (e->h_addrtype == family); ++ TEST_VERIFY_EXIT (e->h_addr_list[0] != NULL); ++ TEST_VERIFY (e->h_addr_list[1] == NULL); ++ switch (family) ++ { ++ case AF_INET: ++ { ++ char addr[4] = {10, 0, counter, get_thread_number ()}; ++ TEST_VERIFY (e->h_length == sizeof (addr)); ++ TEST_VERIFY (memcmp (e->h_addr_list[0], addr, sizeof (addr)) == 0); ++ } ++ break; ++ case AF_INET6: ++ { ++ char addr[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, ++ 0, counter, 0, get_thread_number (), 0, 0}; ++ TEST_VERIFY (e->h_length == sizeof (addr)); ++ TEST_VERIFY (memcmp (e->h_addr_list[0], addr, sizeof (addr)) == 0); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("%s: invalid address family %d", caller, family); ++ } ++ check_have_conf (); ++} ++ ++/* Check a getaddrinfo result. */ ++static void ++check_addrinfo (const char *caller, const char *qname, ++ int ret, struct addrinfo *ai, int family, int counter) ++{ ++ if (ret != 0) ++ { ++ support_record_failure (); ++ printf ("error: %s: getaddrinfo for %s failed: %s\n", ++ caller, qname, gai_strerror (ret)); ++ return; ++ } ++ ++ TEST_VERIFY_EXIT (ai != NULL); ++ ++ /* Check that available data matches the requirements. */ ++ bool have_ipv4 = false; ++ bool have_ipv6 = false; ++ for (struct addrinfo *p = ai; p != NULL; p = p->ai_next) ++ { ++ TEST_VERIFY (p->ai_socktype == SOCK_STREAM); ++ TEST_VERIFY (p->ai_protocol == IPPROTO_TCP); ++ TEST_VERIFY_EXIT (p->ai_addr != NULL); ++ TEST_VERIFY (p->ai_addr->sa_family == p->ai_family); ++ ++ switch (p->ai_family) ++ { ++ case AF_INET: ++ { ++ TEST_VERIFY (!have_ipv4); ++ have_ipv4 = true; ++ struct sockaddr_in *sa = (struct sockaddr_in *) p->ai_addr; ++ TEST_VERIFY (p->ai_addrlen == sizeof (*sa)); ++ char addr[4] = {10, 0, counter, get_thread_number ()}; ++ TEST_VERIFY (memcmp (&sa->sin_addr, addr, sizeof (addr)) == 0); ++ TEST_VERIFY (ntohs (sa->sin_port) == 80); ++ } ++ break; ++ case AF_INET6: ++ { ++ TEST_VERIFY (!have_ipv6); ++ have_ipv6 = true; ++ struct sockaddr_in6 *sa = (struct sockaddr_in6 *) p->ai_addr; ++ TEST_VERIFY (p->ai_addrlen == sizeof (*sa)); ++ char addr[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, ++ 0, counter, 0, get_thread_number (), 0, 0}; ++ TEST_VERIFY (memcmp (&sa->sin6_addr, addr, sizeof (addr)) == 0); ++ TEST_VERIFY (ntohs (sa->sin6_port) == 80); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("%s: invalid address family %d", caller, family); ++ } ++ } ++ ++ switch (family) ++ { ++ case AF_INET: ++ TEST_VERIFY (have_ipv4); ++ TEST_VERIFY (!have_ipv6); ++ break; ++ case AF_INET6: ++ TEST_VERIFY (!have_ipv4); ++ TEST_VERIFY (have_ipv6); ++ break; ++ case AF_UNSPEC: ++ TEST_VERIFY (have_ipv4); ++ TEST_VERIFY (have_ipv6); ++ break; ++ default: ++ FAIL_EXIT1 ("%s: invalid address family %d", caller, family); ++ } ++ ++ check_have_conf (); ++} ++ ++/* This barrier ensures that all test threads begin their work ++ simultaneously. */ ++static pthread_barrier_t barrier; ++ ++/* Test gethostbyname2_r (if do_2 is false) or gethostbyname2_r with ++ AF_INET (if do_2 is true). */ ++static void * ++byname (bool do_2) ++{ ++ int this_thread = get_thread_number (); ++ xpthread_barrier_wait (&barrier); ++ for (int i = 0; i < queries_per_thread; ++i) ++ { ++ char qname[100]; ++ snprintf (qname, sizeof (qname), "counter%d.thread%d.example.com", ++ i, this_thread); ++ struct hostent storage; ++ char buf[1000]; ++ struct hostent *e = NULL; ++ int herrno; ++ int ret; ++ if (do_2) ++ ret = gethostbyname_r (qname, &storage, buf, sizeof (buf), ++ &e, &herrno); ++ else ++ ret = gethostbyname2_r (qname, AF_INET, &storage, buf, sizeof (buf), ++ &e, &herrno); ++ check_hostent (__func__, do_2 ? "gethostbyname2_r" : "gethostbyname_r", ++ qname, ret, e, AF_INET, i); ++ } ++ check_have_conf (); ++ return NULL; ++} ++ ++/* Test gethostbyname_r. */ ++static void * ++thread_byname (void *closure) ++{ ++ return byname (false); ++} ++ ++/* Test gethostbyname2_r with AF_INET. */ ++static void * ++thread_byname2 (void *closure) ++{ ++ return byname (true); ++} ++ ++/* Call gethostbyname_r with RES_USE_INET6 (if do_2 is false), or ++ gethostbyname_r with AF_INET6 (if do_2 is true). */ ++static void * ++byname_inet6 (bool do_2) ++{ ++ int this_thread = get_thread_number (); ++ xpthread_barrier_wait (&barrier); ++ if (!do_2) ++ { ++ res_init (); ++ _res.options |= DEPRECATED_RES_USE_INET6; ++ TEST_VERIFY (strcmp (_res.defdname, "example.com") == 0); ++ } ++ for (int i = 0; i < queries_per_thread; ++i) ++ { ++ char qname[100]; ++ snprintf (qname, sizeof (qname), "counter%d.thread%d.example.com", ++ i, this_thread); ++ struct hostent storage; ++ char buf[1000]; ++ struct hostent *e = NULL; ++ int herrno; ++ int ret; ++ if (do_2) ++ ret = gethostbyname2_r (qname, AF_INET6, &storage, buf, sizeof (buf), ++ &e, &herrno); ++ else ++ ret = gethostbyname_r (qname, &storage, buf, sizeof (buf), ++ &e, &herrno); ++ check_hostent (__func__, ++ do_2 ? "gethostbyname2_r" : "gethostbyname_r", ++ qname, ret, e, AF_INET6, i); ++ } ++ return NULL; ++} ++ ++/* Test gethostbyname_r with AF_INET6. */ ++static void * ++thread_byname_inet6 (void *closure) ++{ ++ return byname_inet6 (false); ++} ++ ++/* Test gethostbyname2_r with AF_INET6. */ ++static void * ++thread_byname2_af_inet6 (void *closure) ++{ ++ return byname_inet6 (true); ++} ++ ++/* Run getaddrinfo tests for FAMILY. */ ++static void * ++gai (int family, bool do_inet6) ++{ ++ int this_thread = get_thread_number (); ++ xpthread_barrier_wait (&barrier); ++ if (do_inet6) ++ { ++ res_init (); ++ _res.options |= DEPRECATED_RES_USE_INET6; ++ check_have_conf (); ++ } ++ for (int i = 0; i < queries_per_thread; ++i) ++ { ++ char qname[100]; ++ snprintf (qname, sizeof (qname), "counter%d.thread%d.example.com", ++ i, this_thread); ++ struct addrinfo hints = ++ { ++ .ai_family = family, ++ .ai_socktype = SOCK_STREAM, ++ .ai_protocol = IPPROTO_TCP, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo (qname, "80", &hints, &ai); ++ check_addrinfo (__func__, qname, ret, ai, family, i); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++ return NULL; ++} ++ ++/* Test getaddrinfo with AF_INET. */ ++static void * ++thread_gai_inet (void *closure) ++{ ++ return gai (AF_INET, false); ++} ++ ++/* Test getaddrinfo with AF_INET6. */ ++static void * ++thread_gai_inet6 (void *closure) ++{ ++ return gai (AF_INET6, false); ++} ++ ++/* Test getaddrinfo with AF_UNSPEC. */ ++static void * ++thread_gai_unspec (void *closure) ++{ ++ return gai (AF_UNSPEC, false); ++} ++ ++/* Test getaddrinfo with AF_INET. */ ++static void * ++thread_gai_inet_inet6 (void *closure) ++{ ++ return gai (AF_INET, true); ++} ++ ++/* Test getaddrinfo with AF_INET6. */ ++static void * ++thread_gai_inet6_inet6 (void *closure) ++{ ++ return gai (AF_INET6, true); ++} ++ ++/* Test getaddrinfo with AF_UNSPEC. */ ++static void * ++thread_gai_unspec_inet6 (void *closure) ++{ ++ return gai (AF_UNSPEC, true); ++} ++ ++/* Description of the chroot environment used to run the tests. */ ++static struct support_chroot *chroot_env; ++ ++/* Set up the chroot environment. */ ++static void ++prepare (int argc, char **argv) ++{ ++ chroot_env = support_chroot_create ++ ((struct support_chroot_configuration) ++ { ++ .resolv_conf = ++ "search example.com\n" ++ "nameserver 127.0.0.1\n" ++ "nameserver 127.0.0.2\n" ++ "nameserver 127.0.0.3\n", ++ }); ++} ++ ++static int ++do_test (void) ++{ ++ support_become_root (); ++ if (!support_enter_network_namespace ()) ++ return EXIT_UNSUPPORTED; ++ if (!support_can_chroot ()) ++ return EXIT_UNSUPPORTED; ++ ++ /* Load the shared object outside of the chroot. */ ++ TEST_VERIFY (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) != NULL); ++ ++ xchroot (chroot_env->path_chroot); ++ TEST_VERIFY_EXIT (chdir ("/") == 0); ++ ++ struct sockaddr_in server_address = ++ { ++ .sin_family = AF_INET, ++ .sin_addr = { .s_addr = htonl (INADDR_LOOPBACK) }, ++ .sin_port = htons (53) ++ }; ++ const struct sockaddr *server_addresses[1] = ++ { (const struct sockaddr *) &server_address }; ++ ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ .nscount = 1, ++ .disable_redirect = true, ++ .server_address_overrides = server_addresses, ++ }); ++ ++ enum { thread_count = 10 }; ++ xpthread_barrier_init (&barrier, NULL, thread_count + 1); ++ pthread_t threads[thread_count]; ++ typedef void *(*thread_func) (void *); ++ thread_func thread_funcs[thread_count] = ++ { ++ thread_byname, ++ thread_byname2, ++ thread_byname_inet6, ++ thread_byname2_af_inet6, ++ thread_gai_inet, ++ thread_gai_inet6, ++ thread_gai_unspec, ++ thread_gai_inet_inet6, ++ thread_gai_inet6_inet6, ++ thread_gai_unspec_inet6, ++ }; ++ for (int i = 0; i < thread_count; ++i) ++ threads[i] = xpthread_create (NULL, thread_funcs[i], NULL); ++ xpthread_barrier_wait (&barrier); /* Start the test threads. */ ++ for (int i = 0; i < thread_count; ++i) ++ xpthread_join (threads[i]); ++ ++ resolv_test_end (aux); ++ support_chroot_free (chroot_env); ++ ++ return 0; ++} ++ ++#define PREPARE prepare ++#include +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c +index 7a6cf71c170ec42f..2c4b6d6793a4c3a9 100644 +--- a/sysdeps/posix/getaddrinfo.c ++++ b/sysdeps/posix/getaddrinfo.c +@@ -1,3 +1,21 @@ ++/* Host and service name lookups using Name Service Switch modules. ++ Copyright (C) 1996-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ + /* The Inner Net License, Version 2.00 + + The author(s) grant permission for redistribution and use in source and +@@ -42,11 +60,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include ++#include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -57,11 +78,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #include + #include + #include +-#include ++#include + #include + #include + #include +-#include ++#include ++#include + + #ifdef HAVE_LIBIDN + extern int __idna_to_ascii_lz (const char *input, char **output, int flags); +@@ -70,13 +92,6 @@ extern int __idna_to_unicode_lzlz (const char *input, char **output, + # include + #endif + +-#define GAIH_OKIFUNSPEC 0x0100 +-#define GAIH_EAI ~(GAIH_OKIFUNSPEC) +- +-#ifndef UNIX_PATH_MAX +-# define UNIX_PATH_MAX 108 +-#endif +- + struct gaih_service + { + const char *name; +@@ -126,14 +141,6 @@ static const struct gaih_typeproto gaih_inet_typeproto[] = + { 0, 0, 0, false, "" } + }; + +-struct gaih +- { +- int family; +- int (*gaih)(const char *name, const struct gaih_service *service, +- const struct addrinfo *req, struct addrinfo **pai, +- unsigned int *naddrs); +- }; +- + static const struct addrinfo default_hints = + { + .ai_flags = AI_DEFAULT, +@@ -149,26 +156,26 @@ static const struct addrinfo default_hints = + + static int + gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, +- const struct addrinfo *req, struct gaih_servtuple *st) ++ const struct addrinfo *req, struct gaih_servtuple *st, ++ struct scratch_buffer *tmpbuf) + { + struct servent *s; +- size_t tmpbuflen = 1024; + struct servent ts; +- char *tmpbuf; + int r; + + do + { +- tmpbuf = __alloca (tmpbuflen); +- +- r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen, +- &s); ++ r = __getservbyname_r (servicename, tp->name, &ts, ++ tmpbuf->data, tmpbuf->length, &s); + if (r != 0 || s == NULL) + { + if (r == ERANGE) +- tmpbuflen *= 2; ++ { ++ if (!scratch_buffer_grow (tmpbuf)) ++ return -EAI_MEMORY; ++ } + else +- return GAIH_OKIFUNSPEC | -EAI_SERVICE; ++ return -EAI_SERVICE; + } + } + while (r); +@@ -182,87 +189,114 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, + return 0; + } + ++/* Convert struct hostent to a list of struct gaih_addrtuple objects. ++ h_name is not copied, and the struct hostent object must not be ++ deallocated prematurely. *RESULT must be NULL or a pointer to a ++ linked-list. The new addresses are appended at the end. */ ++static bool ++convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, ++ int family, ++ struct hostent *h, ++ struct gaih_addrtuple **result) ++{ ++ while (*result) ++ result = &(*result)->next; ++ ++ /* Count the number of addresses in h->h_addr_list. */ ++ size_t count = 0; ++ for (char **p = h->h_addr_list; *p != NULL; ++p) ++ ++count; ++ ++ /* Report no data if no addresses are available, or if the incoming ++ address size is larger than what we can store. */ ++ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr)) ++ return true; ++ ++ struct gaih_addrtuple *array = calloc (count, sizeof (*array)); ++ if (array == NULL) ++ return false; ++ ++ for (size_t i = 0; i < count; ++i) ++ { ++ if (family == AF_INET && req->ai_family == AF_INET6) ++ { ++ /* Perform address mapping. */ ++ array[i].family = AF_INET6; ++ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t)); ++ array[i].addr[2] = htonl (0xffff); ++ } ++ else ++ { ++ array[i].family = family; ++ memcpy (array[i].addr, h->h_addr_list[i], h->h_length); ++ } ++ array[i].next = array + i + 1; ++ } ++ array[0].name = h->h_name; ++ array[count - 1].next = NULL; ++ ++ *result = array; ++ return true; ++} ++ + #define gethosts(_family, _type) \ + { \ +- int i; \ +- int herrno; \ + struct hostent th; \ +- struct hostent *h; \ + char *localcanon = NULL; \ + no_data = 0; \ +- while (1) { \ +- rc = 0; \ +- status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \ +- &rc, &herrno, NULL, &localcanon)); \ +- if (rc != ERANGE || herrno != NETDB_INTERNAL) \ +- break; \ +- if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \ +- tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \ +- alloca_used); \ +- else \ +- { \ +- char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \ +- 2 * tmpbuflen); \ +- if (newp == NULL) \ +- { \ +- result = -EAI_MEMORY; \ +- goto free_and_return; \ +- } \ +- tmpbuf = newp; \ +- malloc_tmpbuf = true; \ +- tmpbuflen = 2 * tmpbuflen; \ +- } \ +- } \ +- if (status == NSS_STATUS_SUCCESS && rc == 0) \ +- h = &th; \ +- else \ +- h = NULL; \ +- if (rc != 0) \ ++ while (1) \ + { \ +- if (herrno == NETDB_INTERNAL) \ ++ status = DL_CALL_FCT (fct, (name, _family, &th, \ ++ tmpbuf->data, tmpbuf->length, \ ++ &errno, &h_errno, NULL, &localcanon)); \ ++ if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \ ++ || errno != ERANGE) \ ++ break; \ ++ if (!scratch_buffer_grow (tmpbuf)) \ + { \ +- __set_h_errno (herrno); \ +- _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; \ ++ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \ ++ __resolv_context_put (res_ctx); \ ++ result = -EAI_MEMORY; \ ++ goto free_and_return; \ ++ } \ ++ } \ ++ if (status == NSS_STATUS_NOTFOUND \ ++ || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \ ++ { \ ++ if (h_errno == NETDB_INTERNAL) \ ++ { \ ++ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \ ++ __resolv_context_put (res_ctx); \ + result = -EAI_SYSTEM; \ + goto free_and_return; \ + } \ +- if (herrno == TRY_AGAIN) \ ++ if (h_errno == TRY_AGAIN) \ + no_data = EAI_AGAIN; \ + else \ +- no_data = herrno == NO_DATA; \ ++ no_data = h_errno == NO_DATA; \ + } \ +- else if (h != NULL) \ ++ else if (status == NSS_STATUS_SUCCESS) \ + { \ +- for (i = 0; h->h_addr_list[i]; i++) \ ++ if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \ + { \ +- if (*pat == NULL) \ +- { \ +- *pat = __alloca (sizeof (struct gaih_addrtuple)); \ +- (*pat)->scopeid = 0; \ +- } \ +- uint32_t *addr = (*pat)->addr; \ +- (*pat)->next = NULL; \ +- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \ +- if (_family == AF_INET && req->ai_family == AF_INET6) \ +- { \ +- (*pat)->family = AF_INET6; \ +- addr[3] = *(uint32_t *) h->h_addr_list[i]; \ +- addr[2] = htonl (0xffff); \ +- addr[1] = 0; \ +- addr[0] = 0; \ +- } \ +- else \ ++ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \ ++ __resolv_context_put (res_ctx); \ ++ result = -EAI_SYSTEM; \ ++ goto free_and_return; \ ++ } \ ++ *pat = addrmem; \ ++ \ ++ if (localcanon != NULL && canon == NULL) \ ++ { \ ++ canonbuf = __strdup (localcanon); \ ++ if (canonbuf == NULL) \ + { \ +- (*pat)->family = _family; \ +- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \ ++ result = -EAI_SYSTEM; \ ++ goto free_and_return; \ + } \ +- pat = &((*pat)->next); \ ++ canon = canonbuf; \ + } \ +- \ +- if (localcanon != NULL && canon == NULL) \ +- canon = strdupa (localcanon); \ +- \ +- if (_family == AF_INET6 && i > 0) \ ++ if (_family == AF_INET6 && *pat != NULL) \ + got_ipv6 = true; \ + } \ + } +@@ -281,20 +315,44 @@ typedef enum nss_status (*nss_getcanonname_r) + int *errnop, int *h_errnop); + extern service_user *__nss_hosts_database attribute_hidden; + ++/* This function is called if a canonical name is requested, but if ++ the service function did not provide it. It tries to obtain the ++ name using getcanonname_r from the same service NIP. If the name ++ cannot be canonicalized, return a copy of NAME. Return NULL on ++ memory allocation failure. The returned string is allocated on the ++ heap; the caller has to free it. */ ++static char * ++getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name) ++{ ++ nss_getcanonname_r cfct = __nss_lookup_function (nip, "getcanonname_r"); ++ char *s = (char *) name; ++ if (cfct != NULL) ++ { ++ char buf[256]; ++ if (DL_CALL_FCT (cfct, (at->name ?: name, buf, sizeof (buf), ++ &s, &errno, &h_errno)) != NSS_STATUS_SUCCESS) ++ /* If the canonical name cannot be determined, use the passed ++ string. */ ++ s = (char *) name; ++ } ++ return __strdup (name); ++} + + static int + gaih_inet (const char *name, const struct gaih_service *service, + const struct addrinfo *req, struct addrinfo **pai, +- unsigned int *naddrs) ++ unsigned int *naddrs, struct scratch_buffer *tmpbuf) + { + const struct gaih_typeproto *tp = gaih_inet_typeproto; + struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv; + struct gaih_addrtuple *at = NULL; +- int rc; + bool got_ipv6 = false; + const char *canon = NULL; + const char *orig_name = name; +- size_t alloca_used = 0; ++ ++ /* Reserve stack memory for the scratch buffer in the getaddrinfo ++ function. */ ++ size_t alloca_used = sizeof (struct scratch_buffer); + + if (req->ai_protocol || req->ai_socktype) + { +@@ -310,9 +368,9 @@ gaih_inet (const char *name, const struct gaih_service *service, + if (! tp->name[0]) + { + if (req->ai_socktype) +- return GAIH_OKIFUNSPEC | -EAI_SOCKTYPE; ++ return -EAI_SOCKTYPE; + else +- return GAIH_OKIFUNSPEC | -EAI_SERVICE; ++ return -EAI_SERVICE; + } + } + +@@ -320,7 +378,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + if (service != NULL) + { + if ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0) +- return GAIH_OKIFUNSPEC | -EAI_SERVICE; ++ return -EAI_SERVICE; + + if (service->num < 0) + { +@@ -329,7 +387,8 @@ gaih_inet (const char *name, const struct gaih_service *service, + st = (struct gaih_servtuple *) + alloca_account (sizeof (struct gaih_servtuple), alloca_used); + +- if ((rc = gaih_inet_serv (service->name, tp, req, st))) ++ int rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf); ++ if (__glibc_unlikely (rc != 0)) + return rc; + } + else +@@ -354,18 +413,15 @@ gaih_inet (const char *name, const struct gaih_service *service, + alloca_account (sizeof (struct gaih_servtuple), + alloca_used); + +- if ((rc = gaih_inet_serv (service->name, tp, req, newp))) +- { +- if (rc & GAIH_OKIFUNSPEC) +- continue; +- return rc; +- } ++ if (gaih_inet_serv (service->name, ++ tp, req, newp, tmpbuf) != 0) ++ continue; + + *pst = newp; + pst = &(newp->next); + } + if (st == (struct gaih_servtuple *) &nullserv) +- return GAIH_OKIFUNSPEC | -EAI_SERVICE; ++ return -EAI_SERVICE; + } + } + else +@@ -411,13 +467,10 @@ gaih_inet (const char *name, const struct gaih_service *service, + } + + bool malloc_name = false; +- bool malloc_addrmem = false; + struct gaih_addrtuple *addrmem = NULL; +- bool malloc_canonbuf = false; + char *canonbuf = NULL; +- bool malloc_tmpbuf = false; +- char *tmpbuf = NULL; + int result = 0; ++ + if (name != NULL) + { + at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used); +@@ -435,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + idn_flags |= IDNA_USE_STD3_ASCII_RULES; + + char *p = NULL; +- rc = __idna_to_ascii_lz (name, &p, idn_flags); ++ int rc = __idna_to_ascii_lz (name, &p, idn_flags); + if (rc != IDNA_SUCCESS) + { + /* No need to jump to free_and_return here. */ +@@ -480,46 +533,11 @@ gaih_inet (const char *name, const struct gaih_service *service, + { + char *scope_delim = strchr (name, SCOPE_DELIMITER); + int e; +- +- { +- bool malloc_namebuf = false; +- char *namebuf = (char *) name; +- +- if (__builtin_expect (scope_delim != NULL, 0)) +- { +- if (malloc_name) +- *scope_delim = '\0'; +- else +- { +- if (__libc_use_alloca (alloca_used +- + scope_delim - name + 1)) +- { +- namebuf = alloca_account (scope_delim - name + 1, +- alloca_used); +- *((char *) __mempcpy (namebuf, name, +- scope_delim - name)) = '\0'; +- } +- else +- { +- namebuf = strndup (name, scope_delim - name); +- if (namebuf == NULL) +- { +- assert (!malloc_name); +- return -EAI_MEMORY; +- } +- malloc_namebuf = true; +- } +- } +- } +- +- e = inet_pton (AF_INET6, namebuf, at->addr); +- +- if (malloc_namebuf) +- free (namebuf); +- else if (scope_delim != NULL && malloc_name) +- /* Undo what we did above. */ +- *scope_delim = SCOPE_DELIMITER; +- } ++ if (scope_delim == NULL) ++ e = inet_pton (AF_INET6, name, at->addr); ++ else ++ e = __inet_pton_length (AF_INET6, name, scope_delim - name, ++ at->addr); + if (e > 0) + { + if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6) +@@ -536,31 +554,13 @@ gaih_inet (const char *name, const struct gaih_service *service, + goto free_and_return; + } + +- if (scope_delim != NULL) ++ if (scope_delim != NULL ++ && __inet6_scopeid_pton ((struct in6_addr *) at->addr, ++ scope_delim + 1, ++ &at->scopeid) != 0) + { +- int try_numericscope = 0; +- if (IN6_IS_ADDR_LINKLOCAL (at->addr) +- || IN6_IS_ADDR_MC_LINKLOCAL (at->addr)) +- { +- at->scopeid = if_nametoindex (scope_delim + 1); +- if (at->scopeid == 0) +- try_numericscope = 1; +- } +- else +- try_numericscope = 1; +- +- if (try_numericscope != 0) +- { +- char *end; +- assert (sizeof (uint32_t) <= sizeof (unsigned long)); +- at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end, +- 10); +- if (*end != '\0') +- { +- result = GAIH_OKIFUNSPEC | -EAI_NONAME; +- goto free_and_return; +- } +- } ++ result = -EAI_NONAME; ++ goto free_and_return; + } + + if (req->ai_flags & AI_CANONNAME) +@@ -573,51 +573,34 @@ gaih_inet (const char *name, const struct gaih_service *service, + struct gaih_addrtuple **pat = &at; + int no_data = 0; + int no_inet6_data = 0; +- service_user *nip = NULL; ++ service_user *nip; + enum nss_status inet6_status = NSS_STATUS_UNAVAIL; + enum nss_status status = NSS_STATUS_UNAVAIL; + int no_more; +- int old_res_options; ++ struct resolv_context *res_ctx = NULL; ++ bool res_enable_inet6 = false; + +- /* If we do not have to look for IPv6 addresses, use +- the simple, old functions, which do not support ++ /* If we do not have to look for IPv6 addresses or the canonical ++ name, use the simple, old functions, which do not support + IPv6 scope ids, nor retrieving the canonical name. */ +- if (req->ai_family == AF_INET && (req->ai_flags & AI_CANONNAME) == 0) ++ if (req->ai_family == AF_INET ++ && (req->ai_flags & AI_CANONNAME) == 0) + { +- /* Allocate additional room for struct host_data. */ +- size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*) +- + 16 * sizeof(char)); +- assert (tmpbuf == NULL); +- tmpbuf = alloca_account (tmpbuflen, alloca_used); + int rc; + struct hostent th; + struct hostent *h; +- int herrno; + + while (1) + { +- rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf, +- tmpbuflen, &h, &herrno); +- if (rc != ERANGE || herrno != NETDB_INTERNAL) ++ rc = __gethostbyname2_r (name, AF_INET, &th, ++ tmpbuf->data, tmpbuf->length, ++ &h, &h_errno); ++ if (rc != ERANGE || h_errno != NETDB_INTERNAL) + break; +- +- if (!malloc_tmpbuf +- && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) +- tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, +- 2 * tmpbuflen, +- alloca_used); +- else ++ if (!scratch_buffer_grow (tmpbuf)) + { +- char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, +- 2 * tmpbuflen); +- if (newp == NULL) +- { +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- tmpbuf = newp; +- malloc_tmpbuf = true; +- tmpbuflen = 2 * tmpbuflen; ++ result = -EAI_MEMORY; ++ goto free_and_return; + } + } + +@@ -625,59 +608,34 @@ gaih_inet (const char *name, const struct gaih_service *service, + { + if (h != NULL) + { +- int i; +- /* We found data, count the number of addresses. */ +- for (i = 0; h->h_addr_list[i]; ++i) +- ; +- if (i > 0 && *pat != NULL) +- --i; +- +- if (__libc_use_alloca (alloca_used +- + i * sizeof (struct gaih_addrtuple))) +- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple), +- alloca_used); +- else +- { +- addrmem = malloc (i +- * sizeof (struct gaih_addrtuple)); +- if (addrmem == NULL) +- { +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- malloc_addrmem = true; +- } +- +- /* Now convert it into the list. */ +- struct gaih_addrtuple *addrfree = addrmem; +- for (i = 0; h->h_addr_list[i]; ++i) ++ /* We found data, convert it. */ ++ if (!convert_hostent_to_gaih_addrtuple ++ (req, AF_INET, h, &addrmem)) + { +- if (*pat == NULL) +- { +- *pat = addrfree++; +- (*pat)->scopeid = 0; +- } +- (*pat)->next = NULL; +- (*pat)->family = AF_INET; +- memcpy ((*pat)->addr, h->h_addr_list[i], +- h->h_length); +- pat = &((*pat)->next); ++ result = -EAI_MEMORY; ++ goto free_and_return; + } ++ *pat = addrmem; ++ } ++ else ++ { ++ if (h_errno == NO_DATA) ++ result = -EAI_NODATA; ++ else ++ result = -EAI_NONAME; ++ goto free_and_return; + } + } + else + { +- if (herrno == NETDB_INTERNAL) +- { +- __set_h_errno (herrno); +- result = -EAI_SYSTEM; +- } +- else if (herrno == TRY_AGAIN) ++ if (h_errno == NETDB_INTERNAL) ++ result = -EAI_SYSTEM; ++ else if (h_errno == TRY_AGAIN) + result = -EAI_AGAIN; + else + /* We made requests but they turned out no data. + The name is known, though. */ +- result = GAIH_OKIFUNSPEC | -EAI_NODATA; ++ result = -EAI_NODATA; + + goto free_and_return; + } +@@ -695,29 +653,18 @@ gaih_inet (const char *name, const struct gaih_service *service, + { + /* Try to use nscd. */ + struct nscd_ai_result *air = NULL; +- int herrno; +- int err = __nscd_getai (name, &air, &herrno); ++ int err = __nscd_getai (name, &air, &h_errno); + if (air != NULL) + { + /* Transform into gaih_addrtuple list. */ + bool added_canon = (req->ai_flags & AI_CANONNAME) == 0; + char *addrs = air->addrs; + +- if (__libc_use_alloca (alloca_used +- + air->naddrs * sizeof (struct gaih_addrtuple))) +- addrmem = alloca_account (air->naddrs +- * sizeof (struct gaih_addrtuple), +- alloca_used); +- else ++ addrmem = calloc (air->naddrs, sizeof (*addrmem)); ++ if (addrmem == NULL) + { +- addrmem = malloc (air->naddrs +- * sizeof (struct gaih_addrtuple)); +- if (addrmem == NULL) +- { +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- malloc_addrmem = true; ++ result = -EAI_MEMORY; ++ goto free_and_return; + } + + struct gaih_addrtuple *addrfree = addrmem; +@@ -748,22 +695,13 @@ gaih_inet (const char *name, const struct gaih_service *service, + (*pat)->name = NULL; + else if (canonbuf == NULL) + { +- size_t canonlen = strlen (air->canon) + 1; +- if ((req->ai_flags & AI_CANONIDN) != 0 +- && __libc_use_alloca (alloca_used + canonlen)) +- canonbuf = alloca_account (canonlen, alloca_used); +- else ++ canonbuf = __strdup (air->canon); ++ if (canonbuf == NULL) + { +- canonbuf = malloc (canonlen); +- if (canonbuf == NULL) +- { +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- malloc_canonbuf = true; ++ result = -EAI_MEMORY; ++ goto free_and_return; + } +- canon = (*pat)->name = memcpy (canonbuf, air->canon, +- canonlen); ++ canon = (*pat)->name = canonbuf; + } + + if (air->family[i] == AF_INET +@@ -795,7 +733,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + + if (at->family == AF_UNSPEC) + { +- result = GAIH_OKIFUNSPEC | -EAI_NONAME; ++ result = -EAI_NONAME; + goto free_and_return; + } + +@@ -806,9 +744,9 @@ gaih_inet (const char *name, const struct gaih_service *service, + goto free_and_return; + else if (__nss_not_use_nscd_hosts == 0) + { +- if (herrno == NETDB_INTERNAL && errno == ENOMEM) ++ if (h_errno == NETDB_INTERNAL && errno == ENOMEM) + result = -EAI_MEMORY; +- else if (herrno == TRY_AGAIN) ++ else if (h_errno == TRY_AGAIN) + result = -EAI_AGAIN; + else + result = -EAI_SYSTEM; +@@ -818,44 +756,22 @@ gaih_inet (const char *name, const struct gaih_service *service, + } + #endif + +- if (__nss_hosts_database != NULL) +- { +- no_more = 0; +- nip = __nss_hosts_database; +- } +- else ++ if (__nss_hosts_database == NULL) + no_more = __nss_database_lookup ("hosts", NULL, + "dns [!UNAVAIL=return] files", +- &nip); +- +- /* Initialize configurations. */ +- if (__builtin_expect (!_res_hconf.initialized, 0)) +- _res_hconf_init (); +- if (__res_maybe_init (&_res, 0) == -1) +- no_more = 1; ++ &__nss_hosts_database); ++ else ++ no_more = 0; ++ nip = __nss_hosts_database; + + /* If we are looking for both IPv4 and IPv6 address we don't + want the lookup functions to automatically promote IPv4 +- addresses to IPv6 addresses. Currently this is decided +- by setting the RES_USE_INET6 bit in _res.options. */ +- old_res_options = _res.options; +- _res.options &= ~DEPRECATED_RES_USE_INET6; +- +- size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple); +- malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen); +- assert (tmpbuf == NULL); +- if (!malloc_tmpbuf) +- tmpbuf = alloca_account (tmpbuflen, alloca_used); +- else +- { +- tmpbuf = malloc (tmpbuflen); +- if (tmpbuf == NULL) +- { +- _res.options |= old_res_options & RES_USE_INET6; +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- } ++ addresses to IPv6 addresses, so we use the no_inet6 ++ function variant. */ ++ res_ctx = __resolv_context_get (); ++ res_enable_inet6 = __resolv_context_disable_inet6 (res_ctx); ++ if (res_ctx == NULL) ++ no_more = 1; + + while (!no_more) + { +@@ -869,44 +785,31 @@ gaih_inet (const char *name, const struct gaih_service *service, + + if (fct4 != NULL) + { +- int herrno; +- + while (1) + { +- rc = 0; +- status = DL_CALL_FCT (fct4, (name, pat, tmpbuf, +- tmpbuflen, &rc, &herrno, ++ status = DL_CALL_FCT (fct4, (name, pat, ++ tmpbuf->data, tmpbuf->length, ++ &errno, &h_errno, + NULL)); + if (status == NSS_STATUS_SUCCESS) + break; + if (status != NSS_STATUS_TRYAGAIN +- || rc != ERANGE || herrno != NETDB_INTERNAL) ++ || errno != ERANGE || h_errno != NETDB_INTERNAL) + { +- if (herrno == TRY_AGAIN) ++ if (h_errno == TRY_AGAIN) + no_data = EAI_AGAIN; + else +- no_data = herrno == NO_DATA; ++ no_data = h_errno == NO_DATA; + break; + } + +- if (!malloc_tmpbuf +- && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) +- tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, +- 2 * tmpbuflen, +- alloca_used); +- else ++ if (!scratch_buffer_grow (tmpbuf)) + { +- char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, +- 2 * tmpbuflen); +- if (newp == NULL) +- { +- _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- tmpbuf = newp; +- malloc_tmpbuf = true; +- tmpbuflen = 2 * tmpbuflen; ++ __resolv_context_enable_inet6 ++ (res_ctx, res_enable_inet6); ++ __resolv_context_put (res_ctx); ++ result = -EAI_MEMORY; ++ goto free_and_return; + } + } + +@@ -1000,54 +903,16 @@ gaih_inet (const char *name, const struct gaih_service *service, + if ((req->ai_flags & AI_CANONNAME) != 0 + && canon == NULL) + { +- /* If we need the canonical name, get it +- from the same service as the result. */ +- nss_getcanonname_r cfct; +- int herrno; +- +- cfct = __nss_lookup_function (nip, +- "getcanonname_r"); +- if (cfct != NULL) ++ canonbuf = getcanonname (nip, at, name); ++ if (canonbuf == NULL) + { +- const size_t max_fqdn_len = 256; +- if ((req->ai_flags & AI_CANONIDN) != 0 +- && __libc_use_alloca (alloca_used +- + max_fqdn_len)) +- canonbuf = alloca_account (max_fqdn_len, +- alloca_used); +- else +- { +- canonbuf = malloc (max_fqdn_len); +- if (canonbuf == NULL) +- { +- _res.options +- |= old_res_options +- & DEPRECATED_RES_USE_INET6; +- result = -EAI_MEMORY; +- goto free_and_return; +- } +- malloc_canonbuf = true; +- } +- char *s; +- +- if (DL_CALL_FCT (cfct, (at->name ?: name, +- canonbuf, +- max_fqdn_len, +- &s, &rc, &herrno)) +- == NSS_STATUS_SUCCESS) +- canon = s; +- else +- { +- /* Set to name now to avoid using +- gethostbyaddr. */ +- if (malloc_canonbuf) +- { +- free (canonbuf); +- malloc_canonbuf = false; +- } +- canon = name; +- } ++ __resolv_context_enable_inet6 ++ (res_ctx, res_enable_inet6); ++ __resolv_context_put (res_ctx); ++ result = -EAI_MEMORY; ++ goto free_and_return; + } ++ canon = canonbuf; + } + status = NSS_STATUS_SUCCESS; + } +@@ -1064,13 +929,17 @@ gaih_inet (const char *name, const struct gaih_service *service, + } + else + { ++ /* Could not locate any of the lookup functions. ++ The NSS lookup code does not consistently set ++ errno, so we need to supply our own error ++ code here. The root cause could either be a ++ resource allocation failure, or a missing ++ service function in the DSO (so it should not ++ be listed in /etc/nsswitch.conf). Assume the ++ former, and return EBUSY. */ + status = NSS_STATUS_UNAVAIL; +- /* Could not load any of the lookup functions. Indicate +- an internal error if the failure was due to a system +- error other than the file not being found. We use the +- errno from the last failed callback. */ +- if (errno != 0 && errno != ENOENT) +- __set_h_errno (NETDB_INTERNAL); ++ __set_h_errno (NETDB_INTERNAL); ++ __set_errno (EBUSY); + } + } + +@@ -1083,11 +952,15 @@ gaih_inet (const char *name, const struct gaih_service *service, + nip = nip->next; + } + +- _res.options |= old_res_options & DEPRECATED_RES_USE_INET6; ++ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); ++ __resolv_context_put (res_ctx); + +- if (h_errno == NETDB_INTERNAL) ++ /* If we have a failure which sets errno, report it using ++ EAI_SYSTEM. */ ++ if ((status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) ++ && h_errno == NETDB_INTERNAL) + { +- result = GAIH_OKIFUNSPEC | -EAI_SYSTEM; ++ result = -EAI_SYSTEM; + goto free_and_return; + } + +@@ -1099,7 +972,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + else + /* We made requests but they turned out no data. The name + is known, though. */ +- result = GAIH_OKIFUNSPEC | -EAI_NODATA; ++ result = -EAI_NODATA; + + goto free_and_return; + } +@@ -1108,7 +981,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + process_list: + if (at->family == AF_UNSPEC) + { +- result = GAIH_OKIFUNSPEC | -EAI_NONAME; ++ result = -EAI_NONAME; + goto free_and_return; + } + } +@@ -1193,12 +1066,13 @@ gaih_inet (const char *name, const struct gaih_service *service, + #ifdef HAVE_LIBIDN + make_copy: + #endif +- if (malloc_canonbuf) +- /* We already allocated the string using malloc. */ +- malloc_canonbuf = false; ++ if (canonbuf != NULL) ++ /* We already allocated the string using malloc, but ++ the buffer is now owned by canon. */ ++ canonbuf = NULL; + else + { +- canon = strdup (canon); ++ canon = __strdup (canon); + if (canon == NULL) + { + result = -EAI_MEMORY; +@@ -1289,12 +1163,8 @@ gaih_inet (const char *name, const struct gaih_service *service, + free_and_return: + if (malloc_name) + free ((char *) name); +- if (malloc_addrmem) +- free (addrmem); +- if (malloc_canonbuf) +- free (canonbuf); +- if (malloc_tmpbuf) +- free (tmpbuf); ++ free (addrmem); ++ free (canonbuf); + + return result; + } +@@ -2429,13 +2299,17 @@ getaddrinfo (const char *name, const char *service, + if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET + || hints->ai_family == AF_INET6) + { +- last_i = gaih_inet (name, pservice, hints, end, &naddrs); ++ struct scratch_buffer tmpbuf; ++ scratch_buffer_init (&tmpbuf); ++ last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf); ++ scratch_buffer_free (&tmpbuf); ++ + if (last_i != 0) + { + freeaddrinfo (p); + __free_in6ai (in6ai); + +- return -(last_i & GAIH_EAI); ++ return -last_i; + } + while (*end) + { +@@ -2462,12 +2336,13 @@ getaddrinfo (const char *name, const char *service, + struct addrinfo *last = NULL; + char *canonname = NULL; + bool malloc_results; ++ size_t alloc_size = nresults * (sizeof (*results) + sizeof (size_t)); + + malloc_results +- = !__libc_use_alloca (nresults * (sizeof (*results) + sizeof (size_t))); ++ = !__libc_use_alloca (alloc_size); + if (malloc_results) + { +- results = malloc (nresults * (sizeof (*results) + sizeof (size_t))); ++ results = malloc (alloc_size); + if (results == NULL) + { + __free_in6ai (in6ai); +@@ -2475,7 +2350,7 @@ getaddrinfo (const char *name, const char *service, + } + } + else +- results = alloca (nresults * (sizeof (*results) + sizeof (size_t))); ++ results = alloca (alloc_size); + order = (size_t *) (results + nresults); + + /* Now we definitely need the interface information. */ +@@ -2526,7 +2401,7 @@ getaddrinfo (const char *name, const char *service, + close_retry: + close_not_cancel_no_status (fd); + af = q->ai_family; +- fd = __socket (af, SOCK_DGRAM, IPPROTO_IP); ++ fd = __socket (af, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_IP); + } + else + { +@@ -2559,7 +2434,7 @@ getaddrinfo (const char *name, const char *service, + tmp.addr[1] = 0; + tmp.addr[2] = htonl (0xffff); + /* Special case for lo interface, the source address +- being possibly different than the interface ++ being possibly different than the interface + address. */ + if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000) + == 0x7f000000) +@@ -2633,7 +2508,7 @@ getaddrinfo (const char *name, const char *service, + the information. */ + struct sort_result_combo src + = { .results = results, .nresults = nresults }; +- if (__builtin_expect (gaiconf_reload_flag_ever_set, 0)) ++ if (__glibc_unlikely (gaiconf_reload_flag_ever_set)) + { + __libc_lock_define_initialized (static, lock); + +@@ -2667,7 +2542,7 @@ getaddrinfo (const char *name, const char *service, + return 0; + } + +- return last_i ? -(last_i & GAIH_EAI) : EAI_NONAME; ++ return last_i ? -last_i : EAI_NONAME; + } + libc_hidden_def (getaddrinfo) diff --git a/SOURCES/glibc-rh677316-scratch_buffer.patch b/SOURCES/glibc-rh677316-scratch_buffer.patch new file mode 100644 index 00000000..67c60a2f --- /dev/null +++ b/SOURCES/glibc-rh677316-scratch_buffer.patch @@ -0,0 +1,591 @@ +Backport of the following upstream commits: + +commit c04af6068b2c2c65c92b3360cbc4b51ad9843f21 +Author: Florian Weimer +Date: Thu Apr 7 13:46:28 2016 +0200 + + scratch_buffer_set_array_size: Include + + It is needed for CHAR_BIT. + +commit dbb7600658d8ea633083ee99572622b04ef23a3f +Author: Joseph Myers +Date: Thu Oct 29 12:46:22 2015 +0000 + + Use max_align_t from . + + Now that we build with -std=gnu11 and can rely on a compiler providing + max_align_t in , we no longer need our own version + libc_max_align_t. This patch removes it and replaces the single user + with a use of max_align_t. + + Tested for x86_64 and x86 (testsuite, and that installed stripped + shared libraries are unchanged by the patch for x86_64; for x86, I see + some code reordering of no significance). + + * include/libc-internal.h (libc_max_align_t): Remove typedef. + * include/scratch_buffer.h: Include instead of + . + (struct scratch_buffer): Use max_align_t instead of + libc_max_align_t. + +(The above is a partial backport. It depends on max_align_t addition to + because glibc 2.17 is not compiled in C11 mode, so +GCC's does not provide it.) + +commit 2902af1631c0c74c2f0c0edd7a85a523370e5027 +Author: Florian Weimer +Date: Thu Apr 9 17:12:42 2015 +0200 + + scratch_buffer: Suppress truncation warning on 32-bit + +commit 72301304a5655662baf2bae88a7aceeabc4a753e +Author: Florian Weimer +Date: Tue Apr 7 17:46:58 2015 +0200 + + scratch_buffer_grow_preserve: Add missing #include + +commit cfcfd4614b8b01b2782ac4dcafb21d14d74d5184 +Author: Florian Weimer +Date: Tue Apr 7 11:03:43 2015 +0200 + + Add struct scratch_buffer and its internal helper functions + + These will be used from NSS modules, so they have to be exported. + +diff --git a/include/scratch_buffer.h b/include/scratch_buffer.h +new file mode 100644 +index 0000000000000000..dd17a4a7e13596aa +--- /dev/null ++++ b/include/scratch_buffer.h +@@ -0,0 +1,136 @@ ++/* Variable-sized buffer with on-stack default allocation. ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _SCRATCH_BUFFER_H ++#define _SCRATCH_BUFFER_H ++ ++/* Scratch buffers with a default stack allocation and fallback to ++ heap allocation. It is expected that this function is used in this ++ way: ++ ++ struct scratch_buffer tmpbuf; ++ scratch_buffer_init (&tmpbuf); ++ ++ while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) ++ if (!scratch_buffer_grow (&tmpbuf)) ++ return -1; ++ ++ scratch_buffer_free (&tmpbuf); ++ return 0; ++ ++ The allocation functions (scratch_buffer_grow, ++ scratch_buffer_grow_preserve, scratch_buffer_set_array_size) make ++ sure that the heap allocation, if any, is freed, so that the code ++ above does not have a memory leak. The buffer still remains in a ++ state that can be deallocated using scratch_buffer_free, so a loop ++ like this is valid as well: ++ ++ struct scratch_buffer tmpbuf; ++ scratch_buffer_init (&tmpbuf); ++ ++ while (!function_that_uses_buffer (tmpbuf.data, tmpbuf.length)) ++ if (!scratch_buffer_grow (&tmpbuf)) ++ break; ++ ++ scratch_buffer_free (&tmpbuf); ++ ++ scratch_buffer_grow and scratch_buffer_grow_preserve are guaranteed ++ to grow the buffer by at least 512 bytes. This means that when ++ using the scratch buffer as a backing store for a non-character ++ array whose element size, in bytes, is 512 or smaller, the scratch ++ buffer only has to grow once to make room for at least one more ++ element. ++*/ ++ ++#include ++#include ++#include ++ ++/* Scratch buffer. Must be initialized with scratch_buffer_init ++ before its use. */ ++struct scratch_buffer { ++ void *data; /* Pointer to the beginning of the scratch area. */ ++ size_t length; /* Allocated space at the data pointer, in bytes. */ ++ char __space[1024] ++ __attribute__ ((aligned (__alignof__ (max_align_t)))); ++}; ++ ++/* Initializes *BUFFER so that BUFFER->data points to BUFFER->__space ++ and BUFFER->length reflects the available space. */ ++static inline void ++scratch_buffer_init (struct scratch_buffer *buffer) ++{ ++ buffer->data = buffer->__space; ++ buffer->length = sizeof (buffer->__space); ++} ++ ++/* Deallocates *BUFFER (if it was heap-allocated). */ ++static inline void ++scratch_buffer_free (struct scratch_buffer *buffer) ++{ ++ if (buffer->data != buffer->__space) ++ free (buffer->data); ++} ++ ++/* Grow *BUFFER by some arbitrary amount. The buffer contents is NOT ++ preserved. Return true on success, false on allocation failure (in ++ which case the old buffer is freed). On success, the new buffer is ++ larger than the previous size. On failure, *BUFFER is deallocated, ++ but remains in a free-able state, and errno is set. */ ++bool __libc_scratch_buffer_grow (struct scratch_buffer *buffer); ++libc_hidden_proto (__libc_scratch_buffer_grow) ++ ++/* Alias for __libc_scratch_buffer_grow. */ ++static __always_inline bool ++scratch_buffer_grow (struct scratch_buffer *buffer) ++{ ++ return __glibc_likely (__libc_scratch_buffer_grow (buffer)); ++} ++ ++/* Like __libc_scratch_buffer_grow, but preserve the old buffer ++ contents on success, as a prefix of the new buffer. */ ++bool __libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer); ++libc_hidden_proto (__libc_scratch_buffer_grow_preserve) ++ ++/* Alias for __libc_scratch_buffer_grow_preserve. */ ++static __always_inline bool ++scratch_buffer_grow_preserve (struct scratch_buffer *buffer) ++{ ++ return __glibc_likely (__libc_scratch_buffer_grow_preserve (buffer)); ++} ++ ++/* Grow *BUFFER so that it can store at least NELEM elements of SIZE ++ bytes. The buffer contents are NOT preserved. Both NELEM and SIZE ++ can be zero. Return true on success, false on allocation failure ++ (in which case the old buffer is freed, but *BUFFER remains in a ++ free-able state, and errno is set). It is unspecified whether this ++ function can reduce the array size. */ ++bool __libc_scratch_buffer_set_array_size (struct scratch_buffer *buffer, ++ size_t nelem, size_t size); ++libc_hidden_proto (__libc_scratch_buffer_set_array_size) ++ ++/* Alias for __libc_scratch_set_array_size. */ ++static __always_inline bool ++scratch_buffer_set_array_size (struct scratch_buffer *buffer, ++ size_t nelem, size_t size) ++{ ++ return __glibc_likely (__libc_scratch_buffer_set_array_size ++ (buffer, nelem, size)); ++} ++ ++#endif /* _SCRATCH_BUFFER_H */ +diff --git a/malloc/Makefile b/malloc/Makefile +index 70e3cefa7b06157e..38aa9e0993d4880c 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -33,6 +33,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-interpose-thread \ + tst-interpose-static-nothread \ + tst-interpose-static-thread \ ++ tst-scratch_buffer \ + + tests-static := \ + tst-interpose-static-nothread \ +@@ -40,7 +41,11 @@ tests-static := \ + + test-srcs = tst-mtrace + +-routines = malloc morecore mcheck mtrace obstack ++routines = malloc morecore mcheck mtrace obstack \ ++ scratch_buffer_grow \ ++ scratch_buffer_grow_preserve \ ++ scratch_buffer_set_array_size \ ++ + + install-lib := libmcheck.a + non-lib.a := libmcheck.a +diff --git a/malloc/Versions b/malloc/Versions +index 7ca9bdf25fcafdf2..f3c3d8a0934bdcd3 100644 +--- a/malloc/Versions ++++ b/malloc/Versions +@@ -67,5 +67,10 @@ libc { + + # Internal destructor hook for libpthread. + __libc_thread_freeres; ++ ++ # struct scratch_buffer support ++ __libc_scratch_buffer_grow; ++ __libc_scratch_buffer_grow_preserve; ++ __libc_scratch_buffer_set_array_size; + } + } +diff --git a/malloc/scratch_buffer_grow.c b/malloc/scratch_buffer_grow.c +new file mode 100644 +index 0000000000000000..22bae506a1946eb4 +--- /dev/null ++++ b/malloc/scratch_buffer_grow.c +@@ -0,0 +1,52 @@ ++/* Variable-sized buffer with on-stack default allocation. ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++bool ++__libc_scratch_buffer_grow (struct scratch_buffer *buffer) ++{ ++ void *new_ptr; ++ size_t new_length = buffer->length * 2; ++ ++ /* Discard old buffer. */ ++ scratch_buffer_free (buffer); ++ ++ /* Check for overflow. */ ++ if (__glibc_likely (new_length >= buffer->length)) ++ new_ptr = malloc (new_length); ++ else ++ { ++ __set_errno (ENOMEM); ++ new_ptr = NULL; ++ } ++ ++ if (__glibc_unlikely (new_ptr == NULL)) ++ { ++ /* Buffer must remain valid to free. */ ++ scratch_buffer_init (buffer); ++ return false; ++ } ++ ++ /* Install new heap-based buffer. */ ++ buffer->data = new_ptr; ++ buffer->length = new_length; ++ return true; ++} ++libc_hidden_def (__libc_scratch_buffer_grow); +diff --git a/malloc/scratch_buffer_grow_preserve.c b/malloc/scratch_buffer_grow_preserve.c +new file mode 100644 +index 0000000000000000..18543ef85b7a48e1 +--- /dev/null ++++ b/malloc/scratch_buffer_grow_preserve.c +@@ -0,0 +1,63 @@ ++/* Variable-sized buffer with on-stack default allocation. ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++bool ++__libc_scratch_buffer_grow_preserve (struct scratch_buffer *buffer) ++{ ++ size_t new_length = 2 * buffer->length; ++ void *new_ptr; ++ ++ if (buffer->data == buffer->__space) ++ { ++ /* Move buffer to the heap. No overflow is possible because ++ buffer->length describes a small buffer on the stack. */ ++ new_ptr = malloc (new_length); ++ if (new_ptr == NULL) ++ return false; ++ memcpy (new_ptr, buffer->__space, buffer->length); ++ } ++ else ++ { ++ /* Buffer was already on the heap. Check for overflow. */ ++ if (__glibc_likely (new_length >= buffer->length)) ++ new_ptr = realloc (buffer->data, new_length); ++ else ++ { ++ __set_errno (ENOMEM); ++ new_ptr = NULL; ++ } ++ ++ if (__glibc_unlikely (new_ptr == NULL)) ++ { ++ /* Deallocate, but buffer must remain valid to free. */ ++ free (buffer->data); ++ scratch_buffer_init (buffer); ++ return false; ++ } ++ } ++ ++ /* Install new heap-based buffer. */ ++ buffer->data = new_ptr; ++ buffer->length = new_length; ++ return true; ++} ++libc_hidden_def (__libc_scratch_buffer_grow_preserve); +diff --git a/malloc/scratch_buffer_set_array_size.c b/malloc/scratch_buffer_set_array_size.c +new file mode 100644 +index 0000000000000000..8ab6d9d300d5c10d +--- /dev/null ++++ b/malloc/scratch_buffer_set_array_size.c +@@ -0,0 +1,60 @@ ++/* Variable-sized buffer with on-stack default allocation. ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++bool ++__libc_scratch_buffer_set_array_size (struct scratch_buffer *buffer, ++ size_t nelem, size_t size) ++{ ++ size_t new_length = nelem * size; ++ ++ /* Avoid overflow check if both values are small. */ ++ if ((nelem | size) >> (sizeof (size_t) * CHAR_BIT / 2) != 0 ++ && nelem != 0 && size != new_length / nelem) ++ { ++ /* Overflow. Discard the old buffer, but it must remain valid ++ to free. */ ++ scratch_buffer_free (buffer); ++ scratch_buffer_init (buffer); ++ __set_errno (ENOMEM); ++ return false; ++ } ++ ++ if (new_length <= buffer->length) ++ return true; ++ ++ /* Discard old buffer. */ ++ scratch_buffer_free (buffer); ++ ++ char *new_ptr = malloc (new_length); ++ if (new_ptr == NULL) ++ { ++ /* Buffer must remain valid to free. */ ++ scratch_buffer_init (buffer); ++ return false; ++ } ++ ++ /* Install new heap-based buffer. */ ++ buffer->data = new_ptr; ++ buffer->length = new_length; ++ return true; ++} ++libc_hidden_def (__libc_scratch_buffer_set_array_size); +diff --git a/malloc/tst-scratch_buffer.c b/malloc/tst-scratch_buffer.c +new file mode 100644 +index 0000000000000000..5c9f3442ae8d6ef9 +--- /dev/null ++++ b/malloc/tst-scratch_buffer.c +@@ -0,0 +1,155 @@ ++/* ++ Copyright (C) 2015-2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static bool ++unchanged_array_size (struct scratch_buffer *buf, size_t a, size_t b) ++{ ++ size_t old_length = buf->length; ++ if (!scratch_buffer_set_array_size (buf, a, b)) ++ { ++ printf ("scratch_buffer_set_array_size failed: %zu %zu\n", ++ a, b); ++ return false; ++ } ++ if (old_length != buf->length) ++ { ++ printf ("scratch_buffer_set_array_size did not preserve size: %zu %zu\n", ++ a, b); ++ return false; ++ } ++ return true; ++} ++ ++static bool ++array_size_must_fail (size_t a, size_t b) ++{ ++ for (int pass = 0; pass < 2; ++pass) ++ { ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ if (pass > 0) ++ if (!scratch_buffer_grow (&buf)) ++ { ++ printf ("scratch_buffer_grow in array_size_must_fail failed\n"); ++ return false; ++ } ++ if (scratch_buffer_set_array_size (&buf, a, b)) ++ { ++ printf ("scratch_buffer_set_array_size passed: %d %zu %zu\n", ++ pass, a, b); ++ return false; ++ } ++ if (buf.data != buf.__space) ++ { ++ printf ("scratch_buffer_set_array_size did not free: %d %zu %zu\n", ++ pass, a, b); ++ return false; ++ } ++ } ++ return true; ++} ++ ++static int ++do_test (void) ++{ ++ { ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ memset (buf.data, ' ', buf.length); ++ scratch_buffer_free (&buf); ++ } ++ { ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ memset (buf.data, ' ', buf.length); ++ size_t old_length = buf.length; ++ scratch_buffer_grow (&buf); ++ if (buf.length <= old_length) ++ { ++ printf ("scratch_buffer_grow did not enlarge buffer\n"); ++ return 1; ++ } ++ memset (buf.data, ' ', buf.length); ++ scratch_buffer_free (&buf); ++ } ++ { ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ memset (buf.data, '@', buf.length); ++ strcpy (buf.data, "prefix"); ++ size_t old_length = buf.length; ++ scratch_buffer_grow_preserve (&buf); ++ if (buf.length <= old_length) ++ { ++ printf ("scratch_buffer_grow_preserve did not enlarge buffer\n"); ++ return 1; ++ } ++ if (strcmp (buf.data, "prefix") != 0) ++ { ++ printf ("scratch_buffer_grow_preserve did not copy buffer\n"); ++ return 1; ++ } ++ for (unsigned i = 7; i < old_length; ++i) ++ if (((char *)buf.data)[i] != '@') ++ { ++ printf ("scratch_buffer_grow_preserve did not copy buffer (%u)\n", ++ i); ++ return 1; ++ } ++ scratch_buffer_free (&buf); ++ } ++ { ++ struct scratch_buffer buf; ++ scratch_buffer_init (&buf); ++ for (int pass = 0; pass < 4; ++pass) ++ { ++ if (!(unchanged_array_size (&buf, 0, 0) ++ && unchanged_array_size (&buf, 1, 0) ++ && unchanged_array_size (&buf, 0, 1) ++ && unchanged_array_size (&buf, -1, 0) ++ && unchanged_array_size (&buf, 0, -1) ++ && unchanged_array_size (&buf, 1ULL << 16, 0) ++ && unchanged_array_size (&buf, 0, 1ULL << 16) ++ && unchanged_array_size (&buf, (size_t) (1ULL << 32), 0) ++ && unchanged_array_size (&buf, 0, (size_t) (1ULL << 32)))) ++ return 1; ++ if (!scratch_buffer_grow (&buf)) ++ { ++ printf ("scratch_buffer_grow_failed (pass %d)\n", pass); ++ } ++ } ++ scratch_buffer_free (&buf); ++ } ++ { ++ if (!(array_size_must_fail (-1, 1) ++ && array_size_must_fail (-1, -1) ++ && array_size_must_fail (1, -1) ++ && array_size_must_fail (((size_t)-1) / 4, 4) ++ && array_size_must_fail (4, ((size_t)-1) / 4))) ++ return 1; ++ } ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh697421.patch b/SOURCES/glibc-rh697421.patch new file mode 100644 index 00000000..1ee03974 --- /dev/null +++ b/SOURCES/glibc-rh697421.patch @@ -0,0 +1,10 @@ +diff -rup glibc-2.17-c758a686/iconvdata/gconv-modules glibc-2.17-c758a686/iconvdata/gconv-modules +--- glibc-2.17-c758a686/iconvdata/gconv-modules 2010-05-04 05:27:23.000000000 -0600 ++++ glibc-2.17-c758a686/iconvdata/gconv-modules 2012-01-26 10:58:24.181895489 -0700 +@@ -1954,3 +1954,6 @@ alias HPGREEK8// HP-GREEK8// + alias OSF10010004// HP-GREEK8// + module HP-GREEK8// INTERNAL HP-GREEK8 1 + module INTERNAL HP-GREEK8// HP-GREEK8 1 ++ ++alias ISO-10646-UCS-2// UNICODE// ++alias ISO-10646-UCS-2// ISO-10646/UTF8/ diff --git a/SOURCES/glibc-rh731833-hwcap-2.patch b/SOURCES/glibc-rh731833-hwcap-2.patch new file mode 100644 index 00000000..b6ff0924 --- /dev/null +++ b/SOURCES/glibc-rh731833-hwcap-2.patch @@ -0,0 +1,108 @@ +From 4b4084b99e6553784a53a2ea683cc768c343d63a Mon Sep 17 00:00:00 2001 +From: "Ryan S. Arnold" +Date: Mon, 24 Jun 2013 15:33:32 -0500 +Subject: [PATCH 37/42] PowerPC: Enable POWER8 platform sans hwcap bits. + (cherry picked from commit + 2f063a6e843c788a05667e6d362d229b3b671920) + +--- + sysdeps/powerpc/dl-procinfo.c | 5 +++-- + sysdeps/powerpc/dl-procinfo.h | 6 +++++- + sysdeps/powerpc/powerpc32/power8/Implies | 2 ++ + sysdeps/powerpc/powerpc64/power8/Implies | 2 ++ + .../unix/sysv/linux/powerpc/powerpc32/power8/Implies | 2 ++ + .../unix/sysv/linux/powerpc/powerpc64/power8/Implies | 2 ++ + 7 files changed, 34 insertions(+), 3 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power8/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power8/Implies + create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies + create mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c +index 8488799..efab165 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c +@@ -67,7 +67,7 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_platforms + #else +-PROCINFO_CLASS const char _dl_powerpc_platforms[13][12] ++PROCINFO_CLASS const char _dl_powerpc_platforms[14][12] + #endif + #ifndef PROCINFO_DECL + = { +@@ -83,7 +83,8 @@ PROCINFO_CLASS const char _dl_powerpc_platforms[13][12] + [PPC_PLATFORM_PPC405] = "ppc405", + [PPC_PLATFORM_PPC440] = "ppc440", + [PPC_PLATFORM_PPC464] = "ppc464", +- [PPC_PLATFORM_PPC476] = "ppc476" ++ [PPC_PLATFORM_PPC476] = "ppc476", ++ [PPC_PLATFORM_POWER8] = "power8", + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +index 6d904ad..0939dcf 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +@@ -30,7 +30,7 @@ + #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ + + PPC_FEATURE_HAS_DFP) + +-#define _DL_PLATFORMS_COUNT 13 ++#define _DL_PLATFORMS_COUNT 14 + + #define _DL_FIRST_PLATFORM 32 + /* Mask to filter out platforms. */ +@@ -51,6 +51,7 @@ + #define PPC_PLATFORM_PPC440 10 + #define PPC_PLATFORM_PPC464 11 + #define PPC_PLATFORM_PPC476 12 ++#define PPC_PLATFORM_POWER8 13 + + static inline const char * + __attribute__ ((unused)) +@@ -111,6 +112,9 @@ _dl_string_platform (const char *str) + case '7': + ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER7; + break; ++ case '8': ++ ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER8; ++ break; + default: + return -1; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power8/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power8/Implies +new file mode 100644 +index 0000000..083f3e9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power8/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc32/power7/fpu ++powerpc/powerpc32/power7 +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/Implies +new file mode 100644 +index 0000000..9a5e3c7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc64/power7/fpu ++powerpc/powerpc64/power7 +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies +new file mode 100644 +index 0000000..066dea2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/power8/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc32/power8/fpu ++powerpc/powerpc32/power8 +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies +new file mode 100644 +index 0000000..fad2505 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies +@@ -0,0 +1,2 @@ ++powerpc/powerpc64/power8/fpu ++powerpc/powerpc64/power8 +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-hwcap-3.patch b/SOURCES/glibc-rh731833-hwcap-3.patch new file mode 100644 index 00000000..e8fdde59 --- /dev/null +++ b/SOURCES/glibc-rh731833-hwcap-3.patch @@ -0,0 +1,36 @@ +From af071af18c3bb13ba0eb48cde35ea5cdbff87b95 Mon Sep 17 00:00:00 2001 +From: "Ryan S. Arnold" +Date: Wed, 26 Jun 2013 08:50:20 -0500 +Subject: [PATCH 38/42] Add AT_HWCAP2 as a new auxv_t a_type to elf.h. (cherry + picked from commit + c18c701d030e28698e6faee9c6d3b8b80d0e2302) + +--- + elf/elf.h | 5 ++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git glibc-2.17-c758a686/elf/elf.h glibc-2.17-c758a686/elf/elf.h +index b07e6ad..8686fd5 100644 +--- glibc-2.17-c758a686/elf/elf.h ++++ glibc-2.17-c758a686/elf/elf.h +@@ -987,7 +987,7 @@ typedef struct + + /* Some more special a_type values describing the hardware. */ + #define AT_PLATFORM 15 /* String identifying platform. */ +-#define AT_HWCAP 16 /* Machine dependent hints about ++#define AT_HWCAP 16 /* Machine-dependent hints about + processor capabilities. */ + + /* This entry gives some information about the FPU initialization +@@ -1009,6 +1009,9 @@ typedef struct + + #define AT_RANDOM 25 /* Address of 16 random bytes. */ + ++#define AT_HWCAP2 26 /* More machine-dependent hints about ++ processor capabilities. */ ++ + #define AT_EXECFN 31 /* Filename of executable. */ + + /* Pointer to the global system page used for system calls and other +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-hwcap-4.patch b/SOURCES/glibc-rh731833-hwcap-4.patch new file mode 100644 index 00000000..8290dda5 --- /dev/null +++ b/SOURCES/glibc-rh731833-hwcap-4.patch @@ -0,0 +1,279 @@ +From dfb57bf8871503967f23f9ce4bf17479a19cf8e4 Mon Sep 17 00:00:00 2001 +From: "Ryan S. Arnold" +Date: Fri, 28 Jun 2013 16:50:48 -0500 +Subject: [PATCH 39/42] Add GLRO(dl_hwcap2) for new AT_HWCAP2 auxv_t a_type. + (cherry picked from commit + 1ae8bfe07c1ab2444cc1d186321ff1431a1b9f96) + +--- + elf/dl-support.c | 4 ++++ + elf/dl-sysdep.c | 10 +++++++--- + misc/getauxval.c | 2 ++ + ports/sysdeps/alpha/dl-procinfo.h | 2 +- + ports/sysdeps/mips/dl-procinfo.h | 2 +- + ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h | 6 +++++- + sysdeps/generic/dl-procinfo.h | 2 +- + sysdeps/generic/ldsodefs.h | 4 ++++ + sysdeps/i386/dl-procinfo.h | 2 +- + sysdeps/powerpc/dl-procinfo.h | 6 +++++- + sysdeps/s390/dl-procinfo.h | 2 +- + sysdeps/sparc/dl-procinfo.h | 6 +++++- + sysdeps/unix/sysv/linux/i386/dl-procinfo.h | 6 +++++- + sysdeps/unix/sysv/linux/s390/dl-procinfo.h | 6 +++++- + 18 files changed, 89 insertions(+), 13 deletions(-) + +diff --git glibc-2.17-c758a686/elf/dl-support.c glibc-2.17-c758a686/elf/dl-support.c +index 81e7172..05f53ee 100644 +--- glibc-2.17-c758a686/elf/dl-support.c ++++ glibc-2.17-c758a686/elf/dl-support.c +@@ -129,6 +129,7 @@ ElfW(auxv_t) *_dl_auxv; + ElfW(Phdr) *_dl_phdr; + size_t _dl_phnum; + uint64_t _dl_hwcap __attribute__ ((nocommon)); ++uint64_t _dl_hwcap2 __attribute__ ((nocommon)); + + /* This is not initialized to HWCAP_IMPORTANT, matching the definition + of _dl_important_hwcaps, below, where no hwcap strings are ever +@@ -212,6 +213,9 @@ _dl_aux_init (ElfW(auxv_t) *av) + case AT_HWCAP: + GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; + break; ++ case AT_HWCAP2: ++ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; ++ break; + #ifdef NEED_DL_SYSINFO + case AT_SYSINFO: + GL(dl_sysinfo) = av->a_un.a_val; +diff --git glibc-2.17-c758a686/elf/dl-sysdep.c glibc-2.17-c758a686/elf/dl-sysdep.c +index 65a9046..a0d1d04 100644 +--- glibc-2.17-c758a686/elf/dl-sysdep.c ++++ glibc-2.17-c758a686/elf/dl-sysdep.c +@@ -156,6 +156,9 @@ _dl_sysdep_start (void **start_argptr, + case AT_HWCAP: + GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val; + break; ++ case AT_HWCAP2: ++ GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val; ++ break; + case AT_CLKTCK: + GLRO(dl_clktck) = av->a_un.a_val; + break; +@@ -298,6 +301,7 @@ _dl_show_auxv (void) + [AT_SYSINFO - 2] = { "SYSINFO: 0x", hex }, + [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex }, + [AT_RANDOM - 2] = { "RANDOM: 0x", hex }, ++ [AT_HWCAP2 - 2] = { "HWCAP2: 0x", hex }, + }; + unsigned int idx = (unsigned int) (av->a_type - 2); + +@@ -309,10 +313,10 @@ _dl_show_auxv (void) + assert (AT_NULL == 0); + assert (AT_IGNORE == 1); + +- if (av->a_type == AT_HWCAP) ++ if (av->a_type == AT_HWCAP || av->a_type == AT_HWCAP2) + { +- /* This is handled special. */ +- if (_dl_procinfo (av->a_un.a_val) == 0) ++ /* These are handled in a special way per platform. */ ++ if (_dl_procinfo (av->a_type, av->a_un.a_val) == 0) + continue; + } + +diff --git glibc-2.17-c758a686/misc/getauxval.c glibc-2.17-c758a686/misc/getauxval.c +index bff4560..1c1882b 100644 +--- glibc-2.17-c758a686/misc/getauxval.c ++++ glibc-2.17-c758a686/misc/getauxval.c +@@ -26,6 +26,8 @@ __getauxval (unsigned long int type) + + if (type == AT_HWCAP) + return GLRO(dl_hwcap); ++ else if (type == AT_HWCAP2) ++ return GLRO(dl_hwcap2); + + for (p = GLRO(dl_auxv); p->a_type != AT_NULL; p++) + if (p->a_type == type) +diff --git glibc-2.17-c758a686/ports/sysdeps/alpha/dl-procinfo.h glibc-2.17-c758a686/ports/sysdeps/alpha/dl-procinfo.h +index 3db0efb..c3b27b4 100644 +--- glibc-2.17-c758a686/ports/sysdeps/alpha/dl-procinfo.h ++++ glibc-2.17-c758a686/ports/sysdeps/alpha/dl-procinfo.h +@@ -51,7 +51,7 @@ _dl_string_platform (const char *str) + }; + + /* We cannot provide a general printing function. */ +-#define _dl_procinfo(word) -1 ++#define _dl_procinfo(type, word) -1 + + /* There are no hardware capabilities defined. */ + #define _dl_hwcap_string(idx) "" +diff --git glibc-2.17-c758a686/ports/sysdeps/mips/dl-procinfo.h glibc-2.17-c758a686/ports/sysdeps/mips/dl-procinfo.h +index d42aea7..8c9f5c2 100644 +--- glibc-2.17-c758a686/ports/sysdeps/mips/dl-procinfo.h ++++ glibc-2.17-c758a686/ports/sysdeps/mips/dl-procinfo.h +@@ -51,7 +51,7 @@ _dl_string_platform (const char *str) + }; + + /* We cannot provide a general printing function. */ +-#define _dl_procinfo(word) -1 ++#define _dl_procinfo(type, word) -1 + + /* There are no hardware capabilities defined. */ + #define _dl_hwcap_string(idx) "" +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h +index bea7100..c96297b 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-procinfo.h +@@ -31,10 +31,14 @@ + + static inline int + __attribute__ ((unused)) +-_dl_procinfo (int word) ++_dl_procinfo (unsigned int type, unsigned long int word) + { + int i; + ++ /* Fallback to unknown output mechanism. */ ++ if (type == AT_HWCAP2) ++ return -1; ++ + _dl_printf ("AT_HWCAP: "); + + for (i = 0; i < _DL_HWCAP_COUNT; ++i) +diff --git glibc-2.17-c758a686/sysdeps/generic/dl-procinfo.h glibc-2.17-c758a686/sysdeps/generic/dl-procinfo.h +index c2bf914..0345717 100644 +--- glibc-2.17-c758a686/sysdeps/generic/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/generic/dl-procinfo.h +@@ -21,7 +21,7 @@ + #define _DL_PROCINFO_H 1 + + /* We cannot provide a general printing function. */ +-#define _dl_procinfo(word) -1 ++#define _dl_procinfo(type, word) -1 + + /* There are no hardware capabilities defined. */ + #define _dl_hwcap_string(idx) "" +diff --git glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +index c667e34..5635d72 100644 +--- glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +@@ -548,6 +548,10 @@ struct rtld_global_ro + EXTERN struct link_map *_dl_sysinfo_map; + #endif + ++ /* Mask for more hardware capabilities that are available on some ++ platforms. */ ++ EXTERN uint64_t _dl_hwcap2; ++ + #ifdef SHARED + /* We add a function table to _rtld_global which is then used to + call the function instead of going through the PLT. The result +diff --git glibc-2.17-c758a686/sysdeps/i386/dl-procinfo.h glibc-2.17-c758a686/sysdeps/i386/dl-procinfo.h +index 6ecaac2..38e902d 100644 +--- glibc-2.17-c758a686/sysdeps/i386/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/i386/dl-procinfo.h +@@ -61,7 +61,7 @@ enum + }; + + /* We cannot provide a general printing function. */ +-#define _dl_procinfo(word) -1 ++#define _dl_procinfo(type, word) -1 + + static inline const char * + __attribute__ ((unused)) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +index 0939dcf..7732ed2 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +@@ -159,8 +159,12 @@ _dl_string_platform (const char *str) + #ifdef IS_IN_rtld + static inline int + __attribute__ ((unused)) +-_dl_procinfo (int word) ++_dl_procinfo (unsigned int type, unsigned long int word) + { ++ /* Fallback to unknown output mechanism. */ ++ if (type == AT_HWCAP2) ++ return -1; ++ + _dl_printf ("AT_HWCAP: "); + + for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) +diff --git glibc-2.17-c758a686/sysdeps/s390/dl-procinfo.h glibc-2.17-c758a686/sysdeps/s390/dl-procinfo.h +index 97dcf07..26de043 100644 +--- glibc-2.17-c758a686/sysdeps/s390/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/s390/dl-procinfo.h +@@ -56,7 +56,7 @@ enum + | HWCAP_S390_EIMM | HWCAP_S390_DFP) + + /* We cannot provide a general printing function. */ +-#define _dl_procinfo(word) -1 ++#define _dl_procinfo(type, word) -1 + + static inline const char * + __attribute__ ((unused)) +diff --git glibc-2.17-c758a686/sysdeps/sparc/dl-procinfo.h glibc-2.17-c758a686/sysdeps/sparc/dl-procinfo.h +index 6ae8768..a05d458 100644 +--- glibc-2.17-c758a686/sysdeps/sparc/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/sparc/dl-procinfo.h +@@ -28,10 +28,14 @@ + + static inline int + __attribute__ ((unused)) +-_dl_procinfo (int word) ++_dl_procinfo (unsigned int type, unsigned long int word) + { + int i; + ++ /* Fallback to unknown output mechanism. */ ++ if (type == AT_HWCAP2) ++ return -1; ++ + _dl_printf ("AT_HWCAP: "); + + for (i = 0; i < _DL_HWCAP_COUNT; ++i) +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/dl-procinfo.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/dl-procinfo.h +index 4c61357..23f4501 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/dl-procinfo.h +@@ -24,12 +24,16 @@ + #undef _dl_procinfo + static inline int + __attribute__ ((unused)) +-_dl_procinfo (int word) ++_dl_procinfo (unsigned int type, unsigned long int word) + { + /* This table should match the information from arch/i386/kernel/setup.c + in the kernel sources. */ + int i; + ++ /* Fallback to unknown output mechanism. */ ++ if (type == AT_HWCAP2) ++ return -1; ++ + _dl_printf ("AT_HWCAP: "); + + for (i = 0; i < _DL_HWCAP_COUNT; ++i) +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/dl-procinfo.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/dl-procinfo.h +index f36ba55..759738e 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/dl-procinfo.h +@@ -24,12 +24,16 @@ + #undef _dl_procinfo + static inline int + __attribute__ ((unused)) +-_dl_procinfo (int word) ++_dl_procinfo (unsigned int type, unsigned long int word) + { + /* This table should match the information from arch/s390/kernel/setup.c + in the kernel sources. */ + int i; + ++ /* Fallback to unknown output mechanism. */ ++ if (type == AT_HWCAP2) ++ return -1; ++ + _dl_printf ("AT_HWCAP: "); + + for (i = 0; i < _DL_HWCAP_COUNT; ++i) +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-hwcap-5.patch b/SOURCES/glibc-rh731833-hwcap-5.patch new file mode 100644 index 00000000..0c3bcbf9 --- /dev/null +++ b/SOURCES/glibc-rh731833-hwcap-5.patch @@ -0,0 +1,192 @@ +From 3ca2c50727b3e3e22eb3606135a18c6212f516d2 Mon Sep 17 00:00:00 2001 +From: "Ryan S. Arnold" +Date: Fri, 28 Jun 2013 16:52:49 -0500 +Subject: [PATCH 40/42] PowerPC: Define AT_HWCAP2 bits and AT_HWCAP2 handling + for POWER8. (cherry picked from commit + 89cd956937f46e8f4a0374994965f991642dd408) + +--- + sysdeps/powerpc/Makefile | 2 +- + sysdeps/powerpc/bits/hwcap.h | 25 +++++++++++----- + sysdeps/powerpc/dl-procinfo.c | 10 ++++++- + sysdeps/powerpc/dl-procinfo.h | 53 ++++++++++++++++++++++++--------- + sysdeps/powerpc/rtld-global-offsets.sym | 1 + + 6 files changed, 86 insertions(+), 23 deletions(-) + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/Makefile glibc-2.17-c758a686/sysdeps/powerpc/Makefile +index 7442b67..f75e625 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/Makefile +@@ -17,7 +17,7 @@ endif + endif + + ifeq ($(subdir),csu) +-# get offset to rtld_global._dl_hwcap ++# get offset to rtld_global._dl_hwcap and rtld_global._dl_hwcap2 + gen-as-const-headers += rtld-global-offsets.sym + # get offset to __locale_struct.__ctype_tolower + gen-as-const-headers += locale-defines.sym +diff --git glibc-2.17-c758a686/sysdeps/powerpc/bits/hwcap.h glibc-2.17-c758a686/sysdeps/powerpc/bits/hwcap.h +index 89e7d8b..0c02fc6 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/bits/hwcap.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/bits/hwcap.h +@@ -1,5 +1,5 @@ +-/* Defines for bits in AT_HWCAP. +- Copyright (C) 2012 Free Software Foundation, Inc. ++/* Defines for bits in AT_HWCAP and AT_HWCAP2. ++ Copyright (C) 2012-2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -20,9 +20,9 @@ + # error "Never include directly; use instead." + #endif + +-/* +- * The following must match the kernels asm/cputable.h. +- */ ++/* The bit numbers must match those in the kernel's asm/cputable.h. */ ++ ++/* Feature definitions in AT_HWCAP. */ + #define PPC_FEATURE_32 0x80000000 /* 32-bit mode. */ + #define PPC_FEATURE_64 0x40000000 /* 64-bit mode. */ + #define PPC_FEATURE_601_INSTR 0x20000000 /* 601 chip, Old POWER ISA. */ +@@ -39,8 +39,9 @@ + #define PPC_FEATURE_POWER5 0x00040000 /* POWER5 ISA 2.02 */ + #define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ ISA 2.03 */ + #define PPC_FEATURE_CELL_BE 0x00010000 /* CELL Broadband Engine */ +-#define PPC_FEATURE_BOOKE 0x00008000 +-#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous Multi-Threading */ ++#define PPC_FEATURE_BOOKE 0x00008000 /* ISA Category Embedded */ ++#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous ++ Multi-Threading */ + #define PPC_FEATURE_ICACHE_SNOOP 0x00002000 + #define PPC_FEATURE_ARCH_2_05 0x00001000 /* ISA 2.05 */ + #define PPC_FEATURE_PA6T 0x00000800 /* PA Semi 6T Core */ +@@ -51,3 +52,13 @@ + #define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040 + #define PPC_FEATURE_TRUE_LE 0x00000002 + #define PPC_FEATURE_PPC_LE 0x00000001 ++ ++/* Feature definitions in AT_HWCAP2. */ ++#define PPC_FEATURE2_ARCH_2_07 0x80000000 /* ISA 2.07 */ ++#define PPC_FEATURE2_HAS_HTM 0x40000000 /* Hardware Transactional ++ Memory */ ++#define PPC_FEATURE2_HAS_DSCR 0x20000000 /* Data Stream Control ++ Register */ ++#define PPC_FEATURE2_HAS_EBB 0x10000000 /* Event Base Branching */ ++#define PPC_FEATURE2_HAS_ISEL 0x08000000 /* Integer Select */ ++#define PPC_FEATURE2_HAS_TAR 0x04000000 /* Target Address Register */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c +index efab165..6cebf99 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c +@@ -45,7 +45,7 @@ + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_cap_flags + #else +-PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] ++PROCINFO_CLASS const char _dl_powerpc_cap_flags[57][10] + #endif + #ifndef PROCINFO_DECL + = { +@@ -56,6 +56,14 @@ PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] + "notb", "efpdouble", "efpsingle", "spe", + "ucache", "4xxmac", "mmu", "fpu", + "altivec", "ppc601", "ppc64", "ppc32", ++ "", "", "", "", ++ "", "", "", "", ++ "", "", "", "", ++ "", "", "", "", ++ "", "", "", "", ++ "", "", "", "", ++ "", "", "tar", "isel", ++ "ebb", "dscr", "htm", "arch_2_07", + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff --git glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +index 7732ed2..dc3b70e 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +@@ -20,11 +20,21 @@ + #define _DL_PROCINFO_H 1 + + #include +-#include /* This defines the PPC_FEATURE_* macros. */ ++#include /* This defines the PPC_FEATURE[2]_* macros. */ + + /* There are 25 bits used, but they are bits 7..31. */ + #define _DL_HWCAP_FIRST 7 +-#define _DL_HWCAP_COUNT 32 ++ ++/* The total number of available bits (including those prior to ++ _DL_HWCAP_FIRST). Some of these bits might not be used. */ ++#define _DL_HWCAP_COUNT 64 ++ ++/* Features started at bit 31 and decremented as new features were added. */ ++#define _DL_HWCAP_LAST 31 ++ ++/* AT_HWCAP2 features started at bit 31 and decremented as new features were ++ added. HWCAP2 feature bits start at bit 0. */ ++#define _DL_HWCAP2_LAST 31 + + /* These bits influence library search. */ + #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ +@@ -161,18 +171,33 @@ static inline int + __attribute__ ((unused)) + _dl_procinfo (unsigned int type, unsigned long int word) + { +- /* Fallback to unknown output mechanism. */ +- if (type == AT_HWCAP2) +- return -1; +- +- _dl_printf ("AT_HWCAP: "); +- +- for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) +- if (word & (1 << i)) +- _dl_printf (" %s", _dl_hwcap_string (i)); +- +- _dl_printf ("\n"); +- ++ switch(type) ++ { ++ case AT_HWCAP: ++ _dl_printf ("AT_HWCAP: "); ++ ++ for (int i = _DL_HWCAP_FIRST; i <= _DL_HWCAP_LAST; ++i) ++ if (word & (1 << i)) ++ _dl_printf (" %s", _dl_hwcap_string (i)); ++ break; ++ case AT_HWCAP2: ++ { ++ unsigned int offset = _DL_HWCAP_LAST + 1; ++ ++ _dl_printf ("AT_HWCAP2: "); ++ ++ /* We have to go through them all because the kernel added the ++ AT_HWCAP2 features starting with the high bits. */ ++ for (int i = 0; i <= _DL_HWCAP2_LAST; ++i) ++ if (word & (1 << i)) ++ _dl_printf (" %s", _dl_hwcap_string (offset + i)); ++ break; ++ } ++ default: ++ /* This should not happen. */ ++ return -1; ++ } ++ _dl_printf ("\n"); + return 0; + } + #endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/rtld-global-offsets.sym glibc-2.17-c758a686/sysdeps/powerpc/rtld-global-offsets.sym +index ff4e97f..f5ea5a1 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/rtld-global-offsets.sym ++++ glibc-2.17-c758a686/sysdeps/powerpc/rtld-global-offsets.sym +@@ -5,3 +5,4 @@ + #define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) + + RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap) ++RTLD_GLOBAL_RO_DL_HWCAP2_OFFSET rtld_global_ro_offsetof (_dl_hwcap2) +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-hwcap.patch b/SOURCES/glibc-rh731833-hwcap.patch new file mode 100644 index 00000000..8abf50d8 --- /dev/null +++ b/SOURCES/glibc-rh731833-hwcap.patch @@ -0,0 +1,408 @@ +This is a combination of two commits: + +From 2d718ff7745d89dcc2a630fe72783acf109cadc0 Mon Sep 17 00:00:00 2001 +From: "Ryan S. Arnold" +Date: Tue, 11 Jun 2013 09:32:41 -0500 +Subject: [PATCH 33/42] PowerPC: Merge ports/ dl-procinfo.[ch] with base. + (cherry picked from commit + fac0c5f2b1dc0e1806cd95f2d6a4619929119f01) + +From e0c595c971d958da58533a2b9b59f46a71a1e4cf Mon Sep 17 00:00:00 2001 +From: "Ryan S. Arnold" +Date: Tue, 11 Jun 2013 09:33:33 -0500 +Subject: [PATCH 34/42] PowerPC: Remove redundant + ports/sysdeps/powerpc/dl-procinfo.[ch]. (cherry + picked from commit + d04310f210734448a5b950988d49dcea145df9c1) + +diff -pruN glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.c glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.c +--- glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.c 1970-01-01 05:30:00.000000000 +0530 +@@ -1,96 +0,0 @@ +-/* Data for processor capability information. PowerPC version. +- Copyright (C) 2005-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library. If not, see +- . */ +- +-/* This information must be kept in sync with the _DL_HWCAP_COUNT and +- _DL_PLATFORM_COUNT definitions in procinfo.h. +- +- If anything should be added here check whether the size of each string +- is still ok with the given array size. +- +- All the #ifdefs in the definitions are quite irritating but +- necessary if we want to avoid duplicating the information. There +- are three different modes: +- +- - PROCINFO_DECL is defined. This means we are only interested in +- declarations. +- +- - PROCINFO_DECL is not defined: +- +- + if SHARED is defined the file is included in an array +- initializer. The .element = { ... } syntax is needed. +- +- + if SHARED is not defined a normal array initialization is +- needed. +- */ +- +-#ifndef PROCINFO_CLASS +-# define PROCINFO_CLASS +-#endif +- +-#if !defined PROCINFO_DECL && defined SHARED +- ._dl_powerpc_cap_flags +-#else +-PROCINFO_CLASS const char _dl_powerpc_cap_flags[25][10] +-#endif +-#ifndef PROCINFO_DECL +-= { +- "vsx", +- "arch_2_06", "power6x", "dfp", "pa6t", +- "arch_2_05", "ic_snoop", "smt", "booke", +- "cellbe", "power5+", "power5", "power4", +- "notb", "efpdouble", "efpsingle", "spe", +- "ucache", "4xxmac", "mmu", "fpu", +- "altivec", "ppc601", "ppc64", "ppc32", +- } +-#endif +-#if !defined SHARED || defined PROCINFO_DECL +-; +-#else +-, +-#endif +- +-#if !defined PROCINFO_DECL && defined SHARED +- ._dl_powerpc_platforms +-#else +-PROCINFO_CLASS const char _dl_powerpc_platforms[13][12] +-#endif +-#ifndef PROCINFO_DECL +-= { +- [PPC_PLATFORM_POWER4] = "power4", +- [PPC_PLATFORM_PPC970] = "ppc970", +- [PPC_PLATFORM_POWER5] = "power5", +- [PPC_PLATFORM_POWER5_PLUS] = "power5+", +- [PPC_PLATFORM_POWER6] = "power6", +- [PPC_PLATFORM_CELL_BE] = "ppc-cell-be", +- [PPC_PLATFORM_POWER6X] = "power6x", +- [PPC_PLATFORM_POWER7] = "power7", +- [PPC_PLATFORM_PPCA2] = "ppca2", +- [PPC_PLATFORM_PPC405] = "ppc405", +- [PPC_PLATFORM_PPC440] = "ppc440", +- [PPC_PLATFORM_PPC464] = "ppc464", +- [PPC_PLATFORM_PPC476] = "ppc476" +- } +-#endif +-#if !defined SHARED || defined PROCINFO_DECL +-; +-#else +-, +-#endif +- +-#undef PROCINFO_DECL +-#undef PROCINFO_CLASS +diff -pruN glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.h glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.h +--- glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/ports/sysdeps/powerpc/dl-procinfo.h 1970-01-01 05:30:00.000000000 +0530 +@@ -1,172 +0,0 @@ +-/* Processor capability information handling macros. PowerPC version. +- Copyright (C) 2005-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library. If not, see +- . */ +- +-#ifndef _DL_PROCINFO_H +-#define _DL_PROCINFO_H 1 +- +-#include +-#include /* This defines the PPC_FEATURE_* macros. */ +- +-/* There are 25 bits used, but they are bits 7..31. */ +-#define _DL_HWCAP_FIRST 7 +-#define _DL_HWCAP_COUNT 32 +- +-/* These bits influence library search. */ +-#define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ +- + PPC_FEATURE_HAS_DFP) +- +-#define _DL_PLATFORMS_COUNT 13 +- +-#define _DL_FIRST_PLATFORM 32 +-/* Mask to filter out platforms. */ +-#define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \ +- << _DL_FIRST_PLATFORM) +- +-/* Platform bits (relative to _DL_FIRST_PLATFORM). */ +-#define PPC_PLATFORM_POWER4 0 +-#define PPC_PLATFORM_PPC970 1 +-#define PPC_PLATFORM_POWER5 2 +-#define PPC_PLATFORM_POWER5_PLUS 3 +-#define PPC_PLATFORM_POWER6 4 +-#define PPC_PLATFORM_CELL_BE 5 +-#define PPC_PLATFORM_POWER6X 6 +-#define PPC_PLATFORM_POWER7 7 +-#define PPC_PLATFORM_PPCA2 8 +-#define PPC_PLATFORM_PPC405 9 +-#define PPC_PLATFORM_PPC440 10 +-#define PPC_PLATFORM_PPC464 11 +-#define PPC_PLATFORM_PPC476 12 +- +-static inline const char * +-__attribute__ ((unused)) +-_dl_hwcap_string (int idx) +-{ +- return GLRO(dl_powerpc_cap_flags)[idx - _DL_HWCAP_FIRST]; +-} +- +-static inline const char * +-__attribute__ ((unused)) +-_dl_platform_string (int idx) +-{ +- return GLRO(dl_powerpc_platforms)[idx - _DL_FIRST_PLATFORM]; +-} +- +-static inline int +-__attribute__ ((unused)) +-_dl_string_hwcap (const char *str) +-{ +- for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) +- if (strcmp (str, _dl_hwcap_string (i)) == 0) +- return i; +- return -1; +-} +- +-static inline int +-__attribute__ ((unused, always_inline)) +-_dl_string_platform (const char *str) +-{ +- if (str == NULL) +- return -1; +- +- if (strncmp (str, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_POWER4], 5) == 0) +- { +- int ret; +- str += 5; +- switch (*str) +- { +- case '4': +- ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER4; +- break; +- case '5': +- ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5; +- if (str[1] == '+') +- { +- ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5_PLUS; +- ++str; +- } +- break; +- case '6': +- ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6; +- if (str[1] == 'x') +- { +- ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6X; +- ++str; +- } +- break; +- case '7': +- ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER7; +- break; +- default: +- return -1; +- } +- if (str[1] == '\0') +- return ret; +- } +- else if (strncmp (str, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC970], +- 3) == 0) +- { +- if (strcmp (str + 3, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC970] +- + 3) == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC970; +- else if (strcmp (str + 3, +- GLRO(dl_powerpc_platforms)[PPC_PLATFORM_CELL_BE] + 3) +- == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_CELL_BE; +- else if (strcmp (str + 3, +- GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPCA2] + 3) +- == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPCA2; +- else if (strcmp (str + 3, +- GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC405] + 3) +- == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC405; +- else if (strcmp (str + 3, +- GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC440] + 3) +- == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC440; +- else if (strcmp (str + 3, +- GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC464] + 3) +- == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC464; +- else if (strcmp (str + 3, +- GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC476] + 3) +- == 0) +- return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC476; +- } +- +- return -1; +-} +- +-#ifdef IS_IN_rtld +-static inline int +-__attribute__ ((unused)) +-_dl_procinfo (int word) +-{ +- _dl_printf ("AT_HWCAP: "); +- +- for (int i = _DL_HWCAP_FIRST; i < _DL_HWCAP_COUNT; ++i) +- if (word & (1 << i)) +- _dl_printf (" %s", _dl_hwcap_string (i)); +- +- _dl_printf ("\n"); +- +- return 0; +-} +-#endif +- +-#endif /* dl-procinfo.h */ +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.c 2013-08-05 19:10:28.980541623 +0530 +@@ -13,7 +13,7 @@ + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see ++ License along with the GNU C Library. If not, see + . */ + + /* This information must be kept in sync with the _DL_HWCAP_COUNT and +@@ -67,7 +67,7 @@ PROCINFO_CLASS const char _dl_powerpc_ca + #if !defined PROCINFO_DECL && defined SHARED + ._dl_powerpc_platforms + #else +-PROCINFO_CLASS const char _dl_powerpc_platforms[9][12] ++PROCINFO_CLASS const char _dl_powerpc_platforms[13][12] + #endif + #ifndef PROCINFO_DECL + = { +@@ -79,7 +79,11 @@ PROCINFO_CLASS const char _dl_powerpc_pl + [PPC_PLATFORM_CELL_BE] = "ppc-cell-be", + [PPC_PLATFORM_POWER6X] = "power6x", + [PPC_PLATFORM_POWER7] = "power7", +- [PPC_PLATFORM_PPCA2] = "ppca2" ++ [PPC_PLATFORM_PPCA2] = "ppca2", ++ [PPC_PLATFORM_PPC405] = "ppc405", ++ [PPC_PLATFORM_PPC440] = "ppc440", ++ [PPC_PLATFORM_PPC464] = "ppc464", ++ [PPC_PLATFORM_PPC476] = "ppc476" + } + #endif + #if !defined SHARED || defined PROCINFO_DECL +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h +--- glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/dl-procinfo.h 2013-08-05 19:10:28.990541622 +0530 +@@ -13,14 +13,14 @@ + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see ++ License along with the GNU C Library. If not, see + . */ + + #ifndef _DL_PROCINFO_H +-#define _DL_PROCINFO_H 1 ++#define _DL_PROCINFO_H 1 + + #include +-#include /* This defines the PPC_FEATURE_* macros. */ ++#include /* This defines the PPC_FEATURE_* macros. */ + + /* There are 25 bits used, but they are bits 7..31. */ + #define _DL_HWCAP_FIRST 7 +@@ -30,12 +30,12 @@ + #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ + + PPC_FEATURE_HAS_DFP) + +-#define _DL_PLATFORMS_COUNT 9 ++#define _DL_PLATFORMS_COUNT 13 + +-#define _DL_FIRST_PLATFORM 32 ++#define _DL_FIRST_PLATFORM 32 + /* Mask to filter out platforms. */ +-#define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \ +- << _DL_FIRST_PLATFORM) ++#define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \ ++ << _DL_FIRST_PLATFORM) + + /* Platform bits (relative to _DL_FIRST_PLATFORM). */ + #define PPC_PLATFORM_POWER4 0 +@@ -47,6 +47,10 @@ + #define PPC_PLATFORM_POWER6X 6 + #define PPC_PLATFORM_POWER7 7 + #define PPC_PLATFORM_PPCA2 8 ++#define PPC_PLATFORM_PPC405 9 ++#define PPC_PLATFORM_PPC440 10 ++#define PPC_PLATFORM_PPC464 11 ++#define PPC_PLATFORM_PPC476 12 + + static inline const char * + __attribute__ ((unused)) +@@ -111,7 +115,7 @@ _dl_string_platform (const char *str) + return -1; + } + if (str[1] == '\0') +- return ret; ++ return ret; + } + else if (strncmp (str, GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC970], + 3) == 0) +@@ -127,6 +131,22 @@ _dl_string_platform (const char *str) + GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPCA2] + 3) + == 0) + return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPCA2; ++ else if (strcmp (str + 3, ++ GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC405] + 3) ++ == 0) ++ return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC405; ++ else if (strcmp (str + 3, ++ GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC440] + 3) ++ == 0) ++ return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC440; ++ else if (strcmp (str + 3, ++ GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC464] + 3) ++ == 0) ++ return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC464; ++ else if (strcmp (str + 3, ++ GLRO(dl_powerpc_platforms)[PPC_PLATFORM_PPC476] + 3) ++ == 0) ++ return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC476; + } + + return -1; diff --git a/SOURCES/glibc-rh731833-libm-2.patch b/SOURCES/glibc-rh731833-libm-2.patch new file mode 100644 index 00000000..cf21a0af --- /dev/null +++ b/SOURCES/glibc-rh731833-libm-2.patch @@ -0,0 +1,1740 @@ +From 66bf22e129f0b8621903a8b0489b2684e70fad65 Mon Sep 17 00:00:00 2001 +From: Siddhesh Poyarekar +Date: Fri, 8 Mar 2013 11:38:41 +0530 +Subject: [PATCH 17/42] Consolidate copies of mp code in powerpc + +Retain a single copy of the mp code in power4 instead of the two +identical copies in powerpc32 and powerpc64. +(backported from commit 6d9145d817e570cd986bb088cf2af0bf51ac7dde) +--- + sysdeps/powerpc/power4/fpu/Makefile | 5 + + sysdeps/powerpc/power4/fpu/mpa.c | 548 ++++++++++++++++++++++++++ + sysdeps/powerpc/powerpc32/power4/Implies | 2 + + sysdeps/powerpc/powerpc32/power4/fpu/Makefile | 5 - + sysdeps/powerpc/powerpc32/power4/fpu/mpa.c | 548 -------------------------- + sysdeps/powerpc/powerpc64/power4/Implies | 2 + + sysdeps/powerpc/powerpc64/power4/fpu/Makefile | 5 - + sysdeps/powerpc/powerpc64/power4/fpu/mpa.c | 548 -------------------------- + 9 files changed, 568 insertions(+), 1106 deletions(-) + create mode 100644 sysdeps/powerpc/power4/fpu/Makefile + create mode 100644 sysdeps/powerpc/power4/fpu/mpa.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/Implies + delete mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/Makefile + delete mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/mpa.c + create mode 100644 sysdeps/powerpc/powerpc64/power4/Implies + delete mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/Makefile + delete mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/mpa.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/Makefile glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/Makefile +new file mode 100644 +index 0000000..f487ed6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/Makefile +@@ -0,0 +1,5 @@ ++# Makefile fragment for POWER4/5/5+ with FPU. ++ ++ifeq ($(subdir),math) ++CFLAGS-mpa.c += --param max-unroll-times=4 -funroll-loops -fpeel-loops ++endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/mpa.c glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/mpa.c +new file mode 100644 +index 0000000..d15680e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power4/fpu/mpa.c +@@ -0,0 +1,548 @@ ++ ++/* ++ * IBM Accurate Mathematical Library ++ * written by International Business Machines Corp. ++ * Copyright (C) 2001, 2006 Free Software Foundation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as published by ++ * the Free Software Foundation; either version 2.1 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public License ++ * along with this program; if not, see . ++ */ ++/************************************************************************/ ++/* MODULE_NAME: mpa.c */ ++/* */ ++/* FUNCTIONS: */ ++/* mcr */ ++/* acr */ ++/* cr */ ++/* cpy */ ++/* cpymn */ ++/* norm */ ++/* denorm */ ++/* mp_dbl */ ++/* dbl_mp */ ++/* add_magnitudes */ ++/* sub_magnitudes */ ++/* add */ ++/* sub */ ++/* mul */ ++/* inv */ ++/* dvd */ ++/* */ ++/* Arithmetic functions for multiple precision numbers. */ ++/* Relative errors are bounded */ ++/************************************************************************/ ++ ++ ++#include "endian.h" ++#include "mpa.h" ++#include "mpa2.h" ++#include /* For MIN() */ ++/* mcr() compares the sizes of the mantissas of two multiple precision */ ++/* numbers. Mantissas are compared regardless of the signs of the */ ++/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */ ++/* disregarded. */ ++static int mcr(const mp_no *x, const mp_no *y, int p) { ++ long i; ++ long p2 = p; ++ for (i=1; i<=p2; i++) { ++ if (X[i] == Y[i]) continue; ++ else if (X[i] > Y[i]) return 1; ++ else return -1; } ++ return 0; ++} ++ ++ ++ ++/* acr() compares the absolute values of two multiple precision numbers */ ++int __acr(const mp_no *x, const mp_no *y, int p) { ++ long i; ++ ++ if (X[0] == ZERO) { ++ if (Y[0] == ZERO) i= 0; ++ else i=-1; ++ } ++ else if (Y[0] == ZERO) i= 1; ++ else { ++ if (EX > EY) i= 1; ++ else if (EX < EY) i=-1; ++ else i= mcr(x,y,p); ++ } ++ ++ return i; ++} ++ ++ ++/* cr90 compares the values of two multiple precision numbers */ ++int __cr(const mp_no *x, const mp_no *y, int p) { ++ int i; ++ ++ if (X[0] > Y[0]) i= 1; ++ else if (X[0] < Y[0]) i=-1; ++ else if (X[0] < ZERO ) i= __acr(y,x,p); ++ else i= __acr(x,y,p); ++ ++ return i; ++} ++ ++ ++/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */ ++void __cpy(const mp_no *x, mp_no *y, int p) { ++ long i; ++ ++ EY = EX; ++ for (i=0; i <= p; i++) Y[i] = X[i]; ++ ++ return; ++} ++ ++ ++/* Copy a multiple precision number x of precision m into a */ ++/* multiple precision number y of precision n. In case n>m, */ ++/* the digits of y beyond the m'th are set to zero. In case */ ++/* n= 2**(-1022))) */ ++static void norm(const mp_no *x, double *y, int p) ++{ ++ #define R radixi.d ++ long i; ++#if 0 ++ int k; ++#endif ++ double a,c,u,v,z[5]; ++ if (p<5) { ++ if (p==1) c = X[1]; ++ else if (p==2) c = X[1] + R* X[2]; ++ else if (p==3) c = X[1] + R*(X[2] + R* X[3]); ++ else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]); ++ } ++ else { ++ for (a=ONE, z[1]=X[1]; z[1] < TWO23; ) ++ {a *= TWO; z[1] *= TWO; } ++ ++ for (i=2; i<5; i++) { ++ z[i] = X[i]*a; ++ u = (z[i] + CUTTER)-CUTTER; ++ if (u > z[i]) u -= RADIX; ++ z[i] -= u; ++ z[i-1] += u*RADIXI; ++ } ++ ++ u = (z[3] + TWO71) - TWO71; ++ if (u > z[3]) u -= TWO19; ++ v = z[3]-u; ++ ++ if (v == TWO18) { ++ if (z[4] == ZERO) { ++ for (i=5; i <= p; i++) { ++ if (X[i] == ZERO) continue; ++ else {z[3] += ONE; break; } ++ } ++ } ++ else z[3] += ONE; ++ } ++ ++ c = (z[1] + R *(z[2] + R * z[3]))/a; ++ } ++ ++ c *= X[0]; ++ ++ for (i=1; iEX; i--) c *= RADIXI; ++ ++ *y = c; ++ return; ++#undef R ++} ++ ++/* Convert a multiple precision number *x into a double precision */ ++/* number *y, denormalized case (|x| < 2**(-1022))) */ ++static void denorm(const mp_no *x, double *y, int p) ++{ ++ long i,k; ++ long p2 = p; ++ double c,u,z[5]; ++#if 0 ++ double a,v; ++#endif ++ ++#define R radixi.d ++ if (EX<-44 || (EX==-44 && X[1] z[3]) u -= TWO5; ++ ++ if (u==z[3]) { ++ for (i=k+1; i <= p2; i++) { ++ if (X[i] == ZERO) continue; ++ else {z[3] += ONE; break; } ++ } ++ } ++ ++ c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10); ++ ++ *y = c*TWOM1032; ++ return; ++ ++#undef R ++} ++ ++/* Convert a multiple precision number *x into a double precision number *y. */ ++/* The result is correctly rounded to the nearest/even. *x is left unchanged */ ++ ++void __mp_dbl(const mp_no *x, double *y, int p) { ++#if 0 ++ int i,k; ++ double a,c,u,v,z[5]; ++#endif ++ ++ if (X[0] == ZERO) {*y = ZERO; return; } ++ ++ if (EX> -42) norm(x,y,p); ++ else if (EX==-42 && X[1]>=TWO10) norm(x,y,p); ++ else denorm(x,y,p); ++} ++ ++ ++/* dbl_mp() converts a double precision number x into a multiple precision */ ++/* number *y. If the precision p is too small the result is truncated. x is */ ++/* left unchanged. */ ++ ++void __dbl_mp(double x, mp_no *y, int p) { ++ ++ long i,n; ++ long p2 = p; ++ double u; ++ ++ /* Sign */ ++ if (x == ZERO) {Y[0] = ZERO; return; } ++ else if (x > ZERO) Y[0] = ONE; ++ else {Y[0] = MONE; x=-x; } ++ ++ /* Exponent */ ++ for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI; ++ for ( ; x < ONE; EY -= ONE) x *= RADIX; ++ ++ /* Digits */ ++ n=MIN(p2,4); ++ for (i=1; i<=n; i++) { ++ u = (x + TWO52) - TWO52; ++ if (u>x) u -= ONE; ++ Y[i] = u; x -= u; x *= RADIX; } ++ for ( ; i<=p2; i++) Y[i] = ZERO; ++ return; ++} ++ ++ ++/* add_magnitudes() adds the magnitudes of *x & *y assuming that */ ++/* abs(*x) >= abs(*y) > 0. */ ++/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */ ++/* No guard digit is used. The result equals the exact sum, truncated. */ ++/* *x & *y are left unchanged. */ ++ ++static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ ++ long i,j,k; ++ long p2 = p; ++ ++ EZ = EX; ++ ++ i=p2; j=p2+ EY - EX; k=p2+1; ++ ++ if (j<1) ++ {__cpy(x,z,p); return; } ++ else Z[k] = ZERO; ++ ++ for (; j>0; i--,j--) { ++ Z[k] += X[i] + Y[j]; ++ if (Z[k] >= RADIX) { ++ Z[k] -= RADIX; ++ Z[--k] = ONE; } ++ else ++ Z[--k] = ZERO; ++ } ++ ++ for (; i>0; i--) { ++ Z[k] += X[i]; ++ if (Z[k] >= RADIX) { ++ Z[k] -= RADIX; ++ Z[--k] = ONE; } ++ else ++ Z[--k] = ZERO; ++ } ++ ++ if (Z[1] == ZERO) { ++ for (i=1; i<=p2; i++) Z[i] = Z[i+1]; } ++ else EZ += ONE; ++} ++ ++ ++/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */ ++/* abs(*x) > abs(*y) > 0. */ ++/* The sign of the difference *z is undefined. x&y may overlap but not x&z */ ++/* or y&z. One guard digit is used. The error is less than one ulp. */ ++/* *x & *y are left unchanged. */ ++ ++static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ ++ long i,j,k; ++ long p2 = p; ++ ++ EZ = EX; ++ ++ if (EX == EY) { ++ i=j=k=p2; ++ Z[k] = Z[k+1] = ZERO; } ++ else { ++ j= EX - EY; ++ if (j > p2) {__cpy(x,z,p); return; } ++ else { ++ i=p2; j=p2+1-j; k=p2; ++ if (Y[j] > ZERO) { ++ Z[k+1] = RADIX - Y[j--]; ++ Z[k] = MONE; } ++ else { ++ Z[k+1] = ZERO; ++ Z[k] = ZERO; j--;} ++ } ++ } ++ ++ for (; j>0; i--,j--) { ++ Z[k] += (X[i] - Y[j]); ++ if (Z[k] < ZERO) { ++ Z[k] += RADIX; ++ Z[--k] = MONE; } ++ else ++ Z[--k] = ZERO; ++ } ++ ++ for (; i>0; i--) { ++ Z[k] += X[i]; ++ if (Z[k] < ZERO) { ++ Z[k] += RADIX; ++ Z[--k] = MONE; } ++ else ++ Z[--k] = ZERO; ++ } ++ ++ for (i=1; Z[i] == ZERO; i++) ; ++ EZ = EZ - i + 1; ++ for (k=1; i <= p2+1; ) ++ Z[k++] = Z[i++]; ++ for (; k <= p2; ) ++ Z[k++] = ZERO; ++ ++ return; ++} ++ ++ ++/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */ ++/* but not x&z or y&z. One guard digit is used. The error is less than */ ++/* one ulp. *x & *y are left unchanged. */ ++ ++void __add(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ ++ int n; ++ ++ if (X[0] == ZERO) {__cpy(y,z,p); return; } ++ else if (Y[0] == ZERO) {__cpy(x,z,p); return; } ++ ++ if (X[0] == Y[0]) { ++ if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } ++ else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; } ++ } ++ else { ++ if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } ++ else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; } ++ else Z[0] = ZERO; ++ } ++ return; ++} ++ ++ ++/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */ ++/* overlap but not x&z or y&z. One guard digit is used. The error is */ ++/* less than one ulp. *x & *y are left unchanged. */ ++ ++void __sub(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ ++ int n; ++ ++ if (X[0] == ZERO) {__cpy(y,z,p); Z[0] = -Z[0]; return; } ++ else if (Y[0] == ZERO) {__cpy(x,z,p); return; } ++ ++ if (X[0] != Y[0]) { ++ if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } ++ else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; } ++ } ++ else { ++ if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } ++ else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; } ++ else Z[0] = ZERO; ++ } ++ return; ++} ++ ++ ++/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */ ++/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */ ++/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */ ++/* *x & *y are left unchanged. */ ++ ++void __mul(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ ++ long i, i1, i2, j, k, k2; ++ long p2 = p; ++ double u, zk, zk2; ++ ++ /* Is z=0? */ ++ if (X[0]*Y[0]==ZERO) ++ { Z[0]=ZERO; return; } ++ ++ /* Multiply, add and carry */ ++ k2 = (p2<3) ? p2+p2 : p2+3; ++ zk = Z[k2]=ZERO; ++ for (k=k2; k>1; ) { ++ if (k > p2) {i1=k-p2; i2=p2+1; } ++ else {i1=1; i2=k; } ++#if 1 ++ /* rearange this inner loop to allow the fmadd instructions to be ++ independent and execute in parallel on processors that have ++ dual symetrical FP pipelines. */ ++ if (i1 < (i2-1)) ++ { ++ /* make sure we have at least 2 iterations */ ++ if (((i2 - i1) & 1L) == 1L) ++ { ++ /* Handle the odd iterations case. */ ++ zk2 = x->d[i2-1]*y->d[i1]; ++ } ++ else ++ zk2 = zero.d; ++ /* Do two multiply/adds per loop iteration, using independent ++ accumulators; zk and zk2. */ ++ for (i=i1,j=i2-1; id[i]*y->d[j]; ++ zk2 += x->d[i+1]*y->d[j-1]; ++ } ++ zk += zk2; /* final sum. */ ++ } ++ else ++ { ++ /* Special case when iterations is 1. */ ++ zk += x->d[i1]*y->d[i1]; ++ } ++#else ++ /* The orginal code. */ ++ for (i=i1,j=i2-1; i zk) u -= RADIX; ++ Z[k] = zk - u; ++ zk = u*RADIXI; ++ --k; ++ } ++ Z[k] = zk; ++ ++ /* Is there a carry beyond the most significant digit? */ ++ if (Z[1] == ZERO) { ++ for (i=1; i<=p2; i++) Z[i]=Z[i+1]; ++ EZ = EX + EY - 1; } ++ else ++ EZ = EX + EY; ++ ++ Z[0] = X[0] * Y[0]; ++ return; ++} ++ ++ ++/* Invert a multiple precision number. Set *y = 1 / *x. */ ++/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */ ++/* 2.001*r**(1-p) for p>3. */ ++/* *x=0 is not permissible. *x is left unchanged. */ ++ ++void __inv(const mp_no *x, mp_no *y, int p) { ++ long i; ++#if 0 ++ int l; ++#endif ++ double t; ++ mp_no z,w; ++ static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3, ++ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4}; ++ const mp_no mptwo = {1,{1.0,2.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,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.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}}; ++ ++ __cpy(x,&z,p); z.e=0; __mp_dbl(&z,&t,p); ++ t=ONE/t; __dbl_mp(t,y,p); EY -= EX; ++ ++ for (i=0; i3. *y=0 is not permissible. */ ++ ++void __dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) { ++ ++ mp_no w; ++ ++ if (X[0] == ZERO) Z[0] = ZERO; ++ else {__inv(y,&w,p); __mul(x,&w,z,p);} ++ return; ++} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/Implies +new file mode 100644 +index 0000000..a372141 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/Implies +@@ -0,0 +1,2 @@ ++powerpc/power4/fpu ++powerpc/power4 +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/Makefile +deleted file mode 100644 +index f487ed6..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/Makefile ++++ /dev/null +@@ -1,5 +0,0 @@ +-# Makefile fragment for POWER4/5/5+ with FPU. +- +-ifeq ($(subdir),math) +-CFLAGS-mpa.c += --param max-unroll-times=4 -funroll-loops -fpeel-loops +-endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c +deleted file mode 100644 +index d15680e..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/mpa.c ++++ /dev/null +@@ -1,548 +0,0 @@ +- +-/* +- * IBM Accurate Mathematical Library +- * written by International Business Machines Corp. +- * Copyright (C) 2001, 2006 Free Software Foundation +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU Lesser General Public License as published by +- * the Free Software Foundation; either version 2.1 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public License +- * along with this program; if not, see . +- */ +-/************************************************************************/ +-/* MODULE_NAME: mpa.c */ +-/* */ +-/* FUNCTIONS: */ +-/* mcr */ +-/* acr */ +-/* cr */ +-/* cpy */ +-/* cpymn */ +-/* norm */ +-/* denorm */ +-/* mp_dbl */ +-/* dbl_mp */ +-/* add_magnitudes */ +-/* sub_magnitudes */ +-/* add */ +-/* sub */ +-/* mul */ +-/* inv */ +-/* dvd */ +-/* */ +-/* Arithmetic functions for multiple precision numbers. */ +-/* Relative errors are bounded */ +-/************************************************************************/ +- +- +-#include "endian.h" +-#include "mpa.h" +-#include "mpa2.h" +-#include /* For MIN() */ +-/* mcr() compares the sizes of the mantissas of two multiple precision */ +-/* numbers. Mantissas are compared regardless of the signs of the */ +-/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */ +-/* disregarded. */ +-static int mcr(const mp_no *x, const mp_no *y, int p) { +- long i; +- long p2 = p; +- for (i=1; i<=p2; i++) { +- if (X[i] == Y[i]) continue; +- else if (X[i] > Y[i]) return 1; +- else return -1; } +- return 0; +-} +- +- +- +-/* acr() compares the absolute values of two multiple precision numbers */ +-int __acr(const mp_no *x, const mp_no *y, int p) { +- long i; +- +- if (X[0] == ZERO) { +- if (Y[0] == ZERO) i= 0; +- else i=-1; +- } +- else if (Y[0] == ZERO) i= 1; +- else { +- if (EX > EY) i= 1; +- else if (EX < EY) i=-1; +- else i= mcr(x,y,p); +- } +- +- return i; +-} +- +- +-/* cr90 compares the values of two multiple precision numbers */ +-int __cr(const mp_no *x, const mp_no *y, int p) { +- int i; +- +- if (X[0] > Y[0]) i= 1; +- else if (X[0] < Y[0]) i=-1; +- else if (X[0] < ZERO ) i= __acr(y,x,p); +- else i= __acr(x,y,p); +- +- return i; +-} +- +- +-/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */ +-void __cpy(const mp_no *x, mp_no *y, int p) { +- long i; +- +- EY = EX; +- for (i=0; i <= p; i++) Y[i] = X[i]; +- +- return; +-} +- +- +-/* Copy a multiple precision number x of precision m into a */ +-/* multiple precision number y of precision n. In case n>m, */ +-/* the digits of y beyond the m'th are set to zero. In case */ +-/* n= 2**(-1022))) */ +-static void norm(const mp_no *x, double *y, int p) +-{ +- #define R radixi.d +- long i; +-#if 0 +- int k; +-#endif +- double a,c,u,v,z[5]; +- if (p<5) { +- if (p==1) c = X[1]; +- else if (p==2) c = X[1] + R* X[2]; +- else if (p==3) c = X[1] + R*(X[2] + R* X[3]); +- else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]); +- } +- else { +- for (a=ONE, z[1]=X[1]; z[1] < TWO23; ) +- {a *= TWO; z[1] *= TWO; } +- +- for (i=2; i<5; i++) { +- z[i] = X[i]*a; +- u = (z[i] + CUTTER)-CUTTER; +- if (u > z[i]) u -= RADIX; +- z[i] -= u; +- z[i-1] += u*RADIXI; +- } +- +- u = (z[3] + TWO71) - TWO71; +- if (u > z[3]) u -= TWO19; +- v = z[3]-u; +- +- if (v == TWO18) { +- if (z[4] == ZERO) { +- for (i=5; i <= p; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } +- } +- } +- else z[3] += ONE; +- } +- +- c = (z[1] + R *(z[2] + R * z[3]))/a; +- } +- +- c *= X[0]; +- +- for (i=1; iEX; i--) c *= RADIXI; +- +- *y = c; +- return; +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision */ +-/* number *y, denormalized case (|x| < 2**(-1022))) */ +-static void denorm(const mp_no *x, double *y, int p) +-{ +- long i,k; +- long p2 = p; +- double c,u,z[5]; +-#if 0 +- double a,v; +-#endif +- +-#define R radixi.d +- if (EX<-44 || (EX==-44 && X[1] z[3]) u -= TWO5; +- +- if (u==z[3]) { +- for (i=k+1; i <= p2; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } +- } +- } +- +- c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10); +- +- *y = c*TWOM1032; +- return; +- +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision number *y. */ +-/* The result is correctly rounded to the nearest/even. *x is left unchanged */ +- +-void __mp_dbl(const mp_no *x, double *y, int p) { +-#if 0 +- int i,k; +- double a,c,u,v,z[5]; +-#endif +- +- if (X[0] == ZERO) {*y = ZERO; return; } +- +- if (EX> -42) norm(x,y,p); +- else if (EX==-42 && X[1]>=TWO10) norm(x,y,p); +- else denorm(x,y,p); +-} +- +- +-/* dbl_mp() converts a double precision number x into a multiple precision */ +-/* number *y. If the precision p is too small the result is truncated. x is */ +-/* left unchanged. */ +- +-void __dbl_mp(double x, mp_no *y, int p) { +- +- long i,n; +- long p2 = p; +- double u; +- +- /* Sign */ +- if (x == ZERO) {Y[0] = ZERO; return; } +- else if (x > ZERO) Y[0] = ONE; +- else {Y[0] = MONE; x=-x; } +- +- /* Exponent */ +- for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI; +- for ( ; x < ONE; EY -= ONE) x *= RADIX; +- +- /* Digits */ +- n=MIN(p2,4); +- for (i=1; i<=n; i++) { +- u = (x + TWO52) - TWO52; +- if (u>x) u -= ONE; +- Y[i] = u; x -= u; x *= RADIX; } +- for ( ; i<=p2; i++) Y[i] = ZERO; +- return; +-} +- +- +-/* add_magnitudes() adds the magnitudes of *x & *y assuming that */ +-/* abs(*x) >= abs(*y) > 0. */ +-/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */ +-/* No guard digit is used. The result equals the exact sum, truncated. */ +-/* *x & *y are left unchanged. */ +- +-static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i,j,k; +- long p2 = p; +- +- EZ = EX; +- +- i=p2; j=p2+ EY - EX; k=p2+1; +- +- if (j<1) +- {__cpy(x,z,p); return; } +- else Z[k] = ZERO; +- +- for (; j>0; i--,j--) { +- Z[k] += X[i] + Y[j]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- if (Z[1] == ZERO) { +- for (i=1; i<=p2; i++) Z[i] = Z[i+1]; } +- else EZ += ONE; +-} +- +- +-/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */ +-/* abs(*x) > abs(*y) > 0. */ +-/* The sign of the difference *z is undefined. x&y may overlap but not x&z */ +-/* or y&z. One guard digit is used. The error is less than one ulp. */ +-/* *x & *y are left unchanged. */ +- +-static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i,j,k; +- long p2 = p; +- +- EZ = EX; +- +- if (EX == EY) { +- i=j=k=p2; +- Z[k] = Z[k+1] = ZERO; } +- else { +- j= EX - EY; +- if (j > p2) {__cpy(x,z,p); return; } +- else { +- i=p2; j=p2+1-j; k=p2; +- if (Y[j] > ZERO) { +- Z[k+1] = RADIX - Y[j--]; +- Z[k] = MONE; } +- else { +- Z[k+1] = ZERO; +- Z[k] = ZERO; j--;} +- } +- } +- +- for (; j>0; i--,j--) { +- Z[k] += (X[i] - Y[j]); +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (i=1; Z[i] == ZERO; i++) ; +- EZ = EZ - i + 1; +- for (k=1; i <= p2+1; ) +- Z[k++] = Z[i++]; +- for (; k <= p2; ) +- Z[k++] = ZERO; +- +- return; +-} +- +- +-/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */ +-/* but not x&z or y&z. One guard digit is used. The error is less than */ +-/* one ulp. *x & *y are left unchanged. */ +- +-void __add(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int n; +- +- if (X[0] == ZERO) {__cpy(y,z,p); return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } +- +- if (X[0] == Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- else Z[0] = ZERO; +- } +- return; +-} +- +- +-/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */ +-/* overlap but not x&z or y&z. One guard digit is used. The error is */ +-/* less than one ulp. *x & *y are left unchanged. */ +- +-void __sub(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int n; +- +- if (X[0] == ZERO) {__cpy(y,z,p); Z[0] = -Z[0]; return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } +- +- if (X[0] != Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- else Z[0] = ZERO; +- } +- return; +-} +- +- +-/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */ +-/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */ +-/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */ +-/* *x & *y are left unchanged. */ +- +-void __mul(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i, i1, i2, j, k, k2; +- long p2 = p; +- double u, zk, zk2; +- +- /* Is z=0? */ +- if (X[0]*Y[0]==ZERO) +- { Z[0]=ZERO; return; } +- +- /* Multiply, add and carry */ +- k2 = (p2<3) ? p2+p2 : p2+3; +- zk = Z[k2]=ZERO; +- for (k=k2; k>1; ) { +- if (k > p2) {i1=k-p2; i2=p2+1; } +- else {i1=1; i2=k; } +-#if 1 +- /* rearange this inner loop to allow the fmadd instructions to be +- independent and execute in parallel on processors that have +- dual symetrical FP pipelines. */ +- if (i1 < (i2-1)) +- { +- /* make sure we have at least 2 iterations */ +- if (((i2 - i1) & 1L) == 1L) +- { +- /* Handle the odd iterations case. */ +- zk2 = x->d[i2-1]*y->d[i1]; +- } +- else +- zk2 = zero.d; +- /* Do two multiply/adds per loop iteration, using independent +- accumulators; zk and zk2. */ +- for (i=i1,j=i2-1; id[i]*y->d[j]; +- zk2 += x->d[i+1]*y->d[j-1]; +- } +- zk += zk2; /* final sum. */ +- } +- else +- { +- /* Special case when iterations is 1. */ +- zk += x->d[i1]*y->d[i1]; +- } +-#else +- /* The orginal code. */ +- for (i=i1,j=i2-1; i zk) u -= RADIX; +- Z[k] = zk - u; +- zk = u*RADIXI; +- --k; +- } +- Z[k] = zk; +- +- /* Is there a carry beyond the most significant digit? */ +- if (Z[1] == ZERO) { +- for (i=1; i<=p2; i++) Z[i]=Z[i+1]; +- EZ = EX + EY - 1; } +- else +- EZ = EX + EY; +- +- Z[0] = X[0] * Y[0]; +- return; +-} +- +- +-/* Invert a multiple precision number. Set *y = 1 / *x. */ +-/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */ +-/* 2.001*r**(1-p) for p>3. */ +-/* *x=0 is not permissible. *x is left unchanged. */ +- +-void __inv(const mp_no *x, mp_no *y, int p) { +- long i; +-#if 0 +- int l; +-#endif +- double t; +- mp_no z,w; +- static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3, +- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4}; +- const mp_no mptwo = {1,{1.0,2.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,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.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}}; +- +- __cpy(x,&z,p); z.e=0; __mp_dbl(&z,&t,p); +- t=ONE/t; __dbl_mp(t,y,p); EY -= EX; +- +- for (i=0; i3. *y=0 is not permissible. */ +- +-void __dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- mp_no w; +- +- if (X[0] == ZERO) Z[0] = ZERO; +- else {__inv(y,&w,p); __mul(x,&w,z,p);} +- return; +-} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/Implies +new file mode 100644 +index 0000000..a372141 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/Implies +@@ -0,0 +1,2 @@ ++powerpc/power4/fpu ++powerpc/power4 +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/Makefile +deleted file mode 100644 +index f8bb3ef..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/Makefile ++++ /dev/null +@@ -1,5 +0,0 @@ +-# Makefile fragment for POWER4/5/5+ platforms with FPU. +- +-ifeq ($(subdir),math) +-CFLAGS-mpa.c += --param max-unroll-times=4 -funroll-loops -fpeel-loops +-endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c +deleted file mode 100644 +index d15680e..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/mpa.c ++++ /dev/null +@@ -1,548 +0,0 @@ +- +-/* +- * IBM Accurate Mathematical Library +- * written by International Business Machines Corp. +- * Copyright (C) 2001, 2006 Free Software Foundation +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU Lesser General Public License as published by +- * the Free Software Foundation; either version 2.1 of the License, or +- * (at your option) any later version. +- * +- * This program is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU Lesser General Public License for more details. +- * +- * You should have received a copy of the GNU Lesser General Public License +- * along with this program; if not, see . +- */ +-/************************************************************************/ +-/* MODULE_NAME: mpa.c */ +-/* */ +-/* FUNCTIONS: */ +-/* mcr */ +-/* acr */ +-/* cr */ +-/* cpy */ +-/* cpymn */ +-/* norm */ +-/* denorm */ +-/* mp_dbl */ +-/* dbl_mp */ +-/* add_magnitudes */ +-/* sub_magnitudes */ +-/* add */ +-/* sub */ +-/* mul */ +-/* inv */ +-/* dvd */ +-/* */ +-/* Arithmetic functions for multiple precision numbers. */ +-/* Relative errors are bounded */ +-/************************************************************************/ +- +- +-#include "endian.h" +-#include "mpa.h" +-#include "mpa2.h" +-#include /* For MIN() */ +-/* mcr() compares the sizes of the mantissas of two multiple precision */ +-/* numbers. Mantissas are compared regardless of the signs of the */ +-/* numbers, even if x->d[0] or y->d[0] are zero. Exponents are also */ +-/* disregarded. */ +-static int mcr(const mp_no *x, const mp_no *y, int p) { +- long i; +- long p2 = p; +- for (i=1; i<=p2; i++) { +- if (X[i] == Y[i]) continue; +- else if (X[i] > Y[i]) return 1; +- else return -1; } +- return 0; +-} +- +- +- +-/* acr() compares the absolute values of two multiple precision numbers */ +-int __acr(const mp_no *x, const mp_no *y, int p) { +- long i; +- +- if (X[0] == ZERO) { +- if (Y[0] == ZERO) i= 0; +- else i=-1; +- } +- else if (Y[0] == ZERO) i= 1; +- else { +- if (EX > EY) i= 1; +- else if (EX < EY) i=-1; +- else i= mcr(x,y,p); +- } +- +- return i; +-} +- +- +-/* cr90 compares the values of two multiple precision numbers */ +-int __cr(const mp_no *x, const mp_no *y, int p) { +- int i; +- +- if (X[0] > Y[0]) i= 1; +- else if (X[0] < Y[0]) i=-1; +- else if (X[0] < ZERO ) i= __acr(y,x,p); +- else i= __acr(x,y,p); +- +- return i; +-} +- +- +-/* Copy a multiple precision number. Set *y=*x. x=y is permissible. */ +-void __cpy(const mp_no *x, mp_no *y, int p) { +- long i; +- +- EY = EX; +- for (i=0; i <= p; i++) Y[i] = X[i]; +- +- return; +-} +- +- +-/* Copy a multiple precision number x of precision m into a */ +-/* multiple precision number y of precision n. In case n>m, */ +-/* the digits of y beyond the m'th are set to zero. In case */ +-/* n= 2**(-1022))) */ +-static void norm(const mp_no *x, double *y, int p) +-{ +- #define R radixi.d +- long i; +-#if 0 +- int k; +-#endif +- double a,c,u,v,z[5]; +- if (p<5) { +- if (p==1) c = X[1]; +- else if (p==2) c = X[1] + R* X[2]; +- else if (p==3) c = X[1] + R*(X[2] + R* X[3]); +- else if (p==4) c =(X[1] + R* X[2]) + R*R*(X[3] + R*X[4]); +- } +- else { +- for (a=ONE, z[1]=X[1]; z[1] < TWO23; ) +- {a *= TWO; z[1] *= TWO; } +- +- for (i=2; i<5; i++) { +- z[i] = X[i]*a; +- u = (z[i] + CUTTER)-CUTTER; +- if (u > z[i]) u -= RADIX; +- z[i] -= u; +- z[i-1] += u*RADIXI; +- } +- +- u = (z[3] + TWO71) - TWO71; +- if (u > z[3]) u -= TWO19; +- v = z[3]-u; +- +- if (v == TWO18) { +- if (z[4] == ZERO) { +- for (i=5; i <= p; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } +- } +- } +- else z[3] += ONE; +- } +- +- c = (z[1] + R *(z[2] + R * z[3]))/a; +- } +- +- c *= X[0]; +- +- for (i=1; iEX; i--) c *= RADIXI; +- +- *y = c; +- return; +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision */ +-/* number *y, denormalized case (|x| < 2**(-1022))) */ +-static void denorm(const mp_no *x, double *y, int p) +-{ +- long i,k; +- long p2 = p; +- double c,u,z[5]; +-#if 0 +- double a,v; +-#endif +- +-#define R radixi.d +- if (EX<-44 || (EX==-44 && X[1] z[3]) u -= TWO5; +- +- if (u==z[3]) { +- for (i=k+1; i <= p2; i++) { +- if (X[i] == ZERO) continue; +- else {z[3] += ONE; break; } +- } +- } +- +- c = X[0]*((z[1] + R*(z[2] + R*z[3])) - TWO10); +- +- *y = c*TWOM1032; +- return; +- +-#undef R +-} +- +-/* Convert a multiple precision number *x into a double precision number *y. */ +-/* The result is correctly rounded to the nearest/even. *x is left unchanged */ +- +-void __mp_dbl(const mp_no *x, double *y, int p) { +-#if 0 +- int i,k; +- double a,c,u,v,z[5]; +-#endif +- +- if (X[0] == ZERO) {*y = ZERO; return; } +- +- if (EX> -42) norm(x,y,p); +- else if (EX==-42 && X[1]>=TWO10) norm(x,y,p); +- else denorm(x,y,p); +-} +- +- +-/* dbl_mp() converts a double precision number x into a multiple precision */ +-/* number *y. If the precision p is too small the result is truncated. x is */ +-/* left unchanged. */ +- +-void __dbl_mp(double x, mp_no *y, int p) { +- +- long i,n; +- long p2 = p; +- double u; +- +- /* Sign */ +- if (x == ZERO) {Y[0] = ZERO; return; } +- else if (x > ZERO) Y[0] = ONE; +- else {Y[0] = MONE; x=-x; } +- +- /* Exponent */ +- for (EY=ONE; x >= RADIX; EY += ONE) x *= RADIXI; +- for ( ; x < ONE; EY -= ONE) x *= RADIX; +- +- /* Digits */ +- n=MIN(p2,4); +- for (i=1; i<=n; i++) { +- u = (x + TWO52) - TWO52; +- if (u>x) u -= ONE; +- Y[i] = u; x -= u; x *= RADIX; } +- for ( ; i<=p2; i++) Y[i] = ZERO; +- return; +-} +- +- +-/* add_magnitudes() adds the magnitudes of *x & *y assuming that */ +-/* abs(*x) >= abs(*y) > 0. */ +-/* The sign of the sum *z is undefined. x&y may overlap but not x&z or y&z. */ +-/* No guard digit is used. The result equals the exact sum, truncated. */ +-/* *x & *y are left unchanged. */ +- +-static void add_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i,j,k; +- long p2 = p; +- +- EZ = EX; +- +- i=p2; j=p2+ EY - EX; k=p2+1; +- +- if (j<1) +- {__cpy(x,z,p); return; } +- else Z[k] = ZERO; +- +- for (; j>0; i--,j--) { +- Z[k] += X[i] + Y[j]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] >= RADIX) { +- Z[k] -= RADIX; +- Z[--k] = ONE; } +- else +- Z[--k] = ZERO; +- } +- +- if (Z[1] == ZERO) { +- for (i=1; i<=p2; i++) Z[i] = Z[i+1]; } +- else EZ += ONE; +-} +- +- +-/* sub_magnitudes() subtracts the magnitudes of *x & *y assuming that */ +-/* abs(*x) > abs(*y) > 0. */ +-/* The sign of the difference *z is undefined. x&y may overlap but not x&z */ +-/* or y&z. One guard digit is used. The error is less than one ulp. */ +-/* *x & *y are left unchanged. */ +- +-static void sub_magnitudes(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i,j,k; +- long p2 = p; +- +- EZ = EX; +- +- if (EX == EY) { +- i=j=k=p2; +- Z[k] = Z[k+1] = ZERO; } +- else { +- j= EX - EY; +- if (j > p2) {__cpy(x,z,p); return; } +- else { +- i=p2; j=p2+1-j; k=p2; +- if (Y[j] > ZERO) { +- Z[k+1] = RADIX - Y[j--]; +- Z[k] = MONE; } +- else { +- Z[k+1] = ZERO; +- Z[k] = ZERO; j--;} +- } +- } +- +- for (; j>0; i--,j--) { +- Z[k] += (X[i] - Y[j]); +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (; i>0; i--) { +- Z[k] += X[i]; +- if (Z[k] < ZERO) { +- Z[k] += RADIX; +- Z[--k] = MONE; } +- else +- Z[--k] = ZERO; +- } +- +- for (i=1; Z[i] == ZERO; i++) ; +- EZ = EZ - i + 1; +- for (k=1; i <= p2+1; ) +- Z[k++] = Z[i++]; +- for (; k <= p2; ) +- Z[k++] = ZERO; +- +- return; +-} +- +- +-/* Add two multiple precision numbers. Set *z = *x + *y. x&y may overlap */ +-/* but not x&z or y&z. One guard digit is used. The error is less than */ +-/* one ulp. *x & *y are left unchanged. */ +- +-void __add(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int n; +- +- if (X[0] == ZERO) {__cpy(y,z,p); return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } +- +- if (X[0] == Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = Y[0]; } +- else Z[0] = ZERO; +- } +- return; +-} +- +- +-/* Subtract two multiple precision numbers. *z is set to *x - *y. x&y may */ +-/* overlap but not x&z or y&z. One guard digit is used. The error is */ +-/* less than one ulp. *x & *y are left unchanged. */ +- +-void __sub(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- int n; +- +- if (X[0] == ZERO) {__cpy(y,z,p); Z[0] = -Z[0]; return; } +- else if (Y[0] == ZERO) {__cpy(x,z,p); return; } +- +- if (X[0] != Y[0]) { +- if (__acr(x,y,p) > 0) {add_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else {add_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- } +- else { +- if ((n=__acr(x,y,p)) == 1) {sub_magnitudes(x,y,z,p); Z[0] = X[0]; } +- else if (n == -1) {sub_magnitudes(y,x,z,p); Z[0] = -Y[0]; } +- else Z[0] = ZERO; +- } +- return; +-} +- +- +-/* Multiply two multiple precision numbers. *z is set to *x * *y. x&y */ +-/* may overlap but not x&z or y&z. In case p=1,2,3 the exact result is */ +-/* truncated to p digits. In case p>3 the error is bounded by 1.001 ulp. */ +-/* *x & *y are left unchanged. */ +- +-void __mul(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- long i, i1, i2, j, k, k2; +- long p2 = p; +- double u, zk, zk2; +- +- /* Is z=0? */ +- if (X[0]*Y[0]==ZERO) +- { Z[0]=ZERO; return; } +- +- /* Multiply, add and carry */ +- k2 = (p2<3) ? p2+p2 : p2+3; +- zk = Z[k2]=ZERO; +- for (k=k2; k>1; ) { +- if (k > p2) {i1=k-p2; i2=p2+1; } +- else {i1=1; i2=k; } +-#if 1 +- /* rearange this inner loop to allow the fmadd instructions to be +- independent and execute in parallel on processors that have +- dual symetrical FP pipelines. */ +- if (i1 < (i2-1)) +- { +- /* make sure we have at least 2 iterations */ +- if (((i2 - i1) & 1L) == 1L) +- { +- /* Handle the odd iterations case. */ +- zk2 = x->d[i2-1]*y->d[i1]; +- } +- else +- zk2 = zero.d; +- /* Do two multiply/adds per loop iteration, using independent +- accumulators; zk and zk2. */ +- for (i=i1,j=i2-1; id[i]*y->d[j]; +- zk2 += x->d[i+1]*y->d[j-1]; +- } +- zk += zk2; /* final sum. */ +- } +- else +- { +- /* Special case when iterations is 1. */ +- zk += x->d[i1]*y->d[i1]; +- } +-#else +- /* The orginal code. */ +- for (i=i1,j=i2-1; i zk) u -= RADIX; +- Z[k] = zk - u; +- zk = u*RADIXI; +- --k; +- } +- Z[k] = zk; +- +- /* Is there a carry beyond the most significant digit? */ +- if (Z[1] == ZERO) { +- for (i=1; i<=p2; i++) Z[i]=Z[i+1]; +- EZ = EX + EY - 1; } +- else +- EZ = EX + EY; +- +- Z[0] = X[0] * Y[0]; +- return; +-} +- +- +-/* Invert a multiple precision number. Set *y = 1 / *x. */ +-/* Relative error bound = 1.001*r**(1-p) for p=2, 1.063*r**(1-p) for p=3, */ +-/* 2.001*r**(1-p) for p>3. */ +-/* *x=0 is not permissible. *x is left unchanged. */ +- +-void __inv(const mp_no *x, mp_no *y, int p) { +- long i; +-#if 0 +- int l; +-#endif +- double t; +- mp_no z,w; +- static const int np1[] = {0,0,0,0,1,2,2,2,2,3,3,3,3,3,3,3,3,3, +- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4}; +- const mp_no mptwo = {1,{1.0,2.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,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.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}}; +- +- __cpy(x,&z,p); z.e=0; __mp_dbl(&z,&t,p); +- t=ONE/t; __dbl_mp(t,y,p); EY -= EX; +- +- for (i=0; i3. *y=0 is not permissible. */ +- +-void __dvd(const mp_no *x, const mp_no *y, mp_no *z, int p) { +- +- mp_no w; +- +- if (X[0] == ZERO) Z[0] = ZERO; +- else {__inv(y,&w,p); __mul(x,&w,z,p);} +- return; +-} +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-libm-3.patch b/SOURCES/glibc-rh731833-libm-3.patch new file mode 100644 index 00000000..b9d710ae --- /dev/null +++ b/SOURCES/glibc-rh731833-libm-3.patch @@ -0,0 +1,268 @@ +From c00f26c0eaba5a9680aac0f98de4b6e385a8cb82 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 8 Mar 2013 11:07:15 -0300 +Subject: [PATCH 18/42] PowerPC: unify math_ldbl.h implementations + +This patch removes redudant definition from PowerPC specific +math_ldbl, using the definitions from ieee754 math_ldbl.h. +(backported from commit edf66e57fc2bac083ecc9756a5fe47f9041ed3bb) +--- + sysdeps/ieee754/ldbl-128ibm/math_ldbl.h | 10 +- + sysdeps/powerpc/Implies | 1 + + sysdeps/powerpc/fpu/math_ldbl.h | 171 ++------------------------------ + sysdeps/unix/sysv/linux/powerpc/Implies | 4 - + 5 files changed, 34 insertions(+), 168 deletions(-) + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/Implies + +diff --git glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +index be9ac71..1cce1fc 100644 +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/math_ldbl.h +@@ -125,7 +125,7 @@ ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) + /* Handy utility functions to pack/unpack/cononicalize and find the nearbyint + of long double implemented as double double. */ + static inline long double +-ldbl_pack (double a, double aa) ++default_ldbl_pack (double a, double aa) + { + union ibm_extended_long_double u; + u.dd[0] = a; +@@ -134,7 +134,7 @@ ldbl_pack (double a, double aa) + } + + static inline void +-ldbl_unpack (long double l, double *a, double *aa) ++default_ldbl_unpack (long double l, double *a, double *aa) + { + union ibm_extended_long_double u; + u.d = l; +@@ -142,6 +142,12 @@ ldbl_unpack (long double l, double *a, double *aa) + *aa = u.dd[1]; + } + ++#ifndef ldbl_pack ++# define ldbl_pack default_ldbl_pack ++#endif ++#ifndef ldbl_unpack ++# define ldbl_unpack default_ldbl_unpack ++#endif + + /* Convert a finite long double to canonical form. + Does not handle +/-Inf properly. */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/Implies glibc-2.17-c758a686/sysdeps/powerpc/Implies +index 7ccf9a7..78dba95 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/Implies ++++ glibc-2.17-c758a686/sysdeps/powerpc/Implies +@@ -1,4 +1,5 @@ + # On PowerPC we use the IBM extended long double format. + ieee754/ldbl-128ibm ++ieee754/ldbl-opt + ieee754/dbl-64 + ieee754/flt-32 +diff --git glibc-2.17-c758a686/sysdeps/powerpc/fpu/math_ldbl.h glibc-2.17-c758a686/sysdeps/powerpc/fpu/math_ldbl.h +index 6cd6d0b..36378c0 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/math_ldbl.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/math_ldbl.h +@@ -2,132 +2,12 @@ + #error "Never use directly; include instead." + #endif + +-#include +-#include +- +-static inline void +-ldbl_extract_mantissa (int64_t *hi64, u_int64_t *lo64, int *exp, long double x) +-{ +- /* We have 105 bits of mantissa plus one implicit digit. Since +- 106 bits are representable we use the first implicit digit for +- the number before the decimal point and the second implicit bit +- as bit 53 of the mantissa. */ +- unsigned long long hi, lo; +- int ediff; +- union ibm_extended_long_double eldbl; +- eldbl.d = x; +- *exp = eldbl.ieee.exponent - IBM_EXTENDED_LONG_DOUBLE_BIAS; +- +- lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; +- hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; +- /* If the lower double is not a denomal or zero then set the hidden +- 53rd bit. */ +- if (eldbl.ieee.exponent2 > 0x001) +- { +- lo |= (1ULL << 52); +- lo = lo << 7; /* pre-shift lo to match ieee854. */ +- /* The lower double is normalized separately from the upper. We +- may need to adjust the lower manitissa to reflect this. */ +- ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; +- if (ediff > 53) +- lo = lo >> (ediff-53); +- } +- hi |= (1ULL << 52); +- +- if ((eldbl.ieee.negative != eldbl.ieee.negative2) +- && ((eldbl.ieee.exponent2 != 0) && (lo != 0LL))) +- { +- hi--; +- lo = (1ULL << 60) - lo; +- if (hi < (1ULL << 52)) +- { +- /* we have a borrow from the hidden bit, so shift left 1. */ +- hi = (hi << 1) | (lo >> 59); +- lo = 0xfffffffffffffffLL & (lo << 1); +- *exp = *exp - 1; +- } +- } +- *lo64 = (hi << 60) | lo; +- *hi64 = hi >> 4; +-} +- +-static inline long double +-ldbl_insert_mantissa (int sign, int exp, int64_t hi64, u_int64_t lo64) +-{ +- union ibm_extended_long_double u; +- unsigned long hidden2, lzcount; +- unsigned long long hi, lo; +- +- u.ieee.negative = sign; +- u.ieee.negative2 = sign; +- u.ieee.exponent = exp + IBM_EXTENDED_LONG_DOUBLE_BIAS; +- u.ieee.exponent2 = exp-53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; +- /* Expect 113 bits (112 bits + hidden) right justified in two longs. +- The low order 53 bits (52 + hidden) go into the lower double */ +- lo = (lo64 >> 7)& ((1ULL << 53) - 1); +- hidden2 = (lo64 >> 59) & 1ULL; +- /* The high order 53 bits (52 + hidden) go into the upper double */ +- hi = (lo64 >> 60) & ((1ULL << 11) - 1); +- hi |= (hi64 << 4); +- +- if (lo != 0LL) +- { +- /* hidden2 bit of low double controls rounding of the high double. +- If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) +- plus change the sign of the low double to compensate. */ +- if (hidden2) +- { +- hi++; +- u.ieee.negative2 = !sign; +- lo = (1ULL << 53) - lo; +- } +- /* The hidden bit of the lo mantissa is zero so we need to +- normalize the it for the low double. Shift it left until the +- hidden bit is '1' then adjust the 2nd exponent accordingly. */ +- +- if (sizeof (lo) == sizeof (long)) +- lzcount = __builtin_clzl (lo); +- else if ((lo >> 32) != 0) +- lzcount = __builtin_clzl ((long) (lo >> 32)); +- else +- lzcount = __builtin_clzl ((long) lo) + 32; +- lzcount = lzcount - 11; +- if (lzcount > 0) +- { +- int expnt2 = u.ieee.exponent2 - lzcount; +- if (expnt2 >= 1) +- { +- /* Not denormal. Normalize and set low exponent. */ +- lo = lo << lzcount; +- u.ieee.exponent2 = expnt2; +- } +- else +- { +- /* Is denormal. */ +- lo = lo << (lzcount + expnt2); +- u.ieee.exponent2 = 0; +- } +- } +- } +- else +- { +- u.ieee.negative2 = 0; +- u.ieee.exponent2 = 0; +- } +- +- u.ieee.mantissa3 = lo & ((1ULL << 32) - 1); +- u.ieee.mantissa2 = (lo >> 32) & ((1ULL << 20) - 1); +- u.ieee.mantissa1 = hi & ((1ULL << 32) - 1); +- u.ieee.mantissa0 = (hi >> 32) & ((1ULL << 20) - 1); +- return u.d; +-} +- +-/* gcc generates disgusting code to pack and unpack long doubles. +- This tells gcc that pack/unpack is really a nop. We use fr1/fr2 +- because those are the regs used to pass/return a single +- long double arg. */ ++/* GCC does not optimize the default ldbl_pack code to not spill register ++ in the stack. The following optimization tells gcc that pack/unpack ++ is really a nop. We use fr1/fr2 because those are the regs used to ++ pass/return a single long double arg. */ + static inline long double +-ldbl_pack (double a, double aa) ++ldbl_pack_ppc (double a, double aa) + { + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); +@@ -139,7 +19,7 @@ ldbl_pack (double a, double aa) + } + + static inline void +-ldbl_unpack (long double l, double *a, double *aa) ++ldbl_unpack_ppc (long double l, double *a, double *aa) + { + register long double x __asm__ ("fr1"); + register double xh __asm__ ("fr1"); +@@ -150,40 +30,7 @@ ldbl_unpack (long double l, double *a, double *aa) + *aa = xl; + } + ++#define ldbl_pack ldbl_pack_ppc ++#define ldbl_unpack ldbl_unpack_ppc + +-/* Convert a finite long double to canonical form. +- Does not handle +/-Inf properly. */ +-static inline void +-ldbl_canonicalize (double *a, double *aa) +-{ +- double xh, xl; +- +- xh = *a + *aa; +- xl = (*a - xh) + *aa; +- *a = xh; +- *aa = xl; +-} +- +-/* Simple inline nearbyint (double) function . +- Only works in the default rounding mode +- but is useful in long double rounding functions. */ +-static inline double +-ldbl_nearbyint (double a) +-{ +- double two52 = 0x10000000000000LL; +- +- if (__builtin_expect ((__builtin_fabs (a) < two52), 1)) +- { +- if (__builtin_expect ((a > 0.0), 1)) +- { +- a += two52; +- a -= two52; +- } +- else if (__builtin_expect ((a < 0.0), 1)) +- { +- a = two52 - a; +- a = -(a - two52); +- } +- } +- return a; +-} ++#include +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Implies +deleted file mode 100644 +index ff27cdb..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Implies ++++ /dev/null +@@ -1,4 +0,0 @@ +-# Make sure these routines come before ldbl-opt. +-ieee754/ldbl-128ibm +-# These supply the ABI compatibility for when long double was double. +-ieee754/ldbl-opt +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-libm-4.patch b/SOURCES/glibc-rh731833-libm-4.patch new file mode 100644 index 00000000..dc37caa4 --- /dev/null +++ b/SOURCES/glibc-rh731833-libm-4.patch @@ -0,0 +1,53 @@ +Combination of the following two commits: + +From 45045c44fabde9152ab1a0b4ed06419a3621f535 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Thu, 21 Mar 2013 14:15:45 -0300 +Subject: [PATCH 20/42] PowerPC: fix sqrtl ABI issue + +This patch fixes a sqrtl ABI issue when building for powerpc64. +(cherry picked from commit b5784d95bb94eda59b08aca735406908e209f638) + +From dad835a11f370afd2dae4bac554fa64fac5a8c6e Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Tue, 26 Mar 2013 10:01:57 -0300 +Subject: [PATCH 21/42] PowerPC: fix libm ABI issue for llroundl (cherry + picked from commit + fce14d4e9c6e08ad8c825fe88d8cbdac5c739565) + +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/s_llround.c 2013-08-06 17:45:56.719534470 +0530 +@@ -17,6 +17,7 @@ + . */ + + #include ++#include + + /* I think that what this routine is supposed to do is round a value + to the nearest integer, with values exactly on the boundary rounded +@@ -47,3 +48,6 @@ weak_alias (__llround, llround) + strong_alias (__llround, __llroundl) + weak_alias (__llround, llroundl) + #endif ++#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_1) ++compat_symbol (libm, __llround, llroundl, GLIBC_2_1); ++#endif +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrt.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrt.c +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrt.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrt.c 2013-08-06 17:45:53.459534613 +0530 +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + + double + __sqrt (double x) /* wrapper sqrt */ +@@ -42,3 +43,6 @@ weak_alias (__sqrt, sqrt) + #ifdef NO_LONG_DOUBLE + strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl) + #endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0); ++#endif diff --git a/SOURCES/glibc-rh731833-libm-5.patch b/SOURCES/glibc-rh731833-libm-5.patch new file mode 100644 index 00000000..e74225bd --- /dev/null +++ b/SOURCES/glibc-rh731833-libm-5.patch @@ -0,0 +1,113 @@ +From 987322bc0b170570a7bd539480252453fcc7a6f5 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 29 Mar 2013 18:15:28 -0500 +Subject: [PATCH 23/42] PowerPC: remove branch prediction from rint + implementation + +The branch prediction hints is actually hurts performance in this case. +The assembly implementation make two assumptions: 1. 'fabs (x) < 2^52' +is unlikely and 2. 'x > 0.0' is unlike (if 1. is true). Since it a +general floating point function, expected input is not bounded and then +it is better to let the hardware handle the branches. + +(backported from commit 60c414c346a1d5ef0510ffbdc0ab75f288ee4d3f) + +This backport does not include the benchmark tests from the original +commit. +--- + sysdeps/powerpc/powerpc32/fpu/s_rint.S | 6 +++--- + sysdeps/powerpc/powerpc32/fpu/s_rintf.S | 6 +++--- + sysdeps/powerpc/powerpc64/fpu/s_rint.S | 6 +++--- + sysdeps/powerpc/powerpc64/fpu/s_rintf.S | 6 +++--- + 4 files changed, 12 insertions(+), 12 deletions(-) + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rint.S +index 0ab9e6c..c28e7f6 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rint.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rint.S +@@ -45,14 +45,14 @@ ENTRY (__rint) + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnllr- cr7 +- bng- cr6,.L4 ++ bnllr cr7 ++ bng cr6,.L4 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = 0.0; */ + .L4: +- bnllr- cr6 /* if (x < 0.0) */ ++ bnllr cr6 /* if (x < 0.0) */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rintf.S +index ddb47db..69aed9c 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rintf.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_rintf.S +@@ -41,14 +41,14 @@ ENTRY (__rintf) + fsubs fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnllr- cr7 +- bng- cr6,.L4 ++ bnllr cr7 ++ bng cr6,.L4 + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = 0.0; */ + .L4: +- bnllr- cr6 /* if (x < 0.0) */ ++ bnllr cr6 /* if (x < 0.0) */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fnabs fp1,fp1 /* if (x == 0.0) */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rint.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rint.S +index db62405..560905a 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rint.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rint.S +@@ -34,14 +34,14 @@ EALIGN (__rint, 4, 0) + fsub fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnllr- cr7 +- bng- cr6,.L4 ++ bnllr cr7 ++ bng cr6,.L4 + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = 0.0; */ + .L4: +- bnllr- cr6 /* if (x < 0.0) */ ++ bnllr cr6 /* if (x < 0.0) */ + fsub fp1,fp1,fp13 /* x-= TWO52; */ + fadd fp1,fp1,fp13 /* x+= TWO52; */ + fnabs fp1,fp1 /* if (x == 0.0) */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S +index 248649d..c120d91 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/s_rintf.S +@@ -30,14 +30,14 @@ EALIGN (__rintf, 4, 0) + fsubs fp12,fp13,fp13 /* generate 0.0 */ + fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ + fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ +- bnllr- cr7 +- bng- cr6,.L4 ++ bnllr cr7 ++ bng cr6,.L4 + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fabs fp1,fp1 /* if (x == 0.0) */ + blr /* x = 0.0; */ + .L4: +- bnllr- cr6 /* if (x < 0.0) */ ++ bnllr cr6 /* if (x < 0.0) */ + fsubs fp1,fp1,fp13 /* x-= TWO23; */ + fadds fp1,fp1,fp13 /* x+= TWO23; */ + fnabs fp1,fp1 /* if (x == 0.0) */ +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-libm-6.patch b/SOURCES/glibc-rh731833-libm-6.patch new file mode 100644 index 00000000..c5413285 --- /dev/null +++ b/SOURCES/glibc-rh731833-libm-6.patch @@ -0,0 +1,169 @@ +Consolidated two commits: + +From 51c33bd233d00d77f268ec28565506a6cd1e7d10 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Mon, 25 Mar 2013 16:10:06 -0500 +Subject: [PATCH 25/42] PowerPC: modf optimization + +This patch implements modf/modff optimization for POWER by focus +on FP operations instead of relying in integer ones. +(backported from commit 3c0265394d9ffedff2b0de508602dc52e077ce5c) + +This backport does not include the benchmark tests from the original +commit. + +From 599fefcc3e7fbf65d9c441bf1b336b272c39f262 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 26 Apr 2013 13:00:56 -0500 +Subject: [PATCH 26/42] PowerPC: modf optimization fix + +This patch fix the 3c0265394d9ffedff2b0de508602dc52e077ce5c commits +by correctly setting minimum architecture for modf PPC optimization +to power5+ instead of power5 (since only on power5+ round/ceil will +be inline to inline assembly). +(cherry picked from commit aa630f590c9c7d070a7cdf3a2a88069ad6b63de9) + +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modf.c glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modf.c +--- glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modf.c 1970-01-01 05:30:00.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modf.c 2013-08-06 17:48:57.609526556 +0530 +@@ -0,0 +1,58 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++ ++double ++__modf (double x, double *iptr) ++{ ++ if (__builtin_isinf (x)) ++ { ++ *iptr = x; ++ return __copysign (0.0, x); ++ } ++ else if (__builtin_isnan (x)) ++ { ++ *iptr = NAN; ++ return NAN; ++ } ++ ++ if (x >= 0.0) ++ { ++ *iptr = __floor (x); ++ return (x - *iptr); ++ } ++ else ++ { ++ *iptr = __ceil (x); ++ return (x - *iptr); ++ } ++} ++weak_alias (__modf, modf) ++#ifdef NO_LONG_DOUBLE ++strong_alias (__modf, __modfl) ++weak_alias (__modf, modfl) ++#endif ++#ifdef IS_IN_libm ++# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __modf, modfl, GLIBC_2_0); ++# endif ++#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) ++compat_symbol (libc, __modf, modfl, GLIBC_2_0); ++#endif +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modff.c glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modff.c +--- glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modff.c 1970-01-01 05:30:00.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/power5+/fpu/s_modff.c 2013-08-06 17:48:57.609526556 +0530 +@@ -0,0 +1,46 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++ ++float ++__modff (float x, float *iptr) ++{ ++ if (__builtin_isinff (x)) ++ { ++ *iptr = x; ++ return __copysignf (0.0, x); ++ } ++ else if (__builtin_isnanf (x)) ++ { ++ *iptr = NAN; ++ return NAN; ++ } ++ ++ if (x >= 0.0) ++ { ++ *iptr = __floorf (x); ++ return (x - *iptr); ++ } ++ else ++ { ++ *iptr = __ceilf (x); ++ return (x - *iptr); ++ } ++} ++weak_alias (__modff, modff) +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/Implies +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/Implies 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5/Implies 2013-08-06 17:48:54.266526703 +0530 +@@ -1,2 +1,4 @@ ++powerpc/power5/fpu ++powerpc/power5 + powerpc/powerpc32/power4/fpu + powerpc/powerpc32/power4 +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/Implies +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/Implies 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power5+/Implies 2013-08-06 17:48:57.609526556 +0530 +@@ -1,2 +1,4 @@ ++powerpc/power5+/fpu ++powerpc/power5+ + powerpc/powerpc32/power5/fpu + powerpc/powerpc32/power5 +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/Implies +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/Implies 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/Implies 2013-08-06 17:48:54.266526703 +0530 +@@ -1,2 +1,4 @@ ++powerpc/power5/fpu ++powerpc/power5 + powerpc/powerpc64/power4/fpu + powerpc/powerpc64/power4 +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/Implies +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/Implies 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/Implies 2013-08-06 17:48:57.610526556 +0530 +@@ -1,2 +1,4 @@ ++powerpc/power5+/fpu ++powerpc/power5+ + powerpc/powerpc64/power5/fpu + powerpc/powerpc64/power5 diff --git a/SOURCES/glibc-rh731833-libm-7.patch b/SOURCES/glibc-rh731833-libm-7.patch new file mode 100644 index 00000000..825a2df2 --- /dev/null +++ b/SOURCES/glibc-rh731833-libm-7.patch @@ -0,0 +1,58 @@ +From ed81f668f7c9eff0692c3c81691a7380b55063ff Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 17 May 2013 08:12:16 -0500 +Subject: [PATCH 28/42] PowerPC: fix hypot/hypotf check for -INF (cherry + picked from commit + 13d3b41a36c4f28d171a144f8a9baad3a8835981) (backported + missing CL/NEWS from commit + 68191c1d59d40b3d9f5babef4f37f265920ff565) + +--- + sysdeps/powerpc/fpu/e_hypot.c | 6 +++--- + sysdeps/powerpc/fpu/e_hypotf.c | 6 +++--- + 4 files changed, 14 insertions(+), 7 deletions(-) + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypot.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypot.c +index cfadd5c..fc17bea 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypot.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypot.c +@@ -52,13 +52,13 @@ static const double pdnum = 2.225073858507201e-308; + ieee_double_shape_type gh_u2; \ + gh_u1.value = (d1); \ + gh_u2.value = (d2); \ +- (i1) = gh_u1.parts.msw; \ +- (i2) = gh_u2.parts.msw; \ ++ (i1) = gh_u1.parts.msw & 0x7fffffff; \ ++ (i2) = gh_u2.parts.msw & 0x7fffffff; \ + } while (0) + + # define TEST_INF_NAN(x, y) \ + do { \ +- int32_t hx, hy; \ ++ uint32_t hx, hy; \ + GET_TW0_HIGH_WORD(x, y, hx, hy); \ + if (hy > hx) { \ + uint32_t ht = hx; hx = hy; hy = ht; \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypotf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypotf.c +index 92e824d..77c1b17 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypotf.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/fpu/e_hypotf.c +@@ -46,13 +46,13 @@ static const float two30 = 1.0737418e09; + ieee_float_shape_type gf_u2; \ + gf_u1.value = (f1); \ + gf_u2.value = (f2); \ +- (i1) = gf_u1.word; \ +- (i2) = gf_u2.word; \ ++ (i1) = gf_u1.word & 0x7fffffff; \ ++ (i2) = gf_u2.word & 0x7fffffff; \ + } while (0) + + # define TEST_INF_NAN(x, y) \ + do { \ +- int32_t hx, hy; \ ++ uint32_t hx, hy; \ + GET_TWO_FLOAT_WORD(x, y, hx, hy); \ + if (hy > hx) { \ + uint32_t ht = hx; hx = hy; hy = ht; \ +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-libm.patch b/SOURCES/glibc-rh731833-libm.patch new file mode 100644 index 00000000..6f433e75 --- /dev/null +++ b/SOURCES/glibc-rh731833-libm.patch @@ -0,0 +1,26 @@ +From 33c15e3ac353a5594efb9815f186d96b0f821f3f Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Mon, 4 Mar 2013 11:37:51 -0300 +Subject: [PATCH 16/42] BZ #15055: Use __ieee754_sqrl in acoshl for + lbdl-128ibm (backported from commit + e0b780ad5b94209bf99bf498314bc5c160dc2a15) + +--- + sysdeps/ieee754/ldbl-128ibm/e_acoshl.c | 2 +- + 3 files changed, 8 insertions(+), 2 deletions(-) + +diff --git glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c +index 117bd0f..abc78a3 100644 +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/e_acoshl.c +@@ -52,7 +52,7 @@ __ieee754_acoshl(long double x) + return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one))); + } else { /* 1 +Date: Thu, 28 Mar 2013 12:16:28 -0500 +Subject: [PATCH 22/42] PowerPC: .eh_frame info in crt1.o isn't useful and + triggers gold bug 14675. + +The .eh_frame info in crt1.o isn't useful and this patch prevents it from +being generated on PowerPC. It triggers the following gold bug: + +http://sourceware.org/bugzilla/show_bug.cgi?id=14675 +(cherry picked from commit b0f1246ab45b6d27e2bba64aa8dfe407ac740537) +--- + sysdeps/powerpc/powerpc32/start.S | 7 +++++++ + sysdeps/powerpc/powerpc64/start.S | 7 +++++++ + 3 files changed, 21 insertions(+) + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/start.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/start.S +index 4935e64..2e454c0 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/start.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/start.S +@@ -37,6 +37,13 @@ + #include + #include "bp-sym.h" + ++/* We do not want .eh_frame info for crt1.o since crt1.o is linked ++ before crtbegin.o, the file defining __EH_FRAME_BEGIN__. */ ++#undef cfi_startproc ++#define cfi_startproc ++#undef cfi_endproc ++#define cfi_endproc ++ + /* These are the various addresses we require. */ + #ifdef PIC + .section ".data" +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/start.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/start.S +index d9c92d1..aadaf0f 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/start.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/start.S +@@ -37,6 +37,13 @@ + #include + #include "bp-sym.h" + ++/* We do not want .eh_frame info for crt1.o since crt1.o is linked ++ before crtbegin.o, the file defining __EH_FRAME_BEGIN__. */ ++#undef cfi_startproc ++#define cfi_startproc ++#undef cfi_endproc ++#define cfi_endproc ++ + /* These are the various addresses we require. */ + #ifdef PIC + .section ".data.rel.ro.local","aw" +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-misc-3.patch b/SOURCES/glibc-rh731833-misc-3.patch new file mode 100644 index 00000000..5d7cb715 --- /dev/null +++ b/SOURCES/glibc-rh731833-misc-3.patch @@ -0,0 +1,145 @@ +From 01c3d9bb14a1e90159d6999cf3469e62c0c5d4b2 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 3 May 2013 15:00:31 -0500 +Subject: [PATCH 27/42] PowerPC: Add time vDSO support + +PowerPC kernel now provides a vDSO implementation for time syscall +(commit fcb41a2030abe0eb716ef0798035ef9562097f42). This patch changes +time syscall wrapper to use the vDSO when available. It also changes +the default non vDSO time on PowerPC to use sysdeps/posix/time.c +(since gettimeofday is a vDSO call). +(cherry picked from commit 83e7640f6bf68708ecf0b09d83c670203167271e) +--- + sysdeps/unix/sysv/linux/powerpc/Versions | 1 + + sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 6 ++- + sysdeps/unix/sysv/linux/powerpc/init-first.c | 4 +- + sysdeps/unix/sysv/linux/powerpc/time.c | 62 ++++++++++++++++++++++++ + 5 files changed, 81 insertions(+), 3 deletions(-) + create mode 100644 sysdeps/unix/sysv/linux/powerpc/time.c + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions +index 396a423..289c4fe 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions +@@ -4,5 +4,6 @@ libc { + __vdso_clock_gettime; + __vdso_clock_getres; + __vdso_getcpu; ++ __vdso_time; + } + } +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +index e4ae630..f7f635e 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +@@ -32,14 +32,16 @@ extern void *__vdso_get_tbfreq; + + extern void *__vdso_getcpu; + ++extern void *__vdso_time; ++ + /* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO + symbol. This works because _dl_vdso_vsym always return the function + address, and no vDSO symbols use the TOC or chain pointers from the OPD + so we can allow them to be garbage. */ + #if defined(__PPC64__) || defined(__powerpc64__) +-#define VDSO_IFUNC_RET(value) &value ++#define VDSO_IFUNC_RET(value) ((void *) &(value)) + #else +-#define VDSO_IFUNC_RET(value) value ++#define VDSO_IFUNC_RET(value) ((void *) (value)) + #endif + + #endif +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c +index 5587e2a..3cefd9b 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c +@@ -28,7 +28,7 @@ void *__vdso_clock_gettime; + void *__vdso_clock_getres; + void *__vdso_get_tbfreq; + void *__vdso_getcpu; +- ++void *__vdso_time; + + static inline void + _libc_vdso_platform_setup (void) +@@ -44,6 +44,8 @@ _libc_vdso_platform_setup (void) + __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_get_tbfreq", &linux2615); + + __vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615); ++ ++ __vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615); + } + + # define VDSO_SETUP _libc_vdso_platform_setup +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c +new file mode 100644 +index 0000000..66b4eb3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/time.c +@@ -0,0 +1,62 @@ ++/* time system call for Linux/PowerPC. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef SHARED ++ ++# include ++# include ++# include ++ ++void *time_ifunc (void) asm ("time"); ++ ++static time_t ++time_syscall (time_t *t) ++{ ++ struct timeval tv; ++ time_t result; ++ ++ if (INLINE_VSYSCALL (gettimeofday, 2, &tv, NULL) < 0) ++ result = (time_t) -1; ++ else ++ result = (time_t) tv.tv_sec; ++ ++ if (t != NULL) ++ *t = result; ++ return result; ++} ++ ++void * ++time_ifunc (void) ++{ ++ /* If the vDSO is not available we fall back to the syscall. */ ++ return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time) ++ : time_syscall); ++} ++asm (".type time, %gnu_indirect_function"); ++ ++/* This is doing "libc_hidden_def (time)" but the compiler won't ++ * let us do it in C because it doesn't know we're defining time ++ * here in this file. */ ++asm (".globl __GI_time\n" ++ "__GI_time = time"); ++ ++#else ++ ++#include ++ ++#endif +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-misc-4.patch b/SOURCES/glibc-rh731833-misc-4.patch new file mode 100644 index 00000000..201cc6a6 --- /dev/null +++ b/SOURCES/glibc-rh731833-misc-4.patch @@ -0,0 +1,140 @@ +This is a combination of two commits: + +From 42b373ad467ba426610a358d90034bcf68abb15f Mon Sep 17 00:00:00 2001 +From: Edjunior Machado +Date: Thu, 23 May 2013 10:06:24 -0500 +Subject: [PATCH 31/42] PowerPC: Add functions for shared resources hints. + (cherry picked from commit + 9323d39baea2fb0cca3735136abe263eff405133) + +From a6d45052042c1fc962523633c0489634864e1a02 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 24 May 2013 13:29:30 -0500 +Subject: [PATCH 32/42] PowerPC: Program Priority Register support + +This patch add inline functions to change the Program Priority Register +from ISA 2.05. +(cherry picked from commit d116b7c414c8239b677e341ac517745db689ac2d) + +diff -pruN glibc-2.17-c758a686/manual/platform.texi glibc-2.17-c758a686/manual/platform.texi +--- glibc-2.17-c758a686/manual/platform.texi 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/manual/platform.texi 2013-08-05 19:06:49.523550318 +0530 +@@ -34,3 +34,48 @@ This frequency is not related to the pro + It is also possible that this frequency is not constant. More information is + available in @cite{Power ISA 2.06b - Book II - Section 5.2}. + @end deftypefun ++ ++The following functions provide hints about the usage of resources that are ++shared with other processors. They can be used, for example, if a program ++waiting on a lock intends to divert the shared resources to be used by other ++processors. More information is available in @cite{Power ISA 2.06b - Book II - ++Section 3.2}. ++ ++@deftypefun {void} __ppc_yield (void) ++Provide a hint that performance will probably be improved if shared resources ++dedicated to the executing processor are released for use by other processors. ++@end deftypefun ++ ++@deftypefun {void} __ppc_mdoio (void) ++Provide a hint that performance will probably be improved if shared resources ++dedicated to the executing processor are released until all outstanding storage ++accesses to caching-inhibited storage have been completed. ++@end deftypefun ++ ++@deftypefun {void} __ppc_mdoom (void) ++Provide a hint that performance will probably be improved if shared resources ++dedicated to the executing processor are released until all outstanding storage ++accesses to cacheable storage for which the data is not in the cache have been ++completed. ++@end deftypefun ++ ++@deftypefun {void} __ppc_set_ppr_med (void) ++Set the Program Priority Register to medium value (default). ++ ++The @dfn{Program Priority Register} (PPR) is a 64-bit register that controls ++the program's priority. By adjusting the PPR value the programmer may ++improve system throughput by causing the system resources to be used ++more efficiently, especially in contention situations. ++The three unprivileged states available are covered by the functions ++@code{__ppc_set_ppr_med} (medium -- default), @code{__ppc_set_ppc_low} (low) ++and @code{__ppc_set_ppc_med_low} (medium low). More information ++available in @cite{Power ISA 2.06b - Book II - Section 3.1}. ++@end deftypefun ++ ++@deftypefun {void} __ppc_set_ppr_low (void) ++Set the Program Priority Register to low value. ++@end deftypefun ++ ++@deftypefun {void} __ppc_set_ppr_med_low (void) ++Set the Program Priority Register to medium low value. ++@end deftypefun +diff -pruN glibc-2.17-c758a686/sysdeps/powerpc/sys/platform/ppc.h glibc-2.17-c758a686/sysdeps/powerpc/sys/platform/ppc.h +--- glibc-2.17-c758a686/sysdeps/powerpc/sys/platform/ppc.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/powerpc/sys/platform/ppc.h 2013-08-05 19:06:49.523550318 +0530 +@@ -50,4 +50,66 @@ __ppc_get_timebase (void) + #endif + } + ++/* The following functions provide hints about the usage of shared processor ++ resources, as defined in ISA 2.06 and newer. */ ++ ++/* Provides a hint that performance will probably be improved if shared ++ resources dedicated to the executing processor are released for use by other ++ processors. */ ++static inline void ++__ppc_yield (void) ++{ ++ __asm__ volatile ("or 27,27,27"); ++} ++ ++/* Provides a hint that performance will probably be improved if shared ++ resources dedicated to the executing processor are released until ++ all outstanding storage accesses to caching-inhibited storage have been ++ completed. */ ++static inline void ++__ppc_mdoio (void) ++{ ++ __asm__ volatile ("or 29,29,29"); ++} ++ ++/* Provides a hint that performance will probably be improved if shared ++ resources dedicated to the executing processor are released until all ++ outstanding storage accesses to cacheable storage for which the data is not ++ in the cache have been completed. */ ++static inline void ++__ppc_mdoom (void) ++{ ++ __asm__ volatile ("or 30,30,30"); ++} ++ ++ ++/* ISA 2.05 and beyond support the Program Priority Register (PPR) to adjust ++ thread priorities based on lock acquisition, wait and release. The ISA ++ defines the use of form 'or Rx,Rx,Rx' as the way to modify the PRI field. ++ The unprivileged priorities are: ++ Rx = 1 (low) ++ Rx = 2 (medium) ++ Rx = 6 (medium-low/normal) ++ The 'or' instruction form is a nop in previous hardware, so it is safe to ++ use unguarded. The default value is 'medium'. ++ */ ++ ++static inline void ++__ppc_set_ppr_med (void) ++{ ++ __asm__ volatile ("or 2,2,2"); ++} ++ ++static inline void ++__ppc_set_ppr_med_low (void) ++{ ++ __asm__ volatile ("or 6,6,6"); ++} ++ ++static inline void ++__ppc_set_ppr_low (void) ++{ ++ __asm__ volatile ("or 1,1,1"); ++} ++ + #endif /* sys/platform/ppc.h */ diff --git a/SOURCES/glibc-rh731833-misc-5.patch b/SOURCES/glibc-rh731833-misc-5.patch new file mode 100644 index 00000000..d674bb10 --- /dev/null +++ b/SOURCES/glibc-rh731833-misc-5.patch @@ -0,0 +1,30 @@ +From 920e759ea4f48ca9c8b4dba6dfe5c88d27033121 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Mon, 17 Jun 2013 15:50:53 -0500 +Subject: [PATCH 36/42] PowerPC: Reserve TCB space for EBB framework + +This patch reserves four pointer to be used in future Event-Based +Branch framework for PowerPC. +(cherry picked from commit e55a9b256d53c7fc5145e3e4d338d3741b23e232) +--- + nptl/sysdeps/powerpc/tls.h | 5 +++++ + 2 files changed, 10 insertions(+) + +diff --git glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h +index 4c09eec..611c773 100644 +--- glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h ++++ glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h +@@ -61,6 +61,11 @@ typedef union dtv + are private. */ + typedef struct + { ++ /* Reservation for the Event-Based Branching ABI. */ ++ uintptr_t ebb_handler; ++ uintptr_t ebb_ctx_pointer; ++ uintptr_t ebb_reserved1; ++ uintptr_t ebb_reserved2; + uintptr_t pointer_guard; + uintptr_t stack_guard; + dtv_t *dtv; +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-misc-6.patch b/SOURCES/glibc-rh731833-misc-6.patch new file mode 100644 index 00000000..9c0783b4 --- /dev/null +++ b/SOURCES/glibc-rh731833-misc-6.patch @@ -0,0 +1,180 @@ +From a06663ebed17775761f501e5f0cdddff159959ac Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Tue, 23 Jul 2013 07:39:57 -0500 +Subject: [PATCH 42/42] PowerPC: use _dl_static_init to set GLRO(gl_pagesize) + +This patch fixes dlfcn/tststatic5 for PowerPC where pagesize +variable was not properly initialized in certain cases. This patch +is based on other architecture code. +(cherry picked from commit 7b1f8b581f9387230788e4d8a67cdbcf464dac85) +--- + sysdeps/unix/sysv/linux/powerpc/Makefile | 6 +++ + sysdeps/unix/sysv/linux/powerpc/Versions | 6 +++ + sysdeps/unix/sysv/linux/powerpc/dl-static.c | 84 +++++++++++++++++++++++++++++ + sysdeps/unix/sysv/linux/powerpc/ldsodefs.h | 33 ++++++++++++ + 5 files changed, 137 insertions(+) + create mode 100644 sysdeps/unix/sysv/linux/powerpc/dl-static.c + create mode 100644 sysdeps/unix/sysv/linux/powerpc/ldsodefs.h + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile +index 4ff7e84..cf4de97 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Makefile +@@ -15,6 +15,12 @@ endif + + ifeq ($(subdir),elf) + sysdep_routines += dl-vdso ++ifeq ($(build-shared),yes) ++# This is needed for DSO loading from static binaries. ++sysdep-dl-routines += dl-static ++sysdep_routines += dl-static ++sysdep-rtld-routines += dl-static ++endif + endif + + ifeq ($(subdir),misc) +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions +index 289c4fe..9b583fb 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions +@@ -1,3 +1,9 @@ ++ld { ++ GLIBC_PRIVATE { ++ # used for loading by static libraries ++ _dl_var_init; ++ } ++} + libc { + GLIBC_PRIVATE { + __vdso_get_tbfreq; +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/dl-static.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/dl-static.c +new file mode 100644 +index 0000000..8289c61 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/dl-static.c +@@ -0,0 +1,84 @@ ++/* Variable initialization. PowerPC version. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library. If not, see ++ . */ ++ ++#include ++ ++#ifdef SHARED ++ ++void ++_dl_var_init (void *array[]) ++{ ++ /* It has to match "variables" below. */ ++ enum ++ { ++ DL_PAGESIZE = 0 ++ }; ++ ++ GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); ++} ++ ++#else ++ ++static void *variables[] = ++{ ++ &GLRO(dl_pagesize) ++}; ++ ++static void ++_dl_unprotect_relro (struct link_map *l) ++{ ++ ElfW(Addr) start = ((l->l_addr + l->l_relro_addr) ++ & ~(GLRO(dl_pagesize) - 1)); ++ ElfW(Addr) end = ((l->l_addr + l->l_relro_addr + l->l_relro_size) ++ & ~(GLRO(dl_pagesize) - 1)); ++ ++ if (start != end) ++ __mprotect ((void *) start, end - start, PROT_READ | PROT_WRITE); ++} ++ ++void ++_dl_static_init (struct link_map *l) ++{ ++ struct link_map *rtld_map = l; ++ struct r_scope_elem **scope; ++ const ElfW(Sym) *ref = NULL; ++ lookup_t loadbase; ++ void (*f) (void *[]); ++ size_t i; ++ ++ loadbase = _dl_lookup_symbol_x ("_dl_var_init", l, &ref, l->l_local_scope, ++ NULL, 0, 1, NULL); ++ ++ for (scope = l->l_local_scope; *scope != NULL; scope++) ++ for (i = 0; i < (*scope)->r_nlist; i++) ++ if ((*scope)->r_list[i] == loadbase) ++ { ++ rtld_map = (*scope)->r_list[i]; ++ break; ++ } ++ ++ if (ref != NULL) ++ { ++ f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); ++ _dl_unprotect_relro (rtld_map); ++ f (variables); ++ _dl_protect_relro (rtld_map); ++ } ++} ++ ++#endif +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldsodefs.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldsodefs.h +new file mode 100644 +index 0000000..fcedf32 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/ldsodefs.h +@@ -0,0 +1,33 @@ ++/* Run-time dynamic linker data structures for loaded ELF shared objects. ++ PowerPC version. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _LDSODEFS_H ++ ++/* Get the real definitions. */ ++#include_next ++ ++/* Now define our stuff. */ ++ ++/* We need special support to initialize DSO loaded for statically linked ++ binaries. */ ++extern void _dl_static_init (struct link_map *map); ++#undef DL_STATIC_INIT ++#define DL_STATIC_INIT(map) _dl_static_init (map) ++ ++#endif /* ldsodefs.h */ +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-misc.patch b/SOURCES/glibc-rh731833-misc.patch new file mode 100644 index 00000000..2e305e6e --- /dev/null +++ b/SOURCES/glibc-rh731833-misc.patch @@ -0,0 +1,210 @@ +From 51a8476450158fb522c791c73b7b56dc30a741fc Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Tue, 15 Jan 2013 12:50:46 -0600 +Subject: [PATCH 14/42] PowerPC: Rename __kernel_vdso_get_tbfreq to + __kernel_get_tbfreq. + +In order for the __kernel_get_tbfreq vDSO call to work the +INTERNAL_VSYSCALL_NCS macro needed to be updated to prevent it from +assuming an integer return type (since the timebase frequency is a 64-bit +value) by specifying the type of the return type as a macro parameter. The +macro then specifically declares the return value as a 'register' (or +implied pair) of the denoted type. The compiler is then informed that this +register (or implied pair) is to be used for the return value. +(cherry picked from commit 471a1672d4d55124de4db8273829f96cc14d424a) +--- + sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c | 3 ++- + sysdeps/unix/sysv/linux/powerpc/init-first.c | 2 +- + sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h | 28 +++++++++++---------- + sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | 29 +++++++++++----------- + 5 files changed, 55 insertions(+), 29 deletions(-) + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c +index a863a27..021594c 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c +@@ -41,7 +41,8 @@ __get_clockfreq (void) + /* If we can use the vDSO to obtain the timebase even better. */ + #ifdef SHARED + INTERNAL_SYSCALL_DECL (err); +- timebase_freq = INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, 0); ++ timebase_freq = ++ INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK (get_tbfreq, err, hp_timing_t, 0); + if (INTERNAL_SYSCALL_ERROR_P (timebase_freq, err) + && INTERNAL_SYSCALL_ERRNO (timebase_freq, err) == ENOSYS) + #endif +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c +index 6bcb7d5..5587e2a 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c +@@ -41,7 +41,7 @@ _libc_vdso_platform_setup (void) + + __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615); + +- __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615); ++ __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_get_tbfreq", &linux2615); + + __vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615); + } +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +index da25c01..fa4116e 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +@@ -60,7 +60,8 @@ + \ + if (__vdso_##name != NULL) \ + { \ +- sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \ ++ sc_ret = \ ++ INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, long int, nr, ##args);\ + if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ + goto out; \ + if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \ +@@ -90,7 +91,8 @@ + \ + if (__vdso_##name != NULL) \ + { \ +- v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ ++ v_ret = \ ++ INTERNAL_VSYSCALL_NCS (__vdso_##name, err, long int, nr, ##args); \ + if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \ + || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \ + goto out; \ +@@ -104,12 +106,12 @@ + INTERNAL_SYSCALL (name, err, nr, ##args) + # endif + +-# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \ ++# define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \ + ({ \ +- long int sc_ret = ENOSYS; \ ++ type sc_ret = ENOSYS; \ + \ + if (__vdso_##name != NULL) \ +- sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ ++ sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args); \ + else \ + err = 1 << 28; \ + sc_ret; \ +@@ -126,7 +128,7 @@ + function call, with the exception of LR (which is needed for the + "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal + an error return status). */ +-# define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \ ++# define INTERNAL_VSYSCALL_NCS(funcptr, err, type, nr, args...) \ + ({ \ + register void *r0 __asm__ ("r0"); \ + register long int r3 __asm__ ("r3"); \ +@@ -139,18 +141,18 @@ + register long int r10 __asm__ ("r10"); \ + register long int r11 __asm__ ("r11"); \ + register long int r12 __asm__ ("r12"); \ ++ register type rval __asm__ ("r3"); \ + LOADARGS_##nr (funcptr, args); \ + __asm__ __volatile__ \ + ("mtctr %0\n\t" \ + "bctrl\n\t" \ + "mfcr %0" \ +- : "=&r" (r0), \ +- "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \ +- "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \ +- : ASM_INPUT_##nr \ +- : "cr0", "ctr", "lr", "memory"); \ ++ : "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), \ ++ "+r" (r8), "+r" (r9), "+r" (r10), "+r" (r11), "+r" (r12) \ ++ : : "cr0", "ctr", "lr", "memory"); \ + err = (long int) r0; \ +- (int) r3; \ ++ __asm__ __volatile__ ("" : "=r" (rval) : "r" (r3), "r" (r4)); \ ++ rval; \ + }) + + # undef INLINE_SYSCALL +@@ -191,7 +193,7 @@ + register long int r10 __asm__ ("r10"); \ + register long int r11 __asm__ ("r11"); \ + register long int r12 __asm__ ("r12"); \ +- LOADARGS_##nr(name, args); \ ++ LOADARGS_##nr(name, args); \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0" \ +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +index 059cf70..b4cdbbb 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +@@ -75,7 +75,8 @@ + \ + if (__vdso_##name != NULL) \ + { \ +- sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, nr, ##args); \ ++ sc_ret = \ ++ INTERNAL_VSYSCALL_NCS (__vdso_##name, sc_err, long int, nr, ##args);\ + if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ + goto out; \ + if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \ +@@ -105,7 +106,8 @@ + \ + if (__vdso_##name != NULL) \ + { \ +- v_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ ++ v_ret = \ ++ INTERNAL_VSYSCALL_NCS (__vdso_##name, err, long int, nr, ##args); \ + if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \ + || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \ + goto out; \ +@@ -121,12 +123,12 @@ + + /* This version is for internal uses when there is no desire + to set errno */ +-#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, nr, args...) \ ++#define INTERNAL_VSYSCALL_NO_SYSCALL_FALLBACK(name, err, type, nr, args...) \ + ({ \ +- long int sc_ret = ENOSYS; \ ++ type sc_ret = ENOSYS; \ + \ + if (__vdso_##name != NULL) \ +- sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, nr, ##args); \ ++ sc_ret = INTERNAL_VSYSCALL_NCS (__vdso_##name, err, type, nr, ##args); \ + else \ + err = 1 << 28; \ + sc_ret; \ +@@ -142,7 +144,7 @@ + gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set) + the negation of the return value in the kernel gets reverted. */ + +-#define INTERNAL_VSYSCALL_NCS(funcptr, err, nr, args...) \ ++#define INTERNAL_VSYSCALL_NCS(funcptr, err, type, nr, args...) \ + ({ \ + register void *r0 __asm__ ("r0"); \ + register long int r3 __asm__ ("r3"); \ +@@ -151,20 +153,19 @@ + register long int r6 __asm__ ("r6"); \ + register long int r7 __asm__ ("r7"); \ + register long int r8 __asm__ ("r8"); \ ++ register type rval __asm__ ("r3"); \ + LOADARGS_##nr (funcptr, args); \ + __asm__ __volatile__ \ + ("mtctr %0\n\t" \ + "bctrl\n\t" \ + "mfcr %0\n\t" \ + "0:" \ +- : "=&r" (r0), \ +- "=&r" (r3), "=&r" (r4), "=&r" (r5), \ +- "=&r" (r6), "=&r" (r7), "=&r" (r8) \ +- : ASM_INPUT_##nr \ +- : "r9", "r10", "r11", "r12", \ +- "cr0", "ctr", "lr", "memory"); \ +- err = (long int) r0; \ +- r3; \ ++ : "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), \ ++ "+r" (r7), "+r" (r8) \ ++ : : "r9", "r10", "r11", "r12", "cr0", "ctr", "lr", "memory"); \ ++ err = (long int) r0; \ ++ __asm__ __volatile__ ("" : "=r" (rval) : "r" (r3)); \ ++ rval; \ + }) + + #undef INLINE_SYSCALL +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh731833-rtkaio-2.patch b/SOURCES/glibc-rh731833-rtkaio-2.patch new file mode 100644 index 00000000..672a9b99 --- /dev/null +++ b/SOURCES/glibc-rh731833-rtkaio-2.patch @@ -0,0 +1,11 @@ +diff -pruN glibc-2.17-c758a686/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c glibc-2.17-c758a686/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c +--- glibc-2.17-c758a686/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c 2011-10-19 16:34:41.000000000 +0530 ++++ glibc-2.17-c758a686/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c 2013-08-16 10:22:30.457609558 +0530 +@@ -59,6 +59,7 @@ struct clparam + + + static void ++__attribute__ ((noinline)) + cleanup (void *arg) + { + #ifdef DONT_NEED_AIO_MISC_COND diff --git a/SOURCES/glibc-rh731833-rtkaio.patch b/SOURCES/glibc-rh731833-rtkaio.patch new file mode 100644 index 00000000..2e3fab72 --- /dev/null +++ b/SOURCES/glibc-rh731833-rtkaio.patch @@ -0,0 +1,31 @@ +diff -pruN glibc-2.17-c758a686/rtkaio/Makefile glibc-2.17-c758a686/rtkaio/Makefile +--- glibc-2.17-c758a686/rtkaio/Makefile 2011-10-19 16:34:41.000000000 +0530 ++++ glibc-2.17-c758a686/rtkaio/Makefile 2013-08-13 18:23:21.064888432 +0530 +@@ -55,7 +55,7 @@ extra-libs-others := $(extra-libs) + + include $(..)Makeconfig + +-ifeq (yesyes,$(build-shared)$(elf)) ++ifeq (yes,$(build-shared)) + generated += librt.so$(librt.so-version) + + $(objpfx)librt.so$(librt.so-version): $(objpfx)librtkaio.so; $(make-link) +@@ -73,7 +73,7 @@ CPPFLAGS-librtkaio += -DIS_IN_librt=1 -I + + rpath-dirs := $(patsubst rt,rtkaio,$(rpath-dirs)) + +-ifeq (yesyes,$(build-shared)$(elf)) ++ifeq (yes,$(build-shared)) + others: $(objpfx)librt.so$(librt.so-version) + endif + +@@ -81,8 +81,7 @@ endif + # This ensures they will load libc.so for needed symbols if loaded by + # a statically-linked program that hasn't already loaded it. + $(objpfx)librtkaio.so: $(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a \ +- $(shared-thread-library) \ +- $(if $(filter yes,$(elf)), $(elfobjdir)/ld.so) ++ $(shared-thread-library) $(elfobjdir)/ld.so + + ifeq (yes,$(build-shared)) + $(addprefix $(objpfx),$(tests)): $(objpfx)librtkaio.so $(shared-thread-library) diff --git a/SOURCES/glibc-rh731835-0.patch b/SOURCES/glibc-rh731835-0.patch new file mode 100644 index 00000000..be90c7ce --- /dev/null +++ b/SOURCES/glibc-rh731835-0.patch @@ -0,0 +1,761 @@ +commit 8d2c0a593bdefd220be0822fb70de6b8d3bfd39d +Author: Adhemerval Zanella +Date: Fri Nov 7 12:25:32 2014 -0500 + + powerpc: Add the lock elision using HTM + + This patch adds support for lock elision using ISA 2.07 hardware + transactional memory instructions for pthread_mutex primitives. + Similar to s390 version, the for elision logic defined in + 'force-elision.h' is only enabled if ENABLE_LOCK_ELISION is defined. + + Also, the lock elision code should be able to be built even with + a compiler that does not provide HTM support with builtins. + However I have noted the performance is sub-optimal due scheduling + pressures. + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +@@ -0,0 +1,80 @@ ++/* elision-conf.c: Lock elision tunable parameters. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "config.h" ++#include ++#include ++#include ++#include ++ ++/* Reasonable initial tuning values, may be revised in the future. ++ This is a conservative initial value. */ ++ ++struct elision_config __elision_aconf = ++ { ++ /* How many times to use a non-transactional lock after a transactional ++ failure has occurred because the lock is already acquired. Expressed ++ in number of lock acquisition attempts. */ ++ .skip_lock_busy = 3, ++ /* How often to not attempt to use elision if a transaction aborted due ++ to reasons other than other threads' memory accesses. Expressed in ++ number of lock acquisition attempts. */ ++ .skip_lock_internal_abort = 3, ++ /* How often to not attempt to use elision if a lock used up all retries ++ without success. Expressed in number of lock acquisition attempts. */ ++ .skip_lock_out_of_tbegin_retries = 3, ++ /* How often we retry using elision if there is chance for the transaction ++ to finish execution (e.g., it wasn't aborted due to the lock being ++ already acquired. */ ++ .try_tbegin = 3, ++ /* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */ ++ .skip_trylock_internal_abort = 3, ++ }; ++ ++/* Force elision for all new locks. This is used to decide whether existing ++ DEFAULT locks should be automatically use elision in pthread_mutex_lock(). ++ Disabled for suid programs. Only used when elision is available. */ ++ ++int __pthread_force_elision attribute_hidden; ++ ++/* Initialize elision. */ ++ ++static void ++elision_init (int argc __attribute__ ((unused)), ++ char **argv __attribute__ ((unused)), ++ char **environ) ++{ ++#ifdef ENABLE_LOCK_ELISION ++ int elision_available = (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM) ? 1 : 0; ++ __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; ++#endif ++} ++ ++#ifdef SHARED ++# define INIT_SECTION ".init_array" ++# define MAYBE_CONST ++#else ++# define INIT_SECTION ".preinit_array" ++# define MAYBE_CONST const ++#endif ++ ++void (*MAYBE_CONST __pthread_init_array []) (int, char **, char **) ++ __attribute__ ((section (INIT_SECTION), aligned (sizeof (void *)))) = ++{ ++ &elision_init ++}; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.h +@@ -0,0 +1,42 @@ ++/* elision-conf.h: Lock elision tunable parameters. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _ELISION_CONF_H ++#define _ELISION_CONF_H 1 ++ ++#include ++#include ++ ++/* Should make sure there is no false sharing on this. */ ++struct elision_config ++{ ++ int skip_lock_busy; ++ int skip_lock_internal_abort; ++ int skip_lock_out_of_tbegin_retries; ++ int try_tbegin; ++ int skip_trylock_internal_abort; ++} __attribute__ ((__aligned__ (128))); ++ ++extern struct elision_config __elision_aconf attribute_hidden; ++ ++extern int __pthread_force_elision attribute_hidden; ++ ++/* Tell the test suite to test elision for this architecture. */ ++#define HAVE_ELISION 1 ++ ++#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-lock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-lock.c +@@ -0,0 +1,107 @@ ++/* elision-lock.c: Elided pthread mutex lock. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "htm.h" ++ ++/* PowerISA 2.0.7 Section B.5.5 defines isync to be insufficient as a ++ barrier in acquire mechanism for HTM operations, a strong 'sync' is ++ required. */ ++#undef __arch_compare_and_exchange_val_32_acq ++#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ ++ ({ \ ++ __typeof (*(mem)) __tmp; \ ++ __typeof (mem) __memp = (mem); \ ++ __asm __volatile ( \ ++ "1: lwarx %0,0,%1" MUTEX_HINT_ACQ "\n" \ ++ " cmpw %0,%2\n" \ ++ " bne 2f\n" \ ++ " stwcx. %3,0,%1\n" \ ++ " bne- 1b\n" \ ++ "2: sync" \ ++ : "=&r" (__tmp) \ ++ : "b" (__memp), "r" (oldval), "r" (newval) \ ++ : "cr0", "memory"); \ ++ __tmp; \ ++ }) ++ ++#if !defined(LLL_LOCK) && !defined(EXTRAARG) ++/* Make sure the configuration code is always linked in for static ++ libraries. */ ++#include "elision-conf.c" ++#endif ++ ++#ifndef EXTRAARG ++# define EXTRAARG ++#endif ++#ifndef LLL_LOCK ++# define LLL_LOCK(a,b) lll_lock(a,b), 0 ++#endif ++ ++#define aconf __elision_aconf ++ ++/* Adaptive lock using transactions. ++ By default the lock region is run as a transaction, and when it ++ aborts or the lock is busy the lock adapts itself. */ ++ ++int ++__lll_lock_elision (int *lock, short *adapt_count, EXTRAARG int pshared) ++{ ++ if (*adapt_count > 0) ++ { ++ (*adapt_count)--; ++ goto use_lock; ++ } ++ ++ int try_begin = aconf.try_tbegin; ++ while (1) ++ { ++ if (__builtin_tbegin (0)) ++ { ++ if (*lock == 0) ++ return 0; ++ /* Lock was busy. Fall back to normal locking. */ ++ __builtin_tabort (_ABORT_LOCK_BUSY); ++ } ++ else ++ { ++ /* A persistent failure indicates that a retry will probably ++ result in another failure. Use normal locking now and ++ for the next couple of calls. */ ++ if (try_begin-- <= 0 ++ || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ())) ++ { ++ if (aconf.skip_lock_internal_abort > 0) ++ *adapt_count = aconf.skip_lock_internal_abort; ++ goto use_lock; ++ } ++ /* Same logic as above, but for for a number of temporary failures ++ in a row. */ ++ else if (aconf.skip_lock_out_of_tbegin_retries > 0 ++ && aconf.try_tbegin > 0) ++ *adapt_count = aconf.skip_lock_out_of_tbegin_retries; ++ } ++ } ++ ++use_lock: ++ return LLL_LOCK ((*lock), pshared); ++} +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-timed.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-timed.c +@@ -0,0 +1,28 @@ ++/* elision-timed.c: Lock elision timed lock. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++#define __lll_lock_elision __lll_timedlock_elision ++#define EXTRAARG const struct timespec *t, ++#undef LLL_LOCK ++#define LLL_LOCK(a, b) lll_timedlock(a, t, b) ++ ++#include "elision-lock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-trylock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-trylock.c +@@ -0,0 +1,68 @@ ++/* elision-trylock.c: Lock eliding trylock for pthreads. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include "htm.h" ++ ++#define aconf __elision_aconf ++ ++/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is ++ the adaptation counter in the mutex. */ ++ ++int ++__lll_trylock_elision (int *futex, short *adapt_count) ++{ ++ /* Implement POSIX semantics by forbiding nesting elided trylocks. */ ++ __builtin_tabort (_ABORT_NESTED_TRYLOCK); ++ ++ /* Only try a transaction if it's worth it. */ ++ if (*adapt_count > 0) ++ { ++ (*adapt_count)--; ++ goto use_lock; ++ } ++ ++ if (__builtin_tbegin (0)) ++ { ++ if (*futex == 0) ++ return 0; ++ ++ /* Lock was busy. Fall back to normal locking. */ ++ __builtin_tabort (_ABORT_LOCK_BUSY); ++ } ++ else ++ { ++ if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ())) ++ { ++ /* A persistent failure indicates that a retry will probably ++ result in another failure. Use normal locking now and ++ for the next couple of calls. */ ++ if (aconf.skip_trylock_internal_abort > 0) ++ *adapt_count = aconf.skip_trylock_internal_abort; ++ } ++ ++ if (aconf.skip_lock_busy > 0) ++ *adapt_count = aconf.skip_lock_busy; ++ } ++ ++use_lock: ++ return lll_trylock (*futex); ++} +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-unlock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-unlock.c +@@ -0,0 +1,32 @@ ++/* elision-unlock.c: Commit an elided pthread lock. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "pthreadP.h" ++#include ++#include "htm.h" ++ ++int ++__lll_unlock_elision(int *lock, int pshared) ++{ ++ /* When the lock was free we're in a transaction. */ ++ if (*lock == 0) ++ __builtin_tend (0); ++ else ++ lll_unlock ((*lock), pshared); ++ return 0; ++} +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/force-elision.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/force-elision.h +@@ -0,0 +1,28 @@ ++/* force-elision.h: Automatic enabling of elision for mutexes ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifdef ENABLE_LOCK_ELISION ++/* Automatically enable elision for existing user lock kinds. */ ++#define FORCE_ELISION(m, s) \ ++ if (__pthread_force_elision \ ++ && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ s; \ ++ } ++#endif +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/htm.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/htm.h +@@ -0,0 +1,138 @@ ++/* Shared HTM header. Emulate transactional execution facility intrinsics for ++ compilers and assemblers that do not support the intrinsics and instructions ++ yet. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _HTM_H ++#define _HTM_H 1 ++ ++#ifdef __ASSEMBLER__ ++ ++/* tbegin. */ ++.macro TBEGIN ++ .long 0x7c00051d ++.endm ++ ++/* tend. 0 */ ++.macro TEND ++ .long 0x7c00055d ++.endm ++ ++/* tabort. code */ ++.macro TABORT code ++ .byte 0x7c ++ .byte \code ++ .byte 0x07 ++ .byte 0x1d ++.endm ++ ++/*"TEXASR - Transaction EXception And Summary Register" ++ mfspr %dst,130 */ ++.macro TEXASR dst ++ mfspr \dst,130 ++.endm ++ ++#else ++ ++#include ++ ++/* Official HTM intrinsics interface matching GCC, but works ++ on older GCC compatible compilers and binutils. ++ We should somehow detect if the compiler supports it, because ++ it may be able to generate slightly better code. */ ++ ++#define TBEGIN ".long 0x7c00051d" ++#define TEND ".long 0x7c00055d" ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++# define TABORT ".byte 0x1d,0x07,%1,0x1d" ++#else ++# define TABORT ".byte 0x7c,%1,0x07,0x1d" ++#endif ++ ++#define __force_inline inline __attribute__((__always_inline__)) ++ ++#ifndef __HTM__ ++ ++#define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \ ++ (((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1)) ++#define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \ ++ _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1) ++ ++#define _tbegin() \ ++ ({ unsigned int __ret; \ ++ asm volatile ( \ ++ TBEGIN "\t\n" \ ++ "mfcr %0\t\n" \ ++ "rlwinm %0,%0,3,1\t\n" \ ++ "xori %0,%0,1\t\n" \ ++ : "=r" (__ret) : \ ++ : "cr0", "memory"); \ ++ __ret; \ ++ }) ++ ++#define _tend() \ ++ ({ unsigned int __ret; \ ++ asm volatile ( \ ++ TEND "\t\n" \ ++ "mfcr %0\t\n" \ ++ "rlwinm %0,%0,3,1\t\n" \ ++ "xori %0,%0,1\t\n" \ ++ : "=r" (__ret) : \ ++ : "cr0", "memory"); \ ++ __ret; \ ++ }) ++ ++#define _tabort(__code) \ ++ ({ unsigned int __ret; \ ++ asm volatile ( \ ++ TABORT "\t\n" \ ++ "mfcr %0\t\n" \ ++ "rlwinm %0,%0,3,1\t\n" \ ++ "xori %0,%0,1\t\n" \ ++ : "=r" (__ret) : "r" (__code) \ ++ : "cr0", "memory"); \ ++ __ret; \ ++ }) ++ ++#define _texasru() \ ++ ({ unsigned long __ret; \ ++ asm volatile ( \ ++ "mfspr %0,131\t\n" \ ++ : "=r" (__ret)); \ ++ __ret; \ ++ }) ++ ++#define __builtin_tbegin(tdb) _tbegin () ++#define __builtin_tend(nested) _tend () ++#define __builtin_tabort(abortcode) _tabort (abortcode) ++#define __builtin_get_texasru() _texasru () ++ ++#else ++# include ++#endif /* __HTM__ */ ++ ++#endif /* __ASSEMBLER__ */ ++ ++/* Definitions used for TEXASR Failure code (bits 0:6), they need to be even ++ because tabort. always sets the first bit. */ ++#define _ABORT_LOCK_BUSY 0x3f /* Lock already used. */ ++#define _ABORT_NESTED_TRYLOCK 0x3e /* Write operation in trylock. */ ++#define _ABORT_SYSCALL 0x3d /* Syscall issued. */ ++ ++#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +@@ -326,4 +326,28 @@ extern int __lll_timedwait_tid (int *, c + __res; \ + }) + ++/* Transactional lock elision definitions. */ ++extern int __lll_timedlock_elision ++ (int *futex, short *adapt_count, const struct timespec *timeout, int private) ++ attribute_hidden; ++ ++#define lll_timedlock_elision(futex, adapt_count, timeout, private) \ ++ __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private) ++ ++extern int __lll_lock_elision (int *futex, short *adapt_count, int private) ++ attribute_hidden; ++ ++extern int __lll_unlock_elision(int *lock, int private) ++ attribute_hidden; ++ ++extern int __lll_trylock_elision(int *lock, short *adapt_count) ++ attribute_hidden; ++ ++#define lll_lock_elision(futex, adapt_count, private) \ ++ __lll_lock_elision (&(futex), &(adapt_count), private) ++#define lll_unlock_elision(futex, private) \ ++ __lll_unlock_elision (&(futex), private) ++#define lll_trylock_elision(futex, adapt_count) \ ++ __lll_trylock_elision (&(futex), &(adapt_count)) ++ + #endif /* lowlevellock.h */ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_cond_lock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_cond_lock.c +@@ -0,0 +1,22 @@ ++/* Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* The cond lock is not actually elided yet, but we still need to handle ++ already elided locks. */ ++#include ++ ++#include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_lock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_lock.c +@@ -0,0 +1,22 @@ ++/* Elided version of pthread_mutex_lock. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_timedlock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_timedlock.c +@@ -0,0 +1,22 @@ ++/* Elided version of pthread_mutex_timedlock. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_trylock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_mutex_trylock.c +@@ -0,0 +1,22 @@ ++/* Elided version of pthread_mutex_trylock. ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/bits/pthreadtypes.h +@@ -90,14 +90,25 @@ typedef union + binary compatibility. */ + int __kind; + #if __WORDSIZE == 64 +- int __spins; ++ short __spins; ++ short __elision; + __pthread_list_t __list; + # define __PTHREAD_MUTEX_HAVE_PREV 1 ++# define __PTHREAD_SPINS 0, 0 ++# define __PTHREAD_MUTEX_HAVE_ELISION 1 + #else + unsigned int __nusers; + __extension__ union + { +- int __spins; ++ struct ++ { ++ short __espins; ++ short __elision; ++# define __spins __elision_data.__espins ++# define __elision __elision_data.__elision ++# define __PTHREAD_SPINS { 0, 0 } ++# define __PTHREAD_MUTEX_HAVE_ELISION 2 ++ } __elision_data; + __pthread_slist_t __list; + }; + #endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/Makefile +@@ -1,2 +1,4 @@ + # pull in __syscall_error routine + libpthread-routines += sysdep ++libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \ ++ elision-trylock diff --git a/SOURCES/glibc-rh731835-1.patch b/SOURCES/glibc-rh731835-1.patch new file mode 100644 index 00000000..d4bfff04 --- /dev/null +++ b/SOURCES/glibc-rh731835-1.patch @@ -0,0 +1,215 @@ +commit 56cf2763819d2f721c98f2b8bcc04a3c673837d3 +Author: Adhemerval Zanella +Date: Fri Nov 7 12:34:52 2014 -0500 + + powerpc: abort transaction in syscalls + + Linux kernel powerpc documentation states issuing a syscall inside a + transaction is not recommended and may lead to undefined behavior. It + also states syscalls does not abort transactoin neither they run in + transactional state. + + To avoid side-effects being visible outside transactions, GLIBC with + lock elision enabled will issue a transaction abort instruction just + before all syscalls if hardware supports hardware transactions. + +Index: glibc-2.17-c758a686/nptl/sysdeps/powerpc/tcb-offsets.sym +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/powerpc/tcb-offsets.sym ++++ glibc-2.17-c758a686/nptl/sysdeps/powerpc/tcb-offsets.sym +@@ -15,6 +15,7 @@ MULTIPLE_THREADS_OFFSET thread_offsetof + PID thread_offsetof (pid) + TID thread_offsetof (tid) + POINTER_GUARD (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) ++TM_CAPABLE (offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) + #ifndef __ASSUME_PRIVATE_FUTEX + PRIVATE_FUTEX_OFFSET thread_offsetof (header.private_futex) + #endif +Index: glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/powerpc/tls.h ++++ glibc-2.17-c758a686/nptl/sysdeps/powerpc/tls.h +@@ -61,6 +61,15 @@ typedef union dtv + are private. */ + typedef struct + { ++ /* Indicate if HTM capable (ISA 2.07). */ ++ uint32_t tm_capable; ++ /* Reservation for AT_PLATFORM data - powerpc64. */ ++#ifdef __powerpc64__ ++ uint32_t at_platform; ++#endif ++ /* Reservation for Dynamic System Optimizer ABI. */ ++ uintptr_t dso_slot2; ++ uintptr_t dso_slot1; + /* GCC split stack support. */ + void *__private_ss; + /* Reservation for the Event-Based Branching ABI. */ +@@ -123,7 +132,11 @@ register void *__thread_register __asm__ + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ + # define TLS_INIT_TP(tcbp, secondcall) \ +- (__thread_register = (void *) (tcbp) + TLS_TCB_OFFSET, NULL) ++ ({ \ ++ __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET; \ ++ THREAD_SET_TM_CAPABLE (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM ? 1 : 0); \ ++ NULL; \ ++ }) + + /* Return the address of the dtv for the current thread. */ + # define THREAD_DTV() \ +@@ -177,6 +190,13 @@ register void *__thread_register __asm__ + + TLS_PRE_TCB_SIZE))[-1].pointer_guard \ + = THREAD_GET_POINTER_GUARD()) + ++/* tm_capable field in TCB head. */ ++# define THREAD_GET_TM_CAPABLE() \ ++ (((tcbhead_t *) ((char *) __thread_register \ ++ - TLS_TCB_OFFSET))[-1].tm_capable) ++# define THREAD_SET_TM_CAPABLE(value) \ ++ (THREAD_GET_TM_CAPABLE () = (value)) ++ + /* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some + different value to mean unset l_tls_offset. */ + # define NO_TLS_OFFSET -1 +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/sysdep.h +@@ -89,7 +89,23 @@ GOT_LABEL: ; \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(name) + ++#if ! IS_IN(rtld) && defined (ENABLE_LOCK_ELISION) ++# define ABORT_TRANSACTION \ ++ cmpwi 2,0; \ ++ beq 1f; \ ++ lwz 0,TM_CAPABLE(2); \ ++ cmpwi 0,0; \ ++ beq 1f; \ ++ li 0,_ABORT_SYSCALL; \ ++ tabort. 0; \ ++ .align 4; \ ++1: ++#else ++# define ABORT_TRANSACTION ++#endif ++ + #define DO_CALL(syscall) \ ++ ABORT_TRANSACTION \ + li 0,syscall; \ + sc + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/sysdep.h +@@ -283,7 +283,23 @@ LT_LABELSUFFIX(name,_name_end): ; \ + TRACEBACK_MASK(name,mask) \ + END_2(name) + ++#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION) ++# define ABORT_TRANSACTION \ ++ cmpdi 13,0; \ ++ beq 1f; \ ++ lwz 0,TM_CAPABLE(13); \ ++ cmpwi 0,0; \ ++ beq 1f; \ ++ li 0,_ABORT_SYSCALL; \ ++ tabort. 0; \ ++ .align 4; \ ++1: ++#else ++# define ABORT_TRANSACTION ++#endif ++ + #define DO_CALL(syscall) \ ++ ABORT_TRANSACTION \ + li 0,syscall; \ + sc + +Index: glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/powerpc/sysdep.h +@@ -21,6 +21,10 @@ + */ + #define _SYS_AUXV_H 1 + #include ++#ifdef ENABLE_LOCK_ELISION ++#include ++#include ++#endif + + #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) + +@@ -164,4 +168,22 @@ + #define ALIGNARG(log2) log2 + #define ASM_SIZE_DIRECTIVE(name) .size name,.-name + ++#else ++ ++/* Linux kernel powerpc documentation [1] states issuing a syscall inside a ++ transaction is not recommended and may lead to undefined behavior. It ++ also states syscalls do not abort transactions. To avoid such traps, ++ we abort transaction just before syscalls. ++ ++ [1] Documentation/powerpc/transactional_memory.txt [Syscalls] */ ++#if !IS_IN(rtld) && defined (ENABLE_LOCK_ELISION) ++# define ABORT_TRANSACTION \ ++ ({ \ ++ if (THREAD_GET_TM_CAPABLE ()) \ ++ __builtin_tabort (_ABORT_SYSCALL); \ ++ }) ++#else ++# define ABORT_TRANSACTION ++#endif ++ + #endif /* __ASSEMBLER__ */ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h +@@ -194,6 +194,7 @@ + register long int r11 __asm__ ("r11"); \ + register long int r12 __asm__ ("r12"); \ + LOADARGS_##nr(name, args); \ ++ ABORT_TRANSACTION; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %0" \ +Index: glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h +@@ -201,6 +201,7 @@ + register long int r7 __asm__ ("r7"); \ + register long int r8 __asm__ ("r8"); \ + LOADARGS_##nr (name, ##args); \ ++ ABORT_TRANSACTION; \ + __asm__ __volatile__ \ + ("sc\n\t" \ + "mfcr %0\n\t" \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/createthread.c +@@ -16,9 +16,16 @@ + License along with the GNU C Library; if not, see + . */ + ++/* RHEL 7-specific changes: The functions PREPARE_CREATE and TLS_VALUE ++ are used by createthread.c to override thread setup. In upstream ++ they appear in TLS_DEFINE_INIT_TP. */ ++# define PREPARE_CREATE \ ++ void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE; \ ++ (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) = \ ++ THREAD_GET_TM_CAPABLE (); ++ + /* Value passed to 'clone' for initialization of the thread register. */ +-#define TLS_VALUE ((void *) (pd) \ +- + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE) ++# define TLS_VALUE tp + + /* Get the real implementation. */ + #include diff --git a/SOURCES/glibc-rh731835-2.patch b/SOURCES/glibc-rh731835-2.patch new file mode 100644 index 00000000..c5ba166a --- /dev/null +++ b/SOURCES/glibc-rh731835-2.patch @@ -0,0 +1,43 @@ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/powerpc/elision-conf.c +@@ -61,7 +61,14 @@ elision_init (int argc __attribute__ ((u + { + #ifdef ENABLE_LOCK_ELISION + int elision_available = (GLRO (dl_hwcap2) & PPC_FEATURE2_HAS_HTM) ? 1 : 0; +- __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; ++ if (!__libc_enable_secure && elision_available) ++ { ++ __pthread_force_elision = GLRO(dl_elision_enabled); ++ } ++ else ++ { ++ __pthread_force_elision = 0; ++ } + #endif + } + +Index: glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strstr.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/powerpc/powerpc64/multiarch/strstr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strstr.c +@@ -17,7 +17,10 @@ + . */ + + /* Define multiple versions only for definition in libc. */ +-#if IS_IN (libc) ++/* RHEL 7-specific: Define multiple versions only for the definition in ++ libc. Don't define multiple versions for strstr in static library ++ since we need strstr before initialization has happened. */ ++#if defined SHARED && IS_IN (libc) + # include + # include + # include "init-arch.h" +@@ -31,4 +34,6 @@ libc_ifunc (strstr, + (hwcap & PPC_FEATURE_HAS_VSX) + ? __strstr_power7 + : __strstr_ppc); ++#else ++#include "string/strstr.c" + #endif diff --git a/SOURCES/glibc-rh731837-00.patch b/SOURCES/glibc-rh731837-00.patch new file mode 100644 index 00000000..cc933b33 --- /dev/null +++ b/SOURCES/glibc-rh731837-00.patch @@ -0,0 +1,210 @@ +From 5315ec1fd24b4f2ae6e8fa624e14da15a8efdd84 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 04:42:49 -0500 +Subject: [PATCH] PowerPC: Adjust multiarch Implies for PowerPC64 + +commit 5e6a4d4b9eb579c5ca606c0eed1f2f40e405a5f1 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:29:27 2013 -0500 + + PowerPC: Adjust multiarch Implies for PowerPC64 + + This patch adds Implies files on multiarch folder for POWER chips so + multirach is enabled when building with --with-cpu and powerN + option. + +The following file changed in the above commit is ignored as its part of already existing patch. +sysdeps/powerpc/powerpc64/power5/Implies +The following file changed in the above commit is ignored as this file is not present at 2.17 code. +sysdeps/unix/sysv/linux/powerpc/powerpc64/power8/Implies +--- + sysdeps/powerpc/powerpc64/power4/fpu/Implies | 1 + + sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power4/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power5+/fpu/Implies | 1 + + sysdeps/powerpc/powerpc64/power5+/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power5/fpu/Implies | 1 + + sysdeps/powerpc/powerpc64/power5/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power6/fpu/Implies | 1 + + sysdeps/powerpc/powerpc64/power6/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power7/fpu/Implies | 1 + + sysdeps/powerpc/powerpc64/power7/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power8/fpu/Implies | 1 + + sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power8/multiarch/Implies | 1 + + sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies | 2 -- + sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies | 2 -- + sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies | 2 -- + sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies | 2 -- + sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies | 2 -- + sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies | 2 -- + 20 files changed, 14 insertions(+), 12 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power4/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power5+/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power5+/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power5/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power5/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power6/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power6/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power7/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power7/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power8/multiarch/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/Implies +new file mode 100644 +index 0000000..c1f617b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/fpu +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies +new file mode 100644 +index 0000000..8d6531a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/multiarch/Implies +new file mode 100644 +index 0000000..30edcf7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/fpu/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/fpu/Implies +new file mode 100644 +index 0000000..f00c50f +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/fpu/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power5/fpu +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/multiarch/Implies +new file mode 100644 +index 0000000..0851b19 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power5/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/Implies +new file mode 100644 +index 0000000..558a5fb +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power4/fpu +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/multiarch/Implies +new file mode 100644 +index 0000000..9a3cbb0 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power4/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/Implies +new file mode 100644 +index 0000000..f09854e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power5+/fpu +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/multiarch/Implies +new file mode 100644 +index 0000000..2ebe304 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power5+/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/Implies +new file mode 100644 +index 0000000..30fa176 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power6/fpu +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/multiarch/Implies +new file mode 100644 +index 0000000..bf5d617 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power6/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/Implies +new file mode 100644 +index 0000000..8447198 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power7/fpu +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies +new file mode 100644 +index 0000000..7fd86fd +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power7/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/multiarch/Implies +new file mode 100644 +index 0000000..1fc7b7c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power8/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power7/multiarch +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies +deleted file mode 100644 +index bedb20b..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power4/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power4/fpu +-powerpc/powerpc64/power4 +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies +deleted file mode 100644 +index 4c782d4..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5+/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power5+/fpu +-powerpc/powerpc64/power5+ +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies +deleted file mode 100644 +index a01a13a..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power5/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power5/fpu +-powerpc/powerpc64/power5 +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies +deleted file mode 100644 +index 9d68f39..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power6/fpu +-powerpc/powerpc64/power6 +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies +deleted file mode 100644 +index 9019778..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power6x/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power6x/fpu +-powerpc/powerpc64/power6x +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies +deleted file mode 100644 +index 9a5e3c7..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/power7/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-powerpc/powerpc64/power7/fpu +-powerpc/powerpc64/power7 +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-01.patch b/SOURCES/glibc-rh731837-01.patch new file mode 100644 index 00000000..12722c04 --- /dev/null +++ b/SOURCES/glibc-rh731837-01.patch @@ -0,0 +1,537 @@ +From 46450f90b70326319f8dc7f0e447e14f0cbd95e6 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:01:14 -0500 +Subject: [PATCH] PowerPC: multiarch memcpy for PowerPC64 + +commit b5beafbceec80b5a33d3383dde88196afc966e67 Author: + Adhemerval Zanella Date: Fri Dec 13 14:31:41 + 2013 -0500 + + PowerPC: multiarch memcpy for PowerPC64 + +Added sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h which was not part +of original commit +--- + .../powerpc/powerpc32/power4/multiarch/init-arch.h | 52 +++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 4 ++ + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 66 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/init-arch.h | 18 ++++++ + sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S | 39 +++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S | 39 +++++++++++++ + .../powerpc/powerpc64/multiarch/memcpy-power4.S | 39 +++++++++++++ + .../powerpc/powerpc64/multiarch/memcpy-power6.S | 39 +++++++++++++ + .../powerpc/powerpc64/multiarch/memcpy-power7.S | 39 +++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S | 41 ++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memcpy.c | 55 ++++++++++++++++++ + 11 files changed, 431 insertions(+) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/Makefile + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/init-arch.h + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcpy.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +new file mode 100644 +index 0000000..51a34f2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h +@@ -0,0 +1,52 @@ ++/* This file is part of the GNU C Library. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* The code checks if _rtld_global_ro was realocated before trying to access ++ the dl_hwcap field. The assembly is to make the compiler not optimize the ++ test (&_rtld_global_ro != NULL), which is always true in ISO C (but not ++ in that case since _rtld_global_ro might not been realocated yet). */ ++#if defined(SHARED) && !defined(IS_IN_rtld) ++# define __GLRO(value) \ ++ ({ volatile void **__p = (volatile void**)(&_rtld_global_ro); \ ++ unsigned long int __ret; \ ++ asm ("# x in %0" : "+r" (__p)); \ ++ __ret = (__p) ? GLRO(value) : 0; \ ++ __ret; }) ++#else ++# define __GLRO(value) GLRO(value) ++#endif ++ ++/* dl_hwcap contains only the latest supported ISA, the macro checks which is ++ and fills the previous ones. */ ++#define INIT_ARCH() \ ++ unsigned long int hwcap = __GLRO(dl_hwcap); \ ++ if (hwcap & PPC_FEATURE_ARCH_2_06) \ ++ hwcap |= PPC_FEATURE_ARCH_2_05 | \ ++ PPC_FEATURE_POWER5_PLUS | \ ++ PPC_FEATURE_POWER5 | \ ++ PPC_FEATURE_POWER4; \ ++ else if (hwcap & PPC_FEATURE_ARCH_2_05) \ ++ hwcap |= PPC_FEATURE_POWER5_PLUS | \ ++ PPC_FEATURE_POWER5 | \ ++ PPC_FEATURE_POWER4; \ ++ else if (hwcap & PPC_FEATURE_POWER5_PLUS) \ ++ hwcap |= PPC_FEATURE_POWER5 | \ ++ PPC_FEATURE_POWER4; \ ++ else if (hwcap & PPC_FEATURE_POWER5) \ ++ hwcap |= PPC_FEATURE_POWER4; +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +new file mode 100644 +index 0000000..638c102 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -0,0 +1,4 @@ ++ifeq ($(subdir),string) ++sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ ++ memcpy-power4 memcpy-ppc64 ++endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +new file mode 100644 +index 0000000..5090af4 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -0,0 +1,66 @@ ++/* Enumerate available IFUNC implementations of a function. PowerPC64 version. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Maximum number of IFUNC implementations. */ ++#define MAX_IFUNC 6 ++ ++size_t ++__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, ++ size_t max) ++{ ++ assert (max >= MAX_IFUNC); ++ ++ size_t i = 0; ++ ++ unsigned long int hwcap = GLRO(dl_hwcap); ++ /* hwcap contains only the latest supported ISA, the code checks which is ++ and fills the previous supported ones. */ ++ if (hwcap & PPC_FEATURE_ARCH_2_06) ++ hwcap |= PPC_FEATURE_ARCH_2_05 | PPC_FEATURE_POWER5_PLUS | ++ PPC_FEATURE_POWER5 | PPC_FEATURE_POWER4; ++ else if (hwcap & PPC_FEATURE_ARCH_2_05) ++ hwcap |= PPC_FEATURE_POWER5_PLUS | PPC_FEATURE_POWER5 | PPC_FEATURE_POWER4; ++ else if (hwcap & PPC_FEATURE_POWER5_PLUS) ++ hwcap |= PPC_FEATURE_POWER5 | PPC_FEATURE_POWER4; ++ else if (hwcap & PPC_FEATURE_POWER5) ++ hwcap |= PPC_FEATURE_POWER4; ++ ++#ifdef SHARED ++ /* Support sysdeps/powerpc/powerpc64/multiarch/memcpy.c. */ ++ IFUNC_IMPL (i, name, memcpy, ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_HAS_VSX, ++ __memcpy_power7) ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_06, ++ __memcpy_a2) ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_ARCH_2_05, ++ __memcpy_power6) ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_CELL_BE, ++ __memcpy_cell) ++ IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_POWER4, ++ __memcpy_power4) ++ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc)) ++#endif ++ ++ return i; ++} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/init-arch.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/init-arch.h +new file mode 100644 +index 0000000..b7d238c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/init-arch.h +@@ -0,0 +1,18 @@ ++/* This file is part of the GNU C Library. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S +new file mode 100644 +index 0000000..2d5bfa9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S +@@ -0,0 +1,39 @@ ++/* Optimized memcpy implementation for PowerPC A2. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcpy_a2) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcpy_a2): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memcpy_a2,mask) \ ++ END_2(__memcpy_a2) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S +new file mode 100644 +index 0000000..92c06be +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S +@@ -0,0 +1,39 @@ ++/* Optimized memcpy implementation for PowerPC/CELL. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcpy_cell) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcpy_cell): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memcpy_cell,mask) \ ++ END_2(__memcpy_cell) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S +new file mode 100644 +index 0000000..eb01d67 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S +@@ -0,0 +1,39 @@ ++/* Optimized memcpy implementation for PowerPC64/POWER4. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcpy_power4) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcpy_power4): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memcpy_power4,mask) \ ++ END_2(__memcpy_power4) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S +new file mode 100644 +index 0000000..13b514d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S +@@ -0,0 +1,39 @@ ++/* Optimized memcpy implementation for PowerPC/POWER6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcpy_power6) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcpy_power6): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memcpy_power6,mask) \ ++ END_2(__memcpy_power6) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S +new file mode 100644 +index 0000000..2aea73d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S +@@ -0,0 +1,39 @@ ++/* Optimized memcpy implementation for PowerPC/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcpy_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcpy_power7): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memcpy_power7,mask) \ ++ END_2(__memcpy_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S +new file mode 100644 +index 0000000..b828915 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S +@@ -0,0 +1,41 @@ ++/* Default memcpy implementation for PowerPC64. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined SHARED && !defined NOT_IN_libc ++# undef EALIGN ++# define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcpy_ppc) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcpy_ppc): \ ++ cfi_startproc; ++ ++# undef END_GEN_TB ++# define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memcpy_ppc,mask) \ ++ END_2(__memcpy_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy.c +new file mode 100644 +index 0000000..305e963 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy.c +@@ -0,0 +1,55 @@ ++/* Multiple versions of memcpy. PowerPC64 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for the definition in lib and for ++ DSO. In static binaries we need memcpy before the initialization ++ happened. */ ++#if defined SHARED && !defined NOT_IN_libc ++/* Redefine memcpy so that the compiler won't complain about the type ++ mismatch with the IFUNC selector in strong_alias, below. */ ++# undef memcpy ++# define memcpy __redirect_memcpy ++# include ++# include "init-arch.h" ++ ++extern __typeof (__redirect_memcpy) __libc_memcpy; ++ ++extern __typeof (__redirect_memcpy) __memcpy_ppc attribute_hidden; ++extern __typeof (__redirect_memcpy) __memcpy_power4 attribute_hidden; ++extern __typeof (__redirect_memcpy) __memcpy_cell attribute_hidden; ++extern __typeof (__redirect_memcpy) __memcpy_power6 attribute_hidden; ++extern __typeof (__redirect_memcpy) __memcpy_a2 attribute_hidden; ++extern __typeof (__redirect_memcpy) __memcpy_power7 attribute_hidden; ++ ++libc_ifunc (__libc_memcpy, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __memcpy_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __memcpy_a2 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __memcpy_power6 : ++ (hwcap & PPC_FEATURE_CELL_BE) ++ ? __memcpy_cell : ++ (hwcap & PPC_FEATURE_POWER4) ++ ? __memcpy_power4 ++ : __memcpy_ppc); ++ ++#undef memcpy ++strong_alias (__libc_memcpy, memcpy); ++libc_hidden_ver (__libc_memcpy, memcpy); ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-02.patch b/SOURCES/glibc-rh731837-02.patch new file mode 100644 index 00000000..815a6624 --- /dev/null +++ b/SOURCES/glibc-rh731837-02.patch @@ -0,0 +1,255 @@ +From 2d5b6d3bb4813306ba5aa9ba03a56fe686bc6d4c Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:05:19 -0500 +Subject: [PATCH] PowerPC: multirach memcmp for PowerPC64 + +commit 07253fcf7b03535b26c81ee216d284ed7f1e250b +Author: Adhemerval Zanella +Date: Fri Dec 13 14:32:31 2013 -0500 +--- + string/memcmp.c | 6 +++- + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + .../powerpc/powerpc64/multiarch/memcmp-power4.S | 41 ++++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/memcmp-power7.S | 41 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c | 33 +++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memcmp.c | 39 ++++++++++++++++++++ + 7 files changed, 169 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memcmp.c + +diff --git glibc-2.17-c758a686/string/memcmp.c glibc-2.17-c758a686/string/memcmp.c +index a73cc19..4a3ef58 100644 +--- glibc-2.17-c758a686/string/memcmp.c ++++ glibc-2.17-c758a686/string/memcmp.c +@@ -30,6 +30,10 @@ + + #undef memcmp + ++#ifndef MEMCMP ++# define MEMCMP memcmp ++#endif ++ + #ifdef _LIBC + + # include +@@ -308,7 +312,7 @@ memcmp_not_common_alignment (srcp1, srcp2, len) + } + + int +-memcmp (s1, s2, len) ++MEMCMP (s1, s2, len) + const __ptr_t s1; + const __ptr_t s2; + size_t len; +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 638c102..c0bc520 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -1,4 +1,5 @@ + ifeq ($(subdir),string) + sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ +- memcpy-power4 memcpy-ppc64 ++ memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \ ++ memcmp-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 5090af4..295ebca 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -62,5 +62,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc)) + #endif + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c. */ ++ IFUNC_IMPL (i, name, memcmp, ++ IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_HAS_VSX, ++ __memcmp_power7) ++ IFUNC_IMPL_ADD (array, i, memcmp, hwcap & PPC_FEATURE_POWER4, ++ __memcmp_power4) ++ IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S +new file mode 100644 +index 0000000..12db42c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S +@@ -0,0 +1,41 @@ ++/* Optimized memcmp implementation for PowerPC64/POWER4. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcmp_power4) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcmp_power4): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__memcmp_power4) \ ++ END_2(__memcmp_power4) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name,alias) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S +new file mode 100644 +index 0000000..4898a88 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S +@@ -0,0 +1,41 @@ ++/* Optimized memcmp implementation for PowerPC64/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memcmp_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memcmp_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__memcmp_power7) \ ++ END_2(__memcmp_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name,alias) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c +new file mode 100644 +index 0000000..1a39d4a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-ppc64.c +@@ -0,0 +1,33 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define MEMCMP __memcmp_ppc ++#undef weak_alias ++#define weak_alias(name, aliasname) \ ++ extern __typeof (__memcmp_ppc) aliasname \ ++ __attribute__ ((weak, alias ("__memcmp_ppc"))); ++#if !defined(NOT_IN_libc) && defined(SHARED) ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1(__memcmp_ppc, __GI_memcmp, __memcmp_ppc); ++#endif ++ ++extern __typeof (memcmp) __memcmp_ppc attribute_hidden; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +new file mode 100644 +index 0000000..af90f0a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp.c +@@ -0,0 +1,39 @@ ++/* Multiple versions of memcmp. PowerPC64 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (memcmp) __memcmp_ppc attribute_hidden; ++extern __typeof (memcmp) __memcmp_power4 attribute_hidden; ++extern __typeof (memcmp) __memcmp_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (memcmp, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __memcmp_power7 : ++ (hwcap & PPC_FEATURE_POWER4) ++ ? __memcmp_power4 ++ : __memcmp_ppc); ++#else ++#include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-03.patch b/SOURCES/glibc-rh731837-03.patch new file mode 100644 index 00000000..221bea74 --- /dev/null +++ b/SOURCES/glibc-rh731837-03.patch @@ -0,0 +1,578 @@ +From 3cd86ba149cd650c338332dddb63e16f95041daf Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:10:37 -0500 +Subject: [PATCH] PowerPC: multiarch memset/bzero for PowerPC64 + +commit 8a29a3d00b5d8ce33fc291baecfd59d715190fd1 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:33:16 2013 -0500 + +--- + sysdeps/powerpc/powerpc64/memset.S | 2 + + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S | 26 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S | 26 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S | 26 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/bzero.c | 40 ++++++++++++++++ + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 20 ++++++++ + .../powerpc/powerpc64/multiarch/memset-power4.S | 40 ++++++++++++++++ + .../powerpc/powerpc64/multiarch/memset-power6.S | 40 ++++++++++++++++ + .../powerpc/powerpc64/multiarch/memset-power7.S | 40 ++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S | 55 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memset.c | 50 ++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c | 18 +++++++ + sysdeps/powerpc/powerpc64/power4/memset.S | 2 + + sysdeps/powerpc/powerpc64/power6/memset.S | 2 + + sysdeps/powerpc/powerpc64/power7/memset.S | 2 + + 16 files changed, 391 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/bzero.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power4.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power6.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memset.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S +index d02af98..fd5d4e5 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/memset.S +@@ -265,6 +265,7 @@ L(medium_28t): + END_GEN_TB (BP_SYM (memset),TB_TOCLESS) + libc_hidden_builtin_def (memset) + ++#ifndef NO_BZERO_IMPL + /* Copied from bzero.S to prevent the linker from inserting a stub + between bzero and memset. */ + ENTRY (BP_SYM (__bzero)) +@@ -284,3 +285,4 @@ ENTRY (BP_SYM (__bzero)) + END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS) + + weak_alias (BP_SYM (__bzero), BP_SYM (bzero)) ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index c0bc520..424d2cd 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -1,5 +1,6 @@ + ifeq ($(subdir),string) + sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \ +- memcmp-ppc64 ++ memcmp-ppc64 memset-power7 memset-power6 memset-power4 \ ++ memset-ppc64 bzero-power4 bzero-power6 bzero-power7 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S +new file mode 100644 +index 0000000..72b75ac +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power4.S +@@ -0,0 +1,26 @@ ++/* Optimized bzero implementation for PowerPC64/POWER4. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++ENTRY (__bzero_power4) ++ CALL_MCOUNT 3 ++ mr r5,r4 ++ li r4,0 ++ b __memset_power4 ++END_GEN_TB (__bzero_power4,TB_TOCLESS) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S +new file mode 100644 +index 0000000..d0917c5 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power6.S +@@ -0,0 +1,26 @@ ++/* Optimized bzero implementation for PowerPC64/POWER6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++ENTRY (__bzero_power6) ++ CALL_MCOUNT 3 ++ mr r5,r4 ++ li r4,0 ++ b __memset_power6 ++END_GEN_TB (__bzero_power6,TB_TOCLESS) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S +new file mode 100644 +index 0000000..0ec285a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero-power7.S +@@ -0,0 +1,26 @@ ++/* Optimized bzero implementation for PowerPC64/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++ENTRY (__bzero_power7) ++ CALL_MCOUNT 3 ++ mr r5,r4 ++ li r4,0 ++ b __memset_power7 ++END_GEN_TB (__bzero_power7,TB_TOCLESS) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero.c +new file mode 100644 +index 0000000..ed83541 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/bzero.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of bzero. PowerPC64 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (bzero) __bzero_ppc attribute_hidden; ++extern __typeof (bzero) __bzero_power4 attribute_hidden; ++extern __typeof (bzero) __bzero_power6 attribute_hidden; ++extern __typeof (bzero) __bzero_power7 attribute_hidden; ++ ++libc_ifunc (__bzero, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __bzero_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __bzero_power6 : ++ (hwcap & PPC_FEATURE_POWER4) ++ ? __bzero_power4 ++ : __bzero_ppc); ++ ++weak_alias (__bzero, bzero) ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 295ebca..11e7063 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -60,6 +60,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, memcpy, hwcap & PPC_FEATURE_POWER4, + __memcpy_power4) + IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/memset.c. */ ++ IFUNC_IMPL (i, name, memset, ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX, ++ __memset_power7) ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_ARCH_2_05, ++ __memset_power6) ++ IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4, ++ __memset_power4) ++ IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc)) + #endif + + /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c. */ +@@ -70,5 +80,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __memcmp_power4) + IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/bzero.c. */ ++ IFUNC_IMPL (i, name, bzero, ++ IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX, ++ __bzero_power7) ++ IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_ARCH_2_05, ++ __bzero_power6) ++ IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_POWER4, ++ __bzero_power4) ++ IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S +new file mode 100644 +index 0000000..9074b95 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S +@@ -0,0 +1,40 @@ ++/* Optimized memset implementation for PowerPC64/POWER4. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memset_power4) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memset_power4): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memset_power4,mask) \ ++ END_2(__memset_power4) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define NO_BZERO_IMPL ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S +new file mode 100644 +index 0000000..70688b5 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S +@@ -0,0 +1,40 @@ ++/* Optimized memset implementation for PowerPC64/POWER6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memset_power6) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memset_power6): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memset_power6,mask) \ ++ END_2(__memset_power6) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define NO_BZERO_IMPL ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S +new file mode 100644 +index 0000000..ab226c5 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized memset implementation for PowerPC64/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memset_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memset_power7): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memset_power7,mask) \ ++ END_2(__memset_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define NO_BZERO_IMPL ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S +new file mode 100644 +index 0000000..dc5549c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S +@@ -0,0 +1,55 @@ ++/* Default memset/bzero implementation for PowerPC64. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* Copied from bzero.S to prevent the linker from inserting a stub ++ between bzero and memset. NOTE: this code should be positioned ++ before ENTRY/END_GEN_TB redefinition. */ ++ENTRY (__bzero_ppc) ++ CALL_MCOUNT 3 ++ mr r5,r4 ++ li r4,0 ++ b L(_memset) ++END_GEN_TB (__bzero_ppc,TB_TOCLESS) ++ ++ ++#if defined SHARED && !defined NOT_IN_libc ++# undef EALIGN ++# define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__memset_ppc) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__memset_ppc): \ ++ cfi_startproc; ++ ++# undef END_GEN_TB ++# define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__memset_ppc,mask) \ ++ END_2(__memset_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) ++#endif ++ ++/* Do not implement __bzero at powerpc64/memset.S. */ ++#define NO_BZERO_IMPL ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset.c +new file mode 100644 +index 0000000..aa2ae70 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset.c +@@ -0,0 +1,50 @@ ++/* Multiple versions of memset. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#if defined SHARED && !defined NOT_IN_libc ++/* Redefine memset so that the compiler won't complain about the type ++ mismatch with the IFUNC selector in strong_alias, below. */ ++# undef memset ++# define memset __redirect_memset ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__redirect_memset) __libc_memset; ++ ++extern __typeof (__redirect_memset) __memset_ppc attribute_hidden; ++extern __typeof (__redirect_memset) __memset_power4 attribute_hidden; ++extern __typeof (__redirect_memset) __memset_power6 attribute_hidden; ++extern __typeof (__redirect_memset) __memset_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__libc_memset, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __memset_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __memset_power6 : ++ (hwcap & PPC_FEATURE_POWER4) ++ ? __memset_power4 ++ : __memset_ppc); ++ ++#undef memset ++strong_alias (__libc_memset, memset); ++libc_hidden_ver (__libc_memset, memset); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c +new file mode 100644 +index 0000000..8eac85b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rtld-memset.c +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S +index c86a68a..c077ae7 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/memset.S +@@ -253,6 +253,7 @@ L(medium_28t): + END_GEN_TB (BP_SYM (memset),TB_TOCLESS) + libc_hidden_builtin_def (memset) + ++#ifndef NO_BZERO_IMPL + /* Copied from bzero.S to prevent the linker from inserting a stub + between bzero and memset. */ + ENTRY (BP_SYM (__bzero)) +@@ -272,3 +273,4 @@ ENTRY (BP_SYM (__bzero)) + END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS) + + weak_alias (BP_SYM (__bzero), BP_SYM (bzero)) ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S +index 930ecce..967642a3 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/memset.S +@@ -397,6 +397,7 @@ L(medium_28t): + END_GEN_TB (BP_SYM (memset),TB_TOCLESS) + libc_hidden_builtin_def (memset) + ++#ifndef NO_BZERO_IMPL + /* Copied from bzero.S to prevent the linker from inserting a stub + between bzero and memset. */ + ENTRY (BP_SYM (__bzero)) +@@ -416,3 +417,4 @@ ENTRY (BP_SYM (__bzero)) + END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS) + + weak_alias (BP_SYM (__bzero), BP_SYM (bzero)) ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S +index 5970fbe..2716656 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/memset.S +@@ -385,6 +385,7 @@ L(small): + END_GEN_TB (BP_SYM (memset),TB_TOCLESS) + libc_hidden_builtin_def (memset) + ++#ifndef NO_BZERO_IMPL + /* Copied from bzero.S to prevent the linker from inserting a stub + between bzero and memset. */ + ENTRY (BP_SYM (__bzero)) +@@ -395,3 +396,4 @@ ENTRY (BP_SYM (__bzero)) + END_GEN_TB (BP_SYM (__bzero),TB_TOCLESS) + + weak_alias (BP_SYM (__bzero), BP_SYM (bzero)) ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-04.patch b/SOURCES/glibc-rh731837-04.patch new file mode 100644 index 00000000..549ee11b --- /dev/null +++ b/SOURCES/glibc-rh731837-04.patch @@ -0,0 +1,232 @@ +From 09f1f5cc860480fd09383bca00eb71e0f71aae79 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:17:26 -0500 +Subject: [PATCH] PowerPC: multiarch mempcpy for PowerPC64 + +commit f00be62b08c1440800898339f74fb4db20b19eef +Author: Adhemerval Zanella +Date: Fri Dec 13 14:34:06 2013 -0500 + +Added sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c and +string/mempcpy.c apart from original commit. +--- + string/mempcpy.c | 9 ++--- + .../powerpc32/power4/multiarch/mempcpy-ppc32.c | 32 +++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + .../powerpc/powerpc64/multiarch/mempcpy-power7.S | 41 ++++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/mempcpy-ppc64.c | 19 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/mempcpy.c | 38 ++++++++++++++++++++ + 7 files changed, 145 insertions(+), 5 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/mempcpy.c + +diff --git glibc-2.17-c758a686/string/mempcpy.c glibc-2.17-c758a686/string/mempcpy.c +index 2a542e3..7509c24 100644 +--- glibc-2.17-c758a686/string/mempcpy.c ++++ glibc-2.17-c758a686/string/mempcpy.c +@@ -26,11 +26,12 @@ + #undef mempcpy + #undef __mempcpy + ++#ifndef MEMPCPY ++# define MEMPCPY __mempcpy ++#endif ++ + void * +-__mempcpy (dstpp, srcpp, len) +- void *dstpp; +- const void *srcpp; +- size_t len; ++MEMPCPY (void *dstpp, const void *srcpp, size_t len) + { + unsigned long int dstp = (long int) dstpp; + unsigned long int srcp = (long int) srcpp; +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c +new file mode 100644 +index 0000000..8dc77e9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c +@@ -0,0 +1,32 @@ ++/* PowerPC32 default implementation of mempcpy. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define MEMPCPY __mempcpy_ppc ++ ++#undef libc_hidden_def ++#define libc_hidden_def(name) ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#if defined SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__mempcpy_ppc, __GI_mempcpy, __mempcpy_ppc); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 424d2cd..22560e8 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -2,5 +2,6 @@ ifeq ($(subdir),string) + sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \ + memcmp-ppc64 memset-power7 memset-power6 memset-power4 \ +- memset-ppc64 bzero-power4 bzero-power6 bzero-power7 ++ memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ ++ mempcpy-power7 mempcpy-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 11e7063..c72c229 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -90,5 +90,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __bzero_power4) + IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/mempcpy.c. */ ++ IFUNC_IMPL (i, name, mempcpy, ++ IFUNC_IMPL_ADD (array, i, mempcpy, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __mempcpy_power7) ++ IFUNC_IMPL_ADD (array, i, mempcpy, 1, ++ __mempcpy_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S +new file mode 100644 +index 0000000..6a79847 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S +@@ -0,0 +1,41 @@ ++/* Optimized mempcpy implementation for PowerPC/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name, alignt, words) \ ++ .section ".text"; \ ++ ENTRY_2(__mempcpy_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__mempcpy_power7): \ ++ cfi_startproc; ++ ++#undef END_GEN_TB ++#define END_GEN_TB(name, mask) \ ++ cfi_endproc; \ ++ TRACEBACK_MASK(__mempcpy_power7,mask) \ ++ END_2(__mempcpy_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c +new file mode 100644 +index 0000000..78260bb +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c +@@ -0,0 +1,19 @@ ++/* PowerPC64 default implementation of mempcpy. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c +new file mode 100644 +index 0000000..38fbcc3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c +@@ -0,0 +1,38 @@ ++/* Multiple versions of mempcpy. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__mempcpy) __mempcpy_ppc attribute_hidden; ++extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__mempcpy, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __mempcpy_power7 ++ : __mempcpy_ppc); ++ ++weak_alias (__mempcpy, mempcpy) ++libc_hidden_def (mempcpy) ++#else ++# include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-05.patch b/SOURCES/glibc-rh731837-05.patch new file mode 100644 index 00000000..429f1906 --- /dev/null +++ b/SOURCES/glibc-rh731837-05.patch @@ -0,0 +1,231 @@ +From a8d62012e2b47e8f62fafe17ab1042b0415a06ea Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:20:37 -0500 +Subject: [PATCH] PowerPC: multiarch memchr for PowerPC64 + +commit 870f867648fc62e230dad80cd34bd599f08e2193 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:35:28 2013 -0500 + +Added string/memchr.c and +sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c aart from +original commit +--- + string/memchr.c | 6 +++- + .../powerpc32/power4/multiarch/memchr-ppc32.c | 34 ++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + .../powerpc/powerpc64/multiarch/memchr-power7.S | 40 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c | 19 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memchr.c | 38 ++++++++++++++++++++ + 7 files changed, 145 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memchr.c + +diff --git glibc-2.17-c758a686/string/memchr.c glibc-2.17-c758a686/string/memchr.c +index 22637cf..822c0a4 100644 +--- glibc-2.17-c758a686/string/memchr.c ++++ glibc-2.17-c758a686/string/memchr.c +@@ -56,9 +56,13 @@ + #undef memchr + #undef __memchr + ++#ifndef MEMCHR ++# define MEMCHR __memchr ++#endif ++ + /* Search no more than N bytes of S for C. */ + __ptr_t +-__memchr (s, c_in, n) ++MEMCHR (s, c_in, n) + const __ptr_t s; + int c_in; + size_t n; +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c +new file mode 100644 +index 0000000..43c5652 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c +@@ -0,0 +1,34 @@ ++/* PowerPC32 default implementation of memchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define MEMCHR __memchr_ppc ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#ifdef SHARED ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ __hidden_ver1 (__memchr_ppc, __GI_memchr, __memchr_ppc); ++#endif ++ ++extern __typeof (memchr) __memchr_ppc attribute_hidden; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 22560e8..b2815e7 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -3,5 +3,5 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \ + memcmp-ppc64 memset-power7 memset-power6 memset-power4 \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ +- mempcpy-power7 mempcpy-ppc64 ++ mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index c72c229..663e294 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -98,5 +98,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, mempcpy, 1, + __mempcpy_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/memchr.c. */ ++ IFUNC_IMPL (i, name, memchr, ++ IFUNC_IMPL_ADD (array, i, memchr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __memchr_power7) ++ IFUNC_IMPL_ADD (array, i, memchr, 1, ++ __memchr_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S +new file mode 100644 +index 0000000..b1b4ec7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized memchr implementation for PowerPC64/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__memchr_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__memchr_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__memchr_power7) \ ++ END_2(__memchr_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name,alias) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c +new file mode 100644 +index 0000000..9e2a711 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-ppc64.c +@@ -0,0 +1,19 @@ ++/* PowerPC64 default implementation of memchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr.c +new file mode 100644 +index 0000000..ca0f714 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr.c +@@ -0,0 +1,38 @@ ++/* Multiple versions of memchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__memchr) __memchr_ppc attribute_hidden; ++extern __typeof (__memchr) __memchr_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__memchr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __memchr_power7 ++ : __memchr_ppc); ++ ++weak_alias (__memchr, memchr) ++libc_hidden_builtin_def (memchr) ++#else ++#include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-06.patch b/SOURCES/glibc-rh731837-06.patch new file mode 100644 index 00000000..06e5f726 --- /dev/null +++ b/SOURCES/glibc-rh731837-06.patch @@ -0,0 +1,201 @@ +From 6a69f5d33526bf8dafd65f3b53719402ce09d566 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:31:40 -0500 +Subject: [PATCH] PowerPC: multiarch memrchr for PowerPC64 + +commit 1fd005ad2f8ca30d44d5bfa036422b4ec281ea4a +Author: Adhemerval Zanella +Date: Fri Dec 13 14:37:26 2013 -0500 + +Added sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c +apart from original commit +--- + .../powerpc32/power4/multiarch/memrchr-ppc32.c | 25 ++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + .../powerpc/powerpc64/multiarch/memrchr-power7.S | 40 ++++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/memrchr-ppc64.c | 19 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/memrchr.c | 37 ++++++++++++++++++++ + 6 files changed, 131 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/memrchr.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c +new file mode 100644 +index 0000000..c30e7d6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/memrchr-ppc32.c +@@ -0,0 +1,25 @@ ++/* PowerPC32 default implementation of memrchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# define MEMRCHR __memrchr_ppc ++# include ++extern void *__memrchr_ppc (const void *, int, size_t); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index b2815e7..db765f2 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -3,5 +3,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memcpy-power4 memcpy-ppc64 memcmp-power7 memcmp-power4 \ + memcmp-ppc64 memset-power7 memset-power6 memset-power4 \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ +- mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 ++ mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ ++ memrchr-power7 memrchr-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 663e294..a0700dc 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -106,5 +106,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, memchr, 1, + __memchr_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/memrchr.c. */ ++ IFUNC_IMPL (i, name, memrchr, ++ IFUNC_IMPL_ADD (array, i, memrchr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __memrchr_power7) ++ IFUNC_IMPL_ADD (array, i, memrchr, 1, ++ __memrchr_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S +new file mode 100644 +index 0000000..42ee8e2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized memrchr implementation for PowerPC64/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__memrchr_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__memrchr_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__memrchr_power7) \ ++ END_2(__memrchr_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name,alias) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c +new file mode 100644 +index 0000000..c2ee4be +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-ppc64.c +@@ -0,0 +1,19 @@ ++/* PowerPC64 default implementation of memrchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +new file mode 100644 +index 0000000..610a957 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr.c +@@ -0,0 +1,37 @@ ++/* Multiple versions of memrchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__memrchr) __memrchr_ppc attribute_hidden; ++extern __typeof (__memrchr) __memrchr_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__memrchr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __memrchr_power7 ++ : __memrchr_ppc); ++ ++weak_alias (__memrchr, memrchr) ++#else ++#include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-07.patch b/SOURCES/glibc-rh731837-07.patch new file mode 100644 index 00000000..3fcaae7d --- /dev/null +++ b/SOURCES/glibc-rh731837-07.patch @@ -0,0 +1,223 @@ +From c59b219a7fb36564572a864bd61a5cdc7e37f25b Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:35:32 -0500 +Subject: [PATCH] PowerPC: multiarch rawmemchr for PowerPC64 + +commit 1fd005ad2f8ca30d44d5bfa036422b4ec281ea4a +Author: Adhemerval Zanella +Date: Fri Dec 13 14:37:26 2013 -0500 + +Added sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c and +string/rawmemchr.c apart from original commit. +--- + string/rawmemchr.c | 5 ++- + .../powerpc32/power4/multiarch/rawmemchr-ppc32.c | 32 +++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + .../powerpc/powerpc64/multiarch/rawmemchr-power7.S | 35 ++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/rawmemchr-ppc64.c | 19 +++++++++++ + sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c | 37 ++++++++++++++++++++++ + 7 files changed, 137 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c + +diff --git glibc-2.17-c758a686/string/rawmemchr.c glibc-2.17-c758a686/string/rawmemchr.c +index 90e8c7c..0e4f192 100644 +--- glibc-2.17-c758a686/string/rawmemchr.c ++++ glibc-2.17-c758a686/string/rawmemchr.c +@@ -47,10 +47,13 @@ + + #undef memchr + ++#ifndef RAWMEMCHR ++# define RAWMEMCHR __rawmemchr ++#endif + + /* Find the first occurrence of C in S. */ + __ptr_t +-__rawmemchr (s, c_in) ++RAWMEMCHR (s, c_in) + const __ptr_t s; + int c_in; + { +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c +new file mode 100644 +index 0000000..2e8abaa +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr-ppc32.c +@@ -0,0 +1,32 @@ ++/* PowerPC32 default implementation of rawmemchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define RAWMEMCHR __rawmemchr_ppc ++#undef weak_alias ++#define weak_alias(a, b) ++#ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__rawmemchr_ppc, __GI___rawmemchr, __rawmemchr_ppc); ++#endif ++ ++extern __typeof (rawmemchr) __rawmemchr_ppc attribute_hidden; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index db765f2..695112c 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -4,5 +4,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memcmp-ppc64 memset-power7 memset-power6 memset-power4 \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ +- memrchr-power7 memrchr-ppc64 ++ memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ ++ rawmemchr-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index a0700dc..5b15c3f 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -114,5 +114,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, memrchr, 1, + __memrchr_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c. */ ++ IFUNC_IMPL (i, name, rawmemchr, ++ IFUNC_IMPL_ADD (array, i, rawmemchr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __rawmemchr_power7) ++ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, ++ __rawmemchr_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S +new file mode 100644 +index 0000000..24ae3bf +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S +@@ -0,0 +1,35 @@ ++/* Optimized rawmemchr implementation for PowerPC64/POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__rawmemchr_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__rawmemchr_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__rawmemchr_power7) \ ++ END_2(__rawmemchr_power7) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c +new file mode 100644 +index 0000000..0f2f202 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-ppc64.c +@@ -0,0 +1,19 @@ ++/* PowerPC64 default implementation of rawmemchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +new file mode 100644 +index 0000000..3f53cd5 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c +@@ -0,0 +1,37 @@ ++/* Multiple versions of rawmemchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__rawmemchr) __rawmemchr_ppc attribute_hidden; ++extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__rawmemchr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __rawmemchr_power7 ++ : __rawmemchr_ppc); ++ ++weak_alias (__rawmemchr, rawmemchr) ++#else ++#include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-08.patch b/SOURCES/glibc-rh731837-08.patch new file mode 100644 index 00000000..44573ef8 --- /dev/null +++ b/SOURCES/glibc-rh731837-08.patch @@ -0,0 +1,187 @@ +From b860ebda47c7964db0582d65ad949780c4c784c5 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:39:07 -0500 +Subject: [PATCH] PowerPC: multiarch strlen for PowerPC64 + +commit a65f4904ab96de789d13f2c4f27c2d82959a546d +Author: Adhemerval Zanella +Date: Fri Dec 13 14:38:17 2013 -0500 +--- + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 7 ++++ + .../powerpc/powerpc64/multiarch/strlen-power7.S | 38 ++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S | 40 +++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strlen.c | 41 ++++++++++++++++++++++ + 5 files changed, 127 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strlen.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 695112c..9da7be1 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -5,5 +5,5 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ +- rawmemchr-ppc64 ++ rawmemchr-ppc64 strlen-power7 strlen-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 5b15c3f..bdc908b 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -70,6 +70,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_POWER4, + __memset_power4) + IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strlen.c. */ ++ IFUNC_IMPL (i, name, strlen, ++ IFUNC_IMPL_ADD (array, i, strlen, hwcap & PPC_FEATURE_HAS_VSX, ++ __strlen_power7) ++ IFUNC_IMPL_ADD (array, i, strlen, 1, ++ __strlen_ppc)) + #endif + + /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c. */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S +new file mode 100644 +index 0000000..a38521d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S +@@ -0,0 +1,38 @@ ++/* Optimized strlen implementation for POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strlen_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strlen_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strlen_power7) \ ++ END_2(__strlen_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S +new file mode 100644 +index 0000000..b463b3a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S +@@ -0,0 +1,40 @@ ++/* Default strlen implementation for PowerPC64. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined SHARED && !defined NOT_IN_libc ++# undef ENTRY ++# define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strlen_ppc) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strlen_ppc): \ ++ cfi_startproc; ++ ++# undef END ++# define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strlen_ppc) \ ++ END_2(__strlen_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen.c +new file mode 100644 +index 0000000..d2c26e9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen.c +@@ -0,0 +1,41 @@ ++/* Multiple versions of strlen. PowerPC64 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#if defined SHARED && !defined NOT_IN_libc ++/* Redefine strlen so that the compiler won't complain about the type ++ mismatch with the IFUNC selector in strong_alias, below. */ ++# undef strlen ++# define strlen __redirect_strlen ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__redirect_strlen) __libc_strlen; ++ ++extern __typeof (__redirect_strlen) __strlen_ppc attribute_hidden; ++extern __typeof (__redirect_strlen) __strlen_power7 attribute_hidden; ++ ++libc_ifunc (__libc_strlen, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strlen_power7 ++ : __strlen_ppc); ++ ++#undef strlen ++strong_alias (__libc_strlen, strlen) ++libc_hidden_ver (__libc_strlen, strlen) ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-09.patch b/SOURCES/glibc-rh731837-09.patch new file mode 100644 index 00000000..8b7e29ff --- /dev/null +++ b/SOURCES/glibc-rh731837-09.patch @@ -0,0 +1,199 @@ +From dc5a73198455f4492a44dbc71fdadeb7551d5810 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:41:40 -0500 +Subject: [PATCH] PowerPC: multiarch strnlen for PowerPC64 + +commit 62982bf9782f0f3ef4259fc03b1b557f1332b182 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:38:50 2013 -0500 + +Added sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c +apart from original commit. +--- + .../powerpc32/power4/multiarch/strnlen-ppc32.c | 26 ++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 7 ++++ + .../powerpc/powerpc64/multiarch/strnlen-power7.S | 40 ++++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/strnlen-ppc64.c | 18 ++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strnlen.c | 36 +++++++++++++++++++ + 6 files changed, 129 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strnlen.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c +new file mode 100644 +index 0000000..676d837 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen-ppc32.c +@@ -0,0 +1,26 @@ ++/* Default strnlen implementation for PowerPC32. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define STRNLEN __strnlen_ppc ++#ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__strnlen_ppc, __GI_strnlen, __strnlen_ppc); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 9da7be1..3285fd7 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -5,5 +5,6 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memset-ppc64 bzero-power4 bzero-power6 bzero-power7 \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ +- rawmemchr-ppc64 strlen-power7 strlen-ppc64 ++ rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ ++ strnlen-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index bdc908b..c9125b8 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -129,5 +129,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, rawmemchr, 1, + __rawmemchr_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strnlen.c. */ ++ IFUNC_IMPL (i, name, strnlen, ++ IFUNC_IMPL_ADD (array, i, strnlen, hwcap & PPC_FEATURE_HAS_VSX, ++ __strnlen_power7) ++ IFUNC_IMPL_ADD (array, i, strnlen, 1, ++ __strnlen_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S +new file mode 100644 +index 0000000..909aae8 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S +@@ -0,0 +1,40 @@ ++/* Optimized strnlen version for POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strnlen_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strnlen_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strnlen_power7) \ ++ END_2(__strnlen_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c +new file mode 100644 +index 0000000..9d23994 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-ppc64.c +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +new file mode 100644 +index 0000000..3926031 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen.c +@@ -0,0 +1,36 @@ ++/* Multiple versions of strnlen. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__strnlen) __strnlen_ppc attribute_hidden; ++extern __typeof (__strnlen) __strnlen_power7 attribute_hidden; ++ ++libc_ifunc (__strnlen, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strnlen_power7 ++ : __strnlen_ppc); ++weak_alias (__strnlen, strnlen) ++libc_hidden_def (strnlen) ++ ++#else ++#include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-10.patch b/SOURCES/glibc-rh731837-10.patch new file mode 100644 index 00000000..b180df23 --- /dev/null +++ b/SOURCES/glibc-rh731837-10.patch @@ -0,0 +1,247 @@ +From 4a6eeaf792815ff197f683e424d64cc3a9e16a66 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:47:00 -0500 +Subject: [PATCH] PowerPC: multiarch strcasecmp for PowerPC64 + +commit 17de3ee3c109a13ecec60b8bc9514f33c5b42178 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:39:51 2013 -0500 +--- + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 15 ++++++++ + .../powerpc64/multiarch/strcasecmp-power7.S | 41 +++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c | 40 ++++++++++++++++++++ + .../powerpc64/multiarch/strcasecmp_l-power7.S | 43 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c | 40 ++++++++++++++++++++ + 6 files changed, 180 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 3285fd7..5e172da 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -6,5 +6,5 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ +- strnlen-ppc64 ++ strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index c9125b8..ba78d97 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -136,5 +136,20 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strnlen, 1, + __strnlen_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c. */ ++ IFUNC_IMPL (i, name, strcasecmp, ++ IFUNC_IMPL_ADD (array, i, strcasecmp, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strcasecmp_power7) ++ IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c. */ ++ IFUNC_IMPL (i, name, strcasecmp_l, ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strcasecmp_l_power7) ++ IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, ++ __strcasecmp_l_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S +new file mode 100644 +index 0000000..9714f88 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S +@@ -0,0 +1,41 @@ ++/* Optimized strcasecmp implementation foOWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strcasecmp_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strcasecmp_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcasecmp_power7) \ ++ END_2(__strcasecmp_power7) ++ ++#undef weak_alias ++#define weak_alias(name, alias) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +new file mode 100644 +index 0000000..7f02a25 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of strcasecmp. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# define strcasecmp __strcasecmp_ppc ++extern __typeof (__strcasecmp) __strcasecmp_ppc attribute_hidden; ++extern __typeof (__strcasecmp) __strcasecmp_power7 attribute_hidden; ++#endif ++ ++#include ++#undef strcasecmp ++ ++#ifndef NOT_IN_libc ++# include ++# include "init-arch.h" ++ ++extern __typeof (__strcasecmp) __libc_strcasecmp; ++libc_ifunc (__libc_strcasecmp, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcasecmp_power7 ++ : __strcasecmp_ppc); ++ ++weak_alias (__libc_strcasecmp, strcasecmp) ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S +new file mode 100644 +index 0000000..117e464 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S +@@ -0,0 +1,43 @@ ++/* Optimized strcasecmp_l implementation for POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strcasecmp_l_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strcasecmp_l_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strcasecmp_l_power7) \ ++ END_2(__strcasecmp_l_power7) ++ ++#undef weak_alias ++#define weak_alias(name, alias) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#define USE_IN_EXTENDED_LOCALE_MODEL ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c +new file mode 100644 +index 0000000..a3374c3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of strcasecmp_l. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# define strcasecmp_l __strcasecmp_l_ppc ++extern __typeof (__strcasecmp_l) __strcasecmp_l_ppc attribute_hidden; ++extern __typeof (__strcasecmp_l) __strcasecmp_l_power7 attribute_hidden; ++#endif ++ ++#include ++#undef strcasecmp_l ++ ++#ifndef NOT_IN_libc ++# include ++# include "init-arch.h" ++ ++extern __typeof (__strcasecmp_l) __libc_strcasecmp_l; ++libc_ifunc (__libc_strcasecmp_l, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strcasecmp_l_power7 ++ : __strcasecmp_l_ppc); ++ ++weak_alias (__libc_strcasecmp_l, strcasecmp_l) ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-11.patch b/SOURCES/glibc-rh731837-11.patch new file mode 100644 index 00000000..d0e47e86 --- /dev/null +++ b/SOURCES/glibc-rh731837-11.patch @@ -0,0 +1,219 @@ +From 0c36ea57312ce701930b879d49b3f64cead222d8 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:48:25 -0500 +Subject: [PATCH] PowerPC: multiarch strncasecmp for PowerPC64 + +commit 1c92d9a0e0be6175915128157036cf138ef64af8 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:40:28 2013 -0500 +--- + sysdeps/powerpc/powerpc64/multiarch/Makefile | 6 +++- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 15 ++++++++ + .../powerpc/powerpc64/multiarch/strncase-power7.c | 24 +++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strncase.c | 41 +++++++++++++++++++++ + .../powerpc64/multiarch/strncase_l-power7.c | 25 +++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strncase_l.c | 42 ++++++++++++++++++++++ + 6 files changed, 152 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncase_l.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 5e172da..4dca756 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -6,5 +6,9 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + mempcpy-power7 mempcpy-ppc64 memchr-power7 memchr-ppc64 \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ +- strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 ++ strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ ++ strncase-power7 strncase_l-power7 ++ ++CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops ++CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index ba78d97..4b8fb22 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -151,5 +151,20 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, + __strcasecmp_l_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strncase.c. */ ++ IFUNC_IMPL (i, name, strncasecmp, ++ IFUNC_IMPL_ADD (array, i, strncasecmp, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strncasecmp_power7) ++ IFUNC_IMPL_ADD (array, i, strncasecmp, 1, __strncasecmp_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strncase_l.c. */ ++ IFUNC_IMPL (i, name, strncasecmp_l, ++ IFUNC_IMPL_ADD (array, i, strncasecmp_l, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strncasecmp_l_power7) ++ IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, ++ __strncasecmp_l_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c +new file mode 100644 +index 0000000..9c5dbab +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase-power7.c +@@ -0,0 +1,24 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define __strncasecmp __strncasecmp_power7 ++ ++extern __typeof (strncasecmp) __strncasecmp_power7 attribute_hidden; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase.c +new file mode 100644 +index 0000000..05eba7c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase.c +@@ -0,0 +1,41 @@ ++/* Multiple versions of strncasecmp ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# define strncasecmp __strncasecmp_ppc ++extern __typeof (__strncasecmp) __strncasecmp_ppc attribute_hidden; ++extern __typeof (__strncasecmp) __strncasecmp_power7 attribute_hidden; ++#endif ++ ++#include ++#undef strncasecmp ++ ++#ifndef NOT_IN_libc ++# include ++# include "init-arch.h" ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++extern __typeof (__strncasecmp) __libc_strncasecmp; ++libc_ifunc (__libc_strncasecmp, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strncasecmp_power7 ++ : __strncasecmp_ppc); ++weak_alias (__libc_strncasecmp, strncasecmp) ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c +new file mode 100644 +index 0000000..8c8cd8d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l-power7.c +@@ -0,0 +1,25 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define __strncasecmp_l __strncasecmp_l_power7 ++#define USE_IN_EXTENDED_LOCALE_MODEL 1 ++ ++extern __typeof (strncasecmp_l) __strncasecmp_l_power7 attribute_hidden; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c +new file mode 100644 +index 0000000..4014269 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncase_l.c +@@ -0,0 +1,42 @@ ++/* Multiple versions of strncasecmp_l ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# define strncasecmp_l __strncasecmp_l_ppc ++extern __typeof (__strncasecmp_l) __strncasecmp_l_ppc attribute_hidden; ++extern __typeof (__strncasecmp_l) __strncasecmp_l_power7 attribute_hidden; ++#endif ++ ++#include ++#undef strncasecmp_l ++ ++#ifndef NOT_IN_libc ++# include ++# include "init-arch.h" ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++extern __typeof (__strncasecmp_l) __libc_strncasecmp_l; ++libc_ifunc (__libc_strncasecmp_l, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strncasecmp_l_power7 ++ : __strncasecmp_l_ppc); ++ ++weak_alias (__libc_strncasecmp_l, strncasecmp_l) ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-12.patch b/SOURCES/glibc-rh731837-12.patch new file mode 100644 index 00000000..73f040d4 --- /dev/null +++ b/SOURCES/glibc-rh731837-12.patch @@ -0,0 +1,236 @@ +From fda2d6aca32ad6a4d546ab3a7dd708de78e18c3a Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:49:36 -0500 +Subject: [PATCH] PowerPC: multiarch strncmp for PowerPC64 + +commit 24c2c3b99699b7cb7cc3c251d9bd504b2cde6a45 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:48:48 2013 -0500 +--- + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 9 +++++ + .../powerpc/powerpc64/multiarch/strncmp-power4.S | 38 ++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/strncmp-power7.S | 39 ++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/strncmp-ppc64.S | 41 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strncmp.c | 37 +++++++++++++++++++ + 6 files changed, 166 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strncmp.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 4dca756..22baf1c 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -7,7 +7,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + memrchr-power7 memrchr-ppc64 rawmemchr-power7 \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ +- strncase-power7 strncase_l-power7 ++ strncase-power7 strncase_l-power7 strncmp-power7 \ ++ strncmp-power4 strncmp-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 4b8fb22..67f75a5 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -77,6 +77,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __strlen_power7) + IFUNC_IMPL_ADD (array, i, strlen, 1, + __strlen_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strncmp.c. */ ++ IFUNC_IMPL (i, name, strncmp, ++ IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_HAS_VSX, ++ __strncmp_power7) ++ IFUNC_IMPL_ADD (array, i, strncmp, hwcap & PPC_FEATURE_POWER4, ++ __strncmp_power4) ++ IFUNC_IMPL_ADD (array, i, strncmp, 1, ++ __strncmp_ppc)) + #endif + + /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c. */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S +new file mode 100644 +index 0000000..62cebbc +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S +@@ -0,0 +1,38 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name,alignt,words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncmp_power4) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncmp_power4): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncmp_power4) \ ++ END_2(__strncmp_power4) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S +new file mode 100644 +index 0000000..b0d607a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S +@@ -0,0 +1,39 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef EALIGN ++#define EALIGN(name,alignt,words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncmp_power7) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncmp_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncmp_power7) \ ++ END_2(__strncmp_power7) ++ ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S +new file mode 100644 +index 0000000..25b7f26 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S +@@ -0,0 +1,41 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if defined SHARED && !defined NOT_IN_libc ++#undef EALIGN ++#define EALIGN(name,alignt,words) \ ++ .section ".text"; \ ++ ENTRY_2(__strncmp_ppc) \ ++ .align ALIGNARG(alignt); \ ++ EALIGN_W_##words; \ ++ BODY_LABEL(__strncmp_ppc): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strncmp_ppc) \ ++ END_2(__strncmp_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ .globl __GI_strncmp; __GI_strncmp = __strncmp_ppc ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +new file mode 100644 +index 0000000..9829d69 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp.c +@@ -0,0 +1,37 @@ ++/* Multiple versions of strncmp. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#if defined SHARED && !defined NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strncmp) __strncmp_ppc attribute_hidden; ++extern __typeof (strncmp) __strncmp_power4 attribute_hidden; ++extern __typeof (strncmp) __strncmp_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (strncmp, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strncmp_power7 : ++ (hwcap & PPC_FEATURE_POWER4) ++ ? __strncmp_power4 ++ : __strncmp_ppc); ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-13.patch b/SOURCES/glibc-rh731837-13.patch new file mode 100644 index 00000000..4a35bbf8 --- /dev/null +++ b/SOURCES/glibc-rh731837-13.patch @@ -0,0 +1,211 @@ +From 1a5121cbdc34d9f56bb1bbb3f3ce3a90ddc1ff6b Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:55:13 -0500 +Subject: [PATCH] PowerPC: multiarch strchr for PowerPC64 + +commit 372dc060e0a25044ba5a797c71fb0ee53921fe47 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:49:54 2013 -0500 +--- + sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S | 18 ++++++++++ + .../powerpc/powerpc64/multiarch/strchr-power7.S | 38 ++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S | 41 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strchr.c | 35 ++++++++++++++++++ + 6 files changed, 141 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchr.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 22baf1c..f7c5853 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -8,7 +8,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 strncmp-power7 \ +- strncmp-power4 strncmp-ppc64 ++ strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 67f75a5..3b005ea 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -86,6 +86,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __strncmp_power4) + IFUNC_IMPL_ADD (array, i, strncmp, 1, + __strncmp_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strchr.c. */ ++ IFUNC_IMPL (i, name, strchr, ++ IFUNC_IMPL_ADD (array, i, strchr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strchr_power7) ++ IFUNC_IMPL_ADD (array, i, strchr, 1, ++ __strchr_ppc)) + #endif + + /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c. */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S +new file mode 100644 +index 0000000..5c62657 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rtld-strchr.S +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S +new file mode 100644 +index 0000000..0b2ca42 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S +@@ -0,0 +1,38 @@ ++/* Optimized strchr implementation for POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strchr_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strchr_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strchr_power7) \ ++ END_2(__strchr_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S +new file mode 100644 +index 0000000..ded9284 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S +@@ -0,0 +1,41 @@ ++/* PowerPC64 default implementation of strchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifdef SHARED ++# undef ENTRY ++# define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strchr_ppc) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strchr_ppc): \ ++ cfi_startproc; ++ ++# undef END ++# define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strchr_ppc) \ ++ END_2(__strchr_ppc) ++ ++# undef libc_hidden_builtin_def ++# define libc_hidden_builtin_def(name) \ ++ .globl __GI_strchr; __GI_strchr = __strchr_ppc ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr.c +new file mode 100644 +index 0000000..74a9d54 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr.c +@@ -0,0 +1,35 @@ ++/* Multiple versions of strchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Define multiple versions only for definition in libc. */ ++#if defined SHARED && !defined NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (strchr) __strchr_ppc attribute_hidden; ++extern __typeof (strchr) __strchr_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (strchr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strchr_power7 ++ : __strchr_ppc); ++weak_alias (strchr, index) ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-14.patch b/SOURCES/glibc-rh731837-14.patch new file mode 100644 index 00000000..6aeafa74 --- /dev/null +++ b/SOURCES/glibc-rh731837-14.patch @@ -0,0 +1,225 @@ +From 942cdf02caef0ea4fe257cf5898754b9b1897c4a Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 05:58:14 -0500 +Subject: [PATCH] PowerPC: multiarch strchrnul for PowerPC64 + +commit 9ee2969b057862443b81789b56a61514edf34779 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:50:26 2013 -0500 + +Added sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c and +string/strchrnul.c apart from original commit. +--- + string/strchrnul.c | 6 +++- + .../powerpc32/power4/multiarch/strchrnul-ppc32.c | 28 ++++++++++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 3 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 8 +++++ + .../powerpc/powerpc64/multiarch/strchrnul-power7.S | 38 ++++++++++++++++++++++ + .../powerpc/powerpc64/multiarch/strchrnul-ppc64.c | 19 +++++++++++ + sysdeps/powerpc/powerpc64/multiarch/strchrnul.c | 37 +++++++++++++++++++++ + 7 files changed, 137 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strchrnul.c + +diff --git glibc-2.17-c758a686/string/strchrnul.c glibc-2.17-c758a686/string/strchrnul.c +index 0db5e23..39540a3 100644 +--- glibc-2.17-c758a686/string/strchrnul.c ++++ glibc-2.17-c758a686/string/strchrnul.c +@@ -27,9 +27,13 @@ + #undef __strchrnul + #undef strchrnul + ++#ifndef STRCHRNUL ++# define STRCHRNUL __strchrnul ++#endif ++ + /* Find the first occurrence of C in S or the final NUL byte. */ + char * +-__strchrnul (s, c_in) ++STRCHRNUL (s, c_in) + const char *s; + int c_in; + { +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c +new file mode 100644 +index 0000000..950643a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/strchrnul-ppc32.c +@@ -0,0 +1,28 @@ ++/* PowerPC32 default implementation of strchrnul. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define STRCHRNUL __strchrnul_ppc ++ ++#undef weak_alias ++#define weak_alias(a,b ) ++ ++extern __typeof (strchrnul) __strchrnul_ppc attribute_hidden; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index f7c5853..15b86bd 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -8,7 +8,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + rawmemchr-ppc64 strlen-power7 strlen-ppc64 strnlen-power7 \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 strncmp-power7 \ +- strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 ++ strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \ ++ strchrnul-power7 strchrnul-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 3b005ea..9e3b89d 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -94,6 +94,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + __strchr_power7) + IFUNC_IMPL_ADD (array, i, strchr, 1, + __strchr_ppc)) ++ ++ /* Support sysdeps/powerpc/powerpc64/multiarch/strchrnul.c. */ ++ IFUNC_IMPL (i, name, strchrnul, ++ IFUNC_IMPL_ADD (array, i, strchrnul, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __strchrnul_power7) ++ IFUNC_IMPL_ADD (array, i, strchrnul, 1, ++ __strchrnul_ppc)) + #endif + + /* Support sysdeps/powerpc/powerpc64/multiarch/memcmp.c. */ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S +new file mode 100644 +index 0000000..87d7c03 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S +@@ -0,0 +1,38 @@ ++/* Optimized strchrnul implementation for POWER7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef ENTRY ++#define ENTRY(name) \ ++ .section ".text"; \ ++ ENTRY_2(__strchrnul_power7) \ ++ .align ALIGNARG(2); \ ++ BODY_LABEL(__strchrnul_power7): \ ++ cfi_startproc; ++ ++#undef END ++#define END(name) \ ++ cfi_endproc; \ ++ TRACEBACK(__strchrnul_power7) \ ++ END_2(__strchrnul_power7) ++ ++#undef libc_hidden_builtin_def ++#define libc_hidden_builtin_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c +new file mode 100644 +index 0000000..a76b335 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-ppc64.c +@@ -0,0 +1,19 @@ ++/* PowerPC64 default implementation of strchrnul. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +new file mode 100644 +index 0000000..dab1cbf +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul.c +@@ -0,0 +1,37 @@ ++/* Multiple versions of strchrnul. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (__strchrnul) __strchrnul_ppc attribute_hidden; ++extern __typeof (__strchrnul) __strchrnul_power7 attribute_hidden; ++ ++/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ++ ifunc symbol properly. */ ++libc_ifunc (__strchrnul, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __strchrnul_power7 ++ : __strchrnul_ppc); ++ ++weak_alias (__strchrnul, strchrnul) ++#else ++#include ++#endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-15.patch b/SOURCES/glibc-rh731837-15.patch new file mode 100644 index 00000000..460312aa --- /dev/null +++ b/SOURCES/glibc-rh731837-15.patch @@ -0,0 +1,398 @@ +From be1d5d1d239883daea876f39e804d87ca028fe2c Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 07:33:06 -0500 +Subject: [PATCH] PowerPC: multiarch wcschr for PowerPC64 + +commit 16fd2ae37cce401aad580d3d6ffae825827231ae +Author: Adhemerval Zanella +Date: Fri Dec 13 14:51:36 2013 -0500 + +Added the following files apart from original commit. +sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c +sysdeps/powerpc/powerpc64/power6/wcschr.c +sysdeps/powerpc/power6/wcschr.c +--- + sysdeps/powerpc/power6/wcschr.c | 89 ++++++++++++++++++++++ + .../powerpc32/power4/multiarch/wcschr-power6.c | 26 +++++++ + .../powerpc32/power4/multiarch/wcschr-power7.c | 26 +++++++ + .../powerpc32/power4/multiarch/wcschr-ppc32.c | 31 ++++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 5 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 11 +++ + .../powerpc/powerpc64/multiarch/wcschr-power6.c | 19 +++++ + .../powerpc/powerpc64/multiarch/wcschr-power7.c | 19 +++++ + sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c | 18 +++++ + sysdeps/powerpc/powerpc64/multiarch/wcschr.c | 38 +++++++++ + sysdeps/powerpc/powerpc64/power6/wcschr.c | 2 +- + 11 files changed, 282 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/power6/wcschr.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcschr.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power6/wcschr.c glibc-2.17-c758a686/sysdeps/powerpc/power6/wcschr.c +new file mode 100644 +index 0000000..7045677 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power6/wcschr.c +@@ -0,0 +1,89 @@ ++/* wcschr.c - Wide Character Search for POWER6+. ++ Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++ ++#ifndef WCSCHR ++# define WCSCHR wcschr ++#endif ++ ++/* Find the first occurrence of WC in WCS. */ ++wchar_t * ++WCSCHR (const wchar_t *wcs, const wchar_t wc) ++{ ++ const wchar_t *wcs2 = wcs + 1; ++ ++ if (*wcs == wc) ++ return (wchar_t *) wcs; ++ if (*wcs == L'\0') ++ return NULL; ++ ++ do ++ { ++ wcs += 2; ++ ++ if (*wcs2 == wc) ++ return (wchar_t *) wcs2; ++ if (*wcs2 == L'\0') ++ return NULL; ++ wcs2 += 2; ++ ++ if (*wcs == wc) ++ return (wchar_t *) wcs; ++ if (*wcs == L'\0') ++ return NULL; ++ wcs += 2; ++ ++ if (*wcs2 == wc) ++ return (wchar_t *) wcs2; ++ if (*wcs2 == L'\0') ++ return NULL; ++ wcs2 += 2; ++ ++ if (*wcs == wc) ++ return (wchar_t *) wcs; ++ if (*wcs == L'\0') ++ return NULL; ++ wcs += 2; ++ ++ if (*wcs2 == wc) ++ return (wchar_t *) wcs2; ++ if (*wcs2 == L'\0') ++ return NULL; ++ wcs2 += 2; ++ ++ if (*wcs == wc) ++ return (wchar_t *) wcs; ++ if (*wcs == L'\0') ++ return NULL; ++ wcs += 2; ++ ++ if (*wcs2 == wc) ++ return (wchar_t *) wcs2; ++ if (*wcs2 == L'\0') ++ return NULL; ++ wcs2 += 2; ++ ++ if (*wcs == wc) ++ return (wchar_t *) wcs; ++ } ++ while (*wcs != L'\0'); ++ ++ return NULL; ++} ++libc_hidden_def (wcschr) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c +new file mode 100644 +index 0000000..7c648d8 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power6.c +@@ -0,0 +1,26 @@ ++/* wcschr.c - Wide Character Search for powerpc32/power6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++ ++#define WCSCHR __wcschr_power6 ++ ++#undef libc_hidden_def ++#define libc_hidden_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c +new file mode 100644 +index 0000000..e561ced +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-power7.c +@@ -0,0 +1,26 @@ ++/* wcschr.c - Wide Character Search for powerpc32/power7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++ ++#define WCSCHR __wcschr_power7 ++ ++#undef libc_hidden_def ++#define libc_hidden_def(name) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c +new file mode 100644 +index 0000000..a42f70c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcschr-ppc32.c +@@ -0,0 +1,31 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifndef NOT_IN_libc ++# ifdef SHARED ++# undef libc_hidden_def ++# define libc_hidden_def(name) \ ++ __hidden_ver1 (__wcschr_ppc, __GI_wcschr, __wcschr_ppc); ++# endif ++# define WCSCHR __wcschr_ppc ++#endif ++ ++extern __typeof (wcschr) __wcschr_ppc; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 15b86bd..ff3b8cf 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -9,8 +9,11 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strnlen-ppc64 strcasecmp-power7 strcasecmp_l-power7 \ + strncase-power7 strncase_l-power7 strncmp-power7 \ + strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \ +- strchrnul-power7 strchrnul-ppc64 ++ strchrnul-power7 strchrnul-ppc64 wcschr-power7 \ ++ wcschr-power6 wcschr-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops ++CFLAGS-wcschr-power7.c += -mcpu=power7 ++CFLAGS-wcschr-power6.c += -mcpu=power6 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 9e3b89d..cc932c9 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -191,5 +191,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, + __strncasecmp_l_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c. */ ++ IFUNC_IMPL (i, name, wcschr, ++ IFUNC_IMPL_ADD (array, i, wcschr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __wcschr_power7) ++ IFUNC_IMPL_ADD (array, i, wcschr, ++ hwcap & PPC_FEATURE_ARCH_2_05, ++ __wcschr_power6) ++ IFUNC_IMPL_ADD (array, i, wcschr, 1, ++ __wcschr_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c +new file mode 100644 +index 0000000..21d965a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-power6.c +@@ -0,0 +1,19 @@ ++/* wcschr.c - Wide Character Search for powerpc64/power6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c +new file mode 100644 +index 0000000..3407219 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-power7.c +@@ -0,0 +1,19 @@ ++/* wcschr.c - Wide Character Search for powerpc64/power7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c +new file mode 100644 +index 0000000..3f1f368 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr-ppc64.c +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr.c +new file mode 100644 +index 0000000..216d2bc +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcschr.c +@@ -0,0 +1,38 @@ ++/* Multiple versions of wcschr ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (wcschr) __wcschr_ppc attribute_hidden; ++extern __typeof (wcschr) __wcschr_power6 attribute_hidden; ++extern __typeof (wcschr) __wcschr_power7 attribute_hidden; ++ ++libc_ifunc (wcschr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __wcschr_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __wcschr_power6 ++ : __wcschr_ppc); ++#else ++#undef libc_hidden_def ++#define libc_hidden_def(a) ++#include ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcschr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcschr.c +index 9136c02..ae04a13 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcschr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcschr.c +@@ -1 +1 @@ +-#include "../../powerpc32/power6/wcschr.c" ++#include +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-16.patch b/SOURCES/glibc-rh731837-16.patch new file mode 100644 index 00000000..9f7f28d2 --- /dev/null +++ b/SOURCES/glibc-rh731837-16.patch @@ -0,0 +1,401 @@ +From 62edac04130e7d91b0d4872376bdaa976065fd25 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 07:40:10 -0500 +Subject: [PATCH] PowerPC: multiarch wcsrchr for PowerPC64 + +commit 7b714620a7146104aaf863ba1dbe386beedbcc0a +Author: Adhemerval Zanella +Date: Fri Dec 13 14:52:48 2013 -0500 + +Added the following files apart from original commit. +sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c +sysdeps/powerpc/powerpc64/power6/wcsrchr.c +wcsmbs/wcsrchr.c +--- + sysdeps/powerpc/power6/wcsrchr.c | 89 ++++++++++++++++++++++ + .../powerpc32/power4/multiarch/wcsrchr-power6.c | 20 +++++ + .../powerpc32/power4/multiarch/wcsrchr-power7.c | 20 +++++ + .../powerpc32/power4/multiarch/wcsrchr-ppc32.c | 26 +++++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 5 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 11 +++ + .../powerpc/powerpc64/multiarch/wcsrchr-power6.c | 19 +++++ + .../powerpc/powerpc64/multiarch/wcsrchr-power7.c | 19 +++++ + .../powerpc/powerpc64/multiarch/wcsrchr-ppc64.c | 18 +++++ + sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c | 36 +++++++++ + sysdeps/powerpc/powerpc64/power6/wcsrchr.c | 2 +- + wcsmbs/wcsrchr.c | 5 +- + 12 files changed, 267 insertions(+), 3 deletions(-) + create mode 100644 sysdeps/powerpc/power6/wcsrchr.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power6/wcsrchr.c glibc-2.17-c758a686/sysdeps/powerpc/power6/wcsrchr.c +new file mode 100644 +index 0000000..278d98d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power6/wcsrchr.c +@@ -0,0 +1,89 @@ ++/* wcsrchr.c - Wide Character Reverse Search for POWER6+. ++ Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++ ++#ifndef WCSRCHR ++# define WCSRCHR wcsrchr ++#endif ++ ++/* Find the last occurrence of WC in WCS. */ ++wchar_t * ++WCSRCHR (const wchar_t *wcs, const wchar_t wc) ++{ ++ const wchar_t *wcs2 = wcs + 1; ++ const wchar_t *retval = NULL; ++ ++ if (*wcs == wc) ++ retval = wcs; ++ ++ if (*wcs == L'\0') return (wchar_t *) retval; ++ ++ do ++ { ++ wcs+=2; ++ ++ if (*wcs2 == wc) ++ retval = wcs2; ++ if (*wcs2 == L'\0') ++ return (wchar_t *) retval; ++ wcs2+=2; ++ ++ if (*wcs == wc) ++ retval = wcs; ++ if (*wcs == L'\0') ++ return (wchar_t *) retval; ++ wcs+=2; ++ ++ if (*wcs2 == wc) ++ retval = wcs2; ++ if (*wcs2 == L'\0') ++ return (wchar_t *) retval; ++ wcs2+=2; ++ ++ if (*wcs == wc) ++ retval = wcs; ++ if (*wcs == L'\0') ++ return (wchar_t *) retval; ++ wcs+=2; ++ ++ if (*wcs2 == wc) ++ retval = wcs2; ++ if (*wcs2 == L'\0') ++ return (wchar_t *) retval; ++ wcs2+=2; ++ ++ if (*wcs == wc) ++ retval = wcs; ++ if (*wcs == L'\0') ++ return (wchar_t *) retval; ++ wcs+=2; ++ ++ if (*wcs2 == wc) ++ retval = wcs2; ++ if (*wcs2 == L'\0') ++ return (wchar_t *) retval; ++ wcs2+=2; ++ ++ if (*wcs == wc) ++ retval = wcs; ++ } ++ while (*wcs != L'\0'); ++ ++ return (wchar_t *) retval; ++} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c +new file mode 100644 +index 0000000..bd77eb3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power6.c +@@ -0,0 +1,20 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WCSRCHR __wcsrchr_power6 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c +new file mode 100644 +index 0000000..829a434 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-power7.c +@@ -0,0 +1,20 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WCSRCHR __wcsrchr_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c +new file mode 100644 +index 0000000..9c7fe2d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcsrchr-ppc32.c +@@ -0,0 +1,26 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifndef NOT_IN_libc ++# define WCSRCHR __wcsrchr_ppc ++#endif ++ ++extern __typeof (wcsrchr) __wcsrchr_ppc; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index ff3b8cf..b4504b7 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -10,10 +10,13 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncase-power7 strncase_l-power7 strncmp-power7 \ + strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \ + strchrnul-power7 strchrnul-ppc64 wcschr-power7 \ +- wcschr-power6 wcschr-ppc64 ++ wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \ ++ wcsrchr-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-wcschr-power7.c += -mcpu=power7 + CFLAGS-wcschr-power6.c += -mcpu=power6 ++CFLAGS-wcsrchr-power7.c += -mcpu=power7 ++CFLAGS-wcsrchr-power6.c += -mcpu=power6 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index cc932c9..6c7422c 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -202,5 +202,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, wcschr, 1, + __wcschr_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/wcschr.c. */ ++ IFUNC_IMPL (i, name, wcsrchr, ++ IFUNC_IMPL_ADD (array, i, wcsrchr, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __wcsrchr_power7) ++ IFUNC_IMPL_ADD (array, i, wcsrchr, ++ hwcap & PPC_FEATURE_ARCH_2_05, ++ __wcsrchr_power6) ++ IFUNC_IMPL_ADD (array, i, wcsrchr, 1, ++ __wcsrchr_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c +new file mode 100644 +index 0000000..da6f27b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power6.c +@@ -0,0 +1,19 @@ ++/* wcsrchr.c - Wide Character Search for powerpc64/power6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c +new file mode 100644 +index 0000000..60f07a8 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-power7.c +@@ -0,0 +1,19 @@ ++/* wcsrchr.c - Wide Character Search for powerpc64/power7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c +new file mode 100644 +index 0000000..1fff510 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr-ppc64.c +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c +new file mode 100644 +index 0000000..3d0ab42 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcsrchr.c +@@ -0,0 +1,36 @@ ++/* Multiple versions of wcsrchr. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (wcsrchr) __wcsrchr_ppc attribute_hidden; ++extern __typeof (wcsrchr) __wcsrchr_power6 attribute_hidden; ++extern __typeof (wcsrchr) __wcsrchr_power7 attribute_hidden; ++ ++libc_ifunc (wcsrchr, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __wcsrchr_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __wcsrchr_power6 ++ : __wcsrchr_ppc); ++#else ++#include ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcsrchr.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcsrchr.c +index 2327c05..b86472d 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcsrchr.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcsrchr.c +@@ -1 +1 @@ +-#include "../../powerpc32/power6/wcsrchr.c" ++#include +diff --git glibc-2.17-c758a686/wcsmbs/wcsrchr.c glibc-2.17-c758a686/wcsmbs/wcsrchr.c +index c1b5a59..27c94c5 100644 +--- glibc-2.17-c758a686/wcsmbs/wcsrchr.c ++++ glibc-2.17-c758a686/wcsmbs/wcsrchr.c +@@ -18,10 +18,13 @@ + + #include + ++#ifndef WCSRCHR ++# define WCSRCHR wcsrchr ++#endif + + /* Find the last occurrence of WC in WCS. */ + wchar_t * +-wcsrchr (wcs, wc) ++WCSRCHR (wcs, wc) + register const wchar_t *wcs; + register const wchar_t wc; + { +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-17.patch b/SOURCES/glibc-rh731837-17.patch new file mode 100644 index 00000000..10282694 --- /dev/null +++ b/SOURCES/glibc-rh731837-17.patch @@ -0,0 +1,423 @@ +From 21ee17d9e36c21d0c143287cc678a373893e94cc Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 07:45:17 -0500 +Subject: [PATCH] PowerPC: multiarch wcscpy for PowerPC64 + +commit 92cacfce7d40cb331009fdcd79d83b075a1a8785 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:53:25 2013 -0500 + +Added the following files apart from original commit. . +sysdeps/powerpc/power6/wcscpy.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c +sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c +sysdeps/powerpc/powerpc64/power6/wcscpy.c +wcsmbs/wcscpy.c +--- + sysdeps/powerpc/power6/wcscpy.c | 105 +++++++++++++++++++++ + .../powerpc32/power4/multiarch/wcscpy-power6.c | 22 +++++ + .../powerpc32/power4/multiarch/wcscpy-power7.c | 22 +++++ + .../powerpc32/power4/multiarch/wcscpy-ppc32.c | 26 +++++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 4 +- + .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 11 +++ + .../powerpc/powerpc64/multiarch/wcscpy-power6.c | 19 ++++ + .../powerpc/powerpc64/multiarch/wcscpy-power7.c | 19 ++++ + sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c | 18 ++++ + sysdeps/powerpc/powerpc64/multiarch/wcscpy.c | 36 +++++++ + sysdeps/powerpc/powerpc64/power6/wcscpy.c | 2 +- + wcsmbs/wcscpy.c | 5 +- + 12 files changed, 286 insertions(+), 3 deletions(-) + create mode 100644 sysdeps/powerpc/power6/wcscpy.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wcscpy.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power6/wcscpy.c glibc-2.17-c758a686/sysdeps/powerpc/power6/wcscpy.c +new file mode 100644 +index 0000000..417ec72 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power6/wcscpy.c +@@ -0,0 +1,105 @@ ++/* wcscpy.c - Wide Character Copy for POWER6+. ++ Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++ ++#ifndef WCSCPY ++# define WCSCPY wcscpy ++#endif ++ ++/* Copy SRC to DEST. */ ++wchar_t * ++WCSCPY (wchar_t *dest, const wchar_t *src) ++{ ++ wint_t c,d; ++ wchar_t *wcp, *wcp2; ++ ++ if (__alignof__ (wchar_t) >= sizeof (wchar_t)) ++ { ++ const ptrdiff_t off = dest - src; ++ ++ wcp = (wchar_t *) src; ++ wcp2 = wcp + 1 ; ++ ++ do ++ { ++ d = *wcp; ++ wcp[off] = d; ++ if (d == L'\0') ++ return dest; ++ wcp += 2; ++ ++ c = *wcp2; ++ wcp2[off] = c; ++ if (c == L'\0') ++ return dest; ++ wcp2 += 2; ++ ++ d = *wcp; ++ wcp[off] = d; ++ if (d == L'\0') ++ return dest; ++ wcp += 2; ++ ++ c = *wcp2; ++ wcp2[off] = c; ++ if (c == L'\0') ++ return dest; ++ wcp2 += 2; ++ ++ d = *wcp; ++ wcp[off] = d; ++ if (d == L'\0') ++ return dest; ++ wcp += 2; ++ ++ c = *wcp2; ++ wcp2[off] = c; ++ if (c == L'\0') ++ return dest; ++ wcp2 += 2; ++ ++ d = *wcp; ++ wcp[off] = d; ++ if (d == L'\0') ++ return dest; ++ wcp += 2; ++ ++ c = *wcp2; ++ wcp2[off] = c; ++ if (c == L'\0') ++ return dest; ++ wcp2 += 2; ++ } ++ while (c != L'\0'); ++ ++ } ++ else ++ { ++ wcp = dest; ++ ++ do ++ { ++ c = *src++; ++ *wcp++ = c; ++ } ++ while (c != L'\0'); ++ } ++ return dest; ++} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c +new file mode 100644 +index 0000000..6c86baa +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power6.c +@@ -0,0 +1,22 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define WCSCPY __wcscpy_power6 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c +new file mode 100644 +index 0000000..dad0e70 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-power7.c +@@ -0,0 +1,22 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#define WCSCPY __wcscpy_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c +new file mode 100644 +index 0000000..c135835 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c +@@ -0,0 +1,26 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#ifndef NOT_IN_libc ++# define WCSCPY __wcscpy_ppc ++#endif ++ ++extern __typeof (wcscpy) __wcscpy_ppc; ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index b4504b7..7113212 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -11,7 +11,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \ + strchrnul-power7 strchrnul-ppc64 wcschr-power7 \ + wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \ +- wcsrchr-ppc64 ++ wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops +@@ -19,4 +19,6 @@ CFLAGS-wcschr-power7.c += -mcpu=power7 + CFLAGS-wcschr-power6.c += -mcpu=power6 + CFLAGS-wcsrchr-power7.c += -mcpu=power7 + CFLAGS-wcsrchr-power6.c += -mcpu=power6 ++CFLAGS-wcscpy-power7.c += -mcpu=power7 ++CFLAGS-wcscpy-power6.c += -mcpu=power6 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +index 6c7422c..2d21ce1 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +@@ -213,5 +213,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, + IFUNC_IMPL_ADD (array, i, wcsrchr, 1, + __wcsrchr_ppc)) + ++ /* Support sysdeps/powerpc/powerpc64/multiarch/wcscpy.c. */ ++ IFUNC_IMPL (i, name, wcscpy, ++ IFUNC_IMPL_ADD (array, i, wcscpy, ++ hwcap & PPC_FEATURE_HAS_VSX, ++ __wcscpy_power7) ++ IFUNC_IMPL_ADD (array, i, wcscpy, ++ hwcap & PPC_FEATURE_ARCH_2_05, ++ __wcscpy_power6) ++ IFUNC_IMPL_ADD (array, i, wcscpy, 1, ++ __wcscpy_ppc)) ++ + return i; + } +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c +new file mode 100644 +index 0000000..9f4bc41 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power6.c +@@ -0,0 +1,19 @@ ++/* wcscpy.c - Wide Character Search for powerpc64/power6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c +new file mode 100644 +index 0000000..0f37ad4 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-power7.c +@@ -0,0 +1,19 @@ ++/* wcscpy.c - Wide Character Search for powerpc64/power7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c +new file mode 100644 +index 0000000..4559569 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy-ppc64.c +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c +new file mode 100644 +index 0000000..5c0a6d3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wcscpy.c +@@ -0,0 +1,36 @@ ++/* Multiple versions of wcscpy. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (wcscpy) __wcscpy_ppc attribute_hidden; ++extern __typeof (wcscpy) __wcscpy_power6 attribute_hidden; ++extern __typeof (wcscpy) __wcscpy_power7 attribute_hidden; ++ ++libc_ifunc (wcscpy, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? __wcscpy_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __wcscpy_power6 ++ : __wcscpy_ppc); ++#else ++#include ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcscpy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcscpy.c +index 57b706a..722c8f9 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcscpy.c ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wcscpy.c +@@ -1 +1 @@ +-#include "../../powerpc32/power6/wcscpy.c" ++#include +diff --git glibc-2.17-c758a686/wcsmbs/wcscpy.c glibc-2.17-c758a686/wcsmbs/wcscpy.c +index 6dea24d..cec1249 100644 +--- glibc-2.17-c758a686/wcsmbs/wcscpy.c ++++ glibc-2.17-c758a686/wcsmbs/wcscpy.c +@@ -19,10 +19,13 @@ + #include + #include + ++#ifndef WCSCPY ++# define WCSCPY wcscpy ++#endif + + /* Copy SRC to DEST. */ + wchar_t * +-wcscpy (dest, src) ++WCSCPY (dest, src) + wchar_t *dest; + const wchar_t *src; + { +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-18.patch b/SOURCES/glibc-rh731837-18.patch new file mode 100644 index 00000000..8ce9d6c4 --- /dev/null +++ b/SOURCES/glibc-rh731837-18.patch @@ -0,0 +1,1075 @@ +From 8d960764b1afa3b64c3c388665499935a38b194e Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 08:12:17 -0500 +Subject: [PATCH] PowerPC: multiarch wordcopy for PowerPC64 + +commit e28bcd427b21b6c74021ca65736dd66474b09013 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:54:08 2013 -0500 + +Added the following files apart from original commit. +sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c +sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c +sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c +sysdeps/powerpc/power4/wordcopy.c +sysdeps/powerpc/power6/wordcopy.c +Removed the following files apart from original commit. +sysdeps/powerpc/power4/wordcopy.c +sysdeps/powerpc/powerpc64/power6/wordcopy.c +--- + string/wordcopy.c | 38 ++-- + sysdeps/powerpc/power4/wordcopy.c | 212 ++++++++++++++++++++ + sysdeps/powerpc/power6/wordcopy.c | 221 +++++++++++++++++++++ + .../powerpc32/power4/multiarch/wordcopy-power6.c | 23 +++ + .../powerpc32/power4/multiarch/wordcopy-power7.c | 23 +++ + .../powerpc32/power4/multiarch/wordcopy-ppc32.c | 23 +++ + sysdeps/powerpc/powerpc64/multiarch/Makefile | 5 +- + .../powerpc/powerpc64/multiarch/wordcopy-power6.c | 19 ++ + .../powerpc/powerpc64/multiarch/wordcopy-power7.c | 19 ++ + .../powerpc/powerpc64/multiarch/wordcopy-ppc64.c | 18 ++ + sysdeps/powerpc/powerpc64/multiarch/wordcopy.c | 86 ++++++++ + sysdeps/powerpc/powerpc64/power4/wordcopy.c | 1 - + sysdeps/powerpc/powerpc64/power6/wordcopy.c | 217 -------------------- + 13 files changed, 669 insertions(+), 236 deletions(-) + create mode 100644 sysdeps/powerpc/power4/wordcopy.c + create mode 100644 sysdeps/powerpc/power6/wordcopy.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/multiarch/wordcopy.c + delete mode 100644 sysdeps/powerpc/powerpc64/power4/wordcopy.c + delete mode 100644 sysdeps/powerpc/powerpc64/power6/wordcopy.c + +diff --git glibc-2.17-c758a686/string/wordcopy.c glibc-2.17-c758a686/string/wordcopy.c +index b171f27..ff4cce4 100644 +--- glibc-2.17-c758a686/string/wordcopy.c ++++ glibc-2.17-c758a686/string/wordcopy.c +@@ -1,5 +1,5 @@ + /* _memcopy.c -- subroutines for memory copy functions. +- Copyright (C) 1991, 1996 Free Software Foundation, Inc. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + +@@ -26,11 +26,12 @@ + block beginning at DSTP with LEN `op_t' words (not LEN bytes!). + Both SRCP and DSTP should be aligned for memory operations on `op_t's. */ + ++#ifndef WORDCOPY_FWD_ALIGNED ++# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned ++#endif ++ + void +-_wordcopy_fwd_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; ++WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len) + { + op_t a0, a1; + +@@ -134,11 +135,12 @@ _wordcopy_fwd_aligned (dstp, srcp, len) + DSTP should be aligned for memory operations on `op_t's, but SRCP must + *not* be aligned. */ + ++#ifndef WORDCOPY_FWD_DEST_ALIGNED ++# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned ++#endif ++ + void +-_wordcopy_fwd_dest_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; ++WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len) + { + op_t a0, a1, a2, a3; + int sh_1, sh_2; +@@ -221,11 +223,12 @@ _wordcopy_fwd_dest_aligned (dstp, srcp, len) + (not LEN bytes!). Both SRCP and DSTP should be aligned for memory + operations on `op_t's. */ + ++#ifndef WORDCOPY_BWD_ALIGNED ++# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned ++#endif ++ + void +-_wordcopy_bwd_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; ++WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len) + { + op_t a0, a1; + +@@ -329,11 +332,12 @@ _wordcopy_bwd_aligned (dstp, srcp, len) + words (not LEN bytes!). DSTP should be aligned for memory + operations on `op_t', but SRCP must *not* be aligned. */ + ++#ifndef WORDCOPY_BWD_DEST_ALIGNED ++# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned ++#endif ++ + void +-_wordcopy_bwd_dest_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; ++WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len) + { + op_t a0, a1, a2, a3; + int sh_1, sh_2; +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power4/wordcopy.c glibc-2.17-c758a686/sysdeps/powerpc/power4/wordcopy.c +new file mode 100644 +index 0000000..263b444 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power4/wordcopy.c +@@ -0,0 +1,212 @@ ++/* _memcopy.c -- subroutines for memory copy functions. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Torbjorn Granlund (tege@sics.se). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */ ++ ++#include ++#include ++ ++/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to ++ block beginning at DSTP with LEN `op_t' words (not LEN bytes!). ++ Both SRCP and DSTP should be aligned for memory operations on `op_t's. */ ++ ++#ifndef WORDCOPY_FWD_ALIGNED ++# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned ++#endif ++ ++void ++WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1; ++ ++ if (len & 1) ++ { ++ ((op_t *) dstp)[0] = ((op_t *) srcp)[0]; ++ ++ if (len == 1) ++ return; ++ srcp += OPSIZ; ++ dstp += OPSIZ; ++ len -= 1; ++ } ++ ++ do ++ { ++ a0 = ((op_t *) srcp)[0]; ++ a1 = ((op_t *) srcp)[1]; ++ ((op_t *) dstp)[0] = a0; ++ ((op_t *) dstp)[1] = a1; ++ ++ srcp += 2 * OPSIZ; ++ dstp += 2 * OPSIZ; ++ len -= 2; ++ } ++ while (len != 0); ++} ++ ++/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to ++ block beginning at DSTP with LEN `op_t' words (not LEN bytes!). ++ DSTP should be aligned for memory operations on `op_t's, but SRCP must ++ *not* be aligned. */ ++ ++#ifndef WORDCOPY_FWD_DEST_ALIGNED ++# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned ++#endif ++ ++void ++WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1, a2; ++ int sh_1, sh_2; ++ ++ /* Calculate how to shift a word read at the memory operation ++ aligned srcp to make it aligned for copy. */ ++ ++ sh_1 = 8 * (srcp % OPSIZ); ++ sh_2 = 8 * OPSIZ - sh_1; ++ ++ /* Make SRCP aligned by rounding it down to the beginning of the `op_t' ++ it points in the middle of. */ ++ srcp &= -OPSIZ; ++ a0 = ((op_t *) srcp)[0]; ++ ++ if (len & 1) ++ { ++ a1 = ((op_t *) srcp)[1]; ++ ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2); ++ ++ if (len == 1) ++ return; ++ ++ a0 = a1; ++ srcp += OPSIZ; ++ dstp += OPSIZ; ++ len -= 1; ++ } ++ ++ do ++ { ++ a1 = ((op_t *) srcp)[1]; ++ a2 = ((op_t *) srcp)[2]; ++ ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2); ++ ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2); ++ a0 = a2; ++ ++ srcp += 2 * OPSIZ; ++ dstp += 2 * OPSIZ; ++ len -= 2; ++ } ++ while (len != 0); ++} ++ ++/* _wordcopy_bwd_aligned -- Copy block finishing right before ++ SRCP to block finishing right before DSTP with LEN `op_t' words ++ (not LEN bytes!). Both SRCP and DSTP should be aligned for memory ++ operations on `op_t's. */ ++ ++#ifndef WORDCOPY_BWD_ALIGNED ++# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned ++#endif ++ ++void ++WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1; ++ ++ if (len & 1) ++ { ++ srcp -= OPSIZ; ++ dstp -= OPSIZ; ++ ((op_t *) dstp)[0] = ((op_t *) srcp)[0]; ++ ++ if (len == 1) ++ return; ++ len -= 1; ++ } ++ ++ do ++ { ++ srcp -= 2 * OPSIZ; ++ dstp -= 2 * OPSIZ; ++ ++ a1 = ((op_t *) srcp)[1]; ++ a0 = ((op_t *) srcp)[0]; ++ ((op_t *) dstp)[1] = a1; ++ ((op_t *) dstp)[0] = a0; ++ ++ len -= 2; ++ } ++ while (len != 0); ++} ++ ++/* _wordcopy_bwd_dest_aligned -- Copy block finishing right ++ before SRCP to block finishing right before DSTP with LEN `op_t' ++ words (not LEN bytes!). DSTP should be aligned for memory ++ operations on `op_t', but SRCP must *not* be aligned. */ ++ ++#ifndef WORDCOPY_BWD_DEST_ALIGNED ++# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned ++#endif ++ ++void ++WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1, a2; ++ int sh_1, sh_2; ++ ++ /* Calculate how to shift a word read at the memory operation ++ aligned srcp to make it aligned for copy. */ ++ ++ sh_1 = 8 * (srcp % OPSIZ); ++ sh_2 = 8 * OPSIZ - sh_1; ++ ++ /* Make srcp aligned by rounding it down to the beginning of the op_t ++ it points in the middle of. */ ++ srcp &= -OPSIZ; ++ a2 = ((op_t *) srcp)[0]; ++ ++ if (len & 1) ++ { ++ srcp -= OPSIZ; ++ dstp -= OPSIZ; ++ a1 = ((op_t *) srcp)[0]; ++ ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2); ++ ++ if (len == 1) ++ return; ++ ++ a2 = a1; ++ len -= 1; ++ } ++ ++ do ++ { ++ srcp -= 2 * OPSIZ; ++ dstp -= 2 * OPSIZ; ++ ++ a1 = ((op_t *) srcp)[1]; ++ a0 = ((op_t *) srcp)[0]; ++ ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2); ++ ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2); ++ a2 = a0; ++ ++ len -= 2; ++ } ++ while (len != 0); ++} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power6/wordcopy.c glibc-2.17-c758a686/sysdeps/powerpc/power6/wordcopy.c +new file mode 100644 +index 0000000..c32e6dd +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power6/wordcopy.c +@@ -0,0 +1,221 @@ ++/* _memcopy.c -- subroutines for memory copy functions. ++ Copyright (C) 1991-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Torbjorn Granlund (tege@sics.se). ++ Updated for POWER6 by Steven Munroe (sjmunroe@us.ibm.com). ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */ ++ ++#include ++#include ++ ++/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to ++ block beginning at DSTP with LEN `op_t' words (not LEN bytes!). ++ Both SRCP and DSTP should be aligned for memory operations on `op_t's. */ ++ ++#ifndef WORDCOPY_FWD_ALIGNED ++# define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned ++#endif ++ ++void ++WORDCOPY_FWD_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1; ++ ++ if (len & 1) ++ { ++ ((op_t *) dstp)[0] = ((op_t *) srcp)[0]; ++ ++ if (len == 1) ++ return; ++ srcp += OPSIZ; ++ dstp += OPSIZ; ++ len -= 1; ++ } ++ ++ do ++ { ++ a0 = ((op_t *) srcp)[0]; ++ a1 = ((op_t *) srcp)[1]; ++ ((op_t *) dstp)[0] = a0; ++ ((op_t *) dstp)[1] = a1; ++ ++ srcp += 2 * OPSIZ; ++ dstp += 2 * OPSIZ; ++ len -= 2; ++ } ++ while (len != 0); ++} ++ ++/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to ++ block beginning at DSTP with LEN `op_t' words (not LEN bytes!). ++ DSTP should be aligned for memory operations on `op_t's, but SRCP must ++ *not* be aligned. */ ++ ++#define fwd_align_merge(align) \ ++ do \ ++ { \ ++ a1 = ((op_t *) srcp)[1]; \ ++ a2 = ((op_t *) srcp)[2]; \ ++ ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (__WORDSIZE-align*8)); \ ++ ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (__WORDSIZE-align*8)); \ ++ a0 = a2; \ ++ srcp += 2 * OPSIZ; \ ++ dstp += 2 * OPSIZ; \ ++ len -= 2; \ ++ } \ ++ while (len != 0) ++ ++#ifndef WORDCOPY_FWD_DEST_ALIGNED ++# define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned ++#endif ++ ++void ++WORDCOPY_FWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1, a2; ++ int sh_1, sh_2; ++ int align; ++ ++ /* Calculate how to shift a word read at the memory operation ++ aligned srcp to make it aligned for copy. */ ++ ++ align = srcp % OPSIZ; ++ sh_1 = 8 * (srcp % OPSIZ); ++ sh_2 = 8 * OPSIZ - sh_1; ++ ++ /* Make SRCP aligned by rounding it down to the beginning of the `op_t' ++ it points in the middle of. */ ++ srcp &= -OPSIZ; ++ a0 = ((op_t *) srcp)[0]; ++ ++ if (len & 1) ++ { ++ a1 = ((op_t *) srcp)[1]; ++ ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2); ++ ++ if (len == 1) ++ return; ++ ++ a0 = a1; ++ srcp += OPSIZ; ++ dstp += OPSIZ; ++ len -= 1; ++ } ++ ++ fwd_align_merge (align); ++ ++} ++ ++/* _wordcopy_bwd_aligned -- Copy block finishing right before ++ SRCP to block finishing right before DSTP with LEN `op_t' words ++ (not LEN bytes!). Both SRCP and DSTP should be aligned for memory ++ operations on `op_t's. */ ++ ++#ifndef WORDCOPY_BWD_ALIGNED ++# define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned ++#endif ++ ++void ++WORDCOPY_BWD_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1; ++ ++ if (len & 1) ++ { ++ srcp -= OPSIZ; ++ dstp -= OPSIZ; ++ ((op_t *) dstp)[0] = ((op_t *) srcp)[0]; ++ ++ if (len == 1) ++ return; ++ len -= 1; ++ } ++ ++ do ++ { ++ srcp -= 2 * OPSIZ; ++ dstp -= 2 * OPSIZ; ++ ++ a1 = ((op_t *) srcp)[1]; ++ a0 = ((op_t *) srcp)[0]; ++ ((op_t *) dstp)[1] = a1; ++ ((op_t *) dstp)[0] = a0; ++ ++ len -= 2; ++ } ++ while (len != 0); ++} ++ ++#define bwd_align_merge(align) \ ++ do \ ++ { \ ++ srcp -= 2 * OPSIZ; \ ++ dstp -= 2 * OPSIZ; \ ++ a1 = ((op_t *) srcp)[1]; \ ++ a0 = ((op_t *) srcp)[0]; \ ++ ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (__WORDSIZE-align*8)); \ ++ ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (__WORDSIZE-align*8)); \ ++ a2 = a0; \ ++ len -= 2; \ ++ } \ ++ while (len != 0) ++ ++/* _wordcopy_bwd_dest_aligned -- Copy block finishing right ++ before SRCP to block finishing right before DSTP with LEN `op_t' ++ words (not LEN bytes!). DSTP should be aligned for memory ++ operations on `op_t', but SRCP must *not* be aligned. */ ++ ++#ifndef WORDCOPY_BWD_DEST_ALIGNED ++# define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned ++#endif ++ ++void ++WORDCOPY_BWD_DEST_ALIGNED (long int dstp, long int srcp, size_t len) ++{ ++ op_t a0, a1, a2; ++ int sh_1, sh_2; ++ int align; ++ ++ /* Calculate how to shift a word read at the memory operation ++ aligned srcp to make it aligned for copy. */ ++ ++ align = srcp % OPSIZ; ++ sh_1 = 8 * (srcp % OPSIZ); ++ sh_2 = 8 * OPSIZ - sh_1; ++ ++ /* Make srcp aligned by rounding it down to the beginning of the op_t ++ it points in the middle of. */ ++ srcp &= -OPSIZ; ++ a2 = ((op_t *) srcp)[0]; ++ ++ if (len & 1) ++ { ++ srcp -= OPSIZ; ++ dstp -= OPSIZ; ++ a1 = ((op_t *) srcp)[0]; ++ ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2); ++ ++ if (len == 1) ++ return; ++ ++ a2 = a1; ++ len -= 1; ++ } ++ ++ bwd_align_merge (align); ++} +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c +new file mode 100644 +index 0000000..c5c6eb7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power6.c +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned_power6 ++#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power6 ++#define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned_power6 ++#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power6 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c +new file mode 100644 +index 0000000..841d1a2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-power7.c +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned_power7 ++#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_power7 ++#define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned_power7 ++#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c +new file mode 100644 +index 0000000..ccd24ad +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/multiarch/wordcopy-ppc32.c +@@ -0,0 +1,23 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define WORDCOPY_FWD_ALIGNED _wordcopy_fwd_aligned_ppc ++#define WORDCOPY_FWD_DEST_ALIGNED _wordcopy_fwd_dest_aligned_ppc ++#define WORDCOPY_BWD_ALIGNED _wordcopy_bwd_aligned_ppc ++#define WORDCOPY_BWD_DEST_ALIGNED _wordcopy_bwd_dest_aligned_ppc ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +index 7113212..8dceb09 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/Makefile +@@ -11,7 +11,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \ + strncmp-power4 strncmp-ppc64 strchr-power7 strchr-ppc64 \ + strchrnul-power7 strchrnul-ppc64 wcschr-power7 \ + wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \ +- wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 ++ wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 \ ++ wordcopy-power7 wordcopy-power6 wordcopy-ppc64 + + CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops + CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops +@@ -21,4 +22,6 @@ CFLAGS-wcsrchr-power7.c += -mcpu=power7 + CFLAGS-wcsrchr-power6.c += -mcpu=power6 + CFLAGS-wcscpy-power7.c += -mcpu=power7 + CFLAGS-wcscpy-power6.c += -mcpu=power6 ++CFLAGS-wordcopy-power7.c += -mcpu=power7 ++CFLAGS-wordcopy-power6.c += -mcpu=power6 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c +new file mode 100644 +index 0000000..2a65b52 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power6.c +@@ -0,0 +1,19 @@ ++/* wordcopy routines for powerpc64/power6. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c +new file mode 100644 +index 0000000..e804f88 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-power7.c +@@ -0,0 +1,19 @@ ++/* wordcopy routines for powerpc64/power7. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c +new file mode 100644 +index 0000000..0584277 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy-ppc64.c +@@ -0,0 +1,18 @@ ++/* Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c +new file mode 100644 +index 0000000..889be25 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/wordcopy.c +@@ -0,0 +1,86 @@ ++/* Multiple versions of wordcopy functions. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef NOT_IN_libc ++# include ++# include ++# include ++# include "init-arch.h" ++ ++extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_ppc ++attribute_hidden; ++extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power6 ++attribute_hidden; ++extern __typeof (_wordcopy_fwd_aligned) _wordcopy_fwd_aligned_power7 ++attribute_hidden; ++ ++libc_ifunc (_wordcopy_fwd_aligned, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? _wordcopy_fwd_aligned_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? _wordcopy_fwd_aligned_power6 ++ : _wordcopy_fwd_aligned_ppc); ++ ++ ++extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_ppc ++attribute_hidden; ++extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power6 ++attribute_hidden; ++extern __typeof (_wordcopy_fwd_dest_aligned) _wordcopy_fwd_dest_aligned_power7 ++attribute_hidden; ++ ++libc_ifunc (_wordcopy_fwd_dest_aligned, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? _wordcopy_fwd_dest_aligned_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? _wordcopy_fwd_dest_aligned_power6 ++ : _wordcopy_fwd_dest_aligned_ppc); ++ ++ ++extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_ppc ++attribute_hidden; ++extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power6 ++attribute_hidden; ++extern __typeof (_wordcopy_bwd_aligned) _wordcopy_bwd_aligned_power7 ++attribute_hidden; ++ ++libc_ifunc (_wordcopy_bwd_aligned, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? _wordcopy_bwd_aligned_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? _wordcopy_bwd_aligned_power6 ++ : _wordcopy_bwd_aligned_ppc); ++ ++ ++extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_ppc ++attribute_hidden; ++extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power6 ++attribute_hidden; ++extern __typeof (_wordcopy_bwd_dest_aligned) _wordcopy_bwd_dest_aligned_power7 ++attribute_hidden; ++ ++libc_ifunc (_wordcopy_bwd_dest_aligned, ++ (hwcap & PPC_FEATURE_HAS_VSX) ++ ? _wordcopy_bwd_dest_aligned_power7 : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? _wordcopy_bwd_dest_aligned_power6 ++ : _wordcopy_bwd_dest_aligned_ppc); ++ ++#else ++#include ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/wordcopy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/wordcopy.c +deleted file mode 100644 +index f427b48..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/wordcopy.c ++++ /dev/null +@@ -1 +0,0 @@ +-#include "../../powerpc32/power4/wordcopy.c" +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wordcopy.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wordcopy.c +deleted file mode 100644 +index 4c72404..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/wordcopy.c ++++ /dev/null +@@ -1,217 +0,0 @@ +-/* _memcopy.c -- subroutines for memory copy functions. +- Copyright (C) 1991-2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- Contributed by Torbjorn Granlund (tege@sics.se). +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */ +- +-#include +-#include +- +-/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to +- block beginning at DSTP with LEN `op_t' words (not LEN bytes!). +- Both SRCP and DSTP should be aligned for memory operations on `op_t's. */ +- +-void +-_wordcopy_fwd_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; +-{ +- op_t a0, a1; +- +- if (len & 1) +- { +- ((op_t *) dstp)[0] = ((op_t *) srcp)[0]; +- +- if (len == 1) +- return; +- srcp += OPSIZ; +- dstp += OPSIZ; +- len -= 1; +- } +- +- do +- { +- a0 = ((op_t *) srcp)[0]; +- a1 = ((op_t *) srcp)[1]; +- ((op_t *) dstp)[0] = a0; +- ((op_t *) dstp)[1] = a1; +- +- srcp += 2 * OPSIZ; +- dstp += 2 * OPSIZ; +- len -= 2; +- } +- while (len != 0); +-} +- +-#define fwd_align_merge(align) \ +- do \ +- { \ +- a1 = ((op_t *) srcp)[1]; \ +- a2 = ((op_t *) srcp)[2]; \ +- ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (64-align*8)); \ +- ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (64-align*8)); \ +- a0 = a2; \ +- srcp += 2 * OPSIZ; \ +- dstp += 2 * OPSIZ; \ +- len -= 2; \ +- } \ +- while (len != 0) +- +- +-/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to +- block beginning at DSTP with LEN `op_t' words (not LEN bytes!). +- DSTP should be aligned for memory operations on `op_t's, but SRCP must +- *not* be aligned. */ +- +-void +-_wordcopy_fwd_dest_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; +-{ +- op_t a0, a1, a2; +- int sh_1, sh_2; +- int align; +- +- /* Calculate how to shift a word read at the memory operation +- aligned srcp to make it aligned for copy. */ +- +- align = srcp % OPSIZ; +- sh_1 = 8 * (srcp % OPSIZ); +- sh_2 = 8 * OPSIZ - sh_1; +- +- /* Make SRCP aligned by rounding it down to the beginning of the `op_t' +- it points in the middle of. */ +- srcp &= -OPSIZ; +- a0 = ((op_t *) srcp)[0]; +- +- if (len & 1) +- { +- a1 = ((op_t *) srcp)[1]; +- ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2); +- +- if (len == 1) +- return; +- +- a0 = a1; +- srcp += OPSIZ; +- dstp += OPSIZ; +- len -= 1; +- } +- +- fwd_align_merge (align); +- +-} +- +-/* _wordcopy_bwd_aligned -- Copy block finishing right before +- SRCP to block finishing right before DSTP with LEN `op_t' words +- (not LEN bytes!). Both SRCP and DSTP should be aligned for memory +- operations on `op_t's. */ +- +-void +-_wordcopy_bwd_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; +-{ +- op_t a0, a1; +- +- if (len & 1) +- { +- srcp -= OPSIZ; +- dstp -= OPSIZ; +- ((op_t *) dstp)[0] = ((op_t *) srcp)[0]; +- +- if (len == 1) +- return; +- len -= 1; +- } +- +- do +- { +- srcp -= 2 * OPSIZ; +- dstp -= 2 * OPSIZ; +- +- a1 = ((op_t *) srcp)[1]; +- a0 = ((op_t *) srcp)[0]; +- ((op_t *) dstp)[1] = a1; +- ((op_t *) dstp)[0] = a0; +- +- len -= 2; +- } +- while (len != 0); +-} +- +-#define bwd_align_merge(align) \ +- do \ +- { \ +- srcp -= 2 * OPSIZ; \ +- dstp -= 2 * OPSIZ; \ +- a1 = ((op_t *) srcp)[1]; \ +- a0 = ((op_t *) srcp)[0]; \ +- ((op_t *) dstp)[1] = MERGE (a1, align*8, a2, (64-align*8)); \ +- ((op_t *) dstp)[0] = MERGE (a0, align*8, a1, (64-align*8)); \ +- a2 = a0; \ +- len -= 2; \ +- } \ +- while (len != 0) +- +-/* _wordcopy_bwd_dest_aligned -- Copy block finishing right +- before SRCP to block finishing right before DSTP with LEN `op_t' +- words (not LEN bytes!). DSTP should be aligned for memory +- operations on `op_t', but SRCP must *not* be aligned. */ +- +-void +-_wordcopy_bwd_dest_aligned (dstp, srcp, len) +- long int dstp; +- long int srcp; +- size_t len; +-{ +- op_t a0, a1, a2; +- int sh_1, sh_2; +- int align; +- +- /* Calculate how to shift a word read at the memory operation +- aligned srcp to make it aligned for copy. */ +- +- align = srcp % OPSIZ; +- sh_1 = 8 * (srcp % OPSIZ); +- sh_2 = 8 * OPSIZ - sh_1; +- +- /* Make srcp aligned by rounding it down to the beginning of the op_t +- it points in the middle of. */ +- srcp &= -OPSIZ; +- a2 = ((op_t *) srcp)[0]; +- +- if (len & 1) +- { +- srcp -= OPSIZ; +- dstp -= OPSIZ; +- a1 = ((op_t *) srcp)[0]; +- ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2); +- +- if (len == 1) +- return; +- +- a2 = a1; +- len -= 1; +- } +- +- bwd_align_merge (align); +-} +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-19.patch b/SOURCES/glibc-rh731837-19.patch new file mode 100644 index 00000000..7cf21c68 --- /dev/null +++ b/SOURCES/glibc-rh731837-19.patch @@ -0,0 +1,27 @@ +From a060ed545478f28bded88544e9361c49cf442427 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 08:19:53 -0500 +Subject: [PATCH] More fixes for unsafe compiler optimization + +commit 1775babf2be39c3e09eb8b855379d0aca867abeb +Author: Adhemerval Zanella +Date: Tue Apr 29 14:15:45 2014 -0500 + +GCC 4.9 -ftree-loop-distribute-patterns now may transform loops in +memcpy. Add the alias to internal GLIBC symbol to avoid PLT creation. +--- + sysdeps/generic/symbol-hacks.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h +index 9eaf014..6bec24b 100644 +--- glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h ++++ glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h +@@ -3,4 +3,5 @@ + #if !defined __ASSEMBLER__ && !defined NOT_IN_libc && defined SHARED + asm ("memmove = __GI_memmove"); + asm ("memset = __GI_memset"); ++asm ("memcpy = __GI_memcpy"); + #endif +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-20.patch b/SOURCES/glibc-rh731837-20.patch new file mode 100644 index 00000000..350b34f3 --- /dev/null +++ b/SOURCES/glibc-rh731837-20.patch @@ -0,0 +1,74 @@ +From 18284d83fcce6440cd6610beff72e2ae475f835d Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 10:34:08 -0500 +Subject: [PATCH] PowerPC: fpu multiarch support for PowerPC64 + +commit 69bbc63d883c2bc9938fc7b8a3b28794de0e26cc +Author: Adhemerval Zanella +Date: Fri Dec 13 14:58:02 2013 -0500 + + PowerPC: Adjust multiarch Implies for PowerPC64 + + This patch adds Implies files on multiarch folder for POWER chips so + multirach is enabled when building with --with-cpu and powerN + option. +--- + sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies | 1 + + sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies | 1 + + sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies | 2 -- + 6 files changed, 5 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies + create mode 100644 sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies + delete mode 100644 sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies +new file mode 100644 +index 0000000..c0e6784 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5+/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power5/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies +new file mode 100644 +index 0000000..3740d05 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power5/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power4/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies +new file mode 100644 +index 0000000..fca8a4e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power5+/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies +new file mode 100644 +index 0000000..410d289 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power6/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies +new file mode 100644 +index 0000000..410d289 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power7/fpu/multiarch/Implies +@@ -0,0 +1 @@ ++powerpc/powerpc64/power6/fpu/multiarch +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies +deleted file mode 100644 +index 6243d2e..0000000 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/powerpc64/fpu/Implies ++++ /dev/null +@@ -1,2 +0,0 @@ +-# Override ldbl-opt with powerpc64 specific routines. +-powerpc/powerpc64/fpu +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-21.patch b/SOURCES/glibc-rh731837-21.patch new file mode 100644 index 00000000..87458083 --- /dev/null +++ b/SOURCES/glibc-rh731837-21.patch @@ -0,0 +1,202 @@ +From ae7cc530d644d05ef11fe9a846dd5e4b51966734 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 10:35:21 -0500 +Subject: [PATCH] PowerPC: Cleaning up uneeded sqrt routines + +commit c24517c9dd9e92b4fa81e192967c63e56c1726e2 +Author: Adhemerval Zanella +Date: Fri Dec 13 14:56:09 2013 -0500 + + PowerPC: Cleaning up uneeded sqrt routines + + For PPC64, all the wrappers at sysdeps are superfluous: they are + basically the same implementation from math/w_sqrt.c with the + '#ifdef _IEEE_LIBM'. And the power4 version just force the 'fsqrt' + instruction utilization with an inline assembly, which is already + handled by math_private.h __ieee754_sqrt implementation. + +File sysdeps/powerpc/fpu/w_sqrt.c (part oforiginal commit) +is already deleted by some previous patch. Hence ignoring that. +--- + sysdeps/powerpc/fpu/w_sqrtf.c | 46 --------------------- + sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c | 55 -------------------------- + sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c | 53 ------------------------- + 3 files changed, 154 deletions(-) + delete mode 100644 sysdeps/powerpc/fpu/w_sqrtf.c + delete mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c + delete mode 100644 sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrtf.c glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrtf.c +deleted file mode 100644 +index 39b5b20..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/fpu/w_sqrtf.c ++++ /dev/null +@@ -1,46 +0,0 @@ +-/* Single-precision floating point square root wrapper. +- Copyright (C) 2004, 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +- +-#include +-#include +- +-float +-__sqrtf (float x) /* wrapper sqrtf */ +-{ +-#ifdef _IEEE_LIBM +- return __ieee754_sqrtf (x); +-#else +- float z; +- z = __ieee754_sqrtf (x); +- +- if (_LIB_VERSION == _IEEE_ || (x != x)) +- return z; +- +- if (x < (float) 0.0) +- /* sqrtf(negative) */ +- return (float) __kernel_standard ((double) x, (double) x, 126); +- else +- return z; +-#endif +-} +- +-weak_alias (__sqrtf, sqrtf) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c +deleted file mode 100644 +index 1bd6a67..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrt.c ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* Double-precision floating point square root wrapper. +- Copyright (C) 2004, 2007, 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +-#include +- +-double +-__sqrt (double x) /* wrapper sqrt */ +-{ +- double z; +-/* Power4 (ISA V2.0) and above implement sqrt in hardware. */ +- __asm __volatile ( +- " fsqrt %0,%1\n" +- : "=f" (z) +- : "f" (x)); +-#ifdef _IEEE_LIBM +- return z; +-#else +- if (__builtin_expect (_LIB_VERSION == _IEEE_, 0)) +- return z; +- +- if (__builtin_expect (x != x, 0)) +- return z; +- +- if (__builtin_expect (x < 0.0, 0)) +- return __kernel_standard (x, x, 26); /* sqrt(negative) */ +- else +- return z; +-#endif +-} +- +-weak_alias (__sqrt, sqrt) +-#ifdef NO_LONG_DOUBLE +- strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl) +-#endif +-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +-compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0); +-#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c +deleted file mode 100644 +index 0e7e692..0000000 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/power4/fpu/w_sqrtf.c ++++ /dev/null +@@ -1,53 +0,0 @@ +-/* Single-precision floating point square root wrapper. +- Copyright (C) 2004, 2007, 2012 Free Software Foundation, Inc. +- This file is part of the GNU C Library. +- +- The GNU C Library is free software; you can redistribute it and/or +- modify it under the terms of the GNU Lesser General Public +- License as published by the Free Software Foundation; either +- version 2.1 of the License, or (at your option) any later version. +- +- The GNU C Library is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public +- License along with the GNU C Library; if not, see +- . */ +- +-#include +-#include +-#include +- +-#include +-#include +- +-float +-__sqrtf (float x) /* wrapper sqrtf */ +-{ +-#ifdef _IEEE_LIBM +- return __ieee754_sqrtf (x); +-#else +- float z; +-/* Power4 (ISA V2.0) and above implement sqrtf in hardware. */ +- __asm __volatile ( +- " fsqrts %0,%1\n" +- : "=f" (z) +- : "f" (x)); +- +- if (__builtin_expect (_LIB_VERSION == _IEEE_, 0)) +- return z; +- +- if (__builtin_expect (x != x, 0)) +- return z; +- +- if (__builtin_expect (x < 0.0, 0)) +- /* sqrtf(negative) */ +- return (float) __kernel_standard ((double) x, (double) x, 126); +- else +- return z; +-#endif +-} +- +-weak_alias (__sqrtf, sqrtf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-22.patch b/SOURCES/glibc-rh731837-22.patch new file mode 100644 index 00000000..6b18bc42 --- /dev/null +++ b/SOURCES/glibc-rh731837-22.patch @@ -0,0 +1,44 @@ +From 1aa79fbb9921281a8aedfe3eea1f273406b5f24c Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:23:08 -0500 +Subject: [PATCH] Fix cproj handling of (finite, NaN) arguments (bug 15531). + +commit c980f2f4fe0f5d301f706017a1f7e4e942193ec0 +Author: Joseph Myers +Date: Tue Aug 20 19:41:15 2013 +0000 + + Fix cproj handling of (finite, NaN) arguments (bug 15531). + + * math/s_cprojf.c (__cprojf): Only return an infinity if one part of + argument is infinite. + +This patch is added so as to compile isnan multiarch implementation +successfully since __GI___isnanf is missing.This wll be fixed later in master. +--- + math/s_cprojf.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git glibc-2.17-c758a686/math/s_cprojf.c glibc-2.17-c758a686/math/s_cprojf.c +index 6cbc93b..a0f0af9 100644 +--- glibc-2.17-c758a686/math/s_cprojf.c ++++ glibc-2.17-c758a686/math/s_cprojf.c +@@ -1,5 +1,5 @@ + /* Compute projection of complex float value to Riemann sphere. +- Copyright (C) 1997, 1999, 2010 Free Software Foundation, Inc. ++ Copyright (C) 1997-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + +@@ -24,9 +24,7 @@ + __complex__ float + __cprojf (__complex__ float x) + { +- if (isnan (__real__ x) && isnan (__imag__ x)) +- return x; +- else if (!isfinite (__real__ x) || !isfinite (__imag__ x)) ++ if (__isinf_nsf (__real__ x) || __isinf_nsf (__imag__ x)) + { + __complex__ float res; + +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-23.patch b/SOURCES/glibc-rh731837-23.patch new file mode 100644 index 00000000..bb21bacd --- /dev/null +++ b/SOURCES/glibc-rh731837-23.patch @@ -0,0 +1,361 @@ +From 54c7fb4227e044758021e638082f69d2a48d2658 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 10:40:10 -0500 +Subject: [PATCH] PowerPC: multiarch isnan/isnanf for PowerPC64 + +commit b2284ad7cf6d9c2fea4223d933fcc152c0fee7c1 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:01:10 2013 -0500 + +Added sysdeps/powerpc/powerpc32/fpu/s_isnan.S apart from +the original commit. +--- + sysdeps/powerpc/powerpc32/fpu/s_isnan.S | 2 + + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 7 +++ + .../powerpc64/fpu/multiarch/s_isnan-power5.S | 33 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_isnan-power6.S | 33 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_isnan-power6x.S | 33 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_isnan-power7.S | 33 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_isnan-ppc64.S | 32 +++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c | 53 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c | 40 ++++++++++++++++ + 9 files changed, 266 insertions(+) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_isnan.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_isnan.S +index f1ea473..0157805 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_isnan.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/fpu/s_isnan.S +@@ -37,9 +37,11 @@ weak_alias (__isnan, isnan) + + /* It turns out that the 'double' version will also always work for + single-precision. */ ++#ifndef __isnan + strong_alias (__isnan, __isnanf) + hidden_def (__isnanf) + weak_alias (__isnanf, isnanf) ++#endif + + #ifdef NO_LONG_DOUBLE + strong_alias (__isnan, __isnanl) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +new file mode 100644 +index 0000000..b57ddc9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -0,0 +1,7 @@ ++ifeq ($(subdir),math) ++sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ ++ s_isnan-power5 s_isnan-ppc64 ++ ++libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ ++ s_isnan-power5 s_isnan-ppc64 ++endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S +new file mode 100644 +index 0000000..145e24b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power5.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER5 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __isnan __isnan_power5 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S +new file mode 100644 +index 0000000..4576eb3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER6 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __isnan __isnan_power6 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S +new file mode 100644 +index 0000000..c2a45e3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power6x.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER6X version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __isnan __isnan_power6x ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S +new file mode 100644 +index 0000000..05b9fbc +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power7.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __isnan __isnan_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S +new file mode 100644 +index 0000000..cf01d64 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-ppc64.S +@@ -0,0 +1,32 @@ ++/* isnan(). PowerPC32 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++ ++#define __isnan __isnan_ppc64 ++#undef hidden_def ++#define hidden_def(name) \ ++ .globl __GI___isnan ; .set __GI___isnan,__isnan_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c +new file mode 100644 +index 0000000..0de833e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c +@@ -0,0 +1,53 @@ ++/* Multiple versions of isnan. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__isnan) __isnan_ppc64 attribute_hidden; ++extern __typeof (__isnan) __isnan_power5 attribute_hidden; ++extern __typeof (__isnan) __isnan_power6 attribute_hidden; ++extern __typeof (__isnan) __isnan_power6x attribute_hidden; ++extern __typeof (__isnan) __isnan_power7 attribute_hidden; ++ ++libc_ifunc (__isnan, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isnan_power7 : ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __isnan_power6x : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __isnan_power6 : ++ (hwcap & PPC_FEATURE_POWER5) ++ ? __isnan_power5 ++ : __isnan_ppc64); ++ ++weak_alias (__isnan, isnan) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__isnan, __isnanl) ++weak_alias (__isnan, isnanl) ++#endif ++ ++#ifndef IS_IN_libm ++# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) ++compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0); ++compat_symbol (libc, isnan, isnanl, GLIBC_2_0); ++# endif ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c +new file mode 100644 +index 0000000..b237455 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of isnan. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include "init-arch.h" ++ ++/* The double-precision implementation also works for the single one. */ ++extern __typeof (__isnanf) __isnan_ppc64 attribute_hidden; ++extern __typeof (__isnanf) __isnan_power5 attribute_hidden; ++extern __typeof (__isnanf) __isnan_power6 attribute_hidden; ++extern __typeof (__isnanf) __isnan_power6x attribute_hidden; ++extern __typeof (__isnanf) __isnan_power7 attribute_hidden; ++ ++libc_ifunc (__isnanf, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isnan_power7 : ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __isnan_power6x : ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __isnan_power6 : ++ (hwcap & PPC_FEATURE_POWER5) ++ ? __isnan_power5 ++ : __isnan_ppc64); ++ ++weak_alias (__isnanf, isnanf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-24.patch b/SOURCES/glibc-rh731837-24.patch new file mode 100644 index 00000000..d08d1dbd --- /dev/null +++ b/SOURCES/glibc-rh731837-24.patch @@ -0,0 +1,219 @@ +From 925c1856c2c73401df1bed739f2f3e89b62bee89 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 10:45:21 -0500 +Subject: [PATCH] PowerPC: multiarch llround/lround for PowerPC64 + +commit c3627f6e965834c7998184a55653ca016b1ff663 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:01:54 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/s_llround-power5+.S | 32 ++++++++++++ + .../powerpc64/fpu/multiarch/s_llround-power6x.S | 32 ++++++++++++ + .../powerpc64/fpu/multiarch/s_llround-ppc64.S | 28 ++++++++++ + .../powerpc/powerpc64/fpu/multiarch/s_llround.c | 60 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c | 1 + + 6 files changed, 155 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index b57ddc9..a4636b0 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -3,5 +3,6 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ +- s_isnan-power5 s_isnan-ppc64 ++ s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ ++ s_llround-power5+ s_llround-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S +new file mode 100644 +index 0000000..ba0b65c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power5+.S +@@ -0,0 +1,32 @@ ++/* llround(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __llround __llround_power5plus ++#define __lround __lround_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S +new file mode 100644 +index 0000000..bd1c22a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power6x.S +@@ -0,0 +1,32 @@ ++/* llround(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, alias, ver) ++ ++#define __llround __llround_power6x ++#define __lround __lround_power6x ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S +new file mode 100644 +index 0000000..2316da2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-ppc64.S +@@ -0,0 +1,28 @@ ++/* llround(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __llround __llround_ppc64 ++#define __lround __lround_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c +new file mode 100644 +index 0000000..a4d1bf3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c +@@ -0,0 +1,60 @@ ++/* Multiple versions of llround. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define lround __hidden_lround ++#define __lround __hidden___lround ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__llround) __llround_ppc64 attribute_hidden; ++extern __typeof (__llround) __llround_power5plus attribute_hidden; ++extern __typeof (__llround) __llround_power6x attribute_hidden; ++ ++libc_ifunc (__llround, ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __llround_power6x : ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __llround_power5plus ++ : __llround_ppc64); ++ ++weak_alias (__llround, llround) ++ ++#ifdef NO_LONG_DOUBLE ++weak_alias (__llround, llroundl) ++strong_alias (__llround, __llroundl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) ++compat_symbol (libm, __llround, llroundl, GLIBC_2_1); ++compat_symbol (libm, llround, lroundl, GLIBC_2_1); ++#endif ++ ++/* long has the same width as long long on PPC64. */ ++#undef lround ++#undef __lround ++strong_alias (__llround, __lround) ++weak_alias (__llround, lround) ++#ifdef NO_LONG_DOUBLE ++strong_alias (__llround, __llroundl) ++weak_alias (__llround, llroundl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) ++compat_symbol (libm, __lround, lroundl, GLIBC_2_1); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c +new file mode 100644 +index 0000000..0dab544 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lround.c +@@ -0,0 +1 @@ ++/* __lround is in s_llround.c */ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-25.patch b/SOURCES/glibc-rh731837-25.patch new file mode 100644 index 00000000..6e98573c --- /dev/null +++ b/SOURCES/glibc-rh731837-25.patch @@ -0,0 +1,260 @@ +From 071e47e7ff9e64db97d887d8fc12a3aa9433685b Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 10:48:41 -0500 +Subject: [PATCH] PowerPC: multiarch ceil/ceilf for PowerPC64 + +commit 96770f12b081984f872c84c2b8067e8ed574c25a +Author: Adhemerval Zanella +Date: Fri Dec 13 15:02:32 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/s_ceil-power5+.S | 31 +++++++++++++++++ + .../powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S | 31 +++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c | 40 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_ceilf-power5+.S | 26 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_ceilf-ppc64.S | 26 ++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c | 32 +++++++++++++++++ + 7 files changed, 188 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index a4636b0..9eb69af 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -4,5 +4,6 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +- s_llround-power5+ s_llround-ppc64 ++ s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \ ++ s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S +new file mode 100644 +index 0000000..cc1316f +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-power5+.S +@@ -0,0 +1,31 @@ ++/* ceil function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __ceil __ceil_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S +new file mode 100644 +index 0000000..52e5a56 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil-ppc64.S +@@ -0,0 +1,31 @@ ++/* ceil function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __ceil __ceil_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c +new file mode 100644 +index 0000000..f53df5b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceil.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of ceil. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__ceil) __ceil_ppc64 attribute_hidden; ++extern __typeof (__ceil) __ceil_power5plus attribute_hidden; ++ ++libc_ifunc (__ceil, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __ceil_power5plus ++ : __ceil_ppc64); ++ ++weak_alias (__ceil, ceil) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__ceil, __ceill) ++weak_alias (__ceil, ceill) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __ceil, ceill, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S +new file mode 100644 +index 0000000..21261e2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-power5+.S +@@ -0,0 +1,26 @@ ++/* ceilf function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __ceilf __ceilf_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S +new file mode 100644 +index 0000000..8cd869b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf-ppc64.S +@@ -0,0 +1,26 @@ ++/* ceilf function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __ceilf __ceilf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c +new file mode 100644 +index 0000000..d951990 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_ceilf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of ceilf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__ceilf) __ceilf_ppc64 attribute_hidden; ++extern __typeof (__ceilf) __ceilf_power5plus attribute_hidden; ++ ++libc_ifunc (__ceilf, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __ceilf_power5plus ++ : __ceilf_ppc64); ++ ++weak_alias (__ceilf, ceilf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-26.patch b/SOURCES/glibc-rh731837-26.patch new file mode 100644 index 00000000..f9855578 --- /dev/null +++ b/SOURCES/glibc-rh731837-26.patch @@ -0,0 +1,262 @@ +From 02a611b03a24e6b67e3f683d05ea374443c7523d Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 10:49:57 -0500 +Subject: [PATCH] PowerPC: multiarch floor/floorf for PowerPC64 + +commit 357fd3b40a59df16191df23439411c1342cc1ba5 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:04:04 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 4 ++- + .../powerpc64/fpu/multiarch/s_floor-power5+.S | 31 +++++++++++++++++ + .../powerpc64/fpu/multiarch/s_floor-ppc64.S | 31 +++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c | 40 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_floorf-power5+.S | 26 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_floorf-ppc64.S | 27 +++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c | 32 +++++++++++++++++ + 7 files changed, 190 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 9eb69af..d3d230d 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -5,5 +5,7 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ + s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \ +- s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 ++ s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \ ++ s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \ ++ s_floorf-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S +new file mode 100644 +index 0000000..a1550e9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-power5+.S +@@ -0,0 +1,31 @@ ++/* floor function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __floor __floor_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S +new file mode 100644 +index 0000000..b5c232c +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor-ppc64.S +@@ -0,0 +1,31 @@ ++/* floor function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __floor __floor_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c +new file mode 100644 +index 0000000..f43976a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floor.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of floor. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__floor) __floor_ppc64 attribute_hidden; ++extern __typeof (__floor) __floor_power5plus attribute_hidden; ++ ++libc_ifunc (__floor, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __floor_power5plus ++ : __floor_ppc64); ++ ++weak_alias (__floor, floor) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__floor, __floorl) ++weak_alias (__floor, floorl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __floor, floorl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S +new file mode 100644 +index 0000000..d371708 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-power5+.S +@@ -0,0 +1,26 @@ ++/* floorf function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __floorf __floorf_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S +new file mode 100644 +index 0000000..dc81dea +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf-ppc64.S +@@ -0,0 +1,27 @@ ++/* floorf function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __floorf __floorf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c +new file mode 100644 +index 0000000..08fc95e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_floorf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of floorf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__floorf) __floorf_ppc64 attribute_hidden; ++extern __typeof (__floorf) __floorf_power5plus attribute_hidden; ++ ++libc_ifunc (__floorf, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __floorf_power5plus ++ : __floorf_ppc64); ++ ++weak_alias (__floorf, floorf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-27.patch b/SOURCES/glibc-rh731837-27.patch new file mode 100644 index 00000000..0babc3c5 --- /dev/null +++ b/SOURCES/glibc-rh731837-27.patch @@ -0,0 +1,260 @@ +From defecce61df9fb5579cefdc26201d2be12b8c72a Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:20:40 -0500 +Subject: [PATCH] PowerPC: multiarch round/roundf for PowerPC64 + +commit 59a3e194f75c4845b15caa1ae16b0264f9c7cf0c +Author: Adhemerval Zanella +Date: Fri Dec 13 15:06:01 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/s_round-power5+.S | 31 +++++++++++++++++ + .../powerpc64/fpu/multiarch/s_round-ppc64.S | 31 +++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c | 40 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_roundf-power5+.S | 26 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_roundf-ppc64.S | 26 ++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c | 32 +++++++++++++++++ + 7 files changed, 188 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index d3d230d..303cd0f 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -7,5 +7,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_llround-power5+ s_llround-ppc64 s_ceil-power5+ \ + s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \ + s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \ +- s_floorf-ppc64 ++ s_floorf-ppc64 s_round-power5+ s_round-ppc64 \ ++ s_roundf-power5+ s_roundf-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S +new file mode 100644 +index 0000000..c2afb4f +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-power5+.S +@@ -0,0 +1,31 @@ ++/* round function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __round __round_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S +new file mode 100644 +index 0000000..76c96b6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round-ppc64.S +@@ -0,0 +1,31 @@ ++/* round function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __round __round_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c +new file mode 100644 +index 0000000..5818411 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_round.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of round. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__round) __round_ppc64 attribute_hidden; ++extern __typeof (__round) __round_power5plus attribute_hidden; ++ ++libc_ifunc (__round, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __round_power5plus ++ : __round_ppc64); ++ ++weak_alias (__round, round) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__round, __roundl) ++weak_alias (__round, roundl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __round, roundl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S +new file mode 100644 +index 0000000..8fbef39 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-power5+.S +@@ -0,0 +1,26 @@ ++/* roundf function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __roundf __roundf_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S +new file mode 100644 +index 0000000..bc51fdd +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf-ppc64.S +@@ -0,0 +1,26 @@ ++/* roundf function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __roundf __roundf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c +new file mode 100644 +index 0000000..34c5bc7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_roundf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of roundf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__roundf) __roundf_ppc64 attribute_hidden; ++extern __typeof (__roundf) __roundf_power5plus attribute_hidden; ++ ++libc_ifunc (__roundf, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __roundf_power5plus ++ : __roundf_ppc64); ++ ++weak_alias (__roundf, roundf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-28.patch b/SOURCES/glibc-rh731837-28.patch new file mode 100644 index 00000000..7d494f85 --- /dev/null +++ b/SOURCES/glibc-rh731837-28.patch @@ -0,0 +1,260 @@ +From 01c7534c4410d709181c835351d26409f4fae2b2 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:21:38 -0500 +Subject: [PATCH] PowerPC: multiarch trunc/truncf for PowerPC64 + +commit 1cb341fd782817ad98a0470aa84b2ab197d7de00 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:30:57 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/s_trunc-power5+.S | 31 +++++++++++++++++ + .../powerpc64/fpu/multiarch/s_trunc-ppc64.S | 31 +++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c | 40 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_truncf-power5+.S | 26 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_truncf-ppc64.S | 26 ++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c | 32 +++++++++++++++++ + 7 files changed, 188 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 303cd0f..4cdb383 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -8,5 +8,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_ceil-ppc64 s_ceilf-power5+ s_ceilf-ppc64 \ + s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \ + s_floorf-ppc64 s_round-power5+ s_round-ppc64 \ +- s_roundf-power5+ s_roundf-ppc64 ++ s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \ ++ s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S +new file mode 100644 +index 0000000..ed22bcb +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-power5+.S +@@ -0,0 +1,31 @@ ++/* trunc function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __trunc __trunc_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S +new file mode 100644 +index 0000000..75b531a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc-ppc64.S +@@ -0,0 +1,31 @@ ++/* trunc function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __trunc __trunc_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c +new file mode 100644 +index 0000000..4dc22a6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_trunc.c +@@ -0,0 +1,40 @@ ++/* Multiple versions of trunc. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__trunc) __trunc_ppc64 attribute_hidden; ++extern __typeof (__trunc) __trunc_power5plus attribute_hidden; ++ ++libc_ifunc (__trunc, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __trunc_power5plus ++ : __trunc_ppc64); ++ ++weak_alias (__trunc, trunc) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__trunc, __truncl) ++weak_alias (__trunc, truncl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __trunc, truncl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S +new file mode 100644 +index 0000000..44d858e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-power5+.S +@@ -0,0 +1,26 @@ ++/* truncf function. PowerPC64/power5+ version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __truncf __truncf_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S +new file mode 100644 +index 0000000..236797d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf-ppc64.S +@@ -0,0 +1,26 @@ ++/* truncf function. PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __truncf __truncf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c +new file mode 100644 +index 0000000..0eef89f +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_truncf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of truncf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__truncf) __truncf_ppc64 attribute_hidden; ++extern __typeof (__truncf) __truncf_power5plus attribute_hidden; ++ ++libc_ifunc (__truncf, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __truncf_power5plus ++ : __truncf_ppc64); ++ ++weak_alias (__truncf, truncf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-29.patch b/SOURCES/glibc-rh731837-29.patch new file mode 100644 index 00000000..9af3f03f --- /dev/null +++ b/SOURCES/glibc-rh731837-29.patch @@ -0,0 +1,218 @@ +From 7560c8b2254c082f754f1e8fd390d4b50146dcdd Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:30:28 -0500 +Subject: [PATCH] PowerPC: multiarch copysign/copysignf for PowerPC64 + +commit 2568f3fa69bbf70d0bea457cb7cbbf3bee45bfe5 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:32:58 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 6 ++- + .../powerpc64/fpu/multiarch/s_copysign-power6.S | 33 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_copysign-ppc64.S | 35 +++++++++++++++ + .../powerpc/powerpc64/fpu/multiarch/s_copysign.c | 51 ++++++++++++++++++++++ + .../powerpc/powerpc64/fpu/multiarch/s_copysignf.c | 32 ++++++++++++++ + 5 files changed, 155 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 4cdb383..3af4ac3 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -1,6 +1,7 @@ + ifeq ($(subdir),math) + sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ +- s_isnan-power5 s_isnan-ppc64 ++ s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \ ++ s_copysign-ppc64 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +@@ -9,5 +10,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_floor-power5+ s_floor-ppc64 s_floorf-power5+ \ + s_floorf-ppc64 s_round-power5+ s_round-ppc64 \ + s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \ +- s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 ++ s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \ ++ s_copysign-power6 s_copysign-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S +new file mode 100644 +index 0000000..4fa34a6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-power6.S +@@ -0,0 +1,33 @@ ++/* copysign(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a, b, c, d) ++#undef hidden_def ++#define hidden_def(name) ++ ++#define __copysign __copysign_power6 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S +new file mode 100644 +index 0000000..a5cdfc2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign-ppc64.S +@@ -0,0 +1,35 @@ ++/* copysign(). PowerPC64 default version. ++ Copyright (C) 2010-2014 Free Software Foundation, Inc. ++ Contributed by Luis Machado . ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a, b, c, d) ++ ++#define __copysign __copysign_ppc64 ++#undef hidden_def ++#define hidden_def(name) \ ++ strong_alias (__copysign_ppc64, __GI___copysign) ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c +new file mode 100644 +index 0000000..f3e6b3a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysign.c +@@ -0,0 +1,51 @@ ++/* Multiple versions of copysign. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Redefine copysign so that the compiler won't complain about the type ++ mismatch with the IFUNC selector in strong_alias below. */ ++#undef __copysign ++#define __copysign __redirect_copysign ++#include ++#include ++#undef __copysign ++#include ++#include "init-arch.h" ++ ++extern __typeof (__redirect_copysign) __copysign_ppc64 attribute_hidden; ++extern __typeof (__redirect_copysign) __copysign_power6 attribute_hidden; ++ ++extern __typeof (__redirect_copysign) __libm_copysign; ++libc_ifunc (__libm_copysign, ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __copysign_power6 ++ : __copysign_ppc64); ++ ++strong_alias (__libm_copysign, __copysign) ++weak_alias (__copysign, copysign) ++ ++#ifdef NO_LONG_DOUBLE ++weak_alias (__copysign,copysignl) ++strong_alias(__copysign,__copysignl) ++#endif ++#ifdef IS_IN_libm ++# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __copysign, copysignl, GLIBC_2_0); ++# endif ++#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) ++compat_symbol (libc, __copysign, copysignl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c +new file mode 100644 +index 0000000..55cc272 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_copysignf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of copysignf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include "init-arch.h" ++ ++/* It's safe to use double-precision implementation for single-precision. */ ++extern __typeof (__copysignf) __copysign_ppc64 attribute_hidden; ++extern __typeof (__copysignf) __copysign_power6 attribute_hidden; ++ ++libc_ifunc (__copysignf, ++ (hwcap & PPC_FEATURE_ARCH_2_05) ++ ? __copysign_power6 ++ : __copysign_ppc64); ++ ++weak_alias (__copysignf, copysignf) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-30.patch b/SOURCES/glibc-rh731837-30.patch new file mode 100644 index 00000000..bb8d9194 --- /dev/null +++ b/SOURCES/glibc-rh731837-30.patch @@ -0,0 +1,178 @@ +From b303432f970be8b430f7155fd40adcffb65390ef Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:31:40 -0500 +Subject: [PATCH] PowerPC: multiarch llrint/lrint for PowerPC64 + +commit 5ccd5fc893ca027703d2d9747092ee25729223d9 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:33:54 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 3 +- + .../powerpc64/fpu/multiarch/s_llrint-power6x.S | 31 ++++++++++++ + .../powerpc64/fpu/multiarch/s_llrint-ppc64.S | 31 ++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c | 57 ++++++++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c | 1 + + 5 files changed, 122 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 3af4ac3..10d0ac9 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -11,5 +11,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_floorf-ppc64 s_round-power5+ s_round-ppc64 \ + s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \ + s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \ +- s_copysign-power6 s_copysign-ppc64 ++ s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \ ++ s_llrint-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S +new file mode 100644 +index 0000000..8cd39c6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power6x.S +@@ -0,0 +1,31 @@ ++/* Round double to long int. PowerPC64/POWER6X default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __llrint __llrint_power6x ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S +new file mode 100644 +index 0000000..754d28f +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-ppc64.S +@@ -0,0 +1,31 @@ ++/* Round double to long int. PowerPC32 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __llrint __llrint_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c +new file mode 100644 +index 0000000..5818b53 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c +@@ -0,0 +1,57 @@ ++/* Multiple versions of llrint. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Redefine lrint/__lrint so that the compiler won't complain about the type ++ mismatch with the IFUNC selector in strong_alias below. */ ++#define lrint __hidden_lrint ++#define __lrint __hidden___lrint ++ ++#include ++#include ++#undef lrint ++#undef __lrint ++#include ++#include "init-arch.h" ++ ++extern __typeof (__llrint) __llrint_ppc64 attribute_hidden; ++extern __typeof (__llrint) __llrint_power6x attribute_hidden; ++ ++libc_ifunc (__llrint, ++ (hwcap & PPC_FEATURE_POWER6_EXT) ++ ? __llrint_power6x ++ : __llrint_ppc64); ++ ++weak_alias (__llrint, llrint) ++#ifdef NO_LONG_DOUBLE ++strong_alias (__llrint, __llrintl) ++weak_alias (__llrint, llrintl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) ++compat_symbol (libm, __llrint, llrintl, GLIBC_2_1); ++#endif ++ ++/* long has the same width as long long on PowerPC64. */ ++strong_alias (__llrint, __lrint) ++weak_alias (__lrint, lrint) ++#ifdef NO_LONG_DOUBLE ++strong_alias (__lrint, __lrintl) ++weak_alias (__lrint, lrintl) ++#endif ++#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1) ++compat_symbol (libm, __lrint, lrintl, GLIBC_2_1); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c +new file mode 100644 +index 0000000..d092862 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_lrint.c +@@ -0,0 +1 @@ ++ /* __lrint is in s_llrint.c */ +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-31.patch b/SOURCES/glibc-rh731837-31.patch new file mode 100644 index 00000000..072475db --- /dev/null +++ b/SOURCES/glibc-rh731837-31.patch @@ -0,0 +1,307 @@ +From e7197c1f8c4c30734723059c97b6e7a8f58fb171 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:33:51 -0500 +Subject: [PATCH] PowerPC: multiarch finite/finitef for PowerPC64 + +commit 1481d7066c4ce697ada1f33c8c7f97b46ef685e3 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:34:52 2013 -0500 + +Modified the following files apart from the original commit. +sysdeps/ieee754/dbl-64/s_finite.c +sysdeps/ieee754/flt-32/s_finitef.c +--- + sysdeps/ieee754/dbl-64/s_finite.c | 13 ++++-- + sysdeps/ieee754/flt-32/s_finitef.c | 7 ++- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 6 ++- + .../powerpc64/fpu/multiarch/s_finite-power7.S | 33 ++++++++++++++ + .../powerpc64/fpu/multiarch/s_finite-ppc64.c | 34 +++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 51 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_finitef-ppc64.c | 32 ++++++++++++++ + .../powerpc/powerpc64/fpu/multiarch/s_finitef.c | 32 ++++++++++++++ + 8 files changed, 201 insertions(+), 7 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c + +diff --git glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/s_finite.c glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/s_finite.c +index 47dad5d..49986bb 100644 +--- glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/s_finite.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/s_finite.c +@@ -23,11 +23,16 @@ static char rcsid[] = "$NetBSD: s_finite.c,v 1.8 1995/05/10 20:47:17 jtc Exp $"; + #include + + #undef __finite +-int __finite(double x) ++ ++#ifndef FINITE ++# define FINITE __finite ++#endif ++ ++int FINITE(double x) + { +- int32_t hx; +- GET_HIGH_WORD(hx,x); +- return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31); ++ int32_t hx; ++ GET_HIGH_WORD (hx, x); ++ return (int) ((u_int32_t) ((hx & 0x7fffffff) - 0x7ff00000) >> 31); + } + hidden_def (__finite) + weak_alias (__finite, finite) +diff --git glibc-2.17-c758a686/sysdeps/ieee754/flt-32/s_finitef.c glibc-2.17-c758a686/sysdeps/ieee754/flt-32/s_finitef.c +index dfdf4ad..4ea270a 100644 +--- glibc-2.17-c758a686/sysdeps/ieee754/flt-32/s_finitef.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/flt-32/s_finitef.c +@@ -26,7 +26,12 @@ static char rcsid[] = "$NetBSD: s_finitef.c,v 1.4 1995/05/10 20:47:18 jtc Exp $" + #include + + #undef __finitef +-int __finitef(float x) ++ ++#ifndef FINITEF ++# define FINITEF __finitef ++#endif ++ ++int FINITEF(float x) + { + int32_t ix; + GET_FLOAT_WORD(ix,x); +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 10d0ac9..1c23ddc 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -1,7 +1,8 @@ + ifeq ($(subdir),math) + sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \ +- s_copysign-ppc64 ++ s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \ ++ s_finitef-ppc64 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +@@ -12,5 +13,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_roundf-power5+ s_roundf-ppc64 s_trunc-power5+ \ + s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \ + s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \ +- s_llrint-ppc64 ++ s_llrint-ppc64 s_finite-power7 s_finite-ppc64 \ ++ s_finitef-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S +new file mode 100644 +index 0000000..ac2244b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power7.S +@@ -0,0 +1,33 @@ ++/* isnan(). PowerPC64/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, symbol, ver) ++ ++#define __finite __finite_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c +new file mode 100644 +index 0000000..1922e2b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-ppc64.c +@@ -0,0 +1,34 @@ ++/* finite(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ Contributed by Luis Machado . ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define FINITE __finite_ppc64 ++#ifdef SHARED ++# undef hidden_def ++# define hidden_def(a) \ ++ __hidden_ver1 (__finite_ppc64, __GI___finite, __finite_ppc64); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c +new file mode 100644 +index 0000000..f79a93e +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c +@@ -0,0 +1,51 @@ ++/* Multiple versions of finite. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__finite) __finite_ppc64 attribute_hidden; ++extern __typeof (__finite) __finite_power7 attribute_hidden; ++ ++libc_ifunc (__finite, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __finite_power7 ++ : __finite_ppc64); ++ ++weak_alias (__finite, finite) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__finite, __finitel) ++weak_alias (__finite, finitel) ++#endif ++ ++#ifdef IS_IN_libm ++# if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) ++compat_symbol (libm, finite, finitel, GLIBC_2_0); ++# endif ++# if LONG_DOUBLE_COMPAT (libm, GLIBC_2_1) ++compat_symbol (libm, __finite, __finitel, GLIBC_2_1); ++# endif ++#else ++# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0) ++compat_symbol (libc, __finite, __finitel, GLIBC_2_0); ++compat_symbol (libc, finite, finitel, GLIBC_2_0); ++# endif ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c +new file mode 100644 +index 0000000..63dd003 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef-ppc64.c +@@ -0,0 +1,32 @@ ++/* finitef(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ Contributed by Luis Machado . ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#define FINITEF __finitef_ppc64 ++#ifdef SHARED ++# undef hidden_def ++# define hidden_def(a) \ ++ __hidden_ver1 (__finitef_ppc64, __GI___finitef, __finitef_ppc64); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c +new file mode 100644 +index 0000000..a7243b5 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of finitef. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__finitef) __finitef_ppc64 attribute_hidden; ++/* The double-precision version also works for single-precision. */ ++extern __typeof (__finitef) __finite_power7 attribute_hidden; ++ ++libc_ifunc (__finitef, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __finite_power7 ++ : __finitef_ppc64); ++ ++weak_alias (__finitef, finitef) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-32.patch b/SOURCES/glibc-rh731837-32.patch new file mode 100644 index 00000000..28f7e509 --- /dev/null +++ b/SOURCES/glibc-rh731837-32.patch @@ -0,0 +1,250 @@ +From 9c2d0f05544d22786bff9324fbd24e6bed8839c4 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 11:36:27 -0500 +Subject: [PATCH] PowerPC: multiarch isinf/isinff for PowerPC64 + +commit 8fdad1237900e10b3b263b18bf6ca4c092e2c609 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:35:44 2013 -0500 +--- + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 6 ++- + .../powerpc64/fpu/multiarch/s_isinf-power7.S | 33 ++++++++++++++++ + .../powerpc64/fpu/multiarch/s_isinf-ppc64.c | 33 ++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c | 44 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_isinff-ppc64.c | 31 +++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 33 ++++++++++++++++ + 6 files changed, 178 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 1c23ddc..64dd85f 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -2,7 +2,8 @@ ifeq ($(subdir),math) + sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \ + s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \ +- s_finitef-ppc64 ++ s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ ++ s_isinf-ppc64 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +@@ -14,5 +15,6 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_trunc-ppc64 s_truncf-power5+ s_truncf-ppc64 \ + s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \ + s_llrint-ppc64 s_finite-power7 s_finite-ppc64 \ +- s_finitef-ppc64 ++ s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ ++ s_isinf-ppc64 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S +new file mode 100644 +index 0000000..80a682a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power7.S +@@ -0,0 +1,33 @@ ++/* isinf(). PowerPC64/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef hidden_def ++#define hidden_def(name) ++#undef weak_alias ++#define weak_alias(name, alias) ++#undef strong_alias ++#define strong_alias(name, alias) ++#undef compat_symbol ++#define compat_symbol(lib, name, alias, ver) ++ ++#define __isinf __isinf_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c +new file mode 100644 +index 0000000..28c5602 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-ppc64.c +@@ -0,0 +1,33 @@ ++/* isinf(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __isinf __isinf_ppc64 ++#ifdef SHARED ++# undef hidden_def ++# define hidden_def(a) \ ++ __hidden_ver1 (__isinf_ppc64, __GI___isinf, __isinf_ppc64); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c +new file mode 100644 +index 0000000..1ee230b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c +@@ -0,0 +1,44 @@ ++/* Multiple versions of isinf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__isinf) __isinf_ppc64 attribute_hidden; ++extern __typeof (__isinf) __isinf_power7 attribute_hidden; ++ ++libc_ifunc (__isinf, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isinf_power7 ++ : __isinf_ppc64); ++ ++weak_alias (__isinf, isinf) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__isinf, __isinfl) ++weak_alias (__isinf, isinfl) ++#endif ++ ++#ifndef IS_IN_libm ++# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0) ++compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0); ++compat_symbol (libc, isinf, isinfl, GLIBC_2_0); ++# endif ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c +new file mode 100644 +index 0000000..c2559d7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff-ppc64.c +@@ -0,0 +1,31 @@ ++/* isinff(). PowerPC64 default version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#define __isinff __isinff_ppc64 ++#ifdef SHARED ++# undef hidden_def ++# define hidden_def(a) \ ++ __hidden_ver1 (__isinff_ppc64, __GI___isinff, __isinff_ppc64); ++#endif ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c +new file mode 100644 +index 0000000..1336feb +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c +@@ -0,0 +1,33 @@ ++/* Multiple versions of isinf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__isinff) __isinff_ppc64 attribute_hidden; ++/* The double-precision version also works for single-precision. */ ++extern __typeof (__isinff) __isinf_power7 attribute_hidden; ++ ++libc_ifunc (__isinff, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __isinf_power7 ++ : __isinff_ppc64); ++ ++weak_alias (__isinff, isinff) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-33.patch b/SOURCES/glibc-rh731837-33.patch new file mode 100644 index 00000000..1929245a --- /dev/null +++ b/SOURCES/glibc-rh731837-33.patch @@ -0,0 +1,697 @@ +From fa809e97912e4bb6faafa74c15a86588c05e89bc Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 12:04:31 -0500 +Subject: [PATCH] PowerPC: multiarch logb/logbl/logbf for PowerPC64 + +commit 43e246d2a6a75710fbe3d3f3db23db3aeb8a9f93 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:36:33 2013 -0500 + +Added the following file apart from the original commit. +sysdeps/powerpc/power7/fpu/s_logb.c +sysdeps/powerpc/power7/fpu/s_logbf.c +sysdeps/powerpc/power7/fpu/s_logbl.c +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c + +--- + sysdeps/ieee754/ldbl-128ibm/s_logbl.c | 2 + + sysdeps/powerpc/power7/fpu/s_logb.c | 78 ++++++++++++++++++++++ + sysdeps/powerpc/power7/fpu/s_logbf.c | 60 +++++++++++++++++ + sysdeps/powerpc/power7/fpu/s_logbl.c | 72 ++++++++++++++++++++ + .../powerpc32/power4/fpu/multiarch/s_logb-power7.c | 31 +++++++++ + .../power4/fpu/multiarch/s_logbf-power7.c | 26 ++++++++ + .../power4/fpu/multiarch/s_logbl-power7.c | 21 ++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 8 ++- + .../powerpc64/fpu/multiarch/s_logb-power7.c | 19 ++++++ + .../powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c | 28 ++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c | 41 ++++++++++++ + .../powerpc64/fpu/multiarch/s_logbf-power7.c | 19 ++++++ + .../powerpc64/fpu/multiarch/s_logbf-ppc64.c | 26 ++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c | 32 +++++++++ + .../powerpc64/fpu/multiarch/s_logbl-power7.c | 19 ++++++ + .../powerpc64/fpu/multiarch/s_logbl-ppc64.c | 21 ++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c | 32 +++++++++ + 17 files changed, 534 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/power7/fpu/s_logb.c + create mode 100644 sysdeps/powerpc/power7/fpu/s_logbf.c + create mode 100644 sysdeps/powerpc/power7/fpu/s_logbl.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c + +diff --git glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c +index 6cbfcfa..28a50de 100644 +--- glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c ++++ glibc-2.17-c758a686/sysdeps/ieee754/ldbl-128ibm/s_logbl.c +@@ -44,4 +44,6 @@ __logbl (long double x) + return (long double) (rhx - 1023); + } + ++#ifndef __logbl + long_double_symbol (libm, __logbl, logbl); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logb.c glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logb.c +new file mode 100644 +index 0000000..87176c3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logb.c +@@ -0,0 +1,78 @@ ++/* logb(). PowerPC/POWER7 version. ++ Copyright (C) 2012 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++/* This implementation avoids FP to INT conversions by using VSX ++ bitwise instructions over FP values. */ ++ ++static const double two1div52 = 2.220446049250313e-16; /* 1/2**52 */ ++static const double two10m1 = -1023.0; /* 2**10 -1 */ ++ ++/* FP mask to extract the exponent. */ ++static const union { ++ unsigned long long mask; ++ double d; ++} mask = { 0x7ff0000000000000ULL }; ++ ++double ++__logb (double x) ++{ ++ double ret; ++ ++ if (__builtin_expect (x == 0.0, 0)) ++ /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF]. */ ++ return -1.0 / __builtin_fabs (x); ++ ++ /* ret = x & 0x7ff0000000000000; */ ++ asm ( ++ "xxland %x0,%x1,%x2\n" ++ "fcfid %0,%0" ++ : "=f" (ret) ++ : "f" (x), "f" (mask.d)); ++ /* ret = (ret >> 52) - 1023.0; */ ++ ret = (ret * two1div52) + two10m1; ++ if (__builtin_expect (ret > -two10m1, 0)) ++ /* Multiplication is used to set logb (+-INF) = INF. */ ++ return (x * x); ++ else if (__builtin_expect (ret == two10m1, 0)) ++ { ++ /* POSIX specifies that denormal numbers are treated as ++ though they were normalized. */ ++ int32_t lx, ix; ++ int ma; ++ ++ EXTRACT_WORDS (ix, lx, x); ++ if (ix == 0) ++ ma = __builtin_clz (lx) + 32; ++ else ++ ma = __builtin_clz (ix); ++ return (double) (-1023 - (ma - 12)); ++ } ++ /* Test to avoid logb_downward (0.0) == -0.0. */ ++ return ret == -0.0 ? 0.0 : ret; ++} ++weak_alias (__logb, logb) ++#ifdef NO_LONG_DOUBLE ++strong_alias (__logb, __logbl) ++weak_alias (__logb, logbl) ++#endif ++ ++#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) ++compat_symbol (libm, logb, logbl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbf.c glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbf.c +new file mode 100644 +index 0000000..aa8499a +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbf.c +@@ -0,0 +1,60 @@ ++/* logbf(). PowerPC/POWER7 version. ++ Copyright (C) 2012 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "math_private.h" ++ ++/* This implementation avoids FP to INT conversions by using VSX ++ bitwise instructions over FP values. */ ++ ++static const double two1div52 = 2.220446049250313e-16; /* 1/2**52 */ ++static const double two10m1 = -1023.0; /* -2**10 + 1 */ ++static const double two7m1 = -127.0; /* -2**7 + 1 */ ++ ++/* FP mask to extract the exponent. */ ++static const union { ++ unsigned long long mask; ++ double d; ++} mask = { 0x7ff0000000000000ULL }; ++ ++float ++__logbf (float x) ++{ ++ /* VSX operation are all done internally as double. */ ++ double ret; ++ ++ if (__builtin_expect (x == 0.0, 0)) ++ /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF]. */ ++ return -1.0 / __builtin_fabsf (x); ++ ++ /* ret = x & 0x7f800000; */ ++ asm ( ++ "xxland %x0,%x1,%x2\n" ++ "fcfid %0,%0" ++ : "=f"(ret) ++ : "f" (x), "f" (mask.d)); ++ /* ret = (ret >> 52) - 1023.0, since ret is double. */ ++ ret = (ret * two1div52) + two10m1; ++ if (__builtin_expect (ret > -two7m1, 0)) ++ /* Multiplication is used to set logb (+-INF) = INF. */ ++ return (x * x); ++ /* Since operations are done with double we don't need ++ additional tests for subnormal numbers. ++ The test is to avoid logb_downward (0.0) == -0.0. */ ++ return ret == -0.0 ? 0.0 : ret; ++} ++weak_alias (__logbf, logbf) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbl.c glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbl.c +new file mode 100644 +index 0000000..e1ec089 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbl.c +@@ -0,0 +1,72 @@ ++/* logbl(). PowerPC/POWER7 version. ++ Copyright (C) 2012 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++/* This implementation avoids FP to INT conversions by using VSX ++ bitwise instructions over FP values. */ ++ ++static const double two1div52 = 2.220446049250313e-16; /* 1/2**52 */ ++static const double two10m1 = -1023.0; /* 2**10 -1 */ ++ ++/* FP mask to extract the exponent. */ ++static const union { ++ unsigned long long mask; ++ double d; ++} mask = { 0x7ff0000000000000ULL }; ++ ++long double ++__logbl (long double x) ++{ ++ double xh, xl; ++ double ret; ++ ++ if (__builtin_expect (x == 0.0L, 0)) ++ /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF]. */ ++ return -1.0L / __builtin_fabsl (x); ++ ++ ldbl_unpack (x, &xh, &xl); ++ /* ret = x & 0x7ff0000000000000; */ ++ asm ( ++ "xxland %x0,%x1,%x2\n" ++ "fcfid %0,%0" ++ : "=f" (ret) ++ : "f" (xh), "f" (mask.d)); ++ /* ret = (ret >> 52) - 1023.0; */ ++ ret = (ret * two1div52) + two10m1; ++ if (__builtin_expect (ret > -two10m1, 0)) ++ /* Multiplication is used to set logb (+-INF) = INF. */ ++ return (xh * xh); ++ else if (__builtin_expect (ret == two10m1, 0)) ++ { ++ /* POSIX specifies that denormal number is treated as ++ though it were normalized. */ ++ int64_t lx, hx; ++ ++ GET_LDOUBLE_WORDS64 (hx, lx, x); ++ return (long double) (-1023 - (__builtin_clzll (hx) - 12)); ++ } ++ /* Test to avoid logb_downward (0.0) == -0.0. */ ++ return ret == -0.0 ? 0.0 : ret; ++} ++ ++#ifndef __logbl ++long_double_symbol (libm, __logbl, logbl); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c +new file mode 100644 +index 0000000..3280566 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logb-power7.c +@@ -0,0 +1,31 @@ ++/* logb(). PowerPC32/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++#undef strong_alias ++#define strong_alias(a, b) ++#undef compat_symbol ++#define compat_symbol(lib, name, alias, ver) ++ ++#define __logb __logb_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c +new file mode 100644 +index 0000000..6531af0 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbf-power7.c +@@ -0,0 +1,26 @@ ++/* logbf(). PowerPC32/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#define __logbf __logbf_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c +new file mode 100644 +index 0000000..7c5ad47 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_logbl-power7.c +@@ -0,0 +1,21 @@ ++/* logbl(). PowerPC32/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define __logbl __logbl_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 64dd85f..87aabca 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -16,5 +16,11 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_copysign-power6 s_copysign-ppc64 s_llrint-power6x \ + s_llrint-ppc64 s_finite-power7 s_finite-ppc64 \ + s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ +- s_isinf-ppc64 ++ s_isinf-ppc64 s_logb-power7 s_logbf-power7 \ ++ s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \ ++ s_logbl-ppc64 ++ ++CFLAGS-s_logbf-power7.c = -mcpu=power7 ++CFLAGS-s_logbl-power7.c = -mcpu=power7 ++CFLAGS-s_logb-power7.c = -mcpu=power7 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c +new file mode 100644 +index 0000000..049f2c1 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-power7.c +@@ -0,0 +1,19 @@ ++/* logb(). PowerPC64/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c +new file mode 100644 +index 0000000..41d1d9b +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb-ppc64.c +@@ -0,0 +1,28 @@ ++/* logb(). PowerPC32/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __logb __logb_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c +new file mode 100644 +index 0000000..e14efa7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logb.c +@@ -0,0 +1,41 @@ ++/* Multiple versions of logb. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__logb) __logb_ppc64 attribute_hidden; ++extern __typeof (__logb) __logb_power7 attribute_hidden; ++ ++libc_ifunc (__logb, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __logb_power7 ++ : __logb_ppc64); ++ ++weak_alias (__logb, logb) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__logb, __logbl) ++weak_alias (__logb, logbl) ++#endif ++ ++#if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0) ++compat_symbol (libm, logb, logbl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c +new file mode 100644 +index 0000000..5e4e4fc +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-power7.c +@@ -0,0 +1,19 @@ ++/* logb(). PowerPC64/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c +new file mode 100644 +index 0000000..08674a6 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf-ppc64.c +@@ -0,0 +1,26 @@ ++/* logbf(). PowerPC64 default implementation. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a, b) ++ ++#define __logbf __logbf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c +new file mode 100644 +index 0000000..01f9ecb +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of logbf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__logbf) __logbf_ppc64 attribute_hidden; ++extern __typeof (__logbf) __logbf_power7 attribute_hidden; ++ ++libc_ifunc (__logbf, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __logbf_power7 ++ : __logbf_ppc64); ++ ++weak_alias (__logbf, logbf) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c +new file mode 100644 +index 0000000..258d502 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-power7.c +@@ -0,0 +1,19 @@ ++/* logb(). PowerPC64/POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c +new file mode 100644 +index 0000000..47d4153 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl-ppc64.c +@@ -0,0 +1,21 @@ ++/* logbl(). PowerPC64/POWER7 version. ++ Copyright (C) 2012-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define __logbl __logbl_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c +new file mode 100644 +index 0000000..cb0b0c5 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_logbl.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of logbl. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__logbl) __logbl_ppc64 attribute_hidden; ++extern __typeof (__logbl) __logbl_power7 attribute_hidden; ++ ++libc_ifunc (__logbl, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __logbl_power7 ++ : __logbl_ppc64); ++ ++long_double_symbol (libm, __logbl, logbl); +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-33A.patch b/SOURCES/glibc-rh731837-33A.patch new file mode 100644 index 00000000..12260613 --- /dev/null +++ b/SOURCES/glibc-rh731837-33A.patch @@ -0,0 +1,44 @@ +--- glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbl.c 2014-09-10 20:52:01.813168232 -0400 ++++ glibc-2.17-c758a686/sysdeps/powerpc/power7/fpu/s_logbl.c 2014-01-02 13:16:41.441557403 -0500 +@@ -1,5 +1,5 @@ + /* logbl(). PowerPC/POWER7 version. +- Copyright (C) 2012 Free Software Foundation, Inc. ++ Copyright (C) 2012-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -35,14 +35,14 @@ + long double + __logbl (long double x) + { +- double xh, xl; ++ double xh; + double ret; + + if (__builtin_expect (x == 0.0L, 0)) + /* Raise FE_DIVBYZERO and return -HUGE_VAL[LF]. */ + return -1.0L / __builtin_fabsl (x); + +- ldbl_unpack (x, &xh, &xl); ++ xh = ldbl_high (x); + /* ret = x & 0x7ff0000000000000; */ + asm ( + "xxland %x0,%x1,%x2\n" +@@ -58,15 +58,14 @@ + { + /* POSIX specifies that denormal number is treated as + though it were normalized. */ +- int64_t lx, hx; ++ int64_t hx; + +- GET_LDOUBLE_WORDS64 (hx, lx, x); ++ EXTRACT_WORDS64 (hx, xh); + return (long double) (-1023 - (__builtin_clzll (hx) - 12)); + } + /* Test to avoid logb_downward (0.0) == -0.0. */ + return ret == -0.0 ? 0.0 : ret; + } +- + #ifndef __logbl + long_double_symbol (libm, __logbl, logbl); + #endif diff --git a/SOURCES/glibc-rh731837-34.patch b/SOURCES/glibc-rh731837-34.patch new file mode 100644 index 00000000..89779701 --- /dev/null +++ b/SOURCES/glibc-rh731837-34.patch @@ -0,0 +1,335 @@ +From 9b608ba89342c722baadb89d221894ca270d4a02 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 12:09:18 -0500 +Subject: [PATCH] PowerPC: multiarch modf/modff for PowerPC64 + +commit 83efded42445e9684173b09a6244109d058ed2bd +Author: Adhemerval Zanella +Date: Fri Dec 13 15:37:23 2013 -0500 + +Added the following files apart from the original commit. +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c +--- + .../power4/fpu/multiarch/s_modf-power5+.c | 31 +++++++++++++++ + .../power4/fpu/multiarch/s_modff-power5+.c | 27 +++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 8 +++- + .../powerpc64/fpu/multiarch/s_modf-power5+.c | 19 ++++++++++ + .../powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c | 29 ++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c | 44 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/s_modff-power5+.c | 19 ++++++++++ + .../powerpc64/fpu/multiarch/s_modff-ppc64.c | 26 +++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c | 30 +++++++++++++++ + 9 files changed, 231 insertions(+), 2 deletions(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c +new file mode 100644 +index 0000000..d7ad0b7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modf-power5+.c +@@ -0,0 +1,31 @@ ++/* PowerPC/POWER5+ implementation for modf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++#undef compat_symbol ++#define compat_symbol(a,b,c,d) ++ ++#define __modf __modf_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c +new file mode 100644 +index 0000000..4021b52 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_modff-power5+.c +@@ -0,0 +1,27 @@ ++/* PowerPC/POWER5+ implementation for modff. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __modff __modff_power5plus ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index 87aabca..e152bf5 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -3,7 +3,8 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_copysign-power6 \ + s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \ + s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ +- s_isinf-ppc64 ++ s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \ ++ s_modff-power5+ s_modff-ppc64 + + libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isnan-power5 s_isnan-ppc64 s_llround-power6x \ +@@ -18,9 +19,12 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \ + s_isinf-ppc64 s_logb-power7 s_logbf-power7 \ + s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \ +- s_logbl-ppc64 ++ s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \ ++ s_modff-power5+ s_modff-ppc64 + + CFLAGS-s_logbf-power7.c = -mcpu=power7 + CFLAGS-s_logbl-power7.c = -mcpu=power7 + CFLAGS-s_logb-power7.c = -mcpu=power7 ++CFLAGS-s_modf-power5+.c = -mcpu=power5+ ++CFLAGS-s_modff-power5+.c = -mcpu=power5+ + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c +new file mode 100644 +index 0000000..bda9920 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-power5+.c +@@ -0,0 +1,19 @@ ++/* PowerPC/POWER5+ implementation for modf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c +new file mode 100644 +index 0000000..90e7599 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf-ppc64.c +@@ -0,0 +1,29 @@ ++/* PowerPC64 default implementation for modf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++#undef strong_alias ++#define strong_alias(a,b) ++ ++#define __modf __modf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c +new file mode 100644 +index 0000000..f416fa9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modf.c +@@ -0,0 +1,44 @@ ++/* Multiple versions of modf. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__modf) __modf_ppc64 attribute_hidden; ++extern __typeof (__modf) __modf_power5plus attribute_hidden; ++ ++libc_ifunc (__modf, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __modf_power5plus ++ : __modf_ppc64); ++ ++weak_alias (__modf, modf) ++ ++#ifdef NO_LONG_DOUBLE ++strong_alias (__modf, __modfl) ++weak_alias (__modf, modfl) ++#endif ++#ifdef IS_IN_libm ++# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) ++compat_symbol (libm, __modf, modfl, GLIBC_2_0); ++# endif ++#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) ++compat_symbol (libc, __modf, modfl, GLIBC_2_0); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c +new file mode 100644 +index 0000000..70a536d +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-power5+.c +@@ -0,0 +1,19 @@ ++/* PowerPC/POWER5+ implementation for modff. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c +new file mode 100644 +index 0000000..89d8f63 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff-ppc64.c +@@ -0,0 +1,26 @@ ++/* PowerPC64 default implementation for modff. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef weak_alias ++#define weak_alias(a,b) ++ ++#define __modff __modff_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c +new file mode 100644 +index 0000000..137b7aa +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/s_modff.c +@@ -0,0 +1,30 @@ ++/* Multiple versions of modff. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include "init-arch.h" ++ ++extern __typeof (__modff) __modff_ppc64 attribute_hidden; ++extern __typeof (__modff) __modff_power5plus attribute_hidden; ++ ++libc_ifunc (__modff, ++ (hwcap & PPC_FEATURE_POWER5_PLUS) ++ ? __modff_power5plus ++ : __modff_ppc64); ++ ++weak_alias (__modff, modff) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-35.patch b/SOURCES/glibc-rh731837-35.patch new file mode 100644 index 00000000..da48f944 --- /dev/null +++ b/SOURCES/glibc-rh731837-35.patch @@ -0,0 +1,308 @@ +From b5910d4c4976f9e1eb6c96d45dc2b7c04f5f3039 Mon Sep 17 00:00:00 2001 +From: Rajalakshmi Srinivasaraghavan +Date: Wed, 30 Jul 2014 12:11:18 -0500 +Subject: [PATCH] PowerPC: multiarch hypot/hypotf for PowerPC64 + +commit 42fcb46ce6dae3a9a55176b4c82e5f07a41ca536 +Author: Adhemerval Zanella +Date: Fri Dec 13 15:38:01 2013 -0500 + +Added the following files apart from the original commit. +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c +sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c +--- + .../power4/fpu/multiarch/e_hypot-power7.c | 26 ++++++++++++++++++ + .../power4/fpu/multiarch/e_hypotf-power7.c | 26 ++++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile | 5 +++- + .../powerpc64/fpu/multiarch/e_hypot-power7.c | 19 +++++++++++++ + .../powerpc64/fpu/multiarch/e_hypot-ppc64.c | 26 ++++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c | 32 ++++++++++++++++++++++ + .../powerpc64/fpu/multiarch/e_hypotf-power7.c | 19 +++++++++++++ + .../powerpc64/fpu/multiarch/e_hypotf-ppc64.c | 26 ++++++++++++++++++ + sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c | 32 ++++++++++++++++++++++ + 9 files changed, 210 insertions(+), 1 deletion(-) + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c + create mode 100644 sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c + create mode 100644 sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c + +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c +new file mode 100644 +index 0000000..967b923 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypot-power7.c +@@ -0,0 +1,26 @@ ++/* __ieee_hypot() POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __ieee754_hypot __ieee754_hypot_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c +new file mode 100644 +index 0000000..d1da9f2 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/e_hypotf-power7.c +@@ -0,0 +1,26 @@ ++/* __ieee754_hypot POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __ieee754_hypotf __ieee754_hypotf_power7 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +index e152bf5..1e04f21 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile +@@ -20,11 +20,14 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \ + s_isinf-ppc64 s_logb-power7 s_logbf-power7 \ + s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \ + s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \ +- s_modff-power5+ s_modff-ppc64 ++ s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \ ++ e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 + + CFLAGS-s_logbf-power7.c = -mcpu=power7 + CFLAGS-s_logbl-power7.c = -mcpu=power7 + CFLAGS-s_logb-power7.c = -mcpu=power7 + CFLAGS-s_modf-power5+.c = -mcpu=power5+ + CFLAGS-s_modff-power5+.c = -mcpu=power5+ ++CFLAGS-e_hypot-power7.c = -mcpu=power7 ++CFLAGS-e_hypotf-power7.c = -mcpu=power7 + endif +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c +new file mode 100644 +index 0000000..b153753 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-power7.c +@@ -0,0 +1,19 @@ ++/* __ieee_hypot() POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c +new file mode 100644 +index 0000000..c418ae7 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot-ppc64.c +@@ -0,0 +1,26 @@ ++/* __ieee_hypot() PowerPC64 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __ieee754_hypot __ieee754_hypot_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c +new file mode 100644 +index 0000000..941b293 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypot.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of ieee754_hypot. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__ieee754_hypot) __ieee754_hypot_ppc64 attribute_hidden; ++extern __typeof (__ieee754_hypot) __ieee754_hypot_power7 attribute_hidden; ++ ++libc_ifunc (__ieee754_hypot, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __ieee754_hypot_power7 ++ : __ieee754_hypot_ppc64); ++ ++strong_alias (__ieee754_hypot, __hypot_finite) +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c +new file mode 100644 +index 0000000..2d67ee9 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-power7.c +@@ -0,0 +1,19 @@ ++/* __ieee_hypotf() POWER7 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c +new file mode 100644 +index 0000000..8335e19 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf-ppc64.c +@@ -0,0 +1,26 @@ ++/* __ieee_hypot() PowerPC64 version. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#undef strong_alias ++#define strong_alias(a, b) ++ ++#define __ieee754_hypotf __ieee754_hypotf_ppc64 ++ ++#include +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c +new file mode 100644 +index 0000000..3c418d3 +--- /dev/null ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c +@@ -0,0 +1,32 @@ ++/* Multiple versions of ieee754_hypot. ++ Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "init-arch.h" ++ ++extern __typeof (__ieee754_hypotf) __ieee754_hypotf_ppc64 attribute_hidden; ++extern __typeof (__ieee754_hypotf) __ieee754_hypotf_power7 attribute_hidden; ++ ++libc_ifunc (__ieee754_hypotf, ++ (hwcap & PPC_FEATURE_ARCH_2_06) ++ ? __ieee754_hypotf_power7 ++ : __ieee754_hypotf_ppc64); ++ ++strong_alias (__ieee754_hypotf, __hypotf_finite) +-- +1.8.3.1 diff --git a/SOURCES/glibc-rh731837-36.patch b/SOURCES/glibc-rh731837-36.patch new file mode 100644 index 00000000..48a1581c --- /dev/null +++ b/SOURCES/glibc-rh731837-36.patch @@ -0,0 +1,382 @@ +# +# Add all of the LOCALENTRY points for all of the functions. +# This is required for LE to materialize the TOC. +# +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S +index b1b4ec7..4a8d459 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memchr-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__memchr_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__memchr_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memchr_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S +index 12db42c..9903276 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power4.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcmp_power4): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcmp_power4) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S +index 4898a88..ee31ca6 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcmp-power7.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcmp_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcmp_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S +index 2d5bfa9..decbcff 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-a2.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcpy_a2): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcpy_a2) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S +index 92c06be..c3c2f7f 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-cell.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcpy_cell): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcpy_cell) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S +index eb01d67..02ba9b1 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power4.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcpy_power4): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcpy_power4) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S +index 13b514d..58e8113 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power6.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcpy_power6): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcpy_power6) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S +index 2aea73d..1170c50 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-power7.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcpy_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcpy_power7) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S +index b828915..c630654 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S +@@ -26,7 +26,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memcpy_ppc): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memcpy_ppc) + + # undef END_GEN_TB + # define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S +index 6a79847..8d4b7a7 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/mempcpy-power7.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__mempcpy_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__mempcpy_power7) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S +index 42ee8e2..c363215 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memrchr-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__memrchr_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__memrchr_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memrchr_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S +index 9074b95..968dc24 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power4.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memset_power4): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memset_power4) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S +index 70688b5..65519b9 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power6.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memset_power6): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memset_power6) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S +index ab226c5..86765e7 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-power7.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memset_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memset_power7) + + #undef END_GEN_TB + #define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S +index dc5549c..3601a77 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S +@@ -37,7 +37,8 @@ END_GEN_TB (__bzero_ppc,TB_TOCLESS) + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__memset_ppc): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__memset_ppc) + + # undef END_GEN_TB + # define END_GEN_TB(name, mask) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S +index 24ae3bf..9f7533a 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/rawmemchr-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__rawmemchr_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__rawmemchr_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__rawmemchr_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S +index 9714f88..ad00f98 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__strcasecmp_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strcasecmp_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strcasecmp_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S +index 117e464..81ec696 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strcasecmp_l-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__strcasecmp_l_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strcasecmp_l_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strcasecmp_l_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S +index 0b2ca42..a3473a6 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__strchr_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strchr_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strchr_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S +index ded9284..607668a 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchr-ppc64.S +@@ -25,7 +25,8 @@ + ENTRY_2(__strchr_ppc) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strchr_ppc): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strchr_ppc) + + # undef END + # define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S +index 87d7c03..95ead0a 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strchrnul-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__strchrnul_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strchrnul_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strchrnul_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S +index a38521d..c47c9d6 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__strlen_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strlen_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strlen_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S +index b463b3a..a195e9a 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S +@@ -25,7 +25,8 @@ + ENTRY_2(__strlen_ppc) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strlen_ppc): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strlen_ppc) + + # undef END + # define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S +index 62cebbc..da32b0b 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power4.S +@@ -24,7 +24,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__strncmp_power4): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strncmp_power4) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S +index b0d607a..65ee0cd 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-power7.S +@@ -24,7 +24,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__strncmp_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strncmp_power7) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S +index 25b7f26..14a2bec 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strncmp-ppc64.S +@@ -25,7 +25,8 @@ + .align ALIGNARG(alignt); \ + EALIGN_W_##words; \ + BODY_LABEL(__strncmp_ppc): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strncmp_ppc) + + #undef END + #define END(name) \ +diff --git glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S +index 909aae8..057e5a8 100644 +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/multiarch/strnlen-power7.S +@@ -24,7 +24,8 @@ + ENTRY_2(__strnlen_power7) \ + .align ALIGNARG(2); \ + BODY_LABEL(__strnlen_power7): \ +- cfi_startproc; ++ cfi_startproc; \ ++ LOCALENTRY(__strnlen_power7) + + #undef END + #define END(name) \ diff --git a/SOURCES/glibc-rh739743.patch b/SOURCES/glibc-rh739743.patch new file mode 100644 index 00000000..1d261999 --- /dev/null +++ b/SOURCES/glibc-rh739743.patch @@ -0,0 +1,56 @@ +Upstream commit: + +commit 894f3f1049135dcbeaab8f18690973663ef3147c +Author: Allan McRae +Date: Fri Oct 25 14:25:38 2013 +1000 + + Fix incorrect getaddrinfo assertion trigger + + [BZ #9954] + +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -1456,13 +1456,13 @@ + + /* Fill in the results in all the records. */ + for (int i = 0; i < src->nresults; ++i) +- if (src->results[i].index == a1_index) ++ if (a1_index != -1 && src->results[i].index == a1_index) + { + assert (src->results[i].native == -1 + || src->results[i].native == a1_native); + src->results[i].native = a1_native; + } +- else if (src->results[i].index == a2_index) ++ else if (a2_index != -1 && src->results[i].index == a2_index) + { + assert (src->results[i].native == -1 + || src->results[i].native == a2_native); + +2009-03-15 Aurelien Jarno + + * sysdeps/posix/getaddrinfo.c (getaddrinfo): correctly detect + interface for all 127.X.Y.Z addresses. + +--- + sysdeps/posix/getaddrinfo.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -2265,7 +2265,14 @@ + tmp.addr[0] = 0; + tmp.addr[1] = 0; + tmp.addr[2] = htonl (0xffff); +- tmp.addr[3] = sinp->sin_addr.s_addr; ++ /* Special case for lo interface, the source address ++ being possibly different than the interface ++ address. */ ++ if ((ntohl(sinp->sin_addr.s_addr) & 0xff000000) ++ == 0x7f000000) ++ tmp.addr[3] = htonl(0x7f000001); ++ else ++ tmp.addr[3] = sinp->sin_addr.s_addr; + } + else + { diff --git a/SOURCES/glibc-rh741105.patch b/SOURCES/glibc-rh741105.patch new file mode 100644 index 00000000..c83cac96 --- /dev/null +++ b/SOURCES/glibc-rh741105.patch @@ -0,0 +1,21 @@ +diff -rup glibc-2.17-c758a686/elf/dl-load.c glibc-2.17-c758a686/elf/dl-load.c +--- glibc-2.17-c758a686/elf/dl-load.c 2012-02-03 10:59:58.917870716 -0700 ++++ glibc-2.17-c758a686/elf/dl-load.c 2012-02-03 11:01:01.796580644 -0700 +@@ -1130,6 +1130,16 @@ _dl_map_object_from_fd (const char *name + = N_("ELF load command address/offset not properly aligned"); + goto call_lose; + } ++ if (__builtin_expect ((ph->p_offset + ph->p_filesz > st.st_size), 0)) ++ { ++ /* If the segment requires zeroing of part of its last ++ page, we'll crash when accessing the unmapped page. ++ There's still a possibility of a race, if the shared ++ object is truncated between the fxstat above and the ++ memset below. */ ++ errstring = N_("ELF load command past end of file"); ++ goto call_lose; ++ } + + c = &loadcmds[nloadcmds++]; + c->mapstart = ph->p_vaddr & ~(GLRO(dl_pagesize) - 1); +Only inglibc-2.17-c758a686/elf: dl-load.c.orig diff --git a/SOURCES/glibc-rh742038.patch b/SOURCES/glibc-rh742038.patch new file mode 100644 index 00000000..d9b5b1fd --- /dev/null +++ b/SOURCES/glibc-rh742038.patch @@ -0,0 +1,607 @@ +Author: Alexandre Oliva + + Add malloc probes for sbrk and heap resizing. + + * malloc/arena.c (new_heap): New memory_heap_new probe. + (grow_heap): New memory_heap_more probe. + (shrink_heap): New memory_heap_less probe. + (heap_trim): New memory_heap_free probe. + * malloc/malloc.c (sysmalloc): New memory_sbrk_more probe. + (systrim): New memory_sbrk_less probe. + * manual/probes.texi: Document them. + + Add catch-all alloc retry probe. + + * malloc/arena.c (arena_get_retry): Add memory_arena_retry probe. + * manual/probes.texi: Document it. + + Add probes for malloc retries. + + * malloc/malloc.c (__libc_malloc): Add memory_malloc_retry probe. + (__libc_realloc): Add memory_realloc_retry probe. + (__libc_memalign): Add memory_memalign_retry probe. + (__libc_valloc): Add memory_valloc_retry probe. + (__libc_pvalloc): Add memory_pvalloc_retry probe. + (__libc_calloc): Add memory_calloc_retry probe. + * manual/probes.texi: Document them. + + Add probes for malloc arena changes. + + * malloc/arena.c (get_free_list): Add probe + memory_arena_reuse_free_list. + (reused_arena) [PER_THREAD]: Add probes memory_arena_reuse_wait + and memory_arena_reuse. + (arena_get2) [!PER_THREAD]: Likewise. + * malloc/malloc.c (__libc_realloc) [!PER_THREAD]: Add probe + memory_arena_reuse_realloc. + * manual/probes.texi: Document them. + + Add probes for all changes to malloc options. + + * malloc/malloc.c (__libc_free): Add + memory_mallopt_free_dyn_thresholds probe. + (__libc_mallopt): Add multiple memory_mallopt probes. + * manual/probes.texi: Document them. + + Add first set of memory probes. + + * malloc/malloc.c: Include stap-probe.h. + (__libc_mallopt): Add memory_mallopt probe. + * malloc/arena.c (_int_new_arena): Add memory_arena_new probe. + * manual/probes.texi: New. + * manual/Makefile (chapters): Add probes. + * manual/debug.texi: Set next node. + +Index: glibc-2.17-c758a686/malloc/arena.c +=================================================================== +--- glibc-2.17-c758a686/malloc/arena.c.orig ++++ glibc-2.17-c758a686/malloc/arena.c +@@ -586,6 +586,7 @@ new_heap(size_t size, size_t top_pad) + h->size = size; + h->mprotect_size = size; + THREAD_STAT(stat_n_heaps++); ++ LIBC_PROBE (memory_heap_new, 2, h, h->size); + return h; + } + +@@ -611,6 +612,7 @@ grow_heap(heap_info *h, long diff) + } + + h->size = new_size; ++ LIBC_PROBE (memory_heap_more, 2, h, h->size); + return 0; + } + +@@ -638,6 +640,7 @@ shrink_heap(heap_info *h, long diff) + /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/ + + h->size = new_size; ++ LIBC_PROBE (memory_heap_less, 2, h, h->size); + return 0; + } + +@@ -679,6 +682,7 @@ heap_trim(heap_info *heap, size_t pad) + break; + ar_ptr->system_mem -= heap->size; + arena_mem -= heap->size; ++ LIBC_PROBE (memory_heap_free, 2, heap, heap->size); + delete_heap(heap); + heap = prev_heap; + if(!prev_inuse(p)) { /* consolidate backward */ +@@ -741,6 +745,7 @@ _int_new_arena(size_t size) + top(a) = (mchunkptr)ptr; + set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE); + ++ LIBC_PROBE (memory_arena_new, 2, a, size); + tsd_setspecific(arena_key, (void *)a); + mutex_init(&a->mutex); + (void)mutex_lock(&a->mutex); +@@ -779,6 +784,7 @@ get_free_list (void) + + if (result != NULL) + { ++ LIBC_PROBE (memory_arena_reuse_free_list, 1, result); + (void)mutex_lock(&result->mutex); + tsd_setspecific(arena_key, (void *)result); + THREAD_STAT(++(result->stat_lock_loop)); +@@ -815,9 +821,11 @@ reused_arena (mstate avoid_arena) + result = result->next; + + /* No arena available. Wait for the next in line. */ ++ LIBC_PROBE (memory_arena_reuse_wait, 3, &result->mutex, result, avoid_arena); + (void)mutex_lock(&result->mutex); + + out: ++ LIBC_PROBE (memory_arena_reuse, 2, result, avoid_arena); + tsd_setspecific(arena_key, (void *)result); + THREAD_STAT(++(result->stat_lock_loop)); + next_to_use = result->next; +@@ -896,6 +904,7 @@ arena_get2(mstate a_tsd, size_t size, ms + if (retried) + (void)mutex_unlock(&list_lock); + THREAD_STAT(++(a->stat_lock_loop)); ++ LIBC_PROBE (memory_arena_reuse, 2, a, a_tsd); + tsd_setspecific(arena_key, (void *)a); + return a; + } +@@ -908,6 +917,7 @@ arena_get2(mstate a_tsd, size_t size, ms + locks. */ + if(!retried && mutex_trylock(&list_lock)) { + /* We will block to not run in a busy loop. */ ++ LIBC_PROBE (memory_arena_reuse_wait, 3, &list_lock, NULL, a_tsd); + (void)mutex_lock(&list_lock); + + /* Since we blocked there might be an arena available now. */ +@@ -931,6 +941,7 @@ arena_get2(mstate a_tsd, size_t size, ms + static mstate + arena_get_retry (mstate ar_ptr, size_t bytes) + { ++ LIBC_PROBE (memory_arena_retry, 2, bytes, ar_ptr); + if(ar_ptr != &main_arena) { + (void)mutex_unlock(&ar_ptr->mutex); + ar_ptr = &main_arena; +Index: glibc-2.17-c758a686/malloc/malloc.c +=================================================================== +--- glibc-2.17-c758a686/malloc/malloc.c.orig ++++ glibc-2.17-c758a686/malloc/malloc.c +@@ -1884,6 +1884,8 @@ static int perturb_byte; + #define free_perturb(p, n) memset (p, perturb_byte & 0xff, n) + + ++#include ++ + /* ------------------- Support for multiple arenas -------------------- */ + #include "arena.c" + +@@ -2452,8 +2454,10 @@ static void* sysmalloc(INTERNAL_SIZE_T n + below even if we cannot call MORECORE. + */ + +- if (size > 0) ++ if (size > 0) { + brk = (char*)(MORECORE(size)); ++ LIBC_PROBE (memory_sbrk_more, 2, brk, size); ++ } + + if (brk != (char*)(MORECORE_FAILURE)) { + /* Call the `morecore' hook if necessary. */ +@@ -2753,6 +2757,8 @@ static int systrim(size_t pad, mstate av + (*hook) (); + new_brk = (char*)(MORECORE(0)); + ++ LIBC_PROBE (memory_sbrk_less, 2, new_brk, extra); ++ + if (new_brk != (char*)MORECORE_FAILURE) { + released = (long)(current_brk - new_brk); + +@@ -2862,6 +2868,7 @@ __libc_malloc(size_t bytes) + return 0; + victim = _int_malloc(ar_ptr, bytes); + if(!victim) { ++ LIBC_PROBE (memory_malloc_retry, 1, bytes); + ar_ptr = arena_get_retry(ar_ptr, bytes); + if (__builtin_expect(ar_ptr != NULL, 1)) { + victim = _int_malloc(ar_ptr, bytes); +@@ -2902,6 +2909,8 @@ __libc_free(void* mem) + { + mp_.mmap_threshold = chunksize (p); + mp_.trim_threshold = 2 * mp_.mmap_threshold; ++ LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2, ++ mp_.mmap_threshold, mp_.trim_threshold); + } + munmap_chunk(p); + return; +@@ -2981,6 +2990,7 @@ __libc_realloc(void* oldmem, size_t byte + #endif + + #if !defined PER_THREAD ++ LIBC_PROBE (memory_arena_reuse_realloc, 1, ar_ptr); + /* As in malloc(), remember this arena for the next allocation. */ + tsd_setspecific(arena_key, (void *)ar_ptr); + #endif +@@ -2994,6 +3004,7 @@ __libc_realloc(void* oldmem, size_t byte + if (newp == NULL) + { + /* Try harder to allocate memory in other arenas. */ ++ LIBC_PROBE (memory_realloc_retry, 2, bytes, oldmem); + newp = __libc_malloc(bytes); + if (newp != NULL) + { +@@ -3029,6 +3040,7 @@ __libc_memalign(size_t alignment, size_t + return 0; + p = _int_memalign(ar_ptr, alignment, bytes); + if(!p) { ++ LIBC_PROBE (memory_memalign_retry, 2, bytes, alignment); + ar_ptr = arena_get_retry (ar_ptr, bytes); + if (__builtin_expect(ar_ptr != NULL, 1)) { + p = _int_memalign(ar_ptr, alignment, bytes); +@@ -3066,6 +3078,7 @@ __libc_valloc(size_t bytes) + return 0; + p = _int_valloc(ar_ptr, bytes); + if(!p) { ++ LIBC_PROBE (memory_valloc_retry, 1, bytes); + ar_ptr = arena_get_retry (ar_ptr, bytes); + if (__builtin_expect(ar_ptr != NULL, 1)) { + p = _int_memalign(ar_ptr, pagesz, bytes); +@@ -3101,6 +3114,7 @@ __libc_pvalloc(size_t bytes) + arena_get(ar_ptr, bytes + 2*pagesz + MINSIZE); + p = _int_pvalloc(ar_ptr, bytes); + if(!p) { ++ LIBC_PROBE (memory_pvalloc_retry, 1, bytes); + ar_ptr = arena_get_retry (ar_ptr, bytes + 2*pagesz + MINSIZE); + if (__builtin_expect(ar_ptr != NULL, 1)) { + p = _int_memalign(ar_ptr, pagesz, rounded_bytes); +@@ -3177,6 +3191,7 @@ __libc_calloc(size_t n, size_t elem_size + av == arena_for_chunk(mem2chunk(mem))); + + if (mem == 0) { ++ LIBC_PROBE (memory_calloc_retry, 1, sz); + av = arena_get_retry (av, sz); + if (__builtin_expect(av != NULL, 1)) { + mem = _int_malloc(av, sz); +@@ -4695,21 +4710,29 @@ int __libc_mallopt(int param_number, int + /* Ensure initialization/consolidation */ + malloc_consolidate(av); + ++ LIBC_PROBE (memory_mallopt, 2, param_number, value); ++ + switch(param_number) { + case M_MXFAST: +- if (value >= 0 && value <= MAX_FAST_SIZE) { +- set_max_fast(value); +- } ++ if (value >= 0 && value <= MAX_FAST_SIZE) ++ { ++ LIBC_PROBE (memory_mallopt_mxfast, 2, value, get_max_fast ()); ++ set_max_fast(value); ++ } + else + res = 0; + break; + + case M_TRIM_THRESHOLD: ++ LIBC_PROBE (memory_mallopt_trim_threshold, 3, value, ++ mp_.trim_threshold, mp_.no_dyn_threshold); + mp_.trim_threshold = value; + mp_.no_dyn_threshold = 1; + break; + + case M_TOP_PAD: ++ LIBC_PROBE (memory_mallopt_top_pad, 3, value, ++ mp_.top_pad, mp_.no_dyn_threshold); + mp_.top_pad = value; + mp_.no_dyn_threshold = 1; + break; +@@ -4720,33 +4743,45 @@ int __libc_mallopt(int param_number, int + res = 0; + else + { ++ LIBC_PROBE (memory_mallopt_mmap_threshold, 3, value, ++ mp_.mmap_threshold, mp_.no_dyn_threshold); + mp_.mmap_threshold = value; + mp_.no_dyn_threshold = 1; + } + break; + + case M_MMAP_MAX: ++ LIBC_PROBE (memory_mallopt_mmap_max, 3, value, ++ mp_.n_mmaps_max, mp_.no_dyn_threshold); + mp_.n_mmaps_max = value; + mp_.no_dyn_threshold = 1; + break; + + case M_CHECK_ACTION: ++ LIBC_PROBE (memory_mallopt_check_action, 2, value, check_action); + check_action = value; + break; + + case M_PERTURB: ++ LIBC_PROBE (memory_mallopt_perturb, 2, value, perturb_byte); + perturb_byte = value; + break; + + #ifdef PER_THREAD + case M_ARENA_TEST: + if (value > 0) +- mp_.arena_test = value; ++ { ++ LIBC_PROBE (memory_mallopt_arena_test, 2, value, mp_.arena_test); ++ mp_.arena_test = value; ++ } + break; + + case M_ARENA_MAX: + if (value > 0) +- mp_.arena_max = value; ++ { ++ LIBC_PROBE (memory_mallopt_arena_max, 2, value, mp_.arena_max); ++ mp_.arena_max = value; ++ } + break; + #endif + } +Index: glibc-2.17-c758a686/manual/Makefile +=================================================================== +--- glibc-2.17-c758a686/manual/Makefile.orig ++++ glibc-2.17-c758a686/manual/Makefile +@@ -43,7 +43,7 @@ chapters = $(addsuffix .texi, \ + message search pattern io stdio llio filesys \ + pipe socket terminal syslog math arith time \ + resource setjmp signal startup process job nss \ +- users sysinfo conf crypt debug) ++ users sysinfo conf crypt debug probes) + add-chapters = $(wildcard $(foreach d, $(add-ons), ../$d/$d.texi)) + appendices = lang.texi header.texi install.texi maint.texi platform.texi \ + contrib.texi +Index: glibc-2.17-c758a686/manual/probes.texi +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/manual/probes.texi +@@ -0,0 +1,257 @@ ++@node Internal Probes ++@c @node Internal Probes, , Debugging Support, Top ++@c %MENU% Probes to monitor libc internal behavior ++@chapter Internal probes ++ ++In order to aid in debugging and monitoring internal behavior, ++@theglibc{} exposes nearly-zero-overhead SystemTap probes marked with ++the @code{libc} provider. ++ ++These probes are not part of the @glibcadj{} stable ABI, and they are ++subject to change or removal across releases. Our only promise with ++regard to them is that, if we find a need to remove or modify the ++arguments of a probe, the modified probe will have a different name, so ++that program monitors relying on the old probe will not get unexpected ++arguments. ++ ++@menu ++* Memory Allocation Probes:: Probes in the memory allocation subsystem ++@end menu ++ ++@node Memory Allocation Probes ++@section Memory Allocation Probes ++ ++These probes are designed to signal relatively unusual situations within ++the virtual memory subsystem of @theglibc{}. The location and the ++availability of some probes depend on whether per-thread arenas are ++enabled (the default) or disabled at the time @theglibc{} is compiled. ++ ++@deftp Probe memory_sbrk_more (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered after the main arena is extended by calling ++@code{sbrk}. Argument @var{$arg1} is the additional size requested to ++@code{sbrk}, and @var{$arg2} is the pointer that marks the end of the ++@code{sbrk} area, returned in response to the request. ++@end deftp ++ ++@deftp Probe memory_sbrk_less (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered after the size of the main arena is decreased by ++calling @code{sbrk}. Argument @var{$arg1} is the size released by ++@code{sbrk} (the positive value, rather than the negative value passed ++to @code{sbrk}), and @var{$arg2} is the pointer that marks the end of ++the @code{sbrk} area, returned in response to the request. ++@end deftp ++ ++@deftp Probe memory_heap_new (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered after a new heap is @code{mmap}ed. Argument ++@var{$arg1} is a pointer to the base of the memory area, where the ++@code{heap_info} data structure is held, and @var{$arg2} is the size of ++the heap. ++@end deftp ++ ++@deftp Probe memory_heap_free (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered @emph{before} (unlike the other sbrk and heap ++probes) a heap is completely removed via @code{munmap}. Argument ++@var{$arg1} is a pointer to the heap, and @var{$arg2} is the size of the ++heap. ++@end deftp ++ ++@deftp Probe memory_heap_more (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered after a trailing portion of an @code{mmap}ed ++heap is extended. Argument @var{$arg1} is a pointer to the heap, and ++@var{$arg2} is the new size of the heap. ++@end deftp ++ ++@deftp Probe memory_heap_less (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered after a trailing portion of an @code{mmap}ed ++heap is released. Argument @var{$arg1} is a pointer to the heap, and ++@var{$arg2} is the new size of the heap. ++@end deftp ++ ++@deftp Probe memory_malloc_retry (size_t @var{$arg1}) ++@deftpx Probe memory_realloc_retry (size_t @var{$arg1}, void *@var{$arg2}) ++@deftpx Probe memory_memalign_retry (size_t @var{$arg1}, size_t @var{$arg2}) ++@deftpx Probe memory_valloc_retry (size_t @var{$arg1}) ++@deftpx Probe memory_pvalloc_retry (size_t @var{$arg1}) ++@deftpx Probe memory_calloc_retry (size_t @var{$arg1}) ++These probes are triggered when the corresponding functions fail to ++obtain the requested amount of memory from the arena in use, before they ++call @code{arena_get_retry} to select an alternate arena in which to ++retry the allocation. Argument @var{$arg1} is the amount of memory ++requested by the user; in the @code{calloc} case, that is the total size ++computed from both function arguments. In the @code{realloc} case, ++@var{$arg2} is the pointer to the memory area being resized. In the ++@code{memalign} case, @var{$arg2} is the alignment to be used for the ++request, which may be stricter than the value passed to the ++@code{memalign} function. ++ ++Note that the argument order does @emph{not} match that of the ++corresponding two-argument functions, so that in all of these probes the ++user-requested allocation size is in @var{$arg1}. ++@end deftp ++ ++@deftp Probe memory_arena_retry (size_t @var{$arg1}, void *@var{$arg2}) ++This probe is triggered within @code{arena_get_retry} (the function ++called to select the alternate arena in which to retry an allocation ++that failed on the first attempt), before the selection of an alternate ++arena. This probe is redundant, but much easier to use when it's not ++important to determine which of the various memory allocation functions ++is failing to allocate on the first try. Argument @var{$arg1} is the ++same as in the function-specific probes, except for extra room for ++padding introduced by functions that have to ensure stricter alignment. ++Argument @var{$arg2} is the arena in which allocation failed. ++@end deftp ++ ++@deftp Probe memory_arena_new (void *@var{$arg1}, size_t @var{$arg2}) ++This probe is triggered when @code{malloc} allocates and initializes an ++additional arena (not the main arena), but before the arena is assigned ++to the running thread or inserted into the internal linked list of ++arenas. The arena's @code{malloc_state} internal data structure is ++located at @var{$arg1}, within a newly-allocated heap big enough to hold ++at least @var{$arg2} bytes. ++@end deftp ++ ++@deftp Probe memory_arena_reuse (void *@var{$arg1}, void *@var{$arg2}) ++This probe is triggered when @code{malloc} has just selected an existing ++arena to reuse, and (temporarily) reserved it for exclusive use. ++Argument @var{$arg1} is a pointer to the newly-selected arena, and ++@var{$arg2} is a pointer to the arena previously used by that thread. ++ ++When per-thread arenas are enabled, this occurs within ++@code{reused_arena}, right after the mutex mentioned in probe ++@code{memory_arena_reuse_wait} is acquired; argument @var{$arg1} will ++point to the same arena. In this configuration, this will usually only ++occur once per thread. The exception is when a thread first selected ++the main arena, but a subsequent allocation from it fails: then, and ++only then, may we switch to another arena to retry that allocations, and ++for further allocations within that thread. ++ ++When per-thread arenas are disabled, this occurs within ++@code{arena_get2}, whenever the mutex for the previously-selected arena ++cannot be immediately acquired. ++@end deftp ++ ++@deftp Probe memory_arena_reuse_wait (void *@var{$arg1}, void *@var{$arg2}, void *@var{$arg3}) ++This probe is triggered when @code{malloc} is about to wait for an arena ++to become available for reuse. Argument @var{$arg1} holds a pointer to ++the mutex the thread is going to wait on, @var{$arg2} is a pointer to a ++newly-chosen arena to be reused, and @var{$arg3} is a pointer to the ++arena previously used by that thread. ++ ++When per-thread arenas are enabled, this occurs within ++@code{reused_arena}, when a thread first tries to allocate memory or ++needs a retry after a failure to allocate from the main arena, there ++isn't any free arena, the maximum number of arenas has been reached, and ++an existing arena was chosen for reuse, but its mutex could not be ++immediately acquired. The mutex in @var{$arg1} is the mutex of the ++selected arena. ++ ++When per-thread arenas are disabled, this occurs within ++@code{arena_get2}, when a thread first tries to allocate memory or the ++mutex of the arena it previously used could not be immediately acquired, ++and none of the existing arenas could be immediately reserved for ++exclusive use. The mutex in @var{$arg1} is that of the list of arenas, ++and since the arena won't have been selected yet, @var{$arg2} will be ++@code{NULL}. ++@end deftp ++ ++@deftp Probe memory_arena_reuse_free_list (void *@var{$arg1}) ++This probe is triggered when @code{malloc} has chosen an arena that is ++in the free list for use by a thread, within the @code{get_free_list} ++function. This probe is only available when @code{malloc} is configured ++to use per-thread arenas. The argument @var{$arg1} holds a pointer to ++the selected arena. ++@end deftp ++ ++@deftp Probe memory_arena_reuse_realloc (void *@var{$arg1}) ++This probe is triggered within @code{realloc}, as the arena of the ++current thread is changed to match that in which the given address was ++allocated. This probe is @emph{not} available when @code{malloc} is ++configured to use per-thread arenas. The argument @var{$arg1} holds a ++pointer to the newly-selected arena. ++@end deftp ++ ++@deftp Probe memory_mallopt (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered when function @code{mallopt} is called to change ++@code{malloc} internal configuration parameters, before any change to ++the parameters is made. The arguments @var{$arg1} and @var{$arg2} are ++the ones passed to the @code{mallopt} function. ++@end deftp ++ ++@deftp Probe memory_mallopt_mxfast (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_MXFAST}, and the requested ++value is in an acceptable range. Argument @var{$arg1} is the requested ++value, and @var{$arg2} is the previous value of this @code{malloc} ++parameter. ++@end deftp ++ ++@deftp Probe memory_mallopt_trim_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3}) ++This probe is triggere shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_TRIM_THRESHOLD}. Argument ++@var{$arg1} is the requested value, @var{$arg2} is the previous value of ++this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic ++threshold adjustment was already disabled. ++@end deftp ++ ++@deftp Probe memory_mallopt_top_pad (int @var{$arg1}, int @var{$arg2}, int @var{$arg3}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_TOP_PAD}. Argument ++@var{$arg1} is the requested value, @var{$arg2} is the previous value of ++this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic ++threshold adjustment was already disabled. ++@end deftp ++ ++@deftp Probe memory_mallopt_mmap_threshold (int @var{$arg1}, int @var{$arg2}, int @var{$arg3}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_MMAP_THRESHOLD}, and the ++requested value is in an acceptable range. Argument @var{$arg1} is the ++requested value, @var{$arg2} is the previous value of this @code{malloc} ++parameter, and @var{$arg3} is nonzero if dynamic threshold adjustment ++was already disabled. ++@end deftp ++ ++@deftp Probe memory_mallopt_mmap_max (int @var{$arg1}, int @var{$arg2}, int @var{$arg3}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_MMAP_MAX}. Argument ++@var{$arg1} is the requested value, @var{$arg2} is the previous value of ++this @code{malloc} parameter, and @var{$arg3} is nonzero if dynamic ++threshold adjustment was already disabled. ++@end deftp ++ ++@deftp Probe memory_mallopt_check_action (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_CHECK_ACTION}. Argument ++@var{$arg1} is the requested value, and @var{$arg2} is the previous ++value of this @code{malloc} parameter. ++@end deftp ++ ++@deftp Probe memory_mallopt_perturb (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_PERTURB}. Argument ++@var{$arg1} is the requested value, and @var{$arg2} is the previous ++value of this @code{malloc} parameter. ++@end deftp ++ ++@deftp Probe memory_mallopt_arena_test (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_ARENA_TEST}, and the ++requested value is in an acceptable range. Argument @var{$arg1} is the ++requested value, and @var{$arg2} is the previous value of this ++@code{malloc} parameter. This probe is only available when per-thread ++arenas are enabled. ++@end deftp ++ ++@deftp Probe memory_mallopt_arena_max (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered shortly after the @code{memory_mallopt} probe, ++when the parameter to be changed is @code{M_ARENA_MAX}, and the ++requested value is in an acceptable range. Argument @var{$arg1} is the ++requested value, and @var{$arg2} is the previous value of this ++@code{malloc} parameter. This probe is only available when per-thread ++arenas are enabled. ++@end deftp ++ ++@deftp Probe memory_mallopt_free_dyn_thresholds (int @var{$arg1}, int @var{$arg2}) ++This probe is triggered when function @code{free} decides to adjust the ++dynamic brk/mmap thresholds. Argument @var{$arg1} and @var{$arg2} are ++the adjusted mmap and trim thresholds, respectively. ++@end deftp +Index: glibc-2.17-c758a686/manual/debug.texi +=================================================================== +--- glibc-2.17-c758a686/manual/debug.texi.orig ++++ glibc-2.17-c758a686/manual/debug.texi +@@ -1,5 +1,5 @@ + @node Debugging Support +-@c @node Debugging Support, , Cryptographic Functions, Top ++@c @node Debugging Support, Internal Probes, Cryptographic Functions, Top + @c %MENU% Functions to help debugging applications + @chapter Debugging support diff --git a/SOURCES/glibc-rh757881.patch b/SOURCES/glibc-rh757881.patch new file mode 100644 index 00000000..26e347b2 --- /dev/null +++ b/SOURCES/glibc-rh757881.patch @@ -0,0 +1,167 @@ +diff -Nru glibc-2.17-c758a686/malloc/arena.c glibc-2.17-c758a686/malloc/arena.c +--- glibc-2.17-c758a686/malloc/arena.c 2012-05-29 16:45:53.000000000 -0600 ++++ glibc-2.17-c758a686/malloc/arena.c 2012-05-30 00:13:40.683514016 -0600 +@@ -673,7 +673,7 @@ heap_trim(heap_info *heap, size_t pad) + heap = prev_heap; + if(!prev_inuse(p)) { /* consolidate backward */ + p = prev_chunk(p); +- unlink(p, bck, fwd); ++ unlink(ar_ptr, p, bck, fwd); + } + assert(((unsigned long)((char*)p + new_size) & (pagesz-1)) == 0); + assert( ((char*)p + new_size) == ((char*)heap + heap->size) ); +diff -Nru glibc-2.17-c758a686/malloc/hooks.c glibc-2.17-c758a686/malloc/hooks.c +--- glibc-2.17-c758a686/malloc/hooks.c 2012-05-29 16:45:53.000000000 -0600 ++++ glibc-2.17-c758a686/malloc/hooks.c 2012-05-30 00:13:40.684514011 -0600 +@@ -191,7 +191,9 @@ top_check(void) + (char*)t + chunksize(t) == mp_.sbrk_base + main_arena.system_mem))) + return 0; + ++ mutex_unlock(&main_arena); + malloc_printerr (check_action, "malloc: top chunk is corrupt", t); ++ mutex_lock(&main_arena); + + /* Try to set up a new top chunk. */ + brk = MORECORE(0); +diff -Nru glibc-2.17-c758a686/malloc/malloc.c glibc-2.17-c758a686/malloc/malloc.c +--- glibc-2.17-c758a686/malloc/malloc.c 2012-05-29 16:45:53.000000000 -0600 ++++ glibc-2.17-c758a686/malloc/malloc.c 2012-05-30 00:13:40.686514001 -0600 +@@ -1424,12 +1424,14 @@ typedef struct malloc_chunk* mbinptr; + #define last(b) ((b)->bk) + + /* Take a chunk off a bin list */ +-#define unlink(P, BK, FD) { \ ++#define unlink(AV, P, BK, FD) { \ + FD = P->fd; \ + BK = P->bk; \ +- if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ ++ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) { \ ++ mutex_unlock(&(AV)->mutex); \ + malloc_printerr (check_action, "corrupted double-linked list", P); \ +- else { \ ++ mutex_lock(&(AV)->mutex); \ ++ } else { \ + FD->bk = BK; \ + BK->fd = FD; \ + if (!in_smallbin_range (P->size) \ +@@ -2511,7 +2513,9 @@ static void* sysmalloc(INTERNAL_SIZE_T n + + else if (contiguous(av) && old_size && brk < old_end) { + /* Oops! Someone else killed our space.. Can't touch anything. */ ++ mutex_unlock(&av->mutex); + malloc_printerr (3, "break adjusted to free malloc space", brk); ++ mutex_lock(&av->mutex); + } + + /* +@@ -3345,7 +3349,9 @@ _int_malloc(mstate av, size_t bytes) + { + errstr = "malloc(): memory corruption (fast)"; + errout: ++ mutex_unlock(&av->mutex); + malloc_printerr (check_action, errstr, chunk2mem (victim)); ++ mutex_lock(&av->mutex); + return NULL; + } + check_remalloced_chunk(av, victim, nb); +@@ -3430,8 +3436,12 @@ _int_malloc(mstate av, size_t bytes) + bck = victim->bk; + if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0) + || __builtin_expect (victim->size > av->system_mem, 0)) +- malloc_printerr (check_action, "malloc(): memory corruption", +- chunk2mem (victim)); ++ { ++ void *p = chunk2mem(victim); ++ mutex_unlock(&av->mutex); ++ malloc_printerr (check_action, "malloc(): memory corruption", p); ++ mutex_lock(&av->mutex); ++ } + size = chunksize(victim); + + /* +@@ -3572,7 +3582,7 @@ _int_malloc(mstate av, size_t bytes) + victim = victim->fd; + + remainder_size = size - nb; +- unlink(victim, bck, fwd); ++ unlink(av, victim, bck, fwd); + + /* Exhaust */ + if (remainder_size < MINSIZE) { +@@ -3670,7 +3680,7 @@ _int_malloc(mstate av, size_t bytes) + remainder_size = size - nb; + + /* unlink */ +- unlink(victim, bck, fwd); ++ unlink(av, victim, bck, fwd); + + /* Exhaust */ + if (remainder_size < MINSIZE) { +@@ -3805,9 +3815,11 @@ _int_free(mstate av, mchunkptr p, int ha + { + errstr = "free(): invalid pointer"; + errout: +- if (! have_lock && locked) ++ if (have_lock || locked) + (void)mutex_unlock(&av->mutex); + malloc_printerr (check_action, errstr, chunk2mem(p)); ++ if (have_lock) ++ mutex_lock(&av->mutex); + return; + } + /* We know that each chunk is at least MINSIZE bytes in size or a +@@ -3952,7 +3964,7 @@ _int_free(mstate av, mchunkptr p, int ha + prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); +- unlink(p, bck, fwd); ++ unlink(av, p, bck, fwd); + } + + if (nextchunk != av->top) { +@@ -3961,7 +3973,7 @@ _int_free(mstate av, mchunkptr p, int ha + + /* consolidate forward */ + if (!nextinuse) { +- unlink(nextchunk, bck, fwd); ++ unlink(av, nextchunk, bck, fwd); + size += nextsize; + } else + clear_inuse_bit_at_offset(nextchunk, 0); +@@ -4122,7 +4134,7 @@ static void malloc_consolidate(mstate av + prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long) prevsize)); +- unlink(p, bck, fwd); ++ unlink(av, p, bck, fwd); + } + + if (nextchunk != av->top) { +@@ -4130,7 +4142,7 @@ static void malloc_consolidate(mstate av + + if (!nextinuse) { + size += nextsize; +- unlink(nextchunk, bck, fwd); ++ unlink(av, nextchunk, bck, fwd); + } else + clear_inuse_bit_at_offset(nextchunk, 0); + +@@ -4199,7 +4211,9 @@ _int_realloc(mstate av, mchunkptr oldp, + { + errstr = "realloc(): invalid old size"; + errout: ++ mutex_unlock(&av->mutex); + malloc_printerr (check_action, errstr, chunk2mem(oldp)); ++ mutex_lock(&av->mutex); + return NULL; + } + +@@ -4241,7 +4255,7 @@ _int_realloc(mstate av, mchunkptr oldp, + (unsigned long)(newsize = oldsize + nextsize) >= + (unsigned long)(nb)) { + newp = oldp; +- unlink(next, bck, fwd); ++ unlink(av, next, bck, fwd); + } + + /* allocate, copy, free */ diff --git a/SOURCES/glibc-rh804768-bugfix.patch b/SOURCES/glibc-rh804768-bugfix.patch new file mode 100644 index 00000000..0cb77310 --- /dev/null +++ b/SOURCES/glibc-rh804768-bugfix.patch @@ -0,0 +1,656 @@ +#Contains the following patches from upstream: +# +#commit c3e94a953347ecf361ab400111dbb1a62505c7fe +#Author: Andreas Krebbel +#Date: Tue Mar 5 08:15:33 2013 +0100 +# +# S/390: Fix rt_sigprocmask syscall invocation in get/set/swapcontext. +# +#****commit e21d7aa71c0700b6611bd55881b862ac73c5cd5b +#Author: Andreas Krebbel +#Date: Thu Feb 21 09:47:55 2013 +0100 +# +# S/390: Fix _dl_runtime_profile for 32 bit. +# +#****commit f78b5caa6ece23ce86f6cabac8edf3ecd6850473 +#Author: Andreas Krebbel +#Date: Mon Feb 18 10:29:40 2013 +0100 +# +# S/390: Fix _dl_runtime_profile +# +# +#****commit bc101e2652728d8a6e8ece7c637e095618546a95 +#Author: Andreas Krebbel +#Date: Wed Jan 23 10:00:24 2013 +0100 +# +# S/390: Fix setjmp/longjmp FPR save/restore +# +#****commit 5c95f7b66be2e59cf26f3c29cfab7657880bd76d +#Author: Heiko Carstens +#Date: Tue Apr 23 08:53:44 2013 +0200 +# +# S/390: Change struct statfs[64] member types to unsigned values + +diff -Nru glibc-2.17-c758a686/sysdeps/s390/bits/setjmp.h glibc-2.17-c758a686/sysdeps/s390/bits/setjmp.h +--- glibc-2.17-c758a686/sysdeps/s390/bits/setjmp.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/s390/bits/setjmp.h 2013-08-23 12:33:20.597299428 -0400 +@@ -34,7 +34,7 @@ typedef struct __s390_jmp_buf + long int __gregs[10]; + + # if __WORDSIZE == 64 +- /* We save fpu registers 1, 3, 5 and 7. */ ++ /* We save fpu registers f8 - f15. */ + long __fpregs[8]; + # else + /* We save fpu registers 4 and 6. */ +diff -Nru glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-trampoline.S glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-trampoline.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/dl-trampoline.S 2013-08-23 12:33:20.593298453 -0400 +@@ -95,16 +95,16 @@ _dl_runtime_profile: + lr %r1,%r2 # function addr returned in r2 + icm %r0,15,20(%r12) # load & test framesize + jnm 2f ++ + lm %r2,%r6,32(%r12) + ld %f0,56(%r12) + ld %f2,64(%r12) +- basr %r14,%r1 # call resolved function +-1: lr %r15,%r12 # remove stack frame ++ lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + l %r14,16(%r15) # restore registers + l %r12,12(%r15) +- l %r6,8(%r15) +- br %r14 ++ br %r1 # tail-call to the resolved function ++ + cfi_def_cfa_register (12) + 2: jz 4f # framesize == 0 ? + ahi %r0,7 # align framesize to 8 +@@ -131,7 +131,13 @@ _dl_runtime_profile: + la %r4,32(%r12) # pointer to struct La_s390_32_regs + la %r5,72(%r12) # pointer to struct La_s390_32_retval + basr %r14,%r1 # call _dl_call_pltexit +- j 1b ++ ++ lr %r15,%r12 # remove stack frame ++ cfi_def_cfa_register (15) ++ l %r14,16(%r15) # restore registers ++ l %r12,12(%r15) ++ br %r14 ++ + 6: .long _dl_profile_fixup - 0b + 7: .long _dl_call_pltexit - 5b + cfi_endproc +diff -Nru glibc-2.17-c758a686/sysdeps/s390/s390-64/dl-trampoline.S glibc-2.17-c758a686/sysdeps/s390/s390-64/dl-trampoline.S +--- glibc-2.17-c758a686/sysdeps/s390/s390-64/dl-trampoline.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/dl-trampoline.S 2013-08-23 12:46:11.478239405 -0400 +@@ -1,4 +1,4 @@ +-/* PLT trampolines. s390 version. ++/* PLT trampolines. s390x version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + +@@ -20,8 +20,8 @@ + * with the following linkage: + * r2 - r6 : parameter registers + * f0, f2, f4, f6 : floating point parameter registers +- * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 +- * 96(r15) : additional stack parameters ++ * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 ++ * 160(r15) : additional stack parameters + * The normal clobber rules for function calls apply: + * r0 - r5 : call clobbered + * r6 - r13 : call saved +@@ -39,21 +39,21 @@ + cfi_startproc + .align 16 + _dl_runtime_resolve: +- stmg 2,5,64(15) # save registers +- stg 14,96(15) ++ stmg %r2,%r5,64(15) # save call-clobbered argument registers ++ stg %r14,96(15) + cfi_offset (r14, -64) +- lgr 0,15 # create stack frame +- aghi 15,-160 ++ lgr %r0,%r15 ++ aghi %r15,-160 # create stack frame + cfi_adjust_cfa_offset (160) +- stg 0,0(15) +- lmg 2,3,208(15) # load args saved by PLT +- brasl 14,_dl_fixup # call fixup +- lgr 1,2 # function addr returned in r2 +- aghi 15,160 # remove stack frame ++ stg %r0,0(%r15) # write backchain ++ lmg %r2,%r3,208(%r15)# load args saved by PLT ++ brasl %r14,_dl_fixup # call fixup ++ lgr %r1,%r2 # function addr returned in r2 ++ aghi %r15,160 # remove stack frame + cfi_adjust_cfa_offset (-160) +- lg 14,96(15) # restore registers +- lmg 2,5,64(15) +- br 1 ++ lg %r14,96(15) # restore registers ++ lmg %r2,%r5,64(15) ++ br %r1 + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + +@@ -64,13 +64,12 @@ _dl_runtime_resolve: + cfi_startproc + .align 16 + _dl_runtime_profile: +- stmg %r2,%r6,64(%r15) # save registers +- std %f0,104(%r15) +- std %f2,112(%r15) ++ stmg %r2,%r6,64(%r15) # save call-clobbered arg regs ++ std %f0,104(%r15) # + r6 needed as arg for ++ std %f2,112(%r15) # _dl_profile_fixup + std %f4,120(%r15) + std %f6,128(%r15) +- stg %r6,16(%r15) +- stg %r12,24(%r15) ++ stg %r12,24(%r15) # r12 is used as backup of r15 + stg %r14,32(%r15) + cfi_offset (r6, -96) + cfi_offset (f0, -56) +@@ -79,10 +78,10 @@ _dl_runtime_profile: + cfi_offset (f6, -32) + cfi_offset (r12, -136) + cfi_offset (r14, -128) +- lgr %r12,%r15 # create stack frame ++ lgr %r12,%r15 # backup stack pointer + cfi_def_cfa_register (12) +- aghi %r15,-160 +- stg %r12,0(%r15) ++ aghi %r15,-160 # create stack frame ++ stg %r12,0(%r15) # save backchain + lmg %r2,%r3,48(%r12) # load arguments saved by PLT + lgr %r4,%r14 # return address as third parameter + la %r5,64(%r12) # pointer to struct La_s390_32_regs +@@ -92,18 +91,19 @@ _dl_runtime_profile: + lg %r0,40(%r12) # load framesize + ltgr %r0,%r0 + jnm 1f +- lmg %r2,%r6,64(%r12) +- ld %f0,104(%r12) +- ld %f2,112(%r12) ++ ++ lmg %r2,%r6,64(%r12) # framesize < 0 means no pltexit call ++ ld %f0,104(%r12) # so we can do a tail call without ++ ld %f2,112(%r12) # copying the arg overflow area + ld %f4,120(%r12) + ld %f6,128(%r12) +- basr %r14,%r1 # call resolved function +-0: lgr %r15,%r12 # remove stack frame ++ ++ lgr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) +- lg %r6,16(%r15) +- br %r14 ++ br %r1 # tail-call to resolved function ++ + cfi_def_cfa_register (12) + 1: jz 4f # framesize == 0 ? + aghi %r0,7 # align framesize to 8 +@@ -118,7 +118,7 @@ _dl_runtime_profile: + la %r3,8(%r3) + brctg %r0,3b + 4: lmg %r2,%r6,64(%r12) # load register parameters +- ld %f0,104(%r12) ++ ld %f0,104(%r12) # restore call-clobbered arg regs + ld %f2,112(%r12) + ld %f4,120(%r12) + ld %f6,128(%r12) +@@ -129,7 +129,13 @@ _dl_runtime_profile: + la %r4,32(%r12) # pointer to struct La_s390_32_regs + la %r5,72(%r12) # pointer to struct La_s390_32_retval + brasl %r14,_dl_call_pltexit +- j 0b ++ ++ lgr %r15,%r12 # remove stack frame ++ cfi_def_cfa_register (15) ++ lg %r14,32(%r15) # restore registers ++ lg %r12,24(%r15) ++ br %r14 ++ + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile + #endif +diff -Nru glibc-2.17-c758a686/sysdeps/s390/s390-64/__longjmp.c glibc-2.17-c758a686/sysdeps/s390/s390-64/__longjmp.c +--- glibc-2.17-c758a686/sysdeps/s390/s390-64/__longjmp.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/__longjmp.c 2013-08-23 12:33:20.597299428 -0400 +@@ -42,10 +42,14 @@ __longjmp (__jmp_buf env, int val) + register void *r1 __asm ("%r1") = (void *) env; + #endif + /* Restore registers and jump back. */ +- asm volatile ("ld %%f7,104(%1)\n\t" +- "ld %%f5,96(%1)\n\t" +- "ld %%f3,88(%1)\n\t" +- "ld %%f1,80(%1)\n\t" ++ asm volatile ("ld %%f8,80(%1)\n\t" ++ "ld %%f9,88(%1)\n\t" ++ "ld %%f10,96(%1)\n\t" ++ "ld %%f11,104(%1)\n\t" ++ "ld %%f12,112(%1)\n\t" ++ "ld %%f13,120(%1)\n\t" ++ "ld %%f14,128(%1)\n\t" ++ "ld %%f15,136(%1)\n\t" + #ifdef PTR_DEMANGLE + "lmg %%r6,%%r13,0(%1)\n\t" + "lmg %%r4,%%r5,64(%1)\n\t" +diff -Nru glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S +--- glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/setjmp.S 2013-08-23 12:33:20.598300448 -0400 +@@ -55,10 +55,14 @@ ENTRY(__sigsetjmp) + #else + stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */ + #endif +- std %f1,80(%r2) +- std %f3,88(%r2) +- std %f5,96(%r2) +- std %f7,104(%r2) ++ std %f8,80(%r2) ++ std %f9,88(%r2) ++ std %f10,96(%r2) ++ std %f11,104(%r2) ++ std %f12,112(%r2) ++ std %f13,120(%r2) ++ std %f14,128(%r2) ++ std %f15,136(%r2) + #if defined NOT_IN_libc && defined IS_IN_rtld + /* In ld.so we never save the signal mask. */ + lghi %r2,0 +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/bits/statfs.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/bits/statfs.h +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/bits/statfs.h 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/bits/statfs.h 2013-08-23 12:33:20.601180842 -0400 +@@ -23,8 +23,8 @@ + + struct statfs + { +- int f_type; +- int f_bsize; ++ unsigned int f_type; ++ unsigned int f_bsize; + #ifndef __USE_FILE_OFFSET64 + __fsblkcnt_t f_blocks; + __fsblkcnt_t f_bfree; +@@ -39,27 +39,27 @@ struct statfs + __fsfilcnt64_t f_ffree; + #endif + __fsid_t f_fsid; +- int f_namelen; +- int f_frsize; +- int f_flags; +- int f_spare[4]; ++ unsigned int f_namelen; ++ unsigned int f_frsize; ++ unsigned int f_flags; ++ unsigned int f_spare[4]; + }; + + #ifdef __USE_LARGEFILE64 + struct statfs64 + { +- int f_type; +- int f_bsize; ++ unsigned int f_type; ++ unsigned int f_bsize; + __fsblkcnt64_t f_blocks; + __fsblkcnt64_t f_bfree; + __fsblkcnt64_t f_bavail; + __fsfilcnt64_t f_files; + __fsfilcnt64_t f_ffree; + __fsid_t f_fsid; +- int f_namelen; +- int f_frsize; +- int f_flags; +- int f_spare[4]; ++ unsigned int f_namelen; ++ unsigned int f_frsize; ++ unsigned int f_flags; ++ unsigned int f_spare[4]; + }; + #endif + +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S 2013-08-23 12:33:20.588297827 -0400 +@@ -31,41 +31,42 @@ + other than the PRESERVED state. */ + + ENTRY(__getcontext) +- lr %r5,%r2 ++ lr %r1,%r2 + + /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ + la %r2,SIG_BLOCK + slr %r3,%r3 +- la %r4,SC_MASK(%r5) ++ la %r4,SC_MASK(%r1) ++ lhi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Store fpu context. */ +- stfpc SC_FPC(%r5) +- std %f0,SC_FPRS(%r5) +- std %f1,SC_FPRS+8(%r5) +- std %f2,SC_FPRS+16(%r5) +- std %f3,SC_FPRS+24(%r5) +- std %f4,SC_FPRS+32(%r5) +- std %f5,SC_FPRS+40(%r5) +- std %f6,SC_FPRS+48(%r5) +- std %f7,SC_FPRS+56(%r5) +- std %f8,SC_FPRS+64(%r5) +- std %f9,SC_FPRS+72(%r5) +- std %f10,SC_FPRS+80(%r5) +- std %f11,SC_FPRS+88(%r5) +- std %f12,SC_FPRS+96(%r5) +- std %f13,SC_FPRS+104(%r5) +- std %f14,SC_FPRS+112(%r5) +- std %f15,SC_FPRS+120(%r5) ++ stfpc SC_FPC(%r1) ++ std %f0,SC_FPRS(%r1) ++ std %f1,SC_FPRS+8(%r1) ++ std %f2,SC_FPRS+16(%r1) ++ std %f3,SC_FPRS+24(%r1) ++ std %f4,SC_FPRS+32(%r1) ++ std %f5,SC_FPRS+40(%r1) ++ std %f6,SC_FPRS+48(%r1) ++ std %f7,SC_FPRS+56(%r1) ++ std %f8,SC_FPRS+64(%r1) ++ std %f9,SC_FPRS+72(%r1) ++ std %f10,SC_FPRS+80(%r1) ++ std %f11,SC_FPRS+88(%r1) ++ std %f12,SC_FPRS+96(%r1) ++ std %f13,SC_FPRS+104(%r1) ++ std %f14,SC_FPRS+112(%r1) ++ std %f15,SC_FPRS+120(%r1) + + /* Set __getcontext return value to 0. */ + slr %r2,%r2 + + /* Store access registers. */ +- stam %a0,%a15,SC_ACRS(%r5) ++ stam %a0,%a15,SC_ACRS(%r1) + + /* Store general purpose registers. */ +- stm %r0,%r15,SC_GPRS(%r5) ++ stm %r0,%r15,SC_GPRS(%r1) + + /* Return. */ + br %r14 +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S 2013-08-23 12:33:20.588297827 -0400 +@@ -31,38 +31,39 @@ + other than the PRESERVED state. */ + + ENTRY(__setcontext) +- lr %r5,%r2 ++ lr %r1,%r2 + + /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ + la %r2,SIG_BLOCK +- la %r3,SC_MASK(%r5) ++ la %r3,SC_MASK(%r1) + slr %r4,%r4 ++ lhi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Load fpu context. */ +- lfpc SC_FPC(%r5) +- ld %f0,SC_FPRS(%r5) +- ld %f1,SC_FPRS+8(%r5) +- ld %f2,SC_FPRS+16(%r5) +- ld %f3,SC_FPRS+24(%r5) +- ld %f4,SC_FPRS+32(%r5) +- ld %f5,SC_FPRS+40(%r5) +- ld %f6,SC_FPRS+48(%r5) +- ld %f7,SC_FPRS+56(%r5) +- ld %f8,SC_FPRS+64(%r5) +- ld %f9,SC_FPRS+72(%r5) +- ld %f10,SC_FPRS+80(%r5) +- ld %f11,SC_FPRS+88(%r5) +- ld %f12,SC_FPRS+96(%r5) +- ld %f13,SC_FPRS+104(%r5) +- ld %f14,SC_FPRS+112(%r5) +- ld %f15,SC_FPRS+120(%r5) ++ lfpc SC_FPC(%r1) ++ ld %f0,SC_FPRS(%r1) ++ ld %f1,SC_FPRS+8(%r1) ++ ld %f2,SC_FPRS+16(%r1) ++ ld %f3,SC_FPRS+24(%r1) ++ ld %f4,SC_FPRS+32(%r1) ++ ld %f5,SC_FPRS+40(%r1) ++ ld %f6,SC_FPRS+48(%r1) ++ ld %f7,SC_FPRS+56(%r1) ++ ld %f8,SC_FPRS+64(%r1) ++ ld %f9,SC_FPRS+72(%r1) ++ ld %f10,SC_FPRS+80(%r1) ++ ld %f11,SC_FPRS+88(%r1) ++ ld %f12,SC_FPRS+96(%r1) ++ ld %f13,SC_FPRS+104(%r1) ++ ld %f14,SC_FPRS+112(%r1) ++ ld %f15,SC_FPRS+120(%r1) + + /* Don't touch %a0, used for thread purposes. */ +- lam %a1,%a15,SC_ACRS+4(%r5) ++ lam %a1,%a15,SC_ACRS+4(%r1) + + /* Load general purpose registers. */ +- lm %r0,%r15,SC_GPRS(%r5) ++ lm %r0,%r15,SC_GPRS(%r1) + + /* Return. */ + br %r14 +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S 2013-08-23 12:33:20.589298155 -0400 +@@ -34,12 +34,13 @@ + + ENTRY(__swapcontext) + lr %r1,%r2 +- lr %r5,%r3 ++ lr %r0,%r3 + + /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ + la %r2,SIG_BLOCK + slr %r3,%r3 + la %r4,SC_MASK(%r1) ++ lhi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Store fpu context. */ +@@ -72,11 +73,14 @@ ENTRY(__swapcontext) + + /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ + la %r2,SIG_BLOCK ++ lr %r5,%r0 + la %r3,SC_MASK(%r5) + slr %r4,%r4 ++ lhi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Load fpu context. */ ++ lr %r5,%r0 + lfpc SC_FPC(%r5) + ld %f0,SC_FPRS(%r5) + ld %f1,SC_FPRS+8(%r5) +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S 2013-08-23 12:33:20.590298812 -0400 +@@ -31,41 +31,42 @@ + other than the PRESERVED state. */ + + ENTRY(__getcontext) +- lgr %r5,%r2 ++ lgr %r1,%r2 + + /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ + la %r2,SIG_BLOCK + slgr %r3,%r3 +- la %r4,SC_MASK(%r5) ++ la %r4,SC_MASK(%r1) ++ lghi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Store fpu context. */ +- stfpc SC_FPC(%r5) +- std %f0,SC_FPRS(%r5) +- std %f1,SC_FPRS+8(%r5) +- std %f2,SC_FPRS+16(%r5) +- std %f3,SC_FPRS+24(%r5) +- std %f4,SC_FPRS+32(%r5) +- std %f5,SC_FPRS+40(%r5) +- std %f6,SC_FPRS+48(%r5) +- std %f7,SC_FPRS+56(%r5) +- std %f8,SC_FPRS+64(%r5) +- std %f9,SC_FPRS+72(%r5) +- std %f10,SC_FPRS+80(%r5) +- std %f11,SC_FPRS+88(%r5) +- std %f12,SC_FPRS+96(%r5) +- std %f13,SC_FPRS+104(%r5) +- std %f14,SC_FPRS+112(%r5) +- std %f15,SC_FPRS+120(%r5) ++ stfpc SC_FPC(%r1) ++ std %f0,SC_FPRS(%r1) ++ std %f1,SC_FPRS+8(%r1) ++ std %f2,SC_FPRS+16(%r1) ++ std %f3,SC_FPRS+24(%r1) ++ std %f4,SC_FPRS+32(%r1) ++ std %f5,SC_FPRS+40(%r1) ++ std %f6,SC_FPRS+48(%r1) ++ std %f7,SC_FPRS+56(%r1) ++ std %f8,SC_FPRS+64(%r1) ++ std %f9,SC_FPRS+72(%r1) ++ std %f10,SC_FPRS+80(%r1) ++ std %f11,SC_FPRS+88(%r1) ++ std %f12,SC_FPRS+96(%r1) ++ std %f13,SC_FPRS+104(%r1) ++ std %f14,SC_FPRS+112(%r1) ++ std %f15,SC_FPRS+120(%r1) + + /* Set __getcontext return value to 0. */ + slgr %r2,%r2 + + /* Store access registers. */ +- stam %a0,%a15,SC_ACRS(%r5) ++ stam %a0,%a15,SC_ACRS(%r1) + + /* Store general purpose registers. */ +- stmg %r0,%r15,SC_GPRS(%r5) ++ stmg %r0,%r15,SC_GPRS(%r1) + + /* Return. */ + br %r14 +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/setcontext.S 2013-08-23 12:33:20.591298098 -0400 +@@ -31,38 +31,39 @@ + other than the PRESERVED state. */ + + ENTRY(__setcontext) +- lgr %r5,%r2 ++ lgr %r1,%r2 + + /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ + la %r2,SIG_BLOCK +- la %r3,SC_MASK(%r5) ++ la %r3,SC_MASK(%r1) + slgr %r4,%r4 ++ lghi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Load fpu context. */ +- lfpc SC_FPC(%r5) +- ld %f0,SC_FPRS(%r5) +- ld %f1,SC_FPRS+8(%r5) +- ld %f2,SC_FPRS+16(%r5) +- ld %f3,SC_FPRS+24(%r5) +- ld %f4,SC_FPRS+32(%r5) +- ld %f5,SC_FPRS+40(%r5) +- ld %f6,SC_FPRS+48(%r5) +- ld %f7,SC_FPRS+56(%r5) +- ld %f8,SC_FPRS+64(%r5) +- ld %f9,SC_FPRS+72(%r5) +- ld %f10,SC_FPRS+80(%r5) +- ld %f11,SC_FPRS+88(%r5) +- ld %f12,SC_FPRS+96(%r5) +- ld %f13,SC_FPRS+104(%r5) +- ld %f14,SC_FPRS+112(%r5) +- ld %f15,SC_FPRS+120(%r5) ++ lfpc SC_FPC(%r1) ++ ld %f0,SC_FPRS(%r1) ++ ld %f1,SC_FPRS+8(%r1) ++ ld %f2,SC_FPRS+16(%r1) ++ ld %f3,SC_FPRS+24(%r1) ++ ld %f4,SC_FPRS+32(%r1) ++ ld %f5,SC_FPRS+40(%r1) ++ ld %f6,SC_FPRS+48(%r1) ++ ld %f7,SC_FPRS+56(%r1) ++ ld %f8,SC_FPRS+64(%r1) ++ ld %f9,SC_FPRS+72(%r1) ++ ld %f10,SC_FPRS+80(%r1) ++ ld %f11,SC_FPRS+88(%r1) ++ ld %f12,SC_FPRS+96(%r1) ++ ld %f13,SC_FPRS+104(%r1) ++ ld %f14,SC_FPRS+112(%r1) ++ ld %f15,SC_FPRS+120(%r1) + + /* Don't touch %a0 and %a1, used for thread purposes. */ +- lam %a2,%a15,SC_ACRS+8(%r5) ++ lam %a2,%a15,SC_ACRS+8(%r1) + + /* Load general purpose registers. */ +- lmg %r0,%r15,SC_GPRS(%r5) ++ lmg %r0,%r15,SC_GPRS(%r1) + + /* Return. */ + br %r14 +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S 2013-08-23 12:33:20.591298098 -0400 +@@ -34,12 +34,13 @@ + + ENTRY(__swapcontext) + lgr %r1,%r2 +- lgr %r5,%r3 ++ lgr %r0,%r3 + + /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */ + la %r2,SIG_BLOCK + slgr %r3,%r3 + la %r4,SC_MASK(%r1) ++ lghi %r5,_NSIG8 + svc SYS_ify(rt_sigprocmask) + + /* Store fpu context. */ +@@ -72,11 +73,14 @@ ENTRY(__swapcontext) + + /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */ + la %r2,SIG_BLOCK ++ lgr %r5,%r0 + la %r3,SC_MASK(%r5) ++ lghi %r5,_NSIG8 + slgr %r4,%r4 + svc SYS_ify(rt_sigprocmask) + + /* Load fpu context. */ ++ lgr %r5,%r0 + lfpc SC_FPC(%r5) + ld %f0,SC_FPRS(%r5) + ld %f1,SC_FPRS+8(%r5) +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/ucontext_i.sym glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/ucontext_i.sym +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/ucontext_i.sym 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/s390/ucontext_i.sym 2013-08-23 12:33:20.591298098 -0400 +@@ -8,6 +8,8 @@ SIG_BLOCK + SIG_UNBLOCK + SIG_SETMASK + ++_NSIG8 (_NSIG / 8) ++ + #define ucontext(member) offsetof (ucontext_t, member) + #define mcontext(member) ucontext (uc_mcontext.member) diff --git a/SOURCES/glibc-rh819430.patch b/SOURCES/glibc-rh819430.patch new file mode 100644 index 00000000..0382f094 --- /dev/null +++ b/SOURCES/glibc-rh819430.patch @@ -0,0 +1,77 @@ +diff -Nru glibc-2.17-c758a686/posix/fnmatch.c glibc-2.17-c758a686/posix/fnmatch.c +--- glibc-2.17-c758a686/posix/fnmatch.c 2012-01-01 07:16:32.000000000 -0500 ++++ glibc-2.17-c758a686/posix/fnmatch.c 2012-05-23 14:14:29.099461189 -0400 +@@ -333,6 +333,7 @@ fnmatch (pattern, string, flags) + # if HANDLE_MULTIBYTE + if (__builtin_expect (MB_CUR_MAX, 1) != 1) + { ++ const char *orig_pattern = pattern; + mbstate_t ps; + size_t n; + const char *p; +@@ -356,10 +357,8 @@ fnmatch (pattern, string, flags) + alloca_used); + n = mbsrtowcs (wpattern, &p, n + 1, &ps); + if (__builtin_expect (n == (size_t) -1, 0)) +- /* Something wrong. +- XXX Do we have to set `errno' to something which mbsrtows hasn't +- already done? */ +- return -1; ++ /* Something wrong: Fall back to single byte matching. */ ++ goto try_singlebyte; + if (p) + { + memset (&ps, '\0', sizeof (ps)); +@@ -371,10 +370,8 @@ fnmatch (pattern, string, flags) + prepare_wpattern: + n = mbsrtowcs (NULL, &pattern, 0, &ps); + if (__builtin_expect (n == (size_t) -1, 0)) +- /* Something wrong. +- XXX Do we have to set `errno' to something which mbsrtows hasn't +- already done? */ +- return -1; ++ /*Something wrong: Fall back to single byte matching. */ ++ goto try_singlebyte; + if (__builtin_expect (n >= (size_t) -1 / sizeof (wchar_t), 0)) + { + __set_errno (ENOMEM); +@@ -401,14 +398,8 @@ fnmatch (pattern, string, flags) + alloca_used); + n = mbsrtowcs (wstring, &p, n + 1, &ps); + if (__builtin_expect (n == (size_t) -1, 0)) +- { +- /* Something wrong. +- XXX Do we have to set `errno' to something which +- mbsrtows hasn't already done? */ +- free_return: +- free (wpattern_malloc); +- return -1; +- } ++ /* Something wrong: Fall back to single byte matching. */ ++ goto free_and_try_singlebyte; + if (p) + { + memset (&ps, '\0', sizeof (ps)); +@@ -420,10 +411,8 @@ fnmatch (pattern, string, flags) + prepare_wstring: + n = mbsrtowcs (NULL, &string, 0, &ps); + if (__builtin_expect (n == (size_t) -1, 0)) +- /* Something wrong. +- XXX Do we have to set `errno' to something which mbsrtows hasn't +- already done? */ +- goto free_return; ++ /* Something wrong: Fall back to singlebyte matching. */ ++ goto free_and_try_singlebyte; + if (__builtin_expect (n >= (size_t) -1 / sizeof (wchar_t), 0)) + { + free (wpattern_malloc); +@@ -450,6 +439,10 @@ fnmatch (pattern, string, flags) + free (wpattern_malloc); + + return res; ++ free_and_try_singlebyte: ++ free(wpattern_malloc); ++ try_singlebyte: ++ pattern = orig_pattern; + } + # endif /* mbstate_t and mbsrtowcs or _LIBC. */ diff --git a/SOURCES/glibc-rh825061.patch b/SOURCES/glibc-rh825061.patch new file mode 100644 index 00000000..f7aa4cf2 --- /dev/null +++ b/SOURCES/glibc-rh825061.patch @@ -0,0 +1,13 @@ +diff -rup glibc-2.17-c758a686/manual/Makefile glibc-2.17-c758a686/manual/Makefile +--- glibc-2.17-c758a686/manual/Makefile 2012-05-20 19:47:38.000000000 -0600 ++++ glibc-2.17-c758a686/manual/Makefile 2012-05-29 22:23:33.920428631 -0600 +@@ -129,7 +129,8 @@ $(objpfx)%.c.texi: examples/%.c + mv -f $@.new $@ + + $(objpfx)%.info: %.texinfo +- LANGUAGE=C LC_ALL=C $(MAKEINFO) -P $(objpfx) --output=$@ $< ++ LANGUAGE=C LC_ALL=C $(MAKEINFO) -P $(objpfx) --output=`basename $@` $< ++ mv `basename $@`* $(objpfx) + + $(objpfx)%.dvi: %.texinfo + cd $(objpfx);$(TEXI2DVI) -I $(shell cd $( + + + * locale/loadlocale.c (_nl_load_locale): Delay setting + file->decided until we have successfully loaded the file's + data. + +diff --git glibc-2.17-c758a686/locale/loadlocale.c glibc-2.17-c758a686/locale/loadlocale.c +index e3fa187..9fd9216 100644 +--- glibc-2.17-c758a686/locale/loadlocale.c ++++ glibc-2.17-c758a686/locale/loadlocale.c +@@ -169,7 +169,6 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) + int save_err; + int alloc = ld_mapped; + +- file->decided = 1; + file->data = NULL; + + fd = open_not_cancel_2 (file->filename, O_RDONLY | O_CLOEXEC); +@@ -278,6 +277,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) + newdata->alloc = alloc; + + file->data = newdata; ++ file->decided = 1; + } + + void diff --git a/SOURCES/glibc-rh841318.patch b/SOURCES/glibc-rh841318.patch new file mode 100644 index 00000000..48797d86 --- /dev/null +++ b/SOURCES/glibc-rh841318.patch @@ -0,0 +1,45241 @@ +Corresponds to: + +commit a5357b7ce2a2982c5778435704bcdb55ce3667a0 +Author: Jeff Law +Date: Mon Dec 15 10:09:32 2014 +0100 + + CVE-2012-3406: Stack overflow in vfprintf [BZ #16617] + + A larger number of format specifiers coudld cause a stack overflow, + potentially allowing to bypass _FORTIFY_SOURCE format string + protection. + +diff -Nru glibc-2.17-c758a686/stdio-common/Makefile glibc-2.17-c758a686/stdio-common/Makefile +--- glibc-2.17-c758a686/stdio-common/Makefile 2012-09-14 14:31:29.000000000 -0600 ++++ glibc-2.17-c758a686/stdio-common/Makefile 2012-09-14 14:41:50.837749196 -0600 +@@ -57,7 +57,7 @@ tests := tstscanf test_rdwr test-popen t + bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \ + scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \ + bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \ +- bug25 tst-printf-round ++ bug25 tst-printf-round bug23-2 bug23-3 + + test-srcs = tst-unbputc tst-printf + +diff -Nru glibc-2.17-c758a686/stdio-common/bug23-2.c glibc-2.17-c758a686/stdio-common/bug23-2.c +--- glibc-2.17-c758a686/stdio-common/bug23-2.c 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/stdio-common/bug23-2.c 2012-09-14 14:41:27.832840375 -0600 +@@ -0,0 +1,70 @@ ++#include ++#include ++#include ++ ++static const char expected[] = "\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; ++ ++static int ++do_test (void) ++{ ++ char *buf = malloc (strlen (expected) + 1); ++ snprintf (buf, strlen (expected) + 1, ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", ++ "a", "b", "c", "d", 5); ++ return strcmp (buf, expected) != 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -Nru glibc-2.17-c758a686/stdio-common/bug23-3.c glibc-2.17-c758a686/stdio-common/bug23-3.c +--- glibc-2.17-c758a686/stdio-common/bug23-3.c 1969-12-31 17:00:00.000000000 -0700 ++++ glibc-2.17-c758a686/stdio-common/bug23-3.c 2012-09-14 14:41:27.884840169 -0600 +@@ -0,0 +1,45076 @@ ++#include ++#include ++#include ++ ++static const char expected[] = "\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55\ ++\n\ ++a\n\ ++abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; ++ ++ ++ ++int ++do_test (void) ++{ ++ char *buf = malloc (strlen (expected) + 1); ++ snprintf (buf, strlen (expected) + 1, ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" ++ "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", ++ "a", "b", "c", "d", 5); ++ return (strcmp (buf, expected) != 0); ++} ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ +diff -Nru glibc-2.17-c758a686/stdio-common/vfprintf.c glibc-2.17-c758a686/stdio-common/vfprintf.c +--- glibc-2.17-c758a686/stdio-common/vfprintf.c 2012-09-14 14:31:29.000000000 -0600 ++++ glibc-2.17-c758a686/stdio-common/vfprintf.c 2012-09-14 14:41:27.891840141 -0600 +@@ -243,6 +243,12 @@ vfprintf (FILE *s, const CHAR_T *format, + /* For the argument descriptions, which may be allocated on the heap. */ + void *args_malloced = NULL; + ++ /* For positional argument handling. */ ++ struct printf_spec *specs; ++ ++ /* Track if we malloced the SPECS array and thus must free it. */ ++ bool specs_malloced = false; ++ + /* This table maps a character into a number representing a + class. In each step there is a destination label for each + class. */ +@@ -1685,8 +1691,8 @@ do_positional: + size_t nspecs = 0; + /* A more or less arbitrary start value. */ + size_t nspecs_size = 32 * sizeof (struct printf_spec); +- struct printf_spec *specs = alloca (nspecs_size); + ++ specs = alloca (nspecs_size); + /* The number of arguments the format string requests. This will + determine the size of the array needed to store the argument + attributes. */ +@@ -1727,10 +1733,25 @@ do_positional: + { + /* Extend the array of format specifiers. */ + struct printf_spec *old = specs; +- specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size); +- ++ if (__libc_use_alloca (2 * nspecs_size)) ++ specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size); ++ else ++ { ++ nspecs_size *= 2; ++ specs = malloc (nspecs_size); ++ } ++ + /* Copy the old array's elements to the new space. */ + memmove (specs, old, nspecs * sizeof (*specs)); ++ ++ /* If we had previously malloc'd space for SPECS, then ++ release it after the copy is complete. */ ++ if (specs_malloced) ++ free (old); ++ ++ /* Now set SPECS_MALLOCED if needed. */ ++ if (!__libc_use_alloca (nspecs_size)) ++ specs_malloced = true; + } + + /* Parse the format specifier. */ +@@ -2045,6 +2066,8 @@ do_positional: + } + + all_done: ++ if (specs_malloced) ++ free (specs); + free (args_malloced); + free (workstart); + /* Unlock the stream. */ diff --git a/SOURCES/glibc-rh841653-0.patch b/SOURCES/glibc-rh841653-0.patch new file mode 100644 index 00000000..9add04f8 --- /dev/null +++ b/SOURCES/glibc-rh841653-0.patch @@ -0,0 +1,761 @@ +In RHEL7 we already have the newer cpu-feature support so we need +to backport b376899d2 to get 1cdbe5794 to compile. The goal wtih elision +is an incremental set of patches each which compile and introduce the +required functionality for elision. + +Partial backport of: + +commit b376899d27e5ac892f0339cf1bbb3d2158347db8 +Author: H.J. Lu +Date: Thu Aug 13 03:40:40 2015 -0700 + + Update x86 elision-conf.c for + + This patch updates x86 elision-conf.c to use the newly defined + HAS_CPU_FEATURE from . + + * sysdeps/unix/sysv/linux/x86/elision-conf.c (elision_init): + Replace HAS_RTM with HAS_CPU_FEATURE (RTM). + + +Full backport of: + +commit 1717da59aed9612becd56aaa1249aac695af4c8a +Author: Andi Kleen +Date: Thu May 16 19:17:14 2013 -0700 + + Add a configure option to enable lock elision and disable by default + + Can be enabled with --enable-lock-elision=yes at configure time. + +commit 1cdbe579482c07e9f4bb3baa4864da2d3e7eb837 +Author: Andi Kleen +Date: Sat Nov 10 00:51:26 2012 -0800 + + Add the low level infrastructure for pthreads lock elision with TSX + + Lock elision using TSX is a technique to optimize lock scaling + It allows to run locks in parallel using hardware support for + a transactional execution mode in 4th generation Intel Core CPUs. + See http://www.intel.com/software/tsx for more Information. + + This patch implements a simple adaptive lock elision algorithm based + on RTM. It enables elision for the pthread mutexes and rwlocks. + The algorithm keeps track whether a mutex successfully elides or not, + and stops eliding for some time when it is not. + + When the CPU supports RTM the elision path is automatically tried, + otherwise any elision is disabled. + + The adaptation algorithm and its tuning is currently preliminary. + + The code adds some checks to the lock fast paths. Micro-benchmarks + show little to no difference without RTM. + + This patch implements the low level "lll_" code for lock elision. + Followon patches hook this into the pthread implementation + + Changes with the RTM mutexes: + ----------------------------- + Lock elision in pthreads is generally compatible with existing programs. + There are some obscure exceptions, which are expected to be uncommon. + See the manual for more details. + + - A broken program that unlocks a free lock will crash. + There are ways around this with some tradeoffs (more code in hot paths) + I'm still undecided on what approach to take here; have to wait for testing reports. + - pthread_mutex_destroy of a lock mutex will not return EBUSY but 0. + - There's also a similar situation with trylock outside the mutex, + "knowing" that the mutex must be held due to some other condition. + In this case an assert failure cannot be recovered. This situation is + usually an existing bug in the program. + - Same applies to the rwlocks. Some of the return values changes + (for example there is no EDEADLK for an elided lock, unless it aborts. + However when elided it will also never deadlock of course) + - Timing changes, so broken programs that make assumptions about specific timing + may expose already existing latent problems. Note that these broken programs will + break in other situations too (loaded system, new faster hardware, compiler + optimizations etc.) + - Programs with non recursive mutexes that take them recursively in a thread and + which would always deadlock without elision may not always see a deadlock. + The deadlock will only happen on an early or delayed abort (which typically + happens at some point) + This only happens for mutexes not explicitely set to PTHREAD_MUTEX_NORMAL + or PTHREAD_MUTEX_ADAPTIVE_NP. PTHREAD_MUTEX_NORMAL mutexes do not elide. + + The elision default can be set at configure time. + + This patch implements the basic infrastructure for elision. +Index: glibc-2.17-c758a686/nptl/elision-conf.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/elision-conf.h +@@ -0,0 +1 @@ ++/* empty */ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +@@ -430,6 +430,12 @@ LLL_STUB_UNWIND_INFO_END + : "memory"); \ + result; }) + ++extern int __lll_timedlock_elision (int *futex, short *adapt_count, ++ const struct timespec *timeout, ++ int private) attribute_hidden; ++ ++#define lll_timedlock_elision(futex, adapt_count, timeout, private) \ ++ __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private) + + #define lll_robust_timedlock(futex, timeout, id, private) \ + ({ int result, ignore1, ignore2, ignore3; \ +@@ -583,6 +589,22 @@ extern int __lll_timedwait_tid (int *tid + } \ + __result; }) + ++extern int __lll_lock_elision (int *futex, short *adapt_count, int private) ++ attribute_hidden; ++ ++extern int __lll_unlock_elision(int *lock, int private) ++ attribute_hidden; ++ ++extern int __lll_trylock_elision(int *lock, short *adapt_count) ++ attribute_hidden; ++ ++#define lll_lock_elision(futex, adapt_count, private) \ ++ __lll_lock_elision (&(futex), &(adapt_count), private) ++#define lll_unlock_elision(futex, private) \ ++ __lll_unlock_elision (&(futex), private) ++#define lll_trylock_elision(futex, adapt_count) \ ++ __lll_trylock_elision(&(futex), &(adapt_count)) ++ + #endif /* !__ASSEMBLER__ */ + + #endif /* lowlevellock.h */ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/Makefile +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/Makefile +@@ -0,0 +1,2 @@ ++libpthread-sysdep_routines += elision-lock elision-unlock elision-timed \ ++ elision-trylock +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +@@ -0,0 +1,90 @@ ++/* elision-conf.c: Lock elision tunable parameters. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "config.h" ++#include ++#include ++#include ++#include ++ ++/* Reasonable initial tuning values, may be revised in the future. ++ This is a conservative initial value. */ ++ ++struct elision_config __elision_aconf = ++ { ++ /* How often to not attempt to use elision if a transaction aborted ++ because the lock is already acquired. Expressed in number of lock ++ acquisition attempts. */ ++ .skip_lock_busy = 3, ++ /* How often to not attempt to use elision if a transaction aborted due ++ to reasons other than other threads' memory accesses. Expressed in ++ number of lock acquisition attempts. */ ++ .skip_lock_internal_abort = 3, ++ /* How often we retry using elision if there is chance for the transaction ++ to finish execution (e.g., it wasn't aborted due to the lock being ++ already acquired. */ ++ .retry_try_xbegin = 3, ++ /* Same as SKIP_LOCK_INTERNAL_ABORT but for trylock. */ ++ .skip_trylock_internal_abort = 3, ++ }; ++ ++/* Elided rwlock toggle, set when elision is available and is ++ enabled for rwlocks. */ ++ ++int __rwlock_rtm_enabled attribute_hidden; ++ ++/* Retries for elided rwlocks on read. Conservative initial value. */ ++ ++int __rwlock_rtm_read_retries attribute_hidden = 3; ++ ++/* Set when the CPU supports elision. When false elision is never attempted. */ ++ ++int __elision_available attribute_hidden; ++ ++/* Force elision for all new locks. This is used to decide whether existing ++ DEFAULT locks should be automatically upgraded to elision in ++ pthread_mutex_lock(). Disabled for suid programs. Only used when elision ++ is available. */ ++ ++int __pthread_force_elision attribute_hidden; ++ ++/* Initialize elison. */ ++ ++static void ++elision_init (int argc __attribute__ ((unused)), ++ char **argv __attribute__ ((unused)), ++ char **environ) ++{ ++ __elision_available = HAS_CPU_FEATURE (RTM); ++#ifdef ENABLE_LOCK_ELISION ++ __pthread_force_elision = __libc_enable_secure ? 0 : __elision_available; ++ __rwlock_rtm_enabled = __libc_enable_secure ? 0 : __elision_available; ++#endif ++} ++ ++#ifdef SHARED ++# define INIT_SECTION ".init_array" ++#else ++# define INIT_SECTION ".preinit_array" ++#endif ++ ++void (*const __pthread_init_array []) (int, char **, char **) ++ __attribute__ ((section (INIT_SECTION), aligned (sizeof (void *)))) = ++{ ++ &elision_init ++}; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h +@@ -0,0 +1,44 @@ ++/* elision-conf.h: Lock elision tunable parameters. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#ifndef _ELISION_CONF_H ++#define _ELISION_CONF_H 1 ++ ++#include ++#include ++#include ++ ++/* Should make sure there is no false sharing on this. */ ++ ++struct elision_config ++{ ++ int skip_lock_busy; ++ int skip_lock_internal_abort; ++ int retry_try_xbegin; ++ int skip_trylock_internal_abort; ++}; ++ ++extern struct elision_config __elision_aconf attribute_hidden; ++ ++extern int __rwlock_rtm_enabled attribute_hidden; ++extern int __elision_available attribute_hidden; ++extern int __pthread_force_elision attribute_hidden; ++ ++/* Tell the test suite to test elision for this architecture. */ ++#define HAVE_ELISION 1 ++ ++#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c +@@ -0,0 +1,95 @@ ++/* elision-lock.c: Elided pthread mutex lock. ++ Copyright (C) 2011-2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include "pthreadP.h" ++#include "lowlevellock.h" ++#include "hle.h" ++#include ++ ++#if !defined(LLL_LOCK) && !defined(EXTRAARG) ++/* Make sure the configuration code is always linked in for static ++ libraries. */ ++#include "elision-conf.c" ++#endif ++ ++#ifndef EXTRAARG ++#define EXTRAARG ++#endif ++#ifndef LLL_LOCK ++#define LLL_LOCK(a,b) lll_lock(a,b), 0 ++#endif ++ ++#define aconf __elision_aconf ++ ++/* Adaptive lock using transactions. ++ By default the lock region is run as a transaction, and when it ++ aborts or the lock is busy the lock adapts itself. */ ++ ++int ++__lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) ++{ ++ if (*adapt_count <= 0) ++ { ++ unsigned status; ++ int try_xbegin; ++ ++ for (try_xbegin = aconf.retry_try_xbegin; ++ try_xbegin > 0; ++ try_xbegin--) ++ { ++ if ((status = _xbegin()) == _XBEGIN_STARTED) ++ { ++ if (*futex == 0) ++ return 0; ++ ++ /* Lock was busy. Fall back to normal locking. ++ Could also _xend here but xabort with 0xff code ++ is more visible in the profiler. */ ++ _xabort (_ABORT_LOCK_BUSY); ++ } ++ ++ if (!(status & _XABORT_RETRY)) ++ { ++ if ((status & _XABORT_EXPLICIT) ++ && _XABORT_CODE (status) == _ABORT_LOCK_BUSY) ++ { ++ /* Right now we skip here. Better would be to wait a bit ++ and retry. This likely needs some spinning. */ ++ if (*adapt_count != aconf.skip_lock_busy) ++ *adapt_count = aconf.skip_lock_busy; ++ } ++ /* Internal abort. There is no chance for retry. ++ Use the normal locking and next time use lock. ++ Be careful to avoid writing to the lock. */ ++ else if (*adapt_count != aconf.skip_lock_internal_abort) ++ *adapt_count = aconf.skip_lock_internal_abort; ++ break; ++ } ++ } ++ } ++ else ++ { ++ /* Use a normal lock until the threshold counter runs out. ++ Lost updates possible. */ ++ (*adapt_count)--; ++ } ++ ++ /* Use a normal lock here. */ ++ return LLL_LOCK ((*futex), private); ++} +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-timed.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-timed.c +@@ -0,0 +1,26 @@ ++/* elision-timed.c: Lock elision timed lock. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include "lowlevellock.h" ++#define __lll_lock_elision __lll_timedlock_elision ++#define EXTRAARG const struct timespec *t, ++#undef LLL_LOCK ++#define LLL_LOCK(a, b) lll_timedlock(a, t, b) ++#include "elision-lock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +@@ -0,0 +1,72 @@ ++/* elision-trylock.c: Lock eliding trylock for pthreads. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include "hle.h" ++#include ++ ++#define aconf __elision_aconf ++ ++/* Try to elide a futex trylock. FUTEX is the futex variable. TRY_LOCK is the ++ adaptation counter in the mutex. UPGRADED is != 0 when this is for an ++ automatically upgraded lock. */ ++ ++int ++__lll_trylock_elision (int *futex, short *adapt_count) ++{ ++ /* Implement POSIX semantics by forbiding nesting ++ trylock. Sorry. After the abort the code is re-executed ++ non transactional and if the lock was already locked ++ return an error. */ ++ _xabort (_ABORT_NESTED_TRYLOCK); ++ ++ /* Only try a transaction if it's worth it. */ ++ if (*adapt_count <= 0) ++ { ++ unsigned status; ++ ++ if ((status = _xbegin()) == _XBEGIN_STARTED) ++ { ++ if (*futex == 0) ++ return 0; ++ ++ /* Lock was busy. Fall back to normal locking. ++ Could also _xend here but xabort with 0xff code ++ is more visible in the profiler. */ ++ _xabort (_ABORT_LOCK_BUSY); ++ } ++ ++ if (!(status & _XABORT_RETRY)) ++ { ++ /* Internal abort. No chance for retry. For future ++ locks don't try speculation for some time. */ ++ if (*adapt_count != aconf.skip_trylock_internal_abort) ++ *adapt_count = aconf.skip_trylock_internal_abort; ++ } ++ /* Could do some retries here. */ ++ } ++ else ++ { ++ /* Lost updates are possible, but harmless. */ ++ (*adapt_count)--; ++ } ++ ++ return lll_trylock (*futex); ++} +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-unlock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-unlock.c +@@ -0,0 +1,33 @@ ++/* elision-unlock.c: Commit an elided pthread lock. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include "pthreadP.h" ++#include "lowlevellock.h" ++#include "hle.h" ++ ++int ++__lll_unlock_elision(int *lock, int private) ++{ ++ /* When the lock was free we're in a transaction. ++ When you crash here you unlocked a free lock. */ ++ if (*lock == 0) ++ _xend(); ++ else ++ lll_unlock ((*lock), private); ++ return 0; ++} +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/hle.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/hle.h +@@ -0,0 +1,75 @@ ++/* Shared RTM header. Emulate TSX intrinsics for compilers and assemblers ++ that do not support the intrinsics and instructions yet. */ ++#ifndef _HLE_H ++#define _HLE_H 1 ++ ++#ifdef __ASSEMBLER__ ++ ++.macro XBEGIN target ++ .byte 0xc7,0xf8 ++ .long \target-1f ++1: ++.endm ++ ++.macro XEND ++ .byte 0x0f,0x01,0xd5 ++.endm ++ ++.macro XABORT code ++ .byte 0xc6,0xf8,\code ++.endm ++ ++.macro XTEST ++ .byte 0x0f,0x01,0xd6 ++.endm ++ ++#endif ++ ++/* Official RTM intrinsics interface matching gcc/icc, but works ++ on older gcc compatible compilers and binutils. ++ We should somehow detect if the compiler supports it, because ++ it may be able to generate slightly better code. */ ++ ++#define _XBEGIN_STARTED (~0u) ++#define _XABORT_EXPLICIT (1 << 0) ++#define _XABORT_RETRY (1 << 1) ++#define _XABORT_CONFLICT (1 << 2) ++#define _XABORT_CAPACITY (1 << 3) ++#define _XABORT_DEBUG (1 << 4) ++#define _XABORT_NESTED (1 << 5) ++#define _XABORT_CODE(x) (((x) >> 24) & 0xff) ++ ++#define _ABORT_LOCK_BUSY 0xff ++#define _ABORT_LOCK_IS_LOCKED 0xfe ++#define _ABORT_NESTED_TRYLOCK 0xfd ++ ++#ifndef __ASSEMBLER__ ++ ++#define __force_inline __attribute__((__always_inline__)) inline ++ ++static __force_inline int _xbegin(void) ++{ ++ int ret = _XBEGIN_STARTED; ++ asm volatile (".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory"); ++ return ret; ++} ++ ++static __force_inline void _xend(void) ++{ ++ asm volatile (".byte 0x0f,0x01,0xd5" ::: "memory"); ++} ++ ++static __force_inline void _xabort(const unsigned int status) ++{ ++ asm volatile (".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory"); ++} ++ ++static __force_inline int _xtest(void) ++{ ++ unsigned char out; ++ asm volatile (".byte 0x0f,0x01,0xd6 ; setnz %0" : "=r" (out) :: "memory"); ++ return out; ++} ++ ++#endif ++#endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +@@ -427,6 +427,13 @@ LLL_STUB_UNWIND_INFO_END + : "memory", "cx", "cc", "r10", "r11"); \ + result; }) + ++extern int __lll_timedlock_elision (int *futex, short *adapt_count, ++ const struct timespec *timeout, ++ int private) attribute_hidden; ++ ++#define lll_timedlock_elision(futex, adapt_count, timeout, private) \ ++ __lll_timedlock_elision(&(futex), &(adapt_count), timeout, private) ++ + #define lll_robust_timedlock(futex, timeout, id, private) \ + ({ int result, ignore1, ignore2, ignore3; \ + __asm __volatile (LOCK_INSTR "cmpxchgl %1, %4\n\t" \ +@@ -597,6 +604,22 @@ extern int __lll_timedwait_tid (int *tid + } \ + __result; }) + ++extern int __lll_lock_elision (int *futex, short *adapt_count, int private) ++ attribute_hidden; ++ ++extern int __lll_unlock_elision (int *lock, int private) ++ attribute_hidden; ++ ++extern int __lll_trylock_elision (int *lock, short *adapt_count) ++ attribute_hidden; ++ ++#define lll_lock_elision(futex, adapt_count, private) \ ++ __lll_lock_elision (&(futex), &(adapt_count), private) ++#define lll_unlock_elision(futex, private) \ ++ __lll_unlock_elision (&(futex), private) ++#define lll_trylock_elision(futex, adapt_count) \ ++ __lll_trylock_elision (&(futex), &(adapt_count)) ++ + #endif /* !__ASSEMBLER__ */ + + #endif /* lowlevellock.h */ +Index: glibc-2.17-c758a686/sysdeps/i386/i686/multiarch/init-arch.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/i386/i686/multiarch/init-arch.c ++++ /dev/null +@@ -1 +0,0 @@ +-#include +Index: glibc-2.17-c758a686/INSTALL +=================================================================== +--- glibc-2.17-c758a686.orig/INSTALL ++++ glibc-2.17-c758a686/INSTALL +@@ -140,6 +140,9 @@ will be used, and CFLAGS sets optimizati + additional security risks to the system and you should enable it + only if you understand and accept those risks. + ++`--enable-lock-elision=yes' ++ Enable lock elision for pthread mutexes and rwlocks by default. ++ + `--build=BUILD-SYSTEM' + `--host=HOST-SYSTEM' + These options are for cross-compiling. If you specify both +Index: glibc-2.17-c758a686/config.h.in +=================================================================== +--- glibc-2.17-c758a686.orig/config.h.in ++++ glibc-2.17-c758a686/config.h.in +@@ -180,6 +180,9 @@ + /* Define if __stack_chk_guard canary should be randomized at program startup. */ + #undef ENABLE_STACKGUARD_RANDOMIZE + ++/* Define if lock elision should be enabled by default. */ ++#undef ENABLE_LOCK_ELISION ++ + /* Package description. */ + #undef PKGVERSION + +Index: glibc-2.17-c758a686/configure +=================================================================== +--- glibc-2.17-c758a686.orig/configure ++++ glibc-2.17-c758a686/configure +@@ -750,6 +750,7 @@ enable_profile + enable_versioning + enable_oldest_abi + enable_stackguard_randomization ++enable_lock_elision + enable_add_ons + enable_hidden_plt + enable_bind_now +@@ -1405,6 +1406,9 @@ Optional Features: + --enable-stackguard-randomization + initialize __stack_chk_guard canary with a random + number at program start ++ --enable-lock-elision=yes/no ++ Enable lock elision for pthread mutexes and rwlocks ++ by default + --enable-add-ons[=DIRS...] + configure and build add-ons in DIR1,DIR2,... search + for add-ons if no parameter given +@@ -3716,6 +3720,18 @@ if test "$enable_stackguard_randomize" = + + fi + ++# Check whether --enable-lock-elision was given. ++if test "${enable_lock_elision+set}" = set; then : ++ enableval=$enable_lock_elision; enable_lock_elision=$enableval ++else ++ enable_lock_elision=no ++fi ++ ++if test "$enable_lock_elision" = yes ; then ++ $as_echo "#define ENABLE_LOCK_ELISION 1" >>confdefs.h ++ ++fi ++ + # Check whether --enable-add-ons was given. + if test "${enable_add_ons+set}" = set; then : + enableval=$enable_add_ons; +Index: glibc-2.17-c758a686/configure.in +=================================================================== +--- glibc-2.17-c758a686.orig/configure.in ++++ glibc-2.17-c758a686/configure.in +@@ -155,6 +155,15 @@ if test "$enable_stackguard_randomize" = + AC_DEFINE(ENABLE_STACKGUARD_RANDOMIZE) + fi + ++AC_ARG_ENABLE([lock-elision], ++ AC_HELP_STRING([--enable-lock-elision[=yes/no]], ++ [Enable lock elision for pthread mutexes and rwlocks by default]), ++ [enable_lock_elision=$enableval], ++ [enable_lock_elision=no]) ++if test "$enable_lock_elision" = yes ; then ++ AC_DEFINE(ENABLE_LOCK_ELISION) ++fi ++ + dnl Generic infrastructure for drop-in additions to libc. + AC_ARG_ENABLE([add-ons], + AC_HELP_STRING([--enable-add-ons@<:@=DIRS...@:>@], +Index: glibc-2.17-c758a686/manual/install.texi +=================================================================== +--- glibc-2.17-c758a686.orig/manual/install.texi ++++ glibc-2.17-c758a686/manual/install.texi +@@ -174,6 +174,9 @@ setuid and owned by @code{root}. The us + additional security risks to the system and you should enable it only if + you understand and accept those risks. + ++@item --enable-lock-elision=yes ++Enable lock elision for pthread mutexes by default. ++ + @item --build=@var{build-system} + @itemx --host=@var{host-system} + These options are for cross-compiling. If you specify both options and diff --git a/SOURCES/glibc-rh841653-1.patch b/SOURCES/glibc-rh841653-1.patch new file mode 100644 index 00000000..9526fbfe --- /dev/null +++ b/SOURCES/glibc-rh841653-1.patch @@ -0,0 +1,102 @@ +commit b023e4ca99f5e81f90d87d23cd267ef2abd2388c +Author: Andi Kleen +Date: Sat Dec 22 00:58:34 2012 -0800 + + Add new internal mutex type flags for elision. + + Add Enable/disable flags used internally + + Extend the mutex initializers to have the fields needed for + elision. The layout stays the same, and this is not visible + to programs. + + These changes are not exposed outside pthread +Index: glibc-2.17-c758a686/nptl/pthreadP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthreadP.h ++++ glibc-2.17-c758a686/nptl/pthreadP.h +@@ -61,6 +61,10 @@ + enum + { + PTHREAD_MUTEX_KIND_MASK_NP = 3, ++ ++ PTHREAD_MUTEX_ELISION_NP = 256, ++ PTHREAD_MUTEX_NO_ELISION_NP = 512, ++ + PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16, + PTHREAD_MUTEX_ROBUST_RECURSIVE_NP + = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP, +@@ -93,12 +97,21 @@ enum + PTHREAD_MUTEX_PP_ERRORCHECK_NP + = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_PP_ADAPTIVE_NP +- = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP ++ = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP, ++ PTHREAD_MUTEX_ELISION_FLAGS_NP ++ = PTHREAD_MUTEX_ELISION_NP | PTHREAD_MUTEX_NO_ELISION_NP, ++ ++ PTHREAD_MUTEX_TIMED_ELISION_NP = ++ PTHREAD_MUTEX_TIMED_NP | PTHREAD_MUTEX_ELISION_NP, ++ PTHREAD_MUTEX_TIMED_NO_ELISION_NP = ++ PTHREAD_MUTEX_TIMED_NP | PTHREAD_MUTEX_NO_ELISION_NP, + }; + #define PTHREAD_MUTEX_PSHARED_BIT 128 + + #define PTHREAD_MUTEX_TYPE(m) \ + ((m)->__data.__kind & 127) ++#define PTHREAD_MUTEX_TYPE_ELISION(m) \ ++ ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_FLAGS_NP)) + + #if LLL_PRIVATE == 0 && LLL_SHARED == 128 + # define PTHREAD_MUTEX_PSHARED(m) \ +Index: glibc-2.17-c758a686/nptl/sysdeps/pthread/pthread.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/pthread/pthread.h ++++ glibc-2.17-c758a686/nptl/sysdeps/pthread/pthread.h +@@ -83,27 +83,39 @@ enum + + + /* Mutex initializers. */ ++#if __PTHREAD_MUTEX_HAVE_ELISION == 1 /* 64bit layout. */ ++#define __PTHREAD_SPINS 0, 0 ++#elif __PTHREAD_MUTEX_HAVE_ELISION == 2 /* 32bit layout. */ ++#define __PTHREAD_SPINS { 0, 0 } ++#else ++#define __PTHREAD_SPINS 0 ++#endif ++ + #ifdef __PTHREAD_MUTEX_HAVE_PREV + # define PTHREAD_MUTEX_INITIALIZER \ +- { { 0, 0, 0, 0, 0, 0, { 0, 0 } } } ++ { { 0, 0, 0, 0, 0, __PTHREAD_SPINS, { 0, 0 } } } + # ifdef __USE_GNU + # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ +- { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0, 0 } } } ++ { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __PTHREAD_SPINS, { 0, 0 } } } + # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \ +- { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0, 0 } } } ++ { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, __PTHREAD_SPINS, { 0, 0 } } } + # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ +- { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0, 0 } } } ++ { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } } ++# define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ ++ { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, __PTHREAD_SPINS, { 0, 0 } } } ++ + # endif + #else + # define PTHREAD_MUTEX_INITIALIZER \ +- { { 0, 0, 0, 0, 0, { 0 } } } ++ { { 0, 0, 0, 0, 0, { __PTHREAD_SPINS } } } + # ifdef __USE_GNU + # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ +- { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { 0 } } } ++ { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, 0, { __PTHREAD_SPINS } } } + # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \ +- { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { 0 } } } ++ { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, 0, { __PTHREAD_SPINS } } } + # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ +- { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { 0 } } } ++ { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, 0, { __PTHREAD_SPINS } } } ++ + # endif + #endif diff --git a/SOURCES/glibc-rh841653-10.patch b/SOURCES/glibc-rh841653-10.patch new file mode 100644 index 00000000..ca4ea553 --- /dev/null +++ b/SOURCES/glibc-rh841653-10.patch @@ -0,0 +1,56 @@ +commit b0a3c1640ab2fb7d16d9b9a8d9c0e524e9cb0001 +Author: Andreas Schwab +Date: Tue Mar 4 13:00:26 2014 +0100 + + Properly handle forced elision in pthread_mutex_trylock (bug 16657) + +Index: glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_trylock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c +@@ -26,8 +26,8 @@ + #define lll_trylock_elision(a,t) lll_trylock(a) + #endif + +-#ifndef DO_ELISION +-#define DO_ELISION(m) 0 ++#ifndef FORCE_ELISION ++#define FORCE_ELISION(m, s) + #endif + + /* We don't force elision in trylock, because this can lead to inconsistent +@@ -69,7 +69,7 @@ __pthread_mutex_trylock (mutex) + break; + + case PTHREAD_MUTEX_TIMED_ELISION_NP: +- elision: ++ elision: __attribute__((unused)) + if (lll_trylock_elision (mutex->__data.__lock, + mutex->__data.__elision) != 0) + break; +@@ -77,8 +77,7 @@ __pthread_mutex_trylock (mutex) + return 0; + + case PTHREAD_MUTEX_TIMED_NP: +- if (DO_ELISION (mutex)) +- goto elision; ++ FORCE_ELISION (mutex, goto elision); + /*FALL THROUGH*/ + case PTHREAD_MUTEX_ADAPTIVE_NP: + case PTHREAD_MUTEX_ERRORCHECK_NP: +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h +@@ -16,11 +16,6 @@ + License along with the GNU C Library; if not, see + . */ + +-/* Check for elision on this lock without upgrading. */ +-#define DO_ELISION(m) \ +- (__pthread_force_elision \ +- && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0) \ +- + /* Automatically enable elision for existing user lock kinds. */ + #define FORCE_ELISION(m, s) \ + if (__pthread_force_elision \ diff --git a/SOURCES/glibc-rh841653-11.patch b/SOURCES/glibc-rh841653-11.patch new file mode 100644 index 00000000..387dba06 --- /dev/null +++ b/SOURCES/glibc-rh841653-11.patch @@ -0,0 +1,26 @@ +commit 7f786dc12bd60f0a134e538429fef98350e4c814 +Author: Torvald Riegel +Date: Mon Dec 15 22:09:55 2014 +0100 + + Fix nptl/tst-mutex5.c: Do not skip tests if elision is enabled. +Index: glibc-2.17-c758a686/nptl/tst-mutex5.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/tst-mutex5.c ++++ glibc-2.17-c758a686/nptl/tst-mutex5.c +@@ -86,8 +86,6 @@ do_test (void) + return 1; + } + +- /* Elided locks do not time out. */ +-#ifndef ENABLE_LOCK_ELISION + if (pthread_mutex_trylock (&m) == 0) + { + puts ("mutex_trylock succeeded"); +@@ -183,7 +181,6 @@ do_test (void) + puts ("3rd timedlock didn't return right away"); + return 1; + } +-#endif + + if (pthread_mutex_unlock (&m) != 0) + { diff --git a/SOURCES/glibc-rh841653-12.patch b/SOURCES/glibc-rh841653-12.patch new file mode 100644 index 00000000..b7ba6607 --- /dev/null +++ b/SOURCES/glibc-rh841653-12.patch @@ -0,0 +1,100 @@ +commit 2868e0703d5b8c8e60c6f60de13e876c4d85daa0 +Author: Andreas Schwab +Date: Mon Aug 11 11:18:26 2014 +0200 + + Filter out PTHREAD_MUTEX_NO_ELISION_NP bit in pthread_mutexattr_gettype (BZ #15790) + + pthread_mutexattr_settype adds PTHREAD_MUTEX_NO_ELISION_NP to kind, + which is an internal flag that pthread_mutexattr_gettype shouldn't + expose, since pthread_mutexattr_settype wouldn't accept it. +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -252,6 +252,7 @@ tests = tst-typesizes \ + tst-exit1 tst-exit2 tst-exit3 \ + tst-stdio1 tst-stdio2 \ + tst-stack1 tst-stack2 tst-stack3 tst-stack4 tst-pthread-getattr \ ++ tst-pthread-mutexattr \ + tst-unload \ + tst-dlsym1 \ + tst-sysconf \ +Index: glibc-2.17-c758a686/nptl/pthread_mutexattr_gettype.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutexattr_gettype.c ++++ glibc-2.17-c758a686/nptl/pthread_mutexattr_gettype.c +@@ -28,7 +28,8 @@ pthread_mutexattr_gettype (attr, kind) + + iattr = (const struct pthread_mutexattr *) attr; + +- *kind = iattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS; ++ *kind = (iattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS ++ & ~PTHREAD_MUTEX_NO_ELISION_NP); + + return 0; + } +Index: glibc-2.17-c758a686/nptl/tst-pthread-mutexattr.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-pthread-mutexattr.c +@@ -0,0 +1,60 @@ ++/* Make sure that pthread_mutexattr_gettype returns a valid kind. ++ ++ Copyright (C) 2015 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ pthread_mutexattr_t attr; ++ int kind; ++ int error; ++ ++ error = pthread_mutexattr_init (&attr); ++ if (error) ++ { ++ printf ("pthread_mutexattr_init: %s\n", strerror (error)); ++ return 1; ++ } ++ error = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_DEFAULT); ++ if (error) ++ { ++ printf ("pthread_mutexattr_settype (1): %s\n", strerror (error)); ++ return 1; ++ } ++ error = pthread_mutexattr_gettype (&attr, &kind); ++ if (error) ++ { ++ printf ("pthread_mutexattr_gettype: %s\n", strerror (error)); ++ return 1; ++ } ++ error = pthread_mutexattr_settype (&attr, kind); ++ if (error) ++ { ++ printf ("pthread_mutexattr_settype (2): %s\n", strerror (error)); ++ return 1; ++ } ++ return 0; ++} ++ ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh841653-13.patch b/SOURCES/glibc-rh841653-13.patch new file mode 100644 index 00000000..8bac62b5 --- /dev/null +++ b/SOURCES/glibc-rh841653-13.patch @@ -0,0 +1,103 @@ +commit 5aded6f2abbe19bc77e563b7db10aa9dd037a90d +Author: Andreas Schwab +Date: Wed Jan 13 16:04:42 2016 +0100 + + Don't do lock elision on an error checking mutex (bug 17514) + + Error checking mutexes are not supposed to be subject to lock elision. + That would defeat the error checking nature of the mutex because lock + elision doesn't record ownership. +Index: glibc-2.17-c758a686/nptl/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/Makefile ++++ glibc-2.17-c758a686/nptl/Makefile +@@ -266,7 +266,8 @@ tests = tst-typesizes \ + tst-abstime \ + tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \ + tst-getpid1 tst-getpid2 tst-getpid3 \ +- tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) ++ tst-initializers1 $(patsubst %,tst-initializers1-%,c89 gnu89 c99 gnu99) \ ++ tst-mutex-errorcheck + xtests = tst-setuid1 tst-setuid1-static tst-mutexpp1 tst-mutexpp6 tst-mutexpp10 + test-srcs = tst-oddstacklimit + +Index: glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_timedlock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c +@@ -87,7 +87,8 @@ pthread_mutex_timedlock (mutex, abstime) + if (__builtin_expect (mutex->__data.__owner == id, 0)) + return EDEADLK; + +- /* FALLTHROUGH */ ++ /* Don't do lock elision on an error checking mutex. */ ++ goto simple; + + case PTHREAD_MUTEX_TIMED_NP: + FORCE_ELISION (mutex, goto elision); +Index: glibc-2.17-c758a686/nptl/tst-mutex-errorcheck.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/tst-mutex-errorcheck.c +@@ -0,0 +1,61 @@ ++/* Check that error checking mutexes are not subject to lock elision. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct timespec tms = { 0 }; ++ pthread_mutex_t mutex; ++ pthread_mutexattr_t mutexattr; ++ int ret = 0; ++ ++ if (pthread_mutexattr_init (&mutexattr) != 0) ++ return 1; ++ if (pthread_mutexattr_settype (&mutexattr, PTHREAD_MUTEX_ERRORCHECK) != 0) ++ return 1; ++ ++ if (pthread_mutex_init (&mutex, &mutexattr) != 0) ++ return 1; ++ if (pthread_mutexattr_destroy (&mutexattr) != 0) ++ return 1; ++ ++ /* The call to pthread_mutex_timedlock erroneously enabled lock elision ++ on the mutex, which then triggered an assertion failure in ++ pthread_mutex_unlock. It would also defeat the error checking nature ++ of the mutex. */ ++ if (pthread_mutex_timedlock (&mutex, &tms) != 0) ++ return 1; ++ if (pthread_mutex_timedlock (&mutex, &tms) != EDEADLK) ++ { ++ printf ("Failed error checking on locked mutex\n"); ++ ret = 1; ++ } ++ ++ if (pthread_mutex_unlock (&mutex) != 0) ++ ret = 1; ++ ++ return ret; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh841653-14.patch b/SOURCES/glibc-rh841653-14.patch new file mode 100644 index 00000000..78a8a269 --- /dev/null +++ b/SOURCES/glibc-rh841653-14.patch @@ -0,0 +1,172 @@ +Partial backport: + +Skipped elide.h since rw-locks are not backported. + +commit ca6e601a9d4a72b3699cca15bad12ac1716bf49a +Author: Torvald Riegel +Date: Wed Nov 30 17:53:11 2016 +0100 + + Use C11-like atomics instead of plain memory accesses in x86 lock elision. + + This uses atomic operations to access lock elision metadata that is accessed + concurrently (ie, adapt_count fields). The size of the data is less than a + word but accessed only with atomic loads and stores; therefore, we add + support for shorter-size atomic load and stores too. + + * include/atomic.h (__atomic_check_size_ls): New. + (atomic_load_relaxed, atomic_load_acquire, atomic_store_relaxed, + atomic_store_release): Use it. + * sysdeps/x86/elide.h (ACCESS_ONCE): Remove. + (elision_adapt, ELIDE_LOCK): Use atomics. + * sysdeps/unix/sysv/linux/x86/elision-lock.c (__lll_lock_elision): Use + atomics and improve code comments. + * sysdeps/unix/sysv/linux/x86/elision-trylock.c + (__lll_trylock_elision): Likewise. + +Index: glibc-2.17-c758a686/include/atomic.h +=================================================================== +--- glibc-2.17-c758a686.orig/include/atomic.h ++++ glibc-2.17-c758a686/include/atomic.h +@@ -567,6 +567,20 @@ void __atomic_link_error (void); + if (sizeof (*mem) != 4) \ + __atomic_link_error (); + # endif ++/* We additionally provide 8b and 16b atomic loads and stores; we do not yet ++ need other atomic operations of such sizes, and restricting the support to ++ loads and stores makes this easier for archs that do not have native ++ support for atomic operations to less-than-word-sized data. */ ++# if __HAVE_64B_ATOMICS == 1 ++# define __atomic_check_size_ls(mem) \ ++ if ((sizeof (*mem) != 1) && (sizeof (*mem) != 2) && (sizeof (*mem) != 4) \ ++ && (sizeof (*mem) != 8)) \ ++ __atomic_link_error (); ++# else ++# define __atomic_check_size_ls(mem) \ ++ if ((sizeof (*mem) != 1) && (sizeof (*mem) != 2) && sizeof (*mem) != 4) \ ++ __atomic_link_error (); ++# endif + + # define atomic_thread_fence_acquire() \ + __atomic_thread_fence (__ATOMIC_ACQUIRE) +@@ -576,18 +590,20 @@ void __atomic_link_error (void); + __atomic_thread_fence (__ATOMIC_SEQ_CST) + + # define atomic_load_relaxed(mem) \ +- ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_RELAXED); }) ++ ({ __atomic_check_size_ls((mem)); \ ++ __atomic_load_n ((mem), __ATOMIC_RELAXED); }) + # define atomic_load_acquire(mem) \ +- ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_ACQUIRE); }) ++ ({ __atomic_check_size_ls((mem)); \ ++ __atomic_load_n ((mem), __ATOMIC_ACQUIRE); }) + + # define atomic_store_relaxed(mem, val) \ + do { \ +- __atomic_check_size((mem)); \ ++ __atomic_check_size_ls((mem)); \ + __atomic_store_n ((mem), (val), __ATOMIC_RELAXED); \ + } while (0) + # define atomic_store_release(mem, val) \ + do { \ +- __atomic_check_size((mem)); \ ++ __atomic_check_size_ls((mem)); \ + __atomic_store_n ((mem), (val), __ATOMIC_RELEASE); \ + } while (0) + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c +@@ -44,7 +44,13 @@ + int + __lll_lock_elision (int *futex, short *adapt_count, EXTRAARG int private) + { +- if (*adapt_count <= 0) ++ /* adapt_count can be accessed concurrently; these accesses can be both ++ inside of transactions (if critical sections are nested and the outer ++ critical section uses lock elision) and outside of transactions. Thus, ++ we need to use atomic accesses to avoid data races. However, the ++ value of adapt_count is just a hint, so relaxed MO accesses are ++ sufficient. */ ++ if (atomic_load_relaxed (adapt_count) <= 0) + { + unsigned status; + int try_xbegin; +@@ -70,15 +76,20 @@ __lll_lock_elision (int *futex, short *a + && _XABORT_CODE (status) == _ABORT_LOCK_BUSY) + { + /* Right now we skip here. Better would be to wait a bit +- and retry. This likely needs some spinning. */ +- if (*adapt_count != aconf.skip_lock_busy) +- *adapt_count = aconf.skip_lock_busy; ++ and retry. This likely needs some spinning. See ++ above for why relaxed MO is sufficient. */ ++ if (atomic_load_relaxed (adapt_count) ++ != aconf.skip_lock_busy) ++ atomic_store_relaxed (adapt_count, aconf.skip_lock_busy); + } + /* Internal abort. There is no chance for retry. + Use the normal locking and next time use lock. +- Be careful to avoid writing to the lock. */ +- else if (*adapt_count != aconf.skip_lock_internal_abort) +- *adapt_count = aconf.skip_lock_internal_abort; ++ Be careful to avoid writing to the lock. See above for why ++ relaxed MO is sufficient. */ ++ else if (atomic_load_relaxed (adapt_count) ++ != aconf.skip_lock_internal_abort) ++ atomic_store_relaxed (adapt_count, ++ aconf.skip_lock_internal_abort); + break; + } + } +@@ -87,7 +98,8 @@ __lll_lock_elision (int *futex, short *a + { + /* Use a normal lock until the threshold counter runs out. + Lost updates possible. */ +- (*adapt_count)--; ++ atomic_store_relaxed (adapt_count, ++ atomic_load_relaxed (adapt_count) - 1); + } + + /* Use a normal lock here. */ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +@@ -36,8 +36,10 @@ __lll_trylock_elision (int *futex, short + return an error. */ + _xabort (_ABORT_NESTED_TRYLOCK); + +- /* Only try a transaction if it's worth it. */ +- if (*adapt_count <= 0) ++ /* Only try a transaction if it's worth it. See __lll_lock_elision for ++ why we need atomic accesses. Relaxed MO is sufficient because this is ++ just a hint. */ ++ if (atomic_load_relaxed (adapt_count) <= 0) + { + unsigned status; + +@@ -55,16 +57,18 @@ __lll_trylock_elision (int *futex, short + if (!(status & _XABORT_RETRY)) + { + /* Internal abort. No chance for retry. For future +- locks don't try speculation for some time. */ +- if (*adapt_count != aconf.skip_trylock_internal_abort) +- *adapt_count = aconf.skip_trylock_internal_abort; ++ locks don't try speculation for some time. See above for MO. */ ++ if (atomic_load_relaxed (adapt_count) ++ != aconf.skip_lock_internal_abort) ++ atomic_store_relaxed (adapt_count, aconf.skip_lock_internal_abort); + } + /* Could do some retries here. */ + } + else + { +- /* Lost updates are possible, but harmless. */ +- (*adapt_count)--; ++ /* Lost updates are possible but harmless (see above). */ ++ atomic_store_relaxed (adapt_count, ++ atomic_load_relaxed (adapt_count) - 1); + } + + return lll_trylock (*futex); diff --git a/SOURCES/glibc-rh841653-15.patch b/SOURCES/glibc-rh841653-15.patch new file mode 100644 index 00000000..3cf8dc49 --- /dev/null +++ b/SOURCES/glibc-rh841653-15.patch @@ -0,0 +1,48 @@ +commit 657c084cd6f69d6cc880c2ae65129a0723d053c5 +Author: Andreas Schwab +Date: Mon Dec 5 12:06:46 2016 +0100 + + Get rid of __elision_available + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +@@ -52,11 +52,6 @@ int __rwlock_rtm_enabled attribute_hidde + + int __rwlock_rtm_read_retries attribute_hidden = 3; + +-/* Set when the CPU supports elision. When false elision is never attempted. +- */ +- +-int __elision_available attribute_hidden; +- + /* Force elision for all new locks. This is used to decide whether existing + DEFAULT locks should be automatically upgraded to elision in + pthread_mutex_lock(). Disabled for suid programs. Only used when elision +@@ -71,10 +66,10 @@ elision_init (int argc __attribute__ ((u + char **argv __attribute__ ((unused)), + char **environ) + { +- __elision_available = HAS_CPU_FEATURE (RTM); ++ int elision_available = HAS_CPU_FEATURE (RTM); + #ifdef ENABLE_LOCK_ELISION +- __pthread_force_elision = __libc_enable_secure ? 0 : __elision_available; +- __rwlock_rtm_enabled = __libc_enable_secure ? 0 : __elision_available; ++ __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; ++ __rwlock_rtm_enabled = __libc_enable_secure ? 0 : elision_available; + #endif + } + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h +@@ -35,7 +35,6 @@ struct elision_config + extern struct elision_config __elision_aconf attribute_hidden; + + extern int __rwlock_rtm_enabled attribute_hidden; +-extern int __elision_available attribute_hidden; + extern int __pthread_force_elision attribute_hidden; + + /* Tell the test suite to test elision for this architecture. */ diff --git a/SOURCES/glibc-rh841653-16.patch b/SOURCES/glibc-rh841653-16.patch new file mode 100644 index 00000000..8be759e9 --- /dev/null +++ b/SOURCES/glibc-rh841653-16.patch @@ -0,0 +1,204 @@ +Index: glibc-2.17-c758a686/elf/rtld.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/rtld.c ++++ glibc-2.17-c758a686/elf/rtld.c +@@ -2478,6 +2478,11 @@ process_envvars (enum mode *modep) + GLRO(dl_profile_output) + = &"/var/tmp\0/var/profile"[INTUSE(__libc_enable_secure) ? 9 : 0]; + ++ /* RHEL 7 specific change: ++ Without the tunables farmework we simulate tunables only for ++ use with enabling transactional memory. */ ++ _dl_process_tunable_env_entries (); ++ + while ((envline = _dl_next_ld_env_entry (&runp)) != NULL) + { + size_t len = 0; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +@@ -68,8 +68,18 @@ elision_init (int argc __attribute__ ((u + { + int elision_available = HAS_CPU_FEATURE (RTM); + #ifdef ENABLE_LOCK_ELISION +- __pthread_force_elision = __libc_enable_secure ? 0 : elision_available; +- __rwlock_rtm_enabled = __libc_enable_secure ? 0 : elision_available; ++ if (!__libc_enable_secure && elision_available) ++ { ++ /* RHEL 7 specific change: Check if elision is enabled for the ++ process. */ ++ __pthread_force_elision = GLRO(dl_elision_enabled); ++ __rwlock_rtm_enabled = GLRO(dl_elision_enabled); ++ } ++ else ++ { ++ __pthread_force_elision = 0; ++ __rwlock_rtm_enabled = 0; ++ } + #endif + } + +Index: glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/generic/ldsodefs.h ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +@@ -557,6 +557,9 @@ struct rtld_global_ro + platforms. */ + EXTERN uint64_t _dl_hwcap2; + ++ /* RHEL 7 specific change: Is elision enabled for this process? */ ++ EXTERN bool _dl_elision_enabled; ++ + #ifdef SHARED + /* We add a function table to _rtld_global which is then used to + call the function instead of going through the PLT. The result +@@ -893,6 +896,10 @@ extern void _dl_show_auxv (void) interna + other. */ + extern char *_dl_next_ld_env_entry (char ***position) internal_function; + ++/* RHEL 7 specific change: ++ Manually process RHEL 7-specific tunable entries. */ ++extern void _dl_process_tunable_env_entries (void) internal_function; ++ + /* Return an array with the names of the important hardware capabilities. */ + extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform, + size_t paltform_len, +Index: glibc-2.17-c758a686/elf/dl-support.c +=================================================================== +--- glibc-2.17-c758a686.orig/elf/dl-support.c ++++ glibc-2.17-c758a686/elf/dl-support.c +@@ -123,6 +123,10 @@ size_t _dl_phnum; + uint64_t _dl_hwcap __attribute__ ((nocommon)); + uint64_t _dl_hwcap2 __attribute__ ((nocommon)); + ++/* RHEL 7-specific change: Is elision enabled for the process? ++ Static library definition. */ ++bool _dl_elision_enabled; ++ + /* This is not initialized to HWCAP_IMPORTANT, matching the definition + of _dl_important_hwcaps, below, where no hwcap strings are ever + used. This mask is still used to mediate the lookups in the cache +@@ -289,6 +293,9 @@ _dl_non_dynamic_init (void) + _dl_profile_output + = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0]; + ++ /* RHEL 7 specific change: Process tunables at startup. */ ++ _dl_process_tunable_env_entries (); ++ + if (__libc_enable_secure) + { + static const char unsecure_envvars[] = +Index: glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86_64/multiarch/strstr-c.c ++++ glibc-2.17-c758a686/sysdeps/x86_64/multiarch/strstr-c.c +@@ -17,6 +17,10 @@ + License along with the GNU C Library; if not, see + . */ + ++/* RHEL 7-specific: Define multiple versions only for the definition in ++ libc. Don't define multiple versions for strstr in static library ++ since we need strstr before initialization has happened. */ ++#if defined SHARED && IS_IN (libc) + /* Redefine strstr so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ + #undef strstr +@@ -30,9 +34,11 @@ + # define libc_hidden_builtin_def(name) \ + __hidden_ver1 (__strstr_sse2, __GI_strstr, __strstr_sse2); + #endif ++#endif + + #include "string/strstr.c" + ++#if defined SHARED && IS_IN (libc) + extern __typeof (__redirect_strstr) __strstr_sse42 attribute_hidden; + extern __typeof (__redirect_strstr) __strstr_sse2_unaligned attribute_hidden; + extern __typeof (__redirect_strstr) __strstr_sse2 attribute_hidden; +@@ -48,3 +54,5 @@ libc_ifunc (__libc_strstr, HAS_CPU_FEATU + + #undef strstr + strong_alias (__libc_strstr, strstr) ++#endif ++ +Index: glibc-2.17-c758a686/elf/Makefile +=================================================================== +--- glibc-2.17-c758a686.orig/elf/Makefile ++++ glibc-2.17-c758a686/elf/Makefile +@@ -35,6 +35,10 @@ dl-routines = $(addprefix dl-,load looku + ifeq (yes,$(use-ldconfig)) + dl-routines += dl-cache + endif ++ ++# RHEL 7-specific change: Add rudimentary tunables support. ++dl-routines += dl-tunables ++ + all-dl-routines = $(dl-routines) $(sysdep-dl-routines) + # But they are absent from the shared libc, because that code is in ld.so. + elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ +Index: glibc-2.17-c758a686/elf/dl-tunables.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/elf/dl-tunables.c +@@ -0,0 +1,60 @@ ++/* RHEL 7-specific rudimentary tunables handling. ++ Copyright (C) 2017 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++/* RHEL 7 specific change: ++ Manually process RHEL 7-specific tunable entries. */ ++void ++internal_function ++_dl_process_tunable_env_entries (void) ++{ ++#if HAVE_ELISION ++ char **ep; ++ const char *envname = { "RHEL_GLIBC_TUNABLES" }; ++# define TUNABLE_ELISION 0 ++# define TUNABLE_MAX 1 ++ const char *tunables[TUNABLE_MAX] = { "glibc.elision.enable=1" }; ++ ++ ep = __environ; ++ while (*ep != NULL) ++ { ++ size_t cnt = 0; ++ ++ while ((*ep)[cnt] == envname[cnt] && envname[cnt] != '\0') ++ ++cnt; ++ ++ if (envname[cnt] == '\0' && (*ep)[cnt] == '=') ++ { ++ /* Found it. */ ++ char *found; ++ found = strstr (*ep, tunables[TUNABLE_ELISION]); ++ /* Process TUNABLE_ELISION: ++ Note: elision-conf.c applies security checks. */ ++ if (found != NULL) ++ GLRO(dl_elision_enabled) = true; ++ /* Continue the loop in case NAME appears again. */ ++ } ++ ++ ++ep; ++ } ++#endif ++} diff --git a/SOURCES/glibc-rh841653-17.patch b/SOURCES/glibc-rh841653-17.patch new file mode 100644 index 00000000..639989b6 --- /dev/null +++ b/SOURCES/glibc-rh841653-17.patch @@ -0,0 +1,82 @@ +commit 2702856bf45c82cf8e69f2064f5aa15c0ceb6359 +Author: Andrew Senkevich +Date: Mon Dec 19 13:20:31 2016 +0300 + + Disable TSX on some Haswell processors. + + Patch disables Intel TSX on some Haswell processors to avoid TSX + on kernels that weren't updated with the latest microcode package + (which disables broken feature by default). + + * sysdeps/x86/cpu-features.c (get_common_indeces): Add + stepping identification. + (init_cpu_features): Add handle of Haswell. + +Index: glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +=================================================================== +--- glibc-2.17-c758a686.orig/sysdeps/x86/cpu-features.c ++++ glibc-2.17-c758a686/sysdeps/x86/cpu-features.c +@@ -21,7 +21,8 @@ + + static inline void + get_common_indeces (struct cpu_features *cpu_features, +- unsigned int *family, unsigned int *model) ++ unsigned int *family, unsigned int *model, ++ unsigned int *stepping) + { + unsigned int eax; + __cpuid (1, eax, cpu_features->cpuid[COMMON_CPUID_INDEX_1].ebx, +@@ -30,6 +31,7 @@ get_common_indeces (struct cpu_features + GLRO(dl_x86_cpu_features).cpuid[COMMON_CPUID_INDEX_1].eax = eax; + *family = (eax >> 8) & 0x0f; + *model = (eax >> 4) & 0x0f; ++ *stepping = eax & 0x0f; + } + + static inline void +@@ -45,9 +47,11 @@ init_cpu_features (struct cpu_features * + /* This spells out "GenuineIntel". */ + if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) + { ++ unsigned int stepping; ++ + kind = arch_kind_intel; + +- get_common_indeces (cpu_features, &family, &model); ++ get_common_indeces (cpu_features, &family, &model, &stepping); + + /* Intel processors prefer SSE instruction for memory/string + routines if they are available. */ +@@ -128,6 +132,20 @@ init_cpu_features (struct cpu_features * + | bit_Fast_Unaligned_Load + | bit_Prefer_PMINUB_for_stringop); + break; ++ ++ case 0x3f: ++ /* Xeon E7 v3 with stepping >= 4 has working TSX. */ ++ if (stepping >= 4) ++ break; ++ case 0x3c: ++ case 0x45: ++ case 0x46: ++ /* Disable Intel TSX on Haswell processors (except Xeon E7 v3 ++ with stepping >= 4) to avoid TSX on kernels that weren't ++ updated with the latest microcode package (which disables ++ broken feature by default). */ ++ cpu_features->cpuid[COMMON_CPUID_INDEX_7].ebx &= ~(bit_RTM); ++ break; + } + } + +@@ -148,9 +166,11 @@ init_cpu_features (struct cpu_features * + /* This spells out "AuthenticAMD". */ + else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) + { ++ unsigned int stepping; ++ + kind = arch_kind_amd; + +- get_common_indeces (cpu_features, &family, &model); ++ get_common_indeces (cpu_features, &family, &model, &stepping); + + ecx = cpu_features->cpuid[COMMON_CPUID_INDEX_1].ecx; diff --git a/SOURCES/glibc-rh841653-2.patch b/SOURCES/glibc-rh841653-2.patch new file mode 100644 index 00000000..839910d9 --- /dev/null +++ b/SOURCES/glibc-rh841653-2.patch @@ -0,0 +1,122 @@ +commit 68cc29355f3334c7ad18f648ff9a6383a0916d23 +Author: Andi Kleen +Date: Fri Jun 28 05:19:37 2013 -0700 + + Add minimal test suite changes for elision enabled kernels + + tst-mutex5 and 8 test some behaviour not required by POSIX, + that elision changes. This changes these tests to not check + this when elision is enabled at configure time. +Index: glibc-2.17-c758a686/nptl/tst-mutex5.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/tst-mutex5.c ++++ glibc-2.17-c758a686/nptl/tst-mutex5.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + + #ifndef TYPE +@@ -85,6 +86,8 @@ do_test (void) + return 1; + } + ++ /* Elided locks do not time out. */ ++#ifdef ENABLE_LOCK_ELISION + if (pthread_mutex_trylock (&m) == 0) + { + puts ("mutex_trylock succeeded"); +@@ -180,6 +183,7 @@ do_test (void) + puts ("3rd timedlock didn't return right away"); + return 1; + } ++#endif + + if (pthread_mutex_unlock (&m) != 0) + { +Index: glibc-2.17-c758a686/nptl/tst-mutex8.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/tst-mutex8.c ++++ glibc-2.17-c758a686/nptl/tst-mutex8.c +@@ -93,6 +93,8 @@ tf (void *arg) + static int + check_type (const char *mas, pthread_mutexattr_t *ma) + { ++ int e __attribute__((unused)); ++ + if (pthread_mutex_init (m, ma) != 0) + { + printf ("1st mutex_init failed for %s\n", mas); +@@ -117,7 +119,10 @@ check_type (const char *mas, pthread_mut + return 1; + } + +- int e = pthread_mutex_destroy (m); ++ /* Elided mutexes don't fail destroy. If elision is not explicitly disabled ++ we don't know, so can also not check this. */ ++#ifndef ENABLE_LOCK_ELISION ++ e = pthread_mutex_destroy (m); + if (e == 0) + { + printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas); +@@ -129,6 +134,7 @@ check_type (const char *mas, pthread_mut + mas); + return 1; + } ++#endif + + if (pthread_mutex_unlock (m) != 0) + { +@@ -142,6 +148,8 @@ check_type (const char *mas, pthread_mut + return 1; + } + ++ /* Elided mutexes don't fail destroy. */ ++#ifndef ENABLE_LOCK_ELISION + e = pthread_mutex_destroy (m); + if (e == 0) + { +@@ -155,6 +163,7 @@ mutex_destroy of self-trylocked mutex di + mas); + return 1; + } ++#endif + + if (pthread_mutex_unlock (m) != 0) + { +@@ -189,6 +198,8 @@ mutex_destroy of self-trylocked mutex di + return 1; + } + ++ /* Elided mutexes don't fail destroy. */ ++#ifndef ENABLE_LOCK_ELISION + e = pthread_mutex_destroy (m); + if (e == 0) + { +@@ -201,6 +212,7 @@ mutex_destroy of self-trylocked mutex di + mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas); + return 1; + } ++#endif + + done = true; + if (pthread_cond_signal (&c) != 0) +@@ -259,6 +271,8 @@ mutex_destroy of condvar-used mutex did + return 1; + } + ++ /* Elided mutexes don't fail destroy. */ ++#ifndef ENABLE_LOCK_ELISION + e = pthread_mutex_destroy (m); + if (e == 0) + { +@@ -273,6 +287,7 @@ mutex_destroy of condvar-used mutex did + mas); + return 1; + } ++#endif + + if (pthread_cancel (th) != 0) + { diff --git a/SOURCES/glibc-rh841653-3.patch b/SOURCES/glibc-rh841653-3.patch new file mode 100644 index 00000000..ca157ed1 --- /dev/null +++ b/SOURCES/glibc-rh841653-3.patch @@ -0,0 +1,541 @@ +commit e8c659d74e011346785355eeef03b7fb6f533c61 +Author: Andi Kleen +Date: Sat Dec 22 01:03:04 2012 -0800 + + Add elision to pthread_mutex_{try,timed,un}lock + + Add elision paths to the basic mutex locks. + + The normal path has a check for RTM and upgrades the lock + to RTM when available. Trylocks cannot automatically upgrade, + so they check for elision every time. + + We use a 4 byte value in the mutex to store the lock + elision adaptation state. This is separate from the adaptive + spin state and uses a separate field. + + Condition variables currently do not support elision. + + Recursive mutexes and condition variables may be supported at some point, + but are not in the current implementation. Also "trylock" will + not automatically enable elision unless some other lock call + has been already called on the lock. + + This version does not use IFUNC, so it means every lock has one + additional check for elision. Benchmarking showed the overhead + to be negligible. +Index: glibc-2.17-c758a686/nptl/pthreadP.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthreadP.h ++++ glibc-2.17-c758a686/nptl/pthreadP.h +@@ -110,8 +110,10 @@ enum + + #define PTHREAD_MUTEX_TYPE(m) \ + ((m)->__data.__kind & 127) ++/* Don't include NO_ELISION, as that type is always the same ++ as the underlying lock type. */ + #define PTHREAD_MUTEX_TYPE_ELISION(m) \ +- ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_FLAGS_NP)) ++ ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP)) + + #if LLL_PRIVATE == 0 && LLL_SHARED == 128 + # define PTHREAD_MUTEX_PSHARED(m) \ +Index: glibc-2.17-c758a686/nptl/pthread_mutex_lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_lock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_lock.c +@@ -25,6 +25,14 @@ + #include + #include + ++#ifndef lll_lock_elision ++#define lll_lock_elision(lock, try_lock, private) ({ \ ++ lll_lock (lock, private); 0; }) ++#endif ++ ++#ifndef lll_trylock_elision ++#define lll_trylock_elision(a,t) lll_trylock(a) ++#endif + + #ifndef LLL_MUTEX_LOCK + # define LLL_MUTEX_LOCK(mutex) \ +@@ -34,39 +42,60 @@ + # define LLL_ROBUST_MUTEX_LOCK(mutex, id) \ + lll_robust_lock ((mutex)->__data.__lock, id, \ + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)) ++# define LLL_MUTEX_LOCK_ELISION(mutex) \ ++ lll_lock_elision ((mutex)->__data.__lock, (mutex)->__data.__elision, \ ++ PTHREAD_MUTEX_PSHARED (mutex)) ++# define LLL_MUTEX_TRYLOCK_ELISION(mutex) \ ++ lll_trylock_elision((mutex)->__data.__lock, (mutex)->__data.__elision, \ ++ PTHREAD_MUTEX_PSHARED (mutex)) + #endif + ++#ifndef FORCE_ELISION ++#define FORCE_ELISION(m, s) ++#endif + + static int __pthread_mutex_lock_full (pthread_mutex_t *mutex) + __attribute_noinline__; + +- + int + __pthread_mutex_lock (mutex) + pthread_mutex_t *mutex; + { + assert (sizeof (mutex->__size) >= sizeof (mutex->__data)); + +- unsigned int type = PTHREAD_MUTEX_TYPE (mutex); ++ unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); + + LIBC_PROBE (mutex_entry, 1, mutex); + +- if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0)) ++ if (__builtin_expect (type & ~(PTHREAD_MUTEX_KIND_MASK_NP ++ | PTHREAD_MUTEX_ELISION_FLAGS_NP), 0)) + return __pthread_mutex_lock_full (mutex); + +- pid_t id = THREAD_GETMEM (THREAD_SELF, tid); +- +- if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP) +- == PTHREAD_MUTEX_TIMED_NP) ++ if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_NP, 1)) + { ++ FORCE_ELISION (mutex, goto elision); + simple: + /* Normal mutex. */ + LLL_MUTEX_LOCK (mutex); + assert (mutex->__data.__owner == 0); + } +- else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1)) ++#ifdef HAVE_ELISION ++ else if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_ELISION_NP, 1)) ++ { ++ elision: __attribute__((unused)) ++ /* This case can never happen on a system without elision, ++ as the mutex type initialization functions will not ++ allow to set the elision flags. */ ++ /* Don't record owner or users for elision case. This is a ++ tail call. */ ++ return LLL_MUTEX_LOCK_ELISION (mutex); ++ } ++#endif ++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex) ++ == PTHREAD_MUTEX_RECURSIVE_NP, 1)) + { + /* Recursive mutex. */ ++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid); + + /* Check whether we already hold the mutex. */ + if (mutex->__data.__owner == id) +@@ -87,7 +116,8 @@ __pthread_mutex_lock (mutex) + assert (mutex->__data.__owner == 0); + mutex->__data.__count = 1; + } +- else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1)) ++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex) ++ == PTHREAD_MUTEX_ADAPTIVE_NP, 1)) + { + if (! __is_smp) + goto simple; +@@ -117,13 +147,16 @@ __pthread_mutex_lock (mutex) + } + else + { +- assert (type == PTHREAD_MUTEX_ERRORCHECK_NP); ++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid); ++ assert (PTHREAD_MUTEX_TYPE (mutex) == PTHREAD_MUTEX_ERRORCHECK_NP); + /* Check whether we already hold the mutex. */ + if (__builtin_expect (mutex->__data.__owner == id, 0)) + return EDEADLK; + goto simple; + } + ++ pid_t id = THREAD_GETMEM (THREAD_SELF, tid); ++ + /* Record the ownership. */ + mutex->__data.__owner = id; + #ifndef NO_INCR +Index: glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_timedlock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_timedlock.c +@@ -25,6 +25,17 @@ + + #include + ++#ifndef lll_timedlock_elision ++#define lll_timedlock_elision(a,dummy,b,c) lll_timedlock(a, b, c) ++#endif ++ ++#ifndef lll_trylock_elision ++#define lll_trylock_elision(a,t) lll_trylock(a) ++#endif ++ ++#ifndef FORCE_ELISION ++#define FORCE_ELISION(m, s) ++#endif + + int + pthread_mutex_timedlock (mutex, abstime) +@@ -40,10 +51,11 @@ pthread_mutex_timedlock (mutex, abstime) + /* We must not check ABSTIME here. If the thread does not block + abstime must not be checked for a valid value. */ + +- switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex), ++ switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), + PTHREAD_MUTEX_TIMED_NP)) + { + /* Recursive mutex. */ ++ case PTHREAD_MUTEX_RECURSIVE_NP|PTHREAD_MUTEX_ELISION_NP: + case PTHREAD_MUTEX_RECURSIVE_NP: + /* Check whether we already hold the mutex. */ + if (mutex->__data.__owner == id) +@@ -78,12 +90,22 @@ pthread_mutex_timedlock (mutex, abstime) + /* FALLTHROUGH */ + + case PTHREAD_MUTEX_TIMED_NP: ++ FORCE_ELISION (mutex, goto elision); + simple: + /* Normal mutex. */ + result = lll_timedlock (mutex->__data.__lock, abstime, + PTHREAD_MUTEX_PSHARED (mutex)); + break; + ++ case PTHREAD_MUTEX_TIMED_ELISION_NP: ++ elision: __attribute__((unused)) ++ /* Don't record ownership */ ++ return lll_timedlock_elision (mutex->__data.__lock, ++ mutex->__data.__spins, ++ abstime, ++ PTHREAD_MUTEX_PSHARED (mutex)); ++ ++ + case PTHREAD_MUTEX_ADAPTIVE_NP: + if (! __is_smp) + goto simple; +Index: glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_trylock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c +@@ -22,6 +22,16 @@ + #include "pthreadP.h" + #include + ++#ifndef lll_trylock_elision ++#define lll_trylock_elision(a,t) lll_trylock(a) ++#endif ++ ++#ifndef DO_ELISION ++#define DO_ELISION(m) 0 ++#endif ++ ++/* We don't force elision in trylock, because this can lead to inconsistent ++ lock state if the lock was actually busy. */ + + int + __pthread_mutex_trylock (mutex) +@@ -30,10 +40,11 @@ __pthread_mutex_trylock (mutex) + int oldval; + pid_t id = THREAD_GETMEM (THREAD_SELF, tid); + +- switch (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex), ++ switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), + PTHREAD_MUTEX_TIMED_NP)) + { + /* Recursive mutex. */ ++ case PTHREAD_MUTEX_RECURSIVE_NP|PTHREAD_MUTEX_ELISION_NP: + case PTHREAD_MUTEX_RECURSIVE_NP: + /* Check whether we already hold the mutex. */ + if (mutex->__data.__owner == id) +@@ -57,10 +68,20 @@ __pthread_mutex_trylock (mutex) + } + break; + +- case PTHREAD_MUTEX_ERRORCHECK_NP: ++ case PTHREAD_MUTEX_TIMED_ELISION_NP: ++ elision: ++ if (lll_trylock_elision (mutex->__data.__lock, ++ mutex->__data.__elision) != 0) ++ break; ++ /* Don't record the ownership. */ ++ return 0; ++ + case PTHREAD_MUTEX_TIMED_NP: ++ if (DO_ELISION (mutex)) ++ goto elision; ++ /*FALL THROUGH*/ + case PTHREAD_MUTEX_ADAPTIVE_NP: +- /* Normal mutex. */ ++ case PTHREAD_MUTEX_ERRORCHECK_NP: + if (lll_trylock (mutex->__data.__lock) != 0) + break; + +@@ -378,4 +399,9 @@ __pthread_mutex_trylock (mutex) + + return EBUSY; + } ++ ++#ifndef __pthread_mutex_trylock ++#ifndef pthread_mutex_trylock + strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock) ++#endif ++#endif +Index: glibc-2.17-c758a686/nptl/pthread_mutex_unlock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_unlock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_unlock.c +@@ -23,6 +23,10 @@ + #include + #include + ++#ifndef lll_unlock_elision ++#define lll_unlock_elision(a,b) ({ lll_unlock (a,b); 0; }) ++#endif ++ + static int + internal_function + __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr) +@@ -34,8 +38,9 @@ __pthread_mutex_unlock_usercnt (mutex, d + pthread_mutex_t *mutex; + int decr; + { +- int type = PTHREAD_MUTEX_TYPE (mutex); +- if (__builtin_expect (type & ~PTHREAD_MUTEX_KIND_MASK_NP, 0)) ++ int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); ++ if (__builtin_expect (type & ++ ~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0)) + return __pthread_mutex_unlock_full (mutex, decr); + + if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP) +@@ -55,7 +60,14 @@ __pthread_mutex_unlock_usercnt (mutex, d + + return 0; + } +- else if (__builtin_expect (type == PTHREAD_MUTEX_RECURSIVE_NP, 1)) ++ else if (__builtin_expect (type == PTHREAD_MUTEX_TIMED_ELISION_NP, 1)) ++ { ++ /* Don't reset the owner/users fields for elision. */ ++ return lll_unlock_elision (mutex->__data.__lock, ++ PTHREAD_MUTEX_PSHARED (mutex)); ++ } ++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex) ++ == PTHREAD_MUTEX_RECURSIVE_NP, 1)) + { + /* Recursive mutex. */ + if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid)) +@@ -66,7 +78,8 @@ __pthread_mutex_unlock_usercnt (mutex, d + return 0; + goto normal; + } +- else if (__builtin_expect (type == PTHREAD_MUTEX_ADAPTIVE_NP, 1)) ++ else if (__builtin_expect (PTHREAD_MUTEX_TYPE (mutex) ++ == PTHREAD_MUTEX_ADAPTIVE_NP, 1)) + goto normal; + else + { +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c +@@ -2,8 +2,15 @@ + + #define LLL_MUTEX_LOCK(mutex) \ + lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)) ++ ++/* Not actually elided so far. Needed? */ ++#define LLL_MUTEX_LOCK_ELISION(mutex) \ ++ ({ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); 0; }) ++ + #define LLL_MUTEX_TRYLOCK(mutex) \ + lll_cond_trylock ((mutex)->__data.__lock) ++#define LLL_MUTEX_TRYLOCK_ELISION(mutex) LLL_MUTEX_TRYLOCK(mutex) ++ + #define LLL_ROBUST_MUTEX_LOCK(mutex, id) \ + lll_robust_cond_lock ((mutex)->__data.__lock, id, \ + PTHREAD_ROBUST_MUTEX_PSHARED (mutex)) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h +@@ -101,14 +101,23 @@ typedef union + binary compatibility. */ + int __kind; + #ifdef __x86_64__ +- int __spins; ++ short __spins; ++ short __elision; + __pthread_list_t __list; + # define __PTHREAD_MUTEX_HAVE_PREV 1 ++# define __PTHREAD_MUTEX_HAVE_ELISION 1 + #else + unsigned int __nusers; + __extension__ union + { +- int __spins; ++ struct ++ { ++ short __espins; ++ short __elision; ++# define __spins d.__espins ++# define __elision d.__elision ++# define __PTHREAD_MUTEX_HAVE_ELISION 2 ++ } d; + __pthread_slist_t __list; + }; + #endif +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +@@ -24,9 +24,8 @@ + + #define aconf __elision_aconf + +-/* Try to elide a futex trylock. FUTEX is the futex variable. TRY_LOCK is the +- adaptation counter in the mutex. UPGRADED is != 0 when this is for an +- automatically upgraded lock. */ ++/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is the ++ adaptation counter in the mutex. */ + + int + __lll_trylock_elision (int *futex, short *adapt_count) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h +@@ -0,0 +1,31 @@ ++/* force-elision.h: Automatic enabling of elision for mutexes ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* Check for elision on this lock without upgrading. */ ++#define DO_ELISION(m) \ ++ (__pthread_force_elision \ ++ && (m->__data.__kind & PTHREAD_MUTEX_NO_ELISION_NP) == 0) \ ++ ++/* Automatically enable elision for existing user lock kinds. */ ++#define FORCE_ELISION(m, s) \ ++ if (__pthread_force_elision \ ++ && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0) \ ++ { \ ++ mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP; \ ++ s; \ ++ } +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c +@@ -0,0 +1,21 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++/* The cond lock is not actually elided yet, but we still need to handle ++ already elided locks. */ ++#include ++#include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c +@@ -0,0 +1,21 @@ ++/* Elided version of pthread_mutex_lock. ++ Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#include ++#include "force-elision.h" ++ ++#include "nptl/pthread_mutex_lock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c +@@ -0,0 +1,20 @@ ++/* Elided version of pthread_mutex_timedlock. ++ Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#include ++#include "force-elision.h" ++#include "nptl/pthread_mutex_timedlock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c +=================================================================== +--- /dev/null ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c +@@ -0,0 +1,21 @@ ++/* Elided version of pthread_mutex_trylock. ++ Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++#include ++#include "force-elision.h" ++ ++#include "nptl/pthread_mutex_trylock.c" diff --git a/SOURCES/glibc-rh841653-4.patch b/SOURCES/glibc-rh841653-4.patch new file mode 100644 index 00000000..9ca05092 --- /dev/null +++ b/SOURCES/glibc-rh841653-4.patch @@ -0,0 +1,29 @@ +commit 49186d21ef2d87986bccaf0a7c45c48c91b265f3 +Author: Andi Kleen +Date: Thu Jun 27 11:15:06 2013 -0700 + + Disable elision for any pthread_mutexattr_settype call + + PTHREAD_MUTEX_NORMAL requires deadlock for nesting, DEFAULT + does not. Since glibc uses the same value (0) disable elision + for any call to pthread_mutexattr_settype() with a 0 value. + This implies that a program can disable elision by doing + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL) + + Based on a original proposal by Rich Felker. +Index: glibc-2.17-c758a686/nptl/pthread_mutexattr_settype.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutexattr_settype.c ++++ glibc-2.17-c758a686/nptl/pthread_mutexattr_settype.c +@@ -30,6 +30,11 @@ __pthread_mutexattr_settype (attr, kind) + if (kind < PTHREAD_MUTEX_NORMAL || kind > PTHREAD_MUTEX_ADAPTIVE_NP) + return EINVAL; + ++ /* Cannot distinguish between DEFAULT and NORMAL. So any settype ++ call disables elision for now. */ ++ if (kind == PTHREAD_MUTEX_DEFAULT) ++ kind |= PTHREAD_MUTEX_NO_ELISION_NP; ++ + iattr = (struct pthread_mutexattr *) attr; + + iattr->mutexkind = (iattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_BITS) | kind; diff --git a/SOURCES/glibc-rh841653-5.patch b/SOURCES/glibc-rh841653-5.patch new file mode 100644 index 00000000..bb840157 --- /dev/null +++ b/SOURCES/glibc-rh841653-5.patch @@ -0,0 +1,45 @@ +commit 52dfbe137e41f2da1f5584f6dd9ea89589c71228 +Author: Siddhesh Poyarekar +Date: Thu Jul 4 20:33:03 2013 +0530 + + Fix lock elision help text in INSTALL and configure +Index: glibc-2.17-c758a686/INSTALL +=================================================================== +--- glibc-2.17-c758a686.orig/INSTALL ++++ glibc-2.17-c758a686/INSTALL +@@ -141,7 +141,7 @@ will be used, and CFLAGS sets optimizati + only if you understand and accept those risks. + + `--enable-lock-elision=yes' +- Enable lock elision for pthread mutexes and rwlocks by default. ++ Enable lock elision for pthread mutexes by default. + + `--build=BUILD-SYSTEM' + `--host=HOST-SYSTEM' +Index: glibc-2.17-c758a686/configure +=================================================================== +--- glibc-2.17-c758a686.orig/configure ++++ glibc-2.17-c758a686/configure +@@ -1407,8 +1407,7 @@ Optional Features: + initialize __stack_chk_guard canary with a random + number at program start + --enable-lock-elision=yes/no +- Enable lock elision for pthread mutexes and rwlocks +- by default ++ Enable lock elision for pthread mutexes by default + --enable-add-ons[=DIRS...] + configure and build add-ons in DIR1,DIR2,... search + for add-ons if no parameter given +Index: glibc-2.17-c758a686/configure.in +=================================================================== +--- glibc-2.17-c758a686.orig/configure.in ++++ glibc-2.17-c758a686/configure.in +@@ -157,7 +157,7 @@ fi + + AC_ARG_ENABLE([lock-elision], + AC_HELP_STRING([--enable-lock-elision[=yes/no]], +- [Enable lock elision for pthread mutexes and rwlocks by default]), ++ [Enable lock elision for pthread mutexes by default]), + [enable_lock_elision=$enableval], + [enable_lock_elision=no]) + if test "$enable_lock_elision" = yes ; then diff --git a/SOURCES/glibc-rh841653-6.patch b/SOURCES/glibc-rh841653-6.patch new file mode 100644 index 00000000..ef8c76de --- /dev/null +++ b/SOURCES/glibc-rh841653-6.patch @@ -0,0 +1,306 @@ +commit 075b9322c9e091b7e139f4c57e07d78d896c7a62 +Author: Dominik Vogt +Date: Fri Jul 19 05:16:28 2013 +0000 + + Clean up whitespace in lock elision patches. + + Signed-off-by: Carlos O'Donell +Index: glibc-2.17-c758a686/nptl/pthread_mutex_lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_lock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_lock.c +@@ -86,7 +86,7 @@ __pthread_mutex_lock (mutex) + /* This case can never happen on a system without elision, + as the mutex type initialization functions will not + allow to set the elision flags. */ +- /* Don't record owner or users for elision case. This is a ++ /* Don't record owner or users for elision case. This is a + tail call. */ + return LLL_MUTEX_LOCK_ELISION (mutex); + } +Index: glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutex_trylock.c ++++ glibc-2.17-c758a686/nptl/pthread_mutex_trylock.c +@@ -31,7 +31,7 @@ + #endif + + /* We don't force elision in trylock, because this can lead to inconsistent +- lock state if the lock was actually busy. */ ++ lock state if the lock was actually busy. */ + + int + __pthread_mutex_trylock (mutex) +@@ -73,7 +73,7 @@ __pthread_mutex_trylock (mutex) + if (lll_trylock_elision (mutex->__data.__lock, + mutex->__data.__elision) != 0) + break; +- /* Don't record the ownership. */ ++ /* Don't record the ownership. */ + return 0; + + case PTHREAD_MUTEX_TIMED_NP: +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h +@@ -112,7 +112,7 @@ typedef union + { + struct + { +- short __espins; ++ short __espins; + short __elision; + # define __spins d.__espins + # define __elision d.__elision +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.c +@@ -14,7 +14,7 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + + #include "config.h" + #include +@@ -32,7 +32,7 @@ struct elision_config __elision_aconf = + acquisition attempts. */ + .skip_lock_busy = 3, + /* How often to not attempt to use elision if a transaction aborted due +- to reasons other than other threads' memory accesses. Expressed in ++ to reasons other than other threads' memory accesses. Expressed in + number of lock acquisition attempts. */ + .skip_lock_internal_abort = 3, + /* How often we retry using elision if there is chance for the transaction +@@ -52,13 +52,14 @@ int __rwlock_rtm_enabled attribute_hidde + + int __rwlock_rtm_read_retries attribute_hidden = 3; + +-/* Set when the CPU supports elision. When false elision is never attempted. */ ++/* Set when the CPU supports elision. When false elision is never attempted. ++ */ + + int __elision_available attribute_hidden; + +-/* Force elision for all new locks. This is used to decide whether existing ++/* Force elision for all new locks. This is used to decide whether existing + DEFAULT locks should be automatically upgraded to elision in +- pthread_mutex_lock(). Disabled for suid programs. Only used when elision ++ pthread_mutex_lock(). Disabled for suid programs. Only used when elision + is available. */ + + int __pthread_force_elision attribute_hidden; +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-conf.h +@@ -14,7 +14,7 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + #ifndef _ELISION_CONF_H + #define _ELISION_CONF_H 1 + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-lock.c +@@ -14,7 +14,7 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + + #include + #include "pthreadP.h" +@@ -58,7 +58,7 @@ __lll_lock_elision (int *futex, short *a + if (*futex == 0) + return 0; + +- /* Lock was busy. Fall back to normal locking. ++ /* Lock was busy. Fall back to normal locking. + Could also _xend here but xabort with 0xff code + is more visible in the profiler. */ + _xabort (_ABORT_LOCK_BUSY); +@@ -69,12 +69,12 @@ __lll_lock_elision (int *futex, short *a + if ((status & _XABORT_EXPLICIT) + && _XABORT_CODE (status) == _ABORT_LOCK_BUSY) + { +- /* Right now we skip here. Better would be to wait a bit +- and retry. This likely needs some spinning. */ ++ /* Right now we skip here. Better would be to wait a bit ++ and retry. This likely needs some spinning. */ + if (*adapt_count != aconf.skip_lock_busy) + *adapt_count = aconf.skip_lock_busy; + } +- /* Internal abort. There is no chance for retry. ++ /* Internal abort. There is no chance for retry. + Use the normal locking and next time use lock. + Be careful to avoid writing to the lock. */ + else if (*adapt_count != aconf.skip_lock_internal_abort) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-timed.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-timed.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-timed.c +@@ -14,7 +14,7 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + + #include + #include +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/elision-trylock.c +@@ -14,7 +14,7 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + + #include + #include +@@ -24,14 +24,14 @@ + + #define aconf __elision_aconf + +-/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is the +- adaptation counter in the mutex. */ ++/* Try to elide a futex trylock. FUTEX is the futex variable. ADAPT_COUNT is ++ the adaptation counter in the mutex. */ + + int + __lll_trylock_elision (int *futex, short *adapt_count) + { + /* Implement POSIX semantics by forbiding nesting +- trylock. Sorry. After the abort the code is re-executed ++ trylock. Sorry. After the abort the code is re-executed + non transactional and if the lock was already locked + return an error. */ + _xabort (_ABORT_NESTED_TRYLOCK); +@@ -46,7 +46,7 @@ __lll_trylock_elision (int *futex, short + if (*futex == 0) + return 0; + +- /* Lock was busy. Fall back to normal locking. ++ /* Lock was busy. Fall back to normal locking. + Could also _xend here but xabort with 0xff code + is more visible in the profiler. */ + _xabort (_ABORT_LOCK_BUSY); +@@ -54,12 +54,12 @@ __lll_trylock_elision (int *futex, short + + if (!(status & _XABORT_RETRY)) + { +- /* Internal abort. No chance for retry. For future ++ /* Internal abort. No chance for retry. For future + locks don't try speculation for some time. */ + if (*adapt_count != aconf.skip_trylock_internal_abort) + *adapt_count = aconf.skip_trylock_internal_abort; + } +- /* Could do some retries here. */ ++ /* Could do some retries here. */ + } + else + { +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/force-elision.h +@@ -14,7 +14,7 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + + /* Check for elision on this lock without upgrading. */ + #define DO_ELISION(m) \ +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/hle.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/hle.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/hle.h +@@ -1,5 +1,5 @@ +-/* Shared RTM header. Emulate TSX intrinsics for compilers and assemblers +- that do not support the intrinsics and instructions yet. */ ++/* Shared RTM header. Emulate TSX intrinsics for compilers and assemblers ++ that do not support the intrinsics and instructions yet. */ + #ifndef _HLE_H + #define _HLE_H 1 + +@@ -28,7 +28,7 @@ + /* Official RTM intrinsics interface matching gcc/icc, but works + on older gcc compatible compilers and binutils. + We should somehow detect if the compiler supports it, because +- it may be able to generate slightly better code. */ ++ it may be able to generate slightly better code. */ + + #define _XBEGIN_STARTED (~0u) + #define _XABORT_EXPLICIT (1 << 0) +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_cond_lock.c +@@ -13,9 +13,10 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ + + /* The cond lock is not actually elided yet, but we still need to handle + already elided locks. */ + #include ++ + #include "sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_lock.c +@@ -14,7 +14,8 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ ++ + #include + #include "force-elision.h" + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_timedlock.c +@@ -14,7 +14,9 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ ++ + #include + #include "force-elision.h" ++ + #include "nptl/pthread_mutex_timedlock.c" +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/pthread_mutex_trylock.c +@@ -14,7 +14,8 @@ + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see +- . */ ++ . */ ++ + #include + #include "force-elision.h" diff --git a/SOURCES/glibc-rh841653-7.patch b/SOURCES/glibc-rh841653-7.patch new file mode 100644 index 00000000..19f3bece --- /dev/null +++ b/SOURCES/glibc-rh841653-7.patch @@ -0,0 +1,18 @@ +commit f8bdf1f0b623f05a80cb23890f165cb0cf8bd8c3 +Author: Stefan Liebler +Date: Mon May 26 11:12:44 2014 +0200 + + Fix typo in tst-mutex5 ifndef -> ifdef +Index: glibc-2.17-c758a686/nptl/tst-mutex5.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/tst-mutex5.c ++++ glibc-2.17-c758a686/nptl/tst-mutex5.c +@@ -87,7 +87,7 @@ do_test (void) + } + + /* Elided locks do not time out. */ +-#ifdef ENABLE_LOCK_ELISION ++#ifndef ENABLE_LOCK_ELISION + if (pthread_mutex_trylock (&m) == 0) + { + puts ("mutex_trylock succeeded"); diff --git a/SOURCES/glibc-rh841653-8.patch b/SOURCES/glibc-rh841653-8.patch new file mode 100644 index 00000000..89fd4d30 --- /dev/null +++ b/SOURCES/glibc-rh841653-8.patch @@ -0,0 +1,18 @@ +commit 673659263d956f45f1ce0c66900fa7f1129db74a +Author: Stefan Liebler +Date: Mon May 26 11:14:25 2014 +0200 + + Disable lock elision for PTHREAD_MUTEX_NORMAL. +Index: glibc-2.17-c758a686/nptl/pthread_mutexattr_settype.c +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/pthread_mutexattr_settype.c ++++ glibc-2.17-c758a686/nptl/pthread_mutexattr_settype.c +@@ -32,7 +32,7 @@ __pthread_mutexattr_settype (attr, kind) + + /* Cannot distinguish between DEFAULT and NORMAL. So any settype + call disables elision for now. */ +- if (kind == PTHREAD_MUTEX_DEFAULT) ++ if (kind == PTHREAD_MUTEX_NORMAL) + kind |= PTHREAD_MUTEX_NO_ELISION_NP; + + iattr = (struct pthread_mutexattr *) attr; diff --git a/SOURCES/glibc-rh841653-9.patch b/SOURCES/glibc-rh841653-9.patch new file mode 100644 index 00000000..f2592332 --- /dev/null +++ b/SOURCES/glibc-rh841653-9.patch @@ -0,0 +1,26 @@ +commit 2307e1261e7ee784afd424a46ad08d3fbed33ba3 +Author: Siddhesh Poyarekar +Date: Tue Jun 24 22:40:07 2014 +0530 + + Fix namespace violation in pthreadtypes.h (BZ #17084) + + This was causing conformtest failures on i386. + +Index: glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h +=================================================================== +--- glibc-2.17-c758a686.orig/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h ++++ glibc-2.17-c758a686/nptl/sysdeps/unix/sysv/linux/x86/bits/pthreadtypes.h +@@ -114,10 +114,10 @@ typedef union + { + short __espins; + short __elision; +-# define __spins d.__espins +-# define __elision d.__elision ++# define __spins __elision_data.__espins ++# define __elision __elision_data.__elision + # define __PTHREAD_MUTEX_HAVE_ELISION 2 +- } d; ++ } __elision_data; + __pthread_slist_t __list; + }; + #endif diff --git a/SOURCES/glibc-rh841787.patch b/SOURCES/glibc-rh841787.patch new file mode 100644 index 00000000..adcbafc4 --- /dev/null +++ b/SOURCES/glibc-rh841787.patch @@ -0,0 +1,56 @@ +Related upstream commit (this bug has been fixed upstream in a +different way): + +commit 2212c1420c92a33b0e0bd9a34938c9814a56c0f7 +Author: Andreas Schwab +Date: Thu Feb 19 15:52:08 2015 +0100 + + Simplify handling of nameserver configuration in resolver + + Remove use of ext.nsmap member of struct __res_state and always use + an identity mapping betwen the nsaddr_list array and the ext.nsaddrs + array. The fact that a nameserver has an IPv6 address is signalled by + setting nsaddr_list[].sin_family to zero. + +diff -rup glibc-2.17-c758a686/resolv/res_init.c glibc-2.17-c758a686/resolv/res_init.c +--- glibc-2.17-c758a686/resolv/res_init.c 2012-07-26 15:10:45.655638776 -0600 ++++ glibc-2.17-c758a686/resolv/res_init.c 2012-07-26 15:11:27.731423002 -0600 +@@ -314,9 +314,9 @@ __res_vinit(res_state statp, int preinit + cp++; + if ((*cp != '\0') && (*cp != '\n') + && __inet_aton(cp, &a)) { +- statp->nsaddr_list[nservall].sin_addr = a; +- statp->nsaddr_list[nservall].sin_family = AF_INET; +- statp->nsaddr_list[nservall].sin_port = ++ statp->nsaddr_list[nserv].sin_addr = a; ++ statp->nsaddr_list[nserv].sin_family = AF_INET; ++ statp->nsaddr_list[nserv].sin_port = + htons(NAMESERVER_PORT); + nserv++; + #ifdef _LIBC +diff -rup glibc-2.17-c758a686/resolv/res_send.c glibc-2.17-c758a686/resolv/res_send.c +--- glibc-2.17-c758a686/resolv/res_send.c 2010-05-04 05:27:23.000000000 -0600 ++++ glibc-2.17-c758a686/resolv/res_send.c 2012-07-26 15:34:58.398261659 -0600 +@@ -421,10 +421,10 @@ __libc_res_nsend(res_state statp, const + EXT(statp).nsmap[n] = MAXNS; + } + } +- n = statp->nscount; +- if (statp->nscount > EXT(statp).nscount) ++ n = statp->nscount - EXT(statp).nscount6; ++ if (n > EXT(statp).nscount) + for (n = EXT(statp).nscount, ns = 0; +- n < statp->nscount; n++) { ++ n < statp->nscount - EXT(statp).nscount6; n++) { + while (ns < MAXNS + && EXT(statp).nsmap[ns] != MAXNS) + ns++; +@@ -441,7 +441,7 @@ __libc_res_nsend(res_state statp, const + malloc(sizeof (struct sockaddr_in6)); + if (EXT(statp).nsaddrs[n] != NULL) { + memset (mempcpy(EXT(statp).nsaddrs[n], +- &statp->nsaddr_list[n], ++ &statp->nsaddr_list[ns], + sizeof (struct sockaddr_in)), + '\0', + sizeof (struct sockaddr_in6) diff --git a/SOURCES/glibc-rh884008.patch b/SOURCES/glibc-rh884008.patch new file mode 100644 index 00000000..35258b9c --- /dev/null +++ b/SOURCES/glibc-rh884008.patch @@ -0,0 +1,26 @@ +diff --git glibc-2.17-c758a686/nptl/tst-cleanup2.c glibc-2.17-c758a686/nptl/tst-cleanup2.c +index 5bd1609..65af0f2 100644 +--- glibc-2.17-c758a686/nptl/tst-cleanup2.c ++++ glibc-2.17-c758a686/nptl/tst-cleanup2.c +@@ -34,6 +34,12 @@ static int + do_test (void) + { + char *p = NULL; ++ /* gcc can overwrite the success written value by scheduling instructions ++ around sprintf. It is allowed to do this since according to C99 the first ++ argument of sprintf is a character array and NULL is not a valid character ++ array. Mark the return value as volatile so that it gets reloaded on ++ return. */ ++ volatile int ret = 0; + struct sigaction sa; + + sa.sa_handler = sig_handler; +@@ -50,7 +56,7 @@ do_test (void) + if (setjmp (jmpbuf)) + { + puts ("Exiting main..."); +- return 0; ++ return ret; + } + + sprintf (p, "This should segv\n"); diff --git a/SOURCES/glibc-rh892777.patch b/SOURCES/glibc-rh892777.patch new file mode 100644 index 00000000..5def5aa3 --- /dev/null +++ b/SOURCES/glibc-rh892777.patch @@ -0,0 +1,60 @@ +diff -Nru glibc-2.17-c758a686/nis/yp_xdr.c glibc-2.17-c758a686/nis/yp_xdr.c +--- glibc-2.17-c758a686/nis/yp_xdr.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/nis/yp_xdr.c 2013-04-17 15:26:50.168999686 -0400 +@@ -32,6 +32,14 @@ + #include + #include + ++/* The specification suggests 1024 as a maximum length of all fields, ++ but current linux systems usually don't use any limits. So, to stay ++ as much compatible as possible with recent linux systems we choose ++ limits large enough to avoid problems. */ ++ ++#define XDRMAXNAME 1024 ++#define XDRMAXRECORD 16 * 1024 * 1024 ++ + bool_t + xdr_ypstat (XDR *xdrs, ypstat *objp) + { +@@ -49,21 +57,21 @@ libnsl_hidden_def (xdr_ypxfrstat) + bool_t + xdr_domainname (XDR *xdrs, domainname *objp) + { +- return xdr_string (xdrs, objp, YPMAXDOMAIN); ++ return xdr_string (xdrs, objp, XDRMAXNAME); + } + libnsl_hidden_def (xdr_domainname) + + bool_t + xdr_mapname (XDR *xdrs, mapname *objp) + { +- return xdr_string (xdrs, objp, YPMAXMAP); ++ return xdr_string (xdrs, objp, XDRMAXNAME); + } + libnsl_hidden_def (xdr_mapname) + + bool_t + xdr_peername (XDR *xdrs, peername *objp) + { +- return xdr_string (xdrs, objp, YPMAXPEER); ++ return xdr_string (xdrs, objp, XDRMAXNAME); + } + libnsl_hidden_def (xdr_peername) + +@@ -71,7 +79,7 @@ bool_t + xdr_keydat (XDR *xdrs, keydat *objp) + { + return xdr_bytes (xdrs, (char **) &objp->keydat_val, +- (u_int *) &objp->keydat_len, YPMAXRECORD); ++ (u_int *) &objp->keydat_len, XDRMAXRECORD); + } + libnsl_hidden_def (xdr_keydat) + +@@ -79,7 +87,7 @@ bool_t + xdr_valdat (XDR *xdrs, valdat *objp) + { + return xdr_bytes (xdrs, (char **) &objp->valdat_val, +- (u_int *) &objp->valdat_len, YPMAXRECORD); ++ (u_int *) &objp->valdat_len, XDRMAXRECORD); + } + libnsl_hidden_def (xdr_valdat) diff --git a/SOURCES/glibc-rh905184.patch b/SOURCES/glibc-rh905184.patch new file mode 100644 index 00000000..365820f7 --- /dev/null +++ b/SOURCES/glibc-rh905184.patch @@ -0,0 +1,95 @@ +# +# Red Hat BZ: +# https://bugzilla.redhat.com/show_bug.cgi?id=905184 +# +# Sourcware BZ: +# http://sourceware.org/bugzilla/show_bug.cgi?id=15006 +# +# Upstream submission: +# http://www.sourceware.org/ml/libc-alpha/2013-02/msg00120.html +# +# ChangeLog +# +# 2013-02-07 Carlos O'Donell +# +# * sysdeps/generic/ldconfig.h: Define FLAG_ARM_LIBSF. +# * elf/cache.c (print_entry): Add FLAG_ARM_LIBSF support. +# +# ports/ChangeLog.arm +# +# 2013-02-07 Carlos O'Donell +# +# * sysdeps/unix/sysv/linux/arm/dl-cache.h +# [__ARM_PCS_VFP] (_dl_cache_check_flags): Allow plain FLAG_ELF_LIBC6. +# [!__ARM_PCS_VFP] (_dl_cache_check_flags): Likewise. +# * sysdeps/unix/sysv/linux/arm/readelflib.c (process_elf_file): +# Set FLAG_ARM_LIBSF for soft-float ABI otherwise just FLAG_ELF_LIBC6. +# +diff --git glibc-2.17-c758a686/elf/cache.c glibc-2.17-c758a686/elf/cache.c +index 9901952..699550b 100644 +--- glibc-2.17-c758a686/elf/cache.c ++++ glibc-2.17-c758a686/elf/cache.c +@@ -100,6 +100,10 @@ print_entry (const char *lib, int flag, unsigned int osversion, + case FLAG_AARCH64_LIB64: + fputs (",AArch64", stdout); + break; ++ /* Uses the ARM soft-float ABI. */ ++ case FLAG_ARM_LIBSF: ++ fputs (",soft-float", stdout); ++ break; + case 0: + break; + default: +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h +index acc4f28..504feca 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/dl-cache.h +@@ -18,12 +18,17 @@ + + #include + ++/* In order to support the transition from unmarked objects ++ to marked objects we must treat unmarked objects as ++ compatible with either FLAG_ARM_LIBHF or FLAG_ARM_LIBSF. */ + #ifdef __ARM_PCS_VFP + # define _dl_cache_check_flags(flags) \ +- ((flags) == (FLAG_ARM_LIBHF | FLAG_ELF_LIBC6)) ++ ((flags) == (FLAG_ARM_LIBHF | FLAG_ELF_LIBC6) \ ++ || (flags) == FLAG_ELF_LIBC6) + #else + # define _dl_cache_check_flags(flags) \ +- ((flags) == FLAG_ELF_LIBC6) ++ ((flags) == (FLAG_ARM_LIBSF | FLAG_ELF_LIBC6) \ ++ || (flags) == FLAG_ELF_LIBC6) + #endif + + #include_next +diff --git glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/readelflib.c glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/readelflib.c +index 81e5ccb..3efb613 100644 +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/readelflib.c ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/arm/readelflib.c +@@ -46,6 +46,12 @@ process_elf_file (const char *file_name, const char *lib, int *flag, + if (elf32_header->e_flags & EF_ARM_ABI_FLOAT_HARD) + *flag = FLAG_ARM_LIBHF|FLAG_ELF_LIBC6; + else if (elf32_header->e_flags & EF_ARM_ABI_FLOAT_SOFT) ++ *flag = FLAG_ARM_LIBSF|FLAG_ELF_LIBC6; ++ else ++ /* We must assume the unmarked objects are compatible ++ with all ABI variants. Such objects may have been ++ generated in a transitional period when the ABI ++ tags were not added to all objects. */ + *flag = FLAG_ELF_LIBC6; + } + } +diff --git glibc-2.17-c758a686/sysdeps/generic/ldconfig.h glibc-2.17-c758a686/sysdeps/generic/ldconfig.h +index 57a9a46..91190aa 100644 +--- glibc-2.17-c758a686/sysdeps/generic/ldconfig.h ++++ glibc-2.17-c758a686/sysdeps/generic/ldconfig.h +@@ -36,6 +36,7 @@ + #define FLAG_X8664_LIBX32 0x0800 + #define FLAG_ARM_LIBHF 0x0900 + #define FLAG_AARCH64_LIB64 0x0a00 ++#define FLAG_ARM_LIBSF 0x0b00 + + /* Name of auxiliary cache. */ + #define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache" diff --git a/SOURCES/glibc-rh905877.patch b/SOURCES/glibc-rh905877.patch new file mode 100644 index 00000000..556b8175 --- /dev/null +++ b/SOURCES/glibc-rh905877.patch @@ -0,0 +1,153 @@ +# +# Backported from upstream. +# +# commit a445af0bc722d620afed7683cd320c0e4c7c6059 +# Author: Andreas Schwab +# Date: Tue Jan 29 14:45:15 2013 +0100 +# +# Fix buffer overrun in regexp matcher +# +# ChangeLog/ +# 2013-02-12 Andreas Schwab +# +# [BZ #15078] +# * posix/regexec.c (extend_buffers): Add parameter min_len. +# (check_matching): Pass minimum needed length. +# (clean_state_log_if_needed): Likewise. +# (get_subexp): Likewise. +# * posix/Makefile (tests): Add bug-regex34. +# (bug-regex34-ENV): Define. +# * posix/bug-regex34.c: New file. +# +--- glibc-2.17-c758a686/posix/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/posix/Makefile 2013-03-17 15:30:13.121068666 -0400 +@@ -86,7 +86,7 @@ + tst-rfc3484-3 \ + tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \ + bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \ +- bug-getopt5 tst-getopt_long1 ++ bug-getopt5 tst-getopt_long1 bug-regex34 + xtests := bug-ga2 + ifeq (yes,$(build-shared)) + test-srcs := globtest +@@ -195,6 +195,7 @@ + bug-regex30-ENV = LOCPATH=$(common-objpfx)localedata + bug-regex32-ENV = LOCPATH=$(common-objpfx)localedata + bug-regex33-ENV = LOCPATH=$(common-objpfx)localedata ++bug-regex34-ENV = LOCPATH=$(common-objpfx)localedata + tst-rxspencer-ARGS = --utf8 rxspencer/tests + tst-rxspencer-ENV = LOCPATH=$(common-objpfx)localedata + tst-pcre-ARGS = PCRE.tests +diff --git glibc-2.17-c758a686/posix/bug-regex34.c glibc-2.17-c758a686/posix/bug-regex34.c +new file mode 100644 +index 0000000..bb3b613 +--- /dev/null ++++ glibc-2.17-c758a686/posix/bug-regex34.c +@@ -0,0 +1,46 @@ ++/* Test re_search with multi-byte characters in UTF-8. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#define _GNU_SOURCE 1 ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ struct re_pattern_buffer r; ++ /* ကျွန်ုပ်x */ ++ const char *s = "\xe1\x80\x80\xe1\x80\xbb\xe1\x80\xbd\xe1\x80\x94\xe1\x80\xba\xe1\x80\xaf\xe1\x80\x95\xe1\x80\xbax"; ++ ++ if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) ++ { ++ puts ("setlocale failed"); ++ return 1; ++ } ++ memset (&r, 0, sizeof (r)); ++ ++ re_compile_pattern ("[^x]x", 5, &r); ++ /* This was triggering a buffer overflow. */ ++ re_search (&r, s, strlen (s), 0, strlen (s), 0); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff --git glibc-2.17-c758a686/posix/regexec.c glibc-2.17-c758a686/posix/regexec.c +index 7f2de85..5ca2bf6 100644 +--- glibc-2.17-c758a686/posix/regexec.c ++++ glibc-2.17-c758a686/posix/regexec.c +@@ -197,7 +197,7 @@ static int group_nodes_into_DFAstates (const re_dfa_t *dfa, + static int check_node_accept (const re_match_context_t *mctx, + const re_token_t *node, int idx) + internal_function; +-static reg_errcode_t extend_buffers (re_match_context_t *mctx) ++static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len) + internal_function; + + /* Entry point for POSIX code. */ +@@ -1160,7 +1160,7 @@ check_matching (re_match_context_t *mctx, int fl_longest_match, + || (BE (next_char_idx >= mctx->input.valid_len, 0) + && mctx->input.valid_len < mctx->input.len)) + { +- err = extend_buffers (mctx); ++ err = extend_buffers (mctx, next_char_idx + 1); + if (BE (err != REG_NOERROR, 0)) + { + assert (err == REG_ESPACE); +@@ -1738,7 +1738,7 @@ clean_state_log_if_needed (re_match_context_t *mctx, int next_state_log_idx) + && mctx->input.valid_len < mctx->input.len)) + { + reg_errcode_t err; +- err = extend_buffers (mctx); ++ err = extend_buffers (mctx, next_state_log_idx + 1); + if (BE (err != REG_NOERROR, 0)) + return err; + } +@@ -2792,7 +2792,7 @@ get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx) + if (bkref_str_off >= mctx->input.len) + break; + +- err = extend_buffers (mctx); ++ err = extend_buffers (mctx, bkref_str_off + 1); + if (BE (err != REG_NOERROR, 0)) + return err; + +@@ -4102,7 +4102,7 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node, + + static reg_errcode_t + internal_function __attribute_warn_unused_result__ +-extend_buffers (re_match_context_t *mctx) ++extend_buffers (re_match_context_t *mctx, int min_len) + { + reg_errcode_t ret; + re_string_t *pstr = &mctx->input; +@@ -4111,8 +4111,10 @@ extend_buffers (re_match_context_t *mctx) + if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0)) + return REG_ESPACE; + +- /* Double the lengthes of the buffers. */ +- ret = re_string_realloc_buffers (pstr, MIN (pstr->len, pstr->bufs_len * 2)); ++ /* Double the lengthes of the buffers, but allocate at least MIN_LEN. */ ++ ret = re_string_realloc_buffers (pstr, ++ MAX (min_len, ++ MIN (pstr->len, pstr->bufs_len * 2))); + if (BE (ret != REG_NOERROR, 0)) + return ret; diff --git a/SOURCES/glibc-rh906468-1.patch b/SOURCES/glibc-rh906468-1.patch new file mode 100644 index 00000000..4dd529eb --- /dev/null +++ b/SOURCES/glibc-rh906468-1.patch @@ -0,0 +1,541 @@ +Backport of these upstream commits: + +commit 29d794863cd6e03115d3670707cc873a9965ba92 +Author: Florian Weimer +Date: Thu Apr 14 09:17:02 2016 +0200 + + malloc: Run fork handler as late as possible [BZ #19431] + + Previously, a thread M invoking fork would acquire locks in this order: + + (M1) malloc arena locks (in the registered fork handler) + (M2) libio list lock + + A thread F invoking flush (NULL) would acquire locks in this order: + + (F1) libio list lock + (F2) individual _IO_FILE locks + + A thread G running getdelim would use this order: + + (G1) _IO_FILE lock + (G2) malloc arena lock + + After executing (M1), (F1), (G1), none of the threads can make progress. + + This commit changes the fork lock order to: + + (M'1) libio list lock + (M'2) malloc arena locks + + It explicitly encodes the lock order in the implementations of fork, + and does not rely on the registration order, thus avoiding the deadlock. + +commit 186fe877f3df0b84d57dfbf0386f6332c6aa69bc +Author: Florian Weimer +Date: Thu Apr 14 12:53:03 2016 +0200 + + malloc: Add missing internal_function attributes on function definitions + + Fixes build on i386 after commit 29d794863cd6e03115d3670707cc873a9965ba92. + +Index: b/malloc/Makefile +=================================================================== +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -28,7 +28,7 @@ tests := mallocbug tst-malloc tst-valloc + tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \ + tst-malloc-usable \ + tst-malloc-backtrace tst-malloc-thread-exit \ +- tst-malloc-thread-fail ++ tst-malloc-thread-fail tst-malloc-fork-deadlock + test-srcs = tst-mtrace + + routines = malloc morecore mcheck mtrace obstack +@@ -49,6 +49,7 @@ $(objpfx)tst-malloc-thread-fail: $(commo + $(common-objpfx)nptl/libpthread_nonshared.a + $(objpfx)tst-malloc-thread-exit: $(common-objpfx)nptl/libpthread.so \ + $(common-objpfx)nptl/libpthread_nonshared.a ++$(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library) + + # These should be removed by `make clean'. + extra-objs = mcheck-init.o libmcheck.a +Index: b/malloc/arena.c +=================================================================== +--- a/malloc/arena.c ++++ b/malloc/arena.c +@@ -162,10 +162,6 @@ static void (*save_free_hook) + const __malloc_ptr_t); + static void* save_arena; + +-#ifdef ATFORK_MEM +-ATFORK_MEM; +-#endif +- + /* Magic value for the thread-specific arena pointer when + malloc_atfork() is in use. */ + +@@ -228,14 +224,15 @@ free_atfork(void* mem, const void *calle + /* Counter for number of times the list is locked by the same thread. */ + static unsigned int atfork_recursive_cntr; + +-/* The following two functions are registered via thread_atfork() to +- make sure that the mutexes remain in a consistent state in the +- fork()ed version of a thread. Also adapt the malloc and free hooks +- temporarily, because the `atfork' handler mechanism may use +- malloc/free internally (e.g. in LinuxThreads). */ ++/* The following three functions are called around fork from a ++ multi-threaded process. We do not use the general fork handler ++ mechanism to make sure that our handlers are the last ones being ++ called, so that other fork handlers can use the malloc ++ subsystem. */ + +-static void +-ptmalloc_lock_all (void) ++void ++internal_function ++__malloc_fork_lock_parent (void) + { + mstate ar_ptr; + +@@ -243,7 +240,7 @@ ptmalloc_lock_all (void) + return; + + /* We do not acquire free_list_lock here because we completely +- reconstruct free_list in ptmalloc_unlock_all2. */ ++ reconstruct free_list in __malloc_fork_unlock_child. */ + + if (mutex_trylock(&list_lock)) + { +@@ -268,7 +265,7 @@ ptmalloc_lock_all (void) + __free_hook = free_atfork; + /* Only the current thread may perform malloc/free calls now. + save_arena will be reattached to the current thread, in +- ptmalloc_lock_all, so save_arena->attached_threads is not ++ __malloc_fork_lock_parent, so save_arena->attached_threads is not + updated. */ + tsd_getspecific(arena_key, save_arena); + tsd_setspecific(arena_key, ATFORK_ARENA_PTR); +@@ -276,8 +273,9 @@ ptmalloc_lock_all (void) + ++atfork_recursive_cntr; + } + +-static void +-ptmalloc_unlock_all (void) ++void ++internal_function ++__malloc_fork_unlock_parent (void) + { + mstate ar_ptr; + +@@ -286,8 +284,8 @@ ptmalloc_unlock_all (void) + if (--atfork_recursive_cntr != 0) + return; + /* Replace ATFORK_ARENA_PTR with save_arena. +- save_arena->attached_threads was not changed in ptmalloc_lock_all +- and is still correct. */ ++ save_arena->attached_threads was not changed in ++ __malloc_fork_lock_parent and is still correct. */ + tsd_setspecific(arena_key, save_arena); + __malloc_hook = save_malloc_hook; + __free_hook = save_free_hook; +@@ -299,15 +297,9 @@ ptmalloc_unlock_all (void) + (void)mutex_unlock(&list_lock); + } + +-# ifdef __linux__ +- +-/* In NPTL, unlocking a mutex in the child process after a +- fork() is currently unsafe, whereas re-initializing it is safe and +- does not leak resources. Therefore, a special atfork handler is +- installed for the child. */ +- +-static void +-ptmalloc_unlock_all2 (void) ++void ++internal_function ++__malloc_fork_unlock_child (void) + { + mstate ar_ptr; + +@@ -338,12 +330,6 @@ ptmalloc_unlock_all2 (void) + atfork_recursive_cntr = 0; + } + +-# else +- +-# define ptmalloc_unlock_all2 ptmalloc_unlock_all +- +-# endif +- + #endif /* !NO_THREADS */ + + /* Initialization routine. */ +@@ -413,7 +399,6 @@ ptmalloc_init (void) + + tsd_key_create(&arena_key, NULL); + tsd_setspecific(arena_key, (void *)&main_arena); +- thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2); + const char *s = NULL; + if (__builtin_expect (_environ != NULL, 1)) + { +@@ -487,12 +472,6 @@ ptmalloc_init (void) + __malloc_initialized = 1; + } + +-/* There are platforms (e.g. Hurd) with a link-time hook mechanism. */ +-#ifdef thread_atfork_static +-thread_atfork_static(ptmalloc_lock_all, ptmalloc_unlock_all, \ +- ptmalloc_unlock_all2) +-#endif +- + + + /* Managing heaps and arenas (for concurrent threads) */ +@@ -827,7 +806,8 @@ _int_new_arena(size_t size) + limit is reached). At this point, some arena has to be attached + to two threads. We could acquire the arena lock before list_lock + to make it less likely that reused_arena picks this new arena, +- but this could result in a deadlock with ptmalloc_lock_all. */ ++ but this could result in a deadlock with ++ __malloc_fork_lock_parent. */ + + (void) mutex_lock (&a->mutex); + +Index: b/malloc/malloc-internal.h +=================================================================== +--- /dev/null ++++ b/malloc/malloc-internal.h +@@ -0,0 +1,32 @@ ++/* Internal declarations for malloc, for use within libc. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#ifndef _MALLOC_PRIVATE_H ++#define _MALLOC_PRIVATE_H ++ ++/* Called in the parent process before a fork. */ ++void __malloc_fork_lock_parent (void) internal_function attribute_hidden; ++ ++/* Called in the parent process after a fork. */ ++void __malloc_fork_unlock_parent (void) internal_function attribute_hidden; ++ ++/* Called in the child process after a fork. */ ++void __malloc_fork_unlock_child (void) internal_function attribute_hidden; ++ ++ ++#endif /* _MALLOC_PRIVATE_H */ +Index: b/malloc/malloc.c +=================================================================== +--- a/malloc/malloc.c ++++ b/malloc/malloc.c +@@ -291,6 +291,7 @@ __malloc_assert (const char *assertion, + } + #endif + ++#include + + /* + INTERNAL_SIZE_T is the word-size used for internal bookkeeping +Index: b/malloc/tst-malloc-fork-deadlock.c +=================================================================== +--- /dev/null ++++ b/malloc/tst-malloc-fork-deadlock.c +@@ -0,0 +1,220 @@ ++/* Test concurrent fork, getline, and fflush (NULL). ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int do_test (void); ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++enum { ++ /* Number of threads which call fork. */ ++ fork_thread_count = 4, ++ /* Number of threads which call getline (and, indirectly, ++ malloc). */ ++ read_thread_count = 8, ++}; ++ ++static bool termination_requested; ++ ++static void * ++fork_thread_function (void *closure) ++{ ++ while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED)) ++ { ++ pid_t pid = fork (); ++ if (pid < 0) ++ { ++ printf ("error: fork: %m\n"); ++ abort (); ++ } ++ else if (pid == 0) ++ _exit (17); ++ ++ int status; ++ if (waitpid (pid, &status, 0) < 0) ++ { ++ printf ("error: waitpid: %m\n"); ++ abort (); ++ } ++ if (!WIFEXITED (status) || WEXITSTATUS (status) != 17) ++ { ++ printf ("error: waitpid returned invalid status: %d\n", status); ++ abort (); ++ } ++ } ++ return NULL; ++} ++ ++static char *file_to_read; ++ ++static void * ++read_thread_function (void *closure) ++{ ++ FILE *f = fopen (file_to_read, "r"); ++ if (f == NULL) ++ { ++ printf ("error: fopen (%s): %m\n", file_to_read); ++ abort (); ++ } ++ ++ while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED)) ++ { ++ rewind (f); ++ char *line = NULL; ++ size_t line_allocated = 0; ++ ssize_t ret = getline (&line, &line_allocated, f); ++ if (ret < 0) ++ { ++ printf ("error: getline: %m\n"); ++ abort (); ++ } ++ free (line); ++ } ++ fclose (f); ++ ++ return NULL; ++} ++ ++static void * ++flushall_thread_function (void *closure) ++{ ++ while (!__atomic_load_n (&termination_requested, __ATOMIC_RELAXED)) ++ if (fflush (NULL) != 0) ++ { ++ printf ("error: fflush (NULL): %m\n"); ++ abort (); ++ } ++ return NULL; ++} ++ ++static void ++create_threads (pthread_t *threads, size_t count, void *(*func) (void *)) ++{ ++ for (size_t i = 0; i < count; ++i) ++ { ++ int ret = pthread_create (threads + i, NULL, func, NULL); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_create: %m\n"); ++ abort (); ++ } ++ } ++} ++ ++static void ++join_threads (pthread_t *threads, size_t count) ++{ ++ for (size_t i = 0; i < count; ++i) ++ { ++ int ret = pthread_join (threads[i], NULL); ++ if (ret != 0) ++ { ++ errno = ret; ++ printf ("error: pthread_join: %m\n"); ++ abort (); ++ } ++ } ++} ++ ++/* Create a file which consists of a single long line, and assigns ++ file_to_read. The hope is that this triggers an allocation in ++ getline which needs a lock. */ ++static void ++create_file_with_large_line (void) ++{ ++ int fd = create_temp_file ("bug19431-large-line", &file_to_read); ++ if (fd < 0) ++ { ++ printf ("error: create_temp_file: %m\n"); ++ abort (); ++ } ++ FILE *f = fdopen (fd, "w+"); ++ if (f == NULL) ++ { ++ printf ("error: fdopen: %m\n"); ++ abort (); ++ } ++ for (int i = 0; i < 50000; ++i) ++ fputc ('x', f); ++ fputc ('\n', f); ++ if (ferror (f)) ++ { ++ printf ("error: fputc: %m\n"); ++ abort (); ++ } ++ if (fclose (f) != 0) ++ { ++ printf ("error: fclose: %m\n"); ++ abort (); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ /* Make sure that we do not exceed the arena limit with the number ++ of threads we configured. */ ++ if (mallopt (M_ARENA_MAX, 400) == 0) ++ { ++ printf ("error: mallopt (M_ARENA_MAX) failed\n"); ++ return 1; ++ } ++ ++ /* Leave some room for shutting down all threads gracefully. */ ++ int timeout = 3; ++ if (timeout > TIMEOUT) ++ timeout = TIMEOUT - 1; ++ ++ create_file_with_large_line (); ++ ++ pthread_t fork_threads[fork_thread_count]; ++ create_threads (fork_threads, fork_thread_count, fork_thread_function); ++ pthread_t read_threads[read_thread_count]; ++ create_threads (read_threads, read_thread_count, read_thread_function); ++ pthread_t flushall_threads[1]; ++ create_threads (flushall_threads, 1, flushall_thread_function); ++ ++ struct timespec ts = {timeout, 0}; ++ if (nanosleep (&ts, NULL)) ++ { ++ printf ("error: error: nanosleep: %m\n"); ++ abort (); ++ } ++ ++ __atomic_store_n (&termination_requested, true, __ATOMIC_RELAXED); ++ ++ join_threads (flushall_threads, 1); ++ join_threads (read_threads, read_thread_count); ++ join_threads (fork_threads, fork_thread_count); ++ ++ free (file_to_read); ++ ++ return 0; ++} +Index: b/manual/memory.texi +=================================================================== +--- a/manual/memory.texi ++++ b/manual/memory.texi +@@ -1055,14 +1055,6 @@ systems that do not support @w{ISO C11}. + @c _dl_addr_inside_object ok + @c determine_info ok + @c __rtld_lock_unlock_recursive (dl_load_lock) @aculock +-@c thread_atfork @asulock @aculock @acsfd @acsmem +-@c __register_atfork @asulock @aculock @acsfd @acsmem +-@c lll_lock (__fork_lock) @asulock @aculock +-@c fork_handler_alloc @asulock @aculock @acsfd @acsmem +-@c calloc dup @asulock @aculock @acsfd @acsmem +-@c __linkin_atfork ok +-@c catomic_compare_and_exchange_bool_acq ok +-@c lll_unlock (__fork_lock) @aculock + @c *_environ @mtsenv + @c next_env_entry ok + @c strcspn dup ok +Index: b/nptl/sysdeps/unix/sysv/linux/fork.c +=================================================================== +--- a/nptl/sysdeps/unix/sysv/linux/fork.c ++++ b/nptl/sysdeps/unix/sysv/linux/fork.c +@@ -29,7 +29,7 @@ + #include + #include + #include +- ++#include + + unsigned long int *__fork_generation_pointer; + +@@ -116,6 +116,11 @@ __libc_fork (void) + + _IO_list_lock (); + ++ /* Acquire malloc locks. This needs to come last because fork ++ handlers may use malloc, and the libio list lock has an indirect ++ malloc dependency as well (via the getdelim function). */ ++ __malloc_fork_lock_parent (); ++ + #ifndef NDEBUG + pid_t ppid = THREAD_GETMEM (THREAD_SELF, tid); + #endif +@@ -172,6 +177,9 @@ __libc_fork (void) + # endif + #endif + ++ /* Release malloc locks. */ ++ __malloc_fork_unlock_child (); ++ + /* Reset the file list. These are recursive mutexes. */ + fresetlockfiles (); + +@@ -213,6 +221,9 @@ __libc_fork (void) + /* Restore the PID value. */ + THREAD_SETMEM (THREAD_SELF, pid, parentpid); + ++ /* Release malloc locks, parent process variant. */ ++ __malloc_fork_unlock_parent (); ++ + /* We execute this even if the 'fork' call failed. */ + _IO_list_unlock (); diff --git a/SOURCES/glibc-rh906468-2.patch b/SOURCES/glibc-rh906468-2.patch new file mode 100644 index 00000000..fefa7f15 --- /dev/null +++ b/SOURCES/glibc-rh906468-2.patch @@ -0,0 +1,816 @@ +Based on the following upstream commit: + +commit ef4f97648dc95849e417dd3e6328165de4c22185 +Author: Florian Weimer +Date: Fri Aug 26 22:40:27 2016 +0200 + + malloc: Simplify static malloc interposition [BZ #20432] + + Existing interposed mallocs do not define the glibc-internal + fork callbacks (and they should not), so statically interposed + mallocs lead to link failures because the strong reference from + fork pulls in glibc's malloc, resulting in multiple definitions + of malloc-related symbols. + +Adjustments: __libc_memalign is defined. is +included because libsupport provides definitions of xthread_* +functions, but not our version of the test skeleton. + +diff --git a/include/libc-symbols.h b/include/libc-symbols.h +index 836fec8c0681ae49..0f47900922d4099b 100644 +--- a/include/libc-symbols.h ++++ b/include/libc-symbols.h +@@ -119,6 +119,21 @@ + # define weak_extern(symbol) _weak_extern (weak symbol) + # define _weak_extern(expr) _Pragma (#expr) + ++/* In shared builds, the expression call_function_static_weak ++ (FUNCTION-SYMBOL, ARGUMENTS) invokes FUNCTION-SYMBOL (an ++ identifier) unconditionally, with the (potentially empty) argument ++ list ARGUMENTS. In static builds, if FUNCTION-SYMBOL has a ++ definition, the function is invoked as before; if FUNCTION-SYMBOL ++ is NULL, no call is performed. */ ++# ifdef SHARED ++# define call_function_static_weak(func, ...) func (__VA_ARGS__) ++# else /* !SHARED */ ++# define call_function_static_weak(func, ...) \ ++ ({ \ ++ extern __typeof__ (func) func weak_function; \ ++ (func != NULL ? func (__VA_ARGS__) : (void)0); \ ++ }) ++# endif + + #else /* __ASSEMBLER__ */ + +diff --git a/malloc/Makefile b/malloc/Makefile +index bb7f455f79ea0be2..71883c2055b8067c 100644 +--- a/malloc/Makefile ++++ b/malloc/Makefile +@@ -28,7 +28,16 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ + tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 \ + tst-malloc-usable \ + tst-malloc-backtrace tst-malloc-thread-exit \ +- tst-malloc-thread-fail tst-malloc-fork-deadlock ++ tst-malloc-thread-fail tst-malloc-fork-deadlock \ ++ tst-interpose-nothread \ ++ tst-interpose-thread \ ++ tst-interpose-static-nothread \ ++ tst-interpose-static-thread \ ++ ++tests-static := \ ++ tst-interpose-static-nothread \ ++ tst-interpose-static-thread \ ++ + test-srcs = tst-mtrace + + routines = malloc morecore mcheck mtrace obstack +@@ -40,6 +49,15 @@ non-lib.a := libmcheck.a + extra-libs = libmemusage + extra-libs-others = $(extra-libs) + ++# Helper objects for some tests. ++extra-tests-objs += \ ++ tst-interpose-aux-nothread.o \ ++ tst-interpose-aux-thread.o \ ++ ++test-extras = \ ++ tst-interpose-aux-nothread \ ++ tst-interpose-aux-thread \ ++ + libmemusage-routines = memusage + libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes)) + +@@ -157,6 +175,13 @@ $(objpfx)libmemusage.so: $(common-objpfx)dlfcn/libdl.so + # Extra dependencies + $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c + ++$(objpfx)tst-interpose-nothread: $(objpfx)tst-interpose-aux-nothread.o ++$(objpfx)tst-interpose-thread: \ ++ $(objpfx)tst-interpose-aux-thread.o $(shared-thread-library) ++$(objpfx)tst-interpose-static-nothread: $(objpfx)tst-interpose-aux-nothread.o ++$(objpfx)tst-interpose-static-thread: \ ++ $(objpfx)tst-interpose-aux-thread.o $(static-thread-library) ++ + # Compile the tests with a flag which suppresses the mallopt call in + # the test skeleton. + $(tests:%=$(objpfx)%.o): CPPFLAGS += -DTEST_NO_MALLOPT +diff --git a/malloc/tst-interpose-aux-nothread.c b/malloc/tst-interpose-aux-nothread.c +new file mode 100644 +index 0000000000000000..0eae66fa6c5260e5 +--- /dev/null ++++ b/malloc/tst-interpose-aux-nothread.c +@@ -0,0 +1,20 @@ ++/* Interposed malloc, version without threading support. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#define INTERPOSE_THREADS 0 ++#include "tst-interpose-aux.c" +diff --git a/malloc/tst-interpose-aux-thread.c b/malloc/tst-interpose-aux-thread.c +new file mode 100644 +index 0000000000000000..354e4d8ed1d4f9c1 +--- /dev/null ++++ b/malloc/tst-interpose-aux-thread.c +@@ -0,0 +1,20 @@ ++/* Interposed malloc, version with threading support. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#define INTERPOSE_THREADS 1 ++#include "tst-interpose-aux.c" +diff --git a/malloc/tst-interpose-aux.c b/malloc/tst-interpose-aux.c +new file mode 100644 +index 0000000000000000..5e8a9b9f5262e363 +--- /dev/null ++++ b/malloc/tst-interpose-aux.c +@@ -0,0 +1,283 @@ ++/* Minimal malloc implementation for interposition tests. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include "tst-interpose-aux.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if INTERPOSE_THREADS ++#include ++#endif ++ ++/* Print the error message and terminate the process with status 1. */ ++__attribute__ ((noreturn)) ++__attribute__ ((format (printf, 1, 2))) ++static void * ++fail (const char *format, ...) ++{ ++ /* This assumes that vsnprintf will not call malloc. It does not do ++ so for the format strings we use. */ ++ char message[4096]; ++ va_list ap; ++ va_start (ap, format); ++ vsnprintf (message, sizeof (message), format, ap); ++ va_end (ap); ++ ++ enum { count = 3 }; ++ struct iovec iov[count]; ++ ++ iov[0].iov_base = (char *) "error: "; ++ iov[1].iov_base = (char *) message; ++ iov[2].iov_base = (char *) "\n"; ++ ++ for (int i = 0; i < count; ++i) ++ iov[i].iov_len = strlen (iov[i].iov_base); ++ ++ int unused __attribute__ ((unused)); ++ unused = writev (STDOUT_FILENO, iov, count); ++ _exit (1); ++} ++ ++#if INTERPOSE_THREADS ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++#endif ++ ++static void ++lock (void) ++{ ++#if INTERPOSE_THREADS ++ int ret = pthread_mutex_lock (&mutex); ++ if (ret != 0) ++ { ++ errno = ret; ++ fail ("pthread_mutex_lock: %m"); ++ } ++#endif ++} ++ ++static void ++unlock (void) ++{ ++#if INTERPOSE_THREADS ++ int ret = pthread_mutex_unlock (&mutex); ++ if (ret != 0) ++ { ++ errno = ret; ++ fail ("pthread_mutex_unlock: %m"); ++ } ++#endif ++} ++ ++struct __attribute__ ((aligned (__alignof__ (max_align_t)))) allocation_header ++{ ++ size_t allocation_index; ++ size_t allocation_size; ++}; ++ ++/* Array of known allocations, to track invalid frees. */ ++enum { max_allocations = 65536 }; ++static struct allocation_header *allocations[max_allocations]; ++static size_t allocation_index; ++static size_t deallocation_count; ++ ++/* Sanity check for successful malloc interposition. */ ++__attribute__ ((destructor)) ++static void ++check_for_allocations (void) ++{ ++ if (allocation_index == 0) ++ { ++ /* Make sure that malloc is called at least once from libc. */ ++ void *volatile ptr = strdup ("ptr"); ++ free (ptr); ++ /* Compiler barrier. The strdup function calls malloc, which ++ updates allocation_index, but strdup is marked __THROW, so ++ the compiler could optimize away the reload. */ ++ __asm__ volatile ("" ::: "memory"); ++ /* If the allocation count is still zero, it means we did not ++ interpose malloc successfully. */ ++ if (allocation_index == 0) ++ fail ("malloc does not seem to have been interposed"); ++ } ++} ++ ++static struct allocation_header *get_header (const char *op, void *ptr) ++{ ++ struct allocation_header *header = ((struct allocation_header *) ptr) - 1; ++ if (header->allocation_index >= allocation_index) ++ fail ("%s: %p: invalid allocation index: %zu (not less than %zu)", ++ op, ptr, header->allocation_index, allocation_index); ++ if (allocations[header->allocation_index] != header) ++ fail ("%s: %p: allocation pointer does not point to header, but %p", ++ op, ptr, allocations[header->allocation_index]); ++ return header; ++} ++ ++/* Internal helper functions. Those must be called while the lock is ++ acquired. */ ++ ++static void * ++malloc_internal (size_t size) ++{ ++ if (allocation_index == max_allocations) ++ { ++ errno = ENOMEM; ++ return NULL; ++ } ++ size_t allocation_size = size + sizeof (struct allocation_header); ++ if (allocation_size < size) ++ { ++ errno = ENOMEM; ++ return NULL; ++ } ++ ++ size_t index = allocation_index++; ++ void *result = mmap (NULL, allocation_size, PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ++ if (result == MAP_FAILED) ++ return NULL; ++ allocations[index] = result; ++ *allocations[index] = (struct allocation_header) ++ { ++ .allocation_index = index, ++ .allocation_size = allocation_size ++ }; ++ return allocations[index] + 1; ++} ++ ++static void ++free_internal (const char *op, struct allocation_header *header) ++{ ++ size_t index = header->allocation_index; ++ int result = mprotect (header, header->allocation_size, PROT_NONE); ++ if (result != 0) ++ fail ("%s: mprotect (%p, %zu): %m", op, header, header->allocation_size); ++ /* Catch double-free issues. */ ++ allocations[index] = NULL; ++ ++deallocation_count; ++} ++ ++static void * ++realloc_internal (void *ptr, size_t new_size) ++{ ++ struct allocation_header *header = get_header ("realloc", ptr); ++ size_t old_size = header->allocation_size - sizeof (struct allocation_header); ++ if (old_size >= new_size) ++ return ptr; ++ ++ void *newptr = malloc_internal (new_size); ++ if (newptr == NULL) ++ return NULL; ++ memcpy (newptr, ptr, old_size); ++ free_internal ("realloc", header); ++ return newptr; ++} ++ ++/* Public interfaces. These functions must perform locking. */ ++ ++size_t ++malloc_allocation_count (void) ++{ ++ lock (); ++ size_t count = allocation_index; ++ unlock (); ++ return count; ++} ++ ++size_t ++malloc_deallocation_count (void) ++{ ++ lock (); ++ size_t count = deallocation_count; ++ unlock (); ++ return count; ++} ++ ++void * ++malloc (size_t size) ++{ ++ lock (); ++ void *result = malloc_internal (size); ++ unlock (); ++ return result; ++} ++ ++void ++free (void *ptr) ++{ ++ if (ptr == NULL) ++ return; ++ lock (); ++ struct allocation_header *header = get_header ("free", ptr); ++ free_internal ("free", header); ++ unlock (); ++} ++ ++void * ++calloc (size_t a, size_t b) ++{ ++ if (b > 0 && a > SIZE_MAX / b) ++ { ++ errno = ENOMEM; ++ return NULL; ++ } ++ lock (); ++ /* malloc_internal uses mmap, so the memory is zeroed. */ ++ void *result = malloc_internal (a * b); ++ unlock (); ++ return result; ++} ++ ++void * ++realloc (void *ptr, size_t n) ++{ ++ if (n ==0) ++ { ++ free (ptr); ++ return NULL; ++ } ++ else if (ptr == NULL) ++ return malloc (n); ++ else ++ { ++ lock (); ++ void *result = realloc_internal (ptr, n); ++ unlock (); ++ return result; ++ } ++} ++ ++/* The dyanmic linker still uses __libc_memalign because we have not ++ backported the fix for swbz#17730. It does not normally request ++ large alignments, so we can call malloc directly. */ ++void * ++__libc_memalign (size_t alignment, size_t size) ++{ ++ void *result = malloc (size); ++ if (((uintptr_t) result % alignment) != 0) ++ fail ("could not fulfill requested alignment %zu", alignment); ++ return result; ++} +diff --git a/malloc/tst-interpose-aux.h b/malloc/tst-interpose-aux.h +new file mode 100644 +index 0000000000000000..2fb22d312a65bff8 +--- /dev/null ++++ b/malloc/tst-interpose-aux.h +@@ -0,0 +1,30 @@ ++/* Statistics interface for the minimal malloc implementation. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#ifndef TST_INTERPOSE_AUX_H ++#define TST_INTERPOSE_AUX_H ++ ++#include ++ ++/* Return the number of allocations performed. */ ++size_t malloc_allocation_count (void); ++ ++/* Return the number of deallocations performed. */ ++size_t malloc_deallocation_count (void); ++ ++#endif /* TST_INTERPOSE_AUX_H */ +diff --git a/malloc/tst-interpose-nothread.c b/malloc/tst-interpose-nothread.c +new file mode 100644 +index 0000000000000000..9acb57209899c8ee +--- /dev/null ++++ b/malloc/tst-interpose-nothread.c +@@ -0,0 +1,20 @@ ++/* Malloc interposition test, dynamically-linked version without threads. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#define INTERPOSE_THREADS 0 ++#include "tst-interpose-skeleton.c" +diff --git a/malloc/tst-interpose-skeleton.c b/malloc/tst-interpose-skeleton.c +new file mode 100644 +index 0000000000000000..418e82465bc719d7 +--- /dev/null ++++ b/malloc/tst-interpose-skeleton.c +@@ -0,0 +1,204 @@ ++/* Test driver for malloc interposition tests. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include ++#include ++#include ++#include ++ ++#if INTERPOSE_THREADS ++#include ++#endif ++ ++static int do_test (void); ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" ++ ++/* Fills BUFFER with a test string. */ ++static void ++line_string (int number, char *buffer, size_t length) ++{ ++ for (size_t i = 0; i < length - 2; ++i) ++ buffer[i] = 'A' + ((number + i) % 26); ++ buffer[length - 2] = '\n'; ++ buffer[length - 1] = '\0'; ++} ++ ++/* Perform the tests. */ ++static void * ++run_tests (void *closure) ++{ ++ char *temp_file_path; ++ int fd = create_temp_file ("tst-malloc-interpose", &temp_file_path); ++ if (fd < 0) ++ _exit (1); ++ ++ /* Line lengths excluding the line terminator. */ ++ static const int line_lengths[] = { 0, 45, 80, 2, 8201, 0, 17, -1 }; ++ ++ /* Fill the test file with data. */ ++ { ++ FILE *fp = fdopen (fd, "w"); ++ for (int lineno = 0; line_lengths[lineno] >= 0; ++lineno) ++ { ++ char buffer[line_lengths[lineno] + 2]; ++ line_string (lineno, buffer, sizeof (buffer)); ++ fprintf (fp, "%s", buffer); ++ } ++ ++ if (ferror (fp)) ++ { ++ printf ("error: fprintf: %m\n"); ++ _exit (1); ++ } ++ if (fclose (fp) != 0) ++ { ++ printf ("error: fclose: %m\n"); ++ _exit (1); ++ } ++ } ++ ++ /* Read the test file. This tests libc-internal allocation with ++ realloc. */ ++ { ++ FILE *fp = fopen (temp_file_path, "r"); ++ ++ char *actual = NULL; ++ size_t actual_size = 0; ++ for (int lineno = 0; ; ++lineno) ++ { ++ errno = 0; ++ ssize_t result = getline (&actual, &actual_size, fp); ++ if (result == 0) ++ { ++ printf ("error: invalid return value 0 from getline\n"); ++ _exit (1); ++ } ++ if (result < 0 && errno != 0) ++ { ++ printf ("error: getline: %m\n"); ++ _exit (1); ++ } ++ if (result < 0 && line_lengths[lineno] >= 0) ++ { ++ printf ("error: unexpected end of file after line %d\n", lineno); ++ _exit (1); ++ } ++ if (result > 0 && line_lengths[lineno] < 0) ++ { ++ printf ("error: no end of file after line %d\n", lineno); ++ _exit (1); ++ } ++ if (result == -1 && line_lengths[lineno] == -1) ++ /* End of file reached as expected. */ ++ break; ++ ++ if (result != line_lengths[lineno] + 1) ++ { ++ printf ("error: line length mismatch: expected %d, got %zd\n", ++ line_lengths[lineno], result); ++ _exit (1); ++ } ++ ++ char expected[line_lengths[lineno] + 2]; ++ line_string (lineno, expected, sizeof (expected)); ++ if (strcmp (actual, expected) != 0) ++ { ++ printf ("error: line mismatch\n"); ++ printf ("error: expected: [[%s]]\n", expected); ++ printf ("error: actual: [[%s]]\n", actual); ++ _exit (1); ++ } ++ } ++ ++ if (fclose (fp) != 0) ++ { ++ printf ("error: fclose (after reading): %m\n"); ++ _exit (1); ++ } ++ } ++ ++ free (temp_file_path); ++ ++ /* Make sure that fork is working. */ ++ pid_t pid = fork (); ++ if (pid == -1) ++ { ++ printf ("error: fork: %m\n"); ++ _exit (1); ++ } ++ enum { exit_code = 55 }; ++ if (pid == 0) ++ _exit (exit_code); ++ int status; ++ int ret = waitpid (pid, &status, 0); ++ if (ret < 0) ++ { ++ printf ("error: waitpid: %m\n"); ++ _exit (1); ++ } ++ if (!WIFEXITED (status) || WEXITSTATUS (status) != exit_code) ++ { ++ printf ("error: unexpected exit status from child process: %d\n", ++ status); ++ _exit (1); ++ } ++ ++ return NULL; ++} ++ ++/* This is used to detect if malloc has not been successfully ++ interposed. The interposed malloc does not use brk/sbrk. */ ++static void *initial_brk; ++__attribute__ ((constructor)) ++static void ++set_initial_brk (void) ++{ ++ initial_brk = sbrk (0); ++} ++ ++/* Terminate the process if the break value has been changed. */ ++__attribute__ ((destructor)) ++static void ++check_brk (void) ++{ ++ void *current = sbrk (0); ++ if (current != initial_brk) ++ { ++ printf ("error: brk changed from %p to %p; no interposition?\n", ++ initial_brk, current); ++ _exit (1); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ check_brk (); ++ ++#if INTERPOSE_THREADS ++ pthread_t thr = xpthread_create (NULL, run_tests, NULL); ++ xpthread_join (thr); ++#else ++ run_tests (NULL); ++#endif ++ ++ check_brk (); ++ ++ return 0; ++} +diff --git a/malloc/tst-interpose-static-nothread.c b/malloc/tst-interpose-static-nothread.c +new file mode 100644 +index 0000000000000000..3fb2dd8777e61ab5 +--- /dev/null ++++ b/malloc/tst-interpose-static-nothread.c +@@ -0,0 +1,19 @@ ++/* Malloc interposition test, static version without threads. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include "tst-interpose-nothread.c" +diff --git a/malloc/tst-interpose-static-thread.c b/malloc/tst-interpose-static-thread.c +new file mode 100644 +index 0000000000000000..c78ebc70ba05c890 +--- /dev/null ++++ b/malloc/tst-interpose-static-thread.c +@@ -0,0 +1,19 @@ ++/* Malloc interposition test, static version with threads. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#include "tst-interpose-nothread.c" +diff --git a/malloc/tst-interpose-thread.c b/malloc/tst-interpose-thread.c +new file mode 100644 +index 0000000000000000..d3e20c745767d6ff +--- /dev/null ++++ b/malloc/tst-interpose-thread.c +@@ -0,0 +1,20 @@ ++/* Malloc interposition test, dynamically-linked version with threads. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public License as ++ published by the Free Software Foundation; either version 2.1 of the ++ License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; see the file COPYING.LIB. If ++ not, see . */ ++ ++#define INTERPOSE_THREADS 1 ++#include "tst-interpose-skeleton.c" +diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c +index 9cc3ff8bf667817f..d404d135bc172555 100644 +--- a/nptl/sysdeps/unix/sysv/linux/fork.c ++++ b/nptl/sysdeps/unix/sysv/linux/fork.c +@@ -119,7 +119,7 @@ __libc_fork (void) + /* Acquire malloc locks. This needs to come last because fork + handlers may use malloc, and the libio list lock has an indirect + malloc dependency as well (via the getdelim function). */ +- __malloc_fork_lock_parent (); ++ call_function_static_weak (__malloc_fork_lock_parent); + + #ifndef NDEBUG + pid_t ppid = THREAD_GETMEM (THREAD_SELF, tid); +@@ -178,7 +178,7 @@ __libc_fork (void) + #endif + + /* Release malloc locks. */ +- __malloc_fork_unlock_child (); ++ call_function_static_weak (__malloc_fork_unlock_child); + + /* Reset the file list. These are recursive mutexes. */ + fresetlockfiles (); +@@ -222,7 +222,7 @@ __libc_fork (void) + THREAD_SETMEM (THREAD_SELF, pid, parentpid); + + /* Release malloc locks, parent process variant. */ +- __malloc_fork_unlock_parent (); ++ call_function_static_weak (__malloc_fork_unlock_parent); + + /* We execute this even if the 'fork' call failed. */ + _IO_list_unlock (); diff --git a/SOURCES/glibc-rh911307-2.patch b/SOURCES/glibc-rh911307-2.patch new file mode 100644 index 00000000..5d52bbd7 --- /dev/null +++ b/SOURCES/glibc-rh911307-2.patch @@ -0,0 +1,43 @@ +From 7dfe8a35215a019f552f117d907eca294225c121 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Wed, 12 Jun 2013 10:21:22 -0500 +Subject: [PATCH 35/42] Fix unsafe compiler optimization + +GCC 4.8 enables -ftree-loop-distribute-patterns at -O3 by default and +this optimization may transform loops into memset/memmove calls. Without +proper handling this may generate unexpected PLT calls on GLIBC. +This patch fixes by create memset/memmove alias to internal GLIBC +__GI_memset/__GI_memmove symbols. +(cherry picked from commit 6a97b62a5b4f18aea849d6f4d8de58d1469d2521) +--- + sysdeps/generic/symbol-hacks.h | 7 ++++++- + sysdeps/wordsize-32/symbol-hacks.h | 2 ++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h +index bc7b4c4..9eaf014 100644 +--- glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h ++++ glibc-2.17-c758a686/sysdeps/generic/symbol-hacks.h +@@ -1 +1,6 @@ +-/* Fortunately nothing to do. */ ++/* Some compiler optimizations may transform loops into memset/memmove ++ calls and without proper declaration it may generate PLT calls. */ ++#if !defined __ASSEMBLER__ && !defined NOT_IN_libc && defined SHARED ++asm ("memmove = __GI_memmove"); ++asm ("memset = __GI_memset"); ++#endif +diff --git glibc-2.17-c758a686/sysdeps/wordsize-32/symbol-hacks.h glibc-2.17-c758a686/sysdeps/wordsize-32/symbol-hacks.h +index 52a14fc..ad5b231 100644 +--- glibc-2.17-c758a686/sysdeps/wordsize-32/symbol-hacks.h ++++ glibc-2.17-c758a686/sysdeps/wordsize-32/symbol-hacks.h +@@ -16,6 +16,8 @@ + License along with the GNU C Library; if not, see + . */ + ++#include_next "symbol-hacks.h" ++ + /* A very dirty trick: gcc emits references to __divdi3, __udivdi3, + __moddi3, and __umoddi3. These functions are exported and + therefore we get PLTs. Unnecessarily so. Changing gcc is a big +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh911307-3.patch b/SOURCES/glibc-rh911307-3.patch new file mode 100644 index 00000000..783a6d7b --- /dev/null +++ b/SOURCES/glibc-rh911307-3.patch @@ -0,0 +1,185 @@ +From 5c616c0a75792d2836412d6c4ed5c71e8e754992 Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Thu, 20 Jun 2013 19:40:55 -0500 +Subject: [PATCH 41/42] Fix loop construction to functions calls + +Check wheter the compiler has the option -fno-tree-loop-distribute-patterns +to inhibit loop transformation to library calls and uses it on memset +and memmove default implementation to avoid recursive calls. +(backported from commit 85c2e6110c9a01ec817c30f1b7e20549d7229987) + +This backport excluded the benchmark tests from the original commit. +--- + config.h.in | 3 +++ + configure | 33 +++++++++++++++++++++++++++++++++ + configure.in | 18 ++++++++++++++++++ + include/libc-symbols.h | 10 ++++++++++ + string/memmove.c | 1 + + string/memset.c | 1 + + string/test-memmove.c | 1 + + string/test-memset.c | 1 + + 9 files changed, 82 insertions(+) + +diff --git glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686/config.h.in +index f3fe6b8..b34aac2 100644 +--- glibc-2.17-c758a686/config.h.in ++++ glibc-2.17-c758a686/config.h.in +@@ -69,6 +69,9 @@ + /* Define if the compiler supports __builtin_memset. */ + #undef HAVE_BUILTIN_MEMSET + ++/* Define if compiler accepts -ftree-loop-distribute-patterns. */ ++#undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL ++ + /* Define if the regparm attribute shall be used for local functions + (gcc on ix86 only). */ + #undef USE_REGPARMS +diff --git glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure +index 8799b7d..99e85be 100755 +--- glibc-2.17-c758a686/configure ++++ glibc-2.17-c758a686/configure +@@ -605,6 +605,7 @@ have_selinux + have_libcap + have_libaudit + LIBGD ++libc_cv_cc_loop_to_function + libc_cv_cc_submachine + exceptions + gnu89_inline +@@ -7164,6 +7165,38 @@ $as_echo "$libc_cv_cc_submachine" >&6; } + fi + + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-tree-loop-distribute-patterns with \ ++__attribute__ ((__optimize__))" >&5 ++$as_echo_n "checking if $CC accepts -fno-tree-loop-distribute-patterns with \ ++__attribute__ ((__optimize__))... " >&6; } ++if ${libc_cv_cc_loop_to_function+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat > conftest.c <&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; } ++then ++ libc_cv_cc_loop_to_function=yes ++fi ++rm -f conftest* ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_loop_to_function" >&5 ++$as_echo "$libc_cv_cc_loop_to_function" >&6; } ++if test $libc_cv_cc_loop_to_function = yes; then ++ $as_echo "#define HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h ++ ++fi ++ ++ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libgd" >&5 + $as_echo_n "checking for libgd... " >&6; } + if test "$with_gd" != "no"; then +diff --git glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in +index d369382..379e77a 100644 +--- glibc-2.17-c758a686/configure.in ++++ glibc-2.17-c758a686/configure.in +@@ -1928,6 +1928,24 @@ if test -n "$submachine"; then + fi + AC_SUBST(libc_cv_cc_submachine) + ++AC_CACHE_CHECK(if $CC accepts -fno-tree-loop-distribute-patterns with \ ++__attribute__ ((__optimize__)), libc_cv_cc_loop_to_function, [dnl ++cat > conftest.c < +# +# * elf/Makefile (CFLAGS-.o): Add -fno-tree-loop-distribute-patterns. +# (CFLAGS-.os): Likewise. +# (CFLAGS-.op): Likewise. +# (CFLAGS-.ob): Likewise. +# (CFLAGS-.oS): Likewise. +# * string/Makefile (CFLAGS-.o): Likewise. +# (CFLAGS-.os): Likewise. +# (CFLAGS-.op): Likewise. +# (CFLAGS-.ob): Likewise. +# (CFLAGS-.oS): Likewise. +# +diff -urN glibc-2.17-c758a686/string/Makefile glibc-2.17-c758a686/string/Makefile +--- glibc-2.17-c758a686/string/Makefile 2013-02-27 18:07:34.618968703 -0500 ++++ glibc-2.17-c758a686/string/Makefile 2013-02-27 18:08:16.075796160 -0500 +@@ -78,6 +78,14 @@ + CFLAGS-bug-strstr1.c = -fno-builtin + CFLAGS-bug-strcasestr1.c = -fno-builtin + ++# Disable any optimization which might result in function calls to the very ++# same functions we are trying to compile, thus creating an infinite loop. ++CFLAGS-.o += -fno-tree-loop-distribute-patterns ++CFLAGS-.os += -fno-tree-loop-distribute-patterns ++CFLAGS-.op += -fno-tree-loop-distribute-patterns ++CFLAGS-.ob += -fno-tree-loop-distribute-patterns ++CFLAGS-.oS += -fno-tree-loop-distribute-patterns ++ + ifeq ($(run-built-tests),yes) + tests: $(objpfx)tst-svc.out + $(objpfx)tst-svc.out: tst-svc.input $(objpfx)tst-svc +diff -urN glibc-2.17-c758a686/elf/Makefile glibc-2.17-c758a686/elf/Makefile +--- glibc-2.17-c758a686/elf/Makefile 2013-02-27 18:07:13.812055613 -0500 ++++ glibc-2.17-c758a686/elf/Makefile 2013-02-27 18:08:16.075796160 -0500 +@@ -432,6 +432,16 @@ + CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\ + -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld) + ++# Disable any optimization which might result in function calls during early ++# dynamic loader startup. We disable -ftree-loop-distribute-patterns which ++# might convert code into calls to functions like memcpy or memset when the PLT ++# is not yet setup. ++CFLAGS-.o += -fno-tree-loop-distribute-patterns ++CFLAGS-.os += -fno-tree-loop-distribute-patterns ++CFLAGS-.op += -fno-tree-loop-distribute-patterns ++CFLAGS-.ob += -fno-tree-loop-distribute-patterns ++CFLAGS-.oS += -fno-tree-loop-distribute-patterns ++ + test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(strip $(modules-names)))) + generated += $(addsuffix .so,$(strip $(modules-names))) diff --git a/SOURCES/glibc-rh950093.patch b/SOURCES/glibc-rh950093.patch new file mode 100644 index 00000000..5a5d10d8 --- /dev/null +++ b/SOURCES/glibc-rh950093.patch @@ -0,0 +1,327 @@ +# +# All patches are from upstream and provide support for correct lib +# directory for AArch64. +# +# From 37bf2f1f983e37c0d87a1e34cd3d8a228ead5e16 Mon Sep 17 00:00:00 2001 +# From: Andreas Schwab +# Date: Thu, 4 Apr 2013 12:22:22 -0400 +# Subject: [PATCH 2/4] Add support for rtld directory different from slib +# directory +# +# --- +# ChangeLog | 15 +++++++++++++++ +# Makeconfig | 10 ++++++++-- +# Makerules | 4 ++-- +# config.make.in | 1 + +# configure | 2 ++ +# configure.in | 1 + +# elf/Makefile | 11 ++++++----- +# scripts/rellns-sh | 17 +++++++++++++++-- +# 8 files changed, 50 insertions(+), 11 deletions(-) +# +# From 937dd2d4a5da7d51b87261b037e22dfca05face7 Mon Sep 17 00:00:00 2001 +# From: Marcus Shawcroft +# Date: Thu, 4 Apr 2013 12:26:55 -0400 +# Subject: [PATCH 4/4] Correct missed use of $(rtlddir). +# +# --- +# ChangeLog | 4 ++++ +# Makerules | 2 +- +# 2 files changed, 5 insertions(+), 1 deletion(-) +# +# From bcce68c6dc678b443e7f140d664ba1fa49c0ceaa Mon Sep 17 00:00:00 2001 +# From: Andreas Schwab +# Date: Thu, 4 Apr 2013 12:23:43 -0400 +# Subject: [PATCH 3/4] aarch64: Move rtld link to /lib +# +# --- +# ports/ChangeLog.aarch64 | 6 ++++++ +# ports/sysdeps/unix/sysv/linux/aarch64/configure | 1 + +# ports/sysdeps/unix/sysv/linux/aarch64/configure.in | 1 + +# 3 files changed, 8 insertions(+) +# +# From 05bc48a20b8c20574bc59a048750f0dd77fd6e23 Mon Sep 17 00:00:00 2001 +# From: Andreas Schwab +# Date: Thu, 4 Apr 2013 12:02:53 -0400 +# Subject: [PATCH 1/4] aarch64: use lib64 as default lib and slib directory +# +# --- +# ports/ChangeLog.aarch64 | 6 ++++++ +# ports/sysdeps/unix/sysv/linux/aarch64/configure | 13 +++++++++++++ +# ports/sysdeps/unix/sysv/linux/aarch64/configure.in | 12 ++++++++++++ +# 3 files changed, 31 insertions(+) +# +# commit 446737706c186b33529a2c07fcb6f0cc10b2d1ea +# Author: Andreas Schwab +# Date: Tue Mar 19 10:13:46 2013 +0100 +# +# s390x: Move rtld link to /lib +# +diff -urN glibc-2.17-c758a686/config.make.in glibc-2.17-c758a686/config.make.in +--- glibc-2.17-c758a686/config.make.in 2013-10-28 10:56:39.996320904 -0400 ++++ glibc-2.17-c758a686/config.make.in 2013-10-28 10:56:57.773317467 -0400 +@@ -11,6 +11,7 @@ + datadir = @datadir@ + libdir = @libdir@ + slibdir = @libc_cv_slibdir@ ++rtlddir = @libc_cv_rtlddir@ + localedir = @libc_cv_localedir@ + sysconfdir = @libc_cv_sysconfdir@ + libexecdir = @libexecdir@ +diff -urN glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure +--- glibc-2.17-c758a686/configure 2013-10-28 10:56:39.935320916 -0400 ++++ glibc-2.17-c758a686/configure 2013-10-28 10:56:57.775317467 -0400 +@@ -594,6 +594,7 @@ + libc_cv_localstatedir + libc_cv_sysconfdir + libc_cv_localedir ++libc_cv_rtlddir + libc_cv_slibdir + old_glibc_headers + use_nscd +@@ -7600,6 +7601,7 @@ + + + ++ + + + +diff -urN glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in +--- glibc-2.17-c758a686/configure.in 2013-10-28 10:56:39.902320923 -0400 ++++ glibc-2.17-c758a686/configure.in 2013-10-28 10:56:57.776317467 -0400 +@@ -2127,6 +2127,7 @@ + AC_SUBST(old_glibc_headers) + + AC_SUBST(libc_cv_slibdir) ++AC_SUBST(libc_cv_rtlddir) + AC_SUBST(libc_cv_localedir) + AC_SUBST(libc_cv_sysconfdir) + AC_SUBST(libc_cv_localstatedir) +diff -urN glibc-2.17-c758a686/elf/Makefile glibc-2.17-c758a686/elf/Makefile +--- glibc-2.17-c758a686/elf/Makefile 2013-10-28 10:56:40.127320879 -0400 ++++ glibc-2.17-c758a686/elf/Makefile 2013-10-28 10:56:57.776317467 -0400 +@@ -66,7 +66,7 @@ + ifeq (yes,$(build-shared)) + extra-objs = $(all-rtld-routines:%=%.os) soinit.os sofini.os interp.os + generated += librtld.os dl-allobjs.os ld.so ldd +-install-others = $(inst_slibdir)/$(rtld-installed-name) ++install-others = $(inst_rtlddir)/$(rtld-installed-name) + install-bin-script = ldd + endif + +@@ -341,7 +341,7 @@ + | $(AWK) '($$7 ~ /^UND(|EF)$$/ && $$1 != "0:" && $$4 != "REGISTER") { print; p=1 } END { exit p != 0 }' + + # interp.c exists just to get this string into the libraries. +-CFLAGS-interp.c = -D'RUNTIME_LINKER="$(slibdir)/$(rtld-installed-name)"' \ ++CFLAGS-interp.c = -D'RUNTIME_LINKER="$(rtlddir)/$(rtld-installed-name)"' \ + -DNOT_IN_libc=1 + $(objpfx)interp.os: $(common-objpfx)config.make + +@@ -373,18 +373,19 @@ + $(make-target-directory) + $(do-install-program) + +-$(inst_slibdir)/$(rtld-installed-name): \ ++$(inst_rtlddir)/$(rtld-installed-name): \ + $(inst_slibdir)/$(rtld-version-installed-name) \ + $(inst_slibdir)/libc-$(version).so ++ $(make-target-directory) + $(make-shlib-link) + + # Special target called by parent to install just the dynamic linker. + .PHONY: ldso_install +-ldso_install: $(inst_slibdir)/$(rtld-installed-name) ++ldso_install: $(inst_rtlddir)/$(rtld-installed-name) + endif + + +-common-ldd-rewrite = -e 's%@RTLD@%$(slibdir)/$(rtld-installed-name)%g' \ ++common-ldd-rewrite = -e 's%@RTLD@%$(rtlddir)/$(rtld-installed-name)%g' \ + -e 's%@VERSION@%$(version)%g' \ + -e 's|@PKGVERSION@|$(PKGVERSION)|g' \ + -e 's|@REPORT_BUGS_TO@|$(REPORT_BUGS_TO)|g' +diff -urN glibc-2.17-c758a686/Makeconfig glibc-2.17-c758a686/Makeconfig +--- glibc-2.17-c758a686/Makeconfig 2013-10-28 10:56:40.434320820 -0400 ++++ glibc-2.17-c758a686/Makeconfig 2013-10-28 10:56:57.772317467 -0400 +@@ -148,12 +148,18 @@ + endif + inst_libdir = $(install_root)$(libdir) + +-# Where to install the shared library and dynamic linker. ++# Where to install the shared library. + ifndef slibdir + slibdir = $(exec_prefix)/lib + endif + inst_slibdir = $(install_root)$(slibdir) + ++# Where to install the dynamic linker. ++ifndef rtlddir ++rtlddir = $(slibdir) ++endif ++inst_rtlddir = $(install_root)$(rtlddir) ++ + # Prefix to put on files installed in $(libdir). For libraries `libNAME.a', + # the prefix is spliced between `lib' and the name, so the linker switch + # `-l$(libprefix)NAME' finds the library; for other files the prefix is +@@ -443,7 +449,7 @@ + endif + ifndef config-LDFLAGS + ifeq (yes,$(build-shared)) +-config-LDFLAGS = -Wl,-dynamic-linker=$(slibdir)/$(rtld-installed-name) ++config-LDFLAGS = -Wl,-dynamic-linker=$(rtlddir)/$(rtld-installed-name) + endif + endif + ifndef link-libc +diff -urN glibc-2.17-c758a686/Makerules glibc-2.17-c758a686/Makerules +--- glibc-2.17-c758a686/Makerules 2013-10-28 10:56:39.928320918 -0400 ++++ glibc-2.17-c758a686/Makerules 2013-10-28 10:56:57.777317467 -0400 +@@ -873,7 +873,7 @@ + symbolic-link-prog := $(common-objpfx)elf/sln + symbolic-link-list := $(common-objpfx)elf/symlink.list + define make-shlib-link +-echo $(> $(symbolic-link-list) ++echo `$(..)scripts/rellns-sh -p $< $@` $@ >> $(symbolic-link-list) + endef + else # cross-compiling + # We need a definition that can be used by elf/Makefile's install rules. +@@ -883,7 +883,7 @@ + ifndef make-shlib-link + define make-shlib-link + rm -f $@ +-$(LN_S) $( $@.new + mv -f $@.new $@ + +diff -urN glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure 2013-10-28 10:56:39.873320928 -0400 ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure 2013-10-28 10:57:26.270311964 -0400 +@@ -1,3 +1,17 @@ + # This file is generated from configure.in by Autoconf. DO NOT EDIT! ++ # Local configure fragment for sysdeps/unix/sysv/linux/aarch64. + + arch_minimum_kernel=3.7.0 ++ ++test -n "$libc_cv_slibdir" || ++case "$prefix" in ++ /usr | /usr/) ++ libc_cv_slibdir="/lib64" ++ libc_cv_rtlddir="/lib" ++ if test "$libdir" = '${exec_prefix}/lib'; then ++ libdir='${exec_prefix}/lib64'; ++ # Locale data can be shared between 32bit and 64bit libraries ++ libc_cv_localedir='${exec_prefix}/lib/locale' ++ fi ++ ;; ++esac +diff -urN glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure.in glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure.in +--- glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure.in 2013-10-28 10:56:39.873320928 -0400 ++++ glibc-2.17-c758a686/ports/sysdeps/unix/sysv/linux/aarch64/configure.in 2013-10-28 10:57:49.162307556 -0400 +@@ -2,3 +2,16 @@ + # Local configure fragment for sysdeps/unix/sysv/linux/aarch64. + + arch_minimum_kernel=3.7.0 ++ ++test -n "$libc_cv_slibdir" || ++case "$prefix" in ++ /usr | /usr/) ++ libc_cv_slibdir="/lib64" ++ libc_cv_rtlddir="/lib" ++ if test "$libdir" = '${exec_prefix}/lib'; then ++ libdir='${exec_prefix}/lib64'; ++ # Locale data can be shared between 32bit and 64bit libraries ++ libc_cv_localedir='${exec_prefix}/lib/locale' ++ fi ++ ;; ++esac +diff -urN glibc-2.17-c758a686/scripts/rellns-sh glibc-2.17-c758a686/scripts/rellns-sh +--- glibc-2.17-c758a686/scripts/rellns-sh 2013-10-28 10:56:40.081320888 -0400 ++++ glibc-2.17-c758a686/scripts/rellns-sh 2013-10-28 10:56:57.776317467 -0400 +@@ -16,8 +16,17 @@ + # You should have received a copy of the GNU General Public License + # along with this program; if not, see . + ++# With -p, instead of creating the link print the computed relative link ++# name. ++do_print=false ++case $1 in ++ -p) ++ do_print=true ++ shift ++ ;; ++esac + if test $# -ne 2; then +- echo "Usage: rellns SOURCE DEST" >&2 ++ echo "Usage: rellns [-p] SOURCE DEST" >&2 + exit 1 + fi + +@@ -70,4 +79,8 @@ + from=`echo $from | sed 's%^[^/]*/*%%'` + done + +-ln -s $rfrom$to $2 ++if $do_print; then ++ echo "$rfrom$to" ++else ++ ln -s $rfrom$to $2 ++fi +diff --git glibc-2.17-c758a686/sysdeps/gnu/configure glibc-2.17-c758a686/sysdeps/gnu/configure +index 26327ca..70aaa90 100644 +--- glibc-2.17-c758a686/sysdeps/gnu/configure ++++ glibc-2.17-c758a686/sysdeps/gnu/configure +@@ -9,12 +9,17 @@ + case "$prefix" in + /usr | /usr/) + # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib. +- # Allow earlier configure scripts to handle libc_cv_slibdir, libdir, +- # and libc_cv_localedir. ++ # Allow earlier configure scripts to handle libc_cv_slibdir, ++ # libc_cv_rtlddir, libdir, and libc_cv_localedir. + test -n "$libc_cv_slibdir" || \ + case $machine in + sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64) + libc_cv_slibdir=/lib64 ++ case $machine in ++ s390/s390-64) ++ libc_cv_rtlddir=/lib ++ ;; ++ esac + if test "$libdir" = '${exec_prefix}/lib'; then + libdir='${exec_prefix}/lib64'; + # Locale data can be shared between 32bit and 64bit libraries +diff --git glibc-2.17-c758a686/sysdeps/gnu/configure.in glibc-2.17-c758a686/sysdeps/gnu/configure.in +index b8fd74c..ce251df 100644 +--- glibc-2.17-c758a686/sysdeps/gnu/configure.in ++++ glibc-2.17-c758a686/sysdeps/gnu/configure.in +@@ -9,12 +9,17 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + case "$prefix" in + /usr | /usr/) + # 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib. +- # Allow earlier configure scripts to handle libc_cv_slibdir, libdir, +- # and libc_cv_localedir. ++ # Allow earlier configure scripts to handle libc_cv_slibdir, ++ # libc_cv_rtlddir, libdir, and libc_cv_localedir. + test -n "$libc_cv_slibdir" || \ + case $machine in + sparc/sparc64 | x86_64* | powerpc/powerpc64 | s390/s390-64) + libc_cv_slibdir=/lib64 ++ case $machine in ++ s390/s390-64) ++ libc_cv_rtlddir=/lib ++ ;; ++ esac + if test "$libdir" = '${exec_prefix}/lib'; then + libdir='${exec_prefix}/lib64'; + # Locale data can be shared between 32bit and 64bit libraries diff --git a/SOURCES/glibc-rh952799.patch b/SOURCES/glibc-rh952799.patch new file mode 100644 index 00000000..afbd06a7 --- /dev/null +++ b/SOURCES/glibc-rh952799.patch @@ -0,0 +1,181 @@ +# +# Red Hat BZ: +# https://bugzilla.redhat.com/show_bug.cgi?id=816647 +# +# ChangeLog +# +#2013-04-30 Patsy Franklin +# +# * iconv/gconv_cache.c (find_module): Demangle init_fct before +# checking for NULL. Mangle __btowc_fct if init_fct is non-NULL. +# * iconv/gconv_db.c (free_derivation): Check that __shlib_handle +# is non-NULL before demangling the end_fct. Check for NULL +# end_fct after demangling. +# (__gconv_release_step): Demangle the end_fct before checking +# it for NULL. Remove assert on __shlibc_handle != NULL. +# (gen_steps): Don't check btowc_fct for NULL before mangling. +# Demangle init_fct before checking for NULL. +# (increment_counter): Likewise +# * gconv_dl.c (__gconv_find_shlib): Don't check init_fct or +# end_fct for NULL before mangling. +# * wcsmbs/btowc.c (__btowc): Demangle btowc_fct before checking +# for NULL. +# +diff -Nru glibc-2.17-c758a686/iconv/gconv_cache.c glibc-2.17-c758a686/iconv/gconv_cache.c +--- glibc-2.17-c758a686/iconv/gconv_cache.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/iconv/gconv_cache.c 2013-04-30 11:34:20.112389987 -0400 +@@ -207,17 +207,16 @@ find_module (const char *directory, cons + result->__data = NULL; + + /* Call the init function. */ +- if (result->__init_fct != NULL) +- { +- __gconv_init_fct init_fct = result->__init_fct; ++ __gconv_init_fct init_fct = result->__init_fct; + #ifdef PTR_DEMANGLE +- PTR_DEMANGLE (init_fct); ++ PTR_DEMANGLE (init_fct); + #endif ++ if (init_fct != NULL) ++ { + status = DL_CALL_FCT (init_fct, (result)); + + #ifdef PTR_MANGLE +- if (result->__btowc_fct != NULL) +- PTR_MANGLE (result->__btowc_fct); ++ PTR_MANGLE (result->__btowc_fct); + #endif + } + } +diff -Nru glibc-2.17-c758a686/iconv/gconv_db.c glibc-2.17-c758a686/iconv/gconv_db.c +--- glibc-2.17-c758a686/iconv/gconv_db.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/iconv/gconv_db.c 2013-04-30 11:32:42.700592914 -0400 +@@ -179,16 +179,15 @@ free_derivation (void *p) + size_t cnt; + + for (cnt = 0; cnt < deriv->nsteps; ++cnt) +- if (deriv->steps[cnt].__counter > 0 +- && deriv->steps[cnt].__end_fct != NULL) ++ if ((deriv->steps[cnt].__counter > 0) ++ && (deriv->steps[cnt].__shlib_handle != NULL)) + { +- assert (deriv->steps[cnt].__shlib_handle != NULL); +- + __gconv_end_fct end_fct = deriv->steps[cnt].__end_fct; + #ifdef PTR_DEMANGLE + PTR_DEMANGLE (end_fct); + #endif +- DL_CALL_FCT (end_fct, (&deriv->steps[cnt])); ++ if (end_fct != NULL) ++ DL_CALL_FCT (end_fct, (&deriv->steps[cnt])); + } + + /* Free the name strings. */ +@@ -212,16 +211,12 @@ __gconv_release_step (struct __gconv_ste + if (step->__shlib_handle != NULL && --step->__counter == 0) + { + /* Call the destructor. */ +- if (step->__end_fct != NULL) +- { +- assert (step->__shlib_handle != NULL); +- +- __gconv_end_fct end_fct = step->__end_fct; ++ __gconv_end_fct end_fct = step->__end_fct; + #ifdef PTR_DEMANGLE +- PTR_DEMANGLE (end_fct); ++ PTR_DEMANGLE (end_fct); + #endif +- DL_CALL_FCT (end_fct, (step)); +- } ++ if (end_fct != NULL) ++ DL_CALL_FCT (end_fct, (step)); + + #ifndef STATIC_GCONV + /* Release the loaded module. */ +@@ -293,13 +288,11 @@ gen_steps (struct derivation_step *best, + + /* Call the init function. */ + __gconv_init_fct init_fct = result[step_cnt].__init_fct; +- if (init_fct != NULL) +- { +- assert (result[step_cnt].__shlib_handle != NULL); +- + # ifdef PTR_DEMANGLE +- PTR_DEMANGLE (init_fct); ++ PTR_DEMANGLE (init_fct); + # endif ++ if (init_fct != NULL) ++ { + status = DL_CALL_FCT (init_fct, (&result[step_cnt])); + + if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK) +@@ -312,8 +305,7 @@ gen_steps (struct derivation_step *best, + } + + # ifdef PTR_MANGLE +- if (result[step_cnt].__btowc_fct != NULL) +- PTR_MANGLE (result[step_cnt].__btowc_fct); ++ PTR_MANGLE (result[step_cnt].__btowc_fct); + # endif + } + } +@@ -393,16 +385,15 @@ increment_counter (struct __gconv_step * + + /* Call the init function. */ + __gconv_init_fct init_fct = step->__init_fct; +- if (init_fct != NULL) +- { + #ifdef PTR_DEMANGLE +- PTR_DEMANGLE (init_fct); ++ PTR_DEMANGLE (init_fct); + #endif ++ if (init_fct != NULL) ++ { + DL_CALL_FCT (init_fct, (step)); + + #ifdef PTR_MANGLE +- if (step->__btowc_fct != NULL) +- PTR_MANGLE (step->__btowc_fct); ++ PTR_MANGLE (step->__btowc_fct); + #endif + } + } +diff -Nru glibc-2.17-c758a686/iconv/gconv_dl.c glibc-2.17-c758a686/iconv/gconv_dl.c +--- glibc-2.17-c758a686/iconv/gconv_dl.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/iconv/gconv_dl.c 2013-04-30 11:32:42.701592922 -0400 +@@ -132,10 +132,8 @@ __gconv_find_shlib (const char *name) + + #ifdef PTR_MANGLE + PTR_MANGLE (found->fct); +- if (found->init_fct != NULL) +- PTR_MANGLE (found->init_fct); +- if (found->end_fct != NULL) +- PTR_MANGLE (found->end_fct); ++ PTR_MANGLE (found->init_fct); ++ PTR_MANGLE (found->end_fct); + #endif + + /* We have succeeded in loading the shared object. */ +diff -Nru glibc-2.17-c758a686/wcsmbs/btowc.c glibc-2.17-c758a686/wcsmbs/btowc.c +--- glibc-2.17-c758a686/wcsmbs/btowc.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/wcsmbs/btowc.c 2013-04-30 11:32:42.701592922 -0400 +@@ -47,15 +47,15 @@ __btowc (c) + /* Get the conversion functions. */ + fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE)); + __gconv_btowc_fct btowc_fct = fcts->towc->__btowc_fct; ++#ifdef PTR_DEMANGLE ++ if (fcts->towc->__shlib_handle != NULL) ++ PTR_DEMANGLE (btowc_fct); ++#endif + + if (__builtin_expect (fcts->towc_nsteps == 1, 1) + && __builtin_expect (btowc_fct != NULL, 1)) + { + /* Use the shortcut function. */ +-#ifdef PTR_DEMANGLE +- if (fcts->towc->__shlib_handle != NULL) +- PTR_DEMANGLE (btowc_fct); +-#endif + return DL_CALL_FCT (btowc_fct, (fcts->towc, (unsigned char) c)); + } + else diff --git a/SOURCES/glibc-rh958652.patch b/SOURCES/glibc-rh958652.patch new file mode 100644 index 00000000..31673f37 --- /dev/null +++ b/SOURCES/glibc-rh958652.patch @@ -0,0 +1,69 @@ +commit 3d04f5db20c8f0d1ba3881b5f5373586a18cf188 +Author: Siddhesh Poyarekar +Date: Tue May 21 21:54:41 2013 +0530 + + Set EAI_SYSTEM only when h_errno is NETDB_INTERNAL + + Fixes BZ #15339. + + NSS_STATUS_UNAVAIL may mean that a necessary input resource is not + available. This could occur in a number of cases including when the + network is down, system runs out of file descriptors, etc. The + correct differentiator in such a case is the h_errno, which gives the + nature of failure. In case of failures other than a simple 'not + found', we set h_errno as NETDB_INTERNAL and let errno be the + identifier for the exact error. + +diff --git glibc-2.17-c758a686/nss/getXXbyYY_r.c glibc-2.17-c758a686/nss/getXXbyYY_r.c +index 44d00f4..33e63d4 100644 +--- glibc-2.17-c758a686/nss/getXXbyYY_r.c ++++ glibc-2.17-c758a686/nss/getXXbyYY_r.c +@@ -287,10 +287,10 @@ done: + #endif + *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL; + #ifdef NEED_H_ERRNO +- if (status == NSS_STATUS_UNAVAIL) +- /* Either we failed to lookup the functions or the functions themselves +- had a system error. Set NETDB_INTERNAL here to let the caller know +- that the errno may have the real reason for failure. */ ++ if (status == NSS_STATUS_UNAVAIL && !any_service && errno != ENOENT) ++ /* This happens when we weren't able to use a service for reasons other ++ than the module not being found. In such a case, we'd want to tell the ++ caller that errno has the real reason for failure. */ + *h_errnop = NETDB_INTERNAL; + else if (status != NSS_STATUS_SUCCESS && !any_service) + /* We were not able to use any service. */ +diff --git glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +index ab135ad..7bb3ded 100644 +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -1036,7 +1036,15 @@ gaih_inet (const char *name, const struct gaih_service *service, + } + } + else +- status = NSS_STATUS_UNAVAIL; ++ { ++ status = NSS_STATUS_UNAVAIL; ++ /* Could not load any of the lookup functions. Indicate ++ an internal error if the failure was due to a system ++ error other than the file not being found. We use the ++ errno from the last failed callback. */ ++ if (errno != 0 && errno != ENOENT) ++ __set_h_errno (NETDB_INTERNAL); ++ } + } + + if (nss_next_action (nip, status) == NSS_ACTION_RETURN) +@@ -1050,7 +1058,7 @@ gaih_inet (const char *name, const struct gaih_service *service, + + _res.options |= old_res_options & RES_USE_INET6; + +- if (status == NSS_STATUS_UNAVAIL) ++ if (h_errno == NETDB_INTERNAL) + { + result = GAIH_OKIFUNSPEC | -EAI_SYSTEM; + goto free_and_return; +_______________________________________________ +glibc mailing list +glibc@lists.fedoraproject.org +https://admin.fedoraproject.org/mailman/listinfo/glibc diff --git a/SOURCES/glibc-rh959034.patch b/SOURCES/glibc-rh959034.patch new file mode 100644 index 00000000..ac18facc --- /dev/null +++ b/SOURCES/glibc-rh959034.patch @@ -0,0 +1,80 @@ +2013-05-03 Carlos O'Donell + + * intl/dcigettext.c (DCIGETTEXT): Skip translating if _nl_find_msg returns -1. + (_nl_find_msg): Return -1 if recursive call returned -1. If newmem is null + return -1. + * intl/loadmsgcat.c (_nl_load_domain): If _nl_find_msg returns -1 abort + loading the domain. + +diff --git glibc-2.17-c758a686/intl/dcigettext.c glibc-2.17-c758a686/intl/dcigettext.c +index 110307b..f4aa215 100644 +--- glibc-2.17-c758a686/intl/dcigettext.c ++++ glibc-2.17-c758a686/intl/dcigettext.c +@@ -638,6 +638,11 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) + retval = _nl_find_msg (domain->successor[cnt], binding, + msgid1, 1, &retlen); + ++ /* Resource problems are not fatal, instead we return no ++ translation. */ ++ if (__builtin_expect (retval == (char *) -1, 0)) ++ goto no_translation; ++ + if (retval != NULL) + { + domain = domain->successor[cnt]; +@@ -941,6 +946,11 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) + nullentry = + _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen); + ++ /* Resource problems are fatal. If we continue onwards we will ++ only attempt to calloc a new conv_tab and fail later. */ ++ if (__builtin_expect (nullentry == (char *) -1, 0)) ++ return (char *) -1; ++ + if (nullentry != NULL) + { + const char *charsetstr; +@@ -1170,10 +1180,14 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) + freemem_size = INITIAL_BLOCK_SIZE; + newmem = (transmem_block_t *) malloc (freemem_size); + # ifdef _LIBC +- /* Add the block to the list of blocks we have to free +- at some point. */ +- newmem->next = transmem_list; +- transmem_list = newmem; ++ if (newmem != NULL) ++ { ++ /* Add the block to the list of blocks we have to free ++ at some point. */ ++ newmem->next = transmem_list; ++ transmem_list = newmem; ++ } ++ /* Fall through and return -1. */ + # endif + } + if (__builtin_expect (newmem == NULL, 0)) +diff --git glibc-2.17-c758a686/intl/loadmsgcat.c glibc-2.17-c758a686/intl/loadmsgcat.c +index e4b7b38..ac90ed1 100644 +--- glibc-2.17-c758a686/intl/loadmsgcat.c ++++ glibc-2.17-c758a686/intl/loadmsgcat.c +@@ -1237,7 +1237,7 @@ _nl_load_domain (domain_file, domainbinding) + default: + /* This is an invalid revision. */ + invalid: +- /* This is an invalid .mo file. */ ++ /* This is an invalid .mo file or we ran out of resources. */ + free (domain->malloced); + #ifdef HAVE_MMAP + if (use_mmap) +@@ -1257,6 +1257,11 @@ _nl_load_domain (domain_file, domainbinding) + + /* Get the header entry and look for a plural specification. */ + nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen); ++ if (__builtin_expect (nullentry == (char *) -1, 0)) ++ { ++ __libc_rwlock_fini (domain->conversions_lock); ++ goto invalid; ++ } + EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals); + + out: diff --git a/SOURCES/glibc-rh966259.patch b/SOURCES/glibc-rh966259.patch new file mode 100644 index 00000000..9f428d04 --- /dev/null +++ b/SOURCES/glibc-rh966259.patch @@ -0,0 +1,55 @@ +commit 96945714ec61951cc748da2b4b8a80cf02127ee9 +Author: Jeff Law +Date: Thu May 23 13:28:00 2013 -0600 + + [BZ #14256] + * manual/errno.texi (ESTALE): Update to account for more than + just NFS file systems. + * sysdeps/gnu/errlist.c: Regenerated. + +diff --git glibc-2.17-c758a686/manual/errno.texi glibc-2.17-c758a686/manual/errno.texi +index 2a3c004..6c9fa86 100644 +--- glibc-2.17-c758a686/manual/errno.texi ++++ glibc-2.17-c758a686/manual/errno.texi +@@ -739,13 +739,14 @@ The user's disk quota was exceeded. + @end deftypevr + + @comment errno.h +-@comment BSD: Stale NFS file handle ++@comment BSD: Stale file handle + @deftypevr Macro int ESTALE + @comment errno 70 @c DO NOT REMOVE +-Stale NFS file handle. This indicates an internal confusion in the NFS +-system which is due to file system rearrangements on the server host. +-Repairing this condition usually requires unmounting and remounting +-the NFS file system on the local host. ++Stale file handle. This indicates an internal confusion in the ++file system which is due to file system rearrangements on the server host ++for NFS file systems or corruption in other file systems. ++Repairing this condition usually requires unmounting, possibly repairing ++and remounting the file system. + @end deftypevr + + @comment errno.h +diff --git glibc-2.17-c758a686/sysdeps/gnu/errlist.c glibc-2.17-c758a686/sysdeps/gnu/errlist.c +index e3d2faf..bbd45f2 100644 +--- glibc-2.17-c758a686/sysdeps/gnu/errlist.c ++++ glibc-2.17-c758a686/sysdeps/gnu/errlist.c +@@ -780,11 +780,12 @@ TRANS The user's disk quota was exceeded. */ + #endif + #ifdef ESTALE + /* +-TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-TRANS system which is due to file system rearrangements on the server host. +-TRANS Repairing this condition usually requires unmounting and remounting +-TRANS the NFS file system on the local host. */ +- [ERR_REMAP (ESTALE)] = N_("Stale NFS file handle"), ++TRANS Stale file handle. This indicates an internal confusion in the ++TRANS file system which is due to file system rearrangements on the server host ++TRANS for NFS file systems or corruption in other file systems. ++TRANS Repairing this condition usually requires unmounting, possibly repairing ++TRANS and remounting the file system. */ ++ [ERR_REMAP (ESTALE)] = N_("Stale file handle"), + # if ESTALE > ERR_MAX + # undef ERR_MAX + # define ERR_MAX ESTALE diff --git a/SOURCES/glibc-rh966633.patch b/SOURCES/glibc-rh966633.patch new file mode 100644 index 00000000..f6f4b722 --- /dev/null +++ b/SOURCES/glibc-rh966633.patch @@ -0,0 +1,95 @@ +commit 50fd745b4dec07e8e213cf2703b5cabcfa128225 +Author: Andreas Schwab +Date: Mon Jun 10 14:39:09 2013 +0200 + + Fix handling of netgroup cache in nscd + +diff --git glibc-2.17-c758a686/nscd/connections.c glibc-2.17-c758a686/nscd/connections.c +index 7099215..69e3e7d 100644 +--- glibc-2.17-c758a686/nscd/connections.c ++++ glibc-2.17-c758a686/nscd/connections.c +@@ -1779,7 +1779,7 @@ nscd_run_worker (void *p) + else + { + /* Get the key. */ +- char keybuf[MAXKEYLEN]; ++ char keybuf[MAXKEYLEN + 1]; + + if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf, + req.key_len)) +@@ -1791,6 +1791,7 @@ nscd_run_worker (void *p) + strerror_r (errno, buf, sizeof (buf))); + goto close_and_out; + } ++ keybuf[req.key_len] = '\0'; + + if (__builtin_expect (debug_level, 0) > 0) + { +diff --git glibc-2.17-c758a686/nscd/netgroupcache.c glibc-2.17-c758a686/nscd/netgroupcache.c +index 2d6c5aa..dd06ce4 100644 +--- glibc-2.17-c758a686/nscd/netgroupcache.c ++++ glibc-2.17-c758a686/nscd/netgroupcache.c +@@ -192,18 +192,26 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + const char *nuser = data.val.triple.user; + const char *ndomain = data.val.triple.domain; + +- if (data.val.triple.host > data.val.triple.user +- || data.val.triple.user > data.val.triple.domain) ++ if (nhost == NULL || nuser == NULL || ndomain == NULL ++ || nhost > nuser || nuser > ndomain) + { +- const char *last = MAX (nhost, +- MAX (nuser, ndomain)); +- size_t bufused = (last + strlen (last) + 1 +- - buffer); ++ const char *last = nhost; ++ if (last == NULL ++ || (nuser != NULL && nuser > last)) ++ last = nuser; ++ if (last == NULL ++ || (ndomain != NULL && ndomain > last)) ++ last = ndomain; ++ ++ size_t bufused ++ = (last == NULL ++ ? buffilled ++ : last + strlen (last) + 1 - buffer); + + /* We have to make temporary copies. */ +- size_t hostlen = strlen (nhost) + 1; +- size_t userlen = strlen (nuser) + 1; +- size_t domainlen = strlen (ndomain) + 1; ++ size_t hostlen = strlen (nhost ?: "") + 1; ++ size_t userlen = strlen (nuser ?: "") + 1; ++ size_t domainlen = strlen (ndomain ?: "") + 1; + size_t needed = hostlen + userlen + domainlen; + + if (buflen - req->key_len - bufused < needed) +@@ -226,11 +234,11 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, + } + + nhost = memcpy (buffer + bufused, +- nhost, hostlen); ++ nhost ?: "", hostlen); + nuser = memcpy ((char *) nhost + hostlen, +- nuser, userlen); ++ nuser ?: "", userlen); + ndomain = memcpy ((char *) nuser + userlen, +- ndomain, domainlen); ++ ndomain ?: "", domainlen); + } + + char *wp = buffer + buffilled; +diff --git glibc-2.17-c758a686/nscd/nscd_netgroup.c glibc-2.17-c758a686/nscd/nscd_netgroup.c +index cac4ebf..acb2c81 100644 +--- glibc-2.17-c758a686/nscd/nscd_netgroup.c ++++ glibc-2.17-c758a686/nscd/nscd_netgroup.c +@@ -48,7 +48,7 @@ __nscd_setnetgrent (const char *group, struct __netgrent *datap) + { + int gc_cycle; + int nretries = 0; +- size_t group_len = strlen (group); ++ size_t group_len = strlen (group) + 1; + + /* If the mapping is available, try to search there instead of + communicating with the nscd. */ diff --git a/SOURCES/glibc-rh970791.patch b/SOURCES/glibc-rh970791.patch new file mode 100644 index 00000000..be942683 --- /dev/null +++ b/SOURCES/glibc-rh970791.patch @@ -0,0 +1,180 @@ +# +# Patch provided by Ulrich Drepper in BZ#919562. +# +# Patch has not been sent upstream. +# +# 2013-03-08 Ulrich Drepper +# +# * elf/rtld.c (dl_main): Correctly determine when the application +# required DSOs with TLS and bump the generation counter in that +# case. The current condition does not account for an audit +# module using TLS. +# * elf/dl-tls.c (_dl_count_modids): New function. +# (_dl_allocate_tls_init): Add assertion to check TLS +# generation. +# * sysdeps/generic/ldsodefs.h: Declare _dl_count_modids. +# * elf/Makefile: Add rules to build and run tst-audit9. +# * elf/tst-audit9.c: New file. +# * elf/tst-auditmod9a.c: New file. +# * elf/tst-auditmod9b.c: New file. +# +diff -urN glibc-2.17-c758a686/elf/dl-tls.c glibc-2.17-c758a686/elf/dl-tls.c +--- glibc-2.17-c758a686/elf/dl-tls.c 2013-04-24 16:06:10.410756438 -0400 ++++ glibc-2.17-c758a686/elf/dl-tls.c 2013-04-24 16:06:49.092604707 -0400 +@@ -109,6 +109,28 @@ + } + + ++size_t ++internal_function ++_dl_count_modids (void) ++{ ++ if (! __builtin_expect (GL(dl_tls_dtv_gaps), true)) ++ return GL(dl_tls_max_dtv_idx); ++ ++ size_t n = 0; ++ struct dtv_slotinfo_list *runp = GL(dl_tls_dtv_slotinfo_list); ++ while (runp != NULL) ++ { ++ for (size_t i = 0; i < runp->len; ++i) ++ if (runp->slotinfo[i].map != NULL) ++ ++n; ++ ++ runp = runp->next; ++ } ++ ++ return n; ++} ++ ++ + #ifdef SHARED + void + internal_function +@@ -411,6 +433,7 @@ + + /* Keep track of the maximum generation number. This might + not be the generation counter. */ ++ assert (listp->slotinfo[cnt].gen <= GL(dl_tls_generation)); + maxgen = MAX (maxgen, listp->slotinfo[cnt].gen); + + if (map->l_tls_offset == NO_TLS_OFFSET +diff -urN glibc-2.17-c758a686/elf/Makefile glibc-2.17-c758a686/elf/Makefile +--- glibc-2.17-c758a686/elf/Makefile 2013-04-24 16:06:10.408756448 -0400 ++++ glibc-2.17-c758a686/elf/Makefile 2013-04-24 16:07:29.475457962 -0400 +@@ -198,7 +200,7 @@ + tst-dlmodcount tst-dlopenrpath tst-deep1 \ + tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \ + unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \ +- tst-audit1 tst-audit2 tst-audit8 \ ++ tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ + tst-stackguard1 tst-addr1 tst-thrlock \ + tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ + tst-initorder tst-initorder2 tst-relsort1 +@@ -251,7 +253,8 @@ + unload8mod1 unload8mod1x unload8mod2 unload8mod3 \ + order2mod1 order2mod2 order2mod3 order2mod4 \ + tst-unique1mod1 tst-unique1mod2 \ +- tst-unique2mod1 tst-unique2mod2 \ ++ tst-unique2mod1 tst-unique2mod2 \ ++ tst-auditmod9a tst-auditmod9b \ + tst-unique3lib tst-unique3lib2 \ + tst-unique4lib \ + tst-initordera1 tst-initorderb1 \ +@@ -574,6 +577,8 @@ + ifuncmod1.so-no-z-defs = yes + ifuncmod5.so-no-z-defs = yes + ifuncmod6.so-no-z-defs = yes ++tst-auditmod9a.so-no-z-defs = yes ++tst-auditmod9b.so-no-z-defs = yes + + ifeq ($(build-shared),yes) + # Build all the modules even when not actually running test programs. +@@ -1015,6 +1020,10 @@ + $(objpfx)tst-audit7.out: $(objpfx)tst-auditmod7b.so + tst-audit7-ENV = LD_AUDIT=$(objpfx)tst-auditmod7b.so + ++$(objpfx)tst-audit9: $(libdl) ++$(objpfx)tst-audit9.out: $(objpfx)tst-auditmod9a.so $(objpfx)tst-auditmod9b.so ++tst-audit9-ENV = LD_AUDIT=$(objpfx)tst-auditmod9a.so ++ + $(objpfx)tst-audit8: $(common-objpfx)math/libm.so + $(objpfx)tst-audit8.out: $(objpfx)tst-auditmod1.so + tst-audit8-ENV = LD_AUDIT=$(objpfx)tst-auditmod1.so +diff -urN glibc-2.17-c758a686/elf/rtld.c glibc-2.17-c758a686/elf/rtld.c +--- glibc-2.17-c758a686/elf/rtld.c 2013-04-24 16:06:10.410756438 -0400 ++++ glibc-2.17-c758a686/elf/rtld.c 2013-04-24 16:06:49.096604693 -0400 +@@ -1637,6 +1637,10 @@ + } + } + ++ /* Keep track of the currently loaded modules to count how many ++ non-audit modules which use TLS are loaded. */ ++ size_t count_modids = _dl_count_modids (); ++ + /* Set up debugging before the debugger is notified for the first time. */ + #ifdef ELF_MACHINE_DEBUG_SETUP + /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */ +@@ -2281,7 +2285,8 @@ + # define NONTLS_INIT_TP do { } while (0) + #endif + +- if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0) ++ if ((!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0) ++ || count_modids != _dl_count_modids ()) + ++GL(dl_tls_generation); + + /* Now that we have completed relocation, the initializer data +diff -urN glibc-2.17-c758a686/elf/tst-audit9.c glibc-2.17-c758a686/elf/tst-audit9.c +--- glibc-2.17-c758a686/elf/tst-audit9.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/elf/tst-audit9.c 2013-04-24 16:06:49.096604693 -0400 +@@ -0,0 +1,8 @@ ++#include ++ ++int main(void) ++{ ++ void *h = dlopen("$ORIGIN/tst-auditmod9b.so", RTLD_LAZY); ++ int (*fp)(void) = dlsym(h, "f"); ++ return fp() - 1; ++} +diff -urN glibc-2.17-c758a686/elf/tst-auditmod9a.c glibc-2.17-c758a686/elf/tst-auditmod9a.c +--- glibc-2.17-c758a686/elf/tst-auditmod9a.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/elf/tst-auditmod9a.c 2013-04-24 16:06:49.097604689 -0400 +@@ -0,0 +1,16 @@ ++#include ++ ++__thread int var; ++ ++unsigned int ++la_version (unsigned int v) ++{ ++ return v; ++} ++ ++void ++la_activity (uintptr_t *cookie, unsigned int flag) ++{ ++ ++var; ++} ++ +diff -urN glibc-2.17-c758a686/elf/tst-auditmod9b.c glibc-2.17-c758a686/elf/tst-auditmod9b.c +--- glibc-2.17-c758a686/elf/tst-auditmod9b.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/elf/tst-auditmod9b.c 2013-04-24 16:06:49.097604689 -0400 +@@ -0,0 +1,6 @@ ++__thread int a; ++ ++int f(void) ++{ ++ return ++a; ++} +diff -urN glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h +--- glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2013-04-24 16:06:10.545755798 -0400 ++++ glibc-2.17-c758a686/sysdeps/generic/ldsodefs.h 2013-04-24 16:06:49.098604686 -0400 +@@ -1031,6 +1031,9 @@ + /* Determine next available module ID. */ + extern size_t _dl_next_tls_modid (void) internal_function attribute_hidden; + ++/* Count the modules with TLS segments. */ ++extern size_t _dl_count_modids (void) internal_function attribute_hidden; ++ + /* Calculate offset of the TLS blocks in the static TLS block. */ + extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden; diff --git a/SOURCES/glibc-rh971416-1.patch b/SOURCES/glibc-rh971416-1.patch new file mode 100644 index 00000000..35995a97 --- /dev/null +++ b/SOURCES/glibc-rh971416-1.patch @@ -0,0 +1,53 @@ +commit 0d822a016b631aef409df5805f58962fe5bbcdc5 +Author: Alexandre Oliva +Date: Mon Nov 17 22:00:58 2014 -0200 + + BZ #15969: search locale archive again after alias expansion + + If a locale alias is defined in locale.alias but not in an archive, + and the referenced locale is only present in the archive, setlocale + will fail if given the alias name. This is unintuitive. This patch + fixes it, arranging for the locale archive to be searched again after + alias expansion. + + for ChangeLog + + [BZ #15969] + * locale/findlocale.c (_nl_find_locale): Retry archive search + after alias expansion. + +Index: b/locale/findlocale.c +=================================================================== +--- a/locale/findlocale.c ++++ b/locale/findlocale.c +@@ -156,15 +156,26 @@ _nl_find_locale (const char *locale_path + if (__builtin_expect (data != NULL, 1)) + return data; + ++ /* Nothing in the archive with the given name. Expanding it as ++ an alias and retry. */ ++ loc_name = (char *) _nl_expand_alias (*name); ++ if (loc_name != NULL) ++ { ++ data = _nl_load_locale_from_archive (category, &loc_name); ++ if (__builtin_expect (data != NULL, 1)) ++ return data; ++ } ++ + /* Nothing in the archive. Set the default path to search below. */ + locale_path = _nl_default_locale_path; + locale_path_len = sizeof _nl_default_locale_path; + } ++ else ++ /* We really have to load some data. First see whether the name is ++ an alias. Please note that this makes it impossible to have "C" ++ or "POSIX" as aliases. */ ++ loc_name = (char *) _nl_expand_alias (*name); + +- /* We really have to load some data. First see whether the name is +- an alias. Please note that this makes it impossible to have "C" +- or "POSIX" as aliases. */ +- loc_name = (char *) _nl_expand_alias (*name); + if (loc_name == NULL) + /* It is no alias. */ + loc_name = (char *) *name; diff --git a/SOURCES/glibc-rh971416-2.patch b/SOURCES/glibc-rh971416-2.patch new file mode 100644 index 00000000..9f892947 --- /dev/null +++ b/SOURCES/glibc-rh971416-2.patch @@ -0,0 +1,26 @@ +commit 23d43090e0b275e47e09e859823e965a1eb323dc +Author: Alexandre Oliva +Date: Thu Feb 26 02:46:02 2015 -0300 + + Fix constness error just introduced in findlocale. + + for ChangeLog + + [BZ #15969] + * locale/findlocale.c (_nl_find_locale): Fix constness error in + the previous change. + +diff --git a/locale/findlocale.c b/locale/findlocale.c +index 360f58b..5e2639b 100644 +--- a/locale/findlocale.c ++++ b/locale/findlocale.c +@@ -161,7 +161,8 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, + loc_name = (char *) _nl_expand_alias (*name); + if (loc_name != NULL) + { +- data = _nl_load_locale_from_archive (category, &loc_name); ++ data = _nl_load_locale_from_archive (category, ++ (const char **) &loc_name); + if (__builtin_expect (data != NULL, 1)) + return data; + } diff --git a/SOURCES/glibc-rh971416-3.patch b/SOURCES/glibc-rh971416-3.patch new file mode 100644 index 00000000..695ffe1c --- /dev/null +++ b/SOURCES/glibc-rh971416-3.patch @@ -0,0 +1,112 @@ +commit e7f07af50b231d3ade6b4d338a65d6b571f96116 +Author: Alexandre Oliva +Date: Fri Feb 27 22:18:56 2015 -0300 + + Avoid unsafe loc_name type casts with additional variable + + for ChangeLog + + [BZ #15969] + * locale/findlocale.c (_nl_find_locale): Introduce const + version of loc_name and drop unsafe type casts. + +diff --git a/locale/findlocale.c b/locale/findlocale.c +index 5e2639b..9e7df12 100644 +--- a/locale/findlocale.c ++++ b/locale/findlocale.c +@@ -105,7 +105,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, + { + int mask; + /* Name of the locale for this category. */ +- char *loc_name = (char *) *name; ++ const char *cloc_name = *name; + const char *language; + const char *modifier; + const char *territory; +@@ -113,39 +113,39 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, + const char *normalized_codeset; + struct loaded_l10nfile *locale_file; + +- if (loc_name[0] == '\0') ++ if (cloc_name[0] == '\0') + { + /* The user decides which locale to use by setting environment + variables. */ +- loc_name = getenv ("LC_ALL"); +- if (!name_present (loc_name)) +- loc_name = getenv (_nl_category_names.str +- + _nl_category_name_idxs[category]); +- if (!name_present (loc_name)) +- loc_name = getenv ("LANG"); +- if (!name_present (loc_name)) +- loc_name = (char *) _nl_C_name; ++ cloc_name = getenv ("LC_ALL"); ++ if (!name_present (cloc_name)) ++ cloc_name = getenv (_nl_category_names.str ++ + _nl_category_name_idxs[category]); ++ if (!name_present (cloc_name)) ++ cloc_name = getenv ("LANG"); ++ if (!name_present (cloc_name)) ++ cloc_name = _nl_C_name; + } + + /* We used to fall back to the C locale if the name contains a slash + character '/', but we now check for directory traversal in + valid_locale_name, so this is no longer necessary. */ + +- if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0 +- || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0) ++ if (__builtin_expect (strcmp (cloc_name, _nl_C_name), 1) == 0 ++ || __builtin_expect (strcmp (cloc_name, _nl_POSIX_name), 1) == 0) + { + /* We need not load anything. The needed data is contained in + the library itself. */ +- *name = (char *) _nl_C_name; ++ *name = _nl_C_name; + return _nl_C[category]; + } +- else if (!valid_locale_name (loc_name)) ++ else if (!valid_locale_name (cloc_name)) + { + __set_errno (EINVAL); + return NULL; + } + +- *name = loc_name; ++ *name = cloc_name; + + /* We really have to load some data. First we try the archive, + but only if there was no LOCPATH environment variable specified. */ +@@ -158,11 +158,10 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, + + /* Nothing in the archive with the given name. Expanding it as + an alias and retry. */ +- loc_name = (char *) _nl_expand_alias (*name); +- if (loc_name != NULL) ++ cloc_name = _nl_expand_alias (*name); ++ if (cloc_name != NULL) + { +- data = _nl_load_locale_from_archive (category, +- (const char **) &loc_name); ++ data = _nl_load_locale_from_archive (category, &cloc_name); + if (__builtin_expect (data != NULL, 1)) + return data; + } +@@ -175,14 +174,14 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len, + /* We really have to load some data. First see whether the name is + an alias. Please note that this makes it impossible to have "C" + or "POSIX" as aliases. */ +- loc_name = (char *) _nl_expand_alias (*name); ++ cloc_name = _nl_expand_alias (*name); + +- if (loc_name == NULL) ++ if (cloc_name == NULL) + /* It is no alias. */ +- loc_name = (char *) *name; ++ cloc_name = *name; + + /* Make a writable copy of the locale name. */ +- loc_name = strdupa (loc_name); ++ char *loc_name = strdupa (cloc_name); + + /* LOCALE can consist of up to four recognized parts for the XPG syntax: diff --git a/SOURCES/glibc-rh971589.patch b/SOURCES/glibc-rh971589.patch new file mode 100644 index 00000000..7aa329d0 --- /dev/null +++ b/SOURCES/glibc-rh971589.patch @@ -0,0 +1,37 @@ +# +# Needs to go upstream. +# +# 2013-09-13 Carlos O'Donell +# +# * manual/crypt.tex (Cryptographic Functions): Using SunRPC and +# AUTH_DES will prevent FIPS 140-2 compliance. Add cindex for +# AUTH_DES and FIPS 140-2. +# (DES Encryption): Add cindex FIPS 46-3. +# +--- glibc-2.17-c758a686/manual/crypt.texi 2013-09-13 03:02:40.891987663 -0400 ++++ glibc-2.17-c758a686/manual/crypt.texi 2013-09-13 03:04:02.082380415 -0400 +@@ -30,8 +30,15 @@ + and the other based on the Data Encryption Standard (DES) that is + compatible with Unix systems. + ++@cindex AUTH_DES ++@cindex FIPS 140-2 + It also provides support for Secure RPC, and some library functions that +-can be used to perform normal DES encryption. ++can be used to perform normal DES encryption. The use of DES when ++using @code{AUTH_DES} in Secure RPC for authentication as provided by ++@theglibc{} is not FIPS 140-2 compliant nor is any other use of DES ++within @theglibc{}. It is recommended that Secure RPC should not be used ++for systems that need to be FIPS 140-2 compliant since all forms of ++supported authentication use normal DES. + + @menu + * Legal Problems:: This software can get you locked up, or worse. +@@ -203,6 +210,7 @@ + @node DES Encryption + @section DES Encryption + ++@cindex FIPS 46-3 + The Data Encryption Standard is described in the US Government Federal + Information Processing Standards (FIPS) 46-3 published by the National + Institute of Standards and Technology. The DES has been very thoroughly diff --git a/SOURCES/glibc-rh977110-2.patch b/SOURCES/glibc-rh977110-2.patch new file mode 100644 index 00000000..f57e27b8 --- /dev/null +++ b/SOURCES/glibc-rh977110-2.patch @@ -0,0 +1,101 @@ +From 3f38cbfa2a44bf510122d3fcb0f0504a208dbf5e Mon Sep 17 00:00:00 2001 +From: Adhemerval Zanella +Date: Fri, 15 Mar 2013 10:58:56 -0300 +Subject: [PATCH 19/42] PowerPC: gettimeofday optimization by using IFUNC + (backported from commit + ef26eece6331a1f6d959818e37c438cc7ce68e53) + +--- + sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h | 10 +++++ + sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 48 +++++++++++++++++------- + 3 files changed, 52 insertions(+), 13 deletions(-) + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +index cda8491..e4ae630 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +@@ -32,6 +32,16 @@ extern void *__vdso_get_tbfreq; + + extern void *__vdso_getcpu; + ++/* This macro is needed for PPC64 to return a skeleton OPD entry of a vDSO ++ symbol. This works because _dl_vdso_vsym always return the function ++ address, and no vDSO symbols use the TOC or chain pointers from the OPD ++ so we can allow them to be garbage. */ ++#if defined(__PPC64__) || defined(__powerpc64__) ++#define VDSO_IFUNC_RET(value) &value ++#else ++#define VDSO_IFUNC_RET(value) value ++#endif ++ + #endif + + #endif /* _LIBC_VDSO_H */ +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +index 7376135..4f4abbd 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c +@@ -15,26 +15,48 @@ + License along with the GNU C Library; if not, see + . */ + +-#include +-#include +-#include + #include +-#include +-#include + +-#include ++#ifdef SHARED + +-/* Get the current time of day and timezone information, +- putting it into *TV and *TZ. If TZ is NULL, *TZ is not filled. +- Returns 0 on success, -1 on errors. */ ++# include ++# include ++ ++void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday"); ++ ++static int ++__gettimeofday_syscall (struct timeval *tv, struct timezone *tz) ++{ ++ return INLINE_SYSCALL (gettimeofday, 2, tv, tz); ++} ++ ++void * ++gettimeofday_ifunc (void) ++{ ++ /* If the vDSO is not available we fall back syscall. */ ++ return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday) ++ : __gettimeofday_syscall); ++} ++asm (".type __gettimeofday, %gnu_indirect_function"); ++ ++/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't ++ let us do it in C because it doesn't know we're defining __gettimeofday ++ here in this file. */ ++asm (".globl __GI___gettimeofday\n" ++ "__GI___gettimeofday = __gettimeofday"); ++ ++#else ++ ++# include ++# include + + int +-__gettimeofday (tv, tz) +- struct timeval *tv; +- struct timezone *tz; ++__gettimeofday (struct timeval *tv, struct timezone *tz) + { +- return INLINE_VSYSCALL (gettimeofday, 2, CHECK_1 (tv), CHECK_1 (tz)); ++ return INLINE_SYSCALL (gettimeofday, 2, tv, tz); + } + libc_hidden_def (__gettimeofday) ++ ++#endif + weak_alias (__gettimeofday, gettimeofday) + libc_hidden_weak (gettimeofday) +-- +1.7.11.7 diff --git a/SOURCES/glibc-rh977110.patch b/SOURCES/glibc-rh977110.patch new file mode 100644 index 00000000..3f4f911a --- /dev/null +++ b/SOURCES/glibc-rh977110.patch @@ -0,0 +1,76 @@ +diff -pruN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h 2013-08-05 16:56:30.295860152 +0530 +@@ -30,6 +30,8 @@ extern void *__vdso_clock_getres; + + extern void *__vdso_get_tbfreq; + ++extern void *__vdso_getcpu; ++ + #endif + + #endif /* _LIBC_VDSO_H */ +diff -pruN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/init-first.c 2013-08-05 16:56:30.318860151 +0530 +@@ -27,6 +27,7 @@ void *__vdso_gettimeofday attribute_hidd + void *__vdso_clock_gettime; + void *__vdso_clock_getres; + void *__vdso_get_tbfreq; ++void *__vdso_getcpu; + + + static inline void +@@ -41,6 +42,8 @@ _libc_vdso_platform_setup (void) + __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615); + + __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615); ++ ++ __vdso_getcpu = _dl_vdso_vsym ("__kernel_getcpu", &linux2615); + } + + # define VDSO_SETUP _libc_vdso_platform_setup +diff -pruN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c 1970-01-01 05:30:00.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/sched_getcpu.c 2013-08-05 16:56:30.319860151 +0530 +@@ -0,0 +1,30 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++ ++ ++int ++sched_getcpu (void) ++{ ++ unsigned int cpu; ++ int r = INLINE_VSYSCALL (getcpu, 3, &cpu, NULL, NULL); ++ ++ return r == -1 ? r : cpu; ++} +diff -pruN glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/powerpc/Versions 2013-08-05 16:56:30.294860152 +0530 +@@ -3,5 +3,6 @@ libc { + __vdso_get_tbfreq; + __vdso_clock_gettime; + __vdso_clock_getres; ++ __vdso_getcpu; + } + } diff --git a/SOURCES/glibc-rh977870.patch b/SOURCES/glibc-rh977870.patch new file mode 100644 index 00000000..87bb0a62 --- /dev/null +++ b/SOURCES/glibc-rh977870.patch @@ -0,0 +1,67 @@ +commit d755bba40f880c01ced8740a26fecc85534454b9 +Author: Siddhesh Poyarekar +Date: Wed Apr 3 10:56:45 2013 +0530 + + Preserve errno across _PC_CHOWN_RESTRICTED call on XFS + + Fix BZ #15305. + + On kernel versions earlier than 2.6.29, the Linux kernel exported a + sysctl called restrict_chown for xfs, which could be used to allow + chown to users other than the owner. 2.6.29 removed this support, + causing the open_not_cancel_2 to fail and thus modify errno. The fix + is to save and restore errno so that the caller sees it as unmodified. + + Additionally, since the code to check the sysctl is not useful on + newer kernels, we add an ifdef so that in future the code block gets + rmeoved completely. + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/kernel-features.h glibc-2.17-c758a686/sysdeps/unix/sysv/linux/kernel-features.h +index 8fdff7e..ccd4c59 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/kernel-features.h ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/kernel-features.h +@@ -221,3 +221,9 @@ + #if defined __x86_64__ && __LINUX_KERNEL_VERSION >= 0x030100 + # define __ASSUME_GETCPU_SYSCALL 1 + #endif ++ ++/* 2.6.29 removed the XFS restricted_chown sysctl, so it is pointless looking ++ for it in newer kernels. */ ++#if __LINUX_KERNEL_VERSION >= 0x02061d ++# define __ASSUME_XFS_RESTRICTED_CHOWN 1 ++#endif +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c +index de91a45..723d234 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c +@@ -289,11 +289,16 @@ __statfs_chown_restricted (int result, const struct statfs *fsbuf) + return -1; + } + ++#if __ASSUME_XFS_RESTRICTED_CHOWN ++ return 1; ++#else + int fd; ++ int save_errno; + long int retval = 1; + switch (fsbuf->f_type) + { + case XFS_SUPER_MAGIC: ++ save_errno = errno; + /* Read the value from /proc/sys/fs/xfs/restrict_chown. If we cannot + read it default to assume the restriction is in place. */ + fd = open_not_cancel_2 ("/proc/sys/fs/xfs/restrict_chown", O_RDONLY); +@@ -306,6 +311,7 @@ __statfs_chown_restricted (int result, const struct statfs *fsbuf) + + close_not_cancel_no_status (fd); + } ++ __set_errno (save_errno); + break; + + default: +@@ -313,4 +319,5 @@ __statfs_chown_restricted (int result, const struct statfs *fsbuf) + } + + return retval; ++#endif + } diff --git a/SOURCES/glibc-rh977872.patch b/SOURCES/glibc-rh977872.patch new file mode 100644 index 00000000..fe118b33 --- /dev/null +++ b/SOURCES/glibc-rh977872.patch @@ -0,0 +1,268 @@ +commit adbb8027be47b3295367019b2f45863ea3d6c727 +Author: Siddhesh Poyarekar +Date: Thu Mar 7 12:15:08 2013 +0530 + + Remove PIPE_BUF Linux-specific code + + Fixes BZ #12723 + + The variable pipe buffer size does nothing to the value of PIPE_BUF, + since the number of bytes that are atomically written is still + PIPE_BUF on Linux. + +diff --git glibc-2.17-c758a686/posix/Makefile glibc-2.17-c758a686/posix/Makefile +index 2cacd21..658c47e 100644 +--- glibc-2.17-c758a686/posix/Makefile ++++ glibc-2.17-c758a686/posix/Makefile +@@ -86,7 +86,8 @@ tests := tstgetopt testfnm runtests runptests \ + tst-rfc3484-3 \ + tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \ + bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \ +- bug-getopt5 tst-getopt_long1 bug-regex34 ++ bug-getopt5 tst-getopt_long1 bug-regex34 \ ++ tst-pathconf + xtests := bug-ga2 + ifeq (yes,$(build-shared)) + test-srcs := globtest +diff --git glibc-2.17-c758a686/posix/tst-pathconf.c glibc-2.17-c758a686/posix/tst-pathconf.c +new file mode 100644 +index 0000000..7627a24 +--- /dev/null ++++ glibc-2.17-c758a686/posix/tst-pathconf.c +@@ -0,0 +1,176 @@ ++/* Test that values of pathconf and fpathconf are consistent for a file. ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++static void prepare (void); ++#define PREPARE(argc, argv) prepare () ++ ++static int do_test (void); ++#define TEST_FUNCTION do_test () ++ ++#include "../test-skeleton.c" ++ ++static int dir_fd; ++static char *dirbuf; ++ ++static void ++prepare (void) ++{ ++ size_t test_dir_len = strlen (test_dir); ++ static const char dir_name[] = "/tst-pathconf.XXXXXX"; ++ ++ size_t dirbuflen = test_dir_len + sizeof (dir_name); ++ dirbuf = malloc (dirbuflen); ++ if (dirbuf == NULL) ++ { ++ puts ("Out of memory"); ++ exit (1); ++ } ++ ++ snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name); ++ if (mkdtemp (dirbuf) == NULL) ++ { ++ printf ("Cannot create temporary directory: %s\n", strerror (errno)); ++ exit (1); ++ } ++ ++ add_temp_file (dirbuf); ++ ++ dir_fd = open (dirbuf, O_RDONLY); ++ if (dir_fd == -1) ++ { ++ printf ("Cannot open directory: %s\n", strerror (errno)); ++ exit (1); ++ } ++} ++ ++ ++static int ++do_test (void) ++{ ++ int ret = 0; ++ static const char *fifo_name = "some-fifo"; ++ ++ size_t filenamelen = strlen (dirbuf) + strlen (fifo_name) + 2; ++ char *filename = malloc (filenamelen); ++ ++ snprintf (filename, filenamelen, "%s/%s", dirbuf, fifo_name); ++ ++ /* Create a fifo in the directory. */ ++ int e = mkfifo (filename, 0777); ++ if (e == -1) ++ { ++ printf ("fifo creation failed (%s)\n", strerror (errno)); ++ ret = 1; ++ goto out_nofifo; ++ } ++ ++ long dir_pathconf = pathconf (dirbuf, _PC_PIPE_BUF); ++ ++ if (dir_pathconf < 0) ++ { ++ printf ("pathconf on directory failed: %s\n", strerror (errno)); ++ ret = 1; ++ goto out_nofifo; ++ } ++ ++ long fifo_pathconf = pathconf (filename, _PC_PIPE_BUF); ++ ++ if (fifo_pathconf < 0) ++ { ++ printf ("pathconf on file failed: %s\n", strerror (errno)); ++ ret = 1; ++ goto out_nofifo; ++ } ++ ++ int fifo = open (filename, O_RDONLY | O_NONBLOCK); ++ ++ if (fifo < 0) ++ { ++ printf ("fifo open failed (%s)\n", strerror (errno)); ++ ret = 1; ++ goto out_nofifo; ++ } ++ ++ long dir_fpathconf = fpathconf (dir_fd, _PC_PIPE_BUF); ++ ++ if (dir_fpathconf < 0) ++ { ++ printf ("fpathconf on directory failed: %s\n", strerror (errno)); ++ ret = 1; ++ goto out; ++ } ++ ++ long fifo_fpathconf = fpathconf (fifo, _PC_PIPE_BUF); ++ ++ if (fifo_fpathconf < 0) ++ { ++ printf ("fpathconf on file failed: %s\n", strerror (errno)); ++ ret = 1; ++ goto out; ++ } ++ ++ if (fifo_pathconf != fifo_fpathconf) ++ { ++ printf ("fifo pathconf (%ld) != fifo fpathconf (%ld)\n", fifo_pathconf, ++ fifo_fpathconf); ++ ret = 1; ++ goto out; ++ } ++ ++ if (dir_pathconf != fifo_pathconf) ++ { ++ printf ("directory pathconf (%ld) != fifo pathconf (%ld)\n", ++ dir_pathconf, fifo_pathconf); ++ ret = 1; ++ goto out; ++ } ++ ++ if (dir_fpathconf != fifo_fpathconf) ++ { ++ printf ("directory fpathconf (%ld) != fifo fpathconf (%ld)\n", ++ dir_fpathconf, fifo_fpathconf); ++ ret = 1; ++ goto out; ++ } ++ ++out: ++ close (fifo); ++out_nofifo: ++ close (dir_fd); ++ ++ if (unlink (filename) != 0) ++ { ++ printf ("Could not remove fifo (%s)\n", strerror (errno)); ++ ret = 1; ++ } ++ ++ if (rmdir (dirbuf) != 0) ++ { ++ printf ("Could not remove directory (%s)\n", strerror (errno)); ++ ret = 1; ++ } ++ ++ return ret; ++} +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/fpathconf.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/fpathconf.c +index c971644..e8c4dc9 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/fpathconf.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/fpathconf.c +@@ -33,7 +33,6 @@ __fpathconf (fd, name) + int name; + { + struct statfs fsbuf; +- int r; + + switch (name) + { +@@ -49,12 +48,6 @@ __fpathconf (fd, name) + case _PC_CHOWN_RESTRICTED: + return __statfs_chown_restricted (__fstatfs (fd, &fsbuf), &fsbuf); + +- case _PC_PIPE_BUF: +- r = __fcntl (fd, F_GETPIPE_SZ); +- if (r > 0) +- return r; +- /* FALLTHROUGH */ +- + default: + return posix_fpathconf (fd, name); + } +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c +index edc691e..de91a45 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/pathconf.c +@@ -39,8 +39,6 @@ long int + __pathconf (const char *file, int name) + { + struct statfs fsbuf; +- int fd; +- int flags; + + switch (name) + { +@@ -56,21 +54,6 @@ __pathconf (const char *file, int name) + case _PC_CHOWN_RESTRICTED: + return __statfs_chown_restricted (__statfs (file, &fsbuf), &fsbuf); + +- case _PC_PIPE_BUF: +- flags = O_RDONLY|O_NONBLOCK|O_NOCTTY; +-#ifdef O_CLOEXEC +- flags |= O_CLOEXEC; +-#endif +- fd = open_not_cancel_2 (file, flags); +- if (fd >= 0) +- { +- long int r = __fcntl (fd, F_GETPIPE_SZ); +- close_not_cancel_no_status (fd); +- if (r > 0) +- return r; +- } +- /* FALLTHROUGH */ +- + default: + return posix_pathconf (file, name); + } diff --git a/SOURCES/glibc-rh977874.patch b/SOURCES/glibc-rh977874.patch new file mode 100644 index 00000000..8bff3c31 --- /dev/null +++ b/SOURCES/glibc-rh977874.patch @@ -0,0 +1,148 @@ +commit 7da6d9ed266105e0ebefd01a4b6bf08bf56257c3 +Author: Siddhesh Poyarekar +Date: Tue Feb 26 14:24:40 2013 +0530 + + Fix FPE in memusagestat when malloc utilization is zero + + [BZ #15160] + + Draw graphs for heap and stack only if MAXSIZE_HEAP and MAXSIZE_STACK + are non-zero. + +diff --git glibc-2.17-c758a686/malloc/memusagestat.c glibc-2.17-c758a686/malloc/memusagestat.c +index f561e0d..7bbd009 100644 +--- glibc-2.17-c758a686/malloc/memusagestat.c ++++ glibc-2.17-c758a686/malloc/memusagestat.c +@@ -319,17 +319,26 @@ main (int argc, char *argv[]) + + for (line = 1; line <= 3; ++line) + { +- cnt = ((ysize - 40) * (maxsize_heap / 4 * line / heap_scale)) / +- (maxsize_heap / heap_scale); +- gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40, +- ysize - 20 - cnt, red); +- snprintf (buf, sizeof (buf), heap_format, maxsize_heap / 4 * line / +- heap_scale); +- gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, +- ysize - 26 - cnt, (unsigned char *) buf, red); +- +- cnt2 = ((ysize - 40) * (maxsize_stack / 4 * line / stack_scale)) / +- (maxsize_stack / stack_scale); ++ if (maxsize_heap > 0) ++ { ++ cnt = (((ysize - 40) * (maxsize_heap / 4 * line / heap_scale)) ++ / (maxsize_heap / heap_scale)); ++ gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40, ++ ysize - 20 - cnt, red); ++ snprintf (buf, sizeof (buf), heap_format, ++ maxsize_heap / 4 * line / heap_scale); ++ gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, ++ ysize - 26 - cnt, (unsigned char *) buf, red); ++ } ++ else ++ cnt = 0; ++ ++ if (maxsize_stack > 0) ++ cnt2 = (((ysize - 40) * (maxsize_stack / 4 * line / stack_scale)) ++ / (maxsize_stack / stack_scale)); ++ else ++ cnt2 = 0; ++ + if (cnt != cnt2) + gdImageDashedLine (im_out, 40, ysize - 20 - cnt2, xsize - 40, + ysize - 20 - cnt2, green); +@@ -372,7 +381,7 @@ main (int argc, char *argv[]) + ysize - 14, yellow); + previously = now; + +- if (also_total) ++ if (also_total && maxsize_heap > 0) + { + size_t new3; + +@@ -386,21 +395,27 @@ main (int argc, char *argv[]) + last_total = new3; + } + +- // assert (entry.heap <= maxsize_heap); +- new[0] = (ysize - 20) - ((((unsigned long long int) (ysize - 40)) +- * entry.heap) / maxsize_heap); +- gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total, +- last_heap, 40 + ((xsize - 80) * cnt) / total, new[0], +- red); +- last_heap = new[0]; +- +- // assert (entry.stack <= maxsize_stack); +- new[1] = (ysize - 20) - ((((unsigned long long int) (ysize - 40)) +- * entry.stack) / maxsize_stack); +- gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total, +- last_stack, 40 + ((xsize - 80) * cnt) / total, new[1], +- green); +- last_stack = new[1]; ++ if (maxsize_heap > 0) ++ { ++ new[0] = ((ysize - 20) ++ - ((((unsigned long long int) (ysize - 40)) ++ * entry.heap) / maxsize_heap)); ++ gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total, ++ last_heap, 40 + ((xsize - 80) * cnt) / total, ++ new[0], red); ++ last_heap = new[0]; ++ } ++ ++ if (maxsize_stack > 0) ++ { ++ new[1] = ((ysize - 20) ++ - ((((unsigned long long int) (ysize - 40)) ++ * entry.stack) / maxsize_stack)); ++ gdImageLine (im_out, 40 + ((xsize - 80) * (cnt - 1)) / total, ++ last_stack, 40 + ((xsize - 80) * cnt) / total, ++ new[1], green); ++ last_stack = new[1]; ++ } + } + + cnt = 0; +@@ -448,7 +463,7 @@ main (int argc, char *argv[]) + next_tick += MAX (1, total / 20); + } + +- if (also_total) ++ if (also_total && maxsize_heap > 0) + { + size_t new3; + +@@ -459,16 +474,24 @@ main (int argc, char *argv[]) + last_total = new3; + } + +- new[0] = (ysize - 20) - ((((unsigned long long int) (ysize - 40)) +- * entry.heap) / maxsize_heap); +- gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red); +- last_heap = new[0]; ++ if (maxsize_heap > 0) ++ { ++ new[0] = ((ysize - 20) ++ - ((((unsigned long long int) (ysize - 40)) ++ * entry.heap) / maxsize_heap)); ++ gdImageLine (im_out, last_xpos, last_heap, xpos, new[0], red); ++ last_heap = new[0]; ++ } + +- // assert (entry.stack <= maxsize_stack); +- new[1] = (ysize - 20) - ((((unsigned long long int) (ysize - 40)) +- * entry.stack) / maxsize_stack); +- gdImageLine (im_out, last_xpos, last_stack, xpos, new[1], green); +- last_stack = new[1]; ++ if (maxsize_stack > 0) ++ { ++ new[1] = ((ysize - 20) ++ - ((((unsigned long long int) (ysize - 40)) ++ * entry.stack) / maxsize_stack)); ++ gdImageLine (im_out, last_xpos, last_stack, xpos, new[1], ++ green); ++ last_stack = new[1]; ++ } + + last_xpos = xpos; + } diff --git a/SOURCES/glibc-rh977875.patch b/SOURCES/glibc-rh977875.patch new file mode 100644 index 00000000..c0431f12 --- /dev/null +++ b/SOURCES/glibc-rh977875.patch @@ -0,0 +1,96 @@ +commit abe7f530bf5c741fe6f0658da7be59d8db168f7f +Author: Siddhesh Poyarekar +Date: Wed Apr 10 11:31:46 2013 +0530 + + Accept leading and trailing spaces in getdate input string + + Fixes #15346. + + The POSIX description of getdate allows for extra spaces in the + getdate input string. __getdate_r uses strptime internally, which + works fine with extra spaces between format strings (and hence within + an input string) but not with leading and trailing spaces. So we trim + off the leading and trailing spaces before we pass it on to strptime. + +diff --git glibc-2.17-c758a686/time/getdate.c glibc-2.17-c758a686/time/getdate.c +index 637dd18..eadebc3 100644 +--- glibc-2.17-c758a686/time/getdate.c ++++ glibc-2.17-c758a686/time/getdate.c +@@ -25,6 +25,8 @@ + #include + #include + #include ++#include ++#include + + #define TM_YEAR_BASE 1900 + +@@ -135,6 +137,44 @@ __getdate_r (const char *string, struct tm *tp) + /* No threads reading this stream. */ + __fsetlocking (fp, FSETLOCKING_BYCALLER); + ++ /* Skip leading whitespace. */ ++ while (isspace (*string)) ++ string++; ++ ++ size_t inlen, oldlen; ++ ++ oldlen = inlen = strlen (string); ++ ++ /* Skip trailing whitespace. */ ++ while (inlen > 0 && isspace (string[inlen - 1])) ++ inlen--; ++ ++ char *instr = NULL; ++ ++ if (inlen < oldlen) ++ { ++ bool using_malloc = false; ++ ++ if (__libc_use_alloca (inlen + 1)) ++ instr = alloca (inlen + 1); ++ else ++ { ++ instr = malloc (inlen + 1); ++ if (instr == NULL) ++ { ++ fclose (fp); ++ return 6; ++ } ++ using_malloc = true; ++ } ++ memcpy (instr, string, inlen); ++ instr[inlen] = '\0'; ++ string = instr; ++ ++ if (!using_malloc) ++ instr = NULL; ++ } ++ + line = NULL; + len = 0; + do +@@ -159,6 +199,8 @@ __getdate_r (const char *string, struct tm *tp) + } + while (!feof_unlocked (fp)); + ++ free (instr); ++ + /* Free the buffer. */ + free (line); + +diff --git glibc-2.17-c758a686/time/tst-getdate.c glibc-2.17-c758a686/time/tst-getdate.c +index 7604e83..dc8ecf4 100644 +--- glibc-2.17-c758a686/time/tst-getdate.c ++++ glibc-2.17-c758a686/time/tst-getdate.c +@@ -31,6 +31,10 @@ static const struct + } tests [] = + { + {"21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}}, ++ {"21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}}, ++ {" 21:01:10 1999-1-31", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}}, ++ {"21:01:10 1999-1-31 ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}}, ++ {" 21:01:10 1999-1-31 ", "Universal", 0, {10, 1, 21, 31, 0, 99, 0, 0, 0}}, + {"21:01:10 1999-2-28", "Universal", 0, {10, 1, 21, 28, 1, 99, 0, 0, 0}}, + {"16:30:46 2000-2-29", "Universal", 0, {46, 30,16, 29, 1, 100, 0, 0, 0}}, + {"01-08-2000 05:06:07", "Europe/Berlin", 0, {7, 6, 5, 1, 7, 100, 0, 0, 0}} diff --git a/SOURCES/glibc-rh977887-2.patch b/SOURCES/glibc-rh977887-2.patch new file mode 100644 index 00000000..dedc5fd3 --- /dev/null +++ b/SOURCES/glibc-rh977887-2.patch @@ -0,0 +1,337 @@ +commit 2506109403de69bd454de27835d42e6eb6ec3abc +Author: Siddhesh Poyarekar +Date: Wed Jun 12 10:36:48 2013 +0530 + + Set/restore rounding mode only when needed + + The most common use case of math functions is with default rounding + mode, i.e. rounding to nearest. Setting and restoring rounding mode + is an unnecessary overhead for this, so I've added support for a + context, which does the set/restore only if the FP status needs a + change. The code is written such that only x86 uses these. Other + architectures should be unaffected by it, but would definitely benefit + if the set/restore has as much overhead relative to the rest of the + code, as the x86 bits do. + + Here's a summary of the performance improvement due to these + improvements; I've only mentioned functions that use the set/restore + and have benchmark inputs for x86_64: + + Before: + + cos(): ITERS:4.69335e+08: TOTAL:28884.6Mcy, MAX:4080.28cy, MIN:57.562cy, 16248.6 calls/Mcy + exp(): ITERS:4.47604e+08: TOTAL:28796.2Mcy, MAX:207.721cy, MIN:62.385cy, 15543.9 calls/Mcy + pow(): ITERS:1.63485e+08: TOTAL:28879.9Mcy, MAX:362.255cy, MIN:172.469cy, 5660.86 calls/Mcy + sin(): ITERS:3.89578e+08: TOTAL:28900Mcy, MAX:704.859cy, MIN:47.583cy, 13480.2 calls/Mcy + tan(): ITERS:7.0971e+07: TOTAL:28902.2Mcy, MAX:1357.79cy, MIN:388.58cy, 2455.55 calls/Mcy + + After: + + cos(): ITERS:6.0014e+08: TOTAL:28875.9Mcy, MAX:364.283cy, MIN:45.716cy, 20783.4 calls/Mcy + exp(): ITERS:5.48578e+08: TOTAL:28764.9Mcy, MAX:191.617cy, MIN:51.011cy, 19071.1 calls/Mcy + pow(): ITERS:1.70013e+08: TOTAL:28873.6Mcy, MAX:689.522cy, MIN:163.989cy, 5888.18 calls/Mcy + sin(): ITERS:4.64079e+08: TOTAL:28891.5Mcy, MAX:6959.3cy, MIN:36.189cy, 16062.8 calls/Mcy + tan(): ITERS:7.2354e+07: TOTAL:28898.9Mcy, MAX:1295.57cy, MIN:380.698cy, 2503.7 calls/Mcy + + So the improvements are: + + cos: 27.9089% + exp: 22.6919% + pow: 4.01564% + sin: 19.1585% + tan: 1.96086% + + The downside of the change is that it will have an adverse performance + impact on non-default rounding modes, but I think the tradeoff is + justified. + +diff --git glibc-2.17-c758a686/include/fenv.h glibc-2.17-c758a686/include/fenv.h +index ed6d139..9f90d17 100644 +--- glibc-2.17-c758a686/include/fenv.h ++++ glibc-2.17-c758a686/include/fenv.h +@@ -1,5 +1,6 @@ + #ifndef _FENV_H + #include ++#include + + #ifndef _ISOMAC + /* Now define the internal interfaces. */ +@@ -23,4 +24,13 @@ libm_hidden_proto (fetestexcept) + libm_hidden_proto (feclearexcept) + #endif + ++/* Rounding mode context. This allows functions to set/restore rounding mode ++ only when the desired rounding mode is different from the current rounding ++ mode. */ ++struct rm_ctx ++{ ++ fenv_t env; ++ bool updated_status; ++}; ++ + #endif +diff --git glibc-2.17-c758a686/sysdeps/generic/math_private.h glibc-2.17-c758a686/sysdeps/generic/math_private.h +index e98360d..c0fc03d 100644 +--- glibc-2.17-c758a686/sysdeps/generic/math_private.h ++++ glibc-2.17-c758a686/sysdeps/generic/math_private.h +@@ -553,35 +553,62 @@ default_libc_feupdateenv_test (fenv_t *e, int ex) + # define libc_feresetround_noexl libc_fesetenvl + #endif + ++#if HAVE_RM_CTX ++/* Set/Restore Rounding Modes only when necessary. If defined, these functions ++ set/restore floating point state only if the state needed within the lexical ++ block is different from the current state. This saves a lot of time when ++ the floating point unit is much slower than the fixed point units. */ ++ ++# ifndef libc_feresetround_noex_ctx ++# define libc_feresetround_noex_ctx libc_fesetenv_ctx ++# endif ++# ifndef libc_feresetround_noexf_ctx ++# define libc_feresetround_noexf_ctx libc_fesetenvf_ctx ++# endif ++# ifndef libc_feresetround_noexl_ctx ++# define libc_feresetround_noexl_ctx libc_fesetenvl_ctx ++# endif ++ ++# ifndef libc_feholdsetround_53bit_ctx ++# define libc_feholdsetround_53bit_ctx libc_feholdsetround_ctx ++# endif ++ ++# ifndef libc_feresetround_53bit_ctx ++# define libc_feresetround_53bit_ctx libc_feresetround_ctx ++# endif ++ ++# define SET_RESTORE_ROUND_GENERIC(RM,ROUNDFUNC,CLEANUPFUNC) \ ++ struct rm_ctx ctx __attribute__((cleanup(CLEANUPFUNC ## _ctx))); \ ++ ROUNDFUNC ## _ctx (&ctx, (RM)) ++#else ++# define SET_RESTORE_ROUND_GENERIC(RM, ROUNDFUNC, CLEANUPFUNC) \ ++ fenv_t __libc_save_rm __attribute__((cleanup(CLEANUPFUNC))); \ ++ ROUNDFUNC (&__libc_save_rm, (RM)) ++#endif ++ + /* Save and restore the rounding mode within a lexical block. */ + + #define SET_RESTORE_ROUND(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround))); \ +- libc_feholdsetround (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround) + #define SET_RESTORE_ROUNDF(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetroundf))); \ +- libc_feholdsetroundf (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetroundf) + #define SET_RESTORE_ROUNDL(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetroundl))); \ +- libc_feholdsetroundl (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetroundl) + + /* Save and restore the rounding mode within a lexical block, and also + the set of exceptions raised within the block may be discarded. */ + + #define SET_RESTORE_ROUND_NOEX(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noex))); \ +- libc_feholdsetround (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround, libc_feresetround_noex) + #define SET_RESTORE_ROUND_NOEXF(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noexf))); \ +- libc_feholdsetroundf (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundf, libc_feresetround_noexf) + #define SET_RESTORE_ROUND_NOEXL(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_noexl))); \ +- libc_feholdsetroundl (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetroundl, libc_feresetround_noexl) + + /* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */ + #define SET_RESTORE_ROUND_53BIT(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_53bit))); \ +- libc_feholdsetround_53bit (&__libc_save_rm, (RM)) ++ SET_RESTORE_ROUND_GENERIC (RM, libc_feholdsetround_53bit, \ ++ libc_feresetround_53bit) + + #define __nan(str) \ + (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) +diff --git glibc-2.17-c758a686/sysdeps/i386/fpu/fenv_private.h glibc-2.17-c758a686/sysdeps/i386/fpu/fenv_private.h +index 1f8336c..3998387 100644 +--- glibc-2.17-c758a686/sysdeps/i386/fpu/fenv_private.h ++++ glibc-2.17-c758a686/sysdeps/i386/fpu/fenv_private.h +@@ -322,6 +322,179 @@ libc_feresetround_387 (fenv_t *e) + # define libc_feholdsetround_53bit libc_feholdsetround_387_53bit + #endif + ++/* We have support for rounding mode context. */ ++#define HAVE_RM_CTX 1 ++ ++static __always_inline void ++libc_feholdexcept_setround_sse_ctx (struct rm_ctx *ctx, int r) ++{ ++ unsigned int mxcsr, new_mxcsr; ++ asm (STMXCSR " %0" : "=m" (*&mxcsr)); ++ new_mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | (r << 3); ++ ++ ctx->env.__mxcsr = mxcsr; ++ if (__glibc_unlikely (mxcsr != new_mxcsr)) ++ { ++ asm volatile (LDMXCSR " %0" : : "m" (*&new_mxcsr)); ++ ctx->updated_status = true; ++ } ++ else ++ ctx->updated_status = false; ++} ++ ++/* Unconditional since we want to overwrite any exceptions that occurred in the ++ context. This is also why all fehold* functions unconditionally write into ++ ctx->env. */ ++static __always_inline void ++libc_fesetenv_sse_ctx (struct rm_ctx *ctx) ++{ ++ libc_fesetenv_sse (&ctx->env); ++} ++ ++static __always_inline void ++libc_feupdateenv_sse_ctx (struct rm_ctx *ctx) ++{ ++ if (__glibc_unlikely (ctx->updated_status)) ++ libc_feupdateenv_test_sse (&ctx->env, 0); ++} ++ ++static __always_inline void ++libc_feholdexcept_setround_387_prec_ctx (struct rm_ctx *ctx, int r) ++{ ++ libc_feholdexcept_387 (&ctx->env); ++ ++ fpu_control_t cw = ctx->env.__control_word; ++ fpu_control_t old_cw = cw; ++ cw &= ~(_FPU_RC_ZERO | _FPU_EXTENDED); ++ cw |= r | 0x3f; ++ ++ if (__glibc_unlikely (old_cw != cw)) ++ { ++ _FPU_SETCW (cw); ++ ctx->updated_status = true; ++ } ++ else ++ ctx->updated_status = false; ++} ++ ++static __always_inline void ++libc_feholdexcept_setround_387_ctx (struct rm_ctx *ctx, int r) ++{ ++ libc_feholdexcept_setround_387_prec_ctx (ctx, r | _FPU_EXTENDED); ++} ++ ++static __always_inline void ++libc_feholdexcept_setround_387_53bit_ctx (struct rm_ctx *ctx, int r) ++{ ++ libc_feholdexcept_setround_387_prec_ctx (ctx, r | _FPU_DOUBLE); ++} ++ ++static __always_inline void ++libc_feholdsetround_387_prec_ctx (struct rm_ctx *ctx, int r) ++{ ++ fpu_control_t cw, new_cw; ++ ++ _FPU_GETCW (cw); ++ new_cw = cw; ++ new_cw &= ~(_FPU_RC_ZERO | _FPU_EXTENDED); ++ new_cw |= r; ++ ++ ctx->env.__control_word = cw; ++ if (__glibc_unlikely (new_cw != cw)) ++ { ++ _FPU_SETCW (new_cw); ++ ctx->updated_status = true; ++ } ++ else ++ ctx->updated_status = false; ++} ++ ++static __always_inline void ++libc_feholdsetround_387_ctx (struct rm_ctx *ctx, int r) ++{ ++ libc_feholdsetround_387_prec_ctx (ctx, r | _FPU_EXTENDED); ++} ++ ++static __always_inline void ++libc_feholdsetround_387_53bit_ctx (struct rm_ctx *ctx, int r) ++{ ++ libc_feholdsetround_387_prec_ctx (ctx, r | _FPU_DOUBLE); ++} ++ ++static __always_inline void ++libc_feholdsetround_sse_ctx (struct rm_ctx *ctx, int r) ++{ ++ unsigned int mxcsr, new_mxcsr; ++ ++ asm (STMXCSR " %0" : "=m" (*&mxcsr)); ++ new_mxcsr = (mxcsr & ~0x6000) | (r << 3); ++ ++ ctx->env.__mxcsr = mxcsr; ++ if (__glibc_unlikely (new_mxcsr != mxcsr)) ++ { ++ asm volatile (LDMXCSR " %0" : : "m" (*&new_mxcsr)); ++ ctx->updated_status = true; ++ } ++ else ++ ctx->updated_status = false; ++} ++ ++static __always_inline void ++libc_feresetround_sse_ctx (struct rm_ctx *ctx) ++{ ++ if (__glibc_unlikely (ctx->updated_status)) ++ libc_feresetround_sse (&ctx->env); ++} ++ ++static __always_inline void ++libc_feresetround_387_ctx (struct rm_ctx *ctx) ++{ ++ if (__glibc_unlikely (ctx->updated_status)) ++ _FPU_SETCW (ctx->env.__control_word); ++} ++ ++static __always_inline void ++libc_feupdateenv_387_ctx (struct rm_ctx *ctx) ++{ ++ if (__glibc_unlikely (ctx->updated_status)) ++ libc_feupdateenv_test_387 (&ctx->env, 0); ++} ++ ++#ifdef __SSE_MATH__ ++# define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_sse_ctx ++# define libc_fesetenvf_ctx libc_fesetenv_sse_ctx ++# define libc_feupdateenvf_ctx libc_feupdateenv_sse_ctx ++# define libc_feholdsetroundf_ctx libc_feholdsetround_sse_ctx ++# define libc_feresetroundf_ctx libc_feresetround_sse_ctx ++#else ++# define libc_feholdexcept_setroundf_ctx libc_feholdexcept_setround_387_ctx ++# define libc_feupdateenvf_ctx libc_feupdateenv_387_ctx ++# define libc_feholdsetroundf_ctx libc_feholdsetround_387_ctx ++# define libc_feresetroundf_ctx libc_feresetround_387_ctx ++#endif /* __SSE_MATH__ */ ++ ++#ifdef __SSE2_MATH__ ++# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_sse_ctx ++# define libc_fesetenv_ctx libc_fesetenv_sse_ctx ++# define libc_feupdateenv_ctx libc_feupdateenv_sse_ctx ++# define libc_feholdsetround_ctx libc_feholdsetround_sse_ctx ++# define libc_feresetround_ctx libc_feresetround_sse_ctx ++#else ++# define libc_feholdexcept_setround_ctx libc_feholdexcept_setround_387_ctx ++# define libc_feupdateenv_ctx libc_feupdateenv_387_ctx ++# define libc_feresetround_ctx libc_feresetround_387_ctx ++#endif /* __SSE2_MATH__ */ ++ ++#define libc_feholdexcept_setroundl_ctx libc_feholdexcept_setround_387_ctx ++#define libc_feupdateenvl_ctx libc_feupdateenv_387_ctx ++#define libc_feholdsetroundl_ctx libc_feholdsetround_387_ctx ++#define libc_feresetroundl_ctx libc_feresetround_387_ctx ++ ++#ifndef __SSE2_MATH__ ++# define libc_feholdsetround_53bit_ctx libc_feholdsetround_387_53bit_ctx ++# define libc_feresetround_53bit_ctx libc_feresetround_387_ctx ++#endif ++ + #undef __mxcsr + + #endif /* FENV_PRIVATE_H */ diff --git a/SOURCES/glibc-rh977887.patch b/SOURCES/glibc-rh977887.patch new file mode 100644 index 00000000..2d4c570f --- /dev/null +++ b/SOURCES/glibc-rh977887.patch @@ -0,0 +1,46 @@ +commit 4c60cb0c8329dd498e9cce3735e5ee6212ad28f4 +Author: Siddhesh Poyarekar +Date: Wed Jun 5 13:56:19 2013 +0530 + + Skip modifying exception mask and flags in SET_RESTORE_ROUND_53BIT + + We only need to set/restore rounding mode to ensure correct + computation for non-default rounding modes. + +diff --git glibc-2.17-c758a686/sysdeps/generic/math_private.h glibc-2.17-c758a686/sysdeps/generic/math_private.h +index 9d6ecad..e98360d 100644 +--- glibc-2.17-c758a686/sysdeps/generic/math_private.h ++++ glibc-2.17-c758a686/sysdeps/generic/math_private.h +@@ -446,8 +446,8 @@ default_libc_feholdexcept_setround (fenv_t *e, int r) + # define libc_feholdexcept_setroundl default_libc_feholdexcept_setround + #endif + +-#ifndef libc_feholdexcept_setround_53bit +-# define libc_feholdexcept_setround_53bit libc_feholdexcept_setround ++#ifndef libc_feholdsetround_53bit ++# define libc_feholdsetround_53bit libc_feholdsetround + #endif + + #ifndef libc_fetestexcept +@@ -492,8 +492,8 @@ default_libc_feupdateenv (fenv_t *e) + # define libc_feupdateenvl default_libc_feupdateenv + #endif + +-#ifndef libc_feupdateenv_53bit +-# define libc_feupdateenv_53bit libc_feupdateenv ++#ifndef libc_feresetround_53bit ++# define libc_feresetround_53bit libc_feresetround + #endif + + static __always_inline int +@@ -580,8 +580,8 @@ default_libc_feupdateenv_test (fenv_t *e, int ex) + + /* Like SET_RESTORE_ROUND, but also set rounding precision to 53 bits. */ + #define SET_RESTORE_ROUND_53BIT(RM) \ +- fenv_t __libc_save_rm __attribute__((cleanup(libc_feupdateenv_53bit))); \ +- libc_feholdexcept_setround_53bit (&__libc_save_rm, (RM)) ++ fenv_t __libc_save_rm __attribute__((cleanup(libc_feresetround_53bit))); \ ++ libc_feholdsetround_53bit (&__libc_save_rm, (RM)) + + #define __nan(str) \ + (__builtin_constant_p (str) && str[0] == '\0' ? NAN : __nan (str)) diff --git a/SOURCES/glibc-rh979363.patch b/SOURCES/glibc-rh979363.patch new file mode 100644 index 00000000..eab6811c --- /dev/null +++ b/SOURCES/glibc-rh979363.patch @@ -0,0 +1,157 @@ +diff --git glibc-2.17-c758a686/libio/fileops.c glibc-2.17-c758a686/libio/fileops.c +index 61b61b3..5f3dae7 100644 +--- glibc-2.17-c758a686/libio/fileops.c ++++ glibc-2.17-c758a686/libio/fileops.c +@@ -1245,13 +1245,12 @@ _IO_new_file_write (f, data, n) + _IO_ssize_t n; + { + _IO_ssize_t to_do = n; +- _IO_ssize_t count = 0; + while (to_do > 0) + { +- count = (__builtin_expect (f->_flags2 +- & _IO_FLAGS2_NOTCANCEL, 0) +- ? write_not_cancel (f->_fileno, data, to_do) +- : write (f->_fileno, data, to_do)); ++ _IO_ssize_t count = (__builtin_expect (f->_flags2 ++ & _IO_FLAGS2_NOTCANCEL, 0) ++ ? write_not_cancel (f->_fileno, data, to_do) ++ : write (f->_fileno, data, to_do)); + if (count < 0) + { + f->_flags |= _IO_ERR_SEEN; +@@ -1263,7 +1262,7 @@ _IO_new_file_write (f, data, n) + n -= to_do; + if (f->_offset >= 0) + f->_offset += n; +- return count < 0 ? count : n; ++ return n; + } + + _IO_size_t +@@ -1323,13 +1322,11 @@ _IO_new_file_xsputn (f, data, n) + _IO_size_t block_size, do_write; + /* Next flush the (full) buffer. */ + if (_IO_OVERFLOW (f, EOF) == EOF) +- /* If nothing else has to be written or nothing has been written, we +- must not signal the caller that the call was even partially +- successful. */ +- return (to_do == 0 || to_do == n) ? EOF : n - to_do; ++ /* If nothing else has to be written we must not signal the ++ caller that everything has been written. */ ++ return to_do == 0 ? EOF : n - to_do; + +- /* Try to maintain alignment: write a whole number of blocks. +- dont_write is what gets left over. */ ++ /* Try to maintain alignment: write a whole number of blocks. */ + block_size = f->_IO_buf_end - f->_IO_buf_base; + do_write = to_do - (block_size >= 128 ? to_do % block_size : 0); + +diff --git glibc-2.17-c758a686/libio/iofwrite.c glibc-2.17-c758a686/libio/iofwrite.c +index 81596a6..66542ea 100644 +--- glibc-2.17-c758a686/libio/iofwrite.c ++++ glibc-2.17-c758a686/libio/iofwrite.c +@@ -42,12 +42,12 @@ _IO_fwrite (buf, size, count, fp) + if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1) + written = _IO_sputn (fp, (const char *) buf, request); + _IO_release_lock (fp); +- /* We are guaranteed to have written all of the input, none of it, or +- some of it. */ +- if (written == request) ++ /* We have written all of the input in case the return value indicates ++ this or EOF is returned. The latter is a special case where we ++ simply did not manage to flush the buffer. But the data is in the ++ buffer and therefore written as far as fwrite is concerned. */ ++ if (written == request || written == EOF) + return count; +- else if (written == EOF) +- return 0; + else + return written / size; + } +diff --git glibc-2.17-c758a686/libio/iofwrite_u.c glibc-2.17-c758a686/libio/iofwrite_u.c +index 4a9d6ca..18dc6d0 100644 +--- glibc-2.17-c758a686/libio/iofwrite_u.c ++++ glibc-2.17-c758a686/libio/iofwrite_u.c +@@ -44,12 +44,12 @@ fwrite_unlocked (buf, size, count, fp) + if (_IO_fwide (fp, -1) == -1) + { + written = _IO_sputn (fp, (const char *) buf, request); +- /* We are guaranteed to have written all of the input, none of it, or +- some of it. */ +- if (written == request) ++ /* We have written all of the input in case the return value indicates ++ this or EOF is returned. The latter is a special case where we ++ simply did not manage to flush the buffer. But the data is in the ++ buffer and therefore written as far as fwrite is concerned. */ ++ if (written == request || written == EOF) + return count; +- else if (written == EOF) +- return 0; + } + + return written / size; +diff --git glibc-2.17-c758a686/libio/iopadn.c glibc-2.17-c758a686/libio/iopadn.c +index cc93c0f..5ebbcf4 100644 +--- glibc-2.17-c758a686/libio/iopadn.c ++++ glibc-2.17-c758a686/libio/iopadn.c +@@ -59,7 +59,7 @@ _IO_padn (fp, pad, count) + w = _IO_sputn (fp, padptr, PADSIZE); + written += w; + if (w != PADSIZE) +- return w == EOF ? w : written; ++ return written; + } + + if (i > 0) +diff --git glibc-2.17-c758a686/libio/iowpadn.c glibc-2.17-c758a686/libio/iowpadn.c +index d94db71..5600f37 100644 +--- glibc-2.17-c758a686/libio/iowpadn.c ++++ glibc-2.17-c758a686/libio/iowpadn.c +@@ -65,7 +65,7 @@ _IO_wpadn (fp, pad, count) + w = _IO_sputn (fp, (char *) padptr, PADSIZE); + written += w; + if (w != PADSIZE) +- return w == EOF ? w : written; ++ return written; + } + + if (i > 0) +diff --git glibc-2.17-c758a686/stdio-common/vfprintf.c glibc-2.17-c758a686/stdio-common/vfprintf.c +index c8bcf5a..61d9dc2 100644 +--- glibc-2.17-c758a686/stdio-common/vfprintf.c ++++ glibc-2.17-c758a686/stdio-common/vfprintf.c +@@ -90,13 +90,13 @@ + do { \ + if (width > 0) \ + { \ +- unsigned int d = _IO_padn (s, (Padchar), width); \ +- if (__builtin_expect (d == EOF, 0)) \ ++ _IO_ssize_t written = _IO_padn (s, (Padchar), width); \ ++ if (__glibc_unlikely (written != width)) \ + { \ + done = -1; \ + goto all_done; \ + } \ +- done_add (d); \ ++ done_add (written); \ + } \ + } while (0) + # define PUTC(C, F) _IO_putc_unlocked (C, F) +@@ -119,13 +119,13 @@ + do { \ + if (width > 0) \ + { \ +- unsigned int d = _IO_wpadn (s, (Padchar), width); \ +- if (__builtin_expect (d == EOF, 0)) \ ++ _IO_ssize_t written = _IO_wpadn (s, (Padchar), width); \ ++ if (__glibc_unlikely (written != width)) \ + { \ + done = -1; \ + goto all_done; \ + } \ +- done_add (d); \ ++ done_add (written); \ + } \ + } while (0) + # define PUTC(C, F) _IO_putwc_unlocked (C, F) diff --git a/SOURCES/glibc-rh980323.patch b/SOURCES/glibc-rh980323.patch new file mode 100644 index 00000000..1dd5146b --- /dev/null +++ b/SOURCES/glibc-rh980323.patch @@ -0,0 +1,50 @@ +commit 1cef1b19089528db11f221e938f60b9b048945d7 +Author: Andreas Schwab +Date: Thu Mar 21 15:50:27 2013 +0100 + + Fix stack overflow in getaddrinfo with many results + +diff --git glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +index d95c2d1..2309281 100644 +--- glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c ++++ glibc-2.17-c758a686/sysdeps/posix/getaddrinfo.c +@@ -2489,11 +2489,27 @@ getaddrinfo (const char *name, const char *service, + __typeof (once) old_once = once; + __libc_once (once, gaiconf_init); + /* Sort results according to RFC 3484. */ +- struct sort_result results[nresults]; +- size_t order[nresults]; ++ struct sort_result *results; ++ size_t *order; + struct addrinfo *q; + struct addrinfo *last = NULL; + char *canonname = NULL; ++ bool malloc_results; ++ ++ malloc_results ++ = !__libc_use_alloca (nresults * (sizeof (*results) + sizeof (size_t))); ++ if (malloc_results) ++ { ++ results = malloc (nresults * (sizeof (*results) + sizeof (size_t))); ++ if (results == NULL) ++ { ++ __free_in6ai (in6ai); ++ return EAI_MEMORY; ++ } ++ } ++ else ++ results = alloca (nresults * (sizeof (*results) + sizeof (size_t))); ++ order = (size_t *) (results + nresults); + + /* Now we definitely need the interface information. */ + if (! check_pf_called) +@@ -2664,6 +2680,9 @@ getaddrinfo (const char *name, const char *service, + + /* Fill in the canonical name into the new first entry. */ + p->ai_canonname = canonname; ++ ++ if (malloc_results) ++ free (results); + } + + __free_in6ai (in6ai); diff --git a/SOURCES/glibc-rh981332.patch b/SOURCES/glibc-rh981332.patch new file mode 100644 index 00000000..f281ba37 --- /dev/null +++ b/SOURCES/glibc-rh981332.patch @@ -0,0 +1,263 @@ +diff -Nru glibc-2.17-c758a686/po/de.po glibc-2.17-c758a686/po/de.po +--- glibc-2.17-c758a686/po/de.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/de.po 2013-08-22 00:23:19.550362503 -0400 +@@ -6342,13 +6342,14 @@ msgstr "Zu viele Benutzer" + msgid "Disk quota exceeded" + msgstr "Der zugewiesene Plattenplatz (Quota) ist überschritten" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "Veraltete NFS-Dateizugriffsnummer" ++msgid "Stale file handle" ++msgstr "Veraltetes Datei-Handle" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/es.po glibc-2.17-c758a686/po/es.po +--- glibc-2.17-c758a686/po/es.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/es.po 2013-08-22 00:26:06.924362114 -0400 +@@ -6419,13 +6419,14 @@ msgstr "Se ha excedido la cuota de disco + # Muy bien, he buscado "stale" y por lo que parece es algo que "caduca" + # o que "vence", como las letras comerciales. Me he decidido por "en desuso". + # +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "`handle' de fichero NFS en desuso" ++msgid "Stale file handle" ++msgstr "Identificador de archivos obsoletos" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/fr.po glibc-2.17-c758a686/po/fr.po +--- glibc-2.17-c758a686/po/fr.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/fr.po 2013-08-22 00:27:48.381361856 -0400 +@@ -6236,13 +6236,14 @@ msgstr "Trop d'usagers" + msgid "Disk quota exceeded" + msgstr "Débordement du quota d'espace disque" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "Panne d'accès au fichier NFS" ++msgid "Stale file handle" ++msgstr "Gestionnaire de fichiers périmés" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/it.po glibc-2.17-c758a686/po/it.po +--- glibc-2.17-c758a686/po/it.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/it.po 2013-08-22 00:31:45.643299312 -0400 +@@ -6488,13 +6488,14 @@ msgstr "Troppi utenti" + msgid "Disk quota exceeded" + msgstr "Quota disco superata" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "Gestione del file NFS interrotta" ++msgid "Stale file handle" ++msgstr "Gestione file obsoleti" + + # lf + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that +diff -Nru glibc-2.17-c758a686/po/ja.po glibc-2.17-c758a686/po/ja.po +--- glibc-2.17-c758a686/po/ja.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/ja.po 2013-08-22 00:40:52.870361885 -0400 +@@ -6060,13 +6060,14 @@ msgstr "ユーザãŒå¤šã™ãŽã¾ã™" + msgid "Disk quota exceeded" + msgstr "ディスク使用é‡åˆ¶é™ã‚’超éŽã—ã¾ã—ãŸ" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "実効性ã®ãªã„NFSファイルãƒãƒ³ãƒ‰ãƒ«ã§ã™" ++msgid "Stale file handle" ++msgstr "å¤ã„ファイルãƒãƒ³ãƒ‰ãƒ«ã§ã™" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/ko.po glibc-2.17-c758a686/po/ko.po +--- glibc-2.17-c758a686/po/ko.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/ko.po 2013-08-22 01:26:54.047362067 -0400 +@@ -6076,13 +6076,14 @@ msgstr "사용ìžê°€ 너무 많ìŒ" + msgid "Disk quota exceeded" + msgstr "ë””ìŠ¤í¬ í• ë‹¹ëŸ‰ì´ ì´ˆê³¼ë¨" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "ëŠì–´ì§„ NFS íŒŒì¼ í•¸ë“¤" ++msgid "Stale file handle" ++msgstr "ì˜¤ëž˜ëœ íŒŒì¼ ì²˜ë¦¬" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/libc.pot glibc-2.17-c758a686/po/libc.pot +--- glibc-2.17-c758a686/po/libc.pot 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/libc.pot 2013-08-22 01:28:04.037362480 -0400 +@@ -6120,12 +6120,13 @@ msgstr "" + msgid "Disk quota exceeded" + msgstr "" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" ++msgid "Stale file handle" + msgstr "" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that +diff -Nru glibc-2.17-c758a686/po/pt_BR.po glibc-2.17-c758a686/po/pt_BR.po +--- glibc-2.17-c758a686/po/pt_BR.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/pt_BR.po 2013-08-22 00:57:47.845218981 -0400 +@@ -2287,13 +2287,14 @@ msgstr "Erro de Srmount" + msgid "Stack fault" + msgstr "Falha de pilha" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. +-#: stdio-common/../sysdeps/gnu/errlist.c:506 +-msgid "Stale NFS file handle" +-msgstr "Manipulador de arquivo NFS corrompido" ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. ++#: sysdeps/gnu/errlist.c:787 ++msgid "Stale file handle" ++msgstr "Manipulador de arquivo obsoleto" + + #: nscd/nscd.c:81 + msgid "Start NUMBER threads" +diff -Nru glibc-2.17-c758a686/po/ru.po glibc-2.17-c758a686/po/ru.po +--- glibc-2.17-c758a686/po/ru.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/ru.po 2013-08-22 01:00:36.824204890 -0400 +@@ -6243,13 +6243,14 @@ msgstr "Слишком много пол + msgid "Disk quota exceeded" + msgstr "Превышена диÑÐºÐ¾Ð²Ð°Ñ ÐºÐ²Ð¾Ñ‚Ð°" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "УÑтаревший деÑкриптор файла NFS" ++msgid "Stale file handle" ++msgstr "УÑтаревший деÑкриптор файла" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/zh_CN.po glibc-2.17-c758a686/po/zh_CN.po +--- glibc-2.17-c758a686/po/zh_CN.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/zh_CN.po 2013-08-22 01:02:42.089238124 -0400 +@@ -5519,13 +5519,14 @@ msgstr "用户过多" + msgid "Disk quota exceeded" + msgstr "超出ç£ç›˜é™é¢" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "" ++msgid "Stale file handle" ++msgstr "失效文件å¥æŸ„" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. +diff -Nru glibc-2.17-c758a686/po/zh_TW.po glibc-2.17-c758a686/po/zh_TW.po +--- glibc-2.17-c758a686/po/zh_TW.po 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/po/zh_TW.po 2013-08-22 01:05:36.949361791 -0400 +@@ -6060,13 +6060,14 @@ msgstr "太多使用者" + msgid "Disk quota exceeded" + msgstr "硬碟 quota 滿了" + +-#. TRANS Stale NFS file handle. This indicates an internal confusion in the NFS +-#. TRANS system which is due to file system rearrangements on the server host. +-#. TRANS Repairing this condition usually requires unmounting and remounting +-#. TRANS the NFS file system on the local host. ++#. TRANS Stale file handle. This indicates an internal confusion in the ++#. TRANS file system which is due to file system rearrangements on the server host ++#. TRANS for NFS filesystems or corruption in other filesystems. ++#. TRANS Repairing this condition usually requires unmounting, possibly ++#. TRANS repairing and remounting the file system. + #: sysdeps/gnu/errlist.c:787 +-msgid "Stale NFS file handle" +-msgstr "éŽèˆŠçš„ NFS 檔案控制碼" ++msgid "Stale file handle" ++msgstr "éŽèˆŠçš„檔案處ç†" + + #. TRANS An attempt was made to NFS-mount a remote file system with a file name that + #. TRANS already specifies an NFS-mounted file. diff --git a/SOURCES/glibc-rh984828.patch b/SOURCES/glibc-rh984828.patch new file mode 100644 index 00000000..f30faa98 --- /dev/null +++ b/SOURCES/glibc-rh984828.patch @@ -0,0 +1,239 @@ +#* CVE-2013-2207 Incorrectly granting access to another user's pseudo-terminal +# has been fixed by disabling the use of pt_chown (Bugzilla #15755). +# Distributions can re-enable building and using pt_chown via the new configure +# option `--enable-pt_chown'. Enabling the use of pt_chown carries with it +# considerable security risks and should only be used if the distribution +# understands and accepts the risks. +# +#2013-07-21 Siddhesh Poyarekar +# Andreas Schwab +# Roland McGrath +# Joseph Myers +# Carlos O'Donell +# +# [BZ #15755] +# * config.h.in: Define HAVE_PT_CHOWN. +# * config.make.in (build-pt-chown): New variable. +# * configure.in (--enable-pt_chown): New configure option. +# * configure: Regenerate. +# * login/Makefile: Include Makeconfig. Build pt_chown only if +# build-pt-chown is enabled. +# * sysdeps/unix/grantpt.c (grantpt) [HAVE_PT_CHOWN]: Spawn +# pt_chown to fix pty ownership. +# * sysdeps/unix/sysv/linux/grantpt.c [HAVE_PT_CHOWN]: Define +# CLOSE_ALL_FDS. +# * manual/install.texi (Configuring and compiling): Mention +# --enable-pt_chown. Add @findex for grantpt. +# * INSTALL: Regenerate. +# +diff -Nru glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686/config.h.in +--- glibc-2.17-c758a686/config.h.in 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/config.h.in 2013-07-24 00:20:07.651301252 -0400 +@@ -232,4 +232,7 @@ + /* The ARM hard-float ABI is being used. */ + #undef HAVE_ARM_PCS_VFP + ++/* The pt_chown binary is being built and used by grantpt. */ ++#undef HAVE_PT_CHOWN ++ + #endif +diff -Nru glibc-2.17-c758a686/config.make.in glibc-2.17-c758a686/config.make.in +--- glibc-2.17-c758a686/config.make.in 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/config.make.in 2013-07-24 00:21:15.244176098 -0400 +@@ -101,6 +101,7 @@ force-install = @force_install@ + link-obsolete-rpc = @link_obsolete_rpc@ + build-nscd = @build_nscd@ + use-nscd = @use_nscd@ ++build-pt-chown = @build_pt_chown@ + + # Build tools. + CC = @CC@ +diff -Nru glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure +--- glibc-2.17-c758a686/configure 2013-07-24 00:25:10.090174244 -0400 ++++ glibc-2.17-c758a686/configure 2013-07-24 00:20:07.769174345 -0400 +@@ -653,6 +653,7 @@ multi_arch + base_machine + add_on_subdirs + add_ons ++build_pt_chown + build_nscd + link_obsolete_rpc + libc_cv_nss_crypt +@@ -759,6 +760,7 @@ enable_obsolete_rpc + enable_systemtap + enable_build_nscd + enable_nscd ++enable_pt_chown + with_cpu + ' + ac_precious_vars='build_alias +@@ -1419,6 +1421,7 @@ Optional Features: + --enable-systemtap enable systemtap static probe points [default=no] + --disable-build-nscd disable building and installing the nscd daemon + --disable-nscd library functions will not contact the nscd daemon ++ --enable-pt_chown Enable building and installing pt_chown + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -3934,6 +3937,19 @@ else + fi + + ++# Check whether --enable-pt_chown was given. ++if test "${enable_pt_chown+set}" = set; then : ++ enableval=$enable_pt_chown; build_pt_chown=$enableval ++else ++ build_pt_chown=no ++fi ++ ++ ++if test $build_pt_chown = yes; then ++ $as_echo "#define HAVE_PT_CHOWN 1" >>confdefs.h ++ ++fi ++ + # The way shlib-versions is used to generate soversions.mk uses a + # fairly simplistic model for name recognition that can't distinguish + # i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a $host_os +diff -Nru glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in +--- glibc-2.17-c758a686/configure.in 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/configure.in 2013-07-24 00:20:07.658298658 -0400 +@@ -315,6 +315,16 @@ AC_ARG_ENABLE([nscd], + [use_nscd=$enableval], + [use_nscd=yes]) + ++AC_ARG_ENABLE([pt_chown], ++ [AS_HELP_STRING([--enable-pt_chown], ++ [Enable building and installing pt_chown])], ++ [build_pt_chown=$enableval], ++ [build_pt_chown=no]) ++AC_SUBST(build_pt_chown) ++if test $build_pt_chown = yes; then ++ AC_DEFINE(HAVE_PT_CHOWN) ++fi ++ + # The way shlib-versions is used to generate soversions.mk uses a + # fairly simplistic model for name recognition that can't distinguish + # i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a $host_os +diff -Nru glibc-2.17-c758a686/INSTALL glibc-2.17-c758a686/INSTALL +--- glibc-2.17-c758a686/INSTALL 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/INSTALL 2013-07-24 00:20:07.650300624 -0400 +@@ -128,6 +128,18 @@ will be used, and CFLAGS sets optimizati + this can be prevented though there generally is no reason since it + creates compatibility problems. + ++`--enable-pt_chown' ++ The file `pt_chown' is a helper binary for `grantpt' (*note ++ Pseudo-Terminals: Allocation.) that is installed setuid root to ++ fix up pseudo-terminal ownership. It is not built by default ++ because systems using the Linux kernel are commonly built with the ++ `devpts' filesystem enabled and mounted at `/dev/pts', which ++ manages pseudo-terminal ownership automatically. By using ++ `--enable-pt_chown', you may build `pt_chown' and install it ++ setuid and owned by `root'. The use of `pt_chown' introduces ++ additional security risks to the system and you should enable it ++ only if you understand and accept those risks. ++ + `--build=BUILD-SYSTEM' + `--host=HOST-SYSTEM' + These options are for cross-compiling. If you specify both +diff -Nru glibc-2.17-c758a686/login/Makefile glibc-2.17-c758a686/login/Makefile +--- glibc-2.17-c758a686/login/Makefile 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/login/Makefile 2013-07-24 00:20:07.660298670 -0400 +@@ -29,9 +29,15 @@ routines := getutent getutent_r getutid + + CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"' + +-others = utmpdump pt_chown ++others = utmpdump ++ ++include ../Makeconfig ++ ++ifeq (yes,$(build-pt-chown)) ++others += pt_chown + others-pie = pt_chown + install-others-programs = $(inst_libexecdir)/pt_chown ++endif + + subdir-dirs = programs + vpath %.c programs +diff -Nru glibc-2.17-c758a686/manual/install.texi glibc-2.17-c758a686/manual/install.texi +--- glibc-2.17-c758a686/manual/install.texi 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/manual/install.texi 2013-07-24 00:20:07.662298261 -0400 +@@ -155,6 +155,20 @@ if the used tools support it. By using + prevented though there generally is no reason since it creates + compatibility problems. + ++@pindex pt_chown ++@findex grantpt ++@item --enable-pt_chown ++The file @file{pt_chown} is a helper binary for @code{grantpt} ++(@pxref{Allocation, Pseudo-Terminals}) that is installed setuid root to ++fix up pseudo-terminal ownership. It is not built by default because ++systems using the Linux kernel are commonly built with the @code{devpts} ++filesystem enabled and mounted at @file{/dev/pts}, which manages ++pseudo-terminal ownership automatically. By using ++@samp{--enable-pt_chown}, you may build @file{pt_chown} and install it ++setuid and owned by @code{root}. The use of @file{pt_chown} introduces ++additional security risks to the system and you should enable it only if ++you understand and accept those risks. ++ + @item --build=@var{build-system} + @itemx --host=@var{host-system} + These options are for cross-compiling. If you specify both options and +diff -Nru glibc-2.17-c758a686/sysdeps/unix/grantpt.c glibc-2.17-c758a686/sysdeps/unix/grantpt.c +--- glibc-2.17-c758a686/sysdeps/unix/grantpt.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/grantpt.c 2013-07-24 00:20:07.663299235 -0400 +@@ -173,9 +173,10 @@ grantpt (int fd) + retval = 0; + goto cleanup; + +- /* We have to use the helper program. */ ++ /* We have to use the helper program if it is available. */ + helper:; + ++#ifdef HAVE_PT_CHOWN + pid_t pid = __fork (); + if (pid == -1) + goto cleanup; +@@ -190,9 +191,9 @@ grantpt (int fd) + if (__dup2 (fd, PTY_FILENO) < 0) + _exit (FAIL_EBADF); + +-#ifdef CLOSE_ALL_FDS ++# ifdef CLOSE_ALL_FDS + CLOSE_ALL_FDS (); +-#endif ++# endif + + execle (_PATH_PT_CHOWN, basename (_PATH_PT_CHOWN), NULL, NULL); + _exit (FAIL_EXEC); +@@ -231,6 +232,7 @@ grantpt (int fd) + assert(! "getpt: internal error: invalid exit code from pt_chown"); + } + } ++#endif + + cleanup: + if (buf != _buf) +diff -Nru glibc-2.17-c758a686/sysdeps/unix/sysv/linux/grantpt.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/grantpt.c +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/grantpt.c 2012-12-24 22:02:13.000000000 -0500 ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/grantpt.c 2013-07-24 00:20:07.664298465 -0400 +@@ -11,7 +11,7 @@ + + #include "pty-private.h" + +- ++#if HAVE_PT_CHOWN + /* Close all file descriptors except the one specified. */ + static void + close_all_fds (void) +@@ -38,6 +38,7 @@ close_all_fds (void) + __dup2 (STDOUT_FILENO, STDERR_FILENO); + } + } +-#define CLOSE_ALL_FDS() close_all_fds() ++# define CLOSE_ALL_FDS() close_all_fds() ++#endif + + #include diff --git a/SOURCES/glibc-rh988869.patch b/SOURCES/glibc-rh988869.patch new file mode 100644 index 00000000..75b8ce6a --- /dev/null +++ b/SOURCES/glibc-rh988869.patch @@ -0,0 +1,22 @@ +commit 705a79f82560ff6472cebed86aa5db04cdea3bce +Author: Florian Weimer +Date: Wed Nov 30 14:59:27 2016 +0100 + + libio: Limit buffer size to 8192 bytes [BZ #4099] + + This avoids overly large buffers with network file systems which report + very large block sizes. + +Index: b/libio/filedoalloc.c +=================================================================== +--- a/libio/filedoalloc.c ++++ b/libio/filedoalloc.c +@@ -121,7 +121,7 @@ _IO_file_doallocate (fp) + fp->_flags |= _IO_LINE_BUF; + } + #if _IO_HAVE_ST_BLKSIZE +- if (st.st_blksize > 0) ++ if (st.st_blksize > 0 && st.st_blksize < _IO_BUFSIZ) + size = st.st_blksize; + #endif + } diff --git a/SOURCES/glibc-rh989861.patch b/SOURCES/glibc-rh989861.patch new file mode 100644 index 00000000..7b05360d --- /dev/null +++ b/SOURCES/glibc-rh989861.patch @@ -0,0 +1,37 @@ +commit 27572ef96a66b61f5a6d81196c05983ab3dc9994 +Author: Siddhesh Poyarekar +Date: Sun Jun 30 20:45:19 2013 +0530 + + Check for integer overflow + +diff --git glibc-2.17-c758a686/string/strcoll_l.c glibc-2.17-c758a686/string/strcoll_l.c +index 1be6874..cbe5962 100644 +--- glibc-2.17-c758a686/string/strcoll_l.c ++++ glibc-2.17-c758a686/string/strcoll_l.c +@@ -524,6 +524,14 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + memset (&seq1, 0, sizeof (seq1)); + seq2 = seq1; + ++ size_t size_max = SIZE_MAX / (sizeof (int32_t) + 1); ++ ++ /* If the strings are long enough to cause overflow in the size request, then ++ skip the allocation and proceed with the non-cached routines. */ ++ if (MIN (s1len, s2len) > size_max ++ || MAX (s1len, s2len) > size_max - MIN (s1len, s2len)) ++ goto begin_collate; ++ + if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1))) + { + seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1)); +@@ -546,8 +554,10 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + seq2.rulearr = (unsigned char *) alloca (s2len); + } + +- int rule = 0; ++ int rule; + ++ begin_collate: ++ rule = 0; + /* Cache values in the first pass and if needed, use them in subsequent + passes. */ + for (int pass = 0; pass < nrules; ++pass) diff --git a/SOURCES/glibc-rh989862-2.patch b/SOURCES/glibc-rh989862-2.patch new file mode 100644 index 00000000..4b1f1af3 --- /dev/null +++ b/SOURCES/glibc-rh989862-2.patch @@ -0,0 +1,325 @@ +commit 9795a1801eb1a4f3ae6346e32666d3d05f006115 +Author: Siddhesh Poyarekar +Date: Sun Jun 30 20:45:05 2013 +0530 + + Fall back to non-cached sequence traversal and comparison + + strcoll currently falls back to alloca if malloc fails, resulting in a + possible stack overflow. This patch implements sequence traversal and + comparison without caching indeces and rules. + +diff --git glibc-2.17-c758a686/string/strcoll_l.c glibc-2.17-c758a686/string/strcoll_l.c +index 1bb9e23..1be6874 100644 +--- glibc-2.17-c758a686/string/strcoll_l.c ++++ glibc-2.17-c758a686/string/strcoll_l.c +@@ -55,6 +55,12 @@ typedef struct + const USTRING_TYPE *us; /* The string. */ + int32_t *idxarr; /* Array to cache weight indeces. */ + unsigned char *rulearr; /* Array to cache rules. */ ++ unsigned char rule; /* Saved rule for the first sequence. */ ++ int32_t idx; /* Index to weight of the current sequence. */ ++ int32_t save_idx; /* Save looked up index of a forward ++ sequence after the last backward ++ sequence. */ ++ const USTRING_TYPE *back_us; /* Beginning of the backward sequence. */ + } coll_seq; + + /* Get next sequence. The weight indeces are cached, so we don't need to +@@ -227,7 +233,191 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets, + seq->us = us; + } + +-/* Compare two sequences. */ ++/* Get next sequence. Traverse the string as required. This function does not ++ set or use any index or rule cache. */ ++static void ++get_next_seq_nocache (coll_seq *seq, int nrules, const unsigned char *rulesets, ++ const USTRING_TYPE *weights, const int32_t *table, ++ const USTRING_TYPE *extra, const int32_t *indirect, ++ int pass) ++{ ++#include WEIGHT_H ++ int val = seq->val = 0; ++ int len = seq->len; ++ size_t backw_stop = seq->backw_stop; ++ size_t backw = seq->backw; ++ size_t idxcnt = seq->idxcnt; ++ size_t idxmax = seq->idxmax; ++ int32_t idx = seq->idx; ++ const USTRING_TYPE *us = seq->us; ++ ++ while (len == 0) ++ { ++ ++val; ++ if (backw_stop != ~0ul) ++ { ++ /* The is something pushed. */ ++ if (backw == backw_stop) ++ { ++ /* The last pushed character was handled. Continue ++ with forward characters. */ ++ if (idxcnt < idxmax) ++ { ++ idx = seq->save_idx; ++ backw_stop = ~0ul; ++ } ++ else ++ { ++ /* Nothing anymore. The backward sequence ended with ++ the last sequence in the string. Note that len is ++ still zero. */ ++ idx = 0; ++ break; ++ } ++ } ++ else ++ { ++ /* XXX Traverse BACKW sequences from the beginning of ++ BACKW_STOP to get the next sequence. Is ther a quicker way ++ to do this? */ ++ int i = backw_stop; ++ us = seq->back_us; ++ while (i < backw) ++ { ++ int32_t tmp = findidx (&us, -1); ++ idx = tmp & 0xffffff; ++ i++; ++ } ++ --backw; ++ us = seq->us; ++ } ++ } ++ else ++ { ++ backw_stop = idxmax; ++ int32_t prev_idx = idx; ++ ++ while (*us != L('\0')) ++ { ++ int32_t tmp = findidx (&us, -1); ++ unsigned char rule = tmp >> 24; ++ prev_idx = idx; ++ idx = tmp & 0xffffff; ++ idxcnt = idxmax++; ++ ++ /* Save the rule for the first sequence. */ ++ if (__glibc_unlikely (idxcnt == 0)) ++ seq->rule = rule; ++ ++ if ((rulesets[rule * nrules + pass] ++ & sort_backward) == 0) ++ /* No more backward characters to push. */ ++ break; ++ ++idxcnt; ++ } ++ ++ if (backw_stop >= idxcnt) ++ { ++ /* No sequence at all or just one. */ ++ if (idxcnt == idxmax || backw_stop > idxcnt) ++ /* Note that len is still zero. */ ++ break; ++ ++ backw_stop = ~0ul; ++ } ++ else ++ { ++ /* We pushed backward sequences. If the stream ended with the ++ backward sequence, then we process the last sequence we ++ found. Otherwise we process the sequence before the last ++ one since the last one was a forward sequence. */ ++ seq->back_us = seq->us; ++ seq->us = us; ++ backw = idxcnt; ++ if (idxmax > idxcnt) ++ { ++ backw--; ++ seq->save_idx = idx; ++ idx = prev_idx; ++ } ++ if (backw > backw_stop) ++ backw--; ++ } ++ } ++ ++ len = weights[idx++]; ++ /* Skip over indeces of previous levels. */ ++ for (int i = 0; i < pass; i++) ++ { ++ idx += len; ++ len = weights[idx]; ++ idx++; ++ } ++ } ++ ++ /* Update the structure. */ ++ seq->val = val; ++ seq->len = len; ++ seq->backw_stop = backw_stop; ++ seq->backw = backw; ++ seq->idxcnt = idxcnt; ++ seq->idxmax = idxmax; ++ seq->us = us; ++ seq->idx = idx; ++} ++ ++/* Compare two sequences. This version does not use the index and rules ++ cache. */ ++static int ++do_compare_nocache (coll_seq *seq1, coll_seq *seq2, int position, ++ const USTRING_TYPE *weights) ++{ ++ int seq1len = seq1->len; ++ int seq2len = seq2->len; ++ int val1 = seq1->val; ++ int val2 = seq2->val; ++ int idx1 = seq1->idx; ++ int idx2 = seq2->idx; ++ int result = 0; ++ ++ /* Test for position if necessary. */ ++ if (position && val1 != val2) ++ { ++ result = val1 - val2; ++ goto out; ++ } ++ ++ /* Compare the two sequences. */ ++ do ++ { ++ if (weights[idx1] != weights[idx2]) ++ { ++ /* The sequences differ. */ ++ result = weights[idx1] - weights[idx2]; ++ goto out; ++ } ++ ++ /* Increment the offsets. */ ++ ++idx1; ++ ++idx2; ++ ++ --seq1len; ++ --seq2len; ++ } ++ while (seq1len > 0 && seq2len > 0); ++ ++ if (position && seq1len != seq2len) ++ result = seq1len - seq2len; ++ ++out: ++ seq1->len = seq1len; ++ seq2->len = seq2len; ++ seq1->idx = idx1; ++ seq2->idx = idx2; ++ return result; ++} ++ ++/* Compare two sequences using the index cache. */ + static int + do_compare (coll_seq *seq1, coll_seq *seq2, int position, + const USTRING_TYPE *weights) +@@ -334,57 +524,62 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + memset (&seq1, 0, sizeof (seq1)); + seq2 = seq1; + +- /* We need the elements of the strings as unsigned values since they +- are used as indeces. */ +- seq1.us = (const USTRING_TYPE *) s1; +- seq2.us = (const USTRING_TYPE *) s2; +- + if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1))) + { + seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1)); +- seq2.idxarr = &seq1.idxarr[s1len]; +- seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len]; +- seq2.rulearr = &seq1.rulearr[s1len]; +- +- if (seq1.idxarr == NULL) +- /* No memory. Well, go with the stack then. +- +- XXX Once this implementation is stable we will handle this +- differently. Instead of precomputing the indeces we will +- do this in time. This means, though, that this happens for +- every pass again. */ +- goto try_stack; +- use_malloc = true; ++ ++ /* If we failed to allocate memory, we leave everything as NULL so that ++ we use the nocache version of traversal and comparison functions. */ ++ if (seq1.idxarr != NULL) ++ { ++ seq2.idxarr = &seq1.idxarr[s1len]; ++ seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len]; ++ seq2.rulearr = &seq1.rulearr[s1len]; ++ use_malloc = true; ++ } + } + else + { +- try_stack: + seq1.idxarr = (int32_t *) alloca (s1len * sizeof (int32_t)); + seq2.idxarr = (int32_t *) alloca (s2len * sizeof (int32_t)); + seq1.rulearr = (unsigned char *) alloca (s1len); + seq2.rulearr = (unsigned char *) alloca (s2len); + } + +- seq1.rulearr[0] = 0; ++ int rule = 0; + + /* Cache values in the first pass and if needed, use them in subsequent + passes. */ + for (int pass = 0; pass < nrules; ++pass) + { + seq1.idxcnt = 0; ++ seq1.idx = 0; ++ seq2.idx = 0; + seq1.backw_stop = ~0ul; + seq1.backw = ~0ul; + seq2.idxcnt = 0; + seq2.backw_stop = ~0ul; + seq2.backw = ~0ul; + ++ /* We need the elements of the strings as unsigned values since they ++ are used as indeces. */ ++ seq1.us = (const USTRING_TYPE *) s1; ++ seq2.us = (const USTRING_TYPE *) s2; ++ + /* We assume that if a rule has defined `position' in one section + this is true for all of them. */ +- int position = rulesets[seq1.rulearr[0] * nrules + pass] & sort_position; ++ int position = rulesets[rule * nrules + pass] & sort_position; + + while (1) + { +- if (pass == 0) ++ if (__glibc_unlikely (seq1.idxarr == NULL)) ++ { ++ get_next_seq_nocache (&seq1, nrules, rulesets, weights, table, ++ extra, indirect, pass); ++ get_next_seq_nocache (&seq2, nrules, rulesets, weights, table, ++ extra, indirect, pass); ++ } ++ else if (pass == 0) + { + get_next_seq (&seq1, nrules, rulesets, weights, table, extra, + indirect); +@@ -411,10 +606,18 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + goto free_and_return; + } + +- result = do_compare (&seq1, &seq2, position, weights); ++ if (__glibc_unlikely (seq1.idxarr == NULL)) ++ result = do_compare_nocache (&seq1, &seq2, position, weights); ++ else ++ result = do_compare (&seq1, &seq2, position, weights); + if (result != 0) + goto free_and_return; + } ++ ++ if (__glibc_likely (seq1.rulearr != NULL)) ++ rule = seq1.rulearr[0]; ++ else ++ rule = seq1.rule; + } + + /* Free the memory if needed. */ diff --git a/SOURCES/glibc-rh989862-3.patch b/SOURCES/glibc-rh989862-3.patch new file mode 100644 index 00000000..75b5e491 --- /dev/null +++ b/SOURCES/glibc-rh989862-3.patch @@ -0,0 +1,21 @@ +commit 91998e449e0ce758db55aecf2abc3ee510fcbc8f +Author: Siddhesh Poyarekar +Date: Fri Dec 28 11:53:01 2012 +0530 + + Add __glibc_likely as an alias for __builtin_expect when available + +diff --git glibc-2.17-c758a686/misc/sys/cdefs.h glibc-2.17-c758a686/misc/sys/cdefs.h +index fb6c959..1eee54e 100644 +--- glibc-2.17-c758a686/misc/sys/cdefs.h ++++ glibc-2.17-c758a686/misc/sys/cdefs.h +@@ -378,8 +378,10 @@ + + #if __GNUC__ >= 3 + # define __glibc_unlikely(cond) __builtin_expect((cond), 0) ++# define __glibc_likely(cond) __builtin_expect((cond), 1) + #else + # define __glibc_unlikely(cond) (cond) ++# define __glibc_likely(cond) (cond) + #endif + + #include diff --git a/SOURCES/glibc-rh989862.patch b/SOURCES/glibc-rh989862.patch new file mode 100644 index 00000000..0d2003fc --- /dev/null +++ b/SOURCES/glibc-rh989862.patch @@ -0,0 +1,790 @@ +commit e91a48408662e591e1320b2cab6d3fcda7793b18 +Author: Siddhesh Poyarekar +Date: Fri Jun 28 16:24:16 2013 +0530 + + Simplify strcoll implementation + +diff --git glibc-2.17-c758a686/string/strcoll_l.c glibc-2.17-c758a686/string/strcoll_l.c +index ecda08f..1bb9e23 100644 +--- glibc-2.17-c758a686/string/strcoll_l.c ++++ glibc-2.17-c758a686/string/strcoll_l.c +@@ -41,11 +41,244 @@ + + #include "../locale/localeinfo.h" + ++/* Track status while looking for sequences in a string. */ ++typedef struct ++{ ++ int len; /* Length of the current sequence. */ ++ int val; /* Position of the sequence relative to the ++ previous non-ignored sequence. */ ++ size_t idxnow; /* Current index in sequences. */ ++ size_t idxmax; /* Maximum index in sequences. */ ++ size_t idxcnt; /* Current count of indeces. */ ++ size_t backw; /* Current Backward sequence index. */ ++ size_t backw_stop; /* Index where the backward sequences stop. */ ++ const USTRING_TYPE *us; /* The string. */ ++ int32_t *idxarr; /* Array to cache weight indeces. */ ++ unsigned char *rulearr; /* Array to cache rules. */ ++} coll_seq; ++ ++/* Get next sequence. The weight indeces are cached, so we don't need to ++ traverse the string. */ ++static void ++get_next_seq_cached (coll_seq *seq, int nrules, int pass, ++ const unsigned char *rulesets, ++ const USTRING_TYPE *weights) ++{ ++ int val = seq->val = 0; ++ int len = seq->len; ++ size_t backw_stop = seq->backw_stop; ++ size_t backw = seq->backw; ++ size_t idxcnt = seq->idxcnt; ++ size_t idxmax = seq->idxmax; ++ size_t idxnow = seq->idxnow; ++ unsigned char *rulearr = seq->rulearr; ++ int32_t *idxarr = seq->idxarr; ++ ++ while (len == 0) ++ { ++ ++val; ++ if (backw_stop != ~0ul) ++ { ++ /* The is something pushed. */ ++ if (backw == backw_stop) ++ { ++ /* The last pushed character was handled. Continue ++ with forward characters. */ ++ if (idxcnt < idxmax) ++ { ++ idxnow = idxcnt; ++ backw_stop = ~0ul; ++ } ++ else ++ { ++ /* Nothing anymore. The backward sequence ++ ended with the last sequence in the string. */ ++ idxnow = ~0ul; ++ break; ++ } ++ } ++ else ++ idxnow = --backw; ++ } ++ else ++ { ++ backw_stop = idxcnt; ++ ++ while (idxcnt < idxmax) ++ { ++ if ((rulesets[rulearr[idxcnt] * nrules + pass] ++ & sort_backward) == 0) ++ /* No more backward characters to push. */ ++ break; ++ ++idxcnt; ++ } ++ ++ if (backw_stop == idxcnt) ++ { ++ /* No sequence at all or just one. */ ++ if (idxcnt == idxmax) ++ /* Note that seq1len is still zero. */ ++ break; ++ ++ backw_stop = ~0ul; ++ idxnow = idxcnt++; ++ } ++ else ++ /* We pushed backward sequences. */ ++ idxnow = backw = idxcnt - 1; ++ } ++ len = weights[idxarr[idxnow]++]; ++ } ++ ++ /* Update the structure. */ ++ seq->val = val; ++ seq->len = len; ++ seq->backw_stop = backw_stop; ++ seq->backw = backw; ++ seq->idxcnt = idxcnt; ++ seq->idxnow = idxnow; ++} ++ ++/* Get next sequence. Traverse the string as required. */ ++static void ++get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets, ++ const USTRING_TYPE *weights, const int32_t *table, ++ const USTRING_TYPE *extra, const int32_t *indirect) ++{ ++#include WEIGHT_H ++ int val = seq->val = 0; ++ int len = seq->len; ++ size_t backw_stop = seq->backw_stop; ++ size_t backw = seq->backw; ++ size_t idxcnt = seq->idxcnt; ++ size_t idxmax = seq->idxmax; ++ size_t idxnow = seq->idxnow; ++ unsigned char *rulearr = seq->rulearr; ++ int32_t *idxarr = seq->idxarr; ++ const USTRING_TYPE *us = seq->us; ++ ++ while (len == 0) ++ { ++ ++val; ++ if (backw_stop != ~0ul) ++ { ++ /* The is something pushed. */ ++ if (backw == backw_stop) ++ { ++ /* The last pushed character was handled. Continue ++ with forward characters. */ ++ if (idxcnt < idxmax) ++ { ++ idxnow = idxcnt; ++ backw_stop = ~0ul; ++ } ++ else ++ /* Nothing anymore. The backward sequence ended with ++ the last sequence in the string. Note that seq2len ++ is still zero. */ ++ break; ++ } ++ else ++ idxnow = --backw; ++ } ++ else ++ { ++ backw_stop = idxmax; ++ ++ while (*us != L('\0')) ++ { ++ int32_t tmp = findidx (&us, -1); ++ rulearr[idxmax] = tmp >> 24; ++ idxarr[idxmax] = tmp & 0xffffff; ++ idxcnt = idxmax++; ++ ++ if ((rulesets[rulearr[idxcnt] * nrules] ++ & sort_backward) == 0) ++ /* No more backward characters to push. */ ++ break; ++ ++idxcnt; ++ } ++ ++ if (backw_stop >= idxcnt) ++ { ++ /* No sequence at all or just one. */ ++ if (idxcnt == idxmax || backw_stop > idxcnt) ++ /* Note that seq1len is still zero. */ ++ break; ++ ++ backw_stop = ~0ul; ++ idxnow = idxcnt; ++ } ++ else ++ /* We pushed backward sequences. */ ++ idxnow = backw = idxcnt - 1; ++ } ++ len = weights[idxarr[idxnow]++]; ++ } ++ ++ /* Update the structure. */ ++ seq->val = val; ++ seq->len = len; ++ seq->backw_stop = backw_stop; ++ seq->backw = backw; ++ seq->idxcnt = idxcnt; ++ seq->idxmax = idxmax; ++ seq->idxnow = idxnow; ++ seq->us = us; ++} ++ ++/* Compare two sequences. */ ++static int ++do_compare (coll_seq *seq1, coll_seq *seq2, int position, ++ const USTRING_TYPE *weights) ++{ ++ int seq1len = seq1->len; ++ int seq2len = seq2->len; ++ int val1 = seq1->val; ++ int val2 = seq2->val; ++ int32_t *idx1arr = seq1->idxarr; ++ int32_t *idx2arr = seq2->idxarr; ++ int idx1now = seq1->idxnow; ++ int idx2now = seq2->idxnow; ++ int result = 0; ++ ++ /* Test for position if necessary. */ ++ if (position && val1 != val2) ++ { ++ result = val1 - val2; ++ goto out; ++ } ++ ++ /* Compare the two sequences. */ ++ do ++ { ++ if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]]) ++ { ++ /* The sequences differ. */ ++ result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]]; ++ goto out; ++ } ++ ++ /* Increment the offsets. */ ++ ++idx1arr[idx1now]; ++ ++idx2arr[idx2now]; ++ ++ --seq1len; ++ --seq2len; ++ } ++ while (seq1len > 0 && seq2len > 0); ++ ++ if (position && seq1len != seq2len) ++ result = seq1len - seq2len; ++ ++out: ++ seq1->len = seq1len; ++ seq2->len = seq2len; ++ return result; ++} ++ + int +-STRCOLL (s1, s2, l) +- const STRING_TYPE *s1; +- const STRING_TYPE *s2; +- __locale_t l; ++STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l) + { + struct __locale_data *current = l->__locales[LC_COLLATE]; + uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word; +@@ -56,34 +289,6 @@ STRCOLL (s1, s2, l) + const USTRING_TYPE *weights; + const USTRING_TYPE *extra; + const int32_t *indirect; +- uint_fast32_t pass; +- int result = 0; +- const USTRING_TYPE *us1; +- const USTRING_TYPE *us2; +- size_t s1len; +- size_t s2len; +- int32_t *idx1arr; +- int32_t *idx2arr; +- unsigned char *rule1arr; +- unsigned char *rule2arr; +- size_t idx1max; +- size_t idx2max; +- size_t idx1cnt; +- size_t idx2cnt; +- size_t idx1now; +- size_t idx2now; +- size_t backw1_stop; +- size_t backw2_stop; +- size_t backw1; +- size_t backw2; +- int val1; +- int val2; +- int position; +- int seq1len; +- int seq2len; +- int use_malloc; +- +-#include WEIGHT_H + + if (nrules == 0) + return STRCMP (s1, s2); +@@ -98,7 +303,6 @@ STRCOLL (s1, s2, l) + current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_EXTRA,SUFFIX))].string; + indirect = (const int32_t *) + current->values[_NL_ITEM_INDEX (CONCAT(_NL_COLLATE_INDIRECT,SUFFIX))].string; +- use_malloc = 0; + + assert (((uintptr_t) table) % __alignof__ (table[0]) == 0); + assert (((uintptr_t) weights) % __alignof__ (weights[0]) == 0); +@@ -106,18 +310,13 @@ STRCOLL (s1, s2, l) + assert (((uintptr_t) indirect) % __alignof__ (indirect[0]) == 0); + + /* We need this a few times. */ +- s1len = STRLEN (s1); +- s2len = STRLEN (s2); ++ size_t s1len = STRLEN (s1); ++ size_t s2len = STRLEN (s2); + + /* Catch empty strings. */ +- if (__builtin_expect (s1len == 0, 0) || __builtin_expect (s2len == 0, 0)) ++ if (__glibc_unlikely (s1len == 0) || __glibc_unlikely (s2len == 0)) + return (s1len != 0) - (s2len != 0); + +- /* We need the elements of the strings as unsigned values since they +- are used as indeces. */ +- us1 = (const USTRING_TYPE *) s1; +- us2 = (const USTRING_TYPE *) s2; +- + /* Perform the first pass over the string and while doing this find + and store the weights for each character. Since we want this to + be as fast as possible we are using `alloca' to store the temporary +@@ -127,14 +326,27 @@ STRCOLL (s1, s2, l) + + Please note that the localedef programs makes sure that `position' + is not used at the first level. */ ++ ++ coll_seq seq1, seq2; ++ bool use_malloc = false; ++ int result = 0; ++ ++ memset (&seq1, 0, sizeof (seq1)); ++ seq2 = seq1; ++ ++ /* We need the elements of the strings as unsigned values since they ++ are used as indeces. */ ++ seq1.us = (const USTRING_TYPE *) s1; ++ seq2.us = (const USTRING_TYPE *) s2; ++ + if (! __libc_use_alloca ((s1len + s2len) * (sizeof (int32_t) + 1))) + { +- idx1arr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1)); +- idx2arr = &idx1arr[s1len]; +- rule1arr = (unsigned char *) &idx2arr[s2len]; +- rule2arr = &rule1arr[s1len]; ++ seq1.idxarr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1)); ++ seq2.idxarr = &seq1.idxarr[s1len]; ++ seq1.rulearr = (unsigned char *) &seq2.idxarr[s2len]; ++ seq2.rulearr = &seq1.rulearr[s1len]; + +- if (idx1arr == NULL) ++ if (seq1.idxarr == NULL) + /* No memory. Well, go with the stack then. + + XXX Once this implementation is stable we will handle this +@@ -142,396 +354,73 @@ STRCOLL (s1, s2, l) + do this in time. This means, though, that this happens for + every pass again. */ + goto try_stack; +- use_malloc = 1; ++ use_malloc = true; + } + else + { + try_stack: +- idx1arr = (int32_t *) alloca (s1len * sizeof (int32_t)); +- idx2arr = (int32_t *) alloca (s2len * sizeof (int32_t)); +- rule1arr = (unsigned char *) alloca (s1len); +- rule2arr = (unsigned char *) alloca (s2len); ++ seq1.idxarr = (int32_t *) alloca (s1len * sizeof (int32_t)); ++ seq2.idxarr = (int32_t *) alloca (s2len * sizeof (int32_t)); ++ seq1.rulearr = (unsigned char *) alloca (s1len); ++ seq2.rulearr = (unsigned char *) alloca (s2len); + } + +- idx1cnt = 0; +- idx2cnt = 0; +- idx1max = 0; +- idx2max = 0; +- idx1now = 0; +- idx2now = 0; +- backw1_stop = ~0ul; +- backw2_stop = ~0ul; +- backw1 = ~0ul; +- backw2 = ~0ul; +- seq1len = 0; +- seq2len = 0; +- position = rulesets[0] & sort_position; +- while (1) +- { +- val1 = 0; +- val2 = 0; +- +- /* Get the next non-IGNOREd element for string `s1'. */ +- if (seq1len == 0) +- do +- { +- ++val1; +- +- if (backw1_stop != ~0ul) +- { +- /* The is something pushed. */ +- if (backw1 == backw1_stop) +- { +- /* The last pushed character was handled. Continue +- with forward characters. */ +- if (idx1cnt < idx1max) +- { +- idx1now = idx1cnt; +- backw1_stop = ~0ul; +- } +- else +- /* Nothing anymore. The backward sequence ended with +- the last sequence in the string. Note that seq1len +- is still zero. */ +- break; +- } +- else +- idx1now = --backw1; +- } +- else +- { +- backw1_stop = idx1max; +- +- while (*us1 != L('\0')) +- { +- int32_t tmp = findidx (&us1, -1); +- rule1arr[idx1max] = tmp >> 24; +- idx1arr[idx1max] = tmp & 0xffffff; +- idx1cnt = idx1max++; +- +- if ((rulesets[rule1arr[idx1cnt] * nrules] +- & sort_backward) == 0) +- /* No more backward characters to push. */ +- break; +- ++idx1cnt; +- } +- +- if (backw1_stop >= idx1cnt) +- { +- /* No sequence at all or just one. */ +- if (idx1cnt == idx1max || backw1_stop > idx1cnt) +- /* Note that seq1len is still zero. */ +- break; +- +- backw1_stop = ~0ul; +- idx1now = idx1cnt; +- } +- else +- /* We pushed backward sequences. */ +- idx1now = backw1 = idx1cnt - 1; +- } +- } +- while ((seq1len = weights[idx1arr[idx1now]++]) == 0); +- +- /* And the same for string `s2'. */ +- if (seq2len == 0) +- do +- { +- ++val2; +- +- if (backw2_stop != ~0ul) +- { +- /* The is something pushed. */ +- if (backw2 == backw2_stop) +- { +- /* The last pushed character was handled. Continue +- with forward characters. */ +- if (idx2cnt < idx2max) +- { +- idx2now = idx2cnt; +- backw2_stop = ~0ul; +- } +- else +- /* Nothing anymore. The backward sequence ended with +- the last sequence in the string. Note that seq2len +- is still zero. */ +- break; +- } +- else +- idx2now = --backw2; +- } +- else +- { +- backw2_stop = idx2max; +- +- while (*us2 != L('\0')) +- { +- int32_t tmp = findidx (&us2, -1); +- rule2arr[idx2max] = tmp >> 24; +- idx2arr[idx2max] = tmp & 0xffffff; +- idx2cnt = idx2max++; +- +- if ((rulesets[rule2arr[idx2cnt] * nrules] +- & sort_backward) == 0) +- /* No more backward characters to push. */ +- break; +- ++idx2cnt; +- } +- +- if (backw2_stop >= idx2cnt) +- { +- /* No sequence at all or just one. */ +- if (idx2cnt == idx2max || backw2_stop > idx2cnt) +- /* Note that seq1len is still zero. */ +- break; +- +- backw2_stop = ~0ul; +- idx2now = idx2cnt; +- } +- else +- /* We pushed backward sequences. */ +- idx2now = backw2 = idx2cnt - 1; +- } +- } +- while ((seq2len = weights[idx2arr[idx2now]++]) == 0); +- +- /* See whether any or both strings are empty. */ +- if (seq1len == 0 || seq2len == 0) +- { +- if (seq1len == seq2len) +- /* Both ended. So far so good, both strings are equal at the +- first level. */ +- break; +- +- /* This means one string is shorter than the other. Find out +- which one and return an appropriate value. */ +- result = seq1len == 0 ? -1 : 1; +- goto free_and_return; +- } ++ seq1.rulearr[0] = 0; + +- /* Test for position if necessary. */ +- if (position && val1 != val2) +- { +- result = val1 - val2; +- goto free_and_return; +- } +- +- /* Compare the two sequences. */ +- do +- { +- if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]]) +- { +- /* The sequences differ. */ +- result = weights[idx1arr[idx1now]] - weights[idx2arr[idx2now]]; +- goto free_and_return; +- } +- +- /* Increment the offsets. */ +- ++idx1arr[idx1now]; +- ++idx2arr[idx2now]; +- +- --seq1len; +- --seq2len; +- } +- while (seq1len > 0 && seq2len > 0); +- +- if (position && seq1len != seq2len) +- { +- result = seq1len - seq2len; +- goto free_and_return; +- } +- } +- +- /* Now the remaining passes over the weights. We now use the +- indeces we found before. */ +- for (pass = 1; pass < nrules; ++pass) ++ /* Cache values in the first pass and if needed, use them in subsequent ++ passes. */ ++ for (int pass = 0; pass < nrules; ++pass) + { ++ seq1.idxcnt = 0; ++ seq1.backw_stop = ~0ul; ++ seq1.backw = ~0ul; ++ seq2.idxcnt = 0; ++ seq2.backw_stop = ~0ul; ++ seq2.backw = ~0ul; ++ + /* We assume that if a rule has defined `position' in one section + this is true for all of them. */ +- idx1cnt = 0; +- idx2cnt = 0; +- backw1_stop = ~0ul; +- backw2_stop = ~0ul; +- backw1 = ~0ul; +- backw2 = ~0ul; +- position = rulesets[rule1arr[0] * nrules + pass] & sort_position; ++ int position = rulesets[seq1.rulearr[0] * nrules + pass] & sort_position; + + while (1) + { +- val1 = 0; +- val2 = 0; +- +- /* Get the next non-IGNOREd element for string `s1'. */ +- if (seq1len == 0) +- do +- { +- ++val1; +- +- if (backw1_stop != ~0ul) +- { +- /* The is something pushed. */ +- if (backw1 == backw1_stop) +- { +- /* The last pushed character was handled. Continue +- with forward characters. */ +- if (idx1cnt < idx1max) +- { +- idx1now = idx1cnt; +- backw1_stop = ~0ul; +- } +- else +- { +- /* Nothing anymore. The backward sequence +- ended with the last sequence in the string. */ +- idx1now = ~0ul; +- break; +- } +- } +- else +- idx1now = --backw1; +- } +- else +- { +- backw1_stop = idx1cnt; +- +- while (idx1cnt < idx1max) +- { +- if ((rulesets[rule1arr[idx1cnt] * nrules + pass] +- & sort_backward) == 0) +- /* No more backward characters to push. */ +- break; +- ++idx1cnt; +- } +- +- if (backw1_stop == idx1cnt) +- { +- /* No sequence at all or just one. */ +- if (idx1cnt == idx1max) +- /* Note that seq1len is still zero. */ +- break; +- +- backw1_stop = ~0ul; +- idx1now = idx1cnt++; +- } +- else +- /* We pushed backward sequences. */ +- idx1now = backw1 = idx1cnt - 1; +- } +- } +- while ((seq1len = weights[idx1arr[idx1now]++]) == 0); +- +- /* And the same for string `s2'. */ +- if (seq2len == 0) +- do +- { +- ++val2; +- +- if (backw2_stop != ~0ul) +- { +- /* The is something pushed. */ +- if (backw2 == backw2_stop) +- { +- /* The last pushed character was handled. Continue +- with forward characters. */ +- if (idx2cnt < idx2max) +- { +- idx2now = idx2cnt; +- backw2_stop = ~0ul; +- } +- else +- { +- /* Nothing anymore. The backward sequence +- ended with the last sequence in the string. */ +- idx2now = ~0ul; +- break; +- } +- } +- else +- idx2now = --backw2; +- } +- else +- { +- backw2_stop = idx2cnt; +- +- while (idx2cnt < idx2max) +- { +- if ((rulesets[rule2arr[idx2cnt] * nrules + pass] +- & sort_backward) == 0) +- /* No more backward characters to push. */ +- break; +- ++idx2cnt; +- } +- +- if (backw2_stop == idx2cnt) +- { +- /* No sequence at all or just one. */ +- if (idx2cnt == idx2max) +- /* Note that seq2len is still zero. */ +- break; +- +- backw2_stop = ~0ul; +- idx2now = idx2cnt++; +- } +- else +- /* We pushed backward sequences. */ +- idx2now = backw2 = idx2cnt - 1; +- } +- } +- while ((seq2len = weights[idx2arr[idx2now]++]) == 0); ++ if (pass == 0) ++ { ++ get_next_seq (&seq1, nrules, rulesets, weights, table, extra, ++ indirect); ++ get_next_seq (&seq2, nrules, rulesets, weights, table, extra, ++ indirect); ++ } ++ else ++ { ++ get_next_seq_cached (&seq1, nrules, pass, rulesets, weights); ++ get_next_seq_cached (&seq2, nrules, pass, rulesets, weights); ++ } + + /* See whether any or both strings are empty. */ +- if (seq1len == 0 || seq2len == 0) ++ if (seq1.len == 0 || seq2.len == 0) + { +- if (seq1len == seq2len) ++ if (seq1.len == seq2.len) + /* Both ended. So far so good, both strings are equal + at this level. */ + break; + + /* This means one string is shorter than the other. Find out + which one and return an appropriate value. */ +- result = seq1len == 0 ? -1 : 1; ++ result = seq1.len == 0 ? -1 : 1; + goto free_and_return; + } + +- /* Test for position if necessary. */ +- if (position && val1 != val2) +- { +- result = val1 - val2; +- goto free_and_return; +- } +- +- /* Compare the two sequences. */ +- do +- { +- if (weights[idx1arr[idx1now]] != weights[idx2arr[idx2now]]) +- { +- /* The sequences differ. */ +- result = (weights[idx1arr[idx1now]] +- - weights[idx2arr[idx2now]]); +- goto free_and_return; +- } +- +- /* Increment the offsets. */ +- ++idx1arr[idx1now]; +- ++idx2arr[idx2now]; +- +- --seq1len; +- --seq2len; +- } +- while (seq1len > 0 && seq2len > 0); +- +- if (position && seq1len != seq2len) +- { +- result = seq1len - seq2len; +- goto free_and_return; +- } ++ result = do_compare (&seq1, &seq2, position, weights); ++ if (result != 0) ++ goto free_and_return; + } + } + + /* Free the memory if needed. */ + free_and_return: + if (use_malloc) +- free (idx1arr); ++ free (seq1.idxarr); + + return result; + } diff --git a/SOURCES/glibc-rh990388-2.patch b/SOURCES/glibc-rh990388-2.patch new file mode 100644 index 00000000..851d4f8e --- /dev/null +++ b/SOURCES/glibc-rh990388-2.patch @@ -0,0 +1,279 @@ +diff -pruN glibc-2.17-c758a686/csu/libc-start.c glibc-2.17-c758a686/csu/libc-start.c +--- glibc-2.17-c758a686/csu/libc-start.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/csu/libc-start.c 2013-07-30 11:46:44.571901690 +0530 +@@ -32,7 +32,7 @@ extern int __libc_multiple_libcs; + #include + #ifndef SHARED + # include +-extern void __pthread_initialize_minimal (void); ++extern void __pthread_initialize_minimal (int, char **, char **); + # ifndef THREAD_SET_STACK_GUARD + /* Only exported for architectures that don't store the stack guard canary + in thread local area. */ +@@ -175,7 +175,7 @@ LIBC_START_MAIN (int (*main) (int, char + /* Initialize the thread library at least a bit since the libgcc + functions are using thread functions if these are available and + we need to setup errno. */ +- __pthread_initialize_minimal (); ++ __pthread_initialize_minimal (argc, argv, __environ); + + /* Set up the stack checker's canary. */ + uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); +diff -pruN glibc-2.17-c758a686/csu/libc-tls.c glibc-2.17-c758a686/csu/libc-tls.c +--- glibc-2.17-c758a686/csu/libc-tls.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/csu/libc-tls.c 2013-07-30 11:46:44.572901690 +0530 +@@ -243,7 +243,7 @@ _dl_tls_setup (void) + not used. */ + void + __attribute__ ((weak)) +-__pthread_initialize_minimal (void) ++__pthread_initialize_minimal (int argc, char **argv, char **envp) + { + __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN); + } +diff -pruN glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686/nptl/Makefile +--- glibc-2.17-c758a686/nptl/Makefile 2013-07-30 11:46:34.909902026 +0530 ++++ glibc-2.17-c758a686/nptl/Makefile 2013-07-30 11:46:44.573901690 +0530 +@@ -201,7 +201,7 @@ CFLAGS-pt-system.c = -fexceptions + + + tests = tst-typesizes \ +- tst-attr1 tst-attr2 tst-attr3 \ ++ tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ + tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ + tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \ + tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \ +@@ -276,6 +276,13 @@ gen-as-const-headers = pthread-errnos.sy + + LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst + ++# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack ++# from resizing the input size to avoid the 64K aliasing conflict on Intel ++# processors. ++DEFAULT_STACKSIZE=1052672 ++CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE) ++tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE) ++ + include ../Makeconfig + + ifeq ($(have-forced-unwind),yes) +diff -pruN glibc-2.17-c758a686/nptl/nptl-init.c glibc-2.17-c758a686/nptl/nptl-init.c +--- glibc-2.17-c758a686/nptl/nptl-init.c 2013-07-30 11:46:35.112902019 +0530 ++++ glibc-2.17-c758a686/nptl/nptl-init.c 2013-07-30 11:46:44.601901689 +0530 +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + + /* Size and alignment of static TLS block. */ +@@ -276,8 +277,28 @@ extern void **__libc_dl_error_tsd (void) + /* This can be set by the debugger before initialization is complete. */ + static bool __nptl_initial_report_events __attribute_used__; + ++/* Validate and set the default stacksize. */ ++static void ++set_default_stacksize (size_t stacksize) ++{ ++ if (stacksize < PTHREAD_STACK_MIN) ++ stacksize = PTHREAD_STACK_MIN; ++ ++ /* Make sure it meets the minimum size that allocate_stack ++ (allocatestack.c) will demand, which depends on the page size. */ ++ const uintptr_t pagesz = GLRO(dl_pagesize); ++ const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK; ++ ++ if (stacksize < minstack) ++ stacksize = minstack; ++ ++ /* Round the resource limit up to page size. */ ++ stacksize = ALIGN_UP (stacksize, pagesz); ++ __default_pthread_attr.stacksize = stacksize; ++} ++ + void +-__pthread_initialize_minimal_internal (void) ++__pthread_initialize_minimal_internal (int argc, char **argv, char **envp) + { + #ifndef SHARED + /* Unlike in the dynamically linked case the dynamic linker has not +@@ -401,29 +422,44 @@ __pthread_initialize_minimal_internal (v + + __static_tls_size = roundup (__static_tls_size, static_tls_align); + +- /* Determine the default allowed stack size. This is the size used +- in case the user does not specify one. */ +- struct rlimit limit; +- if (__getrlimit (RLIMIT_STACK, &limit) != 0 +- || limit.rlim_cur == RLIM_INFINITY) +- /* The system limit is not usable. Use an architecture-specific +- default. */ +- limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE; +- else if (limit.rlim_cur < PTHREAD_STACK_MIN) +- /* The system limit is unusably small. +- Use the minimal size acceptable. */ +- limit.rlim_cur = PTHREAD_STACK_MIN; ++ /* Initialize the environment. libc.so gets initialized after us due to a ++ circular dependency and hence __environ is not available otherwise. */ ++ __environ = envp; + +- /* Make sure it meets the minimum size that allocate_stack +- (allocatestack.c) will demand, which depends on the page size. */ +- const uintptr_t pagesz = GLRO(dl_pagesize); +- const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK; +- if (limit.rlim_cur < minstack) +- limit.rlim_cur = minstack; ++#ifndef SHARED ++ __libc_init_secure (); ++#endif + +- /* Round the resource limit up to page size. */ +- limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz; +- __default_pthread_attr.stacksize = limit.rlim_cur; ++ /* Get the default stack size from the environment variable if it is set and ++ is valid. */ ++ size_t stacksize = 0; ++ char *envval = __libc_secure_getenv ("GLIBC_PTHREAD_STACKSIZE"); ++ ++ if (__builtin_expect (envval != NULL && envval[0] != '\0', 0)) ++ { ++ char *env_conv = envval; ++ size_t ret = strtoul (envval, &env_conv, 0); ++ ++ if (*env_conv == '\0' && env_conv != envval) ++ stacksize = ret; ++ } ++ ++ if (stacksize == 0) ++ { ++ /* Determine the default allowed stack size. */ ++ struct rlimit limit; ++ if (__getrlimit (RLIMIT_STACK, &limit) != 0 ++ || limit.rlim_cur == RLIM_INFINITY) ++ /* The system limit is not usable. Use an architecture-specific ++ default. */ ++ stacksize = ARCH_STACK_DEFAULT_SIZE; ++ else ++ stacksize = limit.rlim_cur; ++ } ++ ++ /* Finally, set the default stack size. This size is used when the user does ++ not specify a stack size during thread creation. */ ++ set_default_stacksize (stacksize); + __default_pthread_attr.guardsize = GLRO (dl_pagesize); + + #ifdef SHARED +diff -pruN glibc-2.17-c758a686/nptl/tst-default-attr.c glibc-2.17-c758a686/nptl/tst-default-attr.c +--- glibc-2.17-c758a686/nptl/tst-default-attr.c 1970-01-01 05:30:00.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/tst-default-attr.c 2013-07-30 11:46:44.601901689 +0530 +@@ -0,0 +1,109 @@ ++/* Verify that default stack size gets set correctly from the environment ++ variable. ++ ++ Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define RETURN_IF_FAIL(f, ...) \ ++ ({ \ ++ int ret = f (__VA_ARGS__); \ ++ if (ret != 0) \ ++ { \ ++ printf ("%s:%d: %s returned %d (errno = %d)\n", __FILE__, __LINE__, \ ++ #f, ret, errno); \ ++ return ret; \ ++ } \ ++ }) ++ ++/* DEFAULT_STACKSIZE macro is defined in the Makefile. */ ++static size_t stacksize = DEFAULT_STACKSIZE; ++ ++static int ++verify_stacksize_result (pthread_attr_t *attr) ++{ ++ size_t stack; ++ ++ RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack); ++ ++ if (stacksize != stack) ++ { ++ printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void * ++thr (void *unused __attribute__ ((unused))) ++{ ++ pthread_attr_t attr; ++ int ret; ++ ++ memset (&attr, 0xab, sizeof attr); ++ /* To verify that the attributes actually got applied. */ ++ if ((ret = pthread_getattr_np (pthread_self (), &attr)) != 0) ++ { ++ printf ("pthread_getattr_np failed: %s\n", strerror (ret)); ++ goto out; ++ } ++ ++ ret = verify_stacksize_result (&attr); ++ ++out: ++ return (void *) (uintptr_t) ret; ++} ++ ++static int ++run_threads (void) ++{ ++ pthread_t t; ++ void *tret = NULL; ++ ++ /* Run twice to ensure that the attributes do not get overwritten in the ++ first run somehow. */ ++ for (int i = 0; i < 2; i++) ++ { ++ RETURN_IF_FAIL (pthread_create, &t, NULL, thr, NULL); ++ RETURN_IF_FAIL (pthread_join, t, &tret); ++ ++ if (tret != NULL) ++ { ++ puts ("Thread failed"); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++static int ++do_test (void) ++{ ++ RETURN_IF_FAIL (run_threads); ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" diff --git a/SOURCES/glibc-rh990388-3.patch b/SOURCES/glibc-rh990388-3.patch new file mode 100644 index 00000000..db3eff36 --- /dev/null +++ b/SOURCES/glibc-rh990388-3.patch @@ -0,0 +1,56 @@ +diff -pruN glibc-2.17-c758a686/nptl/pt-crti.S glibc-2.17-c758a686/nptl/pt-crti.S +--- glibc-2.17-c758a686/nptl/pt-crti.S 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pt-crti.S 2013-07-30 15:53:08.416386853 +0530 +@@ -39,5 +39,6 @@ + + #define PREINIT_FUNCTION __pthread_initialize_minimal_internal + #define PREINIT_FUNCTION_WEAK 0 ++#define PREINIT_FUNCTION_HAS_ARGS 1 + + #include +diff -pruN glibc-2.17-c758a686/sysdeps/i386/crti.S glibc-2.17-c758a686/sysdeps/i386/crti.S +--- glibc-2.17-c758a686/sysdeps/i386/crti.S 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/sysdeps/i386/crti.S 2013-07-30 16:38:41.085291690 +0530 +@@ -49,6 +49,13 @@ + # define PREINIT_FUNCTION_WEAK 1 + #endif + ++/* If the preinit function takes the argc, argv and envp arguments, push them ++ again on top before making the call. This is only used by for pt-crti for ++ nptl. */ ++#ifndef PREINIT_FUNCTION_HAS_ARGS ++# define PREINIT_FUNCTION_HAS_ARGS 0 ++#endif ++ + #if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) + #else +@@ -64,6 +68,18 @@ _init: + /* Maintain 16-byte stack alignment for called functions. */ + subl $8, %esp + LOAD_PIC_REG (bx) ++#if PREINIT_FUNCTION_HAS_ARGS ++/* Get argc, argv and envp from the stack and push them again on top so that ++ the called function can access them. Maintain 16-byte alignment for value ++ in %esp for called functions. */ ++ movl 16(%esp), %eax ++ movl 20(%esp), %ecx ++ movl 24(%esp), %edx ++ subl $4, %esp ++ pushl %edx ++ pushl %ecx ++ pushl %eax ++#endif + #if PREINIT_FUNCTION_WEAK + movl PREINIT_FUNCTION@GOT(%ebx), %eax + testl %eax, %eax +@@ -73,6 +89,9 @@ _init: + #else + call PREINIT_FUNCTION + #endif ++#if PREINIT_FUNCTION_HAS_ARGS ++ addl $16, %esp ++#endif + + .section .fini,"ax",@progbits + .p2align 2 diff --git a/SOURCES/glibc-rh990388-4.patch b/SOURCES/glibc-rh990388-4.patch new file mode 100644 index 00000000..36c0cb4e --- /dev/null +++ b/SOURCES/glibc-rh990388-4.patch @@ -0,0 +1,64 @@ +diff -pruN glibc-2.17-c758a686/nptl/Makefile glibc-2.17-c758a686/nptl/Makefile +--- glibc-2.17-c758a686/nptl/Makefile 2013-07-31 11:51:24.882747234 +0530 ++++ glibc-2.17-c758a686/nptl/Makefile 2013-07-31 11:58:55.964731526 +0530 +@@ -276,10 +276,7 @@ gen-as-const-headers = pthread-errnos.sy + + LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst + +-# The size is 1MB + 4KB. The extra 4KB has been added to prevent allocatestack +-# from resizing the input size to avoid the 64K aliasing conflict on Intel +-# processors. +-DEFAULT_STACKSIZE=1052672 ++DEFAULT_STACKSIZE=1048576 + CFLAGS-tst-default-attr.c = -DDEFAULT_STACKSIZE=$(DEFAULT_STACKSIZE) + tst-default-attr-ENV = GLIBC_PTHREAD_STACKSIZE=$(DEFAULT_STACKSIZE) + +diff -pruN glibc-2.17-c758a686/nptl/tst-default-attr.c glibc-2.17-c758a686/nptl/tst-default-attr.c +--- glibc-2.17-c758a686/nptl/tst-default-attr.c 2013-07-31 11:51:24.885747234 +0530 ++++ glibc-2.17-c758a686/nptl/tst-default-attr.c 2013-07-31 12:18:10.016691337 +0530 +@@ -38,6 +38,7 @@ + + /* DEFAULT_STACKSIZE macro is defined in the Makefile. */ + static size_t stacksize = DEFAULT_STACKSIZE; ++long int pagesize; + + static int + verify_stacksize_result (pthread_attr_t *attr) +@@ -46,12 +47,20 @@ verify_stacksize_result (pthread_attr_t + + RETURN_IF_FAIL (pthread_attr_getstacksize, attr, &stack); + +- if (stacksize != stack) ++ /* pthread_create perturbs the stack size by a page if it aligns to 64K to ++ avoid the 64K aliasing conflict. We cannot simply add 4K to the size in ++ the Makefile because it breaks the test on powerpc since the page size ++ there is 64K, resulting in a resize in __pthread_initialize_minimal. ++ Hence, our check is to ensure that the stack size is not more than a page ++ more than the requested size. */ ++ if (stack < stacksize || stack > stacksize + pagesize) + { + printf ("failed to set default stacksize (%zu, %zu)\n", stacksize, stack); + return 1; + } + ++ printf ("Requested %zu and got %zu\n", stacksize, stack); ++ + return 0; + } + +@@ -101,6 +110,15 @@ run_threads (void) + static int + do_test (void) + { ++ pthread_attr_t attr; ++ ++ pagesize = sysconf (_SC_PAGESIZE); ++ if (pagesize < 0) ++ { ++ printf ("sysconf failed: %s\n", strerror (errno)); ++ return 1; ++ } ++ + RETURN_IF_FAIL (run_threads); + return 0; + } diff --git a/SOURCES/glibc-rh990388.patch b/SOURCES/glibc-rh990388.patch new file mode 100644 index 00000000..44eb571d --- /dev/null +++ b/SOURCES/glibc-rh990388.patch @@ -0,0 +1,191 @@ +diff -pruN glibc-2.17-c758a686/include/libc-internal.h glibc-2.17-c758a686/include/libc-internal.h +--- glibc-2.17-c758a686/include/libc-internal.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/include/libc-internal.h 2013-07-30 11:26:37.947943710 +0530 +@@ -50,4 +50,24 @@ extern void __init_misc (int, char **, c + /* Cast an integer or a pointer VAL to integer with proper type. */ + # define cast_to_integer(val) ((__integer_if_pointer_type (val)) (val)) + ++/* Align a value by rounding down to closest size. ++ e.g. Using size of 4096, we get this behavior: ++ {4095, 4096, 4097} = {0, 4096, 4096}. */ ++#define ALIGN_DOWN(base, size) ((base) & -((__typeof__ (base)) (size))) ++ ++/* Align a value by rounding up to closest size. ++ e.g. Using size of 4096, we get this behavior: ++ {4095, 4096, 4097} = {4096, 4096, 8192}. ++ ++ Note: The size argument has side effects (expanded multiple times). */ ++#define ALIGN_UP(base, size) ALIGN_DOWN ((base) + (size) - 1, (size)) ++ ++/* Same as ALIGN_DOWN(), but automatically casts when base is a pointer. */ ++#define PTR_ALIGN_DOWN(base, size) \ ++ ((__typeof__ (base)) ALIGN_DOWN ((uintptr_t) (base), (size))) ++ ++/* Same as ALIGN_UP(), but automatically casts when base is a pointer. */ ++#define PTR_ALIGN_UP(base, size) \ ++ ((__typeof__ (base)) ALIGN_UP ((uintptr_t) (base), (size))) ++ + #endif /* _LIBC_INTERNAL */ +diff -pruN glibc-2.17-c758a686/nptl/allocatestack.c glibc-2.17-c758a686/nptl/allocatestack.c +--- glibc-2.17-c758a686/nptl/allocatestack.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/allocatestack.c 2013-07-30 11:26:38.012943707 +0530 +@@ -355,7 +355,7 @@ allocate_stack (const struct pthread_att + + /* Get the stack size from the attribute if it is set. Otherwise we + use the default we determined at start time. */ +- size = attr->stacksize ?: __default_stacksize; ++ size = attr->stacksize ?: __default_pthread_attr.stacksize; + + /* Get memory for the stack. */ + if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0)) +diff -pruN glibc-2.17-c758a686/nptl/nptl-init.c glibc-2.17-c758a686/nptl/nptl-init.c +--- glibc-2.17-c758a686/nptl/nptl-init.c 2013-07-30 11:45:16.902904743 +0530 ++++ glibc-2.17-c758a686/nptl/nptl-init.c 2013-07-30 11:44:59.538905347 +0530 +@@ -423,7 +423,8 @@ __pthread_initialize_minimal_internal (v + + /* Round the resource limit up to page size. */ + limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz; +- __default_stacksize = limit.rlim_cur; ++ __default_pthread_attr.stacksize = limit.rlim_cur; ++ __default_pthread_attr.guardsize = GLRO (dl_pagesize); + + #ifdef SHARED + /* Transfer the old value from the dynamic linker's internal location. */ +diff -pruN glibc-2.17-c758a686/nptl/pthread_attr_getstacksize.c glibc-2.17-c758a686/nptl/pthread_attr_getstacksize.c +--- glibc-2.17-c758a686/nptl/pthread_attr_getstacksize.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pthread_attr_getstacksize.c 2013-07-30 11:26:39.650943650 +0530 +@@ -32,7 +32,7 @@ __pthread_attr_getstacksize (attr, stack + + /* If the user has not set a stack size we return what the system + will use as the default. */ +- *stacksize = iattr->stacksize ?: __default_stacksize; ++ *stacksize = iattr->stacksize ?: __default_pthread_attr.stacksize; + + return 0; + } +diff -pruN glibc-2.17-c758a686/nptl/pthread_barrier_init.c glibc-2.17-c758a686/nptl/pthread_barrier_init.c +--- glibc-2.17-c758a686/nptl/pthread_barrier_init.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pthread_barrier_init.c 2013-07-30 11:26:40.206943631 +0530 +@@ -22,7 +22,7 @@ + #include + + +-static const struct pthread_barrierattr default_attr = ++static const struct pthread_barrierattr default_barrierattr = + { + .pshared = PTHREAD_PROCESS_PRIVATE + }; +@@ -42,7 +42,7 @@ pthread_barrier_init (barrier, attr, cou + const struct pthread_barrierattr *iattr + = (attr != NULL + ? iattr = (struct pthread_barrierattr *) attr +- : &default_attr); ++ : &default_barrierattr); + + if (iattr->pshared != PTHREAD_PROCESS_PRIVATE + && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0)) +diff -pruN glibc-2.17-c758a686/nptl/pthread_create.c glibc-2.17-c758a686/nptl/pthread_create.c +--- glibc-2.17-c758a686/nptl/pthread_create.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pthread_create.c 2013-07-30 11:26:40.774943611 +0530 +@@ -432,15 +432,6 @@ start_thread (void *arg) + } + + +-/* Default thread attributes for the case when the user does not +- provide any. */ +-static const struct pthread_attr default_attr = +- { +- /* Just some value > 0 which gets rounded to the nearest page size. */ +- .guardsize = 1, +- }; +- +- + int + __pthread_create_2_1 (newthread, attr, start_routine, arg) + pthread_t *newthread; +@@ -454,7 +445,7 @@ __pthread_create_2_1 (newthread, attr, s + if (iattr == NULL) + /* Is this the best idea? On NUMA machines this could mean + accessing far-away memory. */ +- iattr = &default_attr; ++ iattr = &__default_pthread_attr; + + struct pthread *pd = NULL; + int err = ALLOCATE_STACK (iattr, &pd); +diff -pruN glibc-2.17-c758a686/nptl/pthread_mutex_init.c glibc-2.17-c758a686/nptl/pthread_mutex_init.c +--- glibc-2.17-c758a686/nptl/pthread_mutex_init.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pthread_mutex_init.c 2013-07-30 11:26:42.079943566 +0530 +@@ -24,7 +24,7 @@ + + #include + +-static const struct pthread_mutexattr default_attr = ++static const struct pthread_mutexattr default_mutexattr = + { + /* Default is a normal mutex, not shared between processes. */ + .mutexkind = PTHREAD_MUTEX_NORMAL +@@ -45,7 +45,8 @@ __pthread_mutex_init (mutex, mutexattr) + + assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T); + +- imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr; ++ imutexattr = ((const struct pthread_mutexattr *) mutexattr ++ ?: &default_mutexattr); + + /* Sanity checks. */ + switch (__builtin_expect (imutexattr->mutexkind +diff -pruN glibc-2.17-c758a686/nptl/pthreadP.h glibc-2.17-c758a686/nptl/pthreadP.h +--- glibc-2.17-c758a686/nptl/pthreadP.h 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pthreadP.h 2013-07-30 11:26:43.095943530 +0530 +@@ -147,8 +147,8 @@ enum + /* Internal variables. */ + + +-/* Default stack size. */ +-extern size_t __default_stacksize attribute_hidden; ++/* Default pthread attributes. */ ++extern struct pthread_attr __default_pthread_attr attribute_hidden; + + /* Size and alignment of static TLS block. */ + extern size_t __static_tls_size attribute_hidden; +diff -pruN glibc-2.17-c758a686/nptl/pthread_rwlock_init.c glibc-2.17-c758a686/nptl/pthread_rwlock_init.c +--- glibc-2.17-c758a686/nptl/pthread_rwlock_init.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/pthread_rwlock_init.c 2013-07-30 11:26:43.745943508 +0530 +@@ -21,7 +21,7 @@ + #include + + +-static const struct pthread_rwlockattr default_attr = ++static const struct pthread_rwlockattr default_rwlockattr = + { + .lockkind = PTHREAD_RWLOCK_DEFAULT_NP, + .pshared = PTHREAD_PROCESS_PRIVATE +@@ -35,7 +35,7 @@ __pthread_rwlock_init (rwlock, attr) + { + const struct pthread_rwlockattr *iattr; + +- iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr; ++ iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_rwlockattr; + + memset (rwlock, '\0', sizeof (*rwlock)); + +diff -pruN glibc-2.17-c758a686/nptl/vars.c glibc-2.17-c758a686/nptl/vars.c +--- glibc-2.17-c758a686/nptl/vars.c 2012-12-25 08:32:13.000000000 +0530 ++++ glibc-2.17-c758a686/nptl/vars.c 2013-07-30 11:26:43.763943507 +0530 +@@ -20,13 +20,9 @@ + #include + #include + +-/* Default stack size. */ +-size_t __default_stacksize attribute_hidden +-#ifdef SHARED +-; +-#else +- = PTHREAD_STACK_MIN; +-#endif ++/* Default thread attributes for the case when the user does not ++ provide any. */ ++struct pthread_attr __default_pthread_attr attribute_hidden; + + /* Flag whether the machine is SMP or not. */ + int __is_smp attribute_hidden; diff --git a/SOURCES/glibc-rh990481-CVE-2013-4788.patch b/SOURCES/glibc-rh990481-CVE-2013-4788.patch new file mode 100644 index 00000000..7e392627 --- /dev/null +++ b/SOURCES/glibc-rh990481-CVE-2013-4788.patch @@ -0,0 +1,428 @@ +# +# As of 2013-08-09 this patch is posted upstream here, but not checked in yet: +# http://sourceware.org/ml/libc-alpha/2013-07/msg00367.html +# http://sourceware.org/ml/libc-alpha/2013-08/msg00057.html +# +# Red Hat bug: +# https://bugzilla.redhat.com/show_bug.cgi?id=990481 +# +# Upstream bug: +# http://sourceware.org/bugzilla/show_bug.cgi?id=15754 +# +# 2013-07-19 Carlos O'Donell +# +# [BZ #15754] +# * elf/Makefile (tests): Add tst-ptrguard1. +# (tests-static): Add tst-ptrguard1-static. +# (tst-ptrguard1-ARGS): Define. +# (tst-ptrguard1-static-ARGS): Define. +# * elf/tst-ptrguard1.c: New file. +# * elf/tst-ptrguard1-static.c: New file. +# * sysdeps/x86_64/stackguard-macros.h: Define POINTER_CHK_GUARD. +# * sysdeps/i386/stackguard-macros.h: Likewise. +# * sysdeps/powerpc/powerpc32/stackguard-macros.h: Likewise. +# * sysdeps/powerpc/powerpc64/stackguard-macros.h: Likewise. +# * sysdeps/s390/s390-32/stackguard-macros.h: Likewise. +# * sysdeps/s390/s390-64/stackguard-macros.h: Likewise. +# +# 2013-07-19 Hector Marco +# Ismael Ripoll +# Carlos O'Donell +# +# [BZ #15754] +# * sysdeps/generic/stackguard-macros.h: Define __pointer_chk_guard_local +# and POINTER_CHK_GUARD. +# * csu/libc-start.c [!SHARED && !THREAD_SET_POINTER_GUARD]: +# Define __pointer_chk_guard_local. +# (LIBC_START_MAIN) [!SHARED]: Call _dl_setup_pointer_guard. +# Use THREAD_SET_POINTER_GUARD or set __pointer_chk_guard_local. +# +diff -urN glibc-2.17-c758a686/csu/libc-start.c glibc-2.17-c758a686/csu/libc-start.c +--- glibc-2.17-c758a686/csu/libc-start.c 2013-08-09 17:40:41.662856773 -0400 ++++ glibc-2.17-c758a686/csu/libc-start.c 2013-08-09 17:53:40.383236966 -0400 +@@ -38,6 +38,12 @@ + in thread local area. */ + uintptr_t __stack_chk_guard attribute_relro; + # endif ++# ifndef THREAD_SET_POINTER_GUARD ++/* Only exported for architectures that don't store the pointer guard ++ value in thread local area. */ ++uintptr_t __pointer_chk_guard_local ++ attribute_relro attribute_hidden __attribute__ ((nocommon)); ++# endif + #endif + + #ifdef HAVE_PTR_NTHREADS +@@ -184,6 +190,16 @@ + # else + __stack_chk_guard = stack_chk_guard; + # endif ++ ++ /* Set up the pointer guard value. */ ++ uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random, ++ stack_chk_guard); ++# ifdef THREAD_SET_POINTER_GUARD ++ THREAD_SET_POINTER_GUARD (pointer_chk_guard); ++# else ++ __pointer_chk_guard_local = pointer_chk_guard; ++# endif ++ + #endif + + /* Register the destructor of the dynamic linker if there is any. */ +diff -urN glibc-2.17-c758a686/elf/Makefile glibc-2.17-c758a686/elf/Makefile +--- glibc-2.17-c758a686/elf/Makefile 2013-08-09 17:40:41.757856472 -0400 ++++ glibc-2.17-c758a686/elf/Makefile 2013-08-09 17:53:40.383236966 -0400 +@@ -121,7 +121,8 @@ + tests = tst-tls1 tst-tls2 tst-tls9 tst-leaks1 \ + tst-array1 tst-array2 tst-array3 tst-array4 tst-array5 + tests-static = tst-tls1-static tst-tls2-static tst-stackguard1-static \ +- tst-leaks1-static tst-array1-static tst-array5-static ++ tst-leaks1-static tst-array1-static tst-array5-static \ ++ tst-ptrguard1-static + ifeq (yes,$(build-shared)) + tests-static += tst-tls9-static + tst-tls9-static-ENV = \ +@@ -145,7 +146,7 @@ + tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ + tst-stackguard1 tst-addr1 tst-thrlock \ + tst-unique1 tst-unique2 tst-unique3 tst-unique4 \ +- tst-initorder tst-initorder2 tst-relsort1 ++ tst-initorder tst-initorder2 tst-relsort1 tst-ptrguard1 + # reldep9 + test-srcs = tst-pathopt + selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null) +@@ -1062,6 +1063,9 @@ + tst-stackguard1-ARGS = --command "$(host-built-program-cmd) --child" + tst-stackguard1-static-ARGS = --command "$(objpfx)tst-stackguard1-static --child" + ++tst-ptrguard1-ARGS = --command "$(host-built-program-cmd) --child" ++tst-ptrguard1-static-ARGS = --command "$(objpfx)tst-ptrguard1-static --child" ++ + $(objpfx)tst-leaks1: $(libdl) + $(objpfx)tst-leaks1-mem: $(objpfx)tst-leaks1.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks1.mtrace > $@ +diff -urN glibc-2.17-c758a686/elf/tst-ptrguard1.c glibc-2.17-c758a686/elf/tst-ptrguard1.c +--- glibc-2.17-c758a686/elf/tst-ptrguard1.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/elf/tst-ptrguard1.c 2013-08-09 17:53:40.383236966 -0400 +@@ -0,0 +1,202 @@ ++/* Copyright (C) 2013 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef POINTER_CHK_GUARD ++extern uintptr_t __pointer_chk_guard_local; ++# define POINTER_CHK_GUARD __pointer_chk_guard_local ++#endif ++ ++static const char *command; ++static bool child; ++static uintptr_t ptr_chk_guard_copy; ++static bool ptr_chk_guard_copy_set; ++static int fds[2]; ++ ++static void __attribute__ ((constructor)) ++con (void) ++{ ++ ptr_chk_guard_copy = POINTER_CHK_GUARD; ++ ptr_chk_guard_copy_set = true; ++} ++ ++static int ++uintptr_t_cmp (const void *a, const void *b) ++{ ++ if (*(uintptr_t *) a < *(uintptr_t *) b) ++ return 1; ++ if (*(uintptr_t *) a > *(uintptr_t *) b) ++ return -1; ++ return 0; ++} ++ ++static int ++do_test (void) ++{ ++ if (!ptr_chk_guard_copy_set) ++ { ++ puts ("constructor has not been run"); ++ return 1; ++ } ++ ++ if (ptr_chk_guard_copy != POINTER_CHK_GUARD) ++ { ++ puts ("POINTER_CHK_GUARD changed between constructor and do_test"); ++ return 1; ++ } ++ ++ if (child) ++ { ++ write (2, &ptr_chk_guard_copy, sizeof (ptr_chk_guard_copy)); ++ return 0; ++ } ++ ++ if (command == NULL) ++ { ++ puts ("missing --command or --child argument"); ++ return 1; ++ } ++ ++#define N 16 ++ uintptr_t child_ptr_chk_guards[N + 1]; ++ child_ptr_chk_guards[N] = ptr_chk_guard_copy; ++ int i; ++ for (i = 0; i < N; ++i) ++ { ++ if (pipe (fds) < 0) ++ { ++ printf ("couldn't create pipe: %m\n"); ++ return 1; ++ } ++ ++ pid_t pid = fork (); ++ if (pid < 0) ++ { ++ printf ("fork failed: %m\n"); ++ return 1; ++ } ++ ++ if (!pid) ++ { ++ if (ptr_chk_guard_copy != POINTER_CHK_GUARD) ++ { ++ puts ("POINTER_CHK_GUARD changed after fork"); ++ exit (1); ++ } ++ ++ close (fds[0]); ++ close (2); ++ dup2 (fds[1], 2); ++ close (fds[1]); ++ ++ system (command); ++ exit (0); ++ } ++ ++ close (fds[1]); ++ ++ if (TEMP_FAILURE_RETRY (read (fds[0], &child_ptr_chk_guards[i], ++ sizeof (uintptr_t))) != sizeof (uintptr_t)) ++ { ++ puts ("could not read ptr_chk_guard value from child"); ++ return 1; ++ } ++ ++ close (fds[0]); ++ ++ pid_t termpid; ++ int status; ++ termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)); ++ if (termpid == -1) ++ { ++ printf ("waitpid failed: %m\n"); ++ return 1; ++ } ++ else if (termpid != pid) ++ { ++ printf ("waitpid returned %ld != %ld\n", ++ (long int) termpid, (long int) pid); ++ return 1; ++ } ++ else if (!WIFEXITED (status) || WEXITSTATUS (status)) ++ { ++ puts ("child hasn't exited with exit status 0"); ++ return 1; ++ } ++ } ++ ++ qsort (child_ptr_chk_guards, N + 1, sizeof (uintptr_t), uintptr_t_cmp); ++ ++ /* The default pointer guard is the same as the default stack guard. ++ They are only set to default if dl_random is NULL. */ ++ uintptr_t default_guard = 0; ++ unsigned char *p = (unsigned char *) &default_guard; ++ p[sizeof (uintptr_t) - 1] = 255; ++ p[sizeof (uintptr_t) - 2] = '\n'; ++ p[0] = 0; ++ ++ /* Test if the pointer guard canaries are either randomized, ++ or equal to the default pointer guard canary value. ++ Even with randomized pointer guards it might happen ++ that the random number generator generates the same ++ values, but if that happens in more than half from ++ the 16 runs, something is very wrong. */ ++ int ndifferences = 0; ++ int ndefaults = 0; ++ for (i = 0; i < N; ++i) ++ { ++ if (child_ptr_chk_guards[i] != child_ptr_chk_guards[i+1]) ++ ndifferences++; ++ else if (child_ptr_chk_guards[i] == default_guard) ++ ndefaults++; ++ } ++ ++ printf ("differences %d defaults %d\n", ndifferences, ndefaults); ++ ++ if (ndifferences < N / 2 && ndefaults < N / 2) ++ { ++ puts ("pointer guard canaries are not randomized enough"); ++ puts ("nor equal to the default canary value"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#define OPT_COMMAND 10000 ++#define OPT_CHILD 10001 ++#define CMDLINE_OPTIONS \ ++ { "command", required_argument, NULL, OPT_COMMAND }, \ ++ { "child", no_argument, NULL, OPT_CHILD }, ++#define CMDLINE_PROCESS \ ++ case OPT_COMMAND: \ ++ command = optarg; \ ++ break; \ ++ case OPT_CHILD: \ ++ child = true; \ ++ break; ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +diff -urN glibc-2.17-c758a686/elf/tst-ptrguard1-static.c glibc-2.17-c758a686/elf/tst-ptrguard1-static.c +--- glibc-2.17-c758a686/elf/tst-ptrguard1-static.c 1969-12-31 19:00:00.000000000 -0500 ++++ glibc-2.17-c758a686/elf/tst-ptrguard1-static.c 2013-08-09 17:53:40.384236962 -0400 +@@ -0,0 +1 @@ ++#include "tst-ptrguard1.c" +diff -urN glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h +--- glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h 2013-08-09 17:40:41.917855965 -0400 ++++ glibc-2.17-c758a686/sysdeps/generic/stackguard-macros.h 2013-08-09 17:53:40.384236962 -0400 +@@ -2,3 +2,6 @@ + + extern uintptr_t __stack_chk_guard; + #define STACK_CHK_GUARD __stack_chk_guard ++ ++extern uintptr_t __pointer_chk_guard_local; ++#define POINTER_CHK_GUARD __pointer_chk_guard_local +diff -urN glibc-2.17-c758a686/sysdeps/i386/stackguard-macros.h glibc-2.17-c758a686/sysdeps/i386/stackguard-macros.h +--- glibc-2.17-c758a686/sysdeps/i386/stackguard-macros.h 2013-08-09 17:40:41.893856041 -0400 ++++ glibc-2.17-c758a686/sysdeps/i386/stackguard-macros.h 2013-08-09 22:44:04.774298862 -0400 +@@ -2,3 +2,11 @@ + + #define STACK_CHK_GUARD \ + ({ uintptr_t x; asm ("movl %%gs:0x14, %0" : "=r" (x)); x; }) ++ ++#define POINTER_CHK_GUARD \ ++ ({ \ ++ uintptr_t x; \ ++ asm ("movl %%gs:%c1, %0" : "=r" (x) \ ++ : "i" (offsetof (tcbhead_t, pointer_guard))); \ ++ x; \ ++ }) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stackguard-macros.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stackguard-macros.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stackguard-macros.h 2013-08-09 17:40:42.006855683 -0400 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc32/stackguard-macros.h 2013-08-09 22:24:48.778793075 -0400 +@@ -2,3 +2,13 @@ + + #define STACK_CHK_GUARD \ + ({ uintptr_t x; asm ("lwz %0,-28680(2)" : "=r" (x)); x; }) ++ ++#define POINTER_CHK_GUARD \ ++ ({ \ ++ uintptr_t x; \ ++ asm ("lwz %0,%1(2)" \ ++ : "=r" (x) \ ++ : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \ ++ ); \ ++ x; \ ++ }) +diff -urN glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stackguard-macros.h glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stackguard-macros.h +--- glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stackguard-macros.h 2013-08-09 17:40:41.994855721 -0400 ++++ glibc-2.17-c758a686/sysdeps/powerpc/powerpc64/stackguard-macros.h 2013-08-09 22:24:47.831795865 -0400 +@@ -2,3 +2,13 @@ + + #define STACK_CHK_GUARD \ + ({ uintptr_t x; asm ("ld %0,-28688(13)" : "=r" (x)); x; }) ++ ++#define POINTER_CHK_GUARD \ ++ ({ \ ++ uintptr_t x; \ ++ asm ("ld %0,%1(13)" \ ++ : "=r" (x) \ ++ : "i" (offsetof (tcbhead_t, pointer_guard) - TLS_TCB_OFFSET - sizeof (tcbhead_t)) \ ++ ); \ ++ x; \ ++ }) +diff -urN glibc-2.17-c758a686/sysdeps/s390/s390-32/stackguard-macros.h glibc-2.17-c758a686/sysdeps/s390/s390-32/stackguard-macros.h +--- glibc-2.17-c758a686/sysdeps/s390/s390-32/stackguard-macros.h 2013-08-09 17:40:42.059855515 -0400 ++++ glibc-2.17-c758a686/sysdeps/s390/s390-32/stackguard-macros.h 2013-08-09 22:39:31.913120373 -0400 +@@ -2,3 +2,15 @@ + + #define STACK_CHK_GUARD \ + ({ uintptr_t x; asm ("ear %0,%%a0; l %0,0x14(%0)" : "=a" (x)); x; }) ++ ++/* On s390/s390x there is no unique pointer guard, instead we use the ++ same value as the stack guard. */ ++#define POINTER_CHK_GUARD \ ++ ({ \ ++ uintptr_t x; \ ++ asm ("ear %0,%%a0; l %0,%1(%0)" \ ++ : "=a" (x) \ ++ : "i" (offsetof (tcbhead_t, stack_guard))); \ ++ x; \ ++ }) ++ +diff -urN glibc-2.17-c758a686/sysdeps/x86_64/stackguard-macros.h glibc-2.17-c758a686/sysdeps/x86_64/stackguard-macros.h +--- glibc-2.17-c758a686/sysdeps/x86_64/stackguard-macros.h 2013-08-09 17:40:42.013855661 -0400 ++++ glibc-2.17-c758a686/sysdeps/x86_64/stackguard-macros.h 2013-08-09 22:44:53.550153736 -0400 +@@ -4,3 +4,11 @@ + ({ uintptr_t x; \ + asm ("mov %%fs:%c1, %0" : "=r" (x) \ + : "i" (offsetof (tcbhead_t, stack_guard))); x; }) ++ ++#define POINTER_CHK_GUARD \ ++ ({ \ ++ uintptr_t x; \ ++ asm ("mov %%fs:%c1, %0" : "=r" (x) \ ++ : "i" (offsetof (tcbhead_t, pointer_guard))); \ ++ x; \ ++ }) +--- glibc-2.17-c758a686/sysdeps/s390/s390-64/stackguard-macros.h 2013-08-09 17:40:42.057855522 -0400 ++++ glibc-2.17-c758a686/sysdeps/s390/s390-64/stackguard-macros.h 2013-08-26 15:21:27.239043425 -0400 +@@ -2,3 +2,17 @@ + + #define STACK_CHK_GUARD \ + ({ uintptr_t x; asm ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; }) ++ ++/* On s390/s390x there is no unique pointer guard, instead we use the ++ same value as the stack guard. */ ++#define POINTER_CHK_GUARD \ ++ ({ \ ++ uintptr_t x; \ ++ asm ("ear %0,%%a0;" \ ++ "sllg %0,%0,32;" \ ++ "ear %0,%%a1;" \ ++ "lg %0,%1(%0)" \ ++ : "=a" (x) \ ++ : "i" (offsetof (tcbhead_t, stack_guard))); \ ++ x; \ ++ }) diff --git a/SOURCES/glibc-rh996227.patch b/SOURCES/glibc-rh996227.patch new file mode 100644 index 00000000..e7bc4965 --- /dev/null +++ b/SOURCES/glibc-rh996227.patch @@ -0,0 +1,302 @@ +commit 91ce40854d0b7f865cf5024ef95a8026b76096f3 +Author: Florian Weimer +Date: Fri Aug 16 09:38:52 2013 +0200 + + CVE-2013-4237, BZ #14699: Buffer overflow in readdir_r + + * sysdeps/posix/dirstream.h (struct __dirstream): Add errcode + member. + * sysdeps/posix/opendir.c (__alloc_dir): Initialize errcode + member. + * sysdeps/posix/rewinddir.c (rewinddir): Reset errcode member. + * sysdeps/posix/readdir_r.c (__READDIR_R): Enforce NAME_MAX limit. + Return delayed error code. Remove GETDENTS_64BIT_ALIGNED + conditional. + * sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c: Do not define + GETDENTS_64BIT_ALIGNED. + * sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise. + * manual/filesys.texi (Reading/Closing Directory): Document + ENAMETOOLONG return value of readdir_r. Recommend readdir more + strongly. + * manual/conf.texi (Limits for Files): Add portability note to + NAME_MAX, PATH_MAX. + (Pathconf): Add portability note for _PC_NAME_MAX, _PC_PATH_MAX. + +diff --git glibc-2.17-c758a686/manual/conf.texi glibc-2.17-c758a686/manual/conf.texi +index 7eb8b36..c720063 100644 +--- glibc-2.17-c758a686/manual/conf.texi ++++ glibc-2.17-c758a686/manual/conf.texi +@@ -1149,6 +1149,9 @@ typed ahead as input. @xref{I/O Queues}. + @deftypevr Macro int NAME_MAX + The uniform system limit (if any) for the length of a file name component, not + including the terminating null character. ++ ++@strong{Portability Note:} On some systems, @theglibc{} defines ++@code{NAME_MAX}, but does not actually enforce this limit. + @end deftypevr + + @comment limits.h +@@ -1157,6 +1160,9 @@ including the terminating null character. + The uniform system limit (if any) for the length of an entire file name (that + is, the argument given to system calls such as @code{open}), including the + terminating null character. ++ ++@strong{Portability Note:} @Theglibc{} does not enforce this limit ++even if @code{PATH_MAX} is defined. + @end deftypevr + + @cindex limits, pipe buffer size +@@ -1476,6 +1482,9 @@ Inquire about the value of @code{POSIX_REC_MIN_XFER_SIZE}. + Inquire about the value of @code{POSIX_REC_XFER_ALIGN}. + @end table + ++@strong{Portability Note:} On some systems, @theglibc{} does not ++enforce @code{_PC_NAME_MAX} or @code{_PC_PATH_MAX} limits. ++ + @node Utility Limits + @section Utility Program Capacity Limits + +diff --git glibc-2.17-c758a686/manual/filesys.texi glibc-2.17-c758a686/manual/filesys.texi +index 1df9cf2..814c210 100644 +--- glibc-2.17-c758a686/manual/filesys.texi ++++ glibc-2.17-c758a686/manual/filesys.texi +@@ -444,9 +444,9 @@ symbols are declared in the header file @file{dirent.h}. + @comment POSIX.1 + @deftypefun {struct dirent *} readdir (DIR *@var{dirstream}) + This function reads the next entry from the directory. It normally +-returns a pointer to a structure containing information about the file. +-This structure is statically allocated and can be rewritten by a +-subsequent call. ++returns a pointer to a structure containing information about the ++file. This structure is associated with the @var{dirstream} handle ++and can be rewritten by a subsequent call. + + @strong{Portability Note:} On some systems @code{readdir} may not + return entries for @file{.} and @file{..}, even though these are always +@@ -461,19 +461,61 @@ conditions are defined for this function: + The @var{dirstream} argument is not valid. + @end table + +-@code{readdir} is not thread safe. Multiple threads using +-@code{readdir} on the same @var{dirstream} may overwrite the return +-value. Use @code{readdir_r} when this is critical. ++To distinguish between an end-of-directory condition or an error, you ++must set @code{errno} to zero before calling @code{readdir}. To avoid ++entering an infinite loop, you should stop reading from the directory ++after the first error. ++ ++In POSIX.1-2008, @code{readdir} is not thread-safe. In @theglibc{} ++implementation, it is safe to call @code{readdir} concurrently on ++different @var{dirstream}s, but multiple threads accessing the same ++@var{dirstream} result in undefined behavior. @code{readdir_r} is a ++fully thread-safe alternative, but suffers from poor portability (see ++below). It is recommended that you use @code{readdir}, with external ++locking if multiple threads access the same @var{dirstream}. + @end deftypefun + + @comment dirent.h + @comment GNU + @deftypefun int readdir_r (DIR *@var{dirstream}, struct dirent *@var{entry}, struct dirent **@var{result}) +-This function is the reentrant version of @code{readdir}. Like +-@code{readdir} it returns the next entry from the directory. But to +-prevent conflicts between simultaneously running threads the result is +-not stored in statically allocated memory. Instead the argument +-@var{entry} points to a place to store the result. ++This function is a version of @code{readdir} which performs internal ++locking. Like @code{readdir} it returns the next entry from the ++directory. To prevent conflicts between simultaneously running ++threads the result is stored inside the @var{entry} object. ++ ++@strong{Portability Note:} It is recommended to use @code{readdir} ++instead of @code{readdir_r} for the following reasons: ++ ++@itemize @bullet ++@item ++On systems which do not define @code{NAME_MAX}, it may not be possible ++to use @code{readdir_r} safely because the caller does not specify the ++length of the buffer for the directory entry. ++ ++@item ++On some systems, @code{readdir_r} cannot read directory entries with ++very long names. If such a name is encountered, @theglibc{} ++implementation of @code{readdir_r} returns with an error code of ++@code{ENAMETOOLONG} after the final directory entry has been read. On ++other systems, @code{readdir_r} may return successfully, but the ++@code{d_name} member may not be NUL-terminated or may be truncated. ++ ++@item ++POSIX-1.2008 does not guarantee that @code{readdir} is thread-safe, ++even when access to the same @var{dirstream} is serialized. But in ++current implementations (including @theglibc{}), it is safe to call ++@code{readdir} concurrently on different @var{dirstream}s, so there is ++no need to use @code{readdir_r} in most multi-threaded programs. In ++the rare case that multiple threads need to read from the same ++@var{dirstream}, it is still better to use @code{readdir} and external ++synchronization. ++ ++@item ++It is expected that future versions of POSIX will obsolete ++@code{readdir_r} and mandate the level of thread safety for ++@code{readdir} which is provided by @theglibc{} and other ++implementations today. ++@end itemize + + Normally @code{readdir_r} returns zero and sets @code{*@var{result}} + to @var{entry}. If there are no more entries in the directory or an +@@ -481,15 +523,6 @@ error is detected, @code{readdir_r} sets @code{*@var{result}} to a + null pointer and returns a nonzero error code, also stored in + @code{errno}, as described for @code{readdir}. + +-@strong{Portability Note:} On some systems @code{readdir_r} may not +-return a NUL terminated string for the file name, even when there is no +-@code{d_reclen} field in @code{struct dirent} and the file +-name is the maximum allowed size. Modern systems all have the +-@code{d_reclen} field, and on old systems multi-threading is not +-critical. In any case there is no such problem with the @code{readdir} +-function, so that even on systems without the @code{d_reclen} member one +-could use multiple threads by using external locking. +- + It is also important to look at the definition of the @code{struct + dirent} type. Simply passing a pointer to an object of this type for + the second parameter of @code{readdir_r} might not be enough. Some +diff --git glibc-2.17-c758a686/sysdeps/posix/dirstream.h glibc-2.17-c758a686/sysdeps/posix/dirstream.h +index a7a074d..8e8570d 100644 +--- glibc-2.17-c758a686/sysdeps/posix/dirstream.h ++++ glibc-2.17-c758a686/sysdeps/posix/dirstream.h +@@ -39,6 +39,8 @@ struct __dirstream + + off_t filepos; /* Position of next entry to read. */ + ++ int errcode; /* Delayed error code. */ ++ + /* Directory block. */ + char data[0] __attribute__ ((aligned (__alignof__ (void*)))); + }; +diff --git glibc-2.17-c758a686/sysdeps/posix/opendir.c glibc-2.17-c758a686/sysdeps/posix/opendir.c +index ddfc3a7..fc05b0f 100644 +--- glibc-2.17-c758a686/sysdeps/posix/opendir.c ++++ glibc-2.17-c758a686/sysdeps/posix/opendir.c +@@ -231,6 +231,7 @@ __alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp) + dirp->size = 0; + dirp->offset = 0; + dirp->filepos = 0; ++ dirp->errcode = 0; + + return dirp; + } +diff --git glibc-2.17-c758a686/sysdeps/posix/readdir_r.c glibc-2.17-c758a686/sysdeps/posix/readdir_r.c +index b5a8e2e..8ed5c3f 100644 +--- glibc-2.17-c758a686/sysdeps/posix/readdir_r.c ++++ glibc-2.17-c758a686/sysdeps/posix/readdir_r.c +@@ -40,6 +40,7 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) + DIRENT_TYPE *dp; + size_t reclen; + const int saved_errno = errno; ++ int ret; + + __libc_lock_lock (dirp->lock); + +@@ -70,10 +71,10 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) + bytes = 0; + __set_errno (saved_errno); + } ++ if (bytes < 0) ++ dirp->errcode = errno; + + dp = NULL; +- /* Reclen != 0 signals that an error occurred. */ +- reclen = bytes != 0; + break; + } + dirp->size = (size_t) bytes; +@@ -106,29 +107,46 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) + dirp->filepos += reclen; + #endif + +- /* Skip deleted files. */ ++#ifdef NAME_MAX ++ if (reclen > offsetof (DIRENT_TYPE, d_name) + NAME_MAX + 1) ++ { ++ /* The record is very long. It could still fit into the ++ caller-supplied buffer if we can skip padding at the ++ end. */ ++ size_t namelen = _D_EXACT_NAMLEN (dp); ++ if (namelen <= NAME_MAX) ++ reclen = offsetof (DIRENT_TYPE, d_name) + namelen + 1; ++ else ++ { ++ /* The name is too long. Ignore this file. */ ++ dirp->errcode = ENAMETOOLONG; ++ dp->d_ino = 0; ++ continue; ++ } ++ } ++#endif ++ ++ /* Skip deleted and ignored files. */ + } + while (dp->d_ino == 0); + + if (dp != NULL) + { +-#ifdef GETDENTS_64BIT_ALIGNED +- /* The d_reclen value might include padding which is not part of +- the DIRENT_TYPE data structure. */ +- reclen = MIN (reclen, +- offsetof (DIRENT_TYPE, d_name) + sizeof (dp->d_name)); +-#endif + *result = memcpy (entry, dp, reclen); +-#ifdef GETDENTS_64BIT_ALIGNED ++#ifdef _DIRENT_HAVE_D_RECLEN + entry->d_reclen = reclen; + #endif ++ ret = 0; + } + else +- *result = NULL; ++ { ++ *result = NULL; ++ ret = dirp->errcode; ++ } + + __libc_lock_unlock (dirp->lock); + +- return dp != NULL ? 0 : reclen ? errno : 0; ++ return ret; + } + + #ifdef __READDIR_R_ALIAS +diff --git glibc-2.17-c758a686/sysdeps/posix/rewinddir.c glibc-2.17-c758a686/sysdeps/posix/rewinddir.c +index 2935a8e..d4991ad 100644 +--- glibc-2.17-c758a686/sysdeps/posix/rewinddir.c ++++ glibc-2.17-c758a686/sysdeps/posix/rewinddir.c +@@ -33,6 +33,7 @@ rewinddir (dirp) + dirp->filepos = 0; + dirp->offset = 0; + dirp->size = 0; ++ dirp->errcode = 0; + #ifndef NOT_IN_libc + __libc_lock_unlock (dirp->lock); + #endif +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/readdir64_r.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/readdir64_r.c +index 8ebbcfd..a7d114e 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/readdir64_r.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/i386/readdir64_r.c +@@ -18,7 +18,6 @@ + #define __READDIR_R __readdir64_r + #define __GETDENTS __getdents64 + #define DIRENT_TYPE struct dirent64 +-#define GETDENTS_64BIT_ALIGNED 1 + + #include + +diff --git glibc-2.17-c758a686/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c glibc-2.17-c758a686/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c +index 5ed8e95..290f2c8 100644 +--- glibc-2.17-c758a686/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c ++++ glibc-2.17-c758a686/sysdeps/unix/sysv/linux/wordsize-64/readdir_r.c +@@ -1,5 +1,4 @@ + #define readdir64_r __no_readdir64_r_decl +-#define GETDENTS_64BIT_ALIGNED 1 + #include + #undef readdir64_r + weak_alias (__readdir_r, readdir64_r) diff --git a/SOURCES/glibc-rtkaio-inc-pthread.patch b/SOURCES/glibc-rtkaio-inc-pthread.patch new file mode 100644 index 00000000..372f25b2 --- /dev/null +++ b/SOURCES/glibc-rtkaio-inc-pthread.patch @@ -0,0 +1,20 @@ +diff -urN glibc-2.17-c758a686/rtkaio/tst-aiod2.c glibc-2.17-c758a686/rtkaio/tst-aiod2.c +--- glibc-2.17-c758a686/rtkaio/tst-aiod2.c 2011-10-19 07:04:41.000000000 -0400 ++++ glibc-2.17-c758a686/rtkaio/tst-aiod2.c 2014-08-19 18:32:10.174233598 -0400 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include "tst-aiod.h" + + +diff -urN glibc-2.17-c758a686/rtkaio/tst-aiod3.c glibc-2.17-c758a686/rtkaio/tst-aiod3.c +--- glibc-2.17-c758a686/rtkaio/tst-aiod3.c 2011-10-19 07:04:41.000000000 -0400 ++++ glibc-2.17-c758a686/rtkaio/tst-aiod3.c 2014-08-19 18:31:59.855273111 -0400 +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include "tst-aiod.h" diff --git a/SOURCES/glibc-stap-libm.patch b/SOURCES/glibc-stap-libm.patch new file mode 100644 index 00000000..1b68d67a --- /dev/null +++ b/SOURCES/glibc-stap-libm.patch @@ -0,0 +1,80 @@ +Related upstream commit: + +commit 10e1cf6b73f1598e57d24933a0949dbeffa2c8a0 +Author: Siddhesh Poyarekar +Date: Fri Oct 11 22:37:53 2013 +0530 + + Add systemtap markers to math function slow paths + +diff -rup glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowexp.c glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowexp.c +--- glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowexp.c 2012-05-20 19:47:38.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowexp.c 2012-05-21 10:02:51.693957300 -0600 +@@ -30,6 +30,8 @@ + #include "mpa.h" + #include + ++#include ++ + #ifndef SECTION + # define SECTION + #endif +@@ -60,12 +62,21 @@ __slowexp(double x) { + __sub(&mpy,&mpcor,&mpz,p); + __mp_dbl(&mpw, &w, p); + __mp_dbl(&mpz, &z, p); +- if (w == z) return w; ++ if (w == z) { ++ /* Track how often we get to the slow exp code plus ++ its input/output values. */ ++ LIBC_PROBE (slowexp_p6, 2, &x, &w); ++ return w; ++ } + else { /* if calculating is not exactly */ + p = 32; + __dbl_mp(x,&mpx,p); + __mpexp(&mpx, &mpy, p); + __mp_dbl(&mpy, &res, p); ++ ++ /* Track how often we get to the uber-slow exp code plus ++ its input/output values. */ ++ LIBC_PROBE (slowexp_p32, 2, &x, &res); + return res; + } + } +diff -rup glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowpow.c glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowpow.c +--- glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowpow.c 2012-05-20 19:47:38.000000000 -0600 ++++ glibc-2.17-c758a686/sysdeps/ieee754/dbl-64/slowpow.c 2012-05-21 10:02:51.694957291 -0600 +@@ -34,6 +34,8 @@ + #include "mpa.h" + #include + ++#include ++ + #ifndef SECTION + # define SECTION + #endif +@@ -65,7 +67,12 @@ __slowpow(double x, double y, double z) + __mp_dbl(&mpr, &res, p); + __sub(&mpp,&eps,&mpr1,p); /* pp -eps =r1 */ + __mp_dbl(&mpr1, &res1, p); /* converting into double precision */ +- if (res == res1) return res; ++ if (res == res1) { ++ /* Track how often we get to the slow pow code plus ++ its input/output values. */ ++ LIBC_PROBE (slowpow_p10, 4, &x, &y, &z, &res); ++ return res; ++ } + + p = 32; /* if we get here result wasn't calculated exactly, continue */ + __dbl_mp(x,&mpx,p); /* for more exact calculation */ +@@ -75,5 +82,10 @@ __slowpow(double x, double y, double z) + __mul(&mpy,&mpz,&mpw,p); /* y*z =w */ + __mpexp(&mpw, &mpp, p); /* e^w=pp */ + __mp_dbl(&mpp, &res, p); /* converting into double precision */ ++ ++ /* Track how often we get to the uber-slow pow code plus ++ its input/output values. */ ++ LIBC_PROBE (slowpow_p32, 4, &x, &y, &z, &res); ++ + return res; + } diff --git a/SOURCES/verify.md5 b/SOURCES/verify.md5 new file mode 100644 index 00000000..3bad1fef --- /dev/null +++ b/SOURCES/verify.md5 @@ -0,0 +1,4 @@ +af8e61a4eae427435df03fb8c0ac1057 timezone/testdata/XT1 +b7576564a990041686fc842750e1d235 timezone/testdata/XT2 +2426e353a98edb6620e054f1e9fec78f timezone/testdata/XT3 +715970e1ae4c5bfbb3c1c373bf5f1cca timezone/testdata/XT4 diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index 442c1478..30bf4b5d 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.17-c758a686 %define glibcversion 2.17 -%define glibcrelease 157%{?dist} +%define glibcrelease 222%{?dist} ############################################################################## # We support the following options: # --with/--without, @@ -75,7 +75,6 @@ # - POWER8 LE (default) # 32-bit BE: # - POWER7 (default) -# - POWER8 (enabled via AT_PLATFORM) # # The POWER5 and POWER6 runtimes are now deprecated and no longer provided # or supported. This means that RHEL7 BE will only run on POWER7 or newer @@ -117,6 +116,13 @@ # execution is provided by STT_GNU_IFUNC. %define multiarcharches ppc %{power64} %{ix86} x86_64 %{sparc} s390 s390x ############################################################################## +# If the architecture has elision support in glibc then it should be listed +# here to enable elision for default pthread mutexes and rwlocks. The elision +# is not enabled automatically and each process has to opt-in to elision via +# the environment variable RHEL_GLIBC_TUNABLES by setting it to enabled e.g. +# RHEL_GLIBC_TUNABLES="glibc.elision.enable=1". +%define elisionarches x86_64 %{power64} +############################################################################## # Add -s for a less verbose build output. %define silentrules PARALLELMFLAGS= ############################################################################## @@ -146,6 +152,7 @@ URL: http://www.gnu.org/software/glibc/ # changes should then be a very very small patch set. Source0: %{?glibc_release_url}%{glibcsrcdir}.tar.gz Source1: %{glibcsrcdir}-releng.tar.gz +Source2: verify.md5 ############################################################################## # Start of glibc patches @@ -925,6 +932,236 @@ Patch1755: glibc-rh1298526-4.patch # RHBZ #1350733 locale-archive.tmpl cannot be processed by build-locale-archive Patch1756: glibc-rh1350733-1.patch +# Fix tst-cancel17/tst-cancelx17, which sometimes segfaults while exiting. +Patch1757: glibc-rh1337242.patch + +# RHBZ #1418978: backport upstream support/ directory +Patch17580: glibc-rh1418978-max_align_t.patch +Patch1758: glibc-rh1418978-0.patch +Patch1759: glibc-rh1418978-1.patch +Patch1760: glibc-rh1418978-2-1.patch +Patch1761: glibc-rh1418978-2-2.patch +Patch1762: glibc-rh1418978-2-3.patch +Patch1763: glibc-rh1418978-2-4.patch +Patch1764: glibc-rh1418978-2-5.patch +Patch1765: glibc-rh1418978-2-6.patch +Patch1766: glibc-rh1418978-3-1.patch +Patch1767: glibc-rh1418978-3-2.patch + +# RHBZ #906468: Fix deadlock between fork, malloc, flush (NULL) +Patch1768: glibc-rh906468-1.patch +Patch1769: glibc-rh906468-2.patch + +# RHBZ #988869: stdio buffer auto-tuning should reject large buffer sizes +Patch1770: glibc-rh988869.patch + +# RHBZ #1398244 - RHEL7.3 - glibc: Fix TOC stub on powerpc64 clone() +Patch1771: glibc-rh1398244.patch + +# RHBZ #1228114: Fix sunrpc UDP client timeout handling +Patch1772: glibc-rh1228114-1.patch +Patch1773: glibc-rh1228114-2.patch + +# RHBZ #1298975 - [RFE] Backport the groups merging feature +Patch1774: glibc-rh1298975.patch + +# RHBZ #1318877 - Per C11 and C++11, should not look at +# __STDC_LIMIT_MACROS or __STDC_CONSTANT_MACROS +Patch1775: glibc-rh1318877.patch + +# RHBZ #1417205: Add AF_VSOCK/PF_VSOCK, TCP_TIMESTAMP +Patch1776: glibc-rh1417205.patch + +# RHBZ #1338672: GCC 6 enablement for struct sockaddr_storage +Patch1777: glibc-rh1338672.patch + +# RHBZ #1325138 - glibc: Corrupted aux-cache causes ldconfig to segfault +Patch1778: glibc-rh1325138.patch + +# RHBZ #1374652: Unbounded stack allocation in nan* functions +Patch1779: glibc-rh1374652.patch + +# RHBZ #1374654: Unbounded stack allocation in nan* functions +Patch1780: glibc-rh1374654.patch + +# RHBZ #1322544: Segmentation violation can occur within glibc if fork() +# is used in a multi-threaded application +Patch1781: glibc-rh1322544.patch + +# RHBZ #1418997: does not build with binutils 2.27 due to misuse of the cmpli instruction on ppc64 +Patch1782: glibc-rh1418997.patch + +# RHBZ #1383951: LD_POINTER_GUARD in the environment is not sanitized +Patch1783: glibc-rh1383951.patch + +# RHBZ #1385004: [7.4 FEAT] POWER8 IFUNC update from upstream +Patch1784: glibc-rh1385004-1.patch +Patch1785: glibc-rh1385004-2.patch +Patch1786: glibc-rh1385004-3.patch +Patch1787: glibc-rh1385004-4.patch +Patch1788: glibc-rh1385004-5.patch +Patch1789: glibc-rh1385004-6.patch +Patch1790: glibc-rh1385004-7.patch +Patch1791: glibc-rh1385004-8.patch +Patch1792: glibc-rh1385004-9.patch +Patch1793: glibc-rh1385004-10.patch +Patch1794: glibc-rh1385004-11.patch +Patch1795: glibc-rh1385004-12.patch +Patch1796: glibc-rh1385004-13.patch +Patch1797: glibc-rh1385004-14.patch +Patch1798: glibc-rh1385004-15.patch +Patch1799: glibc-rh1385004-16.patch +Patch1800: glibc-rh1385004-17.patch +Patch1801: glibc-rh1385004-18.patch +Patch1802: glibc-rh1385004-19.patch +Patch1803: glibc-rh1385004-20.patch +Patch1804: glibc-rh1385004-21.patch +Patch1805: glibc-rh1385004-22.patch +Patch1806: glibc-rh1385004-23.patch +Patch1807: glibc-rh1385004-24.patch + +# RHBZ 1380680 - [7.4 FEAT] z13 exploitation in glibc - stage 2 +Patch1808: glibc-rh1380680-1.patch +Patch1809: glibc-rh1380680-2.patch +Patch1810: glibc-rh1380680-3.patch +Patch1811: glibc-rh1380680-4.patch +Patch1812: glibc-rh1380680-5.patch +Patch1813: glibc-rh1380680-6.patch +Patch1814: glibc-rh1380680-7.patch +Patch1815: glibc-rh1380680-8.patch +Patch1816: glibc-rh1380680-9.patch +Patch1817: glibc-rh1380680-10.patch +Patch1818: glibc-rh1380680-11.patch +Patch1819: glibc-rh1380680-12.patch +Patch1820: glibc-rh1380680-13.patch +Patch1821: glibc-rh1380680-14.patch +Patch1822: glibc-rh1380680-15.patch +Patch1823: glibc-rh1380680-16.patch +Patch1824: glibc-rh1380680-17.patch + +# RHBZ #1326739: malloc: additional unlink hardening for non-small bins +Patch1825: glibc-rh1326739.patch + +# RHBZ #1374657: CVE-2015-8778: Integer overflow in hcreate and hcreate_r +Patch1826: glibc-rh1374657.patch + +# RHBZ #1374658 - CVE-2015-8776: Segmentation fault caused by passing +# out-of-range data to strftime() +Patch1827: glibc-rh1374658.patch + +# RHBZ #1385003 - SIZE_MAX evaluates to an expression of the wrong type +# on s390 +Patch1828: glibc-rh1385003.patch + +# RHBZ #1387874 - MSG_FASTOPEN definition missing +Patch1829: glibc-rh1387874.patch + +# RHBZ #1409611 - poor performance with exp() +Patch1830: glibc-rh1409611.patch + +# RHBZ #1421155 - Update dynamic loader trampoline for Intel SSE, AVX, and AVX512 usage. +Patch1831: glibc-rh1421155.patch + +# RHBZ #841653 - [Intel 7.0 FEAT] [RFE] TSX-baed lock elision enabled in glibc. +Patch1832: glibc-rh841653-0.patch +Patch1833: glibc-rh841653-1.patch +Patch1834: glibc-rh841653-2.patch +Patch1835: glibc-rh841653-3.patch +Patch1836: glibc-rh841653-4.patch +Patch1837: glibc-rh841653-5.patch +Patch1838: glibc-rh841653-6.patch +Patch1839: glibc-rh841653-7.patch +Patch1840: glibc-rh841653-8.patch +Patch1841: glibc-rh841653-9.patch +Patch1842: glibc-rh841653-10.patch +Patch1843: glibc-rh841653-11.patch +Patch1844: glibc-rh841653-12.patch +Patch1845: glibc-rh841653-13.patch +Patch1846: glibc-rh841653-14.patch +Patch1847: glibc-rh841653-15.patch +Patch1848: glibc-rh841653-16.patch +Patch1849: glibc-rh841653-17.patch + +# RHBZ #731835 - [RFE] [7.4 FEAT] Hardware Transactional Memory in GLIBC +Patch1850: glibc-rh731835-0.patch +Patch1851: glibc-rh731835-1.patch +Patch1852: glibc-rh731835-2.patch + +# RHBZ #1413638: Inhibit FMA while compiling sqrt, pow +Patch1853: glibc-rh1413638-1.patch +Patch1854: glibc-rh1413638-2.patch + +# RHBZ #1439165: Use a built-in list of known syscalls for +Patch1855: glibc-rh1439165.patch +Patch1856: glibc-rh1439165-syscall-names.patch + +# RHBZ #1457177: Rounding issues on POWER +Patch1857: glibc-rh1457177-1.patch +Patch1858: glibc-rh1457177-2.patch +Patch1859: glibc-rh1457177-3.patch +Patch1860: glibc-rh1457177-4.patch + +Patch1861: glibc-rh1348000.patch +Patch1862: glibc-rh1443236.patch +Patch1863: glibc-rh1447556.patch +Patch1864: glibc-rh1463692-1.patch +Patch1865: glibc-rh1463692-2.patch +Patch1866: glibc-rh1347277.patch + +# RHBZ #1375235: Add new s390x instruction support +Patch1867: glibc-rh1375235-1.patch +Patch1868: glibc-rh1375235-2.patch +Patch1869: glibc-rh1375235-3.patch +Patch1870: glibc-rh1375235-4.patch +Patch1871: glibc-rh1375235-5.patch +Patch1872: glibc-rh1375235-6.patch +Patch1873: glibc-rh1375235-7.patch +Patch1874: glibc-rh1375235-8.patch +Patch1875: glibc-rh1375235-9.patch +Patch1876: glibc-rh1375235-10.patch + +# RHBZ #1435615: nscd cache thread hangs +Patch1877: glibc-rh1435615.patch + +# RHBZ #1398413: libio: Implement vtable verification +Patch1878: glibc-rh1398413.patch + +# RHBZ #1445781: elf/tst-audit set of tests fails with "no PLTREL" +Patch1879: glibc-rh1445781-1.patch +Patch1880: glibc-rh1445781-2.patch + +Patch1881: glibc-rh1500908.patch +Patch1882: glibc-rh1448822.patch +Patch1883: glibc-rh1468807.patch +Patch1884: glibc-rh1372305.patch +Patch1885: glibc-rh1349962.patch +Patch1886: glibc-rh1349964.patch +Patch1887: glibc-rh1440250.patch +Patch1888: glibc-rh1504809-1.patch +Patch1889: glibc-rh1504809-2.patch +Patch1890: glibc-rh1504969.patch +Patch1891: glibc-rh1498925-1.patch +Patch1892: glibc-rh1498925-2.patch + +# RHBZ #1503854: Pegas1.0 - Update HWCAP bits for POWER9 DD2.1 +Patch1893: glibc-rh1503854-1.patch +Patch1894: glibc-rh1503854-2.patch +Patch1895: glibc-rh1503854-3.patch + +# RHBZ #1527904: PTHREAD_STACK_MIN is too small on x86_64 +Patch1896: glibc-rh1527904-1.patch +Patch1897: glibc-rh1527904-2.patch +Patch1898: glibc-rh1527904-3.patch +Patch1899: glibc-rh1527904-4.patch + +# RHBZ #1534635: CVE-2018-1000001 glibc: realpath() buffer underflow. +Patch1900: glibc-rh1534635.patch + +# RHBZ #1529982: recompile glibc to fix incorrect CFI information on i386. +Patch1901: glibc-rh1529982.patch + +Patch1902: glibc-rh1523119-compat-symbols.patch + ############################################################################## # # Patches submitted, but not yet approved upstream. @@ -1005,13 +1242,56 @@ Patch2075: glibc-rh1318890.patch Patch2076: glibc-rh1213603.patch Patch2077: glibc-rh1370630.patch -# getaddrinfo with nscd fixes -Patch2078: glibc-rh1436312.patch +# Add internal-only support for O_TMPFILE. +Patch2078: glibc-rh1330705-1.patch +Patch2079: glibc-rh1330705-2.patch +Patch2080: glibc-rh1330705-3.patch +Patch2081: glibc-rh1330705-4.patch +Patch2082: glibc-rh1330705-5.patch +# The following patch *removes* the public definition of O_TMPFILE. +Patch2083: glibc-rh1330705-6.patch -Patch2079: glibc-rh1452720-1.patch -Patch2080: glibc-rh1452720-2.patch -Patch2081: glibc-rh1452720-3.patch -Patch2082: glibc-rh1452720-4.patch +# getaddrinfo with nscd fixes +Patch2084: glibc-rh1324568.patch + +# RHBZ #1404435 - Remove power8 platform directory +Patch2085: glibc-rh1404435.patch + +# RHBZ #1144516 - aarch64 profil fix +Patch2086: glibc-rh1144516.patch + +# RHBZ #1392540 - Add "sss" service to the automount database in nsswitch.conf +Patch2087: glibc-rh1392540.patch + +# RHBZ #1452721: Avoid large allocas in the dynamic linker +Patch2088: glibc-rh1452721-1.patch +Patch2089: glibc-rh1452721-2.patch +Patch2090: glibc-rh1452721-3.patch +Patch2091: glibc-rh1452721-4.patch + +Patch2092: glibc-rh677316-libc-pointer-arith.patch +Patch2093: glibc-rh677316-libc-lock.patch +Patch2094: glibc-rh677316-libc-diag.patch +Patch2095: glibc-rh677316-check_mul_overflow_size_t.patch +Patch2096: glibc-rh677316-res_state.patch +Patch2097: glibc-rh677316-qsort_r.patch +Patch2098: glibc-rh677316-fgets_unlocked.patch +Patch2099: glibc-rh677316-in6addr_any.patch +Patch2100: glibc-rh677316-netdb-reentrant.patch +Patch2101: glibc-rh677316-h_errno.patch +Patch2102: glibc-rh677316-scratch_buffer.patch +Patch2103: glibc-rh677316-mtrace.patch +Patch2104: glibc-rh677316-dynarray.patch +Patch2105: glibc-rh677316-alloc_buffer.patch +Patch2106: glibc-rh677316-RES_USE_INET6.patch +Patch2107: glibc-rh677316-inet_pton.patch +Patch2108: glibc-rh677316-inet_pton-zeros.patch +Patch2109: glibc-rh677316-hesiod.patch +Patch2110: glibc-rh677316-resolv.patch +Patch2111: glibc-rh677316-legacy.patch + +Patch2112: glibc-rh1498566.patch +Patch2113: glibc-rh1445644.patch ############################################################################## # End of glibc patches. @@ -1065,9 +1345,10 @@ BuildRequires: /usr/bin/valgrind # This is needed to get the _tmpfilesdir macro we use for nscd. BuildRequires: systemd -# This is to ensure that __frame_state_for is exported by glibc -# will be compatible with egcs 1.x.y -BuildRequires: gcc >= 3.2 +# This GCC version introduced the -fstack-clash-protection option with +# the required semantics. +BuildRequires: gcc >= 4.8.5-25 + %define enablekernel 2.6.32 Conflicts: kernel < %{enablekernel} %define target %{_target_cpu}-redhat-linux @@ -1630,6 +1911,15 @@ package or when debugging this package. %patch2080 -p1 %patch2081 -p1 %patch2082 -p1 +%patch2083 -p1 +%patch2084 -p1 +%patch2085 -p1 +%patch2086 -p1 +%patch2087 -p1 +%patch2088 -p1 +%patch2089 -p1 +%patch2090 -p1 +%patch2091 -p1 # Rebase of microbenchmarks. %patch1607 -p1 @@ -1818,11 +2108,206 @@ package or when debugging this package. %patch1754 -p1 %patch1755 -p1 %patch1756 -p1 +%patch1757 -p1 +%patch17580 -p1 +%patch1758 -p1 +%patch1759 -p1 +%patch1760 -p1 +%patch1761 -p1 +%patch1762 -p1 +%patch1763 -p1 +%patch1764 -p1 +%patch1765 -p1 +%patch1766 -p1 +%patch1767 -p1 +%patch1768 -p1 +%patch1769 -p1 +%patch1770 -p1 +%patch1771 -p1 +%patch1772 -p1 +%patch1773 -p1 +%patch1774 -p1 +%patch1775 -p1 +%patch1776 -p1 +%patch1777 -p1 +%patch1778 -p1 +%patch1779 -p1 +%patch1780 -p1 +%patch1781 -p1 +%patch1782 -p1 +%patch1783 -p1 +%patch1784 -p1 +%patch1785 -p1 +%patch1786 -p1 +%patch1787 -p1 +%patch1788 -p1 +%patch1789 -p1 +%patch1790 -p1 +%patch1791 -p1 +%patch1792 -p1 +%patch1793 -p1 +%patch1794 -p1 +%patch1795 -p1 +%patch1796 -p1 +%patch1797 -p1 +%patch1798 -p1 +%patch1799 -p1 +%patch1800 -p1 +%patch1801 -p1 +%patch1802 -p1 +%patch1803 -p1 +%patch1804 -p1 +%patch1805 -p1 +%patch1806 -p1 +%patch1807 -p1 +%patch1808 -p1 +%patch1809 -p1 +%patch1810 -p1 +%patch1811 -p1 +%patch1812 -p1 +%patch1813 -p1 +%patch1814 -p1 +%patch1815 -p1 +%patch1816 -p1 +%patch1817 -p1 +%patch1818 -p1 +%patch1819 -p1 +%patch1820 -p1 +%patch1821 -p1 +%patch1822 -p1 +%patch1823 -p1 +%patch1824 -p1 +%patch1825 -p1 +%patch1826 -p1 +%patch1827 -p1 +%patch1828 -p1 +%patch1829 -p1 +%patch1830 -p1 +%patch1831 -p1 +# RHBZ #841653 - Intel lock elision patch set. +%patch1832 -p1 +%patch1833 -p1 +%patch1834 -p1 +%patch1835 -p1 +%patch1836 -p1 +%patch1837 -p1 +%patch1838 -p1 +%patch1839 -p1 +%patch1840 -p1 +%patch1841 -p1 +%patch1842 -p1 +%patch1843 -p1 +%patch1844 -p1 +%patch1845 -p1 +%patch1846 -p1 +%patch1847 -p1 +%patch1848 -p1 +%patch1849 -p1 +# End of Intel lock elision patch set. +# RHBZ #731835 - IBM POWER lock elision patch set. +%patch1850 -p1 +%patch1851 -p1 +%patch1852 -p1 +# End of IBM POWER lock elision patch set. + +%patch1853 -p1 +%patch1854 -p1 + +# Built-in list of syscall names. +%patch1855 -p1 +%patch1856 -p1 + +%patch1857 -p1 +%patch1858 -p1 +%patch1859 -p1 +%patch1860 -p1 + +%patch1861 -p1 +%patch1862 -p1 +%patch1863 -p1 +%patch1864 -p1 +%patch1865 -p1 +%patch1866 -p1 + +%patch1867 -p1 +%patch1868 -p1 +%patch1869 -p1 +%patch1870 -p1 +%patch1871 -p1 +%patch1872 -p1 +%patch1873 -p1 +%patch1874 -p1 +%patch1875 -p1 +%patch1876 -p1 + +%patch1877 -p1 +%patch2092 -p1 +%patch2093 -p1 +%patch2094 -p1 +%patch2095 -p1 +%patch2096 -p1 +%patch2097 -p1 +%patch2098 -p1 +%patch2099 -p1 +%patch2100 -p1 +%patch2101 -p1 +%patch2102 -p1 +%patch2103 -p1 +%patch2104 -p1 +%patch2105 -p1 +%patch2106 -p1 +%patch2107 -p1 +%patch2108 -p1 +%patch2109 -p1 +%patch2110 -p1 +%patch2111 -p1 +%patch2112 -p1 +%patch2113 -p1 + +%patch1878 -p1 +%patch1879 -p1 +%patch1880 -p1 + +%patch1881 -p1 +%patch1882 -p1 +%patch1883 -p1 +%patch1884 -p1 +%patch1885 -p1 +%patch1886 -p1 +%patch1887 -p1 +%patch1888 -p1 +%patch1889 -p1 +%patch1890 -p1 +%patch1891 -p1 +%patch1892 -p1 + +%patch1893 -p1 +%patch1894 -p1 +%patch1895 -p1 +%patch1896 -p1 +%patch1897 -p1 +%patch1898 -p1 +%patch1899 -p1 +%patch1900 -p1 +%patch1901 -p1 +%patch1902 -p1 ############################################################################## # %%prep - Additional prep required... ############################################################################## +# Verify checksum of certain files in the source tree and exit +# with a failure if they don't match expected values. The most +# important purpose for this verification is patched binary files +# which may get corrupted by editors. Check them here to make sure +# they are OK after patching. +if md5sum -c %{SOURCE2}; then + continue +else + echo "md5sum: Verification of md5 sum for binary source files failed." + exit 1 +fi + # XXX: This sounds entirely out of date, particularly in light of the fact # that we want to be building newer Power support. We should review this # and potentially remove this workaround. However it will require @@ -1933,6 +2418,7 @@ core_with_options="--with-cpu=power7" # %%build - Generic options. ############################################################################## BuildFlags="$BuildFlags -fasynchronous-unwind-tables" +BuildFlags="$BuildFlags -fstack-clash-protection" # Add -DNDEBUG unless using a prerelease case %{version} in *.*.9[0-9]*) ;; @@ -1974,6 +2460,9 @@ configure_CFLAGS="$build_CFLAGS -fno-asynchronous-unwind-tables" --build=%{target} \ %ifarch %{multiarcharches} --enable-multi-arch \ +%endif +%ifarch %{elisionarches} + --enable-lock-elision=yes \ %endif --enable-obsolete-rpc \ --enable-systemtap \ @@ -2965,17 +3454,236 @@ rm -f *.filelist* %endif %changelog -* Fri May 26 2017 Florian Weimer - 2.17-157.4 -- Avoid large allocas in the dynamic linker (#1452720) +* Thu Feb 1 2018 Florian Weimer - 2.17-222 +- Restore internal GLIBC_PRIVATE symbols for use during upgrades (#1523119) + +* Fri Jan 19 2018 Carlos O'Donell - 2.17-221 +- CVE-2018-1000001: Fix realpath() buffer underflow (#1534635) +- i386: Fix unwinding for 32-bit C++ application (#1529982) +- Reduce thread and dynamic loader stack usage (#1527904) +- x86-64: Use XSAVE/XSAVEC more often during lazy symbol binding (#1528418) + +* Fri Nov 17 2017 Carlos O'Donell - 2.17-220 +- Update HWCAP bits for IBM POWER9 DD2.1 (#1503854) + +* Fri Nov 17 2017 Florian Weimer - 2.17-219 +- Rebuild with newer gcc for aarch64 stack probing fixes (#1500475) + +* Tue Nov 7 2017 Carlos O'Donell - 2.17-218 +- Improve memcpy performance for POWER9 DD2.1 (#1498925) + +* Thu Nov 2 2017 Florian Weimer - 2.17-217 +- Update Linux system call list to kernel 4.13 (#1508895) + +* Thu Nov 2 2017 Florian Weimer - 2.17-216 +- x86-64: Use XSAVE/XSAVEC in the ld.so trampoline (#1504969) + +* Thu Nov 2 2017 Florian Weimer - 2.17-215 +- CVE-2017-15670: glob: Fix one-byte overflow with GLOB_TILDE (#1504809) +- CVE-2017-15804: glob: Fix buffer overflow in GLOB_TILDE unescaping (#1504809) + +* Sat Oct 21 2017 Patsy Franklin - 2.17-214 +- Fix check-localplt test failure. +- Include ld.so in check-localplt test. (#1440250) + +* Thu Oct 19 2017 Florian Weimer - 2.17-213 +- Fix build warning in locarchive.c (#1349964) + +* Wed Oct 18 2017 Florian Weimer - 2.17-212 +- Hide reference to mktemp in libpthread (#1349962) + +* Wed Oct 18 2017 Florian Weimer - 2.17-211 +- Implement fopencookie hardening (#1372305) + +* Wed Oct 18 2017 Florian Weimer - 2.17-210 +- x86-64: Support __tls_get_addr with an unaligned stack (#1468807) + +* Wed Oct 18 2017 Florian Weimer - 2.17-209 +- Define CLOCK_TAI in (#1448822) + +* Mon Oct 16 2017 Florian Weimer - 2.17-208 +- Compile glibc with -fstack-clash-protection (#1500475) + +* Thu Oct 12 2017 Florian Weimer - 2.17-207 +- aarch64: Avoid invalid relocations in the startup code (#1500908) + +* Fri Oct 6 2017 Patsy Franklin - 2.17-206 +- Fix timezone test failures on large parallel builds. (#1234449, #1378329) + +* Fri Oct 6 2017 DJ Delorie - 2.17-205 +- Handle DSOs with no PLT (#1445781) + +* Fri Oct 6 2017 DJ Delorie - 2.17-204 +- libio: Implement vtable verification (#1398413) + +* Thu Oct 5 2017 Arjun Shankar - 2.17-203 +- Fix socket system call selection on s390x (#1498566). +- Use different construct for protected visibility in IFUNC tests (#1445644) + +* Fri Sep 29 2017 Florian Weimer - 2.17-202 +- Rebase the DNS stub resolver and getaddrinfo to the glibc 2.26 version +- Support an arbitrary number of search domains in the stub resolver (#677316) +- Detect and apply /etc/resolv.conf changes in libresolv (#1432085) +- CVE-2017-1213: Fragmentation attacks possible when ENDS0 is enabled + (#1487063) +- CVE-2016-3706: Stack (frame) overflow in getaddrinfo when called + with AF_INET, AF_INET6 (#1329674) +- CVE-2015-5180: resolv: Fix crash with internal QTYPE (#1497131) +- CVE-2014-9402: denial of service in getnetbyname function (#1497132) +- Fix getaddrinfo to handle certain long lines in /etc/hosts (#1452034) +- Make RES_ROTATE start with a random name server (#1257639) +- Stricter IPv6 address parser (#1484034) +- Remove noip6dotint support from the stub resolver (#1482988) +- Remove partial bitstring label support from the stub resolver +- Remove unsupported resolver hook functions from the API +- Remove outdated RR type classification macros from the API +- hesiod: Always use TLS resolver state +- hesiod: Avoid non-trust-boundary crossing heap overflow in get_txt_records + +* Tue Sep 26 2017 DJ Delorie - 2.17.201 +- Fix hang in nscd cache prune thread (#1435615) + +* Thu Sep 21 2017 Patsy Franklin - 2.17-200 +- Add binary timezone test data files (#1234449, #1378329) + +* Wed Sep 20 2017 DJ Delorie - 2.17.198 +- Add support for new IBM z14 (s390x) instructions (#1375235) + +* Wed Aug 16 2017 DJ Delorie - 2.17-197 +- Fix compile warnings in malloc (#1347277) +- Fix occasional tst-malloc-usable failures (#1348000) +- Additional chunk hardening in malloc (#1447556) +- Pointer alignment fix in nss group merge (#1463692) +- Fix SIGSEGV when LD_LIBRARY_PATH only has non-existing paths (#1443236) + +* Fri Jun 16 2017 Florian Weimer - 2.17-196 +- CVE-2017-1000366: Avoid large allocas in the dynamic linker (#1452721) + +* Fri Jun 9 2017 Florian Weimer - 2.17-195 +- Rounding issues on POWER (#1457177) + +* Wed Apr 26 2017 Florian Weimer - 2.17-194 +- Use a built-in list of system call names (#1439165) + +* Tue Apr 18 2017 Florian Weimer - 2.17-193 +- Inhibit FMA while compiling sqrt, pow (#1413638) + +* Wed Mar 29 2017 Carlos O'Donell - 2.17-192 +- Exclude lock elision support for older Intel hardware with + Intel TSX that has hardware errata (#841653). + +* Tue Mar 28 2017 Carlos O'Donell - 2.17-191 +- Add transparent lock elision for default POSIX mutexes on + IBM POWER hardware with support for IBM POWER HTM (#731835). + +* Tue Mar 28 2017 Carlos O'Donell - 2.17-190 +- Add transparent lock elision for default POSIX mutexes on + Intel hardware with support for Intel TSX (#841653). +- Update dynamic loader trampoline for Intel Skylake server (#1421155). + +* Wed Mar 15 2017 Carlos O'Donell - 2.17-189 +- Update dynamic loader trampoline for Intel SSE, AVX, and AVX512 usage (#1421155) + +* Wed Mar 15 2017 Carlos O'Donell - 2.17-188 +- Improve exp() and pow() performance in libm (#1409611) +- Add optimized strcmp and strncmp for IBM POWER9 hardware (#1320947) + +* Tue Mar 14 2017 Patsy Franklin - 2.17-187 +- Define MSG_FASTOPEN. (#1387874) + +* Tue Mar 14 2017 Patsy Franklin - 2.17-186 +- Update patch for glibc-rh1288613.patch to include tst-res_hconf_reorder + in the list of tests to be built and run. (#1367804) + +* Tue Mar 14 2017 Florian Weimer - 2.17-185 +- math: Regenerate ULPs for POWER (#1385004) + +* Thu Mar 9 2017 Martin Sebor - 2.17-184 +- Correct s390 definition of SIZE_MAX (#1385003) + +* Thu Mar 9 2017 Martin Sebor - 2.17-183 +- Fix CVE-2015-8776 glibc: Segmentation fault caused by passing + out-of-range data to strftime() (#1374658) + +* Thu Mar 9 2017 Martin Sebor - 2.17-182 +- Fix CVE-2015-8778: Integer overflow in hcreate and hcreate_r (#1374657) + +* Wed Mar 8 2017 DJ Delorie - 2.17-181 +- Fix rare case where calloc may not zero memory properly (#1430477) + +* Wed Mar 8 2017 Florian Weimer - 2.17-180 +- malloc: additional unlink hardening for non-small bins (#1326739) + +* Wed Mar 8 2017 Martin Sebor - 2.17-179 +- Add improvements and optimizations to take advantage of the new + z13 processor design (#1380680) + +* Wed Mar 8 2017 Martin Sebor - 2.17-178 +- Backport the latest POWER8 performance optimizations (#1385004) + +* Tue Mar 7 2017 DJ Delorie - 2.17-177 +- LD_POINTER_GUARD in the environment is not sanitized (#1383951) + +* Tue Mar 7 2017 DJ Delorie - 2.17-176 +- Fix cmpli usage in power6 memset. (#1418997) + +* Mon Mar 6 2017 Martin Sebor - 2.17-175 +- Avoid accessing user-controlled stdio locks in forked child (#1322544) + +* Mon Mar 6 2017 DJ Delorie - 2.17-174 +- Fix unbounded stack allocation in catopen function (#1374654) + +* Mon Mar 6 2017 DJ Delorie - 2.17-173 +- Fix unbounded stack allocation in nan* functions (#1374652) + +* Fri Mar 3 2017 Martin Sebor - 2.17-172 +- Handle /var/cache/ldconfig/aux-cache corruption (#1325138) + +* Wed Mar 1 2017 DJ Delorie - 2.17-171 +- Make padding in struct sockaddr_storage explicit (#1338672) + +* Wed Mar 1 2017 Florian Weimer - 2.17-170 +- Add AF_VSOCK/PF_VSOCK, TCP_TIMESTAMP (#1417205) + +* Tue Feb 28 2017 Martin Sebor - 2.17-169 +- Define and macros unconditionally (#1318877) + +* Tue Feb 28 2017 Martin Sebor - 2.17-168 +- Backport the groups merging feature (#1298975) + +* Tue Feb 28 2017 Florian Weimer - 2.17-167 +- Fix sunrpc UDP client timeout handling (#1228114) + +* Tue Feb 28 2017 Florian Weimer - 2.17-166 +- Add "sss" service to the automount database in nsswitch.conf (#1392540) + +* Mon Feb 27 2017 Florian Weimer - 2.17-165 +- Fix use of uninitialized data in getaddrinfo with nscd (#1324568) +- Remove the "power8" AT_PLATFORM directory (#1404435) +- Fix profil on aarch64 (#1144516) + +* Tue Feb 21 2017 Martin Sebor - 2.17-164 +- Fix TOC stub on powerpc64 clone() (#1398244) + +* Wed Feb 15 2017 Florian Weimer - 2.17-163 +- stdio buffer auto-tuning should reject large buffer sizes (#988869) + +* Tue Feb 14 2017 Florian Weimer - 2.17-162 +- Backport support/ subdirectory from upstream (#1418978) +- Fix deadlock between fork, malloc, flush (NULL) (#906468) + +* Fri Jan 27 2017 Patsy Franklin - 2.17-161 +- Fix tst-cancel17/tst-cancelx17 was sometimes segfaulting. + Wait for the read to finish before returning. (#1337242) -* Tue Mar 28 2017 DJ Delorie - 2.17-157.2 -- Fix use of uninitialized data in getaddrinfo with nscd (#1436312) +* Wed Jan 25 2017 Florian Weimer - 2.17-160 +- Add internal-only support for O_TMPFILE (#1330705) -* Thu Oct 27 2016 Carlos O'Donell - 2.17-157.1 -- Do not set initgroups in default nsswitch.conf (#1388638) -- nss_db: Request larger buffers for long group entries (#1388637) -- nss_db: Fix get*ent crash without preceding set*ent (#1388635) -- nss_db: Fix endless loop in services database processing (#1388639) +* Thu Oct 20 2016 Carlos O'Donell - 2.17-158 +- Do not set initgroups in default nsswitch.conf (#1366569) +- nss_db: Request larger buffers for long group entries (#1318890) +- nss_db: Fix get*ent crash without preceding set*ent (#1213603) +- nss_db: Fix endless loop in services database processing (#1370630) * Thu Aug 11 2016 Florian Weimer - 2.17-157 - Rebuild with updated binutils (#1268008)